snarkos_errors/consensus/
consensus.rs

1// Copyright (C) 2019-2020 Aleo Systems Inc.
2// This file is part of the snarkOS library.
3
4// The snarkOS library is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8
9// The snarkOS library is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13
14// You should have received a copy of the GNU General Public License
15// along with the snarkOS library. If not, see <https://www.gnu.org/licenses/>.
16
17use crate::{
18    algorithms::CRHError,
19    dpc::DPCError,
20    objects::{BlockError, TransactionError},
21    posw::PoswError,
22    storage::StorageError,
23};
24
25use std::fmt::Debug;
26
27/// Possible block verification errors
28#[derive(Debug, Error)]
29pub enum ConsensusError {
30    #[error("UTXO has already been spent {:?} index: {:?}", _0, _1)]
31    AlreadySpent(Vec<u8>, u32),
32
33    #[error("{}", _0)]
34    BlockError(BlockError),
35
36    #[error("Block is too large: {}. Exceeds {} maximum", _0, _1)]
37    BlockTooLarge(usize, usize),
38
39    #[error("A coinbase transaction already exists in the block")]
40    CoinbaseTransactionAlreadyExists(),
41
42    #[error("conflicting network ids: {}, {}", _0, _1)]
43    ConflictingNetworkId(u8, u8),
44
45    #[error("{}: {}", _0, _1)]
46    Crate(&'static str, String),
47
48    #[error("{}", _0)]
49    CRHError(CRHError),
50
51    #[error("wrong difficulty, expected {0} got {1}")]
52    DifficultyMismatch(u64, u64),
53
54    #[error("{}", _0)]
55    DPCError(DPCError),
56
57    #[error("timestamp more than 2 hours into the future {:?} actual {:?}", _0, _1)]
58    FuturisticTimestamp(i64, i64),
59
60    #[error("invalid block {:?}", _0)]
61    InvalidBlock(Vec<u8>),
62
63    #[error("invalid coinbase transaction")]
64    InvalidCoinbaseTransaction,
65
66    #[error("block transactions do not hash to merkle root {:?}", _0)]
67    MerkleRoot(String),
68
69    #[error("{}", _0)]
70    Message(String),
71
72    #[error("the block has multiple coinbase transactions: {:?}", _0)]
73    MultipleCoinbaseTransactions(u32),
74
75    #[error("nonce {:?} is greater than nonce limit {:?}", _0, _1)]
76    NonceInvalid(u32, u32),
77
78    #[error("all nonces have been tried for the current block header")]
79    NonceLimitError,
80
81    #[error("Missing genesis block")]
82    NoGenesisBlock,
83
84    #[error("expected {:?} actual {:?}", _0, _1)]
85    NoParent(String, String),
86
87    #[error("block subroots do not hash to the pedersen merkle root {0}")]
88    PedersenMerkleRoot(String),
89
90    #[error("header greater than difficulty target {:?} actual {:?}", _0, _1)]
91    PowInvalid(u64, u64),
92
93    #[error(transparent)]
94    PoswError(#[from] PoswError),
95
96    #[error("{}", _0)]
97    StorageError(StorageError),
98
99    #[error("timestamp {:?} is less than parent timestamp {:?}", _0, _1)]
100    TimestampInvalid(i64, i64),
101
102    #[error("{}", _0)]
103    TransactionError(TransactionError),
104
105    #[error("Transactions are spending more funds than they have available")]
106    TransactionOverspending,
107}
108
109impl From<BlockError> for ConsensusError {
110    fn from(error: BlockError) -> Self {
111        ConsensusError::BlockError(error)
112    }
113}
114
115impl From<CRHError> for ConsensusError {
116    fn from(error: CRHError) -> Self {
117        ConsensusError::CRHError(error)
118    }
119}
120
121impl From<DPCError> for ConsensusError {
122    fn from(error: DPCError) -> Self {
123        ConsensusError::DPCError(error)
124    }
125}
126
127impl From<StorageError> for ConsensusError {
128    fn from(error: StorageError) -> Self {
129        ConsensusError::StorageError(error)
130    }
131}
132
133impl From<TransactionError> for ConsensusError {
134    fn from(error: TransactionError) -> Self {
135        ConsensusError::TransactionError(error)
136    }
137}
138
139impl From<bincode::Error> for ConsensusError {
140    fn from(error: bincode::Error) -> Self {
141        ConsensusError::Crate("bincode", format!("{:?}", error))
142    }
143}
144
145impl From<std::io::Error> for ConsensusError {
146    fn from(error: std::io::Error) -> Self {
147        ConsensusError::Crate("std::io", format!("{:?}", error))
148    }
149}