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

Fix/charge-for-swap-before-schedule #1141

Open
wants to merge 5 commits into
base: devnet-ready
Choose a base branch
from
Open
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
12 changes: 11 additions & 1 deletion pallets/subtensor/src/macros/dispatches.rs
Original file line number Diff line number Diff line change
Expand Up @@ -954,12 +954,13 @@ mod dispatches {
origin: OriginFor<T>,
old_coldkey: T::AccountId,
new_coldkey: T::AccountId,
swap_cost: u64,
) -> DispatchResultWithPostInfo {
// Ensure it's called with root privileges (scheduler has root privileges)
ensure_root(origin)?;
log::info!("swap_coldkey: {:?} -> {:?}", old_coldkey, new_coldkey);

Self::do_swap_coldkey(&old_coldkey, &new_coldkey)
Self::do_swap_coldkey(&old_coldkey, &new_coldkey, swap_cost)
}

/// Sets the childkey take for a given hotkey.
Expand Down Expand Up @@ -1319,13 +1320,21 @@ mod dispatches {
Error::<T>::SwapAlreadyScheduled
);

// Calculate the swap cost and ensure sufficient balance
let swap_cost = Self::get_key_swap_cost();
ensure!(
Self::can_remove_balance_from_coldkey_account(&who, swap_cost),
Error::<T>::NotEnoughBalanceToPaySwapColdKey
);

let current_block: BlockNumberFor<T> = <frame_system::Pallet<T>>::block_number();
let duration: BlockNumberFor<T> = ColdkeySwapScheduleDuration::<T>::get();
let when: BlockNumberFor<T> = current_block.saturating_add(duration);

let call = Call::<T>::swap_coldkey {
old_coldkey: who.clone(),
new_coldkey: new_coldkey.clone(),
swap_cost,
};

let bound_call = T::Preimages::bound(LocalCallOf::<T>::from(call.clone()))
Expand All @@ -1346,6 +1355,7 @@ mod dispatches {
old_coldkey: who.clone(),
new_coldkey: new_coldkey.clone(),
execution_block: when,
swap_cost,
});

