diff --git a/cmd/geth/main.go b/cmd/geth/main.go index a6af14006c99fd21090141c4d2d9a48350e9adad..1f9ab90e251eea18497352d0051adb9f395f7043 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -43,6 +43,10 @@ import ( "github.com/ledgerwatch/turbo-geth/log" "github.com/ledgerwatch/turbo-geth/metrics" "github.com/ledgerwatch/turbo-geth/node" + + "net/http" + //nolint:gosec + _ "net/http/pprof" ) const ( @@ -260,6 +264,9 @@ func init() { } func main() { + go func() { + log.Info("HTTP", "error", http.ListenAndServe("localhost:6060", nil)) + }() if err := app.Run(os.Args); err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) diff --git a/core/blockchain.go b/core/blockchain.go index 5aaf75081ebe70e5ebfcb50fbca3c600aaf3bf1f..d6ca2d2eaf855e1ddd69f9f98c470ed7abb8cfc5 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -1924,7 +1924,7 @@ func (st *insertStats) report(chain []*types.Block, index int, batch ethdb.DbWit context := []interface{}{ "blocks", st.processed, "txs", txs, "mgas", float64(st.usedGas) / 1000000, "elapsed", common.PrettyDuration(elapsed), "mgasps", float64(st.usedGas) * 1000 / float64(elapsed), - "number", end.Number(), "hash", end.Hash(), "batch", batch.BatchSize(), + "number", end.Number(), "hash", end.Hash(), "batch", common.StorageSize(batch.BatchSize()), } if timestamp := time.Unix(int64(end.Time()), 0); time.Since(timestamp) > time.Minute { context = append(context, []interface{}{"age", common.PrettyAge(timestamp)}...) diff --git a/core/state/db_state_reader.go b/core/state/db_state_reader.go index c2a5b9b297c85aaa79b42f6334b8b0bfae845753..3e0c9e6189f6153e50ad32cbb30c7d39a6221c95 100644 --- a/core/state/db_state_reader.go +++ b/core/state/db_state_reader.go @@ -68,7 +68,7 @@ func (dbr *DbStateReader) ReadAccountData(address common.Address) (*accounts.Acc return nil, nil } if dbr.accountCache != nil { - dbr.accountCache.Add(address, &a) + dbr.accountCache.Add(address, a.SelfCopy()) } return &a, nil } @@ -118,9 +118,12 @@ func (dbr *DbStateReader) ReadAccountCode(address common.Address, codeHash commo } } code, err = dbr.db.Get(dbutils.CodeBucket, codeHash[:]) - if dbr.codeCache != nil { + if dbr.codeCache != nil && len(code) <= 1024 { dbr.codeCache.Add(address, code) } + if dbr.codeSizeCache != nil { + dbr.codeSizeCache.Add(address, len(code)) + } return code, err } diff --git a/core/state/db_state_writer.go b/core/state/db_state_writer.go index 9b862b5cdb59cf62ae938e7e340b0adb51a96304..0050698e28ab9e3995a70b13bf27fd0651eda1a2 100644 --- a/core/state/db_state_writer.go +++ b/core/state/db_state_writer.go @@ -88,7 +88,7 @@ func (dsw *DbStateWriter) UpdateAccountData(ctx context.Context, address common. return err } if dsw.accountCache != nil { - dsw.accountCache.Add(address, account) + dsw.accountCache.Add(address, account.SelfCopy()) } return nil } @@ -129,7 +129,7 @@ func (dsw *DbStateWriter) UpdateAccountCode(address common.Address, incarnation if err := dsw.stateDb.Put(dbutils.ContractCodeBucket, dbutils.GenerateStoragePrefix(addrHash[:], incarnation), codeHash[:]); err != nil { return err } - if dsw.codeCache != nil { + if dsw.codeCache != nil && len(code) <= 1024 { dsw.codeCache.Add(address, code) } if dsw.codeSizeCache != nil { diff --git a/eth/downloader/stagedsync_stage_execute.go b/eth/downloader/stagedsync_stage_execute.go index 765f11d425907b3eadc9e8ab874807906a6ef031..6961077fb8b0919fae7f93eca86e321232cd5cff 100644 --- a/eth/downloader/stagedsync_stage_execute.go +++ b/eth/downloader/stagedsync_stage_execute.go @@ -28,13 +28,15 @@ type progressLogger struct { timer *time.Ticker quit chan struct{} interval int + batch ethdb.DbWithPendingMutations } -func NewProgressLogger(intervalInSeconds int) *progressLogger { +func NewProgressLogger(intervalInSeconds int, batch ethdb.DbWithPendingMutations) *progressLogger { return &progressLogger{ timer: time.NewTicker(time.Duration(intervalInSeconds) * time.Second), quit: make(chan struct{}), interval: intervalInSeconds, + batch: batch, } } @@ -46,7 +48,7 @@ func (l *progressLogger) Start(numberRef *uint64) { speed := float64(now-prev) / float64(l.interval) var m runtime.MemStats runtime.ReadMemStats(&m) - log.Info("Executed blocks:", "currentBlock", now, "speed (blk/second)", speed, + log.Info("Executed blocks:", "currentBlock", now, "speed (blk/second)", speed, "state batch", common.StorageSize(l.batch.BatchSize()), "alloc", int(m.Alloc/1024), "sys", int(m.Sys/1024), "numGC", int(m.NumGC)) prev = now } @@ -67,8 +69,8 @@ func (l *progressLogger) Stop() { close(l.quit) } -const StateBatchSize = 1000000 -const ChangeBatchSize = 1000 +const StateBatchSize = 50 * 1024 * 1024 // 50 Mb +const ChangeBatchSize = 1024 * 2014 // 1 Mb func spawnExecuteBlocksStage(stateDB ethdb.Database, blockchain BlockChain) (uint64, error) { lastProcessedBlockNumber, err := GetStageProgress(stateDB, Execution) @@ -94,7 +96,7 @@ func spawnExecuteBlocksStage(stateDB ethdb.Database, blockchain BlockChain) (uin stateBatch := stateDB.NewBatch() changeBatch := stateDB.NewBatch() - progressLogger := NewProgressLogger(logInterval) + progressLogger := NewProgressLogger(logInterval, stateBatch) progressLogger.Start(&nextBlockNumber) defer progressLogger.Stop() diff --git a/ethdb/bolt_db.go b/ethdb/bolt_db.go index 2a5f75d7566a5f3186b175e9245f616e1073f3ea..816a34433f19f4ff870c738466f518628b37bf06 100644 --- a/ethdb/bolt_db.go +++ b/ethdb/bolt_db.go @@ -725,7 +725,7 @@ func (db *BoltDatabase) NewBatch() DbWithPendingMutations { // IdealBatchSize defines the size of the data batches should ideally add in one write. func (db *BoltDatabase) IdealBatchSize() int { - return 100 * 1024 + return 50 * 1024 * 1024 // 50 Mb } // [TURBO-GETH] Freezer support (not implemented yet) diff --git a/ethdb/mutation.go b/ethdb/mutation.go index c5887c8f2fee7af34eb7c47ad208955792d898c8..14f947ad72f32c47db92dbc228b0675f8ca61506 100644 --- a/ethdb/mutation.go +++ b/ethdb/mutation.go @@ -11,7 +11,7 @@ import ( ) type mutation struct { - puts puts // Map buckets to map[key]value + puts *puts // Map buckets to map[key]value mu sync.RWMutex db Database } diff --git a/ethdb/mutation_puts.go b/ethdb/mutation_puts.go index 83122af419981806ffe47b66e0c50a124ad17300..5413b10133f58eadbab8b8749a4e5ebf5ead56f3 100644 --- a/ethdb/mutation_puts.go +++ b/ethdb/mutation_puts.go @@ -1,29 +1,35 @@ package ethdb -import ( -) - type puts struct { - mp map[string]putsBucket //map[bucket]putsBucket + mp map[string]putsBucket //map[bucket]putsBucket + size int } -func newPuts() puts { - return puts{ - mp: make(map[string]putsBucket), +func newPuts() *puts { + return &puts{ + mp: make(map[string]putsBucket), + size: 0, } } -func (p puts) set(bucket, key, value []byte) { +func (p *puts) set(bucket, key, value []byte) { var bucketPuts putsBucket var ok bool if bucketPuts, ok = p.mp[string(bucket)]; !ok { bucketPuts = make(putsBucket) p.mp[string(bucket)] = bucketPuts } + skey := string(key) + if oldVal, ok := bucketPuts[skey]; ok { + p.size -= len(oldVal) + } else { + p.size += len(skey) + 32 // Add fixed overhead per key + } bucketPuts[string(key)] = value + p.size += len(value) } -func (p puts) get(bucket, key []byte) ([]byte, bool) { +func (p *puts) get(bucket, key []byte) ([]byte, bool) { var bucketPuts putsBucket var ok bool if bucketPuts, ok = p.mp[string(bucket)]; !ok { @@ -32,16 +38,12 @@ func (p puts) get(bucket, key []byte) ([]byte, bool) { return bucketPuts.Get(key) } -func (p puts) Delete(bucket, key []byte) { +func (p *puts) Delete(bucket, key []byte) { p.set(bucket, key, nil) } -func (p puts) Size() int { - var size int - for _, put := range p.mp { - size += len(put) - } - return size +func (p *puts) Size() int { + return p.size } type putsBucket map[string][]byte //map[key]value @@ -71,4 +73,3 @@ func (pb putsBucket) GetStr(key string) ([]byte, bool) { return value, true } -