Skip to content

Commit

Permalink
Bubble up genesis load errors instead of exiting (solana-labs#34851)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
steviez authored Jan 19, 2024
1 parent 32a3de0 commit 3dd3488
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 21 deletions.
39 changes: 23 additions & 16 deletions accounts-db/src/hardened_unpack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
8 changes: 5 additions & 3 deletions core/src/validator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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
Expand Down
6 changes: 5 additions & 1 deletion ledger-tool/src/ledger_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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> + '_ {
Expand Down
2 changes: 1 addition & 1 deletion local-cluster/tests/local_cluster.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down

0 comments on commit 3dd3488

Please sign in to comment.