filter_test.go raw
1 package bloom_test
2
3 import (
4 "bytes"
5 "encoding/hex"
6 block2 "github.com/p9c/p9/pkg/block"
7 "github.com/p9c/p9/pkg/btcaddr"
8 "testing"
9
10 "github.com/p9c/p9/pkg/bloom"
11 "github.com/p9c/p9/pkg/chainhash"
12 "github.com/p9c/p9/pkg/util"
13 "github.com/p9c/p9/pkg/wire"
14 )
15
16 // TestFilterLarge ensures a maximum sized filter can be created.
17 func TestFilterLarge(t *testing.T) {
18 f := bloom.NewFilter(100000000, 0, 0.01, wire.BloomUpdateNone)
19 if len(f.MsgFilterLoad().Filter) > wire.MaxFilterLoadFilterSize {
20 t.Errorf("TestFilterLarge test failed: %d > %d",
21 len(f.MsgFilterLoad().Filter), wire.MaxFilterLoadFilterSize,
22 )
23 }
24 }
25
26 // TestFilterLoad ensures loading and unloading of a filter pass.
27 func TestFilterLoad(t *testing.T) {
28 merkle := wire.MsgFilterLoad{}
29 f := bloom.LoadFilter(&merkle)
30 if !f.IsLoaded() {
31 t.Errorf("TestFilterLoad IsLoaded test failed: want %v got %v",
32 true, !f.IsLoaded(),
33 )
34 return
35 }
36 f.Unload()
37 if f.IsLoaded() {
38 t.Errorf("TestFilterLoad IsLoaded test failed: want %v got %v",
39 f.IsLoaded(), false,
40 )
41 return
42 }
43 }
44
45 // TestFilterInsert ensures inserting data into the filter causes that data to be matched and the resulting serialized
46 // MsgFilterLoad is the expected value.
47 func TestFilterInsert(t *testing.T) {
48 var tests = []struct {
49 hex string
50 insert bool
51 }{
52 {"99108ad8ed9bb6274d3980bab5a85c048f0950c8", true},
53 {"19108ad8ed9bb6274d3980bab5a85c048f0950c8", false},
54 {"b5a2c786d9ef4658287ced5914b37a1b4aa32eee", true},
55 {"b9300670b4c5366e95b2699e8b18bc75e5f729c5", true},
56 }
57 f := bloom.NewFilter(3, 0, 0.01, wire.BloomUpdateAll)
58 for i, test := range tests {
59 data, e := hex.DecodeString(test.hex)
60 if e != nil {
61 t.Errorf("TestFilterInsert DecodeString failed: %v\n", e)
62 return
63 }
64 if test.insert {
65 f.Add(data)
66 }
67 result := f.Matches(data)
68 if test.insert != result {
69 t.Errorf("TestFilterInsert Matches test #%d failure: got %v want %v\n",
70 i, result, test.insert,
71 )
72 return
73 }
74 }
75 want, e := hex.DecodeString("03614e9b050000000000000001")
76 if e != nil {
77 t.Errorf("TestFilterInsert DecodeString failed: %v\n", e)
78 return
79 }
80 got := bytes.NewBuffer(nil)
81 e = f.MsgFilterLoad().BtcEncode(got, wire.ProtocolVersion, wire.LatestEncoding)
82 if e != nil {
83 t.Errorf("TestFilterInsert BtcDecode failed: %v\n", e)
84 return
85 }
86 if !bytes.Equal(got.Bytes(), want) {
87 t.Errorf("TestFilterInsert failure: got %v want %v\n",
88 got.Bytes(), want,
89 )
90 return
91 }
92 }
93
94 // TestFilterFPRange checks that new filters made with out of range false positive targets result in either max or min
95 // false positive rates.
96 func TestFilterFPRange(t *testing.T) {
97 tests := []struct {
98 name string
99 hash string
100 want string
101 filter *bloom.Filter
102 }{
103 {
104 name: "fprates > 1 should be clipped at 1",
105 hash: "02981fa052f0481dbc5868f4fc2166035a10f27a03cfd2de67326471df5bc041",
106 want: "00000000000000000001",
107 filter: bloom.NewFilter(1, 0, 20.9999999769, wire.BloomUpdateAll),
108 },
109 {
110 name: "fprates less than 1e-9 should be clipped at min",
111 hash: "02981fa052f0481dbc5868f4fc2166035a10f27a03cfd2de67326471df5bc041",
112 want: "0566d97a91a91b0000000000000001",
113 filter: bloom.NewFilter(1, 0, 0, wire.BloomUpdateAll),
114 },
115 {
116 name: "negative fprates should be clipped at min",
117 hash: "02981fa052f0481dbc5868f4fc2166035a10f27a03cfd2de67326471df5bc041",
118 want: "0566d97a91a91b0000000000000001",
119 filter: bloom.NewFilter(1, 0, -1, wire.BloomUpdateAll),
120 },
121 }
122 for _, test := range tests {
123 // Convert test input to appropriate types.
124 hash, e := chainhash.NewHashFromStr(test.hash)
125 if e != nil {
126 t.Errorf("NewHashFromStr unexpected error: %v", e)
127 continue
128 }
129 want, e := hex.DecodeString(test.want)
130 if e != nil {
131 t.Errorf("DecodeString unexpected error: %v\n", e)
132 continue
133 }
134 // Add the test hash to the bloom filter and ensure the
135 // filter serializes to the expected bytes.
136 f := test.filter
137 f.AddHash(hash)
138 got := bytes.NewBuffer(nil)
139 e = f.MsgFilterLoad().BtcEncode(got, wire.ProtocolVersion, wire.LatestEncoding)
140 if e != nil {
141 t.Errorf("BtcDecode unexpected error: %v\n", e)
142 continue
143 }
144 if !bytes.Equal(got.Bytes(), want) {
145 t.Errorf("serialized filter mismatch: got %x want %x\n",
146 got.Bytes(), want,
147 )
148 continue
149 }
150 }
151 }
152
153 // TestFilterInsert ensures inserting data into the filter with a tweak causes that data to be matched and the resulting
154 // serialized MsgFilterLoad is the expected value.
155 func TestFilterInsertWithTweak(t *testing.T) {
156 var tests = []struct {
157 hex string
158 insert bool
159 }{
160 {"99108ad8ed9bb6274d3980bab5a85c048f0950c8", true},
161 {"19108ad8ed9bb6274d3980bab5a85c048f0950c8", false},
162 {"b5a2c786d9ef4658287ced5914b37a1b4aa32eee", true},
163 {"b9300670b4c5366e95b2699e8b18bc75e5f729c5", true},
164 }
165 f := bloom.NewFilter(3, 2147483649, 0.01, wire.BloomUpdateAll)
166 for i, test := range tests {
167 data, e := hex.DecodeString(test.hex)
168 if e != nil {
169 t.Errorf("TestFilterInsertWithTweak DecodeString failed: %v\n", e)
170 return
171 }
172 if test.insert {
173 f.Add(data)
174 }
175 result := f.Matches(data)
176 if test.insert != result {
177 t.Errorf("TestFilterInsertWithTweak Matches test #%d failure: got %v want %v\n",
178 i, result, test.insert,
179 )
180 return
181 }
182 }
183 want, e := hex.DecodeString("03ce4299050000000100008001")
184 if e != nil {
185 t.Errorf("TestFilterInsertWithTweak DecodeString failed: %v\n", e)
186 return
187 }
188 got := bytes.NewBuffer(nil)
189 e = f.MsgFilterLoad().BtcEncode(got, wire.ProtocolVersion, wire.LatestEncoding)
190 if e != nil {
191 t.Errorf("TestFilterInsertWithTweak BtcDecode failed: %v\n", e)
192 return
193 }
194 if !bytes.Equal(got.Bytes(), want) {
195 t.Errorf("TestFilterInsertWithTweak failure: got %v want %v\n",
196 got.Bytes(), want,
197 )
198 return
199 }
200 }
201
202 // TestFilterInsertKey ensures inserting public keys and addresses works as expected.
203 func TestFilterInsertKey(t *testing.T) {
204 secret := "5Kg1gnAjaLfKiwhhPpGS3QfRg2m6awQvaj98JCZBZQ5SuS2F15C"
205 wif, e := util.DecodeWIF(secret)
206 if e != nil {
207 t.Errorf("TestFilterInsertKey DecodeWIF failed: %v", e)
208 return
209 }
210 f := bloom.NewFilter(2, 0, 0.001, wire.BloomUpdateAll)
211 f.Add(wif.SerializePubKey())
212 f.Add(btcaddr.Hash160(wif.SerializePubKey()))
213 want, e := hex.DecodeString("038fc16b080000000000000001")
214 if e != nil {
215 t.Errorf("TestFilterInsertWithTweak DecodeString failed: %v\n", e)
216 return
217 }
218 got := bytes.NewBuffer(nil)
219 e = f.MsgFilterLoad().BtcEncode(got, wire.ProtocolVersion, wire.LatestEncoding)
220 if e != nil {
221 t.Errorf("TestFilterInsertWithTweak BtcDecode failed: %v\n", e)
222 return
223 }
224 if !bytes.Equal(got.Bytes(), want) {
225 t.Errorf("TestFilterInsertWithTweak failure: got %v want %v\n",
226 got.Bytes(), want,
227 )
228 return
229 }
230 }
231 func TestFilterBloomMatch(t *testing.T) {
232 str := "01000000010b26e9b7735eb6aabdf358bab62f9816a21ba9ebdb719d5299e" +
233 "88607d722c190000000008b4830450220070aca44506c5cef3a16ed519d7" +
234 "c3c39f8aab192c4e1c90d065f37b8a4af6141022100a8e160b856c2d43d2" +
235 "7d8fba71e5aef6405b8643ac4cb7cb3c462aced7f14711a0141046d11fee" +
236 "51b0e60666d5049a9101a72741df480b96ee26488a4d3466b95c9a40ac5e" +
237 "eef87e10a5cd336c19a84565f80fa6c547957b7700ff4dfbdefe76036c33" +
238 "9ffffffff021bff3d11000000001976a91404943fdd508053c75000106d3" +
239 "bc6e2754dbcff1988ac2f15de00000000001976a914a266436d296554760" +
240 "8b9e15d9032a7b9d64fa43188ac00000000"
241 strBytes, e := hex.DecodeString(str)
242 if e != nil {
243 t.Errorf("TestFilterBloomMatch DecodeString failure: %v", e)
244 return
245 }
246 tx, e := util.NewTxFromBytes(strBytes)
247 if e != nil {
248 t.Errorf("TestFilterBloomMatch NewTxFromBytes failure: %v", e)
249 return
250 }
251 spendingTxBytes := []byte{0x01, 0x00, 0x00, 0x00, 0x01, 0x6b, 0xff, 0x7f,
252 0xcd, 0x4f, 0x85, 0x65, 0xef, 0x40, 0x6d, 0xd5, 0xd6,
253 0x3d, 0x4f, 0xf9, 0x4f, 0x31, 0x8f, 0xe8, 0x20, 0x27,
254 0xfd, 0x4d, 0xc4, 0x51, 0xb0, 0x44, 0x74, 0x01, 0x9f,
255 0x74, 0xb4, 0x00, 0x00, 0x00, 0x00, 0x8c, 0x49, 0x30,
256 0x46, 0x02, 0x21, 0x00, 0xda, 0x0d, 0xc6, 0xae, 0xce,
257 0xfe, 0x1e, 0x06, 0xef, 0xdf, 0x05, 0x77, 0x37, 0x57,
258 0xde, 0xb1, 0x68, 0x82, 0x09, 0x30, 0xe3, 0xb0, 0xd0,
259 0x3f, 0x46, 0xf5, 0xfc, 0xf1, 0x50, 0xbf, 0x99, 0x0c,
260 0x02, 0x21, 0x00, 0xd2, 0x5b, 0x5c, 0x87, 0x04, 0x00,
261 0x76, 0xe4, 0xf2, 0x53, 0xf8, 0x26, 0x2e, 0x76, 0x3e,
262 0x2d, 0xd5, 0x1e, 0x7f, 0xf0, 0xbe, 0x15, 0x77, 0x27,
263 0xc4, 0xbc, 0x42, 0x80, 0x7f, 0x17, 0xbd, 0x39, 0x01,
264 0x41, 0x04, 0xe6, 0xc2, 0x6e, 0xf6, 0x7d, 0xc6, 0x10,
265 0xd2, 0xcd, 0x19, 0x24, 0x84, 0x78, 0x9a, 0x6c, 0xf9,
266 0xae, 0xa9, 0x93, 0x0b, 0x94, 0x4b, 0x7e, 0x2d, 0xb5,
267 0x34, 0x2b, 0x9d, 0x9e, 0x5b, 0x9f, 0xf7, 0x9a, 0xff,
268 0x9a, 0x2e, 0xe1, 0x97, 0x8d, 0xd7, 0xfd, 0x01, 0xdf,
269 0xc5, 0x22, 0xee, 0x02, 0x28, 0x3d, 0x3b, 0x06, 0xa9,
270 0xd0, 0x3a, 0xcf, 0x80, 0x96, 0x96, 0x8d, 0x7d, 0xbb,
271 0x0f, 0x91, 0x78, 0xff, 0xff, 0xff, 0xff, 0x02, 0x8b,
272 0xa7, 0x94, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x19, 0x76,
273 0xa9, 0x14, 0xba, 0xde, 0xec, 0xfd, 0xef, 0x05, 0x07,
274 0x24, 0x7f, 0xc8, 0xf7, 0x42, 0x41, 0xd7, 0x3b, 0xc0,
275 0x39, 0x97, 0x2d, 0x7b, 0x88, 0xac, 0x40, 0x94, 0xa8,
276 0x02, 0x00, 0x00, 0x00, 0x00, 0x19, 0x76, 0xa9, 0x14,
277 0xc1, 0x09, 0x32, 0x48, 0x3f, 0xec, 0x93, 0xed, 0x51,
278 0xf5, 0xfe, 0x95, 0xe7, 0x25, 0x59, 0xf2, 0xcc, 0x70,
279 0x43, 0xf9, 0x88, 0xac, 0x00, 0x00, 0x00, 0x00, 0x00,
280 }
281 spendingTx, e := util.NewTxFromBytes(spendingTxBytes)
282 if e != nil {
283 t.Errorf("TestFilterBloomMatch NewTxFromBytes failure: %v", e)
284 return
285 }
286 f := bloom.NewFilter(10, 0, 0.000001, wire.BloomUpdateAll)
287 inputStr := "b4749f017444b051c44dfd2720e88f314ff94f3dd6d56d40ef65854fcd7fff6b"
288 hash, e := chainhash.NewHashFromStr(inputStr)
289 if e != nil {
290 t.Errorf("TestFilterBloomMatch NewHashFromStr failed: %v\n", e)
291 return
292 }
293 f.AddHash(hash)
294 if !f.MatchTxAndUpdate(tx) {
295 t.Errorf("TestFilterBloomMatch didn't match hash %s", inputStr)
296 }
297 f = bloom.NewFilter(10, 0, 0.000001, wire.BloomUpdateAll)
298 inputStr = "6bff7fcd4f8565ef406dd5d63d4ff94f318fe82027fd4dc451b04474019f74b4"
299 hashBytes, e := hex.DecodeString(inputStr)
300 if e != nil {
301 t.Errorf("TestFilterBloomMatch DecodeString failed: %v\n", e)
302 return
303 }
304 f.Add(hashBytes)
305 if !f.MatchTxAndUpdate(tx) {
306 t.Errorf("TestFilterBloomMatch didn't match hash %s", inputStr)
307 }
308 f = bloom.NewFilter(10, 0, 0.000001, wire.BloomUpdateAll)
309 inputStr = "30450220070aca44506c5cef3a16ed519d7c3c39f8aab192c4e1c90d065" +
310 "f37b8a4af6141022100a8e160b856c2d43d27d8fba71e5aef6405b8643" +
311 "ac4cb7cb3c462aced7f14711a01"
312 hashBytes, e = hex.DecodeString(inputStr)
313 if e != nil {
314 t.Errorf("TestFilterBloomMatch DecodeString failed: %v\n", e)
315 return
316 }
317 f.Add(hashBytes)
318 if !f.MatchTxAndUpdate(tx) {
319 t.Errorf("TestFilterBloomMatch didn't match input signature %s", inputStr)
320 }
321 f = bloom.NewFilter(10, 0, 0.000001, wire.BloomUpdateAll)
322 inputStr = "046d11fee51b0e60666d5049a9101a72741df480b96ee26488a4d3466b95" +
323 "c9a40ac5eeef87e10a5cd336c19a84565f80fa6c547957b7700ff4dfbdefe" +
324 "76036c339"
325 hashBytes, e = hex.DecodeString(inputStr)
326 if e != nil {
327 t.Errorf("TestFilterBloomMatch DecodeString failed: %v\n", e)
328 return
329 }
330 f.Add(hashBytes)
331 if !f.MatchTxAndUpdate(tx) {
332 t.Errorf("TestFilterBloomMatch didn't match input pubkey %s", inputStr)
333 }
334 f = bloom.NewFilter(10, 0, 0.000001, wire.BloomUpdateAll)
335 inputStr = "04943fdd508053c75000106d3bc6e2754dbcff19"
336 hashBytes, e = hex.DecodeString(inputStr)
337 if e != nil {
338 t.Errorf("TestFilterBloomMatch DecodeString failed: %v\n", e)
339 return
340 }
341 f.Add(hashBytes)
342 if !f.MatchTxAndUpdate(tx) {
343 t.Errorf("TestFilterBloomMatch didn't match output address %s", inputStr)
344 }
345 if !f.MatchTxAndUpdate(spendingTx) {
346 t.Errorf("TestFilterBloomMatch spendingTx didn't match output address %s", inputStr)
347 }
348 f = bloom.NewFilter(10, 0, 0.000001, wire.BloomUpdateAll)
349 inputStr = "a266436d2965547608b9e15d9032a7b9d64fa431"
350 hashBytes, e = hex.DecodeString(inputStr)
351 if e != nil {
352 t.Errorf("TestFilterBloomMatch DecodeString failed: %v\n", e)
353 return
354 }
355 f.Add(hashBytes)
356 if !f.MatchTxAndUpdate(tx) {
357 t.Errorf("TestFilterBloomMatch didn't match output address %s", inputStr)
358 }
359 f = bloom.NewFilter(10, 0, 0.000001, wire.BloomUpdateAll)
360 inputStr = "90c122d70786e899529d71dbeba91ba216982fb6ba58f3bdaab65e73b7e9260b"
361 hash, e = chainhash.NewHashFromStr(inputStr)
362 if e != nil {
363 t.Errorf("TestFilterBloomMatch NewHashFromStr failed: %v\n", e)
364 return
365 }
366 outpoint := wire.NewOutPoint(hash, 0)
367 f.AddOutPoint(outpoint)
368 if !f.MatchTxAndUpdate(tx) {
369 t.Errorf("TestFilterBloomMatch didn't match outpoint %s", inputStr)
370 }
371 f = bloom.NewFilter(10, 0, 0.000001, wire.BloomUpdateAll)
372 inputStr = "00000009e784f32f62ef849763d4f45b98e07ba658647343b915ff832b110436"
373 hash, e = chainhash.NewHashFromStr(inputStr)
374 if e != nil {
375 t.Errorf("TestFilterBloomMatch NewHashFromStr failed: %v\n", e)
376 return
377 }
378 f.AddHash(hash)
379 if f.MatchTxAndUpdate(tx) {
380 t.Errorf("TestFilterBloomMatch matched hash %s", inputStr)
381 }
382 f = bloom.NewFilter(10, 0, 0.000001, wire.BloomUpdateAll)
383 inputStr = "0000006d2965547608b9e15d9032a7b9d64fa431"
384 hashBytes, e = hex.DecodeString(inputStr)
385 if e != nil {
386 t.Errorf("TestFilterBloomMatch DecodeString failed: %v\n", e)
387 return
388 }
389 f.Add(hashBytes)
390 if f.MatchTxAndUpdate(tx) {
391 t.Errorf("TestFilterBloomMatch matched address %s", inputStr)
392 }
393 f = bloom.NewFilter(10, 0, 0.000001, wire.BloomUpdateAll)
394 inputStr = "90c122d70786e899529d71dbeba91ba216982fb6ba58f3bdaab65e73b7e9260b"
395 hash, e = chainhash.NewHashFromStr(inputStr)
396 if e != nil {
397 t.Errorf("TestFilterBloomMatch NewHashFromStr failed: %v\n", e)
398 return
399 }
400 outpoint = wire.NewOutPoint(hash, 1)
401 f.AddOutPoint(outpoint)
402 if f.MatchTxAndUpdate(tx) {
403 t.Errorf("TestFilterBloomMatch matched outpoint %s", inputStr)
404 }
405 f = bloom.NewFilter(10, 0, 0.000001, wire.BloomUpdateAll)
406 inputStr = "000000d70786e899529d71dbeba91ba216982fb6ba58f3bdaab65e73b7e9260b"
407 hash, e = chainhash.NewHashFromStr(inputStr)
408 if e != nil {
409 t.Errorf("TestFilterBloomMatch NewHashFromStr failed: %v\n", e)
410 return
411 }
412 outpoint = wire.NewOutPoint(hash, 0)
413 f.AddOutPoint(outpoint)
414 if f.MatchTxAndUpdate(tx) {
415 t.Errorf("TestFilterBloomMatch matched outpoint %s", inputStr)
416 }
417 }
418 func TestFilterInsertUpdateNone(t *testing.T) {
419 f := bloom.NewFilter(10, 0, 0.000001, wire.BloomUpdateNone)
420 // Add the generation pubkey
421 inputStr := "04eaafc2314def4ca98ac970241bcab022b9c1e1f4ea423a20f134c" +
422 "876f2c01ec0f0dd5b2e86e7168cefe0d81113c3807420ce13ad1357231a" +
423 "2252247d97a46a91"
424 inputBytes, e := hex.DecodeString(inputStr)
425 if e != nil {
426 t.Errorf("TestFilterInsertUpdateNone DecodeString failed: %v", e)
427 return
428 }
429 f.Add(inputBytes)
430 // Add the output address for the 4th transaction
431 inputStr = "b6efd80d99179f4f4ff6f4dd0a007d018c385d21"
432 inputBytes, e = hex.DecodeString(inputStr)
433 if e != nil {
434 t.Errorf("TestFilterInsertUpdateNone DecodeString failed: %v", e)
435 return
436 }
437 f.Add(inputBytes)
438 inputStr = "147caa76786596590baa4e98f5d9f48b86c7765e489f7a6ff3360fe5c674360b"
439 hash, e := chainhash.NewHashFromStr(inputStr)
440 if e != nil {
441 t.Errorf("TestFilterInsertUpdateNone NewHashFromStr failed: %v", e)
442 return
443 }
444 outpoint := wire.NewOutPoint(hash, 0)
445 if f.MatchesOutPoint(outpoint) {
446 t.Errorf("TestFilterInsertUpdateNone matched outpoint %s", inputStr)
447 return
448 }
449 inputStr = "02981fa052f0481dbc5868f4fc2166035a10f27a03cfd2de67326471df5bc041"
450 hash, e = chainhash.NewHashFromStr(inputStr)
451 if e != nil {
452 t.Errorf("TestFilterInsertUpdateNone NewHashFromStr failed: %v", e)
453 return
454 }
455 outpoint = wire.NewOutPoint(hash, 0)
456 if f.MatchesOutPoint(outpoint) {
457 t.Errorf("TestFilterInsertUpdateNone matched outpoint %s", inputStr)
458 return
459 }
460 }
461 func TestFilterInsertP2PubKeyOnly(t *testing.T) {
462 blockStr := "0100000082bb869cf3a793432a66e826e05a6fc37469f8efb7421dc" +
463 "880670100000000007f16c5962e8bd963659c793ce370d95f093bc7e367" +
464 "117b3c30c1f8fdd0d9728776381b4d4c86041b554b85290701000000010" +
465 "00000000000000000000000000000000000000000000000000000000000" +
466 "0000ffffffff07044c86041b0136ffffffff0100f2052a0100000043410" +
467 "4eaafc2314def4ca98ac970241bcab022b9c1e1f4ea423a20f134c876f2" +
468 "c01ec0f0dd5b2e86e7168cefe0d81113c3807420ce13ad1357231a22522" +
469 "47d97a46a91ac000000000100000001bcad20a6a29827d1424f08989255" +
470 "120bf7f3e9e3cdaaa6bb31b0737fe048724300000000494830450220356" +
471 "e834b046cadc0f8ebb5a8a017b02de59c86305403dad52cd77b55af062e" +
472 "a10221009253cd6c119d4729b77c978e1e2aa19f5ea6e0e52b3f16e32fa" +
473 "608cd5bab753901ffffffff02008d380c010000001976a9142b4b8072ec" +
474 "bba129b6453c63e129e643207249ca88ac0065cd1d000000001976a9141" +
475 "b8dd13b994bcfc787b32aeadf58ccb3615cbd5488ac0000000001000000" +
476 "03fdacf9b3eb077412e7a968d2e4f11b9a9dee312d666187ed77ee7d26a" +
477 "f16cb0b000000008c493046022100ea1608e70911ca0de5af51ba57ad23" +
478 "b9a51db8d28f82c53563c56a05c20f5a87022100a8bdc8b4a8acc8634c6" +
479 "b420410150775eb7f2474f5615f7fccd65af30f310fbf01410465fdf49e" +
480 "29b06b9a1582287b6279014f834edc317695d125ef623c1cc3aaece245b" +
481 "d69fcad7508666e9c74a49dc9056d5fc14338ef38118dc4afae5fe2c585" +
482 "caffffffff309e1913634ecb50f3c4f83e96e70b2df071b497b8973a3e7" +
483 "5429df397b5af83000000004948304502202bdb79c596a9ffc24e96f438" +
484 "6199aba386e9bc7b6071516e2b51dda942b3a1ed022100c53a857e76b72" +
485 "4fc14d45311eac5019650d415c3abb5428f3aae16d8e69bec2301ffffff" +
486 "ff2089e33491695080c9edc18a428f7d834db5b6d372df13ce2b1b0e0cb" +
487 "cb1e6c10000000049483045022100d4ce67c5896ee251c810ac1ff9cecc" +
488 "d328b497c8f553ab6e08431e7d40bad6b5022033119c0c2b7d792d31f11" +
489 "87779c7bd95aefd93d90a715586d73801d9b47471c601ffffffff010071" +
490 "4460030000001976a914c7b55141d097ea5df7a0ed330cf794376e53ec8" +
491 "d88ac0000000001000000045bf0e214aa4069a3e792ecee1e1bf0c1d397" +
492 "cde8dd08138f4b72a00681743447000000008b48304502200c45de8c4f3" +
493 "e2c1821f2fc878cba97b1e6f8807d94930713aa1c86a67b9bf1e4022100" +
494 "8581abfef2e30f957815fc89978423746b2086375ca8ecf359c85c2a5b7" +
495 "c88ad01410462bb73f76ca0994fcb8b4271e6fb7561f5c0f9ca0cf64852" +
496 "61c4a0dc894f4ab844c6cdfb97cd0b60ffb5018ffd6238f4d87270efb1d" +
497 "3ae37079b794a92d7ec95ffffffffd669f7d7958d40fc59d2253d88e0f2" +
498 "48e29b599c80bbcec344a83dda5f9aa72c000000008a473044022078124" +
499 "c8beeaa825f9e0b30bff96e564dd859432f2d0cb3b72d3d5d93d38d7e93" +
500 "0220691d233b6c0f995be5acb03d70a7f7a65b6bc9bdd426260f38a1346" +
501 "669507a3601410462bb73f76ca0994fcb8b4271e6fb7561f5c0f9ca0cf6" +
502 "485261c4a0dc894f4ab844c6cdfb97cd0b60ffb5018ffd6238f4d87270e" +
503 "fb1d3ae37079b794a92d7ec95fffffffff878af0d93f5229a68166cf051" +
504 "fd372bb7a537232946e0a46f53636b4dafdaa4000000008c49304602210" +
505 "0c717d1714551663f69c3c5759bdbb3a0fcd3fab023abc0e522fe6440de" +
506 "35d8290221008d9cbe25bffc44af2b18e81c58eb37293fd7fe1c2e7b46f" +
507 "c37ee8c96c50ab1e201410462bb73f76ca0994fcb8b4271e6fb7561f5c0" +
508 "f9ca0cf6485261c4a0dc894f4ab844c6cdfb97cd0b60ffb5018ffd6238f" +
509 "4d87270efb1d3ae37079b794a92d7ec95ffffffff27f2b668859cd7f2f8" +
510 "94aa0fd2d9e60963bcd07c88973f425f999b8cbfd7a1e2000000008c493" +
511 "046022100e00847147cbf517bcc2f502f3ddc6d284358d102ed20d47a8a" +
512 "a788a62f0db780022100d17b2d6fa84dcaf1c95d88d7e7c30385aecf415" +
513 "588d749afd3ec81f6022cecd701410462bb73f76ca0994fcb8b4271e6fb" +
514 "7561f5c0f9ca0cf6485261c4a0dc894f4ab844c6cdfb97cd0b60ffb5018" +
515 "ffd6238f4d87270efb1d3ae37079b794a92d7ec95ffffffff0100c817a8" +
516 "040000001976a914b6efd80d99179f4f4ff6f4dd0a007d018c385d2188a" +
517 "c000000000100000001834537b2f1ce8ef9373a258e10545ce5a50b758d" +
518 "f616cd4356e0032554ebd3c4000000008b483045022100e68f422dd7c34" +
519 "fdce11eeb4509ddae38201773dd62f284e8aa9d96f85099d0b002202243" +
520 "bd399ff96b649a0fad05fa759d6a882f0af8c90cf7632c2840c29070aec" +
521 "20141045e58067e815c2f464c6a2a15f987758374203895710c2d452442" +
522 "e28496ff38ba8f5fd901dc20e29e88477167fe4fc299bf818fd0d9e1632" +
523 "d467b2a3d9503b1aaffffffff0280d7e636030000001976a914f34c3e10" +
524 "eb387efe872acb614c89e78bfca7815d88ac404b4c00000000001976a91" +
525 "4a84e272933aaf87e1715d7786c51dfaeb5b65a6f88ac00000000010000" +
526 "000143ac81c8e6f6ef307dfe17f3d906d999e23e0189fda838c5510d850" +
527 "927e03ae7000000008c4930460221009c87c344760a64cb8ae6685a3eec" +
528 "2c1ac1bed5b88c87de51acd0e124f266c16602210082d07c037359c3a25" +
529 "7b5c63ebd90f5a5edf97b2ac1c434b08ca998839f346dd40141040ba7e5" +
530 "21fa7946d12edbb1d1e95a15c34bd4398195e86433c92b431cd315f455f" +
531 "e30032ede69cad9d1e1ed6c3c4ec0dbfced53438c625462afb792dcb098" +
532 "544bffffffff0240420f00000000001976a9144676d1b820d63ec272f19" +
533 "00d59d43bc6463d96f888ac40420f00000000001976a914648d04341d00" +
534 "d7968b3405c034adc38d4d8fb9bd88ac00000000010000000248cc91750" +
535 "1ea5c55f4a8d2009c0567c40cfe037c2e71af017d0a452ff705e3f10000" +
536 "00008b483045022100bf5fdc86dc5f08a5d5c8e43a8c9d5b1ed8c65562e" +
537 "280007b52b133021acd9acc02205e325d613e555f772802bf413d36ba80" +
538 "7892ed1a690a77811d3033b3de226e0a01410429fa713b124484cb2bd7b" +
539 "5557b2c0b9df7b2b1fee61825eadc5ae6c37a9920d38bfccdc7dc3cb0c4" +
540 "7d7b173dbc9db8d37db0a33ae487982c59c6f8606e9d1791ffffffff41e" +
541 "d70551dd7e841883ab8f0b16bf04176b7d1480e4f0af9f3d4c3595768d0" +
542 "68000000008b4830450221008513ad65187b903aed1102d1d0c47688127" +
543 "658c51106753fed0151ce9c16b80902201432b9ebcb87bd04ceb2de6603" +
544 "5fbbaf4bf8b00d1cfe41f1a1f7338f9ad79d210141049d4cf80125bf50b" +
545 "e1709f718c07ad15d0fc612b7da1f5570dddc35f2a352f0f27c978b0682" +
546 "0edca9ef982c35fda2d255afba340068c5035552368bc7200c1488fffff" +
547 "fff0100093d00000000001976a9148edb68822f1ad580b043c7b3df2e40" +
548 "0f8699eb4888ac00000000"
549 blockBytes, e := hex.DecodeString(blockStr)
550 if e != nil {
551 t.Errorf("TestFilterInsertP2PubKeyOnly DecodeString failed: %v", e)
552 return
553 }
554 block, e := block2.NewFromBytes(blockBytes)
555 if e != nil {
556 t.Errorf("TestFilterInsertP2PubKeyOnly NewFromBytes failed: %v", e)
557 return
558 }
559 f := bloom.NewFilter(10, 0, 0.000001, wire.BloomUpdateP2PubkeyOnly)
560 // Generation pubkey
561 inputStr := "04eaafc2314def4ca98ac970241bcab022b9c1e1f4ea423a20f134c" +
562 "876f2c01ec0f0dd5b2e86e7168cefe0d81113c3807420ce13ad1357231a" +
563 "2252247d97a46a91"
564 inputBytes, e := hex.DecodeString(inputStr)
565 if e != nil {
566 t.Errorf("TestFilterInsertP2PubKeyOnly DecodeString failed: %v", e)
567 return
568 }
569 f.Add(inputBytes)
570 // Output address of 4th transaction
571 inputStr = "b6efd80d99179f4f4ff6f4dd0a007d018c385d21"
572 inputBytes, e = hex.DecodeString(inputStr)
573 if e != nil {
574 t.Errorf("TestFilterInsertP2PubKeyOnly DecodeString failed: %v", e)
575 return
576 }
577 f.Add(inputBytes)
578 // Ignore return value -- this is just used to update the filter.
579 _, _ = bloom.NewMerkleBlock(block, f)
580 // We should match the generation pubkey
581 inputStr = "147caa76786596590baa4e98f5d9f48b86c7765e489f7a6ff3360fe5c674360b"
582 hash, e := chainhash.NewHashFromStr(inputStr)
583 if e != nil {
584 t.Errorf("TestMerkleBlockP2PubKeyOnly NewHashFromStr failed: %v", e)
585 return
586 }
587 outpoint := wire.NewOutPoint(hash, 0)
588 if !f.MatchesOutPoint(outpoint) {
589 t.Errorf("TestMerkleBlockP2PubKeyOnly didn't match the generation "+
590 "outpoint %s", inputStr,
591 )
592 return
593 }
594 // We should not match the 4th transaction, which is not p2pk
595 inputStr = "02981fa052f0481dbc5868f4fc2166035a10f27a03cfd2de67326471df5bc041"
596 hash, e = chainhash.NewHashFromStr(inputStr)
597 if e != nil {
598 t.Errorf("TestMerkleBlockP2PubKeyOnly NewHashFromStr failed: %v", e)
599 return
600 }
601 outpoint = wire.NewOutPoint(hash, 0)
602 if f.MatchesOutPoint(outpoint) {
603 t.Errorf("TestMerkleBlockP2PubKeyOnly matched outpoint %s", inputStr)
604 return
605 }
606 }
607 func TestFilterReload(t *testing.T) {
608 f := bloom.NewFilter(10, 0, 0.000001, wire.BloomUpdateAll)
609 bFilter := bloom.LoadFilter(f.MsgFilterLoad())
610 if bFilter.MsgFilterLoad() == nil {
611 t.Errorf("TestFilterReload LoadFilter test failed")
612 return
613 }
614 bFilter.Reload(nil)
615 if bFilter.MsgFilterLoad() != nil {
616 t.Errorf("TestFilterReload Reload test failed")
617 }
618 }
619