Skip to content

Commit 33dd25a

Browse files
committed
feat: improve peerinfo example
1 parent 6538866 commit 33dd25a

4 files changed

Lines changed: 80 additions & 44 deletions

File tree

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,6 @@ target/
1717

1818
# Code coverage output
1919
lcov.info
20+
21+
# Example data directory
22+
.charon-example*

Cargo.lock

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

crates/peerinfo/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ tokio.workspace = true
3232
tracing-subscriber.workspace = true
3333
hex.workspace = true
3434
vise-exporter.workspace = true
35+
charon-eth2.workspace = true
36+
k256.workspace = true
3537

3638
[lints]
3739
workspace = true

crates/peerinfo/examples/peerinfo.rs

Lines changed: 73 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,24 @@
1313
//! Terminal 1: `cargo run --example peerinfo -p charon-peerinfo -- --port 4001`
1414
//! Terminal 2: `cargo run --example peerinfo -p charon-peerinfo -- --port 4002`
1515
#![allow(missing_docs)]
16-
use std::{net::SocketAddr, time::Duration};
16+
use std::{
17+
net::{Ipv4Addr, SocketAddr},
18+
path::PathBuf,
19+
time::Duration,
20+
};
1721

22+
use charon_p2p::{
23+
config::P2PConfig,
24+
k1,
25+
p2p::{Node, NodeType},
26+
};
1827
use charon_peerinfo::{Behaviour, Config, Event, LocalPeerInfo};
1928
use clap::Parser;
2029
use libp2p::{
21-
Multiaddr, Swarm, SwarmBuilder,
30+
Multiaddr, Swarm,
2231
futures::StreamExt,
23-
identify, mdns, noise, ping,
32+
identify, mdns, ping, relay,
2433
swarm::{NetworkBehaviour, SwarmEvent},
25-
tcp, yamux,
2634
};
2735
use tokio::signal;
2836
use tracing_subscriber::EnvFilter;
@@ -48,6 +56,14 @@ pub struct Args {
4856
/// Peer info exchange interval in seconds
4957
#[arg(short, long, default_value = "5")]
5058
pub interval: u64,
59+
60+
/// Data directory for storing the private key
61+
#[arg(long, default_value = ".charon-example")]
62+
pub data_dir: PathBuf,
63+
64+
/// Metrics port to bind to
65+
#[arg(long, default_value = "9465")]
66+
pub metrics_port: u16,
5167
}
5268

5369
/// Combined behaviour with peerinfo, identify, ping, and mdns
@@ -56,46 +72,12 @@ pub struct CombinedBehaviour {
5672
pub peer_info: Behaviour,
5773
pub identify: identify::Behaviour,
5874
pub ping: ping::Behaviour,
75+
pub relay: relay::client::Behaviour,
5976
pub mdns: mdns::tokio::Behaviour,
6077
}
6178

6279
pub type CombinedEvent = CombinedBehaviourEvent;
6380

