@@ -29,8 +29,8 @@ use chain::chaininterface::{BroadcasterInterface,ChainListener,FeeEstimator};
29
29
use chain:: transaction:: OutPoint ;
30
30
use ln:: channel:: { Channel , ChannelError } ;
31
31
use ln:: channelmonitor:: { ChannelMonitor , ChannelMonitorUpdateErr , ManyChannelMonitor , CLTV_CLAIM_BUFFER , LATENCY_GRACE_PERIOD_BLOCKS , ANTI_REORG_DELAY } ;
32
- use ln:: router:: Route ;
33
32
use ln:: features:: { InitFeatures , NodeFeatures } ;
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 } ;
@@ -130,7 +130,7 @@ struct ClaimableHTLC {
130
130
pub ( super ) enum HTLCSource {
131
131
PreviousHopData ( HTLCPreviousHopData ) ,
132
132
OutboundRoute {
133
- route : Route ,
133
+ path : Vec < RouteHop > ,
134
134
session_priv : SecretKey ,
135
135
/// Technically we can recalculate this from the route, but we cache it here to avoid
136
136
/// doing a double-pass on route when we get a failure back
@@ -141,7 +141,7 @@ pub(super) enum HTLCSource {
141
141
impl HTLCSource {
142
142
pub fn dummy ( ) -> Self {
143
143
HTLCSource :: OutboundRoute {
144
- route : Route { hops : Vec :: new ( ) } ,
144
+ path : Vec :: new ( ) ,
145
145
session_priv : SecretKey :: from_slice ( & [ 1 ; 32 ] ) . unwrap ( ) ,
146
146
first_hop_htlc_msat : 0 ,
147
147
}
@@ -1206,23 +1206,26 @@ impl<ChanSigner: ChannelKeys> ChannelManager<ChanSigner> {
1206
1206
/// If a payment_secret *is* provided, we assume that the invoice had the basic_mpp feature bit
1207
1207
/// set (either as required or as available).
1208
1208
pub fn send_payment ( & self , route : Route , payment_hash : PaymentHash , payment_secret : Option < & [ u8 ; 32 ] > ) -> Result < ( ) , APIError > {
1209
- if route. hops . len ( ) < 1 || route. hops . len ( ) > 20 {
1210
- return Err ( APIError :: RouteError { err : "Route didn't go anywhere/had bogus size" } ) ;
1209
+ if route. paths . len ( ) < 1 || route. paths . len ( ) > 1 {
1210
+ return Err ( APIError :: RouteError { err : "We currently don't support MPP, and we need at least one path" } ) ;
1211
+ }
1212
+ if route. paths [ 0 ] . len ( ) < 1 || route. paths [ 0 ] . len ( ) > 20 {
1213
+ return Err ( APIError :: RouteError { err : "Path didn't go anywhere/had bogus size" } ) ;
1211
1214
}
1212
1215
let our_node_id = self . get_our_node_id ( ) ;
1213
- for ( idx, hop) in route. hops . iter ( ) . enumerate ( ) {
1214
- if idx != route. hops . len ( ) - 1 && hop. pubkey == our_node_id {
1215
- return Err ( APIError :: RouteError { err : "Route went through us but wasn't a simple rebalance loop to us" } ) ;
1216
+ for ( idx, hop) in route. paths [ 0 ] . iter ( ) . enumerate ( ) {
1217
+ if idx != route. paths [ 0 ] . len ( ) - 1 && hop. pubkey == our_node_id {
1218
+ return Err ( APIError :: RouteError { err : "Path went through us but wasn't a simple rebalance loop to us" } ) ;
1216
1219
}
1217
1220
}
1218
1221
1219
1222
let ( session_priv, prng_seed) = self . keys_manager . get_onion_rand ( ) ;
1220
1223
1221
1224
let cur_height = self . latest_block_height . load ( Ordering :: Acquire ) as u32 + 1 ;
1222
1225
1223
- let onion_keys = secp_call ! ( onion_utils:: construct_onion_keys( & self . secp_ctx, & route, & session_priv) ,
1226
+ let onion_keys = secp_call ! ( onion_utils:: construct_onion_keys( & self . secp_ctx, & route. paths [ 0 ] , & session_priv) ,
1224
1227
APIError :: RouteError { err: "Pubkey along hop was maliciously selected" } ) ;
1225
- let ( onion_payloads, htlc_msat, htlc_cltv) = onion_utils:: build_onion_payloads ( & route, payment_secret, cur_height) ?;
1228
+ let ( onion_payloads, htlc_msat, htlc_cltv) = onion_utils:: build_onion_payloads ( & route. paths [ 0 ] , payment_secret, cur_height) ?;
1226
1229
if onion_utils:: route_size_insane ( & onion_payloads) {
1227
1230
return Err ( APIError :: RouteError { err : "Route had too large size once" } ) ;
1228
1231
}
@@ -1233,22 +1236,22 @@ impl<ChanSigner: ChannelKeys> ChannelManager<ChanSigner> {
1233
1236
let mut channel_lock = self . channel_state . lock ( ) . unwrap ( ) ;
1234
1237
let err: Result < ( ) , _ > = loop {
1235
1238
1236
- let id = match channel_lock. short_to_id . get ( & route. hops . first ( ) . unwrap ( ) . short_channel_id ) {
1239
+ let id = match channel_lock. short_to_id . get ( & route. paths [ 0 ] . first ( ) . unwrap ( ) . short_channel_id ) {
1237
1240
None => return Err ( APIError :: ChannelUnavailable { err : "No channel available with first hop!" } ) ,
1238
1241
Some ( id) => id. clone ( ) ,
1239
1242
} ;
1240
1243
1241
1244
let channel_state = channel_lock. borrow_parts ( ) ;
1242
1245
if let hash_map:: Entry :: Occupied ( mut chan) = channel_state. by_id . entry ( id) {
1243
1246
match {
1244
- if chan. get ( ) . get_their_node_id ( ) != route. hops . first ( ) . unwrap ( ) . pubkey {
1247
+ if chan. get ( ) . get_their_node_id ( ) != route. paths [ 0 ] . first ( ) . unwrap ( ) . pubkey {
1245
1248
return Err ( APIError :: RouteError { err : "Node ID mismatch on first hop!" } ) ;
1246
1249
}
1247
1250
if !chan. get ( ) . is_live ( ) {
1248
1251
return Err ( APIError :: ChannelUnavailable { err : "Peer for first hop currently disconnected/pending monitor update!" } ) ;
1249
1252
}
1250
1253
break_chan_entry ! ( self , chan. get_mut( ) . send_htlc_and_commit( htlc_msat, payment_hash. clone( ) , htlc_cltv, HTLCSource :: OutboundRoute {
1251
- route : route. clone( ) ,
1254
+ path : route. paths [ 0 ] . clone( ) ,
1252
1255
session_priv: session_priv. clone( ) ,
1253
1256
first_hop_htlc_msat: htlc_msat,
1254
1257
} , onion_packet) , channel_state, chan)
@@ -1264,7 +1267,7 @@ impl<ChanSigner: ChannelKeys> ChannelManager<ChanSigner> {
1264
1267
}
1265
1268
1266
1269
channel_state. pending_msg_events . push ( events:: MessageSendEvent :: UpdateHTLCs {
1267
- node_id : route. hops . first ( ) . unwrap ( ) . pubkey ,
1270
+ node_id : route. paths [ 0 ] . first ( ) . unwrap ( ) . pubkey ,
1268
1271
updates : msgs:: CommitmentUpdate {
1269
1272
update_add_htlcs : vec ! [ update_add] ,
1270
1273
update_fulfill_htlcs : Vec :: new ( ) ,
@@ -1281,7 +1284,7 @@ impl<ChanSigner: ChannelKeys> ChannelManager<ChanSigner> {
1281
1284
return Ok ( ( ) ) ;
1282
1285
} ;
1283
1286
1284
- match handle_error ! ( self , err, route. hops . first( ) . unwrap( ) . pubkey, channel_lock) {
1287
+ match handle_error ! ( self , err, route. paths [ 0 ] . first( ) . unwrap( ) . pubkey, channel_lock) {
1285
1288
Ok ( _) => unreachable ! ( ) ,
1286
1289
Err ( e) => { Err ( APIError :: ChannelUnavailable { err : e. err } ) }
1287
1290
}
@@ -1711,7 +1714,7 @@ impl<ChanSigner: ChannelKeys> ChannelManager<ChanSigner> {
1711
1714
//between the branches here. We should make this async and move it into the forward HTLCs
1712
1715
//timer handling.
1713
1716
match source {
1714
- HTLCSource :: OutboundRoute { ref route , .. } => {
1717
+ HTLCSource :: OutboundRoute { ref path , .. } => {
1715
1718
log_trace ! ( self , "Failing outbound payment HTLC with payment_hash {}" , log_bytes!( payment_hash. 0 ) ) ;
1716
1719
mem:: drop ( channel_state_lock) ;
1717
1720
match & onion_error {
@@ -1753,7 +1756,7 @@ impl<ChanSigner: ChannelKeys> ChannelManager<ChanSigner> {
1753
1756
self . pending_events . lock ( ) . unwrap ( ) . push (
1754
1757
events:: Event :: PaymentFailed {
1755
1758
payment_hash : payment_hash. clone ( ) ,
1756
- rejected_by_dest : route . hops . len ( ) == 1 ,
1759
+ rejected_by_dest : path . len ( ) == 1 ,
1757
1760
#[ cfg( test) ]
1758
1761
error_code : Some ( * failure_code) ,
1759
1762
}
@@ -1817,9 +1820,19 @@ impl<ChanSigner: ChannelKeys> ChannelManager<ChanSigner> {
1817
1820
let mut channel_state = Some ( self . channel_state . lock ( ) . unwrap ( ) ) ;
1818
1821
let removed_source = channel_state. as_mut ( ) . unwrap ( ) . claimable_htlcs . remove ( & ( payment_hash, * payment_secret) ) ;
1819
1822
if let Some ( mut sources) = removed_source {
1823
+ assert ! ( !sources. is_empty( ) ) ;
1824
+ let passes_value = if let & Some ( ref data) = & sources[ 0 ] . payment_data {
1825
+ assert ! ( payment_secret. is_some( ) ) ;
1826
+ if data. total_msat == expected_amount { true } else { false }
1827
+ } else {
1828
+ assert ! ( payment_secret. is_none( ) ) ;
1829
+ false
1830
+ } ;
1831
+
1832
+ let mut one_claimed = false ;
1820
1833
for htlc in sources. drain ( ..) {
1821
1834
if channel_state. is_none ( ) { channel_state = Some ( self . channel_state . lock ( ) . unwrap ( ) ) ; }
1822
- if htlc. value < expected_amount || htlc. value > expected_amount * 2 {
1835
+ if !passes_value && ( htlc. value < expected_amount || htlc. value > expected_amount * 2 ) {
1823
1836
let mut htlc_msat_data = byte_utils:: be64_to_array ( htlc. value ) . to_vec ( ) ;
1824
1837
let mut height_data = byte_utils:: be32_to_array ( self . latest_block_height . load ( Ordering :: Acquire ) as u32 ) . to_vec ( ) ;
1825
1838
htlc_msat_data. append ( & mut height_data) ;
@@ -1828,9 +1841,10 @@ impl<ChanSigner: ChannelKeys> ChannelManager<ChanSigner> {
1828
1841
HTLCFailReason :: Reason { failure_code : 0x4000 |15 , data : htlc_msat_data } ) ;
1829
1842
} else {
1830
1843
self . claim_funds_internal ( channel_state. take ( ) . unwrap ( ) , HTLCSource :: PreviousHopData ( htlc. src ) , payment_preimage) ;
1844
+ one_claimed = true ;
1831
1845
}
1832
1846
}
1833
- true
1847
+ one_claimed
1834
1848
} else { false }
1835
1849
}
1836
1850
fn claim_funds_internal ( & self , mut channel_state_lock : MutexGuard < ChannelHolder < ChanSigner > > , source : HTLCSource , payment_preimage : PaymentPreimage ) {
@@ -3236,9 +3250,9 @@ impl Writeable for HTLCSource {
3236
3250
0u8 . write ( writer) ?;
3237
3251
hop_data. write ( writer) ?;
3238
3252
} ,
3239
- & HTLCSource :: OutboundRoute { ref route , ref session_priv, ref first_hop_htlc_msat } => {
3253
+ & HTLCSource :: OutboundRoute { ref path , ref session_priv, ref first_hop_htlc_msat } => {
3240
3254
1u8 . write ( writer) ?;
3241
- route . write ( writer) ?;
3255
+ path . write ( writer) ?;
3242
3256
session_priv. write ( writer) ?;
3243
3257
first_hop_htlc_msat. write ( writer) ?;
3244
3258
}
@@ -3252,7 +3266,7 @@ impl<R: ::std::io::Read> Readable<R> for HTLCSource {
3252
3266
match <u8 as Readable < R > >:: read ( reader) ? {
3253
3267
0 => Ok ( HTLCSource :: PreviousHopData ( Readable :: read ( reader) ?) ) ,
3254
3268
1 => Ok ( HTLCSource :: OutboundRoute {
3255
- route : Readable :: read ( reader) ?,
3269
+ path : Readable :: read ( reader) ?,
3256
3270
session_priv : Readable :: read ( reader) ?,
3257
3271
first_hop_htlc_msat : Readable :: read ( reader) ?,
3258
3272
} ) ,
0 commit comments