From 9eab023f22790b83e293979c6ce44748fcc34e92 Mon Sep 17 00:00:00 2001 From: JesseAbram <33698952+JesseAbram@users.noreply.github.com> Date: Thu, 24 Oct 2024 14:20:45 -0400 Subject: [PATCH] Check current signers still validators (#1097) * Check current signers still validators * update * tests * end of day push * working reshare * clean * remove mutable * test * update * threhsold limit * fix test * remove old signer * clean * metadata * fmt * test * update benchmarks * working benchmarks * fix benches * Update crates/shared/src/types.rs Co-authored-by: peg * correct truncation * remove hash comparison * Apply suggestions from code review Co-authored-by: Hernando Castano * fix * fix * fix benchmark * fix benchmark * fmt * fix * comment * Update crates/threshold-signature-server/src/validator/api.rs Co-authored-by: David * fix type --------- Co-authored-by: peg Co-authored-by: Hernando Castano Co-authored-by: David --- crates/client/entropy_metadata.scale | Bin 209399 -> 209375 bytes crates/protocol/src/execute_protocol.rs | 3 +- crates/protocol/tests/helpers/mod.rs | 3 +- crates/shared/src/types.rs | 8 +- .../src/signing_client/api.rs | 3 +- .../src/validator/api.rs | 53 ++++---- .../src/validator/tests.rs | 18 ++- .../tests/register_sign_reshare_sign.rs | 17 +-- node/cli/src/chain_spec/integration_tests.rs | 2 +- pallets/propagation/src/lib.rs | 2 +- pallets/propagation/src/tests.rs | 4 +- pallets/staking/src/benchmarking.rs | 47 ++++--- pallets/staking/src/lib.rs | 65 ++++++--- pallets/staking/src/tests.rs | 52 ++++++-- pallets/staking/src/weights.rs | 104 ++++++++------- .../src/weights/pallet_staking_extension.rs | 123 +++++++++--------- 16 files changed, 301 insertions(+), 203 deletions(-) diff --git a/crates/client/entropy_metadata.scale b/crates/client/entropy_metadata.scale index c2927b48e488259151daccc9848e810f25aba892..c8e04d4635263100651d3b91fb5a7e923f53f639 100644 GIT binary patch delta 124 zcmezVnCJduo()FxBxS-=+nzN{Wl)6O)tkOY=%h7-c3G&U-Aalb2c^U!0kq tms(W(l#$T@q!_AU^27NGi#z6fGqP>&e06^cA*Jne>KV7ssb`Ab1OVc$F*yJL delta 155 zcmccrnCJUro()Fx>@$+{Q&N+ytP*o_@_|$th#i)iY*T7s$H1slQd}ILn4Fwnnpa}N zh)wBa?|F~KH1bl*&*;s_zB%jF{VDj=wKvx@Zf~w< HirEAJY(qBt diff --git a/crates/protocol/src/execute_protocol.rs b/crates/protocol/src/execute_protocol.rs index c80af4574..c7df58fe0 100644 --- a/crates/protocol/src/execute_protocol.rs +++ b/crates/protocol/src/execute_protocol.rs @@ -334,6 +334,7 @@ pub async fn execute_reshare( chans: Channels, threshold_pair: &sr25519::Pair, inputs: KeyResharingInputs, + verifiers: &BTreeSet, aux_info_option: Option>, ) -> Result< (ThresholdKeyShare, AuxInfo), @@ -350,7 +351,7 @@ pub async fn execute_reshare( &mut OsRng, SynedrionSessionId::from_seed(session_id_hash.as_slice()), pair, - &inputs.new_holders, + verifiers, inputs.clone(), ) .map_err(ProtocolExecutionErr::SessionCreation)?; diff --git a/crates/protocol/tests/helpers/mod.rs b/crates/protocol/tests/helpers/mod.rs index a1a0f60e9..cae40306a 100644 --- a/crates/protocol/tests/helpers/mod.rs +++ b/crates/protocol/tests/helpers/mod.rs @@ -144,7 +144,8 @@ pub async fn server( new_threshold: old_key.threshold(), }; - let new_keyshare = execute_reshare(session_id, channels, &pair, inputs, None).await?; + let new_keyshare = + execute_reshare(session_id, channels, &pair, inputs, &party_ids, None).await?; Ok(ProtocolOutput::Reshare(new_keyshare.0)) }, SessionId::Dkg { .. } => { diff --git a/crates/shared/src/types.rs b/crates/shared/src/types.rs index 43b7b6d9e..803c9f57c 100644 --- a/crates/shared/src/types.rs +++ b/crates/shared/src/types.rs @@ -37,8 +37,8 @@ pub type BlockNumber = u32; #[derive(Clone, Encode, Decode, Debug, Eq, PartialEq, TypeInfo)] pub struct ValidatorInfo { pub x25519_public_key: X25519PublicKey, - pub ip_address: codec::alloc::vec::Vec, - pub tss_account: codec::alloc::vec::Vec, + pub ip_address: Vec, + pub tss_account: Vec, } /// Offchain worker message for initiating the initial jumpstart DKG @@ -55,8 +55,8 @@ pub struct OcwMessageDkg { #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] #[derive(Clone, Encode, Decode, Debug, Eq, PartialEq, TypeInfo)] pub struct OcwMessageReshare { - // Stash address of new signer - pub new_signer: Vec, + // Stash addresses of new signers + pub new_signers: Vec>, pub block_number: BlockNumber, } diff --git a/crates/threshold-signature-server/src/signing_client/api.rs b/crates/threshold-signature-server/src/signing_client/api.rs index 973499eec..eb55d12a3 100644 --- a/crates/threshold-signature-server/src/signing_client/api.rs +++ b/crates/threshold-signature-server/src/signing_client/api.rs @@ -205,7 +205,8 @@ pub async fn do_proactive_refresh( .await?; let result = - execute_reshare(session_id, channels, signer.signer(), inputs, Some(aux_info)).await?; + execute_reshare(session_id, channels, signer.signer(), inputs, &party_ids, Some(aux_info)) + .await?; Ok(result) } diff --git a/crates/threshold-signature-server/src/validator/api.rs b/crates/threshold-signature-server/src/validator/api.rs index b0be347fb..aff360cb5 100644 --- a/crates/threshold-signature-server/src/validator/api.rs +++ b/crates/threshold-signature-server/src/validator/api.rs @@ -106,7 +106,7 @@ pub async fn new_reshare( .map_err(|e| ValidatorErr::UserError(e.to_string()))?; let old_holder: Option> = - if data.new_signer == my_stash_address.encode() { + if data.new_signers.contains(&my_stash_address.encode()) { None } else { let kvdb_result = app_state.kv_store.kv().get(&hex::encode(NETWORK_PARENT_KEY)).await?; @@ -116,14 +116,15 @@ pub async fn new_reshare( Some(OldHolder { key_share: key_share.0 }) }; - let party_ids: BTreeSet = + // new_holders -> From chain next_signers (old_holders (currently forced to be t) + new_holders) + // also acts as verifiers as is everyone in the party + let new_holders: BTreeSet = validators_info.iter().cloned().map(|x| PartyId::new(x.tss_account)).collect(); - - let pruned_old_holders = - prune_old_holders(&api, &rpc, data.new_signer, validators_info.clone()).await?; - + // old holders -> next_signers - new_signers (will be at least t) + let old_holders = + &prune_old_holders(&api, &rpc, data.new_signers, validators_info.clone()).await?; let old_holders: BTreeSet = - pruned_old_holders.into_iter().map(|x| PartyId::new(x.tss_account)).collect(); + old_holders.iter().map(|x| PartyId::new(x.tss_account.clone())).collect(); let new_holder = NewHolder { verifying_key: decoded_verifying_key, @@ -139,7 +140,7 @@ pub async fn new_reshare( let inputs = KeyResharingInputs { old_holder, new_holder: Some(new_holder), - new_holders: party_ids.clone(), + new_holders: new_holders.clone(), new_threshold: threshold as usize, }; @@ -157,7 +158,6 @@ pub async fn new_reshare( converted_validator_info.push(validator_info.clone()); tss_accounts.push(validator_info.tss_account.clone()); } - let channels = get_channels( &app_state.listener_state, converted_validator_info, @@ -169,7 +169,8 @@ pub async fn new_reshare( .await?; let (new_key_share, aux_info) = - execute_reshare(session_id.clone(), channels, signer.signer(), inputs, None).await?; + execute_reshare(session_id.clone(), channels, signer.signer(), inputs, &new_holders, None) + .await?; let serialized_key_share = key_serialize(&(new_key_share, aux_info)) .map_err(|_| ProtocolErr::KvSerialize("Kv Serialize Error".to_string()))?; @@ -273,8 +274,8 @@ pub async fn validate_new_reshare( .await? .ok_or_else(|| ValidatorErr::ChainFetch("Not Currently in a reshare"))?; - if reshare_data.new_signer != chain_data.new_signer - || chain_data.block_number != reshare_data.block_number + if chain_data.block_number != reshare_data.block_number.saturating_sub(1) + || chain_data.new_signers != reshare_data.new_signers { return Err(ValidatorErr::InvalidData); } @@ -365,20 +366,24 @@ pub fn check_forbidden_key(key: &str) -> Result<(), ValidatorErr> { pub async fn prune_old_holders( api: &OnlineClient, rpc: &LegacyRpcMethods, - new_signer: Vec, + new_signers: Vec>, validators_info: Vec, ) -> Result, ValidatorErr> { - Ok(if !new_signer.is_empty() { - let address_slice: &[u8; 32] = &new_signer.clone().try_into().unwrap(); - let new_signer_address = AccountId32(*address_slice); - let new_signer_info = &get_validators_info(api, rpc, vec![new_signer_address]) - .await - .map_err(|e| ValidatorErr::UserError(e.to_string()))?[0]; - validators_info - .iter() - .filter(|x| x.tss_account != new_signer_info.tss_account) - .cloned() - .collect() + Ok(if !new_signers.is_empty() { + let mut filtered_validators_info = vec![]; + for new_signer in new_signers { + let address_slice: &[u8; 32] = &new_signer.clone().try_into().unwrap(); + let new_signer_address = AccountId32(*address_slice); + let new_signer_info = &get_validators_info(api, rpc, vec![new_signer_address]) + .await + .map_err(|e| ValidatorErr::UserError(e.to_string()))?[0]; + filtered_validators_info = validators_info + .iter() + .filter(|x| x.tss_account != new_signer_info.tss_account) + .cloned() + .collect::>(); + } + filtered_validators_info } else { validators_info.clone() }) diff --git a/crates/threshold-signature-server/src/validator/tests.rs b/crates/threshold-signature-server/src/validator/tests.rs index d34c4504f..4e5cd270c 100644 --- a/crates/threshold-signature-server/src/validator/tests.rs +++ b/crates/threshold-signature-server/src/validator/tests.rs @@ -76,7 +76,7 @@ async fn test_reshare() { let (_validator_ips, _validator_ids) = spawn_testing_validators(ChainSpecType::Integration).await; - let validator_ports = vec![3001, 3002, 3003, 3004]; + let validator_ports = vec![3002, 3003, 3004]; let api = get_api(&cxt.ws_url).await.unwrap(); let rpc = get_rpc(&cxt.ws_url).await.unwrap(); @@ -113,13 +113,15 @@ async fn test_reshare() { let new_signer = all_validators.iter().find(|v| !signer_stash_accounts.contains(v)).unwrap(); let block_number = TEST_RESHARE_BLOCK_NUMBER; - let onchain_reshare_request = - OcwMessageReshare { new_signer: new_signer.0.to_vec(), block_number }; + let onchain_reshare_request = OcwMessageReshare { + new_signers: vec![new_signer.0.to_vec()], + block_number: block_number - 1, + }; - run_to_block(&rpc, block_number + 1).await; + run_to_block(&rpc, block_number).await; // Send the OCW message to all TS servers who don't have a chain node let response_results = join_all( - validator_ports[1..] + validator_ports .iter() .map(|port| { client @@ -323,7 +325,8 @@ async fn test_reshare_validation_fail() { let kv = setup_client().await; let block_number = rpc.chain_get_header(None).await.unwrap().unwrap().number + 1; - let mut ocw_message = OcwMessageReshare { new_signer: dave.public().encode(), block_number }; + let mut ocw_message = + OcwMessageReshare { new_signers: vec![dave.public().encode()], block_number }; let err_stale_data = validate_new_reshare(&api, &rpc, &ocw_message, &kv).await.map_err(|e| e.to_string()); @@ -361,7 +364,8 @@ async fn test_reshare_validation_fail_not_in_reshare() { let kv = setup_client().await; let block_number = rpc.chain_get_header(None).await.unwrap().unwrap().number + 1; - let ocw_message = OcwMessageReshare { new_signer: alice.public().encode(), block_number }; + let ocw_message = + OcwMessageReshare { new_signers: vec![alice.public().encode()], block_number }; run_to_block(&rpc, block_number + 1).await; diff --git a/crates/threshold-signature-server/tests/register_sign_reshare_sign.rs b/crates/threshold-signature-server/tests/register_sign_reshare_sign.rs index 3f6660aa6..3115d30ec 100644 --- a/crates/threshold-signature-server/tests/register_sign_reshare_sign.rs +++ b/crates/threshold-signature-server/tests/register_sign_reshare_sign.rs @@ -153,19 +153,16 @@ async fn do_reshare(api: &OnlineClient, rpc: &LegacyRpcMethods("Charlie//stash")],), + mock_signer_rotate: (true, mock_signer_rotate_data, vec![get_account_id_from_seed::("Charlie//stash")]), }, "elections": ElectionsConfig { members: endowed_accounts diff --git a/pallets/propagation/src/lib.rs b/pallets/propagation/src/lib.rs index 21ebb76a9..fcea66d47 100644 --- a/pallets/propagation/src/lib.rs +++ b/pallets/propagation/src/lib.rs @@ -174,7 +174,7 @@ pub mod pallet { BlockNumberFor::::try_into(block_number).unwrap_or_default(); let req_body = OcwMessageReshare { - new_signer: reshare_data.new_signer, + new_signers: reshare_data.new_signers, // subtract 1 from blocknumber since the request is from the last block block_number: converted_block_number.saturating_sub(1), }; diff --git a/pallets/propagation/src/tests.rs b/pallets/propagation/src/tests.rs index 52ff5b9da..05b597633 100644 --- a/pallets/propagation/src/tests.rs +++ b/pallets/propagation/src/tests.rs @@ -59,7 +59,7 @@ fn knows_how_to_mock_several_http_calls() { uri: "http://localhost:3001/validator/reshare".into(), sent: true, response: Some([].to_vec()), - body: [32, 1, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0].to_vec(), + body: [4, 32, 1, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0].to_vec(), ..Default::default() }); state.expect_request(testing::PendingRequest { @@ -94,7 +94,7 @@ fn knows_how_to_mock_several_http_calls() { Propagation::post_reshare(7).unwrap(); pallet_staking_extension::ReshareData::::put(ReshareInfo { block_number: 7, - new_signer: 1u64.encode(), + new_signers: vec![1u64.encode()], }); // now triggers Propagation::post_reshare(7).unwrap(); diff --git a/pallets/staking/src/benchmarking.rs b/pallets/staking/src/benchmarking.rs index ab093c334..126cd6fed 100644 --- a/pallets/staking/src/benchmarking.rs +++ b/pallets/staking/src/benchmarking.rs @@ -29,8 +29,8 @@ use frame_support::{ use frame_system::{EventRecord, RawOrigin}; use pallet_parameters::{SignersInfo, SignersSize}; use pallet_staking::{ - Event as FrameStakingEvent, MaxNominationsOf, Nominations, Pallet as FrameStaking, - RewardDestination, ValidatorPrefs, + Event as FrameStakingEvent, MaxNominationsOf, MaxValidatorsCount, Nominations, + Pallet as FrameStaking, RewardDestination, ValidatorPrefs, }; use sp_std::{vec, vec::Vec}; @@ -272,7 +272,7 @@ benchmarks! { let block_number = 1; let nonce = NULL_ARR; let x25519_public_key = NULL_ARR; - let endpoint = b"http://localhost:3001".to_vec(); + let endpoint = vec![]; let validate_also = false; prep_bond_and_validate::( @@ -417,13 +417,27 @@ benchmarks! { new_session { let c in 1 .. MAX_SIGNERS as u32 - 1; let l in 0 .. MAX_SIGNERS as u32; + let v in 50 .. 100 as u32; + let r in 0 .. MAX_SIGNERS as u32; + + // c -> current signer size + // l -> Add in new_signer rounds so next signer is in current signer re-run checks + // v -> number of validators, 100 is fine as a bounder, can add more + // r -> adds remove indexes in let caller: T::AccountId = whitelisted_caller(); + let mut validator_ids = create_validators::(v, 1); + let second_signer: T::AccountId = account("second_signer", 0, 10); + let second_signer_id = + ::ValidatorId::try_from(second_signer.clone()) + .or(Err(Error::::InvalidValidatorId)) + .unwrap(); + let mut signers = vec![second_signer_id.clone(); c as usize]; // For the purpose of the bench these values don't actually matter, we just care that there's a // storage entry available SignersInfo::::put(SignersSize { - total_signers: MAX_SIGNERS, + total_signers: 5, threshold: 3, last_session_change: 0, }); @@ -432,23 +446,20 @@ benchmarks! { .or(Err(Error::::InvalidValidatorId)) .unwrap(); - let second_signer: T::AccountId = account("second_signer", 0, SEED); - let second_signer_id = - ::ValidatorId::try_from(second_signer.clone()) - .or(Err(Error::::InvalidValidatorId)) - .unwrap(); - - // full signer list leaving room for one extra validator - let mut signers = vec![second_signer_id.clone(); c as usize]; - - Signers::::put(signers.clone()); - signers.push(second_signer_id.clone()); - // place new signer in the signers struct in different locations to calculate random selection // re-run - signers[l as usize % c as usize] = validator_id.clone(); + // as well validators may be dropped before chosen + signers[l as usize % c as usize] = validator_ids[l as usize % c as usize].clone(); + + // place signers into validators so they won't get dropped + for i in 0 .. r { + if i > signers.len() as u32 && i > validator_ids.len() as u32 { + validator_ids[i as usize] = signers[i as usize].clone(); + } + } + Signers::::put(signers.clone()); }: { - let _ = Staking::::new_session_handler(&signers); + let _ = Staking::::new_session_handler(&validator_ids); } verify { assert!(NextSigners::::get().is_some()); diff --git a/pallets/staking/src/lib.rs b/pallets/staking/src/lib.rs index 0ee229299..cd583982d 100644 --- a/pallets/staking/src/lib.rs +++ b/pallets/staking/src/lib.rs @@ -133,7 +133,7 @@ pub mod pallet { #[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, TypeInfo, Default)] pub struct ReshareInfo { - pub new_signer: Vec, + pub new_signers: Vec>, pub block_number: BlockNumber, } @@ -277,14 +277,17 @@ pub mod pallet { // mocks a signer rotation for tss new_reshare tests if self.mock_signer_rotate.0 { let next_signers = &mut self.mock_signer_rotate.1.clone(); - next_signers.push(self.mock_signer_rotate.2[0].clone()); + let mut new_signers = vec![]; + for new_signer in self.mock_signer_rotate.2.clone() { + next_signers.push(new_signer.clone()); + new_signers.push(new_signer.encode()) + } let next_signers = next_signers.to_vec(); NextSigners::::put(NextSignerInfo { next_signers, confirmations: vec![] }); - ReshareData::::put(ReshareInfo { // To give enough time for test_reshare setup block_number: TEST_RESHARE_BLOCK_NUMBER.into(), - new_signer: self.mock_signer_rotate.clone().2[0].encode(), + new_signers, }) } } @@ -670,15 +673,46 @@ pub mod pallet { return Ok(weight); } - let mut new_signer = vec![]; + let mut new_signers: Vec> = vec![]; let mut count = 0u32; + let mut remove_indicies_len = 0; + // removes first signer and pushes new signer to back if total signers not increased + if current_signers_length >= signers_info.total_signers as usize { + let mut remove_indicies = vec![]; + // Finds signers that are no longer validators to remove + for (i, current_signer) in current_signers.clone().into_iter().enumerate() { + if !validators.contains(¤t_signer) { + remove_indicies.push(i); + } + } + if remove_indicies.is_empty() { + current_signers.remove(0); + } else { + remove_indicies_len = remove_indicies.len(); + // reverses vec so as signers removed it does not change location + let remove_indicies_reversed: Vec<_> = remove_indicies.iter().rev().collect(); + // truncated as a current limitation see issue: https://github.com/entropyxyz/entropy-core/issues/1114 + let truncated = if remove_indicies_reversed.len() + >= (signers_info.total_signers as usize - signers_info.threshold as usize) + { + remove_indicies_reversed[..(signers_info.total_signers as usize + - signers_info.threshold as usize)] + .to_vec() + } else { + remove_indicies_reversed + }; - if current_signers_length <= signers_info.total_signers as usize { + for remove_index in truncated { + current_signers.remove(*remove_index); + } + } + } + + while current_signers.len() < signers_info.total_signers as usize { let mut randomness = Self::get_randomness(); // grab a current signer to initiate value let mut next_signer_up = ¤t_signers[0].clone(); let mut index; - // loops to find signer in validator that is not already signer while current_signers.contains(next_signer_up) { index = randomness.next_u32() % validators.len() as u32; @@ -687,14 +721,8 @@ pub mod pallet { } current_signers.push(next_signer_up.clone()); - new_signer = next_signer_up.encode(); + new_signers.push(next_signer_up.encode()); } - - // removes first signer and pushes new signer to back if total signers not increased - if current_signers_length >= signers_info.total_signers as usize { - current_signers.remove(0); - } - NextSigners::::put(NextSignerInfo { next_signers: current_signers.clone(), confirmations: vec![], @@ -704,7 +732,7 @@ pub mod pallet { let current_block_number = >::block_number(); let reshare_info = ReshareInfo { block_number: current_block_number + sp_runtime::traits::One::one(), - new_signer, + new_signers, }; ReshareData::::put(reshare_info); @@ -712,7 +740,12 @@ pub mod pallet { jump_start_details.parent_key_threshold = signers_info.threshold }); - weight = ::WeightInfo::new_session(current_signers.len() as u32, count); + weight = ::WeightInfo::new_session( + current_signers.len() as u32, + count, + validators.len() as u32, + remove_indicies_len as u32, + ); Ok(weight) } diff --git a/pallets/staking/src/tests.rs b/pallets/staking/src/tests.rs index a1acf8ddc..98faa0d24 100644 --- a/pallets/staking/src/tests.rs +++ b/pallets/staking/src/tests.rs @@ -438,19 +438,18 @@ fn it_tests_new_session_handler() { last_session_change: 0, }); - assert_ok!(Staking::new_session_handler(&[1, 2, 3])); - // takes signers original (5,6) pops off first 5, adds (fake randomness in mock so adds 1) + assert_ok!(Staking::new_session_handler(&[1, 5, 6])); + // takes signers original (5,6) pops off one and adds in new validator assert_eq!(Staking::next_signers().unwrap().next_signers, vec![6, 1]); - assert_eq!( Staking::reshare_data().block_number, 101, "Check reshare block start at 100 + 1" ); assert_eq!( - Staking::reshare_data().new_signer, - 1u64.encode(), - "Check reshare next signer up is 1" + Staking::reshare_data().new_signers, + vec![1u64.encode()], + "Check reshare next signer up is 3" ); assert_eq!( Staking::jump_start_progress().parent_key_threshold, @@ -463,11 +462,6 @@ fn it_tests_new_session_handler() { 101, "Check reshare block start at 100 + 1" ); - assert_eq!( - Staking::reshare_data().new_signer, - 1u64.encode(), - "Check reshare next signer up is 1" - ); assert_ok!(Staking::new_session_handler(&[6, 5, 3])); // takes 3 and leaves 5 and 6 since already in signer group @@ -476,6 +470,42 @@ fn it_tests_new_session_handler() { assert_ok!(Staking::new_session_handler(&[1])); // does nothing as not enough validators assert_eq!(Staking::next_signers().unwrap().next_signers, vec![6, 3]); + + // reduce threshold to make sure next signers does not drop > then threshold of current signers + pallet_parameters::SignersInfo::::put(SignersSize { + total_signers: 2, + threshold: 1, + last_session_change: 0, + }); + + assert_ok!(Staking::new_session_handler(&[1, 2, 3])); + assert_eq!(Staking::next_signers().unwrap().next_signers, vec![5, 1]); + }); +} + +#[test] +fn it_tests_new_session_handler_truncating() { + new_test_ext().execute_with(|| { + // Start with current validators as 7 and 8 based off the Mock `GenesisConfig`. + Signers::::put(vec![7, 8]); + System::set_block_number(100); + pallet_parameters::SignersInfo::::put(SignersSize { + total_signers: 2, + threshold: 2, + last_session_change: 0, + }); + // test truncates none if t and n = 0 + assert_ok!(Staking::new_session_handler(&[1, 2, 3])); + assert_eq!(Staking::next_signers().unwrap().next_signers, vec![7, 8]); + + pallet_parameters::SignersInfo::::put(SignersSize { + total_signers: 2, + threshold: 1, + last_session_change: 0, + }); + // test truncates 1 if n - t = 1 + assert_ok!(Staking::new_session_handler(&[1, 2, 3])); + assert_eq!(Staking::next_signers().unwrap().next_signers, vec![7, 1]); }); } diff --git a/pallets/staking/src/weights.rs b/pallets/staking/src/weights.rs index f04bfbe25..012f873ce 100644 --- a/pallets/staking/src/weights.rs +++ b/pallets/staking/src/weights.rs @@ -61,7 +61,7 @@ pub trait WeightInfo { fn confirm_key_reshare_confirmed(c: u32) -> Weight; fn confirm_key_reshare_completed() -> Weight; fn new_session_base_weight(s: u32) -> Weight; - fn new_session(c: u32, l: u32) -> Weight; + fn new_session(c: u32, l: u32, v: u32, r: u32) -> Weight; } /// Weights for pallet_staking_extension using the Substrate node and recommended hardware. @@ -284,46 +284,53 @@ impl WeightInfo for SubstrateWeight { } /// Storage: `StakingExtension::Signers` (r:1 w:0) /// Proof: `StakingExtension::Signers` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Parameters::SignersInfo` (r:1 w:0) + /// Proof: `Parameters::SignersInfo` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// The range of component `s` is `[2, 15]`. fn new_session_base_weight(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `254 + s * (32 ±0)` - // Estimated: `1739 + s * (32 ±0)` - // Minimum execution time: 7_000_000 picoseconds. - Weight::from_parts(7_682_879, 0) - .saturating_add(Weight::from_parts(0, 1739)) + // Measured: `266 + s * (32 ±0)` + // Estimated: `1751 + s * (32 ±0)` + // Minimum execution time: 5_000_000 picoseconds. + Weight::from_parts(5_772_373, 0) + .saturating_add(Weight::from_parts(0, 1751)) + // Standard Error: 22_735 + .saturating_add(Weight::from_parts(15_564, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(Weight::from_parts(0, 32).saturating_mul(s.into())) } - /// Storage: `StakingExtension::Signers` (r:1 w:0) + /// Storage: `StakingExtension::Signers` (r:1 w:0) /// Proof: `StakingExtension::Signers` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Storage: `Parameters::SignersInfo` (r:1 w:0) /// Proof: `Parameters::SignersInfo` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Babe::NextRandomness` (r:1 w:0) - /// Proof: `Babe::NextRandomness` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) - /// Storage: `Babe::EpochStart` (r:1 w:0) - /// Proof: `Babe::EpochStart` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) /// Storage: `StakingExtension::JumpStartProgress` (r:1 w:1) /// Proof: `StakingExtension::JumpStartProgress` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Storage: `StakingExtension::ReshareData` (r:0 w:1) /// Proof: `StakingExtension::ReshareData` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Storage: `StakingExtension::NextSigners` (r:0 w:1) /// Proof: `StakingExtension::NextSigners` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Babe::NextRandomness` (r:1 w:0) + /// Proof: `Babe::NextRandomness` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) + /// Storage: `Babe::EpochStart` (r:1 w:0) + /// Proof: `Babe::EpochStart` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) /// The range of component `c` is `[1, 14]`. /// The range of component `l` is `[0, 15]`. - fn new_session(c: u32, l: u32, ) -> Weight { + /// The range of component `v` is `[50, 100]`. + /// The range of component `r` is `[0, 15]`. + fn new_session(c: u32, _l: u32, v: u32, r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `482 + c * (32 ±0)` - // Estimated: `1966 + c * (32 ±0)` - // Minimum execution time: 13_000_000 picoseconds. - Weight::from_parts(12_791_889, 0) - .saturating_add(Weight::from_parts(0, 1966)) - // Standard Error: 22_917 - .saturating_add(Weight::from_parts(65_067, 0).saturating_mul(c.into())) - // Standard Error: 19_636 - .saturating_add(Weight::from_parts(30_071, 0).saturating_mul(l.into())) - .saturating_add(T::DbWeight::get().reads(5)) + // Measured: `509 + c * (15 ±0)` + // Estimated: `2096 + c * (15 ±0) + r * (11364552184692736 ±340_282_366_920_938_463_463_374_607_431_768_211_455) + v * (18 ±2_466_463_158_054_763_722_435_771_498_496)` + // Minimum execution time: 10_000_000 picoseconds. + Weight::from_parts(16_699_930, 0) + .saturating_add(Weight::from_parts(0, 2096)) + // Standard Error: 2_130 + .saturating_add(Weight::from_parts(7_887, 0).saturating_mul(v.into())) + .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(3)) - .saturating_add(Weight::from_parts(0, 32).saturating_mul(c.into())) + .saturating_add(Weight::from_parts(0, 15).saturating_mul(c.into())) + .saturating_add(Weight::from_parts(0, 11364552184692736).saturating_mul(r.into())) + .saturating_add(Weight::from_parts(0, 18).saturating_mul(v.into())) } } @@ -546,45 +553,52 @@ impl WeightInfo for () { } /// Storage: `StakingExtension::Signers` (r:1 w:0) /// Proof: `StakingExtension::Signers` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Parameters::SignersInfo` (r:1 w:0) + /// Proof: `Parameters::SignersInfo` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// The range of component `s` is `[2, 15]`. fn new_session_base_weight(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `254 + s * (32 ±0)` - // Estimated: `1739 + s * (32 ±0)` - // Minimum execution time: 7_000_000 picoseconds. - Weight::from_parts(7_682_879, 0) - .saturating_add(Weight::from_parts(0, 1739)) + // Measured: `266 + s * (32 ±0)` + // Estimated: `1751 + s * (32 ±0)` + // Minimum execution time: 5_000_000 picoseconds. + Weight::from_parts(5_772_373, 0) + .saturating_add(Weight::from_parts(0, 1751)) + // Standard Error: 22_735 + .saturating_add(Weight::from_parts(15_564, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(2)) .saturating_add(Weight::from_parts(0, 32).saturating_mul(s.into())) } - /// Storage: `StakingExtension::Signers` (r:1 w:0) + /// Storage: `StakingExtension::Signers` (r:1 w:0) /// Proof: `StakingExtension::Signers` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Storage: `Parameters::SignersInfo` (r:1 w:0) /// Proof: `Parameters::SignersInfo` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Babe::NextRandomness` (r:1 w:0) - /// Proof: `Babe::NextRandomness` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) - /// Storage: `Babe::EpochStart` (r:1 w:0) - /// Proof: `Babe::EpochStart` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) /// Storage: `StakingExtension::JumpStartProgress` (r:1 w:1) /// Proof: `StakingExtension::JumpStartProgress` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Storage: `StakingExtension::ReshareData` (r:0 w:1) /// Proof: `StakingExtension::ReshareData` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Storage: `StakingExtension::NextSigners` (r:0 w:1) /// Proof: `StakingExtension::NextSigners` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Babe::NextRandomness` (r:1 w:0) + /// Proof: `Babe::NextRandomness` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) + /// Storage: `Babe::EpochStart` (r:1 w:0) + /// Proof: `Babe::EpochStart` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) /// The range of component `c` is `[1, 14]`. /// The range of component `l` is `[0, 15]`. - fn new_session(c: u32, l: u32, ) -> Weight { + /// The range of component `v` is `[50, 100]`. + /// The range of component `r` is `[0, 15]`. + fn new_session(c: u32, _l: u32, v: u32, r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `482 + c * (32 ±0)` - // Estimated: `1966 + c * (32 ±0)` - // Minimum execution time: 13_000_000 picoseconds. - Weight::from_parts(12_791_889, 0) - .saturating_add(Weight::from_parts(0, 1966)) - // Standard Error: 22_917 - .saturating_add(Weight::from_parts(65_067, 0).saturating_mul(c.into())) - // Standard Error: 19_636 - .saturating_add(Weight::from_parts(30_071, 0).saturating_mul(l.into())) - .saturating_add(RocksDbWeight::get().reads(5)) + // Measured: `509 + c * (15 ±0)` + // Estimated: `2096 + c * (15 ±0) + r * (11364552184692736 ±340_282_366_920_938_463_463_374_607_431_768_211_455) + v * (18 ±2_466_463_158_054_763_722_435_771_498_496)` + // Minimum execution time: 10_000_000 picoseconds. + Weight::from_parts(16_699_930, 0) + .saturating_add(Weight::from_parts(0, 2096)) + // Standard Error: 2_130 + .saturating_add(Weight::from_parts(7_887, 0).saturating_mul(v.into())) + .saturating_add(RocksDbWeight::get().reads(6)) .saturating_add(RocksDbWeight::get().writes(3)) - .saturating_add(Weight::from_parts(0, 32).saturating_mul(c.into())) + .saturating_add(Weight::from_parts(0, 15).saturating_mul(c.into())) + .saturating_add(Weight::from_parts(0, 11364552184692736).saturating_mul(r.into())) + .saturating_add(Weight::from_parts(0, 18).saturating_mul(v.into())) } } diff --git a/runtime/src/weights/pallet_staking_extension.rs b/runtime/src/weights/pallet_staking_extension.rs index 2bc199b58..a6bc32bad 100644 --- a/runtime/src/weights/pallet_staking_extension.rs +++ b/runtime/src/weights/pallet_staking_extension.rs @@ -16,9 +16,9 @@ //! Autogenerated weights for `pallet_staking_extension` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 33.0.0 -//! DATE: 2024-10-03, STEPS: `25`, REPEAT: `10`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-10-17, STEPS: `5`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `ip-172-31-28-93`, CPU: `Intel(R) Xeon(R) Platinum 8375C CPU @ 2.90GHz` +//! HOSTNAME: `Jesses-MacBook-Pro.local`, CPU: `` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: 1024 // Executed Command: @@ -27,14 +27,11 @@ // pallet // --chain // dev -// --wasm-execution=compiled // --pallet=pallet_staking_extension // --extrinsic=* -// --steps=25 -// --repeat=10 +// --steps=5 +// --repeat=2 // --header=.maintain/AGPL-3.0-header.txt -// --template -// .maintain/frame-weight-template.hbs // --output=./runtime/src/weights/ #![cfg_attr(rustfmt, rustfmt_skip)] @@ -58,8 +55,8 @@ impl pallet_staking_extension::WeightInfo for WeightInf // Proof Size summary in bytes: // Measured: `1421` // Estimated: `4886` - // Minimum execution time: 37_448_000 picoseconds. - Weight::from_parts(39_440_000, 0) + // Minimum execution time: 23_000_000 picoseconds. + Weight::from_parts(25_000_000, 0) .saturating_add(Weight::from_parts(0, 4886)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) @@ -78,10 +75,12 @@ impl pallet_staking_extension::WeightInfo for WeightInf fn change_threshold_accounts(s: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `1599 + s * (32 ±0)` - // Estimated: `5063 + s * (32 ±0)` - // Minimum execution time: 45_995_000 picoseconds. - Weight::from_parts(48_726_051, 0) - .saturating_add(Weight::from_parts(0, 5063)) + // Estimated: `5062 + s * (32 ±0)` + // Minimum execution time: 29_000_000 picoseconds. + Weight::from_parts(29_411_602, 0) + .saturating_add(Weight::from_parts(0, 5062)) + // Standard Error: 26_568 + .saturating_add(Weight::from_parts(40_055, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(2)) .saturating_add(Weight::from_parts(0, 32).saturating_mul(s.into())) @@ -114,13 +113,13 @@ impl pallet_staking_extension::WeightInfo for WeightInf // Proof Size summary in bytes: // Measured: `2140 + n * (32 ±0) + s * (64 ±0)` // Estimated: `4764 + n * (32 ±0) + s * (64 ±0)` - // Minimum execution time: 115_452_000 picoseconds. - Weight::from_parts(116_623_730, 0) + // Minimum execution time: 75_000_000 picoseconds. + Weight::from_parts(75_636_482, 0) .saturating_add(Weight::from_parts(0, 4764)) - // Standard Error: 33_652 - .saturating_add(Weight::from_parts(194_540, 0).saturating_mul(s.into())) - // Standard Error: 31_703 - .saturating_add(Weight::from_parts(188_097, 0).saturating_mul(n.into())) + // Standard Error: 179_756 + .saturating_add(Weight::from_parts(66_938, 0).saturating_mul(s.into())) + // Standard Error: 173_022 + .saturating_add(Weight::from_parts(89_861, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(11)) .saturating_add(T::DbWeight::get().writes(4)) .saturating_add(Weight::from_parts(0, 32).saturating_mul(n.into())) @@ -152,13 +151,13 @@ impl pallet_staking_extension::WeightInfo for WeightInf // Proof Size summary in bytes: // Measured: `1985 + c * (64 ±0) + n * (32 ±0)` // Estimated: `6248 + c * (64 ±0) + n * (32 ±0)` - // Minimum execution time: 95_779_000 picoseconds. - Weight::from_parts(96_617_815, 0) + // Minimum execution time: 59_000_000 picoseconds. + Weight::from_parts(55_944_951, 0) .saturating_add(Weight::from_parts(0, 6248)) - // Standard Error: 23_179 - .saturating_add(Weight::from_parts(168_714, 0).saturating_mul(c.into())) - // Standard Error: 21_837 - .saturating_add(Weight::from_parts(185_817, 0).saturating_mul(n.into())) + // Standard Error: 204_369 + .saturating_add(Weight::from_parts(228_013, 0).saturating_mul(c.into())) + // Standard Error: 196_712 + .saturating_add(Weight::from_parts(371_213, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(11)) .saturating_add(T::DbWeight::get().writes(6)) .saturating_add(Weight::from_parts(0, 64).saturating_mul(c.into())) @@ -188,13 +187,13 @@ impl pallet_staking_extension::WeightInfo for WeightInf // Proof Size summary in bytes: // Measured: `1655 + c * (64 ±0) + n * (32 ±0)` // Estimated: `4764 + c * (64 ±0) + n * (32 ±0)` - // Minimum execution time: 77_414_000 picoseconds. - Weight::from_parts(77_758_089, 0) + // Minimum execution time: 50_000_000 picoseconds. + Weight::from_parts(49_699_348, 0) .saturating_add(Weight::from_parts(0, 4764)) - // Standard Error: 24_246 - .saturating_add(Weight::from_parts(184_017, 0).saturating_mul(c.into())) - // Standard Error: 22_842 - .saturating_add(Weight::from_parts(181_804, 0).saturating_mul(n.into())) + // Standard Error: 98_741 + .saturating_add(Weight::from_parts(156_840, 0).saturating_mul(c.into())) + // Standard Error: 95_041 + .saturating_add(Weight::from_parts(112_011, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(9)) .saturating_add(T::DbWeight::get().writes(3)) .saturating_add(Weight::from_parts(0, 64).saturating_mul(c.into())) @@ -232,8 +231,8 @@ impl pallet_staking_extension::WeightInfo for WeightInf // Proof Size summary in bytes: // Measured: `2141` // Estimated: `6248` - // Minimum execution time: 112_405_000 picoseconds. - Weight::from_parts(116_028_000, 0) + // Minimum execution time: 71_000_000 picoseconds. + Weight::from_parts(71_000_000, 0) .saturating_add(Weight::from_parts(0, 6248)) .saturating_add(T::DbWeight::get().reads(15)) .saturating_add(T::DbWeight::get().writes(8)) @@ -246,15 +245,13 @@ impl pallet_staking_extension::WeightInfo for WeightInf fn confirm_key_reshare_confirmed(c: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `830 + c * (32 ±0)` - // Estimated: `4320 + c * (30 ±0)` - // Minimum execution time: 18_737_000 picoseconds. - Weight::from_parts(20_163_892, 0) - .saturating_add(Weight::from_parts(0, 4320)) - // Standard Error: 7_914 - .saturating_add(Weight::from_parts(37_314, 0).saturating_mul(c.into())) + // Estimated: `4331 + c * (29 ±1)` + // Minimum execution time: 11_000_000 picoseconds. + Weight::from_parts(12_414_364, 0) + .saturating_add(Weight::from_parts(0, 4331)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) - .saturating_add(Weight::from_parts(0, 30).saturating_mul(c.into())) + .saturating_add(Weight::from_parts(0, 29).saturating_mul(c.into())) } /// Storage: `StakingExtension::ThresholdToStash` (r:1 w:0) /// Proof: `StakingExtension::ThresholdToStash` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -268,8 +265,8 @@ impl pallet_staking_extension::WeightInfo for WeightInf // Proof Size summary in bytes: // Measured: `1342` // Estimated: `4807` - // Minimum execution time: 21_013_000 picoseconds. - Weight::from_parts(21_965_000, 0) + // Minimum execution time: 12_000_000 picoseconds. + Weight::from_parts(13_000_000, 0) .saturating_add(Weight::from_parts(0, 4807)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(3)) @@ -283,41 +280,45 @@ impl pallet_staking_extension::WeightInfo for WeightInf // Proof Size summary in bytes: // Measured: `266 + s * (32 ±0)` // Estimated: `1751 + s * (32 ±0)` - // Minimum execution time: 7_529_000 picoseconds. - Weight::from_parts(7_865_217, 0) + // Minimum execution time: 5_000_000 picoseconds. + Weight::from_parts(5_772_373, 0) .saturating_add(Weight::from_parts(0, 1751)) - // Standard Error: 2_909 - .saturating_add(Weight::from_parts(15_094, 0).saturating_mul(s.into())) + // Standard Error: 22_735 + .saturating_add(Weight::from_parts(15_564, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(Weight::from_parts(0, 32).saturating_mul(s.into())) } - /// Storage: `StakingExtension::Signers` (r:1 w:0) + /// Storage: `StakingExtension::Signers` (r:1 w:0) /// Proof: `StakingExtension::Signers` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Storage: `Parameters::SignersInfo` (r:1 w:0) /// Proof: `Parameters::SignersInfo` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Babe::NextRandomness` (r:1 w:0) - /// Proof: `Babe::NextRandomness` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) - /// Storage: `Babe::EpochStart` (r:1 w:0) - /// Proof: `Babe::EpochStart` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) /// Storage: `StakingExtension::JumpStartProgress` (r:1 w:1) /// Proof: `StakingExtension::JumpStartProgress` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Storage: `StakingExtension::ReshareData` (r:0 w:1) /// Proof: `StakingExtension::ReshareData` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Storage: `StakingExtension::NextSigners` (r:0 w:1) /// Proof: `StakingExtension::NextSigners` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Babe::NextRandomness` (r:1 w:0) + /// Proof: `Babe::NextRandomness` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) + /// Storage: `Babe::EpochStart` (r:1 w:0) + /// Proof: `Babe::EpochStart` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) /// The range of component `c` is `[1, 14]`. /// The range of component `l` is `[0, 15]`. - fn new_session(c: u32, _l: u32, ) -> Weight { + /// The range of component `v` is `[50, 100]`. + /// The range of component `r` is `[0, 15]`. + fn new_session(c: u32, _l: u32, v: u32, r: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `494 + c * (32 ±0)` - // Estimated: `1979 + c * (32 ±0)` - // Minimum execution time: 19_313_000 picoseconds. - Weight::from_parts(20_259_262, 0) - .saturating_add(Weight::from_parts(0, 1979)) - // Standard Error: 7_972 - .saturating_add(Weight::from_parts(49_077, 0).saturating_mul(c.into())) - .saturating_add(T::DbWeight::get().reads(5)) + // Measured: `509 + c * (15 ±0)` + // Estimated: `2096 + c * (15 ±0) + r * (11364552184692736 ±340_282_366_920_938_463_463_374_607_431_768_211_455) + v * (18 ±2_466_463_158_054_763_722_435_771_498_496)` + // Minimum execution time: 10_000_000 picoseconds. + Weight::from_parts(16_699_930, 0) + .saturating_add(Weight::from_parts(0, 2096)) + // Standard Error: 2_130 + .saturating_add(Weight::from_parts(7_887, 0).saturating_mul(v.into())) + .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(3)) - .saturating_add(Weight::from_parts(0, 32).saturating_mul(c.into())) + .saturating_add(Weight::from_parts(0, 15).saturating_mul(c.into())) + .saturating_add(Weight::from_parts(0, 11364552184692736).saturating_mul(r.into())) + .saturating_add(Weight::from_parts(0, 18).saturating_mul(v.into())) } }