1use near_primitives::block::BlockValidityError;
2use near_primitives::challenge::{ChunkProofs, MaybeEncodedShardChunk};
3use near_primitives::errors::{
4 ChunkAccessError, EpochError, InvalidSpiceCoreStatementsError, StorageError,
5};
6use near_primitives::shard_layout::ShardLayoutError;
7use near_primitives::sharding::{BadHeaderForProtocolVersionError, ChunkHash, ShardChunkHeader};
8use near_primitives::types::{BlockHeight, EpochId, ShardId, ShardIndex};
9use near_time::Utc;
10use std::io;
11
12#[derive(thiserror::Error, Debug)]
13pub enum QueryError {
14 #[error("Account ID {requested_account_id} is invalid")]
15 InvalidAccount {
16 requested_account_id: near_primitives::types::AccountId,
17 block_height: near_primitives::types::BlockHeight,
18 block_hash: near_primitives::hash::CryptoHash,
19 },
20 #[error("Account {requested_account_id} does not exist while viewing")]
21 UnknownAccount {
22 requested_account_id: near_primitives::types::AccountId,
23 block_height: near_primitives::types::BlockHeight,
24 block_hash: near_primitives::hash::CryptoHash,
25 },
26 #[error(
27 "Contract code for contract ID {contract_account_id} has never been observed on the node"
28 )]
29 NoContractCode {
30 contract_account_id: near_primitives::types::AccountId,
31 block_height: near_primitives::types::BlockHeight,
32 block_hash: near_primitives::hash::CryptoHash,
33 },
34 #[error("Access key for public key {public_key} does not exist while viewing")]
35 UnknownAccessKey {
36 public_key: near_crypto::PublicKey,
37 block_height: near_primitives::types::BlockHeight,
38 block_hash: near_primitives::hash::CryptoHash,
39 },
40 #[error("Gas key for public key {public_key} does not exist while viewing")]
41 UnknownGasKey {
42 public_key: near_crypto::PublicKey,
43 block_height: near_primitives::types::BlockHeight,
44 block_hash: near_primitives::hash::CryptoHash,
45 },
46 #[error("Internal error occurred: {error_message}")]
47 InternalError {
48 error_message: String,
49 block_height: near_primitives::types::BlockHeight,
50 block_hash: near_primitives::hash::CryptoHash,
51 },
52 #[error("Function call returned an error: {error_message}")]
53 ContractExecutionError {
54 error_message: String,
55 error: near_primitives::errors::FunctionCallError,
56 block_height: near_primitives::types::BlockHeight,
57 block_hash: near_primitives::hash::CryptoHash,
58 },
59 #[error("The state of account {requested_account_id} is too large")]
60 TooLargeContractState {
61 requested_account_id: near_primitives::types::AccountId,
62 block_height: near_primitives::types::BlockHeight,
63 block_hash: near_primitives::hash::CryptoHash,
64 },
65 #[error(
66 "Global contract code with identifier {identifier:?} has never been observed on the node"
67 )]
68 NoGlobalContractCode {
69 identifier: near_primitives::action::GlobalContractIdentifier,
70 block_height: near_primitives::types::BlockHeight,
71 block_hash: near_primitives::hash::CryptoHash,
72 },
73}
74
75#[derive(Debug, thiserror::Error)]
76pub enum Error {
77 #[error("Block is known: {0}")]
79 BlockKnown(#[from] BlockKnownError),
80 #[error("Too many blocks being processed")]
81 TooManyProcessingBlocks,
82 #[error("Orphan")]
84 Orphan,
85 #[error("Chunk Missing (unavailable on the node): {0:?}")]
87 ChunkMissing(ChunkHash),
88 #[error("Chunks Missing: {0:?}")]
90 ChunksMissing(Vec<ShardChunkHeader>),
91 #[error("Block Pending Optimistic Execution")]
93 BlockPendingOptimisticExecution,
94 #[error("Invalid Block Time: block time {1} before previous {0}")]
96 InvalidBlockPastTime(Utc, Utc),
97 #[error("Invalid Block Time: Too far in the future: {0}")]
99 InvalidBlockFutureTime(Utc),
100 #[error("Invalid Block Height {0}")]
102 InvalidBlockHeight(BlockHeight),
103 #[error("Invalid Block Proposer Signature")]
105 InvalidBlockProposer,
106 #[error("Invalid State Root Hash")]
108 InvalidStateRoot,
109 #[error("Invalid Chunk Encoded Merkle Root Hash")]
111 InvalidChunkEncodedMerkleRoot,
112 #[error("Invalid Chunk Encoded Merkle Length")]
114 InvalidChunkEncodedLength,
115 #[error("Invalid Block Tx Root Hash")]
117 InvalidTxRoot,
118 #[error("Invalid Chunk Receipts Root Hash")]
120 InvalidChunkReceiptsRoot,
121 #[error("Invalid Chunk Headers Root Hash")]
123 InvalidChunkHeadersRoot,
124 #[error("Invalid Chunk Tx Root Hash")]
126 InvalidChunkTxRoot,
127 #[error("Invalid Receipts Proof")]
129 InvalidReceiptsProof,
130 #[error("Invalid Outcomes Proof")]
132 InvalidOutcomesProof,
133 #[error("Invalid State Payload")]
135 InvalidStatePayload,
136 #[error("Invalid Transactions")]
138 InvalidTransactions,
139 #[error("Invalid Challenge")]
141 InvalidChallenge,
142 #[error("Incorrect Number of Chunk Headers")]
144 IncorrectNumberOfChunkHeaders,
145 #[error("Invalid Chunk")]
147 InvalidChunk(String),
148 #[error("Invalid Chunk Transactions Order")]
150 InvalidChunkTransactionsOrder(Box<MaybeEncodedShardChunk>),
151 #[error("Invalid Chunk Proofs")]
153 InvalidChunkProofs(Box<ChunkProofs>),
154 #[error("Invalid Chunk State Witness: {0}")]
155 InvalidChunkStateWitness(String),
156 #[error("Invalid Partial Chunk State Witness: {0}")]
157 InvalidPartialChunkStateWitness(String),
158 #[error("Invalid Chunk Endorsement")]
159 InvalidChunkEndorsement,
160 #[error("Invalid Chunk Endorsement Bitmap")]
162 InvalidChunkEndorsementBitmap(String),
163 #[error("Invalid Chunk Mask")]
165 InvalidChunkMask,
166 #[error("Invalid Epoch Hash")]
168 InvalidEpochHash,
169 #[error("Invalid Next BP Hash")]
171 InvalidNextBPHash,
172 #[error("Invalid protocol version")]
174 InvalidProtocolVersion,
175 #[error("Not enough approvals")]
177 NotEnoughApprovals,
178 #[error("Invalid finality info")]
180 InvalidFinalityInfo,
181 #[error("Invalid Validator Proposals")]
183 InvalidValidatorProposals,
184 #[error("Invalid Signature")]
186 InvalidSignature,
187 #[error("Invalid Approvals")]
189 InvalidApprovals,
190 #[error("Invalid Gas Limit")]
192 InvalidGasLimit,
193 #[error("Invalid Gas Price")]
195 InvalidGasPrice,
196 #[error("Invalid Gas Used")]
198 InvalidGasUsed,
199 #[error("Invalid Balance Burnt")]
201 InvalidBalanceBurnt,
202 #[error("Invalid Total Supply")]
204 InvalidTotalSupply,
205 #[error("Invalid Congestion Info: {0}")]
207 InvalidCongestionInfo(String),
208 #[error("Invalid bandwidth requests - chunk extra doesn't match chunk header: {0}")]
210 InvalidBandwidthRequests(String),
211 #[error("Invalid proposed_split in chunk header: {0}")]
213 InvalidChunkHeaderShardSplit(String),
214 #[error("Invalid shard_split in block header: {0}")]
216 InvalidBlockHeaderShardSplit(String),
217 #[error("Shard id {0} does not exist")]
219 InvalidShardId(ShardId),
220 #[error("Shard index {0} does not exist")]
221 InvalidShardIndex(ShardIndex),
222 #[error("Shard id {0} does not have a parent")]
223 NoParentShardId(ShardId),
224 #[error("Cannot derive shard layout")]
225 CannotDeriveLayout,
226 #[error("Invalid state request: {0}")]
228 InvalidStateRequest(String),
229 #[error("Invalid Randomness Beacon Output")]
231 InvalidRandomnessBeaconOutput,
232 #[error("Invalid Block Merkle Root")]
234 InvalidBlockMerkleRoot,
235 #[error("Invalid Block Ordinal")]
237 InvalidBlockOrdinal,
238 #[error("Invalid Epoch Sync Data Hash")]
240 InvalidEpochSyncDataHash,
241 #[error("Invalid Split Shard Ids when resharding. shard_id: {0}, parent_shard_id: {1}")]
243 InvalidSplitShardsIds(ShardId, ShardId),
244 #[error("Not A Validator: {0}")]
246 NotAValidator(String),
247 #[error("Not A Chunk Validator")]
251 NotAChunkValidator,
252 #[error("Validator Error: {0}")]
254 ValidatorError(String),
255 #[error("Epoch Out Of Bounds: {:?}", _0)]
257 EpochOutOfBounds(EpochId),
258 #[error("Block cannot be finalized")]
260 CannotBeFinalized,
261 #[error("IO Error: {0}")]
263 IOErr(#[from] io::Error),
264 #[error("DB Not Found Error: {0}")]
266 DBNotFoundErr(String),
267 #[error("Storage Error: {0}")]
269 StorageError(#[from] StorageError),
270 #[error("GC Error: {0}")]
272 GCError(String),
273 #[error("Resharding Error: {0}")]
275 ReshardingError(String),
276 #[error("EpochSyncProof Validation Error: {0}")]
278 InvalidEpochSyncProof(String),
279 #[error(transparent)]
281 BadHeaderForProtocolVersion(#[from] BadHeaderForProtocolVersionError),
282 #[error("Invalid spice core statements in block: {0}")]
284 InvalidSpiceCoreStatements(#[from] Box<InvalidSpiceCoreStatementsError>),
285 #[error("Invalid prev_last_certified_block_epoch_id: {0}")]
288 InvalidPrevLastCertifiedBlockEpochId(String),
289 #[error("Invalid spice_chunk_endorsement_stats: {0}")]
292 InvalidSpiceChunkEndorsementStats(String),
293 #[error("Other Error: {0}")]
295 Other(String),
296}
297
298pub trait LogTransientStorageError {
301 fn log_storage_error(self, message: &str) -> Self;
302}
303
304impl<T> LogTransientStorageError for Result<T, Error> {
305 fn log_storage_error(self, message: &str) -> Self {
306 if let Err(err) = &self {
307 tracing::error!(target: "chain", %message, ?err, "transient storage error");
308 }
309 self
310 }
311}
312
313impl Error {
314 pub fn is_bad_data(&self) -> bool {
315 match self {
316 Error::BlockKnown(_)
317 | Error::TooManyProcessingBlocks
318 | Error::Orphan
319 | Error::ChunkMissing(_)
320 | Error::ChunksMissing(_)
321 | Error::BlockPendingOptimisticExecution
322 | Error::IOErr(_)
323 | Error::Other(_)
324 | Error::ValidatorError(_)
325 | Error::EpochOutOfBounds(_)
326 | Error::CannotBeFinalized
327 | Error::StorageError(_)
328 | Error::GCError(_)
329 | Error::ReshardingError(_)
330 | Error::DBNotFoundErr(_) => false,
331 Error::InvalidBlockPastTime(_, _)
332 | Error::InvalidBlockFutureTime(_)
333 | Error::InvalidBlockHeight(_)
334 | Error::InvalidBlockProposer
335 | Error::InvalidChunk(_)
336 | Error::InvalidChunkTransactionsOrder(_)
337 | Error::InvalidChunkProofs(_)
338 | Error::InvalidChunkStateWitness(_)
339 | Error::InvalidPartialChunkStateWitness(_)
340 | Error::InvalidChunkEndorsement
341 | Error::InvalidChunkEndorsementBitmap(_)
342 | Error::InvalidChunkMask
343 | Error::InvalidStateRoot
344 | Error::InvalidChunkEncodedMerkleRoot
345 | Error::InvalidChunkEncodedLength
346 | Error::InvalidTxRoot
347 | Error::InvalidChunkReceiptsRoot
348 | Error::InvalidOutcomesProof
349 | Error::InvalidChunkHeadersRoot
350 | Error::InvalidChunkTxRoot
351 | Error::InvalidReceiptsProof
352 | Error::InvalidStatePayload
353 | Error::InvalidTransactions
354 | Error::InvalidChallenge
355 | Error::InvalidSplitShardsIds(_, _)
356 | Error::IncorrectNumberOfChunkHeaders
357 | Error::InvalidEpochHash
358 | Error::InvalidEpochSyncProof(_)
359 | Error::InvalidNextBPHash
360 | Error::NotEnoughApprovals
361 | Error::InvalidFinalityInfo
362 | Error::InvalidValidatorProposals
363 | Error::InvalidSignature
364 | Error::InvalidApprovals
365 | Error::InvalidGasLimit
366 | Error::InvalidGasPrice
367 | Error::InvalidGasUsed
368 | Error::InvalidBalanceBurnt
369 | Error::InvalidTotalSupply
370 | Error::InvalidCongestionInfo(_)
371 | Error::InvalidBandwidthRequests(_)
372 | Error::InvalidChunkHeaderShardSplit(_)
373 | Error::InvalidBlockHeaderShardSplit(_)
374 | Error::InvalidShardId(_)
375 | Error::InvalidShardIndex(_)
376 | Error::NoParentShardId(_)
377 | Error::CannotDeriveLayout
378 | Error::InvalidStateRequest(_)
379 | Error::InvalidRandomnessBeaconOutput
380 | Error::InvalidBlockMerkleRoot
381 | Error::InvalidBlockOrdinal
382 | Error::InvalidEpochSyncDataHash
383 | Error::InvalidProtocolVersion
384 | Error::NotAValidator(_)
385 | Error::NotAChunkValidator
386 | Error::BadHeaderForProtocolVersion(_)
387 | Error::InvalidSpiceCoreStatements(_)
388 | Error::InvalidPrevLastCertifiedBlockEpochId(_)
389 | Error::InvalidSpiceChunkEndorsementStats(_) => true,
390 }
391 }
392
393 pub fn is_error(&self) -> bool {
394 match self {
395 Error::IOErr(_) | Error::Other(_) | Error::DBNotFoundErr(_) => true,
396 _ => false,
397 }
398 }
399
400 pub fn prometheus_label_value(&self) -> &'static str {
406 match self {
407 Error::BlockKnown(_) => "block_known",
408 Error::TooManyProcessingBlocks => "too_many_processing_blocks",
409 Error::Orphan => "orphan",
410 Error::ChunkMissing(_) => "chunk_missing",
411 Error::ChunksMissing(_) => "chunks_missing",
412 Error::BlockPendingOptimisticExecution => "block_pending_optimistic_execution",
413 Error::IOErr(_) => "io_err",
414 Error::Other(_) => "other",
415 Error::ValidatorError(_) => "validator_error",
416 Error::EpochOutOfBounds(_) => "epoch_out_of_bounds",
417 Error::CannotBeFinalized => "cannot_be_finalized",
418 Error::StorageError(_) => "storage_error",
419 Error::GCError(_) => "gc_error",
420 Error::DBNotFoundErr(_) => "db_not_found_err",
421 Error::InvalidBlockPastTime(_, _) => "invalid_block_past_time",
422 Error::InvalidBlockFutureTime(_) => "invalid_block_future_time",
423 Error::InvalidBlockHeight(_) => "invalid_block_height",
424 Error::InvalidBlockProposer => "invalid_block_proposer",
425 Error::InvalidChunk(_) => "invalid_chunk",
426 Error::InvalidChunkTransactionsOrder(_) => "invalid_chunk_transactions_order",
427 Error::InvalidChunkProofs(_) => "invalid_chunk_proofs",
428 Error::InvalidChunkStateWitness(_) => "invalid_chunk_state_witness",
429 Error::InvalidPartialChunkStateWitness(_) => "invalid_partial_chunk_state_witness",
430 Error::InvalidChunkEndorsement => "invalid_chunk_endorsement",
431 Error::InvalidChunkEndorsementBitmap(_) => "invalid_chunk_endorsement_bitmap",
432 Error::InvalidChunkMask => "invalid_chunk_mask",
433 Error::InvalidStateRoot => "invalid_state_root",
434 Error::InvalidChunkEncodedMerkleRoot => "invalid_chunk_encoded_merkle_root",
435 Error::InvalidChunkEncodedLength => "invalid_chunk_encoded_length",
436 Error::InvalidTxRoot => "invalid_tx_root",
437 Error::InvalidChunkReceiptsRoot => "invalid_chunk_receipts_root",
438 Error::InvalidOutcomesProof => "invalid_outcomes_proof",
439 Error::InvalidChunkHeadersRoot => "invalid_chunk_headers_root",
440 Error::InvalidChunkTxRoot => "invalid_chunk_tx_root",
441 Error::InvalidReceiptsProof => "invalid_receipts_proof",
442 Error::InvalidStatePayload => "invalid_state_payload",
443 Error::InvalidTransactions => "invalid_transactions",
444 Error::InvalidChallenge => "invalid_challenge",
445 Error::InvalidSplitShardsIds(_, _) => "invalid_split_shard_ids",
446 Error::IncorrectNumberOfChunkHeaders => "incorrect_number_of_chunk_headers",
447 Error::InvalidEpochHash => "invalid_epoch_hash",
448 Error::InvalidEpochSyncProof(_) => "invalid_epoch_sync_proof",
449 Error::InvalidNextBPHash => "invalid_next_bp_hash",
450 Error::NotEnoughApprovals => "not_enough_approvals",
451 Error::InvalidFinalityInfo => "invalid_finality_info",
452 Error::InvalidValidatorProposals => "invalid_validator_proposals",
453 Error::InvalidSignature => "invalid_signature",
454 Error::InvalidApprovals => "invalid_approvals",
455 Error::InvalidGasLimit => "invalid_gas_limit",
456 Error::InvalidGasPrice => "invalid_gas_price",
457 Error::InvalidGasUsed => "invalid_gas_used",
458 Error::InvalidBalanceBurnt => "invalid_balance_burnt",
459 Error::InvalidTotalSupply => "invalid_total_supply",
460 Error::InvalidCongestionInfo(_) => "invalid_congestion_info",
461 Error::InvalidBandwidthRequests(_) => "invalid_bandwidth_requests",
462 Error::InvalidChunkHeaderShardSplit(_) => "invalid_chunk_header_shard_split",
463 Error::InvalidBlockHeaderShardSplit(_) => "invalid_block_header_shard_split",
464 Error::InvalidShardId(_) => "invalid_shard_id",
465 Error::InvalidShardIndex(_) => "invalid_shard_index",
466 Error::NoParentShardId(_) => "no_parent_shard_id",
467 Error::CannotDeriveLayout => "derive_layout",
468 Error::InvalidStateRequest(_) => "invalid_state_request",
469 Error::InvalidRandomnessBeaconOutput => "invalid_randomness_beacon_output",
470 Error::InvalidBlockMerkleRoot => "invalid_block_merkle_root",
471 Error::InvalidBlockOrdinal => "invalid_block_ordinal",
472 Error::InvalidEpochSyncDataHash => "invalid_epoch_sync_data_hash",
473 Error::InvalidProtocolVersion => "invalid_protocol_version",
474 Error::NotAValidator(_) => "not_a_validator",
475 Error::NotAChunkValidator => "not_a_chunk_validator",
476 Error::ReshardingError(_) => "resharding_error",
477 Error::BadHeaderForProtocolVersion(_) => "bad_header_for_protocol_version",
478 Error::InvalidSpiceCoreStatements(_) => "invalid_spice_core_statements",
479 Error::InvalidPrevLastCertifiedBlockEpochId(_) => {
480 "invalid_prev_last_certified_block_epoch_id"
481 }
482 Error::InvalidSpiceChunkEndorsementStats(_) => "invalid_spice_chunk_endorsement_stats",
483 }
484 }
485}
486
487impl From<EpochError> for Error {
488 fn from(error: EpochError) -> Self {
489 match error {
490 EpochError::EpochOutOfBounds(epoch_id) => Error::EpochOutOfBounds(epoch_id),
491 EpochError::MissingBlock(h) => Error::DBNotFoundErr(format!("epoch block: {h}")),
492 EpochError::NotAValidator(account_id, epoch_id) => {
493 Error::NotAValidator(format!("account_id: {account_id}, epoch_id: {epoch_id:?}"))
494 }
495 EpochError::ChunkProducerNotInDB(h, s) => {
496 Error::DBNotFoundErr(format!("chunk producer for block {h} shard {s}"))
497 }
498 err => Error::ValidatorError(err.to_string()),
499 }
500 }
501}
502
503pub trait EpochErrorResultToChainError<T> {
504 fn into_chain_error(self) -> Result<T, Error>;
505}
506
507impl<T> EpochErrorResultToChainError<T> for Result<T, EpochError> {
508 fn into_chain_error(self: Result<T, EpochError>) -> Result<T, Error> {
509 self.map_err(|err| err.into())
510 }
511}
512
513impl From<ShardLayoutError> for Error {
514 fn from(error: ShardLayoutError) -> Self {
515 match error {
516 ShardLayoutError::InvalidShardId { shard_id } => Error::InvalidShardId(shard_id),
517 ShardLayoutError::InvalidShardIndex { shard_index } => {
518 Error::InvalidShardIndex(shard_index)
519 }
520 ShardLayoutError::NoParent { shard_id } => Error::NoParentShardId(shard_id),
521 ShardLayoutError::CannotDeriveLayout => Error::CannotDeriveLayout,
522 ShardLayoutError::DuplicateBoundaryAccount { .. } => Error::CannotDeriveLayout,
523 }
524 }
525}
526
527impl From<BlockValidityError> for Error {
528 fn from(error: BlockValidityError) -> Self {
529 match error {
530 BlockValidityError::InvalidStateRoot => Error::InvalidStateRoot,
531 BlockValidityError::InvalidReceiptRoot => Error::InvalidChunkReceiptsRoot,
532 BlockValidityError::InvalidTransactionRoot => Error::InvalidTxRoot,
533 BlockValidityError::InvalidChunkHeaderRoot => Error::InvalidChunkHeadersRoot,
534 BlockValidityError::InvalidChunkMask => Error::InvalidChunkMask,
535 }
536 }
537}
538
539impl From<ChunkAccessError> for Error {
540 fn from(error: ChunkAccessError) -> Self {
541 match error {
542 ChunkAccessError::ChunkMissing(chunk_hash) => Error::ChunkMissing(chunk_hash),
543 }
544 }
545}
546
547#[derive(Clone, Eq, PartialEq, Debug, thiserror::Error)]
548pub enum BlockKnownError {
549 #[error("already known in header")]
550 KnownInHeader,
551 #[error("already known in head")]
552 KnownInHead,
553 #[error("already known in orphan")]
554 KnownInOrphan,
555 #[error("already known in missing chunks")]
556 KnownInMissingChunks,
557 #[error("already known in store")]
558 KnownInStore,
559 #[error("already known in blocks in processing")]
560 KnownInProcessing,
561 #[error("already known in invalid blocks")]
562 KnownAsInvalid,
563}