Skip to content

Commit 8206aa3

Browse files
authored
Add start call to subtensor module (#1436)
2 parents 5127d4d + 5fb588a commit 8206aa3

File tree

17 files changed

+460
-5
lines changed

17 files changed

+460
-5
lines changed

pallets/admin-utils/src/tests/mock.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ parameter_types! {
135135
pub const InitialDissolveNetworkScheduleDuration: u64 = 5 * 24 * 60 * 60 / 12; // 5 days
136136
pub const InitialTaoWeight: u64 = u64::MAX/10; // 10% global weight.
137137
pub const InitialEmaPriceHalvingPeriod: u64 = 201_600_u64; // 4 weeks
138+
pub const DurationOfStartCall: u64 = 7 * 24 * 60 * 60 / 12; // 7 days
138139
}
139140

140141
impl pallet_subtensor::Config for Test {
@@ -199,6 +200,7 @@ impl pallet_subtensor::Config for Test {
199200
type InitialDissolveNetworkScheduleDuration = InitialDissolveNetworkScheduleDuration;
200201
type InitialTaoWeight = InitialTaoWeight;
201202
type InitialEmaPriceHalvingPeriod = InitialEmaPriceHalvingPeriod;
203+
type DurationOfStartCall = DurationOfStartCall;
202204
}
203205

204206
#[derive_impl(frame_system::config_preludes::TestDefaultConfig)]

pallets/subtensor/src/benchmarks.rs

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use crate::Pallet as Subtensor;
66
use crate::*;
77
use frame_benchmarking::{account, benchmarks, whitelisted_caller};
88
use frame_support::assert_ok;
9-
use frame_system::RawOrigin;
9+
use frame_system::{RawOrigin, pallet_prelude::BlockNumberFor};
1010
pub use pallet::*;
1111
use sp_core::H256;
1212
use sp_runtime::traits::{BlakeTwo256, Hash};
@@ -658,4 +658,35 @@ benchmark_burn_alpha {
658658

659659
}: burn_alpha(RawOrigin::Signed(coldkey), hotkey, alpha_amount, netuid)
660660

661+
662+
benchmark_start_call {
663+
let caller: T::AccountId = whitelisted_caller::<AccountIdOf<T>>();
664+
let caller_origin = <T as frame_system::Config>::RuntimeOrigin::from(RawOrigin::Signed(caller.clone()));
665+
let netuid: u16 = 1;
666+
let tempo: u16 = 1;
667+
let seed: u32 = 1;
668+
669+
// Set up coldkey and hotkey
670+
let coldkey: T::AccountId = account("Test", 0, seed);
671+
let hotkey: T::AccountId = account("Alice", 0, seed);
672+
673+
// Initialize network
674+
Subtensor::<T>::init_new_network(netuid, tempo);
675+
Subtensor::<T>::set_network_registration_allowed(netuid, true);
676+
677+
// Register the neuron
678+
Subtensor::<T>::set_burn(netuid, 1);
679+
let amount_to_be_staked = 1000000u32.into();
680+
Subtensor::<T>::add_balance_to_coldkey_account(&coldkey.clone(), amount_to_be_staked);
681+
682+
assert_ok!(Subtensor::<T>::do_burned_registration(RawOrigin::Signed(coldkey.clone()).into(), netuid, hotkey.clone()));
683+
assert_eq!(SubnetOwner::<T>::get(netuid), coldkey.clone());
684+
assert_eq!(FirstEmissionBlockNumber::<T>::get(netuid), None);
685+
let current_block: u64 = Subtensor::<T>::get_current_block_as_u64();
686+
let duration = <T as Config>::DurationOfStartCall::get();
687+
let block: BlockNumberFor<T> = (current_block + duration).try_into().ok().expect("can't convert to block number");
688+
frame_system::Pallet::<T>::set_block_number(block);
689+
690+
}: start_call(RawOrigin::Signed(coldkey), netuid)
691+
661692
}

pallets/subtensor/src/coinbase/run_coinbase.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,11 @@ impl<T: Config> Pallet<T> {
3737
let current_block: u64 = Self::get_current_block_as_u64();
3838
log::debug!("Current block: {:?}", current_block);
3939

40-
// --- 1. Get all netuids (filter out root.)
40+
// --- 1. Get all netuids (filter out root and new subnet without first emission block)
4141
let subnets: Vec<u16> = Self::get_all_subnet_netuids()
4242
.into_iter()
4343
.filter(|netuid| *netuid != 0)
44+
.filter(|netuid| FirstEmissionBlockNumber::<T>::get(*netuid).is_some())
4445
.collect();
4546
log::debug!("All subnet netuids: {:?}", subnets);
4647

pallets/subtensor/src/lib.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1125,7 +1125,11 @@ pub mod pallet {
11251125
/// ============================
11261126
/// ==== Subnet Parameters =====
11271127
/// ============================
1128-
#[pallet::storage] // --- MAP ( netuid ) --> subnet mechanism
1128+
/// --- MAP ( netuid ) --> block number of first emission
1129+
#[pallet::storage]
1130+
pub type FirstEmissionBlockNumber<T: Config> = StorageMap<_, Identity, u16, u64, OptionQuery>;
1131+
/// --- MAP ( netuid ) --> subnet mechanism
1132+
#[pallet::storage]
11291133
pub type SubnetMechanism<T: Config> =
11301134
StorageMap<_, Identity, u16, u16, ValueQuery, DefaultZeroU16<T>>;
11311135
#[pallet::storage]

pallets/subtensor/src/macros/config.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,5 +210,8 @@ mod config {
210210
/// Initial EMA price halving period
211211
#[pallet::constant]
212212
type InitialEmaPriceHalvingPeriod: Get<u64>;
213+
/// Block number after a new subnet accept the start call extrinsic.
214+
#[pallet::constant]
215+
type DurationOfStartCall: Get<u64>;
213216
}
214217
}

pallets/subtensor/src/macros/dispatches.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1910,6 +1910,25 @@ mod dispatches {
19101910
Ok(())
19111911
}
19121912

1913+
/// Initiates a call on a subnet.
1914+
///
1915+
/// # Arguments
1916+
/// * `origin` - The origin of the call, which must be signed by the subnet owner.
1917+
/// * `netuid` - The unique identifier of the subnet on which the call is being initiated.
1918+
///
1919+
/// # Events
1920+
/// Emits a `FirstEmissionBlockNumberSet` event on success.
1921+
#[pallet::call_index(92)]
1922+
#[pallet::weight((
1923+
Weight::from_parts(3_000_000, 0).saturating_add(T::DbWeight::get().reads_writes(6, 1)),
1924+
DispatchClass::Operational,
1925+
Pays::Yes
1926+
))]
1927+
pub fn start_call(origin: T::RuntimeOrigin, netuid: u16) -> DispatchResult {
1928+
Self::do_start_call(origin, netuid)?;
1929+
Ok(())
1930+
}
1931+
19131932
/// Recycles alpha from a cold/hot key pair, reducing AlphaOut on a subnet
19141933
///
19151934
/// # Arguments

