github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/whisper/whisperv5/filter_test.go (about)

     1  
     2  //此源码被清华学神尹成大魔王专业翻译分析并修改
     3  //尹成QQ77025077
     4  //尹成微信18510341407
     5  //尹成所在QQ群721929980
     6  //尹成邮箱 yinc13@mails.tsinghua.edu.cn
     7  //尹成毕业于清华大学,微软区块链领域全球最有价值专家
     8  //https://mvp.microsoft.com/zh-cn/PublicProfile/4033620
     9  //
    10  //
    11  //
    12  //
    13  //
    14  //
    15  //
    16  //
    17  //
    18  //
    19  //
    20  //
    21  //
    22  //
    23  //
    24  
    25  package whisperv5
    26  
    27  import (
    28  	"math/big"
    29  	mrand "math/rand"
    30  	"testing"
    31  	"time"
    32  
    33  	"github.com/ethereum/go-ethereum/common"
    34  	"github.com/ethereum/go-ethereum/crypto"
    35  )
    36  
    37  var seed int64
    38  
    39  //
    40  //
    41  //
    42  func InitSingleTest() {
    43  	seed = time.Now().Unix()
    44  	mrand.Seed(seed)
    45  }
    46  
    47  func InitDebugTest(i int64) {
    48  	seed = i
    49  	mrand.Seed(seed)
    50  }
    51  
    52  type FilterTestCase struct {
    53  	f      *Filter
    54  	id     string
    55  	alive  bool
    56  	msgCnt int
    57  }
    58  
    59  func generateFilter(t *testing.T, symmetric bool) (*Filter, error) {
    60  	var f Filter
    61  	f.Messages = make(map[common.Hash]*ReceivedMessage)
    62  
    63  	const topicNum = 8
    64  	f.Topics = make([][]byte, topicNum)
    65  	for i := 0; i < topicNum; i++ {
    66  		f.Topics[i] = make([]byte, 4)
    67  		mrand.Read(f.Topics[i][:])
    68  		f.Topics[i][0] = 0x01
    69  	}
    70  
    71  	key, err := crypto.GenerateKey()
    72  	if err != nil {
    73  		t.Fatalf("generateFilter 1 failed with seed %d.", seed)
    74  		return nil, err
    75  	}
    76  	f.Src = &key.PublicKey
    77  
    78  	if symmetric {
    79  		f.KeySym = make([]byte, aesKeyLength)
    80  		mrand.Read(f.KeySym)
    81  		f.SymKeyHash = crypto.Keccak256Hash(f.KeySym)
    82  	} else {
    83  		f.KeyAsym, err = crypto.GenerateKey()
    84  		if err != nil {
    85  			t.Fatalf("generateFilter 2 failed with seed %d.", seed)
    86  			return nil, err
    87  		}
    88  	}
    89  
    90  //
    91  	return &f, nil
    92  }
    93  
    94  func generateTestCases(t *testing.T, SizeTestFilters int) []FilterTestCase {
    95  	cases := make([]FilterTestCase, SizeTestFilters)
    96  	for i := 0; i < SizeTestFilters; i++ {
    97  		f, _ := generateFilter(t, true)
    98  		cases[i].f = f
    99  		cases[i].alive = mrand.Int()&int(1) == 0
   100  	}
   101  	return cases
   102  }
   103  
   104  func TestInstallFilters(t *testing.T) {
   105  	InitSingleTest()
   106  
   107  	const SizeTestFilters = 256
   108  	w := New(&Config{})
   109  	filters := NewFilters(w)
   110  	tst := generateTestCases(t, SizeTestFilters)
   111  
   112  	var err error
   113  	var j string
   114  	for i := 0; i < SizeTestFilters; i++ {
   115  		j, err = filters.Install(tst[i].f)
   116  		if err != nil {
   117  			t.Fatalf("seed %d: failed to install filter: %s", seed, err)
   118  		}
   119  		tst[i].id = j
   120  		if len(j) != keyIdSize*2 {
   121  			t.Fatalf("seed %d: wrong filter id size [%d]", seed, len(j))
   122  		}
   123  	}
   124  
   125  	for _, testCase := range tst {
   126  		if !testCase.alive {
   127  			filters.Uninstall(testCase.id)
   128  		}
   129  	}
   130  
   131  	for i, testCase := range tst {
   132  		fil := filters.Get(testCase.id)
   133  		exist := fil != nil
   134  		if exist != testCase.alive {
   135  			t.Fatalf("seed %d: failed alive: %d, %v, %v", seed, i, exist, testCase.alive)
   136  		}
   137  		if exist && fil.PoW != testCase.f.PoW {
   138  			t.Fatalf("seed %d: failed Get: %d, %v, %v", seed, i, exist, testCase.alive)
   139  		}
   140  	}
   141  }
   142  
   143  func TestInstallSymKeyGeneratesHash(t *testing.T) {
   144  	InitSingleTest()
   145  
   146  	w := New(&Config{})
   147  	filters := NewFilters(w)
   148  	filter, _ := generateFilter(t, true)
   149  
   150  //
   151  	initialSymKeyHash := filter.SymKeyHash
   152  
   153  //
   154  	var invalid common.Hash
   155  	filter.SymKeyHash = invalid
   156  
   157  	_, err := filters.Install(filter)
   158  
   159  	if err != nil {
   160  		t.Fatalf("Error installing the filter: %s", err)
   161  	}
   162  
   163  	for i, b := range filter.SymKeyHash {
   164  		if b != initialSymKeyHash[i] {
   165  			t.Fatalf("The filter's symmetric key hash was not properly generated by Install")
   166  		}
   167  	}
   168  }
   169  
   170  func TestInstallIdenticalFilters(t *testing.T) {
   171  	InitSingleTest()
   172  
   173  	w := New(&Config{})
   174  	filters := NewFilters(w)
   175  	filter1, _ := generateFilter(t, true)
   176  
   177  //
   178  //
   179  	filter2 := &Filter{
   180  		KeySym:   filter1.KeySym,
   181  		Topics:   filter1.Topics,
   182  		PoW:      filter1.PoW,
   183  		AllowP2P: filter1.AllowP2P,
   184  		Messages: make(map[common.Hash]*ReceivedMessage),
   185  	}
   186  
   187  	_, err := filters.Install(filter1)
   188  
   189  	if err != nil {
   190  		t.Fatalf("Error installing the first filter with seed %d: %s", seed, err)
   191  	}
   192  
   193  	_, err = filters.Install(filter2)
   194  
   195  	if err != nil {
   196  		t.Fatalf("Error installing the second filter with seed %d: %s", seed, err)
   197  	}
   198  
   199  	params, err := generateMessageParams()
   200  	if err != nil {
   201  		t.Fatalf("Error generating message parameters with seed %d: %s", seed, err)
   202  	}
   203  
   204  	params.KeySym = filter1.KeySym
   205  	params.Topic = BytesToTopic(filter1.Topics[0])
   206  
   207  	filter1.Src = &params.Src.PublicKey
   208  	filter2.Src = &params.Src.PublicKey
   209  
   210  	sentMessage, err := NewSentMessage(params)
   211  	if err != nil {
   212  		t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
   213  	}
   214  	env, err := sentMessage.Wrap(params)
   215  	if err != nil {
   216  		t.Fatalf("failed Wrap with seed %d: %s.", seed, err)
   217  	}
   218  	msg := env.Open(filter1)
   219  	if msg == nil {
   220  		t.Fatalf("failed to Open with filter1")
   221  	}
   222  
   223  	if !filter1.MatchEnvelope(env) {
   224  		t.Fatalf("failed matching with the first filter")
   225  	}
   226  
   227  	if !filter2.MatchEnvelope(env) {
   228  		t.Fatalf("failed matching with the first filter")
   229  	}
   230  
   231  	if !filter1.MatchMessage(msg) {
   232  		t.Fatalf("failed matching with the second filter")
   233  	}
   234  
   235  	if !filter2.MatchMessage(msg) {
   236  		t.Fatalf("failed matching with the second filter")
   237  	}
   238  }
   239  
   240  func TestComparePubKey(t *testing.T) {
   241  	InitSingleTest()
   242  
   243  	key1, err := crypto.GenerateKey()
   244  	if err != nil {
   245  		t.Fatalf("failed to generate first key with seed %d: %s.", seed, err)
   246  	}
   247  	key2, err := crypto.GenerateKey()
   248  	if err != nil {
   249  		t.Fatalf("failed to generate second key with seed %d: %s.", seed, err)
   250  	}
   251  	if IsPubKeyEqual(&key1.PublicKey, &key2.PublicKey) {
   252  		t.Fatalf("public keys are equal, seed %d.", seed)
   253  	}
   254  
   255  //
   256  	mrand.Seed(seed)
   257  	key3, err := crypto.GenerateKey()
   258  	if err != nil {
   259  		t.Fatalf("failed to generate third key with seed %d: %s.", seed, err)
   260  	}
   261  	if IsPubKeyEqual(&key1.PublicKey, &key3.PublicKey) {
   262  		t.Fatalf("key1 == key3, seed %d.", seed)
   263  	}
   264  }
   265  
   266  func TestMatchEnvelope(t *testing.T) {
   267  	InitSingleTest()
   268  
   269  	fsym, err := generateFilter(t, true)
   270  	if err != nil {
   271  		t.Fatalf("failed generateFilter with seed %d: %s.", seed, err)
   272  	}
   273  
   274  	fasym, err := generateFilter(t, false)
   275  	if err != nil {
   276  		t.Fatalf("failed generateFilter() with seed %d: %s.", seed, err)
   277  	}
   278  
   279  	params, err := generateMessageParams()
   280  	if err != nil {
   281  		t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
   282  	}
   283  
   284  params.Topic[0] = 0xFF //
   285  
   286  //
   287  	msg, err := NewSentMessage(params)
   288  	if err != nil {
   289  		t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
   290  	}
   291  	env, err := msg.Wrap(params)
   292  	if err != nil {
   293  		t.Fatalf("failed Wrap with seed %d: %s.", seed, err)
   294  	}
   295  	match := fsym.MatchEnvelope(env)
   296  	if match {
   297  		t.Fatalf("failed MatchEnvelope symmetric with seed %d.", seed)
   298  	}
   299  	match = fasym.MatchEnvelope(env)
   300  	if match {
   301  		t.Fatalf("failed MatchEnvelope asymmetric with seed %d.", seed)
   302  	}
   303  
   304  //
   305  	i := mrand.Int() % 4
   306  	fsym.Topics[i] = params.Topic[:]
   307  	fasym.Topics[i] = params.Topic[:]
   308  	msg, err = NewSentMessage(params)
   309  	if err != nil {
   310  		t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
   311  	}
   312  	env, err = msg.Wrap(params)
   313  	if err != nil {
   314  		t.Fatalf("failed Wrap() with seed %d: %s.", seed, err)
   315  	}
   316  
   317  //
   318  	match = fsym.MatchEnvelope(env)
   319  	if !match {
   320  		t.Fatalf("failed MatchEnvelope() symmetric with seed %d.", seed)
   321  	}
   322  
   323  //
   324  	match = fasym.MatchEnvelope(env)
   325  	if match {
   326  		t.Fatalf("failed MatchEnvelope() asymmetric with seed %d.", seed)
   327  	}
   328  
   329  //
   330  	fsym.PoW = env.PoW() + 1.0
   331  	match = fsym.MatchEnvelope(env)
   332  	if match {
   333  		t.Fatalf("failed MatchEnvelope(symmetric + matching topic + insufficient PoW) asymmetric with seed %d.", seed)
   334  	}
   335  
   336  //
   337  	fsym.PoW = env.PoW() / 2
   338  	match = fsym.MatchEnvelope(env)
   339  	if !match {
   340  		t.Fatalf("failed MatchEnvelope(symmetric + matching topic + sufficient PoW) with seed %d.", seed)
   341  	}
   342  
   343  //
   344  	prevTopics := fsym.Topics
   345  	fsym.Topics = nil
   346  	match = fsym.MatchEnvelope(env)
   347  	if !match {
   348  		t.Fatalf("failed MatchEnvelope(symmetric + topics are nil) with seed %d.", seed)
   349  	}
   350  	fsym.Topics = prevTopics
   351  
   352  //
   353  	key, err := crypto.GenerateKey()
   354  	if err != nil {
   355  		t.Fatalf("failed GenerateKey with seed %d: %s.", seed, err)
   356  	}
   357  	params.KeySym = nil
   358  	params.Dst = &key.PublicKey
   359  	msg, err = NewSentMessage(params)
   360  	if err != nil {
   361  		t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
   362  	}
   363  	env, err = msg.Wrap(params)
   364  	if err != nil {
   365  		t.Fatalf("failed Wrap() with seed %d: %s.", seed, err)
   366  	}
   367  
   368  //
   369  	match = fsym.MatchEnvelope(env)
   370  	if match {
   371  		t.Fatalf("failed MatchEnvelope(encryption method mismatch) with seed %d.", seed)
   372  	}
   373  
   374  //
   375  	match = fasym.MatchEnvelope(env)
   376  	if !match {
   377  		t.Fatalf("failed MatchEnvelope(asymmetric + mismatching topic) with seed %d.", seed)
   378  	}
   379  
   380  //
   381  	fasym.Topics[i] = fasym.Topics[i+1]
   382  	match = fasym.MatchEnvelope(env)
   383  	if match {
   384  		t.Fatalf("failed MatchEnvelope(asymmetric + matching topic) with seed %d.", seed)
   385  	}
   386  
   387  //
   388  	fasym.Topics = nil
   389  	match = fasym.MatchEnvelope(env)
   390  	if !match {
   391  		t.Fatalf("failed MatchEnvelope(asymmetric + filter without topic) with seed %d.", seed)
   392  	}
   393  
   394  //
   395  	fasym.PoW = env.PoW() + 1.0
   396  	match = fasym.MatchEnvelope(env)
   397  	if match {
   398  		t.Fatalf("failed MatchEnvelope(asymmetric + insufficient PoW) with seed %d.", seed)
   399  	}
   400  
   401  //
   402  	fasym.PoW = env.PoW() / 2
   403  	match = fasym.MatchEnvelope(env)
   404  	if !match {
   405  		t.Fatalf("failed MatchEnvelope(asymmetric + sufficient PoW) with seed %d.", seed)
   406  	}
   407  
   408  //
   409  	env.Topic = TopicType{}
   410  	match = fasym.MatchEnvelope(env)
   411  	if !match {
   412  		t.Fatalf("failed MatchEnvelope(filter without topic + envelope without topic) with seed %d.", seed)
   413  	}
   414  
   415  //
   416  	fasym.Topics = fsym.Topics
   417  	match = fasym.MatchEnvelope(env)
   418  	if match {
   419  		t.Fatalf("failed MatchEnvelope(filter without topic + envelope without topic) with seed %d.", seed)
   420  	}
   421  }
   422  
   423  func TestMatchMessageSym(t *testing.T) {
   424  	InitSingleTest()
   425  
   426  	params, err := generateMessageParams()
   427  	if err != nil {
   428  		t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
   429  	}
   430  
   431  	f, err := generateFilter(t, true)
   432  	if err != nil {
   433  		t.Fatalf("failed generateFilter with seed %d: %s.", seed, err)
   434  	}
   435  
   436  	const index = 1
   437  	params.KeySym = f.KeySym
   438  	params.Topic = BytesToTopic(f.Topics[index])
   439  
   440  	sentMessage, err := NewSentMessage(params)
   441  	if err != nil {
   442  		t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
   443  	}
   444  	env, err := sentMessage.Wrap(params)
   445  	if err != nil {
   446  		t.Fatalf("failed Wrap with seed %d: %s.", seed, err)
   447  	}
   448  	msg := env.Open(f)
   449  	if msg == nil {
   450  		t.Fatalf("failed Open with seed %d.", seed)
   451  	}
   452  
   453  //
   454  	*f.Src.X = *params.Src.PublicKey.X
   455  	*f.Src.Y = *params.Src.PublicKey.Y
   456  	if !f.MatchMessage(msg) {
   457  		t.Fatalf("failed MatchEnvelope(src match) with seed %d.", seed)
   458  	}
   459  
   460  //
   461  	f.PoW = msg.PoW + 1.0
   462  	if f.MatchMessage(msg) {
   463  		t.Fatalf("failed MatchEnvelope(insufficient PoW) with seed %d.", seed)
   464  	}
   465  
   466  //
   467  	f.PoW = msg.PoW / 2
   468  	if !f.MatchMessage(msg) {
   469  		t.Fatalf("failed MatchEnvelope(sufficient PoW) with seed %d.", seed)
   470  	}
   471  
   472  //
   473  	f.Topics[index][0]++
   474  	if f.MatchMessage(msg) {
   475  		t.Fatalf("failed MatchEnvelope(topic mismatch) with seed %d.", seed)
   476  	}
   477  	f.Topics[index][0]--
   478  
   479  //
   480  	f.SymKeyHash[0]++
   481  	if f.MatchMessage(msg) {
   482  		t.Fatalf("failed MatchEnvelope(key mismatch) with seed %d.", seed)
   483  	}
   484  	f.SymKeyHash[0]--
   485  
   486  //
   487  	f.Src = nil
   488  	if !f.MatchMessage(msg) {
   489  		t.Fatalf("failed MatchEnvelope(src absent) with seed %d.", seed)
   490  	}
   491  
   492  //
   493  	h := f.SymKeyHash
   494  	f.SymKeyHash = common.Hash{}
   495  	if f.MatchMessage(msg) {
   496  		t.Fatalf("failed MatchEnvelope(key hash mismatch) with seed %d.", seed)
   497  	}
   498  	f.SymKeyHash = h
   499  	if !f.MatchMessage(msg) {
   500  		t.Fatalf("failed MatchEnvelope(key hash match) with seed %d.", seed)
   501  	}
   502  
   503  //
   504  	f.KeySym = nil
   505  	f.KeyAsym, err = crypto.GenerateKey()
   506  	if err != nil {
   507  		t.Fatalf("failed GenerateKey with seed %d: %s.", seed, err)
   508  	}
   509  	if f.MatchMessage(msg) {
   510  		t.Fatalf("failed MatchEnvelope(encryption method mismatch) with seed %d.", seed)
   511  	}
   512  }
   513  
   514  func TestMatchMessageAsym(t *testing.T) {
   515  	InitSingleTest()
   516  
   517  	f, err := generateFilter(t, false)
   518  	if err != nil {
   519  		t.Fatalf("failed generateFilter with seed %d: %s.", seed, err)
   520  	}
   521  
   522  	params, err := generateMessageParams()
   523  	if err != nil {
   524  		t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
   525  	}
   526  
   527  	const index = 1
   528  	params.Topic = BytesToTopic(f.Topics[index])
   529  	params.Dst = &f.KeyAsym.PublicKey
   530  	keySymOrig := params.KeySym
   531  	params.KeySym = nil
   532  
   533  	sentMessage, err := NewSentMessage(params)
   534  	if err != nil {
   535  		t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
   536  	}
   537  	env, err := sentMessage.Wrap(params)
   538  	if err != nil {
   539  		t.Fatalf("failed Wrap with seed %d: %s.", seed, err)
   540  	}
   541  	msg := env.Open(f)
   542  	if msg == nil {
   543  		t.Fatalf("failed to open with seed %d.", seed)
   544  	}
   545  
   546  //
   547  	*f.Src.X = *params.Src.PublicKey.X
   548  	*f.Src.Y = *params.Src.PublicKey.Y
   549  	if !f.MatchMessage(msg) {
   550  		t.Fatalf("failed MatchMessage(src match) with seed %d.", seed)
   551  	}
   552  
   553  //
   554  	f.PoW = msg.PoW + 1.0
   555  	if f.MatchMessage(msg) {
   556  		t.Fatalf("failed MatchEnvelope(insufficient PoW) with seed %d.", seed)
   557  	}
   558  
   559  //
   560  	f.PoW = msg.PoW / 2
   561  	if !f.MatchMessage(msg) {
   562  		t.Fatalf("failed MatchEnvelope(sufficient PoW) with seed %d.", seed)
   563  	}
   564  
   565  //
   566  	f.Topics[index][0]++
   567  	if f.MatchMessage(msg) {
   568  		t.Fatalf("failed MatchEnvelope(topic mismatch) with seed %d.", seed)
   569  	}
   570  	f.Topics[index][0]--
   571  
   572  //
   573  	prev := *f.KeyAsym.PublicKey.X
   574  	zero := *big.NewInt(0)
   575  	*f.KeyAsym.PublicKey.X = zero
   576  	if f.MatchMessage(msg) {
   577  		t.Fatalf("failed MatchEnvelope(key mismatch) with seed %d.", seed)
   578  	}
   579  	*f.KeyAsym.PublicKey.X = prev
   580  
   581  //
   582  	f.Src = nil
   583  	if !f.MatchMessage(msg) {
   584  		t.Fatalf("failed MatchEnvelope(src absent) with seed %d.", seed)
   585  	}
   586  
   587  //
   588  	f.KeySym = keySymOrig
   589  	f.KeyAsym = nil
   590  	if f.MatchMessage(msg) {
   591  		t.Fatalf("failed MatchEnvelope(encryption method mismatch) with seed %d.", seed)
   592  	}
   593  }
   594  
   595  func cloneFilter(orig *Filter) *Filter {
   596  	var clone Filter
   597  	clone.Messages = make(map[common.Hash]*ReceivedMessage)
   598  	clone.Src = orig.Src
   599  	clone.KeyAsym = orig.KeyAsym
   600  	clone.KeySym = orig.KeySym
   601  	clone.Topics = orig.Topics
   602  	clone.PoW = orig.PoW
   603  	clone.AllowP2P = orig.AllowP2P
   604  	clone.SymKeyHash = orig.SymKeyHash
   605  	return &clone
   606  }
   607  
   608  func generateCompatibeEnvelope(t *testing.T, f *Filter) *Envelope {
   609  	params, err := generateMessageParams()
   610  	if err != nil {
   611  		t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
   612  		return nil
   613  	}
   614  
   615  	params.KeySym = f.KeySym
   616  	params.Topic = BytesToTopic(f.Topics[2])
   617  	sentMessage, err := NewSentMessage(params)
   618  	if err != nil {
   619  		t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
   620  	}
   621  	env, err := sentMessage.Wrap(params)
   622  	if err != nil {
   623  		t.Fatalf("failed Wrap with seed %d: %s.", seed, err)
   624  		return nil
   625  	}
   626  	return env
   627  }
   628  
   629  func TestWatchers(t *testing.T) {
   630  	InitSingleTest()
   631  
   632  	const NumFilters = 16
   633  	const NumMessages = 256
   634  	var i int
   635  	var j uint32
   636  	var e *Envelope
   637  	var x, firstID string
   638  	var err error
   639  
   640  	w := New(&Config{})
   641  	filters := NewFilters(w)
   642  	tst := generateTestCases(t, NumFilters)
   643  	for i = 0; i < NumFilters; i++ {
   644  		tst[i].f.Src = nil
   645  		x, err = filters.Install(tst[i].f)
   646  		if err != nil {
   647  			t.Fatalf("failed to install filter with seed %d: %s.", seed, err)
   648  		}
   649  		tst[i].id = x
   650  		if len(firstID) == 0 {
   651  			firstID = x
   652  		}
   653  	}
   654  
   655  	lastID := x
   656  
   657  	var envelopes [NumMessages]*Envelope
   658  	for i = 0; i < NumMessages; i++ {
   659  		j = mrand.Uint32() % NumFilters
   660  		e = generateCompatibeEnvelope(t, tst[j].f)
   661  		envelopes[i] = e
   662  		tst[j].msgCnt++
   663  	}
   664  
   665  	for i = 0; i < NumMessages; i++ {
   666  		filters.NotifyWatchers(envelopes[i], false)
   667  	}
   668  
   669  	var total int
   670  	var mail []*ReceivedMessage
   671  	var count [NumFilters]int
   672  
   673  	for i = 0; i < NumFilters; i++ {
   674  		mail = tst[i].f.Retrieve()
   675  		count[i] = len(mail)
   676  		total += len(mail)
   677  	}
   678  
   679  	if total != NumMessages {
   680  		t.Fatalf("failed with seed %d: total = %d, want: %d.", seed, total, NumMessages)
   681  	}
   682  
   683  	for i = 0; i < NumFilters; i++ {
   684  		mail = tst[i].f.Retrieve()
   685  		if len(mail) != 0 {
   686  			t.Fatalf("failed with seed %d: i = %d.", seed, i)
   687  		}
   688  
   689  		if tst[i].msgCnt != count[i] {
   690  			t.Fatalf("failed with seed %d: count[%d]: get %d, want %d.", seed, i, tst[i].msgCnt, count[i])
   691  		}
   692  	}
   693  
   694  //
   695  
   696  	clone := cloneFilter(tst[0].f)
   697  	filters.Uninstall(lastID)
   698  	total = 0
   699  	last := NumFilters - 1
   700  	tst[last].f = clone
   701  	filters.Install(clone)
   702  	for i = 0; i < NumFilters; i++ {
   703  		tst[i].msgCnt = 0
   704  		count[i] = 0
   705  	}
   706  
   707  //
   708  	e = generateCompatibeEnvelope(t, tst[0].f)
   709  	envelopes[0] = e
   710  	tst[0].msgCnt++
   711  	for i = 1; i < NumMessages; i++ {
   712  		j = mrand.Uint32() % NumFilters
   713  		e = generateCompatibeEnvelope(t, tst[j].f)
   714  		envelopes[i] = e
   715  		tst[j].msgCnt++
   716  	}
   717  
   718  	for i = 0; i < NumMessages; i++ {
   719  		filters.NotifyWatchers(envelopes[i], false)
   720  	}
   721  
   722  	for i = 0; i < NumFilters; i++ {
   723  		mail = tst[i].f.Retrieve()
   724  		count[i] = len(mail)
   725  		total += len(mail)
   726  	}
   727  
   728  	combined := tst[0].msgCnt + tst[last].msgCnt
   729  	if total != NumMessages+count[0] {
   730  		t.Fatalf("failed with seed %d: total = %d, count[0] = %d.", seed, total, count[0])
   731  	}
   732  
   733  	if combined != count[0] {
   734  		t.Fatalf("failed with seed %d: combined = %d, count[0] = %d.", seed, combined, count[0])
   735  	}
   736  
   737  	if combined != count[last] {
   738  		t.Fatalf("failed with seed %d: combined = %d, count[last] = %d.", seed, combined, count[last])
   739  	}
   740  
   741  	for i = 1; i < NumFilters-1; i++ {
   742  		mail = tst[i].f.Retrieve()
   743  		if len(mail) != 0 {
   744  			t.Fatalf("failed with seed %d: i = %d.", seed, i)
   745  		}
   746  
   747  		if tst[i].msgCnt != count[i] {
   748  			t.Fatalf("failed with seed %d: i = %d, get %d, want %d.", seed, i, tst[i].msgCnt, count[i])
   749  		}
   750  	}
   751  
   752  //
   753  
   754  	total = 0
   755  	filters.NotifyWatchers(envelopes[0], true)
   756  
   757  	for i = 0; i < NumFilters; i++ {
   758  		mail = tst[i].f.Retrieve()
   759  		total += len(mail)
   760  	}
   761  
   762  	if total != 0 {
   763  		t.Fatalf("failed with seed %d: total: got %d, want 0.", seed, total)
   764  	}
   765  
   766  	f := filters.Get(firstID)
   767  	if f == nil {
   768  		t.Fatalf("failed to get the filter with seed %d.", seed)
   769  	}
   770  	f.AllowP2P = true
   771  	total = 0
   772  	filters.NotifyWatchers(envelopes[0], true)
   773  
   774  	for i = 0; i < NumFilters; i++ {
   775  		mail = tst[i].f.Retrieve()
   776  		total += len(mail)
   777  	}
   778  
   779  	if total != 1 {
   780  		t.Fatalf("failed with seed %d: total: got %d, want 1.", seed, total)
   781  	}
   782  }
   783  
   784  func TestVariableTopics(t *testing.T) {
   785  	InitSingleTest()
   786  
   787  	const lastTopicByte = 3
   788  	var match bool
   789  	params, err := generateMessageParams()
   790  	if err != nil {
   791  		t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
   792  	}
   793  	msg, err := NewSentMessage(params)
   794  	if err != nil {
   795  		t.Fatalf("failed to create new message with seed %d: %s.", seed, err)
   796  	}
   797  	env, err := msg.Wrap(params)
   798  	if err != nil {
   799  		t.Fatalf("failed Wrap with seed %d: %s.", seed, err)
   800  	}
   801  
   802  	f, err := generateFilter(t, true)
   803  	if err != nil {
   804  		t.Fatalf("failed generateFilter with seed %d: %s.", seed, err)
   805  	}
   806  
   807  	for i := 0; i < 4; i++ {
   808  		env.Topic = BytesToTopic(f.Topics[i])
   809  		match = f.MatchEnvelope(env)
   810  		if !match {
   811  			t.Fatalf("failed MatchEnvelope symmetric with seed %d, step %d.", seed, i)
   812  		}
   813  
   814  		f.Topics[i][lastTopicByte]++
   815  		match = f.MatchEnvelope(env)
   816  		if match {
   817  			t.Fatalf("MatchEnvelope symmetric with seed %d, step %d: false positive.", seed, i)
   818  		}
   819  	}
   820  }
   821  
   822  func TestMatchSingleTopic_ReturnTrue(t *testing.T) {
   823  	bt := []byte("test")
   824  	topic := BytesToTopic(bt)
   825  
   826  	if !matchSingleTopic(topic, bt) {
   827  		t.FailNow()
   828  	}
   829  }
   830  
   831  func TestMatchSingleTopic_WithTail_ReturnTrue(t *testing.T) {
   832  	bt := []byte("test with tail")
   833  	topic := BytesToTopic([]byte("test"))
   834  
   835  	if !matchSingleTopic(topic, bt) {
   836  		t.FailNow()
   837  	}
   838  }
   839  
   840  func TestMatchSingleTopic_PartialTopic_ReturnTrue(t *testing.T) {
   841  	bt := []byte("tes")
   842  	topic := BytesToTopic([]byte("test"))
   843  
   844  	if !matchSingleTopic(topic, bt) {
   845  		t.FailNow()
   846  	}
   847  }
   848  
   849  func TestMatchSingleTopic_NotEquals_ReturnFalse(t *testing.T) {
   850  	bt := []byte("test")
   851  	topic := BytesToTopic([]byte("not_equal"))
   852  
   853  	if matchSingleTopic(topic, bt) {
   854  		t.FailNow()
   855  	}
   856  }