Skip to content

Commit 7f5c6b3

Browse files
committed
simln-lib/refactor: abstract activities validation
1 parent dda35c1 commit 7f5c6b3

File tree

4 files changed

+117
-92
lines changed

4 files changed

+117
-92
lines changed

sim-cli/src/main.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use clap::Parser;
22
use log::LevelFilter;
3-
use sim_cli::parsing::{create_simulation, Cli};
3+
use sim_cli::parsing::{create_simulation, get_validated_activities, parse_sim_params, Cli};
44
use simple_logger::SimpleLogger;
55

66
#[tokio::main]
@@ -12,6 +12,7 @@ async fn main() -> anyhow::Result<()> {
1212
}
1313

1414
let cli = Cli::parse();
15+
let sim_params = parse_sim_params(&cli).await?;
1516

1617
SimpleLogger::new()
1718
.with_level(LevelFilter::Warn)
@@ -20,15 +21,18 @@ async fn main() -> anyhow::Result<()> {
2021
.init()
2122
.unwrap();
2223

23-
let sim = create_simulation(&cli).await?;
24+
let (sim, nodes_info) = create_simulation(&cli, &sim_params).await?;
2425
let sim2 = sim.clone();
2526

2627
ctrlc::set_handler(move || {
2728
log::info!("Shutting down simulation.");
2829
sim2.shutdown();
2930
})?;
3031

31-
sim.run().await?;
32+
let validated_activities =
33+
get_validated_activities(&sim.nodes, nodes_info, sim_params.activity).await?;
34+
35+
sim.run(&validated_activities).await?;
3236

3337
Ok(())
3438
}

sim-cli/src/parsing.rs

Lines changed: 47 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -82,15 +82,15 @@ pub struct Cli {
8282
}
8383

8484
#[derive(Debug, Serialize, Deserialize, Clone)]
85-
struct SimParams {
85+
pub struct SimParams {
8686
pub nodes: Vec<NodeConnection>,
8787
#[serde(default)]
8888
pub activity: Vec<ActivityParser>,
8989
}
9090

9191
#[derive(Serialize, Deserialize, Debug, Clone)]
9292
#[serde(untagged)]
93-
enum NodeConnection {
93+
pub enum NodeConnection {
9494
Lnd(lnd::LndConnection),
9595
Cln(cln::ClnConnection),
9696
Eclair(eclair::EclairConnection),
@@ -99,7 +99,7 @@ enum NodeConnection {
9999
/// Data structure used to parse information from the simulation file. It allows source and destination to be
100100
/// [NodeId], which enables the use of public keys and aliases in the simulation description.
101101
#[derive(Debug, Clone, Serialize, Deserialize)]
102-
struct ActivityParser {
102+
pub struct ActivityParser {
103103
/// The source of the payment.
104104
#[serde(with = "serializers::serde_node_id")]
105105
pub source: NodeId,
@@ -142,40 +142,21 @@ impl TryFrom<&Cli> for SimulationCfg {
142142

143143
/// Parses the cli options provided and creates a simulation to be run, connecting to lightning nodes and validating
144144
/// any activity described in the simulation file.
145-
pub async fn create_simulation(cli: &Cli) -> Result<Simulation, anyhow::Error> {
145+
pub async fn create_simulation(
146+
cli: &Cli,
147+
sim_params: &SimParams,
148+
) -> Result<(Simulation, HashMap<PublicKey, NodeInfo>), anyhow::Error> {
146149
let cfg: SimulationCfg = SimulationCfg::try_from(cli)?;
147150

148-
let sim_path = read_sim_path(cli.data_dir.clone(), cli.sim_file.clone()).await?;
149-
let SimParams { nodes, activity } = serde_json::from_str(&std::fs::read_to_string(sim_path)?)
150-
.map_err(|e| {
151-
anyhow!(
152-
"Could not deserialize node connection data or activity description from simulation file (line {}, col {}, err: {}).",
153-
e.line(),
154-
e.column(),
155-
e.to_string()
156-
)
157-
})?;
151+
let SimParams {
152+
nodes,
153+
activity: _activity,
154+
} = sim_params;
158155

159-
let (clients, clients_info) = get_clients(nodes).await?;
160-
// We need to be able to look up destination nodes in the graph, because we allow defined activities to send to
161-
// nodes that we do not control. To do this, we can just grab the first node in our map and perform the lookup.
162-
let get_node = async |pk: &PublicKey| -> Result<NodeInfo, LightningError> {
163-
if let Some(c) = clients.values().next() {
164-
return c.lock().await.get_node_info(pk).await;
165-
}
166-
167-
Err(LightningError::GetNodeInfoError(
168-
"no nodes for query".to_string(),
169-
))
170-
};
171-
172-
let (pk_node_map, alias_node_map) = add_node_to_maps(&clients_info).await?;
173-
174-
let validated_activities =
175-
validate_activities(activity, pk_node_map, alias_node_map, get_node).await?;
156+
let (clients, clients_info) = get_clients(nodes.to_vec()).await?;
176157
let tasks = TaskTracker::new();
177158

178-
Ok(Simulation::new(cfg, clients, validated_activities, tasks))
159+
Ok((Simulation::new(cfg, clients, tasks), clients_info))
179160
}
180161

181162
/// Connects to the set of nodes providing, returning a map of node public keys to LightningNode implementations and
@@ -362,3 +343,37 @@ fn mkdir(dir: PathBuf) -> anyhow::Result<PathBuf> {
362343
fs::create_dir_all(&dir)?;
363344
Ok(dir)
364345
}
346+
347+
pub async fn parse_sim_params(cli: &Cli) -> anyhow::Result<SimParams> {
348+
let sim_path = read_sim_path(cli.data_dir.clone(), cli.sim_file.clone()).await?;
349+
let sim_params = serde_json::from_str(&std::fs::read_to_string(sim_path)?).map_err(|e| {
350+
anyhow!(
351+
"Could not deserialize node connection data or activity description from simulation file (line {}, col {}, err: {}).",
352+
e.line(),
353+
e.column(),
354+
e.to_string()
355+
)
356+
})?;
357+
Ok(sim_params)
358+
}
359+
360+
pub async fn get_validated_activities(
361+
clients: &HashMap<PublicKey, Arc<Mutex<dyn LightningNode>>>,
362+
nodes_info: HashMap<PublicKey, NodeInfo>,
363+
activity: Vec<ActivityParser>,
364+
) -> Result<Vec<ActivityDefinition>, LightningError> {
365+
// We need to be able to look up destination nodes in the graph, because we allow defined activities to send to
366+
// nodes that we do not control. To do this, we can just grab the first node in our map and perform the lookup.
367+
let get_node = async |pk: &PublicKey| -> Result<NodeInfo, LightningError> {
368+
if let Some(c) = clients.values().next() {
369+
return c.lock().await.get_node_info(pk).await;
370+
}
371+
Err(LightningError::GetNodeInfoError(
372+
"no nodes for query".to_string(),
373+
))
374+
};
375+
let (pk_node_map, alias_node_map) = add_node_to_maps(&nodes_info).await?;
376+
let validated_activities =
377+
validate_activities(activity.to_vec(), pk_node_map, alias_node_map, get_node).await?;
378+
Ok(validated_activities)
379+
}

0 commit comments

Comments
 (0)