diff --git a/Cargo.lock b/Cargo.lock index b7a3c13b0..76b36e89c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "Inflector" @@ -13282,8 +13282,10 @@ dependencies = [ "serde", "serde_json", "serde_with", + "strata-primitives", "strata-reth-evm", "strata-reth-primitives", + "strata-state", "strata-zkvm", "thiserror", ] diff --git a/bin/prover-client/src/prover.rs b/bin/prover-client/src/prover.rs index 8f97a5cbd..879694599 100644 --- a/bin/prover-client/src/prover.rs +++ b/bin/prover-client/src/prover.rs @@ -5,7 +5,7 @@ use std::{ use strata_db::traits::ProofDatabase; use strata_primitives::proof::{ProofContext, ProofKey, ProofZkVm}; -use strata_proofimpl_evm_ee_stf::ELProofInput; +use strata_proofimpl_evm_ee_stf::EvmBlockStfInput; use strata_rocksdb::{prover::db::ProofDb, DbOpsConfig}; use strata_state::l1::L1BlockId; use strata_zkvm::{ProofReceipt, ProofType, ZkVmHost, ZkVmInputBuilder}; @@ -22,7 +22,6 @@ use crate::{ }, proving_ops::btc_ops::get_pm_rollup_params, }; - #[derive(Debug, Clone)] #[allow(clippy::large_enum_variant)] enum ProvingTaskState { @@ -98,11 +97,15 @@ where { let (zkvm_input, proof_type) = match zkvm_input { ZkVmInput::ElBlock(el_input) => { - let el_input: ELProofInput = bincode::deserialize(&el_input.data)?; - ( - Vm::Input::new().write_serde(&el_input)?.build()?, - ProofType::Compressed, - ) + let el_inputs: Vec = bincode::deserialize(&el_input.data)?; + let mut input_builder = Vm::Input::new(); + + input_builder.write_serde(&el_inputs.len())?; + for el_input in el_inputs { + input_builder.write_serde(&el_input)?; + } + + (input_builder.build()?, ProofType::Compressed) } ZkVmInput::BtcBlock(block, rollup_params) => ( diff --git a/bin/prover-client/src/proving_ops/cl_ops.rs b/bin/prover-client/src/proving_ops/cl_ops.rs index 792f9fad6..98f6fa942 100644 --- a/bin/prover-client/src/proving_ops/cl_ops.rs +++ b/bin/prover-client/src/proving_ops/cl_ops.rs @@ -68,7 +68,9 @@ impl ProvingOperations for ClOperations { task_tracker: Arc, input: Self::Input, ) -> Result { - let el_task_id = self.el_dispatcher.create_task(input.block_num).await?; + // Create proving task for the corresponding EL block + let el_block_range = (input.block_num, input.block_num); + let el_task_id = self.el_dispatcher.create_task(el_block_range).await?; let prover_input = ZkVmInput::ClBlock(input); diff --git a/bin/prover-client/src/proving_ops/el_ops.rs b/bin/prover-client/src/proving_ops/el_ops.rs index 6c43dc121..f4bbee691 100644 --- a/bin/prover-client/src/proving_ops/el_ops.rs +++ b/bin/prover-client/src/proving_ops/el_ops.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use alloy_rpc_types::Block; use async_trait::async_trait; use jsonrpsee::{core::client::ClientT, http_client::HttpClient, rpc_params}; -use strata_proofimpl_evm_ee_stf::ELProofInput; +use strata_proofimpl_evm_ee_stf::EvmBlockStfInput; use tracing::debug; use uuid::Uuid; @@ -29,31 +29,38 @@ impl ElOperations { #[async_trait] impl ProvingOperations for ElOperations { - /// Used serialized [`ELProofInput`] because [`ELProofInput::parent_state_trie`] contains - /// RefCell, which is not Sync or Send + /// Used serialized [`EvmBlockStfInput`] because [`EvmBlockStfInput::pre_state_trie`] + /// contains RefCell, which is not Sync or Send type Input = Vec; - type Params = u64; + type Params = (u64, u64); fn proving_task_type(&self) -> ProvingTaskType { ProvingTaskType::EL } - async fn fetch_input(&self, block_num: Self::Params) -> Result { - debug!(%block_num, "Fetching EL block input"); - let block: Block = self - .el_client - .request( - "eth_getBlockByNumber", - rpc_params![format!("0x{:x}", block_num), false], - ) - .await?; - let block_hash = block.header.hash; - let witness: ELProofInput = self - .el_client - .request("strataee_getBlockWitness", rpc_params![block_hash, true]) - .await?; - debug!("Fetched EL block witness for block {}", block_num); - Ok(bincode::serialize(&witness).unwrap()) + async fn fetch_input(&self, block_range: Self::Params) -> Result { + let (start_block_num, end_block_num) = block_range; + let mut el_proof_inputs: Vec = Vec::new(); + + for block_num in start_block_num..=end_block_num { + let block: Block = self + .el_client + .request( + "eth_getBlockByNumber", + rpc_params![format!("0x{:x}", block_num), false], + ) + .await?; + let block_hash = block.header.hash; + let el_proof_input: EvmBlockStfInput = self + .el_client + .request("strataee_getBlockWitness", rpc_params![block_hash, true]) + .await?; + + el_proof_inputs.push(el_proof_input); + } + + debug!("Fetched EL block witness for block {:?}", block_range); + Ok(bincode::serialize(&el_proof_inputs).unwrap()) } async fn append_task( diff --git a/bin/prover-client/src/rpc_server.rs b/bin/prover-client/src/rpc_server.rs index 3d51c4c66..8da717eba 100644 --- a/bin/prover-client/src/rpc_server.rs +++ b/bin/prover-client/src/rpc_server.rs @@ -114,11 +114,11 @@ impl StrataProverClientApiServer for ProverClientRpc { RpcResult::Ok(task_id) } - async fn prove_el_block(&self, el_block_num: u64) -> RpcResult { + async fn prove_el_blocks(&self, block_range: (u64, u64)) -> RpcResult { let task_id = self .context .el_proving_task_dispatcher - .create_task(el_block_num) + .create_task(block_range) .await .expect("failed to add proving task, el block"); diff --git a/bin/prover-client/src/zkvm/native.rs b/bin/prover-client/src/zkvm/native.rs index 579b2b388..ed6f5e18f 100644 --- a/bin/prover-client/src/zkvm/native.rs +++ b/bin/prover-client/src/zkvm/native.rs @@ -7,6 +7,7 @@ use strata_proofimpl_cl_agg::process_cl_agg; use strata_proofimpl_cl_stf::process_cl_stf; use strata_proofimpl_evm_ee_stf::process_block_transaction_outer; use strata_proofimpl_l1_batch::process_l1_batch_proof; +use strata_zkvm::ZkVmHost; use crate::primitives::vms::ProofVm; diff --git a/bin/prover-client/src/zkvm/risc0.rs b/bin/prover-client/src/zkvm/risc0.rs index dc862e156..2d5a47707 100644 --- a/bin/prover-client/src/zkvm/risc0.rs +++ b/bin/prover-client/src/zkvm/risc0.rs @@ -5,6 +5,7 @@ use strata_risc0_guest_builder::{ GUEST_RISC0_BTC_BLOCKSPACE_ELF, GUEST_RISC0_CHECKPOINT_ELF, GUEST_RISC0_CL_AGG_ELF, GUEST_RISC0_CL_STF_ELF, GUEST_RISC0_EVM_EE_STF_ELF, GUEST_RISC0_L1_BATCH_ELF, }; +use strata_zkvm::ZkVmHost; use crate::primitives::vms::ProofVm; diff --git a/crates/proof-impl/cl-stf/src/lib.rs b/crates/proof-impl/cl-stf/src/lib.rs index 0c4f53b84..6eee08d35 100644 --- a/crates/proof-impl/cl-stf/src/lib.rs +++ b/crates/proof-impl/cl-stf/src/lib.rs @@ -4,12 +4,10 @@ pub mod prover; use borsh::{BorshDeserialize, BorshSerialize}; -use strata_primitives::{buf::Buf32, evm_exec::create_evm_extra_payload, params::RollupParams}; -use strata_proofimpl_evm_ee_stf::ELProofPublicParams; +use strata_primitives::{buf::Buf32, params::RollupParams}; use strata_state::{ block::ExecSegment, block_validation::{check_block_credential, validate_block_segments}, - exec_update::{ExecUpdate, UpdateInput, UpdateOutput}, id::L2BlockId, tx::DepositInfo, }; @@ -41,19 +39,15 @@ impl L2BatchProofOutput { pub fn verify_and_transition( prev_chstate: Chainstate, new_l2_block: L2Block, - el_proof_pp: ELProofPublicParams, + exec_segment: &ExecSegment, rollup_params: &RollupParams, ) -> Chainstate { - verify_l2_block(&new_l2_block, &el_proof_pp, rollup_params); + verify_l2_block(&new_l2_block, exec_segment, rollup_params); apply_state_transition(prev_chstate, &new_l2_block, rollup_params) } /// Verifies the L2 block. -fn verify_l2_block( - block: &L2Block, - el_proof_pp: &ELProofPublicParams, - chain_params: &RollupParams, -) { +fn verify_l2_block(block: &L2Block, exec_segment: &ExecSegment, chain_params: &RollupParams) { // Assert that the block has been signed by the designated signer assert!( check_block_credential(block.header(), chain_params), @@ -67,25 +61,8 @@ fn verify_l2_block( ); // Verify proof public params matches the exec segment - let proof_exec_segment = reconstruct_exec_segment(el_proof_pp); - let block_exec_segment = block.body().exec_segment().clone(); - assert_eq!(proof_exec_segment, block_exec_segment); -} - -/// Generates an execution segment from the given ELProof public parameters. -pub fn reconstruct_exec_segment(el_proof_pp: &ELProofPublicParams) -> ExecSegment { - // create_evm_extra_payload - let update_input = UpdateInput::new( - el_proof_pp.block_idx, - Vec::new(), - Buf32(*el_proof_pp.txn_root), - create_evm_extra_payload(Buf32(*el_proof_pp.new_blockhash)), - ); - - let update_output = UpdateOutput::new_from_state(Buf32(*el_proof_pp.new_state_root)); - let exec_update = ExecUpdate::new(update_input, update_output); - - ExecSegment::new(exec_update) + let block_exec_segment = block.body().exec_segment(); + assert_eq!(exec_segment, block_exec_segment); } /// Applies a state transition for a given L2 block. @@ -110,17 +87,21 @@ fn apply_state_transition( pub fn process_cl_stf(zkvm: &impl ZkVmEnv, el_vkey: &[u32; 8]) { let rollup_params: RollupParams = zkvm.read_serde(); let (prev_state, block): (Chainstate, L2Block) = zkvm.read_borsh(); + let el_pp_deserialized: Vec = zkvm.read_verified_borsh(el_vkey); - // Read the EL proof output - let el_pp_deserialized: ELProofPublicParams = zkvm.read_verified_serde(el_vkey); - - let new_state = verify_and_transition( - prev_state.clone(), - block, - el_pp_deserialized, - &rollup_params, + // The CL block currently includes only a single ExecSegment + assert_eq!( + el_pp_deserialized.len(), + 1, + "execsegment: expected exactly one" ); + let exec_update = el_pp_deserialized + .first() + .expect("execsegment: failed to fetch the first"); + + let new_state = verify_and_transition(prev_state.clone(), block, exec_update, &rollup_params); + let initial_snapshot = ChainStateSnapshot { hash: prev_state.compute_state_root(), slot: prev_state.chain_tip_slot(), diff --git a/crates/proof-impl/evm-ee-stf/Cargo.toml b/crates/proof-impl/evm-ee-stf/Cargo.toml index 8849a5c2b..f1e494783 100644 --- a/crates/proof-impl/evm-ee-stf/Cargo.toml +++ b/crates/proof-impl/evm-ee-stf/Cargo.toml @@ -4,8 +4,10 @@ name = "strata-proofimpl-evm-ee-stf" version = "0.1.0" [dependencies] +strata-primitives.workspace = true strata-reth-evm.workspace = true strata-reth-primitives.workspace = true +strata-state.workspace = true strata-zkvm.workspace = true alloy-consensus = { workspace = true, features = ["serde-bincode-compat"] } diff --git a/crates/proof-impl/evm-ee-stf/src/db.rs b/crates/proof-impl/evm-ee-stf/src/db.rs index e7eb9222d..6df1472fc 100644 --- a/crates/proof-impl/evm-ee-stf/src/db.rs +++ b/crates/proof-impl/evm-ee-stf/src/db.rs @@ -29,13 +29,13 @@ use revm::{ use crate::{ mpt::{keccak, StateAccount, KECCAK_EMPTY}, - ELProofInput, + EvmBlockStfInput, }; /// A helper trait to extend [`InMemoryDB`] with additional functionality. pub trait InMemoryDBHelper { - /// Create an [`InMemoryDB`] from a given [`ELProofInput`]. - fn initialize(input: &mut ELProofInput) -> Result + /// Create an [`InMemoryDB`] from a given [`EvmBlockStfInput`]. + fn initialize(input: &mut EvmBlockStfInput) -> Result where Self: Sized; @@ -53,7 +53,7 @@ pub trait InMemoryDBHelper { } impl InMemoryDBHelper for InMemoryDB { - fn initialize(input: &mut ELProofInput) -> Result { + fn initialize(input: &mut EvmBlockStfInput) -> Result { // For each contract's byte code, hash it and store it in a map. let contracts: HashMap = input .contracts @@ -63,12 +63,12 @@ impl InMemoryDBHelper for InMemoryDB { // For each account, load the information into the database. let mut accounts = HashMap::with_capacity_and_hasher( - input.parent_storage.len(), + input.pre_state_storage.len(), DefaultHashBuilder::default(), ); - for (address, (storage_trie, slots)) in &mut input.parent_storage { + for (address, (storage_trie, slots)) in &mut input.pre_state_storage { let state_account = input - .parent_state_trie + .pre_state_trie .get_rlp::(&keccak(address))? .unwrap_or_default(); diff --git a/crates/proof-impl/evm-ee-stf/src/lib.rs b/crates/proof-impl/evm-ee-stf/src/lib.rs index 610e73449..e904b16dc 100644 --- a/crates/proof-impl/evm-ee-stf/src/lib.rs +++ b/crates/proof-impl/evm-ee-stf/src/lib.rs @@ -17,101 +17,36 @@ // limitations under the License. pub mod db; pub mod mpt; +pub mod primitives; pub mod processor; pub mod prover; - -use std::collections::HashMap; - -use alloy_consensus::{serde_bincode_compat, Header}; +pub mod utils; use db::InMemoryDBHelper; use mpt::keccak; +pub use primitives::{EvmBlockStfInput, EvmBlockStfOutput}; use processor::{EvmConfig, EvmProcessor}; -use reth_primitives::{ - revm_primitives::alloy_primitives::{Address, Bytes, FixedBytes, B256}, - TransactionSignedNoHash, Withdrawal, -}; +use reth_primitives::revm_primitives::alloy_primitives::B256; use revm::{primitives::SpecId, InMemoryDB}; -use serde::{Deserialize, Serialize}; -use serde_with::serde_as; use strata_reth_evm::collect_withdrawal_intents; -use strata_reth_primitives::WithdrawalIntent; use strata_zkvm::ZkVmEnv; - -use crate::mpt::{MptNode, StorageEntry}; +use utils::generate_exec_update; // TODO: Read the evm config from the genesis config. This should be done in compile time. const EVM_CONFIG: EvmConfig = EvmConfig { chain_id: 12345, spec_id: SpecId::SHANGHAI, }; - -/// Public Parameters that proof asserts -#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] -pub struct ELProofPublicParams { - pub block_idx: u64, - pub prev_blockhash: FixedBytes<32>, - pub new_blockhash: FixedBytes<32>, - pub new_state_root: FixedBytes<32>, - pub txn_root: FixedBytes<32>, - pub withdrawal_intents: Vec, - pub deposits_txns_root: FixedBytes<32>, -} - -#[serde_as] -/// Necessary information to prove the execution of the RETH block. -#[derive(Debug, Default, Clone, PartialEq, Serialize, Deserialize)] -pub struct ELProofInput { - /// The Keccak 256-bit hash of the parent block's header, in its entirety. - /// N.B. The reason serde_bincode_compat is necessary: - /// `[serde_bincode_compat]`(alloy_consensus::serde_bincode_compat) - #[serde_as(as = "serde_bincode_compat::Header")] - pub parent_header: Header, - - /// The 160-bit address to which all fees collected from the successful mining of this block - /// be transferred. - pub beneficiary: Address, - - /// A scalar value equal to the current limit of gas expenditure per block. - pub gas_limit: u64, - - /// A scalar value equal to the reasonable output of Unix's time() at this block's inception. - pub timestamp: u64, - - /// An arbitrary byte array containing data relevant to this block. This must be 32 bytes or - /// fewer. - pub extra_data: Bytes, - - /// A 256-bit hash which, combined with the nonce, proves that a sufficient amount of - /// computation has been carried out on this block. - pub mix_hash: B256, - - /// The state trie of the parent block. - pub parent_state_trie: MptNode, - - /// The storage of the parent block. - pub parent_storage: HashMap, - - /// The relevant contracts for the block. - pub contracts: Vec, - - /// The ancestor headers of the parent block. - pub ancestor_headers: Vec
, - - /// A list of transactions to process. - pub transactions: Vec, - - /// A list of withdrawals to process. - pub withdrawals: Vec, -} - /// Executes the block with the given input and EVM configuration, returning public parameters. pub fn process_block_transaction( - mut input: ELProofInput, + mut input: EvmBlockStfInput, evm_config: EvmConfig, -) -> ELProofPublicParams { +) -> EvmBlockStfOutput { // Calculate the previous block hash let previous_block_hash = B256::from(keccak(alloy_rlp::encode(input.parent_header.clone()))); + // Deposit requests are processed and forwarded as public parameters for verification on the CL + let deposit_requests = input.withdrawals.clone(); + // Initialize the in-memory database let db = match InMemoryDB::initialize(&mut input) { Ok(database) => database, @@ -135,32 +70,51 @@ pub fn process_block_transaction( let new_block_hash = B256::from(keccak(alloy_rlp::encode(block_header.clone()))); // TODO: Optimize receipt iteration by implementing bloom filters or adding hints to - // `ELProofInput`. This will allow for efficient filtering of`WithdrawalIntentEvents`. + // `ElBlockStfInput`. This will allow for efficient filtering of`WithdrawalIntentEvents`. let withdrawal_intents = collect_withdrawal_intents(receipts.into_iter().map(|el| Some(el.receipt))) .collect::>(); // Construct the public parameters for the proof - ELProofPublicParams { + EvmBlockStfOutput { block_idx: block_header.number, new_blockhash: new_block_hash, new_state_root: block_header.state_root, prev_blockhash: previous_block_hash, txn_root: block_header.transactions_root, - deposits_txns_root: block_header.withdrawals_root.unwrap_or_default(), + deposit_requests, withdrawal_intents, } } +/// Processes a sequence of EL block transactions from the given `zkvm` environment, ensuring block +/// hash continuity and committing the resulting updates. pub fn process_block_transaction_outer(zkvm: &impl ZkVmEnv) { - let input: ELProofInput = zkvm.read_serde(); - let public_params = process_block_transaction(input, EVM_CONFIG); - zkvm.commit_serde(&public_params); + let num_blocks: u32 = zkvm.read_serde(); + assert!(num_blocks > 0, "At least one block is required."); + + let mut exec_updates = Vec::with_capacity(num_blocks as usize); + let mut current_blockhash = None; + + for _ in 0..num_blocks { + let input: EvmBlockStfInput = zkvm.read_serde(); + let output = process_block_transaction(input, EVM_CONFIG); + + if let Some(expected_hash) = current_blockhash { + assert_eq!(output.prev_blockhash, expected_hash, "Block hash mismatch"); + } + + current_blockhash = Some(output.new_blockhash); + exec_updates.push(generate_exec_update(&output)); + } + + zkvm.commit_borsh(&exec_updates); } #[cfg(test)] mod tests { use revm::primitives::SpecId; + use serde::{Deserialize, Serialize}; use super::*; const EVM_CONFIG: EvmConfig = EvmConfig { @@ -170,8 +124,8 @@ mod tests { #[derive(Serialize, Deserialize)] struct TestData { - witness: ELProofInput, - params: ELProofPublicParams, + witness: EvmBlockStfInput, + params: EvmBlockStfOutput, } fn get_mock_data() -> TestData { @@ -190,7 +144,7 @@ mod tests { let test_data = get_mock_data(); let s = bincode::serialize(&test_data.witness).unwrap(); - let d: ELProofInput = bincode::deserialize(&s[..]).unwrap(); + let d: EvmBlockStfInput = bincode::deserialize(&s[..]).unwrap(); assert_eq!(d, test_data.witness); } @@ -200,7 +154,6 @@ mod tests { let input = test_data.witness; let op = process_block_transaction(input, EVM_CONFIG); - assert_eq!(op, test_data.params); } } diff --git a/crates/proof-impl/evm-ee-stf/src/primitives.rs b/crates/proof-impl/evm-ee-stf/src/primitives.rs new file mode 100644 index 000000000..5bdda0b19 --- /dev/null +++ b/crates/proof-impl/evm-ee-stf/src/primitives.rs @@ -0,0 +1,80 @@ +use std::collections::HashMap; + +use alloy_consensus::{serde_bincode_compat, Header}; +use reth_primitives::{ + revm_primitives::alloy_primitives::{Address, Bytes, FixedBytes, B256}, + TransactionSignedNoHash, Withdrawal, +}; +use serde::{Deserialize, Serialize}; +use serde_with::serde_as; +use strata_reth_primitives::WithdrawalIntent; +use strata_state::block::ExecSegment; + +use crate::mpt::{MptNode, StorageEntry}; + +/// Public Parameters that proof asserts +pub type EvmEeProofOutput = Vec; + +/// Public Parameters that proof asserts +pub type EvmEeProofInput = Vec; + +/// Result of the block execution +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct EvmBlockStfOutput { + pub block_idx: u64, + pub prev_blockhash: FixedBytes<32>, + pub new_blockhash: FixedBytes<32>, + pub new_state_root: FixedBytes<32>, + pub txn_root: FixedBytes<32>, + pub withdrawal_intents: Vec, + pub deposit_requests: Vec, +} + +/// Necessary information to prove the execution of a Evm block. +#[serde_as] +#[derive(Debug, Default, Clone, PartialEq, Serialize, Deserialize)] +pub struct EvmBlockStfInput { + /// The Keccak 256-bit hash of the parent block's header, in its entirety. + /// N.B. The reason serde_bincode_compat is necessary: + /// `[serde_bincode_compat]`(alloy_consensus::serde_bincode_compat) + #[serde_as(as = "serde_bincode_compat::Header")] + pub parent_header: Header, + + /// The 160-bit address to which all fees collected from the successful mining of this block + /// be transferred. + pub beneficiary: Address, + + /// A scalar value equal to the current limit of gas expenditure per block. + pub gas_limit: u64, + + /// A scalar value equal to the reasonable output of Unix's time() at this block's inception. + pub timestamp: u64, + + /// An arbitrary byte array containing data relevant to this block. This must be 32 bytes or + /// fewer. + pub extra_data: Bytes, + + /// A 256-bit hash which, combined with the nonce, proves that a sufficient amount of + /// computation has been carried out on this block. + pub mix_hash: B256, + + /// Represents the pre-state trie containing account states + /// expected to be accessed or modified during execution. + pub pre_state_trie: MptNode, + + /// Represents the pre-state storage containing entries + /// expected to be accessed or modified during execution. + pub pre_state_storage: HashMap, + + /// The relevant contracts for the block. + pub contracts: Vec, + + /// The ancestor headers of the parent block. + pub ancestor_headers: Vec
, + + /// A list of transactions to process. + pub transactions: Vec, + + /// A list of withdrawals to process. + pub withdrawals: Vec, +} diff --git a/crates/proof-impl/evm-ee-stf/src/processor.rs b/crates/proof-impl/evm-ee-stf/src/processor.rs index ff1a28ce1..84ab2a85c 100644 --- a/crates/proof-impl/evm-ee-stf/src/processor.rs +++ b/crates/proof-impl/evm-ee-stf/src/processor.rs @@ -40,7 +40,7 @@ use strata_reth_evm::set_evm_handles; use crate::{ mpt::{keccak, RlpBytes, StateAccount}, - ELProofInput, + EvmBlockStfInput, }; /// The divisor for the gas limit bound. @@ -56,7 +56,7 @@ pub struct EvmConfig { #[derive(Clone)] pub struct EvmProcessor { /// An input containing all necessary data to execute the block. - pub input: ELProofInput, + pub input: EvmBlockStfInput, /// A database to store all state changes. pub db: Option, @@ -273,7 +273,7 @@ impl EvmProcessor { pub fn finalize(&mut self) { let db = self.db.take().expect("DB not initialized"); - let mut state_trie = mem::take(&mut self.input.parent_state_trie); + let mut state_trie = mem::take(&mut self.input.pre_state_trie); for (address, account) in &db.accounts { // Ignore untouched accounts. if account.account_state == AccountState::None { @@ -291,7 +291,7 @@ impl EvmProcessor { // Update storage root for account. let state_storage = &account.storage; let storage_root = { - let (storage_trie, _) = self.input.parent_storage.get_mut(address).unwrap(); + let (storage_trie, _) = self.input.pre_state_storage.get_mut(address).unwrap(); // If the account has been cleared, clear the storage trie. if account.account_state == AccountState::StorageCleared { storage_trie.clear(); diff --git a/crates/proof-impl/evm-ee-stf/src/prover.rs b/crates/proof-impl/evm-ee-stf/src/prover.rs index 41db58c3a..c649622cf 100644 --- a/crates/proof-impl/evm-ee-stf/src/prover.rs +++ b/crates/proof-impl/evm-ee-stf/src/prover.rs @@ -1,28 +1,35 @@ use strata_zkvm::{ProofType, PublicValues, ZkVmInputResult, ZkVmProver, ZkVmResult}; -use crate::{ELProofInput, ELProofPublicParams}; +use crate::primitives::{EvmEeProofInput, EvmEeProofOutput}; pub struct EvmEeProver; impl ZkVmProver for EvmEeProver { - type Input = ELProofInput; - type Output = ELProofPublicParams; + type Input = EvmEeProofInput; + type Output = EvmEeProofOutput; fn proof_type() -> ProofType { ProofType::Compressed } - fn prepare_input<'a, B>(input: &'a Self::Input) -> ZkVmInputResult + fn prepare_input<'a, B>(el_inputs: &'a Self::Input) -> ZkVmInputResult where B: strata_zkvm::ZkVmInputBuilder<'a>, { - B::new().write_serde(input)?.build() + let mut input_builder = B::new(); + input_builder.write_serde(&el_inputs.len())?; + + for el_block_input in el_inputs { + input_builder.write_serde(el_block_input)?; + } + + input_builder.build() } fn process_output(public_values: &PublicValues) -> ZkVmResult where H: strata_zkvm::ZkVmHost, { - H::extract_serde_public_output(public_values) + H::extract_borsh_public_output(public_values) } } diff --git a/crates/proof-impl/evm-ee-stf/src/utils.rs b/crates/proof-impl/evm-ee-stf/src/utils.rs new file mode 100644 index 000000000..22b6b51cd --- /dev/null +++ b/crates/proof-impl/evm-ee-stf/src/utils.rs @@ -0,0 +1,57 @@ +use strata_primitives::{ + buf::Buf32, + evm_exec::create_evm_extra_payload, + l1::{BitcoinAmount, XOnlyPk}, +}; +use strata_state::{ + block::ExecSegment, + bridge_ops, + exec_update::{ELDepositData, ExecUpdate, Op, UpdateInput, UpdateOutput}, +}; + +use crate::EvmBlockStfOutput; + +/// Generates an execution segment from the given EE-STF result. +pub fn generate_exec_update(el_proof_pp: &EvmBlockStfOutput) -> ExecSegment { + let withdrawals = el_proof_pp + .withdrawal_intents + .iter() + .map(|intent| { + bridge_ops::WithdrawalIntent::new( + BitcoinAmount::from_sat(intent.amt), + XOnlyPk::new(intent.dest_pk.into()), + ) + }) + .collect::>(); + + let applied_ops = el_proof_pp + .deposit_requests + .iter() + .map(|request| { + Op::Deposit(ELDepositData::new( + request.index, + gwei_to_sats(request.amount), + request.address.as_slice().to_vec(), + )) + }) + .collect::>(); + + let update_input = UpdateInput::new( + el_proof_pp.block_idx, + applied_ops, + Buf32(*el_proof_pp.txn_root), + create_evm_extra_payload(Buf32(*el_proof_pp.new_blockhash)), + ); + + let update_output = UpdateOutput::new_from_state(el_proof_pp.new_state_root.into()) + .with_withdrawals(withdrawals); + + let exec_update = ExecUpdate::new(update_input, update_output); + + ExecSegment::new(exec_update) +} + +const fn gwei_to_sats(gwei: u64) -> u64 { + // 1 BTC = 10^8 sats = 10^9 gwei + gwei / 10 +} diff --git a/crates/proof-impl/evm-ee-stf/test_data/witness_params.json b/crates/proof-impl/evm-ee-stf/test_data/witness_params.json index fd1d930e7..8b78e0b25 100644 --- a/crates/proof-impl/evm-ee-stf/test_data/witness_params.json +++ b/crates/proof-impl/evm-ee-stf/test_data/witness_params.json @@ -28,7 +28,7 @@ "timestamp": 1727003743, "extra_data": "0x726574682f76312e302e332f6d61636f73", "mix_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "parent_state_trie": { + "pre_state_trie": { "data": { "Leaf": [ [ @@ -151,7 +151,7 @@ ] } }, - "parent_storage": { + "pre_state_storage": { "0x0000000000000000000000000000000000000000": [ { "data": "Null" @@ -215,6 +215,6 @@ "dest_pk": "0xffab0d5c1a6a719fb807387792d63c7f30f6c8205e4150e0267ec95774106d53" } ], - "deposits_txns_root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421" + "deposit_requests": [] } -} \ No newline at end of file +} diff --git a/crates/reth/db/src/lib.rs b/crates/reth/db/src/lib.rs index 09a52813f..849455211 100644 --- a/crates/reth/db/src/lib.rs +++ b/crates/reth/db/src/lib.rs @@ -1,14 +1,14 @@ pub mod rocksdb; use reth_primitives::revm_primitives::alloy_primitives::B256; pub use strata_db::{errors, DbResult}; -use strata_proofimpl_evm_ee_stf::ELProofInput; +use strata_proofimpl_evm_ee_stf::EvmBlockStfInput; pub trait WitnessStore { - fn put_block_witness(&self, block_hash: B256, witness: &ELProofInput) -> DbResult<()>; + fn put_block_witness(&self, block_hash: B256, witness: &EvmBlockStfInput) -> DbResult<()>; fn del_block_witness(&self, block_hash: B256) -> DbResult<()>; } pub trait WitnessProvider { - fn get_block_witness(&self, block_hash: B256) -> DbResult>; + fn get_block_witness(&self, block_hash: B256) -> DbResult>; fn get_block_witness_raw(&self, block_hash: B256) -> DbResult>>; } diff --git a/crates/reth/db/src/rocksdb/db.rs b/crates/reth/db/src/rocksdb/db.rs index 8309bfc12..06e302479 100644 --- a/crates/reth/db/src/rocksdb/db.rs +++ b/crates/reth/db/src/rocksdb/db.rs @@ -2,7 +2,7 @@ use std::sync::Arc; use reth_primitives::revm_primitives::alloy_primitives::B256; use rockbound::{SchemaDBOperations, SchemaDBOperationsExt}; -use strata_proofimpl_evm_ee_stf::ELProofInput; +use strata_proofimpl_evm_ee_stf::EvmBlockStfInput; use super::schema::BlockWitnessSchema; use crate::{errors::DbError, DbResult, WitnessProvider, WitnessStore}; @@ -29,10 +29,10 @@ impl WitnessDB { } impl WitnessProvider for WitnessDB { - fn get_block_witness(&self, block_hash: B256) -> DbResult> { + fn get_block_witness(&self, block_hash: B256) -> DbResult> { let raw = self.db.get::(&block_hash)?; - let parsed: Option = raw + let parsed: Option = raw .map(|bytes| bincode::deserialize(&bytes)) .transpose() .map_err(|err| DbError::CodecError(err.to_string()))?; @@ -46,7 +46,11 @@ impl WitnessProvider for WitnessDB { } impl WitnessStore for WitnessDB { - fn put_block_witness(&self, block_hash: B256, witness: &ELProofInput) -> crate::DbResult<()> { + fn put_block_witness( + &self, + block_hash: B256, + witness: &EvmBlockStfInput, + ) -> crate::DbResult<()> { let serialized = bincode::serialize(witness).map_err(|err| DbError::Other(err.to_string()))?; Ok(self @@ -63,7 +67,7 @@ impl WitnessStore for WitnessDB { mod tests { use rockbound::SchemaDBOperations; use serde::Deserialize; - use strata_proofimpl_evm_ee_stf::{ELProofInput, ELProofPublicParams}; + use strata_proofimpl_evm_ee_stf::{EvmBlockStfInput, EvmBlockStfOutput}; use tempfile::TempDir; use super::*; @@ -89,8 +93,8 @@ mod tests { #[derive(Deserialize)] struct TestData { - witness: ELProofInput, - params: ELProofPublicParams, + witness: EvmBlockStfInput, + params: EvmBlockStfOutput, } fn get_mock_data() -> TestData { @@ -145,7 +149,10 @@ mod tests { .expect("failed to put witness data"); // assert block is present in the db let received_witness = db.get_block_witness(block_hash); - assert!(matches!(received_witness, Ok(Some(ELProofInput { .. })))); + assert!(matches!( + received_witness, + Ok(Some(EvmBlockStfInput { .. })) + )); // deleting existing block is ok let res = db.del_block_witness(block_hash); diff --git a/crates/reth/db/test_data/witness_params.json b/crates/reth/db/test_data/witness_params.json index fd1d930e7..8b78e0b25 100644 --- a/crates/reth/db/test_data/witness_params.json +++ b/crates/reth/db/test_data/witness_params.json @@ -28,7 +28,7 @@ "timestamp": 1727003743, "extra_data": "0x726574682f76312e302e332f6d61636f73", "mix_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "parent_state_trie": { + "pre_state_trie": { "data": { "Leaf": [ [ @@ -151,7 +151,7 @@ ] } }, - "parent_storage": { + "pre_state_storage": { "0x0000000000000000000000000000000000000000": [ { "data": "Null" @@ -215,6 +215,6 @@ "dest_pk": "0xffab0d5c1a6a719fb807387792d63c7f30f6c8205e4150e0267ec95774106d53" } ], - "deposits_txns_root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421" + "deposit_requests": [] } -} \ No newline at end of file +} diff --git a/crates/reth/exex/src/prover_exex.rs b/crates/reth/exex/src/prover_exex.rs index 01de4084f..9985b0c2c 100644 --- a/crates/reth/exex/src/prover_exex.rs +++ b/crates/reth/exex/src/prover_exex.rs @@ -14,7 +14,7 @@ use reth_provider::{BlockReader, Chain, ExecutionOutcome, StateProviderFactory}; use reth_revm::{db::CacheDB, primitives::FixedBytes}; use reth_rpc_types_compat::proof::from_primitive_account_proof; use reth_trie::{HashedPostState, TrieInput}; -use strata_proofimpl_evm_ee_stf::{mpt::proofs_to_tries, ELProofInput}; +use strata_proofimpl_evm_ee_stf::{mpt::proofs_to_tries, EvmBlockStfInput}; use strata_reth_db::WitnessStore; use tracing::{debug, error}; @@ -102,7 +102,7 @@ fn extract_zkvm_input( block_id: FixedBytes<32>, ctx: &ExExContext, exec_outcome: &ExecutionOutcome, -) -> eyre::Result { +) -> eyre::Result { let current_block = ctx .provider() .block_by_hash(block_id)? @@ -189,7 +189,7 @@ fn extract_zkvm_input( ) .expect("Proof to tries infallible"); - let input = ELProofInput { + let input = EvmBlockStfInput { beneficiary: current_block.header.beneficiary, gas_limit: current_block.gas_limit, timestamp: current_block.header.timestamp, @@ -197,8 +197,8 @@ fn extract_zkvm_input( mix_hash: current_block.header.mix_hash, transactions: current_block_txns, withdrawals, - parent_state_trie: state_trie, - parent_storage: storage, + pre_state_trie: state_trie, + pre_state_storage: storage, contracts, parent_header: prev_block.header, // NOTE: using default to save prover cost. diff --git a/crates/reth/rpc/src/lib.rs b/crates/reth/rpc/src/lib.rs index 04fa9fdc7..aad08d7de 100644 --- a/crates/reth/rpc/src/lib.rs +++ b/crates/reth/rpc/src/lib.rs @@ -10,7 +10,7 @@ use reth_primitives::revm_primitives::alloy_primitives::B256; pub use rpc::StrataRPC; pub use sequencer::SequencerClient; use serde::{Deserialize, Serialize}; -use strata_proofimpl_evm_ee_stf::ELProofInput; +use strata_proofimpl_evm_ee_stf::EvmBlockStfInput; #[cfg_attr(not(test), rpc(server, namespace = "strataee"))] #[cfg_attr(test, rpc(server, client, namespace = "strataee"))] @@ -29,5 +29,5 @@ pub trait StrataRpcApi { #[serde(untagged)] pub enum BlockWitness { Raw(#[serde(with = "hex::serde")] Vec), - Json(ELProofInput), + Json(EvmBlockStfInput), } diff --git a/crates/rpc/prover-client-api/src/lib.rs b/crates/rpc/prover-client-api/src/lib.rs index d2722e140..218af5ca9 100644 --- a/crates/rpc/prover-client-api/src/lib.rs +++ b/crates/rpc/prover-client-api/src/lib.rs @@ -12,9 +12,9 @@ pub trait StrataProverClientApi { #[method(name = "proveBtcBlock")] async fn prove_btc_block(&self, el_block_num: u64) -> RpcResult; - /// Start proving the given el block - #[method(name = "proveELBlock")] - async fn prove_el_block(&self, el_block_num: u64) -> RpcResult; + /// Start proving the given el blocks + #[method(name = "proveElBlocks")] + async fn prove_el_blocks(&self, block_range: (u64, u64)) -> RpcResult; /// Start proving the given cl block #[method(name = "proveCLBlock")] diff --git a/crates/test-utils/data/evm_ee/witness_1.json b/crates/test-utils/data/evm_ee/witness_1.json index 74f123c08..1ead3907d 100644 --- a/crates/test-utils/data/evm_ee/witness_1.json +++ b/crates/test-utils/data/evm_ee/witness_1.json @@ -1,40 +1,40 @@ { - "parent_header": { - "parent_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "ommers_hash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", - "beneficiary": "0x0000000000000000000000000000000000000000", - "state_root": "0x351714af72d74259f45cd7eab0b04527cd40e74836a45abcae50f92d919d988f", - "transactions_root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "receipts_root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "withdrawals_root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "logs_bloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "difficulty": "0x0", - "number": 0, + "parent_header": { + "parent_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "ommers_hash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "beneficiary": "0x0000000000000000000000000000000000000000", + "state_root": "0x351714af72d74259f45cd7eab0b04527cd40e74836a45abcae50f92d919d988f", + "transactions_root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "receipts_root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "withdrawals_root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "logs_bloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "difficulty": "0x0", + "number": 0, + "gas_limit": 30000000, + "gas_used": 0, + "timestamp": 0, + "mix_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "nonce": "0x0000000000000042", + "base_fee_per_gas": 1000000000, + "blob_gas_used": null, + "excess_blob_gas": null, + "parent_beacon_block_root": null, + "requests_root": null, + "extra_data": "0x5343" + }, + "beneficiary": "0x5400000000000000000000000000000000000011", "gas_limit": 30000000, - "gas_used": 0, - "timestamp": 0, + "timestamp": 1728049633, + "extra_data": "0x726574682f76312e302e332f6d61636f73", "mix_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "nonce": "0x0000000000000042", - "base_fee_per_gas": 1000000000, - "blob_gas_used": null, - "excess_blob_gas": null, - "parent_beacon_block_root": null, - "requests_root": null, - "extra_data": "0x5343" - }, - "beneficiary": "0x5400000000000000000000000000000000000011", - "gas_limit": 30000000, - "timestamp": 1728049633, - "extra_data": "0x726574682f76312e302e332f6d61636f73", - "mix_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "parent_state_trie": { - "data": { - "Digest": "0x351714af72d74259f45cd7eab0b04527cd40e74836a45abcae50f92d919d988f" - } - }, - "parent_storage": {}, - "contracts": [], - "ancestor_headers": [], - "transactions": [], - "withdrawals": [] -} \ No newline at end of file + "pre_state_trie": { + "data": { + "Digest": "0x351714af72d74259f45cd7eab0b04527cd40e74836a45abcae50f92d919d988f" + } + }, + "pre_state_storage": {}, + "contracts": [], + "ancestor_headers": [], + "transactions": [], + "withdrawals": [] +} diff --git a/crates/test-utils/data/evm_ee/witness_2.json b/crates/test-utils/data/evm_ee/witness_2.json index 005ed0583..404c5df53 100644 --- a/crates/test-utils/data/evm_ee/witness_2.json +++ b/crates/test-utils/data/evm_ee/witness_2.json @@ -1,40 +1,40 @@ { - "parent_header": { - "parent_hash": "0x37ad61cff1367467a98cf7c54c4ac99e989f1fbb1bc1e646235e90c065c565ba", - "ommers_hash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "parent_header": { + "parent_hash": "0x37ad61cff1367467a98cf7c54c4ac99e989f1fbb1bc1e646235e90c065c565ba", + "ommers_hash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "beneficiary": "0x5400000000000000000000000000000000000011", + "state_root": "0x351714af72d74259f45cd7eab0b04527cd40e74836a45abcae50f92d919d988f", + "transactions_root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "receipts_root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "withdrawals_root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "logs_bloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "difficulty": "0x0", + "number": 1, + "gas_limit": 30000000, + "gas_used": 0, + "timestamp": 1728049633, + "mix_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "nonce": "0x0000000000000000", + "base_fee_per_gas": 875000000, + "blob_gas_used": null, + "excess_blob_gas": null, + "parent_beacon_block_root": null, + "requests_root": null, + "extra_data": "0x726574682f76312e302e332f6d61636f73" + }, "beneficiary": "0x5400000000000000000000000000000000000011", - "state_root": "0x351714af72d74259f45cd7eab0b04527cd40e74836a45abcae50f92d919d988f", - "transactions_root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "receipts_root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "withdrawals_root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "logs_bloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "difficulty": "0x0", - "number": 1, "gas_limit": 30000000, - "gas_used": 0, - "timestamp": 1728049633, + "timestamp": 1728049634, + "extra_data": "0x726574682f76312e302e332f6d61636f73", "mix_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "nonce": "0x0000000000000000", - "base_fee_per_gas": 875000000, - "blob_gas_used": null, - "excess_blob_gas": null, - "parent_beacon_block_root": null, - "requests_root": null, - "extra_data": "0x726574682f76312e302e332f6d61636f73" - }, - "beneficiary": "0x5400000000000000000000000000000000000011", - "gas_limit": 30000000, - "timestamp": 1728049634, - "extra_data": "0x726574682f76312e302e332f6d61636f73", - "mix_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "parent_state_trie": { - "data": { - "Digest": "0x351714af72d74259f45cd7eab0b04527cd40e74836a45abcae50f92d919d988f" - } - }, - "parent_storage": {}, - "contracts": [], - "ancestor_headers": [], - "transactions": [], - "withdrawals": [] -} \ No newline at end of file + "pre_state_trie": { + "data": { + "Digest": "0x351714af72d74259f45cd7eab0b04527cd40e74836a45abcae50f92d919d988f" + } + }, + "pre_state_storage": {}, + "contracts": [], + "ancestor_headers": [], + "transactions": [], + "withdrawals": [] +} diff --git a/crates/test-utils/data/evm_ee/witness_3.json b/crates/test-utils/data/evm_ee/witness_3.json index 7101ac5d9..54d0370b2 100644 --- a/crates/test-utils/data/evm_ee/witness_3.json +++ b/crates/test-utils/data/evm_ee/witness_3.json @@ -1,40 +1,40 @@ { - "parent_header": { - "parent_hash": "0x14b2fbd209d6c9334b71596e6207ada9042ba9e738259e1e6a4b1ea5faa71794", - "ommers_hash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "parent_header": { + "parent_hash": "0x14b2fbd209d6c9334b71596e6207ada9042ba9e738259e1e6a4b1ea5faa71794", + "ommers_hash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "beneficiary": "0x5400000000000000000000000000000000000011", + "state_root": "0x351714af72d74259f45cd7eab0b04527cd40e74836a45abcae50f92d919d988f", + "transactions_root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "receipts_root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "withdrawals_root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "logs_bloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "difficulty": "0x0", + "number": 2, + "gas_limit": 30000000, + "gas_used": 0, + "timestamp": 1728049634, + "mix_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "nonce": "0x0000000000000000", + "base_fee_per_gas": 765625000, + "blob_gas_used": null, + "excess_blob_gas": null, + "parent_beacon_block_root": null, + "requests_root": null, + "extra_data": "0x726574682f76312e302e332f6d61636f73" + }, "beneficiary": "0x5400000000000000000000000000000000000011", - "state_root": "0x351714af72d74259f45cd7eab0b04527cd40e74836a45abcae50f92d919d988f", - "transactions_root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "receipts_root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "withdrawals_root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "logs_bloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "difficulty": "0x0", - "number": 2, "gas_limit": 30000000, - "gas_used": 0, - "timestamp": 1728049634, + "timestamp": 1728049635, + "extra_data": "0x726574682f76312e302e332f6d61636f73", "mix_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "nonce": "0x0000000000000000", - "base_fee_per_gas": 765625000, - "blob_gas_used": null, - "excess_blob_gas": null, - "parent_beacon_block_root": null, - "requests_root": null, - "extra_data": "0x726574682f76312e302e332f6d61636f73" - }, - "beneficiary": "0x5400000000000000000000000000000000000011", - "gas_limit": 30000000, - "timestamp": 1728049635, - "extra_data": "0x726574682f76312e302e332f6d61636f73", - "mix_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "parent_state_trie": { - "data": { - "Digest": "0x351714af72d74259f45cd7eab0b04527cd40e74836a45abcae50f92d919d988f" - } - }, - "parent_storage": {}, - "contracts": [], - "ancestor_headers": [], - "transactions": [], - "withdrawals": [] -} \ No newline at end of file + "pre_state_trie": { + "data": { + "Digest": "0x351714af72d74259f45cd7eab0b04527cd40e74836a45abcae50f92d919d988f" + } + }, + "pre_state_storage": {}, + "contracts": [], + "ancestor_headers": [], + "transactions": [], + "withdrawals": [] +} diff --git a/crates/test-utils/data/evm_ee/witness_4.json b/crates/test-utils/data/evm_ee/witness_4.json index 968649df3..83c7dc80a 100644 --- a/crates/test-utils/data/evm_ee/witness_4.json +++ b/crates/test-utils/data/evm_ee/witness_4.json @@ -1,40 +1,40 @@ { - "parent_header": { - "parent_hash": "0xc513b6f6390000bd8376c6c98c4f2a39967236c3972c056525c7342ad9e2f45d", - "ommers_hash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "parent_header": { + "parent_hash": "0xc513b6f6390000bd8376c6c98c4f2a39967236c3972c056525c7342ad9e2f45d", + "ommers_hash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "beneficiary": "0x5400000000000000000000000000000000000011", + "state_root": "0x351714af72d74259f45cd7eab0b04527cd40e74836a45abcae50f92d919d988f", + "transactions_root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "receipts_root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "withdrawals_root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "logs_bloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "difficulty": "0x0", + "number": 3, + "gas_limit": 30000000, + "gas_used": 0, + "timestamp": 1728049635, + "mix_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "nonce": "0x0000000000000000", + "base_fee_per_gas": 669921875, + "blob_gas_used": null, + "excess_blob_gas": null, + "parent_beacon_block_root": null, + "requests_root": null, + "extra_data": "0x726574682f76312e302e332f6d61636f73" + }, "beneficiary": "0x5400000000000000000000000000000000000011", - "state_root": "0x351714af72d74259f45cd7eab0b04527cd40e74836a45abcae50f92d919d988f", - "transactions_root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "receipts_root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "withdrawals_root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "logs_bloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "difficulty": "0x0", - "number": 3, "gas_limit": 30000000, - "gas_used": 0, - "timestamp": 1728049635, + "timestamp": 1728049636, + "extra_data": "0x726574682f76312e302e332f6d61636f73", "mix_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "nonce": "0x0000000000000000", - "base_fee_per_gas": 669921875, - "blob_gas_used": null, - "excess_blob_gas": null, - "parent_beacon_block_root": null, - "requests_root": null, - "extra_data": "0x726574682f76312e302e332f6d61636f73" - }, - "beneficiary": "0x5400000000000000000000000000000000000011", - "gas_limit": 30000000, - "timestamp": 1728049636, - "extra_data": "0x726574682f76312e302e332f6d61636f73", - "mix_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "parent_state_trie": { - "data": { - "Digest": "0x351714af72d74259f45cd7eab0b04527cd40e74836a45abcae50f92d919d988f" - } - }, - "parent_storage": {}, - "contracts": [], - "ancestor_headers": [], - "transactions": [], - "withdrawals": [] -} \ No newline at end of file + "pre_state_trie": { + "data": { + "Digest": "0x351714af72d74259f45cd7eab0b04527cd40e74836a45abcae50f92d919d988f" + } + }, + "pre_state_storage": {}, + "contracts": [], + "ancestor_headers": [], + "transactions": [], + "withdrawals": [] +} diff --git a/crates/test-utils/src/evm_ee.rs b/crates/test-utils/src/evm_ee.rs index 8e4daf594..fa25fb569 100644 --- a/crates/test-utils/src/evm_ee.rs +++ b/crates/test-utils/src/evm_ee.rs @@ -2,9 +2,10 @@ use std::{collections::HashMap, path::PathBuf}; use strata_consensus_logic::genesis::make_genesis_block; use strata_primitives::buf::{Buf32, Buf64}; -use strata_proofimpl_cl_stf::{reconstruct_exec_segment, Chainstate, StateCache}; +use strata_proofimpl_cl_stf::{Chainstate, StateCache}; use strata_proofimpl_evm_ee_stf::{ - process_block_transaction, processor::EvmConfig, ELProofInput, ELProofPublicParams, + process_block_transaction, processor::EvmConfig, utils::generate_exec_update, EvmBlockStfInput, + EvmBlockStfOutput, }; use strata_state::{ block::{L1Segment, L2Block, L2BlockBody}, @@ -18,13 +19,13 @@ use crate::l2::{gen_params, get_genesis_chainstate}; /// generation and processing for testing STF proofs. #[derive(Debug, Clone)] pub struct EvmSegment { - inputs: HashMap, - outputs: HashMap, + inputs: HashMap, + outputs: HashMap, } impl EvmSegment { - /// Initializes the EvmSegment by loading existing [`ELProofInput`] data from the specified - /// range of block heights and generating corresponding ELProofPublicParams. + /// Initializes the EvmSegment by loading existing [`EvmBlockStfInput`] data from the specified + /// range of block heights and generating corresponding ElBlockStfOutput. /// /// This function reads witness data from JSON files, processes them, and stores the results /// for testing purposes of the STF proofs. @@ -45,7 +46,7 @@ impl EvmSegment { for height in start_height..=end_height { let witness_path = dir.join(format!("witness_{}.json", height)); let json_file = std::fs::read_to_string(witness_path).expect("Expected JSON file"); - let el_proof_input: ELProofInput = + let el_proof_input: EvmBlockStfInput = serde_json::from_str(&json_file).expect("Invalid JSON file"); inputs.insert(height, el_proof_input.clone()); @@ -56,17 +57,17 @@ impl EvmSegment { Self { inputs, outputs } } - /// Retrieves the [`ELProofInput`] associated with the given block height. + /// Retrieves the [`EvmBlockStfInput`] associated with the given block height. /// /// Panics if no input is found for the specified height. - pub fn get_input(&self, height: &u64) -> &ELProofInput { + pub fn get_input(&self, height: &u64) -> &EvmBlockStfInput { self.inputs.get(height).expect("No input found at height") } - /// Retrieves the [`ELProofPublicParams`] associated with the given block height. + /// Retrieves the [`EvmBlockStfOutput`] associated with the given block height. /// /// Panics if no output is found for the specified height. - pub fn get_output(&self, height: &u64) -> &ELProofPublicParams { + pub fn get_output(&self, height: &u64) -> &EvmBlockStfOutput { self.outputs.get(height).expect("No output found at height") } } @@ -101,7 +102,7 @@ impl L2Segment { for height in 1..=end_height { let el_proof_in = evm_segment.get_input(&height); let el_proof_out = evm_segment.get_output(&height); - let evm_ee_segment = reconstruct_exec_segment(el_proof_out); + let evm_ee_segment = generate_exec_update(el_proof_out); let l1_segment = L1Segment::new_empty(); let body = L2BlockBody::new(l1_segment, evm_ee_segment); diff --git a/crates/zkvm/adapters/sp1/src/host.rs b/crates/zkvm/adapters/sp1/src/host.rs index 293452f0a..54c110a53 100644 --- a/crates/zkvm/adapters/sp1/src/host.rs +++ b/crates/zkvm/adapters/sp1/src/host.rs @@ -63,7 +63,6 @@ impl ZkVmHost for SP1Host { std::env::set_var("SP1_PROVER", "mock"); } - sp1_sdk::utils::setup_logger(); let client = ProverClient::new(); // Start proving diff --git a/functional-tests/fn_prover_el_dispatch.py b/functional-tests/fn_prover_el_dispatch.py index fb58061d6..1c6c5af43 100644 --- a/functional-tests/fn_prover_el_dispatch.py +++ b/functional-tests/fn_prover_el_dispatch.py @@ -5,6 +5,12 @@ import testenv from utils import wait_for_proof_with_time_out +# Parameters defining the range of Execution Engine (EE) blocks to be proven. +EE_PROVER_PARAMS = { + "start_block": 1, + "end_block": 3, +} + @flexitest.register class ProverClientTest(testenv.StrataTester): @@ -18,9 +24,11 @@ def main(self, ctx: flexitest.RunContext): # Wait for the some block building time.sleep(60) - # Dispatch the prover task - task_id = prover_client_rpc.dev_strata_proveELBlock(1) - self.debug(f"got the task id: {task_id}") + # Prove EL blocks from START_BLOCK to END_BLOCK + task_id = prover_client_rpc.dev_strata_proveELBlocks( + (EE_PROVER_PARAMS["start_block"], EE_PROVER_PARAMS["end_block"]) + ) + print("got the task id: {}", task_id) assert task_id is not None time_out = 10 * 60 diff --git a/functional-tests/run_test.sh b/functional-tests/run_test.sh index a3a31a28a..26adae372 100755 --- a/functional-tests/run_test.sh +++ b/functional-tests/run_test.sh @@ -12,8 +12,7 @@ fi # Conditionally run cargo build based on PROVER_TEST if [ ! -z $PROVER_TEST ]; then echo "Running on prover mode" - # cargo build -F "prover" - cargo build -F "prover" --release + cargo build --release export PATH=$(realpath ../target/release/):$PATH else echo "Running on seq mode" diff --git a/provers/sp1/guest-checkpoint/Cargo.lock b/provers/sp1/guest-checkpoint/Cargo.lock index a9ff3c827..937b71d21 100644 --- a/provers/sp1/guest-checkpoint/Cargo.lock +++ b/provers/sp1/guest-checkpoint/Cargo.lock @@ -2579,7 +2579,6 @@ name = "strata-bridge-tx-builder" version = "0.1.0" dependencies = [ "bitcoin", - "lazy_static", "musig2", "serde", "strata-primitives", @@ -2592,7 +2591,6 @@ version = "0.1.0" dependencies = [ "anyhow", "bitcoin", - "borsh", "rand_chacha", "rand_core", "strata-eectl", @@ -2606,7 +2604,6 @@ dependencies = [ name = "strata-crypto" version = "0.1.0" dependencies = [ - "borsh", "secp256k1", "sha2", "strata-primitives", @@ -2707,8 +2704,10 @@ dependencies = [ "rlp", "serde", "serde_with", + "strata-primitives", "strata-reth-evm", "strata-reth-primitives", + "strata-state", "strata-zkvm", "thiserror", ] diff --git a/provers/sp1/guest-cl-agg/Cargo.lock b/provers/sp1/guest-cl-agg/Cargo.lock index 77e60b048..42c3de1f8 100644 --- a/provers/sp1/guest-cl-agg/Cargo.lock +++ b/provers/sp1/guest-cl-agg/Cargo.lock @@ -2579,7 +2579,6 @@ name = "strata-bridge-tx-builder" version = "0.1.0" dependencies = [ "bitcoin", - "lazy_static", "musig2", "serde", "strata-primitives", @@ -2592,7 +2591,6 @@ version = "0.1.0" dependencies = [ "anyhow", "bitcoin", - "borsh", "rand_chacha", "rand_core", "strata-eectl", @@ -2606,7 +2604,6 @@ dependencies = [ name = "strata-crypto" version = "0.1.0" dependencies = [ - "borsh", "secp256k1", "sha2", "strata-primitives", @@ -2684,8 +2681,10 @@ dependencies = [ "rlp", "serde", "serde_with", + "strata-primitives", "strata-reth-evm", "strata-reth-primitives", + "strata-state", "strata-zkvm", "thiserror", ] diff --git a/provers/sp1/guest-cl-stf/Cargo.lock b/provers/sp1/guest-cl-stf/Cargo.lock index 152d35422..2d01528f0 100644 --- a/provers/sp1/guest-cl-stf/Cargo.lock +++ b/provers/sp1/guest-cl-stf/Cargo.lock @@ -2579,7 +2579,6 @@ name = "strata-bridge-tx-builder" version = "0.1.0" dependencies = [ "bitcoin", - "lazy_static", "musig2", "serde", "strata-primitives", @@ -2592,7 +2591,6 @@ version = "0.1.0" dependencies = [ "anyhow", "bitcoin", - "borsh", "rand_chacha", "rand_core", "strata-eectl", @@ -2606,7 +2604,6 @@ dependencies = [ name = "strata-crypto" version = "0.1.0" dependencies = [ - "borsh", "secp256k1", "sha2", "strata-primitives", @@ -2675,8 +2672,10 @@ dependencies = [ "rlp", "serde", "serde_with", + "strata-primitives", "strata-reth-evm", "strata-reth-primitives", + "strata-state", "strata-zkvm", "thiserror", ] diff --git a/provers/sp1/guest-evm-ee-stf/Cargo.lock b/provers/sp1/guest-evm-ee-stf/Cargo.lock index 3eafd387a..911b33887 100644 --- a/provers/sp1/guest-evm-ee-stf/Cargo.lock +++ b/provers/sp1/guest-evm-ee-stf/Cargo.lock @@ -1070,6 +1070,12 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "ethnum" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b90ca2580b73ab6a1f724b76ca11ab632df820fd6040c336200d2c1df7b3c82c" + [[package]] name = "fastrand" version = "2.1.1" @@ -1575,6 +1581,7 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" dependencies = [ + "proc-macro-crate", "proc-macro2", "quote", "syn 2.0.87", @@ -2567,6 +2574,26 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +[[package]] +name = "strata-bridge-tx-builder" +version = "0.1.0" +dependencies = [ + "bitcoin", + "musig2", + "serde", + "strata-primitives", + "thiserror", +] + +[[package]] +name = "strata-crypto" +version = "0.1.0" +dependencies = [ + "secp256k1", + "sha2", + "strata-primitives", +] + [[package]] name = "strata-primitives" version = "0.1.0" @@ -2608,8 +2635,10 @@ dependencies = [ "rlp", "serde", "serde_with", + "strata-primitives", "strata-reth-evm", "strata-reth-primitives", + "strata-state", "strata-zkvm", "thiserror", ] @@ -2651,6 +2680,26 @@ dependencies = [ "tracing", ] +[[package]] +name = "strata-state" +version = "0.1.0" +dependencies = [ + "arbitrary", + "bitcoin", + "borsh", + "digest 0.10.7", + "ethnum", + "hex", + "num_enum", + "serde", + "sha2", + "strata-bridge-tx-builder", + "strata-crypto", + "strata-primitives", + "strata-zkvm", + "tracing", +] + [[package]] name = "strata-zkvm" version = "0.1.0" diff --git a/provers/sp1/guest-l1-batch/Cargo.lock b/provers/sp1/guest-l1-batch/Cargo.lock index 83e35f54d..d0ddd0c26 100644 --- a/provers/sp1/guest-l1-batch/Cargo.lock +++ b/provers/sp1/guest-l1-batch/Cargo.lock @@ -2121,7 +2121,6 @@ name = "strata-bridge-tx-builder" version = "0.1.0" dependencies = [ "bitcoin", - "lazy_static", "musig2", "serde", "strata-primitives", @@ -2132,7 +2131,6 @@ dependencies = [ name = "strata-crypto" version = "0.1.0" dependencies = [ - "borsh", "secp256k1", "sha2", "strata-primitives", diff --git a/provers/test-util/el/witness_1.json b/provers/test-util/el/witness_1.json index 101e30639..207ce6ec7 100644 --- a/provers/test-util/el/witness_1.json +++ b/provers/test-util/el/witness_1.json @@ -27,14 +27,14 @@ "timestamp": 1727739191, "extra_data": "0x726574682f76312e302e332f6d61636f73", "mix_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "parent_state_trie": { + "pre_state_trie": { "data": { "Digest": "0x351714af72d74259f45cd7eab0b04527cd40e74836a45abcae50f92d919d988f" } }, - "parent_storage": {}, + "pre_state_storage": {}, "contracts": [], "ancestor_headers": [], "transactions": [], "withdrawals": [] -} \ No newline at end of file +} diff --git a/provers/test-util/el/witness_2.json b/provers/test-util/el/witness_2.json index 2f3b9b794..87db6d7e1 100644 --- a/provers/test-util/el/witness_2.json +++ b/provers/test-util/el/witness_2.json @@ -27,14 +27,14 @@ "timestamp": 1727739192, "extra_data": "0x726574682f76312e302e332f6d61636f73", "mix_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "parent_state_trie": { + "pre_state_trie": { "data": { "Digest": "0x351714af72d74259f45cd7eab0b04527cd40e74836a45abcae50f92d919d988f" } }, - "parent_storage": {}, + "pre_state_storage": {}, "contracts": [], "ancestor_headers": [], "transactions": [], "withdrawals": [] -} \ No newline at end of file +} diff --git a/provers/test-util/el/witness_3.json b/provers/test-util/el/witness_3.json index a303925ba..96b462ea7 100644 --- a/provers/test-util/el/witness_3.json +++ b/provers/test-util/el/witness_3.json @@ -27,14 +27,14 @@ "timestamp": 1727739193, "extra_data": "0x726574682f76312e302e332f6d61636f73", "mix_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "parent_state_trie": { + "pre_state_trie": { "data": { "Digest": "0x351714af72d74259f45cd7eab0b04527cd40e74836a45abcae50f92d919d988f" } }, - "parent_storage": {}, + "pre_state_storage": {}, "contracts": [], "ancestor_headers": [], "transactions": [], "withdrawals": [] -} \ No newline at end of file +} diff --git a/provers/test-util/el/witness_4.json b/provers/test-util/el/witness_4.json index 9a0fc1284..e59464e4d 100644 --- a/provers/test-util/el/witness_4.json +++ b/provers/test-util/el/witness_4.json @@ -27,14 +27,14 @@ "timestamp": 1727739194, "extra_data": "0x726574682f76312e302e332f6d61636f73", "mix_hash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "parent_state_trie": { + "pre_state_trie": { "data": { "Digest": "0x351714af72d74259f45cd7eab0b04527cd40e74836a45abcae50f92d919d988f" } }, - "parent_storage": {}, + "pre_state_storage": {}, "contracts": [], "ancestor_headers": [], "transactions": [], "withdrawals": [] -} \ No newline at end of file +} diff --git a/provers/tests/src/provers/el.rs b/provers/tests/src/provers/el.rs index bbc6a1dba..43bb4b7c4 100644 --- a/provers/tests/src/provers/el.rs +++ b/provers/tests/src/provers/el.rs @@ -1,4 +1,4 @@ -use strata_proofimpl_evm_ee_stf::{prover::EvmEeProver, ELProofInput}; +use strata_proofimpl_evm_ee_stf::{primitives::EvmEeProofInput, prover::EvmEeProver}; use strata_test_utils::evm_ee::EvmSegment; use strata_zkvm::{ProofReceipt, ZkVmHost, ZkVmProver, ZkVmResult}; @@ -15,11 +15,11 @@ impl ElProofGenerator { } impl ProofGenerator for ElProofGenerator { - fn get_input(&self, block_num: &u64) -> ZkVmResult { + fn get_input(&self, block_num: &u64) -> ZkVmResult { let input = EvmSegment::initialize_from_saved_ee_data(*block_num, *block_num) .get_input(block_num) .clone(); - Ok(input) + Ok(vec![input]) } fn gen_proof(&self, block_num: &u64) -> ZkVmResult {