clone_solana_download_utils/
lib.rs1pub use clone_solana_file_download::DownloadProgressRecord;
2use {
3 clone_solana_clock::Slot,
4 clone_solana_file_download::{download_file, DownloadProgressCallbackOption},
5 clone_solana_genesis_config::DEFAULT_GENESIS_ARCHIVE,
6 clone_solana_runtime::{
7 snapshot_hash::SnapshotHash,
8 snapshot_package::SnapshotKind,
9 snapshot_utils::{self, ArchiveFormat, ZstdConfig},
10 },
11 log::*,
12 std::{
13 fs,
14 net::SocketAddr,
15 num::NonZeroUsize,
16 path::{Path, PathBuf},
17 },
18};
19
20pub fn download_genesis_if_missing(
21 rpc_addr: &SocketAddr,
22 genesis_package: &Path,
23 use_progress_bar: bool,
24) -> Result<PathBuf, String> {
25 if !genesis_package.exists() {
26 let tmp_genesis_path = genesis_package.parent().unwrap().join("tmp-genesis");
27 let tmp_genesis_package = tmp_genesis_path.join(DEFAULT_GENESIS_ARCHIVE);
28
29 let _ignored = fs::remove_dir_all(&tmp_genesis_path);
30 download_file(
31 &format!("http://{rpc_addr}/{DEFAULT_GENESIS_ARCHIVE}"),
32 &tmp_genesis_package,
33 use_progress_bar,
34 &mut None,
35 )?;
36
37 Ok(tmp_genesis_package)
38 } else {
39 Err("genesis already exists".to_string())
40 }
41}
42
43pub fn download_snapshot_archive(
46 rpc_addr: &SocketAddr,
47 full_snapshot_archives_dir: &Path,
48 incremental_snapshot_archives_dir: &Path,
49 desired_snapshot_hash: (Slot, SnapshotHash),
50 snapshot_kind: SnapshotKind,
51 maximum_full_snapshot_archives_to_retain: NonZeroUsize,
52 maximum_incremental_snapshot_archives_to_retain: NonZeroUsize,
53 use_progress_bar: bool,
54 progress_notify_callback: &mut DownloadProgressCallbackOption<'_>,
55) -> Result<(), String> {
56 snapshot_utils::purge_old_snapshot_archives(
57 full_snapshot_archives_dir,
58 incremental_snapshot_archives_dir,
59 maximum_full_snapshot_archives_to_retain,
60 maximum_incremental_snapshot_archives_to_retain,
61 );
62
63 let snapshot_archives_remote_dir =
64 snapshot_utils::build_snapshot_archives_remote_dir(match snapshot_kind {
65 SnapshotKind::FullSnapshot => full_snapshot_archives_dir,
66 SnapshotKind::IncrementalSnapshot(_) => incremental_snapshot_archives_dir,
67 });
68 fs::create_dir_all(&snapshot_archives_remote_dir).unwrap();
69
70 for archive_format in [
71 ArchiveFormat::TarZstd {
72 config: ZstdConfig::default(),
73 },
74 ArchiveFormat::TarGzip,
75 ArchiveFormat::TarBzip2,
76 ArchiveFormat::TarLz4,
77 ArchiveFormat::Tar,
78 ] {
79 let destination_path = match snapshot_kind {
80 SnapshotKind::FullSnapshot => snapshot_utils::build_full_snapshot_archive_path(
81 &snapshot_archives_remote_dir,
82 desired_snapshot_hash.0,
83 &desired_snapshot_hash.1,
84 archive_format,
85 ),
86 SnapshotKind::IncrementalSnapshot(base_slot) => {
87 snapshot_utils::build_incremental_snapshot_archive_path(
88 &snapshot_archives_remote_dir,
89 base_slot,
90 desired_snapshot_hash.0,
91 &desired_snapshot_hash.1,
92 archive_format,
93 )
94 }
95 };
96
97 if destination_path.is_file() {
98 return Ok(());
99 }
100
101 match download_file(
102 &format!(
103 "http://{}/{}",
104 rpc_addr,
105 destination_path.file_name().unwrap().to_str().unwrap()
106 ),
107 &destination_path,
108 use_progress_bar,
109 progress_notify_callback,
110 ) {
111 Ok(()) => return Ok(()),
112 Err(err) => info!("{}", err),
113 }
114 }
115 Err(format!(
116 "Failed to download a snapshot archive for slot {} from {}",
117 desired_snapshot_hash.0, rpc_addr
118 ))
119}