miden_node_proto/domain/
mempool.rs

1use std::collections::HashSet;
2
3use miden_objects::account::delta::AccountUpdateDetails;
4use miden_objects::block::BlockHeader;
5use miden_objects::note::Nullifier;
6use miden_objects::transaction::TransactionId;
7use miden_objects::utils::{Deserializable, Serializable};
8
9use super::note::NetworkNote;
10use crate::errors::{ConversionError, MissingFieldHelper};
11use crate::generated as proto;
12
13#[derive(Debug, Clone)]
14pub enum MempoolEvent {
15    TransactionAdded {
16        id: TransactionId,
17        nullifiers: Vec<Nullifier>,
18        network_notes: Vec<NetworkNote>,
19        account_delta: Option<AccountUpdateDetails>,
20    },
21    BlockCommitted {
22        header: BlockHeader,
23        txs: Vec<TransactionId>,
24    },
25    TransactionsReverted(HashSet<TransactionId>),
26}
27
28impl MempoolEvent {
29    pub fn kind(&self) -> &'static str {
30        match self {
31            MempoolEvent::TransactionAdded { .. } => "TransactionAdded",
32            MempoolEvent::BlockCommitted { .. } => "BlockCommitted",
33            MempoolEvent::TransactionsReverted(_) => "TransactionsReverted",
34        }
35    }
36}
37
38impl From<MempoolEvent> for proto::block_producer::MempoolEvent {
39    fn from(event: MempoolEvent) -> Self {
40        let event = match event {
41            MempoolEvent::TransactionAdded {
42                id,
43                nullifiers,
44                network_notes,
45                account_delta,
46            } => {
47                let event = proto::block_producer::mempool_event::TransactionAdded {
48                    id: Some(id.into()),
49                    nullifiers: nullifiers.into_iter().map(Into::into).collect(),
50                    network_notes: network_notes.into_iter().map(Into::into).collect(),
51                    network_account_delta: account_delta
52                        .as_ref()
53                        .map(AccountUpdateDetails::to_bytes),
54                };
55
56                proto::block_producer::mempool_event::Event::TransactionAdded(event)
57            },
58            MempoolEvent::BlockCommitted { header, txs } => {
59                proto::block_producer::mempool_event::Event::BlockCommitted(
60                    proto::block_producer::mempool_event::BlockCommitted {
61                        block_header: Some(header.into()),
62                        transactions: txs.into_iter().map(Into::into).collect(),
63                    },
64                )
65            },
66            MempoolEvent::TransactionsReverted(txs) => {
67                proto::block_producer::mempool_event::Event::TransactionsReverted(
68                    proto::block_producer::mempool_event::TransactionsReverted {
69                        reverted: txs.into_iter().map(Into::into).collect(),
70                    },
71                )
72            },
73        }
74        .into();
75
76        Self { event }
77    }
78}
79
80impl TryFrom<proto::block_producer::MempoolEvent> for MempoolEvent {
81    type Error = ConversionError;
82
83    fn try_from(event: proto::block_producer::MempoolEvent) -> Result<Self, Self::Error> {
84        let event =
85            event.event.ok_or(proto::block_producer::MempoolEvent::missing_field("event"))?;
86
87        match event {
88            proto::block_producer::mempool_event::Event::TransactionAdded(tx) => {
89                let id = tx
90                    .id
91                    .ok_or(proto::block_producer::mempool_event::TransactionAdded::missing_field(
92                        "id",
93                    ))?
94                    .try_into()?;
95                let nullifiers =
96                    tx.nullifiers.into_iter().map(TryInto::try_into).collect::<Result<_, _>>()?;
97                let network_notes = tx
98                    .network_notes
99                    .into_iter()
100                    .map(TryInto::try_into)
101                    .collect::<Result<_, _>>()?;
102                let account_delta = tx
103                    .network_account_delta
104                    .as_deref()
105                    .map(AccountUpdateDetails::read_from_bytes)
106                    .transpose()
107                    .map_err(|err| ConversionError::deserialization_error("account_delta", err))?;
108
109                Ok(Self::TransactionAdded {
110                    id,
111                    nullifiers,
112                    network_notes,
113                    account_delta,
114                })
115            },
116            proto::block_producer::mempool_event::Event::BlockCommitted(block_committed) => {
117                let header = block_committed
118                    .block_header
119                    .ok_or(proto::block_producer::mempool_event::BlockCommitted::missing_field(
120                        "block_header",
121                    ))?
122                    .try_into()?;
123                let txs = block_committed
124                    .transactions
125                    .into_iter()
126                    .map(TransactionId::try_from)
127                    .collect::<Result<_, _>>()?;
128
129                Ok(Self::BlockCommitted { header, txs })
130            },
131            proto::block_producer::mempool_event::Event::TransactionsReverted(txs) => {
132                let txs = txs
133                    .reverted
134                    .into_iter()
135                    .map(TransactionId::try_from)
136                    .collect::<Result<_, _>>()?;
137
138                Ok(Self::TransactionsReverted(txs))
139            },
140        }
141    }
142}