-
Notifications
You must be signed in to change notification settings - Fork 21
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(l2): integrate ExecutionDB, prove execution (#956)
**Motivation** Integrates the `ExecutionDB` defined in the `ethereum_rust-vm` crate with the L2 prover, using it to represent the blockchain state in the zkVM and executing a block. **Description** - prover server creates the DB from a pre-execution at request - the zkVM program takes the DB and block as inputs, and executes the block - generate groth16 proof instead of the default, which is not EVM-friendly and has no recursion. Recursion adds proving time and computing requirements, so we must take it into account. --------- Co-authored-by: fborello-lambda <[email protected]> Co-authored-by: Federico Borello <[email protected]>
- Loading branch information
1 parent
66f1d1b
commit 7800e5f
Showing
7 changed files
with
86 additions
and
117 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,111 +1,39 @@ | ||
use ethereum_rust_rlp::{decode::RLPDecode, error::RLPDecodeError}; | ||
use risc0_zkvm::guest::env; | ||
|
||
//use ethereum_rust_blockchain::validate_gas_used; | ||
use ethereum_rust_core::types::{Receipt, Transaction}; | ||
// We have to import the ExecutionDB. | ||
use ethereum_rust_vm::{block_env, tx_env}; | ||
|
||
use revm::{ | ||
db::CacheDB, inspectors::TracerEip3155, primitives::ResultAndState as RevmResultAndState, | ||
Evm as Revm, | ||
}; | ||
use ethereum_rust_blockchain::{validate_block, validate_gas_used}; | ||
use ethereum_rust_core::types::{Block, BlockHeader}; | ||
use ethereum_rust_vm::{execute_block, execution_db::ExecutionDB, get_state_transitions, EvmState}; | ||
|
||
fn main() { | ||
// Read the input | ||
let head_block_bytes = env::read::<Vec<u8>>(); | ||
let parent_header_bytes = env::read::<Vec<u8>>(); | ||
//let execution_db = env::read::<ExecutionDB>(); | ||
let (block, execution_db, parent_header) = read_inputs().expect("failed to read inputs"); | ||
let mut state = EvmState::from_exec_db(execution_db.clone()); | ||
|
||
// SetUp data from inputs | ||
let block = <ethereum_rust_core::types::Block as ethereum_rust_rlp::decode::RLPDecode>::decode( | ||
&head_block_bytes, | ||
) | ||
.unwrap(); | ||
// Validate the block pre-execution | ||
validate_block(&block, &parent_header, &state).expect("invalid block"); | ||
|
||
let parent_header = | ||
<ethereum_rust_core::types::BlockHeader as ethereum_rust_rlp::decode::RLPDecode>::decode( | ||
&parent_header_bytes, | ||
) | ||
.unwrap(); | ||
let receipts = execute_block(&block, &mut state).unwrap(); | ||
|
||
// Make DataInputs public. | ||
env::commit(&block); | ||
env::commit(&parent_header); | ||
//env::commit(&execution_db); | ||
|
||
// SetUp CacheDB in order to use execute_block() | ||
//let mut cache_db = CacheDB::new(execution_db); | ||
println!("executing block"); | ||
validate_gas_used(&receipts, &block.header).expect("invalid gas used"); | ||
|
||
//let block_receipts = execute_block(&block, &mut cache_db).unwrap(); | ||
// TODO | ||
// Handle the case in which the gas used differs and throws an error. | ||
// Should the zkVM panic? Should it generate a dummy proof? | ||
// Private function | ||
//let _ = validate_gas_used(&block_receipts, &block.header); | ||
let _account_updates = get_state_transitions(&mut state); | ||
|
||
//env::commit(&block_receipts); | ||
// TODO: compute new state root from account updates and check it matches with the block's | ||
// header one. | ||
} | ||
|
||
// Modified from ethereum_rust-vm | ||
/* | ||
fn execute_block( | ||
block: ðereum_rust_core::types::Block, | ||
db: &mut CacheDB<ExecutionDB>, | ||
) -> Result<Vec<Receipt>, ethereum_rust_vm::EvmError> { | ||
let spec_id = revm::primitives::SpecId::CANCUN; | ||
let mut receipts = Vec::new(); | ||
let mut cumulative_gas_used = 0; | ||
for transaction in block.body.transactions.iter() { | ||
let result = execute_tx(transaction, &block.header, db, spec_id)?; | ||
cumulative_gas_used += result.gas_used(); | ||
let receipt = Receipt::new( | ||
transaction.tx_type(), | ||
result.is_success(), | ||
cumulative_gas_used, | ||
result.logs(), | ||
); | ||
receipts.push(receipt); | ||
} | ||
fn read_inputs() -> Result<(Block, ExecutionDB, BlockHeader), RLPDecodeError> { | ||
let head_block_bytes = env::read::<Vec<u8>>(); | ||
let execution_db = env::read::<ExecutionDB>(); | ||
let parent_header_bytes = env::read::<Vec<u8>>(); | ||
|
||
Ok(receipts) | ||
} | ||
let block = Block::decode(&head_block_bytes)?; | ||
let parent_header = BlockHeader::decode(&parent_header_bytes)?; | ||
|
||
// Modified from ethereum_rust-vm | ||
fn execute_tx( | ||
transaction: &Transaction, | ||
block_header: ðereum_rust_core::types::BlockHeader, | ||
db: &mut CacheDB<ExecutionDB>, | ||
spec_id: revm::primitives::SpecId, | ||
) -> Result<ethereum_rust_vm::ExecutionResult, ethereum_rust_vm::EvmError> { | ||
let block_env = block_env(block_header); | ||
let tx_env = tx_env(transaction); | ||
run_evm(tx_env, block_env, db, spec_id) | ||
.map(Into::into) | ||
.map_err(ethereum_rust_vm::EvmError::from) | ||
} | ||
// make inputs public | ||
env::commit(&block); | ||
env::commit(&execution_db); | ||
env::commit(&parent_header); | ||
|
||
// Modified from ethereum_rust-vm | ||
fn run_evm( | ||
tx_env: revm::primitives::TxEnv, | ||
block_env: revm::primitives::BlockEnv, | ||
db: &mut CacheDB<ExecutionDB>, | ||
spec_id: revm::primitives::SpecId, | ||
) -> Result<ethereum_rust_vm::ExecutionResult, ethereum_rust_vm::EvmError> { | ||
// let chain_spec = db.get_chain_config()?; | ||
let mut evm = Revm::builder() | ||
.with_db(db) | ||
.with_block_env(block_env) | ||
.with_tx_env(tx_env) | ||
// If the chain_id is not correct, it throws: | ||
// Transaction(InvalidChainId) | ||
// TODO: do not hardcode the chain_id | ||
.modify_cfg_env(|cfg| cfg.chain_id = 1729) | ||
.with_spec_id(spec_id) | ||
.with_external_context(TracerEip3155::new(Box::new(std::io::stderr())).without_summary()) | ||
.build(); | ||
let RevmResultAndState { result, state: _ } = evm.transact().unwrap(); | ||
Ok(result.into()) | ||
Ok((block, execution_db, parent_header)) | ||
} | ||
*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters