Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmd/geth: enable DNS discovery by default #20660

Merged
merged 10 commits into from
Feb 13, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions cmd/geth/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ var (
utils.NetrestrictFlag,
utils.NodeKeyFileFlag,
utils.NodeKeyHexFlag,
utils.DNSDiscoveryFlag,
utils.DeveloperFlag,
utils.DeveloperPeriodFlag,
utils.TestnetFlag,
Expand Down
1 change: 1 addition & 0 deletions cmd/geth/usage.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ var AppHelpFlagGroups = []flagGroup{
utils.BootnodesFlag,
utils.BootnodesV4Flag,
utils.BootnodesV5Flag,
utils.DNSDiscoveryFlag,
utils.ListenPortFlag,
utils.MaxPeersFlag,
utils.MaxPendingPeersFlag,
Expand Down
36 changes: 32 additions & 4 deletions cmd/utils/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -658,6 +658,10 @@ var (
Name: "netrestrict",
Usage: "Restricts network communication to the given IP networks (CIDR masks)",
}
DNSDiscoveryFlag = cli.StringFlag{
Name: "discovery.dns",
Usage: "Sets DNS discovery entry points (use \"\" to disable DNS)",
}

// ATM the url is left to the user and deployment to
JSpathFlag = cli.StringFlag{
Expand Down Expand Up @@ -811,9 +815,9 @@ func setBootstrapNodes(ctx *cli.Context, cfg *p2p.Config) {
switch {
case ctx.GlobalIsSet(BootnodesFlag.Name) || ctx.GlobalIsSet(BootnodesV4Flag.Name):
if ctx.GlobalIsSet(BootnodesV4Flag.Name) {
urls = strings.Split(ctx.GlobalString(BootnodesV4Flag.Name), ",")
urls = splitAndTrim(ctx.GlobalString(BootnodesV4Flag.Name))
} else {
urls = strings.Split(ctx.GlobalString(BootnodesFlag.Name), ",")
urls = splitAndTrim(ctx.GlobalString(BootnodesFlag.Name))
}
case ctx.GlobalBool(TestnetFlag.Name):
urls = params.TestnetBootnodes
Expand Down Expand Up @@ -845,9 +849,9 @@ func setBootstrapNodesV5(ctx *cli.Context, cfg *p2p.Config) {
switch {
case ctx.GlobalIsSet(BootnodesFlag.Name) || ctx.GlobalIsSet(BootnodesV5Flag.Name):
if ctx.GlobalIsSet(BootnodesV5Flag.Name) {
urls = strings.Split(ctx.GlobalString(BootnodesV5Flag.Name), ",")
urls = splitAndTrim(ctx.GlobalString(BootnodesV5Flag.Name))
} else {
urls = strings.Split(ctx.GlobalString(BootnodesFlag.Name), ",")
urls = splitAndTrim(ctx.GlobalString(BootnodesFlag.Name))
}
case ctx.GlobalBool(RinkebyFlag.Name):
urls = params.RinkebyBootnodes
Expand Down Expand Up @@ -1477,6 +1481,14 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *eth.Config) {
if ctx.GlobalIsSet(RPCGlobalGasCap.Name) {
cfg.RPCGasCap = new(big.Int).SetUint64(ctx.GlobalUint64(RPCGlobalGasCap.Name))
}
if ctx.GlobalIsSet(DNSDiscoveryFlag.Name) {
urls := ctx.GlobalString(DNSDiscoveryFlag.Name)
if urls == "" {
cfg.DiscoveryURLs = []string{}
} else {
cfg.DiscoveryURLs = splitAndTrim(urls)
}
}

// Override any default configs for hard coded networks.
switch {
Expand All @@ -1485,16 +1497,19 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *eth.Config) {
cfg.NetworkId = 3
}
cfg.Genesis = core.DefaultTestnetGenesisBlock()
setDNSDiscoveryDefaults(cfg, params.KnownDNSNetworks[params.TestnetGenesisHash])
case ctx.GlobalBool(RinkebyFlag.Name):
if !ctx.GlobalIsSet(NetworkIdFlag.Name) {
cfg.NetworkId = 4
}
cfg.Genesis = core.DefaultRinkebyGenesisBlock()
setDNSDiscoveryDefaults(cfg, params.KnownDNSNetworks[params.RinkebyGenesisHash])
case ctx.GlobalBool(GoerliFlag.Name):
if !ctx.GlobalIsSet(NetworkIdFlag.Name) {
cfg.NetworkId = 5
}
cfg.Genesis = core.DefaultGoerliGenesisBlock()
setDNSDiscoveryDefaults(cfg, params.KnownDNSNetworks[params.GoerliGenesisHash])
case ctx.GlobalBool(DeveloperFlag.Name):
if !ctx.GlobalIsSet(NetworkIdFlag.Name) {
cfg.NetworkId = 1337
Expand All @@ -1521,7 +1536,20 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *eth.Config) {
if !ctx.GlobalIsSet(MinerGasPriceFlag.Name) && !ctx.GlobalIsSet(MinerLegacyGasPriceFlag.Name) {
cfg.Miner.GasPrice = big.NewInt(1)
}
default:
if cfg.NetworkId == 1 {
setDNSDiscoveryDefaults(cfg, params.KnownDNSNetworks[params.MainnetGenesisHash])
}
}
}

// setDNSDiscoveryDefaults configures DNS discovery with the given URL if
// no URLs are set.
func setDNSDiscoveryDefaults(cfg *eth.Config, url string) {
if cfg.DiscoveryURLs != nil {
return
}
cfg.DiscoveryURLs = []string{url}
}

// RegisterEthService adds an Ethereum client to the stack.
Expand Down
8 changes: 8 additions & 0 deletions eth/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ import (
"github.com/ethereum/go-ethereum/miner"
"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/params"
"github.com/ethereum/go-ethereum/rlp"
Expand Down Expand Up @@ -74,6 +75,7 @@ type Ethereum struct {
blockchain *core.BlockChain
protocolManager *ProtocolManager
lesServer LesServer
dialCandiates enode.Iterator

// DB interfaces
chainDb ethdb.Database // Block chain database
Expand Down Expand Up @@ -220,6 +222,11 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
}
eth.APIBackend.gpo = gasprice.NewOracle(eth.APIBackend, gpoParams)

eth.dialCandiates, err = eth.setupDiscovery(&ctx.Config.P2P)
if err != nil {
return nil, err
}

return eth, nil
}

Expand Down Expand Up @@ -510,6 +517,7 @@ func (s *Ethereum) Protocols() []p2p.Protocol {
for i, vsn := range ProtocolVersions {
protos[i] = s.protocolManager.makeProtocol(vsn)
protos[i].Attributes = []enr.Entry{s.currentEthEntry()}
protos[i].DialCandidates = s.dialCandiates
}
if s.lesServer != nil {
protos = append(protos, s.lesServer.Protocols()...)
Expand Down
8 changes: 6 additions & 2 deletions eth/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,10 @@ type Config struct {
NetworkId uint64 // Network ID to use for selecting peers to connect to
SyncMode downloader.SyncMode

// This can be set to list of enrtree:// URLs which will be queried for
// for nodes to connect to.
DiscoveryURLs []string

NoPruning bool // Whether to disable pruning and flush everything to disk
NoPrefetch bool // Whether to disable prefetching and only load state on demand

Expand Down Expand Up @@ -156,8 +160,8 @@ type Config struct {
CheckpointOracle *params.CheckpointOracleConfig `toml:",omitempty"`

// Istanbul block override (TODO: remove after the fork)
OverrideIstanbul *big.Int
OverrideIstanbul *big.Int `toml:",omitempty"`

// MuirGlacier block override (TODO: remove after the fork)
OverrideMuirGlacier *big.Int
OverrideMuirGlacier *big.Int `toml:",omitempty"`
}
12 changes: 12 additions & 0 deletions eth/enr_entry.go → eth/discovery.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ package eth
import (
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/forkid"
"github.com/ethereum/go-ethereum/p2p"
"github.com/ethereum/go-ethereum/p2p/dnsdisc"
"github.com/ethereum/go-ethereum/p2p/enode"
"github.com/ethereum/go-ethereum/rlp"
)
Expand All @@ -37,6 +39,7 @@ func (e ethEntry) ENRKey() string {
return "eth"
}

// startEthEntryUpdate starts the ENR updater loop.
func (eth *Ethereum) startEthEntryUpdate(ln *enode.LocalNode) {
var newHead = make(chan core.ChainHeadEvent, 10)
sub := eth.blockchain.SubscribeChainHeadEvent(newHead)
Expand All @@ -59,3 +62,12 @@ func (eth *Ethereum) startEthEntryUpdate(ln *enode.LocalNode) {
func (eth *Ethereum) currentEthEntry() *ethEntry {
return &ethEntry{ForkID: forkid.NewID(eth.blockchain)}
}

// setupDiscovery creates the node discovery source for the eth protocol.
func (eth *Ethereum) setupDiscovery(cfg *p2p.Config) (enode.Iterator, error) {
if cfg.NoDiscovery || len(eth.config.DiscoveryURLs) == 0 {
return nil, nil
}
client := dnsdisc.NewClient(dnsdisc.Config{})
return client.NewIterator(eth.config.DiscoveryURLs...)
}
18 changes: 18 additions & 0 deletions eth/gen_config.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion node/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ func (n *Node) Start() error {
for _, constructor := range n.serviceFuncs {
// Create a new context for the particular service
ctx := &ServiceContext{
config: n.config,
Config: *n.config,
services: make(map[reflect.Type]Service),
EventMux: n.eventmux,
AccountManager: n.accman,
Expand Down
20 changes: 10 additions & 10 deletions node/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,20 +32,20 @@ import (
// the protocol stack, that is passed to all constructors to be optionally used;
// as well as utility methods to operate on the service environment.
type ServiceContext struct {
config *Config
services map[reflect.Type]Service // Index of the already constructed services
EventMux *event.TypeMux // Event multiplexer used for decoupled notifications
AccountManager *accounts.Manager // Account manager created by the node.
Config Config
EventMux *event.TypeMux // Event multiplexer used for decoupled notifications
AccountManager *accounts.Manager // Account manager created by the node.
}

// OpenDatabase opens an existing database with the given name (or creates one
// if no previous can be found) from within the node's data directory. If the
// node is an ephemeral one, a memory database is returned.
func (ctx *ServiceContext) OpenDatabase(name string, cache int, handles int, namespace string) (ethdb.Database, error) {
if ctx.config.DataDir == "" {
if ctx.Config.DataDir == "" {
return rawdb.NewMemoryDatabase(), nil
}
return rawdb.NewLevelDBDatabase(ctx.config.ResolvePath(name), cache, handles, namespace)
return rawdb.NewLevelDBDatabase(ctx.Config.ResolvePath(name), cache, handles, namespace)
}

// OpenDatabaseWithFreezer opens an existing database with the given name (or
Expand All @@ -54,16 +54,16 @@ func (ctx *ServiceContext) OpenDatabase(name string, cache int, handles int, nam
// database to immutable append-only files. If the node is an ephemeral one, a
// memory database is returned.
func (ctx *ServiceContext) OpenDatabaseWithFreezer(name string, cache int, handles int, freezer string, namespace string) (ethdb.Database, error) {
if ctx.config.DataDir == "" {
if ctx.Config.DataDir == "" {
return rawdb.NewMemoryDatabase(), nil
}
root := ctx.config.ResolvePath(name)
root := ctx.Config.ResolvePath(name)

switch {
case freezer == "":
freezer = filepath.Join(root, "ancient")
case !filepath.IsAbs(freezer):
freezer = ctx.config.ResolvePath(freezer)
freezer = ctx.Config.ResolvePath(freezer)
}
return rawdb.NewLevelDBDatabaseWithFreezer(root, cache, handles, freezer, namespace)
}
Expand All @@ -72,7 +72,7 @@ func (ctx *ServiceContext) OpenDatabaseWithFreezer(name string, cache int, handl
// and if the user actually uses persistent storage. It will return an empty string
// for emphemeral storage and the user's own input for absolute paths.
func (ctx *ServiceContext) ResolvePath(path string) string {
return ctx.config.ResolvePath(path)
return ctx.Config.ResolvePath(path)
}

// Service retrieves a currently running service registered of a specific type.
Expand All @@ -88,7 +88,7 @@ func (ctx *ServiceContext) Service(service interface{}) error {
// ExtRPCEnabled returns the indicator whether node enables the external
// RPC(http, ws or graphql).
func (ctx *ServiceContext) ExtRPCEnabled() bool {
return ctx.config.ExtRPCEnabled()
return ctx.Config.ExtRPCEnabled()
}

// ServiceConstructor is the function signature of the constructors needed to be
Expand Down
4 changes: 2 additions & 2 deletions node/service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ func TestContextDatabases(t *testing.T) {
t.Fatalf("non-created database already exists")
}
// Request the opening/creation of a database and ensure it persists to disk
ctx := &ServiceContext{config: &Config{Name: "unit-test", DataDir: dir}}
ctx := &ServiceContext{Config: Config{Name: "unit-test", DataDir: dir}}
db, err := ctx.OpenDatabase("persistent", 0, 0, "")
if err != nil {
t.Fatalf("failed to open persistent database: %v", err)
Expand All @@ -49,7 +49,7 @@ func TestContextDatabases(t *testing.T) {
t.Fatalf("persistent database doesn't exists: %v", err)
}
// Request th opening/creation of an ephemeral database and ensure it's not persisted
ctx = &ServiceContext{config: &Config{DataDir: ""}}
ctx = &ServiceContext{Config: Config{DataDir: ""}}
db, err = ctx.OpenDatabase("ephemeral", 0, 0, "")
if err != nil {
t.Fatalf("failed to open ephemeral database: %v", err)
Expand Down
13 changes: 13 additions & 0 deletions params/bootnodes.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

package params

import "github.com/ethereum/go-ethereum/common"

// MainnetBootnodes are the enode URLs of the P2P bootstrap nodes running on
// the main Ethereum network.
var MainnetBootnodes = []string{
Expand Down Expand Up @@ -69,3 +71,14 @@ var DiscoveryV5Bootnodes = []string{
"enode://1c7a64d76c0334b0418c004af2f67c50e36a3be60b5e4790bdac0439d21603469a85fad36f2473c9a80eb043ae60936df905fa28f1ff614c3e5dc34f15dcd2dc@40.118.3.223:30306",
"enode://85c85d7143ae8bb96924f2b54f1b3e70d8c4d367af305325d30a61385a432f247d2c75c45c6b4a60335060d072d7f5b35dd1d4c45f76941f62a4f83b6e75daaf@40.118.3.223:30307",
}

const dnsPrefix = "enrtree://AKA3AM6LPBYEUDMVNU3BSVQJ5AD45Y7YPOHJLEF6W26QOE4VTUDPE@"

// These DNS names provide bootstrap connectivity for public testnets and the mainnet.
// See https://github.com/ethereum/discv4-dns-lists for more information.
var KnownDNSNetworks = map[common.Hash]string{
MainnetGenesisHash: dnsPrefix + "all.mainnet.ethdisco.net",
TestnetGenesisHash: dnsPrefix + "all.ropsten.ethdisco.net",
RinkebyGenesisHash: dnsPrefix + "all.rinkeby.ethdisco.net",
GoerliGenesisHash: dnsPrefix + "all.goerli.ethdisco.net",
}