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: integrate custom-evm example #2

Merged
merged 8 commits into from
Mar 6, 2024
Merged
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
7,970 changes: 7,920 additions & 50 deletions Cargo.lock

Large diffs are not rendered by default.

16 changes: 12 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[workspace]
members = ["bin/alphanet/"]
members = ["bin/alphanet/", "crates/node"]
default-members = ["bin/alphanet/"]
resolver = "2"

Expand Down Expand Up @@ -41,16 +41,24 @@ codegen-units = 1
incremental = false

[workspace.dependencies]
# tracing
tracing = "0.1.0"
# alphanet
alphanet-node = { path = "crates/node" }

# tokio
tokio = { version = "1.21", default-features = false }

# reth
reth = { git = "https://github.com/paradigmxyz/reth.git", rev = "96fcdfb", features = ["optimism"] }
reth-node-api = { git = "https://github.com/paradigmxyz/reth.git", rev = "96fcdfb" }
reth-node-optimism = { git = "https://github.com/paradigmxyz/reth.git", rev = "96fcdfb" }
reth-tracing = { git = "https://github.com/paradigmxyz/reth.git", rev = "96fcdfb" }

# revm
revm = { version = "6.1.0", features = ["std", "secp256k1"], default-features = false }
revm-inspectors = { git = "https://github.com/paradigmxyz/evm-inspectors", rev = "7068d39" }
revm-primitives = { version = "2.1.0", features = ["std"], default-features = false }
revm-inspectors = { git = "https://github.com/paradigmxyz/evm-inspectors", rev = "75a187b" }

# misc
clap = "4"
eyre = "0.6.12"
tracing = "0.1.0"
12 changes: 9 additions & 3 deletions bin/alphanet/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,23 @@ default-run = "alphanet"
workspace = true

[dependencies]
alphanet-node.workspace = true
eyre.workspace = true
tokio.workspace = true
tracing.workspace = true
reth.workspace = true
reth-node-optimism.workspace = true
reth-tracing.workspace = true

[target.'cfg(not(windows))'.dependencies]
tikv-jemallocator = { version = "0.5.0", optional = true }
jemallocator = { version = "0.5", optional = true }

[features]
default = ["jemalloc"]
asm-keccak = []

jemalloc = ["dep:tikv-jemallocator"]
jemalloc-prof = ["jemalloc", "tikv-jemallocator?/profiling"]
jemalloc = ["dep:jemallocator"]
jemalloc-prof = ["jemalloc", "jemallocator?/profiling"]

min-error-logs = ["tracing/release_max_level_error"]
min-warn-logs = ["tracing/release_max_level_warn"]
Expand Down
47 changes: 39 additions & 8 deletions bin/alphanet/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,49 @@
//! Reth AlphaNet is a testnet OP Stack rollup aimed at enabling experimentation of bleeding edge
//! Ethereum Research.

#![allow(missing_docs)]
use alphanet_node::node::AlphaNetNode;
use reth::{
args::RpcServerArgs,
builder::{NodeBuilder, NodeConfig},
primitives::{Chain, ChainSpec, Genesis},
tasks::TaskManager,
};
use reth_node_optimism::{args::RollupArgs, OptimismNode};
use reth_tracing::{RethTracer, Tracer};

// We use jemalloc for performance reasons.
#[cfg(all(feature = "jemalloc", unix))]
#[global_allocator]
static ALLOC: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc;
static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc;

