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

Support injecting custom precompiles to anvil #7498

Closed
alexfertel opened this issue Mar 26, 2024 · 4 comments · Fixed by #7589
Closed

Support injecting custom precompiles to anvil #7498

alexfertel opened this issue Mar 26, 2024 · 4 comments · Fixed by #7589
Labels
T-feature Type: feature

Comments

@alexfertel
Copy link
Contributor

alexfertel commented Mar 26, 2024

Component

Anvil

Describe the feature you would like

Currently, we have a use case where we want to spin up an isolated anvil instance per test with custom precompiles.

Given that the team is willing to support custom precompiles as functions in Foundry, it would be nice to add a way to inject custom precompiles to anvil (as a library), like for example, being able to pass the result of revm::Evm::builder().

If I'm reading anvil's source code correctly, this would imply updating NodeConfig to support some form of precompile injection.

This would outsource maintaining custom precompiles from the team to consumers.

Additional context

No response

@alexfertel alexfertel added the T-feature Type: feature label Mar 26, 2024
@mattsse
Copy link
Member

mattsse commented Mar 29, 2024

This should be doable,

what we need is a way to tell the Backend how to configure an Evm, so the Evm::builder() step can be customized.

In reth this is kinda doable already, like:

https://github.com/paradigmxyz/reth/blob/be16072728abae152fd04a83f0f22e8b08ecbe04/examples/custom-evm/src/main.rs#L83-L99

so what we need here is something similar.

I think for anvil this should also be abstracted over a trait that can be boxed so we don't end up with a bunch of generics everywhere, which is the most difficult part here because the Evm interface is a bit hard to work with in that regard.

so this likely needs some trial and error first

@alexfertel
Copy link
Contributor Author

alexfertel commented Apr 1, 2024

Hey, so I started working on this, and I have the following thoughts/questions. I know you know all of this, but I like to have all the context in one place.

I see that Evm environment is separate from Evm execution, in the sense that all that anvil::spawn() does is setup all the environment surrounding execution, which makes sense. However, this also means that instantiation of revm::Evm occurs only in

pub fn new_evm_with_inspector<'a, DB, I>(
db: DB,
env: revm::primitives::EnvWithHandlerCfg,
inspector: I,
) -> revm::Evm<'a, I, DB>
where
DB: revm::Database,
I: revm::Inspector<DB>,
{
// NOTE: We could use `revm::Evm::builder()` here, but on the current patch it has some
// performance issues.
let revm::primitives::EnvWithHandlerCfg { env, handler_cfg } = env;
let context = revm::Context::new(revm::EvmContext::new_with_env(db, env), inspector);
let mut handler = revm::Handler::new(handler_cfg);
handler.append_handler_register_plain(revm::inspector_handle_register);
revm::Evm::new(context, handler)
}

and this is passed the Env constructed by anvil::spawn. The difference between anvil and reth in this regard is that while anvil uses revm's config types for its execution, as you can see in the signature of new_evm_with_inspector() above, reth uses its own config types, and stores the Evm instance itself in the processor https://github.com/paradigmxyz/reth/blob/be16072728abae152fd04a83f0f22e8b08ecbe04/crates/revm/src/processor.rs#L58 and uses it here https://github.com/paradigmxyz/reth/blob/be16072728abae152fd04a83f0f22e8b08ecbe04/crates/revm/src/processor.rs#L279.

So, one path I see is creating a wrapper Env for anvil::eth::backend::mem::Backend, so that the TransactionExecutor can tap into the injected precompiles. This will probably end up looking somewhat similar to paradigmxyz/reth@be16072/examples/custom-evm/src/main.rs#L83-L99.

This will also mean modifying new_evm_with_inspector(), which btw, has the following notice:

    // NOTE: We could use `revm::Evm::builder()` here, but on the current patch it has some
    // performance issues.

Does this make sense to you? Am I missing something?

@mattsse
Copy link
Member

mattsse commented Apr 1, 2024

However, this also means that instantiation of revm::Evm occurs only in

yes, this part we need to make configurable, we need something that knows how to do this and takes care of configuring the evm given an env

we need to abandon this util function

@onbjerg
Copy link
Member

onbjerg commented Apr 1, 2024

Somewhat related #6509 (i.e. the idea is WASM modules to insert as precompiles for foundry)

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

Successfully merging a pull request may close this issue.

3 participants