hopr_db_api/
protocol.rs

1use async_trait::async_trait;
2use hopr_crypto_types::prelude::*;
3use hopr_internal_types::prelude::*;
4use hopr_network_types::prelude::ResolvedTransportRouting;
5use hopr_primitive_types::prelude::Balance;
6use std::{fmt::Debug, result::Result};
7
8use crate::prelude::DbError;
9
10/// Trait defining all DB functionality needed by packet/acknowledgement processing pipeline.
11#[async_trait]
12pub trait HoprDbProtocolOperations {
13    /// Processes the acknowledgements for the pending tickets
14    ///
15    /// There are three cases:
16    /// 1. There is an unacknowledged ticket and we are awaiting a half key.
17    /// 2. We were the creator of the packet, hence we do not wait for any half key
18    /// 3. The acknowledgement is unexpected and stems from a protocol bug or an attacker
19    async fn handle_acknowledgement(&self, ack: Acknowledgement) -> crate::errors::Result<AckResult>;
20
21    /// Loads (presumably cached) value of the network's minimum winning probability from the DB.
22    async fn get_network_winning_probability(&self) -> crate::errors::Result<f64>;
23
24    /// Loads (presumably cached) value of the network's minimum ticket price from the DB.
25    async fn get_network_ticket_price(&self) -> crate::errors::Result<Balance>;
26
27    /// Process the data into an outgoing packet that is not going to be acknowledged.
28    async fn to_send_no_ack(
29        &self,
30        data: Box<[u8]>,
31        destination: OffchainPublicKey,
32    ) -> Result<TransportPacketWithChainData, DbError>;
33
34    /// Process the data into an outgoing packet
35    async fn to_send(
36        &self,
37        data: Box<[u8]>,
38        routing: ResolvedTransportRouting,
39        outgoing_ticket_win_prob: f64,
40        outgoing_ticket_price: Balance,
41    ) -> Result<TransportPacketWithChainData, DbError>;
42
43    /// Process the incoming packet into data
44    #[allow(clippy::wrong_self_convention)]
45    async fn from_recv(
46        &self,
47        data: Box<[u8]>,
48        pkt_keypair: &OffchainKeypair,
49        sender: OffchainPublicKey,
50        outgoing_ticket_win_prob: f64,
51        outgoing_ticket_price: Balance,
52    ) -> crate::errors::Result<TransportPacketWithChainData>;
53}
54
55#[allow(clippy::large_enum_variant)] // TODO: Uses too large objects
56pub enum AckResult {
57    Sender(Acknowledgement),
58    RelayerWinning(AcknowledgedTicket),
59    RelayerLosing,
60}
61
62impl Debug for AckResult {
63    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
64        match self {
65            Self::Sender(_) => f.debug_tuple("Sender").finish(),
66            Self::RelayerWinning(_) => f.debug_tuple("RelayerWinning").finish(),
67            Self::RelayerLosing => write!(f, "RelayerLosing"),
68        }
69    }
70}
71
72// TODO: create 4 separate objects and use them Boxed in the enum variants
73#[allow(clippy::large_enum_variant)]
74pub enum TransportPacketWithChainData {
75    /// Packet is intended for us
76    Final {
77        packet_tag: PacketTag,
78        previous_hop: OffchainPublicKey,
79        plain_text: Box<[u8]>,
80        ack_key: HalfKey,
81        no_ack: bool,
82    },
83    /// Packet must be forwarded
84    Forwarded {
85        packet_tag: PacketTag,
86        previous_hop: OffchainPublicKey,
87        next_hop: OffchainPublicKey,
88        data: Box<[u8]>,
89        ack: Acknowledgement,
90    },
91    /// Packet that is being sent out by us
92    Outgoing {
93        next_hop: OffchainPublicKey,
94        ack_challenge: HalfKeyChallenge,
95        data: Box<[u8]>,
96    },
97}
98
99#[allow(clippy::large_enum_variant)] // TODO: Uses too large objects
100pub enum ResolvedAcknowledgement {
101    Sending(Acknowledgement),
102    RelayingWin(AcknowledgedTicket),
103    RelayingLoss(Hash),
104}
105
106impl From<ResolvedAcknowledgement> for AckResult {
107    fn from(value: ResolvedAcknowledgement) -> Self {
108        match value {
109            ResolvedAcknowledgement::Sending(ack) => AckResult::Sender(ack),
110            ResolvedAcknowledgement::RelayingWin(ack_ticket) => AckResult::RelayerWinning(ack_ticket),
111            ResolvedAcknowledgement::RelayingLoss(_) => AckResult::RelayerLosing,
112        }
113    }
114}