Skip to content

Commit

Permalink
chore: pass primiitves generic to EngineApiTreeHandler fields (#13256)
Browse files Browse the repository at this point in the history
  • Loading branch information
klkvr authored Dec 10, 2024
1 parent c9bd640 commit 5ee776a
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 69 deletions.
1 change: 1 addition & 0 deletions crates/blockchain-tree/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ reth-consensus.workspace = true
reth-node-types.workspace = true

# ethereum
alloy-consensus.workspace = true
alloy-primitives.workspace = true
alloy-eips.workspace = true

Expand Down
34 changes: 18 additions & 16 deletions crates/blockchain-tree/src/block_buffer.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use crate::metrics::BlockBufferMetrics;
use alloy_consensus::BlockHeader;
use alloy_primitives::{BlockHash, BlockNumber};
use reth_network::cache::LruCache;
use reth_node_types::Block;
use reth_primitives::SealedBlockWithSenders;
use std::collections::{BTreeMap, HashMap, HashSet};

Expand All @@ -16,9 +18,9 @@ use std::collections::{BTreeMap, HashMap, HashSet};
/// Note: Buffer is limited by number of blocks that it can contain and eviction of the block
/// is done by last recently used block.
#[derive(Debug)]
pub struct BlockBuffer {
pub struct BlockBuffer<B: Block = reth_primitives::Block> {
/// All blocks in the buffer stored by their block hash.
pub(crate) blocks: HashMap<BlockHash, SealedBlockWithSenders>,
pub(crate) blocks: HashMap<BlockHash, SealedBlockWithSenders<B>>,
/// Map of any parent block hash (even the ones not currently in the buffer)
/// to the buffered children.
/// Allows connecting buffered blocks by parent.
Expand All @@ -35,7 +37,7 @@ pub struct BlockBuffer {
pub(crate) metrics: BlockBufferMetrics,
}

impl BlockBuffer {
impl<B: Block> BlockBuffer<B> {
/// Create new buffer with max limit of blocks
pub fn new(limit: u32) -> Self {
Self {
Expand All @@ -48,37 +50,37 @@ impl BlockBuffer {
}

/// Return reference to buffered blocks
pub const fn blocks(&self) -> &HashMap<BlockHash, SealedBlockWithSenders> {
pub const fn blocks(&self) -> &HashMap<BlockHash, SealedBlockWithSenders<B>> {
&self.blocks
}

/// Return reference to the requested block.
pub fn block(&self, hash: &BlockHash) -> Option<&SealedBlockWithSenders> {
pub fn block(&self, hash: &BlockHash) -> Option<&SealedBlockWithSenders<B>> {
self.blocks.get(hash)
}

/// Return a reference to the lowest ancestor of the given block in the buffer.
pub fn lowest_ancestor(&self, hash: &BlockHash) -> Option<&SealedBlockWithSenders> {
pub fn lowest_ancestor(&self, hash: &BlockHash) -> Option<&SealedBlockWithSenders<B>> {
let mut current_block = self.blocks.get(hash)?;
while let Some(parent) = self.blocks.get(&current_block.parent_hash) {
while let Some(parent) = self.blocks.get(&current_block.parent_hash()) {
current_block = parent;
}
Some(current_block)
}

/// Insert a correct block inside the buffer.
pub fn insert_block(&mut self, block: SealedBlockWithSenders) {
pub fn insert_block(&mut self, block: SealedBlockWithSenders<B>) {
let hash = block.hash();

self.parent_to_child.entry(block.parent_hash).or_default().insert(hash);
self.earliest_blocks.entry(block.number).or_default().insert(hash);
self.parent_to_child.entry(block.parent_hash()).or_default().insert(hash);
self.earliest_blocks.entry(block.number()).or_default().insert(hash);
self.blocks.insert(hash, block);

if let (_, Some(evicted_hash)) = self.lru.insert_and_get_evicted(hash) {
// evict the block if limit is hit
if let Some(evicted_block) = self.remove_block(&evicted_hash) {
// evict the block if limit is hit
self.remove_from_parent(evicted_block.parent_hash, &evicted_hash);
self.remove_from_parent(evicted_block.parent_hash(), &evicted_hash);
}
}
self.metrics.blocks.set(self.blocks.len() as f64);
Expand All @@ -93,7 +95,7 @@ impl BlockBuffer {
pub fn remove_block_with_children(
&mut self,
parent_hash: &BlockHash,
) -> Vec<SealedBlockWithSenders> {
) -> Vec<SealedBlockWithSenders<B>> {
let removed = self
.remove_block(parent_hash)
.into_iter()
Expand Down Expand Up @@ -152,16 +154,16 @@ impl BlockBuffer {
/// This method will only remove the block if it's present inside `self.blocks`.
/// The block might be missing from other collections, the method will only ensure that it has
/// been removed.
fn remove_block(&mut self, hash: &BlockHash) -> Option<SealedBlockWithSenders> {
fn remove_block(&mut self, hash: &BlockHash) -> Option<SealedBlockWithSenders<B>> {
let block = self.blocks.remove(hash)?;
self.remove_from_earliest_blocks(block.number, hash);
self.remove_from_parent(block.parent_hash, hash);
self.remove_from_earliest_blocks(block.number(), hash);
self.remove_from_parent(block.parent_hash(), hash);
self.lru.remove(hash);
Some(block)
}

/// Remove all children and their descendants for the given blocks and return them.
fn remove_children(&mut self, parent_hashes: Vec<BlockHash>) -> Vec<SealedBlockWithSenders> {
fn remove_children(&mut self, parent_hashes: Vec<BlockHash>) -> Vec<SealedBlockWithSenders<B>> {
// remove all parent child connection and all the child children blocks that are connected
// to the discarded parent blocks.
let mut remove_parent_children = parent_hashes;
Expand Down
2 changes: 1 addition & 1 deletion crates/engine/local/src/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ where
/// Processes requests.
///
/// This type is responsible for processing incoming requests.
handler: EngineApiRequestHandler<EngineApiRequest<N::Engine>>,
handler: EngineApiRequestHandler<EngineApiRequest<N::Engine, N::Primitives>>,
/// Receiver for incoming requests (from the engine API endpoint) that need to be processed.
incoming_requests: EngineMessageStream<N::Engine>,
}
Expand Down
6 changes: 4 additions & 2 deletions crates/engine/service/src/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ pub use reth_engine_tree::{
};
use reth_evm::execute::BlockExecutorProvider;
use reth_network_p2p::EthBlockClient;
use reth_node_types::{BlockTy, NodeTypesWithEngine};
use reth_node_types::{BlockTy, NodeTypes, NodeTypesWithEngine};
use reth_payload_builder::PayloadBuilderHandle;
use reth_primitives::EthPrimitives;
use reth_provider::{providers::BlockchainProvider2, ProviderFactory};
Expand All @@ -37,7 +37,9 @@ pub type EngineMessageStream<T> = Pin<Box<dyn Stream<Item = BeaconEngineMessage<
/// Alias for chain orchestrator.
type EngineServiceType<N, Client> = ChainOrchestrator<
EngineHandler<
EngineApiRequestHandler<EngineApiRequest<<N as NodeTypesWithEngine>::Engine>>,
EngineApiRequestHandler<
EngineApiRequest<<N as NodeTypesWithEngine>::Engine, <N as NodeTypes>::Primitives>,
>,
EngineMessageStream<<N as NodeTypesWithEngine>::Engine>,
BasicBlockDownloader<Client>,
>,
Expand Down
14 changes: 8 additions & 6 deletions crates/engine/tree/src/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -238,14 +238,14 @@ impl EngineApiKind {

/// The request variants that the engine API handler can receive.
#[derive(Debug)]
pub enum EngineApiRequest<T: EngineTypes> {
pub enum EngineApiRequest<T: EngineTypes, N: NodePrimitives> {
/// A request received from the consensus engine.
Beacon(BeaconEngineMessage<T>),
/// Request to insert an already executed block, e.g. via payload building.
InsertExecutedBlock(ExecutedBlock),
InsertExecutedBlock(ExecutedBlock<N>),
}

impl<T: EngineTypes> Display for EngineApiRequest<T> {
impl<T: EngineTypes, N: NodePrimitives> Display for EngineApiRequest<T, N> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Beacon(msg) => msg.fmt(f),
Expand All @@ -256,14 +256,16 @@ impl<T: EngineTypes> Display for EngineApiRequest<T> {
}
}

impl<T: EngineTypes> From<BeaconEngineMessage<T>> for EngineApiRequest<T> {
impl<T: EngineTypes, N: NodePrimitives> From<BeaconEngineMessage<T>> for EngineApiRequest<T, N> {
fn from(msg: BeaconEngineMessage<T>) -> Self {
Self::Beacon(msg)
}
}

impl<T: EngineTypes> From<EngineApiRequest<T>> for FromEngine<EngineApiRequest<T>> {
fn from(req: EngineApiRequest<T>) -> Self {
impl<T: EngineTypes, N: NodePrimitives> From<EngineApiRequest<T, N>>
for FromEngine<EngineApiRequest<T, N>>
{
fn from(req: EngineApiRequest<T, N>) -> Self {
Self::Request(req)
}
}
Expand Down
Loading

0 comments on commit 5ee776a

Please sign in to comment.