@@ -710,20 +710,30 @@ macro_rules! maybe_break_monitor_err {
710
710
}
711
711
712
712
macro_rules! handle_chan_restoration_locked {
713
- ( $self: expr , $channel_lock: expr, $channel_state: expr, $channel_entry: expr,
714
- $raa: expr, $commitment_update: expr, $order: expr,
713
+ ( $self: ident , $channel_lock: expr, $channel_state: expr, $channel_entry: expr,
714
+ $raa: expr, $commitment_update: expr, $order: expr, $chanmon_update : expr ,
715
715
$pending_forwards: expr, $broadcast_safe: expr, $funding_locked: expr) => { {
716
716
let mut htlc_forwards = None ;
717
717
let mut funding_broadcast_safe = None ;
718
718
let counterparty_node_id = $channel_entry. get( ) . get_counterparty_node_id( ) ;
719
+ let channel_id = $channel_entry. get( ) . channel_id( ) ;
719
720
720
- {
721
+ let res = loop {
721
722
if !$pending_forwards. is_empty( ) {
722
723
htlc_forwards = Some ( ( $channel_entry. get( ) . get_short_channel_id( ) . expect( "We can't have pending forwards before funding confirmation" ) ,
723
724
$channel_entry. get( ) . get_funding_txo( ) . unwrap( ) , $pending_forwards) ) ;
724
725
}
725
726
726
727
macro_rules! handle_cs { ( ) => {
728
+ if let Some ( monitor_update) = $chanmon_update {
729
+ assert!( $order == RAACommitmentOrder :: RevokeAndACKFirst ) ;
730
+ assert!( !$broadcast_safe) ;
731
+ assert!( $funding_locked. is_none( ) ) ;
732
+ assert!( $commitment_update. is_some( ) ) ;
733
+ if let Err ( e) = $self. chain_monitor. update_channel( $channel_entry. get( ) . get_funding_txo( ) . unwrap( ) , monitor_update) {
734
+ break handle_monitor_err!( $self, e, $channel_state, $channel_entry, RAACommitmentOrder :: CommitmentFirst , false , true ) ;
735
+ }
736
+ }
727
737
if let Some ( update) = $commitment_update {
728
738
$channel_state. pending_msg_events. push( events:: MessageSendEvent :: UpdateHTLCs {
729
739
node_id: counterparty_node_id,
@@ -766,21 +776,26 @@ macro_rules! handle_chan_restoration_locked {
766
776
msg: announcement_sigs,
767
777
} ) ;
768
778
}
769
- $channel_state. short_to_id. insert( $channel_entry. get( ) . get_short_channel_id( ) . unwrap( ) , $channel_entry . get ( ) . channel_id( ) ) ;
779
+ $channel_state. short_to_id. insert( $channel_entry. get( ) . get_short_channel_id( ) . unwrap( ) , channel_id) ;
770
780
}
771
- }
772
- ( htlc_forwards, funding_broadcast_safe)
781
+ break Ok ( ( ) ) ;
782
+ } ;
783
+
784
+ ( htlc_forwards, funding_broadcast_safe, res, channel_id, counterparty_node_id)
773
785
} }
774
786
}
775
787
776
788
macro_rules! post_handle_chan_restoration {
777
- ( $self: expr, $locked_res: expr, $pending_failures: expr) => { {
778
- let ( htlc_forwards, funding_broadcast_safe) = $locked_res;
789
+ ( $self: ident, $locked_res: expr, $pending_failures: expr, $forwarding_failures: expr) => { {
790
+ let ( htlc_forwards, funding_broadcast_safe, res, channel_id, counterparty_node_id) = $locked_res;
791
+
792
+ let _ = handle_error!( $self, res, counterparty_node_id) ;
779
793
780
794
if let Some ( ev) = funding_broadcast_safe {
781
795
$self. pending_events. lock( ) . unwrap( ) . push( ev) ;
782
796
}
783
797
798
+ $self. fail_holding_cell_htlcs( $forwarding_failures, channel_id) ;
784
799
for failure in $pending_failures. drain( ..) {
785
800
$self. fail_htlc_backwards_internal( $self. channel_state. lock( ) . unwrap( ) , failure. 0 , & failure. 1 , failure. 2 ) ;
786
801
}
@@ -2280,6 +2295,10 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
2280
2295
/// ChannelMonitorUpdateErr::TemporaryFailures is fine. The highest_applied_update_id field
2281
2296
/// exists largely only to prevent races between this and concurrent update_monitor calls.
2282
2297
///
2298
+ /// XXX: Update to note re-entrancy - this is really terrible - the reentrancy only happens in
2299
+ /// a really rare case making it incredibly likely users will miss it and never hit it in
2300
+ /// testing.
2301
+ ///
2283
2302
/// Thus, the anticipated use is, at a high level:
2284
2303
/// 1) You register a chain::Watch with this ChannelManager,
2285
2304
/// 2) it stores each update to disk, and begins updating any remote (eg watchtower) copies of
@@ -2291,7 +2310,7 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
2291
2310
pub fn channel_monitor_updated ( & self , funding_txo : & OutPoint , highest_applied_update_id : u64 ) {
2292
2311
let _consistency_lock = self . total_consistency_lock . read ( ) . unwrap ( ) ;
2293
2312
2294
- let ( mut pending_failures, chan_restoration_res) = {
2313
+ let ( mut pending_failures, forwarding_failds , chan_restoration_res) = {
2295
2314
let mut channel_lock = self . channel_state . lock ( ) . unwrap ( ) ;
2296
2315
let channel_state = & mut * channel_lock;
2297
2316
let mut channel = match channel_state. by_id . entry ( funding_txo. to_channel_id ( ) ) {
@@ -2302,10 +2321,10 @@ impl<ChanSigner: ChannelKeys, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref>
2302
2321
return ;
2303
2322
}
2304
2323
2305
- let ( raa, commitment_update, order, pending_forwards, pending_failures, needs_broadcast_safe, funding_locked) = channel. get_mut ( ) . monitor_updating_restored ( & self . logger ) ;
2306
- ( pending_failures, handle_chan_restoration_locked ! ( self , channel_lock, channel_state, channel, raa, commitment_update, order, pending_forwards, needs_broadcast_safe, funding_locked) )
2324
+ let ( raa, commitment_update, order, chanmon_update , pending_forwards, pending_failures, forwarding_failds , needs_broadcast_safe, funding_locked) = channel. get_mut ( ) . monitor_updating_restored ( & self . logger ) ;
2325
+ ( pending_failures, forwarding_failds , handle_chan_restoration_locked ! ( self , channel_lock, channel_state, channel, raa, commitment_update, order, chanmon_update , pending_forwards, needs_broadcast_safe, funding_locked) )
2307
2326
} ;
2308
- post_handle_chan_restoration ! ( self , chan_restoration_res, pending_failures) ;
2327
+ post_handle_chan_restoration ! ( self , chan_restoration_res, pending_failures, forwarding_failds ) ;
2309
2328
}
2310
2329
2311
2330
fn internal_open_channel ( & self , counterparty_node_id : & PublicKey , their_features : InitFeatures , msg : & msgs:: OpenChannel ) -> Result < ( ) , MsgHandleErrInternal > {
0 commit comments