aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHennadii Stepanov <32963518+hebasto@users.noreply.github.com>2018-11-29 13:36:12 +0200
committerHennadii Stepanov <32963518+hebasto@users.noreply.github.com>2018-11-30 12:40:57 +0200
commitc5ed6e73d3e18f26558c49fa3ecb1b7b0bb40d12 (patch)
tree10ec3fe50820e371ba6de079d7a56ce091e88663
parent60b20c869f8df9a81b5080ebcbe8c9cf4e6b9d77 (diff)
Move CheckBlock() call to critical section
This prevents data race for CBlock::fChecked.
-rw-r--r--src/validation.cpp8
-rw-r--r--test/sanitizer_suppressions/tsan3
2 files changed, 5 insertions, 6 deletions
diff --git a/src/validation.cpp b/src/validation.cpp
index 6333dd98d2..512a3619ca 100644
--- a/src/validation.cpp
+++ b/src/validation.cpp
@@ -3530,12 +3530,14 @@ bool ProcessNewBlock(const CChainParams& chainparams, const std::shared_ptr<cons
CBlockIndex *pindex = nullptr;
if (fNewBlock) *fNewBlock = false;
CValidationState state;
- // Ensure that CheckBlock() passes before calling AcceptBlock, as
- // belt-and-suspenders.
- bool ret = CheckBlock(*pblock, state, chainparams.GetConsensus());
+ // CheckBlock() does not support multi-threaded block validation because CBlock::fChecked can cause data race.
+ // Therefore, the following critical section must include the CheckBlock() call as well.
LOCK(cs_main);
+ // Ensure that CheckBlock() passes before calling AcceptBlock, as
+ // belt-and-suspenders.
+ bool ret = CheckBlock(*pblock, state, chainparams.GetConsensus());
if (ret) {
// Store to disk
ret = g_chainstate.AcceptBlock(pblock, state, chainparams, &pindex, fForceProcessing, nullptr, fNewBlock);
diff --git a/test/sanitizer_suppressions/tsan b/test/sanitizer_suppressions/tsan
index 209c46f096..996f342eb9 100644
--- a/test/sanitizer_suppressions/tsan
+++ b/test/sanitizer_suppressions/tsan
@@ -1,9 +1,6 @@
# ThreadSanitizer suppressions
# ============================
-# fChecked is theoretically racy, practically only in unit tests
-race:CheckBlock
-
# WalletBatch (unidentified deadlock)
deadlock:WalletBatch