Skip to content

Commit ba26169

Browse files
committed
[unit test] context-free package checks
1 parent 9b2fdca commit ba26169

File tree

1 file changed

+93
-0
lines changed

1 file changed

+93
-0
lines changed

src/test/txpackage_tests.cpp

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,4 +114,97 @@ BOOST_FIXTURE_TEST_CASE(package_validation_tests, TestChain100Setup)
114114
// Check that mempool size hasn't changed.
115115
BOOST_CHECK_EQUAL(m_node.mempool->size(), initialPoolSize);
116116
}
117+
118+
BOOST_FIXTURE_TEST_CASE(noncontextual_package_tests, TestChain100Setup)
119+
{
120+
// The signatures won't be verified so we can just use a placeholder
121+
CKey placeholder_key;
122+
placeholder_key.MakeNewKey(true);
123+
CScript spk = GetScriptForDestination(PKHash(placeholder_key.GetPubKey()));
124+
CKey placeholder_key_2;
125+
placeholder_key_2.MakeNewKey(true);
126+
CScript spk2 = GetScriptForDestination(PKHash(placeholder_key_2.GetPubKey()));
127+
128+
// Parent and Child Package
129+
{
130+
auto mtx_parent = CreateValidMempoolTransaction(m_coinbase_txns[0], 0, 0, coinbaseKey, spk,
131+
CAmount(49 * COIN), /* submit */ false);
132+
CTransactionRef tx_parent = MakeTransactionRef(mtx_parent);
133+
134+
auto mtx_child = CreateValidMempoolTransaction(tx_parent, 0, 101, placeholder_key, spk2,
135+
CAmount(48 * COIN), /* submit */ false);
136+
CTransactionRef tx_child = MakeTransactionRef(mtx_child);
137+
138+
PackageValidationState state;
139+
BOOST_CHECK(CheckPackage({tx_parent, tx_child}, state));
140+
BOOST_CHECK(!CheckPackage({tx_child, tx_parent}, state));
141+
BOOST_CHECK_EQUAL(state.GetResult(), PackageValidationResult::PCKG_POLICY);
142+
BOOST_CHECK_EQUAL(state.GetRejectReason(), "package-not-sorted");
143+
BOOST_CHECK(IsChildWithParents({tx_parent, tx_child}));
144+
}
145+
146+
// 24 Parents and 1 Child
147+
{
148+
Package package;
149+
CMutableTransaction child;
150+
for (int i{0}; i < 24; ++i) {
151+
auto parent = MakeTransactionRef(CreateValidMempoolTransaction(m_coinbase_txns[i + 1],
152+
0, 0, coinbaseKey, spk, CAmount(48 * COIN), false));
153+
package.emplace_back(parent);
154+
child.vin.push_back(CTxIn(COutPoint(parent->GetHash(), 0)));
155+
}
156+
child.vout.push_back(CTxOut(47 * COIN, spk2));
157+
158+
// The child must be in the package.
159+
BOOST_CHECK(!IsChildWithParents(package));
160+
161+
// The parents can be in any order.
162+
FastRandomContext rng;
163+
Shuffle(package.begin(), package.end(), rng);
164+
package.push_back(MakeTransactionRef(child));
165+
166+
PackageValidationState state;
167+
BOOST_CHECK(CheckPackage(package, state));
168+
BOOST_CHECK(IsChildWithParents(package));
169+
170+
package.erase(package.begin());
171+
BOOST_CHECK(IsChildWithParents(package));
172+
173+
// The package cannot have unrelated transactions.
174+
package.insert(package.begin(), m_coinbase_txns[0]);
175+
BOOST_CHECK(!IsChildWithParents(package));
176+
}
177+
178+
// 2 Parents and 1 Child where one parent depends on the other.
179+
{
180+
CMutableTransaction mtx_parent;
181+
mtx_parent.vin.push_back(CTxIn(COutPoint(m_coinbase_txns[0]->GetHash(), 0)));
182+
mtx_parent.vout.push_back(CTxOut(20 * COIN, spk));
183+
mtx_parent.vout.push_back(CTxOut(20 * COIN, spk2));
184+
CTransactionRef tx_parent = MakeTransactionRef(mtx_parent);
185+
186+
CMutableTransaction mtx_parent_also_child;
187+
mtx_parent_also_child.vin.push_back(CTxIn(COutPoint(tx_parent->GetHash(), 0)));
188+
mtx_parent_also_child.vout.push_back(CTxOut(20 * COIN, spk));
189+
CTransactionRef tx_parent_also_child = MakeTransactionRef(mtx_parent_also_child);
190+
191+
CMutableTransaction mtx_child;
192+
mtx_child.vin.push_back(CTxIn(COutPoint(tx_parent->GetHash(), 1)));
193+
mtx_child.vin.push_back(CTxIn(COutPoint(tx_parent_also_child->GetHash(), 0)));
194+
mtx_child.vout.push_back(CTxOut(39 * COIN, spk));
195+
CTransactionRef tx_child = MakeTransactionRef(mtx_child);
196+
197+
PackageValidationState state;
198+
BOOST_CHECK(IsChildWithParents({tx_parent, tx_parent_also_child}));
199+
BOOST_CHECK(IsChildWithParents({tx_parent, tx_child}));
200+
BOOST_CHECK(IsChildWithParents({tx_parent, tx_parent_also_child, tx_child}));
201+
// IsChildWithParents does not detect unsorted parents.
202+
BOOST_CHECK(IsChildWithParents({tx_parent_also_child, tx_parent, tx_child}));
203+
BOOST_CHECK(CheckPackage({tx_parent, tx_parent_also_child, tx_child}, state));
204+
BOOST_CHECK(!CheckPackage({tx_parent_also_child, tx_parent, tx_child}, state));
205+
BOOST_CHECK_EQUAL(state.GetResult(), PackageValidationResult::PCKG_POLICY);
206+
BOOST_CHECK_EQUAL(state.GetRejectReason(), "package-not-sorted");
207+
}
208+
}
209+
117210
BOOST_AUTO_TEST_SUITE_END()

0 commit comments

Comments
 (0)