Skip to content

Commit

Permalink
Fix local docker compose runs
Browse files Browse the repository at this point in the history
This adds support for multiple bootstrap peers. We use this in the
local docker compose set up to ensure all nodes have at least one
other node to talk to at startup, which they can use to find their
own external address via autonat.

This also means we can remove the incorrect code where we always
trust our observed external address once a single peer reports
one. Instead, the external address candidates are passed to
autonat and confirmed later.

The configuration change is backwards compatible, because we
support either a single entry or a list of bootstrap peers now.
  • Loading branch information
JamesHinshelwood committed Feb 3, 2025
1 parent 9f374c5 commit 5d17b03
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 19 deletions.
2 changes: 2 additions & 0 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ version: "3"
services:
node0:
depends_on:
- node2
- node3
environment:
RUST_BACKTRACE: 1
Expand All @@ -24,6 +25,7 @@ services:

node1:
depends_on:
- node2
- node3
environment:
RUST_BACKTRACE: 1
Expand Down
10 changes: 8 additions & 2 deletions infra/config_docker.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
bootstrap_address = [
"12D3KooWPXw2dXBRH1bT4vcNos9f6W2KoFTiarqptBuTzxaXg7zu",
"/ip4/198.51.100.103/tcp/5643",
[
"12D3KooWLA4xVjiGszqmYJmt8E1NTurVeCujDi17FoSzSDDDKUjT",
"/ip4/198.51.100.102/tcp/5643",
],
[
"12D3KooWPXw2dXBRH1bT4vcNos9f6W2KoFTiarqptBuTzxaXg7zu",
"/ip4/198.51.100.103/tcp/5643",
],
]
p2p_port = 5643

Expand Down
2 changes: 1 addition & 1 deletion z2/src/setup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -500,7 +500,7 @@ impl Setup {
println!("🎱 Generating configuration for node {node_index}...");
let mut cfg = zilliqa::cfg::Config {
otlp_collector_endpoint: Some("http://localhost:4317".to_string()),
bootstrap_address: None,
bootstrap_address: Default::default(),
nodes: Vec::new(),
p2p_port: 0,
external_address: None,
Expand Down
43 changes: 42 additions & 1 deletion zilliqa/src/cfg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,53 @@ pub struct Config {
/// The address of another node to dial when this node starts. To join the network, a node must know about at least
/// one other existing node in the network.
#[serde(default)]
pub bootstrap_address: Option<(PeerId, Multiaddr)>,
pub bootstrap_address: OneOrMany<(PeerId, Multiaddr)>,
/// The base address of the OTLP collector. If not set, metrics will not be exported.
#[serde(default)]
pub otlp_collector_endpoint: Option<String>,
}

#[derive(Debug, Clone)]
pub struct OneOrMany<T>(pub Vec<T>);

impl<T> Default for OneOrMany<T> {
fn default() -> Self {
Self(vec![])
}
}

impl<T: Serialize> Serialize for OneOrMany<T> {
fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
where
S: Serializer,
{
if self.0.len() == 1 {
self.0[0].serialize(serializer)
} else {
self.0.serialize(serializer)
}
}
}

impl<'de, T: Deserialize<'de>> Deserialize<'de> for OneOrMany<T> {
fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
where
D: Deserializer<'de>,
{
#[derive(Deserialize)]
#[serde(untagged)]
enum Inner<T> {
One(T),
Many(Vec<T>),
}

match Inner::deserialize(deserializer)? {
Inner::One(t) => Ok(OneOrMany(vec![t])),
Inner::Many(t) => Ok(OneOrMany(t)),
}
}
}

#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum EnabledApi {
Expand Down
16 changes: 1 addition & 15 deletions zilliqa/src/p2p_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ impl P2pNode {
self.swarm.add_external_address(external_address.clone());
}

if let Some((peer, address)) = &self.config.bootstrap_address {
for (peer, address) in &self.config.bootstrap_address.0 {
if self.swarm.local_peer_id() != peer {
self.swarm.dial(address.clone())?;
self.swarm.add_peer_address(*peer, address.clone());
Expand All @@ -254,20 +254,6 @@ impl P2pNode {
SwarmEvent::NewListenAddr { address, .. } => {
info!(%address, "P2P swarm listening on");
}
SwarmEvent::Behaviour(BehaviourEvent::Identify(identify::Event::Received { peer_id, info: identify::Info{ listen_addrs, observed_addr, protocols, .. }, .. })) => {
self.swarm.add_external_address(observed_addr);
if protocols.iter().any(|p| *p == kad::PROTOCOL_NAME) {
for addr in listen_addrs {
self.swarm.add_peer_address(peer_id, addr);
}
}
}
SwarmEvent::NewExternalAddrOfPeer { peer_id, address } => {
self.swarm
.behaviour_mut()
.kademlia
.add_address(&peer_id, address.clone());
}
SwarmEvent::Behaviour(BehaviourEvent::Gossipsub(gossipsub::Event::Subscribed { peer_id, topic })) => {
if let Some(peers) = self.shard_peers.get(&topic) {
peers.add_peer(peer_id);
Expand Down

0 comments on commit 5d17b03

Please sign in to comment.