mirror of
https://github.com/paradigmxyz/reth.git
synced 2026-01-29 00:58:11 -05:00
feat: add SyncState traits (#693)
* feat: add SyncState traits * docs: clarify execution stage
This commit is contained in:
@@ -22,6 +22,9 @@ pub mod db;
|
||||
/// P2P traits.
|
||||
pub mod p2p;
|
||||
|
||||
/// Syncing related traits.
|
||||
pub mod sync;
|
||||
|
||||
/// Possible errors when interacting with the chain.
|
||||
mod error;
|
||||
|
||||
|
||||
77
crates/interfaces/src/sync.rs
Normal file
77
crates/interfaces/src/sync.rs
Normal file
@@ -0,0 +1,77 @@
|
||||
//! Traits used when interacting with the sync status of the network.
|
||||
|
||||
use reth_primitives::BlockNumber;
|
||||
|
||||
/// A type that provides information about whether the node is currently syncing and the network is
|
||||
/// currently serving syncing related requests.
|
||||
#[auto_impl::auto_impl(&, Arc, Box)]
|
||||
pub trait SyncStateProvider: Send + Sync {
|
||||
/// Returns `true` if the network is undergoing sync.
|
||||
fn is_syncing(&self) -> bool;
|
||||
}
|
||||
|
||||
/// An updater for updating the [SyncState] of the network.
|
||||
///
|
||||
/// The chain sync pipeline consists of several sequential Stages, like the `HeaderStage` for
|
||||
/// downloading bodies, or `ExecutionStage` for process all downloaded data.
|
||||
///
|
||||
/// Some stage transitions will result in an update of the [SyncState] of the network. For example,
|
||||
/// the transition from a download stage (`Headers`, `Bodies`) to a processing stage (`Sender
|
||||
/// Recovery`, `Execution`) marks a transition from [`SyncState::Downloading`] to
|
||||
/// [`SyncState::Executing`]. Since the execution takes some time, after the first pass the node
|
||||
/// will not be synced ([`SyncState::Idle`]) yet and instead transition back to download data, but
|
||||
/// now with a higher `block_target`. This cycle will continue until the node has caught up with the
|
||||
/// chain and will transition to [`SyncState::Idle`] sync.
|
||||
#[auto_impl::auto_impl(&, Arc, Box)]
|
||||
pub trait SyncStateUpdater: SyncStateProvider {
|
||||
/// Notifies about an [SyncState] update.
|
||||
fn update_sync_state(&self, state: SyncState);
|
||||
}
|
||||
|
||||
/// The state the network is currently in when it comes to synchronization.
|
||||
#[derive(Clone, Eq, PartialEq, Debug)]
|
||||
pub enum SyncState {
|
||||
/// Node sync is complete.
|
||||
///
|
||||
/// The network just serves requests to keep up of the chain.
|
||||
Idle,
|
||||
/// Network is syncing and downloading up to the `target_block`.
|
||||
///
|
||||
/// This represents the headers and bodies stage.
|
||||
Downloading {
|
||||
/// The block to which the node is downloading state.
|
||||
target_block: BlockNumber,
|
||||
},
|
||||
/// All headers and bodies up to the `target_block` have been downloaded and are now being
|
||||
/// executed.
|
||||
///
|
||||
/// This represents stages that execute/recover the downloaded data.
|
||||
Executing {
|
||||
/// The block to which the node executes downloaded state.
|
||||
target_block: BlockNumber,
|
||||
},
|
||||
}
|
||||
|
||||
impl SyncState {
|
||||
/// Whether the node is currently syncing.
|
||||
///
|
||||
/// Note: this does not include keep-up sync when the state is idle.
|
||||
pub fn is_syncing(&self) -> bool {
|
||||
!matches!(self, SyncState::Idle)
|
||||
}
|
||||
}
|
||||
|
||||
/// A [SyncStateUpdater] implementation that does nothing.
|
||||
#[derive(Debug, Clone, Default)]
|
||||
#[non_exhaustive]
|
||||
pub struct NoopSyncStateUpdate;
|
||||
|
||||
impl SyncStateProvider for NoopSyncStateUpdate {
|
||||
fn is_syncing(&self) -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
impl SyncStateUpdater for NoopSyncStateUpdate {
|
||||
fn update_sync_state(&self, _state: SyncState) {}
|
||||
}
|
||||
@@ -8,12 +8,15 @@ use crate::{
|
||||
};
|
||||
use parking_lot::Mutex;
|
||||
use reth_eth_wire::{DisconnectReason, NewBlock, NewPooledTransactionHashes, SharedTransactions};
|
||||
use reth_interfaces::p2p::headers::client::StatusUpdater;
|
||||
use reth_interfaces::{
|
||||
p2p::headers::client::StatusUpdater,
|
||||
sync::{SyncState, SyncStateProvider, SyncStateUpdater},
|
||||
};
|
||||
use reth_primitives::{PeerId, TransactionSigned, TxHash, H256, U256};
|
||||
use std::{
|
||||
net::SocketAddr,
|
||||
sync::{
|
||||
atomic::{AtomicUsize, Ordering},
|
||||
atomic::{AtomicBool, AtomicUsize, Ordering},
|
||||
Arc,
|
||||
},
|
||||
};
|
||||
@@ -48,6 +51,7 @@ impl NetworkHandle {
|
||||
local_peer_id,
|
||||
peers,
|
||||
network_mode,
|
||||
is_syncing: Arc::new(Default::default()),
|
||||
};
|
||||
Self { inner: Arc::new(inner) }
|
||||
}
|
||||
@@ -187,6 +191,19 @@ impl StatusUpdater for NetworkHandle {
|
||||
}
|
||||
}
|
||||
|
||||
impl SyncStateProvider for NetworkHandle {
|
||||
fn is_syncing(&self) -> bool {
|
||||
self.inner.is_syncing.load(Ordering::Relaxed)
|
||||
}
|
||||
}
|
||||
|
||||
impl SyncStateUpdater for NetworkHandle {
|
||||
fn update_sync_state(&self, state: SyncState) {
|
||||
let is_syncing = state.is_syncing();
|
||||
self.inner.is_syncing.store(is_syncing, Ordering::Relaxed)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct NetworkInner {
|
||||
/// Number of active peer sessions the node's currently handling.
|
||||
@@ -201,6 +218,8 @@ struct NetworkInner {
|
||||
peers: PeersHandle,
|
||||
/// The mode of the network
|
||||
network_mode: NetworkMode,
|
||||
/// Represents if the network is currently syncing.
|
||||
is_syncing: Arc<AtomicBool>,
|
||||
}
|
||||
|
||||
/// Internal messages that can be passed to the [`NetworkManager`](crate::NetworkManager).
|
||||
|
||||
Reference in New Issue
Block a user