mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-30 16:21:02 +00:00
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:
committed by
GitHub
parent
56fb1cfbb6
commit
6863476603
@@ -31,7 +31,7 @@ use pallet_contracts_primitives::{ExecReturnValue, ReturnFlags};
|
||||
use pwasm_utils::parity_wasm::elements::ValueType;
|
||||
use sp_core::{crypto::UncheckedFrom, Bytes};
|
||||
use sp_io::hashing::{blake2_128, blake2_256, keccak_256, sha2_256};
|
||||
use sp_runtime::traits::Bounded;
|
||||
use sp_runtime::traits::{Bounded, Zero};
|
||||
use sp_sandbox::SandboxMemory;
|
||||
use sp_std::prelude::*;
|
||||
|
||||
@@ -55,15 +55,12 @@ pub enum ReturnCode {
|
||||
CalleeReverted = 2,
|
||||
/// The passed key does not exist in storage.
|
||||
KeyNotFound = 3,
|
||||
/// Transfer failed because it would have brought the sender's total balance below the
|
||||
/// subsistence threshold.
|
||||
BelowSubsistenceThreshold = 4,
|
||||
/// Transfer failed for other reasons. Most probably reserved or locked balance of the
|
||||
/// sender prevents the transfer.
|
||||
/// Deprecated and no longer returned: There is only the minimum balance.
|
||||
_BelowSubsistenceThreshold = 4,
|
||||
/// See [`Error::TransferFailed`].
|
||||
TransferFailed = 5,
|
||||
/// The newly created contract is below the subsistence threshold after executing
|
||||
/// its constructor.
|
||||
NewContractNotFunded = 6,
|
||||
/// Deprecated and no longer returned: Endowment is no longer required.
|
||||
_EndowmentTooLow = 6,
|
||||
/// No code could be found at the supplied code hash.
|
||||
CodeNotFound = 7,
|
||||
/// The contract that was called is no contract (a plain account).
|
||||
@@ -151,8 +148,6 @@ pub enum RuntimeCosts {
|
||||
ValueTransferred,
|
||||
/// Weight of calling `seal_minimum_balance`.
|
||||
MinimumBalance,
|
||||
/// Weight of calling `seal_contract_deposit`.
|
||||
ContractDeposit,
|
||||
/// Weight of calling `seal_block_number`.
|
||||
BlockNumber,
|
||||
/// Weight of calling `seal_now`.
|
||||
@@ -231,7 +226,6 @@ impl RuntimeCosts {
|
||||
Balance => s.balance,
|
||||
ValueTransferred => s.value_transferred,
|
||||
MinimumBalance => s.minimum_balance,
|
||||
ContractDeposit => s.contract_deposit,
|
||||
BlockNumber => s.block_number,
|
||||
Now => s.now,
|
||||
WeightToFee => s.weight_to_fee,
|
||||
@@ -611,16 +605,12 @@ where
|
||||
fn err_into_return_code(from: DispatchError) -> Result<ReturnCode, DispatchError> {
|
||||
use ReturnCode::*;
|
||||
|
||||
let below_sub = Error::<E::T>::BelowSubsistenceThreshold.into();
|
||||
let transfer_failed = Error::<E::T>::TransferFailed.into();
|
||||
let not_funded = Error::<E::T>::NewContractNotFunded.into();
|
||||
let no_code = Error::<E::T>::CodeNotFound.into();
|
||||
let not_found = Error::<E::T>::ContractNotFound.into();
|
||||
|
||||
match from {
|
||||
x if x == below_sub => Ok(BelowSubsistenceThreshold),
|
||||
x if x == transfer_failed => Ok(TransferFailed),
|
||||
x if x == not_funded => Ok(NewContractNotFunded),
|
||||
x if x == no_code => Ok(CodeNotFound),
|
||||
x if x == not_found => Ok(NotCallable),
|
||||
err => Err(err),
|
||||
@@ -837,7 +827,6 @@ define_env!(Env, <E: Ext>,
|
||||
//
|
||||
// # Errors
|
||||
//
|
||||
// `ReturnCode::BelowSubsistenceThreshold`
|
||||
// `ReturnCode::TransferFailed`
|
||||
[seal0] seal_transfer(
|
||||
ctx,
|
||||
@@ -925,7 +914,6 @@ define_env!(Env, <E: Ext>,
|
||||
//
|
||||
// `ReturnCode::CalleeReverted`: Output buffer is returned.
|
||||
// `ReturnCode::CalleeTrapped`
|
||||
// `ReturnCode::BelowSubsistenceThreshold`
|
||||
// `ReturnCode::TransferFailed`
|
||||
// `ReturnCode::NotCallable`
|
||||
[seal1] seal_call(
|
||||
@@ -1002,9 +990,8 @@ define_env!(Env, <E: Ext>,
|
||||
// length to `output_len_ptr`. The copy of the output buffer and address can be skipped by
|
||||
// supplying the sentinel value of `u32::MAX` to `output_ptr` or `address_ptr`.
|
||||
//
|
||||
// After running the constructor it is verified that the contract account holds at
|
||||
// least the subsistence threshold. If that is not the case the instantiation fails and
|
||||
// the contract is not created.
|
||||
// `value` must be at least the minimum balance. Otherwise the instantiation fails and the
|
||||
// contract is not created.
|
||||
//
|
||||
// # Parameters
|
||||
//
|
||||
@@ -1033,9 +1020,7 @@ define_env!(Env, <E: Ext>,
|
||||
//
|
||||
// `ReturnCode::CalleeReverted`: Output buffer is returned.
|
||||
// `ReturnCode::CalleeTrapped`
|
||||
// `ReturnCode::BelowSubsistenceThreshold`
|
||||
// `ReturnCode::TransferFailed`
|
||||
// `ReturnCode::NewContractNotFunded`
|
||||
// `ReturnCode::CodeNotFound`
|
||||
[seal1] seal_instantiate(
|
||||
ctx,
|
||||
@@ -1082,7 +1067,7 @@ define_env!(Env, <E: Ext>,
|
||||
ctx.terminate(beneficiary_ptr)
|
||||
},
|
||||
|
||||
// Remove the calling account and transfer remaining balance.
|
||||
// Remove the calling account and transfer remaining **free** balance.
|
||||
//
|
||||
// This function never returns. Either the termination was successful and the
|
||||
// execution of the destroyed contract is halted. Or it failed during the termination
|
||||
@@ -1215,7 +1200,7 @@ define_env!(Env, <E: Ext>,
|
||||
)?)
|
||||
},
|
||||
|
||||
// Stores the balance of the current account into the supplied buffer.
|
||||
// Stores the **free* balance of the current account into the supplied buffer.
|
||||
//
|
||||
// The value is stored to linear memory at the address pointed to by `out_ptr`.
|
||||
// `out_len_ptr` must point to a u32 value that describes the available space at
|
||||
@@ -1230,7 +1215,7 @@ define_env!(Env, <E: Ext>,
|
||||
)?)
|
||||
},
|
||||
|
||||
// Stores the value transferred along with this call or as endowment into the supplied buffer.
|
||||
// Stores the value transferred along with this call/instantiate into the supplied buffer.
|
||||
//
|
||||
// The value is stored to linear memory at the address pointed to by `out_ptr`.
|
||||
// `out_len_ptr` must point to a u32 value that describes the available space at
|
||||
@@ -1323,38 +1308,20 @@ define_env!(Env, <E: Ext>,
|
||||
)?)
|
||||
},
|
||||
|
||||
// Stores the contract deposit into the supplied buffer.
|
||||
//
|
||||
// # Deprecation
|
||||
//
|
||||
// This is equivalent to calling `seal_contract_deposit` and only exists for backwards
|
||||
// compatibility. See that function for documentation.
|
||||
[seal0] seal_tombstone_deposit(ctx, out_ptr: u32, out_len_ptr: u32) => {
|
||||
ctx.charge_gas(RuntimeCosts::ContractDeposit)?;
|
||||
Ok(ctx.write_sandbox_output(
|
||||
out_ptr, out_len_ptr, &ctx.ext.contract_deposit().encode(), false, already_charged
|
||||
)?)
|
||||
},
|
||||
|
||||
// Stores the contract deposit into the supplied buffer.
|
||||
// Stores the tombstone deposit into the supplied buffer.
|
||||
//
|
||||
// The value is stored to linear memory at the address pointed to by `out_ptr`.
|
||||
// `out_len_ptr` must point to a u32 value that describes the available space at
|
||||
// `out_ptr`. This call overwrites it with the size of the value. If the available
|
||||
// space at `out_ptr` is less than the size of the value a trap is triggered.
|
||||
//
|
||||
// The data is encoded as T::Balance.
|
||||
// # Deprecation
|
||||
//
|
||||
// # Note
|
||||
//
|
||||
// The contract deposit is on top of the existential deposit. The sum
|
||||
// is commonly referred as subsistence threshold in code. No contract initiated
|
||||
// balance transfer can go below this threshold.
|
||||
[seal0] seal_contract_deposit(ctx, out_ptr: u32, out_len_ptr: u32) => {
|
||||
ctx.charge_gas(RuntimeCosts::ContractDeposit)?;
|
||||
Ok(ctx.write_sandbox_output(
|
||||
out_ptr, out_len_ptr, &ctx.ext.contract_deposit().encode(), false, already_charged
|
||||
)?)
|
||||
// There is no longer a tombstone deposit. This function always returns 0.
|
||||
[seal0] seal_tombstone_deposit(ctx, out_ptr: u32, out_len_ptr: u32) => {
|
||||
ctx.charge_gas(RuntimeCosts::Balance)?;
|
||||
let deposit = <BalanceOf<E::T>>::zero().encode();
|
||||
Ok(ctx.write_sandbox_output(out_ptr, out_len_ptr, &deposit, false, already_charged)?)
|
||||
},
|
||||
|
||||
// Was used to restore the given destination contract sacrificing the caller.
|
||||
|
||||
Reference in New Issue
Block a user