Bitcoin ABC  0.29.2
P2P Digital Currency
packages.cpp
Go to the documentation of this file.
1 // Copyright (c) 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 <policy/packages.h>
8 #include <util/hasher.h>
9 
10 #include <numeric>
11 #include <unordered_set>
12 
13 bool CheckPackage(const Package &txns, PackageValidationState &state) {
14  const size_t package_count = txns.size();
15 
16  // These context-free package limits can be checked before taking the
17  // mempool lock.
18  if (package_count > MAX_PACKAGE_COUNT) {
20  "package-too-many-transactions");
21  }
22 
23  const int64_t total_size = std::accumulate(
24  txns.cbegin(), txns.cend(), 0, [](int64_t sum, const auto &tx) {
25  return sum + GetVirtualTransactionSize(*tx);
26  });
27  // If the package only contains 1 tx, it's better to report the policy
28  // violation on individual tx size.
29  if (package_count > 1 && total_size > MAX_PACKAGE_SIZE * 1000) {
31  "package-too-large");
32  }
33 
34  // Require the package to be sorted in order of dependency, i.e. parents
35  // appear before children.
36  // An unsorted package will fail anyway on missing-inputs, but it's better
37  // to quit earlier and fail on something less ambiguous (missing-inputs
38  // could also be an orphan or trying to spend nonexistent coins).
39  std::unordered_set<TxId, SaltedTxIdHasher> later_txids;
40  std::transform(txns.cbegin(), txns.cend(),
41  std::inserter(later_txids, later_txids.end()),
42  [](const auto &tx) { return tx->GetId(); });
43  for (const auto &tx : txns) {
44  for (const auto &input : tx->vin) {
45  if (later_txids.find(input.prevout.GetTxId()) !=
46  later_txids.end()) {
47  // The parent is a subsequent transaction in the package.
49  "package-not-sorted");
50  }
51  }
52  later_txids.erase(tx->GetId());
53  }
54 
55  // Don't allow any conflicting transactions, i.e. spending the same
56  // inputs, in a package.
57  std::unordered_set<COutPoint, SaltedOutpointHasher> inputs_seen;
58  for (const auto &tx : txns) {
59  for (const auto &input : tx->vin) {
60  if (inputs_seen.find(input.prevout) != inputs_seen.end()) {
61  // This input is also present in another tx in the package.
63  "conflict-in-package");
64  }
65  }
66  // Batch-add all the inputs for a tx at a time. If we added them 1
67  // at a time, we could catch duplicate inputs within a single tx.
68  // This is a more severe, consensus error, and we want to report
69  // that from CheckTransaction instead.
70  std::transform(tx->vin.cbegin(), tx->vin.cend(),
71  std::inserter(inputs_seen, inputs_seen.end()),
72  [](const auto &input) { return input.prevout; });
73  }
74  return true;
75 }
76 
77 bool IsChildWithParents(const Package &package) {
78  assert(std::all_of(package.cbegin(), package.cend(),
79  [](const auto &tx) { return tx != nullptr; }));
80  if (package.size() < 2) {
81  return false;
82  }
83 
84  // The package is expected to be sorted, so the last transaction is the
85  // child.
86  const auto &child = package.back();
87  std::unordered_set<TxId, SaltedTxIdHasher> input_txids;
88  std::transform(child->vin.cbegin(), child->vin.cend(),
89  std::inserter(input_txids, input_txids.end()),
90  [](const auto &input) { return input.prevout.GetTxId(); });
91 
92  // Every transaction must be a parent of the last transaction in the
93  // package.
94  return std::all_of(package.cbegin(), package.cend() - 1,
95  [&input_txids](const auto &ptx) {
96  return input_txids.count(ptx->GetId()) > 0;
97  });
98 }
bool Invalid(Result result, const std::string &reject_reason="", const std::string &debug_message="")
Definition: validation.h:94
volatile double sum
Definition: examples.cpp:10
bool IsChildWithParents(const Package &package)
Context-free check that a package is exactly one child and its parents; not all parents need to be pr...
Definition: packages.cpp:77
bool CheckPackage(const Package &txns, PackageValidationState &state)
Context-free package policy checks:
Definition: packages.cpp:13
std::vector< CTransactionRef > Package
A package is an ordered list of transactions.
Definition: packages.h:38
static constexpr uint32_t MAX_PACKAGE_COUNT
Default maximum number of transactions in a package.
Definition: packages.h:15
static constexpr uint32_t MAX_PACKAGE_SIZE
Default maximum total size of transactions in a package in KB.
Definition: packages.h:17
@ PCKG_POLICY
The package itself is invalid (e.g. too many transactions).
assert(!tx.IsCoinBase())