feat: return executed block in eth payload builder (#10717)

This commit is contained in:
Håvard Anda Estensen
2024-09-07 11:27:38 +02:00
committed by GitHub
parent 162f6019d4
commit e7defb2334
7 changed files with 52 additions and 9 deletions

2
Cargo.lock generated
View File

@ -7092,6 +7092,7 @@ name = "reth-ethereum-engine-primitives"
version = "1.0.6"
dependencies = [
"alloy-rlp",
"reth-chain-state",
"reth-chainspec",
"reth-engine-primitives",
"reth-evm-ethereum",
@ -7129,6 +7130,7 @@ name = "reth-ethereum-payload-builder"
version = "1.0.6"
dependencies = [
"reth-basic-payload-builder",
"reth-chain-state",
"reth-errors",
"reth-evm",
"reth-evm-ethereum",

View File

@ -21,6 +21,7 @@ reth-rpc-types.workspace = true
reth-rpc-types-compat.workspace = true
revm-primitives.workspace = true
alloy-rlp.workspace = true
reth-chain-state.workspace = true
# misc
serde.workspace = true

View File

@ -1,6 +1,7 @@
//! Contains types required for building a payload.
use alloy_rlp::Encodable;
use reth_chain_state::ExecutedBlock;
use reth_chainspec::ChainSpec;
use reth_evm_ethereum::revm_spec_by_timestamp_after_merge;
use reth_payload_primitives::{BuiltPayload, PayloadBuilderAttributes};
@ -30,6 +31,8 @@ pub struct EthBuiltPayload {
pub(crate) id: PayloadId,
/// The built block
pub(crate) block: SealedBlock,
/// Block execution data for the payload, if any.
pub(crate) executed_block: Option<ExecutedBlock>,
/// The fees of the block
pub(crate) fees: U256,
/// The blobs, proofs, and commitments in the block. If the block is pre-cancun, this will be
@ -48,8 +51,9 @@ impl EthBuiltPayload {
block: SealedBlock,
fees: U256,
receipts: Vec<Receipt>,
executed_block: Option<ExecutedBlock>,
) -> Self {
Self { id, block, fees, sidecars: Vec::new(), receipts }
Self { id, block, executed_block, fees, sidecars: Vec::new(), receipts }
}
/// Returns the identifier of the payload.
@ -87,6 +91,10 @@ impl BuiltPayload for EthBuiltPayload {
self.fees
}
fn executed_block(&self) -> Option<ExecutedBlock> {
self.executed_block.clone()
}
fn receipts(&self) -> &[Receipt] {
&self.receipts
}
@ -101,6 +109,10 @@ impl<'a> BuiltPayload for &'a EthBuiltPayload {
(**self).fees()
}
fn executed_block(&self) -> Option<ExecutedBlock> {
self.executed_block.clone()
}
fn receipts(&self) -> &[Receipt] {
&self.receipts
}

View File

@ -24,6 +24,7 @@ reth-evm.workspace = true
reth-evm-ethereum.workspace = true
reth-errors.workspace = true
reth-trie.workspace = true
reth-chain-state.workspace = true
# ethereum
revm.workspace = true

View File

@ -13,6 +13,7 @@ use reth_basic_payload_builder::{
commit_withdrawals, is_better_payload, BuildArguments, BuildOutcome, PayloadBuilder,
PayloadConfig, WithdrawalsOutcome,
};
use reth_chain_state::ExecutedBlock;
use reth_errors::RethError;
use reth_evm::{
system_calls::{
@ -45,6 +46,7 @@ use revm::{
primitives::{EVMError, EnvWithHandlerCfg, InvalidTransaction, ResultAndState},
DatabaseCommit, State,
};
use std::sync::Arc;
use tracing::{debug, trace, warn};
/// Ethereum payload builder
@ -255,7 +257,13 @@ where
let block = Block { header, body: vec![], ommers: vec![], withdrawals, requests };
let sealed_block = block.seal_slow();
Ok(EthBuiltPayload::new(attributes.payload_id(), sealed_block, U256::ZERO, Vec::new()))
Ok(EthBuiltPayload::new(
attributes.payload_id(),
sealed_block,
U256::ZERO,
Vec::new(),
None,
))
}
}
@ -298,6 +306,7 @@ where
let base_fee = initialized_block_env.basefee.to::<u64>();
let mut executed_txs = Vec::new();
let mut executed_senders = Vec::new();
let mut best_txs = pool.best_transactions_with_attributes(BestTransactionsAttributes::new(
base_fee,
@ -444,7 +453,8 @@ where
.expect("fee is always valid; execution succeeded");
total_fees += U256::from(miner_fee) * U256::from(gas_used);
// append transaction to the list of executed transactions
// append sender and transaction to the respective lists
executed_senders.push(tx.signer());
executed_txs.push(tx.into_signed());
}
@ -500,11 +510,16 @@ where
let logs_bloom = execution_outcome.block_logs_bloom(block_number).expect("Number is in range");
// calculate the state root
let state_root = {
let hashed_state = HashedPostState::from_bundle_state(&execution_outcome.state().state);
let (state_root, trie_output) = {
let state_provider = db.database.0.inner.borrow_mut();
state_provider
.db
.state_root(HashedPostState::from_bundle_state(&execution_outcome.state().state))?
state_provider.db.state_root_with_updates(hashed_state.clone()).inspect_err(|err| {
warn!(target: "payload_builder",
parent_hash=%parent_block.hash(),
%err,
"failed to calculate state root for empty payload"
);
})?
};
// create the block header
@ -566,7 +581,18 @@ where
debug!(target: "payload_builder", ?sealed_block, "sealed built block");
let receipts_pay: Vec<Receipt> = receipts.into_iter().flatten().collect();
let mut payload = EthBuiltPayload::new(attributes.id, sealed_block, total_fees, receipts_pay);
// create the executed block data
let executed = ExecutedBlock {
block: Arc::new(sealed_block.clone()),
senders: Arc::new(executed_senders),
execution_output: Arc::new(execution_outcome),
hashed_state: Arc::new(hashed_state),
trie: Arc::new(trie_output),
};
let mut payload =
EthBuiltPayload::new(attributes.id, sealed_block, total_fees, receipts_pay, Some(executed));
// extend the payload with the blob sidecars from the executed txs
payload.extend_sidecars(blob_sidecars);

View File

@ -65,7 +65,7 @@
//! },
//! ..Default::default()
//! };
//! let payload = EthBuiltPayload::new(self.attributes.id, payload.seal_slow(), U256::ZERO, Vec::new());
//! let payload = EthBuiltPayload::new(self.attributes.id, payload.seal_slow(), U256::ZERO, Vec::new(), None);
//! Ok(payload)
//! }
//!

View File

@ -87,6 +87,7 @@ impl PayloadJob for TestPayloadJob {
Block::default().seal_slow(),
U256::ZERO,
Vec::new(),
None,
))
}