Skip to content
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
41 changes: 41 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: Build

on:
push:
branches: [main]
pull_request:
branches: [main]

env:
CARGO_TERM_COLOR: always
RUSTFLAGS: -D warnings

jobs:
build:
name: Build
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt, clippy

- name: Cache cargo registry
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-build-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-build-

- name: Build debug
run: cargo build --all --verbose

- name: Build release
run: cargo build --all --release --verbose
53 changes: 53 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
name: Lint

on:
push:
branches: [main]
pull_request:
branches: [main]

env:
CARGO_TERM_COLOR: always

jobs:
fmt:
name: Rustfmt
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt

- name: Check formatting
run: cargo fmt --all -- --check

clippy:
name: Clippy
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
components: clippy

- name: Cache cargo registry
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-clippy-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-clippy-

- name: Run Clippy
run: cargo clippy --all --all-targets -- -D warnings

60 changes: 60 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
name: Test

on:
push:
branches: [main]
pull_request:
branches: [main]

env:
CARGO_TERM_COLOR: always

jobs:
test:
name: Run Tests
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable

- name: Cache cargo registry
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-test-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-test-

- name: Run tests
run: cargo test --all --verbose

doc-test:
name: Doc Tests
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable

- name: Cache cargo registry
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-doc-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-doc-

- name: Run doc tests
run: cargo test --doc --all --verbose

3 changes: 3 additions & 0 deletions crates/chainspec/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
#![cfg_attr(not(test), warn(unused_crate_dependencies))]
#![cfg_attr(docsrs, feature(doc_cfg))]

// Used only in tests, but declared here to silence unused_crate_dependencies warning
use serde_json as _;

pub mod hardfork;
pub mod spec;
pub use spec::MorphChainSpec;
52 changes: 32 additions & 20 deletions crates/chainspec/src/spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,7 @@ pub const SUPPORTED_CHAINS: &[&str] = &["testnet"];
/// to a json file, or a json formatted string in-memory. The json needs to be a Genesis struct.
#[cfg(feature = "cli")]
pub fn chain_value_parser(s: &str) -> eyre::Result<Arc<MorphChainSpec>> {
Ok(match s {
_ => MorphChainSpec::from_genesis(reth_cli::chainspec::parse_genesis(s)?).into(),
})
Ok(MorphChainSpec::from_genesis(reth_cli::chainspec::parse_genesis(s)?).into())
}

