Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
913b56b
feat: add tracing
varex83 Dec 5, 2025
51a691f
fix: linting, cargo-deny
varex83 Dec 5, 2025
e3ece2e
Merge remote-tracking branch 'origin/main' into bohdan/tracing
varex83 Dec 8, 2025
85a9b9c
feat: add p2p config
varex83 Dec 8, 2025
65d5ae7
fix: remove comment
varex83 Dec 9, 2025
a312796
Merge remote-tracking branch 'origin/main' into bohdan/p2p-config
varex83 Dec 9, 2025
1cc2a29
feat: add p2p metrics
varex83 Dec 9, 2025
c432d86
fix: rename label in example
varex83 Dec 9, 2025
aeaa971
fix: linting
varex83 Dec 9, 2025
65d3a49
Merge branch 'bohdan/p2p-config' into bohdan/p2p-create-node
varex83 Dec 10, 2025
a82bbc7
feat: [wip] add relay/ping
varex83 Dec 18, 2025
a2fe791
feat: add behaviours module, add relay client support
varex83 Dec 22, 2025
30a550b
fix: linter warnings
varex83 Dec 22, 2025
df9fdce
Merge remote-tracking branch 'origin/main' into bohdan/p2p-create-node
varex83 Dec 22, 2025
ddbb57b
fix: remove wildcard dependencies
varex83 Dec 22, 2025
3c5d3fe
feat: add connection gater
varex83 Dec 23, 2025
c663f61
fix: linter warnings
varex83 Dec 23, 2025
a244063
fix: linter warnings
varex83 Dec 23, 2025
adfc1ef
feat: create behaviour builder
varex83 Dec 24, 2025
2ed4394
Initial `version` module
emlautarom1 Dec 24, 2025
6bd9fa7
Port version tests
emlautarom1 Dec 24, 2025
f3b599e
Add `FromStr`
emlautarom1 Dec 24, 2025
634effb
Port internal version tests
emlautarom1 Dec 24, 2025
8ed91a8
Add support for build-time data
emlautarom1 Dec 24, 2025
2c919d0
Apply Clippy suggestions
emlautarom1 Dec 24, 2025
37156ef
Apply Copilot suggestion
emlautarom1 Dec 26, 2025
31c4e27
feat: add relay server functionality
varex83 Dec 29, 2025
152fbcf
chore: fix linter, polish code
varex83 Dec 29, 2025
529d794
fix: cargo deny dependency issue
varex83 Dec 29, 2025
1eb752e
chore: add docs
varex83 Dec 30, 2025
7b72369
refactor: move relay-server to a different crate
varex83 Dec 30, 2025
ee147d0
feat: add peerinfo (mvp)
varex83 Jan 5, 2026
351db0e
fix: remove non-relevant comment
varex83 Jan 5, 2026
91b7e10
feat: add peerinfo metrics
varex83 Jan 5, 2026
a556892
feat: add const metrics
varex83 Jan 5, 2026
733cc31
feat: validation of peerinfo (wip)
varex83 Jan 5, 2026
7f7ab4e
Merge version
varex83 Jan 5, 2026
6538866
feat: add validation for peerinfo
varex83 Jan 7, 2026
33dd25a
feat: improve peerinfo example
varex83 Jan 15, 2026
6e33331
fix: remove comments
varex83 Jan 15, 2026
06bf972
feat: add readme for setting up the mvp
varex83 Jan 15, 2026
efe8608
feat: use fork vise version (temporary)
varex83 Jan 20, 2026
ed7f478
feat: move to official vise repository
varex83 Jan 21, 2026
5892234
feat: add global metrics
varex83 Jan 21, 2026
685f34a
Merge remote-tracking branch 'origin/main' into bohdan/p2p-peerinfo-p…
varex83 Jan 23, 2026
1a5a4a5
fix: remove parking_lot
varex83 Jan 23, 2026
15c1be9
fix: cargo deny
varex83 Jan 23, 2026
f197e20
feat: add support for listen addresses via p2p config, filter_private…
varex83 Jan 26, 2026
feecd26
feat: enable autonat
varex83 Jan 26, 2026
67faa24
Merge remote-tracking branch 'origin/main' into bohdan/finish-p2p
varex83 Feb 2, 2026
49fa0df
feat: add connection logger
varex83 Feb 3, 2026
bd15b68
Merge remote-tracking branch 'origin/main' into bohdan/add-connection…
varex83 Feb 16, 2026
91d2709
refactor: pluto behaviour
varex83 Feb 16, 2026
a7809db
feat: remove dummy connection handler impl in favor of libp2p's
varex83 Feb 16, 2026
f88e753
refactor: add inner behaviour
varex83 Feb 18, 2026
71c25b6
feat: inroduce Stream for Node
varex83 Feb 18, 2026
e0fe0c8
feat: add global context for p2p
varex83 Feb 18, 2026
b8308d4
feat: utilize global context for conn logger
varex83 Feb 19, 2026
f82cc25
feat: add ping metrics, move peerstore updates to conn logger, small …
varex83 Feb 19, 2026
816a678
fix: review comments
varex83 Feb 24, 2026
3070a7a
refactor: rename GlobalConext to P2PContext
varex83 Feb 24, 2026
dca1e47
refactor: builder fn for node behaviour
varex83 Feb 24, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ cancellation = "0.1.0"
chrono = { version = "0.4", features = ["serde"] }
clap = { version = "4.5.53", features = ["derive", "env", "cargo"] }
crossbeam = "0.8.4"
either = "1.13"
futures = "0.3"
futures-timer = "3.0"
backon = "1.6.0"
Expand Down
11 changes: 3 additions & 8 deletions crates/p2p/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ publish.workspace = true
[dependencies]
axum.workspace = true
chrono.workspace = true
either.workspace = true
futures.workspace = true
libp2p.workspace = true
thiserror.workspace = true
k256.workspace = true
Expand All @@ -32,11 +34,4 @@ anyhow.workspace = true
clap.workspace = true

