@@ -2075,6 +2075,21 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
2075
2075
Some ( id) => id. clone ( ) ,
2076
2076
} ;
2077
2077
2078
+ macro_rules! insert_outbound_payment {
2079
+ ( ) => {
2080
+ let payment = payment_entry. or_insert_with( || PendingOutboundPayment :: Retryable {
2081
+ session_privs: HashSet :: new( ) ,
2082
+ pending_amt_msat: 0 ,
2083
+ pending_fee_msat: Some ( 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) ) ;
2090
+ }
2091
+ }
2092
+
2078
2093
let channel_state = & mut * channel_lock;
2079
2094
if let hash_map:: Entry :: Occupied ( mut chan) = channel_state. by_id . entry ( id) {
2080
2095
match {
@@ -2084,7 +2099,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
2084
2099
if !chan. get ( ) . is_live ( ) {
2085
2100
return Err ( APIError :: ChannelUnavailable { err : "Peer for first hop currently disconnected/pending monitor update!" . to_owned ( ) } ) ;
2086
2101
}
2087
- let send_res = break_chan_entry ! ( self , chan. get_mut( ) . send_htlc_and_commit(
2102
+ break_chan_entry ! ( self , chan. get_mut( ) . send_htlc_and_commit(
2088
2103
htlc_msat, payment_hash. clone( ) , htlc_cltv, HTLCSource :: OutboundRoute {
2089
2104
path: path. clone( ) ,
2090
2105
session_priv: session_priv. clone( ) ,
@@ -2093,20 +2108,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
2093
2108
payment_secret: payment_secret. clone( ) ,
2094
2109
payee: payee. clone( ) ,
2095
2110
} , onion_packet, & self . logger) ,
2096
- channel_state, chan) ;
2097
-
2098
- let payment = payment_entry. or_insert_with ( || PendingOutboundPayment :: Retryable {
2099
- session_privs : HashSet :: new ( ) ,
2100
- pending_amt_msat : 0 ,
2101
- pending_fee_msat : Some ( 0 ) ,
2102
- payment_hash : * payment_hash,
2103
- payment_secret : * payment_secret,
2104
- starting_block_height : self . best_block . read ( ) . unwrap ( ) . height ( ) ,
2105
- total_msat : total_value,
2106
- } ) ;
2107
- assert ! ( payment. insert( session_priv_bytes, path) ) ;
2108
-
2109
- send_res
2111
+ channel_state, chan)
2110
2112
} {
2111
2113
Some ( ( update_add, commitment_signed, monitor_update) ) => {
2112
2114
if let Err ( e) = self . chain_monitor . update_channel ( chan. get ( ) . get_funding_txo ( ) . unwrap ( ) , monitor_update) {
@@ -2116,8 +2118,10 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
2116
2118
// is restored. Therefore, we must return an error indicating that
2117
2119
// it is unsafe to retry the payment wholesale, which we do in the
2118
2120
// send_payment check for MonitorUpdateFailed, below.
2121
+ insert_outbound_payment ! ( ) ; // Only do this after possibly break'ing on Perm failure above.
2119
2122
return Err ( APIError :: MonitorUpdateFailed ) ;
2120
2123
}
2124
+ insert_outbound_payment ! ( ) ;
2121
2125
2122
2126
log_debug ! ( self . logger, "Sending payment along path resulted in a commitment_signed for channel {}" , log_bytes!( chan. get( ) . channel_id( ) ) ) ;
2123
2127
channel_state. pending_msg_events . push ( events:: MessageSendEvent :: UpdateHTLCs {
@@ -2132,7 +2136,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
2132
2136
} ,
2133
2137
} ) ;
2134
2138
} ,
2135
- None => { } ,
2139
+ None => { insert_outbound_payment ! ( ) ; } ,
2136
2140
}
2137
2141
} else { unreachable ! ( ) ; }
2138
2142
return Ok ( ( ) ) ;
@@ -2249,6 +2253,9 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
2249
2253
if has_err && has_ok {
2250
2254
Err ( PaymentSendFailure :: PartialFailure ( results) )
2251
2255
} else if has_err {
2256
+ // If we failed to send any paths, we shouldn't have inserted the new PaymentId into
2257
+ // our `pending_outbound_payments` map at all.
2258
+ debug_assert ! ( self . pending_outbound_payments. lock( ) . unwrap( ) . get( & payment_id) . is_none( ) ) ;
2252
2259
Err ( PaymentSendFailure :: AllFailedRetrySafe ( results. drain ( ..) . map ( |r| r. unwrap_err ( ) ) . collect ( ) ) )
2253
2260
} else {
2254
2261
Ok ( payment_id)
0 commit comments