@@ -442,6 +442,18 @@ pub struct ChannelManager<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref,
442442 /// Locked *after* channel_state.
443443 pending_inbound_payments : Mutex < HashMap < PaymentHash , PendingInboundPayment > > ,
444444
445+ /// The session_priv bytes of outbound payments which are pending resolution.
446+ /// The authoritative state of these HTLCs resides either within Channels or ChannelMonitors
447+ /// (if the channel has been force-closed), however we track them here to prevent duplicative
448+ /// PaymentSent/PaymentFailed events. Specifically, in the case of a duplicative
449+ /// update_fulfill_htlc message after a reconnect, we may "claim" a payment twice.
450+ /// Additionally, because ChannelMonitors are often not re-serialized after connecting block(s)
451+ /// which may generate a claim event, we may receive similar duplicate claim/fail MonitorEvents
452+ /// after reloading from disk while replaying blocks against ChannelMonitors.
453+ ///
454+ /// Locked *after* channel_state.
455+ pending_outbound_payments : Mutex < HashSet < [ u8 ; 32 ] > > ,
456+
445457 our_network_key : SecretKey ,
446458 our_network_pubkey : PublicKey ,
447459
@@ -913,6 +925,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
913925 pending_msg_events : Vec :: new ( ) ,
914926 } ) ,
915927 pending_inbound_payments : Mutex :: new ( HashMap :: new ( ) ) ,
928+ pending_outbound_payments : Mutex :: new ( HashSet :: new ( ) ) ,
916929
917930 our_network_key : keys_manager. get_node_secret ( ) ,
918931 our_network_pubkey : PublicKey :: from_secret_key ( & secp_ctx, & keys_manager. get_node_secret ( ) ) ,
@@ -1467,7 +1480,8 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
14671480 pub ( crate ) fn send_payment_along_path ( & self , path : & Vec < RouteHop > , payment_hash : & PaymentHash , payment_secret : & Option < PaymentSecret > , total_value : u64 , cur_height : u32 ) -> Result < ( ) , APIError > {
14681481 log_trace ! ( self . logger, "Attempting to send payment for path with next hop {}" , path. first( ) . unwrap( ) . short_channel_id) ;
14691482 let prng_seed = self . keys_manager . get_secure_random_bytes ( ) ;
1470- let session_priv = SecretKey :: from_slice ( & self . keys_manager . get_secure_random_bytes ( ) [ ..] ) . expect ( "RNG is busted" ) ;
1483+ let session_priv_bytes = self . keys_manager . get_secure_random_bytes ( ) ;
1484+ let session_priv = SecretKey :: from_slice ( & session_priv_bytes[ ..] ) . expect ( "RNG is busted" ) ;
14711485
14721486 let onion_keys = onion_utils:: construct_onion_keys ( & self . secp_ctx , & path, & session_priv)
14731487 . map_err ( |_| APIError :: RouteError { err : "Pubkey along hop was maliciously selected" } ) ?;
@@ -1478,6 +1492,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
14781492 let onion_packet = onion_utils:: construct_onion_packet ( onion_payloads, onion_keys, prng_seed, payment_hash) ;
14791493
14801494 let _persistence_guard = PersistenceNotifierGuard :: notify_on_drop ( & self . total_consistency_lock , & self . persistence_notifier ) ;
1495+ assert ! ( self . pending_outbound_payments. lock( ) . unwrap( ) . insert( session_priv_bytes) ) ;
14811496
14821497 let err: Result < ( ) , _ > = loop {
14831498 let mut channel_lock = self . channel_state . lock ( ) . unwrap ( ) ;
@@ -2228,17 +2243,25 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
22282243 self . fail_htlc_backwards_internal ( channel_state,
22292244 htlc_src, & payment_hash, HTLCFailReason :: Reason { failure_code, data : onion_failure_data} ) ;
22302245 } ,
2231- HTLCSource :: OutboundRoute { .. } => {
2232- self . pending_events . lock ( ) . unwrap ( ) . push (
2233- events:: Event :: PaymentFailed {
2234- payment_hash,
2235- rejected_by_dest : false ,
2246+ HTLCSource :: OutboundRoute { session_priv, .. } => {
2247+ if {
2248+ let mut session_priv_bytes = [ 0 ; 32 ] ;
2249+ session_priv_bytes. copy_from_slice ( & session_priv[ ..] ) ;
2250+ self . pending_outbound_payments . lock ( ) . unwrap ( ) . remove ( & session_priv_bytes)
2251+ } {
2252+ self . pending_events . lock ( ) . unwrap ( ) . push (
2253+ events:: Event :: PaymentFailed {
2254+ payment_hash,
2255+ rejected_by_dest : false ,
22362256#[ cfg( test) ]
2237- error_code : None ,
2257+ error_code : None ,
22382258#[ cfg( test) ]
2239- error_data : None ,
2240- }
2241- )
2259+ error_data : None ,
2260+ }
2261+ )
2262+ } else {
2263+ log_trace ! ( self . logger, "Received duplicative fail for HTLC with payment_hash {}" , log_bytes!( payment_hash. 0 ) ) ;
2264+ }
22422265 } ,
22432266 } ;
22442267 }
@@ -2260,7 +2283,15 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
22602283 // from block_connected which may run during initialization prior to the chain_monitor
22612284 // being fully configured. See the docs for `ChannelManagerReadArgs` for more.
22622285 match source {
2263- HTLCSource :: OutboundRoute { ref path, .. } => {
2286+ HTLCSource :: OutboundRoute { ref path, session_priv, .. } => {
2287+ if {
2288+ let mut session_priv_bytes = [ 0 ; 32 ] ;
2289+ session_priv_bytes. copy_from_slice ( & session_priv[ ..] ) ;
2290+ !self . pending_outbound_payments . lock ( ) . unwrap ( ) . remove ( & session_priv_bytes)
2291+ } {
2292+ log_trace ! ( self . logger, "Received duplicative fail for HTLC with payment_hash {}" , log_bytes!( payment_hash. 0 ) ) ;
2293+ return ;
2294+ }
22642295 log_trace ! ( self . logger, "Failing outbound payment HTLC with payment_hash {}" , log_bytes!( payment_hash. 0 ) ) ;
22652296 mem:: drop ( channel_state_lock) ;
22662297 match & onion_error {
@@ -2489,12 +2520,20 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
24892520
24902521 fn claim_funds_internal ( & self , mut channel_state_lock : MutexGuard < ChannelHolder < Signer > > , source : HTLCSource , payment_preimage : PaymentPreimage ) {
24912522 match source {
2492- HTLCSource :: OutboundRoute { .. } => {
2523+ HTLCSource :: OutboundRoute { session_priv , .. } => {
24932524 mem:: drop ( channel_state_lock) ;
2494- let mut pending_events = self . pending_events . lock ( ) . unwrap ( ) ;
2495- pending_events. push ( events:: Event :: PaymentSent {
2496- payment_preimage
2497- } ) ;
2525+ if {
2526+ let mut session_priv_bytes = [ 0 ; 32 ] ;
2527+ session_priv_bytes. copy_from_slice ( & session_priv[ ..] ) ;
2528+ self . pending_outbound_payments . lock ( ) . unwrap ( ) . remove ( & session_priv_bytes)
2529+ } {
2530+ let mut pending_events = self . pending_events . lock ( ) . unwrap ( ) ;
2531+ pending_events. push ( events:: Event :: PaymentSent {
2532+ payment_preimage
2533+ } ) ;
2534+ } else {
2535+ log_trace ! ( self . logger, "Received duplicative fulfill for HTLC with payment_preimage {}" , log_bytes!( payment_preimage. 0 ) ) ;
2536+ }
24982537 } ,
24992538 HTLCSource :: PreviousHopData ( hop_data) => {
25002539 let prev_outpoint = hop_data. outpoint ;
@@ -4470,6 +4509,12 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> Writeable f
44704509 pending_payment. write ( writer) ?;
44714510 }
44724511
4512+ let pending_outbound_payments = self . pending_outbound_payments . lock ( ) . unwrap ( ) ;
4513+ ( pending_outbound_payments. len ( ) as u64 ) . write ( writer) ?;
4514+ for session_priv in pending_outbound_payments. iter ( ) {
4515+ session_priv. write ( writer) ?;
4516+ }
4517+
44734518 Ok ( ( ) )
44744519 }
44754520}
@@ -4709,6 +4754,14 @@ impl<'a, Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
47094754 }
47104755 }
47114756
4757+ let pending_outbound_payments_count: u64 = Readable :: read ( reader) ?;
4758+ let mut pending_outbound_payments: HashSet < [ u8 ; 32 ] > = HashSet :: with_capacity ( cmp:: min ( pending_outbound_payments_count as usize , MAX_ALLOC_SIZE /32 ) ) ;
4759+ for _ in 0 ..pending_outbound_payments_count {
4760+ if !pending_outbound_payments. insert ( Readable :: read ( reader) ?) {
4761+ return Err ( DecodeError :: InvalidValue ) ;
4762+ }
4763+ }
4764+
47124765 let mut secp_ctx = Secp256k1 :: new ( ) ;
47134766 secp_ctx. seeded_randomize ( & args. keys_manager . get_secure_random_bytes ( ) ) ;
47144767
@@ -4728,6 +4781,7 @@ impl<'a, Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
47284781 pending_msg_events : Vec :: new ( ) ,
47294782 } ) ,
47304783 pending_inbound_payments : Mutex :: new ( pending_inbound_payments) ,
4784+ pending_outbound_payments : Mutex :: new ( pending_outbound_payments) ,
47314785
47324786 our_network_key : args. keys_manager . get_node_secret ( ) ,
47334787 our_network_pubkey : PublicKey :: from_secret_key ( & secp_ctx, & args. keys_manager . get_node_secret ( ) ) ,
0 commit comments