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