Skip to content

Commit b4c906a

Browse files
committed
sim_node: add display and is_critical for forwarding error
We want to be able to distinguish between expected and critical payment errors in our simulated payments. An expected error occurs due to a lightning-related failure (such as running out of liquidity), and a critical one happens because something has gone wrong with our simulator (for example, an assertion failure about balances). This commit adds an some utilities to ForwardingError to make this distinction and display errors properly.
1 parent c420b7e commit b4c906a

File tree

1 file changed

+34
-2
lines changed

1 file changed

+34
-2
lines changed

sim-lib/src/sim_node.rs

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use lightning::util::logger::{Level, Logger, Record};
1515
use std::collections::hash_map::Entry;
1616
use std::collections::HashMap;
1717
use std::sync::Arc;
18+
use thiserror::Error;
1819
use tokio::select;
1920
use tokio::sync::oneshot::{channel, Receiver, Sender};
2021
use tokio::sync::Mutex;
@@ -25,42 +26,73 @@ use crate::ShortChannelID;
2526
/// ForwardingError represents the various errors that we can run into when forwarding payments in a simulated network.
2627
/// Since we're not using real lightning nodes, these errors are not obfuscated and can be propagated to the sending
2728
/// node and used for analysis.
28-
#[derive(Debug)]
29+
#[derive(Debug, Error)]
2930
pub enum ForwardingError {
3031
/// Zero amount htlcs are invalid in the protocol.
32+
#[error("ZeroAmountHtlc")]
3133
ZeroAmountHtlc,
3234
/// The outgoing channel id was not found in the network graph.
35+
#[error("ChannelNotFound: {0}")]
3336
ChannelNotFound(ShortChannelID),
3437
/// The node pubkey provided was not associated with the channel in the network graph.
38+
#[error("NodeNotFound: {0:?}")]
3539
NodeNotFound(PublicKey),
3640
/// The channel has already forwarded an HTLC with the payment hash provided.
3741
/// TODO: remove if MPP support is added.
42+
#[error("PaymentHashExists: {0:?}")]
3843
PaymentHashExists(PaymentHash),
3944
/// An htlc with the payment hash provided could not be found to resolve.
45+
#[error("PaymentHashNotFound: {0:?}")]
4046
PaymentHashNotFound(PaymentHash),
4147
/// The forwarding node did not have sufficient outgoing balance to forward the htlc (htlc amount / balance).
48+
#[error("InsufficientBalance: amount: {0} > balance: {1}")]
4249
InsufficientBalance(u64, u64),
4350
/// The htlc forwarded is less than the channel's advertised minimum htlc amount (htlc amount / minimum).
51+
#[error("LessThanMinimum: amount: {0} < minimum: {1}")]
4452
LessThanMinimum(u64, u64),
45-
/// The htlc forwarded is more than the chanenl's advertised maximum htlc amount (htlc amount / maximum).
53+
/// The htlc forwarded is more than the channel's advertised maximum htlc amount (htlc amount / maximum).
54+
#[error("MoreThanMaximum: amount: {0} > maximum: {1}")]
4655
MoreThanMaximum(u64, u64),
4756
/// The channel has reached its maximum allowable number of htlcs in flight (total in flight / maximim).
57+
#[error("ExceedsInFlightCount: total in flight: {0} > maximum count: {1}")]
4858
ExceedsInFlightCount(u64, u64),
4959
/// The forwarded htlc's amount would push the channel over its maximum allowable in flight total
5060
/// (total in flight / maximum).
61+
#[error("ExceedsInFlightTotal: total in flight amount: {0} > maximum amount: {0}")]
5162
ExceedsInFlightTotal(u64, u64),
5263
/// The forwarded htlc's cltv expiry exceeds the maximum value used to express block heights in Bitcoin.
64+
#[error("ExpiryInSeconds: cltv expressed in seconds: {0}")]
5365
ExpiryInSeconds(u32, u32),
5466
/// The forwarded htlc has insufficient cltv delta for the channel's minimum delta (cltv delta / minimum).
67+
#[error("InsufficientCltvDelta: cltv delta: {0} < required: {1}")]
5568
InsufficientCltvDelta(u32, u32),
5669
/// The forwarded htlc has insufficient fee for the channel's policy (fee / expected fee / base fee / prop fee).
70+
#[error("InsufficientFee: offered fee: {0} (base: {1}, prop: {2}) < expected: {3}")]
5771
InsufficientFee(u64, u64, u64, u64),
5872
/// The fee policy for a htlc amount would overflow with the given fee policy (htlc amount / base fee / prop fee).
73+
#[error("FeeOverflow: htlc amount: {0} (base: {1}, prop: {2})")]
5974
FeeOverflow(u64, u64, u64),
6075
/// Sanity check on channel balances failed (node balances / channel capacity).
76+
#[error("SanityCheckFailed: node balance: {0} != capacity: {1}")]
6177
SanityCheckFailed(u64, u64),
6278
}
6379

80+
impl ForwardingError {
81+
/// Returns a boolean indicating whether failure to forward a htlc is a critical error that warrants shutdown.
82+
fn is_critical(&self) -> bool {
83+
matches!(
84+
self,
85+
ForwardingError::ZeroAmountHtlc
86+
| ForwardingError::ChannelNotFound(_)
87+
| ForwardingError::NodeNotFound(_)
88+
| ForwardingError::PaymentHashExists(_)
89+
| ForwardingError::PaymentHashNotFound(_)
90+
| ForwardingError::SanityCheckFailed(_, _)
91+
| ForwardingError::FeeOverflow(_, _, _)
92+
)
93+
}
94+
}
95+
6496
/// Represents an in-flight htlc that has been forwarded over a channel that is awaiting resolution.
6597
#[derive(Copy, Clone)]
6698
struct Htlc {

0 commit comments

Comments
 (0)