@@ -1858,6 +1858,9 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
1858
1858
// for now more than 10 paths likely carries too much one-path failure.
1859
1859
return Err ( PaymentSendFailure :: ParameterError ( APIError :: RouteError { err : "Sending over more than 10 paths is not currently supported" } ) ) ;
1860
1860
}
1861
+ if payment_secret. is_none ( ) && route. paths . len ( ) > 1 {
1862
+ return Err ( PaymentSendFailure :: ParameterError ( APIError :: APIMisuseError { err : "Payment secret is required for multi-path payments" . to_string ( ) } ) ) ;
1863
+ }
1861
1864
let mut total_value = 0 ;
1862
1865
let our_node_id = self . get_our_node_id ( ) ;
1863
1866
let mut path_errs = Vec :: with_capacity ( route. paths . len ( ) ) ;
@@ -5164,11 +5167,13 @@ mod tests {
5164
5167
use bitcoin:: hashes:: sha256:: Hash as Sha256 ;
5165
5168
use core:: time:: Duration ;
5166
5169
use ln:: { PaymentPreimage , PaymentHash , PaymentSecret } ;
5170
+ use ln:: channelmanager:: PaymentSendFailure ;
5167
5171
use ln:: features:: { InitFeatures , InvoiceFeatures } ;
5168
5172
use ln:: functional_test_utils:: * ;
5169
5173
use ln:: msgs;
5170
5174
use ln:: msgs:: ChannelMessageHandler ;
5171
5175
use routing:: router:: { get_keysend_route, get_route} ;
5176
+ use util:: errors:: APIError ;
5172
5177
use util:: events:: { Event , MessageSendEvent , MessageSendEventsProvider } ;
5173
5178
use util:: test_utils;
5174
5179
@@ -5556,6 +5561,39 @@ mod tests {
5556
5561
5557
5562
nodes[ 1 ] . logger . assert_log_contains ( "lightning::ln::channelmanager" . to_string ( ) , "We don't support MPP keysend payments" . to_string ( ) , 1 ) ;
5558
5563
}
5564
+
5565
+ #[ test]
5566
+ fn test_multi_hop_missing_secret ( ) {
5567
+ let chanmon_cfgs = create_chanmon_cfgs ( 4 ) ;
5568
+ let node_cfgs = create_node_cfgs ( 4 , & chanmon_cfgs) ;
5569
+ let node_chanmgrs = create_node_chanmgrs ( 4 , & node_cfgs, & [ None , None , None , None ] ) ;
5570
+ let nodes = create_network ( 4 , & node_cfgs, & node_chanmgrs) ;
5571
+
5572
+ let chan_1_id = create_announced_chan_between_nodes ( & nodes, 0 , 1 , InitFeatures :: known ( ) , InitFeatures :: known ( ) ) . 0 . contents . short_channel_id ;
5573
+ let chan_2_id = create_announced_chan_between_nodes ( & nodes, 0 , 2 , InitFeatures :: known ( ) , InitFeatures :: known ( ) ) . 0 . contents . short_channel_id ;
5574
+ let chan_3_id = create_announced_chan_between_nodes ( & nodes, 1 , 3 , InitFeatures :: known ( ) , InitFeatures :: known ( ) ) . 0 . contents . short_channel_id ;
5575
+ let chan_4_id = create_announced_chan_between_nodes ( & nodes, 2 , 3 , InitFeatures :: known ( ) , InitFeatures :: known ( ) ) . 0 . contents . short_channel_id ;
5576
+ let logger = test_utils:: TestLogger :: new ( ) ;
5577
+
5578
+ // Marshall an MPP route.
5579
+ let ( _, payment_hash, _) = get_payment_preimage_hash ! ( & nodes[ 3 ] ) ;
5580
+ let net_graph_msg_handler = & nodes[ 0 ] . net_graph_msg_handler ;
5581
+ let mut route = get_route ( & nodes[ 0 ] . node . get_our_node_id ( ) , & net_graph_msg_handler. network_graph . read ( ) . unwrap ( ) , & nodes[ 3 ] . node . get_our_node_id ( ) , Some ( InvoiceFeatures :: known ( ) ) , None , & [ ] , 100000 , TEST_FINAL_CLTV , & logger) . unwrap ( ) ;
5582
+ let path = route. paths [ 0 ] . clone ( ) ;
5583
+ route. paths . push ( path) ;
5584
+ route. paths [ 0 ] [ 0 ] . pubkey = nodes[ 1 ] . node . get_our_node_id ( ) ;
5585
+ route. paths [ 0 ] [ 0 ] . short_channel_id = chan_1_id;
5586
+ route. paths [ 0 ] [ 1 ] . short_channel_id = chan_3_id;
5587
+ route. paths [ 1 ] [ 0 ] . pubkey = nodes[ 2 ] . node . get_our_node_id ( ) ;
5588
+ route. paths [ 1 ] [ 0 ] . short_channel_id = chan_2_id;
5589
+ route. paths [ 1 ] [ 1 ] . short_channel_id = chan_4_id;
5590
+
5591
+ match nodes[ 0 ] . node . send_payment ( & route, payment_hash, & None ) . unwrap_err ( ) {
5592
+ PaymentSendFailure :: ParameterError ( APIError :: APIMisuseError { ref err } ) => {
5593
+ assert ! ( regex:: Regex :: new( r"Payment secret is required for multi-path payments" ) . unwrap( ) . is_match( err) ) } ,
5594
+ _ => panic ! ( "unexpected error" )
5595
+ }
5596
+ }
5559
5597
}
5560
5598
5561
5599
#[ cfg( all( any( test, feature = "_test_utils" ) , feature = "unstable" ) ) ]
0 commit comments