@@ -10,7 +10,7 @@ use std::io::Write;
1010use std:: ops:: Deref ;
1111#[ cfg( unix) ]
1212use std:: os:: unix:: fs:: OpenOptionsExt ;
13- use std:: path:: Path ;
13+ use std:: path:: { Path , PathBuf } ;
1414use std:: sync:: Arc ;
1515
1616use bdk_chain:: indexer:: keychain_txout:: ChangeSet as BdkIndexerChangeSet ;
@@ -26,14 +26,16 @@ use lightning::routing::scoring::{
2626 ChannelLiquidities , ProbabilisticScorer , ProbabilisticScoringDecayParameters ,
2727} ;
2828use lightning:: util:: persist:: {
29- KVStore , KVStoreSync , KVSTORE_NAMESPACE_KEY_ALPHABET , KVSTORE_NAMESPACE_KEY_MAX_LEN ,
30- NETWORK_GRAPH_PERSISTENCE_KEY , NETWORK_GRAPH_PERSISTENCE_PRIMARY_NAMESPACE ,
31- NETWORK_GRAPH_PERSISTENCE_SECONDARY_NAMESPACE , OUTPUT_SWEEPER_PERSISTENCE_KEY ,
32- OUTPUT_SWEEPER_PERSISTENCE_PRIMARY_NAMESPACE , OUTPUT_SWEEPER_PERSISTENCE_SECONDARY_NAMESPACE ,
33- SCORER_PERSISTENCE_KEY , SCORER_PERSISTENCE_PRIMARY_NAMESPACE ,
34- SCORER_PERSISTENCE_SECONDARY_NAMESPACE ,
29+ migrate_kv_store_data , KVStore , KVStoreSync , KVSTORE_NAMESPACE_KEY_ALPHABET ,
30+ KVSTORE_NAMESPACE_KEY_MAX_LEN , NETWORK_GRAPH_PERSISTENCE_KEY ,
31+ NETWORK_GRAPH_PERSISTENCE_PRIMARY_NAMESPACE , NETWORK_GRAPH_PERSISTENCE_SECONDARY_NAMESPACE ,
32+ OUTPUT_SWEEPER_PERSISTENCE_KEY , OUTPUT_SWEEPER_PERSISTENCE_PRIMARY_NAMESPACE ,
33+ OUTPUT_SWEEPER_PERSISTENCE_SECONDARY_NAMESPACE , SCORER_PERSISTENCE_KEY ,
34+ SCORER_PERSISTENCE_PRIMARY_NAMESPACE , SCORER_PERSISTENCE_SECONDARY_NAMESPACE ,
3535} ;
3636use lightning:: util:: ser:: { Readable , ReadableArgs , Writeable } ;
37+ use lightning_persister:: fs_store:: v1:: FilesystemStore ;
38+ use lightning_persister:: fs_store:: v2:: FilesystemStoreV2 ;
3739use lightning_types:: string:: PrintableString ;
3840
3941use super :: * ;
@@ -48,7 +50,7 @@ use crate::payment::PendingPaymentDetails;
4850use crate :: peer_store:: PeerStore ;
4951use crate :: types:: { Broadcaster , DynStore , KeysManager , Sweeper } ;
5052use crate :: wallet:: ser:: { ChangeSetDeserWrapper , ChangeSetSerWrapper } ;
51- use crate :: { Error , EventQueue , NodeMetrics , PaymentDetails } ;
53+ use crate :: { BuildError , Error , EventQueue , NodeMetrics , PaymentDetails } ;
5254
5355pub const EXTERNAL_PATHFINDING_SCORES_CACHE_KEY : & str = "external_pathfinding_scores_cache" ;
5456
@@ -702,6 +704,42 @@ where
702704 Ok ( res)
703705}
704706
707+ /// Opens a [`FilesystemStoreV2`], automatically migrating from v1 format if necessary.
708+ ///
709+ /// If the directory contains v1 data (files at the top level), the data is migrated to v2 format
710+ /// in a temporary directory, the original is renamed to `fs_store_v1_backup`, and the migrated
711+ /// directory is moved into place.
712+ pub ( crate ) fn open_or_migrate_fs_store (
713+ storage_dir_path : PathBuf ,
714+ ) -> Result < FilesystemStoreV2 , BuildError > {
715+ match FilesystemStoreV2 :: new ( storage_dir_path. clone ( ) ) {
716+ Ok ( store) => Ok ( store) ,
717+ Err ( e) if e. kind ( ) == std:: io:: ErrorKind :: InvalidData => {
718+ // The directory contains v1 data, migrate to v2.
719+ let mut v1_store = FilesystemStore :: new ( storage_dir_path. clone ( ) ) ;
720+
721+ let mut v2_dir = storage_dir_path. clone ( ) ;
722+ v2_dir. set_file_name ( "fs_store_v2_migrating" ) ;
723+ fs:: create_dir_all ( v2_dir. clone ( ) ) . map_err ( |_| BuildError :: StoragePathAccessFailed ) ?;
724+ let mut v2_store = FilesystemStoreV2 :: new ( v2_dir. clone ( ) )
725+ . map_err ( |_| BuildError :: KVStoreSetupFailed ) ?;
726+
727+ migrate_kv_store_data ( & mut v1_store, & mut v2_store)
728+ . map_err ( |_| BuildError :: KVStoreSetupFailed ) ?;
729+
730+ // Swap directories: rename v1 out of the way, move v2 into place.
731+ let mut backup_dir = storage_dir_path. clone ( ) ;
732+ backup_dir. set_file_name ( "fs_store_v1_backup" ) ;
733+ fs:: rename ( & storage_dir_path, & backup_dir)
734+ . map_err ( |_| BuildError :: KVStoreSetupFailed ) ?;
735+ fs:: rename ( & v2_dir, & storage_dir_path) . map_err ( |_| BuildError :: KVStoreSetupFailed ) ?;
736+
737+ FilesystemStoreV2 :: new ( storage_dir_path) . map_err ( |_| BuildError :: KVStoreSetupFailed )
738+ } ,
739+ Err ( _) => Err ( BuildError :: KVStoreSetupFailed ) ,
740+ }
741+ }
742+
705743#[ cfg( test) ]
706744mod tests {
707745 use super :: read_or_generate_seed_file;
0 commit comments