From 9fecf4acf7d3cdad8143d1d8d1a5c525af7e8ae3 Mon Sep 17 00:00:00 2001
From: Kathy <22675649+anylots@users.noreply.github.com>
Date: Fri, 27 Feb 2026 15:07:48 +0800
Subject: [PATCH 01/21] support proveCommittedBatchStateView in Shadow Proving
---
prover/bin/shadow-prove/abi/Rollup.json | 160 +++++++++++-
prover/bin/shadow-prove/src/main.rs | 17 +-
prover/bin/shadow-prove/src/shadow_prove.rs | 267 +++++++++++---------
3 files changed, 316 insertions(+), 128 deletions(-)
diff --git a/prover/bin/shadow-prove/abi/Rollup.json b/prover/bin/shadow-prove/abi/Rollup.json
index 28f7a5c6d..e32ca8619 100644
--- a/prover/bin/shadow-prove/abi/Rollup.json
+++ b/prover/bin/shadow-prove/abi/Rollup.json
@@ -306,6 +306,25 @@
"name": "UpdateProofWindow",
"type": "event"
},
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "oldPeriod",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "newPeriod",
+ "type": "uint256"
+ }
+ ],
+ "name": "UpdateRollupDelayPeriod",
+ "type": "event"
+ },
{
"anonymous": false,
"inputs": [
@@ -666,6 +685,88 @@
"stateMutability": "payable",
"type": "function"
},
+ {
+ "inputs": [
+ {
+ "components": [
+ {
+ "internalType": "uint8",
+ "name": "version",
+ "type": "uint8"
+ },
+ {
+ "internalType": "bytes",
+ "name": "parentBatchHeader",
+ "type": "bytes"
+ },
+ {
+ "internalType": "uint64",
+ "name": "lastBlockNumber",
+ "type": "uint64"
+ },
+ {
+ "internalType": "uint16",
+ "name": "numL1Messages",
+ "type": "uint16"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "prevStateRoot",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "postStateRoot",
+ "type": "bytes32"
+ },
+ {
+ "internalType": "bytes32",
+ "name": "withdrawalRoot",
+ "type": "bytes32"
+ }
+ ],
+ "internalType": "struct IRollup.BatchDataInput",
+ "name": "batchDataInput",
+ "type": "tuple"
+ },
+ {
+ "components": [
+ {
+ "internalType": "uint256",
+ "name": "signedSequencersBitmap",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bytes",
+ "name": "sequencerSets",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "signature",
+ "type": "bytes"
+ }
+ ],
+ "internalType": "struct IRollup.BatchSignatureInput",
+ "name": "batchSignatureInput",
+ "type": "tuple"
+ },
+ {
+ "internalType": "bytes",
+ "name": "_batchHeader",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "_batchProof",
+ "type": "bytes"
+ }
+ ],
+ "name": "commitBatchWithProof",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
{
"inputs": [
{
@@ -826,6 +927,19 @@
"stateMutability": "nonpayable",
"type": "function"
},
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "_rollupDelayPeriod",
+ "type": "uint256"
+ }
+ ],
+ "name": "initialize3",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
{
"inputs": [
{
@@ -968,6 +1082,24 @@
"stateMutability": "view",
"type": "function"
},
+ {
+ "inputs": [
+ {
+ "internalType": "bytes",
+ "name": "_batchHeader",
+ "type": "bytes"
+ },
+ {
+ "internalType": "bytes",
+ "name": "_batchProof",
+ "type": "bytes"
+ }
+ ],
+ "name": "proveCommittedBatchState",
+ "outputs": [],
+ "stateMutability": "view",
+ "type": "function"
+ },
{
"inputs": [],
"name": "proveRemaining",
@@ -1050,6 +1182,19 @@
"stateMutability": "view",
"type": "function"
},
+ {
+ "inputs": [],
+ "name": "rollupDelayPeriod",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
{
"inputs": [
{
@@ -1115,6 +1260,19 @@
"stateMutability": "nonpayable",
"type": "function"
},
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "_newPeriod",
+ "type": "uint256"
+ }
+ ],
+ "name": "updateRollupDelayPeriod",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
{
"inputs": [
{
@@ -1164,4 +1322,4 @@
"stateMutability": "payable",
"type": "receive"
}
-]
+]
\ No newline at end of file
diff --git a/prover/bin/shadow-prove/src/main.rs b/prover/bin/shadow-prove/src/main.rs
index d406e3965..a9b22d332 100644
--- a/prover/bin/shadow-prove/src/main.rs
+++ b/prover/bin/shadow-prove/src/main.rs
@@ -12,7 +12,7 @@ use prometheus::{Encoder, TextEncoder};
use shadow_proving::{
execute::try_execute_batch,
metrics::{METRICS, REGISTRY},
- shadow_prove::ShadowProver,
+ shadow_prove::{BatchProveInfo, ShadowProver},
shadow_rollup::BatchSyncer,
util::{read_env_var, read_parse_env},
SHADOW_EXECUTE, SHADOW_PROVING_MAX_BLOCK, SHADOW_PROVING_MAX_TXN, SHADOW_PROVING_PROVER_RPC,
@@ -121,8 +121,11 @@ async fn main() {
Err(broadcast::error::RecvError::Closed) => break,
};
- let result = match batch_syncer.sync_batch(batch_info, batch_header).await {
- Ok(Some(batch)) => shadow_prover.prove(batch).await,
+ let result = match batch_syncer.sync_batch(batch_info, batch_header.clone()).await {
+ Ok(Some(batch)) => {
+ let prove_info = BatchProveInfo { batch_info: batch, batch_header };
+ shadow_prover.prove(prove_info).await
+ }
Ok(None) => Ok(()),
Err(e) => Err(e),
};
@@ -172,7 +175,9 @@ fn init_shadow_proving(
let shadow_prover = ShadowProver::new(
signer.address(),
+ Address::from_str(&rollup).unwrap(),
Address::from_str(&shadow_rollup).unwrap(),
+ l1_provider,
verify_provider,
l1_signer,
);
@@ -300,8 +305,10 @@ async fn test_shadow() {
return;
}
if prove {
- let batch = batch_syncer.sync_batch(batch_info, batch_header).await.unwrap().unwrap();
- shadow_prover.prove(batch).await.unwrap();
+ let batch =
+ batch_syncer.sync_batch(batch_info, batch_header.clone()).await.unwrap().unwrap();
+ let prove_info = BatchProveInfo { batch_info: batch, batch_header };
+ shadow_prover.prove(prove_info).await.unwrap();
}
}
diff --git a/prover/bin/shadow-prove/src/shadow_prove.rs b/prover/bin/shadow-prove/src/shadow_prove.rs
index a038beadc..af8c136f0 100644
--- a/prover/bin/shadow-prove/src/shadow_prove.rs
+++ b/prover/bin/shadow-prove/src/shadow_prove.rs
@@ -1,4 +1,9 @@
-use crate::{metrics::METRICS, util, BatchInfo, ShadowRollup::ShadowRollupInstance};
+use crate::{
+ abi::Rollup::{self, RollupInstance},
+ metrics::METRICS,
+ util, BatchInfo,
+ ShadowRollup::ShadowRollupInstance,
+};
use alloy_network::{Network, ReceiptResponse};
use alloy_primitives::{Address, Bytes};
use alloy_provider::{DynProvider, Provider};
@@ -32,13 +37,22 @@ mod task_status {
pub const PROVED: &str = "Proved";
}
+// ShadowProver is responsible for proving the batch state onchain through the shadow rollup contract.
#[derive(Clone, Debug)]
pub struct ShadowProver
{
- l1_provider: DynProvider,
+ shadow_provider: DynProvider,
+ l1_rollup: RollupInstance,
l1_shadow_rollup: ShadowRollupInstance,
wallet_address: Address,
}
+/// BatchProveInfo contains the batch info and batch header needed for proving.
+#[derive(Clone, Debug)]
+pub struct BatchProveInfo {
+ pub batch_info: BatchInfo,
+ pub batch_header: Bytes,
+}
+
impl
ShadowProver
where
P: Provider + Clone,
@@ -47,19 +61,22 @@ where
pub fn new(
wallet_address: Address,
shadow_rollup_address: Address,
- provider: DynProvider,
+ rollup_address: Address,
+ l1_provider: DynProvider,
+ shadow_provider: DynProvider,
wallet: P,
) -> Self {
+ let l1_rollup = Rollup::RollupInstance::new(rollup_address, l1_provider.clone());
let l1_shadow_rollup = ShadowRollupInstance::new(shadow_rollup_address, wallet);
- Self { l1_provider: provider, l1_shadow_rollup, wallet_address }
+ Self { shadow_provider, l1_rollup, l1_shadow_rollup, wallet_address }
}
- pub async fn prove(&self, batch_info: BatchInfo) -> Result<(), anyhow::Error> {
- log::info!(">Start shadow prove for batch: {:#?}", batch_info.batch_index);
+ pub async fn prove(&self, prove_info: BatchProveInfo) -> Result<(), anyhow::Error> {
+ log::info!(">Start shadow prove for batch: {:#?}", prove_info.batch_info.batch_index);
// Record wallet balance.
- let balance = match self.l1_provider.get_balance(self.wallet_address).await {
+ let balance = match self.shadow_provider.get_balance(self.wallet_address).await {
Ok(b) => b,
Err(e) => {
log::error!("shadow_proving_wallet.get_balance error: {:#?}", e);
@@ -70,149 +87,155 @@ where
.shadow_wallet_balance
.set(alloy_primitives::utils::format_ether(balance).parse().unwrap_or(0.0));
- handle_with_prover(&batch_info, &self.l1_shadow_rollup).await;
+ self.handle_with_prover(&prove_info).await;
Ok(())
}
-}
-async fn handle_with_prover(
- batch_info: &BatchInfo,
- l1_shadow_rollup: &ShadowRollupInstance
,
-) where
- P: Provider + Clone,
- N: Network,
-{
- let l2_rpc = var("SHADOW_PROVING_L2_RPC").expect("Cannot detect L2_RPC env var");
- let batch_index = batch_info.batch_index;
- let blocks_len = batch_info.end_block - batch_info.start_block + 1;
+ async fn handle_with_prover(&self, prove_info: &BatchProveInfo) {
+ let l2_rpc = var("SHADOW_PROVING_L2_RPC").expect("Cannot detect L2_RPC env var");
+ let batch_index = prove_info.batch_info.batch_index;
+ let blocks_len = prove_info.batch_info.end_block - prove_info.batch_info.start_block + 1;
- METRICS.shadow_blocks_len.set(blocks_len as i64);
- METRICS.shadow_batch_index.set(batch_index as i64);
+ METRICS.shadow_blocks_len.set(blocks_len as i64);
+ METRICS.shadow_batch_index.set(batch_index as i64);
- for _ in 0..MAX_RETRY_TIMES {
- sleep(Duration::from_secs(12)).await;
+ for _ in 0..MAX_RETRY_TIMES {
+ sleep(Duration::from_secs(12)).await;
- log::info!(
- "Start prove batch of: {:?}, blocks.len = {:?}, block_start = {:#?}",
- batch_index,
- blocks_len,
- batch_info.start_block
- );
+ log::info!(
+ "Start prove batch of: {:?}, blocks.len = {:?}, block_start = {:#?}",
+ batch_index,
+ blocks_len,
+ prove_info.batch_info.start_block
+ );
- // Query existing proof
- if let Some(prove_result) = query_proof(batch_index).await {
- if !prove_result.error_code.is_empty() {
- log::error!("query proof and prove state error, batch_index: {:?}, prove_result.error_code: {:?}, prove_result.error_msg: {:?}", batch_index, prove_result.error_code, prove_result.error_msg);
- break;
- }
- if !prove_result.proof_data.is_empty() {
- log::info!("query proof and prove state: {:?}", batch_index);
- prove_state(batch_index, l1_shadow_rollup).await;
- break;
+ // Query existing proof
+ if let Some(prove_result) = query_proof(batch_index).await {
+ if !prove_result.error_code.is_empty() {
+ log::error!("query proof and prove state error, batch_index: {:?}, prove_result.error_code: {:?}, prove_result.error_msg: {:?}", batch_index, prove_result.error_code, prove_result.error_msg);
+ break;
+ }
+ if !prove_result.proof_data.is_empty() {
+ log::info!("query proof and prove state: {:?}", batch_index);
+ self.prove_state(batch_index, prove_info.batch_header.clone()).await;
+ break;
+ }
}
- }
- // Request the proverServer to prove.
- let request = ProveRequest {
- batch_index,
- start_block: batch_info.start_block,
- end_block: batch_info.end_block,
- rpc: l2_rpc.to_owned(),
- shadow: false,
- };
- let rt = tokio::task::spawn_blocking(move || {
- util::call_prover(serde_json::to_string(&request).unwrap(), "/prove_batch")
- })
- .await
- .unwrap();
+ // Request the proverServer to prove.
+ let request = ProveRequest {
+ batch_index,
+ start_block: prove_info.batch_info.start_block,
+ end_block: prove_info.batch_info.end_block,
+ rpc: l2_rpc.to_owned(),
+ shadow: false,
+ };
+ let rt = tokio::task::spawn_blocking(move || {
+ util::call_prover(serde_json::to_string(&request).unwrap(), "/prove_batch")
+ })
+ .await
+ .unwrap();
- match rt {
- Some(info) => match info.as_str() {
- task_status::STARTED => log::info!(
- "successfully submitted prove task, waiting for proof to be generated"
- ),
- task_status::PROVING => log::info!("waiting for prev proof to be generated"),
- task_status::PROVED => {
- log::info!("proof already generated");
- prove_state(batch_index, l1_shadow_rollup).await;
- break;
- }
- _ => {
- log::error!("submit prove task failed: {:#?}", info);
+ match rt {
+ Some(info) => match info.as_str() {
+ task_status::STARTED => log::info!(
+ "successfully submitted prove task, waiting for proof to be generated"
+ ),
+ task_status::PROVING => log::info!("waiting for prev proof to be generated"),
+ task_status::PROVED => {
+ log::info!("proof already generated");
+ self.prove_state(batch_index, prove_info.batch_header.clone()).await;
+ break;
+ }
+ _ => {
+ log::error!("submit prove task failed: {:#?}", info);
+ continue;
+ }
+ },
+ None => {
+ log::error!("submit prove task failed");
continue;
}
- },
- None => {
- log::error!("submit prove task failed");
- continue;
}
- }
- // Step5. query proof and prove onchain state.
- let mut max_waiting_time: usize = 300 * blocks_len as usize; //block_prove_time = 5min
- while max_waiting_time > 60 {
- sleep(Duration::from_secs(60)).await;
- max_waiting_time -= 60; // Query results every 1 minute.
- match query_proof(batch_index).await {
- Some(prove_result) => {
- if !prove_result.error_code.is_empty() {
- log::error!("query proof and prove state error, batch_index: {:?}, prove_result.error_code: {:?}, prove_result.error_msg: {:?}", batch_index, prove_result.error_code, prove_result.error_msg);
- return;
+ // Step5. query proof and prove onchain state.
+ let mut max_waiting_time: usize = 300 * blocks_len as usize; //block_prove_time = 5min
+ while max_waiting_time > 60 {
+ sleep(Duration::from_secs(60)).await;
+ max_waiting_time -= 60; // Query results every 1 minute.
+ match query_proof(batch_index).await {
+ Some(prove_result) => {
+ if !prove_result.error_code.is_empty() {
+ log::error!("query proof and prove state error, batch_index: {:?}, prove_result.error_code: {:?}, prove_result.error_msg: {:?}", batch_index, prove_result.error_code, prove_result.error_msg);
+ return;
+ }
+ log::debug!("query proof and prove state: {:#?}", batch_index);
+ if !prove_result.proof_data.is_empty() {
+ self.prove_state(batch_index, prove_info.batch_header.clone()).await;
+ return;
+ }
}
- log::debug!("query proof and prove state: {:#?}", batch_index);
- if !prove_result.proof_data.is_empty() {
- prove_state(batch_index, l1_shadow_rollup).await;
- return;
+ None => {
+ log::error!("prover status unknown, resubmit task");
+ break;
}
}
- None => {
- log::error!("prover status unknown, resubmit task");
- break;
- }
}
}
}
-}
-async fn prove_state(batch_index: u64, shadow_rollup: &ShadowRollupInstance
) -> bool
-where
- P: Provider + Clone,
- N: Network,
-{
- for _ in 0..MAX_RETRY_TIMES {
- sleep(Duration::from_secs(12)).await;
- let prove_result = match query_proof(batch_index).await {
- Some(pr) => pr,
- None => continue,
- };
+ async fn prove_state(&self, batch_index: u64, batch_header: Bytes) -> bool {
+ for _ in 0..MAX_RETRY_TIMES {
+ sleep(Duration::from_secs(12)).await;
+ let prove_result = match query_proof(batch_index).await {
+ Some(pr) => pr,
+ None => continue,
+ };
- if prove_result.proof_data.is_empty() {
- log::warn!("query proof of {:#?}, proof_data is empty", batch_index);
- continue;
- }
+ if prove_result.proof_data.is_empty() {
+ log::warn!("query proof of {:#?}, proof_data is empty", batch_index);
+ continue;
+ }
- log::info!(">Starting prove state onchain, batch index = {:#?}", batch_index);
- let aggr_proof = Bytes::from(prove_result.proof_data);
- let shadow_tx = shadow_rollup.proveState(batch_index, aggr_proof);
- let send = shadow_tx.send().await;
+ log::info!(">Starting prove state onchain, batch index = {:#?}", batch_index);
+ let aggr_proof = Bytes::from(prove_result.proof_data);
+ match self
+ .l1_rollup
+ .proveCommittedBatchState(batch_header.clone(), aggr_proof.clone())
+ .call()
+ .await
+ {
+ Ok(_) => log::info!(
+ "proveCommittedBatchState call success, batch index = {:#?}",
+ batch_index
+ ),
+ Err(e) => {
+ log::error!("proveCommittedBatchState call error: {:#?}", e);
+ METRICS.shadow_verify_result.set(2);
+ }
+ }
+ let shadow_tx = self.l1_shadow_rollup.proveState(batch_index, aggr_proof);
+ let send = shadow_tx.send().await;
- let pending_tx = match send {
- Ok(pending_tx) => pending_tx,
- Err(e) => {
- log::error!("send tx of prove_state error: {:#?}", e);
- METRICS.shadow_verify_result.set(2);
- continue;
+ let pending_tx = match send {
+ Ok(pending_tx) => pending_tx,
+ Err(e) => {
+ log::error!("send tx of prove_state error: {:#?}", e);
+ METRICS.shadow_verify_result.set(2);
+ continue;
+ }
+ };
+ let receipt = pending_tx.get_receipt().await.unwrap();
+ if receipt.status() {
+ log::info!("tx of prove_state success, tx hash: {:?}", receipt.transaction_hash());
+ METRICS.shadow_verify_result.set(1);
+ return true;
}
- };
- let receipt = pending_tx.get_receipt().await.unwrap();
- if receipt.status() {
- log::info!("tx of prove_state success, tx hash: {:?}", receipt.transaction_hash());
- return true;
+ log::error!("tx of prove_state failed, tx hash: {:?}", receipt.transaction_hash());
}
- log::error!("tx of prove_state failed, tx hash: {:?}", receipt.transaction_hash());
+ false
}
- false
}
/**
From 537b16a0962b3ecce7820fca3511558a03ccf8d4 Mon Sep 17 00:00:00 2001
From: chengwenxi <22697326+chengwenxi@users.noreply.github.com>
Date: Fri, 27 Feb 2026 09:51:19 +0800
Subject: [PATCH 02/21] update morph-reth deps and fix MorphTx V1 decoding
---
prover/Cargo.lock | 735 ++++++++++++------
prover/Cargo.toml | 60 +-
prover/crates/executor/client/Cargo.toml | 1 +
.../crates/executor/client/src/types/blob.rs | 145 +++-
prover/crates/executor/core/src/executor.rs | 20 +-
prover/crates/executor/host/src/execute.rs | 3 +
prover/crates/primitives/src/lib.rs | 34 +-
prover/crates/primitives/src/types/tx.rs | 21 +
.../crates/storage/rpc-db/src/basic_rpc_db.rs | 1 +
prover/crates/storage/witness-db/src/lib.rs | 1 +
prover/rust-toolchain | 2 +-
11 files changed, 757 insertions(+), 266 deletions(-)
diff --git a/prover/Cargo.lock b/prover/Cargo.lock
index 839f0cac2..69c9d488d 100644
--- a/prover/Cargo.lock
+++ b/prover/Cargo.lock
@@ -63,18 +63,18 @@ checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f"
[[package]]
name = "alloy"
-version = "1.1.3"
+version = "1.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f07655fedc35188f3c50ff8fc6ee45703ae14ef1bc7ae7d80e23a747012184e3"
+checksum = "07dc44b606f29348ce7c127e7f872a6d2df3cfeff85b7d6bba62faca75112fdd"
dependencies = [
"alloy-core",
]
[[package]]
name = "alloy-chains"
-version = "0.2.23"
+version = "0.2.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "35d744058a9daa51a8cf22a3009607498fcf82d3cf4c5444dd8056cdf651f471"
+checksum = "90f374d3c6d729268bbe2d0e0ff992bb97898b2df756691a62ee1d5f0506bc39"
dependencies = [
"alloy-primitives",
"alloy-rlp",
@@ -85,9 +85,9 @@ dependencies = [
[[package]]
name = "alloy-consensus"
-version = "1.1.3"
+version = "1.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2e318e25fb719e747a7e8db1654170fc185024f3ed5b10f86c08d448a912f6e2"
+checksum = "b0c0dc44157867da82c469c13186015b86abef209bf0e41625e4b68bac61d728"
dependencies = [
"alloy-eips",
"alloy-primitives",
@@ -112,9 +112,9 @@ dependencies = [
[[package]]
name = "alloy-consensus-any"
-version = "1.1.3"
+version = "1.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "364380a845193a317bcb7a5398fc86cdb66c47ebe010771dde05f6869bf9e64a"
+checksum = "ba4cdb42df3871cd6b346d6a938ec2ba69a9a0f49d1f82714bc5c48349268434"
dependencies = [
"alloy-consensus",
"alloy-eips",
@@ -211,15 +211,28 @@ dependencies = [
"thiserror 2.0.17",
]
+[[package]]
+name = "alloy-eip7928"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d3231de68d5d6e75332b7489cfcc7f4dfabeba94d990a10e4b923af0e6623540"
+dependencies = [
+ "alloy-primitives",
+ "alloy-rlp",
+ "borsh",
+ "serde",
+]
+
[[package]]
name = "alloy-eips"
-version = "1.2.1"
+version = "1.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6847d641141b92a1557094aa6c236cbe49c06fb24144d4a21fe6acb970c15888"
+checksum = "b9f7ef09f21bd1e9cb8a686f168cb4a206646804567f0889eadb8dcc4c9288c8"
dependencies = [
"alloy-eip2124",
"alloy-eip2930",
"alloy-eip7702",
+ "alloy-eip7928",
"alloy-primitives",
"alloy-rlp",
"alloy-serde",
@@ -238,9 +251,9 @@ dependencies = [
[[package]]
name = "alloy-evm"
-version = "0.25.2"
+version = "0.26.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e6ccc4c702c840148af1ce784cc5c6ed9274a020ef32417c5b1dbeab8c317673"
+checksum = "7b99ba7b74a87176f31ee1cd26768f7155b0eeff61ed925f59b13085ffe5f891"
dependencies = [
"alloy-consensus",
"alloy-eips",
@@ -259,9 +272,9 @@ dependencies = [
[[package]]
name = "alloy-genesis"
-version = "1.1.3"
+version = "1.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1ba4b1be0988c11f0095a2380aa596e35533276b8fa6c9e06961bbfe0aebcac5"
+checksum = "7c9cf3b99f46615fbf7dc1add0c96553abb7bf88fc9ec70dfbe7ad0b47ba7fe8"
dependencies = [
"alloy-eips",
"alloy-primitives",
@@ -274,9 +287,9 @@ dependencies = [
[[package]]
name = "alloy-hardforks"
-version = "0.4.5"
+version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2d9a33550fc21fd77a3f8b63e99969d17660eec8dcc50a95a80f7c9964f7680b"
+checksum = "83ba208044232d14d4adbfa77e57d6329f51bc1acc21f5667bb7db72d88a0831"
dependencies = [
"alloy-chains",
"alloy-eip2124",
@@ -288,9 +301,9 @@ dependencies = [
[[package]]
name = "alloy-json-abi"
-version = "1.4.1"
+version = "1.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5513d5e6bd1cba6bdcf5373470f559f320c05c8c59493b6e98912fbe6733943f"
+checksum = "e9dbe713da0c737d9e5e387b0ba790eb98b14dd207fe53eef50e19a5a8ec3dac"
dependencies = [
"alloy-primitives",
"alloy-sol-type-parser",
@@ -300,9 +313,9 @@ dependencies = [
[[package]]
name = "alloy-json-rpc"
-version = "1.2.1"
+version = "1.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d4ab3330e491053e9608b2a315f147357bb8acb9377a988c1203f2e8e2b296c9"
+checksum = "ff42cd777eea61f370c0b10f2648a1c81e0b783066cd7269228aa993afd487f7"
dependencies = [
"alloy-primitives",
"alloy-sol-types",
@@ -315,9 +328,9 @@ dependencies = [
[[package]]
name = "alloy-network"
-version = "1.1.3"
+version = "1.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "12aeb37b6f2e61b93b1c3d34d01ee720207c76fe447e2a2c217e433ac75b17f5"
+checksum = "8cbca04f9b410fdc51aaaf88433cbac761213905a65fe832058bcf6690585762"
dependencies = [
"alloy-consensus",
"alloy-consensus-any",
@@ -341,9 +354,9 @@ dependencies = [
[[package]]
name = "alloy-network-primitives"
-version = "1.1.3"
+version = "1.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "abd29ace62872083e30929cd9b282d82723196d196db589f3ceda67edcc05552"
+checksum = "42d6d15e069a8b11f56bef2eccbad2a873c6dd4d4c81d04dda29710f5ea52f04"
dependencies = [
"alloy-consensus",
"alloy-eips",
@@ -354,9 +367,9 @@ dependencies = [
[[package]]
name = "alloy-primitives"
-version = "1.4.1"
+version = "1.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "355bf68a433e0fd7f7d33d5a9fc2583fde70bf5c530f63b80845f8da5505cf28"
+checksum = "de3b431b4e72cd8bd0ec7a50b4be18e73dab74de0dba180eef171055e5d5926e"
dependencies = [
"alloy-rlp",
"bytes",
@@ -372,19 +385,19 @@ dependencies = [
"paste",
"proptest",
"rand 0.9.2",
+ "rapidhash",
"rayon",
"ruint",
"rustc-hash 2.1.1",
"serde",
"sha3",
- "tiny-keccak",
]
[[package]]
name = "alloy-provider"
-version = "1.1.3"
+version = "1.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9b710636d7126e08003b8217e24c09f0cca0b46d62f650a841736891b1ed1fc1"
+checksum = "d181c8cc7cf4805d7e589bf4074d56d55064fa1a979f005a45a62b047616d870"
dependencies = [
"alloy-chains",
"alloy-consensus",
@@ -406,7 +419,7 @@ dependencies = [
"either",
"futures",
"futures-utils-wasm",
- "lru 0.13.0",
+ "lru 0.16.3",
"parking_lot",
"pin-project",
"reqwest",
@@ -421,9 +434,9 @@ dependencies = [
[[package]]
name = "alloy-rlp"
-version = "0.3.12"
+version = "0.3.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5f70d83b765fdc080dbcd4f4db70d8d23fe4761f2f02ebfa9146b833900634b4"
+checksum = "e93e50f64a77ad9c5470bf2ad0ca02f228da70c792a8f06634801e202579f35e"
dependencies = [
"alloy-rlp-derive",
"arrayvec",
@@ -432,9 +445,9 @@ dependencies = [
[[package]]
name = "alloy-rlp-derive"
-version = "0.3.12"
+version = "0.3.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "64b728d511962dda67c1bc7ea7c03736ec275ed2cf4c35d9585298ac9ccf3b73"
+checksum = "ce8849c74c9ca0f5a03da1c865e3eb6f768df816e67dd3721a398a8a7e398011"
dependencies = [
"proc-macro2",
"quote",
@@ -443,9 +456,9 @@ dependencies = [
[[package]]
name = "alloy-rpc-client"
-version = "1.1.3"
+version = "1.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d0882e72d2c1c0c79dcf4ab60a67472d3f009a949f774d4c17d0bdb669cfde05"
+checksum = "f2792758a93ae32a32e9047c843d536e1448044f78422d71bf7d7c05149e103f"
dependencies = [
"alloy-json-rpc",
"alloy-primitives",
@@ -466,11 +479,12 @@ dependencies = [
[[package]]
name = "alloy-rpc-types"
-version = "1.1.3"
+version = "1.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "39cf1398cb33aacb139a960fa3d8cf8b1202079f320e77e952a0b95967bf7a9f"
+checksum = "7bdcbf9dfd5eea8bfeb078b1d906da8cd3a39c4d4dbe7a628025648e323611f6"
dependencies = [
"alloy-primitives",
+ "alloy-rpc-types-engine",
"alloy-rpc-types-eth",
"alloy-serde",
"serde",
@@ -478,9 +492,9 @@ dependencies = [
[[package]]
name = "alloy-rpc-types-any"
-version = "1.1.3"
+version = "1.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6a63fb40ed24e4c92505f488f9dd256e2afaed17faa1b7a221086ebba74f4122"
+checksum = "dd720b63f82b457610f2eaaf1f32edf44efffe03ae25d537632e7d23e7929e1a"
dependencies = [
"alloy-consensus-any",
"alloy-rpc-types-eth",
@@ -489,9 +503,9 @@ dependencies = [
[[package]]
name = "alloy-rpc-types-debug"
-version = "1.1.3"
+version = "1.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4936f579d9d10eae01772b2ab3497f9d568684f05f26f8175e12f9a1a2babc33"
+checksum = "e1b21e1ad18ff1b31ff1030e046462ab8168cf8894e6778cd805c8bdfe2bd649"
dependencies = [
"alloy-primitives",
"derive_more 2.1.0",
@@ -501,9 +515,9 @@ dependencies = [
[[package]]
name = "alloy-rpc-types-engine"
-version = "1.1.3"
+version = "1.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4c60bdce3be295924122732b7ecd0b2495ce4790bedc5370ca7019c08ad3f26e"
+checksum = "e4ac61f03f1edabccde1c687b5b25fff28f183afee64eaa2e767def3929e4457"
dependencies = [
"alloy-consensus",
"alloy-eips",
@@ -513,6 +527,7 @@ dependencies = [
"derive_more 2.1.0",
"ethereum_ssz",
"ethereum_ssz_derive",
+ "jsonwebtoken",
"rand 0.8.5",
"serde",
"strum 0.27.2",
@@ -520,9 +535,9 @@ dependencies = [
[[package]]
name = "alloy-rpc-types-eth"
-version = "1.1.3"
+version = "1.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9eae0c7c40da20684548cbc8577b6b7447f7bf4ddbac363df95e3da220e41e72"
+checksum = "9b2dc411f13092f237d2bf6918caf80977fc2f51485f9b90cb2a2f956912c8c9"
dependencies = [
"alloy-consensus",
"alloy-consensus-any",
@@ -541,9 +556,9 @@ dependencies = [
[[package]]
name = "alloy-serde"
-version = "1.2.1"
+version = "1.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "067b718d2e6ac1bb889341fcc7a250cfa49bcd3ba4f23923f1c1eb1f2b10cb7c"
+checksum = "e2ce1e0dbf7720eee747700e300c99aac01b1a95bb93f493a01e78ee28bb1a37"
dependencies = [
"alloy-primitives",
"serde",
@@ -552,9 +567,9 @@ dependencies = [
[[package]]
name = "alloy-signer"
-version = "1.2.1"
+version = "1.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "acff6b251740ef473932386d3b71657d3825daebf2217fb41a7ef676229225d4"
+checksum = "2425c6f314522c78e8198979c8cbf6769362be4da381d4152ea8eefce383535d"
dependencies = [
"alloy-primitives",
"async-trait",
@@ -586,9 +601,9 @@ dependencies = [
[[package]]
name = "alloy-signer-local"
-version = "1.1.3"
+version = "1.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "72cfe0be3ec5a8c1a46b2e5a7047ed41121d360d97f4405bb7c1c784880c86cb"
+checksum = "c3ecb71ee53d8d9c3fa7bac17542c8116ebc7a9726c91b1bf333ec3d04f5a789"
dependencies = [
"alloy-consensus",
"alloy-network",
@@ -602,9 +617,9 @@ dependencies = [
[[package]]
name = "alloy-sol-macro"
-version = "1.4.1"
+version = "1.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f3ce480400051b5217f19d6e9a82d9010cdde20f1ae9c00d53591e4a1afbb312"
+checksum = "ab81bab693da9bb79f7a95b64b394718259fdd7e41dceeced4cad57cb71c4f6a"
dependencies = [
"alloy-sol-macro-expander",
"alloy-sol-macro-input",
@@ -616,9 +631,9 @@ dependencies = [
[[package]]
name = "alloy-sol-macro-expander"
-version = "1.4.1"
+version = "1.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6d792e205ed3b72f795a8044c52877d2e6b6e9b1d13f431478121d8d4eaa9028"
+checksum = "489f1620bb7e2483fb5819ed01ab6edc1d2f93939dce35a5695085a1afd1d699"
dependencies = [
"alloy-json-abi",
"alloy-sol-macro-input",
@@ -628,16 +643,16 @@ dependencies = [
"proc-macro-error2",
"proc-macro2",
"quote",
+ "sha3",
"syn 2.0.111",
"syn-solidity",
- "tiny-keccak",
]
[[package]]
name = "alloy-sol-macro-input"
-version = "1.4.1"
+version = "1.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0bd1247a8f90b465ef3f1207627547ec16940c35597875cdc09c49d58b19693c"
+checksum = "56cef806ad22d4392c5fc83cf8f2089f988eb99c7067b4e0c6f1971fc1cca318"
dependencies = [
"alloy-json-abi",
"const-hex",
@@ -653,9 +668,9 @@ dependencies = [
[[package]]
name = "alloy-sol-type-parser"
-version = "1.4.1"
+version = "1.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "954d1b2533b9b2c7959652df3076954ecb1122a28cc740aa84e7b0a49f6ac0a9"
+checksum = "a6df77fea9d6a2a75c0ef8d2acbdfd92286cc599983d3175ccdc170d3433d249"
dependencies = [
"serde",
"winnow 0.7.14",
@@ -663,9 +678,9 @@ dependencies = [
[[package]]
name = "alloy-sol-types"
-version = "1.4.1"
+version = "1.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "70319350969a3af119da6fb3e9bddb1bce66c9ea933600cb297c8b1850ad2a3c"
+checksum = "64612d29379782a5dde6f4b6570d9c756d734d760c0c94c254d361e678a6591f"
dependencies = [
"alloy-json-abi",
"alloy-primitives",
@@ -675,9 +690,9 @@ dependencies = [
[[package]]
name = "alloy-transport"
-version = "1.1.3"
+version = "1.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "be98b07210d24acf5b793c99b759e9a696e4a2e67593aec0487ae3b3e1a2478c"
+checksum = "fa186e560d523d196580c48bf00f1bf62e63041f28ecf276acc22f8b27bb9f53"
dependencies = [
"alloy-json-rpc",
"auto_impl",
@@ -698,12 +713,13 @@ dependencies = [
[[package]]
name = "alloy-transport-http"
-version = "1.1.3"
+version = "1.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4198a1ee82e562cab85e7f3d5921aab725d9bd154b6ad5017f82df1695877c97"
+checksum = "aa501ad58dd20acddbfebc65b52e60f05ebf97c52fa40d1b35e91f5e2da0ad0e"
dependencies = [
"alloy-json-rpc",
"alloy-transport",
+ "itertools 0.14.0",
"reqwest",
"serde_json",
"tower 0.5.2",
@@ -713,9 +729,9 @@ dependencies = [
[[package]]
name = "alloy-trie"
-version = "0.9.1"
+version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e3412d52bb97c6c6cc27ccc28d4e6e8cf605469101193b50b0bd5813b1f990b5"
+checksum = "4d7fd448ab0a017de542de1dcca7a58e7019fe0e7a34ed3f9543ebddf6aceffa"
dependencies = [
"alloy-primitives",
"alloy-rlp",
@@ -724,14 +740,15 @@ dependencies = [
"nybbles",
"serde",
"smallvec",
+ "thiserror 2.0.17",
"tracing",
]
[[package]]
name = "alloy-tx-macros"
-version = "1.2.1"
+version = "1.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "04950a13cc4209d8e9b78f306e87782466bad8538c94324702d061ff03e211c9"
+checksum = "6fa0c53e8c1e1ef4d01066b01c737fb62fc9397ab52c6e7bb5669f97d281b9bc"
dependencies = [
"darling 0.21.3",
"proc-macro2",
@@ -1666,12 +1683,6 @@ dependencies = [
"tracing",
]
-[[package]]
-name = "az"
-version = "1.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7b7e4c2464d97fe331d41de9d5db0def0a96f4d823b8b32a2efd503578988973"
-
[[package]]
name = "backoff"
version = "0.4.0"
@@ -2990,6 +3001,27 @@ dependencies = [
"static_assertions",
]
+[[package]]
+name = "fixed-map"
+version = "0.9.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "86ed19add84e8cb9e8cc5f7074de0324247149ffef0b851e215fb0edc50c229b"
+dependencies = [
+ "fixed-map-derive",
+ "serde",
+]
+
+[[package]]
+name = "fixed-map-derive"
+version = "0.9.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6dc7a9cb3326bafb80642c5ce99b39a2c0702d4bfa8ee8a3e773791a6cbe2407"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.111",
+]
+
[[package]]
name = "flexi_logger"
version = "0.29.0"
@@ -3225,16 +3257,6 @@ version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
-[[package]]
-name = "gmp-mpfr-sys"
-version = "1.6.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "60f8970a75c006bb2f8ae79c6768a116dd215fa8346a87aed99bf9d82ca43394"
-dependencies = [
- "libc",
- "windows-sys 0.60.2",
-]
-
[[package]]
name = "group"
version = "0.12.1"
@@ -3353,6 +3375,8 @@ version = "0.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100"
dependencies = [
+ "allocator-api2",
+ "equivalent",
"foldhash 0.2.0",
"rayon",
"serde",
@@ -3918,6 +3942,21 @@ dependencies = [
"wasm-bindgen",
]
+[[package]]
+name = "jsonwebtoken"
+version = "9.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5a87cc7a48537badeae96744432de36f4be2b4a34a05a5ef32e9dd8a1c169dde"
+dependencies = [
+ "base64 0.22.1",
+ "js-sys",
+ "pem",
+ "ring",
+ "serde",
+ "serde_json",
+ "simple_asn1",
+]
+
[[package]]
name = "jubjub"
version = "0.9.0"
@@ -3959,9 +3998,9 @@ dependencies = [
[[package]]
name = "keccak-asm"
-version = "0.1.3"
+version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "422fbc7ff2f2f5bdffeb07718e5a5324dca72b0c9293d50df4026652385e3314"
+checksum = "b646a74e746cd25045aa0fd42f4f7f78aa6d119380182c7e63a5593c4ab8df6f"
dependencies = [
"digest 0.10.7",
"sha3-asm",
@@ -4080,11 +4119,11 @@ dependencies = [
[[package]]
name = "lru"
-version = "0.13.0"
+version = "0.16.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "227748d55f2f0ab4735d87fd623798cb6b664512fe979705f829c9f81c934465"
+checksum = "a1dc47f592c06f33f8e3aea9591776ec7c9f9e4124778ff8a3c3b87159f7e593"
dependencies = [
- "hashbrown 0.15.5",
+ "hashbrown 0.16.1",
]
[[package]]
@@ -4137,6 +4176,27 @@ version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d97bbf43eb4f088f8ca469930cde17fa036207c9a5e02ccc5107c4e8b17c964"
+[[package]]
+name = "metrics"
+version = "0.24.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5d5312e9ba3771cfa961b585728215e3d972c950a3eed9252aa093d6301277e8"
+dependencies = [
+ "ahash",
+ "portable-atomic",
+]
+
+[[package]]
+name = "metrics-derive"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "161ab904c2c62e7bda0f7562bf22f96440ca35ff79e66c800cbac298f2f4f5ec"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.111",
+]
+
[[package]]
name = "mime"
version = "0.3.17"
@@ -4194,7 +4254,7 @@ dependencies = [
[[package]]
name = "morph-chainspec"
version = "0.7.5"
-source = "git+https://github.com/morph-l2/morph-reth.git?branch=main#fe322be5ad1436309c298ae269698d4534285374"
+source = "git+https://github.com/morph-l2/morph-reth.git?branch=reference-key-fix#df825ca8a03827029bbd5f4dcbfae5fd4b93a6f9"
dependencies = [
"alloy-chains",
"alloy-consensus",
@@ -4208,6 +4268,7 @@ dependencies = [
"morph-primitives",
"reth-chainspec",
"reth-network-peers",
+ "reth-primitives-traits",
"serde",
"serde_json",
]
@@ -4215,17 +4276,19 @@ dependencies = [
[[package]]
name = "morph-evm"
version = "0.7.5"
-source = "git+https://github.com/morph-l2/morph-reth.git?branch=main#fe322be5ad1436309c298ae269698d4534285374"
+source = "git+https://github.com/morph-l2/morph-reth.git?branch=reference-key-fix#df825ca8a03827029bbd5f4dcbfae5fd4b93a6f9"
dependencies = [
"alloy-consensus",
"alloy-evm",
"alloy-primitives",
"derive_more 2.1.0",
"morph-chainspec",
+ "morph-payload-types",
"morph-primitives",
"morph-revm",
+ "reth-chainspec",
+ "reth-ethereum-primitives",
"reth-evm",
- "reth-evm-ethereum",
"reth-primitives-traits",
"reth-revm",
"revm",
@@ -4233,17 +4296,36 @@ dependencies = [
"tracing",
]
+[[package]]
+name = "morph-payload-types"
+version = "0.7.5"
+source = "git+https://github.com/morph-l2/morph-reth.git?branch=reference-key-fix#df825ca8a03827029bbd5f4dcbfae5fd4b93a6f9"
+dependencies = [
+ "alloy-consensus",
+ "alloy-eips",
+ "alloy-primitives",
+ "alloy-rlp",
+ "alloy-rpc-types-engine",
+ "alloy-serde",
+ "morph-primitives",
+ "reth-ethereum-primitives",
+ "reth-payload-builder",
+ "reth-payload-primitives",
+ "reth-primitives-traits",
+ "serde",
+ "sha2",
+]
+
[[package]]
name = "morph-primitives"
version = "0.7.5"
-source = "git+https://github.com/morph-l2/morph-reth.git?branch=main#fe322be5ad1436309c298ae269698d4534285374"
+source = "git+https://github.com/morph-l2/morph-reth.git?branch=reference-key-fix#df825ca8a03827029bbd5f4dcbfae5fd4b93a6f9"
dependencies = [
"alloy-consensus",
"alloy-eips",
"alloy-primitives",
"alloy-rlp",
"alloy-serde",
- "bytes",
"reth-ethereum-primitives",
"reth-primitives-traits",
"serde",
@@ -4275,7 +4357,7 @@ dependencies = [
[[package]]
name = "morph-revm"
version = "0.7.5"
-source = "git+https://github.com/morph-l2/morph-reth.git?branch=main#fe322be5ad1436309c298ae269698d4534285374"
+source = "git+https://github.com/morph-l2/morph-reth.git?branch=reference-key-fix#df825ca8a03827029bbd5f4dcbfae5fd4b93a6f9"
dependencies = [
"alloy-consensus",
"alloy-eips",
@@ -4287,6 +4369,7 @@ dependencies = [
"derive_more 2.1.0",
"morph-chainspec",
"morph-primitives",
+ "reth-ethereum-primitives",
"reth-evm",
"revm",
"thiserror 2.0.17",
@@ -4402,9 +4485,9 @@ dependencies = [
[[package]]
name = "num-conv"
-version = "0.1.0"
+version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
+checksum = "cf97ec579c3c42f953ef76dbf8d55ac91fb219dde70e49aa4a6b7d74e9919050"
[[package]]
name = "num-integer"
@@ -4508,7 +4591,7 @@ version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56"
dependencies = [
- "proc-macro-crate 3.1.0",
+ "proc-macro-crate 1.3.1",
"proc-macro2",
"quote",
"syn 2.0.111",
@@ -4596,6 +4679,7 @@ dependencies = [
"alloy-serde",
"derive_more 2.1.0",
"serde",
+ "serde_with",
"thiserror 2.0.17",
]
@@ -4673,9 +4757,9 @@ dependencies = [
[[package]]
name = "op-revm"
-version = "14.1.0"
+version = "15.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1475a779c73999fc803778524042319691b31f3d6699d2b560c4ed8be1db802a"
+checksum = "79c92b75162c2ed1661849fa51683b11254a5b661798360a2c24be918edafd40"
dependencies = [
"auto_impl",
"revm",
@@ -5108,6 +5192,16 @@ version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3"
+[[package]]
+name = "pem"
+version = "3.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1d30c53c26bc5b31a98cd02d20f25a7c8567146caf63ed593a9d87b2775291be"
+dependencies = [
+ "base64 0.22.1",
+ "serde_core",
+]
+
[[package]]
name = "pem-rfc7468"
version = "0.7.0"
@@ -5426,6 +5520,7 @@ name = "prover-executor-client"
version = "0.1.0"
dependencies = [
"alloy-consensus",
+ "alloy-eips",
"alloy-primitives",
"alloy-rlp",
"anyhow",
@@ -5643,7 +5738,7 @@ dependencies = [
"once_cell",
"socket2 0.6.1",
"tracing",
- "windows-sys 0.60.2",
+ "windows-sys 0.59.0",
]
[[package]]
@@ -5750,6 +5845,15 @@ dependencies = [
"num-traits",
]
+[[package]]
+name = "rapidhash"
+version = "4.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b5e48930979c155e2f33aa36ab3119b5ee81332beb6482199a8ecd6029b80b59"
+dependencies = [
+ "rustversion",
+]
+
[[package]]
name = "rayon"
version = "1.10.0"
@@ -5799,6 +5903,26 @@ dependencies = [
"thiserror 1.0.63",
]
+[[package]]
+name = "ref-cast"
+version = "1.0.25"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f354300ae66f76f1c85c5f84693f0ce81d747e2c3f21a45fef496d89c960bf7d"
+dependencies = [
+ "ref-cast-impl",
+]
+
+[[package]]
+name = "ref-cast-impl"
+version = "1.0.25"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.111",
+]
+
[[package]]
name = "regex"
version = "1.12.2"
@@ -5901,10 +6025,36 @@ dependencies = [
"tower-service",
]
+[[package]]
+name = "reth-chain-state"
+version = "1.10.2"
+source = "git+https://github.com/paradigmxyz/reth?tag=v1.10.2#8e3b5e6a99439561b73c5dd31bd3eced2e994d60"
+dependencies = [
+ "alloy-consensus",
+ "alloy-eips",
+ "alloy-primitives",
+ "derive_more 2.1.0",
+ "metrics",
+ "parking_lot",
+ "pin-project",
+ "reth-chainspec",
+ "reth-errors",
+ "reth-ethereum-primitives",
+ "reth-execution-types",
+ "reth-metrics",
+ "reth-primitives-traits",
+ "reth-storage-api",
+ "reth-trie",
+ "revm-database",
+ "tokio",
+ "tokio-stream",
+ "tracing",
+]
+
[[package]]
name = "reth-chainspec"
-version = "1.9.3"
-source = "git+https://github.com/paradigmxyz/reth?rev=64909d3#64909d33e6b7ab60774e37f5508fb5ad17f41897"
+version = "1.10.2"
+source = "git+https://github.com/paradigmxyz/reth?tag=v1.10.2#8e3b5e6a99439561b73c5dd31bd3eced2e994d60"
dependencies = [
"alloy-chains",
"alloy-consensus",
@@ -5923,8 +6073,8 @@ dependencies = [
[[package]]
name = "reth-codecs"
-version = "1.9.3"
-source = "git+https://github.com/paradigmxyz/reth?rev=64909d3#64909d33e6b7ab60774e37f5508fb5ad17f41897"
+version = "1.10.2"
+source = "git+https://github.com/paradigmxyz/reth?tag=v1.10.2#8e3b5e6a99439561b73c5dd31bd3eced2e994d60"
dependencies = [
"alloy-consensus",
"alloy-eips",
@@ -5941,18 +6091,31 @@ dependencies = [
[[package]]
name = "reth-codecs-derive"
-version = "1.9.3"
-source = "git+https://github.com/paradigmxyz/reth?rev=64909d3#64909d33e6b7ab60774e37f5508fb5ad17f41897"
+version = "1.10.2"
+source = "git+https://github.com/paradigmxyz/reth?tag=v1.10.2#8e3b5e6a99439561b73c5dd31bd3eced2e994d60"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.111",
]
+[[package]]
+name = "reth-consensus"
+version = "1.10.2"
+source = "git+https://github.com/paradigmxyz/reth?tag=v1.10.2#8e3b5e6a99439561b73c5dd31bd3eced2e994d60"
+dependencies = [
+ "alloy-consensus",
+ "alloy-primitives",
+ "auto_impl",
+ "reth-execution-types",
+ "reth-primitives-traits",
+ "thiserror 2.0.17",
+]
+
[[package]]
name = "reth-db-models"
-version = "1.9.3"
-source = "git+https://github.com/paradigmxyz/reth?rev=64909d3#64909d33e6b7ab60774e37f5508fb5ad17f41897"
+version = "1.10.2"
+source = "git+https://github.com/paradigmxyz/reth?tag=v1.10.2#8e3b5e6a99439561b73c5dd31bd3eced2e994d60"
dependencies = [
"alloy-eips",
"alloy-primitives",
@@ -5961,10 +6124,62 @@ dependencies = [
"serde",
]
+[[package]]
+name = "reth-engine-primitives"
+version = "1.10.2"
+source = "git+https://github.com/paradigmxyz/reth?tag=v1.10.2#8e3b5e6a99439561b73c5dd31bd3eced2e994d60"
+dependencies = [
+ "alloy-consensus",
+ "alloy-eips",
+ "alloy-primitives",
+ "alloy-rpc-types-engine",
+ "auto_impl",
+ "reth-chain-state",
+ "reth-errors",
+ "reth-ethereum-primitives",
+ "reth-evm",
+ "reth-execution-types",
+ "reth-payload-builder-primitives",
+ "reth-payload-primitives",
+ "reth-primitives-traits",
+ "reth-trie-common",
+ "serde",
+ "thiserror 2.0.17",
+]
+
+[[package]]
+name = "reth-errors"
+version = "1.10.2"
+source = "git+https://github.com/paradigmxyz/reth?tag=v1.10.2#8e3b5e6a99439561b73c5dd31bd3eced2e994d60"
+dependencies = [
+ "reth-consensus",
+ "reth-execution-errors",
+ "reth-storage-errors",
+ "thiserror 2.0.17",
+]
+
+[[package]]
+name = "reth-ethereum-engine-primitives"
+version = "1.10.2"
+source = "git+https://github.com/paradigmxyz/reth?tag=v1.10.2#8e3b5e6a99439561b73c5dd31bd3eced2e994d60"
+dependencies = [
+ "alloy-eips",
+ "alloy-primitives",
+ "alloy-rlp",
+ "alloy-rpc-types-engine",
+ "reth-engine-primitives",
+ "reth-ethereum-primitives",
+ "reth-payload-primitives",
+ "reth-primitives-traits",
+ "serde",
+ "sha2",
+ "thiserror 2.0.17",
+]
+
[[package]]
name = "reth-ethereum-forks"
-version = "1.9.3"
-source = "git+https://github.com/paradigmxyz/reth?rev=64909d3#64909d33e6b7ab60774e37f5508fb5ad17f41897"
+version = "1.10.2"
+source = "git+https://github.com/paradigmxyz/reth?tag=v1.10.2#8e3b5e6a99439561b73c5dd31bd3eced2e994d60"
dependencies = [
"alloy-eip2124",
"alloy-hardforks",
@@ -5976,8 +6191,8 @@ dependencies = [
[[package]]
name = "reth-ethereum-primitives"
-version = "1.9.3"
-source = "git+https://github.com/paradigmxyz/reth?rev=64909d3#64909d33e6b7ab60774e37f5508fb5ad17f41897"
+version = "1.10.2"
+source = "git+https://github.com/paradigmxyz/reth?tag=v1.10.2#8e3b5e6a99439561b73c5dd31bd3eced2e994d60"
dependencies = [
"alloy-consensus",
"alloy-eips",
@@ -5994,8 +6209,8 @@ dependencies = [
[[package]]
name = "reth-evm"
-version = "1.9.3"
-source = "git+https://github.com/paradigmxyz/reth?rev=64909d3#64909d33e6b7ab60774e37f5508fb5ad17f41897"
+version = "1.10.2"
+source = "git+https://github.com/paradigmxyz/reth?tag=v1.10.2#8e3b5e6a99439561b73c5dd31bd3eced2e994d60"
dependencies = [
"alloy-consensus",
"alloy-eips",
@@ -6004,6 +6219,7 @@ dependencies = [
"auto_impl",
"derive_more 2.1.0",
"futures-util",
+ "rayon",
"reth-execution-errors",
"reth-execution-types",
"reth-primitives-traits",
@@ -6013,31 +6229,10 @@ dependencies = [
"revm",
]
-[[package]]
-name = "reth-evm-ethereum"
-version = "1.9.3"
-source = "git+https://github.com/paradigmxyz/reth?rev=64909d3#64909d33e6b7ab60774e37f5508fb5ad17f41897"
-dependencies = [
- "alloy-consensus",
- "alloy-eips",
- "alloy-evm",
- "alloy-primitives",
- "alloy-rpc-types-engine",
- "derive_more 2.1.0",
- "reth-chainspec",
- "reth-ethereum-forks",
- "reth-ethereum-primitives",
- "reth-evm",
- "reth-execution-types",
- "reth-primitives-traits",
- "reth-storage-errors",
- "revm",
-]
-
[[package]]
name = "reth-execution-errors"
-version = "1.9.3"
-source = "git+https://github.com/paradigmxyz/reth?rev=64909d3#64909d33e6b7ab60774e37f5508fb5ad17f41897"
+version = "1.10.2"
+source = "git+https://github.com/paradigmxyz/reth?tag=v1.10.2#8e3b5e6a99439561b73c5dd31bd3eced2e994d60"
dependencies = [
"alloy-evm",
"alloy-primitives",
@@ -6049,8 +6244,8 @@ dependencies = [
[[package]]
name = "reth-execution-types"
-version = "1.9.3"
-source = "git+https://github.com/paradigmxyz/reth?rev=64909d3#64909d33e6b7ab60774e37f5508fb5ad17f41897"
+version = "1.10.2"
+source = "git+https://github.com/paradigmxyz/reth?tag=v1.10.2#8e3b5e6a99439561b73c5dd31bd3eced2e994d60"
dependencies = [
"alloy-consensus",
"alloy-eips",
@@ -6065,10 +6260,19 @@ dependencies = [
"serde_with",
]
+[[package]]
+name = "reth-metrics"
+version = "1.10.2"
+source = "git+https://github.com/paradigmxyz/reth?tag=v1.10.2#8e3b5e6a99439561b73c5dd31bd3eced2e994d60"
+dependencies = [
+ "metrics",
+ "metrics-derive",
+]
+
[[package]]
name = "reth-network-peers"
-version = "1.9.3"
-source = "git+https://github.com/paradigmxyz/reth?rev=64909d3#64909d33e6b7ab60774e37f5508fb5ad17f41897"
+version = "1.10.2"
+source = "git+https://github.com/paradigmxyz/reth?tag=v1.10.2#8e3b5e6a99439561b73c5dd31bd3eced2e994d60"
dependencies = [
"alloy-primitives",
"alloy-rlp",
@@ -6078,10 +6282,66 @@ dependencies = [
"url",
]
+[[package]]
+name = "reth-payload-builder"
+version = "1.10.2"
+source = "git+https://github.com/paradigmxyz/reth?tag=v1.10.2#8e3b5e6a99439561b73c5dd31bd3eced2e994d60"
+dependencies = [
+ "alloy-consensus",
+ "alloy-primitives",
+ "alloy-rpc-types",
+ "futures-util",
+ "metrics",
+ "reth-chain-state",
+ "reth-ethereum-engine-primitives",
+ "reth-metrics",
+ "reth-payload-builder-primitives",
+ "reth-payload-primitives",
+ "reth-primitives-traits",
+ "tokio",
+ "tokio-stream",
+ "tracing",
+]
+
+[[package]]
+name = "reth-payload-builder-primitives"
+version = "1.10.2"
+source = "git+https://github.com/paradigmxyz/reth?tag=v1.10.2#8e3b5e6a99439561b73c5dd31bd3eced2e994d60"
+dependencies = [
+ "pin-project",
+ "reth-payload-primitives",
+ "tokio",
+ "tokio-stream",
+ "tracing",
+]
+
+[[package]]
+name = "reth-payload-primitives"
+version = "1.10.2"
+source = "git+https://github.com/paradigmxyz/reth?tag=v1.10.2#8e3b5e6a99439561b73c5dd31bd3eced2e994d60"
+dependencies = [
+ "alloy-consensus",
+ "alloy-eips",
+ "alloy-primitives",
+ "alloy-rpc-types-engine",
+ "auto_impl",
+ "either",
+ "op-alloy-rpc-types-engine",
+ "reth-chain-state",
+ "reth-chainspec",
+ "reth-errors",
+ "reth-execution-types",
+ "reth-primitives-traits",
+ "reth-trie-common",
+ "serde",
+ "thiserror 2.0.17",
+ "tokio",
+]
+
[[package]]
name = "reth-primitives-traits"
-version = "1.9.3"
-source = "git+https://github.com/paradigmxyz/reth?rev=64909d3#64909d33e6b7ab60774e37f5508fb5ad17f41897"
+version = "1.10.2"
+source = "git+https://github.com/paradigmxyz/reth?tag=v1.10.2#8e3b5e6a99439561b73c5dd31bd3eced2e994d60"
dependencies = [
"alloy-consensus",
"alloy-eips",
@@ -6107,8 +6367,8 @@ dependencies = [
[[package]]
name = "reth-prune-types"
-version = "1.9.3"
-source = "git+https://github.com/paradigmxyz/reth?rev=64909d3#64909d33e6b7ab60774e37f5508fb5ad17f41897"
+version = "1.10.2"
+source = "git+https://github.com/paradigmxyz/reth?tag=v1.10.2#8e3b5e6a99439561b73c5dd31bd3eced2e994d60"
dependencies = [
"alloy-primitives",
"derive_more 2.1.0",
@@ -6119,8 +6379,8 @@ dependencies = [
[[package]]
name = "reth-revm"
-version = "1.9.3"
-source = "git+https://github.com/paradigmxyz/reth?rev=64909d3#64909d33e6b7ab60774e37f5508fb5ad17f41897"
+version = "1.10.2"
+source = "git+https://github.com/paradigmxyz/reth?tag=v1.10.2#8e3b5e6a99439561b73c5dd31bd3eced2e994d60"
dependencies = [
"alloy-primitives",
"reth-primitives-traits",
@@ -6131,8 +6391,8 @@ dependencies = [
[[package]]
name = "reth-stages-types"
-version = "1.9.3"
-source = "git+https://github.com/paradigmxyz/reth?rev=64909d3#64909d33e6b7ab60774e37f5508fb5ad17f41897"
+version = "1.10.2"
+source = "git+https://github.com/paradigmxyz/reth?tag=v1.10.2#8e3b5e6a99439561b73c5dd31bd3eced2e994d60"
dependencies = [
"alloy-primitives",
"bytes",
@@ -6142,19 +6402,20 @@ dependencies = [
[[package]]
name = "reth-static-file-types"
-version = "1.9.3"
-source = "git+https://github.com/paradigmxyz/reth?rev=64909d3#64909d33e6b7ab60774e37f5508fb5ad17f41897"
+version = "1.10.2"
+source = "git+https://github.com/paradigmxyz/reth?tag=v1.10.2#8e3b5e6a99439561b73c5dd31bd3eced2e994d60"
dependencies = [
"alloy-primitives",
"derive_more 2.1.0",
+ "fixed-map",
"serde",
"strum 0.27.2",
]
[[package]]
name = "reth-storage-api"
-version = "1.9.3"
-source = "git+https://github.com/paradigmxyz/reth?rev=64909d3#64909d33e6b7ab60774e37f5508fb5ad17f41897"
+version = "1.10.2"
+source = "git+https://github.com/paradigmxyz/reth?tag=v1.10.2#8e3b5e6a99439561b73c5dd31bd3eced2e994d60"
dependencies = [
"alloy-consensus",
"alloy-eips",
@@ -6176,8 +6437,8 @@ dependencies = [
[[package]]
name = "reth-storage-errors"
-version = "1.9.3"
-source = "git+https://github.com/paradigmxyz/reth?rev=64909d3#64909d33e6b7ab60774e37f5508fb5ad17f41897"
+version = "1.10.2"
+source = "git+https://github.com/paradigmxyz/reth?tag=v1.10.2#8e3b5e6a99439561b73c5dd31bd3eced2e994d60"
dependencies = [
"alloy-eips",
"alloy-primitives",
@@ -6187,13 +6448,14 @@ dependencies = [
"reth-prune-types",
"reth-static-file-types",
"revm-database-interface",
+ "revm-state",
"thiserror 2.0.17",
]
[[package]]
name = "reth-trie"
-version = "1.9.3"
-source = "git+https://github.com/paradigmxyz/reth?rev=64909d3#64909d33e6b7ab60774e37f5508fb5ad17f41897"
+version = "1.10.2"
+source = "git+https://github.com/paradigmxyz/reth?tag=v1.10.2#8e3b5e6a99439561b73c5dd31bd3eced2e994d60"
dependencies = [
"alloy-consensus",
"alloy-eips",
@@ -6214,8 +6476,8 @@ dependencies = [
[[package]]
name = "reth-trie-common"
-version = "1.9.3"
-source = "git+https://github.com/paradigmxyz/reth?rev=64909d3#64909d33e6b7ab60774e37f5508fb5ad17f41897"
+version = "1.10.2"
+source = "git+https://github.com/paradigmxyz/reth?tag=v1.10.2#8e3b5e6a99439561b73c5dd31bd3eced2e994d60"
dependencies = [
"alloy-consensus",
"alloy-primitives",
@@ -6237,8 +6499,8 @@ dependencies = [
[[package]]
name = "reth-trie-sparse"
-version = "1.9.3"
-source = "git+https://github.com/paradigmxyz/reth?rev=64909d3#64909d33e6b7ab60774e37f5508fb5ad17f41897"
+version = "1.10.2"
+source = "git+https://github.com/paradigmxyz/reth?tag=v1.10.2#8e3b5e6a99439561b73c5dd31bd3eced2e994d60"
dependencies = [
"alloy-primitives",
"alloy-rlp",
@@ -6253,17 +6515,17 @@ dependencies = [
[[package]]
name = "reth-zstd-compressors"
-version = "1.9.3"
-source = "git+https://github.com/paradigmxyz/reth?rev=64909d3#64909d33e6b7ab60774e37f5508fb5ad17f41897"
+version = "1.10.2"
+source = "git+https://github.com/paradigmxyz/reth?tag=v1.10.2#8e3b5e6a99439561b73c5dd31bd3eced2e994d60"
dependencies = [
"zstd 0.13.3",
]
[[package]]
name = "revm"
-version = "33.1.0"
+version = "34.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0c85ed0028f043f87b3c88d4a4cb6f0a76440085523b6a8afe5ff003cf418054"
+checksum = "c2aabdebaa535b3575231a88d72b642897ae8106cf6b0d12eafc6bfdf50abfc7"
dependencies = [
"revm-bytecode",
"revm-context",
@@ -6280,9 +6542,9 @@ dependencies = [
[[package]]
name = "revm-bytecode"
-version = "7.1.1"
+version = "8.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e2c6b5e6e8dd1e28a4a60e5f46615d4ef0809111c9e63208e55b5c7058200fb0"
+checksum = "74d1e5c1eaa44d39d537f668bc5c3409dc01e5c8be954da6c83370bbdf006457"
dependencies = [
"bitvec",
"phf",
@@ -6292,9 +6554,9 @@ dependencies = [
[[package]]
name = "revm-context"
-version = "12.1.0"
+version = "13.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f038f0c9c723393ac897a5df9140b21cfa98f5753a2cb7d0f28fa430c4118abf"
+checksum = "892ff3e6a566cf8d72ffb627fdced3becebbd9ba64089c25975b9b028af326a5"
dependencies = [
"bitvec",
"cfg-if 1.0.0",
@@ -6309,9 +6571,9 @@ dependencies = [
[[package]]
name = "revm-context-interface"
-version = "13.1.0"
+version = "14.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "431c9a14e4ef1be41ae503708fd02d974f80ef1f2b6b23b5e402e8d854d1b225"
+checksum = "57f61cc6d23678c4840af895b19f8acfbbd546142ec8028b6526c53cc1c16c98"
dependencies = [
"alloy-eip2930",
"alloy-eip7702",
@@ -6325,9 +6587,9 @@ dependencies = [
[[package]]
name = "revm-database"
-version = "9.0.6"
+version = "10.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "980d8d6bba78c5dd35b83abbb6585b0b902eb25ea4448ed7bfba6283b0337191"
+checksum = "529528d0b05fe646be86223032c3e77aa8b05caa2a35447d538c55965956a511"
dependencies = [
"alloy-eips",
"revm-bytecode",
@@ -6339,22 +6601,23 @@ dependencies = [
[[package]]
name = "revm-database-interface"
-version = "8.0.5"
+version = "9.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8cce03e3780287b07abe58faf4a7f5d8be7e81321f93ccf3343c8f7755602bae"
+checksum = "b7bf93ac5b91347c057610c0d96e923db8c62807e03f036762d03e981feddc1d"
dependencies = [
"auto_impl",
"either",
"revm-primitives",
"revm-state",
"serde",
+ "thiserror 2.0.17",
]
[[package]]
name = "revm-handler"
-version = "14.1.0"
+version = "15.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d44f8f6dbeec3fecf9fe55f78ef0a758bdd92ea46cd4f1ca6e2a946b32c367f3"
+checksum = "0cd0e43e815a85eded249df886c4badec869195e70cdd808a13cfca2794622d2"
dependencies = [
"auto_impl",
"derive-where",
@@ -6371,9 +6634,9 @@ dependencies = [
[[package]]
name = "revm-inspector"
-version = "14.1.0"
+version = "15.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5617e49216ce1ca6c8826bcead0386bc84f49359ef67cde6d189961735659f93"
+checksum = "4f3ccad59db91ef93696536a0dbaf2f6f17cfe20d4d8843ae118edb7e97947ef"
dependencies = [
"auto_impl",
"either",
@@ -6389,9 +6652,9 @@ dependencies = [
[[package]]
name = "revm-interpreter"
-version = "31.1.0"
+version = "32.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "26ec36405f7477b9dccdc6caa3be19adf5662a7a0dffa6270cdb13a090c077e5"
+checksum = "11406408597bc249392d39295831c4b641b3a6f5c471a7c41104a7a1e3564c07"
dependencies = [
"revm-bytecode",
"revm-context-interface",
@@ -6402,9 +6665,9 @@ dependencies = [
[[package]]
name = "revm-precompile"
-version = "31.0.0"
+version = "32.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9a62958af953cc4043e93b5be9b8497df84cc3bd612b865c49a7a7dfa26a84e2"
+checksum = "50c1285c848d240678bf69cb0f6179ff5a4aee6fc8e921d89708087197a0aff3"
dependencies = [
"ark-bls12-381",
"ark-bn254",
@@ -6419,7 +6682,6 @@ dependencies = [
"p256",
"revm-primitives",
"ripemd",
- "rug",
"secp256k1 0.31.1",
"sha2",
"substrate-bn",
@@ -6427,9 +6689,9 @@ dependencies = [
[[package]]
name = "revm-primitives"
-version = "21.0.2"
+version = "22.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "29e161db429d465c09ba9cbff0df49e31049fe6b549e28eb0b7bd642fcbd4412"
+checksum = "ba580c56a8ec824a64f8a1683577876c2e1dbe5247044199e9b881421ad5dcf9"
dependencies = [
"alloy-primitives",
"num_enum 0.7.3",
@@ -6439,10 +6701,11 @@ dependencies = [
[[package]]
name = "revm-state"
-version = "8.1.1"
+version = "9.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7d8be953b7e374dbdea0773cf360debed8df394ea8d82a8b240a6b5da37592fc"
+checksum = "311720d4f0f239b041375e7ddafdbd20032a33b7bae718562ea188e188ed9fd3"
dependencies = [
+ "alloy-eip7928",
"bitflags 2.10.0",
"revm-bytecode",
"revm-primitives",
@@ -6509,18 +6772,6 @@ dependencies = [
"paste",
]
-[[package]]
-name = "rug"
-version = "1.28.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "58ad2e973fe3c3214251a840a621812a4f40468da814b1a3d6947d433c2af11f"
-dependencies = [
- "az",
- "gmp-mpfr-sys",
- "libc",
- "libm",
-]
-
[[package]]
name = "ruint"
version = "1.17.0"
@@ -6800,6 +7051,30 @@ dependencies = [
"windows-sys 0.52.0",
]
+[[package]]
+name = "schemars"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4cd191f9397d57d581cddd31014772520aa448f65ef991055d7f61582c65165f"
+dependencies = [
+ "dyn-clone",
+ "ref-cast",
+ "serde",
+ "serde_json",
+]
+
+[[package]]
+name = "schemars"
+version = "1.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a2b42f36aa1cd011945615b92222f6bf73c599a102a300334cd7f8dbeec726cc"
+dependencies = [
+ "dyn-clone",
+ "ref-cast",
+ "serde",
+ "serde_json",
+]
+
[[package]]
name = "scopeguard"
version = "1.2.0"
@@ -7028,17 +7303,18 @@ dependencies = [
[[package]]
name = "serde_with"
-version = "3.9.0"
+version = "3.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "69cecfa94848272156ea67b2b1a53f20fc7bc638c4a46d2f8abde08f05f4b857"
+checksum = "381b283ce7bc6b476d903296fb59d0d36633652b633b27f64db4fb46dcbfc3b9"
dependencies = [
"base64 0.22.1",
"chrono",
"hex",
"indexmap 1.9.3",
"indexmap 2.12.1",
- "serde",
- "serde_derive",
+ "schemars 0.9.0",
+ "schemars 1.2.1",
+ "serde_core",
"serde_json",
"serde_with_macros",
"time",
@@ -7046,11 +7322,11 @@ dependencies = [
[[package]]
name = "serde_with_macros"
-version = "3.9.0"
+version = "3.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a8fee4991ef4f274617a51ad4af30519438dacb2f56ac773b08a1922ff743350"
+checksum = "a6d4e30573c8cb306ed6ab1dca8423eec9a463ea0e155f45399455e0368b27e0"
dependencies = [
- "darling 0.20.10",
+ "darling 0.21.3",
"proc-macro2",
"quote",
"syn 2.0.111",
@@ -7112,9 +7388,9 @@ dependencies = [
[[package]]
name = "sha3-asm"
-version = "0.1.3"
+version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "57d79b758b7cb2085612b11a235055e485605a5103faccdd633f35bd7aee69dd"
+checksum = "b31139435f327c93c6038ed350ae4588e2c70a13d50599509fee6349967ba35a"
dependencies = [
"cc",
"cfg-if 1.0.0",
@@ -7189,6 +7465,18 @@ dependencies = [
"rand_core 0.6.4",
]
+[[package]]
+name = "simple_asn1"
+version = "0.6.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0d585997b0ac10be3c5ee635f1bab02d512760d14b7c468801ac8a01d9ae5f1d"
+dependencies = [
+ "num-bigint 0.4.6",
+ "num-traits",
+ "thiserror 2.0.17",
+ "time",
+]
+
[[package]]
name = "siphasher"
version = "1.0.1"
@@ -7932,9 +8220,9 @@ dependencies = [
[[package]]
name = "syn-solidity"
-version = "1.4.1"
+version = "1.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ff790eb176cc81bb8936aed0f7b9f14fc4670069a2d371b3e3b0ecce908b2cb3"
+checksum = "53f425ae0b12e2f5ae65542e00898d500d4d318b4baf09f40fd0d410454e9947"
dependencies = [
"paste",
"proc-macro2",
@@ -8083,30 +8371,30 @@ dependencies = [
[[package]]
name = "time"
-version = "0.3.44"
+version = "0.3.47"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "91e7d9e3bb61134e77bde20dd4825b97c010155709965fedf0f49bb138e52a9d"
+checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c"
dependencies = [
"deranged",
"itoa",
"num-conv",
"powerfmt",
- "serde",
+ "serde_core",
"time-core",
"time-macros",
]
[[package]]
name = "time-core"
-version = "0.1.6"
+version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "40868e7c1d2f0b8d73e4a8c7f0ff63af4f6d19be117e90bd73eb1d62cf831c6b"
+checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca"
[[package]]
name = "time-macros"
-version = "0.2.24"
+version = "0.2.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "30cfb0125f12d9c277f35663a0a33f8c30190f4e4574868a330595412d34ebf3"
+checksum = "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215"
dependencies = [
"num-conv",
"time-core",
@@ -8516,7 +8804,7 @@ version = "1.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675"
dependencies = [
- "cfg-if 1.0.0",
+ "cfg-if 0.1.10",
"static_assertions",
]
@@ -8589,6 +8877,7 @@ dependencies = [
"form_urlencoded",
"idna",
"percent-encoding",
+ "serde",
]
[[package]]
diff --git a/prover/Cargo.toml b/prover/Cargo.toml
index 127b45133..57523807a 100644
--- a/prover/Cargo.toml
+++ b/prover/Cargo.toml
@@ -71,56 +71,56 @@ sha2 = "0.10.8"
rand = "0.8"
# EVM & Blockchain (Alloy, REVM, Reth)
-alloy = { version = "1.1.3", default-features = false }
-alloy-chains = { version = "0.2.17", default-features = false }
-alloy-consensus = { version = "=1.1.3", default-features = false, features = [
+alloy = { version = "1.6.3", default-features = false }
+alloy-chains = { version = "0.2.30", default-features = false }
+alloy-consensus = { version = "1.6.3", default-features = false, features = [
"serde",
"serde-bincode-compat",
] }
-alloy-eips = { version = "1.1.3", default-features = false }
-alloy-evm = "0.25.2"
-alloy-genesis = { version = "1.1.3", default-features = false, features = [
+alloy-eips = { version = "1.6.3", default-features = false }
+alloy-evm = "0.26.4"
+alloy-genesis = { version = "1.6.3", default-features = false, features = [
"serde-bincode-compat",
] }
-alloy-json-rpc = { version = "1.1.3", default-features = false }
-alloy-network = { version = "1.1.3", default-features = false }
-alloy-primitives = { version = "1.4.1", default-features = false, features = [
+alloy-json-rpc = { version = "1.6.3", default-features = false }
+alloy-network = { version = "1.6.3", default-features = false }
+alloy-primitives = { version = "1.5.6", default-features = false, features = [
"sha3-keccak",
"map-hashbrown",
] }
-alloy-provider = { version = "1.1.3", default-features = false, features = [
+alloy-provider = { version = "1.6.3", default-features = false, features = [
"reqwest",
"reqwest-rustls-tls",
] }
-alloy-rlp = "0.3.10"
-alloy-rpc-client = { version = "1.1.3", default-features = false }
-alloy-rpc-types = { version = "1.1.3", default-features = false, features = [
+alloy-rlp = "0.3.13"
+alloy-rpc-client = { version = "1.6.3", default-features = false }
+alloy-rpc-types = { version = "1.6.3", default-features = false, features = [
"eth",
] }
-alloy-rpc-types-debug = { version = "1.1.3", default-features = false }
-alloy-serde = "1.1.3"
-alloy-transport = { version = "1.1.3", default-features = false }
-alloy-transport-http = { version = "1.1.3", features = [
+alloy-rpc-types-debug = { version = "1.6.3", default-features = false }
+alloy-serde = "1.6.3"
+alloy-transport = { version = "1.6.3", default-features = false }
+alloy-transport-http = { version = "1.6.3", features = [
"reqwest-rustls-tls",
], default-features = false }
-alloy-transport-ws = { version = "1.1.3" }
-alloy-trie = "0.9.1"
-alloy-sol-types = { version = "1.4.1", features = ["json"] }
-alloy-contract = { version = "1.1.3", default-features = false }
-alloy-signer-local = { version = "=1.1.3", default-features = false }
+alloy-transport-ws = { version = "1.6.3" }
+alloy-trie = "0.9.4"
+alloy-sol-types = { version = "1.5.6", features = ["json"] }
+alloy-contract = { version = "1.6.3", default-features = false }
+alloy-signer-local = { version = "1.6.3", default-features = false }
rlp = "0.5.2"
hex-literal = "0.4.1"
-revm = { version = "33.1.0", features = [
+revm = { version = "34.0.0", features = [
"optional_fee_charge",
"optional_eip7623",
], default-features = false }
-reth-primitives-traits = { git = "https://github.com/paradigmxyz/reth", rev = "64909d3", default-features = false }
-reth-storage-errors = { git = "https://github.com/paradigmxyz/reth", rev = "64909d3", default-features = false }
-reth-trie = { git = "https://github.com/paradigmxyz/reth", rev = "64909d3", default-features = false }
-morph-revm = { git = "https://github.com/morph-l2/morph-reth.git", branch = "main" }
-morph-evm = { git = "https://github.com/morph-l2/morph-reth.git", branch = "main" }
-morph-primitives = { git = "https://github.com/morph-l2/morph-reth.git", branch = "main" }
-morph-chainspec = { git = "https://github.com/morph-l2/morph-reth.git", branch = "main" }
+reth-primitives-traits = { git = "https://github.com/paradigmxyz/reth", tag = "v1.10.2", default-features = false }
+reth-storage-errors = { git = "https://github.com/paradigmxyz/reth", tag = "v1.10.2", default-features = false }
+reth-trie = { git = "https://github.com/paradigmxyz/reth", tag = "v1.10.2", default-features = false }
+morph-revm = { git = "https://github.com/morph-l2/morph-reth.git", branch = "reference-key-fix" }
+morph-evm = { git = "https://github.com/morph-l2/morph-reth.git", branch = "reference-key-fix" }
+morph-primitives = { git = "https://github.com/morph-l2/morph-reth.git", branch = "reference-key-fix" }
+morph-chainspec = { git = "https://github.com/morph-l2/morph-reth.git", branch = "reference-key-fix" }
# ZK / SP1
diff --git a/prover/crates/executor/client/Cargo.toml b/prover/crates/executor/client/Cargo.toml
index 844f43871..3d9e51c36 100644
--- a/prover/crates/executor/client/Cargo.toml
+++ b/prover/crates/executor/client/Cargo.toml
@@ -12,6 +12,7 @@ serde_with.workspace = true
ruzstd = { workspace = true }
kzg-rs = { workspace = true }
thiserror = { workspace = true }
+alloy-eips = { workspace = true }
alloy-rlp = { workspace = true }
alloy-primitives = { workspace = true, features = [
"sha3-keccak",
diff --git a/prover/crates/executor/client/src/types/blob.rs b/prover/crates/executor/client/src/types/blob.rs
index ecc4eb0ac..abffd3a5f 100644
--- a/prover/crates/executor/client/src/types/blob.rs
+++ b/prover/crates/executor/client/src/types/blob.rs
@@ -1,8 +1,12 @@
-use anyhow::{anyhow, Context, Ok};
+#[cfg(not(target_os = "zkvm"))]
+use {
+ alloy_eips::eip2718::Decodable2718,
+ alloy_rlp::{Decodable, Header},
+ prover_primitives::MorphTxEnvelope,
+};
+use anyhow::{anyhow, Context};
use ruzstd::StreamingDecoder;
use std::io::Read;
-#[cfg(not(target_os = "zkvm"))]
-use {alloy_rlp::Decodable, prover_primitives::MorphTxEnvelope};
/// This magic number is included at the start of a single Zstandard frame
pub const MAGIC_NUM: u32 = 0xFD2F_B528;
@@ -66,7 +70,7 @@ pub fn decode_transactions(bs: &[u8]) -> Vec {
let tx_len_size = if first_byte > 0xf7 {
(first_byte - 0xf7) as usize
} else {
- // Support transaction types: 0x01, 0x02, 0x04
+ // Support transaction types: 0x01, 0x02, 0x04, 0x7f
if first_byte != 0x01 && first_byte != 0x02 && first_byte != 0x04 && first_byte != 0x7f
{
log::info!("not supported tx type: 0x{first_byte:02x}");
@@ -91,11 +95,22 @@ pub fn decode_transactions(bs: &[u8]) -> Vec {
};
let tx_bytes = bs[offset..offset + rlp_tx_len].to_vec();
- let tx_decoded: MorphTxEnvelope = MorphTxEnvelope::decode(&mut tx_bytes.as_slice())
- .inspect_err(|e| {
- log::error!("decode_transaction error: {e:?}");
- })
- .unwrap();
+ let tx_decoded = if first_byte == 0x7f {
+ // Morph transaction: bypass MorphTxEnvelope::decode_2718 because morph-reth's
+ // TxMorph::rlp_decode_fields incorrectly expects a version-byte prefix that is
+ // NOT present in the signed (batch) encoding.
+ decode_morph_tx_envelope(&tx_bytes)
+ .inspect_err(|e| {
+ log::error!("decode morph tx error: {e:?}");
+ })
+ .unwrap()
+ } else {
+ MorphTxEnvelope::decode_2718(&mut tx_bytes.as_slice())
+ .inspect_err(|e| {
+ log::error!("decode_transaction error: {e:?}");
+ })
+ .unwrap()
+ };
txs_decoded.push(tx_decoded);
offset += rlp_tx_len;
@@ -104,3 +119,115 @@ pub fn decode_transactions(bs: &[u8]) -> Vec {
log::info!("Successfully decoded {} transactions", txs_decoded.len());
txs_decoded
}
+
+/// Decode a morph transaction (type 0x7F) from EIP-2718 encoded bytes.
+///
+/// This manually decodes the fields + signature instead of going through morph-reth's
+/// `TxMorph::rlp_decode_fields` which has a bug: it calls `decode_fields` which tries
+/// to interpret the first RLP byte as a version-byte prefix, but the signed encoding
+/// does NOT include the version byte. V0 vs V1 is distinguished by the number of fields.
+#[cfg(not(target_os = "zkvm"))]
+fn decode_morph_tx_envelope(buf: &[u8]) -> Result {
+ use alloy_primitives::{Bytes, Signature, B256, U256};
+ use alloy_eips::eip2930::AccessList;
+ use alloy_primitives::TxKind;
+ use prover_primitives::TxMorph;
+ use prover_primitives::alloy_consensus::SignableTransaction;
+
+ let mut reader = &buf[1..]; // skip type byte (0x7F)
+
+ // Decode the outer RLP list header
+ let header = Header::decode(&mut reader)?;
+ if !header.list {
+ return Err(alloy_rlp::Error::UnexpectedString);
+ }
+ let payload_end = reader.len() - header.payload_length;
+
+ // Decode common fields (V0 and V1 share these 11 fields)
+ let chain_id: u64 = Decodable::decode(&mut reader)?;
+ let nonce: u64 = Decodable::decode(&mut reader)?;
+ let max_priority_fee_per_gas: u128 = Decodable::decode(&mut reader)?;
+ let max_fee_per_gas: u128 = Decodable::decode(&mut reader)?;
+ let gas_limit: u128 = Decodable::decode(&mut reader)?;
+ let to: TxKind = Decodable::decode(&mut reader)?;
+ let value: U256 = Decodable::decode(&mut reader)?;
+ let input: Bytes = Decodable::decode(&mut reader)?;
+ let access_list: AccessList = Decodable::decode(&mut reader)?;
+ let fee_token_id: u16 = Decodable::decode(&mut reader)?;
+ let fee_limit: U256 = Decodable::decode(&mut reader)?;
+
+ // Signature is 3 fields: v (bool), r (U256), s (U256).
+ // After the common 11 fields, check remaining bytes to determine V0 vs V1:
+ // - V0: next 3 fields are the signature (v, r, s)
+ // - V1: next 2 fields are reference + memo, then signature (v, r, s)
+ //
+ // We detect V1 by saving position and trying to read a bool for v.
+ // If remaining > 3 fields, it's V1 (reference + memo + sig).
+ let saved = reader;
+ let _probe: bool = Decodable::decode(&mut { reader })?;
+ // For V0, the next field is v (bool: 0x00 or 0x01).
+ // For V1, the next field is reference (32 bytes or empty bytes).
+ // We can distinguish by checking: if the probe succeeded AND the following
+ // two fields (r, s) would consume exactly the remaining bytes → V0.
+ // Otherwise → V1.
+ //
+ // Simpler heuristic: check the first byte of the next field.
+ // - v (bool) is encoded as 0x00 or 0x01 (single byte)
+ // - reference (B256) is encoded as 0xa0 + 32 bytes, or 0x80 (empty)
+ let next_byte = saved[0];
+ let (version, reference, memo) = if next_byte == 0x00 || next_byte == 0x01 {
+ // This looks like a bool (v field) → V0 format
+ (0u8, None, None)
+ } else {
+ // V1: decode reference and memo
+ reader = saved;
+ let reference_bytes: Bytes = Decodable::decode(&mut reader)?;
+ let reference = if reference_bytes.is_empty() {
+ None
+ } else if reference_bytes.len() == 32 {
+ Some(B256::from_slice(&reference_bytes))
+ } else {
+ return Err(alloy_rlp::Error::Custom("invalid reference length"));
+ };
+ let memo_bytes: Bytes = Decodable::decode(&mut reader)?;
+ let memo = if memo_bytes.is_empty() { None } else { Some(memo_bytes) };
+ (1u8, reference, memo)
+ };
+
+ // Decode signature (v, r, s)
+ if version != 0 {
+ // reader is already advanced past reference + memo
+ } else {
+ reader = saved;
+ }
+ let sig_v: bool = Decodable::decode(&mut reader)?;
+ let sig_r: U256 = Decodable::decode(&mut reader)?;
+ let sig_s: U256 = Decodable::decode(&mut reader)?;
+
+ if reader.len() != payload_end {
+ return Err(alloy_rlp::Error::ListLengthMismatch {
+ expected: header.payload_length,
+ got: header.payload_length - (reader.len() - payload_end),
+ });
+ }
+
+ let tx = TxMorph {
+ chain_id,
+ nonce,
+ gas_limit,
+ max_fee_per_gas,
+ max_priority_fee_per_gas,
+ to,
+ value,
+ access_list,
+ input,
+ fee_token_id,
+ fee_limit,
+ version,
+ reference,
+ memo,
+ };
+
+ let signature = Signature::new(sig_r, sig_s, sig_v);
+ Ok(MorphTxEnvelope::Morph(tx.into_signed(signature)))
+}
diff --git a/prover/crates/executor/core/src/executor.rs b/prover/crates/executor/core/src/executor.rs
index 82e53ec7f..33a5e2aca 100644
--- a/prover/crates/executor/core/src/executor.rs
+++ b/prover/crates/executor/core/src/executor.rs
@@ -1,6 +1,7 @@
use alloy_consensus::transaction::SignerRecoverable;
use alloy_consensus::Transaction;
use alloy_evm::{revm::Context as EvmContext, Database, EvmEnv};
+use revm::primitives::Bytes;
use anyhow::Context;
use anyhow::Result;
use morph_chainspec::hardfork::MorphHardfork;
@@ -72,7 +73,7 @@ impl MorphExecutor {
DEVNET_CHAIN_ID => MorphHardfork::Emerald,
_ => MorphHardfork::Emerald,
};
- env.cfg_env = env.cfg_env.with_spec(hardfork);
+ env.cfg_env = env.cfg_env.with_spec_and_mainnet_gas_params(hardfork);
env.cfg_env.chain_id = chain_id;
env.cfg_env.tx_gas_limit_cap = Some(block_env.gas_limit);
env.cfg_env.disable_eip7623 = true;
@@ -89,6 +90,23 @@ impl MorphExecutor {
let mut morph_tx = MorphTxEnv::from_recovered_tx(tx, caller);
morph_tx.gas_price = tx.effective_gas_price(Some(basefee));
+ // Fix V1+ MorphTx encoding: alloy's Signed::encode_2718()
+ // omits the version prefix byte that go-ethereum includes after the
+ // type byte. Insert it so L1 data-fee calculation sees the same
+ // byte stream as go-ethereum.
+ if let MorphTxEnvelope::Morph(signed_tx) = tx {
+ let version = signed_tx.tx().version;
+ if version > 0 {
+ if let Some(ref rlp) = morph_tx.rlp_bytes {
+ let mut fixed = Vec::with_capacity(rlp.len() + 1);
+ fixed.push(rlp[0]); // 0x7F type byte
+ fixed.push(version); // version prefix byte
+ fixed.extend_from_slice(&rlp[1..]); // RLP body
+ morph_tx.rlp_bytes = Some(Bytes::from(fixed));
+ }
+ }
+ }
+
self.inner
.transact_commit(morph_tx)
.with_context(|| format!("tx[{tx_index}] transact_commit error"))?;
diff --git a/prover/crates/executor/host/src/execute.rs b/prover/crates/executor/host/src/execute.rs
index 00b32f27e..53ee69c0d 100644
--- a/prover/crates/executor/host/src/execute.rs
+++ b/prover/crates/executor/host/src/execute.rs
@@ -35,6 +35,9 @@ impl HostExecutor {
provider.get_chain_id().await.context("failed to fetch chain_id from provider")?;
// beneficiary(coinbase)
+ // In Clique consensus, header.Coinbase is always 0x0000...0000.
+ // The actual beneficiary is the signer recovered from extraData.
+ // We use a per-chain hardcoded address as the sequencer/beneficiary.
let beneficiary = beneficiary_by_chain_id(chain_id);
// mpt root at this block
diff --git a/prover/crates/primitives/src/lib.rs b/prover/crates/primitives/src/lib.rs
index 1d11362de..2ffe3baca 100644
--- a/prover/crates/primitives/src/lib.rs
+++ b/prover/crates/primitives/src/lib.rs
@@ -4,7 +4,7 @@ use alloy_consensus::{SignableTransaction, TxEip1559, TxEip2930, TxEip7702, TxLe
use alloy_eips::eip2930::AccessList;
use alloy_eips::Encodable2718;
use alloy_primitives::{Bytes, ChainId, Signature, SignatureError, TxKind};
-use morph_primitives::{TxL1Msg, TxMorph};
+use morph_primitives::TxL1Msg;
use std::fmt::Debug;
/// Predeployed contracts
@@ -17,7 +17,7 @@ pub use alloy_consensus::Transaction;
pub use alloy_eips::eip7702::SignedAuthorization;
pub use alloy_primitives;
pub use alloy_primitives::{Address, B256, U256};
-pub use morph_primitives::MorphTxEnvelope;
+pub use morph_primitives::{MorphTxEnvelope, TxMorph};
/// Blanket trait for block trace extensions.
pub trait Block: Debug {
@@ -162,6 +162,21 @@ pub trait TxTrace {
/// Get `sig_v`.
fn sig_v(&self) -> u64;
+ /// Get morph tx `version`.
+ fn morph_tx_version(&self) -> u8 {
+ 0
+ }
+
+ /// Get morph tx `reference`.
+ fn morph_tx_reference(&self) -> Option {
+ None
+ }
+
+ /// Get morph tx `memo`.
+ fn morph_tx_memo(&self) -> Option {
+ None
+ }
+
/// Try to build a envelope tx
fn try_build_tx_envelope(&self) -> Result {
let chain_id = self.chain_id();
@@ -255,6 +270,9 @@ pub trait TxTrace {
input: self.data(),
fee_token_id: self.fee_token_id(),
fee_limit: self.fee_limit(),
+ version: self.morph_tx_version(),
+ reference: self.morph_tx_reference(),
+ memo: self.morph_tx_memo(),
};
MorphTxEnvelope::Morph(tx.into_signed(self.signature()?))
}
@@ -404,4 +422,16 @@ impl TxTrace for &T {
fn queue_index(&self) -> Option {
(*self).queue_index()
}
+
+ fn morph_tx_version(&self) -> u8 {
+ (*self).morph_tx_version()
+ }
+
+ fn morph_tx_reference(&self) -> Option {
+ (*self).morph_tx_reference()
+ }
+
+ fn morph_tx_memo(&self) -> Option {
+ (*self).morph_tx_memo()
+ }
}
diff --git a/prover/crates/primitives/src/types/tx.rs b/prover/crates/primitives/src/types/tx.rs
index 01d7082e6..2e1aab23d 100644
--- a/prover/crates/primitives/src/types/tx.rs
+++ b/prover/crates/primitives/src/types/tx.rs
@@ -71,6 +71,15 @@ pub struct TransactionTrace {
/// For AltFeeType
#[serde(rename = "feeLimit")]
pub(crate) fee_limit: Option,
+ /// Morph tx version
+ #[serde(default)]
+ pub(crate) version: Option,
+ /// Morph tx reference
+ #[serde(default)]
+ pub(crate) reference: Option,
+ /// Morph tx memo
+ #[serde(default)]
+ pub(crate) memo: Option,
/// signature v
pub(crate) v: U64,
/// signature r
@@ -163,4 +172,16 @@ impl TxTrace for TransactionTrace {
fn sig_v(&self) -> u64 {
self.v.to::()
}
+
+ fn morph_tx_version(&self) -> u8 {
+ self.version.map(|v| v.to::()).unwrap_or(0)
+ }
+
+ fn morph_tx_reference(&self) -> Option {
+ self.reference
+ }
+
+ fn morph_tx_memo(&self) -> Option {
+ self.memo.clone()
+ }
}
diff --git a/prover/crates/storage/rpc-db/src/basic_rpc_db.rs b/prover/crates/storage/rpc-db/src/basic_rpc_db.rs
index 43418d38b..63d184096 100644
--- a/prover/crates/storage/rpc-db/src/basic_rpc_db.rs
+++ b/prover/crates/storage/rpc-db/src/basic_rpc_db.rs
@@ -85,6 +85,7 @@ impl + Clone, N: Network> BasicRpcDb {
balance: proof.balance,
code_hash,
code: Some(bytecode.clone()),
+ account_id: None,
};
// Record the account info to the state.
diff --git a/prover/crates/storage/witness-db/src/lib.rs b/prover/crates/storage/witness-db/src/lib.rs
index e466b1b66..d9aabc454 100644
--- a/prover/crates/storage/witness-db/src/lib.rs
+++ b/prover/crates/storage/witness-db/src/lib.rs
@@ -82,6 +82,7 @@ impl DatabaseRef for TrieDB<'_> {
nonce: account_in_trie.nonce,
code_hash: account_in_trie.code_hash,
code: None,
+ account_id: None,
});
Ok(account)
diff --git a/prover/rust-toolchain b/prover/rust-toolchain
index 7855e6d55..ee43e8350 100644
--- a/prover/rust-toolchain
+++ b/prover/rust-toolchain
@@ -1,3 +1,3 @@
[toolchain]
-channel = "1.88.0"
+channel = "1.93.1"
components = ["rustfmt", "clippy"]
From b0db337201c48ce41ebebe0dfc3d5f6f4f87954c Mon Sep 17 00:00:00 2001
From: chengwenxi <22697326+chengwenxi@users.noreply.github.com>
Date: Mon, 2 Mar 2026 21:50:32 +0800
Subject: [PATCH 03/21] cargo fmt
---
prover/crates/executor/client/src/types/blob.rs | 10 +++++-----
prover/crates/executor/core/src/executor.rs | 2 +-
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/prover/crates/executor/client/src/types/blob.rs b/prover/crates/executor/client/src/types/blob.rs
index abffd3a5f..b9ae26969 100644
--- a/prover/crates/executor/client/src/types/blob.rs
+++ b/prover/crates/executor/client/src/types/blob.rs
@@ -1,12 +1,12 @@
+use anyhow::{anyhow, Context};
+use ruzstd::StreamingDecoder;
+use std::io::Read;
#[cfg(not(target_os = "zkvm"))]
use {
alloy_eips::eip2718::Decodable2718,
alloy_rlp::{Decodable, Header},
prover_primitives::MorphTxEnvelope,
};
-use anyhow::{anyhow, Context};
-use ruzstd::StreamingDecoder;
-use std::io::Read;
/// This magic number is included at the start of a single Zstandard frame
pub const MAGIC_NUM: u32 = 0xFD2F_B528;
@@ -128,11 +128,11 @@ pub fn decode_transactions(bs: &[u8]) -> Vec {
/// does NOT include the version byte. V0 vs V1 is distinguished by the number of fields.
#[cfg(not(target_os = "zkvm"))]
fn decode_morph_tx_envelope(buf: &[u8]) -> Result {
- use alloy_primitives::{Bytes, Signature, B256, U256};
use alloy_eips::eip2930::AccessList;
use alloy_primitives::TxKind;
- use prover_primitives::TxMorph;
+ use alloy_primitives::{Bytes, Signature, B256, U256};
use prover_primitives::alloy_consensus::SignableTransaction;
+ use prover_primitives::TxMorph;
let mut reader = &buf[1..]; // skip type byte (0x7F)
diff --git a/prover/crates/executor/core/src/executor.rs b/prover/crates/executor/core/src/executor.rs
index 33a5e2aca..490612a3f 100644
--- a/prover/crates/executor/core/src/executor.rs
+++ b/prover/crates/executor/core/src/executor.rs
@@ -1,7 +1,6 @@
use alloy_consensus::transaction::SignerRecoverable;
use alloy_consensus::Transaction;
use alloy_evm::{revm::Context as EvmContext, Database, EvmEnv};
-use revm::primitives::Bytes;
use anyhow::Context;
use anyhow::Result;
use morph_chainspec::hardfork::MorphHardfork;
@@ -11,6 +10,7 @@ use morph_chainspec::MORPH_MAINNET;
use morph_evm::MorphBlockEnv;
use morph_primitives::MorphTxEnvelope;
use morph_revm::MorphEvm;
+use revm::primitives::Bytes;
use revm::MainContext;
use std::sync::Arc;
From 367d26d78bf8b9cece7f7d0a9e8127aef0828463 Mon Sep 17 00:00:00 2001
From: chengwenxi <22697326+chengwenxi@users.noreply.github.com>
Date: Wed, 4 Mar 2026 19:00:35 +0800
Subject: [PATCH 04/21] update morph-reth deps to v0.1.0 tag
---
prover/Cargo.lock | 20 ++++++++++----------
prover/Cargo.toml | 8 ++++----
2 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/prover/Cargo.lock b/prover/Cargo.lock
index 69c9d488d..78860ace7 100644
--- a/prover/Cargo.lock
+++ b/prover/Cargo.lock
@@ -4253,8 +4253,8 @@ dependencies = [
[[package]]
name = "morph-chainspec"
-version = "0.7.5"
-source = "git+https://github.com/morph-l2/morph-reth.git?branch=reference-key-fix#df825ca8a03827029bbd5f4dcbfae5fd4b93a6f9"
+version = "0.1.0"
+source = "git+https://github.com/morph-l2/morph-reth.git?tag=v0.1.0#e74ac393c99f3d9a130064ec71a9004103833666"
dependencies = [
"alloy-chains",
"alloy-consensus",
@@ -4275,8 +4275,8 @@ dependencies = [
[[package]]
name = "morph-evm"
-version = "0.7.5"
-source = "git+https://github.com/morph-l2/morph-reth.git?branch=reference-key-fix#df825ca8a03827029bbd5f4dcbfae5fd4b93a6f9"
+version = "0.1.0"
+source = "git+https://github.com/morph-l2/morph-reth.git?tag=v0.1.0#e74ac393c99f3d9a130064ec71a9004103833666"
dependencies = [
"alloy-consensus",
"alloy-evm",
@@ -4298,8 +4298,8 @@ dependencies = [
[[package]]
name = "morph-payload-types"
-version = "0.7.5"
-source = "git+https://github.com/morph-l2/morph-reth.git?branch=reference-key-fix#df825ca8a03827029bbd5f4dcbfae5fd4b93a6f9"
+version = "0.1.0"
+source = "git+https://github.com/morph-l2/morph-reth.git?tag=v0.1.0#e74ac393c99f3d9a130064ec71a9004103833666"
dependencies = [
"alloy-consensus",
"alloy-eips",
@@ -4318,8 +4318,8 @@ dependencies = [
[[package]]
name = "morph-primitives"
-version = "0.7.5"
-source = "git+https://github.com/morph-l2/morph-reth.git?branch=reference-key-fix#df825ca8a03827029bbd5f4dcbfae5fd4b93a6f9"
+version = "0.1.0"
+source = "git+https://github.com/morph-l2/morph-reth.git?tag=v0.1.0#e74ac393c99f3d9a130064ec71a9004103833666"
dependencies = [
"alloy-consensus",
"alloy-eips",
@@ -4356,8 +4356,8 @@ dependencies = [
[[package]]
name = "morph-revm"
-version = "0.7.5"
-source = "git+https://github.com/morph-l2/morph-reth.git?branch=reference-key-fix#df825ca8a03827029bbd5f4dcbfae5fd4b93a6f9"
+version = "0.1.0"
+source = "git+https://github.com/morph-l2/morph-reth.git?tag=v0.1.0#e74ac393c99f3d9a130064ec71a9004103833666"
dependencies = [
"alloy-consensus",
"alloy-eips",
diff --git a/prover/Cargo.toml b/prover/Cargo.toml
index 57523807a..e818a6a2e 100644
--- a/prover/Cargo.toml
+++ b/prover/Cargo.toml
@@ -117,10 +117,10 @@ revm = { version = "34.0.0", features = [
reth-primitives-traits = { git = "https://github.com/paradigmxyz/reth", tag = "v1.10.2", default-features = false }
reth-storage-errors = { git = "https://github.com/paradigmxyz/reth", tag = "v1.10.2", default-features = false }
reth-trie = { git = "https://github.com/paradigmxyz/reth", tag = "v1.10.2", default-features = false }
-morph-revm = { git = "https://github.com/morph-l2/morph-reth.git", branch = "reference-key-fix" }
-morph-evm = { git = "https://github.com/morph-l2/morph-reth.git", branch = "reference-key-fix" }
-morph-primitives = { git = "https://github.com/morph-l2/morph-reth.git", branch = "reference-key-fix" }
-morph-chainspec = { git = "https://github.com/morph-l2/morph-reth.git", branch = "reference-key-fix" }
+morph-revm = { git = "https://github.com/morph-l2/morph-reth.git", tag = "v0.1.0" }
+morph-evm = { git = "https://github.com/morph-l2/morph-reth.git", tag = "v0.1.0" }
+morph-primitives = { git = "https://github.com/morph-l2/morph-reth.git", tag = "v0.1.0" }
+morph-chainspec = { git = "https://github.com/morph-l2/morph-reth.git", tag = "v0.1.0" }
# ZK / SP1
From 4638eb83f3d807894769868812d84958a0d92c5a Mon Sep 17 00:00:00 2001
From: chengwenxi <22697326+chengwenxi@users.noreply.github.com>
Date: Thu, 5 Mar 2026 18:33:48 +0800
Subject: [PATCH 05/21] code clean
---
.../crates/executor/client/src/types/blob.rs | 139 +-----------------
prover/crates/executor/core/src/executor.rs | 18 ---
2 files changed, 6 insertions(+), 151 deletions(-)
diff --git a/prover/crates/executor/client/src/types/blob.rs b/prover/crates/executor/client/src/types/blob.rs
index b9ae26969..bebbaec6a 100644
--- a/prover/crates/executor/client/src/types/blob.rs
+++ b/prover/crates/executor/client/src/types/blob.rs
@@ -2,11 +2,7 @@ use anyhow::{anyhow, Context};
use ruzstd::StreamingDecoder;
use std::io::Read;
#[cfg(not(target_os = "zkvm"))]
-use {
- alloy_eips::eip2718::Decodable2718,
- alloy_rlp::{Decodable, Header},
- prover_primitives::MorphTxEnvelope,
-};
+use {alloy_eips::eip2718::Decodable2718, prover_primitives::MorphTxEnvelope};
/// This magic number is included at the start of a single Zstandard frame
pub const MAGIC_NUM: u32 = 0xFD2F_B528;
@@ -95,22 +91,11 @@ pub fn decode_transactions(bs: &[u8]) -> Vec {
};
let tx_bytes = bs[offset..offset + rlp_tx_len].to_vec();
- let tx_decoded = if first_byte == 0x7f {
- // Morph transaction: bypass MorphTxEnvelope::decode_2718 because morph-reth's
- // TxMorph::rlp_decode_fields incorrectly expects a version-byte prefix that is
- // NOT present in the signed (batch) encoding.
- decode_morph_tx_envelope(&tx_bytes)
- .inspect_err(|e| {
- log::error!("decode morph tx error: {e:?}");
- })
- .unwrap()
- } else {
- MorphTxEnvelope::decode_2718(&mut tx_bytes.as_slice())
- .inspect_err(|e| {
- log::error!("decode_transaction error: {e:?}");
- })
- .unwrap()
- };
+ let tx_decoded = MorphTxEnvelope::decode_2718(&mut tx_bytes.as_slice())
+ .inspect_err(|e| {
+ log::error!("decode_transaction error: {e:?}");
+ })
+ .unwrap();
txs_decoded.push(tx_decoded);
offset += rlp_tx_len;
@@ -119,115 +104,3 @@ pub fn decode_transactions(bs: &[u8]) -> Vec {
log::info!("Successfully decoded {} transactions", txs_decoded.len());
txs_decoded
}
-
-/// Decode a morph transaction (type 0x7F) from EIP-2718 encoded bytes.
-///
-/// This manually decodes the fields + signature instead of going through morph-reth's
-/// `TxMorph::rlp_decode_fields` which has a bug: it calls `decode_fields` which tries
-/// to interpret the first RLP byte as a version-byte prefix, but the signed encoding
-/// does NOT include the version byte. V0 vs V1 is distinguished by the number of fields.
-#[cfg(not(target_os = "zkvm"))]
-fn decode_morph_tx_envelope(buf: &[u8]) -> Result {
- use alloy_eips::eip2930::AccessList;
- use alloy_primitives::TxKind;
- use alloy_primitives::{Bytes, Signature, B256, U256};
- use prover_primitives::alloy_consensus::SignableTransaction;
- use prover_primitives::TxMorph;
-
- let mut reader = &buf[1..]; // skip type byte (0x7F)
-
- // Decode the outer RLP list header
- let header = Header::decode(&mut reader)?;
- if !header.list {
- return Err(alloy_rlp::Error::UnexpectedString);
- }
- let payload_end = reader.len() - header.payload_length;
-
- // Decode common fields (V0 and V1 share these 11 fields)
- let chain_id: u64 = Decodable::decode(&mut reader)?;
- let nonce: u64 = Decodable::decode(&mut reader)?;
- let max_priority_fee_per_gas: u128 = Decodable::decode(&mut reader)?;
- let max_fee_per_gas: u128 = Decodable::decode(&mut reader)?;
- let gas_limit: u128 = Decodable::decode(&mut reader)?;
- let to: TxKind = Decodable::decode(&mut reader)?;
- let value: U256 = Decodable::decode(&mut reader)?;
- let input: Bytes = Decodable::decode(&mut reader)?;
- let access_list: AccessList = Decodable::decode(&mut reader)?;
- let fee_token_id: u16 = Decodable::decode(&mut reader)?;
- let fee_limit: U256 = Decodable::decode(&mut reader)?;
-
- // Signature is 3 fields: v (bool), r (U256), s (U256).
- // After the common 11 fields, check remaining bytes to determine V0 vs V1:
- // - V0: next 3 fields are the signature (v, r, s)
- // - V1: next 2 fields are reference + memo, then signature (v, r, s)
- //
- // We detect V1 by saving position and trying to read a bool for v.
- // If remaining > 3 fields, it's V1 (reference + memo + sig).
- let saved = reader;
- let _probe: bool = Decodable::decode(&mut { reader })?;
- // For V0, the next field is v (bool: 0x00 or 0x01).
- // For V1, the next field is reference (32 bytes or empty bytes).
- // We can distinguish by checking: if the probe succeeded AND the following
- // two fields (r, s) would consume exactly the remaining bytes → V0.
- // Otherwise → V1.
- //
- // Simpler heuristic: check the first byte of the next field.
- // - v (bool) is encoded as 0x00 or 0x01 (single byte)
- // - reference (B256) is encoded as 0xa0 + 32 bytes, or 0x80 (empty)
- let next_byte = saved[0];
- let (version, reference, memo) = if next_byte == 0x00 || next_byte == 0x01 {
- // This looks like a bool (v field) → V0 format
- (0u8, None, None)
- } else {
- // V1: decode reference and memo
- reader = saved;
- let reference_bytes: Bytes = Decodable::decode(&mut reader)?;
- let reference = if reference_bytes.is_empty() {
- None
- } else if reference_bytes.len() == 32 {
- Some(B256::from_slice(&reference_bytes))
- } else {
- return Err(alloy_rlp::Error::Custom("invalid reference length"));
- };
- let memo_bytes: Bytes = Decodable::decode(&mut reader)?;
- let memo = if memo_bytes.is_empty() { None } else { Some(memo_bytes) };
- (1u8, reference, memo)
- };
-
- // Decode signature (v, r, s)
- if version != 0 {
- // reader is already advanced past reference + memo
- } else {
- reader = saved;
- }
- let sig_v: bool = Decodable::decode(&mut reader)?;
- let sig_r: U256 = Decodable::decode(&mut reader)?;
- let sig_s: U256 = Decodable::decode(&mut reader)?;
-
- if reader.len() != payload_end {
- return Err(alloy_rlp::Error::ListLengthMismatch {
- expected: header.payload_length,
- got: header.payload_length - (reader.len() - payload_end),
- });
- }
-
- let tx = TxMorph {
- chain_id,
- nonce,
- gas_limit,
- max_fee_per_gas,
- max_priority_fee_per_gas,
- to,
- value,
- access_list,
- input,
- fee_token_id,
- fee_limit,
- version,
- reference,
- memo,
- };
-
- let signature = Signature::new(sig_r, sig_s, sig_v);
- Ok(MorphTxEnvelope::Morph(tx.into_signed(signature)))
-}
diff --git a/prover/crates/executor/core/src/executor.rs b/prover/crates/executor/core/src/executor.rs
index 490612a3f..7d1654354 100644
--- a/prover/crates/executor/core/src/executor.rs
+++ b/prover/crates/executor/core/src/executor.rs
@@ -10,7 +10,6 @@ use morph_chainspec::MORPH_MAINNET;
use morph_evm::MorphBlockEnv;
use morph_primitives::MorphTxEnvelope;
use morph_revm::MorphEvm;
-use revm::primitives::Bytes;
use revm::MainContext;
use std::sync::Arc;
@@ -90,23 +89,6 @@ impl MorphExecutor {
let mut morph_tx = MorphTxEnv::from_recovered_tx(tx, caller);
morph_tx.gas_price = tx.effective_gas_price(Some(basefee));
- // Fix V1+ MorphTx encoding: alloy's Signed::encode_2718()
- // omits the version prefix byte that go-ethereum includes after the
- // type byte. Insert it so L1 data-fee calculation sees the same
- // byte stream as go-ethereum.
- if let MorphTxEnvelope::Morph(signed_tx) = tx {
- let version = signed_tx.tx().version;
- if version > 0 {
- if let Some(ref rlp) = morph_tx.rlp_bytes {
- let mut fixed = Vec::with_capacity(rlp.len() + 1);
- fixed.push(rlp[0]); // 0x7F type byte
- fixed.push(version); // version prefix byte
- fixed.extend_from_slice(&rlp[1..]); // RLP body
- morph_tx.rlp_bytes = Some(Bytes::from(fixed));
- }
- }
- }
-
self.inner
.transact_commit(morph_tx)
.with_context(|| format!("tx[{tx_index}] transact_commit error"))?;
From 4eecf608f3b228b5996222527d8c797d023fe560 Mon Sep 17 00:00:00 2001
From: chengwenxi <22697326+chengwenxi@users.noreply.github.com>
Date: Mon, 9 Mar 2026 16:58:39 +0800
Subject: [PATCH 06/21] prover: update morph-reth to main@7454ea1
---
prover/Cargo.lock | 77 ++++++++++++++++++++++++-----------------------
prover/Cargo.toml | 14 ++++-----
2 files changed, 47 insertions(+), 44 deletions(-)
diff --git a/prover/Cargo.lock b/prover/Cargo.lock
index 78860ace7..05eeb3024 100644
--- a/prover/Cargo.lock
+++ b/prover/Cargo.lock
@@ -4254,7 +4254,7 @@ dependencies = [
[[package]]
name = "morph-chainspec"
version = "0.1.0"
-source = "git+https://github.com/morph-l2/morph-reth.git?tag=v0.1.0#e74ac393c99f3d9a130064ec71a9004103833666"
+source = "git+https://github.com/morph-l2/morph-reth.git?rev=7454ea1b656755be9b81e557fc8d0ff87a8e6268#7454ea1b656755be9b81e557fc8d0ff87a8e6268"
dependencies = [
"alloy-chains",
"alloy-consensus",
@@ -4276,7 +4276,7 @@ dependencies = [
[[package]]
name = "morph-evm"
version = "0.1.0"
-source = "git+https://github.com/morph-l2/morph-reth.git?tag=v0.1.0#e74ac393c99f3d9a130064ec71a9004103833666"
+source = "git+https://github.com/morph-l2/morph-reth.git?rev=7454ea1b656755be9b81e557fc8d0ff87a8e6268#7454ea1b656755be9b81e557fc8d0ff87a8e6268"
dependencies = [
"alloy-consensus",
"alloy-evm",
@@ -4299,7 +4299,7 @@ dependencies = [
[[package]]
name = "morph-payload-types"
version = "0.1.0"
-source = "git+https://github.com/morph-l2/morph-reth.git?tag=v0.1.0#e74ac393c99f3d9a130064ec71a9004103833666"
+source = "git+https://github.com/morph-l2/morph-reth.git?rev=7454ea1b656755be9b81e557fc8d0ff87a8e6268#7454ea1b656755be9b81e557fc8d0ff87a8e6268"
dependencies = [
"alloy-consensus",
"alloy-eips",
@@ -4319,7 +4319,7 @@ dependencies = [
[[package]]
name = "morph-primitives"
version = "0.1.0"
-source = "git+https://github.com/morph-l2/morph-reth.git?tag=v0.1.0#e74ac393c99f3d9a130064ec71a9004103833666"
+source = "git+https://github.com/morph-l2/morph-reth.git?rev=7454ea1b656755be9b81e557fc8d0ff87a8e6268#7454ea1b656755be9b81e557fc8d0ff87a8e6268"
dependencies = [
"alloy-consensus",
"alloy-eips",
@@ -4344,9 +4344,12 @@ dependencies = [
"log",
"once_cell",
"prover-executor-client",
+ "prover-executor-core",
"prover-executor-host",
"prover-primitives",
"prover-utils",
+ "reth-trie",
+ "revm",
"serde",
"serde_json",
"sp1-sdk",
@@ -4357,7 +4360,7 @@ dependencies = [
[[package]]
name = "morph-revm"
version = "0.1.0"
-source = "git+https://github.com/morph-l2/morph-reth.git?tag=v0.1.0#e74ac393c99f3d9a130064ec71a9004103833666"
+source = "git+https://github.com/morph-l2/morph-reth.git?rev=7454ea1b656755be9b81e557fc8d0ff87a8e6268#7454ea1b656755be9b81e557fc8d0ff87a8e6268"
dependencies = [
"alloy-consensus",
"alloy-eips",
@@ -4591,7 +4594,7 @@ version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56"
dependencies = [
- "proc-macro-crate 1.3.1",
+ "proc-macro-crate 3.1.0",
"proc-macro2",
"quote",
"syn 2.0.111",
@@ -5738,7 +5741,7 @@ dependencies = [
"once_cell",
"socket2 0.6.1",
"tracing",
- "windows-sys 0.59.0",
+ "windows-sys 0.60.2",
]
[[package]]
@@ -6028,7 +6031,7 @@ dependencies = [
[[package]]
name = "reth-chain-state"
version = "1.10.2"
-source = "git+https://github.com/paradigmxyz/reth?tag=v1.10.2#8e3b5e6a99439561b73c5dd31bd3eced2e994d60"
+source = "git+https://github.com/morph-l2/reth?rev=8057627ac9f169a0da4de44b616006a9e30382c1#8057627ac9f169a0da4de44b616006a9e30382c1"
dependencies = [
"alloy-consensus",
"alloy-eips",
@@ -6054,7 +6057,7 @@ dependencies = [
[[package]]
name = "reth-chainspec"
version = "1.10.2"
-source = "git+https://github.com/paradigmxyz/reth?tag=v1.10.2#8e3b5e6a99439561b73c5dd31bd3eced2e994d60"
+source = "git+https://github.com/morph-l2/reth?rev=8057627ac9f169a0da4de44b616006a9e30382c1#8057627ac9f169a0da4de44b616006a9e30382c1"
dependencies = [
"alloy-chains",
"alloy-consensus",
@@ -6074,7 +6077,7 @@ dependencies = [
[[package]]
name = "reth-codecs"
version = "1.10.2"
-source = "git+https://github.com/paradigmxyz/reth?tag=v1.10.2#8e3b5e6a99439561b73c5dd31bd3eced2e994d60"
+source = "git+https://github.com/morph-l2/reth?rev=8057627ac9f169a0da4de44b616006a9e30382c1#8057627ac9f169a0da4de44b616006a9e30382c1"
dependencies = [
"alloy-consensus",
"alloy-eips",
@@ -6092,7 +6095,7 @@ dependencies = [
[[package]]
name = "reth-codecs-derive"
version = "1.10.2"
-source = "git+https://github.com/paradigmxyz/reth?tag=v1.10.2#8e3b5e6a99439561b73c5dd31bd3eced2e994d60"
+source = "git+https://github.com/morph-l2/reth?rev=8057627ac9f169a0da4de44b616006a9e30382c1#8057627ac9f169a0da4de44b616006a9e30382c1"
dependencies = [
"proc-macro2",
"quote",
@@ -6102,7 +6105,7 @@ dependencies = [
[[package]]
name = "reth-consensus"
version = "1.10.2"
-source = "git+https://github.com/paradigmxyz/reth?tag=v1.10.2#8e3b5e6a99439561b73c5dd31bd3eced2e994d60"
+source = "git+https://github.com/morph-l2/reth?rev=8057627ac9f169a0da4de44b616006a9e30382c1#8057627ac9f169a0da4de44b616006a9e30382c1"
dependencies = [
"alloy-consensus",
"alloy-primitives",
@@ -6115,7 +6118,7 @@ dependencies = [
[[package]]
name = "reth-db-models"
version = "1.10.2"
-source = "git+https://github.com/paradigmxyz/reth?tag=v1.10.2#8e3b5e6a99439561b73c5dd31bd3eced2e994d60"
+source = "git+https://github.com/morph-l2/reth?rev=8057627ac9f169a0da4de44b616006a9e30382c1#8057627ac9f169a0da4de44b616006a9e30382c1"
dependencies = [
"alloy-eips",
"alloy-primitives",
@@ -6127,7 +6130,7 @@ dependencies = [
[[package]]
name = "reth-engine-primitives"
version = "1.10.2"
-source = "git+https://github.com/paradigmxyz/reth?tag=v1.10.2#8e3b5e6a99439561b73c5dd31bd3eced2e994d60"
+source = "git+https://github.com/morph-l2/reth?rev=8057627ac9f169a0da4de44b616006a9e30382c1#8057627ac9f169a0da4de44b616006a9e30382c1"
dependencies = [
"alloy-consensus",
"alloy-eips",
@@ -6150,7 +6153,7 @@ dependencies = [
[[package]]
name = "reth-errors"
version = "1.10.2"
-source = "git+https://github.com/paradigmxyz/reth?tag=v1.10.2#8e3b5e6a99439561b73c5dd31bd3eced2e994d60"
+source = "git+https://github.com/morph-l2/reth?rev=8057627ac9f169a0da4de44b616006a9e30382c1#8057627ac9f169a0da4de44b616006a9e30382c1"
dependencies = [
"reth-consensus",
"reth-execution-errors",
@@ -6161,7 +6164,7 @@ dependencies = [
[[package]]
name = "reth-ethereum-engine-primitives"
version = "1.10.2"
-source = "git+https://github.com/paradigmxyz/reth?tag=v1.10.2#8e3b5e6a99439561b73c5dd31bd3eced2e994d60"
+source = "git+https://github.com/morph-l2/reth?rev=8057627ac9f169a0da4de44b616006a9e30382c1#8057627ac9f169a0da4de44b616006a9e30382c1"
dependencies = [
"alloy-eips",
"alloy-primitives",
@@ -6179,7 +6182,7 @@ dependencies = [
[[package]]
name = "reth-ethereum-forks"
version = "1.10.2"
-source = "git+https://github.com/paradigmxyz/reth?tag=v1.10.2#8e3b5e6a99439561b73c5dd31bd3eced2e994d60"
+source = "git+https://github.com/morph-l2/reth?rev=8057627ac9f169a0da4de44b616006a9e30382c1#8057627ac9f169a0da4de44b616006a9e30382c1"
dependencies = [
"alloy-eip2124",
"alloy-hardforks",
@@ -6192,7 +6195,7 @@ dependencies = [
[[package]]
name = "reth-ethereum-primitives"
version = "1.10.2"
-source = "git+https://github.com/paradigmxyz/reth?tag=v1.10.2#8e3b5e6a99439561b73c5dd31bd3eced2e994d60"
+source = "git+https://github.com/morph-l2/reth?rev=8057627ac9f169a0da4de44b616006a9e30382c1#8057627ac9f169a0da4de44b616006a9e30382c1"
dependencies = [
"alloy-consensus",
"alloy-eips",
@@ -6210,7 +6213,7 @@ dependencies = [
[[package]]
name = "reth-evm"
version = "1.10.2"
-source = "git+https://github.com/paradigmxyz/reth?tag=v1.10.2#8e3b5e6a99439561b73c5dd31bd3eced2e994d60"
+source = "git+https://github.com/morph-l2/reth?rev=8057627ac9f169a0da4de44b616006a9e30382c1#8057627ac9f169a0da4de44b616006a9e30382c1"
dependencies = [
"alloy-consensus",
"alloy-eips",
@@ -6232,7 +6235,7 @@ dependencies = [
[[package]]
name = "reth-execution-errors"
version = "1.10.2"
-source = "git+https://github.com/paradigmxyz/reth?tag=v1.10.2#8e3b5e6a99439561b73c5dd31bd3eced2e994d60"
+source = "git+https://github.com/morph-l2/reth?rev=8057627ac9f169a0da4de44b616006a9e30382c1#8057627ac9f169a0da4de44b616006a9e30382c1"
dependencies = [
"alloy-evm",
"alloy-primitives",
@@ -6245,7 +6248,7 @@ dependencies = [
[[package]]
name = "reth-execution-types"
version = "1.10.2"
-source = "git+https://github.com/paradigmxyz/reth?tag=v1.10.2#8e3b5e6a99439561b73c5dd31bd3eced2e994d60"
+source = "git+https://github.com/morph-l2/reth?rev=8057627ac9f169a0da4de44b616006a9e30382c1#8057627ac9f169a0da4de44b616006a9e30382c1"
dependencies = [
"alloy-consensus",
"alloy-eips",
@@ -6263,7 +6266,7 @@ dependencies = [
[[package]]
name = "reth-metrics"
version = "1.10.2"
-source = "git+https://github.com/paradigmxyz/reth?tag=v1.10.2#8e3b5e6a99439561b73c5dd31bd3eced2e994d60"
+source = "git+https://github.com/morph-l2/reth?rev=8057627ac9f169a0da4de44b616006a9e30382c1#8057627ac9f169a0da4de44b616006a9e30382c1"
dependencies = [
"metrics",
"metrics-derive",
@@ -6272,7 +6275,7 @@ dependencies = [
[[package]]
name = "reth-network-peers"
version = "1.10.2"
-source = "git+https://github.com/paradigmxyz/reth?tag=v1.10.2#8e3b5e6a99439561b73c5dd31bd3eced2e994d60"
+source = "git+https://github.com/morph-l2/reth?rev=8057627ac9f169a0da4de44b616006a9e30382c1#8057627ac9f169a0da4de44b616006a9e30382c1"
dependencies = [
"alloy-primitives",
"alloy-rlp",
@@ -6285,7 +6288,7 @@ dependencies = [
[[package]]
name = "reth-payload-builder"
version = "1.10.2"
-source = "git+https://github.com/paradigmxyz/reth?tag=v1.10.2#8e3b5e6a99439561b73c5dd31bd3eced2e994d60"
+source = "git+https://github.com/morph-l2/reth?rev=8057627ac9f169a0da4de44b616006a9e30382c1#8057627ac9f169a0da4de44b616006a9e30382c1"
dependencies = [
"alloy-consensus",
"alloy-primitives",
@@ -6306,7 +6309,7 @@ dependencies = [
[[package]]
name = "reth-payload-builder-primitives"
version = "1.10.2"
-source = "git+https://github.com/paradigmxyz/reth?tag=v1.10.2#8e3b5e6a99439561b73c5dd31bd3eced2e994d60"
+source = "git+https://github.com/morph-l2/reth?rev=8057627ac9f169a0da4de44b616006a9e30382c1#8057627ac9f169a0da4de44b616006a9e30382c1"
dependencies = [
"pin-project",
"reth-payload-primitives",
@@ -6318,7 +6321,7 @@ dependencies = [
[[package]]
name = "reth-payload-primitives"
version = "1.10.2"
-source = "git+https://github.com/paradigmxyz/reth?tag=v1.10.2#8e3b5e6a99439561b73c5dd31bd3eced2e994d60"
+source = "git+https://github.com/morph-l2/reth?rev=8057627ac9f169a0da4de44b616006a9e30382c1#8057627ac9f169a0da4de44b616006a9e30382c1"
dependencies = [
"alloy-consensus",
"alloy-eips",
@@ -6341,7 +6344,7 @@ dependencies = [
[[package]]
name = "reth-primitives-traits"
version = "1.10.2"
-source = "git+https://github.com/paradigmxyz/reth?tag=v1.10.2#8e3b5e6a99439561b73c5dd31bd3eced2e994d60"
+source = "git+https://github.com/morph-l2/reth?rev=8057627ac9f169a0da4de44b616006a9e30382c1#8057627ac9f169a0da4de44b616006a9e30382c1"
dependencies = [
"alloy-consensus",
"alloy-eips",
@@ -6368,7 +6371,7 @@ dependencies = [
[[package]]
name = "reth-prune-types"
version = "1.10.2"
-source = "git+https://github.com/paradigmxyz/reth?tag=v1.10.2#8e3b5e6a99439561b73c5dd31bd3eced2e994d60"
+source = "git+https://github.com/morph-l2/reth?rev=8057627ac9f169a0da4de44b616006a9e30382c1#8057627ac9f169a0da4de44b616006a9e30382c1"
dependencies = [
"alloy-primitives",
"derive_more 2.1.0",
@@ -6380,7 +6383,7 @@ dependencies = [
[[package]]
name = "reth-revm"
version = "1.10.2"
-source = "git+https://github.com/paradigmxyz/reth?tag=v1.10.2#8e3b5e6a99439561b73c5dd31bd3eced2e994d60"
+source = "git+https://github.com/morph-l2/reth?rev=8057627ac9f169a0da4de44b616006a9e30382c1#8057627ac9f169a0da4de44b616006a9e30382c1"
dependencies = [
"alloy-primitives",
"reth-primitives-traits",
@@ -6392,7 +6395,7 @@ dependencies = [
[[package]]
name = "reth-stages-types"
version = "1.10.2"
-source = "git+https://github.com/paradigmxyz/reth?tag=v1.10.2#8e3b5e6a99439561b73c5dd31bd3eced2e994d60"
+source = "git+https://github.com/morph-l2/reth?rev=8057627ac9f169a0da4de44b616006a9e30382c1#8057627ac9f169a0da4de44b616006a9e30382c1"
dependencies = [
"alloy-primitives",
"bytes",
@@ -6403,7 +6406,7 @@ dependencies = [
[[package]]
name = "reth-static-file-types"
version = "1.10.2"
-source = "git+https://github.com/paradigmxyz/reth?tag=v1.10.2#8e3b5e6a99439561b73c5dd31bd3eced2e994d60"
+source = "git+https://github.com/morph-l2/reth?rev=8057627ac9f169a0da4de44b616006a9e30382c1#8057627ac9f169a0da4de44b616006a9e30382c1"
dependencies = [
"alloy-primitives",
"derive_more 2.1.0",
@@ -6415,7 +6418,7 @@ dependencies = [
[[package]]
name = "reth-storage-api"
version = "1.10.2"
-source = "git+https://github.com/paradigmxyz/reth?tag=v1.10.2#8e3b5e6a99439561b73c5dd31bd3eced2e994d60"
+source = "git+https://github.com/morph-l2/reth?rev=8057627ac9f169a0da4de44b616006a9e30382c1#8057627ac9f169a0da4de44b616006a9e30382c1"
dependencies = [
"alloy-consensus",
"alloy-eips",
@@ -6438,7 +6441,7 @@ dependencies = [
[[package]]
name = "reth-storage-errors"
version = "1.10.2"
-source = "git+https://github.com/paradigmxyz/reth?tag=v1.10.2#8e3b5e6a99439561b73c5dd31bd3eced2e994d60"
+source = "git+https://github.com/morph-l2/reth?rev=8057627ac9f169a0da4de44b616006a9e30382c1#8057627ac9f169a0da4de44b616006a9e30382c1"
dependencies = [
"alloy-eips",
"alloy-primitives",
@@ -6455,7 +6458,7 @@ dependencies = [
[[package]]
name = "reth-trie"
version = "1.10.2"
-source = "git+https://github.com/paradigmxyz/reth?tag=v1.10.2#8e3b5e6a99439561b73c5dd31bd3eced2e994d60"
+source = "git+https://github.com/morph-l2/reth?rev=8057627ac9f169a0da4de44b616006a9e30382c1#8057627ac9f169a0da4de44b616006a9e30382c1"
dependencies = [
"alloy-consensus",
"alloy-eips",
@@ -6477,7 +6480,7 @@ dependencies = [
[[package]]
name = "reth-trie-common"
version = "1.10.2"
-source = "git+https://github.com/paradigmxyz/reth?tag=v1.10.2#8e3b5e6a99439561b73c5dd31bd3eced2e994d60"
+source = "git+https://github.com/morph-l2/reth?rev=8057627ac9f169a0da4de44b616006a9e30382c1#8057627ac9f169a0da4de44b616006a9e30382c1"
dependencies = [
"alloy-consensus",
"alloy-primitives",
@@ -6500,7 +6503,7 @@ dependencies = [
[[package]]
name = "reth-trie-sparse"
version = "1.10.2"
-source = "git+https://github.com/paradigmxyz/reth?tag=v1.10.2#8e3b5e6a99439561b73c5dd31bd3eced2e994d60"
+source = "git+https://github.com/morph-l2/reth?rev=8057627ac9f169a0da4de44b616006a9e30382c1#8057627ac9f169a0da4de44b616006a9e30382c1"
dependencies = [
"alloy-primitives",
"alloy-rlp",
@@ -6516,7 +6519,7 @@ dependencies = [
[[package]]
name = "reth-zstd-compressors"
version = "1.10.2"
-source = "git+https://github.com/paradigmxyz/reth?tag=v1.10.2#8e3b5e6a99439561b73c5dd31bd3eced2e994d60"
+source = "git+https://github.com/morph-l2/reth?rev=8057627ac9f169a0da4de44b616006a9e30382c1#8057627ac9f169a0da4de44b616006a9e30382c1"
dependencies = [
"zstd 0.13.3",
]
diff --git a/prover/Cargo.toml b/prover/Cargo.toml
index e818a6a2e..9a319315c 100644
--- a/prover/Cargo.toml
+++ b/prover/Cargo.toml
@@ -114,13 +114,13 @@ revm = { version = "34.0.0", features = [
"optional_fee_charge",
"optional_eip7623",
], default-features = false }
-reth-primitives-traits = { git = "https://github.com/paradigmxyz/reth", tag = "v1.10.2", default-features = false }
-reth-storage-errors = { git = "https://github.com/paradigmxyz/reth", tag = "v1.10.2", default-features = false }
-reth-trie = { git = "https://github.com/paradigmxyz/reth", tag = "v1.10.2", default-features = false }
-morph-revm = { git = "https://github.com/morph-l2/morph-reth.git", tag = "v0.1.0" }
-morph-evm = { git = "https://github.com/morph-l2/morph-reth.git", tag = "v0.1.0" }
-morph-primitives = { git = "https://github.com/morph-l2/morph-reth.git", tag = "v0.1.0" }
-morph-chainspec = { git = "https://github.com/morph-l2/morph-reth.git", tag = "v0.1.0" }
+reth-primitives-traits = { git = "https://github.com/morph-l2/reth", rev = "8057627ac9f169a0da4de44b616006a9e30382c1", default-features = false }
+reth-storage-errors = { git = "https://github.com/morph-l2/reth", rev = "8057627ac9f169a0da4de44b616006a9e30382c1", default-features = false }
+reth-trie = { git = "https://github.com/morph-l2/reth", rev = "8057627ac9f169a0da4de44b616006a9e30382c1", default-features = false }
+morph-revm = { git = "https://github.com/morph-l2/morph-reth.git", rev = "7454ea1b656755be9b81e557fc8d0ff87a8e6268" }
+morph-evm = { git = "https://github.com/morph-l2/morph-reth.git", rev = "7454ea1b656755be9b81e557fc8d0ff87a8e6268" }
+morph-primitives = { git = "https://github.com/morph-l2/morph-reth.git", rev = "7454ea1b656755be9b81e557fc8d0ff87a8e6268" }
+morph-chainspec = { git = "https://github.com/morph-l2/morph-reth.git", rev = "7454ea1b656755be9b81e557fc8d0ff87a8e6268" }
# ZK / SP1
From e1a591b51ff88375084c154f0c455992bd82303b Mon Sep 17 00:00:00 2001
From: chengwenxi <22697326+chengwenxi@users.noreply.github.com>
Date: Mon, 9 Mar 2026 18:27:33 +0800
Subject: [PATCH 07/21] prover: remove default impls for
morph_tx_version/reference/memo in TxTrace
---
prover/crates/primitives/src/lib.rs | 12 +++---------
1 file changed, 3 insertions(+), 9 deletions(-)
diff --git a/prover/crates/primitives/src/lib.rs b/prover/crates/primitives/src/lib.rs
index 2ffe3baca..87e283c22 100644
--- a/prover/crates/primitives/src/lib.rs
+++ b/prover/crates/primitives/src/lib.rs
@@ -163,19 +163,13 @@ pub trait TxTrace {
fn sig_v(&self) -> u64;
/// Get morph tx `version`.
- fn morph_tx_version(&self) -> u8 {
- 0
- }
+ fn morph_tx_version(&self) -> u8;
/// Get morph tx `reference`.
- fn morph_tx_reference(&self) -> Option {
- None
- }
+ fn morph_tx_reference(&self) -> Option;
/// Get morph tx `memo`.
- fn morph_tx_memo(&self) -> Option {
- None
- }
+ fn morph_tx_memo(&self) -> Option;
/// Try to build a envelope tx
fn try_build_tx_envelope(&self) -> Result {
From 0f35034fd01e1596b1480082959d298882bb4a31 Mon Sep 17 00:00:00 2001
From: Kathy <22675649+anylots@users.noreply.github.com>
Date: Mon, 9 Mar 2026 21:37:24 +0800
Subject: [PATCH 08/21] add local state test
---
prover/bin/shadow-prove/src/execute.rs | 63 ++++++++++++++++---
.../executor_input_19720290.data | 0
2 files changed, 56 insertions(+), 7 deletions(-)
rename prover/testdata/{mpt => state}/executor_input_19720290.data (100%)
diff --git a/prover/bin/shadow-prove/src/execute.rs b/prover/bin/shadow-prove/src/execute.rs
index 2d2d07247..dd7621d42 100644
--- a/prover/bin/shadow-prove/src/execute.rs
+++ b/prover/bin/shadow-prove/src/execute.rs
@@ -112,7 +112,7 @@ mod tests {
use prover_utils::provider::get_block_trace;
use crate::{
- execute::{execute_host_range, test_args, try_execute_batch},
+ execute::{execute, execute_host_range, test_args, try_execute_batch},
BatchInfo,
};
@@ -130,6 +130,21 @@ mod tests {
let _batch_info = EVMVerifier::verify(block_inputs).unwrap();
}
+ // cargo test -p shadow-proving --lib -- execute::tests::test_execute_block --exact --nocapture -- --block-number 19997 --rpc http://127.0.0.1:9545
+ #[tokio::test]
+ async fn test_execute_block() {
+ env_logger::Builder::new().filter_level(log::LevelFilter::Info).format_target(false).init();
+
+ let (start_block, rpc) = test_args::read_block_number_args_from_argv();
+ let provider = ProviderBuilder::new().connect_http(rpc.parse().unwrap()).erased();
+ let block_input = execute(start_block, &provider).await.unwrap();
+ let _ = EVMVerifier::verify(vec![block_input.clone()]).unwrap();
+ let input_path = format!("../../testdata/state/block_{}.data", start_block);
+ let file = File::create(&input_path).unwrap();
+ serde_json::to_writer(file, &block_input).unwrap();
+ println!("Saved executor input to {input_path}");
+ }
+
#[tokio::test]
async fn test_execute_batch() {
env_logger::Builder::new().filter_level(log::LevelFilter::Info).format_target(false).init();
@@ -162,15 +177,30 @@ mod tests {
println!("batch_info.post_state_root: {:?}", batch_info.post_state_root);
}
+ // cargo test --package shadow-proving --lib -- execute::tests::test_execute_local --exact --nocapture
#[tokio::test]
async fn test_execute_local() {
env_logger::Builder::new().filter_level(log::LevelFilter::Info).format_target(false).init();
- let file = std::fs::File::open("../../testdata/mpt/executor_input_19720290.data").unwrap();
- let reader = std::io::BufReader::new(file);
- let block_input: BlockInput = serde_json::from_reader(reader).unwrap();
-
- let batch_info = EVMVerifier::verify(vec![block_input]).unwrap();
- println!("batch_info.post_state_root: {:?}", batch_info.post_state_root);
+ let dir = "../../testdata/state";
+ let mut entries: Vec<_> = std::fs::read_dir(dir)
+ .unwrap_or_else(|e| panic!("Failed to read dir {dir}: {e}"))
+ .filter_map(|e| e.ok())
+ .filter(|e| {
+ e.path().extension().and_then(|s| s.to_str()) == Some("data")
+ })
+ .collect();
+ entries.sort_by_key(|e| e.path());
+ for entry in entries {
+ let path = entry.path();
+ println!("Processing {:?}", path);
+ let file = std::fs::File::open(&path)
+ .unwrap_or_else(|e| panic!("Failed to open {:?}: {e}", path));
+ let reader = std::io::BufReader::new(file);
+ let block_input: BlockInput = serde_json::from_reader(reader)
+ .unwrap_or_else(|e| panic!("Failed to deserialize {:?}: {e}", path));
+ let batch_info = EVMVerifier::verify(vec![block_input]).unwrap();
+ println!("batch_info.post_state_root: {:?}", batch_info.post_state_root);
+ }
}
#[tokio::test]
@@ -272,6 +302,25 @@ mod test_args {
(args.start_block, args.end_block, args.rpc)
}
+ /// Single block execute parameters.
+ #[derive(Parser, Debug)]
+ #[command(author, version, about, long_about = None, disable_help_flag = true)]
+ struct BlockNumberArgs {
+ /// L2 block number.
+ #[arg(long = "block-number", alias = "block", default_value_t = DEFAULT_BLOCK_NUMBER, value_parser = parse_u64_auto_radix)]
+ block_number: u64,
+
+ /// RPC endpoint.
+ #[arg(long, default_value = DEFAULT_RPC)]
+ rpc: String,
+ }
+
+ pub(super) fn read_block_number_args_from_argv() -> (u64, String) {
+ let filtered = filter_argv(&["--block-number", "--block", "--rpc"]);
+ let args = BlockNumberArgs::parse_from(filtered);
+ (args.block_number, args.rpc)
+ }
+
fn filter_argv(allowed_flags: &[&str]) -> Vec {
let argv: Vec = std::env::args().skip(1).collect();
let mut filtered: Vec = Vec::with_capacity(argv.len() + 1);
diff --git a/prover/testdata/mpt/executor_input_19720290.data b/prover/testdata/state/executor_input_19720290.data
similarity index 100%
rename from prover/testdata/mpt/executor_input_19720290.data
rename to prover/testdata/state/executor_input_19720290.data
From a3ec0f13cade2c2a1afc3362891b2ceee8f4cdf8 Mon Sep 17 00:00:00 2001
From: kathy <22675649+anylots@users.noreply.github.com>
Date: Mon, 9 Mar 2026 22:10:28 +0800
Subject: [PATCH 09/21] fix test_execute_block
---
prover/.gitignore | 3 ++-
prover/bin/shadow-prove/src/execute.rs | 2 +-
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/prover/.gitignore b/prover/.gitignore
index 62bb18875..ea5d86632 100644
--- a/prover/.gitignore
+++ b/prover/.gitignore
@@ -26,4 +26,5 @@ contracts
out
lib
-proof
\ No newline at end of file
+proof
+state
\ No newline at end of file
diff --git a/prover/bin/shadow-prove/src/execute.rs b/prover/bin/shadow-prove/src/execute.rs
index dd7621d42..18893e520 100644
--- a/prover/bin/shadow-prove/src/execute.rs
+++ b/prover/bin/shadow-prove/src/execute.rs
@@ -131,7 +131,7 @@ mod tests {
}
// cargo test -p shadow-proving --lib -- execute::tests::test_execute_block --exact --nocapture -- --block-number 19997 --rpc http://127.0.0.1:9545
- #[tokio::test]
+ #[tokio::test(flavor = "multi_thread")]
async fn test_execute_block() {
env_logger::Builder::new().filter_level(log::LevelFilter::Info).format_target(false).init();
From 1fab79c1f27f27ffa4af9a9cef2b647fcc830496 Mon Sep 17 00:00:00 2001
From: Kathy <22675649+anylots@users.noreply.github.com>
Date: Tue, 10 Mar 2026 00:30:25 +0800
Subject: [PATCH 10/21] gen verifier elf
---
contracts/src/deploy-config/holesky.ts | 2 +-
contracts/src/deploy-config/hoodi.ts | 2 +-
contracts/src/deploy-config/l1.ts | 2 +-
contracts/src/deploy-config/qanetl1.ts | 2 +-
contracts/src/deploy-config/sepolia.ts | 2 +-
contracts/src/deploy-config/testnetl1.ts | 2 +-
prover/Cargo.lock | 280 +-------------------
prover/Cargo.toml | 1 -
prover/bin/client/elf/verifier-client | Bin 6419016 -> 6485804 bytes
prover/bin/shadow-prove/contracts/README.md | 4 +-
prover/contracts/README.md | 2 +-
prover/crates/executor/core/Cargo.toml | 1 -
prover/crates/executor/core/src/executor.rs | 2 +-
prover/rust-toolchain | 2 +-
14 files changed, 13 insertions(+), 291 deletions(-)
diff --git a/contracts/src/deploy-config/holesky.ts b/contracts/src/deploy-config/holesky.ts
index a73fa6cb7..58e2f4fb7 100644
--- a/contracts/src/deploy-config/holesky.ts
+++ b/contracts/src/deploy-config/holesky.ts
@@ -14,7 +14,7 @@ const config = {
l2BaseFee: 0.1, // Gwei
// verify contract config
- programVkey: '0x001bbd0e32f56275cefa4a7313c51b94b763a4c295ac02af037b494895bc58c2',
+ programVkey: '0x0075749fa7bc5836f4fc2037d56fc6a9db3d2d40234facaa8749f3bd8a010266',
// rollup contract config
// initialize config
finalizationPeriodSeconds: 600,
diff --git a/contracts/src/deploy-config/hoodi.ts b/contracts/src/deploy-config/hoodi.ts
index ec2fd2a7b..f9bb2913e 100644
--- a/contracts/src/deploy-config/hoodi.ts
+++ b/contracts/src/deploy-config/hoodi.ts
@@ -17,7 +17,7 @@ const config = {
l2BaseFee: 0.1, // Gwei
// verify contract config
- programVkey: '0x001bbd0e32f56275cefa4a7313c51b94b763a4c295ac02af037b494895bc58c2',
+ programVkey: '0x0075749fa7bc5836f4fc2037d56fc6a9db3d2d40234facaa8749f3bd8a010266',
// rollup contract config
// initialize config
finalizationPeriodSeconds: 600,
diff --git a/contracts/src/deploy-config/l1.ts b/contracts/src/deploy-config/l1.ts
index 42cf90bbe..94d7a4ca4 100644
--- a/contracts/src/deploy-config/l1.ts
+++ b/contracts/src/deploy-config/l1.ts
@@ -17,7 +17,7 @@ const config = {
l2BaseFee: 0.1, // Gwei
// verify contract config
- programVkey: '0x001bbd0e32f56275cefa4a7313c51b94b763a4c295ac02af037b494895bc58c2',
+ programVkey: '0x0075749fa7bc5836f4fc2037d56fc6a9db3d2d40234facaa8749f3bd8a010266',
// rollup contract config
// initialize config
finalizationPeriodSeconds: 10,
diff --git a/contracts/src/deploy-config/qanetl1.ts b/contracts/src/deploy-config/qanetl1.ts
index edb387991..79f23a1a0 100644
--- a/contracts/src/deploy-config/qanetl1.ts
+++ b/contracts/src/deploy-config/qanetl1.ts
@@ -14,7 +14,7 @@ const config = {
l2BaseFee: 0.1, // Gwei
// verify contract config
- programVkey: '0x001bbd0e32f56275cefa4a7313c51b94b763a4c295ac02af037b494895bc58c2',
+ programVkey: '0x0075749fa7bc5836f4fc2037d56fc6a9db3d2d40234facaa8749f3bd8a010266',
// rollup contract config
// initialize config
finalizationPeriodSeconds: 600,
diff --git a/contracts/src/deploy-config/sepolia.ts b/contracts/src/deploy-config/sepolia.ts
index d8c416577..a76340ae8 100644
--- a/contracts/src/deploy-config/sepolia.ts
+++ b/contracts/src/deploy-config/sepolia.ts
@@ -18,7 +18,7 @@ const config = {
/**
* ---to---legacy property
*/
- programVkey: '0x001bbd0e32f56275cefa4a7313c51b94b763a4c295ac02af037b494895bc58c2',
+ programVkey: '0x0075749fa7bc5836f4fc2037d56fc6a9db3d2d40234facaa8749f3bd8a010266',
rollupMinDeposit: 0.0001,
rollupProofWindow: 86400,
rollupGenesisBlockNumber: 0,
diff --git a/contracts/src/deploy-config/testnetl1.ts b/contracts/src/deploy-config/testnetl1.ts
index ce1b46b0e..bfe02cdd1 100644
--- a/contracts/src/deploy-config/testnetl1.ts
+++ b/contracts/src/deploy-config/testnetl1.ts
@@ -13,7 +13,7 @@ const config = {
sequencerWindowSize: 200,
channelTimeout: 120,
- programVkey: '0x001bbd0e32f56275cefa4a7313c51b94b763a4c295ac02af037b494895bc58c2',
+ programVkey: '0x0075749fa7bc5836f4fc2037d56fc6a9db3d2d40234facaa8749f3bd8a010266',
rollupMinDeposit: 1,
rollupProofWindow: 100,
rollupGenesisBlockNumber: 0,
diff --git a/prover/Cargo.lock b/prover/Cargo.lock
index 05eeb3024..7380713ac 100644
--- a/prover/Cargo.lock
+++ b/prover/Cargo.lock
@@ -484,7 +484,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7bdcbf9dfd5eea8bfeb078b1d906da8cd3a39c4d4dbe7a628025648e323611f6"
dependencies = [
"alloy-primitives",
- "alloy-rpc-types-engine",
"alloy-rpc-types-eth",
"alloy-serde",
"serde",
@@ -527,7 +526,6 @@ dependencies = [
"derive_more 2.1.0",
"ethereum_ssz",
"ethereum_ssz_derive",
- "jsonwebtoken",
"rand 0.8.5",
"serde",
"strum 0.27.2",
@@ -3942,21 +3940,6 @@ dependencies = [
"wasm-bindgen",
]
-[[package]]
-name = "jsonwebtoken"
-version = "9.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5a87cc7a48537badeae96744432de36f4be2b4a34a05a5ef32e9dd8a1c169dde"
-dependencies = [
- "base64 0.22.1",
- "js-sys",
- "pem",
- "ring",
- "serde",
- "serde_json",
- "simple_asn1",
-]
-
[[package]]
name = "jubjub"
version = "0.9.0"
@@ -4176,27 +4159,6 @@ version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d97bbf43eb4f088f8ca469930cde17fa036207c9a5e02ccc5107c4e8b17c964"
-[[package]]
-name = "metrics"
-version = "0.24.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5d5312e9ba3771cfa961b585728215e3d972c950a3eed9252aa093d6301277e8"
-dependencies = [
- "ahash",
- "portable-atomic",
-]
-
-[[package]]
-name = "metrics-derive"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "161ab904c2c62e7bda0f7562bf22f96440ca35ff79e66c800cbac298f2f4f5ec"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.111",
-]
-
[[package]]
name = "mime"
version = "0.3.17"
@@ -4273,49 +4235,6 @@ dependencies = [
"serde_json",
]
-[[package]]
-name = "morph-evm"
-version = "0.1.0"
-source = "git+https://github.com/morph-l2/morph-reth.git?rev=7454ea1b656755be9b81e557fc8d0ff87a8e6268#7454ea1b656755be9b81e557fc8d0ff87a8e6268"
-dependencies = [
- "alloy-consensus",
- "alloy-evm",
- "alloy-primitives",
- "derive_more 2.1.0",
- "morph-chainspec",
- "morph-payload-types",
- "morph-primitives",
- "morph-revm",
- "reth-chainspec",
- "reth-ethereum-primitives",
- "reth-evm",
- "reth-primitives-traits",
- "reth-revm",
- "revm",
- "thiserror 2.0.17",
- "tracing",
-]
-
-[[package]]
-name = "morph-payload-types"
-version = "0.1.0"
-source = "git+https://github.com/morph-l2/morph-reth.git?rev=7454ea1b656755be9b81e557fc8d0ff87a8e6268#7454ea1b656755be9b81e557fc8d0ff87a8e6268"
-dependencies = [
- "alloy-consensus",
- "alloy-eips",
- "alloy-primitives",
- "alloy-rlp",
- "alloy-rpc-types-engine",
- "alloy-serde",
- "morph-primitives",
- "reth-ethereum-primitives",
- "reth-payload-builder",
- "reth-payload-primitives",
- "reth-primitives-traits",
- "serde",
- "sha2",
-]
-
[[package]]
name = "morph-primitives"
version = "0.1.0"
@@ -4344,12 +4263,9 @@ dependencies = [
"log",
"once_cell",
"prover-executor-client",
- "prover-executor-core",
"prover-executor-host",
"prover-primitives",
"prover-utils",
- "reth-trie",
- "revm",
"serde",
"serde_json",
"sp1-sdk",
@@ -4594,7 +4510,7 @@ version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56"
dependencies = [
- "proc-macro-crate 3.1.0",
+ "proc-macro-crate 1.3.1",
"proc-macro2",
"quote",
"syn 2.0.111",
@@ -4682,7 +4598,6 @@ dependencies = [
"alloy-serde",
"derive_more 2.1.0",
"serde",
- "serde_with",
"thiserror 2.0.17",
]
@@ -5195,16 +5110,6 @@ version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3"
-[[package]]
-name = "pem"
-version = "3.0.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1d30c53c26bc5b31a98cd02d20f25a7c8567146caf63ed593a9d87b2775291be"
-dependencies = [
- "base64 0.22.1",
- "serde_core",
-]
-
[[package]]
name = "pem-rfc7468"
version = "0.7.0"
@@ -5552,7 +5457,6 @@ dependencies = [
"alloy-evm",
"anyhow",
"morph-chainspec",
- "morph-evm",
"morph-primitives",
"morph-revm",
"revm",
@@ -5741,7 +5645,7 @@ dependencies = [
"once_cell",
"socket2 0.6.1",
"tracing",
- "windows-sys 0.60.2",
+ "windows-sys 0.59.0",
]
[[package]]
@@ -6028,32 +5932,6 @@ dependencies = [
"tower-service",
]
-[[package]]
-name = "reth-chain-state"
-version = "1.10.2"
-source = "git+https://github.com/morph-l2/reth?rev=8057627ac9f169a0da4de44b616006a9e30382c1#8057627ac9f169a0da4de44b616006a9e30382c1"
-dependencies = [
- "alloy-consensus",
- "alloy-eips",
- "alloy-primitives",
- "derive_more 2.1.0",
- "metrics",
- "parking_lot",
- "pin-project",
- "reth-chainspec",
- "reth-errors",
- "reth-ethereum-primitives",
- "reth-execution-types",
- "reth-metrics",
- "reth-primitives-traits",
- "reth-storage-api",
- "reth-trie",
- "revm-database",
- "tokio",
- "tokio-stream",
- "tracing",
-]
-
[[package]]
name = "reth-chainspec"
version = "1.10.2"
@@ -6102,19 +5980,6 @@ dependencies = [
"syn 2.0.111",
]
-[[package]]
-name = "reth-consensus"
-version = "1.10.2"
-source = "git+https://github.com/morph-l2/reth?rev=8057627ac9f169a0da4de44b616006a9e30382c1#8057627ac9f169a0da4de44b616006a9e30382c1"
-dependencies = [
- "alloy-consensus",
- "alloy-primitives",
- "auto_impl",
- "reth-execution-types",
- "reth-primitives-traits",
- "thiserror 2.0.17",
-]
-
[[package]]
name = "reth-db-models"
version = "1.10.2"
@@ -6127,58 +5992,6 @@ dependencies = [
"serde",
]
-[[package]]
-name = "reth-engine-primitives"
-version = "1.10.2"
-source = "git+https://github.com/morph-l2/reth?rev=8057627ac9f169a0da4de44b616006a9e30382c1#8057627ac9f169a0da4de44b616006a9e30382c1"
-dependencies = [
- "alloy-consensus",
- "alloy-eips",
- "alloy-primitives",
- "alloy-rpc-types-engine",
- "auto_impl",
- "reth-chain-state",
- "reth-errors",
- "reth-ethereum-primitives",
- "reth-evm",
- "reth-execution-types",
- "reth-payload-builder-primitives",
- "reth-payload-primitives",
- "reth-primitives-traits",
- "reth-trie-common",
- "serde",
- "thiserror 2.0.17",
-]
-
-[[package]]
-name = "reth-errors"
-version = "1.10.2"
-source = "git+https://github.com/morph-l2/reth?rev=8057627ac9f169a0da4de44b616006a9e30382c1#8057627ac9f169a0da4de44b616006a9e30382c1"
-dependencies = [
- "reth-consensus",
- "reth-execution-errors",
- "reth-storage-errors",
- "thiserror 2.0.17",
-]
-
-[[package]]
-name = "reth-ethereum-engine-primitives"
-version = "1.10.2"
-source = "git+https://github.com/morph-l2/reth?rev=8057627ac9f169a0da4de44b616006a9e30382c1#8057627ac9f169a0da4de44b616006a9e30382c1"
-dependencies = [
- "alloy-eips",
- "alloy-primitives",
- "alloy-rlp",
- "alloy-rpc-types-engine",
- "reth-engine-primitives",
- "reth-ethereum-primitives",
- "reth-payload-primitives",
- "reth-primitives-traits",
- "serde",
- "sha2",
- "thiserror 2.0.17",
-]
-
[[package]]
name = "reth-ethereum-forks"
version = "1.10.2"
@@ -6263,15 +6076,6 @@ dependencies = [
"serde_with",
]
-[[package]]
-name = "reth-metrics"
-version = "1.10.2"
-source = "git+https://github.com/morph-l2/reth?rev=8057627ac9f169a0da4de44b616006a9e30382c1#8057627ac9f169a0da4de44b616006a9e30382c1"
-dependencies = [
- "metrics",
- "metrics-derive",
-]
-
[[package]]
name = "reth-network-peers"
version = "1.10.2"
@@ -6285,62 +6089,6 @@ dependencies = [
"url",
]
-[[package]]
-name = "reth-payload-builder"
-version = "1.10.2"
-source = "git+https://github.com/morph-l2/reth?rev=8057627ac9f169a0da4de44b616006a9e30382c1#8057627ac9f169a0da4de44b616006a9e30382c1"
-dependencies = [
- "alloy-consensus",
- "alloy-primitives",
- "alloy-rpc-types",
- "futures-util",
- "metrics",
- "reth-chain-state",
- "reth-ethereum-engine-primitives",
- "reth-metrics",
- "reth-payload-builder-primitives",
- "reth-payload-primitives",
- "reth-primitives-traits",
- "tokio",
- "tokio-stream",
- "tracing",
-]
-
-[[package]]
-name = "reth-payload-builder-primitives"
-version = "1.10.2"
-source = "git+https://github.com/morph-l2/reth?rev=8057627ac9f169a0da4de44b616006a9e30382c1#8057627ac9f169a0da4de44b616006a9e30382c1"
-dependencies = [
- "pin-project",
- "reth-payload-primitives",
- "tokio",
- "tokio-stream",
- "tracing",
-]
-
-[[package]]
-name = "reth-payload-primitives"
-version = "1.10.2"
-source = "git+https://github.com/morph-l2/reth?rev=8057627ac9f169a0da4de44b616006a9e30382c1#8057627ac9f169a0da4de44b616006a9e30382c1"
-dependencies = [
- "alloy-consensus",
- "alloy-eips",
- "alloy-primitives",
- "alloy-rpc-types-engine",
- "auto_impl",
- "either",
- "op-alloy-rpc-types-engine",
- "reth-chain-state",
- "reth-chainspec",
- "reth-errors",
- "reth-execution-types",
- "reth-primitives-traits",
- "reth-trie-common",
- "serde",
- "thiserror 2.0.17",
- "tokio",
-]
-
[[package]]
name = "reth-primitives-traits"
version = "1.10.2"
@@ -6380,18 +6128,6 @@ dependencies = [
"thiserror 2.0.17",
]
-[[package]]
-name = "reth-revm"
-version = "1.10.2"
-source = "git+https://github.com/morph-l2/reth?rev=8057627ac9f169a0da4de44b616006a9e30382c1#8057627ac9f169a0da4de44b616006a9e30382c1"
-dependencies = [
- "alloy-primitives",
- "reth-primitives-traits",
- "reth-storage-api",
- "reth-storage-errors",
- "revm",
-]
-
[[package]]
name = "reth-stages-types"
version = "1.10.2"
@@ -7468,18 +7204,6 @@ dependencies = [
"rand_core 0.6.4",
]
-[[package]]
-name = "simple_asn1"
-version = "0.6.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0d585997b0ac10be3c5ee635f1bab02d512760d14b7c468801ac8a01d9ae5f1d"
-dependencies = [
- "num-bigint 0.4.6",
- "num-traits",
- "thiserror 2.0.17",
- "time",
-]
-
[[package]]
name = "siphasher"
version = "1.0.1"
diff --git a/prover/Cargo.toml b/prover/Cargo.toml
index 9a319315c..6b1d84af4 100644
--- a/prover/Cargo.toml
+++ b/prover/Cargo.toml
@@ -118,7 +118,6 @@ reth-primitives-traits = { git = "https://github.com/morph-l2/reth", rev = "8057
reth-storage-errors = { git = "https://github.com/morph-l2/reth", rev = "8057627ac9f169a0da4de44b616006a9e30382c1", default-features = false }
reth-trie = { git = "https://github.com/morph-l2/reth", rev = "8057627ac9f169a0da4de44b616006a9e30382c1", default-features = false }
morph-revm = { git = "https://github.com/morph-l2/morph-reth.git", rev = "7454ea1b656755be9b81e557fc8d0ff87a8e6268" }
-morph-evm = { git = "https://github.com/morph-l2/morph-reth.git", rev = "7454ea1b656755be9b81e557fc8d0ff87a8e6268" }
morph-primitives = { git = "https://github.com/morph-l2/morph-reth.git", rev = "7454ea1b656755be9b81e557fc8d0ff87a8e6268" }
morph-chainspec = { git = "https://github.com/morph-l2/morph-reth.git", rev = "7454ea1b656755be9b81e557fc8d0ff87a8e6268" }
diff --git a/prover/bin/client/elf/verifier-client b/prover/bin/client/elf/verifier-client
index 627d6765b9d219e82202710541f01a2864532f66..9b729fed6847712f897e286e10119c6a9ba45645 100755
GIT binary patch
delta 1795280
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