hopr_transport_protocol/ack/
processor.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
use tracing::trace;

use hopr_crypto_types::prelude::*;
pub use hopr_db_api::protocol::AckResult;
use hopr_db_api::protocol::HoprDbProtocolOperations;
use hopr_internal_types::prelude::*;
use hopr_transport_identity::PeerId;

use crate::errors::{ProtocolError, Result};

/// Implements protocol acknowledgement logic for acknowledgements
#[derive(Clone)]
pub struct AcknowledgementProcessor<Db: HoprDbProtocolOperations> {
    db: Db,
    chain_key: ChainKeypair,
}

impl<Db: HoprDbProtocolOperations> AcknowledgementProcessor<Db> {
    pub fn new(db: Db, chain_key: &ChainKeypair) -> Self {
        Self {
            db,
            chain_key: chain_key.clone(),
        }
    }

    /// Processes the outgoing acknowledgement.
    #[inline]
    #[tracing::instrument(level = "debug", skip(self, ack))]
    pub async fn send(&self, peer: &PeerId, ack: Acknowledgement) -> Acknowledgement {
        ack
    }

    /// Processes the incoming acknowledgement.
    #[tracing::instrument(level = "debug", skip(self, ack))]
    pub async fn recv(&self, peer: &PeerId, mut ack: Acknowledgement) -> Result<AckResult> {
        let remote_pk = OffchainPublicKey::try_from(peer)?;
        if !ack.validate(&remote_pk) {
            tracing::error!("Failed to verify signature on received acknowledgement");
            return Err(ProtocolError::InvalidSignature);
        };

        self.db.handle_acknowledgement(ack, &self.chain_key).await.map_err(|e| {
            trace!(error = %e, "Failed to process a received acknowledgement");
            let error: ProtocolError = e.into();
            error
        })
    }
}