Skip to content

Commit f9370aa

Browse files
author
Ifeanyichukwu
committed
feat: add optional name for activity descriptions
1 parent a574b1e commit f9370aa

File tree

2 files changed

+55
-12
lines changed

2 files changed

+55
-12
lines changed

sim-cli/src/main.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ async fn main() -> anyhow::Result<()> {
9595
let mut clients: HashMap<PublicKey, Arc<Mutex<dyn LightningNode>>> = HashMap::new();
9696
let mut pk_node_map = HashMap::new();
9797
let mut alias_node_map = HashMap::new();
98+
let mut activity_name_map = HashMap::new();
9899

99100
for connection in nodes {
100101
// TODO: Feels like there should be a better way of doing this without having to Arc<Mutex<T>>> it at this time.
@@ -182,13 +183,23 @@ async fn main() -> anyhow::Result<()> {
182183
},
183184
};
184185

186+
if activity_name_map.contains_key(&act.activity_name) {
187+
anyhow::bail!(LightningError::ValidationError(format!(
188+
"Duplicate activity name {:?} is not allowed.",
189+
act.activity_name.unwrap()
190+
)));
191+
}
192+
193+
activity_name_map.insert(act.activity_name.clone(), act.clone());
194+
185195
validated_activities.push(ActivityDefinition {
186196
source,
187197
destination,
188198
start_secs: act.start_secs,
189199
count: act.count,
190200
interval_secs: act.interval_secs,
191201
amount_msat: act.amount_msat,
202+
activity_name: act.activity_name,
192203
});
193204
}
194205

sim-lib/src/lib.rs

Lines changed: 44 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,8 @@ pub struct ActivityParser {
149149
pub interval_secs: u16,
150150
/// The amount of m_sat to used in this payment.
151151
pub amount_msat: u64,
152+
/// an optional name for the activity.
153+
pub activity_name: Option<String>,
152154
}
153155

154156
/// Data structure used internally by the simulator. Both source and destination are represented as [PublicKey] here.
@@ -167,6 +169,8 @@ pub struct ActivityDefinition {
167169
pub interval_secs: u16,
168170
/// The amount of m_sat to used in this payment.
169171
pub amount_msat: u64,
172+
/// An optional name for the activity.
173+
pub activity_name: Option<String>,
170174
}
171175

172176
#[derive(Debug, Error)]
@@ -336,14 +340,16 @@ pub enum PaymentOutcome {
336340
}
337341

