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

feat: add TreeConfig #9833

Merged
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
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.

74 changes: 74 additions & 0 deletions crates/engine/tree/src/tree/config.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
//! Engine tree configuration.

const DEFAULT_PERSISTENCE_THRESHOLD: u64 = 256;
const DEFAULT_BLOCK_BUFFER_LIMIT: u32 = 256;
const DEFAULT_MAX_INVALID_HEADER_CACHE_LENGTH: u32 = 256;

/// The configuration of the engine tree.
#[derive(Debug)]
pub struct TreeConfig {
/// Maximum number of blocks to be kept only in memory without triggering persistence.
persistence_threshold: u64,
/// Number of pending blocks that cannot be executed due to missing parent and
/// are kept in cache.
block_buffer_limit: u32,
/// Number of invalid headers to keep in cache.
max_invalid_header_cache_length: u32,
}

impl Default for TreeConfig {
fn default() -> Self {
Self {
persistence_threshold: DEFAULT_PERSISTENCE_THRESHOLD,
block_buffer_limit: DEFAULT_BLOCK_BUFFER_LIMIT,
max_invalid_header_cache_length: DEFAULT_MAX_INVALID_HEADER_CACHE_LENGTH,
}
}
}

impl TreeConfig {
/// Create engine tree configuration.
pub const fn new(
persistence_threshold: u64,
block_buffer_limit: u32,
max_invalid_header_cache_length: u32,
) -> Self {
Self { persistence_threshold, block_buffer_limit, max_invalid_header_cache_length }
}

/// Return the persistence threshold.
pub const fn persistence_threshold(&self) -> u64 {
self.persistence_threshold
}

/// Return the block buffer limit.
pub const fn block_buffer_limit(&self) -> u32 {
self.block_buffer_limit
}

/// Return the maximum invalid cache header length.
pub const fn max_invalid_header_cache_length(&self) -> u32 {
self.max_invalid_header_cache_length
}

/// Setter for persistence threshold.
pub const fn with_persistence_threshold(mut self, persistence_threshold: u64) -> Self {
self.persistence_threshold = persistence_threshold;
self
}

/// Setter for block buffer limit.
pub const fn with_block_buffer_limit(mut self, block_buffer_limit: u32) -> Self {
self.block_buffer_limit = block_buffer_limit;
self
}

/// Setter for maximum invalid header cache length.
pub const fn with_max_invalid_header_cache_length(
mut self,
max_invalid_header_cache_length: u32,
) -> Self {
self.max_invalid_header_cache_length = max_invalid_header_cache_length;
self
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,8 @@ use tokio::sync::{
};
use tracing::*;

/// Maximum number of blocks to be kept only in memory without triggering persistence.
const PERSISTENCE_THRESHOLD: u64 = 256;
/// Number of pending blocks that cannot be executed due to missing parent and
/// are kept in cache.
const DEFAULT_BLOCK_BUFFER_LIMIT: u32 = 256;
/// Number of invalid headers to keep in cache.
const DEFAULT_MAX_INVALID_HEADER_CACHE_LENGTH: u32 = 256;
Comment on lines -52 to -58
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lets keep the constants but move to config

mod config;
pub use config::TreeConfig;

/// Keeps track of the state of the tree.
///
Expand Down Expand Up @@ -387,6 +382,8 @@ pub struct EngineApiTreeHandlerImpl<P, E, T: EngineTypes> {
/// Handle to the payload builder that will receive payload attributes for valid forkchoice
/// updates
payload_builder: PayloadBuilderHandle<T>,
/// Configuration settings.
config: TreeConfig,
}

impl<P, E, T> EngineApiTreeHandlerImpl<P, E, T>
Expand All @@ -407,6 +404,7 @@ where
canonical_in_memory_state: CanonicalInMemoryState,
persistence: PersistenceHandle,
payload_builder: PayloadBuilderHandle<T>,
config: TreeConfig,
) -> Self {
Self {
provider,
Expand All @@ -421,6 +419,7 @@ where
state,
canonical_in_memory_state,
payload_builder,
config,
}
}

Expand All @@ -437,14 +436,15 @@ where
persistence: PersistenceHandle,
payload_builder: PayloadBuilderHandle<T>,
canonical_in_memory_state: CanonicalInMemoryState,
config: TreeConfig,
) -> UnboundedReceiver<EngineApiEvent> {
let best_block_number = provider.best_block_number().unwrap_or(0);
let header = provider.sealed_header(best_block_number).ok().flatten().unwrap_or_default();

let (tx, outgoing) = tokio::sync::mpsc::unbounded_channel();
let state = EngineApiTreeState::new(
DEFAULT_BLOCK_BUFFER_LIMIT,
DEFAULT_MAX_INVALID_HEADER_CACHE_LENGTH,
config.block_buffer_limit(),
config.max_invalid_header_cache_length(),
header.num_hash(),
);

Expand All @@ -459,6 +459,7 @@ where
canonical_in_memory_state,
persistence,
payload_builder,
config,
);
std::thread::Builder::new().name("Tree Task".to_string()).spawn(|| task.run()).unwrap();
outgoing
Expand Down Expand Up @@ -657,12 +658,12 @@ where
fn should_persist(&self) -> bool {
self.state.tree_state.max_block_number() -
self.persistence_state.last_persisted_block_number >=
PERSISTENCE_THRESHOLD
self.config.persistence_threshold()
}

