-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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
refactor: inject call to CREATE2 factory through custom revm handler #7653
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.
this is great,
only have pedantic doc nits for the register function
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.
lgtm, pending @DaniPopes
crates/anvil/Cargo.toml
Outdated
@@ -31,6 +31,7 @@ foundry-cli.workspace = true | |||
foundry-common.workspace = true | |||
foundry-config.workspace = true | |||
foundry-evm.workspace = true | |||
foundry-evm-core.workspace = true |
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.
unused
crates/cheatcodes/src/inspector.rs
Outdated
let is_fixed_gas_limit = check_if_fixed_gas_limit(ecx, call.gas_limit); | ||
|
||
let account = ecx.journaled_state.state().get(&broadcast.new_origin).unwrap(); |
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.
let account = ecx.journaled_state.state().get(&broadcast.new_origin).unwrap(); | |
let account = ecx.journaled_state.state()[&broadcast.new_origin]; |
crates/evm/core/src/utils.rs
Outdated
@@ -1,17 +1,26 @@ | |||
use std::{cell::RefCell, rc::Rc, sync::Arc}; | |||
|
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.
crates/evm/core/src/utils.rs
Outdated
}; | ||
|
||
pub use foundry_compilers::utils::RuntimeOrHandle; | ||
pub use revm::primitives::State as StateChangeset; | ||
|
||
pub use crate::ic::*; | ||
use crate::{constants::DEFAULT_CREATE2_DEPLOYER, InspectorExt}; |
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.
up
crates/evm/core/src/utils.rs
Outdated
@@ -99,6 +108,129 @@ pub fn gas_used(spec: SpecId, spent: u64, refunded: u64) -> u64 { | |||
spent - (refunded).min(spent / refund_quotient) | |||
} | |||
|
|||
pub fn get_create2_factory_call_inputs(salt: U256, inputs: CreateInputs) -> CallInputs { |
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.
does this need to be public?
cabfe24
to
2713557
Compare
2713557
to
c1547da
Compare
Motivation
ref #7632 (comment)
This changes flow for CREATE2 deployments routed through CREATE2 factory. Earlier we would just patch the sender of CREATE2 frame which resulted in data appearing in traces and state diff being different from the actual transaction data.
The way this PR addresses this is by implementing a revm handler register which replaces CREATE2 frame with CALL frame to factory when needed.
Thus, trace of a simple counter CREATE2 deployment changes from:
to:
Solution
Implement
InspectorExt
trait withshould_use_create2_factory
method returning false by default which allows our inspectors to decide if the CREATE frame should be routed through create2 factory.Implement handler register overriding
create
andinsert_call_outcome
hooks:create
hook returnsCALL
frame instead ofCREATE
frame whenshould_use_create2_factory
fn returns true for the current frame.insert_call_outcome
hook decodes result of the create2 factory invocation and inserts it directly into interpreter.Solution is not really clean because I had to duplicate parts of
call
andinsert_call_outcome
hooks from revm inspector hander register instead of just invoking them in register. The motivation behind this is following:insert_call_outcome
hook because it would invokeinspector.insert_call_outcome()
.insert_call_outcome
,call
cannot be reused as well because we'd mess up internal stack of inspector handler register (https://github.com/bluealloy/revm/blob/f4f4745e00b1c2907b6a3527eee3765bc1603b58/crates/revm/src/inspector/handler_register.rs#L167)This impl lets us keep cheatcodes inspector and overall flow simpler however it introduces additional complexity in EVM construction step and might result in issues if revm implementation of inspector handler register changes, so not sure if we should include that