diff options
Diffstat (limited to 'src/test')
-rw-r--r-- | src/test/README.md | 44 | ||||
-rw-r--r-- | src/test/data/script_tests.json | 7 | ||||
-rw-r--r-- | src/test/denialofservice_tests.cpp | 12 | ||||
-rw-r--r-- | src/test/merkle_tests.cpp | 100 | ||||
-rw-r--r-- | src/test/pow_tests.cpp | 54 | ||||
-rw-r--r-- | src/test/serialize_tests.cpp | 8 | ||||
-rw-r--r-- | src/test/streams_tests.cpp | 244 | ||||
-rw-r--r-- | src/test/txvalidationcache_tests.cpp | 20 | ||||
-rw-r--r-- | src/test/util_tests.cpp | 2 |
9 files changed, 455 insertions, 36 deletions
diff --git a/src/test/README.md b/src/test/README.md index 0017e3de26..96dcb072bc 100644 --- a/src/test/README.md +++ b/src/test/README.md @@ -1,3 +1,15 @@ +# Unit tests + +The sources in this directory are unit test cases. Boost includes a +unit testing framework, and since Bitcoin Core already uses Boost, it makes +sense to simply use this framework rather than require developers to +configure some other framework (we want as few impediments to creating +unit tests as possible). + +The build system is set up to compile an executable called `test_bitcoin` +that runs all of the unit tests. The main source file is called +`setup_common.cpp`. + ### Compiling/running unit tests Unit tests will be automatically compiled if dependencies were met in `./configure` @@ -12,7 +24,7 @@ to run the bitcoind tests. To add more bitcoind tests, add `BOOST_AUTO_TEST_CASE` functions to the existing .cpp files in the `test/` directory or add new .cpp files that -implement new BOOST_AUTO_TEST_SUITE sections. +implement new `BOOST_AUTO_TEST_SUITE` sections. To run the bitcoin-qt tests manually, launch `src/qt/test/test_bitcoin-qt` @@ -32,24 +44,24 @@ example, to run just the getarg_tests verbosely: Run `test_bitcoin --help` for the full list. -### Note on adding test cases +### Adding test cases -The sources in this directory are unit test cases. Boost includes a -unit testing framework, and since bitcoin already uses boost, it makes -sense to simply use this framework rather than require developers to -configure some other framework (we want as few impediments to creating -unit tests as possible). - -The build system is setup to compile an executable called `test_bitcoin` -that runs all of the unit tests. The main source file is called -setup_common.cpp. To add a new unit test file to our test suite you need +To add a new unit test file to our test suite you need to add the file to `src/Makefile.test.include`. The pattern is to create one test file for each class or source file for which you want to create -unit tests. The file naming convention is `<source_filename>_tests.cpp` +unit tests. The file naming convention is `<source_filename>_tests.cpp` and such files should wrap their tests in a test suite called `<source_filename>_tests`. For an example of this pattern, -examine `uint256_tests.cpp`. +see `uint256_tests.cpp`. + +### Logging and debugging in unit tests + +To write to logs from unit tests you need to use specific message methods +provided by Boost. The simplest is `BOOST_TEST_MESSAGE`. + +For debugging you can launch the test_bitcoin executable with `gdb`or `lldb` and +start debugging, just like you would with bitcoind: -For further reading, I found the following website to be helpful in -explaining how the boost unit test framework works: -[http://www.alittlemadness.com/2009/03/31/c-unit-testing-with-boosttest/](http://archive.is/dRBGf). +```bash +gdb src/test/test_bitcoin +``` diff --git a/src/test/data/script_tests.json b/src/test/data/script_tests.json index 9b320b6943..3241f32f56 100644 --- a/src/test/data/script_tests.json +++ b/src/test/data/script_tests.json @@ -829,15 +829,16 @@ ["NOP", "2SWAP 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], ["1", "2 3 2SWAP 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], + +["NOP", "SIZE 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], + +["TEST DISABLED OP CODES (CVE-2010-5137)"], ["'a' 'b'", "CAT", "P2SH,STRICTENC", "DISABLED_OPCODE", "CAT disabled"], ["'a' 'b' 0", "IF CAT ELSE 1 ENDIF", "P2SH,STRICTENC", "DISABLED_OPCODE", "CAT disabled"], ["'abc' 1 1", "SUBSTR", "P2SH,STRICTENC", "DISABLED_OPCODE", "SUBSTR disabled"], ["'abc' 1 1 0", "IF SUBSTR ELSE 1 ENDIF", "P2SH,STRICTENC", "DISABLED_OPCODE", "SUBSTR disabled"], ["'abc' 2 0", "IF LEFT ELSE 1 ENDIF", "P2SH,STRICTENC", "DISABLED_OPCODE", "LEFT disabled"], ["'abc' 2 0", "IF RIGHT ELSE 1 ENDIF", "P2SH,STRICTENC", "DISABLED_OPCODE", "RIGHT disabled"], - -["NOP", "SIZE 1", "P2SH,STRICTENC", "INVALID_STACK_OPERATION"], - ["'abc'", "IF INVERT ELSE 1 ENDIF", "P2SH,STRICTENC", "DISABLED_OPCODE", "INVERT disabled"], ["1 2 0 IF AND ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "DISABLED_OPCODE", "AND disabled"], ["1 2 0 IF OR ELSE 1 ENDIF", "NOP", "P2SH,STRICTENC", "DISABLED_OPCODE", "OR disabled"], diff --git a/src/test/denialofservice_tests.cpp b/src/test/denialofservice_tests.cpp index a50d6854f8..b0a613372f 100644 --- a/src/test/denialofservice_tests.cpp +++ b/src/test/denialofservice_tests.cpp @@ -151,17 +151,17 @@ BOOST_AUTO_TEST_CASE(stale_tip_peer_management) auto peerLogic = MakeUnique<PeerLogicValidation>(connman.get(), nullptr, scheduler, false); const Consensus::Params& consensusParams = Params().GetConsensus(); - constexpr int nMaxOutbound = 8; + constexpr int max_outbound_full_relay = 8; CConnman::Options options; options.nMaxConnections = 125; - options.nMaxOutbound = nMaxOutbound; + options.m_max_outbound_full_relay = max_outbound_full_relay; options.nMaxFeeler = 1; connman->Init(options); std::vector<CNode *> vNodes; // Mock some outbound peers - for (int i=0; i<nMaxOutbound; ++i) { + for (int i=0; i<max_outbound_full_relay; ++i) { AddRandomOutboundPeer(vNodes, *peerLogic, connman.get()); } @@ -190,7 +190,7 @@ BOOST_AUTO_TEST_CASE(stale_tip_peer_management) AddRandomOutboundPeer(vNodes, *peerLogic, connman.get()); peerLogic->CheckForStaleTipAndEvictPeers(consensusParams); - for (int i=0; i<nMaxOutbound; ++i) { + for (int i=0; i<max_outbound_full_relay; ++i) { BOOST_CHECK(vNodes[i]->fDisconnect == false); } // Last added node should get marked for eviction @@ -203,10 +203,10 @@ BOOST_AUTO_TEST_CASE(stale_tip_peer_management) UpdateLastBlockAnnounceTime(vNodes.back()->GetId(), GetTime()); peerLogic->CheckForStaleTipAndEvictPeers(consensusParams); - for (int i=0; i<nMaxOutbound-1; ++i) { + for (int i=0; i<max_outbound_full_relay-1; ++i) { BOOST_CHECK(vNodes[i]->fDisconnect == false); } - BOOST_CHECK(vNodes[nMaxOutbound-1]->fDisconnect == true); + BOOST_CHECK(vNodes[max_outbound_full_relay-1]->fDisconnect == true); BOOST_CHECK(vNodes.back()->fDisconnect == false); bool dummy; diff --git a/src/test/merkle_tests.cpp b/src/test/merkle_tests.cpp index 1684258c9f..dc38a1a818 100644 --- a/src/test/merkle_tests.cpp +++ b/src/test/merkle_tests.cpp @@ -249,4 +249,104 @@ BOOST_AUTO_TEST_CASE(merkle_test) } } + +BOOST_AUTO_TEST_CASE(merkle_test_empty_block) +{ + bool mutated = false; + CBlock block; + uint256 root = BlockMerkleRoot(block, &mutated); + + BOOST_CHECK_EQUAL(root.IsNull(), true); + BOOST_CHECK_EQUAL(mutated, false); +} + +BOOST_AUTO_TEST_CASE(merkle_test_oneTx_block) +{ + bool mutated = false; + CBlock block; + + block.vtx.resize(1); + CMutableTransaction mtx; + mtx.nLockTime = 0; + block.vtx[0] = MakeTransactionRef(std::move(mtx)); + uint256 root = BlockMerkleRoot(block, &mutated); + BOOST_CHECK_EQUAL(root, block.vtx[0]->GetHash()); + BOOST_CHECK_EQUAL(mutated, false); +} + +BOOST_AUTO_TEST_CASE(merkle_test_OddTxWithRepeatedLastTx_block) +{ + bool mutated; + CBlock block, blockWithRepeatedLastTx; + + block.vtx.resize(3); + + for (std::size_t pos = 0; pos < block.vtx.size(); pos++) { + CMutableTransaction mtx; + mtx.nLockTime = pos; + block.vtx[pos] = MakeTransactionRef(std::move(mtx)); + } + + blockWithRepeatedLastTx = block; + blockWithRepeatedLastTx.vtx.push_back(blockWithRepeatedLastTx.vtx.back()); + + uint256 rootofBlock = BlockMerkleRoot(block, &mutated); + BOOST_CHECK_EQUAL(mutated, false); + + uint256 rootofBlockWithRepeatedLastTx = BlockMerkleRoot(blockWithRepeatedLastTx, &mutated); + BOOST_CHECK_EQUAL(rootofBlock, rootofBlockWithRepeatedLastTx); + BOOST_CHECK_EQUAL(mutated, true); +} + +BOOST_AUTO_TEST_CASE(merkle_test_LeftSubtreeRightSubtree) +{ + CBlock block, leftSubtreeBlock, rightSubtreeBlock; + + block.vtx.resize(4); + std::size_t pos; + for (pos = 0; pos < block.vtx.size(); pos++) { + CMutableTransaction mtx; + mtx.nLockTime = pos; + block.vtx[pos] = MakeTransactionRef(std::move(mtx)); + } + + for (pos = 0; pos < block.vtx.size() / 2; pos++) + leftSubtreeBlock.vtx.push_back(block.vtx[pos]); + + for (pos = block.vtx.size() / 2; pos < block.vtx.size(); pos++) + rightSubtreeBlock.vtx.push_back(block.vtx[pos]); + + uint256 root = BlockMerkleRoot(block); + uint256 rootOfLeftSubtree = BlockMerkleRoot(leftSubtreeBlock); + uint256 rootOfRightSubtree = BlockMerkleRoot(rightSubtreeBlock); + std::vector<uint256> leftRight; + leftRight.push_back(rootOfLeftSubtree); + leftRight.push_back(rootOfRightSubtree); + uint256 rootOfLR = ComputeMerkleRoot(leftRight); + + BOOST_CHECK_EQUAL(root, rootOfLR); +} + +BOOST_AUTO_TEST_CASE(merkle_test_BlockWitness) +{ + CBlock block; + + block.vtx.resize(2); + for (std::size_t pos = 0; pos < block.vtx.size(); pos++) { + CMutableTransaction mtx; + mtx.nLockTime = pos; + block.vtx[pos] = MakeTransactionRef(std::move(mtx)); + } + + uint256 blockWitness = BlockWitnessMerkleRoot(block); + + std::vector<uint256> hashes; + hashes.resize(block.vtx.size()); + hashes[0].SetNull(); + hashes[1] = block.vtx[1]->GetHash(); + + uint256 merkelRootofHashes = ComputeMerkleRoot(hashes); + + BOOST_CHECK_EQUAL(merkelRootofHashes, blockWitness); +} BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/pow_tests.cpp b/src/test/pow_tests.cpp index 1123d4202c..deac349867 100644 --- a/src/test/pow_tests.cpp +++ b/src/test/pow_tests.cpp @@ -60,6 +60,60 @@ BOOST_AUTO_TEST_CASE(get_next_work_upper_limit_actual) BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime, chainParams->GetConsensus()), 0x1d00e1fdU); } +BOOST_AUTO_TEST_CASE(CheckProofOfWork_test_negative_target) +{ + const auto consensus = CreateChainParams(CBaseChainParams::MAIN)->GetConsensus(); + uint256 hash; + unsigned int nBits; + nBits = UintToArith256(consensus.powLimit).GetCompact(true); + hash.SetHex("0x1"); + BOOST_CHECK(!CheckProofOfWork(hash, nBits, consensus)); +} + +BOOST_AUTO_TEST_CASE(CheckProofOfWork_test_overflow_target) +{ + const auto consensus = CreateChainParams(CBaseChainParams::MAIN)->GetConsensus(); + uint256 hash; + unsigned int nBits = ~0x00800000; + hash.SetHex("0x1"); + BOOST_CHECK(!CheckProofOfWork(hash, nBits, consensus)); +} + +BOOST_AUTO_TEST_CASE(CheckProofOfWork_test_too_easy_target) +{ + const auto consensus = CreateChainParams(CBaseChainParams::MAIN)->GetConsensus(); + uint256 hash; + unsigned int nBits; + arith_uint256 nBits_arith = UintToArith256(consensus.powLimit); + nBits_arith *= 2; + nBits = nBits_arith.GetCompact(); + hash.SetHex("0x1"); + BOOST_CHECK(!CheckProofOfWork(hash, nBits, consensus)); +} + +BOOST_AUTO_TEST_CASE(CheckProofOfWork_test_biger_hash_than_target) +{ + const auto consensus = CreateChainParams(CBaseChainParams::MAIN)->GetConsensus(); + uint256 hash; + unsigned int nBits; + arith_uint256 hash_arith = UintToArith256(consensus.powLimit); + nBits = hash_arith.GetCompact(); + hash_arith *= 2; // hash > nBits + hash = ArithToUint256(hash_arith); + BOOST_CHECK(!CheckProofOfWork(hash, nBits, consensus)); +} + +BOOST_AUTO_TEST_CASE(CheckProofOfWork_test_zero_target) +{ + const auto consensus = CreateChainParams(CBaseChainParams::MAIN)->GetConsensus(); + uint256 hash; + unsigned int nBits; + arith_uint256 hash_arith{0}; + nBits = hash_arith.GetCompact(); + hash = ArithToUint256(hash_arith); + BOOST_CHECK(!CheckProofOfWork(hash, nBits, consensus)); +} + BOOST_AUTO_TEST_CASE(GetBlockProofEquivalentTime_test) { const auto chainParams = CreateChainParams(CBaseChainParams::MAIN); diff --git a/src/test/serialize_tests.cpp b/src/test/serialize_tests.cpp index 8a8620938e..b90be15fba 100644 --- a/src/test/serialize_tests.cpp +++ b/src/test/serialize_tests.cpp @@ -258,6 +258,14 @@ static bool isCanonicalException(const std::ios_base::failure& ex) return strcmp(expectedException.what(), ex.what()) == 0; } +BOOST_AUTO_TEST_CASE(vector_bool) +{ + std::vector<uint8_t> vec1{1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1}; + std::vector<bool> vec2{1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1}; + + BOOST_CHECK(vec1 == std::vector<uint8_t>(vec2.begin(), vec2.end())); + BOOST_CHECK(SerializeHash(vec1) == SerializeHash(vec2)); +} BOOST_AUTO_TEST_CASE(noncanonical) { diff --git a/src/test/streams_tests.cpp b/src/test/streams_tests.cpp index b812cef801..638819d564 100644 --- a/src/test/streams_tests.cpp +++ b/src/test/streams_tests.cpp @@ -2,6 +2,7 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include <random.h> #include <streams.h> #include <test/setup_common.h> @@ -202,4 +203,247 @@ BOOST_AUTO_TEST_CASE(streams_serializedata_xor) std::string(ds.begin(), ds.end())); } +BOOST_AUTO_TEST_CASE(streams_buffered_file) +{ + FILE* file = fsbridge::fopen("streams_test_tmp", "w+b"); + // The value at each offset is the offset. + for (uint8_t j = 0; j < 40; ++j) { + fwrite(&j, 1, 1, file); + } + rewind(file); + + // The buffer size (second arg) must be greater than the rewind + // amount (third arg). + try { + CBufferedFile bfbad(file, 25, 25, 222, 333); + BOOST_CHECK(false); + } catch (const std::exception& e) { + BOOST_CHECK(strstr(e.what(), + "Rewind limit must be less than buffer size") != nullptr); + } + + // The buffer is 25 bytes, allow rewinding 10 bytes. + CBufferedFile bf(file, 25, 10, 222, 333); + BOOST_CHECK(!bf.eof()); + + // These two members have no functional effect. + BOOST_CHECK_EQUAL(bf.GetType(), 222); + BOOST_CHECK_EQUAL(bf.GetVersion(), 333); + + uint8_t i; + bf >> i; + BOOST_CHECK_EQUAL(i, 0); + bf >> i; + BOOST_CHECK_EQUAL(i, 1); + + // After reading bytes 0 and 1, we're positioned at 2. + BOOST_CHECK_EQUAL(bf.GetPos(), 2); + + // Rewind to offset 0, ok (within the 10 byte window). + BOOST_CHECK(bf.SetPos(0)); + bf >> i; + BOOST_CHECK_EQUAL(i, 0); + + // We can go forward to where we've been, but beyond may fail. + BOOST_CHECK(bf.SetPos(2)); + bf >> i; + BOOST_CHECK_EQUAL(i, 2); + + // If you know the maximum number of bytes that should be + // read to deserialize the variable, you can limit the read + // extent. The current file offset is 3, so the following + // SetLimit() allows zero bytes to be read. + BOOST_CHECK(bf.SetLimit(3)); + try { + bf >> i; + BOOST_CHECK(false); + } catch (const std::exception& e) { + BOOST_CHECK(strstr(e.what(), + "Read attempted past buffer limit") != nullptr); + } + // The default argument removes the limit completely. + BOOST_CHECK(bf.SetLimit()); + // The read position should still be at 3 (no change). + BOOST_CHECK_EQUAL(bf.GetPos(), 3); + + // Read from current offset, 3, forward until position 10. + for (uint8_t j = 3; j < 10; ++j) { + bf >> i; + BOOST_CHECK_EQUAL(i, j); + } + BOOST_CHECK_EQUAL(bf.GetPos(), 10); + + // We're guaranteed (just barely) to be able to rewind to zero. + BOOST_CHECK(bf.SetPos(0)); + BOOST_CHECK_EQUAL(bf.GetPos(), 0); + bf >> i; + BOOST_CHECK_EQUAL(i, 0); + + // We can set the position forward again up to the farthest + // into the stream we've been, but no farther. (Attempting + // to go farther may succeed, but it's not guaranteed.) + BOOST_CHECK(bf.SetPos(10)); + bf >> i; + BOOST_CHECK_EQUAL(i, 10); + BOOST_CHECK_EQUAL(bf.GetPos(), 11); + + // Now it's only guaranteed that we can rewind to offset 1 + // (current read position, 11, minus rewind amount, 10). + BOOST_CHECK(bf.SetPos(1)); + BOOST_CHECK_EQUAL(bf.GetPos(), 1); + bf >> i; + BOOST_CHECK_EQUAL(i, 1); + + // We can stream into large variables, even larger than + // the buffer size. + BOOST_CHECK(bf.SetPos(11)); + { + uint8_t a[40 - 11]; + bf >> a; + for (uint8_t j = 0; j < sizeof(a); ++j) { + BOOST_CHECK_EQUAL(a[j], 11 + j); + } + } + BOOST_CHECK_EQUAL(bf.GetPos(), 40); + + // We've read the entire file, the next read should throw. + try { + bf >> i; + BOOST_CHECK(false); + } catch (const std::exception& e) { + BOOST_CHECK(strstr(e.what(), + "CBufferedFile::Fill: end of file") != nullptr); + } + // Attempting to read beyond the end sets the EOF indicator. + BOOST_CHECK(bf.eof()); + + // Still at offset 40, we can go back 10, to 30. + BOOST_CHECK_EQUAL(bf.GetPos(), 40); + BOOST_CHECK(bf.SetPos(30)); + bf >> i; + BOOST_CHECK_EQUAL(i, 30); + BOOST_CHECK_EQUAL(bf.GetPos(), 31); + + // We're too far to rewind to position zero. + BOOST_CHECK(!bf.SetPos(0)); + // But we should now be positioned at least as far back as allowed + // by the rewind window (relative to our farthest read position, 40). + BOOST_CHECK(bf.GetPos() <= 30); + + // We can explicitly close the file, or the destructor will do it. + bf.fclose(); + + fs::remove("streams_test_tmp"); +} + +BOOST_AUTO_TEST_CASE(streams_buffered_file_rand) +{ + // Make this test deterministic. + SeedInsecureRand(true); + + for (int rep = 0; rep < 50; ++rep) { + FILE* file = fsbridge::fopen("streams_test_tmp", "w+b"); + size_t fileSize = InsecureRandRange(256); + for (uint8_t i = 0; i < fileSize; ++i) { + fwrite(&i, 1, 1, file); + } + rewind(file); + + size_t bufSize = InsecureRandRange(300) + 1; + size_t rewindSize = InsecureRandRange(bufSize); + CBufferedFile bf(file, bufSize, rewindSize, 222, 333); + size_t currentPos = 0; + size_t maxPos = 0; + for (int step = 0; step < 100; ++step) { + if (currentPos >= fileSize) + break; + + // We haven't read to the end of the file yet. + BOOST_CHECK(!bf.eof()); + BOOST_CHECK_EQUAL(bf.GetPos(), currentPos); + + // Pretend the file consists of a series of objects of varying + // sizes; the boundaries of the objects can interact arbitrarily + // with the CBufferFile's internal buffer. These first three + // cases simulate objects of various sizes (1, 2, 5 bytes). + switch (InsecureRandRange(5)) { + case 0: { + uint8_t a[1]; + if (currentPos + 1 > fileSize) + continue; + bf.SetLimit(currentPos + 1); + bf >> a; + for (uint8_t i = 0; i < 1; ++i) { + BOOST_CHECK_EQUAL(a[i], currentPos); + currentPos++; + } + break; + } + case 1: { + uint8_t a[2]; + if (currentPos + 2 > fileSize) + continue; + bf.SetLimit(currentPos + 2); + bf >> a; + for (uint8_t i = 0; i < 2; ++i) { + BOOST_CHECK_EQUAL(a[i], currentPos); + currentPos++; + } + break; + } + case 2: { + uint8_t a[5]; + if (currentPos + 5 > fileSize) + continue; + bf.SetLimit(currentPos + 5); + bf >> a; + for (uint8_t i = 0; i < 5; ++i) { + BOOST_CHECK_EQUAL(a[i], currentPos); + currentPos++; + } + break; + } + case 3: { + // Find a byte value (that is at or ahead of the current position). + size_t find = currentPos + InsecureRandRange(8); + if (find >= fileSize) + find = fileSize - 1; + bf.FindByte(static_cast<char>(find)); + // The value at each offset is the offset. + BOOST_CHECK_EQUAL(bf.GetPos(), find); + currentPos = find; + + bf.SetLimit(currentPos + 1); + uint8_t i; + bf >> i; + BOOST_CHECK_EQUAL(i, currentPos); + currentPos++; + break; + } + case 4: { + size_t requestPos = InsecureRandRange(maxPos + 4); + bool okay = bf.SetPos(requestPos); + // The new position may differ from the requested position + // because we may not be able to rewind beyond the rewind + // window, and we may not be able to move forward beyond the + // farthest position we've reached so far. + currentPos = bf.GetPos(); + BOOST_CHECK_EQUAL(okay, currentPos == requestPos); + // Check that we can position within the rewind window. + if (requestPos <= maxPos && + maxPos > rewindSize && + requestPos >= maxPos - rewindSize) { + // We requested a position within the rewind window. + BOOST_CHECK(okay); + } + break; + } + } + if (maxPos < currentPos) + maxPos = currentPos; + } + } + fs::remove("streams_test_tmp"); +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/txvalidationcache_tests.cpp b/src/test/txvalidationcache_tests.cpp index e69ebcc2c3..193858cca9 100644 --- a/src/test/txvalidationcache_tests.cpp +++ b/src/test/txvalidationcache_tests.cpp @@ -13,7 +13,7 @@ #include <boost/test/unit_test.hpp> -bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsViewCache &inputs, bool fScriptChecks, unsigned int flags, bool cacheSigStore, bool cacheFullScriptStore, PrecomputedTransactionData& txdata, std::vector<CScriptCheck> *pvChecks); +bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsViewCache &inputs, unsigned int flags, bool cacheSigStore, bool cacheFullScriptStore, PrecomputedTransactionData& txdata, std::vector<CScriptCheck> *pvChecks); BOOST_AUTO_TEST_SUITE(tx_validationcache_tests) @@ -125,7 +125,7 @@ static void ValidateCheckInputsForAllFlags(const CTransaction &tx, uint32_t fail // WITNESS requires P2SH test_flags |= SCRIPT_VERIFY_P2SH; } - bool ret = CheckInputs(tx, state, &::ChainstateActive().CoinsTip(), true, test_flags, true, add_to_cache, txdata, nullptr); + bool ret = CheckInputs(tx, state, &::ChainstateActive().CoinsTip(), test_flags, true, add_to_cache, txdata, nullptr); // CheckInputs should succeed iff test_flags doesn't intersect with // failing_flags bool expected_return_value = !(test_flags & failing_flags); @@ -135,13 +135,13 @@ static void ValidateCheckInputsForAllFlags(const CTransaction &tx, uint32_t fail if (ret && add_to_cache) { // Check that we get a cache hit if the tx was valid std::vector<CScriptCheck> scriptchecks; - BOOST_CHECK(CheckInputs(tx, state, &::ChainstateActive().CoinsTip(), true, test_flags, true, add_to_cache, txdata, &scriptchecks)); + BOOST_CHECK(CheckInputs(tx, state, &::ChainstateActive().CoinsTip(), test_flags, true, add_to_cache, txdata, &scriptchecks)); BOOST_CHECK(scriptchecks.empty()); } else { // Check that we get script executions to check, if the transaction // was invalid, or we didn't add to cache. std::vector<CScriptCheck> scriptchecks; - BOOST_CHECK(CheckInputs(tx, state, &::ChainstateActive().CoinsTip(), true, test_flags, true, add_to_cache, txdata, &scriptchecks)); + BOOST_CHECK(CheckInputs(tx, state, &::ChainstateActive().CoinsTip(), test_flags, true, add_to_cache, txdata, &scriptchecks)); BOOST_CHECK_EQUAL(scriptchecks.size(), tx.vin.size()); } } @@ -204,13 +204,13 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup) CValidationState state; PrecomputedTransactionData ptd_spend_tx(spend_tx); - BOOST_CHECK(!CheckInputs(CTransaction(spend_tx), state, &::ChainstateActive().CoinsTip(), true, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_DERSIG, true, true, ptd_spend_tx, nullptr)); + BOOST_CHECK(!CheckInputs(CTransaction(spend_tx), state, &::ChainstateActive().CoinsTip(), SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_DERSIG, true, true, ptd_spend_tx, nullptr)); // If we call again asking for scriptchecks (as happens in // ConnectBlock), we should add a script check object for this -- we're // not caching invalidity (if that changes, delete this test case). std::vector<CScriptCheck> scriptchecks; - BOOST_CHECK(CheckInputs(CTransaction(spend_tx), state, &::ChainstateActive().CoinsTip(), true, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_DERSIG, true, true, ptd_spend_tx, &scriptchecks)); + BOOST_CHECK(CheckInputs(CTransaction(spend_tx), state, &::ChainstateActive().CoinsTip(), SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_DERSIG, true, true, ptd_spend_tx, &scriptchecks)); BOOST_CHECK_EQUAL(scriptchecks.size(), 1U); // Test that CheckInputs returns true iff DERSIG-enforcing flags are @@ -272,7 +272,7 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup) invalid_with_cltv_tx.vin[0].scriptSig = CScript() << vchSig << 100; CValidationState state; PrecomputedTransactionData txdata(invalid_with_cltv_tx); - BOOST_CHECK(CheckInputs(CTransaction(invalid_with_cltv_tx), state, ::ChainstateActive().CoinsTip(), true, SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY, true, true, txdata, nullptr)); + BOOST_CHECK(CheckInputs(CTransaction(invalid_with_cltv_tx), state, ::ChainstateActive().CoinsTip(), SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY, true, true, txdata, nullptr)); } // TEST CHECKSEQUENCEVERIFY @@ -300,7 +300,7 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup) invalid_with_csv_tx.vin[0].scriptSig = CScript() << vchSig << 100; CValidationState state; PrecomputedTransactionData txdata(invalid_with_csv_tx); - BOOST_CHECK(CheckInputs(CTransaction(invalid_with_csv_tx), state, &::ChainstateActive().CoinsTip(), true, SCRIPT_VERIFY_CHECKSEQUENCEVERIFY, true, true, txdata, nullptr)); + BOOST_CHECK(CheckInputs(CTransaction(invalid_with_csv_tx), state, &::ChainstateActive().CoinsTip(), SCRIPT_VERIFY_CHECKSEQUENCEVERIFY, true, true, txdata, nullptr)); } // TODO: add tests for remaining script flags @@ -362,12 +362,12 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup) CValidationState state; PrecomputedTransactionData txdata(tx); // This transaction is now invalid under segwit, because of the second input. - BOOST_CHECK(!CheckInputs(CTransaction(tx), state, &::ChainstateActive().CoinsTip(), true, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, true, true, txdata, nullptr)); + BOOST_CHECK(!CheckInputs(CTransaction(tx), state, &::ChainstateActive().CoinsTip(), SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, true, true, txdata, nullptr)); std::vector<CScriptCheck> scriptchecks; // Make sure this transaction was not cached (ie because the first // input was valid) - BOOST_CHECK(CheckInputs(CTransaction(tx), state, &::ChainstateActive().CoinsTip(), true, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, true, true, txdata, &scriptchecks)); + BOOST_CHECK(CheckInputs(CTransaction(tx), state, &::ChainstateActive().CoinsTip(), SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, true, true, txdata, &scriptchecks)); // Should get 2 script checks back -- caching is on a whole-transaction basis. BOOST_CHECK_EQUAL(scriptchecks.size(), 2U); } diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp index 65cb956fbe..d0cd4b0a03 100644 --- a/src/test/util_tests.cpp +++ b/src/test/util_tests.cpp @@ -913,7 +913,7 @@ BOOST_FIXTURE_TEST_CASE(util_ChainMerge, ChainMergeTestingSetup) // Results file is formatted like: // // <input> || <output> - BOOST_CHECK_EQUAL(out_sha_hex, "b284f4b4a15dd6bf8c06213a69a004b1960388e1d9917173927db52ac220927f"); + BOOST_CHECK_EQUAL(out_sha_hex, "94b4ad55c8ac639a56b93e36f7e32e4c611fd7d7dd7b2be6a71707b1eadcaec7"); } BOOST_AUTO_TEST_CASE(util_FormatMoney) |