[contracts] Port host functions to Weight V2 and storage deposit limit (#13565)

* added [unstable][seal2] call()

* updated test to cover new seal_call proof_limit

* docs updated

* add [seal2][unstable] instantiate() and test

* add [seal2][unstable] weight_to_fee() + docs and test

* add [seal2][unstable] gas_left() + docs and test

* update benchmarks

* add DefaultDepositLimit to pallet Config

* specify deposit limit for nested call

add test for nested call deposit limit

save: separate deposit limit for nested calls

* specify deposit limit for nested instantiate

save: works with test

cleaned up debugging outputs

* update benchmarks

* added missing fixtures

* fix benches

* pass explicit deposit limit to storage bench

* explicit deposit limit for another set_storage bench

* add more deposit limit for storage benches

* moving to simplified benchmarks

* moved to simplified benchmarks

* fix seal_weight_to_fee bench

* fix seal_instantiate benchmark

* doc typo fix

* default dl for benchmarking

more dl for tests

dl for tests to max

deposit_limit fix in instantiate bench

fix instantiate bench

fix instantiate benchmark

fix instantiate bench again

remove dbg

fix seal bench again

fixing it still

seal_instantiate zero deposit

less runs to check if deposit enough

try

try 2

try 3

try 4

* max_runtime_mem to Schedule limits

* add default deposit limit fallback check to test

* weight params renaming

* fmt

* Update frame/contracts/src/benchmarking/mod.rs

Co-authored-by: PG Herveou <pgherveou@gmail.com>

* prettify inputs in tests

* typestate param refactored

---------

Co-authored-by: PG Herveou <pgherveou@gmail.com>
This commit is contained in:
Sasha Gryaznov
2023-04-26 14:27:13 +03:00
committed by GitHub
parent 01c66da036
commit 60310de7d6
16 changed files with 949 additions and 275 deletions
@@ -547,7 +547,7 @@ benchmarks! {
seal_gas_left {
let r in 0 .. API_BENCHMARK_RUNS;
let instance = Contract::<T>::new(WasmModule::getter(
"seal0", "seal_gas_left", r
"seal1", "gas_left", r
), vec![])?;
let origin = RawOrigin::Signed(instance.caller.clone());
}: call(origin, instance.addr, 0u32.into(), Weight::MAX, None, vec![])
@@ -604,9 +604,9 @@ benchmarks! {
let code = WasmModule::<T>::from(ModuleDefinition {
memory: Some(ImportedMemory::max::<T>()),
imported_functions: vec![ImportedFunction {
module: "seal0",
name: "seal_weight_to_fee",
params: vec![ValueType::I64, ValueType::I32, ValueType::I32],
module: "seal1",
name: "weight_to_fee",
params: vec![ValueType::I64, ValueType::I64, ValueType::I32, ValueType::I32],
return_type: None,
}],
data_segments: vec![DataSegment {
@@ -615,6 +615,7 @@ benchmarks! {
}],
call_body: Some(body::repeated(r, &[
Instruction::I64Const(500_000),
Instruction::I64Const(300_000),
Instruction::I32Const(4),
Instruction::I32Const(0),
Instruction::Call(0),
@@ -1584,16 +1585,26 @@ benchmarks! {
let callee_bytes = callees.iter().flat_map(|x| x.account_id.encode()).collect();
let value: BalanceOf<T> = 0u32.into();
let value_bytes = value.encode();
let value_len = value_bytes.len();
let value_len = BalanceOf::<T>::max_encoded_len() as u32;
// Set an own limit every 2nd call
let own_limit = (u32::MAX - 100).into();
let deposits = (0..r)
.map(|i| if i % 2 == 0 { 0u32.into() } else { own_limit } )
.collect::<Vec<BalanceOf<T>>>();
let deposits_bytes: Vec<u8> = deposits.iter().flat_map(|i| i.encode()).collect();
let deposits_len = deposits_bytes.len() as u32;
let deposit_len = value_len.clone();
let callee_offset = value_len + deposits_len;
let code = WasmModule::<T>::from(ModuleDefinition {
memory: Some(ImportedMemory::max::<T>()),
imported_functions: vec![ImportedFunction {
module: "seal0",
name: "seal_call",
module: "seal2",
name: "call",
params: vec![
ValueType::I32,
ValueType::I32,
ValueType::I64,
ValueType::I64,
ValueType::I32,
ValueType::I32,
ValueType::I32,
@@ -1609,16 +1620,21 @@ benchmarks! {
value: value_bytes,
},
DataSegment {
offset: value_len as u32,
offset: value_len,
value: deposits_bytes,
},
DataSegment {
offset: callee_offset,
value: callee_bytes,
},
],
call_body: Some(body::repeated_dyn(r, vec![
Counter(value_len as u32, callee_len as u32), // callee_ptr
Regular(Instruction::I32Const(callee_len as i32)), // callee_len
Regular(Instruction::I64Const(0)), // gas
Regular(Instruction::I32Const(0)), // flags
Counter(callee_offset, callee_len as u32), // callee_ptr
Regular(Instruction::I64Const(0)), // ref_time weight
Regular(Instruction::I64Const(0)), // proof_size weight
Counter(value_len, deposit_len as u32), // deposit_limit_ptr
Regular(Instruction::I32Const(0)), // value_ptr
Regular(Instruction::I32Const(value_len as i32)), // value_len
Regular(Instruction::I32Const(0)), // input_data_ptr
Regular(Instruction::I32Const(0)), // input_data_len
Regular(Instruction::I32Const(SENTINEL as i32)), // output_ptr
@@ -1630,7 +1646,7 @@ benchmarks! {
});
let instance = Contract::<T>::new(code, vec![])?;
let origin = RawOrigin::Signed(instance.caller.clone());
}: call(origin, instance.addr, 0u32.into(), Weight::MAX, None, vec![])
}: call(origin, instance.addr, 0u32.into(), Weight::MAX, Some(BalanceOf::<T>::from(u32::MAX).into()), vec![])
// This is a slow call: We redeuce the number of runs.
#[pov_mode = Measured]
@@ -1742,17 +1758,17 @@ benchmarks! {
}: call(origin, instance.addr, 0u32.into(), Weight::MAX, None, bytes)
// We assume that every instantiate sends at least the minimum balance.
// This is a slow call: We redeuce the number of runs.
// This is a slow call: we reduce the number of runs.
#[pov_mode = Measured]
seal_instantiate {
let r in 0 .. API_BENCHMARK_RUNS / 2;
let r in 1 .. API_BENCHMARK_RUNS / 2;
let hashes = (0..r)
.map(|i| {
let code = WasmModule::<T>::from(ModuleDefinition {
memory: Some(ImportedMemory::max::<T>()),
call_body: Some(body::plain(vec![
// we need to add this in order to make contracts unique
// so that they can be deployed from the same sender
// We need to add this in order to make contracts unique,
// so that they can be deployed from the same sender.
Instruction::I32Const(i as i32),
Instruction::Drop,
Instruction::End,
@@ -1765,27 +1781,24 @@ benchmarks! {
.collect::<Result<Vec<_>, &'static str>>()?;
let hash_len = hashes.get(0).map(|x| x.encode().len()).unwrap_or(0);
let hashes_bytes = hashes.iter().flat_map(|x| x.encode()).collect::<Vec<_>>();
let hashes_len = hashes_bytes.len();
let hashes_len = &hashes_bytes.len();
let value = Pallet::<T>::min_balance();
assert!(value > 0u32.into());
let value_bytes = value.encode();
let value_len = value_bytes.len();
let value_len = BalanceOf::<T>::max_encoded_len();
let addr_len = T::AccountId::max_encoded_len();
// offsets where to place static data in contract memory
let value_offset = 0;
let hashes_offset = value_offset + value_len;
// Offsets where to place static data in contract memory.
let hashes_offset = value_len;
let addr_len_offset = hashes_offset + hashes_len;
let addr_offset = addr_len_offset + addr_len;
let code = WasmModule::<T>::from(ModuleDefinition {
memory: Some(ImportedMemory::max::<T>()),
imported_functions: vec![ImportedFunction {
module: "seal0",
name: "seal_instantiate",
module: "seal2",
name: "instantiate",
params: vec![
ValueType::I32,
ValueType::I32,
ValueType::I64,
ValueType::I64,
ValueType::I32,
ValueType::I32,
@@ -1802,7 +1815,7 @@ benchmarks! {
}],
data_segments: vec![
DataSegment {
offset: value_offset as u32,
offset: 0,
value: value_bytes,
},
DataSegment {
@@ -1816,10 +1829,10 @@ benchmarks! {
],
call_body: Some(body::repeated_dyn(r, vec![
Counter(hashes_offset as u32, hash_len as u32), // code_hash_ptr
Regular(Instruction::I32Const(hash_len as i32)), // code_hash_len
Regular(Instruction::I64Const(0)), // gas
Regular(Instruction::I32Const(value_offset as i32)), // value_ptr
Regular(Instruction::I32Const(value_len as i32)), // value_len
Regular(Instruction::I64Const(0)), // ref_time weight
Regular(Instruction::I64Const(0)), // proof_size weight
Regular(Instruction::I32Const(SENTINEL as i32)), // deposit limit ptr: use parent's limit
Regular(Instruction::I32Const(0)), // value_ptr
Regular(Instruction::I32Const(0)), // input_data_ptr
Regular(Instruction::I32Const(0)), // input_data_len
Regular(Instruction::I32Const(addr_offset as i32)), // address_ptr
@@ -1827,7 +1840,7 @@ benchmarks! {
Regular(Instruction::I32Const(SENTINEL as i32)), // output_ptr
Regular(Instruction::I32Const(0)), // output_len_ptr
Regular(Instruction::I32Const(0)), // salt_ptr
Regular(Instruction::I32Const(0)), // salt_ptr_len
Regular(Instruction::I32Const(0)), // salt_len_ptr
Regular(Instruction::Call(0)),
Regular(Instruction::Drop),
])),