diff --git a/runtime/src/accounts_file.rs b/runtime/src/accounts_file.rs index a4f58ada0..d2a37f341 100644 --- a/runtime/src/accounts_file.rs +++ b/runtime/src/accounts_file.rs @@ -3,7 +3,7 @@ use { account_storage::meta::{ StorableAccountsWithHashesAndWriteVersions, StoredAccountInfo, StoredAccountMeta, }, - append_vec::{AppendVec, MatchAccountOwnerError}, + append_vec::{AppendVec, AppendVecError, MatchAccountOwnerError}, storable_accounts::StorableAccounts, tiered_storage::error::TieredStorageError, }, @@ -32,6 +32,9 @@ pub enum AccountsFileError { #[error("I/O error: {0}")] Io(#[from] std::io::Error), + #[error("AppendVecError: {0}")] + AppendVecError(#[from] AppendVecError), + #[error("TieredStorageError: {0}")] TieredStorageError(#[from] TieredStorageError), } diff --git a/runtime/src/append_vec.rs b/runtime/src/append_vec.rs index fe22abfeb..5c0eca8c1 100644 --- a/runtime/src/append_vec.rs +++ b/runtime/src/append_vec.rs @@ -53,6 +53,22 @@ pub fn aligned_stored_size(data_len: usize) -> usize { pub const MAXIMUM_APPEND_VEC_FILE_SIZE: u64 = 16 * 1024 * 1024 * 1024; // 16 GiB +#[derive(Error, Debug)] +/// An enum for AppendVec related errors. +pub enum AppendVecError { + #[error("too small file size {0} for AppendVec")] + FileSizeTooSmall(usize), + + #[error("too large file size {0} for AppendVec")] + FileSizeTooLarge(usize), + + #[error("incorrect layout/length/data in the appendvec at path {}", .0.display())] + IncorrectLayout(PathBuf), + + #[error("offset ({0}) is larger than file size ({1})")] + OffsetOutOfBounds(usize, usize), +} + pub struct AppendVecAccountsIter<'append_vec> { append_vec: &'append_vec AppendVec, offset: usize, @@ -297,23 +313,20 @@ impl AppendVec { fn sanitize_len_and_size(current_len: usize, file_size: usize) -> Result<()> { if file_size == 0 { - Err(AccountsFileError::Io(std::io::Error::new( - std::io::ErrorKind::Other, - format!("too small file size {file_size} for AppendVec"), - ))) + Err(AccountsFileError::AppendVecError( + AppendVecError::FileSizeTooSmall(file_size), + )) } else if usize::try_from(MAXIMUM_APPEND_VEC_FILE_SIZE) .map(|max| file_size > max) .unwrap_or(true) { - Err(AccountsFileError::Io(std::io::Error::new( - std::io::ErrorKind::Other, - format!("too large file size {file_size} for AppendVec"), - ))) + Err(AccountsFileError::AppendVecError( + AppendVecError::FileSizeTooLarge(file_size), + )) } else if current_len > file_size { - Err(AccountsFileError::Io(std::io::Error::new( - std::io::ErrorKind::Other, - format!("current_len is larger than file size ({file_size})"), - ))) + Err(AccountsFileError::AppendVecError( + AppendVecError::OffsetOutOfBounds(current_len, file_size), + )) } else { Ok(()) } @@ -359,14 +372,9 @@ impl AppendVec { if !sanitized { // This info show the failing accountvec file path. It helps debugging // the appendvec data corrupution issues related to recycling. - let err_msg = format!( - "incorrect layout/length/data in the appendvec at path {}", - path.as_ref().display() - ); - return Err(AccountsFileError::Io(std::io::Error::new( - std::io::ErrorKind::Other, - err_msg, - ))); + return Err(AccountsFileError::AppendVecError( + AppendVecError::IncorrectLayout(path.as_ref().to_path_buf()), + )); } Ok((new, num_accounts)) @@ -919,7 +927,7 @@ pub mod tests { } #[test] - #[should_panic(expected = "too small file size 0 for AppendVec")] + #[should_panic(expected = "AppendVecError(FileSizeTooSmall(0))")] fn test_append_vec_new_bad_size() { let path = get_append_vec_path("test_append_vec_new_bad_size"); let _av = AppendVec::new(&path.path, true, 0); @@ -978,7 +986,7 @@ pub mod tests { const LEN: usize = 1024 * 1024 + 1; const SIZE: usize = 1024 * 1024; let result = AppendVec::sanitize_len_and_size(LEN, SIZE); - assert_matches!(result, Err(ref message) if message.to_string().contains("current_len is larger than file size (1048576)")); + assert_matches!(result, Err(ref message) if message.to_string().contains("is larger than file size (1048576)")); } #[test]