Bitcoin Core  31.0.0
P2P Digital Currency
blockencodings_tests.cpp
Go to the documentation of this file.
1 // Copyright (c) 2011-present 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/common.h>
14 #include <test/util/setup_common.h>
15 
16 #include <boost/test/unit_test.hpp>
17 
18 const std::vector<std::pair<Wtxid, CTransactionRef>> empty_extra_txn;
19 
20 BOOST_FIXTURE_TEST_SUITE(blockencodings_tests, RegTestingSetup)
21 
24  tx.vin.resize(1);
25  tx.vin[0].scriptSig.resize(10);
26  tx.vout.resize(1);
27  tx.vout[0].nValue = 42;
28  return tx;
29 }
30 
32  CBlock block;
34 
35  block.vtx.resize(3);
36  block.vtx[0] = MakeTransactionRef(tx);
37  block.nVersion = 42;
38  block.hashPrevBlock = ctx.rand256();
39  block.nBits = 0x207fffff;
40 
41  tx.vin[0].prevout.hash = Txid::FromUint256(ctx.rand256());
42  tx.vin[0].prevout.n = 0;
43  block.vtx[1] = MakeTransactionRef(tx);
44 
45  tx.vin.resize(10);
46  for (size_t i = 0; i < tx.vin.size(); i++) {
47  tx.vin[i].prevout.hash = Txid::FromUint256(ctx.rand256());
48  tx.vin[i].prevout.n = 0;
49  }
50  block.vtx[2] = MakeTransactionRef(tx);
51 
52  bool mutated;
53  block.hashMerkleRoot = BlockMerkleRoot(block, &mutated);
54  assert(!mutated);
55  while (!CheckProofOfWork(block.GetHash(), block.nBits, Params().GetConsensus())) ++block.nNonce;
56  return block;
57 }
58 
59 // Number of shared use_counts we expect for a tx we haven't touched
60 // (block + mempool entry + our copy from the GetSharedTx call)
61 constexpr long SHARED_TX_OFFSET{3};
62 
63 BOOST_AUTO_TEST_CASE(SimpleRoundTripTest)
64 {
65  CTxMemPool& pool = *Assert(m_node.mempool);
67  auto rand_ctx(FastRandomContext(uint256{42}));
68  CBlock block(BuildBlockTestCase(rand_ctx));
69 
70  LOCK2(cs_main, pool.cs);
71  TryAddToMempool(pool, entry.FromTx(block.vtx[2]));
72  BOOST_CHECK_EQUAL(pool.get(block.vtx[2]->GetHash()).use_count(), SHARED_TX_OFFSET + 0);
73 
74  // Do a simple ShortTxIDs RT
75  {
76  CBlockHeaderAndShortTxIDs shortIDs{block, rand_ctx.rand64()};
77 
78  DataStream stream{};
79  stream << shortIDs;
80 
81  CBlockHeaderAndShortTxIDs shortIDs2;
82  stream >> shortIDs2;
83 
84  PartiallyDownloadedBlock partialBlock(&pool);
85  BOOST_CHECK(partialBlock.InitData(shortIDs2, empty_extra_txn) == READ_STATUS_OK);
86  BOOST_CHECK( partialBlock.IsTxAvailable(0));
87  BOOST_CHECK(!partialBlock.IsTxAvailable(1));
88  BOOST_CHECK( partialBlock.IsTxAvailable(2));
89 
90  BOOST_CHECK_EQUAL(pool.get(block.vtx[2]->GetHash()).use_count(), SHARED_TX_OFFSET + 1);
91 
92  size_t poolSize = pool.size();
94  BOOST_CHECK_EQUAL(pool.size(), poolSize - 1);
95 
96  CBlock block2;
97  {
98  PartiallyDownloadedBlock tmp = partialBlock;
99  BOOST_CHECK(partialBlock.FillBlock(block2, {}, /*segwit_active=*/true) == READ_STATUS_INVALID); // No transactions
100  partialBlock = tmp;
101  }
102 
103  // Wrong transaction
104  {
105  PartiallyDownloadedBlock tmp = partialBlock;
106  partialBlock.FillBlock(block2, {block.vtx[2]}, /*segwit_active=*/true); // Current implementation doesn't check txn here, but don't require that
107  partialBlock = tmp;
108  }
109  bool mutated;
110  BOOST_CHECK(block.hashMerkleRoot != BlockMerkleRoot(block2, &mutated));
111 
112  CBlock block3;
113  BOOST_CHECK(partialBlock.FillBlock(block3, {block.vtx[1]}, /*segwit_active=*/true) == READ_STATUS_OK);
114  BOOST_CHECK_EQUAL(block.GetHash().ToString(), block3.GetHash().ToString());
115  BOOST_CHECK_EQUAL(block.hashMerkleRoot.ToString(), BlockMerkleRoot(block3, &mutated).ToString());
116  BOOST_CHECK(!mutated);
117  }
118 }
119 
121  // Utility to encode custom CBlockHeaderAndShortTxIDs
122 public:
124  uint64_t nonce;
125  std::vector<uint64_t> shorttxids;
126  std::vector<PrefilledTransaction> prefilledtxn;
127 
129  DataStream stream{};
130  stream << orig;
131  stream >> *this;
132  }
133  explicit TestHeaderAndShortIDs(const CBlock& block, FastRandomContext& ctx) :
135 
136  uint64_t GetShortID(const Wtxid& txhash) const {
137  DataStream stream{};
138  stream << *this;
140  stream >> base;
141  return base.GetShortID(txhash);
142  }
143 
145 };
146 
147 BOOST_AUTO_TEST_CASE(NonCoinbasePreforwardRTTest)
148 {
149  CTxMemPool& pool = *Assert(m_node.mempool);
151  auto rand_ctx(FastRandomContext(uint256{42}));
152  CBlock block(BuildBlockTestCase(rand_ctx));
153 
154  LOCK2(cs_main, pool.cs);
155  TryAddToMempool(pool, entry.FromTx(block.vtx[2]));
156  BOOST_CHECK_EQUAL(pool.get(block.vtx[2]->GetHash()).use_count(), SHARED_TX_OFFSET + 0);
157 
158  Txid txhash;
159 
160  // Test with pre-forwarding tx 1, but not coinbase
161  {
162  TestHeaderAndShortIDs shortIDs(block, rand_ctx);
163  shortIDs.prefilledtxn.resize(1);
164  shortIDs.prefilledtxn[0] = {1, block.vtx[1]};
165  shortIDs.shorttxids.resize(2);
166  shortIDs.shorttxids[0] = shortIDs.GetShortID(block.vtx[0]->GetWitnessHash());
167  shortIDs.shorttxids[1] = shortIDs.GetShortID(block.vtx[2]->GetWitnessHash());
168 
169  DataStream stream{};
170  stream << shortIDs;
171 
172  CBlockHeaderAndShortTxIDs shortIDs2;
173  stream >> shortIDs2;
174 
175  PartiallyDownloadedBlock partialBlock(&pool);
176  BOOST_CHECK(partialBlock.InitData(shortIDs2, empty_extra_txn) == READ_STATUS_OK);
177  BOOST_CHECK(!partialBlock.IsTxAvailable(0));
178  BOOST_CHECK( partialBlock.IsTxAvailable(1));
179  BOOST_CHECK( partialBlock.IsTxAvailable(2));
180 
181  BOOST_CHECK_EQUAL(pool.get(block.vtx[2]->GetHash()).use_count(), SHARED_TX_OFFSET + 1); // +1 because of partialBlock
182 
183  CBlock block2;
184  {
185  PartiallyDownloadedBlock tmp = partialBlock;
186  BOOST_CHECK(partialBlock.FillBlock(block2, {}, /*segwit_active=*/true) == READ_STATUS_INVALID); // No transactions
187  partialBlock = tmp;
188  }
189 
190  // Wrong transaction
191  {
192  PartiallyDownloadedBlock tmp = partialBlock;
193  partialBlock.FillBlock(block2, {block.vtx[1]}, /*segwit_active=*/true); // Current implementation doesn't check txn here, but don't require that
194  partialBlock = tmp;
195  }
196  BOOST_CHECK_EQUAL(pool.get(block.vtx[2]->GetHash()).use_count(), SHARED_TX_OFFSET + 2); // +2 because of partialBlock and block2
197  bool mutated;
198  BOOST_CHECK(block.hashMerkleRoot != BlockMerkleRoot(block2, &mutated));
199 
200  CBlock block3;
201  PartiallyDownloadedBlock partialBlockCopy = partialBlock;
202  BOOST_CHECK(partialBlock.FillBlock(block3, {block.vtx[0]}, /*segwit_active=*/true) == READ_STATUS_OK);
203  BOOST_CHECK_EQUAL(block.GetHash().ToString(), block3.GetHash().ToString());
204  BOOST_CHECK_EQUAL(block.hashMerkleRoot.ToString(), BlockMerkleRoot(block3, &mutated).ToString());
205  BOOST_CHECK(!mutated);
206 
207  BOOST_CHECK_EQUAL(pool.get(block.vtx[2]->GetHash()).use_count(), SHARED_TX_OFFSET + 3); // +2 because of partialBlock and block2 and block3
208 
209  txhash = block.vtx[2]->GetHash();
210  block.vtx.clear();
211  block2.vtx.clear();
212  block3.vtx.clear();
213  BOOST_CHECK_EQUAL(pool.get(txhash).use_count(), SHARED_TX_OFFSET + 1 - 1); // + 1 because of partialBlock; -1 because of block.
214  }
215  BOOST_CHECK_EQUAL(pool.get(txhash).use_count(), SHARED_TX_OFFSET - 1); // -1 because of block
216 }
217 
218 BOOST_AUTO_TEST_CASE(SufficientPreforwardRTTest)
219 {
220  CTxMemPool& pool = *Assert(m_node.mempool);
222  auto rand_ctx(FastRandomContext(uint256{42}));
223  CBlock block(BuildBlockTestCase(rand_ctx));
224 
225  LOCK2(cs_main, pool.cs);
226  TryAddToMempool(pool, entry.FromTx(block.vtx[1]));
227  BOOST_CHECK_EQUAL(pool.get(block.vtx[1]->GetHash()).use_count(), SHARED_TX_OFFSET + 0);
228 
229  Txid txhash;
230 
231  // Test with pre-forwarding coinbase + tx 2 with tx 1 in mempool
232  {
233  TestHeaderAndShortIDs shortIDs(block, rand_ctx);
234  shortIDs.prefilledtxn.resize(2);
235  shortIDs.prefilledtxn[0] = {0, block.vtx[0]};
236  shortIDs.prefilledtxn[1] = {1, block.vtx[2]}; // id == 1 as it is 1 after index 1
237  shortIDs.shorttxids.resize(1);
238  shortIDs.shorttxids[0] = shortIDs.GetShortID(block.vtx[1]->GetWitnessHash());
239 
240  DataStream stream{};
241  stream << shortIDs;
242 
243  CBlockHeaderAndShortTxIDs shortIDs2;
244  stream >> shortIDs2;
245 
246  PartiallyDownloadedBlock partialBlock(&pool);
247  BOOST_CHECK(partialBlock.InitData(shortIDs2, empty_extra_txn) == READ_STATUS_OK);
248  BOOST_CHECK( partialBlock.IsTxAvailable(0));
249  BOOST_CHECK( partialBlock.IsTxAvailable(1));
250  BOOST_CHECK( partialBlock.IsTxAvailable(2));
251 
252  BOOST_CHECK_EQUAL(pool.get(block.vtx[1]->GetHash()).use_count(), SHARED_TX_OFFSET + 1);
253 
254  CBlock block2;
255  PartiallyDownloadedBlock partialBlockCopy = partialBlock;
256  BOOST_CHECK(partialBlock.FillBlock(block2, {}, /*segwit_active=*/true) == READ_STATUS_OK);
257  BOOST_CHECK_EQUAL(block.GetHash().ToString(), block2.GetHash().ToString());
258  bool mutated;
259  BOOST_CHECK_EQUAL(block.hashMerkleRoot.ToString(), BlockMerkleRoot(block2, &mutated).ToString());
260  BOOST_CHECK(!mutated);
261 
262  txhash = block.vtx[1]->GetHash();
263  block.vtx.clear();
264  block2.vtx.clear();
265  BOOST_CHECK_EQUAL(pool.get(txhash).use_count(), SHARED_TX_OFFSET + 1 - 1); // + 1 because of partialBlock; -1 because of block.
266  }
267  BOOST_CHECK_EQUAL(pool.get(txhash).use_count(), SHARED_TX_OFFSET - 1); // -1 because of block
268 }
269 
270 BOOST_AUTO_TEST_CASE(EmptyBlockRoundTripTest)
271 {
272  CTxMemPool& pool = *Assert(m_node.mempool);
274 
275  CBlock block;
276  auto rand_ctx(FastRandomContext(uint256{42}));
277  block.vtx.resize(1);
278  block.vtx[0] = MakeTransactionRef(std::move(coinbase));
279  block.nVersion = 42;
280  block.hashPrevBlock = rand_ctx.rand256();
281  block.nBits = 0x207fffff;
282 
283  bool mutated;
284  block.hashMerkleRoot = BlockMerkleRoot(block, &mutated);
285  assert(!mutated);
286  while (!CheckProofOfWork(block.GetHash(), block.nBits, Params().GetConsensus())) ++block.nNonce;
287 
288  // Test simple header round-trip with only coinbase
289  {
290  CBlockHeaderAndShortTxIDs shortIDs{block, rand_ctx.rand64()};
291 
292  DataStream stream{};
293  stream << shortIDs;
294 
295  CBlockHeaderAndShortTxIDs shortIDs2;
296  stream >> shortIDs2;
297 
298  PartiallyDownloadedBlock partialBlock(&pool);
299  BOOST_CHECK(partialBlock.InitData(shortIDs2, empty_extra_txn) == READ_STATUS_OK);
300  BOOST_CHECK(partialBlock.IsTxAvailable(0));
301 
302  CBlock block2;
303  std::vector<CTransactionRef> vtx_missing;
304  BOOST_CHECK(partialBlock.FillBlock(block2, vtx_missing, /*segwit_active=*/true) == READ_STATUS_OK);
305  BOOST_CHECK_EQUAL(block.GetHash().ToString(), block2.GetHash().ToString());
306  BOOST_CHECK_EQUAL(block.hashMerkleRoot.ToString(), BlockMerkleRoot(block2, &mutated).ToString());
307  BOOST_CHECK(!mutated);
308  }
309 }
310 
311 BOOST_AUTO_TEST_CASE(ReceiveWithExtraTransactions) {
312  CTxMemPool& pool = *Assert(m_node.mempool);
314  auto rand_ctx(FastRandomContext(uint256{42}));
315 
317  mtx.vin[0].prevout.hash = Txid::FromUint256(rand_ctx.rand256());
318  mtx.vin[0].prevout.n = 0;
319  const CTransactionRef non_block_tx = MakeTransactionRef(std::move(mtx));
320 
321  CBlock block(BuildBlockTestCase(rand_ctx));
322  std::vector<std::pair<Wtxid, CTransactionRef>> extra_txn;
323  extra_txn.resize(10);
324 
325  LOCK2(cs_main, pool.cs);
326  TryAddToMempool(pool, entry.FromTx(block.vtx[2]));
327  BOOST_CHECK_EQUAL(pool.get(block.vtx[2]->GetHash()).use_count(), SHARED_TX_OFFSET + 0);
328  // Ensure the non_block_tx is actually not in the block
329  for (const auto &block_tx : block.vtx) {
330  BOOST_CHECK_NE(block_tx->GetHash(), non_block_tx->GetHash());
331  }
332  // Ensure block.vtx[1] is not in pool
333  BOOST_CHECK_EQUAL(pool.get(block.vtx[1]->GetHash()), nullptr);
334 
335  {
336  const CBlockHeaderAndShortTxIDs cmpctblock{block, rand_ctx.rand64()};
337  PartiallyDownloadedBlock partial_block(&pool);
338  PartiallyDownloadedBlock partial_block_with_extra(&pool);
339 
340  BOOST_CHECK(partial_block.InitData(cmpctblock, extra_txn) == READ_STATUS_OK);
341  BOOST_CHECK( partial_block.IsTxAvailable(0));
342  BOOST_CHECK(!partial_block.IsTxAvailable(1));
343  BOOST_CHECK( partial_block.IsTxAvailable(2));
344 
345  // Add an unrelated tx to extra_txn:
346  extra_txn[0] = {non_block_tx->GetWitnessHash(), non_block_tx};
347  // and a tx from the block that's not in the mempool:
348  extra_txn[1] = {block.vtx[1]->GetWitnessHash(), block.vtx[1]};
349 
350  BOOST_CHECK(partial_block_with_extra.InitData(cmpctblock, extra_txn) == READ_STATUS_OK);
351  BOOST_CHECK(partial_block_with_extra.IsTxAvailable(0));
352  // This transaction is now available via extra_txn:
353  BOOST_CHECK(partial_block_with_extra.IsTxAvailable(1));
354  BOOST_CHECK(partial_block_with_extra.IsTxAvailable(2));
355  }
356 }
357 
358 BOOST_AUTO_TEST_CASE(TransactionsRequestSerializationTest) {
360  req1.blockhash = m_rng.rand256();
361  req1.indexes.resize(4);
362  req1.indexes[0] = 0;
363  req1.indexes[1] = 1;
364  req1.indexes[2] = 3;
365  req1.indexes[3] = 4;
366 
367  DataStream stream{};
368  stream << req1;
369 
371  stream >> req2;
372 
373  BOOST_CHECK_EQUAL(req1.blockhash.ToString(), req2.blockhash.ToString());
374  BOOST_CHECK_EQUAL(req1.indexes.size(), req2.indexes.size());
375  BOOST_CHECK_EQUAL(req1.indexes[0], req2.indexes[0]);
376  BOOST_CHECK_EQUAL(req1.indexes[1], req2.indexes[1]);
377  BOOST_CHECK_EQUAL(req1.indexes[2], req2.indexes[2]);
378  BOOST_CHECK_EQUAL(req1.indexes[3], req2.indexes[3]);
379 }
380 
381 BOOST_AUTO_TEST_CASE(TransactionsRequestDeserializationMaxTest) {
382  // Check that the highest legal index is decoded correctly
384  req0.blockhash = m_rng.rand256();
385  req0.indexes.resize(1);
386  req0.indexes[0] = 0xffff;
387  DataStream stream{};
388  stream << req0;
389 
391  stream >> req1;
392  BOOST_CHECK_EQUAL(req0.indexes.size(), req1.indexes.size());
393  BOOST_CHECK_EQUAL(req0.indexes[0], req1.indexes[0]);
394 }
395 
396 BOOST_AUTO_TEST_CASE(TransactionsRequestDeserializationOverflowTest) {
397  // Any set of index deltas that starts with N values that sum to (0x10000 - N)
398  // causes the edge-case overflow that was originally not checked for. Such
399  // a request cannot be created by serializing a real BlockTransactionsRequest
400  // due to the overflow, so here we'll serialize from raw deltas.
402  req0.blockhash = m_rng.rand256();
403  req0.indexes.resize(3);
404  req0.indexes[0] = 0x7000;
405  req0.indexes[1] = 0x10000 - 0x7000 - 2;
406  req0.indexes[2] = 0;
407  DataStream stream{};
408  stream << req0.blockhash;
409  WriteCompactSize(stream, req0.indexes.size());
410  WriteCompactSize(stream, req0.indexes[0]);
411  WriteCompactSize(stream, req0.indexes[1]);
412  WriteCompactSize(stream, req0.indexes[2]);
413 
415  try {
416  stream >> req1;
417  // before patch: deserialize above succeeds and this check fails, demonstrating the overflow
418  BOOST_CHECK(req1.indexes[1] < req1.indexes[2]);
419  // this shouldn't be reachable before or after patch
420  BOOST_CHECK(0);
421  } catch(std::ios_base::failure &) {
422  // deserialize should fail
423  BOOST_CHECK(true); // Needed to suppress "Test case [...] did not check any assertions"
424  }
425 }
426 
std::shared_ptr< const CTransaction > CTransactionRef
Definition: transaction.h:403
uint32_t nNonce
Definition: block.h:35
ReadStatus InitData(const CBlockHeaderAndShortTxIDs &cmpctblock, const std::vector< std::pair< Wtxid, CTransactionRef >> &extra_txn)
assert(!tx.IsCoinBase())
Definition: txmempool.h:19
Definition: block.h:73
node::NodeContext m_node
Definition: bitcoin-gui.cpp:43
std::vector< uint16_t > indexes
static CMutableTransaction BuildTransactionTestCase()
std::vector< CTxIn > vin
Definition: transaction.h:359
unsigned long size() const
Definition: txmempool.h:485
BOOST_AUTO_TEST_CASE(SimpleRoundTripTest)
const std::vector< std::pair< Wtxid, CTransactionRef > > empty_extra_txn
CTransactionRef get(const Txid &hash) const
Definition: txmempool.cpp:621
TryAddToMempool(pool, CTxMemPoolEntry(tx, fee, 0, 1, 0, false, 4, lp))
CTxMemPoolEntry FromTx(const CMutableTransaction &tx) const
Definition: txmempool.cpp:34
SERIALIZE_METHODS(TestHeaderAndShortIDs, obj)
void check(const CCoinsViewCache &active_coins_tip, int64_t spendheight) const EXCLUSIVE_LOCKS_REQUIRED(void removeRecursive(const CTransaction &tx, MemPoolRemovalReason reason) EXCLUSIVE_LOCKS_REQUIRED(cs)
If sanity-checking is turned on, check makes sure the pool is consistent (does not contain two transa...
Definition: txmempool.h:325
uint64_t GetShortID(const Wtxid &txhash) const
static Wrapper< Formatter, T & > Using(T &&t)
Cause serialization/deserialization of an object to be done using a specified formatter class...
Definition: serialize.h:488
std::unique_ptr< CTxMemPool > mempool
Definition: context.h:68
std::vector< uint64_t > shorttxids
#define LOCK2(cs1, cs2)
Definition: sync.h:259
std::vector< PrefilledTransaction > prefilledtxn
uint256 hashMerkleRoot
Definition: block.h:32
constexpr long SHARED_TX_OFFSET
BOOST_FIXTURE_TEST_SUITE(cuckoocache_tests, BasicTestingSetup)
Test Suite for CuckooCache.
Double ended buffer combining vector and stream-like interfaces.
Definition: streams.h:132
void WriteCompactSize(SizeComputer &os, uint64_t nSize)
Definition: serialize.h:1089
Fast randomness source.
Definition: random.h:385
BOOST_AUTO_TEST_SUITE_END()
TestHeaderAndShortIDs(const CBlockHeaderAndShortTxIDs &orig)
uint256 hashPrevBlock
Definition: block.h:31
uint256 BlockMerkleRoot(const CBlock &block, bool *mutated)
Definition: merkle.cpp:66
static CBlock BuildBlockTestCase(FastRandomContext &ctx)
std::string ToString() const
Definition: uint256.cpp:21
bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params &params)
Check whether a block hash satisfies the proof-of-work requirement specified by nBits.
Definition: pow.cpp:140
std::vector< CTxOut > vout
Definition: transaction.h:360
TestHeaderAndShortIDs(const CBlock &block, FastRandomContext &ctx)
static CTransactionRef MakeTransactionRef(Tx &&txIn)
Definition: transaction.h:404
uint256 GetHash() const
Definition: block.cpp:15
256-bit opaque blob.
Definition: uint256.h:195
std::vector< CTransactionRef > vtx
Definition: block.h:77
CTxMemPool stores valid-according-to-the-current-best-chain transactions that may be included in the ...
Definition: txmempool.h:186
#define BOOST_CHECK_EQUAL(v1, v2)
Definition: object.cpp:17
const CChainParams & Params()
Return the currently selected parameters.
static transaction_identifier FromUint256(const uint256 &id)
bool IsTxAvailable(size_t index) const
uint256 rand256() noexcept
generate a random uint256.
Definition: random.h:317
Serialization wrapper class for custom integers and enums.
Definition: serialize.h:520
A mutable version of CTransaction.
Definition: transaction.h:357
Formatter to serialize/deserialize vector elements using another formatter.
Definition: serialize.h:649
const Consensus::Params & GetConsensus() const
Definition: chainparams.h:89
#define READWRITE(...)
Definition: serialize.h:145
Identical to TestingSetup, but chain set to regtest.
Definition: setup_common.h:128
uint64_t rand64() noexcept
Generate a random 64-bit integer.
Definition: random.h:404
Removed for replacement.
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate...
Definition: cs_main.cpp:8
int32_t nVersion
Definition: block.h:30
Nodes collect new transactions into a block, hash them into a hash tree, and scan through nonce value...
Definition: block.h:26
ReadStatus FillBlock(CBlock &block, const std::vector< CTransactionRef > &vtx_missing, bool segwit_active)
RecursiveMutex cs
This mutex needs to be locked when accessing mapTx or other members that are guarded by it...
Definition: txmempool.h:260
#define Assert(val)
Identity function.
Definition: check.h:113
uint32_t nBits
Definition: block.h:34
uint64_t GetShortID(const Wtxid &wtxid) const
#define BOOST_CHECK(expr)
Definition: object.cpp:16
transaction_identifier represents the two canonical transaction identifier types (txid, wtxid).