diff --git a/.github/workflows/rustdocs.yml b/.github/workflows/rustdocs.yml new file mode 100644 index 0000000000..a58a3a8c2a --- /dev/null +++ b/.github/workflows/rustdocs.yml @@ -0,0 +1,60 @@ +name: Publish rustdocs + +on: + push: + branches: + - main + workflow_dispatch: + +env: + CARGO_TERM_COLOR: always + +jobs: + build: + runs-on: SubtensorCI + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Install rustup + uses: actions-rs/toolchain@v1 + with: + toolchain: stable + + - name: Generate documentation + uses: actions-rs/cargo@v1 + with: + command: doc + args: --document-private-items + + - name: Fix file permissions + shell: sh + run: | + chmod -c -R +rX "target/doc" | + while read line; do + echo "::warning title=Invalid file permissions automatically fixed::$line" + done + - name: Generate index.html file + run: | + echo "" > target/doc/index.html + - name: Upload documentation + uses: actions/upload-pages-artifact@v1 + with: + path: ./target/doc + + deploy: + needs: build + runs-on: SubtensorCI + + permissions: + pages: write + id-token: write + environment: + name: github-pages + url: ${{ steps.pages.outputs.page_url }} + + steps: + - name: Deploy documentation + id: pages + uses: actions/deploy-pages@v2 diff --git a/pallets/commitments/src/lib.rs b/pallets/commitments/src/lib.rs index d0d8d14c9b..5b1ff7f3a8 100644 --- a/pallets/commitments/src/lib.rs +++ b/pallets/commitments/src/lib.rs @@ -47,7 +47,7 @@ pub mod pallet { /// Because this pallet emits events, it depends on the runtime's definition of an event. type RuntimeEvent: From> + IsType<::RuntimeEvent>; - /// Currency type that will be used to place deposits on neurons + ///Currency type that will be used to reserve deposits for commitments type Currency: ReservableCurrency + Send + Sync; /// Weight information for extrinsics in this pallet. @@ -71,11 +71,11 @@ pub mod pallet { #[pallet::constant] type FieldDeposit: Get>; - /// Used to retreive the given subnet's tempo + /// Used to retrieve the given subnet's tempo type TempoInterface: GetTempoInterface; } - /// Used to retreive the given subnet's tempo + /// Used to retrieve the given subnet's tempo pub trait GetTempoInterface { /// Used to retreive the epoch index for the given subnet. fn get_epoch_index(netuid: u16, cur_block: u64) -> u64; @@ -113,7 +113,7 @@ pub mod pallet { pub enum Error { /// Account passed too many additional fields to their commitment TooManyFieldsInCommitmentInfo, - /// Account is not allow to make commitments to the chain + /// Account is not allowed to make commitments to the chain AccountNotAllowedCommit, /// Space Limit Exceeded for the current interval SpaceLimitExceeded, diff --git a/pallets/commitments/src/tests.rs b/pallets/commitments/src/tests.rs index 55e406eb53..62e9444b76 100644 --- a/pallets/commitments/src/tests.rs +++ b/pallets/commitments/src/tests.rs @@ -3,8 +3,8 @@ use sp_std::prelude::*; #[cfg(test)] use crate::{ - CommitmentInfo, CommitmentOf, Config, Data, Error, Event, MaxSpace, Pallet, Registration, - RevealedCommitments, TimelockedIndex, UsedSpaceOf, + BalanceOf, CommitmentInfo, CommitmentOf, Config, Data, Error, Event, MaxSpace, Pallet, + Registration, RevealedCommitments, TimelockedIndex, UsedSpaceOf, mock::{ Balances, DRAND_QUICKNET_SIG_2000_HEX, DRAND_QUICKNET_SIG_HEX, RuntimeEvent, RuntimeOrigin, Test, TestMaxFields, insert_drand_pulse, new_test_ext, produce_ciphertext, @@ -35,6 +35,7 @@ fn manual_data_type_info() { Data::Raw(bytes) => format!("Raw{}", bytes.len()), Data::TimelockEncrypted { .. } => "TimelockEncrypted".to_string(), Data::ResetBondsFlag => "ResetBondsFlag".to_string(), + Data::BigRaw(_) => "BigRaw".to_string(), }; if let scale_info::TypeDef::Variant(variant) = &type_info.type_def { let variant = variant @@ -51,6 +52,7 @@ fn manual_data_type_info() { let expected_len = match data { Data::None => 0, Data::Raw(bytes) => bytes.len() as u32, + Data::BigRaw(bytes) => bytes.len() as u32, Data::BlakeTwo256(_) | Data::Sha256(_) | Data::Keccak256(_) @@ -1745,3 +1747,441 @@ fn usage_respects_minimum_of_100_bytes() { ); }); } + +#[test] +fn set_commitment_works_with_multiple_raw_fields() { + new_test_ext().execute_with(|| { + let cur_block = 10u64.into(); + System::::set_block_number(cur_block); + let initial_deposit: BalanceOf = ::InitialDeposit::get(); + let field_deposit: BalanceOf = ::FieldDeposit::get(); + + let field1 = Data::Raw(vec![0u8; 10].try_into().expect("<=128 bytes is OK")); + let field2 = Data::Raw(vec![1u8; 20].try_into().expect("<=128 bytes is OK")); + let field3 = Data::Raw(vec![2u8; 50].try_into().expect("<=128 bytes is OK")); + + let info_multiple = CommitmentInfo { + fields: BoundedVec::try_from(vec![field1.clone(), field2.clone(), field3.clone()]) + .expect("<= MaxFields"), + }; + + assert_ok!(Pallet::::set_commitment( + RuntimeOrigin::signed(12345), + 99, + Box::new(info_multiple) + )); + + let expected_deposit: BalanceOf = initial_deposit + 3u64 * field_deposit; + let stored = CommitmentOf::::get(99, 12345).expect("Should be stored"); + assert_eq!( + stored.deposit, expected_deposit, + "Deposit must equal initial + 3 * field_deposit" + ); + + assert_eq!(stored.block, cur_block, "Stored block must match cur_block"); + + let usage = UsedSpaceOf::::get(99, 12345).expect("Expected to not panic"); + assert_eq!( + usage.used_space, 100, + "Usage is clamped to 100 when sum of fields is < 100" + ); + + let next_block = 11u64.into(); + System::::set_block_number(next_block); + + let info_two_fields = CommitmentInfo { + fields: BoundedVec::try_from(vec![field1.clone(), field2.clone()]) + .expect("<= MaxFields"), + }; + + assert_ok!(Pallet::::set_commitment( + RuntimeOrigin::signed(12345), + 99, + Box::new(info_two_fields) + )); + + let expected_deposit2: BalanceOf = initial_deposit + 2u64 * field_deposit; + let stored2 = CommitmentOf::::get(99, 12345).expect("Should be stored"); + assert_eq!( + stored2.deposit, expected_deposit2, + "Deposit must have decreased after removing one field" + ); + + let usage2 = UsedSpaceOf::::get(99, 12345).expect("Expected to not panic"); + let expected_usage2 = 200u64; + assert_eq!( + usage2.used_space, expected_usage2, + "Usage accumulates in the same epoch, respecting the min usage of 100 each time" + ); + + let events = System::::events(); + let found_commitment_event = events.iter().any(|e| { + matches!( + e.event, + RuntimeEvent::Commitments(Event::Commitment { + netuid: 99, + who: 12345 + }) + ) + }); + assert!( + found_commitment_event, + "Expected at least one Event::Commitment to be emitted" + ); + }); +} + +#[allow(clippy::indexing_slicing)] +#[test] +fn multiple_timelocked_commitments_reveal_works() { + new_test_ext().execute_with(|| { + // ------------------------------------------- + // 1) Set up initial block number and user + // ------------------------------------------- + let cur_block = 5u64.into(); + System::::set_block_number(cur_block); + + let who = 123; + let netuid = 999; + + // ------------------------------------------- + // 2) Create multiple TLE fields referencing + // two known valid Drand rounds: 1000, 2000 + // ------------------------------------------- + + let round_1000 = 1000; + let round_2000 = 2000; + + // 2.a) TLE #1 => round=1000 + let tle_1_plaintext = b"Timelock #1 => round=1000"; + let ciphertext_1 = produce_ciphertext(tle_1_plaintext, round_1000); + let tle_1 = Data::TimelockEncrypted { + encrypted: ciphertext_1, + reveal_round: round_1000, + }; + + // 2.b) TLE #2 => round=1000 + let tle_2_plaintext = b"Timelock #2 => round=1000"; + let ciphertext_2 = produce_ciphertext(tle_2_plaintext, round_1000); + let tle_2 = Data::TimelockEncrypted { + encrypted: ciphertext_2, + reveal_round: round_1000, + }; + + // 2.c) TLE #3 => round=2000 + let tle_3_plaintext = b"Timelock #3 => round=2000"; + let ciphertext_3 = produce_ciphertext(tle_3_plaintext, round_2000); + let tle_3 = Data::TimelockEncrypted { + encrypted: ciphertext_3, + reveal_round: round_2000, + }; + + // 2.d) TLE #4 => round=2000 + let tle_4_plaintext = b"Timelock #4 => round=2000"; + let ciphertext_4 = produce_ciphertext(tle_4_plaintext, round_2000); + let tle_4 = Data::TimelockEncrypted { + encrypted: ciphertext_4, + reveal_round: round_2000, + }; + + // ------------------------------------------- + // 3) Insert all TLEs in a single CommitmentInfo + // ------------------------------------------- + let fields = vec![tle_1, tle_2, tle_3, tle_4]; + let fields_bounded = BoundedVec::try_from(fields).expect("Must not exceed MaxFields"); + let info = CommitmentInfo { + fields: fields_bounded, + }; + + // ------------------------------------------- + // 4) set_commitment => user is now in TimelockedIndex + // ------------------------------------------- + assert_ok!(Pallet::::set_commitment( + RuntimeOrigin::signed(who), + netuid, + Box::new(info) + )); + assert!( + TimelockedIndex::::get().contains(&(netuid, who)), + "User must appear in TimelockedIndex since they have TLE fields" + ); + + // Confirm the stored fields are as expected + let stored = CommitmentOf::::get(netuid, who).expect("Should be stored"); + assert_eq!( + stored.info.fields.len(), + 4, + "All 4 timelock fields must be stored" + ); + + // ------------------------------------------- + // 5) Insert valid Drand pulse => round=1000 + // ------------------------------------------- + let drand_sig_1000 = hex::decode(DRAND_QUICKNET_SIG_HEX).expect("decode signature"); + insert_drand_pulse(round_1000, &drand_sig_1000); + + // Reveal at block=6 => should remove TLE #1 and TLE #2, leaving TLE #3, #4 + System::::set_block_number(6u64.into()); + assert_ok!(Pallet::::reveal_timelocked_commitments()); + + // Check leftover => TLE #3, TLE #4 remain + let leftover_after_1000 = CommitmentOf::::get(netuid, who).expect("Must exist"); + assert_eq!( + leftover_after_1000.info.fields.len(), + 2, + "After revealing round=1000, 2 timelocks remain (#3, #4)" + ); + + // Check partial reveals => TLE #1 & #2 in revealed storage + let revealed_1000 = RevealedCommitments::::get(netuid, who) + .expect("Should have partial reveals"); + assert_eq!( + revealed_1000.len(), + 2, + "We revealed exactly 2 items at round=1000" + ); + { + let (bytes_a, _) = &revealed_1000[0]; + let (bytes_b, _) = &revealed_1000[1]; + let txt_a = sp_std::str::from_utf8(bytes_a).expect("utf-8 expected"); + let txt_b = sp_std::str::from_utf8(bytes_b).expect("utf-8 expected"); + assert!( + txt_a.contains("Timelock #1") || txt_a.contains("Timelock #2"), + "Revealed #1 or #2" + ); + assert!( + txt_b.contains("Timelock #1") || txt_b.contains("Timelock #2"), + "Revealed #1 or #2" + ); + } + + assert!( + TimelockedIndex::::get().contains(&(netuid, who)), + "TLE left" + ); + + // ------------------------------------------- + // 6) Insert valid Drand pulse => round=2000 + // ------------------------------------------- + let drand_sig_2000_hex = + "b6cb8f482a0b15d45936a4c4ea08e98a087e71787caee3f4d07a8a9843b1bc5423c6b3c22f446488b3137eaca799c77e"; + let drand_sig_2000 = hex::decode(drand_sig_2000_hex).expect("decode signature"); + insert_drand_pulse(round_2000, &drand_sig_2000); + + // Reveal at block=7 => should remove TLE #3 and TLE #4 + System::::set_block_number(7u64.into()); + assert_ok!(Pallet::::reveal_timelocked_commitments()); + + // After revealing these last two timelocks => leftover is none + let leftover_after_2000 = CommitmentOf::::get(netuid, who); + assert!( + leftover_after_2000.is_none(), + "All timelocks revealed => leftover none => entry removed" + ); + + // Because the user has no timelocks left => removed from TimelockedIndex + assert!( + !TimelockedIndex::::get().contains(&(netuid, who)), + "No TLE left => user removed from index" + ); + + // Check TLE #3 and #4 were appended to revealed + let revealed_final = RevealedCommitments::::get(netuid, who) + .expect("Should exist with final reveals"); + assert_eq!( + revealed_final.len(), + 4, + "We should have all 4 TLE items revealed in total" + ); + + // The final two items in `revealed_final` must be #3, #4 + let (third_bytes, _) = &revealed_final[2]; + let (fourth_bytes, _) = &revealed_final[3]; + let third_txt = sp_std::str::from_utf8(third_bytes).expect("utf-8 expected"); + let fourth_txt = sp_std::str::from_utf8(fourth_bytes).expect("utf-8 expected"); + + assert!( + third_txt.contains("Timelock #3"), + "Expected TLE #3 among final reveals" + ); + assert!( + fourth_txt.contains("Timelock #4"), + "Expected TLE #4 among final reveals" + ); + }); +} + +#[allow(clippy::indexing_slicing)] +#[test] +fn mixed_timelocked_and_raw_fields_works() { + new_test_ext().execute_with(|| { + // ------------------------------------------- + // 1) Setup initial block number and user + // ------------------------------------------- + let cur_block = 3u64.into(); + System::::set_block_number(cur_block); + + let who = 77; + let netuid = 501; + + // ------------------------------------------- + // 2) Create raw fields and timelocked fields + // ------------------------------------------- + // We'll use 2 raw fields, and 2 timelocked fields referencing + // 2 Drand rounds (1000 and 2000) that we know have valid signatures. + + // Round constants: + let round_1000 = 1000; + let round_2000 = 2000; + + // (a) Timelock #1 => round=1000 + let tle_1_plaintext = b"TLE #1 => round=1000"; + let ciphertext_1 = produce_ciphertext(tle_1_plaintext, round_1000); + let tle_1 = Data::TimelockEncrypted { + encrypted: ciphertext_1, + reveal_round: round_1000, + }; + + // (b) Timelock #2 => round=2000 + let tle_2_plaintext = b"TLE #2 => round=2000"; + let ciphertext_2 = produce_ciphertext(tle_2_plaintext, round_2000); + let tle_2 = Data::TimelockEncrypted { + encrypted: ciphertext_2, + reveal_round: round_2000, + }; + + // (c) Two Raw fields + let raw_1 = Data::Raw(b"Raw field #1".to_vec().try_into().expect("<= 128 bytes")); + let raw_2 = Data::Raw(b"Raw field #2".to_vec().try_into().expect("<= 128 bytes")); + + // We'll put them in a single vector: [TLE #1, raw_1, TLE #2, raw_2] + let all_fields = vec![tle_1, raw_1.clone(), tle_2, raw_2.clone()]; + let fields_bounded = BoundedVec::try_from(all_fields).expect("<= MaxFields"); + + // ------------------------------------------- + // 3) Submit the single commitment + // ------------------------------------------- + let info = CommitmentInfo { fields: fields_bounded }; + + assert_ok!(Pallet::::set_commitment( + RuntimeOrigin::signed(who), + netuid, + Box::new(info) + )); + + // The user should appear in TimelockedIndex because they have timelocked fields. + assert!( + TimelockedIndex::::get().contains(&(netuid, who)), + "User must be in TimelockedIndex with TLE fields" + ); + + // Check the stored data + let stored = CommitmentOf::::get(netuid, who).expect("Should exist in storage"); + assert_eq!( + stored.info.fields.len(), + 4, + "We have 2 raw + 2 TLE fields in total" + ); + + // ------------------------------------------- + // 4) Insert Drand signature for round=1000 => partial reveal + // ------------------------------------------- + let drand_sig_1000 = hex::decode(DRAND_QUICKNET_SIG_HEX).expect("decode signature"); + insert_drand_pulse(round_1000, &drand_sig_1000); + + System::::set_block_number(4u64.into()); + assert_ok!(Pallet::::reveal_timelocked_commitments()); + + // => TLE #1 (round=1000) is revealed. TLE #2 (round=2000) remains locked. + // => The two raw fields remain untouched. + let leftover_after_1000 = CommitmentOf::::get(netuid, who).expect("Must still exist"); + assert_eq!( + leftover_after_1000.info.fields.len(), + 3, + "One TLE removed => leftover=3 fields: TLE #2 + raw_1 + raw_2" + ); + + // Make sure user is still in TimelockedIndex (they still have TLE #2) + assert!( + TimelockedIndex::::get().contains(&(netuid, who)), + "Still has leftover TLE #2 => remains in index" + ); + + // Check partial reveal + let revealed_1000 = RevealedCommitments::::get(netuid, who) + .expect("Should have partial reveals"); + assert_eq!( + revealed_1000.len(), + 1, + "We revealed exactly 1 item at round=1000" + ); + let (revealed_bytes_1, _block_1) = &revealed_1000[0]; + let revealed_str_1 = + sp_std::str::from_utf8(revealed_bytes_1).expect("Should parse as UTF-8"); + assert!( + revealed_str_1.contains("TLE #1 => round=1000"), + "Check that TLE #1 was revealed" + ); + + // ------------------------------------------- + // 5) Insert Drand signature for round=2000 => final TLE reveal + // ------------------------------------------- + let drand_sig_2000_hex = + "b6cb8f482a0b15d45936a4c4ea08e98a087e71787caee3f4d07a8a9843b1bc5423c6b3c22f446488b3137eaca799c77e"; + let drand_sig_2000 = hex::decode(drand_sig_2000_hex).expect("decode signature"); + insert_drand_pulse(round_2000, &drand_sig_2000); + + System::::set_block_number(5u64.into()); + assert_ok!(Pallet::::reveal_timelocked_commitments()); + + // => TLE #2 is now revealed. The two raw fields remain. + let leftover_after_2000 = CommitmentOf::::get(netuid, who).expect("Still exists"); + let leftover_fields = &leftover_after_2000.info.fields; + assert_eq!( + leftover_fields.len(), + 2, + "Only the 2 raw fields remain after TLE #2 is revealed" + ); + + assert_eq!( + leftover_fields[0], + raw_1, + "Leftover field[0] must match raw_1" + ); + assert_eq!( + leftover_fields[1], + raw_2, + "Leftover field[1] must match raw_2" + ); + + // The user has no leftover timelocks => removed from TimelockedIndex + assert!( + !TimelockedIndex::::get().contains(&(netuid, who)), + "No more TLE => user removed from index" + ); + + // But the record is still present in storage (because raw fields remain) + // => leftover_fields must match our original raw fields. + let [f1, f2] = &leftover_fields[..] else { + panic!("Expected exactly 2 fields leftover"); + }; + assert_eq!(f1, &raw_1, "Raw field #1 remains unaltered"); + assert_eq!(f2, &raw_2, "Raw field #2 remains unaltered"); + + // Check that TLE #2 was appended to revealed data + let revealed_final = RevealedCommitments::::get(netuid, who) + .expect("Should have final reveals"); + assert_eq!( + revealed_final.len(), + 2, + "Now we have 2 revealed TLE items total (TLE #1 and TLE #2)." + ); + let (revealed_bytes_2, _block_2) = &revealed_final[1]; + let revealed_str_2 = + sp_std::str::from_utf8(revealed_bytes_2).expect("Should parse as UTF-8"); + assert!( + revealed_str_2.contains("TLE #2 => round=2000"), + "Check that TLE #2 was revealed" + ); + }); +} diff --git a/pallets/commitments/src/types.rs b/pallets/commitments/src/types.rs index eef0cfd11c..543eb08cd1 100644 --- a/pallets/commitments/src/types.rs +++ b/pallets/commitments/src/types.rs @@ -31,15 +31,18 @@ use sp_runtime::{ use sp_std::{fmt::Debug, iter::once, prelude::*}; use subtensor_macros::freeze_struct; -/// Either underlying data blob if it is at most 32 bytes, or a hash of it. If the data is greater -/// than 32-bytes then it will be truncated when encoding. -/// -/// Can also be `None`. +/// Represents stored data which can be: +/// - `Raw`: a direct blob up to 128 bytes +/// - `BigRaw`: a larger blob up to 512 bytes +/// - A cryptographic hash (BlakeTwo256, Sha256, Keccak256, ShaThree256) +/// - A timelock-encrypted blob with a reveal round +/// - A reset flag (`ResetBondsFlag`) +/// Can also be `None`. #[derive(Clone, Eq, PartialEq, RuntimeDebug, MaxEncodedLen)] pub enum Data { /// No data here. None, - /// The data is stored directly. + /// The data is stored directly (up to 128 bytes). Raw(BoundedVec>), /// Only the Blake2 hash of the data is stored. The preimage of the hash may be retrieved /// through some hash-lookup service. @@ -60,6 +63,8 @@ pub enum Data { }, /// Flag to trigger bonds reset for subnet ResetBondsFlag, + /// The data is stored directly (up to 512 bytes). + BigRaw(BoundedVec>), } impl Data { @@ -82,6 +87,7 @@ impl Data { | Data::ShaThree256(arr) => arr.len() as u64, Data::TimelockEncrypted { encrypted, .. } => encrypted.len() as u64, Data::ResetBondsFlag => 0, + Data::BigRaw(bytes) => bytes.len() as u64, } } } @@ -112,6 +118,11 @@ impl Decode for Data { } } 135 => Data::ResetBondsFlag, + 136 => { + let bigvec = + BoundedVec::>::decode(input)?; + Data::BigRaw(bigvec) + } _ => return Err(codec::Error::from("invalid leading byte")), }) } @@ -141,6 +152,11 @@ impl Encode for Data { r } Data::ResetBondsFlag => vec![135], + Data::BigRaw(bigvec) => { + let mut r = vec![136]; + r.extend_from_slice(&bigvec.encode()); + r + } } } } @@ -327,7 +343,12 @@ impl TypeInfo for Data { .field(|f| f.name("reveal_round").ty::()), ) }) - .variant("ResetBondsFlag", |v| v.index(135)); + .variant("ResetBondsFlag", |v| v.index(135)) + .variant("BigRaw", |v| { + v.index(136).fields(Fields::unnamed().field(|f| { + f.ty::>>() + })) + }); Type::builder() .path(Path::new("Data", module_path!())) @@ -354,6 +375,7 @@ pub struct CommitmentInfo> { /// Maximum size of the serialized timelock commitment in bytes pub const MAX_TIMELOCK_COMMITMENT_SIZE_BYTES: u32 = 1024; +pub const MAX_BIGRAW_COMMITMENT_SIZE_BYTES: u32 = 512; /// Contains the decrypted data of a revealed commitment. #[freeze_struct("bf575857b57f9bef")] diff --git a/pallets/subtensor/src/benchmarks.rs b/pallets/subtensor/src/benchmarks.rs index 717722c479..a7cd03e652 100644 --- a/pallets/subtensor/src/benchmarks.rs +++ b/pallets/subtensor/src/benchmarks.rs @@ -156,173 +156,173 @@ mod pallet_benchmarks { ); } - #[benchmark] - fn add_stake_aggregate() { - let netuid: u16 = 1; - let tempo: u16 = 1; - - Subtensor::::init_new_network(netuid, tempo); - SubtokenEnabled::::insert(netuid, true); - Subtensor::::set_burn(netuid, 1); - Subtensor::::set_network_registration_allowed(netuid, true); - Subtensor::::set_max_allowed_uids(netuid, 4096); - - let seed: u32 = 1; - let coldkey: T::AccountId = account("Test", 0, seed); - let hotkey: T::AccountId = account("Alice", 0, seed); - let total_stake: u64 = 1_000_000_000; - let amount: u64 = 600_000; - - Subtensor::::add_balance_to_coldkey_account(&coldkey, total_stake); - assert_ok!(Subtensor::::do_burned_registration( - RawOrigin::Signed(coldkey.clone()).into(), - netuid, - hotkey.clone() - )); - - #[extrinsic_call] - _( - RawOrigin::Signed(coldkey.clone()), - hotkey.clone(), - netuid, - amount, - ); - } - - #[benchmark] - fn remove_stake_limit_aggregate() { - let netuid: u16 = 1; - - Subtensor::::increase_total_stake(1_000_000_000_000); - Subtensor::::init_new_network(netuid, 1); - Subtensor::::set_network_registration_allowed(netuid, true); - SubtokenEnabled::::insert(netuid, true); - Subtensor::::set_max_allowed_uids(netuid, 4096); - - let seed: u32 = 1; - let coldkey: T::AccountId = account("Test", 0, seed); - let hotkey: T::AccountId = account("Alice", 0, seed); - Subtensor::::set_burn(netuid, 1); - - let limit: u64 = 1_000_000_000; - let tao_reserve: u64 = 150_000_000_000; - let alpha_in: u64 = 100_000_000_000; - SubnetTAO::::insert(netuid, tao_reserve); - SubnetAlphaIn::::insert(netuid, alpha_in); - - let wallet_bal: u64 = 1_000_000; - Subtensor::::add_balance_to_coldkey_account(&coldkey, wallet_bal); - - assert_ok!(Subtensor::::do_burned_registration( - RawOrigin::Signed(coldkey.clone()).into(), - netuid, - hotkey.clone() - )); - - Subtensor::::add_balance_to_coldkey_account(&coldkey, 100_000_000_000u64); - assert_ok!(Subtensor::::add_stake( - RawOrigin::Signed(coldkey.clone()).into(), - hotkey.clone(), - netuid, - 100_000_000_000u64 - )); - - let amount_unstaked: u64 = 30_000_000_000; - - #[extrinsic_call] - _( - RawOrigin::Signed(coldkey.clone()), - hotkey.clone(), - netuid, - amount_unstaked, - limit, - false, - ); - } - - #[benchmark] - fn remove_stake_aggregate() { - let netuid: u16 = 1; - - Subtensor::::increase_total_stake(1_000_000_000_000); - Subtensor::::init_new_network(netuid, 1); - Subtensor::::set_network_registration_allowed(netuid, true); - SubtokenEnabled::::insert(netuid, true); - Subtensor::::set_max_allowed_uids(netuid, 4096); - - let seed: u32 = 1; - let coldkey: T::AccountId = account("Test", 0, seed); - let hotkey: T::AccountId = account("Alice", 0, seed); - Subtensor::::set_burn(netuid, 1); - - let wallet_bal: u64 = 1_000_000; - Subtensor::::add_balance_to_coldkey_account(&coldkey, wallet_bal); - - assert_ok!(Subtensor::::do_burned_registration( - RawOrigin::Signed(coldkey.clone()).into(), - netuid, - hotkey.clone() - )); - - Subtensor::::add_balance_to_coldkey_account(&coldkey, 100_000_000_000u64); - assert_ok!(Subtensor::::add_stake( - RawOrigin::Signed(coldkey.clone()).into(), - hotkey.clone(), - netuid, - 100_000_000_000u64 - )); - - let amount_unstaked: u64 = 600_000; - - #[extrinsic_call] - _( - RawOrigin::Signed(coldkey.clone()), - hotkey.clone(), - netuid, - amount_unstaked, - ); - } - - #[benchmark] - fn add_stake_limit_aggregate() { - let netuid: u16 = 1; - - Subtensor::::init_new_network(netuid, 1); - SubtokenEnabled::::insert(netuid, true); - Subtensor::::set_burn(netuid, 1); - Subtensor::::set_network_registration_allowed(netuid, true); - Subtensor::::set_max_allowed_uids(netuid, 4096); - - let seed: u32 = 1; - let coldkey: T::AccountId = account("Test", 0, seed); - let hotkey: T::AccountId = account("Alice", 0, seed); - - let amount: u64 = 900_000_000_000; - let limit: u64 = 6_000_000_000; - let stake_amt: u64 = 440_000_000_000; - Subtensor::::add_balance_to_coldkey_account(&coldkey, amount); - - let tao_reserve: u64 = 150_000_000_000; - let alpha_in: u64 = 100_000_000_000; - SubnetTAO::::insert(netuid, tao_reserve); - SubnetAlphaIn::::insert(netuid, alpha_in); - - assert_ok!(Subtensor::::do_burned_registration( - RawOrigin::Signed(coldkey.clone()).into(), - netuid, - hotkey.clone() - )); - - #[extrinsic_call] - _( - RawOrigin::Signed(coldkey.clone()), - hotkey.clone(), - netuid, - stake_amt, - limit, - false, - ); - } + // #[benchmark] + // fn add_stake_aggregate() { + // let netuid: u16 = 1; + // let tempo: u16 = 1; + // + // Subtensor::::init_new_network(netuid, tempo); + // SubtokenEnabled::::insert(netuid, true); + // Subtensor::::set_burn(netuid, 1); + // Subtensor::::set_network_registration_allowed(netuid, true); + // Subtensor::::set_max_allowed_uids(netuid, 4096); + // + // let seed: u32 = 1; + // let coldkey: T::AccountId = account("Test", 0, seed); + // let hotkey: T::AccountId = account("Alice", 0, seed); + // let total_stake: u64 = 1_000_000_000; + // let amount: u64 = 600_000; + // + // Subtensor::::add_balance_to_coldkey_account(&coldkey, total_stake); + // assert_ok!(Subtensor::::do_burned_registration( + // RawOrigin::Signed(coldkey.clone()).into(), + // netuid, + // hotkey.clone() + // )); + // + // #[extrinsic_call] + // _( + // RawOrigin::Signed(coldkey.clone()), + // hotkey.clone(), + // netuid, + // amount, + // ); + // } + // + // #[benchmark] + // fn remove_stake_limit_aggregate() { + // let netuid: u16 = 1; + // + // Subtensor::::increase_total_stake(1_000_000_000_000); + // Subtensor::::init_new_network(netuid, 1); + // Subtensor::::set_network_registration_allowed(netuid, true); + // SubtokenEnabled::::insert(netuid, true); + // Subtensor::::set_max_allowed_uids(netuid, 4096); + // + // let seed: u32 = 1; + // let coldkey: T::AccountId = account("Test", 0, seed); + // let hotkey: T::AccountId = account("Alice", 0, seed); + // Subtensor::::set_burn(netuid, 1); + // + // let limit: u64 = 1_000_000_000; + // let tao_reserve: u64 = 150_000_000_000; + // let alpha_in: u64 = 100_000_000_000; + // SubnetTAO::::insert(netuid, tao_reserve); + // SubnetAlphaIn::::insert(netuid, alpha_in); + // + // let wallet_bal: u64 = 1_000_000; + // Subtensor::::add_balance_to_coldkey_account(&coldkey, wallet_bal); + // + // assert_ok!(Subtensor::::do_burned_registration( + // RawOrigin::Signed(coldkey.clone()).into(), + // netuid, + // hotkey.clone() + // )); + // + // Subtensor::::add_balance_to_coldkey_account(&coldkey, 100_000_000_000u64); + // assert_ok!(Subtensor::::add_stake( + // RawOrigin::Signed(coldkey.clone()).into(), + // hotkey.clone(), + // netuid, + // 100_000_000_000u64 + // )); + // + // let amount_unstaked: u64 = 30_000_000_000; + // + // #[extrinsic_call] + // _( + // RawOrigin::Signed(coldkey.clone()), + // hotkey.clone(), + // netuid, + // amount_unstaked, + // limit, + // false, + // ); + // } + // + // #[benchmark] + // fn remove_stake_aggregate() { + // let netuid: u16 = 1; + // + // Subtensor::::increase_total_stake(1_000_000_000_000); + // Subtensor::::init_new_network(netuid, 1); + // Subtensor::::set_network_registration_allowed(netuid, true); + // SubtokenEnabled::::insert(netuid, true); + // Subtensor::::set_max_allowed_uids(netuid, 4096); + // + // let seed: u32 = 1; + // let coldkey: T::AccountId = account("Test", 0, seed); + // let hotkey: T::AccountId = account("Alice", 0, seed); + // Subtensor::::set_burn(netuid, 1); + // + // let wallet_bal: u64 = 1_000_000; + // Subtensor::::add_balance_to_coldkey_account(&coldkey, wallet_bal); + // + // assert_ok!(Subtensor::::do_burned_registration( + // RawOrigin::Signed(coldkey.clone()).into(), + // netuid, + // hotkey.clone() + // )); + // + // Subtensor::::add_balance_to_coldkey_account(&coldkey, 100_000_000_000u64); + // assert_ok!(Subtensor::::add_stake( + // RawOrigin::Signed(coldkey.clone()).into(), + // hotkey.clone(), + // netuid, + // 100_000_000_000u64 + // )); + // + // let amount_unstaked: u64 = 600_000; + // + // #[extrinsic_call] + // _( + // RawOrigin::Signed(coldkey.clone()), + // hotkey.clone(), + // netuid, + // amount_unstaked, + // ); + // } + // + // #[benchmark] + // fn add_stake_limit_aggregate() { + // let netuid: u16 = 1; + // + // Subtensor::::init_new_network(netuid, 1); + // SubtokenEnabled::::insert(netuid, true); + // Subtensor::::set_burn(netuid, 1); + // Subtensor::::set_network_registration_allowed(netuid, true); + // Subtensor::::set_max_allowed_uids(netuid, 4096); + // + // let seed: u32 = 1; + // let coldkey: T::AccountId = account("Test", 0, seed); + // let hotkey: T::AccountId = account("Alice", 0, seed); + // + // let amount: u64 = 900_000_000_000; + // let limit: u64 = 6_000_000_000; + // let stake_amt: u64 = 440_000_000_000; + // Subtensor::::add_balance_to_coldkey_account(&coldkey, amount); + // + // let tao_reserve: u64 = 150_000_000_000; + // let alpha_in: u64 = 100_000_000_000; + // SubnetTAO::::insert(netuid, tao_reserve); + // SubnetAlphaIn::::insert(netuid, alpha_in); + // + // assert_ok!(Subtensor::::do_burned_registration( + // RawOrigin::Signed(coldkey.clone()).into(), + // netuid, + // hotkey.clone() + // )); + // + // #[extrinsic_call] + // _( + // RawOrigin::Signed(coldkey.clone()), + // hotkey.clone(), + // netuid, + // stake_amt, + // limit, + // false, + // ); + // } #[benchmark] fn serve_axon() { diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index 2a36458e4f..197cd5f8f7 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -2194,112 +2194,112 @@ where Self::get_priority_staking(who, hotkey, *amount_unstaked), ) } - Some(Call::add_stake_aggregate { - hotkey, - netuid, - amount_staked, - }) => { - if ColdkeySwapScheduled::::contains_key(who) { - return InvalidTransaction::Custom( - CustomTransactionError::ColdkeyInSwapSchedule.into(), - ) - .into(); - } - // Fully validate the user input - Self::result_to_validity( - Pallet::::validate_add_stake( - who, - hotkey, - *netuid, - *amount_staked, - *amount_staked, - false, - ), - Self::get_priority_staking(who, hotkey, *amount_staked), - ) - } - Some(Call::add_stake_limit_aggregate { - hotkey, - netuid, - amount_staked, - limit_price, - allow_partial, - }) => { - if ColdkeySwapScheduled::::contains_key(who) { - return InvalidTransaction::Custom( - CustomTransactionError::ColdkeyInSwapSchedule.into(), - ) - .into(); - } - - // Calculate the maximum amount that can be executed with price limit - let Ok(max_amount) = Pallet::::get_max_amount_add(*netuid, *limit_price) else { - return InvalidTransaction::Custom( - CustomTransactionError::ZeroMaxAmount.into(), - ) - .into(); - }; - - // Fully validate the user input - Self::result_to_validity( - Pallet::::validate_add_stake( - who, - hotkey, - *netuid, - *amount_staked, - max_amount, - *allow_partial, - ), - Self::get_priority_staking(who, hotkey, *amount_staked), - ) - } - Some(Call::remove_stake_aggregate { - hotkey, - netuid, - amount_unstaked, - }) => { - // Fully validate the user input - Self::result_to_validity( - Pallet::::validate_remove_stake( - who, - hotkey, - *netuid, - *amount_unstaked, - *amount_unstaked, - false, - ), - Self::get_priority_staking(who, hotkey, *amount_unstaked), - ) - } - Some(Call::remove_stake_limit_aggregate { - hotkey, - netuid, - amount_unstaked, - limit_price, - allow_partial, - }) => { - // Calculate the maximum amount that can be executed with price limit - let Ok(max_amount) = Pallet::::get_max_amount_remove(*netuid, *limit_price) - else { - return InvalidTransaction::Custom( - CustomTransactionError::ZeroMaxAmount.into(), - ) - .into(); - }; - - // Fully validate the user input - Self::result_to_validity( - Pallet::::validate_remove_stake( - who, - hotkey, - *netuid, - *amount_unstaked, - max_amount, - *allow_partial, - ), - Self::get_priority_staking(who, hotkey, *amount_unstaked), - ) - } + // Some(Call::add_stake_aggregate { + // hotkey, + // netuid, + // amount_staked, + // }) => { + // if ColdkeySwapScheduled::::contains_key(who) { + // return InvalidTransaction::Custom( + // CustomTransactionError::ColdkeyInSwapSchedule.into(), + // ) + // .into(); + // } + // // Fully validate the user input + // Self::result_to_validity( + // Pallet::::validate_add_stake( + // who, + // hotkey, + // *netuid, + // *amount_staked, + // *amount_staked, + // false, + // ), + // Self::get_priority_staking(who, hotkey, *amount_staked), + // ) + // } + // Some(Call::add_stake_limit_aggregate { + // hotkey, + // netuid, + // amount_staked, + // limit_price, + // allow_partial, + // }) => { + // if ColdkeySwapScheduled::::contains_key(who) { + // return InvalidTransaction::Custom( + // CustomTransactionError::ColdkeyInSwapSchedule.into(), + // ) + // .into(); + // } + // + // // Calculate the maximum amount that can be executed with price limit + // let Ok(max_amount) = Pallet::::get_max_amount_add(*netuid, *limit_price) else { + // return InvalidTransaction::Custom( + // CustomTransactionError::ZeroMaxAmount.into(), + // ) + // .into(); + // }; + // + // // Fully validate the user input + // Self::result_to_validity( + // Pallet::::validate_add_stake( + // who, + // hotkey, + // *netuid, + // *amount_staked, + // max_amount, + // *allow_partial, + // ), + // Self::get_priority_staking(who, hotkey, *amount_staked), + // ) + // } + // Some(Call::remove_stake_aggregate { + // hotkey, + // netuid, + // amount_unstaked, + // }) => { + // // Fully validate the user input + // Self::result_to_validity( + // Pallet::::validate_remove_stake( + // who, + // hotkey, + // *netuid, + // *amount_unstaked, + // *amount_unstaked, + // false, + // ), + // Self::get_priority_staking(who, hotkey, *amount_unstaked), + // ) + // } + // Some(Call::remove_stake_limit_aggregate { + // hotkey, + // netuid, + // amount_unstaked, + // limit_price, + // allow_partial, + // }) => { + // // Calculate the maximum amount that can be executed with price limit + // let Ok(max_amount) = Pallet::::get_max_amount_remove(*netuid, *limit_price) + // else { + // return InvalidTransaction::Custom( + // CustomTransactionError::ZeroMaxAmount.into(), + // ) + // .into(); + // }; + // + // // Fully validate the user input + // Self::result_to_validity( + // Pallet::::validate_remove_stake( + // who, + // hotkey, + // *netuid, + // *amount_unstaked, + // max_amount, + // *allow_partial, + // ), + // Self::get_priority_staking(who, hotkey, *amount_unstaked), + // ) + // } Some(Call::move_stake { origin_hotkey, destination_hotkey, diff --git a/pallets/subtensor/src/macros/dispatches.rs b/pallets/subtensor/src/macros/dispatches.rs index 637042c456..261c55345e 100644 --- a/pallets/subtensor/src/macros/dispatches.rs +++ b/pallets/subtensor/src/macros/dispatches.rs @@ -1993,7 +1993,7 @@ mod dispatches { #[pallet::weight(( Weight::from_parts(3_000_000, 0).saturating_add(T::DbWeight::get().reads_writes(2, 1)), DispatchClass::Operational, - Pays::Yes + Pays::No ))] pub fn associate_evm_key( origin: T::RuntimeOrigin, @@ -2056,288 +2056,288 @@ mod dispatches { Self::do_burn_alpha(origin, hotkey, amount, netuid) } - /// --- Adds stake to a hotkey on a subnet with a price limit. - /// This extrinsic allows to specify the limit price for alpha token - /// at which or better (lower) the staking should execute. - /// - /// In case if slippage occurs and the price shall move beyond the limit - /// price, the staking order may execute only partially or not execute - /// at all. - /// - /// The operation will be delayed. - /// - /// # Args: - /// * 'origin': (Origin): - /// - The signature of the caller's coldkey. - /// - /// * 'hotkey' (T::AccountId): - /// - The associated hotkey account. - /// - /// * 'netuid' (u16): - /// - Subnetwork UID - /// - /// * 'amount_staked' (u64): - /// - The amount of stake to be added to the hotkey staking account. - /// - /// # Event: - /// * StakeAdded; - /// - On the successfully adding stake to a global account. - /// - /// # Raises: - /// * 'NotEnoughBalanceToStake': - /// - Not enough balance on the coldkey to add onto the global account. - /// - /// * 'NonAssociatedColdKey': - /// - The calling coldkey is not associated with this hotkey. - /// - /// * 'BalanceWithdrawalError': - /// - Errors stemming from transaction pallet. - /// - #[pallet::call_index(103)] - #[pallet::weight((Weight::from_parts(162_000_000, 5127) - .saturating_add(T::DbWeight::get().reads(15_u64)) - .saturating_add(T::DbWeight::get().writes(12_u64)), DispatchClass::Normal, Pays::No))] - pub fn add_stake_aggregate( - origin: OriginFor, - hotkey: T::AccountId, - netuid: u16, - amount_staked: u64, - ) -> DispatchResult { - Self::do_add_stake_aggregate(origin, hotkey, netuid, amount_staked) - } - - /// --- Removes stake from a hotkey on a subnet with a price limit. - /// This extrinsic allows to specify the limit price for alpha token - /// at which or better (higher) the staking should execute. - /// - /// In case if slippage occurs and the price shall move beyond the limit - /// price, the staking order may execute only partially or not execute - /// at all. - /// - /// The operation will be delayed. - /// - /// # Args: - /// * 'origin': (Origin): - /// - The signature of the caller's coldkey. - /// - /// * 'hotkey' (T::AccountId): - /// - The associated hotkey account. - /// - /// * 'netuid' (u16): - /// - Subnetwork UID - /// - /// * 'amount_unstaked' (u64): - /// - The amount of stake to be added to the hotkey staking account. - /// - /// # Event: - /// * StakeRemoved; - /// - On the successfully removing stake from the hotkey account. - /// - /// # Raises: - /// * 'NotRegistered': - /// - Thrown if the account we are attempting to unstake from is non existent. - /// - /// * 'NonAssociatedColdKey': - /// - Thrown if the coldkey does not own the hotkey we are unstaking from. - /// - /// * 'NotEnoughStakeToWithdraw': - /// - Thrown if there is not enough stake on the hotkey to withdwraw this amount. - /// - #[pallet::call_index(104)] - #[pallet::weight((Weight::from_parts(213_300_000, 10163) - .saturating_add(T::DbWeight::get().reads(20_u64)) - .saturating_add(T::DbWeight::get().writes(12_u64)), DispatchClass::Normal, Pays::No))] - pub fn remove_stake_aggregate( - origin: OriginFor, - hotkey: T::AccountId, - netuid: u16, - amount_unstaked: u64, - ) -> DispatchResult { - Self::do_remove_stake_aggregate(origin, hotkey, netuid, amount_unstaked) - } - - /// --- Adds stake to a hotkey on a subnet with a price limit. - /// This extrinsic allows to specify the limit price for alpha token - /// at which or better (lower) the staking should execute. - /// - /// In case if slippage occurs and the price shall move beyond the limit - /// price, the staking order may execute only partially or not execute - /// at all. - /// - /// The operation will be delayed. - /// - /// # Args: - /// * 'origin': (Origin): - /// - The signature of the caller's coldkey. - /// - /// * 'hotkey' (T::AccountId): - /// - The associated hotkey account. - /// - /// * 'netuid' (u16): - /// - Subnetwork UID - /// - /// * 'amount_staked' (u64): - /// - The amount of stake to be added to the hotkey staking account. - /// - /// * 'limit_price' (u64): - /// - The limit price expressed in units of RAO per one Alpha. - /// - /// * 'allow_partial' (bool): - /// - Allows partial execution of the amount. If set to false, this becomes - /// fill or kill type or order. - /// - /// # Event: - /// * StakeAdded; - /// - On the successfully adding stake to a global account. - /// - /// # Raises: - /// * 'NotEnoughBalanceToStake': - /// - Not enough balance on the coldkey to add onto the global account. - /// - /// * 'NonAssociatedColdKey': - /// - The calling coldkey is not associated with this hotkey. - /// - /// * 'BalanceWithdrawalError': - /// - Errors stemming from transaction pallet. - /// - #[pallet::call_index(105)] - #[pallet::weight((Weight::from_parts(169_200_000, 5127) - .saturating_add(T::DbWeight::get().reads(14_u64)) - .saturating_add(T::DbWeight::get().writes(12_u64)), DispatchClass::Normal, Pays::No))] - pub fn add_stake_limit_aggregate( - origin: OriginFor, - hotkey: T::AccountId, - netuid: u16, - amount_staked: u64, - limit_price: u64, - allow_partial: bool, - ) -> DispatchResult { - Self::do_add_stake_limit_aggregate( - origin, - hotkey, - netuid, - amount_staked, - limit_price, - allow_partial, - ) - } - - /// --- Removes stake from a hotkey on a subnet with a price limit. - /// This extrinsic allows to specify the limit price for alpha token - /// at which or better (higher) the staking should execute. - /// - /// In case if slippage occurs and the price shall move beyond the limit - /// price, the staking order may execute only partially or not execute - /// at all. - /// - /// The operation will be delayed. - /// - /// # Args: - /// * 'origin': (Origin): - /// - The signature of the caller's coldkey. - /// - /// * 'hotkey' (T::AccountId): - /// - The associated hotkey account. - /// - /// * 'netuid' (u16): - /// - Subnetwork UID - /// - /// * 'amount_unstaked' (u64): - /// - The amount of stake to be added to the hotkey staking account. - /// - /// * 'limit_price' (u64): - /// - The limit price expressed in units of RAO per one Alpha. - /// - /// * 'allow_partial' (bool): - /// - Allows partial execution of the amount. If set to false, this becomes - /// fill or kill type or order. - /// - /// # Event: - /// * StakeRemoved; - /// - On the successfully removing stake from the hotkey account. - /// - /// # Raises: - /// * 'NotRegistered': - /// - Thrown if the account we are attempting to unstake from is non existent. - /// - /// * 'NonAssociatedColdKey': - /// - Thrown if the coldkey does not own the hotkey we are unstaking from. - /// - /// * 'NotEnoughStakeToWithdraw': - /// - Thrown if there is not enough stake on the hotkey to withdwraw this amount. - /// - #[pallet::call_index(106)] - #[pallet::weight((Weight::from_parts(211_700_000, 10163) - .saturating_add(T::DbWeight::get().reads(19_u64)) - .saturating_add(T::DbWeight::get().writes(12_u64)), DispatchClass::Normal, Pays::No))] - pub fn remove_stake_limit_aggregate( - origin: OriginFor, - hotkey: T::AccountId, - netuid: u16, - amount_unstaked: u64, - limit_price: u64, - allow_partial: bool, - ) -> DispatchResult { - Self::do_remove_stake_limit_aggregate( - origin, - hotkey, - netuid, - amount_unstaked, - limit_price, - allow_partial, - ) - } - - /// ---- The implementation for the extrinsic unstake_all_aggregate: Removes all stake from a hotkey account across all subnets and adds it onto a coldkey. - /// - /// The operation will be delayed. - /// - /// # Args: - /// * `origin` - (::Origin): - /// - The signature of the caller's coldkey. - /// - /// * `hotkey` (T::AccountId): - /// - The associated hotkey account. - /// - /// # Event: - /// * StakeRemoved; - /// - On the successfully removing stake from the hotkey account. - /// - /// # Raises: - /// * `NotRegistered`: - /// - Thrown if the account we are attempting to unstake from is non existent. - /// - /// * `NonAssociatedColdKey`: - /// - Thrown if the coldkey does not own the hotkey we are unstaking from. - /// - /// * `NotEnoughStakeToWithdraw`: - /// - Thrown if there is not enough stake on the hotkey to withdraw this amount. - /// - /// * `TxRateLimitExceeded`: - /// - Thrown if key has hit transaction rate limit - #[pallet::call_index(107)] - #[pallet::weight((Weight::from_parts(3_000_000, 0).saturating_add(T::DbWeight::get().writes(1)), DispatchClass::Operational, Pays::No))] - pub fn unstake_all_aggregate(origin: OriginFor, hotkey: T::AccountId) -> DispatchResult { - Self::do_unstake_all_aggregate(origin, hotkey) - } - - /// ---- The implementation for the extrinsic unstake_all_alpha_aggregate: Removes all stake from a hotkey account across all subnets and adds it onto a coldkey. - /// - /// The operation will be delayed. - /// - /// # Args: - /// * `origin` - (::Origin): - /// - The signature of the caller's coldkey. - /// - /// * `hotkey` (T::AccountId): - /// - The associated hotkey account. - #[pallet::call_index(108)] - #[pallet::weight((Weight::from_parts(3_000_000, 0).saturating_add(T::DbWeight::get().writes(1)), DispatchClass::Operational, Pays::No))] - pub fn unstake_all_alpha_aggregate( - origin: OriginFor, - hotkey: T::AccountId, - ) -> DispatchResult { - Self::do_unstake_all_alpha_aggregate(origin, hotkey) - } + // /// --- Adds stake to a hotkey on a subnet with a price limit. + // /// This extrinsic allows to specify the limit price for alpha token + // /// at which or better (lower) the staking should execute. + // /// + // /// In case if slippage occurs and the price shall move beyond the limit + // /// price, the staking order may execute only partially or not execute + // /// at all. + // /// + // /// The operation will be delayed. + // /// + // /// # Args: + // /// * 'origin': (Origin): + // /// - The signature of the caller's coldkey. + // /// + // /// * 'hotkey' (T::AccountId): + // /// - The associated hotkey account. + // /// + // /// * 'netuid' (u16): + // /// - Subnetwork UID + // /// + // /// * 'amount_staked' (u64): + // /// - The amount of stake to be added to the hotkey staking account. + // /// + // /// # Event: + // /// * StakeAdded; + // /// - On the successfully adding stake to a global account. + // /// + // /// # Raises: + // /// * 'NotEnoughBalanceToStake': + // /// - Not enough balance on the coldkey to add onto the global account. + // /// + // /// * 'NonAssociatedColdKey': + // /// - The calling coldkey is not associated with this hotkey. + // /// + // /// * 'BalanceWithdrawalError': + // /// - Errors stemming from transaction pallet. + // /// + // #[pallet::call_index(103)] + // #[pallet::weight((Weight::from_parts(162_000_000, 5127) + // .saturating_add(T::DbWeight::get().reads(15_u64)) + // .saturating_add(T::DbWeight::get().writes(12_u64)), DispatchClass::Normal, Pays::No))] + // pub fn add_stake_aggregate( + // origin: OriginFor, + // hotkey: T::AccountId, + // netuid: u16, + // amount_staked: u64, + // ) -> DispatchResult { + // Self::do_add_stake_aggregate(origin, hotkey, netuid, amount_staked) + // } + + // /// --- Removes stake from a hotkey on a subnet with a price limit. + // /// This extrinsic allows to specify the limit price for alpha token + // /// at which or better (higher) the staking should execute. + // /// + // /// In case if slippage occurs and the price shall move beyond the limit + // /// price, the staking order may execute only partially or not execute + // /// at all. + // /// + // /// The operation will be delayed. + // /// + // /// # Args: + // /// * 'origin': (Origin): + // /// - The signature of the caller's coldkey. + // /// + // /// * 'hotkey' (T::AccountId): + // /// - The associated hotkey account. + // /// + // /// * 'netuid' (u16): + // /// - Subnetwork UID + // /// + // /// * 'amount_unstaked' (u64): + // /// - The amount of stake to be added to the hotkey staking account. + // /// + // /// # Event: + // /// * StakeRemoved; + // /// - On the successfully removing stake from the hotkey account. + // /// + // /// # Raises: + // /// * 'NotRegistered': + // /// - Thrown if the account we are attempting to unstake from is non existent. + // /// + // /// * 'NonAssociatedColdKey': + // /// - Thrown if the coldkey does not own the hotkey we are unstaking from. + // /// + // /// * 'NotEnoughStakeToWithdraw': + // /// - Thrown if there is not enough stake on the hotkey to withdwraw this amount. + // /// + // #[pallet::call_index(104)] + // #[pallet::weight((Weight::from_parts(213_300_000, 10163) + // .saturating_add(T::DbWeight::get().reads(20_u64)) + // .saturating_add(T::DbWeight::get().writes(12_u64)), DispatchClass::Normal, Pays::No))] + // pub fn remove_stake_aggregate( + // origin: OriginFor, + // hotkey: T::AccountId, + // netuid: u16, + // amount_unstaked: u64, + // ) -> DispatchResult { + // Self::do_remove_stake_aggregate(origin, hotkey, netuid, amount_unstaked) + // } + + // /// --- Adds stake to a hotkey on a subnet with a price limit. + // /// This extrinsic allows to specify the limit price for alpha token + // /// at which or better (lower) the staking should execute. + // /// + // /// In case if slippage occurs and the price shall move beyond the limit + // /// price, the staking order may execute only partially or not execute + // /// at all. + // /// + // /// The operation will be delayed. + // /// + // /// # Args: + // /// * 'origin': (Origin): + // /// - The signature of the caller's coldkey. + // /// + // /// * 'hotkey' (T::AccountId): + // /// - The associated hotkey account. + // /// + // /// * 'netuid' (u16): + // /// - Subnetwork UID + // /// + // /// * 'amount_staked' (u64): + // /// - The amount of stake to be added to the hotkey staking account. + // /// + // /// * 'limit_price' (u64): + // /// - The limit price expressed in units of RAO per one Alpha. + // /// + // /// * 'allow_partial' (bool): + // /// - Allows partial execution of the amount. If set to false, this becomes + // /// fill or kill type or order. + // /// + // /// # Event: + // /// * StakeAdded; + // /// - On the successfully adding stake to a global account. + // /// + // /// # Raises: + // /// * 'NotEnoughBalanceToStake': + // /// - Not enough balance on the coldkey to add onto the global account. + // /// + // /// * 'NonAssociatedColdKey': + // /// - The calling coldkey is not associated with this hotkey. + // /// + // /// * 'BalanceWithdrawalError': + // /// - Errors stemming from transaction pallet. + // /// + // #[pallet::call_index(105)] + // #[pallet::weight((Weight::from_parts(169_200_000, 5127) + // .saturating_add(T::DbWeight::get().reads(14_u64)) + // .saturating_add(T::DbWeight::get().writes(12_u64)), DispatchClass::Normal, Pays::No))] + // pub fn add_stake_limit_aggregate( + // origin: OriginFor, + // hotkey: T::AccountId, + // netuid: u16, + // amount_staked: u64, + // limit_price: u64, + // allow_partial: bool, + // ) -> DispatchResult { + // Self::do_add_stake_limit_aggregate( + // origin, + // hotkey, + // netuid, + // amount_staked, + // limit_price, + // allow_partial, + // ) + // } + + // /// --- Removes stake from a hotkey on a subnet with a price limit. + // /// This extrinsic allows to specify the limit price for alpha token + // /// at which or better (higher) the staking should execute. + // /// + // /// In case if slippage occurs and the price shall move beyond the limit + // /// price, the staking order may execute only partially or not execute + // /// at all. + // /// + // /// The operation will be delayed. + // /// + // /// # Args: + // /// * 'origin': (Origin): + // /// - The signature of the caller's coldkey. + // /// + // /// * 'hotkey' (T::AccountId): + // /// - The associated hotkey account. + // /// + // /// * 'netuid' (u16): + // /// - Subnetwork UID + // /// + // /// * 'amount_unstaked' (u64): + // /// - The amount of stake to be added to the hotkey staking account. + // /// + // /// * 'limit_price' (u64): + // /// - The limit price expressed in units of RAO per one Alpha. + // /// + // /// * 'allow_partial' (bool): + // /// - Allows partial execution of the amount. If set to false, this becomes + // /// fill or kill type or order. + // /// + // /// # Event: + // /// * StakeRemoved; + // /// - On the successfully removing stake from the hotkey account. + // /// + // /// # Raises: + // /// * 'NotRegistered': + // /// - Thrown if the account we are attempting to unstake from is non existent. + // /// + // /// * 'NonAssociatedColdKey': + // /// - Thrown if the coldkey does not own the hotkey we are unstaking from. + // /// + // /// * 'NotEnoughStakeToWithdraw': + // /// - Thrown if there is not enough stake on the hotkey to withdwraw this amount. + // /// + // #[pallet::call_index(106)] + // #[pallet::weight((Weight::from_parts(211_700_000, 10163) + // .saturating_add(T::DbWeight::get().reads(19_u64)) + // .saturating_add(T::DbWeight::get().writes(12_u64)), DispatchClass::Normal, Pays::No))] + // pub fn remove_stake_limit_aggregate( + // origin: OriginFor, + // hotkey: T::AccountId, + // netuid: u16, + // amount_unstaked: u64, + // limit_price: u64, + // allow_partial: bool, + // ) -> DispatchResult { + // Self::do_remove_stake_limit_aggregate( + // origin, + // hotkey, + // netuid, + // amount_unstaked, + // limit_price, + // allow_partial, + // ) + // } + + // /// ---- The implementation for the extrinsic unstake_all_aggregate: Removes all stake from a hotkey account across all subnets and adds it onto a coldkey. + // /// + // /// The operation will be delayed. + // /// + // /// # Args: + // /// * `origin` - (::Origin): + // /// - The signature of the caller's coldkey. + // /// + // /// * `hotkey` (T::AccountId): + // /// - The associated hotkey account. + // /// + // /// # Event: + // /// * StakeRemoved; + // /// - On the successfully removing stake from the hotkey account. + // /// + // /// # Raises: + // /// * `NotRegistered`: + // /// - Thrown if the account we are attempting to unstake from is non existent. + // /// + // /// * `NonAssociatedColdKey`: + // /// - Thrown if the coldkey does not own the hotkey we are unstaking from. + // /// + // /// * `NotEnoughStakeToWithdraw`: + // /// - Thrown if there is not enough stake on the hotkey to withdraw this amount. + // /// + // /// * `TxRateLimitExceeded`: + // /// - Thrown if key has hit transaction rate limit + // #[pallet::call_index(107)] + // #[pallet::weight((Weight::from_parts(3_000_000, 0).saturating_add(T::DbWeight::get().writes(1)), DispatchClass::Operational, Pays::No))] + // pub fn unstake_all_aggregate(origin: OriginFor, hotkey: T::AccountId) -> DispatchResult { + // Self::do_unstake_all_aggregate(origin, hotkey) + // } + + // /// ---- The implementation for the extrinsic unstake_all_alpha_aggregate: Removes all stake from a hotkey account across all subnets and adds it onto a coldkey. + // /// + // /// The operation will be delayed. + // /// + // /// # Args: + // /// * `origin` - (::Origin): + // /// - The signature of the caller's coldkey. + // /// + // /// * `hotkey` (T::AccountId): + // /// - The associated hotkey account. + // #[pallet::call_index(108)] + // #[pallet::weight((Weight::from_parts(3_000_000, 0).saturating_add(T::DbWeight::get().writes(1)), DispatchClass::Operational, Pays::No))] + // pub fn unstake_all_alpha_aggregate( + // origin: OriginFor, + // hotkey: T::AccountId, + // ) -> DispatchResult { + // Self::do_unstake_all_alpha_aggregate(origin, hotkey) + // } } } diff --git a/pallets/subtensor/src/macros/hooks.rs b/pallets/subtensor/src/macros/hooks.rs index 78de392218..a0e2fc6e72 100644 --- a/pallets/subtensor/src/macros/hooks.rs +++ b/pallets/subtensor/src/macros/hooks.rs @@ -39,8 +39,8 @@ mod hooks { // # Args: // * 'n': (BlockNumberFor): // - The number of the block we are finalizing. - fn on_finalize(block_number: BlockNumberFor) { - Self::do_on_finalize(block_number); + fn on_finalize(_block_number: BlockNumberFor) { + // Self::do_on_finalize(block_number); } fn on_runtime_upgrade() -> frame_support::weights::Weight { diff --git a/pallets/subtensor/src/staking/stake_utils.rs b/pallets/subtensor/src/staking/stake_utils.rs index 65280c8a43..b7010185f7 100644 --- a/pallets/subtensor/src/staking/stake_utils.rs +++ b/pallets/subtensor/src/staking/stake_utils.rs @@ -1,8 +1,8 @@ use super::*; -use frame_system::pallet_prelude::BlockNumberFor; +//use frame_system::pallet_prelude::BlockNumberFor; use safe_math::*; use share_pool::{SharePool, SharePoolDataOperations}; -use sp_runtime::Saturating; +//use sp_runtime::Saturating; use sp_std::ops::Neg; use substrate_fixed::types::{I64F64, I96F32, U64F64, U96F32, U110F18}; @@ -1170,367 +1170,367 @@ impl Pallet { } } - // Process staking job for on_finalize() hook. - pub(crate) fn do_on_finalize(current_block_number: BlockNumberFor) { - // We delay job execution - const DELAY_IN_BLOCKS: u32 = 1u32; - let actual_block_with_delay = current_block_number.saturating_sub(DELAY_IN_BLOCKS.into()); - - let stake_jobs = StakeJobs::::drain_prefix(actual_block_with_delay).collect::>(); - - // Sort jobs by job type - let mut add_stake = vec![]; - let mut remove_stake = vec![]; - let mut add_stake_limit = vec![]; - let mut remove_stake_limit = vec![]; - let mut unstake_all = vec![]; - let mut unstake_all_aplha = vec![]; - - for (_, job) in stake_jobs.into_iter() { - match &job { - StakeJob::AddStake { .. } => add_stake.push(job), - StakeJob::RemoveStake { .. } => remove_stake.push(job), - StakeJob::AddStakeLimit { .. } => add_stake_limit.push(job), - StakeJob::RemoveStakeLimit { .. } => remove_stake_limit.push(job), - StakeJob::UnstakeAll { .. } => unstake_all.push(job), - StakeJob::UnstakeAllAlpha { .. } => unstake_all_aplha.push(job), - } - } - // Reorder jobs based on the previous block hash - let previous_block_hash = >::parent_hash(); - let hash_bytes = previous_block_hash.as_ref(); - let first_byte = hash_bytes.first().expect("hash operation is infallible"); - // Extract the first bit - let altered_order = (first_byte & 0b10000000) != 0; - - // Ascending sort by coldkey - remove_stake_limit.sort_by(|a, b| match (a, b) { - ( - StakeJob::RemoveStakeLimit { coldkey: a_key, .. }, - StakeJob::RemoveStakeLimit { coldkey: b_key, .. }, - ) => { - let direct_order = a_key.cmp(b_key); // ascending - - if altered_order { - direct_order.reverse() - } else { - direct_order - } - } - _ => sp_std::cmp::Ordering::Equal, // unreachable - }); - - remove_stake.sort_by(|a, b| match (a, b) { - ( - StakeJob::RemoveStake { coldkey: a_key, .. }, - StakeJob::RemoveStake { coldkey: b_key, .. }, - ) => { - let direct_order = a_key.cmp(b_key); // ascending - - if altered_order { - direct_order.reverse() - } else { - direct_order - } - } - _ => sp_std::cmp::Ordering::Equal, // unreachable - }); - - unstake_all.sort_by(|a, b| match (a, b) { - ( - StakeJob::UnstakeAll { coldkey: a_key, .. }, - StakeJob::UnstakeAll { coldkey: b_key, .. }, - ) => { - let direct_order = a_key.cmp(b_key); // ascending - - if altered_order { - direct_order.reverse() - } else { - direct_order - } - } - _ => sp_std::cmp::Ordering::Equal, // unreachable - }); - - unstake_all_aplha.sort_by(|a, b| match (a, b) { - ( - StakeJob::UnstakeAllAlpha { coldkey: a_key, .. }, - StakeJob::UnstakeAllAlpha { coldkey: b_key, .. }, - ) => { - let direct_order = a_key.cmp(b_key); // ascending - - if altered_order { - direct_order.reverse() - } else { - direct_order - } - } - _ => sp_std::cmp::Ordering::Equal, // unreachable - }); - - // Descending sort by coldkey - add_stake_limit.sort_by(|a, b| match (a, b) { - ( - StakeJob::AddStakeLimit { coldkey: a_key, .. }, - StakeJob::AddStakeLimit { coldkey: b_key, .. }, - ) => { - let direct_order = b_key.cmp(a_key); // descending - - if altered_order { - direct_order.reverse() - } else { - direct_order - } - } - _ => sp_std::cmp::Ordering::Equal, // unreachable - }); - - add_stake.sort_by(|a, b| match (a, b) { - ( - StakeJob::AddStake { coldkey: a_key, .. }, - StakeJob::AddStake { coldkey: b_key, .. }, - ) => { - let direct_order = b_key.cmp(a_key); // descending - - if altered_order { - direct_order.reverse() - } else { - direct_order - } - } - _ => sp_std::cmp::Ordering::Equal, // unreachable - }); - - // direct job order - let mut job_batches = vec![ - remove_stake_limit, - remove_stake, - unstake_all, - unstake_all_aplha, - add_stake_limit, - add_stake, - ]; - if altered_order { - job_batches.reverse(); - } - - for jobs in job_batches.into_iter() { - for job in jobs.into_iter() { - match job { - StakeJob::RemoveStakeLimit { - hotkey, - coldkey, - netuid, - alpha_unstaked, - limit_price, - allow_partial, - } => { - let result = Self::do_remove_stake_limit( - dispatch::RawOrigin::Signed(coldkey.clone()).into(), - hotkey.clone(), - netuid, - alpha_unstaked, - limit_price, - allow_partial, - ); - - if let Err(err) = result { - log::debug!( - "Failed to remove aggregated limited stake: {:?}, {:?}, {:?}, {:?}, {:?}, {:?}, {:?}", - coldkey, - hotkey, - netuid, - alpha_unstaked, - limit_price, - allow_partial, - err - ); - Self::deposit_event(Event::FailedToRemoveAggregatedLimitedStake( - coldkey, - hotkey, - netuid, - alpha_unstaked, - limit_price, - allow_partial, - )); - } else { - Self::deposit_event(Event::AggregatedLimitedStakeRemoved( - coldkey, - hotkey, - netuid, - alpha_unstaked, - limit_price, - allow_partial, - )); - } - } - StakeJob::RemoveStake { - coldkey, - hotkey, - netuid, - alpha_unstaked, - } => { - let result = Self::do_remove_stake( - dispatch::RawOrigin::Signed(coldkey.clone()).into(), - hotkey.clone(), - netuid, - alpha_unstaked, - ); - - if let Err(err) = result { - log::debug!( - "Failed to remove aggregated stake: {:?}, {:?}, {:?}, {:?}, {:?}", - coldkey, - hotkey, - netuid, - alpha_unstaked, - err - ); - Self::deposit_event(Event::FailedToRemoveAggregatedStake( - coldkey, - hotkey, - netuid, - alpha_unstaked, - )); - } else { - Self::deposit_event(Event::AggregatedStakeRemoved( - coldkey, - hotkey, - netuid, - alpha_unstaked, - )); - } - } - StakeJob::UnstakeAll { hotkey, coldkey } => { - let result = Self::do_unstake_all( - dispatch::RawOrigin::Signed(coldkey.clone()).into(), - hotkey.clone(), - ); - - if let Err(err) = result { - log::debug!( - "Failed to unstake all: {:?}, {:?}, {:?}", - coldkey, - hotkey, - err - ); - Self::deposit_event(Event::AggregatedUnstakeAllFailed(coldkey, hotkey)); - } else { - Self::deposit_event(Event::AggregatedUnstakeAllSucceeded( - coldkey, hotkey, - )); - } - } - StakeJob::UnstakeAllAlpha { hotkey, coldkey } => { - let result = Self::do_unstake_all_alpha( - dispatch::RawOrigin::Signed(coldkey.clone()).into(), - hotkey.clone(), - ); - - if let Err(err) = result { - log::debug!( - "Failed to unstake all alpha: {:?}, {:?}, {:?}", - coldkey, - hotkey, - err - ); - Self::deposit_event(Event::AggregatedUnstakeAllAlphaFailed( - coldkey, hotkey, - )); - } else { - Self::deposit_event(Event::AggregatedUnstakeAllAlphaSucceeded( - coldkey, hotkey, - )); - } - } - StakeJob::AddStakeLimit { - hotkey, - coldkey, - netuid, - stake_to_be_added, - limit_price, - allow_partial, - } => { - let result = Self::do_add_stake_limit( - dispatch::RawOrigin::Signed(coldkey.clone()).into(), - hotkey.clone(), - netuid, - stake_to_be_added, - limit_price, - allow_partial, - ); - - if let Err(err) = result { - log::debug!( - "Failed to add aggregated limited stake: {:?}, {:?}, {:?}, {:?}, {:?}, {:?}, {:?}", - coldkey, - hotkey, - netuid, - stake_to_be_added, - limit_price, - allow_partial, - err - ); - Self::deposit_event(Event::FailedToAddAggregatedLimitedStake( - coldkey, - hotkey, - netuid, - stake_to_be_added, - limit_price, - allow_partial, - )); - } else { - Self::deposit_event(Event::AggregatedLimitedStakeAdded( - coldkey, - hotkey, - netuid, - stake_to_be_added, - limit_price, - allow_partial, - )); - } - } - StakeJob::AddStake { - hotkey, - coldkey, - netuid, - stake_to_be_added, - } => { - let result = Self::do_add_stake( - dispatch::RawOrigin::Signed(coldkey.clone()).into(), - hotkey.clone(), - netuid, - stake_to_be_added, - ); - - if let Err(err) = result { - log::debug!( - "Failed to add aggregated stake: {:?}, {:?}, {:?}, {:?}, {:?}", - coldkey, - hotkey, - netuid, - stake_to_be_added, - err - ); - Self::deposit_event(Event::FailedToAddAggregatedStake( - coldkey, - hotkey, - netuid, - stake_to_be_added, - )); - } else { - Self::deposit_event(Event::AggregatedStakeAdded( - coldkey, - hotkey, - netuid, - stake_to_be_added, - )); - } - } - } - } - } - } + // // Process staking job for on_finalize() hook. + // pub(crate) fn do_on_finalize(current_block_number: BlockNumberFor) { + // // We delay job execution + // const DELAY_IN_BLOCKS: u32 = 1u32; + // let actual_block_with_delay = current_block_number.saturating_sub(DELAY_IN_BLOCKS.into()); + // + // let stake_jobs = StakeJobs::::drain_prefix(actual_block_with_delay).collect::>(); + // + // // Sort jobs by job type + // let mut add_stake = vec![]; + // let mut remove_stake = vec![]; + // let mut add_stake_limit = vec![]; + // let mut remove_stake_limit = vec![]; + // let mut unstake_all = vec![]; + // let mut unstake_all_aplha = vec![]; + // + // for (_, job) in stake_jobs.into_iter() { + // match &job { + // StakeJob::AddStake { .. } => add_stake.push(job), + // StakeJob::RemoveStake { .. } => remove_stake.push(job), + // StakeJob::AddStakeLimit { .. } => add_stake_limit.push(job), + // StakeJob::RemoveStakeLimit { .. } => remove_stake_limit.push(job), + // StakeJob::UnstakeAll { .. } => unstake_all.push(job), + // StakeJob::UnstakeAllAlpha { .. } => unstake_all_aplha.push(job), + // } + // } + // // Reorder jobs based on the previous block hash + // let previous_block_hash = >::parent_hash(); + // let hash_bytes = previous_block_hash.as_ref(); + // let first_byte = hash_bytes.first().expect("hash operation is infallible"); + // // Extract the first bit + // let altered_order = (first_byte & 0b10000000) != 0; + // + // // Ascending sort by coldkey + // remove_stake_limit.sort_by(|a, b| match (a, b) { + // ( + // StakeJob::RemoveStakeLimit { coldkey: a_key, .. }, + // StakeJob::RemoveStakeLimit { coldkey: b_key, .. }, + // ) => { + // let direct_order = a_key.cmp(b_key); // ascending + // + // if altered_order { + // direct_order.reverse() + // } else { + // direct_order + // } + // } + // _ => sp_std::cmp::Ordering::Equal, // unreachable + // }); + // + // remove_stake.sort_by(|a, b| match (a, b) { + // ( + // StakeJob::RemoveStake { coldkey: a_key, .. }, + // StakeJob::RemoveStake { coldkey: b_key, .. }, + // ) => { + // let direct_order = a_key.cmp(b_key); // ascending + // + // if altered_order { + // direct_order.reverse() + // } else { + // direct_order + // } + // } + // _ => sp_std::cmp::Ordering::Equal, // unreachable + // }); + // + // unstake_all.sort_by(|a, b| match (a, b) { + // ( + // StakeJob::UnstakeAll { coldkey: a_key, .. }, + // StakeJob::UnstakeAll { coldkey: b_key, .. }, + // ) => { + // let direct_order = a_key.cmp(b_key); // ascending + // + // if altered_order { + // direct_order.reverse() + // } else { + // direct_order + // } + // } + // _ => sp_std::cmp::Ordering::Equal, // unreachable + // }); + // + // unstake_all_aplha.sort_by(|a, b| match (a, b) { + // ( + // StakeJob::UnstakeAllAlpha { coldkey: a_key, .. }, + // StakeJob::UnstakeAllAlpha { coldkey: b_key, .. }, + // ) => { + // let direct_order = a_key.cmp(b_key); // ascending + // + // if altered_order { + // direct_order.reverse() + // } else { + // direct_order + // } + // } + // _ => sp_std::cmp::Ordering::Equal, // unreachable + // }); + // + // // Descending sort by coldkey + // add_stake_limit.sort_by(|a, b| match (a, b) { + // ( + // StakeJob::AddStakeLimit { coldkey: a_key, .. }, + // StakeJob::AddStakeLimit { coldkey: b_key, .. }, + // ) => { + // let direct_order = b_key.cmp(a_key); // descending + // + // if altered_order { + // direct_order.reverse() + // } else { + // direct_order + // } + // } + // _ => sp_std::cmp::Ordering::Equal, // unreachable + // }); + // + // add_stake.sort_by(|a, b| match (a, b) { + // ( + // StakeJob::AddStake { coldkey: a_key, .. }, + // StakeJob::AddStake { coldkey: b_key, .. }, + // ) => { + // let direct_order = b_key.cmp(a_key); // descending + // + // if altered_order { + // direct_order.reverse() + // } else { + // direct_order + // } + // } + // _ => sp_std::cmp::Ordering::Equal, // unreachable + // }); + // + // // direct job order + // let mut job_batches = vec![ + // remove_stake_limit, + // remove_stake, + // unstake_all, + // unstake_all_aplha, + // add_stake_limit, + // add_stake, + // ]; + // if altered_order { + // job_batches.reverse(); + // } + // + // for jobs in job_batches.into_iter() { + // for job in jobs.into_iter() { + // match job { + // StakeJob::RemoveStakeLimit { + // hotkey, + // coldkey, + // netuid, + // alpha_unstaked, + // limit_price, + // allow_partial, + // } => { + // let result = Self::do_remove_stake_limit( + // dispatch::RawOrigin::Signed(coldkey.clone()).into(), + // hotkey.clone(), + // netuid, + // alpha_unstaked, + // limit_price, + // allow_partial, + // ); + // + // if let Err(err) = result { + // log::debug!( + // "Failed to remove aggregated limited stake: {:?}, {:?}, {:?}, {:?}, {:?}, {:?}, {:?}", + // coldkey, + // hotkey, + // netuid, + // alpha_unstaked, + // limit_price, + // allow_partial, + // err + // ); + // Self::deposit_event(Event::FailedToRemoveAggregatedLimitedStake( + // coldkey, + // hotkey, + // netuid, + // alpha_unstaked, + // limit_price, + // allow_partial, + // )); + // } else { + // Self::deposit_event(Event::AggregatedLimitedStakeRemoved( + // coldkey, + // hotkey, + // netuid, + // alpha_unstaked, + // limit_price, + // allow_partial, + // )); + // } + // } + // StakeJob::RemoveStake { + // coldkey, + // hotkey, + // netuid, + // alpha_unstaked, + // } => { + // let result = Self::do_remove_stake( + // dispatch::RawOrigin::Signed(coldkey.clone()).into(), + // hotkey.clone(), + // netuid, + // alpha_unstaked, + // ); + // + // if let Err(err) = result { + // log::debug!( + // "Failed to remove aggregated stake: {:?}, {:?}, {:?}, {:?}, {:?}", + // coldkey, + // hotkey, + // netuid, + // alpha_unstaked, + // err + // ); + // Self::deposit_event(Event::FailedToRemoveAggregatedStake( + // coldkey, + // hotkey, + // netuid, + // alpha_unstaked, + // )); + // } else { + // Self::deposit_event(Event::AggregatedStakeRemoved( + // coldkey, + // hotkey, + // netuid, + // alpha_unstaked, + // )); + // } + // } + // StakeJob::UnstakeAll { hotkey, coldkey } => { + // let result = Self::do_unstake_all( + // dispatch::RawOrigin::Signed(coldkey.clone()).into(), + // hotkey.clone(), + // ); + // + // if let Err(err) = result { + // log::debug!( + // "Failed to unstake all: {:?}, {:?}, {:?}", + // coldkey, + // hotkey, + // err + // ); + // Self::deposit_event(Event::AggregatedUnstakeAllFailed(coldkey, hotkey)); + // } else { + // Self::deposit_event(Event::AggregatedUnstakeAllSucceeded( + // coldkey, hotkey, + // )); + // } + // } + // StakeJob::UnstakeAllAlpha { hotkey, coldkey } => { + // let result = Self::do_unstake_all_alpha( + // dispatch::RawOrigin::Signed(coldkey.clone()).into(), + // hotkey.clone(), + // ); + // + // if let Err(err) = result { + // log::debug!( + // "Failed to unstake all alpha: {:?}, {:?}, {:?}", + // coldkey, + // hotkey, + // err + // ); + // Self::deposit_event(Event::AggregatedUnstakeAllAlphaFailed( + // coldkey, hotkey, + // )); + // } else { + // Self::deposit_event(Event::AggregatedUnstakeAllAlphaSucceeded( + // coldkey, hotkey, + // )); + // } + // } + // StakeJob::AddStakeLimit { + // hotkey, + // coldkey, + // netuid, + // stake_to_be_added, + // limit_price, + // allow_partial, + // } => { + // let result = Self::do_add_stake_limit( + // dispatch::RawOrigin::Signed(coldkey.clone()).into(), + // hotkey.clone(), + // netuid, + // stake_to_be_added, + // limit_price, + // allow_partial, + // ); + // + // if let Err(err) = result { + // log::debug!( + // "Failed to add aggregated limited stake: {:?}, {:?}, {:?}, {:?}, {:?}, {:?}, {:?}", + // coldkey, + // hotkey, + // netuid, + // stake_to_be_added, + // limit_price, + // allow_partial, + // err + // ); + // Self::deposit_event(Event::FailedToAddAggregatedLimitedStake( + // coldkey, + // hotkey, + // netuid, + // stake_to_be_added, + // limit_price, + // allow_partial, + // )); + // } else { + // Self::deposit_event(Event::AggregatedLimitedStakeAdded( + // coldkey, + // hotkey, + // netuid, + // stake_to_be_added, + // limit_price, + // allow_partial, + // )); + // } + // } + // StakeJob::AddStake { + // hotkey, + // coldkey, + // netuid, + // stake_to_be_added, + // } => { + // let result = Self::do_add_stake( + // dispatch::RawOrigin::Signed(coldkey.clone()).into(), + // hotkey.clone(), + // netuid, + // stake_to_be_added, + // ); + // + // if let Err(err) = result { + // log::debug!( + // "Failed to add aggregated stake: {:?}, {:?}, {:?}, {:?}, {:?}", + // coldkey, + // hotkey, + // netuid, + // stake_to_be_added, + // err + // ); + // Self::deposit_event(Event::FailedToAddAggregatedStake( + // coldkey, + // hotkey, + // netuid, + // stake_to_be_added, + // )); + // } else { + // Self::deposit_event(Event::AggregatedStakeAdded( + // coldkey, + // hotkey, + // netuid, + // stake_to_be_added, + // )); + // } + // } + // } + // } + // } + // } } /////////////////////////////////////////// diff --git a/pallets/subtensor/src/tests/staking.rs b/pallets/subtensor/src/tests/staking.rs index 8172cab9da..9a672676ee 100644 --- a/pallets/subtensor/src/tests/staking.rs +++ b/pallets/subtensor/src/tests/staking.rs @@ -89,873 +89,873 @@ fn test_add_stake_ok_no_emission() { ); }); } -#[test] -fn test_add_stake_aggregate_ok_no_emission() { - new_test_ext(1).execute_with(|| { - let hotkey_account_id = U256::from(533453); - let coldkey_account_id = U256::from(55453); - let amount = DefaultMinStake::::get() * 10; - let fee = DefaultStakingFee::::get(); - - //add network - let netuid: u16 = add_dynamic_network(&hotkey_account_id, &coldkey_account_id); - - // Give it some $$$ in his coldkey balance - SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, amount); - - // Check we have zero staked before transfer - assert_eq!( - SubtensorModule::get_total_stake_for_hotkey(&hotkey_account_id), - 0 - ); - - // Also total stake should be equal to the network initial lock - assert_eq!( - SubtensorModule::get_total_stake(), - SubtensorModule::get_network_min_lock() - ); - - // Transfer to hotkey account, and check if the result is ok - assert_ok!(SubtensorModule::add_stake_aggregate( - RuntimeOrigin::signed(coldkey_account_id), - hotkey_account_id, - netuid, - amount - )); - - // Ensure that extrinsic call doesn't change the stake. - assert_eq!( - SubtensorModule::get_total_stake(), - SubtensorModule::get_network_min_lock() - ); - - // Check for the block delay - run_to_block_ext(2, true); - - // Check that event was not emitted. - assert!(System::events().iter().all(|e| { - !matches!( - &e.event, - RuntimeEvent::SubtensorModule(Event::AggregatedStakeAdded(..)) - ) - })); - - // Enable on_finalize code to run - run_to_block_ext(3, true); - - // Check if stake has increased - assert_abs_diff_eq!( - SubtensorModule::get_total_stake_for_hotkey(&hotkey_account_id), - amount - fee, - epsilon = amount / 1000, - ); - - // Check if balance has decreased - assert_eq!(SubtensorModule::get_coldkey_balance(&coldkey_account_id), 1); - - // Check if total stake has increased accordingly. - assert_eq!( - SubtensorModule::get_total_stake(), - amount + SubtensorModule::get_network_min_lock() - ); - - // Check that event was emitted. - assert!(System::events().iter().any(|e| { - matches!( - &e.event, - RuntimeEvent::SubtensorModule(Event::StakeAdded(..)) - ) - })); - - // Check that event was emitted. - assert!(System::events().iter().any(|e| { - matches!( - &e.event, - RuntimeEvent::SubtensorModule(Event::AggregatedStakeAdded(..)) - ) - })); - }); -} - -#[test] -fn test_add_stake_aggregate_failed() { - new_test_ext(1).execute_with(|| { - let hotkey_account_id = U256::from(533453); - let coldkey_account_id = U256::from(55453); - let amount = DefaultMinStake::::get() * 100; - //add network - let netuid: u16 = add_dynamic_network(&hotkey_account_id, &coldkey_account_id); - - // Transfer to hotkey account, and check if the result is ok - assert_ok!(SubtensorModule::add_stake_aggregate( - RuntimeOrigin::signed(coldkey_account_id), - hotkey_account_id, - netuid, - amount - )); - - // Check for the block delay - run_to_block_ext(2, true); - - // Check that event was not emitted. - assert!(System::events().iter().all(|e| { - !matches!( - &e.event, - RuntimeEvent::SubtensorModule(Event::FailedToAddAggregatedStake(..)) - ) - })); - - // Enable on_finalize code to run - run_to_block_ext(3, true); - - // Check that event was emitted. - assert!(System::events().iter().any(|e| { - matches!( - &e.event, - RuntimeEvent::SubtensorModule(Event::FailedToAddAggregatedStake(..)) - ) - })); - }); -} - -#[test] -fn test_verify_aggregated_stake_order() { - new_test_ext(1).execute_with(|| { - let hotkey_account_id = U256::from(533453); - let coldkey_account_id = U256::from(55453); - let amount = 1_000_000_000_000u64; - let limit_price = 6_000_000_000u64; - let unstake_amount = 150_000_000_000u64; - let limit_price2 = 1_350_000_000; - - // add network - let netuid1: u16 = add_dynamic_network(&hotkey_account_id, &coldkey_account_id); - let netuid2: u16 = add_dynamic_network(&hotkey_account_id, &coldkey_account_id); - let netuid3: u16 = add_dynamic_network(&hotkey_account_id, &coldkey_account_id); - let netuid4: u16 = add_dynamic_network(&hotkey_account_id, &coldkey_account_id); - let netuid5: u16 = add_dynamic_network(&hotkey_account_id, &coldkey_account_id); - let netuid6: u16 = add_dynamic_network(&hotkey_account_id, &coldkey_account_id); - - let tao_reserve: U96F32 = U96F32::from_num(1_500_000_000_000_u64); - let alpha_in: U96F32 = U96F32::from_num(1_000_000_000_000_u64); - - for netuid in [netuid1, netuid3, netuid3, netuid4, netuid5, netuid6] { - SubnetTAO::::insert(netuid, tao_reserve.to_num::()); - SubnetAlphaIn::::insert(netuid, alpha_in.to_num::()); - } - - // Give it some $$$ in his coldkey balance - SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, 6 * amount); - // Give the neuron some stake to remove - SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( - &hotkey_account_id, - &coldkey_account_id, - netuid3, - amount, - ); - SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( - &hotkey_account_id, - &coldkey_account_id, - netuid4, - amount, - ); - - // Add stake with slippage safety and check if the result is ok - assert_ok!(SubtensorModule::remove_stake_aggregate( - RuntimeOrigin::signed(coldkey_account_id), - hotkey_account_id, - netuid3, - amount - )); - - assert_ok!(SubtensorModule::remove_stake_limit_aggregate( - RuntimeOrigin::signed(coldkey_account_id), - hotkey_account_id, - netuid4, - unstake_amount, - limit_price2, - true - )); - - assert_ok!(SubtensorModule::add_stake_aggregate( - RuntimeOrigin::signed(coldkey_account_id), - hotkey_account_id, - netuid1, - amount, - )); - - assert_ok!(SubtensorModule::add_stake_limit_aggregate( - RuntimeOrigin::signed(coldkey_account_id), - hotkey_account_id, - netuid2, - amount, - limit_price, - true - )); - - assert_ok!(SubtensorModule::unstake_all_aggregate( - RuntimeOrigin::signed(coldkey_account_id), - hotkey_account_id, - )); - - assert_ok!(SubtensorModule::unstake_all_alpha_aggregate( - RuntimeOrigin::signed(coldkey_account_id), - hotkey_account_id, - )); - - // Enable on_finalize code to run - run_to_block_ext(3, true); - - let add_stake_position = System::events() - .iter() - .position(|e| { - if let RuntimeEvent::SubtensorModule(Event::AggregatedStakeAdded(.., netuid, _)) = - e.event - { - netuid == netuid1 - } else { - false - } - }) - .expect("Stake event must be present in the event log."); - - let add_stake_limit_position = System::events() - .iter() - .position(|e| { - if let RuntimeEvent::SubtensorModule(Event::AggregatedLimitedStakeAdded( - _, - _, - netuid, - _, - _, - _, - )) = e.event - { - netuid == netuid2 - } else { - false - } - }) - .expect("Stake event must be present in the event log."); - - let remove_stake_position = System::events() - .iter() - .position(|e| { - if let RuntimeEvent::SubtensorModule(Event::AggregatedStakeRemoved(.., netuid, _)) = - e.event - { - netuid == netuid3 - } else { - false - } - }) - .expect("Stake event must be present in the event log."); - - let remove_stake_limit_position = System::events() - .iter() - .position(|e| { - if let RuntimeEvent::SubtensorModule(Event::AggregatedLimitedStakeRemoved( - .., - netuid, - _, - _, - _, - )) = e.event - { - netuid == netuid4 - } else { - false - } - }) - .expect("Stake event must be present in the event log."); - - let unstake_all_position = System::events() - .iter() - .position(|e| { - matches!( - e.event, - RuntimeEvent::SubtensorModule(Event::AggregatedUnstakeAllSucceeded(..)) - ) - }) - .expect("Stake event must be present in the event log."); - - let unstake_all_alpha_position = System::events() - .iter() - .position(|e| { - matches!( - e.event, - RuntimeEvent::SubtensorModule(Event::AggregatedUnstakeAllAlphaSucceeded(..)) - ) - }) - .expect("Stake event must be present in the event log."); - - // Check events order - assert!(remove_stake_limit_position < remove_stake_position); - assert!(remove_stake_position < unstake_all_position); - assert!(unstake_all_position < unstake_all_alpha_position); - assert!(add_stake_position > unstake_all_alpha_position); - assert!(add_stake_limit_position < add_stake_position); - }); -} - -#[test] -#[allow(clippy::indexing_slicing)] -fn test_verify_aggregated_stake_order_reversed() { - new_test_ext(1).execute_with(|| { - let amount = 1_000_000_000_000u64; - let limit_price = 6_000_000_000u64; - let unstake_amount = 150_000_000_000u64; - let limit_price2 = 1_350_000_000; - - // Coldkeys and hotkeys - let coldkeys = vec![ - U256::from(100), // add_stake - U256::from(200), // add_stake_limit - U256::from(300), // remove_stake - U256::from(400), // remove_stake_limit - U256::from(500), // unstake_all - U256::from(600), // unstake_all_alpha - ]; - - let hotkeys = (1..=6).map(U256::from).collect::>(); - - let netuids: Vec<_> = hotkeys - .iter() - .zip(coldkeys.iter()) - .map(|(h, c)| add_dynamic_network(h, c)) - .collect(); - - let tao_reserve = U96F32::from_num(1_500_000_000_000u64); - let alpha_in = U96F32::from_num(1_000_000_000_000u64); - - for netuid in &netuids { - SubnetTAO::::insert(*netuid, tao_reserve.to_num::()); - SubnetAlphaIn::::insert(*netuid, alpha_in.to_num::()); - } - - for coldkey in &coldkeys { - SubtensorModule::add_balance_to_coldkey_account(coldkey, amount); - } - - for ((hotkey, coldkey), netuid) in hotkeys.iter().zip(coldkeys.iter()).zip(netuids.iter()) { - SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( - hotkey, coldkey, *netuid, amount, - ); - } - - // Add stake with slippage safety and check if the result is ok - assert_ok!(SubtensorModule::remove_stake_aggregate( - RuntimeOrigin::signed(coldkeys[2]), - hotkeys[2], - netuids[2], - amount - )); - - assert_ok!(SubtensorModule::remove_stake_limit_aggregate( - RuntimeOrigin::signed(coldkeys[3]), - hotkeys[3], - netuids[3], - unstake_amount, - limit_price2, - true - )); - - assert_ok!(SubtensorModule::add_stake_aggregate( - RuntimeOrigin::signed(coldkeys[0]), - hotkeys[0], - netuids[0], - amount, - )); - - assert_ok!(SubtensorModule::add_stake_limit_aggregate( - RuntimeOrigin::signed(coldkeys[1]), - hotkeys[1], - netuids[1], - amount, - limit_price, - true - )); - - assert_ok!(SubtensorModule::unstake_all_aggregate( - RuntimeOrigin::signed(coldkeys[4]), - hotkeys[4], - )); - - assert_ok!(SubtensorModule::unstake_all_alpha_aggregate( - RuntimeOrigin::signed(coldkeys[5]), - hotkeys[5], - )); - - // Enable on_finalize code to run - run_to_block_ext(2, false); - // Reorder jobs based on the previous block hash - let mut parent_hash = >::parent_hash(); - parent_hash.as_mut()[0] = 0b10000000; - >::set_parent_hash(parent_hash); - - // Enable on_finalize code to run - run_to_block_ext(3, true); - - let add_stake_position = System::events() - .iter() - .position(|e| { - if let RuntimeEvent::SubtensorModule(Event::AggregatedStakeAdded(.., netuid, _)) = - e.event - { - netuid == netuids[0] - } else { - false - } - }) - .expect("Stake event must be present in the event log."); - - let add_stake_limit_position = System::events() - .iter() - .position(|e| { - if let RuntimeEvent::SubtensorModule(Event::AggregatedLimitedStakeAdded( - _, - _, - netuid, - _, - _, - _, - )) = e.event - { - netuid == netuids[1] - } else { - false - } - }) - .expect("Stake event must be present in the event log."); - - let remove_stake_position = System::events() - .iter() - .position(|e| { - if let RuntimeEvent::SubtensorModule(Event::AggregatedStakeRemoved(.., netuid, _)) = - e.event - { - netuid == netuids[2] - } else { - false - } - }) - .expect("Stake event must be present in the event log."); - - let remove_stake_limit_position = System::events() - .iter() - .position(|e| { - if let RuntimeEvent::SubtensorModule(Event::AggregatedLimitedStakeRemoved( - .., - netuid, - _, - _, - _, - )) = e.event - { - netuid == netuids[3] - } else { - false - } - }) - .expect("Stake event must be present in the event log."); - - let unstake_all_position = System::events() - .iter() - .position(|e| { - matches!( - e.event, - RuntimeEvent::SubtensorModule(Event::AggregatedUnstakeAllSucceeded(..)) - ) - }) - .expect("Stake event must be present in the event log."); - - let unstake_all_alpha_position = System::events() - .iter() - .position(|e| { - matches!( - e.event, - RuntimeEvent::SubtensorModule(Event::AggregatedUnstakeAllAlphaSucceeded(..)) - ) - }) - .expect("Stake event must be present in the event log."); - - // Check events order - assert!(add_stake_limit_position > add_stake_position); - assert!(add_stake_position < unstake_all_alpha_position); - assert!(unstake_all_position > unstake_all_alpha_position); - assert!(remove_stake_position > unstake_all_position); - assert!(remove_stake_limit_position > remove_stake_position); - }); -} - -#[test] -#[allow(clippy::indexing_slicing)] -fn test_verify_all_job_type_sort_by_coldkey() { - new_test_ext(1).execute_with(|| { - let amount = 1_000_000_000_000u64; - let limit_price = 6_000_000_000u64; - let unstake_amount = 150_000_000_000u64; - let limit_price2 = 1_350_000_000; - - // Coldkeys and hotkeys - let coldkeys = vec![ - U256::from(100), // add_stake - U256::from(200), // add_stake - U256::from(300), // add_stake_limit - U256::from(400), // add_stake_limit - U256::from(500), // remove_stake - U256::from(600), // remove_stake - U256::from(700), // remove_stake_limit - U256::from(800), // remove_stake_limit - U256::from(900), // unstake_all - U256::from(1000), // unstake_all - U256::from(1100), // unstake_all_alpha - U256::from(1200), // unstake_all_alpha - ]; - - let hotkeys = (1..=12).map(U256::from).collect::>(); - - let netuids: Vec<_> = hotkeys - .iter() - .zip(coldkeys.iter()) - .map(|(h, c)| add_dynamic_network(h, c)) - .collect(); - - let tao_reserve = U96F32::from_num(1_500_000_000_000u64); - let alpha_in = U96F32::from_num(1_000_000_000_000u64); - - for netuid in &netuids { - SubnetTAO::::insert(*netuid, tao_reserve.to_num::()); - SubnetAlphaIn::::insert(*netuid, alpha_in.to_num::()); - } - - for coldkey in &coldkeys { - SubtensorModule::add_balance_to_coldkey_account(coldkey, amount); - } - - for ((hotkey, coldkey), netuid) in hotkeys.iter().zip(coldkeys.iter()).zip(netuids.iter()) { - SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( - hotkey, coldkey, *netuid, amount, - ); - } - - // === Submit all job types === - - assert_ok!(SubtensorModule::add_stake_aggregate( - RuntimeOrigin::signed(coldkeys[0]), - hotkeys[0], - netuids[0], - amount - )); - assert_ok!(SubtensorModule::add_stake_aggregate( - RuntimeOrigin::signed(coldkeys[1]), - hotkeys[1], - netuids[1], - amount - )); - - assert_ok!(SubtensorModule::add_stake_limit_aggregate( - RuntimeOrigin::signed(coldkeys[2]), - hotkeys[2], - netuids[2], - amount, - limit_price, - true - )); - assert_ok!(SubtensorModule::add_stake_limit_aggregate( - RuntimeOrigin::signed(coldkeys[3]), - hotkeys[3], - netuids[3], - amount, - limit_price, - true - )); - - assert_ok!(SubtensorModule::remove_stake_aggregate( - RuntimeOrigin::signed(coldkeys[4]), - hotkeys[4], - netuids[4], - amount - )); - assert_ok!(SubtensorModule::remove_stake_aggregate( - RuntimeOrigin::signed(coldkeys[5]), - hotkeys[5], - netuids[5], - amount - )); - - assert_ok!(SubtensorModule::remove_stake_limit_aggregate( - RuntimeOrigin::signed(coldkeys[6]), - hotkeys[6], - netuids[6], - unstake_amount, - limit_price2, - true - )); - assert_ok!(SubtensorModule::remove_stake_limit_aggregate( - RuntimeOrigin::signed(coldkeys[7]), - hotkeys[7], - netuids[7], - unstake_amount, - limit_price2, - true - )); - - assert_ok!(SubtensorModule::unstake_all_aggregate( - RuntimeOrigin::signed(coldkeys[8]), - hotkeys[8], - )); - assert_ok!(SubtensorModule::unstake_all_aggregate( - RuntimeOrigin::signed(coldkeys[9]), - hotkeys[9], - )); - - assert_ok!(SubtensorModule::unstake_all_alpha_aggregate( - RuntimeOrigin::signed(coldkeys[10]), - hotkeys[10], - )); - assert_ok!(SubtensorModule::unstake_all_alpha_aggregate( - RuntimeOrigin::signed(coldkeys[11]), - hotkeys[11], - )); - - // Finalize block - run_to_block_ext(3, true); - - // === Collect coldkeys by event type === - let mut add_coldkeys = vec![]; - let mut add_limit_coldkeys = vec![]; - let mut remove_coldkeys = vec![]; - let mut remove_limit_coldkeys = vec![]; - let mut unstake_all_coldkeys = vec![]; - let mut unstake_all_alpha_coldkeys = vec![]; - - for event in System::events().iter().map(|e| &e.event) { - match event { - RuntimeEvent::SubtensorModule(Event::AggregatedStakeAdded(coldkey, ..)) => { - add_coldkeys.push(*coldkey); - } - RuntimeEvent::SubtensorModule(Event::AggregatedLimitedStakeAdded(coldkey, ..)) => { - add_limit_coldkeys.push(*coldkey); - } - RuntimeEvent::SubtensorModule(Event::AggregatedStakeRemoved(coldkey, ..)) => { - remove_coldkeys.push(*coldkey); - } - RuntimeEvent::SubtensorModule(Event::AggregatedLimitedStakeRemoved( - coldkey, - .., - )) => { - remove_limit_coldkeys.push(*coldkey); - } - RuntimeEvent::SubtensorModule(Event::AggregatedUnstakeAllSucceeded(coldkey, _)) => { - unstake_all_coldkeys.push(*coldkey); - } - RuntimeEvent::SubtensorModule(Event::AggregatedUnstakeAllAlphaSucceeded( - coldkey, - _, - )) => { - unstake_all_alpha_coldkeys.push(*coldkey); - } - _ => {} - } - } - - // === Assertions === - assert_eq!(add_coldkeys, vec![coldkeys[1], coldkeys[0]]); // descending - assert_eq!(add_limit_coldkeys, vec![coldkeys[3], coldkeys[2]]); // descending - assert_eq!(remove_coldkeys, vec![coldkeys[4], coldkeys[5]]); // ascending - assert_eq!(remove_limit_coldkeys, vec![coldkeys[6], coldkeys[7]]); // ascending - assert_eq!(unstake_all_coldkeys, vec![coldkeys[8], coldkeys[9]]); // ascending - assert_eq!(unstake_all_alpha_coldkeys, vec![coldkeys[10], coldkeys[11]]); // ascending - }); -} - -#[test] -#[allow(clippy::indexing_slicing)] -fn test_verify_all_job_type_sort_by_coldkey_reverse_order() { - new_test_ext(1).execute_with(|| { - let amount = 1_000_000_000_000u64; - let limit_price = 6_000_000_000u64; - let unstake_amount = 150_000_000_000u64; - let limit_price2 = 1_350_000_000; - - // Coldkeys and hotkeys - let coldkeys = vec![ - U256::from(100), // add_stake - U256::from(200), // add_stake - U256::from(300), // add_stake_limit - U256::from(400), // add_stake_limit - U256::from(500), // remove_stake - U256::from(600), // remove_stake - U256::from(700), // remove_stake_limit - U256::from(800), // remove_stake_limit - U256::from(900), // unstake_all - U256::from(1000), // unstake_all - U256::from(1100), // unstake_all_alpha - U256::from(1200), // unstake_all_alpha - ]; - - let hotkeys = (1..=12).map(U256::from).collect::>(); - - let netuids: Vec<_> = hotkeys - .iter() - .zip(coldkeys.iter()) - .map(|(h, c)| add_dynamic_network(h, c)) - .collect(); - - let tao_reserve = U96F32::from_num(1_500_000_000_000u64); - let alpha_in = U96F32::from_num(1_000_000_000_000u64); - - for netuid in &netuids { - SubnetTAO::::insert(*netuid, tao_reserve.to_num::()); - SubnetAlphaIn::::insert(*netuid, alpha_in.to_num::()); - } - - for coldkey in &coldkeys { - SubtensorModule::add_balance_to_coldkey_account(coldkey, amount); - } - - for ((hotkey, coldkey), netuid) in hotkeys.iter().zip(coldkeys.iter()).zip(netuids.iter()) { - SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( - hotkey, coldkey, *netuid, amount, - ); - } - - // === Submit all job types === - - assert_ok!(SubtensorModule::add_stake_aggregate( - RuntimeOrigin::signed(coldkeys[0]), - hotkeys[0], - netuids[0], - amount - )); - assert_ok!(SubtensorModule::add_stake_aggregate( - RuntimeOrigin::signed(coldkeys[1]), - hotkeys[1], - netuids[1], - amount - )); - - assert_ok!(SubtensorModule::add_stake_limit_aggregate( - RuntimeOrigin::signed(coldkeys[2]), - hotkeys[2], - netuids[2], - amount, - limit_price, - true - )); - assert_ok!(SubtensorModule::add_stake_limit_aggregate( - RuntimeOrigin::signed(coldkeys[3]), - hotkeys[3], - netuids[3], - amount, - limit_price, - true - )); - - assert_ok!(SubtensorModule::remove_stake_aggregate( - RuntimeOrigin::signed(coldkeys[4]), - hotkeys[4], - netuids[4], - amount - )); - assert_ok!(SubtensorModule::remove_stake_aggregate( - RuntimeOrigin::signed(coldkeys[5]), - hotkeys[5], - netuids[5], - amount - )); - - assert_ok!(SubtensorModule::remove_stake_limit_aggregate( - RuntimeOrigin::signed(coldkeys[6]), - hotkeys[6], - netuids[6], - unstake_amount, - limit_price2, - true - )); - assert_ok!(SubtensorModule::remove_stake_limit_aggregate( - RuntimeOrigin::signed(coldkeys[7]), - hotkeys[7], - netuids[7], - unstake_amount, - limit_price2, - true - )); - - assert_ok!(SubtensorModule::unstake_all_aggregate( - RuntimeOrigin::signed(coldkeys[8]), - hotkeys[8], - )); - assert_ok!(SubtensorModule::unstake_all_aggregate( - RuntimeOrigin::signed(coldkeys[9]), - hotkeys[9], - )); - - assert_ok!(SubtensorModule::unstake_all_alpha_aggregate( - RuntimeOrigin::signed(coldkeys[10]), - hotkeys[10], - )); - assert_ok!(SubtensorModule::unstake_all_alpha_aggregate( - RuntimeOrigin::signed(coldkeys[11]), - hotkeys[11], - )); - - // Reorder jobs based on the previous block hash - let mut parent_hash = >::parent_hash(); - parent_hash.as_mut()[0] = 0b10000000; - >::set_parent_hash(parent_hash); - - // Finalize block - run_to_block_ext(3, true); - - // === Collect coldkeys by event type === - let mut add_coldkeys = vec![]; - let mut add_limit_coldkeys = vec![]; - let mut remove_coldkeys = vec![]; - let mut remove_limit_coldkeys = vec![]; - let mut unstake_all_coldkeys = vec![]; - let mut unstake_all_alpha_coldkeys = vec![]; - - for event in System::events().iter().map(|e| &e.event) { - match event { - RuntimeEvent::SubtensorModule(Event::AggregatedStakeAdded(coldkey, ..)) => { - add_coldkeys.push(*coldkey); - } - RuntimeEvent::SubtensorModule(Event::AggregatedLimitedStakeAdded(coldkey, ..)) => { - add_limit_coldkeys.push(*coldkey); - } - RuntimeEvent::SubtensorModule(Event::AggregatedStakeRemoved(coldkey, ..)) => { - remove_coldkeys.push(*coldkey); - } - RuntimeEvent::SubtensorModule(Event::AggregatedLimitedStakeRemoved( - coldkey, - .., - )) => { - remove_limit_coldkeys.push(*coldkey); - } - RuntimeEvent::SubtensorModule(Event::AggregatedUnstakeAllSucceeded(coldkey, _)) => { - unstake_all_coldkeys.push(*coldkey); - } - RuntimeEvent::SubtensorModule(Event::AggregatedUnstakeAllAlphaSucceeded( - coldkey, - _, - )) => { - unstake_all_alpha_coldkeys.push(*coldkey); - } - _ => {} - } - } - - // === Assertions === - assert_eq!(add_coldkeys, vec![coldkeys[0], coldkeys[1]]); // ascending (reversed) - assert_eq!(add_limit_coldkeys, vec![coldkeys[2], coldkeys[3]]); // ascending (reversed) - assert_eq!(remove_coldkeys, vec![coldkeys[5], coldkeys[4]]); // descending (reversed) - assert_eq!(remove_limit_coldkeys, vec![coldkeys[7], coldkeys[6]]); // descending (reversed) - assert_eq!(unstake_all_coldkeys, vec![coldkeys[9], coldkeys[8]]); // descending (reversed) - assert_eq!(unstake_all_alpha_coldkeys, vec![coldkeys[11], coldkeys[10]]); // descending (reversed) - }); -} +// #[test] +// fn test_add_stake_aggregate_ok_no_emission() { +// new_test_ext(1).execute_with(|| { +// let hotkey_account_id = U256::from(533453); +// let coldkey_account_id = U256::from(55453); +// let amount = DefaultMinStake::::get() * 10; +// let fee = DefaultStakingFee::::get(); +// +// //add network +// let netuid: u16 = add_dynamic_network(&hotkey_account_id, &coldkey_account_id); +// +// // Give it some $$$ in his coldkey balance +// SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, amount); +// +// // Check we have zero staked before transfer +// assert_eq!( +// SubtensorModule::get_total_stake_for_hotkey(&hotkey_account_id), +// 0 +// ); +// +// // Also total stake should be equal to the network initial lock +// assert_eq!( +// SubtensorModule::get_total_stake(), +// SubtensorModule::get_network_min_lock() +// ); +// +// // Transfer to hotkey account, and check if the result is ok +// assert_ok!(SubtensorModule::add_stake_aggregate( +// RuntimeOrigin::signed(coldkey_account_id), +// hotkey_account_id, +// netuid, +// amount +// )); +// +// // Ensure that extrinsic call doesn't change the stake. +// assert_eq!( +// SubtensorModule::get_total_stake(), +// SubtensorModule::get_network_min_lock() +// ); +// +// // Check for the block delay +// run_to_block_ext(2, true); +// +// // Check that event was not emitted. +// assert!(System::events().iter().all(|e| { +// !matches!( +// &e.event, +// RuntimeEvent::SubtensorModule(Event::AggregatedStakeAdded(..)) +// ) +// })); +// +// // Enable on_finalize code to run +// run_to_block_ext(3, true); +// +// // Check if stake has increased +// assert_abs_diff_eq!( +// SubtensorModule::get_total_stake_for_hotkey(&hotkey_account_id), +// amount - fee, +// epsilon = amount / 1000, +// ); +// +// // Check if balance has decreased +// assert_eq!(SubtensorModule::get_coldkey_balance(&coldkey_account_id), 1); +// +// // Check if total stake has increased accordingly. +// assert_eq!( +// SubtensorModule::get_total_stake(), +// amount + SubtensorModule::get_network_min_lock() +// ); +// +// // Check that event was emitted. +// assert!(System::events().iter().any(|e| { +// matches!( +// &e.event, +// RuntimeEvent::SubtensorModule(Event::StakeAdded(..)) +// ) +// })); +// +// // Check that event was emitted. +// assert!(System::events().iter().any(|e| { +// matches!( +// &e.event, +// RuntimeEvent::SubtensorModule(Event::AggregatedStakeAdded(..)) +// ) +// })); +// }); +// } +// +// #[test] +// fn test_add_stake_aggregate_failed() { +// new_test_ext(1).execute_with(|| { +// let hotkey_account_id = U256::from(533453); +// let coldkey_account_id = U256::from(55453); +// let amount = DefaultMinStake::::get() * 100; +// //add network +// let netuid: u16 = add_dynamic_network(&hotkey_account_id, &coldkey_account_id); +// +// // Transfer to hotkey account, and check if the result is ok +// assert_ok!(SubtensorModule::add_stake_aggregate( +// RuntimeOrigin::signed(coldkey_account_id), +// hotkey_account_id, +// netuid, +// amount +// )); +// +// // Check for the block delay +// run_to_block_ext(2, true); +// +// // Check that event was not emitted. +// assert!(System::events().iter().all(|e| { +// !matches!( +// &e.event, +// RuntimeEvent::SubtensorModule(Event::FailedToAddAggregatedStake(..)) +// ) +// })); +// +// // Enable on_finalize code to run +// run_to_block_ext(3, true); +// +// // Check that event was emitted. +// assert!(System::events().iter().any(|e| { +// matches!( +// &e.event, +// RuntimeEvent::SubtensorModule(Event::FailedToAddAggregatedStake(..)) +// ) +// })); +// }); +// } +// +// #[test] +// fn test_verify_aggregated_stake_order() { +// new_test_ext(1).execute_with(|| { +// let hotkey_account_id = U256::from(533453); +// let coldkey_account_id = U256::from(55453); +// let amount = 1_000_000_000_000u64; +// let limit_price = 6_000_000_000u64; +// let unstake_amount = 150_000_000_000u64; +// let limit_price2 = 1_350_000_000; +// +// // add network +// let netuid1: u16 = add_dynamic_network(&hotkey_account_id, &coldkey_account_id); +// let netuid2: u16 = add_dynamic_network(&hotkey_account_id, &coldkey_account_id); +// let netuid3: u16 = add_dynamic_network(&hotkey_account_id, &coldkey_account_id); +// let netuid4: u16 = add_dynamic_network(&hotkey_account_id, &coldkey_account_id); +// let netuid5: u16 = add_dynamic_network(&hotkey_account_id, &coldkey_account_id); +// let netuid6: u16 = add_dynamic_network(&hotkey_account_id, &coldkey_account_id); +// +// let tao_reserve: U96F32 = U96F32::from_num(1_500_000_000_000_u64); +// let alpha_in: U96F32 = U96F32::from_num(1_000_000_000_000_u64); +// +// for netuid in [netuid1, netuid3, netuid3, netuid4, netuid5, netuid6] { +// SubnetTAO::::insert(netuid, tao_reserve.to_num::()); +// SubnetAlphaIn::::insert(netuid, alpha_in.to_num::()); +// } +// +// // Give it some $$$ in his coldkey balance +// SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, 6 * amount); +// // Give the neuron some stake to remove +// SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( +// &hotkey_account_id, +// &coldkey_account_id, +// netuid3, +// amount, +// ); +// SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( +// &hotkey_account_id, +// &coldkey_account_id, +// netuid4, +// amount, +// ); +// +// // Add stake with slippage safety and check if the result is ok +// assert_ok!(SubtensorModule::remove_stake_aggregate( +// RuntimeOrigin::signed(coldkey_account_id), +// hotkey_account_id, +// netuid3, +// amount +// )); +// +// assert_ok!(SubtensorModule::remove_stake_limit_aggregate( +// RuntimeOrigin::signed(coldkey_account_id), +// hotkey_account_id, +// netuid4, +// unstake_amount, +// limit_price2, +// true +// )); +// +// assert_ok!(SubtensorModule::add_stake_aggregate( +// RuntimeOrigin::signed(coldkey_account_id), +// hotkey_account_id, +// netuid1, +// amount, +// )); +// +// assert_ok!(SubtensorModule::add_stake_limit_aggregate( +// RuntimeOrigin::signed(coldkey_account_id), +// hotkey_account_id, +// netuid2, +// amount, +// limit_price, +// true +// )); +// +// assert_ok!(SubtensorModule::unstake_all_aggregate( +// RuntimeOrigin::signed(coldkey_account_id), +// hotkey_account_id, +// )); +// +// assert_ok!(SubtensorModule::unstake_all_alpha_aggregate( +// RuntimeOrigin::signed(coldkey_account_id), +// hotkey_account_id, +// )); +// +// // Enable on_finalize code to run +// run_to_block_ext(3, true); +// +// let add_stake_position = System::events() +// .iter() +// .position(|e| { +// if let RuntimeEvent::SubtensorModule(Event::AggregatedStakeAdded(.., netuid, _)) = +// e.event +// { +// netuid == netuid1 +// } else { +// false +// } +// }) +// .expect("Stake event must be present in the event log."); +// +// let add_stake_limit_position = System::events() +// .iter() +// .position(|e| { +// if let RuntimeEvent::SubtensorModule(Event::AggregatedLimitedStakeAdded( +// _, +// _, +// netuid, +// _, +// _, +// _, +// )) = e.event +// { +// netuid == netuid2 +// } else { +// false +// } +// }) +// .expect("Stake event must be present in the event log."); +// +// let remove_stake_position = System::events() +// .iter() +// .position(|e| { +// if let RuntimeEvent::SubtensorModule(Event::AggregatedStakeRemoved(.., netuid, _)) = +// e.event +// { +// netuid == netuid3 +// } else { +// false +// } +// }) +// .expect("Stake event must be present in the event log."); +// +// let remove_stake_limit_position = System::events() +// .iter() +// .position(|e| { +// if let RuntimeEvent::SubtensorModule(Event::AggregatedLimitedStakeRemoved( +// .., +// netuid, +// _, +// _, +// _, +// )) = e.event +// { +// netuid == netuid4 +// } else { +// false +// } +// }) +// .expect("Stake event must be present in the event log."); +// +// let unstake_all_position = System::events() +// .iter() +// .position(|e| { +// matches!( +// e.event, +// RuntimeEvent::SubtensorModule(Event::AggregatedUnstakeAllSucceeded(..)) +// ) +// }) +// .expect("Stake event must be present in the event log."); +// +// let unstake_all_alpha_position = System::events() +// .iter() +// .position(|e| { +// matches!( +// e.event, +// RuntimeEvent::SubtensorModule(Event::AggregatedUnstakeAllAlphaSucceeded(..)) +// ) +// }) +// .expect("Stake event must be present in the event log."); +// +// // Check events order +// assert!(remove_stake_limit_position < remove_stake_position); +// assert!(remove_stake_position < unstake_all_position); +// assert!(unstake_all_position < unstake_all_alpha_position); +// assert!(add_stake_position > unstake_all_alpha_position); +// assert!(add_stake_limit_position < add_stake_position); +// }); +// } +// +// #[test] +// #[allow(clippy::indexing_slicing)] +// fn test_verify_aggregated_stake_order_reversed() { +// new_test_ext(1).execute_with(|| { +// let amount = 1_000_000_000_000u64; +// let limit_price = 6_000_000_000u64; +// let unstake_amount = 150_000_000_000u64; +// let limit_price2 = 1_350_000_000; +// +// // Coldkeys and hotkeys +// let coldkeys = vec![ +// U256::from(100), // add_stake +// U256::from(200), // add_stake_limit +// U256::from(300), // remove_stake +// U256::from(400), // remove_stake_limit +// U256::from(500), // unstake_all +// U256::from(600), // unstake_all_alpha +// ]; +// +// let hotkeys = (1..=6).map(U256::from).collect::>(); +// +// let netuids: Vec<_> = hotkeys +// .iter() +// .zip(coldkeys.iter()) +// .map(|(h, c)| add_dynamic_network(h, c)) +// .collect(); +// +// let tao_reserve = U96F32::from_num(1_500_000_000_000u64); +// let alpha_in = U96F32::from_num(1_000_000_000_000u64); +// +// for netuid in &netuids { +// SubnetTAO::::insert(*netuid, tao_reserve.to_num::()); +// SubnetAlphaIn::::insert(*netuid, alpha_in.to_num::()); +// } +// +// for coldkey in &coldkeys { +// SubtensorModule::add_balance_to_coldkey_account(coldkey, amount); +// } +// +// for ((hotkey, coldkey), netuid) in hotkeys.iter().zip(coldkeys.iter()).zip(netuids.iter()) { +// SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( +// hotkey, coldkey, *netuid, amount, +// ); +// } +// +// // Add stake with slippage safety and check if the result is ok +// assert_ok!(SubtensorModule::remove_stake_aggregate( +// RuntimeOrigin::signed(coldkeys[2]), +// hotkeys[2], +// netuids[2], +// amount +// )); +// +// assert_ok!(SubtensorModule::remove_stake_limit_aggregate( +// RuntimeOrigin::signed(coldkeys[3]), +// hotkeys[3], +// netuids[3], +// unstake_amount, +// limit_price2, +// true +// )); +// +// assert_ok!(SubtensorModule::add_stake_aggregate( +// RuntimeOrigin::signed(coldkeys[0]), +// hotkeys[0], +// netuids[0], +// amount, +// )); +// +// assert_ok!(SubtensorModule::add_stake_limit_aggregate( +// RuntimeOrigin::signed(coldkeys[1]), +// hotkeys[1], +// netuids[1], +// amount, +// limit_price, +// true +// )); +// +// assert_ok!(SubtensorModule::unstake_all_aggregate( +// RuntimeOrigin::signed(coldkeys[4]), +// hotkeys[4], +// )); +// +// assert_ok!(SubtensorModule::unstake_all_alpha_aggregate( +// RuntimeOrigin::signed(coldkeys[5]), +// hotkeys[5], +// )); +// +// // Enable on_finalize code to run +// run_to_block_ext(2, false); +// // Reorder jobs based on the previous block hash +// let mut parent_hash = >::parent_hash(); +// parent_hash.as_mut()[0] = 0b10000000; +// >::set_parent_hash(parent_hash); +// +// // Enable on_finalize code to run +// run_to_block_ext(3, true); +// +// let add_stake_position = System::events() +// .iter() +// .position(|e| { +// if let RuntimeEvent::SubtensorModule(Event::AggregatedStakeAdded(.., netuid, _)) = +// e.event +// { +// netuid == netuids[0] +// } else { +// false +// } +// }) +// .expect("Stake event must be present in the event log."); +// +// let add_stake_limit_position = System::events() +// .iter() +// .position(|e| { +// if let RuntimeEvent::SubtensorModule(Event::AggregatedLimitedStakeAdded( +// _, +// _, +// netuid, +// _, +// _, +// _, +// )) = e.event +// { +// netuid == netuids[1] +// } else { +// false +// } +// }) +// .expect("Stake event must be present in the event log."); +// +// let remove_stake_position = System::events() +// .iter() +// .position(|e| { +// if let RuntimeEvent::SubtensorModule(Event::AggregatedStakeRemoved(.., netuid, _)) = +// e.event +// { +// netuid == netuids[2] +// } else { +// false +// } +// }) +// .expect("Stake event must be present in the event log."); +// +// let remove_stake_limit_position = System::events() +// .iter() +// .position(|e| { +// if let RuntimeEvent::SubtensorModule(Event::AggregatedLimitedStakeRemoved( +// .., +// netuid, +// _, +// _, +// _, +// )) = e.event +// { +// netuid == netuids[3] +// } else { +// false +// } +// }) +// .expect("Stake event must be present in the event log."); +// +// let unstake_all_position = System::events() +// .iter() +// .position(|e| { +// matches!( +// e.event, +// RuntimeEvent::SubtensorModule(Event::AggregatedUnstakeAllSucceeded(..)) +// ) +// }) +// .expect("Stake event must be present in the event log."); +// +// let unstake_all_alpha_position = System::events() +// .iter() +// .position(|e| { +// matches!( +// e.event, +// RuntimeEvent::SubtensorModule(Event::AggregatedUnstakeAllAlphaSucceeded(..)) +// ) +// }) +// .expect("Stake event must be present in the event log."); +// +// // Check events order +// assert!(add_stake_limit_position > add_stake_position); +// assert!(add_stake_position < unstake_all_alpha_position); +// assert!(unstake_all_position > unstake_all_alpha_position); +// assert!(remove_stake_position > unstake_all_position); +// assert!(remove_stake_limit_position > remove_stake_position); +// }); +// } +// +// #[test] +// #[allow(clippy::indexing_slicing)] +// fn test_verify_all_job_type_sort_by_coldkey() { +// new_test_ext(1).execute_with(|| { +// let amount = 1_000_000_000_000u64; +// let limit_price = 6_000_000_000u64; +// let unstake_amount = 150_000_000_000u64; +// let limit_price2 = 1_350_000_000; +// +// // Coldkeys and hotkeys +// let coldkeys = vec![ +// U256::from(100), // add_stake +// U256::from(200), // add_stake +// U256::from(300), // add_stake_limit +// U256::from(400), // add_stake_limit +// U256::from(500), // remove_stake +// U256::from(600), // remove_stake +// U256::from(700), // remove_stake_limit +// U256::from(800), // remove_stake_limit +// U256::from(900), // unstake_all +// U256::from(1000), // unstake_all +// U256::from(1100), // unstake_all_alpha +// U256::from(1200), // unstake_all_alpha +// ]; +// +// let hotkeys = (1..=12).map(U256::from).collect::>(); +// +// let netuids: Vec<_> = hotkeys +// .iter() +// .zip(coldkeys.iter()) +// .map(|(h, c)| add_dynamic_network(h, c)) +// .collect(); +// +// let tao_reserve = U96F32::from_num(1_500_000_000_000u64); +// let alpha_in = U96F32::from_num(1_000_000_000_000u64); +// +// for netuid in &netuids { +// SubnetTAO::::insert(*netuid, tao_reserve.to_num::()); +// SubnetAlphaIn::::insert(*netuid, alpha_in.to_num::()); +// } +// +// for coldkey in &coldkeys { +// SubtensorModule::add_balance_to_coldkey_account(coldkey, amount); +// } +// +// for ((hotkey, coldkey), netuid) in hotkeys.iter().zip(coldkeys.iter()).zip(netuids.iter()) { +// SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( +// hotkey, coldkey, *netuid, amount, +// ); +// } +// +// // === Submit all job types === +// +// assert_ok!(SubtensorModule::add_stake_aggregate( +// RuntimeOrigin::signed(coldkeys[0]), +// hotkeys[0], +// netuids[0], +// amount +// )); +// assert_ok!(SubtensorModule::add_stake_aggregate( +// RuntimeOrigin::signed(coldkeys[1]), +// hotkeys[1], +// netuids[1], +// amount +// )); +// +// assert_ok!(SubtensorModule::add_stake_limit_aggregate( +// RuntimeOrigin::signed(coldkeys[2]), +// hotkeys[2], +// netuids[2], +// amount, +// limit_price, +// true +// )); +// assert_ok!(SubtensorModule::add_stake_limit_aggregate( +// RuntimeOrigin::signed(coldkeys[3]), +// hotkeys[3], +// netuids[3], +// amount, +// limit_price, +// true +// )); +// +// assert_ok!(SubtensorModule::remove_stake_aggregate( +// RuntimeOrigin::signed(coldkeys[4]), +// hotkeys[4], +// netuids[4], +// amount +// )); +// assert_ok!(SubtensorModule::remove_stake_aggregate( +// RuntimeOrigin::signed(coldkeys[5]), +// hotkeys[5], +// netuids[5], +// amount +// )); +// +// assert_ok!(SubtensorModule::remove_stake_limit_aggregate( +// RuntimeOrigin::signed(coldkeys[6]), +// hotkeys[6], +// netuids[6], +// unstake_amount, +// limit_price2, +// true +// )); +// assert_ok!(SubtensorModule::remove_stake_limit_aggregate( +// RuntimeOrigin::signed(coldkeys[7]), +// hotkeys[7], +// netuids[7], +// unstake_amount, +// limit_price2, +// true +// )); +// +// assert_ok!(SubtensorModule::unstake_all_aggregate( +// RuntimeOrigin::signed(coldkeys[8]), +// hotkeys[8], +// )); +// assert_ok!(SubtensorModule::unstake_all_aggregate( +// RuntimeOrigin::signed(coldkeys[9]), +// hotkeys[9], +// )); +// +// assert_ok!(SubtensorModule::unstake_all_alpha_aggregate( +// RuntimeOrigin::signed(coldkeys[10]), +// hotkeys[10], +// )); +// assert_ok!(SubtensorModule::unstake_all_alpha_aggregate( +// RuntimeOrigin::signed(coldkeys[11]), +// hotkeys[11], +// )); +// +// // Finalize block +// run_to_block_ext(3, true); +// +// // === Collect coldkeys by event type === +// let mut add_coldkeys = vec![]; +// let mut add_limit_coldkeys = vec![]; +// let mut remove_coldkeys = vec![]; +// let mut remove_limit_coldkeys = vec![]; +// let mut unstake_all_coldkeys = vec![]; +// let mut unstake_all_alpha_coldkeys = vec![]; +// +// for event in System::events().iter().map(|e| &e.event) { +// match event { +// RuntimeEvent::SubtensorModule(Event::AggregatedStakeAdded(coldkey, ..)) => { +// add_coldkeys.push(*coldkey); +// } +// RuntimeEvent::SubtensorModule(Event::AggregatedLimitedStakeAdded(coldkey, ..)) => { +// add_limit_coldkeys.push(*coldkey); +// } +// RuntimeEvent::SubtensorModule(Event::AggregatedStakeRemoved(coldkey, ..)) => { +// remove_coldkeys.push(*coldkey); +// } +// RuntimeEvent::SubtensorModule(Event::AggregatedLimitedStakeRemoved( +// coldkey, +// .., +// )) => { +// remove_limit_coldkeys.push(*coldkey); +// } +// RuntimeEvent::SubtensorModule(Event::AggregatedUnstakeAllSucceeded(coldkey, _)) => { +// unstake_all_coldkeys.push(*coldkey); +// } +// RuntimeEvent::SubtensorModule(Event::AggregatedUnstakeAllAlphaSucceeded( +// coldkey, +// _, +// )) => { +// unstake_all_alpha_coldkeys.push(*coldkey); +// } +// _ => {} +// } +// } +// +// // === Assertions === +// assert_eq!(add_coldkeys, vec![coldkeys[1], coldkeys[0]]); // descending +// assert_eq!(add_limit_coldkeys, vec![coldkeys[3], coldkeys[2]]); // descending +// assert_eq!(remove_coldkeys, vec![coldkeys[4], coldkeys[5]]); // ascending +// assert_eq!(remove_limit_coldkeys, vec![coldkeys[6], coldkeys[7]]); // ascending +// assert_eq!(unstake_all_coldkeys, vec![coldkeys[8], coldkeys[9]]); // ascending +// assert_eq!(unstake_all_alpha_coldkeys, vec![coldkeys[10], coldkeys[11]]); // ascending +// }); +// } +// +// #[test] +// #[allow(clippy::indexing_slicing)] +// fn test_verify_all_job_type_sort_by_coldkey_reverse_order() { +// new_test_ext(1).execute_with(|| { +// let amount = 1_000_000_000_000u64; +// let limit_price = 6_000_000_000u64; +// let unstake_amount = 150_000_000_000u64; +// let limit_price2 = 1_350_000_000; +// +// // Coldkeys and hotkeys +// let coldkeys = vec![ +// U256::from(100), // add_stake +// U256::from(200), // add_stake +// U256::from(300), // add_stake_limit +// U256::from(400), // add_stake_limit +// U256::from(500), // remove_stake +// U256::from(600), // remove_stake +// U256::from(700), // remove_stake_limit +// U256::from(800), // remove_stake_limit +// U256::from(900), // unstake_all +// U256::from(1000), // unstake_all +// U256::from(1100), // unstake_all_alpha +// U256::from(1200), // unstake_all_alpha +// ]; +// +// let hotkeys = (1..=12).map(U256::from).collect::>(); +// +// let netuids: Vec<_> = hotkeys +// .iter() +// .zip(coldkeys.iter()) +// .map(|(h, c)| add_dynamic_network(h, c)) +// .collect(); +// +// let tao_reserve = U96F32::from_num(1_500_000_000_000u64); +// let alpha_in = U96F32::from_num(1_000_000_000_000u64); +// +// for netuid in &netuids { +// SubnetTAO::::insert(*netuid, tao_reserve.to_num::()); +// SubnetAlphaIn::::insert(*netuid, alpha_in.to_num::()); +// } +// +// for coldkey in &coldkeys { +// SubtensorModule::add_balance_to_coldkey_account(coldkey, amount); +// } +// +// for ((hotkey, coldkey), netuid) in hotkeys.iter().zip(coldkeys.iter()).zip(netuids.iter()) { +// SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( +// hotkey, coldkey, *netuid, amount, +// ); +// } +// +// // === Submit all job types === +// +// assert_ok!(SubtensorModule::add_stake_aggregate( +// RuntimeOrigin::signed(coldkeys[0]), +// hotkeys[0], +// netuids[0], +// amount +// )); +// assert_ok!(SubtensorModule::add_stake_aggregate( +// RuntimeOrigin::signed(coldkeys[1]), +// hotkeys[1], +// netuids[1], +// amount +// )); +// +// assert_ok!(SubtensorModule::add_stake_limit_aggregate( +// RuntimeOrigin::signed(coldkeys[2]), +// hotkeys[2], +// netuids[2], +// amount, +// limit_price, +// true +// )); +// assert_ok!(SubtensorModule::add_stake_limit_aggregate( +// RuntimeOrigin::signed(coldkeys[3]), +// hotkeys[3], +// netuids[3], +// amount, +// limit_price, +// true +// )); +// +// assert_ok!(SubtensorModule::remove_stake_aggregate( +// RuntimeOrigin::signed(coldkeys[4]), +// hotkeys[4], +// netuids[4], +// amount +// )); +// assert_ok!(SubtensorModule::remove_stake_aggregate( +// RuntimeOrigin::signed(coldkeys[5]), +// hotkeys[5], +// netuids[5], +// amount +// )); +// +// assert_ok!(SubtensorModule::remove_stake_limit_aggregate( +// RuntimeOrigin::signed(coldkeys[6]), +// hotkeys[6], +// netuids[6], +// unstake_amount, +// limit_price2, +// true +// )); +// assert_ok!(SubtensorModule::remove_stake_limit_aggregate( +// RuntimeOrigin::signed(coldkeys[7]), +// hotkeys[7], +// netuids[7], +// unstake_amount, +// limit_price2, +// true +// )); +// +// assert_ok!(SubtensorModule::unstake_all_aggregate( +// RuntimeOrigin::signed(coldkeys[8]), +// hotkeys[8], +// )); +// assert_ok!(SubtensorModule::unstake_all_aggregate( +// RuntimeOrigin::signed(coldkeys[9]), +// hotkeys[9], +// )); +// +// assert_ok!(SubtensorModule::unstake_all_alpha_aggregate( +// RuntimeOrigin::signed(coldkeys[10]), +// hotkeys[10], +// )); +// assert_ok!(SubtensorModule::unstake_all_alpha_aggregate( +// RuntimeOrigin::signed(coldkeys[11]), +// hotkeys[11], +// )); +// +// // Reorder jobs based on the previous block hash +// let mut parent_hash = >::parent_hash(); +// parent_hash.as_mut()[0] = 0b10000000; +// >::set_parent_hash(parent_hash); +// +// // Finalize block +// run_to_block_ext(3, true); +// +// // === Collect coldkeys by event type === +// let mut add_coldkeys = vec![]; +// let mut add_limit_coldkeys = vec![]; +// let mut remove_coldkeys = vec![]; +// let mut remove_limit_coldkeys = vec![]; +// let mut unstake_all_coldkeys = vec![]; +// let mut unstake_all_alpha_coldkeys = vec![]; +// +// for event in System::events().iter().map(|e| &e.event) { +// match event { +// RuntimeEvent::SubtensorModule(Event::AggregatedStakeAdded(coldkey, ..)) => { +// add_coldkeys.push(*coldkey); +// } +// RuntimeEvent::SubtensorModule(Event::AggregatedLimitedStakeAdded(coldkey, ..)) => { +// add_limit_coldkeys.push(*coldkey); +// } +// RuntimeEvent::SubtensorModule(Event::AggregatedStakeRemoved(coldkey, ..)) => { +// remove_coldkeys.push(*coldkey); +// } +// RuntimeEvent::SubtensorModule(Event::AggregatedLimitedStakeRemoved( +// coldkey, +// .., +// )) => { +// remove_limit_coldkeys.push(*coldkey); +// } +// RuntimeEvent::SubtensorModule(Event::AggregatedUnstakeAllSucceeded(coldkey, _)) => { +// unstake_all_coldkeys.push(*coldkey); +// } +// RuntimeEvent::SubtensorModule(Event::AggregatedUnstakeAllAlphaSucceeded( +// coldkey, +// _, +// )) => { +// unstake_all_alpha_coldkeys.push(*coldkey); +// } +// _ => {} +// } +// } +// +// // === Assertions === +// assert_eq!(add_coldkeys, vec![coldkeys[0], coldkeys[1]]); // ascending (reversed) +// assert_eq!(add_limit_coldkeys, vec![coldkeys[2], coldkeys[3]]); // ascending (reversed) +// assert_eq!(remove_coldkeys, vec![coldkeys[5], coldkeys[4]]); // descending (reversed) +// assert_eq!(remove_limit_coldkeys, vec![coldkeys[7], coldkeys[6]]); // descending (reversed) +// assert_eq!(unstake_all_coldkeys, vec![coldkeys[9], coldkeys[8]]); // descending (reversed) +// assert_eq!(unstake_all_alpha_coldkeys, vec![coldkeys[11], coldkeys[10]]); // descending (reversed) +// }); +// } #[test] fn test_dividends_with_run_to_block() { @@ -1209,87 +1209,18 @@ fn test_remove_stake_dispatch_info_ok() { }); assert_eq!( call.get_dispatch_info(), - DispatchInfo { - weight: frame_support::weights::Weight::from_parts(1_671_800_000, 0) - .add_proof_size(0), - class: DispatchClass::Normal, - pays_fee: Pays::No - } - ); - }); -} - -#[test] -fn test_remove_stake_ok_no_emission() { - new_test_ext(1).execute_with(|| { - let subnet_owner_coldkey = U256::from(1); - let subnet_owner_hotkey = U256::from(2); - let coldkey_account_id = U256::from(4343); - let hotkey_account_id = U256::from(4968585); - let amount = DefaultMinStake::::get() * 10; - let netuid: u16 = add_dynamic_network(&subnet_owner_hotkey, &subnet_owner_coldkey); - register_ok_neuron(netuid, hotkey_account_id, coldkey_account_id, 192213123); - - // Some basic assertions - assert_eq!( - SubtensorModule::get_total_stake(), - SubtensorModule::get_network_min_lock() - ); - assert_eq!( - SubtensorModule::get_total_stake_for_hotkey(&hotkey_account_id), - 0 - ); - assert_eq!(SubtensorModule::get_coldkey_balance(&coldkey_account_id), 0); - - // Give the neuron some stake to remove - SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( - &hotkey_account_id, - &coldkey_account_id, - netuid, - amount, - ); - assert_eq!( - SubtensorModule::get_total_stake_for_hotkey(&hotkey_account_id), - amount - ); - - // Add subnet TAO for the equivalent amount added at price - let amount_tao = - U96F32::saturating_from_num(amount) * SubtensorModule::get_alpha_price(netuid); - SubnetTAO::::mutate(netuid, |v| *v += amount_tao.saturating_to_num::()); - TotalStake::::mutate(|v| *v += amount_tao.saturating_to_num::()); - - // Do the magic - assert_ok!(SubtensorModule::remove_stake( - RuntimeOrigin::signed(coldkey_account_id), - hotkey_account_id, - netuid, - amount - )); - - let fee = SubtensorModule::calculate_staking_fee( - Some((&hotkey_account_id, netuid)), - &coldkey_account_id, - None, - &coldkey_account_id, - U96F32::saturating_from_num(amount), - ); - - // we do not expect the exact amount due to slippage - assert!(SubtensorModule::get_coldkey_balance(&coldkey_account_id) > amount / 10 * 9 - fee); - assert_eq!( - SubtensorModule::get_total_stake_for_hotkey(&hotkey_account_id), - 0 - ); - assert_eq!( - SubtensorModule::get_total_stake(), - SubtensorModule::get_network_min_lock() + fee + DispatchInfo { + weight: frame_support::weights::Weight::from_parts(1_671_800_000, 0) + .add_proof_size(0), + class: DispatchClass::Normal, + pays_fee: Pays::No + } ); }); } #[test] -fn test_remove_stake_aggregate_ok_no_emission() { +fn test_remove_stake_ok_no_emission() { new_test_ext(1).execute_with(|| { let subnet_owner_coldkey = U256::from(1); let subnet_owner_hotkey = U256::from(2); @@ -1329,27 +1260,13 @@ fn test_remove_stake_aggregate_ok_no_emission() { TotalStake::::mutate(|v| *v += amount_tao.saturating_to_num::()); // Do the magic - assert_ok!(SubtensorModule::remove_stake_aggregate( + assert_ok!(SubtensorModule::remove_stake( RuntimeOrigin::signed(coldkey_account_id), hotkey_account_id, netuid, amount )); - // Check for the block delay - run_to_block_ext(2, true); - - // Check that event was not emitted. - assert!(System::events().iter().all(|e| { - !matches!( - &e.event, - RuntimeEvent::SubtensorModule(Event::AggregatedStakeRemoved(..)) - ) - })); - - // Enable on_finalize code to run - run_to_block_ext(3, true); - let fee = SubtensorModule::calculate_staking_fee( Some((&hotkey_account_id, netuid)), &coldkey_account_id, @@ -1368,64 +1285,147 @@ fn test_remove_stake_aggregate_ok_no_emission() { SubtensorModule::get_total_stake(), SubtensorModule::get_network_min_lock() + fee ); - - // Check that event was emitted. - assert!(System::events().iter().any(|e| { - matches!( - &e.event, - RuntimeEvent::SubtensorModule(Event::StakeRemoved(..)) - ) - })); - // Check that event was emitted. - assert!(System::events().iter().any(|e| { - matches!( - &e.event, - RuntimeEvent::SubtensorModule(Event::AggregatedStakeRemoved(..)) - ) - })); - }); -} -#[test] -fn test_remove_stake_aggregate_fail() { - new_test_ext(1).execute_with(|| { - let subnet_owner_coldkey = U256::from(1); - let subnet_owner_hotkey = U256::from(2); - let coldkey_account_id = U256::from(4343); - let hotkey_account_id = U256::from(4968585); - let amount = DefaultMinStake::::get() * 10; - let netuid: u16 = add_dynamic_network(&subnet_owner_hotkey, &subnet_owner_coldkey); - register_ok_neuron(netuid, hotkey_account_id, coldkey_account_id, 192213123); - - assert_ok!(SubtensorModule::remove_stake_aggregate( - RuntimeOrigin::signed(coldkey_account_id), - hotkey_account_id, - netuid, - amount - )); - - // Check for the block delay - run_to_block_ext(2, true); - - // Check that event was not emitted. - assert!(System::events().iter().all(|e| { - !matches!( - &e.event, - RuntimeEvent::SubtensorModule(Event::FailedToRemoveAggregatedStake(..)) - ) - })); - - // Enable on_finalize code to run - run_to_block_ext(3, true); - - // Check that event was emitted. - assert!(System::events().iter().any(|e| { - matches!( - &e.event, - RuntimeEvent::SubtensorModule(Event::FailedToRemoveAggregatedStake(..)) - ) - })); }); } +// +// #[test] +// fn test_remove_stake_aggregate_ok_no_emission() { +// new_test_ext(1).execute_with(|| { +// let subnet_owner_coldkey = U256::from(1); +// let subnet_owner_hotkey = U256::from(2); +// let coldkey_account_id = U256::from(4343); +// let hotkey_account_id = U256::from(4968585); +// let amount = DefaultMinStake::::get() * 10; +// let netuid: u16 = add_dynamic_network(&subnet_owner_hotkey, &subnet_owner_coldkey); +// register_ok_neuron(netuid, hotkey_account_id, coldkey_account_id, 192213123); +// +// // Some basic assertions +// assert_eq!( +// SubtensorModule::get_total_stake(), +// SubtensorModule::get_network_min_lock() +// ); +// assert_eq!( +// SubtensorModule::get_total_stake_for_hotkey(&hotkey_account_id), +// 0 +// ); +// assert_eq!(SubtensorModule::get_coldkey_balance(&coldkey_account_id), 0); +// +// // Give the neuron some stake to remove +// SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( +// &hotkey_account_id, +// &coldkey_account_id, +// netuid, +// amount, +// ); +// assert_eq!( +// SubtensorModule::get_total_stake_for_hotkey(&hotkey_account_id), +// amount +// ); +// +// // Add subnet TAO for the equivalent amount added at price +// let amount_tao = +// U96F32::saturating_from_num(amount) * SubtensorModule::get_alpha_price(netuid); +// SubnetTAO::::mutate(netuid, |v| *v += amount_tao.saturating_to_num::()); +// TotalStake::::mutate(|v| *v += amount_tao.saturating_to_num::()); +// +// // Do the magic +// assert_ok!(SubtensorModule::remove_stake_aggregate( +// RuntimeOrigin::signed(coldkey_account_id), +// hotkey_account_id, +// netuid, +// amount +// )); +// +// // Check for the block delay +// run_to_block_ext(2, true); +// +// // Check that event was not emitted. +// assert!(System::events().iter().all(|e| { +// !matches!( +// &e.event, +// RuntimeEvent::SubtensorModule(Event::AggregatedStakeRemoved(..)) +// ) +// })); +// +// // Enable on_finalize code to run +// run_to_block_ext(3, true); +// +// let fee = SubtensorModule::calculate_staking_fee( +// Some((&hotkey_account_id, netuid)), +// &coldkey_account_id, +// None, +// &coldkey_account_id, +// U96F32::saturating_from_num(amount), +// ); +// +// // we do not expect the exact amount due to slippage +// assert!(SubtensorModule::get_coldkey_balance(&coldkey_account_id) > amount / 10 * 9 - fee); +// assert_eq!( +// SubtensorModule::get_total_stake_for_hotkey(&hotkey_account_id), +// 0 +// ); +// assert_eq!( +// SubtensorModule::get_total_stake(), +// SubtensorModule::get_network_min_lock() + fee +// ); +// +// // Check that event was emitted. +// assert!(System::events().iter().any(|e| { +// matches!( +// &e.event, +// RuntimeEvent::SubtensorModule(Event::StakeRemoved(..)) +// ) +// })); +// // Check that event was emitted. +// assert!(System::events().iter().any(|e| { +// matches!( +// &e.event, +// RuntimeEvent::SubtensorModule(Event::AggregatedStakeRemoved(..)) +// ) +// })); +// }); +// } +// #[test] +// fn test_remove_stake_aggregate_fail() { +// new_test_ext(1).execute_with(|| { +// let subnet_owner_coldkey = U256::from(1); +// let subnet_owner_hotkey = U256::from(2); +// let coldkey_account_id = U256::from(4343); +// let hotkey_account_id = U256::from(4968585); +// let amount = DefaultMinStake::::get() * 10; +// let netuid: u16 = add_dynamic_network(&subnet_owner_hotkey, &subnet_owner_coldkey); +// register_ok_neuron(netuid, hotkey_account_id, coldkey_account_id, 192213123); +// +// assert_ok!(SubtensorModule::remove_stake_aggregate( +// RuntimeOrigin::signed(coldkey_account_id), +// hotkey_account_id, +// netuid, +// amount +// )); +// +// // Check for the block delay +// run_to_block_ext(2, true); +// +// // Check that event was not emitted. +// assert!(System::events().iter().all(|e| { +// !matches!( +// &e.event, +// RuntimeEvent::SubtensorModule(Event::FailedToRemoveAggregatedStake(..)) +// ) +// })); +// +// // Enable on_finalize code to run +// run_to_block_ext(3, true); +// +// // Check that event was emitted. +// assert!(System::events().iter().any(|e| { +// matches!( +// &e.event, +// RuntimeEvent::SubtensorModule(Event::FailedToRemoveAggregatedStake(..)) +// ) +// })); +// }); +// } #[test] fn test_remove_stake_amount_too_low() { @@ -4856,145 +4856,145 @@ fn test_add_stake_limit_ok() { ); }); } - -#[test] -fn test_add_stake_limit_aggregate_ok() { - new_test_ext(1).execute_with(|| { - let hotkey_account_id = U256::from(533453); - let coldkey_account_id = U256::from(55453); - let amount = 900_000_000_000; // over the maximum - let fee = DefaultStakingFee::::get(); - - // add network - let netuid: u16 = add_dynamic_network(&hotkey_account_id, &coldkey_account_id); - - // Forse-set alpha in and tao reserve to make price equal 1.5 - let tao_reserve: U96F32 = U96F32::from_num(150_000_000_000_u64); - let alpha_in: U96F32 = U96F32::from_num(100_000_000_000_u64); - SubnetTAO::::insert(netuid, tao_reserve.to_num::()); - SubnetAlphaIn::::insert(netuid, alpha_in.to_num::()); - let current_price: U96F32 = U96F32::from_num(SubtensorModule::get_alpha_price(netuid)); - assert_eq!(current_price, U96F32::from_num(1.5)); - - // Give it some $$$ in his coldkey balance - SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, amount); - - // Setup limit price so that it doesn't peak above 4x of current price - // The amount that can be executed at this price is 450 TAO only - // Alpha produced will be equal to 75 = 450*100/(450+150) - let limit_price = 6_000_000_000; - let expected_executed_stake = 75_000_000_000; - - // Add stake with slippage safety and check if the result is ok - assert_ok!(SubtensorModule::add_stake_limit_aggregate( - RuntimeOrigin::signed(coldkey_account_id), - hotkey_account_id, - netuid, - amount, - limit_price, - true - )); - - // Check for the block delay - run_to_block_ext(2, true); - - // Check that event was not emitted. - assert!(System::events().iter().all(|e| { - !matches!( - &e.event, - RuntimeEvent::SubtensorModule(Event::AggregatedLimitedStakeAdded(..)) - ) - })); - - // Enable on_finalize code to run - run_to_block_ext(3, true); - - // Check if stake has increased only by 75 Alpha - assert_abs_diff_eq!( - SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( - &hotkey_account_id, - &coldkey_account_id, - netuid - ), - expected_executed_stake - fee, - epsilon = expected_executed_stake / 1000, - ); - - // Check that 450 TAO balance still remains free on coldkey - assert_abs_diff_eq!( - SubtensorModule::get_coldkey_balance(&coldkey_account_id), - 450_000_000_000, - epsilon = 10_000 - ); - - // Check that price has updated to ~24 = (150+450) / (100 - 75) - let exp_price = U96F32::from_num(24.0); - let current_price: U96F32 = U96F32::from_num(SubtensorModule::get_alpha_price(netuid)); - assert_abs_diff_eq!( - exp_price.to_num::(), - current_price.to_num::(), - epsilon = 0.0001, - ); - - // Check that event was emitted. - assert!(System::events().iter().any(|e| { - matches!( - &e.event, - RuntimeEvent::SubtensorModule(Event::StakeAdded(..)) - ) - })); - // Check that event was emitted. - assert!(System::events().iter().any(|e| { - matches!( - &e.event, - RuntimeEvent::SubtensorModule(Event::AggregatedLimitedStakeAdded(..)) - ) - })); - }); -} - -#[test] -fn test_add_stake_limit_aggregate_fail() { - new_test_ext(1).execute_with(|| { - let hotkey_account_id = U256::from(533453); - let coldkey_account_id = U256::from(55453); - let amount = 900_000_000_000; - let limit_price = 6_000_000_000; - // add network - let netuid: u16 = add_dynamic_network(&hotkey_account_id, &coldkey_account_id); - - assert_ok!(SubtensorModule::add_stake_limit_aggregate( - RuntimeOrigin::signed(coldkey_account_id), - hotkey_account_id, - netuid, - amount, - limit_price, - true - )); - - // Check for the block delay - run_to_block_ext(2, true); - - // Check that event was not emitted. - assert!(System::events().iter().all(|e| { - !matches!( - &e.event, - RuntimeEvent::SubtensorModule(Event::FailedToAddAggregatedLimitedStake(..)) - ) - })); - - // Enable on_finalize code to run - run_to_block_ext(3, true); - - // Check that event was emitted. - assert!(System::events().iter().any(|e| { - matches!( - &e.event, - RuntimeEvent::SubtensorModule(Event::FailedToAddAggregatedLimitedStake(..)) - ) - })); - }); -} +// +// #[test] +// fn test_add_stake_limit_aggregate_ok() { +// new_test_ext(1).execute_with(|| { +// let hotkey_account_id = U256::from(533453); +// let coldkey_account_id = U256::from(55453); +// let amount = 900_000_000_000; // over the maximum +// let fee = DefaultStakingFee::::get(); +// +// // add network +// let netuid: u16 = add_dynamic_network(&hotkey_account_id, &coldkey_account_id); +// +// // Forse-set alpha in and tao reserve to make price equal 1.5 +// let tao_reserve: U96F32 = U96F32::from_num(150_000_000_000_u64); +// let alpha_in: U96F32 = U96F32::from_num(100_000_000_000_u64); +// SubnetTAO::::insert(netuid, tao_reserve.to_num::()); +// SubnetAlphaIn::::insert(netuid, alpha_in.to_num::()); +// let current_price: U96F32 = U96F32::from_num(SubtensorModule::get_alpha_price(netuid)); +// assert_eq!(current_price, U96F32::from_num(1.5)); +// +// // Give it some $$$ in his coldkey balance +// SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, amount); +// +// // Setup limit price so that it doesn't peak above 4x of current price +// // The amount that can be executed at this price is 450 TAO only +// // Alpha produced will be equal to 75 = 450*100/(450+150) +// let limit_price = 6_000_000_000; +// let expected_executed_stake = 75_000_000_000; +// +// // Add stake with slippage safety and check if the result is ok +// assert_ok!(SubtensorModule::add_stake_limit_aggregate( +// RuntimeOrigin::signed(coldkey_account_id), +// hotkey_account_id, +// netuid, +// amount, +// limit_price, +// true +// )); +// +// // Check for the block delay +// run_to_block_ext(2, true); +// +// // Check that event was not emitted. +// assert!(System::events().iter().all(|e| { +// !matches!( +// &e.event, +// RuntimeEvent::SubtensorModule(Event::AggregatedLimitedStakeAdded(..)) +// ) +// })); +// +// // Enable on_finalize code to run +// run_to_block_ext(3, true); +// +// // Check if stake has increased only by 75 Alpha +// assert_abs_diff_eq!( +// SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( +// &hotkey_account_id, +// &coldkey_account_id, +// netuid +// ), +// expected_executed_stake - fee, +// epsilon = expected_executed_stake / 1000, +// ); +// +// // Check that 450 TAO balance still remains free on coldkey +// assert_abs_diff_eq!( +// SubtensorModule::get_coldkey_balance(&coldkey_account_id), +// 450_000_000_000, +// epsilon = 10_000 +// ); +// +// // Check that price has updated to ~24 = (150+450) / (100 - 75) +// let exp_price = U96F32::from_num(24.0); +// let current_price: U96F32 = U96F32::from_num(SubtensorModule::get_alpha_price(netuid)); +// assert_abs_diff_eq!( +// exp_price.to_num::(), +// current_price.to_num::(), +// epsilon = 0.0001, +// ); +// +// // Check that event was emitted. +// assert!(System::events().iter().any(|e| { +// matches!( +// &e.event, +// RuntimeEvent::SubtensorModule(Event::StakeAdded(..)) +// ) +// })); +// // Check that event was emitted. +// assert!(System::events().iter().any(|e| { +// matches!( +// &e.event, +// RuntimeEvent::SubtensorModule(Event::AggregatedLimitedStakeAdded(..)) +// ) +// })); +// }); +// } +// +// #[test] +// fn test_add_stake_limit_aggregate_fail() { +// new_test_ext(1).execute_with(|| { +// let hotkey_account_id = U256::from(533453); +// let coldkey_account_id = U256::from(55453); +// let amount = 900_000_000_000; +// let limit_price = 6_000_000_000; +// // add network +// let netuid: u16 = add_dynamic_network(&hotkey_account_id, &coldkey_account_id); +// +// assert_ok!(SubtensorModule::add_stake_limit_aggregate( +// RuntimeOrigin::signed(coldkey_account_id), +// hotkey_account_id, +// netuid, +// amount, +// limit_price, +// true +// )); +// +// // Check for the block delay +// run_to_block_ext(2, true); +// +// // Check that event was not emitted. +// assert!(System::events().iter().all(|e| { +// !matches!( +// &e.event, +// RuntimeEvent::SubtensorModule(Event::FailedToAddAggregatedLimitedStake(..)) +// ) +// })); +// +// // Enable on_finalize code to run +// run_to_block_ext(3, true); +// +// // Check that event was emitted. +// assert!(System::events().iter().any(|e| { +// matches!( +// &e.event, +// RuntimeEvent::SubtensorModule(Event::FailedToAddAggregatedLimitedStake(..)) +// ) +// })); +// }); +// } #[test] fn test_add_stake_limit_fill_or_kill() { @@ -5031,120 +5031,58 @@ fn test_add_stake_limit_fill_or_kill() { amount, limit_price, false - ), - Error::::SlippageTooHigh - ); - - // Lower the amount and it should succeed now - let amount_ok = 450_000_000_000; // fits the maximum - assert_ok!(SubtensorModule::add_stake_limit( - RuntimeOrigin::signed(coldkey_account_id), - hotkey_account_id, - netuid, - amount_ok, - limit_price, - false - )); - }); -} - -#[test] -fn test_add_stake_limit_partial_zero_max_stake_amount_error() { - new_test_ext(1).execute_with(|| { - let hotkey_account_id = U256::from(533453); - let coldkey_account_id = U256::from(55453); - - // Exact values from the error: - // https://taostats.io/extrinsic/5338471-0009?network=finney - let amount = 19980000000; - let limit_price = 26953618; - let tao_reserve: U96F32 = U96F32::from_num(5_032_494_439_940_u64); - let alpha_in: U96F32 = U96F32::from_num(186_268_425_402_874_u64); - - let netuid: u16 = add_dynamic_network(&hotkey_account_id, &coldkey_account_id); - SubnetTAO::::insert(netuid, tao_reserve.to_num::()); - SubnetAlphaIn::::insert(netuid, alpha_in.to_num::()); - - SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, amount); - - assert_noop!( - SubtensorModule::add_stake_limit( - RuntimeOrigin::signed(coldkey_account_id), - hotkey_account_id, - netuid, - amount, - limit_price, - true - ), - Error::::ZeroMaxStakeAmount - ); - }); -} - -#[test] -fn test_remove_stake_limit_ok() { - new_test_ext(1).execute_with(|| { - let hotkey_account_id = U256::from(533453); - let coldkey_account_id = U256::from(55453); - let stake_amount = 300_000_000_000; - let unstake_amount = 150_000_000_000; - let fee = DefaultStakingFee::::get(); - - // add network - let netuid: u16 = add_dynamic_network(&hotkey_account_id, &coldkey_account_id); - - // Give the neuron some stake to remove - SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( - &hotkey_account_id, - &coldkey_account_id, - netuid, - stake_amount, - ); - let alpha_before = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( - &hotkey_account_id, - &coldkey_account_id, - netuid, - ); - - // Forse-set alpha in and tao reserve to make price equal 1.5 - let tao_reserve: U96F32 = U96F32::from_num(150_000_000_000_u64); - let alpha_in: U96F32 = U96F32::from_num(100_000_000_000_u64); - SubnetTAO::::insert(netuid, tao_reserve.to_num::()); - SubnetAlphaIn::::insert(netuid, alpha_in.to_num::()); - let current_price: U96F32 = U96F32::from_num(SubtensorModule::get_alpha_price(netuid)); - assert_eq!(current_price, U96F32::from_num(1.5)); - - // Setup limit price so resulting average price doesn't drop by more than 10% from current price - let limit_price = 1_350_000_000; - - // Alpha unstaked = 150 / 1.35 - 100 ~ 11.1 - let expected_alpha_reduction = 11_111_111_111; + ), + Error::::SlippageTooHigh + ); - // Remove stake with slippage safety - assert_ok!(SubtensorModule::remove_stake_limit( + // Lower the amount and it should succeed now + let amount_ok = 450_000_000_000; // fits the maximum + assert_ok!(SubtensorModule::add_stake_limit( RuntimeOrigin::signed(coldkey_account_id), hotkey_account_id, netuid, - unstake_amount, + amount_ok, limit_price, - true + false )); + }); +} - // Check if stake has decreased only by - assert_abs_diff_eq!( - SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( - &hotkey_account_id, - &coldkey_account_id, - netuid +#[test] +fn test_add_stake_limit_partial_zero_max_stake_amount_error() { + new_test_ext(1).execute_with(|| { + let hotkey_account_id = U256::from(533453); + let coldkey_account_id = U256::from(55453); + + // Exact values from the error: + // https://taostats.io/extrinsic/5338471-0009?network=finney + let amount = 19980000000; + let limit_price = 26953618; + let tao_reserve: U96F32 = U96F32::from_num(5_032_494_439_940_u64); + let alpha_in: U96F32 = U96F32::from_num(186_268_425_402_874_u64); + + let netuid: u16 = add_dynamic_network(&hotkey_account_id, &coldkey_account_id); + SubnetTAO::::insert(netuid, tao_reserve.to_num::()); + SubnetAlphaIn::::insert(netuid, alpha_in.to_num::()); + + SubtensorModule::add_balance_to_coldkey_account(&coldkey_account_id, amount); + + assert_noop!( + SubtensorModule::add_stake_limit( + RuntimeOrigin::signed(coldkey_account_id), + hotkey_account_id, + netuid, + amount, + limit_price, + true ), - alpha_before - expected_alpha_reduction - fee, - epsilon = expected_alpha_reduction / 1_000, + Error::::ZeroMaxStakeAmount ); }); } #[test] -fn test_remove_stake_limit_aggregate_ok() { +fn test_remove_stake_limit_ok() { new_test_ext(1).execute_with(|| { let hotkey_account_id = U256::from(533453); let coldkey_account_id = U256::from(55453); @@ -5183,7 +5121,7 @@ fn test_remove_stake_limit_aggregate_ok() { let expected_alpha_reduction = 11_111_111_111; // Remove stake with slippage safety - assert_ok!(SubtensorModule::remove_stake_limit_aggregate( + assert_ok!(SubtensorModule::remove_stake_limit( RuntimeOrigin::signed(coldkey_account_id), hotkey_account_id, netuid, @@ -5192,20 +5130,6 @@ fn test_remove_stake_limit_aggregate_ok() { true )); - // Check for the block delay - run_to_block_ext(2, true); - - // Check that event was not emitted. - assert!(System::events().iter().all(|e| { - !matches!( - &e.event, - RuntimeEvent::SubtensorModule(Event::AggregatedLimitedStakeRemoved(..)) - ) - })); - - // Enable on_finalize code to run - run_to_block_ext(3, true); - // Check if stake has decreased only by assert_abs_diff_eq!( SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( @@ -5216,75 +5140,151 @@ fn test_remove_stake_limit_aggregate_ok() { alpha_before - expected_alpha_reduction - fee, epsilon = expected_alpha_reduction / 1_000, ); - - // Check that event was emitted. - assert!(System::events().iter().any(|e| { - matches!( - &e.event, - RuntimeEvent::SubtensorModule(Event::StakeRemoved(..)) - ) - })); - // Check that event was emitted. - assert!(System::events().iter().any(|e| { - matches!( - &e.event, - RuntimeEvent::SubtensorModule(Event::AggregatedLimitedStakeRemoved(..)) - ) - })); - }); -} - -#[test] -fn test_remove_stake_limit_aggregate_fail() { - new_test_ext(1).execute_with(|| { - let hotkey_account_id = U256::from(533453); - let coldkey_account_id = U256::from(55453); - let stake_amount = 300_000_000; - let unstake_amount = 150_000_000_000; - let limit_price = 1_350_000_000; - // add network - let netuid: u16 = add_dynamic_network(&hotkey_account_id, &coldkey_account_id); - - // Give the neuron some stake to remove - SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( - &hotkey_account_id, - &coldkey_account_id, - netuid, - stake_amount, - ); - - assert_ok!(SubtensorModule::remove_stake_limit_aggregate( - RuntimeOrigin::signed(coldkey_account_id), - hotkey_account_id, - netuid, - unstake_amount, - limit_price, - true - )); - - // Check for the block delay - run_to_block_ext(2, true); - - // Check that event was not emitted. - assert!(System::events().iter().all(|e| { - !matches!( - &e.event, - RuntimeEvent::SubtensorModule(Event::FailedToRemoveAggregatedLimitedStake(..)) - ) - })); - - // Enable on_finalize code to run - run_to_block_ext(3, true); - - // Check that event was emitted. - assert!(System::events().iter().any(|e| { - matches!( - &e.event, - RuntimeEvent::SubtensorModule(Event::FailedToRemoveAggregatedLimitedStake(..)) - ) - })); }); } +// +// #[test] +// fn test_remove_stake_limit_aggregate_ok() { +// new_test_ext(1).execute_with(|| { +// let hotkey_account_id = U256::from(533453); +// let coldkey_account_id = U256::from(55453); +// let stake_amount = 300_000_000_000; +// let unstake_amount = 150_000_000_000; +// let fee = DefaultStakingFee::::get(); +// +// // add network +// let netuid: u16 = add_dynamic_network(&hotkey_account_id, &coldkey_account_id); +// +// // Give the neuron some stake to remove +// SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( +// &hotkey_account_id, +// &coldkey_account_id, +// netuid, +// stake_amount, +// ); +// let alpha_before = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( +// &hotkey_account_id, +// &coldkey_account_id, +// netuid, +// ); +// +// // Forse-set alpha in and tao reserve to make price equal 1.5 +// let tao_reserve: U96F32 = U96F32::from_num(150_000_000_000_u64); +// let alpha_in: U96F32 = U96F32::from_num(100_000_000_000_u64); +// SubnetTAO::::insert(netuid, tao_reserve.to_num::()); +// SubnetAlphaIn::::insert(netuid, alpha_in.to_num::()); +// let current_price: U96F32 = U96F32::from_num(SubtensorModule::get_alpha_price(netuid)); +// assert_eq!(current_price, U96F32::from_num(1.5)); +// +// // Setup limit price so resulting average price doesn't drop by more than 10% from current price +// let limit_price = 1_350_000_000; +// +// // Alpha unstaked = 150 / 1.35 - 100 ~ 11.1 +// let expected_alpha_reduction = 11_111_111_111; +// +// // Remove stake with slippage safety +// assert_ok!(SubtensorModule::remove_stake_limit_aggregate( +// RuntimeOrigin::signed(coldkey_account_id), +// hotkey_account_id, +// netuid, +// unstake_amount, +// limit_price, +// true +// )); +// +// // Check for the block delay +// run_to_block_ext(2, true); +// +// // Check that event was not emitted. +// assert!(System::events().iter().all(|e| { +// !matches!( +// &e.event, +// RuntimeEvent::SubtensorModule(Event::AggregatedLimitedStakeRemoved(..)) +// ) +// })); +// +// // Enable on_finalize code to run +// run_to_block_ext(3, true); +// +// // Check if stake has decreased only by +// assert_abs_diff_eq!( +// SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( +// &hotkey_account_id, +// &coldkey_account_id, +// netuid +// ), +// alpha_before - expected_alpha_reduction - fee, +// epsilon = expected_alpha_reduction / 1_000, +// ); +// +// // Check that event was emitted. +// assert!(System::events().iter().any(|e| { +// matches!( +// &e.event, +// RuntimeEvent::SubtensorModule(Event::StakeRemoved(..)) +// ) +// })); +// // Check that event was emitted. +// assert!(System::events().iter().any(|e| { +// matches!( +// &e.event, +// RuntimeEvent::SubtensorModule(Event::AggregatedLimitedStakeRemoved(..)) +// ) +// })); +// }); +// } +// +// #[test] +// fn test_remove_stake_limit_aggregate_fail() { +// new_test_ext(1).execute_with(|| { +// let hotkey_account_id = U256::from(533453); +// let coldkey_account_id = U256::from(55453); +// let stake_amount = 300_000_000; +// let unstake_amount = 150_000_000_000; +// let limit_price = 1_350_000_000; +// // add network +// let netuid: u16 = add_dynamic_network(&hotkey_account_id, &coldkey_account_id); +// +// // Give the neuron some stake to remove +// SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( +// &hotkey_account_id, +// &coldkey_account_id, +// netuid, +// stake_amount, +// ); +// +// assert_ok!(SubtensorModule::remove_stake_limit_aggregate( +// RuntimeOrigin::signed(coldkey_account_id), +// hotkey_account_id, +// netuid, +// unstake_amount, +// limit_price, +// true +// )); +// +// // Check for the block delay +// run_to_block_ext(2, true); +// +// // Check that event was not emitted. +// assert!(System::events().iter().all(|e| { +// !matches!( +// &e.event, +// RuntimeEvent::SubtensorModule(Event::FailedToRemoveAggregatedLimitedStake(..)) +// ) +// })); +// +// // Enable on_finalize code to run +// run_to_block_ext(3, true); +// +// // Check that event was emitted. +// assert!(System::events().iter().any(|e| { +// matches!( +// &e.event, +// RuntimeEvent::SubtensorModule(Event::FailedToRemoveAggregatedLimitedStake(..)) +// ) +// })); +// }); +// } #[test] fn test_remove_stake_limit_fill_or_kill() { @@ -5855,110 +5855,110 @@ fn test_unstake_all_alpha_works() { assert!(new_root > 100_000); }); } -#[test] -fn test_unstake_all_alpha_aggregate_works() { - new_test_ext(1).execute_with(|| { - let subnet_owner_coldkey = U256::from(1001); - let subnet_owner_hotkey = U256::from(1002); - let coldkey = U256::from(1); - let hotkey = U256::from(2); - - let stake_amount = 190_000_000_000; // 190 Alpha - - let netuid: u16 = add_dynamic_network(&subnet_owner_hotkey, &subnet_owner_coldkey); - register_ok_neuron(netuid, hotkey, coldkey, 192213123); - // Give the neuron some stake to remove - SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( - &hotkey, - &coldkey, - netuid, - stake_amount, - ); - - // Setup the Alpha pool so that removing all the Alpha will keep liq above min - let remaining_tao: I96F32 = - DefaultMinimumPoolLiquidity::::get().saturating_add(I96F32::from(10_000_000)); - let alpha_reserves: I110F18 = I110F18::from(stake_amount + 10_000_000); - let alpha = stake_amount; - - let k: I110F18 = I110F18::from_fixed(remaining_tao) - .saturating_mul(alpha_reserves.saturating_add(I110F18::from(alpha))); - let tao_reserves: I110F18 = k.safe_div(alpha_reserves); - - SubnetTAO::::insert(netuid, tao_reserves.to_num::()); - SubnetAlphaIn::::insert(netuid, alpha_reserves.to_num::()); - - // Unstake all alpha to root - assert_ok!(SubtensorModule::unstake_all_alpha_aggregate( - RuntimeOrigin::signed(coldkey), - hotkey, - )); - - // Check for the block delay - run_to_block_ext(2, true); - - // Check that event was not emitted. - assert!(System::events().iter().all(|e| { - !matches!( - &e.event, - RuntimeEvent::SubtensorModule(Event::AggregatedUnstakeAllAlphaSucceeded(..)) - ) - })); - - // Enable on_finalize code to run - run_to_block_ext(3, true); - - let new_alpha = - SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet(&hotkey, &coldkey, netuid); - assert_abs_diff_eq!(new_alpha, 0, epsilon = 1_000,); - let new_root = - SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet(&hotkey, &coldkey, 0); - assert!(new_root > 100_000); - - // Check that event was emitted. - assert!(System::events().iter().any(|e| { - matches!( - &e.event, - RuntimeEvent::SubtensorModule(Event::AggregatedUnstakeAllAlphaSucceeded(..)) - ) - })); - }); -} - -#[test] -fn test_unstake_all_alpha_aggregate_fails() { - new_test_ext(1).execute_with(|| { - let coldkey = U256::from(1); - let hotkey = U256::from(2); - - assert_ok!(SubtensorModule::unstake_all_alpha_aggregate( - RuntimeOrigin::signed(coldkey), - hotkey, - )); - - // Check for the block delay - run_to_block_ext(2, true); - - // Check that event was not emitted. - assert!(System::events().iter().all(|e| { - !matches!( - &e.event, - RuntimeEvent::SubtensorModule(Event::AggregatedUnstakeAllAlphaFailed(..)) - ) - })); - - // Enable on_finalize code to run - run_to_block_ext(3, true); - - // Check that event was emitted. - assert!(System::events().iter().any(|e| { - matches!( - &e.event, - RuntimeEvent::SubtensorModule(Event::AggregatedUnstakeAllAlphaFailed(..)) - ) - })); - }); -} +// #[test] +// fn test_unstake_all_alpha_aggregate_works() { +// new_test_ext(1).execute_with(|| { +// let subnet_owner_coldkey = U256::from(1001); +// let subnet_owner_hotkey = U256::from(1002); +// let coldkey = U256::from(1); +// let hotkey = U256::from(2); +// +// let stake_amount = 190_000_000_000; // 190 Alpha +// +// let netuid: u16 = add_dynamic_network(&subnet_owner_hotkey, &subnet_owner_coldkey); +// register_ok_neuron(netuid, hotkey, coldkey, 192213123); +// // Give the neuron some stake to remove +// SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( +// &hotkey, +// &coldkey, +// netuid, +// stake_amount, +// ); +// +// // Setup the Alpha pool so that removing all the Alpha will keep liq above min +// let remaining_tao: I96F32 = +// DefaultMinimumPoolLiquidity::::get().saturating_add(I96F32::from(10_000_000)); +// let alpha_reserves: I110F18 = I110F18::from(stake_amount + 10_000_000); +// let alpha = stake_amount; +// +// let k: I110F18 = I110F18::from_fixed(remaining_tao) +// .saturating_mul(alpha_reserves.saturating_add(I110F18::from(alpha))); +// let tao_reserves: I110F18 = k.safe_div(alpha_reserves); +// +// SubnetTAO::::insert(netuid, tao_reserves.to_num::()); +// SubnetAlphaIn::::insert(netuid, alpha_reserves.to_num::()); +// +// // Unstake all alpha to root +// assert_ok!(SubtensorModule::unstake_all_alpha_aggregate( +// RuntimeOrigin::signed(coldkey), +// hotkey, +// )); +// +// // Check for the block delay +// run_to_block_ext(2, true); +// +// // Check that event was not emitted. +// assert!(System::events().iter().all(|e| { +// !matches!( +// &e.event, +// RuntimeEvent::SubtensorModule(Event::AggregatedUnstakeAllAlphaSucceeded(..)) +// ) +// })); +// +// // Enable on_finalize code to run +// run_to_block_ext(3, true); +// +// let new_alpha = +// SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet(&hotkey, &coldkey, netuid); +// assert_abs_diff_eq!(new_alpha, 0, epsilon = 1_000,); +// let new_root = +// SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet(&hotkey, &coldkey, 0); +// assert!(new_root > 100_000); +// +// // Check that event was emitted. +// assert!(System::events().iter().any(|e| { +// matches!( +// &e.event, +// RuntimeEvent::SubtensorModule(Event::AggregatedUnstakeAllAlphaSucceeded(..)) +// ) +// })); +// }); +// } +// +// #[test] +// fn test_unstake_all_alpha_aggregate_fails() { +// new_test_ext(1).execute_with(|| { +// let coldkey = U256::from(1); +// let hotkey = U256::from(2); +// +// assert_ok!(SubtensorModule::unstake_all_alpha_aggregate( +// RuntimeOrigin::signed(coldkey), +// hotkey, +// )); +// +// // Check for the block delay +// run_to_block_ext(2, true); +// +// // Check that event was not emitted. +// assert!(System::events().iter().all(|e| { +// !matches!( +// &e.event, +// RuntimeEvent::SubtensorModule(Event::AggregatedUnstakeAllAlphaFailed(..)) +// ) +// })); +// +// // Enable on_finalize code to run +// run_to_block_ext(3, true); +// +// // Check that event was emitted. +// assert!(System::events().iter().any(|e| { +// matches!( +// &e.event, +// RuntimeEvent::SubtensorModule(Event::AggregatedUnstakeAllAlphaFailed(..)) +// ) +// })); +// }); +// } #[test] fn test_unstake_all_works() { @@ -6007,110 +6007,110 @@ fn test_unstake_all_works() { }); } -#[test] -fn test_unstake_all_aggregate_works() { - new_test_ext(1).execute_with(|| { - let subnet_owner_coldkey = U256::from(1001); - let subnet_owner_hotkey = U256::from(1002); - let coldkey = U256::from(1); - let hotkey = U256::from(2); - - let stake_amount = 190_000_000_000; // 190 Alpha - - let netuid: u16 = add_dynamic_network(&subnet_owner_hotkey, &subnet_owner_coldkey); - register_ok_neuron(netuid, hotkey, coldkey, 192213123); - // Give the neuron some stake to remove - SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( - &hotkey, - &coldkey, - netuid, - stake_amount, - ); - - // Setup the Alpha pool so that removing all the Alpha will keep liq above min - let remaining_tao: I96F32 = - DefaultMinimumPoolLiquidity::::get().saturating_add(I96F32::from(10_000_000)); - let alpha_reserves: I110F18 = I110F18::from(stake_amount + 10_000_000); - let alpha = stake_amount; - - let k: I110F18 = I110F18::from_fixed(remaining_tao) - .saturating_mul(alpha_reserves.saturating_add(I110F18::from(alpha))); - let tao_reserves: I110F18 = k.safe_div(alpha_reserves); - - SubnetTAO::::insert(netuid, tao_reserves.to_num::()); - SubnetAlphaIn::::insert(netuid, alpha_reserves.to_num::()); - - // Unstake all alpha to root - assert_ok!(SubtensorModule::unstake_all_aggregate( - RuntimeOrigin::signed(coldkey), - hotkey, - )); - - // Check for the block delay - run_to_block_ext(2, true); - - // Check that event was not emitted. - assert!(System::events().iter().all(|e| { - !matches!( - &e.event, - RuntimeEvent::SubtensorModule(Event::AggregatedUnstakeAllSucceeded(..)) - ) - })); - - // Enable on_finalize code to run - run_to_block_ext(3, true); - - let new_alpha = - SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet(&hotkey, &coldkey, netuid); - assert_abs_diff_eq!(new_alpha, 0, epsilon = 1_000,); - let new_balance = SubtensorModule::get_coldkey_balance(&coldkey); - assert!(new_balance > 100_000); - - // Check that event was emitted. - assert!(System::events().iter().any(|e| { - matches!( - &e.event, - RuntimeEvent::SubtensorModule(Event::AggregatedUnstakeAllSucceeded(..)) - ) - })); - }); -} - -#[test] -fn test_unstake_all_aggregate_fails() { - new_test_ext(1).execute_with(|| { - let coldkey = U256::from(1); - let hotkey = U256::from(2); - - // Unstake all alpha to root - assert_ok!(SubtensorModule::unstake_all_aggregate( - RuntimeOrigin::signed(coldkey), - hotkey, - )); - - // Check for the block delay - run_to_block_ext(2, true); - - // Check that event was not emitted. - assert!(System::events().iter().all(|e| { - !matches!( - &e.event, - RuntimeEvent::SubtensorModule(Event::AggregatedUnstakeAllFailed(..)) - ) - })); - - // Enable on_finalize code to run - run_to_block_ext(3, true); - - // Check that event was emitted. - assert!(System::events().iter().any(|e| { - matches!( - &e.event, - RuntimeEvent::SubtensorModule(Event::AggregatedUnstakeAllFailed(..)) - ) - })); - }); -} +// #[test] +// fn test_unstake_all_aggregate_works() { +// new_test_ext(1).execute_with(|| { +// let subnet_owner_coldkey = U256::from(1001); +// let subnet_owner_hotkey = U256::from(1002); +// let coldkey = U256::from(1); +// let hotkey = U256::from(2); +// +// let stake_amount = 190_000_000_000; // 190 Alpha +// +// let netuid: u16 = add_dynamic_network(&subnet_owner_hotkey, &subnet_owner_coldkey); +// register_ok_neuron(netuid, hotkey, coldkey, 192213123); +// // Give the neuron some stake to remove +// SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( +// &hotkey, +// &coldkey, +// netuid, +// stake_amount, +// ); +// +// // Setup the Alpha pool so that removing all the Alpha will keep liq above min +// let remaining_tao: I96F32 = +// DefaultMinimumPoolLiquidity::::get().saturating_add(I96F32::from(10_000_000)); +// let alpha_reserves: I110F18 = I110F18::from(stake_amount + 10_000_000); +// let alpha = stake_amount; +// +// let k: I110F18 = I110F18::from_fixed(remaining_tao) +// .saturating_mul(alpha_reserves.saturating_add(I110F18::from(alpha))); +// let tao_reserves: I110F18 = k.safe_div(alpha_reserves); +// +// SubnetTAO::::insert(netuid, tao_reserves.to_num::()); +// SubnetAlphaIn::::insert(netuid, alpha_reserves.to_num::()); +// +// // Unstake all alpha to root +// assert_ok!(SubtensorModule::unstake_all_aggregate( +// RuntimeOrigin::signed(coldkey), +// hotkey, +// )); +// +// // Check for the block delay +// run_to_block_ext(2, true); +// +// // Check that event was not emitted. +// assert!(System::events().iter().all(|e| { +// !matches!( +// &e.event, +// RuntimeEvent::SubtensorModule(Event::AggregatedUnstakeAllSucceeded(..)) +// ) +// })); +// +// // Enable on_finalize code to run +// run_to_block_ext(3, true); +// +// let new_alpha = +// SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet(&hotkey, &coldkey, netuid); +// assert_abs_diff_eq!(new_alpha, 0, epsilon = 1_000,); +// let new_balance = SubtensorModule::get_coldkey_balance(&coldkey); +// assert!(new_balance > 100_000); +// +// // Check that event was emitted. +// assert!(System::events().iter().any(|e| { +// matches!( +// &e.event, +// RuntimeEvent::SubtensorModule(Event::AggregatedUnstakeAllSucceeded(..)) +// ) +// })); +// }); +// } +// +// #[test] +// fn test_unstake_all_aggregate_fails() { +// new_test_ext(1).execute_with(|| { +// let coldkey = U256::from(1); +// let hotkey = U256::from(2); +// +// // Unstake all alpha to root +// assert_ok!(SubtensorModule::unstake_all_aggregate( +// RuntimeOrigin::signed(coldkey), +// hotkey, +// )); +// +// // Check for the block delay +// run_to_block_ext(2, true); +// +// // Check that event was not emitted. +// assert!(System::events().iter().all(|e| { +// !matches!( +// &e.event, +// RuntimeEvent::SubtensorModule(Event::AggregatedUnstakeAllFailed(..)) +// ) +// })); +// +// // Enable on_finalize code to run +// run_to_block_ext(3, true); +// +// // Check that event was emitted. +// assert!(System::events().iter().any(|e| { +// matches!( +// &e.event, +// RuntimeEvent::SubtensorModule(Event::AggregatedUnstakeAllFailed(..)) +// ) +// })); +// }); +// } #[test] fn test_increase_stake_for_hotkey_and_coldkey_on_subnet_adds_to_staking_hotkeys_map() { diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 7bc6f7ece1..948b90fcbe 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -209,7 +209,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: 268, + spec_version: 269, impl_version: 1, apis: RUNTIME_API_VERSIONS, transaction_version: 1, @@ -675,18 +675,18 @@ impl InstanceFilter for ProxyType { | RuntimeCall::SubtensorModule( pallet_subtensor::Call::remove_stake_limit { .. } ) - | RuntimeCall::SubtensorModule( - pallet_subtensor::Call::add_stake_aggregate { .. } - ) - | RuntimeCall::SubtensorModule( - pallet_subtensor::Call::add_stake_limit_aggregate { .. } - ) - | RuntimeCall::SubtensorModule( - pallet_subtensor::Call::remove_stake_aggregate { .. } - ) - | RuntimeCall::SubtensorModule( - pallet_subtensor::Call::remove_stake_limit_aggregate { .. } - ) + // | RuntimeCall::SubtensorModule( + // pallet_subtensor::Call::add_stake_aggregate { .. } + // ) + // | RuntimeCall::SubtensorModule( + // pallet_subtensor::Call::add_stake_limit_aggregate { .. } + // ) + // | RuntimeCall::SubtensorModule( + // pallet_subtensor::Call::remove_stake_aggregate { .. } + // ) + // | RuntimeCall::SubtensorModule( + // pallet_subtensor::Call::remove_stake_limit_aggregate { .. } + // ) | RuntimeCall::SubtensorModule(pallet_subtensor::Call::unstake_all { .. }) | RuntimeCall::SubtensorModule( pallet_subtensor::Call::unstake_all_alpha { .. } @@ -767,19 +767,18 @@ impl InstanceFilter for ProxyType { | RuntimeCall::SubtensorModule(pallet_subtensor::Call::add_stake_limit { .. }) | RuntimeCall::SubtensorModule( pallet_subtensor::Call::remove_stake_limit { .. } - ) - | RuntimeCall::SubtensorModule( - pallet_subtensor::Call::add_stake_aggregate { .. } - ) - | RuntimeCall::SubtensorModule( - pallet_subtensor::Call::add_stake_limit_aggregate { .. } - ) - | RuntimeCall::SubtensorModule( - pallet_subtensor::Call::remove_stake_aggregate { .. } - ) - | RuntimeCall::SubtensorModule( - pallet_subtensor::Call::remove_stake_limit_aggregate { .. } - ) + ) // | RuntimeCall::SubtensorModule( + // pallet_subtensor::Call::add_stake_aggregate { .. } + // ) + // | RuntimeCall::SubtensorModule( + // pallet_subtensor::Call::add_stake_limit_aggregate { .. } + // ) + // | RuntimeCall::SubtensorModule( + // pallet_subtensor::Call::remove_stake_aggregate { .. } + // ) + // | RuntimeCall::SubtensorModule( + // pallet_subtensor::Call::remove_stake_limit_aggregate { .. } + // ) ), ProxyType::Registration => matches!( c, @@ -954,7 +953,7 @@ impl pallet_registry::Config for Runtime { } parameter_types! { - pub const MaxCommitFieldsInner: u32 = 2; + pub const MaxCommitFieldsInner: u32 = 3; pub const CommitmentInitialDeposit: Balance = 0; // Free pub const CommitmentFieldDeposit: Balance = 0; // Free }