1use near_primitives::block::Block;
2use near_primitives::hash::CryptoHash;
3use near_primitives::merkle::MerklePath;
4use near_primitives::network::PeerId;
5use near_primitives::sharding::ChunkHash;
6use near_primitives::types::{
7 AccountId, BlockHeight, BlockHeightDelta, BlockReference, EpochId, EpochReference,
8 MaybeBlockId, ShardId, TransactionOrReceiptId,
9};
10use near_primitives::views::{
11 EpochSyncStatusView, ExecutionOutcomeWithIdView, LightClientBlockLiteView, QueryRequest,
12 StateChangesRequestView, StateSyncStatusView, SyncStatusView,
13};
14pub use near_primitives::views::{StatusResponse, StatusSyncInfo};
15use near_time::Duration;
16use std::collections::HashMap;
17use std::sync::Arc;
18
19#[derive(Debug, thiserror::Error)]
21pub enum Error {
22 #[error("Chain: {0}")]
23 Chain(#[from] near_chain_primitives::Error),
24 #[error("Chunk: {0}")]
25 Chunk(#[from] near_chunks_primitives::Error),
26 #[error("Block Producer: {0}")]
27 BlockProducer(String),
28 #[error("Chunk Producer: {0}")]
29 ChunkProducer(String),
30 #[error("Other: {0}")]
31 Other(String),
32}
33
34impl From<near_primitives::errors::EpochError> for Error {
35 fn from(err: near_primitives::errors::EpochError) -> Self {
36 Error::Chain(err.into())
37 }
38}
39
40#[derive(Clone, Copy, Debug)]
42pub enum ShardSyncStatus {
43 StateDownloadHeader,
44 StateDownloadParts { done: u64, total: u64 },
45 StateApplyScheduling,
46 StateApplyInProgress { done: u64, total: u64 },
47 StateApplyFinalizing,
48 StateSyncDone,
49}
50
51impl ShardSyncStatus {
52 pub fn repr(&self) -> u8 {
53 match self {
54 ShardSyncStatus::StateDownloadHeader => 0,
59 ShardSyncStatus::StateDownloadParts { .. } => 1,
60 ShardSyncStatus::StateApplyScheduling => 2,
61 ShardSyncStatus::StateApplyInProgress { .. } => 3,
62 ShardSyncStatus::StateApplyFinalizing => 4,
63 ShardSyncStatus::StateSyncDone => 5,
64 }
65 }
66}
67
68impl PartialEq<Self> for ShardSyncStatus {
70 fn eq(&self, other: &Self) -> bool {
71 std::mem::discriminant(self) == std::mem::discriminant(other)
72 }
73}
74
75impl Eq for ShardSyncStatus {}
76
77impl ToString for ShardSyncStatus {
78 fn to_string(&self) -> String {
79 match self {
80 ShardSyncStatus::StateDownloadHeader => "header".to_string(),
81 ShardSyncStatus::StateDownloadParts { done, total } => {
82 format!("parts ({done}/{total})")
83 }
84 ShardSyncStatus::StateApplyScheduling => "apply scheduling".to_string(),
85 ShardSyncStatus::StateApplyInProgress { done, total } => {
86 format!("apply in progress ({done}/{total})")
87 }
88 ShardSyncStatus::StateApplyFinalizing => "apply finalizing".to_string(),
89 ShardSyncStatus::StateSyncDone => "done".to_string(),
90 }
91 }
92}
93
94#[derive(Clone, Debug)]
95pub struct StateSyncStatus {
96 pub sync_hash: CryptoHash,
97 pub sync_status: HashMap<ShardId, ShardSyncStatus>,
98 pub download_tasks: Vec<String>,
99 pub computation_tasks: Vec<String>,
100}
101
102impl StateSyncStatus {
103 pub fn new(sync_hash: CryptoHash) -> Self {
104 Self {
105 sync_hash,
106 sync_status: HashMap::new(),
107 download_tasks: Vec::new(),
108 computation_tasks: Vec::new(),
109 }
110 }
111}
112
113#[derive(Clone, Debug)]
114pub enum EpochSyncStatus {
115 NotStarted,
117 InProgress {
119 source_peer_height: BlockHeight,
120 source_peer_id: PeerId,
121 attempt_time: near_time::Utc,
122 },
123 Done,
125}
126
127#[derive(Clone, Debug, strum::AsRefStr)]
129pub enum SyncStatus {
130 AwaitingPeers,
132 NoSync,
134 EpochSync(EpochSyncStatus),
137 HeaderSync {
139 start_height: BlockHeight,
142 current_height: BlockHeight,
144 highest_height: BlockHeight,
146 },
147 StateSync(StateSyncStatus),
149 BlockSync {
151 start_height: BlockHeight,
154 current_height: BlockHeight,
156 highest_height: BlockHeight,
158 },
159}
160
161impl SyncStatus {
162 pub fn as_variant_name(&self) -> &str {
164 self.as_ref()
165 }
166
167 pub fn is_syncing(&self) -> bool {
169 match self {
170 SyncStatus::NoSync => false,
171 _ => true,
172 }
173 }
174
175 pub fn repr(&self) -> u8 {
176 match self {
177 SyncStatus::NoSync => 0,
183 SyncStatus::AwaitingPeers => 1,
184 SyncStatus::EpochSync(_) => 2,
185 SyncStatus::HeaderSync { .. } => 4,
186 SyncStatus::StateSync(_) => 5,
187 SyncStatus::BlockSync { .. } => 7,
188 }
189 }
190
191 pub fn start_height(&self) -> Option<BlockHeight> {
192 match self {
193 SyncStatus::HeaderSync { start_height, .. } => Some(*start_height),
194 SyncStatus::BlockSync { start_height, .. } => Some(*start_height),
195 _ => None,
196 }
197 }
198
199 pub fn update(&mut self, new_value: Self) {
200 let _span =
201 tracing::debug_span!(target: "sync", "update_sync_status", old_value = ?self, ?new_value)
202 .entered();
203 *self = new_value;
204 }
205}
206
207impl From<EpochSyncStatus> for EpochSyncStatusView {
208 fn from(status: EpochSyncStatus) -> Self {
209 match status {
210 EpochSyncStatus::NotStarted => EpochSyncStatusView::NotStarted,
211 EpochSyncStatus::InProgress { source_peer_height, source_peer_id, attempt_time } => {
212 EpochSyncStatusView::InProgress {
213 source_peer_height,
214 source_peer_id: source_peer_id.to_string(),
215 attempt_time: attempt_time.to_string(),
216 }
217 }
218 EpochSyncStatus::Done => EpochSyncStatusView::Done,
219 }
220 }
221}
222
223impl From<StateSyncStatus> for StateSyncStatusView {
224 fn from(status: StateSyncStatus) -> Self {
225 StateSyncStatusView {
226 sync_hash: status.sync_hash,
227 shard_sync_status: status
228 .sync_status
229 .iter()
230 .map(|(shard_id, shard_sync_status)| (*shard_id, shard_sync_status.to_string()))
231 .collect(),
232 download_tasks: status.download_tasks,
233 computation_tasks: status.computation_tasks,
234 }
235 }
236}
237
238impl From<SyncStatus> for SyncStatusView {
239 fn from(status: SyncStatus) -> Self {
240 match status {
241 SyncStatus::AwaitingPeers => SyncStatusView::AwaitingPeers,
242 SyncStatus::NoSync => SyncStatusView::NoSync,
243 SyncStatus::EpochSync(status) => SyncStatusView::EpochSync(status.into()),
244 SyncStatus::HeaderSync { start_height, current_height, highest_height } => {
245 SyncStatusView::HeaderSync { start_height, current_height, highest_height }
246 }
247 SyncStatus::StateSync(status) => SyncStatusView::StateSync(status.into()),
248 SyncStatus::BlockSync { start_height, current_height, highest_height } => {
249 SyncStatusView::BlockSync { start_height, current_height, highest_height }
250 }
251 }
252 }
253}
254
255#[derive(Clone, Debug)]
257pub struct GetBlock(pub BlockReference);
258
259#[derive(thiserror::Error, Debug)]
260pub enum GetBlockError {
261 #[error("IO Error: {error_message}")]
262 IOError { error_message: String },
263 #[error(
264 "Block either has never been observed on the node or has been garbage collected: {error_message}"
265 )]
266 UnknownBlock { error_message: String },
267 #[error("There are no fully synchronized blocks yet")]
268 NotSyncedYet,
269 #[error(
274 "It is a bug if you receive this error type, please, report this incident: https://github.com/near/nearcore/issues/new/choose. Details: {error_message}"
275 )]
276 Unreachable { error_message: String },
277}
278
279impl From<near_chain_primitives::Error> for GetBlockError {
280 fn from(error: near_chain_primitives::Error) -> Self {
281 match error {
282 near_chain_primitives::Error::IOErr(error) => {
283 Self::IOError { error_message: error.to_string() }
284 }
285 near_chain_primitives::Error::DBNotFoundErr(error_message) => {
286 Self::UnknownBlock { error_message }
287 }
288 _ => Self::Unreachable { error_message: error.to_string() },
289 }
290 }
291}
292
293impl GetBlock {
294 pub fn latest() -> Self {
295 Self(BlockReference::latest())
296 }
297}
298
299#[derive(Debug)]
301pub struct GetBlockWithMerkleTree(pub BlockReference);
302
303impl GetBlockWithMerkleTree {
304 pub fn latest() -> Self {
305 Self(BlockReference::latest())
306 }
307}
308
309#[derive(Clone, Debug)]
311pub enum GetChunk {
312 Height(BlockHeight, ShardId),
313 BlockHash(CryptoHash, ShardId),
314 ChunkHash(ChunkHash),
315}
316
317#[derive(Debug)]
321pub enum GetShardChunk {
322 Height(BlockHeight, ShardId),
323 BlockHash(CryptoHash, ShardId),
324 ChunkHash(ChunkHash),
325}
326
327#[derive(thiserror::Error, Debug)]
328pub enum GetChunkError {
329 #[error("IO Error: {error_message}")]
330 IOError { error_message: String },
331 #[error(
332 "Block either has never been observed on the node or has been garbage collected: {error_message}"
333 )]
334 UnknownBlock { error_message: String },
335 #[error("Shard ID {shard_id} is invalid")]
336 InvalidShardId { shard_id: ShardId },
337 #[error("Chunk with hash {chunk_hash:?} has never been observed on this node")]
338 UnknownChunk { chunk_hash: ChunkHash },
339 #[error(
344 "It is a bug if you receive this error type, please, report this incident: https://github.com/near/nearcore/issues/new/choose. Details: {error_message}"
345 )]
346 Unreachable { error_message: String },
347}
348
349impl From<near_chain_primitives::Error> for GetChunkError {
350 fn from(error: near_chain_primitives::Error) -> Self {
351 match error {
352 near_chain_primitives::Error::IOErr(error) => {
353 Self::IOError { error_message: error.to_string() }
354 }
355 near_chain_primitives::Error::DBNotFoundErr(error_message) => {
356 Self::UnknownBlock { error_message }
357 }
358 near_chain_primitives::Error::InvalidShardId(shard_id) => {
359 Self::InvalidShardId { shard_id }
360 }
361 near_chain_primitives::Error::ChunkMissing(chunk_hash) => {
362 Self::UnknownChunk { chunk_hash }
363 }
364 _ => Self::Unreachable { error_message: error.to_string() },
365 }
366 }
367}
368
369#[derive(Clone, Debug)]
371pub struct Query {
372 pub block_reference: BlockReference,
373 pub request: QueryRequest,
374}
375
376impl Query {
377 pub fn new(block_reference: BlockReference, request: QueryRequest) -> Self {
378 Query { block_reference, request }
379 }
380}
381
382#[derive(thiserror::Error, Debug)]
383pub enum QueryError {
384 #[error("There are no fully synchronized blocks on the node yet")]
385 NoSyncedBlocks,
386 #[error("The node does not track the shard ID {requested_shard_id}")]
387 UnavailableShard { requested_shard_id: near_primitives::types::ShardId },
388 #[error("Account ID {requested_account_id} is invalid")]
389 InvalidAccount {
390 requested_account_id: near_primitives::types::AccountId,
391 block_height: near_primitives::types::BlockHeight,
392 block_hash: near_primitives::hash::CryptoHash,
393 },
394 #[error("Account {requested_account_id} does not exist while viewing at block #{block_height}")]
395 UnknownAccount {
396 requested_account_id: near_primitives::types::AccountId,
397 block_height: near_primitives::types::BlockHeight,
398 block_hash: near_primitives::hash::CryptoHash,
399 },
400 #[error(
401 "Contract code for contract ID {contract_account_id} has never been observed on the node at block #{block_height}"
402 )]
403 NoContractCode {
404 contract_account_id: near_primitives::types::AccountId,
405 block_height: near_primitives::types::BlockHeight,
406 block_hash: near_primitives::hash::CryptoHash,
407 },
408 #[error("State of contract {contract_account_id} is too large to be viewed")]
409 TooLargeContractState {
410 contract_account_id: near_primitives::types::AccountId,
411 block_height: near_primitives::types::BlockHeight,
412 block_hash: near_primitives::hash::CryptoHash,
413 },
414 #[error(
415 "Access key for public key {public_key} does not exist while viewing at block #{block_height}"
416 )]
417 UnknownAccessKey {
418 public_key: near_crypto::PublicKey,
419 block_height: near_primitives::types::BlockHeight,
420 block_hash: near_primitives::hash::CryptoHash,
421 },
422 #[error(
423 "Gas key for public key {public_key} does not exist while viewing at block #{block_height}"
424 )]
425 UnknownGasKey {
426 public_key: near_crypto::PublicKey,
427 block_height: near_primitives::types::BlockHeight,
428 block_hash: near_primitives::hash::CryptoHash,
429 },
430 #[error("Function call returned an error: {vm_error}")]
431 ContractExecutionError {
432 vm_error: String,
433 error: near_primitives::errors::FunctionCallError,
434 block_height: near_primitives::types::BlockHeight,
435 block_hash: near_primitives::hash::CryptoHash,
436 },
437 #[error("The node reached its limits. Try again later. More details: {error_message}")]
438 InternalError { error_message: String },
439 #[error(
440 "The data for block #{block_height} is garbage collected on this node, use an archival node to fetch historical data"
441 )]
442 GarbageCollectedBlock {
443 block_height: near_primitives::types::BlockHeight,
444 block_hash: near_primitives::hash::CryptoHash,
445 },
446 #[error(
447 "Block either has never been observed on the node or has been garbage collected: {block_reference:?}"
448 )]
449 UnknownBlock { block_reference: near_primitives::types::BlockReference },
450 #[error(
451 "Global contract code with identifier {identifier:?} has never been observed on the node"
452 )]
453 NoGlobalContractCode {
454 identifier: near_primitives::action::GlobalContractIdentifier,
455 block_height: near_primitives::types::BlockHeight,
456 block_hash: near_primitives::hash::CryptoHash,
457 },
458 #[error(
463 "It is a bug if you receive this error type, please, report this incident: https://github.com/near/nearcore/issues/new/choose. Details: {error_message}"
464 )]
465 Unreachable { error_message: String },
466}
467
468#[derive(Debug)]
469pub struct Status {
470 pub is_health_check: bool,
471 pub detailed: bool,
473}
474
475#[derive(thiserror::Error, Debug)]
476pub enum StatusError {
477 #[error("Node is syncing")]
478 NodeIsSyncing,
479 #[error("No blocks for {elapsed:?}")]
480 NoNewBlocks { elapsed: Duration },
481 #[error("Epoch Out Of Bounds {epoch_id:?}")]
482 EpochOutOfBounds { epoch_id: near_primitives::types::EpochId },
483 #[error("The node reached its limits. Try again later. More details: {error_message}")]
484 InternalError { error_message: String },
485 #[error(
490 "It is a bug if you receive this error type, please, report this incident: https://github.com/near/nearcore/issues/new/choose. Details: {error_message}"
491 )]
492 Unreachable { error_message: String },
493}
494
495impl From<near_chain_primitives::error::Error> for StatusError {
496 fn from(error: near_chain_primitives::error::Error) -> Self {
497 match error {
498 near_chain_primitives::error::Error::IOErr(error) => {
499 Self::InternalError { error_message: error.to_string() }
500 }
501 near_chain_primitives::error::Error::DBNotFoundErr(error_message)
502 | near_chain_primitives::error::Error::ValidatorError(error_message) => {
503 Self::InternalError { error_message }
504 }
505 near_chain_primitives::error::Error::EpochOutOfBounds(epoch_id) => {
506 Self::EpochOutOfBounds { epoch_id }
507 }
508 _ => Self::Unreachable { error_message: error.to_string() },
509 }
510 }
511}
512
513#[derive(Debug)]
514pub struct GetNextLightClientBlock {
515 pub last_block_hash: CryptoHash,
516}
517
518#[derive(thiserror::Error, Debug)]
519pub enum GetNextLightClientBlockError {
520 #[error("Internal error: {error_message}")]
521 InternalError { error_message: String },
522 #[error(
523 "Block either has never been observed on the node or has been garbage collected: {error_message}"
524 )]
525 UnknownBlock { error_message: String },
526 #[error("Epoch Out Of Bounds {epoch_id:?}")]
527 EpochOutOfBounds { epoch_id: near_primitives::types::EpochId },
528 #[error(
533 "It is a bug if you receive this error type, please, report this incident: https://github.com/near/nearcore/issues/new/choose. Details: {error_message}"
534 )]
535 Unreachable { error_message: String },
536}
537
538impl From<near_chain_primitives::error::Error> for GetNextLightClientBlockError {
539 fn from(error: near_chain_primitives::error::Error) -> Self {
540 match error {
541 near_chain_primitives::error::Error::DBNotFoundErr(error_message) => {
542 Self::UnknownBlock { error_message }
543 }
544 near_chain_primitives::error::Error::IOErr(error) => {
545 Self::InternalError { error_message: error.to_string() }
546 }
547 near_chain_primitives::error::Error::EpochOutOfBounds(epoch_id) => {
548 Self::EpochOutOfBounds { epoch_id }
549 }
550 _ => Self::Unreachable { error_message: error.to_string() },
551 }
552 }
553}
554
555#[derive(Debug)]
556pub struct GetNetworkInfo {}
557
558#[derive(Debug)]
559pub struct GetGasPrice {
560 pub block_id: MaybeBlockId,
561}
562
563#[derive(thiserror::Error, Debug)]
564pub enum GetGasPriceError {
565 #[error("Internal error: {error_message}")]
566 InternalError { error_message: String },
567 #[error(
568 "Block either has never been observed on the node or has been garbage collected: {error_message}"
569 )]
570 UnknownBlock { error_message: String },
571 #[error(
576 "It is a bug if you receive this error type, please, report this incident: https://github.com/near/nearcore/issues/new/choose. Details: {error_message}"
577 )]
578 Unreachable { error_message: String },
579}
580
581impl From<near_chain_primitives::Error> for GetGasPriceError {
582 fn from(error: near_chain_primitives::Error) -> Self {
583 match error {
584 near_chain_primitives::Error::IOErr(error) => {
585 Self::InternalError { error_message: error.to_string() }
586 }
587 near_chain_primitives::Error::DBNotFoundErr(error_message) => {
588 Self::UnknownBlock { error_message }
589 }
590 _ => Self::Unreachable { error_message: error.to_string() },
591 }
592 }
593}
594
595#[derive(Clone, Debug)]
596pub struct PeerInfo {
597 pub id: PeerId,
598 pub addr: Option<std::net::SocketAddr>,
599 pub account_id: Option<AccountId>,
600}
601
602#[derive(Clone, Debug)]
603pub struct KnownProducer {
604 pub account_id: AccountId,
605 pub addr: Option<std::net::SocketAddr>,
606 pub peer_id: PeerId,
607 pub next_hops: Option<Vec<PeerId>>,
608}
609
610#[derive(Debug)]
611pub struct NetworkInfoResponse {
612 pub connected_peers: Vec<PeerInfo>,
613 pub num_connected_peers: usize,
614 pub peer_max_count: u32,
615 pub sent_bytes_per_sec: u64,
616 pub received_bytes_per_sec: u64,
617 pub known_producers: Vec<KnownProducer>,
619}
620
621#[derive(Debug)]
623pub struct TxStatus {
624 pub tx_hash: CryptoHash,
625 pub signer_account_id: AccountId,
626 pub fetch_receipt: bool,
627}
628
629#[derive(Debug)]
630pub enum TxStatusError {
631 ChainError(near_chain_primitives::Error),
632 MissingTransaction(CryptoHash),
633 InternalError(String),
634 TimeoutError,
635}
636
637impl From<near_chain_primitives::Error> for TxStatusError {
638 fn from(error: near_chain_primitives::Error) -> Self {
639 Self::ChainError(error)
640 }
641}
642
643#[derive(Debug)]
644pub struct GetValidatorInfo {
645 pub epoch_reference: EpochReference,
646}
647
648#[derive(thiserror::Error, Debug)]
649pub enum GetValidatorInfoError {
650 #[error("IO Error: {0}")]
651 IOError(String),
652 #[error("Unknown epoch")]
653 UnknownEpoch,
654 #[error("Validator info unavailable")]
655 ValidatorInfoUnavailable,
656 #[error(
661 "It is a bug if you receive this error type, please, report this incident: https://github.com/near/nearcore/issues/new/choose. Details: {0}"
662 )]
663 Unreachable(String),
664}
665
666impl From<near_chain_primitives::Error> for GetValidatorInfoError {
667 fn from(error: near_chain_primitives::Error) -> Self {
668 match error {
669 near_chain_primitives::Error::DBNotFoundErr(_)
670 | near_chain_primitives::Error::EpochOutOfBounds(_) => Self::UnknownEpoch,
671 near_chain_primitives::Error::IOErr(s) => Self::IOError(s.to_string()),
672 _ => Self::Unreachable(error.to_string()),
673 }
674 }
675}
676
677#[derive(Debug)]
678pub struct GetValidatorOrdered {
679 pub block_id: MaybeBlockId,
680}
681
682#[derive(Debug)]
683pub struct GetStateChanges {
684 pub block_hash: CryptoHash,
685 pub state_changes_request: StateChangesRequestView,
686}
687
688#[derive(thiserror::Error, Debug)]
689pub enum GetStateChangesError {
690 #[error("IO Error: {error_message}")]
691 IOError { error_message: String },
692 #[error(
693 "Block either has never been observed on the node or has been garbage collected: {error_message}"
694 )]
695 UnknownBlock { error_message: String },
696 #[error("There are no fully synchronized blocks yet")]
697 NotSyncedYet,
698 #[error(
703 "It is a bug if you receive this error type, please, report this incident: https://github.com/near/nearcore/issues/new/choose. Details: {error_message}"
704 )]
705 Unreachable { error_message: String },
706}
707
708impl From<near_chain_primitives::Error> for GetStateChangesError {
709 fn from(error: near_chain_primitives::Error) -> Self {
710 match error {
711 near_chain_primitives::Error::IOErr(error) => {
712 Self::IOError { error_message: error.to_string() }
713 }
714 near_chain_primitives::Error::DBNotFoundErr(error_message) => {
715 Self::UnknownBlock { error_message }
716 }
717 _ => Self::Unreachable { error_message: error.to_string() },
718 }
719 }
720}
721
722#[derive(Debug)]
723pub struct GetStateChangesInBlock {
724 pub block_hash: CryptoHash,
725}
726
727#[derive(Debug)]
731pub struct GetChunkExtraExists {
732 pub block_hash: CryptoHash,
733 pub shard_uid: near_primitives::shard_layout::ShardUId,
734}
735
736#[derive(Debug)]
737pub struct GetStateChangesWithCauseInBlock {
738 pub block_hash: CryptoHash,
739}
740
741#[derive(Debug)]
742pub struct GetStateChangesWithCauseInBlockForTrackedShards {
743 pub block_hash: CryptoHash,
744 pub epoch_id: EpochId,
745}
746
747#[derive(Debug)]
748pub struct GetExecutionOutcome {
749 pub id: TransactionOrReceiptId,
750}
751
752#[derive(thiserror::Error, Debug)]
753pub enum GetExecutionOutcomeError {
754 #[error(
755 "Block either has never been observed on the node or has been garbage collected: {error_message}"
756 )]
757 UnknownBlock { error_message: String },
758 #[error(
759 "Inconsistent state. Total number of shards is {number_or_shards} but the execution outcome is in shard {execution_outcome_shard_id}"
760 )]
761 InconsistentState {
762 number_or_shards: usize,
763 execution_outcome_shard_id: near_primitives::types::ShardId,
764 },
765 #[error("{transaction_or_receipt_id} has not been confirmed")]
766 NotConfirmed { transaction_or_receipt_id: near_primitives::hash::CryptoHash },
767 #[error("{transaction_or_receipt_id} does not exist")]
768 UnknownTransactionOrReceipt { transaction_or_receipt_id: near_primitives::hash::CryptoHash },
769 #[error("Node doesn't track the shard where {transaction_or_receipt_id} is executed")]
770 UnavailableShard {
771 transaction_or_receipt_id: near_primitives::hash::CryptoHash,
772 shard_id: near_primitives::types::ShardId,
773 },
774 #[error("Internal error: {error_message}")]
775 InternalError { error_message: String },
776 #[error(
781 "It is a bug if you receive this error type, please, report this incident: https://github.com/near/nearcore/issues/new/choose. Details: {error_message}"
782 )]
783 Unreachable { error_message: String },
784}
785
786impl From<TxStatusError> for GetExecutionOutcomeError {
787 fn from(error: TxStatusError) -> Self {
788 match error {
789 TxStatusError::ChainError(err) => {
790 Self::InternalError { error_message: err.to_string() }
791 }
792 _ => Self::Unreachable { error_message: format!("{:?}", error) },
793 }
794 }
795}
796
797impl From<near_chain_primitives::error::Error> for GetExecutionOutcomeError {
798 fn from(error: near_chain_primitives::error::Error) -> Self {
799 match error {
800 near_chain_primitives::Error::IOErr(error) => {
801 Self::InternalError { error_message: error.to_string() }
802 }
803 near_chain_primitives::Error::DBNotFoundErr(error_message) => {
804 Self::UnknownBlock { error_message }
805 }
806 _ => Self::Unreachable { error_message: error.to_string() },
807 }
808 }
809}
810
811#[derive(Debug)]
812pub struct GetExecutionOutcomeResponse {
813 pub outcome_proof: ExecutionOutcomeWithIdView,
814 pub outcome_root_proof: MerklePath,
815}
816
817#[derive(Debug)]
818pub struct GetExecutionOutcomesForBlock {
819 pub block_hash: CryptoHash,
820}
821
822#[derive(Debug)]
823pub struct GetProcessedReceiptIds {
824 pub block_hash: CryptoHash,
825 pub shard_id: ShardId,
826}
827
828#[derive(thiserror::Error, Debug)]
829pub enum GetProcessedReceiptIdsError {
830 #[error("IO Error: {error_message}")]
831 IOError { error_message: String },
832 #[error("Block or shard data not found: {error_message}")]
833 UnknownBlock { error_message: String },
834 #[error(
835 "It is a bug if you receive this error type, please, report this incident: \
836 https://github.com/near/nearcore/issues/new/choose. Details: {error_message}"
837 )]
838 Unreachable { error_message: String },
839}
840
841impl From<near_chain_primitives::error::Error> for GetProcessedReceiptIdsError {
842 fn from(error: near_chain_primitives::error::Error) -> Self {
843 match error {
844 near_chain_primitives::Error::IOErr(error) => {
845 Self::IOError { error_message: error.to_string() }
846 }
847 near_chain_primitives::Error::DBNotFoundErr(error_message) => {
848 Self::UnknownBlock { error_message }
849 }
850 _ => Self::Unreachable { error_message: error.to_string() },
851 }
852 }
853}
854
855#[derive(Debug)]
856pub struct GetBlockProof {
857 pub block_hash: CryptoHash,
858 pub head_block_hash: CryptoHash,
859}
860
861pub struct GetBlockProofResponse {
862 pub block_header_lite: LightClientBlockLiteView,
863 pub proof: MerklePath,
864}
865
866#[derive(thiserror::Error, Debug)]
867pub enum GetBlockProofError {
868 #[error(
869 "Block either has never been observed on the node or has been garbage collected: {error_message}"
870 )]
871 UnknownBlock { error_message: String },
872 #[error("Internal error: {error_message}")]
873 InternalError { error_message: String },
874 #[error(
879 "It is a bug if you receive this error type, please, report this incident: https://github.com/near/nearcore/issues/new/choose. Details: {error_message}"
880 )]
881 Unreachable { error_message: String },
882}
883
884impl From<near_chain_primitives::error::Error> for GetBlockProofError {
885 fn from(error: near_chain_primitives::error::Error) -> Self {
886 match error {
887 near_chain_primitives::error::Error::DBNotFoundErr(error_message) => {
888 Self::UnknownBlock { error_message }
889 }
890 near_chain_primitives::error::Error::Other(error_message) => {
891 Self::InternalError { error_message }
892 }
893 err => Self::Unreachable { error_message: err.to_string() },
894 }
895 }
896}
897
898#[derive(Debug)]
899pub struct GetReceipt {
900 pub receipt_id: CryptoHash,
901}
902
903#[derive(thiserror::Error, Debug)]
904pub enum GetReceiptError {
905 #[error("IO Error: {0}")]
906 IOError(String),
907 #[error("Receipt with id {0} has never been observed on this node")]
908 UnknownReceipt(near_primitives::hash::CryptoHash),
909 #[error(
914 "It is a bug if you receive this error type, please, report this incident: https://github.com/near/nearcore/issues/new/choose. Details: {0}"
915 )]
916 Unreachable(String),
917}
918
919impl From<near_chain_primitives::Error> for GetReceiptError {
920 fn from(error: near_chain_primitives::Error) -> Self {
921 match error {
922 near_chain_primitives::Error::IOErr(error) => Self::IOError(error.to_string()),
923 _ => Self::Unreachable(error.to_string()),
924 }
925 }
926}
927
928#[derive(Debug)]
929pub struct GetReceiptToTx {
930 pub receipt_id: CryptoHash,
931 pub block_height: Option<BlockHeight>,
936 pub shard_id: Option<ShardId>,
937 pub window: Option<BlockHeightDelta>,
938}
939
940#[derive(Debug)]
941pub struct GetReceiptToTxResponse {
942 pub transaction_hash: CryptoHash,
943 pub sender_account_id: AccountId,
944}
945
946#[derive(thiserror::Error, Debug)]
947pub enum GetReceiptToTxError {
948 #[error("Receipt with id {0} has never been observed on this node")]
949 UnknownReceipt(CryptoHash),
950 #[error("depth limit {limit} exceeded when resolving receipt {receipt_id}")]
951 DepthExceeded { receipt_id: CryptoHash, limit: u32 },
952 #[error("this node does not support receipt-to-tx lookup: {0}")]
953 Unsupported(String),
954 #[error("execution outcomes are not stored on this node (save_tx_outcomes=false)")]
955 OutcomesNotStored,
956 #[error("requested window {requested} exceeds maximum {maximum}")]
957 WindowTooLarge { requested: BlockHeightDelta, maximum: BlockHeightDelta },
958 #[error("malformed hint: {0}")]
959 MalformedHint(String),
960 #[error("hint-scan budget exceeded: {scanned} outcomes scanned, limit {limit}")]
961 BudgetExceeded { scanned: u64, limit: u64 },
962 #[error("internal error: {0}")]
963 InternalError(String),
964}
965
966#[derive(Debug)]
967pub struct GetProtocolConfig(pub BlockReference);
968
969#[derive(thiserror::Error, Debug)]
970pub enum GetProtocolConfigError {
971 #[error("IO Error: {0}")]
972 IOError(String),
973 #[error("Block has never been observed: {0}")]
974 UnknownBlock(String),
975 #[error(
980 "It is a bug if you receive this error type, please, report this incident: https://github.com/near/nearcore/issues/new/choose. Details: {0}"
981 )]
982 Unreachable(String),
983}
984
985impl From<near_chain_primitives::Error> for GetProtocolConfigError {
986 fn from(error: near_chain_primitives::Error) -> Self {
987 match error {
988 near_chain_primitives::Error::IOErr(error) => Self::IOError(error.to_string()),
989 near_chain_primitives::Error::DBNotFoundErr(s) => Self::UnknownBlock(s),
990 _ => Self::Unreachable(error.to_string()),
991 }
992 }
993}
994
995#[derive(Debug)]
996pub struct GetMaintenanceWindows {
997 pub account_id: AccountId,
998}
999
1000#[derive(thiserror::Error, Debug)]
1001pub enum GetMaintenanceWindowsError {
1002 #[error("IO Error: {0}")]
1003 IOError(String),
1004 #[error(
1005 "It is a bug if you receive this error type, please, report this incident: https://github.com/near/nearcore/issues/new/choose. Details: {0}"
1006 )]
1007 Unreachable(String),
1008}
1009
1010impl From<near_chain_primitives::Error> for GetMaintenanceWindowsError {
1011 fn from(error: near_chain_primitives::Error) -> Self {
1012 match error {
1013 near_chain_primitives::Error::IOErr(error) => Self::IOError(error.to_string()),
1014 _ => Self::Unreachable(error.to_string()),
1015 }
1016 }
1017}
1018
1019#[derive(Debug)]
1020pub struct GetClientConfig {}
1021
1022#[derive(thiserror::Error, Debug)]
1023pub enum GetClientConfigError {
1024 #[error("IO Error: {0}")]
1025 IOError(String),
1026 #[error(
1031 "It is a bug if you receive this error type, please, report this incident: https://github.com/near/nearcore/issues/new/choose. Details: {0}"
1032 )]
1033 Unreachable(String),
1034}
1035
1036impl From<near_chain_primitives::Error> for GetClientConfigError {
1037 fn from(error: near_chain_primitives::Error) -> Self {
1038 match error {
1039 near_chain_primitives::Error::IOErr(error) => Self::IOError(error.to_string()),
1040 _ => Self::Unreachable(error.to_string()),
1041 }
1042 }
1043}
1044
1045#[derive(Debug)]
1046pub struct GetSplitStorageInfo {}
1047
1048#[derive(thiserror::Error, Debug)]
1049pub enum GetSplitStorageInfoError {
1050 #[error("IO Error: {0}")]
1051 IOError(String),
1052 #[error(
1057 "It is a bug if you receive this error type, please, report this incident: https://github.com/near/nearcore/issues/new/choose. Details: {0}"
1058 )]
1059 Unreachable(String),
1060}
1061
1062impl From<near_chain_primitives::Error> for GetSplitStorageInfoError {
1063 fn from(error: near_chain_primitives::Error) -> Self {
1064 match error {
1065 near_chain_primitives::Error::IOErr(error) => Self::IOError(error.to_string()),
1066 _ => Self::Unreachable(error.to_string()),
1067 }
1068 }
1069}
1070
1071impl From<std::io::Error> for GetSplitStorageInfoError {
1072 fn from(error: std::io::Error) -> Self {
1073 Self::IOError(error.to_string())
1074 }
1075}
1076
1077#[cfg(feature = "sandbox")]
1078#[derive(Debug)]
1079pub enum SandboxMessage {
1080 SandboxPatchState(Vec<near_primitives::state_record::StateRecord>),
1081 SandboxPatchStateStatus,
1082 SandboxFastForward(near_primitives::types::BlockHeightDelta),
1083 SandboxFastForwardStatus,
1084}
1085
1086#[cfg(feature = "sandbox")]
1087#[derive(Eq, PartialEq, Debug)]
1088pub enum SandboxResponse {
1089 SandboxPatchStateFinished(bool),
1090 SandboxFastForwardFinished(bool),
1091 SandboxFastForwardFailed(String),
1092 SandboxNoResponse,
1093}
1094
1095#[derive(Debug, Clone)]
1097pub struct BlockNotificationMessage {
1098 pub block: Arc<Block>,
1099}