@@ -17,15 +17,16 @@ use crate::sign::{EntropySource, NodeSigner, Recipient};
17
17
use crate :: events:: { self , PaymentFailureReason } ;
18
18
use crate :: ln:: { PaymentHash , PaymentPreimage , PaymentSecret } ;
19
19
use crate :: ln:: channelmanager:: { ChannelDetails , EventCompletionAction , HTLCSource , PaymentId } ;
20
+ use crate :: ln:: msgs;
20
21
use crate :: ln:: onion_utils:: { DecodedOnionFailure , HTLCFailReason } ;
21
22
use crate :: offers:: invoice:: Bolt12Invoice ;
22
- use crate :: routing:: router:: { BlindedTail , InFlightHtlcs , Path , PaymentParameters , Route , RouteParameters , Router } ;
23
+ use crate :: routing:: router:: { BlindedTail , InFlightHtlcs , MAX_PATH_LENGTH_ESTIMATE , Path , Payee , PaymentParameters , Route , RouteParameters , Router } ;
23
24
use crate :: util:: errors:: APIError ;
24
25
use crate :: util:: logger:: Logger ;
25
26
use crate :: util:: time:: Time ;
26
27
#[ cfg( all( feature = "std" , test) ) ]
27
28
use crate :: util:: time:: tests:: SinceEpoch ;
28
- use crate :: util:: ser:: ReadableArgs ;
29
+ use crate :: util:: ser:: { ReadableArgs , Writeable } ;
29
30
30
31
use core:: fmt:: { self , Display , Formatter } ;
31
32
use core:: ops:: Deref ;
@@ -421,6 +422,12 @@ pub enum RetryableSendFailure {
421
422
/// [`Event::PaymentSent`]: crate::events::Event::PaymentSent
422
423
/// [`Event::PaymentFailed`]: crate::events::Event::PaymentFailed
423
424
DuplicatePayment ,
425
+ /// The [`RecipientOnionFields::payment_metadata`], [`RecipientOnionFields::custom_tlvs`], or
426
+ /// [`BlindedPath`]s provided are too large and caused us to exceed the maximum onion packet size
427
+ /// of 1300 bytes.
428
+ ///
429
+ /// [`BlindedPath`]: crate::blinded_path::BlindedPath;
430
+ OnionPacketSizeExceeded ,
424
431
}
425
432
426
433
/// If a payment fails to send with [`ChannelManager::send_payment_with_route`], it can be in one
@@ -886,7 +893,7 @@ impl OutboundPayments {
886
893
/// [`Event::PaymentFailed`]: crate::events::Event::PaymentFailed
887
894
fn send_payment_internal < R : Deref , NS : Deref , ES : Deref , IH , SP , L : Deref > (
888
895
& self , payment_id : PaymentId , payment_hash : PaymentHash , recipient_onion : RecipientOnionFields ,
889
- keysend_preimage : Option < PaymentPreimage > , retry_strategy : Retry , route_params : RouteParameters ,
896
+ keysend_preimage : Option < PaymentPreimage > , retry_strategy : Retry , mut route_params : RouteParameters ,
890
897
router : & R , first_hops : Vec < ChannelDetails > , inflight_htlcs : IH , entropy_source : & ES ,
891
898
node_signer : & NS , best_block_height : u32 , logger : & L ,
892
899
pending_events : & Mutex < VecDeque < ( events:: Event , Option < EventCompletionAction > ) > > , send_payment_along_path : SP ,
@@ -907,6 +914,15 @@ impl OutboundPayments {
907
914
}
908
915
}
909
916
917
+ set_max_path_length (
918
+ & mut route_params, & recipient_onion, keysend_preimage, best_block_height
919
+ )
920
+ . map_err ( |( ) | {
921
+ log_error ! ( logger, "Can't construct an onion packet without exceeding 1300-byte onion \
922
+ hop_data length for payment with id {} and hash {}", payment_id, payment_hash) ;
923
+ RetryableSendFailure :: OnionPacketSizeExceeded
924
+ } ) ?;
925
+
910
926
let mut route = router. find_route_with_id (
911
927
& node_signer. get_node_id ( Recipient :: Node ) . unwrap ( ) , & route_params,
912
928
Some ( & first_hops. iter ( ) . collect :: < Vec < _ > > ( ) ) , inflight_htlcs ( ) ,
@@ -1771,6 +1787,75 @@ impl OutboundPayments {
1771
1787
}
1772
1788
}
1773
1789
1790
+ fn set_max_path_length (
1791
+ route_params : & mut RouteParameters , recipient_onion : & RecipientOnionFields ,
1792
+ keysend_preimage : Option < PaymentPreimage > , best_block_height : u32 ,
1793
+ ) -> Result < ( ) , ( ) > {
1794
+ const PAYLOAD_HMAC_LEN : usize = 32 ;
1795
+ const UNBLINDED_INTERMED_PAYLOAD_LEN : usize = PAYLOAD_HMAC_LEN
1796
+ + 1 + 1 + 8 // amt_to_forward
1797
+ + 1 + 1 + 4 // outgoing_cltv
1798
+ + 1 + 1 + 8 ; // short_channel_id
1799
+
1800
+ let num_reserved_bytes = match & route_params. payment_params . payee {
1801
+ Payee :: Blinded { route_hints, .. } => {
1802
+ let largest_path = route_hints
1803
+ . iter ( )
1804
+ . map ( |( _, path) | path)
1805
+ . max_by ( |path_a, path_b|
1806
+ path_a. serialized_length ( ) . cmp ( & path_b. serialized_length ( ) ) )
1807
+ . ok_or ( ( ) ) ?;
1808
+
1809
+ largest_path. blinded_hops
1810
+ . iter ( )
1811
+ . rev ( )
1812
+ . skip ( 1 )
1813
+ . map ( |bh| msgs:: OutboundOnionPayload :: BlindedForward {
1814
+ encrypted_tlvs : & bh. encrypted_payload ,
1815
+ // For simplicity, always set the intro_node_blinding_point in the
1816
+ // final payload.
1817
+ intro_node_blinding_point : None ,
1818
+ } )
1819
+ . chain ( core:: iter:: once ( msgs:: OutboundOnionPayload :: BlindedReceive {
1820
+ sender_intended_htlc_amt_msat : route_params. final_value_msat ,
1821
+ total_msat : route_params. final_value_msat ,
1822
+ cltv_expiry_height :
1823
+ best_block_height. saturating_add ( route_params. payment_params . max_total_cltv_expiry_delta ) ,
1824
+ encrypted_tlvs : largest_path. blinded_hops
1825
+ . last ( )
1826
+ . map ( |bh| & bh. encrypted_payload )
1827
+ . unwrap_or ( & Vec :: new ( ) ) ,
1828
+ intro_node_blinding_point : Some ( largest_path. blinding_point ) ,
1829
+ keysend_preimage,
1830
+ custom_tlvs : & recipient_onion. custom_tlvs ,
1831
+ } ) )
1832
+ . map ( |payload| payload. serialized_length ( ) . saturating_add ( PAYLOAD_HMAC_LEN ) )
1833
+ . fold ( 0 , |acc : usize , payload_len| acc. saturating_add ( payload_len) )
1834
+ } ,
1835
+ Payee :: Clear { final_cltv_expiry_delta, .. } => {
1836
+ msgs:: OutboundOnionPayload :: Receive {
1837
+ payment_data : recipient_onion. payment_secret . map ( |payment_secret| {
1838
+ msgs:: FinalOnionHopData { payment_secret, total_msat : route_params. final_value_msat }
1839
+ } ) ,
1840
+ payment_metadata : recipient_onion. payment_metadata . as_ref ( ) ,
1841
+ keysend_preimage,
1842
+ custom_tlvs : & recipient_onion. custom_tlvs ,
1843
+ sender_intended_htlc_amt_msat : route_params. final_value_msat ,
1844
+ cltv_expiry_height : best_block_height. saturating_add ( * final_cltv_expiry_delta) ,
1845
+ }
1846
+ . serialized_length ( )
1847
+ . saturating_add ( PAYLOAD_HMAC_LEN )
1848
+ }
1849
+ } ;
1850
+ let max_intermediate_unblinded_hops = 1300usize . checked_sub ( num_reserved_bytes)
1851
+ . map ( |p| p / UNBLINDED_INTERMED_PAYLOAD_LEN )
1852
+ . and_then ( |l| u8:: try_from ( l) . ok ( ) )
1853
+ . ok_or ( ( ) ) ?;
1854
+
1855
+ route_params. payment_params . max_intermediate_hops = core:: cmp:: min ( max_intermediate_unblinded_hops, MAX_PATH_LENGTH_ESTIMATE ) ;
1856
+ Ok ( ( ) )
1857
+ }
1858
+
1774
1859
/// Returns whether a payment with the given [`PaymentHash`] and [`PaymentId`] is, in fact, a
1775
1860
/// payment probe.
1776
1861
pub ( super ) fn payment_is_probe ( payment_hash : & PaymentHash , payment_id : & PaymentId ,
0 commit comments