@@ -446,6 +446,13 @@ where
446446/// If you have many stale updates stored (such as after a crash with pending lazy deletes), and
447447/// would like to get rid of them, consider using the
448448/// [`MonitorUpdatingPersister::cleanup_stale_updates`] function.
449+ ///
450+ /// # Size-based persistence optimization
451+ ///
452+ /// For small channel monitors (below `minimum_monitor_size_for_updates` bytes when serialized),
453+ /// this persister will always write the full monitor instead of individual updates. This avoids
454+ /// the overhead of managing update files and later compaction for tiny monitors that don't benefit
455+ /// from differential updates.
449456pub struct MonitorUpdatingPersister < K : Deref , L : Deref , ES : Deref , SP : Deref , BI : Deref , FE : Deref >
450457where
451458 K :: Target : KVStore ,
@@ -458,6 +465,7 @@ where
458465 kv_store : K ,
459466 logger : L ,
460467 maximum_pending_updates : u64 ,
468+ minimum_monitor_size_for_updates : usize ,
461469 entropy_source : ES ,
462470 signer_provider : SP ,
463471 broadcaster : BI ,
@@ -491,21 +499,45 @@ where
491499 /// less frequent "waves."
492500 /// - [`MonitorUpdatingPersister`] will potentially have more listing to do if you need to run
493501 /// [`MonitorUpdatingPersister::cleanup_stale_updates`].
502+ ///
503+ /// The `minimum_monitor_size_for_updates` parameter sets the minimum serialized size (in bytes)
504+ /// for a [`ChannelMonitor`] to use update-based persistence. Monitors smaller than this threshold
505+ /// will always be persisted in full, avoiding the overhead of managing update files for tiny
506+ /// monitors. A reasonable default is 4096 bytes (4 KiB). Set to 0 to always use update-based
507+ /// persistence regardless of size.
494508 pub fn new (
495- kv_store : K , logger : L , maximum_pending_updates : u64 , entropy_source : ES ,
509+ kv_store : K , logger : L , maximum_pending_updates : u64 , minimum_monitor_size_for_updates : usize , entropy_source : ES ,
496510 signer_provider : SP , broadcaster : BI , fee_estimator : FE ,
497511 ) -> Self {
498512 MonitorUpdatingPersister {
499513 kv_store,
500514 logger,
501515 maximum_pending_updates,
516+ minimum_monitor_size_for_updates,
502517 entropy_source,
503518 signer_provider,
504519 broadcaster,
505520 fee_estimator,
506521 }
507522 }
508523
524+ /// Constructs a new [`MonitorUpdatingPersister`] with a default minimum monitor size threshold.
525+ ///
526+ /// This is a convenience method that sets `minimum_monitor_size_for_updates` to 4096 bytes (4 KiB),
527+ /// which is a reasonable default for most use cases. Monitors smaller than this will be persisted
528+ /// in full rather than using update-based persistence.
529+ ///
530+ /// For other parameters, see [`MonitorUpdatingPersister::new`].
531+ pub fn new_with_default_threshold (
532+ kv_store : K , logger : L , maximum_pending_updates : u64 , entropy_source : ES ,
533+ signer_provider : SP , broadcaster : BI , fee_estimator : FE ,
534+ ) -> Self {
535+ Self :: new (
536+ kv_store, logger, maximum_pending_updates, 4096 , entropy_source,
537+ signer_provider, broadcaster, fee_estimator,
538+ )
539+ }
540+
509541 /// Reads all stored channel monitors, along with any stored updates for them.
510542 ///
511543 /// It is extremely important that your [`KVStore::read`] implementation uses the
@@ -752,7 +784,12 @@ where
752784 ) -> chain:: ChannelMonitorUpdateStatus {
753785 const LEGACY_CLOSED_CHANNEL_UPDATE_ID : u64 = u64:: MAX ;
754786 if let Some ( update) = update {
755- let persist_update = update. update_id != LEGACY_CLOSED_CHANNEL_UPDATE_ID
787+ // Check if monitor is too small for update-based persistence
788+ let monitor_size = monitor. serialized_length ( ) ;
789+ let use_full_persistence = monitor_size < self . minimum_monitor_size_for_updates ;
790+
791+ let persist_update = !use_full_persistence
792+ && update. update_id != LEGACY_CLOSED_CHANNEL_UPDATE_ID
756793 && update. update_id % self . maximum_pending_updates != 0 ;
757794 if persist_update {
758795 let monitor_key = monitor_name. to_string ( ) ;
@@ -1156,6 +1193,7 @@ mod tests {
11561193 kv_store : & TestStore :: new ( false ) ,
11571194 logger : & TestLogger :: new ( ) ,
11581195 maximum_pending_updates : persister_0_max_pending_updates,
1196+ minimum_monitor_size_for_updates : 0 ,
11591197 entropy_source : & chanmon_cfgs[ 0 ] . keys_manager ,
11601198 signer_provider : & chanmon_cfgs[ 0 ] . keys_manager ,
11611199 broadcaster : & chanmon_cfgs[ 0 ] . tx_broadcaster ,
@@ -1165,6 +1203,7 @@ mod tests {
11651203 kv_store : & TestStore :: new ( false ) ,
11661204 logger : & TestLogger :: new ( ) ,
11671205 maximum_pending_updates : persister_1_max_pending_updates,
1206+ minimum_monitor_size_for_updates : 0 ,
11681207 entropy_source : & chanmon_cfgs[ 1 ] . keys_manager ,
11691208 signer_provider : & chanmon_cfgs[ 1 ] . keys_manager ,
11701209 broadcaster : & chanmon_cfgs[ 1 ] . tx_broadcaster ,
@@ -1330,6 +1369,7 @@ mod tests {
13301369 kv_store : & TestStore :: new ( true ) ,
13311370 logger : & TestLogger :: new ( ) ,
13321371 maximum_pending_updates : 11 ,
1372+ minimum_monitor_size_for_updates : 0 ,
13331373 entropy_source : node_cfgs[ 0 ] . keys_manager ,
13341374 signer_provider : node_cfgs[ 0 ] . keys_manager ,
13351375 broadcaster : node_cfgs[ 0 ] . tx_broadcaster ,
@@ -1376,6 +1416,7 @@ mod tests {
13761416 kv_store : & TestStore :: new ( false ) ,
13771417 logger : & TestLogger :: new ( ) ,
13781418 maximum_pending_updates : test_max_pending_updates,
1419+ minimum_monitor_size_for_updates : 0 ,
13791420 entropy_source : & chanmon_cfgs[ 0 ] . keys_manager ,
13801421 signer_provider : & chanmon_cfgs[ 0 ] . keys_manager ,
13811422 broadcaster : & chanmon_cfgs[ 0 ] . tx_broadcaster ,
@@ -1385,6 +1426,7 @@ mod tests {
13851426 kv_store : & TestStore :: new ( false ) ,
13861427 logger : & TestLogger :: new ( ) ,
13871428 maximum_pending_updates : test_max_pending_updates,
1429+ minimum_monitor_size_for_updates : 0 ,
13881430 entropy_source : & chanmon_cfgs[ 1 ] . keys_manager ,
13891431 signer_provider : & chanmon_cfgs[ 1 ] . keys_manager ,
13901432 broadcaster : & chanmon_cfgs[ 1 ] . tx_broadcaster ,
0 commit comments