From 97bfca4b88bf24121ebe46705e5362f21a469d9d Mon Sep 17 00:00:00 2001
From: tersec <tersec@users.noreply.github.com>
Date: Mon, 8 Apr 2024 12:49:03 +0000
Subject: [PATCH] implement Electra beacon API getBlindedBlock (#6183)

---
 beacon_chain/rpc/rest_beacon_api.nim          |  6 +--
 .../eth2_apis/eth2_rest_serialization.nim     |  3 ++
 beacon_chain/spec/eth2_apis/rest_types.nim    | 16 +++++--
 beacon_chain/spec/forks.nim                   | 45 ++++++++++++-------
 beacon_chain/validators/validator_pool.nim    |  3 +-
 5 files changed, 49 insertions(+), 24 deletions(-)

diff --git a/beacon_chain/rpc/rest_beacon_api.nim b/beacon_chain/rpc/rest_beacon_api.nim
index 0af313029..5a7e0fe5f 100644
--- a/beacon_chain/rpc/rest_beacon_api.nim
+++ b/beacon_chain/rpc/rest_beacon_api.nim
@@ -1003,11 +1003,7 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
         RestApiResponse.jsonError(Http500, InvalidAcceptError)
 
     withBlck(bdata.asSigned()):
-      when consensusFork == ConsensusFork.Electra:
-        debugRaiseAssert "electra, beacon API missing"
-        let x = 5
-        RestApiResponse.jsonError(Http500, InvalidAcceptError)
-      elif consensusFork <= ConsensusFork.Altair:
+      when consensusFork <= ConsensusFork.Altair:
         respondSszOrJson(forkyBlck, consensusFork)
       else:
         respondSszOrJson(toSignedBlindedBeaconBlock(forkyBlck), consensusFork)
diff --git a/beacon_chain/spec/eth2_apis/eth2_rest_serialization.nim b/beacon_chain/spec/eth2_apis/eth2_rest_serialization.nim
index 31e19fc88..978c6d05c 100644
--- a/beacon_chain/spec/eth2_apis/eth2_rest_serialization.nim
+++ b/beacon_chain/spec/eth2_apis/eth2_rest_serialization.nim
@@ -250,7 +250,10 @@ RestJson.useDefaultSerializationFor(
   electra.ExecutionPayload,
   electra.ExecutionPayloadHeader,
   electra.SignedBeaconBlock,
+  electra_mev.BlindedBeaconBlock,
+  electra_mev.BlindedBeaconBlockBody,
   electra_mev.ExecutionPayloadAndBlobsBundle,
+  electra_mev.SignedBlindedBeaconBlock,
   phase0.BeaconBlock,
   phase0.BeaconBlockBody,
   phase0.BeaconState,
diff --git a/beacon_chain/spec/eth2_apis/rest_types.nim b/beacon_chain/spec/eth2_apis/rest_types.nim
index 67301e68b..6ceca88a3 100644
--- a/beacon_chain/spec/eth2_apis/rest_types.nim
+++ b/beacon_chain/spec/eth2_apis/rest_types.nim
@@ -721,10 +721,20 @@ func init*(t: typedesc[RestPublishedSignedBlockContents],
   )
 
 func init*(t: typedesc[RestPublishedSignedBlockContents],
-           contents: electra.BeaconBlock, root: Eth2Digest,
+           contents: electra.BlockContents, root: Eth2Digest,
            signature: ValidatorSig): RestPublishedSignedBlockContents =
-  debugRaiseAssert "init*(t: typedesc[RestPublishedSignedBlockContents],"
-  default(RestPublishedSignedBlockContents)
+  RestPublishedSignedBlockContents(
+    kind: ConsensusFork.Electra,
+    electraData: ElectraSignedBlockContents(
+      signed_block: electra.SignedBeaconBlock(
+        message: contents.`block`,
+        root: root,
+        signature: signature
+      ),
+      kzg_proofs: contents.kzg_proofs,
+      blobs: contents.blobs
+    )
+  )
 
 func init*(t: typedesc[StateIdent], v: StateIdentType): StateIdent =
   StateIdent(kind: StateQueryKind.Named, value: v)
diff --git a/beacon_chain/spec/forks.nim b/beacon_chain/spec/forks.nim
index e961a15b8..1c2229c6c 100644
--- a/beacon_chain/spec/forks.nim
+++ b/beacon_chain/spec/forks.nim
@@ -173,7 +173,7 @@ type
     of ConsensusFork.Deneb:
       denebData*: deneb_mev.MaybeBlindedBeaconBlock
     of ConsensusFork.Electra:
-      electraData*: electra.BeaconBlock
+      electraData*: electra_mev.MaybeBlindedBeaconBlock
     consensusValue*: Opt[UInt256]
     executionValue*: Opt[UInt256]
 
@@ -188,7 +188,7 @@ type
     of ConsensusFork.Bellatrix: bellatrixData*: bellatrix_mev.BlindedBeaconBlock
     of ConsensusFork.Capella:   capellaData*:   capella_mev.BlindedBeaconBlock
     of ConsensusFork.Deneb:     denebData*:     deneb_mev.BlindedBeaconBlock
-    of ConsensusFork.Electra:   electraData*:   electra.BeaconBlock
+    of ConsensusFork.Electra:   electraData*:   electra_mev.BlindedBeaconBlock
 
   ForkySignedBeaconBlock* =
     phase0.SignedBeaconBlock |
@@ -212,7 +212,8 @@ type
     altair.SignedBeaconBlock |
     bellatrix_mev.SignedBlindedBeaconBlock |
     capella_mev.SignedBlindedBeaconBlock |
-    deneb_mev.SignedBlindedBeaconBlock
+    deneb_mev.SignedBlindedBeaconBlock |
+    electra_mev.SignedBlindedBeaconBlock
 
   ForkedSignedBlindedBeaconBlock* = object
     case kind*: ConsensusFork
@@ -221,7 +222,7 @@ type
     of ConsensusFork.Bellatrix: bellatrixData*: bellatrix_mev.SignedBlindedBeaconBlock
     of ConsensusFork.Capella:   capellaData*:   capella_mev.SignedBlindedBeaconBlock
     of ConsensusFork.Deneb:     denebData*:     deneb_mev.SignedBlindedBeaconBlock
-    of ConsensusFork.Electra:   electraData*:   electra.SignedBeaconBlock
+    of ConsensusFork.Electra:   electraData*:   electra_mev.SignedBlindedBeaconBlock
 
   ForkySigVerifiedSignedBeaconBlock* =
     phase0.SigVerifiedSignedBeaconBlock |
@@ -496,7 +497,9 @@ template BlindedBeaconBlock*(kind: static ConsensusFork): auto =
     static: raiseAssert "Unreachable"
 
 template MaybeBlindedBeaconBlock*(kind: static ConsensusFork): auto =
-  when kind == ConsensusFork.Deneb:
+  when kind == ConsensusFork.Electra:
+    typedesc[electra_mev.MaybeBlindedBeaconBlock]
+  elif kind == ConsensusFork.Deneb:
     typedesc[deneb_mev.MaybeBlindedBeaconBlock]
   elif kind == ConsensusFork.Capella or kind == ConsensusFork.Bellatrix:
     static: raiseAssert "Unsupported"
@@ -716,9 +719,8 @@ func init*(T: type ForkedSignedBlindedBeaconBlock,
                                                     signature: signature))
   of ConsensusFork.Electra:
     T(kind: ConsensusFork.Electra,
-      electraData: electra.SignedBeaconBlock(message: forked.electraData,
-                                             root: blockRoot,
-                                             signature: signature))
+      electraData: electra_mev.SignedBlindedBeaconBlock(message: forked.electraData,
+                                                        signature: signature))
 
 template init*(T: type ForkedSignedBlindedBeaconBlock,
                blck: capella_mev.BlindedBeaconBlock, blockRoot: Eth2Digest,
@@ -734,6 +736,13 @@ template init*(T: type ForkedSignedBlindedBeaconBlock,
     denebData: deneb_mev.SignedBlindedBeaconBlock(
       message: blck, signature: signature))
 
+template init*(T: type ForkedSignedBlindedBeaconBlock,
+               blck: electra_mev.BlindedBeaconBlock, blockRoot: Eth2Digest,
+               signature: ValidatorSig): T =
+  T(kind: ConsensusFork.Electra,
+    electraData: electra_mev.SignedBlindedBeaconBlock(
+      message: blck, signature: signature))
+
 template init*(T: type ForkedMsgTrustedSignedBeaconBlock, blck: phase0.MsgTrustedSignedBeaconBlock): T =
   T(kind: ConsensusFork.Phase0,    phase0Data: blck)
 template init*(T: type ForkedMsgTrustedSignedBeaconBlock, blck: altair.MsgTrustedSignedBeaconBlock): T =
@@ -1104,11 +1113,17 @@ template withForkyMaybeBlindedBlck*(
     body: untyped): untyped =
   case b.kind
   of ConsensusFork.Electra:
-    const
-      consensusFork {.inject, used.} = ConsensusFork.Electra
-      isBlinded {.inject, used.} = false
-    template forkyMaybeBlindedBlck: untyped {.inject, used.} = b.electraData
-    body
+    const consensusFork {.inject, used.} = ConsensusFork.Electra
+    template d: untyped = b.electraData
+    case d.isBlinded:
+    of true:
+      const isBlinded {.inject, used.} = true
+      template forkyMaybeBlindedBlck: untyped {.inject, used.} = d.blindedData
+      body
+    of false:
+      const isBlinded {.inject, used.} = false
+      template forkyMaybeBlindedBlck: untyped {.inject, used.} = d.data
+      body
   of ConsensusFork.Deneb:
     const consensusFork {.inject, used.} = ConsensusFork.Deneb
     template d: untyped = b.denebData
@@ -1185,8 +1200,8 @@ template withStateAndBlck*(
     body
 
 func toBeaconBlockHeader*(
-    blck: SomeForkyBeaconBlock | deneb_mev.BlindedBeaconBlock):
-    BeaconBlockHeader =
+    blck: SomeForkyBeaconBlock | deneb_mev.BlindedBeaconBlock |
+    electra_mev.BlindedBeaconBlock): BeaconBlockHeader =
   ## Reduce a given `BeaconBlock` to its `BeaconBlockHeader`.
   BeaconBlockHeader(
     slot: blck.slot,
diff --git a/beacon_chain/validators/validator_pool.nim b/beacon_chain/validators/validator_pool.nim
index a04f21dda..d0f1eb7ca 100644
--- a/beacon_chain/validators/validator_pool.nim
+++ b/beacon_chain/validators/validator_pool.nim
@@ -509,7 +509,8 @@ proc getBlockSignature*(v: AttachedValidator, fork: Fork,
     capella.BeaconBlockBody |
     deneb.BeaconBlockBody |
     deneb_mev.BlindedBeaconBlockBody |
-    electra.BeaconBlockBody
+    electra.BeaconBlockBody |
+    electra_mev.BlindedBeaconBlockBody
 
   template blockPropertiesProofs(blockBody: SomeBlockBody,
                                  forkIndexField: untyped): seq[Web3SignerMerkleProof] =