From 408593467bddcc91b328974f7768332fbc6f2185 Mon Sep 17 00:00:00 2001 From: John Letey Date: Thu, 12 Feb 2026 21:42:19 +0100 Subject: [PATCH] feat(download): optional chain-aware snapshot url (#22119) --- crates/cli/commands/src/download.rs | 31 ++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/crates/cli/commands/src/download.rs b/crates/cli/commands/src/download.rs index c0d8041e03..3a348190fe 100644 --- a/crates/cli/commands/src/download.rs +++ b/crates/cli/commands/src/download.rs @@ -37,6 +37,14 @@ pub struct DownloadDefaults { pub available_snapshots: Vec>, /// Default base URL for snapshots pub default_base_url: Cow<'static, str>, + /// Default base URL for chain-aware snapshots. + /// + /// When set, the chain ID is appended to form the full URL: `{base_url}/{chain_id}`. + /// For example, given a base URL of `https://snapshots.example.com` and chain ID `1`, + /// the resulting URL would be `https://snapshots.example.com/1`. + /// + /// Falls back to [`default_base_url`](Self::default_base_url) when `None`. + pub default_chain_aware_base_url: Option>, /// Optional custom long help text that overrides the generated help pub long_help: Option, } @@ -60,6 +68,7 @@ impl DownloadDefaults { Cow::Borrowed("https://publicnode.com/snapshots (full nodes & testnets)"), ], default_base_url: Cow::Borrowed(MERKLE_BASE_URL), + default_chain_aware_base_url: None, long_help: None, } } @@ -84,9 +93,11 @@ impl DownloadDefaults { } help.push_str( - "\nIf no URL is provided, the latest mainnet archive snapshot\nwill be proposed for download from ", + "\nIf no URL is provided, the latest archive snapshot for the selected chain\nwill be proposed for download from ", + ); + help.push_str( + self.default_chain_aware_base_url.as_deref().unwrap_or(&self.default_base_url), ); - help.push_str(self.default_base_url.as_ref()); help.push_str( ".\n\nLocal file:// URLs are also supported for extracting snapshots from disk.", ); @@ -111,6 +122,12 @@ impl DownloadDefaults { self } + /// Set the default chain-aware base URL. + pub fn with_chain_aware_base_url(mut self, url: impl Into>) -> Self { + self.default_chain_aware_base_url = Some(url.into()); + self + } + /// Builder: Set custom long help text, overriding the generated help pub fn with_long_help(mut self, help: impl Into) -> Self { self.long_help = Some(help.into()); @@ -142,7 +159,7 @@ impl> DownloadCo let url = match self.url { Some(url) => url, None => { - let url = get_latest_snapshot_url().await?; + let url = get_latest_snapshot_url(self.env.chain.chain().id()).await?; info!(target: "reth::cli", "Using default snapshot URL: {}", url); url } @@ -509,8 +526,12 @@ async fn stream_and_extract(url: &str, target_dir: &Path) -> Result<()> { } // Builds default URL for latest mainnet archive snapshot using configured defaults -async fn get_latest_snapshot_url() -> Result { - let base_url = &DownloadDefaults::get_global().default_base_url; +async fn get_latest_snapshot_url(chain_id: u64) -> Result { + let defaults = DownloadDefaults::get_global(); + let base_url = match &defaults.default_chain_aware_base_url { + Some(url) => format!("{url}/{chain_id}"), + None => defaults.default_base_url.to_string(), + }; let latest_url = format!("{base_url}/latest.txt"); let filename = Client::new() .get(latest_url)