-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Add support for Celo's stateful transfer precompile #11209
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
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this 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
foundry/crates/anvil/src/eth/backend/executor.rs
Lines 337 to 345 in 79d4ab2
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
/// Run a Celo chain | ||
#[arg(long)] | ||
pub celo: bool, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm, not convinced we want to add a new arg for every network that we can add custom precompiles for.
should we perhaps derive this from the chainid, although an additional celo flag doesnt really hurt
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we only rely on the chainid, new networks won't work with anvil until they have been explicitly supported. And getting PRs with config for short-lived and local networks sounds annoying to me. Adding a flag seems the lesser evil to me.
We can still automatically detect the flags for the most important networks based on the chainid. But if we need a flag anyway, that falls into the "nice to have" category.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could also enable the transfer
precompile by setting --hardfork cel2
, but I'm not sure if adding chain-specific hardforks is better than adding a flag for the chain itself.
There was a problem hiding this comment.
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
foundry/crates/anvil/src/evm.rs
Lines 28 to 29 in 79d4ab2
evm.precompiles_mut().apply_precompile(&addr, move |_| { | |
Some(DynPrecompile::from(move |input: PrecompileInput<'_>| func(input.data, gas))) |
There was a problem hiding this comment.
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
.
There was a problem hiding this comment.
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.
4465f77
to
64f1632
Compare
64f1632
to
08a0fda
Compare
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
|
Motivation
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 thePrecompilesMap
that provides access to thetransfer
precompile.PR Checklist