Skip to content

Commit 0095a23

Browse files
author
sangbida
committed
PR Fixes
1 parent 4eae08a commit 0095a23

File tree

2 files changed

+60
-108
lines changed

2 files changed

+60
-108
lines changed

simln-lib/README.md

Lines changed: 5 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,19 @@
11
# sim-ln
22

3-
A Lightning Network simulation library that enables testing and analysis of payment routing behavior in a controlled environment.
3+
A Lightning Network simulation library that enables testing and analysis of payment routing behavior on any Lightning Network. While primarily designed for controlled environments, it can also be used with real networks like Bitcoin signet where you don't control all nodes.
44

55
## Overview
66

77
sim-ln provides a framework for simulating Lightning Network payment routing behavior, allowing developers and researchers to:
88

9-
- Create simulated Lightning Network topologies
10-
- Test payment routing strategies
11-
- Analyze network behavior under different conditions
12-
- Simulate real Lightning node implementations (LND, c-lightning, Eclair)
13-
9+
- Generate specific or random traffic patterns on a provided Lightning graph.
10+
- Test payment routing strategies.
11+
- Analyze network behavior under different conditions.
1412
## Usage
1513

1614
Add sim-ln to your Cargo.toml:
1715

1816
```toml
1917
[dependencies]
2018
sim-ln = "0.1.0"
21-
```
22-
23-
### Basic Example
24-
25-
```rust
26-
use sim_ln::{SimulationCfg, Simulation, NodeInfo, LightningNode};
27-
28-
// Create simulation configuration
29-
let config = SimulationCfg::new(
30-
Some(3600), // Run for 1 hour
31-
1_000_000, // 1000 sat expected payment size
32-
1.0, // Normal activity level
33-
None, // No result writing
34-
Some(42), // Random seed for reproducibility
35-
);
36-
37-
// Set up nodes and channels
38-
// ... configure your network topology
39-
40-
// Create and run simulation
41-
let simulation = Simulation::new(config, nodes, activity, task_tracker);
42-
simulation.run().await?;
43-
```
19+
```

simln-lib/src/lib.rs

Lines changed: 55 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
#![deny(rustdoc::broken_intra_doc_links)]
2+
#![deny(missing_docs)]
3+
14
use async_trait::async_trait;
25
use bitcoin::secp256k1::PublicKey;
36
use bitcoin::Network;
@@ -39,14 +42,15 @@ mod test_utils;
3942
/// Represents a node id, either by its public key or alias.
4043
#[derive(Serialize, Debug, Clone)]
4144
pub enum NodeId {
42-
/// The node's public key
45+
/// The node's public key.
4346
PublicKey(PublicKey),
44-
/// The node's alias (human-readable name)
47+
/// The node's alias (human-readable name).
4548
Alias(String),
4649
}
4750

4851
impl NodeId {
49-
/// Validates that the provided node id matches the one returned by the backend.
52+
/// Validates that the provided node id matches the one returned by the backend. If the node id is an alias,
53+
/// it will be updated to the one returned by the backend if there is a mismatch.
5054
pub fn validate(&self, node_id: &PublicKey, alias: &mut String) -> Result<(), LightningError> {
5155
match self {
5256
crate::NodeId::PublicKey(pk) => {
@@ -98,21 +102,21 @@ impl std::fmt::Display for NodeId {
98102
#[derive(Debug, Clone, PartialEq, Eq, Hash, Copy)]
99103
pub struct ShortChannelID(u64);
100104

101-
/// Utility function to easily convert from u64 to `ShortChannelID`
105+
/// Utility function to easily convert from u64 to `ShortChannelID`.
102106
impl From<u64> for ShortChannelID {
103107
fn from(value: u64) -> Self {
104108
ShortChannelID(value)
105109
}
106110
}
107111

108-
/// Utility function to easily convert `ShortChannelID` into u64
112+
/// Utility function to easily convert `ShortChannelID` into u64.
109113
impl From<ShortChannelID> for u64 {
110114
fn from(scid: ShortChannelID) -> Self {
111115
scid.0
112116
}
113117
}
114118

115-
/// See <https://github.com/lightning/bolts/blob/60de4a09727c20dea330f9ee8313034de6e50594/07-routing-gossip.md#definition-of-short_channel_id>.
119+
/// See <https://github.com/lightning/bolts/blob/60de4a09727c20dea330f9ee8313034de6e50594/07-routing-gossip.md#definition-of-short_channel_id>
116120
impl std::fmt::Display for ShortChannelID {
117121
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
118122
write!(
@@ -129,9 +133,9 @@ impl std::fmt::Display for ShortChannelID {
129133
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
130134
#[serde(untagged)]
131135
pub enum ValueOrRange<T> {
132-
/// A single fixed value
136+
/// A single fixed value.
133137
Value(T),
134-
/// A range [min, max) from which values are randomly sampled
138+
/// A range [min, max) from which values are randomly sampled.
135139
Range(T, T),
136140
}
137141

@@ -189,85 +193,85 @@ pub struct ActivityDefinition {
189193
/// Represents errors that can occur during simulation execution.
190194
#[derive(Debug, Error)]
191195
pub enum SimulationError {
192-
/// Error that occurred during Lightning Network operations
196+
/// Error that occurred during Lightning Network operations.
193197
#[error("Lightning Error: {0:?}")]
194198
LightningError(#[from] LightningError),
195-
/// Error that occurred during task execution
199+
/// Error that occurred during task execution.
196200
#[error("TaskError")]
197201
TaskError,
198-
/// Error that occurred while writing CSV data
202+
/// Error that occurred while writing CSV data.
199203
#[error("CSV Error: {0:?}")]
200204
CsvError(#[from] csv::Error),
201-
/// Error that occurred during file operations
205+
/// Error that occurred during file operations.
202206
#[error("File Error")]
203207
FileError,
204-
/// Error that occurred during random activity generation
208+
/// Error that occurred during random activity generation.
205209
#[error("{0}")]
206210
RandomActivityError(RandomActivityError),
207-
/// Error that occurred in the simulated network
211+
/// Error that occurred in the simulated network.
208212
#[error("Simulated Network Error: {0}")]
209213
SimulatedNetworkError(String),
210-
/// Error that occurred while accessing system time
214+
/// Error that occurred while accessing system time.
211215
#[error("System Time Error: {0}")]
212216
SystemTimeError(#[from] SystemTimeError),
213-
/// Error that occurred when a required node was not found
217+
/// Error that occurred when a required node was not found.
214218
#[error("Missing Node Error: {0}")]
215219
MissingNodeError(String),
216-
/// Error that occurred in message passing channels
220+
/// Error that occurred in message passing channels.
217221
#[error("Mpsc Channel Error: {0}")]
218222
MpscChannelError(String),
219-
/// Error that occurred while generating payment parameters
223+
/// Error that occurred while generating payment parameters.
220224
#[error("Payment Generation Error: {0}")]
221225
PaymentGenerationError(PaymentGenerationError),
222-
/// Error that occurred while generating destination nodes
226+
/// Error that occurred while generating destination nodes.
223227
#[error("Destination Generation Error: {0}")]
224228
DestinationGenerationError(DestinationGenerationError),
225229
}
226230

227231
/// Represents errors that can occur during Lightning Network operations.
228232
#[derive(Debug, Error)]
229233
pub enum LightningError {
230-
/// Error that occurred while connecting to a Lightning node
234+
/// Error that occurred while connecting to a Lightning node.
231235
#[error("Node connection error: {0}")]
232236
ConnectionError(String),
233-
/// Error that occurred while retrieving node information
237+
/// Error that occurred while retrieving node information.
234238
#[error("Get info error: {0}")]
235239
GetInfoError(String),
236-
/// Error that occurred while sending a payment
240+
/// Error that occurred while sending a payment.
237241
#[error("Send payment error: {0}")]
238242
SendPaymentError(String),
239-
/// Error that occurred while tracking a payment
243+
/// Error that occurred while tracking a payment.
240244
#[error("Track payment error: {0}")]
241245
TrackPaymentError(String),
242-
/// Error that occurred when a payment hash is invalid
246+
/// Error that occurred when a payment hash is invalid.
243247
#[error("Invalid payment hash")]
244248
InvalidPaymentHash,
245-
/// Error that occurred while retrieving information about a specific node
249+
/// Error that occurred while retrieving information about a specific node.
246250
#[error("Get node info error: {0}")]
247251
GetNodeInfoError(String),
248-
/// Error that occurred during configuration validation
252+
/// Error that occurred during configuration validation.
249253
#[error("Config validation failed: {0}")]
250254
ValidationError(String),
251-
/// Error that represents a permanent failure condition
255+
/// Error that represents a permanent failure condition.
252256
#[error("Permanent error: {0:?}")]
253257
PermanentError(String),
254-
/// Error that occurred while listing channels
258+
/// Error that occurred while listing channels.
255259
#[error("List channels error: {0}")]
256260
ListChannelsError(String),
257261
}
258262

259263
/// Information about a Lightning Network node.
260-
/// - Alias: A human-readable name for the node
264+
/// - Alias: A human-readable name for the node.
261265
/// - Features: The node's supported protocol features and capabilities, used to determine compatibility
262266
/// and available functionality. In CLN, features are stored as big-endian bytes, while in LND they are
263267
/// stored as a set of feature flags converted to little-endian bytes.
264268
#[derive(Debug, Clone)]
265269
pub struct NodeInfo {
266-
/// The node's public key
270+
/// The node's public key.
267271
pub pubkey: PublicKey,
268-
/// A human-readable name for the node (may be empty)
272+
/// A human-readable name for the node (may be empty).
269273
pub alias: String,
270-
/// The node's supported protocol features and capabilities
274+
/// The node's supported protocol features and capabilities.
271275
pub features: NodeFeatures,
272276
}
273277

@@ -288,7 +292,7 @@ impl Display for NodeInfo {
288292
pub trait LightningNode: Send {
289293
/// Get information about the node.
290294
fn get_info(&self) -> &NodeInfo;
291-
/// Get the network this node is running at
295+
/// Get the network this node is running at.
292296
async fn get_network(&mut self) -> Result<Network, LightningError>;
293297
/// Keysend payment worth `amount_msat` from a source node to the destination node.
294298
async fn send_payment(
@@ -302,7 +306,7 @@ pub trait LightningNode: Send {
302306
hash: &PaymentHash,
303307
shutdown: Listener,
304308
) -> Result<PaymentResult, LightningError>;
305-
/// Gets information on a specific node
309+
/// Gets information on a specific node.
306310
async fn get_node_info(&mut self, node_id: &PublicKey) -> Result<NodeInfo, LightningError>;
307311
/// Lists all channels, at present only returns a vector of channel capacities in msat because no further
308312
/// information is required.
@@ -315,14 +319,6 @@ pub trait LightningNode: Send {
315319
pub struct DestinationGenerationError(String);
316320

317321
/// A trait for selecting destination nodes for payments in the Lightning Network.
318-
///
319-
/// This trait is responsible for choosing appropriate destination nodes from the existing network
320-
/// for payments to be sent to. The selection can be based on different strategies:
321-
/// - Predefined destinations (for deterministic payment patterns)
322-
/// - Random selection weighted by node capacity
323-
///
324-
/// The trait works with existing nodes in the network and is used in conjunction with
325-
/// the `PaymentGenerator` trait to create complete payment flows.
326322
pub trait DestinationGenerator: Send {
327323
/// choose_destination picks a destination node within the network, returning the node's information and its
328324
/// capacity (if available).
@@ -338,22 +334,13 @@ pub trait DestinationGenerator: Send {
338334
pub struct PaymentGenerationError(String);
339335

340336
/// A trait for generating payment parameters in the Lightning Network.
341-
///
342-
/// This trait is responsible for determining when and how payments should be made,
343-
/// including timing, amounts, and frequency. It can be used to implement various
344-
/// payment strategies, from simple periodic payments to more complex patterns
345-
/// with random timing and amounts.
346-
///
347337
pub trait PaymentGenerator: Display + Send {
348-
/// Returns the time that the payments should start
338+
/// Returns the time that the payments should start.
349339
fn payment_start(&self) -> Option<Duration>;
350340

351341
/// Returns the number of payments that should be made.
352-
///
353-
/// # Returns
354-
///
355-
/// * `Some(u64)` - The exact number of payments to make
356-
/// * `None` - Payments should continue indefinitely
342+
/// Returns `Some(n)` if there's a limit on the number of payments to dispatch,
343+
/// or `None` otherwise.
357344
fn payment_count(&self) -> Option<u64>;
358345

359346
/// Returns the number of seconds that a node should wait until firing its next payment.
@@ -381,12 +368,7 @@ pub struct PaymentResult {
381368
impl PaymentResult {
382369
/// Creates a new PaymentResult indicating that the payment was never dispatched.
383370
/// This is used when there was an error during the initial payment dispatch attempt.
384-
///(e.g., insufficient balance, invalid destination)
385-
///
386-
/// # Returns
387-
/// A PaymentResult with:
388-
/// - htlc_count: 0 (no HTLCs used since payment wasn't dispatched)
389-
/// - payment_outcome: NotDispatched
371+
/// (e.g., insufficient balance, invalid destination) with [`PaymentOutcome::NotDispatched`].
390372
pub fn not_dispatched() -> Self {
391373
PaymentResult {
392374
htlc_count: 0,
@@ -396,12 +378,7 @@ impl PaymentResult {
396378

397379
/// Creates a new PaymentResult indicating that tracking the payment failed.
398380
/// This is used when the payment was dispatched but the system was unable to
399-
/// determine its final outcome (e.g., due to connection issues or timeouts).
400-
///
401-
/// # Returns
402-
/// A PaymentResult with:
403-
/// - htlc_count: 0 (unknown since tracking failed)
404-
/// - payment_outcome: TrackPaymentFailed
381+
/// determine its final outcome (e.g., due to connection issues or timeouts) with [`PaymentOutcome::TrackPaymentFailed`].
405382
pub fn track_payment_failed() -> Self {
406383
PaymentResult {
407384
htlc_count: 0,
@@ -423,29 +400,29 @@ impl Display for PaymentResult {
423400
/// Represents all possible outcomes of a Lightning Network payment attempt.
424401
#[derive(Debug, Clone, Serialize, Deserialize)]
425402
pub enum PaymentOutcome {
426-
/// Payment completed successfully, reaching its intended recipient
403+
/// Payment completed successfully, reaching its intended recipient.
427404
Success,
428-
/// The recipient rejected the payment
405+
/// The recipient rejected the payment.
429406
RecipientRejected,
430-
/// The payment was cancelled by the sending user before completion
407+
/// The payment was cancelled by the sending user before completion.
431408
UserAbandoned,
432-
/// The payment failed after exhausting all retry attempts
409+
/// The payment failed after exhausting all retry attempts.
433410
RetriesExhausted,
434-
/// The payment expired before it could complete (e.g., HTLC timeout)
411+
/// The payment expired before it could complete (e.g., HTLC timeout).
435412
PaymentExpired,
436-
/// No viable route could be found to the destination node
413+
/// No viable route could be found to the destination node.
437414
RouteNotFound,
438-
/// An unexpected error occurred during payment processing
415+
/// An unexpected error occurred during payment processing.
439416
UnexpectedError,
440-
/// The payment failed due to incorrect payment details (e.g., wrong invoice amount)
417+
/// The payment failed due to incorrect payment details (e.g., wrong invoice amount).
441418
IncorrectPaymentDetails,
442-
/// The sending node has insufficient balance to complete the payment
419+
/// The sending node has insufficient balance to complete/dispatch the payment.
443420
InsufficientBalance,
444-
/// The payment failed for an unknown reason
421+
/// The payment failed for an unknown reason.
445422
Unknown,
446-
/// The payment was never dispatched due to an error during initial sending
423+
/// The payment was never dispatched due to an error during initial sending.
447424
NotDispatched,
448-
/// The payment was dispatched but its final status could not be determined
425+
/// The payment was dispatched but its final status could not be determined.
449426
TrackPaymentFailed,
450427
}
451428

@@ -570,7 +547,6 @@ impl SimulationCfg {
570547
/// A Lightning Network payment simulator that manages payment flows between nodes.
571548
/// The simulator can execute both predefined payment patterns and generate random payment activity
572549
/// based on configuration parameters.
573-
///
574550
#[derive(Clone)]
575551
pub struct Simulation {
576552
/// Config for the simulation itself.

0 commit comments

Comments
 (0)