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