Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Contracts: migrate to fungible traits #14020

Merged
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
130 commits
Select commit Hold shift + click to select a range
7179359
contracts: refactor currency to use fungible traits
juangirini Apr 26, 2023
c0a95d2
contracts: refactor currency to use fungible traits
juangirini Apr 26, 2023
da7db01
contracts: merge master and resolve conflicts
juangirini May 2, 2023
9a1e824
Merge branch 'master' into jg/13643-contracts-migrate-to-fungible-traits
juangirini May 2, 2023
5eee859
contracts: add minor improvements
juangirini May 3, 2023
713a426
contracts: merge master and fix conflicts
juangirini May 8, 2023
4acbbe5
contracts: max holds config set
juangirini May 8, 2023
e6d82d1
contracts: fix some typos
juangirini May 8, 2023
c47ac0d
contracts: map token errors
juangirini May 8, 2023
4e8a7cc
fix typo
juangirini May 8, 2023
33229ff
contracts: add 0 balance transfer to test
juangirini May 8, 2023
a1fd020
contracts: not transfer if value is zero
juangirini May 9, 2023
0967556
contracts: [WIP] add StorageDepositHold
juangirini May 11, 2023
3acdcbb
Merge branch 'master' into jg/13643-contracts-migrate-to-fungible-traits
juangirini May 11, 2023
bcb9077
contracts: add storage deposit held event
juangirini May 11, 2023
8f244c4
contracts: clean up some code and comments
juangirini May 11, 2023
73b9285
contracts: add deposit storage released event
juangirini May 11, 2023
26472d5
contracts: update comment
juangirini May 12, 2023
c442b79
contracts: update slash cannot kill account test
juangirini May 12, 2023
3c515ab
contracts: fix tests
juangirini May 12, 2023
4d68a48
contracts: add some comments to the slashing test
juangirini May 12, 2023
78fc19e
contracts: add some comments to the slashing test
juangirini May 12, 2023
2c1e2ea
contracts: remove references to Currency
juangirini May 15, 2023
e6509d7
Merge branch 'master' into jg/13643-contracts-migrate-to-fungible-traits
juangirini May 15, 2023
1c82bef
contracts: do not transfer if from equals to
juangirini May 15, 2023
9eb19ef
wip
juangirini Jun 2, 2023
e4853e9
Merge remote-tracking branch 'origin/master' into jg/13643-contracts-…
juangirini Jun 5, 2023
921d89c
bound BalanceOf<T>
juangirini Jun 6, 2023
a103057
added FixedPointOperand to Balance trait
juangirini Jun 6, 2023
5c14529
move migrate sequence to config
juangirini Jun 6, 2023
e8c493c
remove commented out code
juangirini Jun 6, 2023
0e62930
Update frame/contracts/src/lib.rs
juangirini Jun 6, 2023
14a7175
remove Migrations generic
juangirini Jun 6, 2023
2601d79
make runtime use noop migrations
juangirini Jun 6, 2023
e88854a
restrict is_upgrade_supported
juangirini Jun 6, 2023
1400ab0
undo is_upgrade_supported change
juangirini Jun 7, 2023
cc7609c
Update bin/node/runtime/src/lib.rs
juangirini Jun 7, 2023
c173ad7
add rust doc example for `Migrations`
juangirini Jun 7, 2023
c9cf9c6
feature gate NoopMigration
juangirini Jun 7, 2023
de545a3
fix example code
juangirini Jun 7, 2023
62bec96
improve example
juangirini Jun 8, 2023
f446edc
wip
juangirini Jun 8, 2023
de67661
rebase and fix conflicts
juangirini Jun 8, 2023
a1b9d71
remove FixedPointOperand from trait
juangirini Jun 9, 2023
c68288f
trait bound BalanceOf
juangirini Jun 13, 2023
9a813ef
more trait bound BalanceOf
juangirini Jun 13, 2023
9cddbef
rebase
juangirini Jun 15, 2023
11308f5
update to use RuntimeHoldReason
juangirini Jun 16, 2023
f4e1e53
replace Fungible for Currency
juangirini Jun 16, 2023
4da6b17
update runtime
juangirini Jun 16, 2023
790a8d2
WIP
juangirini Jun 27, 2023
1922bfe
make v10 benchmark generic over currency
juangirini Jul 3, 2023
b2da991
rebase and solve conflicts
juangirini Jul 3, 2023
d3ea9e2
solve merge conflicts
juangirini Jul 4, 2023
3673892
rebase and solve conflicts
juangirini Jul 4, 2023
e6201c1
make v12 migration benchmarking generic over DepositPerItem and Depos…
juangirini Jul 6, 2023
22fd924
give some format
juangirini Jul 6, 2023
013dc41
rebase and fix conflicts
juangirini Jul 6, 2023
f8da1e0
fix tests and old migrations
juangirini Jul 7, 2023
e29f2d4
add migration v13 placholder
juangirini Jul 11, 2023
ca8772a
rebase and fix errors\
juangirini Jul 11, 2023
6df91bd
wip
juangirini Jul 11, 2023
eb9c56a
wip
juangirini Jul 12, 2023
7f18359
rebase and merge conflicts
juangirini Jul 12, 2023
ab1af04
add benchmarking
juangirini Jul 12, 2023
316ab36
add weights
juangirini Jul 13, 2023
5209d01
wip
juangirini Jul 13, 2023
0cd0830
[pallet_collective] Enforce prime is a valid member of collective in …
ToufeeqP Jul 12, 2023
de849d2
update to docify 0.2.0 / crate-relative embed paths (#14570)
sam0x17 Jul 13, 2023
adba2c9
Fix Society v2 migration (#14421)
liamaharon Jul 13, 2023
9a42019
Moves `Block` to `frame_system` instead of `construct_runtime` and re…
gupnik Jul 13, 2023
1744884
Refactor the asset-conversion-tx-payment pallet (#14558)
jsidorenko Jul 13, 2023
15634c2
wip
juangirini Jul 13, 2023
c2eb60d
rebase and fix conflicts
juangirini Jul 14, 2023
1775efa
wip
juangirini Jul 14, 2023
cb1adf3
Merge remote-tracking branch 'origin/master' into jg/13643-contracts-…
juangirini Jul 17, 2023
12c522c
wip
juangirini Jul 17, 2023
6fb9713
improve try-runtime imports
juangirini Jul 17, 2023
cdd0ca4
fix benchmark test
juangirini Jul 18, 2023
ae4fda2
improved rustdocs
juangirini Jul 18, 2023
f5e4b20
improved rustdocs
juangirini Jul 18, 2023
cb9217d
remove log
juangirini Jul 18, 2023
36f936a
Merge branch 'master' into jg/13643-contracts-migrate-to-fungible-traits
juangirini Jul 19, 2023
632ef2e
ignore variable
juangirini Jul 19, 2023
bc8efaf
reduce caller funding
juangirini Jul 19, 2023
7c97aae
move v13 out
juangirini Jul 21, 2023
a96a50e
update v13 migration
juangirini Jul 21, 2023
c67ea9f
v13 migration
juangirini Jul 24, 2023
ad7fa61
benchmark v13_migration
juangirini Jul 24, 2023
6e6fdb3
fix broken compilation
juangirini Jul 24, 2023
ae5d558
Merge branch 'master' of https://github.com/paritytech/substrate into…
Jul 24, 2023
90de832
".git/.scripts/commands/bench/bench.sh" --subcommand=pallet --runtime…
Jul 24, 2023
55fd7ce
remove all the `where BalanceOf`
juangirini Jul 25, 2023
50e0348
add Balance to Config
juangirini Jul 25, 2023
199a6f5
Merge remote-tracking branch 'origin/master' into jg/13643-contracts-…
juangirini Jul 25, 2023
05299ae
Merge remote-tracking branch 'origin/master' into jg/13643-contracts-…
juangirini Jul 25, 2023
a741737
improve docs
juangirini Jul 25, 2023
3950327
add new deposit storage error
juangirini Jul 25, 2023
0a790a6
remove todo message
juangirini Jul 25, 2023
0c57451
rename migration v13 pre rebase
juangirini Jul 26, 2023
ec5415f
rebase
juangirini Jul 26, 2023
560d190
fix tests
juangirini Jul 26, 2023
ed3b399
add missing migration;
juangirini Jul 26, 2023
8186e21
bump storage version
juangirini Jul 27, 2023
08619a0
apply review suggestions
juangirini Jul 27, 2023
9435d4b
improved comment
juangirini Jul 27, 2023
06f7941
remove unnecessary code
juangirini Jul 27, 2023
eec1d20
simplify migrations
juangirini Jul 27, 2023
8b69d3e
mock balance
juangirini Jul 28, 2023
38c044c
mock more for benchmarks
juangirini Jul 28, 2023
48ce88c
rebase and merge conflicts
juangirini Jul 28, 2023
4cd120f
fix benchmarking tests
juangirini Jul 28, 2023
f08f844
fix benchmarking tests with caller
juangirini Jul 28, 2023
da6e8c1
improve cargo toml
juangirini Jul 28, 2023
3e6ce6a
solve nit
juangirini Jul 28, 2023
0ce5815
Update frame/contracts/src/lib.rs
juangirini Jul 31, 2023
3054dce
Update frame/contracts/src/exec.rs
juangirini Jul 31, 2023
b0a6d39
Update frame/contracts/src/exec.rs
juangirini Jul 31, 2023
49d8f7f
Update frame/contracts/src/storage/meter.rs
juangirini Jul 31, 2023
432ea07
review improvements
juangirini Jul 31, 2023
ae7ddf7
Merge remote-tracking branch 'origin/master' into jg/13643-contracts-…
juangirini Jul 31, 2023
a7bf911
remove extra events
juangirini Jul 31, 2023
41812ef
update cargo
juangirini Jul 31, 2023
2ed2c85
undo update cargo
juangirini Jul 31, 2023
49efe87
review updates
juangirini Aug 1, 2023
c9673f6
rebase and fix conflicts
juangirini Aug 1, 2023
90c4c84
rebase and fix conflicts
juangirini Aug 2, 2023
5c668aa
remove type Balance
juangirini Aug 2, 2023
39e83cc
add extra fields to events
juangirini Aug 2, 2023
aae16cc
fix zepter ci
juangirini Aug 2, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 16 additions & 14 deletions frame/contracts/src/exec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,9 @@ use frame_support::{
},
storage::{with_transaction, TransactionOutcome},
traits::{
tokens::{Fortitude::Polite, Preservation::Expendable},
Contains, Currency, ExistenceRequirement, OriginTrait, Randomness, Time,
fungible::{Inspect, Mutate},
tokens::{Fortitude::Polite, Preservation},
Contains, OriginTrait, Randomness, Time,
},
weights::Weight,
Blake2_128Concat, BoundedVec, StorageHasher,
Expand Down Expand Up @@ -1061,13 +1062,15 @@ where

/// Transfer some funds from `from` to `to`.
fn transfer(
existence_requirement: ExistenceRequirement,
preservation: Preservation,
from: &T::AccountId,
to: &T::AccountId,
value: BalanceOf<T>,
) -> DispatchResult {
T::Currency::transfer(from, to, value, existence_requirement)
.map_err(|_| Error::<T>::TransferFailed)?;
if !value.is_zero() {
T::Currency::transfer(from, to, value, preservation)
.map_err(|_| Error::<T>::TransferFailed)?;
}
Ok(())
}

Expand All @@ -1091,7 +1094,7 @@ where
Origin::Root if value.is_zero() => return Ok(()),
Origin::Root => return DispatchError::RootNotAllowed.into(),
};
Self::transfer(ExistenceRequirement::KeepAlive, &caller, &frame.account_id, value)
Self::transfer(Preservation::Protect, &caller, &frame.account_id, value)
juangirini marked this conversation as resolved.
Show resolved Hide resolved
}

/// Reference to the current (top) frame.
Expand Down Expand Up @@ -1239,19 +1242,18 @@ where
}

