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

Runtime State Test + Integration with try-runtime #10174

Merged
merged 48 commits into from
Sep 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
69e92ad
add missing version to dependencies
kianenigma Nov 2, 2021
9f20cbe
Huh
kianenigma Nov 3, 2021
4586de1
add features more
kianenigma Nov 3, 2021
c980770
more fixing
kianenigma Nov 3, 2021
822a4d0
Merge branch 'master' of github.com:paritytech/substrate into kiz-san…
kianenigma Nov 4, 2021
3dad278
last touches
kianenigma Nov 4, 2021
266fcb2
Master.into()
kianenigma Mar 22, 2022
d473421
Mostly merged with master again
kianenigma Jun 17, 2022
f1ceefa
merge current branch and make it compile
kianenigma Jun 18, 2022
844a86f
it all finally works
kianenigma Jun 23, 2022
0a43345
remove some feature gates
kianenigma Jun 23, 2022
d9ddd3e
Merge branch 'master' of github.com:paritytech/substrate into kiz-san…
kianenigma Jun 23, 2022
d6db0d5
remove unused
kianenigma Jun 23, 2022
312749d
fix old macro
kianenigma Jun 24, 2022
d72ff85
make it work again
kianenigma Jun 24, 2022
123a16c
fmt
kianenigma Jun 24, 2022
f07e714
remove unused import
kianenigma Jun 24, 2022
57d9a0e
Master.into()
kianenigma Aug 14, 2022
436afe0
".git/.scripts/fmt.sh" 1
Aug 14, 2022
bab0c67
Merge branch 'master' of github.com:paritytech/substrate into kiz-san…
kianenigma Aug 16, 2022
de27834
Cleanup more
kianenigma Aug 16, 2022
6a3fdd2
fix and rename everything
kianenigma Aug 19, 2022
6eddd2b
a few clippy fixes
kianenigma Aug 19, 2022
10b1af7
Add try-runtime feature
ggwpez Aug 19, 2022
d7f1907
Merge branch 'master' of github.com:paritytech/substrate into kiz-san…
kianenigma Aug 20, 2022
5648534
Merge branch 'kiz-sanity-check-trait' of github.com:paritytech/substr…
kianenigma Aug 20, 2022
d79d33b
small fixes
kianenigma Aug 20, 2022
b2a1ff8
fmt
kianenigma Aug 20, 2022
7590566
Update bin/node-template/runtime/src/lib.rs
kianenigma Aug 21, 2022
8c17b93
fix build
kianenigma Aug 21, 2022
9ccb198
Merge branch 'kiz-sanity-check-trait' of github.com:paritytech/substr…
kianenigma Aug 21, 2022
42450b5
Merge branch 'master' of github.com:paritytech/substrate into kiz-san…
kianenigma Aug 28, 2022
73aa952
Update utils/frame/try-runtime/cli/src/lib.rs
kianenigma Aug 28, 2022
ade3b1c
Update utils/frame/try-runtime/cli/src/commands/execute_block.rs
kianenigma Aug 28, 2022
e53d4eb
address all review comments
kianenigma Aug 28, 2022
1b21397
Merge branch 'kiz-sanity-check-trait' of github.com:paritytech/substr…
kianenigma Aug 28, 2022
e705762
fix typos
kianenigma Aug 29, 2022
6d801e9
Merge branch 'master' of github.com:paritytech/substrate into kiz-san…
kianenigma Aug 29, 2022
f733b6f
revert spec change
kianenigma Aug 29, 2022
dfe0d8e
last touches
kianenigma Aug 29, 2022
73bae7e
update docs
kianenigma Aug 29, 2022
c12202c
fmt
kianenigma Aug 29, 2022
d5bae73
Merge remote-tracking branch 'origin/master' into kiz-sanity-check-trait
Aug 30, 2022
8a76db4
Merge branch 'master' of github.com:paritytech/substrate into kiz-san…
kianenigma Aug 30, 2022
58850ad
Merge branch 'kiz-sanity-check-trait' of github.com:paritytech/substr…
kianenigma Aug 30, 2022
f102730
remove some debug_assertions
kianenigma Aug 30, 2022
3a60fb5
Merge branch 'master' of github.com:paritytech/substrate into kiz-san…
kianenigma Sep 1, 2022
b491796
fmt
kianenigma Sep 1, 2022
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
3 changes: 3 additions & 0 deletions Cargo.lock

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

