openmina_node_common/service/
p2p.rs1use std::collections::BTreeMap;
2
3use node::{
4 core::channels::mpsc,
5 event_source::Event,
6 p2p::{
7 connection::outgoing::P2pConnectionOutgoingInitOpts,
8 identity::{EncryptableType, PublicKey},
9 webrtc::ConnectionAuth,
10 PeerId,
11 },
12};
13use rand::prelude::*;
14#[cfg(feature = "p2p-libp2p")]
15use sha3::digest::XofReader;
16
17pub use node::p2p::{service::*, service_impl::*};
18
19use crate::NodeService;
20
21impl webrtc::P2pServiceWebrtc for NodeService {
22 type Event = Event;
23
24 fn random_pick(
25 &mut self,
26 list: &[P2pConnectionOutgoingInitOpts],
27 ) -> Option<P2pConnectionOutgoingInitOpts> {
28 list.choose(&mut self.rng).cloned()
29 }
30
31 fn event_sender(&self) -> &mpsc::UnboundedSender<Self::Event> {
32 self.event_sender()
33 }
34
35 fn cmd_sender(&self) -> &mpsc::TrackedUnboundedSender<webrtc::Cmd> {
36 &self.p2p.webrtc.cmd_sender
37 }
38
39 fn peers(&mut self) -> &mut BTreeMap<PeerId, webrtc::PeerState> {
40 &mut self.p2p.webrtc.peers
41 }
42
43 fn encrypt<T: EncryptableType>(
44 &mut self,
45 other_pk: &PublicKey,
46 message: &T,
47 ) -> Result<T::Encrypted, Box<dyn std::error::Error>> {
48 let rng = &mut self.rng;
49 self.p2p.sec_key.encrypt(other_pk, rng, message)
50 }
51
52 fn decrypt<T: EncryptableType>(
53 &mut self,
54 other_pk: &PublicKey,
55 encrypted: &T::Encrypted,
56 ) -> Result<T, Box<dyn std::error::Error>> {
57 self.p2p.sec_key.decrypt(other_pk, encrypted)
58 }
59
60 #[cfg(not(feature = "p2p-webrtc"))]
61 fn auth_encrypt_and_send(
62 &mut self,
63 peer_id: PeerId,
64 other_pub_key: &PublicKey,
65 auth: ConnectionAuth,
66 ) {
67 let _ = (peer_id, other_pub_key, auth);
68 }
69
70 #[cfg(feature = "p2p-webrtc")]
71 fn auth_encrypt_and_send(
72 &mut self,
73 peer_id: PeerId,
74 other_pub_key: &PublicKey,
75 auth: ConnectionAuth,
76 ) {
77 let encrypted = auth.encrypt(&self.p2p.sec_key, other_pub_key, &mut self.rng);
78 Self::auth_send(self, peer_id, other_pub_key, encrypted);
79 }
80
81 fn auth_decrypt(
82 &mut self,
83 other_pub_key: &PublicKey,
84 auth: node::p2p::webrtc::ConnectionAuthEncrypted,
85 ) -> Option<ConnectionAuth> {
86 auth.decrypt(&self.p2p.sec_key, other_pub_key)
87 }
88}
89
90impl webrtc_with_libp2p::P2pServiceWebrtcWithLibp2p for NodeService {
91 #[cfg(feature = "p2p-libp2p")]
92 fn mio(&mut self) -> &mut mio::MioService {
93 &mut self.p2p.mio
94 }
95
96 fn connections(&self) -> std::collections::BTreeSet<PeerId> {
97 self.p2p.webrtc.peers.keys().copied().collect()
98 }
99}
100
101#[cfg(feature = "p2p-libp2p")]
102impl P2pCryptoService for NodeService {
103 fn generate_random_nonce(&mut self) -> [u8; 24] {
104 self.rng.gen()
105 }
106
107 fn ephemeral_sk(&mut self) -> [u8; 32] {
108 let mut r = [0; 32];
109 self.rng_ephemeral.read(&mut r);
110 r
111 }
112
113 fn static_sk(&mut self) -> [u8; 32] {
114 let mut r = [0; 32];
115 self.rng_static.read(&mut r);
116 r
117 }
118
119 fn sign_key(&mut self, key: &[u8; 32]) -> Vec<u8> {
120 let msg = [b"noise-libp2p-static-key:", key.as_slice()].concat();
122 let sig = self.p2p.sec_key.sign(&msg);
123 let libp2p_sec_key = libp2p_identity::Keypair::try_from(self.p2p.sec_key.clone()).unwrap();
124
125 let mut payload = vec![];
126 payload.extend_from_slice(b"\x0a\x24");
127 payload.extend_from_slice(&libp2p_sec_key.public().encode_protobuf());
128 payload.extend_from_slice(b"\x12\x40");
129 payload.extend_from_slice(&sig.to_bytes());
130 payload
131 }
132
133 fn sign_publication(&mut self, publication: &[u8]) -> Vec<u8> {
134 self.p2p
135 .sec_key
136 .libp2p_pubsub_sign(publication)
137 .to_bytes()
138 .to_vec()
139 }
140
141 fn verify_publication(
142 &mut self,
143 pk: &libp2p_identity::PublicKey,
144 publication: &[u8],
145 sig: &[u8],
146 ) -> bool {
147 let msg: Vec<u8> = [b"libp2p-pubsub:", publication].concat();
148 pk.verify(&msg, sig)
149 }
150}