Bitcoin Core 31.99.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>
15
16#include <boost/test/unit_test.hpp>
17
18const std::vector<std::pair<Wtxid, CTransactionRef>> empty_extra_txn;
19
20BOOST_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)
61constexpr long SHARED_TX_OFFSET{3};
62
63BOOST_AUTO_TEST_CASE(SimpleRoundTripTest)
64{
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
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());
116 BOOST_CHECK(!mutated);
117 }
118}
119
121 // Utility to encode custom CBlockHeaderAndShortTxIDs
122public:
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) :
134 TestHeaderAndShortIDs(CBlockHeaderAndShortTxIDs{block, ctx.rand64()}) {}
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
149
150 size_t GetMempoolCount() const { return mempool_count; }
151 size_t GetExtraCount() const { return extra_count; }
152};
153
154BOOST_AUTO_TEST_CASE(NonCoinbasePreforwardRTTest)
155{
158 auto rand_ctx(FastRandomContext(uint256{42}));
159 CBlock block(BuildBlockTestCase(rand_ctx));
160
161 LOCK2(cs_main, pool.cs);
162 TryAddToMempool(pool, entry.FromTx(block.vtx[2]));
163 BOOST_CHECK_EQUAL(pool.get(block.vtx[2]->GetHash()).use_count(), SHARED_TX_OFFSET + 0);
164
165 Txid txhash;
166
167 // Test with pre-forwarding tx 1, but not coinbase
168 {
169 TestHeaderAndShortIDs shortIDs(block, rand_ctx);
170 shortIDs.prefilledtxn.resize(1);
171 shortIDs.prefilledtxn[0] = {1, block.vtx[1]};
172 shortIDs.shorttxids.resize(2);
173 shortIDs.shorttxids[0] = shortIDs.GetShortID(block.vtx[0]->GetWitnessHash());
174 shortIDs.shorttxids[1] = shortIDs.GetShortID(block.vtx[2]->GetWitnessHash());
175
176 DataStream stream{};
177 stream << shortIDs;
178
180 stream >> shortIDs2;
181
182 PartiallyDownloadedBlock partialBlock(&pool);
183 BOOST_CHECK(partialBlock.InitData(shortIDs2, empty_extra_txn) == READ_STATUS_OK);
184 BOOST_CHECK(!partialBlock.IsTxAvailable(0));
185 BOOST_CHECK( partialBlock.IsTxAvailable(1));
186 BOOST_CHECK( partialBlock.IsTxAvailable(2));
187
188 BOOST_CHECK_EQUAL(pool.get(block.vtx[2]->GetHash()).use_count(), SHARED_TX_OFFSET + 1); // +1 because of partialBlock
189
190 CBlock block2;
191 {
192 PartiallyDownloadedBlock tmp = partialBlock;
193 BOOST_CHECK(partialBlock.FillBlock(block2, {}, /*segwit_active=*/true) == READ_STATUS_INVALID); // No transactions
194 partialBlock = tmp;
195 }
196
197 // Wrong transaction
198 {
199 PartiallyDownloadedBlock tmp = partialBlock;
200 partialBlock.FillBlock(block2, {block.vtx[1]}, /*segwit_active=*/true); // Current implementation doesn't check txn here, but don't require that
201 partialBlock = tmp;
202 }
203 BOOST_CHECK_EQUAL(pool.get(block.vtx[2]->GetHash()).use_count(), SHARED_TX_OFFSET + 2); // +2 because of partialBlock and block2
204 bool mutated;
205 BOOST_CHECK(block.hashMerkleRoot != BlockMerkleRoot(block2, &mutated));
206
207 CBlock block3;
208 PartiallyDownloadedBlock partialBlockCopy = partialBlock;
209 BOOST_CHECK(partialBlock.FillBlock(block3, {block.vtx[0]}, /*segwit_active=*/true) == READ_STATUS_OK);
210 BOOST_CHECK_EQUAL(block.GetHash().ToString(), block3.GetHash().ToString());
212 BOOST_CHECK(!mutated);
213
214 BOOST_CHECK_EQUAL(pool.get(block.vtx[2]->GetHash()).use_count(), SHARED_TX_OFFSET + 3); // +2 because of partialBlock and block2 and block3
215
216 txhash = block.vtx[2]->GetHash();
217 block.vtx.clear();
218 block2.vtx.clear();
219 block3.vtx.clear();
220 BOOST_CHECK_EQUAL(pool.get(txhash).use_count(), SHARED_TX_OFFSET + 1 - 1); // + 1 because of partialBlock; -1 because of block.
221 }
222 BOOST_CHECK_EQUAL(pool.get(txhash).use_count(), SHARED_TX_OFFSET - 1); // -1 because of block
223}
224
225BOOST_AUTO_TEST_CASE(SufficientPreforwardRTTest)
226{
229 auto rand_ctx(FastRandomContext(uint256{42}));
230 CBlock block(BuildBlockTestCase(rand_ctx));
231
232 LOCK2(cs_main, pool.cs);
233 TryAddToMempool(pool, entry.FromTx(block.vtx[1]));
234 BOOST_CHECK_EQUAL(pool.get(block.vtx[1]->GetHash()).use_count(), SHARED_TX_OFFSET + 0);
235
236 Txid txhash;
237
238 // Test with pre-forwarding coinbase + tx 2 with tx 1 in mempool
239 {
240 TestHeaderAndShortIDs shortIDs(block, rand_ctx);
241 shortIDs.prefilledtxn.resize(2);
242 shortIDs.prefilledtxn[0] = {0, block.vtx[0]};
243 shortIDs.prefilledtxn[1] = {1, block.vtx[2]}; // id == 1 as it is 1 after index 1
244 shortIDs.shorttxids.resize(1);
245 shortIDs.shorttxids[0] = shortIDs.GetShortID(block.vtx[1]->GetWitnessHash());
246
247 DataStream stream{};
248 stream << shortIDs;
249
251 stream >> shortIDs2;
252
253 PartiallyDownloadedBlock partialBlock(&pool);
254 BOOST_CHECK(partialBlock.InitData(shortIDs2, empty_extra_txn) == READ_STATUS_OK);
255 BOOST_CHECK( partialBlock.IsTxAvailable(0));
256 BOOST_CHECK( partialBlock.IsTxAvailable(1));
257 BOOST_CHECK( partialBlock.IsTxAvailable(2));
258
259 BOOST_CHECK_EQUAL(pool.get(block.vtx[1]->GetHash()).use_count(), SHARED_TX_OFFSET + 1);
260
261 CBlock block2;
262 PartiallyDownloadedBlock partialBlockCopy = partialBlock;
263 BOOST_CHECK(partialBlock.FillBlock(block2, {}, /*segwit_active=*/true) == READ_STATUS_OK);
264 BOOST_CHECK_EQUAL(block.GetHash().ToString(), block2.GetHash().ToString());
265 bool mutated;
267 BOOST_CHECK(!mutated);
268
269 txhash = block.vtx[1]->GetHash();
270 block.vtx.clear();
271 block2.vtx.clear();
272 BOOST_CHECK_EQUAL(pool.get(txhash).use_count(), SHARED_TX_OFFSET + 1 - 1); // + 1 because of partialBlock; -1 because of block.
273 }
274 BOOST_CHECK_EQUAL(pool.get(txhash).use_count(), SHARED_TX_OFFSET - 1); // -1 because of block
275}
276
277BOOST_AUTO_TEST_CASE(EmptyBlockRoundTripTest)
278{
281
282 CBlock block;
283 auto rand_ctx(FastRandomContext(uint256{42}));
284 block.vtx.resize(1);
285 block.vtx[0] = MakeTransactionRef(std::move(coinbase));
286 block.nVersion = 42;
287 block.hashPrevBlock = rand_ctx.rand256();
288 block.nBits = 0x207fffff;
289
290 bool mutated;
291 block.hashMerkleRoot = BlockMerkleRoot(block, &mutated);
292 assert(!mutated);
293 while (!CheckProofOfWork(block.GetHash(), block.nBits, Params().GetConsensus())) ++block.nNonce;
294
295 // Test simple header round-trip with only coinbase
296 {
297 CBlockHeaderAndShortTxIDs shortIDs{block, rand_ctx.rand64()};
298
299 DataStream stream{};
300 stream << shortIDs;
301
303 stream >> shortIDs2;
304
305 PartiallyDownloadedBlock partialBlock(&pool);
306 BOOST_CHECK(partialBlock.InitData(shortIDs2, empty_extra_txn) == READ_STATUS_OK);
307 BOOST_CHECK(partialBlock.IsTxAvailable(0));
308
309 CBlock block2;
310 std::vector<CTransactionRef> vtx_missing;
311 BOOST_CHECK(partialBlock.FillBlock(block2, vtx_missing, /*segwit_active=*/true) == READ_STATUS_OK);
312 BOOST_CHECK_EQUAL(block.GetHash().ToString(), block2.GetHash().ToString());
314 BOOST_CHECK(!mutated);
315 }
316}
317
318BOOST_AUTO_TEST_CASE(ReceiveWithExtraTransactions) {
321 auto rand_ctx(FastRandomContext(uint256{42}));
322
324 mtx.vin[0].prevout.hash = Txid::FromUint256(rand_ctx.rand256());
325 mtx.vin[0].prevout.n = 0;
326 const CTransactionRef non_block_tx = MakeTransactionRef(std::move(mtx));
327
328 CBlock block(BuildBlockTestCase(rand_ctx));
329 // Leave one transaction missing so scanning doesn't stop before the collision.
331 mtx.vin[0].prevout.hash = Txid::FromUint256(rand_ctx.rand256());
332 block.vtx.push_back(MakeTransactionRef(std::move(mtx)));
333 block.hashMerkleRoot = BlockMerkleRoot(block);
334 while (!CheckProofOfWork(block.GetHash(), block.nBits, Params().GetConsensus())) ++block.nNonce;
335
336 std::vector<std::pair<Wtxid, CTransactionRef>> extra_txn;
337 extra_txn.resize(10);
338
339 LOCK2(cs_main, pool.cs);
340 TryAddToMempool(pool, entry.FromTx(block.vtx[2]));
341 BOOST_CHECK_EQUAL(pool.get(block.vtx[2]->GetHash()).use_count(), SHARED_TX_OFFSET + 0);
342 // Ensure the non_block_tx is actually not in the block
343 for (const auto &block_tx : block.vtx) {
344 BOOST_CHECK_NE(block_tx->GetHash(), non_block_tx->GetHash());
345 }
346 // Ensure block.vtx[1] is not in pool
347 BOOST_CHECK_EQUAL(pool.get(block.vtx[1]->GetHash()), nullptr);
348
349 {
350 const CBlockHeaderAndShortTxIDs cmpctblock{block, rand_ctx.rand64()};
351 PartiallyDownloadedBlock partial_block(&pool);
352 PartiallyDownloadedBlock partial_block_with_extra(&pool);
353
354 BOOST_CHECK(partial_block.InitData(cmpctblock, extra_txn) == READ_STATUS_OK);
355 BOOST_CHECK( partial_block.IsTxAvailable(0));
356 BOOST_CHECK(!partial_block.IsTxAvailable(1));
357 BOOST_CHECK( partial_block.IsTxAvailable(2));
358
359 // Add an unrelated tx to extra_txn:
360 extra_txn[0] = {non_block_tx->GetWitnessHash(), non_block_tx};
361 // and a tx from the block that's not in the mempool:
362 extra_txn[1] = {block.vtx[1]->GetWitnessHash(), block.vtx[1]};
363
364 BOOST_CHECK(partial_block_with_extra.InitData(cmpctblock, extra_txn) == READ_STATUS_OK);
365 BOOST_CHECK(partial_block_with_extra.IsTxAvailable(0));
366 // This transaction is now available via extra_txn:
367 BOOST_CHECK(partial_block_with_extra.IsTxAvailable(1));
368 BOOST_CHECK(partial_block_with_extra.IsTxAvailable(2));
369
370 // Simulate a mempool collision after finding an unrelated extra transaction.
371 extra_txn[2] = {block.vtx[2]->GetWitnessHash(), non_block_tx};
372 TestPartiallyDownloadedBlock partial_block_with_extra_collision{&pool};
373 BOOST_CHECK_EQUAL(partial_block_with_extra_collision.InitData(cmpctblock, extra_txn), READ_STATUS_OK);
374 BOOST_CHECK(partial_block_with_extra_collision.IsTxAvailable(1));
375 BOOST_CHECK(!partial_block_with_extra_collision.IsTxAvailable(2));
376 BOOST_CHECK_EQUAL(partial_block_with_extra_collision.GetMempoolCount(), 1U);
377 BOOST_CHECK_EQUAL(partial_block_with_extra_collision.GetExtraCount(), 1U);
378
379 // Now also collide the extra-sourced slot: both counters decrement exactly once.
380 extra_txn[3] = {block.vtx[1]->GetWitnessHash(), non_block_tx};
381 TestPartiallyDownloadedBlock partial_block_with_extra_source_collision{&pool};
382 BOOST_CHECK_EQUAL(partial_block_with_extra_source_collision.InitData(cmpctblock, extra_txn), READ_STATUS_OK);
383 BOOST_CHECK(!partial_block_with_extra_source_collision.IsTxAvailable(1));
384 BOOST_CHECK(!partial_block_with_extra_source_collision.IsTxAvailable(2));
385 BOOST_CHECK_EQUAL(partial_block_with_extra_source_collision.GetMempoolCount(), 0U);
386 BOOST_CHECK_EQUAL(partial_block_with_extra_source_collision.GetExtraCount(), 0U);
387
388 // Collided slots are terminal: not even the genuine transactions refill them.
389 extra_txn[4] = {block.vtx[2]->GetWitnessHash(), block.vtx[2]};
390 extra_txn[5] = {block.vtx[1]->GetWitnessHash(), block.vtx[1]};
391 TestPartiallyDownloadedBlock partial_block_no_refill{&pool};
392 BOOST_CHECK_EQUAL(partial_block_no_refill.InitData(cmpctblock, extra_txn), READ_STATUS_OK);
393 BOOST_CHECK(!partial_block_no_refill.IsTxAvailable(1));
394 BOOST_CHECK(!partial_block_no_refill.IsTxAvailable(2));
395 BOOST_CHECK_EQUAL(partial_block_no_refill.GetMempoolCount(), 0U);
396 BOOST_CHECK_EQUAL(partial_block_no_refill.GetExtraCount(), 0U);
397 }
398}
399
400BOOST_AUTO_TEST_CASE(TransactionsRequestSerializationTest) {
402 req1.blockhash = m_rng.rand256();
403 req1.indexes.resize(4);
404 req1.indexes[0] = 0;
405 req1.indexes[1] = 1;
406 req1.indexes[2] = 3;
407 req1.indexes[3] = 4;
408
409 DataStream stream{};
410 stream << req1;
411
413 stream >> req2;
414
416 BOOST_CHECK_EQUAL(req1.indexes.size(), req2.indexes.size());
417 BOOST_CHECK_EQUAL(req1.indexes[0], req2.indexes[0]);
418 BOOST_CHECK_EQUAL(req1.indexes[1], req2.indexes[1]);
419 BOOST_CHECK_EQUAL(req1.indexes[2], req2.indexes[2]);
420 BOOST_CHECK_EQUAL(req1.indexes[3], req2.indexes[3]);
421}
422
423BOOST_AUTO_TEST_CASE(TransactionsRequestDeserializationMaxTest) {
424 // Check that the highest legal index is decoded correctly
426 req0.blockhash = m_rng.rand256();
427 req0.indexes.resize(1);
428 req0.indexes[0] = 0xffff;
429 DataStream stream{};
430 stream << req0;
431
433 stream >> req1;
434 BOOST_CHECK_EQUAL(req0.indexes.size(), req1.indexes.size());
435 BOOST_CHECK_EQUAL(req0.indexes[0], req1.indexes[0]);
436}
437
438BOOST_AUTO_TEST_CASE(TransactionsRequestDeserializationOverflowTest) {
439 // Any set of index deltas that starts with N values that sum to (0x10000 - N)
440 // causes the edge-case overflow that was originally not checked for. Such
441 // a request cannot be created by serializing a real BlockTransactionsRequest
442 // due to the overflow, so here we'll serialize from raw deltas.
444 req0.blockhash = m_rng.rand256();
445 req0.indexes.resize(3);
446 req0.indexes[0] = 0x7000;
447 req0.indexes[1] = 0x10000 - 0x7000 - 2;
448 req0.indexes[2] = 0;
449 DataStream stream{};
450 stream << req0.blockhash;
451 WriteCompactSize(stream, req0.indexes.size());
452 WriteCompactSize(stream, req0.indexes[0]);
453 WriteCompactSize(stream, req0.indexes[1]);
454 WriteCompactSize(stream, req0.indexes[2]);
455
457 try {
458 stream >> req1;
459 // before patch: deserialize above succeeds and this check fails, demonstrating the overflow
460 BOOST_CHECK(req1.indexes[1] < req1.indexes[2]);
461 // this shouldn't be reachable before or after patch
462 BOOST_CHECK(0);
463 } catch(std::ios_base::failure &) {
464 // deserialize should fail
465 BOOST_CHECK(true); // Needed to suppress "Test case [...] did not check any assertions"
466 }
467}
468
TryAddToMempool(pool, CTxMemPoolEntry(tx, fee, 0, 1, 0, false, 4, lp))
node::NodeContext m_node
Definition: bitcoin-gui.cpp:47
@ READ_STATUS_OK
@ READ_STATUS_INVALID
static CBlock BuildBlockTestCase(FastRandomContext &ctx)
BOOST_AUTO_TEST_CASE(SimpleRoundTripTest)
const std::vector< std::pair< Wtxid, CTransactionRef > > empty_extra_txn
constexpr long SHARED_TX_OFFSET
static CMutableTransaction BuildTransactionTestCase()
const CChainParams & Params()
Return the currently selected parameters.
#define Assert(val)
Identity function.
Definition: check.h:116
std::vector< uint16_t > indexes
uint64_t GetShortID(const Wtxid &wtxid) const
Nodes collect new transactions into a block, hash them into a hash tree, and scan through nonce value...
Definition: block.h:27
uint32_t nNonce
Definition: block.h:35
uint32_t nBits
Definition: block.h:34
int32_t nVersion
Definition: block.h:30
uint256 hashPrevBlock
Definition: block.h:31
uint256 hashMerkleRoot
Definition: block.h:32
uint256 GetHash() const
Definition: block.cpp:14
Definition: block.h:74
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:187
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:323
CTransactionRef get(const Txid &hash) const
Return a mempool transaction with a given hash.
Definition: txmempool.cpp:662
unsigned long size() const
Definition: txmempool.h:495
Double ended buffer combining vector and stream-like interfaces.
Definition: streams.h:165
Fast randomness source.
Definition: random.h:386
PartiallyDownloadedBlock(CTxMemPool *poolIn)
ReadStatus FillBlock(CBlock &block, const std::vector< CTransactionRef > &vtx_missing, bool segwit_active)
bool IsTxAvailable(size_t index) const
ReadStatus InitData(const CBlockHeaderAndShortTxIDs &cmpctblock, const std::vector< std::pair< Wtxid, CTransactionRef > > &extra_txn)
uint256 rand256() noexcept
generate a random uint256.
Definition: random.h:317
TestHeaderAndShortIDs(const CBlockHeaderAndShortTxIDs &orig)
std::vector< uint64_t > shorttxids
std::vector< PrefilledTransaction > prefilledtxn
TestHeaderAndShortIDs(const CBlock &block, FastRandomContext &ctx)
uint64_t GetShortID(const Wtxid &txhash) const
SERIALIZE_METHODS(TestHeaderAndShortIDs, obj)
std::string ToString() const
Definition: uint256.cpp:21
transaction_identifier represents the two canonical transaction identifier types (txid,...
static transaction_identifier FromUint256(const uint256 &id)
256-bit opaque blob.
Definition: uint256.h:196
uint256 BlockMerkleRoot(const CBlock &block, bool *mutated)
Definition: merkle.cpp:66
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate.
Definition: cs_main.cpp:8
BOOST_FIXTURE_TEST_SUITE(cuckoocache_tests, BasicTestingSetup)
Test Suite for CuckooCache.
BOOST_AUTO_TEST_SUITE_END()
BOOST_CHECK_EQUAL(headers.FindFirst("key"), "value")
@ REPLACED
Removed for replacement.
std::string ToString(const T &t)
Locale-independent version of std::to_string.
Definition: string.h:249
#define BOOST_CHECK(expr)
Definition: object.cpp:16
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
static CTransactionRef MakeTransactionRef(Tx &&txIn)
Definition: transaction.h:404
std::shared_ptr< const CTransaction > CTransactionRef
Definition: transaction.h:403
void WriteCompactSize(SizeComputer &os, uint64_t nSize)
Definition: serialize.h:1151
static Wrapper< Formatter, T & > Using(T &&t)
Cause serialization/deserialization of an object to be done using a specified formatter class.
Definition: serialize.h:491
#define READWRITE(...)
Definition: serialize.h:148
A mutable version of CTransaction.
Definition: transaction.h:358
std::vector< CTxOut > vout
Definition: transaction.h:360
std::vector< CTxIn > vin
Definition: transaction.h:359
Serialization wrapper class for custom integers and enums.
Definition: serialize.h:525
Identical to TestingSetup, but chain set to regtest.
Definition: setup_common.h:122
Definition: txmempool.h:19
CTxMemPoolEntry FromTx(const CMutableTransaction &tx) const
Definition: txmempool.cpp:34
Formatter to serialize/deserialize vector elements using another formatter.
Definition: serialize.h:667
std::unique_ptr< CTxMemPool > mempool
Definition: context.h:71
#define LOCK2(cs1, cs2)
Definition: sync.h:269
assert(!tx.IsCoinBase())