@@ -221,6 +221,16 @@ impl MsgHandleErrInternal {
221221 }
222222}
223223
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+
224234/// We hold back HTLCs we intend to relay for a random interval in the range (this, 5*this). This
225235/// provides some limited amount of privacy. Ideally this would range from somewhere like 1 second
226236/// to 30 seconds, but people expect lightning to be, you know, kinda fast, sadly. We could
@@ -1393,16 +1403,14 @@ impl ChannelManager {
13931403 events. append ( & mut new_events) ;
13941404 }
13951405
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 {
14001408 let mut channel_state = Some ( self . channel_state . lock ( ) . unwrap ( ) ) ;
14011409 let removed_source = channel_state. as_mut ( ) . unwrap ( ) . claimable_htlcs . remove ( payment_hash) ;
14021410 if let Some ( mut sources) = removed_source {
14031411 for htlc_with_hash in sources. drain ( ..) {
14041412 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 ( ) } ) ;
14061414 }
14071415 true
14081416 } else { false }
@@ -2677,7 +2685,7 @@ mod tests {
26772685 use chain:: chaininterface;
26782686 use chain:: transaction:: OutPoint ;
26792687 use chain:: chaininterface:: ChainListener ;
2680- use ln:: channelmanager:: { ChannelManager , OnionKeys } ;
2688+ use ln:: channelmanager:: { ChannelManager , OnionKeys , PaymentFailReason } ;
26812689 use ln:: channelmonitor:: { ChannelMonitorUpdateErr , CLTV_CLAIM_BUFFER , HTLC_FAIL_TIMEOUT_BLOCKS } ;
26822690 use ln:: router:: { Route , RouteHop , Router } ;
26832691 use ln:: msgs;
@@ -3368,7 +3376,7 @@ mod tests {
33683376 }
33693377
33703378 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 ) ) ;
33723380 check_added_monitors ! ( expected_route. last( ) . unwrap( ) , 1 ) ;
33733381
33743382 let mut next_msgs: Option < ( msgs:: UpdateFailHTLC , msgs:: CommitmentSigned ) > = None ;
0 commit comments