aboutsummaryrefslogtreecommitdiff
path: root/src/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.cpp')
-rw-r--r--src/main.cpp76
1 files changed, 40 insertions, 36 deletions
diff --git a/src/main.cpp b/src/main.cpp
index e27b8444b..1df4c9fa3 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -965,47 +965,45 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
bool GetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock, bool fAllowSlow)
{
CBlockIndex *pindexSlow = NULL;
+
+ LOCK(cs_main);
+
+ if (mempool.lookup(hash, txOut))
{
- LOCK(cs_main);
- {
- if (mempool.lookup(hash, txOut))
- {
- return true;
- }
- }
+ return true;
+ }
- if (fTxIndex) {
- CDiskTxPos postx;
- if (pblocktree->ReadTxIndex(hash, postx)) {
- CAutoFile file(OpenBlockFile(postx, true), SER_DISK, CLIENT_VERSION);
- if (file.IsNull())
- return error("%s: OpenBlockFile failed", __func__);
- CBlockHeader header;
- try {
- file >> header;
- fseek(file.Get(), postx.nTxOffset, SEEK_CUR);
- file >> txOut;
- } catch (const std::exception& e) {
- return error("%s: Deserialize or I/O error - %s", __func__, e.what());
- }
- hashBlock = header.GetHash();
- if (txOut.GetHash() != hash)
- return error("%s: txid mismatch", __func__);
- return true;
+ if (fTxIndex) {
+ CDiskTxPos postx;
+ if (pblocktree->ReadTxIndex(hash, postx)) {
+ CAutoFile file(OpenBlockFile(postx, true), SER_DISK, CLIENT_VERSION);
+ if (file.IsNull())
+ return error("%s: OpenBlockFile failed", __func__);
+ CBlockHeader header;
+ try {
+ file >> header;
+ fseek(file.Get(), postx.nTxOffset, SEEK_CUR);
+ file >> txOut;
+ } catch (const std::exception& e) {
+ return error("%s: Deserialize or I/O error - %s", __func__, e.what());
}
+ hashBlock = header.GetHash();
+ if (txOut.GetHash() != hash)
+ return error("%s: txid mismatch", __func__);
+ return true;
}
+ }
- if (fAllowSlow) { // use coin database to locate block that contains transaction, and scan it
- int nHeight = -1;
- {
- CCoinsViewCache &view = *pcoinsTip;
- const CCoins* coins = view.AccessCoins(hash);
- if (coins)
- nHeight = coins->nHeight;
- }
- if (nHeight > 0)
- pindexSlow = chainActive[nHeight];
+ if (fAllowSlow) { // use coin database to locate block that contains transaction, and scan it
+ int nHeight = -1;
+ {
+ CCoinsViewCache &view = *pcoinsTip;
+ const CCoins* coins = view.AccessCoins(hash);
+ if (coins)
+ nHeight = coins->nHeight;
}
+ if (nHeight > 0)
+ pindexSlow = chainActive[nHeight];
}
if (pindexSlow) {
@@ -2585,6 +2583,9 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo
{
// These are checks that are independent of context.
+ if (block.fChecked)
+ return true;
+
// Check that the header is valid (particularly PoW). This is mostly
// redundant with the call in AcceptBlockHeader.
if (!CheckBlockHeader(block, state, fCheckPOW))
@@ -2593,7 +2594,7 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo
// Check the merkle root.
if (fCheckMerkleRoot) {
bool mutated;
- uint256 hashMerkleRoot2 = block.BuildMerkleTree(&mutated);
+ uint256 hashMerkleRoot2 = block.ComputeMerkleRoot(&mutated);
if (block.hashMerkleRoot != hashMerkleRoot2)
return state.DoS(100, error("CheckBlock(): hashMerkleRoot mismatch"),
REJECT_INVALID, "bad-txnmrklroot", true);
@@ -2640,6 +2641,9 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo
return state.DoS(100, error("CheckBlock(): out-of-bounds SigOpCount"),
REJECT_INVALID, "bad-blk-sigops", true);
+ if (fCheckPOW && fCheckMerkleRoot)
+ block.fChecked = true;
+
return true;
}