fn get_blocks_to_persist(&self) -> Vec<ExecutedBlock> {
let start = self.persistence_state.last_persisted_block_number;
let end = start + PERSISTENCE_THRESHOLD;
let end = start + self.config.persistence_threshold();

// NOTE: this is an exclusive range, to try to include exactly PERSISTENCE_THRESHOLD blocks
self.state
Expand Down Expand Up @@ -1607,6 +1608,7 @@ mod tests {
canonical_in_memory_state,
persistence_handle,
payload_builder,
TreeConfig::default(),
);

Self { tree, to_tree_tx, blocks: vec![], action_rx, payload_command_rx }
Expand Down Expand Up @@ -1675,6 +1677,7 @@ mod tests {
canonical_in_memory_state,
persistence_handle,
payload_builder,
TreeConfig::default(),
);
let last_executed_block = blocks.last().unwrap().clone();
let pending = Some(BlockState::new(last_executed_block));
Expand All @@ -1688,8 +1691,10 @@ mod tests {
async fn test_tree_persist_blocks() {
// we need more than PERSISTENCE_THRESHOLD blocks to trigger the
// persistence task.
let tree_config = TreeConfig::default();

let TestHarness { tree, to_tree_tx, action_rx, mut blocks, payload_command_rx } =
get_default_test_harness(PERSISTENCE_THRESHOLD + 1);
get_default_test_harness(tree_config.persistence_threshold() + 1);
std::thread::Builder::new().name("Tree Task".to_string()).spawn(|| tree.run()).unwrap();

// send a message to the tree to enter the main loop.
Expand All @@ -1699,7 +1704,7 @@ mod tests {
if let PersistenceAction::SaveBlocks((saved_blocks, _)) = received_action {
// only PERSISTENCE_THRESHOLD will be persisted
blocks.pop();
assert_eq!(saved_blocks.len() as u64, PERSISTENCE_THRESHOLD);
assert_eq!(saved_blocks.len() as u64, tree_config.persistence_threshold());
assert_eq!(saved_blocks, blocks);
} else {
panic!("unexpected action received {received_action:?}");
Expand Down Expand Up @@ -1731,8 +1736,10 @@ mod tests {

#[tokio::test]
async fn test_engine_request_during_backfill() {
let tree_config = TreeConfig::default();

let TestHarness { mut tree, to_tree_tx, action_rx, blocks, payload_command_rx } =
get_default_test_harness(PERSISTENCE_THRESHOLD);
get_default_test_harness(tree_config.persistence_threshold());

// set backfill active
tree.backfill_sync_state = BackfillSyncState::Active;
Expand All @@ -1754,7 +1761,7 @@ mod tests {

#[tokio::test]
async fn test_holesky_payload() {
let s = include_str!("../test-data/holesky/1.rlp");
let s = include_str!("../../test-data/holesky/1.rlp");
let data = Bytes::from_str(s).unwrap();
let block = Block::decode(&mut data.as_ref()).unwrap();
let sealed = block.seal_slow();
Expand Down
5 changes: 4 additions & 1 deletion crates/ethereum/engine/src/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use reth_engine_tree::{
download::BasicBlockDownloader,
engine::{EngineApiRequestHandler, EngineHandler},
persistence::PersistenceHandle,
tree::EngineApiTreeHandlerImpl,
tree::{EngineApiTreeHandlerImpl, TreeConfig},
};
pub use reth_engine_tree::{
chain::{ChainEvent, ChainOrchestrator},
Expand Down Expand Up @@ -68,6 +68,7 @@ where
blockchain_db: BlockchainProvider2<DB>,
pruner: Pruner<DB, ProviderFactory<DB>>,
payload_builder: PayloadBuilderHandle<EthEngineTypes>,
tree_config: TreeConfig,
) -> Self {
let consensus = Arc::new(EthBeaconConsensus::new(chain_spec.clone()));
let downloader = BasicBlockDownloader::new(client, consensus.clone());
Expand All @@ -89,6 +90,7 @@ where
persistence_handle,
payload_builder,
canonical_in_memory_state,
tree_config,
);

let engine_handler = EngineApiRequestHandler::new(to_tree_tx, from_tree);
Expand Down Expand Up @@ -174,6 +176,7 @@ mod tests {
blockchain_db,
pruner,
PayloadBuilderHandle::new(tx),
TreeConfig::default(),
);
}
}
1 change: 1 addition & 0 deletions crates/ethereum/node/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ reth-node-events.workspace = true
reth-node-core.workspace = true
reth-exex.workspace = true
reth-blockchain-tree.workspace = true
reth-engine-tree.workspace = true

# misc
eyre.workspace = true
Expand Down
4 changes: 4 additions & 0 deletions crates/ethereum/node/src/launch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use reth_beacon_consensus::{
BeaconConsensusEngineHandle,
};
use reth_blockchain_tree::BlockchainTreeConfig;
use reth_engine_tree::tree::TreeConfig;
use reth_ethereum_engine::service::{ChainEvent, EthService};
use reth_ethereum_engine_primitives::EthEngineTypes;
use reth_exex::ExExManagerHandle;
Expand Down Expand Up @@ -171,6 +172,8 @@ where
let pruner_events = pruner.events();
info!(target: "reth::cli", prune_config=?ctx.prune_config().unwrap_or_default(), "Pruner initialized");

let tree_config = TreeConfig::default().with_persistence_threshold(120);

// Configure the consensus engine
let mut eth_service = EthService::new(
ctx.chain_spec(),
Expand All @@ -182,6 +185,7 @@ where
ctx.blockchain_db().clone(),
pruner,
ctx.components().payload_builder().clone(),
tree_config,
);

let event_sender = EventSender::default();
Expand Down
Loading