Skip to content

Commit 8b9474b

Browse files
authored
Merge pull request #1042 from openmina/feat/webrtc-sniffer
WebRTC sniffer
2 parents 872e1e3 + 787fa30 commit 8b9474b

File tree

22 files changed

+1224
-57
lines changed

22 files changed

+1224
-57
lines changed

Cargo.lock

Lines changed: 164 additions & 31 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ members = [
3131
"tools/fuzzing",
3232
"tools/archive-breadcrumb-compare",
3333
"tools/heartbeats-processor",
34+
"tools/webrtc-sniffer",
35+
3436
"producer-dashboard",
3537

3638
"fuzzer",
@@ -54,8 +56,8 @@ mina-curves = { git = "https://github.com/openmina/proof-systems", rev = "dec49a
5456
# UNCOMMENTED_IN_CI mina-curves = { git = "https://github.com/openmina/proof-systems", rev = "dec49a9", features = [ "32x9" ] }
5557
o1-utils = { git = "https://github.com/openmina/proof-systems", rev = "dec49a9" }
5658
kimchi = { git = "https://github.com/openmina/proof-systems", rev = "dec49a9" }
57-
mina-poseidon = {git = "https://github.com/openmina/proof-systems", rev = "dec49a9" }
58-
poly-commitment = {git = "https://github.com/openmina/proof-systems", rev = "dec49a9" }
59+
mina-poseidon = { git = "https://github.com/openmina/proof-systems", rev = "dec49a9" }
60+
poly-commitment = { git = "https://github.com/openmina/proof-systems", rev = "dec49a9" }
5961

6062
libp2p = { git = "https://github.com/openmina/rust-libp2p", rev = "5c44c7d9", default-features = false }
6163
vrf = { path = "vrf" }
@@ -90,9 +92,9 @@ incremental = false
9092
codegen-units = 1
9193

9294
[patch.crates-io]
93-
ark-ff = { git = "https://github.com/openmina/algebra", rev = "aea157a" } # branch: fix-openmina-webnode
94-
ark-ec = { git = "https://github.com/openmina/algebra", rev = "aea157a" } # branch: fix-openmina-webnode
95-
ark-poly = { git = "https://github.com/openmina/algebra", rev = "aea157a" } # branch: fix-openmina-webnode
95+
ark-ff = { git = "https://github.com/openmina/algebra", rev = "aea157a" } # branch: fix-openmina-webnode
96+
ark-ec = { git = "https://github.com/openmina/algebra", rev = "aea157a" } # branch: fix-openmina-webnode
97+
ark-poly = { git = "https://github.com/openmina/algebra", rev = "aea157a" } # branch: fix-openmina-webnode
9698
ark-serialize = { git = "https://github.com/openmina/algebra", rev = "aea157a" } # branch: fix-openmina-webnode
9799

98100
num-bigint = { git = "https://github.com/openmina/num-bigint", rev = "8bb5ee4" } # branch: on-stack

cli/src/commands/node/mod.rs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,9 @@ pub struct Node {
171171
/// - OPENMINA_AWS_BUCKET_NAME
172172
#[arg(long, env)]
173173
pub archive_aws_storage: bool,
174+
175+
#[arg(long, env)]
176+
pub rng_seed: Option<String>,
174177
}
175178

176179
impl Node {
@@ -216,7 +219,27 @@ impl Node {
216219
node::config::DEVNET_CONFIG.clone(),
217220
),
218221
};
219-
let mut node_builder: NodeBuilder = NodeBuilder::new(None, daemon_conf, genesis_conf);
222+
223+
let custom_rng_seed = match self.rng_seed {
224+
None => None,
225+
Some(v) => match hex::decode(v)
226+
.map_err(anyhow::Error::from)
227+
.and_then(|bytes| {
228+
<[u8; 32]>::try_from(bytes.as_slice()).map_err(anyhow::Error::from)
229+
}) {
230+
Ok(v) => Some(v),
231+
Err(err) => {
232+
node::core::error!(
233+
node::core::log::system_time();
234+
summary = "bad rng seed",
235+
err = err.to_string(),
236+
);
237+
return Err(err);
238+
}
239+
},
240+
};
241+
let mut node_builder: NodeBuilder =
242+
NodeBuilder::new(custom_rng_seed, daemon_conf, genesis_conf);
220243

221244
// let genesis_config = match self.config {
222245
// Some(config_path) => GenesisConfig::DaemonJsonFile(config_path).into(),

node/common/src/service/builder.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ impl NodeServiceCommonBuilder {
112112
self.p2p = Some(<NodeService as P2pServiceWebrtcWithLibp2p>::init(
113113
secret_key.clone(),
114114
task_spawner,
115+
self.rng_seed,
115116
));
116117
self
117118
}

node/testing/src/main.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ pub struct CommandScenariosGenerate {
4040
pub name: Option<String>,
4141
#[arg(long, short)]
4242
pub use_debugger: bool,
43+
#[arg(long, short)]
44+
pub webrtc: bool,
4345
}
4446

4547
/// Run scenario located at `res/scenarios`.
@@ -83,6 +85,9 @@ impl Command {
8385
if cmd.use_debugger {
8486
config.use_debugger();
8587
}
88+
if cmd.webrtc {
89+
config.set_all_rust_to_rust_use_webrtc();
90+
}
8691
Ok(scenario.run_only_from_scratch(config))
8792
};
8893
let fut = async move {

node/testing/src/scenarios/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ impl Scenarios {
131131
Self::SimulationSmall(_) => true,
132132
Self::SimulationSmallForeverRealTime(_) => true,
133133
Self::MultiNodePubsubPropagateBlock(_) => true, // in progress
134-
Self::P2pSignaling(_) => cfg!(feature = "p2p-webrtc"),
134+
Self::P2pSignaling(_) => !cfg!(feature = "p2p-webrtc"),
135135
_ => false,
136136
}
137137
}

p2p/Cargo.toml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ cfg-if = "1.0.0"
2424
url = "2.3.1"
2525
multihash = "0.18.1"
2626
sha2 = "0.10.6"
27-
ed25519-dalek = { version = "2.1.1", features = ["serde"] }
27+
ed25519-dalek = { version = "2.1.1", features = ["serde", "pem"] }
2828
x25519-dalek = { version = "2.0.1", features = ["static_secrets"] }
2929
aes-gcm = "0.10.3"
3030
faster-stun = { version = "1.0.1", optional = true }
@@ -80,10 +80,11 @@ p2p-testing = { path = "testing" }
8080
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
8181
redux = { workspace = true, features = ["serializable_callbacks"] }
8282
tokio = { version = "1.26", features = ["rt"] }
83-
webrtc = { git = "https://github.com/openmina/webrtc.git", rev = "e8705db39af1b198b324a5db6ff57fb213ba75e9", optional = true }
83+
webrtc = { git = "https://github.com/openmina/webrtc.git", rev = "aeaa62682b97f6984627bedd6e6811fe17af18eb", optional = true }
8484
datachannel = { git = "https://github.com/openmina/datachannel-rs.git", rev = "1bfb064d0ff3e54a93ae0288409902aab8d102d3", optional = true, features = [
8585
"vendored",
8686
] }
87+
rcgen = { version = "0.13", features = ["pem", "x509-parser"], optional = true }
8788
reqwest = { version = "0.11", features = ["json"] }
8889
mio = { version = "0.8.11", features = ["os-poll", "net"] }
8990
libc = { version = "0.2.151" }
@@ -119,7 +120,7 @@ getrandom = { version = "0.2", features = ["js"] }
119120
[features]
120121
serializable_callbacks = []
121122
p2p-webrtc = ["p2p-webrtc-rs"]
122-
p2p-webrtc-rs = ["webrtc"]
123+
p2p-webrtc-rs = ["webrtc", "rcgen"]
123124
p2p-webrtc-cpp = ["datachannel"]
124125
p2p-libp2p = ["fuzzing", "dep:reqwest", "dep:faster-stun"]
125126
fuzzing = ["openmina-fuzzer", "openmina-core/fuzzing"]

p2p/src/identity/secret_key.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
use std::{fmt, path::Path, str::FromStr};
22

33
use base64::Engine;
4-
use ed25519_dalek::{ed25519::signature::SignerMut, SigningKey as Ed25519SecretKey};
4+
use ed25519_dalek::{
5+
ed25519::signature::SignerMut, pkcs8::EncodePrivateKey as _, SigningKey as Ed25519SecretKey,
6+
};
57
use openmina_core::{EncryptedSecretKey, EncryptedSecretKeyFile, EncryptionError};
68
use rand::{CryptoRng, Rng};
79
use serde::{Deserialize, Serialize};
10+
use zeroize::Zeroizing;
811

912
use super::{PublicKey, Signature};
1013

@@ -53,6 +56,12 @@ impl SecretKey {
5356
self.0.to_scalar_bytes().into()
5457
}
5558

59+
pub fn to_pem(&self) -> Zeroizing<String> {
60+
self.0
61+
.to_pkcs8_pem(Default::default())
62+
.expect("must be valid key")
63+
}
64+
5665
pub fn from_encrypted_file(
5766
path: impl AsRef<Path>,
5867
password: &str,

p2p/src/service_impl/mod.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,11 @@ pub mod webrtc {
5151

5252
fn peers(&mut self) -> &mut BTreeMap<PeerId, PeerState>;
5353

54-
fn init<S: TaskSpawner>(_secret_key: SecretKey, _spawner: S) -> P2pServiceCtx {
54+
fn init<S: TaskSpawner>(
55+
_secret_key: SecretKey,
56+
_spawner: S,
57+
_rng_seed: [u8; 32],
58+
) -> P2pServiceCtx {
5559
let (cmd_sender, _) = mpsc::unbounded_channel();
5660
P2pServiceCtx {
5761
cmd_sender,

p2p/src/service_impl/webrtc/mod.rs

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -33,22 +33,22 @@ use crate::{
3333
#[cfg(all(not(target_arch = "wasm32"), feature = "p2p-webrtc-rs"))]
3434
mod imports {
3535
pub use super::webrtc_rs::{
36-
build_api, webrtc_signal_send, Api, RTCChannel, RTCConnection, RTCConnectionState,
37-
RTCSignalingError,
36+
build_api, certificate_from_pem_key, webrtc_signal_send, Api, RTCCertificate, RTCChannel,
37+
RTCConnection, RTCConnectionState, RTCSignalingError,
3838
};
3939
}
4040
#[cfg(all(not(target_arch = "wasm32"), feature = "p2p-webrtc-cpp"))]
4141
mod imports {
4242
pub use super::webrtc_cpp::{
43-
build_api, webrtc_signal_send, Api, RTCChannel, RTCConnection, RTCConnectionState,
44-
RTCSignalingError,
43+
build_api, certificate_from_pem_key, webrtc_signal_send, Api, RTCCertificate, RTCChannel,
44+
RTCConnection, RTCConnectionState, RTCSignalingError,
4545
};
4646
}
4747
#[cfg(target_arch = "wasm32")]
4848
mod imports {
4949
pub use super::web::{
50-
build_api, webrtc_signal_send, Api, RTCChannel, RTCConnection, RTCConnectionState,
51-
RTCSignalingError,
50+
build_api, certificate_from_pem_key, webrtc_signal_send, Api, RTCCertificate, RTCChannel,
51+
RTCConnection, RTCConnectionState, RTCSignalingError,
5252
};
5353
}
5454

@@ -140,7 +140,8 @@ pub type OnConnectionStateChangeHdlrFn = Box<
140140

141141
pub struct RTCConfig {
142142
pub ice_servers: RTCConfigIceServers,
143-
// TODO(binier): certificate
143+
pub certificate: RTCCertificate,
144+
pub seed: [u8; 32],
144145
}
145146

146147
#[derive(Serialize)]
@@ -223,7 +224,14 @@ async fn wait_for_ice_gathering_complete(pc: &mut RTCConnection) {
223224
}
224225
}
225226

226-
async fn peer_start(api: Api, args: PeerAddArgs, abort: Aborted, closed: mpsc::Sender<()>) {
227+
async fn peer_start(
228+
api: Api,
229+
args: PeerAddArgs,
230+
abort: Aborted,
231+
closed: mpsc::Sender<()>,
232+
certificate: RTCCertificate,
233+
rng_seed: [u8; 32],
234+
) {
227235
let PeerAddArgs {
228236
peer_id,
229237
kind,
@@ -234,6 +242,8 @@ async fn peer_start(api: Api, args: PeerAddArgs, abort: Aborted, closed: mpsc::S
234242

235243
let config = RTCConfig {
236244
ice_servers: Default::default(),
245+
certificate,
246+
seed: rng_seed,
237247
};
238248
let fut = async {
239249
let mut pc = RTCConnection::create(&api, config).await?;
@@ -723,11 +733,15 @@ pub trait P2pServiceWebrtc: redux::Service {
723733

724734
fn peers(&mut self) -> &mut BTreeMap<PeerId, PeerState>;
725735

726-
fn init<S: TaskSpawner>(secret_key: SecretKey, spawner: S) -> P2pServiceCtx {
736+
fn init<S: TaskSpawner>(
737+
secret_key: SecretKey,
738+
spawner: S,
739+
rng_seed: [u8; 32],
740+
) -> P2pServiceCtx {
727741
const MAX_PEERS: usize = 500;
728742
let (cmd_sender, mut cmd_receiver) = mpsc::unbounded_channel();
729743

730-
let _ = secret_key;
744+
let certificate = certificate_from_pem_key(secret_key.to_pem().as_str());
731745

732746
spawner.spawn_main("webrtc", async move {
733747
#[allow(clippy::all)]
@@ -741,6 +755,7 @@ pub trait P2pServiceWebrtc: redux::Service {
741755
let conn_permits = conn_permits.clone();
742756
let peer_id = args.peer_id;
743757
let event_sender = args.event_sender.clone();
758+
let certificate = certificate.clone();
744759
spawn_local(async move {
745760
let Ok(_permit) = conn_permits.try_acquire() else {
746761
// state machine shouldn't allow this to happen.
@@ -755,8 +770,9 @@ pub trait P2pServiceWebrtc: redux::Service {
755770
event_sender_clone(P2pConnectionEvent::Closed(peer_id).into());
756771
});
757772
tokio::select! {
758-
_ = peer_start(api, args, aborted.clone(), closed_tx.clone()) => {}
759-
_ = aborted.wait() => {}
773+
_ = peer_start(api, args, aborted.clone(), closed_tx.clone(), certificate, rng_seed) => {}
774+
_ = aborted.wait() => {
775+
}
760776
}
761777

762778
// delay dropping permit to give some time for cleanup.

0 commit comments

Comments
 (0)