Bitcoin Core  0.19.99
P2P Digital Currency
blockencodings.h
Go to the documentation of this file.
1 // Copyright (c) 2016-2019 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 
11 class CTxMemPool;
12 
13 // Dumb helper to handle CTransaction compression at serialize-time
15 private:
17 public:
18  explicit TransactionCompressor(CTransactionRef& txIn) : tx(txIn) {}
19 
21 
22  template <typename Stream, typename Operation>
23  inline void SerializationOp(Stream& s, Operation ser_action) {
24  READWRITE(tx); //TODO: Compress tx encoding
25  }
26 };
27 
29 public:
30  // A BlockTransactionsRequest message
32  std::vector<uint16_t> indexes;
33 
35 
36  template <typename Stream, typename Operation>
37  inline void SerializationOp(Stream& s, Operation ser_action) {
38  READWRITE(blockhash);
39  uint64_t indexes_size = (uint64_t)indexes.size();
40  READWRITE(COMPACTSIZE(indexes_size));
41  if (ser_action.ForRead()) {
42  size_t i = 0;
43  while (indexes.size() < indexes_size) {
44  indexes.resize(std::min((uint64_t)(1000 + indexes.size()), indexes_size));
45  for (; i < indexes.size(); i++) {
46  uint64_t index = 0;
47  READWRITE(COMPACTSIZE(index));
48  if (index > std::numeric_limits<uint16_t>::max())
49  throw std::ios_base::failure("index overflowed 16 bits");
50  indexes[i] = index;
51  }
52  }
53 
54  int32_t offset = 0;
55  for (size_t j = 0; j < indexes.size(); j++) {
56  if (int32_t(indexes[j]) + offset > std::numeric_limits<uint16_t>::max())
57  throw std::ios_base::failure("indexes overflowed 16 bits");
58  indexes[j] = indexes[j] + offset;
59  offset = int32_t(indexes[j]) + 1;
60  }
61  } else {
62  for (size_t i = 0; i < indexes.size(); i++) {
63  uint64_t index = indexes[i] - (i == 0 ? 0 : (indexes[i - 1] + 1));
64  READWRITE(COMPACTSIZE(index));
65  }
66  }
67  }
68 };
69 
71 public:
72  // A BlockTransactions message
74  std::vector<CTransactionRef> txn;
75 
78  blockhash(req.blockhash), txn(req.indexes.size()) {}
79 
81 
82  template <typename Stream, typename Operation>
83  inline void SerializationOp(Stream& s, Operation ser_action) {
84  READWRITE(blockhash);
85  uint64_t txn_size = (uint64_t)txn.size();
86  READWRITE(COMPACTSIZE(txn_size));
87  if (ser_action.ForRead()) {
88  size_t i = 0;
89  while (txn.size() < txn_size) {
90  txn.resize(std::min((uint64_t)(1000 + txn.size()), txn_size));
91  for (; i < txn.size(); i++)
93  }
94  } else {
95  for (size_t i = 0; i < txn.size(); i++)
97  }
98  }
99 };
100 
101 // Dumb serialization/storage-helper for CBlockHeaderAndShortTxIDs and PartiallyDownloadedBlock
103  // Used as an offset since last prefilled tx in CBlockHeaderAndShortTxIDs,
104  // as a proper transaction-in-block-index in PartiallyDownloadedBlock
105  uint16_t index;
107 
109 
110  template <typename Stream, typename Operation>
111  inline void SerializationOp(Stream& s, Operation ser_action) {
112  uint64_t idx = index;
113  READWRITE(COMPACTSIZE(idx));
114  if (idx > std::numeric_limits<uint16_t>::max())
115  throw std::ios_base::failure("index overflowed 16-bits");
116  index = idx;
118  }
119 };
120 
121 typedef enum ReadStatus_t
122 {
124  READ_STATUS_INVALID, // Invalid object, peer is sending bogus crap
125  READ_STATUS_FAILED, // Failed to process object
126  READ_STATUS_CHECKBLOCK_FAILED, // Used only by FillBlock to indicate a
127  // failure in CheckBlock.
128 } ReadStatus;
129 
131 private:
132  mutable uint64_t shorttxidk0, shorttxidk1;
133  uint64_t nonce;
134 
135  void FillShortTxIDSelector() const;
136 
138 
139  static const int SHORTTXIDS_LENGTH = 6;
140 protected:
141  std::vector<uint64_t> shorttxids;
142  std::vector<PrefilledTransaction> prefilledtxn;
143 
144 public:
146 
147  // Dummy for deserialization
149 
150  CBlockHeaderAndShortTxIDs(const CBlock& block, bool fUseWTXID);
151 
152  uint64_t GetShortID(const uint256& txhash) const;
153 
154  size_t BlockTxCount() const { return shorttxids.size() + prefilledtxn.size(); }
155 
157 
158  template <typename Stream, typename Operation>
159  inline void SerializationOp(Stream& s, Operation ser_action) {
160  READWRITE(header);
161  READWRITE(nonce);
162 
163  uint64_t shorttxids_size = (uint64_t)shorttxids.size();
164  READWRITE(COMPACTSIZE(shorttxids_size));
165  if (ser_action.ForRead()) {
166  size_t i = 0;
167  while (shorttxids.size() < shorttxids_size) {
168  shorttxids.resize(std::min((uint64_t)(1000 + shorttxids.size()), shorttxids_size));
169  for (; i < shorttxids.size(); i++) {
170  uint32_t lsb = 0; uint16_t msb = 0;
171  READWRITE(lsb);
172  READWRITE(msb);
173  shorttxids[i] = (uint64_t(msb) << 32) | uint64_t(lsb);
174  static_assert(SHORTTXIDS_LENGTH == 6, "shorttxids serialization assumes 6-byte shorttxids");
175  }
176  }
177  } else {
178  for (size_t i = 0; i < shorttxids.size(); i++) {
179  uint32_t lsb = shorttxids[i] & 0xffffffff;
180  uint16_t msb = (shorttxids[i] >> 32) & 0xffff;
181  READWRITE(lsb);
182  READWRITE(msb);
183  }
184  }
185 
186  READWRITE(prefilledtxn);
187 
188  if (BlockTxCount() > std::numeric_limits<uint16_t>::max())
189  throw std::ios_base::failure("indexes overflowed 16 bits");
190 
191  if (ser_action.ForRead())
192  FillShortTxIDSelector();
193  }
194 };
195 
197 protected:
198  std::vector<CTransactionRef> txn_available;
199  size_t prefilled_count = 0, mempool_count = 0, extra_count = 0;
201 public:
203  explicit PartiallyDownloadedBlock(CTxMemPool* poolIn) : pool(poolIn) {}
204 
205  // extra_txn is a list of extra transactions to look at, in <witness hash, reference> form
206  ReadStatus InitData(const CBlockHeaderAndShortTxIDs& cmpctblock, const std::vector<std::pair<uint256, CTransactionRef>>& extra_txn);
207  bool IsTxAvailable(size_t index) const;
208  ReadStatus FillBlock(CBlock& block, const std::vector<CTransactionRef>& vtx_missing);
209 };
210 
211 #endif // BITCOIN_BLOCKENCODINGS_H
std::shared_ptr< const CTransaction > CTransactionRef
Definition: transaction.h:408
enum ReadStatus_t ReadStatus
Definition: block.h:72
std::vector< uint16_t > indexes
std::vector< CTransactionRef > txn_available
#define COMPACTSIZE(obj)
Definition: serialize.h:498
BlockTransactions(const BlockTransactionsRequest &req)
PartiallyDownloadedBlock(CTxMemPool *poolIn)
ReadStatus_t
void SerializationOp(Stream &s, Operation ser_action)
TransactionCompressor(CTransactionRef &txIn)
std::vector< CTransactionRef > txn
void SerializationOp(Stream &s, Operation ser_action)
void SerializationOp(Stream &s, Operation ser_action)
void SerializationOp(Stream &s, Operation ser_action)
CTransactionRef & tx
void SerializationOp(Stream &s, Operation ser_action)
256-bit opaque blob.
Definition: uint256.h:120
std::vector< uint64_t > shorttxids
CTxMemPool stores valid-according-to-the-current-best-chain transactions that may be included in the ...
Definition: txmempool.h:444
std::vector< PrefilledTransaction > prefilledtxn
#define READWRITE(...)
Definition: serialize.h:186
CTransactionRef tx
Nodes collect new transactions into a block, hash them into a hash tree, and scan through nonce value...
Definition: block.h:20