Skip to content

Commit 9f071df

Browse files
author
Antoine Riard
committed
Check expected amount in claim_funds
Require to specify expected amount so that we can claim only payment for thhe correct amount, and reject payments for incorrect amounts (which are probably middle nodes probing to break our privacy). Send back incorrect_or_unknown_payments_details (PERM|15) to avoid the probe node learning that final node is waiting a payment with the routed hash.
1 parent 2afd531 commit 9f071df

6 files changed

+155
-138
lines changed

fuzz/fuzz_targets/chanmon_fail_consistency.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -609,7 +609,7 @@ pub fn do_test(data: &[u8]) {
609609
if $fail {
610610
assert!(nodes[$node].fail_htlc_backwards(&payment_hash));
611611
} else {
612-
assert!(nodes[$node].claim_funds(PaymentPreimage(payment_hash.0)));
612+
assert!(nodes[$node].claim_funds(PaymentPreimage(payment_hash.0), 5_000_000));
613613
}
614614
}
615615
},

fuzz/fuzz_targets/full_stack_target.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,7 @@ pub fn do_test(data: &[u8], logger: &Arc<Logger>) {
346346
let mut pending_funding_generation: Vec<([u8; 32], u64, Script)> = Vec::new();
347347
let mut pending_funding_signatures = HashMap::new();
348348
let mut pending_funding_relay = Vec::new();
349+
let mut values = HashMap::new();
349350

350351
loop {
351352
match get_slice!(1)[0] {
@@ -399,6 +400,7 @@ pub fn do_test(data: &[u8], logger: &Arc<Logger>) {
399400
sha.input(&payment_hash.0[..]);
400401
payment_hash.0 = Sha256::from_engine(sha).into_inner();
401402
payments_sent += 1;
403+
values.insert(payment_hash, value);
402404
match channelmanager.send_payment(route, payment_hash) {
403405
Ok(_) => {},
404406
Err(_) => return,
@@ -436,7 +438,9 @@ pub fn do_test(data: &[u8], logger: &Arc<Logger>) {
436438
} else {
437439
let mut payment_preimage = PaymentPreimage([0; 32]);
438440
payment_preimage.0[0] = payment.0[0];
439-
channelmanager.claim_funds(payment_preimage);
441+
if let Some(value) = values.get(&payment) {
442+
channelmanager.claim_funds(payment_preimage, *value);
443+
}
440444
}
441445
}
442446
},

src/ln/chanmon_update_fail_tests.rs

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ fn do_test_simple_monitor_temporary_update_fail(disconnect: bool) {
9191
_ => panic!("Unexpected event"),
9292
}
9393

94-
claim_payment(&nodes[0], &[&nodes[1]], payment_preimage_1);
94+
claim_payment(&nodes[0], &[&nodes[1]], payment_preimage_1, 1_000_000);
9595

9696
// Now set it to failed again...
9797
let (_, payment_hash_2) = get_payment_preimage_hash!(nodes[0]);
@@ -166,7 +166,7 @@ fn do_test_monitor_temporary_update_fail(disconnect_count: usize) {
166166

167167
// Claim the previous payment, which will result in a update_fulfill_htlc/CS from nodes[1]
168168
// but nodes[0] won't respond since it is frozen.
169-
assert!(nodes[1].node.claim_funds(payment_preimage_1));
169+
assert!(nodes[1].node.claim_funds(payment_preimage_1, 1_000_000));
170170
check_added_monitors!(nodes[1], 1);
171171
let events_2 = nodes[1].node.get_and_clear_pending_msg_events();
172172
assert_eq!(events_2.len(), 1);
@@ -440,7 +440,7 @@ fn do_test_monitor_temporary_update_fail(disconnect_count: usize) {
440440
_ => panic!("Unexpected event"),
441441
}
442442

443-
claim_payment(&nodes[0], &[&nodes[1]], payment_preimage_2);
443+
claim_payment(&nodes[0], &[&nodes[1]], payment_preimage_2, 1_000_000);
444444
}
445445

446446
#[test]
@@ -544,7 +544,7 @@ fn test_monitor_update_fail_cs() {
544544
_ => panic!("Unexpected event"),
545545
};
546546

547-
claim_payment(&nodes[0], &[&nodes[1]], payment_preimage);
547+
claim_payment(&nodes[0], &[&nodes[1]], payment_preimage, 1_000_000);
548548
}
549549

550550
#[test]
@@ -587,7 +587,7 @@ fn test_monitor_update_fail_no_rebroadcast() {
587587
_ => panic!("Unexpected event"),
588588
}
589589

590-
claim_payment(&nodes[0], &[&nodes[1]], payment_preimage_1);
590+
claim_payment(&nodes[0], &[&nodes[1]], payment_preimage_1, 1_000_000);
591591
}
592592

593593
#[test]
@@ -597,7 +597,7 @@ fn test_monitor_update_raa_while_paused() {
597597
let mut nodes = create_network(2, &[None, None]);
598598
create_announced_chan_between_nodes(&nodes, 0, 1, LocalFeatures::new(), LocalFeatures::new());
599599

600-
send_payment(&nodes[0], &[&nodes[1]], 5000000);
600+
send_payment(&nodes[0], &[&nodes[1]], 5000000, 5_000_000);
601601

602602
let route = nodes[0].router.get_route(&nodes[1].node.get_our_node_id(), None, &Vec::new(), 1000000, TEST_FINAL_CLTV).unwrap();
603603
let (payment_preimage_1, our_payment_hash_1) = get_payment_preimage_hash!(nodes[0]);
@@ -655,8 +655,8 @@ fn test_monitor_update_raa_while_paused() {
655655
expect_pending_htlcs_forwardable!(nodes[1]);
656656
expect_payment_received!(nodes[1], our_payment_hash_1, 1000000);
657657

658-
claim_payment(&nodes[0], &[&nodes[1]], payment_preimage_1);
659-
claim_payment(&nodes[1], &[&nodes[0]], payment_preimage_2);
658+
claim_payment(&nodes[0], &[&nodes[1]], payment_preimage_1, 1_000_000);
659+
claim_payment(&nodes[1], &[&nodes[0]], payment_preimage_2, 1_000_000);
660660
}
661661

662662
fn do_test_monitor_update_fail_raa(test_ignore_second_cs: bool) {
@@ -666,7 +666,7 @@ fn do_test_monitor_update_fail_raa(test_ignore_second_cs: bool) {
666666
let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2, LocalFeatures::new(), LocalFeatures::new());
667667

668668
// Rebalance a bit so that we can send backwards from 2 to 1.
669-
send_payment(&nodes[0], &[&nodes[1], &nodes[2]], 5000000);
669+
send_payment(&nodes[0], &[&nodes[1], &nodes[2]], 5000000, 5_000_000);
670670

671671
// Route a first payment that we'll fail backwards
672672
let (_, payment_hash_1) = route_payment(&nodes[0], &[&nodes[1], &nodes[2]], 1000000);
@@ -897,10 +897,10 @@ fn do_test_monitor_update_fail_raa(test_ignore_second_cs: bool) {
897897
Event::PaymentReceived { payment_hash, .. } => assert_eq!(payment_hash, payment_hash_4.unwrap()),
898898
_ => panic!("Unexpected event"),
899899
};
900-
claim_payment(&nodes[2], &[&nodes[1], &nodes[0]], payment_preimage_4.unwrap());
900+
claim_payment(&nodes[2], &[&nodes[1], &nodes[0]], payment_preimage_4.unwrap(), 1_000_000);
901901
}
902902

903-
claim_payment(&nodes[0], &[&nodes[1], &nodes[2]], payment_preimage_2);
903+
claim_payment(&nodes[0], &[&nodes[1], &nodes[2]], payment_preimage_2, 1_000_000);
904904
}
905905

906906
#[test]
@@ -923,7 +923,7 @@ fn test_monitor_update_fail_reestablish() {
923923
nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
924924
nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false);
925925

926-
assert!(nodes[2].node.claim_funds(our_payment_preimage));
926+
assert!(nodes[2].node.claim_funds(our_payment_preimage, 1_000_000));
927927
check_added_monitors!(nodes[2], 1);
928928
let mut updates = get_htlc_update_msgs!(nodes[2], nodes[1].node.get_our_node_id());
929929
assert!(updates.update_add_htlcs.is_empty());
@@ -1092,9 +1092,9 @@ fn raa_no_response_awaiting_raa_state() {
10921092
expect_pending_htlcs_forwardable!(nodes[1]);
10931093
expect_payment_received!(nodes[1], payment_hash_3, 1000000);
10941094

1095-
claim_payment(&nodes[0], &[&nodes[1]], payment_preimage_1);
1096-
claim_payment(&nodes[0], &[&nodes[1]], payment_preimage_2);
1097-
claim_payment(&nodes[0], &[&nodes[1]], payment_preimage_3);
1095+
claim_payment(&nodes[0], &[&nodes[1]], payment_preimage_1, 1_000_000);
1096+
claim_payment(&nodes[0], &[&nodes[1]], payment_preimage_2, 1_000_000);
1097+
claim_payment(&nodes[0], &[&nodes[1]], payment_preimage_3, 1_000_000);
10981098
}
10991099

11001100
#[test]
@@ -1114,7 +1114,7 @@ fn claim_while_disconnected_monitor_update_fail() {
11141114
nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false);
11151115
nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
11161116

1117-
assert!(nodes[1].node.claim_funds(payment_preimage_1));
1117+
assert!(nodes[1].node.claim_funds(payment_preimage_1, 1_000_000));
11181118
check_added_monitors!(nodes[1], 1);
11191119

11201120
nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id());
@@ -1211,7 +1211,7 @@ fn claim_while_disconnected_monitor_update_fail() {
12111211
_ => panic!("Unexpected event"),
12121212
}
12131213

