@@ -187,6 +187,8 @@ pub struct ChannelManager {
187
187
}
188
188
189
189
const CLTV_EXPIRY_DELTA : u16 = 6 * 24 * 2 ; //TODO?
190
+ const CLTV_FAR_FAR_AWAY : u16 = 6 * 24 * 7 ; //TODO?
191
+ const FINAL_NODE_TIMEOUT : u16 = 3 ; //TODO?
190
192
191
193
macro_rules! secp_call {
192
194
( $res: expr, $err_msg: expr, $action: expr ) => {
@@ -755,12 +757,15 @@ impl ChannelManager {
755
757
756
758
let pending_forward_info = if next_hop_data. hmac == [ 0 ; 32 ] {
757
759
// OUR PAYMENT!
758
- if next_hop_data . data . amt_to_forward != msg . amount_msat {
759
- return_err ! ( "Upstream node sent less than we were supposed to receive in payment " , 19 , & byte_utils :: be64_to_array ( msg . amount_msat ) ) ;
760
+ if ( msg . cltv_expiry as u64 ) < self . latest_block_height . load ( Ordering :: Acquire ) as u64 + FINAL_NODE_TIMEOUT as u64 { // final_expiry_too_soon
761
+ return_err ! ( "The CLTV expiry is too soon to handle " , 17 , & [ 0 ; 0 ] ) ;
760
762
}
761
763
if next_hop_data. data . outgoing_cltv_value != msg. cltv_expiry {
762
764
return_err ! ( "Upstream node set CLTV to the wrong value" , 18 , & byte_utils:: be32_to_array( msg. cltv_expiry) ) ;
763
765
}
766
+ if next_hop_data. data . amt_to_forward != msg. amount_msat {
767
+ return_err ! ( "Upstream node sent less than we were supposed to receive in payment" , 19 , & byte_utils:: be64_to_array( msg. amount_msat) ) ;
768
+ }
764
769
765
770
// Note that we could obviously respond immediately with an update_fulfill_htlc
766
771
// message, however that would leak that we are the recipient of this payment, so
@@ -822,29 +827,51 @@ impl ChannelManager {
822
827
if onion_packet. is_some ( ) { // If short_channel_id is 0 here, we'll reject them in the body here
823
828
let id_option = channel_state. as_ref ( ) . unwrap ( ) . short_to_id . get ( & short_channel_id) . cloned ( ) ;
824
829
let forwarding_id = match id_option {
825
- None => {
830
+ None => { // unknown_next_peer
826
831
return_err ! ( "Don't have available channel for forwarding as requested." , 0x4000 | 10 , & [ 0 ; 0 ] ) ;
827
832
} ,
828
833
Some ( id) => id. clone ( ) ,
829
834
} ;
830
- if let Some ( ( err, code, chan_update) ) = {
835
+ if let Some ( ( err, code, chan_update) ) = loop {
831
836
let chan = channel_state. as_mut ( ) . unwrap ( ) . by_id . get_mut ( & forwarding_id) . unwrap ( ) ;
832
- if !chan. is_live ( ) {
833
- Some ( ( "Forwarding channel is not in a ready state." , 0x1000 | 7 , self . get_channel_update ( chan) . unwrap ( ) ) )
834
- } else {
835
- 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 ) } ) ;
836
- if fee. is_none ( ) || msg. amount_msat < fee. unwrap ( ) || ( msg. amount_msat - fee. unwrap ( ) ) < * amt_to_forward {
837
- Some ( ( "Prior hop has deviated from specified fees parameters or origin node has obsolete ones" , 0x1000 | 12 , self . get_channel_update ( chan) . unwrap ( ) ) )
838
- } else {
839
- if ( msg. cltv_expiry as u64 ) < ( * outgoing_cltv_value) as u64 + CLTV_EXPIRY_DELTA as u64 {
840
- 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 ( ) ) )
841
- } else {
842
- None
843
- }
844
- }
837
+
838
+ if !chan. is_live ( ) { // temporary_channel_failure
839
+ break Some ( ( "Forwarding channel is not in a ready state." , 0x1000 | 7 , self . get_channel_update ( chan) . unwrap ( ) ) ) ;
840
+ }
841
+ if * amt_to_forward < chan. get_their_htlc_minimum_msat ( ) { // amount_below_minimum
842
+ break Some ( ( "HTLC amount was below the htlc_minimum_msat" , 0x1000 | 11 , self . get_channel_update ( chan) . unwrap ( ) ) ) ;
845
843
}
846
- } {
847
- return_err ! ( err, code, & chan_update. encode_with_len( ) [ ..] ) ;
844
+ 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 ) } ) ;
845
+ if fee. is_none ( ) || msg. amount_msat < fee. unwrap ( ) || ( msg. amount_msat - fee. unwrap ( ) ) < * amt_to_forward { // fee_insufficient
846
+ break Some ( ( "Prior hop has deviated from specified fees parameters or origin node has obsolete ones" , 0x1000 | 12 , self . get_channel_update ( chan) . unwrap ( ) ) ) ;
847
+ }
848
+ if ( msg. cltv_expiry as u64 ) < ( * outgoing_cltv_value) as u64 + CLTV_EXPIRY_DELTA as u64 { // incorrect_cltv_expiry
849
+ 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 ( ) ) ) ;
850
+ }
851
+ let cur_height = self . latest_block_height . load ( Ordering :: Acquire ) as u32 + 1 ;
852
+ if msg. cltv_expiry <= cur_height + CLTV_EXPIRY_DELTA as u32 { // expiry_too_soon
853
+ break Some ( ( "CLTV expiry is too close" , 0x1000 | 14 , self . get_channel_update ( chan) . unwrap ( ) ) ) ;
854
+ }
855
+ /*
856
+ if chan.is_disabled() {
857
+ break Some(("Forwarding channel has been disabled.", 0x1000 | 20, self.get_channel_update(chan).unwrap()));
858
+ }
859
+ */
860
+ if msg. cltv_expiry > cur_height + CLTV_FAR_FAR_AWAY as u32 { // expiry_too_far
861
+ break Some ( ( "CLTV expiry is too far in the future" , 0x1000 | 21 , self . get_channel_update ( chan) . unwrap ( ) ) ) ;
862
+ }
863
+ break None ;
864
+ }
865
+ {
866
+ let mut res = Vec :: with_capacity ( 8 + 128 ) ;
867
+ if code == 0x1000 | 11 || code == 0x1000 | 12 {
868
+ res. extend_from_slice ( & byte_utils:: be64_to_array ( * amt_to_forward) ) ;
869
+ }
870
+ else if code == 0x1000 | 13 {
871
+ res. extend_from_slice ( & byte_utils:: be32_to_array ( msg. cltv_expiry ) ) ;
872
+ }
873
+ res. extend_from_slice ( & chan_update. encode_with_len ( ) [ ..] ) ;
874
+ return_err ! ( err, code, & res[ ..] ) ;
848
875
}
849
876
}
850
877
}
@@ -1158,6 +1185,11 @@ impl ChannelManager {
1158
1185
self . fail_htlc_backwards_internal ( self . channel_state . lock ( ) . unwrap ( ) , payment_hash, HTLCFailReason :: Reason { failure_code : 0x4000 | 15 , data : Vec :: new ( ) } )
1159
1186
}
1160
1187
1188
+ /// Indicates that the amount for payment_hash is incorrect after a PaymentReceived event.
1189
+ pub fn fail_htlc_backwards_incorrect_payment_amount ( & self , payment_hash : & [ u8 ; 32 ] ) -> bool {
1190
+ self . fail_htlc_backwards_internal ( self . channel_state . lock ( ) . unwrap ( ) , payment_hash, HTLCFailReason :: Reason { failure_code : 0x4000 | 16 , data : Vec :: new ( ) } )
1191
+ }
1192
+
1161
1193
/// Fails an HTLC backwards to the sender of it to us.
1162
1194
/// Note that while we take a channel_state lock as input, we do *not* assume consistency here.
1163
1195
/// There are several callsites that do stupid things like loop over a list of payment_hashes
@@ -3130,6 +3162,8 @@ mod tests {
3130
3162
assert_eq ! ( nodes[ 2 ] . node. list_channels( ) . len( ) , 0 ) ;
3131
3163
assert_eq ! ( nodes[ 3 ] . node. list_channels( ) . len( ) , 1 ) ;
3132
3164
3165
+ let header = BlockHeader { version : 0x20000000 , prev_blockhash : Default :: default ( ) , merkle_root : Default :: default ( ) , time : 42 , bits : 42 , nonce : 42 } ;
3166
+ nodes[ 4 ] . chain_monitor . block_connected_with_filtering ( & Block { header, txdata : vec ! [ ] } , 1 ) ;
3133
3167
// One pending HTLC to time out:
3134
3168
let payment_preimage_2 = route_payment ( & nodes[ 3 ] , & vec ! ( & nodes[ 4 ] ) [ ..] , 3000000 ) . 0 ;
3135
3169
0 commit comments