mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-27 15:16:43 +00:00
swarm/network, p2p: fixes
This commit is contained in:
parent
8cd9adcf38
commit
7f22abaead
13 changed files with 231 additions and 398 deletions
|
|
@ -34,7 +34,6 @@ func newPeer(m Messenger) *Peer {
|
||||||
}
|
}
|
||||||
|
|
||||||
type Peer struct {
|
type Peer struct {
|
||||||
//RW p2p.MsgReadWriter
|
|
||||||
Messenger
|
Messenger
|
||||||
Errc chan error
|
Errc chan error
|
||||||
Flushc chan bool
|
Flushc chan bool
|
||||||
|
|
@ -174,9 +173,9 @@ func (self *SimNode) RunProtocol(id *NodeId, rw, rrw p2p.MsgReadWriter, runc cha
|
||||||
p := p2p.NewPeer(id.NodeID, Name(id.Bytes()), []p2p.Cap{})
|
p := p2p.NewPeer(id.NodeID, Name(id.Bytes()), []p2p.Cap{})
|
||||||
go func() {
|
go func() {
|
||||||
err := self.Run(p, rw)
|
err := self.Run(p, rw)
|
||||||
glog.V(6).Infof("protocol quit on peer %v (connection with %v broken)", self.Id, id)
|
glog.V(6).Infof("protocol quit on peer %v (connection with %v broken: %v)", self.Id, id, err)
|
||||||
<-runc
|
<-runc
|
||||||
self.Disconnect(id.Bytes())
|
// self.Disconnect(id.Bytes())
|
||||||
peer.Errc <- err
|
peer.Errc <- err
|
||||||
}()
|
}()
|
||||||
return nil
|
return nil
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/logger/glog"
|
"github.com/ethereum/go-ethereum/logger/glog"
|
||||||
"github.com/ethereum/go-ethereum/p2p"
|
"github.com/ethereum/go-ethereum/p2p"
|
||||||
"github.com/ethereum/go-ethereum/p2p/adapters"
|
"github.com/ethereum/go-ethereum/p2p/adapters"
|
||||||
|
"github.com/ethereum/go-ethereum/p2p/discover"
|
||||||
)
|
)
|
||||||
|
|
||||||
// error codes used by this protocol scheme
|
// error codes used by this protocol scheme
|
||||||
|
|
@ -158,8 +159,11 @@ func (self *CodeMap) Register(msgs ...interface{}) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewProtocol(protocolname string, protocolversion uint, run func(*Peer) error, na adapters.NodeAdapter, ct *CodeMap) *p2p.Protocol {
|
func NewProtocol(protocolname string, protocolversion uint, run func(*Peer) error, na adapters.NodeAdapter, ct *CodeMap, peerInfo func(id discover.NodeID) interface{}, nodeInfo func() interface{}) *p2p.Protocol {
|
||||||
|
|
||||||
|
// PeerInfo is an optional helper method to retrieve protocol specific metadata
|
||||||
|
// about a certain peer in the network. If an info retrieval function is set,
|
||||||
|
// but returns nil, it is assumed that the protocol handshake is still running.
|
||||||
r := func(p *p2p.Peer, rw p2p.MsgReadWriter) error {
|
r := func(p *p2p.Peer, rw p2p.MsgReadWriter) error {
|
||||||
|
|
||||||
m := na.Messenger(rw)
|
m := na.Messenger(rw)
|
||||||
|
|
@ -180,9 +184,15 @@ func NewProtocol(protocolname string, protocolversion uint, run func(*Peer) erro
|
||||||
Version: protocolversion,
|
Version: protocolversion,
|
||||||
Length: ct.Length(),
|
Length: ct.Length(),
|
||||||
Run: r,
|
Run: r,
|
||||||
|
PeerInfo: peerInfo,
|
||||||
|
NodeInfo: nodeInfo,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Disconnect struct {
|
||||||
|
err error
|
||||||
|
}
|
||||||
|
|
||||||
// A Peer represents a remote peer or protocol instance that is running on a peer connection with
|
// A Peer represents a remote peer or protocol instance that is running on a peer connection with
|
||||||
// a remote peer
|
// a remote peer
|
||||||
type Peer struct {
|
type Peer struct {
|
||||||
|
|
@ -192,6 +202,7 @@ type Peer struct {
|
||||||
rw p2p.MsgReadWriter // p2p.MsgReadWriter to send messages to and read messages from
|
rw p2p.MsgReadWriter // p2p.MsgReadWriter to send messages to and read messages from
|
||||||
handlers map[reflect.Type][]func(interface{}) error // message type -> message handler callback(s) map
|
handlers map[reflect.Type][]func(interface{}) error // message type -> message handler callback(s) map
|
||||||
disconnect func() // Disconnect function set differently for testing
|
disconnect func() // Disconnect function set differently for testing
|
||||||
|
Err error
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewPeer returns a new peer
|
// NewPeer returns a new peer
|
||||||
|
|
@ -222,7 +233,7 @@ func (self *Peer) Register(msg interface{}, handler func(interface{}) error) uin
|
||||||
if !found {
|
if !found {
|
||||||
panic(fmt.Sprintf("message type '%v' unknown ", typ))
|
panic(fmt.Sprintf("message type '%v' unknown ", typ))
|
||||||
}
|
}
|
||||||
glog.V(logger.Detail).Infof("registered handle for %v %v", msg, typ)
|
glog.V(logger.Detail).Infof("register handle for %v", typ)
|
||||||
self.handlers[typ] = append(self.handlers[typ], handler)
|
self.handlers[typ] = append(self.handlers[typ], handler)
|
||||||
return code
|
return code
|
||||||
}
|
}
|
||||||
|
|
@ -233,9 +244,13 @@ func (self *Peer) Run() error {
|
||||||
var err error
|
var err error
|
||||||
for {
|
for {
|
||||||
_, err = self.handleIncoming()
|
_, err = self.handleIncoming()
|
||||||
if err != nil {
|
if self.Err == nil {
|
||||||
return err
|
err = self.Err
|
||||||
}
|
}
|
||||||
|
for _, f := range self.handlers[reflect.TypeOf(&Disconnect{})] {
|
||||||
|
f(err)
|
||||||
|
}
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -245,8 +260,8 @@ func (self *Peer) Run() error {
|
||||||
// TODO: may need to implement protocol drop only? don't want to kick off the peer
|
// TODO: may need to implement protocol drop only? don't want to kick off the peer
|
||||||
// if they are useful for other protocols
|
// if they are useful for other protocols
|
||||||
// overwrite Disconnect for testing, so that protocol readloop quits
|
// overwrite Disconnect for testing, so that protocol readloop quits
|
||||||
func (self *Peer) Drop() {
|
func (self *Peer) Drop(err error) {
|
||||||
self.disconnect()
|
self.Err = err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send takes a message, encodes it in RLP, finds the right message code and sends the
|
// Send takes a message, encodes it in RLP, finds the right message code and sends the
|
||||||
|
|
@ -261,8 +276,9 @@ func (self *Peer) Send(msg interface{}) error {
|
||||||
glog.V(logger.Detail).Infof("=> %v (%d)", msg, code)
|
glog.V(logger.Detail).Infof("=> %v (%d)", msg, code)
|
||||||
err := self.m.SendMsg(uint64(code), msg)
|
err := self.m.SendMsg(uint64(code), msg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
self.Drop()
|
err = errorf(ErrWrite, "(msg code: %v): %v", code, err)
|
||||||
return errorf(ErrWrite, "(msg code: %v): %v", code, err)
|
self.Drop(err)
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,9 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"sync"
|
"sync"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/logger"
|
||||||
"github.com/ethereum/go-ethereum/logger/glog"
|
"github.com/ethereum/go-ethereum/logger/glog"
|
||||||
"github.com/ethereum/go-ethereum/p2p"
|
"github.com/ethereum/go-ethereum/p2p"
|
||||||
"github.com/ethereum/go-ethereum/p2p/adapters"
|
"github.com/ethereum/go-ethereum/p2p/adapters"
|
||||||
|
|
@ -12,7 +14,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
glog.SetV(6)
|
glog.SetV(logger.Detail)
|
||||||
glog.SetToStderr(true)
|
glog.SetToStderr(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -55,9 +57,8 @@ const networkId = "420"
|
||||||
// newProtocol sets up a protocol
|
// newProtocol sets up a protocol
|
||||||
// the run function here demonstrates a typical protocol using peerPool, handshake
|
// the run function here demonstrates a typical protocol using peerPool, handshake
|
||||||
// and messages registered to handlers
|
// and messages registered to handlers
|
||||||
func newProtocol(pp *p2ptest.TestPeerPool, wg *sync.WaitGroup) func(adapters.NodeAdapter) adapters.ProtoCall {
|
func newProtocol(pp *TestPeerPool, wg *sync.WaitGroup) func(adapters.NodeAdapter) adapters.ProtoCall {
|
||||||
ct := NewCodeMap("test", 42, 1024, &protoHandshake{}, &hs0{}, &kill{}, &drop{})
|
ct := NewCodeMap("test", 42, 1024, &protoHandshake{}, &hs0{}, &kill{}, &drop{})
|
||||||
|
|
||||||
return func(na adapters.NodeAdapter) adapters.ProtoCall {
|
return func(na adapters.NodeAdapter) adapters.ProtoCall {
|
||||||
return func(p *p2p.Peer, rw p2p.MsgReadWriter) error {
|
return func(p *p2p.Peer, rw p2p.MsgReadWriter) error {
|
||||||
if wg != nil {
|
if wg != nil {
|
||||||
|
|
@ -69,13 +70,16 @@ func newProtocol(pp *p2ptest.TestPeerPool, wg *sync.WaitGroup) func(adapters.Nod
|
||||||
// demonstrates use of peerPool, killing another peer connection as a response to a message
|
// demonstrates use of peerPool, killing another peer connection as a response to a message
|
||||||
peer.Register(&kill{}, func(msg interface{}) error {
|
peer.Register(&kill{}, func(msg interface{}) error {
|
||||||
id := msg.(*kill).C
|
id := msg.(*kill).C
|
||||||
pp.Get(id).Drop()
|
// pp.Get(id).Drop(fmt.Errorf("killed"))
|
||||||
|
glog.V(logger.Detail).Infof("id %v killed", id)
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
// for testing we can trigger self induced disconnect upon receiving drop message
|
// for testing we can trigger self induced disconnect upon receiving drop message
|
||||||
peer.Register(&drop{}, func(msg interface{}) error {
|
peer.Register(&drop{}, func(msg interface{}) error {
|
||||||
return fmt.Errorf("received disconnect request")
|
glog.V(logger.Detail).Infof("dropped")
|
||||||
|
// return fmt.Errorf("dropped")
|
||||||
|
return
|
||||||
})
|
})
|
||||||
|
|
||||||
// initiate one-off protohandshake and check validity
|
// initiate one-off protohandshake and check validity
|
||||||
|
|
@ -110,20 +114,21 @@ func newProtocol(pp *p2ptest.TestPeerPool, wg *sync.WaitGroup) func(adapters.Nod
|
||||||
return peer.Send(lhs)
|
return peer.Send(lhs)
|
||||||
})
|
})
|
||||||
|
|
||||||
// add/remove peer from pool
|
glog.V(logger.Detail).Infof("adding peer %v", peer)
|
||||||
pp.Add(peer)
|
pp.Add(peer)
|
||||||
defer pp.Remove(peer)
|
defer pp.Remove(peer)
|
||||||
// this launches a forever read loop
|
|
||||||
err = peer.Run()
|
err = peer.Run()
|
||||||
if wg != nil {
|
if wg != nil {
|
||||||
wg.Done()
|
wg.Done()
|
||||||
}
|
}
|
||||||
|
glog.V(logger.Detail).Infof("peer %v protocol quitting: %v", peer, err)
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func protocolTester(t *testing.T, pp *p2ptest.TestPeerPool, wg *sync.WaitGroup) *p2ptest.ExchangeSession {
|
func protocolTester(t *testing.T, pp *TestPeerPool, wg *sync.WaitGroup) *p2ptest.ExchangeSession {
|
||||||
id := p2ptest.RandomNodeId()
|
id := p2ptest.RandomNodeId()
|
||||||
return p2ptest.NewProtocolTester(t, id, 2, newProtocol(pp, wg))
|
return p2ptest.NewProtocolTester(t, id, 2, newProtocol(pp, wg))
|
||||||
}
|
}
|
||||||
|
|
@ -153,7 +158,7 @@ func protoHandshakeExchange(id *adapters.NodeId, proto *protoHandshake) []p2ptes
|
||||||
}
|
}
|
||||||
|
|
||||||
func runProtoHandshake(t *testing.T, proto *protoHandshake, errs ...error) {
|
func runProtoHandshake(t *testing.T, proto *protoHandshake, errs ...error) {
|
||||||
pp := p2ptest.NewTestPeerPool()
|
pp := NewTestPeerPool()
|
||||||
s := protocolTester(t, pp, nil)
|
s := protocolTester(t, pp, nil)
|
||||||
// TODO: make this more than one handshake
|
// TODO: make this more than one handshake
|
||||||
id := s.Ids[0]
|
id := s.Ids[0]
|
||||||
|
|
@ -202,7 +207,7 @@ func moduleHandshakeExchange(id *adapters.NodeId, resp uint) []p2ptest.Exchange
|
||||||
}
|
}
|
||||||
|
|
||||||
func runModuleHandshake(t *testing.T, resp uint, errs ...error) {
|
func runModuleHandshake(t *testing.T, resp uint, errs ...error) {
|
||||||
pp := p2ptest.NewTestPeerPool()
|
pp := NewTestPeerPool()
|
||||||
s := protocolTester(t, pp, nil)
|
s := protocolTester(t, pp, nil)
|
||||||
id := s.Ids[0]
|
id := s.Ids[0]
|
||||||
s.TestExchanges(protoHandshakeExchange(id, &protoHandshake{42, "420"})...)
|
s.TestExchanges(protoHandshakeExchange(id, &protoHandshake{42, "420"})...)
|
||||||
|
|
@ -227,6 +232,7 @@ func testMultiPeerSetup(a, b *adapters.NodeId) []p2ptest.Exchange {
|
||||||
|
|
||||||
return []p2ptest.Exchange{
|
return []p2ptest.Exchange{
|
||||||
p2ptest.Exchange{
|
p2ptest.Exchange{
|
||||||
|
Label: "primary handshake",
|
||||||
Expects: []p2ptest.Expect{
|
Expects: []p2ptest.Expect{
|
||||||
p2ptest.Expect{
|
p2ptest.Expect{
|
||||||
Code: 0,
|
Code: 0,
|
||||||
|
|
@ -241,6 +247,7 @@ func testMultiPeerSetup(a, b *adapters.NodeId) []p2ptest.Exchange {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
p2ptest.Exchange{
|
p2ptest.Exchange{
|
||||||
|
Label: "module handshake",
|
||||||
Triggers: []p2ptest.Trigger{
|
Triggers: []p2ptest.Trigger{
|
||||||
p2ptest.Trigger{
|
p2ptest.Trigger{
|
||||||
Code: 0,
|
Code: 0,
|
||||||
|
|
@ -266,53 +273,30 @@ func testMultiPeerSetup(a, b *adapters.NodeId) []p2ptest.Exchange {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
p2ptest.Exchange{
|
|
||||||
Triggers: []p2ptest.Trigger{
|
p2ptest.Exchange{Label: "alternative module handshake", Triggers: []p2ptest.Trigger{p2ptest.Trigger{Code: 1, Msg: &hs0{41}, Peer: a},
|
||||||
p2ptest.Trigger{
|
p2ptest.Trigger{Code: 1, Msg: &hs0{41}, Peer: b}}},
|
||||||
Code: 1,
|
p2ptest.Exchange{Label: "repeated module handshake", Triggers: []p2ptest.Trigger{p2ptest.Trigger{Code: 1, Msg: &hs0{1}, Peer: a}}},
|
||||||
Msg: &hs0{41},
|
p2ptest.Exchange{Label: "receiving repeated module handshake", Expects: []p2ptest.Expect{p2ptest.Expect{Code: 1, Msg: &hs0{43}, Peer: a}}}}
|
||||||
Peer: a,
|
|
||||||
},
|
|
||||||
p2ptest.Trigger{
|
|
||||||
Code: 1,
|
|
||||||
Msg: &hs0{41},
|
|
||||||
Peer: b,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
p2ptest.Exchange{
|
|
||||||
Triggers: []p2ptest.Trigger{
|
|
||||||
p2ptest.Trigger{
|
|
||||||
Code: 1,
|
|
||||||
Msg: &hs0{1},
|
|
||||||
Peer: a,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
p2ptest.Exchange{
|
|
||||||
Expects: []p2ptest.Expect{
|
|
||||||
p2ptest.Expect{
|
|
||||||
Code: 1,
|
|
||||||
Msg: &hs0{43},
|
|
||||||
Peer: a,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func runMultiplePeers(t *testing.T, peer int, errs ...error) {
|
func runMultiplePeers(t *testing.T, peer int, errs ...error) {
|
||||||
wg := &sync.WaitGroup{}
|
wg := &sync.WaitGroup{}
|
||||||
pp := p2ptest.NewTestPeerPool()
|
pp := NewTestPeerPool()
|
||||||
s := protocolTester(t, pp, wg)
|
s := protocolTester(t, pp, wg)
|
||||||
|
|
||||||
s.TestExchanges(testMultiPeerSetup(s.Ids[0], s.Ids[1])...)
|
s.TestExchanges(testMultiPeerSetup(s.Ids[0], s.Ids[1])...)
|
||||||
// after some exchanges of messages, we can test state changes
|
// after some exchanges of messages, we can test state changes
|
||||||
// here this is simply demonstrated by the peerPool
|
// here this is simply demonstrated by the peerPool
|
||||||
// after the handshake negotiations peers must be addded to the pool
|
// after the handshake negotiations peers must be added to the pool
|
||||||
if !pp.Has(s.Ids[0]) {
|
// time.Sleep(1)
|
||||||
t.Fatalf("missing peer test-0: %v (%v)", pp, s.Ids)
|
for !pp.Has(s.Ids[0]) {
|
||||||
|
time.Sleep(1)
|
||||||
|
glog.V(logger.Detail).Infof("missing peer test-0: %v (%v)", pp, s.Ids)
|
||||||
}
|
}
|
||||||
|
// if !pp.Has(s.Ids[0]) {
|
||||||
|
// t.Fatalf("missing peer test-0: %v (%v)", pp, s.Ids)
|
||||||
|
// }
|
||||||
if !pp.Has(s.Ids[1]) {
|
if !pp.Has(s.Ids[1]) {
|
||||||
t.Fatalf("missing peer test-1: %v (%v)", pp, s.Ids)
|
t.Fatalf("missing peer test-1: %v (%v)", pp, s.Ids)
|
||||||
}
|
}
|
||||||
|
|
@ -355,13 +339,13 @@ func runMultiplePeers(t *testing.T, peer int, errs ...error) {
|
||||||
func TestMultiplePeersDropSelf(t *testing.T) {
|
func TestMultiplePeersDropSelf(t *testing.T) {
|
||||||
runMultiplePeers(t, 0,
|
runMultiplePeers(t, 0,
|
||||||
fmt.Errorf("p2p: read or write on closed message pipe"),
|
fmt.Errorf("p2p: read or write on closed message pipe"),
|
||||||
fmt.Errorf("Message handler error: (msg code 3): received disconnect request"),
|
fmt.Errorf("Message handler error: (msg code 3): killed"),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMultiplePeersDropOther(t *testing.T) {
|
func TestMultiplePeersDropOther(t *testing.T) {
|
||||||
runMultiplePeers(t, 1,
|
runMultiplePeers(t, 1,
|
||||||
fmt.Errorf("Message handler error: (msg code 3): received disconnect request"),
|
fmt.Errorf("Message handler error: (msg code 3): dropped"),
|
||||||
fmt.Errorf("p2p: read or write on closed message pipe"),
|
fmt.Errorf("p2p: read or write on closed message pipe"),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,3 @@
|
||||||
// Package protocols helpers_test make it easier to
|
|
||||||
// write protocol tests by providing convenience functions and structures
|
|
||||||
// protocols uses these helpers for its own tests
|
|
||||||
// but ideally should sit in p2p/protocols/testing/ subpackage
|
|
||||||
package testing
|
package testing
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
@ -34,7 +30,6 @@ type TestNetAdapter interface {
|
||||||
}
|
}
|
||||||
|
|
||||||
type TestMessenger interface {
|
type TestMessenger interface {
|
||||||
// MsgPipe([]byte, []byte) p2p,MsgPipe
|
|
||||||
ExpectMsg(uint64, interface{}) error
|
ExpectMsg(uint64, interface{}) error
|
||||||
TriggerMsg(uint64, interface{}) error
|
TriggerMsg(uint64, interface{}) error
|
||||||
}
|
}
|
||||||
|
|
@ -42,6 +37,7 @@ type TestMessenger interface {
|
||||||
// exchanges are the basic units of protocol tests
|
// exchanges are the basic units of protocol tests
|
||||||
// an exchange is defined on a session
|
// an exchange is defined on a session
|
||||||
type Exchange struct {
|
type Exchange struct {
|
||||||
|
Label string
|
||||||
Triggers []Trigger
|
Triggers []Trigger
|
||||||
Expects []Expect
|
Expects []Expect
|
||||||
}
|
}
|
||||||
|
|
@ -62,8 +58,8 @@ type Expect struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type Disconnect struct {
|
type Disconnect struct {
|
||||||
Peer *adapters.NodeId // the peer that expects the message
|
Peer *adapters.NodeId // discconnected peer
|
||||||
Error error
|
Error error // disconnect reason
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewExchangeTestSession takes a network session and Messenger
|
// NewExchangeTestSession takes a network session and Messenger
|
||||||
|
|
@ -81,12 +77,11 @@ func NewExchangeTestSession(t *testing.T, n TestNetAdapter, ids []*adapters.Node
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type TestPeerInfo struct {
|
// type PeerTester struct {
|
||||||
//RW p2p.MsgReadWriter
|
// Messenger TestMessenger
|
||||||
Messenger TestMessenger
|
// Flushc chan bool
|
||||||
Flushc chan bool
|
// Errc chan error
|
||||||
Errc chan error
|
// }
|
||||||
}
|
|
||||||
|
|
||||||
// trigger sends messages from peers
|
// trigger sends messages from peers
|
||||||
func (self *ExchangeTestSession) trigger(trig Trigger) error {
|
func (self *ExchangeTestSession) trigger(trig Trigger) error {
|
||||||
|
|
@ -102,10 +97,10 @@ func (self *ExchangeTestSession) trigger(trig Trigger) error {
|
||||||
errc := make(chan error)
|
errc := make(chan error)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
glog.V(6).Infof("trigger....")
|
glog.V(6).Infof("trigger %v (%v)....", trig.Msg, trig.Code)
|
||||||
//errc <- self.TriggerMsg(rw, trig.Code, trig.Msg)
|
//errc <- self.TriggerMsg(rw, trig.Code, trig.Msg)
|
||||||
errc <- m.(TestMessenger).TriggerMsg(trig.Code, trig.Msg)
|
errc <- m.(TestMessenger).TriggerMsg(trig.Code, trig.Msg)
|
||||||
glog.V(6).Infof("triggered")
|
glog.V(6).Infof("triggered %v (%v)", trig.Msg, trig.Code)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
t := trig.Timeout
|
t := trig.Timeout
|
||||||
|
|
@ -168,18 +163,13 @@ func (self *ExchangeTestSession) TestExchanges(exchanges ...Exchange) {
|
||||||
// launch all triggers of this exchanges
|
// launch all triggers of this exchanges
|
||||||
|
|
||||||
for i, e := range exchanges {
|
for i, e := range exchanges {
|
||||||
errc := make(chan error)
|
errc := make(chan error, 1)
|
||||||
wg := &sync.WaitGroup{}
|
wg := &sync.WaitGroup{}
|
||||||
for _, trig := range e.Triggers {
|
for _, trig := range e.Triggers {
|
||||||
wg.Add(1)
|
err := self.trigger(trig)
|
||||||
// separate go routing to allow parallel requests
|
|
||||||
go func(t Trigger) {
|
|
||||||
defer wg.Done()
|
|
||||||
err := self.trigger(t)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errc <- err
|
errc <- err
|
||||||
}
|
}
|
||||||
}(trig)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// each expectation is spawned in separate go-routine
|
// each expectation is spawned in separate go-routine
|
||||||
|
|
@ -217,40 +207,16 @@ func (self *ExchangeTestSession) TestExchanges(exchanges ...Exchange) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
self.t.Fatalf("exchange failed with: %v", err)
|
self.t.Fatalf("exchange failed with: %v", err)
|
||||||
} else {
|
} else {
|
||||||
glog.V(6).Infof("exchange %v run successfully", i)
|
glog.V(6).Infof("exchange %v: '%v' run successfully", i, e.Label)
|
||||||
}
|
}
|
||||||
case <-alarm.C:
|
case <-alarm.C:
|
||||||
self.t.Fatalf("exchange timed out")
|
self.t.Fatalf("exchange %v: '%v' timed out", i, e.Label)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type flushMsg struct{}
|
func (self *ExchangeTestSession) TestConnected(peers ...*adapters.NodeId) {
|
||||||
|
|
||||||
func flushExchange(c int, ids ...*adapters.NodeId) Exchange {
|
|
||||||
var triggers []Trigger
|
|
||||||
for _, id := range ids {
|
|
||||||
triggers = append(triggers,
|
|
||||||
Trigger{
|
|
||||||
Code: uint64(c),
|
|
||||||
Msg: &flushMsg{},
|
|
||||||
Peer: id,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return Exchange{
|
|
||||||
Triggers: triggers,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var FlushMsg = &flushMsg{}
|
|
||||||
|
|
||||||
func (self *ExchangeTestSession) TestConnected(flush bool, peers ...*adapters.NodeId) {
|
|
||||||
timeout := time.NewTimer(1000 * time.Millisecond)
|
timeout := time.NewTimer(1000 * time.Millisecond)
|
||||||
var flushc chan bool
|
|
||||||
if !flush {
|
|
||||||
flushc = make(chan bool)
|
|
||||||
close(flushc)
|
|
||||||
}
|
|
||||||
wg := &sync.WaitGroup{}
|
wg := &sync.WaitGroup{}
|
||||||
wg.Add(len(peers))
|
wg.Add(len(peers))
|
||||||
for _, id := range peers {
|
for _, id := range peers {
|
||||||
|
|
@ -260,15 +226,12 @@ func (self *ExchangeTestSession) TestConnected(flush bool, peers ...*adapters.No
|
||||||
for {
|
for {
|
||||||
peer := self.GetPeer(p)
|
peer := self.GetPeer(p)
|
||||||
if peer != nil {
|
if peer != nil {
|
||||||
if flush {
|
|
||||||
flushc = peer.Flushc
|
|
||||||
}
|
|
||||||
select {
|
select {
|
||||||
case <-timeout.C:
|
case <-timeout.C:
|
||||||
self.t.Fatalf("exchange timed out waiting for peer %v to flush", p)
|
self.t.Fatalf("exchange timed out waiting for peer %v to flush", p)
|
||||||
case err := <-peer.Errc:
|
case err := <-peer.Errc:
|
||||||
self.t.Fatalf("peer %v disconnected with error %v", p, err)
|
self.t.Fatalf("peer %v disconnected with error %v", p, err)
|
||||||
case <-flushc:
|
case <-peer.Flushc:
|
||||||
glog.V(6).Infof("peer %v is connected", p)
|
glog.V(6).Infof("peer %v is connected", p)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,48 +0,0 @@
|
||||||
package testing
|
|
||||||
|
|
||||||
import (
|
|
||||||
"sync"
|
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/p2p/adapters"
|
|
||||||
"github.com/ethereum/go-ethereum/p2p/discover"
|
|
||||||
)
|
|
||||||
|
|
||||||
type TestPeer interface {
|
|
||||||
ID() discover.NodeID
|
|
||||||
Drop()
|
|
||||||
}
|
|
||||||
|
|
||||||
// TestPeerPool is an example peerPool to demonstrate registration of peer connections
|
|
||||||
type TestPeerPool struct {
|
|
||||||
lock sync.Mutex
|
|
||||||
peers map[discover.NodeID]TestPeer
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewTestPeerPool() *TestPeerPool {
|
|
||||||
return &TestPeerPool{peers: make(map[discover.NodeID]TestPeer)}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *TestPeerPool) Add(p TestPeer) {
|
|
||||||
self.lock.Lock()
|
|
||||||
defer self.lock.Unlock()
|
|
||||||
self.peers[p.ID()] = p
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *TestPeerPool) Remove(p TestPeer) {
|
|
||||||
self.lock.Lock()
|
|
||||||
defer self.lock.Unlock()
|
|
||||||
delete(self.peers, p.ID())
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *TestPeerPool) Has(n *adapters.NodeId) bool {
|
|
||||||
self.lock.Lock()
|
|
||||||
defer self.lock.Unlock()
|
|
||||||
_, ok := self.peers[n.NodeID]
|
|
||||||
return ok
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *TestPeerPool) Get(n *adapters.NodeId) TestPeer {
|
|
||||||
self.lock.Lock()
|
|
||||||
defer self.lock.Unlock()
|
|
||||||
return self.peers[n.NodeID]
|
|
||||||
}
|
|
||||||
|
|
@ -62,13 +62,7 @@ func NewProtocolTester(t *testing.T, id *adapters.NodeId, n int, run func(id ada
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *ExchangeTestSession) Flush(code int, ids ...*adapters.NodeId) {
|
//
|
||||||
self.TestConnected(false, ids...)
|
|
||||||
glog.V(6).Infof("flushing peers %v (code %v)", ids, code)
|
|
||||||
self.TestExchanges(flushExchange(code, ids...))
|
|
||||||
self.TestConnected(true, ids...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *ExchangeSession) Start(id *adapters.NodeId) error {
|
func (self *ExchangeSession) Start(id *adapters.NodeId) error {
|
||||||
err := self.network.NewNode(&simulations.NodeConfig{Id: id})
|
err := self.network.NewNode(&simulations.NodeConfig{Id: id})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -103,6 +97,10 @@ func (self *ExchangeSession) Connect(ids ...*adapters.NodeId) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// func (self *ExchangeSession) Id(i int) *adapters.NodeId {
|
||||||
|
// return self.network.Nodes[i].Id
|
||||||
|
// }
|
||||||
|
|
||||||
func RandomNodeId() *adapters.NodeId {
|
func RandomNodeId() *adapters.NodeId {
|
||||||
key, err := crypto.GenerateKey()
|
key, err := crypto.GenerateKey()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -1,56 +1,57 @@
|
||||||
package network
|
package network
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/logger"
|
||||||
|
"github.com/ethereum/go-ethereum/logger/glog"
|
||||||
|
"github.com/ethereum/go-ethereum/p2p/discover"
|
||||||
)
|
)
|
||||||
|
|
||||||
// discovery bzz hive extension for efficient peer relaying
|
// discovery bzz hive extension doing peer relaying
|
||||||
// this will be triggered by p2p/protocol already
|
// can be switched off
|
||||||
|
|
||||||
type discPeer struct {
|
type discPeer struct {
|
||||||
Peer
|
Peer
|
||||||
hive Hive
|
hive *Hive
|
||||||
sub overlaySubscription
|
proxLimit uint8
|
||||||
peers map[discover.NodeID]bool
|
peers map[discover.NodeID]bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type overlaySubscription interface {
|
// NotifyPeer notifies the receiver remote end of a peer p or PO po.
|
||||||
Subscribe(proxLimit uint) chan interface{}
|
// callback for overlay driver
|
||||||
SubscribeProxChange(proxLimit uint) chan interface{}
|
func (self *discPeer) NotifyPeer(p Peer, po uint8) error {
|
||||||
|
if po < self.proxLimit || self.peers[p.ID()] {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
resp := &peersMsg{
|
||||||
|
Peers: []*peerAddr{p.(*bzzPeer).peerAddr},
|
||||||
|
}
|
||||||
|
return p.Send(resp)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NotifyProx sends a subPeers Msg to the receiver notifying them about
|
||||||
|
// a change in the prox limit (radius of the set including the nearest X peers
|
||||||
|
// or first empty row)
|
||||||
|
// callback for overlay driver
|
||||||
|
func (self *discPeer) NotifyProx(po uint8) error {
|
||||||
|
return self.Send(&SubPeersMsg{ProxLimit: po, MinProxBinSize: 8})
|
||||||
}
|
}
|
||||||
|
|
||||||
// new discovery contructor
|
// new discovery contructor
|
||||||
func NewDiscovery(p Peer, h Hive) error {
|
func NewDiscovery(p Peer, h *Hive) *discPeer {
|
||||||
overlay, ok := h.Overlay.(overlaySubscription)
|
|
||||||
if !ok {
|
|
||||||
return fmt.Errorf("overlay does not support subscription")
|
|
||||||
}
|
|
||||||
self := &discPeer{
|
self := &discPeer{
|
||||||
sub: overlay,
|
|
||||||
hive: h,
|
hive: h,
|
||||||
Peer: p,
|
Peer: p,
|
||||||
peers: make(map[discover.NodeID]Peer),
|
peers: make(map[discover.NodeID]bool),
|
||||||
}
|
}
|
||||||
|
|
||||||
c := sub.SubscribeProxChange()
|
|
||||||
go func() {
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case <-h.quit:
|
|
||||||
return
|
|
||||||
case p := <-c:
|
|
||||||
resp := &peersMsg{
|
|
||||||
Peers: []*peerAddr{p.PeerAddr.(*peerAddr)},
|
|
||||||
}
|
|
||||||
p.Send(resp)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
p.Register(&subPeersMsg{}, self.handleSubPeersMsg)
|
|
||||||
p.Register(&peersMsg{}, self.handlePeersMsg)
|
p.Register(&peersMsg{}, self.handlePeersMsg)
|
||||||
p.Register(&getPeersMsg{}, self.handleGetPeersMsg)
|
p.Register(&getPeersMsg{}, self.handleGetPeersMsg)
|
||||||
|
p.Register(&SubPeersMsg{}, self.handleSubPeersMsg)
|
||||||
|
|
||||||
return nil
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -61,6 +62,7 @@ The encoding of a peer is identical to that in the devp2p base protocol peers
|
||||||
messages: [IP, Port, NodeID]
|
messages: [IP, Port, NodeID]
|
||||||
note that a node's DPA address is not the NodeID but the hash of the NodeID.
|
note that a node's DPA address is not the NodeID but the hash of the NodeID.
|
||||||
|
|
||||||
|
TODO:
|
||||||
To mitigate against spurious peers messages, requests should be remembered
|
To mitigate against spurious peers messages, requests should be remembered
|
||||||
and correctness of responses should be checked
|
and correctness of responses should be checked
|
||||||
|
|
||||||
|
|
@ -70,7 +72,7 @@ disconnected
|
||||||
|
|
||||||
// peersMsg encapsulates an array of peer addresses
|
// peersMsg encapsulates an array of peer addresses
|
||||||
// used for communicating about known peers
|
// used for communicating about known peers
|
||||||
// relevvant for bootstrapping connectivity and updating peersets
|
// relevant for bootstrapping connectivity and updating peersets
|
||||||
type peersMsg struct {
|
type peersMsg struct {
|
||||||
Peers []*peerAddr
|
Peers []*peerAddr
|
||||||
}
|
}
|
||||||
|
|
@ -81,8 +83,8 @@ func (self peersMsg) String() string {
|
||||||
|
|
||||||
// getPeersMsg is sent to (random) peers to request (Max) peers of a specific order
|
// getPeersMsg is sent to (random) peers to request (Max) peers of a specific order
|
||||||
type getPeersMsg struct {
|
type getPeersMsg struct {
|
||||||
Order uint
|
Order uint8
|
||||||
Max uint
|
Max uint8
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self getPeersMsg) String() string {
|
func (self getPeersMsg) String() string {
|
||||||
|
|
@ -90,20 +92,19 @@ func (self getPeersMsg) String() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// subPeers msg is communicating the depth/sharpness/focus of the overlay table of a peer
|
// subPeers msg is communicating the depth/sharpness/focus of the overlay table of a peer
|
||||||
type subPeersMsg struct {
|
type SubPeersMsg struct {
|
||||||
MinProxBinSize uint
|
MinProxBinSize uint8
|
||||||
ProxLimit uint
|
ProxLimit uint8
|
||||||
// Offset uint
|
|
||||||
// Batch uint
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self subPeersMsg) String() string {
|
func (self SubPeersMsg) String() string {
|
||||||
return fmt.Sprintf("request peers > PO%02d. ProxLimit: %02d", self.Request, self.ProxLimit)
|
return fmt.Sprintf("%T: request peers > PO%02d. ", self, self.ProxLimit)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *discPeer) handleSubPeersMsg(msg interface{}) error {
|
func (self *discPeer) handleSubPeersMsg(msg interface{}) error {
|
||||||
spm := msg.(*subPeersMsg)
|
spm := msg.(*SubPeersMsg)
|
||||||
self.sub.Subscribe(spm.ProxLimit)
|
self.proxLimit = spm.ProxLimit
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// handlePeersMsg called by the protocol when receiving peerset (for target address)
|
// handlePeersMsg called by the protocol when receiving peerset (for target address)
|
||||||
|
|
@ -115,7 +116,7 @@ func (p *discPeer) handlePeersMsg(msg interface{}) error {
|
||||||
for _, na := range msg.(*peersMsg).Peers {
|
for _, na := range msg.(*peersMsg).Peers {
|
||||||
addr := PeerAddr(na)
|
addr := PeerAddr(na)
|
||||||
nas = append(nas, addr)
|
nas = append(nas, addr)
|
||||||
p.peers[NodeId(addr)] = true
|
p.peers[NodeId(addr).NodeID] = true
|
||||||
}
|
}
|
||||||
return p.hive.Register(nas...)
|
return p.hive.Register(nas...)
|
||||||
}
|
}
|
||||||
|
|
@ -130,7 +131,7 @@ func (p *discPeer) handleGetPeersMsg(msg interface{}) error {
|
||||||
var peers []*peerAddr
|
var peers []*peerAddr
|
||||||
alreadySent := p.peers
|
alreadySent := p.peers
|
||||||
i := 0
|
i := 0
|
||||||
p.Overlay.EachLivePeer(p.OverlayAddr(), int(req.Order), func(n Peer, po int) bool {
|
p.hive.EachLivePeer(p.OverlayAddr(), int(req.Order), func(n Peer, po int) bool {
|
||||||
i++
|
i++
|
||||||
if bytes.Compare(n.OverlayAddr(), p.OverlayAddr()) != 0 &&
|
if bytes.Compare(n.OverlayAddr(), p.OverlayAddr()) != 0 &&
|
||||||
// only send peers we have not sent before in this session
|
// only send peers we have not sent before in this session
|
||||||
|
|
@ -149,9 +150,5 @@ func (p *discPeer) handleGetPeersMsg(msg interface{}) error {
|
||||||
resp := &peersMsg{
|
resp := &peersMsg{
|
||||||
Peers: peers,
|
Peers: peers,
|
||||||
}
|
}
|
||||||
err := p.Send(resp)
|
return p.Send(resp)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,30 +1,25 @@
|
||||||
package network
|
package network
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"sync"
|
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/p2p/adapters"
|
|
||||||
// "github.com/ethereum/go-ethereum/p2p/discover"
|
|
||||||
"github.com/ethereum/go-ethereum/logger"
|
|
||||||
"github.com/ethereum/go-ethereum/logger/glog"
|
|
||||||
"github.com/ethereum/go-ethereum/p2p/protocols"
|
|
||||||
p2ptest "github.com/ethereum/go-ethereum/p2p/testing"
|
p2ptest "github.com/ethereum/go-ethereum/p2p/testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestDiscovery(t *testing.T) {
|
func TestDiscovery(t *testing.T) {
|
||||||
addr := RandomAddr()
|
addr := RandomAddr()
|
||||||
to := NewTestOverlay(addr.OverlayAddr())
|
to := NewKademlia(addr.OAddr, NewKadParams())
|
||||||
pp := NewHive(NewHiveParams(), to)
|
pp := NewHive(NewHiveParams(), to)
|
||||||
ct := BzzCodeMap(HiveMsgs...)
|
ct := BzzCodeMap(HiveMsgs...)
|
||||||
s := newDiscoveryTester(t, 0, addr, pp, ct, nil)
|
s := newBzzTester(t, 1, addr, pp, ct, nil)
|
||||||
|
|
||||||
|
s.runHandshakes()
|
||||||
s.TestExchanges(p2ptest.Exchange{
|
s.TestExchanges(p2ptest.Exchange{
|
||||||
Expects: []p2ptest.Expect{
|
Expects: []p2ptest.Expect{
|
||||||
p2ptest.Expect{
|
p2ptest.Expect{
|
||||||
Code: 1,
|
Code: 3,
|
||||||
Msg: &subPeersMsg{uint(o)},
|
Msg: &SubPeersMsg{ProxLimit: 0, MinProxBinSize: 8},
|
||||||
Peer: id,
|
Peer: s.ExchangeSession.Id(1),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -17,13 +17,12 @@
|
||||||
package network
|
package network
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/logger"
|
"github.com/ethereum/go-ethereum/logger"
|
||||||
"github.com/ethereum/go-ethereum/logger/glog"
|
"github.com/ethereum/go-ethereum/logger/glog"
|
||||||
|
"github.com/ethereum/go-ethereum/p2p/adapters"
|
||||||
"github.com/ethereum/go-ethereum/p2p/discover"
|
"github.com/ethereum/go-ethereum/p2p/discover"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -57,7 +56,7 @@ type Overlay interface {
|
||||||
type Hive struct {
|
type Hive struct {
|
||||||
*HiveParams // settings
|
*HiveParams // settings
|
||||||
Overlay // the overlay topology driver
|
Overlay // the overlay topology driver
|
||||||
disc Discovery
|
// disc Discovery
|
||||||
|
|
||||||
lock sync.Mutex
|
lock sync.Mutex
|
||||||
quit chan bool
|
quit chan bool
|
||||||
|
|
@ -72,8 +71,8 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
type HiveParams struct {
|
type HiveParams struct {
|
||||||
PeersBroadcastSetSize uint
|
PeersBroadcastSetSize uint8
|
||||||
MaxPeersPerRequest uint
|
MaxPeersPerRequest uint8
|
||||||
CallInterval uint
|
CallInterval uint
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -95,18 +94,17 @@ func NewHive(params *HiveParams, overlay Overlay) *Hive {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// messages that hive regusters handles for
|
// messages that hive handles
|
||||||
var HiveMsgs = []interface{}{
|
var HiveMsgs = []interface{}{
|
||||||
&getPeersMsg{},
|
&getPeersMsg{},
|
||||||
&peersMsg{},
|
&peersMsg{},
|
||||||
&subPeersMsg{},
|
&SubPeersMsg{},
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start receives network info only at startup
|
// Start receives network info only at startup
|
||||||
// listedAddr is a function to retrieve listening address to advertise to peers
|
|
||||||
// connectPeer is a function to connect to a peer based on its NodeID or enode URL
|
// connectPeer is a function to connect to a peer based on its NodeID or enode URL
|
||||||
|
// these are called on the p2p.Server which runs on the node
|
||||||
// af() returns an arbitrary ticker channel
|
// af() returns an arbitrary ticker channel
|
||||||
// there are called on the p2p.Server which runs on the node
|
|
||||||
func (self *Hive) Start(connectPeer func(string) error, af func() <-chan time.Time) error {
|
func (self *Hive) Start(connectPeer func(string) error, af func() <-chan time.Time) error {
|
||||||
|
|
||||||
self.toggle = make(chan bool)
|
self.toggle = make(chan bool)
|
||||||
|
|
@ -137,10 +135,10 @@ func (self *Hive) Start(connectPeer func(string) error, af func() <-chan time.Ti
|
||||||
}
|
}
|
||||||
if want {
|
if want {
|
||||||
req := &getPeersMsg{
|
req := &getPeersMsg{
|
||||||
Order: uint(order),
|
Order: uint8(order),
|
||||||
Max: self.MaxPeersPerRequest,
|
Max: self.MaxPeersPerRequest,
|
||||||
}
|
}
|
||||||
var i uint
|
var i uint8
|
||||||
var err error
|
var err error
|
||||||
self.EachLivePeer(nil, order, func(n Peer, po int) bool {
|
self.EachLivePeer(nil, order, func(n Peer, po int) bool {
|
||||||
glog.V(logger.Detail).Infof("%T sent to %v", req, n.ID())
|
glog.V(logger.Detail).Infof("%T sent to %v", req, n.ID())
|
||||||
|
|
@ -218,15 +216,12 @@ func (self *Hive) wake() {
|
||||||
// to register a connected (live) peer
|
// to register a connected (live) peer
|
||||||
func (self *Hive) Add(p Peer) error {
|
func (self *Hive) Add(p Peer) error {
|
||||||
defer self.wake()
|
defer self.wake()
|
||||||
|
dp := NewDiscovery(p, self)
|
||||||
glog.V(logger.Debug).Infof("to add new bee %v", p)
|
glog.V(logger.Debug).Infof("to add new bee %v", p)
|
||||||
self.On(p)
|
self.On(dp)
|
||||||
glog.V(logger.Warn).Infof("%v", self)
|
glog.V(logger.Warn).Infof("%v", self)
|
||||||
|
dp.NotifyProx(0)
|
||||||
// self.lock.Lock()
|
return nil
|
||||||
// self.peers[p.ID()] = p
|
|
||||||
// self.lock.Unlock()
|
|
||||||
|
|
||||||
return NewDiscovery(p, self)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove called after peer is disconnected
|
// Remove called after peer is disconnected
|
||||||
|
|
@ -234,9 +229,6 @@ func (self *Hive) Remove(p Peer) {
|
||||||
defer self.wake()
|
defer self.wake()
|
||||||
glog.V(logger.Debug).Infof("remove bee %v", p)
|
glog.V(logger.Debug).Infof("remove bee %v", p)
|
||||||
self.Off(p)
|
self.Off(p)
|
||||||
self.lock.Lock()
|
|
||||||
delete(self.peers, p.ID())
|
|
||||||
self.lock.Unlock()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Hive) NodeInfo() interface{} {
|
func (self *Hive) NodeInfo() interface{} {
|
||||||
|
|
@ -246,11 +238,8 @@ func (self *Hive) NodeInfo() interface{} {
|
||||||
func (self *Hive) PeerInfo(id discover.NodeID) interface{} {
|
func (self *Hive) PeerInfo(id discover.NodeID) interface{} {
|
||||||
self.lock.Lock()
|
self.lock.Lock()
|
||||||
defer self.lock.Unlock()
|
defer self.lock.Unlock()
|
||||||
p, ok := self.peers[id]
|
addr := NewPeerAddrFromNodeId(adapters.NewNodeId(id[:]))
|
||||||
if !ok {
|
return interface{}(addr)
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return interface{}(&peerAddr{p.OverlayAddr(), p.UnderlayAddr()})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func HexToBytes(s string) []byte {
|
func HexToBytes(s string) []byte {
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ import (
|
||||||
// "github.com/ethereum/go-ethereum/p2p/discover"
|
// "github.com/ethereum/go-ethereum/p2p/discover"
|
||||||
"github.com/ethereum/go-ethereum/logger"
|
"github.com/ethereum/go-ethereum/logger"
|
||||||
"github.com/ethereum/go-ethereum/logger/glog"
|
"github.com/ethereum/go-ethereum/logger/glog"
|
||||||
"github.com/ethereum/go-ethereum/p2p/protocols"
|
// "github.com/ethereum/go-ethereum/p2p/protocols"
|
||||||
p2ptest "github.com/ethereum/go-ethereum/p2p/testing"
|
p2ptest "github.com/ethereum/go-ethereum/p2p/testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -37,22 +37,14 @@ func (self *testConnect) connect(na string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func newBzzHiveTester(t *testing.T, n int, addr *peerAddr, pp PeerPool, ct *protocols.CodeMap, services func(Peer) error) *bzzTester {
|
|
||||||
s := p2ptest.NewProtocolTester(t, NodeId(addr), n, newTestBzzProtocol(addr, pp, ct, services))
|
|
||||||
return &bzzTester{
|
|
||||||
addr: addr,
|
|
||||||
flushCode: 3,
|
|
||||||
ExchangeSession: s,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestOverlayRegistration(t *testing.T) {
|
func TestOverlayRegistration(t *testing.T) {
|
||||||
// setup
|
// setup
|
||||||
addr := RandomAddr() // tested peers peer address
|
addr := RandomAddr() // tested peers peer address
|
||||||
to := NewTestOverlay(addr.OverlayAddr()) // overlay topology driver
|
to := NewTestOverlay(addr.OverlayAddr()) // overlay topology driver
|
||||||
pp := NewHive(NewHiveParams(), to) // hive
|
pp := NewHive(NewHiveParams(), to) // hive
|
||||||
ct := BzzCodeMap(HiveMsgs...) // bzz protocol code map
|
ct := BzzCodeMap(HiveMsgs...) // bzz protocol code map
|
||||||
s := newBzzHiveTester(t, 1, addr, pp, ct, nil)
|
|
||||||
|
s := newBzzTester(t, 1, addr, ct, nil)
|
||||||
|
|
||||||
// connect to the other peer
|
// connect to the other peer
|
||||||
id := s.Ids[0]
|
id := s.Ids[0]
|
||||||
|
|
@ -70,14 +62,18 @@ func TestRegisterAndConnect(t *testing.T) {
|
||||||
to := NewTestOverlay(addr.OverlayAddr())
|
to := NewTestOverlay(addr.OverlayAddr())
|
||||||
pp := NewHive(NewHiveParams(), to)
|
pp := NewHive(NewHiveParams(), to)
|
||||||
ct := BzzCodeMap(HiveMsgs...)
|
ct := BzzCodeMap(HiveMsgs...)
|
||||||
s := newBzzHiveTester(t, 0, addr, pp, ct, nil)
|
s := newBzzTester(t, 0, addr, pp, ct, nil)
|
||||||
|
|
||||||
// register the node with the peerPool
|
// register the node with the peerPool
|
||||||
id := p2ptest.RandomNodeId()
|
id := p2ptest.RandomNodeId()
|
||||||
|
// pretend to start the node
|
||||||
s.Start(id)
|
s.Start(id)
|
||||||
|
|
||||||
|
// register another address
|
||||||
raddr := NewPeerAddrFromNodeId(id)
|
raddr := NewPeerAddrFromNodeId(id)
|
||||||
pp.Register(raddr)
|
pp.Register(raddr)
|
||||||
glog.V(5).Infof("%v", pp)
|
glog.V(5).Infof("%v", pp)
|
||||||
|
|
||||||
// start the hive and wait for the connection
|
// start the hive and wait for the connection
|
||||||
tc := &testConnect{
|
tc := &testConnect{
|
||||||
connectf: func(c string) error {
|
connectf: func(c string) error {
|
||||||
|
|
@ -88,42 +84,36 @@ func TestRegisterAndConnect(t *testing.T) {
|
||||||
}
|
}
|
||||||
pp.Start(tc.connect, tc.ping)
|
pp.Start(tc.connect, tc.ping)
|
||||||
tc.ticker <- time.Now()
|
tc.ticker <- time.Now()
|
||||||
|
|
||||||
|
// run bzz handshake
|
||||||
s.runHandshakes()
|
s.runHandshakes()
|
||||||
if to.posMap[string(raddr.OverlayAddr())] == nil {
|
if to.posMap[string(raddr.OverlayAddr())] == nil {
|
||||||
t.Fatalf("Overlay#On not called on new peer")
|
t.Fatalf("Overlay#On not called on new peer")
|
||||||
}
|
}
|
||||||
glog.V(6).Infof("check peer requests for %v", id)
|
|
||||||
// tc.ticker <- time.Now()
|
|
||||||
|
|
||||||
// shakeHands(s, addr, id)
|
// retrieve and broadcast
|
||||||
// s.Flush(int(ct.Length())-1, 0)
|
glog.V(6).Infof("check peer requests for %v", id)
|
||||||
// time.Sleep(3)
|
|
||||||
ord := order(raddr.OverlayAddr())
|
ord := order(raddr.OverlayAddr())
|
||||||
o := 0
|
o := 0
|
||||||
if ord == 0 {
|
if ord == 0 {
|
||||||
o = 1
|
o = 1
|
||||||
}
|
}
|
||||||
|
s.TestExchanges(p2ptest.Exchange{
|
||||||
|
Expects: []p2ptest.Expect{
|
||||||
|
p2ptest.Expect{
|
||||||
|
Code: 3,
|
||||||
|
Msg: &SubPeersMsg{ProxLimit: 0, MinProxBinSize: 8},
|
||||||
|
Peer: s.ExchangeSession.Id(1),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
s.TestExchanges(p2ptest.Exchange{
|
s.TestExchanges(p2ptest.Exchange{
|
||||||
Expects: []p2ptest.Expect{
|
Expects: []p2ptest.Expect{
|
||||||
p2ptest.Expect{
|
p2ptest.Expect{
|
||||||
Code: 1,
|
Code: 1,
|
||||||
Msg: &getPeersMsg{uint(o), 5},
|
Msg: &getPeersMsg{uint8(o), 5},
|
||||||
Peer: id,
|
Peer: id,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// Triggers: []p2ptest.Trigger{
|
|
||||||
// p2ptest.Trigger{
|
|
||||||
// Code: 1,
|
|
||||||
// Msg: &getPeersMsg{0, 1},
|
|
||||||
// Peer: 0,
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// Expects: []p2ptest.Expect{
|
|
||||||
// p2ptest.Expect{
|
|
||||||
// Code: 1,
|
|
||||||
// Msg: &peersMsg{[]*peerAddr{RandomAddr()}},
|
|
||||||
// Peer: 0,
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,10 @@ adjust Prox (proxLimit and proxSize after an insertion/removal of nodes)
|
||||||
caller holds the lock
|
caller holds the lock
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
type KadDiscovery interface {
|
||||||
|
NotifyPeer(Peer, uint8) error
|
||||||
|
NotifyProx(uint8) error
|
||||||
|
}
|
||||||
|
|
||||||
type KadParams struct {
|
type KadParams struct {
|
||||||
// adjustable parameters
|
// adjustable parameters
|
||||||
|
|
@ -199,12 +203,21 @@ func (self *Kademlia) On(p Peer) {
|
||||||
})
|
})
|
||||||
kp.seenAt = time.Now()
|
kp.seenAt = time.Now()
|
||||||
kp.retries = 0
|
kp.retries = 0
|
||||||
f := func(val pot.PotVal, po int) {
|
prox := self.proxLimit()
|
||||||
vp := val.(*KadPeer).Peer
|
|
||||||
dp.NotifyPeer(kp.PeerAddr, po)
|
|
||||||
}
|
|
||||||
|
|
||||||
self.conns.EachNeighbourAsync(pp, 256, 256, f, nil)
|
vp, ok := kp.Peer.(KadDiscovery)
|
||||||
|
if !ok {
|
||||||
|
glog.V(logger.Detail).Infof("not discovery peer")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// vp.NotifyProx(uint8(prox))
|
||||||
|
f := func(val pot.PotVal, po int) {
|
||||||
|
glog.V(logger.Detail).Infof("peer %v nofified", vp)
|
||||||
|
dp := val.(KadDiscovery)
|
||||||
|
dp.NotifyPeer(kp.Peer, uint8(po))
|
||||||
|
dp.NotifyProx(uint8(prox))
|
||||||
|
}
|
||||||
|
self.conns.EachNeighbourAsync(pp, 255, 255, f, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Off removes a peer from among live peers
|
// Off removes a peer from among live peers
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,6 @@ const (
|
||||||
// bzz is the bzz protocol view of a protocols.Peer (itself an extension of p2p.Peer)
|
// bzz is the bzz protocol view of a protocols.Peer (itself an extension of p2p.Peer)
|
||||||
type bzzPeer struct {
|
type bzzPeer struct {
|
||||||
*protocols.Peer
|
*protocols.Peer
|
||||||
hive PeerPool
|
|
||||||
network adapters.NodeAdapter
|
network adapters.NodeAdapter
|
||||||
localAddr *peerAddr
|
localAddr *peerAddr
|
||||||
*peerAddr // remote address
|
*peerAddr // remote address
|
||||||
|
|
@ -68,22 +67,10 @@ type Peer interface {
|
||||||
ID() discover.NodeID // the key that uniquely identifies the Node for the peerPool
|
ID() discover.NodeID // the key that uniquely identifies the Node for the peerPool
|
||||||
Peers() map[discover.NodeID]bool
|
Peers() map[discover.NodeID]bool
|
||||||
Send(interface{}) error // can send messages
|
Send(interface{}) error // can send messages
|
||||||
Drop() // disconnect this peer
|
Drop(error) // disconnect this peer
|
||||||
Register(interface{}, func(interface{}) error) uint64 // register message-handler callbacks
|
Register(interface{}, func(interface{}) error) uint64 // register message-handler callbacks
|
||||||
}
|
}
|
||||||
|
|
||||||
// PeerPool is the interface for the connectivity manager
|
|
||||||
// directly interacts with the p2p server to suggest connections
|
|
||||||
type PeerPool interface {
|
|
||||||
Add(Peer) error
|
|
||||||
Remove(Peer)
|
|
||||||
}
|
|
||||||
|
|
||||||
type PeerInfo interface {
|
|
||||||
NodeInfo() interface{}
|
|
||||||
PeerInfo(discover.NodeID) interface{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BzzCodeMap(msgs ...interface{}) *protocols.CodeMap {
|
func BzzCodeMap(msgs ...interface{}) *protocols.CodeMap {
|
||||||
ct := protocols.NewCodeMap(ProtocolName, Version, ProtocolMaxMsgSize)
|
ct := protocols.NewCodeMap(ProtocolName, Version, ProtocolMaxMsgSize)
|
||||||
ct.Register(&bzzHandshake{})
|
ct.Register(&bzzHandshake{})
|
||||||
|
|
@ -93,13 +80,12 @@ func BzzCodeMap(msgs ...interface{}) *protocols.CodeMap {
|
||||||
|
|
||||||
// Bzz is the protocol constructor
|
// Bzz is the protocol constructor
|
||||||
// returns p2p.Protocol that is to be offered by the node.Service
|
// returns p2p.Protocol that is to be offered by the node.Service
|
||||||
func Bzz(localAddr []byte, hive PeerPool, na adapters.NodeAdapter, ct *protocols.CodeMap, services func(Peer) error) *p2p.Protocol {
|
func Bzz(localAddr []byte, na adapters.NodeAdapter, ct *protocols.CodeMap, services func(Peer) error) *p2p.Protocol {
|
||||||
run := func(p *protocols.Peer) error {
|
run := func(p *protocols.Peer) error {
|
||||||
addr := &peerAddr{localAddr, na.LocalAddr()}
|
addr := &peerAddr{localAddr, na.LocalAddr()}
|
||||||
|
|
||||||
bee := &bzzPeer{
|
bee := &bzzPeer{
|
||||||
Peer: p,
|
Peer: p,
|
||||||
hive: hive,
|
|
||||||
network: na,
|
network: na,
|
||||||
localAddr: addr,
|
localAddr: addr,
|
||||||
peers: make(map[discover.NodeID]bool),
|
peers: make(map[discover.NodeID]bool),
|
||||||
|
|
@ -121,24 +107,10 @@ func Bzz(localAddr []byte, hive PeerPool, na adapters.NodeAdapter, ct *protocols
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = hive.Add(bee)
|
|
||||||
if err != nil {
|
|
||||||
glog.V(6).Infof("failed to add peer '%v' to hive: %v", bee.ID(), err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
defer hive.Remove(bee)
|
|
||||||
return bee.Run()
|
return bee.Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
proto := protocols.NewProtocol(ProtocolName, Version, run, na, ct)
|
return protocols.NewProtocol(ProtocolName, Version, run, na, ct, peerInfo, nodeInfo)
|
||||||
|
|
||||||
if o, ok := hive.(PeerInfo); ok {
|
|
||||||
proto.NodeInfo = o.NodeInfo
|
|
||||||
proto.PeerInfo = o.PeerInfo
|
|
||||||
}
|
|
||||||
|
|
||||||
return proto
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"sync"
|
"sync"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/logger/glog"
|
"github.com/ethereum/go-ethereum/logger/glog"
|
||||||
"github.com/ethereum/go-ethereum/p2p/adapters"
|
"github.com/ethereum/go-ethereum/p2p/adapters"
|
||||||
|
|
@ -37,11 +36,11 @@ func bzzHandshakeExchange(lhs, rhs *bzzHandshake, id *adapters.NodeId) []p2ptest
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func newTestBzzProtocol(addr *peerAddr, pp PeerPool, ct *protocols.CodeMap, services func(Peer) error) func(adapters.NodeAdapter) adapters.ProtoCall {
|
func newTestBzzProtocol(addr *peerAddr, ct *protocols.CodeMap, services func(Peer) error) func(adapters.NodeAdapter) adapters.ProtoCall {
|
||||||
if ct == nil {
|
if ct == nil {
|
||||||
ct = BzzCodeMap()
|
ct = BzzCodeMap()
|
||||||
}
|
}
|
||||||
ct.Register(p2ptest.FlushMsg)
|
// ct.Register(p2ptest.FlushMsg)
|
||||||
return func(na adapters.NodeAdapter) adapters.ProtoCall {
|
return func(na adapters.NodeAdapter) adapters.ProtoCall {
|
||||||
srv := func(p Peer) error {
|
srv := func(p Peer) error {
|
||||||
if services != nil {
|
if services != nil {
|
||||||
|
|
@ -50,12 +49,12 @@ func newTestBzzProtocol(addr *peerAddr, pp PeerPool, ct *protocols.CodeMap, serv
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
id := p.ID()
|
// id := p.ID()
|
||||||
p.Register(p2ptest.FlushMsg, func(interface{}) error {
|
// p.Register(p2ptest.FlushMsg, func(interface{}) error {
|
||||||
flushc := na.(p2ptest.TestNetAdapter).GetPeer(&adapters.NodeId{id}).Flushc
|
// flushc := na.(p2ptest.TestNetAdapter).GetPeer(&adapters.NodeId{id}).Flushc
|
||||||
flushc <- true
|
// flushc <- true
|
||||||
return nil
|
// return nil
|
||||||
})
|
// })
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -66,7 +65,7 @@ func newTestBzzProtocol(addr *peerAddr, pp PeerPool, ct *protocols.CodeMap, serv
|
||||||
|
|
||||||
type bzzTester struct {
|
type bzzTester struct {
|
||||||
*p2ptest.ExchangeSession
|
*p2ptest.ExchangeSession
|
||||||
flushCode int
|
// flushCode int
|
||||||
addr *peerAddr
|
addr *peerAddr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -81,27 +80,23 @@ func (s *bzzTester) testHandshake(lhs, rhs *bzzHandshake, disconnects ...*p2ptes
|
||||||
} else {
|
} else {
|
||||||
peers = []*adapters.NodeId{id}
|
peers = []*adapters.NodeId{id}
|
||||||
}
|
}
|
||||||
s.TestConnected(false, peers...)
|
s.TestConnected(peers...)
|
||||||
s.TestExchanges(bzzHandshakeExchange(lhs, rhs, id)...)
|
s.TestExchanges(bzzHandshakeExchange(lhs, rhs, id)...)
|
||||||
s.TestDisconnected(disconnects...)
|
s.TestDisconnected(disconnects...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *bzzTester) flush(ids ...*adapters.NodeId) {
|
// func (s *bzzTester) flush(ids ...*adapters.NodeId) {
|
||||||
s.Flush(s.flushCode, ids...)
|
// s.Flush(s.flushCode, ids...)
|
||||||
}
|
// }
|
||||||
|
|
||||||
func (s *bzzTester) runHandshakes(ids ...*adapters.NodeId) {
|
func (s *bzzTester) runHandshakes(ids ...*adapters.NodeId) {
|
||||||
if len(ids) == 0 {
|
if len(ids) == 0 {
|
||||||
ids = s.Ids
|
ids = s.Ids
|
||||||
}
|
}
|
||||||
for _, id := range ids {
|
for _, id := range ids {
|
||||||
glog.V(6).Infof("\n\n\nrun handshake with %v", id)
|
|
||||||
time.Sleep(1)
|
|
||||||
s.testHandshake(correctBzzHandshake(s.addr), correctBzzHandshake(NewPeerAddrFromNodeId(id)))
|
s.testHandshake(correctBzzHandshake(s.addr), correctBzzHandshake(NewPeerAddrFromNodeId(id)))
|
||||||
time.Sleep(1)
|
|
||||||
}
|
}
|
||||||
glog.V(6).Infof("flush %v", ids)
|
|
||||||
s.flush(ids...)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func correctBzzHandshake(addr *peerAddr) *bzzHandshake {
|
func correctBzzHandshake(addr *peerAddr) *bzzHandshake {
|
||||||
|
|
@ -109,16 +104,22 @@ func correctBzzHandshake(addr *peerAddr) *bzzHandshake {
|
||||||
}
|
}
|
||||||
|
|
||||||
func newBzzTester(t *testing.T, addr *peerAddr, pp PeerPool, ct *protocols.CodeMap, services func(Peer) error) *bzzTester {
|
func newBzzTester(t *testing.T, addr *peerAddr, pp PeerPool, ct *protocols.CodeMap, services func(Peer) error) *bzzTester {
|
||||||
s := p2ptest.NewProtocolTester(t, NodeId(addr), 1, newTestBzzProtocol(addr, pp, ct, services))
|
|
||||||
|
extraservices := func(p Peer) error {
|
||||||
|
pp.Add(p)
|
||||||
|
p.Register(&protocols.Disconnect{}, func(e interface{}) error { pp.Remove(p) })
|
||||||
|
return services(p)
|
||||||
|
}
|
||||||
|
s := p2ptest.NewProtocolTester(t, NodeId(addr), 1, newTestBzzProtocol(addr, pp, ct, extarservices))
|
||||||
return &bzzTester{
|
return &bzzTester{
|
||||||
addr: addr,
|
addr: addr,
|
||||||
flushCode: 1,
|
// flushCode: 4,
|
||||||
ExchangeSession: s,
|
ExchangeSession: s,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBzzHandshakeNetworkIdMismatch(t *testing.T) {
|
func TestBzzHandshakeNetworkIdMismatch(t *testing.T) {
|
||||||
pp := NewTestPeerPool()
|
pp := p2ptest.NewTestPeerPool()
|
||||||
addr := RandomAddr()
|
addr := RandomAddr()
|
||||||
s := newBzzTester(t, addr, pp, nil, nil)
|
s := newBzzTester(t, addr, pp, nil, nil)
|
||||||
id := s.Ids[0]
|
id := s.Ids[0]
|
||||||
|
|
@ -130,7 +131,7 @@ func TestBzzHandshakeNetworkIdMismatch(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBzzHandshakeVersionMismatch(t *testing.T) {
|
func TestBzzHandshakeVersionMismatch(t *testing.T) {
|
||||||
pp := NewTestPeerPool()
|
pp := p2ptest.NewTestPeerPool()
|
||||||
addr := RandomAddr()
|
addr := RandomAddr()
|
||||||
s := newBzzTester(t, addr, pp, nil, nil)
|
s := newBzzTester(t, addr, pp, nil, nil)
|
||||||
id := s.Ids[0]
|
id := s.Ids[0]
|
||||||
|
|
@ -142,7 +143,7 @@ func TestBzzHandshakeVersionMismatch(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBzzHandshakeSuccess(t *testing.T) {
|
func TestBzzHandshakeSuccess(t *testing.T) {
|
||||||
pp := NewTestPeerPool()
|
pp := p2ptest.NewTestPeerPool()
|
||||||
addr := RandomAddr()
|
addr := RandomAddr()
|
||||||
s := newBzzTester(t, addr, pp, nil, nil)
|
s := newBzzTester(t, addr, pp, nil, nil)
|
||||||
id := s.Ids[0]
|
id := s.Ids[0]
|
||||||
|
|
@ -153,13 +154,14 @@ func TestBzzHandshakeSuccess(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBzzPeerPoolAdd(t *testing.T) {
|
func TestBzzPeerPoolAdd(t *testing.T) {
|
||||||
pp := NewTestPeerPool()
|
pp := p2ptest.NewTestPeerPool()
|
||||||
addr := RandomAddr()
|
addr := RandomAddr()
|
||||||
s := newBzzTester(t, addr, pp, nil, nil)
|
s := newBzzTester(t, addr, pp, nil, nil)
|
||||||
|
|
||||||
id := s.Ids[0]
|
id := s.Ids[0]
|
||||||
glog.V(6).Infof("handshake with %v", id)
|
glog.V(6).Infof("handshake with %v", id)
|
||||||
s.runHandshakes()
|
s.runHandshakes()
|
||||||
|
// s.TestConnected()
|
||||||
if !pp.Has(id) {
|
if !pp.Has(id) {
|
||||||
t.Fatalf("peer '%v' not added: %v", id, pp)
|
t.Fatalf("peer '%v' not added: %v", id, pp)
|
||||||
}
|
}
|
||||||
|
|
@ -167,7 +169,7 @@ func TestBzzPeerPoolAdd(t *testing.T) {
|
||||||
|
|
||||||
func TestBzzPeerPoolRemove(t *testing.T) {
|
func TestBzzPeerPoolRemove(t *testing.T) {
|
||||||
addr := RandomAddr()
|
addr := RandomAddr()
|
||||||
pp := NewTestPeerPool()
|
pp := p2ptest.NewTestPeerPool()
|
||||||
s := newBzzTester(t, addr, pp, nil, nil)
|
s := newBzzTester(t, addr, pp, nil, nil)
|
||||||
s.runHandshakes()
|
s.runHandshakes()
|
||||||
|
|
||||||
|
|
@ -181,7 +183,7 @@ func TestBzzPeerPoolRemove(t *testing.T) {
|
||||||
|
|
||||||
func TestBzzPeerPoolBothAddRemove(t *testing.T) {
|
func TestBzzPeerPoolBothAddRemove(t *testing.T) {
|
||||||
addr := RandomAddr()
|
addr := RandomAddr()
|
||||||
pp := NewTestPeerPool()
|
pp := p2ptest.NewTestPeerPool()
|
||||||
s := newBzzTester(t, addr, pp, nil, nil)
|
s := newBzzTester(t, addr, pp, nil, nil)
|
||||||
s.runHandshakes()
|
s.runHandshakes()
|
||||||
|
|
||||||
|
|
@ -199,7 +201,7 @@ func TestBzzPeerPoolBothAddRemove(t *testing.T) {
|
||||||
|
|
||||||
func TestBzzPeerPoolNotAdd(t *testing.T) {
|
func TestBzzPeerPoolNotAdd(t *testing.T) {
|
||||||
addr := RandomAddr()
|
addr := RandomAddr()
|
||||||
pp := NewTestPeerPool()
|
pp := p2ptest.NewTestPeerPool()
|
||||||
s := newBzzTester(t, addr, pp, nil, nil)
|
s := newBzzTester(t, addr, pp, nil, nil)
|
||||||
|
|
||||||
id := s.Ids[0]
|
id := s.Ids[0]
|
||||||
|
|
@ -208,40 +210,3 @@ func TestBzzPeerPoolNotAdd(t *testing.T) {
|
||||||
t.Fatalf("peer %v incorrectly added: %v", id, pp)
|
t.Fatalf("peer %v incorrectly added: %v", id, pp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestPeerPool is an example peerPool to demonstrate registration of peer connections
|
|
||||||
type TestPeerPool struct {
|
|
||||||
lock sync.Mutex
|
|
||||||
peers map[discover.NodeID]Peer
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewTestPeerPool() *TestPeerPool {
|
|
||||||
return &TestPeerPool{peers: make(map[discover.NodeID]Peer)}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *TestPeerPool) Add(p Peer) error {
|
|
||||||
self.lock.Lock()
|
|
||||||
defer self.lock.Unlock()
|
|
||||||
self.peers[p.ID()] = p
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *TestPeerPool) Remove(p Peer) {
|
|
||||||
self.lock.Lock()
|
|
||||||
defer self.lock.Unlock()
|
|
||||||
// glog.V(6).Infof("removing peer %v", p.ID())
|
|
||||||
delete(self.peers, p.ID())
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *TestPeerPool) Has(n *adapters.NodeId) bool {
|
|
||||||
self.lock.Lock()
|
|
||||||
defer self.lock.Unlock()
|
|
||||||
_, ok := self.peers[n.NodeID]
|
|
||||||
return ok
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *TestPeerPool) Get(n *adapters.NodeId) Peer {
|
|
||||||
self.lock.Lock()
|
|
||||||
defer self.lock.Unlock()
|
|
||||||
return self.peers[n.NodeID]
|
|
||||||
}
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue