github.com/digdeepmining/go-atheios@v1.5.13-0.20180902133602-d5687a2e6f43/whisper/whisperv5/filter_test.go (about)

     1  // Copyright 2016 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-ethereum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package whisperv5
    18  
    19  import (
    20  	"math/big"
    21  	"math/rand"
    22  	"testing"
    23  	"time"
    24  
    25  	"github.com/atheioschain/go-atheios/common"
    26  	"github.com/atheioschain/go-atheios/crypto"
    27  )
    28  
    29  var seed int64
    30  
    31  // InitSingleTest should be called in the beginning of every
    32  // test, which uses RNG, in order to make the tests
    33  // reproduciblity independent of their sequence.
    34  func InitSingleTest() {
    35  	seed = time.Now().Unix()
    36  	rand.Seed(seed)
    37  }
    38  
    39  func InitDebugTest(i int64) {
    40  	seed = i
    41  	rand.Seed(seed)
    42  }
    43  
    44  type FilterTestCase struct {
    45  	f      *Filter
    46  	id     uint32
    47  	alive  bool
    48  	msgCnt int
    49  }
    50  
    51  func generateFilter(t *testing.T, symmetric bool) (*Filter, error) {
    52  	var f Filter
    53  	f.Messages = make(map[common.Hash]*ReceivedMessage)
    54  
    55  	const topicNum = 8
    56  	f.Topics = make([]TopicType, topicNum)
    57  	for i := 0; i < topicNum; i++ {
    58  		randomize(f.Topics[i][:])
    59  		f.Topics[i][0] = 0x01
    60  	}
    61  
    62  	key, err := crypto.GenerateKey()
    63  	if err != nil {
    64  		t.Fatalf("generateFilter 1 failed with seed %d.", seed)
    65  		return nil, err
    66  	}
    67  	f.Src = &key.PublicKey
    68  
    69  	if symmetric {
    70  		f.KeySym = make([]byte, 12)
    71  		randomize(f.KeySym)
    72  		f.SymKeyHash = crypto.Keccak256Hash(f.KeySym)
    73  	} else {
    74  		f.KeyAsym, err = crypto.GenerateKey()
    75  		if err != nil {
    76  			t.Fatalf("generateFilter 2 failed with seed %d.", seed)
    77  			return nil, err
    78  		}
    79  	}
    80  
    81  	// AcceptP2P & PoW are not set
    82  	return &f, nil
    83  }
    84  
    85  func generateTestCases(t *testing.T, SizeTestFilters int) []FilterTestCase {
    86  	cases := make([]FilterTestCase, SizeTestFilters)
    87  	for i := 0; i < SizeTestFilters; i++ {
    88  		f, _ := generateFilter(t, true)
    89  		cases[i].f = f
    90  		cases[i].alive = (rand.Int()&int(1) == 0)
    91  	}
    92  	return cases
    93  }
    94  
    95  func TestInstallFilters(t *testing.T) {
    96  	InitSingleTest()
    97  
    98  	const SizeTestFilters = 256
    99  	w := NewWhisper(nil)
   100  	filters := NewFilters(w)
   101  	tst := generateTestCases(t, SizeTestFilters)
   102  
   103  	var j uint32
   104  	for i := 0; i < SizeTestFilters; i++ {
   105  		j = filters.Install(tst[i].f)
   106  		tst[i].id = j
   107  	}
   108  
   109  	if j < SizeTestFilters-1 {
   110  		t.Fatalf("seed %d: wrong index %d", seed, j)
   111  	}
   112  
   113  	for _, testCase := range tst {
   114  		if !testCase.alive {
   115  			filters.Uninstall(testCase.id)
   116  		}
   117  	}
   118  
   119  	for i, testCase := range tst {
   120  		fil := filters.Get(testCase.id)
   121  		exist := (fil != nil)
   122  		if exist != testCase.alive {
   123  			t.Fatalf("seed %d: failed alive: %d, %v, %v", seed, i, exist, testCase.alive)
   124  		}
   125  		if exist && fil.PoW != testCase.f.PoW {
   126  			t.Fatalf("seed %d: failed Get: %d, %v, %v", seed, i, exist, testCase.alive)
   127  		}
   128  	}
   129  }
   130  
   131  func TestComparePubKey(t *testing.T) {
   132  	InitSingleTest()
   133  
   134  	key1, err := crypto.GenerateKey()
   135  	if err != nil {
   136  		t.Fatalf("failed to generate first key with seed %d: %s.", seed, err)
   137  	}
   138  	key2, err := crypto.GenerateKey()
   139  	if err != nil {
   140  		t.Fatalf("failed to generate second key with seed %d: %s.", seed, err)
   141  	}
   142  	if IsPubKeyEqual(&key1.PublicKey, &key2.PublicKey) {
   143  		t.Fatalf("public keys are equal, seed %d.", seed)
   144  	}
   145  
   146  	// generate key3 == key1
   147  	rand.Seed(seed)
   148  	key3, err := crypto.GenerateKey()
   149  	if err != nil {
   150  		t.Fatalf("failed to generate third key with seed %d: %s.", seed, err)
   151  	}
   152  	if IsPubKeyEqual(&key1.PublicKey, &key3.PublicKey) {
   153  		t.Fatalf("key1 == key3, seed %d.", seed)
   154  	}
   155  }
   156  
   157  func TestMatchEnvelope(t *testing.T) {
   158  	InitSingleTest()
   159  
   160  	fsym, err := generateFilter(t, true)
   161  	if err != nil {
   162  		t.Fatalf("failed generateFilter with seed %d: %s.", seed, err)
   163  	}
   164  
   165  	fasym, err := generateFilter(t, false)
   166  	if err != nil {
   167  		t.Fatalf("failed generateFilter() with seed %d: %s.", seed, err)
   168  	}
   169  
   170  	params, err := generateMessageParams()
   171  	if err != nil {
   172  		t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
   173  	}
   174  
   175  	params.Topic[0] = 0xFF // ensure mismatch
   176  
   177  	// mismatch with pseudo-random data
   178  	msg := NewSentMessage(params)
   179  	env, err := msg.Wrap(params)
   180  	if err != nil {
   181  		t.Fatalf("failed Wrap with seed %d: %s.", seed, err)
   182  	}
   183  	match := fsym.MatchEnvelope(env)
   184  	if match {
   185  		t.Fatalf("failed MatchEnvelope symmetric with seed %d.", seed)
   186  	}
   187  	match = fasym.MatchEnvelope(env)
   188  	if match {
   189  		t.Fatalf("failed MatchEnvelope asymmetric with seed %d.", seed)
   190  	}
   191  
   192  	// encrypt symmetrically
   193  	i := rand.Int() % 4
   194  	fsym.Topics[i] = params.Topic
   195  	fasym.Topics[i] = params.Topic
   196  	msg = NewSentMessage(params)
   197  	env, err = msg.Wrap(params)
   198  	if err != nil {
   199  		t.Fatalf("failed Wrap() with seed %d: %s.", seed, err)
   200  	}
   201  
   202  	// symmetric + matching topic: match
   203  	match = fsym.MatchEnvelope(env)
   204  	if !match {
   205  		t.Fatalf("failed MatchEnvelope() symmetric with seed %d.", seed)
   206  	}
   207  
   208  	// asymmetric + matching topic: mismatch
   209  	match = fasym.MatchEnvelope(env)
   210  	if match {
   211  		t.Fatalf("failed MatchEnvelope() asymmetric with seed %d.", seed)
   212  	}
   213  
   214  	// symmetric + matching topic + insufficient PoW: mismatch
   215  	fsym.PoW = env.PoW() + 1.0
   216  	match = fsym.MatchEnvelope(env)
   217  	if match {
   218  		t.Fatalf("failed MatchEnvelope(symmetric + matching topic + insufficient PoW) asymmetric with seed %d.", seed)
   219  	}
   220  
   221  	// symmetric + matching topic + sufficient PoW: match
   222  	fsym.PoW = env.PoW() / 2
   223  	match = fsym.MatchEnvelope(env)
   224  	if !match {
   225  		t.Fatalf("failed MatchEnvelope(symmetric + matching topic + sufficient PoW) with seed %d.", seed)
   226  	}
   227  
   228  	// symmetric + topics are nil (wildcard): match
   229  	prevTopics := fsym.Topics
   230  	fsym.Topics = nil
   231  	match = fsym.MatchEnvelope(env)
   232  	if !match {
   233  		t.Fatalf("failed MatchEnvelope(symmetric + topics are nil) with seed %d.", seed)
   234  	}
   235  	fsym.Topics = prevTopics
   236  
   237  	// encrypt asymmetrically
   238  	key, err := crypto.GenerateKey()
   239  	if err != nil {
   240  		t.Fatalf("failed GenerateKey with seed %d: %s.", seed, err)
   241  	}
   242  	params.KeySym = nil
   243  	params.Dst = &key.PublicKey
   244  	msg = NewSentMessage(params)
   245  	env, err = msg.Wrap(params)
   246  	if err != nil {
   247  		t.Fatalf("failed Wrap() with seed %d: %s.", seed, err)
   248  	}
   249  
   250  	// encryption method mismatch
   251  	match = fsym.MatchEnvelope(env)
   252  	if match {
   253  		t.Fatalf("failed MatchEnvelope(encryption method mismatch) with seed %d.", seed)
   254  	}
   255  
   256  	// asymmetric + mismatching topic: mismatch
   257  	match = fasym.MatchEnvelope(env)
   258  	if !match {
   259  		t.Fatalf("failed MatchEnvelope(asymmetric + mismatching topic) with seed %d.", seed)
   260  	}
   261  
   262  	// asymmetric + matching topic: match
   263  	fasym.Topics[i] = fasym.Topics[i+1]
   264  	match = fasym.MatchEnvelope(env)
   265  	if match {
   266  		t.Fatalf("failed MatchEnvelope(asymmetric + matching topic) with seed %d.", seed)
   267  	}
   268  
   269  	// asymmetric + filter without topic (wildcard): match
   270  	fasym.Topics = nil
   271  	match = fasym.MatchEnvelope(env)
   272  	if !match {
   273  		t.Fatalf("failed MatchEnvelope(asymmetric + filter without topic) with seed %d.", seed)
   274  	}
   275  
   276  	// asymmetric + insufficient PoW: mismatch
   277  	fasym.PoW = env.PoW() + 1.0
   278  	match = fasym.MatchEnvelope(env)
   279  	if match {
   280  		t.Fatalf("failed MatchEnvelope(asymmetric + insufficient PoW) with seed %d.", seed)
   281  	}
   282  
   283  	// asymmetric + sufficient PoW: match
   284  	fasym.PoW = env.PoW() / 2
   285  	match = fasym.MatchEnvelope(env)
   286  	if !match {
   287  		t.Fatalf("failed MatchEnvelope(asymmetric + sufficient PoW) with seed %d.", seed)
   288  	}
   289  
   290  	// filter without topic + envelope without topic: match
   291  	env.Topic = TopicType{}
   292  	match = fasym.MatchEnvelope(env)
   293  	if !match {
   294  		t.Fatalf("failed MatchEnvelope(filter without topic + envelope without topic) with seed %d.", seed)
   295  	}
   296  
   297  	// filter with topic + envelope without topic: mismatch
   298  	fasym.Topics = fsym.Topics
   299  	match = fasym.MatchEnvelope(env)
   300  	if match {
   301  		t.Fatalf("failed MatchEnvelope(filter without topic + envelope without topic) with seed %d.", seed)
   302  	}
   303  }
   304  
   305  func TestMatchMessageSym(t *testing.T) {
   306  	InitSingleTest()
   307  
   308  	params, err := generateMessageParams()
   309  	if err != nil {
   310  		t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
   311  	}
   312  
   313  	f, err := generateFilter(t, true)
   314  	if err != nil {
   315  		t.Fatalf("failed generateFilter with seed %d: %s.", seed, err)
   316  	}
   317  
   318  	const index = 1
   319  	params.KeySym = f.KeySym
   320  	params.Topic = f.Topics[index]
   321  
   322  	sentMessage := NewSentMessage(params)
   323  	env, err := sentMessage.Wrap(params)
   324  	if err != nil {
   325  		t.Fatalf("failed Wrap with seed %d: %s.", seed, err)
   326  	}
   327  
   328  	msg := env.Open(f)
   329  	if msg == nil {
   330  		t.Fatalf("failed Open with seed %d.", seed)
   331  	}
   332  
   333  	// Src mismatch
   334  	if f.MatchMessage(msg) {
   335  		t.Fatalf("failed MatchMessage(src mismatch) with seed %d.", seed)
   336  	}
   337  
   338  	// Src: match
   339  	*f.Src.X = *params.Src.PublicKey.X
   340  	*f.Src.Y = *params.Src.PublicKey.Y
   341  	if !f.MatchMessage(msg) {
   342  		t.Fatalf("failed MatchEnvelope(src match) with seed %d.", seed)
   343  	}
   344  
   345  	// insufficient PoW: mismatch
   346  	f.PoW = msg.PoW + 1.0
   347  	if f.MatchMessage(msg) {
   348  		t.Fatalf("failed MatchEnvelope(insufficient PoW) with seed %d.", seed)
   349  	}
   350  
   351  	// sufficient PoW: match
   352  	f.PoW = msg.PoW / 2
   353  	if !f.MatchMessage(msg) {
   354  		t.Fatalf("failed MatchEnvelope(sufficient PoW) with seed %d.", seed)
   355  	}
   356  
   357  	// topic mismatch
   358  	f.Topics[index][0]++
   359  	if f.MatchMessage(msg) {
   360  		t.Fatalf("failed MatchEnvelope(topic mismatch) with seed %d.", seed)
   361  	}
   362  	f.Topics[index][0]--
   363  
   364  	// key mismatch
   365  	f.SymKeyHash[0]++
   366  	if f.MatchMessage(msg) {
   367  		t.Fatalf("failed MatchEnvelope(key mismatch) with seed %d.", seed)
   368  	}
   369  	f.SymKeyHash[0]--
   370  
   371  	// Src absent: match
   372  	f.Src = nil
   373  	if !f.MatchMessage(msg) {
   374  		t.Fatalf("failed MatchEnvelope(src absent) with seed %d.", seed)
   375  	}
   376  
   377  	// key hash mismatch
   378  	h := f.SymKeyHash
   379  	f.SymKeyHash = common.Hash{}
   380  	if f.MatchMessage(msg) {
   381  		t.Fatalf("failed MatchEnvelope(key hash mismatch) with seed %d.", seed)
   382  	}
   383  	f.SymKeyHash = h
   384  	if !f.MatchMessage(msg) {
   385  		t.Fatalf("failed MatchEnvelope(key hash match) with seed %d.", seed)
   386  	}
   387  
   388  	// encryption method mismatch
   389  	f.KeySym = nil
   390  	f.KeyAsym, err = crypto.GenerateKey()
   391  	if err != nil {
   392  		t.Fatalf("failed GenerateKey with seed %d: %s.", seed, err)
   393  	}
   394  	if f.MatchMessage(msg) {
   395  		t.Fatalf("failed MatchEnvelope(encryption method mismatch) with seed %d.", seed)
   396  	}
   397  }
   398  
   399  func TestMatchMessageAsym(t *testing.T) {
   400  	InitSingleTest()
   401  
   402  	f, err := generateFilter(t, false)
   403  	if err != nil {
   404  		t.Fatalf("failed generateFilter with seed %d: %s.", seed, err)
   405  	}
   406  
   407  	params, err := generateMessageParams()
   408  	if err != nil {
   409  		t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
   410  	}
   411  
   412  	const index = 1
   413  	params.Topic = f.Topics[index]
   414  	params.Dst = &f.KeyAsym.PublicKey
   415  	keySymOrig := params.KeySym
   416  	params.KeySym = nil
   417  
   418  	sentMessage := NewSentMessage(params)
   419  	env, err := sentMessage.Wrap(params)
   420  	if err != nil {
   421  		t.Fatalf("failed Wrap with seed %d: %s.", seed, err)
   422  	}
   423  
   424  	msg := env.Open(f)
   425  	if msg == nil {
   426  		t.Fatalf("failed to open with seed %d.", seed)
   427  	}
   428  
   429  	// Src mismatch
   430  	if f.MatchMessage(msg) {
   431  		t.Fatalf("failed MatchMessage(src mismatch) with seed %d.", seed)
   432  	}
   433  
   434  	// Src: match
   435  	*f.Src.X = *params.Src.PublicKey.X
   436  	*f.Src.Y = *params.Src.PublicKey.Y
   437  	if !f.MatchMessage(msg) {
   438  		t.Fatalf("failed MatchMessage(src match) with seed %d.", seed)
   439  	}
   440  
   441  	// insufficient PoW: mismatch
   442  	f.PoW = msg.PoW + 1.0
   443  	if f.MatchMessage(msg) {
   444  		t.Fatalf("failed MatchEnvelope(insufficient PoW) with seed %d.", seed)
   445  	}
   446  
   447  	// sufficient PoW: match
   448  	f.PoW = msg.PoW / 2
   449  	if !f.MatchMessage(msg) {
   450  		t.Fatalf("failed MatchEnvelope(sufficient PoW) with seed %d.", seed)
   451  	}
   452  
   453  	// topic mismatch
   454  	f.Topics[index][0]++
   455  	if f.MatchMessage(msg) {
   456  		t.Fatalf("failed MatchEnvelope(topic mismatch) with seed %d.", seed)
   457  	}
   458  	f.Topics[index][0]--
   459  
   460  	// key mismatch
   461  	prev := *f.KeyAsym.PublicKey.X
   462  	zero := *big.NewInt(0)
   463  	*f.KeyAsym.PublicKey.X = zero
   464  	if f.MatchMessage(msg) {
   465  		t.Fatalf("failed MatchEnvelope(key mismatch) with seed %d.", seed)
   466  	}
   467  	*f.KeyAsym.PublicKey.X = prev
   468  
   469  	// Src absent: match
   470  	f.Src = nil
   471  	if !f.MatchMessage(msg) {
   472  		t.Fatalf("failed MatchEnvelope(src absent) with seed %d.", seed)
   473  	}
   474  
   475  	// encryption method mismatch
   476  	f.KeySym = keySymOrig
   477  	f.KeyAsym = nil
   478  	if f.MatchMessage(msg) {
   479  		t.Fatalf("failed MatchEnvelope(encryption method mismatch) with seed %d.", seed)
   480  	}
   481  }
   482  
   483  func cloneFilter(orig *Filter) *Filter {
   484  	var clone Filter
   485  	clone.Messages = make(map[common.Hash]*ReceivedMessage)
   486  	clone.Src = orig.Src
   487  	clone.KeyAsym = orig.KeyAsym
   488  	clone.KeySym = orig.KeySym
   489  	clone.Topics = orig.Topics
   490  	clone.PoW = orig.PoW
   491  	clone.AcceptP2P = orig.AcceptP2P
   492  	clone.SymKeyHash = orig.SymKeyHash
   493  	return &clone
   494  }
   495  
   496  func generateCompatibeEnvelope(t *testing.T, f *Filter) *Envelope {
   497  	params, err := generateMessageParams()
   498  	if err != nil {
   499  		t.Fatalf("failed generateMessageParams with seed %d: %s.", seed, err)
   500  		return nil
   501  	}
   502  
   503  	params.KeySym = f.KeySym
   504  	params.Topic = f.Topics[2]
   505  	sentMessage := NewSentMessage(params)
   506  	env, err := sentMessage.Wrap(params)
   507  	if err != nil {
   508  		t.Fatalf("failed Wrap with seed %d: %s.", seed, err)
   509  		return nil
   510  	}
   511  	return env
   512  }
   513  
   514  func TestWatchers(t *testing.T) {
   515  	InitSingleTest()
   516  
   517  	const NumFilters = 16
   518  	const NumMessages = 256
   519  	var i int
   520  	var j uint32
   521  	var e *Envelope
   522  
   523  	w := NewWhisper(nil)
   524  	filters := NewFilters(w)
   525  	tst := generateTestCases(t, NumFilters)
   526  	for i = 0; i < NumFilters; i++ {
   527  		tst[i].f.Src = nil
   528  		j = filters.Install(tst[i].f)
   529  		tst[i].id = j
   530  	}
   531  
   532  	last := j
   533  
   534  	var envelopes [NumMessages]*Envelope
   535  	for i = 0; i < NumMessages; i++ {
   536  		j = rand.Uint32() % NumFilters
   537  		e = generateCompatibeEnvelope(t, tst[j].f)
   538  		envelopes[i] = e
   539  		tst[j].msgCnt++
   540  	}
   541  
   542  	for i = 0; i < NumMessages; i++ {
   543  		filters.NotifyWatchers(envelopes[i], false)
   544  	}
   545  
   546  	var total int
   547  	var mail []*ReceivedMessage
   548  	var count [NumFilters]int
   549  
   550  	for i = 0; i < NumFilters; i++ {
   551  		mail = tst[i].f.Retrieve()
   552  		count[i] = len(mail)
   553  		total += len(mail)
   554  	}
   555  
   556  	if total != NumMessages {
   557  		t.Fatalf("failed with seed %d: total = %d, want: %d.", seed, total, NumMessages)
   558  	}
   559  
   560  	for i = 0; i < NumFilters; i++ {
   561  		mail = tst[i].f.Retrieve()
   562  		if len(mail) != 0 {
   563  			t.Fatalf("failed with seed %d: i = %d.", seed, i)
   564  		}
   565  
   566  		if tst[i].msgCnt != count[i] {
   567  			t.Fatalf("failed with seed %d: count[%d]: get %d, want %d.", seed, i, tst[i].msgCnt, count[i])
   568  		}
   569  	}
   570  
   571  	// another round with a cloned filter
   572  
   573  	clone := cloneFilter(tst[0].f)
   574  	filters.Uninstall(last)
   575  	total = 0
   576  	last = NumFilters - 1
   577  	tst[last].f = clone
   578  	filters.Install(clone)
   579  	for i = 0; i < NumFilters; i++ {
   580  		tst[i].msgCnt = 0
   581  		count[i] = 0
   582  	}
   583  
   584  	// make sure that the first watcher receives at least one message
   585  	e = generateCompatibeEnvelope(t, tst[0].f)
   586  	envelopes[0] = e
   587  	tst[0].msgCnt++
   588  	for i = 1; i < NumMessages; i++ {
   589  		j = rand.Uint32() % NumFilters
   590  		e = generateCompatibeEnvelope(t, tst[j].f)
   591  		envelopes[i] = e
   592  		tst[j].msgCnt++
   593  	}
   594  
   595  	for i = 0; i < NumMessages; i++ {
   596  		filters.NotifyWatchers(envelopes[i], false)
   597  	}
   598  
   599  	for i = 0; i < NumFilters; i++ {
   600  		mail = tst[i].f.Retrieve()
   601  		count[i] = len(mail)
   602  		total += len(mail)
   603  	}
   604  
   605  	combined := tst[0].msgCnt + tst[last].msgCnt
   606  	if total != NumMessages+count[0] {
   607  		t.Fatalf("failed with seed %d: total = %d, count[0] = %d.", seed, total, count[0])
   608  	}
   609  
   610  	if combined != count[0] {
   611  		t.Fatalf("failed with seed %d: combined = %d, count[0] = %d.", seed, combined, count[0])
   612  	}
   613  
   614  	if combined != count[last] {
   615  		t.Fatalf("failed with seed %d: combined = %d, count[last] = %d.", seed, combined, count[last])
   616  	}
   617  
   618  	for i = 1; i < NumFilters-1; i++ {
   619  		mail = tst[i].f.Retrieve()
   620  		if len(mail) != 0 {
   621  			t.Fatalf("failed with seed %d: i = %d.", seed, i)
   622  		}
   623  
   624  		if tst[i].msgCnt != count[i] {
   625  			t.Fatalf("failed with seed %d: i = %d, get %d, want %d.", seed, i, tst[i].msgCnt, count[i])
   626  		}
   627  	}
   628  
   629  	// test AcceptP2P
   630  
   631  	total = 0
   632  	filters.NotifyWatchers(envelopes[0], true)
   633  
   634  	for i = 0; i < NumFilters; i++ {
   635  		mail = tst[i].f.Retrieve()
   636  		total += len(mail)
   637  	}
   638  
   639  	if total != 0 {
   640  		t.Fatalf("failed with seed %d: total: got %d, want 0.", seed, total)
   641  	}
   642  
   643  	f := filters.Get(1)
   644  	if f == nil {
   645  		t.Fatalf("failed to get the filter with seed %d.", seed)
   646  	}
   647  	f.AcceptP2P = true
   648  	total = 0
   649  	filters.NotifyWatchers(envelopes[0], true)
   650  
   651  	for i = 0; i < NumFilters; i++ {
   652  		mail = tst[i].f.Retrieve()
   653  		total += len(mail)
   654  	}
   655  
   656  	if total != 1 {
   657  		t.Fatalf("failed with seed %d: total: got %d, want 1.", seed, total)
   658  	}
   659  }