Bitcoin Core  27.99.0
P2P Digital Currency
txvalidation_tests.cpp
Go to the documentation of this file.
1 // Copyright (c) 2017-2021 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 <consensus/validation.h>
6 #include <key_io.h>
7 #include <policy/v3_policy.h>
8 #include <policy/packages.h>
9 #include <policy/policy.h>
10 #include <primitives/transaction.h>
11 #include <random.h>
12 #include <script/script.h>
13 #include <test/util/setup_common.h>
14 #include <test/util/txmempool.h>
15 #include <validation.h>
16 
17 #include <boost/test/unit_test.hpp>
18 
19 
20 BOOST_AUTO_TEST_SUITE(txvalidation_tests)
21 
22 
25 BOOST_FIXTURE_TEST_CASE(tx_mempool_reject_coinbase, TestChain100Setup)
26 {
27  CScript scriptPubKey = CScript() << ToByteVector(coinbaseKey.GetPubKey()) << OP_CHECKSIG;
28  CMutableTransaction coinbaseTx;
29 
30  coinbaseTx.nVersion = 1;
31  coinbaseTx.vin.resize(1);
32  coinbaseTx.vout.resize(1);
33  coinbaseTx.vin[0].scriptSig = CScript() << OP_11 << OP_EQUAL;
34  coinbaseTx.vout[0].nValue = 1 * CENT;
35  coinbaseTx.vout[0].scriptPubKey = scriptPubKey;
36 
37  BOOST_CHECK(CTransaction(coinbaseTx).IsCoinBase());
38 
39  LOCK(cs_main);
40 
41  unsigned int initialPoolSize = m_node.mempool->size();
42  const MempoolAcceptResult result = m_node.chainman->ProcessTransaction(MakeTransactionRef(coinbaseTx));
43 
45 
46  // Check that the transaction hasn't been added to mempool.
47  BOOST_CHECK_EQUAL(m_node.mempool->size(), initialPoolSize);
48 
49  // Check that the validation state reflects the unsuccessful attempt.
50  BOOST_CHECK(result.m_state.IsInvalid());
51  BOOST_CHECK_EQUAL(result.m_state.GetRejectReason(), "coinbase");
53 }
54 
55 // Generate a number of random, nonexistent outpoints.
56 static inline std::vector<COutPoint> random_outpoints(size_t num_outpoints) {
57  std::vector<COutPoint> outpoints;
58  for (size_t i{0}; i < num_outpoints; ++i) {
59  outpoints.emplace_back(Txid::FromUint256(GetRandHash()), 0);
60  }
61  return outpoints;
62 }
63 
64 static inline std::vector<CPubKey> random_keys(size_t num_keys) {
65  std::vector<CPubKey> keys;
66  keys.reserve(num_keys);
67  for (size_t i{0}; i < num_keys; ++i) {
68  CKey key;
69  key.MakeNewKey(true);
70  keys.emplace_back(key.GetPubKey());
71  }
72  return keys;
73 }
74 
75 // Creates a placeholder tx (not valid) with 25 outputs. Specify the nVersion and the inputs.
76 static inline CTransactionRef make_tx(const std::vector<COutPoint>& inputs, int32_t version)
77 {
79  mtx.nVersion = version;
80  mtx.vin.resize(inputs.size());
81  mtx.vout.resize(25);
82  for (size_t i{0}; i < inputs.size(); ++i) {
83  mtx.vin[i].prevout = inputs[i];
84  }
85  for (auto i{0}; i < 25; ++i) {
86  mtx.vout[i].scriptPubKey = CScript() << OP_TRUE;
87  mtx.vout[i].nValue = 10000;
88  }
89  return MakeTransactionRef(mtx);
90 }
91 
93 {
94  // Test V3 policy helper functions
95  CTxMemPool& pool = *Assert(m_node.mempool);
96  LOCK2(cs_main, pool.cs);
98  std::set<Txid> empty_conflicts_set;
99  CTxMemPool::setEntries empty_ancestors;
100 
101  auto mempool_tx_v3 = make_tx(random_outpoints(1), /*version=*/3);
102  pool.addUnchecked(entry.FromTx(mempool_tx_v3));
103  auto mempool_tx_v2 = make_tx(random_outpoints(1), /*version=*/2);
104  pool.addUnchecked(entry.FromTx(mempool_tx_v2));
105  // Default values.
106  CTxMemPool::Limits m_limits{};
107 
108  // Cannot spend from an unconfirmed v3 transaction unless this tx is also v3.
109  {
110  // mempool_tx_v3
111  // ^
112  // tx_v2_from_v3
113  auto tx_v2_from_v3 = make_tx({COutPoint{mempool_tx_v3->GetHash(), 0}}, /*version=*/2);
114  auto ancestors_v2_from_v3{pool.CalculateMemPoolAncestors(entry.FromTx(tx_v2_from_v3), m_limits)};
115  const auto expected_error_str{strprintf("non-v3 tx %s (wtxid=%s) cannot spend from v3 tx %s (wtxid=%s)",
116  tx_v2_from_v3->GetHash().ToString(), tx_v2_from_v3->GetWitnessHash().ToString(),
117  mempool_tx_v3->GetHash().ToString(), mempool_tx_v3->GetWitnessHash().ToString())};
118  auto result_v2_from_v3{SingleV3Checks(tx_v2_from_v3, *ancestors_v2_from_v3, empty_conflicts_set, GetVirtualTransactionSize(*tx_v2_from_v3))};
119  BOOST_CHECK_EQUAL(result_v2_from_v3->first, expected_error_str);
120  BOOST_CHECK_EQUAL(result_v2_from_v3->second, nullptr);
121 
122  Package package_v3_v2{mempool_tx_v3, tx_v2_from_v3};
123  BOOST_CHECK_EQUAL(*PackageV3Checks(tx_v2_from_v3, GetVirtualTransactionSize(*tx_v2_from_v3), package_v3_v2, empty_ancestors), expected_error_str);
124  CTxMemPool::setEntries entries_mempool_v3{pool.GetIter(mempool_tx_v3->GetHash().ToUint256()).value()};
125  BOOST_CHECK_EQUAL(*PackageV3Checks(tx_v2_from_v3, GetVirtualTransactionSize(*tx_v2_from_v3), {tx_v2_from_v3}, entries_mempool_v3), expected_error_str);
126 
127  // mempool_tx_v3 mempool_tx_v2
128  // ^ ^
129  // tx_v2_from_v2_and_v3
130  auto tx_v2_from_v2_and_v3 = make_tx({COutPoint{mempool_tx_v3->GetHash(), 0}, COutPoint{mempool_tx_v2->GetHash(), 0}}, /*version=*/2);
131  auto ancestors_v2_from_both{pool.CalculateMemPoolAncestors(entry.FromTx(tx_v2_from_v2_and_v3), m_limits)};
132  const auto expected_error_str_2{strprintf("non-v3 tx %s (wtxid=%s) cannot spend from v3 tx %s (wtxid=%s)",
133  tx_v2_from_v2_and_v3->GetHash().ToString(), tx_v2_from_v2_and_v3->GetWitnessHash().ToString(),
134  mempool_tx_v3->GetHash().ToString(), mempool_tx_v3->GetWitnessHash().ToString())};
135  auto result_v2_from_both{SingleV3Checks(tx_v2_from_v2_and_v3, *ancestors_v2_from_both, empty_conflicts_set, GetVirtualTransactionSize(*tx_v2_from_v2_and_v3))};
136  BOOST_CHECK_EQUAL(result_v2_from_both->first, expected_error_str_2);
137  BOOST_CHECK_EQUAL(result_v2_from_both->second, nullptr);
138 
139  Package package_v3_v2_v2{mempool_tx_v3, mempool_tx_v2, tx_v2_from_v2_and_v3};
140  BOOST_CHECK_EQUAL(*PackageV3Checks(tx_v2_from_v2_and_v3, GetVirtualTransactionSize(*tx_v2_from_v2_and_v3), package_v3_v2_v2, empty_ancestors), expected_error_str_2);
141  }
142 
143  // V3 cannot spend from an unconfirmed non-v3 transaction.
144  {
145  // mempool_tx_v2
146  // ^
147  // tx_v3_from_v2
148  auto tx_v3_from_v2 = make_tx({COutPoint{mempool_tx_v2->GetHash(), 0}}, /*version=*/3);
149  auto ancestors_v3_from_v2{pool.CalculateMemPoolAncestors(entry.FromTx(tx_v3_from_v2), m_limits)};
150  const auto expected_error_str{strprintf("v3 tx %s (wtxid=%s) cannot spend from non-v3 tx %s (wtxid=%s)",
151  tx_v3_from_v2->GetHash().ToString(), tx_v3_from_v2->GetWitnessHash().ToString(),
152  mempool_tx_v2->GetHash().ToString(), mempool_tx_v2->GetWitnessHash().ToString())};
153  auto result_v3_from_v2{SingleV3Checks(tx_v3_from_v2, *ancestors_v3_from_v2, empty_conflicts_set, GetVirtualTransactionSize(*tx_v3_from_v2))};
154  BOOST_CHECK_EQUAL(result_v3_from_v2->first, expected_error_str);
155  BOOST_CHECK_EQUAL(result_v3_from_v2->second, nullptr);
156 
157  Package package_v2_v3{mempool_tx_v2, tx_v3_from_v2};
158  BOOST_CHECK_EQUAL(*PackageV3Checks(tx_v3_from_v2, GetVirtualTransactionSize(*tx_v3_from_v2), package_v2_v3, empty_ancestors), expected_error_str);
159  CTxMemPool::setEntries entries_mempool_v2{pool.GetIter(mempool_tx_v2->GetHash().ToUint256()).value()};
160  BOOST_CHECK_EQUAL(*PackageV3Checks(tx_v3_from_v2, GetVirtualTransactionSize(*tx_v3_from_v2), {tx_v3_from_v2}, entries_mempool_v2), expected_error_str);
161 
162  // mempool_tx_v3 mempool_tx_v2
163  // ^ ^
164  // tx_v3_from_v2_and_v3
165  auto tx_v3_from_v2_and_v3 = make_tx({COutPoint{mempool_tx_v3->GetHash(), 0}, COutPoint{mempool_tx_v2->GetHash(), 0}}, /*version=*/3);
166  auto ancestors_v3_from_both{pool.CalculateMemPoolAncestors(entry.FromTx(tx_v3_from_v2_and_v3), m_limits)};
167  const auto expected_error_str_2{strprintf("v3 tx %s (wtxid=%s) cannot spend from non-v3 tx %s (wtxid=%s)",
168  tx_v3_from_v2_and_v3->GetHash().ToString(), tx_v3_from_v2_and_v3->GetWitnessHash().ToString(),
169  mempool_tx_v2->GetHash().ToString(), mempool_tx_v2->GetWitnessHash().ToString())};
170  auto result_v3_from_both{SingleV3Checks(tx_v3_from_v2_and_v3, *ancestors_v3_from_both, empty_conflicts_set, GetVirtualTransactionSize(*tx_v3_from_v2_and_v3))};
171  BOOST_CHECK_EQUAL(result_v3_from_both->first, expected_error_str_2);
172  BOOST_CHECK_EQUAL(result_v3_from_both->second, nullptr);
173 
174  // tx_v3_from_v2_and_v3 also violates V3_ANCESTOR_LIMIT.
175  const auto expected_error_str_3{strprintf("tx %s (wtxid=%s) would have too many ancestors",
176  tx_v3_from_v2_and_v3->GetHash().ToString(), tx_v3_from_v2_and_v3->GetWitnessHash().ToString())};
177  Package package_v3_v2_v3{mempool_tx_v3, mempool_tx_v2, tx_v3_from_v2_and_v3};
178  BOOST_CHECK_EQUAL(*PackageV3Checks(tx_v3_from_v2_and_v3, GetVirtualTransactionSize(*tx_v3_from_v2_and_v3), package_v3_v2_v3, empty_ancestors), expected_error_str_3);
179  }
180  // V3 from V3 is ok, and non-V3 from non-V3 is ok.
181  {
182  // mempool_tx_v3
183  // ^
184  // tx_v3_from_v3
185  auto tx_v3_from_v3 = make_tx({COutPoint{mempool_tx_v3->GetHash(), 0}}, /*version=*/3);
186  auto ancestors_v3{pool.CalculateMemPoolAncestors(entry.FromTx(tx_v3_from_v3), m_limits)};
187  BOOST_CHECK(SingleV3Checks(tx_v3_from_v3, *ancestors_v3, empty_conflicts_set, GetVirtualTransactionSize(*tx_v3_from_v3))
188  == std::nullopt);
189 
190  Package package_v3_v3{mempool_tx_v3, tx_v3_from_v3};
191  BOOST_CHECK(PackageV3Checks(tx_v3_from_v3, GetVirtualTransactionSize(*tx_v3_from_v3), package_v3_v3, empty_ancestors) == std::nullopt);
192 
193  // mempool_tx_v2
194  // ^
195  // tx_v2_from_v2
196  auto tx_v2_from_v2 = make_tx({COutPoint{mempool_tx_v2->GetHash(), 0}}, /*version=*/2);
197  auto ancestors_v2{pool.CalculateMemPoolAncestors(entry.FromTx(tx_v2_from_v2), m_limits)};
198  BOOST_CHECK(SingleV3Checks(tx_v2_from_v2, *ancestors_v2, empty_conflicts_set, GetVirtualTransactionSize(*tx_v2_from_v2))
199  == std::nullopt);
200 
201  Package package_v2_v2{mempool_tx_v2, tx_v2_from_v2};
202  BOOST_CHECK(PackageV3Checks(tx_v2_from_v2, GetVirtualTransactionSize(*tx_v2_from_v2), package_v2_v2, empty_ancestors) == std::nullopt);
203  }
204 
205  // Tx spending v3 cannot have too many mempool ancestors
206  // Configuration where the tx has multiple direct parents.
207  {
208  Package package_multi_parents;
209  std::vector<COutPoint> mempool_outpoints;
210  mempool_outpoints.emplace_back(mempool_tx_v3->GetHash(), 0);
211  package_multi_parents.emplace_back(mempool_tx_v3);
212  for (size_t i{0}; i < 2; ++i) {
213  auto mempool_tx = make_tx(random_outpoints(i + 1), /*version=*/3);
214  pool.addUnchecked(entry.FromTx(mempool_tx));
215  mempool_outpoints.emplace_back(mempool_tx->GetHash(), 0);
216  package_multi_parents.emplace_back(mempool_tx);
217  }
218  auto tx_v3_multi_parent = make_tx(mempool_outpoints, /*version=*/3);
219  package_multi_parents.emplace_back(tx_v3_multi_parent);
220  auto ancestors{pool.CalculateMemPoolAncestors(entry.FromTx(tx_v3_multi_parent), m_limits)};
221  BOOST_CHECK_EQUAL(ancestors->size(), 3);
222  const auto expected_error_str{strprintf("tx %s (wtxid=%s) would have too many ancestors",
223  tx_v3_multi_parent->GetHash().ToString(), tx_v3_multi_parent->GetWitnessHash().ToString())};
224  auto result{SingleV3Checks(tx_v3_multi_parent, *ancestors, empty_conflicts_set, GetVirtualTransactionSize(*tx_v3_multi_parent))};
225  BOOST_CHECK_EQUAL(result->first, expected_error_str);
226  BOOST_CHECK_EQUAL(result->second, nullptr);
227 
228  BOOST_CHECK_EQUAL(*PackageV3Checks(tx_v3_multi_parent, GetVirtualTransactionSize(*tx_v3_multi_parent), package_multi_parents, empty_ancestors),
229  expected_error_str);
230  }
231 
232  // Configuration where the tx is in a multi-generation chain.
233  {
234  Package package_multi_gen;
235  CTransactionRef middle_tx;
236  auto last_outpoint{random_outpoints(1)[0]};
237  for (size_t i{0}; i < 2; ++i) {
238  auto mempool_tx = make_tx({last_outpoint}, /*version=*/3);
239  pool.addUnchecked(entry.FromTx(mempool_tx));
240  last_outpoint = COutPoint{mempool_tx->GetHash(), 0};
241  package_multi_gen.emplace_back(mempool_tx);
242  if (i == 1) middle_tx = mempool_tx;
243  }
244  auto tx_v3_multi_gen = make_tx({last_outpoint}, /*version=*/3);
245  package_multi_gen.emplace_back(tx_v3_multi_gen);
246  auto ancestors{pool.CalculateMemPoolAncestors(entry.FromTx(tx_v3_multi_gen), m_limits)};
247  const auto expected_error_str{strprintf("tx %s (wtxid=%s) would have too many ancestors",
248  tx_v3_multi_gen->GetHash().ToString(), tx_v3_multi_gen->GetWitnessHash().ToString())};
249  auto result{SingleV3Checks(tx_v3_multi_gen, *ancestors, empty_conflicts_set, GetVirtualTransactionSize(*tx_v3_multi_gen))};
250  BOOST_CHECK_EQUAL(result->first, expected_error_str);
251  BOOST_CHECK_EQUAL(result->second, nullptr);
252 
253  // Middle tx is what triggers a failure for the grandchild:
254  BOOST_CHECK_EQUAL(*PackageV3Checks(middle_tx, GetVirtualTransactionSize(*middle_tx), package_multi_gen, empty_ancestors), expected_error_str);
255  BOOST_CHECK(PackageV3Checks(tx_v3_multi_gen, GetVirtualTransactionSize(*tx_v3_multi_gen), package_multi_gen, empty_ancestors) == std::nullopt);
256  }
257 
258  // Tx spending v3 cannot be too large in virtual size.
259  auto many_inputs{random_outpoints(100)};
260  many_inputs.emplace_back(mempool_tx_v3->GetHash(), 0);
261  {
262  auto tx_v3_child_big = make_tx(many_inputs, /*version=*/3);
263  const auto vsize{GetVirtualTransactionSize(*tx_v3_child_big)};
264  auto ancestors{pool.CalculateMemPoolAncestors(entry.FromTx(tx_v3_child_big), m_limits)};
265  const auto expected_error_str{strprintf("v3 child tx %s (wtxid=%s) is too big: %u > %u virtual bytes",
266  tx_v3_child_big->GetHash().ToString(), tx_v3_child_big->GetWitnessHash().ToString(), vsize, V3_CHILD_MAX_VSIZE)};
267  auto result{SingleV3Checks(tx_v3_child_big, *ancestors, empty_conflicts_set, GetVirtualTransactionSize(*tx_v3_child_big))};
268  BOOST_CHECK_EQUAL(result->first, expected_error_str);
269  BOOST_CHECK_EQUAL(result->second, nullptr);
270 
271  Package package_child_big{mempool_tx_v3, tx_v3_child_big};
272  BOOST_CHECK_EQUAL(*PackageV3Checks(tx_v3_child_big, GetVirtualTransactionSize(*tx_v3_child_big), package_child_big, empty_ancestors),
273  expected_error_str);
274  }
275 
276  // Tx spending v3 cannot have too many sigops.
277  // This child has 10 P2WSH multisig inputs.
278  auto multisig_outpoints{random_outpoints(10)};
279  multisig_outpoints.emplace_back(mempool_tx_v3->GetHash(), 0);
280  auto keys{random_keys(2)};
281  CScript script_multisig;
282  script_multisig << OP_1;
283  for (const auto& key : keys) {
284  script_multisig << ToByteVector(key);
285  }
286  script_multisig << OP_2 << OP_CHECKMULTISIG;
287  {
288  CMutableTransaction mtx_many_sigops = CMutableTransaction{};
289  mtx_many_sigops.nVersion = 3;
290  for (const auto& outpoint : multisig_outpoints) {
291  mtx_many_sigops.vin.emplace_back(outpoint);
292  mtx_many_sigops.vin.back().scriptWitness.stack.emplace_back(script_multisig.begin(), script_multisig.end());
293  }
294  mtx_many_sigops.vout.resize(1);
295  mtx_many_sigops.vout.back().scriptPubKey = CScript() << OP_TRUE;
296  mtx_many_sigops.vout.back().nValue = 10000;
297  auto tx_many_sigops{MakeTransactionRef(mtx_many_sigops)};
298 
299  auto ancestors{pool.CalculateMemPoolAncestors(entry.FromTx(tx_many_sigops), m_limits)};
300  // legacy uses fAccurate = false, and the maximum number of multisig keys is used
301  const int64_t total_sigops{static_cast<int64_t>(tx_many_sigops->vin.size()) * static_cast<int64_t>(script_multisig.GetSigOpCount(/*fAccurate=*/false))};
302  BOOST_CHECK_EQUAL(total_sigops, tx_many_sigops->vin.size() * MAX_PUBKEYS_PER_MULTISIG);
303  const int64_t bip141_vsize{GetVirtualTransactionSize(*tx_many_sigops)};
304  // Weight limit is not reached...
305  BOOST_CHECK(SingleV3Checks(tx_many_sigops, *ancestors, empty_conflicts_set, bip141_vsize) == std::nullopt);
306  // ...but sigop limit is.
307  const auto expected_error_str{strprintf("v3 child tx %s (wtxid=%s) is too big: %u > %u virtual bytes",
308  tx_many_sigops->GetHash().ToString(), tx_many_sigops->GetWitnessHash().ToString(),
310  auto result{SingleV3Checks(tx_many_sigops, *ancestors, empty_conflicts_set,
311  GetVirtualTransactionSize(*tx_many_sigops, /*nSigOpCost=*/total_sigops, /*bytes_per_sigop=*/ DEFAULT_BYTES_PER_SIGOP))};
312  BOOST_CHECK_EQUAL(result->first, expected_error_str);
313  BOOST_CHECK_EQUAL(result->second, nullptr);
314 
315  Package package_child_sigops{mempool_tx_v3, tx_many_sigops};
316  BOOST_CHECK_EQUAL(*PackageV3Checks(tx_many_sigops, total_sigops * DEFAULT_BYTES_PER_SIGOP / WITNESS_SCALE_FACTOR, package_child_sigops, empty_ancestors),
317  expected_error_str);
318  }
319 
320  // Parent + child with v3 in the mempool. Child is allowed as long as it is under V3_CHILD_MAX_VSIZE.
321  auto tx_mempool_v3_child = make_tx({COutPoint{mempool_tx_v3->GetHash(), 0}}, /*version=*/3);
322  {
324  auto ancestors{pool.CalculateMemPoolAncestors(entry.FromTx(tx_mempool_v3_child), m_limits)};
325  BOOST_CHECK(SingleV3Checks(tx_mempool_v3_child, *ancestors, empty_conflicts_set, GetVirtualTransactionSize(*tx_mempool_v3_child)) == std::nullopt);
326  pool.addUnchecked(entry.FromTx(tx_mempool_v3_child));
327 
328  Package package_v3_1p1c{mempool_tx_v3, tx_mempool_v3_child};
329  BOOST_CHECK(PackageV3Checks(tx_mempool_v3_child, GetVirtualTransactionSize(*tx_mempool_v3_child), package_v3_1p1c, empty_ancestors) == std::nullopt);
330  }
331 
332  // A v3 transaction cannot have more than 1 descendant. Sibling is returned when exactly 1 exists.
333  {
334  auto tx_v3_child2 = make_tx({COutPoint{mempool_tx_v3->GetHash(), 1}}, /*version=*/3);
335 
336  // Configuration where parent already has 1 other child in mempool
337  auto ancestors_1sibling{pool.CalculateMemPoolAncestors(entry.FromTx(tx_v3_child2), m_limits)};
338  const auto expected_error_str{strprintf("tx %s (wtxid=%s) would exceed descendant count limit",
339  mempool_tx_v3->GetHash().ToString(), mempool_tx_v3->GetWitnessHash().ToString())};
340  auto result_with_sibling_eviction{SingleV3Checks(tx_v3_child2, *ancestors_1sibling, empty_conflicts_set, GetVirtualTransactionSize(*tx_v3_child2))};
341  BOOST_CHECK_EQUAL(result_with_sibling_eviction->first, expected_error_str);
342  // The other mempool child is returned to allow for sibling eviction.
343  BOOST_CHECK_EQUAL(result_with_sibling_eviction->second, tx_mempool_v3_child);
344 
345  // If directly replacing the child, make sure there is no double-counting.
346  BOOST_CHECK(SingleV3Checks(tx_v3_child2, *ancestors_1sibling, {tx_mempool_v3_child->GetHash()}, GetVirtualTransactionSize(*tx_v3_child2))
347  == std::nullopt);
348 
349  Package package_v3_1p2c{mempool_tx_v3, tx_mempool_v3_child, tx_v3_child2};
350  BOOST_CHECK_EQUAL(*PackageV3Checks(tx_v3_child2, GetVirtualTransactionSize(*tx_v3_child2), package_v3_1p2c, empty_ancestors),
351  expected_error_str);
352 
353  // Configuration where parent already has 2 other children in mempool (no sibling eviction allowed). This may happen as the result of a reorg.
354  pool.addUnchecked(entry.FromTx(tx_v3_child2));
355  auto tx_v3_child3 = make_tx({COutPoint{mempool_tx_v3->GetHash(), 24}}, /*version=*/3);
356  auto entry_mempool_parent = pool.GetIter(mempool_tx_v3->GetHash().ToUint256()).value();
357  BOOST_CHECK_EQUAL(entry_mempool_parent->GetCountWithDescendants(), 3);
358  auto ancestors_2siblings{pool.CalculateMemPoolAncestors(entry.FromTx(tx_v3_child3), m_limits)};
359 
360  auto result_2children{SingleV3Checks(tx_v3_child3, *ancestors_2siblings, empty_conflicts_set, GetVirtualTransactionSize(*tx_v3_child3))};
361  BOOST_CHECK_EQUAL(result_2children->first, expected_error_str);
362  // The other mempool child is not returned because sibling eviction is not allowed.
363  BOOST_CHECK_EQUAL(result_2children->second, nullptr);
364  }
365 
366  // 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.
367  {
368  auto tx_mempool_grandparent = make_tx(random_outpoints(1), /*version=*/3);
369  auto tx_mempool_sibling = make_tx({COutPoint{tx_mempool_grandparent->GetHash(), 0}}, /*version=*/3);
370  auto tx_mempool_nibling = make_tx({COutPoint{tx_mempool_sibling->GetHash(), 0}}, /*version=*/3);
371  auto tx_to_submit = make_tx({COutPoint{tx_mempool_grandparent->GetHash(), 1}}, /*version=*/3);
372 
373  pool.addUnchecked(entry.FromTx(tx_mempool_grandparent));
374  pool.addUnchecked(entry.FromTx(tx_mempool_sibling));
375  pool.addUnchecked(entry.FromTx(tx_mempool_nibling));
376 
377  auto ancestors_3gen{pool.CalculateMemPoolAncestors(entry.FromTx(tx_to_submit), m_limits)};
378  const auto expected_error_str{strprintf("tx %s (wtxid=%s) would exceed descendant count limit",
379  tx_mempool_grandparent->GetHash().ToString(), tx_mempool_grandparent->GetWitnessHash().ToString())};
380  auto result_3gen{SingleV3Checks(tx_to_submit, *ancestors_3gen, empty_conflicts_set, GetVirtualTransactionSize(*tx_to_submit))};
381  BOOST_CHECK_EQUAL(result_3gen->first, expected_error_str);
382  // The other mempool child is not returned because sibling eviction is not allowed.
383  BOOST_CHECK_EQUAL(result_3gen->second, nullptr);
384  }
385 
386  // Configuration where tx has multiple generations of descendants is not tested because that is
387  // equivalent to the tx with multiple generations of ancestors.
388 }
389 
node::NodeContext m_node
Definition: bitcoin-gui.cpp:37
#define Assert(val)
Identity function.
Definition: check.h:77
An encapsulated private key.
Definition: key.h:33
void MakeNewKey(bool fCompressed)
Generate a new private key using a cryptographic PRNG.
Definition: key.cpp:161
CPubKey GetPubKey() const
Compute the public key from a private key.
Definition: key.cpp:188
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:414
unsigned int GetSigOpCount(bool fAccurate) const
Pre-version-0.6, Bitcoin always counted CHECKMULTISIGs as 20 sigops.
Definition: script.cpp:159
The basic transaction that is broadcasted on the network and contained in blocks.
Definition: transaction.h:296
CTxMemPool stores valid-according-to-the-current-best-chain transactions that may be included in the ...
Definition: txmempool.h:302
RecursiveMutex cs
This mutex needs to be locked when accessing mapTx or other members that are guarded by it.
Definition: txmempool.h:390
util::Result< setEntries > CalculateMemPoolAncestors(const CTxMemPoolEntry &entry, const Limits &limits, bool fSearchForParents=true) const EXCLUSIVE_LOCKS_REQUIRED(cs)
Try to calculate all in-mempool ancestors of entry.
Definition: txmempool.cpp:238
std::optional< txiter > GetIter(const uint256 &txid) const EXCLUSIVE_LOCKS_REQUIRED(cs)
Returns an iterator to the given hash, if found.
Definition: txmempool.cpp:950
std::set< txiter, CompareIteratorByHash > setEntries
Definition: txmempool.h:396
void check(const CCoinsViewCache &active_coins_tip, int64_t spendheight) const EXCLUSIVE_LOCKS_REQUIRED(void addUnchecked(const CTxMemPoolEntry &entry) 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:476
std::string GetRejectReason() const
Definition: validation.h:126
Result GetResult() const
Definition: validation.h:125
bool IsInvalid() const
Definition: validation.h:123
iterator begin()
Definition: prevector.h:304
iterator end()
Definition: prevector.h:306
static transaction_identifier FromUint256(const uint256 &id)
static int32_t GetTransactionWeight(const CTransaction &tx)
Definition: validation.h:149
@ 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(cuckoocache_tests)
Test Suite for CuckooCache.
BOOST_AUTO_TEST_SUITE_END()
#define BOOST_CHECK_EQUAL(v1, v2)
Definition: object.cpp:18
#define BOOST_CHECK(expr)
Definition: object.cpp:17
std::vector< CTransactionRef > Package
A package is an ordered list of transactions.
Definition: packages.h:50
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:295
static constexpr unsigned int DEFAULT_BYTES_PER_SIGOP
Default for -bytespersigop.
Definition: policy.h:37
static CTransactionRef MakeTransactionRef(Tx &&txIn)
Definition: transaction.h:424
std::shared_ptr< const CTransaction > CTransactionRef
Definition: transaction.h:423
uint256 GetRandHash() noexcept
Definition: random.cpp:650
std::vector< unsigned char > ToByteVector(const T &in)
Definition: script.h:66
@ OP_2
Definition: script.h:84
@ OP_CHECKMULTISIG
Definition: script.h:191
@ OP_CHECKSIG
Definition: script.h:189
@ OP_EQUAL
Definition: script.h:145
@ OP_1
Definition: script.h:82
@ OP_TRUE
Definition: script.h:83
@ OP_11
Definition: script.h:93
static const int MAX_PUBKEYS_PER_MULTISIG
Definition: script.h:33
static constexpr CAmount CENT
Definition: setup_common.h:47
A mutable version of CTransaction.
Definition: transaction.h:378
std::vector< CTxOut > vout
Definition: transaction.h:380
std::vector< CTxIn > vin
Definition: transaction.h:379
Validation result for a transaction evaluated by MemPoolAccept (single or package).
Definition: validation.h:127
const ResultType m_result_type
Result type.
Definition: validation.h:136
const TxValidationState m_state
Contains information about why the transaction failed.
Definition: validation.h:139
@ INVALID
Fully validated, valid.
Identical to TestingSetup, but chain set to regtest.
Definition: setup_common.h:92
Testing fixture that pre-creates a 100-block REGTEST-mode block chain.
Definition: setup_common.h:104
Definition: txmempool.h:19
CTxMemPoolEntry FromTx(const CMutableTransaction &tx) const
Definition: txmempool.cpp:32
Options struct containing limit options for a CTxMemPool.
std::unique_ptr< CTxMemPool > mempool
Definition: context.h:58
std::unique_ptr< ChainstateManager > chainman
Definition: context.h:62
#define LOCK2(cs1, cs2)
Definition: sync.h:258
#define LOCK(cs)
Definition: sync.h:257
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition: tinyformat.h:1162
static std::vector< COutPoint > random_outpoints(size_t num_outpoints)
static CTransactionRef make_tx(const std::vector< COutPoint > &inputs, int32_t version)
static std::vector< CPubKey > random_keys(size_t num_keys)
BOOST_FIXTURE_TEST_CASE(tx_mempool_reject_coinbase, TestChain100Setup)
Ensure that the mempool won't accept coinbase transactions.
std::optional< std::string > PackageV3Checks(const CTransactionRef &ptx, int64_t vsize, const Package &package, const CTxMemPool::setEntries &mempool_ancestors)
Must be called for every transaction that is submitted within a package, even if not v3.
Definition: v3_policy.cpp:58
std::optional< std::pair< std::string, CTransactionRef > > SingleV3Checks(const CTransactionRef &ptx, const CTxMemPool::setEntries &mempool_ancestors, const std::set< Txid > &direct_conflicts, int64_t vsize)
Must be called for every transaction, even if not v3.
Definition: v3_policy.cpp:162
static constexpr int64_t V3_CHILD_MAX_VSIZE
Maximum sigop-adjusted virtual size of a tx which spends from an unconfirmed v3 transaction.
Definition: v3_policy.h:28