@@ -29,15 +29,29 @@ logScope:
29
29
30
30
const pingExtensionCapabilities = {CapabilitiesType , HistoryRadiusType }
31
31
32
- type FinalizedHistoryNetwork * = ref object
33
- portalProtocol* : PortalProtocol
34
- contentDB* : ContentDB
35
- contentQueue* : AsyncQueue [(Opt [NodeId ], ContentKeysList , seq [seq [byte ]])]
36
- # cfg*: RuntimeConfig
37
- processContentLoops: seq [Future [void ]]
38
- statusLogLoop: Future [void ]
39
- contentRequestRetries: int
40
- contentQueueWorkers: int
32
+ type
33
+ GetHeaderCallback * = proc (blockNumber: uint64 ): Future [Result [Header , string ]] {.
34
+ async : (raises: [CancelledError ]), gcsafe
35
+ .}
36
+
37
+ FinalizedHistoryNetwork * = ref object
38
+ portalProtocol* : PortalProtocol
39
+ contentDB* : ContentDB
40
+ contentQueue* : AsyncQueue [(Opt [NodeId ], ContentKeysList , seq [seq [byte ]])]
41
+ getHeader* : GetHeaderCallback
42
+ # cfg*: RuntimeConfig
43
+ processContentLoops: seq [Future [void ]]
44
+ statusLogLoop: Future [void ]
45
+ contentRequestRetries: int
46
+ contentQueueWorkers: int
47
+
48
+ proc defaultNoGetHeader (
49
+ blockNumber: uint64
50
+ ): Future [Result [Header , string ]] {.async : (raises: [CancelledError ]), gcsafe .} =
51
+ err (
52
+ " No getHeader callback set for PortalNode, cannot verify offered content for block: " &
53
+ $ blockNumber
54
+ )
41
55
42
56
func toContentIdHandler (contentKey: ContentKeyByteList ): results.Opt [ContentId ] =
43
57
toContentId (contentKey)
@@ -48,6 +62,7 @@ proc new*(
48
62
baseProtocol: protocol.Protocol ,
49
63
contentDB: ContentDB ,
50
64
streamManager: StreamManager ,
65
+ getHeaderCallback: GetHeaderCallback = defaultNoGetHeader,
51
66
# cfg: RuntimeConfig,
52
67
bootstrapRecords: openArray [Record ] = [],
53
68
portalConfig: PortalProtocolConfig = defaultPortalProtocolConfig,
@@ -79,6 +94,7 @@ proc new*(
79
94
portalProtocol: portalProtocol,
80
95
contentDB: contentDB,
81
96
contentQueue: contentQueue,
97
+ getHeader: getHeaderCallback,
82
98
# cfg: cfg,
83
99
contentRequestRetries: contentRequestRetries,
84
100
contentQueueWorkers: contentQueueWorkers,
@@ -90,6 +106,12 @@ proc getContent*(
90
106
V: type ContentValueType ,
91
107
header: Header ,
92
108
): Future [Opt [V]] {.async : (raises: [CancelledError ]).} =
109
+ # # Get the decoded content for the given content key.
110
+ # #
111
+ # # When the content is found locally, no validation is performed.
112
+ # # Else, the content is fetched from the network and validated with the provided header.
113
+ # # If content validation fails, the node is banned for a certain period of time and
114
+ # # content request is retried `contentRequestRetries` times.
93
115
let contentKeyBytes = encode (contentKey)
94
116
95
117
logScope:
@@ -146,29 +168,21 @@ proc validateContent(
146
168
let contentKey = finalized_history_content.decode (contentKeyBytes).valueOr:
147
169
return err (" Error decoding content key" )
148
170
171
+ let header = ? (await n.getHeader (contentKey.blockNumber ()))
172
+
149
173
case contentKey.contentType
150
174
of unused:
151
175
raiseAssert (" ContentKey contentType: unused" )
152
176
of blockBody:
153
- let
154
- # TODO : Need to get the header (or just tx root/uncle root/withdrawals root) from the EL client via
155
- # JSON-RPC.
156
- # OR if directly integrated the EL client, we can just pass the header here.
157
- header = Header ()
158
- blockBody = decodeRlp (content, BlockBody ).valueOr:
159
- return err (" Error decoding block body: " & error)
177
+ let blockBody = decodeRlp (content, BlockBody ).valueOr:
178
+ return err (" Error decoding block body: " & error)
160
179
validateBlockBody (blockBody, header).isOkOr:
161
180
return err (" Failed validating block body: " & error)
162
181
163
182
ok ()
164
183
of receipts:
165
- let
166
- # TODO : Need to get the header (or just tx root/uncle root/withdrawals root) from the EL client via
167
- # JSON-RPC.
168
- # OR if directly integrated the EL client, we can just pass the header here.
169
- header = Header ()
170
- receipts = decodeRlp (content, seq [Receipt ]).valueOr:
171
- return err (" Error decoding receipts: " & error)
184
+ let receipts = decodeRlp (content, seq [Receipt ]).valueOr:
185
+ return err (" Error decoding receipts: " & error)
172
186
validateReceipts (receipts, header).isOkOr:
173
187
return err (" Failed validating receipts: " & error)
174
188
0 commit comments