fn main() {
tracing::info!("Hello, world!");
#[tokio::main]
async fn main() -> eyre::Result<()> {
let _guard = RethTracer::new().init()?;

// Enable backtraces unless a RUST_BACKTRACE value has already been explicitly provided.
if std::env::var_os("RUST_BACKTRACE").is_none() {
std::env::set_var("RUST_BACKTRACE", "1");
}
let tasks = TaskManager::current();

// create optimism genesis with canyon at block 2
let spec = ChainSpec::builder()
.chain(Chain::mainnet())
.genesis(Genesis::default())
.london_activated()
.paris_activated()
.shanghai_activated()
.cancun_activated()
.build();

let node_config =
NodeConfig::test().with_rpc(RpcServerArgs::default().with_http()).with_chain(spec);

let handle = NodeBuilder::new(node_config)
.testing_node(tasks.executor())
.with_types(AlphaNetNode::default())
.with_components(OptimismNode::components(RollupArgs::default()))
.launch()
.await
.unwrap();

tracing::info!("Node started");

handle.node_exit_future.await
}
18 changes: 18 additions & 0 deletions crates/node/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[package]
name = "alphanet-node"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
authors.workspace = true
license.workspace = true
repository.workspace = true
keywords.workspace = true
categories.workspace = true

[dependencies]
reth.workspace = true
reth-node-api.workspace = true
reth-node-optimism.workspace = true

[lints]
workspace = true
137 changes: 137 additions & 0 deletions crates/node/src/evm.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
use reth::{
primitives::{
address,
revm::{config::revm_spec, env::fill_op_tx_env},
revm_primitives::{AnalysisKind, CfgEnvWithHandlerCfg, Env, PrecompileResult, TxEnv},
Address, Bytes, ChainSpec, Head, Header, Transaction, U256,
},
revm::{
handler::register::EvmHandler,
precompile::{Precompile, PrecompileSpecId, Precompiles},
Database, Evm, EvmBuilder,
},
};
use reth_node_api::{ConfigureEvm, ConfigureEvmEnv};
use std::sync::Arc;

/// Custom EVM configuration
#[derive(Debug, Clone, Copy, Default)]
#[non_exhaustive]
pub struct AlphaNetEvmConfig;

impl AlphaNetEvmConfig {
/// 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 set_precompiles<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;

// install the precompiles
handler.pre_execution.load_precompiles = Arc::new(move || {
let mut precompiles = Precompiles::new(PrecompileSpecId::from_spec_id(spec_id)).clone();
precompiles.inner.insert(
address!("0000000000000000000000000000000000000999"),
Precompile::Env(Self::alphanet_precompile),
);
precompiles
});
}

/// A custom precompile that does nothing
fn alphanet_precompile(_data: &Bytes, _gas: u64, _env: &Env) -> PrecompileResult {
Ok((0, Bytes::new()))
}
}

impl ConfigureEvm for AlphaNetEvmConfig {
fn evm<'a, DB: Database + 'a>(&self, db: DB) -> Evm<'a, (), DB> {
EvmBuilder::default()
.with_db(db)
// add additional precompiles
.append_handler_register(Self::set_precompiles)
.build()
}

fn evm_with_inspector<'a, DB: Database + 'a, I>(&self, db: DB, inspector: I) -> Evm<'a, I, DB> {
EvmBuilder::default()
.with_db(db)
.with_external_context(inspector)
// add additional precompiles
.append_handler_register(Self::set_precompiles)
.build()
}
}

impl ConfigureEvmEnv for AlphaNetEvmConfig {
type TxMeta = Bytes;

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

fn fill_cfg_env(
cfg_env: &mut CfgEnvWithHandlerCfg,
chain_spec: &ChainSpec,
header: &Header,
total_difficulty: U256,
) {
let spec_id = revm_spec(
chain_spec,
Head {
number: header.number,
timestamp: header.timestamp,
difficulty: header.difficulty,
total_difficulty,
hash: Default::default(),
},
);

cfg_env.chain_id = chain_spec.chain().id();
cfg_env.perf_analyse_created_bytecodes = AnalysisKind::Analyse;

cfg_env.handler_cfg.spec_id = spec_id;
cfg_env.handler_cfg.is_optimism = chain_spec.is_optimism();
}
}

#[cfg(test)]
mod tests {
use super::*;
use reth::primitives::{
revm_primitives::{BlockEnv, CfgEnv, SpecId},
Chain, ChainSpecBuilder, ForkCondition, Genesis, Hardfork,
};

#[test]
fn test_fill_cfg_and_block_env() {
let mut cfg_env = CfgEnvWithHandlerCfg::new_with_spec_id(CfgEnv::default(), SpecId::LATEST);
let mut block_env = BlockEnv::default();
let header = Header::default();
let chain_spec = ChainSpecBuilder::default()
.chain(Chain::optimism_mainnet())
.genesis(Genesis::default())
.with_fork(Hardfork::Frontier, ForkCondition::Block(0))
.build();
let total_difficulty = U256::ZERO;

AlphaNetEvmConfig::fill_cfg_and_block_env(
&mut cfg_env,
&mut block_env,
&chain_spec,
&header,
total_difficulty,
);

assert_eq!(cfg_env.chain_id, chain_spec.chain().id());
}
}
8 changes: 8 additions & 0 deletions crates/node/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
//! Standalone crate for AlphaNet's node configuration and builder types.

#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]

/// Implementation of the ConfigureEvmEnv trait.
pub mod evm;
/// Node types config.
pub mod node;
19 changes: 19 additions & 0 deletions crates/node/src/node.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
use crate::evm::AlphaNetEvmConfig;
use reth::builder::NodeTypes;
use reth_node_optimism::OptimismEngineTypes;

/// Type configuration for a regular AlphaNet node.
#[derive(Debug, Clone, Default)]
#[non_exhaustive]
pub struct AlphaNetNode;

/// Configure the node types
impl NodeTypes for AlphaNetNode {
type Primitives = ();
type Engine = OptimismEngineTypes;
type Evm = AlphaNetEvmConfig;

fn evm_config(&self) -> Self::Evm {
Self::Evm::default()
}
}