2015-07-07 00:54:22 +00:00
|
|
|
// Copyright 2014 The go-ethereum Authors
|
2015-07-22 16:48:40 +00:00
|
|
|
// This file is part of the go-ethereum library.
|
2015-07-07 00:54:22 +00:00
|
|
|
//
|
2015-07-23 16:35:11 +00:00
|
|
|
// The go-ethereum library is free software: you can redistribute it and/or modify
|
2015-07-07 00:54:22 +00:00
|
|
|
// it under the terms of the GNU Lesser General Public License as published by
|
|
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
|
|
// (at your option) any later version.
|
|
|
|
//
|
2015-07-22 16:48:40 +00:00
|
|
|
// The go-ethereum library is distributed in the hope that it will be useful,
|
2015-07-07 00:54:22 +00:00
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
2015-07-22 16:48:40 +00:00
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
2015-07-07 00:54:22 +00:00
|
|
|
// GNU Lesser General Public License for more details.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the GNU Lesser General Public License
|
2015-07-22 16:48:40 +00:00
|
|
|
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
2015-07-07 00:54:22 +00:00
|
|
|
|
2015-07-07 03:08:16 +00:00
|
|
|
// Package eth implements the Ethereum protocol.
|
2014-12-14 18:03:24 +00:00
|
|
|
package eth
|
|
|
|
|
|
|
|
import (
|
2017-04-12 14:27:23 +00:00
|
|
|
"errors"
|
2015-01-04 13:20:16 +00:00
|
|
|
"fmt"
|
2017-05-16 19:07:27 +00:00
|
|
|
"math/big"
|
2017-04-12 14:27:23 +00:00
|
|
|
"runtime"
|
2016-05-12 17:32:04 +00:00
|
|
|
"sync"
|
2017-04-10 08:43:01 +00:00
|
|
|
"sync/atomic"
|
2020-12-11 14:56:00 +00:00
|
|
|
"time"
|
2014-12-14 18:03:24 +00:00
|
|
|
|
2015-02-26 12:22:09 +00:00
|
|
|
"github.com/ethereum/go-ethereum/accounts"
|
2015-03-18 12:00:01 +00:00
|
|
|
"github.com/ethereum/go-ethereum/common"
|
2017-04-12 14:27:23 +00:00
|
|
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
2017-04-04 22:16:29 +00:00
|
|
|
"github.com/ethereum/go-ethereum/consensus"
|
2017-04-10 10:24:12 +00:00
|
|
|
"github.com/ethereum/go-ethereum/consensus/clique"
|
2014-12-14 18:03:24 +00:00
|
|
|
"github.com/ethereum/go-ethereum/core"
|
2017-08-29 11:13:11 +00:00
|
|
|
"github.com/ethereum/go-ethereum/core/bloombits"
|
2018-05-07 11:35:06 +00:00
|
|
|
"github.com/ethereum/go-ethereum/core/rawdb"
|
all: bloom-filter based pruning mechanism (#21724)
* cmd, core, tests: initial state pruner
core: fix db inspector
cmd/geth: add verify-state
cmd/geth: add verification tool
core/rawdb: implement flatdb
cmd, core: fix rebase
core/state: use new contract code layout
core/state/pruner: avoid deleting genesis state
cmd/geth: add helper function
core, cmd: fix extract genesis
core: minor fixes
contracts: remove useless
core/state/snapshot: plugin stacktrie
core: polish
core/state/snapshot: iterate storage concurrently
core/state/snapshot: fix iteration
core: add comments
core/state/snapshot: polish code
core/state: polish
core/state/snapshot: rebase
core/rawdb: add comments
core/rawdb: fix tests
core/rawdb: improve tests
core/state/snapshot: fix concurrent iteration
core/state: run pruning during the recovery
core, trie: implement martin's idea
core, eth: delete flatdb and polish pruner
trie: fix import
core/state/pruner: add log
core/state/pruner: fix issues
core/state/pruner: don't read back
core/state/pruner: fix contract code write
core/state/pruner: check root node presence
cmd, core: polish log
core/state: use HEAD-127 as the target
core/state/snapshot: improve tests
cmd/geth: fix verification tool
cmd/geth: use HEAD as the verification default target
all: replace the bloomfilter with martin's fork
cmd, core: polish code
core, cmd: forcibly delete state root
core/state/pruner: add hash64
core/state/pruner: fix blacklist
core/state: remove blacklist
cmd, core: delete trie clean cache before pruning
cmd, core: fix lint
cmd, core: fix rebase
core/state: fix the special case for clique networks
core/state/snapshot: remove useless code
core/state/pruner: capping the snapshot after pruning
cmd, core, eth: fixes
core/rawdb: update db inspector
cmd/geth: polish code
core/state/pruner: fsync bloom filter
cmd, core: print warning log
core/state/pruner: adjust the parameters for bloom filter
cmd, core: create the bloom filter by size
core: polish
core/state/pruner: sanitize invalid bloomfilter size
cmd: address comments
cmd/geth: address comments
cmd/geth: address comment
core/state/pruner: address comments
core/state/pruner: rename homedir to datadir
cmd, core: address comments
core/state/pruner: address comment
core/state: address comments
core, cmd, tests: address comments
core: address comments
core/state/pruner: release the iterator after each commit
core/state/pruner: improve pruner
cmd, core: adjust bloom paramters
core/state/pruner: fix lint
core/state/pruner: fix tests
core: fix rebase
core/state/pruner: remove atomic rename
core/state/pruner: address comments
all: run go mod tidy
core/state/pruner: avoid false-positive for the middle state roots
core/state/pruner: add checks for middle roots
cmd/geth: replace crit with error
* core/state/pruner: fix lint
* core: drop legacy bloom filter
* core/state/snapshot: improve pruner
* core/state/snapshot: polish concurrent logs to report ETA vs. hashes
* core/state/pruner: add progress report for pruning and compaction too
* core: fix snapshot test API
* core/state: fix some pruning logs
* core/state/pruner: support recovering from bloom flush fail
Co-authored-by: Péter Szilágyi <peterke@gmail.com>
2021-02-08 11:16:30 +00:00
|
|
|
"github.com/ethereum/go-ethereum/core/state/pruner"
|
2015-03-13 17:34:43 +00:00
|
|
|
"github.com/ethereum/go-ethereum/core/types"
|
2017-01-17 11:19:50 +00:00
|
|
|
"github.com/ethereum/go-ethereum/core/vm"
|
2015-04-13 15:22:32 +00:00
|
|
|
"github.com/ethereum/go-ethereum/eth/downloader"
|
2021-02-05 12:51:15 +00:00
|
|
|
"github.com/ethereum/go-ethereum/eth/ethconfig"
|
2015-10-15 14:07:19 +00:00
|
|
|
"github.com/ethereum/go-ethereum/eth/filters"
|
2015-12-16 03:26:23 +00:00
|
|
|
"github.com/ethereum/go-ethereum/eth/gasprice"
|
2020-12-14 09:27:15 +00:00
|
|
|
"github.com/ethereum/go-ethereum/eth/protocols/eth"
|
|
|
|
"github.com/ethereum/go-ethereum/eth/protocols/snap"
|
2015-01-04 13:20:16 +00:00
|
|
|
"github.com/ethereum/go-ethereum/ethdb"
|
2014-12-14 18:03:24 +00:00
|
|
|
"github.com/ethereum/go-ethereum/event"
|
2015-12-16 03:26:23 +00:00
|
|
|
"github.com/ethereum/go-ethereum/internal/ethapi"
|
2017-02-22 12:10:07 +00:00
|
|
|
"github.com/ethereum/go-ethereum/log"
|
2015-02-17 11:24:51 +00:00
|
|
|
"github.com/ethereum/go-ethereum/miner"
|
2015-11-17 16:33:25 +00:00
|
|
|
"github.com/ethereum/go-ethereum/node"
|
2014-12-14 18:03:24 +00:00
|
|
|
"github.com/ethereum/go-ethereum/p2p"
|
2021-05-04 09:29:32 +00:00
|
|
|
"github.com/ethereum/go-ethereum/p2p/dnsdisc"
|
2020-02-13 13:38:30 +00:00
|
|
|
"github.com/ethereum/go-ethereum/p2p/enode"
|
2016-10-20 11:36:29 +00:00
|
|
|
"github.com/ethereum/go-ethereum/params"
|
2017-04-12 14:27:23 +00:00
|
|
|
"github.com/ethereum/go-ethereum/rlp"
|
2015-12-16 09:58:01 +00:00
|
|
|
"github.com/ethereum/go-ethereum/rpc"
|
2014-12-14 18:03:24 +00:00
|
|
|
)
|
|
|
|
|
2021-02-05 12:51:15 +00:00
|
|
|
// Config contains the configuration options of the ETH protocol.
|
|
|
|
// Deprecated: use ethconfig.Config instead.
|
|
|
|
type Config = ethconfig.Config
|
|
|
|
|
2016-06-30 10:03:26 +00:00
|
|
|
// Ethereum implements the Ethereum full node service.
|
|
|
|
type Ethereum struct {
|
2021-02-05 12:51:15 +00:00
|
|
|
config *ethconfig.Config
|
2017-09-05 16:18:28 +00:00
|
|
|
|
2015-10-19 14:08:17 +00:00
|
|
|
// Handlers
|
2020-12-14 09:27:15 +00:00
|
|
|
txPool *core.TxPool
|
|
|
|
blockchain *core.BlockChain
|
|
|
|
handler *handler
|
|
|
|
ethDialCandidates enode.Iterator
|
|
|
|
snapDialCandidates enode.Iterator
|
2017-09-05 16:18:28 +00:00
|
|
|
|
2015-12-16 03:26:23 +00:00
|
|
|
// DB interfaces
|
|
|
|
chainDb ethdb.Database // Block chain database
|
2014-12-14 18:03:24 +00:00
|
|
|
|
2015-12-16 03:26:23 +00:00
|
|
|
eventMux *event.TypeMux
|
2017-04-04 22:16:29 +00:00
|
|
|
engine consensus.Engine
|
2015-12-16 03:26:23 +00:00
|
|
|
accountManager *accounts.Manager
|
2015-05-26 12:17:43 +00:00
|
|
|
|
2020-03-27 13:03:20 +00:00
|
|
|
bloomRequests chan chan *bloombits.Retrieval // Channel receiving bloom data retrieval requests
|
|
|
|
bloomIndexer *core.ChainIndexer // Bloom indexer operating during block imports
|
|
|
|
closeBloomHandler chan struct{}
|
2017-08-18 19:52:20 +00:00
|
|
|
|
2018-05-09 07:59:00 +00:00
|
|
|
APIBackend *EthAPIBackend
|
2015-10-26 21:24:09 +00:00
|
|
|
|
2017-05-29 07:21:34 +00:00
|
|
|
miner *miner.Miner
|
|
|
|
gasPrice *big.Int
|
|
|
|
etherbase common.Address
|
2014-12-14 18:03:24 +00:00
|
|
|
|
2018-06-14 10:14:52 +00:00
|
|
|
networkID uint64
|
2015-12-16 03:26:23 +00:00
|
|
|
netRPCService *ethapi.PublicNetAPI
|
2017-05-29 07:21:34 +00:00
|
|
|
|
2020-08-03 17:40:46 +00:00
|
|
|
p2pServer *p2p.Server
|
2014-12-14 18:03:24 +00:00
|
|
|
|
2020-08-03 17:40:46 +00:00
|
|
|
lock sync.RWMutex // Protects the variadic fields (e.g. gas price and etherbase)
|
all: on-chain oracle checkpoint syncing (#19543)
* all: implement simple checkpoint syncing
cmd, les, node: remove callback mechanism
cmd, node: remove callback definition
les: simplify the registrar
les: expose checkpoint rpc services in the light client
les, light: don't store untrusted receipt
cmd, contracts, les: discard stale checkpoint
cmd, contracts/registrar: loose restriction of registeration
cmd, contracts: add replay-protection
all: off-chain multi-signature contract
params: deploy checkpoint contract for rinkeby
cmd/registrar: add raw signing mode for registrar
cmd/registrar, contracts/registrar, les: fixed messages
* cmd/registrar, contracts/registrar: fix lints
* accounts/abi/bind, les: address comments
* cmd, contracts, les, light, params: minor checkpoint sync cleanups
* cmd, eth, les, light: move checkpoint config to config file
* cmd, eth, les, params: address comments
* eth, les, params: address comments
* cmd: polish up the checkpoint admin CLI
* cmd, contracts, params: deploy new version contract
* cmd/checkpoint-admin: add another flag for clef mode signing
* cmd, contracts, les: rename and regen checkpoint oracle with abigen
2019-06-28 07:34:02 +00:00
|
|
|
}
|
|
|
|
|
2016-06-30 10:03:26 +00:00
|
|
|
// New creates a new Ethereum object (including the
|
2015-12-16 03:26:23 +00:00
|
|
|
// initialisation of the common Ethereum object)
|
2021-02-05 12:51:15 +00:00
|
|
|
func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
|
2018-08-23 10:02:36 +00:00
|
|
|
// Ensure configuration values are compatible and sane
|
2017-04-12 14:27:23 +00:00
|
|
|
if config.SyncMode == downloader.LightSync {
|
|
|
|
return nil, errors.New("can't run eth.Ethereum in light sync mode, use les.LightEthereum")
|
|
|
|
}
|
|
|
|
if !config.SyncMode.IsValid() {
|
|
|
|
return nil, fmt.Errorf("invalid sync mode %d", config.SyncMode)
|
|
|
|
}
|
2019-04-23 07:08:51 +00:00
|
|
|
if config.Miner.GasPrice == nil || config.Miner.GasPrice.Cmp(common.Big0) <= 0 {
|
2021-02-05 12:51:15 +00:00
|
|
|
log.Warn("Sanitizing invalid miner gas price", "provided", config.Miner.GasPrice, "updated", ethconfig.Defaults.Miner.GasPrice)
|
|
|
|
config.Miner.GasPrice = new(big.Int).Set(ethconfig.Defaults.Miner.GasPrice)
|
2018-08-23 10:02:36 +00:00
|
|
|
}
|
2019-02-05 10:49:59 +00:00
|
|
|
if config.NoPruning && config.TrieDirtyCache > 0 {
|
2020-05-06 10:01:01 +00:00
|
|
|
if config.SnapshotCache > 0 {
|
|
|
|
config.TrieCleanCache += config.TrieDirtyCache * 3 / 5
|
|
|
|
config.SnapshotCache += config.TrieDirtyCache * 2 / 5
|
|
|
|
} else {
|
|
|
|
config.TrieCleanCache += config.TrieDirtyCache
|
|
|
|
}
|
2019-02-05 10:49:59 +00:00
|
|
|
config.TrieDirtyCache = 0
|
|
|
|
}
|
|
|
|
log.Info("Allocated trie memory caches", "clean", common.StorageSize(config.TrieCleanCache)*1024*1024, "dirty", common.StorageSize(config.TrieDirtyCache)*1024*1024)
|
|
|
|
|
2021-03-26 17:30:10 +00:00
|
|
|
// Transfer mining-related config to the ethash config.
|
|
|
|
ethashConfig := config.Ethash
|
|
|
|
ethashConfig.NotifyFull = config.Miner.NotifyFull
|
|
|
|
|
2018-08-23 10:02:36 +00:00
|
|
|
// Assemble the Ethereum object
|
2021-03-22 18:06:30 +00:00
|
|
|
chainDb, err := stack.OpenDatabaseWithFreezer("chaindata", config.DatabaseCache, config.DatabaseHandles, config.DatabaseFreezer, "eth/db/chaindata/", false)
|
2015-01-04 13:20:16 +00:00
|
|
|
if err != nil {
|
2015-11-17 16:33:25 +00:00
|
|
|
return nil, err
|
2015-01-04 13:20:16 +00:00
|
|
|
}
|
2021-05-06 09:07:42 +00:00
|
|
|
chainConfig, genesisHash, genesisErr := core.SetupGenesisBlockWithOverride(chainDb, config.Genesis, config.OverrideLondon)
|
2017-03-02 13:03:33 +00:00
|
|
|
if _, ok := genesisErr.(*params.ConfigCompatError); genesisErr != nil && !ok {
|
|
|
|
return nil, genesisErr
|
2015-10-12 15:58:51 +00:00
|
|
|
}
|
2017-03-02 13:03:33 +00:00
|
|
|
log.Info("Initialised chain configuration", "config", chainConfig)
|
|
|
|
|
all: bloom-filter based pruning mechanism (#21724)
* cmd, core, tests: initial state pruner
core: fix db inspector
cmd/geth: add verify-state
cmd/geth: add verification tool
core/rawdb: implement flatdb
cmd, core: fix rebase
core/state: use new contract code layout
core/state/pruner: avoid deleting genesis state
cmd/geth: add helper function
core, cmd: fix extract genesis
core: minor fixes
contracts: remove useless
core/state/snapshot: plugin stacktrie
core: polish
core/state/snapshot: iterate storage concurrently
core/state/snapshot: fix iteration
core: add comments
core/state/snapshot: polish code
core/state: polish
core/state/snapshot: rebase
core/rawdb: add comments
core/rawdb: fix tests
core/rawdb: improve tests
core/state/snapshot: fix concurrent iteration
core/state: run pruning during the recovery
core, trie: implement martin's idea
core, eth: delete flatdb and polish pruner
trie: fix import
core/state/pruner: add log
core/state/pruner: fix issues
core/state/pruner: don't read back
core/state/pruner: fix contract code write
core/state/pruner: check root node presence
cmd, core: polish log
core/state: use HEAD-127 as the target
core/state/snapshot: improve tests
cmd/geth: fix verification tool
cmd/geth: use HEAD as the verification default target
all: replace the bloomfilter with martin's fork
cmd, core: polish code
core, cmd: forcibly delete state root
core/state/pruner: add hash64
core/state/pruner: fix blacklist
core/state: remove blacklist
cmd, core: delete trie clean cache before pruning
cmd, core: fix lint
cmd, core: fix rebase
core/state: fix the special case for clique networks
core/state/snapshot: remove useless code
core/state/pruner: capping the snapshot after pruning
cmd, core, eth: fixes
core/rawdb: update db inspector
cmd/geth: polish code
core/state/pruner: fsync bloom filter
cmd, core: print warning log
core/state/pruner: adjust the parameters for bloom filter
cmd, core: create the bloom filter by size
core: polish
core/state/pruner: sanitize invalid bloomfilter size
cmd: address comments
cmd/geth: address comments
cmd/geth: address comment
core/state/pruner: address comments
core/state/pruner: rename homedir to datadir
cmd, core: address comments
core/state/pruner: address comment
core/state: address comments
core, cmd, tests: address comments
core: address comments
core/state/pruner: release the iterator after each commit
core/state/pruner: improve pruner
cmd, core: adjust bloom paramters
core/state/pruner: fix lint
core/state/pruner: fix tests
core: fix rebase
core/state/pruner: remove atomic rename
core/state/pruner: address comments
all: run go mod tidy
core/state/pruner: avoid false-positive for the middle state roots
core/state/pruner: add checks for middle roots
cmd/geth: replace crit with error
* core/state/pruner: fix lint
* core: drop legacy bloom filter
* core/state/snapshot: improve pruner
* core/state/snapshot: polish concurrent logs to report ETA vs. hashes
* core/state/pruner: add progress report for pruning and compaction too
* core: fix snapshot test API
* core/state: fix some pruning logs
* core/state/pruner: support recovering from bloom flush fail
Co-authored-by: Péter Szilágyi <peterke@gmail.com>
2021-02-08 11:16:30 +00:00
|
|
|
if err := pruner.RecoverPruning(stack.ResolvePath(""), chainDb, stack.ResolvePath(config.TrieCleanCacheJournal)); err != nil {
|
|
|
|
log.Error("Failed to recover state", "error", err)
|
|
|
|
}
|
2016-06-30 10:03:26 +00:00
|
|
|
eth := &Ethereum{
|
2020-03-27 13:03:20 +00:00
|
|
|
config: config,
|
|
|
|
chainDb: chainDb,
|
2020-08-03 17:40:46 +00:00
|
|
|
eventMux: stack.EventMux(),
|
|
|
|
accountManager: stack.AccountManager(),
|
2021-03-26 17:30:10 +00:00
|
|
|
engine: ethconfig.CreateConsensusEngine(stack, chainConfig, ðashConfig, config.Miner.Notify, config.Miner.Noverify, chainDb),
|
2020-03-27 13:03:20 +00:00
|
|
|
closeBloomHandler: make(chan struct{}),
|
|
|
|
networkID: config.NetworkId,
|
|
|
|
gasPrice: config.Miner.GasPrice,
|
|
|
|
etherbase: config.Miner.Etherbase,
|
|
|
|
bloomRequests: make(chan chan *bloombits.Retrieval),
|
2021-02-05 12:51:15 +00:00
|
|
|
bloomIndexer: core.NewBloomIndexer(chainDb, params.BloomBitsBlocks, params.BloomConfirms),
|
2020-08-03 17:40:46 +00:00
|
|
|
p2pServer: stack.Server(),
|
2015-07-10 12:29:40 +00:00
|
|
|
}
|
2016-03-01 22:32:43 +00:00
|
|
|
|
2019-02-21 13:14:35 +00:00
|
|
|
bcVersion := rawdb.ReadDatabaseVersion(chainDb)
|
|
|
|
var dbVer = "<nil>"
|
|
|
|
if bcVersion != nil {
|
|
|
|
dbVer = fmt.Sprintf("%d", *bcVersion)
|
|
|
|
}
|
2020-12-14 09:27:15 +00:00
|
|
|
log.Info("Initialising Ethereum protocol", "network", config.NetworkId, "dbversion", dbVer)
|
2015-12-16 03:26:23 +00:00
|
|
|
|
2015-04-13 08:13:52 +00:00
|
|
|
if !config.SkipBcVersionCheck {
|
2019-01-11 11:49:12 +00:00
|
|
|
if bcVersion != nil && *bcVersion > core.BlockChainVersion {
|
|
|
|
return nil, fmt.Errorf("database version is v%d, Geth %s only supports v%d", *bcVersion, params.VersionWithMeta, core.BlockChainVersion)
|
2019-02-21 13:14:35 +00:00
|
|
|
} else if bcVersion == nil || *bcVersion < core.BlockChainVersion {
|
2021-05-03 12:42:43 +00:00
|
|
|
if bcVersion != nil { // only print warning on upgrade, not on init
|
|
|
|
log.Warn("Upgrade blockchain database version", "from", dbVer, "to", core.BlockChainVersion)
|
|
|
|
}
|
2019-02-21 13:14:35 +00:00
|
|
|
rawdb.WriteDatabaseVersion(chainDb, core.BlockChainVersion)
|
2015-04-13 08:13:52 +00:00
|
|
|
}
|
|
|
|
}
|
2018-02-05 16:40:32 +00:00
|
|
|
var (
|
2018-09-20 07:44:35 +00:00
|
|
|
vmConfig = vm.Config{
|
|
|
|
EnablePreimageRecording: config.EnablePreimageRecording,
|
|
|
|
}
|
2019-04-01 08:52:11 +00:00
|
|
|
cacheConfig = &core.CacheConfig{
|
|
|
|
TrieCleanLimit: config.TrieCleanCache,
|
2020-08-03 17:40:46 +00:00
|
|
|
TrieCleanJournal: stack.ResolvePath(config.TrieCleanCacheJournal),
|
2020-07-28 13:30:31 +00:00
|
|
|
TrieCleanRejournal: config.TrieCleanCacheRejournal,
|
2019-04-01 08:52:11 +00:00
|
|
|
TrieCleanNoPrefetch: config.NoPrefetch,
|
|
|
|
TrieDirtyLimit: config.TrieDirtyCache,
|
|
|
|
TrieDirtyDisabled: config.NoPruning,
|
|
|
|
TrieTimeLimit: config.TrieTimeout,
|
2019-11-26 07:48:29 +00:00
|
|
|
SnapshotLimit: config.SnapshotCache,
|
2020-11-18 09:51:33 +00:00
|
|
|
Preimages: config.Preimages,
|
Statediffing geth
* Write state diff to CSV (#2)
* port statediff from https://github.com/jpmorganchase/quorum/blob/9b7fd9af8082795eeeb6863d9746f12b82dd5078/statediff/statediff.go; minor fixes
* integrating state diff extracting, building, and persisting into geth processes
* work towards persisting created statediffs in ipfs; based off github.com/vulcanize/eth-block-extractor
* Add a state diff service
* Remove diff extractor from blockchain
* Update imports
* Move statediff on/off check to geth cmd config
* Update starting state diff service
* Add debugging logs for creating diff
* Add statediff extractor and builder tests and small refactoring
* Start to write statediff to a CSV
* Restructure statediff directory
* Pull CSV publishing methods into their own file
* Reformatting due to go fmt
* Add gomega to vendor dir
* Remove testing focuses
* Update statediff tests to use golang test pkg
instead of ginkgo
- builder_test
- extractor_test
- publisher_test
* Use hexutil.Encode instead of deprecated common.ToHex
* Remove OldValue from DiffBigInt and DiffUint64 fields
* Update builder test
* Remove old storage value from updated accounts
* Remove old values from created/deleted accounts
* Update publisher to account for only storing current account values
* Update service loop and fetching previous block
* Update testing
- remove statediff ginkgo test suite file
- move mocks to their own dir
* Updates per go fmt
* Updates to tests
* Pass statediff mode and path in through cli
* Return filename from publisher
* Remove some duplication in builder
* Remove code field from state diff output
this is the contract byte code, and it can still be obtained by querying
the db by the codeHash
* Consolidate acct diff structs for updated & updated/deleted accts
* Include block number in csv filename
* Clean up error logging
* Cleanup formatting, spelling, etc
* Address PR comments
* Add contract address and storage value to csv
* Refactor accumulating account row in csv publisher
* Add DiffStorage struct
* Add storage key to csv
* Address PR comments
* Fix publisher to include rows for accounts that don't have store updates
* Update builder test after merging in release/1.8
* Update test contract to include storage on contract intialization
- so that we're able to test that storage diffing works for created and
deleted accounts (not just updated accounts).
* Factor out a common trie iterator method in builder
* Apply goimports to statediff
* Apply gosimple changes to statediff
* Gracefully exit geth command(#4)
* Statediff for full node (#6)
* Open a trie from the in-memory database
* Use a node's LeafKey as an identifier instead of the address
It was proving difficult to find look the address up from a given path
with a full node (sometimes the value wouldn't exist in the disk db).
So, instead, for now we are using the node's LeafKey with is a Keccak256
hash of the address, so if we know the address we can figure out which
LeafKey it matches up to.
* Make sure that statediff has been processed before pruning
* Use blockchain stateCache.OpenTrie for storage diffs
* Clean up log lines and remove unnecessary fields from builder
* Apply go fmt changes
* Add a sleep to the blockchain test
* refactoring/reorganizing packages
* refactoring statediff builder and types and adjusted to relay proofs and paths (still need to make this optional)
* refactoring state diff service and adding api which allows for streaming state diff payloads over an rpc websocket subscription
* make proofs and paths optional + compress service loop into single for loop (may be missing something here)
* option to process intermediate nodes
* make state diff rlp serializable
* cli parameter to limit statediffing to select account addresses + test
* review fixes and fixes for issues ran into in integration
* review fixes; proper method signature for api; adjust service so that statediff processing is halted/paused until there is at least one subscriber listening for the results
* adjust buffering to improve stability; doc.go; fix notifier
err handling
* relay receipts with the rest of the data + review fixes/changes
* rpc method to get statediff at specific block; requires archival node or the block be within the pruning range
* fix linter issues
* include total difficulty to the payload
* fix state diff builder: emit actual leaf nodes instead of value nodes; diff on the leaf not on the value; emit correct path for intermediate nodes
* adjust statediff builder tests to changes and extend to test intermediate nodes; golint
* add genesis block to test; handle block 0 in StateDiffAt
* rlp files for mainnet blocks 0-3, for tests
* builder test on mainnet blocks
* common.BytesToHash(path) => crypto.Keaccak256(hash) in builder; BytesToHash produces same hash for e.g. []byte{} and []byte{\x00} - prefix \x00 steps are inconsequential to the hash result
* complete tests for early mainnet blocks
* diff type for representing deleted accounts
* fix builder so that we handle account deletions properly and properly diff storage when an account is moved to a new path; update params
* remove cli params; moving them to subscriber defined
* remove unneeded bc methods
* update service and api; statediffing params are now defined by user through api rather than by service provider by cli
* update top level tests
* add ability to watch specific storage slots (leaf keys) only
* comments; explain logic
* update mainnet blocks test
* update api_test.go
* storage leafkey filter test
* cleanup chain maker
* adjust chain maker for tests to add an empty account in block1 and switch to EIP-158 afterwards (now we just need to generate enough accounts until one causes the empty account to be touched and removed post-EIP-158 so we can simulate and test that process...); also added 2 new blocks where more contract storage is set and old slots are set to zero so they are removed so we can test that
* found an account whose creation causes the empty account to be moved to a new path; this should count as 'touching; the empty account and cause it to be removed according to eip-158... but it doesn't
* use new contract in unit tests that has self-destruct ability, so we can test eip-158 since simply moving an account to new path doesn't count as 'touchin' it
* handle storage deletions
* tests for eip-158 account removal and storage value deletions; there is one edge case left to test where we remove 1 account when only two exist such that the remaining account is moved up and replaces the root branch node
* finish testing known edge cases
* add endpoint to fetch all state and storage nodes at a given blockheight; useful for generating a recent atate cache/snapshot that we can diff forward from rather than needing to collect all diffs from genesis
* test for state trie builder
* if statediffing is on, lock tries in triedb until the statediffing service signals they are done using them
* fix mock blockchain; golint; bump patch
* increase maxRequestContentLength; bump patch
* log the sizes of the state objects we are sending
* CI build (#20)
* CI: run build on PR and on push to master
* CI: debug building geth
* CI: fix coping file
* CI: fix coping file v2
* CI: temporary upload file to release asset
* CI: get release upload_url by tag, upload asset to current relase
* CI: fix tag name
* fix ci build on statediff_at_anyblock-1.9.11 branch
* fix publishing assets in release
* use context deadline for timeout in eth_call
* collect and emit codehash=>code mappings for state objects
* subscription endpoint for retrieving all the codehash=>code mappings that exist at provided height
* Implement WriteStateDiffAt
* Writes state diffs directly to postgres
* Adds CLI flags to configure PG
* Refactors builder output with callbacks
* Copies refactored postgres handling code from ipld-eth-indexer
* rename PostgresCIDWriter.{index->upsert}*
* go.mod update
* rm unused
* cleanup
* output code & codehash iteratively
* had to rf some types for this
* prometheus metrics output
* duplicate recent eth-indexer changes
* migrations and metrics...
* [wip] prom.Init() here? another CLI flag?
* tidy & DRY
* statediff WriteLoop service + CLI flag
* [wip] update test mocks
* todo - do something meaningful to test write loop
* logging
* use geth log
* port tests to go testing
* drop ginkgo/gomega
* fix and cleanup tests
* fail before defer statement
* delete vendor/ dir
* fixes after rebase onto 1.9.23
* fix API registration
* use golang 1.15.5 version (#34)
* bump version meta; add 0.0.11 branch to actions
* bump version meta; update github actions workflows
* statediff: refactor metrics
* Remove redundant statediff/indexer/prom tooling and use existing
prometheus integration.
* "indexer" namespace for metrics
* add reporting loop for db metrics
* doc
* metrics for statediff stats
* metrics namespace/subsystem = statediff/{indexer,service}
* statediff: use a worker pool (for direct writes)
* fix test
* fix chain event subscription
* log tweaks
* func name
* unused import
* intermediate chain event channel for metrics
* update github actions; linting
* add poststate and status to receipt ipld indexes
* stateDiffFor endpoints for fetching or writing statediff object by blockhash; bump statediff version
* fixes after rebase on to v1.10.1
* update github actions and version meta; go fmt
* add leaf key to removed 'nodes'
* include Postgres migrations and schema
* service documentation
* touching up
update github actions after rebase
fix connection leak (misplaced defer) and perform proper rollback on errs
improve error logging; handle PushBlock internal err
* build docker image and publish it to Docker Hub on release
* add access list tx to unit tests
* MarshalBinary and UnmarshalBinary methods for receipt
* fix error caused by 2718 by using MarshalBinary instead of EncodeRLP methods
* ipld encoding/decoding tests
* update TxModel; add AccessListElementModel
* index tx type and access lists
* add access list metrics
* unit tests for tx_type and access list table
* unit tests for receipt marshal/unmarshal binary methods
* improve documentation of the encoding methods
* fix issue identified in linting
update github actions and version meta after rebase
unit test that fails undeterministically on eip2930 txs, giving same error we are seeing in prod
fix bug
Include genesis block state diff.
Fix linting issue.
documentation on versioning, rebasing, releasing; bump version meta
Add geth and statediff unit test to CI.
Set pgpassword in env.
Added comments.
Add new major branch to github action.
Fix failing test.
Fix lint errors.
Add support for Dynamic txn(EIP-1559).
Update version meta to 0.0.24
Verify block base fee in test.
Fix base_fee type and add backward compatible test.
Remove type definition for AccessListElementModel
Change basefee to int64/bigint.
block and uncle reward in PoA network = 0 (#87)
* in PoA networks there is no block and uncle rewards
* bump meta version
(cherry picked from commit b64ca14689689178b78f915c855fe75010d886c7)
Use Ropsten to test block reward.
Add Makefile target to build static linux binaries.
Strip symbol tables from static binaries.
Fix block_fee to support NULL values.
bump version meta.
Add new major branch to github action.
Add new major branch to github action.
Add new major branch to github action.
2019-01-28 21:31:01 +00:00
|
|
|
StateDiffing: config.Diffing,
|
2019-04-01 08:52:11 +00:00
|
|
|
}
|
2018-02-05 16:40:32 +00:00
|
|
|
)
|
2020-05-11 15:58:43 +00:00
|
|
|
eth.blockchain, err = core.NewBlockChain(chainDb, cacheConfig, chainConfig, eth.engine, vmConfig, eth.shouldPreserve, &config.TxLookupLimit)
|
2015-06-08 10:12:13 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2017-03-02 13:03:33 +00:00
|
|
|
// Rewind the chain in case of an incompatible config upgrade.
|
|
|
|
if compat, ok := genesisErr.(*params.ConfigCompatError); ok {
|
|
|
|
log.Warn("Rewinding chain to upgrade configuration", "err", compat)
|
|
|
|
eth.blockchain.SetHead(compat.RewindTo)
|
2018-05-07 11:35:06 +00:00
|
|
|
rawdb.WriteChainConfig(chainDb, genesisHash, chainConfig)
|
2017-03-02 13:03:33 +00:00
|
|
|
}
|
2017-10-24 13:19:09 +00:00
|
|
|
eth.bloomIndexer.Start(eth.blockchain)
|
2017-03-02 13:03:33 +00:00
|
|
|
|
2017-07-28 13:09:39 +00:00
|
|
|
if config.TxPool.Journal != "" {
|
2020-08-03 17:40:46 +00:00
|
|
|
config.TxPool.Journal = stack.ResolvePath(config.TxPool.Journal)
|
2017-07-28 13:09:39 +00:00
|
|
|
}
|
2019-03-27 11:23:08 +00:00
|
|
|
eth.txPool = core.NewTxPool(config.TxPool, chainConfig, eth.blockchain)
|
2015-06-15 09:33:08 +00:00
|
|
|
|
2019-05-13 12:28:01 +00:00
|
|
|
// Permit the downloader to use the trie cache allowance during fast sync
|
2019-11-26 07:48:29 +00:00
|
|
|
cacheLimit := cacheConfig.TrieCleanLimit + cacheConfig.TrieDirtyLimit + cacheConfig.SnapshotLimit
|
all: on-chain oracle checkpoint syncing (#19543)
* all: implement simple checkpoint syncing
cmd, les, node: remove callback mechanism
cmd, node: remove callback definition
les: simplify the registrar
les: expose checkpoint rpc services in the light client
les, light: don't store untrusted receipt
cmd, contracts, les: discard stale checkpoint
cmd, contracts/registrar: loose restriction of registeration
cmd, contracts: add replay-protection
all: off-chain multi-signature contract
params: deploy checkpoint contract for rinkeby
cmd/registrar: add raw signing mode for registrar
cmd/registrar, contracts/registrar, les: fixed messages
* cmd/registrar, contracts/registrar: fix lints
* accounts/abi/bind, les: address comments
* cmd, contracts, les, light, params: minor checkpoint sync cleanups
* cmd, eth, les, light: move checkpoint config to config file
* cmd, eth, les, params: address comments
* eth, les, params: address comments
* cmd: polish up the checkpoint admin CLI
* cmd, contracts, params: deploy new version contract
* cmd/checkpoint-admin: add another flag for clef mode signing
* cmd, contracts, les: rename and regen checkpoint oracle with abigen
2019-06-28 07:34:02 +00:00
|
|
|
checkpoint := config.Checkpoint
|
|
|
|
if checkpoint == nil {
|
|
|
|
checkpoint = params.TrustedCheckpoints[genesisHash]
|
|
|
|
}
|
2020-12-14 09:27:15 +00:00
|
|
|
if eth.handler, err = newHandler(&handlerConfig{
|
|
|
|
Database: chainDb,
|
|
|
|
Chain: eth.blockchain,
|
|
|
|
TxPool: eth.txPool,
|
|
|
|
Network: config.NetworkId,
|
|
|
|
Sync: config.SyncMode,
|
|
|
|
BloomCache: uint64(cacheLimit),
|
|
|
|
EventMux: eth.eventMux,
|
|
|
|
Checkpoint: checkpoint,
|
|
|
|
Whitelist: config.Whitelist,
|
|
|
|
}); err != nil {
|
2015-09-01 14:35:14 +00:00
|
|
|
return nil, err
|
|
|
|
}
|
2021-04-16 19:29:22 +00:00
|
|
|
|
2019-04-23 07:08:51 +00:00
|
|
|
eth.miner = miner.New(eth, &config.Miner, chainConfig, eth.EventMux(), eth.engine, eth.isLocalBlock)
|
|
|
|
eth.miner.SetExtra(makeExtraData(config.Miner.ExtraData))
|
2015-07-25 15:33:56 +00:00
|
|
|
|
2021-02-23 12:09:19 +00:00
|
|
|
eth.APIBackend = &EthAPIBackend{stack.Config().ExtRPCEnabled(), stack.Config().AllowUnprotectedTxs, eth, nil}
|
|
|
|
if eth.APIBackend.allowUnprotectedTxs {
|
|
|
|
log.Info("Unprotected transactions allowed")
|
|
|
|
}
|
2017-04-12 14:27:23 +00:00
|
|
|
gpoParams := config.GPO
|
|
|
|
if gpoParams.Default == nil {
|
2019-04-23 07:08:51 +00:00
|
|
|
gpoParams.Default = config.Miner.GasPrice
|
2015-12-16 03:26:23 +00:00
|
|
|
}
|
2020-01-09 11:26:37 +00:00
|
|
|
eth.APIBackend.gpo = gasprice.NewOracle(eth.APIBackend, gpoParams)
|
2015-12-16 03:26:23 +00:00
|
|
|
|
2021-05-04 09:29:32 +00:00
|
|
|
// Setup DNS discovery iterators.
|
|
|
|
dnsclient := dnsdisc.NewClient(dnsdisc.Config{})
|
|
|
|
eth.ethDialCandidates, err = dnsclient.NewIterator(eth.config.EthDiscoveryURLs...)
|
2020-12-14 09:27:15 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2021-05-04 09:29:32 +00:00
|
|
|
eth.snapDialCandidates, err = dnsclient.NewIterator(eth.config.SnapDiscoveryURLs...)
|
2020-02-13 13:38:30 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2021-05-04 09:29:32 +00:00
|
|
|
|
2020-08-03 17:40:46 +00:00
|
|
|
// Start the RPC service
|
2020-12-23 12:43:22 +00:00
|
|
|
eth.netRPCService = ethapi.NewPublicNetAPI(eth.p2pServer, config.NetworkId)
|
2020-08-03 17:40:46 +00:00
|
|
|
|
|
|
|
// Register the backend on the node
|
|
|
|
stack.RegisterAPIs(eth.APIs())
|
|
|
|
stack.RegisterProtocols(eth.Protocols())
|
|
|
|
stack.RegisterLifecycle(eth)
|
2020-12-11 14:56:00 +00:00
|
|
|
// Check for unclean shutdown
|
|
|
|
if uncleanShutdowns, discards, err := rawdb.PushUncleanShutdownMarker(chainDb); err != nil {
|
|
|
|
log.Error("Could not update unclean-shutdown-marker list", "error", err)
|
|
|
|
} else {
|
|
|
|
if discards > 0 {
|
|
|
|
log.Warn("Old unclean shutdowns found", "count", discards)
|
|
|
|
}
|
|
|
|
for _, tstamp := range uncleanShutdowns {
|
|
|
|
t := time.Unix(int64(tstamp), 0)
|
|
|
|
log.Warn("Unclean shutdown detected", "booted", t,
|
|
|
|
"age", common.PrettyAge(t))
|
|
|
|
}
|
|
|
|
}
|
2014-12-14 18:03:24 +00:00
|
|
|
return eth, nil
|
|
|
|
}
|
|
|
|
|
2017-04-12 14:27:23 +00:00
|
|
|
func makeExtraData(extra []byte) []byte {
|
|
|
|
if len(extra) == 0 {
|
|
|
|
// create default extradata
|
|
|
|
extra, _ = rlp.EncodeToBytes([]interface{}{
|
|
|
|
uint(params.VersionMajor<<16 | params.VersionMinor<<8 | params.VersionPatch),
|
|
|
|
"geth",
|
|
|
|
runtime.Version(),
|
|
|
|
runtime.GOOS,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
if uint64(len(extra)) > params.MaximumExtraDataSize {
|
|
|
|
log.Warn("Miner extra data exceed limit", "extra", hexutil.Bytes(extra), "limit", params.MaximumExtraDataSize)
|
|
|
|
extra = nil
|
|
|
|
}
|
|
|
|
return extra
|
|
|
|
}
|
|
|
|
|
2018-05-24 12:55:20 +00:00
|
|
|
// APIs return the collection of RPC services the ethereum package offers.
|
2015-10-15 14:07:19 +00:00
|
|
|
// NOTE, some of these services probably need to be moved to somewhere else.
|
2016-06-30 10:03:26 +00:00
|
|
|
func (s *Ethereum) APIs() []rpc.API {
|
2018-05-09 07:59:00 +00:00
|
|
|
apis := ethapi.GetAPIs(s.APIBackend)
|
2017-04-04 22:16:29 +00:00
|
|
|
|
|
|
|
// Append any APIs exposed explicitly by the consensus engine
|
|
|
|
apis = append(apis, s.engine.APIs(s.BlockChain())...)
|
|
|
|
|
|
|
|
// Append all the local APIs and return
|
|
|
|
return append(apis, []rpc.API{
|
2015-10-15 14:07:19 +00:00
|
|
|
{
|
|
|
|
Namespace: "eth",
|
|
|
|
Version: "1.0",
|
2016-06-30 10:03:26 +00:00
|
|
|
Service: NewPublicEthereumAPI(s),
|
2015-10-15 14:07:19 +00:00
|
|
|
Public: true,
|
|
|
|
}, {
|
|
|
|
Namespace: "eth",
|
|
|
|
Version: "1.0",
|
2016-02-09 14:03:04 +00:00
|
|
|
Service: NewPublicMinerAPI(s),
|
2015-10-15 14:07:19 +00:00
|
|
|
Public: true,
|
|
|
|
}, {
|
|
|
|
Namespace: "eth",
|
|
|
|
Version: "1.0",
|
2020-12-14 09:27:15 +00:00
|
|
|
Service: downloader.NewPublicDownloaderAPI(s.handler.downloader, s.eventMux),
|
2015-10-15 14:07:19 +00:00
|
|
|
Public: true,
|
|
|
|
}, {
|
|
|
|
Namespace: "miner",
|
|
|
|
Version: "1.0",
|
|
|
|
Service: NewPrivateMinerAPI(s),
|
|
|
|
Public: false,
|
|
|
|
}, {
|
|
|
|
Namespace: "eth",
|
|
|
|
Version: "1.0",
|
2021-01-21 11:17:10 +00:00
|
|
|
Service: filters.NewPublicFilterAPI(s.APIBackend, false, 5*time.Minute),
|
2015-10-15 14:07:19 +00:00
|
|
|
Public: true,
|
2015-12-04 18:56:11 +00:00
|
|
|
}, {
|
|
|
|
Namespace: "admin",
|
|
|
|
Version: "1.0",
|
2016-06-30 10:03:26 +00:00
|
|
|
Service: NewPrivateAdminAPI(s),
|
2015-12-04 18:56:11 +00:00
|
|
|
}, {
|
|
|
|
Namespace: "debug",
|
|
|
|
Version: "1.0",
|
2016-06-30 10:03:26 +00:00
|
|
|
Service: NewPublicDebugAPI(s),
|
2015-12-04 18:56:11 +00:00
|
|
|
Public: true,
|
|
|
|
}, {
|
|
|
|
Namespace: "debug",
|
|
|
|
Version: "1.0",
|
2019-03-27 11:23:08 +00:00
|
|
|
Service: NewPrivateDebugAPI(s),
|
2015-12-16 09:58:01 +00:00
|
|
|
}, {
|
|
|
|
Namespace: "net",
|
|
|
|
Version: "1.0",
|
|
|
|
Service: s.netRPCService,
|
|
|
|
Public: true,
|
2015-10-15 14:07:19 +00:00
|
|
|
},
|
2015-12-16 03:26:23 +00:00
|
|
|
}...)
|
2015-10-15 14:07:19 +00:00
|
|
|
}
|
|
|
|
|
2016-06-30 10:03:26 +00:00
|
|
|
func (s *Ethereum) ResetWithGenesisBlock(gb *types.Block) {
|
2015-08-31 15:09:50 +00:00
|
|
|
s.blockchain.ResetWithGenesisBlock(gb)
|
2015-03-13 17:34:43 +00:00
|
|
|
}
|
|
|
|
|
2016-06-30 10:03:26 +00:00
|
|
|
func (s *Ethereum) Etherbase() (eb common.Address, err error) {
|
2017-05-29 07:21:34 +00:00
|
|
|
s.lock.RLock()
|
|
|
|
etherbase := s.etherbase
|
|
|
|
s.lock.RUnlock()
|
|
|
|
|
|
|
|
if etherbase != (common.Address{}) {
|
|
|
|
return etherbase, nil
|
2017-01-24 09:49:20 +00:00
|
|
|
}
|
2017-02-07 10:47:34 +00:00
|
|
|
if wallets := s.AccountManager().Wallets(); len(wallets) > 0 {
|
|
|
|
if accounts := wallets[0].Accounts(); len(accounts) > 0 {
|
2017-12-09 22:42:23 +00:00
|
|
|
etherbase := accounts[0].Address
|
|
|
|
|
|
|
|
s.lock.Lock()
|
|
|
|
s.etherbase = etherbase
|
|
|
|
s.lock.Unlock()
|
|
|
|
|
|
|
|
log.Info("Etherbase automatically configured", "address", etherbase)
|
|
|
|
return etherbase, nil
|
2017-02-07 10:47:34 +00:00
|
|
|
}
|
2015-03-26 21:49:22 +00:00
|
|
|
}
|
2017-12-09 22:42:23 +00:00
|
|
|
return common.Address{}, fmt.Errorf("etherbase must be explicitly specified")
|
2015-03-26 21:49:22 +00:00
|
|
|
}
|
|
|
|
|
2018-09-20 17:02:15 +00:00
|
|
|
// isLocalBlock checks whether the specified block is mined
|
|
|
|
// by local miner accounts.
|
2018-09-20 12:09:30 +00:00
|
|
|
//
|
2018-09-20 17:02:15 +00:00
|
|
|
// We regard two types of accounts as local miner account: etherbase
|
|
|
|
// and accounts specified via `txpool.locals` flag.
|
|
|
|
func (s *Ethereum) isLocalBlock(block *types.Block) bool {
|
|
|
|
author, err := s.engine.Author(block.Header())
|
|
|
|
if err != nil {
|
|
|
|
log.Warn("Failed to retrieve block author", "number", block.NumberU64(), "hash", block.Hash(), "err", err)
|
|
|
|
return false
|
|
|
|
}
|
2018-09-20 12:09:30 +00:00
|
|
|
// Check whether the given address is etherbase.
|
|
|
|
s.lock.RLock()
|
|
|
|
etherbase := s.etherbase
|
|
|
|
s.lock.RUnlock()
|
2018-09-20 17:02:15 +00:00
|
|
|
if author == etherbase {
|
2018-09-20 12:09:30 +00:00
|
|
|
return true
|
|
|
|
}
|
|
|
|
// Check whether the given address is specified by `txpool.local`
|
|
|
|
// CLI flag.
|
|
|
|
for _, account := range s.config.TxPool.Locals {
|
2018-09-20 17:02:15 +00:00
|
|
|
if account == author {
|
2018-09-20 12:09:30 +00:00
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2018-09-20 17:02:15 +00:00
|
|
|
// 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(block *types.Block) bool {
|
|
|
|
// The reason we need to disable the self-reorg preserving for clique
|
|
|
|
// is it can be probable to introduce a deadlock.
|
|
|
|
//
|
|
|
|
// e.g. If there are 7 available signers
|
|
|
|
//
|
|
|
|
// r1 A
|
|
|
|
// r2 B
|
|
|
|
// r3 C
|
|
|
|
// r4 D
|
|
|
|
// r5 A [X] F G
|
|
|
|
// r6 [X]
|
|
|
|
//
|
|
|
|
// In the round5, the inturn signer E is offline, so the worst case
|
|
|
|
// 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 {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
return s.isLocalBlock(block)
|
|
|
|
}
|
|
|
|
|
2018-05-03 12:15:33 +00:00
|
|
|
// SetEtherbase sets the mining reward address.
|
|
|
|
func (s *Ethereum) SetEtherbase(etherbase common.Address) {
|
|
|
|
s.lock.Lock()
|
|
|
|
s.etherbase = etherbase
|
|
|
|
s.lock.Unlock()
|
2017-05-29 07:21:34 +00:00
|
|
|
|
2018-05-03 12:15:33 +00:00
|
|
|
s.miner.SetEtherbase(etherbase)
|
2015-07-07 08:32:05 +00:00
|
|
|
}
|
|
|
|
|
2018-08-23 10:02:36 +00:00
|
|
|
// 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(threads int) error {
|
|
|
|
// Update the thread count within the consensus engine
|
|
|
|
type threaded interface {
|
|
|
|
SetThreads(threads int)
|
2016-10-28 17:05:01 +00:00
|
|
|
}
|
2018-08-23 10:02:36 +00:00
|
|
|
if th, ok := s.engine.(threaded); ok {
|
|
|
|
log.Info("Updated mining threads", "threads", threads)
|
|
|
|
if threads == 0 {
|
|
|
|
threads = -1 // Disable the miner from within
|
2017-04-10 10:24:12 +00:00
|
|
|
}
|
2018-08-23 10:02:36 +00:00
|
|
|
th.SetThreads(threads)
|
2017-04-10 10:24:12 +00:00
|
|
|
}
|
2018-08-23 10:02:36 +00:00
|
|
|
// If the miner was not running, initialize it
|
|
|
|
if !s.IsMining() {
|
|
|
|
// Propagate the initial price point to the transaction pool
|
|
|
|
s.lock.RLock()
|
|
|
|
price := s.gasPrice
|
|
|
|
s.lock.RUnlock()
|
|
|
|
s.txPool.SetGasPrice(price)
|
|
|
|
|
2018-09-20 12:09:30 +00:00
|
|
|
// Configure the local mining address
|
2018-08-23 10:02:36 +00:00
|
|
|
eb, err := s.Etherbase()
|
|
|
|
if err != nil {
|
|
|
|
log.Error("Cannot start mining without etherbase", "err", err)
|
|
|
|
return fmt.Errorf("etherbase missing: %v", err)
|
|
|
|
}
|
|
|
|
if clique, ok := s.engine.(*clique.Clique); ok {
|
|
|
|
wallet, err := s.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)
|
|
|
|
}
|
accounts, eth, clique, signer: support for external signer API (#18079)
* accounts, eth, clique: implement external backend + move sighash calc to backend
* signer: implement account_Version on external API
* accounts/external: enable ipc, add copyright
* accounts, internal, signer: formatting
* node: go fmt
* flags: disallow --dev in combo with --externalsigner
* accounts: remove clique-specific signing method, replace with more generic
* accounts, consensus: formatting + fix error in tests
* signer/core: remove (test-) import cycle
* clique: remove unused import
* accounts: remove CliqueHash and avoid dependency on package crypto
* consensus/clique: unduplicate header encoding
2019-02-05 10:23:57 +00:00
|
|
|
clique.Authorize(eb, wallet.SignData)
|
2018-08-23 10:02:36 +00:00
|
|
|
}
|
|
|
|
// If mining is started, we can disable the transaction rejection mechanism
|
|
|
|
// introduced to speed sync times.
|
2020-12-14 09:27:15 +00:00
|
|
|
atomic.StoreUint32(&s.handler.acceptTxs, 1)
|
2018-08-23 10:02:36 +00:00
|
|
|
|
|
|
|
go s.miner.Start(eb)
|
2017-04-10 08:43:01 +00:00
|
|
|
}
|
2016-10-28 17:05:01 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2018-08-23 10:02:36 +00:00
|
|
|
// StopMining terminates the miner, both at the consensus engine level as well as
|
|
|
|
// at the block creation level.
|
|
|
|
func (s *Ethereum) StopMining() {
|
|
|
|
// Update the thread count within the consensus engine
|
|
|
|
type threaded interface {
|
|
|
|
SetThreads(threads int)
|
|
|
|
}
|
|
|
|
if th, ok := s.engine.(threaded); ok {
|
|
|
|
th.SetThreads(-1)
|
|
|
|
}
|
|
|
|
// Stop the block creating itself
|
|
|
|
s.miner.Stop()
|
|
|
|
}
|
|
|
|
|
2016-06-30 10:03:26 +00:00
|
|
|
func (s *Ethereum) IsMining() bool { return s.miner.Mining() }
|
|
|
|
func (s *Ethereum) Miner() *miner.Miner { return s.miner }
|
|
|
|
|
|
|
|
func (s *Ethereum) AccountManager() *accounts.Manager { return s.accountManager }
|
|
|
|
func (s *Ethereum) BlockChain() *core.BlockChain { return s.blockchain }
|
|
|
|
func (s *Ethereum) TxPool() *core.TxPool { return s.txPool }
|
|
|
|
func (s *Ethereum) EventMux() *event.TypeMux { return s.eventMux }
|
2017-04-04 22:16:29 +00:00
|
|
|
func (s *Ethereum) Engine() consensus.Engine { return s.engine }
|
2016-06-30 10:03:26 +00:00
|
|
|
func (s *Ethereum) ChainDb() ethdb.Database { return s.chainDb }
|
|
|
|
func (s *Ethereum) IsListening() bool { return true } // Always listening
|
2020-12-14 09:27:15 +00:00
|
|
|
func (s *Ethereum) Downloader() *downloader.Downloader { return s.handler.downloader }
|
|
|
|
func (s *Ethereum) Synced() bool { return atomic.LoadUint32(&s.handler.acceptTxs) == 1 }
|
2019-06-11 07:40:32 +00:00
|
|
|
func (s *Ethereum) ArchiveMode() bool { return s.config.NoPruning }
|
2020-08-03 17:40:46 +00:00
|
|
|
func (s *Ethereum) BloomIndexer() *core.ChainIndexer { return s.bloomIndexer }
|
2015-01-28 17:14:28 +00:00
|
|
|
|
2020-08-03 17:40:46 +00:00
|
|
|
// Protocols returns all the currently configured
|
2015-11-17 16:33:25 +00:00
|
|
|
// network protocols to start.
|
2016-06-30 10:03:26 +00:00
|
|
|
func (s *Ethereum) Protocols() []p2p.Protocol {
|
2020-12-14 09:27:15 +00:00
|
|
|
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)...)
|
2019-07-08 15:53:47 +00:00
|
|
|
}
|
|
|
|
return protos
|
2015-11-17 16:33:25 +00:00
|
|
|
}
|
2015-04-22 10:46:41 +00:00
|
|
|
|
2020-08-03 17:40:46 +00:00
|
|
|
// Start implements node.Lifecycle, starting all internal goroutines needed by the
|
2016-06-30 10:03:26 +00:00
|
|
|
// Ethereum protocol implementation.
|
2020-08-03 17:40:46 +00:00
|
|
|
func (s *Ethereum) Start() error {
|
2020-12-14 09:27:15 +00:00
|
|
|
eth.StartENRUpdater(s.blockchain, s.p2pServer.LocalNode())
|
2019-07-08 15:53:47 +00:00
|
|
|
|
2017-08-29 11:13:11 +00:00
|
|
|
// Start the bloom bits servicing goroutines
|
2018-08-28 07:08:16 +00:00
|
|
|
s.startBloomHandlers(params.BloomBitsBlocks)
|
2017-08-29 11:13:11 +00:00
|
|
|
|
2017-09-05 16:18:28 +00:00
|
|
|
// Figure out a max peers count based on the server limits
|
2020-08-03 17:40:46 +00:00
|
|
|
maxPeers := s.p2pServer.MaxPeers
|
2017-09-05 16:18:28 +00:00
|
|
|
if s.config.LightServ > 0 {
|
2020-08-03 17:40:46 +00:00
|
|
|
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)
|
2017-09-05 16:18:28 +00:00
|
|
|
}
|
2018-02-05 13:41:53 +00:00
|
|
|
maxPeers -= s.config.LightPeers
|
2017-09-05 16:18:28 +00:00
|
|
|
}
|
2017-08-29 11:13:11 +00:00
|
|
|
// Start the networking layer and the light server if requested
|
2020-12-14 09:27:15 +00:00
|
|
|
s.handler.Start(maxPeers)
|
2014-12-14 18:03:24 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2020-08-03 17:40:46 +00:00
|
|
|
// Stop implements node.Lifecycle, terminating all internal goroutines used by the
|
2015-11-17 16:33:25 +00:00
|
|
|
// Ethereum protocol.
|
2016-06-30 10:03:26 +00:00
|
|
|
func (s *Ethereum) Stop() error {
|
2020-03-27 13:03:20 +00:00
|
|
|
// Stop all the peer-related stuff first.
|
2021-05-04 09:29:32 +00:00
|
|
|
s.ethDialCandidates.Close()
|
|
|
|
s.snapDialCandidates.Close()
|
2020-12-14 09:27:15 +00:00
|
|
|
s.handler.Stop()
|
2020-03-27 13:03:20 +00:00
|
|
|
|
|
|
|
// Then stop everything else.
|
|
|
|
s.bloomIndexer.Close()
|
|
|
|
close(s.closeBloomHandler)
|
2014-12-14 18:03:24 +00:00
|
|
|
s.txPool.Stop()
|
2016-03-29 01:08:16 +00:00
|
|
|
s.miner.Stop()
|
2020-03-27 13:03:20 +00:00
|
|
|
s.blockchain.Stop()
|
|
|
|
s.engine.Close()
|
2020-12-11 14:56:00 +00:00
|
|
|
rawdb.PopUncleanShutdownMarker(s.chainDb)
|
2015-09-14 07:45:40 +00:00
|
|
|
s.chainDb.Close()
|
2020-03-27 13:03:20 +00:00
|
|
|
s.eventMux.Stop()
|
2020-12-14 09:27:15 +00:00
|
|
|
|
2015-11-17 16:33:25 +00:00
|
|
|
return nil
|
2014-12-14 18:03:24 +00:00
|
|
|
}
|