contracts: Add test to verify unique trie ids (#10914)

* Add test to verify unique trie ids

* Rename trie_seed to nonce

* Rename AccountCounter -> Nonce

* fmt
This commit is contained in:
Alexander Theißen
2022-03-10 12:28:00 +01:00
committed by GitHub
parent 18aef02e87
commit bef9b79d7b
6 changed files with 162 additions and 56 deletions
+69 -8
View File
@@ -74,17 +74,15 @@ frame_support::construct_runtime!(
#[macro_use]
pub mod test_utils {
use super::{Balances, Test};
use crate::{
exec::AccountIdOf, storage::Storage, AccountCounter, CodeHash, Config, ContractInfoOf,
};
use crate::{exec::AccountIdOf, storage::Storage, CodeHash, Config, ContractInfoOf, Nonce};
use frame_support::traits::Currency;
pub fn place_contract(address: &AccountIdOf<Test>, code_hash: CodeHash<Test>) {
let seed = <AccountCounter<Test>>::mutate(|counter| {
let nonce = <Nonce<Test>>::mutate(|counter| {
*counter += 1;
*counter
});
let trie_id = Storage::<Test>::generate_trie_id(address, seed);
let trie_id = Storage::<Test>::generate_trie_id(address, nonce);
set_balance(address, <Test as Config>::Currency::minimum_balance() * 10);
let contract = Storage::<Test>::new_contract(&address, trie_id, code_hash).unwrap();
<ContractInfoOf<Test>>::insert(address, contract);
@@ -349,6 +347,11 @@ where
Ok((wasm_binary, code_hash))
}
fn initialize_block(number: u64) {
System::reset_events();
System::initialize(&number, &[0u8; 32].into(), &Default::default());
}
// Perform a call to a plain account.
// The actual transfer fails because we can only call contracts.
// Then we check that at least the base costs where charged (no runtime gas costs.)
@@ -540,9 +543,67 @@ fn run_out_of_gas() {
});
}
fn initialize_block(number: u64) {
System::reset_events();
System::initialize(&number, &[0u8; 32].into(), &Default::default());
/// Check that contracts with the same account id have different trie ids.
/// Check the `Nonce` storage item for more information.
#[test]
fn instantiate_unique_trie_id() {
let (wasm, code_hash) = compile_module::<Test>("self_destruct").unwrap();
ExtBuilder::default().existential_deposit(500).build().execute_with(|| {
let _ = Balances::deposit_creating(&ALICE, 1_000_000);
Contracts::upload_code(Origin::signed(ALICE), wasm, None).unwrap();
let addr = Contracts::contract_address(&ALICE, &code_hash, &[]);
// Instantiate the contract and store its trie id for later comparison.
assert_ok!(Contracts::instantiate(
Origin::signed(ALICE),
0,
GAS_LIMIT,
None,
code_hash,
vec![],
vec![],
));
let trie_id = ContractInfoOf::<Test>::get(&addr).unwrap().trie_id;
// Try to instantiate it again without termination should yield an error.
assert_err_ignore_postinfo!(
Contracts::instantiate(
Origin::signed(ALICE),
0,
GAS_LIMIT,
None,
code_hash,
vec![],
vec![],
),
<Error<Test>>::DuplicateContract,
);
// Terminate the contract.
assert_ok!(Contracts::call(
Origin::signed(ALICE),
addr.clone(),
0,
GAS_LIMIT,
None,
vec![]
));
// Re-Instantiate after termination.
assert_ok!(Contracts::instantiate(
Origin::signed(ALICE),
0,
GAS_LIMIT,
None,
code_hash,
vec![],
vec![],
));
// Trie ids shouldn't match or we might have a collision
assert_ne!(trie_id, ContractInfoOf::<Test>::get(&addr).unwrap().trie_id);
});
}
#[test]