Skip to content
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

chore: remove all reth types #752

Merged
merged 2 commits into from
Jan 30, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 26 additions & 32 deletions bolt-sidecar/src/builder/compat.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use alloy::{
consensus::BlockHeader,
consensus::{transaction::PooledTransaction, Block, BlockHeader},
eips::{eip2718::Encodable2718, eip4895::Withdrawal},
primitives::{Address, Bloom, B256, U256},
rpc::types::Withdrawals,
Expand All @@ -19,14 +19,12 @@ use ethereum_consensus::{
ssz::prelude::{ssz_rs, ByteList, ByteVector, HashTreeRoot, List},
types::mainnet::ExecutionPayload as ConsensusExecutionPayload,
};
use reth_primitives::{SealedBlock, TransactionSigned};
use reth_primitives_traits::BlockBody;

/// Compatibility: convert a sealed header into an ethereum-consensus execution payload header.
/// This requires recalculating the withdrals and transactions roots as SSZ instead of MPT roots.
pub(crate) fn to_execution_payload_header(
sealed_block: &SealedBlock,
transactions: Vec<TransactionSigned>,
sealed_block: &Block<PooledTransaction>,
transactions: Vec<PooledTransaction>,
) -> ConsensusExecutionPayloadHeader {
// Transactions and withdrawals are treated as opaque byte arrays in consensus types
let transactions_bytes = transactions.iter().map(|t| t.encoded_2718()).collect::<Vec<_>>();
Expand All @@ -42,15 +40,15 @@ pub(crate) fn to_execution_payload_header(
let mut withdrawals_ssz: List<ConsensusWithdrawal, MAX_WITHDRAWALS_PER_PAYLOAD> =
List::default();

if let Some(withdrawals) = sealed_block.body().withdrawals.as_ref() {
if let Some(withdrawals) = sealed_block.body.withdrawals.as_ref() {
for w in withdrawals {
withdrawals_ssz.push(to_consensus_withdrawal(w));
}
}

let withdrawals_root = withdrawals_ssz.hash_tree_root().expect("valid withdrawals root");

let header = sealed_block.header();
let header = &sealed_block.header;

ConsensusExecutionPayloadHeader {
parent_hash: to_bytes32(header.parent_hash),
Expand All @@ -75,37 +73,31 @@ pub(crate) fn to_execution_payload_header(

/// Compatibility: convert a sealed block into an Alloy execution payload
pub(crate) fn to_alloy_execution_payload(
block: &SealedBlock,
block: &Block<PooledTransaction>,
block_hash: B256,
) -> ExecutionPayloadV3 {
let alloy_withdrawals = block
.body()
.withdrawals
.as_ref()
.map(|withdrawals| {
withdrawals
.iter()
.map(|w| Withdrawal {
index: w.index,
validator_index: w.validator_index,
address: w.address,
amount: w.amount,
})
.collect::<Vec<_>>()
})
.unwrap_or_default();
let alloy_withdrawals =
block.body.withdrawals.clone().map(|w| w.into_inner()).unwrap_or_default();

let transactions = block
.body
.transactions
.iter()
.map(|tx| tx.encoded_2718())
.map(Into::into)
.collect::<Vec<_>>();

ExecutionPayloadV3 {
blob_gas_used: block.blob_gas_used().unwrap_or_default(),
excess_blob_gas: block.excess_blob_gas.unwrap_or_default(),
payload_inner: ExecutionPayloadV2 {
payload_inner: ExecutionPayloadV1 {
base_fee_per_gas: U256::from(block.base_fee_per_gas.unwrap_or_default()),
block_hash,
transactions,
base_fee_per_gas: U256::from(block.base_fee_per_gas.unwrap_or_default()),
block_number: block.number,
extra_data: block.extra_data.clone(),
transactions: block.body().encoded_2718_transactions(),
fee_recipient: block.header().beneficiary,
fee_recipient: block.header.beneficiary,
gas_limit: block.gas_limit,
gas_used: block.gas_used,
logs_bloom: block.logs_bloom,
Expand All @@ -121,11 +113,13 @@ pub(crate) fn to_alloy_execution_payload(
}

/// Compatibility: convert a sealed block into an ethereum-consensus execution payload
pub(crate) fn to_consensus_execution_payload(value: &SealedBlock) -> ConsensusExecutionPayload {
let hash = value.hash();
let header = value.header();
let transactions = &value.body().transactions;
let withdrawals = &value.body().withdrawals;
pub(crate) fn to_consensus_execution_payload(
value: &Block<PooledTransaction>,
) -> ConsensusExecutionPayload {
let hash = value.hash_slow();
let header = &value.header;
let transactions = &value.body.transactions;
let withdrawals = &value.body.withdrawals;
let transactions = transactions
.iter()
.map(|t| spec::Transaction::try_from(t.encoded_2718().as_ref()).unwrap())
Expand Down
25 changes: 11 additions & 14 deletions bolt-sidecar/src/builder/fallback/engine_hinter.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
use std::ops::Deref;

use alloy::{
consensus::{Header, EMPTY_OMMER_ROOT_HASH},
consensus::{transaction::PooledTransaction, Block, BlockBody, Header, EMPTY_OMMER_ROOT_HASH},
primitives::{Address, Bloom, Bytes, B256, B64, U256},
rpc::types::{Block, Withdrawal, Withdrawals},
rpc::types::{Block as RpcBlock, Withdrawal, Withdrawals},
};
use alloy_provider::ext::EngineApi;
use alloy_rpc_types_engine::{ClientCode, ExecutionPayloadV3, JwtSecret, PayloadStatusEnum};
use reqwest::Url;
use reth_primitives::{BlockBody, SealedBlock, SealedHeader, TransactionSigned};
use tracing::{debug, error};

use crate::{
Expand Down Expand Up @@ -52,7 +51,7 @@ impl EngineHinter {
pub async fn fetch_payload_from_hints(
&self,
mut ctx: EngineHinterContext,
) -> Result<SealedBlock, BuilderError> {
) -> Result<Block<PooledTransaction>, BuilderError> {
// The block body can be the same for all iterations, since it only contains
// the transactions and withdrawals from the context.
let body = ctx.build_block_body();
Expand All @@ -66,20 +65,18 @@ impl EngineHinter {
// Build a new block header using the hints from the context
let header = ctx.build_block_header_with_hints();

let sealed_hash = header.hash_slow();
let sealed_header = SealedHeader::new(header, sealed_hash);
let sealed_block = SealedBlock::new(sealed_header, body.clone());
let block_hash = ctx.hints.block_hash.unwrap_or(sealed_block.hash());
let block = Block { header, body: body.clone() };
let block_hash = ctx.hints.block_hash.unwrap_or(block.hash_slow());

// build the new execution payload from the block header
let exec_payload = to_alloy_execution_payload(&sealed_block, block_hash);
let exec_payload = to_alloy_execution_payload(&block, block_hash);

// attempt to fetch the next hint from the engine API payload response
let hint = self.next_hint(exec_payload, &ctx).await?;
debug!(?hint, "Received hint from engine API");

if matches!(hint, EngineApiHint::ValidPayload) {
return Ok(sealed_block);
return Ok(block);
}

// Populate the new hint in the context and continue the loop
Expand Down Expand Up @@ -206,17 +203,17 @@ pub struct EngineHinterContext {
pub parent_beacon_block_root: B256,
pub blob_versioned_hashes: Vec<B256>,
pub block_timestamp: u64,
pub transactions: Vec<TransactionSigned>,
pub transactions: Vec<PooledTransaction>,
pub withdrawals: Vec<Withdrawal>,
pub head_block: Block,
pub head_block: RpcBlock,
pub hints: Hints,
pub el_client_code: ClientCode,
}

impl EngineHinterContext {
/// Build a block body using the transactions and withdrawals from the context.
pub fn build_block_body(&self) -> BlockBody {
BlockBody {
pub fn build_block_body(&self) -> BlockBody<PooledTransaction> {
BlockBody::<PooledTransaction> {
ommers: Vec::new(),
transactions: self.transactions.clone(),
withdrawals: Some(Withdrawals::new(self.withdrawals.clone())),
Expand Down
14 changes: 6 additions & 8 deletions bolt-sidecar/src/builder/fallback/payload_builder.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
use alloy::{
consensus::{proofs, Transaction},
consensus::{proofs, transaction::PooledTransaction, Block, Transaction},
eips::{calc_excess_blob_gas, calc_next_block_base_fee, eip1559::BaseFeeParams},
primitives::{Address, Bytes},
};
use reth_primitives::{SealedBlock, TransactionSigned};
use tracing::debug;

use super::{
Expand Down Expand Up @@ -62,8 +61,8 @@ impl FallbackPayloadBuilder {
pub async fn build_fallback_payload(
&self,
target_slot: u64,
transactions: &[TransactionSigned],
) -> Result<SealedBlock, BuilderError> {
transactions: &[PooledTransaction],
) -> Result<Block<PooledTransaction>, BuilderError> {
// Fetch the latest block to get the necessary parent values for the new block.
// For the timestamp, we must use the one expected by the beacon chain instead, to
// prevent edge cases where the proposer before us has missed their slot and therefore
Expand Down Expand Up @@ -145,15 +144,14 @@ mod tests {
use std::time::{SystemTime, UNIX_EPOCH};

use alloy::{
consensus::{constants, proofs},
consensus::{constants, proofs, transaction::PooledTransaction},
eips::eip2718::{Decodable2718, Encodable2718},
network::{EthereumWallet, TransactionBuilder},
primitives::{hex, Address},
providers::{Provider, ProviderBuilder},
signers::{k256::ecdsa::SigningKey, local::PrivateKeySigner},
};
use beacon_api_client::mainnet::Client as BeaconClient;
use reth_primitives::TransactionSigned;
use tracing::warn;

use crate::{
Expand Down Expand Up @@ -192,15 +190,15 @@ mod tests {
let tx = default_test_transaction(addy, Some(nonce)).with_chain_id(17000);
let tx_signed = tx.build(&wallet).await?;
let raw_encoded = tx_signed.encoded_2718();
let tx_signed_reth = TransactionSigned::decode_2718(&mut raw_encoded.as_slice())?;
let tx_signed_reth = PooledTransaction::decode_2718(&mut raw_encoded.as_slice())?;

let slot = genesis_time +
(SystemTime::now().duration_since(UNIX_EPOCH)?.as_secs() / cfg.chain.slot_time()) +
1;

let block = builder.build_fallback_payload(slot, &[tx_signed_reth]).await?;

assert_eq!(block.body().transactions.len(), 1);
assert_eq!(block.body.transactions.len(), 1);

Ok(())
}
Expand Down
7 changes: 3 additions & 4 deletions bolt-sidecar/src/builder/template.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
use alloy::{
consensus::Transaction,
consensus::{transaction::PooledTransaction, Transaction},
primitives::{Address, TxHash, U256},
};
use ethereum_consensus::{
crypto::{KzgCommitment, KzgProof},
deneb::mainnet::{Blob, BlobsBundle},
};
use reth_primitives::TransactionSigned;
use std::collections::HashMap;
use tracing::warn;

Expand Down Expand Up @@ -47,10 +46,10 @@ impl BlockTemplate {
/// Converts the list of signed constraints into a list of signed transactions. Use this when
/// building a local execution payload.
#[inline]
pub fn as_signed_transactions(&self) -> Vec<TransactionSigned> {
pub fn as_signed_transactions(&self) -> Vec<PooledTransaction> {
self.signed_constraints_list
.iter()
.flat_map(|sc| sc.message.transactions.iter().map(|c| c.clone().into_signed()))
.flat_map(|sc| sc.message.transactions.iter().map(|c| c.clone().into_inner()))
.collect()
}

Expand Down
23 changes: 3 additions & 20 deletions bolt-sidecar/src/primitives/transaction.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
use std::{borrow::Cow, fmt};

use alloy::{
consensus::{
transaction::PooledTransaction, BlobTransactionSidecar, Signed, Transaction, TxType,
Typed2718,
transaction::PooledTransaction, BlobTransactionSidecar, Transaction, TxType, Typed2718,
},
eips::eip2718::{Decodable2718, Encodable2718},
hex,
primitives::{Address, U256},
};
use reth_primitives::TransactionSigned;
use serde::{de, ser::SerializeSeq};
use std::{borrow::Cow, fmt};

/// Trait that exposes additional information on transaction types that don't already do it
/// by themselves (e.g. [`PooledTransaction`]).
Expand Down Expand Up @@ -139,22 +138,6 @@ impl FullTransaction {
self.tx
}

/// Returns the signed transaction.
pub fn into_signed(self) -> TransactionSigned {
match self.tx {
PooledTransaction::Legacy(tx) => tx.into(),
PooledTransaction::Eip1559(tx) => tx.into(),
PooledTransaction::Eip2930(tx) => tx.into(),
PooledTransaction::Eip4844(tx) => {
let sig = *tx.signature();
let hash = *tx.hash();
let inner_tx = tx.into_parts().0.into_parts().0;
Signed::new_unchecked(inner_tx, sig, hash).into()
}
PooledTransaction::Eip7702(tx) => tx.into(),
}
}

/// Returns the sender of the transaction, if recovered.
pub fn sender(&self) -> Option<&Address> {
self.sender.as_ref()
Expand Down