Line data Source code
1 : // Copyright (c) 2018-2020 The Bitcoin Core developers
2 : // Distributed under the MIT software license, see the accompanying
3 : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 :
5 : #include <test/data/blockfilters.json.h>
6 : #include <test/util/setup_common.h>
7 :
8 : #include <blockfilter.h>
9 : #include <core_io.h>
10 : #include <evo/assetlocktx.h>
11 : #include <evo/netinfo.h>
12 : #include <evo/providertx.h>
13 : #include <evo/specialtx.h>
14 : #include <netaddress.h>
15 : #include <netbase.h>
16 : #include <serialize.h>
17 : #include <span.h>
18 : #include <streams.h>
19 : #include <univalue.h>
20 : #include <util/strencodings.h>
21 :
22 : #include <boost/test/unit_test.hpp>
23 :
24 146 : BOOST_AUTO_TEST_SUITE(blockfilter_tests)
25 :
26 148 : BOOST_AUTO_TEST_CASE(gcsfilter_test)
27 : {
28 1 : GCSFilter::ElementSet included_elements, excluded_elements;
29 101 : for (int i = 0; i < 100; ++i) {
30 100 : GCSFilter::Element element1(32);
31 100 : element1[0] = i;
32 100 : included_elements.insert(std::move(element1));
33 :
34 100 : GCSFilter::Element element2(32);
35 100 : element2[1] = i;
36 100 : excluded_elements.insert(std::move(element2));
37 100 : }
38 :
39 1 : GCSFilter filter({0, 0, 10, 1 << 10}, included_elements);
40 101 : for (const auto& element : included_elements) {
41 100 : BOOST_CHECK(filter.Match(element));
42 :
43 100 : auto insertion = excluded_elements.insert(element);
44 100 : BOOST_CHECK(filter.MatchAny(excluded_elements));
45 100 : excluded_elements.erase(insertion.first);
46 : }
47 1 : }
48 :
49 148 : BOOST_AUTO_TEST_CASE(gcsfilter_default_constructor)
50 : {
51 1 : GCSFilter filter;
52 1 : BOOST_CHECK_EQUAL(filter.GetN(), 0U);
53 1 : BOOST_CHECK_EQUAL(filter.GetEncoded().size(), 1U);
54 :
55 1 : const GCSFilter::Params& params = filter.GetParams();
56 1 : BOOST_CHECK_EQUAL(params.m_siphash_k0, 0U);
57 1 : BOOST_CHECK_EQUAL(params.m_siphash_k1, 0U);
58 1 : BOOST_CHECK_EQUAL(params.m_P, 0);
59 1 : BOOST_CHECK_EQUAL(params.m_M, 1U);
60 1 : }
61 :
62 148 : BOOST_AUTO_TEST_CASE(blockfilter_basic_test)
63 : {
64 8 : CScript included_scripts[5], excluded_scripts[4];
65 :
66 : // First two are outputs on a single transaction.
67 1 : included_scripts[0] << std::vector<unsigned char>(0, 65) << OP_CHECKSIG;
68 1 : included_scripts[1] << OP_DUP << OP_HASH160 << std::vector<unsigned char>(1, 20) << OP_EQUALVERIFY << OP_CHECKSIG;
69 :
70 : // Third is an output on in a second transaction.
71 1 : included_scripts[2] << OP_1 << std::vector<unsigned char>(2, 33) << OP_1 << OP_CHECKMULTISIG;
72 :
73 : // Last two are spent by a single transaction.
74 1 : included_scripts[3] << OP_0 << std::vector<unsigned char>(3, 32);
75 1 : included_scripts[4] << OP_4 << OP_ADD << OP_8 << OP_EQUAL;
76 :
77 : // OP_RETURN output is an output on the second transaction.
78 1 : excluded_scripts[0] << OP_RETURN << std::vector<unsigned char>(4, 40);
79 :
80 : // This script is not related to the block at all.
81 1 : excluded_scripts[1] << std::vector<unsigned char>(5, 33) << OP_CHECKSIG;
82 :
83 : // OP_RETURN is non-standard since it's not followed by a data push, but is still excluded from
84 : // filter.
85 1 : excluded_scripts[2] << OP_RETURN << OP_4 << OP_ADD << OP_8 << OP_EQUAL;
86 :
87 1 : CMutableTransaction tx_1;
88 1 : tx_1.vout.emplace_back(100, included_scripts[0]);
89 1 : tx_1.vout.emplace_back(200, included_scripts[1]);
90 1 : tx_1.vout.emplace_back(0, excluded_scripts[0]);
91 :
92 1 : CMutableTransaction tx_2;
93 1 : tx_2.vout.emplace_back(300, included_scripts[2]);
94 1 : tx_2.vout.emplace_back(0, excluded_scripts[2]);
95 1 : tx_2.vout.emplace_back(400, excluded_scripts[3]); // Script is empty
96 :
97 1 : CBlock block;
98 1 : block.vtx.push_back(MakeTransactionRef(tx_1));
99 1 : block.vtx.push_back(MakeTransactionRef(tx_2));
100 :
101 1 : CBlockUndo block_undo;
102 1 : block_undo.vtxundo.emplace_back();
103 1 : block_undo.vtxundo.back().vprevout.emplace_back(CTxOut(500, included_scripts[3]), 1000, true);
104 1 : block_undo.vtxundo.back().vprevout.emplace_back(CTxOut(600, included_scripts[4]), 10000, false);
105 1 : block_undo.vtxundo.back().vprevout.emplace_back(CTxOut(700, excluded_scripts[3]), 100000, false);
106 :
107 1 : BlockFilter block_filter(BlockFilterType::BASIC_FILTER, block, block_undo);
108 1 : const GCSFilter& filter = block_filter.GetFilter();
109 :
110 6 : for (const CScript& script : included_scripts) {
111 5 : BOOST_CHECK(filter.Match(GCSFilter::Element(script.begin(), script.end())));
112 : }
113 5 : for (const CScript& script : excluded_scripts) {
114 4 : BOOST_CHECK(!filter.Match(GCSFilter::Element(script.begin(), script.end())));
115 : }
116 :
117 : // Test serialization/unserialization.
118 1 : BlockFilter block_filter2;
119 :
120 1 : CDataStream stream(SER_NETWORK, PROTOCOL_VERSION);
121 1 : stream << block_filter;
122 1 : stream >> block_filter2;
123 :
124 1 : BOOST_CHECK_EQUAL(block_filter.GetFilterType(), block_filter2.GetFilterType());
125 1 : BOOST_CHECK_EQUAL(block_filter.GetBlockHash(), block_filter2.GetBlockHash());
126 1 : BOOST_CHECK(block_filter.GetEncodedFilter() == block_filter2.GetEncodedFilter());
127 :
128 1 : BlockFilter default_ctor_block_filter_1;
129 1 : BlockFilter default_ctor_block_filter_2;
130 1 : BOOST_CHECK_EQUAL(default_ctor_block_filter_1.GetFilterType(), default_ctor_block_filter_2.GetFilterType());
131 1 : BOOST_CHECK_EQUAL(default_ctor_block_filter_1.GetBlockHash(), default_ctor_block_filter_2.GetBlockHash());
132 1 : BOOST_CHECK(default_ctor_block_filter_1.GetEncodedFilter() == default_ctor_block_filter_2.GetEncodedFilter());
133 1 : }
134 :
135 148 : BOOST_AUTO_TEST_CASE(blockfilters_json_test)
136 : {
137 1 : UniValue json;
138 1 : std::string json_data(json_tests::blockfilters,
139 : json_tests::blockfilters + sizeof(json_tests::blockfilters));
140 1 : if (!json.read(json_data) || !json.isArray()) {
141 0 : BOOST_ERROR("Parse error.");
142 0 : return;
143 : }
144 :
145 1 : const UniValue& tests = json.get_array();
146 9 : for (unsigned int i = 0; i < tests.size(); i++) {
147 8 : const UniValue& test = tests[i];
148 8 : std::string strTest = test.write();
149 :
150 8 : if (test.size() == 1) {
151 1 : continue;
152 7 : } else if (test.size() < 7) {
153 0 : BOOST_ERROR("Bad test: " << strTest);
154 0 : continue;
155 : }
156 :
157 7 : unsigned int pos = 0;
158 7 : /*int block_height =*/ test[pos++].getInt<int>();
159 7 : uint256 block_hash;
160 7 : BOOST_CHECK(ParseHashStr(test[pos++].get_str(), block_hash));
161 :
162 7 : CBlock block;
163 7 : BOOST_REQUIRE(DecodeHexBlk(block, test[pos++].get_str()));
164 :
165 7 : CBlockUndo block_undo;
166 7 : block_undo.vtxundo.emplace_back();
167 7 : CTxUndo& tx_undo = block_undo.vtxundo.back();
168 7 : const UniValue& prev_scripts = test[pos++].get_array();
169 31 : for (unsigned int ii = 0; ii < prev_scripts.size(); ii++) {
170 24 : std::vector<unsigned char> raw_script = ParseHex(prev_scripts[ii].get_str());
171 24 : CTxOut txout(0, CScript(raw_script.begin(), raw_script.end()));
172 24 : tx_undo.vprevout.emplace_back(txout, 0, false);
173 24 : }
174 :
175 7 : uint256 prev_filter_header_basic;
176 7 : BOOST_CHECK(ParseHashStr(test[pos++].get_str(), prev_filter_header_basic));
177 7 : std::vector<unsigned char> filter_basic = ParseHex(test[pos++].get_str());
178 7 : uint256 filter_header_basic;
179 7 : BOOST_CHECK(ParseHashStr(test[pos++].get_str(), filter_header_basic));
180 :
181 7 : BlockFilter computed_filter_basic(BlockFilterType::BASIC_FILTER, block, block_undo);
182 7 : BOOST_CHECK(computed_filter_basic.GetFilter().GetEncoded() == filter_basic);
183 :
184 7 : uint256 computed_header_basic = computed_filter_basic.ComputeHeader(prev_filter_header_basic);
185 7 : BOOST_CHECK(computed_header_basic == filter_header_basic);
186 8 : }
187 1 : }
188 :
189 148 : BOOST_AUTO_TEST_CASE(blockfilter_type_names)
190 : {
191 1 : BOOST_CHECK_EQUAL(BlockFilterTypeName(BlockFilterType::BASIC_FILTER), "basic");
192 1 : BOOST_CHECK_EQUAL(BlockFilterTypeName(static_cast<BlockFilterType>(255)), "");
193 :
194 : BlockFilterType filter_type;
195 1 : BOOST_CHECK(BlockFilterTypeByName("basic", filter_type));
196 1 : BOOST_CHECK_EQUAL(filter_type, BlockFilterType::BASIC_FILTER);
197 :
198 1 : BOOST_CHECK(!BlockFilterTypeByName("unknown", filter_type));
199 1 : }
200 :
201 148 : BOOST_AUTO_TEST_CASE(blockfilter_special_transactions_test)
202 : {
203 : // Test that special transaction fields are properly included in block filters
204 : // This ensures parity with bloom filter functionality
205 :
206 : // Test 1: ProRegTx (Provider Registration Transaction)
207 1 : CMutableTransaction protx;
208 1 : protx.nVersion = 3;
209 1 : protx.nType = TRANSACTION_PROVIDER_REGISTER;
210 :
211 1 : CProRegTx proRegPayload;
212 1 : proRegPayload.nVersion = 1;
213 1 : proRegPayload.nType = MnType::Regular;
214 1 : proRegPayload.nMode = 0;
215 1 : proRegPayload.collateralOutpoint = COutPoint(uint256S("1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef"), 0);
216 :
217 : // Set up network info (required for serialization)
218 1 : proRegPayload.netInfo = NetInfoInterface::MakeNetInfo(1); // Version 1
219 :
220 1 : proRegPayload.keyIDOwner = CKeyID(uint160(ParseHex("1111111111111111111111111111111111111111")));
221 1 : proRegPayload.keyIDVoting = CKeyID(uint160(ParseHex("2222222222222222222222222222222222222222")));
222 :
223 : // Generate a valid BLS key
224 1 : CBLSSecretKey blsKey;
225 1 : blsKey.MakeNewKey();
226 1 : proRegPayload.pubKeyOperator.Set(blsKey.GetPublicKey(), false);
227 1 : proRegPayload.inputsHash = uint256(); // Empty inputs hash
228 :
229 : // Create payout script
230 1 : CScript payoutScript = CScript() << OP_DUP << OP_HASH160 << ToByteVector(ParseHex("3333333333333333333333333333333333333333")) << OP_EQUALVERIFY << OP_CHECKSIG;
231 1 : proRegPayload.scriptPayout = payoutScript;
232 :
233 1 : SetTxPayload(protx, proRegPayload);
234 :
235 : // Test 2: ProUpServTx (Provider Update Service Transaction)
236 1 : CMutableTransaction proupservtx;
237 1 : proupservtx.nVersion = 3;
238 1 : proupservtx.nType = TRANSACTION_PROVIDER_UPDATE_SERVICE;
239 :
240 1 : CProUpServTx proUpServPayload;
241 1 : proUpServPayload.nVersion = 1;
242 1 : proUpServPayload.proTxHash = uint256S("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
243 1 : proUpServPayload.netInfo = NetInfoInterface::MakeNetInfo(1);
244 1 : CScript operatorPayoutScript = CScript() << OP_DUP << OP_HASH160 << ToByteVector(ParseHex("5555555555555555555555555555555555555555")) << OP_EQUALVERIFY << OP_CHECKSIG;
245 1 : proUpServPayload.scriptOperatorPayout = operatorPayoutScript;
246 1 : proUpServPayload.inputsHash = uint256();
247 :
248 1 : SetTxPayload(proupservtx, proUpServPayload);
249 :
250 : // Test 3: ProUpRegTx (Provider Update Registrar Transaction)
251 1 : CMutableTransaction proupregtx;
252 1 : proupregtx.nVersion = 3;
253 1 : proupregtx.nType = TRANSACTION_PROVIDER_UPDATE_REGISTRAR;
254 :
255 1 : CProUpRegTx proUpRegPayload;
256 1 : proUpRegPayload.nVersion = 1;
257 1 : proUpRegPayload.proTxHash = uint256S("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
258 1 : proUpRegPayload.nMode = 0;
259 1 : proUpRegPayload.pubKeyOperator.Set(blsKey.GetPublicKey(), false);
260 1 : proUpRegPayload.keyIDVoting = CKeyID(uint160(ParseHex("6666666666666666666666666666666666666666")));
261 1 : CScript newPayoutScript = CScript() << OP_DUP << OP_HASH160 << ToByteVector(ParseHex("7777777777777777777777777777777777777777")) << OP_EQUALVERIFY << OP_CHECKSIG;
262 1 : proUpRegPayload.scriptPayout = newPayoutScript;
263 1 : proUpRegPayload.inputsHash = uint256();
264 :
265 1 : SetTxPayload(proupregtx, proUpRegPayload);
266 :
267 : // Test 4: ProUpRevTx (Provider Update Revoke Transaction)
268 1 : CMutableTransaction prouprevtx;
269 1 : prouprevtx.nVersion = 3;
270 1 : prouprevtx.nType = TRANSACTION_PROVIDER_UPDATE_REVOKE;
271 :
272 1 : CProUpRevTx proUpRevPayload;
273 1 : proUpRevPayload.nVersion = 1;
274 1 : proUpRevPayload.proTxHash = uint256S("cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc");
275 1 : proUpRevPayload.nReason = 1;
276 1 : proUpRevPayload.inputsHash = uint256();
277 :
278 1 : SetTxPayload(prouprevtx, proUpRevPayload);
279 :
280 : // Test 5: AssetLockTx
281 1 : CMutableTransaction assetlockTx;
282 1 : assetlockTx.nVersion = 3;
283 1 : assetlockTx.nType = TRANSACTION_ASSET_LOCK;
284 :
285 1 : CAssetLockPayload assetLockPayload;
286 1 : CScript creditScript = CScript() << OP_DUP << OP_HASH160 << ToByteVector(ParseHex("4444444444444444444444444444444444444444")) << OP_EQUALVERIFY << OP_CHECKSIG;
287 1 : CTxOut creditOut(1000, creditScript);
288 1 : std::vector<CTxOut> creditOutputs = {creditOut};
289 1 : assetLockPayload = CAssetLockPayload(creditOutputs);
290 :
291 1 : SetTxPayload(assetlockTx, assetLockPayload);
292 :
293 : // Create block with all special transactions
294 1 : CBlock block;
295 1 : block.vtx.push_back(MakeTransactionRef(protx));
296 1 : block.vtx.push_back(MakeTransactionRef(proupservtx));
297 1 : block.vtx.push_back(MakeTransactionRef(proupregtx));
298 1 : block.vtx.push_back(MakeTransactionRef(prouprevtx));
299 1 : block.vtx.push_back(MakeTransactionRef(assetlockTx));
300 :
301 : // Create minimal block undo
302 1 : CBlockUndo block_undo;
303 6 : for (size_t i = 0; i < block.vtx.size(); i++) {
304 5 : block_undo.vtxundo.emplace_back();
305 5 : }
306 :
307 : // Create block filter
308 1 : BlockFilter block_filter(BlockFilterType::BASIC_FILTER, block, block_undo);
309 1 : const GCSFilter& filter = block_filter.GetFilter();
310 :
311 : // Test ProRegTx fields
312 : // collateralOutpoint
313 1 : CDataStream outpointStream(SER_NETWORK, PROTOCOL_VERSION);
314 1 : outpointStream << proRegPayload.collateralOutpoint;
315 1 : auto outpointSpan = MakeUCharSpan(outpointStream);
316 1 : BOOST_CHECK(filter.Match(GCSFilter::Element(outpointSpan.begin(), outpointSpan.end())));
317 :
318 : // keyIDOwner
319 1 : BOOST_CHECK(filter.Match(GCSFilter::Element(proRegPayload.keyIDOwner.begin(), proRegPayload.keyIDOwner.end())));
320 :
321 : // keyIDVoting
322 1 : BOOST_CHECK(filter.Match(GCSFilter::Element(proRegPayload.keyIDVoting.begin(), proRegPayload.keyIDVoting.end())));
323 :
324 : // scriptPayout
325 1 : BOOST_CHECK(filter.Match(GCSFilter::Element(payoutScript.begin(), payoutScript.end())));
326 :
327 : // Test ProUpServTx fields
328 : // proTxHash
329 1 : BOOST_CHECK(filter.Match(GCSFilter::Element(proUpServPayload.proTxHash.begin(), proUpServPayload.proTxHash.end())));
330 :
331 : // scriptOperatorPayout
332 1 : BOOST_CHECK(filter.Match(GCSFilter::Element(operatorPayoutScript.begin(), operatorPayoutScript.end())));
333 :
334 : // Test ProUpRegTx fields
335 : // proTxHash
336 1 : BOOST_CHECK(filter.Match(GCSFilter::Element(proUpRegPayload.proTxHash.begin(), proUpRegPayload.proTxHash.end())));
337 :
338 : // keyIDVoting
339 1 : BOOST_CHECK(filter.Match(GCSFilter::Element(proUpRegPayload.keyIDVoting.begin(), proUpRegPayload.keyIDVoting.end())));
340 :
341 : // scriptPayout
342 1 : BOOST_CHECK(filter.Match(GCSFilter::Element(newPayoutScript.begin(), newPayoutScript.end())));
343 :
344 : // Test ProUpRevTx fields
345 : // proTxHash
346 1 : BOOST_CHECK(filter.Match(GCSFilter::Element(proUpRevPayload.proTxHash.begin(), proUpRevPayload.proTxHash.end())));
347 :
348 : // Test AssetLock creditOutputs script
349 1 : BOOST_CHECK(filter.Match(GCSFilter::Element(creditScript.begin(), creditScript.end())));
350 :
351 : // Check that unrelated data is not in the filter
352 1 : CKeyID unrelatedKey(uint160(ParseHex("9999999999999999999999999999999999999999")));
353 1 : BOOST_CHECK(!filter.Match(GCSFilter::Element(unrelatedKey.begin(), unrelatedKey.end())));
354 1 : }
355 :
356 148 : BOOST_AUTO_TEST_CASE(blockfilter_special_transactions_edge_cases)
357 : {
358 : // Test edge cases for special transaction filtering
359 :
360 : // Test 1: Empty scripts should be handled gracefully
361 1 : CMutableTransaction protx_empty;
362 1 : protx_empty.nVersion = 3;
363 1 : protx_empty.nType = TRANSACTION_PROVIDER_REGISTER;
364 :
365 1 : CProRegTx proRegPayload_empty;
366 1 : proRegPayload_empty.nVersion = 1;
367 1 : proRegPayload_empty.nType = MnType::Regular;
368 1 : proRegPayload_empty.nMode = 0;
369 1 : proRegPayload_empty.collateralOutpoint = COutPoint(uint256S("1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef"), 0);
370 1 : proRegPayload_empty.netInfo = NetInfoInterface::MakeNetInfo(1);
371 1 : proRegPayload_empty.keyIDOwner = CKeyID(uint160(ParseHex("1111111111111111111111111111111111111111")));
372 1 : proRegPayload_empty.keyIDVoting = CKeyID(uint160(ParseHex("2222222222222222222222222222222222222222")));
373 :
374 1 : CBLSSecretKey blsKey;
375 1 : blsKey.MakeNewKey();
376 1 : proRegPayload_empty.pubKeyOperator.Set(blsKey.GetPublicKey(), false);
377 1 : proRegPayload_empty.inputsHash = uint256();
378 :
379 : // Empty payout script
380 1 : proRegPayload_empty.scriptPayout = CScript();
381 :
382 1 : SetTxPayload(protx_empty, proRegPayload_empty);
383 :
384 : // Test 2: AssetLock with OP_RETURN output (should be excluded)
385 1 : CMutableTransaction assetlock_opreturn;
386 1 : assetlock_opreturn.nVersion = 3;
387 1 : assetlock_opreturn.nType = TRANSACTION_ASSET_LOCK;
388 :
389 1 : CAssetLockPayload assetLockPayload_opreturn;
390 1 : CScript opReturnScript = CScript() << OP_RETURN << ToByteVector(ParseHex("deadbeef"));
391 1 : CScript normalScript = CScript() << OP_DUP << OP_HASH160 << ToByteVector(ParseHex("8888888888888888888888888888888888888888")) << OP_EQUALVERIFY << OP_CHECKSIG;
392 :
393 1 : CTxOut opReturnOut(0, opReturnScript);
394 1 : CTxOut normalOut(1000, normalScript);
395 1 : std::vector<CTxOut> mixedOutputs = {opReturnOut, normalOut};
396 1 : assetLockPayload_opreturn = CAssetLockPayload(mixedOutputs);
397 :
398 1 : SetTxPayload(assetlock_opreturn, assetLockPayload_opreturn);
399 :
400 : // Test 3: ProUpServTx with empty operator payout script
401 1 : CMutableTransaction proupserv_empty;
402 1 : proupserv_empty.nVersion = 3;
403 1 : proupserv_empty.nType = TRANSACTION_PROVIDER_UPDATE_SERVICE;
404 :
405 1 : CProUpServTx proUpServPayload_empty;
406 1 : proUpServPayload_empty.nVersion = 1;
407 1 : proUpServPayload_empty.proTxHash = uint256S("dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd");
408 1 : proUpServPayload_empty.netInfo = NetInfoInterface::MakeNetInfo(1);
409 1 : proUpServPayload_empty.scriptOperatorPayout = CScript(); // Empty script
410 1 : proUpServPayload_empty.inputsHash = uint256();
411 :
412 1 : SetTxPayload(proupserv_empty, proUpServPayload_empty);
413 :
414 : // Create block with edge case transactions
415 1 : CBlock block;
416 1 : block.vtx.push_back(MakeTransactionRef(protx_empty));
417 1 : block.vtx.push_back(MakeTransactionRef(assetlock_opreturn));
418 1 : block.vtx.push_back(MakeTransactionRef(proupserv_empty));
419 :
420 : // Create minimal block undo
421 1 : CBlockUndo block_undo;
422 4 : for (size_t i = 0; i < block.vtx.size(); i++) {
423 3 : block_undo.vtxundo.emplace_back();
424 3 : }
425 :
426 : // Create block filter - should not crash with edge cases
427 1 : BlockFilter block_filter(BlockFilterType::BASIC_FILTER, block, block_undo);
428 1 : const GCSFilter& filter = block_filter.GetFilter();
429 :
430 : // Test that non-empty fields are still included
431 1 : BOOST_CHECK(filter.Match(GCSFilter::Element(proRegPayload_empty.keyIDOwner.begin(),
432 : proRegPayload_empty.keyIDOwner.end())));
433 :
434 : // Test that OP_RETURN script is NOT in filter
435 1 : BOOST_CHECK(!filter.Match(GCSFilter::Element(opReturnScript.begin(), opReturnScript.end())));
436 :
437 : // Test that normal script from AssetLock IS in filter
438 1 : BOOST_CHECK(filter.Match(GCSFilter::Element(normalScript.begin(), normalScript.end())));
439 :
440 : // Test that ProUpServTx hash is still included even with empty payout script
441 1 : BOOST_CHECK(filter.Match(GCSFilter::Element(proUpServPayload_empty.proTxHash.begin(),
442 : proUpServPayload_empty.proTxHash.end())));
443 1 : }
444 :
445 146 : BOOST_AUTO_TEST_SUITE_END()
|