165 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			165 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // Copyright 2018 The go-ethereum Authors
 | |
| // This file is part of the go-ethereum library.
 | |
| //
 | |
| // The go-ethereum library is free software: you can redistribute it and/or modify
 | |
| // it under the terms of the GNU Lesser General Public License as published by
 | |
| // the Free Software Foundation, either version 3 of the License, or
 | |
| // (at your option) any later version.
 | |
| //
 | |
| // The go-ethereum library is distributed in the hope that it will be useful,
 | |
| // but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 | |
| // GNU Lesser General Public License for more details.
 | |
| //
 | |
| // You should have received a copy of the GNU Lesser General Public License
 | |
| // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
 | |
| 
 | |
| package pss
 | |
| 
 | |
| import (
 | |
| 	"bytes"
 | |
| 	"context"
 | |
| 	"fmt"
 | |
| 	"strconv"
 | |
| 	"strings"
 | |
| 	"testing"
 | |
| 	"time"
 | |
| 
 | |
| 	"github.com/ethereum/go-ethereum/common"
 | |
| 	"github.com/ethereum/go-ethereum/p2p"
 | |
| 	"github.com/ethereum/go-ethereum/p2p/enode"
 | |
| 	"github.com/ethereum/go-ethereum/swarm/log"
 | |
| )
 | |
| 
 | |
| type protoCtrl struct {
 | |
| 	C        chan bool
 | |
| 	protocol *Protocol
 | |
| 	run      func(*p2p.Peer, p2p.MsgReadWriter) error
 | |
| }
 | |
| 
 | |
| // simple ping pong protocol test for the pss devp2p emulation
 | |
| func TestProtocol(t *testing.T) {
 | |
| 	t.Run("32", testProtocol)
 | |
| 	t.Run("8", testProtocol)
 | |
| 	t.Run("0", testProtocol)
 | |
| }
 | |
| 
 | |
