github.com/ylsGit/go-ethereum@v1.6.5/whisper/whisperv5/api_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  	"bytes"
    21  	"encoding/json"
    22  	"testing"
    23  	"time"
    24  
    25  	"github.com/ethereum/go-ethereum/common"
    26  	"github.com/ethereum/go-ethereum/common/hexutil"
    27  )
    28  
    29  func TestBasic(t *testing.T) {
    30  	var id string = "test"
    31  	w := New()
    32  	api := NewPublicWhisperAPI(w)
    33  	if api == nil {
    34  		t.Fatalf("failed to create API.")
    35  	}
    36  
    37  	ver, err := api.Version()
    38  	if err != nil {
    39  		t.Fatalf("failed generateFilter: %s.", err)
    40  	}
    41  
    42  	if uint64(ver) != ProtocolVersion {
    43  		t.Fatalf("wrong version: %d.", ver)
    44  	}
    45  
    46  	mail := api.GetNewSubscriptionMessages("non-existent-id")
    47  	if len(mail) != 0 {
    48  		t.Fatalf("failed GetFilterChanges: premature result")
    49  	}
    50  
    51  	exist, err := api.HasKeyPair(id)
    52  	if err != nil {
    53  		t.Fatalf("failed initial HasIdentity: %s.", err)
    54  	}
    55  	if exist {
    56  		t.Fatalf("failed initial HasIdentity: false positive.")
    57  	}
    58  
    59  	success, err := api.DeleteKeyPair(id)
    60  	if err != nil {
    61  		t.Fatalf("failed DeleteIdentity: %s.", err)
    62  	}
    63  	if success {
    64  		t.Fatalf("deleted non-existing identity: false positive.")
    65  	}
    66  
    67  	pub, err := api.NewKeyPair()
    68  	if err != nil {
    69  		t.Fatalf("failed NewIdentity: %s.", err)
    70  	}
    71  	if len(pub) == 0 {
    72  		t.Fatalf("failed NewIdentity: empty")
    73  	}
    74  
    75  	exist, err = api.HasKeyPair(pub)
    76  	if err != nil {
    77  		t.Fatalf("failed HasIdentity: %s.", err)
    78  	}
    79  	if !exist {
    80  		t.Fatalf("failed HasIdentity: false negative.")
    81  	}
    82  
    83  	success, err = api.DeleteKeyPair(pub)
    84  	if err != nil {
    85  		t.Fatalf("failed to delete second identity: %s.", err)
    86  	}
    87  	if !success {
    88  		t.Fatalf("failed to delete second identity.")
    89  	}
    90  
    91  	exist, err = api.HasKeyPair(pub)
    92  	if err != nil {
    93  		t.Fatalf("failed HasIdentity(): %s.", err)
    94  	}
    95  	if exist {
    96  		t.Fatalf("failed HasIdentity(): false positive.")
    97  	}
    98  
    99  	id = "arbitrary text"
   100  	id2 := "another arbitrary string"
   101  
   102  	exist, err = api.HasSymmetricKey(id)
   103  	if err != nil {
   104  		t.Fatalf("failed HasSymKey: %s.", err)
   105  	}
   106  	if exist {
   107  		t.Fatalf("failed HasSymKey: false positive.")
   108  	}
   109  
   110  	id, err = api.GenerateSymmetricKey()
   111  	if err != nil {
   112  		t.Fatalf("failed GenerateSymKey: %s.", err)
   113  	}
   114  
   115  	exist, err = api.HasSymmetricKey(id)
   116  	if err != nil {
   117  		t.Fatalf("failed HasSymKey(): %s.", err)
   118  	}
   119  	if !exist {
   120  		t.Fatalf("failed HasSymKey(): false negative.")
   121  	}
   122  
   123  	const password = "some stuff here"
   124  	id, err = api.AddSymmetricKeyFromPassword(password)
   125  	if err != nil {
   126  		t.Fatalf("failed AddSymKey: %s.", err)
   127  	}
   128  
   129  	id2, err = api.AddSymmetricKeyFromPassword(password)
   130  	if err != nil {
   131  		t.Fatalf("failed AddSymKey: %s.", err)
   132  	}
   133  
   134  	exist, err = api.HasSymmetricKey(id2)
   135  	if err != nil {
   136  		t.Fatalf("failed HasSymKey(id2): %s.", err)
   137  	}
   138  	if !exist {
   139  		t.Fatalf("failed HasSymKey(id2): false negative.")
   140  	}
   141  
   142  	k1, err := api.GetSymmetricKey(id)
   143  	if err != nil {
   144  		t.Fatalf("failed GetSymKey(id): %s.", err)
   145  	}
   146  	k2, err := api.GetSymmetricKey(id2)
   147  	if err != nil {
   148  		t.Fatalf("failed GetSymKey(id2): %s.", err)
   149  	}
   150  
   151  	if !bytes.Equal(k1, k2) {
   152  		t.Fatalf("installed keys are not equal")
   153  	}
   154  
   155  	exist, err = api.DeleteSymmetricKey(id)
   156  	if err != nil {
   157  		t.Fatalf("failed DeleteSymKey(id): %s.", err)
   158  	}
   159  	if !exist {
   160  		t.Fatalf("failed DeleteSymKey(id): false negative.")
   161  	}
   162  
   163  	exist, err = api.HasSymmetricKey(id)
   164  	if err != nil {
   165  		t.Fatalf("failed HasSymKey(id): %s.", err)
   166  	}
   167  	if exist {
   168  		t.Fatalf("failed HasSymKey(id): false positive.")
   169  	}
   170  }
   171  
   172  func TestUnmarshalFilterArgs(t *testing.T) {
   173  	s := []byte(`{
   174  	"type":"sym",
   175  	"key":"0x70c87d191324e6712a591f304b4eedef6ad9bb9d",
   176  	"sig":"0x9b2055d370f73ec7d8a03e965129118dc8f5bf83",
   177  	"minPoW":2.34,
   178  	"topics":["0x00000000", "0x007f80ff", "0xff807f00", "0xf26e7779"],
   179  	"allowP2P":true
   180  	}`)
   181  
   182  	var f WhisperFilterArgs
   183  	err := f.UnmarshalJSON(s)
   184  	if err != nil {
   185  		t.Fatalf("failed UnmarshalJSON: %s.", err)
   186  	}
   187  
   188  	if !f.Symmetric {
   189  		t.Fatalf("wrong type.")
   190  	}
   191  	if f.Key != "0x70c87d191324e6712a591f304b4eedef6ad9bb9d" {
   192  		t.Fatalf("wrong key: %s.", f.Key)
   193  	}
   194  	if f.Sig != "0x9b2055d370f73ec7d8a03e965129118dc8f5bf83" {
   195  		t.Fatalf("wrong sig: %s.", f.Sig)
   196  	}
   197  	if f.MinPoW != 2.34 {
   198  		t.Fatalf("wrong MinPoW: %f.", f.MinPoW)
   199  	}
   200  	if !f.AllowP2P {
   201  		t.Fatalf("wrong AllowP2P.")
   202  	}
   203  	if len(f.Topics) != 4 {
   204  		t.Fatalf("wrong topics number: %d.", len(f.Topics))
   205  	}
   206  
   207  	i := 0
   208  	if !bytes.Equal(f.Topics[i], []byte{0x00, 0x00, 0x00, 0x00}) {
   209  		t.Fatalf("wrong topic[%d]: %x.", i, f.Topics[i])
   210  	}
   211  
   212  	i++
   213  	if !bytes.Equal(f.Topics[i], []byte{0x00, 0x7f, 0x80, 0xff}) {
   214  		t.Fatalf("wrong topic[%d]: %x.", i, f.Topics[i])
   215  	}
   216  
   217  	i++
   218  	if !bytes.Equal(f.Topics[i], []byte{0xff, 0x80, 0x7f, 0x00}) {
   219  		t.Fatalf("wrong topic[%d]: %x.", i, f.Topics[i])
   220  	}
   221  
   222  	i++
   223  	if !bytes.Equal(f.Topics[i], []byte{0xf2, 0x6e, 0x77, 0x79}) {
   224  		t.Fatalf("wrong topic[%d]: %x.", i, f.Topics[i])
   225  	}
   226  }
   227  
   228  func TestUnmarshalPostArgs(t *testing.T) {
   229  	s := []byte(`{
   230  	"type":"sym",
   231  	"ttl":12345,
   232  	"sig":"0x70c87d191324e6712a591f304b4eedef6ad9bb9d",
   233  	"key":"0x9b2055d370f73ec7d8a03e965129118dc8f5bf83",
   234  	"topic":"0xf26e7779",
   235  	"padding":"0x74686973206973206D79207465737420737472696E67",
   236  	"payload":"0x7061796C6F61642073686F756C642062652070736575646F72616E646F6D",
   237  	"powTime":777,
   238  	"powTarget":3.1416,
   239  	"targetPeer":"enode://915533f667b1369793ebb9bda022416b1295235a1420799cd87a969467372546d808ebf59c5c9ce23f103d59b61b97df8af91f0908552485975397181b993461@127.0.0.1:12345"
   240  	}`)
   241  
   242  	var a PostArgs
   243  	err := json.Unmarshal(s, &a)
   244  	if err != nil {
   245  		t.Fatalf("failed UnmarshalJSON: %s.", err)
   246  	}
   247  
   248  	if a.Type != "sym" {
   249  		t.Fatalf("wrong Type: %s.", a.Type)
   250  	}
   251  	if a.TTL != 12345 {
   252  		t.Fatalf("wrong ttl: %d.", a.TTL)
   253  	}
   254  	if a.Sig != "0x70c87d191324e6712a591f304b4eedef6ad9bb9d" {
   255  		t.Fatalf("wrong From: %s.", a.Sig)
   256  	}
   257  	if a.Key != "0x9b2055d370f73ec7d8a03e965129118dc8f5bf83" {
   258  		t.Fatalf("wrong Key: %s.", a.Key)
   259  	}
   260  
   261  	if BytesToTopic(a.Topic) != (TopicType{0xf2, 0x6e, 0x77, 0x79}) {
   262  		t.Fatalf("wrong topic: %x.", a.Topic)
   263  	}
   264  	if string(a.Padding) != "this is my test string" {
   265  		t.Fatalf("wrong Padding: %s.", string(a.Padding))
   266  	}
   267  	if string(a.Payload) != "payload should be pseudorandom" {
   268  		t.Fatalf("wrong Payload: %s.", string(a.Payload))
   269  	}
   270  	if a.PowTime != 777 {
   271  		t.Fatalf("wrong PowTime: %d.", a.PowTime)
   272  	}
   273  	if a.PowTarget != 3.1416 {
   274  		t.Fatalf("wrong PowTarget: %f.", a.PowTarget)
   275  	}
   276  	if a.TargetPeer != "enode://915533f667b1369793ebb9bda022416b1295235a1420799cd87a969467372546d808ebf59c5c9ce23f103d59b61b97df8af91f0908552485975397181b993461@127.0.0.1:12345" {
   277  		t.Fatalf("wrong PeerID: %s.", a.TargetPeer)
   278  	}
   279  }
   280  
   281  func waitForMessages(api *PublicWhisperAPI, id string, target int) []*WhisperMessage {
   282  	// timeout: 2 seconds
   283  	result := make([]*WhisperMessage, 0, target)
   284  	for i := 0; i < 100; i++ {
   285  		mail := api.GetNewSubscriptionMessages(id)
   286  		if len(mail) > 0 {
   287  			for _, m := range mail {
   288  				result = append(result, m)
   289  			}
   290  			if len(result) >= target {
   291  				break
   292  			}
   293  		}
   294  		time.Sleep(time.Millisecond * 20)
   295  	}
   296  
   297  	return result
   298  }
   299  
   300  func TestIntegrationAsym(t *testing.T) {
   301  	w := New()
   302  	api := NewPublicWhisperAPI(w)
   303  	if api == nil {
   304  		t.Fatalf("failed to create API.")
   305  	}
   306  
   307  	api.Start()
   308  	defer api.Stop()
   309  
   310  	sig, err := api.NewKeyPair()
   311  	if err != nil {
   312  		t.Fatalf("failed NewIdentity: %s.", err)
   313  	}
   314  	if len(sig) == 0 {
   315  		t.Fatalf("wrong signature")
   316  	}
   317  
   318  	exist, err := api.HasKeyPair(sig)
   319  	if err != nil {
   320  		t.Fatalf("failed HasIdentity: %s.", err)
   321  	}
   322  	if !exist {
   323  		t.Fatalf("failed HasIdentity: false negative.")
   324  	}
   325  
   326  	sigPubKey, err := api.GetPublicKey(sig)
   327  	if err != nil {
   328  		t.Fatalf("failed GetPublicKey: %s.", err)
   329  	}
   330  
   331  	key, err := api.NewKeyPair()
   332  	if err != nil {
   333  		t.Fatalf("failed NewIdentity(): %s.", err)
   334  	}
   335  	if len(key) == 0 {
   336  		t.Fatalf("wrong key")
   337  	}
   338  
   339  	dstPubKey, err := api.GetPublicKey(key)
   340  	if err != nil {
   341  		t.Fatalf("failed GetPublicKey: %s.", err)
   342  	}
   343  
   344  	var topics [2]TopicType
   345  	topics[0] = TopicType{0x00, 0x64, 0x00, 0xff}
   346  	topics[1] = TopicType{0xf2, 0x6e, 0x77, 0x79}
   347  	var f WhisperFilterArgs
   348  	f.Symmetric = false
   349  	f.Key = key
   350  	f.Sig = sigPubKey.String()
   351  	f.Topics = make([][]byte, 2)
   352  	f.Topics[0] = topics[0][:]
   353  	f.Topics[1] = topics[1][:]
   354  	f.MinPoW = DefaultMinimumPoW / 2
   355  	f.AllowP2P = true
   356  
   357  	id, err := api.Subscribe(f)
   358  	if err != nil {
   359  		t.Fatalf("failed to create new filter: %s.", err)
   360  	}
   361  
   362  	var p PostArgs
   363  	p.Type = "asym"
   364  	p.TTL = 2
   365  	p.Sig = sig
   366  	p.Key = dstPubKey.String()
   367  	p.Padding = []byte("test string")
   368  	p.Payload = []byte("extended test string")
   369  	p.PowTarget = DefaultMinimumPoW
   370  	p.PowTime = 2
   371  	p.Topic = hexutil.Bytes{0xf2, 0x6e, 0x77, 0x79} // topics[1]
   372  
   373  	err = api.Post(p)
   374  	if err != nil {
   375  		t.Errorf("failed to post message: %s.", err)
   376  	}
   377  
   378  	mail := waitForMessages(api, id, 1)
   379  	if len(mail) != 1 {
   380  		t.Fatalf("failed to GetFilterChanges: got %d messages.", len(mail))
   381  	}
   382  
   383  	text := string(common.FromHex(mail[0].Payload))
   384  	if text != string("extended test string") {
   385  		t.Fatalf("failed to decrypt first message: %s.", text)
   386  	}
   387  
   388  	p.Padding = []byte("new value")
   389  	p.Payload = []byte("extended new value")
   390  	err = api.Post(p)
   391  	if err != nil {
   392  		t.Fatalf("failed to post next message: %s.", err)
   393  	}
   394  
   395  	mail = waitForMessages(api, id, 1)
   396  	if len(mail) != 1 {
   397  		t.Fatalf("failed to GetFilterChanges: got %d messages.", len(mail))
   398  	}
   399  
   400  	text = string(common.FromHex(mail[0].Payload))
   401  	if text != string("extended new value") {
   402  		t.Fatalf("failed to decrypt second message: %s.", text)
   403  	}
   404  }
   405  
   406  func TestIntegrationSym(t *testing.T) {
   407  	w := New()
   408  	api := NewPublicWhisperAPI(w)
   409  	if api == nil {
   410  		t.Fatalf("failed to create API.")
   411  	}
   412  
   413  	api.Start()
   414  	defer api.Stop()
   415  
   416  	symKeyID, err := api.GenerateSymmetricKey()
   417  	if err != nil {
   418  		t.Fatalf("failed GenerateSymKey: %s.", err)
   419  	}
   420  
   421  	sig, err := api.NewKeyPair()
   422  	if err != nil {
   423  		t.Fatalf("failed NewKeyPair: %s.", err)
   424  	}
   425  	if len(sig) == 0 {
   426  		t.Fatalf("wrong signature")
   427  	}
   428  
   429  	sigPubKey, err := api.GetPublicKey(sig)
   430  	if err != nil {
   431  		t.Fatalf("failed GetPublicKey: %s.", err)
   432  	}
   433  
   434  	exist, err := api.HasKeyPair(sig)
   435  	if err != nil {
   436  		t.Fatalf("failed HasIdentity: %s.", err)
   437  	}
   438  	if !exist {
   439  		t.Fatalf("failed HasIdentity: false negative.")
   440  	}
   441  
   442  	var topics [2]TopicType
   443  	topics[0] = TopicType{0x00, 0x7f, 0x80, 0xff}
   444  	topics[1] = TopicType{0xf2, 0x6e, 0x77, 0x79}
   445  	var f WhisperFilterArgs
   446  	f.Symmetric = true
   447  	f.Key = symKeyID
   448  	f.Topics = make([][]byte, 2)
   449  	f.Topics[0] = topics[0][:]
   450  	f.Topics[1] = topics[1][:]
   451  	f.MinPoW = DefaultMinimumPoW / 2
   452  	f.Sig = sigPubKey.String()
   453  	f.AllowP2P = false
   454  
   455  	id, err := api.Subscribe(f)
   456  	if err != nil {
   457  		t.Fatalf("failed to create new filter: %s.", err)
   458  	}
   459  
   460  	var p PostArgs
   461  	p.Type = "sym"
   462  	p.TTL = 1
   463  	p.Key = symKeyID
   464  	p.Sig = sig
   465  	p.Padding = []byte("test string")
   466  	p.Payload = []byte("extended test string")
   467  	p.PowTarget = DefaultMinimumPoW
   468  	p.PowTime = 2
   469  	p.Topic = hexutil.Bytes{0xf2, 0x6e, 0x77, 0x79}
   470  
   471  	err = api.Post(p)
   472  	if err != nil {
   473  		t.Fatalf("failed to post first message: %s.", err)
   474  	}
   475  
   476  	mail := waitForMessages(api, id, 1)
   477  	if len(mail) != 1 {
   478  		t.Fatalf("failed GetFilterChanges: got %d messages.", len(mail))
   479  	}
   480  
   481  	text := string(common.FromHex(mail[0].Payload))
   482  	if text != string("extended test string") {
   483  		t.Fatalf("failed to decrypt first message: %s.", text)
   484  	}
   485  
   486  	p.Padding = []byte("new value")
   487  	p.Payload = []byte("extended new value")
   488  	err = api.Post(p)
   489  	if err != nil {
   490  		t.Fatalf("failed to post second message: %s.", err)
   491  	}
   492  
   493  	mail = waitForMessages(api, id, 1)
   494  	if len(mail) != 1 {
   495  		t.Fatalf("failed second GetFilterChanges: got %d messages.", len(mail))
   496  	}
   497  
   498  	text = string(common.FromHex(mail[0].Payload))
   499  	if text != string("extended new value") {
   500  		t.Fatalf("failed to decrypt second message: %s.", text)
   501  	}
   502  }
   503  
   504  func TestIntegrationSymWithFilter(t *testing.T) {
   505  	w := New()
   506  	api := NewPublicWhisperAPI(w)
   507  	if api == nil {
   508  		t.Fatalf("failed to create API.")
   509  	}
   510  
   511  	api.Start()
   512  	defer api.Stop()
   513  
   514  	symKeyID, err := api.GenerateSymmetricKey()
   515  	if err != nil {
   516  		t.Fatalf("failed to GenerateSymKey: %s.", err)
   517  	}
   518  
   519  	sigKeyID, err := api.NewKeyPair()
   520  	if err != nil {
   521  		t.Fatalf("failed NewIdentity: %s.", err)
   522  	}
   523  	if len(sigKeyID) == 0 {
   524  		t.Fatalf("wrong signature.")
   525  	}
   526  
   527  	exist, err := api.HasKeyPair(sigKeyID)
   528  	if err != nil {
   529  		t.Fatalf("failed HasIdentity: %s.", err)
   530  	}
   531  	if !exist {
   532  		t.Fatalf("failed HasIdentity: does not exist.")
   533  	}
   534  
   535  	sigPubKey, err := api.GetPublicKey(sigKeyID)
   536  	if err != nil {
   537  		t.Fatalf("failed GetPublicKey: %s.", err)
   538  	}
   539  
   540  	var topics [2]TopicType
   541  	topics[0] = TopicType{0x00, 0x7f, 0x80, 0xff}
   542  	topics[1] = TopicType{0xf2, 0x6e, 0x77, 0x79}
   543  	var f WhisperFilterArgs
   544  	f.Symmetric = true
   545  	f.Key = symKeyID
   546  	f.Topics = make([][]byte, 2)
   547  	f.Topics[0] = topics[0][:]
   548  	f.Topics[1] = topics[1][:]
   549  	f.MinPoW = DefaultMinimumPoW / 2
   550  	f.Sig = sigPubKey.String()
   551  	f.AllowP2P = false
   552  
   553  	id, err := api.Subscribe(f)
   554  	if err != nil {
   555  		t.Fatalf("failed to create new filter: %s.", err)
   556  	}
   557  
   558  	var p PostArgs
   559  	p.Type = "sym"
   560  	p.TTL = 1
   561  	p.Key = symKeyID
   562  	p.Sig = sigKeyID
   563  	p.Padding = []byte("test string")
   564  	p.Payload = []byte("extended test string")
   565  	p.PowTarget = DefaultMinimumPoW
   566  	p.PowTime = 2
   567  	p.Topic = hexutil.Bytes{0xf2, 0x6e, 0x77, 0x79}
   568  
   569  	err = api.Post(p)
   570  	if err != nil {
   571  		t.Fatalf("failed to post message: %s.", err)
   572  	}
   573  
   574  	mail := waitForMessages(api, id, 1)
   575  	if len(mail) != 1 {
   576  		t.Fatalf("failed to GetFilterChanges: got %d messages.", len(mail))
   577  	}
   578  
   579  	text := string(common.FromHex(mail[0].Payload))
   580  	if text != string("extended test string") {
   581  		t.Fatalf("failed to decrypt first message: %s.", text)
   582  	}
   583  
   584  	p.Padding = []byte("new value")
   585  	p.Payload = []byte("extended new value")
   586  	err = api.Post(p)
   587  	if err != nil {
   588  		t.Fatalf("failed to post next message: %s.", err)
   589  	}
   590  
   591  	mail = waitForMessages(api, id, 1)
   592  	if len(mail) != 1 {
   593  		t.Fatalf("failed to GetFilterChanges: got %d messages.", len(mail))
   594  	}
   595  
   596  	text = string(common.FromHex(mail[0].Payload))
   597  	if text != string("extended new value") {
   598  		t.Fatalf("failed to decrypt second message: %s.", text)
   599  	}
   600  }
   601  
   602  func TestKey(t *testing.T) {
   603  	w := New()
   604  	api := NewPublicWhisperAPI(w)
   605  	if api == nil {
   606  		t.Fatalf("failed to create API.")
   607  	}
   608  
   609  	k, err := api.AddSymmetricKeyFromPassword("wwww")
   610  	if err != nil {
   611  		t.Fatalf("failed to create key: %s.", err)
   612  	}
   613  
   614  	s, err := api.GetSymmetricKey(k)
   615  	if err != nil {
   616  		t.Fatalf("failed to get sym key: %s.", err)
   617  	}
   618  
   619  	k2, err := api.AddSymmetricKeyDirect(s)
   620  	if err != nil {
   621  		t.Fatalf("failed to add sym key: %s.", err)
   622  	}
   623  
   624  	s2, err := api.GetSymmetricKey(k2)
   625  	if err != nil {
   626  		t.Fatalf("failed to get sym key: %s.", err)
   627  	}
   628  
   629  	if s.String() != "0x448652d595bd6ec00b2a9ea220ad6c26592d9bf4cf79023d3c1b30cb681e6e07" {
   630  		t.Fatalf("wrong key from password: %s", s.String())
   631  	}
   632  
   633  	if !bytes.Equal(s, s2) {
   634  		t.Fatalf("wrong key")
   635  	}
   636  }
   637  
   638  func TestSubscribe(t *testing.T) {
   639  	var err error
   640  	var s string
   641  
   642  	w := New()
   643  	api := NewPublicWhisperAPI(w)
   644  	if api == nil {
   645  		t.Fatalf("failed to create API.")
   646  	}
   647  
   648  	symKeyID, err := api.GenerateSymmetricKey()
   649  	if err != nil {
   650  		t.Fatalf("failed to GenerateSymKey: %s.", err)
   651  	}
   652  
   653  	var f WhisperFilterArgs
   654  	f.Symmetric = true
   655  	f.Key = symKeyID
   656  	f.Topics = make([][]byte, 5)
   657  	f.Topics[0] = []byte{0x21}
   658  	f.Topics[1] = []byte{0xd2, 0xe3}
   659  	f.Topics[2] = []byte{0x64, 0x75, 0x76}
   660  	f.Topics[3] = []byte{0xf8, 0xe9, 0xa0, 0xba}
   661  	f.Topics[4] = []byte{0xcb, 0x3c, 0xdd, 0xee, 0xff}
   662  
   663  	s, err = api.Subscribe(f)
   664  	if err == nil {
   665  		t.Fatalf("Subscribe: false positive.")
   666  	}
   667  
   668  	f.Topics[4] = []byte{}
   669  	if err == nil {
   670  		t.Fatalf("Subscribe: false positive again.")
   671  	}
   672  
   673  	f.Topics[4] = []byte{0x00}
   674  	s, err = api.Subscribe(f)
   675  	if err != nil {
   676  		t.Fatalf("failed to subscribe: %s.", err)
   677  	} else {
   678  		api.Unsubscribe(s)
   679  	}
   680  }