@@ -12,9 +12,11 @@ use crate::logger::{log_error, FilesystemLogger};
12
12
use crate :: peer_store:: PeerStore ;
13
13
use crate :: sweep:: DeprecatedSpendableOutputInfo ;
14
14
use crate :: types:: { Broadcaster , ChainSource , DynStore , FeeEstimator , KeysManager , Sweeper } ;
15
+ use crate :: wallet:: ser:: { ChangeSetDeserWrapper , ChangeSetSerWrapper } ;
15
16
use crate :: { Error , EventQueue , PaymentDetails } ;
16
17
17
18
use lightning:: io:: Cursor ;
19
+ use lightning:: ln:: msgs:: DecodeError ;
18
20
use lightning:: routing:: gossip:: NetworkGraph ;
19
21
use lightning:: routing:: scoring:: { ProbabilisticScorer , ProbabilisticScoringDecayParameters } ;
20
22
use lightning:: util:: logger:: Logger ;
@@ -27,9 +29,17 @@ use lightning::util::persist::{
27
29
} ;
28
30
use lightning:: util:: ser:: { Readable , ReadableArgs , Writeable } ;
29
31
use lightning:: util:: string:: PrintableString ;
32
+ use lightning:: util:: sweep:: { OutputSpendStatus , OutputSweeper } ;
33
+
34
+ use bdk_chain:: indexer:: keychain_txout:: ChangeSet as BdkIndexerChangeSet ;
35
+ use bdk_chain:: local_chain:: ChangeSet as BdkLocalChainChangeSet ;
36
+ use bdk_chain:: miniscript:: { Descriptor , DescriptorPublicKey } ;
37
+ use bdk_chain:: tx_graph:: ChangeSet as BdkTxGraphChangeSet ;
38
+ use bdk_chain:: ConfirmationBlockTime ;
39
+ use bdk_wallet:: ChangeSet as BdkWalletChangeSet ;
30
40
31
41
use bip39:: Mnemonic ;
32
- use lightning :: util :: sweep :: { OutputSpendStatus , OutputSweeper } ;
42
+ use bitcoin :: Network ;
33
43
use rand:: { thread_rng, RngCore } ;
34
44
35
45
use std:: fs;
@@ -519,6 +529,164 @@ pub(crate) fn check_namespace_key_validity(
519
529
Ok ( ( ) )
520
530
}
521
531
532
+ macro_rules! impl_read_write_change_set_type {
533
+ ( $read_name: ident, $write_name: ident, $change_set_type: ty, $primary_namespace: expr, $secondary_namespace: expr, $key: expr ) => {
534
+ pub ( crate ) fn $read_name<L : Deref >(
535
+ kv_store: Arc <DynStore >, logger: L ,
536
+ ) -> Result <Option <$change_set_type>, std:: io:: Error >
537
+ where
538
+ L :: Target : Logger ,
539
+ {
540
+ let bytes = match kv_store. read( $primary_namespace, $secondary_namespace, $key) {
541
+ Ok ( bytes) => bytes,
542
+ Err ( e) => {
543
+ if e. kind( ) == lightning:: io:: ErrorKind :: NotFound {
544
+ return Ok ( None ) ;
545
+ } else {
546
+ log_error!(
547
+ logger,
548
+ "Reading data from key {}/{}/{} failed due to: {}" ,
549
+ $primary_namespace,
550
+ $secondary_namespace,
551
+ $key,
552
+ e
553
+ ) ;
554
+ return Err ( e. into( ) ) ;
555
+ }
556
+ } ,
557
+ } ;
558
+
559
+ let mut reader = Cursor :: new( bytes) ;
560
+ let res: Result <ChangeSetDeserWrapper <$change_set_type>, DecodeError > =
561
+ Readable :: read( & mut reader) ;
562
+ match res {
563
+ Ok ( res) => Ok ( Some ( res. 0 ) ) ,
564
+ Err ( e) => {
565
+ log_error!( logger, "Failed to deserialize BDK wallet field: {}" , e) ;
566
+ Err ( std:: io:: Error :: new(
567
+ std:: io:: ErrorKind :: InvalidData ,
568
+ "Failed to deserialize BDK wallet field" ,
569
+ ) )
570
+ } ,
571
+ }
572
+ }
573
+
574
+ pub ( crate ) fn $write_name<L : Deref >(
575
+ value: & $change_set_type, kv_store: Arc <DynStore >, logger: L ,
576
+ ) -> Result <( ) , std:: io:: Error >
577
+ where
578
+ L :: Target : Logger ,
579
+ {
580
+ let data = ChangeSetSerWrapper ( value) . encode( ) ;
581
+ kv_store. write( $primary_namespace, $secondary_namespace, $key, & data) . map_err( |e| {
582
+ log_error!(
583
+ logger,
584
+ "Writing data to key {}/{}/{} failed due to: {}" ,
585
+ $primary_namespace,
586
+ $secondary_namespace,
587
+ $key,
588
+ e
589
+ ) ;
590
+ e. into( )
591
+ } )
592
+ }
593
+ } ;
594
+ }
595
+
596
+ impl_read_write_change_set_type ! (
597
+ read_bdk_wallet_descriptor,
598
+ write_bdk_wallet_descriptor,
599
+ Descriptor <DescriptorPublicKey >,
600
+ BDK_WALLET_DESCRIPTOR_PRIMARY_NAMESPACE ,
601
+ BDK_WALLET_DESCRIPTOR_SECONDARY_NAMESPACE ,
602
+ BDK_WALLET_DESCRIPTOR_KEY
603
+ ) ;
604
+
605
+ impl_read_write_change_set_type ! (
606
+ read_bdk_wallet_change_descriptor,
607
+ write_bdk_wallet_change_descriptor,
608
+ Descriptor <DescriptorPublicKey >,
609
+ BDK_WALLET_CHANGE_DESCRIPTOR_PRIMARY_NAMESPACE ,
610
+ BDK_WALLET_CHANGE_DESCRIPTOR_SECONDARY_NAMESPACE ,
611
+ BDK_WALLET_CHANGE_DESCRIPTOR_KEY
612
+ ) ;
613
+
614
+ impl_read_write_change_set_type ! (
615
+ read_bdk_wallet_network,
616
+ write_bdk_wallet_network,
617
+ Network ,
618
+ BDK_WALLET_NETWORK_PRIMARY_NAMESPACE ,
619
+ BDK_WALLET_NETWORK_SECONDARY_NAMESPACE ,
620
+ BDK_WALLET_NETWORK_KEY
621
+ ) ;
622
+
623
+ impl_read_write_change_set_type ! (
624
+ read_bdk_wallet_local_chain,
625
+ write_bdk_wallet_local_chain,
626
+ BdkLocalChainChangeSet ,
627
+ BDK_WALLET_LOCAL_CHAIN_PRIMARY_NAMESPACE ,
628
+ BDK_WALLET_LOCAL_CHAIN_SECONDARY_NAMESPACE ,
629
+ BDK_WALLET_LOCAL_CHAIN_KEY
630
+ ) ;
631
+
632
+ impl_read_write_change_set_type ! (
633
+ read_bdk_wallet_tx_graph,
634
+ write_bdk_wallet_tx_graph,
635
+ BdkTxGraphChangeSet <ConfirmationBlockTime >,
636
+ BDK_WALLET_TX_GRAPH_PRIMARY_NAMESPACE ,
637
+ BDK_WALLET_TX_GRAPH_SECONDARY_NAMESPACE ,
638
+ BDK_WALLET_TX_GRAPH_KEY
639
+ ) ;
640
+
641
+ impl_read_write_change_set_type ! (
642
+ read_bdk_wallet_indexer,
643
+ write_bdk_wallet_indexer,
644
+ BdkIndexerChangeSet ,
645
+ BDK_WALLET_INDEXER_PRIMARY_NAMESPACE ,
646
+ BDK_WALLET_INDEXER_SECONDARY_NAMESPACE ,
647
+ BDK_WALLET_INDEXER_KEY
648
+ ) ;
649
+
650
+ // Reads the full BdkWalletChangeSet or returns default fields
651
+ pub ( crate ) fn read_bdk_wallet_change_set (
652
+ kv_store : Arc < DynStore > , logger : Arc < FilesystemLogger > ,
653
+ ) -> Result < Option < BdkWalletChangeSet > , std:: io:: Error > {
654
+ let mut change_set = BdkWalletChangeSet :: default ( ) ;
655
+
656
+ // We require a descriptor and return `None` to signal creation of a new wallet otherwise.
657
+ if let Some ( descriptor) =
658
+ read_bdk_wallet_descriptor ( Arc :: clone ( & kv_store) , Arc :: clone ( & logger) ) ?
659
+ {
660
+ change_set. descriptor = Some ( descriptor) ;
661
+ } else {
662
+ return Ok ( None ) ;
663
+ }
664
+
665
+ // We require a change_descriptor and return `None` to signal creation of a new wallet otherwise.
666
+ if let Some ( change_descriptor) =
667
+ read_bdk_wallet_change_descriptor ( Arc :: clone ( & kv_store) , Arc :: clone ( & logger) ) ?
668
+ {
669
+ change_set. change_descriptor = Some ( change_descriptor) ;
670
+ } else {
671
+ return Ok ( None ) ;
672
+ }
673
+
674
+ // We require a network and return `None` to signal creation of a new wallet otherwise.
675
+ if let Some ( network) = read_bdk_wallet_network ( Arc :: clone ( & kv_store) , Arc :: clone ( & logger) ) ? {
676
+ change_set. network = Some ( network) ;
677
+ } else {
678
+ return Ok ( None ) ;
679
+ }
680
+
681
+ read_bdk_wallet_local_chain ( Arc :: clone ( & kv_store) , Arc :: clone ( & logger) ) ?
682
+ . map ( |local_chain| change_set. local_chain = local_chain) ;
683
+ read_bdk_wallet_tx_graph ( Arc :: clone ( & kv_store) , Arc :: clone ( & logger) ) ?
684
+ . map ( |tx_graph| change_set. tx_graph = tx_graph) ;
685
+ read_bdk_wallet_indexer ( Arc :: clone ( & kv_store) , Arc :: clone ( & logger) ) ?
686
+ . map ( |indexer| change_set. indexer = indexer) ;
687
+ Ok ( Some ( change_set) )
688
+ }
689
+
522
690
#[ cfg( test) ]
523
691
mod tests {
524
692
use super :: * ;
0 commit comments