[lints]
workspace = true

[features]
mdns = ["libp2p/mdns"]

[[example]]
name = "p2p"
required-features = ["mdns"]
workspace = true
112 changes: 77 additions & 35 deletions crates/p2p/examples/p2p.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,52 @@
use anyhow::Result;
use clap::Parser;
use k256::elliptic_curve::rand_core::OsRng;
use libp2p::{Multiaddr, futures::StreamExt, identify, multiaddr::Protocol, swarm::SwarmEvent};
use libp2p::{
Multiaddr,
futures::StreamExt,
identify, mdns,
multiaddr::Protocol,
relay,
swarm::{NetworkBehaviour, SwarmEvent},
};
use pluto_eth2util::enr::Record;
use pluto_p2p::{
behaviours::{
pluto::PlutoBehaviourEvent,
pluto_mdns::{PlutoMdnsBehaviour, PlutoMdnsBehaviourEvent},
},
behaviours::pluto::PlutoBehaviourEvent,
config::P2PConfig,
p2p::{Node, NodeType},
};
use tokio::signal;

/// Combined behaviour with relay client and mDNS discovery.
#[derive(NetworkBehaviour)]
#[behaviour(to_swarm = "CombinedBehaviourEvent")]
pub struct CombinedBehaviour {
/// Relay client for NAT traversal.
pub relay: relay::client::Behaviour,
/// mDNS for local peer discovery.
pub mdns: mdns::tokio::Behaviour,
}

/// Events emitted by the combined behaviour.
#[allow(missing_docs)]
#[derive(Debug)]
pub enum CombinedBehaviourEvent {
Relay(relay::client::Event),
Mdns(mdns::Event),
}

impl From<relay::client::Event> for CombinedBehaviourEvent {
fn from(event: relay::client::Event) -> Self {
CombinedBehaviourEvent::Relay(event)
}
}

impl From<mdns::Event> for CombinedBehaviourEvent {
fn from(event: mdns::Event) -> Self {
CombinedBehaviourEvent::Mdns(event)
}
}

