github.com/oskarth/go-ethereum@v1.6.8-0.20191013093314-dac24a9d3494/swarm/pss/pss_test.go (about)

     1  // Copyright 2018 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 pss
    18  
    19  import (
    20  	"bytes"
    21  	"context"
    22  	"crypto/ecdsa"
    23  	"encoding/binary"
    24  	"encoding/hex"
    25  	"encoding/json"
    26  	"flag"
    27  	"fmt"
    28  	"io/ioutil"
    29  	"math/rand"
    30  	"os"
    31  	"strconv"
    32  	"strings"
    33  	"sync"
    34  	"testing"
    35  	"time"
    36  
    37  	"github.com/ethereum/go-ethereum/common"
    38  	"github.com/ethereum/go-ethereum/common/hexutil"
    39  	"github.com/ethereum/go-ethereum/crypto"
    40  	"github.com/ethereum/go-ethereum/log"
    41  	"github.com/ethereum/go-ethereum/metrics"
    42  	"github.com/ethereum/go-ethereum/metrics/influxdb"
    43  	"github.com/ethereum/go-ethereum/node"
    44  	"github.com/ethereum/go-ethereum/p2p"
    45  	"github.com/ethereum/go-ethereum/p2p/enode"
    46  	"github.com/ethereum/go-ethereum/p2p/protocols"
    47  	"github.com/ethereum/go-ethereum/p2p/simulations"
    48  	"github.com/ethereum/go-ethereum/p2p/simulations/adapters"
    49  	"github.com/ethereum/go-ethereum/rpc"
    50  	"github.com/ethereum/go-ethereum/swarm/network"
    51  	"github.com/ethereum/go-ethereum/swarm/state"
    52  	whisper "github.com/ethereum/go-ethereum/whisper/whisperv5"
    53  )
    54  
    55  var (
    56  	initOnce       = sync.Once{}
    57  	debugdebugflag = flag.Bool("vv", false, "veryverbose")
    58  	debugflag      = flag.Bool("v", false, "verbose")
    59  	longrunning    = flag.Bool("longrunning", false, "do run long-running tests")
    60  	w              *whisper.Whisper
    61  	wapi           *whisper.PublicWhisperAPI
    62  	psslogmain     log.Logger
    63  	pssprotocols   map[string]*protoCtrl
    64  	useHandshake   bool
    65  )
    66  
    67  func init() {
    68  	flag.Parse()
    69  	rand.Seed(time.Now().Unix())
    70  
    71  	adapters.RegisterServices(newServices(false))
    72  	initTest()
    73  }
    74  
    75  func initTest() {
    76  	initOnce.Do(
    77  		func() {
    78  			loglevel := log.LvlInfo
    79  			if *debugflag {
    80  				loglevel = log.LvlDebug
    81  			} else if *debugdebugflag {
    82  				loglevel = log.LvlTrace
    83  			}
    84  
    85  			psslogmain = log.New("psslog", "*")
    86  			hs := log.StreamHandler(os.Stderr, log.TerminalFormat(true))
    87  			hf := log.LvlFilterHandler(loglevel, hs)
    88  			h := log.CallerFileHandler(hf)
    89  			log.Root().SetHandler(h)
    90  
    91  			w = whisper.New(&whisper.DefaultConfig)
    92  			wapi = whisper.NewPublicWhisperAPI(w)
    93  
    94  			pssprotocols = make(map[string]*protoCtrl)
    95  		},
    96  	)
    97  }
    98  
    99  // test that topic conversion functions give predictable results
   100  func TestTopic(t *testing.T) {
   101  
   102  	api := &API{}
   103  
   104  	topicstr := strings.Join([]string{PingProtocol.Name, strconv.Itoa(int(PingProtocol.Version))}, ":")
   105  
   106  	// bytestotopic is the authoritative topic conversion source
   107  	topicobj := BytesToTopic([]byte(topicstr))
   108  
   109  	// string to topic and bytes to topic must match
   110  	topicapiobj, _ := api.StringToTopic(topicstr)
   111  	if topicobj != topicapiobj {
   112  		t.Fatalf("bytes and string topic conversion mismatch; %s != %s", topicobj, topicapiobj)
   113  	}
   114  
   115  	// string representation of topichex
   116  	topichex := topicobj.String()
   117  
   118  	// protocoltopic wrapper on pingtopic should be same as topicstring
   119  	// check that it matches
   120  	pingtopichex := PingTopic.String()
   121  	if topichex != pingtopichex {
   122  		t.Fatalf("protocol topic conversion mismatch; %s != %s", topichex, pingtopichex)
   123  	}
   124  
   125  	// json marshal of topic
   126  	topicjsonout, err := topicobj.MarshalJSON()
   127  	if err != nil {
   128  		t.Fatal(err)
   129  	}
   130  	if string(topicjsonout)[1:len(topicjsonout)-1] != topichex {
   131  		t.Fatalf("topic json marshal mismatch; %s != \"%s\"", topicjsonout, topichex)
   132  	}
   133  
   134  	// json unmarshal of topic
   135  	var topicjsonin Topic
   136  	topicjsonin.UnmarshalJSON(topicjsonout)
   137  	if topicjsonin != topicobj {
   138  		t.Fatalf("topic json unmarshal mismatch: %x != %x", topicjsonin, topicobj)
   139  	}
   140  }
   141  
   142  // test bit packing of message control flags
   143  func TestMsgParams(t *testing.T) {
   144  	var ctrl byte
   145  	ctrl |= pssControlRaw
   146  	p := newMsgParamsFromBytes([]byte{ctrl})
   147  	m := newPssMsg(p)
   148  	if !m.isRaw() || m.isSym() {
   149  		t.Fatal("expected raw=true and sym=false")
   150  	}
   151  	ctrl |= pssControlSym
   152  	p = newMsgParamsFromBytes([]byte{ctrl})
   153  	m = newPssMsg(p)
   154  	if !m.isRaw() || !m.isSym() {
   155  		t.Fatal("expected raw=true and sym=true")
   156  	}
   157  	ctrl &= 0xff &^ pssControlRaw
   158  	p = newMsgParamsFromBytes([]byte{ctrl})
   159  	m = newPssMsg(p)
   160  	if m.isRaw() || !m.isSym() {
   161  		t.Fatal("expected raw=false and sym=true")
   162  	}
   163  }
   164  
   165  // test if we can insert into cache, match items with cache and cache expiry
   166  func TestCache(t *testing.T) {
   167  	var err error
   168  	to, _ := hex.DecodeString("08090a0b0c0d0e0f1011121314150001020304050607161718191a1b1c1d1e1f")
   169  	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
   170  	defer cancel()
   171  	keys, err := wapi.NewKeyPair(ctx)
   172  	privkey, err := w.GetPrivateKey(keys)
   173  	if err != nil {
   174  		t.Fatal(err)
   175  	}
   176  	ps := newTestPss(privkey, nil, nil)
   177  	pp := NewPssParams().WithPrivateKey(privkey)
   178  	data := []byte("foo")
   179  	datatwo := []byte("bar")
   180  	datathree := []byte("baz")
   181  	wparams := &whisper.MessageParams{
   182  		TTL:      defaultWhisperTTL,
   183  		Src:      privkey,
   184  		Dst:      &privkey.PublicKey,
   185  		Topic:    whisper.TopicType(PingTopic),
   186  		WorkTime: defaultWhisperWorkTime,
   187  		PoW:      defaultWhisperPoW,
   188  		Payload:  data,
   189  	}
   190  	woutmsg, err := whisper.NewSentMessage(wparams)
   191  	env, err := woutmsg.Wrap(wparams)
   192  	msg := &PssMsg{
   193  		Payload: env,
   194  		To:      to,
   195  	}
   196  	wparams.Payload = datatwo
   197  	woutmsg, err = whisper.NewSentMessage(wparams)
   198  	envtwo, err := woutmsg.Wrap(wparams)
   199  	msgtwo := &PssMsg{
   200  		Payload: envtwo,
   201  		To:      to,
   202  	}
   203  	wparams.Payload = datathree
   204  	woutmsg, err = whisper.NewSentMessage(wparams)
   205  	envthree, err := woutmsg.Wrap(wparams)
   206  	msgthree := &PssMsg{
   207  		Payload: envthree,
   208  		To:      to,
   209  	}
   210  
   211  	digest := ps.digest(msg)
   212  	if err != nil {
   213  		t.Fatalf("could not store cache msgone: %v", err)
   214  	}
   215  	digesttwo := ps.digest(msgtwo)
   216  	if err != nil {
   217  		t.Fatalf("could not store cache msgtwo: %v", err)
   218  	}
   219  	digestthree := ps.digest(msgthree)
   220  	if err != nil {
   221  		t.Fatalf("could not store cache msgthree: %v", err)
   222  	}
   223  
   224  	if digest == digesttwo {
   225  		t.Fatalf("different msgs return same hash: %d", digesttwo)
   226  	}
   227  
   228  	// check the cache
   229  	err = ps.addFwdCache(msg)
   230  	if err != nil {
   231  		t.Fatalf("write to pss expire cache failed: %v", err)
   232  	}
   233  
   234  	if !ps.checkFwdCache(msg) {
   235  		t.Fatalf("message %v should have EXPIRE record in cache but checkCache returned false", msg)
   236  	}
   237  
   238  	if ps.checkFwdCache(msgtwo) {
   239  		t.Fatalf("message %v should NOT have EXPIRE record in cache but checkCache returned true", msgtwo)
   240  	}
   241  
   242  	time.Sleep(pp.CacheTTL + 1*time.Second)
   243  	err = ps.addFwdCache(msgthree)
   244  	if err != nil {
   245  		t.Fatalf("write to pss expire cache failed: %v", err)
   246  	}
   247  
   248  	if ps.checkFwdCache(msg) {
   249  		t.Fatalf("message %v should have expired from cache but checkCache returned true", msg)
   250  	}
   251  
   252  	if _, ok := ps.fwdCache[digestthree]; !ok {
   253  		t.Fatalf("unexpired message should be in the cache: %v", digestthree)
   254  	}
   255  
   256  	if _, ok := ps.fwdCache[digesttwo]; ok {
   257  		t.Fatalf("expired message should have been cleared from the cache: %v", digesttwo)
   258  	}
   259  }
   260  
   261  // matching of address hints; whether a message could be or is for the node
   262  func TestAddressMatch(t *testing.T) {
   263  
   264  	localaddr := network.RandomAddr().Over()
   265  	copy(localaddr[:8], []byte("deadbeef"))
   266  	remoteaddr := []byte("feedbeef")
   267  	kadparams := network.NewKadParams()
   268  	kad := network.NewKademlia(localaddr, kadparams)
   269  	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
   270  	defer cancel()
   271  	keys, err := wapi.NewKeyPair(ctx)
   272  	if err != nil {
   273  		t.Fatalf("Could not generate private key: %v", err)
   274  	}
   275  	privkey, err := w.GetPrivateKey(keys)
   276  	pssp := NewPssParams().WithPrivateKey(privkey)
   277  	ps, err := NewPss(kad, pssp)
   278  	if err != nil {
   279  		t.Fatal(err.Error())
   280  	}
   281  
   282  	pssmsg := &PssMsg{
   283  		To:      remoteaddr,
   284  		Payload: &whisper.Envelope{},
   285  	}
   286  
   287  	// differ from first byte
   288  	if ps.isSelfRecipient(pssmsg) {
   289  		t.Fatalf("isSelfRecipient true but %x != %x", remoteaddr, localaddr)
   290  	}
   291  	if ps.isSelfPossibleRecipient(pssmsg) {
   292  		t.Fatalf("isSelfPossibleRecipient true but %x != %x", remoteaddr[:8], localaddr[:8])
   293  	}
   294  
   295  	// 8 first bytes same
   296  	copy(remoteaddr[:4], localaddr[:4])
   297  	if ps.isSelfRecipient(pssmsg) {
   298  		t.Fatalf("isSelfRecipient true but %x != %x", remoteaddr, localaddr)
   299  	}
   300  	if !ps.isSelfPossibleRecipient(pssmsg) {
   301  		t.Fatalf("isSelfPossibleRecipient false but %x == %x", remoteaddr[:8], localaddr[:8])
   302  	}
   303  
   304  	// all bytes same
   305  	pssmsg.To = localaddr
   306  	if !ps.isSelfRecipient(pssmsg) {
   307  		t.Fatalf("isSelfRecipient false but %x == %x", remoteaddr, localaddr)
   308  	}
   309  	if !ps.isSelfPossibleRecipient(pssmsg) {
   310  		t.Fatalf("isSelfPossibleRecipient false but %x == %x", remoteaddr[:8], localaddr[:8])
   311  	}
   312  }
   313  
   314  //
   315  func TestHandlerConditions(t *testing.T) {
   316  
   317  	t.Skip("Disabled due to probable faulty logic for outbox expectations")
   318  	// setup
   319  	privkey, err := crypto.GenerateKey()
   320  	if err != nil {
   321  		t.Fatal(err.Error())
   322  	}
   323  
   324  	addr := make([]byte, 32)
   325  	addr[0] = 0x01
   326  	ps := newTestPss(privkey, network.NewKademlia(addr, network.NewKadParams()), NewPssParams())
   327  
   328  	// message should pass
   329  	msg := &PssMsg{
   330  		To:     addr,
   331  		Expire: uint32(time.Now().Add(time.Second * 60).Unix()),
   332  		Payload: &whisper.Envelope{
   333  			Topic: [4]byte{},
   334  			Data:  []byte{0x66, 0x6f, 0x6f},
   335  		},
   336  	}
   337  	if err := ps.handlePssMsg(context.TODO(), msg); err != nil {
   338  		t.Fatal(err.Error())
   339  	}
   340  	tmr := time.NewTimer(time.Millisecond * 100)
   341  	var outmsg *PssMsg
   342  	select {
   343  	case outmsg = <-ps.outbox:
   344  	case <-tmr.C:
   345  	default:
   346  	}
   347  	if outmsg != nil {
   348  		t.Fatalf("expected outbox empty after full address on msg, but had message %s", msg)
   349  	}
   350  
   351  	// message should pass and queue due to partial length
   352  	msg.To = addr[0:1]
   353  	msg.Payload.Data = []byte{0x78, 0x79, 0x80, 0x80, 0x79}
   354  	if err := ps.handlePssMsg(context.TODO(), msg); err != nil {
   355  		t.Fatal(err.Error())
   356  	}
   357  	tmr.Reset(time.Millisecond * 100)
   358  	outmsg = nil
   359  	select {
   360  	case outmsg = <-ps.outbox:
   361  	case <-tmr.C:
   362  	}
   363  	if outmsg == nil {
   364  		t.Fatal("expected message in outbox on encrypt fail, but empty")
   365  	}
   366  	outmsg = nil
   367  	select {
   368  	case outmsg = <-ps.outbox:
   369  	default:
   370  	}
   371  	if outmsg != nil {
   372  		t.Fatalf("expected only one queued message but also had message %v", msg)
   373  	}
   374  
   375  	// full address mismatch should put message in queue
   376  	msg.To[0] = 0xff
   377  	if err := ps.handlePssMsg(context.TODO(), msg); err != nil {
   378  		t.Fatal(err.Error())
   379  	}
   380  	tmr.Reset(time.Millisecond * 10)
   381  	outmsg = nil
   382  	select {
   383  	case outmsg = <-ps.outbox:
   384  	case <-tmr.C:
   385  	}
   386  	if outmsg == nil {
   387  		t.Fatal("expected message in outbox on address mismatch, but empty")
   388  	}
   389  	outmsg = nil
   390  	select {
   391  	case outmsg = <-ps.outbox:
   392  	default:
   393  	}
   394  	if outmsg != nil {
   395  		t.Fatalf("expected only one queued message but also had message %v", msg)
   396  	}
   397  
   398  	// expired message should be dropped
   399  	msg.Expire = uint32(time.Now().Add(-time.Second).Unix())
   400  	if err := ps.handlePssMsg(context.TODO(), msg); err != nil {
   401  		t.Fatal(err.Error())
   402  	}
   403  	tmr.Reset(time.Millisecond * 10)
   404  	outmsg = nil
   405  	select {
   406  	case outmsg = <-ps.outbox:
   407  	case <-tmr.C:
   408  	default:
   409  	}
   410  	if outmsg != nil {
   411  		t.Fatalf("expected empty queue but have message %v", msg)
   412  	}
   413  
   414  	// invalid message should return error
   415  	fckedupmsg := &struct {
   416  		pssMsg *PssMsg
   417  	}{
   418  		pssMsg: &PssMsg{},
   419  	}
   420  	if err := ps.handlePssMsg(context.TODO(), fckedupmsg); err == nil {
   421  		t.Fatalf("expected error from processMsg but error nil")
   422  	}
   423  
   424  	// outbox full should return error
   425  	msg.Expire = uint32(time.Now().Add(time.Second * 60).Unix())
   426  	for i := 0; i < defaultOutboxCapacity; i++ {
   427  		ps.outbox <- msg
   428  	}
   429  	msg.Payload.Data = []byte{0x62, 0x61, 0x72}
   430  	err = ps.handlePssMsg(context.TODO(), msg)
   431  	if err == nil {
   432  		t.Fatal("expected error when mailbox full, but was nil")
   433  	}
   434  }
   435  
   436  // set and generate pubkeys and symkeys
   437  func TestKeys(t *testing.T) {
   438  	// make our key and init pss with it
   439  	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
   440  	defer cancel()
   441  	ourkeys, err := wapi.NewKeyPair(ctx)
   442  	if err != nil {
   443  		t.Fatalf("create 'our' key fail")
   444  	}
   445  	ctx, cancel2 := context.WithTimeout(context.Background(), time.Second)
   446  	defer cancel2()
   447  	theirkeys, err := wapi.NewKeyPair(ctx)
   448  	if err != nil {
   449  		t.Fatalf("create 'their' key fail")
   450  	}
   451  	ourprivkey, err := w.GetPrivateKey(ourkeys)
   452  	if err != nil {
   453  		t.Fatalf("failed to retrieve 'our' private key")
   454  	}
   455  	theirprivkey, err := w.GetPrivateKey(theirkeys)
   456  	if err != nil {
   457  		t.Fatalf("failed to retrieve 'their' private key")
   458  	}
   459  	ps := newTestPss(ourprivkey, nil, nil)
   460  
   461  	// set up peer with mock address, mapped to mocked publicaddress and with mocked symkey
   462  	addr := make(PssAddress, 32)
   463  	copy(addr, network.RandomAddr().Over())
   464  	outkey := network.RandomAddr().Over()
   465  	topicobj := BytesToTopic([]byte("foo:42"))
   466  	ps.SetPeerPublicKey(&theirprivkey.PublicKey, topicobj, &addr)
   467  	outkeyid, err := ps.SetSymmetricKey(outkey, topicobj, &addr, false)
   468  	if err != nil {
   469  		t.Fatalf("failed to set 'our' outgoing symmetric key")
   470  	}
   471  
   472  	// make a symmetric key that we will send to peer for encrypting messages to us
   473  	inkeyid, err := ps.GenerateSymmetricKey(topicobj, &addr, true)
   474  	if err != nil {
   475  		t.Fatalf("failed to set 'our' incoming symmetric key")
   476  	}
   477  
   478  	// get the key back from whisper, check that it's still the same
   479  	outkeyback, err := ps.w.GetSymKey(outkeyid)
   480  	if err != nil {
   481  		t.Fatalf(err.Error())
   482  	}
   483  	inkey, err := ps.w.GetSymKey(inkeyid)
   484  	if err != nil {
   485  		t.Fatalf(err.Error())
   486  	}
   487  	if !bytes.Equal(outkeyback, outkey) {
   488  		t.Fatalf("passed outgoing symkey doesnt equal stored: %x / %x", outkey, outkeyback)
   489  	}
   490  
   491  	t.Logf("symout: %v", outkeyback)
   492  	t.Logf("symin: %v", inkey)
   493  
   494  	// check that the key is stored in the peerpool
   495  	psp := ps.symKeyPool[inkeyid][topicobj]
   496  	if psp.address != &addr {
   497  		t.Fatalf("inkey address does not match; %p != %p", psp.address, &addr)
   498  	}
   499  }
   500  
   501  func TestGetPublickeyEntries(t *testing.T) {
   502  
   503  	privkey, err := crypto.GenerateKey()
   504  	if err != nil {
   505  		t.Fatal(err)
   506  	}
   507  	ps := newTestPss(privkey, nil, nil)
   508  
   509  	peeraddr := network.RandomAddr().Over()
   510  	topicaddr := make(map[Topic]PssAddress)
   511  	topicaddr[Topic{0x13}] = peeraddr
   512  	topicaddr[Topic{0x2a}] = peeraddr[:16]
   513  	topicaddr[Topic{0x02, 0x9a}] = []byte{}
   514  
   515  	remoteprivkey, err := crypto.GenerateKey()
   516  	if err != nil {
   517  		t.Fatal(err)
   518  	}
   519  	remotepubkeybytes := crypto.FromECDSAPub(&remoteprivkey.PublicKey)
   520  	remotepubkeyhex := common.ToHex(remotepubkeybytes)
   521  
   522  	pssapi := NewAPI(ps)
   523  
   524  	for to, a := range topicaddr {
   525  		err = pssapi.SetPeerPublicKey(remotepubkeybytes, to, a)
   526  		if err != nil {
   527  			t.Fatal(err)
   528  		}
   529  	}
   530  
   531  	intopic, err := pssapi.GetPeerTopics(remotepubkeyhex)
   532  	if err != nil {
   533  		t.Fatal(err)
   534  	}
   535  
   536  OUTER:
   537  	for _, tnew := range intopic {
   538  		for torig, addr := range topicaddr {
   539  			if bytes.Equal(torig[:], tnew[:]) {
   540  				inaddr, err := pssapi.GetPeerAddress(remotepubkeyhex, torig)
   541  				if err != nil {
   542  					t.Fatal(err)
   543  				}
   544  				if !bytes.Equal(addr, inaddr) {
   545  					t.Fatalf("Address mismatch for topic %x; got %x, expected %x", torig, inaddr, addr)
   546  				}
   547  				delete(topicaddr, torig)
   548  				continue OUTER
   549  			}
   550  		}
   551  		t.Fatalf("received topic %x did not match any existing topics", tnew)
   552  	}
   553  
   554  	if len(topicaddr) != 0 {
   555  		t.Fatalf("%d topics were not matched", len(topicaddr))
   556  	}
   557  }
   558  
   559  // forwarding should skip peers that do not have matching pss capabilities
   560  func TestMismatch(t *testing.T) {
   561  
   562  	// create privkey for forwarder node
   563  	privkey, err := crypto.GenerateKey()
   564  	if err != nil {
   565  		t.Fatal(err)
   566  	}
   567  
   568  	// initialize kad
   569  	baseaddr := network.RandomAddr()
   570  	kad := network.NewKademlia((baseaddr).Over(), network.NewKadParams())
   571  	rw := &p2p.MsgPipeRW{}
   572  
   573  	// one peer has a mismatching version of pss
   574  	wrongpssaddr := network.RandomAddr()
   575  	wrongpsscap := p2p.Cap{
   576  		Name:    pssProtocolName,
   577  		Version: 0,
   578  	}
   579  	nid := enode.ID{0x01}
   580  	wrongpsspeer := network.NewPeer(&network.BzzPeer{
   581  		Peer:    protocols.NewPeer(p2p.NewPeer(nid, common.ToHex(wrongpssaddr.Over()), []p2p.Cap{wrongpsscap}), rw, nil),
   582  		BzzAddr: &network.BzzAddr{OAddr: wrongpssaddr.Over(), UAddr: nil},
   583  	}, kad)
   584  
   585  	// one peer doesn't even have pss (boo!)
   586  	nopssaddr := network.RandomAddr()
   587  	nopsscap := p2p.Cap{
   588  		Name:    "nopss",
   589  		Version: 1,
   590  	}
   591  	nid = enode.ID{0x02}
   592  	nopsspeer := network.NewPeer(&network.BzzPeer{
   593  		Peer:    protocols.NewPeer(p2p.NewPeer(nid, common.ToHex(nopssaddr.Over()), []p2p.Cap{nopsscap}), rw, nil),
   594  		BzzAddr: &network.BzzAddr{OAddr: nopssaddr.Over(), UAddr: nil},
   595  	}, kad)
   596  
   597  	// add peers to kademlia and activate them
   598  	// it's safe so don't check errors
   599  	kad.Register(wrongpsspeer.BzzAddr)
   600  	kad.On(wrongpsspeer)
   601  	kad.Register(nopsspeer.BzzAddr)
   602  	kad.On(nopsspeer)
   603  
   604  	// create pss
   605  	pssmsg := &PssMsg{
   606  		To:      []byte{},
   607  		Expire:  uint32(time.Now().Add(time.Second).Unix()),
   608  		Payload: &whisper.Envelope{},
   609  	}
   610  	ps := newTestPss(privkey, kad, nil)
   611  
   612  	// run the forward
   613  	// it is enough that it completes; trying to send to incapable peers would create segfault
   614  	ps.forward(pssmsg)
   615  
   616  }
   617  
   618  func TestSendRaw(t *testing.T) {
   619  	t.Run("32", testSendRaw)
   620  	t.Run("8", testSendRaw)
   621  	t.Run("0", testSendRaw)
   622  }
   623  
   624  func testSendRaw(t *testing.T) {
   625  
   626  	var addrsize int64
   627  	var err error
   628  
   629  	paramstring := strings.Split(t.Name(), "/")
   630  
   631  	addrsize, _ = strconv.ParseInt(paramstring[1], 10, 0)
   632  	log.Info("raw send test", "addrsize", addrsize)
   633  
   634  	clients, err := setupNetwork(2, true)
   635  	if err != nil {
   636  		t.Fatal(err)
   637  	}
   638  
   639  	topic := "0xdeadbeef"
   640  
   641  	var loaddrhex string
   642  	err = clients[0].Call(&loaddrhex, "pss_baseAddr")
   643  	if err != nil {
   644  		t.Fatalf("rpc get node 1 baseaddr fail: %v", err)
   645  	}
   646  	loaddrhex = loaddrhex[:2+(addrsize*2)]
   647  	var roaddrhex string
   648  	err = clients[1].Call(&roaddrhex, "pss_baseAddr")
   649  	if err != nil {
   650  		t.Fatalf("rpc get node 2 baseaddr fail: %v", err)
   651  	}
   652  	roaddrhex = roaddrhex[:2+(addrsize*2)]
   653  
   654  	time.Sleep(time.Millisecond * 500)
   655  
   656  	// at this point we've verified that symkeys are saved and match on each peer
   657  	// now try sending symmetrically encrypted message, both directions
   658  	lmsgC := make(chan APIMsg)
   659  	lctx, lcancel := context.WithTimeout(context.Background(), time.Second*10)
   660  	defer lcancel()
   661  	lsub, err := clients[0].Subscribe(lctx, "pss", lmsgC, "receive", topic)
   662  	log.Trace("lsub", "id", lsub)
   663  	defer lsub.Unsubscribe()
   664  	rmsgC := make(chan APIMsg)
   665  	rctx, rcancel := context.WithTimeout(context.Background(), time.Second*10)
   666  	defer rcancel()
   667  	rsub, err := clients[1].Subscribe(rctx, "pss", rmsgC, "receive", topic)
   668  	log.Trace("rsub", "id", rsub)
   669  	defer rsub.Unsubscribe()
   670  
   671  	// send and verify delivery
   672  	lmsg := []byte("plugh")
   673  	err = clients[1].Call(nil, "pss_sendRaw", loaddrhex, topic, lmsg)
   674  	if err != nil {
   675  		t.Fatal(err)
   676  	}
   677  	select {
   678  	case recvmsg := <-lmsgC:
   679  		if !bytes.Equal(recvmsg.Msg, lmsg) {
   680  			t.Fatalf("node 1 received payload mismatch: expected %v, got %v", lmsg, recvmsg)
   681  		}
   682  	case cerr := <-lctx.Done():
   683  		t.Fatalf("test message (left) timed out: %v", cerr)
   684  	}
   685  	rmsg := []byte("xyzzy")
   686  	err = clients[0].Call(nil, "pss_sendRaw", roaddrhex, topic, rmsg)
   687  	if err != nil {
   688  		t.Fatal(err)
   689  	}
   690  	select {
   691  	case recvmsg := <-rmsgC:
   692  		if !bytes.Equal(recvmsg.Msg, rmsg) {
   693  			t.Fatalf("node 2 received payload mismatch: expected %x, got %v", rmsg, recvmsg.Msg)
   694  		}
   695  	case cerr := <-rctx.Done():
   696  		t.Fatalf("test message (right) timed out: %v", cerr)
   697  	}
   698  }
   699  
   700  // send symmetrically encrypted message between two directly connected peers
   701  func TestSendSym(t *testing.T) {
   702  	t.Run("32", testSendSym)
   703  	t.Run("8", testSendSym)
   704  	t.Run("0", testSendSym)
   705  }
   706  
   707  func testSendSym(t *testing.T) {
   708  
   709  	// address hint size
   710  	var addrsize int64
   711  	var err error
   712  	paramstring := strings.Split(t.Name(), "/")
   713  	addrsize, _ = strconv.ParseInt(paramstring[1], 10, 0)
   714  	log.Info("sym send test", "addrsize", addrsize)
   715  
   716  	clients, err := setupNetwork(2, false)
   717  	if err != nil {
   718  		t.Fatal(err)
   719  	}
   720  
   721  	var topic string
   722  	err = clients[0].Call(&topic, "pss_stringToTopic", "foo:42")
   723  	if err != nil {
   724  		t.Fatal(err)
   725  	}
   726  
   727  	var loaddrhex string
   728  	err = clients[0].Call(&loaddrhex, "pss_baseAddr")
   729  	if err != nil {
   730  		t.Fatalf("rpc get node 1 baseaddr fail: %v", err)
   731  	}
   732  	loaddrhex = loaddrhex[:2+(addrsize*2)]
   733  	var roaddrhex string
   734  	err = clients[1].Call(&roaddrhex, "pss_baseAddr")
   735  	if err != nil {
   736  		t.Fatalf("rpc get node 2 baseaddr fail: %v", err)
   737  	}
   738  	roaddrhex = roaddrhex[:2+(addrsize*2)]
   739  
   740  	// retrieve public key from pss instance
   741  	// set this public key reciprocally
   742  	var lpubkeyhex string
   743  	err = clients[0].Call(&lpubkeyhex, "pss_getPublicKey")
   744  	if err != nil {
   745  		t.Fatalf("rpc get node 1 pubkey fail: %v", err)
   746  	}
   747  	var rpubkeyhex string
   748  	err = clients[1].Call(&rpubkeyhex, "pss_getPublicKey")
   749  	if err != nil {
   750  		t.Fatalf("rpc get node 2 pubkey fail: %v", err)
   751  	}
   752  
   753  	time.Sleep(time.Millisecond * 500)
   754  
   755  	// at this point we've verified that symkeys are saved and match on each peer
   756  	// now try sending symmetrically encrypted message, both directions
   757  	lmsgC := make(chan APIMsg)
   758  	lctx, lcancel := context.WithTimeout(context.Background(), time.Second*10)
   759  	defer lcancel()
   760  	lsub, err := clients[0].Subscribe(lctx, "pss", lmsgC, "receive", topic)
   761  	log.Trace("lsub", "id", lsub)
   762  	defer lsub.Unsubscribe()
   763  	rmsgC := make(chan APIMsg)
   764  	rctx, rcancel := context.WithTimeout(context.Background(), time.Second*10)
   765  	defer rcancel()
   766  	rsub, err := clients[1].Subscribe(rctx, "pss", rmsgC, "receive", topic)
   767  	log.Trace("rsub", "id", rsub)
   768  	defer rsub.Unsubscribe()
   769  
   770  	lrecvkey := network.RandomAddr().Over()
   771  	rrecvkey := network.RandomAddr().Over()
   772  
   773  	var lkeyids [2]string
   774  	var rkeyids [2]string
   775  
   776  	// manually set reciprocal symkeys
   777  	err = clients[0].Call(&lkeyids, "psstest_setSymKeys", rpubkeyhex, lrecvkey, rrecvkey, defaultSymKeySendLimit, topic, roaddrhex)
   778  	if err != nil {
   779  		t.Fatal(err)
   780  	}
   781  	err = clients[1].Call(&rkeyids, "psstest_setSymKeys", lpubkeyhex, rrecvkey, lrecvkey, defaultSymKeySendLimit, topic, loaddrhex)
   782  	if err != nil {
   783  		t.Fatal(err)
   784  	}
   785  
   786  	// send and verify delivery
   787  	lmsg := []byte("plugh")
   788  	err = clients[1].Call(nil, "pss_sendSym", rkeyids[1], topic, hexutil.Encode(lmsg))
   789  	if err != nil {
   790  		t.Fatal(err)
   791  	}
   792  	select {
   793  	case recvmsg := <-lmsgC:
   794  		if !bytes.Equal(recvmsg.Msg, lmsg) {
   795  			t.Fatalf("node 1 received payload mismatch: expected %v, got %v", lmsg, recvmsg)
   796  		}
   797  	case cerr := <-lctx.Done():
   798  		t.Fatalf("test message timed out: %v", cerr)
   799  	}
   800  	rmsg := []byte("xyzzy")
   801  	err = clients[0].Call(nil, "pss_sendSym", lkeyids[1], topic, hexutil.Encode(rmsg))
   802  	if err != nil {
   803  		t.Fatal(err)
   804  	}
   805  	select {
   806  	case recvmsg := <-rmsgC:
   807  		if !bytes.Equal(recvmsg.Msg, rmsg) {
   808  			t.Fatalf("node 2 received payload mismatch: expected %x, got %v", rmsg, recvmsg.Msg)
   809  		}
   810  	case cerr := <-rctx.Done():
   811  		t.Fatalf("test message timed out: %v", cerr)
   812  	}
   813  }
   814  
   815  // send asymmetrically encrypted message between two directly connected peers
   816  func TestSendAsym(t *testing.T) {
   817  	t.Run("32", testSendAsym)
   818  	t.Run("8", testSendAsym)
   819  	t.Run("0", testSendAsym)
   820  }
   821  
   822  func testSendAsym(t *testing.T) {
   823  
   824  	// address hint size
   825  	var addrsize int64
   826  	var err error
   827  	paramstring := strings.Split(t.Name(), "/")
   828  	addrsize, _ = strconv.ParseInt(paramstring[1], 10, 0)
   829  	log.Info("asym send test", "addrsize", addrsize)
   830  
   831  	clients, err := setupNetwork(2, false)
   832  	if err != nil {
   833  		t.Fatal(err)
   834  	}
   835  
   836  	var topic string
   837  	err = clients[0].Call(&topic, "pss_stringToTopic", "foo:42")
   838  	if err != nil {
   839  		t.Fatal(err)
   840  	}
   841  
   842  	time.Sleep(time.Millisecond * 250)
   843  
   844  	var loaddrhex string
   845  	err = clients[0].Call(&loaddrhex, "pss_baseAddr")
   846  	if err != nil {
   847  		t.Fatalf("rpc get node 1 baseaddr fail: %v", err)
   848  	}
   849  	loaddrhex = loaddrhex[:2+(addrsize*2)]
   850  	var roaddrhex string
   851  	err = clients[1].Call(&roaddrhex, "pss_baseAddr")
   852  	if err != nil {
   853  		t.Fatalf("rpc get node 2 baseaddr fail: %v", err)
   854  	}
   855  	roaddrhex = roaddrhex[:2+(addrsize*2)]
   856  
   857  	// retrieve public key from pss instance
   858  	// set this public key reciprocally
   859  	var lpubkey string
   860  	err = clients[0].Call(&lpubkey, "pss_getPublicKey")
   861  	if err != nil {
   862  		t.Fatalf("rpc get node 1 pubkey fail: %v", err)
   863  	}
   864  	var rpubkey string
   865  	err = clients[1].Call(&rpubkey, "pss_getPublicKey")
   866  	if err != nil {
   867  		t.Fatalf("rpc get node 2 pubkey fail: %v", err)
   868  	}
   869  
   870  	time.Sleep(time.Millisecond * 500) // replace with hive healthy code
   871  
   872  	lmsgC := make(chan APIMsg)
   873  	lctx, lcancel := context.WithTimeout(context.Background(), time.Second*10)
   874  	defer lcancel()
   875  	lsub, err := clients[0].Subscribe(lctx, "pss", lmsgC, "receive", topic)
   876  	log.Trace("lsub", "id", lsub)
   877  	defer lsub.Unsubscribe()
   878  	rmsgC := make(chan APIMsg)
   879  	rctx, rcancel := context.WithTimeout(context.Background(), time.Second*10)
   880  	defer rcancel()
   881  	rsub, err := clients[1].Subscribe(rctx, "pss", rmsgC, "receive", topic)
   882  	log.Trace("rsub", "id", rsub)
   883  	defer rsub.Unsubscribe()
   884  
   885  	// store reciprocal public keys
   886  	err = clients[0].Call(nil, "pss_setPeerPublicKey", rpubkey, topic, roaddrhex)
   887  	if err != nil {
   888  		t.Fatal(err)
   889  	}
   890  	err = clients[1].Call(nil, "pss_setPeerPublicKey", lpubkey, topic, loaddrhex)
   891  	if err != nil {
   892  		t.Fatal(err)
   893  	}
   894  
   895  	// send and verify delivery
   896  	rmsg := []byte("xyzzy")
   897  	err = clients[0].Call(nil, "pss_sendAsym", rpubkey, topic, hexutil.Encode(rmsg))
   898  	if err != nil {
   899  		t.Fatal(err)
   900  	}
   901  	select {
   902  	case recvmsg := <-rmsgC:
   903  		if !bytes.Equal(recvmsg.Msg, rmsg) {
   904  			t.Fatalf("node 2 received payload mismatch: expected %v, got %v", rmsg, recvmsg.Msg)
   905  		}
   906  	case cerr := <-rctx.Done():
   907  		t.Fatalf("test message timed out: %v", cerr)
   908  	}
   909  	lmsg := []byte("plugh")
   910  	err = clients[1].Call(nil, "pss_sendAsym", lpubkey, topic, hexutil.Encode(lmsg))
   911  	if err != nil {
   912  		t.Fatal(err)
   913  	}
   914  	select {
   915  	case recvmsg := <-lmsgC:
   916  		if !bytes.Equal(recvmsg.Msg, lmsg) {
   917  			t.Fatalf("node 1 received payload mismatch: expected %v, got %v", lmsg, recvmsg.Msg)
   918  		}
   919  	case cerr := <-lctx.Done():
   920  		t.Fatalf("test message timed out: %v", cerr)
   921  	}
   922  }
   923  
   924  type Job struct {
   925  	Msg      []byte
   926  	SendNode enode.ID
   927  	RecvNode enode.ID
   928  }
   929  
   930  func worker(id int, jobs <-chan Job, rpcs map[enode.ID]*rpc.Client, pubkeys map[enode.ID]string, topic string) {
   931  	for j := range jobs {
   932  		rpcs[j.SendNode].Call(nil, "pss_sendAsym", pubkeys[j.RecvNode], topic, hexutil.Encode(j.Msg))
   933  	}
   934  }
   935  
   936  func TestNetwork(t *testing.T) {
   937  	t.Run("16/1000/4/sim", testNetwork)
   938  }
   939  
   940  // params in run name:
   941  // nodes/msgs/addrbytes/adaptertype
   942  // if adaptertype is exec uses execadapter, simadapter otherwise
   943  func TestNetwork2000(t *testing.T) {
   944  	//enableMetrics()
   945  
   946  	if !*longrunning {
   947  		t.Skip("run with --longrunning flag to run extensive network tests")
   948  	}
   949  	t.Run("3/2000/4/sim", testNetwork)
   950  	t.Run("4/2000/4/sim", testNetwork)
   951  	t.Run("8/2000/4/sim", testNetwork)
   952  	t.Run("16/2000/4/sim", testNetwork)
   953  }
   954  
   955  func TestNetwork5000(t *testing.T) {
   956  	//enableMetrics()
   957  
   958  	if !*longrunning {
   959  		t.Skip("run with --longrunning flag to run extensive network tests")
   960  	}
   961  	t.Run("3/5000/4/sim", testNetwork)
   962  	t.Run("4/5000/4/sim", testNetwork)
   963  	t.Run("8/5000/4/sim", testNetwork)
   964  	t.Run("16/5000/4/sim", testNetwork)
   965  }
   966  
   967  func TestNetwork10000(t *testing.T) {
   968  	//enableMetrics()
   969  
   970  	if !*longrunning {
   971  		t.Skip("run with --longrunning flag to run extensive network tests")
   972  	}
   973  	t.Run("3/10000/4/sim", testNetwork)
   974  	t.Run("4/10000/4/sim", testNetwork)
   975  	t.Run("8/10000/4/sim", testNetwork)
   976  }
   977  
   978  func testNetwork(t *testing.T) {
   979  	paramstring := strings.Split(t.Name(), "/")
   980  	nodecount, _ := strconv.ParseInt(paramstring[1], 10, 0)
   981  	msgcount, _ := strconv.ParseInt(paramstring[2], 10, 0)
   982  	addrsize, _ := strconv.ParseInt(paramstring[3], 10, 0)
   983  	adapter := paramstring[4]
   984  
   985  	log.Info("network test", "nodecount", nodecount, "msgcount", msgcount, "addrhintsize", addrsize)
   986  
   987  	nodes := make([]enode.ID, nodecount)
   988  	bzzaddrs := make(map[enode.ID]string, nodecount)
   989  	rpcs := make(map[enode.ID]*rpc.Client, nodecount)
   990  	pubkeys := make(map[enode.ID]string, nodecount)
   991  
   992  	sentmsgs := make([][]byte, msgcount)
   993  	recvmsgs := make([]bool, msgcount)
   994  	nodemsgcount := make(map[enode.ID]int, nodecount)
   995  
   996  	trigger := make(chan enode.ID)
   997  
   998  	var a adapters.NodeAdapter
   999  	if adapter == "exec" {
  1000  		dirname, err := ioutil.TempDir(".", "")
  1001  		if err != nil {
  1002  			t.Fatal(err)
  1003  		}
  1004  		a = adapters.NewExecAdapter(dirname)
  1005  	} else if adapter == "tcp" {
  1006  		a = adapters.NewTCPAdapter(newServices(false))
  1007  	} else if adapter == "sim" {
  1008  		a = adapters.NewSimAdapter(newServices(false))
  1009  	}
  1010  	net := simulations.NewNetwork(a, &simulations.NetworkConfig{
  1011  		ID: "0",
  1012  	})
  1013  	defer net.Shutdown()
  1014  
  1015  	f, err := os.Open(fmt.Sprintf("testdata/snapshot_%d.json", nodecount))
  1016  	if err != nil {
  1017  		t.Fatal(err)
  1018  	}
  1019  	jsonbyte, err := ioutil.ReadAll(f)
  1020  	if err != nil {
  1021  		t.Fatal(err)
  1022  	}
  1023  	var snap simulations.Snapshot
  1024  	err = json.Unmarshal(jsonbyte, &snap)
  1025  	if err != nil {
  1026  		t.Fatal(err)
  1027  	}
  1028  	err = net.Load(&snap)
  1029  	if err != nil {
  1030  		//TODO: Fix p2p simulation framework to not crash when loading 32-nodes
  1031  		//t.Fatal(err)
  1032  	}
  1033  
  1034  	time.Sleep(1 * time.Second)
  1035  
  1036  	triggerChecks := func(trigger chan enode.ID, id enode.ID, rpcclient *rpc.Client, topic string) error {
  1037  		msgC := make(chan APIMsg)
  1038  		ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
  1039  		defer cancel()
  1040  		sub, err := rpcclient.Subscribe(ctx, "pss", msgC, "receive", topic)
  1041  		if err != nil {
  1042  			t.Fatal(err)
  1043  		}
  1044  		go func() {
  1045  			defer sub.Unsubscribe()
  1046  			for {
  1047  				select {
  1048  				case recvmsg := <-msgC:
  1049  					idx, _ := binary.Uvarint(recvmsg.Msg)
  1050  					if !recvmsgs[idx] {
  1051  						log.Debug("msg recv", "idx", idx, "id", id)
  1052  						recvmsgs[idx] = true
  1053  						trigger <- id
  1054  					}
  1055  				case <-sub.Err():
  1056  					return
  1057  				}
  1058  			}
  1059  		}()
  1060  		return nil
  1061  	}
  1062  
  1063  	var topic string
  1064  	for i, nod := range net.GetNodes() {
  1065  		nodes[i] = nod.ID()
  1066  		rpcs[nodes[i]], err = nod.Client()
  1067  		if err != nil {
  1068  			t.Fatal(err)
  1069  		}
  1070  		if topic == "" {
  1071  			err = rpcs[nodes[i]].Call(&topic, "pss_stringToTopic", "foo:42")
  1072  			if err != nil {
  1073  				t.Fatal(err)
  1074  			}
  1075  		}
  1076  		var pubkey string
  1077  		err = rpcs[nodes[i]].Call(&pubkey, "pss_getPublicKey")
  1078  		if err != nil {
  1079  			t.Fatal(err)
  1080  		}
  1081  		pubkeys[nod.ID()] = pubkey
  1082  		var addrhex string
  1083  		err = rpcs[nodes[i]].Call(&addrhex, "pss_baseAddr")
  1084  		if err != nil {
  1085  			t.Fatal(err)
  1086  		}
  1087  		bzzaddrs[nodes[i]] = addrhex
  1088  		err = triggerChecks(trigger, nodes[i], rpcs[nodes[i]], topic)
  1089  		if err != nil {
  1090  			t.Fatal(err)
  1091  		}
  1092  	}
  1093  
  1094  	time.Sleep(1 * time.Second)
  1095  
  1096  	// setup workers
  1097  	jobs := make(chan Job, 10)
  1098  	for w := 1; w <= 10; w++ {
  1099  		go worker(w, jobs, rpcs, pubkeys, topic)
  1100  	}
  1101  
  1102  	time.Sleep(1 * time.Second)
  1103  
  1104  	for i := 0; i < int(msgcount); i++ {
  1105  		sendnodeidx := rand.Intn(int(nodecount))
  1106  		recvnodeidx := rand.Intn(int(nodecount - 1))
  1107  		if recvnodeidx >= sendnodeidx {
  1108  			recvnodeidx++
  1109  		}
  1110  		nodemsgcount[nodes[recvnodeidx]]++
  1111  		sentmsgs[i] = make([]byte, 8)
  1112  		c := binary.PutUvarint(sentmsgs[i], uint64(i))
  1113  		if c == 0 {
  1114  			t.Fatal("0 byte message")
  1115  		}
  1116  		if err != nil {
  1117  			t.Fatal(err)
  1118  		}
  1119  		err = rpcs[nodes[sendnodeidx]].Call(nil, "pss_setPeerPublicKey", pubkeys[nodes[recvnodeidx]], topic, bzzaddrs[nodes[recvnodeidx]])
  1120  		if err != nil {
  1121  			t.Fatal(err)
  1122  		}
  1123  
  1124  		jobs <- Job{
  1125  			Msg:      sentmsgs[i],
  1126  			SendNode: nodes[sendnodeidx],
  1127  			RecvNode: nodes[recvnodeidx],
  1128  		}
  1129  	}
  1130  
  1131  	finalmsgcount := 0
  1132  	ctx, cancel := context.WithTimeout(context.Background(), 120*time.Second)
  1133  	defer cancel()
  1134  outer:
  1135  	for i := 0; i < int(msgcount); i++ {
  1136  		select {
  1137  		case id := <-trigger:
  1138  			nodemsgcount[id]--
  1139  			finalmsgcount++
  1140  		case <-ctx.Done():
  1141  			log.Warn("timeout")
  1142  			break outer
  1143  		}
  1144  	}
  1145  
  1146  	for i, msg := range recvmsgs {
  1147  		if !msg {
  1148  			log.Debug("missing message", "idx", i)
  1149  		}
  1150  	}
  1151  	t.Logf("%d of %d messages received", finalmsgcount, msgcount)
  1152  
  1153  	if finalmsgcount != int(msgcount) {
  1154  		t.Fatalf("%d messages were not received", int(msgcount)-finalmsgcount)
  1155  	}
  1156  
  1157  }
  1158  
  1159  // check that in a network of a -> b -> c -> a
  1160  // a doesn't receive a sent message twice
  1161  func TestDeduplication(t *testing.T) {
  1162  	var err error
  1163  
  1164  	clients, err := setupNetwork(3, false)
  1165  	if err != nil {
  1166  		t.Fatal(err)
  1167  	}
  1168  
  1169  	var addrsize = 32
  1170  	var loaddrhex string
  1171  	err = clients[0].Call(&loaddrhex, "pss_baseAddr")
  1172  	if err != nil {
  1173  		t.Fatalf("rpc get node 1 baseaddr fail: %v", err)
  1174  	}
  1175  	loaddrhex = loaddrhex[:2+(addrsize*2)]
  1176  	var roaddrhex string
  1177  	err = clients[1].Call(&roaddrhex, "pss_baseAddr")
  1178  	if err != nil {
  1179  		t.Fatalf("rpc get node 2 baseaddr fail: %v", err)
  1180  	}
  1181  	roaddrhex = roaddrhex[:2+(addrsize*2)]
  1182  	var xoaddrhex string
  1183  	err = clients[2].Call(&xoaddrhex, "pss_baseAddr")
  1184  	if err != nil {
  1185  		t.Fatalf("rpc get node 3 baseaddr fail: %v", err)
  1186  	}
  1187  	xoaddrhex = xoaddrhex[:2+(addrsize*2)]
  1188  
  1189  	log.Info("peer", "l", loaddrhex, "r", roaddrhex, "x", xoaddrhex)
  1190  
  1191  	var topic string
  1192  	err = clients[0].Call(&topic, "pss_stringToTopic", "foo:42")
  1193  	if err != nil {
  1194  		t.Fatal(err)
  1195  	}
  1196  
  1197  	time.Sleep(time.Millisecond * 250)
  1198  
  1199  	// retrieve public key from pss instance
  1200  	// set this public key reciprocally
  1201  	var rpubkey string
  1202  	err = clients[1].Call(&rpubkey, "pss_getPublicKey")
  1203  	if err != nil {
  1204  		t.Fatalf("rpc get receivenode pubkey fail: %v", err)
  1205  	}
  1206  
  1207  	time.Sleep(time.Millisecond * 500) // replace with hive healthy code
  1208  
  1209  	rmsgC := make(chan APIMsg)
  1210  	rctx, cancel := context.WithTimeout(context.Background(), time.Second*1)
  1211  	defer cancel()
  1212  	rsub, err := clients[1].Subscribe(rctx, "pss", rmsgC, "receive", topic)
  1213  	log.Trace("rsub", "id", rsub)
  1214  	defer rsub.Unsubscribe()
  1215  
  1216  	// store public key for recipient
  1217  	// zero-length address means forward to all
  1218  	// we have just two peers, they will be in proxbin, and will both receive
  1219  	err = clients[0].Call(nil, "pss_setPeerPublicKey", rpubkey, topic, "0x")
  1220  	if err != nil {
  1221  		t.Fatal(err)
  1222  	}
  1223  
  1224  	// send and verify delivery
  1225  	rmsg := []byte("xyzzy")
  1226  	err = clients[0].Call(nil, "pss_sendAsym", rpubkey, topic, hexutil.Encode(rmsg))
  1227  	if err != nil {
  1228  		t.Fatal(err)
  1229  	}
  1230  
  1231  	var receivedok bool
  1232  OUTER:
  1233  	for {
  1234  		select {
  1235  		case <-rmsgC:
  1236  			if receivedok {
  1237  				t.Fatalf("duplicate message received")
  1238  			}
  1239  			receivedok = true
  1240  		case <-rctx.Done():
  1241  			break OUTER
  1242  		}
  1243  	}
  1244  	if !receivedok {
  1245  		t.Fatalf("message did not arrive")
  1246  	}
  1247  }
  1248  
  1249  // symmetric send performance with varying message sizes
  1250  func BenchmarkSymkeySend(b *testing.B) {
  1251  	b.Run(fmt.Sprintf("%d", 256), benchmarkSymKeySend)
  1252  	b.Run(fmt.Sprintf("%d", 1024), benchmarkSymKeySend)
  1253  	b.Run(fmt.Sprintf("%d", 1024*1024), benchmarkSymKeySend)
  1254  	b.Run(fmt.Sprintf("%d", 1024*1024*10), benchmarkSymKeySend)
  1255  	b.Run(fmt.Sprintf("%d", 1024*1024*100), benchmarkSymKeySend)
  1256  }
  1257  
  1258  func benchmarkSymKeySend(b *testing.B) {
  1259  	msgsizestring := strings.Split(b.Name(), "/")
  1260  	if len(msgsizestring) != 2 {
  1261  		b.Fatalf("benchmark called without msgsize param")
  1262  	}
  1263  	msgsize, err := strconv.ParseInt(msgsizestring[1], 10, 0)
  1264  	if err != nil {
  1265  		b.Fatalf("benchmark called with invalid msgsize param '%s': %v", msgsizestring[1], err)
  1266  	}
  1267  	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
  1268  	defer cancel()
  1269  	keys, err := wapi.NewKeyPair(ctx)
  1270  	privkey, err := w.GetPrivateKey(keys)
  1271  	ps := newTestPss(privkey, nil, nil)
  1272  	msg := make([]byte, msgsize)
  1273  	rand.Read(msg)
  1274  	topic := BytesToTopic([]byte("foo"))
  1275  	to := make(PssAddress, 32)
  1276  	copy(to[:], network.RandomAddr().Over())
  1277  	symkeyid, err := ps.GenerateSymmetricKey(topic, &to, true)
  1278  	if err != nil {
  1279  		b.Fatalf("could not generate symkey: %v", err)
  1280  	}
  1281  	symkey, err := ps.w.GetSymKey(symkeyid)
  1282  	if err != nil {
  1283  		b.Fatalf("could not retrieve symkey: %v", err)
  1284  	}
  1285  	ps.SetSymmetricKey(symkey, topic, &to, false)
  1286  
  1287  	b.ResetTimer()
  1288  	for i := 0; i < b.N; i++ {
  1289  		ps.SendSym(symkeyid, topic, msg)
  1290  	}
  1291  }
  1292  
  1293  // asymmetric send performance with varying message sizes
  1294  func BenchmarkAsymkeySend(b *testing.B) {
  1295  	b.Run(fmt.Sprintf("%d", 256), benchmarkAsymKeySend)
  1296  	b.Run(fmt.Sprintf("%d", 1024), benchmarkAsymKeySend)
  1297  	b.Run(fmt.Sprintf("%d", 1024*1024), benchmarkAsymKeySend)
  1298  	b.Run(fmt.Sprintf("%d", 1024*1024*10), benchmarkAsymKeySend)
  1299  	b.Run(fmt.Sprintf("%d", 1024*1024*100), benchmarkAsymKeySend)
  1300  }
  1301  
  1302  func benchmarkAsymKeySend(b *testing.B) {
  1303  	msgsizestring := strings.Split(b.Name(), "/")
  1304  	if len(msgsizestring) != 2 {
  1305  		b.Fatalf("benchmark called without msgsize param")
  1306  	}
  1307  	msgsize, err := strconv.ParseInt(msgsizestring[1], 10, 0)
  1308  	if err != nil {
  1309  		b.Fatalf("benchmark called with invalid msgsize param '%s': %v", msgsizestring[1], err)
  1310  	}
  1311  	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
  1312  	defer cancel()
  1313  	keys, err := wapi.NewKeyPair(ctx)
  1314  	privkey, err := w.GetPrivateKey(keys)
  1315  	ps := newTestPss(privkey, nil, nil)
  1316  	msg := make([]byte, msgsize)
  1317  	rand.Read(msg)
  1318  	topic := BytesToTopic([]byte("foo"))
  1319  	to := make(PssAddress, 32)
  1320  	copy(to[:], network.RandomAddr().Over())
  1321  	ps.SetPeerPublicKey(&privkey.PublicKey, topic, &to)
  1322  	b.ResetTimer()
  1323  	for i := 0; i < b.N; i++ {
  1324  		ps.SendAsym(common.ToHex(crypto.FromECDSAPub(&privkey.PublicKey)), topic, msg)
  1325  	}
  1326  }
  1327  func BenchmarkSymkeyBruteforceChangeaddr(b *testing.B) {
  1328  	for i := 100; i < 100000; i = i * 10 {
  1329  		for j := 32; j < 10000; j = j * 8 {
  1330  			b.Run(fmt.Sprintf("%d/%d", i, j), benchmarkSymkeyBruteforceChangeaddr)
  1331  		}
  1332  		//b.Run(fmt.Sprintf("%d", i), benchmarkSymkeyBruteforceChangeaddr)
  1333  	}
  1334  }
  1335  
  1336  // decrypt performance using symkey cache, worst case
  1337  // (decrypt key always last in cache)
  1338  func benchmarkSymkeyBruteforceChangeaddr(b *testing.B) {
  1339  	keycountstring := strings.Split(b.Name(), "/")
  1340  	cachesize := int64(0)
  1341  	var ps *Pss
  1342  	if len(keycountstring) < 2 {
  1343  		b.Fatalf("benchmark called without count param")
  1344  	}
  1345  	keycount, err := strconv.ParseInt(keycountstring[1], 10, 0)
  1346  	if err != nil {
  1347  		b.Fatalf("benchmark called with invalid count param '%s': %v", keycountstring[1], err)
  1348  	}
  1349  	if len(keycountstring) == 3 {
  1350  		cachesize, err = strconv.ParseInt(keycountstring[2], 10, 0)
  1351  		if err != nil {
  1352  			b.Fatalf("benchmark called with invalid cachesize '%s': %v", keycountstring[2], err)
  1353  		}
  1354  	}
  1355  	pssmsgs := make([]*PssMsg, 0, keycount)
  1356  	var keyid string
  1357  	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
  1358  	defer cancel()
  1359  	keys, err := wapi.NewKeyPair(ctx)
  1360  	privkey, err := w.GetPrivateKey(keys)
  1361  	if cachesize > 0 {
  1362  		ps = newTestPss(privkey, nil, &PssParams{SymKeyCacheCapacity: int(cachesize)})
  1363  	} else {
  1364  		ps = newTestPss(privkey, nil, nil)
  1365  	}
  1366  	topic := BytesToTopic([]byte("foo"))
  1367  	for i := 0; i < int(keycount); i++ {
  1368  		to := make(PssAddress, 32)
  1369  		copy(to[:], network.RandomAddr().Over())
  1370  		keyid, err = ps.GenerateSymmetricKey(topic, &to, true)
  1371  		if err != nil {
  1372  			b.Fatalf("cant generate symkey #%d: %v", i, err)
  1373  		}
  1374  		symkey, err := ps.w.GetSymKey(keyid)
  1375  		if err != nil {
  1376  			b.Fatalf("could not retrieve symkey %s: %v", keyid, err)
  1377  		}
  1378  		wparams := &whisper.MessageParams{
  1379  			TTL:      defaultWhisperTTL,
  1380  			KeySym:   symkey,
  1381  			Topic:    whisper.TopicType(topic),
  1382  			WorkTime: defaultWhisperWorkTime,
  1383  			PoW:      defaultWhisperPoW,
  1384  			Payload:  []byte("xyzzy"),
  1385  			Padding:  []byte("1234567890abcdef"),
  1386  		}
  1387  		woutmsg, err := whisper.NewSentMessage(wparams)
  1388  		if err != nil {
  1389  			b.Fatalf("could not create whisper message: %v", err)
  1390  		}
  1391  		env, err := woutmsg.Wrap(wparams)
  1392  		if err != nil {
  1393  			b.Fatalf("could not generate whisper envelope: %v", err)
  1394  		}
  1395  		ps.Register(&topic, func(msg []byte, p *p2p.Peer, asymmetric bool, keyid string) error {
  1396  			return nil
  1397  		})
  1398  		pssmsgs = append(pssmsgs, &PssMsg{
  1399  			To:      to,
  1400  			Payload: env,
  1401  		})
  1402  	}
  1403  	b.ResetTimer()
  1404  	for i := 0; i < b.N; i++ {
  1405  		if err := ps.process(pssmsgs[len(pssmsgs)-(i%len(pssmsgs))-1]); err != nil {
  1406  			b.Fatalf("pss processing failed: %v", err)
  1407  		}
  1408  	}
  1409  }
  1410  
  1411  func BenchmarkSymkeyBruteforceSameaddr(b *testing.B) {
  1412  	for i := 100; i < 100000; i = i * 10 {
  1413  		for j := 32; j < 10000; j = j * 8 {
  1414  			b.Run(fmt.Sprintf("%d/%d", i, j), benchmarkSymkeyBruteforceSameaddr)
  1415  		}
  1416  	}
  1417  }
  1418  
  1419  // decrypt performance using symkey cache, best case
  1420  // (decrypt key always first in cache)
  1421  func benchmarkSymkeyBruteforceSameaddr(b *testing.B) {
  1422  	var keyid string
  1423  	var ps *Pss
  1424  	cachesize := int64(0)
  1425  	keycountstring := strings.Split(b.Name(), "/")
  1426  	if len(keycountstring) < 2 {
  1427  		b.Fatalf("benchmark called without count param")
  1428  	}
  1429  	keycount, err := strconv.ParseInt(keycountstring[1], 10, 0)
  1430  	if err != nil {
  1431  		b.Fatalf("benchmark called with invalid count param '%s': %v", keycountstring[1], err)
  1432  	}
  1433  	if len(keycountstring) == 3 {
  1434  		cachesize, err = strconv.ParseInt(keycountstring[2], 10, 0)
  1435  		if err != nil {
  1436  			b.Fatalf("benchmark called with invalid cachesize '%s': %v", keycountstring[2], err)
  1437  		}
  1438  	}
  1439  	addr := make([]PssAddress, keycount)
  1440  	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
  1441  	defer cancel()
  1442  	keys, err := wapi.NewKeyPair(ctx)
  1443  	privkey, err := w.GetPrivateKey(keys)
  1444  	if cachesize > 0 {
  1445  		ps = newTestPss(privkey, nil, &PssParams{SymKeyCacheCapacity: int(cachesize)})
  1446  	} else {
  1447  		ps = newTestPss(privkey, nil, nil)
  1448  	}
  1449  	topic := BytesToTopic([]byte("foo"))
  1450  	for i := 0; i < int(keycount); i++ {
  1451  		copy(addr[i], network.RandomAddr().Over())
  1452  		keyid, err = ps.GenerateSymmetricKey(topic, &addr[i], true)
  1453  		if err != nil {
  1454  			b.Fatalf("cant generate symkey #%d: %v", i, err)
  1455  		}
  1456  
  1457  	}
  1458  	symkey, err := ps.w.GetSymKey(keyid)
  1459  	if err != nil {
  1460  		b.Fatalf("could not retrieve symkey %s: %v", keyid, err)
  1461  	}
  1462  	wparams := &whisper.MessageParams{
  1463  		TTL:      defaultWhisperTTL,
  1464  		KeySym:   symkey,
  1465  		Topic:    whisper.TopicType(topic),
  1466  		WorkTime: defaultWhisperWorkTime,
  1467  		PoW:      defaultWhisperPoW,
  1468  		Payload:  []byte("xyzzy"),
  1469  		Padding:  []byte("1234567890abcdef"),
  1470  	}
  1471  	woutmsg, err := whisper.NewSentMessage(wparams)
  1472  	if err != nil {
  1473  		b.Fatalf("could not create whisper message: %v", err)
  1474  	}
  1475  	env, err := woutmsg.Wrap(wparams)
  1476  	if err != nil {
  1477  		b.Fatalf("could not generate whisper envelope: %v", err)
  1478  	}
  1479  	ps.Register(&topic, func(msg []byte, p *p2p.Peer, asymmetric bool, keyid string) error {
  1480  		return nil
  1481  	})
  1482  	pssmsg := &PssMsg{
  1483  		To:      addr[len(addr)-1][:],
  1484  		Payload: env,
  1485  	}
  1486  	for i := 0; i < b.N; i++ {
  1487  		if err := ps.process(pssmsg); err != nil {
  1488  			b.Fatalf("pss processing failed: %v", err)
  1489  		}
  1490  	}
  1491  }
  1492  
  1493  // setup simulated network with bzz/discovery and pss services.
  1494  // connects nodes in a circle
  1495  // if allowRaw is set, omission of builtin pss encryption is enabled (see PssParams)
  1496  func setupNetwork(numnodes int, allowRaw bool) (clients []*rpc.Client, err error) {
  1497  	nodes := make([]*simulations.Node, numnodes)
  1498  	clients = make([]*rpc.Client, numnodes)
  1499  	if numnodes < 2 {
  1500  		return nil, fmt.Errorf("Minimum two nodes in network")
  1501  	}
  1502  	adapter := adapters.NewSimAdapter(newServices(allowRaw))
  1503  	net := simulations.NewNetwork(adapter, &simulations.NetworkConfig{
  1504  		ID:             "0",
  1505  		DefaultService: "bzz",
  1506  	})
  1507  	for i := 0; i < numnodes; i++ {
  1508  		nodeconf := adapters.RandomNodeConfig()
  1509  		nodeconf.Services = []string{"bzz", pssProtocolName}
  1510  		nodes[i], err = net.NewNodeWithConfig(nodeconf)
  1511  		if err != nil {
  1512  			return nil, fmt.Errorf("error creating node 1: %v", err)
  1513  		}
  1514  		err = net.Start(nodes[i].ID())
  1515  		if err != nil {
  1516  			return nil, fmt.Errorf("error starting node 1: %v", err)
  1517  		}
  1518  		if i > 0 {
  1519  			err = net.Connect(nodes[i].ID(), nodes[i-1].ID())
  1520  			if err != nil {
  1521  				return nil, fmt.Errorf("error connecting nodes: %v", err)
  1522  			}
  1523  		}
  1524  		clients[i], err = nodes[i].Client()
  1525  		if err != nil {
  1526  			return nil, fmt.Errorf("create node 1 rpc client fail: %v", err)
  1527  		}
  1528  	}
  1529  	if numnodes > 2 {
  1530  		err = net.Connect(nodes[0].ID(), nodes[len(nodes)-1].ID())
  1531  		if err != nil {
  1532  			return nil, fmt.Errorf("error connecting first and last nodes")
  1533  		}
  1534  	}
  1535  	return clients, nil
  1536  }
  1537  
  1538  func newServices(allowRaw bool) adapters.Services {
  1539  	stateStore := state.NewInmemoryStore()
  1540  	kademlias := make(map[enode.ID]*network.Kademlia)
  1541  	kademlia := func(id enode.ID) *network.Kademlia {
  1542  		if k, ok := kademlias[id]; ok {
  1543  			return k
  1544  		}
  1545  		params := network.NewKadParams()
  1546  		params.MinProxBinSize = 2
  1547  		params.MaxBinSize = 3
  1548  		params.MinBinSize = 1
  1549  		params.MaxRetries = 1000
  1550  		params.RetryExponent = 2
  1551  		params.RetryInterval = 1000000
  1552  		kademlias[id] = network.NewKademlia(id[:], params)
  1553  		return kademlias[id]
  1554  	}
  1555  	return adapters.Services{
  1556  		pssProtocolName: func(ctx *adapters.ServiceContext) (node.Service, error) {
  1557  			// execadapter does not exec init()
  1558  			initTest()
  1559  
  1560  			ctxlocal, cancel := context.WithTimeout(context.Background(), time.Second)
  1561  			defer cancel()
  1562  			keys, err := wapi.NewKeyPair(ctxlocal)
  1563  			privkey, err := w.GetPrivateKey(keys)
  1564  			pssp := NewPssParams().WithPrivateKey(privkey)
  1565  			pssp.AllowRaw = allowRaw
  1566  			pskad := kademlia(ctx.Config.ID)
  1567  			ps, err := NewPss(pskad, pssp)
  1568  			if err != nil {
  1569  				return nil, err
  1570  			}
  1571  
  1572  			ping := &Ping{
  1573  				OutC: make(chan bool),
  1574  				Pong: true,
  1575  			}
  1576  			p2pp := NewPingProtocol(ping)
  1577  			pp, err := RegisterProtocol(ps, &PingTopic, PingProtocol, p2pp, &ProtocolParams{Asymmetric: true})
  1578  			if err != nil {
  1579  				return nil, err
  1580  			}
  1581  			if useHandshake {
  1582  				SetHandshakeController(ps, NewHandshakeParams())
  1583  			}
  1584  			ps.Register(&PingTopic, pp.Handle)
  1585  			ps.addAPI(rpc.API{
  1586  				Namespace: "psstest",
  1587  				Version:   "0.3",
  1588  				Service:   NewAPITest(ps),
  1589  				Public:    false,
  1590  			})
  1591  			if err != nil {
  1592  				log.Error("Couldnt register pss protocol", "err", err)
  1593  				os.Exit(1)
  1594  			}
  1595  			pssprotocols[ctx.Config.ID.String()] = &protoCtrl{
  1596  				C:        ping.OutC,
  1597  				protocol: pp,
  1598  				run:      p2pp.Run,
  1599  			}
  1600  			return ps, nil
  1601  		},
  1602  		"bzz": func(ctx *adapters.ServiceContext) (node.Service, error) {
  1603  			addr := network.NewAddr(ctx.Config.Node())
  1604  			hp := network.NewHiveParams()
  1605  			hp.Discovery = false
  1606  			config := &network.BzzConfig{
  1607  				OverlayAddr:  addr.Over(),
  1608  				UnderlayAddr: addr.Under(),
  1609  				HiveParams:   hp,
  1610  			}
  1611  			return network.NewBzz(config, kademlia(ctx.Config.ID), stateStore, nil, nil), nil
  1612  		},
  1613  	}
  1614  }
  1615  
  1616  func newTestPss(privkey *ecdsa.PrivateKey, kad *network.Kademlia, ppextra *PssParams) *Pss {
  1617  	nid := enode.PubkeyToIDV4(&privkey.PublicKey)
  1618  	// set up routing if kademlia is not passed to us
  1619  	if kad == nil {
  1620  		kp := network.NewKadParams()
  1621  		kp.MinProxBinSize = 3
  1622  		kad = network.NewKademlia(nid[:], kp)
  1623  	}
  1624  
  1625  	// create pss
  1626  	pp := NewPssParams().WithPrivateKey(privkey)
  1627  	if ppextra != nil {
  1628  		pp.SymKeyCacheCapacity = ppextra.SymKeyCacheCapacity
  1629  	}
  1630  	ps, err := NewPss(kad, pp)
  1631  	if err != nil {
  1632  		return nil
  1633  	}
  1634  	ps.Start(nil)
  1635  
  1636  	return ps
  1637  }
  1638  
  1639  // API calls for test/development use
  1640  type APITest struct {
  1641  	*Pss
  1642  }
  1643  
  1644  func NewAPITest(ps *Pss) *APITest {
  1645  	return &APITest{Pss: ps}
  1646  }
  1647  
  1648  func (apitest *APITest) SetSymKeys(pubkeyid string, recvsymkey []byte, sendsymkey []byte, limit uint16, topic Topic, to PssAddress) ([2]string, error) {
  1649  	recvsymkeyid, err := apitest.SetSymmetricKey(recvsymkey, topic, &to, true)
  1650  	if err != nil {
  1651  		return [2]string{}, err
  1652  	}
  1653  	sendsymkeyid, err := apitest.SetSymmetricKey(sendsymkey, topic, &to, false)
  1654  	if err != nil {
  1655  		return [2]string{}, err
  1656  	}
  1657  	return [2]string{recvsymkeyid, sendsymkeyid}, nil
  1658  }
  1659  
  1660  func (apitest *APITest) Clean() (int, error) {
  1661  	return apitest.Pss.cleanKeys(), nil
  1662  }
  1663  
  1664  // enableMetrics is starting InfluxDB reporter so that we collect stats when running tests locally
  1665  func enableMetrics() {
  1666  	metrics.Enabled = true
  1667  	go influxdb.InfluxDBWithTags(metrics.DefaultRegistry, 1*time.Second, "http://localhost:8086", "metrics", "admin", "admin", "swarm.", map[string]string{
  1668  		"host": "test",
  1669  	})
  1670  }