@@ -221,6 +221,16 @@ impl MsgHandleErrInternal {
221
221
}
222
222
}
223
223
224
+ /// Pass to fail_htlc_backwwards to indicate the reason to fail the payment
225
+ /// after a PaymentReceived event.
226
+ #[ derive( PartialEq ) ]
227
+ pub enum PaymentFailReason {
228
+ /// Indicate the preimage for payment_hash is not known after a PaymentReceived event
229
+ PreimageUnknown ,
230
+ /// Indicate the payment amount is incorrect ( received is < expected or > 2*expected ) after a PaymentReceived event
231
+ AmountMismatch ,
232
+ }
233
+
224
234
/// We hold back HTLCs we intend to relay for a random interval in the range (this, 5*this). This
225
235
/// provides some limited amount of privacy. Ideally this would range from somewhere like 1 second
226
236
/// to 30 seconds, but people expect lightning to be, you know, kinda fast, sadly. We could
@@ -1393,16 +1403,14 @@ impl ChannelManager {
1393
1403
events. append ( & mut new_events) ;
1394
1404
}
1395
1405
1396
- /// Indicates that the preimage for payment_hash is unknown after a PaymentReceived event.
1397
- pub fn fail_htlc_backwards ( & self , payment_hash : & [ u8 ; 32 ] ) -> bool {
1398
- // TODO: Add ability to return 0x4000|16 (incorrect_payment_amount) if the amount we
1399
- // received is < expected or > 2*expected
1406
+ /// Indicates that the preimage for payment_hash is unknown or the received amount is incorrect after a PaymentReceived event.
1407
+ pub fn fail_htlc_backwards ( & self , payment_hash : & [ u8 ; 32 ] , reason : PaymentFailReason ) -> bool {
1400
1408
let mut channel_state = Some ( self . channel_state . lock ( ) . unwrap ( ) ) ;
1401
1409
let removed_source = channel_state. as_mut ( ) . unwrap ( ) . claimable_htlcs . remove ( payment_hash) ;
1402
1410
if let Some ( mut sources) = removed_source {
1403
1411
for htlc_with_hash in sources. drain ( ..) {
1404
1412
if channel_state. is_none ( ) { channel_state = Some ( self . channel_state . lock ( ) . unwrap ( ) ) ; }
1405
- self . fail_htlc_backwards_internal ( channel_state. take ( ) . unwrap ( ) , HTLCSource :: PreviousHopData ( htlc_with_hash) , payment_hash, HTLCFailReason :: Reason { failure_code : 0x4000 | 15 , data : Vec :: new ( ) } ) ;
1413
+ self . fail_htlc_backwards_internal ( channel_state. take ( ) . unwrap ( ) , HTLCSource :: PreviousHopData ( htlc_with_hash) , payment_hash, HTLCFailReason :: Reason { failure_code : if reason == PaymentFailReason :: PreimageUnknown { 0x4000 | 15 } else { 0x4000 | 16 } , data : Vec :: new ( ) } ) ;
1406
1414
}
1407
1415
true
1408
1416
} else { false }
@@ -2677,7 +2685,7 @@ mod tests {
2677
2685
use chain:: chaininterface;
2678
2686
use chain:: transaction:: OutPoint ;
2679
2687
use chain:: chaininterface:: ChainListener ;
2680
- use ln:: channelmanager:: { ChannelManager , OnionKeys } ;
2688
+ use ln:: channelmanager:: { ChannelManager , OnionKeys , PaymentFailReason } ;
2681
2689
use ln:: channelmonitor:: { ChannelMonitorUpdateErr , CLTV_CLAIM_BUFFER , HTLC_FAIL_TIMEOUT_BLOCKS } ;
2682
2690
use ln:: router:: { Route , RouteHop , Router } ;
2683
2691
use ln:: msgs;
@@ -3368,7 +3376,7 @@ mod tests {
3368
3376
}
3369
3377
3370
3378
fn fail_payment_along_route ( origin_node : & Node , expected_route : & [ & Node ] , skip_last : bool , our_payment_hash : [ u8 ; 32 ] ) {
3371
- assert ! ( expected_route. last( ) . unwrap( ) . node. fail_htlc_backwards( & our_payment_hash) ) ;
3379
+ assert ! ( expected_route. last( ) . unwrap( ) . node. fail_htlc_backwards( & our_payment_hash, PaymentFailReason :: PreimageUnknown ) ) ;
3372
3380
check_added_monitors ! ( expected_route. last( ) . unwrap( ) , 1 ) ;
3373
3381
3374
3382
let mut next_msgs: Option < ( msgs:: UpdateFailHTLC , msgs:: CommitmentSigned ) > = None ;
0 commit comments