4 changes: 3 additions & 1 deletion bin/node-template/runtime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ std = [
"frame-support/std",
"frame-system-rpc-runtime-api/std",
"frame-system/std",
"frame-try-runtime/std",
"pallet-aura/std",
"pallet-balances/std",
"pallet-grandpa/std",
Expand Down Expand Up @@ -97,9 +98,10 @@ runtime-benchmarks = [
"sp-runtime/runtime-benchmarks",
]
try-runtime = [
"frame-executive/try-runtime",
"frame-try-runtime",
"frame-executive/try-runtime",
"frame-system/try-runtime",
"frame-support/try-runtime",
"pallet-aura/try-runtime",
"pallet-balances/try-runtime",
"pallet-grandpa/try-runtime",
Expand Down
10 changes: 8 additions & 2 deletions bin/node-template/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -545,8 +545,14 @@ impl_runtime_apis! {
(weight, BlockWeights::get().max_block)
}

fn execute_block_no_check(block: Block) -> Weight {
Executive::execute_block_no_check(block)
fn execute_block(
block: Block,
state_root_check: bool,
select: frame_try_runtime::TryStateSelect
) -> Weight {
// NOTE: intentional unwrap: we don't want to propagate the error backwards, and want to
// have a backtrace here.
Executive::try_execute_block(block, state_root_check, select).expect("execute-block failed")
kianenigma marked this conversation as resolved.
Show resolved Hide resolved
}
}
}
20 changes: 13 additions & 7 deletions bin/node/runtime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -245,14 +245,16 @@ runtime-benchmarks = [
"hex-literal",
]
try-runtime = [
"frame-executive/try-runtime",
"frame-try-runtime",
"frame-executive/try-runtime",
"frame-system/try-runtime",
"frame-support/try-runtime",
"pallet-alliance/try-runtime",
"pallet-assets/try-runtime",
"pallet-authority-discovery/try-runtime",
"pallet-authorship/try-runtime",
"pallet-babe/try-runtime",
"pallet-bags-list/try-runtime",
"pallet-balances/try-runtime",
"pallet-bounties/try-runtime",
"pallet-child-bounties/try-runtime",
Expand All @@ -264,32 +266,36 @@ try-runtime = [
"pallet-elections-phragmen/try-runtime",
"pallet-gilt/try-runtime",
"pallet-grandpa/try-runtime",
"pallet-identity/try-runtime",
"pallet-im-online/try-runtime",
"pallet-indices/try-runtime",
"pallet-identity/try-runtime",
"pallet-lottery/try-runtime",
"pallet-membership/try-runtime",
"pallet-mmr/try-runtime",
"pallet-multisig/try-runtime",
"pallet-nomination-pools/try-runtime",
"pallet-offences/try-runtime",
"pallet-preimage/try-runtime",
"pallet-proxy/try-runtime",
"pallet-ranked-collective/try-runtime",
"pallet-randomness-collective-flip/try-runtime",
"pallet-ranked-collective/try-runtime",
"pallet-recovery/try-runtime",
"pallet-referenda/try-runtime",
"pallet-scheduler/try-runtime",
"pallet-remark/try-runtime",
"pallet-session/try-runtime",
"pallet-society/try-runtime",
"pallet-staking/try-runtime",
"pallet-state-trie-migration/try-runtime",
"pallet-scheduler/try-runtime",
"pallet-society/try-runtime",
"pallet-sudo/try-runtime",
"pallet-timestamp/try-runtime",
"pallet-tips/try-runtime",
"pallet-transaction-payment/try-runtime",
"pallet-treasury/try-runtime",
"pallet-uniques/try-runtime",
"pallet-utility/try-runtime",
"pallet-transaction-payment/try-runtime",
"pallet-asset-tx-payment/try-runtime",
"pallet-transaction-storage/try-runtime",
"pallet-uniques/try-runtime",
"pallet-vesting/try-runtime",
"pallet-whitelist/try-runtime",
]
Expand Down
17 changes: 15 additions & 2 deletions bin/node/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2079,8 +2079,21 @@ impl_runtime_apis! {
(weight, RuntimeBlockWeights::get().max_block)
}

fn execute_block_no_check(block: Block) -> Weight {
Executive::execute_block_no_check(block)
fn execute_block(
block: Block,
state_root_check: bool,
select: frame_try_runtime::TryStateSelect
) -> Weight {
log::info!(
target: "node-runtime",
"try-runtime: executing block {:?} / root checks: {:?} / try-state-select: {:?}",
block.header.hash(),
state_root_check,
select,
);
// NOTE: intentional unwrap: we don't want to propagate the error backwards, and want to
// have a backtrace here.
Executive::try_execute_block(block, state_root_check, select).unwrap()
}
}

Expand Down
2 changes: 1 addition & 1 deletion frame/bags-list/fuzzer/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ fn main() {
},
}

assert!(BagsList::sanity_check().is_ok());
assert!(BagsList::try_state().is_ok());
})
});
}
2 changes: 1 addition & 1 deletion frame/bags-list/remote-tests/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ use sp_std::prelude::*;
pub const LOG_TARGET: &str = "runtime::bags-list::remote-tests";

