@@ -47,23 +47,35 @@ use core::ops::Deref;
4747use core:: sync:: atomic:: { AtomicUsize , Ordering } ;
4848use bitcoin:: secp256k1:: PublicKey ;
4949
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+ }
6168}
6269
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+
6375/// An opaque identifier describing a specific [`Persist`] method call.
6476#[ derive( Debug , Clone , Copy , Hash , PartialEq , Eq ) ]
6577pub struct MonitorUpdateId {
66- contents : UpdateOrigin ,
78+ pub ( crate ) contents : UpdateOrigin ,
6779}
6880
6981impl MonitorUpdateId {
@@ -155,8 +167,8 @@ pub trait Persist<ChannelSigner: WriteableEcdsaChannelSigner> {
155167 /// updated monitor itself to disk/backups. See the [`Persist`] trait documentation for more
156168 /// details.
157169 ///
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.
160172 /// Note that after the full [`ChannelMonitor`] is persisted any previous
161173 /// [`ChannelMonitorUpdate`]s which were persisted should be discarded - they can no longer be
162174 /// applied to the persisted [`ChannelMonitor`] as they were already applied.
@@ -756,14 +768,20 @@ where C::Target: chain::Filter,
756768 let monitor = & monitor_state. monitor ;
757769 log_trace ! ( self . logger, "Updating ChannelMonitor for channel {}" , log_funding_info!( monitor) ) ;
758770 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+
764772 let update_id = MonitorUpdateId :: from_monitor_update ( update) ;
765773 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+ } ;
767785 match persist_res {
768786 ChannelMonitorUpdateStatus :: InProgress => {
769787 pending_monitor_updates. push ( update_id) ;
0 commit comments