-
Notifications
You must be signed in to change notification settings - Fork 5
State Forking
This document explains how to get the state of our TestNet or MainNet. This can be useful in the following cases:
- Testing runtime upgrades
- Debugging issues that are not replicable with the Dev chain spec
The state from our networks come in two formats, as a chain spec or as a state snapshot. Both formats have their uses cases
From root folder execute the following command:
./scripts/state_forking.sh
By default the script will checkout to the latest git tag and get Porcini's state.
Getting Root's state and using a different tag can be done like this:
# We are forking root at the tag v1.32.0
./scripts/state_forking.sh -c root -t v1.32.0
# Now it won't do a tag switch
./scripts/state_forking.sh -i
./scripts/state_forking.sh --help
The script generates two chain specifications. One untouched but unrunable and one modified but runable.
This chain specification contains the full and true state of a network. Because it contains all the data, it is virtually unrunable and should not be used unless there is a specific need for it. You can find this file under the name porcini_chain_state.json
or root_chain_state.json
.
This chain specification was made by combining the Dev chain specification together with the previous mentioned untouched chain specification. The end result is a fully runable chain that contains most of the data. This chain specification is the one that should be used and you can find it under the name dev_chain_state.json
.
Run the generate node binary together with the generate dev chain specification. Command:
./output/binary --chain ./output/dev_chain_state.json --alice --tmp
Our tests are running in a controlled environment with mocked data. This is OK for most situations but there are cases where we need use actual data to properly debug an issue. This can be done by using the generated state snapshot together with writing tests inside the remote_tests
namespace. This means that you can run and debug any test or arbitrary code with Porcini's or Root's data which is perfect for inspecting babe, staking or grandpa data since these things are not available when the chain spec is used.
Set the SNAP
environment variable to point to the state.top
file path and execute the following command:
cargo test --all-features
Currently we only test our migrations with the snapshot but you can easily add your own tests or custom logic by changing the run_migrations
test inside the remote_tests
namespace.
This is how it looks currently (./runtime/migrations/mod.rs):
#[cfg(all(test, feature = "try-runtime"))]
mod remote_tests {
use super::*;
use crate::{migrations::AllMigrations, Block};
use remote_externalities::{Builder, Mode, OfflineConfig};
use std::env::var;
#[tokio::test]
async fn run_migrations() {
//std::env::set_var("SNAP", "/full/path/to/snap.top");
let Some(state_snapshot) = var("SNAP").map(|s| s.into()).ok() else {
return;
};
let mode = Mode::Offline(OfflineConfig { state_snapshot });
let mut ext = Builder::<Block>::default().mode(mode).build().await.unwrap();
ext.execute_with(|| {
AllMigrations::pre_upgrade().unwrap();
AllMigrations::on_runtime_upgrade();
AllMigrations::post_upgrade().unwrap();
});
}
}
If you don't want to use the environment variable you can uncomment the set_var
line and replace the default path with your one. Example:
- //std::env::set_var("SNAP", "/full/path/to/snap.top");
+ std::env::set_var("SNAP", "/home/marko/futureverse/seed/snap.top");