github.com/shyftnetwork/go-empyrean@v1.8.3-0.20191127201940-fbfca9338f04/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/ShyftNetwork/go-empyrean/common"
    38  	"github.com/ShyftNetwork/go-empyrean/common/hexutil"
    39  	"github.com/ShyftNetwork/go-empyrean/crypto"
    40  	"github.com/ShyftNetwork/go-empyrean/log"
    41  	"github.com/ShyftNetwork/go-empyrean/metrics"
    42  	"github.com/ShyftNetwork/go-empyrean/metrics/influxdb"
    43  	"github.com/ShyftNetwork/go-empyrean/node"
    44  	"github.com/ShyftNetwork/go-empyrean/p2p"
    45  	"github.com/ShyftNetwork/go-empyrean/p2p/enode"
    46  	"github.com/ShyftNetwork/go-empyrean/p2p/protocols"
    47  	"github.com/ShyftNetwork/go-empyrean/p2p/simulations"
    48  	"github.com/ShyftNetwork/go-empyrean/p2p/simulations/adapters"
    49  	"github.com/ShyftNetwork/go-empyrean/rpc"
    50  	"github.com/ShyftNetwork/go-empyrean/swarm/network"
    51  	"github.com/ShyftNetwork/go-empyrean/swarm/pot"
    52  	"github.com/ShyftNetwork/go-empyrean/swarm/state"
    53  	whisper "github.com/ShyftNetwork/go-empyrean/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  	depth := kad.NeighbourhoodDepth()
   495  	kad.EachConn(nil, peerCount, func(p *network.Peer, po int) bool {
   496  		conns++
   497  		if po >= depth {
   498  			proxes++
   499  		}
   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 !bytes.Equal(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  // BELOW HERE ARE TESTS USING THE SIMULATION FRAMEWORK
  1012  
  1013  // tests that the API layer can handle edge case values
  1014  func TestApi(t *testing.T) {
  1015  	clients, err := setupNetwork(2, true)
  1016  	if err != nil {
  1017  		t.Fatal(err)
  1018  	}
  1019  
  1020  	topic := "0xdeadbeef"
  1021  
  1022  	err = clients[0].Call(nil, "pss_sendRaw", "0x", topic, "0x666f6f")
  1023  	if err != nil {
  1024  		t.Fatal(err)
  1025  	}
  1026  
  1027  	err = clients[0].Call(nil, "pss_sendRaw", "0xabcdef", topic, "0x")
  1028  	if err == nil {
  1029  		t.Fatal("expected error on empty msg")
  1030  	}
  1031  
  1032  	overflowAddr := [33]byte{}
  1033  	err = clients[0].Call(nil, "pss_sendRaw", hexutil.Encode(overflowAddr[:]), topic, "0x666f6f")
  1034  	if err == nil {
  1035  		t.Fatal("expected error on send too big address")
  1036  	}
  1037  }
  1038  
  1039  // verifies that nodes can send and receive raw (verbatim) messages
  1040  func TestSendRaw(t *testing.T) {
  1041  	t.Run("32", testSendRaw)
  1042  	t.Run("8", testSendRaw)
  1043  	t.Run("0", testSendRaw)
  1044  }
  1045  
  1046  func testSendRaw(t *testing.T) {
  1047  
  1048  	var addrsize int64
  1049  	var err error
  1050  
  1051  	paramstring := strings.Split(t.Name(), "/")
  1052  
  1053  	addrsize, _ = strconv.ParseInt(paramstring[1], 10, 0)
  1054  	log.Info("raw send test", "addrsize", addrsize)
  1055  
  1056  	clients, err := setupNetwork(2, true)
  1057  	if err != nil {
  1058  		t.Fatal(err)
  1059  	}
  1060  
  1061  	topic := "0xdeadbeef"
  1062  
  1063  	var loaddrhex string
  1064  	err = clients[0].Call(&loaddrhex, "pss_baseAddr")
  1065  	if err != nil {
  1066  		t.Fatalf("rpc get node 1 baseaddr fail: %v", err)
  1067  	}
  1068  	loaddrhex = loaddrhex[:2+(addrsize*2)]
  1069  	var roaddrhex string
  1070  	err = clients[1].Call(&roaddrhex, "pss_baseAddr")
  1071  	if err != nil {
  1072  		t.Fatalf("rpc get node 2 baseaddr fail: %v", err)
  1073  	}
  1074  	roaddrhex = roaddrhex[:2+(addrsize*2)]
  1075  
  1076  	time.Sleep(time.Millisecond * 500)
  1077  
  1078  	// at this point we've verified that symkeys are saved and match on each peer
  1079  	// now try sending symmetrically encrypted message, both directions
  1080  	lmsgC := make(chan APIMsg)
  1081  	lctx, lcancel := context.WithTimeout(context.Background(), time.Second*10)
  1082  	defer lcancel()
  1083  	lsub, err := clients[0].Subscribe(lctx, "pss", lmsgC, "receive", topic, true, false)
  1084  	log.Trace("lsub", "id", lsub)
  1085  	defer lsub.Unsubscribe()
  1086  	rmsgC := make(chan APIMsg)
  1087  	rctx, rcancel := context.WithTimeout(context.Background(), time.Second*10)
  1088  	defer rcancel()
  1089  	rsub, err := clients[1].Subscribe(rctx, "pss", rmsgC, "receive", topic, true, false)
  1090  	log.Trace("rsub", "id", rsub)
  1091  	defer rsub.Unsubscribe()
  1092  
  1093  	// send and verify delivery
  1094  	lmsg := []byte("plugh")
  1095  	err = clients[1].Call(nil, "pss_sendRaw", loaddrhex, topic, hexutil.Encode(lmsg))
  1096  	if err != nil {
  1097  		t.Fatal(err)
  1098  	}
  1099  	select {
  1100  	case recvmsg := <-lmsgC:
  1101  		if !bytes.Equal(recvmsg.Msg, lmsg) {
  1102  			t.Fatalf("node 1 received payload mismatch: expected %v, got %v", lmsg, recvmsg)
  1103  		}
  1104  	case cerr := <-lctx.Done():
  1105  		t.Fatalf("test message (left) timed out: %v", cerr)
  1106  	}
  1107  	rmsg := []byte("xyzzy")
  1108  	err = clients[0].Call(nil, "pss_sendRaw", roaddrhex, topic, hexutil.Encode(rmsg))
  1109  	if err != nil {
  1110  		t.Fatal(err)
  1111  	}
  1112  	select {
  1113  	case recvmsg := <-rmsgC:
  1114  		if !bytes.Equal(recvmsg.Msg, rmsg) {
  1115  			t.Fatalf("node 2 received payload mismatch: expected %x, got %v", rmsg, recvmsg.Msg)
  1116  		}
  1117  	case cerr := <-rctx.Done():
  1118  		t.Fatalf("test message (right) timed out: %v", cerr)
  1119  	}
  1120  }
  1121  
  1122  // send symmetrically encrypted message between two directly connected peers
  1123  func TestSendSym(t *testing.T) {
  1124  	t.Run("32", testSendSym)
  1125  	t.Run("8", testSendSym)
  1126  	t.Run("0", testSendSym)
  1127  }
  1128  
  1129  func testSendSym(t *testing.T) {
  1130  
  1131  	// address hint size
  1132  	var addrsize int64
  1133  	var err error
  1134  	paramstring := strings.Split(t.Name(), "/")
  1135  	addrsize, _ = strconv.ParseInt(paramstring[1], 10, 0)
  1136  	log.Info("sym send test", "addrsize", addrsize)
  1137  
  1138  	clients, err := setupNetwork(2, false)
  1139  	if err != nil {
  1140  		t.Fatal(err)
  1141  	}
  1142  
  1143  	var topic string
  1144  	err = clients[0].Call(&topic, "pss_stringToTopic", "foo:42")
  1145  	if err != nil {
  1146  		t.Fatal(err)
  1147  	}
  1148  
  1149  	var loaddrhex string
  1150  	err = clients[0].Call(&loaddrhex, "pss_baseAddr")
  1151  	if err != nil {
  1152  		t.Fatalf("rpc get node 1 baseaddr fail: %v", err)
  1153  	}
  1154  	loaddrhex = loaddrhex[:2+(addrsize*2)]
  1155  	var roaddrhex string
  1156  	err = clients[1].Call(&roaddrhex, "pss_baseAddr")
  1157  	if err != nil {
  1158  		t.Fatalf("rpc get node 2 baseaddr fail: %v", err)
  1159  	}
  1160  	roaddrhex = roaddrhex[:2+(addrsize*2)]
  1161  
  1162  	// retrieve public key from pss instance
  1163  	// set this public key reciprocally
  1164  	var lpubkeyhex string
  1165  	err = clients[0].Call(&lpubkeyhex, "pss_getPublicKey")
  1166  	if err != nil {
  1167  		t.Fatalf("rpc get node 1 pubkey fail: %v", err)
  1168  	}
  1169  	var rpubkeyhex string
  1170  	err = clients[1].Call(&rpubkeyhex, "pss_getPublicKey")
  1171  	if err != nil {
  1172  		t.Fatalf("rpc get node 2 pubkey fail: %v", err)
  1173  	}
  1174  
  1175  	time.Sleep(time.Millisecond * 500)
  1176  
  1177  	// at this point we've verified that symkeys are saved and match on each peer
  1178  	// now try sending symmetrically encrypted message, both directions
  1179  	lmsgC := make(chan APIMsg)
  1180  	lctx, lcancel := context.WithTimeout(context.Background(), time.Second*10)
  1181  	defer lcancel()
  1182  	lsub, err := clients[0].Subscribe(lctx, "pss", lmsgC, "receive", topic, false, false)
  1183  	log.Trace("lsub", "id", lsub)
  1184  	defer lsub.Unsubscribe()
  1185  	rmsgC := make(chan APIMsg)
  1186  	rctx, rcancel := context.WithTimeout(context.Background(), time.Second*10)
  1187  	defer rcancel()
  1188  	rsub, err := clients[1].Subscribe(rctx, "pss", rmsgC, "receive", topic, false, false)
  1189  	log.Trace("rsub", "id", rsub)
  1190  	defer rsub.Unsubscribe()
  1191  
  1192  	lrecvkey := network.RandomAddr().Over()
  1193  	rrecvkey := network.RandomAddr().Over()
  1194  
  1195  	var lkeyids [2]string
  1196  	var rkeyids [2]string
  1197  
  1198  	// manually set reciprocal symkeys
  1199  	err = clients[0].Call(&lkeyids, "psstest_setSymKeys", rpubkeyhex, lrecvkey, rrecvkey, defaultSymKeySendLimit, topic, roaddrhex)
  1200  	if err != nil {
  1201  		t.Fatal(err)
  1202  	}
  1203  	err = clients[1].Call(&rkeyids, "psstest_setSymKeys", lpubkeyhex, rrecvkey, lrecvkey, defaultSymKeySendLimit, topic, loaddrhex)
  1204  	if err != nil {
  1205  		t.Fatal(err)
  1206  	}
  1207  
  1208  	// send and verify delivery
  1209  	lmsg := []byte("plugh")
  1210  	err = clients[1].Call(nil, "pss_sendSym", rkeyids[1], topic, hexutil.Encode(lmsg))
  1211  	if err != nil {
  1212  		t.Fatal(err)
  1213  	}
  1214  	select {
  1215  	case recvmsg := <-lmsgC:
  1216  		if !bytes.Equal(recvmsg.Msg, lmsg) {
  1217  			t.Fatalf("node 1 received payload mismatch: expected %v, got %v", lmsg, recvmsg)
  1218  		}
  1219  	case cerr := <-lctx.Done():
  1220  		t.Fatalf("test message timed out: %v", cerr)
  1221  	}
  1222  	rmsg := []byte("xyzzy")
  1223  	err = clients[0].Call(nil, "pss_sendSym", lkeyids[1], topic, hexutil.Encode(rmsg))
  1224  	if err != nil {
  1225  		t.Fatal(err)
  1226  	}
  1227  	select {
  1228  	case recvmsg := <-rmsgC:
  1229  		if !bytes.Equal(recvmsg.Msg, rmsg) {
  1230  			t.Fatalf("node 2 received payload mismatch: expected %x, got %v", rmsg, recvmsg.Msg)
  1231  		}
  1232  	case cerr := <-rctx.Done():
  1233  		t.Fatalf("test message timed out: %v", cerr)
  1234  	}
  1235  }
  1236  
  1237  // send asymmetrically encrypted message between two directly connected peers
  1238  func TestSendAsym(t *testing.T) {
  1239  	t.Run("32", testSendAsym)
  1240  	t.Run("8", testSendAsym)
  1241  	t.Run("0", testSendAsym)
  1242  }
  1243  
  1244  func testSendAsym(t *testing.T) {
  1245  
  1246  	// address hint size
  1247  	var addrsize int64
  1248  	var err error
  1249  	paramstring := strings.Split(t.Name(), "/")
  1250  	addrsize, _ = strconv.ParseInt(paramstring[1], 10, 0)
  1251  	log.Info("asym send test", "addrsize", addrsize)
  1252  
  1253  	clients, err := setupNetwork(2, false)
  1254  	if err != nil {
  1255  		t.Fatal(err)
  1256  	}
  1257  
  1258  	var topic string
  1259  	err = clients[0].Call(&topic, "pss_stringToTopic", "foo:42")
  1260  	if err != nil {
  1261  		t.Fatal(err)
  1262  	}
  1263  
  1264  	time.Sleep(time.Millisecond * 250)
  1265  
  1266  	var loaddrhex string
  1267  	err = clients[0].Call(&loaddrhex, "pss_baseAddr")
  1268  	if err != nil {
  1269  		t.Fatalf("rpc get node 1 baseaddr fail: %v", err)
  1270  	}
  1271  	loaddrhex = loaddrhex[:2+(addrsize*2)]
  1272  	var roaddrhex string
  1273  	err = clients[1].Call(&roaddrhex, "pss_baseAddr")
  1274  	if err != nil {
  1275  		t.Fatalf("rpc get node 2 baseaddr fail: %v", err)
  1276  	}
  1277  	roaddrhex = roaddrhex[:2+(addrsize*2)]
  1278  
  1279  	// retrieve public key from pss instance
  1280  	// set this public key reciprocally
  1281  	var lpubkey string
  1282  	err = clients[0].Call(&lpubkey, "pss_getPublicKey")
  1283  	if err != nil {
  1284  		t.Fatalf("rpc get node 1 pubkey fail: %v", err)
  1285  	}
  1286  	var rpubkey string
  1287  	err = clients[1].Call(&rpubkey, "pss_getPublicKey")
  1288  	if err != nil {
  1289  		t.Fatalf("rpc get node 2 pubkey fail: %v", err)
  1290  	}
  1291  
  1292  	time.Sleep(time.Millisecond * 500) // replace with hive healthy code
  1293  
  1294  	lmsgC := make(chan APIMsg)
  1295  	lctx, lcancel := context.WithTimeout(context.Background(), time.Second*10)
  1296  	defer lcancel()
  1297  	lsub, err := clients[0].Subscribe(lctx, "pss", lmsgC, "receive", topic, false, false)
  1298  	log.Trace("lsub", "id", lsub)
  1299  	defer lsub.Unsubscribe()
  1300  	rmsgC := make(chan APIMsg)
  1301  	rctx, rcancel := context.WithTimeout(context.Background(), time.Second*10)
  1302  	defer rcancel()
  1303  	rsub, err := clients[1].Subscribe(rctx, "pss", rmsgC, "receive", topic, false, false)
  1304  	log.Trace("rsub", "id", rsub)
  1305  	defer rsub.Unsubscribe()
  1306  
  1307  	// store reciprocal public keys
  1308  	err = clients[0].Call(nil, "pss_setPeerPublicKey", rpubkey, topic, roaddrhex)
  1309  	if err != nil {
  1310  		t.Fatal(err)
  1311  	}
  1312  	err = clients[1].Call(nil, "pss_setPeerPublicKey", lpubkey, topic, loaddrhex)
  1313  	if err != nil {
  1314  		t.Fatal(err)
  1315  	}
  1316  
  1317  	// send and verify delivery
  1318  	rmsg := []byte("xyzzy")
  1319  	err = clients[0].Call(nil, "pss_sendAsym", rpubkey, topic, hexutil.Encode(rmsg))
  1320  	if err != nil {
  1321  		t.Fatal(err)
  1322  	}
  1323  	select {
  1324  	case recvmsg := <-rmsgC:
  1325  		if !bytes.Equal(recvmsg.Msg, rmsg) {
  1326  			t.Fatalf("node 2 received payload mismatch: expected %v, got %v", rmsg, recvmsg.Msg)
  1327  		}
  1328  	case cerr := <-rctx.Done():
  1329  		t.Fatalf("test message timed out: %v", cerr)
  1330  	}
  1331  	lmsg := []byte("plugh")
  1332  	err = clients[1].Call(nil, "pss_sendAsym", lpubkey, topic, hexutil.Encode(lmsg))
  1333  	if err != nil {
  1334  		t.Fatal(err)
  1335  	}
  1336  	select {
  1337  	case recvmsg := <-lmsgC:
  1338  		if !bytes.Equal(recvmsg.Msg, lmsg) {
  1339  			t.Fatalf("node 1 received payload mismatch: expected %v, got %v", lmsg, recvmsg.Msg)
  1340  		}
  1341  	case cerr := <-lctx.Done():
  1342  		t.Fatalf("test message timed out: %v", cerr)
  1343  	}
  1344  }
  1345  
  1346  type Job struct {
  1347  	Msg      []byte
  1348  	SendNode enode.ID
  1349  	RecvNode enode.ID
  1350  }
  1351  
  1352  func worker(id int, jobs <-chan Job, rpcs map[enode.ID]*rpc.Client, pubkeys map[enode.ID]string, topic string) {
  1353  	for j := range jobs {
  1354  		rpcs[j.SendNode].Call(nil, "pss_sendAsym", pubkeys[j.RecvNode], topic, hexutil.Encode(j.Msg))
  1355  	}
  1356  }
  1357  
  1358  func TestNetwork(t *testing.T) {
  1359  	t.Run("16/1000/4/sim", testNetwork)
  1360  }
  1361  
  1362  // params in run name:
  1363  // nodes/msgs/addrbytes/adaptertype
  1364  // if adaptertype is exec uses execadapter, simadapter otherwise
  1365  func TestNetwork2000(t *testing.T) {
  1366  	//enableMetrics()
  1367  
  1368  	if !*longrunning {
  1369  		t.Skip("run with --longrunning flag to run extensive network tests")
  1370  	}
  1371  	t.Run("3/2000/4/sim", testNetwork)
  1372  	t.Run("4/2000/4/sim", testNetwork)
  1373  	t.Run("8/2000/4/sim", testNetwork)
  1374  	t.Run("16/2000/4/sim", testNetwork)
  1375  }
  1376  
  1377  func TestNetwork5000(t *testing.T) {
  1378  	//enableMetrics()
  1379  
  1380  	if !*longrunning {
  1381  		t.Skip("run with --longrunning flag to run extensive network tests")
  1382  	}
  1383  	t.Run("3/5000/4/sim", testNetwork)
  1384  	t.Run("4/5000/4/sim", testNetwork)
  1385  	t.Run("8/5000/4/sim", testNetwork)
  1386  	t.Run("16/5000/4/sim", testNetwork)
  1387  }
  1388  
  1389  func TestNetwork10000(t *testing.T) {
  1390  	//enableMetrics()
  1391  
  1392  	if !*longrunning {
  1393  		t.Skip("run with --longrunning flag to run extensive network tests")
  1394  	}
  1395  	t.Run("3/10000/4/sim", testNetwork)
  1396  	t.Run("4/10000/4/sim", testNetwork)
  1397  	t.Run("8/10000/4/sim", testNetwork)
  1398  }
  1399  
  1400  func testNetwork(t *testing.T) {
  1401  	paramstring := strings.Split(t.Name(), "/")
  1402  	nodecount, _ := strconv.ParseInt(paramstring[1], 10, 0)
  1403  	msgcount, _ := strconv.ParseInt(paramstring[2], 10, 0)
  1404  	addrsize, _ := strconv.ParseInt(paramstring[3], 10, 0)
  1405  	adapter := paramstring[4]
  1406  
  1407  	log.Info("network test", "nodecount", nodecount, "msgcount", msgcount, "addrhintsize", addrsize)
  1408  
  1409  	nodes := make([]enode.ID, nodecount)
  1410  	bzzaddrs := make(map[enode.ID]string, nodecount)
  1411  	rpcs := make(map[enode.ID]*rpc.Client, nodecount)
  1412  	pubkeys := make(map[enode.ID]string, nodecount)
  1413  
  1414  	sentmsgs := make([][]byte, msgcount)
  1415  	recvmsgs := make([]bool, msgcount)
  1416  	nodemsgcount := make(map[enode.ID]int, nodecount)
  1417  
  1418  	trigger := make(chan enode.ID)
  1419  
  1420  	var a adapters.NodeAdapter
  1421  	if adapter == "exec" {
  1422  		dirname, err := ioutil.TempDir(".", "")
  1423  		if err != nil {
  1424  			t.Fatal(err)
  1425  		}
  1426  		a = adapters.NewExecAdapter(dirname)
  1427  	} else if adapter == "tcp" {
  1428  		a = adapters.NewTCPAdapter(newServices(false))
  1429  	} else if adapter == "sim" {
  1430  		a = adapters.NewSimAdapter(newServices(false))
  1431  	}
  1432  	net := simulations.NewNetwork(a, &simulations.NetworkConfig{
  1433  		ID: "0",
  1434  	})
  1435  	defer net.Shutdown()
  1436  
  1437  	f, err := os.Open(fmt.Sprintf("testdata/snapshot_%d.json", nodecount))
  1438  	if err != nil {
  1439  		t.Fatal(err)
  1440  	}
  1441  	jsonbyte, err := ioutil.ReadAll(f)
  1442  	if err != nil {
  1443  		t.Fatal(err)
  1444  	}
  1445  	var snap simulations.Snapshot
  1446  	err = json.Unmarshal(jsonbyte, &snap)
  1447  	if err != nil {
  1448  		t.Fatal(err)
  1449  	}
  1450  	err = net.Load(&snap)
  1451  	if err != nil {
  1452  		//TODO: Fix p2p simulation framework to not crash when loading 32-nodes
  1453  		//t.Fatal(err)
  1454  	}
  1455  
  1456  	time.Sleep(1 * time.Second)
  1457  
  1458  	triggerChecks := func(trigger chan enode.ID, id enode.ID, rpcclient *rpc.Client, topic string) error {
  1459  		msgC := make(chan APIMsg)
  1460  		ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
  1461  		defer cancel()
  1462  		sub, err := rpcclient.Subscribe(ctx, "pss", msgC, "receive", topic, false, false)
  1463  		if err != nil {
  1464  			t.Fatal(err)
  1465  		}
  1466  		go func() {
  1467  			defer sub.Unsubscribe()
  1468  			for {
  1469  				select {
  1470  				case recvmsg := <-msgC:
  1471  					idx, _ := binary.Uvarint(recvmsg.Msg)
  1472  					if !recvmsgs[idx] {
  1473  						log.Debug("msg recv", "idx", idx, "id", id)
  1474  						recvmsgs[idx] = true
  1475  						trigger <- id
  1476  					}
  1477  				case <-sub.Err():
  1478  					return
  1479  				}
  1480  			}
  1481  		}()
  1482  		return nil
  1483  	}
  1484  
  1485  	var topic string
  1486  	for i, nod := range net.GetNodes() {
  1487  		nodes[i] = nod.ID()
  1488  		rpcs[nodes[i]], err = nod.Client()
  1489  		if err != nil {
  1490  			t.Fatal(err)
  1491  		}
  1492  		if topic == "" {
  1493  			err = rpcs[nodes[i]].Call(&topic, "pss_stringToTopic", "foo:42")
  1494  			if err != nil {
  1495  				t.Fatal(err)
  1496  			}
  1497  		}
  1498  		var pubkey string
  1499  		err = rpcs[nodes[i]].Call(&pubkey, "pss_getPublicKey")
  1500  		if err != nil {
  1501  			t.Fatal(err)
  1502  		}
  1503  		pubkeys[nod.ID()] = pubkey
  1504  		var addrhex string
  1505  		err = rpcs[nodes[i]].Call(&addrhex, "pss_baseAddr")
  1506  		if err != nil {
  1507  			t.Fatal(err)
  1508  		}
  1509  		bzzaddrs[nodes[i]] = addrhex
  1510  		err = triggerChecks(trigger, nodes[i], rpcs[nodes[i]], topic)
  1511  		if err != nil {
  1512  			t.Fatal(err)
  1513  		}
  1514  	}
  1515  
  1516  	time.Sleep(1 * time.Second)
  1517  
  1518  	// setup workers
  1519  	jobs := make(chan Job, 10)
  1520  	for w := 1; w <= 10; w++ {
  1521  		go worker(w, jobs, rpcs, pubkeys, topic)
  1522  	}
  1523  
  1524  	time.Sleep(1 * time.Second)
  1525  
  1526  	for i := 0; i < int(msgcount); i++ {
  1527  		sendnodeidx := rand.Intn(int(nodecount))
  1528  		recvnodeidx := rand.Intn(int(nodecount - 1))
  1529  		if recvnodeidx >= sendnodeidx {
  1530  			recvnodeidx++
  1531  		}
  1532  		nodemsgcount[nodes[recvnodeidx]]++
  1533  		sentmsgs[i] = make([]byte, 8)
  1534  		c := binary.PutUvarint(sentmsgs[i], uint64(i))
  1535  		if c == 0 {
  1536  			t.Fatal("0 byte message")
  1537  		}
  1538  		if err != nil {
  1539  			t.Fatal(err)
  1540  		}
  1541  		err = rpcs[nodes[sendnodeidx]].Call(nil, "pss_setPeerPublicKey", pubkeys[nodes[recvnodeidx]], topic, bzzaddrs[nodes[recvnodeidx]])
  1542  		if err != nil {
  1543  			t.Fatal(err)
  1544  		}
  1545  
  1546  		jobs <- Job{
  1547  			Msg:      sentmsgs[i],
  1548  			SendNode: nodes[sendnodeidx],
  1549  			RecvNode: nodes[recvnodeidx],
  1550  		}
  1551  	}
  1552  
  1553  	finalmsgcount := 0
  1554  	ctx, cancel := context.WithTimeout(context.Background(), 120*time.Second)
  1555  	defer cancel()
  1556  outer:
  1557  	for i := 0; i < int(msgcount); i++ {
  1558  		select {
  1559  		case id := <-trigger:
  1560  			nodemsgcount[id]--
  1561  			finalmsgcount++
  1562  		case <-ctx.Done():
  1563  			log.Warn("timeout")
  1564  			break outer
  1565  		}
  1566  	}
  1567  
  1568  	for i, msg := range recvmsgs {
  1569  		if !msg {
  1570  			log.Debug("missing message", "idx", i)
  1571  		}
  1572  	}
  1573  	t.Logf("%d of %d messages received", finalmsgcount, msgcount)
  1574  
  1575  	if finalmsgcount != int(msgcount) {
  1576  		t.Fatalf("%d messages were not received", int(msgcount)-finalmsgcount)
  1577  	}
  1578  
  1579  }
  1580  
  1581  // check that in a network of a -> b -> c -> a
  1582  // a doesn't receive a sent message twice
  1583  func TestDeduplication(t *testing.T) {
  1584  	var err error
  1585  
  1586  	clients, err := setupNetwork(3, false)
  1587  	if err != nil {
  1588  		t.Fatal(err)
  1589  	}
  1590  
  1591  	var addrsize = 32
  1592  	var loaddrhex string
  1593  	err = clients[0].Call(&loaddrhex, "pss_baseAddr")
  1594  	if err != nil {
  1595  		t.Fatalf("rpc get node 1 baseaddr fail: %v", err)
  1596  	}
  1597  	loaddrhex = loaddrhex[:2+(addrsize*2)]
  1598  	var roaddrhex string
  1599  	err = clients[1].Call(&roaddrhex, "pss_baseAddr")
  1600  	if err != nil {
  1601  		t.Fatalf("rpc get node 2 baseaddr fail: %v", err)
  1602  	}
  1603  	roaddrhex = roaddrhex[:2+(addrsize*2)]
  1604  	var xoaddrhex string
  1605  	err = clients[2].Call(&xoaddrhex, "pss_baseAddr")
  1606  	if err != nil {
  1607  		t.Fatalf("rpc get node 3 baseaddr fail: %v", err)
  1608  	}
  1609  	xoaddrhex = xoaddrhex[:2+(addrsize*2)]
  1610  
  1611  	log.Info("peer", "l", loaddrhex, "r", roaddrhex, "x", xoaddrhex)
  1612  
  1613  	var topic string
  1614  	err = clients[0].Call(&topic, "pss_stringToTopic", "foo:42")
  1615  	if err != nil {
  1616  		t.Fatal(err)
  1617  	}
  1618  
  1619  	time.Sleep(time.Millisecond * 250)
  1620  
  1621  	// retrieve public key from pss instance
  1622  	// set this public key reciprocally
  1623  	var rpubkey string
  1624  	err = clients[1].Call(&rpubkey, "pss_getPublicKey")
  1625  	if err != nil {
  1626  		t.Fatalf("rpc get receivenode pubkey fail: %v", err)
  1627  	}
  1628  
  1629  	time.Sleep(time.Millisecond * 500) // replace with hive healthy code
  1630  
  1631  	rmsgC := make(chan APIMsg)
  1632  	rctx, cancel := context.WithTimeout(context.Background(), time.Second*1)
  1633  	defer cancel()
  1634  	rsub, err := clients[1].Subscribe(rctx, "pss", rmsgC, "receive", topic, false, false)
  1635  	log.Trace("rsub", "id", rsub)
  1636  	defer rsub.Unsubscribe()
  1637  
  1638  	// store public key for recipient
  1639  	// zero-length address means forward to all
  1640  	// we have just two peers, they will be in proxbin, and will both receive
  1641  	err = clients[0].Call(nil, "pss_setPeerPublicKey", rpubkey, topic, "0x")
  1642  	if err != nil {
  1643  		t.Fatal(err)
  1644  	}
  1645  
  1646  	// send and verify delivery
  1647  	rmsg := []byte("xyzzy")
  1648  	err = clients[0].Call(nil, "pss_sendAsym", rpubkey, topic, hexutil.Encode(rmsg))
  1649  	if err != nil {
  1650  		t.Fatal(err)
  1651  	}
  1652  
  1653  	var receivedok bool
  1654  OUTER:
  1655  	for {
  1656  		select {
  1657  		case <-rmsgC:
  1658  			if receivedok {
  1659  				t.Fatalf("duplicate message received")
  1660  			}
  1661  			receivedok = true
  1662  		case <-rctx.Done():
  1663  			break OUTER
  1664  		}
  1665  	}
  1666  	if !receivedok {
  1667  		t.Fatalf("message did not arrive")
  1668  	}
  1669  }
  1670  
  1671  // symmetric send performance with varying message sizes
  1672  func BenchmarkSymkeySend(b *testing.B) {
  1673  	b.Run(fmt.Sprintf("%d", 256), benchmarkSymKeySend)
  1674  	b.Run(fmt.Sprintf("%d", 1024), benchmarkSymKeySend)
  1675  	b.Run(fmt.Sprintf("%d", 1024*1024), benchmarkSymKeySend)
  1676  	b.Run(fmt.Sprintf("%d", 1024*1024*10), benchmarkSymKeySend)
  1677  	b.Run(fmt.Sprintf("%d", 1024*1024*100), benchmarkSymKeySend)
  1678  }
  1679  
  1680  func benchmarkSymKeySend(b *testing.B) {
  1681  	msgsizestring := strings.Split(b.Name(), "/")
  1682  	if len(msgsizestring) != 2 {
  1683  		b.Fatalf("benchmark called without msgsize param")
  1684  	}
  1685  	msgsize, err := strconv.ParseInt(msgsizestring[1], 10, 0)
  1686  	if err != nil {
  1687  		b.Fatalf("benchmark called with invalid msgsize param '%s': %v", msgsizestring[1], err)
  1688  	}
  1689  	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
  1690  	defer cancel()
  1691  	keys, err := wapi.NewKeyPair(ctx)
  1692  	privkey, err := w.GetPrivateKey(keys)
  1693  	ps := newTestPss(privkey, nil, nil)
  1694  	msg := make([]byte, msgsize)
  1695  	rand.Read(msg)
  1696  	topic := BytesToTopic([]byte("foo"))
  1697  	to := make(PssAddress, 32)
  1698  	copy(to[:], network.RandomAddr().Over())
  1699  	symkeyid, err := ps.GenerateSymmetricKey(topic, to, true)
  1700  	if err != nil {
  1701  		b.Fatalf("could not generate symkey: %v", err)
  1702  	}
  1703  	symkey, err := ps.w.GetSymKey(symkeyid)
  1704  	if err != nil {
  1705  		b.Fatalf("could not retrieve symkey: %v", err)
  1706  	}
  1707  	ps.SetSymmetricKey(symkey, topic, to, false)
  1708  
  1709  	b.ResetTimer()
  1710  	for i := 0; i < b.N; i++ {
  1711  		ps.SendSym(symkeyid, topic, msg)
  1712  	}
  1713  }
  1714  
  1715  // asymmetric send performance with varying message sizes
  1716  func BenchmarkAsymkeySend(b *testing.B) {
  1717  	b.Run(fmt.Sprintf("%d", 256), benchmarkAsymKeySend)
  1718  	b.Run(fmt.Sprintf("%d", 1024), benchmarkAsymKeySend)
  1719  	b.Run(fmt.Sprintf("%d", 1024*1024), benchmarkAsymKeySend)
  1720  	b.Run(fmt.Sprintf("%d", 1024*1024*10), benchmarkAsymKeySend)
  1721  	b.Run(fmt.Sprintf("%d", 1024*1024*100), benchmarkAsymKeySend)
  1722  }
  1723  
  1724  func benchmarkAsymKeySend(b *testing.B) {
  1725  	msgsizestring := strings.Split(b.Name(), "/")
  1726  	if len(msgsizestring) != 2 {
  1727  		b.Fatalf("benchmark called without msgsize param")
  1728  	}
  1729  	msgsize, err := strconv.ParseInt(msgsizestring[1], 10, 0)
  1730  	if err != nil {
  1731  		b.Fatalf("benchmark called with invalid msgsize param '%s': %v", msgsizestring[1], err)
  1732  	}
  1733  	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
  1734  	defer cancel()
  1735  	keys, err := wapi.NewKeyPair(ctx)
  1736  	privkey, err := w.GetPrivateKey(keys)
  1737  	ps := newTestPss(privkey, nil, nil)
  1738  	msg := make([]byte, msgsize)
  1739  	rand.Read(msg)
  1740  	topic := BytesToTopic([]byte("foo"))
  1741  	to := make(PssAddress, 32)
  1742  	copy(to[:], network.RandomAddr().Over())
  1743  	ps.SetPeerPublicKey(&privkey.PublicKey, topic, to)
  1744  	b.ResetTimer()
  1745  	for i := 0; i < b.N; i++ {
  1746  		ps.SendAsym(common.ToHex(crypto.FromECDSAPub(&privkey.PublicKey)), topic, msg)
  1747  	}
  1748  }
  1749  func BenchmarkSymkeyBruteforceChangeaddr(b *testing.B) {
  1750  	for i := 100; i < 100000; i = i * 10 {
  1751  		for j := 32; j < 10000; j = j * 8 {
  1752  			b.Run(fmt.Sprintf("%d/%d", i, j), benchmarkSymkeyBruteforceChangeaddr)
  1753  		}
  1754  		//b.Run(fmt.Sprintf("%d", i), benchmarkSymkeyBruteforceChangeaddr)
  1755  	}
  1756  }
  1757  
  1758  // decrypt performance using symkey cache, worst case
  1759  // (decrypt key always last in cache)
  1760  func benchmarkSymkeyBruteforceChangeaddr(b *testing.B) {
  1761  	keycountstring := strings.Split(b.Name(), "/")
  1762  	cachesize := int64(0)
  1763  	var ps *Pss
  1764  	if len(keycountstring) < 2 {
  1765  		b.Fatalf("benchmark called without count param")
  1766  	}
  1767  	keycount, err := strconv.ParseInt(keycountstring[1], 10, 0)
  1768  	if err != nil {
  1769  		b.Fatalf("benchmark called with invalid count param '%s': %v", keycountstring[1], err)
  1770  	}
  1771  	if len(keycountstring) == 3 {
  1772  		cachesize, err = strconv.ParseInt(keycountstring[2], 10, 0)
  1773  		if err != nil {
  1774  			b.Fatalf("benchmark called with invalid cachesize '%s': %v", keycountstring[2], err)
  1775  		}
  1776  	}
  1777  	pssmsgs := make([]*PssMsg, 0, keycount)
  1778  	var keyid string
  1779  	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
  1780  	defer cancel()
  1781  	keys, err := wapi.NewKeyPair(ctx)
  1782  	privkey, err := w.GetPrivateKey(keys)
  1783  	if cachesize > 0 {
  1784  		ps = newTestPss(privkey, nil, &PssParams{SymKeyCacheCapacity: int(cachesize)})
  1785  	} else {
  1786  		ps = newTestPss(privkey, nil, nil)
  1787  	}
  1788  	topic := BytesToTopic([]byte("foo"))
  1789  	for i := 0; i < int(keycount); i++ {
  1790  		to := make(PssAddress, 32)
  1791  		copy(to[:], network.RandomAddr().Over())
  1792  		keyid, err = ps.GenerateSymmetricKey(topic, to, true)
  1793  		if err != nil {
  1794  			b.Fatalf("cant generate symkey #%d: %v", i, err)
  1795  		}
  1796  		symkey, err := ps.w.GetSymKey(keyid)
  1797  		if err != nil {
  1798  			b.Fatalf("could not retrieve symkey %s: %v", keyid, err)
  1799  		}
  1800  		wparams := &whisper.MessageParams{
  1801  			TTL:      defaultWhisperTTL,
  1802  			KeySym:   symkey,
  1803  			Topic:    whisper.TopicType(topic),
  1804  			WorkTime: defaultWhisperWorkTime,
  1805  			PoW:      defaultWhisperPoW,
  1806  			Payload:  []byte("xyzzy"),
  1807  			Padding:  []byte("1234567890abcdef"),
  1808  		}
  1809  		woutmsg, err := whisper.NewSentMessage(wparams)
  1810  		if err != nil {
  1811  			b.Fatalf("could not create whisper message: %v", err)
  1812  		}
  1813  		env, err := woutmsg.Wrap(wparams)
  1814  		if err != nil {
  1815  			b.Fatalf("could not generate whisper envelope: %v", err)
  1816  		}
  1817  		ps.Register(&topic, &handler{
  1818  			f: noopHandlerFunc,
  1819  		})
  1820  		pssmsgs = append(pssmsgs, &PssMsg{
  1821  			To:      to,
  1822  			Payload: env,
  1823  		})
  1824  	}
  1825  	b.ResetTimer()
  1826  	for i := 0; i < b.N; i++ {
  1827  		if err := ps.process(pssmsgs[len(pssmsgs)-(i%len(pssmsgs))-1], false, false); err != nil {
  1828  			b.Fatalf("pss processing failed: %v", err)
  1829  		}
  1830  	}
  1831  }
  1832  
  1833  func BenchmarkSymkeyBruteforceSameaddr(b *testing.B) {
  1834  	for i := 100; i < 100000; i = i * 10 {
  1835  		for j := 32; j < 10000; j = j * 8 {
  1836  			b.Run(fmt.Sprintf("%d/%d", i, j), benchmarkSymkeyBruteforceSameaddr)
  1837  		}
  1838  	}
  1839  }
  1840  
  1841  // decrypt performance using symkey cache, best case
  1842  // (decrypt key always first in cache)
  1843  func benchmarkSymkeyBruteforceSameaddr(b *testing.B) {
  1844  	var keyid string
  1845  	var ps *Pss
  1846  	cachesize := int64(0)
  1847  	keycountstring := strings.Split(b.Name(), "/")
  1848  	if len(keycountstring) < 2 {
  1849  		b.Fatalf("benchmark called without count param")
  1850  	}
  1851  	keycount, err := strconv.ParseInt(keycountstring[1], 10, 0)
  1852  	if err != nil {
  1853  		b.Fatalf("benchmark called with invalid count param '%s': %v", keycountstring[1], err)
  1854  	}
  1855  	if len(keycountstring) == 3 {
  1856  		cachesize, err = strconv.ParseInt(keycountstring[2], 10, 0)
  1857  		if err != nil {
  1858  			b.Fatalf("benchmark called with invalid cachesize '%s': %v", keycountstring[2], err)
  1859  		}
  1860  	}
  1861  	addr := make([]PssAddress, keycount)
  1862  	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
  1863  	defer cancel()
  1864  	keys, err := wapi.NewKeyPair(ctx)
  1865  	privkey, err := w.GetPrivateKey(keys)
  1866  	if cachesize > 0 {
  1867  		ps = newTestPss(privkey, nil, &PssParams{SymKeyCacheCapacity: int(cachesize)})
  1868  	} else {
  1869  		ps = newTestPss(privkey, nil, nil)
  1870  	}
  1871  	topic := BytesToTopic([]byte("foo"))
  1872  	for i := 0; i < int(keycount); i++ {
  1873  		copy(addr[i], network.RandomAddr().Over())
  1874  		keyid, err = ps.GenerateSymmetricKey(topic, addr[i], true)
  1875  		if err != nil {
  1876  			b.Fatalf("cant generate symkey #%d: %v", i, err)
  1877  		}
  1878  
  1879  	}
  1880  	symkey, err := ps.w.GetSymKey(keyid)
  1881  	if err != nil {
  1882  		b.Fatalf("could not retrieve symkey %s: %v", keyid, err)
  1883  	}
  1884  	wparams := &whisper.MessageParams{
  1885  		TTL:      defaultWhisperTTL,
  1886  		KeySym:   symkey,
  1887  		Topic:    whisper.TopicType(topic),
  1888  		WorkTime: defaultWhisperWorkTime,
  1889  		PoW:      defaultWhisperPoW,
  1890  		Payload:  []byte("xyzzy"),
  1891  		Padding:  []byte("1234567890abcdef"),
  1892  	}
  1893  	woutmsg, err := whisper.NewSentMessage(wparams)
  1894  	if err != nil {
  1895  		b.Fatalf("could not create whisper message: %v", err)
  1896  	}
  1897  	env, err := woutmsg.Wrap(wparams)
  1898  	if err != nil {
  1899  		b.Fatalf("could not generate whisper envelope: %v", err)
  1900  	}
  1901  	ps.Register(&topic, &handler{
  1902  		f: noopHandlerFunc,
  1903  	})
  1904  	pssmsg := &PssMsg{
  1905  		To:      addr[len(addr)-1][:],
  1906  		Payload: env,
  1907  	}
  1908  	for i := 0; i < b.N; i++ {
  1909  		if err := ps.process(pssmsg, false, false); err != nil {
  1910  			b.Fatalf("pss processing failed: %v", err)
  1911  		}
  1912  	}
  1913  }
  1914  
  1915  // setup simulated network with bzz/discovery and pss services.
  1916  // connects nodes in a circle
  1917  // if allowRaw is set, omission of builtin pss encryption is enabled (see PssParams)
  1918  func setupNetwork(numnodes int, allowRaw bool) (clients []*rpc.Client, err error) {
  1919  	nodes := make([]*simulations.Node, numnodes)
  1920  	clients = make([]*rpc.Client, numnodes)
  1921  	if numnodes < 2 {
  1922  		return nil, fmt.Errorf("Minimum two nodes in network")
  1923  	}
  1924  	adapter := adapters.NewSimAdapter(newServices(allowRaw))
  1925  	net := simulations.NewNetwork(adapter, &simulations.NetworkConfig{
  1926  		ID:             "0",
  1927  		DefaultService: "bzz",
  1928  	})
  1929  	for i := 0; i < numnodes; i++ {
  1930  		nodeconf := adapters.RandomNodeConfig()
  1931  		nodeconf.Services = []string{"bzz", pssProtocolName}
  1932  		nodes[i], err = net.NewNodeWithConfig(nodeconf)
  1933  		if err != nil {
  1934  			return nil, fmt.Errorf("error creating node 1: %v", err)
  1935  		}
  1936  		err = net.Start(nodes[i].ID())
  1937  		if err != nil {
  1938  			return nil, fmt.Errorf("error starting node 1: %v", err)
  1939  		}
  1940  		if i > 0 {
  1941  			err = net.Connect(nodes[i].ID(), nodes[i-1].ID())
  1942  			if err != nil {
  1943  				return nil, fmt.Errorf("error connecting nodes: %v", err)
  1944  			}
  1945  		}
  1946  		clients[i], err = nodes[i].Client()
  1947  		if err != nil {
  1948  			return nil, fmt.Errorf("create node 1 rpc client fail: %v", err)
  1949  		}
  1950  	}
  1951  	if numnodes > 2 {
  1952  		err = net.Connect(nodes[0].ID(), nodes[len(nodes)-1].ID())
  1953  		if err != nil {
  1954  			return nil, fmt.Errorf("error connecting first and last nodes")
  1955  		}
  1956  	}
  1957  	return clients, nil
  1958  }
  1959  
  1960  func newServices(allowRaw bool) adapters.Services {
  1961  	stateStore := state.NewInmemoryStore()
  1962  	kademlias := make(map[enode.ID]*network.Kademlia)
  1963  	kademlia := func(id enode.ID) *network.Kademlia {
  1964  		if k, ok := kademlias[id]; ok {
  1965  			return k
  1966  		}
  1967  		params := network.NewKadParams()
  1968  		params.NeighbourhoodSize = 2
  1969  		params.MaxBinSize = 3
  1970  		params.MinBinSize = 1
  1971  		params.MaxRetries = 1000
  1972  		params.RetryExponent = 2
  1973  		params.RetryInterval = 1000000
  1974  		kademlias[id] = network.NewKademlia(id[:], params)
  1975  		return kademlias[id]
  1976  	}
  1977  	return adapters.Services{
  1978  		pssProtocolName: func(ctx *adapters.ServiceContext) (node.Service, error) {
  1979  			// execadapter does not exec init()
  1980  			initTest()
  1981  
  1982  			ctxlocal, cancel := context.WithTimeout(context.Background(), time.Second)
  1983  			defer cancel()
  1984  			keys, err := wapi.NewKeyPair(ctxlocal)
  1985  			privkey, err := w.GetPrivateKey(keys)
  1986  			pssp := NewPssParams().WithPrivateKey(privkey)
  1987  			pssp.AllowRaw = allowRaw
  1988  			pskad := kademlia(ctx.Config.ID)
  1989  			ps, err := NewPss(pskad, pssp)
  1990  			if err != nil {
  1991  				return nil, err
  1992  			}
  1993  
  1994  			ping := &Ping{
  1995  				OutC: make(chan bool),
  1996  				Pong: true,
  1997  			}
  1998  			p2pp := NewPingProtocol(ping)
  1999  			pp, err := RegisterProtocol(ps, &PingTopic, PingProtocol, p2pp, &ProtocolParams{Asymmetric: true})
  2000  			if err != nil {
  2001  				return nil, err
  2002  			}
  2003  			if useHandshake {
  2004  				SetHandshakeController(ps, NewHandshakeParams())
  2005  			}
  2006  			ps.Register(&PingTopic, &handler{
  2007  				f: pp.Handle,
  2008  				caps: &handlerCaps{
  2009  					raw: true,
  2010  				},
  2011  			})
  2012  			ps.addAPI(rpc.API{
  2013  				Namespace: "psstest",
  2014  				Version:   "0.3",
  2015  				Service:   NewAPITest(ps),
  2016  				Public:    false,
  2017  			})
  2018  			if err != nil {
  2019  				log.Error("Couldnt register pss protocol", "err", err)
  2020  				os.Exit(1)
  2021  			}
  2022  			pssprotocols[ctx.Config.ID.String()] = &protoCtrl{
  2023  				C:        ping.OutC,
  2024  				protocol: pp,
  2025  				run:      p2pp.Run,
  2026  			}
  2027  			return ps, nil
  2028  		},
  2029  		"bzz": func(ctx *adapters.ServiceContext) (node.Service, error) {
  2030  			addr := network.NewAddr(ctx.Config.Node())
  2031  			hp := network.NewHiveParams()
  2032  			hp.Discovery = false
  2033  			config := &network.BzzConfig{
  2034  				OverlayAddr:  addr.Over(),
  2035  				UnderlayAddr: addr.Under(),
  2036  				HiveParams:   hp,
  2037  			}
  2038  			return network.NewBzz(config, kademlia(ctx.Config.ID), stateStore, nil, nil), nil
  2039  		},
  2040  	}
  2041  }
  2042  
  2043  func newTestPss(privkey *ecdsa.PrivateKey, kad *network.Kademlia, ppextra *PssParams) *Pss {
  2044  	nid := enode.PubkeyToIDV4(&privkey.PublicKey)
  2045  	// set up routing if kademlia is not passed to us
  2046  	if kad == nil {
  2047  		kp := network.NewKadParams()
  2048  		kp.NeighbourhoodSize = 3
  2049  		kad = network.NewKademlia(nid[:], kp)
  2050  	}
  2051  
  2052  	// create pss
  2053  	pp := NewPssParams().WithPrivateKey(privkey)
  2054  	if ppextra != nil {
  2055  		pp.SymKeyCacheCapacity = ppextra.SymKeyCacheCapacity
  2056  	}
  2057  	ps, err := NewPss(kad, pp)
  2058  	if err != nil {
  2059  		return nil
  2060  	}
  2061  	ps.Start(nil)
  2062  
  2063  	return ps
  2064  }
  2065  
  2066  // API calls for test/development use
  2067  type APITest struct {
  2068  	*Pss
  2069  }
  2070  
  2071  func NewAPITest(ps *Pss) *APITest {
  2072  	return &APITest{Pss: ps}
  2073  }
  2074  
  2075  func (apitest *APITest) SetSymKeys(pubkeyid string, recvsymkey []byte, sendsymkey []byte, limit uint16, topic Topic, to hexutil.Bytes) ([2]string, error) {
  2076  
  2077  	recvsymkeyid, err := apitest.SetSymmetricKey(recvsymkey, topic, PssAddress(to), true)
  2078  	if err != nil {
  2079  		return [2]string{}, err
  2080  	}
  2081  	sendsymkeyid, err := apitest.SetSymmetricKey(sendsymkey, topic, PssAddress(to), false)
  2082  	if err != nil {
  2083  		return [2]string{}, err
  2084  	}
  2085  	return [2]string{recvsymkeyid, sendsymkeyid}, nil
  2086  }
  2087  
  2088  func (apitest *APITest) Clean() (int, error) {
  2089  	return apitest.Pss.cleanKeys(), nil
  2090  }
  2091  
  2092  // enableMetrics is starting InfluxDB reporter so that we collect stats when running tests locally
  2093  func enableMetrics() {
  2094  	metrics.Enabled = true
  2095  	go influxdb.InfluxDBWithTags(metrics.DefaultRegistry, 1*time.Second, "http://localhost:8086", "metrics", "admin", "admin", "swarm.", map[string]string{
  2096  		"host": "test",
  2097  	})
  2098  }