@@ -43,7 +43,6 @@ use ldk_node::config::{
4343use ldk_node:: entropy:: { generate_entropy_mnemonic, NodeEntropy } ;
4444use ldk_node:: io:: sqlite_store:: SqliteStore ;
4545use ldk_node:: payment:: { PaymentDirection , PaymentKind , PaymentStatus } ;
46- #[ cfg( feature = "uniffi" ) ]
4746use ldk_node:: DynStoreWrapper ;
4847use ldk_node:: {
4948 Builder , ChannelShutdownState , CustomTlvRecord , Event , LightningBalance , Node , NodeError ,
@@ -414,10 +413,19 @@ pub(crate) enum TestChainSource<'a> {
414413 BitcoindRestSync ( & ' a BitcoinD ) ,
415414}
416415
417- #[ derive( Clone , Copy ) ]
416+ #[ cfg( feature = "uniffi" ) ]
417+ use ldk_node:: FfiDynStoreTrait ;
418+
419+ #[ cfg( feature = "uniffi" ) ]
420+ type TestDynStore = Arc < dyn FfiDynStoreTrait > ;
421+ #[ cfg( not( feature = "uniffi" ) ) ]
422+ type TestDynStore = TestSyncStore ;
423+
424+ #[ derive( Clone ) ]
418425pub ( crate ) enum TestStoreType {
419426 TestSyncStore ,
420427 Sqlite ,
428+ TierStore { primary : TestDynStore , ephemeral : Option < TestDynStore > } ,
421429}
422430
423431impl Default for TestStoreType {
@@ -434,6 +442,7 @@ pub(crate) struct TestConfig {
434442 pub node_entropy : NodeEntropy ,
435443 pub async_payments_role : Option < AsyncPaymentsRole > ,
436444 pub recovery_mode : bool ,
445+ pub backup_storage_dir_path : Option < String > ,
437446}
438447
439448impl Default for TestConfig {
@@ -446,13 +455,15 @@ impl Default for TestConfig {
446455 let node_entropy = NodeEntropy :: from_bip39_mnemonic ( mnemonic, None ) ;
447456 let async_payments_role = None ;
448457 let recovery_mode = false ;
458+ let backup_storage_dir_path = None ;
449459 TestConfig {
450460 node_config,
451461 log_writer,
452462 store_type,
453463 node_entropy,
454464 async_payments_role,
455465 recovery_mode,
466+ backup_storage_dir_path,
456467 }
457468 }
458469}
@@ -469,6 +480,35 @@ pub(crate) use setup_builder;
469480#[ cfg( any( cln_test, lnd_test, eclair_test) ) ]
470481pub ( crate ) mod scenarios;
471482
483+ // Helper function to create primary and ephemeral tier stores.
484+ pub ( crate ) fn create_primary_and_ephemeral_stores (
485+ base_path : PathBuf ,
486+ ) -> ( TestDynStore , TestDynStore ) {
487+ let primary = TestSyncStore :: new ( base_path. join ( "primary" ) ) ;
488+ let ephemeral = TestSyncStore :: new ( base_path. join ( "ephemeral" ) ) ;
489+
490+ #[ cfg( feature = "uniffi" ) ]
491+ {
492+ (
493+ Arc :: new ( DynStoreWrapper ( primary) ) as Arc < dyn FfiDynStoreTrait > ,
494+ Arc :: new ( DynStoreWrapper ( ephemeral) ) as Arc < dyn FfiDynStoreTrait > ,
495+ )
496+ }
497+ #[ cfg( not( feature = "uniffi" ) ) ]
498+ {
499+ ( primary, ephemeral)
500+ }
501+ }
502+
503+ pub ( crate ) fn open_test_backup_store ( path : PathBuf ) -> SqliteStore {
504+ SqliteStore :: new (
505+ path,
506+ Some ( ldk_node:: io:: sqlite_store:: SQLITE_BACKUP_DB_FILE_NAME . to_string ( ) ) ,
507+ Some ( ldk_node:: io:: sqlite_store:: KV_TABLE_NAME . to_string ( ) ) ,
508+ )
509+ . unwrap ( )
510+ }
511+
472512pub ( crate ) fn setup_two_nodes (
473513 chain_source : & TestChainSource , allow_0conf : bool , anchor_channels : bool ,
474514 anchors_trusted_no_reserve : bool ,
@@ -479,16 +519,15 @@ pub(crate) fn setup_two_nodes(
479519 anchor_channels,
480520 anchors_trusted_no_reserve,
481521 TestStoreType :: TestSyncStore ,
522+ TestStoreType :: TestSyncStore ,
482523 )
483524}
484525
485- pub ( crate ) fn setup_two_nodes_with_store (
526+ pub ( crate ) fn setup_two_nodes_with_config (
486527 chain_source : & TestChainSource , allow_0conf : bool , anchor_channels : bool ,
487- anchors_trusted_no_reserve : bool , store_type : TestStoreType ,
528+ anchors_trusted_no_reserve : bool , mut config_a : TestConfig , mut config_b : TestConfig ,
488529) -> ( TestNode , TestNode ) {
489530 println ! ( "== Node A ==" ) ;
490- let mut config_a = random_config ( anchor_channels) ;
491- config_a. store_type = store_type;
492531
493532 if cfg ! ( hrn_tests) {
494533 config_a. node_config . hrn_config =
@@ -498,8 +537,6 @@ pub(crate) fn setup_two_nodes_with_store(
498537 let node_a = setup_node ( chain_source, config_a) ;
499538
500539 println ! ( "\n == Node B ==" ) ;
501- let mut config_b = random_config ( anchor_channels) ;
502- config_b. store_type = store_type;
503540
504541 if cfg ! ( hrn_tests) {
505542 config_b. node_config . hrn_config = HumanReadableNamesConfig {
@@ -522,10 +559,31 @@ pub(crate) fn setup_two_nodes_with_store(
522559 . trusted_peers_no_reserve
523560 . push ( node_a. node_id ( ) ) ;
524561 }
562+
525563 let node_b = setup_node ( chain_source, config_b) ;
526564 ( node_a, node_b)
527565}
528566
567+ pub ( crate ) fn setup_two_nodes_with_store (
568+ chain_source : & TestChainSource , allow_0conf : bool , anchor_channels : bool ,
569+ anchors_trusted_no_reserve : bool , store_type_a : TestStoreType , store_type_b : TestStoreType ,
570+ ) -> ( TestNode , TestNode ) {
571+ let mut config_a = random_config ( anchor_channels) ;
572+ config_a. store_type = store_type_a;
573+
574+ let mut config_b = random_config ( anchor_channels) ;
575+ config_b. store_type = store_type_b;
576+
577+ setup_two_nodes_with_config (
578+ chain_source,
579+ allow_0conf,
580+ anchor_channels,
581+ anchors_trusted_no_reserve,
582+ config_a,
583+ config_b,
584+ )
585+ }
586+
529587pub ( crate ) fn setup_node ( chain_source : & TestChainSource , config : TestConfig ) -> TestNode {
530588 setup_node_with_builder ( chain_source, config, |_| { } )
531589}
@@ -600,15 +658,46 @@ where
600658
601659 let node = match config. store_type {
602660 TestStoreType :: TestSyncStore => {
603- #[ cfg( not( feature = "uniffi" ) ) ]
604661 let kv_store = TestSyncStore :: new ( config. node_config . storage_dir_path . into ( ) ) ;
662+
605663 #[ cfg( feature = "uniffi" ) ]
606- let kv_store = Arc :: new ( DynStoreWrapper ( TestSyncStore :: new (
607- config. node_config . storage_dir_path . into ( ) ,
608- ) ) ) ;
609- builder. build_with_store ( config. node_entropy . into ( ) , kv_store) . unwrap ( )
664+ {
665+ let kv_store: Arc < dyn FfiDynStoreTrait > = Arc :: new ( DynStoreWrapper ( kv_store) ) ;
666+ builder. build_with_store ( config. node_entropy . into ( ) , kv_store) . unwrap ( )
667+ }
668+
669+ #[ cfg( not( feature = "uniffi" ) ) ]
670+ {
671+ builder. build_with_store ( config. node_entropy . into ( ) , kv_store) . unwrap ( )
672+ }
610673 } ,
611674 TestStoreType :: Sqlite => builder. build ( config. node_entropy . into ( ) ) . unwrap ( ) ,
675+ TestStoreType :: TierStore { primary, ephemeral } => {
676+ if let Some ( backup_storage_dir_path) = config. backup_storage_dir_path {
677+ builder. set_backup_storage_dir_path ( backup_storage_dir_path) ;
678+ }
679+
680+ if let Some ( ephemeral) = ephemeral {
681+ #[ cfg( feature = "uniffi" ) ]
682+ {
683+ builder. set_ephemeral_store ( ephemeral) ;
684+ }
685+ #[ cfg( not( feature = "uniffi" ) ) ]
686+ {
687+ use ldk_node:: DynStore ;
688+ let store: Arc < DynStore > = Arc :: new ( DynStoreWrapper ( ephemeral) ) ;
689+ builder. set_ephemeral_store ( store) ;
690+ }
691+ }
692+ #[ cfg( feature = "uniffi" ) ]
693+ {
694+ builder. build_with_store ( config. node_entropy . into ( ) , primary) . unwrap ( )
695+ }
696+ #[ cfg( not( feature = "uniffi" ) ) ]
697+ {
698+ builder. build_with_store ( config. node_entropy , primary) . unwrap ( )
699+ }
700+ } ,
612701 } ;
613702
614703 node. start ( ) . unwrap ( ) ;
@@ -1931,3 +2020,36 @@ impl TestSyncStoreInner {
19312020 self . do_list ( primary_namespace, secondary_namespace)
19322021 }
19332022}
2023+
2024+ pub fn test_kv_read (
2025+ store : & TestDynStore , primary_ns : & str , secondary_ns : & str , key : & str ,
2026+ ) -> Result < Vec < u8 > , bitcoin:: io:: Error > {
2027+ #[ cfg( feature = "uniffi" ) ]
2028+ {
2029+ ldk_node:: FfiDynStoreTrait :: read (
2030+ & * * store,
2031+ primary_ns. to_string ( ) ,
2032+ secondary_ns. to_string ( ) ,
2033+ key. to_string ( ) ,
2034+ )
2035+ . map_err ( Into :: into)
2036+ }
2037+ #[ cfg( not( feature = "uniffi" ) ) ]
2038+ {
2039+ KVStoreSync :: read ( store, primary_ns, secondary_ns, key)
2040+ }
2041+ }
2042+
2043+ pub fn test_kv_list (
2044+ store : & TestDynStore , primary_ns : & str , secondary_ns : & str ,
2045+ ) -> Result < Vec < String > , bitcoin:: io:: Error > {
2046+ #[ cfg( feature = "uniffi" ) ]
2047+ {
2048+ ldk_node:: FfiDynStoreTrait :: list ( & * * store, primary_ns. to_string ( ) , secondary_ns. to_string ( ) )
2049+ . map_err ( Into :: into)
2050+ }
2051+ #[ cfg( not( feature = "uniffi" ) ) ]
2052+ {
2053+ KVStoreSync :: list ( store, primary_ns, secondary_ns)
2054+ }
2055+ }
0 commit comments