Ok(().into())
Expand Down
4 changes: 4 additions & 0 deletions pallets/subtensor/src/macros/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,8 @@ mod events {
old_coldkey: T::AccountId,
/// the account ID of new coldkey
new_coldkey: T::AccountId,
/// the swap cost
swap_cost: u64,
},
/// All balance of a hotkey has been unstaked and transferred to a new coldkey
AllBalanceUnstakedAndTransferredToNewColdkey {
Expand All @@ -175,6 +177,8 @@ mod events {
new_coldkey: T::AccountId,
/// The arbitration block for the coldkey swap
execution_block: BlockNumberFor<T>,
/// The swap cost
swap_cost: u64,
},
/// The arbitration period has been extended
ArbitrationPeriodExtended {
Expand Down
5 changes: 3 additions & 2 deletions pallets/subtensor/src/swap/swap_coldkey.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ impl<T: Config> Pallet<T> {
pub fn do_swap_coldkey(
old_coldkey: &T::AccountId,
new_coldkey: &T::AccountId,
swap_cost: u64,
) -> DispatchResultWithPostInfo {
// 2. Initialize the weight for this operation
let mut weight: Weight = T::DbWeight::get().reads(2);
Expand All @@ -54,8 +55,7 @@ impl<T: Config> Pallet<T> {
Identities::<T>::insert(new_coldkey, identity);
}

// 6. Calculate the swap cost and ensure sufficient balance
let swap_cost = Self::get_key_swap_cost();
// 6. Ensure sufficient balance for the swap cost
ensure!(
Self::can_remove_balance_from_coldkey_account(old_coldkey, swap_cost),
Error::<T>::NotEnoughBalanceToPaySwapColdKey
Expand All @@ -82,6 +82,7 @@ impl<T: Config> Pallet<T> {
Self::deposit_event(Event::ColdkeySwapped {
old_coldkey: old_coldkey.clone(),
new_coldkey: new_coldkey.clone(),
swap_cost,
});

// 12. Return the result with the updated weight
Expand Down
63 changes: 56 additions & 7 deletions pallets/subtensor/src/tests/swap_coldkey.rs
Original file line number Diff line number Diff line change
Expand Up @@ -566,7 +566,8 @@ fn test_do_swap_coldkey_success() {
assert_ok!(SubtensorModule::do_swap_coldkey(
// <<Test as Config>::RuntimeOrigin>::signed(old_coldkey),
&old_coldkey,
&new_coldkey
&new_coldkey,
swap_cost
));

// Log state after swap
Expand Down Expand Up @@ -630,6 +631,7 @@ fn test_do_swap_coldkey_success() {
Event::ColdkeySwapped {
old_coldkey,
new_coldkey,
swap_cost,
}
.into(),
);
Expand Down Expand Up @@ -913,7 +915,11 @@ fn test_do_swap_coldkey_with_subnet_ownership() {
OwnedHotkeys::<Test>::insert(old_coldkey, vec![hotkey]);

// Perform the swap
assert_ok!(SubtensorModule::do_swap_coldkey(&old_coldkey, &new_coldkey));
assert_ok!(SubtensorModule::do_swap_coldkey(
&old_coldkey,
&new_coldkey,
swap_cost
));

// Verify subnet ownership transfer
assert_eq!(SubnetOwner::<Test>::get(netuid), new_coldkey);
Expand Down Expand Up @@ -1325,6 +1331,8 @@ fn test_schedule_swap_coldkey_success() {
// Add balance to the old coldkey account
SubtensorModule::add_balance_to_coldkey_account(&old_coldkey, 1000);

let swap_cost = SubtensorModule::get_key_swap_cost();

// Schedule the coldkey swap
assert_ok!(SubtensorModule::schedule_swap_coldkey(
<<Test as Config>::RuntimeOrigin>::signed(old_coldkey),
Expand All @@ -1343,6 +1351,7 @@ fn test_schedule_swap_coldkey_success() {
old_coldkey,
new_coldkey,
execution_block: expected_execution_block,
swap_cost,
}
.into(),
);
Expand Down Expand Up @@ -1403,6 +1412,8 @@ fn test_schedule_swap_coldkey_execution() {
"Initial ownership check failed"
);

let swap_cost = SubtensorModule::get_key_swap_cost();

// Schedule the swap
assert_ok!(SubtensorModule::schedule_swap_coldkey(
<<Test as Config>::RuntimeOrigin>::signed(old_coldkey),
Expand All @@ -1418,6 +1429,7 @@ fn test_schedule_swap_coldkey_execution() {
old_coldkey,
new_coldkey,
execution_block,
swap_cost,
}
.into(),
);
Expand Down Expand Up @@ -1455,6 +1467,7 @@ fn test_schedule_swap_coldkey_execution() {
Event::ColdkeySwapped {
old_coldkey,
new_coldkey,
swap_cost,
}
.into(),
);
Expand All @@ -1472,7 +1485,8 @@ fn test_direct_swap_coldkey_call_fails() {
SubtensorModule::swap_coldkey(
<<Test as Config>::RuntimeOrigin>::signed(old_coldkey),
old_coldkey,
new_coldkey
new_coldkey,
0
),
BadOrigin
);
Expand Down Expand Up @@ -1541,7 +1555,11 @@ fn test_coldkey_swap_delegate_identity_updated() {
assert!(Identities::<Test>::get(old_coldkey).is_some());
assert!(Identities::<Test>::get(new_coldkey).is_none());

assert_ok!(SubtensorModule::do_swap_coldkey(&old_coldkey, &new_coldkey));
assert_ok!(SubtensorModule::do_swap_coldkey(
&old_coldkey,
&new_coldkey,
burn_cost
));

assert!(Identities::<Test>::get(old_coldkey).is_none());
assert!(Identities::<Test>::get(new_coldkey).is_some());
Expand Down Expand Up @@ -1577,7 +1595,11 @@ fn test_coldkey_swap_no_identity_no_changes() {
assert!(Identities::<Test>::get(old_coldkey).is_none());

// Perform the coldkey swap
assert_ok!(SubtensorModule::do_swap_coldkey(&old_coldkey, &new_coldkey));
assert_ok!(SubtensorModule::do_swap_coldkey(
&old_coldkey,
&new_coldkey,
burn_cost
));

// Ensure no identities have been changed
assert!(Identities::<Test>::get(old_coldkey).is_none());
Expand Down Expand Up @@ -1621,7 +1643,11 @@ fn test_coldkey_swap_no_identity_no_changes_newcoldkey_exists() {
assert!(Identities::<Test>::get(old_coldkey).is_none());

// Perform the coldkey swap
assert_ok!(SubtensorModule::do_swap_coldkey(&old_coldkey, &new_coldkey));
assert_ok!(SubtensorModule::do_swap_coldkey(
&old_coldkey,
&new_coldkey,
burn_cost
));

// Ensure no identities have been changed
assert!(Identities::<Test>::get(old_coldkey).is_none());
Expand Down Expand Up @@ -1653,7 +1679,11 @@ fn test_coldkey_swap_stake_delta() {
SubtensorModule::add_balance_to_coldkey_account(&old_coldkey, 100e9 as u64);

// Perform the coldkey swap
assert_ok!(SubtensorModule::do_swap_coldkey(&old_coldkey, &new_coldkey));
assert_ok!(SubtensorModule::do_swap_coldkey(
&old_coldkey,
&new_coldkey,
burn_cost
));

// Ensure the stake delta is correctly transferred
assert_eq!(
Expand All @@ -1666,3 +1696,22 @@ fn test_coldkey_swap_stake_delta() {
);
});
}

// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test swap_coldkey -- test_cant_schedule_swap_without_enough_to_burn --exact --nocapture
#[test]
fn test_cant_schedule_swap_without_enough_to_burn() {
new_test_ext(1).execute_with(|| {
let old_coldkey = U256::from(3);
let new_coldkey = U256::from(4);
let hotkey = U256::from(5);

let burn_cost = SubtensorModule::get_key_swap_cost();
assert_noop!(
SubtensorModule::schedule_swap_coldkey(
<<Test as Config>::RuntimeOrigin>::signed(old_coldkey),
new_coldkey
),
Error::<Test>::NotEnoughBalanceToPaySwapColdKey
);
});
}
Loading