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}