Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
993f033
clean up swap coldkey
l0r1s Nov 27, 2025
14fe3f6
deprecate old calls
l0r1s Nov 30, 2025
7c485f0
add new storage for announcements
l0r1s Nov 30, 2025
54eded0
remove perform_swap_coldkey
l0r1s Nov 30, 2025
d16bba5
added new extrinsics
l0r1s Nov 30, 2025
dfdf22d
update errors
l0r1s Nov 30, 2025
ed2bab6
updated events
l0r1s Nov 30, 2025
7b4bdab
fix claim root test
l0r1s Nov 30, 2025
d92a19b
added new tests for swap coldkey announce/remove
l0r1s Nov 30, 2025
a6f7fc6
No need to remove because we take
l0r1s Nov 30, 2025
40f4d9a
renamed to swap_coldkey_announced
l0r1s Nov 30, 2025
c5b0330
update SubtensorTransactionExtension
l0r1s Dec 2, 2025
e96625a
fix announcement
l0r1s Dec 2, 2025
949e936
fix most tests
l0r1s Dec 2, 2025
e8cee05
error cases tests + clean up
l0r1s Dec 3, 2025
dcc85bc
preserve new identity + tests
l0r1s Dec 4, 2025
2f1ad59
comprehensive test
l0r1s Dec 4, 2025
74a0dad
fix extension + tests
l0r1s Dec 5, 2025
e6d6925
rename tests
l0r1s Dec 5, 2025
760f4d3
use hash instead of coldkey during announcement
l0r1s Dec 5, 2025
07f5e72
remove unused RescheduleDuration
l0r1s Dec 5, 2025
a962bcd
fix TransactionError naming
l0r1s Dec 5, 2025
688ed68
announcements are hash of coldkey instead of raw coldkey
l0r1s Dec 5, 2025
dfd326d
rename config parameters/admin dispatches
l0r1s Dec 5, 2025
370db1a
added migration + fix old migration
l0r1s Dec 8, 2025
492b417
cargo fmt
l0r1s Dec 8, 2025
1c6fb23
clippy fix
l0r1s Dec 8, 2025
184c8d4
Merge branch 'devnet-ready' into rework-coldkey-swap
l0r1s Dec 8, 2025
8391945
reinstate swap_coldkey call + add call to remove announcement as root
l0r1s Dec 8, 2025
2e6e1cb
rework test + add tests for swap_coldkey as root
l0r1s Dec 8, 2025
44837ec
fix clippy
l0r1s Dec 8, 2025
88d8984
Merge branch 'devnet-ready' into rework-coldkey-swap
l0r1s Dec 9, 2025
39ef15e
remove useless block number from event
l0r1s Dec 9, 2025
4b64484
fix benchmarks
l0r1s Dec 9, 2025
e354520
fix benchmarks
l0r1s Dec 9, 2025
bee751d
cargo fmt
l0r1s Dec 9, 2025
7136bfd
fix benchmark
l0r1s Dec 9, 2025
ea8aa07
Merge branch 'devnet-ready' into rework-coldkey-swap
l0r1s Dec 9, 2025
f920c77
fix clippy
l0r1s Dec 10, 2025
4e74495
fix benchmarks
l0r1s Dec 10, 2025
f0b851a
bump spec version
l0r1s Dec 10, 2025
c1d1ba0
Merge branch 'devnet-ready' into rework-coldkey-swap
l0r1s Dec 11, 2025
baae06b
fix weights
l0r1s Dec 11, 2025
5a6c0b9
pays swap cost on first announcement
l0r1s Dec 11, 2025
0595130
store when can be performed instead of when was announced
l0r1s Dec 11, 2025
12eb085
reannouncement delay
l0r1s Dec 11, 2025
61acd0f
fix test
l0r1s Dec 11, 2025
d387861
Merge branch 'devnet-ready' into rework-coldkey-swap
l0r1s Dec 12, 2025
fc42240
fix rust
l0r1s Dec 12, 2025
c415d8b
cargo clippy
l0r1s Dec 12, 2025
a54ac00
fix benchmark
l0r1s Dec 12, 2025
083c723
Merge branch 'devnet-ready' into rework-coldkey-swap
l0r1s Dec 13, 2025
9236594
fix call indices
l0r1s Dec 13, 2025
1079b3c
fix missing return
l0r1s Dec 14, 2025
72fd24e
Merge branch 'testnet' into rework-coldkey-swap
l0r1s Dec 15, 2025
bd774ad
Merge branch 'devnet-ready' into rework-coldkey-swap
l0r1s Dec 16, 2025
ac1b1c8
add prod_or_fast
l0r1s Dec 16, 2025
9dba44e
fix typo
basfroman Dec 18, 2025
82ca17b
Merge branch 'devnet-ready' into rework-coldkey-swap
basfroman Dec 18, 2025
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
9 changes: 4 additions & 5 deletions chain-extensions/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -325,9 +325,8 @@ parameter_types! {
pub const InitialAlphaLow: u16 = 45875; // Represents 0.7 as per the production default
pub const InitialLiquidAlphaOn: bool = false; // Default value for LiquidAlphaOn
pub const InitialYuma3On: bool = false; // Default value for Yuma3On
// pub const InitialNetworkMaxStake: u64 = u64::MAX; // (DEPRECATED)
pub const InitialColdkeySwapScheduleDuration: u64 = 5 * 24 * 60 * 60 / 12; // Default as 5 days
pub const InitialColdkeySwapRescheduleDuration: u64 = 24 * 60 * 60 / 12; // Default as 1 day
pub const InitialColdkeySwapAnnouncementDelay: u64 = 5 * 24 * 60 * 60 / 12; // Default as 5 days
pub const InitialColdkeySwapReannouncementDelay: u64 = 24 * 60 * 60 / 12; // Default as 1 day
pub const InitialDissolveNetworkScheduleDuration: u64 = 5 * 24 * 60 * 60 / 12; // Default as 5 days
pub const InitialTaoWeight: u64 = 0; // 100% global weight.
pub const InitialEmaPriceHalvingPeriod: u64 = 201_600_u64; // 4 weeks
Expand Down Expand Up @@ -397,8 +396,8 @@ impl pallet_subtensor::Config for Test {
type LiquidAlphaOn = InitialLiquidAlphaOn;
type Yuma3On = InitialYuma3On;
type Preimages = Preimage;
type InitialColdkeySwapScheduleDuration = InitialColdkeySwapScheduleDuration;
type InitialColdkeySwapRescheduleDuration = InitialColdkeySwapRescheduleDuration;
type InitialColdkeySwapAnnouncementDelay = InitialColdkeySwapAnnouncementDelay;
type InitialColdkeySwapReannouncementDelay = InitialColdkeySwapReannouncementDelay;
type InitialDissolveNetworkScheduleDuration = InitialDissolveNetworkScheduleDuration;
type InitialTaoWeight = InitialTaoWeight;
type InitialEmaPriceHalvingPeriod = InitialEmaPriceHalvingPeriod;
Expand Down
2 changes: 1 addition & 1 deletion pallets/admin-utils/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -480,7 +480,7 @@ mod benchmarks {
}

#[benchmark]
fn sudo_set_coldkey_swap_schedule_duration() {
fn sudo_set_coldkey_swap_announcement_delay() {
#[extrinsic_call]
_(RawOrigin::Root, 100u32.into());
}
Expand Down
78 changes: 39 additions & 39 deletions pallets/admin-utils/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1354,44 +1354,6 @@ pub mod pallet {
res
}

/// Sets the duration of the coldkey swap schedule.
///
/// This extrinsic allows the root account to set the duration for the coldkey swap schedule.
/// The coldkey swap schedule determines how long it takes for a coldkey swap operation to complete.
///
/// # Arguments
/// * `origin` - The origin of the call, which must be the root account.
/// * `duration` - The new duration for the coldkey swap schedule, in number of blocks.
///
/// # Errors
/// * `BadOrigin` - If the caller is not the root account.
///
/// # Weight
/// Weight is handled by the `#[pallet::weight]` attribute.
#[pallet::call_index(54)]
#[pallet::weight((
Weight::from_parts(5_000_000, 0)
.saturating_add(T::DbWeight::get().reads(0_u64))
.saturating_add(T::DbWeight::get().writes(1_u64)),
DispatchClass::Operational,
Pays::Yes
))]
pub fn sudo_set_coldkey_swap_schedule_duration(
origin: OriginFor<T>,
duration: BlockNumberFor<T>,
) -> DispatchResult {
// Ensure the call is made by the root account
ensure_root(origin)?;

// Set the new duration of schedule coldkey swap
pallet_subtensor::Pallet::<T>::set_coldkey_swap_schedule_duration(duration);

// Log the change
log::trace!("ColdkeySwapScheduleDurationSet( duration: {duration:?} )");

Ok(())
}

