@@ -89,24 +89,70 @@ proc putKeyAtLevel(
89
89
90
90
ok ()
91
91
92
- template encodeLeaf (w: var RlpWriter , pfx: NibblesBuf , leafData: untyped ): HashKey =
92
+ template appendLeaf (w: var RlpWriter , pfx: NibblesBuf , leafData: untyped ) =
93
93
w.startList (2 )
94
94
w.append (pfx.toHexPrefix (isLeaf = true ).data ())
95
+ w.wrapEncoding (1 )
95
96
w.append (leafData)
96
- w.finish ().digestTo (HashKey )
97
97
98
- template encodeBranch (w: var RlpWriter , vtx: VertexRef , subKeyForN: untyped ): HashKey =
98
+ template encodeLeaf (pfx: NibblesBuf , leafData: untyped ): HashKey =
99
+ var tracker = DynamicRlpLengthTracker ()
100
+ tracker.initLengthTracker ()
101
+ tracker.appendLeaf (pfx, leafData)
102
+
103
+ if tracker.totalLength < 32 :
104
+ var writer = initTwoPassWriter (tracker)
105
+ writer.appendLeaf (pfx, leafData)
106
+ let buf = HashKey .fromBytes (writer.finish)
107
+ buf.value
108
+ else :
109
+ var writer = initHashWriter (tracker)
110
+ writer.appendLeaf (pfx, leafData)
111
+ let buf = writer.finish ()
112
+ buf.to (HashKey )
113
+
114
+ template appendBranch (w: var RlpWriter , vtx: VertexRef , subKeyForN: untyped ) =
99
115
w.startList (17 )
100
116
for (n {.inject .}, subvid {.inject .}) in vtx.allPairs ():
101
117
w.append (subKeyForN)
102
118
w.append EmptyBlob
103
- w.finish ().digestTo (HashKey )
104
119
105
- template encodeExt (w: var RlpWriter , pfx: NibblesBuf , branchKey: HashKey ): HashKey =
120
+ template encodeBranch (vtx: VertexRef , subKeyForN: untyped ): HashKey =
121
+ var tracker: DynamicRlpLengthTracker
122
+ tracker.initLengthTracker ()
123
+ tracker.appendBranch (vtx, subKeyForN)
124
+
125
+ if tracker.totalLength < 32 :
126
+ var writer = initTwoPassWriter (tracker)
127
+ writer.appendBranch (vtx, subKeyForN)
128
+ let buf = HashKey .fromBytes (writer.finish)
129
+ buf.value
130
+ else :
131
+ var writer = initHashWriter (tracker)
132
+ writer.appendBranch (vtx, subKeyForN)
133
+ let buf = writer.finish ()
134
+ buf.to (HashKey )
135
+
136
+ template appendExt (w: var RlpWriter , pfx: NibblesBuf , branchKey: HashKey ) =
106
137
w.startList (2 )
107
138
w.append (pfx.toHexPrefix (isLeaf = false ).data ())
108
139
w.append (branchKey)
109
- w.finish ().digestTo (HashKey )
140
+
141
+ template encodeExt (pfx: NibblesBuf , branchKey: untyped ): HashKey =
142
+ var tracker: DynamicRlpLengthTracker
143
+ tracker.initLengthTracker ()
144
+ tracker.appendExt (pfx, branchKey)
145
+
146
+ if tracker.totalLength < 32 :
147
+ var writer = initTwoPassWriter (tracker)
148
+ writer.appendExt (pfx, branchKey)
149
+ let buf = HashKey .fromBytes (writer.finish)
150
+ buf.value
151
+ else :
152
+ var writer = initHashWriter (tracker)
153
+ writer.appendExt (pfx, branchKey)
154
+ let buf = writer.finish ()
155
+ buf.to (HashKey )
110
156
111
157
proc getKey (
112
158
db: AristoTxRef , rvid: RootedVertexID , skipLayers: static bool
@@ -146,14 +192,11 @@ proc computeKeyImpl(
146
192
# Top-most level of all the verticies this hash computation depends on
147
193
var level = level
148
194
149
- # TODO this is the same code as when serializing NodeRef, without the NodeRef
150
- var writer = initRlpWriter ()
151
-
152
195
let key =
153
196
case vtx.vType
154
197
of AccLeaf :
155
198
let vtx = AccLeafRef (vtx)
156
- writer. encodeLeaf (vtx.pfx):
199
+ encodeLeaf (vtx.pfx):
157
200
let
158
201
stoID = vtx.stoID
159
202
skey =
@@ -176,17 +219,16 @@ proc computeKeyImpl(
176
219
else :
177
220
VOID_HASH_KEY
178
221
179
- rlp. encode Account (
222
+ Account (
180
223
nonce: vtx.account.nonce,
181
224
balance: vtx.account.balance,
182
225
storageRoot: skey.to (Hash32 ),
183
226
codeHash: vtx.account.codeHash,
184
227
)
185
228
of StoLeaf :
186
229
let vtx = StoLeafRef (vtx)
187
- writer.encodeLeaf (vtx.pfx):
188
- # TODO avoid memory allocation when encoding storage data
189
- rlp.encode (vtx.stoData)
230
+ encodeLeaf (vtx.pfx):
231
+ vtx.stoData
190
232
of Branches :
191
233
# For branches, we need to load the vertices before recursing into them
192
234
# to exploit their on-disk order
@@ -245,21 +287,19 @@ proc computeKeyImpl(
245
287
)
246
288
batch.leave (n)
247
289
248
- template writeBranch (w: var RlpWriter , vtx: BranchRef ): HashKey =
249
- w. encodeBranch (vtx):
290
+ template writeBranch (): HashKey =
291
+ encodeBranch (vtx):
250
292
if subvid.isValid:
251
293
level = max (level, keyvtxs[n][1 ])
252
294
keyvtxs[n][0 ][0 ]
253
295
else :
254
296
VOID_HASH_KEY
255
297
256
- if vtx.vType == ExtBranch :
257
- let vtx = ExtBranchRef (vtx)
258
- writer.encodeExt (vtx.pfx):
259
- var bwriter = initRlpWriter ()
260
- bwriter.writeBranch (vtx)
298
+ if vtx.pfx.len > 0 : # Extension node
299
+ encodeExt (vtx.pfx):
300
+ writeBranch ()
261
301
else :
262
- writer. writeBranch (vtx )
302
+ writeBranch ()
263
303
264
304
# Cache the hash into the same storage layer as the the top-most value that it
265
305
# depends on (recursively) - this could be an ephemeral in-memory layer or the
@@ -270,7 +310,7 @@ proc computeKeyImpl(
270
310
271
311
if vtx.vType notin Leaves :
272
312
? db.putKeyAtLevel (rvid, vtx, key, level, batch)
273
- ok (key, level)
313
+ return ok (key, level)
274
314
275
315
proc computeKeyImpl (
276
316
db: AristoTxRef , rvid: RootedVertexID , skipLayers: static bool
0 commit comments