|
|
@ -45,6 +45,7 @@ int nScriptCheckThreads = 0; |
|
|
|
bool fImporting = false; |
|
|
|
bool fImporting = false; |
|
|
|
bool fReindex = false; |
|
|
|
bool fReindex = false; |
|
|
|
bool fBenchmark = false; |
|
|
|
bool fBenchmark = false; |
|
|
|
|
|
|
|
bool fTxIndex = false; |
|
|
|
unsigned int nCoinCacheSize = 5000; |
|
|
|
unsigned int nCoinCacheSize = 5000; |
|
|
|
|
|
|
|
|
|
|
|
CMedianFilter<int> cPeerBlockCounts(8, 0); // Amount of blocks that other nodes claim to have
|
|
|
|
CMedianFilter<int> cPeerBlockCounts(8, 0); // Amount of blocks that other nodes claim to have
|
|
|
@ -950,6 +951,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
|
|
|
|
if (fAllowSlow) { // use coin database to locate block that contains transaction, and scan it
|
|
|
|
int nHeight = -1; |
|
|
|
int nHeight = -1; |
|
|
|
{ |
|
|
|
{ |
|
|
@ -1641,6 +1661,9 @@ bool CBlock::ConnectBlock(CBlockIndex* pindex, CCoinsViewCache &view, bool fJust |
|
|
|
int64 nFees = 0; |
|
|
|
int64 nFees = 0; |
|
|
|
int nInputs = 0; |
|
|
|
int nInputs = 0; |
|
|
|
unsigned int nSigOps = 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++) |
|
|
|
for (unsigned int i=0; i<vtx.size(); i++) |
|
|
|
{ |
|
|
|
{ |
|
|
|
|
|
|
|
|
|
|
@ -1680,6 +1703,8 @@ bool CBlock::ConnectBlock(CBlockIndex* pindex, CCoinsViewCache &view, bool fJust |
|
|
|
if (!tx.IsCoinBase()) |
|
|
|
if (!tx.IsCoinBase()) |
|
|
|
blockundo.vtxundo.push_back(txundo); |
|
|
|
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; |
|
|
|
int64 nTime = GetTimeMicros() - nStart; |
|
|
|
if (fBenchmark) |
|
|
|
if (fBenchmark) |
|
|
@ -1719,6 +1744,9 @@ bool CBlock::ConnectBlock(CBlockIndex* pindex, CCoinsViewCache &view, bool fJust |
|
|
|
return error("ConnectBlock() : WriteBlockIndex failed"); |
|
|
|
return error("ConnectBlock() : WriteBlockIndex failed"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (fTxIndex) |
|
|
|
|
|
|
|
pblocktree->WriteTxIndex(vPos); |
|
|
|
|
|
|
|
|
|
|
|
// add this block to the view's block chain
|
|
|
|
// add this block to the view's block chain
|
|
|
|
if (!view.SetBestBlock(pindex)) |
|
|
|
if (!view.SetBestBlock(pindex)) |
|
|
|
return false; |
|
|
|
return false; |
|
|
@ -2548,6 +2576,10 @@ bool static LoadBlockIndexDB() |
|
|
|
pblocktree->ReadReindexing(fReindexing); |
|
|
|
pblocktree->ReadReindexing(fReindexing); |
|
|
|
fReindex |= 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
|
|
|
|
// Load hashBestChain pointer to end of best chain
|
|
|
|
pindexBest = pcoinsTip->GetBestBlock(); |
|
|
|
pindexBest = pcoinsTip->GetBestBlock(); |
|
|
|
if (pindexBest == NULL) |
|
|
|
if (pindexBest == NULL) |
|
|
@ -2652,13 +2684,10 @@ bool LoadBlockIndex() |
|
|
|
hashGenesisBlock = uint256("000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943"); |
|
|
|
hashGenesisBlock = uint256("000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (fReindex) |
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
//
|
|
|
|
// Load block index from databases
|
|
|
|
// Load block index from databases
|
|
|
|
//
|
|
|
|
//
|
|
|
|
if (!LoadBlockIndexDB()) |
|
|
|
if (!fReindex && !LoadBlockIndexDB()) |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
//
|
|
|
@ -2666,6 +2695,13 @@ bool LoadBlockIndex() |
|
|
|
//
|
|
|
|
//
|
|
|
|
if (mapBlockIndex.empty()) |
|
|
|
if (mapBlockIndex.empty()) |
|
|
|
{ |
|
|
|
{ |
|
|
|
|
|
|
|
fTxIndex = GetBoolArg("-txindex", false); |
|
|
|
|
|
|
|
pblocktree->WriteFlag("txindex", fTxIndex); |
|
|
|
|
|
|
|
printf("Initializing databases...\n"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (fReindex) |
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
|
|
|
|
// Genesis Block:
|
|
|
|
// Genesis Block:
|
|
|
|
// CBlock(hash=000000000019d6, ver=1, hashPrevBlock=00000000000000, hashMerkleRoot=4a5e1e, nTime=1231006505, nBits=1d00ffff, nNonce=2083236893, vtx=1)
|
|
|
|
// 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)
|
|
|
|
// CTransaction(hash=4a5e1e, ver=1, vin.size=1, vout.size=1, nLockTime=0)
|
|
|
|