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

Refactor/hotkey swap #556

Merged
merged 24 commits into from
Jul 3, 2024
Merged
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
8 changes: 6 additions & 2 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ clippy-fix:
-A clippy::todo \
-A clippy::unimplemented \
-A clippy::indexing_slicing
@echo "Running cargo clippy with automatic fixes on potentially dirty code..."
cargo +{{RUSTV}} clippy --fix --allow-dirty --workspace --all-targets -- \
-A clippy::todo \
-A clippy::unimplemented \
-A clippy::indexing_slicing
fix:
@echo "Running cargo fix..."
cargo +{{RUSTV}} fix --workspace
Expand All @@ -46,5 +51,4 @@ lint:
@echo "Running cargo clippy with automatic fixes on potentially dirty code..."
just clippy-fix
@echo "Running cargo clippy..."
just clippy

just clippy
2 changes: 2 additions & 0 deletions pallets/admin-utils/tests/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +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 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 @@ -164,6 +165,7 @@ impl pallet_subtensor::Config for Test {
type InitialSubnetLimit = InitialSubnetLimit;
type InitialNetworkRateLimit = InitialNetworkRateLimit;
type InitialTargetStakesPerInterval = InitialTargetStakesPerInterval;
type HotkeySwapCost = InitialHotkeySwapCost;
type AlphaHigh = InitialAlphaHigh;
type AlphaLow = InitialAlphaLow;
type LiquidAlphaOn = InitialLiquidAlphaOn;
Expand Down
16 changes: 10 additions & 6 deletions pallets/subtensor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ mod registration;
mod root;
mod serving;
mod staking;
mod swap;
mod uids;
mod utils;
mod weights;
Expand Down Expand Up @@ -238,6 +239,9 @@ pub mod pallet {
/// Initial target stakes per interval issuance.
#[pallet::constant]
type InitialTargetStakesPerInterval: Get<u64>;
/// Cost of swapping a hotkey.
#[pallet::constant]
type HotkeySwapCost: Get<u64>;
/// The upper bound for the alpha parameter. Used for Liquid Alpha.
#[pallet::constant]
type AlphaHigh: Get<u16>;
Expand Down Expand Up @@ -740,7 +744,7 @@ pub mod pallet {
pub(super) type TxDelegateTakeRateLimit<T> =
StorageValue<_, u64, ValueQuery, DefaultTxDelegateTakeRateLimit<T>>;
#[pallet::storage] // --- MAP ( key ) --> last_block
pub(super) type LastTxBlock<T: Config> =
pub type LastTxBlock<T: Config> =
StorageMap<_, Identity, T::AccountId, u64, ValueQuery, DefaultLastTxBlock<T>>;
#[pallet::storage] // --- MAP ( key ) --> last_block
pub(super) type LastTxBlockDelegateTake<T: Config> =
Expand All @@ -756,10 +760,10 @@ pub mod pallet {
pub type ServingRateLimit<T> =
StorageMap<_, Identity, u16, u64, ValueQuery, DefaultServingRateLimit<T>>;
#[pallet::storage] // --- MAP ( netuid, hotkey ) --> axon_info
pub(super) type Axons<T: Config> =
pub type Axons<T: Config> =
StorageDoubleMap<_, Identity, u16, Blake2_128Concat, T::AccountId, AxonInfoOf, OptionQuery>;
#[pallet::storage] // --- MAP ( netuid, hotkey ) --> prometheus_info
pub(super) type Prometheus<T: Config> = StorageDoubleMap<
pub type Prometheus<T: Config> = StorageDoubleMap<
_,
Identity,
u16,
Expand Down Expand Up @@ -1013,13 +1017,13 @@ pub mod pallet {
}

#[pallet::storage] // --- DMAP ( netuid, hotkey ) --> uid
pub(super) type Uids<T: Config> =
pub type Uids<T: Config> =
StorageDoubleMap<_, Identity, u16, Blake2_128Concat, T::AccountId, u16, OptionQuery>;
#[pallet::storage] // --- DMAP ( netuid, uid ) --> hotkey
pub(super) type Keys<T: Config> =
pub type Keys<T: Config> =
StorageDoubleMap<_, Identity, u16, Identity, u16, T::AccountId, ValueQuery, DefaultKey<T>>;
#[pallet::storage] // --- DMAP ( netuid ) --> (hotkey, se, ve)
pub(super) type LoadedEmission<T: Config> =
pub type LoadedEmission<T: Config> =
StorageMap<_, Identity, u16, Vec<(T::AccountId, u64, u64)>, OptionQuery>;

#[pallet::storage] // --- DMAP ( netuid ) --> active
Expand Down
141 changes: 2 additions & 139 deletions pallets/subtensor/src/registration.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use super::*;
use frame_support::storage::IterableStorageDoubleMap;
use sp_core::{Get, H256, U256};
use sp_core::{H256, U256};
use sp_io::hashing::{keccak_256, sha2_256};
use sp_runtime::Saturating;
use system::pallet_prelude::BlockNumberFor;
Expand Down Expand Up @@ -395,7 +394,7 @@ impl<T: Config> Pallet<T> {
UsedWork::<T>::insert(work.clone(), current_block_number);

// --- 5. Add Balance via faucet.
let balance_to_add: u64 = 100_000_000_000;
let balance_to_add: u64 = 1_000_000_000_000;
Self::coinbase(100_000_000_000); // We are creating tokens here from the coinbase.

Self::add_balance_to_coldkey_account(&coldkey, balance_to_add);
Expand Down Expand Up @@ -591,140 +590,4 @@ impl<T: Config> Pallet<T> {
let vec_work: Vec<u8> = Self::hash_to_vec(work);
(nonce, vec_work)
}

pub fn do_swap_hotkey(
origin: T::RuntimeOrigin,
old_hotkey: &T::AccountId,
new_hotkey: &T::AccountId,
) -> DispatchResultWithPostInfo {
let coldkey = ensure_signed(origin)?;

let mut weight = T::DbWeight::get().reads_writes(2, 0);
ensure!(
Self::coldkey_owns_hotkey(&coldkey, old_hotkey),
Error::<T>::NonAssociatedColdKey
);

let block: u64 = Self::get_current_block_as_u64();
ensure!(
!Self::exceeds_tx_rate_limit(Self::get_last_tx_block(&coldkey), block),
Error::<T>::HotKeySetTxRateLimitExceeded
);

weight.saturating_accrue(T::DbWeight::get().reads(2));

ensure!(old_hotkey != new_hotkey, Error::<T>::NewHotKeyIsSameWithOld);
ensure!(
!Self::is_hotkey_registered_on_any_network(new_hotkey),
Error::<T>::HotKeyAlreadyRegisteredInSubNet
);

weight.saturating_accrue(
T::DbWeight::get().reads((TotalNetworks::<T>::get().saturating_add(1)) as u64),
);

let swap_cost = 1_000_000_000u64;
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);

Owner::<T>::remove(old_hotkey);
Owner::<T>::insert(new_hotkey, coldkey.clone());
weight.saturating_accrue(T::DbWeight::get().writes(2));

if let Ok(total_hotkey_stake) = TotalHotkeyStake::<T>::try_get(old_hotkey) {
TotalHotkeyStake::<T>::remove(old_hotkey);
TotalHotkeyStake::<T>::insert(new_hotkey, total_hotkey_stake);

weight.saturating_accrue(T::DbWeight::get().writes(2));
}

if let Ok(delegate_take) = Delegates::<T>::try_get(old_hotkey) {
Delegates::<T>::remove(old_hotkey);
Delegates::<T>::insert(new_hotkey, delegate_take);

weight.saturating_accrue(T::DbWeight::get().writes(2));
}

if let Ok(last_tx) = LastTxBlock::<T>::try_get(old_hotkey) {
LastTxBlock::<T>::remove(old_hotkey);
LastTxBlock::<T>::insert(new_hotkey, last_tx);

weight.saturating_accrue(T::DbWeight::get().writes(2));
}

let mut coldkey_stake: Vec<(T::AccountId, u64)> = vec![];
for (coldkey, stake_amount) in Stake::<T>::iter_prefix(old_hotkey) {
coldkey_stake.push((coldkey.clone(), stake_amount));
}

let _ = Stake::<T>::clear_prefix(old_hotkey, coldkey_stake.len() as u32, None);
weight.saturating_accrue(T::DbWeight::get().writes(coldkey_stake.len() as u64));

for (coldkey, stake_amount) in coldkey_stake {
Stake::<T>::insert(new_hotkey, coldkey, stake_amount);
weight.saturating_accrue(T::DbWeight::get().writes(1));
}

let mut netuid_is_member: Vec<u16> = vec![];
for netuid in <IsNetworkMember<T> as IterableStorageDoubleMap<T::AccountId, u16, bool>>::iter_key_prefix(old_hotkey) {
netuid_is_member.push(netuid);
}

let _ = IsNetworkMember::<T>::clear_prefix(old_hotkey, netuid_is_member.len() as u32, None);
weight.saturating_accrue(T::DbWeight::get().writes(netuid_is_member.len() as u64));

for netuid in netuid_is_member.iter() {
IsNetworkMember::<T>::insert(new_hotkey, netuid, true);
weight.saturating_accrue(T::DbWeight::get().writes(1));
}

for netuid in netuid_is_member.iter() {
if let Ok(axon_info) = Axons::<T>::try_get(netuid, old_hotkey) {
Axons::<T>::remove(netuid, old_hotkey);
Axons::<T>::insert(netuid, new_hotkey, axon_info);

weight.saturating_accrue(T::DbWeight::get().writes(2));
}
}

for netuid in netuid_is_member.iter() {
if let Ok(uid) = Uids::<T>::try_get(netuid, old_hotkey) {
Uids::<T>::remove(netuid, old_hotkey);
Uids::<T>::insert(netuid, new_hotkey, uid);

weight.saturating_accrue(T::DbWeight::get().writes(2));

Keys::<T>::insert(netuid, uid, new_hotkey);

weight.saturating_accrue(T::DbWeight::get().writes(1));

LoadedEmission::<T>::mutate(netuid, |emission_exists| match emission_exists {
Some(emissions) => {
if let Some(emission) = emissions.get_mut(uid as usize) {
let (_, se, ve) = emission;
*emission = (new_hotkey.clone(), *se, *ve);
}
}
None => {}
});

weight.saturating_accrue(T::DbWeight::get().writes(1));
}
}

Self::set_last_tx_block(&coldkey, block);
weight.saturating_accrue(T::DbWeight::get().writes(1));

Self::deposit_event(Event::HotkeySwapped {
coldkey,
old_hotkey: old_hotkey.clone(),
new_hotkey: new_hotkey.clone(),
});

Ok(Some(weight).into())
}
}
Loading
Loading