@@ -6171,3 +6171,50 @@ fn test_data_loss_protect() {
6171
6171
assert_eq ! ( spend_txn. len( ) , 1 ) ;
6172
6172
check_spends ! ( spend_txn[ 0 ] , node_txn[ 0 ] . clone( ) ) ;
6173
6173
}
6174
+
6175
+ #[ test]
6176
+ fn test_check_htlc_underpaying ( ) {
6177
+ // Send payment through A -> B but A is maliciously
6178
+ // sending a probe payment (i.e less than expected value0
6179
+ // to B, B should refuse payment.
6180
+
6181
+ let nodes = create_network ( 2 , & [ None , None , None ] ) ;
6182
+
6183
+ // Create some initial channels
6184
+ create_announced_chan_between_nodes ( & nodes, 0 , 1 , LocalFeatures :: new ( ) , LocalFeatures :: new ( ) ) ;
6185
+
6186
+ let ( payment_preimage, _) = route_payment ( & nodes[ 0 ] , & [ & nodes[ 1 ] ] , 10_000 ) ;
6187
+
6188
+ // Node 3 is expecting payment of 100_000 but receive 10_000,
6189
+ // fail htlc like we didn't know the preimage.
6190
+ nodes[ 1 ] . node . claim_funds ( payment_preimage, 100_000 ) ;
6191
+ nodes[ 1 ] . node . process_pending_htlc_forwards ( ) ;
6192
+
6193
+ let events = nodes[ 1 ] . node . get_and_clear_pending_msg_events ( ) ;
6194
+ assert_eq ! ( events. len( ) , 1 ) ;
6195
+ let ( update_fail_htlc, commitment_signed) = match events[ 0 ] {
6196
+ MessageSendEvent :: UpdateHTLCs { node_id : _ , updates : msgs:: CommitmentUpdate { ref update_add_htlcs, ref update_fulfill_htlcs, ref update_fail_htlcs, ref update_fail_malformed_htlcs, ref update_fee, ref commitment_signed } } => {
6197
+ assert ! ( update_add_htlcs. is_empty( ) ) ;
6198
+ assert ! ( update_fulfill_htlcs. is_empty( ) ) ;
6199
+ assert_eq ! ( update_fail_htlcs. len( ) , 1 ) ;
6200
+ assert ! ( update_fail_malformed_htlcs. is_empty( ) ) ;
6201
+ assert ! ( update_fee. is_none( ) ) ;
6202
+ ( update_fail_htlcs[ 0 ] . clone ( ) , commitment_signed)
6203
+ } ,
6204
+ _ => panic ! ( "Unexpected event" ) ,
6205
+ } ;
6206
+ check_added_monitors ! ( nodes[ 1 ] , 1 ) ;
6207
+
6208
+ nodes[ 0 ] . node . handle_update_fail_htlc ( & nodes[ 1 ] . node . get_our_node_id ( ) , & update_fail_htlc) . unwrap ( ) ;
6209
+ commitment_signed_dance ! ( nodes[ 0 ] , nodes[ 1 ] , commitment_signed, false , true ) ;
6210
+
6211
+ let events = nodes[ 0 ] . node . get_and_clear_pending_events ( ) ;
6212
+ assert_eq ! ( events. len( ) , 1 ) ;
6213
+ if let & Event :: PaymentFailed { payment_hash : _, ref rejected_by_dest, ref error_code } = & events[ 0 ] {
6214
+ assert_eq ! ( * rejected_by_dest, true ) ;
6215
+ assert_eq ! ( error_code. unwrap( ) , 0x4000 |15 ) ;
6216
+ } else {
6217
+ panic ! ( "Unexpected event" ) ;
6218
+ }
6219
+ nodes[ 1 ] . node . get_and_clear_pending_events ( ) ;
6220
+ }
0 commit comments