/// Command line arguments
#[derive(Debug, Parser)]
pub struct Args {
Expand All @@ -36,49 +70,61 @@ pub struct Args {
#[tokio::main]
async fn main() -> Result<()> {
let key = k256::SecretKey::random(&mut OsRng);
let mut p2p: Node<_> = Node::new(

// Create node with composed behaviour
// No known cluster peers in this example
let known_peers: Vec<libp2p::PeerId> = vec![];
let mut p2p = Node::new(
P2PConfig::default(),
key.clone(),
false,
NodeType::QUIC,
PlutoMdnsBehaviour::new,
false,
known_peers,
|builder, keypair, relay_client| {
builder
.with_user_agent("pluto-p2p-example/1.0.0")
.with_inner(CombinedBehaviour {
relay: relay_client,
mdns: mdns::tokio::Behaviour::new(
mdns::Config::default(),
keypair.public().to_peer_id(),
)
.expect("Failed to create mDNS behaviour"),
})
},
)?;

let args = Args::parse();

let swarm = &mut p2p.swarm;

let enr = Record::new(key.clone(), vec![])?;

if let Some(relay_url) = &args.relay_url {
swarm.dial(relay_url.clone())?;
p2p.dial(relay_url.clone())?;
println!("Dialed relay");
let mut learned_observed_addr = false;
let mut told_relay_observed_addr = false;

loop {
match swarm
match p2p
.next()
.await
.ok_or(anyhow::anyhow!("Swarm event is None"))?
{
SwarmEvent::NewListenAddr { .. } => {}
SwarmEvent::Dialing { .. } => {}
SwarmEvent::ConnectionEstablished { .. } => {}
SwarmEvent::Behaviour(PlutoMdnsBehaviourEvent::Pluto(
PlutoBehaviourEvent::Ping(_),
)) => {}
SwarmEvent::Behaviour(PlutoMdnsBehaviourEvent::Pluto(
PlutoBehaviourEvent::Identify(identify::Event::Sent { .. }),
)) => {
SwarmEvent::Behaviour(PlutoBehaviourEvent::Ping(_)) => {}
SwarmEvent::Behaviour(PlutoBehaviourEvent::Identify(identify::Event::Sent {
..
})) => {
println!("Told relay its public address");
told_relay_observed_addr = true;
}
SwarmEvent::Behaviour(PlutoMdnsBehaviourEvent::Pluto(
PlutoBehaviourEvent::Identify(identify::Event::Received {
SwarmEvent::Behaviour(PlutoBehaviourEvent::Identify(
identify::Event::Received {
info: identify::Info { observed_addr, .. },
..
}),
},
)) => {
println!("Relay told us our observed address: {}", observed_addr);
learned_observed_addr = true;
Expand All @@ -93,32 +139,32 @@ async fn main() -> Result<()> {

println!("ENR: {}", enr);

swarm.listen_on(format!("/ip4/0.0.0.0/udp/{}/quic-v1", args.port).parse()?)?;
swarm.listen_on(format!("/ip4/0.0.0.0/tcp/{}", args.port).parse()?)?;
p2p.listen_on(format!("/ip4/0.0.0.0/udp/{}/quic-v1", args.port).parse()?)?;
p2p.listen_on(format!("/ip4/0.0.0.0/tcp/{}", args.port).parse()?)?;
if let Some(relay_url) = args.relay_url {
swarm.listen_on(relay_url.with(Protocol::P2pCircuit))?;
p2p.listen_on(relay_url.with(Protocol::P2pCircuit))?;
}

loop {
tokio::select! {
event = swarm.select_next_some() => match event {
SwarmEvent::Behaviour(PlutoMdnsBehaviourEvent::Pluto(PlutoBehaviourEvent::Identify(identify::Event::Received { info: identify::Info { observed_addr, .. }, .. }))) => {
swarm.add_external_address(observed_addr.clone());
event = p2p.select_next_some() => match event {
SwarmEvent::Behaviour(PlutoBehaviourEvent::Identify(identify::Event::Received { info: identify::Info { observed_addr, .. }, .. })) => {
p2p.add_external_address(observed_addr.clone());
println!("Address observed {}", observed_addr);
}
SwarmEvent::Behaviour(PlutoMdnsBehaviourEvent::Pluto(PlutoBehaviourEvent::Relay(event))) => {
SwarmEvent::Behaviour(PlutoBehaviourEvent::Inner(CombinedBehaviourEvent::Relay(event))) => {
println!("Got relay event: {:?}", event);
},
SwarmEvent::Behaviour(PlutoMdnsBehaviourEvent::Mdns(libp2p::mdns::Event::Discovered(nodes))) => {
SwarmEvent::Behaviour(PlutoBehaviourEvent::Inner(CombinedBehaviourEvent::Mdns(mdns::Event::Discovered(nodes)))) => {
for node in nodes {
println!("Discovered node: {:?}", node);
swarm.dial(node.1)?;
p2p.dial(node.1)?;
}
}
SwarmEvent::NewListenAddr { address, .. } => {
println!("Local node is listening on {address}");
}
SwarmEvent::Behaviour(PlutoMdnsBehaviourEvent::Pluto(PlutoBehaviourEvent::Ping(ping_event))) => {
SwarmEvent::Behaviour(PlutoBehaviourEvent::Ping(ping_event)) => {
println!("Got ping event: {:?}", ping_event);
}
SwarmEvent::IncomingConnection { connection_id, local_addr, send_back_addr } => {
Expand All @@ -133,11 +179,7 @@ async fn main() -> Result<()> {
},
_ = signal::ctrl_c() => {
println!("\nReceived Ctrl+C, shutting down gracefully...");

// Perform cleanup
let _ = swarm;
drop(p2p);

println!("Shutdown complete");
break;
}
Expand Down
12 changes: 2 additions & 10 deletions crates/p2p/src/behaviours/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,14 @@
//!
//! This module provides pre-configured network behaviours that combine multiple
//! libp2p protocols for use in Charon nodes.
//!
//! # Available Behaviours
//!
//! - [`PlutoBehaviour`](pluto::PlutoBehaviour): Core behaviour with relay,
//! identify, ping, and AutoNAT
//! - [`PlutoMdnsBehaviour`](pluto_mdns::PlutoMdnsBehaviour): Extends
//! `PlutoBehaviour` with mDNS discovery (requires `mdns` feature)

#![allow(missing_docs)] // we need to allow missing docs for the derive macro

/// Pluto behaviour.
pub mod pluto;

#[cfg(feature = "mdns")]
/// Pluto Mdns behaviour.
pub mod pluto_mdns;
/// Optional behaviour wrapper.
pub mod optional;

// Re-export autonat types for convenience
pub use libp2p::autonat;
Loading