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

Commit 55c64bc

Browse files
libreloismelekes
andauthored
try-runtime: add cli option --export-proof (#12539)
* try-runtime: add cli option --export-proof * extract proof in raw json format * fix build * fix(try-runtime execute-block): wrong block parsing * fmt * apply suggestions * Update utils/frame/try-runtime/cli/src/lib.rs Co-authored-by: Anton <[email protected]> * Update utils/frame/try-runtime/cli/src/lib.rs Co-authored-by: Anton <[email protected]> * Update utils/frame/try-runtime/cli/src/lib.rs Co-authored-by: Anton <[email protected]> * Update utils/frame/try-runtime/cli/src/lib.rs Co-authored-by: Anton <[email protected]> * split off external dependencies * fmt * fix try-runtime compilation Co-authored-by: Anton <[email protected]>
1 parent ed82c87 commit 55c64bc

File tree

6 files changed

+61
-2
lines changed

6 files changed

+61
-2
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

utils/frame/try-runtime/cli/Cargo.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,12 @@ sp-weights = { version = "4.0.0", path = "../../../../primitives/weights" }
3030
frame-try-runtime = { optional = true, path = "../../../../frame/try-runtime" }
3131
substrate-rpc-client = { path = "../../rpc/client" }
3232

33-
parity-scale-codec = "3.0.0"
34-
hex = "0.4.3"
3533
clap = { version = "4.0.9", features = ["derive"] }
34+
hex = { version = "0.4.3", default-features = false }
3635
log = "0.4.17"
36+
parity-scale-codec = "3.0.0"
3737
serde = "1.0.136"
38+
serde_json = "1.0.85"
3839
zstd = { version = "0.11.2", default-features = false }
3940

4041
[dev-dependencies]

utils/frame/try-runtime/cli/src/commands/execute_block.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ where
134134
"TryRuntime_execute_block",
135135
&payload,
136136
full_extensions(),
137+
shared.export_proof,
137138
)?;
138139

139140
Ok(())

utils/frame/try-runtime/cli/src/commands/follow_chain.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,10 @@ where
150150
"TryRuntime_execute_block",
151151
(block, command.state_root_check, command.try_state.clone()).encode().as_ref(),
152152
full_extensions(),
153+
shared
154+
.export_proof
155+
.as_ref()
156+
.map(|path| path.as_path().join(&format!("{}.json", number))),
153157
);
154158

155159
if let Err(why) = result {

utils/frame/try-runtime/cli/src/commands/on_runtime_upgrade.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ where
5959
"TryRuntime_on_runtime_upgrade",
6060
command.checks.encode().as_ref(),
6161
Default::default(), // we don't really need any extensions here.
62+
shared.export_proof,
6263
)?;
6364

6465
let (weight, total_weight) = <(Weight, Weight) as Decode>::decode(&mut &*encoded_result)

utils/frame/try-runtime/cli/src/lib.rs

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -523,6 +523,12 @@ pub struct SharedParams {
523523
#[arg(long)]
524524
pub heap_pages: Option<u64>,
525525

526+
/// Path to a file to export the storage proof into (as a JSON).
527+
/// If several blocks are executed, the path is interpreted as a folder
528+
/// where one file per block will be written (named `{block_number}-{block_hash}`).
529+
#[clap(long)]
530+
pub export_proof: Option<PathBuf>,
531+
526532
/// Overwrite the `state_version`.
527533
///
528534
/// Otherwise `remote-externalities` will automatically set the correct state version.
@@ -863,6 +869,7 @@ pub(crate) fn state_machine_call_with_proof<Block: BlockT, HostFns: HostFunction
863869
method: &'static str,
864870
data: &[u8],
865871
extensions: Extensions,
872+
maybe_export_proof: Option<PathBuf>,
866873
) -> sc_cli::Result<(OverlayedChanges, Vec<u8>)> {
867874
use parity_scale_codec::Encode;
868875

@@ -891,6 +898,32 @@ pub(crate) fn state_machine_call_with_proof<Block: BlockT, HostFns: HostFunction
891898
let proof = proving_backend
892899
.extract_proof()
893900
.expect("A recorder was set and thus, a storage proof can be extracted; qed");
901+
902+
if let Some(path) = maybe_export_proof {
903+
let mut file = std::fs::File::create(&path).map_err(|e| {
904+
log::error!(
905+
target: LOG_TARGET,
906+
"Failed to create file {}: {:?}",
907+
path.to_string_lossy(),
908+
e
909+
);
910+
e
911+
})?;
912+
913+
log::info!(target: LOG_TARGET, "Writing storage proof to {}", path.to_string_lossy());
914+
915+
use std::io::Write as _;
916+
file.write_all(storage_proof_to_raw_json(&proof).as_bytes()).map_err(|e| {
917+
log::error!(
918+
target: LOG_TARGET,
919+
"Failed to write storage proof to {}: {:?}",
920+
path.to_string_lossy(),
921+
e
922+
);
923+
e
924+
})?;
925+
}
926+
894927
let proof_size = proof.encoded_size();
895928
let compact_proof = proof
896929
.clone()
@@ -951,3 +984,21 @@ pub(crate) fn rpc_err_handler(error: impl Debug) -> &'static str {
951984
log::error!(target: LOG_TARGET, "rpc error: {:?}", error);
952985
"rpc error."
953986
}
987+
988+
/// Converts a [`sp_state_machine::StorageProof`] into a JSON string.
989+
fn storage_proof_to_raw_json(storage_proof: &sp_state_machine::StorageProof) -> String {
990+
serde_json::Value::Object(
991+
storage_proof
992+
.to_memory_db::<sp_runtime::traits::BlakeTwo256>()
993+
.drain()
994+
.iter()
995+
.map(|(key, (value, _n))| {
996+
(
997+
format!("0x{}", hex::encode(key.as_bytes())),
998+
serde_json::Value::String(format!("0x{}", hex::encode(value))),
999+
)
1000+
})
1001+
.collect(),
1002+
)
1003+
.to_string()
1004+
}

0 commit comments

Comments
 (0)