Skip to main content

hopr_protocol_hopr/
types.rs

1use bytes::Bytes;
2use hopr_api::types::{crypto::prelude::*, internal::prelude::*};
3use hopr_crypto_packet::prelude::*;
4
5/// Packet that is being sent out by us.
6pub struct OutgoingPacket {
7    /// Offchain public key of the next hop.
8    pub next_hop: OffchainPublicKey,
9    /// Challenge to be solved from the acknowledgement of the next hop.
10    pub ack_challenge: HalfKeyChallenge,
11    /// Encoded HOPR packet.
12    pub data: Bytes,
13    /// SURBs minted onto this packet, in the order of the return paths that produced them.
14    ///
15    /// Surfaced so a layer above can pair each SURB with the return path it encodes — the ids exist
16    /// only inside packet construction, and the routing that produced them only outside it, so this
17    /// is the single point where the two can be associated. Empty for packets carrying no SURBs.
18    pub minted_surbs: Vec<HoprSurbId>,
19}
20
21impl std::fmt::Debug for OutgoingPacket {
22    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
23        f.debug_struct("OutgoingPacket")
24            .field("next_hop", &self.next_hop)
25            .field("ack_challenge", &self.ack_challenge)
26            .finish_non_exhaustive()
27    }
28}
29
30/// Contains some miscellaneous information about a received packet.
31#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)]
32pub struct AuxiliaryPacketInfo {
33    /// Packet signals that the packet carried.
34    ///
35    /// Zero if no signal flags were specified.
36    pub packet_signals: PacketSignals,
37    /// Number of SURBs that the packet carried.
38    pub num_surbs: usize,
39    /// How many already-held SURBs the store evicted while inserting this packet's, because the
40    /// per-pseudonym buffer was already full.
41    ///
42    /// The arriving SURBs are retained; what is lost is the oldest of what was already queued. This
43    /// is the only point at which an overflow is visible — every layer above sees an insert that
44    /// merely "succeeded". See
45    /// [`SurbStoreConfig::rb_capacity`](crate::SurbStoreConfig::rb_capacity).
46    ///
47    /// Carried for observability. Sessions deliberately do not subtract it from their SURB level
48    /// estimate, because the imprecise estimate is the one that fails safe — see
49    /// `counterparty_buffer_capacity` in `hopr-transport-session`.
50    pub num_evicted_surbs: usize,
51}
52
53/// An incoming packet with a payload intended for us.
54pub struct IncomingFinalPacket {
55    /// Packet tag.
56    pub packet_tag: PacketTag,
57    /// Offchain public key of the previous hop.
58    pub previous_hop: OffchainPublicKey,
59    /// Sender pseudonym.
60    pub sender: HoprPseudonym,
61    /// SURB this packet was a reply on, when it was one.
62    ///
63    /// `None` for a packet that was not sent using one of our SURBs. Surfaced because decoding
64    /// already resolves the sender id to find the reply opener, so the id is known here and
65    /// nowhere later.
66    pub replied_on_surb: Option<HoprSurbId>,
67    /// Plain text payload of the packet.
68    pub plain_text: Box<[u8]>,
69    /// Acknowledgement to be sent to the previous hop.
70    pub ack_key: HalfKey,
71    /// Miscellaneous information about the packet.
72    pub info: AuxiliaryPacketInfo,
73}
74
75impl std::fmt::Debug for IncomingFinalPacket {
76    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
77        f.debug_struct("IncomingFinalPacket")
78            .field("packet_tag", &self.packet_tag)
79            .field("previous_hop", &self.previous_hop)
80            .field("sender", &self.sender)
81            .field("ack_key", &self.ack_key)
82            .field("info", &self.info)
83            .finish_non_exhaustive()
84    }
85}
86
87/// Incoming packet that must be forwarded.
88pub struct IncomingForwardedPacket {
89    /// Packet tag.
90    pub packet_tag: PacketTag,
91    /// Offchain public key of the previous hop.
92    pub previous_hop: OffchainPublicKey,
93    /// Offchain public key of the next hop.
94    pub next_hop: OffchainPublicKey,
95    /// Data to be forwarded to the next hop.
96    pub data: Bytes,
97    /// Challenge to be solved from the acknowledgement received from the next hop.
98    pub ack_challenge: HalfKeyChallenge,
99    /// Ticket to be acknowledged by solving the `ack_challenge`.
100    pub received_ticket: UnacknowledgedTicket,
101    /// Acknowledgement payload to be sent to the previous hop
102    pub ack_key_prev_hop: HalfKey,
103}
104
105impl std::fmt::Debug for IncomingForwardedPacket {
106    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
107        f.debug_struct("IncomingForwardedPacket")
108            .field("packet_tag", &self.packet_tag)
109            .field("previous_hop", &self.previous_hop)
110            .field("next_hop", &self.next_hop)
111            .field("received_ticket", &self.received_ticket)
112            .field("ack_challenge", &self.ack_challenge)
113            .field("ack_key_prev_hop", &self.ack_key_prev_hop)
114            .finish_non_exhaustive()
115    }
116}
117
118/// Incoming packet that contains acknowledgements of delivered packets.
119pub struct IncomingAcknowledgementPacket {
120    /// Packet tag.
121    pub packet_tag: PacketTag,
122    /// Offchain public key of the previous hop which sent the acknowledgements.
123    pub previous_hop: OffchainPublicKey,
124    /// Unverified acknowledgements.
125    pub received_acks: Vec<Acknowledgement>,
126}
127
128impl std::fmt::Debug for IncomingAcknowledgementPacket {
129    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
130        f.debug_struct("IncomingAcknowledgementPacket")
131            .field("packet_tag", &self.packet_tag)
132            .field("previous_hop", &self.previous_hop)
133            .field("received_acks", &self.received_acks)
134            .finish()
135    }
136}
137
138/// Incoming HOPR packet.
139#[derive(Debug, strum::EnumTryAs)]
140pub enum IncomingPacket {
141    /// Packet is intended for us
142    Final(Box<IncomingFinalPacket>),
143    /// Packet must be forwarded
144    Forwarded(Box<IncomingForwardedPacket>),
145    /// The packet contains acknowledgements of delivered packets.
146    Acknowledgement(Box<IncomingAcknowledgementPacket>),
147}
148
149impl IncomingPacket {
150    /// Tag identifying the packet.
151    pub fn packet_tag(&self) -> &PacketTag {
152        match self {
153            IncomingPacket::Final(f) => &f.packet_tag,
154            IncomingPacket::Forwarded(f) => &f.packet_tag,
155            IncomingPacket::Acknowledgement(f) => &f.packet_tag,
156        }
157    }
158
159    /// Previous hop that sent us the packet.
160    pub fn previous_hop(&self) -> &OffchainPublicKey {
161        match self {
162            IncomingPacket::Final(f) => &f.previous_hop,
163            IncomingPacket::Forwarded(f) => &f.previous_hop,
164            IncomingPacket::Acknowledgement(f) => &f.previous_hop,
165        }
166    }
167}
168
169/// Contains a SURB found in the SURB ring buffer via `SurbStore::find_surb`.
170#[derive(Debug)]
171pub struct FoundSurb {
172    /// Complete sender ID of the SURB.
173    pub sender_id: HoprSenderId,
174    /// The SURB itself.
175    pub surb: HoprSurb,
176    /// Number of SURBs remaining in the ring buffer with the same pseudonym.
177    pub remaining: usize,
178}
179
180/// What storing SURBs via `SurbStore::insert_surbs` did to the ring buffer.
181///
182/// The `evicted` count exists because an overflow is otherwise entirely silent: the buffer drops its
183/// oldest entry and the caller sees only that the insert "succeeded". That count is the only local
184/// evidence that the sender is producing faster than this side can hold.
185#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
186pub struct SurbInsertOutcome {
187    /// Number of SURBs held for the pseudonym after the insert.
188    pub retained: usize,
189    /// Number of SURBs dropped to make room during this insert, oldest first.
190    pub evicted: usize,
191}
192
193/// Determines the result of how an acknowledgement was resolved.
194#[derive(Debug, strum::EnumTryAs)]
195pub enum ResolvedAcknowledgement {
196    /// The acknowledgement resulted in a winning ticket.
197    RelayingWin(Box<RedeemableTicket>),
198    /// The acknowledgement resulted in a losing ticket.
199    RelayingLoss(ChannelId),
200}