@@ -19,7 +19,6 @@ package trie
1919import (
2020 "fmt"
2121 "reflect"
22- "sort"
2322 "strings"
2423
2524 "github.com/ethereum/go-ethereum/common"
@@ -41,8 +40,8 @@ var memoryNodeSize = int(reflect.TypeOf(memoryNode{}).Size())
4140
4241// memorySize returns the total memory size used by this node.
4342// nolint:unused
44- func (n * memoryNode ) memorySize (pathlen int ) int {
45- return int (n .size ) + memoryNodeSize + pathlen
43+ func (n * memoryNode ) memorySize (key int ) int {
44+ return int (n .size ) + memoryNodeSize + key
4645}
4746
4847// rlp returns the raw rlp encoded blob of the cached trie node, either directly
@@ -65,107 +64,96 @@ func (n *memoryNode) obj() node {
6564 return expandNode (n .hash [:], n .node )
6665}
6766
68- // isDeleted returns the indicator if the node is marked as deleted.
69- func (n * memoryNode ) isDeleted () bool {
70- return n .hash == (common.Hash {})
71- }
72-
7367// nodeWithPrev wraps the memoryNode with the previous node value.
74- // nolint: unused
7568type nodeWithPrev struct {
7669 * memoryNode
7770 prev []byte // RLP-encoded previous value, nil means it's non-existent
7871}
7972
8073// unwrap returns the internal memoryNode object.
81- // nolint: unused
74+ // nolint:unused
8275func (n * nodeWithPrev ) unwrap () * memoryNode {
8376 return n .memoryNode
8477}
8578
8679// memorySize returns the total memory size used by this node. It overloads
8780// the function in memoryNode by counting the size of previous value as well.
8881// nolint: unused
89- func (n * nodeWithPrev ) memorySize (pathlen int ) int {
90- return n .memoryNode .memorySize (pathlen ) + len (n .prev )
82+ func (n * nodeWithPrev ) memorySize (key int ) int {
83+ return n .memoryNode .memorySize (key ) + len (n .prev )
84+ }
85+
86+ // nodesWithOrder represents a collection of dirty nodes which includes
87+ // newly-inserted and updated nodes. The modification order of all nodes
88+ // is represented by order list.
89+ type nodesWithOrder struct {
90+ order []string // the path list of dirty nodes, sort by insertion order
91+ nodes map [string ]* nodeWithPrev // the map of dirty nodes, keyed by node path
9192}
9293
9394// NodeSet contains all dirty nodes collected during the commit operation.
9495// Each node is keyed by path. It's not thread-safe to use.
9596type NodeSet struct {
96- owner common.Hash // the identifier of the trie
97- nodes map [ string ] * memoryNode // the set of dirty nodes(inserted, updated, deleted )
98- leaves [] * leaf // the list of dirty leaves
99- accessList map [ string ][] byte // The list of accessed nodes, which records the original node value
97+ owner common.Hash // the identifier of the trie
98+ updates * nodesWithOrder // the set of updated nodes(newly inserted, updated)
99+ deletes map [ string ][] byte // the map of deleted nodes, keyed by node
100+ leaves [] * leaf // the list of dirty leaves
100101}
101102
102103// NewNodeSet initializes an empty node set to be used for tracking dirty nodes
103- // for a specific account or storage trie. The owner is zero for the account trie
104- // and the owning account address hash for storage tries. The provided accessList
105- // represents the original value of accessed nodes, it can be optional but would
106- // be beneficial for speeding up the construction of trie history.
107- func NewNodeSet (owner common.Hash , accessList map [string ][]byte ) * NodeSet {
108- // Don't panic for lazy users
109- if accessList == nil {
110- accessList = make (map [string ][]byte )
111- }
104+ // from a specific account or storage trie. The owner is zero for the account
105+ // trie and the owning account address hash for storage tries.
106+ func NewNodeSet (owner common.Hash ) * NodeSet {
112107 return & NodeSet {
113- owner : owner ,
114- nodes : make (map [string ]* memoryNode ),
115- accessList : accessList ,
108+ owner : owner ,
109+ updates : & nodesWithOrder {
110+ nodes : make (map [string ]* nodeWithPrev ),
111+ },
112+ deletes : make (map [string ][]byte ),
116113 }
117114}
118115
119- // forEachWithOrder iterates the dirty nodes with the specified order.
120- // If topToBottom is true:
121- //
122- // then the order of iteration is top to bottom, left to right.
123- //
124- // If topToBottom is false:
125- //
126- // then the order of iteration is bottom to top, right to left.
127- func (set * NodeSet ) forEachWithOrder (topToBottom bool , callback func (path string , n * memoryNode )) {
128- var paths sort.StringSlice
129- for path := range set .nodes {
130- paths = append (paths , path )
131- }
132- if topToBottom {
133- paths .Sort ()
134- } else {
135- sort .Sort (sort .Reverse (paths ))
136- }
137- for _ , path := range paths {
138- callback (path , set .nodes [path ])
116+ /*
117+ // NewNodeSetWithDeletion initializes the nodeset with provided deletion set.
118+ func NewNodeSetWithDeletion(owner common.Hash, paths [][]byte, prev [][]byte) *NodeSet {
119+ set := NewNodeSet(owner)
120+ for i, path := range paths {
121+ set.markDeleted(path, prev[i])
139122 }
123+ return set
140124}
125+ */
141126
142127// markUpdated marks the node as dirty(newly-inserted or updated) with provided
143128// node path, node object along with its previous value.
144- func (set * NodeSet ) markUpdated (path []byte , node * memoryNode ) {
145- set .nodes [string (path )] = node
129+ func (set * NodeSet ) markUpdated (path []byte , node * memoryNode , prev []byte ) {
130+ set .updates .order = append (set .updates .order , string (path ))
131+ set .updates .nodes [string (path )] = & nodeWithPrev {
132+ memoryNode : node ,
133+ prev : prev ,
134+ }
146135}
147136
148137// markDeleted marks the node as deleted with provided path and previous value.
149- // nolint: unused
150- func (set * NodeSet ) markDeleted (path []byte ) {
151- set .nodes [string (path )] = & memoryNode {}
138+ func (set * NodeSet ) markDeleted (path []byte , prev []byte ) {
139+ set .deletes [string (path )] = prev
152140}
153141
154142// addLeaf collects the provided leaf node into set.
155143func (set * NodeSet ) addLeaf (node * leaf ) {
156144 set .leaves = append (set .leaves , node )
157145}
158146
159- // Size returns the number of dirty nodes contained in the set.
160- func (set * NodeSet ) Size () int {
161- return len (set .nodes )
147+ // Size returns the number of updated and deleted nodes contained in the set.
148+ func (set * NodeSet ) Size () ( int , int ) {
149+ return len (set .updates . order ), len ( set . deletes )
162150}
163151
164152// Hashes returns the hashes of all updated nodes. TODO(rjl493456442) how can
165153// we get rid of it?
166154func (set * NodeSet ) Hashes () []common.Hash {
167155 var ret []common.Hash
168- for _ , node := range set .nodes {
156+ for _ , node := range set .updates . nodes {
169157 ret = append (ret , node .hash )
170158 }
171159 return ret
@@ -175,17 +163,19 @@ func (set *NodeSet) Hashes() []common.Hash {
175163func (set * NodeSet ) Summary () string {
176164 var out = new (strings.Builder )
177165 fmt .Fprintf (out , "nodeset owner: %v\n " , set .owner )
178- if set .nodes != nil {
179- for path , n := range set .nodes {
180- // Deletion
181- if n .isDeleted () {
182- fmt .Fprintf (out , " [-]: %x\n " , path )
183- continue
166+ if set .updates != nil {
167+ for _ , key := range set .updates .order {
168+ updated := set .updates .nodes [key ]
169+ if updated .prev != nil {
170+ fmt .Fprintf (out , " [*]: %x -> %v prev: %x\n " , key , updated .hash , updated .prev )
171+ } else {
172+ fmt .Fprintf (out , " [+]: %x -> %v\n " , key , updated .hash )
184173 }
185- // Update
186- fmt .Fprintf (out , " [+]: %x -> %v\n " , path , n .hash )
187174 }
188175 }
176+ for k , n := range set .deletes {
177+ fmt .Fprintf (out , " [-]: %x -> %x\n " , k , n )
178+ }
189179 for _ , n := range set .leaves {
190180 fmt .Fprintf (out , "[leaf]: %v\n " , n )
191181 }
0 commit comments