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
3 changes: 3 additions & 0 deletions node/src/chain_spec/localnet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,5 +124,8 @@ fn localnet_genesis(
"evmChainId": {
"chainId": 42,
},
"subtensorModule": {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This breaks all the benchmarks

"startCallDelay": 10,
},
Comment on lines +127 to +129
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It needs to be added to the GenesisConfig of the Subtensor pallet

})
}
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 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it intentional to make it a global hyperparam (i.e. not per-subnet)?

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"
);
Comment on lines +2907 to +2918
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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"
);
assert_noop!(
AdminUtils::sudo_set_start_call_delay(
<<Test as Config>::RuntimeOrigin>::signed(non_root_account),
0
),
DispatchError::BadOrigin
);


// 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 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in my opinion we should avoid introducing more of these kind of getters. StartCallDelay::get() is pretty much self-sufficient and clear.

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()
}
Comment on lines +644 to +647
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#[pallet::type_value]
pub fn DefaultStartCallDelay<T: Config>() -> u64 {
T::InitialStartCallDelay::get()
}

I suspect it may not be needed because the role of type_value is to derive a Get implementation, which T::InitialStartCallDelay already has so you can just use it directly


/// 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>>;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
pub type StartCallDelay<T> = StorageValue<_, u64, ValueQuery, DefaultStartCallDelay<T>>;
pub type StartCallDelay<T> = StorageValue<_, u64, ValueQuery, T::InitialStartCallDelay>;


/// 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.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// Initial block number after a new subnet accept the start call extrinsic.
/// Delay after which a new subnet can dispatch 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