mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-17 00:51:06 +00:00
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:
@@ -22,7 +22,7 @@ pub mod meter;
|
||||
use crate::{
|
||||
exec::{AccountIdOf, Key},
|
||||
weights::WeightInfo,
|
||||
AddressGenerator, BalanceOf, CodeHash, Config, ContractInfoOf, DeletionQueue,
|
||||
AddressGenerator, BalanceOf, CodeHash, CodeInfo, Config, ContractInfoOf, DeletionQueue,
|
||||
DeletionQueueCounter, Error, Pallet, TrieId, SENTINEL,
|
||||
};
|
||||
use codec::{Decode, Encode, MaxEncodedLen};
|
||||
@@ -30,19 +30,22 @@ use frame_support::{
|
||||
dispatch::DispatchError,
|
||||
storage::child::{self, ChildInfo},
|
||||
weights::Weight,
|
||||
DefaultNoBound, RuntimeDebugNoBound,
|
||||
CloneNoBound, DefaultNoBound, RuntimeDebugNoBound,
|
||||
};
|
||||
use scale_info::TypeInfo;
|
||||
use sp_core::Get;
|
||||
use sp_io::KillStorageResult;
|
||||
use sp_runtime::{
|
||||
traits::{Hash, Saturating, Zero},
|
||||
RuntimeDebug,
|
||||
BoundedBTreeMap, DispatchResult, RuntimeDebug,
|
||||
};
|
||||
use sp_std::{marker::PhantomData, ops::Deref, prelude::*};
|
||||
|
||||
use self::meter::Diff;
|
||||
|
||||
/// Information for managing an account and its sub trie abstraction.
|
||||
/// This is the required info to cache for an account.
|
||||
#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)]
|
||||
#[derive(Encode, Decode, CloneNoBound, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)]
|
||||
#[scale_info(skip_type_params(T))]
|
||||
pub struct ContractInfo<T: Config> {
|
||||
/// Unique ID for the subtree encoded as a bytes vector.
|
||||
@@ -66,6 +69,12 @@ pub struct ContractInfo<T: Config> {
|
||||
/// We need to store this information separately so it is not used when calculating any refunds
|
||||
/// since the base deposit can only ever be refunded on contract termination.
|
||||
storage_base_deposit: BalanceOf<T>,
|
||||
/// Map of code hashes and deposit balances.
|
||||
///
|
||||
/// Tracks the code hash and deposit held for adding delegate dependencies. Dependencies added
|
||||
/// to the map can not be removed from the chain state and can be safely used for delegate
|
||||
/// calls.
|
||||
delegate_dependencies: BoundedBTreeMap<CodeHash<T>, BalanceOf<T>, T::MaxDelegateDependencies>,
|
||||
}
|
||||
|
||||
impl<T: Config> ContractInfo<T> {
|
||||
@@ -101,6 +110,7 @@ impl<T: Config> ContractInfo<T> {
|
||||
storage_byte_deposit: Zero::zero(),
|
||||
storage_item_deposit: Zero::zero(),
|
||||
storage_base_deposit: Zero::zero(),
|
||||
delegate_dependencies: Default::default(),
|
||||
};
|
||||
|
||||
Ok(contract)
|
||||
@@ -123,11 +133,16 @@ impl<T: Config> ContractInfo<T> {
|
||||
.saturating_sub(Pallet::<T>::min_balance())
|
||||
}
|
||||
|
||||
/// Return the account that storage deposits should be deposited into.
|
||||
/// Returns the account that storage deposits should be deposited into.
|
||||
pub fn deposit_account(&self) -> &DepositAccount<T> {
|
||||
&self.deposit_account
|
||||
}
|
||||
|
||||
/// Returns the storage base deposit of the contract.
|
||||
pub fn storage_base_deposit(&self) -> BalanceOf<T> {
|
||||
self.storage_base_deposit
|
||||
}
|
||||
|
||||
/// Reads a storage kv pair of a contract.
|
||||
///
|
||||
/// The read is performed from the `trie_id` only. The `address` is not necessary. If the
|
||||
@@ -201,6 +216,68 @@ impl<T: Config> ContractInfo<T> {
|
||||
})
|
||||
}
|
||||
|
||||
/// Sets and returns the contract base deposit.
|
||||
///
|
||||
/// The base deposit is updated when the `code_hash` of the contract changes, as it depends on
|
||||
/// the deposit paid to upload the contract's code.
|
||||
pub fn update_base_deposit(&mut self, code_info: &CodeInfo<T>) -> BalanceOf<T> {
|
||||
let ed = Pallet::<T>::min_balance();
|
||||
let info_deposit =
|
||||
Diff { bytes_added: self.encoded_size() as u32, items_added: 1, ..Default::default() }
|
||||
.update_contract::<T>(None)
|
||||
.charge_or_zero();
|
||||
|
||||
// Instantiating the contract prevents its code to be deleted, therefore the base deposit
|
||||
// includes a fraction (`T::CodeHashLockupDepositPercent`) of the original storage deposit
|
||||
// to prevent abuse.
|
||||
let upload_deposit = T::CodeHashLockupDepositPercent::get().mul_ceil(code_info.deposit());
|
||||
|
||||
// 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.
|
||||
let deposit = info_deposit.saturating_add(upload_deposit).max(ed).saturating_add(ed);
|
||||
|
||||
self.storage_base_deposit = deposit;
|
||||
deposit
|
||||
}
|
||||
|
||||
/// Adds a new delegate dependency to the contract.
|
||||
/// The `amount` is the amount of funds that will be reserved for the dependency.
|
||||
///
|
||||
/// Returns an error if the maximum number of delegate_dependencies is reached or if
|
||||
/// the delegate dependency already exists.
|
||||
pub fn add_delegate_dependency(
|
||||
&mut self,
|
||||
code_hash: CodeHash<T>,
|
||||
amount: BalanceOf<T>,
|
||||
) -> DispatchResult {
|
||||
self.delegate_dependencies
|
||||
.try_insert(code_hash, amount)
|
||||
.map_err(|_| Error::<T>::MaxDelegateDependenciesReached)?
|
||||
.map_or(Ok(()), |_| Err(Error::<T>::DelegateDependencyAlreadyExists))
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
||||
/// Removes the delegate dependency from the contract and returns the deposit held for this
|
||||
/// dependency.
|
||||
///
|
||||
/// Returns an error if the entry doesn't exist.
|
||||
pub fn remove_delegate_dependency(
|
||||
&mut self,
|
||||
code_hash: &CodeHash<T>,
|
||||
) -> Result<BalanceOf<T>, DispatchError> {
|
||||
self.delegate_dependencies
|
||||
.remove(code_hash)
|
||||
.ok_or(Error::<T>::DelegateDependencyNotFound.into())
|
||||
}
|
||||
|
||||
/// Returns the delegate_dependencies of the contract.
|
||||
pub fn delegate_dependencies(
|
||||
&self,
|
||||
) -> &BoundedBTreeMap<CodeHash<T>, BalanceOf<T>, T::MaxDelegateDependencies> {
|
||||
&self.delegate_dependencies
|
||||
}
|
||||
|
||||
/// Push a contract's trie to the deletion queue for lazy removal.
|
||||
///
|
||||
/// You must make sure that the contract is also removed when queuing the trie for deletion.
|
||||
|
||||
Reference in New Issue
Block a user