mirror of
https://github.com/lightningdevkit/rust-lightning.git
synced 2025-02-24 23:08:36 +01:00
Add total_value_received
to ClaimableHTLC
for claim validation
This is pre-work for allowing nodes to overshoot onion values and changing validation for MPP completion. This adds a field to `ClaimableHTLC` that is separate from the onion values, which represents the actual received amount reported in `PaymentClaimable` which is what we want to validate against when a user goes to claim.
This commit is contained in:
parent
31e78ff258
commit
b9f4ebdd28
1 changed files with 28 additions and 7 deletions
|
@ -194,7 +194,10 @@ struct ClaimableHTLC {
|
||||||
value: u64,
|
value: u64,
|
||||||
onion_payload: OnionPayload,
|
onion_payload: OnionPayload,
|
||||||
timer_ticks: u8,
|
timer_ticks: u8,
|
||||||
/// The sum total of all MPP parts
|
/// The total value received for a payment (sum of all MPP parts if the payment is a MPP).
|
||||||
|
/// Gets set to the amount reported when pushing [`Event::PaymentClaimable`].
|
||||||
|
total_value_received: Option<u64>,
|
||||||
|
/// The sender intended sum total of all MPP parts specified in the onion
|
||||||
total_msat: u64,
|
total_msat: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3272,7 +3275,7 @@ where
|
||||||
panic!("short_channel_id == 0 should imply any pending_forward entries are of type Receive");
|
panic!("short_channel_id == 0 should imply any pending_forward entries are of type Receive");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let claimable_htlc = ClaimableHTLC {
|
let mut claimable_htlc = ClaimableHTLC {
|
||||||
prev_hop: HTLCPreviousHopData {
|
prev_hop: HTLCPreviousHopData {
|
||||||
short_channel_id: prev_short_channel_id,
|
short_channel_id: prev_short_channel_id,
|
||||||
outpoint: prev_funding_outpoint,
|
outpoint: prev_funding_outpoint,
|
||||||
|
@ -3282,6 +3285,7 @@ where
|
||||||
},
|
},
|
||||||
value: outgoing_amt_msat,
|
value: outgoing_amt_msat,
|
||||||
timer_ticks: 0,
|
timer_ticks: 0,
|
||||||
|
total_value_received: None,
|
||||||
total_msat: if let Some(data) = &payment_data { data.total_msat } else { outgoing_amt_msat },
|
total_msat: if let Some(data) = &payment_data { data.total_msat } else { outgoing_amt_msat },
|
||||||
cltv_expiry,
|
cltv_expiry,
|
||||||
onion_payload,
|
onion_payload,
|
||||||
|
@ -3326,7 +3330,7 @@ where
|
||||||
fail_htlc!(claimable_htlc, payment_hash);
|
fail_htlc!(claimable_htlc, payment_hash);
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
let (_, htlcs) = claimable_payments.claimable_htlcs.entry(payment_hash)
|
let (_, ref mut htlcs) = claimable_payments.claimable_htlcs.entry(payment_hash)
|
||||||
.or_insert_with(|| (purpose(), Vec::new()));
|
.or_insert_with(|| (purpose(), Vec::new()));
|
||||||
if htlcs.len() == 1 {
|
if htlcs.len() == 1 {
|
||||||
if let OnionPayload::Spontaneous(_) = htlcs[0].onion_payload {
|
if let OnionPayload::Spontaneous(_) = htlcs[0].onion_payload {
|
||||||
|
@ -3357,11 +3361,13 @@ where
|
||||||
} else if total_value == $payment_data.total_msat {
|
} else if total_value == $payment_data.total_msat {
|
||||||
let prev_channel_id = prev_funding_outpoint.to_channel_id();
|
let prev_channel_id = prev_funding_outpoint.to_channel_id();
|
||||||
htlcs.push(claimable_htlc);
|
htlcs.push(claimable_htlc);
|
||||||
|
let amount_msat = htlcs.iter().map(|htlc| htlc.value).sum();
|
||||||
|
htlcs.iter_mut().for_each(|htlc| htlc.total_value_received = Some(amount_msat));
|
||||||
new_events.push(events::Event::PaymentClaimable {
|
new_events.push(events::Event::PaymentClaimable {
|
||||||
receiver_node_id: Some(receiver_node_id),
|
receiver_node_id: Some(receiver_node_id),
|
||||||
payment_hash,
|
payment_hash,
|
||||||
purpose: purpose(),
|
purpose: purpose(),
|
||||||
amount_msat: total_value,
|
amount_msat,
|
||||||
via_channel_id: Some(prev_channel_id),
|
via_channel_id: Some(prev_channel_id),
|
||||||
via_user_channel_id: Some(prev_user_channel_id),
|
via_user_channel_id: Some(prev_user_channel_id),
|
||||||
});
|
});
|
||||||
|
@ -3415,6 +3421,8 @@ where
|
||||||
}
|
}
|
||||||
match claimable_payments.claimable_htlcs.entry(payment_hash) {
|
match claimable_payments.claimable_htlcs.entry(payment_hash) {
|
||||||
hash_map::Entry::Vacant(e) => {
|
hash_map::Entry::Vacant(e) => {
|
||||||
|
let amount_msat = claimable_htlc.value;
|
||||||
|
claimable_htlc.total_value_received = Some(amount_msat);
|
||||||
let purpose = events::PaymentPurpose::SpontaneousPayment(preimage);
|
let purpose = events::PaymentPurpose::SpontaneousPayment(preimage);
|
||||||
e.insert((purpose.clone(), vec![claimable_htlc]));
|
e.insert((purpose.clone(), vec![claimable_htlc]));
|
||||||
let prev_channel_id = prev_funding_outpoint.to_channel_id();
|
let prev_channel_id = prev_funding_outpoint.to_channel_id();
|
||||||
|
@ -3960,6 +3968,7 @@ where
|
||||||
// provide the preimage, so worrying too much about the optimal handling isn't worth
|
// provide the preimage, so worrying too much about the optimal handling isn't worth
|
||||||
// it.
|
// it.
|
||||||
let mut claimable_amt_msat = 0;
|
let mut claimable_amt_msat = 0;
|
||||||
|
let mut prev_total_msat = None;
|
||||||
let mut expected_amt_msat = None;
|
let mut expected_amt_msat = None;
|
||||||
let mut valid_mpp = true;
|
let mut valid_mpp = true;
|
||||||
let mut errs = Vec::new();
|
let mut errs = Vec::new();
|
||||||
|
@ -3987,14 +3996,22 @@ where
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if expected_amt_msat.is_some() && expected_amt_msat != Some(htlc.total_msat) {
|
if prev_total_msat.is_some() && prev_total_msat != Some(htlc.total_msat) {
|
||||||
log_error!(self.logger, "Somehow ended up with an MPP payment with different total amounts - this should not be reachable!");
|
log_error!(self.logger, "Somehow ended up with an MPP payment with different expected total amounts - this should not be reachable!");
|
||||||
debug_assert!(false);
|
debug_assert!(false);
|
||||||
valid_mpp = false;
|
valid_mpp = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
prev_total_msat = Some(htlc.total_msat);
|
||||||
|
|
||||||
|
if expected_amt_msat.is_some() && expected_amt_msat != htlc.total_value_received {
|
||||||
|
log_error!(self.logger, "Somehow ended up with an MPP payment with different received total amounts - this should not be reachable!");
|
||||||
|
debug_assert!(false);
|
||||||
|
valid_mpp = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
expected_amt_msat = htlc.total_value_received;
|
||||||
|
|
||||||
expected_amt_msat = Some(htlc.total_msat);
|
|
||||||
if let OnionPayload::Spontaneous(_) = &htlc.onion_payload {
|
if let OnionPayload::Spontaneous(_) = &htlc.onion_payload {
|
||||||
// We don't currently support MPP for spontaneous payments, so just check
|
// We don't currently support MPP for spontaneous payments, so just check
|
||||||
// that there's one payment here and move on.
|
// that there's one payment here and move on.
|
||||||
|
@ -6795,6 +6812,7 @@ impl Writeable for ClaimableHTLC {
|
||||||
(1, self.total_msat, required),
|
(1, self.total_msat, required),
|
||||||
(2, self.value, required),
|
(2, self.value, required),
|
||||||
(4, payment_data, option),
|
(4, payment_data, option),
|
||||||
|
(5, self.total_value_received, option),
|
||||||
(6, self.cltv_expiry, required),
|
(6, self.cltv_expiry, required),
|
||||||
(8, keysend_preimage, option),
|
(8, keysend_preimage, option),
|
||||||
});
|
});
|
||||||
|
@ -6808,6 +6826,7 @@ impl Readable for ClaimableHTLC {
|
||||||
let mut value = 0;
|
let mut value = 0;
|
||||||
let mut payment_data: Option<msgs::FinalOnionHopData> = None;
|
let mut payment_data: Option<msgs::FinalOnionHopData> = None;
|
||||||
let mut cltv_expiry = 0;
|
let mut cltv_expiry = 0;
|
||||||
|
let mut total_value_received = None;
|
||||||
let mut total_msat = None;
|
let mut total_msat = None;
|
||||||
let mut keysend_preimage: Option<PaymentPreimage> = None;
|
let mut keysend_preimage: Option<PaymentPreimage> = None;
|
||||||
read_tlv_fields!(reader, {
|
read_tlv_fields!(reader, {
|
||||||
|
@ -6815,6 +6834,7 @@ impl Readable for ClaimableHTLC {
|
||||||
(1, total_msat, option),
|
(1, total_msat, option),
|
||||||
(2, value, required),
|
(2, value, required),
|
||||||
(4, payment_data, option),
|
(4, payment_data, option),
|
||||||
|
(5, total_value_received, option),
|
||||||
(6, cltv_expiry, required),
|
(6, cltv_expiry, required),
|
||||||
(8, keysend_preimage, option)
|
(8, keysend_preimage, option)
|
||||||
});
|
});
|
||||||
|
@ -6842,6 +6862,7 @@ impl Readable for ClaimableHTLC {
|
||||||
prev_hop: prev_hop.0.unwrap(),
|
prev_hop: prev_hop.0.unwrap(),
|
||||||
timer_ticks: 0,
|
timer_ticks: 0,
|
||||||
value,
|
value,
|
||||||
|
total_value_received,
|
||||||
total_msat: total_msat.unwrap(),
|
total_msat: total_msat.unwrap(),
|
||||||
onion_payload,
|
onion_payload,
|
||||||
cltv_expiry,
|
cltv_expiry,
|
||||||
|
|
Loading…
Add table
Reference in a new issue