github.com/linapex/ethereum-dpos-chinese@v0.0.0-20190316121959-b78b3a4a1ece/swarm/pss/notify/notify_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:48</date>
    10  //</624342677860651008>
    11  
    12  package notify
    13  
    14  import (
    15  	"bytes"
    16  	"context"
    17  	"flag"
    18  	"fmt"
    19  	"os"
    20  	"testing"
    21  	"time"
    22  
    23  	"github.com/ethereum/go-ethereum/common/hexutil"
    24  	"github.com/ethereum/go-ethereum/crypto"
    25  	"github.com/ethereum/go-ethereum/log"
    26  	"github.com/ethereum/go-ethereum/node"
    27  	"github.com/ethereum/go-ethereum/p2p/discover"
    28  	"github.com/ethereum/go-ethereum/p2p/simulations"
    29  	"github.com/ethereum/go-ethereum/p2p/simulations/adapters"
    30  	"github.com/ethereum/go-ethereum/swarm/network"
    31  	"github.com/ethereum/go-ethereum/swarm/pss"
    32  	"github.com/ethereum/go-ethereum/swarm/state"
    33  	whisper "github.com/ethereum/go-ethereum/whisper/whisperv5"
    34  )
    35  
    36  var (
    37  	loglevel = flag.Int("l", 3, "loglevel")
    38  	psses    map[string]*pss.Pss
    39  	w        *whisper.Whisper
    40  	wapi     *whisper.PublicWhisperAPI
    41  )
    42  
    43  func init() {
    44  	flag.Parse()
    45  	hs := log.StreamHandler(os.Stderr, log.TerminalFormat(true))
    46  	hf := log.LvlFilterHandler(log.Lvl(*loglevel), hs)
    47  	h := log.CallerFileHandler(hf)
    48  	log.Root().SetHandler(h)
    49  
    50  	w = whisper.New(&whisper.DefaultConfig)
    51  	wapi = whisper.NewPublicWhisperAPI(w)
    52  	psses = make(map[string]*pss.Pss)
    53  }
    54  
    55  //
    56  //
    57  //
    58  //
    59  func TestStart(t *testing.T) {
    60  	adapter := adapters.NewSimAdapter(newServices(false))
    61  	net := simulations.NewNetwork(adapter, &simulations.NetworkConfig{
    62  		ID:             "0",
    63  		DefaultService: "bzz",
    64  	})
    65  	leftNodeConf := adapters.RandomNodeConfig()
    66  	leftNodeConf.Services = []string{"bzz", "pss"}
    67  	leftNode, err := net.NewNodeWithConfig(leftNodeConf)
    68  	if err != nil {
    69  		t.Fatal(err)
    70  	}
    71  	err = net.Start(leftNode.ID())
    72  	if err != nil {
    73  		t.Fatal(err)
    74  	}
    75  
    76  	rightNodeConf := adapters.RandomNodeConfig()
    77  	rightNodeConf.Services = []string{"bzz", "pss"}
    78  	rightNode, err := net.NewNodeWithConfig(rightNodeConf)
    79  	if err != nil {
    80  		t.Fatal(err)
    81  	}
    82  	err = net.Start(rightNode.ID())
    83  	if err != nil {
    84  		t.Fatal(err)
    85  	}
    86  
    87  	err = net.Connect(rightNode.ID(), leftNode.ID())
    88  	if err != nil {
    89  		t.Fatal(err)
    90  	}
    91  
    92  	leftRpc, err := leftNode.Client()
    93  	if err != nil {
    94  		t.Fatal(err)
    95  	}
    96  
    97  	rightRpc, err := rightNode.Client()
    98  	if err != nil {
    99  		t.Fatal(err)
   100  	}
   101  
   102  	var leftAddr string
   103  	err = leftRpc.Call(&leftAddr, "pss_baseAddr")
   104  	if err != nil {
   105  		t.Fatal(err)
   106  	}
   107  
   108  	var rightAddr string
   109  	err = rightRpc.Call(&rightAddr, "pss_baseAddr")
   110  	if err != nil {
   111  		t.Fatal(err)
   112  	}
   113  
   114  	var leftPub string
   115  	err = leftRpc.Call(&leftPub, "pss_getPublicKey")
   116  	if err != nil {
   117  		t.Fatal(err)
   118  	}
   119  
   120  	var rightPub string
   121  	err = rightRpc.Call(&rightPub, "pss_getPublicKey")
   122  	if err != nil {
   123  		t.Fatal(err)
   124  	}
   125  
   126  	rsrcName := "foo.eth"
   127  	rsrcTopic := pss.BytesToTopic([]byte(rsrcName))
   128  
   129  //
   130  	time.Sleep(time.Second)
   131  
   132  	ctx, cancel := context.WithTimeout(context.Background(), time.Second*2)
   133  	defer cancel()
   134  	rmsgC := make(chan *pss.APIMsg)
   135  	rightSub, err := rightRpc.Subscribe(ctx, "pss", rmsgC, "receive", controlTopic)
   136  	if err != nil {
   137  		t.Fatal(err)
   138  	}
   139  	defer rightSub.Unsubscribe()
   140  
   141  	updateC := make(chan []byte)
   142  	updateMsg := []byte{}
   143  	ctrlClient := NewController(psses[rightPub])
   144  	ctrlNotifier := NewController(psses[leftPub])
   145  	ctrlNotifier.NewNotifier("foo.eth", 2, updateC)
   146  
   147  	pubkeybytes, err := hexutil.Decode(leftPub)
   148  	if err != nil {
   149  		t.Fatal(err)
   150  	}
   151  	pubkey, err := crypto.UnmarshalPubkey(pubkeybytes)
   152  	if err != nil {
   153  		t.Fatal(err)
   154  	}
   155  	addrbytes, err := hexutil.Decode(leftAddr)
   156  	if err != nil {
   157  		t.Fatal(err)
   158  	}
   159  	ctrlClient.Subscribe(rsrcName, pubkey, addrbytes, func(s string, b []byte) error {
   160  		if s != "foo.eth" || !bytes.Equal(updateMsg, b) {
   161  			t.Fatalf("unexpected result in client handler: '%s':'%x'", s, b)
   162  		}
   163  		log.Info("client handler receive", "s", s, "b", b)
   164  		return nil
   165  	})
   166  
   167  	var inMsg *pss.APIMsg
   168  	select {
   169  	case inMsg = <-rmsgC:
   170  	case <-ctx.Done():
   171  		t.Fatal(ctx.Err())
   172  	}
   173  
   174  	dMsg, err := NewMsgFromPayload(inMsg.Msg)
   175  	if err != nil {
   176  		t.Fatal(err)
   177  	}
   178  	if dMsg.namestring != rsrcName {
   179  		t.Fatalf("expected name '%s', got '%s'", rsrcName, dMsg.namestring)
   180  	}
   181  	if !bytes.Equal(dMsg.Payload[:len(updateMsg)], updateMsg) {
   182  		t.Fatalf("expected payload first %d bytes '%x', got '%x'", len(updateMsg), updateMsg, dMsg.Payload[:len(updateMsg)])
   183  	}
   184  	if len(updateMsg)+symKeyLength != len(dMsg.Payload) {
   185  		t.Fatalf("expected payload length %d, have %d", len(updateMsg)+symKeyLength, len(dMsg.Payload))
   186  	}
   187  
   188  	rightSubUpdate, err := rightRpc.Subscribe(ctx, "pss", rmsgC, "receive", rsrcTopic)
   189  	if err != nil {
   190  		t.Fatal(err)
   191  	}
   192  	defer rightSubUpdate.Unsubscribe()
   193  
   194  	updateMsg = []byte("plugh")
   195  	updateC <- updateMsg
   196  	select {
   197  	case inMsg = <-rmsgC:
   198  	case <-ctx.Done():
   199  		log.Error("timed out waiting for msg", "topic", fmt.Sprintf("%x", rsrcTopic))
   200  		t.Fatal(ctx.Err())
   201  	}
   202  	dMsg, err = NewMsgFromPayload(inMsg.Msg)
   203  	if err != nil {
   204  		t.Fatal(err)
   205  	}
   206  	if dMsg.namestring != rsrcName {
   207  		t.Fatalf("expected name %s, got %s", rsrcName, dMsg.namestring)
   208  	}
   209  	if !bytes.Equal(dMsg.Payload, updateMsg) {
   210  		t.Fatalf("expected payload '%x', got '%x'", updateMsg, dMsg.Payload)
   211  	}
   212  
   213  }
   214  
   215  func newServices(allowRaw bool) adapters.Services {
   216  	stateStore := state.NewInmemoryStore()
   217  	kademlias := make(map[discover.NodeID]*network.Kademlia)
   218  	kademlia := func(id discover.NodeID) *network.Kademlia {
   219  		if k, ok := kademlias[id]; ok {
   220  			return k
   221  		}
   222  		addr := network.NewAddrFromNodeID(id)
   223  		params := network.NewKadParams()
   224  		params.MinProxBinSize = 2
   225  		params.MaxBinSize = 3
   226  		params.MinBinSize = 1
   227  		params.MaxRetries = 1000
   228  		params.RetryExponent = 2
   229  		params.RetryInterval = 1000000
   230  		kademlias[id] = network.NewKademlia(addr.Over(), params)
   231  		return kademlias[id]
   232  	}
   233  	return adapters.Services{
   234  		"pss": func(ctx *adapters.ServiceContext) (node.Service, error) {
   235  			ctxlocal, cancel := context.WithTimeout(context.Background(), time.Second)
   236  			defer cancel()
   237  			keys, err := wapi.NewKeyPair(ctxlocal)
   238  			privkey, err := w.GetPrivateKey(keys)
   239  			pssp := pss.NewPssParams().WithPrivateKey(privkey)
   240  			pssp.MsgTTL = time.Second * 30
   241  			pssp.AllowRaw = allowRaw
   242  			pskad := kademlia(ctx.Config.ID)
   243  			ps, err := pss.NewPss(pskad, pssp)
   244  			if err != nil {
   245  				return nil, err
   246  			}
   247  //
   248  			psses[hexutil.Encode(crypto.FromECDSAPub(&privkey.PublicKey))] = ps
   249  			return ps, nil
   250  		},
   251  		"bzz": func(ctx *adapters.ServiceContext) (node.Service, error) {
   252  			addr := network.NewAddrFromNodeID(ctx.Config.ID)
   253  			hp := network.NewHiveParams()
   254  			hp.Discovery = false
   255  			config := &network.BzzConfig{
   256  				OverlayAddr:  addr.Over(),
   257  				UnderlayAddr: addr.Under(),
   258  				HiveParams:   hp,
   259  			}
   260  			return network.NewBzz(config, kademlia(ctx.Config.ID), stateStore, nil, nil), nil
   261  		},
   262  	}
   263  }
   264