Skip to content
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
4 changes: 2 additions & 2 deletions chain-extensions/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@ parameter_types! {
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
pub const DurationOfStartCall: u64 = 7 * 24 * 60 * 60 / 12; // Default as 7 days
pub const InitialStartCallDelay: u64 = 7 * 24 * 60 * 60 / 12; // Default as 7 days
pub const InitialKeySwapOnSubnetCost: u64 = 10_000_000;
pub const HotkeySwapOnSubnetInterval: u64 = 15; // 15 block, should be bigger than subnet number, then trigger clean up for all subnets
pub const MaxContributorsPerLeaseToRemove: u32 = 3;
Expand Down Expand Up @@ -402,7 +402,7 @@ impl pallet_subtensor::Config for Test {
type InitialDissolveNetworkScheduleDuration = InitialDissolveNetworkScheduleDuration;
type InitialTaoWeight = InitialTaoWeight;
type InitialEmaPriceHalvingPeriod = InitialEmaPriceHalvingPeriod;
type DurationOfStartCall = DurationOfStartCall;
type InitialStartCallDelay = InitialStartCallDelay;
type SwapInterface = pallet_subtensor_swap::Pallet<Self>;
type KeySwapOnSubnetCost = InitialKeySwapOnSubnetCost;
type HotkeySwapOnSubnetInterval = HotkeySwapOnSubnetInterval;
Expand Down
2 changes: 1 addition & 1 deletion contract-tests/src/subtensor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ export async function setSubtokenEnable(api: TypedApi<typeof devnet>, netuid: nu
export async function startCall(api: TypedApi<typeof devnet>, netuid: number, keypair: KeyPair) {
const registerBlock = Number(await api.query.SubtensorModule.NetworkRegisteredAt.getValue(netuid))
let currentBlock = await api.query.System.Number.getValue()
const duration = Number(await api.constants.SubtensorModule.DurationOfStartCall)
const duration = Number(await api.constants.SubtensorModule.InitialStartCallDelay)

while (currentBlock - registerBlock <= duration) {
await new Promise((resolve) => setTimeout(resolve, 2000));
Expand Down
15 changes: 15 additions & 0 deletions pallets/admin-utils/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2240,6 +2240,21 @@ pub mod pallet {
pallet_subtensor::Pallet::<T>::set_min_non_immune_uids(netuid, min);
Ok(())
}

/// Sets the delay before a subnet can call start
#[pallet::call_index(85)]
#[pallet::weight((
Weight::from_parts(14_000_000, 0)
.saturating_add(<T as frame_system::Config>::DbWeight::get().writes(1)),
DispatchClass::Operational,
Pays::Yes
))]
pub fn sudo_set_start_call_delay(origin: OriginFor<T>, delay: u64) -> DispatchResult {
ensure_root(origin)?;
pallet_subtensor::Pallet::<T>::set_start_call_delay(delay);
log::debug!("StartCallDelay( delay: {delay:?} ) ");
Ok(())
}
}
}

Expand Down
4 changes: 2 additions & 2 deletions pallets/admin-utils/src/tests/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ parameter_types! {
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
pub const DurationOfStartCall: u64 = 7 * 24 * 60 * 60 / 12; // 7 days
pub const InitialStartCallDelay: u64 = 7 * 24 * 60 * 60 / 12; // 7 days
pub const InitialKeySwapOnSubnetCost: u64 = 10_000_000;
pub const HotkeySwapOnSubnetInterval: u64 = 7 * 24 * 60 * 60 / 12; // 7 days
pub const LeaseDividendsDistributionInterval: u32 = 100; // 100 blocks
Expand Down Expand Up @@ -215,7 +215,7 @@ impl pallet_subtensor::Config for Test {
type InitialDissolveNetworkScheduleDuration = InitialDissolveNetworkScheduleDuration;
type InitialTaoWeight = InitialTaoWeight;
type InitialEmaPriceHalvingPeriod = InitialEmaPriceHalvingPeriod;
type DurationOfStartCall = DurationOfStartCall;
type InitialStartCallDelay = InitialStartCallDelay;
type SwapInterface = Swap;
type KeySwapOnSubnetCost = InitialKeySwapOnSubnetCost;
type HotkeySwapOnSubnetInterval = HotkeySwapOnSubnetInterval;
Expand Down
98 changes: 98 additions & 0 deletions pallets/admin-utils/src/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2887,3 +2887,101 @@ fn test_sudo_set_min_non_immune_uids() {
assert_eq!(SubtensorModule::get_min_non_immune_uids(netuid), to_be_set);
});
}

