swarm/network: address PR comments on TestInitialPeersMsg

* eliminate *testing.T argument from bzz/hive protocoltesters
 * add sorting (only runs in test code) on peersMsg payload
 * add random (0 to MaxPeersPerPO) peers for each po
 * add extra peers closer to pivot than control
This commit is contained in:
zelig 2019-04-01 07:46:09 +02:00
parent a89902e649
commit a47e1685c0
4 changed files with 63 additions and 23 deletions

View file

@ -26,6 +26,8 @@ import (
// discovery bzz extension for requesting and relaying node address records // discovery bzz extension for requesting and relaying node address records
var sortPeers = noSortPeers
// Peer wraps BzzPeer and embeds Kademlia overlay connectivity driver // Peer wraps BzzPeer and embeds Kademlia overlay connectivity driver
type Peer struct { type Peer struct {
*BzzPeer *BzzPeer
@ -181,7 +183,7 @@ func (d *Peer) handleSubPeersMsg(msg *subPeersMsg) error {
}) })
// if useful peers are found, send them over // if useful peers are found, send them over
if len(peers) > 0 { if len(peers) > 0 {
go d.Send(context.TODO(), &peersMsg{Peers: peers}) go d.Send(context.TODO(), &peersMsg{Peers: sortPeers(peers)})
} }
} }
d.sentPeers = true d.sentPeers = true
@ -212,3 +214,7 @@ func (d *Peer) setDepth(depth uint8) {
defer d.mtx.Unlock() defer d.mtx.Unlock()
d.depth = depth d.depth = depth
} }
func noSortPeers(peers []*BzzAddr) []*BzzAddr {
return peers
}

View file

