@@ -90,6 +90,8 @@ func process(ctx context.Context, data *dataIn) (*dataOut, error) {
9090 err = processDenebBlock (ctx , data , block )
9191 case spec .DataVersionElectra :
9292 err = processElectraBlock (ctx , data , block )
93+ case spec .DataVersionFulu :
94+ err = processFuluBlock (ctx , data , block )
9395 default :
9496 return nil , errors .New ("unknown block version" )
9597 }
@@ -215,6 +217,35 @@ func processElectraBlock(ctx context.Context,
215217 return nil
216218}
217219
220+ func processFuluBlock (ctx context.Context ,
221+ data * dataIn ,
222+ block * spec.VersionedSignedBeaconBlock ,
223+ ) error {
224+ var blobSidecars []* deneb.BlobSidecar
225+ kzgCommitments , err := block .BlobKZGCommitments ()
226+ if err != nil {
227+ return err
228+ }
229+ if len (kzgCommitments ) > 0 {
230+ blobSidecarsResponse , err := results .eth2Client .(eth2client.BlobSidecarsProvider ).BlobSidecars (ctx , & api.BlobSidecarsOpts {
231+ Block : data .blockID ,
232+ })
233+ if err != nil {
234+ var apiErr * api.Error
235+ if errors .As (err , & apiErr ) && apiErr .StatusCode != http .StatusNotFound {
236+ return errors .Wrap (err , "failed to obtain blob sidecars" )
237+ }
238+ } else {
239+ blobSidecars = blobSidecarsResponse .Data
240+ }
241+ }
242+ if err := outputFuluBlock (ctx , data .jsonOutput , data .sszOutput , block .Fulu , blobSidecars ); err != nil {
243+ return errors .Wrap (err , "failed to output block" )
244+ }
245+
246+ return nil
247+ }
248+
218249func headEventHandler (ctx context.Context , headEvent * apiv1.HeadEvent ) {
219250 blockID := fmt .Sprintf ("%#x" , headEvent .Block [:])
220251 blockResponse , err := results .eth2Client .(eth2client.SignedBeaconBlockProvider ).SignedBeaconBlock (ctx , & api.SignedBeaconBlockOpts {
@@ -263,6 +294,46 @@ func headEventHandler(ctx context.Context, headEvent *apiv1.HeadEvent) {
263294 blobSidecars = blobSidecarsResponse .Data
264295 }
265296 err = outputDenebBlock (context .Background (), jsonOutput , sszOutput , block .Deneb , blobSidecars )
297+ case spec .DataVersionElectra :
298+ var blobSidecars []* deneb.BlobSidecar
299+ var kzgCommitments []deneb.KZGCommitment
300+ kzgCommitments , err = block .BlobKZGCommitments ()
301+ if err != nil {
302+ fmt .Fprintf (os .Stderr , "Failed to obtain KZG commitments: %v\n " , err )
303+ return
304+ }
305+ if len (kzgCommitments ) > 0 {
306+ var blobSidecarsResponse * api.Response [[]* deneb.BlobSidecar ]
307+ blobSidecarsResponse , err = results .eth2Client .(eth2client.BlobSidecarsProvider ).BlobSidecars (ctx , & api.BlobSidecarsOpts {
308+ Block : blockID ,
309+ })
310+ if err != nil {
311+ fmt .Fprintf (os .Stderr , "Failed to obtain blob sidecars: %v\n " , err )
312+ return
313+ }
314+ blobSidecars = blobSidecarsResponse .Data
315+ }
316+ err = outputElectraBlock (context .Background (), jsonOutput , sszOutput , block .Electra , blobSidecars )
317+ case spec .DataVersionFulu :
318+ var blobSidecars []* deneb.BlobSidecar
319+ var kzgCommitments []deneb.KZGCommitment
320+ kzgCommitments , err = block .BlobKZGCommitments ()
321+ if err != nil {
322+ fmt .Fprintf (os .Stderr , "Failed to obtain KZG commitments: %v\n " , err )
323+ return
324+ }
325+ if len (kzgCommitments ) > 0 {
326+ var blobSidecarsResponse * api.Response [[]* deneb.BlobSidecar ]
327+ blobSidecarsResponse , err = results .eth2Client .(eth2client.BlobSidecarsProvider ).BlobSidecars (ctx , & api.BlobSidecarsOpts {
328+ Block : blockID ,
329+ })
330+ if err != nil {
331+ fmt .Fprintf (os .Stderr , "Failed to obtain blob sidecars: %v\n " , err )
332+ return
333+ }
334+ blobSidecars = blobSidecarsResponse .Data
335+ }
336+ err = outputFuluBlock (context .Background (), jsonOutput , sszOutput , block .Fulu , blobSidecars )
266337 default :
267338 err = errors .New ("unknown block version" )
268339 }
@@ -424,6 +495,35 @@ func outputElectraBlock(ctx context.Context,
424495 return nil
425496}
426497
498+ func outputFuluBlock (ctx context.Context ,
499+ jsonOutput bool ,
500+ sszOutput bool ,
501+ signedBlock * electra.SignedBeaconBlock ,
502+ blobs []* deneb.BlobSidecar ,
503+ ) error {
504+ switch {
505+ case jsonOutput :
506+ data , err := json .Marshal (signedBlock )
507+ if err != nil {
508+ return errors .Wrap (err , "failed to generate JSON" )
509+ }
510+ fmt .Printf ("%s\n " , string (data ))
511+ case sszOutput :
512+ data , err := signedBlock .MarshalSSZ ()
513+ if err != nil {
514+ return errors .Wrap (err , "failed to generate SSZ" )
515+ }
516+ fmt .Printf ("%x\n " , data )
517+ default :
518+ data , err := outputElectraBlockText (ctx , results , signedBlock , blobs )
519+ if err != nil {
520+ return errors .Wrap (err , "failed to generate text" )
521+ }
522+ fmt .Print (data )
523+ }
524+ return nil
525+ }
526+
427527func timeToBlockID (ctx context.Context , eth2Client eth2client.Service , input string ) (string , error ) {
428528 var timestamp time.Time
429529
0 commit comments