mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-18 02:40:45 +00:00
parent
d6cecbf570
commit
93c2745b7b
12 changed files with 112 additions and 48 deletions
|
|
@ -138,7 +138,13 @@ func NewXDCSimulatedBackend(alloc types.GenesisAlloc, gasLimit uint64, chainConf
|
||||||
return lendingServ
|
return lendingServ
|
||||||
}
|
}
|
||||||
|
|
||||||
blockchain, _ := core.NewBlockChain(database, nil, genesis.Config, consensus, vm.Config{})
|
cacheConfig := &core.CacheConfig{
|
||||||
|
TrieCleanLimit: 256,
|
||||||
|
TrieDirtyLimit: 256,
|
||||||
|
TrieTimeLimit: 5 * time.Minute,
|
||||||
|
Preimages: true,
|
||||||
|
}
|
||||||
|
blockchain, _ := core.NewBlockChain(database, cacheConfig, genesis.Config, consensus, vm.Config{})
|
||||||
|
|
||||||
backend := &SimulatedBackend{
|
backend := &SimulatedBackend{
|
||||||
database: database,
|
database: database,
|
||||||
|
|
|
||||||
|
|
@ -100,6 +100,7 @@ var (
|
||||||
utils.CacheGCFlag,
|
utils.CacheGCFlag,
|
||||||
utils.CachePrefetchFlag,
|
utils.CachePrefetchFlag,
|
||||||
//utils.TrieCacheGenFlag,
|
//utils.TrieCacheGenFlag,
|
||||||
|
utils.CachePreimagesFlag,
|
||||||
utils.CacheLogSizeFlag,
|
utils.CacheLogSizeFlag,
|
||||||
utils.FDLimitFlag,
|
utils.FDLimitFlag,
|
||||||
utils.CryptoKZGFlag,
|
utils.CryptoKZGFlag,
|
||||||
|
|
|
||||||
|
|
@ -308,6 +308,12 @@ var (
|
||||||
Usage: "Enable heuristic state prefetch during block import",
|
Usage: "Enable heuristic state prefetch during block import",
|
||||||
Category: flags.PerfCategory,
|
Category: flags.PerfCategory,
|
||||||
}
|
}
|
||||||
|
CachePreimagesFlag = &cli.BoolFlag{
|
||||||
|
Name: "cache-preimages",
|
||||||
|
Usage: "Enable recording the SHA3/keccak preimages of trie keys (default: true)",
|
||||||
|
Value: true,
|
||||||
|
Category: flags.PerfCategory,
|
||||||
|
}
|
||||||
CacheLogSizeFlag = &cli.IntFlag{
|
CacheLogSizeFlag = &cli.IntFlag{
|
||||||
Name: "cache-blocklogs",
|
Name: "cache-blocklogs",
|
||||||
Aliases: []string{"cache.blocklogs"},
|
Aliases: []string{"cache.blocklogs"},
|
||||||
|
|
@ -1513,7 +1519,12 @@ 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"
|
||||||
cfg.NoPrefetch = !ctx.Bool(CachePrefetchFlag.Name)
|
cfg.NoPrefetch = !ctx.Bool(CachePrefetchFlag.Name)
|
||||||
|
// Read the value from the flag no matter if it's set or not.
|
||||||
|
cfg.Preimages = ctx.Bool(CachePreimagesFlag.Name)
|
||||||
|
if cfg.NoPruning && !cfg.Preimages {
|
||||||
|
cfg.Preimages = true
|
||||||
|
log.Info("Enabling recording of key preimages since archive mode is used")
|
||||||
|
}
|
||||||
if ctx.IsSet(CacheFlag.Name) || ctx.IsSet(CacheTrieFlag.Name) {
|
if ctx.IsSet(CacheFlag.Name) || ctx.IsSet(CacheTrieFlag.Name) {
|
||||||
cfg.TrieCleanCache = ctx.Int(CacheFlag.Name) * ctx.Int(CacheTrieFlag.Name) / 100
|
cfg.TrieCleanCache = ctx.Int(CacheFlag.Name) * ctx.Int(CacheTrieFlag.Name) / 100
|
||||||
}
|
}
|
||||||
|
|
@ -1780,6 +1791,11 @@ func MakeChain(ctx *cli.Context, stack *node.Node, readonly bool) (chain *core.B
|
||||||
TrieDirtyLimit: ethconfig.Defaults.TrieDirtyCache,
|
TrieDirtyLimit: ethconfig.Defaults.TrieDirtyCache,
|
||||||
TrieDirtyDisabled: ctx.String(GCModeFlag.Name) == "archive",
|
TrieDirtyDisabled: ctx.String(GCModeFlag.Name) == "archive",
|
||||||
TrieTimeLimit: ethconfig.Defaults.TrieTimeout,
|
TrieTimeLimit: ethconfig.Defaults.TrieTimeout,
|
||||||
|
Preimages: ctx.Bool(CachePreimagesFlag.Name),
|
||||||
|
}
|
||||||
|
if cache.TrieDirtyDisabled && !cache.Preimages {
|
||||||
|
cache.Preimages = true
|
||||||
|
log.Info("Enabling recording of key preimages since archive mode is used")
|
||||||
}
|
}
|
||||||
if ctx.IsSet(CacheFlag.Name) || ctx.IsSet(CacheTrieFlag.Name) {
|
if ctx.IsSet(CacheFlag.Name) || ctx.IsSet(CacheTrieFlag.Name) {
|
||||||
cache.TrieCleanLimit = ctx.Int(CacheFlag.Name) * ctx.Int(CacheTrieFlag.Name) / 100
|
cache.TrieCleanLimit = ctx.Int(CacheFlag.Name) * ctx.Int(CacheTrieFlag.Name) / 100
|
||||||
|
|
|
||||||
|
|
@ -135,6 +135,7 @@ type CacheConfig struct {
|
||||||
TrieDirtyLimit int // Memory limit (MB) at which to start flushing dirty trie nodes to disk
|
TrieDirtyLimit int // Memory limit (MB) at which to start flushing dirty trie nodes to disk
|
||||||
TrieDirtyDisabled bool // Whether to disable trie write caching and GC altogether (archive node)
|
TrieDirtyDisabled bool // Whether to disable trie write caching and GC altogether (archive node)
|
||||||
TrieTimeLimit time.Duration // Time limit after which to flush the current in-memory trie to disk
|
TrieTimeLimit time.Duration // Time limit after which to flush the current in-memory trie to disk
|
||||||
|
Preimages bool // Whether to store preimage of trie key to the disk
|
||||||
}
|
}
|
||||||
|
|
||||||
type ResultProcessBlock struct {
|
type ResultProcessBlock struct {
|
||||||
|
|
@ -238,11 +239,14 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, chainConfig *par
|
||||||
}
|
}
|
||||||
|
|
||||||
bc := &BlockChain{
|
bc := &BlockChain{
|
||||||
chainConfig: chainConfig,
|
chainConfig: chainConfig,
|
||||||
cacheConfig: cacheConfig,
|
cacheConfig: cacheConfig,
|
||||||
db: db,
|
db: db,
|
||||||
triegc: prque.New[int64, common.Hash](nil),
|
triegc: prque.New[int64, common.Hash](nil),
|
||||||
stateCache: state.NewDatabaseWithCache(db, cacheConfig.TrieCleanLimit),
|
stateCache: state.NewDatabaseWithConfig(db, &trie.Config{
|
||||||
|
Cache: cacheConfig.TrieCleanLimit,
|
||||||
|
Preimages: cacheConfig.Preimages,
|
||||||
|
}),
|
||||||
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),
|
||||||
|
|
|
||||||
|
|
@ -102,18 +102,18 @@ 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 and retains a few recent expanded trie nodes in memory. To keep
|
// concurrent use, but does not retain any recent trie nodes in memory. To keep some
|
||||||
// more historical state in memory, use the NewDatabaseWithCache constructor.
|
// historical state in memory, use the NewDatabaseWithConfig constructor.
|
||||||
func NewDatabase(db ethdb.Database) Database {
|
func NewDatabase(db ethdb.Database) Database {
|
||||||
return NewDatabaseWithCache(db, 0)
|
return NewDatabaseWithConfig(db, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDatabase creates a backing store for state. The returned database is safe for
|
// NewDatabaseWithConfig creates a backing store for state. The returned database
|
||||||
// concurrent use and retains both a few recent expanded trie nodes in memory, as
|
// is safe for concurrent use and retains a lot of collapsed RLP trie nodes in a
|
||||||
// well as a lot of collapsed RLP trie nodes in a large memory cache.
|
// large memory cache.
|
||||||
func NewDatabaseWithCache(db ethdb.Database, cache int) Database {
|
func NewDatabaseWithConfig(db ethdb.Database, config *trie.Config) Database {
|
||||||
return &cachingDB{
|
return &cachingDB{
|
||||||
db: trie.NewDatabaseWithCache(db, cache),
|
db: trie.NewDatabaseWithConfig(db, config),
|
||||||
codeCache: lru.NewSizeConstrainedCache[common.Hash, []byte](codeCacheSize),
|
codeCache: lru.NewSizeConstrainedCache[common.Hash, []byte](codeCacheSize),
|
||||||
codeSizeCache: lru.NewCache[common.Hash, int](codeSizeCacheSize),
|
codeSizeCache: lru.NewCache[common.Hash, int](codeSizeCacheSize),
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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.NewDatabaseWithCache(api.eth.ChainDb(), 16) // Chain tracing will probably start at genesis
|
database := state.NewDatabaseWithConfig(api.eth.ChainDb(), &trie.Config{Cache: 16, Preimages: true})
|
||||||
|
|
||||||
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)
|
||||||
|
|
@ -549,7 +549,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.NewDatabaseWithCache(api.eth.ChainDb(), 16)
|
database := state.NewDatabaseWithConfig(api.eth.ChainDb(), &trie.Config{Cache: 16, Preimages: true})
|
||||||
|
|
||||||
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)
|
||||||
|
|
|
||||||
|
|
@ -181,6 +181,7 @@ func New(stack *node.Node, config *ethconfig.Config, XDCXServ *XDCx.XDCX, lendin
|
||||||
TrieDirtyLimit: config.TrieDirtyCache,
|
TrieDirtyLimit: config.TrieDirtyCache,
|
||||||
TrieDirtyDisabled: config.NoPruning,
|
TrieDirtyDisabled: config.NoPruning,
|
||||||
TrieTimeLimit: config.TrieTimeout,
|
TrieTimeLimit: config.TrieTimeout,
|
||||||
|
Preimages: config.Preimages,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
if eth.chainConfig.XDPoS != nil {
|
if eth.chainConfig.XDPoS != nil {
|
||||||
|
|
|
||||||
|
|
@ -118,6 +118,7 @@ type Config struct {
|
||||||
TrieCleanCache int
|
TrieCleanCache int
|
||||||
TrieDirtyCache int
|
TrieDirtyCache int
|
||||||
TrieTimeout time.Duration
|
TrieTimeout time.Duration
|
||||||
|
Preimages bool
|
||||||
|
|
||||||
// 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.
|
||||||
FilterLogCacheSize int
|
FilterLogCacheSize int
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@ func (c Config) MarshalTOML() (interface{}, error) {
|
||||||
TrieCleanCache int
|
TrieCleanCache int
|
||||||
TrieDirtyCache int
|
TrieDirtyCache int
|
||||||
TrieTimeout time.Duration
|
TrieTimeout time.Duration
|
||||||
|
Preimages bool
|
||||||
FilterLogCacheSize int
|
FilterLogCacheSize int
|
||||||
Etherbase common.Address `toml:",omitempty"`
|
Etherbase common.Address `toml:",omitempty"`
|
||||||
MinerThreads int `toml:",omitempty"`
|
MinerThreads int `toml:",omitempty"`
|
||||||
|
|
@ -57,6 +58,7 @@ func (c Config) MarshalTOML() (interface{}, error) {
|
||||||
enc.TrieCleanCache = c.TrieCleanCache
|
enc.TrieCleanCache = c.TrieCleanCache
|
||||||
enc.TrieDirtyCache = c.TrieDirtyCache
|
enc.TrieDirtyCache = c.TrieDirtyCache
|
||||||
enc.TrieTimeout = c.TrieTimeout
|
enc.TrieTimeout = c.TrieTimeout
|
||||||
|
enc.Preimages = c.Preimages
|
||||||
enc.FilterLogCacheSize = c.FilterLogCacheSize
|
enc.FilterLogCacheSize = c.FilterLogCacheSize
|
||||||
enc.Etherbase = c.Etherbase
|
enc.Etherbase = c.Etherbase
|
||||||
enc.MinerThreads = c.MinerThreads
|
enc.MinerThreads = c.MinerThreads
|
||||||
|
|
@ -86,6 +88,7 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error {
|
||||||
TrieCleanCache *int
|
TrieCleanCache *int
|
||||||
TrieDirtyCache *int
|
TrieDirtyCache *int
|
||||||
TrieTimeout *time.Duration
|
TrieTimeout *time.Duration
|
||||||
|
Preimages *bool
|
||||||
FilterLogCacheSize *int
|
FilterLogCacheSize *int
|
||||||
Etherbase *common.Address `toml:",omitempty"`
|
Etherbase *common.Address `toml:",omitempty"`
|
||||||
MinerThreads *int `toml:",omitempty"`
|
MinerThreads *int `toml:",omitempty"`
|
||||||
|
|
@ -138,6 +141,9 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error {
|
||||||
if dec.TrieTimeout != nil {
|
if dec.TrieTimeout != nil {
|
||||||
c.TrieTimeout = *dec.TrieTimeout
|
c.TrieTimeout = *dec.TrieTimeout
|
||||||
}
|
}
|
||||||
|
if dec.Preimages != nil {
|
||||||
|
c.Preimages = *dec.Preimages
|
||||||
|
}
|
||||||
if dec.FilterLogCacheSize != nil {
|
if dec.FilterLogCacheSize != nil {
|
||||||
c.FilterLogCacheSize = *dec.FilterLogCacheSize
|
c.FilterLogCacheSize = *dec.FilterLogCacheSize
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ func (eth *Ethereum) stateAtBlock(block *types.Block, reexec uint64, base *state
|
||||||
|
|
||||||
// Create an ephemeral trie.Database for isolating the live one. Otherwise
|
// Create an ephemeral trie.Database for isolating the live one. Otherwise
|
||||||
// the internal junks created by tracing will be persisted into the disk.
|
// the internal junks created by tracing will be persisted into the disk.
|
||||||
database = state.NewDatabaseWithCache(eth.chainDb, 16)
|
database = state.NewDatabaseWithConfig(eth.chainDb, &trie.Config{Cache: 16, Preimages: true})
|
||||||
// If we didn't check the dirty database, do check the clean one, otherwise
|
// If we didn't check the dirty database, do check the clean one, otherwise
|
||||||
// we would rewind past a persisted block (specific corner case is chain
|
// we would rewind past a persisted block (specific corner case is chain
|
||||||
// tracing from the genesis).
|
// tracing from the genesis).
|
||||||
|
|
|
||||||
|
|
@ -260,29 +260,38 @@ func expandNode(hash hashNode, n node) node {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Config defines all necessary options for database.
|
||||||
|
type Config struct {
|
||||||
|
Cache int // Memory allowance (MB) to use for caching trie nodes in memory
|
||||||
|
Preimages bool // Flag whether the preimage of trie key is recorded
|
||||||
|
}
|
||||||
|
|
||||||
// NewDatabase creates a new trie database to store ephemeral trie content before
|
// NewDatabase creates a new trie database to store ephemeral trie content before
|
||||||
// its written out to disk or garbage collected. No read Cache is created, so all
|
// its written out to disk or garbage collected. No read Cache is created, so all
|
||||||
// data retrievals will hit the underlying disk database.
|
// data retrievals will hit the underlying disk database.
|
||||||
func NewDatabase(diskdb ethdb.KeyValueStore) *Database {
|
func NewDatabase(diskdb ethdb.KeyValueStore) *Database {
|
||||||
return NewDatabaseWithCache(diskdb, 0)
|
return NewDatabaseWithConfig(diskdb, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDatabaseWithCache creates a new trie database to store ephemeral trie content
|
// NewDatabaseWithConfig creates a new trie database to store ephemeral trie content
|
||||||
// before its written out to disk or garbage collected. It also acts as a read Cache
|
// before its written out to disk or garbage collected. It also acts as a read cache
|
||||||
// for nodes loaded from disk.
|
// for nodes loaded from disk.
|
||||||
func NewDatabaseWithCache(diskdb ethdb.KeyValueStore, cache int) *Database {
|
func NewDatabaseWithConfig(diskdb ethdb.KeyValueStore, config *Config) *Database {
|
||||||
var cleans *fastcache.Cache
|
var cleans *fastcache.Cache
|
||||||
if cache > 0 {
|
if config != nil && config.Cache > 0 {
|
||||||
cleans = fastcache.New(cache * 1024 * 1024)
|
cleans = fastcache.New(config.Cache * 1024 * 1024)
|
||||||
}
|
}
|
||||||
return &Database{
|
db := &Database{
|
||||||
diskdb: diskdb,
|
diskdb: diskdb,
|
||||||
cleans: cleans,
|
cleans: cleans,
|
||||||
dirties: map[common.Hash]*cachedNode{{}: {
|
dirties: map[common.Hash]*cachedNode{{}: {
|
||||||
children: make(map[common.Hash]uint16),
|
children: make(map[common.Hash]uint16),
|
||||||
}},
|
}},
|
||||||
preimages: make(map[common.Hash][]byte),
|
|
||||||
}
|
}
|
||||||
|
if config == nil || config.Preimages { // TODO(karalabe): Flip to default off in the future
|
||||||
|
db.preimages = make(map[common.Hash][]byte)
|
||||||
|
}
|
||||||
|
return db
|
||||||
}
|
}
|
||||||
|
|
||||||
// DiskDB retrieves the persistent storage backing the trie database.
|
// DiskDB retrieves the persistent storage backing the trie database.
|
||||||
|
|
@ -329,6 +338,11 @@ func (db *Database) insert(hash common.Hash, size int, node node) {
|
||||||
//
|
//
|
||||||
// Note, this method assumes that the database's Lock is held!
|
// Note, this method assumes that the database's Lock is held!
|
||||||
func (db *Database) InsertPreimage(hash common.Hash, preimage []byte) {
|
func (db *Database) InsertPreimage(hash common.Hash, preimage []byte) {
|
||||||
|
// Short circuit if preimage collection is disabled
|
||||||
|
if db.preimages == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// Track the preimage if a yet unknown one
|
||||||
if _, ok := db.preimages[hash]; ok {
|
if _, ok := db.preimages[hash]; ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -415,6 +429,10 @@ func (db *Database) Node(hash common.Hash) ([]byte, error) {
|
||||||
// Preimage retrieves a cached trie Node pre-image from memory. If it cannot be
|
// Preimage retrieves a cached trie Node pre-image from memory. If it cannot be
|
||||||
// found cached, the method queries the persistent database for the content.
|
// found cached, the method queries the persistent database for the content.
|
||||||
func (db *Database) Preimage(hash common.Hash) []byte {
|
func (db *Database) Preimage(hash common.Hash) []byte {
|
||||||
|
// Short circuit if preimage collection is disabled
|
||||||
|
if db.preimages == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
// Retrieve the Node from Cache if available
|
// Retrieve the Node from Cache if available
|
||||||
db.Lock.RLock()
|
db.Lock.RLock()
|
||||||
preimage := db.preimages[hash]
|
preimage := db.preimages[hash]
|
||||||
|
|
@ -572,12 +590,16 @@ func (db *Database) Cap(limit common.StorageSize) error {
|
||||||
// leave for later to deduplicate writes.
|
// leave for later to deduplicate writes.
|
||||||
flushPreimages := db.preimagesSize > 4*1024*1024
|
flushPreimages := db.preimagesSize > 4*1024*1024
|
||||||
if flushPreimages {
|
if flushPreimages {
|
||||||
rawdb.WritePreimages(batch, db.preimages)
|
if db.preimages == nil {
|
||||||
if batch.ValueSize() > ethdb.IdealBatchSize {
|
log.Error("Attempted to write preimages whilst disabled")
|
||||||
if err := batch.Write(); err != nil {
|
} else {
|
||||||
return err
|
rawdb.WritePreimages(batch, db.preimages)
|
||||||
|
if batch.ValueSize() > ethdb.IdealBatchSize {
|
||||||
|
if err := batch.Write(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
batch.Reset()
|
||||||
}
|
}
|
||||||
batch.Reset()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Keep committing nodes from the flush-list until we're below allowance
|
// Keep committing nodes from the flush-list until we're below allowance
|
||||||
|
|
@ -614,7 +636,11 @@ func (db *Database) Cap(limit common.StorageSize) error {
|
||||||
defer db.Lock.Unlock()
|
defer db.Lock.Unlock()
|
||||||
|
|
||||||
if flushPreimages {
|
if flushPreimages {
|
||||||
db.preimages, db.preimagesSize = make(map[common.Hash][]byte), 0
|
if db.preimages == nil {
|
||||||
|
log.Error("Attempted to reset preimage cache whilst disabled")
|
||||||
|
} else {
|
||||||
|
db.preimages, db.preimagesSize = make(map[common.Hash][]byte), 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for db.oldest != oldest {
|
for db.oldest != oldest {
|
||||||
node := db.dirties[db.oldest]
|
node := db.dirties[db.oldest]
|
||||||
|
|
@ -658,20 +684,21 @@ func (db *Database) Commit(node common.Hash, report bool) error {
|
||||||
batch := db.diskdb.NewBatch()
|
batch := db.diskdb.NewBatch()
|
||||||
|
|
||||||
// Move all of the accumulated preimages into a write batch
|
// Move all of the accumulated preimages into a write batch
|
||||||
rawdb.WritePreimages(batch, db.preimages)
|
if db.preimages != nil {
|
||||||
if batch.ValueSize() > ethdb.IdealBatchSize {
|
rawdb.WritePreimages(batch, db.preimages)
|
||||||
|
if batch.ValueSize() > ethdb.IdealBatchSize {
|
||||||
|
if err := batch.Write(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
batch.Reset()
|
||||||
|
}
|
||||||
|
// Since we're going to replay trie Node writes into the clean Cache, flush out
|
||||||
|
// any batched pre-images before continuing.
|
||||||
if err := batch.Write(); err != nil {
|
if err := batch.Write(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
batch.Reset()
|
batch.Reset()
|
||||||
}
|
}
|
||||||
// Since we're going to replay trie Node writes into the clean Cache, flush out
|
|
||||||
// any batched pre-images before continuing.
|
|
||||||
if err := batch.Write(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
batch.Reset()
|
|
||||||
|
|
||||||
// Move the trie itself into the batch, flushing if enough data is accumulated
|
// Move the trie itself into the batch, flushing if enough data is accumulated
|
||||||
nodes, storage := len(db.dirties), db.dirtiesSize
|
nodes, storage := len(db.dirties), db.dirtiesSize
|
||||||
|
|
||||||
|
|
@ -693,8 +720,9 @@ func (db *Database) Commit(node common.Hash, report bool) error {
|
||||||
batch.Reset()
|
batch.Reset()
|
||||||
|
|
||||||
// Reset the storage counters and bumpd metrics
|
// Reset the storage counters and bumpd metrics
|
||||||
db.preimages, db.preimagesSize = make(map[common.Hash][]byte), 0
|
if db.preimages != nil {
|
||||||
|
db.preimages, db.preimagesSize = make(map[common.Hash][]byte), 0
|
||||||
|
}
|
||||||
memcacheCommitTimeTimer.Update(time.Since(start))
|
memcacheCommitTimeTimer.Update(time.Since(start))
|
||||||
memcacheCommitSizeMeter.Mark(int64(storage - db.dirtiesSize))
|
memcacheCommitSizeMeter.Mark(int64(storage - db.dirtiesSize))
|
||||||
memcacheCommitNodesMeter.Mark(int64(nodes - len(db.dirties)))
|
memcacheCommitNodesMeter.Mark(int64(nodes - len(db.dirties)))
|
||||||
|
|
|
||||||
|
|
@ -141,12 +141,13 @@ func (t *SecureTrie) GetKey(shaKey []byte) []byte {
|
||||||
func (t *SecureTrie) Commit(onleaf LeafCallback) (root common.Hash, err error) {
|
func (t *SecureTrie) Commit(onleaf LeafCallback) (root common.Hash, err error) {
|
||||||
// Write all the pre-images to the actual disk database
|
// Write all the pre-images to the actual disk database
|
||||||
if len(t.getSecKeyCache()) > 0 {
|
if len(t.getSecKeyCache()) > 0 {
|
||||||
t.trie.Db.Lock.Lock()
|
if t.trie.Db.preimages != nil { // Ugly direct check but avoids the below write lock
|
||||||
for hk, key := range t.secKeyCache {
|
t.trie.Db.Lock.Lock()
|
||||||
t.trie.Db.InsertPreimage(common.BytesToHash([]byte(hk)), key)
|
for hk, key := range t.secKeyCache {
|
||||||
|
t.trie.Db.InsertPreimage(common.BytesToHash([]byte(hk)), key)
|
||||||
|
}
|
||||||
|
t.trie.Db.Lock.Unlock()
|
||||||
}
|
}
|
||||||
t.trie.Db.Lock.Unlock()
|
|
||||||
|
|
||||||
t.secKeyCache = make(map[string][]byte)
|
t.secKeyCache = make(map[string][]byte)
|
||||||
}
|
}
|
||||||
// Commit the trie to its intermediate Node database
|
// Commit the trie to its intermediate Node database
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue