Skip to main content

solana_ledger/blockstore/
error.rs

1//! The error that can be produced from Blockstore operations.
2
3use {
4    super::PurgeType, crate::blockstore_meta::BlockLocation,
5    agave_snapshots::hardened_unpack::UnpackError, solana_clock::Slot, thiserror::Error,
6};
7
8#[derive(Error, Debug)]
9pub enum BlockstoreError {
10    #[error("shred for index exists")]
11    ShredForIndexExists,
12    #[error("invalid shred data: {0}")]
13    InvalidShredData(String),
14    #[error("RocksDB error: {0}")]
15    RocksDb(#[from] rocksdb::Error),
16    #[error("slot is not rooted")]
17    SlotNotRooted,
18    #[error("slot is not full")]
19    SlotNotFull,
20    #[error("dead slot")]
21    DeadSlot,
22    #[error("io error: {0}")]
23    Io(#[from] std::io::Error),
24    #[error("deserialization wincode error: {0}")]
25    WincodeRead(#[from] wincode::ReadError),
26    #[error("serialization wincode error: {0}")]
27    WincodeWrite(#[from] wincode::WriteError),
28    #[error("fs extra error: {0}")]
29    FsExtraError(#[from] fs_extra::error::Error),
30    #[error("slot cleaned up")]
31    SlotCleanedUp,
32    #[error("unpack error: {0}")]
33    UnpackError(#[from] UnpackError),
34    #[error("transaction status slot mismatch")]
35    TransactionStatusSlotMismatch,
36    #[error("empty epoch stakes")]
37    EmptyEpochStakes,
38    #[error("no vote timestamps in range")]
39    NoVoteTimestampsInRange,
40    #[error("protobuf encode error: {0}")]
41    ProtobufEncodeError(#[from] prost::EncodeError),
42    #[error("protobuf decode error: {0}")]
43    ProtobufDecodeError(#[from] prost::DecodeError),
44    #[error("parent entries unavailable")]
45    ParentEntriesUnavailable,
46    #[error("parent info unavailable: slot {0} location {1}")]
47    ParentInfoUnavailable(Slot, BlockLocation),
48    #[error("merkle tree construction failure: slot {0} location {1}")]
49    MerkleTreeConstructionFailure(Slot, BlockLocation),
50    #[error("merkle proof construction failure: slot {0} location {1}")]
51    MerkleProofConstructionFailure(Slot, BlockLocation),
52    #[error("slot unavailable")]
53    SlotUnavailable,
54    #[error("unsupported transaction version")]
55    UnsupportedTransactionVersion,
56    #[error("missing transaction metadata")]
57    MissingTransactionMetadata,
58    #[error("transaction-index overflow")]
59    TransactionIndexOverflow,
60    #[error("invalid erasure config")]
61    InvalidErasureConfig,
62    #[error("last shred index missing slot {0}")]
63    UnknownLastIndex(Slot),
64    #[error("missing shred slot {0}, index {1}")]
65    MissingShred(Slot, u64),
66    #[error("legacy shred slot {0}, index {1}")]
67    LegacyShred(Slot, u64),
68    #[error("unable to read merkle root slot {0}, index {1}")]
69    MissingMerkleRoot(Slot, u64),
70    #[error("block contains an empty entry batch for slot {0}")]
71    EmptyEntryBatch(Slot),
72    #[error("unable to purge slots in range [{from_slot}, {to_slot}] {purge_type:?}: {inner:?}")]
73    PurgeFailed {
74        from_slot: Slot,
75        to_slot: Slot,
76        purge_type: PurgeType,
77        #[source]
78        inner: Box<BlockstoreError>,
79    },
80    #[error(transparent)]
81    ManualPurge(#[from] BlockstoreManualPurgeError),
82    #[error("update parent matches block header for slot {0}")]
83    UpdateParentMatchesBlockHeader(Slot),
84    #[error("update parent slot greater than block header for slot {0}")]
85    UpdateParentSlotGreaterThanBlockHeader(Slot),
86    #[error(
87        "update parent {update_parent_slot} is greater than shred parent {shred_parent_slot} for \
88         slot {slot}"
89    )]
90    UpdateParentSlotGreaterThanShredParent {
91        slot: Slot,
92        update_parent_slot: Slot,
93        shred_parent_slot: Slot,
94    },
95    #[error("update parent is only valid in the first slot of a leader window for slot {0}")]
96    UpdateParentNotFirstInLeaderWindow(Slot),
97    #[error("unexpected block component")]
98    UnexpectedBlockComponent,
99    #[error("multiple update parents for slot {0}")]
100    MultipleUpdateParents(Slot),
101    #[error("block component mismatch for slot {0}")]
102    BlockComponentMismatch(Slot),
103    #[error("invalid parent info for slot {slot}: parent {parent_slot}, max root {root}")]
104    InvalidParentInfo {
105        slot: Slot,
106        parent_slot: Slot,
107        root: Slot,
108    },
109    #[error(
110        "block header parent {block_header_parent_slot} does not match shred parent \
111         {shred_parent_slot} for slot {slot}"
112    )]
113    BlockHeaderParentMismatch {
114        slot: Slot,
115        block_header_parent_slot: Slot,
116        shred_parent_slot: Slot,
117    },
118    #[error("Block in slot {0} was aborted as leader sent an empty entry batch")]
119    BlockAborted(Slot),
120}
121pub type Result<T> = std::result::Result<T, BlockstoreError>;
122
123#[derive(Error, Debug)]
124pub enum BlockstoreManualPurgeError {
125    #[error("purge request sender is unavailable")]
126    SenderUnavailable,
127
128    #[error("purge request for slot {request_slot} must be less than the latest root {max_root}")]
129    SlotGreaterThanOrEqualToRoot { request_slot: Slot, max_root: Slot },
130
131    #[error("purge request try send error")]
132    TrySend,
133}
134
135impl<T> std::convert::From<crossbeam_channel::TrySendError<T>> for BlockstoreManualPurgeError {
136    fn from(_e: crossbeam_channel::TrySendError<T>) -> BlockstoreManualPurgeError {
137        BlockstoreManualPurgeError::TrySend
138    }
139}