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

Can we replay an on-chain optimism transaction using revm? #377

Closed
Tracked by #373
Wodann opened this issue Apr 10, 2024 · 1 comment
Closed
Tracked by #373

Can we replay an on-chain optimism transaction using revm? #377

Wodann opened this issue Apr 10, 2024 · 1 comment
Assignees
Milestone

Comments

@Wodann
Copy link
Member

Wodann commented Apr 10, 2024

No description provided.

@Wodann
Copy link
Member Author

Wodann commented May 7, 2024

Terminology: I'll use the word vanilla to mean the unaltered EVM as proposed in the Ethereum white/yellow paper.

In its current form, it's impossible to run REVM both in vanilla and Optimism mode. Rust features are supposed to be additive such that enabling a feature doesn't disable some other feature. Unfortunately, in REVM the optimism feature flag doesn't quite work this way. When you enable the optimism feature flag, you can no longer use a vanilla EVM. Instead:

  • the enum SpecId will contain optimism-specific hardforks;
  • the enum HaltReason contains optimism-specific variants;
  • the enum InvalidTransaction contains optimism-specific variants;
  • the struct TxEnv contains a field optimism: OptimismFields
  • the struct InnerEvmContext contains a field l1_block_info: L1BlockInfo.

As a result, vanilla EVM exeuction code in EDR would need to set missing struct fields at construction and handle missing enum variants in match statements.

I did some experiments to see whether I could decouple the SpecId and HaltReason. The results are in this draft PR: bluealloy/revm#1378. With this design it's possible to configure the EVM per chain, allowing:

  • static typing of the chain spec using trait ChainSpec;
  • the EvmBuilder to restrict typing using the specified ChainSpec;
  • custom HaltReasons;
  • custom SpecIds;
  • custom opcode handlers that have access to the chain-specific trait {CustomChain}Spec;
  • reuse of the vanilla mainnet opcode handlers, thanks to the ability to const cast to the base trait {Vanilla}Spec

I did not research the OpCode struct, which provides convenience functions for retrieving opcode name, accessing the jump table, etc. However, it seems possible to extend the opcode! macro to implement chain-specific OpCode structs that are able to retrieve this information for that particular chain

Based on the design pattern used in the draft PR, I think we can use the same pattern as I used for HaltReason to also convert the TxEnv and InnerEvmContext to use composition instead of a feature flag inside the structs.

With those changes, I think that would remove the last occurrences of the optimism feature flag inside "core" REVM code.

Alternatives

If we cannot make the base REVM implementation generic for alternative chains, we can use the generic EXT (i.e. external context) to pass in chain-specific data for the block, transaction, SpecId, etc.

This doesn't allow us to override the HaltReason, ExecutionResult, etc.; preventing us from returning chain specific errors this way. We can circumvent this by setting chain-specific results in the external context.

This solution doesn't follow the normal control-flow of Rust, so will be "hacky".

@Wodann Wodann closed this as completed May 7, 2024
@Wodann Wodann added this to the EDR v0.5.0 milestone May 9, 2024
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 8, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
Status: Done
Development

No branches or pull requests

2 participants