/// Sets the duration of the dissolve network schedule.
///
/// This extrinsic allows the root account to set the duration for the dissolve network schedule.
Expand Down Expand Up @@ -1618,7 +1580,7 @@ pub mod pallet {
/// Weight is handled by the `#[pallet::weight]` attribute.
#[pallet::call_index(62)]
#[pallet::weight((
Weight::from_parts(5_744_000, 3507)
Weight::from_parts(5_698_000, 0)
.saturating_add(T::DbWeight::get().reads(1_u64))
.saturating_add(T::DbWeight::get().writes(0_u64)),
DispatchClass::Operational,
Expand Down Expand Up @@ -2240,6 +2202,44 @@ pub mod pallet {
pallet_subtensor::Pallet::<T>::set_min_non_immune_uids(netuid, min);
Ok(())
}

/// Sets the announcement delay for coldkey swap.
#[pallet::call_index(85)]
#[pallet::weight((
Weight::from_parts(5_000_000, 0)
.saturating_add(T::DbWeight::get().reads(0_u64))
.saturating_add(T::DbWeight::get().writes(1_u64)),
DispatchClass::Operational,
Pays::Yes
))]
pub fn sudo_set_coldkey_swap_announcement_delay(
origin: OriginFor<T>,
duration: BlockNumberFor<T>,
) -> DispatchResult {
ensure_root(origin)?;
pallet_subtensor::Pallet::<T>::set_coldkey_swap_announcement_delay(duration);
log::trace!("ColdkeySwapAnnouncementDelaySet( duration: {duration:?} )");
Ok(())
}

