Bubble up genesis load errors instead of exiting (#34851)

The function open_genesis_config() performs several operations that
could fail. If any of these fail, the process exits immediately.

Instead of exiting immediately, bubble up the error and let the caller
decide the appropriate action. solana-validator and solana-ledger-tool
will functionally be unchanged, but this consolidates startup failures
for both of these processes.
This commit is contained in:
steviez 2024-01-19 09:25:46 -06:00 committed by GitHub
parent 32a3de0939
commit 3dd348802f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 34 additions and 21 deletions

View File

@ -446,28 +446,35 @@ fn is_valid_snapshot_archive_entry(parts: &[&str], kind: tar::EntryType) -> bool
}
}
#[derive(Error, Debug)]
pub enum OpenGenesisConfigError {
#[error("unpack error: {0}")]
Unpack(#[from] UnpackError),
#[error("Genesis load error: {0}")]
Load(#[from] std::io::Error),
}
pub fn open_genesis_config(
ledger_path: &Path,
max_genesis_archive_unpacked_size: u64,
) -> GenesisConfig {
GenesisConfig::load(ledger_path).unwrap_or_else(|load_err| {
let genesis_package = ledger_path.join(DEFAULT_GENESIS_ARCHIVE);
unpack_genesis_archive(
&genesis_package,
ledger_path,
max_genesis_archive_unpacked_size,
)
.unwrap_or_else(|unpack_err| {
) -> std::result::Result<GenesisConfig, OpenGenesisConfigError> {
match GenesisConfig::load(ledger_path) {
Ok(genesis_config) => Ok(genesis_config),
Err(load_err) => {
warn!(
"Failed to open ledger genesis_config at {:?}: {}, {}",
ledger_path, load_err, unpack_err,
"Failed to load genesis_config at {ledger_path:?}: {load_err}. \
Will attempt to unpack genesis archive and then retry loading."
);
std::process::exit(1);
});
// loading must succeed at this moment
GenesisConfig::load(ledger_path).unwrap()
})
let genesis_package = ledger_path.join(DEFAULT_GENESIS_ARCHIVE);
unpack_genesis_archive(
&genesis_package,
ledger_path,
max_genesis_archive_unpacked_size,
)?;
GenesisConfig::load(ledger_path).map_err(OpenGenesisConfigError::Load)
}
}
}
pub fn unpack_genesis_archive(

View File

@ -565,9 +565,10 @@ impl Validator {
"ledger directory does not exist or is not accessible: {ledger_path:?}"
));
}
let genesis_config =
open_genesis_config(ledger_path, config.max_genesis_archive_unpacked_size);
open_genesis_config(ledger_path, config.max_genesis_archive_unpacked_size)
.map_err(|err| format!("Failed to open genesis config: {err}"))?;
metrics_config_sanity_check(genesis_config.cluster_type)?;
if let Some(expected_shred_version) = config.expected_shred_version {
@ -1764,7 +1765,8 @@ fn load_blockstore(
> {
info!("loading ledger from {:?}...", ledger_path);
*start_progress.write().unwrap() = ValidatorStartProgress::LoadingLedger;
let genesis_config = open_genesis_config(ledger_path, config.max_genesis_archive_unpacked_size);
let genesis_config = open_genesis_config(ledger_path, config.max_genesis_archive_unpacked_size)
.map_err(|err| format!("Failed to open genesis config: {err}"))?;
// This needs to be limited otherwise the state in the VoteAccount data
// grows too large

View File

@ -553,7 +553,11 @@ fn open_blockstore_with_temporary_primary_access(
pub fn open_genesis_config_by(ledger_path: &Path, matches: &ArgMatches<'_>) -> GenesisConfig {
let max_genesis_archive_unpacked_size =
value_t_or_exit!(matches, "max_genesis_archive_unpacked_size", u64);
open_genesis_config(ledger_path, max_genesis_archive_unpacked_size)
open_genesis_config(ledger_path, max_genesis_archive_unpacked_size).unwrap_or_else(|err| {
eprintln!("Exiting. Failed to open genesis config: {err}");
exit(1);
})
}
pub fn get_program_ids(tx: &VersionedTransaction) -> impl Iterator<Item = &Pubkey> + '_ {

View File

@ -2196,7 +2196,7 @@ fn create_snapshot_to_hard_fork(
..ProcessOptions::default()
};
let ledger_path = blockstore.ledger_path();
let genesis_config = open_genesis_config(ledger_path, u64::max_value());
let genesis_config = open_genesis_config(ledger_path, u64::max_value()).unwrap();
let snapshot_config = create_simple_snapshot_config(ledger_path);
let (bank_forks, ..) = bank_forks_utils::load(
&genesis_config,