Skip to content

Commit

Permalink
Add flag to see storage diff if idemptotent check fails (#78)
Browse files Browse the repository at this point in the history
When the idempotent migration check fails, users see this unhelpful
error message:

```
❌ Migrations are not idempotent. Selectively remove migrations from Executive until you find the culprit.
```

This PR implements a flag to enable printing the differences in storage.
It is disabled by default because users can ignore the "idempotent"
warning if they want to. If the flag is disabled there is a log that
suggests enabling it, improving the old message.

![Captura desde 2024-02-20
13-59-48](https://github.com/paritytech/try-runtime-cli/assets/44604217/1ae51887-6d26-411a-8874-23924b5cb536)

---------

Co-authored-by: Oliver Tale-Yazdi <[email protected]>
Co-authored-by: Liam Aharon <[email protected]>
  • Loading branch information
3 people authored Feb 27, 2024
1 parent 7abe31b commit 8762d74
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 7 deletions.
46 changes: 42 additions & 4 deletions Cargo.lock

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

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ resolver = "2"
members = ["cli", "core"]

[workspace.package]
version = "0.5.4"
version = "0.6.0"
authors = ["Parity Technologies <[email protected]>"]
description = "Substrate's programmatic testing framework."
edition = "2021"
Expand Down
1 change: 1 addition & 0 deletions core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ sp-weights = { workspace = true }

substrate-rpc-client = { workspace = true }
paris = "1.5.15"
similar-asserts = "1.5.0"

[dev-dependencies]
assert_cmd = { workspace = true }
Expand Down
39 changes: 37 additions & 2 deletions core/src/commands/on_runtime_upgrade.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

use std::{fmt::Debug, str::FromStr};
use std::{collections::BTreeMap, fmt::Debug, str::FromStr};

use bytesize::ByteSize;
use frame_try_runtime::UpgradeCheckSelect;
Expand All @@ -24,7 +24,7 @@ use parity_scale_codec::Encode;
use sc_executor::sp_wasm_interface::HostFunctions;
use sp_core::{hexdisplay::HexDisplay, Hasher};
use sp_runtime::traits::{Block as BlockT, HashingFor, NumberFor};
use sp_state_machine::{CompactProof, StorageProof};
use sp_state_machine::{CompactProof, OverlayedChanges, StorageProof};

use crate::{
build_executor,
Expand Down Expand Up @@ -69,6 +69,11 @@ pub struct Command {
/// Whether to disable migration idempotency checks
#[clap(long, default_value = "false", default_missing_value = "true")]
pub disable_idempotency_checks: bool,

/// When migrations are detected as not idempotent, enabling this will output a diff of the
/// storage before and after running the same set of migrations the second time.
#[clap(long, default_value = "false", default_missing_value = "true")]
pub print_storage_diff: bool,
}

// Runs the `on-runtime-upgrade` command.
Expand Down Expand Up @@ -187,6 +192,7 @@ where
colorize_string("<bold><blue>-------------------------------------------------------------------")
);
let (oc_pre_root, _) = overlayed_changes.storage_root(&ext.backend, ext.state_version);
overlayed_changes.start_transaction();
match state_machine_call_with_proof::<Block, HostFns>(
&ext,
&mut overlayed_changes,
Expand All @@ -202,6 +208,21 @@ where
overlayed_changes.storage_root(&ext.backend, ext.state_version);
if oc_pre_root != oc_post_root {
log::error!("❌ Migrations are not idempotent. Selectively remove migrations from Executive until you find the culprit.");
if command.print_storage_diff {
log::info!("Changed storage keys:");
let changes_after =
collect_storage_changes_as_hex::<Block>(&overlayed_changes);
overlayed_changes.rollback_transaction().expect(
"Migrations must not rollback transactions that they did not open",
);
let changes_before =
collect_storage_changes_as_hex::<Block>(&overlayed_changes);

similar_asserts::assert_eq!(changes_before, changes_after);
} else {
log::error!("Run with --print-storage-diff to see list of changed storage keys.");
}

false
} else {
// Exeuction was OK and state root didn't change
Expand Down Expand Up @@ -366,3 +387,17 @@ fn analyse_ref_time(ref_time_results: RefTimeInfo, no_weight_warnings: bool) ->
WeightSafety::ProbablySafe
}
}

fn collect_storage_changes_as_hex<Block: BlockT>(
overlayed_changes: &OverlayedChanges<HashingFor<Block>>,
) -> BTreeMap<String, String> {
overlayed_changes
.changes()
.filter_map(|(key, entry)| {
Some((
HexDisplay::from(key).to_string(),
HexDisplay::from(entry.value_ref().as_ref()?).to_string(),
))
})
.collect()
}

0 comments on commit 8762d74

Please sign in to comment.