main: start of address index
Adds a configuration option for addressindex to search for txids by address. Includes an additional rpc method for getting the txids for an address.
This commit is contained in:
committed by
Braydon Fuller
parent
075b416f56
commit
9babc7ff9f
@@ -350,6 +350,8 @@ std::string HelpMessage(HelpMessageMode mode)
|
|||||||
#endif
|
#endif
|
||||||
strUsage += HelpMessageOpt("-txindex", strprintf(_("Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)"), DEFAULT_TXINDEX));
|
strUsage += HelpMessageOpt("-txindex", strprintf(_("Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)"), DEFAULT_TXINDEX));
|
||||||
|
|
||||||
|
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));
|
||||||
|
|
||||||
strUsage += HelpMessageGroup(_("Connection options:"));
|
strUsage += HelpMessageGroup(_("Connection options:"));
|
||||||
strUsage += HelpMessageOpt("-addnode=<ip>", _("Add a node to connect to and attempt to keep the connection open"));
|
strUsage += HelpMessageOpt("-addnode=<ip>", _("Add a node to connect to and attempt to keep the connection open"));
|
||||||
strUsage += HelpMessageOpt("-banscore=<n>", strprintf(_("Threshold for disconnecting misbehaving peers (default: %u)"), DEFAULT_BANSCORE_THRESHOLD));
|
strUsage += HelpMessageOpt("-banscore=<n>", strprintf(_("Threshold for disconnecting misbehaving peers (default: %u)"), DEFAULT_BANSCORE_THRESHOLD));
|
||||||
|
|||||||
62
src/main.cpp
62
src/main.cpp
@@ -66,6 +66,7 @@ int nScriptCheckThreads = 0;
|
|||||||
bool fImporting = false;
|
bool fImporting = false;
|
||||||
bool fReindex = false;
|
bool fReindex = false;
|
||||||
bool fTxIndex = false;
|
bool fTxIndex = false;
|
||||||
|
bool fAddressIndex = false;
|
||||||
bool fHavePruned = false;
|
bool fHavePruned = false;
|
||||||
bool fPruneMode = false;
|
bool fPruneMode = false;
|
||||||
bool fIsBareMultisigStd = DEFAULT_PERMIT_BAREMULTISIG;
|
bool fIsBareMultisigStd = DEFAULT_PERMIT_BAREMULTISIG;
|
||||||
@@ -1438,6 +1439,17 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool GetAddressIndex(uint160 addressHash, int type, std::vector<std::pair<CAddressIndexKey, CAmount> > &addressIndex)
|
||||||
|
{
|
||||||
|
if (!fAddressIndex)
|
||||||
|
return error("%s: address index not enabled");
|
||||||
|
|
||||||
|
if (!pblocktree->ReadAddressIndex(addressHash, type, addressIndex))
|
||||||
|
return error("%s: unable to get txids for address");
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/** Return transaction in tx, and if it was found inside a block, its hash is placed in hashBlock */
|
/** Return transaction in tx, and if it was found inside a block, its hash is placed in hashBlock */
|
||||||
bool GetTransaction(const uint256 &hash, CTransaction &txOut, const Consensus::Params& consensusParams, uint256 &hashBlock, bool fAllowSlow)
|
bool GetTransaction(const uint256 &hash, CTransaction &txOut, const Consensus::Params& consensusParams, uint256 &hashBlock, bool fAllowSlow)
|
||||||
{
|
{
|
||||||
@@ -2322,9 +2334,12 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
|
|||||||
std::vector<std::pair<uint256, CDiskTxPos> > vPos;
|
std::vector<std::pair<uint256, CDiskTxPos> > vPos;
|
||||||
vPos.reserve(block.vtx.size());
|
vPos.reserve(block.vtx.size());
|
||||||
blockundo.vtxundo.reserve(block.vtx.size() - 1);
|
blockundo.vtxundo.reserve(block.vtx.size() - 1);
|
||||||
|
std::vector<std::pair<CAddressIndexKey, CAmount> > addressIndex;
|
||||||
|
|
||||||
for (unsigned int i = 0; i < block.vtx.size(); i++)
|
for (unsigned int i = 0; i < block.vtx.size(); i++)
|
||||||
{
|
{
|
||||||
const CTransaction &tx = block.vtx[i];
|
const CTransaction &tx = block.vtx[i];
|
||||||
|
const uint256 txhash = tx.GetHash();
|
||||||
|
|
||||||
nInputs += tx.vin.size();
|
nInputs += tx.vin.size();
|
||||||
nSigOps += GetLegacySigOpCount(tx);
|
nSigOps += GetLegacySigOpCount(tx);
|
||||||
@@ -2351,6 +2366,22 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
|
|||||||
REJECT_INVALID, "bad-txns-nonfinal");
|
REJECT_INVALID, "bad-txns-nonfinal");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (fAddressIndex)
|
||||||
|
{
|
||||||
|
for (size_t j = 0; j < tx.vin.size(); j++) {
|
||||||
|
const CTxOut &prevout = view.GetOutputFor(tx.vin[j]);
|
||||||
|
if (prevout.scriptPubKey.IsPayToScriptHash()) {
|
||||||
|
vector<unsigned char> hashBytes(prevout.scriptPubKey.begin()+2, prevout.scriptPubKey.begin()+22);
|
||||||
|
addressIndex.push_back(make_pair(CAddressIndexKey(uint160(hashBytes), 2, txhash, j), prevout.nValue * -1));
|
||||||
|
} else if (prevout.scriptPubKey.IsPayToPublicKeyHash()) {
|
||||||
|
vector<unsigned char> hashBytes(prevout.scriptPubKey.begin()+3, prevout.scriptPubKey.begin()+23);
|
||||||
|
addressIndex.push_back(make_pair(CAddressIndexKey(uint160(hashBytes), 1, txhash, j), prevout.nValue * -1));
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (fStrictPayToScriptHash)
|
if (fStrictPayToScriptHash)
|
||||||
{
|
{
|
||||||
// Add in sigops done by pay-to-script-hash inputs;
|
// Add in sigops done by pay-to-script-hash inputs;
|
||||||
@@ -2372,6 +2403,24 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
|
|||||||
control.Add(vChecks);
|
control.Add(vChecks);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (fAddressIndex) {
|
||||||
|
for (unsigned int k = 0; k < tx.vout.size(); k++) {
|
||||||
|
const CTxOut &out = tx.vout[k];
|
||||||
|
|
||||||
|
if (out.scriptPubKey.IsPayToScriptHash()) {
|
||||||
|
vector<unsigned char> hashBytes(out.scriptPubKey.begin()+2, out.scriptPubKey.begin()+22);
|
||||||
|
addressIndex.push_back(make_pair(CAddressIndexKey(uint160(hashBytes), 2, txhash, k), out.nValue));
|
||||||
|
} else if (out.scriptPubKey.IsPayToPublicKeyHash()) {
|
||||||
|
vector<unsigned char> hashBytes(out.scriptPubKey.begin()+3, out.scriptPubKey.begin()+23);
|
||||||
|
addressIndex.push_back(make_pair(CAddressIndexKey(uint160(hashBytes), 1, txhash, k), out.nValue));
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
CTxUndo undoDummy;
|
CTxUndo undoDummy;
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
blockundo.vtxundo.push_back(CTxUndo());
|
blockundo.vtxundo.push_back(CTxUndo());
|
||||||
@@ -2422,6 +2471,10 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
|
|||||||
if (!pblocktree->WriteTxIndex(vPos))
|
if (!pblocktree->WriteTxIndex(vPos))
|
||||||
return AbortNode(state, "Failed to write transaction index");
|
return AbortNode(state, "Failed to write transaction index");
|
||||||
|
|
||||||
|
if (fAddressIndex)
|
||||||
|
if (!pblocktree->WriteAddressIndex(addressIndex))
|
||||||
|
return AbortNode(state, "Failed to write address index");
|
||||||
|
|
||||||
// add this block to the view's block chain
|
// add this block to the view's block chain
|
||||||
view.SetBestBlock(pindex->GetBlockHash());
|
view.SetBestBlock(pindex->GetBlockHash());
|
||||||
|
|
||||||
@@ -3813,6 +3866,10 @@ bool static LoadBlockIndexDB()
|
|||||||
pblocktree->ReadFlag("txindex", fTxIndex);
|
pblocktree->ReadFlag("txindex", fTxIndex);
|
||||||
LogPrintf("%s: transaction index %s\n", __func__, fTxIndex ? "enabled" : "disabled");
|
LogPrintf("%s: transaction index %s\n", __func__, fTxIndex ? "enabled" : "disabled");
|
||||||
|
|
||||||
|
// Check whether we have an address index
|
||||||
|
pblocktree->ReadFlag("addressindex", fAddressIndex);
|
||||||
|
LogPrintf("%s: address index %s\n", __func__, fAddressIndex ? "enabled" : "disabled");
|
||||||
|
|
||||||
// Load pointer to end of best chain
|
// Load pointer to end of best chain
|
||||||
BlockMap::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock());
|
BlockMap::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock());
|
||||||
if (it == mapBlockIndex.end())
|
if (it == mapBlockIndex.end())
|
||||||
@@ -3973,6 +4030,11 @@ bool InitBlockIndex(const CChainParams& chainparams)
|
|||||||
// Use the provided setting for -txindex in the new database
|
// Use the provided setting for -txindex in the new database
|
||||||
fTxIndex = GetBoolArg("-txindex", DEFAULT_TXINDEX);
|
fTxIndex = GetBoolArg("-txindex", DEFAULT_TXINDEX);
|
||||||
pblocktree->WriteFlag("txindex", fTxIndex);
|
pblocktree->WriteFlag("txindex", fTxIndex);
|
||||||
|
|
||||||
|
// Use the provided setting for -addressindex in the new database
|
||||||
|
fAddressIndex = GetBoolArg("-addressindex", DEFAULT_ADDRESSINDEX);
|
||||||
|
pblocktree->WriteFlag("addressindex", fAddressIndex);
|
||||||
|
|
||||||
LogPrintf("Initializing databases...\n");
|
LogPrintf("Initializing databases...\n");
|
||||||
|
|
||||||
// Only add the genesis block if not reindexing (in which case we reuse the one already on disk)
|
// Only add the genesis block if not reindexing (in which case we reuse the one already on disk)
|
||||||
|
|||||||
38
src/main.h
38
src/main.h
@@ -111,6 +111,7 @@ static const bool DEFAULT_PERMIT_BAREMULTISIG = true;
|
|||||||
static const unsigned int DEFAULT_BYTES_PER_SIGOP = 20;
|
static const unsigned int DEFAULT_BYTES_PER_SIGOP = 20;
|
||||||
static const bool DEFAULT_CHECKPOINTS_ENABLED = true;
|
static const bool DEFAULT_CHECKPOINTS_ENABLED = true;
|
||||||
static const bool DEFAULT_TXINDEX = false;
|
static const bool DEFAULT_TXINDEX = false;
|
||||||
|
static const bool DEFAULT_ADDRESSINDEX = false;
|
||||||
static const unsigned int DEFAULT_BANSCORE_THRESHOLD = 100;
|
static const unsigned int DEFAULT_BANSCORE_THRESHOLD = 100;
|
||||||
|
|
||||||
static const bool DEFAULT_TESTSAFEMODE = false;
|
static const bool DEFAULT_TESTSAFEMODE = false;
|
||||||
@@ -290,6 +291,42 @@ struct CNodeStateStats {
|
|||||||
std::vector<int> vHeightInFlight;
|
std::vector<int> vHeightInFlight;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct CAddressIndexKey {
|
||||||
|
uint160 hashBytes;
|
||||||
|
unsigned int type;
|
||||||
|
uint256 txhash;
|
||||||
|
size_t index;
|
||||||
|
|
||||||
|
ADD_SERIALIZE_METHODS;
|
||||||
|
|
||||||
|
template <typename Stream, typename Operation>
|
||||||
|
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
|
||||||
|
READWRITE(hashBytes);
|
||||||
|
READWRITE(type);
|
||||||
|
READWRITE(txhash);
|
||||||
|
READWRITE(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
CAddressIndexKey(uint160 addressHash, unsigned int addressType, uint256 txid, size_t txindex) {
|
||||||
|
hashBytes = addressHash;
|
||||||
|
type = addressType;
|
||||||
|
txhash = txid;
|
||||||
|
index = txindex;
|
||||||
|
}
|
||||||
|
|
||||||
|
CAddressIndexKey() {
|
||||||
|
SetNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetNull() {
|
||||||
|
hashBytes.SetNull();
|
||||||
|
type = 0;
|
||||||
|
txhash.SetNull();
|
||||||
|
index = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
struct CDiskTxPos : public CDiskBlockPos
|
struct CDiskTxPos : public CDiskBlockPos
|
||||||
{
|
{
|
||||||
unsigned int nTxOffset; // after header
|
unsigned int nTxOffset; // after header
|
||||||
@@ -420,6 +457,7 @@ public:
|
|||||||
ScriptError GetScriptError() const { return error; }
|
ScriptError GetScriptError() const { return error; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool GetAddressIndex(uint160 addressHash, int type, std::vector<std::pair<CAddressIndexKey, CAmount> > &addressIndex);
|
||||||
|
|
||||||
/** Functions for disk access for blocks */
|
/** Functions for disk access for blocks */
|
||||||
bool WriteBlockToDisk(const CBlock& block, CDiskBlockPos& pos, const CMessageHeader::MessageStartChars& messageStart);
|
bool WriteBlockToDisk(const CBlock& block, CDiskBlockPos& pos, const CMessageHeader::MessageStartChars& messageStart);
|
||||||
|
|||||||
@@ -396,3 +396,39 @@ UniValue setmocktime(const UniValue& params, bool fHelp)
|
|||||||
|
|
||||||
return NullUniValue;
|
return NullUniValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UniValue getaddresstxids(const UniValue& params, bool fHelp)
|
||||||
|
{
|
||||||
|
if (fHelp || params.size() != 1)
|
||||||
|
throw runtime_error(
|
||||||
|
"getaddresstxids\n"
|
||||||
|
"\nReturns the txids for an address (requires addressindex to be enabled).\n"
|
||||||
|
"\nResult\n"
|
||||||
|
"[\n"
|
||||||
|
" \"transactionid\" (string) The transaction id\n"
|
||||||
|
" ,...\n"
|
||||||
|
"]\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
CBitcoinAddress address(params[0].get_str());
|
||||||
|
if (!address.IsValid())
|
||||||
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address");
|
||||||
|
|
||||||
|
CKeyID keyID;
|
||||||
|
address.GetKeyID(keyID);
|
||||||
|
|
||||||
|
int type = 1; // TODO
|
||||||
|
std::vector<std::pair<CAddressIndexKey, CAmount> > addressIndex;
|
||||||
|
|
||||||
|
LOCK(cs_main);
|
||||||
|
|
||||||
|
if (!GetAddressIndex(keyID, type, addressIndex))
|
||||||
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available for address");
|
||||||
|
|
||||||
|
UniValue result(UniValue::VARR);
|
||||||
|
for (std::vector<std::pair<CAddressIndexKey, CAmount> >::const_iterator it=addressIndex.begin(); it!=addressIndex.end(); it++)
|
||||||
|
result.push_back(it->first.txhash.GetHex());
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -313,6 +313,9 @@ static const CRPCCommand vRPCCommands[] =
|
|||||||
{ "rawtransactions", "fundrawtransaction", &fundrawtransaction, false },
|
{ "rawtransactions", "fundrawtransaction", &fundrawtransaction, false },
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Address index */
|
||||||
|
{ "addressindex", "getaddresstxids", &getaddresstxids, false },
|
||||||
|
|
||||||
/* Utility functions */
|
/* Utility functions */
|
||||||
{ "util", "createmultisig", &createmultisig, true },
|
{ "util", "createmultisig", &createmultisig, true },
|
||||||
{ "util", "validateaddress", &validateaddress, true }, /* uses wallet if enabled */
|
{ "util", "validateaddress", &validateaddress, true }, /* uses wallet if enabled */
|
||||||
|
|||||||
@@ -166,6 +166,8 @@ extern std::string HelpExampleRpc(const std::string& methodname, const std::stri
|
|||||||
extern void EnsureWalletIsUnlocked();
|
extern void EnsureWalletIsUnlocked();
|
||||||
|
|
||||||
extern UniValue getconnectioncount(const UniValue& params, bool fHelp); // in rpcnet.cpp
|
extern UniValue getconnectioncount(const UniValue& params, bool fHelp); // in rpcnet.cpp
|
||||||
|
extern UniValue getaddresstxids(const UniValue& params, bool fHelp);
|
||||||
|
|
||||||
extern UniValue getpeerinfo(const UniValue& params, bool fHelp);
|
extern UniValue getpeerinfo(const UniValue& params, bool fHelp);
|
||||||
extern UniValue ping(const UniValue& params, bool fHelp);
|
extern UniValue ping(const UniValue& params, bool fHelp);
|
||||||
extern UniValue addnode(const UniValue& params, bool fHelp);
|
extern UniValue addnode(const UniValue& params, bool fHelp);
|
||||||
|
|||||||
@@ -201,6 +201,17 @@ unsigned int CScript::GetSigOpCount(const CScript& scriptSig) const
|
|||||||
return subscript.GetSigOpCount(true);
|
return subscript.GetSigOpCount(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CScript::IsPayToPublicKeyHash() const
|
||||||
|
{
|
||||||
|
// Extra-fast test for pay-to-pubkey-hash CScripts:
|
||||||
|
return (this->size() == 25 &&
|
||||||
|
(*this)[0] == OP_DUP &&
|
||||||
|
(*this)[1] == OP_HASH160 &&
|
||||||
|
(*this)[2] == 0x14 &&
|
||||||
|
(*this)[23] == OP_EQUALVERIFY &&
|
||||||
|
(*this)[24] == OP_CHECKSIG);
|
||||||
|
}
|
||||||
|
|
||||||
bool CScript::IsPayToScriptHash() const
|
bool CScript::IsPayToScriptHash() const
|
||||||
{
|
{
|
||||||
// Extra-fast test for pay-to-script-hash CScripts:
|
// Extra-fast test for pay-to-script-hash CScripts:
|
||||||
|
|||||||
@@ -608,6 +608,8 @@ public:
|
|||||||
*/
|
*/
|
||||||
unsigned int GetSigOpCount(const CScript& scriptSig) const;
|
unsigned int GetSigOpCount(const CScript& scriptSig) const;
|
||||||
|
|
||||||
|
bool IsPayToPublicKeyHash() const;
|
||||||
|
|
||||||
bool IsPayToScriptHash() const;
|
bool IsPayToScriptHash() const;
|
||||||
|
|
||||||
/** Called by IsStandardTx and P2SH/BIP62 VerifyScript (which makes it consensus-critical). */
|
/** Called by IsStandardTx and P2SH/BIP62 VerifyScript (which makes it consensus-critical). */
|
||||||
|
|||||||
33
src/txdb.cpp
33
src/txdb.cpp
@@ -21,6 +21,7 @@ using namespace std;
|
|||||||
static const char DB_COINS = 'c';
|
static const char DB_COINS = 'c';
|
||||||
static const char DB_BLOCK_FILES = 'f';
|
static const char DB_BLOCK_FILES = 'f';
|
||||||
static const char DB_TXINDEX = 't';
|
static const char DB_TXINDEX = 't';
|
||||||
|
static const char DB_ADDRESSINDEX = 'a';
|
||||||
static const char DB_BLOCK_INDEX = 'b';
|
static const char DB_BLOCK_INDEX = 'b';
|
||||||
|
|
||||||
static const char DB_BEST_BLOCK = 'B';
|
static const char DB_BEST_BLOCK = 'B';
|
||||||
@@ -163,6 +164,38 @@ bool CBlockTreeDB::WriteTxIndex(const std::vector<std::pair<uint256, CDiskTxPos>
|
|||||||
return WriteBatch(batch);
|
return WriteBatch(batch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CBlockTreeDB::WriteAddressIndex(const std::vector<std::pair<CAddressIndexKey, CAmount > >&vect) {
|
||||||
|
CDBBatch batch(&GetObfuscateKey());
|
||||||
|
for (std::vector<std::pair<CAddressIndexKey, CAmount> >::const_iterator it=vect.begin(); it!=vect.end(); it++)
|
||||||
|
batch.Write(make_pair(DB_ADDRESSINDEX, it->first), it->second);
|
||||||
|
return WriteBatch(batch);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CBlockTreeDB::ReadAddressIndex(uint160 addressHash, int type, std::vector<std::pair<CAddressIndexKey, CAmount> > &addressIndex) {
|
||||||
|
|
||||||
|
boost::scoped_ptr<CDBIterator> pcursor(NewIterator());
|
||||||
|
|
||||||
|
pcursor->Seek(make_pair(DB_ADDRESSINDEX, addressHash)); //TODO include type
|
||||||
|
|
||||||
|
while (pcursor->Valid()) {
|
||||||
|
boost::this_thread::interruption_point();
|
||||||
|
std::pair<char,CAddressIndexKey> key;
|
||||||
|
if (pcursor->GetKey(key) && key.first == DB_ADDRESSINDEX && key.second.hashBytes == addressHash) {
|
||||||
|
CAmount nValue;
|
||||||
|
if (pcursor->GetValue(nValue)) {
|
||||||
|
addressIndex.push_back(make_pair(key.second, nValue));
|
||||||
|
pcursor->Next();
|
||||||
|
} else {
|
||||||
|
return error("failed to get address index value");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool CBlockTreeDB::WriteFlag(const std::string &name, bool fValue) {
|
bool CBlockTreeDB::WriteFlag(const std::string &name, bool fValue) {
|
||||||
return Write(std::make_pair(DB_FLAG, name), fValue ? '1' : '0');
|
return Write(std::make_pair(DB_FLAG, name), fValue ? '1' : '0');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
class CBlockFileInfo;
|
class CBlockFileInfo;
|
||||||
class CBlockIndex;
|
class CBlockIndex;
|
||||||
struct CDiskTxPos;
|
struct CDiskTxPos;
|
||||||
|
struct CAddressIndexKey;
|
||||||
class uint256;
|
class uint256;
|
||||||
|
|
||||||
//! -dbcache default (MiB)
|
//! -dbcache default (MiB)
|
||||||
@@ -57,6 +58,8 @@ public:
|
|||||||
bool ReadReindexing(bool &fReindex);
|
bool ReadReindexing(bool &fReindex);
|
||||||
bool ReadTxIndex(const uint256 &txid, CDiskTxPos &pos);
|
bool ReadTxIndex(const uint256 &txid, CDiskTxPos &pos);
|
||||||
bool WriteTxIndex(const std::vector<std::pair<uint256, CDiskTxPos> > &list);
|
bool WriteTxIndex(const std::vector<std::pair<uint256, CDiskTxPos> > &list);
|
||||||
|
bool WriteAddressIndex(const std::vector<std::pair<CAddressIndexKey, CAmount> > &vect);
|
||||||
|
bool ReadAddressIndex(uint160 addressHash, int type, std::vector<std::pair<CAddressIndexKey, CAmount> > &addressIndex);
|
||||||
bool WriteFlag(const std::string &name, bool fValue);
|
bool WriteFlag(const std::string &name, bool fValue);
|
||||||
bool ReadFlag(const std::string &name, bool &fValue);
|
bool ReadFlag(const std::string &name, bool &fValue);
|
||||||
bool LoadBlockIndexGuts();
|
bool LoadBlockIndexGuts();
|
||||||
|
|||||||
Reference in New Issue
Block a user