@@ -200,16 +200,10 @@ func (s *Server) GetBlockAttestations(w http.ResponseWriter, r *http.Request) {
200
200
ctx , span := trace .StartSpan (r .Context (), "beacon.GetBlockAttestations" )
201
201
defer span .End ()
202
202
203
- blockId := r .PathValue ("block_id" )
204
- if blockId == "" {
205
- httputil .HandleError (w , "block_id is required in URL params" , http .StatusBadRequest )
206
- return
207
- }
208
- blk , err := s .Blocker .Block (ctx , []byte (blockId ))
209
- if ! shared .WriteBlockFetchError (w , blk , err ) {
203
+ blk , isOptimistic , root := s .blockData (ctx , w , r )
204
+ if blk == nil {
210
205
return
211
206
}
212
-
213
207
consensusAtts := blk .Block ().Body ().Attestations ()
214
208
atts := make ([]* structs.Attestation , len (consensusAtts ))
215
209
for i , att := range consensusAtts {
@@ -221,25 +215,87 @@ func (s *Server) GetBlockAttestations(w http.ResponseWriter, r *http.Request) {
221
215
return
222
216
}
223
217
}
224
- root , err := blk .Block ().HashTreeRoot ()
225
- if err != nil {
226
- httputil .HandleError (w , "Could not get block root: " + err .Error (), http .StatusInternalServerError )
218
+ resp := & structs.GetBlockAttestationsResponse {
219
+ Data : atts ,
220
+ ExecutionOptimistic : isOptimistic ,
221
+ Finalized : s .FinalizationFetcher .IsFinalized (ctx , root ),
222
+ }
223
+ httputil .WriteJson (w , resp )
224
+ }
225
+
226
+ // GetBlockAttestationsV2 retrieves attestation included in requested block.
227
+ func (s * Server ) GetBlockAttestationsV2 (w http.ResponseWriter , r * http.Request ) {
228
+ ctx , span := trace .StartSpan (r .Context (), "beacon.GetBlockAttestationsV2" )
229
+ defer span .End ()
230
+
231
+ blk , isOptimistic , root := s .blockData (ctx , w , r )
232
+ if blk == nil {
227
233
return
228
234
}
229
- isOptimistic , err := s .OptimisticModeFetcher .IsOptimisticForRoot (ctx , root )
235
+ consensusAtts := blk .Block ().Body ().Attestations ()
236
+
237
+ v := blk .Block ().Version ()
238
+ var attStructs []interface {}
239
+ if v >= version .Electra {
240
+ for _ , att := range consensusAtts {
241
+ a , ok := att .(* eth.AttestationElectra )
242
+ if ! ok {
243
+ httputil .HandleError (w , fmt .Sprintf ("unable to convert consensus attestations electra of type %T" , att ), http .StatusInternalServerError )
244
+ return
245
+ }
246
+ attStruct := structs .AttElectraFromConsensus (a )
247
+ attStructs = append (attStructs , attStruct )
248
+ }
249
+ } else {
250
+ for _ , att := range consensusAtts {
251
+ a , ok := att .(* eth.Attestation )
252
+ if ! ok {
253
+ httputil .HandleError (w , fmt .Sprintf ("unable to convert consensus attestation of type %T" , att ), http .StatusInternalServerError )
254
+ return
255
+ }
256
+ attStruct := structs .AttFromConsensus (a )
257
+ attStructs = append (attStructs , attStruct )
258
+ }
259
+ }
260
+
261
+ attBytes , err := json .Marshal (attStructs )
230
262
if err != nil {
231
- httputil .HandleError (w , "Could not check if block is optimistic: " + err . Error ( ), http .StatusInternalServerError )
263
+ httputil .HandleError (w , fmt . Sprintf ( "failed to marshal attestations: %v" , err ), http .StatusInternalServerError )
232
264
return
233
265
}
234
-
235
- resp := & structs.GetBlockAttestationsResponse {
236
- Data : atts ,
266
+ resp := & structs.GetBlockAttestationsV2Response {
267
+ Version : version .String (v ),
237
268
ExecutionOptimistic : isOptimistic ,
238
269
Finalized : s .FinalizationFetcher .IsFinalized (ctx , root ),
270
+ Data : attBytes ,
239
271
}
240
272
httputil .WriteJson (w , resp )
241
273
}
242
274
275
+ func (s * Server ) blockData (ctx context.Context , w http.ResponseWriter , r * http.Request ) (interfaces.ReadOnlySignedBeaconBlock , bool , [32 ]byte ) {
276
+ blockId := r .PathValue ("block_id" )
277
+ if blockId == "" {
278
+ httputil .HandleError (w , "block_id is required in URL params" , http .StatusBadRequest )
279
+ return nil , false , [32 ]byte {}
280
+ }
281
+ blk , err := s .Blocker .Block (ctx , []byte (blockId ))
282
+ if ! shared .WriteBlockFetchError (w , blk , err ) {
283
+ return nil , false , [32 ]byte {}
284
+ }
285
+
286
+ root , err := blk .Block ().HashTreeRoot ()
287
+ if err != nil {
288
+ httputil .HandleError (w , "Could not get block root: " + err .Error (), http .StatusInternalServerError )
289
+ return nil , false , [32 ]byte {}
290
+ }
291
+ isOptimistic , err := s .OptimisticModeFetcher .IsOptimisticForRoot (ctx , root )
292
+ if err != nil {
293
+ httputil .HandleError (w , "Could not check if block is optimistic: " + err .Error (), http .StatusInternalServerError )
294
+ return nil , false , [32 ]byte {}
295
+ }
296
+ return blk , isOptimistic , root
297
+ }
298
+
243
299
// PublishBlindedBlock instructs the beacon node to use the components of the `SignedBlindedBeaconBlock` to construct
244
300
// and publish a SignedBeaconBlock by swapping out the transactions_root for the corresponding full list of `transactions`.
245
301
// The beacon node should broadcast a newly constructed SignedBeaconBlock to the beacon network, to be included in the
0 commit comments