1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
use crate::consts::appconsts;

/// Alias for a `Result` with the error type [`celestia_types::Error`].
///
/// [`celestia_types::Error`]: crate::Error
pub type Result<T, E = Error> = std::result::Result<T, E>;

/// Representation of all the errors that can occur when interacting with [`celestia_types`].
///
/// [`celestia_types`]: crate
#[derive(Debug, thiserror::Error)]
pub enum Error {
    /// Unsupported namespace version.
    #[error("Unsupported namespace version: {0}")]
    UnsupportedNamespaceVersion(u8),

    /// Invalid namespace size.
    #[error("Invalid namespace size")]
    InvalidNamespaceSize,

    /// Error propagated from the [`celestia_tendermint`].
    #[error(transparent)]
    Tendermint(#[from] celestia_tendermint::Error),

    /// Error propagated from the [`celestia_tendermint_proto`].
    #[error(transparent)]
    Protobuf(#[from] celestia_tendermint_proto::Error),

    /// Error propagated from the [`cid::multihash`].
    #[error(transparent)]
    Multihash(#[from] cid::multihash::Error),

    /// Error returned when trying to compute new or parse existing CID. See [`blockstore::block`]
    #[error(transparent)]
    CidError(#[from] blockstore::block::CidError),

    /// Missing header.
    #[error("Missing header")]
    MissingHeader,

    /// Missing commit.
    #[error("Missing commit")]
    MissingCommit,

    /// Missing validator set.
    #[error("Missing validator set")]
    MissingValidatorSet,

    /// Missing data availability header.
    #[error("Missing data availability header")]
    MissingDataAvailabilityHeader,

    /// Missing proof.
    #[error("Missing proof")]
    MissingProof,

    /// Wrong proof type.
    #[error("Wrong proof type")]
    WrongProofType,

    /// Unsupported share version.
    #[error("Unsupported share version: {0}")]
    UnsupportedShareVersion(u8),

    /// Invalid share size.
    #[error("Invalid share size: {0}")]
    InvalidShareSize(usize),

    /// Invalid nmt leaf size.
    #[error("Invalid nmt leaf size: {0}")]
    InvalidNmtLeafSize(usize),

    /// Invalid nmt node order.
    #[error("Invalid nmt node order")]
    InvalidNmtNodeOrder,

    /// Share sequence length exceeded.
    #[error(
        "Sequence len must fit into {} bytes, got value {0}",
        appconsts::SEQUENCE_LEN_BYTES
    )]
    ShareSequenceLenExceeded(usize),

    /// Invalid namespace in version 0.
    #[error("Invalid namespace v0")]
    InvalidNamespaceV0,

    /// Invalid namespace in version 255.
    #[error("Invalid namespace v255")]
    InvalidNamespaceV255,

    /// Invalid namespaced hash.
    #[error(transparent)]
    InvalidNamespacedHash(#[from] nmt_rs::InvalidNamespacedHash),

    /// Invalid index of signature in commit.
    #[error("Invalid index of signature in commit {0}, height {1}")]
    InvalidSignatureIndex(usize, u64),

    /// Invalid axis.
    #[error("Invalid axis type: {0}")]
    InvalidAxis(i32),

    /// Range proof verification error.
    #[error("Range proof verification failed: {0:?}")]
    RangeProofError(nmt_rs::simple_merkle::error::RangeProofError),

    /// Row root computed from shares doesn't match one received in `DataAvailabilityHeaderz
    #[error("Computed root doesn't match received one")]
    RootMismatch,

    /// Unexpected signature in absent commit.
    #[error("Unexpected absent commit signature")]
    UnexpectedAbsentSignature,

    /// Error that happened during validation.
    #[error("Validation error: {0}")]
    Validation(#[from] ValidationError),

    /// Error that happened during verification.
    #[error("Verification error: {0}")]
    Verification(#[from] VerificationError),

    /// Max share version exceeded.
    #[error(
        "Share version has to be at most {}, got {0}",
        appconsts::MAX_SHARE_VERSION
    )]
    MaxShareVersionExceeded(u8),

    /// An error related to the namespaced merkle tree.
    #[error("Nmt error: {0}")]
    Nmt(&'static str),

    /// Invalid address bech32 prefix.
    #[error("Invalid address prefix: {0}")]
    InvalidAddressPrefix(String),

    /// Invalid size of the address.
    #[error("Invalid address size: {0}")]
    InvalidAddressSize(usize),

    /// Invalid address.
    #[error("Invalid address: {0}")]
    InvalidAddress(String),

    /// Invalid balance denomination.
    #[error("Invalid balance denomination: {0}")]
    InvalidBalanceDenomination(String),

    /// Invalid balance amount.
    #[error("Invalid balance amount: {0}")]
    InvalidBalanceAmount(String),

    /// Unsupported fraud proof type.
    #[error("Unsupported fraud proof type: {0}")]
    UnsupportedFraudProofType(String),

    /// Data square index out of range.
    #[error("Data square index out of range: {0}")]
    EdsIndexOutOfRange(usize),

    /// Could not create EDS, provided number of shares doesn't form a pefect square
    #[error("Invalid dimensions of EDS")]
    EdsInvalidDimentions,

    /// Zero block height.
    #[error("Invalid zero block height")]
    ZeroBlockHeight,
}

/// Representation of the errors that can occur when validating data.
///
/// See [`ValidateBasic`]
///
/// [`ValidateBasic`]: crate::ValidateBasic
#[derive(Debug, thiserror::Error)]
pub enum ValidationError {
    /// Not enough voting power for a commit.
    #[error("Not enought voting power (got {0}, needed {1})")]
    NotEnoughVotingPower(u64, u64),

    /// Other errors that can happen during validation.
    #[error("{0}")]
    Other(String),
}

/// Representation of the errors that can occur when verifying data.
///
/// See [`ExtendedHeader::verify`].
///
/// [`ExtendedHeader::verify`]: crate::ExtendedHeader::verify
#[derive(Debug, thiserror::Error)]
pub enum VerificationError {
    /// Not enough voting power for a commit.
    #[error("Not enought voting power (got {0}, needed {1})")]
    NotEnoughVotingPower(u64, u64),

    /// Other errors that can happen during verification.
    #[error("{0}")]
    Other(String),
}

macro_rules! validation_error {
    ($fmt:literal $(,)?) => {
        $crate::ValidationError::Other(std::format!($fmt))
    };
    ($fmt:literal, $($arg:tt)*) => {
        $crate::ValidationError::Other(std::format!($fmt, $($arg)*))
    };
}

macro_rules! bail_validation {
    ($($arg:tt)*) => {
        return Err($crate::validation_error!($($arg)*).into())
    };
}

macro_rules! verification_error {
    ($fmt:literal $(,)?) => {
        $crate::VerificationError::Other(std::format!($fmt))
    };
    ($fmt:literal, $($arg:tt)*) => {
        $crate::VerificationError::Other(std::format!($fmt, $($arg)*))
    };
}

macro_rules! bail_verification {
    ($($arg:tt)*) => {
        return Err($crate::verification_error!($($arg)*).into())
    };
}

// NOTE: This need to be always after the macro definitions
pub(crate) use bail_validation;
pub(crate) use bail_verification;
pub(crate) use validation_error;
pub(crate) use verification_error;