github.com/jincm/wesharechain@v0.0.0-20210122032815-1537409ce26a/chain/swarm/pss/pss_test.go (about)

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