mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-06-14 08:39:35 +02:00
Merge #11824: Block ActivateBestChain to empty validationinterface queue
97d2b09c12Add helper to wait for validation interface queue to catch up (Matt Corallo)36137497f1Block ActivateBestChain to empty validationinterface queue (Matt Corallo)5a933cefccAdd an interface to get the queue depth out of CValidationInterface (Matt Corallo)a99b76f269Require no cs_main lock for ProcessNewBlock/ActivateBestChain (Matt Corallo)a734896038Avoid cs_main in net_processing ActivateBestChain calls (Matt Corallo)66aa1d58a1Refactor ProcessGetData in anticipation of avoiding cs_main for ABC (Matt Corallo)818075adacCreate new mutex for orphans, no cs_main in PLV::BlockConnected (Matt Corallo) Pull request description: This should fix #11822. It ended up bigger than I hoped for, but its not too gnarly. Note that " Require no cs_main lock for ProcessNewBlock/ActivateBestChain" is mostly pure code-movement. Tree-SHA512: 1127688545926f6099449dca6a4e6609eefc3abbd72f1c66e03d32bd8c7b31e82097d8307822cfd1dec0321703579cfdd82069cab6e17b1024e75eac694122cb
This commit is contained in:
@@ -216,7 +216,6 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
|
||||
entry.nFee = 11;
|
||||
entry.nHeight = 11;
|
||||
|
||||
LOCK(cs_main);
|
||||
fCheckpointsEnabled = false;
|
||||
|
||||
// Simple block creation, nothing special yet:
|
||||
@@ -229,27 +228,32 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
|
||||
for (unsigned int i = 0; i < sizeof(blockinfo)/sizeof(*blockinfo); ++i)
|
||||
{
|
||||
CBlock *pblock = &pblocktemplate->block; // pointer for convenience
|
||||
pblock->nVersion = 1;
|
||||
pblock->nTime = chainActive.Tip()->GetMedianTimePast()+1;
|
||||
CMutableTransaction txCoinbase(*pblock->vtx[0]);
|
||||
txCoinbase.nVersion = 1;
|
||||
txCoinbase.vin[0].scriptSig = CScript();
|
||||
txCoinbase.vin[0].scriptSig.push_back(blockinfo[i].extranonce);
|
||||
txCoinbase.vin[0].scriptSig.push_back(chainActive.Height());
|
||||
txCoinbase.vout.resize(1); // Ignore the (optional) segwit commitment added by CreateNewBlock (as the hardcoded nonces don't account for this)
|
||||
txCoinbase.vout[0].scriptPubKey = CScript();
|
||||
pblock->vtx[0] = MakeTransactionRef(std::move(txCoinbase));
|
||||
if (txFirst.size() == 0)
|
||||
baseheight = chainActive.Height();
|
||||
if (txFirst.size() < 4)
|
||||
txFirst.push_back(pblock->vtx[0]);
|
||||
pblock->hashMerkleRoot = BlockMerkleRoot(*pblock);
|
||||
pblock->nNonce = blockinfo[i].nonce;
|
||||
{
|
||||
LOCK(cs_main);
|
||||
pblock->nVersion = 1;
|
||||
pblock->nTime = chainActive.Tip()->GetMedianTimePast()+1;
|
||||
CMutableTransaction txCoinbase(*pblock->vtx[0]);
|
||||
txCoinbase.nVersion = 1;
|
||||
txCoinbase.vin[0].scriptSig = CScript();
|
||||
txCoinbase.vin[0].scriptSig.push_back(blockinfo[i].extranonce);
|
||||
txCoinbase.vin[0].scriptSig.push_back(chainActive.Height());
|
||||
txCoinbase.vout.resize(1); // Ignore the (optional) segwit commitment added by CreateNewBlock (as the hardcoded nonces don't account for this)
|
||||
txCoinbase.vout[0].scriptPubKey = CScript();
|
||||
pblock->vtx[0] = MakeTransactionRef(std::move(txCoinbase));
|
||||
if (txFirst.size() == 0)
|
||||
baseheight = chainActive.Height();
|
||||
if (txFirst.size() < 4)
|
||||
txFirst.push_back(pblock->vtx[0]);
|
||||
pblock->hashMerkleRoot = BlockMerkleRoot(*pblock);
|
||||
pblock->nNonce = blockinfo[i].nonce;
|
||||
}
|
||||
std::shared_ptr<const CBlock> shared_pblock = std::make_shared<const CBlock>(*pblock);
|
||||
BOOST_CHECK(ProcessNewBlock(chainparams, shared_pblock, true, nullptr));
|
||||
pblock->hashPrevBlock = pblock->GetHash();
|
||||
}
|
||||
|
||||
LOCK(cs_main);
|
||||
|
||||
// Just to make sure we can still make simple blocks
|
||||
BOOST_CHECK(pblocktemplate = AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey));
|
||||
|
||||
|
||||
@@ -69,9 +69,9 @@ TestingSetup::TestingSetup(const std::string& chainName) : BasicTestingSetup(cha
|
||||
fs::create_directories(pathTemp);
|
||||
gArgs.ForceSetArg("-datadir", pathTemp.string());
|
||||
|
||||
// Note that because we don't bother running a scheduler thread here,
|
||||
// callbacks via CValidationInterface are unreliable, but that's OK,
|
||||
// our unit tests aren't testing multiple parts of the code at once.
|
||||
// We have to run a scheduler thread to prevent ActivateBestChain
|
||||
// from blocking due to queue overrun.
|
||||
threadGroup.create_thread(boost::bind(&CScheduler::serviceQueue, &scheduler));
|
||||
GetMainSignals().RegisterBackgroundSignalScheduler(scheduler);
|
||||
|
||||
mempool.setSanityCheck(1.0);
|
||||
|
||||
@@ -66,7 +66,6 @@ BOOST_FIXTURE_TEST_CASE(tx_mempool_block_doublespend, TestChain100Setup)
|
||||
|
||||
// Test 1: block with both of those transactions should be rejected.
|
||||
block = CreateAndProcessBlock(spends, scriptPubKey);
|
||||
LOCK(cs_main);
|
||||
BOOST_CHECK(chainActive.Tip()->GetBlockHash() != block.GetHash());
|
||||
|
||||
// Test 2: ... and should be rejected if spend1 is in the memory pool
|
||||
@@ -190,12 +189,12 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup)
|
||||
spend_tx.vin[0].scriptSig << vchSig;
|
||||
}
|
||||
|
||||
LOCK(cs_main);
|
||||
|
||||
// Test that invalidity under a set of flags doesn't preclude validity
|
||||
// under other (eg consensus) flags.
|
||||
// spend_tx is invalid according to DERSIG
|
||||
{
|
||||
LOCK(cs_main);
|
||||
|
||||
CValidationState state;
|
||||
PrecomputedTransactionData ptd_spend_tx(spend_tx);
|
||||
|
||||
@@ -213,16 +212,18 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup)
|
||||
// test later that block validation works fine in the absence of cached
|
||||
// successes.
|
||||
ValidateCheckInputsForAllFlags(spend_tx, SCRIPT_VERIFY_DERSIG | SCRIPT_VERIFY_LOW_S | SCRIPT_VERIFY_STRICTENC, false);
|
||||
|
||||
// And if we produce a block with this tx, it should be valid (DERSIG not
|
||||
// enabled yet), even though there's no cache entry.
|
||||
CBlock block;
|
||||
|
||||
block = CreateAndProcessBlock({spend_tx}, p2pk_scriptPubKey);
|
||||
BOOST_CHECK(chainActive.Tip()->GetBlockHash() == block.GetHash());
|
||||
BOOST_CHECK(pcoinsTip->GetBestBlock() == block.GetHash());
|
||||
}
|
||||
|
||||
// And if we produce a block with this tx, it should be valid (DERSIG not
|
||||
// enabled yet), even though there's no cache entry.
|
||||
CBlock block;
|
||||
|
||||
block = CreateAndProcessBlock({spend_tx}, p2pk_scriptPubKey);
|
||||
BOOST_CHECK(chainActive.Tip()->GetBlockHash() == block.GetHash());
|
||||
BOOST_CHECK(pcoinsTip->GetBestBlock() == block.GetHash());
|
||||
|
||||
LOCK(cs_main);
|
||||
|
||||
// Test P2SH: construct a transaction that is valid without P2SH, and
|
||||
// then test validity with P2SH.
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user