github.com/murrekatt/go-ethereum@v1.5.8-0.20170123175102-fc52f2c007fb/whisper/shhapi/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 shhapi
    18  
    19  import (
    20  	"bytes"
    21  	"testing"
    22  	"time"
    23  
    24  	"encoding/json"
    25  
    26  	"github.com/ethereum/go-ethereum/common"
    27  	"github.com/ethereum/go-ethereum/whisper/whisperv5"
    28  )
    29  
    30  func TestBasic(t *testing.T) {
    31  	var id string = "test"
    32  	api := NewPublicWhisperAPI()
    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) != whisperv5.ProtocolVersion {
    43  		t.Fatalf("wrong version: %d.", ver)
    44  	}
    45  
    46  	mail := api.GetFilterChanges(1)
    47  	if len(mail) != 0 {
    48  		t.Fatalf("failed GetFilterChanges: premature result")
    49  	}
    50  
    51  	exist, err := api.HasIdentity(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  	err = api.DeleteIdentity(id)
    60  	if err != nil {
    61  		t.Fatalf("failed DeleteIdentity: %s.", err)
    62  	}
    63  
    64  	pub, err := api.NewIdentity()
    65  	if err != nil {
    66  		t.Fatalf("failed NewIdentity: %s.", err)
    67  	}
    68  	if len(pub) == 0 {
    69  		t.Fatalf("failed NewIdentity: empty")
    70  	}
    71  
    72  	exist, err = api.HasIdentity(pub)
    73  	if err != nil {
    74  		t.Fatalf("failed HasIdentity: %s.", err)
    75  	}
    76  	if !exist {
    77  		t.Fatalf("failed HasIdentity: false negative.")
    78  	}
    79  
    80  	err = api.DeleteIdentity(pub)
    81  	if err != nil {
    82  		t.Fatalf("failed to delete second identity: %s.", err)
    83  	}
    84  
    85  	exist, err = api.HasIdentity(pub)
    86  	if err != nil {
    87  		t.Fatalf("failed HasIdentity(): %s.", err)
    88  	}
    89  	if exist {
    90  		t.Fatalf("failed HasIdentity(): false positive.")
    91  	}
    92  
    93  	id = "arbitrary text"
    94  	id2 := "another arbitrary string"
    95  
    96  	exist, err = api.HasSymKey(id)
    97  	if err != nil {
    98  		t.Fatalf("failed HasSymKey: %s.", err)
    99  	}
   100  	if exist {
   101  		t.Fatalf("failed HasSymKey: false positive.")
   102  	}
   103  
   104  	err = api.GenerateSymKey(id)
   105  	if err != nil {
   106  		t.Fatalf("failed GenerateSymKey: %s.", err)
   107  	}
   108  
   109  	exist, err = api.HasSymKey(id)
   110  	if err != nil {
   111  		t.Fatalf("failed HasSymKey(): %s.", err)
   112  	}
   113  	if !exist {
   114  		t.Fatalf("failed HasSymKey(): false negative.")
   115  	}
   116  
   117  	err = api.AddSymKey(id, []byte("some stuff here"))
   118  	if err == nil {
   119  		t.Fatalf("failed AddSymKey: %s.", err)
   120  	}
   121  
   122  	err = api.AddSymKey(id2, []byte("some stuff here"))
   123  	if err != nil {
   124  		t.Fatalf("failed AddSymKey: %s.", err)
   125  	}
   126  
   127  	exist, err = api.HasSymKey(id2)
   128  	if err != nil {
   129  		t.Fatalf("failed HasSymKey(id2): %s.", err)
   130  	}
   131  	if !exist {
   132  		t.Fatalf("failed HasSymKey(id2): false negative.")
   133  	}
   134  
   135  	err = api.DeleteSymKey(id)
   136  	if err != nil {
   137  		t.Fatalf("failed DeleteSymKey(id): %s.", err)
   138  	}
   139  
   140  	exist, err = api.HasSymKey(id)
   141  	if err != nil {
   142  		t.Fatalf("failed HasSymKey(id): %s.", err)
   143  	}
   144  	if exist {
   145  		t.Fatalf("failed HasSymKey(id): false positive.")
   146  	}
   147  }
   148  
   149  func TestUnmarshalFilterArgs(t *testing.T) {
   150  	s := []byte(`{
   151  	"to":"0x70c87d191324e6712a591f304b4eedef6ad9bb9d",
   152  	"from":"0x9b2055d370f73ec7d8a03e965129118dc8f5bf83",
   153  	"keyname":"testname",
   154  	"pow":2.34,
   155  	"topics":["0x00000000", "0x007f80ff", "0xff807f00", "0xf26e7779"],
   156  	"acceptP2P":true
   157  	}`)
   158  
   159  	var f WhisperFilterArgs
   160  	err := f.UnmarshalJSON(s)
   161  	if err != nil {
   162  		t.Fatalf("failed UnmarshalJSON: %s.", err)
   163  	}
   164  
   165  	if f.To != "0x70c87d191324e6712a591f304b4eedef6ad9bb9d" {
   166  		t.Fatalf("wrong To: %x.", f.To)
   167  	}
   168  	if f.From != "0x9b2055d370f73ec7d8a03e965129118dc8f5bf83" {
   169  		t.Fatalf("wrong From: %x.", f.To)
   170  	}
   171  	if f.KeyName != "testname" {
   172  		t.Fatalf("wrong KeyName: %s.", f.KeyName)
   173  	}
   174  	if f.PoW != 2.34 {
   175  		t.Fatalf("wrong pow: %f.", f.PoW)
   176  	}
   177  	if !f.AcceptP2P {
   178  		t.Fatalf("wrong AcceptP2P: %v.", f.AcceptP2P)
   179  	}
   180  	if len(f.Topics) != 4 {
   181  		t.Fatalf("wrong topics number: %d.", len(f.Topics))
   182  	}
   183  
   184  	i := 0
   185  	if f.Topics[i] != (whisperv5.TopicType{0x00, 0x00, 0x00, 0x00}) {
   186  		t.Fatalf("wrong topic[%d]: %x.", i, f.Topics[i])
   187  	}
   188  
   189  	i++
   190  	if f.Topics[i] != (whisperv5.TopicType{0x00, 0x7f, 0x80, 0xff}) {
   191  		t.Fatalf("wrong topic[%d]: %x.", i, f.Topics[i])
   192  	}
   193  
   194  	i++
   195  	if f.Topics[i] != (whisperv5.TopicType{0xff, 0x80, 0x7f, 0x00}) {
   196  		t.Fatalf("wrong topic[%d]: %x.", i, f.Topics[i])
   197  	}
   198  
   199  	i++
   200  	if f.Topics[i] != (whisperv5.TopicType{0xf2, 0x6e, 0x77, 0x79}) {
   201  		t.Fatalf("wrong topic[%d]: %x.", i, f.Topics[i])
   202  	}
   203  }
   204  
   205  func TestUnmarshalPostArgs(t *testing.T) {
   206  	s := []byte(`{
   207  	"ttl":12345,
   208  	"from":"0x70c87d191324e6712a591f304b4eedef6ad9bb9d",
   209  	"to":"0x9b2055d370f73ec7d8a03e965129118dc8f5bf83",
   210  	"keyname":"shh_test",
   211  	"topic":"0xf26e7779",
   212  	"padding":"0x74686973206973206D79207465737420737472696E67",
   213  	"payload":"0x7061796C6F61642073686F756C642062652070736575646F72616E646F6D",
   214  	"worktime":777,
   215  	"pow":3.1416,
   216  	"filterID":64,
   217  	"peerID":"0xf26e7779"
   218  	}`)
   219  
   220  	var a PostArgs
   221  	err := json.Unmarshal(s, &a)
   222  	if err != nil {
   223  		t.Fatalf("failed UnmarshalJSON: %s.", err)
   224  	}
   225  
   226  	if a.TTL != 12345 {
   227  		t.Fatalf("wrong ttl: %d.", a.TTL)
   228  	}
   229  	if a.From != "0x70c87d191324e6712a591f304b4eedef6ad9bb9d" {
   230  		t.Fatalf("wrong From: %x.", a.To)
   231  	}
   232  	if a.To != "0x9b2055d370f73ec7d8a03e965129118dc8f5bf83" {
   233  		t.Fatalf("wrong To: %x.", a.To)
   234  	}
   235  	if a.KeyName != "shh_test" {
   236  		t.Fatalf("wrong KeyName: %s.", a.KeyName)
   237  	}
   238  	if a.Topic != (whisperv5.TopicType{0xf2, 0x6e, 0x77, 0x79}) {
   239  		t.Fatalf("wrong topic: %x.", a.Topic)
   240  	}
   241  	if string(a.Padding) != "this is my test string" {
   242  		t.Fatalf("wrong Padding: %s.", string(a.Padding))
   243  	}
   244  	if string(a.Payload) != "payload should be pseudorandom" {
   245  		t.Fatalf("wrong Payload: %s.", string(a.Payload))
   246  	}
   247  	if a.WorkTime != 777 {
   248  		t.Fatalf("wrong WorkTime: %d.", a.WorkTime)
   249  	}
   250  	if a.PoW != 3.1416 {
   251  		t.Fatalf("wrong pow: %f.", a.PoW)
   252  	}
   253  	if a.FilterID != 64 {
   254  		t.Fatalf("wrong FilterID: %d.", a.FilterID)
   255  	}
   256  	if !bytes.Equal(a.PeerID[:], a.Topic[:]) {
   257  		t.Fatalf("wrong PeerID: %x.", a.PeerID)
   258  	}
   259  }
   260  
   261  func waitForMessage(api *PublicWhisperAPI, id uint32, target int) bool {
   262  	for i := 0; i < 64; i++ {
   263  		all := api.GetMessages(id)
   264  		if len(all) >= target {
   265  			return true
   266  		}
   267  		time.Sleep(time.Millisecond * 16)
   268  	}
   269  
   270  	// timeout 1024 milliseconds
   271  	return false
   272  }
   273  
   274  func TestIntegrationAsym(t *testing.T) {
   275  	api := NewPublicWhisperAPI()
   276  	if api == nil {
   277  		t.Fatalf("failed to create API.")
   278  	}
   279  
   280  	api.Start()
   281  	defer api.Stop()
   282  
   283  	sig, err := api.NewIdentity()
   284  	if err != nil {
   285  		t.Fatalf("failed NewIdentity: %s.", err)
   286  	}
   287  	if len(sig) == 0 {
   288  		t.Fatalf("wrong signature")
   289  	}
   290  
   291  	exist, err := api.HasIdentity(sig)
   292  	if err != nil {
   293  		t.Fatalf("failed HasIdentity: %s.", err)
   294  	}
   295  	if !exist {
   296  		t.Fatalf("failed HasIdentity: false negative.")
   297  	}
   298  
   299  	key, err := api.NewIdentity()
   300  	if err != nil {
   301  		t.Fatalf("failed NewIdentity(): %s.", err)
   302  	}
   303  	if len(key) == 0 {
   304  		t.Fatalf("wrong key")
   305  	}
   306  
   307  	var topics [2]whisperv5.TopicType
   308  	topics[0] = whisperv5.TopicType{0x00, 0x64, 0x00, 0xff}
   309  	topics[1] = whisperv5.TopicType{0xf2, 0x6e, 0x77, 0x79}
   310  	var f WhisperFilterArgs
   311  	f.To = key
   312  	f.From = sig
   313  	f.Topics = topics[:]
   314  	f.PoW = whisperv5.MinimumPoW / 2
   315  	f.AcceptP2P = true
   316  
   317  	id, err := api.NewFilter(f)
   318  	if err != nil {
   319  		t.Fatalf("failed to create new filter: %s.", err)
   320  	}
   321  
   322  	var p PostArgs
   323  	p.TTL = 2
   324  	p.From = f.From
   325  	p.To = f.To
   326  	p.Padding = []byte("test string")
   327  	p.Payload = []byte("extended test string")
   328  	p.PoW = whisperv5.MinimumPoW
   329  	p.Topic = whisperv5.TopicType{0xf2, 0x6e, 0x77, 0x79}
   330  	p.WorkTime = 2
   331  
   332  	err = api.Post(p)
   333  	if err != nil {
   334  		t.Errorf("failed to post message: %s.", err)
   335  	}
   336  
   337  	ok := waitForMessage(api, id, 1)
   338  	if !ok {
   339  		t.Fatalf("failed to receive first message: timeout.")
   340  	}
   341  
   342  	mail := api.GetFilterChanges(id)
   343  	if len(mail) != 1 {
   344  		t.Fatalf("failed to GetFilterChanges: got %d messages.", len(mail))
   345  	}
   346  
   347  	text := string(common.FromHex(mail[0].Payload))
   348  	if text != string("extended test string") {
   349  		t.Fatalf("failed to decrypt first message: %s.", text)
   350  	}
   351  
   352  	p.Padding = []byte("new value")
   353  	p.Payload = []byte("extended new value")
   354  	err = api.Post(p)
   355  	if err != nil {
   356  		t.Fatalf("failed to post next message: %s.", err)
   357  	}
   358  
   359  	ok = waitForMessage(api, id, 2)
   360  	if !ok {
   361  		t.Fatalf("failed to receive second message: timeout.")
   362  	}
   363  
   364  	mail = api.GetFilterChanges(id)
   365  	if len(mail) != 1 {
   366  		t.Fatalf("failed to GetFilterChanges: got %d messages.", len(mail))
   367  	}
   368  
   369  	text = string(common.FromHex(mail[0].Payload))
   370  	if text != string("extended new value") {
   371  		t.Fatalf("failed to decrypt second message: %s.", text)
   372  	}
   373  }
   374  
   375  func TestIntegrationSym(t *testing.T) {
   376  	api := NewPublicWhisperAPI()
   377  	if api == nil {
   378  		t.Fatalf("failed to create API.")
   379  	}
   380  
   381  	api.Start()
   382  	defer api.Stop()
   383  
   384  	keyname := "schluessel"
   385  	err := api.GenerateSymKey(keyname)
   386  	if err != nil {
   387  		t.Fatalf("failed GenerateSymKey: %s.", err)
   388  	}
   389  
   390  	sig, err := api.NewIdentity()
   391  	if err != nil {
   392  		t.Fatalf("failed NewIdentity: %s.", err)
   393  	}
   394  	if len(sig) == 0 {
   395  		t.Fatalf("wrong signature")
   396  	}
   397  
   398  	exist, err := api.HasIdentity(sig)
   399  	if err != nil {
   400  		t.Fatalf("failed HasIdentity: %s.", err)
   401  	}
   402  	if !exist {
   403  		t.Fatalf("failed HasIdentity: false negative.")
   404  	}
   405  
   406  	var topics [2]whisperv5.TopicType
   407  	topics[0] = whisperv5.TopicType{0x00, 0x7f, 0x80, 0xff}
   408  	topics[1] = whisperv5.TopicType{0xf2, 0x6e, 0x77, 0x79}
   409  	var f WhisperFilterArgs
   410  	f.KeyName = keyname
   411  	f.Topics = topics[:]
   412  	f.PoW = 0.324
   413  	f.From = sig
   414  	f.AcceptP2P = false
   415  
   416  	id, err := api.NewFilter(f)
   417  	if err != nil {
   418  		t.Fatalf("failed to create new filter: %s.", err)
   419  	}
   420  
   421  	var p PostArgs
   422  	p.TTL = 1
   423  	p.KeyName = keyname
   424  	p.From = f.From
   425  	p.Padding = []byte("test string")
   426  	p.Payload = []byte("extended test string")
   427  	p.PoW = whisperv5.MinimumPoW
   428  	p.Topic = whisperv5.TopicType{0xf2, 0x6e, 0x77, 0x79}
   429  	p.WorkTime = 2
   430  
   431  	err = api.Post(p)
   432  	if err != nil {
   433  		t.Fatalf("failed to post first message: %s.", err)
   434  	}
   435  
   436  	ok := waitForMessage(api, id, 1)
   437  	if !ok {
   438  		t.Fatalf("failed to receive first message: timeout.")
   439  	}
   440  
   441  	mail := api.GetFilterChanges(id)
   442  	if len(mail) != 1 {
   443  		t.Fatalf("failed GetFilterChanges: got %d messages.", len(mail))
   444  	}
   445  
   446  	text := string(common.FromHex(mail[0].Payload))
   447  	if text != string("extended test string") {
   448  		t.Fatalf("failed to decrypt first message: %s.", text)
   449  	}
   450  
   451  	p.Padding = []byte("new value")
   452  	p.Payload = []byte("extended new value")
   453  	err = api.Post(p)
   454  	if err != nil {
   455  		t.Fatalf("failed to post second message: %s.", err)
   456  	}
   457  
   458  	ok = waitForMessage(api, id, 2)
   459  	if !ok {
   460  		t.Fatalf("failed to receive second message: timeout.")
   461  	}
   462  
   463  	mail = api.GetFilterChanges(id)
   464  	if len(mail) != 1 {
   465  		t.Fatalf("failed second GetFilterChanges: got %d messages.", len(mail))
   466  	}
   467  
   468  	text = string(common.FromHex(mail[0].Payload))
   469  	if text != string("extended new value") {
   470  		t.Fatalf("failed to decrypt second message: %s.", text)
   471  	}
   472  }
   473  
   474  func TestIntegrationSymWithFilter(t *testing.T) {
   475  	api := NewPublicWhisperAPI()
   476  	if api == nil {
   477  		t.Fatalf("failed to create API.")
   478  	}
   479  
   480  	api.Start()
   481  	defer api.Stop()
   482  
   483  	keyname := "schluessel"
   484  	err := api.GenerateSymKey(keyname)
   485  	if err != nil {
   486  		t.Fatalf("failed to GenerateSymKey: %s.", err)
   487  	}
   488  
   489  	sig, err := api.NewIdentity()
   490  	if err != nil {
   491  		t.Fatalf("failed NewIdentity: %s.", err)
   492  	}
   493  	if len(sig) == 0 {
   494  		t.Fatalf("wrong signature.")
   495  	}
   496  
   497  	exist, err := api.HasIdentity(sig)
   498  	if err != nil {
   499  		t.Fatalf("failed HasIdentity: %s.", err)
   500  	}
   501  	if !exist {
   502  		t.Fatalf("failed HasIdentity: does not exist.")
   503  	}
   504  
   505  	var topics [2]whisperv5.TopicType
   506  	topics[0] = whisperv5.TopicType{0x00, 0x7f, 0x80, 0xff}
   507  	topics[1] = whisperv5.TopicType{0xf2, 0x6e, 0x77, 0x79}
   508  	var f WhisperFilterArgs
   509  	f.KeyName = keyname
   510  	f.Topics = topics[:]
   511  	f.PoW = 0.324
   512  	f.From = sig
   513  	f.AcceptP2P = false
   514  
   515  	id, err := api.NewFilter(f)
   516  	if err != nil {
   517  		t.Fatalf("failed to create new filter: %s.", err)
   518  	}
   519  
   520  	var p PostArgs
   521  	p.TTL = 1
   522  	p.FilterID = id
   523  	p.From = sig
   524  	p.Padding = []byte("test string")
   525  	p.Payload = []byte("extended test string")
   526  	p.PoW = whisperv5.MinimumPoW
   527  	p.Topic = whisperv5.TopicType{0xf2, 0x6e, 0x77, 0x79}
   528  	p.WorkTime = 2
   529  
   530  	err = api.Post(p)
   531  	if err != nil {
   532  		t.Fatalf("failed to post message: %s.", err)
   533  	}
   534  
   535  	ok := waitForMessage(api, id, 1)
   536  	if !ok {
   537  		t.Fatalf("failed to receive first message: timeout.")
   538  	}
   539  
   540  	mail := api.GetFilterChanges(id)
   541  	if len(mail) != 1 {
   542  		t.Fatalf("failed to GetFilterChanges: got %d messages.", len(mail))
   543  	}
   544  
   545  	text := string(common.FromHex(mail[0].Payload))
   546  	if text != string("extended test string") {
   547  		t.Fatalf("failed to decrypt first message: %s.", text)
   548  	}
   549  
   550  	p.Padding = []byte("new value")
   551  	p.Payload = []byte("extended new value")
   552  	err = api.Post(p)
   553  	if err != nil {
   554  		t.Fatalf("failed to post next message: %s.", err)
   555  	}
   556  
   557  	ok = waitForMessage(api, id, 2)
   558  	if !ok {
   559  		t.Fatalf("failed to receive second message: timeout.")
   560  	}
   561  
   562  	mail = api.GetFilterChanges(id)
   563  	if len(mail) != 1 {
   564  		t.Fatalf("failed to GetFilterChanges: got %d messages.", len(mail))
   565  	}
   566  
   567  	text = string(common.FromHex(mail[0].Payload))
   568  	if text != string("extended new value") {
   569  		t.Fatalf("failed to decrypt second message: %s.", text)
   570  	}
   571  }