Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
klkvr committed Dec 6, 2024
1 parent 55f931d commit 7777630
Show file tree
Hide file tree
Showing 23 changed files with 278 additions and 112 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion crates/e2e-test-utils/src/engine_api.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::traits::PayloadEnvelopeExt;
use alloy_primitives::B256;
use alloy_primitives::{B256, U256};
use alloy_rpc_types_engine::{ForkchoiceState, PayloadStatusEnum};
use jsonrpsee::{
core::client::ClientT,
Expand Down Expand Up @@ -67,6 +67,7 @@ impl<E: EngineTypes, ChainSpec: EthereumHardforks> EngineApiTestContext<E, Chain
versioned_hashes,
payload_builder_attributes.parent_beacon_block_root().unwrap(),
requests,
U256::from(payload_builder_attributes.target_blobs_per_block().unwrap()),
)
.await?
} else {
Expand Down
4 changes: 2 additions & 2 deletions crates/e2e-test-utils/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ pub async fn setup<N>(
num_nodes: usize,
chain_spec: Arc<N::ChainSpec>,
is_dev: bool,
attributes_generator: impl Fn(u64) -> <<N as NodeTypesWithEngine>::Engine as PayloadTypes>::PayloadBuilderAttributes + Copy + 'static,
attributes_generator: impl Fn(Arc<N::ChainSpec>, u64) -> <<N as NodeTypesWithEngine>::Engine as PayloadTypes>::PayloadBuilderAttributes + Copy + 'static,
) -> eyre::Result<(Vec<NodeHelperType<N>>, TaskManager, Wallet)>
where
N: Default + Node<TmpNodeAdapter<N>> + NodeTypesForTree + NodeTypesWithEngine,
Expand Down Expand Up @@ -113,7 +113,7 @@ pub async fn setup_engine<N>(
num_nodes: usize,
chain_spec: Arc<N::ChainSpec>,
is_dev: bool,
attributes_generator: impl Fn(u64) -> <<N as NodeTypesWithEngine>::Engine as PayloadTypes>::PayloadBuilderAttributes + Copy + 'static,
attributes_generator: impl Fn(Arc<N::ChainSpec>, u64) -> <<N as NodeTypesWithEngine>::Engine as PayloadTypes>::PayloadBuilderAttributes + Copy + 'static,
) -> eyre::Result<(
Vec<NodeHelperType<N, BlockchainProvider2<NodeTypesWithDBAdapter<N, TmpDB>>>>,
TaskManager,
Expand Down
8 changes: 6 additions & 2 deletions crates/e2e-test-utils/src/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use reth_provider::{
};
use reth_rpc_eth_api::helpers::{EthApiSpec, EthTransactions, TraceExt};
use reth_stages_types::StageId;
use std::{marker::PhantomData, pin::Pin};
use std::{marker::PhantomData, pin::Pin, sync::Arc};
use tokio_stream::StreamExt;
use url::Url;

Expand Down Expand Up @@ -61,10 +61,14 @@ where
/// Creates a new test node
pub async fn new(
node: FullNode<Node, AddOns>,
attributes_generator: impl Fn(u64) -> Engine::PayloadBuilderAttributes + 'static,
attributes_generator: impl Fn(Arc<<Node::Types as NodeTypes>::ChainSpec>, u64) -> Engine::PayloadBuilderAttributes
+ 'static,
) -> eyre::Result<Self> {
let builder = node.payload_builder.clone();
let chain_spec = node.chain_spec();

let attributes_generator =
move |timestamp| attributes_generator(chain_spec.clone(), timestamp);
Ok(Self {
inner: node.clone(),
payload: PayloadTestContext::new(builder, attributes_generator).await?,
Expand Down
1 change: 1 addition & 0 deletions crates/engine/local/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ reth-transaction-pool.workspace = true
reth-stages-api.workspace = true

# alloy
alloy-eips.workspace = true
alloy-consensus.workspace = true
alloy-primitives.workspace = true
alloy-rpc-types-engine.workspace = true
Expand Down
11 changes: 9 additions & 2 deletions crates/engine/local/src/payload.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//! The implementation of the [`PayloadAttributesBuilder`] for the
//! [`LocalEngineService`](super::service::LocalEngineService).
use alloy_eips::eip4844;
use alloy_primitives::{Address, B256};
use reth_chainspec::EthereumHardforks;
use reth_ethereum_engine_primitives::EthPayloadAttributes;
Expand Down Expand Up @@ -39,8 +40,14 @@ where
.chain_spec
.is_cancun_active_at_timestamp(timestamp)
.then(B256::random),
target_blobs_per_block: None,
max_blobs_per_block: None,
target_blobs_per_block: self
.chain_spec
.is_prague_active_at_timestamp(timestamp)
.then_some(eip4844::TARGET_BLOBS_PER_BLOCK),
max_blobs_per_block: self
.chain_spec
.is_prague_active_at_timestamp(timestamp)
.then_some(eip4844::MAX_BLOBS_PER_BLOCK as u64),
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions crates/engine/util/src/reorg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -421,8 +421,8 @@ where
blob_gas_used: blob_gas_used.map(Into::into),
excess_blob_gas: excess_blob_gas.map(Into::into),
state_root: state_provider.state_root(hashed_state)?,
requests_hash: None, // TODO(prague)
target_blobs_per_block: None, // TODO(prague)
requests_hash: None, // TODO(prague)
target_blobs_per_block: reorg_target.header.target_blobs_per_block,
},
body: BlockBody {
transactions,
Expand Down
10 changes: 10 additions & 0 deletions crates/ethereum/engine-primitives/src/payload.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,10 @@ pub struct EthPayloadBuilderAttributes {
pub withdrawals: Withdrawals,
/// Root of the parent beacon block
pub parent_beacon_block_root: Option<B256>,
/// Target blobs per block for the generated payload
pub target_blobs_per_block: Option<u64>,
/// Max blobs per block for the generated payload
pub max_blobs_per_block: Option<u64>,
}

// === impl EthPayloadBuilderAttributes ===
Expand All @@ -229,6 +233,8 @@ impl EthPayloadBuilderAttributes {
prev_randao: attributes.prev_randao,
withdrawals: attributes.withdrawals.unwrap_or_default().into(),
parent_beacon_block_root: attributes.parent_beacon_block_root,
target_blobs_per_block: attributes.target_blobs_per_block,
max_blobs_per_block: attributes.max_blobs_per_block,
}
}
}
Expand Down Expand Up @@ -275,6 +281,10 @@ impl PayloadBuilderAttributes for EthPayloadBuilderAttributes {
fn withdrawals(&self) -> &Withdrawals {
&self.withdrawals
}

fn target_blobs_per_block(&self) -> Option<u64> {
self.target_blobs_per_block
}
}

/// Generates the payload id for the configured payload from the [`PayloadAttributes`].
Expand Down
16 changes: 12 additions & 4 deletions crates/ethereum/node/tests/e2e/utils.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use alloy_eips::{BlockId, BlockNumberOrTag};
use alloy_eips::{eip4844, BlockId, BlockNumberOrTag};
use alloy_primitives::{bytes, Address, B256};
use alloy_provider::{
network::{
Expand All @@ -10,6 +10,7 @@ use alloy_rpc_types_engine::PayloadAttributes;
use alloy_rpc_types_eth::TransactionRequest;
use alloy_signer::SignerSync;
use rand::{seq::SliceRandom, Rng};
use reth_chainspec::EthereumHardforks;
use reth_e2e_test_utils::{wallet::Wallet, NodeHelperType, TmpDB};
use reth_node_api::NodeTypesWithDBAdapter;
use reth_node_ethereum::EthereumNode;
Expand All @@ -19,15 +20,22 @@ use reth_provider::FullProvider;
use revm::primitives::{AccessListItem, Authorization};

/// Helper function to create a new eth payload attributes
pub(crate) fn eth_payload_attributes(timestamp: u64) -> EthPayloadBuilderAttributes {
pub(crate) fn eth_payload_attributes(
chain_spec: impl EthereumHardforks,
timestamp: u64,
) -> EthPayloadBuilderAttributes {
let attributes = PayloadAttributes {
timestamp,
prev_randao: B256::ZERO,
suggested_fee_recipient: Address::ZERO,
withdrawals: Some(vec![]),
parent_beacon_block_root: Some(B256::ZERO),
target_blobs_per_block: None,
max_blobs_per_block: None,
target_blobs_per_block: chain_spec
.is_prague_active_at_timestamp(timestamp)
.then_some(eip4844::TARGET_BLOBS_PER_BLOCK),
max_blobs_per_block: chain_spec
.is_prague_active_at_timestamp(timestamp)
.then_some(eip4844::MAX_BLOBS_PER_BLOCK as u64),
};
EthPayloadBuilderAttributes::new(B256::ZERO, attributes)
}
Expand Down
21 changes: 12 additions & 9 deletions crates/ethereum/payload/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,11 @@

use alloy_consensus::{Header, EMPTY_OMMER_ROOT_HASH};
use alloy_eips::{
eip4844::MAX_DATA_GAS_PER_BLOCK, eip7002::WITHDRAWAL_REQUEST_TYPE,
eip7251::CONSOLIDATION_REQUEST_TYPE, eip7685::Requests, merge::BEACON_NONCE,
eip4844::{self},
eip7002::WITHDRAWAL_REQUEST_TYPE,
eip7251::CONSOLIDATION_REQUEST_TYPE,
eip7685::Requests,
merge::BEACON_NONCE,
};
use alloy_primitives::U256;
use reth_basic_payload_builder::{
Expand Down Expand Up @@ -173,6 +176,9 @@ where
let mut cumulative_gas_used = 0;
let mut sum_blob_gas_used = 0;
let block_gas_limit: u64 = initialized_block_env.gas_limit.to::<u64>();
let blob_gas_limit =
attributes.max_blobs_per_block.unwrap_or(eip4844::MAX_BLOBS_PER_BLOCK as u64) *
eip4844::DATA_GAS_PER_BLOB;
let base_fee = initialized_block_env.basefee.to::<u64>();

let mut executed_txs = Vec::new();
Expand Down Expand Up @@ -250,18 +256,15 @@ where
// the EIP-4844 can still fit in the block
if let Some(blob_tx) = tx.transaction.as_eip4844() {
let tx_blob_gas = blob_tx.blob_gas();
if sum_blob_gas_used + tx_blob_gas > MAX_DATA_GAS_PER_BLOCK {
if sum_blob_gas_used + tx_blob_gas > blob_gas_limit {
// we can't fit this _blob_ transaction into the block, so we mark it as
// invalid, which removes its dependent transactions from
// the iterator. This is similar to the gas limit condition
// for regular transactions above.
trace!(target: "payload_builder", tx=?tx.hash, ?sum_blob_gas_used, ?tx_blob_gas, "skipping blob transaction because it would exceed the max data gas per block");
best_txs.mark_invalid(
&pool_tx,
InvalidPoolTransactionError::ExceedsGasLimit(
tx_blob_gas,
MAX_DATA_GAS_PER_BLOCK,
),
InvalidPoolTransactionError::ExceedsGasLimit(tx_blob_gas, blob_gas_limit),
);
continue
}
Expand Down Expand Up @@ -309,7 +312,7 @@ where
sum_blob_gas_used += tx_blob_gas;

// if we've reached the max data gas per block, we can skip blob txs entirely
if sum_blob_gas_used == MAX_DATA_GAS_PER_BLOCK {
if sum_blob_gas_used == blob_gas_limit {
best_txs.skip_blobs();
}
}
Expand Down Expand Up @@ -475,7 +478,7 @@ where
blob_gas_used: blob_gas_used.map(Into::into),
excess_blob_gas: excess_blob_gas.map(Into::into),
requests_hash,
target_blobs_per_block: None,
target_blobs_per_block: attributes.target_blobs_per_block,
};

let withdrawals = chain_spec
Expand Down
8 changes: 7 additions & 1 deletion crates/optimism/node/src/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ use reth_node_api::{
EngineObjectValidationError, MessageValidationKind, PayloadOrAttributes, PayloadTypes,
VersionSpecificValidationError,
},
validate_version_specific_fields, EngineTypes, EngineValidator,
validate_eip7742_fields_presence, validate_version_specific_fields, EngineTypes,
EngineValidator,
};
use reth_optimism_chainspec::OpChainSpec;
use reth_optimism_forks::{OpHardfork, OpHardforks};
Expand Down Expand Up @@ -101,6 +102,11 @@ where
payload_or_attrs.message_validation_kind(),
payload_or_attrs.timestamp(),
payload_or_attrs.parent_beacon_block_root().is_some(),
)?;
validate_eip7742_fields_presence(
version,
payload_or_attrs.message_validation_kind(),
payload_or_attrs.target_blobs_per_block().is_some(),
)
}

Expand Down
15 changes: 12 additions & 3 deletions crates/optimism/node/src/utils.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use crate::{OpBuiltPayload, OpNode as OtherOpNode, OpPayloadBuilderAttributes};
use alloy_eips::eip4844;
use alloy_genesis::Genesis;
use alloy_primitives::{Address, B256};
use alloy_rpc_types_engine::PayloadAttributes;
use reth_chainspec::EthereumHardforks;
use reth_e2e_test_utils::{transaction::TransactionTestContext, wallet::Wallet, NodeHelperType};
use reth_optimism_chainspec::OpChainSpecBuilder;
use reth_payload_builder::EthPayloadBuilderAttributes;
Expand Down Expand Up @@ -48,15 +50,22 @@ pub async fn advance_chain(
}

/// Helper function to create a new eth payload attributes
pub fn optimism_payload_attributes(timestamp: u64) -> OpPayloadBuilderAttributes {
pub fn optimism_payload_attributes(
chain_spec: impl EthereumHardforks,
timestamp: u64,
) -> OpPayloadBuilderAttributes {
let attributes = PayloadAttributes {
timestamp,
prev_randao: B256::ZERO,
suggested_fee_recipient: Address::ZERO,
withdrawals: Some(vec![]),
parent_beacon_block_root: Some(B256::ZERO),
target_blobs_per_block: None,
max_blobs_per_block: None,
target_blobs_per_block: chain_spec
.is_prague_active_at_timestamp(timestamp)
.then_some(eip4844::TARGET_BLOBS_PER_BLOCK),
max_blobs_per_block: chain_spec
.is_prague_active_at_timestamp(timestamp)
.then_some(eip4844::MAX_BLOBS_PER_BLOCK as u64),
};

OpPayloadBuilderAttributes {
Expand Down
6 changes: 6 additions & 0 deletions crates/optimism/payload/src/payload.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ impl PayloadBuilderAttributes for OpPayloadBuilderAttributes {
prev_randao: attributes.payload_attributes.prev_randao,
withdrawals: attributes.payload_attributes.withdrawals.unwrap_or_default().into(),
parent_beacon_block_root: attributes.payload_attributes.parent_beacon_block_root,
target_blobs_per_block: attributes.payload_attributes.target_blobs_per_block,
max_blobs_per_block: attributes.payload_attributes.max_blobs_per_block,
};

Ok(Self {
Expand Down Expand Up @@ -127,6 +129,10 @@ impl PayloadBuilderAttributes for OpPayloadBuilderAttributes {
fn withdrawals(&self) -> &Withdrawals {
&self.payload_attributes.withdrawals
}

fn target_blobs_per_block(&self) -> Option<u64> {
self.payload_attributes.target_blobs_per_block
}
}

/// Contains the built payload.
Expand Down
7 changes: 7 additions & 0 deletions crates/payload/basic/src/stack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,13 @@ where
Self::Right(r) => r.withdrawals(),
}
}

fn target_blobs_per_block(&self) -> Option<u64> {
match self {
Self::Left(l) => l.target_blobs_per_block(),
Self::Right(r) => r.target_blobs_per_block(),
}
}
}

/// this structure enables the chaining of multiple `PayloadBuilder` implementations,
Expand Down
8 changes: 8 additions & 0 deletions crates/payload/primitives/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,14 @@ pub enum VersionSpecificValidationError {
/// root after Cancun
#[error("no parent beacon block root post-cancun")]
NoParentBeaconBlockRootPostCancun,
/// Thrown if the pre-V4 `PayloadAttributes` or `ExecutionPayload` contains a target blobs per
/// block field
#[error("target blobs per block not supported before V4")]
TargetBlobsPerBlockNotSupportedBeforeV4,
/// Thrown if the `PayloadAttributes` or `ExecutionPayload` contains no target blobs per block
/// field after Cancun
#[error("no target blobs per block post-Prague")]
NoTargetBlobsPerBlockPostPrague,
}

impl EngineObjectValidationError {
Expand Down
Loading

0 comments on commit 7777630

Please sign in to comment.