swarm/api, swarm/network, p2p/simulations: Prerequisites for handshake remove

This commit is contained in:
lash 2019-03-12 23:32:31 +01:00
parent b87a68407b
commit 3d931cccad
5 changed files with 153 additions and 7 deletions

View file

@ -28,6 +28,7 @@ import (
"github.com/ethereum/go-ethereum/node"
"github.com/ethereum/go-ethereum/p2p"
"github.com/ethereum/go-ethereum/p2p/enode"
"github.com/ethereum/go-ethereum/p2p/enr"
"github.com/ethereum/go-ethereum/p2p/simulations/pipes"
"github.com/ethereum/go-ethereum/rpc"
)
@ -87,6 +88,23 @@ func (s *SimAdapter) NewNode(config *NodeConfig) (Node, error) {
}
}
// dialer in simulations based on ENR records
// doesn't work unless we explicitly set localhost record
ip := enr.IP(net.IPv4(127, 0, 0, 1))
config.Record.Set(&ip)
tcpPort := enr.TCP(0)
config.Record.Set(&tcpPort)
err := enode.SignV4(&config.Record, config.PrivateKey)
if err != nil {
return nil, fmt.Errorf("unable to generate ENR: %v", err)
}
nod, err := enode.New(enode.V4ID{}, &config.Record)
if err != nil {
return nil, fmt.Errorf("unable to create enode: %v", err)
}
config.node = nod
n, err := node.New(&node.Config{
P2P: p2p.Config{
PrivateKey: config.PrivateKey,

View file

@ -30,6 +30,7 @@ import (
"github.com/ethereum/go-ethereum/node"
"github.com/ethereum/go-ethereum/p2p"
"github.com/ethereum/go-ethereum/p2p/enode"
"github.com/ethereum/go-ethereum/p2p/enr"
"github.com/ethereum/go-ethereum/rpc"
)
@ -99,6 +100,12 @@ type NodeConfig struct {
// services registered by calling the RegisterService function)
Services []string
// Enode
node *enode.Node
// ENR Record with entries to overwrite
Record enr.Record
// function to sanction or prevent suggesting a peer
Reachable func(id enode.ID) bool
@ -168,26 +175,27 @@ func (n *NodeConfig) UnmarshalJSON(data []byte) error {
// 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))
return n.node
}
// RandomNodeConfig returns node configuration with a randomly generated ID and
// PrivateKey
func RandomNodeConfig() *NodeConfig {
key, err := crypto.GenerateKey()
prvkey, err := crypto.GenerateKey()
if err != nil {
panic("unable to generate key")
}
id := enode.PubkeyToIDV4(&key.PublicKey)
port, err := assignTCPPort()
if err != nil {
panic("unable to assign tcp port")
}
enodId := enode.PubkeyToIDV4(&prvkey.PublicKey)
return &NodeConfig{
ID: id,
Name: fmt.Sprintf("node_%s", id.String()),
PrivateKey: key,
PrivateKey: prvkey,
ID: enodId,
Name: fmt.Sprintf("node_%s", enodId.String()),
Port: port,
EnableMsgEvents: true,
}

View file

@ -24,6 +24,7 @@ import (
"time"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/contracts/ens"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/node"
@ -117,7 +118,8 @@ func (c *Config) Init(prvKey *ecdsa.PrivateKey) {
pubkey := crypto.FromECDSAPub(&prvKey.PublicKey)
pubkeyhex := common.ToHex(pubkey)
keyhex := crypto.Keccak256Hash(pubkey).Hex()
//keyhex := crypto.Keccak256Hash(pubkey).Hex()
keyhex := hexutil.Encode(PrivateKeyToBzzKey(prvKey))
c.PublicKey = pubkeyhex
c.BzzKey = keyhex
@ -134,6 +136,11 @@ func (c *Config) Init(prvKey *ecdsa.PrivateKey) {
c.Pss = c.Pss.WithPrivateKey(c.privateKey)
}
func PrivateKeyToBzzKey(prvKey *ecdsa.PrivateKey) []byte {
pubkeyBytes := crypto.FromECDSAPub(&prvKey.PublicKey)
return crypto.Keccak256Hash(pubkeyBytes).Bytes()
}
func (c *Config) ShiftPrivateKey() (privKey *ecdsa.PrivateKey) {
if c.privateKey != nil {
privKey = c.privateKey

93
swarm/network/enr.go Normal file
View file

@ -0,0 +1,93 @@
package network
import (
"fmt"
"io"
"github.com/ethereum/go-ethereum/p2p"
"github.com/ethereum/go-ethereum/p2p/enode"
"github.com/ethereum/go-ethereum/p2p/protocols"
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/swarm/log"
)
// ENRAddrEntry is the entry type to store the bzz key in the enode
type ENRAddrEntry struct {
data []byte
}
func NewENRAddrEntry(addr []byte) *ENRAddrEntry {
return &ENRAddrEntry{
data: addr,
}
}
func (b ENRAddrEntry) Address() []byte {
return b.data
}
// ENRKey implements enr.Entry
func (b ENRAddrEntry) ENRKey() string {
return "bzzkey"
}
// EncodeRLP implements rlp.Encoder
func (b ENRAddrEntry) EncodeRLP(w io.Writer) error {
log.Debug("in encoderlp", "b", b, "p", fmt.Sprintf("%p", &b))
return rlp.Encode(w, &b.data)
}
// DecodeRLP implements rlp.Decoder
func (b *ENRAddrEntry) DecodeRLP(s *rlp.Stream) error {
byt, err := s.Bytes()
if err != nil {
return err
}
b.data = byt
log.Debug("in decoderlp", "b", b, "p", fmt.Sprintf("%p", &b))
return nil
}
type ENRLightNodeEntry bool
func (b ENRLightNodeEntry) ENRKey() string {
return "bzzlightnode"
}
type ENRBootNodeEntry bool
func (b ENRBootNodeEntry) ENRKey() string {
return "bzzbootnode"
}
func getENRBzzPeer(p *p2p.Peer, rw p2p.MsgReadWriter, spec *protocols.Spec) *BzzPeer {
var lightnode ENRLightNodeEntry
//var bootnode ENRBootNodeEntry
// retrieve the ENR Record data
record := p.Node().Record()
record.Load(&lightnode)
//record.Load(&bootnode)
// get the address; separate function as long as we need swarm/network:NewAddr() to call it
addr := getENRBzzAddr(p.Node())
// build the peer using the retrieved data
return &BzzPeer{
Peer: protocols.NewPeer(p, rw, spec),
LightNode: bool(lightnode),
BzzAddr: addr,
}
}
func getENRBzzAddr(nod *enode.Node) *BzzAddr {
var addr ENRAddrEntry
record := nod.Record()
record.Load(&addr)
return &BzzAddr{
OAddr: addr.data,
UAddr: []byte(nod.String()),
}
}

View file

@ -28,6 +28,8 @@ import (
"github.com/ethereum/go-ethereum/p2p/enode"
"github.com/ethereum/go-ethereum/p2p/simulations"
"github.com/ethereum/go-ethereum/p2p/simulations/adapters"
bzzapi "github.com/ethereum/go-ethereum/swarm/api"
"github.com/ethereum/go-ethereum/swarm/network"
)
// NodeIDs returns NodeIDs for all nodes in the network.
@ -96,10 +98,28 @@ func (s *Simulation) AddNode(opts ...AddNodeOption) (id enode.ID, err error) {
if len(conf.Services) == 0 {
conf.Services = s.serviceNames
}
// add ENR records to the underlying node
// most importantly the bzz overlay address
//
// for now we have no way of setting bootnodes or lightnodes in sims
// so we just set them as false
// they should perhaps be possible to override them with AddNodeOption
bzzKey := bzzapi.PrivateKeyToBzzKey(conf.PrivateKey)
bzzAddr := network.NewENRAddrEntry(bzzKey)
var lightnode network.ENRLightNodeEntry
var bootnode network.ENRBootNodeEntry
conf.Record.Set(bzzAddr)
conf.Record.Set(&lightnode)
conf.Record.Set(&bootnode)
// Add the bzz address to the node config
node, err := s.Net.NewNodeWithConfig(conf)
if err != nil {
return id, err
}
return node.ID(), s.Net.Start(node.ID())
}