use {
super::PurgeType, crate::blockstore_meta::BlockLocation,
agave_snapshots::hardened_unpack::UnpackError, solana_clock::Slot, thiserror::Error,
};
#[derive(Error, Debug)]
pub enum BlockstoreError {
#[error("shred for index exists")]
ShredForIndexExists,
#[error("invalid shred data: {0}")]
InvalidShredData(String),
#[error("RocksDB error: {0}")]
RocksDb(#[from] rocksdb::Error),
#[error("slot is not rooted")]
SlotNotRooted,
#[error("slot is not full")]
SlotNotFull,
#[error("dead slot")]
DeadSlot,
#[error("io error: {0}")]
Io(#[from] std::io::Error),
#[error("deserialization wincode error: {0}")]
WincodeRead(#[from] wincode::ReadError),
#[error("serialization wincode error: {0}")]
WincodeWrite(#[from] wincode::WriteError),
#[error("fs extra error: {0}")]
FsExtraError(#[from] fs_extra::error::Error),
#[error("slot cleaned up")]
SlotCleanedUp,
#[error("unpack error: {0}")]
UnpackError(#[from] UnpackError),
#[error("transaction status slot mismatch")]
TransactionStatusSlotMismatch,
#[error("empty epoch stakes")]
EmptyEpochStakes,
#[error("no vote timestamps in range")]
NoVoteTimestampsInRange,
#[error("protobuf encode error: {0}")]
ProtobufEncodeError(#[from] prost::EncodeError),
#[error("protobuf decode error: {0}")]
ProtobufDecodeError(#[from] prost::DecodeError),
#[error("parent entries unavailable")]
ParentEntriesUnavailable,
#[error("parent info unavailable: slot {0} location {1}")]
ParentInfoUnavailable(Slot, BlockLocation),
#[error("merkle tree construction failure: slot {0} location {1}")]
MerkleTreeConstructionFailure(Slot, BlockLocation),
#[error("merkle proof construction failure: slot {0} location {1}")]
MerkleProofConstructionFailure(Slot, BlockLocation),
#[error("slot unavailable")]
SlotUnavailable,
#[error("unsupported transaction version")]
UnsupportedTransactionVersion,
#[error("missing transaction metadata")]
MissingTransactionMetadata,
#[error("transaction-index overflow")]
TransactionIndexOverflow,
#[error("invalid erasure config")]
InvalidErasureConfig,
#[error("last shred index missing slot {0}")]
UnknownLastIndex(Slot),
#[error("missing shred slot {0}, index {1}")]
MissingShred(Slot, u64),
#[error("legacy shred slot {0}, index {1}")]
LegacyShred(Slot, u64),
#[error("unable to read merkle root slot {0}, index {1}")]
MissingMerkleRoot(Slot, u64),
#[error("block contains an empty entry batch for slot {0}")]
EmptyEntryBatch(Slot),
#[error("unable to purge slots in range [{from_slot}, {to_slot}] {purge_type:?}: {inner:?}")]
PurgeFailed {
from_slot: Slot,
to_slot: Slot,
purge_type: PurgeType,
#[source]
inner: Box<BlockstoreError>,
},
#[error(transparent)]
ManualPurge(#[from] BlockstoreManualPurgeError),
#[error("update parent matches block header for slot {0}")]
UpdateParentMatchesBlockHeader(Slot),
#[error("update parent slot greater than block header for slot {0}")]
UpdateParentSlotGreaterThanBlockHeader(Slot),
#[error(
"update parent {update_parent_slot} is greater than shred parent {shred_parent_slot} for \
slot {slot}"
)]
UpdateParentSlotGreaterThanShredParent {
slot: Slot,
update_parent_slot: Slot,
shred_parent_slot: Slot,
},
#[error("update parent is only valid in the first slot of a leader window for slot {0}")]
UpdateParentNotFirstInLeaderWindow(Slot),
#[error("unexpected block component")]
UnexpectedBlockComponent,
#[error("multiple update parents for slot {0}")]
MultipleUpdateParents(Slot),
#[error("block component mismatch for slot {0}")]
BlockComponentMismatch(Slot),
#[error("invalid parent info for slot {slot}: parent {parent_slot}, max root {root}")]
InvalidParentInfo {
slot: Slot,
parent_slot: Slot,
root: Slot,
},
#[error(
"block header parent {block_header_parent_slot} does not match shred parent \
{shred_parent_slot} for slot {slot}"
)]
BlockHeaderParentMismatch {
slot: Slot,
block_header_parent_slot: Slot,
shred_parent_slot: Slot,
},
#[error("Block in slot {0} was aborted as leader sent an empty entry batch")]
BlockAborted(Slot),
}
pub type Result<T> = std::result::Result<T, BlockstoreError>;
#[derive(Error, Debug)]
pub enum BlockstoreManualPurgeError {
#[error("purge request sender is unavailable")]
SenderUnavailable,
#[error("purge request for slot {request_slot} must be less than the latest root {max_root}")]
SlotGreaterThanOrEqualToRoot { request_slot: Slot, max_root: Slot },
#[error("purge request try send error")]
TrySend,
}
impl<T> std::convert::From<crossbeam_channel::TrySendError<T>> for BlockstoreManualPurgeError {
fn from(_e: crossbeam_channel::TrySendError<T>) -> BlockstoreManualPurgeError {
BlockstoreManualPurgeError::TrySend
}
}