main: add spentindex option
This commit is contained in:
committed by
Braydon Fuller
parent
8636f36477
commit
e3d9207e5a
86
src/main.cpp
86
src/main.cpp
@@ -68,6 +68,7 @@ bool fReindex = false;
|
||||
bool fTxIndex = false;
|
||||
bool fAddressIndex = false;
|
||||
bool fTimestampIndex = false;
|
||||
bool fSpentIndex = false;
|
||||
bool fHavePruned = false;
|
||||
bool fPruneMode = false;
|
||||
bool fIsBareMultisigStd = DEFAULT_PERMIT_BAREMULTISIG;
|
||||
@@ -1454,6 +1455,17 @@ bool GetTimestampIndex(const unsigned int &high, const unsigned int &low, std::v
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GetSpentIndex(CSpentIndexKey &key, CSpentIndexValue &value)
|
||||
{
|
||||
if (!fSpentIndex)
|
||||
return error("spent index not enabled");
|
||||
|
||||
if (!pblocktree->ReadSpentIndex(key, value))
|
||||
return error("unable to get spent info");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GetAddressIndex(uint160 addressHash, int type,
|
||||
std::vector<std::pair<CAddressIndexKey, CAmount> > &addressIndex, int start, int end)
|
||||
{
|
||||
@@ -2058,6 +2070,7 @@ bool DisconnectBlock(const CBlock& block, CValidationState& state, const CBlockI
|
||||
|
||||
std::vector<std::pair<CAddressIndexKey, CAmount> > addressIndex;
|
||||
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > addressUnspentIndex;
|
||||
std::vector<std::pair<CSpentIndexKey, CSpentIndexValue> > spentIndex;
|
||||
|
||||
// undo transactions in reverse order
|
||||
for (int i = block.vtx.size() - 1; i >= 0; i--) {
|
||||
@@ -2125,8 +2138,14 @@ bool DisconnectBlock(const CBlock& block, CValidationState& state, const CBlockI
|
||||
if (!ApplyTxInUndo(undo, view, out))
|
||||
fClean = false;
|
||||
|
||||
const CTxIn input = tx.vin[j];
|
||||
|
||||
if (fSpentIndex) {
|
||||
// undo and delete the spent index
|
||||
spentIndex.push_back(make_pair(CSpentIndexKey(input.prevout.hash, input.prevout.n), CSpentIndexValue()));
|
||||
}
|
||||
|
||||
if (fAddressIndex) {
|
||||
const CTxIn input = tx.vin[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);
|
||||
@@ -2151,6 +2170,7 @@ bool DisconnectBlock(const CBlock& block, CValidationState& state, const CBlockI
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2435,6 +2455,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
|
||||
blockundo.vtxundo.reserve(block.vtx.size() - 1);
|
||||
std::vector<std::pair<CAddressIndexKey, CAmount> > addressIndex;
|
||||
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > addressUnspentIndex;
|
||||
std::vector<std::pair<CSpentIndexKey, CSpentIndexValue> > spentIndex;
|
||||
|
||||
for (unsigned int i = 0; i < block.vtx.size(); i++)
|
||||
{
|
||||
@@ -2466,31 +2487,43 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
|
||||
REJECT_INVALID, "bad-txns-nonfinal");
|
||||
}
|
||||
|
||||
if (fAddressIndex)
|
||||
if (fAddressIndex || fSpentIndex)
|
||||
{
|
||||
for (size_t j = 0; j < tx.vin.size(); j++) {
|
||||
|
||||
const CTxIn input = tx.vin[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);
|
||||
|
||||
// record spending activity
|
||||
addressIndex.push_back(make_pair(CAddressIndexKey(2, uint160(hashBytes), pindex->nHeight, i, txhash, j, true), prevout.nValue * -1));
|
||||
|
||||
// remove address from unspent index
|
||||
addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(2, uint160(hashBytes), input.prevout.hash, input.prevout.n), CAddressUnspentValue()));
|
||||
} else if (prevout.scriptPubKey.IsPayToPublicKeyHash()) {
|
||||
vector<unsigned char> hashBytes(prevout.scriptPubKey.begin()+3, prevout.scriptPubKey.begin()+23);
|
||||
|
||||
// record spending activity
|
||||
addressIndex.push_back(make_pair(CAddressIndexKey(1, uint160(hashBytes), pindex->nHeight, i, txhash, j, true), prevout.nValue * -1));
|
||||
|
||||
// remove address from unspent index
|
||||
addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, uint160(hashBytes), input.prevout.hash, input.prevout.n), CAddressUnspentValue()));
|
||||
|
||||
} else {
|
||||
continue;
|
||||
if (fSpentIndex) {
|
||||
// add the spent index to determine the txid and input that spent an output
|
||||
spentIndex.push_back(make_pair(CSpentIndexKey(input.prevout.hash, input.prevout.n), CSpentIndexValue(txhash, j, pindex->nHeight)));
|
||||
}
|
||||
|
||||
if (fAddressIndex) {
|
||||
|
||||
const CTxOut &prevout = view.GetOutputFor(tx.vin[j]);
|
||||
|
||||
if (prevout.scriptPubKey.IsPayToScriptHash()) {
|
||||
vector<unsigned char> hashBytes(prevout.scriptPubKey.begin()+2, prevout.scriptPubKey.begin()+22);
|
||||
|
||||
// record spending activity
|
||||
addressIndex.push_back(make_pair(CAddressIndexKey(2, uint160(hashBytes), pindex->nHeight, i, txhash, j, true), prevout.nValue * -1));
|
||||
|
||||
// remove address from unspent index
|
||||
addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(2, uint160(hashBytes), input.prevout.hash, input.prevout.n), CAddressUnspentValue()));
|
||||
} else if (prevout.scriptPubKey.IsPayToPublicKeyHash()) {
|
||||
vector<unsigned char> hashBytes(prevout.scriptPubKey.begin()+3, prevout.scriptPubKey.begin()+23);
|
||||
|
||||
// record spending activity
|
||||
addressIndex.push_back(make_pair(CAddressIndexKey(1, uint160(hashBytes), pindex->nHeight, i, txhash, j, true), prevout.nValue * -1));
|
||||
|
||||
// remove address from unspent index
|
||||
addressUnspentIndex.push_back(make_pair(CAddressUnspentKey(1, uint160(hashBytes), input.prevout.hash, input.prevout.n), CAddressUnspentValue()));
|
||||
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2604,6 +2637,10 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
|
||||
}
|
||||
}
|
||||
|
||||
if (fSpentIndex)
|
||||
if (!pblocktree->UpdateSpentIndex(spentIndex))
|
||||
return AbortNode(state, "Failed to write transaction index");
|
||||
|
||||
if (fTimestampIndex)
|
||||
if (!pblocktree->WriteTimestampIndex(CTimestampIndexKey(pindex->nTime, pindex->GetBlockHash())))
|
||||
return AbortNode(state, "Failed to write timestamp index");
|
||||
@@ -4007,6 +4044,10 @@ bool static LoadBlockIndexDB()
|
||||
pblocktree->ReadFlag("timestampindex", fTimestampIndex);
|
||||
LogPrintf("%s: timestamp index %s\n", __func__, fTimestampIndex ? "enabled" : "disabled");
|
||||
|
||||
// Check whether we have a spent index
|
||||
pblocktree->ReadFlag("spentindex", fSpentIndex);
|
||||
LogPrintf("%s: spent index %s\n", __func__, fSpentIndex ? "enabled" : "disabled");
|
||||
|
||||
// Load pointer to end of best chain
|
||||
BlockMap::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock());
|
||||
if (it == mapBlockIndex.end())
|
||||
@@ -4176,6 +4217,9 @@ bool InitBlockIndex(const CChainParams& chainparams)
|
||||
fTimestampIndex = GetBoolArg("-timestampindex", DEFAULT_TIMESTAMPINDEX);
|
||||
pblocktree->WriteFlag("timestampindex", fTimestampIndex);
|
||||
|
||||
fSpentIndex = GetBoolArg("-spentindex", DEFAULT_SPENTINDEX);
|
||||
pblocktree->WriteFlag("spentindex", fSpentIndex);
|
||||
|
||||
LogPrintf("Initializing databases...\n");
|
||||
|
||||
// Only add the genesis block if not reindexing (in which case we reuse the one already on disk)
|
||||
|
||||
Reference in New Issue
Block a user