Skip to content

Commit 83e2d28

Browse files
committed
add peer discovery
1 parent f228e48 commit 83e2d28

8 files changed

Lines changed: 210 additions & 49 deletions

File tree

sim-cli/src/parsing.rs

Lines changed: 59 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use std::path::PathBuf;
2020
use std::sync::Arc;
2121
use tokio::sync::Mutex;
2222
use tokio_util::task::TaskTracker;
23+
use triggered::Listener;
2324

2425
/// The default directory where the simulation files are stored and where the results will be written to.
2526
pub const DEFAULT_DATA_DIR: &str = ".";
@@ -359,8 +360,14 @@ pub async fn create_simulation(
359360
ldk_hub: _,
360361
} = sim_params;
361362

362-
let (clients, clients_info) = get_clients(nodes.to_vec(), sim_params.ldk_hub.clone()).await?;
363363
let (shutdown_trigger, shutdown_listener) = triggered::trigger();
364+
let (clients, clients_info) = get_clients(
365+
nodes.to_vec(),
366+
sim_params.ldk_hub.clone(),
367+
tasks.clone(),
368+
shutdown_listener.clone(),
369+
)
370+
.await?;
364371

365372
let validated_activities =
366373
get_validated_activities(&clients, clients_info, sim_params.activity.clone()).await?;
@@ -383,6 +390,8 @@ pub async fn create_simulation(
383390
async fn get_clients(
384391
nodes: Vec<NodeConnection>,
385392
ldk_hub: Option<ldk::LdkHubConfig>,
393+
tasks: TaskTracker,
394+
shutdown: Listener,
386395
) -> Result<
387396
(
388397
HashMap<PublicKey, Arc<Mutex<dyn LightningNode>>>,
@@ -393,24 +402,12 @@ async fn get_clients(
393402
let mut clients: HashMap<PublicKey, Arc<Mutex<dyn LightningNode>>> = HashMap::new();
394403
let mut clients_info: HashMap<PublicKey, NodeInfo> = HashMap::new();
395404

396-
let (ldk_connections, other_connections): (Vec<_>, Vec<_>) =
397-
nodes.into_iter().partition(|n| matches!(n, NodeConnection::Ldk(_)));
398-
399-
let ldk_configs: Vec<ldk::LdkNodeConfig> = ldk_connections
405+
let (ldk_connections, other_connections): (Vec<_>, Vec<_>) = nodes
400406
.into_iter()
401-
.filter_map(|n| match n {
402-
NodeConnection::Ldk(cfg) => Some(cfg),
403-
_ => None,
404-
})
405-
.collect();
406-
407-
for ldk_node in ldk::build_ldk_nodes(ldk_configs, ldk_hub).await? {
408-
let info = ldk_node.get_info().clone();
409-
let node: Arc<Mutex<dyn LightningNode>> = Arc::new(Mutex::new(ldk_node));
410-
clients.insert(info.pubkey, node);
411-
clients_info.insert(info.pubkey, info);
412-
}
407+
.partition(|n| matches!(n, NodeConnection::Ldk(_)));
413408

409+
// Build non-LDK nodes first so we have their peer addresses before connecting LDK nodes.
410+
let mut non_ldk_peers: Vec<(PublicKey, String)> = Vec::new();
414411
for connection in other_connections {
415412
let node: Arc<Mutex<dyn LightningNode>> = match connection {
416413
NodeConnection::Lnd(c) => Arc::new(Mutex::new(LndNode::new(c).await?)),
@@ -419,10 +416,55 @@ async fn get_clients(
419416
NodeConnection::Ldk(_) => unreachable!(),
420417
};
421418
let node_info = node.lock().await.get_info().clone();
419+
if let Some(addr) = node_info.p2p_addr.clone() {
420+
non_ldk_peers.push((node_info.pubkey, addr));
421+
} else {
422+
log::warn!(
423+
"No p2p_addr for {}: LDK nodes will not connect to it as a peer.",
424+
node_info.alias
425+
);
426+
}
422427
clients.insert(node_info.pubkey, node);
423428
clients_info.insert(node_info.pubkey, node_info);
424429
}
425430

431+
let ldk_configs: Vec<ldk::LdkNodeConfig> = ldk_connections
432+
.into_iter()
433+
.filter_map(|n| match n {
434+
NodeConnection::Ldk(cfg) => Some(cfg),
435+
_ => None,
436+
})
437+
.collect();
438+
439+
let ldk_nodes = ldk::build_ldk_nodes(ldk_configs, ldk_hub, tasks, shutdown).await?;
440+
441+
// Collect LDK peer info for all-to-all connections.
442+
let ldk_peers: Vec<(PublicKey, String)> = ldk_nodes
443+
.iter()
444+
.filter_map(|n| {
445+
let info = n.get_info();
446+
info.p2p_addr.as_ref().map(|addr| (info.pubkey, addr.clone()))
447+
})
448+
.collect();
449+
450+
for ldk_node in ldk_nodes {
451+
let info = ldk_node.get_info().clone();
452+
453+
// Connect to every other LDK node.
454+
for (peer_pk, peer_addr) in &ldk_peers {
455+
if peer_pk != &info.pubkey {
456+
ldk_node.connect_peer(*peer_pk, peer_addr);
457+
}
458+
}
459+
// Connect to non-LDK nodes.
460+
for (peer_pk, peer_addr) in &non_ldk_peers {
461+
ldk_node.connect_peer(*peer_pk, peer_addr);
462+
}
463+
464+
clients.insert(info.pubkey, Arc::new(Mutex::new(ldk_node)));
465+
clients_info.insert(info.pubkey, info);
466+
}
467+
426468
Ok((clients, clients_info))
427469
}
428470

simln-lib/src/cln.rs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,10 @@ impl ClnNode {
9292
.map_err(|err| LightningError::GetInfoError(err.to_string()))?
9393
.into_inner();
9494

95+
let p2p_addr = info.binding.first().and_then(|b| {
96+
b.address.as_deref().zip(b.port).map(|(host, port)| format!("{}:{}", host, port))
97+
});
98+
9599
let pubkey = PublicKey::from_slice(&info.id)
96100
.map_err(|err| LightningError::GetInfoError(err.to_string()))?;
97101
let mut alias = info.alias;
@@ -111,6 +115,7 @@ impl ClnNode {
111115
pubkey,
112116
features,
113117
alias,
118+
p2p_addr,
114119
},
115120
network,
116121
})
@@ -249,13 +254,18 @@ impl LightningNode for ClnNode {
249254

250255
// We are filtering `list_nodes` to a single node, so we should get either an empty vector or one with a single element
251256
if let Some(node) = nodes.pop() {
257+
let p2p_addr = node
258+
.addresses
259+
.first()
260+
.and_then(|a| a.address.as_ref().map(|host| format!("{}:{}", host, a.port)));
252261
Ok(NodeInfo {
253262
pubkey: *node_id,
254263
alias: node.alias.unwrap_or(String::new()),
255264
features: node
256265
.features
257266
.clone()
258267
.map_or(NodeFeatures::empty(), NodeFeatures::from_be_bytes),
268+
p2p_addr,
259269
})
260270
} else {
261271
Err(LightningError::GetNodeInfoError(
@@ -282,15 +292,22 @@ impl LightningNode for ClnNode {
282292
let mut nodes_by_pk: HashMap<PublicKey, NodeInfo> = HashMap::new();
283293

284294
for node in nodes {
295+
let pubkey =
296+
PublicKey::from_slice(&node.nodeid).expect("Public Key not valid");
297+
let p2p_addr = node
298+
.addresses
299+
.first()
300+
.and_then(|a| a.address.as_ref().map(|host| format!("{}:{}", host, a.port)));
285301
nodes_by_pk.insert(
286-
PublicKey::from_slice(&node.nodeid).expect("Public Key not valid"),
302+
pubkey,
287303
NodeInfo {
288-
pubkey: PublicKey::from_slice(&node.nodeid).expect("Public Key not valid"),
304+
pubkey,
289305
alias: node.clone().alias.unwrap_or(String::new()),
290306
features: node
291307
.features
292308
.clone()
293309
.map_or(NodeFeatures::empty(), NodeFeatures::from_be_bytes),
310+
p2p_addr,
294311
},
295312
);
296313
}

simln-lib/src/eclair.rs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,12 +110,15 @@ impl EclairNode {
110110
.map_err(|err| LightningError::ValidationError(err.to_string()))?;
111111
let features = parse_json_to_node_features(&info.features);
112112

113+
let p2p_addr = info.public_addresses.into_iter().next();
114+
113115
Ok(Self {
114116
client: Mutex::new(client),
115117
info: NodeInfo {
116118
pubkey,
117119
alias: info.alias,
118120
features,
121+
p2p_addr,
119122
},
120123
network,
121124
})
@@ -214,11 +217,13 @@ impl LightningNode for EclairNode {
214217
.await
215218
.map_err(|err| LightningError::GetNodeInfoError(err.to_string()))?;
216219
let features = parse_json_to_node_features(&node_info.announcement.features);
220+
let p2p_addr = node_info.announcement.addresses.into_iter().next();
217221

218222
Ok(NodeInfo {
219223
pubkey: *node_id,
220224
alias: node_info.announcement.alias,
221225
features,
226+
p2p_addr,
222227
})
223228
}
224229

@@ -255,12 +260,15 @@ impl LightningNode for EclairNode {
255260
let mut nodes_by_pk: HashMap<PublicKey, NodeInfo> = HashMap::new();
256261

257262
for node in nodes {
263+
let pubkey = PublicKey::from_str(&node.node_id).expect("Public Key not valid");
264+
let p2p_addr = node.addresses.into_iter().next();
258265
nodes_by_pk.insert(
259-
PublicKey::from_str(&node.node_id).expect("Public Key not valid"),
266+
pubkey,
260267
NodeInfo {
261-
pubkey: PublicKey::from_str(&node.node_id).expect("Public Key not valid"),
268+
pubkey,
262269
alias: node.alias.clone(),
263270
features: parse_json_to_node_features(&node.features),
271+
p2p_addr,
264272
},
265273
);
266274
}
@@ -276,6 +284,8 @@ struct GetInfoResponse {
276284
alias: String,
277285
network: String,
278286
features: Value,
287+
#[serde(rename = "publicAddresses", default)]
288+
public_addresses: Vec<String>,
279289
}
280290

281291
#[derive(Debug, Deserialize)]
@@ -305,6 +315,8 @@ type PaymentInfoResponse = Vec<PaymentPart>;
305315
struct Announcement {
306316
alias: String,
307317
features: Value,
318+
#[serde(default)]
319+
addresses: Vec<String>,
308320
}
309321

310322
#[derive(Debug, Deserialize)]
@@ -318,6 +330,8 @@ struct NodeInGraph {
318330
node_id: String,
319331
alias: String,
320332
features: Value,
333+
#[serde(default)]
334+
addresses: Vec<String>,
321335
}
322336

323337
type ChannelsResponse = Vec<Channel>;

0 commit comments

Comments
 (0)