triedb/pathdb: polish code

This commit is contained in:
Gary Rong 2025-03-04 16:35:33 +08:00
parent 5afd54abb3
commit 20830ec86b

View file

@ -47,22 +47,17 @@ func newNodeSet(nodes map[common.Hash]map[string]*trienode.Node) *nodeSet {
if nodes == nil { if nodes == nil {
nodes = make(map[common.Hash]map[string]*trienode.Node) nodes = make(map[common.Hash]map[string]*trienode.Node)
} }
// Create the new structure with separate maps
s := &nodeSet{ s := &nodeSet{
accountNodes: make(map[string]*trienode.Node), accountNodes: make(map[string]*trienode.Node),
storageNodes: make(map[common.Hash]map[string]*trienode.Node), storageNodes: make(map[common.Hash]map[string]*trienode.Node),
} }
// Migrate the nodes to the appropriate maps
for owner, subset := range nodes { for owner, subset := range nodes {
if owner == (common.Hash{}) { if owner == (common.Hash{}) {
maps.Copy(s.accountNodes, subset) s.accountNodes = subset
} else { } else {
s.storageNodes[owner] = maps.Clone(subset) s.storageNodes[owner] = subset
} }
} }
s.computeSize() s.computeSize()
return s return s
} }
@ -70,15 +65,12 @@ func newNodeSet(nodes map[common.Hash]map[string]*trienode.Node) *nodeSet {
// computeSize calculates the database size of the held trie nodes. // computeSize calculates the database size of the held trie nodes.
func (s *nodeSet) computeSize() { func (s *nodeSet) computeSize() {
var size uint64 var size uint64
for path, n := range s.accountNodes { for path, n := range s.accountNodes {
size += uint64(len(n.Blob) + len(path)) size += uint64(len(n.Blob) + len(path))
} }
for _, subset := range s.storageNodes { for _, subset := range s.storageNodes {
prefix := common.HashLength // owner (32 bytes) for storage trie nodes
for path, n := range subset { for path, n := range subset {
size += uint64(prefix + len(n.Blob) + len(path)) size += uint64(common.HashLength + len(n.Blob) + len(path))
} }
} }
s.size = size s.size = size
@ -97,12 +89,11 @@ func (s *nodeSet) updateSize(delta int64) {
// node retrieves the trie node with node path and its trie identifier. // node retrieves the trie node with node path and its trie identifier.
func (s *nodeSet) node(owner common.Hash, path []byte) (*trienode.Node, bool) { func (s *nodeSet) node(owner common.Hash, path []byte) (*trienode.Node, bool) {
if owner == (common.Hash{}) {
// Account trie node // Account trie node
if owner == (common.Hash{}) {
n, ok := s.accountNodes[string(path)] n, ok := s.accountNodes[string(path)]
return n, ok return n, ok
} }
// Storage trie node // Storage trie node
subset, ok := s.storageNodes[owner] subset, ok := s.storageNodes[owner]
if !ok { if !ok {
@ -133,11 +124,10 @@ func (s *nodeSet) merge(set *nodeSet) {
// Merge storage nodes // Merge storage nodes
for owner, subset := range set.storageNodes { for owner, subset := range set.storageNodes {
prefix := common.HashLength
current, exist := s.storageNodes[owner] current, exist := s.storageNodes[owner]
if !exist { if !exist {
for path, n := range subset { for path, n := range subset {
delta += int64(prefix + len(n.Blob) + len(path)) delta += int64(common.HashLength + len(n.Blob) + len(path))
} }
// Perform a shallow copy of the map for the subset instead of claiming it // Perform a shallow copy of the map for the subset instead of claiming it
// directly from the provided nodeset to avoid potential concurrent map // directly from the provided nodeset to avoid potential concurrent map
@ -150,10 +140,10 @@ func (s *nodeSet) merge(set *nodeSet) {
} }
for path, n := range subset { for path, n := range subset {
if orig, exist := current[path]; !exist { if orig, exist := current[path]; !exist {
delta += int64(prefix + len(n.Blob) + len(path)) delta += int64(common.HashLength + len(n.Blob) + len(path))
} else { } else {
delta += int64(len(n.Blob) - len(orig.Blob)) delta += int64(len(n.Blob) - len(orig.Blob))
overwrite.add(prefix + len(orig.Blob) + len(path)) overwrite.add(common.HashLength + len(orig.Blob) + len(path))
} }
current[path] = n current[path] = n
} }
@ -177,7 +167,7 @@ func (s *nodeSet) revertTo(db ethdb.KeyValueReader, nodes map[common.Hash]map[st
if bytes.Equal(blob, n.Blob) { if bytes.Equal(blob, n.Blob) {
continue continue
} }
panic(fmt.Sprintf("non-existent node (account %v) blob: %v", path, crypto.Keccak256Hash(n.Blob).Hex())) panic(fmt.Sprintf("non-existent account node (%v) blob: %v", path, crypto.Keccak256Hash(n.Blob).Hex()))
} }
s.accountNodes[path] = n s.accountNodes[path] = n
delta += int64(len(n.Blob)) - int64(len(orig.Blob)) delta += int64(len(n.Blob)) - int64(len(orig.Blob))
@ -195,7 +185,7 @@ func (s *nodeSet) revertTo(db ethdb.KeyValueReader, nodes map[common.Hash]map[st
if bytes.Equal(blob, n.Blob) { if bytes.Equal(blob, n.Blob) {
continue continue
} }
panic(fmt.Sprintf("non-existent node (%x %v) blob: %v", owner, path, crypto.Keccak256Hash(n.Blob).Hex())) panic(fmt.Sprintf("non-existent storage node (%x %v) blob: %v", owner, path, crypto.Keccak256Hash(n.Blob).Hex()))
} }
current[path] = n current[path] = n
delta += int64(len(n.Blob)) - int64(len(orig.Blob)) delta += int64(len(n.Blob)) - int64(len(orig.Blob))
@ -220,7 +210,7 @@ type journalNodes struct {
// encode serializes the content of trie nodes into the provided writer. // encode serializes the content of trie nodes into the provided writer.
func (s *nodeSet) encode(w io.Writer) error { func (s *nodeSet) encode(w io.Writer) error {
nodes := make([]journalNodes, 0, len(s.storageNodes)+len(s.accountNodes)) nodes := make([]journalNodes, 0, len(s.storageNodes)+1)
// Encode account nodes // Encode account nodes
if len(s.accountNodes) > 0 { if len(s.accountNodes) > 0 {
@ -233,7 +223,6 @@ func (s *nodeSet) encode(w io.Writer) error {
} }
nodes = append(nodes, entry) nodes = append(nodes, entry)
} }
// Encode storage nodes // Encode storage nodes
for owner, subset := range s.storageNodes { for owner, subset := range s.storageNodes {
entry := journalNodes{Owner: owner} entry := journalNodes{Owner: owner}
@ -254,12 +243,9 @@ func (s *nodeSet) decode(r *rlp.Stream) error {
if err := r.Decode(&encoded); err != nil { if err := r.Decode(&encoded); err != nil {
return fmt.Errorf("load nodes: %v", err) return fmt.Errorf("load nodes: %v", err)
} }
// Initialize the maps
s.accountNodes = make(map[string]*trienode.Node) s.accountNodes = make(map[string]*trienode.Node)
s.storageNodes = make(map[common.Hash]map[string]*trienode.Node) s.storageNodes = make(map[common.Hash]map[string]*trienode.Node)
// Decode the nodes
for _, entry := range encoded { for _, entry := range encoded {
if entry.Owner == (common.Hash{}) { if entry.Owner == (common.Hash{}) {
// Account nodes // Account nodes
@ -289,19 +275,13 @@ func (s *nodeSet) decode(r *rlp.Stream) error {
// write flushes nodes into the provided database batch as a whole. // write flushes nodes into the provided database batch as a whole.
func (s *nodeSet) write(batch ethdb.Batch, clean *fastcache.Cache) int { func (s *nodeSet) write(batch ethdb.Batch, clean *fastcache.Cache) int {
// Convert the separate maps back to the format expected by writeNodes
nodes := make(map[common.Hash]map[string]*trienode.Node) nodes := make(map[common.Hash]map[string]*trienode.Node)
// Add account nodes
if len(s.accountNodes) > 0 { if len(s.accountNodes) > 0 {
nodes[common.Hash{}] = s.accountNodes nodes[common.Hash{}] = s.accountNodes
} }
// Add storage nodes
for owner, subset := range s.storageNodes { for owner, subset := range s.storageNodes {
nodes[owner] = subset nodes[owner] = subset
} }
return writeNodes(batch, nodes, clean) return writeNodes(batch, nodes, clean)
} }
@ -315,12 +295,9 @@ func (s *nodeSet) reset() {
// dbsize returns the approximate size of db write. // dbsize returns the approximate size of db write.
func (s *nodeSet) dbsize() int { func (s *nodeSet) dbsize() int {
var m int var m int
m += len(s.accountNodes) * len(rawdb.TrieNodeAccountPrefix) // database key prefix m += len(s.accountNodes) * len(rawdb.TrieNodeAccountPrefix) // database key prefix
for _, nodes := range s.storageNodes { for _, nodes := range s.storageNodes {
m += len(nodes) * (len(rawdb.TrieNodeStoragePrefix)) // database key prefix m += len(nodes) * (len(rawdb.TrieNodeStoragePrefix)) // database key prefix
} }
return m + int(s.size) return m + int(s.size)
} }