core/stateless: speed up witness stats leaf tracking

This commit is contained in:
Sahil Sojitra 2026-04-27 14:36:35 +05:30
parent 2d5da60371
commit 1e0dfc1adb

View file

@ -18,11 +18,7 @@ package stateless
import ( import (
"encoding/json" "encoding/json"
"maps"
"slices"
"sort"
"strconv" "strconv"
"strings"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
@ -44,6 +40,7 @@ func init() {
type WitnessStats struct { type WitnessStats struct {
accountTrie *trie.LevelStats accountTrie *trie.LevelStats
storageTrie *trie.LevelStats storageTrie *trie.LevelStats
prefixes map[string]struct{}
} }
// NewWitnessStats creates a new WitnessStats collector. // NewWitnessStats creates a new WitnessStats collector.
@ -76,19 +73,23 @@ func (s *WitnessStats) init() {
func (s *WitnessStats) Add(nodes map[string][]byte, owner common.Hash) { func (s *WitnessStats) Add(nodes map[string][]byte, owner common.Hash) {
s.init() s.init()
// Extract paths from the nodes map.
paths := slices.Collect(maps.Keys(nodes))
sort.Strings(paths)
ownerStat := s.accountTrie ownerStat := s.accountTrie
if owner != (common.Hash{}) { if owner != (common.Hash{}) {
ownerStat = s.storageTrie ownerStat = s.storageTrie
} }
for i, path := range paths { if s.prefixes == nil {
// If current path is a prefix of the next path, it's not a leaf. s.prefixes = make(map[string]struct{}, len(nodes))
// The last path is always a leaf. } else {
if i == len(paths)-1 || !strings.HasPrefix(paths[i+1], paths[i]) { clear(s.prefixes)
}
for path := range nodes {
for i := 0; i < len(path); i++ {
s.prefixes[path[:i]] = struct{}{}
}
}
for path := range nodes {
if _, ok := s.prefixes[path]; !ok {
ownerStat.AddLeaf(len(path)) ownerStat.AddLeaf(len(path))
} }
} }