@@ -2058,6 +2058,20 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
2058
2058
Some ( id) => id. clone ( ) ,
2059
2059
} ;
2060
2060
2061
+ macro_rules! insert_payment_id {
2062
+ ( ) => {
2063
+ let payment = payment_entry. or_insert_with( || PendingOutboundPayment :: Retryable {
2064
+ session_privs: HashSet :: new( ) ,
2065
+ pending_amt_msat: 0 ,
2066
+ payment_hash: * payment_hash,
2067
+ payment_secret: * payment_secret,
2068
+ starting_block_height: self . best_block. read( ) . unwrap( ) . height( ) ,
2069
+ total_msat: total_value,
2070
+ } ) ;
2071
+ assert!( payment. insert( session_priv_bytes, path. last( ) . unwrap( ) . fee_msat) ) ;
2072
+ }
2073
+ }
2074
+
2061
2075
let channel_state = & mut * channel_lock;
2062
2076
if let hash_map:: Entry :: Occupied ( mut chan) = channel_state. by_id . entry ( id) {
2063
2077
match {
@@ -2067,7 +2081,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
2067
2081
if !chan. get ( ) . is_live ( ) {
2068
2082
return Err ( APIError :: ChannelUnavailable { err : "Peer for first hop currently disconnected/pending monitor update!" . to_owned ( ) } ) ;
2069
2083
}
2070
- let send_res = break_chan_entry ! ( self , chan. get_mut( ) . send_htlc_and_commit(
2084
+ break_chan_entry ! ( self , chan. get_mut( ) . send_htlc_and_commit(
2071
2085
htlc_msat, payment_hash. clone( ) , htlc_cltv, HTLCSource :: OutboundRoute {
2072
2086
path: path. clone( ) ,
2073
2087
session_priv: session_priv. clone( ) ,
@@ -2076,19 +2090,8 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
2076
2090
payment_secret: payment_secret. clone( ) ,
2077
2091
payee: payee. clone( ) ,
2078
2092
} , onion_packet, & self . logger) ,
2079
- channel_state, chan) ;
2080
-
2081
- let payment = payment_entry. or_insert_with ( || PendingOutboundPayment :: Retryable {
2082
- session_privs : HashSet :: new ( ) ,
2083
- pending_amt_msat : 0 ,
2084
- payment_hash : * payment_hash,
2085
- payment_secret : * payment_secret,
2086
- starting_block_height : self . best_block . read ( ) . unwrap ( ) . height ( ) ,
2087
- total_msat : total_value,
2088
- } ) ;
2089
- assert ! ( payment. insert( session_priv_bytes, path. last( ) . unwrap( ) . fee_msat) ) ;
2093
+ channel_state, chan)
2090
2094
2091
- send_res
2092
2095
} {
2093
2096
Some ( ( update_add, commitment_signed, monitor_update) ) => {
2094
2097
if let Err ( e) = self . chain_monitor . update_channel ( chan. get ( ) . get_funding_txo ( ) . unwrap ( ) , monitor_update) {
@@ -2098,8 +2101,10 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
2098
2101
// is restored. Therefore, we must return an error indicating that
2099
2102
// it is unsafe to retry the payment wholesale, which we do in the
2100
2103
// send_payment check for MonitorUpdateFailed, below.
2104
+ insert_payment_id ! ( ) ; // Only do this after possibly break'ing on Perm failure above.
2101
2105
return Err ( APIError :: MonitorUpdateFailed ) ;
2102
2106
}
2107
+ insert_payment_id ! ( ) ;
2103
2108
2104
2109
log_debug ! ( self . logger, "Sending payment along path resulted in a commitment_signed for channel {}" , log_bytes!( chan. get( ) . channel_id( ) ) ) ;
2105
2110
channel_state. pending_msg_events . push ( events:: MessageSendEvent :: UpdateHTLCs {
@@ -2114,7 +2119,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
2114
2119
} ,
2115
2120
} ) ;
2116
2121
} ,
2117
- None => { } ,
2122
+ None => { insert_payment_id ! ( ) ; } ,
2118
2123
}
2119
2124
} else { unreachable ! ( ) ; }
2120
2125
return Ok ( ( ) ) ;
@@ -2231,6 +2236,9 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
2231
2236
if has_err && has_ok {
2232
2237
Err ( PaymentSendFailure :: PartialFailure ( results) )
2233
2238
} else if has_err {
2239
+ // If we failed to send any paths, we shouldn't have inserted the new PaymentId into
2240
+ // our `pending_outbound_payments` map at all.
2241
+ debug_assert ! ( self . pending_outbound_payments. lock( ) . unwrap( ) . get( & payment_id) . is_none( ) ) ;
2234
2242
Err ( PaymentSendFailure :: AllFailedRetrySafe ( results. drain ( ..) . map ( |r| r. unwrap_err ( ) ) . collect ( ) ) )
2235
2243
} else {
2236
2244
Ok ( payment_id)
0 commit comments