p2p/sim, swarm/network: propagate port via NodeConfig

This commit is contained in:
Anton Evangelatov 2018-02-07 12:47:34 +01:00
parent 0bea19ec34
commit d0e104b280
4 changed files with 56 additions and 102 deletions

View file

@ -30,20 +30,17 @@ import (
"os/signal" "os/signal"
"path/filepath" "path/filepath"
"regexp" "regexp"
"strconv"
"strings" "strings"
"sync" "sync"
"syscall" "syscall"
"time" "time"
"github.com/davecgh/go-spew/spew"
"github.com/docker/docker/pkg/reexec" "github.com/docker/docker/pkg/reexec"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/node" "github.com/ethereum/go-ethereum/node"
"github.com/ethereum/go-ethereum/p2p" "github.com/ethereum/go-ethereum/p2p"
"github.com/ethereum/go-ethereum/p2p/discover" "github.com/ethereum/go-ethereum/p2p/discover"
"github.com/ethereum/go-ethereum/rpc" "github.com/ethereum/go-ethereum/rpc"
"github.com/ethereum/go-ethereum/swarm/network"
"golang.org/x/net/websocket" "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) // starting the node through the RPC admin.nodeInfo method)
conf.Stack.P2P.ListenAddr = fmt.Sprintf("127.0.0.1:%d", config.Port) conf.Stack.P2P.ListenAddr = fmt.Sprintf("127.0.0.1:%d", config.Port)
spew.Dump("correct config")
spew.Dump(conf)
node := &ExecNode{ node := &ExecNode{
ID: config.ID, ID: config.ID,
Dir: dir, Dir: dir,
@ -388,14 +382,6 @@ func execP2PNode() {
conf.Stack.WSHost = externalIP() 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 // initialize the devp2p stack
stack, err := node.New(&conf.Stack) stack, err := node.New(&conf.Stack)
if err != nil { if err != nil {
@ -406,90 +392,28 @@ func execP2PNode() {
// them in a snapshot service // them in a snapshot service
services := make(map[string]node.Service, len(serviceNames)) services := make(map[string]node.Service, len(serviceNames))
for _, name := range serviceNames { for _, name := range serviceNames {
if name == "discovery" { serviceFunc, exists := serviceFuncs[name]
serviceFunc := func(ctx *ServiceContext) (node.Service, error) { if !exists {
//addr := network.NewAddrFromNodeID(ctx.Config.ID) log.Crit("unknown node service", "name", name)
}
spew.Dump("incorrect config") constructor := func(nodeCtx *node.ServiceContext) (node.Service, error) {
spew.Dump(ctx.Config) ctx := &ServiceContext{
RPCDialer: &wsRPCDialer{addrs: conf.PeerAddrs},
addr := &network.BzzAddr{ NodeContext: nodeCtx,
OAddr: network.ToOverlayAddr(ctx.Config.ID.Bytes()), Config: conf.Node,
//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
} }
if conf.Snapshots != nil {
constructor := func(nodeCtx *node.ServiceContext) (node.Service, error) { ctx.Snapshot = conf.Snapshots[name]
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 { service, err := serviceFunc(ctx)
log.Crit("error starting service", "name", name, "err", err) if err != nil {
} return nil, 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)
} }
services[name] = service
return service, nil
}
if err := stack.Register(constructor); err != nil {
log.Crit("error starting service", "name", name, "err", err)
} }
} }

View file

@ -21,10 +21,9 @@ import (
"encoding/hex" "encoding/hex"
"encoding/json" "encoding/json"
"fmt" "fmt"
"math/rand"
"net" "net"
"os" "os"
"time" "strconv"
"github.com/docker/docker/pkg/reexec" "github.com/docker/docker/pkg/reexec"
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
@ -110,6 +109,7 @@ type nodeConfigJSON struct {
PrivateKey string `json:"private_key"` PrivateKey string `json:"private_key"`
Name string `json:"name"` Name string `json:"name"`
Services []string `json:"services"` Services []string `json:"services"`
Port uint16 `json:"port"`
} }
// MarshalJSON implements the json.Marshaler interface by encoding the config // MarshalJSON implements the json.Marshaler interface by encoding the config
@ -119,6 +119,7 @@ func (n *NodeConfig) MarshalJSON() ([]byte, error) {
ID: n.ID.String(), ID: n.ID.String(),
Name: n.Name, Name: n.Name,
Services: n.Services, Services: n.Services,
Port: n.Port,
} }
if n.PrivateKey != nil { if n.PrivateKey != nil {
confJSON.PrivateKey = hex.EncodeToString(crypto.FromECDSA(n.PrivateKey)) confJSON.PrivateKey = hex.EncodeToString(crypto.FromECDSA(n.PrivateKey))
@ -156,6 +157,7 @@ func (n *NodeConfig) UnmarshalJSON(data []byte) error {
n.Name = confJSON.Name n.Name = confJSON.Name
n.Services = confJSON.Services n.Services = confJSON.Services
n.Port = confJSON.Port
return nil return nil
} }
@ -169,15 +171,34 @@ func RandomNodeConfig() *NodeConfig {
} }
id := discover.PubkeyID(&key.PublicKey) id := discover.PubkeyID(&key.PublicKey)
rand.Seed(time.Now().UTC().UnixNano()) port, err := assignTCPPort()
fmt.Println(rand.Int()) if err != nil {
panic("unable to assign tcp port")
}
return &NodeConfig{ return &NodeConfig{
ID: id, ID: id,
PrivateKey: key, 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 // ServiceContext is a collection of options and methods which can be utilised
// when starting services // when starting services
type ServiceContext struct { type ServiceContext struct {

View file

@ -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 // ToOverlayAddr creates an overlayaddress from a byte slice
func ToOverlayAddr(id []byte) []byte { func ToOverlayAddr(id []byte) []byte {
return crypto.Keccak256(id) return crypto.Keccak256(id)

View file

@ -139,7 +139,7 @@ func benchmarkDiscovery(b *testing.B, nodes, conns int) {
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
result, err := discoverySimulation(nodes, conns, adapters.NewSimAdapter(services)) result, err := discoverySimulation(nodes, conns, adapters.NewSimAdapter(services))
if err != nil { if err != nil {
b.Fatalf("setting up simulation failed", result) b.Fatalf("setting up simulation failed: %s", err)
} }
if result.Error != nil { if result.Error != nil {
b.Logf("simulation failed: %s", result.Error) 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) { 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 := network.NewKadParams()
kp.MinProxBinSize = testMinProxBinSize kp.MinProxBinSize = testMinProxBinSize