-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: add cli download
to download public node snapshots
#13598
Open
lean-apple
wants to merge
12
commits into
paradigmxyz:main
Choose a base branch
from
lean-apple:cli-download-public-node-snapshots
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+393
−127
Open
Changes from all commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
1cb2f46
feat: add v1 for execute fn with url necessary and decompression not …
lean-apple 3c45e96
feat: add v1 for execute fn with url necessary
lean-apple d82392e
feat: add decompression file option to cli
lean-apple 9a134cc
docs: add command documentation
lean-apple f27faf4
docs: improve code doc + cli displayed
lean-apple fd8f9f2
fix: typo
lean-apple 8b05e7c
fix: complete doc
lean-apple 01f2206
fix: complete doc
lean-apple 337e819
fix: fix doc fmt
lean-apple 48ac0a8
fix: fix doc fmt
lean-apple d7ad3ee
docs: add download cli ref to global summary
lean-apple 74950e9
Merge branch 'main' into cli-download-public-node-snapshots
lean-apple File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
# reth download | ||
|
||
Downloads and optionally decompresses node snapshots from a URL | ||
|
||
```bash | ||
$ reth download --help | ||
``` | ||
```txt | ||
Usage: reth download [OPTIONS] --url <URL> | ||
|
||
Options: | ||
--chain <CHAIN_OR_PATH> | ||
The chain this node is running. | ||
Possible values are either a built-in chain or the path to a chain specification file. | ||
|
||
Built-in chains: | ||
mainnet, sepolia, holesky, dev | ||
|
||
[default: mainnet] | ||
|
||
--instance <INSTANCE> | ||
Add a new instance of a node. | ||
|
||
Configures the ports of the node to avoid conflicts with the defaults. This is useful for running multiple nodes on the same machine. | ||
|
||
Max number of instances is 200. It is chosen in a way so that it's not possible to have port numbers that conflict with each other. | ||
|
||
Changes to the following port numbers: - `DISCOVERY_PORT`: default + `instance` - 1 - `AUTH_PORT`: default + `instance` * 100 - 100 - `HTTP_RPC_PORT`: default - `instance` + 1 - `WS_RPC_PORT`: default + `instance` * 2 - 2 | ||
|
||
[default: 1] | ||
|
||
-h, --help | ||
Print help (see a summary with '-h') | ||
|
||
Datadir: | ||
--datadir <DATA_DIR> | ||
The path to the data dir for all reth files and subdirectories. | ||
|
||
Defaults to the OS-specific data directory: | ||
|
||
- Linux: `$XDG_DATA_HOME/reth/` or `$HOME/.local/share/reth/` | ||
- Windows: `{FOLDERID_RoamingAppData}/reth/` | ||
- macOS: `$HOME/Library/Application Support/reth/` | ||
|
||
[default: default] | ||
|
||
--datadir.static-files <PATH> | ||
The absolute path to store static files in. | ||
|
||
-u, --url <URL> | ||
Custom URL to download the snapshot from | ||
|
||
-d, --decompress | ||
Whether to automatically decompress the snapshot after downloading | ||
|
||
Logging: | ||
--log.stdout.format <FORMAT> | ||
The format to use for logs written to stdout | ||
|
||
[default: terminal] | ||
|
||
Possible values: | ||
- json: Represents JSON formatting for logs. This format outputs log records as JSON objects, making it suitable for structured logging | ||
- log-fmt: Represents logfmt (key=value) formatting for logs. This format is concise and human-readable, typically used in command-line applications | ||
- terminal: Represents terminal-friendly formatting for logs | ||
|
||
--log.stdout.filter <FILTER> | ||
The filter to use for logs written to stdout | ||
|
||
[default: ] | ||
|
||
--log.file.format <FORMAT> | ||
The format to use for logs written to the log file | ||
|
||
[default: terminal] | ||
|
||
Possible values: | ||
- json: Represents JSON formatting for logs. This format outputs log records as JSON objects, making it suitable for structured logging | ||
- log-fmt: Represents logfmt (key=value) formatting for logs. This format is concise and human-readable, typically used in command-line applications | ||
- terminal: Represents terminal-friendly formatting for logs | ||
|
||
--log.file.filter <FILTER> | ||
The filter to use for logs written to the log file | ||
|
||
[default: debug] | ||
|
||
--log.file.directory <PATH> | ||
The path to put log files in | ||
|
||
[default: <CACHE_DIR>/logs] | ||
|
||
--log.file.max-size <SIZE> | ||
The maximum size (in MB) of one log file | ||
|
||
[default: 200] | ||
|
||
--log.file.max-files <COUNT> | ||
The maximum amount of log files that will be stored. If set to 0, background file logging is disabled | ||
|
||
[default: 5] | ||
|
||
--log.journald | ||
Write logs to journald | ||
|
||
--log.journald.filter <FILTER> | ||
The filter to use for logs written to journald | ||
|
||
[default: error] | ||
|
||
--color <COLOR> | ||
Sets whether or not the formatter emits ANSI terminal escape codes for colors and other text formatting | ||
|
||
[default: always] | ||
|
||
Possible values: | ||
- always: Colors on | ||
- auto: Colors on | ||
- never: Colors off | ||
|
||
Display: | ||
-v, --verbosity... | ||
Set the minimum log level. | ||
|
||
-v Errors | ||
-vv Warnings | ||
-vvv Info | ||
-vvvv Debug | ||
-vvvvv Traces (warning: very verbose!) | ||
|
||
-q, --quiet | ||
Silence all log output | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
use std::{io::Write, path::Path, process::Command as ProcessCommand, sync::Arc}; | ||
use tokio::{fs, io::AsyncWriteExt}; | ||
|
||
use clap::Parser; | ||
use eyre::Result; | ||
use reqwest::Client; | ||
use reth_chainspec::{EthChainSpec, EthereumHardforks}; | ||
use reth_cli::chainspec::ChainSpecParser; | ||
use reth_node_core::args::DatadirArgs; | ||
|
||
const SNAPSHOT_FILE: &str = "snapshot.tar.lz4"; | ||
|
||
/// `reth download` command | ||
#[derive(Debug, Parser, Clone)] | ||
pub struct Command<C: ChainSpecParser> { | ||
/// The chain this node is running. | ||
/// | ||
/// Possible values are either a built-in chain or the path to a chain specification file. | ||
#[arg( | ||
long, | ||
value_name = "CHAIN_OR_PATH", | ||
long_help = C::help_message(), | ||
default_value = C::SUPPORTED_CHAINS[0], | ||
value_parser = C::parser() | ||
)] | ||
chain: Arc<C::ChainSpec>, | ||
|
||
/// Path where will be stored the snapshot | ||
#[command(flatten)] | ||
datadir: DatadirArgs, | ||
|
||
/// Custom URL to download the snapshot from | ||
#[arg(long, short, required = true)] | ||
url: String, | ||
|
||
/// Whether to automatically decompress the snapshot after downloading | ||
#[arg(long, short)] | ||
decompress: bool, | ||
} | ||
|
||
impl<C: ChainSpecParser<ChainSpec: EthChainSpec + EthereumHardforks>> Command<C> { | ||
/// Downloads and saves the snapshot from the specified URL | ||
pub async fn execute<N>(self) -> Result<()> { | ||
let data_dir = self.datadir.resolve_datadir(self.chain.chain()); | ||
let snapshot_path = data_dir.data_dir().join(SNAPSHOT_FILE); | ||
fs::create_dir_all(&data_dir).await?; | ||
|
||
println!("Starting snapshot download for chain: {:?}", self.chain.chain()); | ||
println!("Target directory: {:?}", data_dir.data_dir()); | ||
println!("Source URL: {}", self.url); | ||
Comment on lines
+48
to
+50
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should use |
||
|
||
download_snapshot(&self.url, &snapshot_path).await?; | ||
|
||
println!("Snapshot downloaded successfully to {:?}", snapshot_path); | ||
if self.decompress { | ||
println!("Decompressing snapshot..."); | ||
decompress_snapshot(&snapshot_path, data_dir.data_dir())?; | ||
println!("Snapshot decompressed successfully"); | ||
|
||
// Clean up compressed file | ||
fs::remove_file(&snapshot_path).await?; | ||
} else { | ||
println!( | ||
"Please extract the snapshot using: tar --use-compress-program=lz4 -xf {:?}", | ||
snapshot_path | ||
); | ||
} | ||
|
||
Ok(()) | ||
} | ||
} | ||
|
||
// Downloads a file from the given URL to the specified path, displaying download progress. | ||
async fn download_snapshot(url: &str, target_path: &Path) -> Result<()> { | ||
let client = Client::new(); | ||
let mut response = client.get(url).send().await?.error_for_status()?; | ||
|
||
let total_size = response.content_length().unwrap_or(0); | ||
let mut file = fs::File::create(&target_path).await?; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there a reason for using |
||
let mut downloaded = 0u64; | ||
|
||
while let Some(chunk) = response.chunk().await? { | ||
file.write_all(&chunk).await?; | ||
downloaded += chunk.len() as u64; | ||
|
||
if total_size > 0 { | ||
let progress = (downloaded as f64 / total_size as f64) * 100.0; | ||
print!("\rDownloading... {:.1}%", progress); | ||
std::io::stdout().flush()?; | ||
} | ||
} | ||
println!("\nDownload complete!"); | ||
|
||
Ok(()) | ||
} | ||
|
||
// Helper to decompress snapshot file using lz4 | ||
fn decompress_snapshot(snapshot_path: &Path, target_dir: &Path) -> Result<()> { | ||
let status = ProcessCommand::new("tar") | ||
.arg("--use-compress-program=lz4") | ||
.arg("-xf") | ||
.arg(snapshot_path) | ||
.arg("-C") | ||
.arg(target_dir) | ||
.status()?; | ||
|
||
if !status.success() { | ||
return Err(eyre::eyre!("Failed to decompress snapshot")); | ||
} | ||
|
||
Ok(()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
std::fs instead of tokio::fs