[txpackages] IsChildWithParentsTree()
Many edge cases exist when parents in a child-with-parents package can spend each other. However, this pattern should also be uncommon in normal use cases.
This commit is contained in:
1 parent
b4f28cc345
commit
e32ba1599c
3 files changed
+22
No files matched your search
@@ -88,3 +88,18 @@ bool IsChildWithParents(const Package& package)
|
|||||||
return std::all_of(package.cbegin(), package.cend() - 1,
|
return std::all_of(package.cbegin(), package.cend() - 1,
|
||||||
[&input_txids](const auto& ptx) { return input_txids.count(ptx->GetHash()) > 0; });
|
[&input_txids](const auto& ptx) { return input_txids.count(ptx->GetHash()) > 0; });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IsChildWithParentsTree(const Package& package)
|
||||||
|
{
|
||||||
|
if (!IsChildWithParents(package)) return false;
|
||||||
|
std::unordered_set<uint256, SaltedTxidHasher> parent_txids;
|
||||||
|
std::transform(package.cbegin(), package.cend() - 1, std::inserter(parent_txids, parent_txids.end()),
|
||||||
|
[](const auto& ptx) { return ptx->GetHash(); });
|
||||||
|
// Each parent must not have an input who is one of the other parents.
|
||||||
|
return std::all_of(package.cbegin(), package.cend() - 1, [&](const auto& ptx) {
|
||||||
|
for (const auto& input : ptx->vin) {
|
||||||
|
if (parent_txids.count(input.prevout.hash) > 0) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -63,4 +63,8 @@ bool CheckPackage(const Package& txns, PackageValidationState& state);
|
|||||||
*/
|
*/
|
||||||
bool IsChildWithParents(const Package& package);
|
bool IsChildWithParents(const Package& package);
|
||||||
|
|
||||||
|
/** Context-free check that a package IsChildWithParents() and none of the parents depend on each
|
||||||
|
* other (the package is a "tree").
|
||||||
|
*/
|
||||||
|
bool IsChildWithParentsTree(const Package& package);
|
||||||
#endif // BITCOIN_POLICY_PACKAGES_H
|
#endif // BITCOIN_POLICY_PACKAGES_H
|
||||||
@@ -162,6 +162,7 @@ BOOST_FIXTURE_TEST_CASE(noncontextual_package_tests, TestChain100Setup)
|
|||||||
BOOST_CHECK_EQUAL(state.GetResult(), PackageValidationResult::PCKG_POLICY);
|
BOOST_CHECK_EQUAL(state.GetResult(), PackageValidationResult::PCKG_POLICY);
|
||||||
BOOST_CHECK_EQUAL(state.GetRejectReason(), "package-not-sorted");
|
BOOST_CHECK_EQUAL(state.GetRejectReason(), "package-not-sorted");
|
||||||
BOOST_CHECK(IsChildWithParents({tx_parent, tx_child}));
|
BOOST_CHECK(IsChildWithParents({tx_parent, tx_child}));
|
||||||
|
BOOST_CHECK(IsChildWithParentsTree({tx_parent, tx_child}));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 24 Parents and 1 Child
|
// 24 Parents and 1 Child
|
||||||
@@ -187,6 +188,7 @@ BOOST_FIXTURE_TEST_CASE(noncontextual_package_tests, TestChain100Setup)
|
|||||||
PackageValidationState state;
|
PackageValidationState state;
|
||||||
BOOST_CHECK(CheckPackage(package, state));
|
BOOST_CHECK(CheckPackage(package, state));
|
||||||
BOOST_CHECK(IsChildWithParents(package));
|
BOOST_CHECK(IsChildWithParents(package));
|
||||||
|
BOOST_CHECK(IsChildWithParentsTree(package));
|
||||||
|
|
||||||
package.erase(package.begin());
|
package.erase(package.begin());
|
||||||
BOOST_CHECK(IsChildWithParents(package));
|
BOOST_CHECK(IsChildWithParents(package));
|
||||||
@@ -219,6 +221,7 @@ BOOST_FIXTURE_TEST_CASE(noncontextual_package_tests, TestChain100Setup)
|
|||||||
BOOST_CHECK(IsChildWithParents({tx_parent, tx_parent_also_child}));
|
BOOST_CHECK(IsChildWithParents({tx_parent, tx_parent_also_child}));
|
||||||
BOOST_CHECK(IsChildWithParents({tx_parent, tx_child}));
|
BOOST_CHECK(IsChildWithParents({tx_parent, tx_child}));
|
||||||
BOOST_CHECK(IsChildWithParents({tx_parent, tx_parent_also_child, tx_child}));
|
BOOST_CHECK(IsChildWithParents({tx_parent, tx_parent_also_child, tx_child}));
|
||||||
|
BOOST_CHECK(!IsChildWithParentsTree({tx_parent, tx_parent_also_child, tx_child}));
|
||||||
// IsChildWithParents does not detect unsorted parents.
|
// IsChildWithParents does not detect unsorted parents.
|
||||||
BOOST_CHECK(IsChildWithParents({tx_parent_also_child, tx_parent, tx_child}));
|
BOOST_CHECK(IsChildWithParents({tx_parent_also_child, tx_parent, tx_child}));
|
||||||
BOOST_CHECK(CheckPackage({tx_parent, tx_parent_also_child, tx_child}, state));
|
BOOST_CHECK(CheckPackage({tx_parent, tx_parent_also_child, tx_child}, state));
|
||||||
|
|||||||
Reference in new issue
Block a user