mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-14 08:41:07 +00:00
contracts: Move Schedule from Storage to Config (#8773)
* Move `Schedule` from Storage to Config * Updated CHANGELOG * Fix nits from review * Fix migration * Print the debug buffer as tracing message * Use `debug` instead of `trace` and update README * Add additional assert to test * Rename `schedule_version` to `instruction_weights_version` * Fixed typo * Added more comments to wat fixtures * Add clarification for the `debug_message` field
This commit is contained in:
committed by
GitHub
parent
3c0270fe57
commit
1ac95b6ba6
@@ -290,7 +290,7 @@ benchmarks! {
|
||||
|
||||
on_initialize_per_trie_key {
|
||||
let k in 0..1024;
|
||||
let instance = ContractWithStorage::<T>::new(k, T::MaxValueSize::get())?;
|
||||
let instance = ContractWithStorage::<T>::new(k, T::Schedule::get().limits.payload_len)?;
|
||||
Storage::<T>::queue_trie_for_deletion(&instance.contract.alive_info()?)?;
|
||||
}: {
|
||||
Storage::<T>::process_deletion_queue_batch(Weight::max_value())
|
||||
@@ -311,23 +311,15 @@ benchmarks! {
|
||||
// first time after a new schedule was deployed: For every new schedule a contract needs
|
||||
// to re-run the instrumentation once.
|
||||
instrument {
|
||||
let c in 0 .. T::MaxCodeSize::get() / 1024;
|
||||
let c in 0 .. T::Schedule::get().limits.code_len / 1024;
|
||||
let WasmModule { code, hash, .. } = WasmModule::<T>::sized(c * 1024);
|
||||
Contracts::<T>::store_code_raw(code)?;
|
||||
let mut module = PrefabWasmModule::from_storage_noinstr(hash)?;
|
||||
let schedule = <CurrentSchedule<T>>::get();
|
||||
let schedule = T::Schedule::get();
|
||||
}: {
|
||||
Contracts::<T>::reinstrument_module(&mut module, &schedule)?;
|
||||
}
|
||||
|
||||
// This extrinsic is pretty much constant as it is only a simple setter.
|
||||
update_schedule {
|
||||
let schedule = Schedule {
|
||||
version: 1,
|
||||
.. Default::default()
|
||||
};
|
||||
}: _(RawOrigin::Root, schedule)
|
||||
|
||||
// This constructs a contract that is maximal expensive to instrument.
|
||||
// It creates a maximum number of metering blocks per byte.
|
||||
// The size of the salt influences the runtime because is is hashed in order to
|
||||
@@ -340,7 +332,7 @@ benchmarks! {
|
||||
// We cannot let `c` grow to the maximum code size because the code is not allowed
|
||||
// to be larger than the maximum size **after instrumentation**.
|
||||
instantiate_with_code {
|
||||
let c in 0 .. Perbill::from_percent(50).mul_ceil(T::MaxCodeSize::get() / 1024);
|
||||
let c in 0 .. Perbill::from_percent(50).mul_ceil(T::Schedule::get().limits.code_len / 1024);
|
||||
let s in 0 .. code::max_pages::<T>() * 64;
|
||||
let salt = vec![42u8; (s * 1024) as usize];
|
||||
let endowment = caller_funding::<T>() / 3u32.into();
|
||||
@@ -363,7 +355,7 @@ benchmarks! {
|
||||
// `c`: Size of the code in kilobytes.
|
||||
// `s`: Size of the salt in kilobytes.
|
||||
instantiate {
|
||||
let c in 0 .. T::MaxCodeSize::get() / 1024;
|
||||
let c in 0 .. T::Schedule::get().limits.code_len / 1024;
|
||||
let s in 0 .. code::max_pages::<T>() * 64;
|
||||
let salt = vec![42u8; (s * 1024) as usize];
|
||||
let endowment = caller_funding::<T>() / 3u32.into();
|
||||
@@ -390,7 +382,7 @@ benchmarks! {
|
||||
// part of `seal_input`.
|
||||
// `c`: Size of the code in kilobytes.
|
||||
call {
|
||||
let c in 0 .. T::MaxCodeSize::get() / 1024;
|
||||
let c in 0 .. T::Schedule::get().limits.code_len / 1024;
|
||||
let data = vec![42u8; 1024];
|
||||
let instance = Contract::<T>::with_caller(
|
||||
whitelisted_caller(), WasmModule::dummy_with_bytes(c * 1024), vec![], Endow::CollectRent
|
||||
@@ -423,7 +415,7 @@ benchmarks! {
|
||||
// the reward for removing them.
|
||||
// `c`: Size of the code of the contract that should be evicted.
|
||||
claim_surcharge {
|
||||
let c in 0 .. T::MaxCodeSize::get() / 1024;
|
||||
let c in 0 .. T::Schedule::get().limits.code_len / 1024;
|
||||
let instance = Contract::<T>::with_caller(
|
||||
whitelisted_caller(), WasmModule::dummy_with_bytes(c * 1024), vec![], Endow::CollectRent
|
||||
)?;
|
||||
@@ -730,7 +722,7 @@ benchmarks! {
|
||||
}
|
||||
|
||||
seal_terminate_per_code_kb {
|
||||
let c in 0 .. T::MaxCodeSize::get() / 1024;
|
||||
let c in 0 .. T::Schedule::get().limits.code_len / 1024;
|
||||
let beneficiary = account::<T::AccountId>("beneficiary", 0, 0);
|
||||
let beneficiary_bytes = beneficiary.encode();
|
||||
let beneficiary_len = beneficiary_bytes.len();
|
||||
@@ -771,7 +763,7 @@ benchmarks! {
|
||||
// Restore just moves the trie id from origin to destination and therefore
|
||||
// does not depend on the size of the destination contract. However, to not
|
||||
// trigger any edge case we won't use an empty contract as destination.
|
||||
let mut tombstone = ContractWithStorage::<T>::new(10, T::MaxValueSize::get())?;
|
||||
let mut tombstone = ContractWithStorage::<T>::new(10, T::Schedule::get().limits.payload_len)?;
|
||||
tombstone.evict()?;
|
||||
|
||||
let dest = tombstone.contract.account_id.encode();
|
||||
@@ -847,14 +839,14 @@ benchmarks! {
|
||||
// `t`: Code size of tombstone contract
|
||||
// `d`: Number of supplied delta keys
|
||||
seal_restore_to_per_code_kb_delta {
|
||||
let c in 0 .. T::MaxCodeSize::get() / 1024;
|
||||
let t in 0 .. T::MaxCodeSize::get() / 1024;
|
||||
let c in 0 .. T::Schedule::get().limits.code_len / 1024;
|
||||
let t in 0 .. T::Schedule::get().limits.code_len / 1024;
|
||||
let d in 0 .. API_BENCHMARK_BATCHES;
|
||||
let mut tombstone = ContractWithStorage::<T>::with_code(
|
||||
WasmModule::<T>::dummy_with_bytes(t * 1024), 0, 0
|
||||
)?;
|
||||
tombstone.evict()?;
|
||||
let delta = create_storage::<T>(d * API_BENCHMARK_BATCH_SIZE, T::MaxValueSize::get())?;
|
||||
let delta = create_storage::<T>(d * API_BENCHMARK_BATCH_SIZE, T::Schedule::get().limits.payload_len)?;
|
||||
|
||||
let dest = tombstone.contract.account_id.encode();
|
||||
let dest_len = dest.len();
|
||||
@@ -938,7 +930,7 @@ benchmarks! {
|
||||
seal_random {
|
||||
let r in 0 .. API_BENCHMARK_BATCHES;
|
||||
let pages = code::max_pages::<T>();
|
||||
let subject_len = <CurrentSchedule<T>>::get().limits.subject_len;
|
||||
let subject_len = T::Schedule::get().limits.subject_len;
|
||||
assert!(subject_len < 1024);
|
||||
let code = WasmModule::<T>::from(ModuleDefinition {
|
||||
memory: Some(ImportedMemory::max::<T>()),
|
||||
@@ -994,8 +986,8 @@ benchmarks! {
|
||||
// `t`: Number of topics
|
||||
// `n`: Size of event payload in kb
|
||||
seal_deposit_event_per_topic_and_kb {
|
||||
let t in 0 .. <CurrentSchedule<T>>::get().limits.event_topics;
|
||||
let n in 0 .. T::MaxValueSize::get() / 1024;
|
||||
let t in 0 .. T::Schedule::get().limits.event_topics;
|
||||
let n in 0 .. T::Schedule::get().limits.payload_len / 1024;
|
||||
let mut topics = (0..API_BENCHMARK_BATCH_SIZE)
|
||||
.map(|n| (n * t..n * t + t).map(|i| T::Hashing::hash_of(&i)).collect::<Vec<_>>().encode())
|
||||
.peekable();
|
||||
@@ -1055,6 +1047,31 @@ benchmarks! {
|
||||
let origin = RawOrigin::Signed(instance.caller.clone());
|
||||
}: call(origin, instance.addr, 0u32.into(), Weight::max_value(), vec![])
|
||||
|
||||
// The size of the supplied message does not influence the weight because as it is never
|
||||
// processed during on-chain execution: It is only ever read during debugging which happens
|
||||
// when the contract is called as RPC where weights do not matter.
|
||||
seal_debug_message {
|
||||
let r in 0 .. API_BENCHMARK_BATCHES;
|
||||
let max_bytes = code::max_pages::<T>() * 64 * 1024;
|
||||
let code = WasmModule::<T>::from(ModuleDefinition {
|
||||
memory: Some(ImportedMemory { min_pages: 1, max_pages: 1 }),
|
||||
imported_functions: vec![ImportedFunction {
|
||||
name: "seal_debug_message",
|
||||
params: vec![ValueType::I32, ValueType::I32],
|
||||
return_type: Some(ValueType::I32),
|
||||
}],
|
||||
call_body: Some(body::repeated(r * API_BENCHMARK_BATCH_SIZE, &[
|
||||
Instruction::I32Const(0), // value_ptr
|
||||
Instruction::I32Const(max_bytes as i32), // value_len
|
||||
Instruction::Call(0),
|
||||
Instruction::Drop,
|
||||
])),
|
||||
.. Default::default()
|
||||
});
|
||||
let instance = Contract::<T>::new(code, vec![], Endow::Max)?;
|
||||
let origin = RawOrigin::Signed(instance.caller.clone());
|
||||
}: call(origin, instance.addr, 0u32.into(), Weight::max_value(), vec![])
|
||||
|
||||
// Only the overhead of calling the function itself with minimal arguments.
|
||||
// The contract is a bit more complex because I needs to use different keys in order
|
||||
// to generate unique storage accesses. However, it is still dominated by the storage
|
||||
@@ -1091,7 +1108,7 @@ benchmarks! {
|
||||
}: call(origin, instance.addr, 0u32.into(), Weight::max_value(), vec![])
|
||||
|
||||
seal_set_storage_per_kb {
|
||||
let n in 0 .. T::MaxValueSize::get() / 1024;
|
||||
let n in 0 .. T::Schedule::get().limits.payload_len / 1024;
|
||||
let key = T::Hashing::hash_of(&1u32).as_ref().to_vec();
|
||||
let key_len = key.len();
|
||||
let code = WasmModule::<T>::from(ModuleDefinition {
|
||||
@@ -1155,7 +1172,7 @@ benchmarks! {
|
||||
<System<T>>::block_number(),
|
||||
&mut info,
|
||||
key.as_slice().try_into().map_err(|e| "Key has wrong length")?,
|
||||
Some(vec![42; T::MaxValueSize::get() as usize])
|
||||
Some(vec![42; T::Schedule::get().limits.payload_len as usize])
|
||||
)
|
||||
.map_err(|_| "Failed to write to storage during setup.")?;
|
||||
}
|
||||
@@ -1210,7 +1227,7 @@ benchmarks! {
|
||||
}: call(origin, instance.addr, 0u32.into(), Weight::max_value(), vec![])
|
||||
|
||||
seal_get_storage_per_kb {
|
||||
let n in 0 .. T::MaxValueSize::get() / 1024;
|
||||
let n in 0 .. T::Schedule::get().limits.payload_len / 1024;
|
||||
let key = T::Hashing::hash_of(&1u32).as_ref().to_vec();
|
||||
let key_len = key.len();
|
||||
let code = WasmModule::<T>::from(ModuleDefinition {
|
||||
@@ -1227,7 +1244,7 @@ benchmarks! {
|
||||
},
|
||||
DataSegment {
|
||||
offset: key_len as u32,
|
||||
value: T::MaxValueSize::get().to_le_bytes().into(),
|
||||
value: T::Schedule::get().limits.payload_len.to_le_bytes().into(),
|
||||
},
|
||||
],
|
||||
call_body: Some(body::repeated(API_BENCHMARK_BATCH_SIZE, &[
|
||||
@@ -1363,7 +1380,7 @@ benchmarks! {
|
||||
}: call(origin, instance.addr, 0u32.into(), Weight::max_value(), vec![])
|
||||
|
||||
seal_call_per_code_transfer_input_output_kb {
|
||||
let c in 0 .. T::MaxCodeSize::get() / 1024;
|
||||
let c in 0 .. T::Schedule::get().limits.code_len / 1024;
|
||||
let t in 0 .. 1;
|
||||
let i in 0 .. code::max_pages::<T>() * 64;
|
||||
let o in 0 .. (code::max_pages::<T>() - 1) * 64;
|
||||
@@ -1560,7 +1577,7 @@ benchmarks! {
|
||||
}
|
||||
|
||||
seal_instantiate_per_code_input_output_salt_kb {
|
||||
let c in 0 .. T::MaxCodeSize::get() / 1024;
|
||||
let c in 0 .. T::Schedule::get().limits.code_len / 1024;
|
||||
let i in 0 .. (code::max_pages::<T>() - 1) * 64;
|
||||
let o in 0 .. (code::max_pages::<T>() - 1) * 64;
|
||||
let s in 0 .. (code::max_pages::<T>() - 1) * 64;
|
||||
@@ -1927,7 +1944,7 @@ benchmarks! {
|
||||
|
||||
// w_br_table_per_entry = w_bench
|
||||
instr_br_table_per_entry {
|
||||
let e in 1 .. <CurrentSchedule<T>>::get().limits.br_table_size;
|
||||
let e in 1 .. T::Schedule::get().limits.br_table_size;
|
||||
let entry: Vec<u32> = [0, 1].iter()
|
||||
.cloned()
|
||||
.cycle()
|
||||
@@ -1983,7 +2000,7 @@ benchmarks! {
|
||||
// w_call_indrect = w_bench - 3 * w_param
|
||||
instr_call_indirect {
|
||||
let r in 0 .. INSTR_BENCHMARK_BATCHES;
|
||||
let num_elements = <CurrentSchedule<T>>::get().limits.table_size;
|
||||
let num_elements = T::Schedule::get().limits.table_size;
|
||||
use self::code::TableSegment;
|
||||
let mut sbox = Sandbox::from(&WasmModule::<T>::from(ModuleDefinition {
|
||||
// We need to make use of the stack here in order to trigger stack height
|
||||
@@ -2013,8 +2030,8 @@ benchmarks! {
|
||||
// linearly depend on the amount of parameters to this function.
|
||||
// Please note that this is not necessary with a direct call.
|
||||
instr_call_indirect_per_param {
|
||||
let p in 0 .. <CurrentSchedule<T>>::get().limits.parameters;
|
||||
let num_elements = <CurrentSchedule<T>>::get().limits.table_size;
|
||||
let p in 0 .. T::Schedule::get().limits.parameters;
|
||||
let num_elements = T::Schedule::get().limits.table_size;
|
||||
use self::code::TableSegment;
|
||||
let mut sbox = Sandbox::from(&WasmModule::<T>::from(ModuleDefinition {
|
||||
// We need to make use of the stack here in order to trigger stack height
|
||||
@@ -2044,7 +2061,7 @@ benchmarks! {
|
||||
// w_local_get = w_bench - 1 * w_param
|
||||
instr_local_get {
|
||||
let r in 0 .. INSTR_BENCHMARK_BATCHES;
|
||||
let max_locals = <CurrentSchedule<T>>::get().limits.stack_height;
|
||||
let max_locals = T::Schedule::get().limits.stack_height;
|
||||
let mut call_body = body::repeated_dyn(r * INSTR_BENCHMARK_BATCH_SIZE, vec![
|
||||
RandomGetLocal(0, max_locals),
|
||||
Regular(Instruction::Drop),
|
||||
@@ -2061,7 +2078,7 @@ benchmarks! {
|
||||
// w_local_set = w_bench - 1 * w_param
|
||||
instr_local_set {
|
||||
let r in 0 .. INSTR_BENCHMARK_BATCHES;
|
||||
let max_locals = <CurrentSchedule<T>>::get().limits.stack_height;
|
||||
let max_locals = T::Schedule::get().limits.stack_height;
|
||||
let mut call_body = body::repeated_dyn(r * INSTR_BENCHMARK_BATCH_SIZE, vec![
|
||||
RandomI64Repeated(1),
|
||||
RandomSetLocal(0, max_locals),
|
||||
@@ -2078,7 +2095,7 @@ benchmarks! {
|
||||
// w_local_tee = w_bench - 2 * w_param
|
||||
instr_local_tee {
|
||||
let r in 0 .. INSTR_BENCHMARK_BATCHES;
|
||||
let max_locals = <CurrentSchedule<T>>::get().limits.stack_height;
|
||||
let max_locals = T::Schedule::get().limits.stack_height;
|
||||
let mut call_body = body::repeated_dyn(r * INSTR_BENCHMARK_BATCH_SIZE, vec![
|
||||
RandomI64Repeated(1),
|
||||
RandomTeeLocal(0, max_locals),
|
||||
@@ -2096,7 +2113,7 @@ benchmarks! {
|
||||
// w_global_get = w_bench - 1 * w_param
|
||||
instr_global_get {
|
||||
let r in 0 .. INSTR_BENCHMARK_BATCHES;
|
||||
let max_globals = <CurrentSchedule<T>>::get().limits.globals;
|
||||
let max_globals = T::Schedule::get().limits.globals;
|
||||
let mut sbox = Sandbox::from(&WasmModule::<T>::from(ModuleDefinition {
|
||||
call_body: Some(body::repeated_dyn(r * INSTR_BENCHMARK_BATCH_SIZE, vec![
|
||||
RandomGetGlobal(0, max_globals),
|
||||
@@ -2112,7 +2129,7 @@ benchmarks! {
|
||||
// w_global_set = w_bench - 1 * w_param
|
||||
instr_global_set {
|
||||
let r in 0 .. INSTR_BENCHMARK_BATCHES;
|
||||
let max_globals = <CurrentSchedule<T>>::get().limits.globals;
|
||||
let max_globals = T::Schedule::get().limits.globals;
|
||||
let mut sbox = Sandbox::from(&WasmModule::<T>::from(ModuleDefinition {
|
||||
call_body: Some(body::repeated_dyn(r * INSTR_BENCHMARK_BATCH_SIZE, vec![
|
||||
RandomI64Repeated(1),
|
||||
|
||||
Reference in New Issue
Block a user