16 #include <unordered_set> 20 const unsigned int package_count = txns.size();
26 const int64_t total_weight = std::accumulate(txns.cbegin(), txns.cend(), 0,
37 std::unordered_set<uint256, SaltedTxidHasher> later_txids;
38 std::transform(txns.cbegin(), txns.cend(), std::inserter(later_txids, later_txids.end()),
39 [](
const auto& tx) {
return tx->GetHash(); });
43 if (later_txids.size() != txns.size()) {
47 for (
const auto& tx : txns) {
48 for (
const auto& input : tx->vin) {
49 if (later_txids.find(input.prevout.hash) != later_txids.end()) {
54 later_txids.erase(tx->GetHash());
58 std::unordered_set<COutPoint, SaltedOutpointHasher> inputs_seen;
59 for (
const auto& tx : txns) {
60 for (
const auto& input : tx->vin) {
61 if (inputs_seen.find(input.prevout) != inputs_seen.end()) {
69 std::transform(tx->vin.cbegin(), tx->vin.cend(), std::inserter(inputs_seen, inputs_seen.end()),
70 [](
const auto& input) {
return input.prevout; });
77 assert(std::all_of(package.cbegin(), package.cend(), [](
const auto& tx){
return tx !=
nullptr;}));
78 if (package.size() < 2)
return false;
81 const auto& child = package.back();
82 std::unordered_set<uint256, SaltedTxidHasher> input_txids;
83 std::transform(child->vin.cbegin(), child->vin.cend(),
84 std::inserter(input_txids, input_txids.end()),
85 [](
const auto& input) {
return input.prevout.hash; });
88 return std::all_of(package.cbegin(), package.cend() - 1,
89 [&input_txids](
const auto& ptx) {
return input_txids.count(ptx->GetHash()) > 0; });
95 std::unordered_set<uint256, SaltedTxidHasher> parent_txids;
96 std::transform(package.cbegin(), package.cend() - 1, std::inserter(parent_txids, parent_txids.end()),
97 [](
const auto& ptx) {
return ptx->GetHash(); });
99 return std::all_of(package.cbegin(), package.cend() - 1, [&](
const auto& ptx) {
100 for (
const auto& input : ptx->vin) {
101 if (parent_txids.count(input.prevout.hash) > 0)
return false;
The package itself is invalid (e.g. too many transactions).
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...
std::vector< CTransactionRef > Package
A package is an ordered list of transactions.
bool IsChildWithParentsTree(const Package &package)
Context-free check that a package IsChildWithParents() and none of the parents depend on each other (...
bool CheckPackage(const Package &txns, PackageValidationState &state)
Context-free package policy checks:
static int32_t GetTransactionWeight(const CTransaction &tx)
bool Invalid(Result result, const std::string &reject_reason="", const std::string &debug_message="")
static constexpr uint32_t MAX_PACKAGE_COUNT
Default maximum number of transactions in a package.
static constexpr uint32_t MAX_PACKAGE_WEIGHT
Default maximum total weight of transactions in a package in weight to allow for context-less checks...