mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-06 03:18:01 +00:00
Make automatic storage deposits resistant against changing deposit prices (#12083)
* Require `FixedPointOperand` for Balances * Delay deposit calculation * Make refunds pro rata of consumed storage * Add storage migration * Fix clippy * Add liquidity checks * Fixe delayed deposit limit enforcement * Defer charges * Import Vec * Add try-runtime hooks for migration * Fix warning * Adapt to new OnRuntimeUpgrade trait * Apply suggestions from code review Co-authored-by: Sasha Gryaznov <hi@agryaznov.com> * fmt * Apply suggestions from code review Co-authored-by: Sasha Gryaznov <hi@agryaznov.com> * More suggestions from code review Co-authored-by: Sasha Gryaznov <hi@agryaznov.com>
This commit is contained in:
committed by
GitHub
parent
cb82064cb8
commit
857c3bf37b
@@ -34,31 +34,51 @@ use scale_info::TypeInfo;
|
||||
use sp_core::crypto::UncheckedFrom;
|
||||
use sp_io::KillStorageResult;
|
||||
use sp_runtime::{
|
||||
traits::{Hash, Zero},
|
||||
traits::{Hash, Saturating, Zero},
|
||||
RuntimeDebug,
|
||||
};
|
||||
use sp_std::{marker::PhantomData, prelude::*};
|
||||
|
||||
pub type ContractInfo<T> = RawContractInfo<CodeHash<T>, BalanceOf<T>>;
|
||||
|
||||
/// 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)]
|
||||
pub struct RawContractInfo<CodeHash, Balance> {
|
||||
#[scale_info(skip_type_params(T))]
|
||||
pub struct ContractInfo<T: Config> {
|
||||
/// Unique ID for the subtree encoded as a bytes vector.
|
||||
pub trie_id: TrieId,
|
||||
/// The code associated with a given account.
|
||||
pub code_hash: CodeHash,
|
||||
/// The amount of balance that is currently deposited to pay for consumed storage.
|
||||
pub storage_deposit: Balance,
|
||||
pub code_hash: CodeHash<T>,
|
||||
/// How many bytes of storage are accumulated in this contract's child trie.
|
||||
pub storage_bytes: u32,
|
||||
/// How many items of storage are accumulated in this contract's child trie.
|
||||
pub storage_items: u32,
|
||||
/// This records to how much deposit the accumulated `storage_bytes` amount to.
|
||||
pub storage_byte_deposit: BalanceOf<T>,
|
||||
/// This records to how much deposit the accumulated `storage_items` amount to.
|
||||
pub storage_item_deposit: BalanceOf<T>,
|
||||
/// This records how much deposit is put down in order to pay for the contract itself.
|
||||
///
|
||||
/// 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.
|
||||
pub storage_base_deposit: BalanceOf<T>,
|
||||
}
|
||||
|
||||
impl<CodeHash, Balance> RawContractInfo<CodeHash, Balance> {
|
||||
impl<T: Config> ContractInfo<T> {
|
||||
/// Associated child trie unique id is built from the hash part of the trie id.
|
||||
#[cfg(test)]
|
||||
pub fn child_trie_info(&self) -> ChildInfo {
|
||||
child_trie_info(&self.trie_id[..])
|
||||
}
|
||||
|
||||
/// The deposit paying for the accumulated storage generated within the contract's child trie.
|
||||
pub fn extra_deposit(&self) -> BalanceOf<T> {
|
||||
self.storage_byte_deposit.saturating_add(self.storage_item_deposit)
|
||||
}
|
||||
|
||||
/// Same as [`Self::extra_deposit`] but including the base deposit.
|
||||
pub fn total_deposit(&self) -> BalanceOf<T> {
|
||||
self.extra_deposit().saturating_add(self.storage_base_deposit)
|
||||
}
|
||||
}
|
||||
|
||||
/// Associated child trie unique id is built from the hash part of the trie id.
|
||||
@@ -178,7 +198,7 @@ where
|
||||
},
|
||||
(None, None) => (),
|
||||
}
|
||||
storage_meter.charge(&diff)?;
|
||||
storage_meter.charge(&diff);
|
||||
}
|
||||
|
||||
match &new_value {
|
||||
@@ -200,14 +220,21 @@ where
|
||||
pub fn new_contract(
|
||||
account: &AccountIdOf<T>,
|
||||
trie_id: TrieId,
|
||||
ch: CodeHash<T>,
|
||||
code_hash: CodeHash<T>,
|
||||
) -> Result<ContractInfo<T>, DispatchError> {
|
||||
if <ContractInfoOf<T>>::contains_key(account) {
|
||||
return Err(Error::<T>::DuplicateContract.into())
|
||||
}
|
||||
|
||||
let contract =
|
||||
ContractInfo::<T> { code_hash: ch, trie_id, storage_deposit: <BalanceOf<T>>::zero() };
|
||||
let contract = ContractInfo::<T> {
|
||||
code_hash,
|
||||
trie_id,
|
||||
storage_bytes: 0,
|
||||
storage_items: 0,
|
||||
storage_byte_deposit: Zero::zero(),
|
||||
storage_item_deposit: Zero::zero(),
|
||||
storage_base_deposit: Zero::zero(),
|
||||
};
|
||||
|
||||
Ok(contract)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user