diff --git a/pallets/subtensor/src/swap/swap_coldkey.rs b/pallets/subtensor/src/swap/swap_coldkey.rs index 2358fcecf1..e3a9c8a27c 100644 --- a/pallets/subtensor/src/swap/swap_coldkey.rs +++ b/pallets/subtensor/src/swap/swap_coldkey.rs @@ -37,8 +37,6 @@ impl Pallet { // Transfer any remaining balance from old_coldkey to new_coldkey Self::transfer_all_tao_and_kill(old_coldkey, new_coldkey)?; - Self::set_last_tx_block(new_coldkey, Self::get_current_block_as_u64()); - Self::deposit_event(Event::ColdkeySwapped { old_coldkey: old_coldkey.clone(), new_coldkey: new_coldkey.clone(), diff --git a/pallets/subtensor/src/swap/swap_hotkey.rs b/pallets/subtensor/src/swap/swap_hotkey.rs index 944ea5877f..791786d027 100644 --- a/pallets/subtensor/src/swap/swap_hotkey.rs +++ b/pallets/subtensor/src/swap/swap_hotkey.rs @@ -24,7 +24,6 @@ impl Pallet { /// # Errors /// /// * `NonAssociatedColdKey` - If the coldkey does not own the old hotkey. - /// * `HotKeySetTxRateLimitExceeded` - If the transaction rate limit is exceeded. /// * `NewHotKeyIsSameWithOld` - If the new hotkey is the same as the old hotkey. /// * `HotKeyAlreadyRegisteredInSubNet` - If the new hotkey is already registered in the subnet. /// * `NewHotKeyNotCleanForRootSwap` - If the swap touches root and the new hotkey @@ -52,17 +51,6 @@ impl Pallet { // 4. Ensure the new hotkey is different from the old one ensure!(old_hotkey != new_hotkey, Error::::NewHotKeyIsSameWithOld); - // 5. Get the current block number - let block: u64 = Self::get_current_block_as_u64(); - - // 6. Ensure the transaction rate limit is not exceeded - ensure!( - !Self::exceeds_tx_rate_limit(Self::get_last_tx_block(&coldkey), block), - Error::::HotKeySetTxRateLimitExceeded - ); - - weight.saturating_accrue(T::DbWeight::get().reads(2)); - match netuid { // 7. Ensure the hotkey is not registered on the network before, if netuid is provided Some(netuid) => { @@ -96,12 +84,7 @@ impl Pallet { ); } - // 8. Swap LastTxBlock - let last_tx_block: u64 = Self::get_last_tx_block(old_hotkey); - Self::set_last_tx_block(new_hotkey, last_tx_block); - weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 1)); - - // 9. Swap LastTxBlockDelegateTake + // 8. Swap LastTxBlockDelegateTake let last_tx_block_delegate_take: u64 = Self::get_last_tx_block_delegate_take(old_hotkey); Self::set_last_tx_block_delegate_take(new_hotkey, last_tx_block_delegate_take); weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 1)); @@ -144,11 +127,7 @@ impl Pallet { keep_stake, )?; - // 20. Update the last transaction block for the coldkey - Self::set_last_tx_block(&coldkey, block); - weight.saturating_accrue(T::DbWeight::get().writes(1)); - - // 21. Emit an event for the hotkey swap + // 20. Emit an event for the hotkey swap Self::deposit_event(Event::HotkeySwapped { coldkey, old_hotkey: old_hotkey.clone(), @@ -359,10 +338,10 @@ impl Pallet { keep_stake, )?; - // 10. Update the last transaction block for the coldkey - Self::set_last_tx_block(coldkey, block); + // 10. Record the per-subnet swap block for the HotkeySwapOnSubnetInterval gate. + // The generic LastTxBlock setter is dropped together with its removed check. LastHotkeySwapOnNetuid::::insert(netuid, coldkey, block); - weight.saturating_accrue(T::DbWeight::get().writes(2)); + weight.saturating_accrue(T::DbWeight::get().writes(1)); // 11. Emit an event for the hotkey swap Self::deposit_event(Event::HotkeySwappedOnSubnet { diff --git a/pallets/subtensor/src/tests/swap_hotkey.rs b/pallets/subtensor/src/tests/swap_hotkey.rs index 3fdacf23be..d918f05794 100644 --- a/pallets/subtensor/src/tests/swap_hotkey.rs +++ b/pallets/subtensor/src/tests/swap_hotkey.rs @@ -719,9 +719,9 @@ fn test_swap_hotkey_with_multiple_coldkeys_and_subnets() { }); } -// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_hotkey -- test_swap_hotkey_tx_rate_limit_exceeded --exact --nocapture +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_hotkey -- test_swap_hotkey_no_tx_rate_limit --exact --nocapture #[test] -fn test_swap_hotkey_tx_rate_limit_exceeded() { +fn test_swap_hotkey_no_tx_rate_limit() { new_test_ext(1).execute_with(|| { let netuid = NetUid::from(1); let tempo: u16 = 13; @@ -731,16 +731,9 @@ fn test_swap_hotkey_tx_rate_limit_exceeded() { let coldkey = U256::from(3); let swap_cost = SubtensorModule::get_key_swap_cost() * 2.into(); - let tx_rate_limit = 1; - - // Get the current transaction rate limit - let current_tx_rate_limit = SubtensorModule::get_tx_rate_limit(); - log::info!("current_tx_rate_limit: {current_tx_rate_limit:?}"); - - // Set the transaction rate limit - SubtensorModule::set_tx_rate_limit(tx_rate_limit); - // assert the rate limit is set to 1000 blocks - assert_eq!(SubtensorModule::get_tx_rate_limit(), tx_rate_limit); + // Set a strict tx rate limit to prove it no longer gates hotkey swaps. + SubtensorModule::set_tx_rate_limit(1); + assert_eq!(SubtensorModule::get_tx_rate_limit(), 1); // Setup initial state add_network(netuid, tempo, 0); @@ -756,20 +749,8 @@ fn test_swap_hotkey_tx_rate_limit_exceeded() { false, )); - // Attempt to perform another swap immediately, which should fail due to rate limit - assert_err!( - SubtensorModule::do_swap_hotkey( - <::RuntimeOrigin>::signed(coldkey), - &new_hotkey_1, - &new_hotkey_2, - None, - false, - ), - Error::::HotKeySetTxRateLimitExceeded - ); - - // move in time past the rate limit - step_block(1001); + // A second swap in the same block now succeeds (rate limit removed); the fee is + // charged again, so the coldkey must have funded two swaps. assert_ok!(SubtensorModule::do_swap_hotkey( <::RuntimeOrigin>::signed(coldkey), &new_hotkey_1, @@ -1567,12 +1548,9 @@ fn test_swap_hotkey_swap_rate_limits() { let netuid = add_dynamic_network(&old_hotkey, &coldkey); add_balance_to_coldkey_account(&coldkey, 1_000_000_000_000_u64.into()); - let last_tx_block = 123; let delegate_take_block = 4567; let child_key_take_block = 8910; - // Set the last tx block for the old hotkey - SubtensorModule::set_last_tx_block(&old_hotkey, last_tx_block); // Set the last delegate take block for the old hotkey SubtensorModule::set_last_tx_block_delegate_take(&old_hotkey, delegate_take_block); // Set last childkey take block for the old hotkey @@ -1587,11 +1565,8 @@ fn test_swap_hotkey_swap_rate_limits() { false, )); - // Check for new hotkey - assert_eq!( - SubtensorModule::get_last_tx_block(&new_hotkey), - last_tx_block - ); + // Check for new hotkey (LastTxBlock is no longer transferred: the generic tx rate + // limit was removed, so it is dead state). The take rate limits are still active. assert_eq!( SubtensorModule::get_last_tx_block_delegate_take(&new_hotkey), delegate_take_block diff --git a/pallets/subtensor/src/tests/swap_hotkey_with_subnet.rs b/pallets/subtensor/src/tests/swap_hotkey_with_subnet.rs index 426572bdcd..aa248b6ddc 100644 --- a/pallets/subtensor/src/tests/swap_hotkey_with_subnet.rs +++ b/pallets/subtensor/src/tests/swap_hotkey_with_subnet.rs @@ -774,69 +774,6 @@ fn test_swap_hotkey_with_multiple_coldkeys_and_subnets() { }); } -// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_hotkey_with_subnet -- test_swap_hotkey_tx_rate_limit_exceeded --exact --nocapture -#[test] -fn test_swap_hotkey_tx_rate_limit_exceeded() { - new_test_ext(1).execute_with(|| { - let netuid = NetUid::from(1); - let tempo: u16 = 13; - let old_hotkey = U256::from(1); - let new_hotkey_1 = U256::from(2); - let new_hotkey_2 = U256::from(4); - let coldkey = U256::from(3); - let swap_cost = TaoBalance::from(1_000_000_000u64) * 2.into(); - - let tx_rate_limit = 1; - - // Get the current transaction rate limit - let current_tx_rate_limit = SubtensorModule::get_tx_rate_limit(); - log::info!("current_tx_rate_limit: {current_tx_rate_limit:?}"); - - // Set the transaction rate limit - SubtensorModule::set_tx_rate_limit(tx_rate_limit); - // assert the rate limit is set to 1000 blocks - assert_eq!(SubtensorModule::get_tx_rate_limit(), tx_rate_limit); - - // Setup initial state - add_network(netuid, tempo, 0); - register_ok_neuron(netuid, old_hotkey, coldkey, 0); - add_balance_to_coldkey_account(&coldkey, swap_cost); - - // Perform the first swap - System::set_block_number(System::block_number() + HotkeySwapOnSubnetInterval::get()); - assert_ok!(SubtensorModule::do_swap_hotkey( - RuntimeOrigin::signed(coldkey), - &old_hotkey, - &new_hotkey_1, - Some(netuid), - false - ),); - - // Attempt to perform another swap immediately, which should fail due to rate limit - assert_err!( - SubtensorModule::do_swap_hotkey( - RuntimeOrigin::signed(coldkey), - &old_hotkey, - &new_hotkey_1, - Some(netuid), - false - ), - Error::::HotKeySetTxRateLimitExceeded - ); - - // move in time past the rate limit - step_block(1001); - System::set_block_number(System::block_number() + HotkeySwapOnSubnetInterval::get()); - assert_ok!(SubtensorModule::do_swap_hotkey( - <::RuntimeOrigin>::signed(coldkey), - &new_hotkey_1, - &new_hotkey_2, - None, - false - )); - }); -} - // SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_hotkey_with_subnet -- test_do_swap_hotkey_err_not_owner --exact --nocapture #[test] fn test_do_swap_hotkey_err_not_owner() { @@ -1574,15 +1511,12 @@ fn test_swap_hotkey_swap_rate_limits() { let new_hotkey = U256::from(2); let coldkey = U256::from(3); - let last_tx_block = 123; let delegate_take_block = 4567; let child_key_take_block = 8910; let netuid = add_dynamic_network(&old_hotkey, &coldkey); add_balance_to_coldkey_account(&coldkey, 1_000_000_000_000_u64.into()); - // Set the last tx block for the old hotkey - SubtensorModule::set_last_tx_block(&old_hotkey, last_tx_block); // Set the last delegate take block for the old hotkey SubtensorModule::set_last_tx_block_delegate_take(&old_hotkey, delegate_take_block); // Set last childkey take block for the old hotkey @@ -1598,11 +1532,8 @@ fn test_swap_hotkey_swap_rate_limits() { false ),); - // Check for new hotkey - assert_eq!( - SubtensorModule::get_last_tx_block(&new_hotkey), - last_tx_block - ); + // Check for new hotkey (LastTxBlock is no longer transferred: the generic tx rate + // limit was removed. assert_eq!( SubtensorModule::get_last_tx_block_delegate_take(&new_hotkey), delegate_take_block