#[cfg(feature = "cli")]
Expand Down Expand Up @@ -238,34 +236,49 @@ impl MorphHardforks for MorphChainSpec {
mod tests {
use crate::hardfork::{MorphHardfork, MorphHardforks};
use reth_chainspec::{EthereumHardfork, ForkCondition, Hardforks};
use reth_cli::chainspec::ChainSpecParser as _;
use serde_json::json;

#[test]
fn can_load_testnet() {
let _ = super::MorphChainSpecParser::parse("testnet")
.expect("the testnet chainspec must always be well formed");
}

#[test]
fn can_load_dev() {
let _ = super::MorphChainSpecParser::parse("dev")
.expect("the dev chainspec must always be well formed");
/// Helper function to create a test genesis with Morph hardforks at timestamp 0
fn create_test_genesis() -> alloy_genesis::Genesis {
let genesis_json = json!({
"config": {
"chainId": 1337,
"homesteadBlock": 0,
"eip150Block": 0,
"eip155Block": 0,
"eip158Block": 0,
"byzantiumBlock": 0,
"constantinopleBlock": 0,
"petersburgBlock": 0,
"istanbulBlock": 0,
"berlinBlock": 0,
"londonBlock": 0,
"mergeNetsplitBlock": 0,
"terminalTotalDifficulty": 0,
"terminalTotalDifficultyPassed": true,
"shanghaiTime": 0,
"cancunTime": 0,
"bernoulliTime": 0,
"curieTime": 0,
"morph203Time": 0,
"viridianTime": 0
},
"alloc": {}
});
serde_json::from_value(genesis_json).expect("genesis should be valid")
}

#[test]
fn test_morph_chainspec_has_morph_hardforks() {
let chainspec = super::MorphChainSpecParser::parse("testnet")
.expect("the testnet chainspec must always be well formed");
let chainspec = super::MorphChainSpec::from_genesis(create_test_genesis());

// Bernoulli should be active at genesis (timestamp 0)
assert!(chainspec.is_bernoulli_active_at_timestamp(0));
}

#[test]
fn test_morph_chainspec_implements_morph_hardforks_trait() {
let chainspec = super::MorphChainSpecParser::parse("testnet")
.expect("the testnet chainspec must always be well formed");
let chainspec = super::MorphChainSpec::from_genesis(create_test_genesis());

// Should be able to query Morph hardfork activation through trait
let activation = chainspec.morph_fork_activation(MorphHardfork::Bernoulli);
Expand All @@ -278,8 +291,7 @@ mod tests {

#[test]
fn test_morph_hardforks_in_inner_hardforks() {
let chainspec = super::MorphChainSpecParser::parse("testnet")
.expect("the testnet chainspec must always be well formed");
let chainspec = super::MorphChainSpec::from_genesis(create_test_genesis());

// Morph hardforks should be queryable from inner.hardforks via Hardforks trait
let activation = chainspec.fork(MorphHardfork::Bernoulli);
Expand Down
2 changes: 2 additions & 0 deletions crates/evm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ thiserror.workspace = true

[dev-dependencies]
revm.workspace = true
serde_json.workspace = true
alloy-genesis.workspace = true

[features]
default = ["rpc"]
Expand Down
21 changes: 18 additions & 3 deletions crates/evm/src/evm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -207,15 +207,30 @@ where

#[cfg(test)]
mod tests {
use alloy_primitives::U256;
use reth_revm::context::BlockEnv;
use revm::{context::TxEnv, database::EmptyDB};
use revm::{
context::TxEnv,
database::{CacheDB, EmptyDB},
state::AccountInfo,
};

use super::*;

#[test]
fn can_execute_tx() {
// Create a database with the caller having sufficient balance
let mut db = CacheDB::new(EmptyDB::default());
db.insert_account_info(
Address::ZERO,
AccountInfo {
balance: U256::from(1_000_000),
..Default::default()
},
);

let mut evm = MorphEvm::new(
EmptyDB::default(),
db,
EvmEnv {
block_env: MorphBlockEnv {
inner: BlockEnv {
Expand All @@ -230,7 +245,7 @@ mod tests {
.transact(MorphTxEnv {
inner: TxEnv {
caller: Address::ZERO,
gas_price: 0,
gas_price: 1, // Must be >= basefee
gas_limit: 21000,
..Default::default()
},
Expand Down
35 changes: 33 additions & 2 deletions crates/evm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
#![cfg_attr(not(test), warn(unused_crate_dependencies))]
#![cfg_attr(docsrs, feature(doc_cfg))]

mod assemble;
#[cfg(feature = "engine")]
mod engine;
mod assemble;
use alloy_consensus::BlockHeader as _;
pub use assemble::MorphBlockAssembler;
mod block;
Expand Down Expand Up @@ -193,12 +193,43 @@ impl ConfigureEvm for MorphEvmConfig {
mod tests {
use super::*;
use morph_chainspec::hardfork::{MorphHardfork, MorphHardforks};
use serde_json::json;

/// Helper function to create a test genesis with Morph hardforks at timestamp 0
fn create_test_genesis() -> alloy_genesis::Genesis {
let genesis_json = json!({
"config": {
"chainId": 1337,
"homesteadBlock": 0,
"eip150Block": 0,
"eip155Block": 0,
"eip158Block": 0,
"byzantiumBlock": 0,
"constantinopleBlock": 0,
"petersburgBlock": 0,
"istanbulBlock": 0,
"berlinBlock": 0,
"londonBlock": 0,
"mergeNetsplitBlock": 0,
"terminalTotalDifficulty": 0,
"terminalTotalDifficultyPassed": true,
"shanghaiTime": 0,
"cancunTime": 0,
"bernoulliTime": 0,
"curieTime": 0,
"morph203Time": 0,
"viridianTime": 0
},
"alloc": {}
});
serde_json::from_value(genesis_json).expect("genesis should be valid")
}

#[test]
fn test_evm_config_can_query_morph_hardforks() {
// Create a test chainspec with Bernoulli at genesis
let chainspec = Arc::new(morph_chainspec::MorphChainSpec::from_genesis(
Default::default(),
create_test_genesis(),
));

let evm_config = MorphEvmConfig::new_with_default_factory(chainspec);
Expand Down
5 changes: 2 additions & 3 deletions crates/primitives/src/transaction/alt_fee.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@ pub struct TxAltFee {
/// accessing outside the list.
pub access_list: AccessList,


/// Maximum amount of tokens the sender is willing to pay as fee.
pub fee_limit: U256,

Expand Down Expand Up @@ -309,7 +308,7 @@ impl RlpEcdsaEncodableTx for TxAltFee {
}

impl RlpEcdsaDecodableTx for TxAltFee {
const DEFAULT_TX_TYPE: u8 = { Self::tx_type() as u8 };
const DEFAULT_TX_TYPE: u8 = { Self::tx_type() };

/// Decodes the inner [TxEip1559] fields from RLP bytes.
fn rlp_decode_fields(buf: &mut &[u8]) -> alloy_rlp::Result<Self> {
Expand All @@ -323,7 +322,7 @@ impl SignableTransaction<Signature> for TxAltFee {
}

fn encode_for_signing(&self, out: &mut dyn alloy_rlp::BufMut) {
out.put_u8(Self::tx_type() as u8);
out.put_u8(Self::tx_type());
self.encode(out)
}

Expand Down
1 change: 0 additions & 1 deletion crates/primitives/src/transaction/envelope.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ use crate::{TxAltFee, TxL1Msg};

#[derive(Debug, Clone, TransactionEnvelope)]
#[envelope(tx_type_name = MorphTxType)]
#[expect(clippy::large_enum_variant)]
pub enum MorphTxEnvelope {
/// Legacy transaction (type 0x00)
#[envelope(ty = 0)]
Expand Down
Loading