Skip to main content

miden_client/rpc/domain/
status.rs

1use alloc::string::{String, ToString};
2use core::convert::TryInto;
3
4use miden_protocol::Word;
5
6use crate::rpc::RpcError;
7use crate::rpc::generated::{self as proto};
8
9/// Represents node status info with fields converted into domain types.
10pub struct RpcStatusInfo {
11    pub version: String,
12    pub genesis_commitment: Option<Word>,
13    pub chain_tip: u32,
14    pub block_producer: Option<BlockProducerStatusInfo>,
15}
16
17/// Represents block producer status info with fields converted into domain types.
18pub struct BlockProducerStatusInfo {
19    pub version: String,
20    pub status: String,
21    pub chain_tip: u32,
22    pub mempool_stats: Option<MempoolStatsInfo>,
23}
24
25/// Represents mempool stats with fields converted into domain types.
26pub struct MempoolStatsInfo {
27    pub unbatched_transactions: u64,
28    pub proposed_batches: u64,
29    pub proven_batches: u64,
30}
31
32pub enum NetworkNoteStatus {
33    /// The note is awaiting execution or being retried after transient failures.
34    Pending,
35    /// The note has been consumed by a transaction that was sent to the block producer.
36    NullifierInflight,
37    /// The note exceeded the maximum retry count and will not be retried.
38    Discarded,
39    /// The note's consuming transaction has been committed on-chain.
40    NullifierCommitted,
41}
42
43impl core::fmt::Display for NetworkNoteStatus {
44    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
45        match self {
46            NetworkNoteStatus::Pending => write!(f, "Pending"),
47            NetworkNoteStatus::NullifierInflight => write!(f, "NullifierInflight"),
48            NetworkNoteStatus::Discarded => write!(f, "Discarded"),
49            NetworkNoteStatus::NullifierCommitted => write!(f, "NullifierCommitted"),
50        }
51    }
52}
53
54/// Information about the processing status of a note submitted to the network.
55///
56/// This is returned by the `GetNetworkNoteStatus` RPC endpoint and provides details
57/// about how the node is handling a note, including retry attempts and error diagnostics.
58pub struct NetworkNoteStatusInfo {
59    /// The current processing status of the note.
60    pub status: NetworkNoteStatus,
61    /// The error message from the most recent failed processing attempt, if any.
62    pub last_error: Option<String>,
63    /// The total number of times the node has attempted to process this note.
64    pub attempt_count: u32,
65    /// The block number at which the last processing attempt occurred, if any.
66    pub last_attempt_block_num: Option<u32>,
67}
68
69impl TryFrom<i32> for NetworkNoteStatus {
70    type Error = RpcError;
71
72    fn try_from(value: i32) -> Result<Self, Self::Error> {
73        let value: proto::rpc::NetworkNoteStatus = value
74            .try_into()
75            .map_err(|_| RpcError::ExpectedDataMissing("NetworkNoteStatus".to_string()))?;
76
77        match value {
78            proto::rpc::NetworkNoteStatus::Unspecified => {
79                Err(RpcError::ExpectedDataMissing("NetworkNoteStatus".to_string()))
80            },
81            proto::rpc::NetworkNoteStatus::Pending => Ok(NetworkNoteStatus::Pending),
82            proto::rpc::NetworkNoteStatus::NullifierInflight => {
83                Ok(NetworkNoteStatus::NullifierInflight)
84            },
85            proto::rpc::NetworkNoteStatus::Discarded => Ok(NetworkNoteStatus::Discarded),
86            proto::rpc::NetworkNoteStatus::NullifierCommitted => {
87                Ok(NetworkNoteStatus::NullifierCommitted)
88            },
89        }
90    }
91}
92
93impl TryFrom<proto::rpc::GetNetworkNoteStatusResponse> for NetworkNoteStatusInfo {
94    type Error = RpcError;
95
96    fn try_from(value: proto::rpc::GetNetworkNoteStatusResponse) -> Result<Self, Self::Error> {
97        let status = value.status.try_into()?;
98        let last_error = value.last_error;
99        let attempt_count = value.attempt_count;
100        let last_attempt_block_num = value.last_attempt_block_num;
101
102        Ok(NetworkNoteStatusInfo {
103            status,
104            last_error,
105            attempt_count,
106            last_attempt_block_num,
107        })
108    }
109}
110
111impl TryFrom<proto::rpc::RpcStatus> for RpcStatusInfo {
112    type Error = RpcError;
113
114    fn try_from(value: proto::rpc::RpcStatus) -> Result<Self, Self::Error> {
115        let genesis_commitment = value.genesis_commitment.map(TryInto::try_into).transpose()?;
116        Ok(Self {
117            version: value.version,
118            genesis_commitment,
119            chain_tip: value.chain_tip,
120            block_producer: value.block_producer.map(Into::into),
121        })
122    }
123}
124
125impl From<proto::rpc::BlockProducerStatus> for BlockProducerStatusInfo {
126    fn from(value: proto::rpc::BlockProducerStatus) -> Self {
127        Self {
128            version: value.version,
129            status: value.status,
130            chain_tip: value.chain_tip,
131            mempool_stats: value.mempool_stats.map(Into::into),
132        }
133    }
134}
135
136impl From<proto::rpc::MempoolStats> for MempoolStatsInfo {
137    fn from(value: proto::rpc::MempoolStats) -> Self {
138        Self {
139            unbatched_transactions: value.unbatched_transactions,
140            proposed_batches: value.proposed_batches,
141            proven_batches: value.proven_batches,
142        }
143    }
144}