Skip to content

Commit a2c6531

Browse files
committed
Include MPP payment amount in RecipientOnionFields
In some uses of LDK we need the ability to send HTLCs for only a portion of some larger MPP payment. This allows payers to make single payments which spend funds from multiple wallets, which may be important for ecash wallets holding funds in multiple mints or graduated wallets which hold funds across a trusted wallet and a self-custodial wallet. In order to allow for this, we need to separate the concept of the payment amount from the onion MPP amount. Here we start this process by adding a `total_mpp_amount_msat` field to `RecipientOnionFields` (which is the appropriate place for a field describing something in the recipient onion). We currently always assert that it is equal to the existing fields, but will relax this in the coming commit(s). We also start including a payment preimage on probe attempts, which appears to have been the intent of the code, but which did not work correctly. The bulk of the test updates were done by Claude.
1 parent d804a6c commit a2c6531

29 files changed

Lines changed: 484 additions & 335 deletions

fuzz/src/chanmon_consistency.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -585,7 +585,7 @@ fn send_payment(
585585
}],
586586
route_params: Some(route_params.clone()),
587587
};
588-
let onion = RecipientOnionFields::secret_only(payment_secret);
588+
let onion = RecipientOnionFields::secret_only(payment_secret, amt);
589589
let res = source.send_payment_with_route(route, payment_hash, onion, payment_id);
590590
match res {
591591
Err(err) => {
@@ -642,7 +642,7 @@ fn send_hop_payment(
642642
}],
643643
route_params: Some(route_params.clone()),
644644
};
645-
let onion = RecipientOnionFields::secret_only(payment_secret);
645+
let onion = RecipientOnionFields::secret_only(payment_secret, amt);
646646
let res = source.send_payment_with_route(route, payment_hash, onion, payment_id);
647647
match res {
648648
Err(err) => {
@@ -698,7 +698,7 @@ fn send_mpp_payment(
698698
amt,
699699
);
700700
let route = Route { paths, route_params: Some(route_params) };
701-
let onion = RecipientOnionFields::secret_only(payment_secret);
701+
let onion = RecipientOnionFields::secret_only(payment_secret, amt);
702702
let res = source.send_payment_with_route(route, payment_hash, onion, payment_id);
703703
match res {
704704
Err(_) => false,
@@ -769,7 +769,7 @@ fn send_mpp_hop_payment(
769769
amt,
770770
);
771771
let route = Route { paths, route_params: Some(route_params) };
772-
let onion = RecipientOnionFields::secret_only(payment_secret);
772+
let onion = RecipientOnionFields::secret_only(payment_secret, amt);
773773
let res = source.send_payment_with_route(route, payment_hash, onion, payment_id);
774774
match res {
775775
Err(_) => false,

fuzz/src/full_stack.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -739,7 +739,7 @@ pub fn do_test(mut data: &[u8], logger: &Arc<dyn Logger>) {
739739
payments_sent += 1;
740740
let _ = channelmanager.send_payment(
741741
payment_hash,
742-
RecipientOnionFields::spontaneous_empty(),
742+
RecipientOnionFields::spontaneous_empty(final_value_msat),
743743
PaymentId(payment_hash.0),
744744
params,
745745
Retry::Attempts(2),
@@ -761,7 +761,7 @@ pub fn do_test(mut data: &[u8], logger: &Arc<dyn Logger>) {
761761
payments_sent += 1;
762762
let _ = channelmanager.send_payment(
763763
payment_hash,
764-
RecipientOnionFields::secret_only(payment_secret),
764+
RecipientOnionFields::secret_only(payment_secret, final_value_msat),
765765
PaymentId(payment_hash.0),
766766
params,
767767
Retry::Attempts(2),

lightning/src/chain/channelmonitor.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6850,7 +6850,7 @@ mod tests {
68506850
// the update through to the ChannelMonitor which will refuse it (as the channel is closed).
68516851
let (route, payment_hash, _, payment_secret) = get_route_and_payment_hash!(nodes[1], nodes[0], 100_000);
68526852
nodes[1].node.send_payment_with_route(route, payment_hash,
6853-
RecipientOnionFields::secret_only(payment_secret), PaymentId(payment_hash.0)
6853+
RecipientOnionFields::secret_only(payment_secret, 100_000), PaymentId(payment_hash.0)
68546854
).unwrap();
68556855
check_added_monitors(&nodes[1], 1);
68566856

lightning/src/events/mod.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@ use crate::types::payment::{PaymentHash, PaymentPreimage, PaymentSecret};
4141
use crate::types::string::UntrustedString;
4242
use crate::util::errors::APIError;
4343
use crate::util::ser::{
44-
BigSize, FixedLengthReader, MaybeReadable, Readable, RequiredWrapper, UpgradableRequired,
45-
WithoutLength, Writeable, Writer,
44+
BigSize, FixedLengthReader, MaybeReadable, Readable, ReadableArgs, RequiredWrapper,
45+
UpgradableRequired, WithoutLength, Writeable, Writer,
4646
};
4747

4848
use crate::io;
@@ -2378,7 +2378,7 @@ impl MaybeReadable for Event {
23782378
(6, _user_payment_id, option),
23792379
(7, claim_deadline, option),
23802380
(8, payment_preimage, option),
2381-
(9, onion_fields, option),
2381+
(9, onion_fields, (option: ReadableArgs, amount_msat)),
23822382
(10, counterparty_skimmed_fee_msat_opt, option),
23832383
(11, payment_context, option),
23842384
(13, payment_id, option),
@@ -2710,7 +2710,8 @@ impl MaybeReadable for Event {
27102710
(4, amount_msat, required),
27112711
(5, htlcs, optional_vec),
27122712
(7, sender_intended_total_msat, option),
2713-
(9, onion_fields, option),
2713+
(9, onion_fields, (option: ReadableArgs,
2714+
sender_intended_total_msat.unwrap_or(amount_msat))),
27142715
(11, payment_id, option),
27152716
});
27162717
Ok(Some(Event::PaymentClaimed {

lightning/src/ln/accountable_tests.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ fn test_accountable_forwarding_with_override(
3131
PaymentParameters::from_node_id(nodes[2].node.get_our_node_id(), TEST_FINAL_CLTV),
3232
100_000,
3333
);
34-
let onion_fields = RecipientOnionFields::secret_only(payment_secret);
34+
let onion_fields = RecipientOnionFields::secret_only(payment_secret, 100_000);
3535
let payment_id = PaymentId(payment_hash.0);
3636
nodes[0]
3737
.node

lightning/src/ln/async_payments_tests.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -615,7 +615,7 @@ fn invalid_keysend_payment_secret() {
615615
.node
616616
.send_spontaneous_payment(
617617
Some(keysend_preimage),
618-
RecipientOnionFields::spontaneous_empty(),
618+
RecipientOnionFields::spontaneous_empty(amt_msat),
619619
PaymentId(keysend_preimage.0),
620620
route_params,
621621
Retry::Attempts(0),

lightning/src/ln/async_signer_tests.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,7 @@ fn do_test_async_commitment_signature_for_commitment_signed_revoke_and_ack(
297297

298298
let (route, our_payment_hash, _our_payment_preimage, our_payment_secret) =
299299
get_route_and_payment_hash!(src, dst, 8000000);
300-
let recipient_fields = RecipientOnionFields::secret_only(our_payment_secret);
300+
let recipient_fields = RecipientOnionFields::secret_only(our_payment_secret, 8000000);
301301
let payment_id = PaymentId(our_payment_hash.0);
302302
src.node
303303
.send_payment_with_route(route, our_payment_hash, recipient_fields, payment_id)
@@ -521,7 +521,7 @@ fn do_test_async_raa_peer_disconnect(
521521

522522
let (route, our_payment_hash, _our_payment_preimage, our_payment_secret) =
523523
get_route_and_payment_hash!(src, dst, 8000000);
524-
let recipient_fields = RecipientOnionFields::secret_only(our_payment_secret);
524+
let recipient_fields = RecipientOnionFields::secret_only(our_payment_secret, 8000000);
525525
let payment_id = PaymentId(our_payment_hash.0);
526526
src.node
527527
.send_payment_with_route(route, our_payment_hash, recipient_fields, payment_id)
@@ -670,7 +670,7 @@ fn do_test_async_commitment_signature_peer_disconnect(
670670

671671
let (route, our_payment_hash, _our_payment_preimage, our_payment_secret) =
672672
get_route_and_payment_hash!(src, dst, 8000000);
673-
let recipient_fields = RecipientOnionFields::secret_only(our_payment_secret);
673+
let recipient_fields = RecipientOnionFields::secret_only(our_payment_secret, 8000000);
674674
let payment_id = PaymentId(our_payment_hash.0);
675675
src.node
676676
.send_payment_with_route(route, our_payment_hash, recipient_fields, payment_id)
@@ -805,7 +805,7 @@ fn do_test_async_commitment_signature_ordering(monitor_update_failure: bool) {
805805
// to the peer.
806806
let (route, payment_hash_2, payment_preimage_2, payment_secret_2) =
807807
get_route_and_payment_hash!(nodes[0], nodes[1], 1000000);
808-
let recipient_fields = RecipientOnionFields::secret_only(payment_secret_2);
808+
let recipient_fields = RecipientOnionFields::secret_only(payment_secret_2, 1000000);
809809
let payment_id = PaymentId(payment_hash_2.0);
810810
nodes[0]
811811
.node
@@ -1344,14 +1344,14 @@ fn test_no_disconnect_while_async_revoke_and_ack_expecting_remote_commitment_sig
13441344
// We'll send a payment from both nodes to each other.
13451345
let (route1, payment_hash1, _, payment_secret1) =
13461346
get_route_and_payment_hash!(&nodes[0], &nodes[1], payment_amount);
1347-
let onion1 = RecipientOnionFields::secret_only(payment_secret1);
1347+
let onion1 = RecipientOnionFields::secret_only(payment_secret1, payment_amount);
13481348
let payment_id1 = PaymentId(payment_hash1.0);
13491349
nodes[0].node.send_payment_with_route(route1, payment_hash1, onion1, payment_id1).unwrap();
13501350
check_added_monitors(&nodes[0], 1);
13511351

13521352
let (route2, payment_hash2, _, payment_secret2) =
13531353
get_route_and_payment_hash!(&nodes[1], &nodes[0], payment_amount);
1354-
let onion2 = RecipientOnionFields::secret_only(payment_secret2);
1354+
let onion2 = RecipientOnionFields::secret_only(payment_secret2, payment_amount);
13551355
let payment_id2 = PaymentId(payment_hash2.0);
13561356
nodes[1].node.send_payment_with_route(route2, payment_hash2, onion2, payment_id2).unwrap();
13571357
check_added_monitors(&nodes[1], 1);

0 commit comments

Comments
 (0)