Skip to content

Commit d58c28d

Browse files
committed
[NO MERGE]: run simulation with ring of nodes for testing
This commit is not intended for merge, it just spins up a circle of sim nodes so that we can test this functionality out. It'll be dropped before merge and replaced with the ability to properly configure your simulation (likely in a followup PR).
1 parent 6f3c936 commit d58c28d

File tree

3 files changed

+111
-10
lines changed

3 files changed

+111
-10
lines changed

Cargo.lock

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

sim-cli/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,4 @@ tokio = { version = "1.26.0", features = ["full"] }
2121
bitcoin = { version = "0.30.1" }
2222
ctrlc = "3.4.0"
2323
triggered = "0.1.2"
24+
rand = "0.8.5"

sim-cli/src/main.rs

Lines changed: 109 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,24 @@
1-
use bitcoin::secp256k1::PublicKey;
2-
use std::collections::HashMap;
3-
use std::path::PathBuf;
4-
use std::sync::Arc;
5-
use tokio::sync::Mutex;
6-
71
use anyhow::anyhow;
2+
use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey};
83
use clap::builder::TypedValueParser;
94
use clap::Parser;
105
use log::LevelFilter;
6+
use rand::distributions::Uniform;
7+
use rand::Rng;
118
use sim_lib::{
12-
cln::ClnNode, lnd::LndNode, ActivityDefinition, LightningError, LightningNode, NodeConnection,
13-
NodeId, SimParams, Simulation, WriteResults,
9+
cln::ClnNode,
10+
lnd::LndNode,
11+
sim_node::{
12+
ln_node_from_graph, populate_network_graph, ChannelPolicy, SimGraph, SimulatedChannel,
13+
},
14+
ActivityDefinition, LightningError, LightningNode, NodeConnection, NodeId, SimParams,
15+
Simulation, WriteResults,
1416
};
1517
use simple_logger::SimpleLogger;
18+
use std::collections::HashMap;
19+
use std::path::PathBuf;
20+
use std::sync::Arc;
21+
use tokio::sync::Mutex;
1622

1723
/// The default directory where the simulation files are stored and where the results will be written to.
1824
pub const DEFAULT_DATA_DIR: &str = ".";
@@ -189,7 +195,6 @@ async fn main() -> anyhow::Result<()> {
189195
amount_msat: act.amount_msat,
190196
});
191197
}
192-
193198
let write_results = if !cli.no_results {
194199
Some(WriteResults {
195200
results_dir: mkdir(cli.data_dir.join("results")).await?,
@@ -200,8 +205,20 @@ async fn main() -> anyhow::Result<()> {
200205
};
201206

202207
let (shutdown_trigger, shutdown_listener) = triggered::trigger();
208+
209+
let channels = generate_sim_nodes();
210+
let graph = match SimGraph::new(channels.clone(), shutdown_trigger.clone()) {
211+
Ok(graph) => Arc::new(Mutex::new(graph)),
212+
Err(e) => anyhow::bail!("failed: {:?}", e),
213+
};
214+
215+
let routing_graph = match populate_network_graph(channels) {
216+
Ok(r) => r,
217+
Err(e) => anyhow::bail!("failed: {:?}", e),
218+
};
219+
203220
let sim = Simulation::new(
204-
clients,
221+
ln_node_from_graph(graph.clone(), Arc::new(routing_graph)).await,
205222
validated_activities,
206223
cli.total_time,
207224
cli.expected_pmt_amt,
@@ -216,11 +233,93 @@ async fn main() -> anyhow::Result<()> {
216233
sim2.shutdown();
217234
})?;
218235

236+
// Run the simulation (blocking) until it exits. Once this happens, we can also wait for the simulated graph to
237+
// shut down. Errors in either of these will universally trigger shutdown because we share a trigger, so it doesn't
238+
// matter what order we wait for these.
219239
sim.run().await?;
240+
graph.lock().await.wait_for_shutdown().await;
220241

221242
Ok(())
222243
}
223244

245+
fn generate_sim_nodes() -> Vec<SimulatedChannel> {
246+
let capacity = 300000000;
247+
let mut channels: Vec<SimulatedChannel> = vec![];
248+
let (_, first_node) = get_random_keypair();
249+
250+
// Create channels in a ring so that we'll get long payment paths.
251+
let mut node_1 = first_node;
252+
for i in 0..10 {
253+
// Create a new node that we'll create a channel with. If we're on the last node in the circle, we'll loop
254+
// back around to the first node to close it.
255+
let node_2 = if i == 10 {
256+
first_node
257+
} else {
258+
let (_, pk) = get_random_keypair();
259+
pk
260+
};
261+
262+
let node_1_to_2 = ChannelPolicy {
263+
pubkey: node_1,
264+
max_htlc_count: 483,
265+
max_in_flight_msat: capacity / 2,
266+
min_htlc_size_msat: 1,
267+
max_htlc_size_msat: capacity / 2,
268+
cltv_expiry_delta: 40,
269+
// Alter fee rate a little for different values.
270+
base_fee: 1000 * i,
271+
fee_rate_prop: 1500 * i,
272+
};
273+
274+
let node_2_to_1 = ChannelPolicy {
275+
pubkey: node_2,
276+
max_htlc_count: 483,
277+
max_in_flight_msat: capacity / 2,
278+
min_htlc_size_msat: 1,
279+
max_htlc_size_msat: capacity / 2,
280+
cltv_expiry_delta: 40 + 10 * i as u32,
281+
// Alter fee rate a little for different values.
282+
base_fee: 2000 * i,
283+
fee_rate_prop: i,
284+
};
285+
286+
channels.push(SimulatedChannel::new(
287+
capacity,
288+
// Unique channel ID per link.
289+
100 + i,
290+
node_1_to_2,
291+
node_2_to_1,
292+
));
293+
294+
// Once we've created this link in the circle, progress our current node to be node_1 so that we can generate
295+
// a new edge.
296+
node_1 = node_2;
297+
}
298+
299+
channels
300+
}
301+
302+
/// COPIED from test utils!
303+
pub fn get_random_bytes(size: usize) -> Vec<u8> {
304+
rand::thread_rng()
305+
.sample_iter(Uniform::new(u8::MIN, u8::MAX))
306+
.take(size)
307+
.collect()
308+
}
309+
310+
pub fn get_random_int(s: u64, e: u64) -> u64 {
311+
rand::thread_rng().gen_range(s..e)
312+
}
313+
314+
pub fn get_random_keypair() -> (SecretKey, PublicKey) {
315+
loop {
316+
if let Ok(sk) = SecretKey::from_slice(&get_random_bytes(32)) {
317+
return (sk, PublicKey::from_secret_key(&Secp256k1::new(), &sk));
318+
}
319+
}
320+
}
321+
/// COPIED from test utils!
322+
224323
async fn read_sim_path(data_dir: PathBuf, sim_file: PathBuf) -> anyhow::Result<PathBuf> {
225324
let sim_path = if sim_file.is_relative() {
226325
data_dir.join(sim_file)

0 commit comments

Comments
 (0)