@@ -2,9 +2,11 @@ import { Block, BlockHeader } from '@ethereumjs/block'
2
2
import { bytesToHex , bytesToInt , equalsBytes , hexToBytes } from '@ethereumjs/util'
3
3
import debug from 'debug'
4
4
5
+ import type { BaseNetworkConfig , ContentLookupResponse , FindContentMessage } from '../../index.js'
5
6
import {
6
7
ContentMessageType ,
7
8
FoundContent ,
9
+ HistoricalSummariesBlockProof ,
8
10
MessageCodes ,
9
11
PingPongPayloadExtensions ,
10
12
PortalWireMessageType ,
@@ -19,19 +21,26 @@ import { BaseNetwork } from '../network.js'
19
21
import { NetworkId } from '../types.js'
20
22
21
23
import {
24
+ AccumulatorProofType ,
22
25
BlockHeaderWithProof ,
23
26
BlockNumberKey ,
27
+ HistoricalRootsBlockProof ,
24
28
HistoryNetworkContentType ,
25
29
MERGE_BLOCK ,
26
30
SHANGHAI_BLOCK ,
27
31
sszReceiptsListType ,
28
32
} from './types.js'
29
- import { getContentKey , verifyPostCapellaHeaderProof , verifyPreCapellaHeaderProof , verifyPreMergeHeaderProof } from './util.js'
33
+ import {
34
+ getContentKey ,
35
+ verifyPostCapellaHeaderProof ,
36
+ verifyPreCapellaHeaderProof ,
37
+ verifyPreMergeHeaderProof ,
38
+ } from './util.js'
30
39
31
40
import type { ENR } from '@chainsafe/enr'
32
- import type { Debugger } from 'debug'
33
- import type { BaseNetworkConfig , ContentLookupResponse , FindContentMessage } from '../../index.js'
41
+
34
42
import { RunStatusCode } from '@lodestar/light-client'
43
+ import type { Debugger } from 'debug'
35
44
36
45
export class HistoryNetwork extends BaseNetwork {
37
46
networkId : NetworkId . HistoryNetwork
@@ -95,7 +104,7 @@ export class HistoryNetwork extends BaseNetwork {
95
104
/**
96
105
* Retrieve a blockheader from the DB by hash
97
106
* @param blockHash the hash of the blockheader sought
98
- * @param asBytes return the header as RLP encoded bytes or as an @ethereumjs/block BlockHeader
107
+ * @param asBytes return the header as RLP encoded bytes or as an ` @ethereumjs/block` BlockHeader
99
108
* @returns the bytes or Blockheader if found or else undefined
100
109
*/
101
110
public getBlockHeaderFromDB = async (
@@ -109,6 +118,7 @@ export class HistoryNetwork extends BaseNetwork {
109
118
const value = await this . findContentLocally ( contentKey )
110
119
if ( value === undefined ) return undefined
111
120
const header = BlockHeaderWithProof . deserialize ( value ) . header
121
+
112
122
return asBytes === true
113
123
? header
114
124
: BlockHeader . fromRLPSerializedHeader ( header , { setHardfork : true } )
@@ -162,57 +172,76 @@ export class HistoryNetwork extends BaseNetwork {
162
172
const proof = headerProof . proof
163
173
164
174
if ( header . number < MERGE_BLOCK ) {
165
- if ( proof . value === null ) {
166
- throw new Error ( 'Received pre-merge block header without proof' )
175
+ let deserializedProof : Uint8Array [ ]
176
+ try {
177
+ deserializedProof = AccumulatorProofType . deserialize ( proof )
178
+ } catch ( err : any ) {
179
+ this . logger ( `invalid proof for block ${ bytesToHex ( header . hash ( ) ) } ` )
180
+ throw new Error ( `invalid proof for block ${ bytesToHex ( header . hash ( ) ) } ` )
167
181
}
168
- if ( Array . isArray ( proof . value ) ) {
169
- let validated = false
170
- if ( 'blockHash' in validation ) {
171
- validated = verifyPreMergeHeaderProof ( proof . value , validation . blockHash , header . number )
172
- } else {
173
- validated = verifyPreMergeHeaderProof (
174
- proof . value ,
175
- bytesToHex ( header . hash ( ) ) ,
176
- validation . blockNumber ,
177
- )
178
- }
179
- if ( ! validated ) {
180
- throw new Error ( 'Unable to validate proof for pre-merge header' )
181
- }
182
+ let validated = false
183
+ if ( 'blockHash' in validation ) {
184
+ validated = verifyPreMergeHeaderProof (
185
+ deserializedProof ,
186
+ validation . blockHash ,
187
+ header . number ,
188
+ )
189
+ } else {
190
+ validated = verifyPreMergeHeaderProof (
191
+ deserializedProof ,
192
+ bytesToHex ( header . hash ( ) ) ,
193
+ validation . blockNumber ,
194
+ )
195
+ }
196
+ if ( ! validated ) {
197
+ throw new Error ( 'Unable to validate proof for pre-merge header' )
182
198
}
183
199
} else if ( header . number < SHANGHAI_BLOCK ) {
184
- if ( proof . value === null ) {
185
- this . logger ( 'Received post-merge block without proof' )
186
- throw new Error ( 'Received post-merge block header without proof' )
200
+ let deserializedProof : ReturnType < typeof HistoricalRootsBlockProof . deserialize >
201
+ try {
202
+ deserializedProof = HistoricalRootsBlockProof . deserialize ( proof )
203
+ } catch ( err : any ) {
204
+ this . logger ( `invalid proof for block ${ bytesToHex ( header . hash ( ) ) } ` )
205
+ throw new Error ( `invalid proof for block ${ bytesToHex ( header . hash ( ) ) } ` )
187
206
}
188
207
let validated = false
189
208
try {
190
- validated = verifyPreCapellaHeaderProof ( proof . value as any , header . hash ( ) )
209
+ validated = verifyPreCapellaHeaderProof ( deserializedProof , header . hash ( ) )
191
210
} catch ( err : any ) {
192
211
this . logger ( `Unable to validate proof for post-merge header: ${ err . message } ` )
193
212
}
194
213
if ( ! validated ) {
195
214
throw new Error ( 'Unable to validate proof for post-merge header' )
196
215
}
197
- }
198
- else {
216
+ } else {
199
217
// TODO: Check proof slot to ensure header is from previous sync period and handle ephemeral headers separately
200
- if ( proof . value === null ) {
201
- this . logger ( 'Received post-merge block without proof' )
218
+
219
+ let deserializedProof : ReturnType < typeof HistoricalSummariesBlockProof . deserialize >
220
+ try {
221
+ deserializedProof = HistoricalSummariesBlockProof . deserialize ( proof )
222
+ } catch ( err : any ) {
223
+ this . logger ( `invalid proof for block ${ bytesToHex ( header . hash ( ) ) } ` )
224
+ throw new Error ( `invalid proof for block ${ bytesToHex ( header . hash ( ) ) } ` )
202
225
}
203
226
const beacon = this . portal . network ( ) [ '0x500c' ]
204
227
if ( beacon !== undefined && beacon . lightClient ?. status === RunStatusCode . started ) {
205
228
try {
206
- verifyPostCapellaHeaderProof ( proof . value as any , header . hash ( ) , beacon . historicalSummaries , beacon . beaconConfig )
229
+ verifyPostCapellaHeaderProof (
230
+ deserializedProof ,
231
+ header . hash ( ) ,
232
+ beacon . historicalSummaries ,
233
+ beacon . beaconConfig ,
234
+ )
207
235
this . logger ( `Successfully verified proof for block header ${ header . number } ` )
208
236
} catch {
209
237
this . logger ( 'Received post-capella block header with invalid proof' )
210
238
// TODO: throw new Error('Received post-merge block header with invalid proof')
211
239
}
212
240
} else {
213
- this . logger ( 'Received post-capella block but Beacon light client is not running so cannot verify proof' )
241
+ this . logger (
242
+ 'Received post-capella block but Beacon light client is not running so cannot verify proof' ,
243
+ )
214
244
}
215
-
216
245
}
217
246
await this . indexBlockHash ( header . number , bytesToHex ( header . hash ( ) ) )
218
247
return header . hash ( )
@@ -348,7 +377,8 @@ export class HistoryNetwork extends BaseNetwork {
348
377
this . gossipManager . add ( contentKey )
349
378
}
350
379
this . logger (
351
- `${ HistoryNetworkContentType [ contentType ] } added for ${ keyOpt instanceof Uint8Array ? bytesToHex ( keyOpt ) : keyOpt
380
+ `${ HistoryNetworkContentType [ contentType ] } added for ${
381
+ keyOpt instanceof Uint8Array ? bytesToHex ( keyOpt ) : keyOpt
352
382
} `,
353
383
)
354
384
}
0 commit comments