Skip to content

Commit

Permalink
Uses consistent error types in tiered storage (solana-labs#34110)
Browse files Browse the repository at this point in the history
  • Loading branch information
brooksprumo authored and yhchiang-sol committed Feb 13, 2024
1 parent d904305 commit a61915e
Show file tree
Hide file tree
Showing 7 changed files with 33 additions and 29 deletions.
10 changes: 5 additions & 5 deletions accounts-db/src/tiered_storage/byte_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
use {
crate::tiered_storage::{footer::AccountBlockFormat, meta::AccountMetaOptionalFields},
std::{
io::{Cursor, Read, Write},
io::{Cursor, Read, Result as IoResult, Write},
mem,
},
};
Expand Down Expand Up @@ -90,7 +90,7 @@ impl ByteBlockWriter {
pub fn write_optional_fields(
&mut self,
opt_fields: &AccountMetaOptionalFields,
) -> std::io::Result<usize> {
) -> IoResult<usize> {
let mut size = 0;
if let Some(rent_epoch) = opt_fields.rent_epoch {
size += self.write_pod(&rent_epoch)?;
Expand All @@ -106,7 +106,7 @@ impl ByteBlockWriter {

/// Write the specified typed bytes to the internal buffer of the
/// ByteBlockWriter instance.
pub fn write(&mut self, buf: &[u8]) -> std::io::Result<()> {
pub fn write(&mut self, buf: &[u8]) -> IoResult<()> {
match &mut self.encoder {
ByteBlockEncoder::Raw(cursor) => cursor.write_all(buf)?,
ByteBlockEncoder::Lz4(lz4_encoder) => lz4_encoder.write_all(buf)?,
Expand All @@ -117,7 +117,7 @@ impl ByteBlockWriter {

/// Flush the internal byte buffer that collects all the previous writes
/// into an encoded byte array.
pub fn finish(self) -> std::io::Result<Vec<u8>> {
pub fn finish(self) -> IoResult<Vec<u8>> {
match self.encoder {
ByteBlockEncoder::Raw(cursor) => Ok(cursor.into_inner()),
ByteBlockEncoder::Lz4(lz4_encoder) => {
Expand Down Expand Up @@ -176,7 +176,7 @@ impl ByteBlockReader {
///
/// Note that calling this function with AccountBlockFormat::AlignedRaw encoding
/// will result in panic as the input is already decoded.
pub fn decode(encoding: AccountBlockFormat, input: &[u8]) -> std::io::Result<Vec<u8>> {
pub fn decode(encoding: AccountBlockFormat, input: &[u8]) -> IoResult<Vec<u8>> {
match encoding {
AccountBlockFormat::Lz4 => {
let mut decoder = lz4::Decoder::new(input).unwrap();
Expand Down
8 changes: 4 additions & 4 deletions accounts-db/src/tiered_storage/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ impl TieredStorageFile {
)
}

pub fn new_writable(file_path: impl AsRef<Path>) -> Result<Self, std::io::Error> {
pub fn new_writable(file_path: impl AsRef<Path>) -> IoResult<Self> {
Ok(Self(
OpenOptions::new()
.create_new(true)
Expand Down Expand Up @@ -87,15 +87,15 @@ impl TieredStorageFile {
self.read_bytes(bytes)
}

pub fn seek(&self, offset: u64) -> Result<u64, std::io::Error> {
pub fn seek(&self, offset: u64) -> IoResult<u64> {
(&self.0).seek(SeekFrom::Start(offset))
}

pub fn seek_from_end(&self, offset: i64) -> Result<u64, std::io::Error> {
pub fn seek_from_end(&self, offset: i64) -> IoResult<u64> {
(&self.0).seek(SeekFrom::End(offset))
}

pub fn write_bytes(&self, bytes: &[u8]) -> Result<usize, std::io::Error> {
pub fn write_bytes(&self, bytes: &[u8]) -> IoResult<usize> {
(&self.0).write_all(bytes)?;

Ok(bytes.len())
Expand Down
2 changes: 1 addition & 1 deletion accounts-db/src/tiered_storage/footer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ impl Default for TieredStorageFooter {
}

impl TieredStorageFooter {
pub fn new_from_path(path: impl AsRef<Path>) -> TsResult<Self> {
pub fn new_from_path(path: impl AsRef<Path>) -> TieredStorageResult<Self> {
let file = TieredStorageFile::new_readonly(path);
Self::new_from_footer_block(&file)
}
Expand Down
23 changes: 12 additions & 11 deletions accounts-db/src/tiered_storage/hot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use {
TieredStorageError, TieredStorageFormat, TieredStorageResult,
},
},
bytemuck::{Pod, Zeroable},
memmap2::{Mmap, MmapOptions},
modular_bitfield::prelude::*,
solana_sdk::{pubkey::Pubkey, stake_history::Epoch},
Expand All @@ -41,14 +42,14 @@ const MAX_HOT_OWNER_OFFSET: OwnerOffset = OwnerOffset((1 << 29) - 1);
/// file is mmapped. In addition, as all hot accounts are aligned, it allows
/// each hot accounts file to handle more accounts with the same number of
/// bytes in HotAccountOffset.
pub(crate) const HOT_ACCOUNT_ALIGNMENT: usize = 8;
pub(crate) const HOT_ACCOUNT_OFFSET_ALIGNMENT: usize = 8;

/// The maximum supported offset for hot accounts storage.
const MAX_HOT_ACCOUNT_OFFSET: usize = u32::MAX as usize * HOT_ACCOUNT_ALIGNMENT;
const MAX_HOT_ACCOUNT_OFFSET: usize = u32::MAX as usize * HOT_ACCOUNT_OFFSET_ALIGNMENT;

#[bitfield(bits = 32)]
#[repr(C)]
#[derive(Debug, Default, Copy, Clone, Eq, PartialEq)]
#[derive(Debug, Default, Copy, Clone, Eq, PartialEq, Pod, Zeroable)]
struct HotMetaPackedFields {
/// A hot account entry consists of the following elements:
///
Expand All @@ -66,7 +67,7 @@ struct HotMetaPackedFields {

/// The offset to access a hot account.
#[repr(C)]
#[derive(Debug, Default, Copy, Clone, Eq, PartialEq)]
#[derive(Debug, Default, Copy, Clone, Eq, PartialEq, Pod, Zeroable)]
pub struct HotAccountOffset(u32);

impl AccountOffset for HotAccountOffset {}
Expand All @@ -81,26 +82,26 @@ impl HotAccountOffset {
));
}

// Hot accounts are aligned based on HOT_ACCOUNT_ALIGNMENT.
if offset % HOT_ACCOUNT_ALIGNMENT != 0 {
// Hot accounts are aligned based on HOT_ACCOUNT_OFFSET_ALIGNMENT.
if offset % HOT_ACCOUNT_OFFSET_ALIGNMENT != 0 {
return Err(TieredStorageError::OffsetAlignmentError(
offset,
HOT_ACCOUNT_ALIGNMENT,
HOT_ACCOUNT_OFFSET_ALIGNMENT,
));
}

Ok(HotAccountOffset((offset / HOT_ACCOUNT_ALIGNMENT) as u32))
Ok(HotAccountOffset((offset / HOT_ACCOUNT_OFFSET_ALIGNMENT) as u32))
}

/// Returns the offset to the account.
fn offset(&self) -> usize {
self.0 as usize * HOT_ACCOUNT_ALIGNMENT
self.0 as usize * HOT_ACCOUNT_OFFSET_ALIGNMENT
}
}

/// The storage and in-memory representation of the metadata entry for a
/// hot account.
#[derive(Debug, PartialEq, Eq)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Pod, Zeroable)]
#[repr(C)]
pub struct HotAccountMeta {
/// The balance of this account.
Expand Down Expand Up @@ -615,7 +616,7 @@ pub mod tests {
.map(|address| AccountIndexWriterEntry {
address,
offset: HotAccountOffset::new(
rng.gen_range(0..u32::MAX) as usize * HOT_ACCOUNT_ALIGNMENT,
rng.gen_range(0..u32::MAX) as usize * HOT_ACCOUNT_OFFSET_ALIGNMENT,
)
.unwrap(),
})
Expand Down
13 changes: 7 additions & 6 deletions accounts-db/src/tiered_storage/index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use {
file::TieredStorageFile, footer::TieredStorageFooter, mmap_utils::get_pod,
TieredStorageResult,
},
bytemuck::{Pod, Zeroable},
memmap2::Mmap,
solana_sdk::pubkey::Pubkey,
};
Expand All @@ -17,7 +18,7 @@ pub struct AccountIndexWriterEntry<'a, Offset: AccountOffset> {
}

/// The offset to an account.
pub trait AccountOffset {}
pub trait AccountOffset: Clone + Copy + Pod + Zeroable {}

/// The offset to an account/address entry in the accounts index block.
/// This can be used to obtain the AccountOffset and address by looking through
Expand Down Expand Up @@ -71,7 +72,7 @@ impl IndexBlockFormat {
/// Returns the address of the account given the specified index.
pub fn get_account_address<'a>(
&self,
map: &'a Mmap,
mmap: &'a Mmap,
footer: &TieredStorageFooter,
index_offset: IndexOffset,
) -> TieredStorageResult<&'a Pubkey> {
Expand All @@ -98,7 +99,7 @@ impl IndexBlockFormat {
/// Returns the offset to the account given the specified index.
pub fn get_account_offset<Offset: AccountOffset + Copy>(
&self,
map: &Mmap,
mmap: &Mmap,
footer: &TieredStorageFooter,
index_offset: IndexOffset,
) -> TieredStorageResult<Offset> {
Expand Down Expand Up @@ -130,7 +131,7 @@ mod tests {
super::*,
crate::tiered_storage::{
file::TieredStorageFile,
hot::{HotAccountOffset, HOT_ACCOUNT_ALIGNMENT},
hot::{HotAccountOffset, HOT_ACCOUNT_OFFSET_ALIGNMENT},
},
memmap2::MmapOptions,
rand::Rng,
Expand All @@ -156,7 +157,7 @@ mod tests {
.map(|address| AccountIndexWriterEntry {
address,
offset: HotAccountOffset::new(
rng.gen_range(0..u32::MAX) as usize * HOT_ACCOUNT_ALIGNMENT,
rng.gen_range(0..u32::MAX) as usize * HOT_ACCOUNT_OFFSET_ALIGNMENT,
)
.unwrap(),
})
Expand All @@ -175,7 +176,7 @@ mod tests {
.create(false)
.open(&path)
.unwrap();
let map = unsafe { MmapOptions::new().map(&file).unwrap() };
let mmap = unsafe { MmapOptions::new().map(&file).unwrap() };
for (i, index_entry) in index_entries.iter().enumerate() {
let account_offset = indexer
.get_account_offset::<HotAccountOffset>(&mmap, &footer, IndexOffset(i as u32))
Expand Down
3 changes: 2 additions & 1 deletion accounts-db/src/tiered_storage/meta.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@
//! The account meta and related structs for the tiered storage.
use {
crate::{accounts_hash::AccountHash, tiered_storage::owners::OwnerOffset},
bytemuck::{Pod, Zeroable},
modular_bitfield::prelude::*,
solana_sdk::stake_history::Epoch,
};

/// The struct that handles the account meta flags.
#[bitfield(bits = 32)]
#[repr(C)]
#[derive(Debug, Default, Copy, Clone, Eq, PartialEq)]
#[derive(Debug, Default, Copy, Clone, Eq, PartialEq, Pod, Zeroable)]
pub struct AccountMetaFlags {
/// whether the account meta has rent epoch
pub has_rent_epoch: bool,
Expand Down
3 changes: 2 additions & 1 deletion accounts-db/src/tiered_storage/mmap_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use {
crate::{accounts_file::ALIGN_BOUNDARY_OFFSET, u64_align},
log::*,
memmap2::Mmap,
std::io::Result as IoResult,
};

/// Borrows a value of type `T` from `mmap`
Expand Down Expand Up @@ -35,7 +36,7 @@ pub unsafe fn get_type<T>(mmap: &Mmap, offset: usize) -> IoResult<(&T, usize)> {
/// doesn't overrun the internal buffer. Otherwise return an Error.
/// Also return the offset of the first byte after the requested data that
/// falls on a 64-byte boundary.
pub fn get_slice(map: &Mmap, offset: usize, size: usize) -> std::io::Result<(&[u8], usize)> {
pub fn get_slice(map: &Mmap, offset: usize, size: usize) -> IoResult<(&[u8], usize)> {
let (next, overflow) = offset.overflowing_add(size);
if overflow || next > map.len() {
error!(
Expand Down

0 comments on commit a61915e

Please sign in to comment.