feat: reth stage unwind --offline (#9097)

Co-authored-by: Georgios Konstantopoulos <me@gakonst.com>
Co-authored-by: Oliver <onbjerg@users.noreply.github.com>
This commit is contained in:
Dan Cline
2024-06-25 14:50:30 -04:00
committed by GitHub
parent 270df3eeb8
commit aa952309e8
2 changed files with 45 additions and 16 deletions

View File

@ -15,7 +15,7 @@ use reth_provider::{
};
use reth_prune_types::PruneModes;
use reth_stages::{
sets::DefaultStages,
sets::{DefaultStages, OfflineStages},
stages::{ExecutionStage, ExecutionStageThresholds},
Pipeline, StageSet,
};
@ -40,6 +40,11 @@ pub struct Command {
#[command(subcommand)]
command: Subcommands,
/// If this is enabled, then all stages except headers, bodies, and sender recovery will be
/// unwound.
#[arg(long)]
offline: bool,
}
impl Command {
@ -52,16 +57,30 @@ impl Command {
eyre::bail!("Cannot unwind genesis block")
}
// Only execute a pipeline unwind if the start of the range overlaps the existing static
// files. If that's the case, then copy all available data from MDBX to static files, and
// only then, proceed with the unwind.
if let Some(highest_static_block) = provider_factory
let highest_static_file_block = provider_factory
.static_file_provider()
.get_highest_static_files()
.max()
.filter(|highest_static_file_block| highest_static_file_block >= range.start())
{
info!(target: "reth::cli", ?range, ?highest_static_block, "Executing a pipeline unwind.");
.filter(|highest_static_file_block| highest_static_file_block >= range.start());
// Execute a pipeline unwind if the start of the range overlaps the existing static
// files. If that's the case, then copy all available data from MDBX to static files, and
// only then, proceed with the unwind.
//
// We also execute a pipeline unwind if `offline` is specified, because we need to only
// unwind the data associated with offline stages.
if highest_static_file_block.is_some() || self.offline {
if self.offline {
info!(target: "reth::cli", "Performing an unwind for offline-only data!");
}
if let Some(highest_static_file_block) = highest_static_file_block {
info!(target: "reth::cli", ?range, ?highest_static_file_block, "Executing a pipeline unwind.");
} else {
info!(target: "reth::cli", ?range, "Executing a pipeline unwind.");
}
// This will build an offline-only pipeline if the `offline` flag is enabled
let mut pipeline = self.build_pipeline(config, provider_factory.clone()).await?;
// Move all applicable data from database to static files.
@ -87,7 +106,7 @@ impl Command {
provider.commit()?;
}
println!("Unwound {} blocks", range.count());
info!(target: "reth::cli", range=?range.clone(), count=range.count(), "Unwound blocks");
Ok(())
}
@ -105,9 +124,14 @@ impl Command {
let (tip_tx, tip_rx) = watch::channel(B256::ZERO);
let executor = block_executor!(provider_factory.chain_spec());
let pipeline = Pipeline::builder()
.with_tip_sender(tip_tx)
.add_stages(
let builder = if self.offline {
Pipeline::builder().add_stages(
OfflineStages::new(executor, config.stages, PruneModes::default())
.builder()
.disable(reth_stages::StageId::SenderRecovery),
)
} else {
Pipeline::builder().with_tip_sender(tip_tx).add_stages(
DefaultStages::new(
provider_factory.clone(),
tip_rx,
@ -131,7 +155,9 @@ impl Command {
ExExManagerHandle::empty(),
)),
)
.build(
};
let pipeline = builder.build(
provider_factory.clone(),
StaticFileProducer::new(provider_factory, PruneModes::default()),
);

View File

@ -204,6 +204,9 @@ Networking:
[default: 131072]
--offline
If this is enabled, then all stages except headers, bodies, and sender recovery will be unwound
Logging:
--log.stdout.format <FORMAT>
The format to use for logs written to stdout