Skip to content

Commit

Permalink
Merge branch 'rkhalil/op-compose' of github.com:risc0/zeth into rkhal…
Browse files Browse the repository at this point in the history
…il/stark2snark
  • Loading branch information
hashcashier committed Feb 12, 2024
2 parents 24905a7 + 3f7905a commit f75538f
Show file tree
Hide file tree
Showing 8 changed files with 96 additions and 27 deletions.
19 changes: 19 additions & 0 deletions Cargo.lock

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

7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,13 @@ cargo build -F metal --release
```console
cargo build -F cuda --release
```

#### docker (recommended)

If you wish to use the `--release` profile when building Zeth,
check out https://docs.docker.com/engine/install/ for a guide on how to install docker, which is required for reproducible builds of the zkVM binaries in Zeth.


#### Execution:

Run the built binary (instead of using `cargo run`) using:
Expand Down
1 change: 1 addition & 0 deletions host/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ zeth-primitives = { path = "../primitives" }

[dev-dependencies]
assert_cmd = "2.0"
predicates = "3.0"
rstest = "0.18"

[features]
Expand Down
17 changes: 13 additions & 4 deletions host/tests/cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use std::path::{Path, PathBuf};

use assert_cmd::Command;
use predicates::prelude::*;
use rstest::rstest;

