Skip to content

Commit 67d3f6e

Browse files
authored
feat(crate): no-std support (#60)
* feat(crate): no-std support This adds a std feature (enabled by default), and adds support for a no-std environment. The most notable changes are: - `OnceLock` has been replaced for `OnceCell` on `BlockOutput`. We lose thread safety by doing this, but the EVM, and trevm by extension, has been designed to work on a single-thread context, so this is OK for now (and easily encapsulable with message passing if concurrency was indeed needed e.g for a fuzzer). - The 3155 tracer test util was std-gated. This is OK, as the 3155 tracer requires std anywhere. * chore: misc fixes and missing alloc/core imports * chore(errors): manually implement errors instead of using thiserror * feat: no-default features check on trevm * chore: remove comments * feat: implement ERror for JournalDecodeError * chore: rebase * fixes
1 parent 28cb36d commit 67d3f6e

File tree

16 files changed

+172
-56
lines changed

16 files changed

+172
-56
lines changed

.github/workflows/rust-ci.yml

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,20 @@ env:
1111

1212
jobs:
1313
rust-base:
14-
uses: init4tech/actions/.github/workflows/rust-base.yml@main
14+
uses: init4tech/actions/.github/workflows/rust-base.yml@main
15+
16+
test-no-features:
17+
name: Test Suite (no default features)
18+
runs-on:
19+
group: init4-runners
20+
steps:
21+
- name: Checkout repository
22+
uses: actions/checkout@v4
23+
- name: Install Rust toolchain
24+
uses: dtolnay/rust-toolchain@stable
25+
- uses: Swatinem/rust-cache@v2
26+
- name: Run tests
27+
env:
28+
CARGO_NET_GIT_FETCH_WITH_CLI: true
29+
run: |
30+
cargo test --no-default-features

Cargo.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,6 @@ revm = { version = "16.0.0", default-features = false, features = ["std"] }
3838

3939
zenith-types = "0.10"
4040

41-
thiserror = "1.0"
42-
4341
# TODO: remove this later
4442
# https://github.com/serde-rs/serde/issues/2844
4543
serde = { version = "=1.0.210"}
@@ -64,13 +62,16 @@ eyre = "0.6"
6462

6563
[features]
6664
default = [
65+
"std",
6766
"revm/std",
6867
"revm/c-kzg",
6968
"revm/blst",
7069
"revm/portable",
7170
"revm/secp256k1",
7271
]
7372

73+
std = ["revm/std", "alloy/std", "alloy-rlp/std", "alloy-primitives/std", "alloy-sol-types/std"]
74+
7475
test-utils = ["revm/test-utils", "revm/std", "revm/serde-json", "revm/alloydb"]
7576

7677

src/driver/alloy.rs

Lines changed: 49 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use crate::{
22
trevm_bail, trevm_ensure, unwrap_or_trevm_err, Block, BundleDriver, DriveBundleResult,
33
};
4+
use alloc::vec::Vec;
45
use alloy::{
56
consensus::{Transaction, TxEip4844Variant, TxEnvelope},
67
eips::{eip2718::Decodable2718, BlockNumberOrTag},
@@ -11,51 +12,82 @@ use alloy::{
1112
};
1213
use alloy_primitives::{bytes::Buf, keccak256, Address, Bytes, TxKind, U256};
1314
use revm::primitives::{EVMError, ExecutionResult, MAX_BLOB_GAS_PER_BLOCK};
14-
use thiserror::Error;
1515

1616
/// Possible errors that can occur while driving a bundle.
17-
#[derive(Error)]
1817
pub enum BundleError<Db: revm::Database> {
1918
/// The block number of the bundle does not match the block number of the revm block configuration.
20-
#[error("revm block number must match the bundle block number")]
2119
BlockNumberMismatch,
2220
/// The timestamp of the bundle is out of range.
23-
#[error("timestamp out of range")]
2421
TimestampOutOfRange,
2522
/// The bundle was reverted (or halted).
26-
#[error("bundle reverted")]
2723
BundleReverted,
2824
/// The bundle has no transactions
29-
#[error("bundle has no transactions")]
3025
BundleEmpty,
3126
/// Too many blob transactions
32-
#[error("max blob gas limit exceeded")]
3327
Eip4844BlobGasExceeded,
3428
/// An unsupported transaction type was encountered.
35-
#[error("unsupported transaction type")]
3629
UnsupportedTransactionType,
3730
/// An error occurred while decoding a transaction contained in the bundle.
38-
#[error("transaction decoding error")]
39-
TransactionDecodingError(#[from] alloy::eips::eip2718::Eip2718Error),
40-
/// An error ocurred while recovering the sender of a transaction
41-
#[error("transaction sender recovery error")]
42-
TransactionSenderRecoveryError(#[from] alloy_primitives::SignatureError),
31+
TransactionDecodingError(alloy::eips::eip2718::Eip2718Error),
32+
/// An error occurred while recovering the sender of a transaction.
33+
TransactionSenderRecoveryError(alloy_primitives::SignatureError),
4334
/// An error occurred while running the EVM.
44-
#[error("internal EVM Error")]
4535
EVMError {
4636
/// The error that occurred while running the EVM.
4737
inner: EVMError<Db::Error>,
4838
},
4939
}
5040

41+
impl<Db: revm::Database> core::fmt::Display for BundleError<Db> {
42+
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
43+
match self {
44+
Self::BlockNumberMismatch => {
45+
write!(f, "revm block number must match the bundle block number")
46+
}
47+
Self::TimestampOutOfRange => write!(f, "timestamp out of range"),
48+
Self::BundleReverted => write!(f, "bundle reverted"),
49+
Self::BundleEmpty => write!(f, "bundle has no transactions"),
50+
Self::Eip4844BlobGasExceeded => write!(f, "max blob gas limit exceeded"),
51+
Self::UnsupportedTransactionType => write!(f, "unsupported transaction type"),
52+
Self::TransactionDecodingError(_) => write!(f, "transaction decoding error"),
53+
Self::TransactionSenderRecoveryError(_) => {
54+
write!(f, "transaction sender recovery error")
55+
}
56+
Self::EVMError { inner: _ } => write!(f, "internal EVM Error"),
57+
}
58+
}
59+
}
60+
61+
impl<Db: revm::Database> From<alloy::eips::eip2718::Eip2718Error> for BundleError<Db> {
62+
fn from(err: alloy::eips::eip2718::Eip2718Error) -> Self {
63+
Self::TransactionDecodingError(err)
64+
}
65+
}
66+
67+
impl<Db: revm::Database> From<alloy_primitives::SignatureError> for BundleError<Db> {
68+
fn from(err: alloy_primitives::SignatureError) -> Self {
69+
Self::TransactionSenderRecoveryError(err)
70+
}
71+
}
72+
5173
impl<Db: revm::Database> From<EVMError<Db::Error>> for BundleError<Db> {
5274
fn from(inner: EVMError<Db::Error>) -> Self {
5375
Self::EVMError { inner }
5476
}
5577
}
5678

57-
impl<Db: revm::Database> std::fmt::Debug for BundleError<Db> {
58-
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
79+
impl<Db: revm::Database> core::error::Error for BundleError<Db> {
80+
fn source(&self) -> Option<&(dyn core::error::Error + 'static)> {
81+
match self {
82+
Self::TransactionDecodingError(err) => Some(err),
83+
Self::TransactionSenderRecoveryError(err) => Some(err),
84+
_ => None,
85+
}
86+
}
87+
}
88+
89+
impl<Db: revm::Database> core::fmt::Debug for BundleError<Db> {
90+
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
5991
match self {
6092
Self::TimestampOutOfRange => write!(f, "TimestampOutOfRange"),
6193
Self::BlockNumberMismatch => write!(f, "BlockNumberMismatch"),
@@ -94,7 +126,7 @@ where
94126
/// Clear the driver, resetting the response. This resets the driver,
95127
/// allowing for resimulation of the same bundle.
96128
pub fn clear(&mut self) -> R {
97-
std::mem::take(&mut self.response)
129+
core::mem::take(&mut self.response)
98130
}
99131
}
100132

src/driver/block.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ pub trait BlockDriver<Ext> {
1717
type Block: Block;
1818

1919
/// An error type for this driver.
20-
type Error<Db: Database>: std::error::Error + From<EVMError<Db::Error>>;
20+
type Error<Db: Database>: core::error::Error + From<EVMError<Db::Error>>;
2121

2222
/// Get a reference to the block filler for this driver.
2323
fn block(&self) -> &Self::Block;

src/driver/bundle.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ pub type DriveBundleResult<'a, Ext, Db, T> =
99
/// entire lifecycle of a bundle, simulating the entire list of transactions.
1010
pub trait BundleDriver<Ext> {
1111
/// An error type for this driver.
12-
type Error<Db: Database>: std::error::Error + From<EVMError<Db::Error>>;
12+
type Error<Db: Database>: core::error::Error + From<EVMError<Db::Error>>;
1313

1414
/// Run the transactions contained in the bundle.
1515
fn run_bundle<'a, Db: Database + DatabaseCommit>(

src/driver/chain.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ pub trait ChainDriver<Ext> {
1414
type BlockDriver: BlockDriver<Ext>;
1515

1616
/// An error type for this driver.
17-
type Error<Db: Database>: std::error::Error
17+
type Error<Db: Database>: core::error::Error
1818
+ From<EVMError<Db::Error>>
1919
+ From<<Self::BlockDriver as BlockDriver<Ext>>::Error<Db>>;
2020

src/evm.rs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ use crate::{
44
EvmNeedsCfg, EvmNeedsTx, EvmReady, EvmTransacted, HasBlock, HasCfg, HasTx, NeedsCfg, NeedsTx,
55
TransactedState, Tx,
66
};
7+
use alloc::{boxed::Box, fmt};
78
use alloy_primitives::{Address, Bytes, U256};
9+
use core::convert::Infallible;
810
use revm::{
911
db::{states::bundle_state::BundleRetention, BundleState, State},
1012
primitives::{
@@ -13,7 +15,6 @@ use revm::{
1315
},
1416
Database, DatabaseCommit, DatabaseRef, Evm,
1517
};
16-
use std::{convert::Infallible, fmt};
1718

1819
/// Trevm provides a type-safe interface to the EVM, using the typestate pattern.
1920
///
@@ -459,7 +460,7 @@ impl<'a, Ext, Db: Database + DatabaseCommit> EvmNeedsCfg<'a, Ext, Db> {
459460
pub fn fill_cfg<T: Cfg>(mut self, filler: &T) -> EvmNeedsBlock<'a, Ext, Db> {
460461
filler.fill_cfg(&mut self.inner);
461462
// SAFETY: Same size and repr. Only phantomdata type changes
462-
unsafe { std::mem::transmute(self) }
463+
unsafe { core::mem::transmute(self) }
463464
}
464465
}
465466

@@ -567,7 +568,7 @@ impl<'a, Ext, Db: Database + DatabaseCommit, TrevmState: HasCfg> Trevm<'a, Ext,
567568
settings: revm::primitives::EnvKzgSettings,
568569
) -> revm::primitives::EnvKzgSettings {
569570
let cfg = self.inner.cfg_mut();
570-
std::mem::replace(&mut cfg.kzg_settings, settings)
571+
core::mem::replace(&mut cfg.kzg_settings, settings)
571572
}
572573

573574
/// Set a limit beyond which a callframe's memory cannot be resized.
@@ -582,7 +583,7 @@ impl<'a, Ext, Db: Database + DatabaseCommit, TrevmState: HasCfg> Trevm<'a, Ext,
582583
#[cfg(feature = "memory_limit")]
583584
pub fn set_memory_limit(&mut self, new_limit: u64) -> u64 {
584585
let cfg = self.inner.cfg_mut();
585-
std::mem::replace(&mut cfg.memory_limit, new_limit)
586+
core::mem::replace(&mut cfg.memory_limit, new_limit)
586587
}
587588

588589
/// Disable balance checks. If the sender does not have enough balance to
@@ -833,7 +834,7 @@ impl<'a, Ext, Db: Database + DatabaseCommit> EvmNeedsBlock<'a, Ext, Db> {
833834
pub fn fill_block<B: Block>(mut self, filler: &B) -> EvmNeedsTx<'a, Ext, Db> {
834835
filler.fill_block(self.inner_mut_unchecked());
835836
// SAFETY: Same size and repr. Only phantomdata type changes
836-
unsafe { std::mem::transmute(self) }
837+
unsafe { core::mem::transmute(self) }
837838
}
838839
}
839840

@@ -905,7 +906,7 @@ impl<'a, Ext, Db: Database + DatabaseCommit> EvmNeedsTx<'a, Ext, Db> {
905906
/// Close the current block, returning the EVM ready for the next block.
906907
pub fn close_block(self) -> EvmNeedsBlock<'a, Ext, Db> {
907908
// SAFETY: Same size and repr. Only phantomdata type changes
908-
unsafe { std::mem::transmute(self) }
909+
unsafe { core::mem::transmute(self) }
909910
}
910911

911912
/// Drive a bundle to completion, apply some post-bundle logic, and return the
@@ -926,7 +927,7 @@ impl<'a, Ext, Db: Database + DatabaseCommit> EvmNeedsTx<'a, Ext, Db> {
926927
pub fn fill_tx<T: Tx>(mut self, filler: &T) -> EvmReady<'a, Ext, Db> {
927928
filler.fill_tx(&mut self.inner);
928929
// SAFETY: Same size and repr. Only phantomdata type changes
929-
unsafe { std::mem::transmute(self) }
930+
unsafe { core::mem::transmute(self) }
930931
}
931932

932933
/// Execute a transaction. Shortcut for `fill_tx(tx).run_tx()`.
@@ -992,7 +993,7 @@ impl<'a, Ext, Db: Database + DatabaseCommit> EvmReady<'a, Ext, Db> {
992993
// logic in a block driver
993994

994995
// SAFETY: Same size and repr. Only phantomdata type changes
995-
unsafe { std::mem::transmute(self) }
996+
unsafe { core::mem::transmute(self) }
996997
}
997998

998999
/// Execute the loaded transaction. This is a wrapper around

src/ext.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
1-
use std::collections::HashMap;
2-
31
use alloy_primitives::{Address, B256, U256};
42
use revm::{
5-
primitives::{Account, AccountInfo, Bytecode, EvmState, EvmStorageSlot},
3+
primitives::{Account, AccountInfo, Bytecode, EvmState, EvmStorageSlot, HashMap},
64
Database, DatabaseCommit,
75
};
86

src/fill/zenith.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use crate::Tx;
2+
use alloc::vec;
23
use alloy_primitives::{Address, U256};
34
use alloy_sol_types::SolCall;
45
use revm::primitives::{TransactTo, TxEnv};

0 commit comments

Comments
 (0)