Skip to content

Conversation

karlb
Copy link
Contributor

@karlb karlb commented Aug 5, 2025

Motivation

Closes #11210
The Celo blockchain makes use of a stateful transfer precompile. Implementing this in Anvil allows running more of our tests in Anvil.

In addition to providing this feature to Celo blockchains, it also serves as an example on how to add stateful precompiles to anvil, closing #11210

Solution

Since inject_precompiles does not support stateful precompiles, a Celo-specific lookup function is added to the PrecompilesMap that provides access to the transfer precompile.

PR Checklist

  • Added Tests
  • Added Documentation
  • Breaking changes (none)

@karlb karlb changed the title Karlb/celo transfer precompile Add support for Celo's stateful transfer precompile Aug 5, 2025
Copy link
Member

@mattsse mattsse left a comment

Choose a reason for hiding this comment

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

supportive, because this can serve as a reference for additional precompile support.

left some pointers, re reusing the PrecompilesMap and inject dynamically.

we can likely clean up a few more things as well,

perhaps rethink how and where we call

let mut evm = new_evm_with_inspector(&mut *self.db, &env, &mut inspector);
if self.odyssey {
inject_precompiles(&mut evm, vec![(P256VERIFY, P256VERIFY_BASE_GAS_FEE)]);
}
if let Some(factory) = &self.precompile_factory {
inject_precompiles(&mut evm, factory.precompiles());
}

ideally we only have these in one location

Copy link
Member

Choose a reason for hiding this comment

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

I believe this is now redundant, because we can now dynamically inject precompiles into the regular evm with PrecompilesMap via

evm.precompiles_mut().apply_precompile(&addr, move |_| {
Some(DynPrecompile::from(move |input: PrecompileInput<'_>| func(input.data, gas)))

Copy link
Contributor Author

@karlb karlb Aug 6, 2025

Choose a reason for hiding this comment

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

In its current form, this can only be used to inject stateless precompiles. The PrecompileWithAddress that is passed into this function does not take any context/state as parameter:

pub struct PrecompileWithAddress(pub Address, pub PrecompileFn);
pub type PrecompileFn = fn(&[u8], u64) -> PrecompileResult;

But now that PrecompilesMap has gained a settable lookup function, I can try to use that to include a stateful precompile. Unfortunately, the EvmInternals in the PrecompileInput don't provide access to the journal, so that I can't use the journal's transfer method like I do in this PR. I might be able to use load_account instead, since it returns a mutable Account.

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 updated the code with this approach and it looks much better now.

@karlb karlb force-pushed the karlb/celo-transfer-precompile branch from 4465f77 to 64f1632 Compare August 6, 2025 15:42
@karlb karlb force-pushed the karlb/celo-transfer-precompile branch from 64f1632 to 08a0fda Compare August 8, 2025 14:15
@karlb
Copy link
Contributor Author

karlb commented Aug 8, 2025

I'm quite happy with the current implementation and updated the PR description. Before I add tests and/or docs, some feedback on the following points would be appreciated

  • Is the --celo flag ok for this PR or should I change how the precompile is enabled
  • What kind of tests would you recommend for this change
  • Are there any major changes needed or is it a good time to start on tests and docs now?

@karlb karlb marked this pull request as ready for review August 8, 2025 15:39
Copy link
Member

@mattsse mattsse left a comment

Choose a reason for hiding this comment

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

sorry for the late review

this looks complete, I'm fine with the celo flag honestly.

I do want to block this until we have

#11293

which would allow a smol simplification here as well, will take over then

@mattsse
Copy link
Member

mattsse commented Aug 28, 2025

whoops forgot about this, will wrap up in a bit

@mattsse
Copy link
Member

mattsse commented Aug 30, 2025

closing this since #11491 was merged

@mattsse mattsse closed this Aug 30, 2025
@github-project-automation github-project-automation bot moved this to Done in Foundry Aug 30, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

Stateful precompile support in Anvil
3 participants