Skip to main content

reth_node_builder/
sync.rs

1//! Backfill the engine runs while the node is far behind the chain.
2
3use crate::components::NodeComponents;
4use reth_engine_tree::backfill::{BackfillSync, PipelineSync};
5use reth_network_api::BlockDownloaderProvider;
6use reth_provider::{providers::ProviderNodeTypes, ProviderFactory};
7use reth_stages::Pipeline;
8use reth_tasks::Runtime;
9
10/// Builds the [`BackfillSync`] the engine hands long-range sync to.
11///
12/// Nodes pick one with [`EngineNodeLauncher::with_backfill`](crate::EngineNodeLauncher); the
13/// default is [`PipelineBackfill`].
14pub trait BackfillSyncBuilder<N: ProviderNodeTypes, C>: Send {
15    /// The backfill this builder produces.
16    type Backfill: BackfillSync + Unpin + 'static;
17
18    /// Builds the backfill from the node's staged pipeline, block client and database.
19    fn build(self, ctx: BackfillContext<N, C>) -> eyre::Result<Self::Backfill>;
20
21    /// Recovers from an earlier run that stopped mid-write, before the node checks the database
22    /// for consistency. A backfill that commits static files and the database separately uses it
23    /// so a crash between the two isn't treated as corruption. Does nothing by default.
24    fn recover(&mut self, _provider_factory: &ProviderFactory<N>) -> eyre::Result<()> {
25        Ok(())
26    }
27}
28
29/// What the launcher hands a [`BackfillSyncBuilder`].
30#[derive(Debug)]
31pub struct BackfillContext<N: ProviderNodeTypes, C> {
32    // Staged pipeline the backfill runs or hands over to.
33    pipeline: Pipeline<N>,
34    // Client the pipeline downloads blocks with.
35    client: C,
36    provider_factory: ProviderFactory<N>,
37    runtime: Runtime,
38}
39
40impl<N: ProviderNodeTypes, C> BackfillContext<N, C> {
41    /// Creates the context for one backfill build.
42    pub const fn new(
43        pipeline: Pipeline<N>,
44        client: C,
45        provider_factory: ProviderFactory<N>,
46        runtime: Runtime,
47    ) -> Self {
48        Self { pipeline, client, provider_factory, runtime }
49    }
50
51    /// Returns the client the pipeline downloads blocks with.
52    pub const fn client(&self) -> &C {
53        &self.client
54    }
55
56    /// Returns the node's database.
57    pub const fn provider_factory(&self) -> &ProviderFactory<N> {
58        &self.provider_factory
59    }
60
61    /// Returns the runtime backfill tasks are spawned on.
62    pub const fn runtime(&self) -> &Runtime {
63        &self.runtime
64    }
65
66    /// Consumes the context, returning the staged pipeline.
67    pub fn into_pipeline(self) -> Pipeline<N> {
68        self.pipeline
69    }
70}
71
72/// Backfills with the staged pipeline, as every node does unless it picks another backfill.
73#[derive(Debug, Clone, Copy, Default)]
74pub struct PipelineBackfill;
75
76impl<N: ProviderNodeTypes, C> BackfillSyncBuilder<N, C> for PipelineBackfill {
77    type Backfill = PipelineSync<N>;
78
79    fn build(self, ctx: BackfillContext<N, C>) -> eyre::Result<Self::Backfill> {
80        let runtime = ctx.runtime().clone();
81        Ok(PipelineSync::new(ctx.into_pipeline(), runtime))
82    }
83}
84
85/// Client the network of `Components` hands the engine's backfill.
86pub type BackfillClientFor<T, Components> =
87    <<Components as NodeComponents<T>>::Network as BlockDownloaderProvider>::Client;