1214-
claim_payment(&nodes[0], &[&nodes[1]], payment_preimage_2);
1214+
claim_payment(&nodes[0], &[&nodes[1]], payment_preimage_2, 1_000_000);
12151215
}
12161216

12171217
#[test]
@@ -1271,7 +1271,7 @@ fn monitor_failed_no_reestablish_response() {
12711271
expect_pending_htlcs_forwardable!(nodes[1]);
12721272
expect_payment_received!(nodes[1], payment_hash_1, 1000000);
12731273

1274-
claim_payment(&nodes[0], &[&nodes[1]], payment_preimage_1);
1274+
claim_payment(&nodes[0], &[&nodes[1]], payment_preimage_1, 1_000_000);
12751275
}
12761276

12771277
#[test]
@@ -1360,8 +1360,8 @@ fn first_message_on_recv_ordering() {
13601360
expect_pending_htlcs_forwardable!(nodes[1]);
13611361
expect_payment_received!(nodes[1], payment_hash_2, 1000000);
13621362

1363-
claim_payment(&nodes[0], &[&nodes[1]], payment_preimage_1);
1364-
claim_payment(&nodes[0], &[&nodes[1]], payment_preimage_2);
1363+
claim_payment(&nodes[0], &[&nodes[1]], payment_preimage_1, 1_000_000);
1364+
claim_payment(&nodes[0], &[&nodes[1]], payment_preimage_2, 1_000_000);
13651365
}
13661366

