@@ -57,11 +57,10 @@ use lightning::sign::{
5757use lightning:: util:: async_poll:: MaybeSend ;
5858use lightning:: util:: logger:: Logger ;
5959use lightning:: util:: persist:: {
60- KVStore , KVStoreSync , KVStoreSyncWrapper , CHANNEL_MANAGER_PERSISTENCE_KEY ,
61- CHANNEL_MANAGER_PERSISTENCE_PRIMARY_NAMESPACE , CHANNEL_MANAGER_PERSISTENCE_SECONDARY_NAMESPACE ,
62- NETWORK_GRAPH_PERSISTENCE_KEY , NETWORK_GRAPH_PERSISTENCE_PRIMARY_NAMESPACE ,
63- NETWORK_GRAPH_PERSISTENCE_SECONDARY_NAMESPACE , SCORER_PERSISTENCE_KEY ,
64- SCORER_PERSISTENCE_PRIMARY_NAMESPACE , SCORER_PERSISTENCE_SECONDARY_NAMESPACE ,
60+ KVStore , KVStoreSync , KVStoreSyncWrapper , NETWORK_GRAPH_PERSISTENCE_KEY ,
61+ NETWORK_GRAPH_PERSISTENCE_PRIMARY_NAMESPACE , NETWORK_GRAPH_PERSISTENCE_SECONDARY_NAMESPACE ,
62+ SCORER_PERSISTENCE_KEY , SCORER_PERSISTENCE_PRIMARY_NAMESPACE ,
63+ SCORER_PERSISTENCE_SECONDARY_NAMESPACE ,
6564} ;
6665use lightning:: util:: sweep:: { OutputSweeper , OutputSweeperSync } ;
6766use lightning:: util:: wakers:: Future ;
@@ -1150,44 +1149,13 @@ where
11501149 None => { } ,
11511150 }
11521151
1153- let mut futures = Joiner :: new ( ) ;
1152+ // Type A is unused but needed for inference - we use the same boxed future type as other slots
1153+ let mut futures: Joiner < lightning:: io:: Error , core:: pin:: Pin < Box < dyn core:: future:: Future < Output = Result < ( ) , lightning:: io:: Error > > + Send + ' static > > , _ , _ , _ , _ > = Joiner :: new ( ) ;
11541154
1155- // Capture the number of pending monitor writes before persisting the channel manager.
1156- // We'll only flush this many writes after the manager is persisted, to avoid flushing
1157- // monitor updates that arrived after the manager state was captured.
1155+ // Capture the number of pending monitor writes and whether manager needs persistence.
1156+ // We'll flush monitors and manager together in a single batch after other tasks complete.
11581157 let pending_monitor_writes = chain_monitor. pending_write_count ( ) ;
1159-
1160- if channel_manager. get_cm ( ) . get_and_clear_needs_persistence ( ) {
1161- log_trace ! ( logger, "Persisting ChannelManager..." ) ;
1162-
1163- let fut = async {
1164- kv_store
1165- . write (
1166- CHANNEL_MANAGER_PERSISTENCE_PRIMARY_NAMESPACE ,
1167- CHANNEL_MANAGER_PERSISTENCE_SECONDARY_NAMESPACE ,
1168- CHANNEL_MANAGER_PERSISTENCE_KEY ,
1169- channel_manager. get_cm ( ) . encode ( ) ,
1170- )
1171- . await
1172- } ;
1173- // TODO: Once our MSRV is 1.68 we should be able to drop the Box
1174- let mut fut = Box :: pin ( fut) ;
1175-
1176- // Because persisting the ChannelManager is important to avoid accidental
1177- // force-closures, go ahead and poll the future once before we do slightly more
1178- // CPU-intensive tasks in the form of NetworkGraph pruning or scorer time-stepping
1179- // below. This will get it moving but won't block us for too long if the underlying
1180- // future is actually async.
1181- use core:: future:: Future ;
1182- let mut waker = dummy_waker ( ) ;
1183- let mut ctx = task:: Context :: from_waker ( & mut waker) ;
1184- match core:: pin:: Pin :: new ( & mut fut) . poll ( & mut ctx) {
1185- task:: Poll :: Ready ( res) => futures. set_a_res ( res) ,
1186- task:: Poll :: Pending => futures. set_a ( fut) ,
1187- }
1188-
1189- log_trace ! ( logger, "Done persisting ChannelManager." ) ;
1190- }
1158+ let needs_manager_persist = channel_manager. get_cm ( ) . get_and_clear_needs_persistence ( ) ;
11911159
11921160 // Note that we want to archive stale ChannelMonitors and run a network graph prune once
11931161 // not long after startup before falling back to their usual infrequent runs. This avoids
@@ -1354,11 +1322,13 @@ where
13541322 res?;
13551323 }
13561324
1357- // Flush the monitor writes that were pending before we persisted the channel manager.
1358- // Any writes that arrived after are left in the queue for the next iteration.
1359- if pending_monitor_writes > 0 {
1360- match chain_monitor. flush ( pending_monitor_writes) {
1361- Ok ( ( ) ) => log_trace ! ( logger, "Flushed {} monitor writes" , pending_monitor_writes) ,
1325+ // Flush monitors and manager together in a single batch.
1326+ // Any monitor writes that arrived after are left in the queue for the next iteration.
1327+ if pending_monitor_writes > 0 || needs_manager_persist {
1328+ log_trace ! ( logger, "Persisting ChannelManager and flushing {} monitor writes..." , pending_monitor_writes) ;
1329+ let manager_bytes = channel_manager. get_cm ( ) . encode ( ) ;
1330+ match chain_monitor. flush ( pending_monitor_writes, manager_bytes) {
1331+ Ok ( ( ) ) => log_trace ! ( logger, "Flushed ChannelManager and {} monitor writes" , pending_monitor_writes) ,
13621332 Err ( e) => log_error ! ( logger, "Failed to flush chain monitor: {}" , e) ,
13631333 }
13641334 }
@@ -1416,25 +1386,18 @@ where
14161386 }
14171387 log_trace ! ( logger, "Terminating background processor." ) ;
14181388
1419- // After we exit, ensure we persist the ChannelManager one final time - this avoids
1420- // some races where users quit while channel updates were in-flight, with
1421- // ChannelMonitor update(s) persisted without a corresponding ChannelManager update.
1422- kv_store
1423- . write (
1424- CHANNEL_MANAGER_PERSISTENCE_PRIMARY_NAMESPACE ,
1425- CHANNEL_MANAGER_PERSISTENCE_SECONDARY_NAMESPACE ,
1426- CHANNEL_MANAGER_PERSISTENCE_KEY ,
1427- channel_manager. get_cm ( ) . encode ( ) ,
1428- )
1429- . await ?;
1430-
1431- // Flush all pending monitor writes after final channel manager persistence.
1389+ // After we exit, ensure we persist the ChannelManager one final time along with any
1390+ // pending monitor writes - this avoids some races where users quit while channel updates
1391+ // were in-flight, with ChannelMonitor update(s) persisted without a corresponding
1392+ // ChannelManager update.
14321393 let pending_monitor_writes = chain_monitor. pending_write_count ( ) ;
1433- if pending_monitor_writes > 0 {
1434- match chain_monitor. flush ( pending_monitor_writes) {
1435- Ok ( ( ) ) => log_trace ! ( logger, "Flushed {} monitor writes" , pending_monitor_writes) ,
1436- Err ( e) => log_error ! ( logger, "Failed to flush chain monitor: {}" , e) ,
1437- }
1394+ let manager_bytes = channel_manager. get_cm ( ) . encode ( ) ;
1395+ match chain_monitor. flush ( pending_monitor_writes, manager_bytes) {
1396+ Ok ( ( ) ) => log_trace ! ( logger, "Final flush: ChannelManager and {} monitor writes" , pending_monitor_writes) ,
1397+ Err ( e) => {
1398+ log_error ! ( logger, "Failed final flush: {}" , e) ;
1399+ return Err ( e) ;
1400+ } ,
14381401 }
14391402
14401403 if let Some ( ref scorer) = scorer {
@@ -1746,25 +1709,17 @@ impl BackgroundProcessor {
17461709 channel_manager. get_cm ( ) . timer_tick_occurred ( ) ;
17471710 last_freshness_call = Instant :: now ( ) ;
17481711 }
1749- // Capture the number of pending monitor writes before persisting the channel manager .
1712+ // Capture the number of pending monitor writes and whether manager needs persistence .
17501713 let pending_monitor_writes = chain_monitor. pending_write_count ( ) ;
1714+ let needs_manager_persist = channel_manager. get_cm ( ) . get_and_clear_needs_persistence ( ) ;
17511715
1752- if channel_manager. get_cm ( ) . get_and_clear_needs_persistence ( ) {
1753- log_trace ! ( logger, "Persisting ChannelManager..." ) ;
1754- ( kv_store. write (
1755- CHANNEL_MANAGER_PERSISTENCE_PRIMARY_NAMESPACE ,
1756- CHANNEL_MANAGER_PERSISTENCE_SECONDARY_NAMESPACE ,
1757- CHANNEL_MANAGER_PERSISTENCE_KEY ,
1758- channel_manager. get_cm ( ) . encode ( ) ,
1759- ) ) ?;
1760- log_trace ! ( logger, "Done persisting ChannelManager." ) ;
1761- }
1762-
1763- // Flush the monitor writes that were pending before we persisted the channel manager.
1764- if pending_monitor_writes > 0 {
1765- match chain_monitor. flush ( pending_monitor_writes) {
1716+ // Flush monitors and manager together in a single batch.
1717+ if pending_monitor_writes > 0 || needs_manager_persist {
1718+ log_trace ! ( logger, "Persisting ChannelManager and flushing {} monitor writes..." , pending_monitor_writes) ;
1719+ let manager_bytes = channel_manager. get_cm ( ) . encode ( ) ;
1720+ match chain_monitor. flush ( pending_monitor_writes, manager_bytes) {
17661721 Ok ( ( ) ) => {
1767- log_trace ! ( logger, "Flushed {} monitor writes" , pending_monitor_writes)
1722+ log_trace ! ( logger, "Flushed ChannelManager and {} monitor writes" , pending_monitor_writes)
17681723 } ,
17691724 Err ( e) => log_error ! ( logger, "Failed to flush chain monitor: {}" , e) ,
17701725 }
@@ -1881,25 +1836,20 @@ impl BackgroundProcessor {
18811836 }
18821837 }
18831838
1884- // After we exit, ensure we persist the ChannelManager one final time - this avoids
1885- // some races where users quit while channel updates were in-flight, with
1886- // ChannelMonitor update(s) persisted without a corresponding ChannelManager update.
1887- kv_store. write (
1888- CHANNEL_MANAGER_PERSISTENCE_PRIMARY_NAMESPACE ,
1889- CHANNEL_MANAGER_PERSISTENCE_SECONDARY_NAMESPACE ,
1890- CHANNEL_MANAGER_PERSISTENCE_KEY ,
1891- channel_manager. get_cm ( ) . encode ( ) ,
1892- ) ?;
1893-
1894- // Flush all pending monitor writes after final channel manager persistence.
1839+ // After we exit, ensure we persist the ChannelManager one final time along with any
1840+ // pending monitor writes - this avoids some races where users quit while channel updates
1841+ // were in-flight, with ChannelMonitor update(s) persisted without a corresponding
1842+ // ChannelManager update.
18951843 let pending_monitor_writes = chain_monitor. pending_write_count ( ) ;
1896- if pending_monitor_writes > 0 {
1897- match chain_monitor. flush ( pending_monitor_writes) {
1898- Ok ( ( ) ) => {
1899- log_trace ! ( logger, "Flushed {} monitor writes" , pending_monitor_writes)
1900- } ,
1901- Err ( e) => log_error ! ( logger, "Failed to flush chain monitor: {}" , e) ,
1902- }
1844+ let manager_bytes = channel_manager. get_cm ( ) . encode ( ) ;
1845+ match chain_monitor. flush ( pending_monitor_writes, manager_bytes) {
1846+ Ok ( ( ) ) => {
1847+ log_trace ! ( logger, "Final flush: ChannelManager and {} monitor writes" , pending_monitor_writes)
1848+ } ,
1849+ Err ( e) => {
1850+ log_error ! ( logger, "Failed final flush: {}" , e) ;
1851+ return Err ( e. into ( ) ) ;
1852+ } ,
19031853 }
19041854
19051855 if let Some ( ref scorer) = scorer {
0 commit comments