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

refactor: allow chain-specific configuration of Evm #1378

Closed
wants to merge 30 commits into from

Conversation

Wodann
Copy link
Contributor

@Wodann Wodann commented May 3, 2024

Experiment to see whether it would be possible to separate optimism and mainnet SpecIds and other types, such as HaltReason.

I'm curious to hear whether any of this is in line with #918

Copy link
Member

@rakita rakita left a 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.

crates/precompile/Cargo.toml Show resolved Hide resolved
crates/precompile/src/lib.rs Outdated Show resolved Hide resolved
crates/primitives/src/chain_spec.rs Outdated Show resolved Hide resolved
crates/primitives/src/chain_spec.rs Outdated Show resolved Hide resolved
crates/primitives/src/chain_spec.rs Outdated Show resolved Hide resolved
crates/primitives/src/result.rs Show resolved Hide resolved
crates/revm/benches/bench.rs Outdated Show resolved Hide resolved
crates/revm/src/builder.rs Outdated Show resolved Hide resolved
crates/revm/src/builder.rs Outdated Show resolved Hide resolved
crates/revm/src/builder.rs Show resolved Hide resolved
@@ -0,0 +1,253 @@
use revm_interpreter::{
Copy link
Contributor Author

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.

Copy link
Member

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.

@Wodann
Copy link
Contributor Author

Wodann commented May 24, 2024

Given that the general approach seemed to be the right direction, I removed the last instances of [cfg(feature = "optimism")] from the codebase by adding new types to the trait ChainSpec for variability of transaction and block environments.

Please let me know what you think. You should be able to review those changes commit-by-commit

@Wodann
Copy link
Contributor Author

Wodann commented May 24, 2024

I'll hold off on resolving merge conflicts until we're happy with the full design, if that's okay.

@Wodann
Copy link
Contributor Author

Wodann commented May 24, 2024

There are still some EVMError::Custom invocations in handler_register.rs. My understanding is that we could catch those when validating the environment.

That way we could use chain-specific errors static errors instead of strings. Alternatively, we could also add a custom error type to the trait ChainSpec.

That would allow us to remove the EVMError::Custom(String)

WDYT, @rakita ?

@rakita
Copy link
Member

rakita commented Jun 17, 2024

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.

I'll hold off on resolving merge conflicts until we're happy with the full design, if that's okay.

This is perfectly fine.

There are still some EVMError::Custom invocations in handler_register.rs. My understanding is that we could catch those when validating the environment.

That way we could use chain-specific errors static errors instead of strings. Alternatively, we could also add a custom error type to the trait ChainSpec.

That would allow us to remove the EVMError::Custom(String)

I would leave it as String for now, PR is getting big and we can add this later.

@rakita
Copy link
Member

rakita commented Jun 17, 2024

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!

@Wodann
Copy link
Contributor Author

Wodann commented Jun 17, 2024

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 main

@Wodann Wodann marked this pull request as ready for review June 17, 2024 20:00
@Wodann Wodann force-pushed the refactor/opt-spec-id branch 4 times, most recently from 637c088 to f9b2d03 Compare June 17, 2024 22:55
@rakita
Copy link
Member

rakita commented Jun 18, 2024

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 dont have any action items rn, but I will ping you if something comes up.
PR is in good state, but it is a massive change in both the code and the design, so I want to be sure that it is okay.

I added your commits to this PR, squashed, and rebased on main

Great!

@Wodann Wodann force-pushed the refactor/opt-spec-id branch 2 times, most recently from 1744639 to 4bb0f27 Compare June 18, 2024 20:33
@@ -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))]
Copy link
Contributor Author

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?

Comment on lines -46 to -47
.field("inner", &self.inner)
.field("precompiles", &self.inner)
Copy link
Contributor Author

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).

Comment on lines -279 to -284
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()
});
Copy link
Contributor Author

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;
Copy link
Contributor Author

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.

@Wodann Wodann force-pushed the refactor/opt-spec-id branch 2 times, most recently from 9e5dbea to cd9c906 Compare June 24, 2024 17:33
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct EthChainSpec;

impl ChainSpec for EthChainSpec {
Copy link
Contributor Author

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,
Copy link
Contributor Author

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> {
Copy link
Contributor Author

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?

Comment on lines +54 to +66
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)
}
Copy link
Member

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Refactor REVM to make optimism feature flag additive
2 participants