Skip to content

Commit edba328

Browse files
Test failing phantom payments
Also fix a bug where we were failing back phantom payments with the wrong scid, causing them to never actually be failed backwards. Finally, drop some unnecessary panics when reading OnionHopData objects. This also enables one of the phantom failure tests because we can construct OnionHopDatas with invalid amounts
1 parent 1f6700c commit edba328

File tree

3 files changed

+312
-28
lines changed

3 files changed

+312
-28
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,7 @@ mod inbound_payment {
358358
// our payment, which we can use to decode errors or inform the user that the payment was sent.
359359

360360
#[derive(Clone)] // See Channel::revoke_and_ack for why, tl;dr: Rust bug
361-
enum PendingHTLCRouting {
361+
pub(super) enum PendingHTLCRouting {
362362
Forward {
363363
onion_packet: msgs::OnionPacket,
364364
short_channel_id: u64, // This should be NonZero<u64> eventually when we bump MSRV
@@ -375,8 +375,8 @@ enum PendingHTLCRouting {
375375

376376
#[derive(Clone)] // See Channel::revoke_and_ack for why, tl;dr: Rust bug
377377
pub(super) struct PendingHTLCInfo {
378-
routing: PendingHTLCRouting,
379-
incoming_shared_secret: [u8; 32],
378+
pub(super) routing: PendingHTLCRouting,
379+
pub(super) incoming_shared_secret: [u8; 32],
380380
payment_hash: PaymentHash,
381381
pub(super) amt_to_forward: u64,
382382
pub(super) outgoing_cltv_value: u32,
@@ -3011,45 +3011,59 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
30113011
HTLCForwardInfo::AddHTLC { prev_short_channel_id, prev_htlc_id, forward_info: PendingHTLCInfo {
30123012
routing, incoming_shared_secret, payment_hash, amt_to_forward, outgoing_cltv_value },
30133013
prev_funding_outpoint } => {
3014+
let htlc_failure_source = HTLCSource::PreviousHopData(HTLCPreviousHopData {
3015+
short_channel_id: prev_short_channel_id,
3016+
outpoint: prev_funding_outpoint,
3017+
htlc_id: prev_htlc_id,
3018+
incoming_packet_shared_secret: incoming_shared_secret,
3019+
});
30143020
macro_rules! fail_forward {
30153021
($msg: expr, $err_code: expr, $err_data: expr) => {
30163022
{
30173023
log_info!(self.logger, "Failed to accept/forward incoming HTLC: {}", $msg);
3018-
let htlc_source = HTLCSource::PreviousHopData(HTLCPreviousHopData {
3019-
short_channel_id: short_chan_id,
3020-
outpoint: prev_funding_outpoint,
3021-
htlc_id: prev_htlc_id,
3022-
incoming_packet_shared_secret: incoming_shared_secret,
3023-
});
3024-
failed_forwards.push((htlc_source, payment_hash,
3024+
failed_forwards.push((htlc_failure_source, payment_hash,
30253025
HTLCFailReason::Reason { failure_code: $err_code, data: $err_data }
30263026
));
30273027
continue;
30283028
}
30293029
}
30303030
}
3031+
macro_rules! fail_phantom_forward {
3032+
($msg: expr, $err_code: expr, $err_data: expr, $phantom_shared_secret: expr) => {
3033+
{
3034+
log_info!(self.logger, "Failed to accept/forward incoming phantom node HTLC: {}", $msg);
3035+
let packet = onion_utils::build_failure_packet(&$phantom_shared_secret, $err_code, &$err_data[..]).encode();
3036+
let error_data = onion_utils::encrypt_failure_packet(&$phantom_shared_secret, &packet);
3037+
failed_forwards.push((htlc_failure_source, payment_hash,
3038+
HTLCFailReason::LightningError { err: error_data }
3039+
));
3040+
continue;
3041+
}
3042+
}
3043+
}
30313044
if let PendingHTLCRouting::Forward { onion_packet, .. } = routing {
30323045
let phantom_secret_res = self.keys_manager.get_node_secret(Recipient::PhantomNode);
30333046
if phantom_secret_res.is_ok() && fake_scid::is_valid_phantom(&self.fake_scid_rand_bytes, short_chan_id) {
3034-
let shared_secret = {
3047+
let phantom_shared_secret = {
30353048
let mut arr = [0; 32];
30363049
arr.copy_from_slice(&SharedSecret::new(&onion_packet.public_key.unwrap(), &phantom_secret_res.unwrap())[..]);
30373050
arr
30383051
};
3039-
let next_hop = match onion_utils::decode_next_hop(shared_secret, &onion_packet.hop_data, onion_packet.hmac, payment_hash) {
3052+
let next_hop = match onion_utils::decode_next_hop(phantom_shared_secret, &onion_packet.hop_data, onion_packet.hmac, payment_hash) {
30403053
Ok(res) => res,
30413054
Err(onion_utils::OnionDecodeErr::Malformed { err_msg, err_code }) => {
3042-
fail_forward!(err_msg, err_code, Vec::new());
3055+
let sha256_of_onion = Sha256::hash(&onion_packet.hop_data).into_inner();
3056+
fail_forward!(err_msg, err_code, sha256_of_onion.to_vec());
30433057
},
30443058
Err(onion_utils::OnionDecodeErr::Relay { err_msg, err_code }) => {
3045-
fail_forward!(err_msg, err_code, Vec::new());
3059+
fail_phantom_forward!(err_msg, err_code, Vec::new(), phantom_shared_secret);
30463060
},
30473061
};
30483062
match next_hop {
30493063
onion_utils::Hop::Receive(hop_data) => {
3050-
match self.construct_recv_pending_htlc_info(hop_data, shared_secret, payment_hash, amt_to_forward, outgoing_cltv_value) {
3064+
match self.construct_recv_pending_htlc_info(hop_data, phantom_shared_secret, payment_hash, amt_to_forward, outgoing_cltv_value) {
30513065
Ok(info) => phantom_receives.push((prev_short_channel_id, prev_funding_outpoint, vec![(info, prev_htlc_id)])),
3052-
Err(ReceiveError { err_code, err_data, msg }) => fail_forward!(msg, err_code, err_data)
3066+
Err(ReceiveError { err_code, err_data, msg }) => fail_phantom_forward!(msg, err_code, err_data, phantom_shared_secret)
30533067
}
30543068
},
30553069
_ => panic!(),

lightning/src/ln/msgs.rs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1291,10 +1291,6 @@ impl Readable for FinalOnionHopData {
12911291

12921292
impl Writeable for OnionHopData {
12931293
fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
1294-
// Note that this should never be reachable if Rust-Lightning generated the message, as we
1295-
// check values are sane long before we get here, though its possible in the future
1296-
// user-generated messages may hit this.
1297-
if self.amt_to_forward > MAX_VALUE_MSAT { panic!("We should never be sending infinite/overflow onion payments"); }
12981294
match self.format {
12991295
OnionHopDataFormat::Legacy { short_channel_id } => {
13001296
0u8.write(w)?;
@@ -1311,9 +1307,6 @@ impl Writeable for OnionHopData {
13111307
});
13121308
},
13131309
OnionHopDataFormat::FinalNode { ref payment_data, ref keysend_preimage } => {
1314-
if let Some(final_data) = payment_data {
1315-
if final_data.total_msat > MAX_VALUE_MSAT { panic!("We should never be sending infinite/overflow onion payments"); }
1316-
}
13171310
encode_varint_length_prefixed_tlv!(w, {
13181311
(2, HighZeroBytesDroppedVarInt(self.amt_to_forward), required),
13191312
(4, HighZeroBytesDroppedVarInt(self.outgoing_cltv_value), required),

0 commit comments

Comments
 (0)