LCOV - code coverage report
Current view: top level - src - blockencodings.h (source / functions) Hit Total Coverage
Test: fuzz_coverage.info Lines: 34 34 100.0 %
Date: 2023-10-05 15:40:34 Functions: 53 60 88.3 %
Branches: 11 20 55.0 %

           Branch data     Line data    Source code
       1                 :            : // Copyright (c) 2016-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                 :            : #ifndef BITCOIN_BLOCKENCODINGS_H
       6                 :            : #define BITCOIN_BLOCKENCODINGS_H
       7                 :            : 
       8                 :            : #include <primitives/block.h>
       9                 :            : 
      10                 :            : #include <functional>
      11                 :            : 
      12                 :            : class CTxMemPool;
      13                 :            : class BlockValidationState;
      14                 :            : namespace Consensus {
      15                 :            : struct Params;
      16                 :            : };
      17                 :            : 
      18                 :            : // Transaction compression schemes for compact block relay can be introduced by writing
      19                 :            : // an actual formatter here.
      20                 :            : using TransactionCompression = DefaultFormatter;
      21                 :            : 
      22                 :      14836 : class DifferenceFormatter
      23                 :            : {
      24                 :      14836 :     uint64_t m_shift = 0;
      25                 :            : 
      26                 :            : public:
      27                 :            :     template<typename Stream, typename I>
      28                 :     121071 :     void Ser(Stream& s, I v)
      29                 :            :     {
      30   [ +  -  #  # ]:     121071 :         if (v < m_shift || v >= std::numeric_limits<uint64_t>::max()) throw std::ios_base::failure("differential value overflow");
      31                 :     121071 :         WriteCompactSize(s, v - m_shift);
      32                 :     121071 :         m_shift = uint64_t(v) + 1;
      33                 :     121071 :     }
      34                 :            :     template<typename Stream, typename I>
      35                 :     816500 :     void Unser(Stream& s, I& v)
      36                 :            :     {
      37                 :     816500 :         uint64_t n = ReadCompactSize(s);
      38                 :     816500 :         m_shift += n;
      39   [ +  +  +  - ]:     816500 :         if (m_shift < n || m_shift >= std::numeric_limits<uint64_t>::max() || m_shift < std::numeric_limits<I>::min() || m_shift > std::numeric_limits<I>::max()) throw std::ios_base::failure("differential value overflow");
      40                 :     815110 :         v = I(m_shift++);
      41                 :     815110 :     }
      42                 :            : };
      43                 :            : 
      44                 :            : class BlockTransactionsRequest {
      45                 :            : public:
      46                 :            :     // A BlockTransactionsRequest message
      47                 :            :     uint256 blockhash;
      48                 :            :     std::vector<uint16_t> indexes;
      49                 :            : 
      50                 :      56580 :     SERIALIZE_METHODS(BlockTransactionsRequest, obj)
      51                 :            :     {
      52                 :      18860 :         READWRITE(obj.blockhash, Using<VectorFormatter<DifferenceFormatter>>(obj.indexes));
      53                 :      18860 :     }
      54                 :            : };
      55                 :            : 
      56                 :            : class BlockTransactions {
      57                 :            : public:
      58                 :            :     // A BlockTransactions message
      59                 :            :     uint256 blockhash;
      60                 :            :     std::vector<CTransactionRef> txn;
      61                 :            : 
      62                 :       5688 :     BlockTransactions() {}
      63                 :       4194 :     explicit BlockTransactions(const BlockTransactionsRequest& req) :
      64         [ +  - ]:       4194 :         blockhash(req.blockhash), txn(req.indexes.size()) {}
      65                 :            : 
      66                 :      26964 :     SERIALIZE_METHODS(BlockTransactions, obj)
      67                 :            :     {
      68                 :       8988 :         READWRITE(obj.blockhash, Using<VectorFormatter<TransactionCompression>>(obj.txn));
      69                 :       8988 :     }
      70                 :            : };
      71                 :            : 
      72                 :            : // Dumb serialization/storage-helper for CBlockHeaderAndShortTxIDs and PartiallyDownloadedBlock
      73                 :            : struct PrefilledTransaction {
      74                 :            :     // Used as an offset since last prefilled tx in CBlockHeaderAndShortTxIDs,
      75                 :            :     // as a proper transaction-in-block-index in PartiallyDownloadedBlock
      76                 :            :     uint16_t index;
      77                 :            :     CTransactionRef tx;
      78                 :            : 
      79                 :      69837 :     SERIALIZE_METHODS(PrefilledTransaction, obj) { READWRITE(COMPACTSIZE(obj.index), Using<TransactionCompression>(obj.tx)); }
      80                 :            : };
      81                 :            : 
      82                 :            : typedef enum ReadStatus_t
      83                 :            : {
      84                 :            :     READ_STATUS_OK,
      85                 :            :     READ_STATUS_INVALID, // Invalid object, peer is sending bogus crap
      86                 :            :     READ_STATUS_FAILED, // Failed to process object
      87                 :            :     READ_STATUS_CHECKBLOCK_FAILED, // Used only by FillBlock to indicate a
      88                 :            :                                    // failure in CheckBlock.
      89                 :            : } ReadStatus;
      90                 :            : 
      91                 :            : class CBlockHeaderAndShortTxIDs {
      92                 :            : private:
      93                 :            :     mutable uint64_t shorttxidk0, shorttxidk1;
      94                 :            :     uint64_t nonce;
      95                 :            : 
      96                 :            :     void FillShortTxIDSelector() const;
      97                 :            : 
      98                 :            :     friend class PartiallyDownloadedBlock;
      99                 :            : 
     100                 :            : protected:
     101                 :            :     std::vector<uint64_t> shorttxids;
     102                 :            :     std::vector<PrefilledTransaction> prefilledtxn;
     103                 :            : 
     104                 :            : public:
     105                 :            :     static constexpr int SHORTTXIDS_LENGTH = 6;
     106                 :            : 
     107                 :            :     CBlockHeader header;
     108                 :            : 
     109                 :            :     // Dummy for deserialization
     110         [ +  - ]:      25274 :     CBlockHeaderAndShortTxIDs() {}
     111                 :            : 
     112                 :            :     CBlockHeaderAndShortTxIDs(const CBlock& block);
     113                 :            : 
     114                 :            :     uint64_t GetShortID(const uint256& txhash) const;
     115                 :            : 
     116                 :     322958 :     size_t BlockTxCount() const { return shorttxids.size() + prefilledtxn.size(); }
     117                 :            : 
     118                 :      76431 :     SERIALIZE_METHODS(CBlockHeaderAndShortTxIDs, obj)
     119                 :            :     {
     120                 :      25477 :         READWRITE(obj.header, obj.nonce, Using<VectorFormatter<CustomUintFormatter<SHORTTXIDS_LENGTH>>>(obj.shorttxids), obj.prefilledtxn);
     121                 :            :         if (ser_action.ForRead()) {
     122         [ +  + ]:      25273 :             if (obj.BlockTxCount() > std::numeric_limits<uint16_t>::max()) {
     123         [ +  - ]:          3 :                 throw std::ios_base::failure("indexes overflowed 16 bits");
     124                 :            :             }
     125                 :      25270 :             obj.FillShortTxIDSelector();
     126                 :            :         }
     127                 :      25474 :     }
     128                 :            : };
     129                 :            : 
     130                 :            : class PartiallyDownloadedBlock {
     131                 :            : protected:
     132                 :            :     std::vector<CTransactionRef> txn_available;
     133                 :        457 :     size_t prefilled_count = 0, mempool_count = 0, extra_count = 0;
     134                 :            :     const CTxMemPool* pool;
     135                 :            : public:
     136                 :            :     CBlockHeader header;
     137                 :            : 
     138                 :            :     // Can be overridden for testing
     139                 :            :     using CheckBlockFn = std::function<bool(const CBlock&, BlockValidationState&, const Consensus::Params&, bool, bool)>;
     140                 :        457 :     CheckBlockFn m_check_block_mock{nullptr};
     141                 :            : 
     142   [ +  -  +  - ]:        914 :     explicit PartiallyDownloadedBlock(CTxMemPool* poolIn) : pool(poolIn) {}
     143                 :            : 
     144                 :            :     // extra_txn is a list of extra transactions to look at, in <witness hash, reference> form
     145                 :            :     ReadStatus InitData(const CBlockHeaderAndShortTxIDs& cmpctblock, const std::vector<std::pair<uint256, CTransactionRef>>& extra_txn);
     146                 :            :     bool IsTxAvailable(size_t index) const;
     147                 :            :     ReadStatus FillBlock(CBlock& block, const std::vector<CTransactionRef>& vtx_missing);
     148                 :            : };
     149                 :            : 
     150                 :            : #endif // BITCOIN_BLOCKENCODINGS_H

Generated by: LCOV version 1.14