Skip to content

Commit

Permalink
feat: reth stage unwind --offline (#9097)
Browse files Browse the repository at this point in the history
Co-authored-by: Georgios Konstantopoulos <[email protected]>
Co-authored-by: Oliver <[email protected]>
  • Loading branch information
3 people authored Jun 25, 2024
1 parent 270df3e commit aa95230
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 16 deletions.
58 changes: 42 additions & 16 deletions bin/reth/src/commands/stage/unwind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
};
Expand All @@ -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 {
Expand All @@ -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.
Expand All @@ -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(())
}
Expand All @@ -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,
Expand All @@ -131,10 +155,12 @@ impl Command {
ExExManagerHandle::empty(),
)),
)
.build(
provider_factory.clone(),
StaticFileProducer::new(provider_factory, PruneModes::default()),
);
};

let pipeline = builder.build(
provider_factory.clone(),
StaticFileProducer::new(provider_factory, PruneModes::default()),
);
Ok(pipeline)
}
}
Expand Down
3 changes: 3 additions & 0 deletions book/cli/reth/stage/unwind.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit aa95230

Please sign in to comment.