| func testProtocol(t *testing.T) {
 | |
| 
 | |
| 	// address hint size
 | |
| 	var addrsize int64
 | |
| 	paramstring := strings.Split(t.Name(), "/")
 | |
| 	addrsize, _ = strconv.ParseInt(paramstring[1], 10, 0)
 | |
| 	log.Info("protocol test", "addrsize", addrsize)
 | |
| 
 | |
| 	topic := PingTopic.String()
 | |
| 
 | |
| 	clients, err := setupNetwork(2, false)
 | |
| 	if err != nil {
 | |
| 		t.Fatal(err)
 | |
| 	}
 | |
| 	var loaddrhex string
 | |
| 	err = clients[0].Call(&loaddrhex, "pss_baseAddr")
 | |
| 	if err != nil {
 | |
| 		t.Fatalf("rpc get node 1 baseaddr fail: %v", err)
 | |
| 	}
 | |
| 	loaddrhex = loaddrhex[:2+(addrsize*2)]
 | |
| 	var roaddrhex string
 | |
| 	err = clients[1].Call(&roaddrhex, "pss_baseAddr")
 | |
| 	if err != nil {
 | |
| 		t.Fatalf("rpc get node 2 baseaddr fail: %v", err)
 | |
| 	}
 | |
| 	roaddrhex = roaddrhex[:2+(addrsize*2)]
 | |
| 	lnodeinfo := &p2p.NodeInfo{}
 | |
| 	err = clients[0].Call(&lnodeinfo, "admin_nodeInfo")
 | |
| 	if err != nil {
 | |
| 		t.Fatalf("rpc nodeinfo node 11 fail: %v", err)
 | |
| 	}
 | |
| 
 | |
| 	var lpubkey string
 | |
| 	err = clients[0].Call(&lpubkey, "pss_getPublicKey")
 | |
| 	if err != nil {
 | |
| 		t.Fatalf("rpc get node 1 pubkey fail: %v", err)
 | |
| 	}
 | |
| 	var rpubkey string
 | |
| 	err = clients[1].Call(&rpubkey, "pss_getPublicKey")
 | |
| 	if err != nil {
 | |
| 		t.Fatalf("rpc get node 2 pubkey fail: %v", err)
 | |
| 	}
 | |
| 
 | |
| 	time.Sleep(time.Millisecond * 1000) // replace with hive healthy code
 | |
| 
 | |
| 	lmsgC := make(chan APIMsg)
 | |
| 	lctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
 | |
| 	defer cancel()
 | |
| 	lsub, err := clients[0].Subscribe(lctx, "pss", lmsgC, "receive", topic, false, false)
 | |
| 	if err != nil {
 | |
| 		t.Fatal(err)
 | |
| 	}
 | |
| 	defer lsub.Unsubscribe()
 | |
| 	rmsgC := make(chan APIMsg)
 | |
| 	rctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
 | |
| 	defer cancel()
 | |
| 	rsub, err := clients[1].Subscribe(rctx, "pss", rmsgC, "receive", topic, false, false)
 | |
| 	if err != nil {
 | |
| 		t.Fatal(err)
 | |
| 	}
 | |
| 	defer rsub.Unsubscribe()
 | |
| 
 | |
| 	// set reciprocal public keys
 | |
| 	err = clients[0].Call(nil, "pss_setPeerPublicKey", rpubkey, topic, roaddrhex)
 | |
| 	if err != nil {
 | |
| 		t.Fatal(err)
 | |
| 	}
 | |
| 	err = clients[1].Call(nil, "pss_setPeerPublicKey", lpubkey, topic, loaddrhex)
 | |
| 	if err != nil {
 | |
| 		t.Fatal(err)
 | |
| 	}
 | |
| 
 | |
| 	// add right peer's public key as protocol peer on left
 | |
| 	p := p2p.NewPeer(enode.ID{}, fmt.Sprintf("%x", common.FromHex(loaddrhex)), []p2p.Cap{})
 | |
| 	_, err = pssprotocols[lnodeinfo.ID].protocol.AddPeer(p, PingTopic, true, rpubkey)
 | |
| 	if err != nil {
 | |
| 		t.Fatal(err)
 | |
| 	}
 | |
| 
 | |
| 	// sends ping asym, checks delivery
 | |
| 	pssprotocols[lnodeinfo.ID].C <- false
 | |
| 	select {
 | |
| 	case <-lmsgC:
 | |
| 		log.Debug("lnode ok")
 | |
| 	case cerr := <-lctx.Done():
 | |
| 		t.Fatalf("test message timed out: %v", cerr)
 | |
| 		return
 | |
| 	}
 | |
| 	select {
 | |
| 	case <-rmsgC:
 | |
| 		log.Debug("rnode ok")
 | |
| 	case cerr := <-lctx.Done():
 | |
| 		t.Fatalf("test message timed out: %v", cerr)
 | |
| 	}
 | |
| 
 | |
| 	// sends ping asym, checks delivery
 | |
| 	pssprotocols[lnodeinfo.ID].C <- false
 | |
| 	select {
 | |
| 	case <-lmsgC:
 | |
| 		log.Debug("lnode ok")
 | |
| 	case cerr := <-lctx.Done():
 | |
| 		t.Fatalf("test message timed out: %v", cerr)
 | |
| 	}
 | |
| 	select {
 | |
| 	case <-rmsgC:
 | |
| 		log.Debug("rnode ok")
 | |
| 	case cerr := <-lctx.Done():
 | |
| 		t.Fatalf("test message timed out: %v", cerr)
 | |
| 	}
 | |
| 	rw := pssprotocols[lnodeinfo.ID].protocol.pubKeyRWPool[rpubkey]
 | |
| 	pssprotocols[lnodeinfo.ID].protocol.RemovePeer(true, rpubkey)
 | |
| 	if err := rw.WriteMsg(p2p.Msg{
 | |
| 		Size:    3,
 | |
| 		Payload: bytes.NewReader([]byte("foo")),
 | |
| 	}); err == nil {
 | |
| 		t.Fatalf("expected error on write")
 | |
| 	}
 | |
| }
 |