@@ -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 } ;
@@ -132,7 +132,7 @@ struct ClaimableHTLC {
132
132
pub ( super ) enum HTLCSource {
133
133
PreviousHopData ( HTLCPreviousHopData ) ,
134
134
OutboundRoute {
135
- route : Route ,
135
+ path : Vec < RouteHop > ,
136
136
session_priv : SecretKey ,
137
137
/// Technically we can recalculate this from the route, but we cache it here to avoid
138
138
/// doing a double-pass on route when we get a failure back
@@ -143,7 +143,7 @@ pub(super) enum HTLCSource {
143
143
impl HTLCSource {
144
144
pub fn dummy ( ) -> Self {
145
145
HTLCSource :: OutboundRoute {
146
- route : Route { hops : Vec :: new ( ) } ,
146
+ path : Vec :: new ( ) ,
147
147
session_priv : SecretKey :: from_slice ( & [ 1 ; 32 ] ) . unwrap ( ) ,
148
148
first_hop_htlc_msat : 0 ,
149
149
}
@@ -1202,23 +1202,26 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref> ChannelMan
1202
1202
/// If a payment_secret *is* provided, we assume that the invoice had the basic_mpp feature bit
1203
1203
/// set (either as required or as available).
1204
1204
pub fn send_payment ( & self , route : Route , payment_hash : PaymentHash , payment_secret : Option < & [ u8 ; 32 ] > ) -> Result < ( ) , APIError > {
1205
- if route. hops . len ( ) < 1 || route. hops . len ( ) > 20 {
1206
- return Err ( APIError :: RouteError { err : "Route didn't go anywhere/had bogus size" } ) ;
1205
+ if route. paths . len ( ) < 1 || route. paths . len ( ) > 1 {
1206
+ return Err ( APIError :: RouteError { err : "We currently don't support MPP, and we need at least one path" } ) ;
1207
+ }
1208
+ if route. paths [ 0 ] . len ( ) < 1 || route. paths [ 0 ] . len ( ) > 20 {
1209
+ return Err ( APIError :: RouteError { err : "Path didn't go anywhere/had bogus size" } ) ;
1207
1210
}
1208
1211
let our_node_id = self . get_our_node_id ( ) ;
1209
- for ( idx, hop) in route. hops . iter ( ) . enumerate ( ) {
1210
- if idx != route. hops . len ( ) - 1 && hop. pubkey == our_node_id {
1211
- return Err ( APIError :: RouteError { err : "Route went through us but wasn't a simple rebalance loop to us" } ) ;
1212
+ for ( idx, hop) in route. paths [ 0 ] . iter ( ) . enumerate ( ) {
1213
+ if idx != route. paths [ 0 ] . len ( ) - 1 && hop. pubkey == our_node_id {
1214
+ return Err ( APIError :: RouteError { err : "Path went through us but wasn't a simple rebalance loop to us" } ) ;
1212
1215
}
1213
1216
}
1214
1217
1215
1218
let ( session_priv, prng_seed) = self . keys_manager . get_onion_rand ( ) ;
1216
1219
1217
1220
let cur_height = self . latest_block_height . load ( Ordering :: Acquire ) as u32 + 1 ;
1218
1221
1219
- let onion_keys = secp_call ! ( onion_utils:: construct_onion_keys( & self . secp_ctx, & route, & session_priv) ,
1222
+ let onion_keys = secp_call ! ( onion_utils:: construct_onion_keys( & self . secp_ctx, & route. paths [ 0 ] , & session_priv) ,
1220
1223
APIError :: RouteError { err: "Pubkey along hop was maliciously selected" } ) ;
1221
- let ( onion_payloads, htlc_msat, htlc_cltv) = onion_utils:: build_onion_payloads ( & route, payment_secret, cur_height) ?;
1224
+ let ( onion_payloads, htlc_msat, htlc_cltv) = onion_utils:: build_onion_payloads ( & route. paths [ 0 ] , payment_secret, cur_height) ?;
1222
1225
if onion_utils:: route_size_insane ( & onion_payloads) {
1223
1226
return Err ( APIError :: RouteError { err : "Route size too large considering onion data" } ) ;
1224
1227
}
@@ -1229,22 +1232,22 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref> ChannelMan
1229
1232
let mut channel_lock = self . channel_state . lock ( ) . unwrap ( ) ;
1230
1233
let err: Result < ( ) , _ > = loop {
1231
1234
1232
- let id = match channel_lock. short_to_id . get ( & route. hops . first ( ) . unwrap ( ) . short_channel_id ) {
1235
+ let id = match channel_lock. short_to_id . get ( & route. paths [ 0 ] . first ( ) . unwrap ( ) . short_channel_id ) {
1233
1236
None => return Err ( APIError :: ChannelUnavailable { err : "No channel available with first hop!" } ) ,
1234
1237
Some ( id) => id. clone ( ) ,
1235
1238
} ;
1236
1239
1237
1240
let channel_state = & mut * channel_lock;
1238
1241
if let hash_map:: Entry :: Occupied ( mut chan) = channel_state. by_id . entry ( id) {
1239
1242
match {
1240
- if chan. get ( ) . get_their_node_id ( ) != route. hops . first ( ) . unwrap ( ) . pubkey {
1243
+ if chan. get ( ) . get_their_node_id ( ) != route. paths [ 0 ] . first ( ) . unwrap ( ) . pubkey {
1241
1244
return Err ( APIError :: RouteError { err : "Node ID mismatch on first hop!" } ) ;
1242
1245
}
1243
1246
if !chan. get ( ) . is_live ( ) {
1244
1247
return Err ( APIError :: ChannelUnavailable { err : "Peer for first hop currently disconnected/pending monitor update!" } ) ;
1245
1248
}
1246
1249
break_chan_entry ! ( self , chan. get_mut( ) . send_htlc_and_commit( htlc_msat, payment_hash. clone( ) , htlc_cltv, HTLCSource :: OutboundRoute {
1247
- route : route. clone( ) ,
1250
+ path : route. paths [ 0 ] . clone( ) ,
1248
1251
session_priv: session_priv. clone( ) ,
1249
1252
first_hop_htlc_msat: htlc_msat,
1250
1253
} , onion_packet) , channel_state, chan)
@@ -1260,7 +1263,7 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref> ChannelMan
1260
1263
}
1261
1264
1262
1265
channel_state. pending_msg_events . push ( events:: MessageSendEvent :: UpdateHTLCs {
1263
- node_id : route. hops . first ( ) . unwrap ( ) . pubkey ,
1266
+ node_id : route. paths [ 0 ] . first ( ) . unwrap ( ) . pubkey ,
1264
1267
updates : msgs:: CommitmentUpdate {
1265
1268
update_add_htlcs : vec ! [ update_add] ,
1266
1269
update_fulfill_htlcs : Vec :: new ( ) ,
@@ -1277,7 +1280,7 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref> ChannelMan
1277
1280
return Ok ( ( ) ) ;
1278
1281
} ;
1279
1282
1280
- match handle_error ! ( self , err, route. hops . first( ) . unwrap( ) . pubkey, channel_lock) {
1283
+ match handle_error ! ( self , err, route. paths [ 0 ] . first( ) . unwrap( ) . pubkey, channel_lock) {
1281
1284
Ok ( _) => unreachable ! ( ) ,
1282
1285
Err ( e) => { Err ( APIError :: ChannelUnavailable { err : e. err } ) }
1283
1286
}
@@ -1730,7 +1733,7 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref> ChannelMan
1730
1733
//between the branches here. We should make this async and move it into the forward HTLCs
1731
1734
//timer handling.
1732
1735
match source {
1733
- HTLCSource :: OutboundRoute { ref route , .. } => {
1736
+ HTLCSource :: OutboundRoute { ref path , .. } => {
1734
1737
log_trace ! ( self , "Failing outbound payment HTLC with payment_hash {}" , log_bytes!( payment_hash. 0 ) ) ;
1735
1738
mem:: drop ( channel_state_lock) ;
1736
1739
match & onion_error {
@@ -1772,7 +1775,7 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref> ChannelMan
1772
1775
self . pending_events . lock ( ) . unwrap ( ) . push (
1773
1776
events:: Event :: PaymentFailed {
1774
1777
payment_hash : payment_hash. clone ( ) ,
1775
- rejected_by_dest : route . hops . len ( ) == 1 ,
1778
+ rejected_by_dest : path . len ( ) == 1 ,
1776
1779
#[ cfg( test) ]
1777
1780
error_code : Some ( * failure_code) ,
1778
1781
}
@@ -1836,9 +1839,19 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref> ChannelMan
1836
1839
let mut channel_state = Some ( self . channel_state . lock ( ) . unwrap ( ) ) ;
1837
1840
let removed_source = channel_state. as_mut ( ) . unwrap ( ) . claimable_htlcs . remove ( & ( payment_hash, * payment_secret) ) ;
1838
1841
if let Some ( mut sources) = removed_source {
1842
+ assert ! ( !sources. is_empty( ) ) ;
1843
+ let passes_value = if let & Some ( ref data) = & sources[ 0 ] . payment_data {
1844
+ assert ! ( payment_secret. is_some( ) ) ;
1845
+ if data. total_msat == expected_amount { true } else { false }
1846
+ } else {
1847
+ assert ! ( payment_secret. is_none( ) ) ;
1848
+ false
1849
+ } ;
1850
+
1851
+ let mut one_claimed = false ;
1839
1852
for htlc in sources. drain ( ..) {
1840
1853
if channel_state. is_none ( ) { channel_state = Some ( self . channel_state . lock ( ) . unwrap ( ) ) ; }
1841
- if htlc. value < expected_amount || htlc. value > expected_amount * 2 {
1854
+ if !passes_value && ( htlc. value < expected_amount || htlc. value > expected_amount * 2 ) {
1842
1855
let mut htlc_msat_data = byte_utils:: be64_to_array ( htlc. value ) . to_vec ( ) ;
1843
1856
let mut height_data = byte_utils:: be32_to_array ( self . latest_block_height . load ( Ordering :: Acquire ) as u32 ) . to_vec ( ) ;
1844
1857
htlc_msat_data. append ( & mut height_data) ;
@@ -1847,9 +1860,10 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref> ChannelMan
1847
1860
HTLCFailReason :: Reason { failure_code : 0x4000 |15 , data : htlc_msat_data } ) ;
1848
1861
} else {
1849
1862
self . claim_funds_internal ( channel_state. take ( ) . unwrap ( ) , HTLCSource :: PreviousHopData ( htlc. prev_hop ) , payment_preimage) ;
1863
+ one_claimed = true ;
1850
1864
}
1851
1865
}
1852
- true
1866
+ one_claimed
1853
1867
} else { false }
1854
1868
}
1855
1869
fn claim_funds_internal ( & self , mut channel_state_lock : MutexGuard < ChannelHolder < ChanSigner > > , source : HTLCSource , payment_preimage : PaymentPreimage ) {
@@ -3308,9 +3322,9 @@ impl Writeable for HTLCSource {
3308
3322
0u8 . write ( writer) ?;
3309
3323
hop_data. write ( writer) ?;
3310
3324
} ,
3311
- & HTLCSource :: OutboundRoute { ref route , ref session_priv, ref first_hop_htlc_msat } => {
3325
+ & HTLCSource :: OutboundRoute { ref path , ref session_priv, ref first_hop_htlc_msat } => {
3312
3326
1u8 . write ( writer) ?;
3313
- route . write ( writer) ?;
3327
+ path . write ( writer) ?;
3314
3328
session_priv. write ( writer) ?;
3315
3329
first_hop_htlc_msat. write ( writer) ?;
3316
3330
}
@@ -3324,7 +3338,7 @@ impl Readable for HTLCSource {
3324
3338
match <u8 as Readable >:: read ( reader) ? {
3325
3339
0 => Ok ( HTLCSource :: PreviousHopData ( Readable :: read ( reader) ?) ) ,
3326
3340
1 => Ok ( HTLCSource :: OutboundRoute {
3327
- route : Readable :: read ( reader) ?,
3341
+ path : Readable :: read ( reader) ?,
3328
3342
session_priv : Readable :: read ( reader) ?,
3329
3343
first_hop_htlc_msat : Readable :: read ( reader) ?,
3330
3344
} ) ,
0 commit comments