Contracts Add deposit for dependencies (#14079)

* wip

* fixes

* rm comment

* join fns

* clippy

* Fix limits

* reduce diff

* fix

* fix

* fix typo

* refactor store to  use self

* refactor run to take self by value

* pass tests

* rm comment

* fixes

* fix typo

* rm

* fix fmt

* clippy

* ".git/.scripts/commands/bench/bench.sh" pallet dev pallet_contracts

* Update frame/contracts/src/lib.rs

Co-authored-by: Sasha Gryaznov <hi@agryaznov.com>

* Update frame/contracts/src/wasm/mod.rs

Co-authored-by: Sasha Gryaznov <hi@agryaznov.com>

* Update frame/contracts/src/wasm/mod.rs

Co-authored-by: Sasha Gryaznov <hi@agryaznov.com>

* PR review, rm duplicate increment_refcount

* PR review

* Update frame/contracts/src/wasm/prepare.rs

Co-authored-by: Sasha Gryaznov <hi@agryaznov.com>

* Add test for failing storage_deposit

* fix lint

* wip

* Delegate update take 2

* update

* fix migration

* fix migration

* doc

* fix lint

* update migration

* fix warning

* reformat comment

* regenerate weightInfo trait

* fix merge

* PR review

https://github.com/paritytech/substrate/pull/14079#discussion_r1255904563

* PR review

https://github.com/paritytech/substrate/pull/14079/files#r1257521373

* PR review remove optimisation

https://github.com/paritytech/substrate/pull/14079/files#r1263312237

* PR review fix return type

https://github.com/paritytech/substrate/pull/14079/files#r1263315804

* Apply suggestions from code review

Co-authored-by: Alexander Theißen <alex.theissen@me.com>

* PR review pass CodeInfo and update docstring

https://github.com/paritytech/substrate/pull/14079/files#r1257522327

* PR review add code_info to the executable

https://github.com/paritytech/substrate/pull/14079/files#r1263309049

* rename info -> contract_info

* Update frame/contracts/src/exec.rs

Co-authored-by: Alexander Theißen <alex.theissen@me.com>

* Update frame/contracts/fixtures/add_remove_delegate_dependency.wat

Co-authored-by: Alexander Theißen <alex.theissen@me.com>

* Update frame/contracts/src/migration/v13.rs

* fix tests

* Fmt & fix tests

* Test Result<(), _> return type

* Update frame/contracts/src/migration.rs

Co-authored-by: Alexander Theißen <alex.theissen@me.com>

* Revert "Test Result<(), _> return type"

This reverts commit a876168f2054edf84d720c666387583ccbe78dcd.

* add / update doc comments

* fix backticks

* Revert "Revert "Test Result<(), _> return type""

This reverts commit 3cbb6161d1abd9520cd9f8519b4dfbf4f29a2998.

* fix bench

* fix bench

* fix

* Update frame/contracts/src/storage/meter.rs

Co-authored-by: Alexander Theißen <alex.theissen@me.com>

* rm stale comments

* Apply suggestions from code review

Co-authored-by: Sasha Gryaznov <hi@agryaznov.com>

* PR suggestion

* Add missing doc

* fx lint

* ".git/.scripts/commands/bench/bench.sh" --subcommand=pallet --runtime=dev --target_dir=substrate --pallet=pallet_contracts

* Update frame/contracts/src/lib.rs

Co-authored-by: Juan <juangirini@gmail.com>

---------

Co-authored-by: command-bot <>
Co-authored-by: Sasha Gryaznov <hi@agryaznov.com>
Co-authored-by: Alexander Theißen <alex.theissen@me.com>
Co-authored-by: Juan <juangirini@gmail.com>
This commit is contained in:
PG Herveou
2023-07-26 14:09:02 +02:00
committed by GitHub
parent 47bb475d6d
commit 5a5b1df69b
14 changed files with 3956 additions and 2798 deletions
+24 -18
View File
@@ -19,9 +19,9 @@
use crate::{
storage::{ContractInfo, DepositAccount},
BalanceOf, Config, Error, Inspect, Origin, Pallet, System,
BalanceOf, CodeInfo, Config, Error, Inspect, Origin, Pallet, StorageDeposit as Deposit, System,
};
use codec::Encode;
use frame_support::{
dispatch::{fmt::Debug, DispatchError},
ensure,
@@ -31,7 +31,6 @@ use frame_support::{
},
DefaultNoBound, RuntimeDebugNoBound,
};
use pallet_contracts_primitives::StorageDeposit as Deposit;
use sp_runtime::{
traits::{Saturating, Zero},
FixedPointNumber, FixedU128,
@@ -398,7 +397,7 @@ where
T: Config,
E: Ext<T>,
{
/// Charge `diff` from the meter.
/// Charges `diff` from the meter.
pub fn charge(&mut self, diff: &Diff) {
match &mut self.own_contribution {
Contribution::Alive(own) => *own = own.saturating_add(diff),
@@ -406,46 +405,52 @@ where
};
}
/// Charge from `origin` a storage deposit for contract instantiation.
/// Adds a deposit charge.
///
/// Use this method instead of [`Self::charge`] when the charge is not the result of a storage
/// change. This is the case when a `delegate_dependency` is added or removed, or when the
/// `code_hash` is updated. [`Self::charge`] cannot be used here because we keep track of the
/// deposit charge separately from the storage charge.
pub fn charge_deposit(&mut self, deposit_account: DepositAccount<T>, amount: DepositOf<T>) {
self.total_deposit = self.total_deposit.saturating_add(&amount);
self.charges.push(Charge { deposit_account, amount, terminated: false });
}
/// Charges from `origin` a storage deposit for contract instantiation.
///
/// This immediately transfers the balance in order to create the account.
pub fn charge_instantiate(
&mut self,
origin: &T::AccountId,
contract: &T::AccountId,
info: &mut ContractInfo<T>,
contract_info: &mut ContractInfo<T>,
code_info: &CodeInfo<T>,
) -> Result<DepositOf<T>, DispatchError> {
debug_assert!(self.is_alive());
let ed = Pallet::<T>::min_balance();
let mut deposit =
Diff { bytes_added: info.encoded_size() as u32, items_added: 1, ..Default::default() }
.update_contract::<T>(None);
// Instantiate needs to transfer at least the minimum balance in order to pull the
// deposit account into existence.
// We also add another `ed` here which goes to the contract's own account into existence.
deposit = deposit.max(Deposit::Charge(ed)).saturating_add(&Deposit::Charge(ed));
if deposit.charge_or_zero() > self.limit {
let deposit = contract_info.update_base_deposit(&code_info);
if deposit > self.limit {
return Err(<Error<T>>::StorageDepositLimitExhausted.into())
}
let deposit = Deposit::Charge(deposit);
// We do not increase `own_contribution` because this will be charged later when the
// contract execution does conclude and hence would lead to a double charge.
self.total_deposit = deposit.clone();
info.storage_base_deposit = deposit.charge_or_zero();
// Normally, deposit charges are deferred to be able to coalesce them with refunds.
// However, we need to charge immediately so that the account is created before
// charges possibly below the ed are collected and fail.
E::charge(
origin,
info.deposit_account(),
contract_info.deposit_account(),
&deposit.saturating_sub(&Deposit::Charge(ed)),
false,
)?;
System::<T>::inc_consumers(info.deposit_account())?;
System::<T>::inc_consumers(contract_info.deposit_account())?;
// We also need to make sure that the contract's account itself exists.
T::Currency::transfer(origin, contract, ed, ExistenceRequirement::KeepAlive)?;
@@ -664,6 +669,7 @@ mod tests {
storage_byte_deposit: info.bytes_deposit,
storage_item_deposit: info.items_deposit,
storage_base_deposit: Default::default(),
delegate_dependencies: Default::default(),
}
}