#[test]
fn test_sudo_set_start_call_delay_permissions_and_zero_delay() {
new_test_ext().execute_with(|| {
let netuid = NetUid::from(1);
let tempo: u16 = 13;
let coldkey_account_id = U256::from(0);
let non_root_account = U256::from(1);

// Get initial delay value (should be non-zero)
let initial_delay = pallet_subtensor::StartCallDelay::<Test>::get();
assert!(
initial_delay > 0,
"Initial delay should be greater than zero"
);

// Test 1: Non-root account should fail to set delay
assert_err!(
AdminUtils::sudo_set_start_call_delay(
<<Test as Config>::RuntimeOrigin>::signed(non_root_account),
0
),
DispatchError::BadOrigin
);
assert_eq!(
pallet_subtensor::StartCallDelay::<Test>::get(),
initial_delay,
"Delay should not have changed"
);

// Test 2: Create a subnet
add_network(netuid, tempo);
assert_eq!(
pallet_subtensor::FirstEmissionBlockNumber::<Test>::get(netuid),
None,
"Emission block should not be set yet"
);
assert_eq!(
pallet_subtensor::SubnetOwner::<Test>::get(netuid),
coldkey_account_id,
"Default owner should be account 0"
);

// Test 3: Try to start the subnet immediately - should FAIL (delay not passed)
assert_err!(
pallet_subtensor::Pallet::<Test>::start_call(
<<Test as Config>::RuntimeOrigin>::signed(coldkey_account_id),
netuid
),
pallet_subtensor::Error::<Test>::NeedWaitingMoreBlocksToStarCall
);

// Verify emission has not been set
assert_eq!(
pallet_subtensor::FirstEmissionBlockNumber::<Test>::get(netuid),
None,
"Emission should not be set yet"
);

// Test 4: Root sets delay to zero
assert_ok!(AdminUtils::sudo_set_start_call_delay(
<<Test as Config>::RuntimeOrigin>::root(),
0
));
assert_eq!(
pallet_subtensor::StartCallDelay::<Test>::get(),
0,
"Delay should now be zero"
);

// Verify event was emitted
frame_system::Pallet::<Test>::assert_last_event(RuntimeEvent::SubtensorModule(
pallet_subtensor::Event::StartCallDelaySet(0),
));

// Test 5: Try to start the subnet again - should SUCCEED (delay is now zero)
let current_block = frame_system::Pallet::<Test>::block_number();
assert_ok!(pallet_subtensor::Pallet::<Test>::start_call(
<<Test as Config>::RuntimeOrigin>::signed(coldkey_account_id),
netuid
));

assert_eq!(
pallet_subtensor::FirstEmissionBlockNumber::<Test>::get(netuid),
Some(current_block + 1),
"Emission should start at next block"
);

// Test 6: Try to start it a third time - should FAIL (already started)
assert_err!(
pallet_subtensor::Pallet::<Test>::start_call(
<<Test as Config>::RuntimeOrigin>::signed(coldkey_account_id),
netuid
),
pallet_subtensor::Error::<Test>::FirstEmissionBlockNumberAlreadySet
);
});
}
2 changes: 1 addition & 1 deletion pallets/subtensor/src/benchmarks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -648,7 +648,7 @@ mod pallet_benchmarks {
assert_eq!(FirstEmissionBlockNumber::<T>::get(netuid), None);

let current_block: u64 = Subtensor::<T>::get_current_block_as_u64();
let duration = <T as Config>::DurationOfStartCall::get();
let duration = StartCallDelay::<T>::get();
let block: BlockNumberFor<T> = (current_block + duration)
.try_into()
.ok()
Expand Down
7 changes: 7 additions & 0 deletions pallets/subtensor/src/coinbase/root.rs
Original file line number Diff line number Diff line change
Expand Up @@ -542,6 +542,13 @@ impl<T: Config> Pallet<T> {
NetworkImmunityPeriod::<T>::set(net_immunity_period);
Self::deposit_event(Event::NetworkImmunityPeriodSet(net_immunity_period));
}
pub fn get_start_call_delay() -> u64 {
StartCallDelay::<T>::get()
}
pub fn set_start_call_delay(delay: u64) {
StartCallDelay::<T>::set(delay);
Self::deposit_event(Event::StartCallDelaySet(delay));
}
pub fn set_network_min_lock(net_min_lock: TaoCurrency) {
NetworkMinLockCost::<T>::set(net_min_lock);
Self::deposit_event(Event::NetworkMinLockCostSet(net_min_lock));
Expand Down
10 changes: 10 additions & 0 deletions pallets/subtensor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -640,6 +640,12 @@ pub mod pallet {
T::InitialSubnetOwnerCut::get()
}

/// Default value for start call delay.
#[pallet::type_value]
pub fn DefaultStartCallDelay<T: Config>() -> u64 {
T::InitialStartCallDelay::get()
}

/// Default value for recycle or burn.
#[pallet::type_value]
pub fn DefaultRecycleOrBurn<T: Config>() -> RecycleOrBurnEnum {
Expand Down Expand Up @@ -1514,6 +1520,10 @@ pub mod pallet {
pub type NetworkImmunityPeriod<T> =
StorageValue<_, u64, ValueQuery, DefaultNetworkImmunityPeriod<T>>;

/// ITEM( start_call_delay )
#[pallet::storage]
pub type StartCallDelay<T> = StorageValue<_, u64, ValueQuery, DefaultStartCallDelay<T>>;

/// ITEM( min_network_lock_cost )
#[pallet::storage]
pub type NetworkMinLockCost<T> =
Expand Down
4 changes: 2 additions & 2 deletions pallets/subtensor/src/macros/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -233,9 +233,9 @@ mod config {
/// Initial EMA price halving period
#[pallet::constant]
type InitialEmaPriceHalvingPeriod: Get<u64>;
/// Block number after a new subnet accept the start call extrinsic.
/// Initial block number after a new subnet accept the start call extrinsic.
#[pallet::constant]
type DurationOfStartCall: Get<u64>;
type InitialStartCallDelay: Get<u64>;
/// Cost of swapping a hotkey in a subnet.
#[pallet::constant]
type KeySwapOnSubnetCost: Get<u64>;
Expand Down
2 changes: 2 additions & 0 deletions pallets/subtensor/src/macros/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,8 @@ mod events {
NetworkRateLimitSet(u64),
/// the network immunity period is set.
NetworkImmunityPeriodSet(u64),
/// the start call delay is set.
StartCallDelaySet(u64),
/// the network minimum locking cost is set.
NetworkMinLockCostSet(TaoCurrency),
/// the maximum number of subnets is set
Expand Down
2 changes: 1 addition & 1 deletion pallets/subtensor/src/subnets/subnet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,7 @@ impl<T: Config> Pallet<T> {

ensure!(
current_block_number
>= registration_block_number.saturating_add(T::DurationOfStartCall::get()),
>= registration_block_number.saturating_add(StartCallDelay::<T>::get()),
Error::<T>::NeedWaitingMoreBlocksToStarCall
);
let next_block_number = current_block_number.saturating_add(1);
Expand Down
2 changes: 1 addition & 1 deletion pallets/subtensor/src/tests/coinbase.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2701,7 +2701,7 @@ fn test_run_coinbase_not_started_start_after() {
// We expect that the epoch ran.
assert_eq!(BlocksSinceLastStep::<Test>::get(netuid), 0);

let block_number = DurationOfStartCall::get();
let block_number = StartCallDelay::<Test>::get();
run_to_block_no_epoch(netuid, block_number);

let current_block = System::block_number();
Expand Down
4 changes: 2 additions & 2 deletions pallets/subtensor/src/tests/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ parameter_types! {
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
pub const DurationOfStartCall: u64 = 7 * 24 * 60 * 60 / 12; // Default as 7 days
pub const InitialStartCallDelay: u64 = 7 * 24 * 60 * 60 / 12; // Default as 7 days
pub const InitialKeySwapOnSubnetCost: u64 = 10_000_000;
pub const HotkeySwapOnSubnetInterval: u64 = 15; // 15 block, should be bigger than subnet number, then trigger clean up for all subnets
pub const MaxContributorsPerLeaseToRemove: u32 = 3;
Expand Down Expand Up @@ -289,7 +289,7 @@ impl crate::Config for Test {
type InitialDissolveNetworkScheduleDuration = InitialDissolveNetworkScheduleDuration;
type InitialTaoWeight = InitialTaoWeight;
type InitialEmaPriceHalvingPeriod = InitialEmaPriceHalvingPeriod;
type DurationOfStartCall = DurationOfStartCall;
type InitialStartCallDelay = InitialStartCallDelay;
type SwapInterface = pallet_subtensor_swap::Pallet<Self>;
type KeySwapOnSubnetCost = InitialKeySwapOnSubnetCost;
type HotkeySwapOnSubnetInterval = HotkeySwapOnSubnetInterval;
Expand Down
10 changes: 5 additions & 5 deletions pallets/subtensor/src/tests/subnet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ fn test_do_start_call_ok() {
// account 0 is the default owner for any subnet
assert_eq!(SubnetOwner::<Test>::get(netuid), coldkey_account_id);

let block_number = System::block_number() + DurationOfStartCall::get();
let block_number = System::block_number() + StartCallDelay::<Test>::get();
System::set_block_number(block_number);

assert_ok!(SubtensorModule::start_call(
Expand Down Expand Up @@ -76,7 +76,7 @@ fn test_do_start_call_fail_not_owner() {

assert_eq!(SubnetOwner::<Test>::get(netuid), coldkey_account_id);

System::set_block_number(System::block_number() + DurationOfStartCall::get());
System::set_block_number(System::block_number() + StartCallDelay::<Test>::get());

assert_noop!(
SubtensorModule::start_call(
Expand Down Expand Up @@ -143,7 +143,7 @@ fn test_do_start_call_fail_for_set_again() {

assert_eq!(SubnetOwner::<Test>::get(netuid), coldkey_account_id);

let block_number = System::block_number() + DurationOfStartCall::get();
let block_number = System::block_number() + StartCallDelay::<Test>::get();
System::set_block_number(block_number);

assert_ok!(SubtensorModule::start_call(
Expand Down Expand Up @@ -174,7 +174,7 @@ fn test_do_start_call_ok_with_same_block_number_after_coinbase() {

assert_eq!(SubnetOwner::<Test>::get(netuid), coldkey_account_id);

let block_number = System::block_number() + DurationOfStartCall::get();
let block_number = System::block_number() + StartCallDelay::<Test>::get();
System::set_block_number(block_number);

assert_ok!(SubtensorModule::start_call(
Expand Down Expand Up @@ -368,7 +368,7 @@ fn test_subtoken_enable() {
add_network_disable_subtoken(netuid, 10, 0);
assert!(!SubtokenEnabled::<Test>::get(netuid));

let block_number = System::block_number() + DurationOfStartCall::get();
let block_number = System::block_number() + StartCallDelay::<Test>::get();
System::set_block_number(block_number);

assert_ok!(SubtensorModule::start_call(
Expand Down
4 changes: 2 additions & 2 deletions pallets/transaction-fee/src/tests/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ parameter_types! {
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
pub const DurationOfStartCall: u64 = 7 * 24 * 60 * 60 / 12; // 7 days
pub const InitialStartCallDelay: u64 = 7 * 24 * 60 * 60 / 12; // 7 days
pub const InitialKeySwapOnSubnetCost: u64 = 10_000_000;
pub const HotkeySwapOnSubnetInterval: u64 = 7 * 24 * 60 * 60 / 12; // 7 days
pub const LeaseDividendsDistributionInterval: u32 = 100; // 100 blocks
Expand Down Expand Up @@ -280,7 +280,7 @@ impl pallet_subtensor::Config for Test {
type InitialDissolveNetworkScheduleDuration = InitialDissolveNetworkScheduleDuration;
type InitialTaoWeight = InitialTaoWeight;
type InitialEmaPriceHalvingPeriod = InitialEmaPriceHalvingPeriod;
type DurationOfStartCall = DurationOfStartCall;
type InitialStartCallDelay = InitialStartCallDelay;
type SwapInterface = Swap;
type KeySwapOnSubnetCost = InitialKeySwapOnSubnetCost;
type HotkeySwapOnSubnetInterval = HotkeySwapOnSubnetInterval;
Expand Down
4 changes: 2 additions & 2 deletions runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1058,7 +1058,7 @@ parameter_types! {
pub const SubtensorInitialTaoWeight: u64 = 971_718_665_099_567_868; // 0.05267697438728329% tao weight.
pub const InitialEmaPriceHalvingPeriod: u64 = 201_600_u64; // 4 weeks
// 7 * 24 * 60 * 60 / 12 = 7 days
pub const DurationOfStartCall: u64 = prod_or_fast!(7 * 24 * 60 * 60 / 12, 10);
pub const InitialStartCallDelay: u64 = prod_or_fast!(7 * 24 * 60 * 60 / 12, 10);
pub const SubtensorInitialKeySwapOnSubnetCost: u64 = 1_000_000; // 0.001 TAO
pub const HotkeySwapOnSubnetInterval : BlockNumber = 5 * 24 * 60 * 60 / 12; // 5 days
pub const LeaseDividendsDistributionInterval: BlockNumber = 100; // 100 blocks
Expand Down Expand Up @@ -1128,7 +1128,7 @@ impl pallet_subtensor::Config for Runtime {
type InitialColdkeySwapRescheduleDuration = InitialColdkeySwapRescheduleDuration;
type InitialDissolveNetworkScheduleDuration = InitialDissolveNetworkScheduleDuration;
type InitialEmaPriceHalvingPeriod = InitialEmaPriceHalvingPeriod;
type DurationOfStartCall = DurationOfStartCall;
type InitialStartCallDelay = InitialStartCallDelay;
type SwapInterface = Swap;
type KeySwapOnSubnetCost = SubtensorInitialKeySwapOnSubnetCost;
type HotkeySwapOnSubnetInterval = HotkeySwapOnSubnetInterval;
Expand Down
Loading
Loading