12
12
#include < addrman.h>
13
13
#include < amount.h>
14
14
#include < banman.h>
15
+ #include < blockfilter.h>
15
16
#include < chain.h>
16
17
#include < chainparams.h>
17
18
#include < checkpoints.h>
20
21
#include < fs.h>
21
22
#include < httpserver.h>
22
23
#include < httprpc.h>
24
+ #include < index/blockfilterindex.h>
23
25
#include < interfaces/chain.h>
24
26
#include < index/txindex.h>
25
27
#include < key.h>
@@ -189,6 +191,7 @@ void Interrupt()
189
191
if (g_txindex) {
190
192
g_txindex->Interrupt ();
191
193
}
194
+ ForEachBlockFilterIndex ([](BlockFilterIndex& index) { index.Interrupt (); });
192
195
}
193
196
194
197
void Shutdown (InitInterfaces& interfaces)
@@ -220,6 +223,7 @@ void Shutdown(InitInterfaces& interfaces)
220
223
if (peerLogic) UnregisterValidationInterface (peerLogic.get ());
221
224
if (g_connman) g_connman->Stop ();
222
225
if (g_txindex) g_txindex->Stop ();
226
+ ForEachBlockFilterIndex ([](BlockFilterIndex& index) { index.Stop (); });
223
227
224
228
StopTorControl ();
225
229
@@ -234,6 +238,7 @@ void Shutdown(InitInterfaces& interfaces)
234
238
g_connman.reset ();
235
239
g_banman.reset ();
236
240
g_txindex.reset ();
241
+ DestroyAllBlockFilterIndexes ();
237
242
238
243
if (g_is_mempool_loaded && gArgs .GetArg (" -persistmempool" , DEFAULT_PERSIST_MEMPOOL)) {
239
244
DumpMempool ();
@@ -404,6 +409,10 @@ void SetupServerArgs()
404
409
hidden_args.emplace_back (" -sysperms" );
405
410
#endif
406
411
gArgs .AddArg (" -txindex" , strprintf (" Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)" , DEFAULT_TXINDEX), false , OptionsCategory::OPTIONS);
412
+ gArgs .AddArg (" -blockfilterindex=<type>" ,
413
+ strprintf (" Maintain an index of compact filters by block (default: %s, values: %s)." , DEFAULT_BLOCKFILTERINDEX, ListBlockFilterTypes ()) +
414
+ " If <type> is not supplied or if <type> = 1, indexes for all known types are enabled." ,
415
+ false , OptionsCategory::OPTIONS);
407
416
408
417
gArgs .AddArg (" -addnode=<ip>" , " Add a node to connect to and attempt to keep the connection open (see the `addnode` RPC command help for more info). This option can be specified multiple times to add multiple nodes." , false , OptionsCategory::CONNECTION);
409
418
gArgs .AddArg (" -banscore=<n>" , strprintf (" Threshold for disconnecting misbehaving peers (default: %u)" , DEFAULT_BANSCORE_THRESHOLD), false , OptionsCategory::CONNECTION);
@@ -886,6 +895,7 @@ int nUserMaxConnections;
886
895
int nFD;
887
896
ServiceFlags nLocalServices = ServiceFlags(NODE_NETWORK | NODE_NETWORK_LIMITED);
888
897
int64_t peer_connect_timeout;
898
+ std::vector<BlockFilterType> g_enabled_filter_types;
889
899
890
900
} // namespace
891
901
@@ -954,10 +964,29 @@ bool AppInitParameterInteraction()
954
964
return InitError (strprintf (_ (" Specified blocks directory \" %s\" does not exist." ), gArgs .GetArg (" -blocksdir" , " " ).c_str ()));
955
965
}
956
966
967
+ // parse and validate enabled filter types
968
+ std::string blockfilterindex_value = gArgs .GetArg (" -blockfilterindex" , DEFAULT_BLOCKFILTERINDEX);
969
+ if (blockfilterindex_value == " " || blockfilterindex_value == " 1" ) {
970
+ g_enabled_filter_types = AllBlockFilterTypes ();
971
+ } else if (blockfilterindex_value != " 0" ) {
972
+ const std::vector<std::string> names = gArgs .GetArgs (" -blockfilterindex" );
973
+ g_enabled_filter_types.reserve (names.size ());
974
+ for (const auto & name : names) {
975
+ BlockFilterType filter_type;
976
+ if (!BlockFilterTypeByName (name, filter_type)) {
977
+ return InitError (strprintf (_ (" Unknown -blockfilterindex value %s." ), name));
978
+ }
979
+ g_enabled_filter_types.push_back (filter_type);
980
+ }
981
+ }
982
+
957
983
// if using block pruning, then disallow txindex
958
984
if (gArgs .GetArg (" -prune" , 0 )) {
959
985
if (gArgs .GetBoolArg (" -txindex" , DEFAULT_TXINDEX))
960
986
return InitError (_ (" Prune mode is incompatible with -txindex." ));
987
+ if (!g_enabled_filter_types.empty ()) {
988
+ return InitError (_ (" Prune mode is incompatible with -blockfilterindex." ));
989
+ }
961
990
}
962
991
963
992
// -bind and -whitebind can't be set when not listening
@@ -1448,6 +1477,13 @@ bool AppInitMain(InitInterfaces& interfaces)
1448
1477
nTotalCache -= nBlockTreeDBCache;
1449
1478
int64_t nTxIndexCache = std::min (nTotalCache / 8 , gArgs .GetBoolArg (" -txindex" , DEFAULT_TXINDEX) ? nMaxTxIndexCache << 20 : 0 );
1450
1479
nTotalCache -= nTxIndexCache;
1480
+ int64_t filter_index_cache = 0 ;
1481
+ if (!g_enabled_filter_types.empty ()) {
1482
+ size_t n_indexes = g_enabled_filter_types.size ();
1483
+ int64_t max_cache = std::min (nTotalCache / 8 , max_filter_index_cache << 20 );
1484
+ filter_index_cache = max_cache / n_indexes;
1485
+ nTotalCache -= filter_index_cache * n_indexes;
1486
+ }
1451
1487
int64_t nCoinDBCache = std::min (nTotalCache / 2 , (nTotalCache / 4 ) + (1 << 23 )); // use 25%-50% of the remainder for disk cache
1452
1488
nCoinDBCache = std::min (nCoinDBCache, nMaxCoinsDBCache << 20 ); // cap total coins db cache
1453
1489
nTotalCache -= nCoinDBCache;
@@ -1458,6 +1494,10 @@ bool AppInitMain(InitInterfaces& interfaces)
1458
1494
if (gArgs .GetBoolArg (" -txindex" , DEFAULT_TXINDEX)) {
1459
1495
LogPrintf (" * Using %.1f MiB for transaction index database\n " , nTxIndexCache * (1.0 / 1024 / 1024 ));
1460
1496
}
1497
+ for (BlockFilterType filter_type : g_enabled_filter_types) {
1498
+ LogPrintf (" * Using %.1f MiB for %s block filter index database\n " ,
1499
+ filter_index_cache * (1.0 / 1024 / 1024 ), BlockFilterTypeName (filter_type));
1500
+ }
1461
1501
LogPrintf (" * Using %.1f MiB for chain state database\n " , nCoinDBCache * (1.0 / 1024 / 1024 ));
1462
1502
LogPrintf (" * Using %.1f MiB for in-memory UTXO set (plus up to %.1f MiB of unused mempool space)\n " , nCoinCacheUsage * (1.0 / 1024 / 1024 ), nMempoolSizeMax * (1.0 / 1024 / 1024 ));
1463
1503
@@ -1645,6 +1685,11 @@ bool AppInitMain(InitInterfaces& interfaces)
1645
1685
g_txindex->Start ();
1646
1686
}
1647
1687
1688
+ for (const auto & filter_type : g_enabled_filter_types) {
1689
+ InitBlockFilterIndex (filter_type, filter_index_cache, false , fReindex );
1690
+ GetBlockFilterIndex (filter_type)->Start ();
1691
+ }
1692
+
1648
1693
// ********************************************************* Step 9: load wallet
1649
1694
for (const auto & client : interfaces.chain_clients ) {
1650
1695
if (!client->load ()) {
0 commit comments