Bitcoin Core 31.0.0
P2P Digital Currency
Loading...
Searching...
No Matches
txvalidation_tests.cpp
Go to the documentation of this file.
1// Copyright (c) 2017-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
6#include <key_io.h>
7#include <policy/packages.h>
8#include <policy/policy.h>
10#include <policy/truc_policy.h>
12#include <random.h>
13#include <script/script.h>
14#include <test/util/common.h>
16#include <test/util/txmempool.h>
17#include <validation.h>
18
19#include <boost/test/unit_test.hpp>
20
21
23
24
28{
29 CScript scriptPubKey = CScript() << ToByteVector(coinbaseKey.GetPubKey()) << OP_CHECKSIG;
31
33 coinbaseTx.vin.resize(1);
34 coinbaseTx.vout.resize(1);
35 coinbaseTx.vin[0].scriptSig = CScript() << OP_11 << OP_EQUAL;
36 coinbaseTx.vout[0].nValue = 1 * CENT;
37 coinbaseTx.vout[0].scriptPubKey = scriptPubKey;
38
39 BOOST_CHECK(CTransaction(coinbaseTx).IsCoinBase());
40
42
43 unsigned int initialPoolSize = m_node.mempool->size();
44 const MempoolAcceptResult result = m_node.chainman->ProcessTransaction(MakeTransactionRef(coinbaseTx));
45
47
48 // Check that the transaction hasn't been added to mempool.
50
51 // Check that the validation state reflects the unsuccessful attempt.
53 BOOST_CHECK_EQUAL(result.m_state.GetRejectReason(), "coinbase");
55}
56
57// Generate a number of random, nonexistent outpoints.
58static inline std::vector<COutPoint> random_outpoints(size_t num_outpoints) {
59 std::vector<COutPoint> outpoints;
60 for (size_t i{0}; i < num_outpoints; ++i) {
61 outpoints.emplace_back(Txid::FromUint256(GetRandHash()), 0);
62 }
63 return outpoints;
64}
65
66static inline std::vector<CPubKey> random_keys(size_t num_keys) {
67 std::vector<CPubKey> keys;
68 keys.reserve(num_keys);
69 for (size_t i{0}; i < num_keys; ++i) {
70 CKey key;
71 key.MakeNewKey(true);
72 keys.emplace_back(key.GetPubKey());
73 }
74 return keys;
75}
76
77// Creates a placeholder tx (not valid) with 25 outputs. Specify the version and the inputs.
78static inline CTransactionRef make_tx(const std::vector<COutPoint>& inputs, int32_t version)
79{
81 mtx.version = version;
82 mtx.vin.resize(inputs.size());
83 mtx.vout.resize(25);
84 for (size_t i{0}; i < inputs.size(); ++i) {
85 mtx.vin[i].prevout = inputs[i];
86 }
87 for (auto i{0}; i < 25; ++i) {
88 mtx.vout[i].scriptPubKey = CScript() << OP_TRUE;
89 mtx.vout[i].nValue = 10000;
90 }
91 return MakeTransactionRef(mtx);
92}
93
94static constexpr auto NUM_EPHEMERAL_TX_OUTPUTS = 3;
96
97// Same as make_tx but adds 2 normal outputs and 0-value dust to end of vout
98static inline CTransactionRef make_ephemeral_tx(const std::vector<COutPoint>& inputs, int32_t version)
99{
101 mtx.version = version;
102 mtx.vin.resize(inputs.size());
103 for (size_t i{0}; i < inputs.size(); ++i) {
104 mtx.vin[i].prevout = inputs[i];
105 }
106 mtx.vout.resize(NUM_EPHEMERAL_TX_OUTPUTS);
107 for (auto i{0}; i < NUM_EPHEMERAL_TX_OUTPUTS; ++i) {
108 mtx.vout[i].scriptPubKey = CScript() << OP_TRUE;
109 mtx.vout[i].nValue = (i == EPHEMERAL_DUST_INDEX) ? 0 : 10000;
110 }
111 return MakeTransactionRef(mtx);
112}
113
115{
117 LOCK2(cs_main, pool.cs);
119
122
123 // Arbitrary non-0 feerate for these tests
125
126 // Basic transaction with dust
127 auto grandparent_tx_1 = make_ephemeral_tx(random_outpoints(1), /*version=*/2);
128 const auto dust_txid = grandparent_tx_1->GetHash();
129
130 // Child transaction spending dust
131 auto dust_spend = make_tx({COutPoint{dust_txid, EPHEMERAL_DUST_INDEX}}, /*version=*/2);
132
133 // We first start with nothing "in the mempool", using package checks
134
135 // Trivial single transaction with no dust
137 BOOST_CHECK(child_state.IsValid());
139
140 // Now with dust, ok because the tx has no dusty parents
142 BOOST_CHECK(child_state.IsValid());
144
145 // Dust checks pass
147 BOOST_CHECK(child_state.IsValid());
150 BOOST_CHECK(child_state.IsValid());
152
153 auto dust_non_spend = make_tx({COutPoint{dust_txid, EPHEMERAL_DUST_INDEX - 1}}, /*version=*/2);
154
155 // Child spending non-dust only from parent should be disallowed even if dust otherwise spent
156 const auto dust_non_spend_wtxid{dust_non_spend->GetWitnessHash()};
158 BOOST_CHECK(!child_state.IsValid());
161 child_wtxid = Wtxid();
162
164 BOOST_CHECK(!child_state.IsValid());
167 child_wtxid = Wtxid();
168
170 BOOST_CHECK(!child_state.IsValid());
173 child_wtxid = Wtxid();
174
175 auto grandparent_tx_2 = make_ephemeral_tx(random_outpoints(1), /*version=*/2);
176 const auto dust_txid_2 = grandparent_tx_2->GetHash();
177
178 // Spend dust from one but not another is ok, as long as second grandparent has no child
180 BOOST_CHECK(child_state.IsValid());
182
184 // But if we spend from the parent, it must spend dust
186 BOOST_CHECK(!child_state.IsValid());
189 child_wtxid = Wtxid();
190
193 BOOST_CHECK(child_state.IsValid());
195
196 // Spending other outputs is also correct, as long as the dusty one is spent
197 const std::vector<COutPoint> all_outpoints{COutPoint(dust_txid, 0), COutPoint(dust_txid, 1), COutPoint(dust_txid, 2),
199 auto dust_spend_all_outpoints = make_tx(all_outpoints, /*version=*/2);
201 BOOST_CHECK(child_state.IsValid());
203
204 // 2 grandparents with dust <- 1 dust-spending parent with dust <- child with no dust
206 // Ok for parent to have dust
208 BOOST_CHECK(child_state.IsValid());
210 auto child_no_dust = make_tx({COutPoint{parent_with_dust->GetHash(), EPHEMERAL_DUST_INDEX}}, /*version=*/2);
212 BOOST_CHECK(child_state.IsValid());
214
215 // 2 grandparents with dust <- 1 dust-spending parent with dust <- child with dust
218 BOOST_CHECK(child_state.IsValid());
220
221 // Tests with parents in mempool
222
223 // Nothing in mempool, this should pass for any transaction
225 BOOST_CHECK(child_state.IsValid());
227
228 // Add first grandparent to mempool and fetch entry
230
231 // Ignores ancestors that aren't direct parents
233 BOOST_CHECK(child_state.IsValid());
235
236 // Valid spend of dust with grandparent in mempool
238 BOOST_CHECK(child_state.IsValid());
240
241 // Second grandparent in same package
243 BOOST_CHECK(child_state.IsValid());
245
246 // Order in package doesn't matter
248 BOOST_CHECK(child_state.IsValid());
250
251 // Add second grandparent to mempool
253
254 // Only spends single dust out of two direct parents
256 BOOST_CHECK(!child_state.IsValid());
259 child_wtxid = Wtxid();
260
261 // Spends both parents' dust
263 BOOST_CHECK(child_state.IsValid());
265
266 // Now add dusty parent to mempool
268
269 // Passes dust checks even with non-parent ancestors
271 BOOST_CHECK(child_state.IsValid());
273}
274
276{
277 // Test TRUC policy helper functions
279 LOCK2(cs_main, pool.cs);
281 std::set<Txid> empty_conflicts_set;
282 std::vector<CTxMemPoolEntry::CTxMemPoolEntryRef> empty_parents;
283
284 auto mempool_tx_v3 = make_tx(random_outpoints(1), /*version=*/3);
286 auto mempool_tx_v2 = make_tx(random_outpoints(1), /*version=*/2);
288
289 // Cannot spend from an unconfirmed TRUC transaction unless this tx is also TRUC.
290 {
291 // mempool_tx_v3
292 // ^
293 // tx_v2_from_v3
294 auto tx_v2_from_v3 = make_tx({COutPoint{mempool_tx_v3->GetHash(), 0}}, /*version=*/2);
296 const auto expected_error_str{strprintf("non-version=3 tx %s (wtxid=%s) cannot spend from version=3 tx %s (wtxid=%s)",
297 tx_v2_from_v3->GetHash().ToString(), tx_v2_from_v3->GetWitnessHash().ToString(),
298 mempool_tx_v3->GetHash().ToString(), mempool_tx_v3->GetWitnessHash().ToString())};
301 BOOST_CHECK_EQUAL(result_v2_from_v3->second, nullptr);
302
306
307 // mempool_tx_v3 mempool_tx_v2
308 // ^ ^
309 // tx_v2_from_v2_and_v3
310 auto tx_v2_from_v2_and_v3 = make_tx({COutPoint{mempool_tx_v3->GetHash(), 0}, COutPoint{mempool_tx_v2->GetHash(), 0}}, /*version=*/2);
312 const auto expected_error_str_2{strprintf("non-version=3 tx %s (wtxid=%s) cannot spend from version=3 tx %s (wtxid=%s)",
313 tx_v2_from_v2_and_v3->GetHash().ToString(), tx_v2_from_v2_and_v3->GetWitnessHash().ToString(),
314 mempool_tx_v3->GetHash().ToString(), mempool_tx_v3->GetWitnessHash().ToString())};
317 BOOST_CHECK_EQUAL(result_v2_from_both->second, nullptr);
318
321 }
322
323 // TRUC cannot spend from an unconfirmed non-TRUC transaction.
324 {
325 // mempool_tx_v2
326 // ^
327 // tx_v3_from_v2
328 auto tx_v3_from_v2 = make_tx({COutPoint{mempool_tx_v2->GetHash(), 0}}, /*version=*/3);
330 const auto expected_error_str{strprintf("version=3 tx %s (wtxid=%s) cannot spend from non-version=3 tx %s (wtxid=%s)",
331 tx_v3_from_v2->GetHash().ToString(), tx_v3_from_v2->GetWitnessHash().ToString(),
332 mempool_tx_v2->GetHash().ToString(), mempool_tx_v2->GetWitnessHash().ToString())};
335 BOOST_CHECK_EQUAL(result_v3_from_v2->second, nullptr);
336
340
341 // mempool_tx_v3 mempool_tx_v2
342 // ^ ^
343 // tx_v3_from_v2_and_v3
344 auto tx_v3_from_v2_and_v3 = make_tx({COutPoint{mempool_tx_v3->GetHash(), 0}, COutPoint{mempool_tx_v2->GetHash(), 0}}, /*version=*/3);
346 const auto expected_error_str_2{strprintf("version=3 tx %s (wtxid=%s) cannot spend from non-version=3 tx %s (wtxid=%s)",
347 tx_v3_from_v2_and_v3->GetHash().ToString(), tx_v3_from_v2_and_v3->GetWitnessHash().ToString(),
348 mempool_tx_v2->GetHash().ToString(), mempool_tx_v2->GetWitnessHash().ToString())};
351 BOOST_CHECK_EQUAL(result_v3_from_both->second, nullptr);
352
353 // tx_v3_from_v2_and_v3 also violates TRUC_ANCESTOR_LIMIT.
354 const auto expected_error_str_3{strprintf("tx %s (wtxid=%s) would have too many ancestors",
355 tx_v3_from_v2_and_v3->GetHash().ToString(), tx_v3_from_v2_and_v3->GetWitnessHash().ToString())};
358 }
359 // V3 from V3 is ok, and non-V3 from non-V3 is ok.
360 {
361 // mempool_tx_v3
362 // ^
363 // tx_v3_from_v3
364 auto tx_v3_from_v3 = make_tx({COutPoint{mempool_tx_v3->GetHash(), 0}}, /*version=*/3);
365 auto parents_v3{pool.GetParents(entry.FromTx(tx_v3_from_v3))};
367 == std::nullopt);
368
371
372 // mempool_tx_v2
373 // ^
374 // tx_v2_from_v2
375 auto tx_v2_from_v2 = make_tx({COutPoint{mempool_tx_v2->GetHash(), 0}}, /*version=*/2);
376 auto parents_v2{pool.GetParents(entry.FromTx(tx_v2_from_v2))};
378 == std::nullopt);
379
382 }
383
384 // Tx spending TRUC cannot have too many mempool ancestors
385 // Configuration where the tx has multiple direct parents.
386 {
388 std::vector<COutPoint> mempool_outpoints;
389 mempool_outpoints.emplace_back(mempool_tx_v3->GetHash(), 0);
391 for (size_t i{0}; i < 2; ++i) {
392 auto mempool_tx = make_tx(random_outpoints(i + 1), /*version=*/3);
393 TryAddToMempool(pool, entry.FromTx(mempool_tx));
394 mempool_outpoints.emplace_back(mempool_tx->GetHash(), 0);
395 package_multi_parents.emplace_back(mempool_tx);
396 }
397 auto tx_v3_multi_parent = make_tx(mempool_outpoints, /*version=*/3);
399 auto parents{pool.GetParents(entry.FromTx(tx_v3_multi_parent))};
400 BOOST_CHECK_EQUAL(parents.size(), 3);
401 const auto expected_error_str{strprintf("tx %s (wtxid=%s) would have too many ancestors",
402 tx_v3_multi_parent->GetHash().ToString(), tx_v3_multi_parent->GetWitnessHash().ToString())};
405 BOOST_CHECK_EQUAL(result->second, nullptr);
406
409 }
410
411 // Configuration where the tx is in a multi-generation chain.
412 {
416 for (size_t i{0}; i < 2; ++i) {
417 auto mempool_tx = make_tx({last_outpoint}, /*version=*/3);
418 TryAddToMempool(pool, entry.FromTx(mempool_tx));
419 last_outpoint = COutPoint{mempool_tx->GetHash(), 0};
420 package_multi_gen.emplace_back(mempool_tx);
421 if (i == 1) middle_tx = mempool_tx;
422 }
423 auto tx_v3_multi_gen = make_tx({last_outpoint}, /*version=*/3);
425 auto parents{pool.GetParents(entry.FromTx(tx_v3_multi_gen))};
426 const auto expected_error_str{strprintf("tx %s (wtxid=%s) would have too many ancestors",
427 tx_v3_multi_gen->GetHash().ToString(), tx_v3_multi_gen->GetWitnessHash().ToString())};
430 BOOST_CHECK_EQUAL(result->second, nullptr);
431
432 // Middle tx is what triggers a failure for the grandchild:
435 }
436
437 // Tx spending TRUC cannot be too large in virtual size.
438 auto many_inputs{random_outpoints(100)};
439 many_inputs.emplace_back(mempool_tx_v3->GetHash(), 0);
440 {
441 auto tx_v3_child_big = make_tx(many_inputs, /*version=*/3);
442 const auto vsize{GetVirtualTransactionSize(*tx_v3_child_big)};
443 auto parents{pool.GetParents(entry.FromTx(tx_v3_child_big))};
444 const auto expected_error_str{strprintf("version=3 child tx %s (wtxid=%s) is too big: %u > %u virtual bytes",
445 tx_v3_child_big->GetHash().ToString(), tx_v3_child_big->GetWitnessHash().ToString(), vsize, TRUC_CHILD_MAX_VSIZE)};
448 BOOST_CHECK_EQUAL(result->second, nullptr);
449
453 }
454
455 // Tx spending TRUC cannot have too many sigops.
456 // This child has 10 P2WSH multisig inputs.
458 multisig_outpoints.emplace_back(mempool_tx_v3->GetHash(), 0);
459 auto keys{random_keys(2)};
462 for (const auto& key : keys) {
464 }
466 {
469 for (const auto& outpoint : multisig_outpoints) {
470 mtx_many_sigops.vin.emplace_back(outpoint);
471 mtx_many_sigops.vin.back().scriptWitness.stack.emplace_back(script_multisig.begin(), script_multisig.end());
472 }
473 mtx_many_sigops.vout.resize(1);
474 mtx_many_sigops.vout.back().scriptPubKey = CScript() << OP_TRUE;
475 mtx_many_sigops.vout.back().nValue = 10000;
477
478 auto parents{pool.GetParents(entry.FromTx(tx_many_sigops))};
479 // legacy uses fAccurate = false, and the maximum number of multisig keys is used
480 const int64_t total_sigops{static_cast<int64_t>(tx_many_sigops->vin.size()) * static_cast<int64_t>(script_multisig.GetSigOpCount(/*fAccurate=*/false))};
483 // Weight limit is not reached...
485 // ...but sigop limit is.
486 const auto expected_error_str{strprintf("version=3 child tx %s (wtxid=%s) is too big: %u > %u virtual bytes",
487 tx_many_sigops->GetHash().ToString(), tx_many_sigops->GetWitnessHash().ToString(),
489 auto result{SingleTRUCChecks(pool, tx_many_sigops, parents, empty_conflicts_set,
490 GetVirtualTransactionSize(*tx_many_sigops, /*nSigOpCost=*/total_sigops, /*bytes_per_sigop=*/ DEFAULT_BYTES_PER_SIGOP))};
492 BOOST_CHECK_EQUAL(result->second, nullptr);
493
497 }
498
499 // Parent + child with TRUC in the mempool. Child is allowed as long as it is under TRUC_CHILD_MAX_VSIZE.
500 auto tx_mempool_v3_child = make_tx({COutPoint{mempool_tx_v3->GetHash(), 0}}, /*version=*/3);
501 {
503 auto parents{pool.GetParents(entry.FromTx(tx_mempool_v3_child))};
506
509 }
510
511 // A TRUC transaction cannot have more than 1 descendant. Sibling is returned when exactly 1 exists.
512 {
513 auto tx_v3_child2 = make_tx({COutPoint{mempool_tx_v3->GetHash(), 1}}, /*version=*/3);
514 // Configuration where parent already has 1 other child in mempool
516 const auto expected_error_str{strprintf("tx %s (wtxid=%s) would exceed descendant count limit",
517 mempool_tx_v3->GetHash().ToString(), mempool_tx_v3->GetWitnessHash().ToString())};
520 // The other mempool child is returned to allow for sibling eviction.
522
523 // If directly replacing the child, make sure there is no double-counting.
525 == std::nullopt);
526
530
531 // Configuration where parent already has 2 other children in mempool (no sibling eviction allowed). This may happen as the result of a reorg.
532 TryAddToMempool(pool, entry.FromTx(tx_v3_child2));
533 auto tx_v3_child3 = make_tx({COutPoint{mempool_tx_v3->GetHash(), 24}}, /*version=*/3);
534 auto entry_mempool_parent = pool.GetIter(mempool_tx_v3->GetHash()).value();
537
540 // The other mempool child is not returned because sibling eviction is not allowed.
541 BOOST_CHECK_EQUAL(result_2children->second, nullptr);
542 }
543
544 // Sibling eviction: parent already has 1 other child, which also has its own child (no sibling eviction allowed). This may happen as the result of a reorg.
545 {
546 auto tx_mempool_grandparent = make_tx(random_outpoints(1), /*version=*/3);
547 auto tx_mempool_sibling = make_tx({COutPoint{tx_mempool_grandparent->GetHash(), 0}}, /*version=*/3);
548 auto tx_mempool_nibling = make_tx({COutPoint{tx_mempool_sibling->GetHash(), 0}}, /*version=*/3);
549 auto tx_to_submit = make_tx({COutPoint{tx_mempool_grandparent->GetHash(), 1}}, /*version=*/3);
550
554
555 auto parents_3gen{pool.GetParents(entry.FromTx(tx_to_submit))};
556 const auto expected_error_str{strprintf("tx %s (wtxid=%s) would exceed descendant count limit",
557 tx_mempool_grandparent->GetHash().ToString(), tx_mempool_grandparent->GetWitnessHash().ToString())};
560 // The other mempool child is not returned because sibling eviction is not allowed.
561 BOOST_CHECK_EQUAL(result_3gen->second, nullptr);
562 }
563
564 // Configuration where tx has multiple generations of descendants is not tested because that is
565 // equivalent to the tx with multiple generations of ancestors.
566}
567
TryAddToMempool(pool, CTxMemPoolEntry(tx, fee, 0, 1, 0, false, 4, lp))
node::NodeContext m_node
#define Assert(val)
Identity function.
Definition check.h:113
Fee rate in satoshis per virtualbyte: CAmount / vB the feerate is represented internally as FeeFrac.
Definition feerate.h:32
An encapsulated private key.
Definition key.h:36
void MakeNewKey(bool fCompressed)
Generate a new private key using a cryptographic PRNG.
Definition key.cpp:162
CPubKey GetPubKey() const
Compute the public key from a private key.
Definition key.cpp:183
An outpoint - a combination of a transaction hash and an index n into its vout.
Definition transaction.h:29
Serialized script, used inside transaction inputs and outputs.
Definition script.h:405
The basic transaction that is broadcasted on the network and contained in blocks.
CTxMemPool stores valid-according-to-the-current-best-chain transactions that may be included in the ...
Definition txmempool.h:187
std::optional< txiter > GetIter(const Txid &txid) const EXCLUSIVE_LOCKS_REQUIRED(cs)
Returns an iterator to the given hash, if found.
RecursiveMutex cs
This mutex needs to be locked when accessing mapTx or other members that are guarded by it.
Definition txmempool.h:260
int64_t GetDescendantCount(txiter it) const
Definition txmempool.h:274
std::vector< CTxMemPoolEntry::CTxMemPoolEntryRef > GetParents(const CTxMemPoolEntry &entry) const
Definition txmempool.cpp:74
std::string GetRejectReason() const
Definition validation.h:109
Result GetResult() const
Definition validation.h:108
bool IsInvalid() const
Definition validation.h:106
T & back()
Definition prevector.h:408
transaction_identifier represents the two canonical transaction identifier types (txid,...
static transaction_identifier FromUint256(const uint256 &id)
static int32_t GetTransactionWeight(const CTransaction &tx)
Definition validation.h:132
@ TX_CONSENSUS
invalid by consensus rules
static const int WITNESS_SCALE_FACTOR
Definition consensus.h:21
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate.
Definition cs_main.cpp:8
BOOST_AUTO_TEST_SUITE_END()
bool CheckEphemeralSpends(const Package &package, CFeeRate dust_relay_rate, const CTxMemPool &tx_pool, TxValidationState &out_child_state, Wtxid &out_child_wtxid)
Called for each transaction(package) if any dust is in the package.
#define BOOST_CHECK_EQUAL(v1, v2)
Definition object.cpp:17
#define BOOST_CHECK(expr)
Definition object.cpp:16
std::vector< CTransactionRef > Package
A package is an ordered list of transactions.
Definition packages.h:45
int64_t GetVirtualTransactionSize(int64_t nWeight, int64_t nSigOpCost, unsigned int bytes_per_sigop)
Compute the virtual transaction size (weight reinterpreted as bytes).
Definition policy.cpp:381
static constexpr unsigned int DUST_RELAY_TX_FEE
Min feerate for defining dust.
Definition policy.h:67
static constexpr unsigned int DEFAULT_BYTES_PER_SIGOP
Default for -bytespersigop.
Definition policy.h:49
static CTransactionRef MakeTransactionRef(Tx &&txIn)
std::shared_ptr< const CTransaction > CTransactionRef
uint256 GetRandHash() noexcept
Generate a random uint256.
Definition random.h:463
@ OP_2
Definition script.h:85
@ OP_CHECKMULTISIG
Definition script.h:192
@ OP_CHECKSIG
Definition script.h:190
@ OP_EQUAL
Definition script.h:146
@ OP_1
Definition script.h:83
@ OP_TRUE
Definition script.h:84
@ OP_11
Definition script.h:94
static const int MAX_PUBKEYS_PER_MULTISIG
Definition script.h:34
std::vector< unsigned char > ToByteVector(const T &in)
Definition script.h:67
static constexpr CAmount CENT
A mutable version of CTransaction.
Validation result for a transaction evaluated by MemPoolAccept (single or package).
Definition validation.h:131
const ResultType m_result_type
Result type.
Definition validation.h:140
const TxValidationState m_state
Contains information about why the transaction failed.
Definition validation.h:143
@ INVALID
‍Fully validated, valid.
Identical to TestingSetup, but chain set to regtest.
Testing fixture that pre-creates a 100-block REGTEST-mode block chain.
Definition txmempool.h:19
CTxMemPoolEntry FromTx(const CMutableTransaction &tx) const
Definition txmempool.cpp:34
std::unique_ptr< CTxMemPool > mempool
Definition context.h:68
std::unique_ptr< ChainstateManager > chainman
Definition context.h:72
#define LOCK2(cs1, cs2)
Definition sync.h:259
#define LOCK(cs)
Definition sync.h:258
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
transaction_identifier< true > Wtxid
Wtxid commits to all transaction fields including the witness.
std::optional< std::pair< std::string, CTransactionRef > > SingleTRUCChecks(const CTxMemPool &pool, const CTransactionRef &ptx, const std::vector< CTxMemPoolEntry::CTxMemPoolEntryRef > &mempool_parents, const std::set< Txid > &direct_conflicts, int64_t vsize)
Must be called for every transaction, even if not TRUC.
std::optional< std::string > PackageTRUCChecks(const CTxMemPool &pool, const CTransactionRef &ptx, int64_t vsize, const Package &package, const std::vector< CTxMemPoolEntry::CTxMemPoolEntryRef > &mempool_parents)
Must be called for every transaction that is submitted within a package, even if not TRUC.
static constexpr int64_t TRUC_CHILD_MAX_VSIZE
Maximum sigop-adjusted virtual size of a tx which spends from an unconfirmed TRUC transaction.
Definition truc_policy.h:33
static constexpr decltype(CTransaction::version) TRUC_VERSION
Definition truc_policy.h:20
static CTransactionRef make_ephemeral_tx(const std::vector< COutPoint > &inputs, int32_t version)
static CTransactionRef make_tx(const std::vector< COutPoint > &inputs, int32_t version)
static std::vector< COutPoint > random_outpoints(size_t num_outpoints)
static constexpr auto NUM_EPHEMERAL_TX_OUTPUTS
BOOST_FIXTURE_TEST_CASE(tx_mempool_reject_coinbase, TestChain100Setup)
Ensure that the mempool won't accept coinbase transactions.
static std::vector< CPubKey > random_keys(size_t num_keys)
static constexpr auto EPHEMERAL_DUST_INDEX
constexpr auto Ticks(Dur2 d)
Helper to count the seconds of a duration/time_point.
Definition time.h:73