@@ -28,22 +28,22 @@ template rpcClient(vp: VerifiedRpcProxy): RpcClient =
28
28
29
29
proc resolveTag (
30
30
self: VerifiedRpcProxy , blockTag: BlockTag
31
- ): base.BlockNumber {. raises : [ ValueError ].} =
31
+ ): Result [ base.BlockNumber , string ] =
32
32
if blockTag.kind == bidAlias:
33
33
let tag = blockTag.alias.toLowerAscii ()
34
34
case tag
35
35
of " latest" :
36
36
let hLatest = self.headerStore.latest ()
37
37
if hLatest.isSome:
38
- return hLatest.get ().number
38
+ return ok ( hLatest.get ().number)
39
39
else :
40
- raise newException ( ValueError , " Couldn't get the latest block number from header store" )
40
+ return err ( " Couldn't get the latest block number from header store" )
41
41
else :
42
- raise newException ( ValueError , " No support for block tag " & $ blockTag)
42
+ return err ( " No support for block tag " & $ blockTag)
43
43
else :
44
- return base.BlockNumber (distinctBase (blockTag.number))
44
+ return ok ( base.BlockNumber (distinctBase (blockTag.number) ))
45
45
46
- proc convHeader (blk: BlockObject ): Header =
46
+ proc convHeader (blk: eth_api_types. BlockObject ): Header =
47
47
let
48
48
nonce = if blk.nonce.isSome: blk.nonce.get
49
49
else : default (Bytes8 )
@@ -77,16 +77,22 @@ proc walkBlocks(
77
77
sourceNum: base.BlockNumber ,
78
78
targetNum: base.BlockNumber ,
79
79
sourceHash: Hash32 ,
80
- targetHash: Hash32 ): Future [bool ] {.async : (raises: [ValueError , CatchableError ]).} =
80
+ targetHash: Hash32 ): Future [bool ] {.async : (raises: []).} =
81
81
82
82
var nextHash = sourceHash
83
83
info " starting block walk to verify" , blockHash= targetHash
84
84
85
85
# TODO : use batch calls to get all blocks at once by number
86
86
for i in 0 ..< sourceNum - targetNum:
87
87
# TODO : use a verified hash cache
88
- let blk = await self.rpcClient.eth_getBlockByHash (nextHash, false )
89
- info " getting next block" , hash= nextHash, number= blk.number, remaining= distinctBase (blk.number) - targetNum
88
+ let blk =
89
+ try :
90
+ await self.rpcClient.eth_getBlockByHash (nextHash, false )
91
+ except :
92
+ # TODO : retry before failing?
93
+ return false
94
+
95
+ trace " getting next block" , hash= nextHash, number= blk.number, remaining= distinctBase (blk.number) - targetNum
90
96
91
97
if blk.parentHash == targetHash:
92
98
return true
@@ -97,145 +103,167 @@ proc walkBlocks(
97
103
98
104
proc getBlockByHash * (
99
105
self: VerifiedRpcProxy , blockHash: Hash32 , fullTransactions: bool
100
- ): Future [BlockObject ] {.async : (raises: [ValueError , CatchableError ]).} =
106
+ ): Future [Result [eth_api_types. BlockObject , string ]] {.async : (raises: []).} =
101
107
# get the target block
102
- let blk = await self.rpcClient.eth_getBlockByHash (blockHash, fullTransactions)
108
+ let blk =
109
+ try :
110
+ await self.rpcClient.eth_getBlockByHash (blockHash, fullTransactions)
111
+ except CatchableError as e:
112
+ return err (e.msg)
113
+
103
114
let header = convHeader (blk)
104
115
105
116
# verify header hash
106
117
if header.rlpHash != blockHash:
107
- raise newException ( ValueError , " hashed block header doesn't match with blk.hash(downloaded)" )
118
+ return err ( " hashed block header doesn't match with blk.hash(downloaded)" )
108
119
109
120
if blockHash != blk.hash:
110
- raise newException ( ValueError , " the downloaded block hash doesn't match with the requested hash" )
121
+ return err ( " the downloaded block hash doesn't match with the requested hash" )
111
122
112
123
let earliestHeader = self.headerStore.earliest.valueOr:
113
- raise newException ( ValueError , " Syncing " )
124
+ return err ( " syncing " )
114
125
115
126
# walk blocks backwards(time) from source to target
116
127
let isLinked = await self.walkBlocks (earliestHeader.number, header.number, earliestHeader.parentHash, blockHash)
117
128
118
129
if not isLinked:
119
- raise newException ( ValueError , " the requested block is not part of the canonical chain" )
130
+ return err ( " the requested block is not part of the canonical chain" )
120
131
121
132
# verify transactions
122
133
if fullTransactions:
123
134
let verified = verifyTransactions (header.transactionsRoot, blk.transactions).valueOr:
124
- raise newException ( ValueError , " error while verifying transactions root" )
135
+ return err ( " error while verifying transactions root" )
125
136
if not verified:
126
- raise newException ( ValueError , " transactions within the block do not yield the same transaction root" )
137
+ return err ( " transactions within the block do not yield the same transaction root" )
127
138
128
139
# verify withdrawals
129
140
if blk.withdrawals.isSome ():
130
141
if blk.withdrawalsRoot.get () != orderedTrieRoot (blk.withdrawals.get ()):
131
- raise newException ( ValueError , " withdrawals within the block do not yield the same withdrawals root" )
142
+ return err ( " withdrawals within the block do not yield the same withdrawals root" )
132
143
133
- return blk
144
+ return ok ( blk)
134
145
135
146
proc getBlockByTag * (
136
147
self: VerifiedRpcProxy , blockTag: BlockTag , fullTransactions: bool
137
- ): Future [BlockObject ] {.async : (raises: [ValueError , CatchableError ]).} =
138
- let n = self.resolveTag (blockTag)
148
+ ): Future [Result [BlockObject , string ]] {.async : (raises: []).} =
149
+ let n = self.resolveTag (blockTag).valueOr:
150
+ return err (error)
139
151
140
152
# get the target block
141
- let blk = await self.rpcClient.eth_getBlockByNumber (blockTag, false )
153
+ let blk =
154
+ try :
155
+ await self.rpcClient.eth_getBlockByNumber (blockTag, false )
156
+ except CatchableError as e:
157
+ return err (e.msg)
158
+
142
159
let header = convHeader (blk)
143
160
144
161
# verify header hash
145
162
if header.rlpHash != blk.hash:
146
- raise newException ( ValueError , " hashed block header doesn't match with blk.hash(downloaded)" )
163
+ return err ( " hashed block header doesn't match with blk.hash(downloaded)" )
147
164
148
165
if n != header.number:
149
- raise newException ( ValueError , " the downloaded block number doesn't match with the requested block number" )
166
+ return err ( " the downloaded block number doesn't match with the requested block number" )
150
167
151
168
# get the source block
152
169
let earliestHeader = self.headerStore.earliest.valueOr:
153
- raise newException ( ValueError , " Syncing" )
170
+ return err ( " Syncing" )
154
171
155
172
# walk blocks backwards(time) from source to target
156
173
let isLinked = await self.walkBlocks (earliestHeader.number, header.number, earliestHeader.parentHash, blk.hash)
157
174
158
175
if not isLinked:
159
- raise newException ( ValueError , " the requested block is not part of the canonical chain" )
176
+ return err ( " the requested block is not part of the canonical chain" )
160
177
161
178
# verify transactions
162
179
if fullTransactions:
163
180
let verified = verifyTransactions (header.transactionsRoot, blk.transactions).valueOr:
164
- raise newException ( ValueError , " error while verifying transactions root" )
181
+ return err ( " error while verifying transactions root" )
165
182
if not verified:
166
- raise newException ( ValueError , " transactions within the block do not yield the same transaction root" )
183
+ return err ( " transactions within the block do not yield the same transaction root" )
167
184
168
185
# verify withdrawals
169
186
if blk.withdrawals.isSome ():
170
187
if blk.withdrawalsRoot.get () != orderedTrieRoot (blk.withdrawals.get ()):
171
- raise newException ( ValueError , " withdrawals within the block do not yield the same withdrawals root" )
188
+ return err ( " withdrawals within the block do not yield the same withdrawals root" )
172
189
173
- return blk
190
+ return ok ( blk)
174
191
175
192
proc getHeaderByHash * (
176
193
self: VerifiedRpcProxy , blockHash: Hash32
177
- ): Future [Header ] {.async : (raises: [ValueError , CatchableError ]).} =
194
+ ): Future [Result [ Header , string ]] {.async : (raises: []).} =
178
195
let cachedHeader = self.headerStore.get (blockHash)
179
196
180
197
if cachedHeader.isNone ():
181
198
debug " did not find the header in the cache" , blockHash= blockHash
182
199
else :
183
- return cachedHeader.get ()
200
+ return ok ( cachedHeader.get () )
184
201
185
202
# get the source block
186
203
let earliestHeader = self.headerStore.earliest.valueOr:
187
- raise newException ( ValueError , " Syncing" )
204
+ return err ( " Syncing" )
188
205
189
206
# get the target block
190
- let blk = await self.rpcClient.eth_getBlockByHash (blockHash, false )
207
+ let blk =
208
+ try :
209
+ await self.rpcClient.eth_getBlockByHash (blockHash, false )
210
+ except CatchableError as e:
211
+ return err (e.msg)
212
+
191
213
let header = convHeader (blk)
192
214
193
215
# verify header hash
194
216
if header.rlpHash != blk.hash:
195
- raise newException ( ValueError , " hashed block header doesn't match with blk.hash(downloaded)" )
217
+ return err ( " hashed block header doesn't match with blk.hash(downloaded)" )
196
218
197
219
if blockHash != blk.hash:
198
- raise newException ( ValueError , " the blk.hash(downloaded) doesn't match with the provided hash" )
220
+ return err ( " the blk.hash(downloaded) doesn't match with the provided hash" )
199
221
200
222
# walk blocks backwards(time) from source to target
201
223
let isLinked = await self.walkBlocks (earliestHeader.number, header.number, earliestHeader.parentHash, blockHash)
202
224
203
225
if not isLinked:
204
- raise newException ( ValueError , " the requested block is not part of the canonical chain" )
226
+ return err ( " the requested block is not part of the canonical chain" )
205
227
206
- return header
228
+ return ok ( header)
207
229
208
230
proc getHeaderByTag * (
209
231
self: VerifiedRpcProxy , blockTag: BlockTag
210
- ): Future [Header ] {.async : (raises: [ValueError , CatchableError ]).} =
232
+ ): Future [Result [ Header , string ]] {.async : (raises: []).} =
211
233
let
212
- n = self.resolveTag (blockTag)
234
+ n = self.resolveTag (blockTag).valueOr:
235
+ return err (error)
213
236
cachedHeader = self.headerStore.get (n)
214
237
215
238
if cachedHeader.isNone ():
216
239
debug " did not find the header in the cache" , blockTag= blockTag
217
240
else :
218
- return cachedHeader.get ()
241
+ return ok ( cachedHeader.get () )
219
242
220
243
# get the source block
221
244
let earliestHeader = self.headerStore.earliest.valueOr:
222
- raise newException ( ValueError , " Syncing" )
245
+ return err ( " Syncing" )
223
246
224
247
# get the target block
225
- let blk = await self.rpcClient.eth_getBlockByNumber (blockTag, false )
248
+ let blk =
249
+ try :
250
+ await self.rpcClient.eth_getBlockByNumber (blockTag, false )
251
+ except CatchableError as e:
252
+ return err (e.msg)
253
+
226
254
let header = convHeader (blk)
227
255
228
256
# verify header hash
229
257
if header.rlpHash != blk.hash:
230
- raise newException ( ValueError , " hashed block header doesn't match with blk.hash(downloaded)" )
258
+ return err ( " hashed block header doesn't match with blk.hash(downloaded)" )
231
259
232
260
if n != header.number:
233
- raise newException ( ValueError , " the downloaded block number doesn't match with the requested block number" )
261
+ return err ( " the downloaded block number doesn't match with the requested block number" )
234
262
235
263
# walk blocks backwards(time) from source to target
236
264
let isLinked = await self.walkBlocks (earliestHeader.number, header.number, earliestHeader.parentHash, blk.hash)
237
265
238
266
if not isLinked:
239
- raise newException ( ValueError , " the requested block is not part of the canonical chain" )
267
+ return err ( " the requested block is not part of the canonical chain" )
240
268
241
- return header
269
+ return ok ( header)
0 commit comments