@ -64,15 +64,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
@ -162,6 +160,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 ) ,
}
bcVersion := rawdb . ReadDatabaseVersion ( chainDb )
@ -266,17 +265,6 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
}
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 , networkID )
@ -359,9 +347,9 @@ func (s *Ethereum) BloomIndexer() *core.ChainIndexer { return s.bloomIndexer }
// 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 . ethDialCan didate s)
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
}
@ -369,7 +357,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 )
@ -382,12 +370,43 @@ func (s *Ethereum) Start() error {
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
}
// 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 . ethDialCandidates . Close ( )
s . snapDialCandidates . Close ( )
s . discmix . Close ( )
s . handler . Stop ( )
// Then stop everything else.