Skip to content

Commit 6e75f7b

Browse files
Rjectedmattsse
andauthored
feat(download): support zst archives in reth download (#18237)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
1 parent de24793 commit 6e75f7b

File tree

3 files changed

+37
-10
lines changed

3 files changed

+37
-10
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/cli/commands/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ human_bytes.workspace = true
7272
eyre.workspace = true
7373
clap = { workspace = true, features = ["derive", "env"] }
7474
lz4.workspace = true
75+
zstd.workspace = true
7576
serde.workspace = true
7677
serde_json.workspace = true
7778
tar.workspace = true

crates/cli/commands/src/download.rs

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,12 @@ use std::{
1515
use tar::Archive;
1616
use tokio::task;
1717
use tracing::info;
18+
use zstd::stream::read::Decoder as ZstdDecoder;
1819

1920
const BYTE_UNITS: [&str; 4] = ["B", "KB", "MB", "GB"];
2021
const MERKLE_BASE_URL: &str = "https://downloads.merkle.io";
21-
const EXTENSION_TAR_FILE: &str = ".tar.lz4";
22+
const EXTENSION_TAR_LZ4: &str = ".tar.lz4";
23+
const EXTENSION_TAR_ZSTD: &str = ".tar.zst";
2224

2325
#[derive(Debug, Parser)]
2426
pub struct DownloadCommand<C: ChainSpecParser> {
@@ -148,7 +150,27 @@ impl<R: Read> Read for ProgressReader<R> {
148150
}
149151
}
150152

151-
/// Downloads and extracts a snapshot with blocking approach
153+
/// Supported compression formats for snapshots
154+
#[derive(Debug, Clone, Copy)]
155+
enum CompressionFormat {
156+
Lz4,
157+
Zstd,
158+
}
159+
160+
impl CompressionFormat {
161+
/// Detect compression format from file extension
162+
fn from_url(url: &str) -> Result<Self> {
163+
if url.ends_with(EXTENSION_TAR_LZ4) {
164+
Ok(Self::Lz4)
165+
} else if url.ends_with(EXTENSION_TAR_ZSTD) {
166+
Ok(Self::Zstd)
167+
} else {
168+
Err(eyre::eyre!("Unsupported file format. Expected .tar.lz4 or .tar.zst, got: {}", url))
169+
}
170+
}
171+
}
172+
173+
/// Downloads and extracts a snapshot, blocking until finished.
152174
fn blocking_download_and_extract(url: &str, target_dir: &Path) -> Result<()> {
153175
let client = reqwest::blocking::Client::builder().build()?;
154176
let response = client.get(url).send()?.error_for_status()?;
@@ -160,11 +182,18 @@ fn blocking_download_and_extract(url: &str, target_dir: &Path) -> Result<()> {
160182
})?;
161183

162184
let progress_reader = ProgressReader::new(response, total_size);
185+
let format = CompressionFormat::from_url(url)?;
163186

164-
let decoder = Decoder::new(progress_reader)?;
165-
let mut archive = Archive::new(decoder);
166-
167-
archive.unpack(target_dir)?;
187+
match format {
188+
CompressionFormat::Lz4 => {
189+
let decoder = Decoder::new(progress_reader)?;
190+
Archive::new(decoder).unpack(target_dir)?;
191+
}
192+
CompressionFormat::Zstd => {
193+
let decoder = ZstdDecoder::new(progress_reader)?;
194+
Archive::new(decoder).unpack(target_dir)?;
195+
}
196+
}
168197

169198
info!(target: "reth::cli", "Extraction complete.");
170199
Ok(())
@@ -191,9 +220,5 @@ async fn get_latest_snapshot_url() -> Result<String> {
191220
.trim()
192221
.to_string();
193222

194-
if !filename.ends_with(EXTENSION_TAR_FILE) {
195-
return Err(eyre::eyre!("Unexpected snapshot filename format: {}", filename));
196-
}
197-
198223
Ok(format!("{MERKLE_BASE_URL}/{filename}"))
199224
}

0 commit comments

Comments
 (0)