Skip to main content

sidestr_core/
error.rs

1//! The one error type every fallible function in this crate returns.
2//!
3//! siding throws `Error` objects whose *messages* are the contract its tests
4//! match against (`/already claimed/`, `/below the minimum/`, `/not a hex
5//! script/`). The messages here keep that wording where a test in `tests/`
6//! depends on it, so a port of a siding test reads the same way.
7
8use crate::parents::Family;
9
10/// Everything that can go wrong, from a document that names a parent this
11/// validator does not carry to a block the rules refuse.
12#[derive(Debug, thiserror::Error)]
13pub enum Error {
14    /// The document names a parent alias that is not in the SPEC 3.2 table.
15    #[error("unknown parent \"{0}\": one of btc, tbtc4, xbt, txbt4, ltc, vtc (SPEC 3.2)")]
16    UnknownParent(String),
17    /// The alias is in the table but reserved: no validator carries its rules.
18    #[error(
19        "parent \"{alias}\" ({label}) is reserved: no validator carries its rules yet (SPEC 3.2)"
20    )]
21    ReservedParent {
22        /// The short alias, `ltc` or `vtc`.
23        alias: &'static str,
24        /// The human label from the table.
25        label: &'static str,
26    },
27    /// The document's parent hands down a header family other than the one
28    /// this state or chain is instantiated for (SPEC 3): a `State` over
29    /// `Stock` refuses a `txbt4` document, a `StateOf<Blake2bV2>` a `tbtc4` one.
30    #[error("the document's parent hands down the {0:?} header family, not the one this validator is instantiated for (SPEC 3.2: stock for btc/tbtc4, BLAKE2b for xbt/txbt4)")]
31    UnsupportedFamily(Family),
32    /// The chain document is malformed or names something this validator lacks.
33    #[error("chain document: {0}")]
34    Document(String),
35    /// JSON that does not parse or does not fit the document shape.
36    #[error("json: {0}")]
37    Json(#[from] serde_json::Error),
38    /// Bytes that do not decode as a block, transaction or hex.
39    #[error("encoding: {0}")]
40    Encoding(String),
41    /// A coinbase whose scriptSig does not start with a BIP 34 height push.
42    #[error("{0}")]
43    CoinbaseHeight(String),
44    /// A block the rules refused; `rules` lists the failed rule ids in order.
45    #[error("block {height} failed: {}", rules.join(", "))]
46    Rejected {
47        /// The height the block claimed.
48        height: u32,
49        /// The rule ids whose check returned `false`.
50        rules: Vec<String>,
51    },
52    /// A block that does not follow the tip, or whose hash is not the expected one.
53    #[error("{0}")]
54    Chain(String),
55    /// The block file's block 0 does not hash to the document's `genesisHash`.
56    #[error("genesis {found} is not the document's {expected}")]
57    GenesisMismatch {
58        /// The hash of block 0 as read.
59        found: String,
60        /// The document's `genesisHash`.
61        expected: String,
62    },
63    /// A transaction the producer's mempool policy or the rules refused.
64    #[error("{0}")]
65    Transaction(String),
66    /// Building or signing a block failed (no commitment output, a solution
67    /// too long for one push, a key that is not the challenge's).
68    #[error("{0}")]
69    Block(String),
70    /// A federation that cannot be built or used: signers out of range, a
71    /// duplicate signer, too few signatures, a key that is not a signer, or
72    /// `produce()` on a chain whose blocks come from a round.
73    #[error("federation: {0}")]
74    Federation(String),
75    /// The parent view: a node that cannot be reached or answers badly, a
76    /// cookie the node refuses, a script with no parent address, a
77    /// checkpoint over the data limit.
78    #[error("parent: {0}")]
79    Parent(String),
80    /// A secp256k1 failure: a bad key, a message that is not 32 bytes.
81    #[error("secp256k1: {0}")]
82    Secp(#[from] bitcoin::secp256k1::Error),
83    /// Filesystem trouble reading or writing the block file (feature `std`).
84    #[cfg(feature = "std")]
85    #[error("io: {0}")]
86    Io(#[from] std::io::Error),
87    /// The block file and its index disagree: an index entry that runs past
88    /// the end of `blocks.dat`, or a record whose `[u32 height][u32 size]`
89    /// prefix is not what the index entry says. Not gated on `std`: a
90    /// mirror's bytes are read the same way in a browser
91    /// ([`crate::mirror`]) as the file is on disk.
92    #[error("block file: {0}")]
93    BlockFile(String),
94}
95
96/// `Result` with this crate's [`Error`].
97pub type Result<T> = core::result::Result<T, Error>;