Skip to content

Commit caeff85

Browse files
committed
Update incorrect_payment_amount generation/handling for BOLT uptd
ie dont generate them as they're a really obvious privacy leak. Luckily we were already handling them the same aside from log printing so don't have to touch anything there. I was lazy in updating tests but it only effects log printing, so whatever.
1 parent 3f4ab94 commit caeff85

File tree

4 files changed

+28
-36
lines changed

4 files changed

+28
-36
lines changed

fuzz/fuzz_targets/full_stack_target.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use lightning::chain::chaininterface::{BroadcasterInterface,ConfirmationTarget,C
1717
use lightning::chain::transaction::OutPoint;
1818
use lightning::chain::keysinterface::{ChannelKeys, KeysInterface};
1919
use lightning::ln::channelmonitor;
20-
use lightning::ln::channelmanager::{ChannelManager, PaymentFailReason, PaymentHash, PaymentPreimage};
20+
use lightning::ln::channelmanager::{ChannelManager, PaymentHash, PaymentPreimage};
2121
use lightning::ln::peer_handler::{MessageHandler,PeerManager,SocketDescriptor};
2222
use lightning::ln::router::Router;
2323
use lightning::util::events::{EventsProvider,Event};
@@ -419,7 +419,7 @@ pub fn do_test(data: &[u8], logger: &Arc<Logger>) {
419419
// fulfill this HTLC, but if they are, we can just take the first byte and
420420
// place that anywhere in our preimage.
421421
if &payment.0[1..] != &[0; 31] {
422-
channelmanager.fail_htlc_backwards(&payment, PaymentFailReason::PreimageUnknown);
422+
channelmanager.fail_htlc_backwards(&payment, 0);
423423
} else {
424424
let mut payment_preimage = PaymentPreimage([0; 32]);
425425
payment_preimage.0[0] = payment.0[0];
@@ -429,7 +429,7 @@ pub fn do_test(data: &[u8], logger: &Arc<Logger>) {
429429
},
430430
9 => {
431431
for payment in payments_received.drain(..) {
432-
channelmanager.fail_htlc_backwards(&payment, PaymentFailReason::PreimageUnknown);
432+
channelmanager.fail_htlc_backwards(&payment, 0);
433433
}
434434
},
435435
10 => {

src/ln/channelmanager.rs

Lines changed: 20 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -212,16 +212,6 @@ impl MsgHandleErrInternal {
212212
}
213213
}
214214

215-
/// Pass to fail_htlc_backwwards to indicate the reason to fail the payment
216-
/// after a PaymentReceived event.
217-
#[derive(PartialEq)]
218-
pub enum PaymentFailReason {
219-
/// Indicate the preimage for payment_hash is not known after a PaymentReceived event
220-
PreimageUnknown,
221-
/// Indicate the payment amount is incorrect ( received is < expected or > 2*expected ) after a PaymentReceived event
222-
AmountMismatch,
223-
}
224-
225215
/// We hold back HTLCs we intend to relay for a random interval in the range (this, 5*this). This
226216
/// provides some limited amount of privacy. Ideally this would range from somewhere like 1 second
227217
/// to 30 seconds, but people expect lightning to be, you know, kinda fast, sadly. We could
@@ -1530,16 +1520,21 @@ impl ChannelManager {
15301520
events.append(&mut new_events);
15311521
}
15321522

1533-
/// Indicates that the preimage for payment_hash is unknown or the received amount is incorrect after a PaymentReceived event.
1534-
pub fn fail_htlc_backwards(&self, payment_hash: &PaymentHash, reason: PaymentFailReason) -> bool {
1523+
/// Indicates that the preimage for payment_hash is unknown or the received amount is incorrect
1524+
/// after a PaymentReceived event.
1525+
/// expected_value is the value you expected the payment to be for (not the amount it actually
1526+
/// was for from the PaymentReceived event).
1527+
pub fn fail_htlc_backwards(&self, payment_hash: &PaymentHash, expected_value: u64) -> bool {
15351528
let _ = self.total_consistency_lock.read().unwrap();
15361529

15371530
let mut channel_state = Some(self.channel_state.lock().unwrap());
15381531
let removed_source = channel_state.as_mut().unwrap().claimable_htlcs.remove(payment_hash);
15391532
if let Some(mut sources) = removed_source {
15401533
for htlc_with_hash in sources.drain(..) {
15411534
if channel_state.is_none() { channel_state = Some(self.channel_state.lock().unwrap()); }
1542-
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() });
1535+
self.fail_htlc_backwards_internal(channel_state.take().unwrap(),
1536+
HTLCSource::PreviousHopData(htlc_with_hash), payment_hash,
1537+
HTLCFailReason::Reason { failure_code: 0x4000 | 15, data: byte_utils::be64_to_array(expected_value).to_vec() });
15431538
}
15441539
true
15451540
} else { false }
@@ -3363,7 +3358,7 @@ mod tests {
33633358
use chain::keysinterface::{KeysInterface, SpendableOutputDescriptor};
33643359
use chain::keysinterface;
33653360
use ln::channel::{COMMITMENT_TX_BASE_WEIGHT, COMMITMENT_TX_WEIGHT_PER_HTLC};
3366-
use ln::channelmanager::{ChannelManager,ChannelManagerReadArgs,OnionKeys,PaymentFailReason,RAACommitmentOrder, PaymentPreimage, PaymentHash};
3361+
use ln::channelmanager::{ChannelManager,ChannelManagerReadArgs,OnionKeys,RAACommitmentOrder, PaymentPreimage, PaymentHash};
33673362
use ln::channelmonitor::{ChannelMonitor, ChannelMonitorUpdateErr, CLTV_CLAIM_BUFFER, HTLC_FAIL_TIMEOUT_BLOCKS, ManyChannelMonitor};
33683363
use ln::channel::{ACCEPTED_HTLC_SCRIPT_WEIGHT, OFFERED_HTLC_SCRIPT_WEIGHT};
33693364
use ln::router::{Route, RouteHop, Router};
@@ -4221,7 +4216,7 @@ mod tests {
42214216
}
42224217

42234218
fn fail_payment_along_route(origin_node: &Node, expected_route: &[&Node], skip_last: bool, our_payment_hash: PaymentHash) {
4224-
assert!(expected_route.last().unwrap().node.fail_htlc_backwards(&our_payment_hash, PaymentFailReason::PreimageUnknown));
4219+
assert!(expected_route.last().unwrap().node.fail_htlc_backwards(&our_payment_hash, 0));
42254220
check_added_monitors!(expected_route.last().unwrap(), 1);
42264221

42274222
let mut next_msgs: Option<(msgs::UpdateFailHTLC, msgs::CommitmentSigned)> = None;
@@ -6348,7 +6343,7 @@ mod tests {
63486343
// Brodacast legit commitment tx from C on B's chain
63496344
let commitment_tx = nodes[2].node.channel_state.lock().unwrap().by_id.get(&chan_2.2).unwrap().last_local_commitment_txn.clone();
63506345
check_spends!(commitment_tx[0], chan_2.3.clone());
6351-
nodes[2].node.fail_htlc_backwards(&payment_hash, PaymentFailReason::PreimageUnknown);
6346+
nodes[2].node.fail_htlc_backwards(&payment_hash, 0);
63526347
{
63536348
let mut added_monitors = nodes[2].chan_monitor.added_monitors.lock().unwrap();
63546349
assert_eq!(added_monitors.len(), 1);
@@ -6533,7 +6528,7 @@ mod tests {
65336528
let (_, second_payment_hash) = route_payment(&nodes[0], &[&nodes[1], &nodes[2]], 3000000);
65346529
let (_, third_payment_hash) = route_payment(&nodes[0], &[&nodes[1], &nodes[2]], 3000000);
65356530

6536-
assert!(nodes[2].node.fail_htlc_backwards(&first_payment_hash, PaymentFailReason::PreimageUnknown));
6531+
assert!(nodes[2].node.fail_htlc_backwards(&first_payment_hash, 0));
65376532
check_added_monitors!(nodes[2], 1);
65386533
let updates = get_htlc_update_msgs!(nodes[2], nodes[1].node.get_our_node_id());
65396534
assert!(updates.update_add_htlcs.is_empty());
@@ -6545,7 +6540,7 @@ mod tests {
65456540
let bs_raa = commitment_signed_dance!(nodes[1], nodes[2], updates.commitment_signed, false, true, false, true);
65466541
// Drop the last RAA from 3 -> 2
65476542

6548-
assert!(nodes[2].node.fail_htlc_backwards(&second_payment_hash, PaymentFailReason::PreimageUnknown));
6543+
assert!(nodes[2].node.fail_htlc_backwards(&second_payment_hash, 0));
65496544
check_added_monitors!(nodes[2], 1);
65506545
let updates = get_htlc_update_msgs!(nodes[2], nodes[1].node.get_our_node_id());
65516546
assert!(updates.update_add_htlcs.is_empty());
@@ -6561,7 +6556,7 @@ mod tests {
65616556
nodes[2].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &as_raa).unwrap();
65626557
check_added_monitors!(nodes[2], 1);
65636558

6564-
assert!(nodes[2].node.fail_htlc_backwards(&third_payment_hash, PaymentFailReason::PreimageUnknown));
6559+
assert!(nodes[2].node.fail_htlc_backwards(&third_payment_hash, 0));
65656560
check_added_monitors!(nodes[2], 1);
65666561
let updates = get_htlc_update_msgs!(nodes[2], nodes[1].node.get_our_node_id());
65676562
assert!(updates.update_add_htlcs.is_empty());
@@ -8156,7 +8151,7 @@ mod tests {
81568151
let (_, payment_hash_1) = route_payment(&nodes[0], &[&nodes[1], &nodes[2]], 1000000);
81578152

81588153
// Fail the payment backwards, failing the monitor update on nodes[1]'s receipt of the RAA
8159-
assert!(nodes[2].node.fail_htlc_backwards(&payment_hash_1, PaymentFailReason::PreimageUnknown));
8154+
assert!(nodes[2].node.fail_htlc_backwards(&payment_hash_1, 0));
81608155
check_added_monitors!(nodes[2], 1);
81618156

81628157
let updates = get_htlc_update_msgs!(nodes[2], nodes[1].node.get_our_node_id());
@@ -9721,7 +9716,7 @@ mod tests {
97219716
let onion_keys = ChannelManager::construct_onion_keys(&Secp256k1::new(), &route, &session_priv).unwrap();
97229717
msg.reason = ChannelManager::build_first_hop_failure_packet(&onion_keys[1].shared_secret[..], NODE|2, &[0;0]);
97239718
}, ||{
9724-
nodes[2].node.fail_htlc_backwards(&payment_hash, PaymentFailReason::PreimageUnknown);
9719+
nodes[2].node.fail_htlc_backwards(&payment_hash, 0);
97259720
}, true, Some(NODE|2), Some(msgs::HTLCFailChannelUpdate::NodeFailure{node_id: route.hops[1].pubkey, is_permanent: false}));
97269721

97279722
// intermediate node failure
@@ -9739,7 +9734,7 @@ mod tests {
97399734
let onion_keys = ChannelManager::construct_onion_keys(&Secp256k1::new(), &route, &session_priv).unwrap();
97409735
msg.reason = ChannelManager::build_first_hop_failure_packet(&onion_keys[1].shared_secret[..], PERM|NODE|2, &[0;0]);
97419736
}, ||{
9742-
nodes[2].node.fail_htlc_backwards(&payment_hash, PaymentFailReason::PreimageUnknown);
9737+
nodes[2].node.fail_htlc_backwards(&payment_hash, 0);
97439738
}, false, Some(PERM|NODE|2), Some(msgs::HTLCFailChannelUpdate::NodeFailure{node_id: route.hops[1].pubkey, is_permanent: true}));
97449739

97459740
// intermediate node failure
@@ -9750,7 +9745,7 @@ mod tests {
97509745
let onion_keys = ChannelManager::construct_onion_keys(&Secp256k1::new(), &route, &session_priv).unwrap();
97519746
msg.reason = ChannelManager::build_first_hop_failure_packet(&onion_keys[0].shared_secret[..], PERM|NODE|3, &[0;0]);
97529747
}, ||{
9753-
nodes[2].node.fail_htlc_backwards(&payment_hash, PaymentFailReason::PreimageUnknown);
9748+
nodes[2].node.fail_htlc_backwards(&payment_hash, 0);
97549749
}, true, Some(PERM|NODE|3), Some(msgs::HTLCFailChannelUpdate::NodeFailure{node_id: route.hops[0].pubkey, is_permanent: true}));
97559750

97569751
// final node failure
@@ -9759,7 +9754,7 @@ mod tests {
97599754
let onion_keys = ChannelManager::construct_onion_keys(&Secp256k1::new(), &route, &session_priv).unwrap();
97609755
msg.reason = ChannelManager::build_first_hop_failure_packet(&onion_keys[1].shared_secret[..], PERM|NODE|3, &[0;0]);
97619756
}, ||{
9762-
nodes[2].node.fail_htlc_backwards(&payment_hash, PaymentFailReason::PreimageUnknown);
9757+
nodes[2].node.fail_htlc_backwards(&payment_hash, 0);
97639758
}, false, Some(PERM|NODE|3), Some(msgs::HTLCFailChannelUpdate::NodeFailure{node_id: route.hops[1].pubkey, is_permanent: true}));
97649759

97659760
run_onion_failure_test("invalid_onion_version", 0, &nodes, &route, &payment_hash, |msg| { msg.onion_routing_packet.version = 1; }, ||{}, true,
@@ -9826,13 +9821,9 @@ mod tests {
98269821
}, ||{}, true, Some(UPDATE|14), Some(msgs::HTLCFailChannelUpdate::ChannelUpdateMessage{msg: ChannelUpdate::dummy()}));
98279822

98289823
run_onion_failure_test("unknown_payment_hash", 2, &nodes, &route, &payment_hash, |_| {}, || {
9829-
nodes[2].node.fail_htlc_backwards(&payment_hash, PaymentFailReason::PreimageUnknown);
9824+
nodes[2].node.fail_htlc_backwards(&payment_hash, 0);
98309825
}, false, Some(PERM|15), None);
98319826

9832-
run_onion_failure_test("incorrect_payment_amount", 2, &nodes, &route, &payment_hash, |_| {}, || {
9833-
nodes[2].node.fail_htlc_backwards(&payment_hash, PaymentFailReason::AmountMismatch);
9834-
}, false, Some(PERM|16), None);
9835-
98369827
run_onion_failure_test("final_expiry_too_soon", 1, &nodes, &route, &payment_hash, |msg| {
98379828
let height = msg.cltv_expiry - CLTV_CLAIM_BUFFER - HTLC_FAIL_TIMEOUT_BLOCKS + 1;
98389829
let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };

src/util/errors.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ pub(crate) fn get_onion_error_description(error_code: u16) -> (&'static str, &'s
8484
_c if _c == UPDATE|12 => ("Node indicated the fee amount does not meet the required level", "fee_insufficient"),
8585
_c if _c == UPDATE|13 => ("Node indicated the cltv_expiry does not comply with the cltv_expiry_delta required by the outgoing channel", "incorrect_cltv_expiry"),
8686
_c if _c == UPDATE|14 => ("Node indicated the CLTV expiry too close to the current block height for safe handling", "expiry_too_soon"),
87-
_c if _c == PERM|15 => ("The final node indicated the payment hash is unknown", "unknown_payment_hash"),
87+
_c if _c == PERM|15 => ("The final node indicated the payment hash is unknown or amount is incorrect", "incorrect_or_unknown_payment_details"),
8888
_c if _c == PERM|16 => ("The final node indicated the payment amount is incorrect", "incorrect_payment_amount"),
8989
_c if _c == 17 => ("The final node indicated the CLTV expiry is too close to the current block height for safe handling", "final_expiry_too_soon"),
9090
_c if _c == 18 => ("The final node indicated the CLTV expiry in the HTLC does not match the value in the onion", "final_incorrect_cltv_expiry"),

src/util/events.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,14 +54,15 @@ pub enum Event {
5454
/// Indicates we've received money! Just gotta dig out that payment preimage and feed it to
5555
/// ChannelManager::claim_funds to get it....
5656
/// Note that if the preimage is not known or the amount paid is incorrect, you must call
57-
/// ChannelManager::fail_htlc_backwards with PaymentFailReason::PreimageUnknown or
58-
/// PaymentFailReason::AmountMismatch, respectively, to free up resources for this HTLC.
57+
/// ChannelManager::fail_htlc_backwards to free up resources for this HTLC.
5958
/// The amount paid should be considered 'incorrect' when it is less than or more than twice
6059
/// the amount expected.
6160
PaymentReceived {
6261
/// The hash for which the preimage should be handed to the ChannelManager.
6362
payment_hash: PaymentHash,
64-
/// The value, in thousandths of a satoshi, that this payment is for.
63+
/// The value, in thousandths of a satoshi, that this payment is for. Note that you must
64+
/// compare this to the expected value before accepting the payment (as otherwise you are
65+
/// providing proof-of-payment for less than the value you expected!).
6566
amt: u64,
6667
},
6768
/// Indicates an outbound payment we made succeeded (ie it made it all the way to its target

0 commit comments

Comments
 (0)