@@ -4,8 +4,9 @@ use std::{collections::BTreeMap, pin::Pin, str::FromStr};
44
55use bdk_chain:: bitcoin;
66use bdk_chain:: miniscript;
7- use bdk_wallet:: { AsyncWalletPersister , ChangeSet , KeychainKind } ;
7+ use bdk_wallet:: { AsyncWalletPersister , ChangeSet , KeychainKind , locked_outpoints } ;
88use bitcoin:: Network ;
9+ use bitcoin:: OutPoint ;
910use miniscript:: descriptor:: { Descriptor , DescriptorPublicKey } ;
1011use sqlx:: Row ;
1112
@@ -31,6 +32,8 @@ impl Store {
3132 self . write_local_chain ( & changeset. local_chain ) . await ?;
3233 self . write_tx_graph ( & changeset. tx_graph ) . await ?;
3334 self . write_keychain_txout ( & changeset. indexer ) . await ?;
35+ self . write_locked_outpoints ( & changeset. locked_outpoints )
36+ . await ?;
3437
3538 Ok ( ( ) )
3639 }
@@ -76,6 +79,7 @@ impl Store {
7679 let tx_graph = self . read_tx_graph ( ) . await ?;
7780 let local_chain = self . read_local_chain ( ) . await ?;
7881 let indexer = self . read_keychain_txout ( ) . await ?;
82+ let locked_outpoints = self . read_locked_outpoints ( ) . await ?;
7983
8084 Ok ( ChangeSet {
8185 network,
@@ -84,6 +88,7 @@ impl Store {
8488 tx_graph,
8589 local_chain,
8690 indexer,
91+ locked_outpoints,
8792 } )
8893 }
8994
@@ -126,6 +131,49 @@ impl Store {
126131
127132 Ok ( descriptors)
128133 }
134+
135+ /// Write locked outpoints.
136+ pub async fn write_locked_outpoints (
137+ & self ,
138+ locked_outpoints : & locked_outpoints:: ChangeSet ,
139+ ) -> Result < ( ) , Error > {
140+ for ( & outpoint, & is_locked) in & locked_outpoints. outpoints {
141+ let OutPoint { txid, vout } = outpoint;
142+ if is_locked {
143+ sqlx:: query ( "INSERT OR IGNORE INTO locked_outpoint(txid, vout) VALUES($1, $2)" )
144+ . bind ( txid. to_string ( ) )
145+ . bind ( vout)
146+ . execute ( & self . pool )
147+ . await ?;
148+ } else {
149+ sqlx:: query ( "DELETE FROM locked_outpoint WHERE txid = $1 AND vout = $2" )
150+ . bind ( txid. to_string ( ) )
151+ . bind ( vout)
152+ . execute ( & self . pool )
153+ . await ?;
154+ }
155+ }
156+
157+ Ok ( ( ) )
158+ }
159+
160+ /// Read locked outpoints.
161+ pub async fn read_locked_outpoints ( & self ) -> Result < locked_outpoints:: ChangeSet , Error > {
162+ let mut changeset = locked_outpoints:: ChangeSet :: default ( ) ;
163+
164+ let rows = sqlx:: query ( "SELECT txid, vout FROM locked_outpoint" )
165+ . fetch_all ( & self . pool )
166+ . await ?;
167+ for row in rows {
168+ let txid: String = row. get ( "txid" ) ;
169+ let txid: bitcoin:: Txid = txid. parse ( ) ?;
170+ let vout: u32 = row. get ( "vout" ) ;
171+ let outpoint = OutPoint { txid, vout } ;
172+ changeset. outpoints . insert ( outpoint, true ) ;
173+ }
174+
175+ Ok ( changeset)
176+ }
129177}
130178
131179type FutureResult < ' a , T , E > = Pin < Box < dyn Future < Output = Result < T , E > > + ' a + Send > > ;
0 commit comments