-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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: add pre-block EIP-4788 beacon root contract call #4457
Conversation
206c353
to
fed5b0e
Compare
fed5b0e
to
2378263
Compare
Codecov Report
... and 10 files with indirect coverage changes
Flags with carried forward coverage won't be shown. Click here to find out more.
|
83c600d
to
f81d404
Compare
// TODO: there isn't really a parent beacon block root here, so not sure whether or not to | ||
// call the 4788 beacon contract |
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.
yeah I think we need to figure out what to do here, but no blocker for this pr
/// * the call does not follow the EIP-1559 burn semantics - no value should be transferred as | ||
/// part of the call | ||
/// * if no code exists at `BEACON_ROOTS_ADDRESS`, the call must fail silently | ||
pub fn fill_tx_env_with_beacon_root_contract_call(env: &mut Env, parent_beacon_block_root: H256) { |
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
crates/revm/src/processor.rs
Outdated
/// | ||
/// If cancun is not activated or the block is the genesis block, then this is a no-op, and no | ||
/// state changes are made. | ||
pub fn apply_pre_block_call(&mut self, block: &Block) -> Result<(), BlockExecutionError> { |
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.
it's not obvious that this is the eip-4788 call,
in favour of changing the function names accordingly
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.
changed to apply_beacon_root_contract_call
crates/payload/basic/src/lib.rs
Outdated
..Default::default() | ||
}; | ||
|
||
// apply pre-block EIP-4788 contract call | ||
let mut evm_pre_block = revm::EVM::with_env(env); | ||
evm_pre_block.database(db); | ||
|
||
// initialize a block from the env, because the pre block call needs the block itself | ||
match apply_pre_block_call( | ||
chain_spec, | ||
attributes.timestamp, | ||
block_number, | ||
attributes.parent_beacon_block_root, | ||
&mut evm_pre_block, |
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.
the txenv is still uninitialized here?
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.
Changed fill_tx_env_with_beacon_root_contract_call
to explicitly set each field in the TxEnv
crates/payload/basic/src/lib.rs
Outdated
@@ -967,6 +990,49 @@ fn commit_withdrawals<DB: Database<Error = Error>>( | |||
}) | |||
} | |||
|
|||
/// TODO: docs | |||
fn pre_block_contract_call<DB>( |
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 will be required for any kind of payload building so I think we should move this to the payload/builder crate
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's track in new good-first-issue
crates/payload/basic/src/lib.rs
Outdated
@@ -967,6 +990,49 @@ fn commit_withdrawals<DB: Database<Error = Error>>( | |||
}) | |||
} | |||
|
|||
/// TODO: docs | |||
fn pre_block_contract_call<DB>( | |||
db: State<DB>, |
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 think this could be Database + DatabaseCommit
, so it no longer requires a concrete type,
all of them are also implemented on &mut
so we don't need to return it
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.
same in separate good first issue
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.
was an easy change, it's all &mut now
@@ -234,15 +249,14 @@ impl<'a> EVMProcessor<'a> { | |||
total_difficulty: U256, | |||
senders: Option<Vec<Address>>, | |||
) -> Result<(Vec<Receipt>, u64), BlockExecutionError> { | |||
self.init_env(&block.header, total_difficulty); |
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 happen even if the block is empty? if not, should prob move back to where it was before
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.
yes, this happens on every block, regardless of empty / non empty
|
||
/// Returns the beacon root contract code | ||
fn beacon_root_contract_code() -> Bytes { | ||
Bytes::from_str("0x3373fffffffffffffffffffffffffffffffffffffffe14604457602036146024575f5ffd5b620180005f350680545f35146037575f5ffd5b6201800001545f5260205ff35b6201800042064281555f359062018000015500").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.
nit: can be a lazy static?
if block_number == 0 { | ||
if block_parent_beacon_block_root != Some(H256::zero()) { |
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.
nit: can be rolled into 1 statement
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 don't think so, because if the parent root is Some(H256::zero())
on genesis, then we don't want to run the beacon root contract call, per the spec. If we rolled the statements into one, then we would run the contract call on a genesis with parent_beacon_block_root = Some(H256::zero())
.
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. Let's open issues for the nits/todos from the PR and get this in, unless any objections. We'll merge Revm State PR first, and then we'll need to do a smol rebase against main before getting this in main.
crates/payload/basic/src/lib.rs
Outdated
@@ -967,6 +990,49 @@ fn commit_withdrawals<DB: Database<Error = Error>>( | |||
}) | |||
} | |||
|
|||
/// TODO: docs | |||
fn pre_block_contract_call<DB>( |
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's track in new good-first-issue
crates/payload/basic/src/lib.rs
Outdated
@@ -967,6 +990,49 @@ fn commit_withdrawals<DB: Database<Error = Error>>( | |||
}) | |||
} | |||
|
|||
/// TODO: docs | |||
fn pre_block_contract_call<DB>( | |||
db: State<DB>, |
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.
same in separate good first issue
where | ||
<DB as Database>::Error: Debug, | ||
{ | ||
if chain_spec.is_cancun_activated_at_timestamp(block_timestamp) { |
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.
you can de-indent twice here if you collapse the ifs / invert this and return early, but nbd
// get previous env | ||
let previous_env = evm.env.clone(); |
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.
nit: can you not instead call this beacon_roots_env
and do the fill_tx
call with that, to avoid having to re-set the evm.env
at the end of the 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.
no, because the env would have to be set in the evm anyways, for it to be used during transact
. We could initialize a new Env
and swap
them, but I don't see how that's different than cloning here, since we have to initialize a second Env
anyways.
We could get rid of the reset by just telling the caller (in docs) to make sure the block and tx env are initialized properly before the next call to transact
, and make sure to do that in the processor, payload builder, etc.
crates/revm/src/state_change.rs
Outdated
// TODO: re-evaluate this after 4788 implementers call, this is to prevent EIP161 state | ||
// clearing of the system address, since it is touched during transact. The pyspec | ||
// tests currently require the state to remain empty if it started empty, which | ||
// somewhat contradicts EIP161, and clients still need consensus on what to do here. | ||
state.remove(&SYSTEM_ADDRESS); | ||
state.remove(&evm.env.block.coinbase); |
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 think this current way makes sense? My default way of doing this EIP would've been w/o a smart contract but with direct state surgery, and that would involve no system address. So my intuition is that the system address should not be anywhere outside of this kind of weird functions.
72fe343
to
4d487f2
Compare
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
50c9996
to
ae9c5cc
Compare
This is #4438 but using the new revm API (#3512). Adds a new method
apply_pre_block_call
which applies the cancun beacon block root contract call.