Skip to content

Commit

Permalink
Added the new MaturityHeightIndex DB needed by the getblockexpanded R…
Browse files Browse the repository at this point in the history
…PC call (#208)

* First backport of address indexing from Zend

Todo:
 - txindex.py not working (neither on Zend repo)

* Fixed conflict for DB index tags

* Added some furhter code from zen addressIndexing branch; Added handling for spentIndex in disconnect block stage

* Updated structures for LevelDB indexes

Updated the value structures for the following indexes:
 - TxIndex
 - AddressIndex
 - AddressUnspentIndex

* Changed interface to mempool address indexing functions for accepting CTransactionBase

* Improved CTxIndexValue constructor

* WIP: first versionof code implementation for mempool handling of address indexing data: non tested yet

* Changes on getaddressbalance to don't include by default immature BTs, and added new field immature in the response

* Changes on getaddressutxo to don't include by default immature BTs and added new field maurityHeight for each utxo

* Moved some code for better organization

* WIP: Address Index: Added logic for modifying output entries for a cerificate superseeded by a new top quality accepted in mempool

* Added python test for getaddress* RPC commands

* Minor modifications for certificate handling flow; removed unused code

* Improved code related to address indexing

* Added getaddressmempool check inside sc_cert_addressindex.py test

* Added update of low quality certs in address index data when the top quality cert is evicted from mempool

* Changed value of outStatus for input records in address index mempool map (from -1 to 0xff); used GetType() func instead of if/else blocks

* Used GetType()/GetAddressHash instead of if/else blocks also in addSpentIndex

* Updated the addressindexing Python test with additional scenarios

* Added bwt related dat to json result of getaddressutxos rpc cmd

* Moved instantiation of height and best block hash at the implementation start using lock in getaddressutxos cmd

* Added rpc command getcertmaturityinfo; it relies on txindex option to be on

* Implemented explorer indexes update for certificates in the ConnectBlock

* Moved to_satoshis() func into util.py

* Fixed the serialization of "maturityHeight" for the SpentIndex

* Updated sc_cert_addressindex to test the DisconnectTip

* Implemented indexes update for certificates in the DiconnectBlock

* Implemented indexes update when sidechain ceased state changes

* Added sc_cert_addrmempool.py test expecially aimed at getaddressmempool rpc command

* Added vcsw_ccin field inside TxToJSONExpanded

* Minor fixes for indexes management

- Removed some unused input parameters
- Added a flag check inside the DisconnectBlock function

* Added new index update test cases for ceased sidechains

* Fix for py test using createrawcertificate

* Improved AddressIndex update procedure

Improved the code so that AddressIndex entries are removed and updated in one single batch operation (instead of two different ones).

* Improved code reuse for serialization of VARINT with sign

* Fixed issues after rebasing onto testnet_staging

* Added a conditional compilation flag for AddressIndex related features

* Fixed a flag for optionally run address indexing Python tests

* Added extended information to certificate JSON representation

* Added some code under address indexing conditional compilation

* Fixed the regression tests

* Improved management of the -addressindex parameter

* Removed some debug prints from the build configuration file

* Fix Python test failing after extending getrawtransaction JSON fields

* Fixed a Python test failing after requiring txIndex for addressIndex

* Renamed JSON field 'valueSat' as 'valueZat'

* Put additional code under conditional compilation for Address Indexing

* Removed unused references to wallet-utility

* Improved comment about address-indexing flag

* Added comments to #endif for ENABLE_ADDRESS_INDEXING macro

* Removed nonexistent header from Makefile

* Added some LevelDB collection IDs into the Address Indexing section

* Improved management of flags "dbmaxopenfiles" and "dbcompression"

- Renamed "dbmaxopenfiles" as "blocktreedbmaxopenfiles"
- Renamed "dbcompression" as "blocktreedbcompression"
- Put both flags under #ifdef
- Fixed the default options for the Block Tree LevelDB

* Moved blockOnchainActive() function under #ifdef

* Moved some Address Indexing related code under #ifdef

* Fixed the implementation of blockOnchainActive() function

* Added to ConnectBlock a flag to skip writing Address Indexing DB

* Restored some code to the previous location

* Added management for TxIndex update during Connect/Disconnect of block

* Substituted an assert with an if, since we must update the txindex entry only if it is there

* Added the state INVALID to the output of the rpc cmd getcertmaturityinfo

* Fixed txindex.py test and added it to regression script

* Added checks to update TxIndex DB only if the related flag is enabled

* Added some test for getcertmaturityinfo; to be continued

* Included search in the mempool for the RPC command getcertmaturityinfo

* Fixed sc_cert_addrmempool.py test

* Added a test case for a certificate removed from the blockchain

- Added the new test case to sc_cert_addrmempool.py
- Added a new RPC command to clear the mempool of a node (REGTEST only)

* Added the cleanup of other data structures in the mempool clean() method

* Enabled clearmempool rpc command also for testnet

* Changed the status string of a mempool cert in the output of rpc cmd getcertmaturityinfo

* Added a flag to enable/disable write of TxIndex when checking blocks

* Moved a variable initialization into the correct scope

* Added verifychain rpc call to py tests

* Added  maturityHeightIndex DB

* Fix after rebase

* Added new flag to enable the maturityHeightIndex DB

* Added a comment to the CMaturityHeightValue

* Fix after code review

* Restore previous serialization of MaturityHeightIndex keys

* Removed the txindex dependency from the maturityHeight DB

* New error handling inside ReadMaturityHeightIndex

* Removed print from ReadMaturityHeightIndex

* Minor fix

* Re-added txindex and a couple of other fixes

Co-authored-by: Paolo Tagliaferri <paolotagliaferri@horizenlabs.io>
Co-authored-by: Alberto Sala <alberto.sala@nttdata.com>
  • Loading branch information
3 people authored Oct 28, 2021
1 parent 5241b9e commit 67759c0
Show file tree
Hide file tree
Showing 14 changed files with 744 additions and 11 deletions.
1 change: 1 addition & 0 deletions qa/pull-tester/rpc-tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ testScripts=(
'sc_cert_getblocktemplate.py'
'sc_cert_bt_immature_balances.py'
'txindex.py'
'getblockexpanded.py'
);
testScriptsExt=(
'getblocktemplate_longpoll.py'
Expand Down
259 changes: 259 additions & 0 deletions qa/rpc-tests/getblockexpanded.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,259 @@
#!/usr/bin/env python2
# Copyright (c) 2014 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.

from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import assert_equal, initialize_chain_clean, \
start_node, connect_nodes_bi, assert_true, assert_false, get_epoch_data, \
swap_bytes
from test_framework.mc_test.mc_test import CertTestUtils, generate_random_field_element_hex
from test_framework.authproxy import JSONRPCException

from decimal import Decimal

EPOCH_LENGTH = 100
CERT_FEE = Decimal("0.000123")
SC_FEE = Decimal("0.000345")
FT_SC_FEE = Decimal('0')
MBTR_SC_FEE = Decimal('0')
MINIMAL_SC_HEIGHT = 420

class getblockexpanded(BitcoinTestFramework):
FEE = 0.0001
FT_SC_FEE = Decimal('0')
MBTR_SC_FEE = Decimal('0')
CERT_FEE = Decimal('0.00015')

def setup_chain(self):
print("Initializing test directory "+self.options.tmpdir)
initialize_chain_clean(self.options.tmpdir, 2)

def setup_network(self, split=False):
self.nodes=[]
self.nodes += [start_node(0, self.options.tmpdir,extra_args=['-txindex=1','-maturityheightindex=1'])]
self.nodes += [start_node(1, self.options.tmpdir)]

connect_nodes_bi(self.nodes,0,1)

self.is_network_split=False
self.sync_all()

def run_test(self):

#amounts
creation_amount = Decimal("50")
bwt_amount = Decimal("5")
tAddr1 = self.nodes[1].getnewaddress()
node1Addr = self.nodes[1].validateaddress(tAddr1)['address']
self.nodes[0].generate(MINIMAL_SC_HEIGHT)
self.sync_all()

########### Create the sidechain ##################
print("########### Create the sidechain ##################")

mcTest = CertTestUtils(self.options.tmpdir, self.options.srcdir)
vk = mcTest.generate_params("sc1")
constant = generate_random_field_element_hex()

ret = self.nodes[0].dep_sc_create(EPOCH_LENGTH, "dada", creation_amount, vk, "", constant)
creating_tx = ret['txid']
scid = ret['scid']
scid_swapped = str(swap_bytes(scid))
self.sync_all()

decoded_tx = self.nodes[0].getrawtransaction(creating_tx, 1)
assert_equal(scid, decoded_tx['vsc_ccout'][0]['scid'])

sc_creation_block_hash = self.nodes[0].generate(1)[0]
sc_creation_block = self.nodes[0].getblock(sc_creation_block_hash)
self.sync_all()

#Advance for 1 Epoch
self.nodes[0].generate(EPOCH_LENGTH)
self.sync_all()

########### Mine Certificate 1 with quality = 5 ##################
print("########### Mine Certificate 1 with quality = 5 ##################")

epoch_number, epoch_cum_tree_hash = get_epoch_data(scid, self.nodes[0], EPOCH_LENGTH)
quality = 5
proof = mcTest.create_test_proof(
"sc1", scid_swapped, epoch_number, quality, MBTR_SC_FEE, FT_SC_FEE, epoch_cum_tree_hash, constant, [node1Addr], [bwt_amount])

amount_cert_1 = [{"address": node1Addr, "amount": bwt_amount}]

self.nodes[0].sc_send_certificate(scid, epoch_number, quality,
epoch_cum_tree_hash, proof, amount_cert_1, FT_SC_FEE, MBTR_SC_FEE, CERT_FEE)
self.sync_all()
maturityHeight = sc_creation_block["height"]+(EPOCH_LENGTH*2)+EPOCH_LENGTH*0.2 - 1

#Add to mempool Certificate 2 with quality = 7
print("########### Add to mempool Certificate 2 with quality = 7 ##################")
quality = 7
bwt_amount2 = Decimal("7")
proof = mcTest.create_test_proof(
"sc1", scid_swapped, epoch_number, quality, MBTR_SC_FEE, FT_SC_FEE, epoch_cum_tree_hash, constant, [node1Addr], [bwt_amount2])

amount_cert_2 = [{"address": node1Addr, "amount": bwt_amount2}]

self.nodes[0].sc_send_certificate(scid, epoch_number, quality,
epoch_cum_tree_hash, proof, amount_cert_2, FT_SC_FEE, MBTR_SC_FEE, CERT_FEE)
self.sync_all()

#Mine a block
self.nodes[0].generate(1)
self.sync_all()

#Mine a block with a new Certificate 3 with quality = 8
print("########### Mine a block with a new Certificate 3 with quality = 8 ##################")
quality = 8
bwt_amount3 = Decimal("7")
proof = mcTest.create_test_proof(
"sc1", scid_swapped, epoch_number, quality, MBTR_SC_FEE, FT_SC_FEE, epoch_cum_tree_hash, constant, [node1Addr], [bwt_amount3])

amount_cert_3 = [{"address": node1Addr, "amount": bwt_amount3}]

cert3 = self.nodes[0].sc_send_certificate(scid, epoch_number, quality,
epoch_cum_tree_hash, proof, amount_cert_3, FT_SC_FEE, MBTR_SC_FEE, CERT_FEE)
self.sync_all()
cert3_block = self.nodes[0].generate(1)[0]
self.sync_all()

#Advance of 1 epoch
print("########### Advance of 1 epoch ##################")
self.nodes[0].generate(116)
self.sync_all()

epoch_number, epoch_cum_tree_hash = get_epoch_data(scid, self.nodes[0], EPOCH_LENGTH)
quality = 9
bwt_amount4 = Decimal("9")
proof = mcTest.create_test_proof(
"sc1", scid_swapped, epoch_number, quality, MBTR_SC_FEE, FT_SC_FEE, epoch_cum_tree_hash, constant, [node1Addr], [bwt_amount4])

amount_cert_4 = [{"address": node1Addr, "amount": bwt_amount4}]

self.nodes[0].sc_send_certificate(scid, epoch_number, quality,
epoch_cum_tree_hash, proof, amount_cert_4, FT_SC_FEE, MBTR_SC_FEE, CERT_FEE)

cert4_block = self.nodes[0].generate(1)[0]
self.sync_all()

#Enter in the next epoch
new_epoch_block = self.nodes[0].generate(1)[0]
self.sync_all()

rpcCertBlock = self.nodes[0].getblock(cert3_block, 2)
cert_3_json = {}
for cert in rpcCertBlock['cert']:
if (cert['txid'] == cert3):
cert_3_json = cert
assert_true(cert_3_json != {})
tipHeight = self.nodes[0].getblockcount()

#Test that we require -maturityheightindex=1 to run the getblockexpanded
try:
self.nodes[1].getblockexpanded("640")
assert(False)
except JSONRPCException as e:
errorString = e.error['message']
print(errorString)
assert("maturityHeightIndex option not set: can not retrieve info" in errorString)

#Test that we see the certificate 3 but non the certificate 2 and 1
for i in range (1,tipHeight+1):
rpcDataByHeight = self.nodes[0].getblockexpanded(str(i))
rpcDataByHeightVerbosity = self.nodes[0].getblockexpanded(str(i), 2)
rpcDataByHash = self.nodes[0].getblockexpanded(rpcDataByHeight['hash'])
rpcDataByHashVerbosity = self.nodes[0].getblockexpanded(rpcDataByHeight['hash'],2)

if (rpcDataByHash['height'] >= MINIMAL_SC_HEIGHT):
assert_true('matureCertificate' in rpcDataByHash)
assert_true('matureCertificate' in rpcDataByHeight)
assert_true('matureCertificate' in rpcDataByHashVerbosity)
assert_true('matureCertificate' in rpcDataByHeightVerbosity)
if (rpcDataByHash['height'] == int(maturityHeight)):
assert_equal(len(rpcDataByHash['matureCertificate']), 1)
assert_equal(len(rpcDataByHeight['matureCertificate']), 1)
assert_equal(rpcDataByHash['matureCertificate'][0], cert3)
assert_equal(rpcDataByHeight['matureCertificate'][0], cert3)
assert_equal(len(rpcDataByHashVerbosity['matureCertificate']), 1)
assert_equal(len(rpcDataByHeightVerbosity['matureCertificate']), 1)
assert_equal(rpcDataByHashVerbosity['matureCertificate'][0], cert_3_json)
assert_equal(rpcDataByHeightVerbosity['matureCertificate'][0], cert_3_json)
else:
assert_equal(len(rpcDataByHash['matureCertificate']), 0)
assert_equal(len(rpcDataByHeight['matureCertificate']), 0)
assert_equal(len(rpcDataByHashVerbosity['matureCertificate']), 0)
assert_equal(len(rpcDataByHeightVerbosity['matureCertificate']), 0)
else:
assert_false('matureCertificate' in rpcDataByHash)
assert_false('matureCertificate' in rpcDataByHeight)
assert_false('matureCertificate' in rpcDataByHashVerbosity)
assert_false('matureCertificate' in rpcDataByHeightVerbosity)

self.nodes[0].invalidateblock(new_epoch_block)
self.nodes[0].invalidateblock(cert4_block)
self.nodes[1].invalidateblock(new_epoch_block)
self.nodes[1].invalidateblock(cert4_block)
assert_equal(self.nodes[0].getblockcount(), 639)
assert_equal(self.nodes[1].getblockcount(), 639)

self.nodes[0].clearmempool()
self.nodes[1].clearmempool()
assert_equal(len(self.nodes[0].getrawmempool()),0)
assert_equal(len(self.nodes[1].getrawmempool()),0)
self.sync_all()

fake_block = self.nodes[0].generate(1)[0]
self.sync_all()

rpcDataByHeight = self.nodes[0].getblockexpanded("640")
rpcDataByHeightVerbosity = self.nodes[0].getblockexpanded("640", 2)
rpcDataByHash = self.nodes[0].getblockexpanded(rpcDataByHeight['hash'])
rpcDataByHashVerbosity = self.nodes[0].getblockexpanded(rpcDataByHeight['hash'],2)
assert_equal(len(rpcDataByHash['matureCertificate']), 0)
assert_equal(len(rpcDataByHeight['matureCertificate']), 0)
assert_equal(len(rpcDataByHashVerbosity['matureCertificate']), 0)
assert_equal(len(rpcDataByHeightVerbosity['matureCertificate']), 0)

self.nodes[0].invalidateblock(fake_block)
self.nodes[1].invalidateblock(fake_block)

self.nodes[0].sc_send_certificate(scid, epoch_number, quality,
epoch_cum_tree_hash, proof, amount_cert_4, FT_SC_FEE, MBTR_SC_FEE, CERT_FEE)
self.nodes[0].generate(2)
self.sync_all()

rpcDataByHeight = self.nodes[0].getblockexpanded("640")
rpcDataByHeightVerbosity = self.nodes[0].getblockexpanded("640", 2)
rpcDataByHash = self.nodes[0].getblockexpanded(rpcDataByHeight['hash'])
rpcDataByHashVerbosity = self.nodes[0].getblockexpanded(rpcDataByHeight['hash'],2)
assert_equal(len(rpcDataByHash['matureCertificate']), 1)
assert_equal(len(rpcDataByHeight['matureCertificate']), 1)
assert_equal(len(rpcDataByHashVerbosity['matureCertificate']), 1)
assert_equal(len(rpcDataByHeightVerbosity['matureCertificate']), 1)
assert_equal(rpcDataByHashVerbosity['matureCertificate'][0], cert_3_json)
assert_equal(rpcDataByHeightVerbosity['matureCertificate'][0], cert_3_json)
assert_equal(self.nodes[0].getscinfo(scid)['items'][0]['state'], "ALIVE")

#Let the sidechain cease
self.nodes[0].generate(130)
self.sync_all()

assert_equal(self.nodes[0].getscinfo(scid)['items'][0]['state'], "CEASED")
tipHeightCeased = self.nodes[0].getblockcount()

for i in range (tipHeight, tipHeightCeased+1):
rpcDataByHeight = self.nodes[0].getblockexpanded(str(i))
rpcDataByHeightVerbosity = self.nodes[0].getblockexpanded(str(i), 2)
rpcDataByHash = self.nodes[0].getblockexpanded(rpcDataByHeight['hash'])
rpcDataByHashVerbosity = self.nodes[0].getblockexpanded(rpcDataByHeight['hash'],2)

assert_equal(len(rpcDataByHash['matureCertificate']), 0)
assert_equal(len(rpcDataByHeight['matureCertificate']), 0)
assert_equal(len(rpcDataByHashVerbosity['matureCertificate']), 0)
assert_equal(len(rpcDataByHeightVerbosity['matureCertificate']), 0)

if __name__ == '__main__':
getblockexpanded().main()
64 changes: 64 additions & 0 deletions src/coins.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <sc/proofverifier.h>

#include "txdb.h"
#include "maturityheightindex.h"

std::string CCoins::ToString() const
{
Expand Down Expand Up @@ -1110,6 +1111,18 @@ void CCoinsViewCache::RevertTxIndexSidechainEvents(int height, CBlockUndo& block
return;
}

void CCoinsViewCache::HandleMaturityHeightIndexSidechainEvents(int height, CBlockTreeDB* pblocktree,
std::vector<std::pair<CMaturityHeightKey,CMaturityHeightValue>>& maturityHeightIndex)
{
return;
}

void CCoinsViewCache::RevertMaturityHeightIndexSidechainEvents(int height, CBlockUndo& blockUndo, CBlockTreeDB* pblocktree,
std::vector<std::pair<CMaturityHeightKey,CMaturityHeightValue>>& maturityHeightIndex)
{
return;
}

#ifdef ENABLE_ADDRESS_INDEXING
void CCoinsViewCache::HandleIndexesSidechainEvents(int height, CBlockTreeDB* pblocktree,
std::vector<std::pair<CAddressIndexKey, CAddressIndexValue>>& addressIndex,
Expand Down Expand Up @@ -1644,6 +1657,57 @@ void CCoinsViewCache::RevertTxIndexSidechainEvents(int height, CBlockUndo& block
}
}

void CCoinsViewCache::HandleMaturityHeightIndexSidechainEvents(int height, CBlockTreeDB* pblocktree,
std::vector<std::pair<CMaturityHeightKey,CMaturityHeightValue>>& maturityHeightIndex)
{
if (!HaveSidechainEvents(height))
return;

CSidechainEvents scEvents;
GetSidechainEvents(height, scEvents);

//Handle Ceasing Sidechain
for (const uint256& ceasingScId : scEvents.ceasingScs)
{
CSidechain sidechain;
assert(GetSidechain(ceasingScId, sidechain));

if (sidechain.lastTopQualityCertReferencedEpoch == CScCertificate::EPOCH_NULL) {
assert(sidechain.lastTopQualityCertHash.IsNull());
continue;
}

//Remove the certificate from the MaturityHeight DB
CMaturityHeightKey maturityHeightKey = CMaturityHeightKey(height, sidechain.lastTopQualityCertHash);
maturityHeightIndex.push_back(std::make_pair(maturityHeightKey, CMaturityHeightValue()));
}
}

void CCoinsViewCache::RevertMaturityHeightIndexSidechainEvents(int height, CBlockUndo& blockUndo, CBlockTreeDB* pblocktree,
std::vector<std::pair<CMaturityHeightKey,CMaturityHeightValue>>& maturityHeightIndex)
{
if (!HaveSidechainEvents(height))
return;

// Reverting ceasing sidechains
for (auto it = blockUndo.scUndoDatabyScId.begin(); it != blockUndo.scUndoDatabyScId.end(); ++it)
{
if ((it->second.contentBitMask & CSidechainUndoData::AvailableSections::CEASED_CERT_DATA) == 0)
continue;

const uint256& scId = it->first;
const CSidechain* const pSidechain = AccessSidechain(scId);

if (pSidechain->lastTopQualityCertReferencedEpoch != CScCertificate::EPOCH_NULL)
{
// Restore lastTopQualityCert as valid (not superseded)
CMaturityHeightKey maturityHeightKey = CMaturityHeightKey(height, pSidechain->lastTopQualityCertHash);
maturityHeightIndex.push_back(std::make_pair(maturityHeightKey, CMaturityHeightValue(static_cast<char>(1))));
}
}
}


#ifdef ENABLE_ADDRESS_INDEXING
void CCoinsViewCache::HandleIndexesSidechainEvents(int height, CBlockTreeDB* pblocktree,
std::vector<std::pair<CAddressIndexKey, CAddressIndexValue>>& addressIndex,
Expand Down
6 changes: 6 additions & 0 deletions src/coins.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ class CSidechainUndoData;
class CScProofVerifier;

struct CTxIndexValue;
struct CMaturityHeightValue;
struct CMaturityHeightKey;

#ifdef ENABLE_ADDRESS_INDEXING
struct CAddressIndexKey;
Expand Down Expand Up @@ -742,6 +744,10 @@ class CCoinsViewCache : public CCoinsViewBacked
void RevertTxIndexSidechainEvents(int height, CBlockUndo& blockUndo, CBlockTreeDB* pblocktree,
std::vector<std::pair<uint256, CTxIndexValue>>& txIndex);

void HandleMaturityHeightIndexSidechainEvents(int height, CBlockTreeDB* pblocktree,
std::vector<std::pair<CMaturityHeightKey,CMaturityHeightValue>>& maturityHeightIndex);
void RevertMaturityHeightIndexSidechainEvents(int height, CBlockUndo& blockUndo, CBlockTreeDB* pblocktree,
std::vector<std::pair<CMaturityHeightKey,CMaturityHeightValue>>& maturityHeightIndex);
#ifdef ENABLE_ADDRESS_INDEXING
void HandleIndexesSidechainEvents(int height, CBlockTreeDB* pblocktree,
std::vector<std::pair<CAddressIndexKey, CAddressIndexValue>>& addressIndex,
Expand Down
13 changes: 13 additions & 0 deletions src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,7 @@ std::string HelpMessage(HelpMessageMode mode)
strUsage += HelpMessageOpt("-sysperms", _("Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)"));
#endif
strUsage += HelpMessageOpt("-txindex", strprintf(_("Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)"), 0));
strUsage += HelpMessageOpt("-maturityheightindex", strprintf(_("Maintain a maturity height index that stores for every height the cerficates that became mature, used by the getblockexpanded rpc call. It requires -txindex (default: %u)"), 0));

#ifdef ENABLE_ADDRESS_INDEXING
strUsage += HelpMessageOpt("-addressindex", strprintf(_("Maintain a full address index, used to query for the balance, txids and unspent outputs for addresses (default: %u)"), DEFAULT_ADDRESSINDEX));
Expand Down Expand Up @@ -1629,6 +1630,18 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
break;
}

// Check for changed -maturityheightindex state
if (fMaturityHeightIndex != GetBoolArg("-maturityheightindex", false)) {
strLoadError = _("You need to rebuild the database using -reindex to change -maturityheightindex");
break;
}

// Check that -txindex is enabled when -maturityheightindex is enabled
if (fMaturityHeightIndex && !fTxIndex) {
strLoadError = _("You need to enable -txindex in order to use -maturityheightindex");
break;
}

#ifdef ENABLE_ADDRESS_INDEXING
// Check for changed -addressindex state
if (fAddressIndex != GetBoolArg("-addressindex", false)) {
Expand Down
Loading

0 comments on commit 67759c0

Please sign in to comment.