@ -18,9 +18,12 @@ package network
import ( import (
"crypto/ecdsa" "crypto/ecdsa"
"crypto/rand" crand "crypto/rand"
"encoding/binary"
"fmt" "fmt"
"math/rand"
"net" "net"
"sort"
"testing" "testing"
"time" "time"
@ -39,7 +42,7 @@ import (
*/ */
func TestSubPeersMsg(t *testing.T) { func TestSubPeersMsg(t *testing.T) {
params := NewHiveParams() params := NewHiveParams()
s, pp, err := newHiveTester(t, params, 1, nil) s, pp, err := newHiveTester(params, 1, nil)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -70,8 +73,9 @@ func TestSubPeersMsg(t *testing.T) {
} }
const ( const (
maxPO = 8 // PO of pivot and control; chosen to test enough cases but not run too long maxPO = 8 // PO of pivot and control; chosen to test enough cases but not run too long
maxPeerPO = 6 // pivot has no peers closer than this to the control peer maxPeerPO = 6 // pivot has no peers closer than this to the control peer
maxPeersPerPO = 3
) )
// TestInitialPeersMsg tests if peersMsg response to incoming subPeersMsg is correct // TestInitialPeersMsg tests if peersMsg response to incoming subPeersMsg is correct
@ -93,6 +97,11 @@ func testInitialPeersMsg(t *testing.T, peerPO, peerDepth int) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
defer func(orig func([]*BzzAddr) []*BzzAddr) {
sortPeers = orig
}(sortPeers)
sortPeers = testSortPeers
pivotAddr := pot.NewAddressFromBytes(PrivateKeyToBzzKey(prvkey)) pivotAddr := pot.NewAddressFromBytes(PrivateKeyToBzzKey(prvkey))
// generate control peers address at peerPO wrt pivot // generate control peers address at peerPO wrt pivot
peerAddr := pot.RandomAddressAt(pivotAddr, peerPO) peerAddr := pot.RandomAddressAt(pivotAddr, peerPO)
@ -102,10 +111,17 @@ func testInitialPeersMsg(t *testing.T, peerPO, peerDepth int) {
// expected addrs in peersMsg response // expected addrs in peersMsg response
var expBzzAddrs []*BzzAddr var expBzzAddrs []*BzzAddr
connect := func(a pot.Address, po int) *BzzAddr { connect := func(a pot.Address, po int) (addrs []*BzzAddr) {
peer := newDiscPeer(pot.RandomAddressAt(a, po)) n := rand.Intn(maxPeersPerPO)
hive.On(peer) for i := 0; i < n; i++ {
return peer.BzzAddr peer, err := newDiscPeer(pot.RandomAddressAt(a, po))
if err != nil {
t.Fatal(err)
}
hive.On(peer)
addrs = append(addrs, peer.BzzAddr)
}
return addrs
} }
register := func(a pot.Address, po int) { register := func(a pot.Address, po int) {
addr := pot.RandomAddressAt(a, po) addr := pot.RandomAddressAt(a, po)
@ -115,18 +131,26 @@ func testInitialPeersMsg(t *testing.T, peerPO, peerDepth int) {
// generate connected and just registered peers // generate connected and just registered peers
for po := maxPeerPO; po >= 0; po-- { for po := maxPeerPO; po >= 0; po-- {
// create a fake connected peer at po from peerAddr // create a fake connected peer at po from peerAddr
on := connect(peerAddr, po) ons := connect(peerAddr, po)
// create a fake registered address at po from peerAddr // create a fake registered address at po from peerAddr
register(peerAddr, po) register(peerAddr, po)
// we collect expected peer addresses only up till peerPO // we collect expected peer addresses only up till peerPO
if po < peerDepth { if po < peerDepth {
continue continue
} }
expBzzAddrs = append(expBzzAddrs, on) expBzzAddrs = append(expBzzAddrs, ons...)
}
// add extra connections closer to pivot than control
for po := peerPO + 1; po < maxPO; po++ {
ons := connect(pivotAddr, po)
if peerDepth <= peerPO {
expBzzAddrs = append(expBzzAddrs, ons...)
}
} }
// create a special bzzBaseTester in which we can associate `enode.ID` to the `bzzAddr` we created above // create a special bzzBaseTester in which we can associate `enode.ID` to the `bzzAddr` we created above
s, _, err := newBzzBaseTesterWithAddrs(t, prvkey, [][]byte{peerAddr[:]}, DiscoverySpec, hive.Run) s, _, err := newBzzBaseTesterWithAddrs(prvkey, [][]byte{peerAddr[:]}, DiscoverySpec, hive.Run)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -175,7 +199,7 @@ func testInitialPeersMsg(t *testing.T, peerPO, peerDepth int) {
Expects: []p2ptest.Expect{ Expects: []p2ptest.Expect{
{ {
Code: 0, Code: 0,
Msg: &peersMsg{Peers: expBzzAddrs}, Msg: &peersMsg{Peers: testSortPeers(expBzzAddrs)},
Peer: peerID, Peer: peerID,
Timeout: 100 * time.Millisecond, Timeout: 100 * time.Millisecond,
}, },
@ -199,13 +223,23 @@ func testInitialPeersMsg(t *testing.T, peerPO, peerDepth int) {
} }
} }
func testSortPeers(peers []*BzzAddr) []*BzzAddr {
comp := func(i, j int) bool {
vi := binary.BigEndian.Uint64(peers[i].OAddr)
vj := binary.BigEndian.Uint64(peers[j].OAddr)
return vi < vj
}
sort.Slice(peers, comp)
return peers
}
// as we are not creating a real node via the protocol, // as we are not creating a real node via the protocol,
// we need to create the discovery peer objects for the additional kademlia // we need to create the discovery peer objects for the additional kademlia
// nodes manually // nodes manually
func newDiscPeer(addr pot.Address) *Peer { func newDiscPeer(addr pot.Address) (*Peer, error) {
pKey, err := ecdsa.GenerateKey(crypto.S256(), rand.Reader) pKey, err := ecdsa.GenerateKey(crypto.S256(), crand.Reader)
if err != nil { if err != nil {
panic(err.Error()) return nil, err
} }
pubKey := pKey.PublicKey pubKey := pKey.PublicKey
nod := enode.NewV4(&pubKey, net.IPv4(127, 0, 0, 1), 0, 0) nod := enode.NewV4(&pubKey, net.IPv4(127, 0, 0, 1), 0, 0)
@ -215,7 +249,7 @@ func newDiscPeer(addr pot.Address) *Peer {
return NewPeer(&BzzPeer{ return NewPeer(&BzzPeer{
Peer: protocols.NewPeer(p2pPeer, &dummyMsgRW{}, DiscoverySpec), Peer: protocols.NewPeer(p2pPeer, &dummyMsgRW{}, DiscoverySpec),
BzzAddr: bzzAddr, BzzAddr: bzzAddr,
}, nil) }, nil), nil
} }
type dummyMsgRW struct{} type dummyMsgRW struct{}

View file

@ -28,7 +28,7 @@ import (
"github.com/ethereum/go-ethereum/swarm/state" "github.com/ethereum/go-ethereum/swarm/state"
) )
func newHiveTester(t *testing.T, params *HiveParams, n int, store state.Store) (*bzzTester, *Hive, error) { func newHiveTester(params *HiveParams, n int, store state.Store) (*bzzTester, *Hive, error) {
// setup // setup
prvkey, err := crypto.GenerateKey() prvkey, err := crypto.GenerateKey()
if err != nil { if err != nil {
@ -38,7 +38,7 @@ func newHiveTester(t *testing.T, params *HiveParams, n int, store state.Store) (
to := NewKademlia(addr, NewKadParams()) to := NewKademlia(addr, NewKadParams())
pp := NewHive(params, to, store) // hive pp := NewHive(params, to, store) // hive
bt, err := newBzzBaseTester(t, n, prvkey, DiscoverySpec, pp.Run) bt, err := newBzzBaseTester(n, prvkey, DiscoverySpec, pp.Run)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
@ -49,7 +49,7 @@ func newHiveTester(t *testing.T, params *HiveParams, n int, store state.Store) (
// and that the peer connection exists afterwards // and that the peer connection exists afterwards
func TestRegisterAndConnect(t *testing.T) { func TestRegisterAndConnect(t *testing.T) {
params := NewHiveParams() params := NewHiveParams()
s, pp, err := newHiveTester(t, params, 1, nil) s, pp, err := newHiveTester(params, 1, nil)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }

View file

@ -73,17 +73,17 @@ func HandshakeMsgExchange(lhs, rhs *HandshakeMsg, id enode.ID) []p2ptest.Exchang
} }
} }
func newBzzBaseTester(t *testing.T, n int, prvkey *ecdsa.PrivateKey, spec *protocols.Spec, run func(*BzzPeer) error) (*bzzTester, error) { func newBzzBaseTester(n int, prvkey *ecdsa.PrivateKey, spec *protocols.Spec, run func(*BzzPeer) error) (*bzzTester, error) {
var addrs [][]byte var addrs [][]byte
for i := 0; i < n; i++ { for i := 0; i < n; i++ {
addr := pot.RandomAddress() addr := pot.RandomAddress()
addrs = append(addrs, addr[:]) addrs = append(addrs, addr[:])
} }
pt, _, err := newBzzBaseTesterWithAddrs(t, prvkey, addrs, spec, run) pt, _, err := newBzzBaseTesterWithAddrs(prvkey, addrs, spec, run)
return pt, err return pt, err
} }
func newBzzBaseTesterWithAddrs(t *testing.T, prvkey *ecdsa.PrivateKey, addrs [][]byte, spec *protocols.Spec, run func(*BzzPeer) error) (*bzzTester, [][]byte, error) { func newBzzBaseTesterWithAddrs(prvkey *ecdsa.PrivateKey, addrs [][]byte, spec *protocols.Spec, run func(*BzzPeer) error) (*bzzTester, [][]byte, error) {
n := len(addrs) n := len(addrs)
cs := make(map[enode.ID]chan bool) cs := make(map[enode.ID]chan bool)