Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: custom evm #18

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion src/config/env.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
//! This module contains the environment variables for the EigenZeth service

use once_cell::sync::Lazy;
use std::string::ToString;

/// EigenZethEnv is a struct that holds the environment variables
pub struct GlobalEnv {
Expand Down
171 changes: 162 additions & 9 deletions src/custom_reth/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ use reth_node_builder::{
node::NodeTypes,
BuilderContext, FullNodeTypes, Node, NodeBuilder, PayloadBuilderConfig,
};
use reth_primitives::revm_primitives::{BlockEnv, CfgEnvWithHandlerCfg};
use reth_primitives::{Address, ChainSpec, Header, Withdrawals, B256};

use reth_primitives::revm_primitives::{BlockEnv, CfgEnvWithHandlerCfg, TxEnv};
use reth_primitives::{address, Address, ChainSpec, Header, Transaction, Withdrawals, B256, U256};
use revm_primitives::{CancunSpec, StorageSlot};
use std::sync::Arc;

use reth_basic_payload_builder::{
Expand All @@ -14,8 +16,9 @@ use reth_basic_payload_builder::{
};
use reth_db::init_db;
use reth_node_api::{
validate_version_specific_fields, AttributesValidationError, EngineApiMessageVersion,
EngineTypes, PayloadAttributes, PayloadBuilderAttributes, PayloadOrAttributes,
validate_version_specific_fields, AttributesValidationError, ConfigureEvm, ConfigureEvmEnv,
EngineApiMessageVersion, EngineTypes, PayloadAttributes, PayloadBuilderAttributes,
PayloadOrAttributes,
};
use reth_provider::{
providers::{BlockchainProvider, ProviderFactory},
Expand Down Expand Up @@ -57,7 +60,11 @@ use reth_interfaces::consensus::Consensus;
use reth_node_core::args::{DevArgs, RpcServerArgs};
use reth_node_core::dirs::{DataDirPath, MaybePlatformPath};
use reth_node_core::node_config::NodeConfig;
use reth_revm::EvmProcessorFactory;
use reth_revm::{
handler::{mainnet, register::EvmHandler},
Context, Database, Evm, EvmBuilder, EvmProcessorFactory, JournalEntry,
};
use revm_primitives::SHANGHAI;

pub(crate) mod eigen;

Expand Down Expand Up @@ -184,6 +191,152 @@ impl EngineTypes for CustomEngineTypes {
}
}

/// Custom EVM configuration: Read the L1 EMT root, and set it up when creating EVM.
/// Take set_precompiles for instance, we should change [ConfigureEvm::evm] and
/// [ConfigureEvm::evm_with_inspector]. TODO
#[derive(Debug, Clone, Copy, Default)]
#[non_exhaustive]
pub struct MyEvmConfig;

impl MyEvmConfig {
/// Sets the precompiles to the EVM handler
///
/// This will be invoked when the EVM is created via [ConfigureEvm::evm] or
/// [ConfigureEvm::evm_with_inspector]
///
/// This will use the default mainnet precompiles and add additional precompiles.
pub fn sync_emt_root_from_l1<EXT, DB>(handler: &mut EvmHandler<EXT, DB>)
where
DB: Database,
{
// first we need the evm spec id, which determines the precompiles
let spec_id = handler.cfg.spec_id;
handler.pre_execution.load_accounts = Arc::new(move |ctx: &mut Context<EXT, DB>| {
//let new_accounts = mainnet::load_accounts::<CancunSpec, EXT, DB>(ctx);

// set journaling state flag.
ctx.evm.journaled_state.set_spec_id(spec_id);

// load coinbase
// EIP-3651: Warm COINBASE. Starts the `COINBASE` address warm
if spec_id == SHANGHAI {
ctx.evm.inner.journaled_state.initial_account_load(
ctx.evm.inner.env.block.coinbase,
&[],
&mut ctx.evm.inner.db,
)?;
}
let contract_address = std::env::var("L1_EMT_ADDRESS")
.unwrap_or("7a70eAF4822217A65F5cAF35e8b0d9b319Df9Ad0".to_string());
let contract_address = Address::parse_checksummed(contract_address.as_str(), None)
.expect("Invalid contract address");
let slot_id = U256::from(0);
{
let _ = ctx.evm.load_account_exist(contract_address);

let storage = match ctx.evm.sload(contract_address, slot_id) {
Ok(x) => x.0,
Err(_e) => todo!(), // FIXME: print the error
};
println!("storage: {:?}", storage);

let sstore_res = match ctx.evm.sstore(contract_address, slot_id, U256::from(1000)) {
Ok(x) => x,
Err(_e) => todo!(),
};
println!("sstore res: {:?}", sstore_res);

let storage = match ctx.evm.sload(contract_address, slot_id) {
Ok(x) => x.0,
Err(_e) => todo!(), // FIXME: print the error
};
println!("storage after sstore: {:?}", storage);

let curr_acc = match ctx.evm.load_account(contract_address) {
Ok(x) => x.0,
Err(_e) => todo!(), // FIXME: print the error
};

println!("curr_acc: {:?}", curr_acc);
let default_storage_slot = StorageSlot {
present_value: U256::from(0),
previous_or_original_value: U256::from(0),
};

let previous_root = match curr_acc.storage.get(&slot_id) {
Some(value) => value,
None => &default_storage_slot,
};
let present_root = U256::from(1212);
curr_acc.storage.insert(
slot_id,
StorageSlot {
previous_or_original_value: previous_root.present_value(),
present_value: present_root,
},
);
println!("curr_acc after insert: {:?}", curr_acc);
// ctx.evm.journaled_state.journal.last_mut().unwrap().push(
// JournalEntry::StorageChange {
// address: contract_address,
// key: slot_id,
// had_value: Some(present_root),
// },
// );
}

let storage = match ctx.evm.db.storage(contract_address, slot_id) {
Ok(x) => x,
Err(_e) => todo!(), // FIXME: print the error
};
println!("storage in db: {:?}", storage);
ctx.evm.load_access_list()?;
Ok(())
});
}
}

impl ConfigureEvmEnv for MyEvmConfig {
type TxMeta = ();

fn fill_tx_env<T>(tx_env: &mut TxEnv, transaction: T, sender: Address, meta: Self::TxMeta)
where
T: AsRef<Transaction>,
{
EthEvmConfig::fill_tx_env(tx_env, transaction, sender, meta)
}

fn fill_cfg_env(
cfg_env: &mut CfgEnvWithHandlerCfg,
chain_spec: &ChainSpec,
header: &Header,
total_difficulty: U256,
) {
EthEvmConfig::fill_cfg_env(cfg_env, chain_spec, header, total_difficulty)
}
}

impl ConfigureEvm for MyEvmConfig {
fn evm<'a, DB: Database + 'a>(&self, db: DB) -> Evm<'a, (), DB> {
EvmBuilder::default()
.with_db(db)
// add additional precompiles
.append_handler_register(MyEvmConfig::sync_emt_root_from_l1)
.build()
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Call the transact here too.

}

fn evm_with_inspector<'a, DB: Database + 'a, I>(&self, db: DB, inspector: I) -> Evm<'a, I, DB> {
let mut evm = EvmBuilder::default()
.with_db(db)
.with_external_context(inspector)
// add additional precompiles
.append_handler_register(MyEvmConfig::sync_emt_root_from_l1)
.build();
let _ = evm.transact();
evm
}
}

