saito_core/core/consensus/
hop.rs1use std::fmt::Display;
2use std::io::{Error, ErrorKind};
3
4use serde::{Deserialize, Serialize};
5
6use crate::core::consensus::transaction::Transaction;
7use crate::core::defs::{PrintForLog, SaitoPrivateKey, SaitoPublicKey, SaitoSignature};
8use crate::core::util::crypto::sign;
9
10pub const HOP_SIZE: usize = 130;
11
12#[serde_with::serde_as]
13#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
14pub struct Hop {
15 #[serde_as(as = "[_; 33]")]
16 pub from: SaitoPublicKey,
17 #[serde_as(as = "[_; 33]")]
18 pub to: SaitoPublicKey,
19 #[serde_as(as = "[_; 64]")]
20 pub sig: SaitoSignature,
21}
22impl Display for Hop {
23 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
24 writeln!(f, "Hop : {{")?;
25 writeln!(f, " from : {}", self.from.to_base58())?;
26 writeln!(f, " to : {}", self.to.to_base58())?;
27 writeln!(f, " sig: {}", self.sig.to_hex())?;
28 writeln!(f, "}}")
29 }
30}
31impl Default for Hop {
32 fn default() -> Self {
33 Hop {
34 from: [0; 33],
35 to: [0; 33],
36 sig: [0; 64],
37 }
38 }
39}
40
41impl Hop {
42 pub fn generate(
43 my_private_key: &SaitoPrivateKey,
44 my_public_key: &SaitoPublicKey,
45 to_public_key: &SaitoPublicKey,
46 tx: &Transaction,
47 ) -> Hop {
48 let mut hop = Hop::default();
49
50 let buffer: Vec<u8> = [tx.signature.as_slice(), to_public_key.as_slice()].concat();
52
53 hop.from = my_public_key.clone();
54 hop.to = to_public_key.clone();
55 hop.sig = sign(buffer.as_slice(), &my_private_key);
56
57 hop
58 }
59
60 pub fn deserialize_from_net(bytes: &Vec<u8>) -> Result<Hop, Error> {
61 if bytes.len() != HOP_SIZE {
62 return Err(Error::from(ErrorKind::InvalidInput));
63 }
64 let from: SaitoPublicKey = bytes[..33]
65 .try_into()
66 .or(Err(Error::from(ErrorKind::InvalidData)))?;
67 let to: SaitoPublicKey = bytes[33..66]
68 .try_into()
69 .or(Err(Error::from(ErrorKind::InvalidData)))?;
70 let sig: SaitoSignature = bytes[66..130]
71 .try_into()
72 .or(Err(Error::from(ErrorKind::InvalidData)))?;
73
74 let mut hop = Hop::default();
75 hop.from = from;
76 hop.to = to;
77 hop.sig = sig;
78
79 Ok(hop)
80 }
81
82 pub fn serialize_for_net(&self) -> Vec<u8> {
83 let vbytes: Vec<u8> = [
84 self.from.as_slice(),
85 self.to.as_slice(),
86 self.sig.as_slice(),
87 ]
88 .concat();
89 vbytes
93 }
94}
95
96#[cfg(test)]
97mod tests {
98 use std::sync::Arc;
99
100 use tokio::sync::RwLock;
101
102 use crate::core::consensus::hop::Hop;
103 use crate::core::consensus::wallet::Wallet;
104 use crate::core::defs::SaitoPublicKey;
105 use crate::core::util::crypto::{generate_keys, verify};
106
107 use super::*;
108
109 #[test]
110 fn hop_new_test() {
111 let hop = Hop::default();
112 assert_eq!(hop.from, [0; 33]);
113 assert_eq!(hop.to, [0; 33]);
114 assert_eq!(hop.sig, [0; 64]);
115 }
116
117 #[tokio::test]
118 async fn generate_test() {
119 let keys = generate_keys();
120 let wallet = Arc::new(RwLock::new(Wallet::new(keys.1, keys.0)));
121 let sender_public_key: SaitoPublicKey;
122
123 {
124 let wallet = wallet.read().await;
125
126 sender_public_key = wallet.public_key;
127 }
128
129 let tx = Transaction::default();
130 let (receiver_public_key, _receiver_private_key) = generate_keys();
131
132 let wallet = wallet.read().await;
133 let hop = Hop::generate(
134 &wallet.private_key,
135 &wallet.public_key,
136 &receiver_public_key,
137 &tx,
138 );
139
140 assert_eq!(hop.from, sender_public_key);
141 assert_eq!(hop.to, receiver_public_key);
142 }
143
144 #[tokio::test]
145 async fn serialize_and_deserialize_test() {
146 let keys = generate_keys();
147 let wallet = Arc::new(RwLock::new(Wallet::new(keys.1, keys.0)));
148 let mut tx = Transaction::default();
149 {
150 let wallet = wallet.read().await;
151 tx.sign(&wallet.private_key);
152 }
153 let (receiver_public_key, _receiver_private_key) = generate_keys();
154
155 let wallet = wallet.read().await;
156 let hop = Hop::generate(
157 &wallet.private_key,
158 &wallet.public_key,
159 &receiver_public_key,
160 &tx,
161 );
162
163 let hop2 = Hop::deserialize_from_net(&hop.serialize_for_net()).unwrap();
164
165 assert_eq!(hop.from, hop2.from);
166 assert_eq!(hop.to, hop2.to);
167 assert_eq!(hop.sig, hop2.sig);
168
169 let mut buffer = vec![];
170 buffer.extend(tx.signature.to_vec());
171 buffer.extend(hop.to.to_vec());
172 let result = verify(buffer.as_slice(), &hop.sig, &hop.from);
173 assert!(result);
174
175 let result = Hop::deserialize_from_net(&vec![]);
176 assert!(result.is_err());
177 }
178}