1use alloc::string::{FromUtf8Error, String};
5use core::{convert::Infallible, fmt};
6
7use crypto::Error as CryptoError;
8use prefix_hex::Error as HexError;
9use primitive_types::U256;
10
11use crate::block::output::{
12 AliasId, ChainId, MetadataFeatureLength, NativeTokenCount, NftId, OutputIndex,
13 StateMetadataLength, TagFeatureLength, feature::FeatureCount,
14 unlock_condition::UnlockConditionCount,
15};
16
17#[derive(Debug, PartialEq, Eq)]
19#[allow(missing_docs)]
20pub enum Error {
21 ConsumedAmountOverflow,
22 ConsumedNativeTokensAmountOverflow,
23 CreatedAmountOverflow,
24 CreatedNativeTokensAmountOverflow,
25 Crypto(CryptoError),
26 DuplicateSignatureUnlock(u16),
27 ExpirationUnlockConditionZero,
28 FeaturesNotUniqueSorted,
29 InputUnlockCountMismatch {
30 input_count: usize,
31 unlock_count: usize,
32 },
33 InvalidAddress,
34 InvalidAddressKind(u8),
35 InvalidBech32Hrp(String),
36 InvalidStorageDepositAmount(u64),
37 InsufficientStorageDepositAmount {
40 amount: u64,
41 required: u64,
42 },
43 StorageDepositReturnExceedsOutputAmount {
44 deposit: u64,
45 amount: u64,
46 },
47 InsufficientStorageDepositReturnAmount {
48 deposit: u64,
49 required: u64,
50 },
51 InvalidEssenceKind(u8),
52 InvalidFeatureCount(<FeatureCount as TryFrom<usize>>::Error),
53 InvalidFeatureKind(u8),
54 InvalidFoundryOutputSupply {
55 minted: U256,
56 melted: U256,
57 max: U256,
58 },
59 Hex(HexError),
60 InvalidInputKind(u8),
61 InvalidInputOutputIndex(<OutputIndex as TryFrom<u16>>::Error),
62 InvalidBlockLength(usize),
63 InvalidStateMetadataLength(<StateMetadataLength as TryFrom<usize>>::Error),
64 InvalidMetadataFeatureLength(<MetadataFeatureLength as TryFrom<usize>>::Error),
65 InvalidMilestoneOptionKind(u8),
66 InvalidBinaryParametersLength(packable::bounded::InvalidBoundedU16<0, 8192>),
67 InvalidBinaryParametersLengthValue(usize),
68 InvalidMigratedFundsEntryAmount(u64),
69 InvalidNativeTokenCount(<NativeTokenCount as TryFrom<usize>>::Error),
70 InvalidNetworkName(FromUtf8Error),
71 InvalidOutputAmount(u64),
72 InvalidOutputKind(u8),
73 InvalidPayloadKind(u32),
74 InvalidPayloadLength {
75 expected: usize,
76 actual: usize,
77 },
78 InvalidReceiptFundsSum(u128),
79 InvalidSignature,
80 InvalidSignatureKind(u8),
81 InvalidStringPrefix(<u8 as TryFrom<usize>>::Error),
82 InvalidTagFeatureLength(<TagFeatureLength as TryFrom<usize>>::Error),
83 InvalidTailTransactionHash,
84 InvalidTokenSchemeKind(u8),
85 InvalidTransactionAmountSum(u128),
86 InvalidTransactionNativeTokensCount(u16),
87 InvalidTreasuryOutputAmount(u64),
88 InvalidUnlockKind(u8),
89 InvalidUnlockReference(u16),
90 InvalidUnlockAlias(u16),
91 InvalidUnlockNft(u16),
92 InvalidUnlockConditionCount(<UnlockConditionCount as TryFrom<usize>>::Error),
93 InvalidUnlockConditionKind(u8),
94 InvalidFoundryZeroSerialNumber,
95 MilestonePublicKeysSignaturesCountMismatch {
96 key_count: usize,
97 sig_count: usize,
98 },
99 MilestoneOptionsNotUniqueSorted,
100 MilestoneSignaturesNotUniqueSorted,
101 MissingAddressUnlockCondition,
102 MissingGovernorUnlockCondition,
103 MissingStateControllerUnlockCondition,
104 NativeTokensNotUniqueSorted,
105 NativeTokensNullAmount,
106 NativeTokensOverflow,
107 NetworkIdMismatch {
108 expected: u64,
109 actual: u64,
110 },
111 NonZeroStateIndexOrFoundryCounter,
112 ParentsNotUniqueSorted,
113 ProtocolVersionMismatch {
114 expected: u8,
115 actual: u8,
116 },
117 NonceNotFound,
118 ReceiptFundsNotUniqueSorted,
119 RemainingBytesAfterBlock,
120 SelfControlledAliasOutput(AliasId),
121 SelfDepositNft(NftId),
122 SignaturePublicKeyMismatch {
123 expected: String,
124 actual: String,
125 },
126 StorageDepositReturnOverflow,
127 TailTransactionHashNotUnique {
128 previous: usize,
129 current: usize,
130 },
131 TimelockUnlockConditionZero,
132 UnallowedFeature {
133 index: usize,
134 kind: u8,
135 },
136 UnallowedUnlockCondition {
137 index: usize,
138 kind: u8,
139 },
140 UnlockConditionsNotUniqueSorted,
141 UnsupportedOutputKind(u8),
142 DuplicateOutputChain(ChainId),
143 InvalidField(&'static str),
144}
145
146#[cfg(feature = "std")]
147impl std::error::Error for Error {}
148
149impl fmt::Display for Error {
150 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
151 match self {
152 Self::ConsumedAmountOverflow => write!(f, "consumed amount overflow"),
153 Self::ConsumedNativeTokensAmountOverflow => {
154 write!(f, "consumed native tokens amount overflow")
155 }
156 Self::CreatedAmountOverflow => write!(f, "created amount overflow"),
157 Self::CreatedNativeTokensAmountOverflow => {
158 write!(f, "created native tokens amount overflow")
159 }
160 Self::Crypto(e) => write!(f, "cryptographic error: {e}"),
161 Self::DuplicateSignatureUnlock(index) => {
162 write!(f, "duplicate signature unlock at index: {index}")
163 }
164 Self::ExpirationUnlockConditionZero => {
165 write!(
166 f,
167 "expiration unlock condition with milestone index and timestamp set to 0",
168 )
169 }
170 Self::FeaturesNotUniqueSorted => write!(f, "features are not unique and/or sorted"),
171 Self::InputUnlockCountMismatch {
172 input_count,
173 unlock_count,
174 } => {
175 write!(
176 f,
177 "input count and unlock count mismatch: {input_count} != {unlock_count}",
178 )
179 }
180 Self::InvalidAddress => write!(f, "invalid address provided"),
181 Self::InvalidAddressKind(k) => write!(f, "invalid address kind: {k}"),
182 Self::InvalidBech32Hrp(hrp) => write!(f, "invalid bech32 hrp: {hrp}"),
183 Self::InvalidStorageDepositAmount(amount) => {
184 write!(f, "invalid storage deposit amount: {amount}")
185 }
186 Self::InsufficientStorageDepositAmount { amount, required } => {
187 write!(
188 f,
189 "insufficient output amount for storage deposit: {amount} (should be at least {required})"
190 )
191 }
192 Self::InsufficientStorageDepositReturnAmount { deposit, required } => {
193 write!(
194 f,
195 "the return deposit ({deposit}) must be greater than the minimum storage deposit ({required})"
196 )
197 }
198 Self::StorageDepositReturnExceedsOutputAmount { deposit, amount } => write!(
199 f,
200 "storage deposit return of {deposit} exceeds the original output amount of {amount}"
201 ),
202 Self::InvalidEssenceKind(k) => write!(f, "invalid essence kind: {k}"),
203 Self::InvalidFeatureCount(count) => write!(f, "invalid feature count: {count}"),
204 Self::InvalidFeatureKind(k) => write!(f, "invalid feature kind: {k}"),
205 Self::InvalidFoundryOutputSupply {
206 minted,
207 melted,
208 max,
209 } => write!(
210 f,
211 "invalid foundry output supply: minted {minted}, melted {melted} max {max}",
212 ),
213 Self::Hex(error) => write!(f, "hex error: {error}"),
214 Self::InvalidInputKind(k) => write!(f, "invalid input kind: {k}"),
215 Self::InvalidInputOutputIndex(index) => {
216 write!(f, "invalid input or output index: {index}")
217 }
218 Self::InvalidBlockLength(length) => write!(f, "invalid block length {length}"),
219 Self::InvalidStateMetadataLength(length) => {
220 write!(f, "invalid state metadata length {length}")
221 }
222 Self::InvalidMetadataFeatureLength(length) => {
223 write!(f, "invalid metadata feature length {length}")
224 }
225
226 Self::InvalidMilestoneOptionKind(k) => write!(f, "invalid milestone option kind: {k}"),
227 Self::InvalidBinaryParametersLength(length) => {
228 write!(f, "invalid binary parameters length: {length}")
229 }
230 Self::InvalidBinaryParametersLengthValue(length) => {
231 write!(f, "invalid binary parameters length: {length}")
232 }
233 Self::InvalidMigratedFundsEntryAmount(amount) => {
234 write!(f, "invalid migrated funds entry amount: {amount}")
235 }
236 Self::InvalidNativeTokenCount(count) => {
237 write!(f, "invalid native token count: {count}")
238 }
239 Self::InvalidNetworkName(err) => write!(f, "invalid network name: {err}"),
240 Self::InvalidOutputAmount(amount) => write!(f, "invalid output amount: {amount}"),
241 Self::InvalidOutputKind(k) => write!(f, "invalid output kind: {k}"),
242
243 Self::InvalidPayloadKind(k) => write!(f, "invalid payload kind: {k}"),
244 Self::InvalidPayloadLength { expected, actual } => {
245 write!(
246 f,
247 "invalid payload length: expected {expected} but got {actual}"
248 )
249 }
250
251 Self::InvalidReceiptFundsSum(sum) => write!(f, "invalid receipt amount sum: {sum}"),
252 Self::InvalidSignature => write!(f, "invalid signature provided"),
253 Self::InvalidSignatureKind(k) => write!(f, "invalid signature kind: {k}"),
254 Self::InvalidStringPrefix(p) => write!(f, "invalid string prefix: {p}"),
255 Self::InvalidTagFeatureLength(length) => {
256 write!(f, "invalid tag feature length {length}")
257 }
258 Self::InvalidTailTransactionHash => write!(f, "invalid tail transaction hash"),
259 Self::InvalidTokenSchemeKind(k) => write!(f, "invalid token scheme kind {k}"),
260 Self::InvalidTransactionAmountSum(value) => {
261 write!(f, "invalid transaction amount sum: {value}")
262 }
263 Self::InvalidTransactionNativeTokensCount(count) => {
264 write!(f, "invalid transaction native tokens count: {count}")
265 }
266 Self::InvalidTreasuryOutputAmount(amount) => {
267 write!(f, "invalid treasury amount: {amount}")
268 }
269 Self::InvalidUnlockKind(k) => write!(f, "invalid unlock kind: {k}"),
270 Self::InvalidUnlockReference(index) => {
271 write!(f, "invalid unlock reference: {index}")
272 }
273 Self::InvalidUnlockAlias(index) => {
274 write!(f, "invalid unlock alias: {index}")
275 }
276 Self::InvalidUnlockNft(index) => {
277 write!(f, "invalid unlock nft: {index}")
278 }
279 Self::InvalidUnlockConditionCount(count) => {
280 write!(f, "invalid unlock condition count: {count}")
281 }
282 Self::InvalidUnlockConditionKind(k) => write!(f, "invalid unlock condition kind: {k}"),
283 Self::InvalidFoundryZeroSerialNumber => write!(f, "invalid foundry zero serial number"),
284
285 Self::MilestonePublicKeysSignaturesCountMismatch {
286 key_count,
287 sig_count,
288 } => {
289 write!(
290 f,
291 "milestone public keys and signatures count mismatch: {key_count} != {sig_count}",
292 )
293 }
294 Self::MilestoneOptionsNotUniqueSorted => {
295 write!(f, "milestone options are not unique and/or sorted")
296 }
297 Self::MilestoneSignaturesNotUniqueSorted => {
298 write!(f, "milestone signatures are not unique and/or sorted")
299 }
300 Self::MissingAddressUnlockCondition => write!(f, "missing address unlock condition"),
301 Self::MissingGovernorUnlockCondition => write!(f, "missing governor unlock condition"),
302 Self::MissingStateControllerUnlockCondition => {
303 write!(f, "missing state controller unlock condition")
304 }
305 Self::NativeTokensNotUniqueSorted => {
306 write!(f, "native tokens are not unique and/or sorted")
307 }
308 Self::NativeTokensNullAmount => write!(f, "native tokens null amount"),
309 Self::NativeTokensOverflow => write!(f, "native tokens overflow"),
310 Self::NetworkIdMismatch { expected, actual } => {
311 write!(
312 f,
313 "network ID mismatch: expected {expected} but got {actual}"
314 )
315 }
316 Self::NonZeroStateIndexOrFoundryCounter => {
317 write!(
318 f,
319 "non zero state index or foundry counter while alias ID is all zero"
320 )
321 }
322 Self::ParentsNotUniqueSorted => {
323 write!(f, "parents are not unique and/or sorted")
324 }
325 Self::ProtocolVersionMismatch { expected, actual } => {
326 write!(
327 f,
328 "protocol version mismatch: expected {expected} but got {actual}"
329 )
330 }
331 Self::NonceNotFound => {
332 write!(f, "nonce miner could not find a nonce")
333 }
334 Self::ReceiptFundsNotUniqueSorted => {
335 write!(f, "receipt funds are not unique and/or sorted")
336 }
337 Self::RemainingBytesAfterBlock => {
338 write!(f, "remaining bytes after block")
339 }
340 Self::SelfControlledAliasOutput(alias_id) => {
341 write!(f, "self controlled alias output, alias ID {alias_id}")
342 }
343 Self::SelfDepositNft(nft_id) => {
344 write!(f, "self deposit nft output, NFT ID {nft_id}")
345 }
346 Self::SignaturePublicKeyMismatch { expected, actual } => {
347 write!(
348 f,
349 "signature public key mismatch: expected {expected} but got {actual}",
350 )
351 }
352 Self::StorageDepositReturnOverflow => {
353 write!(f, "storage deposit return overflow",)
354 }
355 Self::TailTransactionHashNotUnique { previous, current } => {
356 write!(
357 f,
358 "tail transaction hash is not unique at indices: {previous} and {current}",
359 )
360 }
361 Self::TimelockUnlockConditionZero => {
362 write!(
363 f,
364 "timelock unlock condition with milestone index and timestamp set to 0",
365 )
366 }
367 Self::UnallowedFeature { index, kind } => {
368 write!(f, "unallowed feature at index {index} with kind {kind}")
369 }
370 Self::UnallowedUnlockCondition { index, kind } => {
371 write!(
372 f,
373 "unallowed unlock condition at index {index} with kind {kind}"
374 )
375 }
376 Self::UnlockConditionsNotUniqueSorted => {
377 write!(f, "unlock conditions are not unique and/or sorted")
378 }
379 Self::UnsupportedOutputKind(k) => write!(f, "unsupported output kind: {k}"),
380 Self::DuplicateOutputChain(chain_id) => write!(f, "duplicate output chain {chain_id}"),
381 Self::InvalidField(field) => write!(f, "invalid field: {field}"),
382 }
383 }
384}
385
386impl From<CryptoError> for Error {
387 fn from(error: CryptoError) -> Self {
388 Self::Crypto(error)
389 }
390}
391
392impl From<Infallible> for Error {
393 fn from(error: Infallible) -> Self {
394 match error {}
395 }
396}