From d60fcc9d834d8c8f03aad1d4598f75fa969d4e4f Mon Sep 17 00:00:00 2001 From: dapplion <35266934+dapplion@users.noreply.github.com> Date: Wed, 12 Jun 2024 01:36:23 +0200 Subject: [PATCH 1/2] Mint basefee gas to collector address --- Cargo.lock | 1 + Cargo.toml | 1 + src/evm_config.rs | 107 ++++++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 7 +-- 4 files changed, 113 insertions(+), 3 deletions(-) create mode 100644 src/evm_config.rs diff --git a/Cargo.lock b/Cargo.lock index d4d5ea8..1a1922f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6496,6 +6496,7 @@ dependencies = [ "reth-evm", "reth-evm-ethereum", "reth-node-ethereum", + "revm", "tikv-jemallocator", ] diff --git a/Cargo.toml b/Cargo.toml index 6a5302e..3c91cc7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,6 +22,7 @@ eyre = "0.6.12" clap = { version = "4.5.6", features = ["derive"] } alloy-sol-macro = "0.7.6" alloy-sol-types = "0.7.6" +revm = "9.0.0" [target.'cfg(unix)'.dependencies] tikv-jemallocator = { version = "0.5.0", optional = true } diff --git a/src/evm_config.rs b/src/evm_config.rs new file mode 100644 index 0000000..294dcba --- /dev/null +++ b/src/evm_config.rs @@ -0,0 +1,107 @@ +use reth::{ + primitives::{address, Address, ChainSpec, Header, TransactionSigned, U256}, + revm::{ + inspector_handle_register, + interpreter::Gas, + primitives::{spec_to_generic, CfgEnvWithHandlerCfg, EVMError, Spec, SpecId, TxEnv}, + Context, Database, Evm, EvmBuilder, GetInspector, + }, +}; +use reth_evm::{ConfigureEvm, ConfigureEvmEnv}; +use reth_evm_ethereum::EthEvmConfig; +use revm::handler::mainnet::reward_beneficiary as reward_beneficiary_mainnet; +use std::sync::Arc; + +// TODO: Define a per-network collector address configurable via genesis file +const COLLECTOR_ADDRESS: Address = address!("6BBe78ee9e474842Dbd4AB4987b3CeFE88426A92"); + +/// Reward beneficiary with gas fee. +#[inline] +pub fn reward_beneficiary( + context: &mut Context, + gas: &Gas, +) -> Result<(), EVMError> { + reward_beneficiary_mainnet::(context, gas)?; + if SPEC::enabled(SpecId::LONDON) { + mint_basefee_to_collector_address::(context, gas)?; + } + Ok(()) +} + +/// Mint basefee to eip1559 collector +#[inline] +pub fn mint_basefee_to_collector_address( + context: &mut Context, + gas: &Gas, +) -> Result<(), EVMError> { + // TODO: Define a per-network collector address configurable via genesis file + let base_fee = context.evm.env.block.basefee; + let gas_used = U256::from(gas.spent() - gas.refunded() as u64); + + let (collector_account, _) = context + .evm + .inner + .journaled_state + .load_account(COLLECTOR_ADDRESS, &mut context.evm.inner.db)?; + + collector_account.mark_touch(); + collector_account.info.balance = collector_account + .info + .balance + .saturating_add(base_fee * gas_used); + + Ok(()) +} + +/// Custom EVM configuration +#[derive(Debug, Clone, Copy, Default)] +pub struct GnosisEvmConfig; + +impl ConfigureEvm for GnosisEvmConfig { + type DefaultExternalContext<'a> = (); + + fn evm<'a, DB: Database + 'a>(&self, db: DB) -> Evm<'a, Self::DefaultExternalContext<'a>, DB> { + EvmBuilder::default() + .with_db(db) + .append_handler_register_box(Box::new(|h| { + spec_to_generic!(h.spec_id(), { + h.post_execution.reward_beneficiary = + Arc::new(reward_beneficiary::); + }); + })) + .build() + } + + fn evm_with_inspector<'a, DB, I>(&self, db: DB, inspector: I) -> Evm<'a, I, DB> + where + DB: Database + 'a, + I: GetInspector, + { + EvmBuilder::default() + .with_db(db) + .with_external_context(inspector) + .append_handler_register_box(Box::new(|h| { + spec_to_generic!(h.spec_id(), { + h.post_execution.reward_beneficiary = + Arc::new(reward_beneficiary::); + }); + })) + .append_handler_register(inspector_handle_register) + .build() + } +} + +impl ConfigureEvmEnv for GnosisEvmConfig { + fn fill_tx_env(tx_env: &mut TxEnv, transaction: &TransactionSigned, sender: Address) { + EthEvmConfig::fill_tx_env(tx_env, transaction, sender) + } + + 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); + } +} diff --git a/src/lib.rs b/src/lib.rs index 882ffdf..b68904a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,4 @@ +use evm_config::GnosisEvmConfig; use execute::GnosisExecutorProvider; use reth::{ api::NodeTypes, @@ -7,13 +8,13 @@ use reth::{ BuilderContext, Node, }, }; -use reth_evm_ethereum::EthEvmConfig; use reth_node_ethereum::{ node::{EthereumNetworkBuilder, EthereumPayloadBuilder, EthereumPoolBuilder}, EthEngineTypes, EthereumNode, }; mod ethereum; +mod evm_config; mod execute; mod gnosis; @@ -88,7 +89,7 @@ where Node: FullNodeTypes, { // Must implement ConfigureEvm; - type EVM = EthEvmConfig; + type EVM = GnosisEvmConfig; // Must implement BlockExecutorProvider; type Executor = GnosisExecutorProvider; @@ -97,7 +98,7 @@ where ctx: &BuilderContext, ) -> eyre::Result<(Self::EVM, Self::Executor)> { let chain_spec = ctx.chain_spec(); - let evm_config = EthEvmConfig::default(); + let evm_config = GnosisEvmConfig; let executor = GnosisExecutorProvider::new(chain_spec, evm_config); Ok((evm_config, executor)) From 84b7946c6d279228ffb6985910cc9243b8b56a01 Mon Sep 17 00:00:00 2001 From: dapplion <35266934+dapplion@users.noreply.github.com> Date: Wed, 12 Jun 2024 02:04:15 +0200 Subject: [PATCH 2/2] Add genesis param to customize collector address --- Cargo.lock | 1 + Cargo.toml | 1 + src/evm_config.rs | 33 +++++++++++++++++++-------------- src/lib.rs | 14 +++++++++++++- 4 files changed, 34 insertions(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1a1922f..a5caf16 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6497,6 +6497,7 @@ dependencies = [ "reth-evm-ethereum", "reth-node-ethereum", "revm", + "serde_json", "tikv-jemallocator", ] diff --git a/Cargo.toml b/Cargo.toml index 3c91cc7..d789b16 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,6 +23,7 @@ clap = { version = "4.5.6", features = ["derive"] } alloy-sol-macro = "0.7.6" alloy-sol-types = "0.7.6" revm = "9.0.0" +serde_json = "1.0.117" [target.'cfg(unix)'.dependencies] tikv-jemallocator = { version = "0.5.0", optional = true } diff --git a/src/evm_config.rs b/src/evm_config.rs index 294dcba..4174c0f 100644 --- a/src/evm_config.rs +++ b/src/evm_config.rs @@ -1,5 +1,5 @@ use reth::{ - primitives::{address, Address, ChainSpec, Header, TransactionSigned, U256}, + primitives::{Address, ChainSpec, Header, TransactionSigned, U256}, revm::{ inspector_handle_register, interpreter::Gas, @@ -12,18 +12,16 @@ use reth_evm_ethereum::EthEvmConfig; use revm::handler::mainnet::reward_beneficiary as reward_beneficiary_mainnet; use std::sync::Arc; -// TODO: Define a per-network collector address configurable via genesis file -const COLLECTOR_ADDRESS: Address = address!("6BBe78ee9e474842Dbd4AB4987b3CeFE88426A92"); - /// Reward beneficiary with gas fee. #[inline] pub fn reward_beneficiary( context: &mut Context, gas: &Gas, + collector_address: Address, ) -> Result<(), EVMError> { reward_beneficiary_mainnet::(context, gas)?; if SPEC::enabled(SpecId::LONDON) { - mint_basefee_to_collector_address::(context, gas)?; + mint_basefee_to_collector_address::(context, gas, collector_address)?; } Ok(()) } @@ -33,6 +31,7 @@ pub fn reward_beneficiary( pub fn mint_basefee_to_collector_address( context: &mut Context, gas: &Gas, + collector_address: Address, ) -> Result<(), EVMError> { // TODO: Define a per-network collector address configurable via genesis file let base_fee = context.evm.env.block.basefee; @@ -42,7 +41,7 @@ pub fn mint_basefee_to_collector_address( .evm .inner .journaled_state - .load_account(COLLECTOR_ADDRESS, &mut context.evm.inner.db)?; + .load_account(collector_address, &mut context.evm.inner.db)?; collector_account.mark_touch(); collector_account.info.balance = collector_account @@ -54,19 +53,23 @@ pub fn mint_basefee_to_collector_address( } /// Custom EVM configuration -#[derive(Debug, Clone, Copy, Default)] -pub struct GnosisEvmConfig; +#[derive(Debug, Clone, Copy)] +pub struct GnosisEvmConfig { + pub collector_address: Address, +} impl ConfigureEvm for GnosisEvmConfig { type DefaultExternalContext<'a> = (); fn evm<'a, DB: Database + 'a>(&self, db: DB) -> Evm<'a, Self::DefaultExternalContext<'a>, DB> { + let collector_address = self.collector_address; EvmBuilder::default() .with_db(db) - .append_handler_register_box(Box::new(|h| { + .append_handler_register_box(Box::new(move |h| { spec_to_generic!(h.spec_id(), { - h.post_execution.reward_beneficiary = - Arc::new(reward_beneficiary::); + h.post_execution.reward_beneficiary = Arc::new(move |context, gas| { + reward_beneficiary::(context, gas, collector_address) + }); }); })) .build() @@ -77,13 +80,15 @@ impl ConfigureEvm for GnosisEvmConfig { DB: Database + 'a, I: GetInspector, { + let collector_address = self.collector_address; EvmBuilder::default() .with_db(db) .with_external_context(inspector) - .append_handler_register_box(Box::new(|h| { + .append_handler_register_box(Box::new(move |h| { spec_to_generic!(h.spec_id(), { - h.post_execution.reward_beneficiary = - Arc::new(reward_beneficiary::); + h.post_execution.reward_beneficiary = Arc::new(move |context, gas| { + reward_beneficiary::(context, gas, collector_address) + }); }); })) .append_handler_register(inspector_handle_register) diff --git a/src/lib.rs b/src/lib.rs index b68904a..f13c2eb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,6 @@ use evm_config::GnosisEvmConfig; use execute::GnosisExecutorProvider; +use eyre::eyre; use reth::{ api::NodeTypes, builder::{ @@ -98,7 +99,18 @@ where ctx: &BuilderContext, ) -> eyre::Result<(Self::EVM, Self::Executor)> { let chain_spec = ctx.chain_spec(); - let evm_config = GnosisEvmConfig; + let collector_address = ctx + .config() + .chain + .genesis() + .config + .extra_fields + .get("eip1559collector") + .ok_or(eyre!("no eip1559collector field"))?; + + let evm_config = GnosisEvmConfig { + collector_address: serde_json::from_value(collector_address.clone())?, + }; let executor = GnosisExecutorProvider::new(chain_spec, evm_config); Ok((evm_config, executor))