#[derive(Debug, Clone, Default)]
#[non_exhaustive]
struct MyCustomNode;
Expand All @@ -194,7 +347,7 @@ impl NodeTypes for MyCustomNode {
// use the custom engine types
type Engine = CustomEngineTypes;
// use the default ethereum EVM config
type Evm = EthEvmConfig;
type Evm = MyEvmConfig;

fn evm_config(&self) -> Self::Evm {
Self::Evm::default()
Expand Down Expand Up @@ -373,13 +526,13 @@ pub async fn launch_custom_node(

let consensus: Arc<dyn Consensus> = Arc::new(BeaconConsensus::new(Arc::clone(&spec)));

let evm_config = EthEvmConfig::default();
let custom_node = MyCustomNode::default();

// Configure blockchain tree
let tree_externals = TreeExternals::new(
factory.clone(),
Arc::clone(&consensus),
EvmProcessorFactory::new(spec.clone(), evm_config),
EvmProcessorFactory::new(spec.clone(), custom_node.evm_config()),
);

let tree = BlockchainTree::new(tree_externals, BlockchainTreeConfig::default(), None)?;
Expand All @@ -390,7 +543,7 @@ pub async fn launch_custom_node(
let handle = NodeBuilder::new(node_config)
.with_database(database)
.with_launch_context(tasks.executor(), data_dir)
.node(MyCustomNode::default())
.node(custom_node)
.extend_rpc_modules(move |ctx| {
// create EigenRpcExt Instance
let custom_rpc = EigenRpcExt {
Expand Down
Loading