pub mod migration;
pub mod sanity_check;
pub mod snapshot;
pub mod try_state;

/// A wrapper for a runtime that the functions of this crate expect.
///
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ pub async fn execute<Runtime: crate::RuntimeT, Block: BlockT + DeserializeOwned>

ext.execute_with(|| {
sp_core::crypto::set_default_ss58_version(Runtime::SS58Prefix::get().try_into().unwrap());
pallet_bags_list::Pallet::<Runtime>::sanity_check().unwrap();
pallet_bags_list::Pallet::<Runtime>::try_state().unwrap();
log::info!(target: crate::LOG_TARGET, "executed bags-list sanity check with no errors.");

crate::display_and_check_bags::<Runtime>(currency_unit, currency_name);
Expand Down
15 changes: 7 additions & 8 deletions frame/bags-list/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,11 @@ pub mod pallet {
"thresholds must strictly increase, and have no duplicates",
);
}

#[cfg(feature = "try-runtime")]
fn try_state(_: BlockNumberFor<T>) -> Result<(), &'static str> {
<Self as SortedListProvider<T::AccountId>>::try_state()
}
}
}

Expand Down Expand Up @@ -340,14 +345,8 @@ impl<T: Config<I>, I: 'static> SortedListProvider<T::AccountId> for Pallet<T, I>
List::<T, I>::unsafe_regenerate(all, score_of)
}

#[cfg(feature = "std")]
fn sanity_check() -> Result<(), &'static str> {
List::<T, I>::sanity_check()
}

#[cfg(not(feature = "std"))]
fn sanity_check() -> Result<(), &'static str> {
Ok(())
fn try_state() -> Result<(), &'static str> {
List::<T, I>::try_state()
}

fn unsafe_clear() {
Expand Down
43 changes: 15 additions & 28 deletions frame/bags-list/src/list/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ use crate::Config;
use codec::{Decode, Encode, MaxEncodedLen};
use frame_election_provider_support::ScoreProvider;
use frame_support::{
ensure,
traits::{Defensive, Get},
defensive, ensure,
traits::{Defensive, DefensiveOption, Get},
DefaultNoBound, PalletError,
};
use scale_info::TypeInfo;
Expand Down Expand Up @@ -220,7 +220,8 @@ impl<T: Config<I>, I: 'static> List<T, I> {
crate::ListBags::<T, I>::remove(removed_bag);
}

debug_assert_eq!(Self::sanity_check(), Ok(()));
#[cfg(feature = "std")]
debug_assert_eq!(Self::try_state(), Ok(()));
kianenigma marked this conversation as resolved.
Show resolved Hide resolved

num_affected
}
Expand Down Expand Up @@ -325,8 +326,7 @@ impl<T: Config<I>, I: 'static> List<T, I> {

crate::log!(
debug,
"inserted {:?} with score {:?
} into bag {:?}, new count is {}",
"inserted {:?} with score {:?} into bag {:?}, new count is {}",
id,
score,
bag_score,
Expand Down Expand Up @@ -457,11 +457,8 @@ impl<T: Config<I>, I: 'static> List<T, I> {

// re-fetch `lighter_node` from storage since it may have been updated when `heavier_node`
// was removed.
let lighter_node = Node::<T, I>::get(lighter_id).ok_or_else(|| {
debug_assert!(false, "id that should exist cannot be found");
crate::log!(warn, "id that should exist cannot be found");
ListError::NodeNotFound
})?;
let lighter_node =
Node::<T, I>::get(lighter_id).defensive_ok_or_else(|| ListError::NodeNotFound)?;

