-
Notifications
You must be signed in to change notification settings - Fork 1.9k
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
feat(anvil): add support for injecting precompiles #7589
Merged
mattsse
merged 17 commits into
foundry-rs:master
from
alexfertel:extend-precompiles-anvil
Apr 9, 2024
Merged
Changes from 10 commits
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
c358b10
feat(anvil): add support for injecting precompiles
alexfertel bee89d9
test: check precompiles get injected
alexfertel d092014
feat(docs): add a few doc comments
alexfertel d03c1f5
feat(docs): document with_extra_precompiles
alexfertel d65c9fd
ref: localize changes to the anvil crate
alexfertel 8470a31
ref: rename with_extra_precompiles -> with_precompile_factory
alexfertel 31e32bc
lint(fmt): fix formatting
alexfertel 885b2d5
ref: fix invalid comment
alexfertel bc2c9a0
ref: remove unnecessary generic bound
alexfertel 4e85f4d
ref: revert formatting change
alexfertel e4901c8
ref: extract evm creation to a method
alexfertel d8d86d9
fix: inject precompiles to the executor
alexfertel a1fe064
lint(fmt): fix formatting
alexfertel fd746d2
Merge branch 'master' into extend-precompiles-anvil
alexfertel 4679dff
Merge branch 'master' into extend-precompiles-anvil
mattsse 6cc3047
chore: add doc
mattsse efcc956
nit
mattsse File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
use std::{fmt::Debug, sync::Arc}; | ||
|
||
use alloy_primitives::Address; | ||
use foundry_evm::revm::{self, precompile::Precompile, ContextPrecompile, ContextPrecompiles}; | ||
|
||
/// Object-safe trait that enables injecting extra precompiles when using | ||
/// `anvil` as a library. | ||
pub trait PrecompileFactory: Send + Sync + Unpin + Debug { | ||
/// Returns a set of precompiles to extend the EVM with. | ||
fn precompiles(&self) -> Vec<(Address, Precompile)>; | ||
} | ||
|
||
/// Appends a handler register to `evm` that injects the given `precompiles`. | ||
pub fn inject_precompiles<DB, I>( | ||
evm: &mut revm::Evm<'_, I, DB>, | ||
precompiles: Vec<(Address, Precompile)>, | ||
) where | ||
DB: revm::Database, | ||
{ | ||
evm.handler.append_handler_register_box(Box::new(move |handler| { | ||
let precompiles = precompiles.clone(); | ||
let loaded_precompiles = handler.pre_execution().load_precompiles(); | ||
handler.pre_execution.load_precompiles = Arc::new(move || { | ||
let mut loaded_precompiles = loaded_precompiles.clone(); | ||
loaded_precompiles.extend( | ||
precompiles | ||
.clone() | ||
.into_iter() | ||
.map(|(addr, p)| (addr, ContextPrecompile::Ordinary(p))), | ||
); | ||
let mut default_precompiles = ContextPrecompiles::default(); | ||
default_precompiles.extend(loaded_precompiles); | ||
default_precompiles | ||
}); | ||
})); | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use alloy_primitives::Address; | ||
use foundry_evm::revm::{ | ||
self, | ||
primitives::{address, Bytes, Precompile, PrecompileResult, SpecId}, | ||
}; | ||
|
||
use crate::{evm::inject_precompiles, PrecompileFactory}; | ||
|
||
#[test] | ||
fn build_evm_with_extra_precompiles() { | ||
const PRECOMPILE_ADDR: Address = address!("0000000000000000000000000000000000000071"); | ||
fn my_precompile(_bytes: &Bytes, _gas_limit: u64) -> PrecompileResult { | ||
Ok((0, Bytes::new())) | ||
} | ||
|
||
#[derive(Debug)] | ||
struct CustomPrecompileFactory; | ||
|
||
impl PrecompileFactory for CustomPrecompileFactory { | ||
fn precompiles(&self) -> Vec<(Address, Precompile)> { | ||
vec![(PRECOMPILE_ADDR, Precompile::Standard(my_precompile))] | ||
} | ||
} | ||
|
||
let db = revm::db::EmptyDB::default(); | ||
let env = Box::<revm::primitives::Env>::default(); | ||
let spec = SpecId::LATEST; | ||
let handler_cfg = revm::primitives::HandlerCfg::new(spec); | ||
let inspector = revm::inspectors::NoOpInspector; | ||
let context = revm::Context::new(revm::EvmContext::new_with_env(db, env), inspector); | ||
let handler = revm::Handler::new(handler_cfg); | ||
let mut evm = revm::Evm::new(context, handler); | ||
assert!(!evm | ||
.handler | ||
.pre_execution() | ||
.load_precompiles() | ||
.addresses() | ||
.any(|&addr| addr == PRECOMPILE_ADDR)); | ||
|
||
inject_precompiles(&mut evm, CustomPrecompileFactory.precompiles()); | ||
assert!(evm | ||
.handler | ||
.pre_execution() | ||
.load_precompiles() | ||
.addresses() | ||
.any(|&addr| addr == PRECOMPILE_ADDR)); | ||
|
||
let result = evm.transact().unwrap(); | ||
assert!(result.result.is_success()); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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 can put this in a function of Backend::new_evm_with_inspector_ref