github.com/xxRanger/go-ethereum@v1.8.23/swarm/pss/pss_test.go (about)

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