@@ -291,6 +291,8 @@ pub struct ChannelManager {
291
291
}
292
292
293
293
const CLTV_EXPIRY_DELTA : u16 = 6 * 24 * 2 ; //TODO?
294
+ const CLTV_FAR_FAR_AWAY : u16 = 6 * 24 * 7 ; //TODO?
295
+ const FINAL_NODE_TIMEOUT : u16 = 3 ; //TODO?
294
296
295
297
macro_rules! secp_call {
296
298
( $res: expr, $err: expr ) => {
@@ -878,12 +880,15 @@ impl ChannelManager {
878
880
879
881
let pending_forward_info = if next_hop_data. hmac == [ 0 ; 32 ] {
880
882
// OUR PAYMENT!
881
- if next_hop_data . data . amt_to_forward != msg . amount_msat {
882
- return_err ! ( "Upstream node sent less than we were supposed to receive in payment " , 19 , & byte_utils :: be64_to_array ( msg . amount_msat ) ) ;
883
+ if ( msg . cltv_expiry as u64 ) < self . latest_block_height . load ( Ordering :: Acquire ) as u64 + FINAL_NODE_TIMEOUT as u64 { // final_expiry_too_soon
884
+ return_err ! ( "The CLTV expiry is too soon to handle " , 17 , & [ 0 ; 0 ] ) ;
883
885
}
884
886
if next_hop_data. data . outgoing_cltv_value != msg. cltv_expiry {
885
887
return_err ! ( "Upstream node set CLTV to the wrong value" , 18 , & byte_utils:: be32_to_array( msg. cltv_expiry) ) ;
886
888
}
889
+ if next_hop_data. data . amt_to_forward != msg. amount_msat {
890
+ return_err ! ( "Upstream node sent less than we were supposed to receive in payment" , 19 , & byte_utils:: be64_to_array( msg. amount_msat) ) ;
891
+ }
887
892
888
893
// Note that we could obviously respond immediately with an update_fulfill_htlc
889
894
// message, however that would leak that we are the recipient of this payment, so
@@ -945,29 +950,51 @@ impl ChannelManager {
945
950
if onion_packet. is_some ( ) { // If short_channel_id is 0 here, we'll reject them in the body here
946
951
let id_option = channel_state. as_ref ( ) . unwrap ( ) . short_to_id . get ( & short_channel_id) . cloned ( ) ;
947
952
let forwarding_id = match id_option {
948
- None => {
953
+ None => { // unknown_next_peer
949
954
return_err ! ( "Don't have available channel for forwarding as requested." , 0x4000 | 10 , & [ 0 ; 0 ] ) ;
950
955
} ,
951
956
Some ( id) => id. clone ( ) ,
952
957
} ;
953
- if let Some ( ( err, code, chan_update) ) = {
958
+ if let Some ( ( err, code, chan_update) ) = loop {
954
959
let chan = channel_state. as_mut ( ) . unwrap ( ) . by_id . get_mut ( & forwarding_id) . unwrap ( ) ;
955
- if !chan. is_live ( ) {
956
- Some ( ( "Forwarding channel is not in a ready state." , 0x1000 | 7 , self . get_channel_update ( chan) . unwrap ( ) ) )
957
- } else {
958
- let fee = amt_to_forward. checked_mul ( self . fee_proportional_millionths as u64 ) . and_then ( |prop_fee| { ( prop_fee / 1000000 ) . checked_add ( chan. get_our_fee_base_msat ( & * self . fee_estimator ) as u64 ) } ) ;
959
- if fee. is_none ( ) || msg. amount_msat < fee. unwrap ( ) || ( msg. amount_msat - fee. unwrap ( ) ) < * amt_to_forward {
960
- Some ( ( "Prior hop has deviated from specified fees parameters or origin node has obsolete ones" , 0x1000 | 12 , self . get_channel_update ( chan) . unwrap ( ) ) )
961
- } else {
962
- if ( msg. cltv_expiry as u64 ) < ( * outgoing_cltv_value) as u64 + CLTV_EXPIRY_DELTA as u64 {
963
- Some ( ( "Forwarding node has tampered with the intended HTLC values or origin node has an obsolete cltv_expiry_delta" , 0x1000 | 13 , self . get_channel_update ( chan) . unwrap ( ) ) )
964
- } else {
965
- None
966
- }
967
- }
960
+
961
+ if !chan. is_live ( ) { // temporary_channel_failure
962
+ break Some ( ( "Forwarding channel is not in a ready state." , 0x1000 | 7 , self . get_channel_update ( chan) . unwrap ( ) ) ) ;
963
+ }
964
+ if * amt_to_forward < chan. get_their_htlc_minimum_msat ( ) { // amount_below_minimum
965
+ break Some ( ( "HTLC amount was below the htlc_minimum_msat" , 0x1000 | 11 , self . get_channel_update ( chan) . unwrap ( ) ) ) ;
966
+ }
967
+ let fee = amt_to_forward. checked_mul ( self . fee_proportional_millionths as u64 ) . and_then ( |prop_fee| { ( prop_fee / 1000000 ) . checked_add ( chan. get_our_fee_base_msat ( & * self . fee_estimator ) as u64 ) } ) ;
968
+ if fee. is_none ( ) || msg. amount_msat < fee. unwrap ( ) || ( msg. amount_msat - fee. unwrap ( ) ) < * amt_to_forward { // fee_insufficient
969
+ break Some ( ( "Prior hop has deviated from specified fees parameters or origin node has obsolete ones" , 0x1000 | 12 , self . get_channel_update ( chan) . unwrap ( ) ) ) ;
968
970
}
969
- } {
970
- return_err ! ( err, code, & chan_update. encode_with_len( ) [ ..] ) ;
971
+ if ( msg. cltv_expiry as u64 ) < ( * outgoing_cltv_value) as u64 + CLTV_EXPIRY_DELTA as u64 { // incorrect_cltv_expiry
972
+ break Some ( ( "Forwarding node has tampered with the intended HTLC values or origin node has an obsolete cltv_expiry_delta" , 0x1000 | 13 , self . get_channel_update ( chan) . unwrap ( ) ) ) ;
973
+ }
974
+ let cur_height = self . latest_block_height . load ( Ordering :: Acquire ) as u32 + 1 ;
975
+ if msg. cltv_expiry <= cur_height + CLTV_EXPIRY_DELTA as u32 { // expiry_too_soon
976
+ break Some ( ( "CLTV expiry is too close" , 0x1000 | 14 , self . get_channel_update ( chan) . unwrap ( ) ) ) ;
977
+ }
978
+ /*
979
+ if chan.is_disabled() {
980
+ break Some(("Forwarding channel has been disabled.", 0x1000 | 20, self.get_channel_update(chan).unwrap()));
981
+ }
982
+ */
983
+ if msg. cltv_expiry > cur_height + CLTV_FAR_FAR_AWAY as u32 { // expiry_too_far
984
+ break Some ( ( "CLTV expiry is too far in the future" , 0x1000 | 21 , self . get_channel_update ( chan) . unwrap ( ) ) ) ;
985
+ }
986
+ break None ;
987
+ }
988
+ {
989
+ let mut res = Vec :: with_capacity ( 8 + 128 ) ;
990
+ if code == 0x1000 | 11 || code == 0x1000 | 12 {
991
+ res. extend_from_slice ( & byte_utils:: be64_to_array ( * amt_to_forward) ) ;
992
+ }
993
+ else if code == 0x1000 | 13 {
994
+ res. extend_from_slice ( & byte_utils:: be32_to_array ( msg. cltv_expiry ) ) ;
995
+ }
996
+ res. extend_from_slice ( & chan_update. encode_with_len ( ) [ ..] ) ;
997
+ return_err ! ( err, code, & res[ ..] ) ;
971
998
}
972
999
}
973
1000
}
@@ -1318,6 +1345,11 @@ impl ChannelManager {
1318
1345
} else { false }
1319
1346
}
1320
1347
1348
+ /// Indicates that the amount for payment_hash is incorrect after a PaymentReceived event.
1349
+ pub fn fail_htlc_backwards_incorrect_payment_amount ( & self , payment_hash : & [ u8 ; 32 ] ) -> bool {
1350
+ self . fail_htlc_backwards_internal ( self . channel_state . lock ( ) . unwrap ( ) , payment_hash, HTLCFailReason :: Reason { failure_code : 0x4000 | 16 , data : Vec :: new ( ) } )
1351
+ }
1352
+
1321
1353
/// Fails an HTLC backwards to the sender of it to us.
1322
1354
/// Note that while we take a channel_state lock as input, we do *not* assume consistency here.
1323
1355
/// There are several callsites that do stupid things like loop over a list of payment_hashes
@@ -4245,6 +4277,8 @@ mod tests {
4245
4277
assert_eq ! ( nodes[ 2 ] . node. list_channels( ) . len( ) , 0 ) ;
4246
4278
assert_eq ! ( nodes[ 3 ] . node. list_channels( ) . len( ) , 1 ) ;
4247
4279
4280
+ let header = BlockHeader { version : 0x20000000 , prev_blockhash : Default :: default ( ) , merkle_root : Default :: default ( ) , time : 42 , bits : 42 , nonce : 42 } ;
4281
+ nodes[ 4 ] . chain_monitor . block_connected_with_filtering ( & Block { header, txdata : vec ! [ ] } , 1 ) ;
4248
4282
// One pending HTLC to time out:
4249
4283
let payment_preimage_2 = route_payment ( & nodes[ 3 ] , & vec ! ( & nodes[ 4 ] ) [ ..] , 3000000 ) . 0 ;
4250
4284
0 commit comments