hopr_internal_types/
protocol.rs1use hopr_crypto_random::Randomizable;
2use hopr_crypto_types::prelude::*;
3use hopr_primitive_types::prelude::*;
4
5use crate::{
6 errors::{CoreTypesError, Result},
7 prelude::UnacknowledgedTicket,
8};
9
10pub const INTERMEDIATE_HOPS: usize = 3;
12
13pub const DEFAULT_MINIMUM_INCOMING_TICKET_WIN_PROB: f64 = 1.0;
15
16pub const DEFAULT_MAXIMUM_INCOMING_TICKET_WIN_PROB: f64 = 1.0; pub type HoprPseudonym = SimplePseudonym;
22
23#[derive(Copy, Clone, Debug, PartialEq, Eq)]
30#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
31pub struct Acknowledgement(#[cfg_attr(feature = "serde", serde(with = "serde_bytes"))] [u8; Self::SIZE]);
32
33impl AsRef<[u8]> for Acknowledgement {
34 fn as_ref(&self) -> &[u8] {
35 &self.0
36 }
37}
38
39impl TryFrom<&[u8]> for Acknowledgement {
40 type Error = GeneralError;
41
42 fn try_from(value: &[u8]) -> std::result::Result<Self, Self::Error> {
43 Ok(Self(
44 value
45 .try_into()
46 .map_err(|_| GeneralError::ParseError("Acknowledgement".into()))?,
47 ))
48 }
49}
50
51impl BytesRepresentable for Acknowledgement {
52 const SIZE: usize = HalfKey::SIZE + OffchainSignature::SIZE;
53}
54
55impl Acknowledgement {
56 pub fn verify(self, sender_node_key: &OffchainPublicKey) -> Result<VerifiedAcknowledgement> {
58 let signature = OffchainSignature::try_from(&self.0[HalfKey::SIZE..HalfKey::SIZE + OffchainSignature::SIZE])?;
59 if signature.verify_message(&self.0[0..HalfKey::SIZE], sender_node_key) {
60 Ok(VerifiedAcknowledgement {
61 ack_key_share: HalfKey::try_from(&self.0[0..HalfKey::SIZE])?,
62 signature,
63 })
64 } else {
65 Err(CoreTypesError::InvalidAcknowledgement)
66 }
67 }
68}
69
70#[derive(Copy, Clone, Debug, PartialEq)]
74pub struct VerifiedAcknowledgement {
75 ack_key_share: HalfKey,
76 signature: OffchainSignature,
77}
78
79impl VerifiedAcknowledgement {
80 pub fn new(ack_key_share: HalfKey, node_keypair: &OffchainKeypair) -> Self {
81 let signature = OffchainSignature::sign_message(ack_key_share.as_ref(), node_keypair);
82 Self {
83 ack_key_share,
84 signature,
85 }
86 }
87
88 pub fn random(offchain_keypair: &OffchainKeypair) -> Self {
90 Self::new(HalfKey::random(), offchain_keypair)
91 }
92
93 pub fn leak(self) -> Acknowledgement {
95 let mut ret = [0u8; Acknowledgement::SIZE];
96 ret[0..HalfKey::SIZE].copy_from_slice(self.ack_key_share.as_ref());
97 ret[HalfKey::SIZE..HalfKey::SIZE + OffchainSignature::SIZE].copy_from_slice(self.signature.as_ref());
98 Acknowledgement(ret)
99 }
100
101 pub fn ack_key_share(&self) -> &HalfKey {
105 &self.ack_key_share
106 }
107}
108
109#[derive(Clone, Debug, PartialEq, Eq)]
112#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
113pub enum PendingAcknowledgement {
114 WaitingAsSender,
116 WaitingAsRelayer(Box<UnacknowledgedTicket>),
118}
119
120#[cfg(test)]
121mod tests {
122 use super::*;
123
124 #[test]
125 fn acknowledgement_should_verify() -> anyhow::Result<()> {
126 let kp = OffchainKeypair::random();
127 let v_ack_1 = VerifiedAcknowledgement::random(&kp);
128 let v_ack_2 = v_ack_1.leak().verify(kp.public())?;
129
130 assert_eq!(v_ack_1, v_ack_2);
131 Ok(())
132 }
133}