Skip to content

Commit 0a4b2f6

Browse files
authored
feat: add relay server functionality (#101)
* feat: add tracing * fix: linting, cargo-deny * feat: add p2p config * fix: remove comment * feat: add p2p metrics * fix: rename label in example * fix: linting * feat: [wip] add relay/ping * feat: add behaviours module, add relay client support * fix: linter warnings * fix: remove wildcard dependencies * feat: add connection gater * fix: linter warnings * fix: linter warnings * feat: create behaviour builder * feat: add relay server functionality * chore: fix linter, polish code * fix: cargo deny dependency issue * chore: add docs * refactor: move relay-server to a different crate * fix: remove unnecessary tick skip * fix: remove unused fn, drop lock after usage * fix: linter * fix: module visibility * feat: add bon support * feat: make ping config unconfigurable, use default ping config instead * fix: set ping timeout to 10 seconds * feat: add user agent support * feat: make relay identify protocol const
1 parent 9f6cde2 commit 0a4b2f6

22 files changed

Lines changed: 1187 additions & 47 deletions

File tree

Cargo.lock

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

Cargo.toml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ members = [
1313
"crates/charon-testutil",
1414
"crates/tracing",
1515
"crates/eth2api",
16+
"crates/relay-server"
1617
]
1718
resolver = "3"
1819

@@ -28,9 +29,10 @@ alloy = { version = "1.3", features = ["essentials"] }
2829
built = { version = "0.8.0", features = ["git2", "chrono", "cargo-lock"] }
2930
blst = "0.3"
3031
anyhow = "1"
32+
axum = "0.8.6"
3133
cancellation = "0.1.0"
3234
chrono = { version = "0.4", features = ["serde"] }
33-
clap = { version = "4.5", features = ["derive", "env", "cargo"] }
35+
clap = { version = "4.5.53", features = ["derive", "env", "cargo"] }
3436
crossbeam = "0.8.4"
3537
backon = "1.6.0"
3638
hex = { version = "0.4.3" }
@@ -43,7 +45,7 @@ serde = { version = "1.0", features = ["derive"] }
4345
serde_json = { version = "1.0" }
4446
thiserror = "2.0"
4547
tokio = { version = "1", features = ["full"] }
46-
tokio-util = { version = "0.7" }
48+
tokio-util = "0.7.11"
4749
libp2p = { version = "0.56", features = ["full", "secp256k1"] }
4850
url = "2.5"
4951
uuid = { version = "1.19", features = ["serde", "v4"] }
@@ -76,6 +78,7 @@ charon-k1util = { path = "crates/charon-k1util" }
7678
charon-p2p = { path = "crates/charon-p2p" }
7779
charon-testutil = { path = "crates/charon-testutil" }
7880
charon-tracing = { path = "crates/tracing" }
81+
charon-relay-server = { path = "crates/relay-server" }
7982
eth2api = { path = "crates/eth2api" }
8083

8184
[workspace.lints.rust]

crates/charon-p2p/Cargo.toml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ license.workspace = true
77
publish.workspace = true
88

99
[dependencies]
10+
axum.workspace = true
1011
chrono.workspace = true
1112
libp2p.workspace = true
1213
thiserror.workspace = true
@@ -15,8 +16,14 @@ charon-eth2.workspace = true
1516
charon-k1util.workspace = true
1617
vise.workspace = true
1718
tokio.workspace = true
19+
tokio-util.workspace = true
1820
rand.workspace = true
1921
tempfile.workspace = true
22+
charon-tracing.workspace = true
23+
tracing.workspace = true
24+
serde.workspace = true
25+
serde_json.workspace = true
26+
charon-core.workspace = true
2027

2128
[dev-dependencies]
2229
charon-testutil.workspace = true

crates/charon-p2p/examples/p2p.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ use charon_p2p::{
1212
pluto_mdns::{PlutoMdnsBehaviour, PlutoMdnsBehaviourEvent},
1313
},
1414
config::P2PConfig,
15-
gater::ConnGater,
1615
p2p::{Node, NodeType},
1716
};
1817
use clap::Parser;
@@ -40,7 +39,6 @@ async fn main() -> Result<()> {
4039
let mut p2p: Node<_> = Node::new(
4140
P2PConfig::default(),
4241
key.clone(),
43-
ConnGater::new_open_gater(),
4442
false,
4543
NodeType::QUIC,
4644
PlutoMdnsBehaviour::new,
Lines changed: 73 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
//! Pluto behaviour.
22
3-
use std::time::Duration;
3+
use std::sync::LazyLock;
44

55
use libp2p::{identify, identity::Keypair, ping, relay, swarm::NetworkBehaviour};
66

7-
use crate::gater::ConnGater;
7+
use crate::{config::default_ping_config, gater::ConnGater};
88

9+
/// Pluto network behaviour.
910
#[derive(NetworkBehaviour)]
1011
pub struct PlutoBehaviour {
1112
/// Connection gater behaviour.
@@ -19,20 +20,80 @@ pub struct PlutoBehaviour {
1920
}
2021

2122
impl PlutoBehaviour {
22-
/// Creates a new Pluto behaviour.
23+
/// Creates a new Pluto behaviour with default configuration.
2324
pub fn new(key: &Keypair, relay_client: relay::client::Behaviour) -> Self {
25+
PlutoBehaviourBuilder::default().build(key, relay_client)
26+
}
27+
28+
/// Returns a new builder for configuring a PlutoBehaviour.
29+
pub fn builder() -> PlutoBehaviourBuilder {
30+
PlutoBehaviourBuilder::default()
31+
}
32+
}
33+
34+
/// The default user agent for the Pluto network.
35+
pub static DEFAULT_USER_AGENT: LazyLock<String> =
36+
LazyLock::new(|| format!("pluto/{}", *charon_core::version::VERSION));
37+
38+
/// The default identify protocol for the Pluto network.
39+
pub static DEFAULT_IDENTIFY_PROTOCOL: LazyLock<String> =
40+
LazyLock::new(|| format!("/pluto/{}", *charon_core::version::VERSION));
41+
42+
/// Builder for [`PlutoBehaviour`].
43+
#[derive(Debug, Clone)]
44+
pub struct PlutoBehaviourBuilder {
45+
gater: Option<ConnGater>,
46+
identify_protocol: String,
47+
user_agent: String,
48+
}
49+
50+
impl Default for PlutoBehaviourBuilder {
51+
fn default() -> Self {
2452
Self {
53+
gater: None,
54+
identify_protocol: DEFAULT_IDENTIFY_PROTOCOL.clone(),
55+
user_agent: DEFAULT_USER_AGENT.clone(),
56+
}
57+
}
58+
}
59+
60+
impl PlutoBehaviourBuilder {
61+
/// Creates a new builder with default configuration.
62+
pub fn new() -> Self {
63+
Self::default()
64+
}
65+
66+
/// Sets the connection gater.
67+
pub fn with_gater(mut self, gater: ConnGater) -> Self {
68+
self.gater = Some(gater);
69+
self
70+
}
71+
72+
/// Sets the identify protocol string.
73+
pub fn with_identify_protocol(mut self, protocol: impl Into<String>) -> Self {
74+
self.identify_protocol = protocol.into();
75+
self
76+
}
77+
78+
/// Sets the user agent string.
79+
pub fn with_user_agent(mut self, user_agent: impl Into<String>) -> Self {
80+
self.user_agent = user_agent.into();
81+
self
82+
}
83+
84+
/// Builds the [`PlutoBehaviour`] with the provided keypair and relay
85+
/// client.
86+
pub fn build(self, key: &Keypair, relay_client: relay::client::Behaviour) -> PlutoBehaviour {
87+
PlutoBehaviour {
88+
gater: self
89+
.gater
90+
.unwrap_or_else(|| ConnGater::new_conn_gater(vec![], vec![])),
2591
relay: relay_client,
26-
identify: identify::Behaviour::new(identify::Config::new(
27-
"/pluto/1.0.0-alpha".into(),
28-
key.public(),
29-
)),
30-
ping: ping::Behaviour::new(
31-
ping::Config::new()
32-
.with_interval(Duration::from_secs(1))
33-
.with_timeout(Duration::from_secs(2)),
92+
identify: identify::Behaviour::new(
93+
identify::Config::new(self.identify_protocol, key.public())
94+
.with_agent_version(self.user_agent),
3495
),
35-
gater: ConnGater::new_conn_gater(vec![], vec![]),
96+
ping: ping::Behaviour::new(default_ping_config()),
3697
}
3798
}
3899
}

0 commit comments

Comments
 (0)