// insert `heavier_node` directly in front of `lighter_node`. This will update both nodes
// in storage and update the node counter.
Expand Down Expand Up @@ -508,7 +505,7 @@ impl<T: Config<I>, I: 'static> List<T, I> {
node.put();
}

/// Sanity check the list.
/// Check the internal state of the list.
///
/// This should be called from the call-site, whenever one of the mutating apis (e.g. `insert`)
/// is being used, after all other staking data (such as counter) has been updated. It checks:
Expand All @@ -517,8 +514,7 @@ impl<T: Config<I>, I: 'static> List<T, I> {
/// * length of this list is in sync with `ListNodes::count()`,
/// * and sanity-checks all bags and nodes. This will cascade down all the checks and makes sure
/// all bags and nodes are checked per *any* update to `List`.
#[cfg(feature = "std")]
pub(crate) fn sanity_check() -> Result<(), &'static str> {
pub(crate) fn try_state() -> Result<(), &'static str> {
let mut seen_in_list = BTreeSet::new();
ensure!(
Self::iter().map(|node| node.id).all(|id| seen_in_list.insert(id)),
Expand Down Expand Up @@ -546,7 +542,7 @@ impl<T: Config<I>, I: 'static> List<T, I> {
thresholds.into_iter().filter_map(|t| Bag::<T, I>::get(t))
};

let _ = active_bags.clone().try_for_each(|b| b.sanity_check())?;
let _ = active_bags.clone().try_for_each(|b| b.try_state())?;

let nodes_in_bags_count =
active_bags.clone().fold(0u32, |acc, cur| acc + cur.iter().count() as u32);
Expand All @@ -557,17 +553,12 @@ impl<T: Config<I>, I: 'static> List<T, I> {
// check that all nodes are sane. We check the `ListNodes` storage item directly in case we
// have some "stale" nodes that are not in a bag.
for (_id, node) in crate::ListNodes::<T, I>::iter() {
node.sanity_check()?
node.try_state()?
}

Ok(())
}

#[cfg(not(feature = "std"))]
pub(crate) fn sanity_check() -> Result<(), &'static str> {
Ok(())
}

/// Returns the nodes of all non-empty bags. For testing and benchmarks.
#[cfg(any(feature = "std", feature = "runtime-benchmarks"))]
#[allow(dead_code)]
Expand Down Expand Up @@ -701,8 +692,7 @@ impl<T: Config<I>, I: 'static> Bag<T, I> {
if *tail == node.id {
// this should never happen, but this check prevents one path to a worst case
// infinite loop.
debug_assert!(false, "system logic error: inserting a node who has the id of tail");
crate::log!(warn, "system logic error: inserting a node who has the id of tail");
defensive!("system logic error: inserting a node who has the id of tail");
return
};
}
Expand Down Expand Up @@ -753,16 +743,15 @@ impl<T: Config<I>, I: 'static> Bag<T, I> {
}
}

/// Sanity check this bag.
/// Check the internal state of the bag.
///
/// Should be called by the call-site, after any mutating operation on a bag. The call site of
/// this struct is always `List`.
///
/// * Ensures head has no prev.
/// * Ensures tail has no next.
/// * Ensures there are no loops, traversal from head to tail is correct.
#[cfg(feature = "std")]
fn sanity_check(&self) -> Result<(), &'static str> {
fn try_state(&self) -> Result<(), &'static str> {
frame_support::ensure!(
self.head()
.map(|head| head.prev().is_none())
Expand Down Expand Up @@ -801,7 +790,6 @@ impl<T: Config<I>, I: 'static> Bag<T, I> {
}

/// Check if the bag contains a node with `id`.
#[cfg(feature = "std")]
fn contains(&self, id: &T::AccountId) -> bool {
self.iter().any(|n| n.id() == id)
}
Expand Down Expand Up @@ -906,8 +894,7 @@ impl<T: Config<I>, I: 'static> Node<T, I> {
self.bag_upper
}

#[cfg(feature = "std")]
fn sanity_check(&self) -> Result<(), &'static str> {
fn try_state(&self) -> Result<(), &'static str> {
let expected_bag = Bag::<T, I>::get(self.bag_upper).ok_or("bag not found for node")?;

let id = self.id();
Expand Down
Loading