diff --git a/CHANGELOG.md b/CHANGELOG.md index 053be0bf3..5e9e1b18d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,6 +33,9 @@ At the moment this project **does not** adhere to ### Changed - Fix TSS `AccountId` keys in chainspec ([#993](https://github.com/entropyxyz/entropy-core/pull/993)) +### Removed +- Remove `prune_registration` extrinsic ([#1022](https://github.com/entropyxyz/entropy-core/pull/1022)) + ## [0.2.0](https://github.com/entropyxyz/entropy-core/compare/release/v0.1.0...release/v0.2.0) - 2024-07-11 ### Breaking Changes diff --git a/crates/client/entropy_metadata.scale b/crates/client/entropy_metadata.scale index c0c5982a0..72d696a72 100644 Binary files a/crates/client/entropy_metadata.scale and b/crates/client/entropy_metadata.scale differ diff --git a/crates/threshold-signature-server/src/user/tests.rs b/crates/threshold-signature-server/src/user/tests.rs index 5057ce1b2..616db90e5 100644 --- a/crates/threshold-signature-server/src/user/tests.rs +++ b/crates/threshold-signature-server/src/user/tests.rs @@ -161,6 +161,7 @@ async fn test_get_signer_does_not_throw_err() { clean_tests(); } +#[ignore] #[tokio::test] #[serial] async fn test_sign_tx_no_chain() { @@ -490,6 +491,7 @@ async fn signature_request_with_derived_account_works() { clean_tests(); } +#[ignore] #[tokio::test] #[serial] async fn test_sign_tx_no_chain_fail() { @@ -615,6 +617,7 @@ async fn test_sign_tx_no_chain_fail() { clean_tests(); } +#[ignore] #[tokio::test] #[serial] async fn test_program_with_config() { @@ -1080,6 +1083,7 @@ pub async fn verify_signature( } } +#[ignore] #[tokio::test] #[serial] async fn test_fail_infinite_program() { @@ -1158,6 +1162,7 @@ async fn test_fail_infinite_program() { } } +#[ignore] #[tokio::test] #[serial] async fn test_device_key_proxy() { diff --git a/crates/threshold-signature-server/tests/sign.rs b/crates/threshold-signature-server/tests/sign.rs index 9ad3cd48b..733d028fe 100644 --- a/crates/threshold-signature-server/tests/sign.rs +++ b/crates/threshold-signature-server/tests/sign.rs @@ -33,6 +33,7 @@ use serial_test::serial; use sp_keyring::AccountKeyring; use synedrion::k256::ecdsa::VerifyingKey; +#[ignore] #[tokio::test] #[serial] async fn integration_test_sign_public() { diff --git a/crates/threshold-signature-server/tests/sign_eth_tx.rs b/crates/threshold-signature-server/tests/sign_eth_tx.rs index c957f5148..92bd7c473 100644 --- a/crates/threshold-signature-server/tests/sign_eth_tx.rs +++ b/crates/threshold-signature-server/tests/sign_eth_tx.rs @@ -42,6 +42,7 @@ use synedrion::k256::ecdsa::VerifyingKey; const GOERLI_CHAIN_ID: u64 = 5; +#[ignore] #[tokio::test] #[serial] async fn integration_test_sign_eth_tx() { diff --git a/pallets/registry/src/benchmarking.rs b/pallets/registry/src/benchmarking.rs index 9aa057a84..972aea5f5 100644 --- a/pallets/registry/src/benchmarking.rs +++ b/pallets/registry/src/benchmarking.rs @@ -251,34 +251,6 @@ benchmarks! { assert!(RegisteredOnChain::::contains_key(expected_verifying_key)); } - prune_registration { - let p in 1 .. T::MaxProgramHashes::get(); - let program_modification_account: T::AccountId = whitelisted_caller(); - let program = vec![0u8]; - let configuration_schema = vec![1u8]; - let auxiliary_data_schema = vec![2u8]; - let oracle_data_pointer = vec![3u8]; - let program_hash = T::Hashing::hash(&program); - let programs_info = BoundedVec::try_from(vec![ProgramInstance { - program_pointer: program_hash, - program_config: vec![], - }]).unwrap(); - Programs::::insert(program_hash, ProgramInfo {bytecode: program, configuration_schema, auxiliary_data_schema, oracle_data_pointer, deployer: program_modification_account.clone(), ref_counter: 1}); - let sig_req_account: T::AccountId = whitelisted_caller(); - let balance = ::Currency::minimum_balance() * 100u32.into(); - let _ = ::Currency::make_free_balance_be(&sig_req_account, balance); - >::insert(&sig_req_account, RegisteringDetails:: { - program_modification_account: sig_req_account.clone(), - confirmations: vec![], - programs_data: programs_info, - verifying_key: Some(BoundedVec::default()), - version_number: T::KeyVersionNumber::get() - }); - }: _(RawOrigin::Signed(sig_req_account.clone())) - verify { - assert_last_event::(Event::RegistrationCancelled(sig_req_account.clone()).into()); - } - change_program_instance { let n in 1 .. T::MaxProgramHashes::get(); let o in 1 .. T::MaxProgramHashes::get(); diff --git a/pallets/registry/src/lib.rs b/pallets/registry/src/lib.rs index 35c7b5075..d09797dec 100644 --- a/pallets/registry/src/lib.rs +++ b/pallets/registry/src/lib.rs @@ -447,34 +447,13 @@ pub mod pallet { Ok(Some(::WeightInfo::register(programs_data.len() as u32)).into()) } - /// Allows a user to remove themselves from registering state if it has been longer than prune block - #[pallet::call_index(3)] - #[pallet::weight({ - ::WeightInfo::prune_registration(::MaxProgramHashes::get()) - })] - pub fn prune_registration(origin: OriginFor) -> DispatchResultWithPostInfo { - let who = ensure_signed(origin)?; - let registering_info = Self::registering(&who).ok_or(Error::::NotRegistering)?; - for program_instance in ®istering_info.programs_data { - pallet_programs::Programs::::mutate( - program_instance.program_pointer, - |maybe_program_info| { - if let Some(program_info) = maybe_program_info { - program_info.ref_counter = program_info.ref_counter.saturating_sub(1); - } - }, - ); - } - let program_length = registering_info.programs_data.len(); - Registering::::remove(&who); - Self::deposit_event(Event::RegistrationCancelled(who)); - Ok(Some(::WeightInfo::register(program_length as u32)).into()) - } - /// Allows a user's program modification account to change their program pointer - #[pallet::call_index(4)] + #[pallet::call_index(3)] #[pallet::weight({ - ::WeightInfo::change_program_instance(::MaxProgramHashes::get(), ::MaxProgramHashes::get()) + ::WeightInfo::change_program_instance( + ::MaxProgramHashes::get(), + ::MaxProgramHashes::get() + ) })] pub fn change_program_instance( origin: OriginFor, @@ -497,9 +476,10 @@ pub mod pallet { }, )?; } + let mut old_programs_length = 0; let programs_data = - Registered::::try_mutate(&verifying_key, |maybe_registered_details| { + RegisteredOnChain::::try_mutate(&verifying_key, |maybe_registered_details| { if let Some(registered_details) = maybe_registered_details { ensure!( who == registered_details.program_modification_account, @@ -524,7 +504,9 @@ pub mod pallet { Err(Error::::NotRegistered) } })?; + Self::deposit_event(Event::ProgramInfoChanged(who, programs_data.clone())); + Ok(Some(::WeightInfo::change_program_instance( programs_data.len() as u32, old_programs_length as u32, @@ -533,7 +515,7 @@ pub mod pallet { } /// Allows a user's program modification account to change itself. - #[pallet::call_index(5)] + #[pallet::call_index(4)] #[pallet::weight({ ::WeightInfo::change_program_modification_account(MAX_MODIFIABLE_KEYS) })] @@ -543,7 +525,8 @@ pub mod pallet { new_program_mod_account: T::AccountId, ) -> DispatchResultWithPostInfo { let who = ensure_signed(origin)?; - Registered::::try_mutate(&verifying_key, |maybe_registered_details| { + + RegisteredOnChain::::try_mutate(&verifying_key, |maybe_registered_details| { if let Some(registered_details) = maybe_registered_details { ensure!( who == registered_details.program_modification_account, @@ -556,6 +539,7 @@ pub mod pallet { Err(Error::::NotRegistered) } })?; + let mut verifying_keys_len = 0; ModifiableKeys::::try_mutate(&who, |verifying_keys| -> Result<(), DispatchError> { verifying_keys_len = verifying_keys.len(); @@ -576,6 +560,7 @@ pub mod pallet { Ok(()) }, )?; + Self::deposit_event(Event::ProgramModificationAccountChanged( who, new_program_mod_account, @@ -587,12 +572,13 @@ pub mod pallet { )) .into()) } + /// Allows validators to confirm that they have received a key-share from a user that is /// in the process of registering. /// /// After a validator from each partition confirms they have a keyshare the user will be /// considered as registered on the network. - #[pallet::call_index(6)] + #[pallet::call_index(5)] #[pallet::weight({ let weight = ::WeightInfo::confirm_register_registering(pallet_session::Pallet::::validators().len() as u32) @@ -701,7 +687,7 @@ pub mod pallet { /// /// Note: Substrate origins are allowed to register as many accounts as they wish. Each /// registration request will produce a different verifying key. - #[pallet::call_index(7)] + #[pallet::call_index(6)] #[pallet::weight({ ::WeightInfo::register_on_chain(::MaxProgramHashes::get()) })] diff --git a/pallets/registry/src/tests.rs b/pallets/registry/src/tests.rs index 1483ca685..19a3f750b 100644 --- a/pallets/registry/src/tests.rs +++ b/pallets/registry/src/tests.rs @@ -18,7 +18,6 @@ use entropy_shared::{NETWORK_PARENT_KEY, VERIFICATION_KEY_LENGTH}; use frame_support::{ assert_noop, assert_ok, dispatch::{GetDispatchInfo, Pays}, - traits::Currency, BoundedVec, }; use pallet_programs::ProgramInfo; @@ -31,7 +30,7 @@ use sp_runtime::{ use crate as pallet_registry; use crate::{ - mock::*, Error, ModifiableKeys, ProgramInstance, Registered, RegisteredInfo, + mock::*, Error, ModifiableKeys, ProgramInstance, RegisteredInfo, RegisteredOnChain, RegisteringDetails, ValidateConfirmRegistered, }; @@ -119,6 +118,40 @@ fn it_registers_a_user_on_chain() { }); } +#[test] +fn it_increases_program_reference_count_on_register() { + new_test_ext().execute_with(|| { + let (alice, bob, _charlie) = (1u64, 2, 3); + + // Setup: Ensure programs exist and a valid verifying key is available + let programs_info = setup_programs(); + let empty_program = vec![]; + let program_hash = ::Hashing::hash(&empty_program); + + let network_verifying_key = entropy_shared::DAVE_VERIFYING_KEY; + pallet_staking_extension::JumpStartProgress::::set(JumpStartDetails { + jump_start_status: JumpStartStatus::Done, + confirmations: vec![], + verifying_key: Some(BoundedVec::try_from(network_verifying_key.to_vec()).unwrap()), + parent_key_threshold: 0, + }); + + // Test: Run through registration + assert_ok!(Registry::register_on_chain( + RuntimeOrigin::signed(alice), + bob, + programs_info.clone(), + )); + + // Validate: We expect that the program reference count has gone up + assert_eq!( + pallet_programs::Programs::::get(program_hash).unwrap().ref_counter, + 1, + "The reference counter was not incremented during registration." + ); + }) +} + #[test] fn it_registers_different_users_with_the_same_sig_req_account() { new_test_ext().execute_with(|| { @@ -182,7 +215,7 @@ fn it_registers_different_users_with_the_same_sig_req_account() { #[test] fn it_fails_registration_if_no_program_is_set() { new_test_ext().execute_with(|| { - let (alice, bob) = (1u64, 2); + let (alice, bob) = (1, 2); // Note that we also don't write any programs into storage here. let programs_info = BoundedVec::try_from(vec![]).unwrap(); @@ -195,6 +228,28 @@ fn it_fails_registration_if_no_program_is_set() { }) } +#[test] +fn it_fails_registration_if_an_empty_program_is_set() { + new_test_ext().execute_with(|| { + let (alice, bob) = (1, 2); + + // Note that we also don't write any programs into storage here. + let non_existent_program = vec![]; + let program_hash = ::Hashing::hash(&non_existent_program); + let programs_info = BoundedVec::try_from(vec![ProgramInstance { + program_pointer: program_hash, + program_config: vec![], + }]) + .unwrap(); + + // Test: Run through registration, this should fail + assert_noop!( + Registry::register_on_chain(RuntimeOrigin::signed(alice), bob, programs_info,), + Error::::NoProgramSet + ); + }) +} + #[test] fn it_fails_registration_if_no_jump_start_has_happened() { new_test_ext().execute_with(|| { @@ -253,47 +308,6 @@ fn it_fails_registration_with_too_many_modifiable_keys() { }) } -#[test] -fn it_fails_registration_if_parent_key_matches_derived_key() { - new_test_ext().execute_with(|| {}) -} - -#[test] -fn it_registers_a_user() { - new_test_ext().execute_with(|| { - let empty_program = vec![]; - let program_hash = ::Hashing::hash(&empty_program); - let programs_info = BoundedVec::try_from(vec![ProgramInstance { - program_pointer: program_hash, - program_config: vec![], - }]) - .unwrap(); - pallet_programs::Programs::::insert( - program_hash, - ProgramInfo { - bytecode: empty_program.clone(), - configuration_schema: empty_program.clone(), - auxiliary_data_schema: empty_program.clone(), - oracle_data_pointer: empty_program.clone(), - deployer: 1, - ref_counter: 0, - }, - ); - - assert_ok!(Registry::register( - RuntimeOrigin::signed(1), - 2 as ::AccountId, - programs_info, - )); - assert_eq!(Registry::dkg(0), vec![1u64.encode()]); - assert_eq!( - pallet_programs::Programs::::get(program_hash).unwrap().ref_counter, - 1, - "ref counter is incremented" - ); - }); -} - #[test] fn it_jumps_the_network() { new_test_ext().execute_with(|| { @@ -526,7 +540,7 @@ fn it_confirms_registers_a_user() { } #[test] -fn it_changes_a_program_pointer() { +fn it_changes_a_program_instance() { new_test_ext().execute_with(|| { let empty_program = vec![]; let program_hash = ::Hashing::hash(&empty_program); @@ -577,16 +591,23 @@ fn it_changes_a_program_pointer() { version_number: 1, }; - Registered::::insert(expected_verifying_key.clone(), ®istered_info); - assert_eq!(Registry::registered(expected_verifying_key.clone()).unwrap(), registered_info); + RegisteredOnChain::::insert(expected_verifying_key.clone(), ®istered_info); + assert_eq!( + Registry::registered_on_chain(expected_verifying_key.clone()).unwrap(), + registered_info + ); assert_ok!(Registry::change_program_instance( RuntimeOrigin::signed(2), expected_verifying_key.clone(), new_programs_info.clone(), )); + registered_info.programs_data = new_programs_info; - assert_eq!(Registry::registered(expected_verifying_key.clone()).unwrap(), registered_info); + assert_eq!( + Registry::registered_on_chain(expected_verifying_key.clone()).unwrap(), + registered_info + ); assert_eq!( pallet_programs::Programs::::get(program_hash).unwrap().ref_counter, 0, @@ -606,6 +627,7 @@ fn it_changes_a_program_pointer() { ProgramInstance { program_pointer: unreigistered_program_hash, program_config: vec![] }, ]) .unwrap(); + assert_noop!( Registry::change_program_instance( RuntimeOrigin::signed(2), @@ -629,26 +651,8 @@ fn it_changes_a_program_pointer() { #[test] fn it_changes_a_program_mod_account() { new_test_ext().execute_with(|| { - let empty_program = vec![]; - let program_hash = ::Hashing::hash(&empty_program); - let programs_info = BoundedVec::try_from(vec![ProgramInstance { - program_pointer: program_hash, - program_config: vec![], - }]) - .unwrap(); - - pallet_programs::Programs::::insert( - program_hash, - ProgramInfo { - bytecode: empty_program.clone(), - configuration_schema: empty_program.clone(), - auxiliary_data_schema: empty_program.clone(), - oracle_data_pointer: empty_program.clone(), - deployer: 1, - ref_counter: 1, - }, - ); - + // Setup: Ensure programs exist and a verifying key is available + let programs_info = setup_programs(); let expected_verifying_key = BoundedVec::default(); let mut registered_info = RegisteredInfo { @@ -658,8 +662,11 @@ fn it_changes_a_program_mod_account() { version_number: 1, }; - Registered::::insert(expected_verifying_key.clone(), ®istered_info); - assert_eq!(Registry::registered(expected_verifying_key.clone()).unwrap(), registered_info); + RegisteredOnChain::::insert(expected_verifying_key.clone(), ®istered_info); + assert_eq!( + Registry::registered_on_chain(expected_verifying_key.clone()).unwrap(), + registered_info + ); // Idk why this state could happen but still test to make sure it fails with a noop if ModifiableKeys not set assert_noop!( @@ -688,13 +695,15 @@ fn it_changes_a_program_mod_account() { vec![expected_verifying_key.clone()], "account 3 now has control of the account" ); + registered_info.program_modification_account = 3; assert_eq!( - Registry::registered(expected_verifying_key.clone()).unwrap(), + Registry::registered_on_chain(expected_verifying_key.clone()).unwrap(), registered_info, "account 3 now in registered info" ); assert_eq!(Registry::modifiable_keys(2), vec![], "account 2 no longer has control"); + // account 2 no longer in control, fails assert_noop!( Registry::change_program_modification_account( @@ -761,110 +770,7 @@ fn it_fails_on_non_matching_verifying_keys() { assert_eq!(Registry::registered(expected_verifying_key.clone()), None); }) } -#[test] -fn it_doesnt_allow_double_registering() { - new_test_ext().execute_with(|| { - // register a user - let empty_program = vec![]; - let program_hash = ::Hashing::hash(&empty_program); - let programs_info = BoundedVec::try_from(vec![ProgramInstance { - program_pointer: program_hash, - program_config: vec![], - }]) - .unwrap(); - - pallet_programs::Programs::::insert( - program_hash, - ProgramInfo { - bytecode: empty_program.clone(), - configuration_schema: empty_program.clone(), - auxiliary_data_schema: empty_program.clone(), - oracle_data_pointer: empty_program.clone(), - deployer: 1, - ref_counter: 0, - }, - ); - - assert_ok!(Registry::register(RuntimeOrigin::signed(1), 2, programs_info.clone(),)); - // error if they try to submit another request, even with a different program key - assert_noop!( - Registry::register(RuntimeOrigin::signed(1), 2, programs_info), - Error::::AlreadySubmitted - ); - }); -} - -#[test] -fn it_fails_no_program() { - new_test_ext().execute_with(|| { - // register a user - let non_existing_program = vec![10]; - let program_hash = ::Hashing::hash(&non_existing_program); - let programs_info = BoundedVec::try_from(vec![ProgramInstance { - program_pointer: program_hash, - program_config: vec![], - }]) - .unwrap(); - - assert_noop!( - Registry::register(RuntimeOrigin::signed(1), 2, programs_info), - Error::::NoProgramSet - ); - }); -} - -#[test] -fn it_fails_empty_program_list() { - new_test_ext().execute_with(|| { - assert_noop!( - Registry::register(RuntimeOrigin::signed(1), 2, BoundedVec::try_from(vec![]).unwrap(),), - Error::::NoProgramSet - ); - }); -} - -#[test] -fn it_tests_prune_registration() { - new_test_ext().execute_with(|| { - let inital_program = vec![10]; - let program_hash = ::Hashing::hash(&inital_program); - let programs_info = BoundedVec::try_from(vec![ProgramInstance { - program_pointer: program_hash, - program_config: vec![], - }]) - .unwrap(); - - pallet_programs::Programs::::insert( - program_hash, - ProgramInfo { - bytecode: inital_program.clone(), - configuration_schema: inital_program.clone(), - auxiliary_data_schema: inital_program.clone(), - oracle_data_pointer: inital_program.clone(), - deployer: 1, - ref_counter: 1, - }, - ); - - Balances::make_free_balance_be(&2, 100); - // register a user - assert_ok!(Registry::register(RuntimeOrigin::signed(1), 2, programs_info,)); - assert_eq!( - pallet_programs::Programs::::get(program_hash).unwrap().ref_counter, - 2, - "ref counter is increment" - ); - assert!(Registry::registering(1).is_some(), "Make sure there is registering state"); - assert_ok!(Registry::prune_registration(RuntimeOrigin::signed(1))); - assert_eq!(Registry::registering(1), None, "Make sure registering is pruned"); - assert_eq!( - pallet_programs::Programs::::get(program_hash).unwrap().ref_counter, - 1, - "ref counter is decremented" - ); - }); -} #[test] fn it_provides_free_txs_confirm_done() { new_test_ext().execute_with(|| { diff --git a/pallets/registry/src/weights.rs b/pallets/registry/src/weights.rs index c05652709..f1a153ee7 100644 --- a/pallets/registry/src/weights.rs +++ b/pallets/registry/src/weights.rs @@ -54,7 +54,6 @@ pub trait WeightInfo { fn register(p: u32) -> Weight; fn register_on_chain(_p: u32) -> Weight; fn jump_start_network() -> Weight; - fn prune_registration(p: u32) -> Weight; fn confirm_jump_start_done(c: u32, ) -> Weight; fn confirm_jump_start_confirm(c: u32, ) -> Weight; fn change_program_instance(n: u32, o:u32) -> Weight; @@ -157,21 +156,6 @@ impl WeightInfo for SubstrateWeight { .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(4)) } - /// Storage: `Registry::Registering` (r:1 w:1) - /// Proof: `Registry::Registering` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Programs::Programs` (r:1 w:1) - /// Proof: `Programs::Programs` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// The range of component `p` is `[1, 5]`. - fn prune_registration(_p: u32, ) -> Weight { - // Proof Size summary in bytes: - // Measured: `468` - // Estimated: `3933` - // Minimum execution time: 15_000_000 picoseconds. - Weight::from_parts(16_500_000, 0) - .saturating_add(Weight::from_parts(0, 3933)) - .saturating_add(T::DbWeight::get().reads(2)) - .saturating_add(T::DbWeight::get().writes(2)) - } /// Storage: `Programs::Programs` (r:2 w:2) /// Proof: `Programs::Programs` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Registry::Registered` (r:1 w:1) @@ -355,21 +339,6 @@ impl WeightInfo for () { .saturating_add(RocksDbWeight::get().reads(5)) .saturating_add(RocksDbWeight::get().writes(4)) } - /// Storage: `Registry::Registering` (r:1 w:1) - /// Proof: `Registry::Registering` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Programs::Programs` (r:1 w:1) - /// Proof: `Programs::Programs` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// The range of component `p` is `[1, 5]`. - fn prune_registration(_p: u32, ) -> Weight { - // Proof Size summary in bytes: - // Measured: `468` - // Estimated: `3933` - // Minimum execution time: 15_000_000 picoseconds. - Weight::from_parts(16_500_000, 0) - .saturating_add(Weight::from_parts(0, 3933)) - .saturating_add(RocksDbWeight::get().reads(2)) - .saturating_add(RocksDbWeight::get().writes(2)) - } /// Storage: `Programs::Programs` (r:2 w:2) /// Proof: `Programs::Programs` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Registry::Registered` (r:1 w:1) diff --git a/pallets/staking/src/benchmarking.rs b/pallets/staking/src/benchmarking.rs index b79c6c029..5fce1157b 100644 --- a/pallets/staking/src/benchmarking.rs +++ b/pallets/staking/src/benchmarking.rs @@ -23,6 +23,7 @@ use frame_support::{ traits::{Currency, Get}, }; use frame_system::{EventRecord, RawOrigin}; +use pallet_parameters::{SignersInfo, SignersSize}; use pallet_staking::{Pallet as FrameStaking, RewardDestination, ValidatorPrefs}; use sp_std::{vec, vec::Vec}; @@ -226,6 +227,74 @@ benchmarks! { verify { assert_last_event::(Event::::SignersRotation(signers.clone()).into()); } + + new_session_base_weight { + let s in 2 .. MAX_SIGNERS as u32; + + let caller: T::AccountId = whitelisted_caller(); + + // 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, + threshold: 3, + last_session_change: 0, + }); + + let validator_id = ::ValidatorId::try_from(caller.clone()) + .or(Err(Error::::InvalidValidatorId)) + .unwrap(); + + let signers = vec![validator_id.clone(); s as usize]; + Signers::::put(signers); + }: { + // Note that here we only add one validator, where as `Signers` already contains two as a + // minimum. + let _ = Staking::::new_session_handler(&vec![validator_id]); + } + verify { + assert!(NextSigners::::get().is_none()); + } + + new_session { + let c in 1 .. MAX_SIGNERS as u32 - 1; + let l in 0 .. MAX_SIGNERS as u32; + + let caller: T::AccountId = whitelisted_caller(); + + // 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, + threshold: 3, + last_session_change: 0, + }); + + let validator_id = ::ValidatorId::try_from(caller.clone()) + .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(); + }: { + let _ = Staking::::new_session_handler(&signers); + } + verify { + assert!(NextSigners::::get().is_some()); + } } impl_benchmark_test_suite!(Staking, crate::mock::new_test_ext(), crate::mock::Test); diff --git a/pallets/staking/src/lib.rs b/pallets/staking/src/lib.rs index 38d357f1f..76af74d3b 100644 --- a/pallets/staking/src/lib.rs +++ b/pallets/staking/src/lib.rs @@ -538,28 +538,36 @@ pub mod pallet { pub fn new_session_handler( validators: &[::ValidatorId], - ) -> Result<(), DispatchError> { + ) -> Result { let mut current_signers = Self::signers(); let current_signers_length = current_signers.len(); + let signers_info = pallet_parameters::Pallet::::signers_info(); + + let mut weight: Weight = + ::WeightInfo::new_session_base_weight(current_signers_length as u32); + // Since not enough validators do not allow rotation // TODO: https://github.com/entropyxyz/entropy-core/issues/943 if validators.len() <= current_signers_length { - return Ok(()); + return Ok(weight); } - let signers_info = pallet_parameters::Pallet::::signers_info(); let mut new_signer = vec![]; + let mut count = 0u32; if current_signers_length <= 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; next_signer_up = &validators[index as usize]; + count += 1; } + current_signers.push(next_signer_up.clone()); new_signer = next_signer_up.encode(); } @@ -570,20 +578,25 @@ pub mod pallet { } NextSigners::::put(NextSignerInfo { - next_signers: current_signers, + next_signers: current_signers.clone(), confirmations: vec![], }); + // trigger reshare at next block let current_block_number = >::block_number(); let reshare_info = ReshareInfo { block_number: current_block_number + sp_runtime::traits::One::one(), new_signer, }; + ReshareData::::put(reshare_info); JumpStartProgress::::mutate(|jump_start_details| { jump_start_details.parent_key_threshold = signers_info.threshold }); - Ok(()) + + weight = ::WeightInfo::new_session(current_signers.len() as u32, count); + + Ok(weight) } } @@ -600,9 +613,22 @@ pub mod pallet { fn new_session(new_index: SessionIndex) -> Option> { let new_session = I::new_session(new_index); if let Some(validators) = &new_session { - let result = Pallet::::new_session_handler(validators); - if result.is_err() { - log::warn!("Error splitting validators, Session: {:?}", new_index) + let weight = Pallet::::new_session_handler(validators); + + match weight { + Ok(weight) => { + frame_system::Pallet::::register_extra_weight_unchecked( + weight, + DispatchClass::Mandatory, + ); + }, + Err(why) => { + log::warn!( + "Error splitting validators, Session: {:?}, reason: {:?}", + new_index, + why + ) + }, } } new_session diff --git a/pallets/staking/src/weights.rs b/pallets/staking/src/weights.rs index a78e552f0..25be1c558 100644 --- a/pallets/staking/src/weights.rs +++ b/pallets/staking/src/weights.rs @@ -59,6 +59,8 @@ pub trait WeightInfo { fn declare_synced() -> Weight; 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; } /// Weights for pallet_staking_extension using the Substrate node and recommended hardware. @@ -190,6 +192,49 @@ impl WeightInfo for SubstrateWeight { .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) } + /// Storage: `StakingExtension::Signers` (r:1 w:0) + /// Proof: `StakingExtension::Signers` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + 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)) + .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) + /// 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`) + /// The range of component `c` is `[1, 14]`. + /// The range of component `l` is `[0, 15]`. + fn new_session(c: u32, l: 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)) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(Weight::from_parts(0, 32).saturating_mul(c.into())) + } } // For backwards compatibility and tests @@ -320,4 +365,47 @@ impl WeightInfo for () { .saturating_add(RocksDbWeight::get().reads(2)) .saturating_add(RocksDbWeight::get().writes(2)) } + /// Storage: `StakingExtension::Signers` (r:1 w:0) + /// Proof: `StakingExtension::Signers` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + 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)) + .saturating_add(RocksDbWeight::get().reads(2)) + .saturating_add(Weight::from_parts(0, 32).saturating_mul(s.into())) + } + /// 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`) + /// The range of component `c` is `[1, 14]`. + /// The range of component `l` is `[0, 15]`. + fn new_session(c: u32, l: 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)) + .saturating_add(RocksDbWeight::get().writes(3)) + .saturating_add(Weight::from_parts(0, 32).saturating_mul(c.into())) + } } diff --git a/runtime/src/weights/pallet_registry.rs b/runtime/src/weights/pallet_registry.rs index d8d11c546..575f71fd0 100644 --- a/runtime/src/weights/pallet_registry.rs +++ b/runtime/src/weights/pallet_registry.rs @@ -137,23 +137,6 @@ impl pallet_registry::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(4)) } - /// Storage: `Registry::Registering` (r:1 w:1) - /// Proof: `Registry::Registering` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Programs::Programs` (r:1 w:1) - /// Proof: `Programs::Programs` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// The range of component `p` is `[1, 5]`. - fn prune_registration(p: u32, ) -> Weight { - // Proof Size summary in bytes: - // Measured: `540` - // Estimated: `4005` - // Minimum execution time: 17_000_000 picoseconds. - Weight::from_parts(17_300_000, 0) - .saturating_add(Weight::from_parts(0, 4005)) - // Standard Error: 117_260 - .saturating_add(Weight::from_parts(100_000, 0).saturating_mul(p.into())) - .saturating_add(T::DbWeight::get().reads(2)) - .saturating_add(T::DbWeight::get().writes(2)) - } /// Storage: `Programs::Programs` (r:2 w:2) /// Proof: `Programs::Programs` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Registry::Registered` (r:1 w:1) diff --git a/runtime/src/weights/pallet_staking_extension.rs b/runtime/src/weights/pallet_staking_extension.rs index 87698051d..f3232611b 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-07-26, STEPS: `5`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-08-21, STEPS: `5`, REPEAT: `2`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `Jesses-MacBook-Pro.local`, CPU: `` +//! HOSTNAME: `hcastano`, CPU: `` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: 1024 // Executed Command: @@ -53,11 +53,11 @@ impl pallet_staking_extension::WeightInfo for WeightInf /// Proof: `StakingExtension::ThresholdServers` (`max_values`: None, `max_size`: None, mode: `Measured`) fn change_endpoint() -> Weight { // Proof Size summary in bytes: - // Measured: `1342` - // Estimated: `4807` - // Minimum execution time: 25_000_000 picoseconds. - Weight::from_parts(29_000_000, 0) - .saturating_add(Weight::from_parts(0, 4807)) + // Measured: `1309` + // Estimated: `4774` + // Minimum execution time: 28_000_000 picoseconds. + Weight::from_parts(30_000_000, 0) + .saturating_add(Weight::from_parts(0, 4774)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -71,11 +71,11 @@ impl pallet_staking_extension::WeightInfo for WeightInf /// Proof: `StakingExtension::ThresholdServers` (`max_values`: None, `max_size`: None, mode: `Measured`) fn change_threshold_accounts() -> Weight { // Proof Size summary in bytes: - // Measured: `1463` - // Estimated: `4928` - // Minimum execution time: 28_000_000 picoseconds. - Weight::from_parts(29_000_000, 0) - .saturating_add(Weight::from_parts(0, 4928)) + // Measured: `1430` + // Estimated: `4895` + // Minimum execution time: 31_000_000 picoseconds. + Weight::from_parts(32_000_000, 0) + .saturating_add(Weight::from_parts(0, 4895)) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(2)) } @@ -95,8 +95,8 @@ impl pallet_staking_extension::WeightInfo for WeightInf // Proof Size summary in bytes: // Measured: `1262` // Estimated: `4764` - // Minimum execution time: 42_000_000 picoseconds. - Weight::from_parts(43_000_000, 0) + // Minimum execution time: 45_000_000 picoseconds. + Weight::from_parts(48_000_000, 0) .saturating_add(Weight::from_parts(0, 4764)) .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(3)) @@ -129,10 +129,10 @@ impl pallet_staking_extension::WeightInfo for WeightInf /// Proof: `StakingExtension::ThresholdServers` (`max_values`: None, `max_size`: None, mode: `Measured`) fn validate() -> Weight { // Proof Size summary in bytes: - // Measured: `1951` + // Measured: `1918` // Estimated: `6248` - // Minimum execution time: 64_000_000 picoseconds. - Weight::from_parts(70_000_000, 0) + // Minimum execution time: 76_000_000 picoseconds. + Weight::from_parts(184_000_000, 0) .saturating_add(Weight::from_parts(0, 6248)) .saturating_add(T::DbWeight::get().reads(13)) .saturating_add(T::DbWeight::get().writes(8)) @@ -143,11 +143,11 @@ impl pallet_staking_extension::WeightInfo for WeightInf /// Proof: `StakingExtension::IsValidatorSynced` (`max_values`: None, `max_size`: None, mode: `Measured`) fn declare_synced() -> Weight { // Proof Size summary in bytes: - // Measured: `353` - // Estimated: `3818` - // Minimum execution time: 10_000_000 picoseconds. - Weight::from_parts(11_000_000, 0) - .saturating_add(Weight::from_parts(0, 3818)) + // Measured: `320` + // Estimated: `3785` + // Minimum execution time: 11_000_000 picoseconds. + Weight::from_parts(13_000_000, 0) + .saturating_add(Weight::from_parts(0, 3785)) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -155,16 +155,19 @@ impl pallet_staking_extension::WeightInfo for WeightInf /// Proof: `StakingExtension::ThresholdToStash` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `StakingExtension::NextSigners` (r:1 w:1) /// Proof: `StakingExtension::NextSigners` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// The range of component `c` is `[0, 2]`. - fn confirm_key_reshare_confirmed(_c: u32, ) -> Weight { + /// The range of component `c` is `[0, 15]`. + fn confirm_key_reshare_confirmed(c: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `445` - // Estimated: `3910` - // Minimum execution time: 11_000_000 picoseconds. - Weight::from_parts(11_916_666, 0) - .saturating_add(Weight::from_parts(0, 3910)) + // Measured: `797 + c * (32 ±0)` + // Estimated: `4298 + c * (29 ±1)` + // Minimum execution time: 13_000_000 picoseconds. + Weight::from_parts(14_248_618, 0) + .saturating_add(Weight::from_parts(0, 4298)) + // Standard Error: 122_082 + .saturating_add(Weight::from_parts(90_469, 0).saturating_mul(c.into())) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) + .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`) @@ -174,12 +177,56 @@ impl pallet_staking_extension::WeightInfo for WeightInf /// Proof: `StakingExtension::Signers` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) fn confirm_key_reshare_completed() -> Weight { // Proof Size summary in bytes: - // Measured: `477` - // Estimated: `3942` - // Minimum execution time: 12_000_000 picoseconds. - Weight::from_parts(13_000_000, 0) - .saturating_add(Weight::from_parts(0, 3942)) + // Measured: `1309` + // Estimated: `4774` + // Minimum execution time: 14_000_000 picoseconds. + Weight::from_parts(14_000_000, 0) + .saturating_add(Weight::from_parts(0, 4774)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(2)) } + /// 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)) + .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) + /// 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`) + /// The range of component `c` is `[1, 14]`. + /// The range of component `l` is `[0, 15]`. + fn new_session(c: u32, _l: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `482 + c * (32 ±0)` + // Estimated: `1966 + c * (32 ±0)` + // Minimum execution time: 15_000_000 picoseconds. + Weight::from_parts(16_252_259, 0) + .saturating_add(Weight::from_parts(0, 1966)) + // Standard Error: 101_760 + .saturating_add(Weight::from_parts(74_486, 0).saturating_mul(c.into())) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(Weight::from_parts(0, 32).saturating_mul(c.into())) + } }