mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-12 21:41:12 +00:00
seal: Fail instantiate if new contract is below subsistence threshold (#6719)
* seal: Fail instantiate if new contract is below subsistence threshold We need each contract that exists to be above the subsistence threshold in order to keep up the guarantuee that we always leave a tombstone behind with the exception of a contract that called `ext_terminate`. * Fixup executor test * Bump runtime
This commit is contained in:
committed by
GitHub
parent
63bd1d8346
commit
bead1becf0
@@ -591,6 +591,8 @@ fn deploying_wasm_contract_should_work() {
|
||||
&charlie(),
|
||||
);
|
||||
|
||||
let subsistence = pallet_contracts::Config::<Runtime>::subsistence_threshold_uncached();
|
||||
|
||||
let b = construct_block(
|
||||
&mut new_test_ext(compact_code_unwrap(), false),
|
||||
1,
|
||||
@@ -610,7 +612,7 @@ fn deploying_wasm_contract_should_work() {
|
||||
signed: Some((charlie(), signed_extra(1, 0))),
|
||||
function: Call::Contracts(
|
||||
pallet_contracts::Call::instantiate::<Runtime>(
|
||||
1 * DOLLARS,
|
||||
1 * DOLLARS + subsistence,
|
||||
500_000_000,
|
||||
transfer_ch,
|
||||
Vec::new()
|
||||
|
||||
@@ -105,7 +105,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
|
||||
// and set impl_version to 0. If only runtime
|
||||
// implementation changes and behavior does not, then leave spec_version as
|
||||
// is and increment impl_version.
|
||||
spec_version: 256,
|
||||
spec_version: 257,
|
||||
impl_version: 0,
|
||||
apis: RUNTIME_API_VERSIONS,
|
||||
transaction_version: 1,
|
||||
|
||||
@@ -426,7 +426,10 @@ where
|
||||
)?;
|
||||
|
||||
// Error out if insufficient remaining balance.
|
||||
if T::Currency::free_balance(&dest) < nested.config.existential_deposit {
|
||||
// We need each contract that exists to be above the subsistence threshold
|
||||
// in order to keep up the guarantuee that we always leave a tombstone behind
|
||||
// with the exception of a contract that called `ext_terminate`.
|
||||
if T::Currency::free_balance(&dest) < nested.config.subsistence_threshold() {
|
||||
Err("insufficient remaining balance")?
|
||||
}
|
||||
|
||||
@@ -1016,7 +1019,7 @@ mod tests {
|
||||
|
||||
let mut gas_meter = GasMeter::<Test>::new(GAS_LIMIT);
|
||||
|
||||
let result = ctx.instantiate(1, &mut gas_meter, &code, vec![]);
|
||||
let result = ctx.instantiate(cfg.subsistence_threshold(), &mut gas_meter, &code, vec![]);
|
||||
assert_matches!(result, Ok(_));
|
||||
|
||||
let mut toks = gas_meter.tokens().iter();
|
||||
@@ -1306,7 +1309,7 @@ mod tests {
|
||||
set_balance(&ALICE, 100);
|
||||
|
||||
let result = ctx.instantiate(
|
||||
1,
|
||||
cfg.subsistence_threshold(),
|
||||
&mut GasMeter::<Test>::new(GAS_LIMIT),
|
||||
&input_data_ch,
|
||||
vec![1, 2, 3, 4],
|
||||
@@ -1549,7 +1552,7 @@ mod tests {
|
||||
// Instantiate a contract and save it's address in `instantiated_contract_address`.
|
||||
let (address, output) = ctx.ext.instantiate(
|
||||
&dummy_ch,
|
||||
15u64,
|
||||
Config::<Test>::subsistence_threshold_uncached(),
|
||||
ctx.gas_meter,
|
||||
vec![]
|
||||
).unwrap();
|
||||
@@ -1679,7 +1682,7 @@ mod tests {
|
||||
set_balance(&ALICE, 100);
|
||||
|
||||
let result = ctx.instantiate(
|
||||
1,
|
||||
cfg.subsistence_threshold(),
|
||||
&mut GasMeter::<Test>::new(GAS_LIMIT),
|
||||
&rent_allowance_ch,
|
||||
vec![],
|
||||
|
||||
@@ -743,7 +743,7 @@ impl<T: Trait> Config<T> {
|
||||
/// than the subsistence threshold in order to guarantee that a tombstone is created.
|
||||
///
|
||||
/// The only way to completely kill a contract without a tombstone is calling `ext_terminate`.
|
||||
fn subsistence_threshold(&self) -> BalanceOf<T> {
|
||||
pub fn subsistence_threshold(&self) -> BalanceOf<T> {
|
||||
self.existential_deposit.saturating_add(self.tombstone_deposit)
|
||||
}
|
||||
|
||||
@@ -751,7 +751,7 @@ impl<T: Trait> Config<T> {
|
||||
///
|
||||
/// This is for cases where this value is needed in rent calculation rather than
|
||||
/// during contract execution.
|
||||
fn subsistence_threshold_uncached() -> BalanceOf<T> {
|
||||
pub fn subsistence_threshold_uncached() -> BalanceOf<T> {
|
||||
T::Currency::minimum_balance().saturating_add(T::TombstoneDeposit::get())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -385,13 +385,14 @@ fn instantiate_and_call_and_deposit_event() {
|
||||
.build()
|
||||
.execute_with(|| {
|
||||
let _ = Balances::deposit_creating(&ALICE, 1_000_000);
|
||||
let subsistence = super::Config::<Test>::subsistence_threshold_uncached();
|
||||
|
||||
assert_ok!(Contracts::put_code(Origin::signed(ALICE), wasm));
|
||||
|
||||
// Check at the end to get hash on error easily
|
||||
let creation = Contracts::instantiate(
|
||||
Origin::signed(ALICE),
|
||||
100,
|
||||
subsistence,
|
||||
GAS_LIMIT,
|
||||
code_hash.into(),
|
||||
vec![],
|
||||
@@ -421,14 +422,14 @@ fn instantiate_and_call_and_deposit_event() {
|
||||
EventRecord {
|
||||
phase: Phase::Initialization,
|
||||
event: MetaEvent::balances(
|
||||
pallet_balances::RawEvent::Endowed(BOB, 100)
|
||||
pallet_balances::RawEvent::Endowed(BOB, subsistence)
|
||||
),
|
||||
topics: vec![],
|
||||
},
|
||||
EventRecord {
|
||||
phase: Phase::Initialization,
|
||||
event: MetaEvent::balances(
|
||||
pallet_balances::RawEvent::Transfer(ALICE, BOB, 100)
|
||||
pallet_balances::RawEvent::Transfer(ALICE, BOB, subsistence)
|
||||
),
|
||||
topics: vec![],
|
||||
},
|
||||
|
||||
@@ -617,10 +617,12 @@ define_env!(Env, <E: Ext>,
|
||||
// This function creates an account and executes the constructor defined in the code specified
|
||||
// by the code hash. The address of this new account is copied to `address_ptr` and its length
|
||||
// to `address_len_ptr`. The constructors output buffer is copied to `output_ptr` and its
|
||||
// length to `output_len_ptr`.
|
||||
// length to `output_len_ptr`. The copy of the output buffer and address can be skipped by
|
||||
// supplying the sentinel value of `u32::max_value()` to `output_ptr` or `address_ptr`.
|
||||
//
|
||||
// The copy of the output buffer and address can be skipped by supplying the sentinel value
|
||||
// of `u32::max_value()` to `output_ptr` or `address_ptr`.
|
||||
// After running the constructor it is verfied that the contract account holds at
|
||||
// least the subsistence threshold. If that is not the case the instantion fails and
|
||||
// the contract is not created.
|
||||
//
|
||||
// # Parameters
|
||||
//
|
||||
|
||||
Reference in New Issue
Block a user