From 11bbdd5ad53ccc4a307acdc994c94300eb27bd3f Mon Sep 17 00:00:00 2001 From: Ayden Brewer Date: Mon, 10 Jul 2023 11:51:15 -0700 Subject: [PATCH 1/5] Add motion duration argument to Collective::propose with minimum duration --- pallets/collective/src/benchmarking.rs | 10 +++- pallets/collective/src/lib.rs | 10 +++- pallets/collective/src/tests.rs | 82 +++++++++++++++++--------- 3 files changed, 72 insertions(+), 30 deletions(-) diff --git a/pallets/collective/src/benchmarking.rs b/pallets/collective/src/benchmarking.rs index b8dcedabf..8b8ab0e44 100644 --- a/pallets/collective/src/benchmarking.rs +++ b/pallets/collective/src/benchmarking.rs @@ -73,6 +73,7 @@ benchmarks_instance_pallet! { SystemOrigin::Signed(old_members.last().unwrap().clone()).into(), Box::new(proposal.clone()), MAX_BYTES, + TryInto::::try_into(3u64).ok().expect("convert u64 to block number.") )?; let hash = T::Hashing::hash_of(&proposal); // Vote on the proposal to increase state relevant for `set_members`. @@ -161,6 +162,7 @@ benchmarks_instance_pallet! { SystemOrigin::Signed(caller.clone()).into(), Box::new(proposal), bytes_in_storage, + TryInto::::try_into(3u64).ok().expect("convert u64 to block number.") )?; } @@ -168,7 +170,7 @@ benchmarks_instance_pallet! { let proposal: T::Proposal = SystemCall::::remark { remark: id_to_remark_data(p, b as usize) }.into(); - }: propose(SystemOrigin::Signed(caller.clone()), Box::new(proposal.clone()), bytes_in_storage) + }: propose(SystemOrigin::Signed(caller.clone()), Box::new(proposal.clone()), bytes_in_storage, TryInto::::try_into(3u64).ok().expect("convert u64 to block number.")) verify { // New proposal is recorded assert_eq!(Collective::::proposals().len(), p as usize); @@ -208,6 +210,7 @@ benchmarks_instance_pallet! { SystemOrigin::Signed(proposer.clone()).into(), Box::new(proposal.clone()), bytes_in_storage, + TryInto::::try_into(3u64).ok().expect("convert u64 to block number.") )?; last_hash = T::Hashing::hash_of(&proposal); } @@ -282,6 +285,7 @@ benchmarks_instance_pallet! { SystemOrigin::Signed(proposer.clone()).into(), Box::new(proposal.clone()), bytes_in_storage, + TryInto::::try_into(3u64).ok().expect("convert u64 to block number.") )?; last_hash = T::Hashing::hash_of(&proposal); } @@ -358,6 +362,7 @@ benchmarks_instance_pallet! { SystemOrigin::Signed(caller.clone()).into(), Box::new(proposal.clone()), bytes_in_storage, + TryInto::::try_into(3u64).ok().expect("convert u64 to block number.") )?; last_hash = T::Hashing::hash_of(&proposal); } @@ -443,6 +448,7 @@ benchmarks_instance_pallet! { SystemOrigin::Signed(caller.clone()).into(), Box::new(proposal.clone()), bytes_in_storage, + TryInto::::try_into(3u64).ok().expect("convert u64 to block number.") )?; last_hash = T::Hashing::hash_of(&proposal); } @@ -524,6 +530,7 @@ benchmarks_instance_pallet! { SystemOrigin::Signed(caller.clone()).into(), Box::new(proposal.clone()), bytes_in_storage, + TryInto::::try_into(3u64).ok().expect("convert u64 to block number.") )?; last_hash = T::Hashing::hash_of(&proposal); } @@ -594,6 +601,7 @@ benchmarks_instance_pallet! { SystemOrigin::Signed(caller.clone()).into(), Box::new(proposal.clone()), bytes_in_storage, + TryInto::::try_into(3u64).ok().expect("convert u64 to block number.") )?; last_hash = T::Hashing::hash_of(&proposal); } diff --git a/pallets/collective/src/lib.rs b/pallets/collective/src/lib.rs index 858e7cd85..0bf34014b 100644 --- a/pallets/collective/src/lib.rs +++ b/pallets/collective/src/lib.rs @@ -348,6 +348,8 @@ pub mod pallet { WrongProposalWeight, /// The given length bound for the proposal was too low. WrongProposalLength, + /// The given motion duration for the proposal was too low. + WrongDuration, } // Note that councillor operations are assigned to the operational class. @@ -498,15 +500,18 @@ pub mod pallet { origin: OriginFor, proposal: Box<>::Proposal>, #[pallet::compact] length_bound: u32, + duration: T::BlockNumber, ) -> DispatchResultWithPostInfo { let who = ensure_signed(origin.clone())?; ensure!(T::CanPropose::can_propose(&who), Error::::NotMember); + + ensure!(duration >= T::MotionDuration::get(), Error::::WrongDuration); let threshold = (T::GetVotingMembers::get_count() / 2) + 1; let members = Self::members(); let (proposal_len, active_proposals) = - Self::do_propose_proposed(who, threshold, proposal, length_bound)?; + Self::do_propose_proposed(who, threshold, proposal, length_bound, duration)?; Ok(Some(T::WeightInfo::propose_proposed( proposal_len as u32, // B @@ -719,6 +724,7 @@ impl, I: 'static> Pallet { threshold: MemberCount, proposal: Box<>::Proposal>, length_bound: MemberCount, + duration: T::BlockNumber, ) -> Result<(u32, u32), DispatchError> { let proposal_len = proposal.encoded_size(); ensure!(proposal_len <= length_bound as usize, Error::::WrongProposalLength); @@ -736,7 +742,7 @@ impl, I: 'static> Pallet { >::mutate(|i| *i += 1); >::insert(proposal_hash, proposal); let votes = { - let end = frame_system::Pallet::::block_number() + T::MotionDuration::get(); + let end = frame_system::Pallet::::block_number() + duration; Votes { index, threshold, ayes: vec![], nays: vec![], end } }; >::insert(proposal_hash, votes); diff --git a/pallets/collective/src/tests.rs b/pallets/collective/src/tests.rs index 3f186543d..c13d02dde 100644 --- a/pallets/collective/src/tests.rs +++ b/pallets/collective/src/tests.rs @@ -282,7 +282,8 @@ fn close_works() { assert_ok!(Collective::propose( RuntimeOrigin::signed(1), Box::new(proposal.clone()), - proposal_len + proposal_len, + TryInto::<::BlockNumber>::try_into(3u64).ok().expect("convert u64 to block number.") )); assert_ok!(Collective::vote(RuntimeOrigin::signed(1), hash, 0, true)); @@ -346,7 +347,8 @@ fn proposal_weight_limit_works_on_approve() { assert_ok!(Collective::propose( RuntimeOrigin::signed(1), Box::new(proposal.clone()), - proposal_len + proposal_len, + TryInto::<::BlockNumber>::try_into(3u64).ok().expect("convert u64 to block number.") )); assert_ok!(Collective::vote(RuntimeOrigin::signed(1), hash, 0, true)); // With 1's prime vote, this should pass @@ -386,7 +388,8 @@ fn proposal_weight_limit_ignored_on_disapprove() { assert_ok!(Collective::propose( RuntimeOrigin::signed(1), Box::new(proposal.clone()), - proposal_len + proposal_len, + TryInto::<::BlockNumber>::try_into(3u64).ok().expect("convert u64 to block number.") )); // No votes, this proposal wont pass System::set_block_number(4); @@ -417,7 +420,8 @@ fn close_with_prime_works() { assert_ok!(Collective::propose( RuntimeOrigin::signed(1), Box::new(proposal.clone()), - proposal_len + proposal_len, + TryInto::<::BlockNumber>::try_into(3u64).ok().expect("convert u64 to block number.") )); assert_ok!(Collective::vote(RuntimeOrigin::signed(1), hash, 0, true)); @@ -476,7 +480,8 @@ fn close_with_voting_prime_works() { assert_ok!(Collective::propose( RuntimeOrigin::signed(1), Box::new(proposal.clone()), - proposal_len + proposal_len, + TryInto::<::BlockNumber>::try_into(3u64).ok().expect("convert u64 to block number.") )); assert_ok!(Collective::vote(RuntimeOrigin::signed(1), hash, 0, true)); @@ -537,7 +542,8 @@ fn close_with_no_prime_but_majority_works() { assert_ok!(CollectiveMajority::propose( RuntimeOrigin::signed(1), Box::new(proposal.clone()), - proposal_len + proposal_len, + TryInto::<::BlockNumber>::try_into(3u64).ok().expect("convert u64 to block number.") )); assert_ok!(CollectiveMajority::vote(RuntimeOrigin::signed(1), hash, 0, true)); assert_ok!(CollectiveMajority::vote(RuntimeOrigin::signed(2), hash, 0, true)); @@ -609,7 +615,8 @@ fn removal_of_old_voters_votes_works() { assert_ok!(Collective::propose( RuntimeOrigin::signed(1), Box::new(proposal.clone()), - proposal_len + proposal_len, + TryInto::<::BlockNumber>::try_into(3u64).ok().expect("convert u64 to block number.") )); assert_ok!(Collective::vote(RuntimeOrigin::signed(1), hash, 0, true)); assert_ok!(Collective::vote(RuntimeOrigin::signed(2), hash, 0, true)); @@ -629,7 +636,8 @@ fn removal_of_old_voters_votes_works() { assert_ok!(Collective::propose( RuntimeOrigin::signed(2), Box::new(proposal.clone()), - proposal_len + proposal_len, + TryInto::<::BlockNumber>::try_into(3u64).ok().expect("convert u64 to block number.") )); assert_ok!(Collective::vote(RuntimeOrigin::signed(2), hash, 1, true)); assert_ok!(Collective::vote(RuntimeOrigin::signed(3), hash, 1, false)); @@ -655,7 +663,8 @@ fn removal_of_old_voters_votes_works_with_set_members() { assert_ok!(Collective::propose( RuntimeOrigin::signed(1), Box::new(proposal.clone()), - proposal_len + proposal_len, + TryInto::<::BlockNumber>::try_into(3u64).ok().expect("convert u64 to block number.") )); assert_ok!(Collective::vote(RuntimeOrigin::signed(1), hash, 0, true)); assert_ok!(Collective::vote(RuntimeOrigin::signed(2), hash, 0, true)); @@ -680,7 +689,8 @@ fn removal_of_old_voters_votes_works_with_set_members() { assert_ok!(Collective::propose( RuntimeOrigin::signed(2), Box::new(proposal.clone()), - proposal_len + proposal_len, + TryInto::<::BlockNumber>::try_into(3u64).ok().expect("convert u64 to block number.") )); assert_ok!(Collective::vote(RuntimeOrigin::signed(2), hash, 1, true)); assert_ok!(Collective::vote(RuntimeOrigin::signed(3), hash, 1, false)); @@ -711,7 +721,8 @@ fn propose_works() { assert_ok!(Collective::propose( RuntimeOrigin::signed(1), Box::new(proposal.clone()), - proposal_len + proposal_len, + TryInto::<::BlockNumber>::try_into(3u64).ok().expect("convert u64 to block number.") )); assert_eq!(*Collective::proposals(), vec![hash]); assert_eq!(Collective::proposal_of(&hash), Some(proposal)); @@ -741,7 +752,8 @@ fn limit_active_proposals() { assert_ok!(Collective::propose( RuntimeOrigin::signed(1), Box::new(proposal.clone()), - proposal_len + proposal_len, + TryInto::<::BlockNumber>::try_into(3u64).ok().expect("convert u64 to block number.") )); } let proposal = make_proposal(MaxProposals::get() as u64 + 1); @@ -750,7 +762,8 @@ fn limit_active_proposals() { Collective::propose( RuntimeOrigin::signed(1), Box::new(proposal.clone()), - proposal_len + proposal_len, + TryInto::<::BlockNumber>::try_into(3u64).ok().expect("convert u64 to block number.") ), Error::::TooManyProposals ); @@ -769,7 +782,8 @@ fn correct_validate_and_get_proposal() { assert_ok!(Collective::propose( RuntimeOrigin::signed(1), Box::new(proposal.clone()), - length + length, + TryInto::<::BlockNumber>::try_into(3u64).ok().expect("convert u64 to block number.") )); let hash = BlakeTwo256::hash_of(&proposal); @@ -811,7 +825,8 @@ fn motions_ignoring_non_collective_proposals_works() { Collective::propose( RuntimeOrigin::signed(42), Box::new(proposal.clone()), - proposal_len + proposal_len, + TryInto::<::BlockNumber>::try_into(3u64).ok().expect("convert u64 to block number.") ), Error::::NotMember ); @@ -827,7 +842,8 @@ fn motions_ignoring_non_collective_votes_works() { assert_ok!(Collective::propose( RuntimeOrigin::signed(1), Box::new(proposal.clone()), - proposal_len + proposal_len, + TryInto::<::BlockNumber>::try_into(3u64).ok().expect("convert u64 to block number.") )); assert_noop!( Collective::vote(RuntimeOrigin::signed(42), hash, 0, true), @@ -846,7 +862,8 @@ fn motions_ignoring_bad_index_collective_vote_works() { assert_ok!(Collective::propose( RuntimeOrigin::signed(1), Box::new(proposal.clone()), - proposal_len + proposal_len, + TryInto::<::BlockNumber>::try_into(3u64).ok().expect("convert u64 to block number.") )); assert_noop!( Collective::vote(RuntimeOrigin::signed(2), hash, 1, true), @@ -865,7 +882,8 @@ fn motions_vote_after_works() { assert_ok!(Collective::propose( RuntimeOrigin::signed(1), Box::new(proposal.clone()), - proposal_len + proposal_len, + TryInto::<::BlockNumber>::try_into(3u64).ok().expect("convert u64 to block number.") )); // Initially there a no votes when the motion is proposed. assert_eq!( @@ -934,6 +952,7 @@ fn motions_all_first_vote_free_works() { RuntimeOrigin::signed(1), Box::new(proposal.clone()), proposal_len, + TryInto::<::BlockNumber>::try_into(3u64).ok().expect("convert u64 to block number.") )); assert_eq!( Collective::voting(&hash), @@ -990,7 +1009,8 @@ fn motions_reproposing_disapproved_works() { assert_ok!(Collective::propose( RuntimeOrigin::signed(1), Box::new(proposal.clone()), - proposal_len + proposal_len, + TryInto::<::BlockNumber>::try_into(3u64).ok().expect("convert u64 to block number.") )); assert_ok!(Collective::vote(RuntimeOrigin::signed(1), hash, 0, false)); @@ -1007,7 +1027,8 @@ fn motions_reproposing_disapproved_works() { assert_ok!(Collective::propose( RuntimeOrigin::signed(1), Box::new(proposal.clone()), - proposal_len + proposal_len, + TryInto::<::BlockNumber>::try_into(3u64).ok().expect("convert u64 to block number.") )); assert_eq!(*Collective::proposals(), vec![hash]); }); @@ -1028,7 +1049,8 @@ fn motions_approval_with_enough_votes_and_lower_voting_threshold_works() { assert_ok!(Collective::propose( RuntimeOrigin::signed(1), Box::new(proposal.clone()), - proposal_len + proposal_len, + TryInto::<::BlockNumber>::try_into(3u64).ok().expect("convert u64 to block number.") )); assert_ok!(Collective::vote(RuntimeOrigin::signed(1), hash, 0, true)); assert_ok!(Collective::vote(RuntimeOrigin::signed(2), hash, 0, true)); @@ -1081,7 +1103,8 @@ fn motions_approval_with_enough_votes_and_lower_voting_threshold_works() { assert_ok!(Collective::propose( RuntimeOrigin::signed(1), Box::new(proposal.clone()), - proposal_len + proposal_len, + TryInto::<::BlockNumber>::try_into(3u64).ok().expect("convert u64 to block number.") )); assert_ok!(Collective::vote(RuntimeOrigin::signed(1), hash, 1, true)); assert_ok!(Collective::vote(RuntimeOrigin::signed(2), hash, 1, true)); @@ -1151,7 +1174,8 @@ fn motions_disapproval_works() { assert_ok!(Collective::propose( RuntimeOrigin::signed(1), Box::new(proposal.clone()), - proposal_len + proposal_len, + TryInto::<::BlockNumber>::try_into(3u64).ok().expect("convert u64 to block number.") )); assert_ok!(Collective::vote(RuntimeOrigin::signed(1), hash, 0, false)); assert_ok!(Collective::vote(RuntimeOrigin::signed(2), hash, 0, false)); @@ -1209,7 +1233,8 @@ fn motions_approval_works() { assert_ok!(Collective::propose( RuntimeOrigin::signed(1), Box::new(proposal.clone()), - proposal_len + proposal_len, + TryInto::<::BlockNumber>::try_into(3u64).ok().expect("convert u64 to block number.") )); assert_ok!(Collective::vote(RuntimeOrigin::signed(1), hash, 0, true)); assert_ok!(Collective::vote(RuntimeOrigin::signed(2), hash, 0, true)); @@ -1269,7 +1294,8 @@ fn motion_with_no_votes_closes_with_disapproval() { assert_ok!(Collective::propose( RuntimeOrigin::signed(1), Box::new(proposal.clone()), - proposal_len + proposal_len, + TryInto::<::BlockNumber>::try_into(3u64).ok().expect("convert u64 to block number.") )); assert_eq!( System::events()[0], @@ -1328,7 +1354,8 @@ fn close_disapprove_does_not_care_about_weight_or_len() { assert_ok!(Collective::propose( RuntimeOrigin::signed(1), Box::new(proposal.clone()), - proposal_len + proposal_len, + TryInto::<::BlockNumber>::try_into(3u64).ok().expect("convert u64 to block number.") )); // First we make the proposal succeed assert_ok!(Collective::vote(RuntimeOrigin::signed(1), hash, 0, true)); @@ -1359,7 +1386,8 @@ fn disapprove_proposal_works() { assert_ok!(Collective::propose( RuntimeOrigin::signed(1), Box::new(proposal.clone()), - proposal_len + proposal_len, + TryInto::<::BlockNumber>::try_into(3u64).ok().expect("convert u64 to block number.") )); // Proposal would normally succeed assert_ok!(Collective::vote(RuntimeOrigin::signed(1), hash, 0, true)); From 69ec1c8f61906dffe27198f74967098c2513f746 Mon Sep 17 00:00:00 2001 From: Ayden Brewer Date: Mon, 10 Jul 2023 11:53:16 -0700 Subject: [PATCH 2/5] Update CouncilMotionDuration 6 DAYS -> 12 HOURS --- runtime/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 5c05d933e..791d9fc1c 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -322,7 +322,7 @@ impl pallet_transaction_payment::Config for Runtime { // Configure collective pallet for council parameter_types! { - pub const CouncilMotionDuration: BlockNumber = 6 * DAYS; + pub const CouncilMotionDuration: BlockNumber = 12 * HOURS; pub const CouncilMaxProposals: u32 = 10; pub const CouncilMaxMembers: u32 = 3; } From f44cc5925168020ddf45a58396d497363b3a5d6b Mon Sep 17 00:00:00 2001 From: Ayden Brewer Date: Mon, 10 Jul 2023 11:54:51 -0700 Subject: [PATCH 3/5] Up spec_version -> 127 --- runtime/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 791d9fc1c..5bb9a1be3 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -116,7 +116,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // `spec_version`, and `authoring_version` are the same between Wasm and native. // This value is set to 100 to notify Polkadot-JS App (https://polkadot.js.org/apps) to use // the compatible custom types. - spec_version: 126, + spec_version: 127, impl_version: 1, apis: RUNTIME_API_VERSIONS, transaction_version: 1, From f1db2c252c120b947542ceb247a8f1c04d994953 Mon Sep 17 00:00:00 2001 From: Ayden Brewer Date: Mon, 10 Jul 2023 12:42:46 -0700 Subject: [PATCH 4/5] Fix testing and benchmarks for propose change and auto threshold --- pallets/collective/src/benchmarking.rs | 36 ++++++-------------------- pallets/subtensor/tests/senate.rs | 9 ++++--- 2 files changed, 14 insertions(+), 31 deletions(-) diff --git a/pallets/collective/src/benchmarking.rs b/pallets/collective/src/benchmarking.rs index 8b8ab0e44..d42f329ab 100644 --- a/pallets/collective/src/benchmarking.rs +++ b/pallets/collective/src/benchmarking.rs @@ -153,7 +153,7 @@ benchmarks_instance_pallet! { members.push(caller.clone()); Collective::::set_members(SystemOrigin::Root.into(), members, None, T::MaxMembers::get())?; - let threshold = m; + let threshold = (m / 2) + 1; // Add previous proposals. for i in 0 .. p - 1 { // Proposals should be different so that different proposal hashes are generated @@ -273,9 +273,6 @@ benchmarks_instance_pallet! { members.push(voter.clone()); Collective::::set_members(SystemOrigin::Root.into(), members.clone(), None, T::MaxMembers::get())?; - // Threshold is total members so that one nay will disapprove the vote - let threshold = m; - // Add previous proposals let mut last_hash = T::Hash::default(); for i in 0 .. p { @@ -291,10 +288,10 @@ benchmarks_instance_pallet! { } let index = p - 1; - // Have most everyone vote aye on last proposal, while keeping it from passing. + // Have most everyone vote nay on last proposal, while keeping it from passing. for j in 0 .. m - 2 { let voter = &members[j as usize]; - let approve = true; + let approve = false; Collective::::vote( SystemOrigin::Signed(voter.clone()).into(), last_hash, @@ -302,6 +299,7 @@ benchmarks_instance_pallet! { approve, )?; } + // Voter votes aye without resolving the vote. let approve = true; Collective::::vote( @@ -313,15 +311,6 @@ benchmarks_instance_pallet! { assert_eq!(Collective::::proposals().len(), p as usize); - // Voter switches vote to nay, which kills the vote - let approve = false; - Collective::::vote( - SystemOrigin::Signed(voter.clone()).into(), - last_hash, - index, - approve, - )?; - // Whitelist voter account from further DB operations. let voter_key = frame_system::Account::::hashed_key_for(&voter); frame_benchmarking::benchmarking::add_to_whitelist(voter_key.into()); @@ -350,9 +339,6 @@ benchmarks_instance_pallet! { members.push(caller.clone()); Collective::::set_members(SystemOrigin::Root.into(), members.clone(), None, T::MaxMembers::get())?; - // Threshold is 2 so any two ayes will approve the vote - let threshold = 2; - // Add previous proposals let mut last_hash = T::Hash::default(); for i in 0 .. p { @@ -375,10 +361,10 @@ benchmarks_instance_pallet! { false, )?; - // Have almost everyone vote nay on last proposal, while keeping it from failing. + // Have almost everyone vote aye on last proposal, while keeping it from failing. for j in 2 .. m - 1 { let voter = &members[j as usize]; - let approve = false; + let approve = true; Collective::::vote( SystemOrigin::Signed(voter.clone()).into(), last_hash, @@ -436,9 +422,6 @@ benchmarks_instance_pallet! { T::MaxMembers::get(), )?; - // Threshold is one less than total members so that two nays will disapprove the vote - let threshold = m - 1; - // Add proposals let mut last_hash = T::Hash::default(); for i in 0 .. p { @@ -457,7 +440,7 @@ benchmarks_instance_pallet! { // Have almost everyone vote aye on last proposal, while keeping it from passing. // A few abstainers will be the nay votes needed to fail the vote. let mut yes_votes: MemberCount = 0; - for j in 2 .. m - 1 { + for j in 2 .. m / 2 { let voter = &members[j as usize]; let approve = true; yes_votes += 1; @@ -518,9 +501,6 @@ benchmarks_instance_pallet! { T::MaxMembers::get(), )?; - // Threshold is two, so any two ayes will pass the vote - let threshold = 2; - // Add proposals let mut last_hash = T::Hash::default(); for i in 0 .. p { @@ -545,7 +525,7 @@ benchmarks_instance_pallet! { // Have almost everyone vote nay on last proposal, while keeping it from failing. // A few abstainers will be the aye votes needed to pass the vote. - for j in 2 .. m - 1 { + for j in 2 .. m / 2 { let voter = &members[j as usize]; let approve = false; Collective::::vote( diff --git a/pallets/subtensor/tests/senate.rs b/pallets/subtensor/tests/senate.rs index c77240cbd..a992eb3b3 100644 --- a/pallets/subtensor/tests/senate.rs +++ b/pallets/subtensor/tests/senate.rs @@ -167,7 +167,8 @@ fn test_senate_vote_works() { assert_ok!(Triumvirate::propose( RuntimeOrigin::signed(senate_hotkey), Box::new(proposal.clone()), - proposal_len + proposal_len, + TryInto::<::BlockNumber>::try_into(100u64).ok().expect("convert u64 to block number.") )); assert_ok!(SubtensorModule::do_vote_senate(<::RuntimeOrigin>::signed(coldkey_account_id), &hotkey_account_id, hash, 0, true)); @@ -223,7 +224,8 @@ fn test_senate_vote_not_member() { assert_ok!(Triumvirate::propose( RuntimeOrigin::signed(senate_hotkey), Box::new(proposal.clone()), - proposal_len + proposal_len, + TryInto::<::BlockNumber>::try_into(100u64).ok().expect("convert u64 to block number.") )); assert_noop!(SubtensorModule::do_vote_senate( @@ -354,7 +356,8 @@ fn test_senate_leave_vote_removal() { assert_ok!(Triumvirate::propose( RuntimeOrigin::signed(senate_hotkey), Box::new(proposal.clone()), - proposal_len + proposal_len, + TryInto::<::BlockNumber>::try_into(100u64).ok().expect("convert u64 to block number.") )); assert_ok!(SubtensorModule::do_vote_senate(coldkey_origin.clone(), &hotkey_account_id, hash, 0, true)); From 10240ad3453189e2f700202f6093d42779085e76 Mon Sep 17 00:00:00 2001 From: Ayden Brewer Date: Mon, 10 Jul 2023 12:42:46 -0700 Subject: [PATCH 5/5] :robot: :butter: Reformat source code --- pallets/collective/src/benchmarking.rs | 1118 +++++++++++------------ pallets/subtensor/tests/senate.rs | 1154 +++++++++++++++--------- 2 files changed, 1271 insertions(+), 1001 deletions(-) diff --git a/pallets/collective/src/benchmarking.rs b/pallets/collective/src/benchmarking.rs index d42f329ab..48a545634 100644 --- a/pallets/collective/src/benchmarking.rs +++ b/pallets/collective/src/benchmarking.rs @@ -31,569 +31,569 @@ const SEED: u32 = 0; const MAX_BYTES: u32 = 1_024; fn assert_last_event, I: 'static>(generic_event: >::RuntimeEvent) { - frame_system::Pallet::::assert_last_event(generic_event.into()); + frame_system::Pallet::::assert_last_event(generic_event.into()); } fn id_to_remark_data(id: u32, length: usize) -> Vec { - id.to_le_bytes().into_iter().cycle().take(length).collect() + id.to_le_bytes().into_iter().cycle().take(length).collect() } benchmarks_instance_pallet! { - set_members { - let m in 0 .. T::MaxMembers::get(); - let n in 0 .. T::MaxMembers::get(); - let p in 0 .. T::MaxProposals::get(); - - // Set old members. - // We compute the difference of old and new members, so it should influence timing. - let mut old_members = vec![]; - for i in 0 .. m { - let old_member = account::("old member", i, SEED); - old_members.push(old_member); - } - let old_members_count = old_members.len() as u32; - - Collective::::set_members( - SystemOrigin::Root.into(), - old_members.clone(), - old_members.last().cloned(), - T::MaxMembers::get(), - )?; - - // If there were any old members generate a bunch of proposals. - if m > 0 { - // Set a high threshold for proposals passing so that they stay around. - let threshold = m.max(2); - // Length of the proposals should be irrelevant to `set_members`. - let length = 100; - for i in 0 .. p { - // Proposals should be different so that different proposal hashes are generated - let proposal: T::Proposal = SystemCall::::remark { remark: id_to_remark_data(i, length) }.into(); - Collective::::propose( - SystemOrigin::Signed(old_members.last().unwrap().clone()).into(), - Box::new(proposal.clone()), - MAX_BYTES, - TryInto::::try_into(3u64).ok().expect("convert u64 to block number.") - )?; - let hash = T::Hashing::hash_of(&proposal); - // Vote on the proposal to increase state relevant for `set_members`. - // Not voting for last old member because they proposed and not voting for the first member - // to keep the proposal from passing. - for j in 2 .. m - 1 { - let voter = &old_members[j as usize]; - let approve = true; - Collective::::vote( - SystemOrigin::Signed(voter.clone()).into(), - hash, - i, - approve, - )?; - } - } - } - - // Construct `new_members`. - // It should influence timing since it will sort this vector. - let mut new_members = vec![]; - for i in 0 .. n { - let member = account::("member", i, SEED); - new_members.push(member); - } - - }: _(SystemOrigin::Root, new_members.clone(), new_members.last().cloned(), T::MaxMembers::get()) - verify { - new_members.sort(); - assert_eq!(Collective::::members(), new_members); - } - - execute { - let b in 2 .. MAX_BYTES; - let m in 1 .. T::MaxMembers::get(); - - let bytes_in_storage = b + size_of::() as u32; - - // Construct `members`. - let mut members = vec![]; - for i in 0 .. m - 1 { - let member = account::("member", i, SEED); - members.push(member); - } - - let caller: T::AccountId = whitelisted_caller(); - members.push(caller.clone()); - - Collective::::set_members(SystemOrigin::Root.into(), members, None, T::MaxMembers::get())?; - - let proposal: T::Proposal = SystemCall::::remark { remark: id_to_remark_data(1, b as usize) }.into(); - - }: _(SystemOrigin::Signed(caller), Box::new(proposal.clone()), bytes_in_storage) - verify { - let proposal_hash = T::Hashing::hash_of(&proposal); - // Note that execution fails due to mis-matched origin - assert_last_event::( - Event::MemberExecuted { proposal_hash, result: Err(DispatchError::BadOrigin) }.into() - ); - } - - // This tests when proposal is created and queued as "proposed" - propose_proposed { - let b in 2 .. MAX_BYTES; - let m in 2 .. T::MaxMembers::get(); - let p in 1 .. T::MaxProposals::get(); - - let bytes_in_storage = b + size_of::() as u32; - - // Construct `members`. - let mut members = vec![]; - for i in 0 .. m - 1 { - let member = account::("member", i, SEED); - members.push(member); - } - let caller: T::AccountId = whitelisted_caller(); - members.push(caller.clone()); - Collective::::set_members(SystemOrigin::Root.into(), members, None, T::MaxMembers::get())?; - - let threshold = (m / 2) + 1; - // Add previous proposals. - for i in 0 .. p - 1 { - // Proposals should be different so that different proposal hashes are generated - let proposal: T::Proposal = SystemCall::::remark { remark: id_to_remark_data(i, b as usize) }.into(); - Collective::::propose( - SystemOrigin::Signed(caller.clone()).into(), - Box::new(proposal), - bytes_in_storage, - TryInto::::try_into(3u64).ok().expect("convert u64 to block number.") - )?; - } - - assert_eq!(Collective::::proposals().len(), (p - 1) as usize); - - let proposal: T::Proposal = SystemCall::::remark { remark: id_to_remark_data(p, b as usize) }.into(); - - }: propose(SystemOrigin::Signed(caller.clone()), Box::new(proposal.clone()), bytes_in_storage, TryInto::::try_into(3u64).ok().expect("convert u64 to block number.")) - verify { - // New proposal is recorded - assert_eq!(Collective::::proposals().len(), p as usize); - let proposal_hash = T::Hashing::hash_of(&proposal); - assert_last_event::(Event::Proposed { account: caller, proposal_index: p - 1, proposal_hash, threshold }.into()); - } - - vote { - // We choose 5 as a minimum so we always trigger a vote in the voting loop (`for j in ...`) - let m in 5 .. T::MaxMembers::get(); - - let p = T::MaxProposals::get(); - let b = MAX_BYTES; - let bytes_in_storage = b + size_of::() as u32; - - // Construct `members`. - let mut members = vec![]; - let proposer: T::AccountId = account::("proposer", 0, SEED); - members.push(proposer.clone()); - for i in 1 .. m - 1 { - let member = account::("member", i, SEED); - members.push(member); - } - let voter: T::AccountId = account::("voter", 0, SEED); - members.push(voter.clone()); - Collective::::set_members(SystemOrigin::Root.into(), members.clone(), None, T::MaxMembers::get())?; - - // Threshold is 1 less than the number of members so that one person can vote nay - let threshold = m - 1; - - // Add previous proposals - let mut last_hash = T::Hash::default(); - for i in 0 .. p { - // Proposals should be different so that different proposal hashes are generated - let proposal: T::Proposal = SystemCall::::remark { remark: id_to_remark_data(i, b as usize) }.into(); - Collective::::propose( - SystemOrigin::Signed(proposer.clone()).into(), - Box::new(proposal.clone()), - bytes_in_storage, - TryInto::::try_into(3u64).ok().expect("convert u64 to block number.") - )?; - last_hash = T::Hashing::hash_of(&proposal); - } - - let index = p - 1; - // Have almost everyone vote aye on last proposal, while keeping it from passing. - for j in 0 .. m - 3 { - let voter = &members[j as usize]; - let approve = true; - Collective::::vote( - SystemOrigin::Signed(voter.clone()).into(), - last_hash, - index, - approve, - )?; - } - // Voter votes aye without resolving the vote. - let approve = true; - Collective::::vote( - SystemOrigin::Signed(voter.clone()).into(), - last_hash, - index, - approve, - )?; - - assert_eq!(Collective::::proposals().len(), p as usize); - - // Voter switches vote to nay, but does not kill the vote, just updates + inserts - let approve = false; - - // Whitelist voter account from further DB operations. - let voter_key = frame_system::Account::::hashed_key_for(&voter); - frame_benchmarking::benchmarking::add_to_whitelist(voter_key.into()); - }: _(SystemOrigin::Signed(voter), last_hash, index, approve) - verify { - // All proposals exist and the last proposal has just been updated. - assert_eq!(Collective::::proposals().len(), p as usize); - let voting = Collective::::voting(&last_hash).ok_or("Proposal Missing")?; - assert_eq!(voting.ayes.len(), (m - 3) as usize); - assert_eq!(voting.nays.len(), 1); - } - - close_early_disapproved { - // We choose 4 as a minimum so we always trigger a vote in the voting loop (`for j in ...`) - let m in 4 .. T::MaxMembers::get(); - let p in 1 .. T::MaxProposals::get(); - - let bytes = 100; - let bytes_in_storage = bytes + size_of::() as u32; - - // Construct `members`. - let mut members = vec![]; - let proposer = account::("proposer", 0, SEED); - members.push(proposer.clone()); - for i in 1 .. m - 1 { - let member = account::("member", i, SEED); - members.push(member); - } - let voter = account::("voter", 0, SEED); - members.push(voter.clone()); - Collective::::set_members(SystemOrigin::Root.into(), members.clone(), None, T::MaxMembers::get())?; - - // Add previous proposals - let mut last_hash = T::Hash::default(); - for i in 0 .. p { - // Proposals should be different so that different proposal hashes are generated - let proposal: T::Proposal = SystemCall::::remark { remark: id_to_remark_data(i, bytes as usize) }.into(); - Collective::::propose( - SystemOrigin::Signed(proposer.clone()).into(), - Box::new(proposal.clone()), - bytes_in_storage, - TryInto::::try_into(3u64).ok().expect("convert u64 to block number.") - )?; - last_hash = T::Hashing::hash_of(&proposal); - } - - let index = p - 1; - // Have most everyone vote nay on last proposal, while keeping it from passing. - for j in 0 .. m - 2 { - let voter = &members[j as usize]; - let approve = false; - Collective::::vote( - SystemOrigin::Signed(voter.clone()).into(), - last_hash, - index, - approve, - )?; - } - - // Voter votes aye without resolving the vote. - let approve = true; - Collective::::vote( - SystemOrigin::Signed(voter.clone()).into(), - last_hash, - index, - approve, - )?; - - assert_eq!(Collective::::proposals().len(), p as usize); - - // Whitelist voter account from further DB operations. - let voter_key = frame_system::Account::::hashed_key_for(&voter); - frame_benchmarking::benchmarking::add_to_whitelist(voter_key.into()); - }: close(SystemOrigin::Signed(voter), last_hash, index, Weight::MAX, bytes_in_storage) - verify { - // The last proposal is removed. - assert_eq!(Collective::::proposals().len(), (p - 1) as usize); - assert_last_event::(Event::Disapproved { proposal_hash: last_hash }.into()); - } - - close_early_approved { - let b in 2 .. MAX_BYTES; - // We choose 4 as a minimum so we always trigger a vote in the voting loop (`for j in ...`) - let m in 4 .. T::MaxMembers::get(); - let p in 1 .. T::MaxProposals::get(); - - let bytes_in_storage = b + size_of::() as u32; - - // Construct `members`. - let mut members = vec![]; - for i in 0 .. m - 1 { - let member = account::("member", i, SEED); - members.push(member); - } - let caller: T::AccountId = whitelisted_caller(); - members.push(caller.clone()); - Collective::::set_members(SystemOrigin::Root.into(), members.clone(), None, T::MaxMembers::get())?; - - // Add previous proposals - let mut last_hash = T::Hash::default(); - for i in 0 .. p { - // Proposals should be different so that different proposal hashes are generated - let proposal: T::Proposal = SystemCall::::remark { remark: id_to_remark_data(i, b as usize) }.into(); - Collective::::propose( - SystemOrigin::Signed(caller.clone()).into(), - Box::new(proposal.clone()), - bytes_in_storage, - TryInto::::try_into(3u64).ok().expect("convert u64 to block number.") - )?; - last_hash = T::Hashing::hash_of(&proposal); - } - - // Caller switches vote to nay on their own proposal, allowing them to be the deciding approval vote - Collective::::vote( - SystemOrigin::Signed(caller.clone()).into(), - last_hash, - p - 1, - false, - )?; - - // Have almost everyone vote aye on last proposal, while keeping it from failing. - for j in 2 .. m - 1 { - let voter = &members[j as usize]; - let approve = true; - Collective::::vote( - SystemOrigin::Signed(voter.clone()).into(), - last_hash, - p - 1, - approve, - )?; - } - - // Member zero is the first aye - Collective::::vote( - SystemOrigin::Signed(members[0].clone()).into(), - last_hash, - p - 1, - true, - )?; - - assert_eq!(Collective::::proposals().len(), p as usize); - - // Caller switches vote to aye, which passes the vote - let index = p - 1; - let approve = true; - Collective::::vote( - SystemOrigin::Signed(caller.clone()).into(), - last_hash, - index, approve, - )?; - - }: close(SystemOrigin::Signed(caller), last_hash, index, Weight::MAX, bytes_in_storage) - verify { - // The last proposal is removed. - assert_eq!(Collective::::proposals().len(), (p - 1) as usize); - assert_last_event::(Event::Executed { proposal_hash: last_hash, result: Err(DispatchError::BadOrigin) }.into()); - } - - close_disapproved { - // We choose 4 as a minimum so we always trigger a vote in the voting loop (`for j in ...`) - let m in 4 .. T::MaxMembers::get(); - let p in 1 .. T::MaxProposals::get(); - - let bytes = 100; - let bytes_in_storage = bytes + size_of::() as u32; - - // Construct `members`. - let mut members = vec![]; - for i in 0 .. m - 1 { - let member = account::("member", i, SEED); - members.push(member); - } - let caller: T::AccountId = whitelisted_caller(); - members.push(caller.clone()); - Collective::::set_members( - SystemOrigin::Root.into(), - members.clone(), - Some(caller.clone()), - T::MaxMembers::get(), - )?; - - // Add proposals - let mut last_hash = T::Hash::default(); - for i in 0 .. p { - // Proposals should be different so that different proposal hashes are generated - let proposal: T::Proposal = SystemCall::::remark { remark: id_to_remark_data(i, bytes as usize) }.into(); - Collective::::propose( - SystemOrigin::Signed(caller.clone()).into(), - Box::new(proposal.clone()), - bytes_in_storage, - TryInto::::try_into(3u64).ok().expect("convert u64 to block number.") - )?; - last_hash = T::Hashing::hash_of(&proposal); - } - - let index = p - 1; - // Have almost everyone vote aye on last proposal, while keeping it from passing. - // A few abstainers will be the nay votes needed to fail the vote. - let mut yes_votes: MemberCount = 0; - for j in 2 .. m / 2 { - let voter = &members[j as usize]; - let approve = true; - yes_votes += 1; - // vote aye till a prime nay vote keeps the proposal disapproved. - if <>::DefaultVote as DefaultVote>::default_vote( - Some(false), - yes_votes, - 0, - m,) { - break; - } - Collective::::vote( - SystemOrigin::Signed(voter.clone()).into(), - last_hash, - index, - approve, - )?; - } - - // caller is prime, prime votes nay - Collective::::vote( - SystemOrigin::Signed(caller.clone()).into(), - last_hash, - index, - false, - )?; - - System::::set_block_number(T::BlockNumber::max_value()); - assert_eq!(Collective::::proposals().len(), p as usize); - - // Prime nay will close it as disapproved - }: close(SystemOrigin::Signed(caller), last_hash, index, Weight::MAX, bytes_in_storage) - verify { - assert_eq!(Collective::::proposals().len(), (p - 1) as usize); - assert_last_event::(Event::Disapproved { proposal_hash: last_hash }.into()); - } - - close_approved { - let b in 2 .. MAX_BYTES; - // We choose 4 as a minimum so we always trigger a vote in the voting loop (`for j in ...`) - let m in 4 .. T::MaxMembers::get(); - let p in 1 .. T::MaxProposals::get(); - - let bytes_in_storage = b + size_of::() as u32; - - // Construct `members`. - let mut members = vec![]; - for i in 0 .. m - 1 { - let member = account::("member", i, SEED); - members.push(member); - } - let caller: T::AccountId = whitelisted_caller(); - members.push(caller.clone()); - Collective::::set_members( - SystemOrigin::Root.into(), - members.clone(), - Some(caller.clone()), - T::MaxMembers::get(), - )?; - - // Add proposals - let mut last_hash = T::Hash::default(); - for i in 0 .. p { - // Proposals should be different so that different proposal hashes are generated - let proposal: T::Proposal = SystemCall::::remark { remark: id_to_remark_data(i, b as usize) }.into(); - Collective::::propose( - SystemOrigin::Signed(caller.clone()).into(), - Box::new(proposal.clone()), - bytes_in_storage, - TryInto::::try_into(3u64).ok().expect("convert u64 to block number.") - )?; - last_hash = T::Hashing::hash_of(&proposal); - } - - // The prime member votes aye, so abstentions default to aye. - Collective::::vote( - SystemOrigin::Signed(caller.clone()).into(), - last_hash, - p - 1, - true // Vote aye. - )?; - - // Have almost everyone vote nay on last proposal, while keeping it from failing. - // A few abstainers will be the aye votes needed to pass the vote. - for j in 2 .. m / 2 { - let voter = &members[j as usize]; - let approve = false; - Collective::::vote( - SystemOrigin::Signed(voter.clone()).into(), - last_hash, - p - 1, - approve - )?; - } - - // caller is prime, prime already votes aye by creating the proposal - System::::set_block_number(T::BlockNumber::max_value()); - assert_eq!(Collective::::proposals().len(), p as usize); - - // Prime aye will close it as approved - }: close(SystemOrigin::Signed(caller), last_hash, p - 1, Weight::MAX, bytes_in_storage) - verify { - assert_eq!(Collective::::proposals().len(), (p - 1) as usize); - assert_last_event::(Event::Executed { proposal_hash: last_hash, result: Err(DispatchError::BadOrigin) }.into()); - } - - disapprove_proposal { - let p in 1 .. T::MaxProposals::get(); - - let m = 3; - let b = MAX_BYTES; - let bytes_in_storage = b + size_of::() as u32; - - // Construct `members`. - let mut members = vec![]; - for i in 0 .. m - 1 { - let member = account::("member", i, SEED); - members.push(member); - } - let caller = account::("caller", 0, SEED); - members.push(caller.clone()); - Collective::::set_members( - SystemOrigin::Root.into(), - members.clone(), - Some(caller.clone()), - T::MaxMembers::get(), - )?; - - // Threshold is one less than total members so that two nays will disapprove the vote - let threshold = m - 1; - - // Add proposals - let mut last_hash = T::Hash::default(); - for i in 0 .. p { - // Proposals should be different so that different proposal hashes are generated - let proposal: T::Proposal = SystemCall::::remark { remark: id_to_remark_data(i, b as usize) }.into(); - Collective::::propose( - SystemOrigin::Signed(caller.clone()).into(), - Box::new(proposal.clone()), - bytes_in_storage, - TryInto::::try_into(3u64).ok().expect("convert u64 to block number.") - )?; - last_hash = T::Hashing::hash_of(&proposal); - } - - System::::set_block_number(T::BlockNumber::max_value()); - assert_eq!(Collective::::proposals().len(), p as usize); - - }: _(SystemOrigin::Root, last_hash) - verify { - assert_eq!(Collective::::proposals().len(), (p - 1) as usize); - assert_last_event::(Event::Disapproved { proposal_hash: last_hash }.into()); - } - - impl_benchmark_test_suite!(Collective, crate::tests::new_test_ext(), crate::tests::Test); + set_members { + let m in 0 .. T::MaxMembers::get(); + let n in 0 .. T::MaxMembers::get(); + let p in 0 .. T::MaxProposals::get(); + + // Set old members. + // We compute the difference of old and new members, so it should influence timing. + let mut old_members = vec![]; + for i in 0 .. m { + let old_member = account::("old member", i, SEED); + old_members.push(old_member); + } + let old_members_count = old_members.len() as u32; + + Collective::::set_members( + SystemOrigin::Root.into(), + old_members.clone(), + old_members.last().cloned(), + T::MaxMembers::get(), + )?; + + // If there were any old members generate a bunch of proposals. + if m > 0 { + // Set a high threshold for proposals passing so that they stay around. + let threshold = m.max(2); + // Length of the proposals should be irrelevant to `set_members`. + let length = 100; + for i in 0 .. p { + // Proposals should be different so that different proposal hashes are generated + let proposal: T::Proposal = SystemCall::::remark { remark: id_to_remark_data(i, length) }.into(); + Collective::::propose( + SystemOrigin::Signed(old_members.last().unwrap().clone()).into(), + Box::new(proposal.clone()), + MAX_BYTES, + TryInto::::try_into(3u64).ok().expect("convert u64 to block number.") + )?; + let hash = T::Hashing::hash_of(&proposal); + // Vote on the proposal to increase state relevant for `set_members`. + // Not voting for last old member because they proposed and not voting for the first member + // to keep the proposal from passing. + for j in 2 .. m - 1 { + let voter = &old_members[j as usize]; + let approve = true; + Collective::::vote( + SystemOrigin::Signed(voter.clone()).into(), + hash, + i, + approve, + )?; + } + } + } + + // Construct `new_members`. + // It should influence timing since it will sort this vector. + let mut new_members = vec![]; + for i in 0 .. n { + let member = account::("member", i, SEED); + new_members.push(member); + } + + }: _(SystemOrigin::Root, new_members.clone(), new_members.last().cloned(), T::MaxMembers::get()) + verify { + new_members.sort(); + assert_eq!(Collective::::members(), new_members); + } + + execute { + let b in 2 .. MAX_BYTES; + let m in 1 .. T::MaxMembers::get(); + + let bytes_in_storage = b + size_of::() as u32; + + // Construct `members`. + let mut members = vec![]; + for i in 0 .. m - 1 { + let member = account::("member", i, SEED); + members.push(member); + } + + let caller: T::AccountId = whitelisted_caller(); + members.push(caller.clone()); + + Collective::::set_members(SystemOrigin::Root.into(), members, None, T::MaxMembers::get())?; + + let proposal: T::Proposal = SystemCall::::remark { remark: id_to_remark_data(1, b as usize) }.into(); + + }: _(SystemOrigin::Signed(caller), Box::new(proposal.clone()), bytes_in_storage) + verify { + let proposal_hash = T::Hashing::hash_of(&proposal); + // Note that execution fails due to mis-matched origin + assert_last_event::( + Event::MemberExecuted { proposal_hash, result: Err(DispatchError::BadOrigin) }.into() + ); + } + + // This tests when proposal is created and queued as "proposed" + propose_proposed { + let b in 2 .. MAX_BYTES; + let m in 2 .. T::MaxMembers::get(); + let p in 1 .. T::MaxProposals::get(); + + let bytes_in_storage = b + size_of::() as u32; + + // Construct `members`. + let mut members = vec![]; + for i in 0 .. m - 1 { + let member = account::("member", i, SEED); + members.push(member); + } + let caller: T::AccountId = whitelisted_caller(); + members.push(caller.clone()); + Collective::::set_members(SystemOrigin::Root.into(), members, None, T::MaxMembers::get())?; + + let threshold = (m / 2) + 1; + // Add previous proposals. + for i in 0 .. p - 1 { + // Proposals should be different so that different proposal hashes are generated + let proposal: T::Proposal = SystemCall::::remark { remark: id_to_remark_data(i, b as usize) }.into(); + Collective::::propose( + SystemOrigin::Signed(caller.clone()).into(), + Box::new(proposal), + bytes_in_storage, + TryInto::::try_into(3u64).ok().expect("convert u64 to block number.") + )?; + } + + assert_eq!(Collective::::proposals().len(), (p - 1) as usize); + + let proposal: T::Proposal = SystemCall::::remark { remark: id_to_remark_data(p, b as usize) }.into(); + + }: propose(SystemOrigin::Signed(caller.clone()), Box::new(proposal.clone()), bytes_in_storage, TryInto::::try_into(3u64).ok().expect("convert u64 to block number.")) + verify { + // New proposal is recorded + assert_eq!(Collective::::proposals().len(), p as usize); + let proposal_hash = T::Hashing::hash_of(&proposal); + assert_last_event::(Event::Proposed { account: caller, proposal_index: p - 1, proposal_hash, threshold }.into()); + } + + vote { + // We choose 5 as a minimum so we always trigger a vote in the voting loop (`for j in ...`) + let m in 5 .. T::MaxMembers::get(); + + let p = T::MaxProposals::get(); + let b = MAX_BYTES; + let bytes_in_storage = b + size_of::() as u32; + + // Construct `members`. + let mut members = vec![]; + let proposer: T::AccountId = account::("proposer", 0, SEED); + members.push(proposer.clone()); + for i in 1 .. m - 1 { + let member = account::("member", i, SEED); + members.push(member); + } + let voter: T::AccountId = account::("voter", 0, SEED); + members.push(voter.clone()); + Collective::::set_members(SystemOrigin::Root.into(), members.clone(), None, T::MaxMembers::get())?; + + // Threshold is 1 less than the number of members so that one person can vote nay + let threshold = m - 1; + + // Add previous proposals + let mut last_hash = T::Hash::default(); + for i in 0 .. p { + // Proposals should be different so that different proposal hashes are generated + let proposal: T::Proposal = SystemCall::::remark { remark: id_to_remark_data(i, b as usize) }.into(); + Collective::::propose( + SystemOrigin::Signed(proposer.clone()).into(), + Box::new(proposal.clone()), + bytes_in_storage, + TryInto::::try_into(3u64).ok().expect("convert u64 to block number.") + )?; + last_hash = T::Hashing::hash_of(&proposal); + } + + let index = p - 1; + // Have almost everyone vote aye on last proposal, while keeping it from passing. + for j in 0 .. m - 3 { + let voter = &members[j as usize]; + let approve = true; + Collective::::vote( + SystemOrigin::Signed(voter.clone()).into(), + last_hash, + index, + approve, + )?; + } + // Voter votes aye without resolving the vote. + let approve = true; + Collective::::vote( + SystemOrigin::Signed(voter.clone()).into(), + last_hash, + index, + approve, + )?; + + assert_eq!(Collective::::proposals().len(), p as usize); + + // Voter switches vote to nay, but does not kill the vote, just updates + inserts + let approve = false; + + // Whitelist voter account from further DB operations. + let voter_key = frame_system::Account::::hashed_key_for(&voter); + frame_benchmarking::benchmarking::add_to_whitelist(voter_key.into()); + }: _(SystemOrigin::Signed(voter), last_hash, index, approve) + verify { + // All proposals exist and the last proposal has just been updated. + assert_eq!(Collective::::proposals().len(), p as usize); + let voting = Collective::::voting(&last_hash).ok_or("Proposal Missing")?; + assert_eq!(voting.ayes.len(), (m - 3) as usize); + assert_eq!(voting.nays.len(), 1); + } + + close_early_disapproved { + // We choose 4 as a minimum so we always trigger a vote in the voting loop (`for j in ...`) + let m in 4 .. T::MaxMembers::get(); + let p in 1 .. T::MaxProposals::get(); + + let bytes = 100; + let bytes_in_storage = bytes + size_of::() as u32; + + // Construct `members`. + let mut members = vec![]; + let proposer = account::("proposer", 0, SEED); + members.push(proposer.clone()); + for i in 1 .. m - 1 { + let member = account::("member", i, SEED); + members.push(member); + } + let voter = account::("voter", 0, SEED); + members.push(voter.clone()); + Collective::::set_members(SystemOrigin::Root.into(), members.clone(), None, T::MaxMembers::get())?; + + // Add previous proposals + let mut last_hash = T::Hash::default(); + for i in 0 .. p { + // Proposals should be different so that different proposal hashes are generated + let proposal: T::Proposal = SystemCall::::remark { remark: id_to_remark_data(i, bytes as usize) }.into(); + Collective::::propose( + SystemOrigin::Signed(proposer.clone()).into(), + Box::new(proposal.clone()), + bytes_in_storage, + TryInto::::try_into(3u64).ok().expect("convert u64 to block number.") + )?; + last_hash = T::Hashing::hash_of(&proposal); + } + + let index = p - 1; + // Have most everyone vote nay on last proposal, while keeping it from passing. + for j in 0 .. m - 2 { + let voter = &members[j as usize]; + let approve = false; + Collective::::vote( + SystemOrigin::Signed(voter.clone()).into(), + last_hash, + index, + approve, + )?; + } + + // Voter votes aye without resolving the vote. + let approve = true; + Collective::::vote( + SystemOrigin::Signed(voter.clone()).into(), + last_hash, + index, + approve, + )?; + + assert_eq!(Collective::::proposals().len(), p as usize); + + // Whitelist voter account from further DB operations. + let voter_key = frame_system::Account::::hashed_key_for(&voter); + frame_benchmarking::benchmarking::add_to_whitelist(voter_key.into()); + }: close(SystemOrigin::Signed(voter), last_hash, index, Weight::MAX, bytes_in_storage) + verify { + // The last proposal is removed. + assert_eq!(Collective::::proposals().len(), (p - 1) as usize); + assert_last_event::(Event::Disapproved { proposal_hash: last_hash }.into()); + } + + close_early_approved { + let b in 2 .. MAX_BYTES; + // We choose 4 as a minimum so we always trigger a vote in the voting loop (`for j in ...`) + let m in 4 .. T::MaxMembers::get(); + let p in 1 .. T::MaxProposals::get(); + + let bytes_in_storage = b + size_of::() as u32; + + // Construct `members`. + let mut members = vec![]; + for i in 0 .. m - 1 { + let member = account::("member", i, SEED); + members.push(member); + } + let caller: T::AccountId = whitelisted_caller(); + members.push(caller.clone()); + Collective::::set_members(SystemOrigin::Root.into(), members.clone(), None, T::MaxMembers::get())?; + + // Add previous proposals + let mut last_hash = T::Hash::default(); + for i in 0 .. p { + // Proposals should be different so that different proposal hashes are generated + let proposal: T::Proposal = SystemCall::::remark { remark: id_to_remark_data(i, b as usize) }.into(); + Collective::::propose( + SystemOrigin::Signed(caller.clone()).into(), + Box::new(proposal.clone()), + bytes_in_storage, + TryInto::::try_into(3u64).ok().expect("convert u64 to block number.") + )?; + last_hash = T::Hashing::hash_of(&proposal); + } + + // Caller switches vote to nay on their own proposal, allowing them to be the deciding approval vote + Collective::::vote( + SystemOrigin::Signed(caller.clone()).into(), + last_hash, + p - 1, + false, + )?; + + // Have almost everyone vote aye on last proposal, while keeping it from failing. + for j in 2 .. m - 1 { + let voter = &members[j as usize]; + let approve = true; + Collective::::vote( + SystemOrigin::Signed(voter.clone()).into(), + last_hash, + p - 1, + approve, + )?; + } + + // Member zero is the first aye + Collective::::vote( + SystemOrigin::Signed(members[0].clone()).into(), + last_hash, + p - 1, + true, + )?; + + assert_eq!(Collective::::proposals().len(), p as usize); + + // Caller switches vote to aye, which passes the vote + let index = p - 1; + let approve = true; + Collective::::vote( + SystemOrigin::Signed(caller.clone()).into(), + last_hash, + index, approve, + )?; + + }: close(SystemOrigin::Signed(caller), last_hash, index, Weight::MAX, bytes_in_storage) + verify { + // The last proposal is removed. + assert_eq!(Collective::::proposals().len(), (p - 1) as usize); + assert_last_event::(Event::Executed { proposal_hash: last_hash, result: Err(DispatchError::BadOrigin) }.into()); + } + + close_disapproved { + // We choose 4 as a minimum so we always trigger a vote in the voting loop (`for j in ...`) + let m in 4 .. T::MaxMembers::get(); + let p in 1 .. T::MaxProposals::get(); + + let bytes = 100; + let bytes_in_storage = bytes + size_of::() as u32; + + // Construct `members`. + let mut members = vec![]; + for i in 0 .. m - 1 { + let member = account::("member", i, SEED); + members.push(member); + } + let caller: T::AccountId = whitelisted_caller(); + members.push(caller.clone()); + Collective::::set_members( + SystemOrigin::Root.into(), + members.clone(), + Some(caller.clone()), + T::MaxMembers::get(), + )?; + + // Add proposals + let mut last_hash = T::Hash::default(); + for i in 0 .. p { + // Proposals should be different so that different proposal hashes are generated + let proposal: T::Proposal = SystemCall::::remark { remark: id_to_remark_data(i, bytes as usize) }.into(); + Collective::::propose( + SystemOrigin::Signed(caller.clone()).into(), + Box::new(proposal.clone()), + bytes_in_storage, + TryInto::::try_into(3u64).ok().expect("convert u64 to block number.") + )?; + last_hash = T::Hashing::hash_of(&proposal); + } + + let index = p - 1; + // Have almost everyone vote aye on last proposal, while keeping it from passing. + // A few abstainers will be the nay votes needed to fail the vote. + let mut yes_votes: MemberCount = 0; + for j in 2 .. m / 2 { + let voter = &members[j as usize]; + let approve = true; + yes_votes += 1; + // vote aye till a prime nay vote keeps the proposal disapproved. + if <>::DefaultVote as DefaultVote>::default_vote( + Some(false), + yes_votes, + 0, + m,) { + break; + } + Collective::::vote( + SystemOrigin::Signed(voter.clone()).into(), + last_hash, + index, + approve, + )?; + } + + // caller is prime, prime votes nay + Collective::::vote( + SystemOrigin::Signed(caller.clone()).into(), + last_hash, + index, + false, + )?; + + System::::set_block_number(T::BlockNumber::max_value()); + assert_eq!(Collective::::proposals().len(), p as usize); + + // Prime nay will close it as disapproved + }: close(SystemOrigin::Signed(caller), last_hash, index, Weight::MAX, bytes_in_storage) + verify { + assert_eq!(Collective::::proposals().len(), (p - 1) as usize); + assert_last_event::(Event::Disapproved { proposal_hash: last_hash }.into()); + } + + close_approved { + let b in 2 .. MAX_BYTES; + // We choose 4 as a minimum so we always trigger a vote in the voting loop (`for j in ...`) + let m in 4 .. T::MaxMembers::get(); + let p in 1 .. T::MaxProposals::get(); + + let bytes_in_storage = b + size_of::() as u32; + + // Construct `members`. + let mut members = vec![]; + for i in 0 .. m - 1 { + let member = account::("member", i, SEED); + members.push(member); + } + let caller: T::AccountId = whitelisted_caller(); + members.push(caller.clone()); + Collective::::set_members( + SystemOrigin::Root.into(), + members.clone(), + Some(caller.clone()), + T::MaxMembers::get(), + )?; + + // Add proposals + let mut last_hash = T::Hash::default(); + for i in 0 .. p { + // Proposals should be different so that different proposal hashes are generated + let proposal: T::Proposal = SystemCall::::remark { remark: id_to_remark_data(i, b as usize) }.into(); + Collective::::propose( + SystemOrigin::Signed(caller.clone()).into(), + Box::new(proposal.clone()), + bytes_in_storage, + TryInto::::try_into(3u64).ok().expect("convert u64 to block number.") + )?; + last_hash = T::Hashing::hash_of(&proposal); + } + + // The prime member votes aye, so abstentions default to aye. + Collective::::vote( + SystemOrigin::Signed(caller.clone()).into(), + last_hash, + p - 1, + true // Vote aye. + )?; + + // Have almost everyone vote nay on last proposal, while keeping it from failing. + // A few abstainers will be the aye votes needed to pass the vote. + for j in 2 .. m / 2 { + let voter = &members[j as usize]; + let approve = false; + Collective::::vote( + SystemOrigin::Signed(voter.clone()).into(), + last_hash, + p - 1, + approve + )?; + } + + // caller is prime, prime already votes aye by creating the proposal + System::::set_block_number(T::BlockNumber::max_value()); + assert_eq!(Collective::::proposals().len(), p as usize); + + // Prime aye will close it as approved + }: close(SystemOrigin::Signed(caller), last_hash, p - 1, Weight::MAX, bytes_in_storage) + verify { + assert_eq!(Collective::::proposals().len(), (p - 1) as usize); + assert_last_event::(Event::Executed { proposal_hash: last_hash, result: Err(DispatchError::BadOrigin) }.into()); + } + + disapprove_proposal { + let p in 1 .. T::MaxProposals::get(); + + let m = 3; + let b = MAX_BYTES; + let bytes_in_storage = b + size_of::() as u32; + + // Construct `members`. + let mut members = vec![]; + for i in 0 .. m - 1 { + let member = account::("member", i, SEED); + members.push(member); + } + let caller = account::("caller", 0, SEED); + members.push(caller.clone()); + Collective::::set_members( + SystemOrigin::Root.into(), + members.clone(), + Some(caller.clone()), + T::MaxMembers::get(), + )?; + + // Threshold is one less than total members so that two nays will disapprove the vote + let threshold = m - 1; + + // Add proposals + let mut last_hash = T::Hash::default(); + for i in 0 .. p { + // Proposals should be different so that different proposal hashes are generated + let proposal: T::Proposal = SystemCall::::remark { remark: id_to_remark_data(i, b as usize) }.into(); + Collective::::propose( + SystemOrigin::Signed(caller.clone()).into(), + Box::new(proposal.clone()), + bytes_in_storage, + TryInto::::try_into(3u64).ok().expect("convert u64 to block number.") + )?; + last_hash = T::Hashing::hash_of(&proposal); + } + + System::::set_block_number(T::BlockNumber::max_value()); + assert_eq!(Collective::::proposals().len(), p as usize); + + }: _(SystemOrigin::Root, last_hash) + verify { + assert_eq!(Collective::::proposals().len(), (p - 1) as usize); + assert_last_event::(Event::Disapproved { proposal_hash: last_hash }.into()); + } + + impl_benchmark_test_suite!(Collective, crate::tests::new_test_ext(), crate::tests::Test); } diff --git a/pallets/subtensor/tests/senate.rs b/pallets/subtensor/tests/senate.rs index a992eb3b3..8d273cf1c 100644 --- a/pallets/subtensor/tests/senate.rs +++ b/pallets/subtensor/tests/senate.rs @@ -1,495 +1,765 @@ mod mock; use mock::*; -use sp_core::{H256, U256, bounded_vec}; +use frame_support::{assert_noop, assert_ok, codec::Encode}; use frame_system::{EventRecord, Phase}; -use frame_support::{assert_ok, assert_noop, codec::Encode}; +use sp_core::{bounded_vec, H256, U256}; use sp_runtime::{ - traits::{BlakeTwo256, Hash}, - BuildStorage, + traits::{BlakeTwo256, Hash}, + BuildStorage, }; use frame_system::Config; -use pallet_subtensor::{Error}; -use pallet_collective::{Event as CollectiveEvent}; +use pallet_collective::Event as CollectiveEvent; +use pallet_subtensor::Error; pub fn new_test_ext() -> sp_io::TestExternalities { - sp_tracing::try_init_simple(); - - let mut ext: sp_io::TestExternalities = GenesisConfig { - senate_members: pallet_membership::GenesisConfig:: { - members: bounded_vec![1.into(), 2.into(), 3.into(), 4.into(), 5.into()], - phantom: Default::default() - }, - triumvirate: pallet_collective::GenesisConfig:: { - members: vec![1.into()], - phantom: Default::default(), - }, - ..Default::default() - } - .build_storage() - .unwrap() - .into(); - - ext.execute_with(|| System::set_block_number(1)); - ext + sp_tracing::try_init_simple(); + + let mut ext: sp_io::TestExternalities = GenesisConfig { + senate_members: pallet_membership::GenesisConfig:: { + members: bounded_vec![1.into(), 2.into(), 3.into(), 4.into(), 5.into()], + phantom: Default::default(), + }, + triumvirate: pallet_collective::GenesisConfig:: { + members: vec![1.into()], + phantom: Default::default(), + }, + ..Default::default() + } + .build_storage() + .unwrap() + .into(); + + ext.execute_with(|| System::set_block_number(1)); + ext } fn make_proposal(value: u64) -> RuntimeCall { - RuntimeCall::System(frame_system::Call::remark_with_event { - remark: value.to_be_bytes().to_vec(), - }) + RuntimeCall::System(frame_system::Call::remark_with_event { + remark: value.to_be_bytes().to_vec(), + }) } fn record(event: RuntimeEvent) -> EventRecord { - EventRecord { phase: Phase::Initialization, event, topics: vec![] } + EventRecord { + phase: Phase::Initialization, + event, + topics: vec![], + } } #[test] fn test_senate_join_works() { - new_test_ext().execute_with( || { - let netuid: u16 = 1; - let tempo: u16 = 13; - let hotkey_account_id = U256::from(6); - let burn_cost = 1000; - let coldkey_account_id = U256::from(667); // Neighbour of the beast, har har - - //add network - SubtensorModule::set_burn( netuid, burn_cost); - add_network(netuid, tempo, 0); - // Give it some $$$ in his coldkey balance - SubtensorModule::add_balance_to_coldkey_account( &coldkey_account_id, 10000 ); - - // Subscribe and check extrinsic output - assert_ok!(SubtensorModule::burned_register(<::RuntimeOrigin>::signed(coldkey_account_id), netuid, hotkey_account_id)); - // Check if balance has decreased to pay for the burn. - assert_eq!(SubtensorModule::get_coldkey_balance(&coldkey_account_id) as u64, 10000 - burn_cost); // funds drained on reg. - // Check if neuron has added to the specified network(netuid) - assert_eq!(SubtensorModule::get_subnetwork_n(netuid), 1); - // Check if hotkey is added to the Hotkeys - assert_eq!(SubtensorModule::get_owning_coldkey_for_hotkey(&hotkey_account_id), coldkey_account_id); - - // Lets make this new key a delegate with a 50% take. - assert_ok!(SubtensorModule::do_become_delegate(<::RuntimeOrigin>::signed(coldkey_account_id), hotkey_account_id, u16::MAX/2)); - - let staker_coldkey = U256::from(7); - SubtensorModule::add_balance_to_coldkey_account(&staker_coldkey, 100_000); - - assert_ok!(SubtensorModule::add_stake(<::RuntimeOrigin>::signed(staker_coldkey), hotkey_account_id, 100_000)); - assert_eq!(SubtensorModule::get_stake_for_coldkey_and_hotkey(&staker_coldkey, &hotkey_account_id), 100_000); - assert_eq!(SubtensorModule::get_total_stake_for_hotkey(&hotkey_account_id), 100_000); - - assert_ok!(SubtensorModule::do_join_senate(<::RuntimeOrigin>::signed(coldkey_account_id), &hotkey_account_id)); - assert_eq!(Senate::is_member(&hotkey_account_id), true); - }); + new_test_ext().execute_with(|| { + let netuid: u16 = 1; + let tempo: u16 = 13; + let hotkey_account_id = U256::from(6); + let burn_cost = 1000; + let coldkey_account_id = U256::from(667); // Neighbour of the beast, har har + + //add network + SubtensorModule::set_burn(netuid, burn_cost); + add_network(netuid, tempo, 0); + // Give it some $$$ in his coldkey balance + SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, 10000); + + // Subscribe and check extrinsic output + assert_ok!(SubtensorModule::burned_register( + <::RuntimeOrigin>::signed(coldkey_account_id), + netuid, + hotkey_account_id + )); + // Check if balance has decreased to pay for the burn. + assert_eq!( + SubtensorModule::get_coldkey_balance(&coldkey_account_id) as u64, + 10000 - burn_cost + ); // funds drained on reg. + // Check if neuron has added to the specified network(netuid) + assert_eq!(SubtensorModule::get_subnetwork_n(netuid), 1); + // Check if hotkey is added to the Hotkeys + assert_eq!( + SubtensorModule::get_owning_coldkey_for_hotkey(&hotkey_account_id), + coldkey_account_id + ); + + // Lets make this new key a delegate with a 50% take. + assert_ok!(SubtensorModule::do_become_delegate( + <::RuntimeOrigin>::signed(coldkey_account_id), + hotkey_account_id, + u16::MAX / 2 + )); + + let staker_coldkey = U256::from(7); + SubtensorModule::add_balance_to_coldkey_account(&staker_coldkey, 100_000); + + assert_ok!(SubtensorModule::add_stake( + <::RuntimeOrigin>::signed(staker_coldkey), + hotkey_account_id, + 100_000 + )); + assert_eq!( + SubtensorModule::get_stake_for_coldkey_and_hotkey(&staker_coldkey, &hotkey_account_id), + 100_000 + ); + assert_eq!( + SubtensorModule::get_total_stake_for_hotkey(&hotkey_account_id), + 100_000 + ); + + assert_ok!(SubtensorModule::do_join_senate( + <::RuntimeOrigin>::signed(coldkey_account_id), + &hotkey_account_id + )); + assert_eq!(Senate::is_member(&hotkey_account_id), true); + }); } #[test] fn test_senate_join_fails_stake_req() { - new_test_ext().execute_with( || { - let netuid: u16 = 1; - let tempo: u16 = 13; - let hotkey_account_id = U256::from(6); - let burn_cost = 1000; - let coldkey_account_id = U256::from(667); // Neighbour of the beast, har har - - //add network - SubtensorModule::set_burn( netuid, burn_cost); - add_network(netuid, tempo, 0); - // Give it some $$$ in his coldkey balance - SubtensorModule::add_balance_to_coldkey_account( &coldkey_account_id, 10000 ); - - // Subscribe and check extrinsic output - assert_ok!(SubtensorModule::burned_register(<::RuntimeOrigin>::signed(coldkey_account_id), netuid, hotkey_account_id)); - // Check if balance has decreased to pay for the burn. - assert_eq!(SubtensorModule::get_coldkey_balance(&coldkey_account_id) as u64, 10000 - burn_cost); // funds drained on reg. - // Check if neuron has added to the specified network(netuid) - assert_eq!(SubtensorModule::get_subnetwork_n(netuid), 1); - // Check if hotkey is added to the Hotkeys - assert_eq!(SubtensorModule::get_owning_coldkey_for_hotkey(&hotkey_account_id), coldkey_account_id); - - // Lets make this new key a delegate with a 50% take. - assert_ok!(SubtensorModule::do_become_delegate(<::RuntimeOrigin>::signed(coldkey_account_id), hotkey_account_id, u16::MAX/2)); - - SubtensorModule::increase_total_stake(100_000); - assert_eq!(SubtensorModule::get_total_stake(), 100_000); - - assert_noop!(SubtensorModule::do_join_senate( - <::RuntimeOrigin>::signed(coldkey_account_id), - &hotkey_account_id - ), Error::::BelowStakeThreshold); - }); + new_test_ext().execute_with(|| { + let netuid: u16 = 1; + let tempo: u16 = 13; + let hotkey_account_id = U256::from(6); + let burn_cost = 1000; + let coldkey_account_id = U256::from(667); // Neighbour of the beast, har har + + //add network + SubtensorModule::set_burn(netuid, burn_cost); + add_network(netuid, tempo, 0); + // Give it some $$$ in his coldkey balance + SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, 10000); + + // Subscribe and check extrinsic output + assert_ok!(SubtensorModule::burned_register( + <::RuntimeOrigin>::signed(coldkey_account_id), + netuid, + hotkey_account_id + )); + // Check if balance has decreased to pay for the burn. + assert_eq!( + SubtensorModule::get_coldkey_balance(&coldkey_account_id) as u64, + 10000 - burn_cost + ); // funds drained on reg. + // Check if neuron has added to the specified network(netuid) + assert_eq!(SubtensorModule::get_subnetwork_n(netuid), 1); + // Check if hotkey is added to the Hotkeys + assert_eq!( + SubtensorModule::get_owning_coldkey_for_hotkey(&hotkey_account_id), + coldkey_account_id + ); + + // Lets make this new key a delegate with a 50% take. + assert_ok!(SubtensorModule::do_become_delegate( + <::RuntimeOrigin>::signed(coldkey_account_id), + hotkey_account_id, + u16::MAX / 2 + )); + + SubtensorModule::increase_total_stake(100_000); + assert_eq!(SubtensorModule::get_total_stake(), 100_000); + + assert_noop!( + SubtensorModule::do_join_senate( + <::RuntimeOrigin>::signed(coldkey_account_id), + &hotkey_account_id + ), + Error::::BelowStakeThreshold + ); + }); } #[test] fn test_senate_vote_works() { - new_test_ext().execute_with( || { - let netuid: u16 = 1; - let tempo: u16 = 13; - let senate_hotkey = U256::from(1); - let hotkey_account_id = U256::from(6); - let burn_cost = 1000; - let coldkey_account_id = U256::from(667); // Neighbour of the beast, har har - - //add network - SubtensorModule::set_burn( netuid, burn_cost); - add_network(netuid, tempo, 0); - // Give it some $$$ in his coldkey balance - SubtensorModule::add_balance_to_coldkey_account( &coldkey_account_id, 10000 ); - - // Subscribe and check extrinsic output - assert_ok!(SubtensorModule::burned_register(<::RuntimeOrigin>::signed(coldkey_account_id), netuid, hotkey_account_id)); - // Check if balance has decreased to pay for the burn. - assert_eq!(SubtensorModule::get_coldkey_balance(&coldkey_account_id) as u64, 10000 - burn_cost); // funds drained on reg. - // Check if neuron has added to the specified network(netuid) - assert_eq!(SubtensorModule::get_subnetwork_n(netuid), 1); - // Check if hotkey is added to the Hotkeys - assert_eq!(SubtensorModule::get_owning_coldkey_for_hotkey(&hotkey_account_id), coldkey_account_id); - - // Lets make this new key a delegate with a 50% take. - assert_ok!(SubtensorModule::do_become_delegate(<::RuntimeOrigin>::signed(coldkey_account_id), hotkey_account_id, u16::MAX/2)); - - let staker_coldkey = U256::from(7); - SubtensorModule::add_balance_to_coldkey_account(&staker_coldkey, 100_000); - - assert_ok!(SubtensorModule::add_stake(<::RuntimeOrigin>::signed(staker_coldkey), hotkey_account_id, 100_000)); - assert_eq!(SubtensorModule::get_stake_for_coldkey_and_hotkey(&staker_coldkey, &hotkey_account_id), 100_000); - assert_eq!(SubtensorModule::get_total_stake_for_hotkey(&hotkey_account_id), 100_000); - - assert_ok!(SubtensorModule::do_join_senate(<::RuntimeOrigin>::signed(coldkey_account_id), &hotkey_account_id)); - assert_eq!(Senate::is_member(&hotkey_account_id), true); - - System::reset_events(); - - let proposal = make_proposal(42); - let proposal_len: u32 = proposal.using_encoded(|p| p.len() as u32); - let hash = BlakeTwo256::hash_of(&proposal); - assert_ok!(Triumvirate::propose( - RuntimeOrigin::signed(senate_hotkey), - Box::new(proposal.clone()), - proposal_len, - TryInto::<::BlockNumber>::try_into(100u64).ok().expect("convert u64 to block number.") - )); - - assert_ok!(SubtensorModule::do_vote_senate(<::RuntimeOrigin>::signed(coldkey_account_id), &hotkey_account_id, hash, 0, true)); - assert_eq!( - System::events(), - vec![ - record(RuntimeEvent::Triumvirate(CollectiveEvent::Proposed { - account: senate_hotkey, - proposal_index: 0, - proposal_hash: hash, - threshold: 4 - })), - record(RuntimeEvent::Triumvirate(CollectiveEvent::Voted { - account: hotkey_account_id, - proposal_hash: hash, - voted: true, - yes: 1, - no: 0 - })) - ] - ); - }); + new_test_ext().execute_with(|| { + let netuid: u16 = 1; + let tempo: u16 = 13; + let senate_hotkey = U256::from(1); + let hotkey_account_id = U256::from(6); + let burn_cost = 1000; + let coldkey_account_id = U256::from(667); // Neighbour of the beast, har har + + //add network + SubtensorModule::set_burn(netuid, burn_cost); + add_network(netuid, tempo, 0); + // Give it some $$$ in his coldkey balance + SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, 10000); + + // Subscribe and check extrinsic output + assert_ok!(SubtensorModule::burned_register( + <::RuntimeOrigin>::signed(coldkey_account_id), + netuid, + hotkey_account_id + )); + // Check if balance has decreased to pay for the burn. + assert_eq!( + SubtensorModule::get_coldkey_balance(&coldkey_account_id) as u64, + 10000 - burn_cost + ); // funds drained on reg. + // Check if neuron has added to the specified network(netuid) + assert_eq!(SubtensorModule::get_subnetwork_n(netuid), 1); + // Check if hotkey is added to the Hotkeys + assert_eq!( + SubtensorModule::get_owning_coldkey_for_hotkey(&hotkey_account_id), + coldkey_account_id + ); + + // Lets make this new key a delegate with a 50% take. + assert_ok!(SubtensorModule::do_become_delegate( + <::RuntimeOrigin>::signed(coldkey_account_id), + hotkey_account_id, + u16::MAX / 2 + )); + + let staker_coldkey = U256::from(7); + SubtensorModule::add_balance_to_coldkey_account(&staker_coldkey, 100_000); + + assert_ok!(SubtensorModule::add_stake( + <::RuntimeOrigin>::signed(staker_coldkey), + hotkey_account_id, + 100_000 + )); + assert_eq!( + SubtensorModule::get_stake_for_coldkey_and_hotkey(&staker_coldkey, &hotkey_account_id), + 100_000 + ); + assert_eq!( + SubtensorModule::get_total_stake_for_hotkey(&hotkey_account_id), + 100_000 + ); + + assert_ok!(SubtensorModule::do_join_senate( + <::RuntimeOrigin>::signed(coldkey_account_id), + &hotkey_account_id + )); + assert_eq!(Senate::is_member(&hotkey_account_id), true); + + System::reset_events(); + + let proposal = make_proposal(42); + let proposal_len: u32 = proposal.using_encoded(|p| p.len() as u32); + let hash = BlakeTwo256::hash_of(&proposal); + assert_ok!(Triumvirate::propose( + RuntimeOrigin::signed(senate_hotkey), + Box::new(proposal.clone()), + proposal_len, + TryInto::<::BlockNumber>::try_into(100u64) + .ok() + .expect("convert u64 to block number.") + )); + + assert_ok!(SubtensorModule::do_vote_senate( + <::RuntimeOrigin>::signed(coldkey_account_id), + &hotkey_account_id, + hash, + 0, + true + )); + assert_eq!( + System::events(), + vec![ + record(RuntimeEvent::Triumvirate(CollectiveEvent::Proposed { + account: senate_hotkey, + proposal_index: 0, + proposal_hash: hash, + threshold: 4 + })), + record(RuntimeEvent::Triumvirate(CollectiveEvent::Voted { + account: hotkey_account_id, + proposal_hash: hash, + voted: true, + yes: 1, + no: 0 + })) + ] + ); + }); } #[test] fn test_senate_vote_not_member() { - new_test_ext().execute_with( || { - let netuid: u16 = 1; - let tempo: u16 = 13; - let senate_hotkey = U256::from(1); - let hotkey_account_id = U256::from(6); - let burn_cost = 1000; - let coldkey_account_id = U256::from(667); // Neighbour of the beast, har har - - //add network - SubtensorModule::set_burn( netuid, burn_cost); - add_network(netuid, tempo, 0); - // Give it some $$$ in his coldkey balance - SubtensorModule::add_balance_to_coldkey_account( &coldkey_account_id, 10000 ); - - // Subscribe and check extrinsic output - assert_ok!(SubtensorModule::burned_register(<::RuntimeOrigin>::signed(coldkey_account_id), netuid, hotkey_account_id)); - // Check if balance has decreased to pay for the burn. - assert_eq!(SubtensorModule::get_coldkey_balance(&coldkey_account_id) as u64, 10000 - burn_cost); // funds drained on reg. - // Check if neuron has added to the specified network(netuid) - assert_eq!(SubtensorModule::get_subnetwork_n(netuid), 1); - // Check if hotkey is added to the Hotkeys - assert_eq!(SubtensorModule::get_owning_coldkey_for_hotkey(&hotkey_account_id), coldkey_account_id); - - let proposal = make_proposal(42); - let proposal_len: u32 = proposal.using_encoded(|p| p.len() as u32); - let hash = BlakeTwo256::hash_of(&proposal); - assert_ok!(Triumvirate::propose( - RuntimeOrigin::signed(senate_hotkey), - Box::new(proposal.clone()), - proposal_len, - TryInto::<::BlockNumber>::try_into(100u64).ok().expect("convert u64 to block number.") - )); - - assert_noop!(SubtensorModule::do_vote_senate( - <::RuntimeOrigin>::signed(coldkey_account_id), - &hotkey_account_id, - hash, - 0, - true - ), Error::::NotSenateMember); - }); + new_test_ext().execute_with(|| { + let netuid: u16 = 1; + let tempo: u16 = 13; + let senate_hotkey = U256::from(1); + let hotkey_account_id = U256::from(6); + let burn_cost = 1000; + let coldkey_account_id = U256::from(667); // Neighbour of the beast, har har + + //add network + SubtensorModule::set_burn(netuid, burn_cost); + add_network(netuid, tempo, 0); + // Give it some $$$ in his coldkey balance + SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, 10000); + + // Subscribe and check extrinsic output + assert_ok!(SubtensorModule::burned_register( + <::RuntimeOrigin>::signed(coldkey_account_id), + netuid, + hotkey_account_id + )); + // Check if balance has decreased to pay for the burn. + assert_eq!( + SubtensorModule::get_coldkey_balance(&coldkey_account_id) as u64, + 10000 - burn_cost + ); // funds drained on reg. + // Check if neuron has added to the specified network(netuid) + assert_eq!(SubtensorModule::get_subnetwork_n(netuid), 1); + // Check if hotkey is added to the Hotkeys + assert_eq!( + SubtensorModule::get_owning_coldkey_for_hotkey(&hotkey_account_id), + coldkey_account_id + ); + + let proposal = make_proposal(42); + let proposal_len: u32 = proposal.using_encoded(|p| p.len() as u32); + let hash = BlakeTwo256::hash_of(&proposal); + assert_ok!(Triumvirate::propose( + RuntimeOrigin::signed(senate_hotkey), + Box::new(proposal.clone()), + proposal_len, + TryInto::<::BlockNumber>::try_into(100u64) + .ok() + .expect("convert u64 to block number.") + )); + + assert_noop!( + SubtensorModule::do_vote_senate( + <::RuntimeOrigin>::signed(coldkey_account_id), + &hotkey_account_id, + hash, + 0, + true + ), + Error::::NotSenateMember + ); + }); } #[test] fn test_senate_leave_works() { - new_test_ext().execute_with( || { - let netuid: u16 = 1; - let tempo: u16 = 13; - let hotkey_account_id = U256::from(6); - let burn_cost = 1000; - let coldkey_account_id = U256::from(667); // Neighbour of the beast, har har - - //add network - SubtensorModule::set_burn( netuid, burn_cost); - add_network(netuid, tempo, 0); - // Give it some $$$ in his coldkey balance - SubtensorModule::add_balance_to_coldkey_account( &coldkey_account_id, 10000 ); - - // Subscribe and check extrinsic output - assert_ok!(SubtensorModule::burned_register(<::RuntimeOrigin>::signed(coldkey_account_id), netuid, hotkey_account_id)); - // Check if balance has decreased to pay for the burn. - assert_eq!(SubtensorModule::get_coldkey_balance(&coldkey_account_id) as u64, 10000 - burn_cost); // funds drained on reg. - // Check if neuron has added to the specified network(netuid) - assert_eq!(SubtensorModule::get_subnetwork_n(netuid), 1); - // Check if hotkey is added to the Hotkeys - assert_eq!(SubtensorModule::get_owning_coldkey_for_hotkey(&hotkey_account_id), coldkey_account_id); - - // Lets make this new key a delegate with a 50% take. - assert_ok!(SubtensorModule::do_become_delegate(<::RuntimeOrigin>::signed(coldkey_account_id), hotkey_account_id, u16::MAX/2)); - - let staker_coldkey = U256::from(7); - SubtensorModule::add_balance_to_coldkey_account(&staker_coldkey, 100_000); - - assert_ok!(SubtensorModule::add_stake(<::RuntimeOrigin>::signed(staker_coldkey), hotkey_account_id, 100_000)); - assert_eq!(SubtensorModule::get_stake_for_coldkey_and_hotkey(&staker_coldkey, &hotkey_account_id), 100_000); - assert_eq!(SubtensorModule::get_total_stake_for_hotkey(&hotkey_account_id), 100_000); - - assert_ok!(SubtensorModule::do_join_senate(<::RuntimeOrigin>::signed(coldkey_account_id), &hotkey_account_id)); - assert_eq!(Senate::is_member(&hotkey_account_id), true); - - assert_ok!(SubtensorModule::do_leave_senate(<::RuntimeOrigin>::signed(coldkey_account_id), &hotkey_account_id)); - assert_eq!(Senate::is_member(&hotkey_account_id), false); - }); + new_test_ext().execute_with(|| { + let netuid: u16 = 1; + let tempo: u16 = 13; + let hotkey_account_id = U256::from(6); + let burn_cost = 1000; + let coldkey_account_id = U256::from(667); // Neighbour of the beast, har har + + //add network + SubtensorModule::set_burn(netuid, burn_cost); + add_network(netuid, tempo, 0); + // Give it some $$$ in his coldkey balance + SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, 10000); + + // Subscribe and check extrinsic output + assert_ok!(SubtensorModule::burned_register( + <::RuntimeOrigin>::signed(coldkey_account_id), + netuid, + hotkey_account_id + )); + // Check if balance has decreased to pay for the burn. + assert_eq!( + SubtensorModule::get_coldkey_balance(&coldkey_account_id) as u64, + 10000 - burn_cost + ); // funds drained on reg. + // Check if neuron has added to the specified network(netuid) + assert_eq!(SubtensorModule::get_subnetwork_n(netuid), 1); + // Check if hotkey is added to the Hotkeys + assert_eq!( + SubtensorModule::get_owning_coldkey_for_hotkey(&hotkey_account_id), + coldkey_account_id + ); + + // Lets make this new key a delegate with a 50% take. + assert_ok!(SubtensorModule::do_become_delegate( + <::RuntimeOrigin>::signed(coldkey_account_id), + hotkey_account_id, + u16::MAX / 2 + )); + + let staker_coldkey = U256::from(7); + SubtensorModule::add_balance_to_coldkey_account(&staker_coldkey, 100_000); + + assert_ok!(SubtensorModule::add_stake( + <::RuntimeOrigin>::signed(staker_coldkey), + hotkey_account_id, + 100_000 + )); + assert_eq!( + SubtensorModule::get_stake_for_coldkey_and_hotkey(&staker_coldkey, &hotkey_account_id), + 100_000 + ); + assert_eq!( + SubtensorModule::get_total_stake_for_hotkey(&hotkey_account_id), + 100_000 + ); + + assert_ok!(SubtensorModule::do_join_senate( + <::RuntimeOrigin>::signed(coldkey_account_id), + &hotkey_account_id + )); + assert_eq!(Senate::is_member(&hotkey_account_id), true); + + assert_ok!(SubtensorModule::do_leave_senate( + <::RuntimeOrigin>::signed(coldkey_account_id), + &hotkey_account_id + )); + assert_eq!(Senate::is_member(&hotkey_account_id), false); + }); } #[test] fn test_senate_leave_not_member() { - new_test_ext().execute_with( || { - let netuid: u16 = 1; - let tempo: u16 = 13; - let hotkey_account_id = U256::from(6); - let burn_cost = 1000; - let coldkey_account_id = U256::from(667); // Neighbour of the beast, har har - - //add network - SubtensorModule::set_burn( netuid, burn_cost); - add_network(netuid, tempo, 0); - // Give it some $$$ in his coldkey balance - SubtensorModule::add_balance_to_coldkey_account( &coldkey_account_id, 10000 ); - - // Subscribe and check extrinsic output - assert_ok!(SubtensorModule::burned_register(<::RuntimeOrigin>::signed(coldkey_account_id), netuid, hotkey_account_id)); - // Check if balance has decreased to pay for the burn. - assert_eq!(SubtensorModule::get_coldkey_balance(&coldkey_account_id) as u64, 10000 - burn_cost); // funds drained on reg. - // Check if neuron has added to the specified network(netuid) - assert_eq!(SubtensorModule::get_subnetwork_n(netuid), 1); - // Check if hotkey is added to the Hotkeys - assert_eq!(SubtensorModule::get_owning_coldkey_for_hotkey(&hotkey_account_id), coldkey_account_id); - - assert_noop!(SubtensorModule::do_leave_senate( - <::RuntimeOrigin>::signed(coldkey_account_id), - &hotkey_account_id - ), Error::::NotSenateMember); - }); + new_test_ext().execute_with(|| { + let netuid: u16 = 1; + let tempo: u16 = 13; + let hotkey_account_id = U256::from(6); + let burn_cost = 1000; + let coldkey_account_id = U256::from(667); // Neighbour of the beast, har har + + //add network + SubtensorModule::set_burn(netuid, burn_cost); + add_network(netuid, tempo, 0); + // Give it some $$$ in his coldkey balance + SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, 10000); + + // Subscribe and check extrinsic output + assert_ok!(SubtensorModule::burned_register( + <::RuntimeOrigin>::signed(coldkey_account_id), + netuid, + hotkey_account_id + )); + // Check if balance has decreased to pay for the burn. + assert_eq!( + SubtensorModule::get_coldkey_balance(&coldkey_account_id) as u64, + 10000 - burn_cost + ); // funds drained on reg. + // Check if neuron has added to the specified network(netuid) + assert_eq!(SubtensorModule::get_subnetwork_n(netuid), 1); + // Check if hotkey is added to the Hotkeys + assert_eq!( + SubtensorModule::get_owning_coldkey_for_hotkey(&hotkey_account_id), + coldkey_account_id + ); + + assert_noop!( + SubtensorModule::do_leave_senate( + <::RuntimeOrigin>::signed(coldkey_account_id), + &hotkey_account_id + ), + Error::::NotSenateMember + ); + }); } #[test] fn test_senate_leave_vote_removal() { - new_test_ext().execute_with( || { - let netuid: u16 = 1; - let tempo: u16 = 13; - let senate_hotkey = U256::from(1); - let hotkey_account_id = U256::from(6); - let burn_cost = 1000; - let coldkey_account_id = U256::from(667); // Neighbour of the beast, har har - let coldkey_origin = <::RuntimeOrigin>::signed(coldkey_account_id); - - //add network - SubtensorModule::set_burn( netuid, burn_cost); - add_network(netuid, tempo, 0); - // Give it some $$$ in his coldkey balance - SubtensorModule::add_balance_to_coldkey_account( &coldkey_account_id, 10000 ); - - // Subscribe and check extrinsic output - assert_ok!(SubtensorModule::burned_register(coldkey_origin.clone(), netuid, hotkey_account_id)); - // Check if balance has decreased to pay for the burn. - assert_eq!(SubtensorModule::get_coldkey_balance(&coldkey_account_id) as u64, 10000 - burn_cost); // funds drained on reg. - // Check if neuron has added to the specified network(netuid) - assert_eq!(SubtensorModule::get_subnetwork_n(netuid), 1); - // Check if hotkey is added to the Hotkeys - assert_eq!(SubtensorModule::get_owning_coldkey_for_hotkey(&hotkey_account_id), coldkey_account_id); - - // Lets make this new key a delegate with a 50% take. - assert_ok!(SubtensorModule::do_become_delegate(coldkey_origin.clone(), hotkey_account_id, u16::MAX/2)); - - let staker_coldkey = U256::from(7); - SubtensorModule::add_balance_to_coldkey_account(&staker_coldkey, 100_000); - - assert_ok!(SubtensorModule::add_stake(<::RuntimeOrigin>::signed(staker_coldkey), hotkey_account_id, 100_000)); - assert_eq!(SubtensorModule::get_stake_for_coldkey_and_hotkey(&staker_coldkey, &hotkey_account_id), 100_000); - assert_eq!(SubtensorModule::get_total_stake_for_hotkey(&hotkey_account_id), 100_000); - - assert_ok!(SubtensorModule::do_join_senate(coldkey_origin.clone(), &hotkey_account_id)); - assert_eq!(Senate::is_member(&hotkey_account_id), true); - - let proposal = make_proposal(42); - let proposal_len: u32 = proposal.using_encoded(|p| p.len() as u32); - let hash = BlakeTwo256::hash_of(&proposal); - assert_ok!(Triumvirate::propose( - RuntimeOrigin::signed(senate_hotkey), - Box::new(proposal.clone()), - proposal_len, - TryInto::<::BlockNumber>::try_into(100u64).ok().expect("convert u64 to block number.") - )); - - assert_ok!(SubtensorModule::do_vote_senate(coldkey_origin.clone(), &hotkey_account_id, hash, 0, true)); - assert_ok!(SubtensorModule::do_leave_senate(coldkey_origin, &hotkey_account_id)); - - assert_eq!(Triumvirate::has_voted(hash, 0, &hotkey_account_id), Ok(false)); - }); + new_test_ext().execute_with(|| { + let netuid: u16 = 1; + let tempo: u16 = 13; + let senate_hotkey = U256::from(1); + let hotkey_account_id = U256::from(6); + let burn_cost = 1000; + let coldkey_account_id = U256::from(667); // Neighbour of the beast, har har + let coldkey_origin = <::RuntimeOrigin>::signed(coldkey_account_id); + + //add network + SubtensorModule::set_burn(netuid, burn_cost); + add_network(netuid, tempo, 0); + // Give it some $$$ in his coldkey balance + SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, 10000); + + // Subscribe and check extrinsic output + assert_ok!(SubtensorModule::burned_register( + coldkey_origin.clone(), + netuid, + hotkey_account_id + )); + // Check if balance has decreased to pay for the burn. + assert_eq!( + SubtensorModule::get_coldkey_balance(&coldkey_account_id) as u64, + 10000 - burn_cost + ); // funds drained on reg. + // Check if neuron has added to the specified network(netuid) + assert_eq!(SubtensorModule::get_subnetwork_n(netuid), 1); + // Check if hotkey is added to the Hotkeys + assert_eq!( + SubtensorModule::get_owning_coldkey_for_hotkey(&hotkey_account_id), + coldkey_account_id + ); + + // Lets make this new key a delegate with a 50% take. + assert_ok!(SubtensorModule::do_become_delegate( + coldkey_origin.clone(), + hotkey_account_id, + u16::MAX / 2 + )); + + let staker_coldkey = U256::from(7); + SubtensorModule::add_balance_to_coldkey_account(&staker_coldkey, 100_000); + + assert_ok!(SubtensorModule::add_stake( + <::RuntimeOrigin>::signed(staker_coldkey), + hotkey_account_id, + 100_000 + )); + assert_eq!( + SubtensorModule::get_stake_for_coldkey_and_hotkey(&staker_coldkey, &hotkey_account_id), + 100_000 + ); + assert_eq!( + SubtensorModule::get_total_stake_for_hotkey(&hotkey_account_id), + 100_000 + ); + + assert_ok!(SubtensorModule::do_join_senate( + coldkey_origin.clone(), + &hotkey_account_id + )); + assert_eq!(Senate::is_member(&hotkey_account_id), true); + + let proposal = make_proposal(42); + let proposal_len: u32 = proposal.using_encoded(|p| p.len() as u32); + let hash = BlakeTwo256::hash_of(&proposal); + assert_ok!(Triumvirate::propose( + RuntimeOrigin::signed(senate_hotkey), + Box::new(proposal.clone()), + proposal_len, + TryInto::<::BlockNumber>::try_into(100u64) + .ok() + .expect("convert u64 to block number.") + )); + + assert_ok!(SubtensorModule::do_vote_senate( + coldkey_origin.clone(), + &hotkey_account_id, + hash, + 0, + true + )); + assert_ok!(SubtensorModule::do_leave_senate( + coldkey_origin, + &hotkey_account_id + )); + + assert_eq!( + Triumvirate::has_voted(hash, 0, &hotkey_account_id), + Ok(false) + ); + }); } #[test] fn test_senate_leave_when_stake_removed() { - new_test_ext().execute_with( || { - let netuid: u16 = 1; - let tempo: u16 = 13; - let hotkey_account_id = U256::from(6); - let burn_cost = 1000; - let coldkey_account_id = U256::from(667); // Neighbour of the beast, har har - - //add network - SubtensorModule::set_burn( netuid, burn_cost); - add_network(netuid, tempo, 0); - // Give it some $$$ in his coldkey balance - SubtensorModule::add_balance_to_coldkey_account( &coldkey_account_id, 10000 ); - - // Subscribe and check extrinsic output - assert_ok!(SubtensorModule::burned_register(<::RuntimeOrigin>::signed(coldkey_account_id), netuid, hotkey_account_id)); - // Check if balance has decreased to pay for the burn. - assert_eq!(SubtensorModule::get_coldkey_balance(&coldkey_account_id) as u64, 10000 - burn_cost); // funds drained on reg. - // Check if neuron has added to the specified network(netuid) - assert_eq!(SubtensorModule::get_subnetwork_n(netuid), 1); - // Check if hotkey is added to the Hotkeys - assert_eq!(SubtensorModule::get_owning_coldkey_for_hotkey(&hotkey_account_id), coldkey_account_id); - - // Lets make this new key a delegate with a 50% take. - assert_ok!(SubtensorModule::do_become_delegate(<::RuntimeOrigin>::signed(coldkey_account_id), hotkey_account_id, u16::MAX/2)); - - let staker_coldkey = U256::from(7); - let stake_amount: u64 = 100_000; - SubtensorModule::add_balance_to_coldkey_account(&staker_coldkey, stake_amount); - - assert_ok!(SubtensorModule::add_stake(<::RuntimeOrigin>::signed(staker_coldkey), hotkey_account_id, stake_amount)); - assert_eq!(SubtensorModule::get_stake_for_coldkey_and_hotkey(&staker_coldkey, &hotkey_account_id), stake_amount); - assert_eq!(SubtensorModule::get_total_stake_for_hotkey(&hotkey_account_id), stake_amount); - - assert_ok!(SubtensorModule::do_join_senate(<::RuntimeOrigin>::signed(coldkey_account_id), &hotkey_account_id)); - assert_eq!(Senate::is_member(&hotkey_account_id), true); - - step_block(100); - - assert_ok!(SubtensorModule::remove_stake(<::RuntimeOrigin>::signed(staker_coldkey), hotkey_account_id, stake_amount)); - assert_eq!(Senate::is_member(&hotkey_account_id), false); - }); + new_test_ext().execute_with(|| { + let netuid: u16 = 1; + let tempo: u16 = 13; + let hotkey_account_id = U256::from(6); + let burn_cost = 1000; + let coldkey_account_id = U256::from(667); // Neighbour of the beast, har har + + //add network + SubtensorModule::set_burn(netuid, burn_cost); + add_network(netuid, tempo, 0); + // Give it some $$$ in his coldkey balance + SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, 10000); + + // Subscribe and check extrinsic output + assert_ok!(SubtensorModule::burned_register( + <::RuntimeOrigin>::signed(coldkey_account_id), + netuid, + hotkey_account_id + )); + // Check if balance has decreased to pay for the burn. + assert_eq!( + SubtensorModule::get_coldkey_balance(&coldkey_account_id) as u64, + 10000 - burn_cost + ); // funds drained on reg. + // Check if neuron has added to the specified network(netuid) + assert_eq!(SubtensorModule::get_subnetwork_n(netuid), 1); + // Check if hotkey is added to the Hotkeys + assert_eq!( + SubtensorModule::get_owning_coldkey_for_hotkey(&hotkey_account_id), + coldkey_account_id + ); + + // Lets make this new key a delegate with a 50% take. + assert_ok!(SubtensorModule::do_become_delegate( + <::RuntimeOrigin>::signed(coldkey_account_id), + hotkey_account_id, + u16::MAX / 2 + )); + + let staker_coldkey = U256::from(7); + let stake_amount: u64 = 100_000; + SubtensorModule::add_balance_to_coldkey_account(&staker_coldkey, stake_amount); + + assert_ok!(SubtensorModule::add_stake( + <::RuntimeOrigin>::signed(staker_coldkey), + hotkey_account_id, + stake_amount + )); + assert_eq!( + SubtensorModule::get_stake_for_coldkey_and_hotkey(&staker_coldkey, &hotkey_account_id), + stake_amount + ); + assert_eq!( + SubtensorModule::get_total_stake_for_hotkey(&hotkey_account_id), + stake_amount + ); + + assert_ok!(SubtensorModule::do_join_senate( + <::RuntimeOrigin>::signed(coldkey_account_id), + &hotkey_account_id + )); + assert_eq!(Senate::is_member(&hotkey_account_id), true); + + step_block(100); + + assert_ok!(SubtensorModule::remove_stake( + <::RuntimeOrigin>::signed(staker_coldkey), + hotkey_account_id, + stake_amount + )); + assert_eq!(Senate::is_member(&hotkey_account_id), false); + }); } #[test] fn test_senate_replace_lowest_member() { - new_test_ext().execute_with( || { - let netuid: u16 = 1; - let tempo: u16 = 13; - let burn_cost = 1000; - - //add network - add_network(netuid, tempo, 0); - SubtensorModule::set_max_allowed_uids(netuid, 4096); - SubtensorModule::set_burn( netuid, burn_cost ); - SubtensorModule::set_max_registrations_per_block(netuid, 100); - - for i in 1..11u64 { - let coldkey_account_id = U256::from(100 + i); - let coldkey_origin = <::RuntimeOrigin>::signed(coldkey_account_id); - - let hotkey_account_id = U256::from(5 + i); - - // Give it some $$$ in his coldkey balance - SubtensorModule::add_balance_to_coldkey_account( &coldkey_account_id, 10000 ); - - // Subscribe and check extrinsic output - assert_ok!(SubtensorModule::burned_register(coldkey_origin.clone(), netuid, hotkey_account_id)); - // Check if balance has decreased to pay for the burn. - assert_eq!(SubtensorModule::get_coldkey_balance(&coldkey_account_id) as u64, 10000 - burn_cost); // funds drained on reg. - // Check if neuron has added to the specified network(netuid) - assert_eq!(u64::from(SubtensorModule::get_subnetwork_n(netuid)), i); - // Check if hotkey is added to the Hotkeys - assert_eq!(SubtensorModule::get_owning_coldkey_for_hotkey(&hotkey_account_id), coldkey_account_id); - - // Lets make this new key a delegate with a 50% take. - assert_ok!(SubtensorModule::do_become_delegate(coldkey_origin.clone(), hotkey_account_id, u16::MAX/2)); - - let staker_coldkey = U256::from(200 + i); - let staked_amount = 100_000 * i; - SubtensorModule::add_balance_to_coldkey_account(&staker_coldkey, staked_amount); - - assert_ok!(SubtensorModule::add_stake(<::RuntimeOrigin>::signed(staker_coldkey), hotkey_account_id, staked_amount)); - assert_eq!(SubtensorModule::get_stake_for_coldkey_and_hotkey(&staker_coldkey, &hotkey_account_id), staked_amount); - assert_eq!(SubtensorModule::get_total_stake_for_hotkey(&hotkey_account_id), staked_amount); - - assert_ok!(SubtensorModule::do_join_senate(coldkey_origin, &hotkey_account_id)); - assert_eq!(Senate::is_member(&hotkey_account_id), true); - - SubtensorModule::set_burn( netuid, burn_cost ); - step_block(100); - } - - let hotkey_account_id = U256::from(16); - let coldkey_account_id = U256::from(667); // Neighbour of the beast, har har - let coldkey_origin = <::RuntimeOrigin>::signed(coldkey_account_id); - - // Give it some $$$ in his coldkey balance - SubtensorModule::add_balance_to_coldkey_account( &coldkey_account_id, 10000 ); - - // Subscribe and check extrinsic output - assert_ok!(SubtensorModule::burned_register(coldkey_origin.clone(), netuid, hotkey_account_id)); - // Check if balance has decreased to pay for the burn. - assert_eq!(SubtensorModule::get_coldkey_balance(&coldkey_account_id) as u64, 10000 - burn_cost); // funds drained on reg. - // Check if hotkey is added to the Hotkeys - assert_eq!(SubtensorModule::get_owning_coldkey_for_hotkey(&hotkey_account_id), coldkey_account_id); - - // Lets make this new key a delegate with a 50% take. - assert_ok!(SubtensorModule::do_become_delegate(coldkey_origin.clone(), hotkey_account_id, u16::MAX/2)); - - let staker_coldkey = U256::from(1000); - let stake_amount = 1_000_001; - SubtensorModule::add_balance_to_coldkey_account(&staker_coldkey, stake_amount); - - assert_ok!(SubtensorModule::add_stake(<::RuntimeOrigin>::signed(staker_coldkey), hotkey_account_id, stake_amount)); - assert_eq!(SubtensorModule::get_stake_for_coldkey_and_hotkey(&staker_coldkey, &hotkey_account_id), stake_amount); - assert_eq!(SubtensorModule::get_total_stake_for_hotkey(&hotkey_account_id), stake_amount); - - assert_ok!(SubtensorModule::do_join_senate(coldkey_origin.clone(), &hotkey_account_id)); - assert_eq!(Senate::is_member(&hotkey_account_id), true); - - // Lowest stake amount should get kicked out - assert_eq!(Senate::is_member(&U256::from(6)), false); - }); + new_test_ext().execute_with(|| { + let netuid: u16 = 1; + let tempo: u16 = 13; + let burn_cost = 1000; + + //add network + add_network(netuid, tempo, 0); + SubtensorModule::set_max_allowed_uids(netuid, 4096); + SubtensorModule::set_burn(netuid, burn_cost); + SubtensorModule::set_max_registrations_per_block(netuid, 100); + + for i in 1..11u64 { + let coldkey_account_id = U256::from(100 + i); + let coldkey_origin = <::RuntimeOrigin>::signed(coldkey_account_id); + + let hotkey_account_id = U256::from(5 + i); + + // Give it some $$$ in his coldkey balance + SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, 10000); + + // Subscribe and check extrinsic output + assert_ok!(SubtensorModule::burned_register( + coldkey_origin.clone(), + netuid, + hotkey_account_id + )); + // Check if balance has decreased to pay for the burn. + assert_eq!( + SubtensorModule::get_coldkey_balance(&coldkey_account_id) as u64, + 10000 - burn_cost + ); // funds drained on reg. + // Check if neuron has added to the specified network(netuid) + assert_eq!(u64::from(SubtensorModule::get_subnetwork_n(netuid)), i); + // Check if hotkey is added to the Hotkeys + assert_eq!( + SubtensorModule::get_owning_coldkey_for_hotkey(&hotkey_account_id), + coldkey_account_id + ); + + // Lets make this new key a delegate with a 50% take. + assert_ok!(SubtensorModule::do_become_delegate( + coldkey_origin.clone(), + hotkey_account_id, + u16::MAX / 2 + )); + + let staker_coldkey = U256::from(200 + i); + let staked_amount = 100_000 * i; + SubtensorModule::add_balance_to_coldkey_account(&staker_coldkey, staked_amount); + + assert_ok!(SubtensorModule::add_stake( + <::RuntimeOrigin>::signed(staker_coldkey), + hotkey_account_id, + staked_amount + )); + assert_eq!( + SubtensorModule::get_stake_for_coldkey_and_hotkey( + &staker_coldkey, + &hotkey_account_id + ), + staked_amount + ); + assert_eq!( + SubtensorModule::get_total_stake_for_hotkey(&hotkey_account_id), + staked_amount + ); + + assert_ok!(SubtensorModule::do_join_senate( + coldkey_origin, + &hotkey_account_id + )); + assert_eq!(Senate::is_member(&hotkey_account_id), true); + + SubtensorModule::set_burn(netuid, burn_cost); + step_block(100); + } + + let hotkey_account_id = U256::from(16); + let coldkey_account_id = U256::from(667); // Neighbour of the beast, har har + let coldkey_origin = <::RuntimeOrigin>::signed(coldkey_account_id); + + // Give it some $$$ in his coldkey balance + SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, 10000); + + // Subscribe and check extrinsic output + assert_ok!(SubtensorModule::burned_register( + coldkey_origin.clone(), + netuid, + hotkey_account_id + )); + // Check if balance has decreased to pay for the burn. + assert_eq!( + SubtensorModule::get_coldkey_balance(&coldkey_account_id) as u64, + 10000 - burn_cost + ); // funds drained on reg. + // Check if hotkey is added to the Hotkeys + assert_eq!( + SubtensorModule::get_owning_coldkey_for_hotkey(&hotkey_account_id), + coldkey_account_id + ); + + // Lets make this new key a delegate with a 50% take. + assert_ok!(SubtensorModule::do_become_delegate( + coldkey_origin.clone(), + hotkey_account_id, + u16::MAX / 2 + )); + + let staker_coldkey = U256::from(1000); + let stake_amount = 1_000_001; + SubtensorModule::add_balance_to_coldkey_account(&staker_coldkey, stake_amount); + + assert_ok!(SubtensorModule::add_stake( + <::RuntimeOrigin>::signed(staker_coldkey), + hotkey_account_id, + stake_amount + )); + assert_eq!( + SubtensorModule::get_stake_for_coldkey_and_hotkey(&staker_coldkey, &hotkey_account_id), + stake_amount + ); + assert_eq!( + SubtensorModule::get_total_stake_for_hotkey(&hotkey_account_id), + stake_amount + ); + + assert_ok!(SubtensorModule::do_join_senate( + coldkey_origin.clone(), + &hotkey_account_id + )); + assert_eq!(Senate::is_member(&hotkey_account_id), true); + + // Lowest stake amount should get kicked out + assert_eq!(Senate::is_member(&U256::from(6)), false); + }); }