@@ -47,23 +47,35 @@ use core::ops::Deref;
47
47
use core:: sync:: atomic:: { AtomicUsize , Ordering } ;
48
48
use bitcoin:: secp256k1:: PublicKey ;
49
49
50
- #[ derive( Debug , Clone , Copy , Hash , PartialEq , Eq ) ]
51
- /// A specific update's ID stored in a `MonitorUpdateId`, separated out to make the contents
52
- /// entirely opaque.
53
- enum UpdateOrigin {
54
- /// An update that was generated by the `ChannelManager` (via our `chain::Watch`
55
- /// implementation). This corresponds to an actual [`ChannelMonitorUpdate::update_id`] field
56
- /// and [`ChannelMonitor::get_latest_update_id`].
57
- OffChain ( u64 ) ,
58
- /// An update that was generated during blockchain processing. The ID here is specific to the
59
- /// generating [`ChainMonitor`] and does *not* correspond to any on-disk IDs.
60
- ChainSync ( u64 ) ,
50
+ mod update_origin {
51
+ #[ derive( Debug , Clone , Copy , Hash , PartialEq , Eq ) ]
52
+ /// A specific update's ID stored in a `MonitorUpdateId`, separated out to make the contents
53
+ /// entirely opaque.
54
+ pub ( crate ) enum UpdateOrigin {
55
+ /// An update that was generated by the `ChannelManager` (via our [`crate::chain::Watch`]
56
+ /// implementation). This corresponds to an actual [ChannelMonitorUpdate::update_id] field
57
+ /// and [ChannelMonitor::get_latest_update_id].
58
+ ///
59
+ /// [ChannelMonitor::get_latest_update_id]: crate::chain::channelmonitor::ChannelMonitor::get_latest_update_id
60
+ /// [ChannelMonitorUpdate::update_id]: crate::chain::channelmonitor::ChannelMonitorUpdate::update_id
61
+ OffChain ( u64 ) ,
62
+ /// An update that was generated during blockchain processing. The ID here is specific to the
63
+ /// generating [ChannelMonitor] and does *not* correspond to any on-disk IDs.
64
+ ///
65
+ /// [ChannelMonitor]: crate::chain::channelmonitor::ChannelMonitor
66
+ ChainSync ( u64 ) ,
67
+ }
61
68
}
62
69
70
+ #[ cfg( any( feature = "_test_utils" , test) ) ]
71
+ pub ( crate ) use update_origin:: UpdateOrigin ;
72
+ #[ cfg( not( any( feature = "_test_utils" , test) ) ) ]
73
+ use update_origin:: UpdateOrigin ;
74
+
63
75
/// An opaque identifier describing a specific [`Persist`] method call.
64
76
#[ derive( Debug , Clone , Copy , Hash , PartialEq , Eq ) ]
65
77
pub struct MonitorUpdateId {
66
- contents : UpdateOrigin ,
78
+ pub ( crate ) contents : UpdateOrigin ,
67
79
}
68
80
69
81
impl MonitorUpdateId {
@@ -155,8 +167,8 @@ pub trait Persist<ChannelSigner: WriteableEcdsaChannelSigner> {
155
167
/// updated monitor itself to disk/backups. See the [`Persist`] trait documentation for more
156
168
/// details.
157
169
///
158
- /// During blockchain synchronization operations, this may be called with no
159
- /// [`ChannelMonitorUpdate`], in which case the full [`ChannelMonitor`] needs to be persisted.
170
+ /// During blockchain synchronization operations, and in some rare cases, this may be called with
171
+ /// no [`ChannelMonitorUpdate`], in which case the full [`ChannelMonitor`] needs to be persisted.
160
172
/// Note that after the full [`ChannelMonitor`] is persisted any previous
161
173
/// [`ChannelMonitorUpdate`]s which were persisted should be discarded - they can no longer be
162
174
/// applied to the persisted [`ChannelMonitor`] as they were already applied.
@@ -756,14 +768,20 @@ where C::Target: chain::Filter,
756
768
let monitor = & monitor_state. monitor ;
757
769
log_trace ! ( self . logger, "Updating ChannelMonitor for channel {}" , log_funding_info!( monitor) ) ;
758
770
let update_res = monitor. update_monitor ( update, & self . broadcaster , & * self . fee_estimator , & self . logger ) ;
759
- if update_res. is_err ( ) {
760
- log_error ! ( self . logger, "Failed to update ChannelMonitor for channel {}." , log_funding_info!( monitor) ) ;
761
- }
762
- // Even if updating the monitor returns an error, the monitor's state will
763
- // still be changed. So, persist the updated monitor despite the error.
771
+
764
772
let update_id = MonitorUpdateId :: from_monitor_update ( update) ;
765
773
let mut pending_monitor_updates = monitor_state. pending_monitor_updates . lock ( ) . unwrap ( ) ;
766
- let persist_res = self . persister . update_persisted_channel ( funding_txo, Some ( update) , monitor, update_id) ;
774
+ let persist_res = if update_res. is_err ( ) {
775
+ // Even if updating the monitor returns an error, the monitor's state will
776
+ // still be changed. Therefore, we should persist the updated monitor despite the error.
777
+ // We don't want to persist a `monitor_update` which results in a failure to apply later
778
+ // while reading `channel_monitor` with updates from storage. Instead, we should persist
779
+ // the entire `channel_monitor` here.
780
+ log_warn ! ( self . logger, "Failed to update ChannelMonitor for channel {}. Going ahead and persisting the entire ChannelMonitor" , log_funding_info!( monitor) ) ;
781
+ self . persister . update_persisted_channel ( funding_txo, None , monitor, update_id)
782
+ } else {
783
+ self . persister . update_persisted_channel ( funding_txo, Some ( update) , monitor, update_id)
784
+ } ;
767
785
match persist_res {
768
786
ChannelMonitorUpdateStatus :: InProgress => {
769
787
pending_monitor_updates. push ( update_id) ;
0 commit comments