/// Sets the reannouncement delay for coldkey swap.
#[pallet::call_index(86)]
#[pallet::weight((
Weight::from_parts(5_000_000, 0)
.saturating_add(T::DbWeight::get().reads(0_u64))
.saturating_add(T::DbWeight::get().writes(1_u64)),
DispatchClass::Operational,
Pays::Yes
))]
pub fn sudo_set_coldkey_swap_reannouncement_delay(
origin: OriginFor<T>,
duration: BlockNumberFor<T>,
) -> DispatchResult {
ensure_root(origin)?;
pallet_subtensor::Pallet::<T>::set_coldkey_swap_reannouncement_delay(duration);
log::trace!("ColdkeySwapReannouncementDelaySet( duration: {duration:?} )");
Ok(())
}
}
}

Expand Down
11 changes: 4 additions & 7 deletions pallets/admin-utils/src/tests/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,17 +131,14 @@ parameter_types! {
pub const InitialNetworkMinLockCost: u64 = 100_000_000_000;
pub const InitialSubnetOwnerCut: u16 = 0; // 0%. 100% of rewards go to validators + miners.
pub const InitialNetworkLockReductionInterval: u64 = 2; // 2 blocks.
// pub const InitialSubnetLimit: u16 = 10; // (DEPRECATED)
pub const InitialNetworkRateLimit: u64 = 0;
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
pub const InitialYuma3On: bool = false; // Default value for Yuma3On
// pub const InitialHotkeyEmissionTempo: u64 = 1; // (DEPRECATED)
// pub const InitialNetworkMaxStake: u64 = u64::MAX; // (DEPRECATED)
pub const InitialColdkeySwapScheduleDuration: u64 = 5 * 24 * 60 * 60 / 12; // 5 days
pub const InitialColdkeySwapRescheduleDuration: u64 = 24 * 60 * 60 / 12; // 1 day
pub const InitialColdkeySwapAnnouncementDelay: u64 = 5 * 24 * 60 * 60 / 12; // 5 days
pub const InitialColdkeySwapReannouncementDelay: u64 = 24 * 60 * 60 / 12; // 1 day
pub const InitialDissolveNetworkScheduleDuration: u64 = 5 * 24 * 60 * 60 / 12; // 5 days
pub const InitialTaoWeight: u64 = u64::MAX/10; // 10% global weight.
pub const InitialEmaPriceHalvingPeriod: u64 = 201_600_u64; // 4 weeks
Expand Down Expand Up @@ -210,8 +207,8 @@ impl pallet_subtensor::Config for Test {
type LiquidAlphaOn = InitialLiquidAlphaOn;
type Yuma3On = InitialYuma3On;
type Preimages = ();
type InitialColdkeySwapScheduleDuration = InitialColdkeySwapScheduleDuration;
type InitialColdkeySwapRescheduleDuration = InitialColdkeySwapRescheduleDuration;
type InitialColdkeySwapAnnouncementDelay = InitialColdkeySwapAnnouncementDelay;
type InitialColdkeySwapReannouncementDelay = InitialColdkeySwapReannouncementDelay;
type InitialDissolveNetworkScheduleDuration = InitialDissolveNetworkScheduleDuration;
type InitialTaoWeight = InitialTaoWeight;
type InitialEmaPriceHalvingPeriod = InitialEmaPriceHalvingPeriod;
Expand Down
59 changes: 47 additions & 12 deletions pallets/admin-utils/src/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1382,39 +1382,74 @@ fn test_sudo_get_set_alpha() {
}

#[test]
fn test_sudo_set_coldkey_swap_schedule_duration() {
fn test_sudo_set_coldkey_swap_announcement_delay() {
new_test_ext().execute_with(|| {
// Arrange
let root = RuntimeOrigin::root();
let non_root = RuntimeOrigin::signed(U256::from(1));
let new_duration = 100u32.into();
let new_delay = 100u32.into();

// Act & Assert: Non-root account should fail
assert_noop!(
AdminUtils::sudo_set_coldkey_swap_schedule_duration(non_root, new_duration),
AdminUtils::sudo_set_coldkey_swap_announcement_delay(non_root, new_delay),
DispatchError::BadOrigin
);

// Act: Root account should succeed
assert_ok!(AdminUtils::sudo_set_coldkey_swap_schedule_duration(
assert_ok!(AdminUtils::sudo_set_coldkey_swap_announcement_delay(
root.clone(),
new_duration
new_delay
));

// Assert: Check if the duration was actually set
// Assert: Check if the delay was actually set
assert_eq!(
pallet_subtensor::ColdkeySwapScheduleDuration::<Test>::get(),
new_duration
pallet_subtensor::ColdkeySwapAnnouncementDelay::<Test>::get(),
new_delay
);

// Act & Assert: Setting the same value again should succeed (idempotent operation)
assert_ok!(AdminUtils::sudo_set_coldkey_swap_schedule_duration(
root,
new_duration
assert_ok!(AdminUtils::sudo_set_coldkey_swap_announcement_delay(
root, new_delay
));

// You might want to check for events here if your pallet emits them
System::assert_last_event(Event::ColdkeySwapAnnouncementDelaySet(new_delay).into());
});
}

#[test]
fn test_sudo_set_coldkey_swap_reannouncement_delay() {
new_test_ext().execute_with(|| {
// Arrange
let root = RuntimeOrigin::root();
let non_root = RuntimeOrigin::signed(U256::from(1));
let new_delay = 100u32.into();

// Act & Assert: Non-root account should fail
assert_noop!(
AdminUtils::sudo_set_coldkey_swap_reannouncement_delay(non_root, new_delay),
DispatchError::BadOrigin
);

// Act: Root account should succeed
assert_ok!(AdminUtils::sudo_set_coldkey_swap_reannouncement_delay(
root.clone(),
new_delay
));

// Assert: Check if the delay was actually set
assert_eq!(
pallet_subtensor::ColdkeySwapReannouncementDelay::<Test>::get(),
new_delay
);

// Act & Assert: Setting the same value again should succeed (idempotent operation)
assert_ok!(AdminUtils::sudo_set_coldkey_swap_reannouncement_delay(
root, new_delay
));

// You might want to check for events here if your pallet emits them
System::assert_last_event(Event::ColdkeySwapScheduleDurationSet(new_duration).into());
System::assert_last_event(Event::ColdkeySwapReannouncementDelaySet(new_delay).into());
});
}

Expand Down
88 changes: 62 additions & 26 deletions pallets/subtensor/src/benchmarks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -369,17 +369,6 @@ mod pallet_benchmarks {
);
}

#[benchmark]
fn schedule_swap_coldkey() {
let old_coldkey: T::AccountId = account("old_cold", 0, 1);
let new_coldkey: T::AccountId = account("new_cold", 1, 2);
let amount: u64 = 100_000_000_000_000;
Subtensor::<T>::add_balance_to_coldkey_account(&old_coldkey, amount);

#[extrinsic_call]
_(RawOrigin::Signed(old_coldkey.clone()), new_coldkey.clone());
}

#[benchmark]
fn sudo_set_tx_childkey_take_rate_limit() {
let new_rate_limit: u64 = 100;
Expand Down Expand Up @@ -419,14 +408,62 @@ mod pallet_benchmarks {
}

#[benchmark]
fn swap_coldkey() {
fn announce_coldkey_swap() {
let coldkey: T::AccountId = account("old_coldkey", 0, 0);
let new_coldkey: T::AccountId = account("new_coldkey", 0, 0);
let new_coldkey_hash: T::Hash = <T as frame_system::Config>::Hashing::hash_of(&new_coldkey);

let swap_cost = Subtensor::<T>::get_key_swap_cost();
Subtensor::<T>::add_balance_to_coldkey_account(&coldkey, swap_cost.into());

#[extrinsic_call]
_(RawOrigin::Signed(coldkey), new_coldkey_hash);
}

#[benchmark]
fn swap_coldkey_announced() {
let old_coldkey: T::AccountId = account("old_coldkey", 0, 0);
let new_coldkey: T::AccountId = account("new_coldkey", 0, 0);
let new_coldkey_hash: T::Hash = <T as frame_system::Config>::Hashing::hash_of(&new_coldkey);
let hotkey1: T::AccountId = account("hotkey1", 0, 0);

let now = frame_system::Pallet::<T>::block_number();
let delay = ColdkeySwapAnnouncementDelay::<T>::get();
ColdkeySwapAnnouncements::<T>::insert(&old_coldkey, (now, new_coldkey_hash));
frame_system::Pallet::<T>::set_block_number(now + delay + 1u32.into());

let netuid = NetUid::from(1);
Subtensor::<T>::init_new_network(netuid, 1);
Subtensor::<T>::set_network_registration_allowed(netuid, true);
Subtensor::<T>::set_network_pow_registration_allowed(netuid, true);

let block_number = Subtensor::<T>::get_current_block_as_u64();
let (nonce, work) =
Subtensor::<T>::create_work_for_block_number(netuid, block_number, 3, &hotkey1);
let _ = Subtensor::<T>::register(
RawOrigin::Signed(old_coldkey.clone()).into(),
netuid,
block_number,
nonce,
work.clone(),
hotkey1.clone(),
old_coldkey.clone(),
);

#[extrinsic_call]
_(RawOrigin::Signed(old_coldkey), new_coldkey);
}

#[benchmark]
fn swap_coldkey() {
let old_coldkey: T::AccountId = account("old_coldkey", 0, 0);
let new_coldkey: T::AccountId = account("new_coldkey", 0, 0);
let hotkey1: T::AccountId = account("hotkey1", 0, 0);

let swap_cost = Subtensor::<T>::get_key_swap_cost();
let free_balance_old = swap_cost + 12345.into();
Subtensor::<T>::add_balance_to_coldkey_account(&old_coldkey, swap_cost.into());

let netuid = NetUid::from(1);
Subtensor::<T>::init_new_network(netuid, 1);
Subtensor::<T>::set_network_registration_allowed(netuid, true);
Subtensor::<T>::set_network_pow_registration_allowed(netuid, true);
Expand All @@ -444,19 +481,6 @@ mod pallet_benchmarks {
old_coldkey.clone(),
);

Subtensor::<T>::add_balance_to_coldkey_account(&old_coldkey, free_balance_old.into());
let name: Vec<u8> = b"The fourth Coolest Identity".to_vec();
let identity = ChainIdentityV2 {
name,
url: vec![],
github_repo: vec![],
image: vec![],
discord: vec![],
description: vec![],
additional: vec![],
};
IdentitiesV2::<T>::insert(&old_coldkey, identity);

#[extrinsic_call]
_(
RawOrigin::Root,
Expand All @@ -466,6 +490,18 @@ mod pallet_benchmarks {
);
}

#[benchmark]
fn remove_coldkey_swap_announcement() {
let coldkey: T::AccountId = account("old_coldkey", 0, 0);
let coldkey_hash: T::Hash = <T as frame_system::Config>::Hashing::hash_of(&coldkey);
let now = frame_system::Pallet::<T>::block_number();

ColdkeySwapAnnouncements::<T>::insert(&coldkey, (now, coldkey_hash));

#[extrinsic_call]
_(RawOrigin::Root, coldkey);
}

#[benchmark]
fn batch_reveal_weights() {
let tempo: u16 = 0;
Expand Down
Loading
Loading