-
Notifications
You must be signed in to change notification settings - Fork 572
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
refactor: allow chain-specific configuration of Evm #1378
Conversation
0e87f0b
to
45c9517
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have started reviewing this last weeks, but didnt have time to finish it whole and getter better grasp on it.
I general like it, change is needed but would like to minimise renames to get smaller PR.
As this is potentially a breaking change will need look at reth code and think how this impacts them as we are in the middle of devnet for Prague.
@@ -0,0 +1,253 @@ | |||
use revm_interpreter::{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file merely serves to illustrate that we can support custom opcodes. It should be removed before merging.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can move it to examples later, fine with leaving it here for now.
Given that the general approach seemed to be the right direction, I removed the last instances of Please let me know what you think. You should be able to review those changes commit-by-commit |
I'll hold off on resolving merge conflicts until we're happy with the full design, if that's okay. |
There are still some That way we could use chain-specific errors static errors instead of strings. Alternatively, we could also add a custom error type to the That would allow us to remove the WDYT, @rakita ? |
I really like this path. For organizational purposes, lets merge this into chain_spec branch so we can work on it and make PR there, and after we are fine with the design, we can think about rebasing it on the main.
This is perfectly fine.
I would leave it as |
I made a PR that refactors few things #1528 I couldn't make it in nomicfoundation/revm didn't get the option for target repo to make a PR on. I am still in investigation phase, but this looks great! |
Awesome! Is there anything you'd like me to do? I added your commits to this PR, squashed, and rebased on |
637c088
to
f9b2d03
Compare
I dont have any action items rn, but I will ping you if something comes up.
Great! |
1744639
to
4bb0f27
Compare
@@ -16,7 +16,6 @@ pub type EVMResultGeneric<T, ChainSpecT, DBError> = core::result::Result< | |||
>; | |||
|
|||
#[derive(Debug, Clone, PartialEq, Eq)] | |||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removing serde (de)serialisation allowed the removal of the serde-related trait bounds from the HaltReasonTrait
. As the ExecutionResult
and ResultAndState
aren't part of the JSON-RPC of Ethereum, I think it should be safe to remove this.
WDYT?
9cb81da
to
2881cdf
Compare
.field("inner", &self.inner) | ||
.field("precompiles", &self.inner) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I used the derive_where
procedural macro to avoid errors like this (double usage of self.inner
).
let nonce = self.env.tx.nonce.unwrap_or_else(|| { | ||
let caller = self.env.tx.caller; | ||
self.load_account(caller) | ||
.map(|(a, _)| a.info.nonce) | ||
.unwrap_or_default() | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I moved the configuration of disabled nonce checks to the CfgEnv
such that the transaction itself always requires a nonce
value to be provided. If someone wants to disable nonce checks, they can do so for the whole Evm
, similar to how it works for disabling other checks.
This voids the need for the trait Transaction
to return an Option<u64>
and I believe is in line with the overall design philosophy for having compile-time disable for checks like these.
/// Trait for retrieving transaction information required for execution. | ||
pub trait Transaction { | ||
/// Caller aka Author aka transaction signer. | ||
fn caller(&self) -> &Address; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I used the philosophy that anything larger than a u64
(pointer) should use a &
whereas anything smaller or equal to a u64
is returned by value. This is also the guideline for when to derive Copy
or not, as it avoids unnecessarily large copies.
I'm not sure whether the presence of lifetimes in the return arguments might be a concern for some people though.
9e5dbea
to
cd9c906
Compare
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash, PartialOrd, Ord)] | ||
pub struct EthChainSpec; | ||
|
||
impl ChainSpec for EthChainSpec { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would L1ChainSpec
be a better/clearer name?
/// Configuration of the transaction that is being executed. | ||
pub tx: TxEnv, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As BlockEnv
and TxEnv
are no needed for the EthChainSpec
, should they be moved to chain_spec.rs
?
}; | ||
use core::marker::PhantomData; | ||
use std::boxed::Box; | ||
|
||
/// Evm Builder allows building or modifying EVM. | ||
/// Note that some of the methods that changes underlying structures | ||
/// will reset the registered handler to default mainnet. | ||
pub struct EvmBuilder<'a, BuilderStage, EXT, DB: Database> { | ||
context: Context<EXT, DB>, | ||
pub struct EvmBuilder<'a, BuilderStage, ChainSpecT: ChainSpec, EXT, DB: Database> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of requiring Default
for ChainSpec::Transaction
and ChainSpec::Block
, I think a nice design would be to have EvmBuilder
contain transaction: Option<ChainSpecT::Transaction>
and block: Option<ChainSpecT::Block>
.
I feel that both should explicitly be set and when finishing the builder, a Result
could be returned that constructs the Context
or returns an error mentioning that no transaction and/or block was provided.
That way the user is not quietly using a default transaction or block configuration.
WDYT?
335551e
to
e65e829
Compare
pub fn get_blob_gasprice(block: &impl Block) -> Option<&u128> { | ||
block.blob_excess_gas_and_price().map(|a| &a.blob_gasprice) | ||
} | ||
|
||
/// Return `blob_excess_gas` header field. See [EIP-4844]. | ||
/// | ||
/// Returns `None` if `Cancun` is not enabled. This is enforced in [`crate::Env::validate_block_env`]. | ||
/// | ||
/// [EIP-4844]: https://eips.ethereum.org/EIPS/eip-4844 | ||
#[inline] | ||
pub fn get_blob_excess_gas(block: &impl Block) -> Option<u64> { | ||
block.blob_excess_gas_and_price().map(|a| a.excess_blob_gas) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: those two can be part of Block trait but with default impl
Experiment to see whether it would be possible to separate optimism and mainnet
SpecId
s and other types, such asHaltReason
.I'm curious to hear whether any of this is in line with #918