@@ -39,21 +39,21 @@ type binaryIterator struct {
39
39
// initBinaryAccountIterator creates a simplistic iterator to step over all the
40
40
// accounts in a slow, but easily verifiable way. Note this function is used for
41
41
// initialization, use `newBinaryAccountIterator` as the API.
42
- func (dl * diffLayer ) initBinaryAccountIterator () Iterator {
42
+ func (dl * diffLayer ) initBinaryAccountIterator (seek common. Hash ) Iterator {
43
43
parent , ok := dl .parent .(* diffLayer )
44
44
if ! ok {
45
45
l := & binaryIterator {
46
- a : dl .AccountIterator (common. Hash {} ),
47
- b : dl .Parent ().AccountIterator (common. Hash {} ),
46
+ a : dl .AccountIterator (seek ),
47
+ b : dl .Parent ().AccountIterator (seek ),
48
48
accountIterator : true ,
49
49
}
50
50
l .aDone = ! l .a .Next ()
51
51
l .bDone = ! l .b .Next ()
52
52
return l
53
53
}
54
54
l := & binaryIterator {
55
- a : dl .AccountIterator (common. Hash {} ),
56
- b : parent .initBinaryAccountIterator (),
55
+ a : dl .AccountIterator (seek ),
56
+ b : parent .initBinaryAccountIterator (seek ),
57
57
accountIterator : true ,
58
58
}
59
59
l .aDone = ! l .a .Next ()
@@ -64,12 +64,12 @@ func (dl *diffLayer) initBinaryAccountIterator() Iterator {
64
64
// initBinaryStorageIterator creates a simplistic iterator to step over all the
65
65
// storage slots in a slow, but easily verifiable way. Note this function is used
66
66
// for initialization, use `newBinaryStorageIterator` as the API.
67
- func (dl * diffLayer ) initBinaryStorageIterator (account common.Hash ) Iterator {
67
+ func (dl * diffLayer ) initBinaryStorageIterator (account , seek common.Hash ) Iterator {
68
68
parent , ok := dl .parent .(* diffLayer )
69
69
if ! ok {
70
70
// If the storage in this layer is already destructed, discard all
71
71
// deeper layers but still return a valid single-branch iterator.
72
- a , destructed := dl .StorageIterator (account , common. Hash {} )
72
+ a , destructed := dl .StorageIterator (account , seek )
73
73
if destructed {
74
74
l := & binaryIterator {
75
75
a : a ,
@@ -81,7 +81,7 @@ func (dl *diffLayer) initBinaryStorageIterator(account common.Hash) Iterator {
81
81
}
82
82
// The parent is disk layer, don't need to take care "destructed"
83
83
// anymore.
84
- b , _ := dl .Parent ().StorageIterator (account , common. Hash {} )
84
+ b , _ := dl .Parent ().StorageIterator (account , seek )
85
85
l := & binaryIterator {
86
86
a : a ,
87
87
b : b ,
@@ -93,7 +93,7 @@ func (dl *diffLayer) initBinaryStorageIterator(account common.Hash) Iterator {
93
93
}
94
94
// If the storage in this layer is already destructed, discard all
95
95
// deeper layers but still return a valid single-branch iterator.
96
- a , destructed := dl .StorageIterator (account , common. Hash {} )
96
+ a , destructed := dl .StorageIterator (account , seek )
97
97
if destructed {
98
98
l := & binaryIterator {
99
99
a : a ,
@@ -105,7 +105,7 @@ func (dl *diffLayer) initBinaryStorageIterator(account common.Hash) Iterator {
105
105
}
106
106
l := & binaryIterator {
107
107
a : a ,
108
- b : parent .initBinaryStorageIterator (account ),
108
+ b : parent .initBinaryStorageIterator (account , seek ),
109
109
account : account ,
110
110
}
111
111
l .aDone = ! l .a .Next ()
@@ -117,33 +117,50 @@ func (dl *diffLayer) initBinaryStorageIterator(account common.Hash) Iterator {
117
117
// or an error if iteration failed for some reason (e.g. root being iterated
118
118
// becomes stale and garbage collected).
119
119
func (it * binaryIterator ) Next () bool {
120
+ for {
121
+ if ! it .next () {
122
+ return false
123
+ }
124
+ if len (it .Account ()) != 0 || len (it .Slot ()) != 0 {
125
+ return true
126
+ }
127
+ // it.fail might be set if error occurs by calling
128
+ // it.Account() or it.Slot(), stop iteration if so.
129
+ if it .fail != nil {
130
+ return false
131
+ }
132
+ }
133
+ }
134
+
135
+ func (it * binaryIterator ) next () bool {
120
136
if it .aDone && it .bDone {
121
137
return false
122
138
}
123
- first:
124
- if it .aDone {
125
- it .k = it .b .Hash ()
139
+ for {
140
+ if it .aDone {
141
+ it .k = it .b .Hash ()
142
+ it .bDone = ! it .b .Next ()
143
+ return true
144
+ }
145
+ if it .bDone {
146
+ it .k = it .a .Hash ()
147
+ it .aDone = ! it .a .Next ()
148
+ return true
149
+ }
150
+ nextA , nextB := it .a .Hash (), it .b .Hash ()
151
+ if diff := bytes .Compare (nextA [:], nextB [:]); diff < 0 {
152
+ it .aDone = ! it .a .Next ()
153
+ it .k = nextA
154
+ return true
155
+ } else if diff == 0 {
156
+ // Now we need to advance one of them
157
+ it .aDone = ! it .a .Next ()
158
+ continue
159
+ }
126
160
it .bDone = ! it .b .Next ()
161
+ it .k = nextB
127
162
return true
128
163
}
129
- if it .bDone {
130
- it .k = it .a .Hash ()
131
- it .aDone = ! it .a .Next ()
132
- return true
133
- }
134
- nextA , nextB := it .a .Hash (), it .b .Hash ()
135
- if diff := bytes .Compare (nextA [:], nextB [:]); diff < 0 {
136
- it .aDone = ! it .a .Next ()
137
- it .k = nextA
138
- return true
139
- } else if diff == 0 {
140
- // Now we need to advance one of them
141
- it .aDone = ! it .a .Next ()
142
- goto first
143
- }
144
- it .bDone = ! it .b .Next ()
145
- it .k = nextB
146
- return true
147
164
}
148
165
149
166
// Error returns any failure that occurred during iteration, which might have
@@ -195,19 +212,21 @@ func (it *binaryIterator) Slot() []byte {
195
212
// Release recursively releases all the iterators in the stack.
196
213
func (it * binaryIterator ) Release () {
197
214
it .a .Release ()
198
- it .b .Release ()
215
+ if it .b != nil {
216
+ it .b .Release ()
217
+ }
199
218
}
200
219
201
220
// newBinaryAccountIterator creates a simplistic account iterator to step over
202
221
// all the accounts in a slow, but easily verifiable way.
203
- func (dl * diffLayer ) newBinaryAccountIterator () AccountIterator {
204
- iter := dl .initBinaryAccountIterator ()
222
+ func (dl * diffLayer ) newBinaryAccountIterator (seek common. Hash ) AccountIterator {
223
+ iter := dl .initBinaryAccountIterator (seek )
205
224
return iter .(AccountIterator )
206
225
}
207
226
208
227
// newBinaryStorageIterator creates a simplistic account iterator to step over
209
228
// all the storage slots in a slow, but easily verifiable way.
210
- func (dl * diffLayer ) newBinaryStorageIterator (account common.Hash ) StorageIterator {
211
- iter := dl .initBinaryStorageIterator (account )
229
+ func (dl * diffLayer ) newBinaryStorageIterator (account , seek common.Hash ) StorageIterator {
230
+ iter := dl .initBinaryStorageIterator (account , seek )
212
231
return iter .(StorageIterator )
213
232
}
0 commit comments