mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-01-18 22:35:39 +01:00
Add optional transaction index to databases
By specifying -txindex when initializing the database, a txid-to-diskpos index is maintained in the blktree database. This database is used to help answering getrawtransaction() RPC queries, when enabled. Changing the -txindex value requires a -reindex; the client will abort at startup if the database and the specified -txindex mismatch.
This commit is contained in:
committed by
Pieter Wuille
parent
2c7847349d
commit
2d1fa42e85
44
src/main.cpp
44
src/main.cpp
@@ -45,6 +45,7 @@ int nScriptCheckThreads = 0;
|
||||
bool fImporting = false;
|
||||
bool fReindex = false;
|
||||
bool fBenchmark = false;
|
||||
bool fTxIndex = false;
|
||||
unsigned int nCoinCacheSize = 5000;
|
||||
|
||||
CMedianFilter<int> cPeerBlockCounts(8, 0); // Amount of blocks that other nodes claim to have
|
||||
@@ -949,6 +950,25 @@ bool GetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock
|
||||
}
|
||||
}
|
||||
|
||||
if (fTxIndex) {
|
||||
CDiskTxPos postx;
|
||||
if (pblocktree->ReadTxIndex(hash, postx)) {
|
||||
CAutoFile file(OpenBlockFile(postx, true), SER_DISK, CLIENT_VERSION);
|
||||
CBlockHeader header;
|
||||
try {
|
||||
file >> header;
|
||||
fseek(file, postx.nTxOffset, SEEK_CUR);
|
||||
file >> txOut;
|
||||
} catch (std::exception &e) {
|
||||
return error("%s() : deserialize or I/O error", __PRETTY_FUNCTION__);
|
||||
}
|
||||
hashBlock = header.GetHash();
|
||||
if (txOut.GetHash() != hash)
|
||||
return error("%s() : txid mismatch", __PRETTY_FUNCTION__);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (fAllowSlow) { // use coin database to locate block that contains transaction, and scan it
|
||||
int nHeight = -1;
|
||||
{
|
||||
@@ -1632,6 +1652,9 @@ bool CBlock::ConnectBlock(CBlockIndex* pindex, CCoinsViewCache &view, bool fJust
|
||||
int64 nFees = 0;
|
||||
int nInputs = 0;
|
||||
unsigned int nSigOps = 0;
|
||||
CDiskTxPos pos(pindex->GetBlockPos(), GetSizeOfCompactSize(vtx.size()));
|
||||
std::vector<std::pair<uint256, CDiskTxPos> > vPos;
|
||||
vPos.reserve(vtx.size());
|
||||
for (unsigned int i=0; i<vtx.size(); i++)
|
||||
{
|
||||
|
||||
@@ -1671,6 +1694,8 @@ bool CBlock::ConnectBlock(CBlockIndex* pindex, CCoinsViewCache &view, bool fJust
|
||||
if (!tx.IsCoinBase())
|
||||
blockundo.vtxundo.push_back(txundo);
|
||||
|
||||
vPos.push_back(std::make_pair(GetTxHash(i), pos));
|
||||
pos.nTxOffset += ::GetSerializeSize(tx, SER_DISK, CLIENT_VERSION);
|
||||
}
|
||||
int64 nTime = GetTimeMicros() - nStart;
|
||||
if (fBenchmark)
|
||||
@@ -1710,6 +1735,9 @@ bool CBlock::ConnectBlock(CBlockIndex* pindex, CCoinsViewCache &view, bool fJust
|
||||
return error("ConnectBlock() : WriteBlockIndex failed");
|
||||
}
|
||||
|
||||
if (fTxIndex)
|
||||
pblocktree->WriteTxIndex(vPos);
|
||||
|
||||
// add this block to the view's block chain
|
||||
if (!view.SetBestBlock(pindex))
|
||||
return false;
|
||||
@@ -2554,6 +2582,10 @@ bool static LoadBlockIndexDB()
|
||||
pblocktree->ReadReindexing(fReindexing);
|
||||
fReindex |= fReindexing;
|
||||
|
||||
// Check whether we have a transaction index
|
||||
pblocktree->ReadFlag("txindex", fTxIndex);
|
||||
printf("LoadBlockIndex(): transaction index %s\n", fTxIndex ? "enabled" : "disabled");
|
||||
|
||||
// Load hashBestChain pointer to end of best chain
|
||||
pindexBest = pcoinsTip->GetBestBlock();
|
||||
if (pindexBest == NULL)
|
||||
@@ -2658,13 +2690,10 @@ bool LoadBlockIndex()
|
||||
hashGenesisBlock = uint256("000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943");
|
||||
}
|
||||
|
||||
if (fReindex)
|
||||
return true;
|
||||
|
||||
//
|
||||
// Load block index from databases
|
||||
//
|
||||
if (!LoadBlockIndexDB())
|
||||
if (!fReindex && !LoadBlockIndexDB())
|
||||
return false;
|
||||
|
||||
//
|
||||
@@ -2672,6 +2701,13 @@ bool LoadBlockIndex()
|
||||
//
|
||||
if (mapBlockIndex.empty())
|
||||
{
|
||||
fTxIndex = GetBoolArg("-txindex", false);
|
||||
pblocktree->WriteFlag("txindex", fTxIndex);
|
||||
printf("Initializing databases...\n");
|
||||
|
||||
if (fReindex)
|
||||
return true;
|
||||
|
||||
// Genesis Block:
|
||||
// CBlock(hash=000000000019d6, ver=1, hashPrevBlock=00000000000000, hashMerkleRoot=4a5e1e, nTime=1231006505, nBits=1d00ffff, nNonce=2083236893, vtx=1)
|
||||
// CTransaction(hash=4a5e1e, ver=1, vin.size=1, vout.size=1, nLockTime=0)
|
||||
|
||||
Reference in New Issue
Block a user