github.com/codingfuture/orig-energi3@v0.8.4/swarm/pss/pss_test.go (about)

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