@@ -15,6 +15,7 @@ use lightning::util::logger::{Level, Logger, Record};
15
15
use std:: collections:: hash_map:: Entry ;
16
16
use std:: collections:: HashMap ;
17
17
use std:: sync:: Arc ;
18
+ use thiserror:: Error ;
18
19
use tokio:: select;
19
20
use tokio:: sync:: oneshot:: { channel, Receiver , Sender } ;
20
21
use tokio:: sync:: Mutex ;
@@ -25,42 +26,73 @@ use crate::ShortChannelID;
25
26
/// ForwardingError represents the various errors that we can run into when forwarding payments in a simulated network.
26
27
/// Since we're not using real lightning nodes, these errors are not obfuscated and can be propagated to the sending
27
28
/// node and used for analysis.
28
- #[ derive( Debug ) ]
29
+ #[ derive( Debug , Error ) ]
29
30
pub enum ForwardingError {
30
31
/// Zero amount htlcs are invalid in the protocol.
32
+ #[ error( "ZeroAmountHtlc" ) ]
31
33
ZeroAmountHtlc ,
32
34
/// The outgoing channel id was not found in the network graph.
35
+ #[ error( "ChannelNotFound: {0}" ) ]
33
36
ChannelNotFound ( ShortChannelID ) ,
34
37
/// The node pubkey provided was not associated with the channel in the network graph.
38
+ #[ error( "NodeNotFound: {0:?}" ) ]
35
39
NodeNotFound ( PublicKey ) ,
36
40
/// The channel has already forwarded an HTLC with the payment hash provided.
37
41
/// TODO: remove if MPP support is added.
42
+ #[ error( "PaymentHashExists: {0:?}" ) ]
38
43
PaymentHashExists ( PaymentHash ) ,
39
44
/// An htlc with the payment hash provided could not be found to resolve.
45
+ #[ error( "PaymentHashNotFound: {0:?}" ) ]
40
46
PaymentHashNotFound ( PaymentHash ) ,
41
47
/// The forwarding node did not have sufficient outgoing balance to forward the htlc (htlc amount / balance).
48
+ #[ error( "InsufficientBalance: amount: {0} > balance: {1}" ) ]
42
49
InsufficientBalance ( u64 , u64 ) ,
43
50
/// The htlc forwarded is less than the channel's advertised minimum htlc amount (htlc amount / minimum).
51
+ #[ error( "LessThanMinimum: amount: {0} < minimum: {1}" ) ]
44
52
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}" ) ]
46
55
MoreThanMaximum ( u64 , u64 ) ,
47
56
/// 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}" ) ]
48
58
ExceedsInFlightCount ( u64 , u64 ) ,
49
59
/// The forwarded htlc's amount would push the channel over its maximum allowable in flight total
50
60
/// (total in flight / maximum).
61
+ #[ error( "ExceedsInFlightTotal: total in flight amount: {0} > maximum amount: {0}" ) ]
51
62
ExceedsInFlightTotal ( u64 , u64 ) ,
52
63
/// 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}" ) ]
53
65
ExpiryInSeconds ( u32 , u32 ) ,
54
66
/// The forwarded htlc has insufficient cltv delta for the channel's minimum delta (cltv delta / minimum).
67
+ #[ error( "InsufficientCltvDelta: cltv delta: {0} < required: {1}" ) ]
55
68
InsufficientCltvDelta ( u32 , u32 ) ,
56
69
/// 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}" ) ]
57
71
InsufficientFee ( u64 , u64 , u64 , u64 ) ,
58
72
/// 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})" ) ]
59
74
FeeOverflow ( u64 , u64 , u64 ) ,
60
75
/// Sanity check on channel balances failed (node balances / channel capacity).
76
+ #[ error( "SanityCheckFailed: node balance: {0} != capacity: {1}" ) ]
61
77
SanityCheckFailed ( u64 , u64 ) ,
62
78
}
63
79
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
+
64
96
/// Represents an in-flight htlc that has been forwarded over a channel that is awaiting resolution.
65
97
#[ derive( Copy , Clone ) ]
66
98
struct Htlc {
0 commit comments