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:
parent
32a3de0939
commit
3dd348802f
|
@ -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(
|
pub fn open_genesis_config(
|
||||||
ledger_path: &Path,
|
ledger_path: &Path,
|
||||||
max_genesis_archive_unpacked_size: u64,
|
max_genesis_archive_unpacked_size: u64,
|
||||||
) -> GenesisConfig {
|
) -> std::result::Result<GenesisConfig, OpenGenesisConfigError> {
|
||||||
GenesisConfig::load(ledger_path).unwrap_or_else(|load_err| {
|
match GenesisConfig::load(ledger_path) {
|
||||||
let genesis_package = ledger_path.join(DEFAULT_GENESIS_ARCHIVE);
|
Ok(genesis_config) => Ok(genesis_config),
|
||||||
unpack_genesis_archive(
|
Err(load_err) => {
|
||||||
&genesis_package,
|
|
||||||
ledger_path,
|
|
||||||
max_genesis_archive_unpacked_size,
|
|
||||||
)
|
|
||||||
.unwrap_or_else(|unpack_err| {
|
|
||||||
warn!(
|
warn!(
|
||||||
"Failed to open ledger genesis_config at {:?}: {}, {}",
|
"Failed to load genesis_config at {ledger_path:?}: {load_err}. \
|
||||||
ledger_path, load_err, unpack_err,
|
Will attempt to unpack genesis archive and then retry loading."
|
||||||
);
|
);
|
||||||
std::process::exit(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
// loading must succeed at this moment
|
let genesis_package = ledger_path.join(DEFAULT_GENESIS_ARCHIVE);
|
||||||
GenesisConfig::load(ledger_path).unwrap()
|
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(
|
pub fn unpack_genesis_archive(
|
||||||
|
|
|
@ -565,9 +565,10 @@ impl Validator {
|
||||||
"ledger directory does not exist or is not accessible: {ledger_path:?}"
|
"ledger directory does not exist or is not accessible: {ledger_path:?}"
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
let genesis_config =
|
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)?;
|
metrics_config_sanity_check(genesis_config.cluster_type)?;
|
||||||
|
|
||||||
if let Some(expected_shred_version) = config.expected_shred_version {
|
if let Some(expected_shred_version) = config.expected_shred_version {
|
||||||
|
@ -1764,7 +1765,8 @@ fn load_blockstore(
|
||||||
> {
|
> {
|
||||||
info!("loading ledger from {:?}...", ledger_path);
|
info!("loading ledger from {:?}...", ledger_path);
|
||||||
*start_progress.write().unwrap() = ValidatorStartProgress::LoadingLedger;
|
*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
|
// This needs to be limited otherwise the state in the VoteAccount data
|
||||||
// grows too large
|
// grows too large
|
||||||
|
|
|
@ -553,7 +553,11 @@ fn open_blockstore_with_temporary_primary_access(
|
||||||
pub fn open_genesis_config_by(ledger_path: &Path, matches: &ArgMatches<'_>) -> GenesisConfig {
|
pub fn open_genesis_config_by(ledger_path: &Path, matches: &ArgMatches<'_>) -> GenesisConfig {
|
||||||
let max_genesis_archive_unpacked_size =
|
let max_genesis_archive_unpacked_size =
|
||||||
value_t_or_exit!(matches, "max_genesis_archive_unpacked_size", u64);
|
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> + '_ {
|
pub fn get_program_ids(tx: &VersionedTransaction) -> impl Iterator<Item = &Pubkey> + '_ {
|
||||||
|
|
|
@ -2196,7 +2196,7 @@ fn create_snapshot_to_hard_fork(
|
||||||
..ProcessOptions::default()
|
..ProcessOptions::default()
|
||||||
};
|
};
|
||||||
let ledger_path = blockstore.ledger_path();
|
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 snapshot_config = create_simple_snapshot_config(ledger_path);
|
||||||
let (bank_forks, ..) = bank_forks_utils::load(
|
let (bank_forks, ..) = bank_forks_utils::load(
|
||||||
&genesis_config,
|
&genesis_config,
|
||||||
|
|
Loading…
Reference in New Issue