Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: trace decoder tests #596

Merged
merged 9 commits into from
Sep 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
112 changes: 69 additions & 43 deletions Cargo.lock

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

14 changes: 13 additions & 1 deletion trace_decoder/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,26 @@ zk_evm_common = { workspace = true }

[dev-dependencies]
alloy = { workspace = true }
alloy-compat = "0.1.0"
0xaatif marked this conversation as resolved.
Show resolved Hide resolved
assert2 = "0.3.15"
camino = "1.1.9"
criterion = { workspace = true }
glob = "0.3.1"
libtest-mimic = "0.7.3"
plonky2_maybe_rayon = { workspace = true }
pretty_env_logger = { workspace = true }
prover = { workspace = true }
rstest = "0.21.0"
serde_json = { workspace = true }
serde_path_to_error = { workspace = true }

[[bench]]
name = "block_processing"
harness = false

[[test]]
name = "consistent-with-header"
harness = false

[[test]]
name = "simulate-execution"
harness = false
1 change: 1 addition & 0 deletions trace_decoder/src/cases/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Test vectors for unit tests in [../wire](../wire.rs).
11 changes: 5 additions & 6 deletions trace_decoder/src/type1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -380,12 +380,11 @@ fn finish_stack(v: &mut Vec<Node>) -> anyhow::Result<Execution> {

#[test]
fn test_tries() {
for (ix, case) in serde_json::from_str::<Vec<super::Case>>(include_str!(
"../tests/data/tries/zero_jerigon.json"
))
.unwrap()
.into_iter()
.enumerate()
for (ix, case) in
serde_json::from_str::<Vec<super::Case>>(include_str!("cases/zero_jerigon.json"))
.unwrap()
.into_iter()
.enumerate()
{
println!("case {}", ix);
let instructions = crate::wire::parse(&case.bytes).unwrap();
Expand Down
11 changes: 5 additions & 6 deletions trace_decoder/src/type2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -226,12 +226,11 @@ fn iter_leaves(node: Node) -> Box<dyn Iterator<Item = (BitVec, Either<[u8; 32],

#[test]
fn test_tries() {
for (ix, case) in serde_json::from_str::<Vec<super::Case>>(include_str!(
"../tests/data/tries/hermez_cdk_erigon.json"
))
.unwrap()
.into_iter()
.enumerate()
for (ix, case) in
serde_json::from_str::<Vec<super::Case>>(include_str!("cases/hermez_cdk_erigon.json"))
.unwrap()
.into_iter()
.enumerate()
{
println!("case {}", ix);
let instructions = crate::wire::parse(&case.bytes).unwrap();
Expand Down
1 change: 1 addition & 0 deletions trace_decoder/tests/cases/.gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.json linguist-generated=true
83 changes: 83 additions & 0 deletions trace_decoder/tests/common/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
use std::{fs::File, path::Path};

use alloy::rpc::types::Header;
use anyhow::{ensure, Context as _};
use camino::Utf8Path;
use prover::BlockProverInput;
use serde::de::DeserializeOwned;
use trace_decoder::{BlockTrace, OtherBlockData};

pub fn cases() -> anyhow::Result<Vec<Case>> {
print!("loading test vectors...");
let ret = glob::glob(concat!(
env!("CARGO_MANIFEST_DIR"),
"/tests/cases/*_header.json"
))
.expect("valid glob pattern")
.map(|res| {
let header_path = res.context("filesystem error discovering test vectors")?;
Case::load(&header_path).context(format!(
"couldn't load case for header {}",
header_path.display()
))
})
.collect();
println!("done");
ret
}

/// Test cases consist of [`BlockProverInput`] collected from `zero_bin`'s `rpc`
/// command, and the corresponding block header, fetched directly over RPC.
///
/// In directory above, the files are stored alongside one another, as, for
/// example:
/// - `b4_dev.json`
/// - `b4_dev_header.json`
pub struct Case {
/// `b4_dev`, in the above example.
///
/// Used as a test identifier.
pub name: String,
#[allow(unused)] // only used by one of the test binaries
pub header: Header,
pub trace: BlockTrace,
pub other: OtherBlockData,
}

impl Case {
fn load(header_path: &Path) -> anyhow::Result<Self> {
let header_path = Utf8Path::from_path(header_path).context("non-UTF-8 path")?;
let base = Utf8Path::new(
header_path
.as_str()
.strip_suffix("_header.json")
.context("inconsistent header name")?, // sync with glob call
);
// for some reason these are lists...
let mut headers = json::<Vec<Header>>(header_path)?;
let mut bpis = json::<Vec<BlockProverInput>>(base.with_extension("json"))?;
ensure!(headers.len() == 1, "bad header file");
ensure!(bpis.len() == 1, "bad bpi file");
let BlockProverInput {
block_trace,
other_data,
} = bpis.remove(0);
anyhow::Ok(Case {
name: base.file_name().context("inconsistent base name")?.into(),
header: headers.remove(0),
trace: block_trace,
other: other_data,
})
}
}

fn json<T: DeserializeOwned>(path: impl AsRef<Path>) -> anyhow::Result<T> {
fn _imp<T: DeserializeOwned>(path: impl AsRef<Path>) -> anyhow::Result<T> {
let file = File::open(path)?;
Ok(serde_path_to_error::deserialize(
&mut serde_json::Deserializer::from_reader(file),
)?)
}

_imp(&path).context(format!("couldn't load {}", path.as_ref().display()))
}
Loading
Loading