Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enforce rate limits in decrease take #626

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 16 additions & 3 deletions pallets/subtensor/src/staking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,9 +155,22 @@ impl<T: Config> Pallet<T> {
let min_take = MinTake::<T>::get();
ensure!(take >= min_take, Error::<T>::DelegateTakeTooLow);

// Enforce the rate limit (independently on do_add_stake rate limits)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Enforce the rate limit (independently on do_add_stake rate limits)
// Enforce the rate limit (independent of do_add_stake rate limits)

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),
block
),
Error::<T>::DelegateTxRateLimitExceeded
);

// --- 4. Set the new take value.
Delegates::<T>::insert(hotkey.clone(), take);

// Set last block for rate limiting
Self::set_last_tx_block_delegate_take(&coldkey, block);

// --- 5. Emit the take value.
log::info!(
"TakeDecreased( coldkey:{:?}, hotkey:{:?}, take:{:?} )",
Expand Down Expand Up @@ -241,12 +254,12 @@ impl<T: Config> Pallet<T> {
Error::<T>::DelegateTxRateLimitExceeded
);

// Set last block for rate limiting
Self::set_last_tx_block_delegate_take(&coldkey, block);

// --- 6. Set the new take value.
Delegates::<T>::insert(hotkey.clone(), take);

// Set last block for rate limiting
Self::set_last_tx_block_delegate_take(&coldkey, block);

// --- 7. Emit the take value.
log::info!(
"TakeIncreased( coldkey:{:?}, hotkey:{:?}, take:{:?} )",
Expand Down
129 changes: 129 additions & 0 deletions pallets/subtensor/tests/staking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2824,6 +2824,9 @@ fn test_can_set_min_take_ok() {
u16::MAX / 10
));

// Wait so that we can decrease take
step_block(1 + InitialTxDelegateTakeRateLimit::get() as u16);

// Coldkey / hotkey 0 decreases take to min
assert_ok!(SubtensorModule::do_decrease_take(
<<Test as Config>::RuntimeOrigin>::signed(coldkey0),
Expand Down Expand Up @@ -3136,6 +3139,132 @@ fn test_rate_limits_enforced_on_increase_take() {
});
}

// Test rate-limiting on decrease_take + increase_take
#[test]
fn test_rate_limits_enforced_on_increase_take_after_decrease() {
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, 0, 0);
register_ok_neuron(netuid, hotkey0, coldkey0, 124124);

// Coldkey / hotkey 0 become delegates with max take
assert_ok!(SubtensorModule::do_become_delegate(
<<Test as Config>::RuntimeOrigin>::signed(coldkey0),
hotkey0,
pallet_subtensor::MaxTake::<Test>::get()
));

// Wait so that we can decrease take
step_block(1 + InitialTxDelegateTakeRateLimit::get() as u16);

// Coldkey / hotkey 0 decreases take
assert_ok!(SubtensorModule::do_decrease_take(
<<Test as Config>::RuntimeOrigin>::signed(coldkey0),
hotkey0,
SubtensorModule::get_min_take()
));

// Attempt to immediately increase fails due to rate limit
assert_eq!(
SubtensorModule::do_increase_take(
<<Test as Config>::RuntimeOrigin>::signed(coldkey0),
hotkey0,
pallet_subtensor::MaxTake::<Test>::get()
),
Err(Error::<Test>::DelegateTxRateLimitExceeded.into())
);
assert_eq!(
SubtensorModule::get_hotkey_take(&hotkey0),
SubtensorModule::get_min_take()
);

// After number of blocks, take can be increased
step_block(1 + InitialTxDelegateTakeRateLimit::get() as u16);

// Can increase after waiting
assert_ok!(SubtensorModule::do_increase_take(
<<Test as Config>::RuntimeOrigin>::signed(coldkey0),
hotkey0,
pallet_subtensor::MaxTake::<Test>::get()
));
assert_eq!(
SubtensorModule::get_hotkey_take(&hotkey0),
pallet_subtensor::MaxTake::<Test>::get()
);
});
}

// Test rate-limiting on decrease_take
#[test]
fn test_rate_limits_enforced_on_decrease_take() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this the expected behaviour? imo, one should be able to decrease without rate limit, but not increase until after the rate limit since the last change (increase or decrease)

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, 0, 0);
register_ok_neuron(netuid, hotkey0, coldkey0, 124124);

// Coldkey / hotkey 0 become delegates with max take
assert_ok!(SubtensorModule::do_become_delegate(
<<Test as Config>::RuntimeOrigin>::signed(coldkey0),
hotkey0,
pallet_subtensor::MaxTake::<Test>::get()
));

// Wait so that we can decrease take first time
step_block(1 + InitialTxDelegateTakeRateLimit::get() as u16);

// Coldkey / hotkey 0 decreases take
assert_ok!(SubtensorModule::do_decrease_take(
<<Test as Config>::RuntimeOrigin>::signed(coldkey0),
hotkey0,
SubtensorModule::get_min_take() + 1
));

// Attempt to immediately decrease again fails due to rate limit
assert_eq!(
SubtensorModule::do_decrease_take(
<<Test as Config>::RuntimeOrigin>::signed(coldkey0),
hotkey0,
SubtensorModule::get_min_take()
),
Err(Error::<Test>::DelegateTxRateLimitExceeded.into())
);
assert_eq!(
SubtensorModule::get_hotkey_take(&hotkey0),
SubtensorModule::get_min_take() + 1
);

// After number of blocks, take can be decreased
step_block(1 + InitialTxDelegateTakeRateLimit::get() as u16);

// Can increase after waiting
assert_ok!(SubtensorModule::do_decrease_take(
<<Test as Config>::RuntimeOrigin>::signed(coldkey0),
hotkey0,
SubtensorModule::get_min_take()
));
assert_eq!(
SubtensorModule::get_hotkey_take(&hotkey0),
SubtensorModule::get_min_take()
);
});
}

// Helper function to set up a test environment
fn setup_test_environment() -> (AccountId, AccountId, AccountId) {
let current_coldkey = U256::from(1);
Expand Down
Loading