Skip to content
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
69 changes: 45 additions & 24 deletions eth/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,15 +73,13 @@ type Config = ethconfig.Config

// Ethereum implements the Ethereum full node service.
type Ethereum struct {
config *ethconfig.Config
// core protocol objects
config *ethconfig.Config
txPool *txpool.TxPool
blockchain *core.BlockChain

// Handlers
txPool *txpool.TxPool

blockchain *core.BlockChain
handler *handler
ethDialCandidates enode.Iterator
snapDialCandidates enode.Iterator
handler *handler
discmix *enode.FairMix

// DB interfaces
chainDb ethdb.Database // Block chain database
Expand Down Expand Up @@ -168,6 +166,7 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
bloomRequests: make(chan chan *bloombits.Retrieval),
bloomIndexer: core.NewBloomIndexer(chainDb, params.BloomBitsBlocks, params.BloomConfirms),
p2pServer: stack.Server(),
discmix: enode.NewFairMix(0),
shutdownTracker: shutdowncheck.NewShutdownTracker(chainDb),
closeCh: make(chan struct{}),
}
Expand Down Expand Up @@ -322,17 +321,6 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
// 1.14.8: NewOracle function definition was changed to accept (startPrice *big.Int) param.
eth.APIBackend.gpo = gasprice.NewOracle(eth.APIBackend, config.GPO, config.Miner.GasPrice)

// Setup DNS discovery iterators.
dnsclient := dnsdisc.NewClient(dnsdisc.Config{})
eth.ethDialCandidates, err = dnsclient.NewIterator(eth.config.EthDiscoveryURLs...)
if err != nil {
return nil, err
}
eth.snapDialCandidates, err = dnsclient.NewIterator(eth.config.SnapDiscoveryURLs...)
if err != nil {
return nil, err
}

// Start the RPC service
eth.netRPCService = ethapi.NewNetAPI(eth.p2pServer, config.NetworkId)

