1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
//! [`Trevm`] - a typestate interface to [`revm`].
//!
//! Trevm provides a safe and low-overhead way to interact with the EVM. It is
//! based on the [typestate pattern], which allows the compiler to enforce
//! correct usage of the EVM.
//!
//! Trevm is NOT an EVM implementation. It is a thin wrapper around the EVM
//! provided by [`revm`].
//!
//! [`Trevm`] models the EVM as a state machine with the following states:
//!
//! - [`EvmNeedsCfg`]: The EVM needs to be configured.
//! - [`EvmNeedsBlock`]: The EVM is configured and needs a block environment.
//! - [`EvmNeedsTx`]: The EVM is configured and has a block environment, and
//! now needs a transaction to execute.
//! - [`EvmReady`]: The EVM has a transaction loaded and is ready to execute it.
//! - [`EvmErrored`]: The EVM has executed a transaction and encountered an
//! error.
//! - [`EvmTransacted`]: The EVM has executed a transaction successfully.
//!
//! ## Quickstart
//!
//! To get started, use a [`revm::EvmBuilder`] to configure the EVM, then call
//! [`TrevmBuilder::build_trevm`] to construct the [`Trevm`] instance. From
//! there, you should do the following:
//!
//! - Fill a Cfg by calling [`Trevm::fill_cfg`] with a [`Cfg`].
//! - Open a block by calling [`Trevm::fill_block`] with a [`Block`].
//! - Fill a Tx by calling [`Trevm::fill_tx`] with a [`Tx`].
//! - Run the transaction by calling [`Trevm::run_tx`].
//! - Handle the result by calling [`EvmTransacted::accept`] or
//! [`EvmTransacted::reject`].
//! - Call [`Trevm::close_block`] to close the block.
//! - Then call [`Trevm::finish`] to get the outputs.
//!
//!
//! ### Running a transaction
//!
//! Running transactions is simple with Trevm. Here's a basic example:
//!
//! ```
//! use revm::{EvmBuilder, db::InMemoryDB};
//! use trevm::{TrevmBuilder, EvmErrored, Cfg, Block, Tx};
//!
//! # fn t<C: Cfg, B: Block, T: Tx>(cfg: &C, block: &B, tx: &T)
//! # -> Result<(), Box<dyn std::error::Error>> {
//! EvmBuilder::default()
//! .with_db(InMemoryDB::default())
//! .build_trevm()
//! .fill_cfg(cfg)
//! .fill_block(block)
//! .run_tx(tx);
//! # Ok(())
//! # }
//! ```
//! If you get stuck, don't worry! You _cannot_ invoke the wrong function or
//! mess up the inner state unless you access a method marked `_unchecked`.
//! While the states and generics may seem intimidating at first, they fade
//! into the background when you start writing your application.
//!
//! ## Writing an application
//!
//! When writing your code, we strongly recommend using the `Evm____` type
//! aliases to simplify your code.
//!
//! We also recommend defining concrete types for `Ext` and `Db` whenever
//! possible, to simplify your code and remove bounds. Most users will want
//! `()` for `Ext`, unless specifically using an inspector or a customized EVM.
//!
//! To help you use concrete types, we provide the [`trevm_aliases`] macro. This
//! macro generates type aliases for the Trevm states with concrete `Ext` and `Db` types.
//!
//! ```
//! use trevm::trevm_aliases;
//! use revm::db::InMemoryDB;
//!
//! // produces types that look like this:
//! // type EvmNeedsCfg = trevm::EvmNeedsCfg<'static, (), InMemoryDB>;
//! trevm_aliases!(revm::db::InMemoryDB);
//! ```
//!
//! ### [`BlockDriver`] and [`ChainDriver`]
//!
//! Trevm handles transaction application, receipts, and pre- and post-block
//! logic through the [`BlockDriver`] and [`ChainDriver`] traits. These
//! traits invoked by [`Trevm`] via [`EvmNeedsBlock::drive_block`] and
//! [`EvmNeedsCfg::drive_chain`], respectively.
//!
//! To aid in the creation of drivers, Trevm offers helper functions for
//! common eips:
//!
//! - [`eip2935`] - Prague's [EIP-2935], which updates historical block
//! hashes in a special system contract.
//! - [`eip4788`] - Cancun's [EIP-4788], which updates historical beacon
//! roots in a special system contract.
//! - [`eip4895`] - Cancun's [EIP-4895], which processes withdrawal
//! requests by crediting accounts.
//! - [`eip6110`] - Prague's [EIP-6110], which extracts deposit
//! requests from the withdrawal contract events.
//! - [`eip7002`] - Prague's [EIP-7002], which extracts withdrawal requests
//! from the system withdrawal contract state.
//! - [`eip7251`] - Prague's [EIP-7251], which extracts
//! consolidation requests from the system consolidation contract state.
//!
//! The [`BlockDriver`] and [`ChainDriver`] trait methods take a mutable
//! reference to allow the driver to accumulate information about the
//! execution. This is useful for accumulating receipts, senders, or other
//! information that is more readily available during execution. It is also
//! useful for pre-block logic, where the lifecycle may need to accumulate
//! information about the block before the first transaction is executed, and
//! re-use that information to close the block. It may also be used to compute
//! statistics or indices that are only available after the block is closed.
//!
//! ```
//! # use revm::{EvmBuilder, db::InMemoryDB};
//! # use trevm::{TrevmBuilder, EvmErrored, Cfg, BlockDriver};
//! # use alloy::primitives::B256;
//! # fn t<C: Cfg, D: BlockDriver<()>>(cfg: &C, mut driver: D)
//! # -> Result<(), Box<dyn std::error::Error>> {
//! let trevm = EvmBuilder::default()
//! .with_db(InMemoryDB::default())
//! .build_trevm()
//! .fill_cfg(cfg)
//! .drive_block(&mut driver);
//! # Ok(())
//! # }
//! ```
//!
//! [`BlockDriver`] and [`ChainDriver`] implementations are generic over the
//! `Ext` type. This means that you can use customized revm extensions and
//! inspectors in your driver logic.
//!
//! ### Handling execution errors
//!
//! Trevm uses the [`EvmErrored`] state to handle errors during transaction
//! execution. This type is a wrapper around the error that occurred, and
//! provides a method to discard the error and continue execution. This is
//! useful when you want to continue executing transactions even if one fails.
//!
//! Usually, errors will be [`EVMError<Db>`], but [`BlockDriver`] and
//! [`ChainDriver`] implementations may return other errors. The [`EvmErrored`]
//! type is generic over the error type, so you can use it with any error type.
//!
//! ```
//! # use revm::{EvmBuilder, db::InMemoryDB};
//! # use trevm::{TrevmBuilder, EvmErrored, Cfg, Block, Tx};
//! # use alloy::primitives::B256;
//! # fn t<C: Cfg, B: Block, T: Tx>(cfg: &C, block: &B, tx: &T)
//! # -> Result<(), Box<dyn std::error::Error>> {
//! let trevm = match EvmBuilder::default()
//! .with_db(InMemoryDB::default())
//! .build_trevm()
//! .fill_cfg(cfg)
//! .fill_block(block)
//! .fill_tx(tx)
//! .run() {
//! Ok(trevm) => trevm.accept_state(),
//! Err(e) => e.discard_error(),
//! };
//! # Ok(())
//! # }
//! ```
//!
//! ### Extending Trevm
//!
//! Trevm has a few extension points:
//!
//! - Build the [`revm::Evm`] with a [`revm::Inspector`] and use it in trevm.
//! - Implement the [`PostTx`] trait to apply post-transaction logic/changes.
//! - Implement your own [`Cfg`], [`Block`], and
//! [`Tx`] to fill the EVM from your own data structures.
//! - Implement your own [`BlockDriver`] to apply pre- and post-block logic,
//! use custom receipt types, or more.
//!
//! ```
//! # use trevm::Tx;
//! # use alloy::primitives::Address;
//! // You can implement your own Tx to fill the EVM environment with your own
//! // data.
//! pub struct MyTx;
//!
//! impl Tx for MyTx {
//! fn fill_tx_env(&self, tx_env: &mut revm::primitives::TxEnv) {
//! // fill the tx_env with your data
//! // we recommend destructuring here to safeguard against future changes
//! // to the TxEnv struct
//! let revm::primitives::TxEnv {
//! caller,
//! ..
//! } = tx_env;
//! *caller = Address::repeat_byte(0xde);
//! }
//! }
//! ```
//!
//! ### Trevm feature flags
//!
//! Trevm passes through most feature flags from revm, the following are on by
//! default:
//!
//! - `c-kzg` - Enable KZG precompiles as specced for [EIP-4844].
//! - `blst` - Enable BLST precompiles as speced for [EIP-2537].
//! - `portable` - Compiles BLST in portable mode.
//! - `secp256k1` - Use libsecp256k1 for ecrecover (default is k256).
//!
//! Cfg features:
//! - `memory_limit` - Allow users to limit callframe memory usage.
//! - `optional_balance_check` - Allow transacting with insufficient balance.
//! - `optional_block_gas_limit` - Allow transactions that exceed the block gas
//! limit.
//! - `optional_eip3607` - Allow transactions whose sender account has contract
//! code.
//! - `optional_gas_refund` - Allow disabling gas refunds, as in Avalanche.
//! - `optional_no_base_fee` - Allow disabling basefee checks.
//! - `optional_beneficiary_reward` - Allow disabling fees and rewards paid to
//! the block beneficiary.
//!
//! - `dev` - Enable all Cfg features.
//!
//! Trevm also provides the following:
//!
//! - `test-utils` - activates revm's `test-utils` feature, and provides
//! convenience functions for instantiating [`Trevm`] with an in-memory DB.
//!
//! ### Testing using Trevm
//!
//! Trevm provides a `test-utils` module for easy testing. The test-utils gives
//! you access to an in-memory clean-slate [`Trevm`] instance, as well as tools
//! for directly modifying the state of the EVM.
//!
//! During testing you can use
//! - set balance, nonce, codehash for any account
//! - a single-function setup for a blank EVM
//! - pre-funding for any number of accounts
//! ## Understanding the state machine
//!
//! Here's an example, with states written out:
//!
//! ```
//! # use revm::{EvmBuilder, db::{InMemoryDB, BundleState}, State,
//! # StateBuilder};
//! # use trevm::{TrevmBuilder, EvmErrored, Cfg, Block, Tx, BlockOutput,
//! # EvmNeedsCfg, EvmNeedsBlock, EvmNeedsTx, EvmReady, EvmTransacted};
//! # fn t<C: Cfg, B: Block, T: Tx>(cfg: &C, block: &B, tx: &T)
//! # -> Result<(), Box<dyn std::error::Error>> {
//! let state = StateBuilder::new_with_database(InMemoryDB::default()).build();
//!
//! // Trevm starts in `EvmNeedsCfg`.
//! let trevm: EvmNeedsCfg<'_, _, _> = EvmBuilder::default()
//! .with_db(state)
//! .build_trevm();
//!
//! // Once the cfg is filled, we move to `EvmNeedsBlock`.
//! let trevm: EvmNeedsBlock<'_, _, _> = trevm.fill_cfg(cfg);
//!
//! // Filling the block gets us to `EvmNeedsTx`.
//! let trevm: EvmNeedsTx<'_, _, _> = trevm.fill_block(
//! block,
//! );
//! // Filling the tx gets us to `EvmReady`.
//! let trevm: EvmReady<'_, _, _> = trevm.fill_tx(tx);
//!
//! let res: Result<
//! EvmTransacted<'_, _, _>,
//! EvmErrored<'_, _, _, _>,
//! > = trevm.run();
//!
//!
//! // Applying the tx or ignoring the error gets us back to `EvmNeedsTx`.
//! // You could also make additional checks and discard the success result here
//! let trevm: EvmNeedsTx<'_, _, _> = match res {
//! Ok(trevm) => trevm.accept_state(),
//! Err(e) => e.discard_error(),
//! };
//!
//! // Clearing or closing a block gets us to `EvmNeedsBlock`, ready for the
//! // next block.
//! let trevm: EvmNeedsBlock<'_, _, _> = trevm
//! .close_block();
//!
//! // Finishing the EVM gets us the final changes and a list of block outputs
//! // that includes the transaction receipts.
//! let bundle: BundleState = trevm.finish();
//! # Ok(())
//! # }
//! ```
//!
//! ## Happy Path Loop
//!
//! The most simple, straightforward application of Trevm is applying a
//! set of transaction to the EVM. This is done by following :
//!
//! ```none
//! +-----+ +-----------+
//! |Start| ---> |EvmNeedsCfg|
//! +-----+ +-----------+
//! |
//! +-- fill_cfg() --+
//! |
//! V
//! +------+ +-------------+
//! |Finish|<- finish() -|EvmNeedsBlock|---+
//! +------+ +-------------+ |
//! ^ |
//! | |
//! +-----------+ |
//! | |
//! close_block() |
//! | |
//! +----------+ |
//! |EvmNeedsTx| <---- fill_block() -----+
//! +----------+
//! ^ | +--------+
//! | +------- fill_tx() -------> |EvmReady|--+
//! | +--------+ |
//! | +-------------+ |
//! +- accept() --|EvmTransacted| <-- run_tx() -----+
//! or reject() +-------------+
//! ```
//!
//! A basic block loop should look like this:
//!
//! ```no_compile
//! let mut evm = evm
//! .fill_cfg(cfg);
//! .fill_block(block, pre_block_logic);
//!
//! for tx in txs {
//! // apply the transaction, discard the error if any
//! evm = match evm.run_tx(tx);
//! }
//!
//! // close out the EVM, getting the final state
//! let (bundle, outputs) = evm.close_block(block, post_block_logic).finish();
//! ```
//!
//! [`EVMError<Db>`]: revm::primitives::EVMError<Db>
//! [typestate pattern]: https://cliffle.com/blog/rust-typestate/
//! [crate readme]: https://github.com/init4tt/trevm
//! [EIP-2537]: https://eips.ethereum.org/EIPS/eip-2537
//! [EIP-2935]: https://eips.ethereum.org/EIPS/eip-2935
//! [EIP-4788]: https://eips.ethereum.org/EIPS/eip-4788
//! [EIP-4844]: https://eips.ethereum.org/EIPS/eip-4844
//! [EIP-4895]: https://eips.ethereum.org/EIPS/eip-4895
//! [EIP-6110]: https://eips.ethereum.org/EIPS/eip-6110
//! [EIP-7002]: https://eips.ethereum.org/EIPS/eip-7002
//! [EIP-7251]: https://eips.ethereum.org/EIPS/eip-7251
//! [`eip2935`]: crate::system::eip2935
//! [`eip4788`]: crate::system::eip4788
//! [`eip4895`]: crate::system::eip4895
//! [`eip6110`]: crate::system::eip6110
//! [`eip7002`]: crate::system::eip7002
//! [`eip7251`]: crate::system::eip7251
pub use ;
/// Contains database implementations for concurrent EVM operation.
pub use ;
pub use Trevm;
pub use EstimationResult;
pub use EvmExtUnchecked;
pub use ;
pub use ;
pub use *;
pub use ;
pub use revm;
/// Utilities for testing Trevm or testing with Trevm.
use ;
/// The minimum gas required for a transaction.
pub const MIN_TRANSACTION_GAS: u64 = 21_000;
/// Ext trait for [`EvmBuilder`] that builds a [`Trevm`], and adds features for
/// [`DbConnect`].