Skip to main content

cuprated/blockchain/
error.rs

1//! Error types for the blockchain manager interface.
2
3use cuprate_blockchain::BlockchainError;
4use cuprate_consensus::{block::BlockVerificationError, ExtendedConsensusError};
5use cuprate_consensus_rules::ConsensusError;
6use cuprate_txpool::TxPoolError;
7
8use crate::monitor::FatalError;
9
10/// An error returned from [`BlockchainManagerHandle::handle_incoming_block`](super::interface::BlockchainManagerHandle::handle_incoming_block).
11#[derive(Debug, thiserror::Error)]
12pub enum IncomingBlockError {
13    /// The peer sent us an invalid block.
14    #[error("Block verification failed: {inner}")]
15    Validation {
16        /// Whether the block's proof-of-work was verified before the failure.
17        pow_valid: bool,
18        /// The consensus rule that was broken.
19        inner: ConsensusError,
20    },
21
22    /// We cannot recover; shut the node down.
23    #[error(transparent)]
24    Fatal(#[from] FatalError),
25
26    /// We are missing the block's parent.
27    #[error("The block has an unknown parent.")]
28    Orphan,
29
30    /// Some transactions in the block were unknown.
31    ///
32    /// The inner values are the block hash and the indexes of the missing txs in the block.
33    #[error("Unknown transactions in block.")]
34    UnknownTransactions([u8; 32], Vec<usize>),
35
36    /// The block claimed more transactions than it contained.
37    #[error("Too many transactions given for block.")]
38    TooManyTxs,
39
40    /// The blockchain manager command channel is closed.
41    #[error("The blockchain manager command channel is closed.")]
42    ChannelClosed,
43}
44
45impl From<BlockVerificationError> for IncomingBlockError {
46    fn from(error: BlockVerificationError) -> Self {
47        let BlockVerificationError { pow_valid, inner } = error;
48
49        match inner {
50            ExtendedConsensusError::FatalError(error) => Self::Fatal(error),
51            ExtendedConsensusError::ConsensusError(inner) => Self::Validation { pow_valid, inner },
52        }
53    }
54}
55
56impl From<BlockchainError> for IncomingBlockError {
57    fn from(e: BlockchainError) -> Self {
58        Self::Fatal(e.into())
59    }
60}
61
62impl From<TxPoolError> for IncomingBlockError {
63    fn from(v: TxPoolError) -> Self {
64        Self::Fatal(v.into())
65    }
66}