fn terminate(&mut self, beneficiary: &AccountIdOf<Self::T>) -> Result<(), DispatchError> {
use frame_support::traits::fungible::Inspect;
if self.is_recursive() {
return Err(Error::<T>::TerminatedWhileReentrant.into())
}
let frame = self.top_frame_mut();
let info = frame.terminate();
frame.nested_storage.terminate(&info);
System::<T>::dec_consumers(&frame.account_id);
T::Currency::transfer(
Self::transfer(
Preservation::Expendable,
&frame.account_id,
beneficiary,
T::Currency::reducible_balance(&frame.account_id, Expendable, Polite),
ExistenceRequirement::AllowDeath,
T::Currency::reducible_balance(&frame.account_id, Preservation::Expendable, Polite),
)?;
info.queue_trie_for_deletion();
ContractInfoOf::<T>::remove(&frame.account_id);
Expand All @@ -1267,7 +1269,7 @@ where
}

fn transfer(&mut self, to: &T::AccountId, value: BalanceOf<T>) -> DispatchResult {
Self::transfer(ExistenceRequirement::KeepAlive, &self.top_frame().account_id, to, value)
Self::transfer(Preservation::Protect, &self.top_frame().account_id, to, value)
juangirini marked this conversation as resolved.
Show resolved Hide resolved
}

fn get_storage(&mut self, key: &Key<T>) -> Option<Vec<u8>> {
Expand Down Expand Up @@ -1330,7 +1332,7 @@ where
}

fn balance(&self) -> BalanceOf<T> {
T::Currency::free_balance(&self.top_frame().account_id)
T::Currency::balance(&self.top_frame().account_id)
}

fn value_transferred(&self) -> BalanceOf<T> {
Expand Down Expand Up @@ -1694,7 +1696,7 @@ mod tests {
set_balance(&origin, 100);
set_balance(&dest, 0);

MockStack::transfer(ExistenceRequirement::KeepAlive, &origin, &dest, 55).unwrap();
MockStack::transfer(Preservation::Protect, &origin, &dest, 55).unwrap();
juangirini marked this conversation as resolved.
Show resolved Hide resolved

assert_eq!(get_balance(&origin), 45);
assert_eq!(get_balance(&dest), 55);
Expand Down Expand Up @@ -1832,7 +1834,7 @@ mod tests {
ExtBuilder::default().build().execute_with(|| {
set_balance(&origin, 0);

let result = MockStack::transfer(ExistenceRequirement::KeepAlive, &origin, &dest, 100);
let result = MockStack::transfer(Preservation::Protect, &origin, &dest, 100);
juangirini marked this conversation as resolved.
Show resolved Hide resolved

assert_eq!(result, Err(Error::<Test>::TransferFailed.into()));
assert_eq!(get_balance(&origin), 0);
Expand Down
51 changes: 42 additions & 9 deletions frame/contracts/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@
//!
//! ## Overview
//!
//! This module extends accounts based on the [`Currency`] trait to have smart-contract
//! functionality. It can be used with other modules that implement accounts based on [`Currency`].
//! These "smart-contract accounts" have the ability to instantiate smart-contracts and make calls
//! to other contract and non-contract accounts.
//! This module extends accounts based on the [`fungible`] traits to have smart-contract
//! functionality. It can be used with other modules that implement accounts based on [`fungible`]
//! traits. These "smart-contract accounts" have the ability to instantiate smart-contracts and make
//! calls to other contract and non-contract accounts.
//!
//! The smart-contract code is stored once in a code cache, and later retrievable via its hash.
//! This means that multiple smart-contracts can be instantiated from the same hash, without
Expand Down Expand Up @@ -111,8 +111,8 @@ use frame_support::{
ensure,
error::BadOrigin,
traits::{
tokens::fungible::Inspect, ConstU32, Contains, Currency, Get, Randomness,
ReservableCurrency, Time,
fungible::{Inspect, InspectHold, Mutate, MutateHold},
ConstU32, Contains, Get, Randomness, Time,
},
weights::Weight,
BoundedVec, RuntimeDebugNoBound, WeakBoundedVec,
Expand Down Expand Up @@ -143,7 +143,7 @@ pub use crate::wasm::api_doc;
type CodeHash<T> = <T as frame_system::Config>::Hash;
type TrieId = BoundedVec<u8, ConstU32<128>>;
type BalanceOf<T> =
<<T as Config>::Currency as Currency<<T as frame_system::Config>::AccountId>>::Balance;
<<T as Config>::Currency as Inspect<<T as frame_system::Config>::AccountId>>::Balance;
type CodeVec<T> = BoundedVec<u8, <T as Config>::MaxCodeLen>;
type RelaxedCodeVec<T> = WeakBoundedVec<u8, <T as Config>::MaxCodeLen>;
type AccountIdLookupOf<T> = <<T as frame_system::Config>::Lookup as StaticLookup>::Source;
Expand Down Expand Up @@ -201,8 +201,9 @@ pub mod pallet {
type Randomness: Randomness<Self::Hash, Self::BlockNumber>;

/// The currency in which fees are paid and contract balances are held.
type Currency: ReservableCurrency<Self::AccountId> // TODO: Move to fungible traits
+ Inspect<Self::AccountId, Balance = BalanceOf<Self>>;
type Currency: Inspect<Self::AccountId>
+ Mutate<Self::AccountId>
+ MutateHold<Self::AccountId>;

/// The overarching event type.
type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
Expand Down Expand Up @@ -311,6 +312,10 @@ pub mod pallet {
/// The maximum length of the debug buffer in bytes.
#[pallet::constant]
type MaxDebugBufferLen: Get<u32>;

/// The identifier of the hold reason.
#[pallet::constant]
type HoldReason: Get<<Self::Currency as InspectHold<Self::AccountId>>::Reason>;
}

#[pallet::hooks]
Expand Down Expand Up @@ -782,6 +787,12 @@ pub mod pallet {
/// The code hash that was delegate called.
code_hash: CodeHash<T>,
},

StorageDepositHeld {
who: T::AccountId,
amount: BalanceOf<T>,
// reason: <T::Currency as InspectHold<T::AccountId>>::Reason,
},
}

#[pallet::error]
Expand Down Expand Up @@ -863,6 +874,14 @@ pub mod pallet {
Indeterministic,
}

/// A reason for the pallet contracts placing a hold on funds.
#[pallet::composite_enum]
pub enum HoldReason {
/// The Pallet has reserved it for storage deposit.
#[codec(index = 0)]
StorageDepositReserve,
}

/// A mapping from an original code hash to the original code, untouched by instrumentation.
#[pallet::storage]
pub(crate) type PristineCode<T: Config> = StorageMap<_, Identity, CodeHash<T>, CodeVec<T>>;
Expand Down Expand Up @@ -1210,6 +1229,20 @@ impl<T: Config> Invokable<T> for InstantiateInput<T> {
}
}

// pub trait StorageDepositHold<AccountId>: MutateHold<AccountId> {
// fn done_hold<T: Config>(reason: &Self::Reason, who: &T::AccountId, amount: Self::Balance) {
// // let reason = HoldReason::StorageDepositReserve;
// <Pallet<T>>::deposit_event(
// vec![
// T::Hashing::hash_of(who),
// T::Hashing::hash_of(&amount),
// T::Hashing::hash_of(&reason),
// ],
// Event::Held { who: who.clone() },
// );
// }
// }

impl<T: Config> Pallet<T> {
/// Perform a call to a specified contract.
///
Expand Down
27 changes: 14 additions & 13 deletions frame/contracts/src/storage/meter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,9 @@ use frame_support::{
dispatch::{fmt::Debug, DispatchError},
ensure,
traits::{
tokens::{Fortitude::Polite, Preservation::Protect, WithdrawConsequence},
Currency, ExistenceRequirement, Get,
fungible::Mutate,
tokens::{Fortitude::Polite, Preservation, WithdrawConsequence},
Get,
},
DefaultNoBound, RuntimeDebugNoBound,
};
Expand Down Expand Up @@ -448,7 +449,7 @@ where
System::<T>::inc_consumers(info.deposit_account())?;

// We also need to make sure that the contract's account itself exists.
T::Currency::transfer(origin, contract, ed, ExistenceRequirement::KeepAlive)?;
T::Currency::transfer(origin, contract, ed, Preservation::Protect)?;
juangirini marked this conversation as resolved.
Show resolved Hide resolved
System::<T>::inc_consumers(contract)?;

Ok(deposit)
Expand Down Expand Up @@ -512,7 +513,7 @@ impl<T: Config> Ext<T> for ReservingExt {
// We are sending the `min_leftover` and the `min_balance` from the origin
// account as part of a contract call. Hence origin needs to have those left over
// as free balance after accounting for all deposits.
let max = T::Currency::reducible_balance(origin, Protect, Polite)
let max = T::Currency::reducible_balance(origin, Preservation::Protect, Polite)
juangirini marked this conversation as resolved.
Show resolved Hide resolved
.saturating_sub(min_leftover)
.saturating_sub(Pallet::<T>::min_balance());
let default = max.min(T::DefaultDepositLimit::get());
Expand All @@ -532,12 +533,10 @@ impl<T: Config> Ext<T> for ReservingExt {
terminated: bool,
) -> Result<(), DispatchError> {
match amount {
Deposit::Charge(amount) => T::Currency::transfer(
origin,
deposit_account,
*amount,
ExistenceRequirement::KeepAlive,
),
Deposit::Charge(amount) => {
T::Currency::transfer(origin, deposit_account, *amount, Preservation::Protect)?;
juangirini marked this conversation as resolved.
Show resolved Hide resolved
Ok(())
},
Deposit::Refund(amount) => {
if terminated {
System::<T>::dec_consumers(&deposit_account);
Expand All @@ -546,9 +545,11 @@ impl<T: Config> Ext<T> for ReservingExt {
deposit_account,
origin,
*amount,
// We can safely use `AllowDeath` because our own consumer prevents an removal.
ExistenceRequirement::AllowDeath,
)
// We can safely make it `Expendable` because our own consumer prevents an
// removal.
juangirini marked this conversation as resolved.
Show resolved Hide resolved
Preservation::Expendable,
)?;
Ok(())
},
}
}
Expand Down
16 changes: 13 additions & 3 deletions frame/contracts/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ use crate::{
DefaultAddressGenerator, DeletionQueueCounter, Error, Origin, Pallet, Schedule,
};
use assert_matches::assert_matches;
use codec::Encode;
use codec::{Decode, Encode, MaxEncodedLen};
use frame_support::{
assert_err, assert_err_ignore_postinfo, assert_err_with_weight, assert_noop, assert_ok,
dispatch::{DispatchError, DispatchErrorWithPostInfo, PostDispatchInfo},
Expand All @@ -45,6 +45,7 @@ use frame_support::{
};
use frame_system::{EventRecord, Phase};
use pretty_assertions::{assert_eq, assert_ne};
use scale_info::TypeInfo;
use sp_core::ByteArray;
use sp_io::hashing::blake2_256;
use sp_keystore::{testing::MemoryKeystore, KeystoreExt};
Expand Down Expand Up @@ -322,8 +323,8 @@ impl pallet_balances::Config for Test {
type WeightInfo = ();
type FreezeIdentifier = ();
type MaxFreezes = ();
type HoldIdentifier = ();
type MaxHolds = ();
type HoldIdentifier = HoldIdentifier;
type MaxHolds = ConstU32<1>;
}

impl pallet_timestamp::Config for Test {
Expand Down Expand Up @@ -386,6 +387,13 @@ impl Default for Filters {
}
}

#[derive(
Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, MaxEncodedLen, Debug, TypeInfo,
)]
pub enum HoldIdentifier {
StorageDepositReserve,
}

parameter_types! {
static CallFilter: Filters = Default::default();
}
Expand All @@ -404,6 +412,7 @@ impl Contains<RuntimeCall> for TestFilter {

parameter_types! {
pub static UnstableInterface: bool = true;
pub const HoldReason: HoldIdentifier = HoldIdentifier::StorageDepositReserve;
}

impl Config for Test {
Expand All @@ -427,6 +436,7 @@ impl Config for Test {
type MaxStorageKeyLen = ConstU32<128>;
type UnsafeUnstableInterface = UnstableInterface;
type MaxDebugBufferLen = ConstU32<{ 2 * 1024 * 1024 }>;
type HoldReason = HoldReason;
}

pub const ALICE: AccountId32 = AccountId32::new([1u8; 32]);
Expand Down
34 changes: 29 additions & 5 deletions frame/contracts/src/wasm/code_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,11 @@ use crate::{
use frame_support::{
dispatch::{DispatchError, DispatchResult},
ensure,
traits::{Get, ReservableCurrency},
traits::{fungible::MutateHold, tokens::Precision::BestEffort, Get},
WeakBoundedVec,
};
use sp_runtime::traits::BadOrigin;
use sp_api::HashT;
use sp_runtime::{traits::BadOrigin, TokenError};
use sp_std::vec;

/// Put the instrumented module in storage.
Expand Down Expand Up @@ -95,8 +96,26 @@ pub fn store<T: Config>(mut module: PrefabWasmModule<T>, instantiated: bool) ->
);
// This `None` case happens only in freshly uploaded modules. This means that
// the `owner` is always the origin of the current transaction.
T::Currency::reserve(&new_owner_info.owner, new_owner_info.deposit)
.map_err(|_| <Error<T>>::StorageDepositNotEnoughFunds)?;
T::Currency::hold(
&T::HoldReason::get(),
&new_owner_info.owner,
new_owner_info.deposit,
)
.map_err(|e| match e {
DispatchError::Token(TokenError::FundsUnavailable) =>
<Error<T>>::StorageDepositNotEnoughFunds.into(),
_ => e,
})?;
<Pallet<T>>::deposit_event(
vec![
T::Hashing::hash_of(&new_owner_info.owner),
T::Hashing::hash_of(&new_owner_info.deposit),
],
Event::StorageDepositHeld {
who: new_owner_info.owner.clone(),
amount: new_owner_info.deposit.clone(),
},
juangirini marked this conversation as resolved.
Show resolved Hide resolved
);
new_owner_info.refcount = if instantiated { 1 } else { 0 };
<PristineCode<T>>::insert(&code_hash, orig_code);
<CodeStorage<T>>::insert(&code_hash, module);
Expand Down Expand Up @@ -144,7 +163,12 @@ pub fn try_remove<T: Config>(origin: &T::AccountId, code_hash: CodeHash<T>) -> D
if let Some(owner_info) = existing {
ensure!(owner_info.refcount == 0, <Error<T>>::CodeInUse);
ensure!(&owner_info.owner == origin, BadOrigin);
T::Currency::unreserve(&owner_info.owner, owner_info.deposit);
T::Currency::release(
&T::HoldReason::get(),
&owner_info.owner,
owner_info.deposit,
BestEffort,
)?;
*existing = None;
<PristineCode<T>>::remove(&code_hash);
<CodeStorage<T>>::remove(&code_hash);
Expand Down
Loading