Skip to content

Commit f33134d

Browse files
committed
evm execute
1 parent 5e8d64b commit f33134d

File tree

12 files changed

+194
-41
lines changed

12 files changed

+194
-41
lines changed

prover/Cargo.lock

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

prover/Cargo.toml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -114,10 +114,11 @@ revm = { version = "33.1.0", features = ["optional_fee_charge"] }
114114
reth-primitives-traits = { git = "https://github.com/paradigmxyz/reth", rev = "64909d3" }
115115
reth-storage-errors = { git = "https://github.com/paradigmxyz/reth", rev = "64909d3" }
116116
reth-trie = { git = "https://github.com/paradigmxyz/reth", rev = "64909d3" }
117-
morph-revm = { path = "/root/projects/layer2/morph/morph-reth/crates/revm" }
118-
morph-evm = { path = "/root/projects/layer2/morph/morph-reth/crates/evm" }
119-
morph-primitives = { path = "/root/projects/layer2/morph/morph-reth/crates/primitives" }
120-
morph-chainspec = { path = "/root/projects/layer2/morph/morph-reth/crates/chainspec" }
117+
morph-revm = { git = "https://github.com/morph-l2/morph-reth.git", branch = "main" }
118+
morph-evm = { git = "https://github.com/morph-l2/morph-reth.git", branch = "main" }
119+
morph-primitives = { git = "https://github.com/morph-l2/morph-reth.git", branch = "main" }
120+
morph-chainspec = { git = "https://github.com/morph-l2/morph-reth.git", branch = "main" }
121+
121122
# ZK / SP1
122123
sp1-sdk = { version = "5.1.0" }
123124
sp1-zkvm = { version = "5.1.0" }

prover/bin/shadow-prove/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,5 @@ alloy-signer-local = { workspace = true }
4040

4141
prover-executor-host = { workspace = true }
4242
prover-executor-client = { workspace = true }
43-
prover-primitives = { workspace = true }
43+
prover-primitives = { workspace = true }
44+
prover-utils.workspace = true

prover/bin/shadow-prove/src/execute.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,3 +74,24 @@ async fn get_block_traces(
7474
}
7575
Some(block_traces)
7676
}
77+
78+
#[cfg(test)]
79+
mod tests {
80+
use alloy_provider::{Provider, ProviderBuilder};
81+
use prover_executor_client::{types::input::BlockInput, EVMVerifier};
82+
use prover_primitives::types::BlockTrace;
83+
use prover_utils::provider::get_block_trace;
84+
85+
#[tokio::test]
86+
async fn test_execute_remote() {
87+
let provider =
88+
ProviderBuilder::new().connect_http("http://127.0.0.1:9545".parse().unwrap()).erased();
89+
90+
let block_trace = get_block_trace::<BlockTrace>(53, &provider).await.unwrap();
91+
println!("loaded block_{} traces", block_trace.header.number);
92+
let block_input: BlockInput = BlockInput::from_trace(&block_trace);
93+
94+
let batch_info = EVMVerifier::verify(vec![block_input]).unwrap();
95+
println!("batch_info.post_state_root: {:?}", batch_info.post_state_root);
96+
}
97+
}

prover/crates/executor/client/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,4 @@ morph-revm = { workspace = true }
3232

3333

3434
[dev-dependencies]
35-
serde_json = { workspace = true }
35+
serde_json = { workspace = true }

prover/crates/executor/client/src/verifier/evm_verifier.rs

Lines changed: 44 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,10 @@ use morph_revm::MorphTxEnv;
99
use prover_executor_core::MorphExecutor;
1010
use reth_trie::{HashedPostState, KeccakKeyHasher};
1111
use revm::context::BlockEnv;
12-
use revm::database::{BundleState, State};
12+
use revm::database::states::bundle_state::BundleRetention;
13+
use revm::database::State;
1314
use revm::primitives::address;
14-
use revm::ExecuteEvm;
15+
use revm::ExecuteCommitEvm;
1516

