Skip to content

test: broken example when using database with lifetime #2201

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

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

Wodann
Copy link
Contributor

@Wodann Wodann commented Mar 12, 2025

This example serves to illustrate a limitation when using the current API with (mutable) references.

The first commit shows the resulting compiler error - when using the current API.

The second commit tries to resolve this by introducing the Context as an associated type on trait Inspector such that we can introduce a 'context lifetime for the context. This lifetime represents the duration during which the Context will be available to the inspector.

This results in the following compiler error:

error[E0308]: mismatched types
  --> examples/inspector_with_lifetime/src/main.rs:79:19
   |
79 |     let results = mine_block(&cfg, &mut db, transactions, &mut inspector)?;
   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
   |
   = note: expected struct `revm::Context<_, _, _, &mut dyn revm::Database<Error = Infallible>, Journal<&mut dyn revm::Database<Error = Infallible>>, _>`
              found struct `revm::Context<_, _, _, &'context mut (dyn revm::Database<Error = Infallible> + 'context), Journal<&'context mut (dyn revm::Database<Error = Infallible> + 'context)>, _>`
note: the lifetime requirement is introduced here
  --> examples/inspector_with_lifetime/src/main.rs:33:41
   |
33 |     InspectorT: for<'context> Inspector<Context<'context> = ContextRef<'context>>,
   |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

I've tried a lot of things to circumvent this but have been unable to. This might be a language limitation rather than an API limitation. See this article.

I still wanted to bring this to your attention, in case you had any ideas on how to solve it.

cfg: &CfgEnv,
db: &mut dyn DBSuperTrait,
tx: TxEnv,
inspector: &mut InspectorT,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, the Inspector takes the lifetime of the Context and it is impossible to use in the way we expect and it sucks. This was a reason why inspector field is part Evm struct, if you send full Evm here it will work, or even impl InspectEvm

Copy link
Contributor Author

@Wodann Wodann Mar 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For some of our use cases that's possible, like building a block.

In other cases we construct the EVM ad-hoc. The flow is similar to this, e.g. for eth_call:

  • Retrieve state at the requested block number from blockchain
  • Construct a BlockEnv for the requested block number
  • Construct a transaction for the eth_call request
  • Construct EVM with DatabaseComponents (for blockchain and state), the requested eth_call transaction, BlockEnv, and CfgEnv
  • Run replay_transact

I might just have to inline the construction of an EVM in that case using an efficient builder pattern API.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inspector is the one that makes a problem, as it takes a &mut Context and rust ties those together, I don't have a good solution how to go around that.

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.

None yet

2 participants