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