From 2257ce92546c291a12ebbdb5cf729b0b5e4c3101 Mon Sep 17 00:00:00 2001 From: Philip Maymin Date: Thu, 30 Jul 2026 16:33:26 +0200 Subject: [PATCH 1/3] Benchmark register_network against a full subnet map register_network's benchmark registers into a chain with no subnets on it, so neither of the two costs that scale with subnet count lands in the measurement: the unconditional NetworksAdded::iter() count, and the get_network_to_prune scan that runs once the count reaches SubnetLimit. Fill the map before measuring, and add register_network_pruning for the branch that was never measured at all. The two outcomes are mutually exclusive and neither dominates: creation costs more ref_time, pruning more proof_size. Both dispatches charge the componentwise max. register_network measures 293 reads and 14.39 ms of charged weight against the 41 reads and 5.98 ms it currently declares. --- .../subtensor/src/benchmarks/benchmarks.rs | 35 ++++ pallets/subtensor/src/benchmarks/helpers.rs | 34 ++++ pallets/subtensor/src/macros/dispatches.rs | 11 +- pallets/subtensor/src/weights.rs | 191 +++++++++++++++--- 4 files changed, 237 insertions(+), 34 deletions(-) diff --git a/pallets/subtensor/src/benchmarks/benchmarks.rs b/pallets/subtensor/src/benchmarks/benchmarks.rs index 375bdb61ea..e869014ecb 100644 --- a/pallets/subtensor/src/benchmarks/benchmarks.rs +++ b/pallets/subtensor/src/benchmarks/benchmarks.rs @@ -301,10 +301,42 @@ mod pallet_benchmarks { let amount: u64 = 100_000_000_000_000u64.saturating_mul(2); add_balance_to_coldkey_account::(&coldkey, amount.into()); + frame_system::Pallet::::set_block_number(1u32.into()); + fill_subnets_below_limit::(&account("FillOwner", 0, seed)); + #[extrinsic_call] _(RawOrigin::Signed(coldkey.clone()), hotkey.clone()); } + /// The other outcome of `do_register_network`: at `SubnetLimit` the call prunes a subnet and + /// queues rather than creating one. Not an extrinsic; it exists so the two dispatches that can + /// reach this branch can charge the worst of the two. + #[benchmark] + fn register_network_pruning() { + let seed: u32 = 1; + let coldkey: T::AccountId = account("Test", 0, seed); + let hotkey: T::AccountId = account("TestHotkey", 0, seed); + + Subtensor::::set_network_rate_limit(1); + let amount: u64 = 100_000_000_000_000u64.saturating_mul(2); + add_balance_to_coldkey_account::(&coldkey, amount.into()); + + frame_system::Pallet::::set_block_number(1u32.into()); + fill_subnets_to_limit::(&account("FillOwner", 0, seed)); + + #[block] + { + let _ = Subtensor::::do_register_network( + RawOrigin::Signed(coldkey.clone()).into(), + &hotkey, + 1, + None, + ); + } + + assert!(!NetworkRegistrationQueue::::get().is_empty()); + } + #[benchmark] fn commit_weights() { let tempo: u16 = 1; @@ -1456,6 +1488,9 @@ mod pallet_benchmarks { let amount: u64 = 9_999_999_999_999; add_balance_to_coldkey_account::(&coldkey, amount.into()); + frame_system::Pallet::::set_block_number(1u32.into()); + fill_subnets_below_limit::(&account("FillOwner", 0, 1)); + #[extrinsic_call] _( RawOrigin::Signed(coldkey.clone()), diff --git a/pallets/subtensor/src/benchmarks/helpers.rs b/pallets/subtensor/src/benchmarks/helpers.rs index 2f45e98e80..3abc6730dd 100644 --- a/pallets/subtensor/src/benchmarks/helpers.rs +++ b/pallets/subtensor/src/benchmarks/helpers.rs @@ -15,6 +15,40 @@ pub(super) fn set_reserves( SubnetAlphaIn::::insert(netuid, alpha_in); } +/// Fill the chain with prunable subnets so a registration benchmark runs against a realistic +/// `NetworksAdded` map rather than an empty one. +/// +/// `do_register_network` counts every entry in `NetworksAdded` on every call, and once that count +/// reaches `SubnetLimit` it also walks `get_network_to_prune`. Registering into an empty chain +/// measures neither. The two outcomes are mutually exclusive and neither dominates the other: +/// below the limit the call creates a subnet (many writes), at the limit it prunes and queues +/// instead (far more reads). Callers pick which one they are measuring via `subnets`. +/// +/// Immunity is set to one block and `NetworkRegisteredAt` to zero so no candidate is skipped. +/// Requires a current block above zero. +pub(super) fn fill_subnets(owner: &T::AccountId, subnets: u16) { + NetworkImmunityPeriod::::set(1); + + for netuid in 1..=subnets { + let netuid = NetUid::from(netuid); + Subtensor::::init_new_network(netuid, 1); + NetworkRegisteredAt::::insert(netuid, 0); + SubnetOwner::::insert(netuid, owner.clone()); + } +} + +/// One below `SubnetLimit`: the registration still creates a subnet, but pays the full count. +pub(super) fn fill_subnets_below_limit(owner: &T::AccountId) { + let limit = Subtensor::::get_max_subnets(); + fill_subnets::(owner, limit.saturating_sub(1)); +} + +/// At `SubnetLimit`: the registration prunes a subnet and queues instead of creating one. +pub(super) fn fill_subnets_to_limit(owner: &T::AccountId) { + let limit = Subtensor::::get_max_subnets(); + fill_subnets::(owner, limit); +} + pub(super) fn benchmark_registration_burn() -> TaoBalance { TaoBalance::from(1_000_000) } diff --git a/pallets/subtensor/src/macros/dispatches.rs b/pallets/subtensor/src/macros/dispatches.rs index 4c190a7497..a809553b7b 100644 --- a/pallets/subtensor/src/macros/dispatches.rs +++ b/pallets/subtensor/src/macros/dispatches.rs @@ -1001,8 +1001,12 @@ mod dispatches { } /// User register a new subnetwork + /// + /// Below `SubnetLimit` this creates a subnet; at the limit it prunes one and queues + /// instead. The two are mutually exclusive and neither dominates, so charge the worse. #[pallet::call_index(59)] - #[pallet::weight(::WeightInfo::register_network())] + #[pallet::weight(::WeightInfo::register_network() + .max(::WeightInfo::register_network_pruning()))] pub fn register_network(origin: OriginFor, hotkey: T::AccountId) -> DispatchResult { Self::do_register_network(origin, &hotkey, 1, None) } @@ -1181,8 +1185,11 @@ mod dispatches { } /// User register a new subnetwork + /// + /// Same two outcomes as `register_network`, so the same worst case applies. #[pallet::call_index(79)] - #[pallet::weight(::WeightInfo::register_network_with_identity())] + #[pallet::weight(::WeightInfo::register_network_with_identity() + .max(::WeightInfo::register_network_pruning()))] pub fn register_network_with_identity( origin: OriginFor, hotkey: T::AccountId, diff --git a/pallets/subtensor/src/weights.rs b/pallets/subtensor/src/weights.rs index 63bd54336a..5e74840483 100644 --- a/pallets/subtensor/src/weights.rs +++ b/pallets/subtensor/src/weights.rs @@ -44,6 +44,7 @@ pub trait WeightInfo { fn burned_register() -> Weight; fn root_register() -> Weight; fn register_network() -> Weight; + fn register_network_pruning() -> Weight; fn commit_weights() -> Weight; fn reveal_weights() -> Weight; fn sudo_set_tx_childkey_take_rate_limit() -> Weight; @@ -604,7 +605,7 @@ impl WeightInfo for SubstrateWeight { /// Proof: `SubtensorModule::LastRateLimitedBlock` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::SubnetLimit` (r:1 w:0) /// Proof: `SubtensorModule::SubnetLimit` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `SubtensorModule::NetworksAdded` (r:3 w:1) + /// Storage: `SubtensorModule::NetworksAdded` (r:129 w:1) /// Proof: `SubtensorModule::NetworksAdded` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::DissolveCleanupQueue` (r:1 w:0) /// Proof: `SubtensorModule::DissolveCleanupQueue` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) @@ -620,7 +621,7 @@ impl WeightInfo for SubstrateWeight { /// Proof: `SubtensorModule::TotalIssuance` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Storage: `System::Account` (r:2 w:2) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(104), added: 2579, mode: `MaxEncodedLen`) - /// Storage: `SubtensorModule::SubnetMechanism` (r:1 w:1) + /// Storage: `SubtensorModule::SubnetMechanism` (r:127 w:1) /// Proof: `SubtensorModule::SubnetMechanism` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::SubnetAlphaIn` (r:1 w:1) /// Proof: `SubtensorModule::SubnetAlphaIn` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -704,18 +705,79 @@ impl WeightInfo for SubstrateWeight { /// Proof: `SubtensorModule::NetworkRegistrationAllowed` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::Yuma3On` (r:0 w:1) /// Proof: `SubtensorModule::Yuma3On` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::HotkeySuccessor` (r:0 w:1) + /// Proof: `SubtensorModule::HotkeySuccessor` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::IsNetworkMember` (r:0 w:1) /// Proof: `SubtensorModule::IsNetworkMember` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::MaxAllowedUids` (r:0 w:1) /// Proof: `SubtensorModule::MaxAllowedUids` (`max_values`: None, `max_size`: None, mode: `Measured`) fn register_network() -> Weight { // Proof Size summary in bytes: - // Measured: `1532` - // Estimated: `9947` - // Minimum execution time: 145_000_000 picoseconds. - Weight::from_parts(153_000_000, 9947) - .saturating_add(T::DbWeight::get().reads(41_u64)) - .saturating_add(T::DbWeight::get().writes(48_u64)) + // Measured: `3721` + // Estimated: `323986` + // Minimum execution time: 2_130_304_000 picoseconds. + Weight::from_parts(2_160_771_000, 323986) + .saturating_add(T::DbWeight::get().reads(293_u64)) + .saturating_add(T::DbWeight::get().writes(49_u64)) + } + /// Storage: `SubtensorModule::Owner` (r:1 w:0) + /// Proof: `SubtensorModule::Owner` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::NetworkRegistrationStartBlock` (r:1 w:0) + /// Proof: `SubtensorModule::NetworkRegistrationStartBlock` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::NetworkRateLimit` (r:1 w:0) + /// Proof: `SubtensorModule::NetworkRateLimit` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::LastRateLimitedBlock` (r:1 w:0) + /// Proof: `SubtensorModule::LastRateLimitedBlock` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::SubnetLimit` (r:1 w:0) + /// Proof: `SubtensorModule::SubnetLimit` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::NetworksAdded` (r:130 w:1) + /// Proof: `SubtensorModule::NetworksAdded` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::DissolveCleanupQueue` (r:1 w:1) + /// Proof: `SubtensorModule::DissolveCleanupQueue` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::NetworkRegistrationQueue` (r:1 w:1) + /// Proof: `SubtensorModule::NetworkRegistrationQueue` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::NetworkRegisteredAt` (r:128 w:0) + /// Proof: `SubtensorModule::NetworkRegisteredAt` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::NetworkImmunityPeriod` (r:1 w:0) + /// Proof: `SubtensorModule::NetworkImmunityPeriod` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::SubnetMechanism` (r:128 w:0) + /// Proof: `SubtensorModule::SubnetMechanism` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::SubnetMovingPrice` (r:1 w:0) + /// Proof: `SubtensorModule::SubnetMovingPrice` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::NetworkLastLockCost` (r:1 w:0) + /// Proof: `SubtensorModule::NetworkLastLockCost` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::NetworkMinLockCost` (r:1 w:0) + /// Proof: `SubtensorModule::NetworkMinLockCost` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::NetworkLockReductionInterval` (r:1 w:0) + /// Proof: `SubtensorModule::NetworkLockReductionInterval` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::TotalIssuance` (r:1 w:0) + /// Proof: `SubtensorModule::TotalIssuance` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(104), added: 2579, mode: `MaxEncodedLen`) + /// Storage: `Swap::BalancerTaoReservoir` (r:1 w:1) + /// Proof: `Swap::BalancerTaoReservoir` (`max_values`: None, `max_size`: Some(18), added: 2493, mode: `MaxEncodedLen`) + /// Storage: `Swap::BalancerAlphaReservoir` (r:1 w:1) + /// Proof: `Swap::BalancerAlphaReservoir` (`max_values`: None, `max_size`: Some(18), added: 2493, mode: `MaxEncodedLen`) + /// Storage: `SubtensorModule::TotalNetworks` (r:1 w:1) + /// Proof: `SubtensorModule::TotalNetworks` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::TotalStake` (r:1 w:1) + /// Proof: `SubtensorModule::TotalStake` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::SubnetTAO` (r:1 w:0) + /// Proof: `SubtensorModule::SubnetTAO` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::NetworkRegistrationLockId` (r:1 w:1) + /// Proof: `SubtensorModule::NetworkRegistrationLockId` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(899), added: 3374, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(499), added: 2974, mode: `MaxEncodedLen`) + fn register_network_pruning() -> Weight { + // Proof Size summary in bytes: + // Measured: `3943` + // Estimated: `326683` + // Minimum execution time: 2_210_744_000 picoseconds. + Weight::from_parts(2_283_058_000, 326683) + .saturating_add(T::DbWeight::get().reads(408_u64)) + .saturating_add(T::DbWeight::get().writes(10_u64)) } /// Storage: `SubtensorModule::NetworksAdded` (r:1 w:0) /// Proof: `SubtensorModule::NetworksAdded` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -2050,7 +2112,7 @@ impl WeightInfo for SubstrateWeight { /// Proof: `SubtensorModule::LastRateLimitedBlock` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::SubnetLimit` (r:1 w:0) /// Proof: `SubtensorModule::SubnetLimit` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `SubtensorModule::NetworksAdded` (r:3 w:1) + /// Storage: `SubtensorModule::NetworksAdded` (r:129 w:1) /// Proof: `SubtensorModule::NetworksAdded` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::DissolveCleanupQueue` (r:1 w:0) /// Proof: `SubtensorModule::DissolveCleanupQueue` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) @@ -2064,7 +2126,7 @@ impl WeightInfo for SubstrateWeight { /// Proof: `SubtensorModule::NetworkLockReductionInterval` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::TotalIssuance` (r:1 w:0) /// Proof: `SubtensorModule::TotalIssuance` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `SubtensorModule::SubnetMechanism` (r:1 w:1) + /// Storage: `SubtensorModule::SubnetMechanism` (r:127 w:1) /// Proof: `SubtensorModule::SubnetMechanism` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::SubnetAlphaIn` (r:1 w:1) /// Proof: `SubtensorModule::SubnetAlphaIn` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -2150,18 +2212,20 @@ impl WeightInfo for SubstrateWeight { /// Proof: `SubtensorModule::NetworkRegistrationAllowed` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::Yuma3On` (r:0 w:1) /// Proof: `SubtensorModule::Yuma3On` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::HotkeySuccessor` (r:0 w:1) + /// Proof: `SubtensorModule::HotkeySuccessor` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::IsNetworkMember` (r:0 w:1) /// Proof: `SubtensorModule::IsNetworkMember` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::MaxAllowedUids` (r:0 w:1) /// Proof: `SubtensorModule::MaxAllowedUids` (`max_values`: None, `max_size`: None, mode: `Measured`) fn register_network_with_identity() -> Weight { // Proof Size summary in bytes: - // Measured: `1468` - // Estimated: `9883` - // Minimum execution time: 143_000_000 picoseconds. - Weight::from_parts(148_000_000, 9883) - .saturating_add(T::DbWeight::get().reads(40_u64)) - .saturating_add(T::DbWeight::get().writes(47_u64)) + // Measured: `3657` + // Estimated: `323922` + // Minimum execution time: 2_160_801_000 picoseconds. + Weight::from_parts(2_248_876_000, 323922) + .saturating_add(T::DbWeight::get().reads(292_u64)) + .saturating_add(T::DbWeight::get().writes(48_u64)) } /// Storage: `SubtensorModule::NetworksAdded` (r:1 w:0) /// Proof: `SubtensorModule::NetworksAdded` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -4218,7 +4282,7 @@ impl WeightInfo for () { /// Proof: `SubtensorModule::LastRateLimitedBlock` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::SubnetLimit` (r:1 w:0) /// Proof: `SubtensorModule::SubnetLimit` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `SubtensorModule::NetworksAdded` (r:3 w:1) + /// Storage: `SubtensorModule::NetworksAdded` (r:129 w:1) /// Proof: `SubtensorModule::NetworksAdded` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::DissolveCleanupQueue` (r:1 w:0) /// Proof: `SubtensorModule::DissolveCleanupQueue` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) @@ -4234,7 +4298,7 @@ impl WeightInfo for () { /// Proof: `SubtensorModule::TotalIssuance` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Storage: `System::Account` (r:2 w:2) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(104), added: 2579, mode: `MaxEncodedLen`) - /// Storage: `SubtensorModule::SubnetMechanism` (r:1 w:1) + /// Storage: `SubtensorModule::SubnetMechanism` (r:127 w:1) /// Proof: `SubtensorModule::SubnetMechanism` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::SubnetAlphaIn` (r:1 w:1) /// Proof: `SubtensorModule::SubnetAlphaIn` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -4318,18 +4382,79 @@ impl WeightInfo for () { /// Proof: `SubtensorModule::NetworkRegistrationAllowed` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::Yuma3On` (r:0 w:1) /// Proof: `SubtensorModule::Yuma3On` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::HotkeySuccessor` (r:0 w:1) + /// Proof: `SubtensorModule::HotkeySuccessor` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::IsNetworkMember` (r:0 w:1) /// Proof: `SubtensorModule::IsNetworkMember` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::MaxAllowedUids` (r:0 w:1) /// Proof: `SubtensorModule::MaxAllowedUids` (`max_values`: None, `max_size`: None, mode: `Measured`) fn register_network() -> Weight { // Proof Size summary in bytes: - // Measured: `1532` - // Estimated: `9947` - // Minimum execution time: 145_000_000 picoseconds. - Weight::from_parts(153_000_000, 9947) - .saturating_add(RocksDbWeight::get().reads(41_u64)) - .saturating_add(RocksDbWeight::get().writes(48_u64)) + // Measured: `3721` + // Estimated: `323986` + // Minimum execution time: 2_130_304_000 picoseconds. + Weight::from_parts(2_160_771_000, 323986) + .saturating_add(RocksDbWeight::get().reads(293_u64)) + .saturating_add(RocksDbWeight::get().writes(49_u64)) + } + /// Storage: `SubtensorModule::Owner` (r:1 w:0) + /// Proof: `SubtensorModule::Owner` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::NetworkRegistrationStartBlock` (r:1 w:0) + /// Proof: `SubtensorModule::NetworkRegistrationStartBlock` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::NetworkRateLimit` (r:1 w:0) + /// Proof: `SubtensorModule::NetworkRateLimit` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::LastRateLimitedBlock` (r:1 w:0) + /// Proof: `SubtensorModule::LastRateLimitedBlock` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::SubnetLimit` (r:1 w:0) + /// Proof: `SubtensorModule::SubnetLimit` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::NetworksAdded` (r:130 w:1) + /// Proof: `SubtensorModule::NetworksAdded` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::DissolveCleanupQueue` (r:1 w:1) + /// Proof: `SubtensorModule::DissolveCleanupQueue` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::NetworkRegistrationQueue` (r:1 w:1) + /// Proof: `SubtensorModule::NetworkRegistrationQueue` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::NetworkRegisteredAt` (r:128 w:0) + /// Proof: `SubtensorModule::NetworkRegisteredAt` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::NetworkImmunityPeriod` (r:1 w:0) + /// Proof: `SubtensorModule::NetworkImmunityPeriod` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::SubnetMechanism` (r:128 w:0) + /// Proof: `SubtensorModule::SubnetMechanism` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::SubnetMovingPrice` (r:1 w:0) + /// Proof: `SubtensorModule::SubnetMovingPrice` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::NetworkLastLockCost` (r:1 w:0) + /// Proof: `SubtensorModule::NetworkLastLockCost` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::NetworkMinLockCost` (r:1 w:0) + /// Proof: `SubtensorModule::NetworkMinLockCost` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::NetworkLockReductionInterval` (r:1 w:0) + /// Proof: `SubtensorModule::NetworkLockReductionInterval` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::TotalIssuance` (r:1 w:0) + /// Proof: `SubtensorModule::TotalIssuance` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(104), added: 2579, mode: `MaxEncodedLen`) + /// Storage: `Swap::BalancerTaoReservoir` (r:1 w:1) + /// Proof: `Swap::BalancerTaoReservoir` (`max_values`: None, `max_size`: Some(18), added: 2493, mode: `MaxEncodedLen`) + /// Storage: `Swap::BalancerAlphaReservoir` (r:1 w:1) + /// Proof: `Swap::BalancerAlphaReservoir` (`max_values`: None, `max_size`: Some(18), added: 2493, mode: `MaxEncodedLen`) + /// Storage: `SubtensorModule::TotalNetworks` (r:1 w:1) + /// Proof: `SubtensorModule::TotalNetworks` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::TotalStake` (r:1 w:1) + /// Proof: `SubtensorModule::TotalStake` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::SubnetTAO` (r:1 w:0) + /// Proof: `SubtensorModule::SubnetTAO` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::NetworkRegistrationLockId` (r:1 w:1) + /// Proof: `SubtensorModule::NetworkRegistrationLockId` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(899), added: 3374, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(499), added: 2974, mode: `MaxEncodedLen`) + fn register_network_pruning() -> Weight { + // Proof Size summary in bytes: + // Measured: `3943` + // Estimated: `326683` + // Minimum execution time: 2_210_744_000 picoseconds. + Weight::from_parts(2_283_058_000, 326683) + .saturating_add(RocksDbWeight::get().reads(408_u64)) + .saturating_add(RocksDbWeight::get().writes(10_u64)) } /// Storage: `SubtensorModule::NetworksAdded` (r:1 w:0) /// Proof: `SubtensorModule::NetworksAdded` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -5664,7 +5789,7 @@ impl WeightInfo for () { /// Proof: `SubtensorModule::LastRateLimitedBlock` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::SubnetLimit` (r:1 w:0) /// Proof: `SubtensorModule::SubnetLimit` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `SubtensorModule::NetworksAdded` (r:3 w:1) + /// Storage: `SubtensorModule::NetworksAdded` (r:129 w:1) /// Proof: `SubtensorModule::NetworksAdded` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::DissolveCleanupQueue` (r:1 w:0) /// Proof: `SubtensorModule::DissolveCleanupQueue` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) @@ -5678,7 +5803,7 @@ impl WeightInfo for () { /// Proof: `SubtensorModule::NetworkLockReductionInterval` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::TotalIssuance` (r:1 w:0) /// Proof: `SubtensorModule::TotalIssuance` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `SubtensorModule::SubnetMechanism` (r:1 w:1) + /// Storage: `SubtensorModule::SubnetMechanism` (r:127 w:1) /// Proof: `SubtensorModule::SubnetMechanism` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::SubnetAlphaIn` (r:1 w:1) /// Proof: `SubtensorModule::SubnetAlphaIn` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -5764,18 +5889,20 @@ impl WeightInfo for () { /// Proof: `SubtensorModule::NetworkRegistrationAllowed` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::Yuma3On` (r:0 w:1) /// Proof: `SubtensorModule::Yuma3On` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::HotkeySuccessor` (r:0 w:1) + /// Proof: `SubtensorModule::HotkeySuccessor` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::IsNetworkMember` (r:0 w:1) /// Proof: `SubtensorModule::IsNetworkMember` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::MaxAllowedUids` (r:0 w:1) /// Proof: `SubtensorModule::MaxAllowedUids` (`max_values`: None, `max_size`: None, mode: `Measured`) fn register_network_with_identity() -> Weight { // Proof Size summary in bytes: - // Measured: `1468` - // Estimated: `9883` - // Minimum execution time: 143_000_000 picoseconds. - Weight::from_parts(148_000_000, 9883) - .saturating_add(RocksDbWeight::get().reads(40_u64)) - .saturating_add(RocksDbWeight::get().writes(47_u64)) + // Measured: `3657` + // Estimated: `323922` + // Minimum execution time: 2_160_801_000 picoseconds. + Weight::from_parts(2_248_876_000, 323922) + .saturating_add(RocksDbWeight::get().reads(292_u64)) + .saturating_add(RocksDbWeight::get().writes(48_u64)) } /// Storage: `SubtensorModule::NetworksAdded` (r:1 w:0) /// Proof: `SubtensorModule::NetworksAdded` (`max_values`: None, `max_size`: None, mode: `Measured`) From 08144e6ddbbde0cd9ba155d4b1640254f65ab598 Mon Sep 17 00:00:00 2001 From: Philip Maymin Date: Thu, 30 Jul 2026 18:45:15 +0200 Subject: [PATCH 2/3] benchmarks: price the subnets the registration fixture builds fill_subnets created stable subnets with empty pools, so both price scans over NetworksAdded exited early on every entry. get_moving_alpha_price returns on SubnetMechanism == 0 without reading SubnetMovingPrice, and swap current_price returns before reading the TAO reserve or the balancer unless the alpha reserve is nonzero. The map was walked while nothing on it was priced. Every synthetic subnet now gets a dynamic mechanism and a funded pool. Reserves and moving prices are staggered per subnet so the median's BTreeMap holds distinct keys instead of collapsing to a single entry. register_network_with_identity and register_network_pruning now carry a maximum 6,656 byte identity. Creation writes it to storage; queueing encodes it into the queue entry and again into the event. Passing None measured neither, which is why main charges register_network_with_identity less than register_network on every dimension despite it doing strictly more work. register_network 293 -> 671 reads, register_network_pruning 408 -> 916, register_network_with_identity 292 -> 670. do_register_network has three successful outcomes, not two. The third, wait_to_cleanup, reaches the same queueing block without running get_network_to_prune or do_dissolve_network, so at equal queue depth it is dominated by the pruning measurement. Comments corrected to say so. --- .../subtensor/src/benchmarks/benchmarks.rs | 20 ++-- pallets/subtensor/src/benchmarks/helpers.rs | 52 ++++++++- pallets/subtensor/src/macros/dispatches.rs | 7 +- pallets/subtensor/src/weights.rs | 108 ++++++++++-------- 4 files changed, 126 insertions(+), 61 deletions(-) diff --git a/pallets/subtensor/src/benchmarks/benchmarks.rs b/pallets/subtensor/src/benchmarks/benchmarks.rs index e869014ecb..e2c9bb7e72 100644 --- a/pallets/subtensor/src/benchmarks/benchmarks.rs +++ b/pallets/subtensor/src/benchmarks/benchmarks.rs @@ -308,9 +308,15 @@ mod pallet_benchmarks { _(RawOrigin::Signed(coldkey.clone()), hotkey.clone()); } - /// The other outcome of `do_register_network`: at `SubnetLimit` the call prunes a subnet and - /// queues rather than creating one. Not an extrinsic; it exists so the two dispatches that can - /// reach this branch can charge the worst of the two. + /// The queueing outcome of `do_register_network`: at `SubnetLimit` the call prunes a subnet and + /// queues rather than creating one. Not an extrinsic; it exists so the dispatches that can reach + /// this branch have a worst case to charge. + /// + /// This also covers the third outcome, `wait_to_cleanup`. That path reaches the same queueing + /// block without running `get_network_to_prune` or `do_dissolve_network`, so at equal queue + /// depth it is strictly cheaper than this one. Queue depth itself is measured at neither: both + /// queues are decoded unconditionally on every call and neither is a `BoundedVec`, so there is + /// no maximum to benchmark against. #[benchmark] fn register_network_pruning() { let seed: u32 = 1; @@ -326,12 +332,12 @@ mod pallet_benchmarks { #[block] { - let _ = Subtensor::::do_register_network( + assert_ok!(Subtensor::::do_register_network( RawOrigin::Signed(coldkey.clone()).into(), &hotkey, 1, - None, - ); + Some(max_subnet_identity()), + )); } assert!(!NetworkRegistrationQueue::::get().is_empty()); @@ -1481,7 +1487,7 @@ mod pallet_benchmarks { fn register_network_with_identity() { let coldkey: T::AccountId = whitelisted_caller(); let hotkey: T::AccountId = account("Alice", 0, 1); - let identity: Option = None; + let identity: Option = Some(max_subnet_identity()); Subtensor::::set_network_registration_allowed(1.into(), true); Subtensor::::set_network_rate_limit(1); diff --git a/pallets/subtensor/src/benchmarks/helpers.rs b/pallets/subtensor/src/benchmarks/helpers.rs index 3abc6730dd..98f52fa43f 100644 --- a/pallets/subtensor/src/benchmarks/helpers.rs +++ b/pallets/subtensor/src/benchmarks/helpers.rs @@ -15,25 +15,71 @@ pub(super) fn set_reserves( SubnetAlphaIn::::insert(netuid, alpha_in); } +/// The largest identity `is_valid_subnet_identity` accepts: 6,656 bytes across the eight fields. +/// +/// Both registration outcomes carry the identity. Creation writes it to `SubnetIdentitiesV3`; +/// queueing encodes it into the `NetworkRegistrationQueue` entry and again into the event. `None` +/// measures neither. +pub(super) fn max_subnet_identity() -> SubnetIdentityOfV3 { + SubnetIdentityOfV3 { + subnet_name: vec![b'n'; 256], + github_repo: vec![b'g'; 1024], + subnet_contact: vec![b'c'; 1024], + subnet_url: vec![b'u'; 1024], + discord: vec![b'd'; 256], + description: vec![b'e'; 1024], + logo_url: vec![b'l'; 1024], + additional: vec![b'a'; 1024], + } +} + /// Fill the chain with prunable subnets so a registration benchmark runs against a realistic /// `NetworksAdded` map rather than an empty one. /// /// `do_register_network` counts every entry in `NetworksAdded` on every call, and once that count /// reaches `SubnetLimit` it also walks `get_network_to_prune`. Registering into an empty chain -/// measures neither. The two outcomes are mutually exclusive and neither dominates the other: -/// below the limit the call creates a subnet (many writes), at the limit it prunes and queues -/// instead (far more reads). Callers pick which one they are measuring via `subnets`. +/// measures neither. Callers pick which outcome they are measuring via `subnets`: below the limit +/// the call creates a subnet (many writes), at the limit it prunes and queues instead (far more +/// reads). Neither dominates the other. /// /// Immunity is set to one block and `NetworkRegisteredAt` to zero so no candidate is skipped. /// Requires a current block above zero. +/// +/// Every subnet is made dynamic with a funded pool, and both prices are staggered per subnet. +/// +/// Two independent scans walk `NetworksAdded`, and a fixture of stable, empty-pool subnets makes +/// both of them exit early on every entry: +/// +/// - `get_network_to_prune` calls `get_moving_alpha_price`, which returns on `SubnetMechanism == 0` +/// without reading `SubnetMovingPrice`. +/// - `get_median_subnet_alpha_price` calls swap `current_price`, which returns on a non-dynamic +/// mechanism, and on a dynamic one still returns before reading the TAO reserve or the balancer +/// unless the alpha reserve is nonzero. +/// +/// So the scans would walk 128 entries while pricing none, which is the same class of mistake as +/// benchmarking against an empty chain. Staggering matters as well as seeding: the median builds a +/// `BTreeMap` keyed on price, and identical reserves collapse it to a single entry. pub(super) fn fill_subnets(owner: &T::AccountId, subnets: u16) { NetworkImmunityPeriod::::set(1); for netuid in 1..=subnets { + let offset = u64::from(netuid); let netuid = NetUid::from(netuid); + Subtensor::::init_new_network(netuid, 1); NetworkRegisteredAt::::insert(netuid, 0); SubnetOwner::::insert(netuid, owner.clone()); + SubnetMechanism::::insert(netuid, 1); + set_reserves::( + netuid, + TaoBalance::from(150_000_000_000_u64.saturating_add(offset.saturating_mul(1_000_000))), + AlphaBalance::from(100_000_000_000_u64), + ); + SubnetMovingPrice::::insert( + netuid, + I96F32::saturating_from_num(1_000_u64.saturating_add(offset)) + .saturating_div(I96F32::saturating_from_num(1_000)), + ); } } diff --git a/pallets/subtensor/src/macros/dispatches.rs b/pallets/subtensor/src/macros/dispatches.rs index a809553b7b..da88a346b9 100644 --- a/pallets/subtensor/src/macros/dispatches.rs +++ b/pallets/subtensor/src/macros/dispatches.rs @@ -1002,8 +1002,9 @@ mod dispatches { /// User register a new subnetwork /// - /// Below `SubnetLimit` this creates a subnet; at the limit it prunes one and queues - /// instead. The two are mutually exclusive and neither dominates, so charge the worse. + /// Below `SubnetLimit` this creates a subnet; at the limit it either prunes one and queues, + /// or queues to wait on a cleanup already in flight. The first two are mutually exclusive + /// and neither dominates, so charge the worse; the third is dominated by the second. #[pallet::call_index(59)] #[pallet::weight(::WeightInfo::register_network() .max(::WeightInfo::register_network_pruning()))] @@ -1186,7 +1187,7 @@ mod dispatches { /// User register a new subnetwork /// - /// Same two outcomes as `register_network`, so the same worst case applies. + /// Same outcomes as `register_network`, so the same worst case applies. #[pallet::call_index(79)] #[pallet::weight(::WeightInfo::register_network_with_identity() .max(::WeightInfo::register_network_pruning()))] diff --git a/pallets/subtensor/src/weights.rs b/pallets/subtensor/src/weights.rs index 5e74840483..6f7658973a 100644 --- a/pallets/subtensor/src/weights.rs +++ b/pallets/subtensor/src/weights.rs @@ -623,11 +623,11 @@ impl WeightInfo for SubstrateWeight { /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(104), added: 2579, mode: `MaxEncodedLen`) /// Storage: `SubtensorModule::SubnetMechanism` (r:127 w:1) /// Proof: `SubtensorModule::SubnetMechanism` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `SubtensorModule::SubnetAlphaIn` (r:1 w:1) + /// Storage: `SubtensorModule::SubnetAlphaIn` (r:127 w:1) /// Proof: `SubtensorModule::SubnetAlphaIn` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `SubtensorModule::SubnetTAO` (r:1 w:1) + /// Storage: `SubtensorModule::SubnetTAO` (r:127 w:1) /// Proof: `SubtensorModule::SubnetTAO` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Swap::SwapBalancer` (r:1 w:0) + /// Storage: `Swap::SwapBalancer` (r:127 w:0) /// Proof: `Swap::SwapBalancer` (`max_values`: None, `max_size`: Some(18), added: 2493, mode: `MaxEncodedLen`) /// Storage: `SubtensorModule::TotalNetworks` (r:1 w:1) /// Proof: `SubtensorModule::TotalNetworks` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) @@ -713,11 +713,11 @@ impl WeightInfo for SubstrateWeight { /// Proof: `SubtensorModule::MaxAllowedUids` (`max_values`: None, `max_size`: None, mode: `Measured`) fn register_network() -> Weight { // Proof Size summary in bytes: - // Measured: `3721` - // Estimated: `323986` - // Minimum execution time: 2_130_304_000 picoseconds. - Weight::from_parts(2_160_771_000, 323986) - .saturating_add(T::DbWeight::get().reads(293_u64)) + // Measured: `7696` + // Estimated: `327961` + // Minimum execution time: 3_401_152_000 picoseconds. + Weight::from_parts(3_505_837_000, 327961) + .saturating_add(T::DbWeight::get().reads(671_u64)) .saturating_add(T::DbWeight::get().writes(49_u64)) } /// Storage: `SubtensorModule::Owner` (r:1 w:0) @@ -742,7 +742,7 @@ impl WeightInfo for SubstrateWeight { /// Proof: `SubtensorModule::NetworkImmunityPeriod` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::SubnetMechanism` (r:128 w:0) /// Proof: `SubtensorModule::SubnetMechanism` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `SubtensorModule::SubnetMovingPrice` (r:1 w:0) + /// Storage: `SubtensorModule::SubnetMovingPrice` (r:128 w:0) /// Proof: `SubtensorModule::SubnetMovingPrice` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::NetworkLastLockCost` (r:1 w:0) /// Proof: `SubtensorModule::NetworkLastLockCost` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) @@ -762,7 +762,7 @@ impl WeightInfo for SubstrateWeight { /// Proof: `SubtensorModule::TotalNetworks` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::TotalStake` (r:1 w:1) /// Proof: `SubtensorModule::TotalStake` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `SubtensorModule::SubnetTAO` (r:1 w:0) + /// Storage: `SubtensorModule::SubnetTAO` (r:128 w:0) /// Proof: `SubtensorModule::SubnetTAO` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::NetworkRegistrationLockId` (r:1 w:1) /// Proof: `SubtensorModule::NetworkRegistrationLockId` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) @@ -770,13 +770,17 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(899), added: 3374, mode: `MaxEncodedLen`) /// Storage: `Balances::Freezes` (r:1 w:0) /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(499), added: 2974, mode: `MaxEncodedLen`) + /// Storage: `SubtensorModule::SubnetAlphaIn` (r:127 w:0) + /// Proof: `SubtensorModule::SubnetAlphaIn` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Swap::SwapBalancer` (r:127 w:0) + /// Proof: `Swap::SwapBalancer` (`max_values`: None, `max_size`: Some(18), added: 2493, mode: `MaxEncodedLen`) fn register_network_pruning() -> Weight { // Proof Size summary in bytes: - // Measured: `3943` - // Estimated: `326683` - // Minimum execution time: 2_210_744_000 picoseconds. - Weight::from_parts(2_283_058_000, 326683) - .saturating_add(T::DbWeight::get().reads(408_u64)) + // Measured: `10544` + // Estimated: `333284` + // Minimum execution time: 4_004_051_000 picoseconds. + Weight::from_parts(4_090_472_000, 333284) + .saturating_add(T::DbWeight::get().reads(916_u64)) .saturating_add(T::DbWeight::get().writes(10_u64)) } /// Storage: `SubtensorModule::NetworksAdded` (r:1 w:0) @@ -2128,11 +2132,11 @@ impl WeightInfo for SubstrateWeight { /// Proof: `SubtensorModule::TotalIssuance` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::SubnetMechanism` (r:127 w:1) /// Proof: `SubtensorModule::SubnetMechanism` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `SubtensorModule::SubnetAlphaIn` (r:1 w:1) + /// Storage: `SubtensorModule::SubnetAlphaIn` (r:127 w:1) /// Proof: `SubtensorModule::SubnetAlphaIn` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `SubtensorModule::SubnetTAO` (r:1 w:1) + /// Storage: `SubtensorModule::SubnetTAO` (r:127 w:1) /// Proof: `SubtensorModule::SubnetTAO` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Swap::SwapBalancer` (r:1 w:0) + /// Storage: `Swap::SwapBalancer` (r:127 w:0) /// Proof: `Swap::SwapBalancer` (`max_values`: None, `max_size`: Some(18), added: 2493, mode: `MaxEncodedLen`) /// Storage: `SubtensorModule::TotalNetworks` (r:1 w:1) /// Proof: `SubtensorModule::TotalNetworks` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) @@ -2206,6 +2210,8 @@ impl WeightInfo for SubstrateWeight { /// Proof: `SubtensorModule::Uids` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::ImmunityPeriod` (r:0 w:1) /// Proof: `SubtensorModule::ImmunityPeriod` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::SubnetIdentitiesV3` (r:0 w:1) + /// Proof: `SubtensorModule::SubnetIdentitiesV3` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::SubnetEmissionEnabled` (r:0 w:1) /// Proof: `SubtensorModule::SubnetEmissionEnabled` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::NetworkRegistrationAllowed` (r:0 w:1) @@ -2220,12 +2226,12 @@ impl WeightInfo for SubstrateWeight { /// Proof: `SubtensorModule::MaxAllowedUids` (`max_values`: None, `max_size`: None, mode: `Measured`) fn register_network_with_identity() -> Weight { // Proof Size summary in bytes: - // Measured: `3657` - // Estimated: `323922` - // Minimum execution time: 2_160_801_000 picoseconds. - Weight::from_parts(2_248_876_000, 323922) - .saturating_add(T::DbWeight::get().reads(292_u64)) - .saturating_add(T::DbWeight::get().writes(48_u64)) + // Measured: `7632` + // Estimated: `327897` + // Minimum execution time: 3_420_479_000 picoseconds. + Weight::from_parts(3_487_302_000, 327897) + .saturating_add(T::DbWeight::get().reads(670_u64)) + .saturating_add(T::DbWeight::get().writes(49_u64)) } /// Storage: `SubtensorModule::NetworksAdded` (r:1 w:0) /// Proof: `SubtensorModule::NetworksAdded` (`max_values`: None, `max_size`: None, mode: `Measured`) @@ -4300,11 +4306,11 @@ impl WeightInfo for () { /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(104), added: 2579, mode: `MaxEncodedLen`) /// Storage: `SubtensorModule::SubnetMechanism` (r:127 w:1) /// Proof: `SubtensorModule::SubnetMechanism` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `SubtensorModule::SubnetAlphaIn` (r:1 w:1) + /// Storage: `SubtensorModule::SubnetAlphaIn` (r:127 w:1) /// Proof: `SubtensorModule::SubnetAlphaIn` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `SubtensorModule::SubnetTAO` (r:1 w:1) + /// Storage: `SubtensorModule::SubnetTAO` (r:127 w:1) /// Proof: `SubtensorModule::SubnetTAO` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Swap::SwapBalancer` (r:1 w:0) + /// Storage: `Swap::SwapBalancer` (r:127 w:0) /// Proof: `Swap::SwapBalancer` (`max_values`: None, `max_size`: Some(18), added: 2493, mode: `MaxEncodedLen`) /// Storage: `SubtensorModule::TotalNetworks` (r:1 w:1) /// Proof: `SubtensorModule::TotalNetworks` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) @@ -4390,11 +4396,11 @@ impl WeightInfo for () { /// Proof: `SubtensorModule::MaxAllowedUids` (`max_values`: None, `max_size`: None, mode: `Measured`) fn register_network() -> Weight { // Proof Size summary in bytes: - // Measured: `3721` - // Estimated: `323986` - // Minimum execution time: 2_130_304_000 picoseconds. - Weight::from_parts(2_160_771_000, 323986) - .saturating_add(RocksDbWeight::get().reads(293_u64)) + // Measured: `7696` + // Estimated: `327961` + // Minimum execution time: 3_401_152_000 picoseconds. + Weight::from_parts(3_505_837_000, 327961) + .saturating_add(RocksDbWeight::get().reads(671_u64)) .saturating_add(RocksDbWeight::get().writes(49_u64)) } /// Storage: `SubtensorModule::Owner` (r:1 w:0) @@ -4419,7 +4425,7 @@ impl WeightInfo for () { /// Proof: `SubtensorModule::NetworkImmunityPeriod` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::SubnetMechanism` (r:128 w:0) /// Proof: `SubtensorModule::SubnetMechanism` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `SubtensorModule::SubnetMovingPrice` (r:1 w:0) + /// Storage: `SubtensorModule::SubnetMovingPrice` (r:128 w:0) /// Proof: `SubtensorModule::SubnetMovingPrice` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::NetworkLastLockCost` (r:1 w:0) /// Proof: `SubtensorModule::NetworkLastLockCost` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) @@ -4439,7 +4445,7 @@ impl WeightInfo for () { /// Proof: `SubtensorModule::TotalNetworks` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::TotalStake` (r:1 w:1) /// Proof: `SubtensorModule::TotalStake` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `SubtensorModule::SubnetTAO` (r:1 w:0) + /// Storage: `SubtensorModule::SubnetTAO` (r:128 w:0) /// Proof: `SubtensorModule::SubnetTAO` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::NetworkRegistrationLockId` (r:1 w:1) /// Proof: `SubtensorModule::NetworkRegistrationLockId` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) @@ -4447,13 +4453,17 @@ impl WeightInfo for () { /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(899), added: 3374, mode: `MaxEncodedLen`) /// Storage: `Balances::Freezes` (r:1 w:0) /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(499), added: 2974, mode: `MaxEncodedLen`) + /// Storage: `SubtensorModule::SubnetAlphaIn` (r:127 w:0) + /// Proof: `SubtensorModule::SubnetAlphaIn` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Swap::SwapBalancer` (r:127 w:0) + /// Proof: `Swap::SwapBalancer` (`max_values`: None, `max_size`: Some(18), added: 2493, mode: `MaxEncodedLen`) fn register_network_pruning() -> Weight { // Proof Size summary in bytes: - // Measured: `3943` - // Estimated: `326683` - // Minimum execution time: 2_210_744_000 picoseconds. - Weight::from_parts(2_283_058_000, 326683) - .saturating_add(RocksDbWeight::get().reads(408_u64)) + // Measured: `10544` + // Estimated: `333284` + // Minimum execution time: 4_004_051_000 picoseconds. + Weight::from_parts(4_090_472_000, 333284) + .saturating_add(RocksDbWeight::get().reads(916_u64)) .saturating_add(RocksDbWeight::get().writes(10_u64)) } /// Storage: `SubtensorModule::NetworksAdded` (r:1 w:0) @@ -5805,11 +5815,11 @@ impl WeightInfo for () { /// Proof: `SubtensorModule::TotalIssuance` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::SubnetMechanism` (r:127 w:1) /// Proof: `SubtensorModule::SubnetMechanism` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `SubtensorModule::SubnetAlphaIn` (r:1 w:1) + /// Storage: `SubtensorModule::SubnetAlphaIn` (r:127 w:1) /// Proof: `SubtensorModule::SubnetAlphaIn` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `SubtensorModule::SubnetTAO` (r:1 w:1) + /// Storage: `SubtensorModule::SubnetTAO` (r:127 w:1) /// Proof: `SubtensorModule::SubnetTAO` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Swap::SwapBalancer` (r:1 w:0) + /// Storage: `Swap::SwapBalancer` (r:127 w:0) /// Proof: `Swap::SwapBalancer` (`max_values`: None, `max_size`: Some(18), added: 2493, mode: `MaxEncodedLen`) /// Storage: `SubtensorModule::TotalNetworks` (r:1 w:1) /// Proof: `SubtensorModule::TotalNetworks` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) @@ -5883,6 +5893,8 @@ impl WeightInfo for () { /// Proof: `SubtensorModule::Uids` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::ImmunityPeriod` (r:0 w:1) /// Proof: `SubtensorModule::ImmunityPeriod` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `SubtensorModule::SubnetIdentitiesV3` (r:0 w:1) + /// Proof: `SubtensorModule::SubnetIdentitiesV3` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::SubnetEmissionEnabled` (r:0 w:1) /// Proof: `SubtensorModule::SubnetEmissionEnabled` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `SubtensorModule::NetworkRegistrationAllowed` (r:0 w:1) @@ -5897,12 +5909,12 @@ impl WeightInfo for () { /// Proof: `SubtensorModule::MaxAllowedUids` (`max_values`: None, `max_size`: None, mode: `Measured`) fn register_network_with_identity() -> Weight { // Proof Size summary in bytes: - // Measured: `3657` - // Estimated: `323922` - // Minimum execution time: 2_160_801_000 picoseconds. - Weight::from_parts(2_248_876_000, 323922) - .saturating_add(RocksDbWeight::get().reads(292_u64)) - .saturating_add(RocksDbWeight::get().writes(48_u64)) + // Measured: `7632` + // Estimated: `327897` + // Minimum execution time: 3_420_479_000 picoseconds. + Weight::from_parts(3_487_302_000, 327897) + .saturating_add(RocksDbWeight::get().reads(670_u64)) + .saturating_add(RocksDbWeight::get().writes(49_u64)) } /// Storage: `SubtensorModule::NetworksAdded` (r:1 w:0) /// Proof: `SubtensorModule::NetworksAdded` (`max_values`: None, `max_size`: None, mode: `Measured`) From bd4583f0cfea81300a3a0c7f778b3f64deee18a2 Mon Sep 17 00:00:00 2001 From: Philip Maymin Date: Fri, 31 Jul 2026 01:51:55 +0200 Subject: [PATCH 3/3] runtime: bump spec_version for the corrected register_network weights The weight constants in pallets/subtensor live in the runtime wasm, so the corrected register_network measurement only reaches a chain through a runtime release. Mainnet is on 440. --- runtime/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 95eaca16ee..521906bb58 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -235,7 +235,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // `spec_version`, and `authoring_version` are the same between Wasm and native. // This value is set to 100 to notify Polkadot-JS App (https://polkadot.js.org/apps) to use // the compatible custom types. - spec_version: 440, + spec_version: 441, impl_version: 1, apis: RUNTIME_API_VERSIONS, transaction_version: 1,