From d0e104b280e51222f13a240e2b2f692f358b280b Mon Sep 17 00:00:00 2001 From: Anton Evangelatov Date: Wed, 7 Feb 2018 12:47:34 +0100 Subject: [PATCH] p2p/sim, swarm/network: propagate port via NodeConfig --- p2p/simulations/adapters/exec.go | 114 +++--------------- p2p/simulations/adapters/types.go | 31 ++++- swarm/network/protocol.go | 9 ++ .../simulations/discovery/discovery_test.go | 4 +- 4 files changed, 56 insertions(+), 102 deletions(-) diff --git a/p2p/simulations/adapters/exec.go b/p2p/simulations/adapters/exec.go index 2123168469..808383939b 100644 --- a/p2p/simulations/adapters/exec.go +++ b/p2p/simulations/adapters/exec.go @@ -30,20 +30,17 @@ import ( "os/signal" "path/filepath" "regexp" - "strconv" "strings" "sync" "syscall" "time" - "github.com/davecgh/go-spew/spew" "github.com/docker/docker/pkg/reexec" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/node" "github.com/ethereum/go-ethereum/p2p" "github.com/ethereum/go-ethereum/p2p/discover" "github.com/ethereum/go-ethereum/rpc" - "github.com/ethereum/go-ethereum/swarm/network" "golang.org/x/net/websocket" ) @@ -112,9 +109,6 @@ func (e *ExecAdapter) NewNode(config *NodeConfig) (Node, error) { // starting the node through the RPC admin.nodeInfo method) conf.Stack.P2P.ListenAddr = fmt.Sprintf("127.0.0.1:%d", config.Port) - spew.Dump("correct config") - spew.Dump(conf) - node := &ExecNode{ ID: config.ID, Dir: dir, @@ -388,14 +382,6 @@ func execP2PNode() { conf.Stack.WSHost = externalIP() } - ports := strings.Split(conf.Stack.P2P.ListenAddr, ":") - - prt, err := strconv.ParseInt(ports[1], 10, 32) - if err != nil { - panic(err) - } - prt16 := uint16(prt) - // initialize the devp2p stack stack, err := node.New(&conf.Stack) if err != nil { @@ -406,90 +392,28 @@ func execP2PNode() { // them in a snapshot service services := make(map[string]node.Service, len(serviceNames)) for _, name := range serviceNames { - if name == "discovery" { - serviceFunc := func(ctx *ServiceContext) (node.Service, error) { - //addr := network.NewAddrFromNodeID(ctx.Config.ID) - - spew.Dump("incorrect config") - spew.Dump(ctx.Config) - - addr := &network.BzzAddr{ - OAddr: network.ToOverlayAddr(ctx.Config.ID.Bytes()), - //UAddr: []byte(discover.NewNode(ctx.Config.ID, net.IP{127, 0, 0, 1}, ctx.Config.Port, ctx.Config.Port).String()), - UAddr: []byte(discover.NewNode(ctx.Config.ID, net.IP{127, 0, 0, 1}, prt16, prt16).String()), - } - - kp := network.NewKadParams() - kp.MinProxBinSize = 2 - kp.MaxBinSize = 3 - kp.MinBinSize = 1 - kp.MaxRetries = 1000 - kp.RetryExponent = 2 - kp.RetryInterval = 50000000 - - if ctx.Config.Reachable != nil { - kp.Reachable = func(o network.OverlayAddr) bool { - return ctx.Config.Reachable(o.(*network.BzzAddr).ID()) - } - } - kad := network.NewKademlia(addr.Over(), kp) - - hp := network.NewHiveParams() - hp.KeepAliveInterval = 200 * time.Millisecond - - config := &network.BzzConfig{ - OverlayAddr: addr.Over(), - UnderlayAddr: addr.Under(), - HiveParams: hp, - } - - return network.NewBzz(config, kad, nil), nil + serviceFunc, exists := serviceFuncs[name] + if !exists { + log.Crit("unknown node service", "name", name) + } + constructor := func(nodeCtx *node.ServiceContext) (node.Service, error) { + ctx := &ServiceContext{ + RPCDialer: &wsRPCDialer{addrs: conf.PeerAddrs}, + NodeContext: nodeCtx, + Config: conf.Node, } - - constructor := func(nodeCtx *node.ServiceContext) (node.Service, error) { - ctx := &ServiceContext{ - RPCDialer: &wsRPCDialer{addrs: conf.PeerAddrs}, - NodeContext: nodeCtx, - Config: conf.Node, - } - if conf.Snapshots != nil { - ctx.Snapshot = conf.Snapshots[name] - } - service, err := serviceFunc(ctx) - if err != nil { - return nil, err - } - services[name] = service - return service, nil + if conf.Snapshots != nil { + ctx.Snapshot = conf.Snapshots[name] } - if err := stack.Register(constructor); err != nil { - log.Crit("error starting service", "name", name, "err", err) - } - - } else { - serviceFunc, exists := serviceFuncs[name] - if !exists { - log.Crit("unknown node service", "name", name) - } - constructor := func(nodeCtx *node.ServiceContext) (node.Service, error) { - ctx := &ServiceContext{ - RPCDialer: &wsRPCDialer{addrs: conf.PeerAddrs}, - NodeContext: nodeCtx, - Config: conf.Node, - } - if conf.Snapshots != nil { - ctx.Snapshot = conf.Snapshots[name] - } - service, err := serviceFunc(ctx) - if err != nil { - return nil, err - } - services[name] = service - return service, nil - } - if err := stack.Register(constructor); err != nil { - log.Crit("error starting service", "name", name, "err", err) + service, err := serviceFunc(ctx) + if err != nil { + return nil, err } + services[name] = service + return service, nil + } + if err := stack.Register(constructor); err != nil { + log.Crit("error starting service", "name", name, "err", err) } } diff --git a/p2p/simulations/adapters/types.go b/p2p/simulations/adapters/types.go index 129942e05e..2169d68308 100644 --- a/p2p/simulations/adapters/types.go +++ b/p2p/simulations/adapters/types.go @@ -21,10 +21,9 @@ import ( "encoding/hex" "encoding/json" "fmt" - "math/rand" "net" "os" - "time" + "strconv" "github.com/docker/docker/pkg/reexec" "github.com/ethereum/go-ethereum/crypto" @@ -110,6 +109,7 @@ type nodeConfigJSON struct { PrivateKey string `json:"private_key"` Name string `json:"name"` Services []string `json:"services"` + Port uint16 `json:"port"` } // MarshalJSON implements the json.Marshaler interface by encoding the config @@ -119,6 +119,7 @@ func (n *NodeConfig) MarshalJSON() ([]byte, error) { ID: n.ID.String(), Name: n.Name, Services: n.Services, + Port: n.Port, } if n.PrivateKey != nil { confJSON.PrivateKey = hex.EncodeToString(crypto.FromECDSA(n.PrivateKey)) @@ -156,6 +157,7 @@ func (n *NodeConfig) UnmarshalJSON(data []byte) error { n.Name = confJSON.Name n.Services = confJSON.Services + n.Port = confJSON.Port return nil } @@ -169,15 +171,34 @@ func RandomNodeConfig() *NodeConfig { } id := discover.PubkeyID(&key.PublicKey) - rand.Seed(time.Now().UTC().UnixNano()) - fmt.Println(rand.Int()) + port, err := assignTCPPort() + if err != nil { + panic("unable to assign tcp port") + } return &NodeConfig{ ID: id, PrivateKey: key, - Port: uint16(5000 + rand.Int()%2000), + Port: port, } } +func assignTCPPort() (uint16, error) { + l, err := net.Listen("tcp", "127.0.0.1:0") + if err != nil { + return 0, err + } + l.Close() + _, port, err := net.SplitHostPort(l.Addr().String()) + if err != nil { + return 0, err + } + p, err := strconv.ParseInt(port, 10, 32) + if err != nil { + return 0, err + } + return uint16(p), nil +} + // ServiceContext is a collection of options and methods which can be utilised // when starting services type ServiceContext struct { diff --git a/swarm/network/protocol.go b/swarm/network/protocol.go index 9afa69c3a9..448e722269 100644 --- a/swarm/network/protocol.go +++ b/swarm/network/protocol.go @@ -402,6 +402,15 @@ func NewAddrFromNodeID(id discover.NodeID) *BzzAddr { } } +// NewAddrFromNodeIDAndPort constucts a BzzAddr from a discover.NodeID and port uint16 +// the overlay address is derived as the hash of the nodeID +func NewAddrFromNodeIDAndPort(id discover.NodeID, port uint16) *BzzAddr { + return &BzzAddr{ + OAddr: ToOverlayAddr(id.Bytes()), + UAddr: []byte(discover.NewNode(id, net.IP{127, 0, 0, 1}, port, port).String()), + } +} + // ToOverlayAddr creates an overlayaddress from a byte slice func ToOverlayAddr(id []byte) []byte { return crypto.Keccak256(id) diff --git a/swarm/network/simulations/discovery/discovery_test.go b/swarm/network/simulations/discovery/discovery_test.go index 63674c3c02..cc4373483b 100644 --- a/swarm/network/simulations/discovery/discovery_test.go +++ b/swarm/network/simulations/discovery/discovery_test.go @@ -139,7 +139,7 @@ func benchmarkDiscovery(b *testing.B, nodes, conns int) { for i := 0; i < b.N; i++ { result, err := discoverySimulation(nodes, conns, adapters.NewSimAdapter(services)) if err != nil { - b.Fatalf("setting up simulation failed", result) + b.Fatalf("setting up simulation failed: %s", err) } if result.Error != nil { b.Logf("simulation failed: %s", result.Error) @@ -297,7 +297,7 @@ func triggerChecks(trigger chan discover.NodeID, net *simulations.Network, id di } func newService(ctx *adapters.ServiceContext) (node.Service, error) { - addr := network.NewAddrFromNodeID(ctx.Config.ID) + addr := network.NewAddrFromNodeIDAndPort(ctx.Config.ID, ctx.Config.Port) kp := network.NewKadParams() kp.MinProxBinSize = testMinProxBinSize