1617
// use Verifier;
1718
pub struct EVMVerifier;
@@ -58,12 +59,13 @@ fn execute(mut block_inputs: Vec<BlockInput>) -> Result<BatchInfo, ClientError>
5859
fn execute_block(block_input: &mut BlockInput) -> Result<(), ClientError> {
5960
//Build db and verify state.
6061
let trie_db = block_input.witness_db()?;
61-
let bundle_state = BundleState::default();
62+
6263
let state = State::builder()
6364
.with_database_ref(&trie_db)
64-
.with_bundle_prestate(bundle_state)
65+
.with_bundle_update()
6566
.without_state_clear()
6667
.build();
68+
6769
// Build EVM.
6870
let block_env = BlockEnv {
6971
number: block_input.current_block.header.number,
@@ -76,11 +78,12 @@ fn execute_block(block_input: &mut BlockInput) -> Result<(), ClientError> {
7678

7779
let mut evm = MorphExecutor::with_hardfork(state, block_env);
7880
// Execute transactions in block.
81+
let mut block_input_orgin = block_input.clone();
7982
let block = &block_input.current_block;
8083
for tx in &block.transactions {
8184
let recovered_from = SignerRecoverable::recover_signer(tx)
8285
.map_err(|_| ClientError::SignatureRecoveryFailed)?;
83-
let tx = revm::context::TxEnv {
86+
let tx_env = revm::context::TxEnv {
8487
caller: recovered_from,
8588
nonce: tx.nonce(),
8689
gas_price: tx.gas_price().unwrap_or_default(),
@@ -90,24 +93,53 @@ fn execute_block(block_input: &mut BlockInput) -> Result<(), ClientError> {
9093
data: revm::primitives::Bytes::from(tx.input().to_vec()),
9194
..Default::default()
9295
};
93-
let morph_tx = MorphTxEnv { inner: tx, rlp_bytes: Default::default(), fee_token_id: 1u16 };
96+
let morph_tx = MorphTxEnv { inner: tx_env, rlp_bytes: None, ..Default::default() };
9497

9598
let _rt = evm
9699
.inner
97-
.transact(morph_tx)
100+
.transact_commit(morph_tx)
98101
.map_err(|e| ClientError::BlockExecutionError(e.to_string()))?;
99102
}
103+
evm.inner.ctx.journaled_state.database.merge_transitions(BundleRetention::Reverts);
100104
let bundle_state = evm.inner.ctx.journaled_state.database.take_bundle();
101-
drop(evm);
102-
drop(trie_db);
105+
println!("bundle_state len: {:?}", bundle_state.len());
103106
// Verify post state root.
104107
let hashed_post_state =
105108
HashedPostState::from_bundle_state::<KeccakKeyHasher>(&bundle_state.state);
106-
block_input.parent_state.update(&hashed_post_state);
107-
if block_input.parent_state.state_root() != block_input.current_block.post_state_root {
109+
block_input_orgin.parent_state.update(&hashed_post_state);
110+
111+
if block_input_orgin.parent_state.state_root()
112+
!= block_input_orgin.current_block.post_state_root
113+
{
108114
return Err(ClientError::MismatchedStateRoot(
109-
block_input.current_block.header.number.to::<u64>(),
115+
block_input_orgin.current_block.header.number.to::<u64>(),
110116
));
111117
};
112118
Ok(())
113119
}
120+
121+
#[cfg(test)]
122+
mod tests {
123+
use crate::types::input::BlockInput;
124+
use crate::verifier::evm_verifier::execute;
125+
use prover_primitives::types::BlockTrace;
126+
use std::fs::File;
127+
use std::io::BufReader;
128+
129+
#[test]
130+
fn test_execute_local() {
131+
let block_trace = load_trace("../../../testdata/mpt/local_transfer_eth.json");
132+
println!("loaded {} block_traces", block_trace.len());
133+
let blocks: Vec<BlockInput> =
134+
block_trace.iter().map(|trace| BlockInput::from_trace(trace)).collect();
135+
println!("blocks len: {:?}", blocks.len());
136+
137+
let _rt = execute(blocks).unwrap();
138+
}
139+
140+
fn load_trace(file_path: &str) -> Vec<BlockTrace> {
141+
let file = File::open(file_path).unwrap();
142+
let reader = BufReader::new(file);
143+
serde_json::from_reader(reader).unwrap()
144+
}
145+
}

prover/crates/executor/core/src/executor.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ impl<DB: Database> MorphExecutor<DB> {
2828
pub fn with_hardfork(db: DB, block_env: BlockEnv) -> Self {
2929
let mut env: EvmEnv<MorphHardfork, MorphBlockEnv> =
3030
EvmEnv::default().with_timestamp(block_env.timestamp);
31-
env.cfg_env = env.cfg_env.with_spec(MorphHardfork::Viridian);
31+
env.cfg_env = env.cfg_env.with_spec(MorphHardfork::Curie);
3232
env.block_env = MorphBlockEnv { inner: block_env };
3333
Self::new(db, env)
3434
}
@@ -60,7 +60,8 @@ mod tests {
6060
data: revm::primitives::Bytes::new(),
6161
..Default::default()
6262
};
63-
let morph_tx = MorphTxEnv { inner: tx, rlp_bytes: Default::default(), fee_token_id: 1u16 };
63+
let morph_tx =
64+
MorphTxEnv { inner: tx, rlp_bytes: Default::default(), ..Default::default() };
6465
let _rt = evm.inner.transact_one(morph_tx);
6566
let _state = evm.inner.finalize();
6667
let _db = evm.inner.journaled_state.database.take_bundle();

prover/crates/executor/host/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,11 @@ prover-executor-client = { workspace = true }
1717
prover-utils = { workspace = true }
1818
prover-storage.workspace = true
1919
prover-executor-core.workspace = true
20+
prover-mpt = { workspace = true }
2021
revm = { workspace = true }
2122
alloy-provider = { workspace = true }
2223
alloy-network = { workspace = true }
2324
alloy-rpc-types = { workspace = true }
2425
reth-trie.workspace = true
2526
morph-revm = { workspace = true }
27+
alloy-primitives = { workspace = true }

prover/crates/executor/host/src/execute.rs

Lines changed: 49 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,23 @@
11
use alloy_consensus::{transaction::SignerRecoverable, BlockHeader, Transaction};
2-
use alloy_network::{BlockResponse, Network};
3-
use alloy_provider::Provider;
2+
use alloy_network::{BlockResponse, Ethereum, Network};
3+
use alloy_primitives::map::HashMap;
4+
use alloy_provider::{DynProvider, Provider, ProviderBuilder};
45
use anyhow::{bail, Context};
56
use morph_revm::MorphTxEnv;
67
use prover_executor_core::MorphExecutor;
7-
use prover_primitives::{MorphTxEnvelope, B256};
8-
use prover_storage::basic_rpc_db::{BasicRpcDb, RpcDb};
8+
use prover_mpt::EthereumState;
9+
use prover_primitives::{types::BlockTrace, Block, MorphTxEnvelope, B256};
10+
use prover_storage::{
11+
basic_rpc_db::{BasicRpcDb, RpcDb},
12+
trace_to_execution_witness, TrieDB,
13+
};
14+
use prover_utils::provider::{get_block_trace, get_block_traces};
915
use reth_trie::{HashedPostState, KeccakKeyHasher};
1016
use revm::{
1117
context::BlockEnv,
12-
database::{BundleState, State},
13-
ExecuteEvm,
18+
database::{states::bundle_state::BundleRetention, BundleState, State},
19+
state::Bytecode,
20+
ExecuteCommitEvm, ExecuteEvm,
1421
};
1522

1623
/// An executor that fetches data from a [Provider] to execute blocks in the [ClientExecutor].
@@ -38,10 +45,11 @@ impl HostExecutor {
3845

3946
// Init db.
4047
let rpc_db = BasicRpcDb::new(provider.clone(), block_number, B256::default());
41-
let bundle_state = BundleState::default();
48+
49+
// let (trie_db, mut orgin_state) = build_trie_db(block_number, provider).await.unwrap();
4250
let state = State::builder()
4351
.with_database_ref(&rpc_db)
44-
.with_bundle_prestate(bundle_state)
52+
.with_bundle_update()
4553
.without_state_clear()
4654
.build();
4755
let block_env = BlockEnv::default();
@@ -51,7 +59,7 @@ impl HostExecutor {
5159
// Execute transactions in block.
5260
for tx in evm_txns {
5361
let recovered_from = tx.recover_signer().context("tx recover signer error")?;
54-
let tx = revm::context::TxEnv {
62+
let tx_env = revm::context::TxEnv {
5563
caller: recovered_from,
5664
nonce: tx.nonce(),
5765
gas_price: tx.gas_price().unwrap_or_default(),
@@ -62,22 +70,19 @@ impl HostExecutor {
6270
..Default::default()
6371
};
6472
let morph_tx =
65-
MorphTxEnv { inner: tx, rlp_bytes: Default::default(), fee_token_id: 1u16 };
73+
MorphTxEnv { inner: tx_env, rlp_bytes: Some(tx.rlp()), ..Default::default() };
6674

67-
let _rt = evm.inner.transact(morph_tx).context("tx transact error")?;
75+
let _rt = evm.inner.transact_commit(morph_tx).context("tx transact error")?;
6876
}
77+
evm.inner.ctx.journaled_state.database.merge_transitions(BundleRetention::Reverts);
6978
let bundle_state = evm.inner.ctx.journaled_state.database.take_bundle();
70-
let state = rpc_db.state(&bundle_state).await?;
71-
drop(evm);
72-
// drop(rpc_db);
79+
let mut state = rpc_db.state(&bundle_state).await?;
7380
// Verify post state root.
74-
7581
let hashed_post_state =
7682
HashedPostState::from_bundle_state::<KeccakKeyHasher>(&bundle_state.state);
77-
let mut mutated_state = state.clone();
78-
mutated_state.update(&hashed_post_state);
83+
state.update(&hashed_post_state);
7984

80-
let computed_state_root = mutated_state.state_root();
85+
let computed_state_root = state.state_root();
8186
let expected_state_root = block.header().state_root();
8287
if computed_state_root != expected_state_root {
8388
bail!(
@@ -88,6 +93,32 @@ impl HostExecutor {
8893
}
8994
}
9095

96+
// async fn build_trie_db<P, N>(
97+
// block_number: u64,
98+
// provider: &P,
99+
// ) -> Result<(TrieDB<'_>, EthereumState), String>
100+
// where
101+
// P: Provider<N> + Clone + std::fmt::Debug,
102+
// N: Network,
103+
// {
104+
// let trace = get_block_trace::<BlockTrace, P, N>(block_number, &provider).await.unwrap();
105+
// let witness = trace_to_execution_witness(&trace).unwrap();
106+
// let state = EthereumState::from_execution_witness(&witness, trace.root_before());
107+
// let bytecodes =
108+
// witness.codes.into_iter().map(|code| Bytecode::new_raw(code)).collect::<Vec<_>>();
109+
// let bytecodes_by_hash =
110+
// bytecodes.iter().map(|code| (code.hash_slow(), code)).collect::<HashMap<_, _>>();
111+
// let block_hashes: HashMap<u64, B256> = HashMap::with_hasher(Default::default());
112+
// let statea= state.clone();
113+
// Ok((TrieDB::new(&state.clone(), block_hashes, bytecodes_by_hash), statea))
114+
// }
115+
91116
fn _to_prover_tx(_txns: &Vec<alloy_rpc_types::Transaction>) -> Vec<MorphTxEnvelope> {
92117
vec![]
93118
}
119+
120+
#[test]
121+
fn test_execute_host() {
122+
let provider =
123+
ProviderBuilder::new().connect_http("http://127.0.0.1:8545".parse().unwrap()).erased();
124+
}

prover/crates/utils/Cargo.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,8 @@ edition = "2021"
66

77
[dependencies]
88
anyhow = { workspace = true }
9+
alloy-provider = { workspace = true }
10+
alloy-network = { workspace = true }
11+
alloy-json-rpc = { workspace = true }
12+
serde = { workspace = true, features = ["derive"] }
13+
log = { workspace = true }

0 commit comments

Comments
 (0)