Expand Down Expand Up @@ -600,9 +588,9 @@ func (s *Ethereum) SetAuthorized(authorized bool) {
// Protocols returns all the currently configured
// network protocols to start.
func (s *Ethereum) Protocols() []p2p.Protocol {
protos := eth.MakeProtocols((*ethHandler)(s.handler), s.networkID, s.ethDialCandidates)
protos := eth.MakeProtocols((*ethHandler)(s.handler), s.networkID, s.discmix)
if s.config.SnapshotCache > 0 {
protos = append(protos, snap.MakeProtocols((*snapHandler)(s.handler), s.snapDialCandidates)...)
protos = append(protos, snap.MakeProtocols((*snapHandler)(s.handler))...)
}

return protos
Expand All @@ -611,7 +599,7 @@ func (s *Ethereum) Protocols() []p2p.Protocol {
// Start implements node.Lifecycle, starting all internal goroutines needed by the
// Ethereum protocol implementation.
func (s *Ethereum) Start() error {
eth.StartENRUpdater(s.blockchain, s.p2pServer.LocalNode())
s.setupDiscovery()

// Start the bloom bits servicing goroutines
s.startBloomHandlers(params.BloomBitsBlocks)
Expand Down Expand Up @@ -798,6 +786,38 @@ func (s *Ethereum) handleNoAckMilestoneByID(ctx context.Context, ethHandler *eth
return nil
}

func (s *Ethereum) setupDiscovery() error {
eth.StartENRUpdater(s.blockchain, s.p2pServer.LocalNode())

// Add eth nodes from DNS.
dnsclient := dnsdisc.NewClient(dnsdisc.Config{})
if len(s.config.EthDiscoveryURLs) > 0 {
iter, err := dnsclient.NewIterator(s.config.EthDiscoveryURLs...)
if err != nil {
return err
}
s.discmix.AddSource(iter)
}

// Add snap nodes from DNS.
if len(s.config.SnapDiscoveryURLs) > 0 {
iter, err := dnsclient.NewIterator(s.config.SnapDiscoveryURLs...)
if err != nil {
return err
}
s.discmix.AddSource(iter)
}

// Add DHT nodes from discv5.
if s.p2pServer.DiscoveryV5() != nil {
filter := eth.NewNodeFilter(s.blockchain)
iter := enode.Filter(s.p2pServer.DiscoveryV5().RandomNodes(), filter)
s.discmix.AddSource(iter)
}

return nil
}

func (s *Ethereum) getHandler() (*ethHandler, *bor.Bor, error) {
ethHandler := (*ethHandler)(s.handler)

Expand All @@ -816,13 +836,14 @@ func (s *Ethereum) getHandler() (*ethHandler, *bor.Bor, error) {
// Stop implements node.Lifecycle, terminating all internal goroutines used by the
// Ethereum protocol.
func (s *Ethereum) Stop() error {
// Stop all the peer-related stuff first.
s.discmix.Close()

// Close the engine before handler else it may cause a deadlock where
// the heimdall is unresponsive and the syncing loop keeps waiting
// for a response and is unable to proceed to exit `Finalize` during
// block processing.
s.engine.Close()
s.ethDialCandidates.Close()
s.snapDialCandidates.Close()
s.handler.Stop()

// Then stop everything else.
Expand Down
14 changes: 14 additions & 0 deletions eth/protocols/eth/discovery.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,17 @@ func currentENREntry(chain *core.BlockChain) *enrEntry {
ForkID: forkid.NewID(chain.Config(), chain.Genesis(), head.Number.Uint64(), head.Time),
}
}

// NewNodeFilter returns a filtering function that returns whether the provided
// enode advertises a forkid compatible with the current chain.
func NewNodeFilter(chain *core.BlockChain) func(*enode.Node) bool {
filter := forkid.NewFilter(chain)
return func(n *enode.Node) bool {
var entry enrEntry
if err := n.Load(entry); err != nil {
return false
}
err := filter(entry.ForkID)
return err == nil
}
}
4 changes: 2 additions & 2 deletions eth/protocols/eth/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ type TxPool interface {
}

// MakeProtocols constructs the P2P protocol definitions for `eth`.
func MakeProtocols(backend Backend, network uint64, dnsdisc enode.Iterator) []p2p.Protocol {
func MakeProtocols(backend Backend, network uint64, disc enode.Iterator) []p2p.Protocol {
protocols := make([]p2p.Protocol, 0, len(ProtocolVersions))
for _, version := range ProtocolVersions {
// Blob transactions require eth/68 announcements, disable everything else
Expand All @@ -117,8 +117,8 @@ func MakeProtocols(backend Backend, network uint64, dnsdisc enode.Iterator) []p2
PeerInfo: func(id enode.ID) interface{} {
return backend.PeerInfo(id)
},
DialCandidates: disc,
Attributes: []enr.Entry{currentENREntry(backend.Chain())},
DialCandidates: dnsdisc,
})
}
return protocols
Expand Down
11 changes: 2 additions & 9 deletions eth/protocols/snap/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,7 @@ type Backend interface {
}

// MakeProtocols constructs the P2P protocol definitions for `snap`.
func MakeProtocols(backend Backend, dnsdisc enode.Iterator) []p2p.Protocol {
// Filter the discovery iterator for nodes advertising snap support.
dnsdisc = enode.Filter(dnsdisc, func(n *enode.Node) bool {
var snap enrEntry
return n.Load(&snap) == nil
})

func MakeProtocols(backend Backend) []p2p.Protocol {
protocols := make([]p2p.Protocol, len(ProtocolVersions))

for i, version := range ProtocolVersions {
Expand All @@ -109,8 +103,7 @@ func MakeProtocols(backend Backend, dnsdisc enode.Iterator) []p2p.Protocol {
PeerInfo: func(id enode.ID) interface{} {
return backend.PeerInfo(id)
},
Attributes: []enr.Entry{&enrEntry{}},
DialCandidates: dnsdisc,
Attributes: []enr.Entry{&enrEntry{}},
}
}

Expand Down
Loading