diff options
author | Alex Morcos <morcos@chaincode.com> | 2015-09-17 17:43:34 -0400 |
---|---|---|
committer | Luke Dashjr <luke-jr+git@utopios.org> | 2015-10-14 08:20:36 +0000 |
commit | 01878c9c3f42961b8fb1356105b7b90abbce1c9d (patch) | |
tree | 1ae9c99b861379e707dffb90ec3580cadcd136da /src | |
parent | 9b9acc27d2ea91223177bc2509568721334af178 (diff) | |
download | bitcoin-01878c9c3f42961b8fb1356105b7b90abbce1c9d.tar.xz |
Fix locking in GetTransaction.
GetTransaction needs to lock cs_main until ReadBlockFromDisk completes, the data inside CBlockIndex's can change since pruning. This lock was held by all calls to GetTransaction except rest_tx.
Diffstat (limited to 'src')
-rw-r--r-- | src/main.cpp | 68 |
1 files changed, 33 insertions, 35 deletions
diff --git a/src/main.cpp b/src/main.cpp index f6deaa29b6..77d9227f5c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1092,47 +1092,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) { |