1#![deny(
19 clippy::expect_used,
20 clippy::unwrap_used,
21 missing_debug_implementations,
22 missing_copy_implementations,
23 trivial_casts,
24 trivial_numeric_casts,
25 unsafe_code,
26 unstable_features,
27 unused_import_braces
28)]
29
30pub(crate) use dubp_common::{
31 crypto::{
32 bases::b58::ToBase58,
33 keys::{
34 ed25519::{PublicKey, Signature},
35 PublicKey as _, Signature as _,
36 },
37 },
38 prelude::*,
39};
40pub(crate) use serde::{Deserialize, Serialize};
41pub(crate) use smallvec::SmallVec;
42
43#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
44pub struct PeerV10 {
45 pub currency: String,
46 pub pubkey: PublicKey,
47 pub blockstamp: Blockstamp,
48 pub endpoints: SmallVec<[String; 4]>,
49 pub signature: Signature,
50}
51
52impl PeerV10 {
53 pub fn to_raw_string(&self) -> String {
54 format!(
55 "{}{}\n",
56 self.to_raw_unsigned_string(),
57 self.signature.to_base64(),
58 )
59 }
60 fn to_raw_unsigned_string(&self) -> String {
61 format!(
62 "Version: 10\nType: Peer\nCurrency: {}\nPublicKey: {}\nBlock: {}\nEndpoints:\n{}\n",
63 self.currency,
64 self.pubkey.to_base58(),
65 self.blockstamp,
66 self.endpoints.join("\n"),
67 )
68 }
69 pub fn verify_sig(&self) -> Result<(), dubp_common::crypto::keys::SigError> {
70 self.pubkey
71 .verify(self.to_raw_unsigned_string().as_bytes(), &self.signature)
72 }
73}
74
75#[cfg(test)]
76mod tests {
77 use super::*;
78 use smallvec::smallvec;
79 use std::str::FromStr;
80 use unwrap::unwrap;
81
82 #[test]
83 fn test_peer_sig() {
84 let peer = PeerV10 {
85 currency: "g1".to_owned(),
86 pubkey: unwrap!(PublicKey::from_base58("8iVdpXqFLCxGyPqgVx5YbFSkmWKkceXveRd2yvBKeARL")),
87 blockstamp: unwrap!(Blockstamp::from_str("423354-00000033A87209DC21BD643088ED8AD52464A80C04BE3F8FBFA4291A9999BE50")),
88 endpoints: smallvec![
89 "BMAS g1.duniter.org 443".to_owned(),
90 "BASIC_MERKLED_API 91.121.157.13 10901".to_owned(),
91 "WS2P e66254bf g1.duniter.org 443 ws2p".to_owned()
92 ],
93 signature: unwrap!(Signature::from_base64("qr6Cnr/Qsgw/clbt0LbdkaFaUwhdgBJw5Fzpn8EhI9zM5/rGbVF6kqiB5pRJxf17XtI45qQ7H7SBbl8X2kAtCA==")),
94 };
95
96 let peer_raw = peer.to_raw_unsigned_string();
97 assert_eq!(
98 &peer_raw,
99 "Version: 10\nType: Peer\nCurrency: g1\nPublicKey: 8iVdpXqFLCxGyPqgVx5YbFSkmWKkceXveRd2yvBKeARL\nBlock: 423354-00000033A87209DC21BD643088ED8AD52464A80C04BE3F8FBFA4291A9999BE50\nEndpoints:\nBMAS g1.duniter.org 443\nBASIC_MERKLED_API 91.121.157.13 10901\nWS2P e66254bf g1.duniter.org 443 ws2p\n",
100 );
101 assert!(peer.verify_sig().is_ok());
102 }
103}