Replace existing MPP-total args with `RecipientOnionFields`
What changed, and why it matters
This commit is a code cleanup and feature-enabling refactor in the Lightning Dev Kit (LDK). It moves the total amount for multi-path payments (MPP) out of individual function arguments and into a structured object called `RecipientOnionFields`. This makes it possible for future callers to send partial payments that add up to a larger total, which is useful for wallets that hold funds in multiple places. The commit itself does not appear to fix a known bug or vulnerability; it is preparation for a new capability.
No immediate security action required. Reviewers should verify that all call sites now correctly populate `RecipientOnionFields::total_mpp_amount_msat` and that no production path accidentally omits or missets the total. Because this is a partial commit in a series, monitor subsequent commits for the actual partial-MPP logic and any associated validation.
Security signals we found
Refactor centralizes MPP total amount in `RecipientOnionFields`, reducing risk of inconsistent total values being passed to onion construction
Removal of duplicate `total_msat` arguments eliminates a class of API misuse where caller-provided total could differ from recipient onion total
No direct fix for memory safety, cryptographic flaw, or consensus bug is visible in the diff
Change is part of a larger feature (partial MPP payments from multiple wallets) and may have follow-up commits with additional security implications
Evidence from the diff
The change removes redundant total_msat/total_value/recv_value_msat arguments from onion-building and payment-sending methods, using RecipientOnionFields::total_mpp_amount_msat instead. It renames the test-visible build_onion_payloads to test_build_onion_payloads and makes the internal build_onion_payloads private. Several debug_assert_eq!(total_msat, recipient_onion.total_mpp_amount_msat) checks are removed because the value now comes from a single source. A test comment about setting the onion amount to amt_msat instead of amt_msat + 1 is resolved by using amt_msat. No security bug is directly patched in this diff.
Changed components
lightning/src/ln/onion_utils.rslightning/src/ln/outbound_payment.rslightning/src/ln/channelmanager.rslightning/src/ln/onion_payment.rslightning/src/ln/blinded_payment_tests.rslightning/src/ln/functional_tests.rslightning/src/ln/htlc_reserve_unit_tests.rslightning/src/ln/max_payment_path_len_tests.rslightning/src/ln/onion_route_tests.rslightning/src/ln/payment_tests.rslightning/src/ln/reload_tests.rsInspect captured patch +101 / −135
diff --git a/lightning/src/ln/blinded_payment_tests.rs b/lightning/src/ln/blinded_payment_tests.rs
index 3cabdee..e8469ca 100644
--- a/lightning/src/ln/blinded_payment_tests.rs
+++ b/lightning/src/ln/blinded_payment_tests.rs
@@ -478,8 +478,8 @@ fn do_forward_checks_failure(check: ForwardCheckFail, intro_fails: bool) {
let session_priv = SecretKey::from_slice(&[3; 32]).unwrap();
let mut onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route.paths[0], &session_priv);
let cur_height = nodes[0].best_block_info().1;
- let (mut onion_payloads, ..) = onion_utils::build_onion_payloads(
- &route.paths[0], amt_msat, &recipient_onion_fields, cur_height, &None, None, None).unwrap();
+ let (mut onion_payloads, ..) = onion_utils::test_build_onion_payloads(
+ &route.paths[0], &recipient_onion_fields, cur_height, &None, None, None).unwrap();
// Remove the receive payload so the blinded forward payload is encoded as a final payload
// (i.e. next_hop_hmac == [0; 32])
onion_payloads.pop();
@@ -1065,8 +1065,8 @@ fn do_multi_hop_receiver_fail(check: ReceiveCheckFail) {
let mut onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route.paths[0], &session_priv);
let cur_height = nodes[0].best_block_info().1;
let recipient_onion_fields = RecipientOnionFields::spontaneous_empty(amt_msat);
- let (mut onion_payloads, ..) = onion_utils::build_onion_payloads(
- &route.paths[0], amt_msat, &recipient_onion_fields, cur_height, &None, None, None).unwrap();
+ let (mut onion_payloads, ..) = onion_utils::test_build_onion_payloads(
+ &route.paths[0], &recipient_onion_fields, cur_height, &None, None, None).unwrap();
let update_add = &mut payment_event_1_2.msgs[0];
onion_payloads.last_mut().map(|p| {
@@ -1681,7 +1681,7 @@ fn route_blinding_spec_test_vector() {
}),
};
let cur_height = 747_000;
- let (bob_onion, _, _) = onion_utils::create_payment_onion(&secp_ctx, &path, &session_priv, amt_msat, &RecipientOnionFields::spontaneous_empty(amt_msat), cur_height, &PaymentHash([0; 32]), &None, None, [0; 32]).unwrap();
+ let (bob_onion, _, _) = onion_utils::create_payment_onion(&secp_ctx, &path, &session_priv, &RecipientOnionFields::spontaneous_empty(amt_msat), cur_height, &PaymentHash([0; 32]), &None, None, [0; 32]).unwrap();
struct TestEcdhSigner {
node_secret: SecretKey,
@@ -1905,7 +1905,7 @@ fn test_combined_trampoline_onion_creation_vectors() {
let amt_msat = 150_000_000;
let cur_height = 800_000;
let recipient_onion_fields = RecipientOnionFields::secret_only(payment_secret, amt_msat);
- let (bob_onion, htlc_msat, htlc_cltv) = onion_utils::create_payment_onion_internal(&secp_ctx, &path, &outer_session_key, amt_msat, &recipient_onion_fields, cur_height, &associated_data, &None, None, outer_onion_prng_seed, Some(session_priv), Some([0; 32])).unwrap();
+ let (bob_onion, htlc_msat, htlc_cltv) = onion_utils::create_payment_onion_internal(&secp_ctx, &path, &outer_session_key, &recipient_onion_fields, cur_height, &associated_data, &None, None, outer_onion_prng_seed, Some(session_priv), Some([0; 32])).unwrap();
let outer_onion_packet_hex = bob_onion.encode().to_lower_hex_string();
assert_eq!(outer_onion_packet_hex, "00025fd60556c134ae97e4baedba220a644037754ee67c54fd05e93bf40c17cbb73362fb9dee96001ff229945595b6edb59437a6bc143406d3f90f749892a84d8d430c6890437d26d5bfc599d565316ef51347521075bbab87c59c57bcf20af7e63d7192b46cf171e4f73cb11f9f603915389105d91ad630224bea95d735e3988add1e24b5bf28f1d7128db64284d90a839ba340d088c74b1fb1bd21136b1809428ec5399c8649e9bdf92d2dcfc694deae5046fa5b2bdf646847aaad73f5e95275763091c90e71031cae1f9a770fdea559642c9c02f424a2a28163dd0957e3874bd28a97bec67d18c0321b0e68bc804aa8345b17cb626e2348ca06c8312a167c989521056b0f25c55559d446507d6c491d50605cb79fa87929ce64b0a9860926eeaec2c431d926a1cadb9a1186e4061cb01671a122fc1f57602cbef06d6c194ec4b715c2e3dd4120baca3172cd81900b49fef857fb6d6afd24c983b608108b0a5ac0c1c6c52011f23b8778059ffadd1bb7cd06e2525417365f485a7fd1d4a9ba3818ede7cdc9e71afee8532252d08e2531ca52538655b7e8d912f7ec6d37bbcce8d7ec690709dbf9321e92c565b78e7fe2c22edf23e0902153d1ca15a112ad32fb19695ec65ce11ddf670da7915f05ad4b86c154fb908cb567315d1124f303f75fa075ebde8ef7bb12e27737ad9e4924439097338ea6d7a6fc3721b88c9b830a34e8d55f4c582b74a3895cc848fe57f4fe29f115dabeb6b3175be15d94408ed6771109cfaf57067ae658201082eae7605d26b1449af4425ae8e8f58cdda5c6265f1fd7a386fc6cea3074e4f25b909b96175883676f7610a00fdf34df9eb6c7b9a4ae89b839c69fd1f285e38cdceb634d782cc6d81179759bc9fd47d7fd060470d0b048287764c6837963274e708314f017ac7dc26d0554d59bfcfd3136225798f65f0b0fea337c6b256ebbb63a90b994c0ab93fd8b1d6bd4c74aebe535d6110014cd3d525394027dfe8faa98b4e9b2bee7949eb1961f1b026791092f84deea63afab66603dbe9b6365a102a1fef2f6b9744bc1bb091a8da9130d34d4d39f25dbad191649cfb67e10246364b7ce0c6ec072f9690cabb459d9fda0c849e17535de4357e9907270c75953fca3c845bb613926ecf73205219c7057a4b6bb244c184362bb4e2f24279dc4e60b94a5b1ec11c34081a628428ba5646c995b9558821053ba9c84a05afbf00dabd60223723096516d2f5668f3ec7e11612b01eb7a3a0506189a2272b88e89807943adb34291a17f6cb5516ffd6f945a1c42a524b21f096d66f350b1dad4db455741ae3d0e023309fbda5ef55fb0dc74f3297041448b2be76c525141963934c6afc53d263fb7836626df502d7c2ee9e79cbbd87afd84bbb8dfbf45248af3cd61ad5fac827e7683ca4f91dfad507a8eb9c17b2c9ac5ec051fe645a4a6cb37136f6f19b611e0ea8da7960af2d779507e55f57305bc74b7568928c5dd5132990fe54c22117df91c257d8c7b61935a018a28c1c3b17bab8e4294fa699161ec21123c9fc4e71079df31f300c2822e1246561e04765d3aab333eafd026c7431ac7616debb0e022746f4538e1c6348b600c988eeb2d051fc60c468dca260a84c79ab3ab8342dc345a764672848ea234e17332bc124799daf7c5fcb2e2358514a7461357e1c19c802c5ee32deccf1776885dd825bedd5f781d459984370a6b7ae885d4483a76ddb19b30f47ed47cd56aa5a079a89793dbcad461c59f2e002067ac98dd5a534e525c9c46c2af730741bf1f8629357ec0bfc0bc9ecb31af96777e507648ff4260dc3673716e098d9111dfd245f1d7c55a6de340deb8bd7a053e5d62d760f184dc70ca8fa255b9023b9b9aedfb6e419a5b5951ba0f83b603793830ee68d442d7b88ee1bbf6bbd1bcd6f68cc1af");
@@ -1996,7 +1996,7 @@ fn test_trampoline_inbound_payment_decoding() {
let amt_msat = 150_000_001;
let cur_height = 800_001;
let recipient_onion_fields = RecipientOnionFields::secret_only(payment_secret, amt_msat);
- let (bob_onion, _, _) = onion_utils::create_payment_onion(&secp_ctx, &path, &session_priv, amt_msat, &recipient_onion_fields, cur_height, &PaymentHash([0; 32]), &None, None, [0; 32]).unwrap();
+ let (bob_onion, _, _) = onion_utils::create_payment_onion(&secp_ctx, &path, &session_priv, &recipient_onion_fields, cur_height, &PaymentHash([0; 32]), &None, None, [0; 32]).unwrap();
struct TestEcdhSigner {
node_secret: SecretKey,
@@ -2181,7 +2181,7 @@ fn test_trampoline_forward_payload_encoded_as_receive() {
});
let recipient_onion_fields = RecipientOnionFields::spontaneous_empty(amt_msat);
- let (mut trampoline_payloads, outer_total_msat, outer_starting_htlc_offset) = onion_utils::build_trampoline_onion_payloads(&blinded_tail, amt_msat, &recipient_onion_fields, 32, &None).unwrap();
+ let (mut trampoline_payloads, outer_total_msat, outer_starting_htlc_offset) = onion_utils::build_trampoline_onion_payloads(&blinded_tail, &recipient_onion_fields, 32, &None).unwrap();
// pop the last dummy hop
trampoline_payloads.pop();
@@ -2196,7 +2196,7 @@ fn test_trampoline_forward_payload_encoded_as_receive() {
).unwrap();
let recipient_onion_fields = RecipientOnionFields::spontaneous_empty(outer_total_msat);
- let (outer_payloads, _, _) = onion_utils::build_onion_payloads(&route.paths[0], outer_total_msat, &recipient_onion_fields, outer_starting_htlc_offset, &None, None, Some(trampoline_packet)).unwrap();
+ let (outer_payloads, _, _) = onion_utils::test_build_onion_payloads(&route.paths[0], &recipient_onion_fields, outer_starting_htlc_offset, &None, None, Some(trampoline_packet)).unwrap();
let outer_onion_keys = onion_utils::construct_onion_keys(&secp_ctx, &route.clone().paths[0], &outer_session_priv);
let outer_packet = onion_utils::construct_onion_packet(
outer_payloads,
@@ -2489,7 +2489,6 @@ fn replacement_onion(
let (mut trampoline_payloads, outer_total_msat, outer_starting_htlc_offset) =
onion_utils::build_trampoline_onion_payloads(
&blinded_tail,
- original_amt_msat,
&recipient_onion_fields,
starting_htlc_offset,
&None,
@@ -2527,9 +2526,8 @@ fn replacement_onion(
// Use a different session key to construct the replacement onion packet. Note that the
// sender isn't aware of this and won't be able to decode the fulfill hold times.
let recipient_onion_fields = RecipientOnionFields::spontaneous_empty(outer_total_msat);
- let (mut outer_payloads, _, _) = onion_utils::build_onion_payloads(
+ let (mut outer_payloads, _, _) = onion_utils::test_build_onion_payloads(
&route.paths[0],
- outer_total_msat,
&recipient_onion_fields,
outer_starting_htlc_offset,
&None,
diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs
index 18bbbbc..99d5794 100644
--- a/lightning/src/ln/channelmanager.rs
+++ b/lightning/src/ln/channelmanager.rs
@@ -5153,15 +5153,14 @@ impl<
#[cfg(any(test, feature = "_externalize_tests"))]
pub(crate) fn test_send_payment_along_path(
&self, path: &Path, payment_hash: &PaymentHash, recipient_onion: RecipientOnionFields,
- total_value: u64, cur_height: u32, payment_id: PaymentId,
- keysend_preimage: &Option<PaymentPreimage>, session_priv_bytes: [u8; 32],
+ cur_height: u32, payment_id: PaymentId, keysend_preimage: &Option<PaymentPreimage>,
+ session_priv_bytes: [u8; 32],
) -> Result<(), APIError> {
let _lck = self.total_consistency_lock.read().unwrap();
self.send_payment_along_path(SendAlongPathArgs {
path,
payment_hash,
recipient_onion: &recipient_onion,
- total_value,
cur_height,
payment_id,
keysend_preimage,
@@ -5177,7 +5176,6 @@ impl<
path,
payment_hash,
recipient_onion,
- total_value,
cur_height,
payment_id,
keysend_preimage,
@@ -5202,7 +5200,6 @@ impl<
&self.secp_ctx,
&path,
&session_priv,
- total_value,
recipient_onion,
cur_height,
payment_hash,
@@ -5421,7 +5418,7 @@ impl<
pub(super) fn test_send_payment_internal(
&self, route: &Route, payment_hash: PaymentHash, recipient_onion: RecipientOnionFields,
keysend_preimage: Option<PaymentPreimage>, payment_id: PaymentId,
- recv_value_msat: Option<u64>, onion_session_privs: Vec<[u8; 32]>,
+ onion_session_privs: Vec<[u8; 32]>,
) -> Result<(), PaymentSendFailure> {
let best_block_height = self.best_block.read().unwrap().height;
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self);
@@ -5431,7 +5428,6 @@ impl<
recipient_onion,
keysend_preimage,
payment_id,
- recv_value_msat,
onion_session_privs,
&self.node_signer,
best_block_height,
@@ -20074,7 +20070,7 @@ mod tests {
let session_privs = nodes[0].node.test_add_new_pending_payment(our_payment_hash,
RecipientOnionFields::secret_only(payment_secret, 200_000), payment_id, &mpp_route).unwrap();
nodes[0].node.test_send_payment_along_path(&mpp_route.paths[0], &our_payment_hash,
- RecipientOnionFields::secret_only(payment_secret, 200_000), 200_000, cur_height, payment_id, &None, session_privs[0]).unwrap();
+ RecipientOnionFields::secret_only(payment_secret, 200_000), cur_height, payment_id, &None, session_privs[0]).unwrap();
check_added_monitors(&nodes[0], 1);
let mut events = nodes[0].node.get_and_clear_pending_msg_events();
assert_eq!(events.len(), 1);
@@ -20110,7 +20106,7 @@ mod tests {
// Send the second half of the original MPP payment.
nodes[0].node.test_send_payment_along_path(&mpp_route.paths[1], &our_payment_hash,
- RecipientOnionFields::secret_only(payment_secret, 200_000), 200_000, cur_height, payment_id, &None, session_privs[1]).unwrap();
+ RecipientOnionFields::secret_only(payment_secret, 200_000), cur_height, payment_id, &None, session_privs[1]).unwrap();
check_added_monitors(&nodes[0], 1);
let mut events = nodes[0].node.get_and_clear_pending_msg_events();
assert_eq!(events.len(), 1);
@@ -20358,7 +20354,7 @@ mod tests {
let session_privs = nodes[0].node.test_add_new_pending_payment(mismatch_payment_hash,
RecipientOnionFields::spontaneous_empty(10_000), PaymentId(mismatch_payment_hash.0), &route).unwrap();
nodes[0].node.test_send_payment_internal(&route, mismatch_payment_hash,
- RecipientOnionFields::spontaneous_empty(10_000), Some(test_preimage), PaymentId(mismatch_payment_hash.0), None, session_privs).unwrap();
+ RecipientOnionFields::spontaneous_empty(10_000), Some(test_preimage), PaymentId(mismatch_payment_hash.0), session_privs).unwrap();
check_added_monitors(&nodes[0], 1);
let updates = get_htlc_update_msgs(&nodes[0], &nodes[1].node.get_our_node_id());
diff --git a/lightning/src/ln/functional_tests.rs b/lightning/src/ln/functional_tests.rs
index 796c151..09a87d9 100644
--- a/lightning/src/ln/functional_tests.rs
+++ b/lightning/src/ln/functional_tests.rs
@@ -2284,9 +2284,8 @@ pub fn fail_backward_pending_htlc_upon_channel_failure() {
let session_priv = SecretKey::from_slice(&[42; 32]).unwrap();
let current_height = nodes[1].node.best_block.read().unwrap().height + 1;
let recipient_onion_fields = RecipientOnionFields::secret_only(payment_secret, 50_000);
- let (onion_payloads, _amount_msat, cltv_expiry) = onion_utils::build_onion_payloads(
+ let (onion_payloads, _amount_msat, cltv_expiry) = onion_utils::test_build_onion_payloads(
&route.paths[0],
- 50_000,
&recipient_onion_fields,
current_height,
&None,
@@ -3321,7 +3320,6 @@ fn do_test_htlc_timeout(send_partial_mpp: bool) {
&route.paths[0],
&our_payment_hash,
RecipientOnionFields::secret_only(payment_secret, 200_000),
- 200_000,
cur_height,
payment_id,
&None,
@@ -7011,10 +7009,9 @@ pub fn test_onion_value_mpp_set_calculation() {
let onion = RecipientOnionFields::secret_only(payment_secret, total_msat);
let onion_session_privs =
nodes[0].node.test_add_new_pending_payment(hash, onion.clone(), id, &route).unwrap();
- let amt = Some(total_msat);
nodes[0]
.node
- .test_send_payment_internal(&route, hash, onion, None, id, amt, onion_session_privs)
+ .test_send_payment_internal(&route, hash, onion, None, id, onion_session_privs)
.unwrap();
check_added_monitors(&nodes[0], expected_paths.len());
@@ -7042,9 +7039,8 @@ pub fn test_onion_value_mpp_set_calculation() {
&session_priv,
);
let recipient_onion_fields = RecipientOnionFields::secret_only(payment_secret, 100_000);
- let (mut onion_payloads, _, _) = onion_utils::build_onion_payloads(
+ let (mut onion_payloads, _, _) = onion_utils::test_build_onion_payloads(
&route.paths[0],
- 100_000,
&recipient_onion_fields,
height + 1,
&None,
@@ -7150,10 +7146,9 @@ fn do_test_overshoot_mpp(msat_amounts: &[u64], total_msat: u64) {
let onion_session_privs =
nodes[src_idx].node.test_add_new_pending_payment(hash, onion, id, &route).unwrap();
let onion = RecipientOnionFields::secret_only(payment_secret, total_msat);
- let amt = Some(total_msat);
nodes[src_idx]
.node
- .test_send_payment_internal(&route, hash, onion, None, id, amt, onion_session_privs)
+ .test_send_payment_internal(&route, hash, onion, None, id, onion_session_privs)
.unwrap();
check_added_monitors(&nodes[src_idx], expected_paths.len());
@@ -8488,7 +8483,7 @@ pub fn test_inconsistent_mpp_params() {
let priv_a = session_privs[0];
nodes[0]
.node
- .test_send_payment_along_path(path_a, &hash, onion, real_amt, cur_height, id, &None, priv_a)
+ .test_send_payment_along_path(path_a, &hash, onion, cur_height, id, &None, priv_a)
.unwrap();
check_added_monitors(&nodes[0], 1);
@@ -8501,11 +8496,10 @@ pub fn test_inconsistent_mpp_params() {
let path_b = &route.paths[1];
let onion = RecipientOnionFields::secret_only(payment_secret, 14_000_000);
- let amt_b = 14_000_000;
let priv_b = session_privs[1];
nodes[0]
.node
- .test_send_payment_along_path(path_b, &hash, onion, amt_b, cur_height, id, &None, priv_b)
+ .test_send_payment_along_path(path_b, &hash, onion, cur_height, id, &None, priv_b)
.unwrap();
check_added_monitors(&nodes[0], 1);
@@ -8565,7 +8559,7 @@ pub fn test_inconsistent_mpp_params() {
let priv_c = session_privs[2];
nodes[0]
.node
- .test_send_payment_along_path(path_b, &hash, onion, real_amt, cur_height, id, &None, priv_c)
+ .test_send_payment_along_path(path_b, &hash, onion, cur_height, id, &None, priv_c)
.unwrap();
check_added_monitors(&nodes[0], 1);
diff --git a/lightning/src/ln/htlc_reserve_unit_tests.rs b/lightning/src/ln/htlc_reserve_unit_tests.rs
index 1a1cfed..6f02c93 100644
--- a/lightning/src/ln/htlc_reserve_unit_tests.rs
+++ b/lightning/src/ln/htlc_reserve_unit_tests.rs
@@ -822,9 +822,8 @@ pub fn do_test_fee_spike_buffer(cfg: Option<UserConfig>, htlc_fails: bool) {
let onion_keys = onion_utils::construct_onion_keys(&secp_ctx, &route.paths[0], &session_priv);
let recipient_onion_fields =
RecipientOnionFields::secret_only(payment_secret, payment_amt_msat);
- let (onion_payloads, htlc_msat, htlc_cltv) = onion_utils::build_onion_payloads(
+ let (onion_payloads, htlc_msat, htlc_cltv) = onion_utils::test_build_onion_payloads(
&route.paths[0],
- payment_amt_msat,
&recipient_onion_fields,
cur_height,
&None,
@@ -1070,9 +1069,8 @@ pub fn test_chan_reserve_violation_inbound_htlc_outbound_channel() {
let cur_height = nodes[1].node.best_block.read().unwrap().height + 1;
let onion_keys = onion_utils::construct_onion_keys(&secp_ctx, &route.paths[0], &session_priv);
let recipient_onion_fields = RecipientOnionFields::secret_only(payment_secret, 700_000);
- let (onion_payloads, htlc_msat, htlc_cltv) = onion_utils::build_onion_payloads(
+ let (onion_payloads, htlc_msat, htlc_cltv) = onion_utils::test_build_onion_payloads(
&route.paths[0],
- 700_000,
&recipient_onion_fields,
cur_height,
&None,
@@ -1255,9 +1253,8 @@ pub fn test_chan_reserve_violation_inbound_htlc_inbound_chan() {
let cur_height = nodes[0].node.best_block.read().unwrap().height + 1;
let onion_keys = onion_utils::construct_onion_keys(&secp_ctx, &route_2.paths[0], &session_priv);
let recipient_onion_fields = RecipientOnionFields::spontaneous_empty(recv_value_2);
- let (onion_payloads, htlc_msat, htlc_cltv) = onion_utils::build_onion_payloads(
+ let (onion_payloads, htlc_msat, htlc_cltv) = onion_utils::test_build_onion_payloads(
&route_2.paths[0],
- recv_value_2,
&recipient_onion_fields,
cur_height,
&None,
@@ -1645,9 +1642,8 @@ pub fn test_update_add_htlc_bolt2_receiver_check_max_htlc_limit() {
&session_priv,
);
let recipient_onion_fields = RecipientOnionFields::secret_only(our_payment_secret, send_amt);
- let (onion_payloads, _htlc_msat, htlc_cltv) = onion_utils::build_onion_payloads(
+ let (onion_payloads, _htlc_msat, htlc_cltv) = onion_utils::test_build_onion_payloads(
&route.paths[0],
- send_amt,
&recipient_onion_fields,
cur_height,
&None,
@@ -2247,9 +2243,8 @@ pub fn do_test_dust_limit_fee_accounting(can_afford: bool) {
onion_utils::construct_onion_keys(&secp_ctx, &route_0_1.paths[0], &session_priv);
let recipient_onion_fields =
RecipientOnionFields::secret_only(payment_secret_0_1, HTLC_AMT_SAT * 1000);
- let (onion_payloads, amount_msat, cltv_expiry) = onion_utils::build_onion_payloads(
+ let (onion_payloads, amount_msat, cltv_expiry) = onion_utils::test_build_onion_payloads(
&route_0_1.paths[0],
- HTLC_AMT_SAT * 1000,
&recipient_onion_fields,
cur_height,
&None,
diff --git a/lightning/src/ln/max_payment_path_len_tests.rs b/lightning/src/ln/max_payment_path_len_tests.rs
index ea78449..45640d3 100644
--- a/lightning/src/ln/max_payment_path_len_tests.rs
+++ b/lightning/src/ln/max_payment_path_len_tests.rs
@@ -139,7 +139,6 @@ fn large_payment_metadata() {
&secp_ctx,
&route_0_1.paths[0],
&test_utils::privkey(42),
- MIN_FINAL_VALUE_ESTIMATE_WITH_OVERPAY,
&too_large_onion,
nodes[0].best_block_info().1 + DEFAULT_MAX_TOTAL_CLTV_EXPIRY_DELTA,
&payment_hash,
@@ -369,9 +368,8 @@ fn blinded_path_with_custom_tlv() {
// Calculate the maximum custom TLV value size where a valid onion packet is still possible.
const CUSTOM_TLV_TYPE: u64 = 65537;
let mut route = get_route(&nodes[1], &route_params).unwrap();
- let reserved_packet_bytes_without_custom_tlv: usize = onion_utils::build_onion_payloads(
+ let reserved_packet_bytes_without_custom_tlv: usize = onion_utils::test_build_onion_payloads(
&route.paths[0],
- MIN_FINAL_VALUE_ESTIMATE_WITH_OVERPAY,
&RecipientOnionFields::spontaneous_empty(MIN_FINAL_VALUE_ESTIMATE_WITH_OVERPAY),
nodes[0].best_block_info().1 + DEFAULT_MAX_TOTAL_CLTV_EXPIRY_DELTA,
&None,
@@ -433,7 +431,6 @@ fn blinded_path_with_custom_tlv() {
&secp_ctx,
&route.paths[0],
&test_utils::privkey(42),
- MIN_FINAL_VALUE_ESTIMATE_WITH_OVERPAY,
&too_large_onion,
nodes[0].best_block_info().1 + DEFAULT_MAX_TOTAL_CLTV_EXPIRY_DELTA,
&payment_hash,
diff --git a/lightning/src/ln/onion_payment.rs b/lightning/src/ln/onion_payment.rs
index d0d50c6..def4a18 100644
--- a/lightning/src/ln/onion_payment.rs
+++ b/lightning/src/ln/onion_payment.rs
@@ -779,7 +779,7 @@ mod tests {
let charlie_pk = PublicKey::from_secret_key(&secp_ctx, &charlie.get_node_secret_key());
let (
- session_priv, total_amt_msat, cur_height, mut recipient_onion, keysend_preimage, payment_hash,
+ session_priv, _total_amt_msat, cur_height, mut recipient_onion, keysend_preimage, payment_hash,
prng_seed, hops, ..
) = payment_onion_args(bob_pk, charlie_pk);
@@ -788,8 +788,8 @@ mod tests {
let path = Path { hops, blinded_tail: None, };
let onion_keys = super::onion_utils::construct_onion_keys(&secp_ctx, &path, &session_priv);
- let (onion_payloads, ..) = super::onion_utils::build_onion_payloads(
- &path, total_amt_msat, &recipient_onion, cur_height + 1, &Some(keysend_preimage), None, None
+ let (onion_payloads, ..) = super::onion_utils::test_build_onion_payloads(
+ &path, &recipient_onion, cur_height + 1, &Some(keysend_preimage), None, None
).unwrap();
assert!(super::onion_utils::construct_onion_packet(
@@ -817,7 +817,7 @@ mod tests {
};
let (onion, amount_msat, cltv_expiry) = create_payment_onion(
- &secp_ctx, &path, &session_priv, total_amt_msat, &recipient_onion,
+ &secp_ctx, &path, &session_priv, &recipient_onion,
cur_height, &payment_hash, &Some(preimage), None, prng_seed
).unwrap();
diff --git a/lightning/src/ln/onion_route_tests.rs b/lightning/src/ln/onion_route_tests.rs
index 74c76ee..ceb9300 100644
--- a/lightning/src/ln/onion_route_tests.rs
+++ b/lightning/src/ln/onion_route_tests.rs
@@ -25,7 +25,7 @@ use crate::ln::msgs::{
OutboundOnionPayload, OutboundTrampolinePayload,
};
use crate::ln::onion_utils::{
- self, build_onion_payloads, construct_onion_keys, LocalHTLCFailureReason,
+ self, construct_onion_keys, test_build_onion_payloads, LocalHTLCFailureReason,
};
use crate::ln::outbound_payment::RecipientOnionFields;
use crate::ln::wire::Encode;
@@ -527,7 +527,7 @@ fn test_onion_failure() {
let recipient_fields = RecipientOnionFields::spontaneous_empty(40000);
let path = &route.paths[0];
let (mut onion_payloads, _htlc_msat, _htlc_cltv) =
- build_onion_payloads(path, 40000, &recipient_fields, cur_height, &None, None, None)
+ test_build_onion_payloads(path, &recipient_fields, cur_height, &None, None, None)
.unwrap();
let mut new_payloads = Vec::new();
for payload in onion_payloads.drain(..) {
@@ -569,7 +569,7 @@ fn test_onion_failure() {
let recipient_fields = RecipientOnionFields::spontaneous_empty(40000);
let path = &route.paths[0];
let (mut onion_payloads, _htlc_msat, _htlc_cltv) =
- build_onion_payloads(path, 40000, &recipient_fields, cur_height, &None, None, None)
+ test_build_onion_payloads(path, &recipient_fields, cur_height, &None, None, None)
.unwrap();
let mut new_payloads = Vec::new();
for payload in onion_payloads.drain(..) {
@@ -1288,7 +1288,7 @@ fn test_onion_failure() {
let recipient_fields = RecipientOnionFields::spontaneous_empty(40000);
let path = &route.paths[0];
let (onion_payloads, _, htlc_cltv) =
- build_onion_payloads(path, 40000, &recipient_fields, height, &None, None, None)
+ test_build_onion_payloads(path, &recipient_fields, height, &None, None, None)
.unwrap();
let onion_packet = onion_utils::construct_onion_packet(
onion_payloads,
@@ -1841,8 +1841,7 @@ fn test_always_create_tlv_format_onion_payloads() {
let recipient_fields = RecipientOnionFields::spontaneous_empty(40000);
let path = &route.paths[0];
let (onion_payloads, _htlc_msat, _htlc_cltv) =
- build_onion_payloads(path, 40000, &recipient_fields, cur_height, &None, None, None)
- .unwrap();
+ test_build_onion_payloads(path, &recipient_fields, cur_height, &None, None, None).unwrap();
match onion_payloads[0] {
msgs::OutboundOnionPayload::Forward { .. } => {},
@@ -1978,7 +1977,6 @@ fn test_trampoline_onion_payload_assembly_values() {
let (trampoline_payloads, outer_total_msat, outer_starting_htlc_offset) =
onion_utils::build_trampoline_onion_payloads(
&path.blinded_tail.as_ref().unwrap(),
- amt_msat,
&recipient_onion_fields,
cur_height,
&None,
@@ -2041,9 +2039,8 @@ fn test_trampoline_onion_payload_assembly_values() {
let recipient_onion_fields =
RecipientOnionFields::secret_only(payment_secret, outer_total_msat);
- let (outer_payloads, total_msat, total_htlc_offset) = build_onion_payloads(
+ let (outer_payloads, total_msat, total_htlc_offset) = test_build_onion_payloads(
&path,
- outer_total_msat,
&recipient_onion_fields,
outer_starting_htlc_offset,
&None,
@@ -2080,7 +2077,6 @@ fn test_trampoline_onion_payload_assembly_values() {
&Secp256k1::new(),
&path,
&session_priv,
- amt_msat,
&recipient_onion_fields,
cur_height,
&payment_hash,
@@ -2540,9 +2536,8 @@ fn test_phantom_invalid_onion_payload() {
construct_onion_keys(&Secp256k1::new(), &route.paths[0], &session_priv);
let recipient_onion_fields =
RecipientOnionFields::secret_only(payment_secret, msgs::MAX_VALUE_MSAT + 1);
- let (mut onion_payloads, _, _) = build_onion_payloads(
+ let (mut onion_payloads, _, _) = test_build_onion_payloads(
&route.paths[0],
- msgs::MAX_VALUE_MSAT + 1,
&recipient_onion_fields,
height + 1,
&None,
diff --git a/lightning/src/ln/onion_utils.rs b/lightning/src/ln/onion_utils.rs
index 22cb758..a95012d 100644
--- a/lightning/src/ln/onion_utils.rs
+++ b/lightning/src/ln/onion_utils.rs
@@ -193,7 +193,7 @@ trait OnionPayload<'a, 'b> {
) -> Self;
fn new_receive(
recipient_onion: &'a RecipientOnionFields, keysend_preimage: Option<PaymentPreimage>,
- sender_intended_htlc_amt_msat: u64, total_msat: u64, cltv_expiry_height: u32,
+ sender_intended_htlc_amt_msat: u64, cltv_expiry_height: u32,
) -> Result<Self::ReceiveType, APIError>;
fn new_blinded_forward(
encrypted_tlvs: &'a Vec<u8>, intro_node_blinding_point: Option<PublicKey>,
@@ -205,8 +205,8 @@ trait OnionPayload<'a, 'b> {
custom_tlvs: &'a Vec<(u64, Vec<u8>)>,
) -> Self;
fn new_trampoline_entry(
- total_msat: u64, amt_to_forward: u64, outgoing_cltv_value: u32,
- recipient_onion: &'a RecipientOnionFields, packet: msgs::TrampolineOnionPacket,
+ amt_to_forward: u64, outgoing_cltv_value: u32, recipient_onion: &'a RecipientOnionFields,
+ packet: msgs::TrampolineOnionPacket,
) -> Result<Self::ReceiveType, APIError>;
}
impl<'a, 'b> OnionPayload<'a, 'b> for msgs::OutboundOnionPayload<'a> {
@@ -217,13 +217,15 @@ impl<'a, 'b> OnionPayload<'a, 'b> for msgs::OutboundOnionPayload<'a> {
}
fn new_receive(
recipient_onion: &'a RecipientOnionFields, keysend_preimage: Option<PaymentPreimage>,
- sender_intended_htlc_amt_msat: u64, total_msat: u64, cltv_expiry_height: u32,
+ sender_intended_htlc_amt_msat: u64, cltv_expiry_height: u32,
) -> Result<Self::ReceiveType, APIError> {
- debug_assert_eq!(total_msat, recipient_onion.total_mpp_amount_msat);
Ok(Self::Receive {
- payment_data: recipient_onion
- .payment_secret
- .map(|payment_secret| msgs::FinalOnionHopData { payment_secret, total_msat }),
+ payment_data: recipient_onion.payment_secret.map(|payment_secret| {
+ msgs::FinalOnionHopData {
+ payment_secret,
+ total_msat: recipient_onion.total_mpp_amount_msat,
+ }
+ }),
payment_metadata: recipient_onion.payment_metadata.as_ref(),
keysend_preimage,
custom_tlvs: &recipient_onion.custom_tlvs,
@@ -255,16 +257,18 @@ impl<'a, 'b> OnionPayload<'a, 'b> for msgs::OutboundOnionPayload<'a> {
}
fn new_trampoline_entry(
- total_msat: u64, amt_to_forward: u64, outgoing_cltv_value: u32,
- recipient_onion: &'a RecipientOnionFields, packet: msgs::TrampolineOnionPacket,
+ amt_to_forward: u64, outgoing_cltv_value: u32, recipient_onion: &'a RecipientOnionFields,
+ packet: msgs::TrampolineOnionPacket,
) -> Result<Self, APIError> {
- debug_assert_eq!(total_msat, recipient_onion.total_mpp_amount_msat);
Ok(Self::TrampolineEntrypoint {
amt_to_forward,
outgoing_cltv_value,
- multipath_trampoline_data: recipient_onion
- .payment_secret
- .map(|payment_secret| msgs::FinalOnionHopData { payment_secret, total_msat }),
+ multipath_trampoline_data: recipient_onion.payment_secret.map(|payment_secret| {
+ msgs::FinalOnionHopData {
+ payment_secret,
+ total_msat: recipient_onion.total_mpp_amount_msat,
+ }
+ }),
trampoline_packet: packet,
})
}
@@ -279,7 +283,7 @@ impl<'a, 'b> OnionPayload<'a, 'b> for msgs::OutboundTrampolinePayload<'a> {
}
fn new_receive(
_recipient_onion: &'a RecipientOnionFields, _keysend_preimage: Option<PaymentPreimage>,
- _sender_intended_htlc_amt_msat: u64, _total_msat: u64, _cltv_expiry_height: u32,
+ _sender_intended_htlc_amt_msat: u64, _cltv_expiry_height: u32,
) -> Result<Self::ReceiveType, APIError> {
Err(APIError::InvalidRoute {
err: "Unblinded receiving is not supported for Trampoline!".to_string(),
@@ -308,7 +312,7 @@ impl<'a, 'b> OnionPayload<'a, 'b> for msgs::OutboundTrampolinePayload<'a> {
}
fn new_trampoline_entry(
- _total_msat: u64, _amt_to_forward: u64, _outgoing_cltv_value: u32,
+ _amt_to_forward: u64, _outgoing_cltv_value: u32,
_recipient_onion: &'a RecipientOnionFields, _packet: msgs::TrampolineOnionPacket,
) -> Result<Self::ReceiveType, APIError> {
Err(APIError::InvalidRoute {
@@ -410,7 +414,7 @@ pub(super) fn construct_trampoline_onion_keys<T: secp256k1::Signing>(
}
pub(super) fn build_trampoline_onion_payloads<'a>(
- blinded_tail: &'a BlindedTail, total_msat: u64, recipient_onion: &'a RecipientOnionFields,
+ blinded_tail: &'a BlindedTail, recipient_onion: &'a RecipientOnionFields,
starting_htlc_offset: u32, keysend_preimage: &Option<PaymentPreimage>,
) -> Result<(Vec<msgs::OutboundTrampolinePayload<'a>>, u64, u32), APIError> {
let mut res: Vec<msgs::OutboundTrampolinePayload> =
@@ -425,7 +429,6 @@ pub(super) fn build_trampoline_onion_payloads<'a>(
let (value_msat, cltv) = build_onion_payloads_callback(
blinded_tail.trampoline_hops.iter(),
Some(blinded_tail_with_hop_iter),
- total_msat,
recipient_onion,
starting_htlc_offset,
keysend_preimage,
@@ -439,14 +442,28 @@ pub(super) fn build_trampoline_onion_payloads<'a>(
}
/// returns the hop data, as well as the first-hop value_msat and CLTV value we should send.
-pub(super) fn build_onion_payloads<'a>(
- path: &'a Path, total_msat: u64, recipient_onion: &'a RecipientOnionFields,
- starting_htlc_offset: u32, keysend_preimage: &Option<PaymentPreimage>,
- invoice_request: Option<&'a InvoiceRequest>,
+#[cfg(any(test, feature = "_externalize_tests"))]
+pub(crate) fn test_build_onion_payloads<'a>(
+ path: &'a Path, recipient_onion: &'a RecipientOnionFields, starting_htlc_offset: u32,
+ keysend_preimage: &Option<PaymentPreimage>, invoice_request: Option<&'a InvoiceRequest>,
trampoline_packet: Option<msgs::TrampolineOnionPacket>,
) -> Result<(Vec<msgs::OutboundOnionPayload<'a>>, u64, u32), APIError> {
- debug_assert_eq!(total_msat, recipient_onion.total_mpp_amount_msat);
+ build_onion_payloads(
+ path,
+ recipient_onion,
+ starting_htlc_offset,
+ keysend_preimage,
+ invoice_request,
+ trampoline_packet,
+ )
+}
+/// returns the hop data, as well as the first-hop value_msat and CLTV value we should send.
+fn build_onion_payloads<'a>(
+ path: &'a Path, recipient_onion: &'a RecipientOnionFields, starting_htlc_offset: u32,
+ keysend_preimage: &Option<PaymentPreimage>, invoice_request: Option<&'a InvoiceRequest>,
+ trampoline_packet: Option<msgs::TrampolineOnionPacket>,
+) -> Result<(Vec<msgs::OutboundOnionPayload<'a>>, u64, u32), APIError> {
let mut res: Vec<msgs::OutboundOnionPayload> = Vec::with_capacity(
path.hops.len() + path.blinded_tail.as_ref().map_or(0, |t| t.hops.len()),
);
@@ -472,7 +489,6 @@ pub(super) fn build_onion_payloads<'a>(
let (value_msat, cltv) = build_onion_payloads_callback(
path.hops.iter(),
blinded_tail_with_hop_iter,
- total_msat,
recipient_onion,
starting_htlc_offset,
keysend_preimage,
@@ -503,7 +519,7 @@ enum PayloadCallbackAction {
PushFront,
}
fn build_onion_payloads_callback<'a, 'b, H, B, F, OP>(
- hops: H, mut blinded_tail: Option<BlindedTailDetails<'a, B>>, total_msat: u64,
+ hops: H, mut blinded_tail: Option<BlindedTailDetails<'a, B>>,
recipient_onion: &'a RecipientOnionFields, starting_htlc_offset: u32,
keysend_preimage: &Option<PaymentPreimage>, invoice_request: Option<&'a InvoiceRequest>,
mut callback: F,
@@ -518,8 +534,6 @@ where
let mut cur_cltv = starting_htlc_offset;
let mut last_hop_id = None;
- debug_assert_eq!(total_msat, recipient_onion.total_mpp_amount_msat);
-
for (idx, hop) in hops.rev().enumerate() {
// First hop gets special values so that it can check, on receipt, that everything is
// exactly as it should be (and the next hop isn't trying to probe to find out if we're
@@ -548,7 +562,7 @@ where
PayloadCallbackAction::PushBack,
OP::new_blinded_receive(
final_value_msat,
- total_msat,
+ recipient_onion.total_mpp_amount_msat,
cur_cltv + excess_final_cltv_expiry_delta,
&blinded_hop.encrypted_payload,
blinding_point.take(),
@@ -576,7 +590,6 @@ where
callback(
PayloadCallbackAction::PushBack,
OP::new_trampoline_entry(
- total_msat,
final_value_msat + hop.fee_msat(),
cur_cltv,
&recipient_onion,
@@ -587,13 +600,7 @@ where
None => {
callback(
PayloadCallbackAction::PushBack,
- OP::new_receive(
- &recipient_onion,
- *keysend_preimage,
- value_msat,
- total_msat,
- cltv,
- )?,
+ OP::new_receive(&recipient_onion, *keysend_preimage, value_msat, cltv)?,
);
},
}
@@ -674,7 +681,6 @@ pub(crate) fn set_max_path_length(
let build_payloads_res = build_onion_payloads_callback(
core::iter::once(&unblinded_route_hop),
blinded_tail_opt,
- final_value_msat_with_overpay_buffer,
&recipient_onion_with_excess_value,
best_block_height,
&keysend_preimage,
@@ -2596,7 +2602,7 @@ pub(super) fn peel_dummy_hop_update_add_htlc<NS: NodeSigner, T: secp256k1::Verif
///
/// `cur_block_height` should be set to the best known block height + 1.
pub fn create_payment_onion<T: secp256k1::Signing>(
- secp_ctx: &Secp256k1<T>, path: &Path, session_priv: &SecretKey, total_msat: u64,
+ secp_ctx: &Secp256k1<T>, path: &Path, session_priv: &SecretKey,
recipient_onion: &RecipientOnionFields, cur_block_height: u32, payment_hash: &PaymentHash,
keysend_preimage: &Option<PaymentPreimage>, invoice_request: Option<&InvoiceRequest>,
prng_seed: [u8; 32],
@@ -2605,7 +2611,6 @@ pub fn create_payment_onion<T: secp256k1::Signing>(
secp_ctx,
path,
session_priv,
- total_msat,
recipient_onion,
cur_block_height,
payment_hash,
@@ -2627,15 +2632,12 @@ pub(super) fn compute_trampoline_session_priv(outer_onion_session_priv: &SecretK
/// Build a payment onion, returning the first hop msat and cltv values as well.
/// `cur_block_height` should be set to the best known block height + 1.
pub(crate) fn create_payment_onion_internal<T: secp256k1::Signing>(
- secp_ctx: &Secp256k1<T>, path: &Path, session_priv: &SecretKey, total_msat: u64,
+ secp_ctx: &Secp256k1<T>, path: &Path, session_priv: &SecretKey,
recipient_onion: &RecipientOnionFields, cur_block_height: u32, payment_hash: &PaymentHash,
keysend_preimage: &Option<PaymentPreimage>, invoice_request: Option<&InvoiceRequest>,
prng_seed: [u8; 32], trampoline_session_priv_override: Option<SecretKey>,
trampoline_prng_seed_override: Option<[u8; 32]>,
) -> Result<(msgs::OnionPacket, u64, u32), APIError> {
- debug_assert_eq!(total_msat, recipient_onion.total_mpp_amount_msat);
-
- let mut outer_total_msat = total_msat;
let mut outer_starting_htlc_offset = cur_block_height;
// If we're paying to a recipient through a trampoline, we use the `payment_secret` provided in
@@ -2658,10 +2660,10 @@ pub(crate) fn create_payment_onion_internal<T: secp256k1::Signing>(
if !blinded_tail.trampoline_hops.is_empty() {
let trampoline_payloads;
+ let outer_total_msat;
(trampoline_payloads, outer_total_msat, outer_starting_htlc_offset) =
build_trampoline_onion_payloads(
&blinded_tail,
- total_msat,
recipient_onion,
cur_block_height,
keysend_preimage,
@@ -2695,7 +2697,6 @@ pub(crate) fn create_payment_onion_internal<T: secp256k1::Signing>(
let (onion_payloads, htlc_msat, htlc_cltv) = build_onion_payloads(
&path,
- outer_total_msat,
outer_onion,
outer_starting_htlc_offset,
keysend_preimage,
diff --git a/lightning/src/ln/outbound_payment.rs b/lightning/src/ln/outbound_payment.rs
index b9a5884..65cc21a 100644
--- a/lightning/src/ln/outbound_payment.rs
+++ b/lightning/src/ln/outbound_payment.rs
@@ -913,7 +913,6 @@ pub(super) struct SendAlongPathArgs<'a> {
pub path: &'a Path,
pub payment_hash: &'a PaymentHash,
pub recipient_onion: &'a RecipientOnionFields,
- pub total_value: u64,
pub cur_height: u32,
pub payment_id: PaymentId,
pub keysend_preimage: &'a Option<PaymentPreimage>,
@@ -1192,7 +1191,7 @@ impl OutboundPayments {
let result = self.pay_route_internal(
&route, payment_hash, &recipient_onion, keysend_preimage, invoice_request, Some(&bolt12_invoice), payment_id,
- Some(route_params.final_value_msat), &onion_session_privs, hold_htlcs_at_next_hop, node_signer,
+ &onion_session_privs, hold_htlcs_at_next_hop, node_signer,
best_block_height, &send_payment_along_path
);
log_info!(
@@ -1583,7 +1582,7 @@ impl OutboundPayments {
})?;
let res = self.pay_route_internal(&route, payment_hash, &recipient_onion,
- keysend_preimage, None, None, payment_id, None, &onion_session_privs, false, node_signer,
+ keysend_preimage, None, None, payment_id, &onion_session_privs, false, node_signer,
best_block_height, &send_payment_along_path);
log_info!(logger, "Sending payment with id {} and hash {} returned {:?}",
payment_id, payment_hash, res);
@@ -1650,7 +1649,7 @@ impl OutboundPayments {
}
}
}
- let (total_msat, recipient_onion, keysend_preimage, onion_session_privs, invoice_request, bolt12_invoice) = {
+ let (recipient_onion, keysend_preimage, onion_session_privs, invoice_request, bolt12_invoice) = {
let mut outbounds = self.pending_outbound_payments.lock().unwrap();
match outbounds.entry(payment_id) {
hash_map::Entry::Occupied(mut payment) => {
@@ -1673,12 +1672,11 @@ impl OutboundPayments {
return
}
- let total_msat = *total_msat;
let recipient_onion = RecipientOnionFields {
payment_secret: *payment_secret,
payment_metadata: payment_metadata.clone(),
custom_tlvs: custom_tlvs.clone(),
- total_mpp_amount_msat: total_msat,
+ total_mpp_amount_msat: *total_msat,
};
let keysend_preimage = *keysend_preimage;
let invoice_request = invoice_request.clone();
@@ -1695,7 +1693,7 @@ impl OutboundPayments {
payment.get_mut().increment_attempts();
let bolt12_invoice = payment.get().bolt12_invoice();
- (total_msat, recipient_onion, keysend_preimage, onion_session_privs, invoice_request, bolt12_invoice.cloned())
+ (recipient_onion, keysend_preimage, onion_session_privs, invoice_request, bolt12_invoice.cloned())
},
PendingOutboundPayment::Legacy { .. } => {
log_error!(logger, "Unable to retry payments that were initially sent on LDK versions prior to 0.0.102");
@@ -1735,7 +1733,7 @@ impl OutboundPayments {
}
};
let res = self.pay_route_internal(&route, payment_hash, &recipient_onion, keysend_preimage,
- invoice_request.as_ref(), bolt12_invoice.as_ref(), payment_id, Some(total_msat),
+ invoice_request.as_ref(), bolt12_invoice.as_ref(), payment_id,
&onion_session_privs, false, node_signer, best_block_height, &send_payment_along_path);
log_info!(logger, "Result retrying payment id {}: {:?}", &payment_id, res);
if let Err(e) = res {
@@ -1894,7 +1892,7 @@ impl OutboundPayments {
})?;
match self.pay_route_internal(&route, payment_hash, &recipient_onion_fields,
- None, None, None, payment_id, None, &onion_session_privs, false, node_signer,
+ None, None, None, payment_id, &onion_session_privs, false, node_signer,
best_block_height, &send_payment_along_path
) {
Ok(()) => Ok((payment_hash, payment_id)),
@@ -2139,7 +2137,7 @@ impl OutboundPayments {
fn pay_route_internal<NS: NodeSigner, F>(
&self, route: &Route, payment_hash: PaymentHash, recipient_onion: &RecipientOnionFields,
keysend_preimage: Option<PaymentPreimage>, invoice_request: Option<&InvoiceRequest>, bolt12_invoice: Option<&PaidBolt12Invoice>,
- payment_id: PaymentId, recv_value_msat: Option<u64>, onion_session_privs: &Vec<[u8; 32]>,
+ payment_id: PaymentId, onion_session_privs: &Vec<[u8; 32]>,
hold_htlcs_at_next_hop: bool, node_signer: &NS, best_block_height: u32, send_payment_along_path: &F
) -> Result<(), PaymentSendFailure>
where
@@ -2153,7 +2151,6 @@ impl OutboundPayments {
{
return Err(PaymentSendFailure::ParameterError(APIError::APIMisuseError{err: "Payment secret is required for multi-path payments".to_owned()}));
}
- let mut total_value = 0;
let our_node_id = node_signer.get_node_id(Recipient::Node).unwrap(); // TODO no unwrap
let mut path_errs = Vec::with_capacity(route.paths.len());
'path_check: for path in route.paths.iter() {
@@ -2176,22 +2173,18 @@ impl OutboundPayments {
continue 'path_check;
}
}
- total_value += path.final_value_msat();
path_errs.push(Ok(()));
}
if path_errs.iter().any(|e| e.is_err()) {
return Err(PaymentSendFailure::PathParameterError(path_errs));
}
- if let Some(amt_msat) = recv_value_msat {
- total_value = amt_msat;
- }
let cur_height = best_block_height + 1;
let mut results = Vec::new();
debug_assert_eq!(route.paths.len(), onion_session_privs.len());
for (path, session_priv_bytes) in route.paths.iter().zip(onion_session_privs.iter()) {
let path_res = send_payment_along_path(SendAlongPathArgs {
- path: &path, payment_hash: &payment_hash, recipient_onion, total_value,
+ path: &path, payment_hash: &payment_hash, recipient_onion,
cur_height, payment_id, keysend_preimage: &keysend_preimage, invoice_request,
bolt12_invoice, hold_htlc_at_next_hop: hold_htlcs_at_next_hop,
session_priv_bytes: *session_priv_bytes
@@ -2252,7 +2245,7 @@ impl OutboundPayments {
#[rustfmt::skip]
pub(super) fn test_send_payment_internal<NS: NodeSigner, F>(
&self, route: &Route, payment_hash: PaymentHash, recipient_onion: RecipientOnionFields,
- keysend_preimage: Option<PaymentPreimage>, payment_id: PaymentId, recv_value_msat: Option<u64>,
+ keysend_preimage: Option<PaymentPreimage>, payment_id: PaymentId,
onion_session_privs: Vec<[u8; 32]>, node_signer: &NS, best_block_height: u32,
send_payment_along_path: F
) -> Result<(), PaymentSendFailure>
@@ -2260,7 +2253,7 @@ impl OutboundPayments {
F: Fn(SendAlongPathArgs) -> Result<(), APIError>,
{
self.pay_route_internal(route, payment_hash, &recipient_onion,
- keysend_preimage, None, None, payment_id, recv_value_msat, &onion_session_privs,
+ keysend_preimage, None, None, payment_id, &onion_session_privs,
false, node_signer, best_block_height, &send_payment_along_path)
.map_err(|e| { self.remove_outbound_if_all_failed(payment_id, &e); e })
}
diff --git a/lightning/src/ln/payment_tests.rs b/lightning/src/ln/payment_tests.rs
index 1a01358..c618b51 100644
--- a/lightning/src/ln/payment_tests.rs
+++ b/lightning/src/ln/payment_tests.rs
@@ -3342,9 +3342,7 @@ fn retry_multi_path_single_failed_payment() {
scorer.expect_usage(chans[1].short_channel_id.unwrap(), usage);
}
- // Note that while we actaully pay amt_msat + 1, we should really set the onion amount to
- // amt_msat as that's what we built a route for.
- let onion = RecipientOnionFields::secret_only(payment_secret, amt_msat + 1);
+ let onion = RecipientOnionFields::secret_only(payment_secret, amt_msat);
let id = PaymentId(payment_hash.0);
nodes[0].node.send_payment(payment_hash, onion, id, route_params, Retry::Attempts(1)).unwrap();
let events = nodes[0].node.get_and_clear_pending_events();
@@ -4713,7 +4711,7 @@ fn do_test_custom_tlvs_consistency(
let priv_a = session_privs[0];
nodes[0]
.node
- .test_send_payment_along_path(path_a, &hash, onion, amt_msat, cur_height, id, &None, priv_a)
+ .test_send_payment_along_path(path_a, &hash, onion, cur_height, id, &None, priv_a)
.unwrap();
check_added_monitors(&nodes[0], 1);
@@ -4736,7 +4734,7 @@ fn do_test_custom_tlvs_consistency(
let priv_b = session_privs[1];
nodes[0]
.node
- .test_send_payment_along_path(path_b, &hash, onion, amt_msat, cur_height, id, &None, priv_b)
+ .test_send_payment_along_path(path_b, &hash, onion, cur_height, id, &None, priv_b)
.unwrap();
check_added_monitors(&nodes[0], 1);
@@ -5128,7 +5126,6 @@ fn peel_payment_onion_custom_tlvs() {
&secp_ctx,
&route.paths[0],
&session_priv,
- amt_msat,
&recipient_onion,
nodes[0].best_block_info().1,
&payment_hash,
diff --git a/lightning/src/ln/reload_tests.rs b/lightning/src/ln/reload_tests.rs
index 2e8a060..bb730f8 100644
--- a/lightning/src/ln/reload_tests.rs
+++ b/lightning/src/ln/reload_tests.rs
@@ -1558,7 +1558,7 @@ fn test_htlc_localremoved_persistence() {
let session_privs = nodes[0].node.test_add_new_pending_payment(mismatch_payment_hash,
RecipientOnionFields::spontaneous_empty(10_000), PaymentId(mismatch_payment_hash.0), &route).unwrap();
nodes[0].node.test_send_payment_internal(&route, mismatch_payment_hash,
- RecipientOnionFields::spontaneous_empty(10_000), Some(test_preimage), PaymentId(mismatch_payment_hash.0), None, session_privs).unwrap();
+ RecipientOnionFields::spontaneous_empty(10_000), Some(test_preimage), PaymentId(mismatch_payment_hash.0), session_privs).unwrap();
check_added_monitors(&nodes[0], 1);
let updates = get_htlc_update_msgs(&nodes[0], &nodes[1].node.get_our_node_id());
Why this scored 34/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.