mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-27 23:26:44 +00:00
* Add CLI flags to config LevelDB table/total sizes
I wired up CLI flags to allow configuring LevelDB table and total sizes:
- `--leveldb.compaction.table.size`, LevelDB SSTable file size factor in MiB (default: 2)
- `--leveldb.compaction.table.multiplier`, multiplier on LevelDB SSTable file size (default: 1)
- `--leveldb.compaction.total.size`, total size factor in MiB of LevelDB levels (default: 10)
- `--leveldb.compaction.total.multiplier`, multiplier on LevelDB total level size (default: 10)
N.B. that the default values for these configs are exactly the same as
before this changset and so Bor behavior should not change unless these
flags are deliberately overridden. Bor/Geth inherited the default values
from [the `goleveldb`
defaults](126854af5e/leveldb/opt/options.go).
We (Alchemy) found it necessary to override these configs as follows to
keep Bor archive nodes tracking the canonical chain:
- `--leveldb.compaction.table.size=4`
- `--leveldb.compaction.total.size=20`
These overrides double the size of LevelDB SSTable files (2 MiB -> 4
MiB) and also the total amount of data in each level (100 MiB -> 200
MiB, 1,000 MiB -> 2,000 MiB, etc.). The idea is to have LevelDB read and
write data in larger chunks while keeping the proportional frequency of
compaction operations the same as in the original defaults defined by
Dean and Ghemawat.
Without these overrides we found that our archive nodes would tend to
fall into a "LevelDB compaction loop of death" where the incoming stream
of blockchain data could not be flowed into LevelDB's structure quickly
enough, resulting in the node blocking writes for long periods of time
while LevelDB's single-threaded compaction organized the data. Over
time the nodes would fall farther and farther behind the canonical chain
head, metaphorically dying a slow node's death.
These configs can be changed on existing node databases (resyncing is
not necessary). LevelDB appears to work correctly with SSTable files of
different sizes. Note that the database does not undergo any sort of
migration when changing these configs. Only newly-written files (due to
new data or compaction) are affected by these configs.
* Update docs
* Adjust line spacing for linter
* Replace map with `ExtraDBConfig`
* Rename `LevelDbConfig` to `ExtraDBConfig`
* Regenerate docs
318 lines
12 KiB
Go
318 lines
12 KiB
Go
// Copyright 2021 The go-ethereum Authors
|
|
// This file is part of the go-ethereum library.
|
|
//
|
|
// The go-ethereum library is free software: you can redistribute it and/or modify
|
|
// 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.
|
|
//
|
|
// The go-ethereum library is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU Lesser General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU Lesser General Public License
|
|
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
// Package ethconfig contains the configuration of the ETH and LES protocols.
|
|
package ethconfig
|
|
|
|
import (
|
|
"os"
|
|
"os/user"
|
|
"path/filepath"
|
|
"runtime"
|
|
"time"
|
|
|
|
"github.com/ethereum/go-ethereum/common"
|
|
"github.com/ethereum/go-ethereum/consensus"
|
|
"github.com/ethereum/go-ethereum/consensus/beacon"
|
|
"github.com/ethereum/go-ethereum/consensus/bor"
|
|
"github.com/ethereum/go-ethereum/consensus/bor/contract"
|
|
"github.com/ethereum/go-ethereum/consensus/bor/heimdall" //nolint:typecheck
|
|
"github.com/ethereum/go-ethereum/consensus/bor/heimdall/span"
|
|
"github.com/ethereum/go-ethereum/consensus/bor/heimdallapp"
|
|
"github.com/ethereum/go-ethereum/consensus/bor/heimdallgrpc"
|
|
"github.com/ethereum/go-ethereum/consensus/clique"
|
|
"github.com/ethereum/go-ethereum/consensus/ethash"
|
|
"github.com/ethereum/go-ethereum/core"
|
|
"github.com/ethereum/go-ethereum/core/txpool"
|
|
"github.com/ethereum/go-ethereum/eth/downloader"
|
|
"github.com/ethereum/go-ethereum/eth/gasprice"
|
|
"github.com/ethereum/go-ethereum/ethdb"
|
|
"github.com/ethereum/go-ethereum/internal/ethapi"
|
|
"github.com/ethereum/go-ethereum/log"
|
|
"github.com/ethereum/go-ethereum/miner"
|
|
"github.com/ethereum/go-ethereum/node"
|
|
"github.com/ethereum/go-ethereum/params"
|
|
)
|
|
|
|
// FullNodeGPO contains default gasprice oracle settings for full node.
|
|
var FullNodeGPO = gasprice.Config{
|
|
Blocks: 20,
|
|
Percentile: 60,
|
|
MaxHeaderHistory: 1024,
|
|
MaxBlockHistory: 1024,
|
|
MaxPrice: gasprice.DefaultMaxPrice,
|
|
IgnorePrice: gasprice.DefaultIgnorePrice,
|
|
}
|
|
|
|
// LightClientGPO contains default gasprice oracle settings for light client.
|
|
var LightClientGPO = gasprice.Config{
|
|
Blocks: 2,
|
|
Percentile: 60,
|
|
MaxHeaderHistory: 300,
|
|
MaxBlockHistory: 5,
|
|
MaxPrice: gasprice.DefaultMaxPrice,
|
|
IgnorePrice: gasprice.DefaultIgnorePrice,
|
|
}
|
|
|
|
// Defaults contains default settings for use on the Ethereum main net.
|
|
var Defaults = Config{
|
|
SyncMode: downloader.SnapSync,
|
|
Ethash: ethash.Config{
|
|
CacheDir: "ethash",
|
|
CachesInMem: 2,
|
|
CachesOnDisk: 3,
|
|
CachesLockMmap: false,
|
|
DatasetsInMem: 1,
|
|
DatasetsOnDisk: 2,
|
|
DatasetsLockMmap: false,
|
|
},
|
|
NetworkId: 1,
|
|
TxLookupLimit: 2350000,
|
|
LightPeers: 100,
|
|
UltraLightFraction: 75,
|
|
DatabaseCache: 512,
|
|
TrieCleanCache: 154,
|
|
TrieCleanCacheJournal: "triecache",
|
|
TrieCleanCacheRejournal: 60 * time.Minute,
|
|
TrieDirtyCache: 256,
|
|
TrieTimeout: 60 * time.Minute,
|
|
SnapshotCache: 102,
|
|
FilterLogCacheSize: 32,
|
|
Miner: miner.DefaultConfig,
|
|
TxPool: txpool.DefaultConfig,
|
|
RPCGasCap: 50000000,
|
|
RPCReturnDataLimit: 100000,
|
|
RPCEVMTimeout: 5 * time.Second,
|
|
GPO: FullNodeGPO,
|
|
RPCTxFeeCap: 5, // 1 ether
|
|
}
|
|
|
|
func init() {
|
|
home := os.Getenv("HOME")
|
|
if home == "" {
|
|
if user, err := user.Current(); err == nil {
|
|
home = user.HomeDir
|
|
}
|
|
}
|
|
|
|
if runtime.GOOS == "darwin" {
|
|
Defaults.Ethash.DatasetDir = filepath.Join(home, "Library", "Ethash")
|
|
} else if runtime.GOOS == "windows" {
|
|
localappdata := os.Getenv("LOCALAPPDATA")
|
|
if localappdata != "" {
|
|
Defaults.Ethash.DatasetDir = filepath.Join(localappdata, "Ethash")
|
|
} else {
|
|
Defaults.Ethash.DatasetDir = filepath.Join(home, "AppData", "Local", "Ethash")
|
|
}
|
|
} else {
|
|
Defaults.Ethash.DatasetDir = filepath.Join(home, ".ethash")
|
|
}
|
|
}
|
|
|
|
//go:generate go run github.com/fjl/gencodec -type Config -formats toml -out gen_config.go
|
|
|
|
// Config contains configuration options for of the ETH and LES protocols.
|
|
type Config struct {
|
|
// The genesis block, which is inserted if the database is empty.
|
|
// If nil, the Ethereum main net block is used.
|
|
Genesis *core.Genesis `toml:",omitempty"`
|
|
|
|
// Protocol options
|
|
NetworkId uint64 // Network ID to use for selecting peers to connect to
|
|
SyncMode downloader.SyncMode
|
|
|
|
// This can be set to list of enrtree:// URLs which will be queried for
|
|
// for nodes to connect to.
|
|
EthDiscoveryURLs []string
|
|
SnapDiscoveryURLs []string
|
|
|
|
NoPruning bool // Whether to disable pruning and flush everything to disk
|
|
NoPrefetch bool // Whether to disable prefetching and only load state on demand
|
|
|
|
TxLookupLimit uint64 `toml:",omitempty"` // The maximum number of blocks from head whose tx indices are reserved.
|
|
|
|
// RequiredBlocks is a set of block number -> hash mappings which must be in the
|
|
// canonical chain of all remote peers. Setting the option makes geth verify the
|
|
// presence of these blocks for every new peer connection.
|
|
RequiredBlocks map[uint64]common.Hash `toml:"-"`
|
|
|
|
// Light client options
|
|
LightServ int `toml:",omitempty"` // Maximum percentage of time allowed for serving LES requests
|
|
LightIngress int `toml:",omitempty"` // Incoming bandwidth limit for light servers
|
|
LightEgress int `toml:",omitempty"` // Outgoing bandwidth limit for light servers
|
|
LightPeers int `toml:",omitempty"` // Maximum number of LES client peers
|
|
LightNoPrune bool `toml:",omitempty"` // Whether to disable light chain pruning
|
|
LightNoSyncServe bool `toml:",omitempty"` // Whether to serve light clients before syncing
|
|
SyncFromCheckpoint bool `toml:",omitempty"` // Whether to sync the header chain from the configured checkpoint
|
|
|
|
// Ultra Light client options
|
|
UltraLightServers []string `toml:",omitempty"` // List of trusted ultra light servers
|
|
UltraLightFraction int `toml:",omitempty"` // Percentage of trusted servers to accept an announcement
|
|
UltraLightOnlyAnnounce bool `toml:",omitempty"` // Whether to only announce headers, or also serve them
|
|
|
|
// Database options
|
|
SkipBcVersionCheck bool `toml:"-"`
|
|
DatabaseHandles int `toml:"-"`
|
|
DatabaseCache int
|
|
DatabaseFreezer string
|
|
|
|
// Database - LevelDB options
|
|
LevelDbCompactionTableSize uint64
|
|
LevelDbCompactionTableSizeMultiplier float64
|
|
LevelDbCompactionTotalSize uint64
|
|
LevelDbCompactionTotalSizeMultiplier float64
|
|
|
|
TrieCleanCache int
|
|
TrieCleanCacheJournal string `toml:",omitempty"` // Disk journal directory for trie cache to survive node restarts
|
|
TrieCleanCacheRejournal time.Duration `toml:",omitempty"` // Time interval to regenerate the journal for clean cache
|
|
TrieDirtyCache int
|
|
TrieTimeout time.Duration
|
|
SnapshotCache int
|
|
Preimages bool
|
|
TriesInMemory uint64
|
|
|
|
// This is the number of blocks for which logs will be cached in the filter system.
|
|
FilterLogCacheSize int
|
|
|
|
// Mining options
|
|
Miner miner.Config
|
|
|
|
// Ethash options
|
|
Ethash ethash.Config
|
|
|
|
// Transaction pool options
|
|
TxPool txpool.Config
|
|
|
|
// Gas Price Oracle options
|
|
GPO gasprice.Config
|
|
|
|
// Enables tracking of SHA3 preimages in the VM
|
|
EnablePreimageRecording bool
|
|
|
|
// Miscellaneous options
|
|
DocRoot string `toml:"-"`
|
|
|
|
// RPCGasCap is the global gas cap for eth-call variants.
|
|
RPCGasCap uint64
|
|
|
|
// Maximum size (in bytes) a result of an rpc request could have
|
|
RPCReturnDataLimit uint64
|
|
|
|
// RPCEVMTimeout is the global timeout for eth-call.
|
|
RPCEVMTimeout time.Duration
|
|
|
|
// RPCTxFeeCap is the global transaction fee(price * gaslimit) cap for
|
|
// send-transaction variants. The unit is ether.
|
|
RPCTxFeeCap float64
|
|
|
|
// Checkpoint is a hardcoded checkpoint which can be nil.
|
|
Checkpoint *params.TrustedCheckpoint `toml:",omitempty"`
|
|
|
|
// CheckpointOracle is the configuration for checkpoint oracle.
|
|
CheckpointOracle *params.CheckpointOracleConfig `toml:",omitempty"`
|
|
|
|
// TODO marcello double check
|
|
// OverrideShanghai (TODO: remove after the fork)
|
|
OverrideShanghai *uint64 `toml:",omitempty"`
|
|
|
|
// URL to connect to Heimdall node
|
|
HeimdallURL string
|
|
|
|
// No heimdall service
|
|
WithoutHeimdall bool
|
|
|
|
// Address to connect to Heimdall gRPC server
|
|
HeimdallgRPCAddress string
|
|
|
|
// Run heimdall service as a child process
|
|
RunHeimdall bool
|
|
|
|
// Arguments to pass to heimdall service
|
|
RunHeimdallArgs string
|
|
|
|
// Use child heimdall process to fetch data, Only works when RunHeimdall is true
|
|
UseHeimdallApp bool
|
|
|
|
// Bor logs flag
|
|
BorLogs bool
|
|
|
|
// Parallel EVM (Block-STM) related config
|
|
ParallelEVM core.ParallelEVMConfig `toml:",omitempty"`
|
|
|
|
// Develop Fake Author mode to produce blocks without authorisation
|
|
DevFakeAuthor bool `hcl:"devfakeauthor,optional" toml:"devfakeauthor,optional"`
|
|
}
|
|
|
|
// CreateConsensusEngine creates a consensus engine for the given chain configuration.
|
|
func CreateConsensusEngine(stack *node.Node, chainConfig *params.ChainConfig, ethConfig *Config, ethashConfig *ethash.Config, cliqueConfig *params.CliqueConfig, notify []string, noverify bool, db ethdb.Database, blockchainAPI *ethapi.BlockChainAPI) consensus.Engine {
|
|
var engine consensus.Engine
|
|
// nolint:nestif
|
|
if cliqueConfig != nil {
|
|
// If proof-of-authority is requested, set it up
|
|
engine = clique.New(cliqueConfig, db)
|
|
} else if chainConfig.Bor != nil && chainConfig.Bor.ValidatorContract != "" {
|
|
// If Matic bor consensus is requested, set it up
|
|
// In order to pass the ethereum transaction tests, we need to set the burn contract which is in the bor config
|
|
// Then, bor != nil will also be enabled for ethash and clique. Only enable Bor for real if there is a validator contract present.
|
|
genesisContractsClient := contract.NewGenesisContractsClient(chainConfig, chainConfig.Bor.ValidatorContract, chainConfig.Bor.StateReceiverContract, blockchainAPI)
|
|
spanner := span.NewChainSpanner(blockchainAPI, contract.ValidatorSet(), chainConfig, common.HexToAddress(chainConfig.Bor.ValidatorContract))
|
|
|
|
if ethConfig.WithoutHeimdall {
|
|
return bor.New(chainConfig, db, blockchainAPI, spanner, nil, genesisContractsClient, ethConfig.DevFakeAuthor)
|
|
} else {
|
|
if ethConfig.DevFakeAuthor {
|
|
log.Warn("Sanitizing DevFakeAuthor", "Use DevFakeAuthor with", "--bor.withoutheimdall")
|
|
}
|
|
|
|
var heimdallClient bor.IHeimdallClient
|
|
if ethConfig.RunHeimdall && ethConfig.UseHeimdallApp {
|
|
heimdallClient = heimdallapp.NewHeimdallAppClient()
|
|
} else if ethConfig.HeimdallgRPCAddress != "" {
|
|
heimdallClient = heimdallgrpc.NewHeimdallGRPCClient(ethConfig.HeimdallgRPCAddress)
|
|
} else {
|
|
heimdallClient = heimdall.NewHeimdallClient(ethConfig.HeimdallURL)
|
|
}
|
|
|
|
return bor.New(chainConfig, db, blockchainAPI, spanner, heimdallClient, genesisContractsClient, false)
|
|
}
|
|
} else {
|
|
// nolint : exhaustive
|
|
switch ethashConfig.PowMode {
|
|
case ethash.ModeFake:
|
|
log.Warn("Ethash used in fake mode")
|
|
case ethash.ModeTest:
|
|
log.Warn("Ethash used in test mode")
|
|
case ethash.ModeShared:
|
|
log.Warn("Ethash used in shared mode")
|
|
}
|
|
|
|
engine = ethash.New(ethash.Config{
|
|
PowMode: ethashConfig.PowMode,
|
|
CacheDir: stack.ResolvePath(ethashConfig.CacheDir),
|
|
CachesInMem: ethashConfig.CachesInMem,
|
|
CachesOnDisk: ethashConfig.CachesOnDisk,
|
|
CachesLockMmap: ethashConfig.CachesLockMmap,
|
|
DatasetDir: ethashConfig.DatasetDir,
|
|
DatasetsInMem: ethashConfig.DatasetsInMem,
|
|
DatasetsOnDisk: ethashConfig.DatasetsOnDisk,
|
|
DatasetsLockMmap: ethashConfig.DatasetsLockMmap,
|
|
NotifyFull: ethashConfig.NotifyFull,
|
|
}, notify, noverify)
|
|
engine.(*ethash.Ethash).SetThreads(-1) // Disable CPU mining
|
|
}
|
|
|
|
return beacon.New(engine)
|
|
}
|