Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Co reducing fast-unstake bench time and more #6552

Merged
merged 27 commits into from
Jan 27, 2023
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
1052ffd
update stuff
kianenigma Jan 13, 2023
e0e7b98
remove
kianenigma Jan 13, 2023
467c282
update
kianenigma Jan 13, 2023
69f01c5
update
kianenigma Jan 13, 2023
c7cc367
update weights
kianenigma Jan 14, 2023
292221b
fix tests
kianenigma Jan 14, 2023
aee9758
update weights
kianenigma Jan 15, 2023
6e93949
Merge branch 'master' of https://github.com/paritytech/polkadot into …
Jan 15, 2023
0c9d768
fix a few small things
kianenigma Jan 15, 2023
4891dbf
".git/.scripts/commands/bench/bench.sh" runtime polkadot-dev pallet-f…
Jan 15, 2023
6496a57
Merge branch 'kiz-fix-fast-unstake-bench' of github.com:paritytech/po…
kianenigma Jan 15, 2023
133e26c
".git/.scripts/commands/bench/bench.sh" runtime polkadot-dev pallet-f…
Jan 15, 2023
9a4972c
".git/.scripts/commands/bench/bench.sh" runtime kusama-dev pallet-fas…
Jan 15, 2023
b5945ef
reduce batch size
kianenigma Jan 15, 2023
1e64eb8
Merge branch 'kiz-fix-fast-unstake-bench' of github.com:paritytech/po…
kianenigma Jan 15, 2023
6427465
".git/.scripts/commands/bench/bench.sh" runtime polkadot-dev pallet-f…
Jan 15, 2023
b1b19c0
Merged
kianenigma Jan 25, 2023
d8e099e
Merge branch 'kiz-fix-fast-unstake-bench' of github.com:paritytech/po…
kianenigma Jan 25, 2023
f7afb5d
update
kianenigma Jan 25, 2023
b513136
fix
kianenigma Jan 25, 2023
8861212
fix
kianenigma Jan 25, 2023
4d0abd7
".git/.scripts/commands/bench/bench.sh" runtime polkadot-dev pallet-f…
Jan 25, 2023
729f7bd
update lockfile for {"substrate"}
Jan 26, 2023
a1fef94
Merge branch 'master' of github.com:paritytech/polkadot into kiz-fix-…
kianenigma Jan 26, 2023
4c3eb7d
fmt
kianenigma Jan 26, 2023
6825d0a
Master.into()
kianenigma Jan 26, 2023
119d604
Env gate migration try_fast_unstake_all
ggwpez Jan 27, 2023
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
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions runtime/common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ sp-npos-elections = { git = "https://github.com/paritytech/substrate", branch =

pallet-authorship = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
pallet-fast-unstake = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
pallet-session = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
frame-support = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
pallet-staking = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
Expand Down Expand Up @@ -84,6 +85,7 @@ std = [
"pallet-balances/std",
"pallet-beefy-mmr/std",
"pallet-session/std",
"pallet-fast-unstake/std",
"pallet-staking/std",
"pallet-staking-reward-fn/std",
"pallet-timestamp/std",
Expand Down Expand Up @@ -111,6 +113,7 @@ runtime-benchmarks = [
"runtime-parachains/runtime-benchmarks",
"pallet-babe/runtime-benchmarks",
"pallet-bags-list/runtime-benchmarks",
"pallet-fast-unstake/runtime-benchmarks"
]
try-runtime = [
"runtime-parachains/try-runtime",
Expand All @@ -122,4 +125,5 @@ try-runtime = [
"pallet-vesting/try-runtime",
"pallet-transaction-payment/try-runtime",
"pallet-treasury/try-runtime",
"pallet-fast-unstake/try-runtime",
]
2 changes: 2 additions & 0 deletions runtime/common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ pub mod slot_range;
pub mod slots;
pub mod traits;
pub mod xcm_sender;
#[cfg(feature = "try-runtime")]
pub mod try_runtime;

#[cfg(test)]
mod integration_tests;
Expand Down
105 changes: 105 additions & 0 deletions runtime/common/src/try_runtime.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
// Copyright 2023 Parity Technologies (UK) Ltd.
// This file is part of Polkadot.

// Polkadot is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// Polkadot is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.

//! common try-runtime only tests for runtimes.
kianenigma marked this conversation as resolved.
Show resolved Hide resolved

/// register all inactive nominators for fast-unstake, and progress until they have all been
/// processed.
pub fn migrate_all_inactive_nominators<T: pallet_fast_unstake::Config + pallet_staking::Config>()
where
<T as frame_system::Config>::RuntimeEvent: TryInto<pallet_fast_unstake::Event<T>>,
{
use frame_support::{
dispatch::RawOrigin,
traits::{Get, Hooks},
};
use pallet_fast_unstake::{Pallet as FastUnstake, *};
use pallet_staking::*;
use sp_std::{collections::btree_set::BTreeSet, prelude::*};
kianenigma marked this conversation as resolved.
Show resolved Hide resolved

let mut unstaked_ok = 0;
let mut unstaked_err = 0;
let mut unstaked_slashed = 0;

let all_stakers = Ledger::<T>::iter().map(|(ctrl, l)| (ctrl, l.stash)).collect::<BTreeSet<_>>();
let mut all_exposed = BTreeSet::new();
ErasStakers::<T>::iter().for_each(|(_, val, expo)| {
all_exposed.insert(val);
expo.others.iter().for_each(|ie| {
all_exposed.insert(ie.who.clone());
})
kianenigma marked this conversation as resolved.
Show resolved Hide resolved
});

let eligible = all_stakers
.iter()
.filter_map(|(ctrl, stash)| if all_exposed.contains(stash) { None } else { Some(ctrl) })
kianenigma marked this conversation as resolved.
Show resolved Hide resolved
.collect::<Vec<_>>();

log::info!(
target: "runtime::test",
"registering {} out of {} stakers for fast-unstake",
eligible.len(),
all_stakers.len()
);
for ctrl in eligible {
if let Err(why) =
FastUnstake::<T>::register_fast_unstake(RawOrigin::Signed(ctrl.clone()).into())
{
log::warn!(target: "runtime::test", "failed to register {:?} due to {:?}", ctrl, why);
}
Copy link
Member

Choose a reason for hiding this comment

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

Maybe also add a success log?
The queue count below could also contain non-migration unstakers, or?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The pallet is already logging that.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The queue count below could also contain non-migration unstakers, or?

The queue is always the un-migrated ones.

}

log::info!(target: "runtime::test", "registered {} successfully, starting at {:?}.", Queue::<T>::count(), frame_system::Pallet::<T>::block_number());
kianenigma marked this conversation as resolved.
Show resolved Hide resolved
while Queue::<T>::count() != 0 || Head::<T>::get().is_some() {
// assume half of the block weight is available.
let now = frame_system::Pallet::<T>::block_number();
let weight = <T as frame_system::Config>::BlockWeights::get().max_block;
kianenigma marked this conversation as resolved.
Show resolved Hide resolved
let consumed = FastUnstake::<T>::on_idle(now, weight);
log::debug!(target: "runtime::test", "consumed {:?} ({})", consumed, consumed.ref_time() as f32 / weight.ref_time() as f32);
kianenigma marked this conversation as resolved.
Show resolved Hide resolved

frame_system::Pallet::<T>::read_events_no_consensus()
Copy link
Member

Choose a reason for hiding this comment

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

This is only in consensus code since its a migration, or?
Maybe put a comment so that no one copy&pastes this 🙈

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is purely test code, not migration.

.into_iter()
.map(|r| r.event)
.filter_map(|e| {
let maybe_fast_unstake_event: Option<pallet_fast_unstake::Event<T>> =
e.try_into().ok();
maybe_fast_unstake_event
})
.for_each(|e: pallet_fast_unstake::Event<T>| match e {
pallet_fast_unstake::Event::<T>::Unstaked { result, .. } =>
if result.is_ok() {
unstaked_ok += 1;
} else {
unstaked_err += 1
},
pallet_fast_unstake::Event::<T>::Slashed { .. } => unstaked_slashed += 1,
pallet_fast_unstake::Event::<T>::InternalError => unreachable!(),
_ => {},
});

if now % 100u32.into() == sp_runtime::traits::Zero::zero() {
log::info!(
target: "runtime::test",
"status: ok {}, err {}, slash {}",
unstaked_ok,
unstaked_err,
unstaked_slashed,
);
}

frame_system::Pallet::<T>::reset_events();
Copy link
Member

Choose a reason for hiding this comment

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

Why did you do the event checking here and not in post_upgrade? To reduce the WASM memory when there are a lot of events? Or the storage?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Same as above, this is test, not migration.

}
}
50 changes: 47 additions & 3 deletions runtime/kusama/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -608,8 +608,11 @@ impl pallet_fast_unstake::Config for Runtime {
EnsureRoot<AccountId>,
pallet_collective::EnsureProportionAtLeast<AccountId, CouncilCollective, 1, 2>,
>;
type WeightInfo = weights::pallet_fast_unstake::WeightInfo<Runtime>;
type Staking = Staking;
type MaxErasToCheckPerBlock = ConstU32<1>;
#[cfg(feature = "runtime-benchmarks")]
type MaxBackersPerValidator = MaxNominatorRewardedPerValidator;
type WeightInfo = weights::pallet_fast_unstake::WeightInfo<Runtime>;
}

parameter_types! {
Expand Down Expand Up @@ -2129,6 +2132,19 @@ mod multiplier_tests {
})
}

#[test]
fn fast_unstake_estimate() {
use pallet_fast_unstake::WeightInfo;
let block_time = BlockWeights::get().max_block.ref_time() as f32;
let on_idle = weights::pallet_fast_unstake::WeightInfo::<Runtime>::on_idle_check(
1000,
<Runtime as pallet_fast_unstake::Config>::BatchSize::get(),
)
.ref_time() as f32;
println!("ratio of block weight for full batch fast-unstake {}", on_idle / block_time);
assert!(on_idle / block_time <= 0.5f32)
}

#[test]
#[ignore]
fn multiplier_growth_simulator() {
Expand Down Expand Up @@ -2213,7 +2229,7 @@ mod multiplier_tests {
#[cfg(all(test, feature = "try-runtime"))]
mod remote_tests {
use super::*;
use frame_try_runtime::runtime_decl_for_TryRuntime::TryRuntime;
use frame_try_runtime::{runtime_decl_for_TryRuntime::TryRuntime, UpgradeCheckSelect};
use remote_externalities::{
Builder, Mode, OfflineConfig, OnlineConfig, SnapshotConfig, Transport,
};
Expand Down Expand Up @@ -2241,6 +2257,34 @@ mod remote_tests {
.build()
.await
.unwrap();
ext.execute_with(|| Runtime::on_runtime_upgrade(true));
ext.execute_with(|| Runtime::on_runtime_upgrade(UpgradeCheckSelect::All));
}

#[tokio::test]
async fn try_fast_unstake_all() {
sp_tracing::try_init_simple();
let transport: Transport =
var("WS").unwrap_or("wss://kusama-rpc.polkadot.io:443".to_string()).into();
let maybe_state_snapshot: Option<SnapshotConfig> = var("SNAP").map(|s| s.into()).ok();
let mut ext = Builder::<Block>::default()
.mode(if let Some(state_snapshot) = maybe_state_snapshot {
Mode::OfflineOrElseOnline(
OfflineConfig { state_snapshot: state_snapshot.clone() },
OnlineConfig {
transport,
state_snapshot: Some(state_snapshot),
..Default::default()
},
)
} else {
Mode::Online(OnlineConfig { transport, ..Default::default() })
})
.build()
.await
.unwrap();
ext.execute_with(|| {
pallet_fast_unstake::ErasToCheckPerBlock::<Runtime>::put(1);
runtime_common::try_runtime::migrate_all_inactive_nominators::<Runtime>()
});
}
}
98 changes: 54 additions & 44 deletions runtime/kusama/src/weights/pallet_fast_unstake.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,23 @@
//! Autogenerated weights for `pallet_fast_unstake`
//!
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
//! DATE: 2022-11-16, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]`
//! HOSTNAME: `bm5`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz`
//! DATE: 2023-01-15, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]`
//! HOSTNAME: `bm3`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz`
//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("kusama-dev"), DB CACHE: 1024

// Executed Command:
// ./target/production/polkadot
// /home/benchbot/cargo_target_dir/production/polkadot
// benchmark
// pallet
// --chain=kusama-dev
// --steps=50
// --repeat=20
// --pallet=pallet_fast_unstake
// --extrinsic=*
// --execution=wasm
// --wasm-execution=compiled
// --heap-pages=4096
// --json-file=/var/lib/gitlab-runner/builds/zyw4fam_/0/parity/mirrors/polkadot/.git/.artifacts/bench.json
// --pallet=pallet-fast-unstake
// --chain=kusama-dev
// --header=./file_header.txt
// --output=./runtime/kusama/src/weights/

Expand All @@ -46,40 +48,48 @@ pub struct WeightInfo<T>(PhantomData<T>);
impl<T: frame_system::Config> pallet_fast_unstake::WeightInfo for WeightInfo<T> {
// Storage: FastUnstake ErasToCheckPerBlock (r:1 w:0)
// Storage: Staking ValidatorCount (r:1 w:0)
// Storage: ElectionProviderMultiPhase CurrentPhase (r:1 w:0)
// Storage: FastUnstake Head (r:1 w:1)
// Storage: FastUnstake CounterForQueue (r:1 w:0)
// Storage: ElectionProviderMultiPhase CurrentPhase (r:1 w:0)
// Storage: Staking CurrentEra (r:1 w:0)
// Storage: Staking SlashingSpans (r:64 w:0)
// Storage: Staking Bonded (r:64 w:64)
// Storage: Staking Validators (r:64 w:0)
// Storage: Staking Nominators (r:64 w:0)
// Storage: System Account (r:64 w:64)
// Storage: Balances Locks (r:64 w:64)
// Storage: Staking Ledger (r:0 w:64)
// Storage: Staking Payee (r:0 w:64)
fn on_idle_unstake() -> Weight {
// Minimum execution time: 2_141_174 nanoseconds.
Weight::from_ref_time(2_204_649_000 as u64)
.saturating_add(T::DbWeight::get().reads(389 as u64))
.saturating_add(T::DbWeight::get().writes(321 as u64))
// Storage: Staking SlashingSpans (r:1 w:0)
// Storage: Staking Bonded (r:1 w:1)
// Storage: Staking Validators (r:1 w:0)
// Storage: Staking Nominators (r:1 w:0)
// Storage: System Account (r:1 w:1)
// Storage: Balances Locks (r:1 w:1)
// Storage: Staking Ledger (r:0 w:1)
// Storage: Staking Payee (r:0 w:1)
/// The range of component `b` is `[1, 64]`.
fn on_idle_unstake(b: u32, ) -> Weight {
// Minimum execution time: 77_225 nanoseconds.
Weight::from_ref_time(45_851_915)
// Standard Error: 27_205
.saturating_add(Weight::from_ref_time(34_256_381).saturating_mul(b.into()))
.saturating_add(T::DbWeight::get().reads(6))
.saturating_add(T::DbWeight::get().reads((6_u64).saturating_mul(b.into())))
.saturating_add(T::DbWeight::get().writes(1))
.saturating_add(T::DbWeight::get().writes((5_u64).saturating_mul(b.into())))
}
// Storage: FastUnstake ErasToCheckPerBlock (r:1 w:0)
// Storage: Staking ValidatorCount (r:1 w:0)
// Storage: ElectionProviderMultiPhase CurrentPhase (r:1 w:0)
// Storage: FastUnstake Head (r:1 w:1)
// Storage: FastUnstake Queue (r:65 w:64)
// Storage: FastUnstake CounterForQueue (r:1 w:1)
// Storage: FastUnstake CounterForQueue (r:1 w:0)
// Storage: ElectionProviderMultiPhase CurrentPhase (r:1 w:0)
// Storage: Staking CurrentEra (r:1 w:0)
// Storage: Staking ErasStakers (r:56 w:0)
/// The range of component `x` is `[28, 3584]`.
fn on_idle_check(x: u32, ) -> Weight {
// Minimum execution time: 21_964_474 nanoseconds.
Weight::from_ref_time(22_227_783_000 as u64)
// Standard Error: 498_921
.saturating_add(Weight::from_ref_time(624_289_713 as u64).saturating_mul(x as u64))
.saturating_add(T::DbWeight::get().reads(85 as u64))
.saturating_add(T::DbWeight::get().reads((1 as u64).saturating_mul(x as u64)))
.saturating_add(T::DbWeight::get().writes(66 as u64))
// Storage: Staking ErasStakers (r:2 w:0)
/// The range of component `v` is `[1, 256]`.
/// The range of component `b` is `[1, 64]`.
fn on_idle_check(v: u32, b: u32, ) -> Weight {
// Minimum execution time: 1_671_682 nanoseconds.
Weight::from_ref_time(1_683_909_000)
// Standard Error: 16_637_473
.saturating_add(Weight::from_ref_time(533_652_266).saturating_mul(v.into()))
// Standard Error: 66_568_424
.saturating_add(Weight::from_ref_time(2_085_678_765).saturating_mul(b.into()))
.saturating_add(T::DbWeight::get().reads(7))
.saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(v.into())))
.saturating_add(T::DbWeight::get().writes(1))
}
// Storage: FastUnstake ErasToCheckPerBlock (r:1 w:0)
// Storage: Staking Ledger (r:1 w:1)
Expand All @@ -89,33 +99,33 @@ impl<T: frame_system::Config> pallet_fast_unstake::WeightInfo for WeightInfo<T>
// Storage: Staking Validators (r:1 w:0)
// Storage: Staking Nominators (r:1 w:1)
// Storage: Staking CounterForNominators (r:1 w:1)
// Storage: VoterList ListNodes (r:2 w:2)
// Storage: VoterList ListNodes (r:1 w:1)
// Storage: VoterList ListBags (r:1 w:1)
// Storage: VoterList CounterForListNodes (r:1 w:1)
// Storage: Staking CurrentEra (r:1 w:0)
// Storage: Balances Locks (r:1 w:1)
// Storage: FastUnstake CounterForQueue (r:1 w:1)
fn register_fast_unstake() -> Weight {
// Minimum execution time: 124_637 nanoseconds.
Weight::from_ref_time(126_193_000 as u64)
.saturating_add(T::DbWeight::get().reads(15 as u64))
.saturating_add(T::DbWeight::get().writes(10 as u64))
// Minimum execution time: 106_509 nanoseconds.
Weight::from_ref_time(107_537_000)
.saturating_add(T::DbWeight::get().reads(14))
.saturating_add(T::DbWeight::get().writes(9))
}
// Storage: FastUnstake ErasToCheckPerBlock (r:1 w:0)
// Storage: Staking Ledger (r:1 w:0)
// Storage: FastUnstake Queue (r:1 w:1)
// Storage: FastUnstake Head (r:1 w:0)
// Storage: FastUnstake CounterForQueue (r:1 w:1)
fn deregister() -> Weight {
// Minimum execution time: 50_711 nanoseconds.
Weight::from_ref_time(51_537_000 as u64)
.saturating_add(T::DbWeight::get().reads(5 as u64))
.saturating_add(T::DbWeight::get().writes(2 as u64))
// Minimum execution time: 43_328 nanoseconds.
Weight::from_ref_time(43_904_000)
.saturating_add(T::DbWeight::get().reads(5))
.saturating_add(T::DbWeight::get().writes(2))
}
// Storage: FastUnstake ErasToCheckPerBlock (r:0 w:1)
fn control() -> Weight {
// Minimum execution time: 4_008 nanoseconds.
Weight::from_ref_time(4_153_000 as u64)
.saturating_add(T::DbWeight::get().writes(1 as u64))
// Minimum execution time: 4_153 nanoseconds.
Weight::from_ref_time(4_337_000)
.saturating_add(T::DbWeight::get().writes(1))
}
}
Loading