Skip to content

Commit 1c16702

Browse files
authored
Merge pull request #241 from sangbida/sangbida/docs
Update simln-lib docs
2 parents dda35c1 + 0bebc63 commit 1c16702

File tree

2 files changed

+100
-7
lines changed

2 files changed

+100
-7
lines changed

simln-lib/README.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# sim-ln
2+
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.
4+
5+
## Overview
6+
7+
sim-ln provides a framework for simulating Lightning Network payment routing behavior, allowing developers and researchers to:
8+
9+
- Generate specific or random traffic patterns on a provided Lightning graph.
10+
- Test payment routing strategies.
11+
- Analyze network behavior under different conditions.
12+
13+
## Usage
14+
15+
Add sim-ln to your Cargo.toml:
16+
17+
```toml
18+
[dependencies]
19+
sim-ln = "0.1.0"
20+
```

simln-lib/src/lib.rs

Lines changed: 80 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#![deny(rustdoc::broken_intra_doc_links)]
2+
13
use async_trait::async_trait;
24
use bitcoin::secp256k1::PublicKey;
35
use bitcoin::Network;
@@ -35,13 +37,18 @@ pub mod serializers;
3537
pub mod sim_node;
3638
mod test_utils;
3739

40+
/// Represents a node id, either by its public key or alias.
3841
#[derive(Serialize, Debug, Clone)]
3942
pub enum NodeId {
43+
/// The node's public key.
4044
PublicKey(PublicKey),
45+
/// The node's alias (human-readable name).
4146
Alias(String),
4247
}
4348

