mirror of
https://github.com/paradigmxyz/reth.git
synced 2026-02-19 03:04:27 -05:00
feat(engine): add trigger-based MiningMode variant (#22250)
Co-authored-by: Amp <amp@ampcode.com> Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
This commit is contained in:
committed by
GitHub
parent
2eec519bf9
commit
5b8808e5fd
6
.changelog/warm-donkeys-dry.md
Normal file
6
.changelog/warm-donkeys-dry.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
reth-engine-local: minor
|
||||
reth-node-builder: minor
|
||||
---
|
||||
|
||||
Added trigger-based `MiningMode` variant that allows blocks to be built on-demand via custom streams, and exposed `with_mining_mode` method on `DebugNodeLauncherFuture` to override default mining configuration.
|
||||
@@ -3,7 +3,7 @@
|
||||
use alloy_primitives::{TxHash, B256};
|
||||
use alloy_rpc_types_engine::ForkchoiceState;
|
||||
use eyre::OptionExt;
|
||||
use futures_util::{stream::Fuse, StreamExt};
|
||||
use futures_util::{stream::Fuse, Stream, StreamExt};
|
||||
use reth_engine_primitives::ConsensusEngineHandle;
|
||||
use reth_payload_builder::PayloadBuilderHandle;
|
||||
use reth_payload_primitives::{
|
||||
@@ -14,6 +14,7 @@ use reth_storage_api::BlockReader;
|
||||
use reth_transaction_pool::TransactionPool;
|
||||
use std::{
|
||||
collections::VecDeque,
|
||||
fmt,
|
||||
future::Future,
|
||||
pin::Pin,
|
||||
task::{Context, Poll},
|
||||
@@ -24,7 +25,6 @@ use tokio_stream::wrappers::ReceiverStream;
|
||||
use tracing::error;
|
||||
|
||||
/// A mining mode for the local dev engine.
|
||||
#[derive(Debug)]
|
||||
pub enum MiningMode<Pool: TransactionPool + Unpin> {
|
||||
/// In this mode a block is built as soon as
|
||||
/// a valid transaction reaches the pool.
|
||||
@@ -43,6 +43,25 @@ pub enum MiningMode<Pool: TransactionPool + Unpin> {
|
||||
},
|
||||
/// In this mode a block is built at a fixed interval.
|
||||
Interval(Interval),
|
||||
/// In this mode a block is built when the trigger stream yields a value.
|
||||
///
|
||||
/// This is a general-purpose trigger that can be fired on demand, for example via a channel
|
||||
/// or any other [`Stream`] implementation.
|
||||
Trigger(Pin<Box<dyn Stream<Item = ()> + Send + Sync>>),
|
||||
}
|
||||
|
||||
impl<Pool: TransactionPool + Unpin> fmt::Debug for MiningMode<Pool> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Self::Instant { max_transactions, accumulated, .. } => f
|
||||
.debug_struct("Instant")
|
||||
.field("max_transactions", max_transactions)
|
||||
.field("accumulated", accumulated)
|
||||
.finish(),
|
||||
Self::Interval(interval) => f.debug_tuple("Interval").field(interval).finish(),
|
||||
Self::Trigger(_) => f.debug_tuple("Trigger").finish(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<Pool: TransactionPool + Unpin> MiningMode<Pool> {
|
||||
@@ -57,6 +76,14 @@ impl<Pool: TransactionPool + Unpin> MiningMode<Pool> {
|
||||
let start = tokio::time::Instant::now() + duration;
|
||||
Self::Interval(tokio::time::interval_at(start, duration))
|
||||
}
|
||||
|
||||
/// Constructor for a [`MiningMode::Trigger`]
|
||||
///
|
||||
/// Accepts any stream that yields `()` values, each of which triggers a new block to be
|
||||
/// mined. This can be backed by a channel, a custom stream, or any other async source.
|
||||
pub fn trigger(trigger: impl Stream<Item = ()> + Send + Sync + 'static) -> Self {
|
||||
Self::Trigger(Box::pin(trigger))
|
||||
}
|
||||
}
|
||||
|
||||
impl<Pool: TransactionPool + Unpin> Future for MiningMode<Pool> {
|
||||
@@ -91,6 +118,12 @@ impl<Pool: TransactionPool + Unpin> Future for MiningMode<Pool> {
|
||||
}
|
||||
Poll::Pending
|
||||
}
|
||||
Self::Trigger(trigger) => {
|
||||
if trigger.poll_next_unpin(cx).is_ready() {
|
||||
return Poll::Ready(())
|
||||
}
|
||||
Poll::Pending
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ use reth_chainspec::EthChainSpec;
|
||||
use reth_consensus_debug_client::{
|
||||
BlockProvider, DebugConsensusClient, EtherscanBlockProvider, RpcBlockProvider,
|
||||
};
|
||||
use reth_engine_local::LocalMiner;
|
||||
use reth_engine_local::{LocalMiner, MiningMode};
|
||||
use reth_node_api::{
|
||||
BlockTy, FullNodeComponents, FullNodeTypes, HeaderTy, PayloadAttrTy, PayloadAttributesBuilder,
|
||||
PayloadTypes,
|
||||
@@ -132,6 +132,7 @@ where
|
||||
map_attributes:
|
||||
Option<Box<dyn Fn(PayloadAttrTy<N::Types>) -> PayloadAttrTy<N::Types> + Send + Sync>>,
|
||||
debug_block_provider: Option<B>,
|
||||
mining_mode: Option<MiningMode<N::Pool>>,
|
||||
}
|
||||
|
||||
impl<L, Target, N, AddOns, B> DebugNodeLauncherFuture<L, Target, N, B>
|
||||
@@ -152,6 +153,7 @@ where
|
||||
local_payload_attributes_builder: Some(Box::new(builder)),
|
||||
map_attributes: None,
|
||||
debug_block_provider: self.debug_block_provider,
|
||||
mining_mode: self.mining_mode,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -166,9 +168,19 @@ where
|
||||
local_payload_attributes_builder: None,
|
||||
map_attributes: Some(Box::new(f)),
|
||||
debug_block_provider: self.debug_block_provider,
|
||||
mining_mode: self.mining_mode,
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets a custom [`MiningMode`] for the local miner in dev mode.
|
||||
///
|
||||
/// This overrides the default mining mode that is derived from the node configuration
|
||||
/// (instant or interval). This can be used to provide a custom trigger-based mining mode.
|
||||
pub fn with_mining_mode(mut self, mode: MiningMode<N::Pool>) -> Self {
|
||||
self.mining_mode = Some(mode);
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets a custom block provider for the debug consensus client.
|
||||
///
|
||||
/// When set, this provider will be used instead of creating an `EtherscanBlockProvider`
|
||||
@@ -186,6 +198,7 @@ where
|
||||
local_payload_attributes_builder: self.local_payload_attributes_builder,
|
||||
map_attributes: self.map_attributes,
|
||||
debug_block_provider: Some(provider),
|
||||
mining_mode: self.mining_mode,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -196,6 +209,7 @@ where
|
||||
local_payload_attributes_builder,
|
||||
map_attributes,
|
||||
debug_block_provider,
|
||||
mining_mode,
|
||||
} = self;
|
||||
|
||||
let handle = inner.launch_node(target).await?;
|
||||
@@ -291,7 +305,8 @@ where
|
||||
Either::Right(builder)
|
||||
};
|
||||
|
||||
let dev_mining_mode = handle.node.config.dev_mining_mode(pool);
|
||||
let dev_mining_mode =
|
||||
mining_mode.unwrap_or_else(|| handle.node.config.dev_mining_mode(pool));
|
||||
handle.node.task_executor.spawn_critical_task("local engine", async move {
|
||||
LocalMiner::new(
|
||||
blockchain_db,
|
||||
@@ -343,6 +358,7 @@ where
|
||||
local_payload_attributes_builder: None,
|
||||
map_attributes: None,
|
||||
debug_block_provider: None,
|
||||
mining_mode: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user