contracts: add seal_code_hash and seal_own_code_hash to API (#10933)

* `seal_origin` + tests added

* `seal_origin` benchmark added

* `seal_code_hash` + tests added

* `seal_code_hash` benchmark added

* `seal_own_code_hash` + tests added

* `seal_own_code_hash` benchmark added

* fmt lil fix

* akward accident bug fix

* Apply suggestions from code review

Co-authored-by: Alexander Theißen <alex.theissen@me.com>

* Apply suggestions from code review

Co-authored-by: Alexander Theißen <alex.theissen@me.com>

* benchmark fix

* `WasmModule::getter()` to take `module_name` arg

* test enhanced

* fixes based on review feedback

* Apply suggestions from code review

Co-authored-by: Alexander Theißen <alex.theissen@me.com>

* Hash left as const to return a ref to it from mock

* HASH test val to local const in mock

* Apply suggestions from code review

Co-authored-by: Alexander Theißen <alex.theissen@me.com>

* fixes to benchmarks according to review feedback

* cargo run --quiet --profile=production  --features=runtime-benchmarks --manifest-path=bin/node/cli/Cargo.toml -- benchmark --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

* removed `seal_origin` from API

Co-authored-by: Alexander Theißen <alex.theissen@me.com>
Co-authored-by: Parity Bot <admin@parity.io>
This commit is contained in:
Alexander Gryaznov
2022-03-29 17:14:49 +02:00
committed by GitHub
parent 83d4be6151
commit e4caf7388a
7 changed files with 995 additions and 658 deletions
+72
View File
@@ -162,6 +162,14 @@ pub trait Ext: sealing::Sealed {
/// Check if a contract lives at the specified `address`.
fn is_contract(&self, address: &AccountIdOf<Self::T>) -> bool;
/// Returns the code hash of the contract for the given `address`.
///
/// Returns `None` if the `address` does not belong to a contract.
fn code_hash(&self, address: &AccountIdOf<Self::T>) -> Option<CodeHash<Self::T>>;
/// Returns the code hash of the contract being executed.
fn own_code_hash(&mut self) -> &CodeHash<Self::T>;
/// Check if the caller of the current contract is the origin of the whole call stack.
///
/// This can be checked with `is_contract(self.caller())` as well.
@@ -1103,6 +1111,14 @@ where
ContractInfoOf::<T>::contains_key(&address)
}
fn code_hash(&self, address: &T::AccountId) -> Option<CodeHash<Self::T>> {
<ContractInfoOf<T>>::get(&address).map(|contract| contract.code_hash)
}
fn own_code_hash(&mut self) -> &CodeHash<Self::T> {
&self.top_frame_mut().contract_info().code_hash
}
fn caller_is_origin(&self) -> bool {
self.caller() == &self.origin
}
@@ -1753,6 +1769,62 @@ mod tests {
});
}
#[test]
fn code_hash_returns_proper_values() {
let code_bob = MockLoader::insert(Call, |ctx, _| {
// ALICE is not a contract and hence she does not have a code_hash
assert!(ctx.ext.code_hash(&ALICE).is_none());
// BOB is a contract and hence he has a code_hash
assert!(ctx.ext.code_hash(&BOB).is_some());
exec_success()
});
ExtBuilder::default().build().execute_with(|| {
let schedule = <Test as Config>::Schedule::get();
place_contract(&BOB, code_bob);
let mut storage_meter = storage::meter::Meter::new(&ALICE, Some(0), 0).unwrap();
// ALICE (not contract) -> BOB (contract)
let result = MockStack::run_call(
ALICE,
BOB,
&mut GasMeter::<Test>::new(GAS_LIMIT),
&mut storage_meter,
&schedule,
0,
vec![0],
None,
);
assert_matches!(result, Ok(_));
});
}
#[test]
fn own_code_hash_returns_proper_values() {
let bob_ch = MockLoader::insert(Call, |ctx, _| {
let code_hash = ctx.ext.code_hash(&BOB).unwrap();
assert_eq!(*ctx.ext.own_code_hash(), code_hash);
exec_success()
});
ExtBuilder::default().build().execute_with(|| {
let schedule = <Test as Config>::Schedule::get();
place_contract(&BOB, bob_ch);
let mut storage_meter = storage::meter::Meter::new(&ALICE, Some(0), 0).unwrap();
// ALICE (not contract) -> BOB (contract)
let result = MockStack::run_call(
ALICE,
BOB,
&mut GasMeter::<Test>::new(GAS_LIMIT),
&mut storage_meter,
&schedule,
0,
vec![0],
None,
);
assert_matches!(result, Ok(_));
});
}
#[test]
fn caller_is_origin_returns_proper_values() {
let code_charlie = MockLoader::insert(Call, |ctx, _| {