/root/bitcoin/src/blockencodings.h
| Line | Count | Source | 
| 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 |  | class DifferenceFormatter | 
| 23 |  | { | 
| 24 |  |     uint64_t m_shift = 0; | 
| 25 |  |  | 
| 26 |  | public: | 
| 27 |  |     template<typename Stream, typename I> | 
| 28 |  |     void Ser(Stream& s, I v) | 
| 29 | 0 |     { | 
| 30 | 0 |         if (v < m_shift || v >= std::numeric_limits<uint64_t>::max()) throw std::ios_base::failure("differential value overflow"); | 
| 31 | 0 |         WriteCompactSize(s, v - m_shift); | 
| 32 | 0 |         m_shift = uint64_t(v) + 1; | 
| 33 | 0 |     } Unexecuted instantiation: _ZN19DifferenceFormatter3SerI10DataStreamtEEvRT_T0_Unexecuted instantiation: _ZN19DifferenceFormatter3SerI12VectorWritertEEvRT_T0_ | 
| 34 |  |     template<typename Stream, typename I> | 
| 35 |  |     void Unser(Stream& s, I& v) | 
| 36 | 0 |     { | 
| 37 | 0 |         uint64_t n = ReadCompactSize(s); | 
| 38 | 0 |         m_shift += n; | 
| 39 | 0 |         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 | 0 |         v = I(m_shift++); | 
| 41 | 0 |     } | 
| 42 |  | }; | 
| 43 |  |  | 
| 44 |  | class BlockTransactionsRequest { | 
| 45 |  | public: | 
| 46 |  |     // A BlockTransactionsRequest message | 
| 47 |  |     uint256 blockhash; | 
| 48 |  |     std::vector<uint16_t> indexes; | 
| 49 |  |  | 
| 50 |  |     SERIALIZE_METHODS(BlockTransactionsRequest, obj) | 
| 51 | 0 |     { | 
| 52 | 0 |         READWRITE(obj.blockhash, Using<VectorFormatter<DifferenceFormatter>>(obj.indexes)); | 
| 53 | 0 |     } Unexecuted instantiation: _ZN24BlockTransactionsRequest16SerializationOpsI10DataStreamS_17ActionUnserializeEEvRT0_RT_T1_Unexecuted instantiation: _ZN24BlockTransactionsRequest16SerializationOpsI10DataStreamKS_15ActionSerializeEEvRT0_RT_T1_Unexecuted instantiation: _ZN24BlockTransactionsRequest16SerializationOpsI12VectorWriterKS_15ActionSerializeEEvRT0_RT_T1_ | 
| 54 |  | }; | 
| 55 |  |  | 
| 56 |  | class BlockTransactions { | 
| 57 |  | public: | 
| 58 |  |     // A BlockTransactions message | 
| 59 |  |     uint256 blockhash; | 
| 60 |  |     std::vector<CTransactionRef> txn; | 
| 61 |  |  | 
| 62 | 0 |     BlockTransactions() = default; | 
| 63 |  |     explicit BlockTransactions(const BlockTransactionsRequest& req) : | 
| 64 | 0 |         blockhash(req.blockhash), txn(req.indexes.size()) {} | 
| 65 |  |  | 
| 66 |  |     SERIALIZE_METHODS(BlockTransactions, obj) | 
| 67 | 0 |     { | 
| 68 | 0 |         READWRITE(obj.blockhash, TX_WITH_WITNESS(Using<VectorFormatter<TransactionCompression>>(obj.txn))); | 
| 69 | 0 |     } Unexecuted instantiation: _ZN17BlockTransactions16SerializationOpsI10DataStreamS_17ActionUnserializeEEvRT0_RT_T1_Unexecuted instantiation: _ZN17BlockTransactions16SerializationOpsI10DataStreamKS_15ActionSerializeEEvRT0_RT_T1_Unexecuted instantiation: _ZN17BlockTransactions16SerializationOpsI12VectorWriterKS_15ActionSerializeEEvRT0_RT_T1_ | 
| 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 | 0 |     SERIALIZE_METHODS(PrefilledTransaction, obj) { READWRITE(COMPACTSIZE(obj.index), TX_WITH_WITNESS(Using<TransactionCompression>(obj.tx))); }Unexecuted instantiation: _ZN20PrefilledTransaction16SerializationOpsI10DataStreamS_17ActionUnserializeEEvRT0_RT_T1_Unexecuted instantiation: _ZN20PrefilledTransaction16SerializationOpsI10DataStreamKS_15ActionSerializeEEvRT0_RT_T1_Unexecuted instantiation: _ZN20PrefilledTransaction16SerializationOpsI12ParamsStreamIR12VectorWriter20TransactionSerParamsEKS_15ActionSerializeEEvRT0_RT_T1_Unexecuted instantiation: _ZN20PrefilledTransaction16SerializationOpsI12SizeComputerKS_15ActionSerializeEEvRT0_RT_T1_Unexecuted instantiation: _ZN20PrefilledTransaction16SerializationOpsI12VectorWriterKS_15ActionSerializeEEvRT0_RT_T1_ | 
| 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 |  | } ReadStatus; | 
| 88 |  |  | 
| 89 |  | class CBlockHeaderAndShortTxIDs { | 
| 90 |  | private: | 
| 91 |  |     mutable uint64_t shorttxidk0, shorttxidk1; | 
| 92 |  |     uint64_t nonce; | 
| 93 |  |  | 
| 94 |  |     void FillShortTxIDSelector() const; | 
| 95 |  |  | 
| 96 |  |     friend class PartiallyDownloadedBlock; | 
| 97 |  |  | 
| 98 |  | protected: | 
| 99 |  |     std::vector<uint64_t> shorttxids; | 
| 100 |  |     std::vector<PrefilledTransaction> prefilledtxn; | 
| 101 |  |  | 
| 102 |  | public: | 
| 103 |  |     static constexpr int SHORTTXIDS_LENGTH = 6; | 
| 104 |  |  | 
| 105 |  |     CBlockHeader header; | 
| 106 |  |  | 
| 107 |  |     /** | 
| 108 |  |      * Dummy for deserialization | 
| 109 |  |      */ | 
| 110 | 0 |     CBlockHeaderAndShortTxIDs() = default; | 
| 111 |  |  | 
| 112 |  |     /** | 
| 113 |  |      * @param[in]  nonce  This should be randomly generated, and is used for the siphash secret key | 
| 114 |  |      */ | 
| 115 |  |     CBlockHeaderAndShortTxIDs(const CBlock& block, const uint64_t nonce); | 
| 116 |  |  | 
| 117 |  |     uint64_t GetShortID(const Wtxid& wtxid) const; | 
| 118 |  |  | 
| 119 | 0 |     size_t BlockTxCount() const { return shorttxids.size() + prefilledtxn.size(); } | 
| 120 |  |  | 
| 121 |  |     SERIALIZE_METHODS(CBlockHeaderAndShortTxIDs, obj) | 
| 122 | 0 |     { | 
| 123 | 0 |         READWRITE(obj.header, obj.nonce, Using<VectorFormatter<CustomUintFormatter<SHORTTXIDS_LENGTH>>>(obj.shorttxids), obj.prefilledtxn); | 
| 124 | 0 |         if (ser_action.ForRead()) { | 
| 125 | 0 |             if (obj.BlockTxCount() > std::numeric_limits<uint16_t>::max()) { | 
| 126 | 0 |                 throw std::ios_base::failure("indexes overflowed 16 bits"); | 
| 127 | 0 |             } | 
| 128 | 0 |             obj.FillShortTxIDSelector(); | 
| 129 | 0 |         } | 
| 130 | 0 |     } Unexecuted instantiation: _ZN25CBlockHeaderAndShortTxIDs16SerializationOpsI10DataStreamS_17ActionUnserializeEEvRT0_RT_T1_Unexecuted instantiation: _ZN25CBlockHeaderAndShortTxIDs16SerializationOpsI10DataStreamKS_15ActionSerializeEEvRT0_RT_T1_Unexecuted instantiation: _ZN25CBlockHeaderAndShortTxIDs16SerializationOpsI12ParamsStreamIR12VectorWriter20TransactionSerParamsEKS_15ActionSerializeEEvRT0_RT_T1_Unexecuted instantiation: _ZN25CBlockHeaderAndShortTxIDs16SerializationOpsI12SizeComputerKS_15ActionSerializeEEvRT0_RT_T1_Unexecuted instantiation: _ZN25CBlockHeaderAndShortTxIDs16SerializationOpsI12VectorWriterKS_15ActionSerializeEEvRT0_RT_T1_ | 
| 131 |  | }; | 
| 132 |  |  | 
| 133 |  | class PartiallyDownloadedBlock { | 
| 134 |  | protected: | 
| 135 |  |     std::vector<CTransactionRef> txn_available; | 
| 136 |  |     size_t prefilled_count = 0, mempool_count = 0, extra_count = 0; | 
| 137 |  |     const CTxMemPool* pool; | 
| 138 |  | public: | 
| 139 |  |     CBlockHeader header; | 
| 140 |  |  | 
| 141 |  |     // Can be overridden for testing | 
| 142 |  |     using IsBlockMutatedFn = std::function<bool(const CBlock&, bool)>; | 
| 143 |  |     IsBlockMutatedFn m_check_block_mutated_mock{nullptr}; | 
| 144 |  |  | 
| 145 | 0 |     explicit PartiallyDownloadedBlock(CTxMemPool* poolIn) : pool(poolIn) {} | 
| 146 |  |  | 
| 147 |  |     // extra_txn is a list of extra transactions to look at, in <witness hash, reference> form | 
| 148 |  |     ReadStatus InitData(const CBlockHeaderAndShortTxIDs& cmpctblock, const std::vector<std::pair<Wtxid, CTransactionRef>>& extra_txn); | 
| 149 |  |     bool IsTxAvailable(size_t index) const; | 
| 150 |  |     // segwit_active enforces witness mutation checks just before reporting a healthy status | 
| 151 |  |     ReadStatus FillBlock(CBlock& block, const std::vector<CTransactionRef>& vtx_missing, bool segwit_active); | 
| 152 |  | }; | 
| 153 |  |  | 
| 154 |  | #endif // BITCOIN_BLOCKENCODINGS_H |