casper_node/effect/
requests.rs

1//! Request effects.
2//!
3//! Requests typically ask other components to perform a service and report back the result. See the
4//! top-level module documentation for details.
5
6use std::{
7    collections::{BTreeMap, BTreeSet, HashMap, HashSet},
8    fmt::{self, Display, Formatter},
9    sync::Arc,
10};
11
12use datasize::DataSize;
13use hex_fmt::HexFmt;
14use serde::Serialize;
15use smallvec::SmallVec;
16use static_assertions::const_assert;
17
18use casper_binary_port::{
19    ConsensusStatus, ConsensusValidatorChanges, LastProgress, NetworkName, RecordId, Uptime,
20};
21use casper_storage::{
22    block_store::types::ApprovalsHashes,
23    data_access_layer::{
24        prefixed_values::{PrefixedValuesRequest, PrefixedValuesResult},
25        tagged_values::{TaggedValuesRequest, TaggedValuesResult},
26        AddressableEntityResult, BalanceRequest, BalanceResult, EntryPointExistsResult,
27        EraValidatorsRequest, EraValidatorsResult, ExecutionResultsChecksumResult, PutTrieRequest,
28        PutTrieResult, QueryRequest, QueryResult, SeigniorageRecipientsRequest,
29        SeigniorageRecipientsResult, TrieRequest, TrieResult,
30    },
31    DbRawBytesSpec,
32};
33use casper_types::{
34    execution::ExecutionResult, Approval, AvailableBlockRange, Block, BlockHash, BlockHeader,
35    BlockSignatures, BlockSynchronizerStatus, BlockV2, ChainspecRawBytes, DeployHash, Digest,
36    DisplayIter, EntityAddr, EraId, ExecutionInfo, FinalitySignature, FinalitySignatureId,
37    HashAddr, NextUpgrade, ProtocolUpgradeConfig, PublicKey, TimeDiff, Timestamp, Transaction,
38    TransactionHash, TransactionId, Transfer,
39};
40
41use super::{AutoClosingResponder, GossipTarget, Responder};
42use crate::{
43    components::{
44        block_synchronizer::{
45            GlobalStateSynchronizerError, GlobalStateSynchronizerResponse, TrieAccumulatorError,
46            TrieAccumulatorResponse,
47        },
48        consensus::{ClContext, ProposedBlock},
49        contract_runtime::SpeculativeExecutionResult,
50        diagnostics_port::StopAtSpec,
51        fetcher::{FetchItem, FetchResult},
52        gossiper::GossipItem,
53        network::NetworkInsights,
54        transaction_acceptor,
55    },
56    contract_runtime::ExecutionPreState,
57    reactor::main_reactor::ReactorState,
58    types::{
59        appendable_block::AppendableBlock, BlockExecutionResultsOrChunk,
60        BlockExecutionResultsOrChunkId, BlockWithMetadata, ExecutableBlock, InvalidProposalError,
61        LegacyDeploy, MetaBlockState, NodeId, StatusFeed, TransactionHeader,
62    },
63    utils::Source,
64};
65
66const _STORAGE_REQUEST_SIZE: usize = size_of::<StorageRequest>();
67const_assert!(_STORAGE_REQUEST_SIZE < 129);
68
69/// A metrics request.
70#[derive(Debug)]
71pub(crate) enum MetricsRequest {
72    /// Render current node metrics as prometheus-formatted string.
73    RenderNodeMetricsText {
74        /// Responder returning the rendered metrics or `None`, if an internal error occurred.
75        responder: Responder<Option<String>>,
76    },
77}
78
79impl Display for MetricsRequest {
80    fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
81        match self {
82            MetricsRequest::RenderNodeMetricsText { .. } => write!(formatter, "get metrics text"),
83        }
84    }
85}
86
87const _NETWORK_EVENT_SIZE: usize = size_of::<NetworkRequest<String>>();
88const_assert!(_NETWORK_EVENT_SIZE < 105);
89
90/// A networking request.
91#[derive(Debug, Serialize)]
92#[must_use]
93pub(crate) enum NetworkRequest<P> {
94    /// Send a message on the network to a specific peer.
95    SendMessage {
96        /// Message destination.
97        dest: Box<NodeId>,
98        /// Message payload.
99        payload: Box<P>,
100        /// If `true`, the responder will be called early after the message has been queued, not
101        /// waiting until it has passed to the kernel.
102        respond_after_queueing: bool,
103        /// Responder to be called when the message has been *buffered for sending*.
104        #[serde(skip_serializing)]
105        auto_closing_responder: AutoClosingResponder<()>,
106    },
107    /// Send a message on the network to validator peers in the given era.
108    ValidatorBroadcast {
109        /// Message payload.
110        payload: Box<P>,
111        /// Era whose validators are recipients.
112        era_id: EraId,
113        /// Responder to be called when all messages are queued.
114        #[serde(skip_serializing)]
115        auto_closing_responder: AutoClosingResponder<()>,
116    },
117    /// Gossip a message to a random subset of peers.
118    Gossip {
119        /// Payload to gossip.
120        payload: Box<P>,
121        /// Type of peers that should receive the gossip message.
122        gossip_target: GossipTarget,
123        /// Number of peers to gossip to. This is an upper bound, otherwise best-effort.
124        count: usize,
125        /// Node IDs of nodes to exclude from gossiping to.
126        #[serde(skip_serializing)]
127        exclude: HashSet<NodeId>,
128        /// Responder to be called when all messages are queued.
129        #[serde(skip_serializing)]
130        auto_closing_responder: AutoClosingResponder<HashSet<NodeId>>,
131    },
132}
133
134impl<P> NetworkRequest<P> {
135    /// Transform a network request by mapping the contained payload.
136    ///
137    /// This is a replacement for a `From` conversion that is not possible without specialization.
138    pub(crate) fn map_payload<F, P2>(self, wrap_payload: F) -> NetworkRequest<P2>
139    where
140        F: FnOnce(P) -> P2,
141    {
142        match self {
143            NetworkRequest::SendMessage {
144                dest,
145                payload,
146                respond_after_queueing,
147                auto_closing_responder,
148            } => NetworkRequest::SendMessage {
149                dest,
150                payload: Box::new(wrap_payload(*payload)),
151                respond_after_queueing,
152                auto_closing_responder,
153            },
154            NetworkRequest::ValidatorBroadcast {
155                payload,
156                era_id,
157                auto_closing_responder,
158            } => NetworkRequest::ValidatorBroadcast {
159                payload: Box::new(wrap_payload(*payload)),
160                era_id,
161                auto_closing_responder,
162            },
163            NetworkRequest::Gossip {
164                payload,
165                gossip_target,
166                count,
167                exclude,
168                auto_closing_responder,
169            } => NetworkRequest::Gossip {
170                payload: Box::new(wrap_payload(*payload)),
171                gossip_target,
172                count,
173                exclude,
174                auto_closing_responder,
175            },
176        }
177    }
178}
179
180impl<P> Display for NetworkRequest<P>
181where
182    P: Display,
183{
184    fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
185        match self {
186            NetworkRequest::SendMessage { dest, payload, .. } => {
187                write!(formatter, "send to {}: {}", dest, payload)
188            }
189            NetworkRequest::ValidatorBroadcast { payload, .. } => {
190                write!(formatter, "broadcast: {}", payload)
191            }
192            NetworkRequest::Gossip { payload, .. } => write!(formatter, "gossip: {}", payload),
193        }
194    }
195}
196
197/// A networking info request.
198#[derive(Debug, Serialize)]
199pub(crate) enum NetworkInfoRequest {
200    /// Get incoming and outgoing peers.
201    Peers {
202        /// Responder to be called with all connected peers.
203        /// Responds with a map from [NodeId]s to a socket address, represented as a string.
204        responder: Responder<BTreeMap<NodeId, String>>,
205    },
206    /// Get up to `count` fully-connected peers in random order.
207    FullyConnectedPeers {
208        count: usize,
209        /// Responder to be called with the peers.
210        responder: Responder<Vec<NodeId>>,
211    },
212    /// Get detailed insights into the nodes networking.
213    Insight {
214        responder: Responder<NetworkInsights>,
215    },
216}
217
218impl Display for NetworkInfoRequest {
219    fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
220        match self {
221            NetworkInfoRequest::Peers { responder: _ } => {
222                formatter.write_str("get peers-to-socket-address map")
223            }
224            NetworkInfoRequest::FullyConnectedPeers {
225                count,
226                responder: _,
227            } => {
228                write!(formatter, "get up to {} fully connected peers", count)
229            }
230            NetworkInfoRequest::Insight { responder: _ } => {
231                formatter.write_str("get networking insights")
232            }
233        }
234    }
235}
236
237/// A gossip request.
238///
239/// This request usually initiates gossiping process of the specified item. Note that the gossiper
240/// will fetch the item itself, so only the ID is needed.
241///
242/// The responder will be called as soon as the gossiper has initiated the process.
243// Note: This request should eventually entirely replace `ItemReceived`.
244#[derive(Debug, Serialize)]
245#[must_use]
246pub(crate) struct BeginGossipRequest<T>
247where
248    T: GossipItem,
249{
250    pub(crate) item_id: T::Id,
251    pub(crate) source: Source,
252    pub(crate) target: GossipTarget,
253    pub(crate) responder: Responder<()>,
254}
255
256impl<T> Display for BeginGossipRequest<T>
257where
258    T: GossipItem,
259{
260    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
261        write!(f, "begin gossip of {} from {}", self.item_id, self.source)
262    }
263}
264
265#[derive(Debug, Serialize)]
266/// A storage request.
267pub(crate) enum StorageRequest {
268    /// Store given block.
269    PutBlock {
270        /// Block to be stored.
271        block: Arc<Block>,
272        /// Responder to call with the result.  Returns true if the block was stored on this
273        /// attempt or false if it was previously stored.
274        responder: Responder<bool>,
275    },
276    /// Store the approvals hashes.
277    PutApprovalsHashes {
278        /// Approvals hashes to store.
279        approvals_hashes: Box<ApprovalsHashes>,
280        responder: Responder<bool>,
281    },
282    /// Store the block and approvals hashes.
283    PutExecutedBlock {
284        /// Block to be stored.
285        block: Arc<BlockV2>,
286        /// Approvals hashes to store.
287        approvals_hashes: Box<ApprovalsHashes>,
288        execution_results: HashMap<TransactionHash, ExecutionResult>,
289        responder: Responder<bool>,
290    },
291    /// Retrieve block with given hash.
292    GetBlock {
293        /// Hash of block to be retrieved.
294        block_hash: BlockHash,
295        /// Responder to call with the result.  Returns `None` if the block doesn't exist in local
296        /// storage.
297        responder: Responder<Option<Block>>,
298    },
299    IsBlockStored {
300        block_hash: BlockHash,
301        responder: Responder<bool>,
302    },
303    /// Retrieve the approvals hashes.
304    GetApprovalsHashes {
305        /// Hash of the block for which to retrieve approvals hashes.
306        block_hash: BlockHash,
307        /// Responder to call with the result.  Returns `None` if the approvals hashes don't exist
308        /// in local storage.
309        responder: Responder<Option<ApprovalsHashes>>,
310    },
311    /// Retrieve the highest complete block.
312    GetHighestCompleteBlock {
313        /// Responder.
314        responder: Responder<Option<Block>>,
315    },
316    /// Retrieve the highest complete block header.
317    GetHighestCompleteBlockHeader {
318        /// Responder.
319        responder: Responder<Option<BlockHeader>>,
320    },
321    /// Retrieve the era IDs of the blocks in which the given transactions were executed.
322    GetTransactionsEraIds {
323        transaction_hashes: HashSet<TransactionHash>,
324        responder: Responder<HashSet<EraId>>,
325    },
326    /// Retrieve block header with given hash.
327    GetBlockHeader {
328        /// Hash of block to get header of.
329        block_hash: BlockHash,
330        /// If true, only return `Some` if the block is in the available block range, i.e. the
331        /// highest contiguous range of complete blocks.
332        only_from_available_block_range: bool,
333        /// Responder to call with the result.  Returns `None` if the block header doesn't exist in
334        /// local storage.
335        responder: Responder<Option<BlockHeader>>,
336    },
337    /// Retrieve block header with given hash.
338    GetRawData {
339        /// Which record to get.
340        record_id: RecordId,
341        /// bytesrepr serialized key.
342        key: Vec<u8>,
343        /// Responder to call with the result.  Returns `None` if the data doesn't exist in
344        /// local storage.
345        responder: Responder<Option<DbRawBytesSpec>>,
346    },
347    GetBlockHeaderByHeight {
348        /// Height of block to get header of.
349        block_height: u64,
350        /// If true, only return `Some` if the block is in the available block range, i.e. the
351        /// highest contiguous range of complete blocks.
352        only_from_available_block_range: bool,
353        /// Responder to call with the result.  Returns `None` if the block header doesn't exist in
354        /// local storage.
355        responder: Responder<Option<BlockHeader>>,
356    },
357    GetLatestSwitchBlockHeader {
358        responder: Responder<Option<BlockHeader>>,
359    },
360    GetSwitchBlockHeaderByEra {
361        /// Era ID for which to get the block header.
362        era_id: EraId,
363        /// Responder to call with the result.
364        responder: Responder<Option<BlockHeader>>,
365    },
366    /// Retrieve all transfers in a block with given hash.
367    GetBlockTransfers {
368        /// Hash of block to get transfers of.
369        block_hash: BlockHash,
370        /// Responder to call with the result.  Returns `None` if the transfers do not exist in
371        /// local storage under the block_hash provided.
372        responder: Responder<Option<Vec<Transfer>>>,
373    },
374    PutTransaction {
375        transaction: Arc<Transaction>,
376        /// Returns `true` if the transaction was stored on this attempt or false if it was
377        /// previously stored.
378        responder: Responder<bool>,
379    },
380    /// Retrieve transaction with given hashes.
381    GetTransactions {
382        transaction_hashes: Vec<TransactionHash>,
383        #[allow(clippy::type_complexity)]
384        responder: Responder<SmallVec<[Option<(Transaction, Option<BTreeSet<Approval>>)>; 1]>>,
385    },
386    /// Retrieve legacy deploy with given hash.
387    GetLegacyDeploy {
388        deploy_hash: DeployHash,
389        responder: Responder<Option<LegacyDeploy>>,
390    },
391    GetTransaction {
392        transaction_id: TransactionId,
393        responder: Responder<Option<Transaction>>,
394    },
395    IsTransactionStored {
396        transaction_id: TransactionId,
397        responder: Responder<bool>,
398    },
399    GetTransactionAndExecutionInfo {
400        transaction_hash: TransactionHash,
401        with_finalized_approvals: bool,
402        responder: Responder<Option<(Transaction, Option<ExecutionInfo>)>>,
403    },
404    /// Store execution results for a set of transactions of a single block.
405    ///
406    /// Will return a fatal error if there are already execution results known for a specific
407    /// transaction/block combination and a different result is inserted.
408    ///
409    /// Inserting the same transaction/block combination multiple times with the same execution
410    /// results is not an error and will silently be ignored.
411    PutExecutionResults {
412        /// Hash of block.
413        block_hash: Box<BlockHash>,
414        block_height: u64,
415        era_id: EraId,
416        /// Mapping of transactions to execution results of the block.
417        execution_results: HashMap<TransactionHash, ExecutionResult>,
418        /// Responder to call when done storing.
419        responder: Responder<()>,
420    },
421    GetExecutionResults {
422        block_hash: BlockHash,
423        responder: Responder<Option<Vec<(TransactionHash, TransactionHeader, ExecutionResult)>>>,
424    },
425    GetBlockExecutionResultsOrChunk {
426        /// Request ID.
427        id: BlockExecutionResultsOrChunkId,
428        /// Responder to call with the execution results.
429        /// None is returned when we don't have the block in the storage.
430        responder: Responder<Option<BlockExecutionResultsOrChunk>>,
431    },
432    /// Retrieve a finality signature by block hash and public key.
433    GetFinalitySignature {
434        id: Box<FinalitySignatureId>,
435        responder: Responder<Option<FinalitySignature>>,
436    },
437    IsFinalitySignatureStored {
438        id: Box<FinalitySignatureId>,
439        responder: Responder<bool>,
440    },
441    /// Retrieve block and its metadata at a given height.
442    GetBlockAndMetadataByHeight {
443        /// The height of the block.
444        block_height: BlockHeight,
445        /// Flag indicating whether storage should check the block availability before trying to
446        /// retrieve it.
447        only_from_available_block_range: bool,
448        /// The responder to call with the results.
449        responder: Responder<Option<BlockWithMetadata>>,
450    },
451    /// Get a single finality signature for a block hash.
452    GetBlockSignature {
453        /// The hash for the request.
454        block_hash: BlockHash,
455        /// The public key of the signer.
456        public_key: Box<PublicKey>,
457        /// Responder to call with the result.
458        responder: Responder<Option<FinalitySignature>>,
459    },
460    /// Store finality signatures.
461    PutBlockSignatures {
462        /// Signatures that are to be stored.
463        signatures: BlockSignatures,
464        /// Responder to call with the result, if true then the signatures were successfully
465        /// stored.
466        responder: Responder<bool>,
467    },
468    PutFinalitySignature {
469        signature: Box<FinalitySignature>,
470        responder: Responder<bool>,
471    },
472    /// Store a block header.
473    PutBlockHeader {
474        /// Block header that is to be stored.
475        block_header: Box<BlockHeader>,
476        /// Responder to call with the result, if true then the block header was successfully
477        /// stored.
478        responder: Responder<bool>,
479    },
480    /// Retrieve the height range of fully available blocks (not just block headers). Returns
481    /// `[u64::MAX, u64::MAX]` when there are no sequences.
482    GetAvailableBlockRange {
483        /// Responder to call with the result.
484        responder: Responder<AvailableBlockRange>,
485    },
486    /// Store a set of finalized approvals for a specific transaction.
487    StoreFinalizedApprovals {
488        /// The transaction hash to store the finalized approvals for.
489        transaction_hash: TransactionHash,
490        /// The set of finalized approvals.
491        finalized_approvals: BTreeSet<Approval>,
492        /// Responder, responded to once the approvals are written.  If true, new approvals were
493        /// written.
494        responder: Responder<bool>,
495    },
496    /// Retrieve the height of the final block of the previous protocol version, if known.
497    GetKeyBlockHeightForActivationPoint { responder: Responder<Option<u64>> },
498    /// Retrieve the block utilization score.
499    GetBlockUtilizationScore {
500        /// The era id.
501        era_id: EraId,
502        /// The block height of the switch block
503        block_height: u64,
504        /// The utilization within the switch block.
505        switch_block_utilization: u64,
506        /// Responder, responded once the utilization for the era has been determined.
507        responder: Responder<Option<(u64, u64)>>,
508    },
509}
510
511impl Display for StorageRequest {
512    fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
513        match self {
514            StorageRequest::PutBlock { block, .. } => {
515                write!(formatter, "put {}", block)
516            }
517            StorageRequest::PutApprovalsHashes {
518                approvals_hashes, ..
519            } => {
520                write!(formatter, "put {}", approvals_hashes)
521            }
522            StorageRequest::GetBlock { block_hash, .. } => {
523                write!(formatter, "get block {}", block_hash)
524            }
525            StorageRequest::IsBlockStored { block_hash, .. } => {
526                write!(formatter, "is block {} stored", block_hash)
527            }
528            StorageRequest::GetApprovalsHashes { block_hash, .. } => {
529                write!(formatter, "get approvals hashes {}", block_hash)
530            }
531            StorageRequest::GetHighestCompleteBlock { .. } => {
532                write!(formatter, "get highest complete block")
533            }
534            StorageRequest::GetHighestCompleteBlockHeader { .. } => {
535                write!(formatter, "get highest complete block header")
536            }
537            StorageRequest::GetTransactionsEraIds {
538                transaction_hashes, ..
539            } => {
540                write!(
541                    formatter,
542                    "get era ids for {} transactions",
543                    transaction_hashes.len()
544                )
545            }
546            StorageRequest::GetBlockHeader { block_hash, .. } => {
547                write!(formatter, "get {}", block_hash)
548            }
549            StorageRequest::GetBlockHeaderByHeight { block_height, .. } => {
550                write!(formatter, "get header for height {}", block_height)
551            }
552            StorageRequest::GetLatestSwitchBlockHeader { .. } => {
553                write!(formatter, "get latest switch block header")
554            }
555            StorageRequest::GetSwitchBlockHeaderByEra { era_id, .. } => {
556                write!(formatter, "get header for era {}", era_id)
557            }
558            StorageRequest::GetBlockTransfers { block_hash, .. } => {
559                write!(formatter, "get transfers for {}", block_hash)
560            }
561            StorageRequest::PutTransaction { transaction, .. } => {
562                write!(formatter, "put {}", transaction)
563            }
564            StorageRequest::GetTransactions {
565                transaction_hashes, ..
566            } => {
567                write!(
568                    formatter,
569                    "get {}",
570                    DisplayIter::new(transaction_hashes.iter())
571                )
572            }
573            StorageRequest::GetLegacyDeploy { deploy_hash, .. } => {
574                write!(formatter, "get legacy deploy {}", deploy_hash)
575            }
576            StorageRequest::GetTransaction { transaction_id, .. } => {
577                write!(formatter, "get transaction {}", transaction_id)
578            }
579            StorageRequest::GetTransactionAndExecutionInfo {
580                transaction_hash, ..
581            } => {
582                write!(
583                    formatter,
584                    "get transaction and exec info {}",
585                    transaction_hash
586                )
587            }
588            StorageRequest::IsTransactionStored { transaction_id, .. } => {
589                write!(formatter, "is transaction {} stored", transaction_id)
590            }
591            StorageRequest::PutExecutionResults { block_hash, .. } => {
592                write!(formatter, "put execution results for {}", block_hash)
593            }
594            StorageRequest::GetExecutionResults { block_hash, .. } => {
595                write!(formatter, "get execution results for {}", block_hash)
596            }
597            StorageRequest::GetBlockExecutionResultsOrChunk { id, .. } => {
598                write!(formatter, "get block execution results or chunk for {}", id)
599            }
600            StorageRequest::GetFinalitySignature { id, .. } => {
601                write!(formatter, "get finality signature {}", id)
602            }
603            StorageRequest::IsFinalitySignatureStored { id, .. } => {
604                write!(formatter, "is finality signature {} stored", id)
605            }
606            StorageRequest::GetBlockAndMetadataByHeight { block_height, .. } => {
607                write!(
608                    formatter,
609                    "get block and metadata for block at height: {}",
610                    block_height
611                )
612            }
613            StorageRequest::GetBlockSignature {
614                block_hash,
615                public_key,
616                ..
617            } => {
618                write!(
619                    formatter,
620                    "get finality signature for block hash {} from {}",
621                    block_hash, public_key
622                )
623            }
624            StorageRequest::PutBlockSignatures { .. } => {
625                write!(formatter, "put finality signatures")
626            }
627            StorageRequest::PutFinalitySignature { .. } => {
628                write!(formatter, "put finality signature")
629            }
630            StorageRequest::PutBlockHeader { block_header, .. } => {
631                write!(formatter, "put block header: {}", block_header)
632            }
633            StorageRequest::GetAvailableBlockRange { .. } => {
634                write!(formatter, "get available block range",)
635            }
636            StorageRequest::StoreFinalizedApprovals {
637                transaction_hash, ..
638            } => {
639                write!(
640                    formatter,
641                    "finalized approvals for transaction {}",
642                    transaction_hash
643                )
644            }
645            StorageRequest::PutExecutedBlock { block, .. } => {
646                write!(formatter, "put executed block {}", block.hash(),)
647            }
648            StorageRequest::GetKeyBlockHeightForActivationPoint { .. } => {
649                write!(
650                    formatter,
651                    "get key block height for current activation point"
652                )
653            }
654            StorageRequest::GetRawData {
655                key,
656                responder: _responder,
657                record_id,
658            } => {
659                write!(formatter, "get raw data {}::{:?}", record_id, key)
660            }
661            StorageRequest::GetBlockUtilizationScore { era_id, .. } => {
662                write!(formatter, "get utilization score for era {}", era_id)
663            }
664        }
665    }
666}
667
668#[derive(Debug, Serialize)]
669pub(crate) struct MakeBlockExecutableRequest {
670    /// Hash of the block to be made executable.
671    pub block_hash: BlockHash,
672    /// Responder with the executable block and it's transactions
673    pub responder: Responder<Option<ExecutableBlock>>,
674}
675
676impl Display for MakeBlockExecutableRequest {
677    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
678        write!(f, "block made executable: {}", self.block_hash)
679    }
680}
681
682/// A request to mark a block at a specific height completed.
683///
684/// A block is considered complete if
685///
686/// * the block header and the actual block are persisted in storage,
687/// * all of its transactions are persisted in storage, and
688/// * the global state root the block refers to has no missing dependencies locally.
689#[derive(Debug, Serialize)]
690pub(crate) struct MarkBlockCompletedRequest {
691    pub block_height: u64,
692    /// Responds `true` if the block was not previously marked complete.
693    pub responder: Responder<bool>,
694}
695
696impl Display for MarkBlockCompletedRequest {
697    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
698        write!(f, "block completed: height {}", self.block_height)
699    }
700}
701
702#[derive(DataSize, Debug, Serialize)]
703pub(crate) enum TransactionBufferRequest {
704    GetAppendableBlock {
705        timestamp: Timestamp,
706        era_id: EraId,
707        request_expiry: Timestamp,
708        responder: Responder<AppendableBlock>,
709    },
710}
711
712impl Display for TransactionBufferRequest {
713    fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
714        match self {
715            TransactionBufferRequest::GetAppendableBlock {
716                timestamp,
717                era_id,
718                request_expiry,
719                ..
720            } => {
721                write!(
722                    formatter,
723                    "request for appendable block at instant {} for era {} (expires at {})",
724                    timestamp, era_id, request_expiry
725                )
726            }
727        }
728    }
729}
730
731/// Abstract REST request.
732///
733/// An REST request is an abstract request that does not concern itself with serialization or
734/// transport.
735#[derive(Debug)]
736#[must_use]
737pub(crate) enum RestRequest {
738    /// Return string formatted status or `None` if an error occurred.
739    Status {
740        /// Responder to call with the result.
741        responder: Responder<StatusFeed>,
742    },
743    /// Return string formatted, prometheus compatible metrics or `None` if an error occurred.
744    Metrics {
745        /// Responder to call with the result.
746        responder: Responder<Option<String>>,
747    },
748}
749
750impl Display for RestRequest {
751    fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
752        match self {
753            RestRequest::Status { .. } => write!(formatter, "get status"),
754            RestRequest::Metrics { .. } => write!(formatter, "get metrics"),
755        }
756    }
757}
758
759/// A contract runtime request.
760#[derive(Debug, Serialize)]
761#[must_use]
762pub(crate) enum ContractRuntimeRequest {
763    /// A request to enqueue a `ExecutableBlock` for execution.
764    EnqueueBlockForExecution {
765        /// A `ExecutableBlock` to enqueue.
766        executable_block: ExecutableBlock,
767        /// The key block height for the current protocol version's activation point.
768        key_block_height_for_activation_point: u64,
769        meta_block_state: MetaBlockState,
770    },
771    /// A query request.
772    Query {
773        /// Query request.
774        #[serde(skip_serializing)]
775        request: QueryRequest,
776        /// Responder to call with the query result.
777        responder: Responder<QueryResult>,
778    },
779    /// A query by prefix request.
780    QueryByPrefix {
781        /// Query by prefix request.
782        #[serde(skip_serializing)]
783        request: PrefixedValuesRequest,
784        /// Responder to call with the query result.
785        responder: Responder<PrefixedValuesResult>,
786    },
787    /// A balance request.
788    GetBalance {
789        /// Balance request.
790        #[serde(skip_serializing)]
791        request: BalanceRequest,
792        /// Responder to call with the balance result.
793        responder: Responder<BalanceResult>,
794    },
795    /// Returns validator weights.
796    GetEraValidators {
797        /// Get validators weights request.
798        #[serde(skip_serializing)]
799        request: EraValidatorsRequest,
800        /// Responder to call with the result.
801        responder: Responder<EraValidatorsResult>,
802    },
803    /// Returns the seigniorage recipients snapshot at the given state root hash.
804    GetSeigniorageRecipients {
805        /// Get seigniorage recipients request.
806        #[serde(skip_serializing)]
807        request: SeigniorageRecipientsRequest,
808        /// Responder to call with the result.
809        responder: Responder<SeigniorageRecipientsResult>,
810    },
811    /// Return all values at a given state root hash and given key tag.
812    GetTaggedValues {
813        /// Get tagged values request.
814        #[serde(skip_serializing)]
815        request: TaggedValuesRequest,
816        /// Responder to call with the result.
817        responder: Responder<TaggedValuesResult>,
818    },
819    /// Returns the value of the execution results checksum stored in the ChecksumRegistry for the
820    /// given state root hash.
821    GetExecutionResultsChecksum {
822        state_root_hash: Digest,
823        responder: Responder<ExecutionResultsChecksumResult>,
824    },
825    /// Returns an `AddressableEntity` if found under the given entity_addr.  If a legacy `Account`
826    /// or contract exists under the given key, it will be migrated to an `AddressableEntity`
827    /// and returned. However, global state is not altered and the migrated record does not
828    /// actually exist.
829    GetAddressableEntity {
830        state_root_hash: Digest,
831        entity_addr: EntityAddr,
832        responder: Responder<AddressableEntityResult>,
833    },
834    /// Returns information if an entry point exists under the given state root hash and entry
835    /// point key.
836    GetEntryPointExists {
837        state_root_hash: Digest,
838        contract_hash: HashAddr,
839        entry_point_name: String,
840        responder: Responder<EntryPointExistsResult>,
841    },
842    /// Get a trie or chunk by its ID.
843    GetTrie {
844        /// A request for a trie element.
845        #[serde(skip_serializing)]
846        request: TrieRequest,
847        /// Responder to call with the result.
848        responder: Responder<TrieResult>,
849    },
850    /// Insert a trie into global storage
851    PutTrie {
852        /// A request to persist a trie element.
853        #[serde(skip_serializing)]
854        request: PutTrieRequest,
855        /// Responder to call with the result. Contains the hash of the persisted trie.
856        responder: Responder<PutTrieResult>,
857    },
858    /// Execute transaction without committing results
859    SpeculativelyExecute {
860        /// Pre-state.
861        block_header: Box<BlockHeader>,
862        /// Transaction to execute.
863        transaction: Box<Transaction>,
864        /// Results
865        responder: Responder<SpeculativeExecutionResult>,
866    },
867    UpdateRuntimePrice(EraId, u8),
868    GetEraGasPrice {
869        era_id: EraId,
870        responder: Responder<Option<u8>>,
871    },
872    DoProtocolUpgrade {
873        protocol_upgrade_config: ProtocolUpgradeConfig,
874        next_block_height: u64,
875        parent_hash: BlockHash,
876        parent_seed: Digest,
877    },
878    UpdatePreState {
879        new_pre_state: ExecutionPreState,
880    },
881}
882
883impl Display for ContractRuntimeRequest {
884    fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
885        match self {
886            ContractRuntimeRequest::EnqueueBlockForExecution {
887                executable_block, ..
888            } => {
889                write!(formatter, "executable_block: {}", executable_block)
890            }
891            ContractRuntimeRequest::Query {
892                request: query_request,
893                ..
894            } => {
895                write!(formatter, "query request: {:?}", query_request)
896            }
897            ContractRuntimeRequest::QueryByPrefix { request, .. } => {
898                write!(formatter, "query by prefix request: {:?}", request)
899            }
900            ContractRuntimeRequest::GetBalance {
901                request: balance_request,
902                ..
903            } => write!(formatter, "balance request: {:?}", balance_request),
904            ContractRuntimeRequest::GetEraValidators { request, .. } => {
905                write!(formatter, "get era validators: {:?}", request)
906            }
907            ContractRuntimeRequest::GetSeigniorageRecipients { request, .. } => {
908                write!(formatter, "get seigniorage recipients for {:?}", request)
909            }
910            ContractRuntimeRequest::GetTaggedValues {
911                request: get_all_values_request,
912                ..
913            } => {
914                write!(
915                    formatter,
916                    "get all values request: {:?}",
917                    get_all_values_request
918                )
919            }
920            ContractRuntimeRequest::GetExecutionResultsChecksum {
921                state_root_hash, ..
922            } => write!(
923                formatter,
924                "get execution results checksum under {}",
925                state_root_hash
926            ),
927            ContractRuntimeRequest::GetAddressableEntity {
928                state_root_hash,
929                entity_addr,
930                ..
931            } => {
932                write!(
933                    formatter,
934                    "get addressable_entity {} under {}",
935                    entity_addr, state_root_hash
936                )
937            }
938            ContractRuntimeRequest::GetTrie { request, .. } => {
939                write!(formatter, "get trie: {:?}", request)
940            }
941            ContractRuntimeRequest::PutTrie { request, .. } => {
942                write!(formatter, "trie: {:?}", request)
943            }
944            ContractRuntimeRequest::SpeculativelyExecute {
945                transaction,
946                block_header,
947                ..
948            } => {
949                write!(
950                    formatter,
951                    "Execute {} on {}",
952                    transaction.hash(),
953                    block_header.state_root_hash()
954                )
955            }
956            ContractRuntimeRequest::UpdateRuntimePrice(_, era_gas_price) => {
957                write!(formatter, "updating price to {}", era_gas_price)
958            }
959            ContractRuntimeRequest::GetEraGasPrice { era_id, .. } => {
960                write!(formatter, "Get gas price for era {}", era_id)
961            }
962            ContractRuntimeRequest::GetEntryPointExists {
963                state_root_hash,
964                contract_hash,
965                entry_point_name,
966                ..
967            } => {
968                let formatted_contract_hash = HexFmt(contract_hash);
969                write!(
970                    formatter,
971                    "get entry point {}-{} under {}",
972                    formatted_contract_hash, entry_point_name, state_root_hash
973                )
974            }
975            ContractRuntimeRequest::DoProtocolUpgrade {
976                protocol_upgrade_config,
977                ..
978            } => {
979                write!(
980                    formatter,
981                    "execute protocol upgrade against config: {:?}",
982                    protocol_upgrade_config
983                )
984            }
985            ContractRuntimeRequest::UpdatePreState { new_pre_state } => {
986                write!(
987                    formatter,
988                    "Updating contract runtimes execution prestate: {:?}",
989                    new_pre_state
990                )
991            }
992        }
993    }
994}
995
996/// Fetcher related requests.
997#[derive(Debug, Serialize)]
998#[must_use]
999pub(crate) struct FetcherRequest<T: FetchItem> {
1000    /// The ID of the item to be retrieved.
1001    pub(crate) id: T::Id,
1002    /// The peer id of the peer to be asked if the item is not held locally
1003    pub(crate) peer: NodeId,
1004    /// Metadata used during validation of the fetched item.
1005    pub(crate) validation_metadata: Box<T::ValidationMetadata>,
1006    /// Responder to call with the result.
1007    pub(crate) responder: Responder<FetchResult<T>>,
1008}
1009
1010impl<T: FetchItem> Display for FetcherRequest<T> {
1011    fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
1012        write!(formatter, "request item by id {}", self.id)
1013    }
1014}
1015
1016/// TrieAccumulator related requests.
1017#[derive(Debug, Serialize, DataSize)]
1018#[must_use]
1019pub(crate) struct TrieAccumulatorRequest {
1020    /// The hash of the trie node.
1021    pub(crate) hash: Digest,
1022    /// The peers to try to fetch from.
1023    pub(crate) peers: Vec<NodeId>,
1024    /// Responder to call with the result.
1025    pub(crate) responder: Responder<Result<TrieAccumulatorResponse, TrieAccumulatorError>>,
1026}
1027
1028impl Display for TrieAccumulatorRequest {
1029    fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
1030        write!(formatter, "request trie by hash {}", self.hash)
1031    }
1032}
1033
1034#[derive(Debug, Serialize)]
1035pub(crate) struct SyncGlobalStateRequest {
1036    pub(crate) block_hash: BlockHash,
1037    pub(crate) state_root_hash: Digest,
1038    #[serde(skip)]
1039    pub(crate) responder:
1040        Responder<Result<GlobalStateSynchronizerResponse, GlobalStateSynchronizerError>>,
1041}
1042
1043impl Display for SyncGlobalStateRequest {
1044    fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
1045        write!(
1046            formatter,
1047            "request to sync global state at {}",
1048            self.block_hash
1049        )
1050    }
1051}
1052
1053/// A block validator request.
1054#[derive(Debug, DataSize)]
1055#[must_use]
1056pub(crate) struct BlockValidationRequest {
1057    /// The height of the proposed block in the chain.
1058    pub(crate) proposed_block_height: u64,
1059    /// The block to be validated.
1060    pub(crate) block: ProposedBlock<ClContext>,
1061    /// The sender of the block, which will be asked to provide all missing transactions.
1062    pub(crate) sender: NodeId,
1063    /// Responder to call with the result.
1064    ///
1065    /// Indicates whether validation was successful.
1066    pub(crate) responder: Responder<Result<(), Box<InvalidProposalError>>>,
1067}
1068
1069impl Display for BlockValidationRequest {
1070    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1071        let BlockValidationRequest { block, sender, .. } = self;
1072        write!(f, "validate block {} from {}", block, sender)
1073    }
1074}
1075
1076type BlockHeight = u64;
1077
1078#[derive(DataSize, Debug)]
1079#[must_use]
1080/// Consensus component requests.
1081pub(crate) enum ConsensusRequest {
1082    /// Request for our public key, and if we're a validator, the next round length.
1083    Status(Responder<Option<ConsensusStatus>>),
1084    /// Request for a list of validator status changes, by public key.
1085    ValidatorChanges(Responder<ConsensusValidatorChanges>),
1086}
1087
1088/// ChainspecLoader component requests.
1089#[derive(Debug, Serialize)]
1090pub(crate) enum ChainspecRawBytesRequest {
1091    /// Request for the chainspec file bytes with the genesis_accounts and global_state bytes, if
1092    /// they are present.
1093    GetChainspecRawBytes(Responder<Arc<ChainspecRawBytes>>),
1094}
1095
1096impl Display for ChainspecRawBytesRequest {
1097    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1098        match self {
1099            ChainspecRawBytesRequest::GetChainspecRawBytes(_) => {
1100                write!(f, "get chainspec raw bytes")
1101            }
1102        }
1103    }
1104}
1105
1106/// UpgradeWatcher component request to get the next scheduled upgrade, if any.
1107#[derive(Debug, Serialize)]
1108pub(crate) struct UpgradeWatcherRequest(pub(crate) Responder<Option<NextUpgrade>>);
1109
1110impl Display for UpgradeWatcherRequest {
1111    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1112        write!(f, "get next upgrade")
1113    }
1114}
1115
1116#[derive(Debug, Serialize)]
1117pub(crate) enum ReactorInfoRequest {
1118    ReactorState { responder: Responder<ReactorState> },
1119    LastProgress { responder: Responder<LastProgress> },
1120    Uptime { responder: Responder<Uptime> },
1121    NetworkName { responder: Responder<NetworkName> },
1122    BalanceHoldsInterval { responder: Responder<TimeDiff> },
1123}
1124
1125impl Display for ReactorInfoRequest {
1126    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1127        write!(
1128            f,
1129            "get reactor status: {}",
1130            match self {
1131                ReactorInfoRequest::ReactorState { .. } => "ReactorState",
1132                ReactorInfoRequest::LastProgress { .. } => "LastProgress",
1133                ReactorInfoRequest::Uptime { .. } => "Uptime",
1134                ReactorInfoRequest::NetworkName { .. } => "NetworkName",
1135                ReactorInfoRequest::BalanceHoldsInterval { .. } => "BalanceHoldsInterval",
1136            }
1137        )
1138    }
1139}
1140
1141#[derive(Debug, Serialize)]
1142#[allow(clippy::enum_variant_names)]
1143pub(crate) enum BlockAccumulatorRequest {
1144    GetPeersForBlock {
1145        block_hash: BlockHash,
1146        responder: Responder<Option<Vec<NodeId>>>,
1147    },
1148}
1149
1150impl Display for BlockAccumulatorRequest {
1151    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1152        match self {
1153            BlockAccumulatorRequest::GetPeersForBlock { block_hash, .. } => {
1154                write!(f, "get peers for {}", block_hash)
1155            }
1156        }
1157    }
1158}
1159
1160#[derive(Debug, Serialize)]
1161pub(crate) enum BlockSynchronizerRequest {
1162    NeedNext,
1163    DishonestPeers,
1164    SyncGlobalStates(Vec<(BlockHash, Digest)>),
1165    Status {
1166        responder: Responder<BlockSynchronizerStatus>,
1167    },
1168}
1169
1170impl Display for BlockSynchronizerRequest {
1171    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1172        match self {
1173            BlockSynchronizerRequest::NeedNext => {
1174                write!(f, "block synchronizer request: need next")
1175            }
1176            BlockSynchronizerRequest::DishonestPeers => {
1177                write!(f, "block synchronizer request: dishonest peers")
1178            }
1179            BlockSynchronizerRequest::Status { .. } => {
1180                write!(f, "block synchronizer request: status")
1181            }
1182            BlockSynchronizerRequest::SyncGlobalStates(_) => {
1183                write!(f, "request to sync global states")
1184            }
1185        }
1186    }
1187}
1188
1189/// A request to set the current shutdown trigger.
1190#[derive(DataSize, Debug, Serialize)]
1191pub(crate) struct SetNodeStopRequest {
1192    /// The specific stop-at spec.
1193    ///
1194    /// If `None`, clears the current stop at setting.
1195    pub(crate) stop_at: Option<StopAtSpec>,
1196    /// Responder to send the previously set stop-at spec to, if any.
1197    pub(crate) responder: Responder<Option<StopAtSpec>>,
1198}
1199
1200impl Display for SetNodeStopRequest {
1201    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1202        match self.stop_at {
1203            None => f.write_str("clear node stop"),
1204            Some(stop_at) => write!(f, "set node stop to: {}", stop_at),
1205        }
1206    }
1207}
1208
1209/// A request to accept a new transaction.
1210#[derive(DataSize, Debug, Serialize)]
1211pub(crate) struct AcceptTransactionRequest {
1212    pub(crate) transaction: Transaction,
1213    pub(crate) is_speculative: bool,
1214    pub(crate) responder: Responder<Result<(), transaction_acceptor::Error>>,
1215}
1216
1217impl Display for AcceptTransactionRequest {
1218    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
1219        write!(
1220            f,
1221            "accept transaction {} is_speculative: {}",
1222            self.transaction.hash(),
1223            self.is_speculative
1224        )
1225    }
1226}