Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.

Commit a7e2817

Browse files
atheixermicus
authored andcommitted
contracts: Use proof_size from benchmarks (#13268)
* Avoid reading contract code when it is supplied in the extrinsic * Remove custom proof size injection from schedule * Set benchmarks pov_mode to Measure * Reduce overestimation of code size on re-instrument * ".git/.scripts/commands/bench/bench.sh" pallet dev pallet_contracts * Do not override proof size from benchmark * Do not charge proof size for basic block * Incrase gas limit for tests * Fix deletion queue to also use `proof_size` * Fix tests * Update frame/contracts/src/schedule.rs Co-authored-by: Cyrill Leutwiler <[email protected]> * Fix wrong schedule macro invocations * Remove stale docs * ".git/.scripts/commands/bench/bench.sh" pallet dev pallet_contracts * Handle zero components * ".git/.scripts/commands/bench/bench.sh" pallet dev pallet_contracts * Fix instruction weight --------- Co-authored-by: command-bot <> Co-authored-by: Cyrill Leutwiler <[email protected]>
1 parent 2709ac6 commit a7e2817

File tree

8 files changed

+2173
-2021
lines changed

8 files changed

+2173
-2021
lines changed

frame/contracts/src/benchmarking/mod.rs

Lines changed: 73 additions & 75 deletions
Large diffs are not rendered by default.

frame/contracts/src/schedule.rs

Lines changed: 71 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -447,7 +447,7 @@ macro_rules! call_zero {
447447

448448
macro_rules! cost_args {
449449
($name:ident, $( $arg: expr ),+) => {
450-
(T::WeightInfo::$name($( $arg ),+).saturating_sub(call_zero!($name, $( $arg ),+))).ref_time()
450+
(T::WeightInfo::$name($( $arg ),+).saturating_sub(call_zero!($name, $( $arg ),+)))
451451
}
452452
}
453453

@@ -459,7 +459,7 @@ macro_rules! cost_batched_args {
459459

460460
macro_rules! cost_instr_no_params_with_batch_size {
461461
($name:ident, $batch_size:expr) => {
462-
(cost_args!($name, 1) / u64::from($batch_size)) as u32
462+
(cost_args!($name, 1).ref_time() / u64::from($batch_size)) as u32
463463
};
464464
}
465465

@@ -514,12 +514,6 @@ macro_rules! cost_byte_batched {
514514
};
515515
}
516516

517-
macro_rules! to_weight {
518-
($ref_time:expr $(, $proof_size:expr )?) => {
519-
Weight::from_ref_time($ref_time)$(.set_proof_size($proof_size))?
520-
};
521-
}
522-
523517
impl Default for Limits {
524518
fn default() -> Self {
525519
Self {
@@ -554,8 +548,8 @@ impl<T: Config> Default for InstructionWeights<T> {
554548
br_table_per_entry: cost_instr!(instr_br_table_per_entry, 0),
555549
call: cost_instr!(instr_call, 2),
556550
call_indirect: cost_instr!(instr_call_indirect, 3),
557-
call_indirect_per_param: cost_instr!(instr_call_indirect_per_param, 1),
558-
call_per_local: cost_instr!(instr_call_per_local, 1),
551+
call_indirect_per_param: cost_instr!(instr_call_indirect_per_param, 0),
552+
call_per_local: cost_instr!(instr_call_per_local, 0),
559553
local_get: cost_instr!(instr_local_get, 1),
560554
local_set: cost_instr!(instr_local_set, 1),
561555
local_tee: cost_instr!(instr_local_tee, 2),
@@ -601,116 +595,91 @@ impl<T: Config> Default for InstructionWeights<T> {
601595
}
602596

603597
impl<T: Config> Default for HostFnWeights<T> {
604-
/// PoV should contain all trie nodes that are read during state transition (i.e. block
605-
/// production). Hence we need to charge the `proof_size` weight for every host function which
606-
/// reads storage, namely:
607-
/// - get_storage,
608-
/// - take_storage,
609-
/// - contains_storage,
610-
/// - clear_storage,
611-
/// - set_storage.
612-
///
613-
/// The last two functions write to storage, but they also do read storage in order to return
614-
/// the size of the pre-existed value. Till we have PoV benchmarks implemented, we approximate
615-
/// `proof_size` as being equal to the size of storage read.
616598
fn default() -> Self {
617599
Self {
618-
caller: to_weight!(cost_batched!(seal_caller)),
619-
is_contract: to_weight!(cost_batched!(seal_is_contract)),
620-
code_hash: to_weight!(cost_batched!(seal_code_hash)),
621-
own_code_hash: to_weight!(cost_batched!(seal_own_code_hash)),
622-
caller_is_origin: to_weight!(cost_batched!(seal_caller_is_origin)),
623-
address: to_weight!(cost_batched!(seal_address)),
624-
gas_left: to_weight!(cost_batched!(seal_gas_left)),
625-
balance: to_weight!(cost_batched!(seal_balance)),
626-
value_transferred: to_weight!(cost_batched!(seal_value_transferred)),
627-
minimum_balance: to_weight!(cost_batched!(seal_minimum_balance)),
628-
block_number: to_weight!(cost_batched!(seal_block_number)),
629-
now: to_weight!(cost_batched!(seal_now)),
630-
weight_to_fee: to_weight!(cost_batched!(seal_weight_to_fee)),
631-
gas: to_weight!(cost_batched!(seal_gas)),
632-
input: to_weight!(cost_batched!(seal_input)),
633-
input_per_byte: to_weight!(cost_byte_batched!(seal_input_per_kb)),
634-
r#return: to_weight!(cost!(seal_return)),
635-
return_per_byte: to_weight!(cost_byte!(seal_return_per_kb)),
636-
terminate: to_weight!(cost!(seal_terminate)),
637-
random: to_weight!(cost_batched!(seal_random)),
638-
deposit_event: to_weight!(cost_batched!(seal_deposit_event)),
639-
deposit_event_per_topic: to_weight!(cost_batched_args!(
640-
seal_deposit_event_per_topic_and_kb,
641-
1,
642-
0
643-
)),
644-
deposit_event_per_byte: to_weight!(cost_byte_batched_args!(
600+
caller: cost_batched!(seal_caller),
601+
is_contract: cost_batched!(seal_is_contract),
602+
code_hash: cost_batched!(seal_code_hash),
603+
own_code_hash: cost_batched!(seal_own_code_hash),
604+
caller_is_origin: cost_batched!(seal_caller_is_origin),
605+
address: cost_batched!(seal_address),
606+
gas_left: cost_batched!(seal_gas_left),
607+
balance: cost_batched!(seal_balance),
608+
value_transferred: cost_batched!(seal_value_transferred),
609+
minimum_balance: cost_batched!(seal_minimum_balance),
610+
block_number: cost_batched!(seal_block_number),
611+
now: cost_batched!(seal_now),
612+
weight_to_fee: cost_batched!(seal_weight_to_fee),
613+
// Manually remove proof size from basic block cost.
614+
//
615+
// Due to imperfect benchmarking some host functions incur a small
616+
// amount of proof size. Usually this is ok. However, charging a basic block is such
617+
// a frequent operation that this would be a vast overestimation.
618+
gas: cost_batched!(seal_gas).set_proof_size(0),
619+
input: cost_batched!(seal_input),
620+
input_per_byte: cost_byte_batched!(seal_input_per_kb),
621+
r#return: cost!(seal_return),
622+
return_per_byte: cost_byte!(seal_return_per_kb),
623+
terminate: cost!(seal_terminate),
624+
random: cost_batched!(seal_random),
625+
deposit_event: cost_batched!(seal_deposit_event),
626+
deposit_event_per_topic: cost_batched_args!(seal_deposit_event_per_topic_and_kb, 1, 0),
627+
deposit_event_per_byte: cost_byte_batched_args!(
645628
seal_deposit_event_per_topic_and_kb,
646629
0,
647630
1
648-
)),
649-
debug_message: to_weight!(cost_batched!(seal_debug_message)),
650-
debug_message_per_byte: to_weight!(cost_byte!(seal_debug_message_per_kb)),
651-
set_storage: to_weight!(cost_batched!(seal_set_storage), 1024u64),
652-
set_code_hash: to_weight!(cost_batched!(seal_set_code_hash)),
653-
set_storage_per_new_byte: to_weight!(cost_byte_batched!(seal_set_storage_per_new_kb)),
654-
set_storage_per_old_byte: to_weight!(
655-
cost_byte_batched!(seal_set_storage_per_old_kb),
656-
1u64
657-
),
658-
clear_storage: to_weight!(cost_batched!(seal_clear_storage), 1024u64),
659-
clear_storage_per_byte: to_weight!(cost_byte_batched!(seal_clear_storage_per_kb), 1u64),
660-
contains_storage: to_weight!(cost_batched!(seal_contains_storage), 1024u64),
661-
contains_storage_per_byte: to_weight!(
662-
cost_byte_batched!(seal_contains_storage_per_kb),
663-
1u64
664631
),
665-
get_storage: to_weight!(cost_batched!(seal_get_storage), 1024u64),
666-
get_storage_per_byte: to_weight!(cost_byte_batched!(seal_get_storage_per_kb), 1u64),
667-
take_storage: to_weight!(cost_batched!(seal_take_storage), 1024u64),
668-
take_storage_per_byte: to_weight!(cost_byte_batched!(seal_take_storage_per_kb), 1u64),
669-
transfer: to_weight!(cost_batched!(seal_transfer)),
670-
call: to_weight!(cost_batched!(seal_call)),
671-
delegate_call: to_weight!(cost_batched!(seal_delegate_call)),
672-
call_transfer_surcharge: to_weight!(cost_batched_args!(
673-
seal_call_per_transfer_clone_kb,
674-
1,
675-
0
676-
)),
677-
call_per_cloned_byte: to_weight!(cost_batched_args!(
678-
seal_call_per_transfer_clone_kb,
679-
0,
680-
1
681-
)),
682-
instantiate: to_weight!(cost_batched!(seal_instantiate)),
683-
instantiate_transfer_surcharge: to_weight!(cost_byte_batched_args!(
632+
debug_message: cost_batched!(seal_debug_message),
633+
debug_message_per_byte: cost_byte!(seal_debug_message_per_kb),
634+
set_storage: cost_batched!(seal_set_storage),
635+
set_code_hash: cost_batched!(seal_set_code_hash),
636+
set_storage_per_new_byte: cost_byte_batched!(seal_set_storage_per_new_kb),
637+
set_storage_per_old_byte: cost_byte_batched!(seal_set_storage_per_old_kb),
638+
clear_storage: cost_batched!(seal_clear_storage),
639+
clear_storage_per_byte: cost_byte_batched!(seal_clear_storage_per_kb),
640+
contains_storage: cost_batched!(seal_contains_storage),
641+
contains_storage_per_byte: cost_byte_batched!(seal_contains_storage_per_kb),
642+
get_storage: cost_batched!(seal_get_storage),
643+
get_storage_per_byte: cost_byte_batched!(seal_get_storage_per_kb),
644+
take_storage: cost_batched!(seal_take_storage),
645+
take_storage_per_byte: cost_byte_batched!(seal_take_storage_per_kb),
646+
transfer: cost_batched!(seal_transfer),
647+
call: cost_batched!(seal_call),
648+
delegate_call: cost_batched!(seal_delegate_call),
649+
call_transfer_surcharge: cost_batched_args!(seal_call_per_transfer_clone_kb, 1, 0),
650+
call_per_cloned_byte: cost_byte_batched_args!(seal_call_per_transfer_clone_kb, 0, 1),
651+
instantiate: cost_batched!(seal_instantiate),
652+
instantiate_transfer_surcharge: cost_batched_args!(
684653
seal_instantiate_per_transfer_input_salt_kb,
685654
1,
686655
0,
687656
0
688-
)),
689-
instantiate_per_input_byte: to_weight!(cost_byte_batched_args!(
657+
),
658+
instantiate_per_input_byte: cost_byte_batched_args!(
690659
seal_instantiate_per_transfer_input_salt_kb,
691660
0,
692661
1,
693662
0
694-
)),
695-
instantiate_per_salt_byte: to_weight!(cost_byte_batched_args!(
663+
),
664+
instantiate_per_salt_byte: cost_byte_batched_args!(
696665
seal_instantiate_per_transfer_input_salt_kb,
697666
0,
698667
0,
699668
1
700-
)),
701-
hash_sha2_256: to_weight!(cost_batched!(seal_hash_sha2_256)),
702-
hash_sha2_256_per_byte: to_weight!(cost_byte_batched!(seal_hash_sha2_256_per_kb)),
703-
hash_keccak_256: to_weight!(cost_batched!(seal_hash_keccak_256)),
704-
hash_keccak_256_per_byte: to_weight!(cost_byte_batched!(seal_hash_keccak_256_per_kb)),
705-
hash_blake2_256: to_weight!(cost_batched!(seal_hash_blake2_256)),
706-
hash_blake2_256_per_byte: to_weight!(cost_byte_batched!(seal_hash_blake2_256_per_kb)),
707-
hash_blake2_128: to_weight!(cost_batched!(seal_hash_blake2_128)),
708-
hash_blake2_128_per_byte: to_weight!(cost_byte_batched!(seal_hash_blake2_128_per_kb)),
709-
ecdsa_recover: to_weight!(cost_batched!(seal_ecdsa_recover)),
710-
ecdsa_to_eth_address: to_weight!(cost_batched!(seal_ecdsa_to_eth_address)),
711-
reentrance_count: to_weight!(cost_batched!(seal_reentrance_count)),
712-
account_reentrance_count: to_weight!(cost_batched!(seal_account_reentrance_count)),
713-
instantiation_nonce: to_weight!(cost_batched!(seal_instantiation_nonce)),
669+
),
670+
hash_sha2_256: cost_batched!(seal_hash_sha2_256),
671+
hash_sha2_256_per_byte: cost_byte_batched!(seal_hash_sha2_256_per_kb),
672+
hash_keccak_256: cost_batched!(seal_hash_keccak_256),
673+
hash_keccak_256_per_byte: cost_byte_batched!(seal_hash_keccak_256_per_kb),
674+
hash_blake2_256: cost_batched!(seal_hash_blake2_256),
675+
hash_blake2_256_per_byte: cost_byte_batched!(seal_hash_blake2_256_per_kb),
676+
hash_blake2_128: cost_batched!(seal_hash_blake2_128),
677+
hash_blake2_128_per_byte: cost_byte_batched!(seal_hash_blake2_128_per_kb),
678+
ecdsa_recover: cost_batched!(seal_ecdsa_recover),
679+
ecdsa_to_eth_address: cost_batched!(seal_ecdsa_to_eth_address),
680+
reentrance_count: cost_batched!(seal_reentrance_count),
681+
account_reentrance_count: cost_batched!(seal_account_reentrance_count),
682+
instantiation_nonce: cost_batched!(seal_instantiation_nonce),
714683
_phantom: PhantomData,
715684
}
716685
}

frame/contracts/src/storage.rs

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -245,23 +245,21 @@ impl<T: Config> Storage<T> {
245245
/// Calculates the weight that is necessary to remove one key from the trie and how many
246246
/// of those keys can be deleted from the deletion queue given the supplied queue length
247247
/// and weight limit.
248-
pub fn deletion_budget(queue_len: usize, weight_limit: Weight) -> (u64, u32) {
248+
pub fn deletion_budget(queue_len: usize, weight_limit: Weight) -> (Weight, u32) {
249249
let base_weight = T::WeightInfo::on_process_deletion_queue_batch();
250250
let weight_per_queue_item = T::WeightInfo::on_initialize_per_queue_item(1) -
251251
T::WeightInfo::on_initialize_per_queue_item(0);
252-
let weight_per_key = (T::WeightInfo::on_initialize_per_trie_key(1) -
253-
T::WeightInfo::on_initialize_per_trie_key(0))
254-
.ref_time();
252+
let weight_per_key = T::WeightInfo::on_initialize_per_trie_key(1) -
253+
T::WeightInfo::on_initialize_per_trie_key(0);
255254
let decoding_weight = weight_per_queue_item.saturating_mul(queue_len as u64);
256255

257256
// `weight_per_key` being zero makes no sense and would constitute a failure to
258257
// benchmark properly. We opt for not removing any keys at all in this case.
259258
let key_budget = weight_limit
260259
.saturating_sub(base_weight)
261260
.saturating_sub(decoding_weight)
262-
.checked_div(weight_per_key)
263-
.unwrap_or(Weight::zero())
264-
.ref_time() as u32;
261+
.checked_div_per_component(&weight_per_key)
262+
.unwrap_or(0) as u32;
265263

266264
(weight_per_key, key_budget)
267265
}
@@ -306,10 +304,7 @@ impl<T: Config> Storage<T> {
306304
}
307305

308306
<DeletionQueue<T>>::put(queue);
309-
let ref_time_weight = weight_limit
310-
.ref_time()
311-
.saturating_sub(weight_per_key.saturating_mul(u64::from(remaining_key_budget)));
312-
Weight::from_ref_time(ref_time_weight)
307+
weight_limit.saturating_sub(weight_per_key.saturating_mul(u64::from(remaining_key_budget)))
313308
}
314309

315310
/// Generates a unique trie id by returning `hash(account_id ++ nonce)`.

frame/contracts/src/tests.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -383,7 +383,7 @@ impl Contains<RuntimeCall> for TestFilter {
383383
}
384384

385385
parameter_types! {
386-
pub const DeletionWeightLimit: Weight = Weight::from_ref_time(500_000_000_000);
386+
pub const DeletionWeightLimit: Weight = GAS_LIMIT;
387387
pub static UnstableInterface: bool = true;
388388
}
389389

@@ -416,7 +416,7 @@ pub const BOB: AccountId32 = AccountId32::new([2u8; 32]);
416416
pub const CHARLIE: AccountId32 = AccountId32::new([3u8; 32]);
417417
pub const DJANGO: AccountId32 = AccountId32::new([4u8; 32]);
418418

419-
pub const GAS_LIMIT: Weight = Weight::from_parts(100_000_000_000, 512 * 1024);
419+
pub const GAS_LIMIT: Weight = Weight::from_parts(100_000_000_000, 3 * 1024 * 1024);
420420

421421
pub struct ExtBuilder {
422422
existential_deposit: u64,
@@ -2322,7 +2322,7 @@ fn lazy_removal_does_no_run_on_low_remaining_weight() {
23222322
fn lazy_removal_does_not_use_all_weight() {
23232323
let (code, _hash) = compile_module::<Test>("self_destruct").unwrap();
23242324

2325-
let weight_limit = Weight::from_ref_time(5_000_000_000);
2325+
let weight_limit = Weight::from_parts(5_000_000_000, 100 * 1024);
23262326
let mut ext = ExtBuilder::default().existential_deposit(50).build();
23272327

23282328
let (trie, vals, weight_per_key) = ext.execute_with(|| {
@@ -2396,7 +2396,7 @@ fn lazy_removal_does_not_use_all_weight() {
23962396
let weight_used = Storage::<Test>::process_deletion_queue_batch(weight_limit);
23972397

23982398
// We have one less key in our trie than our weight limit suffices for
2399-
assert_eq!(weight_used, weight_limit - Weight::from_ref_time(weight_per_key));
2399+
assert_eq!(weight_used, weight_limit - weight_per_key);
24002400

24012401
// All the keys are removed
24022402
for val in vals {

0 commit comments

Comments
 (0)