Skip to content

Commit

Permalink
Merge pull request #631 from opentensor/feat/remove_schedule_coldkey_…
Browse files Browse the repository at this point in the history
…swap

Resuming the network
  • Loading branch information
distributedstatemachine authored Jul 12, 2024
2 parents bcb696b + f49bb55 commit 884a179
Show file tree
Hide file tree
Showing 8 changed files with 135 additions and 74 deletions.
4 changes: 2 additions & 2 deletions pallets/admin-utils/tests/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ parameter_types! {
pub const InitialSubnetLimit: u16 = 10; // Max 10 subnets.
pub const InitialNetworkRateLimit: u64 = 0;
pub const InitialTargetStakesPerInterval: u16 = 1;
pub const InitialHotkeySwapCost: u64 = 1_000_000_000;
pub const InitialKeySwapCost: u64 = 1_000_000_000;
pub const InitialAlphaHigh: u16 = 58982; // Represents 0.9 as per the production default
pub const InitialAlphaLow: u16 = 45875; // Represents 0.7 as per the production default
pub const InitialLiquidAlphaOn: bool = false; // Default value for LiquidAlphaOn
Expand Down Expand Up @@ -166,7 +166,7 @@ impl pallet_subtensor::Config for Test {
type InitialSubnetLimit = InitialSubnetLimit;
type InitialNetworkRateLimit = InitialNetworkRateLimit;
type InitialTargetStakesPerInterval = InitialTargetStakesPerInterval;
type HotkeySwapCost = InitialHotkeySwapCost;
type KeySwapCost = InitialKeySwapCost;
type AlphaHigh = InitialAlphaHigh;
type AlphaLow = InitialAlphaLow;
type LiquidAlphaOn = InitialLiquidAlphaOn;
Expand Down
26 changes: 0 additions & 26 deletions pallets/subtensor/src/benchmarks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -429,30 +429,4 @@ reveal_weights {

}: reveal_weights(RawOrigin::Signed(hotkey.clone()), netuid, uids, weight_values, salt, version_key)

schedule_coldkey_swap {
let seed: u32 = 1;
let old_coldkey: T::AccountId = account("OldColdkey", 0, seed);
let new_coldkey: T::AccountId = account("NewColdkey", 0, seed + 1);
let hotkey: T::AccountId = account("Hotkey", 0, seed);

let netuid = 1u16;
let tempo = 1u16;
let block_number: u64 = Subtensor::<T>::get_current_block_as_u64();
let nonce = 0;

// Initialize the network
Subtensor::<T>::init_new_network(netuid, tempo);
Subtensor::<T>::set_network_registration_allowed(netuid, true);

// Add balance to the old coldkey account
let amount_to_be_staked: u64 = 1000000u32.into();
Subtensor::<T>::add_balance_to_coldkey_account(&old_coldkey.clone(), amount_to_be_staked+1000000000);
// Burned register the hotkey with the old coldkey
assert_ok!(Subtensor::<T>::burned_register(
RawOrigin::Signed(old_coldkey.clone()).into(),
netuid,
hotkey.clone()
));

}: schedule_coldkey_swap(RawOrigin::Signed(old_coldkey.clone()), new_coldkey.clone(), vec![], block_number, nonce)
}
4 changes: 2 additions & 2 deletions pallets/subtensor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ pub mod pallet {
type InitialTargetStakesPerInterval: Get<u64>;
/// Cost of swapping a hotkey.
#[pallet::constant]
type HotkeySwapCost: Get<u64>;
type KeySwapCost: Get<u64>;
/// The upper bound for the alpha parameter. Used for Liquid Alpha.
#[pallet::constant]
type AlphaHigh: Get<u16>;
Expand Down Expand Up @@ -2098,7 +2098,6 @@ pub mod pallet {
) -> DispatchResultWithPostInfo {
Self::do_swap_coldkey(origin, &new_coldkey)
}

/// Unstakes all tokens associated with a hotkey and transfers them to a new coldkey.
///
/// # Arguments
Expand All @@ -2114,6 +2113,7 @@ pub mod pallet {
/// # Weight
///
/// Weight is calculated based on the number of database reads and writes.
#[cfg(test)]
#[pallet::call_index(72)]
#[pallet::weight((Weight::from_parts(21_000_000, 0)
.saturating_add(T::DbWeight::get().reads(3))
Expand Down
57 changes: 48 additions & 9 deletions pallets/subtensor/src/swap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ impl<T: Config> Pallet<T> {
new_hotkey: &T::AccountId,
) -> DispatchResultWithPostInfo {
let coldkey = ensure_signed(origin)?;

ensure!(
!Self::coldkey_in_arbitration(&coldkey),
Error::<T>::ColdkeyIsInArbitration
Expand Down Expand Up @@ -60,6 +61,16 @@ impl<T: Config> Pallet<T> {
T::DbWeight::get().reads((TotalNetworks::<T>::get().saturating_add(1u16)) as u64),
);

let swap_cost = Self::get_key_swap_cost();
log::debug!("Swap cost: {:?}", swap_cost);

ensure!(
Self::can_remove_balance_from_coldkey_account(&coldkey, swap_cost),
Error::<T>::NotEnoughBalanceToPaySwapHotKey
);
let actual_burn_amount = Self::remove_balance_from_coldkey_account(&coldkey, swap_cost)?;
Self::burn_tokens(actual_burn_amount);

Self::swap_owner(old_hotkey, new_hotkey, &coldkey, &mut weight);
Self::swap_total_hotkey_stake(old_hotkey, new_hotkey, &mut weight);
Self::swap_delegates(old_hotkey, new_hotkey, &mut weight);
Expand All @@ -74,6 +85,7 @@ impl<T: Config> Pallet<T> {
Self::swap_loaded_emission(old_hotkey, new_hotkey, &netuid_is_member, &mut weight);
Self::swap_uids(old_hotkey, new_hotkey, &netuid_is_member, &mut weight);
Self::swap_prometheus(old_hotkey, new_hotkey, &netuid_is_member, &mut weight);
Self::swap_senate_member(old_hotkey, new_hotkey, &mut weight)?;

Self::swap_total_hotkey_coldkey_stakes_this_interval(old_hotkey, new_hotkey, &mut weight);

Expand Down Expand Up @@ -140,6 +152,20 @@ impl<T: Config> Pallet<T> {
Error::<T>::ColdKeyAlreadyAssociated
);

// Calculate and charge the swap fee
let swap_cost = Self::get_key_swap_cost();
log::debug!("Coldkey swap cost: {:?}", swap_cost);

ensure!(
Self::can_remove_balance_from_coldkey_account(&old_coldkey, swap_cost),
Error::<T>::NotEnoughBalanceToPaySwapColdKey
);
let actual_burn_amount =
Self::remove_balance_from_coldkey_account(&old_coldkey, swap_cost)?;
Self::burn_tokens(actual_burn_amount);

weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 1));

// Actually do the swap.
weight = weight.saturating_add(
Self::perform_swap_coldkey(&old_coldkey, new_coldkey)
Expand Down Expand Up @@ -189,15 +215,15 @@ impl<T: Config> Pallet<T> {
///
/// This function calculates the remaining arbitration period by subtracting the current block number
/// from the arbitration block number of the coldkey.
// pub fn get_remaining_arbitration_period(coldkey: &T::AccountId) -> u64 {
// let current_block: u64 = Self::get_current_block_as_u64();
// let arbitration_block: u64 = ColdkeyArbitrationBlock::<T>::get(coldkey);
// if arbitration_block > current_block {
// arbitration_block.saturating_sub(current_block)
// } else {
// 0
// }
// }
pub fn get_remaining_arbitration_period(coldkey: &T::AccountId) -> u64 {
let current_block: u64 = Self::get_current_block_as_u64();
let arbitration_block: u64 = ColdkeyArbitrationBlock::<T>::get(coldkey);
if arbitration_block > current_block {
arbitration_block.saturating_sub(current_block)
} else {
0
}
}

pub fn meets_min_allowed_coldkey_balance(coldkey: &T::AccountId) -> bool {
let all_staked_keys: Vec<T::AccountId> = StakingHotkeys::<T>::get(coldkey);
Expand Down Expand Up @@ -948,4 +974,17 @@ impl<T: Config> Pallet<T> {
}
weight.saturating_accrue(T::DbWeight::get().reads(TotalNetworks::<T>::get() as u64));
}

pub fn swap_senate_member(
old_hotkey: &T::AccountId,
new_hotkey: &T::AccountId,
weight: &mut Weight,
) -> DispatchResult {
weight.saturating_accrue(T::DbWeight::get().reads(1));
if T::SenateMembers::is_member(old_hotkey) {
T::SenateMembers::swap_member(old_hotkey, new_hotkey).map_err(|e| e.error)?;
weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 2));
}
Ok(())
}
}
4 changes: 2 additions & 2 deletions pallets/subtensor/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -671,8 +671,8 @@ impl<T: Config> Pallet<T> {
NominatorMinRequiredStake::<T>::put(min_stake);
}

pub fn get_hotkey_swap_cost() -> u64 {
T::HotkeySwapCost::get()
pub fn get_key_swap_cost() -> u64 {
T::KeySwapCost::get()
}

pub fn get_alpha_values(netuid: u16) -> (u16, u16) {
Expand Down
4 changes: 2 additions & 2 deletions pallets/subtensor/tests/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ parameter_types! {
pub const InitialSubnetLimit: u16 = 10; // Max 10 subnets.
pub const InitialNetworkRateLimit: u64 = 0;
pub const InitialTargetStakesPerInterval: u16 = 2;
pub const InitialHotkeySwapCost: u64 = 1_000_000_000;
pub const InitialKeySwapCost: u64 = 1_000_000_000;
pub const InitialAlphaHigh: u16 = 58982; // Represents 0.9 as per the production default
pub const InitialAlphaLow: u16 = 45875; // Represents 0.7 as per the production default
pub const InitialLiquidAlphaOn: bool = false; // Default value for LiquidAlphaOn
Expand Down Expand Up @@ -375,7 +375,7 @@ impl pallet_subtensor::Config for Test {
type InitialSubnetLimit = InitialSubnetLimit;
type InitialNetworkRateLimit = InitialNetworkRateLimit;
type InitialTargetStakesPerInterval = InitialTargetStakesPerInterval;
type HotkeySwapCost = InitialHotkeySwapCost;
type KeySwapCost = InitialKeySwapCost;
type AlphaHigh = InitialAlphaHigh;
type AlphaLow = InitialAlphaLow;
type LiquidAlphaOn = InitialLiquidAlphaOn;
Expand Down
101 changes: 75 additions & 26 deletions pallets/subtensor/tests/swap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

use codec::Encode;
use frame_support::weights::Weight;
use frame_support::{assert_err, assert_ok};
use frame_system::Config;
use frame_support::{assert_err, assert_noop, assert_ok};
use frame_system::{Config, RawOrigin};
mod mock;
use mock::*;
use pallet_subtensor::*;
Expand Down Expand Up @@ -167,6 +167,22 @@ fn test_do_swap_hotkey_ok_robust() {
SubtensorModule::add_balance_to_coldkey_account(coldkey, swap_cost);
}

// Add old_hotkeys[0] and old_hotkeys[1] to Senate
assert_ok!(SenateMembers::add_member(
RawOrigin::Root.into(),
old_hotkeys[0]
));
assert_ok!(SenateMembers::add_member(
RawOrigin::Root.into(),
old_hotkeys[1]
));

// Verify initial Senate membership
assert!(Senate::is_member(&old_hotkeys[0]));
assert!(Senate::is_member(&old_hotkeys[1]));
assert!(!Senate::is_member(&new_hotkeys[0]));
assert!(!Senate::is_member(&new_hotkeys[1]));

// Perform the swaps for only two hotkeys
assert_ok!(SubtensorModule::do_swap_hotkey(
<<Test as Config>::RuntimeOrigin>::signed(coldkeys[0]),
Expand Down Expand Up @@ -268,6 +284,10 @@ fn test_do_swap_hotkey_ok_robust() {
assert_eq!(Keys::<Test>::get(netuid, uid), new_hotkeys[i]);
}
}

// Verify Senate membership swap
assert!(!Senate::is_member(&old_hotkeys[i]));
assert!(Senate::is_member(&new_hotkeys[i]));
} else {
// Ensure other hotkeys remain unchanged
assert_eq!(
Expand All @@ -278,6 +298,10 @@ fn test_do_swap_hotkey_ok_robust() {
SubtensorModule::get_owning_coldkey_for_hotkey(&new_hotkeys[i]),
coldkeys[i]
);

// Verify Senate membership remains unchanged for other hotkeys
assert!(!Senate::is_member(&old_hotkeys[i]));
assert!(!Senate::is_member(&new_hotkeys[i]));
}
}
}
Expand Down Expand Up @@ -1059,7 +1083,8 @@ fn test_do_swap_coldkey_success() {
let netuid = 1u16;
let stake_amount1 = 1000u64;
let stake_amount2 = 2000u64;
let free_balance_old = 12345u64 + MIN_BALANCE_TO_PERFORM_COLDKEY_SWAP;
let swap_cost = SubtensorModule::get_key_swap_cost();
let free_balance_old = 12345u64 + swap_cost;

// Setup initial state
add_network(netuid, 13, 0);
Expand Down Expand Up @@ -1158,7 +1183,7 @@ fn test_do_swap_coldkey_success() {
// Verify balance transfer
assert_eq!(
SubtensorModule::get_coldkey_balance(&new_coldkey),
free_balance_old
free_balance_old - swap_cost
);
assert_eq!(SubtensorModule::get_coldkey_balance(&old_coldkey), 0);

Expand Down Expand Up @@ -1332,6 +1357,7 @@ fn test_do_swap_coldkey_with_subnet_ownership() {
let hotkey = U256::from(3);
let netuid = 1u16;
let stake_amount: u64 = 1000u64;
let swap_cost = SubtensorModule::get_key_swap_cost();

// Setup initial state
add_network(netuid, 13, 0);
Expand All @@ -1340,7 +1366,7 @@ fn test_do_swap_coldkey_with_subnet_ownership() {
// Set TotalNetworks because swap relies on it
pallet_subtensor::TotalNetworks::<Test>::set(1);

SubtensorModule::add_balance_to_coldkey_account(&old_coldkey, stake_amount);
SubtensorModule::add_balance_to_coldkey_account(&old_coldkey, stake_amount + swap_cost);
SubnetOwner::<Test>::insert(netuid, old_coldkey);

// Populate OwnedHotkeys map
Expand Down Expand Up @@ -1666,24 +1692,47 @@ fn test_coldkey_swap_total() {
});
}

// #[test]
// fn test_coldkey_arbitrated_sw() {
// new_test_ext(1).execute_with(|| {
// let coldkey = U256::from(1);
// let hotkey = U256::from(2);
// let netuid = 1u16;

// // Setup initial state
// add_network(netuid, 13, 0);
// register_ok_neuron(netuid, hotkey, coldkey, 0);

// // Check if coldkey has associated hotkeys
// assert!(SubtensorModule::coldkey_has_associated_hotkeys(&coldkey));

// // Check for a coldkey without associated hotkeys
// let unassociated_coldkey = U256::from(3);
// assert!(!SubtensorModule::coldkey_has_associated_hotkeys(
// &unassociated_coldkey
// ));
// });
// }
#[test]
fn test_swap_senate_member() {
new_test_ext(1).execute_with(|| {
let old_hotkey = U256::from(1);
let new_hotkey = U256::from(2);
let non_member_hotkey = U256::from(3);
let mut weight = Weight::zero();

// Setup: Add old_hotkey as a Senate member
assert_ok!(SenateMembers::add_member(
RawOrigin::Root.into(),
old_hotkey
));

// Test 1: Successful swap
assert_ok!(SubtensorModule::swap_senate_member(
&old_hotkey,
&new_hotkey,
&mut weight
));
assert!(Senate::is_member(&new_hotkey));
assert!(!Senate::is_member(&old_hotkey));

// Verify weight update
let expected_weight = <Test as frame_system::Config>::DbWeight::get().reads_writes(2, 2);
assert_eq!(weight, expected_weight);

// Reset weight for next test
weight = Weight::zero();

// Test 2: Swap with non-member (should not change anything)
assert_ok!(SubtensorModule::swap_senate_member(
&non_member_hotkey,
&new_hotkey,
&mut weight
));
assert!(Senate::is_member(&new_hotkey));
assert!(!Senate::is_member(&non_member_hotkey));

// Verify weight update (should only have read operations)
let expected_weight = <Test as frame_system::Config>::DbWeight::get().reads(1);
assert_eq!(weight, expected_weight);
});
}
9 changes: 4 additions & 5 deletions runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,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: 194,
spec_version: 162,
impl_version: 1,
apis: RUNTIME_API_VERSIONS,
transaction_version: 1,
Expand Down Expand Up @@ -312,8 +312,7 @@ impl Contains<RuntimeCall> for SafeModeWhitelistedCalls {
| RuntimeCall::SafeMode(_)
| RuntimeCall::Timestamp(_)
| RuntimeCall::SubtensorModule(
pallet_subtensor::Call::schedule_coldkey_swap { .. }
| pallet_subtensor::Call::set_weights { .. }
pallet_subtensor::Call::set_weights { .. }
| pallet_subtensor::Call::set_root_weights { .. }
| pallet_subtensor::Call::serve_axon { .. }
)
Expand Down Expand Up @@ -877,7 +876,7 @@ parameter_types! {
pub const SubtensorInitialNetworkLockReductionInterval: u64 = 14 * 7200;
pub const SubtensorInitialNetworkRateLimit: u64 = 7200;
pub const SubtensorInitialTargetStakesPerInterval: u16 = 1;
pub const SubtensorInitialHotkeySwapCost: u64 = 1_000_000_000;
pub const SubtensorInitialKeySwapCost: u64 = 1_000_000_000;
pub const InitialAlphaHigh: u16 = 58982; // Represents 0.9 as per the production default
pub const InitialAlphaLow: u16 = 45875; // Represents 0.7 as per the production default
pub const InitialLiquidAlphaOn: bool = false; // Default value for LiquidAlphaOn
Expand Down Expand Up @@ -933,7 +932,7 @@ impl pallet_subtensor::Config for Runtime {
type InitialSubnetLimit = SubtensorInitialSubnetLimit;
type InitialNetworkRateLimit = SubtensorInitialNetworkRateLimit;
type InitialTargetStakesPerInterval = SubtensorInitialTargetStakesPerInterval;
type HotkeySwapCost = SubtensorInitialHotkeySwapCost;
type KeySwapCost = SubtensorInitialKeySwapCost;
type AlphaHigh = InitialAlphaHigh;
type AlphaLow = InitialAlphaLow;
type LiquidAlphaOn = InitialLiquidAlphaOn;
Expand Down

0 comments on commit 884a179

Please sign in to comment.