feat(op): Cancun support in payload builder and processor (#6731)

This commit is contained in:
clabby
2024-02-23 12:11:25 -07:00
committed by GitHub
parent be1ebeea62
commit 21bc1a861b
6 changed files with 107 additions and 44 deletions

33
Cargo.lock generated
View File

@ -173,7 +173,7 @@ dependencies = [
[[package]]
name = "alloy-eips"
version = "0.1.0"
source = "git+https://github.com/alloy-rs/alloy?rev=5062eaf#5062eaf1af2733a7115bc0536c9708a42bfb53ca"
source = "git+https://github.com/alloy-rs/alloy?rev=76c70fb#76c70fb9d44ace661bbf33408c2527e3874c964e"
dependencies = [
"alloy-primitives",
"alloy-rlp",
@ -183,7 +183,7 @@ dependencies = [
[[package]]
name = "alloy-genesis"
version = "0.1.0"
source = "git+https://github.com/alloy-rs/alloy?rev=5062eaf#5062eaf1af2733a7115bc0536c9708a42bfb53ca"
source = "git+https://github.com/alloy-rs/alloy?rev=76c70fb#76c70fb9d44ace661bbf33408c2527e3874c964e"
dependencies = [
"alloy-primitives",
"alloy-rpc-types",
@ -205,7 +205,7 @@ dependencies = [
[[package]]
name = "alloy-node-bindings"
version = "0.1.0"
source = "git+https://github.com/alloy-rs/alloy?rev=5062eaf#5062eaf1af2733a7115bc0536c9708a42bfb53ca"
source = "git+https://github.com/alloy-rs/alloy?rev=76c70fb#76c70fb9d44ace661bbf33408c2527e3874c964e"
dependencies = [
"alloy-genesis",
"alloy-primitives",
@ -266,7 +266,7 @@ dependencies = [
[[package]]
name = "alloy-rpc-engine-types"
version = "0.1.0"
source = "git+https://github.com/alloy-rs/alloy?rev=5062eaf#5062eaf1af2733a7115bc0536c9708a42bfb53ca"
source = "git+https://github.com/alloy-rs/alloy?rev=76c70fb#76c70fb9d44ace661bbf33408c2527e3874c964e"
dependencies = [
"alloy-primitives",
"alloy-rlp",
@ -281,7 +281,7 @@ dependencies = [
[[package]]
name = "alloy-rpc-trace-types"
version = "0.1.0"
source = "git+https://github.com/alloy-rs/alloy?rev=5062eaf#5062eaf1af2733a7115bc0536c9708a42bfb53ca"
source = "git+https://github.com/alloy-rs/alloy?rev=76c70fb#76c70fb9d44ace661bbf33408c2527e3874c964e"
dependencies = [
"alloy-primitives",
"alloy-rpc-types",
@ -292,7 +292,7 @@ dependencies = [
[[package]]
name = "alloy-rpc-types"
version = "0.1.0"
source = "git+https://github.com/alloy-rs/alloy?rev=5062eaf#5062eaf1af2733a7115bc0536c9708a42bfb53ca"
source = "git+https://github.com/alloy-rs/alloy?rev=76c70fb#76c70fb9d44ace661bbf33408c2527e3874c964e"
dependencies = [
"alloy-primitives",
"alloy-rlp",
@ -7006,9 +7006,9 @@ dependencies = [
[[package]]
name = "revm"
version = "6.0.0"
version = "6.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8154cec6f8c4f543a379cf00a839cf47c67f405e8a92361a7791c55196c9b7e2"
checksum = "1d35316fc02d99e42831356c71e882f5d385c77b78f64a44ae82f2f9a4b8b72f"
dependencies = [
"auto_impl",
"cfg-if",
@ -7021,7 +7021,7 @@ dependencies = [
[[package]]
name = "revm-inspectors"
version = "0.1.0"
source = "git+https://github.com/paradigmxyz/evm-inspectors?rev=ac63f06#ac63f069977d04cd68d96fe7ad9dd4b74ceab44e"
source = "git+https://github.com/paradigmxyz/evm-inspectors?rev=75a187b#75a187ba967a29b30af2e5e848073c755068da06"
dependencies = [
"alloy-primitives",
"alloy-rpc-trace-types",
@ -7032,16 +7032,15 @@ dependencies = [
"boa_gc",
"colorchoice",
"revm",
"serde",
"serde_json",
"thiserror",
]
[[package]]
name = "revm-interpreter"
version = "3.0.0"
version = "3.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dff72cc825a9c44b28749a6181e21fa85ba45ac8d4b5732a7ded165a770ecbd9"
checksum = "8fa10c2dc1e8f4934bdc763a2c09371bcec29e50c22e55e3eb325ee0cba09064"
dependencies = [
"revm-primitives",
"serde",
@ -7049,12 +7048,11 @@ dependencies = [
[[package]]
name = "revm-precompile"
version = "4.0.1"
version = "4.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "186373108c0a46e47368752372cc721d4b0ab4886d6786d180ef9dbf4dd71865"
checksum = "db828d49d329560a70809d9d1fa0c74695edb49f50c5332db3eb24483076deac"
dependencies = [
"aurora-engine-modexp",
"blst",
"c-kzg",
"k256",
"once_cell",
@ -7067,15 +7065,14 @@ dependencies = [
[[package]]
name = "revm-primitives"
version = "2.0.1"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "093dc5df253eececaf03ffe0c12d3fd7ce5dea3342bc9de109d1aac2647ffa81"
checksum = "fecd125aad58e135e2ca5771ed6e4e7b1f05fa3a64e0dfb9cc643b7a800a8435"
dependencies = [
"alloy-primitives",
"auto_impl",
"bitflags 2.4.2",
"bitvec",
"blst",
"c-kzg",
"cfg-if",
"derive_more",

View File

@ -170,9 +170,9 @@ reth-transaction-pool = { path = "crates/transaction-pool" }
reth-trie = { path = "crates/trie" }
# revm
revm = { version = "6.0", features = ["std", "secp256k1"], default-features = false }
revm-primitives = { version = "2.0", features = ["std"], default-features = false }
revm-inspectors = { git = "https://github.com/paradigmxyz/evm-inspectors", rev = "ac63f06" }
revm = { version = "6.1.0", features = ["std", "secp256k1"], default-features = false }
revm-primitives = { version = "2.1.0", features = ["std"], default-features = false }
revm-inspectors = { git = "https://github.com/paradigmxyz/evm-inspectors", rev = "75a187b" }
# eth
alloy-chains = { version = "0.1", feature = ["serde", "rlp", "arbitrary"] }
@ -181,12 +181,12 @@ alloy-dyn-abi = "0.6"
alloy-sol-types = "0.6"
alloy-rlp = "0.3"
alloy-trie = "0.2"
alloy-rpc-types = { git = "https://github.com/alloy-rs/alloy", rev = "5062eaf" }
alloy-rpc-trace-types = { git = "https://github.com/alloy-rs/alloy", rev = "5062eaf" }
alloy-rpc-engine-types = { git = "https://github.com/alloy-rs/alloy", rev = "5062eaf" }
alloy-genesis = { git = "https://github.com/alloy-rs/alloy", rev = "5062eaf" }
alloy-node-bindings = { git = "https://github.com/alloy-rs/alloy", rev = "5062eaf" }
alloy-eips = { git = "https://github.com/alloy-rs/alloy", rev = "5062eaf" }
alloy-rpc-types = { git = "https://github.com/alloy-rs/alloy", rev = "76c70fb" }
alloy-rpc-trace-types = { git = "https://github.com/alloy-rs/alloy", rev = "76c70fb" }
alloy-rpc-engine-types = { git = "https://github.com/alloy-rs/alloy", rev = "76c70fb" }
alloy-genesis = { git = "https://github.com/alloy-rs/alloy", rev = "76c70fb" }
alloy-node-bindings = { git = "https://github.com/alloy-rs/alloy", rev = "76c70fb" }
alloy-eips = { git = "https://github.com/alloy-rs/alloy", rev = "76c70fb" }
ethers-core = { version = "2.0", default-features = false }
ethers-providers = { version = "2.0", default-features = false }
ethers-signers = { version = "2.0", default-features = false }

View File

@ -73,7 +73,7 @@ impl EthBuiltPayload {
self.into()
}
/// Converts the type into the response expected by `engine_getPayloadV2`
/// Converts the type into the response expected by `engine_getPayloadV3`
pub fn into_v3_payload(self) -> ExecutionPayloadEnvelopeV3 {
self.into()
}
@ -137,6 +137,10 @@ impl From<EthBuiltPayload> for ExecutionPayloadEnvelopeV3 {
// <https://github.com/ethereum/execution-apis/blob/fe8e13c288c592ec154ce25c534e26cb7ce0530d/src/engine/cancun.md#specification-2>
should_override_builder: false,
blobs_bundle: sidecars.into_iter().map(Into::into).collect::<Vec<_>>().into(),
// Optimism-specific: Post-cancun, the parent beacon block root is included in the
// enveloped payload. We set this as `None` here so that optimism-specific
// handling can fill the value.
parent_beacon_block_root: None,
}
}
}

View File

@ -21,6 +21,7 @@ mod builder {
};
use reth_primitives::{
constants::{BEACON_NONCE, EMPTY_RECEIPTS, EMPTY_TRANSACTIONS},
eip4844::calculate_excess_blob_gas,
proofs,
revm::env::tx_env_with_recovered,
Block, Hardfork, Header, IntoRecoveredTransaction, Receipt, Receipts, TxType,
@ -158,6 +159,25 @@ mod builder {
err
})?;
let mut excess_blob_gas = None;
let mut blob_gas_used = None;
if chain_spec.is_cancun_active_at_timestamp(attributes.payload_attributes.timestamp) {
excess_blob_gas = if chain_spec
.is_cancun_active_at_timestamp(parent_block.timestamp)
{
let parent_excess_blob_gas = parent_block.excess_blob_gas.unwrap_or_default();
let parent_blob_gas_used = parent_block.blob_gas_used.unwrap_or_default();
Some(calculate_excess_blob_gas(parent_excess_blob_gas, parent_blob_gas_used))
} else {
// for the first post-fork block, both parent.blob_gas_used and
// parent.excess_blob_gas are evaluated as 0
Some(calculate_excess_blob_gas(0, 0))
};
blob_gas_used = Some(0);
}
let header = Header {
parent_hash: parent_block.hash(),
ommers_hash: EMPTY_OMMER_ROOT_HASH,
@ -176,8 +196,8 @@ mod builder {
difficulty: U256::ZERO,
gas_used: 0,
extra_data,
blob_gas_used: None,
excess_blob_gas: None,
blob_gas_used,
excess_blob_gas,
parent_beacon_block_root: attributes.payload_attributes.parent_beacon_block_root,
};
@ -249,6 +269,16 @@ mod builder {
attributes.payload_attributes.timestamp,
);
// apply eip-4788 pre block contract call
pre_block_beacon_root_contract_call(
&mut db,
&chain_spec,
block_number,
&initialized_cfg,
&initialized_block_env,
&attributes,
)?;
// Ensure that the create2deployer is force-deployed at the canyon transition. Optimism
// blocks will always have at least a single transaction in them (the L1 info transaction),
// so we can safely assume that this will always be triggered upon the transition and that
@ -369,6 +399,13 @@ mod builder {
continue
}
// A sequencer's block should never contain blob transactions.
if pool_tx.tx_type() == TxType::EIP4844 as u8 {
return Err(PayloadBuilderError::other(
OptimismPayloadBuilderError::BlobTransactionRejected,
))
}
// check if the job was cancelled, if so we can exit early
if cancel.is_cancelled() {
return Ok(BuildOutcome::Cancelled)
@ -378,7 +415,6 @@ mod builder {
let tx = pool_tx.to_recovered_transaction();
// Configure the environment for the block.
let mut evm = revm::Evm::builder()
.with_db(&mut db)
.with_env_with_handler_cfg(EnvWithHandlerCfg::new_with_cfg_env(
@ -412,7 +448,7 @@ mod builder {
}
}
};
// to realease the db reference drop evm.
// drop evm so db is released.
drop(evm);
// commit changes
db.commit(state);
@ -454,7 +490,7 @@ mod builder {
&mut db,
&chain_spec,
attributes.payload_attributes.timestamp,
attributes.payload_attributes.withdrawals.clone(),
attributes.payload_attributes.withdrawals,
)?;
// merge all transitions into bundle state, this would apply the withdrawal balance changes
@ -481,10 +517,25 @@ mod builder {
// create the block header
let transactions_root = proofs::calculate_transaction_root(&executed_txs);
// Cancun is not yet active on Optimism chains.
// initialize empty blob sidecars. There are no blob transactions on L2.
let blob_sidecars = Vec::new();
let excess_blob_gas = None;
let blob_gas_used = None;
let mut excess_blob_gas = None;
let mut blob_gas_used = None;
// only determine cancun fields when active
if chain_spec.is_cancun_active_at_timestamp(attributes.payload_attributes.timestamp) {
excess_blob_gas = if chain_spec.is_cancun_active_at_timestamp(parent_block.timestamp) {
let parent_excess_blob_gas = parent_block.excess_blob_gas.unwrap_or_default();
let parent_blob_gas_used = parent_block.blob_gas_used.unwrap_or_default();
Some(calculate_excess_blob_gas(parent_excess_blob_gas, parent_blob_gas_used))
} else {
// for the first post-fork block, both parent.blob_gas_used and
// parent.excess_blob_gas are evaluated as 0
Some(calculate_excess_blob_gas(0, 0))
};
blob_gas_used = Some(0);
}
let header = Header {
parent_hash: parent_block.hash(),
@ -515,11 +566,8 @@ mod builder {
let sealed_block = block.seal_slow();
debug!(target: "payload_builder", ?sealed_block, "sealed built block");
let mut payload = EthBuiltPayload::new(
attributes.payload_attributes.payload_id(),
sealed_block,
total_fees,
);
let mut payload =
EthBuiltPayload::new(attributes.payload_attributes.id, sealed_block, total_fees);
// extend the payload with the blob sidecars from the executed txs
payload.extend_sidecars(blob_sidecars);

View File

@ -156,7 +156,9 @@ pub fn fill_tx_env_with_beacon_root_contract_call(env: &mut Env, parent_beacon_b
source_hash: None,
mint: None,
is_system_transaction: Some(false),
enveloped_tx: None,
// The L1 fee is not charged for the EIP-4788 transaction, submit zero bytes for the
// enveloped tx size.
enveloped_tx: Some(Bytes::default()),
},
};

View File

@ -265,13 +265,25 @@ where
)?;
// Now resolve the payload
Ok(self
let mut resolved_payload = self
.inner
.payload_store
.resolve(payload_id)
.await
.ok_or(EngineApiError::UnknownPayload)?
.map(|payload| payload.into_v3_payload())?)
.map(|payload| payload.into_v3_payload())?;
// After `Cancun` is enabled on optimism, an extra field `parent_beacon_block_root` is
// included in the enveloped V3 payload. On ethereum, this field is not included.
if self.inner.chain_spec.is_optimism() &&
self.inner
.chain_spec
.is_fork_active_at_timestamp(Hardfork::Cancun, attributes.timestamp())
{
resolved_payload.parent_beacon_block_root = attributes.parent_beacon_block_root();
}
Ok(resolved_payload)
}
/// Returns the execution payload bodies by the range starting at `start`, containing `count`