diff --git a/eth/backend.go b/eth/backend.go index 774ffaf248..86a944e799 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -306,44 +306,44 @@ func makeExtraData(extra []byte) []byte { // APIs return the collection of RPC services the ethereum package offers. // NOTE, some of these services probably need to be moved to somewhere else. -func (s *Ethereum) APIs() []rpc.API { - apis := ethapi.GetAPIs(s.APIBackend) +func (e *Ethereum) APIs() []rpc.API { + apis := ethapi.GetAPIs(e.APIBackend) // Append any APIs exposed explicitly by the consensus engine - apis = append(apis, s.engine.APIs(s.BlockChain())...) + apis = append(apis, e.engine.APIs(e.BlockChain())...) // Append all the local APIs and return return append(apis, []rpc.API{ { Namespace: "eth", - Service: NewEthereumAPI(s), + Service: NewEthereumAPI(e), }, { Namespace: "miner", - Service: NewMinerAPI(s), + Service: NewMinerAPI(e), }, { Namespace: "eth", - Service: downloader.NewDownloaderAPI(s.handler.downloader, s.eventMux), + Service: downloader.NewDownloaderAPI(e.handler.downloader, e.eventMux), }, { Namespace: "admin", - Service: NewAdminAPI(s), + Service: NewAdminAPI(e), }, { Namespace: "debug", - Service: NewDebugAPI(s), + Service: NewDebugAPI(e), }, { Namespace: "net", - Service: s.netRPCService, + Service: e.netRPCService, }, }...) } -func (s *Ethereum) ResetWithGenesisBlock(gb *types.Block) { - s.blockchain.ResetWithGenesisBlock(gb) +func (e *Ethereum) ResetWithGenesisBlock(gb *types.Block) { + e.blockchain.ResetWithGenesisBlock(gb) } -func (s *Ethereum) Etherbase() (eb common.Address, err error) { - s.lock.RLock() - etherbase := s.etherbase - s.lock.RUnlock() +func (e *Ethereum) Etherbase() (eb common.Address, err error) { + e.lock.RLock() + etherbase := e.etherbase + e.lock.RUnlock() if etherbase != (common.Address{}) { return etherbase, nil @@ -356,22 +356,22 @@ func (s *Ethereum) Etherbase() (eb common.Address, err error) { // // We regard two types of accounts as local miner account: etherbase // and accounts specified via `txpool.locals` flag. -func (s *Ethereum) isLocalBlock(header *types.Header) bool { - author, err := s.engine.Author(header) +func (e *Ethereum) isLocalBlock(header *types.Header) bool { + author, err := e.engine.Author(header) if err != nil { log.Warn("Failed to retrieve block author", "number", header.Number.Uint64(), "hash", header.Hash(), "err", err) return false } // Check whether the given address is etherbase. - s.lock.RLock() - etherbase := s.etherbase - s.lock.RUnlock() + e.lock.RLock() + etherbase := e.etherbase + e.lock.RUnlock() if author == etherbase { return true } // Check whether the given address is specified by `txpool.local` // CLI flag. - for _, account := range s.config.TxPool.Locals { + for _, account := range e.config.TxPool.Locals { if account == author { return true } @@ -382,7 +382,7 @@ func (s *Ethereum) isLocalBlock(header *types.Header) bool { // shouldPreserve checks whether we should preserve the given block // during the chain reorg depending on whether the author of block // is a local account. -func (s *Ethereum) shouldPreserve(header *types.Header) bool { +func (e *Ethereum) shouldPreserve(header *types.Header) bool { // The reason we need to disable the self-reorg preserving for clique // is it can be probable to introduce a deadlock. // @@ -399,49 +399,49 @@ func (s *Ethereum) shouldPreserve(header *types.Header) bool { // is A, F and G sign the block of round5 and reject the block of opponents // and in the round6, the last available signer B is offline, the whole // network is stuck. - if _, ok := s.engine.(*clique.Clique); ok { + if _, ok := e.engine.(*clique.Clique); ok { return false } - return s.isLocalBlock(header) + return e.isLocalBlock(header) } // SetEtherbase sets the mining reward address. -func (s *Ethereum) SetEtherbase(etherbase common.Address) { - s.lock.Lock() - s.etherbase = etherbase - s.lock.Unlock() +func (e *Ethereum) SetEtherbase(etherbase common.Address) { + e.lock.Lock() + e.etherbase = etherbase + e.lock.Unlock() - s.miner.SetEtherbase(etherbase) + e.miner.SetEtherbase(etherbase) } // StartMining starts the miner with the given number of CPU threads. If mining // is already running, this method adjust the number of threads allowed to use // and updates the minimum price required by the transaction pool. -func (s *Ethereum) StartMining() error { +func (e *Ethereum) StartMining() error { // If the miner was not running, initialize it - if !s.IsMining() { + if !e.IsMining() { // Propagate the initial price point to the transaction pool - s.lock.RLock() - price := s.gasPrice - s.lock.RUnlock() - s.txPool.SetGasTip(price) + e.lock.RLock() + price := e.gasPrice + e.lock.RUnlock() + e.txPool.SetGasTip(price) // Configure the local mining address - eb, err := s.Etherbase() + eb, err := e.Etherbase() if err != nil { log.Error("Cannot start mining without etherbase", "err", err) return fmt.Errorf("etherbase missing: %v", err) } var cli *clique.Clique - if c, ok := s.engine.(*clique.Clique); ok { + if c, ok := e.engine.(*clique.Clique); ok { cli = c - } else if cl, ok := s.engine.(*beacon.Beacon); ok { + } else if cl, ok := e.engine.(*beacon.Beacon); ok { if c, ok := cl.InnerEngine().(*clique.Clique); ok { cli = c } } if cli != nil { - wallet, err := s.accountManager.Find(accounts.Account{Address: eb}) + wallet, err := e.accountManager.Find(accounts.Account{Address: eb}) if wallet == nil || err != nil { log.Error("Etherbase account unavailable locally", "err", err) return fmt.Errorf("signer missing: %v", err) @@ -450,103 +450,103 @@ func (s *Ethereum) StartMining() error { } // If mining is started, we can disable the transaction rejection mechanism // introduced to speed sync times. - s.handler.enableSyncedFeatures() + e.handler.enableSyncedFeatures() - go s.miner.Start() + go e.miner.Start() } return nil } // StopMining terminates the miner, both at the consensus engine level as well as // at the block creation level. -func (s *Ethereum) StopMining() { +func (e *Ethereum) StopMining() { // Update the thread count within the consensus engine type threaded interface { SetThreads(threads int) } - if th, ok := s.engine.(threaded); ok { + if th, ok := e.engine.(threaded); ok { th.SetThreads(-1) } // Stop the block creating itself - s.miner.Stop() + e.miner.Stop() } -func (s *Ethereum) IsMining() bool { return s.miner.Mining() } -func (s *Ethereum) Miner() *miner.Miner { return s.miner } +func (e *Ethereum) IsMining() bool { return e.miner.Mining() } +func (e *Ethereum) Miner() *miner.Miner { return e.miner } -func (s *Ethereum) AccountManager() *accounts.Manager { return s.accountManager } -func (s *Ethereum) BlockChain() *core.BlockChain { return s.blockchain } -func (s *Ethereum) TxPool() *txpool.TxPool { return s.txPool } -func (s *Ethereum) EventMux() *event.TypeMux { return s.eventMux } -func (s *Ethereum) Engine() consensus.Engine { return s.engine } -func (s *Ethereum) ChainDb() ethdb.Database { return s.chainDb } -func (s *Ethereum) IsListening() bool { return true } // Always listening -func (s *Ethereum) Downloader() *downloader.Downloader { return s.handler.downloader } -func (s *Ethereum) Synced() bool { return s.handler.synced.Load() } -func (s *Ethereum) SetSynced() { s.handler.enableSyncedFeatures() } -func (s *Ethereum) ArchiveMode() bool { return s.config.NoPruning } -func (s *Ethereum) BloomIndexer() *core.ChainIndexer { return s.bloomIndexer } -func (s *Ethereum) Merger() *consensus.Merger { return s.merger } -func (s *Ethereum) SyncMode() downloader.SyncMode { - mode, _ := s.handler.chainSync.modeAndLocalHead() +func (e *Ethereum) AccountManager() *accounts.Manager { return e.accountManager } +func (e *Ethereum) BlockChain() *core.BlockChain { return e.blockchain } +func (e *Ethereum) TxPool() *txpool.TxPool { return e.txPool } +func (e *Ethereum) EventMux() *event.TypeMux { return e.eventMux } +func (e *Ethereum) Engine() consensus.Engine { return e.engine } +func (e *Ethereum) ChainDb() ethdb.Database { return e.chainDb } +func (e *Ethereum) IsListening() bool { return true } // Always listening +func (e *Ethereum) Downloader() *downloader.Downloader { return e.handler.downloader } +func (e *Ethereum) Synced() bool { return e.handler.synced.Load() } +func (e *Ethereum) SetSynced() { e.handler.enableSyncedFeatures() } +func (e *Ethereum) ArchiveMode() bool { return e.config.NoPruning } +func (e *Ethereum) BloomIndexer() *core.ChainIndexer { return e.bloomIndexer } +func (e *Ethereum) Merger() *consensus.Merger { return e.merger } +func (e *Ethereum) SyncMode() downloader.SyncMode { + mode, _ := e.handler.chainSync.modeAndLocalHead() return mode } // 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) - if s.config.SnapshotCache > 0 { - protos = append(protos, snap.MakeProtocols((*snapHandler)(s.handler), s.snapDialCandidates)...) +func (e *Ethereum) Protocols() []p2p.Protocol { + protos := eth.MakeProtocols((*ethHandler)(e.handler), e.networkID, e.ethDialCandidates) + if e.config.SnapshotCache > 0 { + protos = append(protos, snap.MakeProtocols((*snapHandler)(e.handler), e.snapDialCandidates)...) } return protos } // 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()) +func (e *Ethereum) Start() error { + eth.StartENRUpdater(e.blockchain, e.p2pServer.LocalNode()) // Start the bloom bits servicing goroutines - s.startBloomHandlers(params.BloomBitsBlocks) + e.startBloomHandlers(params.BloomBitsBlocks) // Regularly update shutdown marker - s.shutdownTracker.Start() + e.shutdownTracker.Start() // Figure out a max peers count based on the server limits - maxPeers := s.p2pServer.MaxPeers - if s.config.LightServ > 0 { - if s.config.LightPeers >= s.p2pServer.MaxPeers { - return fmt.Errorf("invalid peer config: light peer count (%d) >= total peer count (%d)", s.config.LightPeers, s.p2pServer.MaxPeers) + maxPeers := e.p2pServer.MaxPeers + if e.config.LightServ > 0 { + if e.config.LightPeers >= e.p2pServer.MaxPeers { + return fmt.Errorf("invalid peer config: light peer count (%d) >= total peer count (%d)", e.config.LightPeers, e.p2pServer.MaxPeers) } - maxPeers -= s.config.LightPeers + maxPeers -= e.config.LightPeers } // Start the networking layer and the light server if requested - s.handler.Start(maxPeers) + e.handler.Start(maxPeers) return nil } // Stop implements node.Lifecycle, terminating all internal goroutines used by the // Ethereum protocol. -func (s *Ethereum) Stop() error { +func (e *Ethereum) Stop() error { // Stop all the peer-related stuff first. - s.ethDialCandidates.Close() - s.snapDialCandidates.Close() - s.handler.Stop() + e.ethDialCandidates.Close() + e.snapDialCandidates.Close() + e.handler.Stop() // Then stop everything else. - s.bloomIndexer.Close() - close(s.closeBloomHandler) - s.txPool.Close() - s.miner.Close() - s.blockchain.Stop() - s.engine.Close() + e.bloomIndexer.Close() + close(e.closeBloomHandler) + e.txPool.Close() + e.miner.Close() + e.blockchain.Stop() + e.engine.Close() // Clean shutdown marker as the last thing before closing db - s.shutdownTracker.Stop() + e.shutdownTracker.Stop() - s.chainDb.Close() - s.eventMux.Stop() + e.chainDb.Close() + e.eventMux.Stop() return nil } diff --git a/eth/bloombits.go b/eth/bloombits.go index d02142e886..1099e2ac28 100644 --- a/eth/bloombits.go +++ b/eth/bloombits.go @@ -43,20 +43,20 @@ const ( // startBloomHandlers starts a batch of goroutines to accept bloom bit database // retrievals from possibly a range of filters and serving the data to satisfy. -func (s *Ethereum) startBloomHandlers(sectionSize uint64) { +func (e *Ethereum) startBloomHandlers(sectionSize uint64) { for i := 0; i < bloomServiceThreads; i++ { go func() { for { select { - case <-s.closeBloomHandler: + case <-e.closeBloomHandler: return - case request := <-s.bloomRequests: + case request := <-e.bloomRequests: task := <-request task.Bitsets = make([][]byte, len(task.Sections)) for i, section := range task.Sections { - head := rawdb.ReadCanonicalHash(s.chainDb, (section+1)*sectionSize-1) - if compVector, err := rawdb.ReadBloomBits(s.chainDb, task.Bit, section, head); err == nil { + head := rawdb.ReadCanonicalHash(e.chainDb, (section+1)*sectionSize-1) + if compVector, err := rawdb.ReadBloomBits(e.chainDb, task.Bit, section, head); err == nil { if blob, err := bitutil.DecompressBytes(compVector, int(sectionSize/8)); err == nil { task.Bitsets[i] = blob } else { diff --git a/eth/state_accessor.go b/eth/state_accessor.go index 31aeebff0f..3fe1c0a7eb 100644 --- a/eth/state_accessor.go +++ b/eth/state_accessor.go @@ -37,7 +37,7 @@ import ( // for releasing state. var noopReleaser = tracers.StateReleaseFunc(func() {}) -func (s *Ethereum) hashState(ctx context.Context, block *types.Block, reexec uint64, base *state.StateDB, readOnly bool, preferDisk bool) (statedb *state.StateDB, release tracers.StateReleaseFunc, err error) { +func (e *Ethereum) hashState(ctx context.Context, block *types.Block, reexec uint64, base *state.StateDB, readOnly bool, preferDisk bool) (statedb *state.StateDB, release tracers.StateReleaseFunc, err error) { var ( current *types.Block database state.Database @@ -51,10 +51,10 @@ func (s *Ethereum) hashState(ctx context.Context, block *types.Block, reexec uin // The state is available in live database, create a reference // on top to prevent garbage collection and return a release // function to deref it. - if statedb, err = s.blockchain.StateAt(block.Root()); err == nil { - s.blockchain.TrieDB().Reference(block.Root(), common.Hash{}) + if statedb, err = e.blockchain.StateAt(block.Root()); err == nil { + e.blockchain.TrieDB().Reference(block.Root(), common.Hash{}) return statedb, func() { - s.blockchain.TrieDB().Dereference(block.Root()) + e.blockchain.TrieDB().Dereference(block.Root()) }, nil } } @@ -67,7 +67,7 @@ func (s *Ethereum) hashState(ctx context.Context, block *types.Block, reexec uin // the internal junks created by tracing will be persisted into the disk. // TODO(rjl493456442), clean cache is disabled to prevent memory leak, // please re-enable it for better performance. - database = state.NewDatabaseWithConfig(s.chainDb, trie.HashDefaults) + database = state.NewDatabaseWithConfig(e.chainDb, trie.HashDefaults) if statedb, err = state.New(block.Root(), database, nil); err == nil { log.Info("Found disk backend for state trie", "root", block.Root(), "number", block.Number()) return statedb, noopReleaser, nil @@ -75,7 +75,7 @@ func (s *Ethereum) hashState(ctx context.Context, block *types.Block, reexec uin } // The optional base statedb is given, mark the start point as parent block statedb, database, triedb, report = base, base.Database(), base.Database().TrieDB(), false - current = s.blockchain.GetBlock(block.ParentHash(), block.NumberU64()-1) + current = e.blockchain.GetBlock(block.ParentHash(), block.NumberU64()-1) } else { // Otherwise, try to reexec blocks until we find a state or reach our limit current = block @@ -84,8 +84,8 @@ func (s *Ethereum) hashState(ctx context.Context, block *types.Block, reexec uin // the internal junks created by tracing will be persisted into the disk. // TODO(rjl493456442), clean cache is disabled to prevent memory leak, // please re-enable it for better performance. - triedb = trie.NewDatabase(s.chainDb, trie.HashDefaults) - database = state.NewDatabaseWithNodeDB(s.chainDb, triedb) + triedb = trie.NewDatabase(e.chainDb, trie.HashDefaults) + database = state.NewDatabaseWithNodeDB(e.chainDb, triedb) // If we didn't check the live database, do check state over ephemeral database, // otherwise we would rewind past a persisted block (specific corner case is @@ -104,7 +104,7 @@ func (s *Ethereum) hashState(ctx context.Context, block *types.Block, reexec uin if current.NumberU64() == 0 { return nil, nil, errors.New("genesis state is missing") } - parent := s.blockchain.GetBlock(current.ParentHash(), current.NumberU64()-1) + parent := e.blockchain.GetBlock(current.ParentHash(), current.NumberU64()-1) if parent == nil { return nil, nil, fmt.Errorf("missing block %v %d", current.ParentHash(), current.NumberU64()-1) } @@ -142,15 +142,15 @@ func (s *Ethereum) hashState(ctx context.Context, block *types.Block, reexec uin } // Retrieve the next block to regenerate and process it next := current.NumberU64() + 1 - if current = s.blockchain.GetBlockByNumber(next); current == nil { + if current = e.blockchain.GetBlockByNumber(next); current == nil { return nil, nil, fmt.Errorf("block #%d not found", next) } - _, _, _, err := s.blockchain.Processor().Process(current, statedb, vm.Config{}) + _, _, _, err := e.blockchain.Processor().Process(current, statedb, vm.Config{}) if err != nil { return nil, nil, fmt.Errorf("processing block %d failed: %v", current.NumberU64(), err) } // Finalize the state so any modifications are written to the trie - root, err := statedb.Commit(current.NumberU64(), s.blockchain.Config().IsEIP158(current.Number())) + root, err := statedb.Commit(current.NumberU64(), e.blockchain.Config().IsEIP158(current.Number())) if err != nil { return nil, nil, fmt.Errorf("stateAtBlock commit failed, number %d root %v: %w", current.NumberU64(), current.Root().Hex(), err) @@ -174,9 +174,9 @@ func (s *Ethereum) hashState(ctx context.Context, block *types.Block, reexec uin return statedb, func() { triedb.Dereference(block.Root()) }, nil } -func (s *Ethereum) pathState(block *types.Block) (*state.StateDB, func(), error) { +func (e *Ethereum) pathState(block *types.Block) (*state.StateDB, func(), error) { // Check if the requested state is available in the live chain. - statedb, err := s.blockchain.StateAt(block.Root()) + statedb, err := e.blockchain.StateAt(block.Root()) if err == nil { return statedb, noopReleaser, nil } @@ -208,27 +208,27 @@ func (s *Ethereum) pathState(block *types.Block) (*state.StateDB, func(), error) // - preferDisk: This arg can be used by the caller to signal that even though the 'base' is // provided, it would be preferable to start from a fresh state, if we have it // on disk. -func (s *Ethereum) stateAtBlock(ctx context.Context, block *types.Block, reexec uint64, base *state.StateDB, readOnly bool, preferDisk bool) (statedb *state.StateDB, release tracers.StateReleaseFunc, err error) { - if s.blockchain.TrieDB().Scheme() == rawdb.HashScheme { - return s.hashState(ctx, block, reexec, base, readOnly, preferDisk) +func (e *Ethereum) stateAtBlock(ctx context.Context, block *types.Block, reexec uint64, base *state.StateDB, readOnly bool, preferDisk bool) (statedb *state.StateDB, release tracers.StateReleaseFunc, err error) { + if e.blockchain.TrieDB().Scheme() == rawdb.HashScheme { + return e.hashState(ctx, block, reexec, base, readOnly, preferDisk) } - return s.pathState(block) + return e.pathState(block) } // stateAtTransaction returns the execution environment of a certain transaction. -func (s *Ethereum) stateAtTransaction(ctx context.Context, block *types.Block, txIndex int, reexec uint64) (*core.Message, vm.BlockContext, *state.StateDB, tracers.StateReleaseFunc, error) { +func (e *Ethereum) stateAtTransaction(ctx context.Context, block *types.Block, txIndex int, reexec uint64) (*core.Message, vm.BlockContext, *state.StateDB, tracers.StateReleaseFunc, error) { // Short circuit if it's genesis block. if block.NumberU64() == 0 { return nil, vm.BlockContext{}, nil, nil, errors.New("no transaction in genesis") } // Create the parent state database - parent := s.blockchain.GetBlock(block.ParentHash(), block.NumberU64()-1) + parent := e.blockchain.GetBlock(block.ParentHash(), block.NumberU64()-1) if parent == nil { return nil, vm.BlockContext{}, nil, nil, fmt.Errorf("parent %#x not found", block.ParentHash()) } // Lookup the statedb of parent block from the live database, // otherwise regenerate it on the flight. - statedb, release, err := s.stateAtBlock(ctx, parent, reexec, nil, true, false) + statedb, release, err := e.stateAtBlock(ctx, parent, reexec, nil, true, false) if err != nil { return nil, vm.BlockContext{}, nil, nil, err } @@ -236,17 +236,17 @@ func (s *Ethereum) stateAtTransaction(ctx context.Context, block *types.Block, t return nil, vm.BlockContext{}, statedb, release, nil } // Recompute transactions up to the target index. - signer := types.MakeSigner(s.blockchain.Config(), block.Number(), block.Time()) + signer := types.MakeSigner(e.blockchain.Config(), block.Number(), block.Time()) for idx, tx := range block.Transactions() { // Assemble the transaction call message and return if the requested offset msg, _ := core.TransactionToMessage(tx, signer, block.BaseFee()) txContext := core.NewEVMTxContext(msg) - context := core.NewEVMBlockContext(block.Header(), s.blockchain, nil) + context := core.NewEVMBlockContext(block.Header(), e.blockchain, nil) if idx == txIndex { return msg, context, statedb, release, nil } // Not yet the searched for transaction, execute on top of the current state - vmenv := vm.NewEVM(context, txContext, statedb, s.blockchain.Config(), vm.Config{}) + vmenv := vm.NewEVM(context, txContext, statedb, e.blockchain.Config(), vm.Config{}) statedb.SetTxContext(tx.Hash(), idx) if _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(tx.Gas())); err != nil { return nil, vm.BlockContext{}, nil, nil, fmt.Errorf("transaction %#x failed: %v", tx.Hash(), err)