contracts: Add set_code root dispatchable (#11451)

* Add `set_code` dispatchable

* cargo run --quiet --profile=production  --features=runtime-benchmarks --manifest-path=bin/node/cli/Cargo.toml -- benchmark pallet --chain=dev --steps=50 --repeat=20 --pallet=pallet_contracts --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --output=./frame/contracts/src/weights.rs --template=./.maintain/frame-weight-template.hbs

Co-authored-by: Parity Bot <admin@parity.io>
This commit is contained in:
Alexander Theißen
2022-05-19 01:50:22 +02:00
committed by GitHub
parent bd225c7938
commit b3b7b4ddc7
4 changed files with 918 additions and 768 deletions
+81 -1
View File
@@ -40,7 +40,7 @@ use frame_support::{
weights::{constants::WEIGHT_PER_SECOND, DispatchClass, PostDispatchInfo, Weight},
};
use frame_system::{self as system, EventRecord, Phase};
use pretty_assertions::assert_eq;
use pretty_assertions::{assert_eq, assert_ne};
use sp_core::Bytes;
use sp_io::hashing::blake2_256;
use sp_keystore::{testing::KeyStore, KeystoreExt};
@@ -2862,6 +2862,86 @@ fn storage_deposit_works() {
});
}
#[test]
fn set_code_extrinsic() {
let (wasm, code_hash) = compile_module::<Test>("dummy").unwrap();
let (new_wasm, new_code_hash) = compile_module::<Test>("crypto_hashes").unwrap();
assert_ne!(code_hash, new_code_hash);
ExtBuilder::default().existential_deposit(100).build().execute_with(|| {
let _ = Balances::deposit_creating(&ALICE, 1_000_000);
assert_ok!(Contracts::instantiate_with_code(
Origin::signed(ALICE),
0,
GAS_LIMIT,
None,
wasm,
vec![],
vec![],
));
let addr = Contracts::contract_address(&ALICE, &code_hash, &[]);
assert_ok!(Contracts::upload_code(Origin::signed(ALICE), new_wasm, None,));
// Drop previous events
initialize_block(2);
assert_eq!(<ContractInfoOf<Test>>::get(&addr).unwrap().code_hash, code_hash);
assert_refcount!(&code_hash, 1);
assert_refcount!(&new_code_hash, 0);
// only root can execute this extrinsic
assert_noop!(
Contracts::set_code(Origin::signed(ALICE), addr.clone(), new_code_hash),
sp_runtime::traits::BadOrigin,
);
assert_eq!(<ContractInfoOf<Test>>::get(&addr).unwrap().code_hash, code_hash);
assert_refcount!(&code_hash, 1);
assert_refcount!(&new_code_hash, 0);
assert_eq!(System::events(), vec![],);
// contract must exist
assert_noop!(
Contracts::set_code(Origin::root(), BOB, new_code_hash),
<Error<Test>>::ContractNotFound,
);
assert_eq!(<ContractInfoOf<Test>>::get(&addr).unwrap().code_hash, code_hash);
assert_refcount!(&code_hash, 1);
assert_refcount!(&new_code_hash, 0);
assert_eq!(System::events(), vec![],);
// new code hash must exist
assert_noop!(
Contracts::set_code(Origin::root(), addr.clone(), Default::default()),
<Error<Test>>::CodeNotFound,
);
assert_eq!(<ContractInfoOf<Test>>::get(&addr).unwrap().code_hash, code_hash);
assert_refcount!(&code_hash, 1);
assert_refcount!(&new_code_hash, 0);
assert_eq!(System::events(), vec![],);
// successful call
assert_ok!(Contracts::set_code(Origin::root(), addr.clone(), new_code_hash));
assert_eq!(<ContractInfoOf<Test>>::get(&addr).unwrap().code_hash, new_code_hash);
assert_refcount!(&code_hash, 0);
assert_refcount!(&new_code_hash, 1);
assert_eq!(
System::events(),
vec![EventRecord {
phase: Phase::Initialization,
event: Event::Contracts(pallet_contracts::Event::ContractCodeUpdated {
contract: addr,
new_code_hash,
old_code_hash: code_hash,
}),
topics: vec![],
},]
);
});
}
#[test]
fn call_after_killed_account_needs_funding() {
let (wasm, code_hash) = compile_module::<Test>("dummy").unwrap();