Skip to content
This repository was archived by the owner on Aug 2, 2021. It is now read-only.

Commit 8d38f02

Browse files
nolashnonsense
authored andcommitted
cmd/swarm, p2p, swarm: Enable ENR in binary/execadapter (#19309)
* cmd/swarm, p2p, swarm: Enable ENR in binary/execadapter * cmd/p2p/swarm: Remove comments + config.Enode nomarshal * p2p/simulations: Remove superfluous error check * p2p/simulation: Move init enode comment * swarm/api: Check error in config test * swarm, p2p/simulations, cmd/swarm: Use nodekey in binary record sign * cmd/swarm: Make nodekey available for swarm api config
1 parent 3292c41 commit 8d38f02

File tree

12 files changed

+165
-55
lines changed

12 files changed

+165
-55
lines changed

cmd/swarm/config.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,18 +123,22 @@ func buildConfig(ctx *cli.Context) (config *bzzapi.Config, err error) {
123123
}
124124

125125
//finally, after the configuration build phase is finished, initialize
126-
func initSwarmNode(config *bzzapi.Config, stack *node.Node, ctx *cli.Context) {
126+
func initSwarmNode(config *bzzapi.Config, stack *node.Node, ctx *cli.Context, nodeconfig *node.Config) error {
127127
//at this point, all vars should be set in the Config
128128
//get the account for the provided swarm account
129129
prvkey := getAccount(config.BzzAccount, ctx, stack)
130130
//set the resolved config path (geth --datadir)
131131
config.Path = expandPath(stack.InstanceDir())
132132
//finally, initialize the configuration
133-
config.Init(prvkey)
133+
err := config.Init(prvkey, nodeconfig.NodeKey())
134+
if err != nil {
135+
return err
136+
}
134137
//configuration phase completed here
135138
log.Debug("Starting Swarm with the following parameters:")
136139
//after having created the config, print it to screen
137140
log.Debug(printConfig(config))
141+
return nil
138142
}
139143

140144
//configFileOverride overrides the current config with the config file, if a config file has been provided

cmd/swarm/main.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,10 @@ func bzzd(ctx *cli.Context) error {
298298

299299
//a few steps need to be done after the config phase is completed,
300300
//due to overriding behavior
301-
initSwarmNode(bzzconfig, stack, ctx)
301+
err = initSwarmNode(bzzconfig, stack, ctx, &cfg)
302+
if err != nil {
303+
return err
304+
}
302305
//register BZZ as node.Service in the ethereum node
303306
registerBzzService(bzzconfig, stack)
304307
//start the node

p2p/simulations/adapters/exec.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,10 @@ func (e *ExecAdapter) NewNode(config *NodeConfig) (Node, error) {
9292
return nil, fmt.Errorf("error creating node directory: %s", err)
9393
}
9494

95+
err := config.initDummyEnode()
96+
if err != nil {
97+
return nil, err
98+
}
9599
// generate the config
96100
conf := &execNodeConfig{
97101
Stack: node.DefaultConfig,
@@ -403,6 +407,14 @@ func startExecNodeStack() (*node.Node, error) {
403407
if err := json.Unmarshal([]byte(confEnv), &conf); err != nil {
404408
return nil, fmt.Errorf("error decoding %s: %v", envNodeConfig, err)
405409
}
410+
// TODO verify that ListenAddr will contain the correct tcp addr
411+
// if we should start using exec adapters with other host than local
412+
nodeTcpConn, err := net.ResolveTCPAddr("tcp", conf.Stack.P2P.ListenAddr)
413+
if err != nil {
414+
conf.Node.initDummyEnode()
415+
} else {
416+
conf.Node.initEnode(nodeTcpConn.IP, nodeTcpConn.Port, nodeTcpConn.Port)
417+
}
406418
conf.Stack.P2P.PrivateKey = conf.Node.PrivateKey
407419
conf.Stack.Logger = log.New("node.id", conf.Node.ID.String())
408420

p2p/simulations/adapters/inproc.go

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ import (
2828
"github.com/ethereum/go-ethereum/node"
2929
"github.com/ethereum/go-ethereum/p2p"
3030
"github.com/ethereum/go-ethereum/p2p/enode"
31-
"github.com/ethereum/go-ethereum/p2p/enr"
3231
"github.com/ethereum/go-ethereum/p2p/simulations/pipes"
3332
"github.com/ethereum/go-ethereum/rpc"
3433
)
@@ -93,23 +92,10 @@ func (s *SimAdapter) NewNode(config *NodeConfig) (Node, error) {
9392
}
9493
}
9594

96-
// dialer in simulations based on ENR records
97-
// doesn't work unless we explicitly set localhost record
98-
ip := enr.IP(net.IPv4(127, 0, 0, 1))
99-
config.Record.Set(&ip)
100-
tcpPort := enr.TCP(0)
101-
config.Record.Set(&tcpPort)
102-
103-
err := enode.SignV4(&config.Record, config.PrivateKey)
104-
if err != nil {
105-
return nil, fmt.Errorf("unable to generate ENR: %v", err)
106-
}
107-
nod, err := enode.New(enode.V4ID{}, &config.Record)
95+
err := config.initDummyEnode()
10896
if err != nil {
109-
return nil, fmt.Errorf("unable to create enode: %v", err)
97+
return nil, err
11098
}
111-
log.Trace("simnode new", "record", config.Record)
112-
config.node = nod
11399

114100
n, err := node.New(&node.Config{
115101
P2P: p2p.Config{

p2p/simulations/adapters/types.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import (
2727

2828
"github.com/docker/docker/pkg/reexec"
2929
"github.com/ethereum/go-ethereum/crypto"
30+
"github.com/ethereum/go-ethereum/log"
3031
"github.com/ethereum/go-ethereum/node"
3132
"github.com/ethereum/go-ethereum/p2p"
3233
"github.com/ethereum/go-ethereum/p2p/enode"
@@ -262,3 +263,30 @@ func RegisterServices(services Services) {
262263
os.Exit(0)
263264
}
264265
}
266+
267+
// adds the host part to the configuration's ENR, signs it
268+
// creates and the corresponding enode object to the configuration
269+
func (n *NodeConfig) initEnode(ip net.IP, tcpport int, udpport int) error {
270+
enrIp := enr.IP(ip)
271+
n.Record.Set(&enrIp)
272+
enrTcpPort := enr.TCP(tcpport)
273+
n.Record.Set(&enrTcpPort)
274+
enrUdpPort := enr.UDP(tcpport)
275+
n.Record.Set(&enrUdpPort)
276+
277+
err := enode.SignV4(&n.Record, n.PrivateKey)
278+
if err != nil {
279+
return fmt.Errorf("unable to generate ENR: %v", err)
280+
}
281+
nod, err := enode.New(enode.V4ID{}, &n.Record)
282+
if err != nil {
283+
return fmt.Errorf("unable to create enode: %v", err)
284+
}
285+
log.Trace("simnode new", "record", n.Record)
286+
n.node = nod
287+
return nil
288+
}
289+
290+
func (n *NodeConfig) initDummyEnode() error {
291+
return n.initEnode(net.IPv4(127, 0, 0, 1), 0, 0)
292+
}

swarm/api/config.go

Lines changed: 44 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ import (
2929
"github.com/ethereum/go-ethereum/crypto"
3030
"github.com/ethereum/go-ethereum/node"
3131
"github.com/ethereum/go-ethereum/p2p/enode"
32-
"github.com/ethereum/go-ethereum/swarm/log"
3332
"github.com/ethereum/go-ethereum/swarm/network"
3433
"github.com/ethereum/go-ethereum/swarm/pss"
3534
"github.com/ethereum/go-ethereum/swarm/services/swap"
@@ -58,7 +57,7 @@ type Config struct {
5857
Port string
5958
PublicKey string
6059
BzzKey string
61-
NodeID string
60+
Enode *enode.Node `toml:"-"`
6261
NetworkID uint64
6362
SwapEnabled bool
6463
SyncEnabled bool
@@ -104,33 +103,38 @@ func NewConfig() (c *Config) {
104103

105104
//some config params need to be initialized after the complete
106105
//config building phase is completed (e.g. due to overriding flags)
107-
func (c *Config) Init(prvKey *ecdsa.PrivateKey) {
106+
func (c *Config) Init(prvKey *ecdsa.PrivateKey, nodeKey *ecdsa.PrivateKey) error {
108107

109-
address := crypto.PubkeyToAddress(prvKey.PublicKey)
110-
c.Path = filepath.Join(c.Path, "bzz-"+common.Bytes2Hex(address.Bytes()))
111-
err := os.MkdirAll(c.Path, os.ModePerm)
108+
// create swarm dir and record key
109+
err := c.createAndSetPath(c.Path, prvKey)
112110
if err != nil {
113-
log.Error(fmt.Sprintf("Error creating root swarm data directory: %v", err))
114-
return
111+
return fmt.Errorf("Error creating root swarm data directory: %v", err)
112+
}
113+
c.setKey(prvKey)
114+
115+
// create the new enode record
116+
// signed with the ephemeral node key
117+
enodeParams := &network.EnodeParams{
118+
PrivateKey: prvKey,
119+
EnodeKey: nodeKey,
120+
Lightnode: c.LightNodeEnabled,
121+
Bootnode: c.BootnodeMode,
122+
}
123+
c.Enode, err = network.NewEnode(enodeParams)
124+
if err != nil {
125+
return fmt.Errorf("Error creating enode: %v", err)
115126
}
116127

117-
pubkey := crypto.FromECDSAPub(&prvKey.PublicKey)
118-
pubkeyhex := common.ToHex(pubkey)
119-
keyhex := hexutil.Encode(network.PrivateKeyToBzzKey(prvKey))
120-
121-
c.PublicKey = pubkeyhex
122-
c.BzzKey = keyhex
123-
c.NodeID = enode.PubkeyToIDV4(&prvKey.PublicKey).String()
124-
128+
// initialize components that depend on the swarm instance's private key
125129
if c.SwapEnabled {
126130
c.Swap.Init(c.Contract, prvKey)
127131
}
128132

129-
c.privateKey = prvKey
130133
c.LocalStoreParams.Init(c.Path)
131-
c.LocalStoreParams.BaseKey = common.FromHex(keyhex)
134+
c.LocalStoreParams.BaseKey = common.FromHex(c.BzzKey)
132135

133136
c.Pss = c.Pss.WithPrivateKey(c.privateKey)
137+
return nil
134138
}
135139

136140
func (c *Config) ShiftPrivateKey() (privKey *ecdsa.PrivateKey) {
@@ -140,3 +144,25 @@ func (c *Config) ShiftPrivateKey() (privKey *ecdsa.PrivateKey) {
140144
}
141145
return privKey
142146
}
147+
148+
func (c *Config) setKey(prvKey *ecdsa.PrivateKey) {
149+
bzzkeybytes := network.PrivateKeyToBzzKey(prvKey)
150+
pubkey := crypto.FromECDSAPub(&prvKey.PublicKey)
151+
pubkeyhex := hexutil.Encode(pubkey)
152+
keyhex := hexutil.Encode(bzzkeybytes)
153+
154+
c.privateKey = prvKey
155+
c.PublicKey = pubkeyhex
156+
c.BzzKey = keyhex
157+
}
158+
159+
func (c *Config) createAndSetPath(datadirPath string, prvKey *ecdsa.PrivateKey) error {
160+
address := crypto.PubkeyToAddress(prvKey.PublicKey)
161+
bzzdirPath := filepath.Join(datadirPath, "bzz-"+common.Bytes2Hex(address.Bytes()))
162+
err := os.MkdirAll(bzzdirPath, os.ModePerm)
163+
if err != nil {
164+
return err
165+
}
166+
c.Path = bzzdirPath
167+
return nil
168+
}

swarm/api/config_test.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,16 @@ import (
2727
func TestConfig(t *testing.T) {
2828

2929
var hexprvkey = "65138b2aa745041b372153550584587da326ab440576b2a1191dd95cee30039c"
30+
var hexnodekey = "75138b2aa745041b372153550584587da326ab440576b2a1191dd95cee30039c"
3031

3132
prvkey, err := crypto.HexToECDSA(hexprvkey)
3233
if err != nil {
3334
t.Fatalf("failed to load private key: %v", err)
3435
}
36+
nodekey, err := crypto.HexToECDSA(hexnodekey)
37+
if err != nil {
38+
t.Fatalf("failed to load private key: %v", err)
39+
}
3540

3641
one := NewConfig()
3742
two := NewConfig()
@@ -41,7 +46,10 @@ func TestConfig(t *testing.T) {
4146
t.Fatal("Two default configs are not equal")
4247
}
4348

44-
one.Init(prvkey)
49+
err = one.Init(prvkey, nodekey)
50+
if err != nil {
51+
t.Fatal(err)
52+
}
4553

4654
//the init function should set the following fields
4755
if one.BzzKey == "" {

swarm/network/network.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77

88
"github.com/ethereum/go-ethereum/crypto"
99
"github.com/ethereum/go-ethereum/p2p/enode"
10+
"github.com/ethereum/go-ethereum/p2p/enr"
1011
)
1112

1213
// BzzAddr implements the PeerAddr interface
@@ -68,3 +69,37 @@ func PrivateKeyToBzzKey(prvKey *ecdsa.PrivateKey) []byte {
6869
pubkeyBytes := crypto.FromECDSAPub(&prvKey.PublicKey)
6970
return crypto.Keccak256Hash(pubkeyBytes).Bytes()
7071
}
72+
73+
type EnodeParams struct {
74+
PrivateKey *ecdsa.PrivateKey
75+
EnodeKey *ecdsa.PrivateKey
76+
Lightnode bool
77+
Bootnode bool
78+
}
79+
80+
func NewEnodeRecord(params *EnodeParams) (*enr.Record, error) {
81+
82+
if params.PrivateKey == nil {
83+
return nil, fmt.Errorf("all param private keys must be defined")
84+
}
85+
86+
bzzkeybytes := PrivateKeyToBzzKey(params.PrivateKey)
87+
88+
var record enr.Record
89+
record.Set(NewENRAddrEntry(bzzkeybytes))
90+
record.Set(ENRLightNodeEntry(params.Lightnode))
91+
record.Set(ENRBootNodeEntry(params.Bootnode))
92+
return &record, nil
93+
}
94+
95+
func NewEnode(params *EnodeParams) (*enode.Node, error) {
96+
record, err := NewEnodeRecord(params)
97+
if err != nil {
98+
return nil, err
99+
}
100+
err = enode.SignV4(record, params.EnodeKey)
101+
if err != nil {
102+
return nil, fmt.Errorf("ENR create fail: %v", err)
103+
}
104+
return enode.New(enode.V4ID{}, record)
105+
}

swarm/network/simulation/node.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -102,16 +102,16 @@ func (s *Simulation) AddNode(opts ...AddNodeOption) (id enode.ID, err error) {
102102
// most importantly the bzz overlay address
103103
//
104104
// for now we have no way of setting bootnodes or lightnodes in sims
105-
// so we just set them as false
105+
// so we just let them be set to false
106106
// they should perhaps be possible to override them with AddNodeOption
107-
bzzKey := network.PrivateKeyToBzzKey(conf.PrivateKey)
108-
bzzAddr := network.NewENRAddrEntry(bzzKey)
109-
110-
var lightnode network.ENRLightNodeEntry
111-
var bootnode network.ENRBootNodeEntry
112-
conf.Record.Set(bzzAddr)
113-
conf.Record.Set(&lightnode)
114-
conf.Record.Set(&bootnode)
107+
enodeParams := &network.EnodeParams{
108+
PrivateKey: conf.PrivateKey,
109+
}
110+
record, err := network.NewEnodeRecord(enodeParams)
111+
if err != nil {
112+
return enode.ID{}, err
113+
}
114+
conf.Record = *record
115115

116116
// Add the bzz address to the node config
117117
node, err := s.Net.NewNodeWithConfig(conf)

swarm/network_test.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -311,8 +311,12 @@ func testSwarmNetwork(t *testing.T, o *testSwarmNetworkOptions, steps ...testSwa
311311
if err != nil {
312312
return nil, cleanup, err
313313
}
314+
nodekey, err := crypto.GenerateKey()
315+
if err != nil {
316+
return nil, cleanup, err
317+
}
314318

315-
config.Init(privkey)
319+
config.Init(privkey, nodekey)
316320
config.DeliverySkipCheck = o.SkipCheck
317321
config.Port = ""
318322

0 commit comments

Comments
 (0)