diff --git a/pallets/subtensor/src/staking/decrease_take.rs b/pallets/subtensor/src/staking/decrease_take.rs index 8742f809db..c227aad8a3 100644 --- a/pallets/subtensor/src/staking/decrease_take.rs +++ b/pallets/subtensor/src/staking/decrease_take.rs @@ -57,7 +57,11 @@ impl Pallet { // --- 4. Set the new take value. Delegates::::insert(hotkey.clone(), take); - // --- 5. Emit the take value. + // --- 5. Set last block for rate limiting + let block: u64 = Self::get_current_block_as_u64(); + Self::set_last_tx_block_delegate_take(&hotkey, block); + + // --- 6. Emit the take value. log::debug!( "TakeDecreased( coldkey:{:?}, hotkey:{:?}, take:{:?} )", coldkey, diff --git a/pallets/subtensor/src/staking/increase_take.rs b/pallets/subtensor/src/staking/increase_take.rs index 0218184471..349f86e7cf 100644 --- a/pallets/subtensor/src/staking/increase_take.rs +++ b/pallets/subtensor/src/staking/increase_take.rs @@ -61,14 +61,14 @@ impl Pallet { let block: u64 = Self::get_current_block_as_u64(); ensure!( !Self::exceeds_tx_delegate_take_rate_limit( - Self::get_last_tx_block_delegate_take(&coldkey), + Self::get_last_tx_block_delegate_take(&hotkey), block ), Error::::DelegateTxRateLimitExceeded ); // Set last block for rate limiting - Self::set_last_tx_block_delegate_take(&coldkey, block); + Self::set_last_tx_block_delegate_take(&hotkey, block); // --- 6. Set the new take value. Delegates::::insert(hotkey.clone(), take); diff --git a/pallets/subtensor/src/tests/staking.rs b/pallets/subtensor/src/tests/staking.rs index e5ed95f41d..5d9db9f4e8 100644 --- a/pallets/subtensor/src/tests/staking.rs +++ b/pallets/subtensor/src/tests/staking.rs @@ -1671,6 +1671,70 @@ fn test_rate_limits_enforced_on_increase_take() { }); } +// Test rate-limiting on an increase take just after a decrease take +// Prevents a Validator from decreasing take and then increasing it immediately after. +#[test] +fn test_rate_limits_enforced_on_decrease_before_increase_take() { + new_test_ext(1).execute_with(|| { + // Make account + let hotkey0 = U256::from(1); + let coldkey0 = U256::from(3); + + // Add balance + SubtensorModule::add_balance_to_coldkey_account(&coldkey0, 100000); + + // Register the neuron to a new network + let netuid = 1; + add_network(netuid, 1, 0); + register_ok_neuron(netuid, hotkey0, coldkey0, 124124); + + // Coldkey / hotkey 0 become delegates with 9% take + Delegates::::insert(hotkey0, SubtensorModule::get_min_delegate_take() + 1); + assert_eq!( + SubtensorModule::get_hotkey_take(&hotkey0), + SubtensorModule::get_min_delegate_take() + 1 + ); + + // Decrease take + assert_ok!(SubtensorModule::do_decrease_take( + RuntimeOrigin::signed(coldkey0), + hotkey0, + SubtensorModule::get_min_delegate_take() + )); // Verify decrease + assert_eq!( + SubtensorModule::get_hotkey_take(&hotkey0), + SubtensorModule::get_min_delegate_take() + ); + + // Increase take immediately after + assert_eq!( + SubtensorModule::do_increase_take( + RuntimeOrigin::signed(coldkey0), + hotkey0, + SubtensorModule::get_min_delegate_take() + 1 + ), + Err(Error::::DelegateTxRateLimitExceeded.into()) + ); // Verify no change + assert_eq!( + SubtensorModule::get_hotkey_take(&hotkey0), + SubtensorModule::get_min_delegate_take() + ); + + step_block(1 + InitialTxDelegateTakeRateLimit::get() as u16); + + // Can increase after waiting + assert_ok!(SubtensorModule::do_increase_take( + RuntimeOrigin::signed(coldkey0), + hotkey0, + SubtensorModule::get_min_delegate_take() + 1 + )); // Verify increase + assert_eq!( + SubtensorModule::get_hotkey_take(&hotkey0), + SubtensorModule::get_min_delegate_take() + 1 + ); + }); +} + #[test] fn test_get_total_delegated_stake_after_unstaking() { new_test_ext(1).execute_with(|| { diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index fa47d5be21..a8774795b9 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -228,7 +228,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: 243, + spec_version: 244, impl_version: 1, apis: RUNTIME_API_VERSIONS, transaction_version: 1,