contracts: Add storage deposits (#10082)

* Frame no longer needs to be mutable (refactoring artifact)

* Remove Contract/Tombstone deposit

* Add StorageMeter

* cargo fmt

* Fix weight annotation

* cargo run --quiet --release --features=runtime-benchmarks --manifest-path=bin/node/cli/Cargo.toml -- benchmark --chain=dev --steps=50 --repeat=20 --pallet=pallet_contracts --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --output=./frame/contracts/src/weights.rs --template=./.maintain/frame-weight-template.hbs

* Simplify keep check for contract accounts

- Make sure that the "base deposit" for each contract >= ed
- Remove now obsolete checks when sneding away free balance

* Remove unused imports and functions

* Rename storage_limit to storage_deposit_limit

* cargo fmt

* Fix typo

Co-authored-by: Michael Müller <michi@parity.io>

* Finish up rename of storage_limit

* Fix rpc tests

* Make use of `StorageDepositLimitTooHigh`

* Add tests and fix bugs discovered by tests

* Add storage migration

* Don't use u128 in RPC

* Fix weight of migration

* Rename `endowment` to `value`

* Fix bug where contract couldn't get funded by a storage deposit

- Make sure that contract gets funded from deposits before value is transferred
- Don't reserve value at origin because otherwise funding isn't possible
	- Just transfer free balance and reserve it after the transfer
- When refunding make sure that this refund can't dust the contract
	- Can only happen after a runtime upgrade where costs where upped
- Add more tests

* Apply suggestions from code review

Co-authored-by: Andrew Jones <ascjones@gmail.com>

* Remove unused `fn storage_meter`

* Fix copy pasta doc error

* Import `MaxEncodeLen` from codec

* Beautify RPC trait bounds

* Add re-instrument behaviour to dispatchable doc

* Make sure a account won't be destroyed a refund after a slash

* Apply suggestions from code review

Co-authored-by: Andrew Jones <ascjones@gmail.com>

* Update `Storage::write` docs

* Improve doc

* Remove superflous conditional

* Typos

* Remove superflous clone (refactoring artifact)

* Apply suggestions from code review

Co-authored-by: Andrew Jones <ascjones@gmail.com>

Co-authored-by: Parity Bot <admin@parity.io>
Co-authored-by: Michael Müller <michi@parity.io>
Co-authored-by: Andrew Jones <ascjones@gmail.com>
This commit is contained in:
Alexander Theißen
2021-12-07 13:19:30 +01:00
committed by GitHub
parent 56fb1cfbb6
commit 6863476603
27 changed files with 4395 additions and 1914 deletions
+1
View File
@@ -20,6 +20,7 @@ sc-executor = { version = "0.10.0-dev", path = "../../../client/executor" }
sp-core = { version = "4.0.0-dev", path = "../../../primitives/core" }
sp-keystore = { version = "0.10.0-dev", path = "../../../primitives/keystore" }
sp-state-machine = { version = "0.10.0-dev", path = "../../../primitives/state-machine" }
sp-tracing = { version = "4.0.0-dev", path = "../../../primitives/tracing" }
sp-trie = { version = "4.0.0-dev", path = "../../../primitives/trie" }
frame-benchmarking = { version = "4.0.0-dev", path = "../../../frame/benchmarking" }
+3 -3
View File
@@ -685,8 +685,6 @@ fn deploying_wasm_contract_should_work() {
let addr = pallet_contracts::Pallet::<Runtime>::contract_address(&charlie(), &transfer_ch, &[]);
let subsistence = pallet_contracts::Pallet::<Runtime>::subsistence_threshold();
let time = 42 * 1000;
let b = construct_block(
&mut new_test_ext(compact_code_unwrap()),
@@ -701,8 +699,9 @@ fn deploying_wasm_contract_should_work() {
signed: Some((charlie(), signed_extra(0, 0))),
function: Call::Contracts(
pallet_contracts::Call::instantiate_with_code::<Runtime> {
endowment: 1000 * DOLLARS + subsistence,
value: 0,
gas_limit: 500_000_000,
storage_deposit_limit: None,
code: transfer_code,
data: Vec::new(),
salt: Vec::new(),
@@ -715,6 +714,7 @@ fn deploying_wasm_contract_should_work() {
dest: sp_runtime::MultiAddress::Id(addr.clone()),
value: 10,
gas_limit: 500_000_000,
storage_deposit_limit: None,
data: vec![0x00, 0x01, 0x02, 0x03],
}),
},
+1 -1
View File
@@ -119,7 +119,7 @@ pub fn executor_call<
hash: sp_core::blake2_256(&code).to_vec(),
heap_pages: heap_pages.and_then(|hp| Decode::decode(&mut &hp[..]).ok()),
};
sp_tracing::try_init_simple();
executor().call::<R, NC>(&mut t, &runtime_code, method, data, use_native, native_call)
}
+20 -10
View File
@@ -897,10 +897,8 @@ impl pallet_tips::Config for Runtime {
}
parameter_types! {
pub ContractDeposit: Balance = deposit(
1,
<pallet_contracts::Pallet<Runtime>>::contract_info_size(),
);
pub const DepositPerItem: Balance = deposit(1, 0);
pub const DepositPerByte: Balance = deposit(0, 1);
pub const MaxValueSize: u32 = 16 * 1024;
// The lazy deletion runs inside on_initialize.
pub DeletionWeightLimit: Weight = AVERAGE_ON_INITIALIZE_RATIO *
@@ -927,7 +925,8 @@ impl pallet_contracts::Config for Runtime {
/// change because that would break already deployed contracts. The `Call` structure itself
/// is not allowed to change the indices of existing pallets, too.
type CallFilter = Nothing;
type ContractDeposit = ContractDeposit;
type DepositPerItem = DepositPerItem;
type DepositPerByte = DepositPerByte;
type CallStack = [pallet_contracts::Frame<Self>; 31];
type WeightPrice = pallet_transaction_payment::Pallet<Self>;
type WeightInfo = pallet_contracts::weights::SubstrateWeight<Self>;
@@ -1522,21 +1521,32 @@ impl_runtime_apis! {
dest: AccountId,
value: Balance,
gas_limit: u64,
storage_deposit_limit: Option<Balance>,
input_data: Vec<u8>,
) -> pallet_contracts_primitives::ContractExecResult {
Contracts::bare_call(origin, dest, value, gas_limit, input_data, true)
) -> pallet_contracts_primitives::ContractExecResult<Balance> {
Contracts::bare_call(origin, dest, value, gas_limit, storage_deposit_limit, input_data, true)
}
fn instantiate(
origin: AccountId,
endowment: Balance,
value: Balance,
gas_limit: u64,
storage_deposit_limit: Option<Balance>,
code: pallet_contracts_primitives::Code<Hash>,
data: Vec<u8>,
salt: Vec<u8>,
) -> pallet_contracts_primitives::ContractInstantiateResult<AccountId>
) -> pallet_contracts_primitives::ContractInstantiateResult<AccountId, Balance>
{
Contracts::bare_instantiate(origin, endowment, gas_limit, code, data, salt, true)
Contracts::bare_instantiate(origin, value, gas_limit, storage_deposit_limit, code, data, salt, true)
}
fn upload_code(
origin: AccountId,
code: Vec<u8>,
storage_deposit_limit: Option<Balance>,
) -> pallet_contracts_primitives::CodeUploadResult<Hash, Balance>
{
Contracts::bare_upload_code(origin, code, storage_deposit_limit)
}
fn get_storage(