From 788c6dc86814f1f8e2567149c4e534043633ae61 Mon Sep 17 00:00:00 2001 From: N Date: Fri, 8 Aug 2025 02:23:41 +0800 Subject: [PATCH] reduce memory and cpu usage --- core/state/statedb.go | 23 +++++++++++++++++++++++ core/state_prefetcher.go | 10 +++------- 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/core/state/statedb.go b/core/state/statedb.go index 7aa6780cfa..3ec333f9d5 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -786,6 +786,18 @@ func (s *StateDB) Finalise(deleteEmptyObjects bool) { // It is called in between transactions to get the root hash that // goes into transaction receipts. func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash { + return s.intermediateRoot(deleteEmptyObjects, false) +} + +// IntermediateRootPrefetch triggers trie loading for cache warming without +// computing the actual root hash, optimized for prefetching. +func (s *StateDB) IntermediateRootPrefetch(deleteEmptyObjects bool) { + s.intermediateRoot(deleteEmptyObjects, true) +} + +// intermediateRoot is the internal implementation that supports both normal +// and prefetch modes to reduce memory allocations in prefetching scenarios. +func (s *StateDB) intermediateRoot(deleteEmptyObjects bool, prefetchMode bool) common.Hash { // Finalise all the dirty storage states and write them into the tries s.Finalise(deleteEmptyObjects) @@ -835,6 +847,10 @@ func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash { workers.Go(func() error { if s.db.TrieDB().IsVerkle() { obj.updateTrie() + } else if prefetchMode { + // In prefetch mode, flushes cached storage mutations to trie + // for cache warming without computing the expensive root hash + obj.updateTrie() } else { obj.updateRoot() @@ -935,6 +951,13 @@ func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash { if s.prefetcher != nil { s.prefetcher.used(common.Hash{}, s.originalRoot, usedAddrs, nil) } + + // In prefetch mode, skip expensive hash computation since we only want + // the side effects of trie loading for cache warming + if prefetchMode { + return common.Hash{} + } + // Track the amount of time wasted on hashing the account trie defer func(start time.Time) { s.AccountHashes += time.Since(start) }(time.Now()) diff --git a/core/state_prefetcher.go b/core/state_prefetcher.go index c0ce705c77..c13fa580a1 100644 --- a/core/state_prefetcher.go +++ b/core/state_prefetcher.go @@ -111,12 +111,9 @@ func (p *statePrefetcher) Prefetch(block *types.Block, statedb *state.StateDB, c fails.Add(1) return nil // Ugh, something went horribly wrong, bail out } - // Pre-load trie nodes for the intermediate root. - // - // This operation incurs significant memory allocations due to - // trie hashing and node decoding. TODO(rjl493456442): investigate - // ways to mitigate this overhead. - stateCpy.IntermediateRoot(true) + // Pre-load trie nodes for cache warming without computing the actual + // intermediate root hash, reducing memory allocations and cpu cost from hashing. + stateCpy.IntermediateRootPrefetch(true) return nil }) } @@ -124,5 +121,4 @@ func (p *statePrefetcher) Prefetch(block *types.Block, statedb *state.StateDB, c blockPrefetchTxsValidMeter.Mark(int64(len(block.Transactions())) - fails.Load()) blockPrefetchTxsInvalidMeter.Mark(fails.Load()) - return }