diff --git a/.github/workflows/run-benchmarks.yml b/.github/workflows/run-benchmarks.yml new file mode 100644 index 0000000000..71f69fcd75 --- /dev/null +++ b/.github/workflows/run-benchmarks.yml @@ -0,0 +1,46 @@ +# .github/workflows/benchmarks.yml +name: Validate-Benchmarks + +on: + pull_request: + workflow_dispatch: + +concurrency: + group: run-benchmarks-${{ github.ref }} + cancel-in-progress: true + +jobs: + validate-benchmarks: + if: ${{ !contains(github.event.pull_request.labels.*.name, 'skip-validate-benchmarks') }} + runs-on: SubtensorCI + steps: + - name: Checkout PR branch + uses: actions/checkout@v4 + with: + ref: ${{ github.head_ref }} + fetch-depth: 0 + + - name: Install system dependencies + run: | + sudo apt-get update + sudo apt-get install -y clang curl libssl-dev llvm libudev-dev protobuf-compiler + + - name: Install Rust toolchain + uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: stable + + - name: Cache Rust build + uses: Swatinem/rust-cache@v2 + with: + key: bench-${{ hashFiles('**/Cargo.lock') }} + + - name: Build node with benchmarks + run: | + cargo build --profile production -p node-subtensor --features runtime-benchmarks + + - name: Run & validate benchmarks + run: | + chmod +x scripts/benchmark_action.sh + ./scripts/benchmark_action.sh diff --git a/pallets/subtensor/src/benchmarks.rs b/pallets/subtensor/src/benchmarks.rs index 7433176398..b5ff1197e0 100644 --- a/pallets/subtensor/src/benchmarks.rs +++ b/pallets/subtensor/src/benchmarks.rs @@ -145,7 +145,7 @@ benchmarks! { let seed : u32 = 1; Subtensor::::init_new_network(netuid, tempo); - + SubtokenEnabled::::insert(netuid, true); Subtensor::::set_burn(netuid, 1); Subtensor::::set_network_registration_allowed( netuid, true ); @@ -175,6 +175,7 @@ benchmarks! { Subtensor::::init_new_network(netuid, tempo); Subtensor::::set_network_registration_allowed( netuid, true ); + SubtokenEnabled::::insert(netuid, true); Subtensor::::set_max_allowed_uids( netuid, 4096 ); assert_eq!(Subtensor::::get_max_allowed_uids(netuid), 4096); @@ -216,6 +217,7 @@ benchmarks! { Subtensor::::init_new_network(netuid, tempo); Subtensor::::set_network_registration_allowed( netuid, true ); + SubtokenEnabled::::insert(netuid, true); Subtensor::::set_max_allowed_uids( netuid, 4096 ); assert_eq!(Subtensor::::get_max_allowed_uids(netuid), 4096); @@ -247,6 +249,7 @@ benchmarks! { let seed : u32 = 1; Subtensor::::init_new_network(netuid, tempo); + SubtokenEnabled::::insert(netuid, true); Subtensor::::set_burn(netuid, 1); Subtensor::::set_network_registration_allowed( netuid, true ); Subtensor::::set_max_allowed_uids( netuid, 4096 ); diff --git a/pallets/subtensor/src/macros/dispatches.rs b/pallets/subtensor/src/macros/dispatches.rs index 30041e037f..de22d64c88 100644 --- a/pallets/subtensor/src/macros/dispatches.rs +++ b/pallets/subtensor/src/macros/dispatches.rs @@ -77,8 +77,8 @@ mod dispatches { /// * 'MaxWeightExceeded': /// - Attempting to set weights with max value exceeding limit. #[pallet::call_index(0)] - #[pallet::weight((Weight::from_parts(22_060_000_000, 0) - .saturating_add(T::DbWeight::get().reads(4106)) + #[pallet::weight((Weight::from_parts(20_730_000_000, 0) + .saturating_add(T::DbWeight::get().reads(4111)) .saturating_add(T::DbWeight::get().writes(2)), DispatchClass::Normal, Pays::No))] pub fn set_weights( origin: OriginFor, @@ -120,8 +120,8 @@ mod dispatches { /// - On failure for each failed item in the batch. /// #[pallet::call_index(80)] - #[pallet::weight((Weight::from_parts(22_060_000_000, 0) - .saturating_add(T::DbWeight::get().reads(4106)) + #[pallet::weight((Weight::from_parts(105_100_000, 0) + .saturating_add(T::DbWeight::get().reads(14)) .saturating_add(T::DbWeight::get().writes(2)), DispatchClass::Normal, Pays::No))] pub fn batch_set_weights( origin: OriginFor, @@ -186,8 +186,8 @@ mod dispatches { /// - On failure for each failed item in the batch. /// #[pallet::call_index(100)] - #[pallet::weight((Weight::from_parts(46_000_000, 0) - .saturating_add(T::DbWeight::get().reads(1)) + #[pallet::weight((Weight::from_parts(89_380_000, 0) + .saturating_add(T::DbWeight::get().reads(8)) .saturating_add(T::DbWeight::get().writes(2)), DispatchClass::Normal, Pays::No))] pub fn batch_commit_weights( origin: OriginFor, @@ -279,9 +279,9 @@ mod dispatches { /// - Attempting to commit when the user has more than the allowed limit of unrevealed commits. /// #[pallet::call_index(99)] - #[pallet::weight((Weight::from_parts(46_000_000, 0) - .saturating_add(T::DbWeight::get().reads(1)) - .saturating_add(T::DbWeight::get().writes(1)), DispatchClass::Normal, Pays::No))] + #[pallet::weight((Weight::from_parts(73_720_000, 0) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(2)), DispatchClass::Normal, Pays::No))] pub fn commit_crv3_weights( origin: T::RuntimeOrigin, netuid: u16, @@ -413,9 +413,9 @@ mod dispatches { /// - Attempting to set weights with max value exceeding limit. /// #[pallet::call_index(8)] - #[pallet::weight((Weight::from_parts(10_151_000_000, 0) - .saturating_add(T::DbWeight::get().reads(4104)) - .saturating_add(T::DbWeight::get().writes(2)), DispatchClass::Normal, Pays::No))] + #[pallet::weight((Weight::from_parts(4_068_000, 0) + .saturating_add(T::DbWeight::get().reads(0)) + .saturating_add(T::DbWeight::get().writes(0)), DispatchClass::Normal, Pays::No))] pub fn set_tao_weights( _origin: OriginFor, _netuid: u16, @@ -454,9 +454,9 @@ mod dispatches { /// - The hotkey we are delegating is not owned by the calling coldket. /// #[pallet::call_index(1)] - #[pallet::weight((Weight::from_parts(79_000_000, 0) - .saturating_add(T::DbWeight::get().reads(6)) - .saturating_add(T::DbWeight::get().writes(3)), DispatchClass::Normal, Pays::No))] + #[pallet::weight((Weight::from_parts(4_428_000, 0) + .saturating_add(T::DbWeight::get().reads(0)) + .saturating_add(T::DbWeight::get().writes(0)), DispatchClass::Normal, Pays::No))] pub fn become_delegate(_origin: OriginFor, _hotkey: T::AccountId) -> DispatchResult { // DEPRECATED // Self::do_become_delegate(origin, hotkey, Self::get_default_delegate_take()) @@ -498,7 +498,9 @@ mod dispatches { /// - The delegate is setting a take which is not lower than the previous. /// #[pallet::call_index(65)] - #[pallet::weight((0, DispatchClass::Normal, Pays::No))] + #[pallet::weight((Weight::from_parts(37_380_000, 0) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(2)), DispatchClass::Normal, Pays::No))] pub fn decrease_take( origin: OriginFor, hotkey: T::AccountId, @@ -538,7 +540,9 @@ mod dispatches { /// - The delegate is setting a take which is not greater than the previous. /// #[pallet::call_index(66)] - #[pallet::weight((0, DispatchClass::Normal, Pays::No))] + #[pallet::weight((Weight::from_parts(44_630_000, 0) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(2)), DispatchClass::Normal, Pays::No))] pub fn increase_take( origin: OriginFor, hotkey: T::AccountId, @@ -581,9 +585,9 @@ mod dispatches { /// - Errors stemming from transaction pallet. /// #[pallet::call_index(2)] - #[pallet::weight((Weight::from_parts(124_000_000, 0) - .saturating_add(T::DbWeight::get().reads(10)) - .saturating_add(T::DbWeight::get().writes(7)), DispatchClass::Normal, Pays::No))] + #[pallet::weight((Weight::from_parts(151_000_000, 0) + .saturating_add(T::DbWeight::get().reads(14)) + .saturating_add(T::DbWeight::get().writes(10)), DispatchClass::Normal, Pays::No))] pub fn add_stake( origin: OriginFor, hotkey: T::AccountId, @@ -625,10 +629,9 @@ mod dispatches { /// - Thrown if there is not enough stake on the hotkey to withdwraw this amount. /// #[pallet::call_index(3)] - #[pallet::weight((Weight::from_parts(111_000_000, 0) - .saturating_add(Weight::from_parts(0, 43991)) - .saturating_add(T::DbWeight::get().reads(10)) - .saturating_add(T::DbWeight::get().writes(7)), DispatchClass::Normal, Pays::No))] + #[pallet::weight((Weight::from_parts(196_800_000, 0) + .saturating_add(T::DbWeight::get().reads(19)) + .saturating_add(T::DbWeight::get().writes(10)), DispatchClass::Normal, Pays::No))] pub fn remove_stake( origin: OriginFor, hotkey: T::AccountId, @@ -690,7 +693,7 @@ mod dispatches { /// - Attempting to set prometheus information withing the rate limit min. /// #[pallet::call_index(4)] - #[pallet::weight((Weight::from_parts(46_000_000, 0) + #[pallet::weight((Weight::from_parts(35_670_000, 0) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(1)), DispatchClass::Normal, Pays::No))] pub fn serve_axon( @@ -774,7 +777,7 @@ mod dispatches { /// - Attempting to set prometheus information withing the rate limit min. /// #[pallet::call_index(40)] - #[pallet::weight((Weight::from_parts(46_000_000, 0) + #[pallet::weight((Weight::from_parts(33_890_000, 0) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(1)), DispatchClass::Normal, Pays::No))] pub fn serve_axon_tls( @@ -824,7 +827,7 @@ mod dispatches { /// - The ip type v4 or v6. /// #[pallet::call_index(5)] - #[pallet::weight((Weight::from_parts(45_000_000, 0) + #[pallet::weight((Weight::from_parts(31_170_000, 0) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(1)), DispatchClass::Normal, Pays::No))] pub fn serve_prometheus( @@ -887,8 +890,8 @@ mod dispatches { /// #[pallet::call_index(6)] #[pallet::weight((Weight::from_parts(192_000_000, 0) - .saturating_add(T::DbWeight::get().reads(24)) - .saturating_add(T::DbWeight::get().writes(22)), DispatchClass::Normal, Pays::No))] + .saturating_add(T::DbWeight::get().reads(26)) + .saturating_add(T::DbWeight::get().writes(23)), DispatchClass::Normal, Pays::No))] pub fn register( origin: OriginFor, netuid: u16, @@ -903,7 +906,7 @@ mod dispatches { /// Register the hotkey to root network #[pallet::call_index(62)] - #[pallet::weight((Weight::from_parts(164_000_000, 0) + #[pallet::weight((Weight::from_parts(145_500_000, 0) .saturating_add(T::DbWeight::get().reads(23)) .saturating_add(T::DbWeight::get().writes(20)), DispatchClass::Normal, Pays::No))] pub fn root_register(origin: OriginFor, hotkey: T::AccountId) -> DispatchResult { @@ -912,18 +915,18 @@ mod dispatches { /// Attempt to adjust the senate membership to include a hotkey #[pallet::call_index(63)] - #[pallet::weight((Weight::from_parts(0, 0) - .saturating_add(T::DbWeight::get().reads(0)) - .saturating_add(T::DbWeight::get().writes(0)), DispatchClass::Normal, Pays::Yes))] + #[pallet::weight((Weight::from_parts(68_100_000, 0) + .saturating_add(T::DbWeight::get().reads(7)) + .saturating_add(T::DbWeight::get().writes(4)), DispatchClass::Normal, Pays::Yes))] pub fn adjust_senate(origin: OriginFor, hotkey: T::AccountId) -> DispatchResult { Self::do_adjust_senate(origin, hotkey) } /// User register a new subnetwork via burning token #[pallet::call_index(7)] - #[pallet::weight((Weight::from_parts(177_000_000, 0) - .saturating_add(T::DbWeight::get().reads(26)) - .saturating_add(T::DbWeight::get().writes(24)), DispatchClass::Normal, Pays::No))] + #[pallet::weight((Weight::from_parts(219_400_000, 0) + .saturating_add(T::DbWeight::get().reads(34)) + .saturating_add(T::DbWeight::get().writes(29)), DispatchClass::Normal, Pays::No))] pub fn burned_register( origin: OriginFor, netuid: u16, @@ -934,9 +937,9 @@ mod dispatches { /// The extrinsic for user to change its hotkey #[pallet::call_index(70)] - #[pallet::weight((Weight::from_parts(1_940_000_000, 0) - .saturating_add(T::DbWeight::get().reads(272)) - .saturating_add(T::DbWeight::get().writes(527)), DispatchClass::Operational, Pays::No))] + #[pallet::weight((Weight::from_parts(240_600_000, 0) + .saturating_add(T::DbWeight::get().reads(31)) + .saturating_add(T::DbWeight::get().writes(23)), DispatchClass::Operational, Pays::No))] pub fn swap_hotkey( origin: OriginFor, hotkey: T::AccountId, @@ -962,7 +965,7 @@ mod dispatches { /// Weight is calculated based on the number of database reads and writes. #[pallet::call_index(71)] #[pallet::weight((Weight::from_parts(127_713_000, 0) - .saturating_add(Weight::from_parts(0, 11645)) + .saturating_add(Weight::from_parts(111_100_000, 11645)) .saturating_add(T::DbWeight::get().reads(18)) .saturating_add(T::DbWeight::get().writes(12)), DispatchClass::Operational, Pays::No))] pub fn swap_coldkey( @@ -1009,7 +1012,7 @@ mod dispatches { /// #[pallet::call_index(75)] #[pallet::weight(( - Weight::from_parts(34_000, 0) + Weight::from_parts(49_470_000, 0) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(2)), DispatchClass::Normal, @@ -1042,7 +1045,8 @@ mod dispatches { /// #[pallet::call_index(69)] #[pallet::weight(( - Weight::from_parts(6_000, 0) + Weight::from_parts(6_873_000, 0) + .saturating_add(T::DbWeight::get().reads(0)) .saturating_add(T::DbWeight::get().writes(1)), DispatchClass::Operational, Pays::No @@ -1070,6 +1074,7 @@ mod dispatches { #[pallet::call_index(76)] #[pallet::weight(( Weight::from_parts(6_000, 0) + .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)), DispatchClass::Operational, Pays::No @@ -1094,6 +1099,7 @@ mod dispatches { #[pallet::call_index(77)] #[pallet::weight(( Weight::from_parts(6_000, 0) + .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)), DispatchClass::Operational, Pays::No @@ -1125,7 +1131,7 @@ mod dispatches { /// ## Complexity /// - O(1). #[pallet::call_index(51)] - #[pallet::weight((Weight::from_parts(0, 0), DispatchClass::Operational, Pays::No))] + #[pallet::weight((Weight::from_parts(111_100_000, 0), DispatchClass::Operational, Pays::No))] pub fn sudo( origin: OriginFor, call: Box, @@ -1172,8 +1178,7 @@ mod dispatches { /// User vote on a proposal #[pallet::call_index(55)] - #[pallet::weight((Weight::from_parts(0, 0) - .saturating_add(Weight::from_parts(0, 0)) + #[pallet::weight((Weight::from_parts(111_100_000, 0) .saturating_add(T::DbWeight::get().reads(0)) .saturating_add(T::DbWeight::get().writes(0)), DispatchClass::Operational))] pub fn vote( @@ -1188,9 +1193,9 @@ mod dispatches { /// User register a new subnetwork #[pallet::call_index(59)] - #[pallet::weight((Weight::from_parts(157_000_000, 0) - .saturating_add(T::DbWeight::get().reads(16)) - .saturating_add(T::DbWeight::get().writes(30)), DispatchClass::Operational, Pays::No))] + #[pallet::weight((Weight::from_parts(260_500_000, 0) + .saturating_add(T::DbWeight::get().reads(33)) + .saturating_add(T::DbWeight::get().writes(52)), DispatchClass::Operational, Pays::No))] pub fn register_network(origin: OriginFor, hotkey: T::AccountId) -> DispatchResult { Self::do_register_network(origin, &hotkey, 1, None) } @@ -1455,8 +1460,8 @@ mod dispatches { /// - The ip type v4 or v6. /// #[pallet::call_index(68)] - #[pallet::weight((Weight::from_parts(45_000_000, 0) - .saturating_add(T::DbWeight::get().reads(4)) + #[pallet::weight((Weight::from_parts(32_340_000, 0) + .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)), DispatchClass::Normal, Pays::Yes))] pub fn set_identity( origin: OriginFor, @@ -1497,8 +1502,8 @@ mod dispatches { /// * `subnet_contact` (Vec): /// - The contact information for the subnet. #[pallet::call_index(78)] - #[pallet::weight((Weight::from_parts(45_000_000, 0) - .saturating_add(T::DbWeight::get().reads(4)) + #[pallet::weight((Weight::from_parts(23_080_000, 0) + .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)), DispatchClass::Normal, Pays::Yes))] pub fn set_subnet_identity( origin: OriginFor, @@ -1526,9 +1531,9 @@ mod dispatches { /// User register a new subnetwork #[pallet::call_index(79)] - #[pallet::weight((Weight::from_parts(157_000_000, 0) - .saturating_add(T::DbWeight::get().reads(16)) - .saturating_add(T::DbWeight::get().writes(30)), DispatchClass::Operational, Pays::No))] + #[pallet::weight((Weight::from_parts(239_700_000, 0) + .saturating_add(T::DbWeight::get().reads(32)) + .saturating_add(T::DbWeight::get().writes(51)), DispatchClass::Operational, Pays::No))] pub fn register_network_with_identity( origin: OriginFor, hotkey: T::AccountId, @@ -1563,7 +1568,9 @@ mod dispatches { /// * `TxRateLimitExceeded`: /// - Thrown if key has hit transaction rate limit #[pallet::call_index(83)] - #[pallet::weight((Weight::from_parts(3_000_000, 0).saturating_add(T::DbWeight::get().writes(1)), DispatchClass::Operational, Pays::No))] + #[pallet::weight((Weight::from_parts(36_200_000, 0) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(0)), DispatchClass::Operational, Pays::No))] pub fn unstake_all(origin: OriginFor, hotkey: T::AccountId) -> DispatchResult { Self::do_unstake_all(origin, hotkey) } @@ -1594,7 +1601,9 @@ mod dispatches { /// * `TxRateLimitExceeded`: /// - Thrown if key has hit transaction rate limit #[pallet::call_index(84)] - #[pallet::weight((Weight::from_parts(3_000_000, 0).saturating_add(T::DbWeight::get().writes(1)), DispatchClass::Operational, Pays::No))] + #[pallet::weight((Weight::from_parts(68_730_000, 0) + .saturating_add(T::DbWeight::get().reads(12)) + .saturating_add(T::DbWeight::get().writes(6)), DispatchClass::Operational, Pays::No))] pub fn unstake_all_alpha(origin: OriginFor, hotkey: T::AccountId) -> DispatchResult { Self::do_unstake_all_alpha(origin, hotkey) } @@ -1621,7 +1630,9 @@ mod dispatches { /// - The alpha stake amount to move. /// #[pallet::call_index(85)] - #[pallet::weight((Weight::from_parts(3_000_000, 0).saturating_add(T::DbWeight::get().writes(1)), DispatchClass::Operational, Pays::No))] + #[pallet::weight((Weight::from_parts(196_600_000, 0) + .saturating_add(T::DbWeight::get().reads(17)) + .saturating_add(T::DbWeight::get().writes(13)), DispatchClass::Operational, Pays::No))] pub fn move_stake( origin: T::RuntimeOrigin, origin_hotkey: T::AccountId, @@ -1662,7 +1673,9 @@ mod dispatches { /// # Events /// May emit a `StakeTransferred` event on success. #[pallet::call_index(86)] - #[pallet::weight((Weight::from_parts(3_000_000, 0).saturating_add(T::DbWeight::get().writes(1)), DispatchClass::Operational, Pays::No))] + #[pallet::weight((Weight::from_parts(207_300_000, 0) + .saturating_add(T::DbWeight::get().reads(16)) + .saturating_add(T::DbWeight::get().writes(13)), DispatchClass::Operational, Pays::No))] pub fn transfer_stake( origin: T::RuntimeOrigin, destination_coldkey: T::AccountId, @@ -1702,7 +1715,9 @@ mod dispatches { /// May emit a `StakeSwapped` event on success. #[pallet::call_index(87)] #[pallet::weight(( - Weight::from_parts(3_000_000, 0).saturating_add(T::DbWeight::get().writes(1)), + Weight::from_parts(190_100_000, 0) + .saturating_add(T::DbWeight::get().reads(13)) + .saturating_add(T::DbWeight::get().writes(9)), DispatchClass::Operational, Pays::No ))] @@ -1765,9 +1780,9 @@ mod dispatches { /// - Errors stemming from transaction pallet. /// #[pallet::call_index(88)] - #[pallet::weight((Weight::from_parts(124_000_000, 0) + #[pallet::weight((Weight::from_parts(91_010_000, 0) .saturating_add(T::DbWeight::get().reads(10)) - .saturating_add(T::DbWeight::get().writes(7)), DispatchClass::Normal, Pays::No))] + .saturating_add(T::DbWeight::get().writes(6)), DispatchClass::Normal, Pays::No))] pub fn add_stake_limit( origin: OriginFor, hotkey: T::AccountId, @@ -1829,10 +1844,9 @@ mod dispatches { /// - Thrown if there is not enough stake on the hotkey to withdwraw this amount. /// #[pallet::call_index(89)] - #[pallet::weight((Weight::from_parts(111_000_000, 0) - .saturating_add(Weight::from_parts(0, 43991)) - .saturating_add(T::DbWeight::get().reads(10)) - .saturating_add(T::DbWeight::get().writes(7)), DispatchClass::Normal, Pays::No))] + #[pallet::weight((Weight::from_parts(172_100_000, 0) + .saturating_add(T::DbWeight::get().reads(17)) + .saturating_add(T::DbWeight::get().writes(9)), DispatchClass::Normal, Pays::No))] pub fn remove_stake_limit( origin: OriginFor, hotkey: T::AccountId, @@ -1874,7 +1888,9 @@ mod dispatches { /// May emit a `StakeSwapped` event on success. #[pallet::call_index(90)] #[pallet::weight(( - Weight::from_parts(3_000_000, 0).saturating_add(T::DbWeight::get().writes(1)), + Weight::from_parts(162_400_000, 0) + .saturating_add(T::DbWeight::get().reads(12)) + .saturating_add(T::DbWeight::get().writes(9)), DispatchClass::Operational, Pays::No ))] @@ -1908,7 +1924,7 @@ mod dispatches { /// Will charge based on the weight even if the hotkey is already associated with a coldkey. #[pallet::call_index(91)] #[pallet::weight(( - Weight::from_parts(3_000_000, 0).saturating_add(T::DbWeight::get().reads_writes(3, 3)), + Weight::from_parts(32_560_000, 0).saturating_add(T::DbWeight::get().reads_writes(3, 3)), DispatchClass::Operational, Pays::Yes ))] @@ -1933,7 +1949,7 @@ mod dispatches { /// Emits a `FirstEmissionBlockNumberSet` event on success. #[pallet::call_index(92)] #[pallet::weight(( - Weight::from_parts(3_000_000, 0).saturating_add(T::DbWeight::get().reads_writes(6, 1)), + Weight::from_parts(35_770_000, 0).saturating_add(T::DbWeight::get().reads_writes(4, 2)), DispatchClass::Operational, Pays::Yes ))] @@ -1998,7 +2014,7 @@ mod dispatches { /// Emits a `TokensRecycled` event on success. #[pallet::call_index(101)] #[pallet::weight(( - Weight::from_parts(3_000_000, 0).saturating_add(T::DbWeight::get().reads_writes(3, 2)), + Weight::from_parts(101_000_000, 0).saturating_add(T::DbWeight::get().reads_writes(7, 4)), DispatchClass::Operational, Pays::Yes ))] @@ -2023,7 +2039,7 @@ mod dispatches { /// Emits a `TokensBurned` event on success. #[pallet::call_index(102)] #[pallet::weight(( - Weight::from_parts(2_000_000, 0).saturating_add(T::DbWeight::get().reads_writes(2, 1)), + Weight::from_parts(98_010_000, 0).saturating_add(T::DbWeight::get().reads_writes(7, 3)), DispatchClass::Operational, Pays::Yes ))] @@ -2074,8 +2090,8 @@ mod dispatches { /// - Errors stemming from transaction pallet. /// #[pallet::call_index(103)] - #[pallet::weight((Weight::from_parts(99_000_000, 5127) - .saturating_add(T::DbWeight::get().reads(14_u64)) + #[pallet::weight((Weight::from_parts(162_000_000, 5127) + .saturating_add(T::DbWeight::get().reads(15_u64)) .saturating_add(T::DbWeight::get().writes(12_u64)), DispatchClass::Normal, Pays::No))] pub fn add_stake_aggregate( origin: OriginFor, @@ -2124,8 +2140,8 @@ mod dispatches { /// - Thrown if there is not enough stake on the hotkey to withdwraw this amount. /// #[pallet::call_index(104)] - #[pallet::weight((Weight::from_parts(129_000_000, 10163) - .saturating_add(T::DbWeight::get().reads(19_u64)) + #[pallet::weight((Weight::from_parts(213_300_000, 10163) + .saturating_add(T::DbWeight::get().reads(20_u64)) .saturating_add(T::DbWeight::get().writes(12_u64)), DispatchClass::Normal, Pays::No))] pub fn remove_stake_aggregate( origin: OriginFor, @@ -2181,7 +2197,7 @@ mod dispatches { /// - Errors stemming from transaction pallet. /// #[pallet::call_index(105)] - #[pallet::weight((Weight::from_parts(99_000_000, 5127) + #[pallet::weight((Weight::from_parts(169_200_000, 5127) .saturating_add(T::DbWeight::get().reads(14_u64)) .saturating_add(T::DbWeight::get().writes(12_u64)), DispatchClass::Normal, Pays::No))] pub fn add_stake_limit_aggregate( @@ -2247,7 +2263,7 @@ mod dispatches { /// - Thrown if there is not enough stake on the hotkey to withdwraw this amount. /// #[pallet::call_index(106)] - #[pallet::weight((Weight::from_parts(129_000_000, 10163) + #[pallet::weight((Weight::from_parts(211_700_000, 10163) .saturating_add(T::DbWeight::get().reads(19_u64)) .saturating_add(T::DbWeight::get().writes(12_u64)), DispatchClass::Normal, Pays::No))] pub fn remove_stake_limit_aggregate( diff --git a/pallets/subtensor/src/tests/registration.rs b/pallets/subtensor/src/tests/registration.rs index 1ae16d95c0..498cce15b2 100644 --- a/pallets/subtensor/src/tests/registration.rs +++ b/pallets/subtensor/src/tests/registration.rs @@ -37,7 +37,7 @@ fn test_registration_subscribe_ok_dispatch_info_ok() { assert_eq!( call.get_dispatch_info(), DispatchInfo { - weight: frame_support::weights::Weight::from_parts(2_992_000_000, 0), + weight: frame_support::weights::Weight::from_parts(3_142_000_000, 0), class: DispatchClass::Normal, pays_fee: Pays::No } diff --git a/pallets/subtensor/src/tests/serving.rs b/pallets/subtensor/src/tests/serving.rs index 1d8202a242..251dde2078 100644 --- a/pallets/subtensor/src/tests/serving.rs +++ b/pallets/subtensor/src/tests/serving.rs @@ -53,7 +53,7 @@ fn test_serving_subscribe_ok_dispatch_info_ok() { assert_eq!( call.get_dispatch_info(), DispatchInfo { - weight: frame_support::weights::Weight::from_parts(246_000_000, 0), + weight: frame_support::weights::Weight::from_parts(235_670_000, 0), class: DispatchClass::Normal, pays_fee: Pays::No } @@ -355,7 +355,7 @@ fn test_prometheus_serving_subscribe_ok_dispatch_info_ok() { assert_eq!( call.get_dispatch_info(), DispatchInfo { - weight: frame_support::weights::Weight::from_parts(245_000_000, 0), + weight: frame_support::weights::Weight::from_parts(231_170_000, 0), class: DispatchClass::Normal, pays_fee: Pays::No } diff --git a/pallets/subtensor/src/tests/staking.rs b/pallets/subtensor/src/tests/staking.rs index 9ab34c608f..bc64a740fd 100644 --- a/pallets/subtensor/src/tests/staking.rs +++ b/pallets/subtensor/src/tests/staking.rs @@ -31,7 +31,7 @@ fn test_add_stake_dispatch_info_ok() { assert_eq!( call.get_dispatch_info(), DispatchInfo { - weight: frame_support::weights::Weight::from_parts(1_074_000_000, 0), + weight: frame_support::weights::Weight::from_parts(1_501_000_000, 0), class: DispatchClass::Normal, pays_fee: Pays::No } @@ -1203,8 +1203,8 @@ fn test_remove_stake_dispatch_info_ok() { assert_eq!( call.get_dispatch_info(), DispatchInfo { - weight: frame_support::weights::Weight::from_parts(1_061_000_000, 0) - .add_proof_size(43991), + weight: frame_support::weights::Weight::from_parts(1_671_800_000, 0) + .add_proof_size(0), class: DispatchClass::Normal, pays_fee: Pays::No } diff --git a/scripts/benchmark_action.sh b/scripts/benchmark_action.sh new file mode 100755 index 0000000000..9989f66c52 --- /dev/null +++ b/scripts/benchmark_action.sh @@ -0,0 +1,167 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Max allowed drift (%) +THRESHOLD=10 + +# Resolve script paths +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +DISPATCH="$SCRIPT_DIR/../pallets/subtensor/src/macros/dispatches.rs" +RUNTIME_WASM="./target/production/wbuild/node-subtensor-runtime/node_subtensor_runtime.compact.compressed.wasm" + +# Sanity check +if [[ ! -f "$DISPATCH" ]]; then + echo "❌ ERROR: dispatches.rs not found at $DISPATCH" + exit 1 +fi + +echo "Building runtime-benchmarks…" +cargo build --profile production -p node-subtensor --features runtime-benchmarks + +echo +echo "──────────────────────────────────────────" +echo " Running pallet_subtensor benchmarks…" +echo "──────────────────────────────────────────" + +MAX_RETRIES=3 +attempt=1 + +while (( attempt <= MAX_RETRIES )); do + echo + echo "Attempt #$attempt" + echo "──────────────────────────────────────────" + + # run benchmarks and capture output + TMP="$(mktemp)" + trap "rm -f \"$TMP\"" EXIT + ./target/production/node-subtensor benchmark pallet \ + --runtime "$RUNTIME_WASM" \ + --genesis-builder=runtime \ + --genesis-builder-preset=benchmark \ + --wasm-execution=compiled \ + --pallet pallet_subtensor \ + --extrinsic "*" \ + --steps 50 \ + --repeat 5 \ + | tee "$TMP" + + # reset counters + declare -a summary_lines=() + declare -a failures=() + fail=0 + extr="" + + # parse output + while IFS= read -r line; do + if [[ $line =~ Extrinsic:\ \"benchmark_([[:alnum:]_]+)\" ]]; then + extr="${BASH_REMATCH[1]}" + continue + fi + + if [[ $line =~ Time\ ~=\ *([0-9]+(\.[0-9]+)?) ]]; then + [[ -z "$extr" ]] && continue + + meas_us="${BASH_REMATCH[1]}" + meas_ps=$(awk -v u="$meas_us" 'BEGIN{printf("%.0f", u * 1000000)}') + + # grab reads & writes + meas_reads="" meas_writes="" + while IFS= read -r sub; do + [[ $sub =~ Reads[[:space:]]*=[[:space:]]*([0-9]+) ]] && meas_reads="${BASH_REMATCH[1]}" && continue + [[ $sub =~ Writes[[:space:]]*=[[:space:]]*([0-9]+) ]] && meas_writes="${BASH_REMATCH[1]}" && break + done + + # extract code-side values + code_record=$( + awk -v extr="$extr" ' + /^\s*#\[pallet::call_index\(/ { next } + /Weight::from_parts/ { + lw=$0; sub(/.*Weight::from_parts\(\s*/, "", lw); + sub(/[^0-9_].*$/, "", lw); gsub(/_/, "", lw); + w=lw + } + /reads_writes\(/ { + lw=$0; sub(/.*reads_writes\(/, "", lw); + sub(/\).*/, "", lw); + split(lw,io,/,/); + gsub(/^[ \t]+|[ \t]+$/, "", io[1]); + gsub(/^[ \t]+|[ \t]+$/, "", io[2]); + r=io[1]; wri=io[2]; next + } + /\.reads\(/ { + lw=$0; sub(/.*\.reads\(/, "", lw); + sub(/\).*/, "", lw); + r=lw; next + } + /\.writes\(/ { + lw=$0; sub(/.*\.writes\(/, "", lw); + sub(/\).*/, "", lw); + wri=lw; next + } + $0 ~ ("pub fn[[:space:]]+" extr "\\(") { print w, r, wri; exit } + ' "$DISPATCH" + ) + read code_w code_reads code_writes <<<"$code_record" + + # strip any non-digit (e.g. "_u64") so math works + code_w=${code_w//_/} + code_w=${code_w%%[^0-9]*} + code_reads=${code_reads//_/} + code_reads=${code_reads%%[^0-9]*} + code_writes=${code_writes//_/} + code_writes=${code_writes%%[^0-9]*} + + # compute drift % + drift=$(awk -v a="$meas_ps" -v b="$code_w" 'BEGIN{printf("%.1f", (a-b)/b*100)}') + + summary_lines+=("$(printf "%-30s | reads code=%3s measured=%3s | writes code=%3s measured=%3s | weight code=%12s measured=%12s | drift %6s%%" \ + "$extr" "$code_reads" "$meas_reads" "$code_writes" "$meas_writes" "$code_w" "$meas_ps" "$drift")") + + # validations + [[ -z "$code_w" ]] && failures+=("[${extr}] missing code weight") && fail=1 + [[ -z "$meas_reads" ]] && failures+=("[${extr}] missing measured reads") && fail=1 + [[ -z "$meas_writes" ]] && failures+=("[${extr}] missing measured writes") && fail=1 + (( meas_reads != code_reads )) && failures+=("[${extr}] reads mismatch code=${code_reads}, measured=${meas_reads}") && fail=1 + (( meas_writes != code_writes )) && failures+=("[${extr}] writes mismatch code=${code_writes}, measured=${meas_writes}") && fail=1 + [[ "$code_w" == "0" ]] && failures+=("[${extr}] zero code weight") && fail=1 + + abs_drift=${drift#-} + drift_int=${abs_drift%%.*} + if (( drift_int > THRESHOLD )); then + failures+=("[${extr}] weight code=${code_w}, measured=${meas_ps}, drift=${drift}%") + fail=1 + fi + + extr="" + fi + done < "$TMP" + + # summary output + echo + echo "Benchmark Summary for attempt #$attempt:" + for l in "${summary_lines[@]}"; do + echo " $l" + done + + if (( fail )); then + echo + echo "❌ Issues detected on attempt #$attempt:" + for e in "${failures[@]}"; do + echo " • $e" + done + + if (( attempt < MAX_RETRIES )); then + echo "→ Retrying…" + (( attempt++ )) + continue + else + echo + echo "❌ Benchmarks failed after $MAX_RETRIES attempts." + exit 1 + fi + else + echo + echo "✅ All benchmarks within ±${THRESHOLD}% drift." + exit 0 + fi +done diff --git a/scripts/benchmark_all.sh b/scripts/benchmark_all.sh index cfdd1e9672..22d23483f3 100755 --- a/scripts/benchmark_all.sh +++ b/scripts/benchmark_all.sh @@ -29,4 +29,4 @@ for pallet in "${pallets[@]}"; do --extrinsic "*" \ --steps 50 \ --repeat 5 -done +done \ No newline at end of file