diff --git a/Cargo.lock b/Cargo.lock index 134200d9a..090a955ba 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5745,7 +5745,9 @@ dependencies = [ name = "solana-genesis-utils" version = "1.16.0" dependencies = [ + "log", "solana-download-utils", + "solana-rpc-client", "solana-runtime", "solana-sdk 1.16.0", ] diff --git a/genesis-utils/Cargo.toml b/genesis-utils/Cargo.toml index 2ab1c1bd2..223a4566f 100644 --- a/genesis-utils/Cargo.toml +++ b/genesis-utils/Cargo.toml @@ -10,7 +10,9 @@ license = { workspace = true } edition = { workspace = true } [dependencies] +log = { workspace = true } solana-download-utils = { workspace = true } +solana-rpc-client = { workspace = true } solana-runtime = { workspace = true } solana-sdk = { workspace = true } diff --git a/genesis-utils/src/lib.rs b/genesis-utils/src/lib.rs index 7aa151201..7fd317567 100644 --- a/genesis-utils/src/lib.rs +++ b/genesis-utils/src/lib.rs @@ -1,5 +1,7 @@ use { + log::*, solana_download_utils::download_genesis_if_missing, + solana_rpc_client::rpc_client::RpcClient, solana_runtime::hardened_unpack::unpack_genesis_archive, solana_sdk::{ genesis_config::{GenesisConfig, DEFAULT_GENESIS_ARCHIVE}, @@ -36,7 +38,7 @@ fn load_local_genesis( Ok(existing_genesis) } -pub fn download_then_check_genesis_hash( +fn get_genesis_config( rpc_addr: &SocketAddr, ledger_path: &std::path::Path, expected_genesis_hash: Option, @@ -45,12 +47,11 @@ pub fn download_then_check_genesis_hash( use_progress_bar: bool, ) -> Result { if no_genesis_fetch { - let genesis_config = load_local_genesis(ledger_path, expected_genesis_hash)?; - return Ok(genesis_config); + return load_local_genesis(ledger_path, expected_genesis_hash); } let genesis_package = ledger_path.join(DEFAULT_GENESIS_ARCHIVE); - let genesis_config = if let Ok(tmp_genesis_package) = + if let Ok(tmp_genesis_package) = download_genesis_if_missing(rpc_addr, &genesis_package, use_progress_bar) { unpack_genesis_archive( @@ -67,10 +68,56 @@ pub fn download_then_check_genesis_hash( std::fs::rename(tmp_genesis_package, genesis_package) .map_err(|err| format!("Unable to rename: {err:?}"))?; - downloaded_genesis + Ok(downloaded_genesis) } else { - load_local_genesis(ledger_path, expected_genesis_hash)? - }; - - Ok(genesis_config) + load_local_genesis(ledger_path, expected_genesis_hash) + } +} + +fn set_and_verify_expected_genesis_hash( + genesis_config: GenesisConfig, + expected_genesis_hash: &mut Option, + rpc_client: &RpcClient, +) -> Result<(), String> { + let genesis_hash = genesis_config.hash(); + if expected_genesis_hash.is_none() { + info!("Expected genesis hash set to {}", genesis_hash); + *expected_genesis_hash = Some(genesis_hash); + } + let expected_genesis_hash = expected_genesis_hash.unwrap(); + + // Sanity check that the RPC node is using the expected genesis hash before + // downloading a snapshot from it + let rpc_genesis_hash = rpc_client + .get_genesis_hash() + .map_err(|err| format!("Failed to get genesis hash: {err}"))?; + + if expected_genesis_hash != rpc_genesis_hash { + return Err(format!( + "Genesis hash mismatch: expected {expected_genesis_hash} but RPC node genesis hash is {rpc_genesis_hash}" + )); + } + + Ok(()) +} + +pub fn download_then_check_genesis_hash( + rpc_addr: &SocketAddr, + ledger_path: &std::path::Path, + expected_genesis_hash: &mut Option, + max_genesis_archive_unpacked_size: u64, + no_genesis_fetch: bool, + use_progress_bar: bool, + rpc_client: &RpcClient, +) -> Result<(), String> { + let genesis_config = get_genesis_config( + rpc_addr, + ledger_path, + *expected_genesis_hash, + max_genesis_archive_unpacked_size, + no_genesis_fetch, + use_progress_bar, + )?; + + set_and_verify_expected_genesis_hash(genesis_config, expected_genesis_hash, rpc_client) } diff --git a/programs/sbf/Cargo.lock b/programs/sbf/Cargo.lock index 5387337d9..2d07f6daa 100644 --- a/programs/sbf/Cargo.lock +++ b/programs/sbf/Cargo.lock @@ -4942,7 +4942,9 @@ dependencies = [ name = "solana-genesis-utils" version = "1.16.0" dependencies = [ + "log", "solana-download-utils", + "solana-rpc-client", "solana-runtime", "solana-sdk 1.16.0", ] diff --git a/validator/src/bootstrap.rs b/validator/src/bootstrap.rs index b5a2cbaf7..a1dfbf17a 100644 --- a/validator/src/bootstrap.rs +++ b/validator/src/bootstrap.rs @@ -398,36 +398,15 @@ pub fn attempt_download_genesis_and_snapshot( vote_account: &Pubkey, authorized_voter_keypairs: Arc>>>, ) -> Result<(), String> { - let genesis_config = download_then_check_genesis_hash( + download_then_check_genesis_hash( &rpc_contact_info.rpc, ledger_path, - validator_config.expected_genesis_hash, + &mut validator_config.expected_genesis_hash, bootstrap_config.max_genesis_archive_unpacked_size, bootstrap_config.no_genesis_fetch, use_progress_bar, - ); - - if let Ok(genesis_config) = genesis_config { - let genesis_hash = genesis_config.hash(); - if validator_config.expected_genesis_hash.is_none() { - info!("Expected genesis hash set to {}", genesis_hash); - validator_config.expected_genesis_hash = Some(genesis_hash); - } - } - - if let Some(expected_genesis_hash) = validator_config.expected_genesis_hash { - // Sanity check that the RPC node is using the expected genesis hash before - // downloading a snapshot from it - let rpc_genesis_hash = rpc_client - .get_genesis_hash() - .map_err(|err| format!("Failed to get genesis hash: {err}"))?; - - if expected_genesis_hash != rpc_genesis_hash { - return Err(format!( - "Genesis hash mismatch: expected {expected_genesis_hash} but RPC node genesis hash is {rpc_genesis_hash}" - )); - } - } + rpc_client, + )?; if let Some(gossip) = gossip.take() { shutdown_gossip_service(gossip);