@@ -89,24 +89,70 @@ proc putKeyAtLevel(
8989
9090 ok ()
9191
92- template encodeLeaf (w: var RlpWriter , pfx: NibblesBuf , leafData: untyped ): HashKey =
92+ template appendLeaf (w: var RlpWriter , pfx: NibblesBuf , leafData: untyped ) =
9393 w.startList (2 )
9494 w.append (pfx.toHexPrefix (isLeaf = true ).data ())
95+ w.wrapEncoding (1 )
9596 w.append (leafData)
96- w.finish ().digestTo (HashKey )
9797
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 ) =
99115 w.startList (17 )
100116 for (n {.inject .}, subvid {.inject .}) in vtx.allPairs ():
101117 w.append (subKeyForN)
102118 w.append EmptyBlob
103- w.finish ().digestTo (HashKey )
104119
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 ) =
106137 w.startList (2 )
107138 w.append (pfx.toHexPrefix (isLeaf = false ).data ())
108139 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 )
110156
111157proc getKey (
112158 db: AristoTxRef , rvid: RootedVertexID , skipLayers: static bool
@@ -146,14 +192,11 @@ proc computeKeyImpl(
146192 # Top-most level of all the verticies this hash computation depends on
147193 var level = level
148194
149- # TODO this is the same code as when serializing NodeRef, without the NodeRef
150- var writer = initRlpWriter ()
151-
152195 let key =
153196 case vtx.vType
154197 of AccLeaf :
155198 let vtx = AccLeafRef (vtx)
156- writer. encodeLeaf (vtx.pfx):
199+ encodeLeaf (vtx.pfx):
157200 let
158201 stoID = vtx.stoID
159202 skey =
@@ -176,17 +219,16 @@ proc computeKeyImpl(
176219 else :
177220 VOID_HASH_KEY
178221
179- rlp. encode Account (
222+ Account (
180223 nonce: vtx.account.nonce,
181224 balance: vtx.account.balance,
182225 storageRoot: skey.to (Hash32 ),
183226 codeHash: vtx.account.codeHash,
184227 )
185228 of StoLeaf :
186229 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
190232 of Branches :
191233 # For branches, we need to load the vertices before recursing into them
192234 # to exploit their on-disk order
@@ -245,21 +287,19 @@ proc computeKeyImpl(
245287 )
246288 batch.leave (n)
247289
248- template writeBranch (w: var RlpWriter , vtx: BranchRef ): HashKey =
249- w. encodeBranch (vtx):
290+ template writeBranch (): HashKey =
291+ encodeBranch (vtx):
250292 if subvid.isValid:
251293 level = max (level, keyvtxs[n][1 ])
252294 keyvtxs[n][0 ][0 ]
253295 else :
254296 VOID_HASH_KEY
255297
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 ()
261301 else :
262- writer. writeBranch (vtx )
302+ writeBranch ()
263303
264304 # Cache the hash into the same storage layer as the the top-most value that it
265305 # depends on (recursively) - this could be an ephemeral in-memory layer or the
@@ -268,9 +308,9 @@ proc computeKeyImpl(
268308 # root key also changing while leaves that have never been hashed will see
269309 # their hash being saved directly to the backend.
270310
271- if vtx.vType in Branches :
272- ? db.putKeyAtLevel (rvid, BranchRef ( vtx) , key, level, batch)
273- ok (key, level)
311+ if vtx.vType notin Leaves :
312+ ? db.putKeyAtLevel (rvid, vtx, key, level, batch)
313+ return ok (key, level)
274314
275315proc computeKeyImpl (
276316 db: AristoTxRef , rvid: RootedVertexID , skipLayers: static bool
0 commit comments