22 Assume(txns.size() == later_txids.size());
27 for (
const auto& tx : txns) {
28 for (
const auto& input : tx->vin) {
29 if (later_txids.find(input.prevout.hash) != later_txids.end()) {
35 Assume(later_txids.erase(tx->GetHash()) == 1);
39 Assume(later_txids.empty());
45 std::unordered_set<uint256, SaltedTxidHasher> later_txids;
46 std::transform(txns.cbegin(), txns.cend(), std::inserter(later_txids, later_txids.end()),
47 [](
const auto& tx) { return tx->GetHash(); });
55 std::unordered_set<COutPoint, SaltedOutpointHasher> inputs_seen;
56 for (
const auto& tx : txns) {
57 if (tx->vin.empty()) {
64 for (
const auto& input : tx->vin) {
65 if (inputs_seen.find(input.prevout) != inputs_seen.end()) {
73 std::transform(tx->vin.cbegin(), tx->vin.cend(), std::inserter(inputs_seen, inputs_seen.end()),
74 [](
const auto& input) { return input.prevout; });
81 const unsigned int package_count = txns.size();
87 const int64_t total_weight = std::accumulate(txns.cbegin(), txns.cend(), 0,
88 [](int64_t
sum,
const auto& tx) { return sum + GetTransactionWeight(*tx); });
94 std::unordered_set<uint256, SaltedTxidHasher> later_txids;
95 std::transform(txns.cbegin(), txns.cend(), std::inserter(later_txids, later_txids.end()),
96 [](
const auto& tx) { return tx->GetHash(); });
100 if (later_txids.size() != txns.size()) {
121 assert(std::all_of(package.cbegin(), package.cend(), [](
const auto& tx){return tx != nullptr;}));
122 if (package.size() < 2)
return false;
125 const auto& child = package.back();
126 std::unordered_set<uint256, SaltedTxidHasher> input_txids;
127 std::transform(child->vin.cbegin(), child->vin.cend(),
128 std::inserter(input_txids, input_txids.end()),
129 [](
const auto& input) { return input.prevout.hash; });
132 return std::all_of(package.cbegin(), package.cend() - 1,
133 [&input_txids](
const auto& ptx) { return input_txids.count(ptx->GetHash()) > 0; });
139 std::unordered_set<uint256, SaltedTxidHasher> parent_txids;
140 std::transform(package.cbegin(), package.cend() - 1, std::inserter(parent_txids, parent_txids.end()),
141 [](
const auto& ptx) { return ptx->GetHash(); });
143 return std::all_of(package.cbegin(), package.cend() - 1, [&](
const auto& ptx) {
144 for (const auto& input : ptx->vin) {
145 if (parent_txids.count(input.prevout.hash) > 0) return false;
154 std::vector<Wtxid> wtxids_copy;
155 std::transform(transactions.cbegin(), transactions.cend(), std::back_inserter(wtxids_copy),
156 [](
const auto& tx){ return tx->GetWitnessHash(); });
159 std::sort(wtxids_copy.begin(), wtxids_copy.end(), [](
const auto& lhs,
const auto& rhs) {
160 return std::lexicographical_compare(std::make_reverse_iterator(lhs.end()), std::make_reverse_iterator(lhs.begin()),
161 std::make_reverse_iterator(rhs.end()), std::make_reverse_iterator(rhs.begin()));
166 for (
const auto& wtxid : wtxids_copy) {
#define Assume(val)
Assume is the identity function.
A writer stream (for serialization) that computes a 256-bit hash.
uint256 GetSHA256()
Compute the SHA256 hash of all data written to this object.
bool Invalid(Result result, const std::string &reject_reason="", const std::string &debug_message="")
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...
bool IsConsistentPackage(const Package &txns)
Checks that these transactions don't conflict, i.e., spend the same prevout.
bool IsWellFormedPackage(const Package &txns, PackageValidationState &state, bool require_sorted)
Context-free package policy checks:
bool IsChildWithParentsTree(const Package &package)
Context-free check that a package IsChildWithParents() and none of the parents depend on each other (...
uint256 GetPackageHash(const std::vector< CTransactionRef > &transactions)
Get the hash of these transactions' wtxids, concatenated in lexicographical order (treating the wtxid...
bool IsTopoSortedPackage(const Package &txns, std::unordered_set< uint256, SaltedTxidHasher > &later_txids)
IsTopoSortedPackage where a set of txids has been pre-populated.
std::vector< CTransactionRef > Package
A package is an ordered list of transactions.
static constexpr uint32_t MAX_PACKAGE_WEIGHT
Default maximum total weight of transactions in a package in weight to allow for context-less checks.
static constexpr uint32_t MAX_PACKAGE_COUNT
Default maximum number of transactions in a package.
@ PCKG_POLICY
The package itself is invalid (e.g. too many transactions).