github.com/coltonfike/e2c@v21.1.0+incompatible/eth/backend.go (about) 1 // Copyright 2014 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 // Package eth implements the Ethereum protocol. 18 package eth 19 20 import ( 21 "errors" 22 "fmt" 23 "math/big" 24 "runtime" 25 "sync" 26 "sync/atomic" 27 28 "github.com/ethereum/go-ethereum/accounts" 29 "github.com/ethereum/go-ethereum/accounts/abi/bind" 30 "github.com/ethereum/go-ethereum/common" 31 "github.com/ethereum/go-ethereum/common/hexutil" 32 "github.com/ethereum/go-ethereum/consensus" 33 "github.com/ethereum/go-ethereum/consensus/clique" 34 "github.com/ethereum/go-ethereum/consensus/ethash" 35 "github.com/ethereum/go-ethereum/consensus/istanbul" 36 istanbulBackend "github.com/ethereum/go-ethereum/consensus/istanbul/backend" 37 "github.com/ethereum/go-ethereum/core" 38 "github.com/ethereum/go-ethereum/core/bloombits" 39 "github.com/ethereum/go-ethereum/core/rawdb" 40 "github.com/ethereum/go-ethereum/core/types" 41 "github.com/ethereum/go-ethereum/core/vm" 42 "github.com/ethereum/go-ethereum/crypto" 43 "github.com/ethereum/go-ethereum/eth/downloader" 44 "github.com/ethereum/go-ethereum/eth/filters" 45 "github.com/ethereum/go-ethereum/eth/gasprice" 46 "github.com/ethereum/go-ethereum/ethdb" 47 "github.com/ethereum/go-ethereum/event" 48 "github.com/ethereum/go-ethereum/internal/ethapi" 49 "github.com/ethereum/go-ethereum/log" 50 "github.com/ethereum/go-ethereum/miner" 51 "github.com/ethereum/go-ethereum/multitenancy" 52 "github.com/ethereum/go-ethereum/node" 53 "github.com/ethereum/go-ethereum/p2p" 54 "github.com/ethereum/go-ethereum/p2p/enr" 55 "github.com/ethereum/go-ethereum/params" 56 "github.com/ethereum/go-ethereum/rlp" 57 "github.com/ethereum/go-ethereum/rpc" 58 ) 59 60 type LesServer interface { 61 Start(srvr *p2p.Server) 62 Stop() 63 APIs() []rpc.API 64 Protocols() []p2p.Protocol 65 SetBloomBitsIndexer(bbIndexer *core.ChainIndexer) 66 SetContractBackend(bind.ContractBackend) 67 } 68 69 // Ethereum implements the Ethereum full node service. 70 type Ethereum struct { 71 config *Config 72 73 // Channel for shutting down the service 74 shutdownChan chan bool 75 76 // Handlers 77 txPool *core.TxPool 78 blockchain *core.BlockChain 79 protocolManager *ProtocolManager 80 lesServer LesServer 81 82 // DB interfaces 83 chainDb ethdb.Database // Block chain database 84 85 eventMux *event.TypeMux 86 engine consensus.Engine 87 accountManager *accounts.Manager 88 89 bloomRequests chan chan *bloombits.Retrieval // Channel receiving bloom data retrieval requests 90 bloomIndexer *core.ChainIndexer // Bloom indexer operating during block imports 91 92 APIBackend *EthAPIBackend 93 94 miner *miner.Miner 95 gasPrice *big.Int 96 etherbase common.Address 97 98 networkID uint64 99 netRPCService *ethapi.PublicNetAPI 100 101 lock sync.RWMutex // Protects the variadic fields (e.g. gas price and etherbase) 102 103 // Quorum - Multitenancy 104 // contractAuthzProvider is set after node starts instead in New() 105 contractAuthzProvider multitenancy.ContractAuthorizationProvider 106 } 107 108 func (s *Ethereum) AddLesServer(ls LesServer) { 109 s.lesServer = ls 110 ls.SetBloomBitsIndexer(s.bloomIndexer) 111 } 112 113 // SetClient sets a rpc client which connecting to our local node. 114 func (s *Ethereum) SetContractBackend(backend bind.ContractBackend) { 115 // Pass the rpc client to les server if it is enabled. 116 if s.lesServer != nil { 117 s.lesServer.SetContractBackend(backend) 118 } 119 } 120 121 // Quorum 122 // 123 // Set the decision manager for multitenancy support 124 func (s *Ethereum) SetContractAuthorizationProvider(dm multitenancy.ContractAuthorizationProvider) { 125 s.contractAuthzProvider = dm 126 } 127 128 // New creates a new Ethereum object (including the 129 // initialisation of the common Ethereum object) 130 func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) { 131 // Ensure configuration values are compatible and sane 132 if config.SyncMode == downloader.LightSync { 133 return nil, errors.New("can't run eth.Ethereum in light sync mode, use les.LightEthereum") 134 } 135 if !config.SyncMode.IsValid() { 136 return nil, fmt.Errorf("invalid sync mode %d", config.SyncMode) 137 } 138 if config.Miner.GasPrice == nil || config.Miner.GasPrice.Cmp(common.Big0) <= 0 { 139 log.Warn("Sanitizing invalid miner gas price", "provided", config.Miner.GasPrice, "updated", DefaultConfig.Miner.GasPrice) 140 config.Miner.GasPrice = new(big.Int).Set(DefaultConfig.Miner.GasPrice) 141 } 142 if config.NoPruning && config.TrieDirtyCache > 0 { 143 config.TrieCleanCache += config.TrieDirtyCache 144 config.TrieDirtyCache = 0 145 } 146 log.Info("Allocated trie memory caches", "clean", common.StorageSize(config.TrieCleanCache)*1024*1024, "dirty", common.StorageSize(config.TrieDirtyCache)*1024*1024) 147 148 // Assemble the Ethereum object 149 chainDb, err := ctx.OpenDatabaseWithFreezer("chaindata", config.DatabaseCache, config.DatabaseHandles, config.DatabaseFreezer, "eth/db/chaindata/") 150 if err != nil { 151 return nil, err 152 } 153 chainConfig, genesisHash, genesisErr := core.SetupGenesisBlockWithOverride(chainDb, config.Genesis, config.OverrideIstanbul) 154 if _, ok := genesisErr.(*params.ConfigCompatError); genesisErr != nil && !ok { 155 return nil, genesisErr 156 } 157 log.Info("Initialised chain configuration", "config", chainConfig) 158 159 // changes to manipulate the chain id for migration from 2.0.2 and below version to 2.0.3 160 // version of Quorum - this is applicable for v2.0.3 onwards 161 if chainConfig.IsQuorum { 162 if (chainConfig.ChainID != nil && chainConfig.ChainID.Int64() == 1) || config.NetworkId == 1 { 163 return nil, errors.New("Cannot have chain id or network id as 1.") 164 } 165 } 166 167 if !rawdb.GetIsQuorumEIP155Activated(chainDb) && chainConfig.ChainID != nil { 168 //Upon starting the node, write the flag to disallow changing ChainID/EIP155 block after HF 169 rawdb.WriteQuorumEIP155Activation(chainDb) 170 } 171 172 eth := &Ethereum{ 173 config: config, 174 chainDb: chainDb, 175 eventMux: ctx.EventMux, 176 accountManager: ctx.AccountManager, 177 engine: CreateConsensusEngine(ctx, chainConfig, config, config.Miner.Notify, config.Miner.Noverify, chainDb), 178 shutdownChan: make(chan bool), 179 networkID: config.NetworkId, 180 gasPrice: config.Miner.GasPrice, 181 etherbase: config.Miner.Etherbase, 182 bloomRequests: make(chan chan *bloombits.Retrieval), 183 bloomIndexer: NewBloomIndexer(chainDb, params.BloomBitsBlocks, params.BloomConfirms), 184 } 185 186 // Quorum: Set protocol Name/Version 187 if chainConfig.IsQuorum { 188 quorumProtocol := eth.engine.Protocol() 189 protocolName = quorumProtocol.Name 190 ProtocolVersions = quorumProtocol.Versions 191 } 192 193 // force to set the istanbul etherbase to node key address 194 if chainConfig.Istanbul != nil { 195 eth.etherbase = crypto.PubkeyToAddress(ctx.NodeKey().PublicKey) 196 } 197 bcVersion := rawdb.ReadDatabaseVersion(chainDb) 198 var dbVer = "<nil>" 199 if bcVersion != nil { 200 dbVer = fmt.Sprintf("%d", *bcVersion) 201 } 202 log.Info("Initialising Ethereum protocol", "name", protocolName, "versions", ProtocolVersions, "network", config.NetworkId, "dbversion", dbVer) 203 204 if !config.SkipBcVersionCheck { 205 if bcVersion != nil && *bcVersion > core.BlockChainVersion { 206 return nil, fmt.Errorf("database version is v%d, Geth %s only supports v%d", *bcVersion, params.VersionWithMeta, core.BlockChainVersion) 207 } else if bcVersion == nil || *bcVersion < core.BlockChainVersion { 208 log.Warn("Upgrade blockchain database version", "from", dbVer, "to", core.BlockChainVersion) 209 rawdb.WriteDatabaseVersion(chainDb, core.BlockChainVersion) 210 } 211 } 212 var ( 213 vmConfig = vm.Config{ 214 EnablePreimageRecording: config.EnablePreimageRecording, 215 EWASMInterpreter: config.EWASMInterpreter, 216 EVMInterpreter: config.EVMInterpreter, 217 } 218 cacheConfig = &core.CacheConfig{ 219 TrieCleanLimit: config.TrieCleanCache, 220 TrieCleanNoPrefetch: config.NoPrefetch, 221 TrieDirtyLimit: config.TrieDirtyCache, 222 TrieDirtyDisabled: config.NoPruning, 223 TrieTimeLimit: config.TrieTimeout, 224 } 225 ) 226 newBlockChainFunc := core.NewBlockChain 227 if config.EnableMultitenancy { 228 newBlockChainFunc = core.NewMultitenantBlockChain 229 } 230 eth.blockchain, err = newBlockChainFunc(chainDb, cacheConfig, chainConfig, eth.engine, vmConfig, eth.shouldPreserve) 231 if err != nil { 232 return nil, err 233 } 234 // Rewind the chain in case of an incompatible config upgrade. 235 if compat, ok := genesisErr.(*params.ConfigCompatError); ok { 236 log.Warn("Rewinding chain to upgrade configuration", "err", compat) 237 eth.blockchain.SetHead(compat.RewindTo) 238 rawdb.WriteChainConfig(chainDb, genesisHash, chainConfig) 239 } 240 eth.bloomIndexer.Start(eth.blockchain) 241 242 if config.TxPool.Journal != "" { 243 config.TxPool.Journal = ctx.ResolvePath(config.TxPool.Journal) 244 } 245 eth.txPool = core.NewTxPool(config.TxPool, chainConfig, eth.blockchain) 246 247 // Permit the downloader to use the trie cache allowance during fast sync 248 cacheLimit := cacheConfig.TrieCleanLimit + cacheConfig.TrieDirtyLimit 249 checkpoint := config.Checkpoint 250 if checkpoint == nil { 251 checkpoint = params.TrustedCheckpoints[genesisHash] 252 } 253 if eth.protocolManager, err = NewProtocolManager(chainConfig, checkpoint, config.SyncMode, config.NetworkId, eth.eventMux, eth.txPool, eth.engine, eth.blockchain, chainDb, cacheLimit, config.Whitelist, config.RaftMode); err != nil { 254 return nil, err 255 } 256 eth.miner = miner.New(eth, &config.Miner, chainConfig, eth.EventMux(), eth.engine, eth.isLocalBlock) 257 eth.miner.SetExtra(makeExtraData(config.Miner.ExtraData, eth.blockchain.Config().IsQuorum)) 258 259 hexNodeId := fmt.Sprintf("%x", crypto.FromECDSAPub(&ctx.NodeKey().PublicKey)[1:]) // Quorum 260 eth.APIBackend = &EthAPIBackend{ctx.ExtRPCEnabled(), eth, nil, hexNodeId, config.EVMCallTimeOut} 261 gpoParams := config.GPO 262 if gpoParams.Default == nil { 263 gpoParams.Default = config.Miner.GasPrice 264 } 265 eth.APIBackend.gpo = gasprice.NewOracle(eth.APIBackend, gpoParams) 266 267 return eth, nil 268 } 269 270 func makeExtraData(extra []byte, isQuorum bool) []byte { 271 if len(extra) == 0 { 272 // create default extradata 273 extra, _ = rlp.EncodeToBytes([]interface{}{ 274 uint(params.VersionMajor<<16 | params.VersionMinor<<8 | params.VersionPatch), 275 "geth", 276 runtime.Version(), 277 runtime.GOOS, 278 }) 279 } 280 if uint64(len(extra)) > params.GetMaximumExtraDataSize(isQuorum) { 281 log.Warn("Miner extra data exceed limit", "extra", hexutil.Bytes(extra), "limit", params.GetMaximumExtraDataSize(isQuorum)) 282 extra = nil 283 } 284 return extra 285 } 286 287 // CreateConsensusEngine creates the required type of consensus engine instance for an Ethereum service 288 func CreateConsensusEngine(ctx *node.ServiceContext, chainConfig *params.ChainConfig, config *Config, notify []string, noverify bool, db ethdb.Database) consensus.Engine { 289 // If proof-of-authority is requested, set it up 290 if chainConfig.Clique != nil { 291 chainConfig.Clique.AllowedFutureBlockTime = config.Miner.AllowedFutureBlockTime //Quorum 292 return clique.New(chainConfig.Clique, db) 293 } 294 // If Istanbul is requested, set it up 295 if chainConfig.Istanbul != nil { 296 if chainConfig.Istanbul.Epoch != 0 { 297 config.Istanbul.Epoch = chainConfig.Istanbul.Epoch 298 } 299 config.Istanbul.ProposerPolicy = istanbul.ProposerPolicy(chainConfig.Istanbul.ProposerPolicy) 300 config.Istanbul.Ceil2Nby3Block = chainConfig.Istanbul.Ceil2Nby3Block 301 config.Istanbul.AllowedFutureBlockTime = config.Miner.AllowedFutureBlockTime //Quorum 302 303 return istanbulBackend.New(&config.Istanbul, ctx.NodeKey(), db) 304 } 305 306 // Otherwise assume proof-of-work 307 switch config.Ethash.PowMode { 308 case ethash.ModeFake: 309 log.Warn("Ethash used in fake mode") 310 return ethash.NewFaker() 311 case ethash.ModeTest: 312 log.Warn("Ethash used in test mode") 313 return ethash.NewTester(nil, noverify) 314 case ethash.ModeShared: 315 log.Warn("Ethash used in shared mode") 316 return ethash.NewShared() 317 default: 318 // For Quorum, Raft run as a separate service, so 319 // the Ethereum service still needs a consensus engine, 320 // use the consensus with the lightest overhead 321 log.Warn("Ethash used in full fake mode") 322 return ethash.NewFullFaker() 323 } 324 } 325 326 // APIs return the collection of RPC services the ethereum package offers. 327 // NOTE, some of these services probably need to be moved to somewhere else. 328 func (s *Ethereum) APIs() []rpc.API { 329 apis := ethapi.GetAPIs(s.APIBackend) 330 331 // Append any APIs exposed explicitly by the les server 332 if s.lesServer != nil { 333 apis = append(apis, s.lesServer.APIs()...) 334 } 335 // Append any APIs exposed explicitly by the consensus engine 336 apis = append(apis, s.engine.APIs(s.BlockChain())...) 337 338 // Append any APIs exposed explicitly by the les server 339 if s.lesServer != nil { 340 apis = append(apis, s.lesServer.APIs()...) 341 } 342 343 // Append all the local APIs and return 344 apis = append(apis, []rpc.API{ 345 { 346 Namespace: "eth", 347 Version: "1.0", 348 Service: NewPublicEthereumAPI(s), 349 Public: true, 350 }, { 351 Namespace: "eth", 352 Version: "1.0", 353 Service: NewPublicMinerAPI(s), 354 Public: true, 355 }, { 356 Namespace: "eth", 357 Version: "1.0", 358 Service: downloader.NewPublicDownloaderAPI(s.protocolManager.downloader, s.eventMux), 359 Public: true, 360 }, { 361 Namespace: "miner", 362 Version: "1.0", 363 Service: NewPrivateMinerAPI(s), 364 Public: false, 365 }, { 366 Namespace: "eth", 367 Version: "1.0", 368 Service: filters.NewPublicFilterAPI(s.APIBackend, false), 369 Public: true, 370 }, { 371 Namespace: "admin", 372 Version: "1.0", 373 Service: NewPrivateAdminAPI(s), 374 }, { 375 Namespace: "debug", 376 Version: "1.0", 377 Service: NewPublicDebugAPI(s), 378 Public: true, 379 }, { 380 Namespace: "debug", 381 Version: "1.0", 382 Service: NewPrivateDebugAPI(s), 383 }, { 384 Namespace: "net", 385 Version: "1.0", 386 Service: s.netRPCService, 387 Public: true, 388 }, 389 }...) 390 return apis 391 } 392 393 func (s *Ethereum) ResetWithGenesisBlock(gb *types.Block) { 394 s.blockchain.ResetWithGenesisBlock(gb) 395 } 396 397 func (s *Ethereum) Etherbase() (eb common.Address, err error) { 398 s.lock.RLock() 399 etherbase := s.etherbase 400 s.lock.RUnlock() 401 402 if etherbase != (common.Address{}) { 403 return etherbase, nil 404 } 405 if wallets := s.AccountManager().Wallets(); len(wallets) > 0 { 406 if accounts := wallets[0].Accounts(); len(accounts) > 0 { 407 etherbase := accounts[0].Address 408 409 s.lock.Lock() 410 s.etherbase = etherbase 411 s.lock.Unlock() 412 413 log.Info("Etherbase automatically configured", "address", etherbase) 414 return etherbase, nil 415 } 416 } 417 return common.Address{}, fmt.Errorf("etherbase must be explicitly specified") 418 } 419 420 // isLocalBlock checks whether the specified block is mined 421 // by local miner accounts. 422 // 423 // We regard two types of accounts as local miner account: etherbase 424 // and accounts specified via `txpool.locals` flag. 425 func (s *Ethereum) isLocalBlock(block *types.Block) bool { 426 author, err := s.engine.Author(block.Header()) 427 if err != nil { 428 log.Warn("Failed to retrieve block author", "number", block.NumberU64(), "hash", block.Hash(), "err", err) 429 return false 430 } 431 // Check whether the given address is etherbase. 432 s.lock.RLock() 433 etherbase := s.etherbase 434 s.lock.RUnlock() 435 if author == etherbase { 436 return true 437 } 438 // Check whether the given address is specified by `txpool.local` 439 // CLI flag. 440 for _, account := range s.config.TxPool.Locals { 441 if account == author { 442 return true 443 } 444 } 445 return false 446 } 447 448 // shouldPreserve checks whether we should preserve the given block 449 // during the chain reorg depending on whether the author of block 450 // is a local account. 451 func (s *Ethereum) shouldPreserve(block *types.Block) bool { 452 // The reason we need to disable the self-reorg preserving for clique 453 // is it can be probable to introduce a deadlock. 454 // 455 // e.g. If there are 7 available signers 456 // 457 // r1 A 458 // r2 B 459 // r3 C 460 // r4 D 461 // r5 A [X] F G 462 // r6 [X] 463 // 464 // In the round5, the inturn signer E is offline, so the worst case 465 // is A, F and G sign the block of round5 and reject the block of opponents 466 // and in the round6, the last available signer B is offline, the whole 467 // network is stuck. 468 if _, ok := s.engine.(*clique.Clique); ok { 469 return false 470 } 471 return s.isLocalBlock(block) 472 } 473 474 // SetEtherbase sets the mining reward address. 475 func (s *Ethereum) SetEtherbase(etherbase common.Address) { 476 s.lock.Lock() 477 defer s.lock.Unlock() 478 if _, ok := s.engine.(consensus.Istanbul); ok { 479 log.Error("Cannot set etherbase in Istanbul consensus") 480 return 481 } 482 s.etherbase = etherbase 483 484 s.miner.SetEtherbase(etherbase) 485 } 486 487 // StartMining starts the miner with the given number of CPU threads. If mining 488 // is already running, this method adjust the number of threads allowed to use 489 // and updates the minimum price required by the transaction pool. 490 func (s *Ethereum) StartMining(threads int) error { 491 // Update the thread count within the consensus engine 492 type threaded interface { 493 SetThreads(threads int) 494 } 495 if th, ok := s.engine.(threaded); ok { 496 log.Info("Updated mining threads", "threads", threads) 497 if threads == 0 { 498 threads = -1 // Disable the miner from within 499 } 500 th.SetThreads(threads) 501 } 502 // If the miner was not running, initialize it 503 if !s.IsMining() { 504 // Propagate the initial price point to the transaction pool 505 s.lock.RLock() 506 price := s.gasPrice 507 s.lock.RUnlock() 508 s.txPool.SetGasPrice(price) 509 510 // Configure the local mining address 511 eb, err := s.Etherbase() 512 if err != nil { 513 log.Error("Cannot start mining without etherbase", "err", err) 514 return fmt.Errorf("etherbase missing: %v", err) 515 } 516 if clique, ok := s.engine.(*clique.Clique); ok { 517 wallet, err := s.accountManager.Find(accounts.Account{Address: eb}) 518 if wallet == nil || err != nil { 519 log.Error("Etherbase account unavailable locally", "err", err) 520 return fmt.Errorf("signer missing: %v", err) 521 } 522 clique.Authorize(eb, wallet.SignData) 523 } 524 // If mining is started, we can disable the transaction rejection mechanism 525 // introduced to speed sync times. 526 atomic.StoreUint32(&s.protocolManager.acceptTxs, 1) 527 528 go s.miner.Start(eb) 529 } 530 return nil 531 } 532 533 // StopMining terminates the miner, both at the consensus engine level as well as 534 // at the block creation level. 535 func (s *Ethereum) StopMining() { 536 // Update the thread count within the consensus engine 537 type threaded interface { 538 SetThreads(threads int) 539 } 540 if th, ok := s.engine.(threaded); ok { 541 th.SetThreads(-1) 542 } 543 // Stop the block creating itself 544 s.miner.Stop() 545 } 546 547 func (s *Ethereum) IsMining() bool { return s.miner.Mining() } 548 func (s *Ethereum) Miner() *miner.Miner { return s.miner } 549 550 func (s *Ethereum) AccountManager() *accounts.Manager { return s.accountManager } 551 func (s *Ethereum) BlockChain() *core.BlockChain { return s.blockchain } 552 func (s *Ethereum) TxPool() *core.TxPool { return s.txPool } 553 func (s *Ethereum) EventMux() *event.TypeMux { return s.eventMux } 554 func (s *Ethereum) Engine() consensus.Engine { return s.engine } 555 func (s *Ethereum) ChainDb() ethdb.Database { return s.chainDb } 556 func (s *Ethereum) IsListening() bool { return true } // Always listening 557 func (s *Ethereum) EthVersion() int { return int(ProtocolVersions[0]) } 558 func (s *Ethereum) NetVersion() uint64 { return s.networkID } 559 func (s *Ethereum) Downloader() *downloader.Downloader { return s.protocolManager.downloader } 560 func (s *Ethereum) Synced() bool { return atomic.LoadUint32(&s.protocolManager.acceptTxs) == 1 } 561 func (s *Ethereum) ArchiveMode() bool { return s.config.NoPruning } 562 563 // Protocols implements node.Service, returning all the currently configured 564 // network protocols to start. 565 func (s *Ethereum) Protocols() []p2p.Protocol { 566 protos := make([]p2p.Protocol, len(ProtocolVersions)) 567 for i, vsn := range ProtocolVersions { 568 protos[i] = s.protocolManager.makeProtocol(vsn) 569 protos[i].Attributes = []enr.Entry{s.currentEthEntry()} 570 } 571 if s.lesServer != nil { 572 protos = append(protos, s.lesServer.Protocols()...) 573 } 574 return protos 575 } 576 577 // Start implements node.Service, starting all internal goroutines needed by the 578 // Ethereum protocol implementation. 579 func (s *Ethereum) Start(srvr *p2p.Server) error { 580 s.startEthEntryUpdate(srvr.LocalNode()) 581 582 // Start the bloom bits servicing goroutines 583 s.startBloomHandlers(params.BloomBitsBlocks) 584 585 // Start the RPC service 586 s.netRPCService = ethapi.NewPublicNetAPI(srvr, s.NetVersion()) 587 588 // Figure out a max peers count based on the server limits 589 maxPeers := srvr.MaxPeers 590 if s.config.LightServ > 0 { 591 if s.config.LightPeers >= srvr.MaxPeers { 592 return fmt.Errorf("invalid peer config: light peer count (%d) >= total peer count (%d)", s.config.LightPeers, srvr.MaxPeers) 593 } 594 maxPeers -= s.config.LightPeers 595 } 596 // Start the networking layer and the light server if requested 597 s.protocolManager.Start(maxPeers) 598 if s.lesServer != nil { 599 s.lesServer.Start(srvr) 600 } 601 return nil 602 } 603 604 // Stop implements node.Service, terminating all internal goroutines used by the 605 // Ethereum protocol. 606 func (s *Ethereum) Stop() error { 607 s.bloomIndexer.Close() 608 s.blockchain.Stop() 609 s.engine.Close() 610 s.protocolManager.Stop() 611 if s.lesServer != nil { 612 s.lesServer.Stop() 613 } 614 s.txPool.Stop() 615 s.miner.Stop() 616 s.eventMux.Stop() 617 618 s.chainDb.Close() 619 close(s.shutdownChan) 620 return nil 621 } 622 623 func (s *Ethereum) CalcGasLimit(block *types.Block) uint64 { 624 return core.CalcGasLimit(block, s.config.Miner.GasFloor, s.config.Miner.GasCeil) 625 }