mirror of
https://github.com/jwinterm/myriadcoin.git
synced 2026-10-22 06:28:44 +02:00
add support for address index
This commit is contained in:
+98
-5
@@ -9,6 +9,7 @@
|
||||
#include "alert.h"
|
||||
#include "arith_uint256.h"
|
||||
#include "auxpow.h"
|
||||
#include "base58.h"
|
||||
#include "chainparams.h"
|
||||
#include "checkpoints.h"
|
||||
#include "checkqueue.h"
|
||||
@@ -57,6 +58,7 @@ bool fReindex = false;
|
||||
bool fTxIndex = false;
|
||||
bool fHavePruned = false;
|
||||
bool fPruneMode = false;
|
||||
bool fAddrIndex = false;
|
||||
bool fIsBareMultisigStd = true;
|
||||
bool fCheckBlockIndex = false;
|
||||
bool fCheckpointsEnabled = true;
|
||||
@@ -1113,6 +1115,43 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ReadTransaction(CTransaction& tx, const CDiskTxPos &pos, uint256 &hashBlock) {
|
||||
CAutoFile file(OpenBlockFile(pos, true), SER_DISK, CLIENT_VERSION);
|
||||
CBlockHeader header;
|
||||
try {
|
||||
file >> header;
|
||||
fseek(file.Get(), pos.nTxOffset, SEEK_CUR);
|
||||
file >> tx;
|
||||
} catch (std::exception &e) {
|
||||
return error("%s() : deserialize or I/O error", __PRETTY_FUNCTION__);
|
||||
}
|
||||
hashBlock = header.GetHash();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FindTransactionsByDestination(const CTxDestination &dest, std::set<CExtDiskTxPos> &setpos) {
|
||||
uint160 addrid;
|
||||
const CKeyID *pkeyid = boost::get<CKeyID>(&dest);
|
||||
if (pkeyid)
|
||||
addrid = static_cast<uint160>(*pkeyid);
|
||||
if (addrid.IsNull()) {
|
||||
const CScriptID *pscriptid = boost::get<CScriptID>(&dest);
|
||||
if (pscriptid)
|
||||
addrid = static_cast<uint160>(*pscriptid);
|
||||
}
|
||||
if (addrid.IsNull())
|
||||
return false;
|
||||
|
||||
LOCK(cs_main);
|
||||
if (!fAddrIndex)
|
||||
return false;
|
||||
std::vector<CExtDiskTxPos> vPos;
|
||||
if (!pblocktree->ReadAddrIndex(addrid, vPos))
|
||||
return false;
|
||||
setpos.insert(vPos.begin(), vPos.end());
|
||||
return true;
|
||||
}
|
||||
|
||||
/** 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, uint256 &hashBlock, bool fAllowSlow)
|
||||
{
|
||||
@@ -1850,6 +1889,33 @@ static int64_t nTimeIndex = 0;
|
||||
static int64_t nTimeCallbacks = 0;
|
||||
static int64_t nTimeTotal = 0;
|
||||
|
||||
// Index either: a) every data push >=8 bytes, b) if no such pushes, the entire script
|
||||
void static BuildAddrIndex(const CScript &script, const CExtDiskTxPos &pos, std::vector<std::pair<uint160, CExtDiskTxPos> > &out)
|
||||
{
|
||||
CScript::const_iterator pc = script.begin();
|
||||
CScript::const_iterator pend = script.end();
|
||||
std::vector<unsigned char> data;
|
||||
opcodetype opcode;
|
||||
bool fHaveData = false;
|
||||
while (pc < pend) {
|
||||
script.GetOp(pc, opcode, data);
|
||||
if (0 <= opcode && opcode <= OP_PUSHDATA4 && data.size() >= 8) { // data element
|
||||
uint160 addrid;
|
||||
if (data.size() <= 20) {
|
||||
memcpy(&addrid, &data[0], data.size());
|
||||
} else {
|
||||
addrid = Hash160(data);
|
||||
}
|
||||
out.push_back(std::make_pair(addrid, pos));
|
||||
fHaveData = true;
|
||||
}
|
||||
}
|
||||
if (!fHaveData) {
|
||||
uint160 addrid = Hash160(script);
|
||||
out.push_back(std::make_pair(addrid, pos));
|
||||
}
|
||||
}
|
||||
|
||||
bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, bool fJustCheck)
|
||||
{
|
||||
const CChainParams& chainparams = Params();
|
||||
@@ -1925,9 +1991,13 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
|
||||
CAmount nFees = 0;
|
||||
int nInputs = 0;
|
||||
unsigned int nSigOps = 0;
|
||||
CDiskTxPos pos(pindex->GetBlockPos(), GetSizeOfCompactSize(block.vtx.size()));
|
||||
std::vector<std::pair<uint256, CDiskTxPos> > vPos;
|
||||
vPos.reserve(block.vtx.size());
|
||||
CExtDiskTxPos pos(CDiskTxPos(pindex->GetBlockPos(), GetSizeOfCompactSize(block.vtx.size())), pindex->nHeight);
|
||||
std::vector<std::pair<uint256, CDiskTxPos> > vPosTxid;
|
||||
std::vector<std::pair<uint160, CExtDiskTxPos> > vPosAddrid;
|
||||
if (fTxIndex)
|
||||
vPosTxid.reserve(block.vtx.size());
|
||||
if (fAddrIndex)
|
||||
vPosAddrid.reserve(4*block.vtx.size());
|
||||
blockundo.vtxundo.reserve(block.vtx.size() - 1);
|
||||
for (unsigned int i = 0; i < block.vtx.size(); i++)
|
||||
{
|
||||
@@ -1965,13 +2035,26 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
|
||||
control.Add(vChecks);
|
||||
}
|
||||
|
||||
if (fTxIndex)
|
||||
vPosTxid.push_back(std::make_pair(tx.GetHash(), pos));
|
||||
if (fAddrIndex) {
|
||||
if (!tx.IsCoinBase()) {
|
||||
BOOST_FOREACH(const CTxIn &txin, tx.vin) {
|
||||
CCoins coins;
|
||||
view.GetCoins(txin.prevout.hash, coins);
|
||||
BuildAddrIndex(coins.vout[txin.prevout.n].scriptPubKey, pos, vPosAddrid);
|
||||
}
|
||||
}
|
||||
BOOST_FOREACH(const CTxOut &txout, tx.vout)
|
||||
BuildAddrIndex(txout.scriptPubKey, pos, vPosAddrid);
|
||||
}
|
||||
|
||||
CTxUndo undoDummy;
|
||||
if (i > 0) {
|
||||
blockundo.vtxundo.push_back(CTxUndo());
|
||||
}
|
||||
UpdateCoins(tx, state, view, i == 0 ? undoDummy : blockundo.vtxundo.back(), pindex->nHeight);
|
||||
|
||||
vPos.push_back(std::make_pair(tx.GetHash(), pos));
|
||||
pos.nTxOffset += ::GetSerializeSize(tx, SER_DISK, CLIENT_VERSION);
|
||||
}
|
||||
int64_t nTime1 = GetTimeMicros(); nTimeConnect += nTime1 - nTimeStart;
|
||||
@@ -2012,8 +2095,12 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
|
||||
}
|
||||
|
||||
if (fTxIndex)
|
||||
if (!pblocktree->WriteTxIndex(vPos))
|
||||
if (!pblocktree->WriteTxIndex(vPosTxid))
|
||||
return AbortNode(state, "Failed to write transaction index");
|
||||
|
||||
if (fAddrIndex)
|
||||
if (!pblocktree->AddAddrIndex(vPosAddrid))
|
||||
return AbortNode(state, "Failed to write address index");
|
||||
|
||||
// add this block to the view's block chain
|
||||
view.SetBestBlock(pindex->GetBlockHash());
|
||||
@@ -3385,6 +3472,10 @@ bool static LoadBlockIndexDB()
|
||||
pblocktree->ReadFlag("txindex", fTxIndex);
|
||||
LogPrintf("%s: transaction index %s\n", __func__, fTxIndex ? "enabled" : "disabled");
|
||||
|
||||
// Check whether we have an address index
|
||||
pblocktree->ReadFlag("addrindex", fAddrIndex);
|
||||
LogPrintf("%s: address index %s\n", __func__, fAddrIndex ? "enabled" : "disabled");
|
||||
|
||||
// Load pointer to end of best chain
|
||||
BlockMap::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock());
|
||||
if (it == mapBlockIndex.end())
|
||||
@@ -3543,6 +3634,8 @@ bool InitBlockIndex() {
|
||||
// Use the provided setting for -txindex in the new database
|
||||
fTxIndex = GetBoolArg("-txindex", false);
|
||||
pblocktree->WriteFlag("txindex", fTxIndex);
|
||||
fAddrIndex = GetBoolArg("-addrindex", false);
|
||||
pblocktree->WriteFlag("addrindex", fAddrIndex);
|
||||
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