13671367
#[test]
@@ -1376,12 +1376,12 @@ fn test_monitor_update_fail_claim() {
13761376
create_announced_chan_between_nodes(&nodes, 1, 2, LocalFeatures::new(), LocalFeatures::new());
13771377

13781378
// Rebalance a bit so that we can send backwards from 3 to 2.
1379-
send_payment(&nodes[0], &[&nodes[1], &nodes[2]], 5000000);
1379+
send_payment(&nodes[0], &[&nodes[1], &nodes[2]], 5000000, 5_000_000);
13801380

13811381
let (payment_preimage_1, _) = route_payment(&nodes[0], &[&nodes[1]], 1000000);
13821382

13831383
*nodes[1].chan_monitor.update_ret.lock().unwrap() = Err(ChannelMonitorUpdateErr::TemporaryFailure);
1384-
assert!(nodes[1].node.claim_funds(payment_preimage_1));
1384+
assert!(nodes[1].node.claim_funds(payment_preimage_1, 1_000_000));
13851385
check_added_monitors!(nodes[1], 1);
13861386

13871387
let route = nodes[2].router.get_route(&nodes[0].node.get_our_node_id(), None, &Vec::new(), 1000000, TEST_FINAL_CLTV).unwrap();
@@ -1446,7 +1446,7 @@ fn test_monitor_update_on_pending_forwards() {
14461446
create_announced_chan_between_nodes(&nodes, 1, 2, LocalFeatures::new(), LocalFeatures::new());
14471447

14481448
// Rebalance a bit so that we can send backwards from 3 to 1.
1449-
send_payment(&nodes[0], &[&nodes[1], &nodes[2]], 5000000);
1449+
send_payment(&nodes[0], &[&nodes[1], &nodes[2]], 5000000, 5_000_000);
14501450

14511451
let (_, payment_hash_1) = route_payment(&nodes[0], &[&nodes[1], &nodes[2]], 1000000);
14521452
assert!(nodes[2].node.fail_htlc_backwards(&payment_hash_1));
@@ -1496,7 +1496,7 @@ fn test_monitor_update_on_pending_forwards() {
14961496
nodes[0].node.process_pending_htlc_forwards();
14971497
expect_payment_received!(nodes[0], payment_hash_2, 1000000);
14981498

1499-
claim_payment(&nodes[2], &[&nodes[1], &nodes[0]], payment_preimage_2);
1499+
claim_payment(&nodes[2], &[&nodes[1], &nodes[0]], payment_preimage_2, 1_000_000);
15001500
}
15011501

15021502
#[test]
@@ -1524,7 +1524,7 @@ fn monitor_update_claim_fail_no_response() {
15241524
let as_raa = commitment_signed_dance!(nodes[1], nodes[0], payment_event.commitment_msg, false, true, false, true);
15251525

15261526
*nodes[1].chan_monitor.update_ret.lock().unwrap() = Err(ChannelMonitorUpdateErr::TemporaryFailure);
1527-
assert!(nodes[1].node.claim_funds(payment_preimage_1));
1527+
assert!(nodes[1].node.claim_funds(payment_preimage_1, 1_000_000));
15281528
check_added_monitors!(nodes[1], 1);
15291529
assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
15301530

@@ -1551,7 +1551,7 @@ fn monitor_update_claim_fail_no_response() {
15511551
_ => panic!("Unexpected event"),
15521552
}
15531553

1554-
claim_payment(&nodes[0], &[&nodes[1]], payment_preimage_2);
1554+
claim_payment(&nodes[0], &[&nodes[1]], payment_preimage_2, 1_000_000);
15551555
}
15561556

15571557
// Note that restore_between_fails with !fail_on_generate is useless
@@ -1671,7 +1671,7 @@ fn do_during_funding_monitor_fail(fail_on_generate: bool, restore_between_fails:
16711671
node.router.handle_channel_update(&bs_update).unwrap();
16721672
}
16731673

1674-
send_payment(&nodes[0], &[&nodes[1]], 8000000);
1674+
send_payment(&nodes[0], &[&nodes[1]], 8000000, 8_000_000);
16751675
close_channel(&nodes[0], &nodes[1], &channel_id, funding_tx, true);
16761676
}
16771677

src/ln/channelmanager.rs

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1574,21 +1574,34 @@ impl ChannelManager {
15741574
/// generating message events for the net layer to claim the payment, if possible. Thus, you
15751575
/// should probably kick the net layer to go send messages if this returns true!
15761576
///
1577+
/// You must specify the expected amounts for this HTLC, and we will only claim HTLCs
1578+
/// available within a few percent of the expected amount. This is critical for several
1579+
/// reasons : a) it avoids providing senders with `proof-of-payment` (in the form of the
1580+
/// payment_preimage without having provided the full value and b) it avoids certain
1581+
/// privacy-breaking recipient-probing attacks which may reveal payment activity to
1582+
/// motivated attackers.
1583+
///
15771584
/// May panic if called except in response to a PaymentReceived event.
1578-
pub fn claim_funds(&self, payment_preimage: PaymentPreimage) -> bool {
1585+
pub fn claim_funds(&self, payment_preimage: PaymentPreimage, expected_amount: u64) -> bool {
15791586
let payment_hash = PaymentHash(Sha256::hash(&payment_preimage.0).into_inner());
15801587

15811588
let _ = self.total_consistency_lock.read().unwrap();
15821589

15831590
let mut channel_state = Some(self.channel_state.lock().unwrap());
15841591
let removed_source = channel_state.as_mut().unwrap().claimable_htlcs.remove(&payment_hash);
15851592
if let Some(mut sources) = removed_source {
1586-
// TODO: We should require the user specify the expected amount so that we can claim
1587-
// only payments for the correct amount, and reject payments for incorrect amounts
1588-
// (which are probably middle nodes probing to break our privacy).
1589-
for (_, htlc_with_hash) in sources.drain(..) {
1593+
for (received_amount, htlc_with_hash) in sources.drain(..) {
15901594
if channel_state.is_none() { channel_state = Some(self.channel_state.lock().unwrap()); }
1591-
self.claim_funds_internal(channel_state.take().unwrap(), HTLCSource::PreviousHopData(htlc_with_hash), payment_preimage);
1595+
if received_amount < expected_amount || received_amount * 2 > expected_amount {
1596+
let mut htlc_msat_data = byte_utils::be64_to_array(received_amount).to_vec();
1597+
let mut height_data = byte_utils::be32_to_array(self.latest_block_height.load(Ordering::Acquire) as u32).to_vec();
1598+
htlc_msat_data.append(&mut height_data);
1599+
self.fail_htlc_backwards_internal(channel_state.take().unwrap(),
1600+
HTLCSource::PreviousHopData(htlc_with_hash), &payment_hash,
1601+
HTLCFailReason::Reason { failure_code: 0x4000|15, data: htlc_msat_data });
1602+
} else {
1603+
self.claim_funds_internal(channel_state.take().unwrap(), HTLCSource::PreviousHopData(htlc_with_hash), payment_preimage);
1604+
}
15921605
}
15931606
true
15941607
} else { false }

src/ln/functional_test_utils.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -636,8 +636,8 @@ pub fn send_along_route(origin_node: &Node, route: Route, expected_route: &[&Nod
636636
(our_payment_preimage, our_payment_hash)
637637
}
638638

639-
pub fn claim_payment_along_route(origin_node: &Node, expected_route: &[&Node], skip_last: bool, our_payment_preimage: PaymentPreimage) {
640-
assert!(expected_route.last().unwrap().node.claim_funds(our_payment_preimage));
639+
pub fn claim_payment_along_route(origin_node: &Node, expected_route: &[&Node], skip_last: bool, our_payment_preimage: PaymentPreimage, expected_amount: u64) {
640+
assert!(expected_route.last().unwrap().node.claim_funds(our_payment_preimage, expected_amount));
641641
check_added_monitors!(expected_route.last().unwrap(), 1);
642642

643643
let mut next_msgs: Option<(msgs::UpdateFulfillHTLC, msgs::CommitmentSigned)> = None;
@@ -714,8 +714,8 @@ pub fn claim_payment_along_route(origin_node: &Node, expected_route: &[&Node], s
714714
}
715715
}
716716

717-
pub fn claim_payment(origin_node: &Node, expected_route: &[&Node], our_payment_preimage: PaymentPreimage) {
718-
claim_payment_along_route(origin_node, expected_route, false, our_payment_preimage);
717+
pub fn claim_payment(origin_node: &Node, expected_route: &[&Node], our_payment_preimage: PaymentPreimage, expected_amount: u64) {
718+
claim_payment_along_route(origin_node, expected_route, false, our_payment_preimage, expected_amount);
719719
}
720720

721721
pub const TEST_FINAL_CLTV: u32 = 32;
@@ -746,9 +746,9 @@ pub fn route_over_limit(origin_node: &Node, expected_route: &[&Node], recv_value
746746
};
747747
}
748748

749-
pub fn send_payment(origin: &Node, expected_route: &[&Node], recv_value: u64) {
749+
pub fn send_payment(origin: &Node, expected_route: &[&Node], recv_value: u64, expected_value: u64) {
750750
let our_payment_preimage = route_payment(&origin, expected_route, recv_value).0;
751-
claim_payment(&origin, expected_route, our_payment_preimage);
751+
claim_payment(&origin, expected_route, our_payment_preimage, expected_value);
752752
}
753753

754754
pub fn fail_payment_along_route(origin_node: &Node, expected_route: &[&Node], skip_last: bool, our_payment_hash: PaymentHash) {

0 commit comments

Comments
 (0)