hopr_db_api/
protocol.rs

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