338342
/// Describes a payment from a source node to a destination node.
339-
#[derive(Debug, Clone, Copy, Serialize)]
343+
#[derive(Debug, Clone, Serialize)]
340344
struct Payment {
341345
/// Pubkey of the source node dispatching the payment.
342346
source: PublicKey,
343347
/// Pubkey of the destination node receiving the payment.
344348
destination: PublicKey,
345349
/// Amount of the payment in msat.
346350
amount_msat: u64,
351+
/// Name of the activity.
352+
activity_name: String,
347353
/// Hash of the payment if it has been successfully dispatched.
348354
#[serde(with = "serializers::serde_option_payment_hash")]
349355
hash: Option<PaymentHash>,
@@ -352,6 +358,16 @@ struct Payment {
352358
dispatch_time: SystemTime,
353359
}
354360

361+
impl Payment {
362+
fn formatted_activity_name(&self) -> String {
363+
if !self.activity_name.is_empty() {
364+
format!("{} activity:", self.activity_name)
365+
} else {
366+
"".to_string()
367+
}
368+
}
369+
}
370+
355371
impl Display for Payment {
356372
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
357373
let dispatch_time = self
@@ -361,7 +377,8 @@ impl Display for Payment {
361377

362378
write!(
363379
f,
364-
"Payment {} dispatched at {:?} sending {} msat from {} -> {}.",
380+
"{} Payment {} dispatched at {:?} sending {} msat from {} -> {}.",
381+
self.formatted_activity_name(),
365382
self.hash.map(|h| hex::encode(h.0)).unwrap_or_default(),
366383
dispatch_time,
367384
self.amount_msat,
@@ -377,7 +394,7 @@ impl Display for Payment {
377394
enum SimulationEvent {
378395
/// Dispatch a payment of the specified amount to the public key provided.
379396
/// Results in `SimulationOutput::SendPaymentSuccess` or `SimulationOutput::SendPaymentFailure`.
380-
SendPayment(NodeInfo, u64),
397+
SendPayment(NodeInfo, u64, String),
381398
}
382399

383400
/// SimulationOutput provides the output of a simulation event.
@@ -427,6 +444,7 @@ struct ExecutorKit {
427444
/// See [NetworkGraphView] for details.
428445
network_generator: Arc<Mutex<dyn DestinationGenerator>>,
429446
payment_generator: Box<dyn PaymentGenerator>,
447+
activity_name: String,
430448
}
431449

432450
impl Simulation {
@@ -696,7 +714,12 @@ impl Simulation {
696714
// Note: when we allow configuring both defined and random activity, this will no longer be an if/else, we'll
697715
// just populate with each type as configured.
698716
if !self.activity.is_empty() {
699-
for description in self.activity.iter() {
717+
for (index, description) in self.activity.iter().enumerate() {
718+
let activity_name = match &description.activity_name {
719+
Some(name) => name.clone(),
720+
None => format!("Index {}", index),
721+
};
722+
700723
let activity_generator = DefinedPaymentActivity::new(
701724
description.destination.clone(),
702725
Duration::from_secs(description.start_secs.into()),
@@ -711,6 +734,7 @@ impl Simulation {
711734
// a single struct which we just cheaply clone.
712735
network_generator: Arc::new(Mutex::new(activity_generator.clone())),
713736
payment_generator: Box::new(activity_generator),
737+
activity_name,
714738
});
715739
}
716740
} else {
@@ -762,6 +786,7 @@ impl Simulation {
762786
generators.push(ExecutorKit {
763787
source_info: node_info.clone(),
764788
network_generator: network_generator.clone(),
789+
activity_name: "".to_string(),
765790
payment_generator: Box::new(
766791
RandomPaymentActivity::new(
767792
*capacity,
@@ -845,13 +870,15 @@ impl Simulation {
845870
let source = executor.source_info.clone();
846871

847872
log::info!(
848-
"Starting activity producer for {}: {}.",
873+
"Starting {} activity producer for {}: {}.",
874+
executor.activity_name,
849875
source,
850876
executor.payment_generator
851877
);
852878

853879
if let Err(e) = produce_events(
854880
executor.source_info,
881+
executor.activity_name,
855882
executor.network_generator,
856883
executor.payment_generator,
857884
pe_sender,
@@ -888,7 +915,7 @@ async fn consume_events(
888915
simulation_event = receiver.recv() => {
889916
if let Some(event) = simulation_event {
890917
match event {
891-
SimulationEvent::SendPayment(dest, amt_msat) => {
918+
SimulationEvent::SendPayment(dest, amt_msat, activity_name) => {
892919
let mut node = node.lock().await;
893920

894921
let mut payment = Payment {
@@ -897,6 +924,7 @@ async fn consume_events(
897924
amount_msat: amt_msat,
898925
destination: dest.pubkey,
899926
dispatch_time: SystemTime::now(),
927+
activity_name,
900928
};
901929

902930
let outcome = match node.send_payment(dest.pubkey, amt_msat).await {
@@ -947,6 +975,7 @@ async fn consume_events(
947975
/// exit if other threads signal that they have errored out.
948976
async fn produce_events<N: DestinationGenerator + ?Sized, A: PaymentGenerator + ?Sized>(
949977
source: NodeInfo,
978+
activity_name: String,
950979
network_generator: Arc<Mutex<N>>,
951980
node_generator: Box<A>,
952981
sender: Sender<SimulationEvent>,
@@ -996,7 +1025,7 @@ async fn produce_events<N: DestinationGenerator + ?Sized, A: PaymentGenerator +
9961025
let amount = match node_generator.payment_amount(capacity) {
9971026
Ok(amt) => {
9981027
if amt == 0 {
999-
log::debug!("Skipping zero amount payment for {source} -> {destination}.");
1028+
log::debug!("{activity_name} activity : Skipping zero amount payment for {source} -> {destination}.");
10001029
continue;
10011030
}
10021031
amt
@@ -1009,7 +1038,7 @@ async fn produce_events<N: DestinationGenerator + ?Sized, A: PaymentGenerator +
10091038
log::debug!("Generated payment: {source} -> {}: {amount} msat.", destination);
10101039

10111040
// Send the payment, exiting if we can no longer send to the consumer.
1012-
let event = SimulationEvent::SendPayment(destination.clone(), amount);
1041+
let event = SimulationEvent::SendPayment(destination.clone(), amount, activity_name.clone());
10131042
if sender.send(event.clone()).await.is_err() {
10141043
return Err(SimulationError::MpscChannelError (format!("Stopped activity producer for {amount}: {source} -> {destination}.")));
10151044
}
@@ -1076,11 +1105,12 @@ async fn consume_simulation_results(
10761105
}
10771106

10781107
/// PaymentResultLogger is an aggregate logger that will report on a summary of the payments that have been reported.
1079-
#[derive(Default)]
1108+
#[derive(Default, Clone)]
10801109
struct PaymentResultLogger {
10811110
success_payment: u64,
10821111
failed_payment: u64,
10831112
total_sent: u64,
1113+
activity_name: String,
10841114
}
10851115

10861116
impl PaymentResultLogger {
@@ -1097,6 +1127,7 @@ impl PaymentResultLogger {
10971127
}
10981128

10991129
self.total_sent += details.amount_msat;
1130+
self.activity_name = details.formatted_activity_name();
11001131
}
11011132
}
11021133

@@ -1105,7 +1136,8 @@ impl Display for PaymentResultLogger {
11051136
let total_payments = self.success_payment + self.failed_payment;
11061137
write!(
11071138
f,
1108-
"Processed {} payments sending {} msat total with {:.2}% success rate.",
1139+
"{} Processed {} payments sending {} msat total with {:.2}% success rate.",
1140+
self.activity_name,
11091141
total_payments,
11101142
self.total_sent,
11111143
(self.success_payment as f64 / total_payments as f64) * 100.0
@@ -1174,7 +1206,7 @@ async fn produce_simulation_results(
11741206
}
11751207
},
11761208
SimulationOutput::SendPaymentFailure(payment, result) => {
1177-
if results.send((payment, result.clone())).await.is_err() {
1209+
if results.send((payment.clone(), result.clone())).await.is_err() {
11781210
return Err(SimulationError::MpscChannelError(
11791211
format!("Failed to send payment result: {result} for payment {:?} dispatched at {:?}.", payment.hash, payment.dispatch_time),
11801212
));
@@ -1245,7 +1277,7 @@ async fn track_payment_result(
12451277
_ = listener.clone() => {
12461278
log::debug!("Track payment result received a shutdown signal.");
12471279
},
1248-
send_payment_result = results.send((payment, res.clone())) => {
1280+
send_payment_result = results.send((payment.clone(), res.clone())) => {
12491281
if send_payment_result.is_err() {
12501282
return Err(SimulationError::MpscChannelError(format!("Failed to send payment result {res} for payment {payment}.")))
12511283
}

0 commit comments

Comments
 (0)