@@ -24,6 +24,7 @@ use parking_lot::{Mutex, RwLock};
2424use crate :: Config ;
2525
2626type TxIndexHandle = Arc < Mutex < Box < dyn bitcoin_rs_index:: IndexerLike > > > ;
27+ type FilterIndexHandle = Arc < Box < dyn bitcoin_rs_filters:: FilterIndexLike > > ;
2728
2829/// Errors produced when applying a block to the node state.
2930#[ derive( Debug , thiserror:: Error ) ]
@@ -201,6 +202,33 @@ fn open_tx_index(config: &Config) -> Result<TxIndexHandle> {
201202 Ok ( Arc :: new ( Mutex :: new ( tx_index) ) )
202203}
203204
205+ fn open_filter_index ( config : & Config ) -> Result < FilterIndexHandle > {
206+ let filters_dir = config. data_dir . join ( "filters" ) ;
207+ std:: fs:: create_dir_all ( & filters_dir)
208+ . with_context ( || format ! ( "create filters_dir {}" , filters_dir. display( ) ) ) ?;
209+ let filter_index: Box < dyn bitcoin_rs_filters:: FilterIndexLike > =
210+ match config. storage_backend . as_str ( ) {
211+ #[ cfg( feature = "rocksdb" ) ]
212+ "rocksdb" => Box :: new ( bitcoin_rs_filters:: FilterIndex :: new (
213+ bitcoin_rs_storage:: RocksDbStore :: open ( & filters_dir) . map_err ( anyhow:: Error :: new) ?,
214+ ) ) ,
215+ #[ cfg( feature = "fjall" ) ]
216+ "fjall" => Box :: new ( bitcoin_rs_filters:: FilterIndex :: new (
217+ bitcoin_rs_storage:: FjallStore :: open ( & filters_dir) . map_err ( anyhow:: Error :: new) ?,
218+ ) ) ,
219+ #[ cfg( feature = "redb" ) ]
220+ "redb" => Box :: new ( bitcoin_rs_filters:: FilterIndex :: new (
221+ bitcoin_rs_storage:: RedbStore :: open ( & filters_dir) . map_err ( anyhow:: Error :: new) ?,
222+ ) ) ,
223+ #[ cfg( feature = "mdbx" ) ]
224+ "mdbx" => Box :: new ( bitcoin_rs_filters:: FilterIndex :: new (
225+ bitcoin_rs_storage:: MdbxStore :: open ( & filters_dir) . map_err ( anyhow:: Error :: new) ?,
226+ ) ) ,
227+ other => bail ! ( "unsupported storage backend for filter index: {other}" ) ,
228+ } ;
229+ Ok ( Arc :: new ( filter_index) )
230+ }
231+
204232/// Aggregate handle to a running node.
205233pub struct NodeState {
206234 config : Config ,
@@ -209,6 +237,7 @@ pub struct NodeState {
209237 utxo : Arc < UtxoSet > ,
210238 coin_stats : Arc < bitcoin_rs_coinstats:: CoinStatsListener > ,
211239 tx_index : TxIndexHandle ,
240+ filter_index : FilterIndexHandle ,
212241 mempool : Arc < RwLock < Mempool > > ,
213242 chain_tip : Arc < ArcSwapOption < TipSnapshot > > ,
214243 applied_tip : Arc < ArcSwapOption < TipSnapshot > > ,
@@ -241,6 +270,7 @@ impl NodeState {
241270 . with_context ( || format ! ( "create data_dir {}" , config. data_dir. display( ) ) ) ?;
242271 let storage = NodeStorage :: open ( & config) ?;
243272 let tx_index = open_tx_index ( & config) ?;
273+ let filter_index = open_filter_index ( & config) ?;
244274 let mut utxo_set = bitcoin_rs_utxo:: UtxoSet :: new ( ) ;
245275 let coin_stats_listener = bitcoin_rs_coinstats:: CoinStatsListener :: new (
246276 bitcoin_rs_coinstats:: CoinStats :: default ( ) ,
@@ -273,6 +303,7 @@ impl NodeState {
273303 utxo : Arc :: clone ( & utxo) ,
274304 coin_stats : Arc :: clone ( & coin_stats) ,
275305 tx_index : Arc :: clone ( & tx_index) ,
306+ filter_index : Arc :: clone ( & filter_index) ,
276307 mempool : Arc :: clone ( & mempool) ,
277308 blocks : Arc :: clone ( & blocks) ,
278309 transactions : Arc :: clone ( & transactions) ,
@@ -295,6 +326,7 @@ impl NodeState {
295326 utxo,
296327 coin_stats,
297328 tx_index,
329+ filter_index,
298330 mempool,
299331 chain_tip,
300332 applied_tip,
@@ -350,6 +382,12 @@ impl NodeState {
350382 Arc :: clone ( & self . tx_index )
351383 }
352384
385+ /// Returns the shared compact-filter index handle.
386+ #[ must_use]
387+ pub fn filter_index ( & self ) -> FilterIndexHandle {
388+ Arc :: clone ( & self . filter_index )
389+ }
390+
353391 /// Returns the shared mempool handle.
354392 #[ must_use]
355393 pub fn mempool ( & self ) -> Arc < RwLock < Mempool > > {
@@ -498,6 +536,7 @@ impl NodeState {
498536 utxo : Arc :: clone ( & self . utxo ) ,
499537 coin_stats : Arc :: clone ( & self . coin_stats ) ,
500538 tx_index : Arc :: clone ( & self . tx_index ) ,
539+ filter_index : Arc :: clone ( & self . filter_index ) ,
501540 mempool : Arc :: clone ( & self . mempool ) ,
502541 blocks : Arc :: clone ( & self . blocks ) ,
503542 transactions : Arc :: clone ( & self . transactions ) ,
@@ -598,6 +637,22 @@ mod tests {
598637 Ok ( ( ) )
599638 }
600639
640+ #[ test]
641+ fn open_constructs_filter_index ( ) -> anyhow:: Result < ( ) > {
642+ let dir = tempfile:: tempdir ( ) ?;
643+ let mut config = crate :: Config :: default_for_network ( crate :: Network :: Regtest ) ;
644+ config. data_dir = dir. path ( ) . join ( "node" ) ;
645+ config. p2p_listen . clear ( ) ;
646+ let state = NodeState :: open ( config) ?;
647+ let a = state. filter_index ( ) ;
648+ let b = state. filter_index ( ) ;
649+ assert ! (
650+ Arc :: ptr_eq( & a, & b) ,
651+ "filter_index handle stable across calls"
652+ ) ;
653+ Ok ( ( ) )
654+ }
655+
601656 #[ test]
602657 fn open_constructs_block_sync_orchestrator ( ) -> anyhow:: Result < ( ) > {
603658 let dir = tempfile:: tempdir ( ) ?;
0 commit comments