@@ -30,7 +30,7 @@ use chain::transaction::OutPoint;
30
30
use ln:: channel:: { Channel , ChannelError } ;
31
31
use ln:: channelmonitor:: { ChannelMonitor , ChannelMonitorUpdate , ChannelMonitorUpdateErr , ManyChannelMonitor , CLTV_CLAIM_BUFFER , LATENCY_GRACE_PERIOD_BLOCKS , ANTI_REORG_DELAY } ;
32
32
use ln:: features:: { InitFeatures , NodeFeatures } ;
33
- use ln:: router:: Route ;
33
+ use ln:: router:: { Route , RouteHop } ;
34
34
use ln:: msgs;
35
35
use ln:: onion_utils;
36
36
use ln:: msgs:: { ChannelMessageHandler , DecodeError , LightningError } ;
@@ -136,7 +136,7 @@ struct ClaimableHTLC {
136
136
pub ( super ) enum HTLCSource {
137
137
PreviousHopData ( HTLCPreviousHopData ) ,
138
138
OutboundRoute {
139
- route : Route ,
139
+ path : Vec < RouteHop > ,
140
140
session_priv : SecretKey ,
141
141
/// Technically we can recalculate this from the route, but we cache it here to avoid
142
142
/// doing a double-pass on route when we get a failure back
@@ -147,7 +147,7 @@ pub(super) enum HTLCSource {
147
147
impl HTLCSource {
148
148
pub fn dummy ( ) -> Self {
149
149
HTLCSource :: OutboundRoute {
150
- route : Route { hops : Vec :: new ( ) } ,
150
+ path : Vec :: new ( ) ,
151
151
session_priv : SecretKey :: from_slice ( & [ 1 ; 32 ] ) . unwrap ( ) ,
152
152
first_hop_htlc_msat : 0 ,
153
153
}
@@ -1231,23 +1231,26 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref> ChannelMan
1231
1231
/// bit set (either as required or as available). If multiple paths are present in the Route,
1232
1232
/// we assume the invoice had the basic_mpp feature set.
1233
1233
pub fn send_payment ( & self , route : Route , payment_hash : PaymentHash , payment_secret : & Option < PaymentSecret > ) -> Result < ( ) , APIError > {
1234
- if route. hops . len ( ) < 1 || route. hops . len ( ) > 20 {
1235
- return Err ( APIError :: RouteError { err : "Route didn't go anywhere/had bogus size" } ) ;
1234
+ if route. paths . len ( ) < 1 || route. paths . len ( ) > 1 {
1235
+ return Err ( APIError :: RouteError { err : "We currently don't support MPP, and we need at least one path" } ) ;
1236
+ }
1237
+ if route. paths [ 0 ] . len ( ) < 1 || route. paths [ 0 ] . len ( ) > 20 {
1238
+ return Err ( APIError :: RouteError { err : "Path didn't go anywhere/had bogus size" } ) ;
1236
1239
}
1237
1240
let our_node_id = self . get_our_node_id ( ) ;
1238
- for ( idx, hop) in route. hops . iter ( ) . enumerate ( ) {
1239
- if idx != route. hops . len ( ) - 1 && hop. pubkey == our_node_id {
1240
- return Err ( APIError :: RouteError { err : "Route went through us but wasn't a simple rebalance loop to us" } ) ;
1241
+ for ( idx, hop) in route. paths [ 0 ] . iter ( ) . enumerate ( ) {
1242
+ if idx != route. paths [ 0 ] . len ( ) - 1 && hop. pubkey == our_node_id {
1243
+ return Err ( APIError :: RouteError { err : "Path went through us but wasn't a simple rebalance loop to us" } ) ;
1241
1244
}
1242
1245
}
1243
1246
1244
1247
let ( session_priv, prng_seed) = self . keys_manager . get_onion_rand ( ) ;
1245
1248
1246
1249
let cur_height = self . latest_block_height . load ( Ordering :: Acquire ) as u32 + 1 ;
1247
1250
1248
- let onion_keys = secp_call ! ( onion_utils:: construct_onion_keys( & self . secp_ctx, & route, & session_priv) ,
1251
+ let onion_keys = secp_call ! ( onion_utils:: construct_onion_keys( & self . secp_ctx, & route. paths [ 0 ] , & session_priv) ,
1249
1252
APIError :: RouteError { err: "Pubkey along hop was maliciously selected" } ) ;
1250
- let ( onion_payloads, htlc_msat, htlc_cltv) = onion_utils:: build_onion_payloads ( & route, payment_secret, cur_height) ?;
1253
+ let ( onion_payloads, htlc_msat, htlc_cltv) = onion_utils:: build_onion_payloads ( & route. paths [ 0 ] , payment_secret, cur_height) ?;
1251
1254
if onion_utils:: route_size_insane ( & onion_payloads) {
1252
1255
return Err ( APIError :: RouteError { err : "Route size too large considering onion data" } ) ;
1253
1256
}
@@ -1257,22 +1260,22 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref> ChannelMan
1257
1260
1258
1261
let err: Result < ( ) , _ > = loop {
1259
1262
let mut channel_lock = self . channel_state . lock ( ) . unwrap ( ) ;
1260
- let id = match channel_lock. short_to_id . get ( & route. hops . first ( ) . unwrap ( ) . short_channel_id ) {
1263
+ let id = match channel_lock. short_to_id . get ( & route. paths [ 0 ] . first ( ) . unwrap ( ) . short_channel_id ) {
1261
1264
None => return Err ( APIError :: ChannelUnavailable { err : "No channel available with first hop!" } ) ,
1262
1265
Some ( id) => id. clone ( ) ,
1263
1266
} ;
1264
1267
1265
1268
let channel_state = & mut * channel_lock;
1266
1269
if let hash_map:: Entry :: Occupied ( mut chan) = channel_state. by_id . entry ( id) {
1267
1270
match {
1268
- if chan. get ( ) . get_their_node_id ( ) != route. hops . first ( ) . unwrap ( ) . pubkey {
1271
+ if chan. get ( ) . get_their_node_id ( ) != route. paths [ 0 ] . first ( ) . unwrap ( ) . pubkey {
1269
1272
return Err ( APIError :: RouteError { err : "Node ID mismatch on first hop!" } ) ;
1270
1273
}
1271
1274
if !chan. get ( ) . is_live ( ) {
1272
1275
return Err ( APIError :: ChannelUnavailable { err : "Peer for first hop currently disconnected/pending monitor update!" } ) ;
1273
1276
}
1274
1277
break_chan_entry ! ( self , chan. get_mut( ) . send_htlc_and_commit( htlc_msat, payment_hash. clone( ) , htlc_cltv, HTLCSource :: OutboundRoute {
1275
- route : route. clone( ) ,
1278
+ path : route. paths [ 0 ] . clone( ) ,
1276
1279
session_priv: session_priv. clone( ) ,
1277
1280
first_hop_htlc_msat: htlc_msat,
1278
1281
} , onion_packet) , channel_state, chan)
@@ -1288,7 +1291,7 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref> ChannelMan
1288
1291
}
1289
1292
1290
1293
channel_state. pending_msg_events . push ( events:: MessageSendEvent :: UpdateHTLCs {
1291
- node_id : route. hops . first ( ) . unwrap ( ) . pubkey ,
1294
+ node_id : route. paths [ 0 ] . first ( ) . unwrap ( ) . pubkey ,
1292
1295
updates : msgs:: CommitmentUpdate {
1293
1296
update_add_htlcs : vec ! [ update_add] ,
1294
1297
update_fulfill_htlcs : Vec :: new ( ) ,
@@ -1305,7 +1308,7 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref> ChannelMan
1305
1308
return Ok ( ( ) ) ;
1306
1309
} ;
1307
1310
1308
- match handle_error ! ( self , err, route. hops . first( ) . unwrap( ) . pubkey) {
1311
+ match handle_error ! ( self , err, route. paths [ 0 ] . first( ) . unwrap( ) . pubkey) {
1309
1312
Ok ( _) => unreachable ! ( ) ,
1310
1313
Err ( e) => { Err ( APIError :: ChannelUnavailable { err : e. err } ) }
1311
1314
}
@@ -1750,7 +1753,7 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref> ChannelMan
1750
1753
//between the branches here. We should make this async and move it into the forward HTLCs
1751
1754
//timer handling.
1752
1755
match source {
1753
- HTLCSource :: OutboundRoute { ref route , .. } => {
1756
+ HTLCSource :: OutboundRoute { ref path , .. } => {
1754
1757
log_trace ! ( self , "Failing outbound payment HTLC with payment_hash {}" , log_bytes!( payment_hash. 0 ) ) ;
1755
1758
mem:: drop ( channel_state_lock) ;
1756
1759
match & onion_error {
@@ -1792,7 +1795,7 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref> ChannelMan
1792
1795
self . pending_events . lock ( ) . unwrap ( ) . push (
1793
1796
events:: Event :: PaymentFailed {
1794
1797
payment_hash : payment_hash. clone ( ) ,
1795
- rejected_by_dest : route . hops . len ( ) == 1 ,
1798
+ rejected_by_dest : path . len ( ) == 1 ,
1796
1799
#[ cfg( test) ]
1797
1800
error_code : Some ( * failure_code) ,
1798
1801
}
@@ -1856,9 +1859,19 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref> ChannelMan
1856
1859
let mut channel_state = Some ( self . channel_state . lock ( ) . unwrap ( ) ) ;
1857
1860
let removed_source = channel_state. as_mut ( ) . unwrap ( ) . claimable_htlcs . remove ( & ( payment_hash, * payment_secret) ) ;
1858
1861
if let Some ( mut sources) = removed_source {
1862
+ assert ! ( !sources. is_empty( ) ) ;
1863
+ let valid_mpp_amount = if let & Some ( ref data) = & sources[ 0 ] . payment_data {
1864
+ assert ! ( payment_secret. is_some( ) ) ;
1865
+ data. total_msat == expected_amount
1866
+ } else {
1867
+ assert ! ( payment_secret. is_none( ) ) ;
1868
+ false
1869
+ } ;
1870
+
1871
+ let mut claimed_any_htlcs = false ;
1859
1872
for htlc in sources. drain ( ..) {
1860
1873
if channel_state. is_none ( ) { channel_state = Some ( self . channel_state . lock ( ) . unwrap ( ) ) ; }
1861
- if htlc. value < expected_amount || htlc. value > expected_amount * 2 {
1874
+ if !valid_mpp_amount && ( htlc. value < expected_amount || htlc. value > expected_amount * 2 ) {
1862
1875
let mut htlc_msat_data = byte_utils:: be64_to_array ( htlc. value ) . to_vec ( ) ;
1863
1876
let mut height_data = byte_utils:: be32_to_array ( self . latest_block_height . load ( Ordering :: Acquire ) as u32 ) . to_vec ( ) ;
1864
1877
htlc_msat_data. append ( & mut height_data) ;
@@ -1867,9 +1880,10 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref> ChannelMan
1867
1880
HTLCFailReason :: Reason { failure_code : 0x4000 |15 , data : htlc_msat_data } ) ;
1868
1881
} else {
1869
1882
self . claim_funds_internal ( channel_state. take ( ) . unwrap ( ) , HTLCSource :: PreviousHopData ( htlc. prev_hop ) , payment_preimage) ;
1883
+ claimed_any_htlcs = true ;
1870
1884
}
1871
1885
}
1872
- true
1886
+ claimed_any_htlcs
1873
1887
} else { false }
1874
1888
}
1875
1889
fn claim_funds_internal ( & self , mut channel_state_lock : MutexGuard < ChannelHolder < ChanSigner > > , source : HTLCSource , payment_preimage : PaymentPreimage ) {
@@ -3271,9 +3285,9 @@ impl Writeable for HTLCSource {
3271
3285
0u8 . write ( writer) ?;
3272
3286
hop_data. write ( writer) ?;
3273
3287
} ,
3274
- & HTLCSource :: OutboundRoute { ref route , ref session_priv, ref first_hop_htlc_msat } => {
3288
+ & HTLCSource :: OutboundRoute { ref path , ref session_priv, ref first_hop_htlc_msat } => {
3275
3289
1u8 . write ( writer) ?;
3276
- route . write ( writer) ?;
3290
+ path . write ( writer) ?;
3277
3291
session_priv. write ( writer) ?;
3278
3292
first_hop_htlc_msat. write ( writer) ?;
3279
3293
}
@@ -3287,7 +3301,7 @@ impl Readable for HTLCSource {
3287
3301
match <u8 as Readable >:: read ( reader) ? {
3288
3302
0 => Ok ( HTLCSource :: PreviousHopData ( Readable :: read ( reader) ?) ) ,
3289
3303
1 => Ok ( HTLCSource :: OutboundRoute {
3290
- route : Readable :: read ( reader) ?,
3304
+ path : Readable :: read ( reader) ?,
3291
3305
session_priv : Readable :: read ( reader) ?,
3292
3306
first_hop_htlc_msat : Readable :: read ( reader) ?,
3293
3307
} ) ,
0 commit comments