github.com/linapex/ethereum-dpos-chinese@v0.0.0-20190316121959-b78b3a4a1ece/swarm/pss/pss_test.go (about)

     1  
     2  //<developer>
     3  //    <name>linapex 曹一峰</name>
     4  //    <email>linapex@163.com</email>
     5  //    <wx>superexc</wx>
     6  //    <qqgroup>128148617</qqgroup>
     7  //    <url>https://jsq.ink</url>
     8  //    <role>pku engineer</role>
     9  //    <date>2019-03-16 12:09:49</date>
    10  //</624342678481408000>
    11  
    12  //
    13  //
    14  //
    15  //
    16  //
    17  //
    18  //
    19  //
    20  //
    21  //
    22  //
    23  //
    24  //
    25  //
    26  //
    27  
    28  package pss
    29  
    30  import (
    31  	"bytes"
    32  	"context"
    33  	"crypto/ecdsa"
    34  	"encoding/binary"
    35  	"encoding/hex"
    36  	"encoding/json"
    37  	"flag"
    38  	"fmt"
    39  	"io/ioutil"
    40  	"math/rand"
    41  	"os"
    42  	"strconv"
    43  	"strings"
    44  	"sync"
    45  	"testing"
    46  	"time"
    47  
    48  	"github.com/ethereum/go-ethereum/common"
    49  	"github.com/ethereum/go-ethereum/common/hexutil"
    50  	"github.com/ethereum/go-ethereum/crypto"
    51  	"github.com/ethereum/go-ethereum/log"
    52  	"github.com/ethereum/go-ethereum/metrics"
    53  	"github.com/ethereum/go-ethereum/metrics/influxdb"
    54  	"github.com/ethereum/go-ethereum/node"
    55  	"github.com/ethereum/go-ethereum/p2p"
    56  	"github.com/ethereum/go-ethereum/p2p/discover"
    57  	"github.com/ethereum/go-ethereum/p2p/protocols"
    58  	"github.com/ethereum/go-ethereum/p2p/simulations"
    59  	"github.com/ethereum/go-ethereum/p2p/simulations/adapters"
    60  	"github.com/ethereum/go-ethereum/rpc"
    61  	"github.com/ethereum/go-ethereum/swarm/network"
    62  	"github.com/ethereum/go-ethereum/swarm/state"
    63  	whisper "github.com/ethereum/go-ethereum/whisper/whisperv5"
    64  )
    65  
    66  var (
    67  	initOnce       = sync.Once{}
    68  	debugdebugflag = flag.Bool("vv", false, "veryverbose")
    69  	debugflag      = flag.Bool("v", false, "verbose")
    70  	longrunning    = flag.Bool("longrunning", false, "do run long-running tests")
    71  	w              *whisper.Whisper
    72  	wapi           *whisper.PublicWhisperAPI
    73  	psslogmain     log.Logger
    74  	pssprotocols   map[string]*protoCtrl
    75  	useHandshake   bool
    76  )
    77  
    78  func init() {
    79  	flag.Parse()
    80  	rand.Seed(time.Now().Unix())
    81  
    82  	adapters.RegisterServices(newServices(false))
    83  	initTest()
    84  }
    85  
    86  func initTest() {
    87  	initOnce.Do(
    88  		func() {
    89  			loglevel := log.LvlInfo
    90  			if *debugflag {
    91  				loglevel = log.LvlDebug
    92  			} else if *debugdebugflag {
    93  				loglevel = log.LvlTrace
    94  			}
    95  
    96  			psslogmain = log.New("psslog", "*")
    97  			hs := log.StreamHandler(os.Stderr, log.TerminalFormat(true))
    98  			hf := log.LvlFilterHandler(loglevel, hs)
    99  			h := log.CallerFileHandler(hf)
   100  			log.Root().SetHandler(h)
   101  
   102  			w = whisper.New(&whisper.DefaultConfig)
   103  			wapi = whisper.NewPublicWhisperAPI(w)
   104  
   105  			pssprotocols = make(map[string]*protoCtrl)
   106  		},
   107  	)
   108  }
   109  
   110  //
   111  func TestTopic(t *testing.T) {
   112  
   113  	api := &API{}
   114  
   115  	topicstr := strings.Join([]string{PingProtocol.Name, strconv.Itoa(int(PingProtocol.Version))}, ":")
   116  
   117  //
   118  	topicobj := BytesToTopic([]byte(topicstr))
   119  
   120  //
   121  	topicapiobj, _ := api.StringToTopic(topicstr)
   122  	if topicobj != topicapiobj {
   123  		t.Fatalf("bytes and string topic conversion mismatch; %s != %s", topicobj, topicapiobj)
   124  	}
   125  
   126  //
   127  	topichex := topicobj.String()
   128  
   129  //
   130  //
   131  	pingtopichex := PingTopic.String()
   132  	if topichex != pingtopichex {
   133  		t.Fatalf("protocol topic conversion mismatch; %s != %s", topichex, pingtopichex)
   134  	}
   135  
   136  //
   137  	topicjsonout, err := topicobj.MarshalJSON()
   138  	if err != nil {
   139  		t.Fatal(err)
   140  	}
   141  	if string(topicjsonout)[1:len(topicjsonout)-1] != topichex {
   142  		t.Fatalf("topic json marshal mismatch; %s != \"%s\"", topicjsonout, topichex)
   143  	}
   144  
   145  //
   146  	var topicjsonin Topic
   147  	topicjsonin.UnmarshalJSON(topicjsonout)
   148  	if topicjsonin != topicobj {
   149  		t.Fatalf("topic json unmarshal mismatch: %x != %x", topicjsonin, topicobj)
   150  	}
   151  }
   152  
   153  //
   154  func TestMsgParams(t *testing.T) {
   155  	var ctrl byte
   156  	ctrl |= pssControlRaw
   157  	p := newMsgParamsFromBytes([]byte{ctrl})
   158  	m := newPssMsg(p)
   159  	if !m.isRaw() || m.isSym() {
   160  		t.Fatal("expected raw=true and sym=false")
   161  	}
   162  	ctrl |= pssControlSym
   163  	p = newMsgParamsFromBytes([]byte{ctrl})
   164  	m = newPssMsg(p)
   165  	if !m.isRaw() || !m.isSym() {
   166  		t.Fatal("expected raw=true and sym=true")
   167  	}
   168  	ctrl &= 0xff &^ pssControlRaw
   169  	p = newMsgParamsFromBytes([]byte{ctrl})
   170  	m = newPssMsg(p)
   171  	if m.isRaw() || !m.isSym() {
   172  		t.Fatal("expected raw=false and sym=true")
   173  	}
   174  }
   175  
   176  //
   177  func TestCache(t *testing.T) {
   178  	var err error
   179  	to, _ := hex.DecodeString("08090a0b0c0d0e0f1011121314150001020304050607161718191a1b1c1d1e1f")
   180  	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
   181  	defer cancel()
   182  	keys, err := wapi.NewKeyPair(ctx)
   183  	privkey, err := w.GetPrivateKey(keys)
   184  	if err != nil {
   185  		t.Fatal(err)
   186  	}
   187  	ps := newTestPss(privkey, nil, nil)
   188  	pp := NewPssParams().WithPrivateKey(privkey)
   189  	data := []byte("foo")
   190  	datatwo := []byte("bar")
   191  	datathree := []byte("baz")
   192  	wparams := &whisper.MessageParams{
   193  		TTL:      defaultWhisperTTL,
   194  		Src:      privkey,
   195  		Dst:      &privkey.PublicKey,
   196  		Topic:    whisper.TopicType(PingTopic),
   197  		WorkTime: defaultWhisperWorkTime,
   198  		PoW:      defaultWhisperPoW,
   199  		Payload:  data,
   200  	}
   201  	woutmsg, err := whisper.NewSentMessage(wparams)
   202  	env, err := woutmsg.Wrap(wparams)
   203  	msg := &PssMsg{
   204  		Payload: env,
   205  		To:      to,
   206  	}
   207  	wparams.Payload = datatwo
   208  	woutmsg, err = whisper.NewSentMessage(wparams)
   209  	envtwo, err := woutmsg.Wrap(wparams)
   210  	msgtwo := &PssMsg{
   211  		Payload: envtwo,
   212  		To:      to,
   213  	}
   214  	wparams.Payload = datathree
   215  	woutmsg, err = whisper.NewSentMessage(wparams)
   216  	envthree, err := woutmsg.Wrap(wparams)
   217  	msgthree := &PssMsg{
   218  		Payload: envthree,
   219  		To:      to,
   220  	}
   221  
   222  	digest := ps.digest(msg)
   223  	if err != nil {
   224  		t.Fatalf("could not store cache msgone: %v", err)
   225  	}
   226  	digesttwo := ps.digest(msgtwo)
   227  	if err != nil {
   228  		t.Fatalf("could not store cache msgtwo: %v", err)
   229  	}
   230  	digestthree := ps.digest(msgthree)
   231  	if err != nil {
   232  		t.Fatalf("could not store cache msgthree: %v", err)
   233  	}
   234  
   235  	if digest == digesttwo {
   236  		t.Fatalf("different msgs return same hash: %d", digesttwo)
   237  	}
   238  
   239  //
   240  	err = ps.addFwdCache(msg)
   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 EXPIRE record in cache but checkCache returned false", msg)
   247  	}
   248  
   249  	if ps.checkFwdCache(msgtwo) {
   250  		t.Fatalf("message %v should NOT have EXPIRE record in cache but checkCache returned true", msgtwo)
   251  	}
   252  
   253  	time.Sleep(pp.CacheTTL + 1*time.Second)
   254  	err = ps.addFwdCache(msgthree)
   255  	if err != nil {
   256  		t.Fatalf("write to pss expire cache failed: %v", err)
   257  	}
   258  
   259  	if ps.checkFwdCache(msg) {
   260  		t.Fatalf("message %v should have expired from cache but checkCache returned true", msg)
   261  	}
   262  
   263  	if _, ok := ps.fwdCache[digestthree]; !ok {
   264  		t.Fatalf("unexpired message should be in the cache: %v", digestthree)
   265  	}
   266  
   267  	if _, ok := ps.fwdCache[digesttwo]; ok {
   268  		t.Fatalf("expired message should have been cleared from the cache: %v", digesttwo)
   269  	}
   270  }
   271  
   272  //
   273  func TestAddressMatch(t *testing.T) {
   274  
   275  	localaddr := network.RandomAddr().Over()
   276  	copy(localaddr[:8], []byte("deadbeef"))
   277  	remoteaddr := []byte("feedbeef")
   278  	kadparams := network.NewKadParams()
   279  	kad := network.NewKademlia(localaddr, kadparams)
   280  	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
   281  	defer cancel()
   282  	keys, err := wapi.NewKeyPair(ctx)
   283  	if err != nil {
   284  		t.Fatalf("Could not generate private key: %v", err)
   285  	}
   286  	privkey, err := w.GetPrivateKey(keys)
   287  	pssp := NewPssParams().WithPrivateKey(privkey)
   288  	ps, err := NewPss(kad, pssp)
   289  	if err != nil {
   290  		t.Fatal(err.Error())
   291  	}
   292  
   293  	pssmsg := &PssMsg{
   294  		To:      remoteaddr,
   295  		Payload: &whisper.Envelope{},
   296  	}
   297  
   298  //
   299  	if ps.isSelfRecipient(pssmsg) {
   300  		t.Fatalf("isSelfRecipient true but %x != %x", remoteaddr, localaddr)
   301  	}
   302  	if ps.isSelfPossibleRecipient(pssmsg) {
   303  		t.Fatalf("isSelfPossibleRecipient true but %x != %x", remoteaddr[:8], localaddr[:8])
   304  	}
   305  
   306  //
   307  	copy(remoteaddr[:4], localaddr[:4])
   308  	if ps.isSelfRecipient(pssmsg) {
   309  		t.Fatalf("isSelfRecipient true but %x != %x", remoteaddr, localaddr)
   310  	}
   311  	if !ps.isSelfPossibleRecipient(pssmsg) {
   312  		t.Fatalf("isSelfPossibleRecipient false but %x == %x", remoteaddr[:8], localaddr[:8])
   313  	}
   314  
   315  //
   316  	pssmsg.To = localaddr
   317  	if !ps.isSelfRecipient(pssmsg) {
   318  		t.Fatalf("isSelfRecipient false but %x == %x", remoteaddr, localaddr)
   319  	}
   320  	if !ps.isSelfPossibleRecipient(pssmsg) {
   321  		t.Fatalf("isSelfPossibleRecipient false but %x == %x", remoteaddr[:8], localaddr[:8])
   322  	}
   323  }
   324  
   325  //
   326  func TestHandlerConditions(t *testing.T) {
   327  
   328  	t.Skip("Disabled due to probable faulty logic for outbox expectations")
   329  //
   330  	privkey, err := crypto.GenerateKey()
   331  	if err != nil {
   332  		t.Fatal(err.Error())
   333  	}
   334  
   335  	addr := make([]byte, 32)
   336  	addr[0] = 0x01
   337  	ps := newTestPss(privkey, network.NewKademlia(addr, network.NewKadParams()), NewPssParams())
   338  
   339  //
   340  	msg := &PssMsg{
   341  		To:     addr,
   342  		Expire: uint32(time.Now().Add(time.Second * 60).Unix()),
   343  		Payload: &whisper.Envelope{
   344  			Topic: [4]byte{},
   345  			Data:  []byte{0x66, 0x6f, 0x6f},
   346  		},
   347  	}
   348  	if err := ps.handlePssMsg(context.TODO(), msg); err != nil {
   349  		t.Fatal(err.Error())
   350  	}
   351  	tmr := time.NewTimer(time.Millisecond * 100)
   352  	var outmsg *PssMsg
   353  	select {
   354  	case outmsg = <-ps.outbox:
   355  	case <-tmr.C:
   356  	default:
   357  	}
   358  	if outmsg != nil {
   359  		t.Fatalf("expected outbox empty after full address on msg, but had message %s", msg)
   360  	}
   361  
   362  //
   363  	msg.To = addr[0:1]
   364  	msg.Payload.Data = []byte{0x78, 0x79, 0x80, 0x80, 0x79}
   365  	if err := ps.handlePssMsg(context.TODO(), msg); err != nil {
   366  		t.Fatal(err.Error())
   367  	}
   368  	tmr.Reset(time.Millisecond * 100)
   369  	outmsg = nil
   370  	select {
   371  	case outmsg = <-ps.outbox:
   372  	case <-tmr.C:
   373  	}
   374  	if outmsg == nil {
   375  		t.Fatal("expected message in outbox on encrypt fail, but empty")
   376  	}
   377  	outmsg = nil
   378  	select {
   379  	case outmsg = <-ps.outbox:
   380  	default:
   381  	}
   382  	if outmsg != nil {
   383  		t.Fatalf("expected only one queued message but also had message %v", msg)
   384  	}
   385  
   386  //
   387  	msg.To[0] = 0xff
   388  	if err := ps.handlePssMsg(context.TODO(), msg); err != nil {
   389  		t.Fatal(err.Error())
   390  	}
   391  	tmr.Reset(time.Millisecond * 10)
   392  	outmsg = nil
   393  	select {
   394  	case outmsg = <-ps.outbox:
   395  	case <-tmr.C:
   396  	}
   397  	if outmsg == nil {
   398  		t.Fatal("expected message in outbox on address mismatch, but empty")
   399  	}
   400  	outmsg = nil
   401  	select {
   402  	case outmsg = <-ps.outbox:
   403  	default:
   404  	}
   405  	if outmsg != nil {
   406  		t.Fatalf("expected only one queued message but also had message %v", msg)
   407  	}
   408  
   409  //
   410  	msg.Expire = uint32(time.Now().Add(-time.Second).Unix())
   411  	if err := ps.handlePssMsg(context.TODO(), msg); err != nil {
   412  		t.Fatal(err.Error())
   413  	}
   414  	tmr.Reset(time.Millisecond * 10)
   415  	outmsg = nil
   416  	select {
   417  	case outmsg = <-ps.outbox:
   418  	case <-tmr.C:
   419  	default:
   420  	}
   421  	if outmsg != nil {
   422  		t.Fatalf("expected empty queue but have message %v", msg)
   423  	}
   424  
   425  //
   426  	fckedupmsg := &struct {
   427  		pssMsg *PssMsg
   428  	}{
   429  		pssMsg: &PssMsg{},
   430  	}
   431  	if err := ps.handlePssMsg(context.TODO(), fckedupmsg); err == nil {
   432  		t.Fatalf("expected error from processMsg but error nil")
   433  	}
   434  
   435  //
   436  	msg.Expire = uint32(time.Now().Add(time.Second * 60).Unix())
   437  	for i := 0; i < defaultOutboxCapacity; i++ {
   438  		ps.outbox <- msg
   439  	}
   440  	msg.Payload.Data = []byte{0x62, 0x61, 0x72}
   441  	err = ps.handlePssMsg(context.TODO(), msg)
   442  	if err == nil {
   443  		t.Fatal("expected error when mailbox full, but was nil")
   444  	}
   445  }
   446  
   447  //
   448  func TestKeys(t *testing.T) {
   449  //
   450  	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
   451  	defer cancel()
   452  	ourkeys, err := wapi.NewKeyPair(ctx)
   453  	if err != nil {
   454  		t.Fatalf("create 'our' key fail")
   455  	}
   456  	ctx, cancel2 := context.WithTimeout(context.Background(), time.Second)
   457  	defer cancel2()
   458  	theirkeys, err := wapi.NewKeyPair(ctx)
   459  	if err != nil {
   460  		t.Fatalf("create 'their' key fail")
   461  	}
   462  	ourprivkey, err := w.GetPrivateKey(ourkeys)
   463  	if err != nil {
   464  		t.Fatalf("failed to retrieve 'our' private key")
   465  	}
   466  	theirprivkey, err := w.GetPrivateKey(theirkeys)
   467  	if err != nil {
   468  		t.Fatalf("failed to retrieve 'their' private key")
   469  	}
   470  	ps := newTestPss(ourprivkey, nil, nil)
   471  
   472  //
   473  	addr := make(PssAddress, 32)
   474  	copy(addr, network.RandomAddr().Over())
   475  	outkey := network.RandomAddr().Over()
   476  	topicobj := BytesToTopic([]byte("foo:42"))
   477  	ps.SetPeerPublicKey(&theirprivkey.PublicKey, topicobj, &addr)
   478  	outkeyid, err := ps.SetSymmetricKey(outkey, topicobj, &addr, false)
   479  	if err != nil {
   480  		t.Fatalf("failed to set 'our' outgoing symmetric key")
   481  	}
   482  
   483  //
   484  	inkeyid, err := ps.GenerateSymmetricKey(topicobj, &addr, true)
   485  	if err != nil {
   486  		t.Fatalf("failed to set 'our' incoming symmetric key")
   487  	}
   488  
   489  //
   490  	outkeyback, err := ps.w.GetSymKey(outkeyid)
   491  	if err != nil {
   492  		t.Fatalf(err.Error())
   493  	}
   494  	inkey, err := ps.w.GetSymKey(inkeyid)
   495  	if err != nil {
   496  		t.Fatalf(err.Error())
   497  	}
   498  	if !bytes.Equal(outkeyback, outkey) {
   499  		t.Fatalf("passed outgoing symkey doesnt equal stored: %x / %x", outkey, outkeyback)
   500  	}
   501  
   502  	t.Logf("symout: %v", outkeyback)
   503  	t.Logf("symin: %v", inkey)
   504  
   505  //
   506  	psp := ps.symKeyPool[inkeyid][topicobj]
   507  	if psp.address != &addr {
   508  		t.Fatalf("inkey address does not match; %p != %p", psp.address, &addr)
   509  	}
   510  }
   511  
   512  func TestGetPublickeyEntries(t *testing.T) {
   513  
   514  	privkey, err := crypto.GenerateKey()
   515  	if err != nil {
   516  		t.Fatal(err)
   517  	}
   518  	ps := newTestPss(privkey, nil, nil)
   519  
   520  	peeraddr := network.RandomAddr().Over()
   521  	topicaddr := make(map[Topic]PssAddress)
   522  	topicaddr[Topic{0x13}] = peeraddr
   523  	topicaddr[Topic{0x2a}] = peeraddr[:16]
   524  	topicaddr[Topic{0x02, 0x9a}] = []byte{}
   525  
   526  	remoteprivkey, err := crypto.GenerateKey()
   527  	if err != nil {
   528  		t.Fatal(err)
   529  	}
   530  	remotepubkeybytes := crypto.FromECDSAPub(&remoteprivkey.PublicKey)
   531  	remotepubkeyhex := common.ToHex(remotepubkeybytes)
   532  
   533  	pssapi := NewAPI(ps)
   534  
   535  	for to, a := range topicaddr {
   536  		err = pssapi.SetPeerPublicKey(remotepubkeybytes, to, a)
   537  		if err != nil {
   538  			t.Fatal(err)
   539  		}
   540  	}
   541  
   542  	intopic, err := pssapi.GetPeerTopics(remotepubkeyhex)
   543  	if err != nil {
   544  		t.Fatal(err)
   545  	}
   546  
   547  OUTER:
   548  	for _, tnew := range intopic {
   549  		for torig, addr := range topicaddr {
   550  			if bytes.Equal(torig[:], tnew[:]) {
   551  				inaddr, err := pssapi.GetPeerAddress(remotepubkeyhex, torig)
   552  				if err != nil {
   553  					t.Fatal(err)
   554  				}
   555  				if !bytes.Equal(addr, inaddr) {
   556  					t.Fatalf("Address mismatch for topic %x; got %x, expected %x", torig, inaddr, addr)
   557  				}
   558  				delete(topicaddr, torig)
   559  				continue OUTER
   560  			}
   561  		}
   562  		t.Fatalf("received topic %x did not match any existing topics", tnew)
   563  	}
   564  
   565  	if len(topicaddr) != 0 {
   566  		t.Fatalf("%d topics were not matched", len(topicaddr))
   567  	}
   568  }
   569  
   570  type pssTestPeer struct {
   571  	*protocols.Peer
   572  	addr []byte
   573  }
   574  
   575  func (t *pssTestPeer) Address() []byte {
   576  	return t.addr
   577  }
   578  
   579  func (t *pssTestPeer) Update(addr network.OverlayAddr) network.OverlayAddr {
   580  	return addr
   581  }
   582  
   583  func (t *pssTestPeer) Off() network.OverlayAddr {
   584  	return &pssTestPeer{}
   585  }
   586  
   587  //
   588  func TestMismatch(t *testing.T) {
   589  
   590  //
   591  	privkey, err := crypto.GenerateKey()
   592  	if err != nil {
   593  		t.Fatal(err)
   594  	}
   595  
   596  //
   597  	baseaddr := network.RandomAddr()
   598  	kad := network.NewKademlia((baseaddr).Over(), network.NewKadParams())
   599  	rw := &p2p.MsgPipeRW{}
   600  
   601  //
   602  	wrongpssaddr := network.RandomAddr()
   603  	wrongpsscap := p2p.Cap{
   604  		Name:    pssProtocolName,
   605  		Version: 0,
   606  	}
   607  	nid, _ := discover.HexID("0x01")
   608  	wrongpsspeer := &pssTestPeer{
   609  		Peer: protocols.NewPeer(p2p.NewPeer(nid, common.ToHex(wrongpssaddr.Over()), []p2p.Cap{wrongpsscap}), rw, nil),
   610  		addr: wrongpssaddr.Over(),
   611  	}
   612  
   613  //
   614  	nopssaddr := network.RandomAddr()
   615  	nopsscap := p2p.Cap{
   616  		Name:    "nopss",
   617  		Version: 1,
   618  	}
   619  	nid, _ = discover.HexID("0x02")
   620  	nopsspeer := &pssTestPeer{
   621  		Peer: protocols.NewPeer(p2p.NewPeer(nid, common.ToHex(nopssaddr.Over()), []p2p.Cap{nopsscap}), rw, nil),
   622  		addr: nopssaddr.Over(),
   623  	}
   624  
   625  //
   626  //
   627  	kad.Register([]network.OverlayAddr{wrongpsspeer})
   628  	kad.On(wrongpsspeer)
   629  	kad.Register([]network.OverlayAddr{nopsspeer})
   630  	kad.On(nopsspeer)
   631  
   632  //
   633  	pssmsg := &PssMsg{
   634  		To:      []byte{},
   635  		Expire:  uint32(time.Now().Add(time.Second).Unix()),
   636  		Payload: &whisper.Envelope{},
   637  	}
   638  	ps := newTestPss(privkey, kad, nil)
   639  
   640  //
   641  //
   642  	ps.forward(pssmsg)
   643  
   644  }
   645  
   646  func TestSendRaw(t *testing.T) {
   647  	t.Run("32", testSendRaw)
   648  	t.Run("8", testSendRaw)
   649  	t.Run("0", testSendRaw)
   650  }
   651  
   652  func testSendRaw(t *testing.T) {
   653  
   654  	var addrsize int64
   655  	var err error
   656  
   657  	paramstring := strings.Split(t.Name(), "/")
   658  
   659  	addrsize, _ = strconv.ParseInt(paramstring[1], 10, 0)
   660  	log.Info("raw send test", "addrsize", addrsize)
   661  
   662  	clients, err := setupNetwork(2, true)
   663  	if err != nil {
   664  		t.Fatal(err)
   665  	}
   666  
   667  	topic := "0xdeadbeef"
   668  
   669  	var loaddrhex string
   670  	err = clients[0].Call(&loaddrhex, "pss_baseAddr")
   671  	if err != nil {
   672  		t.Fatalf("rpc get node 1 baseaddr fail: %v", err)
   673  	}
   674  	loaddrhex = loaddrhex[:2+(addrsize*2)]
   675  	var roaddrhex string
   676  	err = clients[1].Call(&roaddrhex, "pss_baseAddr")
   677  	if err != nil {
   678  		t.Fatalf("rpc get node 2 baseaddr fail: %v", err)
   679  	}
   680  	roaddrhex = roaddrhex[:2+(addrsize*2)]
   681  
   682  	time.Sleep(time.Millisecond * 500)
   683  
   684  //
   685  //
   686  	lmsgC := make(chan APIMsg)
   687  	lctx, lcancel := context.WithTimeout(context.Background(), time.Second*10)
   688  	defer lcancel()
   689  	lsub, err := clients[0].Subscribe(lctx, "pss", lmsgC, "receive", topic)
   690  	log.Trace("lsub", "id", lsub)
   691  	defer lsub.Unsubscribe()
   692  	rmsgC := make(chan APIMsg)
   693  	rctx, rcancel := context.WithTimeout(context.Background(), time.Second*10)
   694  	defer rcancel()
   695  	rsub, err := clients[1].Subscribe(rctx, "pss", rmsgC, "receive", topic)
   696  	log.Trace("rsub", "id", rsub)
   697  	defer rsub.Unsubscribe()
   698  
   699  //
   700  	lmsg := []byte("plugh")
   701  	err = clients[1].Call(nil, "pss_sendRaw", loaddrhex, topic, lmsg)
   702  	if err != nil {
   703  		t.Fatal(err)
   704  	}
   705  	select {
   706  	case recvmsg := <-lmsgC:
   707  		if !bytes.Equal(recvmsg.Msg, lmsg) {
   708  			t.Fatalf("node 1 received payload mismatch: expected %v, got %v", lmsg, recvmsg)
   709  		}
   710  	case cerr := <-lctx.Done():
   711  		t.Fatalf("test message (left) timed out: %v", cerr)
   712  	}
   713  	rmsg := []byte("xyzzy")
   714  	err = clients[0].Call(nil, "pss_sendRaw", roaddrhex, topic, rmsg)
   715  	if err != nil {
   716  		t.Fatal(err)
   717  	}
   718  	select {
   719  	case recvmsg := <-rmsgC:
   720  		if !bytes.Equal(recvmsg.Msg, rmsg) {
   721  			t.Fatalf("node 2 received payload mismatch: expected %x, got %v", rmsg, recvmsg.Msg)
   722  		}
   723  	case cerr := <-rctx.Done():
   724  		t.Fatalf("test message (right) timed out: %v", cerr)
   725  	}
   726  }
   727  
   728  //
   729  func TestSendSym(t *testing.T) {
   730  	t.Run("32", testSendSym)
   731  	t.Run("8", testSendSym)
   732  	t.Run("0", testSendSym)
   733  }
   734  
   735  func testSendSym(t *testing.T) {
   736  
   737  //
   738  	var addrsize int64
   739  	var err error
   740  	paramstring := strings.Split(t.Name(), "/")
   741  	addrsize, _ = strconv.ParseInt(paramstring[1], 10, 0)
   742  	log.Info("sym send test", "addrsize", addrsize)
   743  
   744  	clients, err := setupNetwork(2, false)
   745  	if err != nil {
   746  		t.Fatal(err)
   747  	}
   748  
   749  	var topic string
   750  	err = clients[0].Call(&topic, "pss_stringToTopic", "foo:42")
   751  	if err != nil {
   752  		t.Fatal(err)
   753  	}
   754  
   755  	var loaddrhex string
   756  	err = clients[0].Call(&loaddrhex, "pss_baseAddr")
   757  	if err != nil {
   758  		t.Fatalf("rpc get node 1 baseaddr fail: %v", err)
   759  	}
   760  	loaddrhex = loaddrhex[:2+(addrsize*2)]
   761  	var roaddrhex string
   762  	err = clients[1].Call(&roaddrhex, "pss_baseAddr")
   763  	if err != nil {
   764  		t.Fatalf("rpc get node 2 baseaddr fail: %v", err)
   765  	}
   766  	roaddrhex = roaddrhex[:2+(addrsize*2)]
   767  
   768  //
   769  //
   770  	var lpubkeyhex string
   771  	err = clients[0].Call(&lpubkeyhex, "pss_getPublicKey")
   772  	if err != nil {
   773  		t.Fatalf("rpc get node 1 pubkey fail: %v", err)
   774  	}
   775  	var rpubkeyhex string
   776  	err = clients[1].Call(&rpubkeyhex, "pss_getPublicKey")
   777  	if err != nil {
   778  		t.Fatalf("rpc get node 2 pubkey fail: %v", err)
   779  	}
   780  
   781  	time.Sleep(time.Millisecond * 500)
   782  
   783  //
   784  //
   785  	lmsgC := make(chan APIMsg)
   786  	lctx, lcancel := context.WithTimeout(context.Background(), time.Second*10)
   787  	defer lcancel()
   788  	lsub, err := clients[0].Subscribe(lctx, "pss", lmsgC, "receive", topic)
   789  	log.Trace("lsub", "id", lsub)
   790  	defer lsub.Unsubscribe()
   791  	rmsgC := make(chan APIMsg)
   792  	rctx, rcancel := context.WithTimeout(context.Background(), time.Second*10)
   793  	defer rcancel()
   794  	rsub, err := clients[1].Subscribe(rctx, "pss", rmsgC, "receive", topic)
   795  	log.Trace("rsub", "id", rsub)
   796  	defer rsub.Unsubscribe()
   797  
   798  	lrecvkey := network.RandomAddr().Over()
   799  	rrecvkey := network.RandomAddr().Over()
   800  
   801  	var lkeyids [2]string
   802  	var rkeyids [2]string
   803  
   804  //
   805  	err = clients[0].Call(&lkeyids, "psstest_setSymKeys", rpubkeyhex, lrecvkey, rrecvkey, defaultSymKeySendLimit, topic, roaddrhex)
   806  	if err != nil {
   807  		t.Fatal(err)
   808  	}
   809  	err = clients[1].Call(&rkeyids, "psstest_setSymKeys", lpubkeyhex, rrecvkey, lrecvkey, defaultSymKeySendLimit, topic, loaddrhex)
   810  	if err != nil {
   811  		t.Fatal(err)
   812  	}
   813  
   814  //
   815  	lmsg := []byte("plugh")
   816  	err = clients[1].Call(nil, "pss_sendSym", rkeyids[1], topic, hexutil.Encode(lmsg))
   817  	if err != nil {
   818  		t.Fatal(err)
   819  	}
   820  	select {
   821  	case recvmsg := <-lmsgC:
   822  		if !bytes.Equal(recvmsg.Msg, lmsg) {
   823  			t.Fatalf("node 1 received payload mismatch: expected %v, got %v", lmsg, recvmsg)
   824  		}
   825  	case cerr := <-lctx.Done():
   826  		t.Fatalf("test message timed out: %v", cerr)
   827  	}
   828  	rmsg := []byte("xyzzy")
   829  	err = clients[0].Call(nil, "pss_sendSym", lkeyids[1], topic, hexutil.Encode(rmsg))
   830  	if err != nil {
   831  		t.Fatal(err)
   832  	}
   833  	select {
   834  	case recvmsg := <-rmsgC:
   835  		if !bytes.Equal(recvmsg.Msg, rmsg) {
   836  			t.Fatalf("node 2 received payload mismatch: expected %x, got %v", rmsg, recvmsg.Msg)
   837  		}
   838  	case cerr := <-rctx.Done():
   839  		t.Fatalf("test message timed out: %v", cerr)
   840  	}
   841  }
   842  
   843  //
   844  func TestSendAsym(t *testing.T) {
   845  	t.Run("32", testSendAsym)
   846  	t.Run("8", testSendAsym)
   847  	t.Run("0", testSendAsym)
   848  }
   849  
   850  func testSendAsym(t *testing.T) {
   851  
   852  //
   853  	var addrsize int64
   854  	var err error
   855  	paramstring := strings.Split(t.Name(), "/")
   856  	addrsize, _ = strconv.ParseInt(paramstring[1], 10, 0)
   857  	log.Info("asym send test", "addrsize", addrsize)
   858  
   859  	clients, err := setupNetwork(2, false)
   860  	if err != nil {
   861  		t.Fatal(err)
   862  	}
   863  
   864  	var topic string
   865  	err = clients[0].Call(&topic, "pss_stringToTopic", "foo:42")
   866  	if err != nil {
   867  		t.Fatal(err)
   868  	}
   869  
   870  	time.Sleep(time.Millisecond * 250)
   871  
   872  	var loaddrhex string
   873  	err = clients[0].Call(&loaddrhex, "pss_baseAddr")
   874  	if err != nil {
   875  		t.Fatalf("rpc get node 1 baseaddr fail: %v", err)
   876  	}
   877  	loaddrhex = loaddrhex[:2+(addrsize*2)]
   878  	var roaddrhex string
   879  	err = clients[1].Call(&roaddrhex, "pss_baseAddr")
   880  	if err != nil {
   881  		t.Fatalf("rpc get node 2 baseaddr fail: %v", err)
   882  	}
   883  	roaddrhex = roaddrhex[:2+(addrsize*2)]
   884  
   885  //
   886  //
   887  	var lpubkey string
   888  	err = clients[0].Call(&lpubkey, "pss_getPublicKey")
   889  	if err != nil {
   890  		t.Fatalf("rpc get node 1 pubkey fail: %v", err)
   891  	}
   892  	var rpubkey string
   893  	err = clients[1].Call(&rpubkey, "pss_getPublicKey")
   894  	if err != nil {
   895  		t.Fatalf("rpc get node 2 pubkey fail: %v", err)
   896  	}
   897  
   898  time.Sleep(time.Millisecond * 500) //
   899  
   900  	lmsgC := make(chan APIMsg)
   901  	lctx, lcancel := context.WithTimeout(context.Background(), time.Second*10)
   902  	defer lcancel()
   903  	lsub, err := clients[0].Subscribe(lctx, "pss", lmsgC, "receive", topic)
   904  	log.Trace("lsub", "id", lsub)
   905  	defer lsub.Unsubscribe()
   906  	rmsgC := make(chan APIMsg)
   907  	rctx, rcancel := context.WithTimeout(context.Background(), time.Second*10)
   908  	defer rcancel()
   909  	rsub, err := clients[1].Subscribe(rctx, "pss", rmsgC, "receive", topic)
   910  	log.Trace("rsub", "id", rsub)
   911  	defer rsub.Unsubscribe()
   912  
   913  //
   914  	err = clients[0].Call(nil, "pss_setPeerPublicKey", rpubkey, topic, roaddrhex)
   915  	if err != nil {
   916  		t.Fatal(err)
   917  	}
   918  	err = clients[1].Call(nil, "pss_setPeerPublicKey", lpubkey, topic, loaddrhex)
   919  	if err != nil {
   920  		t.Fatal(err)
   921  	}
   922  
   923  //
   924  	rmsg := []byte("xyzzy")
   925  	err = clients[0].Call(nil, "pss_sendAsym", rpubkey, topic, hexutil.Encode(rmsg))
   926  	if err != nil {
   927  		t.Fatal(err)
   928  	}
   929  	select {
   930  	case recvmsg := <-rmsgC:
   931  		if !bytes.Equal(recvmsg.Msg, rmsg) {
   932  			t.Fatalf("node 2 received payload mismatch: expected %v, got %v", rmsg, recvmsg.Msg)
   933  		}
   934  	case cerr := <-rctx.Done():
   935  		t.Fatalf("test message timed out: %v", cerr)
   936  	}
   937  	lmsg := []byte("plugh")
   938  	err = clients[1].Call(nil, "pss_sendAsym", lpubkey, topic, hexutil.Encode(lmsg))
   939  	if err != nil {
   940  		t.Fatal(err)
   941  	}
   942  	select {
   943  	case recvmsg := <-lmsgC:
   944  		if !bytes.Equal(recvmsg.Msg, lmsg) {
   945  			t.Fatalf("node 1 received payload mismatch: expected %v, got %v", lmsg, recvmsg.Msg)
   946  		}
   947  	case cerr := <-lctx.Done():
   948  		t.Fatalf("test message timed out: %v", cerr)
   949  	}
   950  }
   951  
   952  type Job struct {
   953  	Msg      []byte
   954  	SendNode discover.NodeID
   955  	RecvNode discover.NodeID
   956  }
   957  
   958  func worker(id int, jobs <-chan Job, rpcs map[discover.NodeID]*rpc.Client, pubkeys map[discover.NodeID]string, topic string) {
   959  	for j := range jobs {
   960  		rpcs[j.SendNode].Call(nil, "pss_sendAsym", pubkeys[j.RecvNode], topic, hexutil.Encode(j.Msg))
   961  	}
   962  }
   963  
   964  func TestNetwork(t *testing.T) {
   965  	t.Run("16/1000/4/sim", testNetwork)
   966  }
   967  
   968  //
   969  //
   970  //
   971  func TestNetwork2000(t *testing.T) {
   972  //
   973  
   974  	if !*longrunning {
   975  		t.Skip("run with --longrunning flag to run extensive network tests")
   976  	}
   977  	t.Run("3/2000/4/sim", testNetwork)
   978  	t.Run("4/2000/4/sim", testNetwork)
   979  	t.Run("8/2000/4/sim", testNetwork)
   980  	t.Run("16/2000/4/sim", testNetwork)
   981  }
   982  
   983  func TestNetwork5000(t *testing.T) {
   984  //
   985  
   986  	if !*longrunning {
   987  		t.Skip("run with --longrunning flag to run extensive network tests")
   988  	}
   989  	t.Run("3/5000/4/sim", testNetwork)
   990  	t.Run("4/5000/4/sim", testNetwork)
   991  	t.Run("8/5000/4/sim", testNetwork)
   992  	t.Run("16/5000/4/sim", testNetwork)
   993  }
   994  
   995  func TestNetwork10000(t *testing.T) {
   996  //
   997  
   998  	if !*longrunning {
   999  		t.Skip("run with --longrunning flag to run extensive network tests")
  1000  	}
  1001  	t.Run("3/10000/4/sim", testNetwork)
  1002  	t.Run("4/10000/4/sim", testNetwork)
  1003  	t.Run("8/10000/4/sim", testNetwork)
  1004  }
  1005  
  1006  func testNetwork(t *testing.T) {
  1007  	type msgnotifyC struct {
  1008  		id     discover.NodeID
  1009  		msgIdx int
  1010  	}
  1011  
  1012  	paramstring := strings.Split(t.Name(), "/")
  1013  	nodecount, _ := strconv.ParseInt(paramstring[1], 10, 0)
  1014  	msgcount, _ := strconv.ParseInt(paramstring[2], 10, 0)
  1015  	addrsize, _ := strconv.ParseInt(paramstring[3], 10, 0)
  1016  	adapter := paramstring[4]
  1017  
  1018  	log.Info("network test", "nodecount", nodecount, "msgcount", msgcount, "addrhintsize", addrsize)
  1019  
  1020  	nodes := make([]discover.NodeID, nodecount)
  1021  	bzzaddrs := make(map[discover.NodeID]string, nodecount)
  1022  	rpcs := make(map[discover.NodeID]*rpc.Client, nodecount)
  1023  	pubkeys := make(map[discover.NodeID]string, nodecount)
  1024  
  1025  	sentmsgs := make([][]byte, msgcount)
  1026  	recvmsgs := make([]bool, msgcount)
  1027  	nodemsgcount := make(map[discover.NodeID]int, nodecount)
  1028  
  1029  	trigger := make(chan discover.NodeID)
  1030  
  1031  	var a adapters.NodeAdapter
  1032  	if adapter == "exec" {
  1033  		dirname, err := ioutil.TempDir(".", "")
  1034  		if err != nil {
  1035  			t.Fatal(err)
  1036  		}
  1037  		a = adapters.NewExecAdapter(dirname)
  1038  	} else if adapter == "tcp" {
  1039  		a = adapters.NewTCPAdapter(newServices(false))
  1040  	} else if adapter == "sim" {
  1041  		a = adapters.NewSimAdapter(newServices(false))
  1042  	}
  1043  	net := simulations.NewNetwork(a, &simulations.NetworkConfig{
  1044  		ID: "0",
  1045  	})
  1046  	defer net.Shutdown()
  1047  
  1048  	f, err := os.Open(fmt.Sprintf("testdata/snapshot_%d.json", nodecount))
  1049  	if err != nil {
  1050  		t.Fatal(err)
  1051  	}
  1052  	jsonbyte, err := ioutil.ReadAll(f)
  1053  	if err != nil {
  1054  		t.Fatal(err)
  1055  	}
  1056  	var snap simulations.Snapshot
  1057  	err = json.Unmarshal(jsonbyte, &snap)
  1058  	if err != nil {
  1059  		t.Fatal(err)
  1060  	}
  1061  	err = net.Load(&snap)
  1062  	if err != nil {
  1063  //
  1064  //
  1065  	}
  1066  
  1067  	time.Sleep(1 * time.Second)
  1068  
  1069  	triggerChecks := func(trigger chan discover.NodeID, id discover.NodeID, rpcclient *rpc.Client, topic string) error {
  1070  		msgC := make(chan APIMsg)
  1071  		ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
  1072  		defer cancel()
  1073  		sub, err := rpcclient.Subscribe(ctx, "pss", msgC, "receive", topic)
  1074  		if err != nil {
  1075  			t.Fatal(err)
  1076  		}
  1077  		go func() {
  1078  			defer sub.Unsubscribe()
  1079  			for {
  1080  				select {
  1081  				case recvmsg := <-msgC:
  1082  					idx, _ := binary.Uvarint(recvmsg.Msg)
  1083  					if !recvmsgs[idx] {
  1084  						log.Debug("msg recv", "idx", idx, "id", id)
  1085  						recvmsgs[idx] = true
  1086  						trigger <- id
  1087  					}
  1088  				case <-sub.Err():
  1089  					return
  1090  				}
  1091  			}
  1092  		}()
  1093  		return nil
  1094  	}
  1095  
  1096  	var topic string
  1097  	for i, nod := range net.GetNodes() {
  1098  		nodes[i] = nod.ID()
  1099  		rpcs[nodes[i]], err = nod.Client()
  1100  		if err != nil {
  1101  			t.Fatal(err)
  1102  		}
  1103  		if topic == "" {
  1104  			err = rpcs[nodes[i]].Call(&topic, "pss_stringToTopic", "foo:42")
  1105  			if err != nil {
  1106  				t.Fatal(err)
  1107  			}
  1108  		}
  1109  		var pubkey string
  1110  		err = rpcs[nodes[i]].Call(&pubkey, "pss_getPublicKey")
  1111  		if err != nil {
  1112  			t.Fatal(err)
  1113  		}
  1114  		pubkeys[nod.ID()] = pubkey
  1115  		var addrhex string
  1116  		err = rpcs[nodes[i]].Call(&addrhex, "pss_baseAddr")
  1117  		if err != nil {
  1118  			t.Fatal(err)
  1119  		}
  1120  		bzzaddrs[nodes[i]] = addrhex
  1121  		err = triggerChecks(trigger, nodes[i], rpcs[nodes[i]], topic)
  1122  		if err != nil {
  1123  			t.Fatal(err)
  1124  		}
  1125  	}
  1126  
  1127  	time.Sleep(1 * time.Second)
  1128  
  1129  //
  1130  	jobs := make(chan Job, 10)
  1131  	for w := 1; w <= 10; w++ {
  1132  		go worker(w, jobs, rpcs, pubkeys, topic)
  1133  	}
  1134  
  1135  	time.Sleep(1 * time.Second)
  1136  
  1137  	for i := 0; i < int(msgcount); i++ {
  1138  		sendnodeidx := rand.Intn(int(nodecount))
  1139  		recvnodeidx := rand.Intn(int(nodecount - 1))
  1140  		if recvnodeidx >= sendnodeidx {
  1141  			recvnodeidx++
  1142  		}
  1143  		nodemsgcount[nodes[recvnodeidx]]++
  1144  		sentmsgs[i] = make([]byte, 8)
  1145  		c := binary.PutUvarint(sentmsgs[i], uint64(i))
  1146  		if c == 0 {
  1147  			t.Fatal("0 byte message")
  1148  		}
  1149  		if err != nil {
  1150  			t.Fatal(err)
  1151  		}
  1152  		err = rpcs[nodes[sendnodeidx]].Call(nil, "pss_setPeerPublicKey", pubkeys[nodes[recvnodeidx]], topic, bzzaddrs[nodes[recvnodeidx]])
  1153  		if err != nil {
  1154  			t.Fatal(err)
  1155  		}
  1156  
  1157  		jobs <- Job{
  1158  			Msg:      sentmsgs[i],
  1159  			SendNode: nodes[sendnodeidx],
  1160  			RecvNode: nodes[recvnodeidx],
  1161  		}
  1162  	}
  1163  
  1164  	finalmsgcount := 0
  1165  	ctx, cancel := context.WithTimeout(context.Background(), 120*time.Second)
  1166  	defer cancel()
  1167  outer:
  1168  	for i := 0; i < int(msgcount); i++ {
  1169  		select {
  1170  		case id := <-trigger:
  1171  			nodemsgcount[id]--
  1172  			finalmsgcount++
  1173  		case <-ctx.Done():
  1174  			log.Warn("timeout")
  1175  			break outer
  1176  		}
  1177  	}
  1178  
  1179  	for i, msg := range recvmsgs {
  1180  		if !msg {
  1181  			log.Debug("missing message", "idx", i)
  1182  		}
  1183  	}
  1184  	t.Logf("%d of %d messages received", finalmsgcount, msgcount)
  1185  
  1186  	if finalmsgcount != int(msgcount) {
  1187  		t.Fatalf("%d messages were not received", int(msgcount)-finalmsgcount)
  1188  	}
  1189  
  1190  }
  1191  
  1192  //
  1193  //
  1194  func TestDeduplication(t *testing.T) {
  1195  	var err error
  1196  
  1197  	clients, err := setupNetwork(3, false)
  1198  	if err != nil {
  1199  		t.Fatal(err)
  1200  	}
  1201  
  1202  	var addrsize = 32
  1203  	var loaddrhex string
  1204  	err = clients[0].Call(&loaddrhex, "pss_baseAddr")
  1205  	if err != nil {
  1206  		t.Fatalf("rpc get node 1 baseaddr fail: %v", err)
  1207  	}
  1208  	loaddrhex = loaddrhex[:2+(addrsize*2)]
  1209  	var roaddrhex string
  1210  	err = clients[1].Call(&roaddrhex, "pss_baseAddr")
  1211  	if err != nil {
  1212  		t.Fatalf("rpc get node 2 baseaddr fail: %v", err)
  1213  	}
  1214  	roaddrhex = roaddrhex[:2+(addrsize*2)]
  1215  	var xoaddrhex string
  1216  	err = clients[2].Call(&xoaddrhex, "pss_baseAddr")
  1217  	if err != nil {
  1218  		t.Fatalf("rpc get node 3 baseaddr fail: %v", err)
  1219  	}
  1220  	xoaddrhex = xoaddrhex[:2+(addrsize*2)]
  1221  
  1222  	log.Info("peer", "l", loaddrhex, "r", roaddrhex, "x", xoaddrhex)
  1223  
  1224  	var topic string
  1225  	err = clients[0].Call(&topic, "pss_stringToTopic", "foo:42")
  1226  	if err != nil {
  1227  		t.Fatal(err)
  1228  	}
  1229  
  1230  	time.Sleep(time.Millisecond * 250)
  1231  
  1232  //
  1233  //
  1234  	var rpubkey string
  1235  	err = clients[1].Call(&rpubkey, "pss_getPublicKey")
  1236  	if err != nil {
  1237  		t.Fatalf("rpc get receivenode pubkey fail: %v", err)
  1238  	}
  1239  
  1240  time.Sleep(time.Millisecond * 500) //
  1241  
  1242  	rmsgC := make(chan APIMsg)
  1243  	rctx, cancel := context.WithTimeout(context.Background(), time.Second*1)
  1244  	defer cancel()
  1245  	rsub, err := clients[1].Subscribe(rctx, "pss", rmsgC, "receive", topic)
  1246  	log.Trace("rsub", "id", rsub)
  1247  	defer rsub.Unsubscribe()
  1248  
  1249  //
  1250  //
  1251  //
  1252  	err = clients[0].Call(nil, "pss_setPeerPublicKey", rpubkey, topic, "0x")
  1253  	if err != nil {
  1254  		t.Fatal(err)
  1255  	}
  1256  
  1257  //
  1258  	rmsg := []byte("xyzzy")
  1259  	err = clients[0].Call(nil, "pss_sendAsym", rpubkey, topic, hexutil.Encode(rmsg))
  1260  	if err != nil {
  1261  		t.Fatal(err)
  1262  	}
  1263  
  1264  	var receivedok bool
  1265  OUTER:
  1266  	for {
  1267  		select {
  1268  		case <-rmsgC:
  1269  			if receivedok {
  1270  				t.Fatalf("duplicate message received")
  1271  			}
  1272  			receivedok = true
  1273  		case <-rctx.Done():
  1274  			break OUTER
  1275  		}
  1276  	}
  1277  	if !receivedok {
  1278  		t.Fatalf("message did not arrive")
  1279  	}
  1280  }
  1281  
  1282  //
  1283  func BenchmarkSymkeySend(b *testing.B) {
  1284  	b.Run(fmt.Sprintf("%d", 256), benchmarkSymKeySend)
  1285  	b.Run(fmt.Sprintf("%d", 1024), benchmarkSymKeySend)
  1286  	b.Run(fmt.Sprintf("%d", 1024*1024), benchmarkSymKeySend)
  1287  	b.Run(fmt.Sprintf("%d", 1024*1024*10), benchmarkSymKeySend)
  1288  	b.Run(fmt.Sprintf("%d", 1024*1024*100), benchmarkSymKeySend)
  1289  }
  1290  
  1291  func benchmarkSymKeySend(b *testing.B) {
  1292  	msgsizestring := strings.Split(b.Name(), "/")
  1293  	if len(msgsizestring) != 2 {
  1294  		b.Fatalf("benchmark called without msgsize param")
  1295  	}
  1296  	msgsize, err := strconv.ParseInt(msgsizestring[1], 10, 0)
  1297  	if err != nil {
  1298  		b.Fatalf("benchmark called with invalid msgsize param '%s': %v", msgsizestring[1], err)
  1299  	}
  1300  	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
  1301  	defer cancel()
  1302  	keys, err := wapi.NewKeyPair(ctx)
  1303  	privkey, err := w.GetPrivateKey(keys)
  1304  	ps := newTestPss(privkey, nil, nil)
  1305  	msg := make([]byte, msgsize)
  1306  	rand.Read(msg)
  1307  	topic := BytesToTopic([]byte("foo"))
  1308  	to := make(PssAddress, 32)
  1309  	copy(to[:], network.RandomAddr().Over())
  1310  	symkeyid, err := ps.GenerateSymmetricKey(topic, &to, true)
  1311  	if err != nil {
  1312  		b.Fatalf("could not generate symkey: %v", err)
  1313  	}
  1314  	symkey, err := ps.w.GetSymKey(symkeyid)
  1315  	if err != nil {
  1316  		b.Fatalf("could not retrieve symkey: %v", err)
  1317  	}
  1318  	ps.SetSymmetricKey(symkey, topic, &to, false)
  1319  
  1320  	b.ResetTimer()
  1321  	for i := 0; i < b.N; i++ {
  1322  		ps.SendSym(symkeyid, topic, msg)
  1323  	}
  1324  }
  1325  
  1326  //
  1327  func BenchmarkAsymkeySend(b *testing.B) {
  1328  	b.Run(fmt.Sprintf("%d", 256), benchmarkAsymKeySend)
  1329  	b.Run(fmt.Sprintf("%d", 1024), benchmarkAsymKeySend)
  1330  	b.Run(fmt.Sprintf("%d", 1024*1024), benchmarkAsymKeySend)
  1331  	b.Run(fmt.Sprintf("%d", 1024*1024*10), benchmarkAsymKeySend)
  1332  	b.Run(fmt.Sprintf("%d", 1024*1024*100), benchmarkAsymKeySend)
  1333  }
  1334  
  1335  func benchmarkAsymKeySend(b *testing.B) {
  1336  	msgsizestring := strings.Split(b.Name(), "/")
  1337  	if len(msgsizestring) != 2 {
  1338  		b.Fatalf("benchmark called without msgsize param")
  1339  	}
  1340  	msgsize, err := strconv.ParseInt(msgsizestring[1], 10, 0)
  1341  	if err != nil {
  1342  		b.Fatalf("benchmark called with invalid msgsize param '%s': %v", msgsizestring[1], err)
  1343  	}
  1344  	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
  1345  	defer cancel()
  1346  	keys, err := wapi.NewKeyPair(ctx)
  1347  	privkey, err := w.GetPrivateKey(keys)
  1348  	ps := newTestPss(privkey, nil, nil)
  1349  	msg := make([]byte, msgsize)
  1350  	rand.Read(msg)
  1351  	topic := BytesToTopic([]byte("foo"))
  1352  	to := make(PssAddress, 32)
  1353  	copy(to[:], network.RandomAddr().Over())
  1354  	ps.SetPeerPublicKey(&privkey.PublicKey, topic, &to)
  1355  	b.ResetTimer()
  1356  	for i := 0; i < b.N; i++ {
  1357  		ps.SendAsym(common.ToHex(crypto.FromECDSAPub(&privkey.PublicKey)), topic, msg)
  1358  	}
  1359  }
  1360  func BenchmarkSymkeyBruteforceChangeaddr(b *testing.B) {
  1361  	for i := 100; i < 100000; i = i * 10 {
  1362  		for j := 32; j < 10000; j = j * 8 {
  1363  			b.Run(fmt.Sprintf("%d/%d", i, j), benchmarkSymkeyBruteforceChangeaddr)
  1364  		}
  1365  //
  1366  	}
  1367  }
  1368  
  1369  //
  1370  //
  1371  func benchmarkSymkeyBruteforceChangeaddr(b *testing.B) {
  1372  	keycountstring := strings.Split(b.Name(), "/")
  1373  	cachesize := int64(0)
  1374  	var ps *Pss
  1375  	if len(keycountstring) < 2 {
  1376  		b.Fatalf("benchmark called without count param")
  1377  	}
  1378  	keycount, err := strconv.ParseInt(keycountstring[1], 10, 0)
  1379  	if err != nil {
  1380  		b.Fatalf("benchmark called with invalid count param '%s': %v", keycountstring[1], err)
  1381  	}
  1382  	if len(keycountstring) == 3 {
  1383  		cachesize, err = strconv.ParseInt(keycountstring[2], 10, 0)
  1384  		if err != nil {
  1385  			b.Fatalf("benchmark called with invalid cachesize '%s': %v", keycountstring[2], err)
  1386  		}
  1387  	}
  1388  	pssmsgs := make([]*PssMsg, 0, keycount)
  1389  	var keyid string
  1390  	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
  1391  	defer cancel()
  1392  	keys, err := wapi.NewKeyPair(ctx)
  1393  	privkey, err := w.GetPrivateKey(keys)
  1394  	if cachesize > 0 {
  1395  		ps = newTestPss(privkey, nil, &PssParams{SymKeyCacheCapacity: int(cachesize)})
  1396  	} else {
  1397  		ps = newTestPss(privkey, nil, nil)
  1398  	}
  1399  	topic := BytesToTopic([]byte("foo"))
  1400  	for i := 0; i < int(keycount); i++ {
  1401  		to := make(PssAddress, 32)
  1402  		copy(to[:], network.RandomAddr().Over())
  1403  		keyid, err = ps.GenerateSymmetricKey(topic, &to, true)
  1404  		if err != nil {
  1405  			b.Fatalf("cant generate symkey #%d: %v", i, err)
  1406  		}
  1407  		symkey, err := ps.w.GetSymKey(keyid)
  1408  		if err != nil {
  1409  			b.Fatalf("could not retrieve symkey %s: %v", keyid, err)
  1410  		}
  1411  		wparams := &whisper.MessageParams{
  1412  			TTL:      defaultWhisperTTL,
  1413  			KeySym:   symkey,
  1414  			Topic:    whisper.TopicType(topic),
  1415  			WorkTime: defaultWhisperWorkTime,
  1416  			PoW:      defaultWhisperPoW,
  1417  			Payload:  []byte("xyzzy"),
  1418  			Padding:  []byte("1234567890abcdef"),
  1419  		}
  1420  		woutmsg, err := whisper.NewSentMessage(wparams)
  1421  		if err != nil {
  1422  			b.Fatalf("could not create whisper message: %v", err)
  1423  		}
  1424  		env, err := woutmsg.Wrap(wparams)
  1425  		if err != nil {
  1426  			b.Fatalf("could not generate whisper envelope: %v", err)
  1427  		}
  1428  		ps.Register(&topic, func(msg []byte, p *p2p.Peer, asymmetric bool, keyid string) error {
  1429  			return nil
  1430  		})
  1431  		pssmsgs = append(pssmsgs, &PssMsg{
  1432  			To:      to,
  1433  			Payload: env,
  1434  		})
  1435  	}
  1436  	b.ResetTimer()
  1437  	for i := 0; i < b.N; i++ {
  1438  		if err := ps.process(pssmsgs[len(pssmsgs)-(i%len(pssmsgs))-1]); err != nil {
  1439  			b.Fatalf("pss processing failed: %v", err)
  1440  		}
  1441  	}
  1442  }
  1443  
  1444  func BenchmarkSymkeyBruteforceSameaddr(b *testing.B) {
  1445  	for i := 100; i < 100000; i = i * 10 {
  1446  		for j := 32; j < 10000; j = j * 8 {
  1447  			b.Run(fmt.Sprintf("%d/%d", i, j), benchmarkSymkeyBruteforceSameaddr)
  1448  		}
  1449  	}
  1450  }
  1451  
  1452  //
  1453  //
  1454  func benchmarkSymkeyBruteforceSameaddr(b *testing.B) {
  1455  	var keyid string
  1456  	var ps *Pss
  1457  	cachesize := int64(0)
  1458  	keycountstring := strings.Split(b.Name(), "/")
  1459  	if len(keycountstring) < 2 {
  1460  		b.Fatalf("benchmark called without count param")
  1461  	}
  1462  	keycount, err := strconv.ParseInt(keycountstring[1], 10, 0)
  1463  	if err != nil {
  1464  		b.Fatalf("benchmark called with invalid count param '%s': %v", keycountstring[1], err)
  1465  	}
  1466  	if len(keycountstring) == 3 {
  1467  		cachesize, err = strconv.ParseInt(keycountstring[2], 10, 0)
  1468  		if err != nil {
  1469  			b.Fatalf("benchmark called with invalid cachesize '%s': %v", keycountstring[2], err)
  1470  		}
  1471  	}
  1472  	addr := make([]PssAddress, keycount)
  1473  	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
  1474  	defer cancel()
  1475  	keys, err := wapi.NewKeyPair(ctx)
  1476  	privkey, err := w.GetPrivateKey(keys)
  1477  	if cachesize > 0 {
  1478  		ps = newTestPss(privkey, nil, &PssParams{SymKeyCacheCapacity: int(cachesize)})
  1479  	} else {
  1480  		ps = newTestPss(privkey, nil, nil)
  1481  	}
  1482  	topic := BytesToTopic([]byte("foo"))
  1483  	for i := 0; i < int(keycount); i++ {
  1484  		copy(addr[i], network.RandomAddr().Over())
  1485  		keyid, err = ps.GenerateSymmetricKey(topic, &addr[i], true)
  1486  		if err != nil {
  1487  			b.Fatalf("cant generate symkey #%d: %v", i, err)
  1488  		}
  1489  
  1490  	}
  1491  	symkey, err := ps.w.GetSymKey(keyid)
  1492  	if err != nil {
  1493  		b.Fatalf("could not retrieve symkey %s: %v", keyid, err)
  1494  	}
  1495  	wparams := &whisper.MessageParams{
  1496  		TTL:      defaultWhisperTTL,
  1497  		KeySym:   symkey,
  1498  		Topic:    whisper.TopicType(topic),
  1499  		WorkTime: defaultWhisperWorkTime,
  1500  		PoW:      defaultWhisperPoW,
  1501  		Payload:  []byte("xyzzy"),
  1502  		Padding:  []byte("1234567890abcdef"),
  1503  	}
  1504  	woutmsg, err := whisper.NewSentMessage(wparams)
  1505  	if err != nil {
  1506  		b.Fatalf("could not create whisper message: %v", err)
  1507  	}
  1508  	env, err := woutmsg.Wrap(wparams)
  1509  	if err != nil {
  1510  		b.Fatalf("could not generate whisper envelope: %v", err)
  1511  	}
  1512  	ps.Register(&topic, func(msg []byte, p *p2p.Peer, asymmetric bool, keyid string) error {
  1513  		return nil
  1514  	})
  1515  	pssmsg := &PssMsg{
  1516  		To:      addr[len(addr)-1][:],
  1517  		Payload: env,
  1518  	}
  1519  	for i := 0; i < b.N; i++ {
  1520  		if err := ps.process(pssmsg); err != nil {
  1521  			b.Fatalf("pss processing failed: %v", err)
  1522  		}
  1523  	}
  1524  }
  1525  
  1526  //
  1527  //
  1528  //
  1529  func setupNetwork(numnodes int, allowRaw bool) (clients []*rpc.Client, err error) {
  1530  	nodes := make([]*simulations.Node, numnodes)
  1531  	clients = make([]*rpc.Client, numnodes)
  1532  	if numnodes < 2 {
  1533  		return nil, fmt.Errorf("Minimum two nodes in network")
  1534  	}
  1535  	adapter := adapters.NewSimAdapter(newServices(allowRaw))
  1536  	net := simulations.NewNetwork(adapter, &simulations.NetworkConfig{
  1537  		ID:             "0",
  1538  		DefaultService: "bzz",
  1539  	})
  1540  	for i := 0; i < numnodes; i++ {
  1541  		nodeconf := adapters.RandomNodeConfig()
  1542  		nodeconf.Services = []string{"bzz", pssProtocolName}
  1543  		nodes[i], err = net.NewNodeWithConfig(nodeconf)
  1544  		if err != nil {
  1545  			return nil, fmt.Errorf("error creating node 1: %v", err)
  1546  		}
  1547  		err = net.Start(nodes[i].ID())
  1548  		if err != nil {
  1549  			return nil, fmt.Errorf("error starting node 1: %v", err)
  1550  		}
  1551  		if i > 0 {
  1552  			err = net.Connect(nodes[i].ID(), nodes[i-1].ID())
  1553  			if err != nil {
  1554  				return nil, fmt.Errorf("error connecting nodes: %v", err)
  1555  			}
  1556  		}
  1557  		clients[i], err = nodes[i].Client()
  1558  		if err != nil {
  1559  			return nil, fmt.Errorf("create node 1 rpc client fail: %v", err)
  1560  		}
  1561  	}
  1562  	if numnodes > 2 {
  1563  		err = net.Connect(nodes[0].ID(), nodes[len(nodes)-1].ID())
  1564  		if err != nil {
  1565  			return nil, fmt.Errorf("error connecting first and last nodes")
  1566  		}
  1567  	}
  1568  	return clients, nil
  1569  }
  1570  
  1571  func newServices(allowRaw bool) adapters.Services {
  1572  	stateStore := state.NewInmemoryStore()
  1573  	kademlias := make(map[discover.NodeID]*network.Kademlia)
  1574  	kademlia := func(id discover.NodeID) *network.Kademlia {
  1575  		if k, ok := kademlias[id]; ok {
  1576  			return k
  1577  		}
  1578  		addr := network.NewAddrFromNodeID(id)
  1579  		params := network.NewKadParams()
  1580  		params.MinProxBinSize = 2
  1581  		params.MaxBinSize = 3
  1582  		params.MinBinSize = 1
  1583  		params.MaxRetries = 1000
  1584  		params.RetryExponent = 2
  1585  		params.RetryInterval = 1000000
  1586  		kademlias[id] = network.NewKademlia(addr.Over(), params)
  1587  		return kademlias[id]
  1588  	}
  1589  	return adapters.Services{
  1590  		pssProtocolName: func(ctx *adapters.ServiceContext) (node.Service, error) {
  1591  //
  1592  			initTest()
  1593  
  1594  			ctxlocal, cancel := context.WithTimeout(context.Background(), time.Second)
  1595  			defer cancel()
  1596  			keys, err := wapi.NewKeyPair(ctxlocal)
  1597  			privkey, err := w.GetPrivateKey(keys)
  1598  			pssp := NewPssParams().WithPrivateKey(privkey)
  1599  			pssp.AllowRaw = allowRaw
  1600  			pskad := kademlia(ctx.Config.ID)
  1601  			ps, err := NewPss(pskad, pssp)
  1602  			if err != nil {
  1603  				return nil, err
  1604  			}
  1605  
  1606  			ping := &Ping{
  1607  				OutC: make(chan bool),
  1608  				Pong: true,
  1609  			}
  1610  			p2pp := NewPingProtocol(ping)
  1611  			pp, err := RegisterProtocol(ps, &PingTopic, PingProtocol, p2pp, &ProtocolParams{Asymmetric: true})
  1612  			if err != nil {
  1613  				return nil, err
  1614  			}
  1615  			if useHandshake {
  1616  				SetHandshakeController(ps, NewHandshakeParams())
  1617  			}
  1618  			ps.Register(&PingTopic, pp.Handle)
  1619  			ps.addAPI(rpc.API{
  1620  				Namespace: "psstest",
  1621  				Version:   "0.3",
  1622  				Service:   NewAPITest(ps),
  1623  				Public:    false,
  1624  			})
  1625  			if err != nil {
  1626  				log.Error("Couldnt register pss protocol", "err", err)
  1627  				os.Exit(1)
  1628  			}
  1629  			pssprotocols[ctx.Config.ID.String()] = &protoCtrl{
  1630  				C:        ping.OutC,
  1631  				protocol: pp,
  1632  				run:      p2pp.Run,
  1633  			}
  1634  			return ps, nil
  1635  		},
  1636  		"bzz": func(ctx *adapters.ServiceContext) (node.Service, error) {
  1637  			addr := network.NewAddrFromNodeID(ctx.Config.ID)
  1638  			hp := network.NewHiveParams()
  1639  			hp.Discovery = false
  1640  			config := &network.BzzConfig{
  1641  				OverlayAddr:  addr.Over(),
  1642  				UnderlayAddr: addr.Under(),
  1643  				HiveParams:   hp,
  1644  			}
  1645  			return network.NewBzz(config, kademlia(ctx.Config.ID), stateStore, nil, nil), nil
  1646  		},
  1647  	}
  1648  }
  1649  
  1650  func newTestPss(privkey *ecdsa.PrivateKey, overlay network.Overlay, ppextra *PssParams) *Pss {
  1651  
  1652  	var nid discover.NodeID
  1653  	copy(nid[:], crypto.FromECDSAPub(&privkey.PublicKey))
  1654  	addr := network.NewAddrFromNodeID(nid)
  1655  
  1656  //
  1657  	if overlay == nil {
  1658  		kp := network.NewKadParams()
  1659  		kp.MinProxBinSize = 3
  1660  		overlay = network.NewKademlia(addr.Over(), kp)
  1661  	}
  1662  
  1663  //
  1664  	pp := NewPssParams().WithPrivateKey(privkey)
  1665  	if ppextra != nil {
  1666  		pp.SymKeyCacheCapacity = ppextra.SymKeyCacheCapacity
  1667  	}
  1668  	ps, err := NewPss(overlay, pp)
  1669  	if err != nil {
  1670  		return nil
  1671  	}
  1672  	ps.Start(nil)
  1673  
  1674  	return ps
  1675  }
  1676  
  1677  //
  1678  type APITest struct {
  1679  	*Pss
  1680  }
  1681  
  1682  func NewAPITest(ps *Pss) *APITest {
  1683  	return &APITest{Pss: ps}
  1684  }
  1685  
  1686  func (apitest *APITest) SetSymKeys(pubkeyid string, recvsymkey []byte, sendsymkey []byte, limit uint16, topic Topic, to PssAddress) ([2]string, error) {
  1687  	recvsymkeyid, err := apitest.SetSymmetricKey(recvsymkey, topic, &to, true)
  1688  	if err != nil {
  1689  		return [2]string{}, err
  1690  	}
  1691  	sendsymkeyid, err := apitest.SetSymmetricKey(sendsymkey, topic, &to, false)
  1692  	if err != nil {
  1693  		return [2]string{}, err
  1694  	}
  1695  	return [2]string{recvsymkeyid, sendsymkeyid}, nil
  1696  }
  1697  
  1698  func (apitest *APITest) Clean() (int, error) {
  1699  	return apitest.Pss.cleanKeys(), nil
  1700  }
  1701  
  1702  //
  1703  func enableMetrics() {
  1704  	metrics.Enabled = true
  1705  go influxdb.InfluxDBWithTags(metrics.DefaultRegistry, 1*time.Second, "http://
  1706  		"host": "test",
  1707  	})
  1708  }
  1709