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