hopr_internal_types/
protocol.rs1use hopr_crypto_random::Randomizable;
2use hopr_crypto_types::prelude::*;
3use hopr_primitive_types::prelude::*;
4use tracing::warn;
5
6use crate::{
7 errors::{CoreTypesError, Result},
8 prelude::UnacknowledgedTicket,
9};
10
11pub const INTERMEDIATE_HOPS: usize = 3;
13
14pub const DEFAULT_MINIMUM_INCOMING_TICKET_WIN_PROB: f64 = 1.0;
16
17pub const DEFAULT_MAXIMUM_INCOMING_TICKET_WIN_PROB: f64 = 1.0; pub type HoprPseudonym = SimplePseudonym;
23
24#[derive(Copy, Clone, Debug, PartialEq)]
26#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
27pub struct Acknowledgement {
28 #[cfg_attr(feature = "serde", serde(with = "serde_bytes"))]
29 data: [u8; Self::SIZE],
30 #[cfg_attr(feature = "serde", serde(skip))]
31 validated: bool,
32}
33
34impl AsRef<[u8]> for Acknowledgement {
35 fn as_ref(&self) -> &[u8] {
36 &self.data
37 }
38}
39
40impl TryFrom<&[u8]> for Acknowledgement {
41 type Error = GeneralError;
42
43 fn try_from(value: &[u8]) -> std::result::Result<Self, Self::Error> {
44 if value.len() == Self::SIZE {
45 Ok(Self {
46 data: value.try_into().unwrap(),
47 validated: false,
48 })
49 } else {
50 Err(GeneralError::ParseError("Acknowledgement".into()))
51 }
52 }
53}
54
55impl Acknowledgement {
56 pub fn new(ack_key_share: HalfKey, node_keypair: &OffchainKeypair) -> Self {
57 let signature = OffchainSignature::sign_message(ack_key_share.as_ref(), node_keypair);
58 let mut data = [0u8; Self::SIZE];
59 data[0..HalfKey::SIZE].copy_from_slice(ack_key_share.as_ref());
60 data[HalfKey::SIZE..HalfKey::SIZE + OffchainSignature::SIZE].copy_from_slice(signature.as_ref());
61
62 Self { data, validated: true }
63 }
64
65 pub fn random(offchain_keypair: &OffchainKeypair) -> Self {
67 Self::new(HalfKey::random(), offchain_keypair)
68 }
69
70 #[tracing::instrument(level = "debug", skip(self, sender_node_key))]
75 pub fn validate(self, sender_node_key: &OffchainPublicKey) -> Result<Self> {
76 if !self.validated {
77 let signature =
78 OffchainSignature::try_from(&self.data[HalfKey::SIZE..HalfKey::SIZE + OffchainSignature::SIZE])?;
79 if signature.verify_message(&self.data[0..HalfKey::SIZE], sender_node_key) {
80 Ok(Self {
81 data: self.data,
82 validated: true,
83 })
84 } else {
85 Err(CoreTypesError::InvalidAcknowledgement)
86 }
87 } else {
88 Ok(self)
89 }
90 }
91
92 pub fn ack_key_share(&self) -> Result<HalfKey> {
97 if self.validated {
98 Ok(HalfKey::try_from(&self.data[0..HalfKey::SIZE])?)
99 } else {
100 Err(CoreTypesError::InvalidAcknowledgement)
101 }
102 }
103
104 pub fn ack_challenge(&self) -> Result<HalfKeyChallenge> {
109 Ok(self.ack_key_share()?.to_challenge())
110 }
111
112 pub fn is_validated(&self) -> bool {
114 self.validated
115 }
116}
117
118impl BytesRepresentable for Acknowledgement {
119 const SIZE: usize = HalfKey::SIZE + OffchainSignature::SIZE;
120}
121
122#[allow(clippy::large_enum_variant)]
125#[derive(Clone, Debug, PartialEq, Eq)]
126#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
127pub enum PendingAcknowledgement {
128 WaitingAsSender,
130 WaitingAsRelayer(UnacknowledgedTicket),
132}