all: new p2p node representation (#17643)
Package p2p/enode provides a generalized representation of p2p nodes which can contain arbitrary information in key/value pairs. It is also the new home for the node database. The "v4" identity scheme is also moved here from p2p/enr to remove the dependency on Ethereum crypto from that package. Record signature handling is changed significantly. The identity scheme registry is removed and acceptable schemes must be passed to any method that needs identity. This means records must now be validated explicitly after decoding. The enode API is designed to make signature handling easy and safe: most APIs around the codebase work with enode.Node, which is a wrapper around a valid record. Going from enr.Record to enode.Node requires a valid signature. * p2p/discover: port to p2p/enode This ports the discovery code to the new node representation in p2p/enode. The wire protocol is unchanged, this can be considered a refactoring change. The Kademlia table can now deal with nodes using an arbitrary identity scheme. This requires a few incompatible API changes: - Table.Lookup is not available anymore. It used to take a public key as argument because v4 protocol requires one. Its replacement is LookupRandom. - Table.Resolve takes *enode.Node instead of NodeID. This is also for v4 protocol compatibility because nodes cannot be looked up by ID alone. - Types Node and NodeID are gone. Further commits in the series will be fixes all over the the codebase to deal with those removals. * p2p: port to p2p/enode and discovery changes This adapts package p2p to the changes in p2p/discover. All uses of discover.Node and discover.NodeID are replaced by their equivalents from p2p/enode. New API is added to retrieve the enode.Node instance of a peer. The behavior of Server.Self with discovery disabled is improved. It now tries much harder to report a working IP address, falling back to 127.0.0.1 if no suitable address can be determined through other means. These changes were needed for tests of other packages later in the series. * p2p/simulations, p2p/testing: port to p2p/enode No surprises here, mostly replacements of discover.Node, discover.NodeID with their new equivalents. The 'interesting' API changes are: - testing.ProtocolSession tracks complete nodes, not just their IDs. - adapters.NodeConfig has a new method to create a complete node. These changes were needed to make swarm tests work. Note that the NodeID change makes the code incompatible with old simulation snapshots. * whisper/whisperv5, whisper/whisperv6: port to p2p/enode This port was easy because whisper uses []byte for node IDs and URL strings in the API. * eth: port to p2p/enode Again, easy to port because eth uses strings for node IDs and doesn't care about node information in any way. * les: port to p2p/enode Apart from replacing discover.NodeID with enode.ID, most changes are in the server pool code. It now deals with complete nodes instead of (Pubkey, IP, Port) triples. The database format is unchanged for now, but we should probably change it to use the node database later. * node: port to p2p/enode This change simply replaces discover.Node and discover.NodeID with their new equivalents. * swarm/network: port to p2p/enode Swarm has its own node address representation, BzzAddr, containing both an overlay address (the hash of a secp256k1 public key) and an underlay address (enode:// URL). There are no changes to the BzzAddr format in this commit, but certain operations such as creating a BzzAddr from a node ID are now impossible because node IDs aren't public keys anymore. Most swarm-related changes in the series remove uses of NewAddrFromNodeID, replacing it with NewAddr which takes a complete node as argument. ToOverlayAddr is removed because we can just use the node ID directly.
This commit is contained in:
@ -29,7 +29,7 @@ import (
|
||||
|
||||
"github.com/docker/docker/pkg/reexec"
|
||||
"github.com/ethereum/go-ethereum/node"
|
||||
"github.com/ethereum/go-ethereum/p2p/discover"
|
||||
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -64,7 +64,7 @@ func NewDockerAdapter() (*DockerAdapter, error) {
|
||||
|
||||
return &DockerAdapter{
|
||||
ExecAdapter{
|
||||
nodes: make(map[discover.NodeID]*ExecNode),
|
||||
nodes: make(map[enode.ID]*ExecNode),
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ import (
|
||||
"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/p2p/enode"
|
||||
"github.com/ethereum/go-ethereum/rpc"
|
||||
"golang.org/x/net/websocket"
|
||||
)
|
||||
@ -54,7 +54,7 @@ type ExecAdapter struct {
|
||||
// simulation node are created.
|
||||
BaseDir string
|
||||
|
||||
nodes map[discover.NodeID]*ExecNode
|
||||
nodes map[enode.ID]*ExecNode
|
||||
}
|
||||
|
||||
// NewExecAdapter returns an ExecAdapter which stores node data in
|
||||
@ -62,7 +62,7 @@ type ExecAdapter struct {
|
||||
func NewExecAdapter(baseDir string) *ExecAdapter {
|
||||
return &ExecAdapter{
|
||||
BaseDir: baseDir,
|
||||
nodes: make(map[discover.NodeID]*ExecNode),
|
||||
nodes: make(map[enode.ID]*ExecNode),
|
||||
}
|
||||
}
|
||||
|
||||
@ -122,7 +122,7 @@ func (e *ExecAdapter) NewNode(config *NodeConfig) (Node, error) {
|
||||
// ExecNode starts a simulation node by exec'ing the current binary and
|
||||
// running the configured services
|
||||
type ExecNode struct {
|
||||
ID discover.NodeID
|
||||
ID enode.ID
|
||||
Dir string
|
||||
Config *execNodeConfig
|
||||
Cmd *exec.Cmd
|
||||
@ -492,7 +492,7 @@ type wsRPCDialer struct {
|
||||
|
||||
// DialRPC implements the RPCDialer interface by creating a WebSocket RPC
|
||||
// client of the given node
|
||||
func (w *wsRPCDialer) DialRPC(id discover.NodeID) (*rpc.Client, error) {
|
||||
func (w *wsRPCDialer) DialRPC(id enode.ID) (*rpc.Client, error) {
|
||||
addr, ok := w.addrs[id.String()]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unknown node: %s", id)
|
||||
|
@ -27,7 +27,7 @@ import (
|
||||
"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/p2p/enode"
|
||||
"github.com/ethereum/go-ethereum/p2p/simulations/pipes"
|
||||
"github.com/ethereum/go-ethereum/rpc"
|
||||
)
|
||||
@ -37,7 +37,7 @@ import (
|
||||
type SimAdapter struct {
|
||||
pipe func() (net.Conn, net.Conn, error)
|
||||
mtx sync.RWMutex
|
||||
nodes map[discover.NodeID]*SimNode
|
||||
nodes map[enode.ID]*SimNode
|
||||
services map[string]ServiceFunc
|
||||
}
|
||||
|
||||
@ -48,7 +48,7 @@ type SimAdapter struct {
|
||||
func NewSimAdapter(services map[string]ServiceFunc) *SimAdapter {
|
||||
return &SimAdapter{
|
||||
pipe: pipes.NetPipe,
|
||||
nodes: make(map[discover.NodeID]*SimNode),
|
||||
nodes: make(map[enode.ID]*SimNode),
|
||||
services: services,
|
||||
}
|
||||
}
|
||||
@ -56,7 +56,7 @@ func NewSimAdapter(services map[string]ServiceFunc) *SimAdapter {
|
||||
func NewTCPAdapter(services map[string]ServiceFunc) *SimAdapter {
|
||||
return &SimAdapter{
|
||||
pipe: pipes.TCPPipe,
|
||||
nodes: make(map[discover.NodeID]*SimNode),
|
||||
nodes: make(map[enode.ID]*SimNode),
|
||||
services: services,
|
||||
}
|
||||
}
|
||||
@ -115,14 +115,14 @@ func (s *SimAdapter) NewNode(config *NodeConfig) (Node, error) {
|
||||
|
||||
// Dial implements the p2p.NodeDialer interface by connecting to the node using
|
||||
// an in-memory net.Pipe
|
||||
func (s *SimAdapter) Dial(dest *discover.Node) (conn net.Conn, err error) {
|
||||
node, ok := s.GetNode(dest.ID)
|
||||
func (s *SimAdapter) Dial(dest *enode.Node) (conn net.Conn, err error) {
|
||||
node, ok := s.GetNode(dest.ID())
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unknown node: %s", dest.ID)
|
||||
return nil, fmt.Errorf("unknown node: %s", dest.ID())
|
||||
}
|
||||
srv := node.Server()
|
||||
if srv == nil {
|
||||
return nil, fmt.Errorf("node not running: %s", dest.ID)
|
||||
return nil, fmt.Errorf("node not running: %s", dest.ID())
|
||||
}
|
||||
// SimAdapter.pipe is net.Pipe (NewSimAdapter)
|
||||
pipe1, pipe2, err := s.pipe()
|
||||
@ -138,7 +138,7 @@ func (s *SimAdapter) Dial(dest *discover.Node) (conn net.Conn, err error) {
|
||||
|
||||
// DialRPC implements the RPCDialer interface by creating an in-memory RPC
|
||||
// client of the given node
|
||||
func (s *SimAdapter) DialRPC(id discover.NodeID) (*rpc.Client, error) {
|
||||
func (s *SimAdapter) DialRPC(id enode.ID) (*rpc.Client, error) {
|
||||
node, ok := s.GetNode(id)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unknown node: %s", id)
|
||||
@ -151,7 +151,7 @@ func (s *SimAdapter) DialRPC(id discover.NodeID) (*rpc.Client, error) {
|
||||
}
|
||||
|
||||
// GetNode returns the node with the given ID if it exists
|
||||
func (s *SimAdapter) GetNode(id discover.NodeID) (*SimNode, bool) {
|
||||
func (s *SimAdapter) GetNode(id enode.ID) (*SimNode, bool) {
|
||||
s.mtx.RLock()
|
||||
defer s.mtx.RUnlock()
|
||||
node, ok := s.nodes[id]
|
||||
@ -163,7 +163,7 @@ func (s *SimAdapter) GetNode(id discover.NodeID) (*SimNode, bool) {
|
||||
// pipe
|
||||
type SimNode struct {
|
||||
lock sync.RWMutex
|
||||
ID discover.NodeID
|
||||
ID enode.ID
|
||||
config *NodeConfig
|
||||
adapter *SimAdapter
|
||||
node *node.Node
|
||||
@ -177,9 +177,9 @@ func (sn *SimNode) Addr() []byte {
|
||||
return []byte(sn.Node().String())
|
||||
}
|
||||
|
||||
// Node returns a discover.Node representing the SimNode
|
||||
func (sn *SimNode) Node() *discover.Node {
|
||||
return discover.NewNode(sn.ID, net.IP{127, 0, 0, 1}, 30303, 30303)
|
||||
// Node returns a node descriptor representing the SimNode
|
||||
func (sn *SimNode) Node() *enode.Node {
|
||||
return sn.config.Node()
|
||||
}
|
||||
|
||||
// Client returns an rpc.Client which can be used to communicate with the
|
||||
|
@ -29,7 +29,7 @@ import (
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/node"
|
||||
"github.com/ethereum/go-ethereum/p2p"
|
||||
"github.com/ethereum/go-ethereum/p2p/discover"
|
||||
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||
"github.com/ethereum/go-ethereum/rpc"
|
||||
)
|
||||
|
||||
@ -78,7 +78,7 @@ type NodeAdapter interface {
|
||||
type NodeConfig struct {
|
||||
// ID is the node's ID which is used to identify the node in the
|
||||
// simulation network
|
||||
ID discover.NodeID
|
||||
ID enode.ID
|
||||
|
||||
// PrivateKey is the node's private key which is used by the devp2p
|
||||
// stack to encrypt communications
|
||||
@ -97,7 +97,7 @@ type NodeConfig struct {
|
||||
Services []string
|
||||
|
||||
// function to sanction or prevent suggesting a peer
|
||||
Reachable func(id discover.NodeID) bool
|
||||
Reachable func(id enode.ID) bool
|
||||
|
||||
Port uint16
|
||||
}
|
||||
@ -138,11 +138,9 @@ func (n *NodeConfig) UnmarshalJSON(data []byte) error {
|
||||
}
|
||||
|
||||
if confJSON.ID != "" {
|
||||
nodeID, err := discover.HexID(confJSON.ID)
|
||||
if err != nil {
|
||||
if err := n.ID.UnmarshalText([]byte(confJSON.ID)); err != nil {
|
||||
return err
|
||||
}
|
||||
n.ID = nodeID
|
||||
}
|
||||
|
||||
if confJSON.PrivateKey != "" {
|
||||
@ -165,6 +163,11 @@ func (n *NodeConfig) UnmarshalJSON(data []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Node returns the node descriptor represented by the config.
|
||||
func (n *NodeConfig) Node() *enode.Node {
|
||||
return enode.NewV4(&n.PrivateKey.PublicKey, net.IP{127, 0, 0, 1}, int(n.Port), int(n.Port))
|
||||
}
|
||||
|
||||
// RandomNodeConfig returns node configuration with a randomly generated ID and
|
||||
// PrivateKey
|
||||
func RandomNodeConfig() *NodeConfig {
|
||||
@ -173,7 +176,7 @@ func RandomNodeConfig() *NodeConfig {
|
||||
panic("unable to generate key")
|
||||
}
|
||||
|
||||
id := discover.PubkeyID(&key.PublicKey)
|
||||
id := enode.PubkeyToIDV4(&key.PublicKey)
|
||||
port, err := assignTCPPort()
|
||||
if err != nil {
|
||||
panic("unable to assign tcp port")
|
||||
@ -218,7 +221,7 @@ type ServiceContext struct {
|
||||
// other nodes in the network (for example a simulated Swarm node which needs
|
||||
// to connect to a Geth node to resolve ENS names)
|
||||
type RPCDialer interface {
|
||||
DialRPC(id discover.NodeID) (*rpc.Client, error)
|
||||
DialRPC(id enode.ID) (*rpc.Client, error)
|
||||
}
|
||||
|
||||
// Services is a collection of services which can be run in a simulation
|
||||
|
@ -28,7 +28,7 @@ import (
|
||||
"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/p2p/enode"
|
||||
"github.com/ethereum/go-ethereum/p2p/simulations"
|
||||
"github.com/ethereum/go-ethereum/p2p/simulations/adapters"
|
||||
"github.com/ethereum/go-ethereum/rpc"
|
||||
@ -96,12 +96,12 @@ func main() {
|
||||
// sends a ping to all its connected peers every 10s and receives a pong in
|
||||
// return
|
||||
type pingPongService struct {
|
||||
id discover.NodeID
|
||||
id enode.ID
|
||||
log log.Logger
|
||||
received int64
|
||||
}
|
||||
|
||||
func newPingPongService(id discover.NodeID) *pingPongService {
|
||||
func newPingPongService(id enode.ID) *pingPongService {
|
||||
return &pingPongService{
|
||||
id: id,
|
||||
log: log.New("node.id", id),
|
||||
|
@ -31,7 +31,7 @@ import (
|
||||
|
||||
"github.com/ethereum/go-ethereum/event"
|
||||
"github.com/ethereum/go-ethereum/p2p"
|
||||
"github.com/ethereum/go-ethereum/p2p/discover"
|
||||
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||
"github.com/ethereum/go-ethereum/p2p/simulations/adapters"
|
||||
"github.com/ethereum/go-ethereum/rpc"
|
||||
"github.com/julienschmidt/httprouter"
|
||||
@ -709,8 +709,9 @@ func (s *Server) wrapHandler(handler http.HandlerFunc) httprouter.Handle {
|
||||
ctx := context.Background()
|
||||
|
||||
if id := params.ByName("nodeid"); id != "" {
|
||||
var nodeID enode.ID
|
||||
var node *Node
|
||||
if nodeID, err := discover.HexID(id); err == nil {
|
||||
if nodeID.UnmarshalText([]byte(id)) == nil {
|
||||
node = s.network.GetNode(nodeID)
|
||||
} else {
|
||||
node = s.network.GetNodeByName(id)
|
||||
@ -723,8 +724,9 @@ func (s *Server) wrapHandler(handler http.HandlerFunc) httprouter.Handle {
|
||||
}
|
||||
|
||||
if id := params.ByName("peerid"); id != "" {
|
||||
var peerID enode.ID
|
||||
var peer *Node
|
||||
if peerID, err := discover.HexID(id); err == nil {
|
||||
if peerID.UnmarshalText([]byte(id)) == nil {
|
||||
peer = s.network.GetNode(peerID)
|
||||
} else {
|
||||
peer = s.network.GetNodeByName(id)
|
||||
|
@ -30,7 +30,7 @@ import (
|
||||
"github.com/ethereum/go-ethereum/event"
|
||||
"github.com/ethereum/go-ethereum/node"
|
||||
"github.com/ethereum/go-ethereum/p2p"
|
||||
"github.com/ethereum/go-ethereum/p2p/discover"
|
||||
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||
"github.com/ethereum/go-ethereum/p2p/simulations/adapters"
|
||||
"github.com/ethereum/go-ethereum/rpc"
|
||||
)
|
||||
@ -38,12 +38,12 @@ import (
|
||||
// testService implements the node.Service interface and provides protocols
|
||||
// and APIs which are useful for testing nodes in a simulation network
|
||||
type testService struct {
|
||||
id discover.NodeID
|
||||
id enode.ID
|
||||
|
||||
// peerCount is incremented once a peer handshake has been performed
|
||||
peerCount int64
|
||||
|
||||
peers map[discover.NodeID]*testPeer
|
||||
peers map[enode.ID]*testPeer
|
||||
peersMtx sync.Mutex
|
||||
|
||||
// state stores []byte which is used to test creating and loading
|
||||
@ -54,7 +54,7 @@ type testService struct {
|
||||
func newTestService(ctx *adapters.ServiceContext) (node.Service, error) {
|
||||
svc := &testService{
|
||||
id: ctx.Config.ID,
|
||||
peers: make(map[discover.NodeID]*testPeer),
|
||||
peers: make(map[enode.ID]*testPeer),
|
||||
}
|
||||
svc.state.Store(ctx.Snapshot)
|
||||
return svc, nil
|
||||
@ -65,7 +65,7 @@ type testPeer struct {
|
||||
dumReady chan struct{}
|
||||
}
|
||||
|
||||
func (t *testService) peer(id discover.NodeID) *testPeer {
|
||||
func (t *testService) peer(id enode.ID) *testPeer {
|
||||
t.peersMtx.Lock()
|
||||
defer t.peersMtx.Unlock()
|
||||
if peer, ok := t.peers[id]; ok {
|
||||
@ -410,7 +410,7 @@ func (t *expectEvents) nodeEvent(id string, up bool) *Event {
|
||||
Type: EventTypeNode,
|
||||
Node: &Node{
|
||||
Config: &adapters.NodeConfig{
|
||||
ID: discover.MustHexID(id),
|
||||
ID: enode.HexID(id),
|
||||
},
|
||||
Up: up,
|
||||
},
|
||||
@ -421,8 +421,8 @@ func (t *expectEvents) connEvent(one, other string, up bool) *Event {
|
||||
return &Event{
|
||||
Type: EventTypeConn,
|
||||
Conn: &Conn{
|
||||
One: discover.MustHexID(one),
|
||||
Other: discover.MustHexID(other),
|
||||
One: enode.HexID(one),
|
||||
Other: enode.HexID(other),
|
||||
Up: up,
|
||||
},
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/ethereum/go-ethereum/p2p/discover"
|
||||
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||
"github.com/ethereum/go-ethereum/p2p/simulations/adapters"
|
||||
)
|
||||
|
||||
@ -154,7 +154,7 @@ func probabilistic(net *Network, quit chan struct{}, nodeCount int) {
|
||||
wg.Done()
|
||||
continue
|
||||
}
|
||||
go func(id discover.NodeID) {
|
||||
go func(id enode.ID) {
|
||||
time.Sleep(randWait)
|
||||
err := net.Start(id)
|
||||
if err != nil {
|
||||
@ -169,8 +169,8 @@ func probabilistic(net *Network, quit chan struct{}, nodeCount int) {
|
||||
}
|
||||
|
||||
//connect nodeCount number of nodes in a ring
|
||||
func connectNodesInRing(net *Network, nodeCount int) ([]discover.NodeID, error) {
|
||||
ids := make([]discover.NodeID, nodeCount)
|
||||
func connectNodesInRing(net *Network, nodeCount int) ([]enode.ID, error) {
|
||||
ids := make([]enode.ID, nodeCount)
|
||||
for i := 0; i < nodeCount; i++ {
|
||||
conf := adapters.RandomNodeConfig()
|
||||
node, err := net.NewNodeWithConfig(conf)
|
||||
|
@ -27,7 +27,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/p2p/discover"
|
||||
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||
)
|
||||
|
||||
func TestMocker(t *testing.T) {
|
||||
@ -82,7 +82,7 @@ func TestMocker(t *testing.T) {
|
||||
defer sub.Unsubscribe()
|
||||
//wait until all nodes are started and connected
|
||||
//store every node up event in a map (value is irrelevant, mimic Set datatype)
|
||||
nodemap := make(map[discover.NodeID]bool)
|
||||
nodemap := make(map[enode.ID]bool)
|
||||
wg.Add(1)
|
||||
nodesComplete := false
|
||||
connCount := 0
|
||||
|
@ -27,7 +27,7 @@ import (
|
||||
"github.com/ethereum/go-ethereum/event"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/ethereum/go-ethereum/p2p"
|
||||
"github.com/ethereum/go-ethereum/p2p/discover"
|
||||
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||
"github.com/ethereum/go-ethereum/p2p/simulations/adapters"
|
||||
)
|
||||
|
||||
@ -51,7 +51,7 @@ type Network struct {
|
||||
NetworkConfig
|
||||
|
||||
Nodes []*Node `json:"nodes"`
|
||||
nodeMap map[discover.NodeID]int
|
||||
nodeMap map[enode.ID]int
|
||||
|
||||
Conns []*Conn `json:"conns"`
|
||||
connMap map[string]int
|
||||
@ -67,7 +67,7 @@ func NewNetwork(nodeAdapter adapters.NodeAdapter, conf *NetworkConfig) *Network
|
||||
return &Network{
|
||||
NetworkConfig: *conf,
|
||||
nodeAdapter: nodeAdapter,
|
||||
nodeMap: make(map[discover.NodeID]int),
|
||||
nodeMap: make(map[enode.ID]int),
|
||||
connMap: make(map[string]int),
|
||||
quitc: make(chan struct{}),
|
||||
}
|
||||
@ -85,7 +85,7 @@ func (net *Network) NewNodeWithConfig(conf *adapters.NodeConfig) (*Node, error)
|
||||
defer net.lock.Unlock()
|
||||
|
||||
if conf.Reachable == nil {
|
||||
conf.Reachable = func(otherID discover.NodeID) bool {
|
||||
conf.Reachable = func(otherID enode.ID) bool {
|
||||
_, err := net.InitConn(conf.ID, otherID)
|
||||
if err != nil && bytes.Compare(conf.ID.Bytes(), otherID.Bytes()) < 0 {
|
||||
return false
|
||||
@ -158,13 +158,13 @@ func (net *Network) StopAll() error {
|
||||
}
|
||||
|
||||
// Start starts the node with the given ID
|
||||
func (net *Network) Start(id discover.NodeID) error {
|
||||
func (net *Network) Start(id enode.ID) error {
|
||||
return net.startWithSnapshots(id, nil)
|
||||
}
|
||||
|
||||
// startWithSnapshots starts the node with the given ID using the give
|
||||
// snapshots
|
||||
func (net *Network) startWithSnapshots(id discover.NodeID, snapshots map[string][]byte) error {
|
||||
func (net *Network) startWithSnapshots(id enode.ID, snapshots map[string][]byte) error {
|
||||
net.lock.Lock()
|
||||
defer net.lock.Unlock()
|
||||
node := net.getNode(id)
|
||||
@ -200,7 +200,7 @@ func (net *Network) startWithSnapshots(id discover.NodeID, snapshots map[string]
|
||||
|
||||
// watchPeerEvents reads peer events from the given channel and emits
|
||||
// corresponding network events
|
||||
func (net *Network) watchPeerEvents(id discover.NodeID, events chan *p2p.PeerEvent, sub event.Subscription) {
|
||||
func (net *Network) watchPeerEvents(id enode.ID, events chan *p2p.PeerEvent, sub event.Subscription) {
|
||||
defer func() {
|
||||
sub.Unsubscribe()
|
||||
|
||||
@ -248,7 +248,7 @@ func (net *Network) watchPeerEvents(id discover.NodeID, events chan *p2p.PeerEve
|
||||
}
|
||||
|
||||
// Stop stops the node with the given ID
|
||||
func (net *Network) Stop(id discover.NodeID) error {
|
||||
func (net *Network) Stop(id enode.ID) error {
|
||||
net.lock.Lock()
|
||||
defer net.lock.Unlock()
|
||||
node := net.getNode(id)
|
||||
@ -270,7 +270,7 @@ func (net *Network) Stop(id discover.NodeID) error {
|
||||
|
||||
// Connect connects two nodes together by calling the "admin_addPeer" RPC
|
||||
// method on the "one" node so that it connects to the "other" node
|
||||
func (net *Network) Connect(oneID, otherID discover.NodeID) error {
|
||||
func (net *Network) Connect(oneID, otherID enode.ID) error {
|
||||
log.Debug(fmt.Sprintf("connecting %s to %s", oneID, otherID))
|
||||
conn, err := net.InitConn(oneID, otherID)
|
||||
if err != nil {
|
||||
@ -286,7 +286,7 @@ func (net *Network) Connect(oneID, otherID discover.NodeID) error {
|
||||
|
||||
// Disconnect disconnects two nodes by calling the "admin_removePeer" RPC
|
||||
// method on the "one" node so that it disconnects from the "other" node
|
||||
func (net *Network) Disconnect(oneID, otherID discover.NodeID) error {
|
||||
func (net *Network) Disconnect(oneID, otherID enode.ID) error {
|
||||
conn := net.GetConn(oneID, otherID)
|
||||
if conn == nil {
|
||||
return fmt.Errorf("connection between %v and %v does not exist", oneID, otherID)
|
||||
@ -303,7 +303,7 @@ func (net *Network) Disconnect(oneID, otherID discover.NodeID) error {
|
||||
}
|
||||
|
||||
// DidConnect tracks the fact that the "one" node connected to the "other" node
|
||||
func (net *Network) DidConnect(one, other discover.NodeID) error {
|
||||
func (net *Network) DidConnect(one, other enode.ID) error {
|
||||
net.lock.Lock()
|
||||
defer net.lock.Unlock()
|
||||
conn, err := net.getOrCreateConn(one, other)
|
||||
@ -320,7 +320,7 @@ func (net *Network) DidConnect(one, other discover.NodeID) error {
|
||||
|
||||
// DidDisconnect tracks the fact that the "one" node disconnected from the
|
||||
// "other" node
|
||||
func (net *Network) DidDisconnect(one, other discover.NodeID) error {
|
||||
func (net *Network) DidDisconnect(one, other enode.ID) error {
|
||||
net.lock.Lock()
|
||||
defer net.lock.Unlock()
|
||||
conn := net.getConn(one, other)
|
||||
@ -337,7 +337,7 @@ func (net *Network) DidDisconnect(one, other discover.NodeID) error {
|
||||
}
|
||||
|
||||
// DidSend tracks the fact that "sender" sent a message to "receiver"
|
||||
func (net *Network) DidSend(sender, receiver discover.NodeID, proto string, code uint64) error {
|
||||
func (net *Network) DidSend(sender, receiver enode.ID, proto string, code uint64) error {
|
||||
msg := &Msg{
|
||||
One: sender,
|
||||
Other: receiver,
|
||||
@ -350,7 +350,7 @@ func (net *Network) DidSend(sender, receiver discover.NodeID, proto string, code
|
||||
}
|
||||
|
||||
// DidReceive tracks the fact that "receiver" received a message from "sender"
|
||||
func (net *Network) DidReceive(sender, receiver discover.NodeID, proto string, code uint64) error {
|
||||
func (net *Network) DidReceive(sender, receiver enode.ID, proto string, code uint64) error {
|
||||
msg := &Msg{
|
||||
One: sender,
|
||||
Other: receiver,
|
||||
@ -364,7 +364,7 @@ func (net *Network) DidReceive(sender, receiver discover.NodeID, proto string, c
|
||||
|
||||
// GetNode gets the node with the given ID, returning nil if the node does not
|
||||
// exist
|
||||
func (net *Network) GetNode(id discover.NodeID) *Node {
|
||||
func (net *Network) GetNode(id enode.ID) *Node {
|
||||
net.lock.Lock()
|
||||
defer net.lock.Unlock()
|
||||
return net.getNode(id)
|
||||
@ -387,7 +387,7 @@ func (net *Network) GetNodes() (nodes []*Node) {
|
||||
return nodes
|
||||
}
|
||||
|
||||
func (net *Network) getNode(id discover.NodeID) *Node {
|
||||
func (net *Network) getNode(id enode.ID) *Node {
|
||||
i, found := net.nodeMap[id]
|
||||
if !found {
|
||||
return nil
|
||||
@ -406,7 +406,7 @@ func (net *Network) getNodeByName(name string) *Node {
|
||||
|
||||
// GetConn returns the connection which exists between "one" and "other"
|
||||
// regardless of which node initiated the connection
|
||||
func (net *Network) GetConn(oneID, otherID discover.NodeID) *Conn {
|
||||
func (net *Network) GetConn(oneID, otherID enode.ID) *Conn {
|
||||
net.lock.Lock()
|
||||
defer net.lock.Unlock()
|
||||
return net.getConn(oneID, otherID)
|
||||
@ -414,13 +414,13 @@ func (net *Network) GetConn(oneID, otherID discover.NodeID) *Conn {
|
||||
|
||||
// GetOrCreateConn is like GetConn but creates the connection if it doesn't
|
||||
// already exist
|
||||
func (net *Network) GetOrCreateConn(oneID, otherID discover.NodeID) (*Conn, error) {
|
||||
func (net *Network) GetOrCreateConn(oneID, otherID enode.ID) (*Conn, error) {
|
||||
net.lock.Lock()
|
||||
defer net.lock.Unlock()
|
||||
return net.getOrCreateConn(oneID, otherID)
|
||||
}
|
||||
|
||||
func (net *Network) getOrCreateConn(oneID, otherID discover.NodeID) (*Conn, error) {
|
||||
func (net *Network) getOrCreateConn(oneID, otherID enode.ID) (*Conn, error) {
|
||||
if conn := net.getConn(oneID, otherID); conn != nil {
|
||||
return conn, nil
|
||||
}
|
||||
@ -445,7 +445,7 @@ func (net *Network) getOrCreateConn(oneID, otherID discover.NodeID) (*Conn, erro
|
||||
return conn, nil
|
||||
}
|
||||
|
||||
func (net *Network) getConn(oneID, otherID discover.NodeID) *Conn {
|
||||
func (net *Network) getConn(oneID, otherID enode.ID) *Conn {
|
||||
label := ConnLabel(oneID, otherID)
|
||||
i, found := net.connMap[label]
|
||||
if !found {
|
||||
@ -462,7 +462,7 @@ func (net *Network) getConn(oneID, otherID discover.NodeID) *Conn {
|
||||
// it also checks whether there has been recent attempt to connect the peers
|
||||
// this is cheating as the simulation is used as an oracle and know about
|
||||
// remote peers attempt to connect to a node which will then not initiate the connection
|
||||
func (net *Network) InitConn(oneID, otherID discover.NodeID) (*Conn, error) {
|
||||
func (net *Network) InitConn(oneID, otherID enode.ID) (*Conn, error) {
|
||||
net.lock.Lock()
|
||||
defer net.lock.Unlock()
|
||||
if oneID == otherID {
|
||||
@ -508,7 +508,7 @@ func (net *Network) Reset() {
|
||||
|
||||
//re-initialize the maps
|
||||
net.connMap = make(map[string]int)
|
||||
net.nodeMap = make(map[discover.NodeID]int)
|
||||
net.nodeMap = make(map[enode.ID]int)
|
||||
|
||||
net.Nodes = nil
|
||||
net.Conns = nil
|
||||
@ -527,7 +527,7 @@ type Node struct {
|
||||
}
|
||||
|
||||
// ID returns the ID of the node
|
||||
func (n *Node) ID() discover.NodeID {
|
||||
func (n *Node) ID() enode.ID {
|
||||
return n.Config.ID
|
||||
}
|
||||
|
||||
@ -564,10 +564,10 @@ func (n *Node) MarshalJSON() ([]byte, error) {
|
||||
// Conn represents a connection between two nodes in the network
|
||||
type Conn struct {
|
||||
// One is the node which initiated the connection
|
||||
One discover.NodeID `json:"one"`
|
||||
One enode.ID `json:"one"`
|
||||
|
||||
// Other is the node which the connection was made to
|
||||
Other discover.NodeID `json:"other"`
|
||||
Other enode.ID `json:"other"`
|
||||
|
||||
// Up tracks whether or not the connection is active
|
||||
Up bool `json:"up"`
|
||||
@ -596,11 +596,11 @@ func (c *Conn) String() string {
|
||||
|
||||
// Msg represents a p2p message sent between two nodes in the network
|
||||
type Msg struct {
|
||||
One discover.NodeID `json:"one"`
|
||||
Other discover.NodeID `json:"other"`
|
||||
Protocol string `json:"protocol"`
|
||||
Code uint64 `json:"code"`
|
||||
Received bool `json:"received"`
|
||||
One enode.ID `json:"one"`
|
||||
Other enode.ID `json:"other"`
|
||||
Protocol string `json:"protocol"`
|
||||
Code uint64 `json:"code"`
|
||||
Received bool `json:"received"`
|
||||
}
|
||||
|
||||
// String returns a log-friendly string
|
||||
@ -611,8 +611,8 @@ func (m *Msg) String() string {
|
||||
// ConnLabel generates a deterministic string which represents a connection
|
||||
// between two nodes, used to compare if two connections are between the same
|
||||
// nodes
|
||||
func ConnLabel(source, target discover.NodeID) string {
|
||||
var first, second discover.NodeID
|
||||
func ConnLabel(source, target enode.ID) string {
|
||||
var first, second enode.ID
|
||||
if bytes.Compare(source.Bytes(), target.Bytes()) > 0 {
|
||||
first = target
|
||||
second = source
|
||||
|
@ -22,7 +22,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/p2p/discover"
|
||||
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||
"github.com/ethereum/go-ethereum/p2p/simulations/adapters"
|
||||
)
|
||||
|
||||
@ -39,7 +39,7 @@ func TestNetworkSimulation(t *testing.T) {
|
||||
})
|
||||
defer network.Shutdown()
|
||||
nodeCount := 20
|
||||
ids := make([]discover.NodeID, nodeCount)
|
||||
ids := make([]enode.ID, nodeCount)
|
||||
for i := 0; i < nodeCount; i++ {
|
||||
conf := adapters.RandomNodeConfig()
|
||||
node, err := network.NewNodeWithConfig(conf)
|
||||
@ -64,7 +64,7 @@ func TestNetworkSimulation(t *testing.T) {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
check := func(ctx context.Context, id discover.NodeID) (bool, error) {
|
||||
check := func(ctx context.Context, id enode.ID) (bool, error) {
|
||||
// check we haven't run out of time
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
@ -102,7 +102,7 @@ func TestNetworkSimulation(t *testing.T) {
|
||||
defer cancel()
|
||||
|
||||
// trigger a check every 100ms
|
||||
trigger := make(chan discover.NodeID)
|
||||
trigger := make(chan enode.ID)
|
||||
go triggerChecks(ctx, ids, trigger, 100*time.Millisecond)
|
||||
|
||||
result := NewSimulation(network).Run(ctx, &Step{
|
||||
@ -140,7 +140,7 @@ func TestNetworkSimulation(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func triggerChecks(ctx context.Context, ids []discover.NodeID, trigger chan discover.NodeID, interval time.Duration) {
|
||||
func triggerChecks(ctx context.Context, ids []enode.ID, trigger chan enode.ID, interval time.Duration) {
|
||||
tick := time.NewTicker(interval)
|
||||
defer tick.Stop()
|
||||
for {
|
||||
|
@ -20,7 +20,7 @@ import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/p2p/discover"
|
||||
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||
)
|
||||
|
||||
// Simulation provides a framework for running actions in a simulated network
|
||||
@ -55,7 +55,7 @@ func (s *Simulation) Run(ctx context.Context, step *Step) (result *StepResult) {
|
||||
}
|
||||
|
||||
// wait for all node expectations to either pass, error or timeout
|
||||
nodes := make(map[discover.NodeID]struct{}, len(step.Expect.Nodes))
|
||||
nodes := make(map[enode.ID]struct{}, len(step.Expect.Nodes))
|
||||
for _, id := range step.Expect.Nodes {
|
||||
nodes[id] = struct{}{}
|
||||
}
|
||||
@ -119,7 +119,7 @@ type Step struct {
|
||||
|
||||
// Trigger is a channel which receives node ids and triggers an
|
||||
// expectation check for that node
|
||||
Trigger chan discover.NodeID
|
||||
Trigger chan enode.ID
|
||||
|
||||
// Expect is the expectation to wait for when performing this step
|
||||
Expect *Expectation
|
||||
@ -127,15 +127,15 @@ type Step struct {
|
||||
|
||||
type Expectation struct {
|
||||
// Nodes is a list of nodes to check
|
||||
Nodes []discover.NodeID
|
||||
Nodes []enode.ID
|
||||
|
||||
// Check checks whether a given node meets the expectation
|
||||
Check func(context.Context, discover.NodeID) (bool, error)
|
||||
Check func(context.Context, enode.ID) (bool, error)
|
||||
}
|
||||
|
||||
func newStepResult() *StepResult {
|
||||
return &StepResult{
|
||||
Passes: make(map[discover.NodeID]time.Time),
|
||||
Passes: make(map[enode.ID]time.Time),
|
||||
}
|
||||
}
|
||||
|
||||
@ -150,7 +150,7 @@ type StepResult struct {
|
||||
FinishedAt time.Time
|
||||
|
||||
// Passes are the timestamps of the successful node expectations
|
||||
Passes map[discover.NodeID]time.Time
|
||||
Passes map[enode.ID]time.Time
|
||||
|
||||
// NetworkEvents are the network events which occurred during the step
|
||||
NetworkEvents []*Event
|
||||
|
Reference in New Issue
Block a user