fn file_prefix(path: &Path) -> &str {
Expand All @@ -28,14 +29,16 @@ fn build_ethereum(#[files("testdata/ethereum/*.json.gz")] path: PathBuf) {

Command::cargo_bin("zeth")
.unwrap()
.env("RUST_LOG", "info")
.args([
"build",
"--network=ethereum",
"--cache=testdata",
&format!("--block-number={}", block_number),
])
.assert()
.success();
.success()
.stderr(predicate::str::contains(" WARN ").not());
}

#[rstest]
Expand All @@ -44,21 +47,24 @@ fn build_optimism(#[files("testdata/optimism/*.json.gz")] path: PathBuf) {

Command::cargo_bin("zeth")
.unwrap()
.env("RUST_LOG", "info")
.args([
"build",
"--network=optimism",
"--cache=testdata",
&format!("--block-number={}", block_number),
])
.assert()
.success();
.success()
.stderr(predicate::str::contains(" WARN ").not());
}

#[rstest]
#[case(109279674, 6)]
fn build_optimism_derived(#[case] block_number: u64, #[case] block_count: u64) {
Command::cargo_bin("zeth")
.unwrap()
.env("RUST_LOG", "info")
.args([
"build",
"--network=optimism-derived",
Expand All @@ -67,11 +73,13 @@ fn build_optimism_derived(#[case] block_number: u64, #[case] block_count: u64) {
&format!("--block-count={}", block_count),
])
.assert()
.success();
.success()
.stderr(predicate::str::contains(" WARN ").not());

// test composition
Command::cargo_bin("zeth")
.unwrap()
.env("RUST_LOG", "info")
.args([
"build",
"--network=optimism-derived",
Expand All @@ -81,5 +89,6 @@ fn build_optimism_derived(#[case] block_number: u64, #[case] block_count: u64) {
"--composition=1",
])
.assert()
.success();
.success()
.stderr(predicate::str::contains(" WARN ").not());
}
8 changes: 4 additions & 4 deletions lib/src/builder/execute/ethereum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use core::{fmt::Debug, mem::take};

use anyhow::{anyhow, bail, Context};
#[cfg(not(target_os = "zkvm"))]
use log::trace;
use log::{debug, trace};
use revm::{
interpreter::Host,
primitives::{Account, Address, ResultAndState, SpecId, TransactTo, TxEnv},
Expand Down Expand Up @@ -78,9 +78,9 @@ impl TxExecStrategy<EthereumTxEssence> for EthTxExecStrategy {
)
.unwrap();

trace!("Block no. {}", header.number);
trace!(" EVM spec ID: {:?}", spec_id);
trace!(" Timestamp: {}", dt);
debug!("Block no. {}", header.number);
debug!(" EVM spec ID: {:?}", spec_id);
debug!(" Timestamp: {}", dt);
trace!(
" Transactions: {}",
block_builder.input.state_input.transactions.len()
Expand Down
8 changes: 4 additions & 4 deletions lib/src/builder/execute/optimism.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use core::{fmt::Debug, mem::take};

use anyhow::{anyhow, bail, Context, Result};
#[cfg(not(target_os = "zkvm"))]
use log::trace;
use log::{debug, trace};
use revm::{
interpreter::Host,
optimism,
Expand Down Expand Up @@ -81,9 +81,9 @@ impl TxExecStrategy<OptimismTxEssence> for OpTxExecStrategy {
)
.unwrap();

trace!("Block no. {}", header.number);
trace!(" EVM spec ID: {:?}", spec_id);
trace!(" Timestamp: {}", dt);
debug!("Block no. {}", header.number);
debug!(" EVM spec ID: {:?}", spec_id);
debug!(" Timestamp: {}", dt);
trace!(
" Transactions: {}",
block_builder.input.state_input.transactions.len()
Expand Down
30 changes: 30 additions & 0 deletions lib/src/optimism/composition.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,28 +28,58 @@ use crate::optimism::{batcher::BlockId, DeriveOutput};
pub type ImageId = [u32; 8];

#[derive(Debug, Clone, Deserialize, Serialize)]
/// The input given to the composition predicate
pub struct ComposeInput {
/// The image id used for op block building/transaction execution
pub block_image_id: ImageId,
/// The image id used for op block derivation
pub derive_image_id: ImageId,
/// The image id of the composition guest itself
pub compose_image_id: ImageId,
/// The “operation” which this invocation of the guest should perform
/// (prep/lift/join/finish)
pub operation: ComposeInputOperation,
/// The Merkle-tree root of the Ethereum blockchain using which all derivation should
/// be performed.
pub eth_chain_merkle_root: mmr::Hash,
}

#[derive(Debug, Clone, Deserialize, Serialize)]
pub enum ComposeInputOperation {
/// Takes a chain of ethereum blocks and inserts them into a Merkle-tree,
/// resulting in a composition statement about an eth_chain_root value.
/// This operation can also be performed incrementally when given a Merkle
/// mountain range (and corresponding proof) as input if the ethereum chain
/// is too large for one session.
PREP {
eth_blocks: Vec<Header>,
prior_prep: Option<(ComposeOutput, MerkleMountainRange)>,
},
/// Lifting converts a block derivation proof into an equivalent proof, only after
/// verifying that the last ethereum block read during derivation belongs to the
/// continuous chain committed to under eth_chain_root. This is done using a
/// merkle inclusion proof.
LIFT {
derivation: DeriveOutput,
eth_tail_proof: MerkleProof,
},
/// Where the stitching logic happens. Joining can only succeed if:
/// 1. The optimism “tail” of the left proof is equal to the optimism “head” of the
/// right proof (i.e. the optimism blocks in the right proof’s chain start off
/// where the left proof chain ends).
/// 2. The ethereum blocks used for derivation in both proofs are on the same chain.
/// (security)
/// The first condition is checked during the join operation, while the second
/// condition is already validated during the pre-requisite “lift” operation using the
/// eth_chain_root.
JOIN {
left: ComposeOutput,
right: ComposeOutput,
},
/// Finalization takes as input a composition “preparation” proof about the merkle
/// root eth_chain_root, asserting its commitment to a continuous chain of
/// ethereum blocks, and a composition “aggregation” proof about the derivation of
/// a series of op-blocks from the ethereum blocks under eth_chain_root.
FINISH {
prep: ComposeOutput,
aggregate: ComposeOutput,
Expand Down
33 changes: 18 additions & 15 deletions lib/src/optimism/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -303,22 +303,25 @@ impl<D: BatcherDb> DeriveMachine<D> {
// The first transaction MUST be a L1 attributes deposited transaction,
// followed by an array of zero-or-more user-deposited transactions.
let l1_attributes_tx = self.derive_l1_attributes_deposited_tx(&op_batch);
// TODO: revise that skipping undecodable transactions is part of spec
let decoded_batch_transactions: Vec<_> = op_batch
.0
.transactions
.iter()
.filter_map(|raw_tx| {
match Transaction::<OptimismTxEssence>::decode_bytes(raw_tx) {
Ok(tx) => Some(tx),
Err(_err) => {
#[cfg(not(target_os = "zkvm"))]
log::warn!("Skipping undecodable transaction: {:#}", _err);
None
}

let mut decoded_batch_transactions = vec![];
let mut decoding_error = false;
for raw_tx in &op_batch.0.transactions {
match Transaction::<OptimismTxEssence>::decode_bytes(raw_tx) {
Ok(tx) => {
decoded_batch_transactions.push(tx);
}
})
.collect();
Err(_err) => {
#[cfg(not(target_os = "zkvm"))]
log::warn!("Skipping undecodable transaction: {:#}", _err);
decoding_error = true;
break;
}
}
}
if decoding_error {
continue;
}

let derived_transactions: Vec<_> = once(l1_attributes_tx)
.chain(deposits)
Expand Down

0 comments on commit f75538f

Please sign in to comment.