@@ -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 } ;
@@ -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
}
@@ -1191,23 +1191,26 @@ impl<ChanSigner: ChannelKeys, M: Deref> ChannelManager<ChanSigner, M> where M::T
1191
1191
/// If a payment_secret *is* provided, we assume that the invoice had the basic_mpp feature bit
1192
1192
/// set (either as required or as available).
1193
1193
pub fn send_payment ( & self , route : Route , payment_hash : PaymentHash , payment_secret : Option < & [ u8 ; 32 ] > ) -> Result < ( ) , APIError > {
1194
- if route. hops . len ( ) < 1 || route. hops . len ( ) > 20 {
1195
- return Err ( APIError :: RouteError { err : "Route didn't go anywhere/had bogus size" } ) ;
1194
+ if route. paths . len ( ) < 1 || route. paths . len ( ) > 1 {
1195
+ return Err ( APIError :: RouteError { err : "We currently don't support MPP, and we need at least one path" } ) ;
1196
+ }
1197
+ if route. paths [ 0 ] . len ( ) < 1 || route. paths [ 0 ] . len ( ) > 20 {
1198
+ return Err ( APIError :: RouteError { err : "Path didn't go anywhere/had bogus size" } ) ;
1196
1199
}
1197
1200
let our_node_id = self . get_our_node_id ( ) ;
1198
- for ( idx, hop) in route. hops . iter ( ) . enumerate ( ) {
1199
- if idx != route. hops . len ( ) - 1 && hop. pubkey == our_node_id {
1200
- return Err ( APIError :: RouteError { err : "Route went through us but wasn't a simple rebalance loop to us" } ) ;
1201
+ for ( idx, hop) in route. paths [ 0 ] . iter ( ) . enumerate ( ) {
1202
+ if idx != route. paths [ 0 ] . len ( ) - 1 && hop. pubkey == our_node_id {
1203
+ return Err ( APIError :: RouteError { err : "Path went through us but wasn't a simple rebalance loop to us" } ) ;
1201
1204
}
1202
1205
}
1203
1206
1204
1207
let ( session_priv, prng_seed) = self . keys_manager . get_onion_rand ( ) ;
1205
1208
1206
1209
let cur_height = self . latest_block_height . load ( Ordering :: Acquire ) as u32 + 1 ;
1207
1210
1208
- let onion_keys = secp_call ! ( onion_utils:: construct_onion_keys( & self . secp_ctx, & route, & session_priv) ,
1211
+ let onion_keys = secp_call ! ( onion_utils:: construct_onion_keys( & self . secp_ctx, & route. paths [ 0 ] , & session_priv) ,
1209
1212
APIError :: RouteError { err: "Pubkey along hop was maliciously selected" } ) ;
1210
- let ( onion_payloads, htlc_msat, htlc_cltv) = onion_utils:: build_onion_payloads ( & route, payment_secret, cur_height) ?;
1213
+ let ( onion_payloads, htlc_msat, htlc_cltv) = onion_utils:: build_onion_payloads ( & route. paths [ 0 ] , payment_secret, cur_height) ?;
1211
1214
if onion_utils:: route_size_insane ( & onion_payloads) {
1212
1215
return Err ( APIError :: RouteError { err : "Route size too large considering onion data" } ) ;
1213
1216
}
@@ -1218,22 +1221,22 @@ impl<ChanSigner: ChannelKeys, M: Deref> ChannelManager<ChanSigner, M> where M::T
1218
1221
let mut channel_lock = self . channel_state . lock ( ) . unwrap ( ) ;
1219
1222
let err: Result < ( ) , _ > = loop {
1220
1223
1221
- let id = match channel_lock. short_to_id . get ( & route. hops . first ( ) . unwrap ( ) . short_channel_id ) {
1224
+ let id = match channel_lock. short_to_id . get ( & route. paths [ 0 ] . first ( ) . unwrap ( ) . short_channel_id ) {
1222
1225
None => return Err ( APIError :: ChannelUnavailable { err : "No channel available with first hop!" } ) ,
1223
1226
Some ( id) => id. clone ( ) ,
1224
1227
} ;
1225
1228
1226
1229
let channel_state = & mut * channel_lock;
1227
1230
if let hash_map:: Entry :: Occupied ( mut chan) = channel_state. by_id . entry ( id) {
1228
1231
match {
1229
- if chan. get ( ) . get_their_node_id ( ) != route. hops . first ( ) . unwrap ( ) . pubkey {
1232
+ if chan. get ( ) . get_their_node_id ( ) != route. paths [ 0 ] . first ( ) . unwrap ( ) . pubkey {
1230
1233
return Err ( APIError :: RouteError { err : "Node ID mismatch on first hop!" } ) ;
1231
1234
}
1232
1235
if !chan. get ( ) . is_live ( ) {
1233
1236
return Err ( APIError :: ChannelUnavailable { err : "Peer for first hop currently disconnected/pending monitor update!" } ) ;
1234
1237
}
1235
1238
break_chan_entry ! ( self , chan. get_mut( ) . send_htlc_and_commit( htlc_msat, payment_hash. clone( ) , htlc_cltv, HTLCSource :: OutboundRoute {
1236
- route : route. clone( ) ,
1239
+ path : route. paths [ 0 ] . clone( ) ,
1237
1240
session_priv: session_priv. clone( ) ,
1238
1241
first_hop_htlc_msat: htlc_msat,
1239
1242
} , onion_packet) , channel_state, chan)
@@ -1249,7 +1252,7 @@ impl<ChanSigner: ChannelKeys, M: Deref> ChannelManager<ChanSigner, M> where M::T
1249
1252
}
1250
1253
1251
1254
channel_state. pending_msg_events . push ( events:: MessageSendEvent :: UpdateHTLCs {
1252
- node_id : route. hops . first ( ) . unwrap ( ) . pubkey ,
1255
+ node_id : route. paths [ 0 ] . first ( ) . unwrap ( ) . pubkey ,
1253
1256
updates : msgs:: CommitmentUpdate {
1254
1257
update_add_htlcs : vec ! [ update_add] ,
1255
1258
update_fulfill_htlcs : Vec :: new ( ) ,
@@ -1266,7 +1269,7 @@ impl<ChanSigner: ChannelKeys, M: Deref> ChannelManager<ChanSigner, M> where M::T
1266
1269
return Ok ( ( ) ) ;
1267
1270
} ;
1268
1271
1269
- match handle_error ! ( self , err, route. hops . first( ) . unwrap( ) . pubkey, channel_lock) {
1272
+ match handle_error ! ( self , err, route. paths [ 0 ] . first( ) . unwrap( ) . pubkey, channel_lock) {
1270
1273
Ok ( _) => unreachable ! ( ) ,
1271
1274
Err ( e) => { Err ( APIError :: ChannelUnavailable { err : e. err } ) }
1272
1275
}
@@ -1701,7 +1704,7 @@ impl<ChanSigner: ChannelKeys, M: Deref> ChannelManager<ChanSigner, M> where M::T
1701
1704
//between the branches here. We should make this async and move it into the forward HTLCs
1702
1705
//timer handling.
1703
1706
match source {
1704
- HTLCSource :: OutboundRoute { ref route , .. } => {
1707
+ HTLCSource :: OutboundRoute { ref path , .. } => {
1705
1708
log_trace ! ( self , "Failing outbound payment HTLC with payment_hash {}" , log_bytes!( payment_hash. 0 ) ) ;
1706
1709
mem:: drop ( channel_state_lock) ;
1707
1710
match & onion_error {
@@ -1743,7 +1746,7 @@ impl<ChanSigner: ChannelKeys, M: Deref> ChannelManager<ChanSigner, M> where M::T
1743
1746
self . pending_events . lock ( ) . unwrap ( ) . push (
1744
1747
events:: Event :: PaymentFailed {
1745
1748
payment_hash : payment_hash. clone ( ) ,
1746
- rejected_by_dest : route . hops . len ( ) == 1 ,
1749
+ rejected_by_dest : path . len ( ) == 1 ,
1747
1750
#[ cfg( test) ]
1748
1751
error_code : Some ( * failure_code) ,
1749
1752
}
@@ -1807,9 +1810,19 @@ impl<ChanSigner: ChannelKeys, M: Deref> ChannelManager<ChanSigner, M> where M::T
1807
1810
let mut channel_state = Some ( self . channel_state . lock ( ) . unwrap ( ) ) ;
1808
1811
let removed_source = channel_state. as_mut ( ) . unwrap ( ) . claimable_htlcs . remove ( & ( payment_hash, * payment_secret) ) ;
1809
1812
if let Some ( mut sources) = removed_source {
1813
+ assert ! ( !sources. is_empty( ) ) ;
1814
+ let passes_value = if let & Some ( ref data) = & sources[ 0 ] . payment_data {
1815
+ assert ! ( payment_secret. is_some( ) ) ;
1816
+ if data. total_msat == expected_amount { true } else { false }
1817
+ } else {
1818
+ assert ! ( payment_secret. is_none( ) ) ;
1819
+ false
1820
+ } ;
1821
+
1822
+ let mut one_claimed = false ;
1810
1823
for htlc in sources. drain ( ..) {
1811
1824
if channel_state. is_none ( ) { channel_state = Some ( self . channel_state . lock ( ) . unwrap ( ) ) ; }
1812
- if htlc. value < expected_amount || htlc. value > expected_amount * 2 {
1825
+ if !passes_value && ( htlc. value < expected_amount || htlc. value > expected_amount * 2 ) {
1813
1826
let mut htlc_msat_data = byte_utils:: be64_to_array ( htlc. value ) . to_vec ( ) ;
1814
1827
let mut height_data = byte_utils:: be32_to_array ( self . latest_block_height . load ( Ordering :: Acquire ) as u32 ) . to_vec ( ) ;
1815
1828
htlc_msat_data. append ( & mut height_data) ;
@@ -1818,9 +1831,10 @@ impl<ChanSigner: ChannelKeys, M: Deref> ChannelManager<ChanSigner, M> where M::T
1818
1831
HTLCFailReason :: Reason { failure_code : 0x4000 |15 , data : htlc_msat_data } ) ;
1819
1832
} else {
1820
1833
self . claim_funds_internal ( channel_state. take ( ) . unwrap ( ) , HTLCSource :: PreviousHopData ( htlc. src ) , payment_preimage) ;
1834
+ one_claimed = true ;
1821
1835
}
1822
1836
}
1823
- true
1837
+ one_claimed
1824
1838
} else { false }
1825
1839
}
1826
1840
fn claim_funds_internal ( & self , mut channel_state_lock : MutexGuard < ChannelHolder < ChanSigner > > , source : HTLCSource , payment_preimage : PaymentPreimage ) {
@@ -3233,9 +3247,9 @@ impl Writeable for HTLCSource {
3233
3247
0u8 . write ( writer) ?;
3234
3248
hop_data. write ( writer) ?;
3235
3249
} ,
3236
- & HTLCSource :: OutboundRoute { ref route , ref session_priv, ref first_hop_htlc_msat } => {
3250
+ & HTLCSource :: OutboundRoute { ref path , ref session_priv, ref first_hop_htlc_msat } => {
3237
3251
1u8 . write ( writer) ?;
3238
- route . write ( writer) ?;
3252
+ path . write ( writer) ?;
3239
3253
session_priv. write ( writer) ?;
3240
3254
first_hop_htlc_msat. write ( writer) ?;
3241
3255
}
@@ -3249,7 +3263,7 @@ impl<R: ::std::io::Read> Readable<R> for HTLCSource {
3249
3263
match <u8 as Readable < R > >:: read ( reader) ? {
3250
3264
0 => Ok ( HTLCSource :: PreviousHopData ( Readable :: read ( reader) ?) ) ,
3251
3265
1 => Ok ( HTLCSource :: OutboundRoute {
3252
- route : Readable :: read ( reader) ?,
3266
+ path : Readable :: read ( reader) ?,
3253
3267
session_priv : Readable :: read ( reader) ?,
3254
3268
first_hop_htlc_msat : Readable :: read ( reader) ?,
3255
3269
} ) ,
0 commit comments