Skip to main content

amaru_protocols/tx_submission/
outcome.rs

1// Copyright 2025 PRAGMA
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use std::fmt::{Display, Formatter};
16
17use amaru_ouroboros_traits::TxId;
18use serde::{Deserialize, Serialize};
19
20use crate::tx_submission::{ResponderResult, initiator::InitiatorResult};
21
22/// Outcome of a protocol state machine step
23#[derive(Debug)]
24pub enum Outcome {
25    Done,
26    Error(ProtocolError),
27    Initiator(InitiatorResult),
28    Responder(ResponderResult),
29}
30
31#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
32pub enum ProtocolError {
33    NoTxIdsRequested,
34    BlockingRequestMadeWhenTxsStillUnacknowledged,
35    NonBlockingRequestMadeWhenAllTxsAcknowledged,
36    NoAckOrReqTxIdsRequested,
37    NoTxsRequested,
38    UnadvertisedTransactionIdsRequested(Vec<TxId>),
39    UnknownTxsRequested(Vec<TxId>),
40    DuplicateTxIds(Vec<TxId>),
41    MaxOutstandingTxIdsRequested(u16, u16),
42    TooManyAcknowledgedTxs(u16, u16),
43    TooManyTxIdsReceived(usize, usize, usize),
44    ReceivedTxsExceedsBatchSize(usize, usize),
45    SomeReceivedTxsNotInFlight(Vec<TxId>),
46}
47
48impl Display for ProtocolError {
49    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
50        match self {
51            ProtocolError::NoTxIdsRequested => write!(f, "0 tx ids were requested"),
52            ProtocolError::BlockingRequestMadeWhenTxsStillUnacknowledged => {
53                write!(f, "a non-blocking request must be made when some txs are unacknowledged")
54            }
55            ProtocolError::NonBlockingRequestMadeWhenAllTxsAcknowledged => {
56                write!(f, "a blocking request must be made when all the txs are acknowledged")
57            }
58            ProtocolError::NoAckOrReqTxIdsRequested => {
59                write!(f, "0 transactions acknowledged and 0 transaction ids requested")
60            }
61            ProtocolError::NoTxsRequested => write!(f, "0 transactions were requested"),
62            ProtocolError::UnadvertisedTransactionIdsRequested(tx_ids) => {
63                write!(f, "unadvertised transaction ids requested: {:?}", tx_ids)
64            }
65            ProtocolError::UnknownTxsRequested(tx_ids) => {
66                write!(f, "unknown transactions requested: {:?}", tx_ids)
67            }
68            ProtocolError::MaxOutstandingTxIdsRequested(req, limit) => {
69                write!(f, "the number of requested transaction ids exceeds the protocol limit: {req} > {limit}")
70            }
71            ProtocolError::TooManyAcknowledgedTxs(ack, window_len) => {
72                write!(
73                    f,
74                    "it is not possible to acknowledge more transactions than currently unacknowledged: {ack} > {window_len}"
75                )
76            }
77            ProtocolError::TooManyTxIdsReceived(received, current_window_len, max_window_len) => {
78                write!(
79                    f,
80                    "the number of received transaction ids exceeds the max window size: {received} + {current_window_len} > {max_window_len}"
81                )
82            }
83            ProtocolError::ReceivedTxsExceedsBatchSize(received, max) => {
84                write!(f, "the number of received transactions exceeds the configured batch size: {received} > {max}")
85            }
86            ProtocolError::SomeReceivedTxsNotInFlight(tx_ids) => {
87                write!(f, "some received transactions were not requested: {tx_ids:?}")
88            }
89            ProtocolError::DuplicateTxIds(tx_ids) => {
90                write!(f, "duplicate transaction ids were found in the request: {tx_ids:?}")
91            }
92        }
93    }
94}
95
96impl PartialEq for Outcome {
97    fn eq(&self, other: &Self) -> bool {
98        match (self, other) {
99            (Outcome::Done, Outcome::Done) => true,
100            (Outcome::Error(e1), Outcome::Error(e2)) => e1 == e2,
101            (Outcome::Initiator(m1), Outcome::Initiator(m2)) => m1 == m2,
102            (Outcome::Responder(m1), Outcome::Responder(m2)) => m1 == m2,
103            _ => false,
104        }
105    }
106}
107
108impl Eq for Outcome {}
109
110impl Display for Outcome {
111    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
112        match self {
113            Outcome::Done => write!(f, "Done"),
114            Outcome::Error(err) => write!(f, "ProtocolError({})", err),
115            Outcome::Initiator(msg) => write!(f, "Initiator({})", msg),
116            Outcome::Responder(msg) => write!(f, "Responder({})", msg),
117        }
118    }
119}