forked from matter-labs/zksync-era
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(prover): File-info tool to help prover debugging (matter-labs#1216)
## What ❔ * a helper tool to see the contents of the prover files - it auto-guesses the file type and displays information. ## Why ❔ * to make prover debugging easier ```shell cargo run --release file-info 1_0_1_Scheduler_0.bin ``` ![image](https://github.com/matter-labs/zksync-era/assets/128217157/d87d84cc-a16b-43f7-aebe-5da6a6d722dd)
- Loading branch information
Showing
5 changed files
with
329 additions
and
0 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
[package] | ||
name = "tools" | ||
version = "0.1.0" | ||
edition = "2021" | ||
|
||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
|
||
[dependencies] | ||
|
||
clap = { version = "4.4.6", features = ["derive"] } | ||
tracing = "0.1" | ||
tracing-subscriber = { version = "0.3", features = ["env-filter"] } | ||
zksync_prover_fri_types = {path = "../prover_fri_types"} | ||
bincode = "1.0" | ||
colored = "2.0" | ||
zksync_prover_interface = { path = "../../core/lib/prover_interface" } | ||
hex = "0.4" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
# Tool to better understand and debug provers | ||
|
||
For now, it has only one command 'file-info' | ||
|
||
``` | ||
cargo run --release file-info /zksync-era/prover/artifacts/proofs_fri/l1_batch_proof_1.bin | ||
``` | ||
|
||
Example outputs: | ||
|
||
``` | ||
L1 proof | ||
AUX info: | ||
L1 msg linear hash: [163, 243, 172, 16, 189, 59, 100, 227, 249, 46, 226, 220, 82, 135, 213, 208, 221, 228, 49, 46, 121, 136, 78, 163, 15, 155, 199, 82, 64, 24, 172, 198] | ||
Rollup_state_diff_for_compression: [157, 150, 29, 193, 105, 162, 176, 61, 83, 241, 72, 206, 68, 20, 143, 69, 119, 162, 138, 101, 80, 139, 193, 211, 188, 250, 156, 86, 254, 148, 117, 60] | ||
bootloader_heap_initial_content: [112, 2, 120, 255, 156, 227, 172, 92, 134, 48, 247, 243, 148, 241, 11, 122, 6, 189, 46, 164, 89, 78, 209, 118, 115, 239, 195, 15, 225, 143, 97, 204] | ||
events_queue_state: [202, 78, 244, 233, 150, 17, 247, 25, 183, 51, 245, 110, 135, 31, 115, 109, 84, 193, 17, 1, 153, 32, 39, 199, 102, 25, 63, 216, 220, 68, 212, 233] | ||
Inputs: [Fr(0x00000000775db828700e0ebbe0384f8a017598a271dfb6c96ebb2baf22a7a572)] | ||
``` | ||
|
||
``` | ||
== Circuit == | ||
Type: basic. Id: 1 (Scheduler) | ||
Geometry: CSGeometry { num_columns_under_copy_permutation: 130, num_witness_columns: 0, num_constant_columns: 4, max_allowed_constraint_degree: 8 } | ||
Circuit size: trace length: Some(1048576) something??: Some(100663296) | ||
Scheduler witness info | ||
Previous block data: | ||
Enumeration counter: 25 | ||
State root: [107, 233, 138, 154, 21, 134, 189, 220, 183, 250, 117, 243, 103, 124, 71, 221, 160, 136, 249, 25, 197, 109, 8, 75, 26, 12, 81, 109, 36, 56, 30, 17] | ||
Block meta parameters | ||
bootloader code hash: 452367551810219221093730953379759186922674186246309239546886848509599206765 | ||
aa code hash: 452349823575802367618424269668644286404749728714566974110193150711820505769 | ||
Previous block meta hash: [63, 236, 0, 236, 23, 236, 175, 242, 75, 187, 203, 193, 88, 80, 202, 53, 40, 206, 28, 40, 125, 58, 53, 254, 233, 122, 108, 101, 101, 88, 102, 193] | ||
Previous block aux hash: [200, 12, 70, 33, 103, 13, 251, 174, 96, 165, 135, 138, 34, 75, 249, 81, 93, 86, 110, 52, 30, 172, 198, 51, 155, 82, 86, 137, 156, 215, 11, 119] | ||
EIP 4844 - witnesses: None | ||
EIP 4844 - proofs: 0 | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,250 @@ | ||
use std::fs; | ||
|
||
use clap::{Parser, Subcommand}; | ||
use colored::Colorize; | ||
use tracing::level_filters::LevelFilter; | ||
use zksync_prover_fri_types::{ | ||
circuit_definitions::{ | ||
boojum::{ | ||
field::goldilocks::{GoldilocksExt2, GoldilocksField}, | ||
gadgets::recursion::recursive_tree_hasher::CircuitGoldilocksPoseidon2Sponge, | ||
}, | ||
circuit_definitions::{ | ||
base_layer::ZkSyncBaseLayerCircuit, recursion_layer::ZkSyncRecursiveLayerCircuit, | ||
}, | ||
zkevm_circuits::scheduler::input::SchedulerCircuitInstanceWitness, | ||
}, | ||
CircuitWrapper, FriProofWrapper, | ||
}; | ||
use zksync_prover_interface::outputs::L1BatchProofForL1; | ||
|
||
#[derive(Debug, Parser)] | ||
#[command( | ||
author = "Matter Labs", | ||
version, | ||
about = "Debugging tools for prover related things", | ||
long_about = None | ||
)] | ||
|
||
struct Cli { | ||
#[command(subcommand)] | ||
command: Command, | ||
} | ||
|
||
#[derive(Debug, Subcommand)] | ||
enum Command { | ||
#[command(name = "file-info")] | ||
FileInfo { file_path: String }, | ||
} | ||
|
||
fn pretty_print_size_hint(size_hint: (Option<usize>, Option<usize>)) { | ||
println!( | ||
"Circuit size: trace length: {:?} something??: {:?}", | ||
size_hint.0, size_hint.1 | ||
); | ||
} | ||
|
||
fn pretty_print_scheduler_witness( | ||
witness: &SchedulerCircuitInstanceWitness< | ||
GoldilocksField, | ||
CircuitGoldilocksPoseidon2Sponge, | ||
GoldilocksExt2, | ||
>, | ||
) { | ||
println!("Scheduler witness info"); | ||
println!(" Previous block data: "); | ||
println!( | ||
" Enumeration counter: {:?}", | ||
witness.prev_block_data.per_shard_states[0].enumeration_counter[0] | ||
); | ||
println!( | ||
" State root: 0x{}", | ||
hex::encode(witness.prev_block_data.per_shard_states[0].state_root) | ||
); | ||
|
||
println!(" Block meta parameters"); | ||
println!( | ||
" bootloader code hash: {:?}", | ||
witness.block_meta_parameters.bootloader_code_hash | ||
); | ||
println!( | ||
" aa code hash: {:?}", | ||
witness.block_meta_parameters.default_aa_code_hash | ||
); | ||
|
||
println!( | ||
" Previous block meta hash: 0x{}", | ||
hex::encode(witness.previous_block_meta_hash) | ||
); | ||
println!( | ||
" Previous block aux hash: 0x{}", | ||
hex::encode(witness.previous_block_aux_hash) | ||
); | ||
|
||
println!(" EIP 4844 - witnesses: {:?}", witness.eip4844_witnesses); | ||
println!(" EIP 4844 - proofs: {:?}", witness.eip4844_proofs.len()); | ||
} | ||
|
||
fn pretty_print_circuit_wrapper(circuit: &CircuitWrapper) { | ||
println!(" == Circuit =="); | ||
match circuit { | ||
CircuitWrapper::Base(circuit) => { | ||
println!( | ||
"Type: basic. Id: {:?} ({})", | ||
circuit.numeric_circuit_type(), | ||
circuit.short_description().bold() | ||
); | ||
println!("Geometry: {:?}", circuit.geometry()); | ||
pretty_print_size_hint(circuit.size_hint()); | ||
|
||
match circuit { | ||
ZkSyncBaseLayerCircuit::MainVM(_) => todo!(), | ||
ZkSyncBaseLayerCircuit::CodeDecommittmentsSorter(_) => todo!(), | ||
ZkSyncBaseLayerCircuit::CodeDecommitter(_) => todo!(), | ||
ZkSyncBaseLayerCircuit::LogDemuxer(_) => todo!(), | ||
ZkSyncBaseLayerCircuit::KeccakRoundFunction(_) => todo!(), | ||
ZkSyncBaseLayerCircuit::Sha256RoundFunction(_) => todo!(), | ||
ZkSyncBaseLayerCircuit::ECRecover(circuit) => { | ||
println!("Expected public input: {:?}", circuit.expected_public_input); | ||
println!("Max ECRecovers per circuit: {:?}", circuit.config); | ||
} | ||
ZkSyncBaseLayerCircuit::RAMPermutation(_) => todo!(), | ||
ZkSyncBaseLayerCircuit::StorageSorter(_) => todo!(), | ||
ZkSyncBaseLayerCircuit::StorageApplication(circuit) => circuit.debug_witness(), | ||
ZkSyncBaseLayerCircuit::EventsSorter(_) => todo!(), | ||
ZkSyncBaseLayerCircuit::L1MessagesSorter(_) => todo!(), | ||
ZkSyncBaseLayerCircuit::L1MessagesHasher(_) => todo!(), | ||
} | ||
} | ||
CircuitWrapper::Recursive(circuit) => { | ||
println!( | ||
"Type: basic. Id: {:?} ({})", | ||
circuit.numeric_circuit_type(), | ||
circuit.short_description().bold() | ||
); | ||
println!("Geometry: {:?}", circuit.geometry()); | ||
pretty_print_size_hint(circuit.size_hint()); | ||
match circuit { | ||
ZkSyncRecursiveLayerCircuit::SchedulerCircuit(circuit) => { | ||
//println!("Expected public input: {:?}", circuit.witness); | ||
pretty_print_scheduler_witness(&circuit.witness); | ||
} | ||
ZkSyncRecursiveLayerCircuit::NodeLayerCircuit(_) => todo!(), | ||
ZkSyncRecursiveLayerCircuit::LeafLayerCircuitForMainVM(_) => todo!(), | ||
ZkSyncRecursiveLayerCircuit::LeafLayerCircuitForCodeDecommittmentsSorter(_) => { | ||
todo!() | ||
} | ||
ZkSyncRecursiveLayerCircuit::LeafLayerCircuitForCodeDecommitter(_) => todo!(), | ||
ZkSyncRecursiveLayerCircuit::LeafLayerCircuitForLogDemuxer(_) => todo!(), | ||
ZkSyncRecursiveLayerCircuit::LeafLayerCircuitForKeccakRoundFunction(_) => todo!(), | ||
ZkSyncRecursiveLayerCircuit::LeafLayerCircuitForSha256RoundFunction(_) => todo!(), | ||
ZkSyncRecursiveLayerCircuit::LeafLayerCircuitForECRecover(_) => todo!(), | ||
ZkSyncRecursiveLayerCircuit::LeafLayerCircuitForRAMPermutation(_) => todo!(), | ||
ZkSyncRecursiveLayerCircuit::LeafLayerCircuitForStorageSorter(_) => todo!(), | ||
ZkSyncRecursiveLayerCircuit::LeafLayerCircuitForStorageApplication(_) => todo!(), | ||
ZkSyncRecursiveLayerCircuit::LeafLayerCircuitForEventsSorter(_) => todo!(), | ||
ZkSyncRecursiveLayerCircuit::LeafLayerCircuitForL1MessagesSorter(_) => todo!(), | ||
ZkSyncRecursiveLayerCircuit::LeafLayerCircuitForL1MessagesHasher(_) => todo!(), | ||
} | ||
} | ||
CircuitWrapper::Eip4844(_) => { | ||
println!("Type: eip4844") | ||
} | ||
} | ||
} | ||
|
||
fn pretty_print_proof(result: &FriProofWrapper) { | ||
println!("{}", "== FRI proof ==".to_string().bold()); | ||
match result { | ||
FriProofWrapper::Base(proof) => { | ||
println!( | ||
"Basic proof {} {}", | ||
proof.numeric_circuit_type(), | ||
proof.short_description() | ||
); | ||
} | ||
FriProofWrapper::Recursive(proof) => { | ||
println!( | ||
"Recursive proof {} {}", | ||
proof.numeric_circuit_type(), | ||
proof.short_description() | ||
); | ||
|
||
let proof = proof.clone().into_inner(); | ||
println!("Proof config: {:?}", proof.proof_config); | ||
println!("Proof public inputs: {:?}", proof.public_inputs); | ||
} | ||
FriProofWrapper::Eip4844(_) => { | ||
println!("4844 blob proof",); | ||
} | ||
} | ||
} | ||
|
||
fn pretty_print_l1_proof(result: &L1BatchProofForL1) { | ||
println!("{}", "== Snark wrapped L1 proof ==".to_string().bold()); | ||
println!("AUX info:"); | ||
println!( | ||
" L1 msg linear hash: 0x{}", | ||
hex::encode(result.aggregation_result_coords[0]) | ||
); | ||
println!( | ||
" Rollup_state_diff_for_compression: 0x{}", | ||
hex::encode(result.aggregation_result_coords[1]) | ||
); | ||
println!( | ||
" bootloader_heap_initial_content: 0x{}", | ||
hex::encode(result.aggregation_result_coords[2]) | ||
); | ||
println!( | ||
" events_queue_state: 0x{}", | ||
hex::encode(result.aggregation_result_coords[3]) | ||
); | ||
|
||
println!("Inputs: {:?}", result.scheduler_proof.inputs); | ||
println!(" This proof will pass on L1, if L1 executor computes the block commitment that is matching exactly the Inputs value above"); | ||
} | ||
|
||
fn file_info(path: String) { | ||
println!("Reading file {} and guessing the type.", path.bold()); | ||
|
||
let bytes = fs::read(path).unwrap(); | ||
|
||
// Parsing stuff from `prover_jobs_fri` directory. | ||
let maybe_circuit: Option<CircuitWrapper> = bincode::deserialize(&bytes).ok(); | ||
if let Some(circuit) = maybe_circuit { | ||
println!(" Parsing file as CircuitWrapper."); | ||
pretty_print_circuit_wrapper(&circuit); | ||
return; | ||
} | ||
println!(" NOT a CircuitWrapper."); | ||
let maybe_fri_proof: Option<FriProofWrapper> = bincode::deserialize(&bytes).ok(); | ||
if let Some(fri_proof) = maybe_fri_proof { | ||
println!(" Parsing file as FriProofWrapper."); | ||
pretty_print_proof(&fri_proof); | ||
return; | ||
} | ||
println!(" NOT a FriProofWrapper."); | ||
|
||
let maybe_snark_proof: Option<L1BatchProofForL1> = bincode::deserialize(&bytes).ok(); | ||
if let Some(snark_proof) = maybe_snark_proof { | ||
println!(" Parsing file as L1BatchProofForL1."); | ||
pretty_print_l1_proof(&snark_proof) | ||
} else { | ||
println!(" NOT a L1BatchProof."); | ||
} | ||
} | ||
|
||
fn main() { | ||
tracing_subscriber::fmt() | ||
.with_env_filter( | ||
tracing_subscriber::EnvFilter::builder() | ||
.with_default_directive(LevelFilter::INFO.into()) | ||
.from_env_lossy(), | ||
) | ||
.init(); | ||
|
||
let opt = Cli::parse(); | ||
match opt.command { | ||
Command::FileInfo { file_path } => file_info(file_path), | ||
} | ||
} |