4449
impl NodeId {
50+
/// Validates that the provided node id matches the one returned by the backend. If the node id is an alias,
51+
/// it will be updated to the one returned by the backend if there is a mismatch.
4552
pub fn validate(&self, node_id: &PublicKey, alias: &mut String) -> Result<(), LightningError> {
4653
match self {
4754
crate::NodeId::PublicKey(pk) => {
@@ -66,6 +73,7 @@ impl NodeId {
6673
Ok(())
6774
}
6875

76+
/// Returns the public key of the node if it is a public key node id.
6977
pub fn get_pk(&self) -> Result<&PublicKey, String> {
7078
if let NodeId::PublicKey(pk) = self {
7179
Ok(pk)
@@ -92,21 +100,21 @@ impl std::fmt::Display for NodeId {
92100
#[derive(Debug, Clone, PartialEq, Eq, Hash, Copy)]
93101
pub struct ShortChannelID(u64);
94102

95-
/// Utility function to easily convert from u64 to `ShortChannelID`
103+
/// Utility function to easily convert from u64 to `ShortChannelID`.
96104
impl From<u64> for ShortChannelID {
97105
fn from(value: u64) -> Self {
98106
ShortChannelID(value)
99107
}
100108
}
101109

102-
/// Utility function to easily convert `ShortChannelID` into u64
110+
/// Utility function to easily convert `ShortChannelID` into u64.
103111
impl From<ShortChannelID> for u64 {
104112
fn from(scid: ShortChannelID) -> Self {
105113
scid.0
106114
}
107115
}
108116

109-
/// See https://github.com/lightning/bolts/blob/60de4a09727c20dea330f9ee8313034de6e50594/07-routing-gossip.md#definition-of-short_channel_id.
117+
/// See <https://github.com/lightning/bolts/blob/60de4a09727c20dea330f9ee8313034de6e50594/07-routing-gossip.md#definition-of-short_channel_id>
110118
impl std::fmt::Display for ShortChannelID {
111119
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
112120
write!(
@@ -123,7 +131,9 @@ impl std::fmt::Display for ShortChannelID {
123131
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
124132
#[serde(untagged)]
125133
pub enum ValueOrRange<T> {
134+
/// A single fixed value.
126135
Value(T),
136+
/// A range [min, max) from which values are randomly sampled.
127137
Range(T, T),
128138
}
129139

@@ -178,58 +188,87 @@ pub struct ActivityDefinition {
178188
pub amount_msat: Amount,
179189
}
180190

191+
/// Represents errors that can occur during simulation execution.
181192
#[derive(Debug, Error)]
182193
pub enum SimulationError {
194+
/// Error that occurred during Lightning Network operations.
183195
#[error("Lightning Error: {0:?}")]
184196
LightningError(#[from] LightningError),
197+
/// Error that occurred during task execution.
185198
#[error("TaskError")]
186199
TaskError,
200+
/// Error that occurred while writing CSV data.
187201
#[error("CSV Error: {0:?}")]
188202
CsvError(#[from] csv::Error),
203+
/// Error that occurred during file operations.
189204
#[error("File Error")]
190205
FileError,
206+
/// Error that occurred during random activity generation.
191207
#[error("{0}")]
192208
RandomActivityError(RandomActivityError),
209+
/// Error that occurred in the simulated network.
193210
#[error("Simulated Network Error: {0}")]
194211
SimulatedNetworkError(String),
212+
/// Error that occurred while accessing system time.
195213
#[error("System Time Error: {0}")]
196214
SystemTimeError(#[from] SystemTimeError),
215+
/// Error that occurred when a required node was not found.
197216
#[error("Missing Node Error: {0}")]
198217
MissingNodeError(String),
218+
/// Error that occurred in message passing channels.
199219
#[error("Mpsc Channel Error: {0}")]
200220
MpscChannelError(String),
221+
/// Error that occurred while generating payment parameters.
201222
#[error("Payment Generation Error: {0}")]
202223
PaymentGenerationError(PaymentGenerationError),
224+
/// Error that occurred while generating destination nodes.
203225
#[error("Destination Generation Error: {0}")]
204226
DestinationGenerationError(DestinationGenerationError),
205227
}
206228

229+
/// Represents errors that can occur during Lightning Network operations.
207230
#[derive(Debug, Error)]
208231
pub enum LightningError {
232+
/// Error that occurred while connecting to a Lightning node.
209233
#[error("Node connection error: {0}")]
210234
ConnectionError(String),
235+
/// Error that occurred while retrieving node information.
211236
#[error("Get info error: {0}")]
212237
GetInfoError(String),
238+
/// Error that occurred while sending a payment.
213239
#[error("Send payment error: {0}")]
214240
SendPaymentError(String),
241+
/// Error that occurred while tracking a payment.
215242
#[error("Track payment error: {0}")]
216243
TrackPaymentError(String),
244+
/// Error that occurred when a payment hash is invalid.
217245
#[error("Invalid payment hash")]
218246
InvalidPaymentHash,
247+
/// Error that occurred while retrieving information about a specific node.
219248
#[error("Get node info error: {0}")]
220249
GetNodeInfoError(String),
250+
/// Error that occurred during configuration validation.
221251
#[error("Config validation failed: {0}")]
222252
ValidationError(String),
253+
/// Error that represents a permanent failure condition.
223254
#[error("Permanent error: {0:?}")]
224255
PermanentError(String),
256+
/// Error that occurred while listing channels.
225257
#[error("List channels error: {0}")]
226258
ListChannelsError(String),
227259
}
228260

261+
/// Information about a Lightning Network node.
262+
/// - Alias: A human-readable name for the node.
263+
/// - Features: The node's supported protocol features and capabilities,
264+
/// used to determine compatibility and available
229265
#[derive(Debug, Clone)]
230266
pub struct NodeInfo {
267+
/// The node's public key.
231268
pub pubkey: PublicKey,
269+
/// A human-readable name for the node (may be empty).
232270
pub alias: String,
271+
/// The node's supported protocol features and capabilities.
233272
pub features: NodeFeatures,
234273
}
235274

@@ -250,7 +289,7 @@ impl Display for NodeInfo {
250289
pub trait LightningNode: Send {
251290
/// Get information about the node.
252291
fn get_info(&self) -> &NodeInfo;
253-
/// Get the network this node is running at
292+
/// Get the network this node is running at.
254293
async fn get_network(&mut self) -> Result<Network, LightningError>;
255294
/// Keysend payment worth `amount_msat` from a source node to the destination node.
256295
async fn send_payment(
@@ -264,17 +303,19 @@ pub trait LightningNode: Send {
264303
hash: &PaymentHash,
265304
shutdown: Listener,
266305
) -> Result<PaymentResult, LightningError>;
267-
/// Gets information on a specific node
306+
/// Gets information on a specific node.
268307
async fn get_node_info(&mut self, node_id: &PublicKey) -> Result<NodeInfo, LightningError>;
269308
/// Lists all channels, at present only returns a vector of channel capacities in msat because no further
270309
/// information is required.
271310
async fn list_channels(&mut self) -> Result<Vec<u64>, LightningError>;
272311
}
273312

313+
/// Represents an error that occurs when generating a destination for a payment.
274314
#[derive(Debug, Error)]
275315
#[error("Destination generation error: {0}")]
276316
pub struct DestinationGenerationError(String);
277317

318+
/// A trait for selecting destination nodes for payments in the Lightning Network.
278319
pub trait DestinationGenerator: Send {
279320
/// choose_destination picks a destination node within the network, returning the node's information and its
280321
/// capacity (if available).
@@ -284,15 +325,18 @@ pub trait DestinationGenerator: Send {
284325
) -> Result<(NodeInfo, Option<u64>), DestinationGenerationError>;
285326
}
286327

328+
/// Represents an error that occurs when generating payments.
287329
#[derive(Debug, Error)]
288330
#[error("Payment generation error: {0}")]
289331
pub struct PaymentGenerationError(String);
290332

333+
/// A trait for generating payment parameters in the Lightning Network.
291334
pub trait PaymentGenerator: Display + Send {
292-
/// Returns the time that the payments should start
335+
/// Returns the time that the payments should start.
293336
fn payment_start(&self) -> Option<Duration>;
294337

295-
/// Returns the number of payments that should be made
338+
/// Returns the number of payments that should be made.
339+
/// Returns `Some(n)` if there's a limit on the number of payments to dispatch, or `None` otherwise.
296340
fn payment_count(&self) -> Option<u64>;
297341

298342
/// Returns the number of seconds that a node should wait until firing its next payment.
@@ -305,20 +349,32 @@ pub trait PaymentGenerator: Display + Send {
305349
) -> Result<u64, PaymentGenerationError>;
306350
}
307351

352+
/// Represents the result of a payment attempt.
308353
#[derive(Debug, Clone, Serialize, Deserialize)]
309354
pub struct PaymentResult {
355+
/// The number of HTLCs (Hash Time Locked Contracts) used in the payment attempt.
356+
/// Multiple HTLCs may be used for a single payment when using techniques like multi-part payments or when
357+
/// retrying failed payment paths.
310358
pub htlc_count: usize,
359+
/// The final outcome of the payment attempt, indicating whether it succeeded or failed
360+
/// (and if failed, the reason for failure).
311361
pub payment_outcome: PaymentOutcome,
312362
}
313363

314364
impl PaymentResult {
365+
/// Creates a new PaymentResult indicating that the payment was never dispatched. This is used when there was an
366+
/// error during the initial payment dispatch attempt (e.g., insufficient balance, invalid destination) with
367+
/// [`PaymentOutcome::NotDispatched`].
315368
pub fn not_dispatched() -> Self {
316369
PaymentResult {
317370
htlc_count: 0,
318371
payment_outcome: PaymentOutcome::NotDispatched,
319372
}
320373
}
321374

375+
/// Creates a new PaymentResult indicating that tracking the payment failed. This is used when the payment was
376+
/// dispatched but the system was unable to determine its final outcome (e.g. due to connection issues or timeouts)
377+
/// with [`PaymentOutcome::TrackPaymentFailed`].
322378
pub fn track_payment_failed() -> Self {
323379
PaymentResult {
324380
htlc_count: 0,
@@ -337,19 +393,32 @@ impl Display for PaymentResult {
337393
}
338394
}
339395

396+
/// Represents all possible outcomes of a Lightning Network payment attempt.
340397
#[derive(Debug, Clone, Serialize, Deserialize)]
341398
pub enum PaymentOutcome {
399+
/// Payment completed successfully, reaching its intended recipient.
342400
Success,
401+
/// The recipient rejected the payment.
343402
RecipientRejected,
403+
/// The payment was cancelled by the sending user before completion.
344404
UserAbandoned,
405+
/// The payment failed after exhausting all retry attempts.
345406
RetriesExhausted,
407+
/// The payment expired before it could complete (e.g., HTLC timeout).
346408
PaymentExpired,
409+
/// No viable route could be found to the destination node.
347410
RouteNotFound,
411+
/// An unexpected error occurred during payment processing.
348412
UnexpectedError,
413+
/// The payment failed due to incorrect payment details (e.g., wrong invoice amount).
349414
IncorrectPaymentDetails,
415+
/// The sending node has insufficient balance to complete/dispatch the payment.
350416
InsufficientBalance,
417+
/// The payment failed for an unknown reason.
351418
Unknown,
419+
/// The payment was never dispatched due to an error during initial sending.
352420
NotDispatched,
421+
/// The payment was dispatched but its final status could not be determined.
353422
TrackPaymentFailed,
354423
}
355424

@@ -471,6 +540,9 @@ impl SimulationCfg {
471540
}
472541
}
473542

543+
/// A Lightning Network payment simulator that manages payment flows between nodes.
544+
/// The simulator can execute both predefined payment patterns and generate random payment activity
545+
/// based on configuration parameters.
474546
#[derive(Clone)]
475547
pub struct Simulation {
476548
/// Config for the simulation itself.
@@ -489,6 +561,7 @@ pub struct Simulation {
489561
shutdown_listener: Listener,
490562
}
491563

564+
/// Configuration for writing simulation results to CSV files.
492565
#[derive(Clone)]
493566
pub struct WriteResults {
494567
/// Data directory where CSV result files are written.

0 commit comments

Comments
 (0)