pallets/subtensor/src/macros/errors.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,10 @@ mod errors {
195195
ActivityCutoffTooLow,
196196
/// Call is disabled
197197
CallDisabled,
198+
/// FirstEmissionBlockNumber is already set.
199+
FirstEmissionBlockNumberAlreadySet,
200+
/// need wait for more blocks to accept the start call extrinsic.
201+
NeedWaitingMoreBlocksToStarCall,
198202
/// Not enough AlphaOut on the subnet to recycle
199203
NotEnoughAlphaOutToRecycle,
200204
}

pallets/subtensor/src/macros/events.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,12 @@ mod events {
275275
/// Parameters:
276276
/// (netuid, new_hotkey)
277277
SubnetOwnerHotkeySet(u16, T::AccountId),
278+
/// FirstEmissionBlockNumber is set via start call extrinsic
279+
///
280+
/// Parameters:
281+
/// netuid
282+
/// block number
283+
FirstEmissionBlockNumberSet(u16, u64),
278284

279285
/// Alpha has been recycled, reducing AlphaOut on a subnet.
280286
///

pallets/subtensor/src/macros/hooks.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,9 @@ mod hooks {
8181
// Remove Stake map entries
8282
.saturating_add(migrations::migrate_remove_stake_map::migrate_remove_stake_map::<T>())
8383
// Remove unused maps entries
84-
.saturating_add(migrations::migrate_remove_unused_maps_and_values::migrate_remove_unused_maps_and_values::<T>());
84+
.saturating_add(migrations::migrate_remove_unused_maps_and_values::migrate_remove_unused_maps_and_values::<T>())
85+
// Set last emission block number for all existed subnets before start call feature applied
86+
.saturating_add(migrations::migrate_set_first_emission_block_number::migrate_set_first_emission_block_number::<T>());
8587
weight
8688
}
8789

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
use super::*;
2+
use crate::HasMigrationRun;
3+
use frame_support::{traits::Get, weights::Weight};
4+
use scale_info::prelude::string::String;
5+
6+
pub fn migrate_set_first_emission_block_number<T: Config>() -> Weight {
7+
let migration_name = b"migrate_set_first_emission_block_number".to_vec();
8+
9+
let mut weight = T::DbWeight::get().reads(1);
10+
if HasMigrationRun::<T>::get(&migration_name) {
11+
log::info!(
12+
"Migration '{:?}' has already run. Skipping.",
13+
String::from_utf8_lossy(&migration_name)
14+
);
15+
return weight;
16+
}
17+
18+
log::info!(
19+
"Running migration '{:?}'",
20+
String::from_utf8_lossy(&migration_name)
21+
);
22+
23+
// ------------------------------
24+
// Step 1: Set the first emission block for all subnets except root
25+
// ------------------------------
26+
let netuids = Pallet::<T>::get_all_subnet_netuids();
27+
let current_block_number = Pallet::<T>::get_current_block_as_u64();
28+
for netuid in netuids.iter() {
29+
if *netuid != 0 {
30+
FirstEmissionBlockNumber::<T>::insert(netuid, current_block_number);
31+
}
32+
}
33+
34+
// ------------------------------
35+
// Step 2: Mark Migration as Completed
36+
// ------------------------------
37+
38+
HasMigrationRun::<T>::insert(&migration_name, true);
39+
weight = weight.saturating_add(T::DbWeight::get().reads(2));
40+
41+
if netuids.is_empty() {
42+
weight = weight.saturating_add(T::DbWeight::get().writes(1_u64));
43+
} else {
44+
weight = weight.saturating_add(T::DbWeight::get().writes(netuids.len() as u64));
45+
}
46+
47+
log::info!(
48+
"Migration '{:?}' completed successfully.",
49+
String::from_utf8_lossy(&migration_name)
50+
);
51+
52+
weight
53+
}

0 commit comments

Comments
 (0)