@@ -15,10 +15,12 @@ use std::{
1515use tar:: Archive ;
1616use tokio:: task;
1717use tracing:: info;
18+ use zstd:: stream:: read:: Decoder as ZstdDecoder ;
1819
1920const BYTE_UNITS : [ & str ; 4 ] = [ "B" , "KB" , "MB" , "GB" ] ;
2021const 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 ) ]
2426pub 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.
152174fn 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