mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-17 18:30:45 +00:00
parent
5759893f2b
commit
b9a6c8c32d
11 changed files with 68 additions and 32 deletions
|
|
@ -95,7 +95,8 @@ var (
|
||||||
//utils.LightKDFFlag,
|
//utils.LightKDFFlag,
|
||||||
utils.CacheFlag,
|
utils.CacheFlag,
|
||||||
utils.CacheDatabaseFlag,
|
utils.CacheDatabaseFlag,
|
||||||
//utils.CacheGCFlag,
|
utils.CacheTrieFlag,
|
||||||
|
utils.CacheGCFlag,
|
||||||
//utils.TrieCacheGenFlag,
|
//utils.TrieCacheGenFlag,
|
||||||
utils.CacheLogSizeFlag,
|
utils.CacheLogSizeFlag,
|
||||||
utils.FDLimitFlag,
|
utils.FDLimitFlag,
|
||||||
|
|
|
||||||
|
|
@ -289,6 +289,12 @@ var (
|
||||||
Value: 50,
|
Value: 50,
|
||||||
Category: flags.PerfCategory,
|
Category: flags.PerfCategory,
|
||||||
}
|
}
|
||||||
|
CacheTrieFlag = &cli.IntFlag{
|
||||||
|
Name: "cache.trie",
|
||||||
|
Usage: "Percentage of cache memory allowance to use for trie caching (default = 15% full mode, 30% archive mode)",
|
||||||
|
Value: 15,
|
||||||
|
Category: flags.PerfCategory,
|
||||||
|
}
|
||||||
CacheGCFlag = &cli.IntFlag{
|
CacheGCFlag = &cli.IntFlag{
|
||||||
Name: "cache-gc",
|
Name: "cache-gc",
|
||||||
Aliases: []string{"cache.gc"},
|
Aliases: []string{"cache.gc"},
|
||||||
|
|
@ -1424,8 +1430,11 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
|
||||||
}
|
}
|
||||||
cfg.NoPruning = ctx.String(GCModeFlag.Name) == "archive"
|
cfg.NoPruning = ctx.String(GCModeFlag.Name) == "archive"
|
||||||
|
|
||||||
|
if ctx.IsSet(CacheFlag.Name) || ctx.IsSet(CacheTrieFlag.Name) {
|
||||||
|
cfg.TrieCleanCache = ctx.Int(CacheFlag.Name) * ctx.Int(CacheTrieFlag.Name) / 100
|
||||||
|
}
|
||||||
if ctx.IsSet(CacheFlag.Name) || ctx.IsSet(CacheGCFlag.Name) {
|
if ctx.IsSet(CacheFlag.Name) || ctx.IsSet(CacheGCFlag.Name) {
|
||||||
cfg.TrieCache = ctx.Int(CacheFlag.Name) * ctx.Int(CacheGCFlag.Name) / 100
|
cfg.TrieDirtyCache = ctx.Int(CacheFlag.Name) * ctx.Int(CacheGCFlag.Name) / 100
|
||||||
}
|
}
|
||||||
if ctx.IsSet(MinerThreadsFlag.Name) {
|
if ctx.IsSet(MinerThreadsFlag.Name) {
|
||||||
cfg.MinerThreads = ctx.Int(MinerThreadsFlag.Name)
|
cfg.MinerThreads = ctx.Int(MinerThreadsFlag.Name)
|
||||||
|
|
@ -1673,12 +1682,16 @@ func MakeChain(ctx *cli.Context, stack *node.Node, readonly bool) (chain *core.B
|
||||||
Fatalf("--%s must be either 'full' or 'archive'", GCModeFlag.Name)
|
Fatalf("--%s must be either 'full' or 'archive'", GCModeFlag.Name)
|
||||||
}
|
}
|
||||||
cache := &core.CacheConfig{
|
cache := &core.CacheConfig{
|
||||||
Disabled: ctx.String(GCModeFlag.Name) == "archive",
|
Disabled: ctx.String(GCModeFlag.Name) == "archive",
|
||||||
TrieNodeLimit: ethconfig.Defaults.TrieCache,
|
TrieCleanLimit: ethconfig.Defaults.TrieCleanCache,
|
||||||
TrieTimeLimit: ethconfig.Defaults.TrieTimeout,
|
TrieDirtyLimit: ethconfig.Defaults.TrieDirtyCache,
|
||||||
|
TrieTimeLimit: ethconfig.Defaults.TrieTimeout,
|
||||||
|
}
|
||||||
|
if ctx.IsSet(CacheFlag.Name) || ctx.IsSet(CacheTrieFlag.Name) {
|
||||||
|
cache.TrieCleanLimit = ctx.Int(CacheFlag.Name) * ctx.Int(CacheTrieFlag.Name) / 100
|
||||||
}
|
}
|
||||||
if ctx.IsSet(CacheFlag.Name) || ctx.IsSet(CacheGCFlag.Name) {
|
if ctx.IsSet(CacheFlag.Name) || ctx.IsSet(CacheGCFlag.Name) {
|
||||||
cache.TrieNodeLimit = ctx.Int(CacheFlag.Name) * ctx.Int(CacheGCFlag.Name) / 100
|
cache.TrieCleanLimit = ctx.Int(CacheFlag.Name) * ctx.Int(CacheGCFlag.Name) / 100
|
||||||
}
|
}
|
||||||
vmcfg := vm.Config{EnablePreimageRecording: ctx.Bool(VMEnableDebugFlag.Name)}
|
vmcfg := vm.Config{EnablePreimageRecording: ctx.Bool(VMEnableDebugFlag.Name)}
|
||||||
chain, err = core.NewBlockChain(chainDb, cache, config, engine, vmcfg)
|
chain, err = core.NewBlockChain(chainDb, cache, config, engine, vmcfg)
|
||||||
|
|
|
||||||
|
|
@ -127,10 +127,12 @@ const (
|
||||||
// CacheConfig contains the configuration values for the trie caching/pruning
|
// CacheConfig contains the configuration values for the trie caching/pruning
|
||||||
// that's resident in a blockchain.
|
// that's resident in a blockchain.
|
||||||
type CacheConfig struct {
|
type CacheConfig struct {
|
||||||
Disabled bool // Whether to disable trie write caching (archive node)
|
Disabled bool // Whether to disable trie write caching (archive node)
|
||||||
TrieNodeLimit int // Memory limit (MB) at which to flush the current in-memory trie to disk
|
TrieCleanLimit int // Memory allowance (MB) to use for caching trie nodes in memory
|
||||||
TrieTimeLimit time.Duration // Time limit after which to flush the current in-memory trie to disk
|
TrieDirtyLimit int // Memory limit (MB) at which to start flushing dirty trie nodes to disk
|
||||||
|
TrieTimeLimit time.Duration // Time limit after which to flush the current in-memory trie to disk
|
||||||
}
|
}
|
||||||
|
|
||||||
type ResultProcessBlock struct {
|
type ResultProcessBlock struct {
|
||||||
logs []*types.Log
|
logs []*types.Log
|
||||||
receipts []*types.Receipt
|
receipts []*types.Receipt
|
||||||
|
|
@ -226,8 +228,9 @@ type BlockChain struct {
|
||||||
func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, chainConfig *params.ChainConfig, engine consensus.Engine, vmConfig vm.Config) (*BlockChain, error) {
|
func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, chainConfig *params.ChainConfig, engine consensus.Engine, vmConfig vm.Config) (*BlockChain, error) {
|
||||||
if cacheConfig == nil {
|
if cacheConfig == nil {
|
||||||
cacheConfig = &CacheConfig{
|
cacheConfig = &CacheConfig{
|
||||||
TrieNodeLimit: 256 * 1024 * 1024,
|
TrieCleanLimit: 256,
|
||||||
TrieTimeLimit: 5 * time.Minute,
|
TrieDirtyLimit: 256,
|
||||||
|
TrieTimeLimit: 5 * time.Minute,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -236,7 +239,7 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, chainConfig *par
|
||||||
cacheConfig: cacheConfig,
|
cacheConfig: cacheConfig,
|
||||||
db: db,
|
db: db,
|
||||||
triegc: prque.New[int64, common.Hash](nil),
|
triegc: prque.New[int64, common.Hash](nil),
|
||||||
stateCache: state.NewDatabase(db),
|
stateCache: state.NewDatabaseWithCache(db, cacheConfig.TrieCleanLimit),
|
||||||
quit: make(chan struct{}),
|
quit: make(chan struct{}),
|
||||||
chainmu: syncx.NewClosableMutex(),
|
chainmu: syncx.NewClosableMutex(),
|
||||||
bodyCache: lru.NewCache[common.Hash, *types.Body](bodyCacheLimit),
|
bodyCache: lru.NewCache[common.Hash, *types.Body](bodyCacheLimit),
|
||||||
|
|
@ -589,6 +592,11 @@ func (bc *BlockChain) StateAt(root common.Hash) (*state.StateDB, error) {
|
||||||
return state.New(root, bc.stateCache)
|
return state.New(root, bc.stateCache)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// StateCache returns the caching database underpinning the blockchain instance.
|
||||||
|
func (bc *BlockChain) StateCache() state.Database {
|
||||||
|
return bc.stateCache
|
||||||
|
}
|
||||||
|
|
||||||
// OrderStateAt returns a new mutable state based on a particular point in time.
|
// OrderStateAt returns a new mutable state based on a particular point in time.
|
||||||
func (bc *BlockChain) OrderStateAt(block *types.Block) (*tradingstate.TradingStateDB, error) {
|
func (bc *BlockChain) OrderStateAt(block *types.Block) (*tradingstate.TradingStateDB, error) {
|
||||||
engine, ok := bc.Engine().(*XDPoS.XDPoS)
|
engine, ok := bc.Engine().(*XDPoS.XDPoS)
|
||||||
|
|
@ -1450,7 +1458,7 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types.
|
||||||
//}
|
//}
|
||||||
var (
|
var (
|
||||||
nodes, imgs = triedb.Size()
|
nodes, imgs = triedb.Size()
|
||||||
limit = common.StorageSize(bc.cacheConfig.TrieNodeLimit) * 1024 * 1024
|
limit = common.StorageSize(bc.cacheConfig.TrieDirtyLimit) * 1024 * 1024
|
||||||
)
|
)
|
||||||
if nodes > limit || imgs > 4*1024*1024 {
|
if nodes > limit || imgs > 4*1024*1024 {
|
||||||
triedb.Cap(limit - ethdb.IdealBatchSize)
|
triedb.Cap(limit - ethdb.IdealBatchSize)
|
||||||
|
|
|
||||||
|
|
@ -102,15 +102,15 @@ type Trie interface {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDatabase creates a backing store for state. The returned database is safe for
|
// NewDatabase creates a backing store for state. The returned database is safe for
|
||||||
// concurrent use, but does not retain any recent trie nodes in memory. To keep some
|
// concurrent use and retains a few recent expanded trie nodes in memory. To keep
|
||||||
// historical state in memory, use the NewDatabaseWithCache constructor.
|
// more historical state in memory, use the NewDatabaseWithCache constructor.
|
||||||
func NewDatabase(db ethdb.Database) Database {
|
func NewDatabase(db ethdb.Database) Database {
|
||||||
return NewDatabaseWithCache(db, 0)
|
return NewDatabaseWithCache(db, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDatabaseWithCache creates a backing store for state. The returned database
|
// NewDatabase creates a backing store for state. The returned database is safe for
|
||||||
// is safe for concurrent use and retains a lot of collapsed RLP trie nodes in a
|
// concurrent use and retains both a few recent expanded trie nodes in memory, as
|
||||||
// large memory cache.
|
// well as a lot of collapsed RLP trie nodes in a large memory cache.
|
||||||
func NewDatabaseWithCache(db ethdb.Database, cache int) Database {
|
func NewDatabaseWithCache(db ethdb.Database, cache int) Database {
|
||||||
return &cachingDB{
|
return &cachingDB{
|
||||||
db: trie.NewDatabaseWithCache(db, cache),
|
db: trie.NewDatabaseWithCache(db, cache),
|
||||||
|
|
|
||||||
|
|
@ -462,12 +462,13 @@ func (api *PrivateDebugAPI) getModifiedAccounts(startBlock, endBlock *types.Bloc
|
||||||
if startBlock.Number().Uint64() >= endBlock.Number().Uint64() {
|
if startBlock.Number().Uint64() >= endBlock.Number().Uint64() {
|
||||||
return nil, fmt.Errorf("start block height (%d) must be less than end block height (%d)", startBlock.Number().Uint64(), endBlock.Number().Uint64())
|
return nil, fmt.Errorf("start block height (%d) must be less than end block height (%d)", startBlock.Number().Uint64(), endBlock.Number().Uint64())
|
||||||
}
|
}
|
||||||
|
triedb := api.eth.BlockChain().StateCache().TrieDB()
|
||||||
|
|
||||||
oldTrie, err := trie.NewSecure(startBlock.Root(), trie.NewDatabase(api.eth.chainDb))
|
oldTrie, err := trie.NewSecure(startBlock.Root(), triedb)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
newTrie, err := trie.NewSecure(endBlock.Root(), trie.NewDatabase(api.eth.chainDb))
|
newTrie, err := trie.NewSecure(endBlock.Root(), triedb)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -177,7 +177,7 @@ func (api *PrivateDebugAPI) traceChain(ctx context.Context, start, end *types.Bl
|
||||||
|
|
||||||
// Ensure we have a valid starting state before doing any work
|
// Ensure we have a valid starting state before doing any work
|
||||||
origin := start.NumberU64()
|
origin := start.NumberU64()
|
||||||
database := state.NewDatabase(api.eth.ChainDb())
|
database := state.NewDatabaseWithCache(api.eth.ChainDb(), 16) // Chain tracing will probably start at genesis
|
||||||
|
|
||||||
if number := start.NumberU64(); number > 0 {
|
if number := start.NumberU64(); number > 0 {
|
||||||
start = api.eth.blockchain.GetBlock(start.ParentHash(), start.NumberU64()-1)
|
start = api.eth.blockchain.GetBlock(start.ParentHash(), start.NumberU64()-1)
|
||||||
|
|
@ -563,7 +563,7 @@ func (api *PrivateDebugAPI) computeStateDB(block *types.Block, reexec uint64) (*
|
||||||
}
|
}
|
||||||
// Otherwise try to reexec blocks until we find a state or reach our limit
|
// Otherwise try to reexec blocks until we find a state or reach our limit
|
||||||
origin := block.NumberU64()
|
origin := block.NumberU64()
|
||||||
database := state.NewDatabase(api.eth.ChainDb())
|
database := state.NewDatabaseWithCache(api.eth.ChainDb(), 16)
|
||||||
|
|
||||||
for i := uint64(0); i < reexec; i++ {
|
for i := uint64(0); i < reexec; i++ {
|
||||||
block = api.eth.blockchain.GetBlock(block.ParentHash(), block.NumberU64()-1)
|
block = api.eth.blockchain.GetBlock(block.ParentHash(), block.NumberU64()-1)
|
||||||
|
|
|
||||||
|
|
@ -175,7 +175,12 @@ func New(stack *node.Node, config *ethconfig.Config, XDCXServ *XDCx.XDCX, lendin
|
||||||
|
|
||||||
var (
|
var (
|
||||||
vmConfig = vm.Config{EnablePreimageRecording: config.EnablePreimageRecording}
|
vmConfig = vm.Config{EnablePreimageRecording: config.EnablePreimageRecording}
|
||||||
cacheConfig = &core.CacheConfig{Disabled: config.NoPruning, TrieNodeLimit: config.TrieCache, TrieTimeLimit: config.TrieTimeout}
|
cacheConfig = &core.CacheConfig{
|
||||||
|
Disabled: config.NoPruning,
|
||||||
|
TrieCleanLimit: config.TrieCleanCache,
|
||||||
|
TrieDirtyLimit: config.TrieDirtyCache,
|
||||||
|
TrieTimeLimit: config.TrieTimeout,
|
||||||
|
}
|
||||||
)
|
)
|
||||||
if eth.chainConfig.XDPoS != nil {
|
if eth.chainConfig.XDPoS != nil {
|
||||||
c := eth.engine.(*XDPoS.XDPoS)
|
c := eth.engine.(*XDPoS.XDPoS)
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,8 @@ var Defaults = Config{
|
||||||
NetworkId: 0, // enable auto configuration of networkID == chainID
|
NetworkId: 0, // enable auto configuration of networkID == chainID
|
||||||
LightPeers: 100,
|
LightPeers: 100,
|
||||||
DatabaseCache: 768,
|
DatabaseCache: 768,
|
||||||
TrieCache: 256,
|
TrieCleanCache: 256,
|
||||||
|
TrieDirtyCache: 256,
|
||||||
TrieTimeout: 5 * time.Minute,
|
TrieTimeout: 5 * time.Minute,
|
||||||
FilterLogCacheSize: 32,
|
FilterLogCacheSize: 32,
|
||||||
GasPrice: big.NewInt(0.25 * params.Shannon),
|
GasPrice: big.NewInt(0.25 * params.Shannon),
|
||||||
|
|
@ -112,7 +113,8 @@ type Config struct {
|
||||||
SkipBcVersionCheck bool `toml:"-"`
|
SkipBcVersionCheck bool `toml:"-"`
|
||||||
DatabaseHandles int `toml:"-"`
|
DatabaseHandles int `toml:"-"`
|
||||||
DatabaseCache int
|
DatabaseCache int
|
||||||
TrieCache int
|
TrieCleanCache int
|
||||||
|
TrieDirtyCache int
|
||||||
TrieTimeout time.Duration
|
TrieTimeout time.Duration
|
||||||
|
|
||||||
// This is the number of blocks for which logs will be cached in the filter system.
|
// This is the number of blocks for which logs will be cached in the filter system.
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,8 @@ func (c Config) MarshalTOML() (interface{}, error) {
|
||||||
SkipBcVersionCheck bool `toml:"-"`
|
SkipBcVersionCheck bool `toml:"-"`
|
||||||
DatabaseHandles int `toml:"-"`
|
DatabaseHandles int `toml:"-"`
|
||||||
DatabaseCache int
|
DatabaseCache int
|
||||||
TrieCache int
|
TrieCleanCache int
|
||||||
|
TrieDirtyCache int
|
||||||
TrieTimeout time.Duration
|
TrieTimeout time.Duration
|
||||||
FilterLogCacheSize int
|
FilterLogCacheSize int
|
||||||
Etherbase common.Address `toml:",omitempty"`
|
Etherbase common.Address `toml:",omitempty"`
|
||||||
|
|
@ -53,7 +54,8 @@ func (c Config) MarshalTOML() (interface{}, error) {
|
||||||
enc.SkipBcVersionCheck = c.SkipBcVersionCheck
|
enc.SkipBcVersionCheck = c.SkipBcVersionCheck
|
||||||
enc.DatabaseHandles = c.DatabaseHandles
|
enc.DatabaseHandles = c.DatabaseHandles
|
||||||
enc.DatabaseCache = c.DatabaseCache
|
enc.DatabaseCache = c.DatabaseCache
|
||||||
enc.TrieCache = c.TrieCache
|
enc.TrieCleanCache = c.TrieCleanCache
|
||||||
|
enc.TrieDirtyCache = c.TrieDirtyCache
|
||||||
enc.TrieTimeout = c.TrieTimeout
|
enc.TrieTimeout = c.TrieTimeout
|
||||||
enc.FilterLogCacheSize = c.FilterLogCacheSize
|
enc.FilterLogCacheSize = c.FilterLogCacheSize
|
||||||
enc.Etherbase = c.Etherbase
|
enc.Etherbase = c.Etherbase
|
||||||
|
|
@ -81,7 +83,8 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error {
|
||||||
SkipBcVersionCheck *bool `toml:"-"`
|
SkipBcVersionCheck *bool `toml:"-"`
|
||||||
DatabaseHandles *int `toml:"-"`
|
DatabaseHandles *int `toml:"-"`
|
||||||
DatabaseCache *int
|
DatabaseCache *int
|
||||||
TrieCache *int
|
TrieCleanCache *int
|
||||||
|
TrieDirtyCache *int
|
||||||
TrieTimeout *time.Duration
|
TrieTimeout *time.Duration
|
||||||
FilterLogCacheSize *int
|
FilterLogCacheSize *int
|
||||||
Etherbase *common.Address `toml:",omitempty"`
|
Etherbase *common.Address `toml:",omitempty"`
|
||||||
|
|
@ -126,8 +129,11 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error {
|
||||||
if dec.DatabaseCache != nil {
|
if dec.DatabaseCache != nil {
|
||||||
c.DatabaseCache = *dec.DatabaseCache
|
c.DatabaseCache = *dec.DatabaseCache
|
||||||
}
|
}
|
||||||
if dec.TrieCache != nil {
|
if dec.TrieCleanCache != nil {
|
||||||
c.TrieCache = *dec.TrieCache
|
c.TrieCleanCache = *dec.TrieCleanCache
|
||||||
|
}
|
||||||
|
if dec.TrieDirtyCache != nil {
|
||||||
|
c.TrieDirtyCache = *dec.TrieDirtyCache
|
||||||
}
|
}
|
||||||
if dec.TrieTimeout != nil {
|
if dec.TrieTimeout != nil {
|
||||||
c.TrieTimeout = *dec.TrieTimeout
|
c.TrieTimeout = *dec.TrieTimeout
|
||||||
|
|
|
||||||
|
|
@ -114,7 +114,7 @@ func (t *BlockTest) Run() error {
|
||||||
return fmt.Errorf("genesis block state root does not match test: computed=%x, test=%x", gblock.Root().Bytes(), t.json.Genesis.StateRoot)
|
return fmt.Errorf("genesis block state root does not match test: computed=%x, test=%x", gblock.Root().Bytes(), t.json.Genesis.StateRoot)
|
||||||
}
|
}
|
||||||
|
|
||||||
chain, err := core.NewBlockChain(db, nil, config, ethash.NewShared(), vm.Config{})
|
chain, err := core.NewBlockChain(db, &core.CacheConfig{TrieCleanLimit: 0}, config, ethash.NewShared(), vm.Config{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -336,7 +336,7 @@ func (db *Database) InsertPreimage(hash common.Hash, preimage []byte) {
|
||||||
db.preimagesSize += common.StorageSize(common.HashLength + len(preimage))
|
db.preimagesSize += common.StorageSize(common.HashLength + len(preimage))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Node retrieves a cached trie Node from memory, or returns nil if none can be
|
// node retrieves a cached trie Node from memory, or returns nil if none can be
|
||||||
// found in the memory Cache.
|
// found in the memory Cache.
|
||||||
func (db *Database) node(hash common.Hash) node {
|
func (db *Database) node(hash common.Hash) node {
|
||||||
// Retrieve the Node from the clean Cache if available
|
// Retrieve the Node from the clean Cache if available
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue