github.com/jincm/wesharechain@v0.0.0-20210122032815-1537409ce26a/chain/swarm/pss/notify/notify_test.go (about)

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