@@ -18,14 +18,13 @@ package trie
18
18
19
19
import (
20
20
"maps"
21
-
22
- "github.com/ethereum/go-ethereum/common"
21
+ "slices"
23
22
)
24
23
25
- // tracer tracks the changes of trie nodes. During the trie operations,
24
+ // opTracer tracks the changes of trie nodes. During the trie operations,
26
25
// some nodes can be deleted from the trie, while these deleted nodes
27
26
// won't be captured by trie.Hasher or trie.Committer. Thus, these deleted
28
- // nodes won't be removed from the disk at all. Tracer is an auxiliary tool
27
+ // nodes won't be removed from the disk at all. opTracer is an auxiliary tool
29
28
// used to track all insert and delete operations of trie and capture all
30
29
// deleted nodes eventually.
31
30
//
@@ -35,38 +34,25 @@ import (
35
34
// This tool can track all of them no matter the node is embedded in its
36
35
// parent or not, but valueNode is never tracked.
37
36
//
38
- // Besides, it's also used for recording the original value of the nodes
39
- // when they are resolved from the disk. The pre-value of the nodes will
40
- // be used to construct trie history in the future.
41
- //
42
- // Note tracer is not thread-safe, callers should be responsible for handling
37
+ // Note opTracer is not thread-safe, callers should be responsible for handling
43
38
// the concurrency issues by themselves.
44
- type tracer struct {
45
- inserts map [string ]struct {}
46
- deletes map [string ]struct {}
47
- accessList map [string ][]byte
39
+ type opTracer struct {
40
+ inserts map [string ]struct {}
41
+ deletes map [string ]struct {}
48
42
}
49
43
50
- // newTracer initializes the tracer for capturing trie changes.
51
- func newTracer () * tracer {
52
- return & tracer {
53
- inserts : make (map [string ]struct {}),
54
- deletes : make (map [string ]struct {}),
55
- accessList : make (map [string ][]byte ),
44
+ // newOpTracer initializes the tracer for capturing trie changes.
45
+ func newOpTracer () * opTracer {
46
+ return & opTracer {
47
+ inserts : make (map [string ]struct {}),
48
+ deletes : make (map [string ]struct {}),
56
49
}
57
50
}
58
51
59
- // onRead tracks the newly loaded trie node and caches the rlp-encoded
60
- // blob internally. Don't change the value outside of function since
61
- // it's not deep-copied.
62
- func (t * tracer ) onRead (path []byte , val []byte ) {
63
- t .accessList [string (path )] = val
64
- }
65
-
66
52
// onInsert tracks the newly inserted trie node. If it's already
67
53
// in the deletion set (resurrected node), then just wipe it from
68
54
// the deletion set as it's "untouched".
69
- func (t * tracer ) onInsert (path []byte ) {
55
+ func (t * opTracer ) onInsert (path []byte ) {
70
56
if _ , present := t .deletes [string (path )]; present {
71
57
delete (t .deletes , string (path ))
72
58
return
@@ -77,7 +63,7 @@ func (t *tracer) onInsert(path []byte) {
77
63
// onDelete tracks the newly deleted trie node. If it's already
78
64
// in the addition set, then just wipe it from the addition set
79
65
// as it's untouched.
80
- func (t * tracer ) onDelete (path []byte ) {
66
+ func (t * opTracer ) onDelete (path []byte ) {
81
67
if _ , present := t .inserts [string (path )]; present {
82
68
delete (t .inserts , string (path ))
83
69
return
@@ -86,37 +72,83 @@ func (t *tracer) onDelete(path []byte) {
86
72
}
87
73
88
74
// reset clears the content tracked by tracer.
89
- func (t * tracer ) reset () {
90
- t .inserts = make (map [string ]struct {})
91
- t .deletes = make (map [string ]struct {})
92
- t .accessList = make (map [string ][]byte )
75
+ func (t * opTracer ) reset () {
76
+ clear (t .inserts )
77
+ clear (t .deletes )
93
78
}
94
79
95
80
// copy returns a deep copied tracer instance.
96
- func (t * tracer ) copy () * tracer {
97
- accessList := make (map [string ][]byte , len (t .accessList ))
98
- for path , blob := range t .accessList {
99
- accessList [path ] = common .CopyBytes (blob )
100
- }
101
- return & tracer {
102
- inserts : maps .Clone (t .inserts ),
103
- deletes : maps .Clone (t .deletes ),
104
- accessList : accessList ,
81
+ func (t * opTracer ) copy () * opTracer {
82
+ return & opTracer {
83
+ inserts : maps .Clone (t .inserts ),
84
+ deletes : maps .Clone (t .deletes ),
105
85
}
106
86
}
107
87
108
- // deletedNodes returns a list of node paths which are deleted from the trie.
109
- func (t * tracer ) deletedNodes () []string {
110
- var paths [] string
88
+ // deletedList returns a list of node paths which are deleted from the trie.
89
+ func (t * opTracer ) deletedList () [][] byte {
90
+ paths := make ([][] byte , 0 , len ( t . deletes ))
111
91
for path := range t .deletes {
112
- // It's possible a few deleted nodes were embedded
113
- // in their parent before, the deletions can be no
114
- // effect by deleting nothing, filter them out.
115
- _ , ok := t .accessList [path ]
116
- if ! ok {
117
- continue
118
- }
119
- paths = append (paths , path )
92
+ paths = append (paths , []byte (path ))
120
93
}
121
94
return paths
122
95
}
96
+
97
+ // prevalueTracer tracks the original values of resolved trie nodes. Cached trie
98
+ // node values are expected to be immutable. A zero-size node value is treated as
99
+ // non-existent and should not occur in practice.
100
+ //
101
+ // Note prevalueTracer is not thread-safe, callers should be responsible for
102
+ // handling the concurrency issues by themselves.
103
+ type prevalueTracer struct {
104
+ data map [string ][]byte
105
+ }
106
+
107
+ // newPrevalueTracer initializes the tracer for capturing resolved trie nodes.
108
+ func newPrevalueTracer () * prevalueTracer {
109
+ return & prevalueTracer {
110
+ data : make (map [string ][]byte ),
111
+ }
112
+ }
113
+
114
+ // put tracks the newly loaded trie node and caches its RLP-encoded
115
+ // blob internally. Do not modify the value outside this function,
116
+ // as it is not deep-copied.
117
+ func (t * prevalueTracer ) put (path []byte , val []byte ) {
118
+ t .data [string (path )] = val
119
+ }
120
+
121
+ // get returns the cached trie node value. If the node is not found, nil will
122
+ // be returned.
123
+ func (t * prevalueTracer ) get (path []byte ) []byte {
124
+ return t .data [string (path )]
125
+ }
126
+
127
+ // hasList returns a list of flags indicating whether the corresponding trie nodes
128
+ // specified by the path exist in the trie.
129
+ func (t * prevalueTracer ) hasList (list [][]byte ) []bool {
130
+ exists := make ([]bool , 0 , len (list ))
131
+ for _ , path := range list {
132
+ _ , ok := t .data [string (path )]
133
+ exists = append (exists , ok )
134
+ }
135
+ return exists
136
+ }
137
+
138
+ // values returns a list of values of the cached trie nodes.
139
+ func (t * prevalueTracer ) values () [][]byte {
140
+ return slices .Collect (maps .Values (t .data ))
141
+ }
142
+
143
+ // reset resets the cached content in the prevalueTracer.
144
+ func (t * prevalueTracer ) reset () {
145
+ clear (t .data )
146
+ }
147
+
148
+ // copy returns a copied prevalueTracer instance.
149
+ func (t * prevalueTracer ) copy () * prevalueTracer {
150
+ // Shadow clone is used, as the cached trie node values are immutable
151
+ return & prevalueTracer {
152
+ data : maps .Clone (t .data ),
153
+ }
154
+ }
0 commit comments