Skip to content

Commit 12781db

Browse files
committed
[Tests] check specific validation error in miner tests
BOOST_CHECK_THROW merely checks that some std::runtime_error is thrown, but not which one. One example of how this could lead to a test passing when a developer introduces a consensus bug: the test for the sigops limit assumes that CreateNewBlock fails with bad-blk-sigops. However it can also fail with bad-txns-vout-negative, e.g. if a naive developer lowers BLOCKSUBSIDY to 1*COIN in the test. BOOST_CHECK_EXCEPTION allows an additional predicate function. This commit uses this for all exceptions that are checked for in miner_tets.cpp: * bad-blk-sigops * bad-cb-multiple * bad-txns-inputs-missingorspent * block-validation-failed An instance of the CheckRejectInvalid class (for a given validation string) is passed to BOOST_CHECK_EXCEPTION.
1 parent f7388e9 commit 12781db

File tree

1 file changed

+19
-5
lines changed

1 file changed

+19
-5
lines changed

src/test/miner_tests.cpp

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,17 @@
2626

2727
BOOST_FIXTURE_TEST_SUITE(miner_tests, TestingSetup)
2828

29+
// BOOST_CHECK_EXCEPTION predicates to check the specific validation error
30+
class HasReason {
31+
public:
32+
HasReason(const std::string& reason) : m_reason(reason) {}
33+
bool operator() (const std::runtime_error& e) const {
34+
return std::string(e.what()).find(m_reason) != std::string::npos;
35+
};
36+
private:
37+
const std::string m_reason;
38+
};
39+
2940
static CFeeRate blockMinFeeRate = CFeeRate(DEFAULT_BLOCK_MIN_TX_FEE);
3041

3142
static BlockAssembler AssemblerForTest(const CChainParams& params) {
@@ -264,7 +275,8 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
264275
mempool.addUnchecked(hash, entry.Fee(LOWFEE).Time(GetTime()).SpendsCoinbase(spendsCoinbase).FromTx(tx));
265276
tx.vin[0].prevout.hash = hash;
266277
}
267-
BOOST_CHECK_THROW(AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey), std::runtime_error);
278+
279+
BOOST_CHECK_EXCEPTION(AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey), std::runtime_error, HasReason("bad-blk-sigops"));
268280
mempool.clear();
269281

270282
tx.vin[0].prevout.hash = txFirst[0]->GetHash();
@@ -304,7 +316,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
304316
// orphan in mempool, template creation fails
305317
hash = tx.GetHash();
306318
mempool.addUnchecked(hash, entry.Fee(LOWFEE).Time(GetTime()).FromTx(tx));
307-
BOOST_CHECK_THROW(AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey), std::runtime_error);
319+
BOOST_CHECK_EXCEPTION(AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey), std::runtime_error, HasReason("bad-txns-inputs-missingorspent"));
308320
mempool.clear();
309321

310322
// child with higher feerate than parent
@@ -332,7 +344,8 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
332344
hash = tx.GetHash();
333345
// give it a fee so it'll get mined
334346
mempool.addUnchecked(hash, entry.Fee(LOWFEE).Time(GetTime()).SpendsCoinbase(false).FromTx(tx));
335-
BOOST_CHECK_THROW(AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey), std::runtime_error);
347+
// Should throw bad-cb-multiple
348+
BOOST_CHECK_EXCEPTION(AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey), std::runtime_error, HasReason("bad-cb-multiple"));
336349
mempool.clear();
337350

338351
// double spend txn pair in mempool, template creation fails
@@ -345,7 +358,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
345358
tx.vout[0].scriptPubKey = CScript() << OP_2;
346359
hash = tx.GetHash();
347360
mempool.addUnchecked(hash, entry.Fee(HIGHFEE).Time(GetTime()).SpendsCoinbase(true).FromTx(tx));
348-
BOOST_CHECK_THROW(AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey), std::runtime_error);
361+
BOOST_CHECK_EXCEPTION(AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey), std::runtime_error, HasReason("bad-txns-inputs-missingorspent"));
349362
mempool.clear();
350363

351364
// subsidy changing
@@ -389,7 +402,8 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
389402
tx.vout[0].nValue -= LOWFEE;
390403
hash = tx.GetHash();
391404
mempool.addUnchecked(hash, entry.Fee(LOWFEE).Time(GetTime()).SpendsCoinbase(false).FromTx(tx));
392-
BOOST_CHECK_THROW(AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey), std::runtime_error);
405+
// Should throw block-validation-failed
406+
BOOST_CHECK_EXCEPTION(AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey), std::runtime_error, HasReason("block-validation-failed"));
393407
mempool.clear();
394408

395409
// Delete the dummy blocks again.

0 commit comments

Comments
 (0)