15
15
{.push raises: [].}
16
16
17
17
import
18
+ std/ [tables, sets, sequtils],
18
19
eth/ common/ hashes,
19
20
results,
20
21
./ [aristo_desc, aristo_fetch, aristo_get, aristo_serialise, aristo_utils]
21
22
22
- # ------------------------------------------------------------------------------
23
- # Public functions
24
- # ------------------------------------------------------------------------------
25
-
26
-
27
23
const
28
24
ChainRlpNodesNoEntry* = {
29
25
PartChnLeafPathMismatch, PartChnExtPfxMismatch, PartChnBranchVoidEdge}
@@ -133,38 +129,37 @@ proc trackRlpNodes(
133
129
return err(PartTrkLinkExpected)
134
130
chain.toOpenArray(1 ,chain.len- 1 ).trackRlpNodes(nextKey, path.slice nChewOff)
135
131
136
- # ------------------------------------------------------------------------------
137
- # Public functions
138
- # ------------------------------------------------------------------------------
139
-
140
132
proc makeProof(
141
133
db: AristoTxRef;
142
134
root: VertexID;
143
135
path: NibblesBuf;
144
136
nodesCache: var NodesCache;
145
- ): Result[(seq [seq [byte ]], bool ), AristoError] =
137
+ chain: var seq [seq [byte ]];
138
+ ): Result[bool , AristoError] =
146
139
# # This function returns a chain of rlp-encoded nodes along the argument
147
140
# # path `(root,path)` followed by a `true` value if the `path` argument
148
141
# # exists in the database. If the argument `path` is not on the database,
149
142
# # a partial path will be returned follwed by a `false` value.
150
143
# #
151
144
# # Errors will only be returned for invalid paths.
152
145
# #
153
- var chain: seq [seq [byte ]]
154
146
let rc = db.chainRlpNodes((root,root), path, chain, nodesCache)
155
147
if rc.isOk:
156
- ok((chain, true ) )
148
+ ok(true )
157
149
elif rc.error in ChainRlpNodesNoEntry:
158
- ok((chain, false ) )
150
+ ok(false )
159
151
else :
160
152
err(rc.error)
161
153
162
154
proc makeAccountProof* (
163
155
db: AristoTxRef;
164
156
accPath: Hash32;
165
157
): Result[(seq [seq [byte ]], bool ), AristoError] =
166
- var nodesCache: NodesCache
167
- db.makeProof(STATE_ROOT_VID, NibblesBuf.fromBytes accPath.data, nodesCache)
158
+ var
159
+ nodesCache: NodesCache
160
+ proof: seq [seq [byte ]]
161
+ let exists = ? db.makeProof(STATE_ROOT_VID, NibblesBuf.fromBytes accPath.data, nodesCache, proof)
162
+ ok((proof, exists))
168
163
169
164
proc makeStorageProof* (
170
165
db: AristoTxRef;
@@ -177,8 +172,11 @@ proc makeStorageProof*(
177
172
if error == FetchPathStoRootMissing:
178
173
return ok((@ [],false ))
179
174
return err(error)
180
- var nodesCache: NodesCache
181
- db.makeProof(vid, NibblesBuf.fromBytes stoPath.data, nodesCache)
175
+ var
176
+ nodesCache: NodesCache
177
+ proof: seq [seq [byte ]]
178
+ let exists = ? db.makeProof(vid, NibblesBuf.fromBytes stoPath.data, nodesCache, proof)
179
+ ok((proof, exists))
182
180
183
181
proc makeStorageProofs* (
184
182
db: AristoTxRef;
@@ -196,14 +194,56 @@ proc makeStorageProofs*(
196
194
var
197
195
nodesCache: NodesCache
198
196
proofs = newSeqOfCap[seq [seq [byte ]]](stoPaths.len())
199
-
200
197
for stoPath in stoPaths:
201
- let (proof, _) = ? db.makeProof(vid, NibblesBuf.fromBytes stoPath.data, nodesCache)
198
+ var proof: seq [seq [byte ]]
199
+ discard ? db.makeProof(vid, NibblesBuf.fromBytes stoPath.data, nodesCache, proof)
202
200
proofs.add(proof)
203
201
204
202
ok(proofs)
205
203
206
- # ----------
204
+ proc makeStorageMultiProof(
205
+ db: AristoTxRef;
206
+ accPath: Hash32;
207
+ stoPaths: openArray [Hash32];
208
+ nodesCache: var NodesCache;
209
+ multiProof: var HashSet[seq [byte ]]
210
+ ): Result[void , AristoError] =
211
+ # # Note that the function returns an error unless
212
+ # # the argument `accPath` is valid.
213
+ let vid = db.fetchStorageID(accPath).valueOr:
214
+ if error == FetchPathStoRootMissing:
215
+ return ok()
216
+ return err(error)
217
+
218
+ for stoPath in stoPaths:
219
+ var proof: seq [seq [byte ]]
220
+ discard ? db.makeProof(vid, NibblesBuf.fromBytes stoPath.data, nodesCache, proof)
221
+ for node in proof:
222
+ multiProof.incl(node)
223
+
224
+ ok()
225
+
226
+ proc makeMultiProof* (
227
+ db: AristoTxRef;
228
+ paths: Table[Hash32, seq [Hash32]], # maps each account path to a list of storage paths
229
+ multiProof: var seq [seq [byte ]]
230
+ ): Result[void , AristoError] =
231
+ var
232
+ nodesCache: NodesCache
233
+ proofNodes: HashSet[seq [byte ]]
234
+
235
+ for accPath, stoPaths in paths:
236
+ var accProof: seq [seq [byte ]]
237
+ let exists = ? db.makeProof(STATE_ROOT_VID, NibblesBuf.fromBytes accPath.data, nodesCache, accProof)
238
+ for node in accProof:
239
+ proofNodes.incl(node)
240
+
241
+ if exists:
242
+ ? db.makeStorageMultiProof(accPath, stoPaths, nodesCache, proofNodes)
243
+
244
+ multiProof = proofNodes.toSeq()
245
+
246
+ ok()
207
247
208
248
proc verifyProof* (
209
249
chain: openArray [seq [byte ]];
@@ -222,7 +262,3 @@ proc verifyProof*(
222
262
return err(rc.error)
223
263
except RlpError:
224
264
return err(PartTrkRlpError)
225
-
226
- # ------------------------------------------------------------------------------
227
- # End
228
- # ------------------------------------------------------------------------------
0 commit comments