@@ -114,4 +114,97 @@ BOOST_FIXTURE_TEST_CASE(package_validation_tests, TestChain100Setup)
114
114
// Check that mempool size hasn't changed.
115
115
BOOST_CHECK_EQUAL (m_node.mempool ->size (), initialPoolSize);
116
116
}
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
+
117
210
BOOST_AUTO_TEST_SUITE_END ()
0 commit comments