64-
fn build_swarm(
65-
peerinfo_config: LocalPeerInfo,
66-
interval: Duration,
67-
) -> anyhow::Result<Swarm<CombinedBehaviour>> {
68-
let swarm = SwarmBuilder::with_new_identity()
69-
.with_tokio()
70-
.with_tcp(
71-
tcp::Config::default(),
72-
noise::Config::new,
73-
yamux::Config::default,
74-
)?
75-
.with_behaviour(|key| {
76-
Ok(CombinedBehaviour {
77-
peer_info: Behaviour::new(Config::new(peerinfo_config).with_interval(interval)),
78-
identify: identify::Behaviour::new(identify::Config::new(
79-
"/peerinfo-example/1.0.0".to_string(),
80-
key.public(),
81-
)),
82-
ping: ping::Behaviour::new(
83-
ping::Config::new()
84-
.with_interval(Duration::from_secs(15))
85-
.with_timeout(Duration::from_secs(10)),
86-
),
87-
mdns: mdns::tokio::Behaviour::new(
88-
mdns::Config::default(),
89-
key.public().to_peer_id(),
90-
)?,
91-
})
92-
})?
93-
.with_swarm_config(|cfg| cfg.with_idle_connection_timeout(Duration::from_secs(300)))
94-
.build();
95-
96-
Ok(swarm)
97-
}
98-
9981
fn handle_event(event: SwarmEvent<CombinedEvent>, swarm: &mut Swarm<CombinedBehaviour>) {
10082
match event {
10183
SwarmEvent::NewListenAddr { address, .. } => {
@@ -114,7 +96,7 @@ fn handle_event(event: SwarmEvent<CombinedEvent>, swarm: &mut Swarm<CombinedBeha
11496
}
11597
SwarmEvent::Behaviour(CombinedEvent::PeerInfo(Event::Received { peer, info, .. })) => {
11698
tracing::info!(
117-
"📥 Received PeerInfo from {peer}:\n\
99+
"Received PeerInfo from {peer}:\n\
118100
│ Version: {}\n\
119101
│ Git Hash: {}\n\
120102
│ Nickname: {}\n\
@@ -174,8 +156,10 @@ async fn main() -> anyhow::Result<()> {
174156
.with_env_filter(EnvFilter::from_default_env().add_directive("debug".parse()?))
175157
.init();
176158

159+
let args = Args::parse();
160+
177161
// Run the metrics exporter
178-
let bind_address = SocketAddr::from(([0, 0, 0, 0], 9465));
162+
let bind_address = SocketAddr::from(([0, 0, 0, 0], args.metrics_port));
179163

180164
let exporter = MetricsExporter::default()
181165
.bind(bind_address)
@@ -188,18 +172,63 @@ async fn main() -> anyhow::Result<()> {
188172
.expect("Failed to start metrics exporter");
189173
});
190174

191-
let args = Args::parse();
175+
// Load existing key or create a new one
176+
let key = match k1::load_priv_key(&args.data_dir) {
177+
Ok(key) => {
178+
tracing::info!(
179+
"Loaded existing private key from {}",
180+
args.data_dir.display()
181+
);
182+
key
183+
}
184+
Err(_) => {
185+
tracing::info!("Creating new private key in {}", args.data_dir.display());
186+
k1::new_saved_priv_key(&args.data_dir)?
187+
}
188+
};
189+
let enr = charon_eth2::enr::Record::new(
190+
key.clone(),
191+
vec![
192+
charon_eth2::enr::with_ip_impl(Ipv4Addr::from([0, 0, 0, 0])),
193+
charon_eth2::enr::with_tcp_impl(args.port),
194+
charon_eth2::enr::with_udp_impl(args.port),
195+
],
196+
)?;
197+
198+
tracing::info!("ENR: {}", enr);
192199

193200
// Create local peer info
194201
let local_info = LocalPeerInfo::new(
195202
"v1.0.0", // charon_version
196-
vec![0xDE, 0xAD, 0xBE, 0xEF], // lock_hash (example)
203+
vec![0x00, 0x00, 0x00, 0x00], // lock_hash (example)
197204
"abc1234", // git_hash
198205
false, // builder_api_enabled
199206
&args.nickname, // nickname
200207
);
201208

202-
let mut swarm = build_swarm(local_info, Duration::from_secs(args.interval))?;
209+
let Node { mut swarm } = Node::new(
210+
P2PConfig::default(),
211+
key,
212+
false,
213+
NodeType::TCP,
214+
|key, relay_client| CombinedBehaviour {
215+
peer_info: Behaviour::new(
216+
Config::new(local_info.clone()).with_interval(Duration::from_secs(args.interval)),
217+
),
218+
identify: identify::Behaviour::new(identify::Config::new(
219+
"/peerinfo-example/1.0.0".to_string(),
220+
key.public(),
221+
)),
222+
ping: ping::Behaviour::new(
223+
ping::Config::new()
224+
.with_interval(Duration::from_secs(15))
225+
.with_timeout(Duration::from_secs(10)),
226+
),
227+
mdns: mdns::tokio::Behaviour::new(mdns::Config::default(), key.public().to_peer_id())
228+
.expect("Failed to create mDNS behaviour"),
229+
relay: relay_client,
230+
},
231+
)?;
203232

204233
let local_peer_id = *swarm.local_peer_id();
205234
tracing::info!("Local peer id: {local_peer_id}");

0 commit comments

Comments
 (0)