LCOV - code coverage report
Current view: top level - src/test - blockencodings_tests.cpp (source / functions) Hit Total Coverage
Test: fuzz_coverage.info Lines: 0 254 0.0 %
Date: 2023-10-05 12:38:51 Functions: 0 53 0.0 %
Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : // Copyright (c) 2011-2022 The Bitcoin Core developers
       2                 :            : // Distributed under the MIT software license, see the accompanying
       3                 :            : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
       4                 :            : 
       5                 :            : #include <blockencodings.h>
       6                 :            : #include <chainparams.h>
       7                 :            : #include <consensus/merkle.h>
       8                 :            : #include <pow.h>
       9                 :            : #include <streams.h>
      10                 :            : #include <test/util/random.h>
      11                 :            : #include <test/util/txmempool.h>
      12                 :            : 
      13                 :            : #include <test/util/setup_common.h>
      14                 :            : 
      15                 :            : #include <boost/test/unit_test.hpp>
      16                 :            : 
      17                 :          0 : std::vector<std::pair<uint256, CTransactionRef>> extra_txn;
      18                 :          0 : 
      19                 :          0 : BOOST_FIXTURE_TEST_SUITE(blockencodings_tests, RegTestingSetup)
      20                 :            : 
      21                 :          0 : static CBlock BuildBlockTestCase() {
      22                 :          0 :     CBlock block;
      23                 :          0 :     CMutableTransaction tx;
      24                 :          0 :     tx.vin.resize(1);
      25                 :          0 :     tx.vin[0].scriptSig.resize(10);
      26                 :          0 :     tx.vout.resize(1);
      27                 :          0 :     tx.vout[0].nValue = 42;
      28                 :            : 
      29                 :          0 :     block.vtx.resize(3);
      30                 :          0 :     block.vtx[0] = MakeTransactionRef(tx);
      31                 :          0 :     block.nVersion = 42;
      32                 :          0 :     block.hashPrevBlock = InsecureRand256();
      33                 :          0 :     block.nBits = 0x207fffff;
      34                 :            : 
      35                 :          0 :     tx.vin[0].prevout.hash = InsecureRand256();
      36                 :          0 :     tx.vin[0].prevout.n = 0;
      37                 :          0 :     block.vtx[1] = MakeTransactionRef(tx);
      38                 :            : 
      39                 :          0 :     tx.vin.resize(10);
      40                 :          0 :     for (size_t i = 0; i < tx.vin.size(); i++) {
      41                 :          0 :         tx.vin[i].prevout.hash = InsecureRand256();
      42                 :          0 :         tx.vin[i].prevout.n = 0;
      43                 :          0 :     }
      44                 :          0 :     block.vtx[2] = MakeTransactionRef(tx);
      45                 :            : 
      46                 :            :     bool mutated;
      47                 :          0 :     block.hashMerkleRoot = BlockMerkleRoot(block, &mutated);
      48                 :          0 :     assert(!mutated);
      49                 :          0 :     while (!CheckProofOfWork(block.GetHash(), block.nBits, Params().GetConsensus())) ++block.nNonce;
      50                 :          0 :     return block;
      51                 :          0 : }
      52                 :            : 
      53                 :            : // Number of shared use_counts we expect for a tx we haven't touched
      54                 :            : // (block + mempool + our copy from the GetSharedTx call)
      55                 :            : constexpr long SHARED_TX_OFFSET{3};
      56                 :            : 
      57                 :          0 : BOOST_AUTO_TEST_CASE(SimpleRoundTripTest)
      58                 :            : {
      59                 :          0 :     CTxMemPool& pool = *Assert(m_node.mempool);
      60                 :          0 :     TestMemPoolEntryHelper entry;
      61                 :          0 :     CBlock block(BuildBlockTestCase());
      62                 :            : 
      63                 :          0 :     LOCK2(cs_main, pool.cs);
      64                 :          0 :     pool.addUnchecked(entry.FromTx(block.vtx[2]));
      65                 :          0 :     BOOST_CHECK_EQUAL(pool.mapTx.find(block.vtx[2]->GetHash())->GetSharedTx().use_count(), SHARED_TX_OFFSET + 0);
      66                 :            : 
      67                 :            :     // Do a simple ShortTxIDs RT
      68                 :            :     {
      69                 :          0 :         CBlockHeaderAndShortTxIDs shortIDs{block};
      70                 :            : 
      71                 :          0 :         CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
      72                 :          0 :         stream << shortIDs;
      73                 :            : 
      74                 :          0 :         CBlockHeaderAndShortTxIDs shortIDs2;
      75                 :          0 :         stream >> shortIDs2;
      76                 :            : 
      77                 :          0 :         PartiallyDownloadedBlock partialBlock(&pool);
      78                 :          0 :         BOOST_CHECK(partialBlock.InitData(shortIDs2, extra_txn) == READ_STATUS_OK);
      79                 :          0 :         BOOST_CHECK( partialBlock.IsTxAvailable(0));
      80                 :          0 :         BOOST_CHECK(!partialBlock.IsTxAvailable(1));
      81                 :          0 :         BOOST_CHECK( partialBlock.IsTxAvailable(2));
      82                 :            : 
      83                 :          0 :         BOOST_CHECK_EQUAL(pool.mapTx.find(block.vtx[2]->GetHash())->GetSharedTx().use_count(), SHARED_TX_OFFSET + 1);
      84                 :            : 
      85                 :          0 :         size_t poolSize = pool.size();
      86                 :          0 :         pool.removeRecursive(*block.vtx[2], MemPoolRemovalReason::REPLACED);
      87                 :          0 :         BOOST_CHECK_EQUAL(pool.size(), poolSize - 1);
      88                 :            : 
      89                 :          0 :         CBlock block2;
      90                 :            :         {
      91                 :          0 :             PartiallyDownloadedBlock tmp = partialBlock;
      92                 :          0 :             BOOST_CHECK(partialBlock.FillBlock(block2, {}) == READ_STATUS_INVALID); // No transactions
      93                 :          0 :             partialBlock = tmp;
      94                 :          0 :         }
      95                 :            : 
      96                 :            :         // Wrong transaction
      97                 :            :         {
      98                 :          0 :             PartiallyDownloadedBlock tmp = partialBlock;
      99                 :          0 :             partialBlock.FillBlock(block2, {block.vtx[2]}); // Current implementation doesn't check txn here, but don't require that
     100                 :          0 :             partialBlock = tmp;
     101                 :          0 :         }
     102                 :            :         bool mutated;
     103                 :          0 :         BOOST_CHECK(block.hashMerkleRoot != BlockMerkleRoot(block2, &mutated));
     104                 :            : 
     105                 :          0 :         CBlock block3;
     106                 :          0 :         BOOST_CHECK(partialBlock.FillBlock(block3, {block.vtx[1]}) == READ_STATUS_OK);
     107                 :          0 :         BOOST_CHECK_EQUAL(block.GetHash().ToString(), block3.GetHash().ToString());
     108                 :          0 :         BOOST_CHECK_EQUAL(block.hashMerkleRoot.ToString(), BlockMerkleRoot(block3, &mutated).ToString());
     109                 :          0 :         BOOST_CHECK(!mutated);
     110                 :          0 :     }
     111                 :          0 : }
     112                 :            : 
     113                 :            : class TestHeaderAndShortIDs {
     114                 :            :     // Utility to encode custom CBlockHeaderAndShortTxIDs
     115                 :            : public:
     116                 :            :     CBlockHeader header;
     117                 :            :     uint64_t nonce;
     118                 :            :     std::vector<uint64_t> shorttxids;
     119                 :            :     std::vector<PrefilledTransaction> prefilledtxn;
     120                 :            : 
     121                 :          0 :     explicit TestHeaderAndShortIDs(const CBlockHeaderAndShortTxIDs& orig) {
     122                 :          0 :         CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
     123                 :          0 :         stream << orig;
     124                 :          0 :         stream >> *this;
     125                 :          0 :     }
     126                 :          0 :     explicit TestHeaderAndShortIDs(const CBlock& block) :
     127                 :          0 :         TestHeaderAndShortIDs(CBlockHeaderAndShortTxIDs{block}) {}
     128                 :            : 
     129                 :          0 :     uint64_t GetShortID(const uint256& txhash) const {
     130                 :          0 :         CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
     131                 :          0 :         stream << *this;
     132                 :          0 :         CBlockHeaderAndShortTxIDs base;
     133                 :          0 :         stream >> base;
     134                 :          0 :         return base.GetShortID(txhash);
     135                 :          0 :     }
     136                 :            : 
     137                 :          0 :     SERIALIZE_METHODS(TestHeaderAndShortIDs, obj) { READWRITE(obj.header, obj.nonce, Using<VectorFormatter<CustomUintFormatter<CBlockHeaderAndShortTxIDs::SHORTTXIDS_LENGTH>>>(obj.shorttxids), obj.prefilledtxn); }
     138                 :            : };
     139                 :            : 
     140                 :          0 : BOOST_AUTO_TEST_CASE(NonCoinbasePreforwardRTTest)
     141                 :            : {
     142                 :          0 :     CTxMemPool& pool = *Assert(m_node.mempool);
     143                 :          0 :     TestMemPoolEntryHelper entry;
     144                 :          0 :     CBlock block(BuildBlockTestCase());
     145                 :            : 
     146                 :          0 :     LOCK2(cs_main, pool.cs);
     147                 :          0 :     pool.addUnchecked(entry.FromTx(block.vtx[2]));
     148                 :          0 :     BOOST_CHECK_EQUAL(pool.mapTx.find(block.vtx[2]->GetHash())->GetSharedTx().use_count(), SHARED_TX_OFFSET + 0);
     149                 :            : 
     150                 :          0 :     uint256 txhash;
     151                 :            : 
     152                 :            :     // Test with pre-forwarding tx 1, but not coinbase
     153                 :            :     {
     154                 :          0 :         TestHeaderAndShortIDs shortIDs(block);
     155                 :          0 :         shortIDs.prefilledtxn.resize(1);
     156                 :          0 :         shortIDs.prefilledtxn[0] = {1, block.vtx[1]};
     157                 :          0 :         shortIDs.shorttxids.resize(2);
     158                 :          0 :         shortIDs.shorttxids[0] = shortIDs.GetShortID(block.vtx[0]->GetHash());
     159                 :          0 :         shortIDs.shorttxids[1] = shortIDs.GetShortID(block.vtx[2]->GetHash());
     160                 :            : 
     161                 :          0 :         CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
     162                 :          0 :         stream << shortIDs;
     163                 :            : 
     164                 :          0 :         CBlockHeaderAndShortTxIDs shortIDs2;
     165                 :          0 :         stream >> shortIDs2;
     166                 :            : 
     167                 :          0 :         PartiallyDownloadedBlock partialBlock(&pool);
     168                 :          0 :         BOOST_CHECK(partialBlock.InitData(shortIDs2, extra_txn) == READ_STATUS_OK);
     169                 :          0 :         BOOST_CHECK(!partialBlock.IsTxAvailable(0));
     170                 :          0 :         BOOST_CHECK( partialBlock.IsTxAvailable(1));
     171                 :          0 :         BOOST_CHECK( partialBlock.IsTxAvailable(2));
     172                 :            : 
     173                 :          0 :         BOOST_CHECK_EQUAL(pool.mapTx.find(block.vtx[2]->GetHash())->GetSharedTx().use_count(), SHARED_TX_OFFSET + 1); // +1 because of partialBlock
     174                 :            : 
     175                 :          0 :         CBlock block2;
     176                 :            :         {
     177                 :          0 :             PartiallyDownloadedBlock tmp = partialBlock;
     178                 :          0 :             BOOST_CHECK(partialBlock.FillBlock(block2, {}) == READ_STATUS_INVALID); // No transactions
     179                 :          0 :             partialBlock = tmp;
     180                 :          0 :         }
     181                 :            : 
     182                 :            :         // Wrong transaction
     183                 :            :         {
     184                 :          0 :             PartiallyDownloadedBlock tmp = partialBlock;
     185                 :          0 :             partialBlock.FillBlock(block2, {block.vtx[1]}); // Current implementation doesn't check txn here, but don't require that
     186                 :          0 :             partialBlock = tmp;
     187                 :          0 :         }
     188                 :          0 :         BOOST_CHECK_EQUAL(pool.mapTx.find(block.vtx[2]->GetHash())->GetSharedTx().use_count(), SHARED_TX_OFFSET + 2); // +2 because of partialBlock and block2
     189                 :            :         bool mutated;
     190                 :          0 :         BOOST_CHECK(block.hashMerkleRoot != BlockMerkleRoot(block2, &mutated));
     191                 :            : 
     192                 :          0 :         CBlock block3;
     193                 :          0 :         PartiallyDownloadedBlock partialBlockCopy = partialBlock;
     194                 :          0 :         BOOST_CHECK(partialBlock.FillBlock(block3, {block.vtx[0]}) == READ_STATUS_OK);
     195                 :          0 :         BOOST_CHECK_EQUAL(block.GetHash().ToString(), block3.GetHash().ToString());
     196                 :          0 :         BOOST_CHECK_EQUAL(block.hashMerkleRoot.ToString(), BlockMerkleRoot(block3, &mutated).ToString());
     197                 :          0 :         BOOST_CHECK(!mutated);
     198                 :            : 
     199                 :          0 :         BOOST_CHECK_EQUAL(pool.mapTx.find(block.vtx[2]->GetHash())->GetSharedTx().use_count(), SHARED_TX_OFFSET + 3); // +2 because of partialBlock and block2 and block3
     200                 :            : 
     201                 :          0 :         txhash = block.vtx[2]->GetHash();
     202                 :          0 :         block.vtx.clear();
     203                 :          0 :         block2.vtx.clear();
     204                 :          0 :         block3.vtx.clear();
     205                 :          0 :         BOOST_CHECK_EQUAL(pool.mapTx.find(txhash)->GetSharedTx().use_count(), SHARED_TX_OFFSET + 1 - 1); // + 1 because of partialBlock; -1 because of block.
     206                 :          0 :     }
     207                 :          0 :     BOOST_CHECK_EQUAL(pool.mapTx.find(txhash)->GetSharedTx().use_count(), SHARED_TX_OFFSET - 1); // -1 because of block
     208                 :          0 : }
     209                 :            : 
     210                 :          0 : BOOST_AUTO_TEST_CASE(SufficientPreforwardRTTest)
     211                 :            : {
     212                 :          0 :     CTxMemPool& pool = *Assert(m_node.mempool);
     213                 :          0 :     TestMemPoolEntryHelper entry;
     214                 :          0 :     CBlock block(BuildBlockTestCase());
     215                 :            : 
     216                 :          0 :     LOCK2(cs_main, pool.cs);
     217                 :          0 :     pool.addUnchecked(entry.FromTx(block.vtx[1]));
     218                 :          0 :     BOOST_CHECK_EQUAL(pool.mapTx.find(block.vtx[1]->GetHash())->GetSharedTx().use_count(), SHARED_TX_OFFSET + 0);
     219                 :            : 
     220                 :          0 :     uint256 txhash;
     221                 :            : 
     222                 :            :     // Test with pre-forwarding coinbase + tx 2 with tx 1 in mempool
     223                 :            :     {
     224                 :          0 :         TestHeaderAndShortIDs shortIDs(block);
     225                 :          0 :         shortIDs.prefilledtxn.resize(2);
     226                 :          0 :         shortIDs.prefilledtxn[0] = {0, block.vtx[0]};
     227                 :          0 :         shortIDs.prefilledtxn[1] = {1, block.vtx[2]}; // id == 1 as it is 1 after index 1
     228                 :          0 :         shortIDs.shorttxids.resize(1);
     229                 :          0 :         shortIDs.shorttxids[0] = shortIDs.GetShortID(block.vtx[1]->GetHash());
     230                 :            : 
     231                 :          0 :         CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
     232                 :          0 :         stream << shortIDs;
     233                 :            : 
     234                 :          0 :         CBlockHeaderAndShortTxIDs shortIDs2;
     235                 :          0 :         stream >> shortIDs2;
     236                 :            : 
     237                 :          0 :         PartiallyDownloadedBlock partialBlock(&pool);
     238                 :          0 :         BOOST_CHECK(partialBlock.InitData(shortIDs2, extra_txn) == READ_STATUS_OK);
     239                 :          0 :         BOOST_CHECK( partialBlock.IsTxAvailable(0));
     240                 :          0 :         BOOST_CHECK( partialBlock.IsTxAvailable(1));
     241                 :          0 :         BOOST_CHECK( partialBlock.IsTxAvailable(2));
     242                 :            : 
     243                 :          0 :         BOOST_CHECK_EQUAL(pool.mapTx.find(block.vtx[1]->GetHash())->GetSharedTx().use_count(), SHARED_TX_OFFSET + 1);
     244                 :            : 
     245                 :          0 :         CBlock block2;
     246                 :          0 :         PartiallyDownloadedBlock partialBlockCopy = partialBlock;
     247                 :          0 :         BOOST_CHECK(partialBlock.FillBlock(block2, {}) == READ_STATUS_OK);
     248                 :          0 :         BOOST_CHECK_EQUAL(block.GetHash().ToString(), block2.GetHash().ToString());
     249                 :            :         bool mutated;
     250                 :          0 :         BOOST_CHECK_EQUAL(block.hashMerkleRoot.ToString(), BlockMerkleRoot(block2, &mutated).ToString());
     251                 :          0 :         BOOST_CHECK(!mutated);
     252                 :            : 
     253                 :          0 :         txhash = block.vtx[1]->GetHash();
     254                 :          0 :         block.vtx.clear();
     255                 :          0 :         block2.vtx.clear();
     256                 :          0 :         BOOST_CHECK_EQUAL(pool.mapTx.find(txhash)->GetSharedTx().use_count(), SHARED_TX_OFFSET + 1 - 1); // + 1 because of partialBlock; -1 because of block.
     257                 :          0 :     }
     258                 :          0 :     BOOST_CHECK_EQUAL(pool.mapTx.find(txhash)->GetSharedTx().use_count(), SHARED_TX_OFFSET - 1); // -1 because of block
     259                 :          0 : }
     260                 :            : 
     261                 :          0 : BOOST_AUTO_TEST_CASE(EmptyBlockRoundTripTest)
     262                 :            : {
     263                 :          0 :     CTxMemPool& pool = *Assert(m_node.mempool);
     264                 :          0 :     CMutableTransaction coinbase;
     265                 :          0 :     coinbase.vin.resize(1);
     266                 :          0 :     coinbase.vin[0].scriptSig.resize(10);
     267                 :          0 :     coinbase.vout.resize(1);
     268                 :          0 :     coinbase.vout[0].nValue = 42;
     269                 :            : 
     270                 :          0 :     CBlock block;
     271                 :          0 :     block.vtx.resize(1);
     272                 :          0 :     block.vtx[0] = MakeTransactionRef(std::move(coinbase));
     273                 :          0 :     block.nVersion = 42;
     274                 :          0 :     block.hashPrevBlock = InsecureRand256();
     275                 :          0 :     block.nBits = 0x207fffff;
     276                 :            : 
     277                 :            :     bool mutated;
     278                 :          0 :     block.hashMerkleRoot = BlockMerkleRoot(block, &mutated);
     279                 :          0 :     assert(!mutated);
     280                 :          0 :     while (!CheckProofOfWork(block.GetHash(), block.nBits, Params().GetConsensus())) ++block.nNonce;
     281                 :            : 
     282                 :            :     // Test simple header round-trip with only coinbase
     283                 :            :     {
     284                 :          0 :         CBlockHeaderAndShortTxIDs shortIDs{block};
     285                 :            : 
     286                 :          0 :         CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
     287                 :          0 :         stream << shortIDs;
     288                 :            : 
     289                 :          0 :         CBlockHeaderAndShortTxIDs shortIDs2;
     290                 :          0 :         stream >> shortIDs2;
     291                 :            : 
     292                 :          0 :         PartiallyDownloadedBlock partialBlock(&pool);
     293                 :          0 :         BOOST_CHECK(partialBlock.InitData(shortIDs2, extra_txn) == READ_STATUS_OK);
     294                 :          0 :         BOOST_CHECK(partialBlock.IsTxAvailable(0));
     295                 :            : 
     296                 :          0 :         CBlock block2;
     297                 :          0 :         std::vector<CTransactionRef> vtx_missing;
     298                 :          0 :         BOOST_CHECK(partialBlock.FillBlock(block2, vtx_missing) == READ_STATUS_OK);
     299                 :          0 :         BOOST_CHECK_EQUAL(block.GetHash().ToString(), block2.GetHash().ToString());
     300                 :          0 :         BOOST_CHECK_EQUAL(block.hashMerkleRoot.ToString(), BlockMerkleRoot(block2, &mutated).ToString());
     301                 :          0 :         BOOST_CHECK(!mutated);
     302                 :          0 :     }
     303                 :          0 : }
     304                 :            : 
     305                 :          0 : BOOST_AUTO_TEST_CASE(TransactionsRequestSerializationTest) {
     306                 :          0 :     BlockTransactionsRequest req1;
     307                 :          0 :     req1.blockhash = InsecureRand256();
     308                 :          0 :     req1.indexes.resize(4);
     309                 :          0 :     req1.indexes[0] = 0;
     310                 :          0 :     req1.indexes[1] = 1;
     311                 :          0 :     req1.indexes[2] = 3;
     312                 :          0 :     req1.indexes[3] = 4;
     313                 :            : 
     314                 :          0 :     DataStream stream{};
     315                 :          0 :     stream << req1;
     316                 :            : 
     317                 :          0 :     BlockTransactionsRequest req2;
     318                 :          0 :     stream >> req2;
     319                 :            : 
     320                 :          0 :     BOOST_CHECK_EQUAL(req1.blockhash.ToString(), req2.blockhash.ToString());
     321                 :          0 :     BOOST_CHECK_EQUAL(req1.indexes.size(), req2.indexes.size());
     322                 :          0 :     BOOST_CHECK_EQUAL(req1.indexes[0], req2.indexes[0]);
     323                 :          0 :     BOOST_CHECK_EQUAL(req1.indexes[1], req2.indexes[1]);
     324                 :          0 :     BOOST_CHECK_EQUAL(req1.indexes[2], req2.indexes[2]);
     325                 :          0 :     BOOST_CHECK_EQUAL(req1.indexes[3], req2.indexes[3]);
     326                 :          0 : }
     327                 :            : 
     328                 :          0 : BOOST_AUTO_TEST_CASE(TransactionsRequestDeserializationMaxTest) {
     329                 :            :     // Check that the highest legal index is decoded correctly
     330                 :          0 :     BlockTransactionsRequest req0;
     331                 :          0 :     req0.blockhash = InsecureRand256();
     332                 :          0 :     req0.indexes.resize(1);
     333                 :          0 :     req0.indexes[0] = 0xffff;
     334                 :          0 :     DataStream stream{};
     335                 :          0 :     stream << req0;
     336                 :            : 
     337                 :          0 :     BlockTransactionsRequest req1;
     338                 :          0 :     stream >> req1;
     339                 :          0 :     BOOST_CHECK_EQUAL(req0.indexes.size(), req1.indexes.size());
     340                 :          0 :     BOOST_CHECK_EQUAL(req0.indexes[0], req1.indexes[0]);
     341                 :          0 : }
     342                 :            : 
     343                 :          0 : BOOST_AUTO_TEST_CASE(TransactionsRequestDeserializationOverflowTest) {
     344                 :            :     // Any set of index deltas that starts with N values that sum to (0x10000 - N)
     345                 :            :     // causes the edge-case overflow that was originally not checked for. Such
     346                 :            :     // a request cannot be created by serializing a real BlockTransactionsRequest
     347                 :            :     // due to the overflow, so here we'll serialize from raw deltas.
     348                 :          0 :     BlockTransactionsRequest req0;
     349                 :          0 :     req0.blockhash = InsecureRand256();
     350                 :          0 :     req0.indexes.resize(3);
     351                 :          0 :     req0.indexes[0] = 0x7000;
     352                 :          0 :     req0.indexes[1] = 0x10000 - 0x7000 - 2;
     353                 :          0 :     req0.indexes[2] = 0;
     354                 :          0 :     DataStream stream{};
     355                 :          0 :     stream << req0.blockhash;
     356                 :          0 :     WriteCompactSize(stream, req0.indexes.size());
     357                 :          0 :     WriteCompactSize(stream, req0.indexes[0]);
     358                 :          0 :     WriteCompactSize(stream, req0.indexes[1]);
     359                 :          0 :     WriteCompactSize(stream, req0.indexes[2]);
     360                 :            : 
     361                 :          0 :     BlockTransactionsRequest req1;
     362                 :            :     try {
     363                 :          0 :         stream >> req1;
     364                 :            :         // before patch: deserialize above succeeds and this check fails, demonstrating the overflow
     365                 :          0 :         BOOST_CHECK(req1.indexes[1] < req1.indexes[2]);
     366                 :            :         // this shouldn't be reachable before or after patch
     367                 :          0 :         BOOST_CHECK(0);
     368                 :          0 :     } catch(std::ios_base::failure &) {
     369                 :            :         // deserialize should fail
     370                 :          0 :         BOOST_CHECK(true); // Needed to suppress "Test case [...] did not check any assertions"
     371                 :          0 :     }
     372                 :          0 : }
     373                 :            : 
     374                 :          0 : BOOST_AUTO_TEST_SUITE_END()

Generated by: LCOV version 1.14