mirror of
https://github.com/status-im/nimbus-eth2.git
synced 2025-02-27 21:50:33 +00:00
avoid code repetition across forks for signed block contents (#6150)
Use forks sugar to make `RestPublishedSignedBlockContents` more concise.
This commit is contained in:
parent
109007dc93
commit
5f4fa9ae69
@ -129,21 +129,6 @@ proc toString*(kind: ValidatorFilterKind): string =
|
|||||||
of ValidatorFilterKind.WithdrawalDone:
|
of ValidatorFilterKind.WithdrawalDone:
|
||||||
"withdrawal_done"
|
"withdrawal_done"
|
||||||
|
|
||||||
func checkRestBlockBlobsValid(
|
|
||||||
forkyBlck: deneb.SignedBeaconBlock | electra.SignedBeaconBlock,
|
|
||||||
kzg_proofs: KzgProofs,
|
|
||||||
blobs: Blobs): Result[void, string] =
|
|
||||||
if kzg_proofs.len != blobs.len:
|
|
||||||
return err("Invalid block publish: " & $kzg_proofs.len & " KZG proofs and " &
|
|
||||||
$blobs.len & " blobs")
|
|
||||||
|
|
||||||
if kzg_proofs.len != forkyBlck.message.body.blob_kzg_commitments.len:
|
|
||||||
return err("Invalid block publish: " & $kzg_proofs.len &
|
|
||||||
" KZG proofs and " & $forkyBlck.message.body.blob_kzg_commitments.len &
|
|
||||||
" KZG commitments")
|
|
||||||
|
|
||||||
ok()
|
|
||||||
|
|
||||||
proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
||||||
# https://github.com/ethereum/EIPs/blob/master/EIPS/eip-4881.md
|
# https://github.com/ethereum/EIPs/blob/master/EIPS/eip-4881.md
|
||||||
router.api2(MethodGet, "/eth/v1/beacon/deposit_snapshot") do (
|
router.api2(MethodGet, "/eth/v1/beacon/deposit_snapshot") do (
|
||||||
@ -900,50 +885,23 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||||||
let
|
let
|
||||||
body = contentBody.get()
|
body = contentBody.get()
|
||||||
version = request.headers.getString("eth-consensus-version")
|
version = request.headers.getString("eth-consensus-version")
|
||||||
var
|
restBlock = decodeBody(
|
||||||
restBlock = decodeBody(RestPublishedSignedBlockContents, body,
|
RestPublishedSignedBlockContents, body, version).valueOr:
|
||||||
version).valueOr:
|
return RestApiResponse.jsonError(error)
|
||||||
return RestApiResponse.jsonError(error)
|
|
||||||
forked = ForkedSignedBeaconBlock.init(restBlock)
|
|
||||||
|
|
||||||
if restBlock.kind != node.dag.cfg.consensusForkAtEpoch(
|
withForkyBlck(restBlock):
|
||||||
getForkedBlockField(forked, slot).epoch):
|
if restBlock.kind != node.dag.cfg.consensusForkAtEpoch(
|
||||||
doAssert strictVerification notin node.dag.updateFlags
|
forkyBlck.message.slot.epoch):
|
||||||
return RestApiResponse.jsonError(Http400, InvalidBlockObjectError)
|
doAssert strictVerification notin node.dag.updateFlags
|
||||||
|
return RestApiResponse.jsonError(Http400, InvalidBlockObjectError)
|
||||||
|
|
||||||
case restBlock.kind
|
when consensusFork >= ConsensusFork.Deneb:
|
||||||
of ConsensusFork.Phase0:
|
await node.router.routeSignedBeaconBlock(
|
||||||
var blck = restBlock.phase0Data
|
forkyBlck, Opt.some(
|
||||||
blck.root = hash_tree_root(blck.message)
|
forkyBlck.create_blob_sidecars(kzg_proofs, blobs)))
|
||||||
await node.router.routeSignedBeaconBlock(
|
else:
|
||||||
blck, Opt.none(seq[BlobSidecar]))
|
await node.router.routeSignedBeaconBlock(
|
||||||
of ConsensusFork.Altair:
|
forkyBlck, Opt.none(seq[BlobSidecar]))
|
||||||
var blck = restBlock.altairData
|
|
||||||
blck.root = hash_tree_root(blck.message)
|
|
||||||
await node.router.routeSignedBeaconBlock(
|
|
||||||
blck, Opt.none(seq[BlobSidecar]))
|
|
||||||
of ConsensusFork.Bellatrix:
|
|
||||||
var blck = restBlock.bellatrixData
|
|
||||||
blck.root = hash_tree_root(blck.message)
|
|
||||||
await node.router.routeSignedBeaconBlock(
|
|
||||||
blck, Opt.none(seq[BlobSidecar]))
|
|
||||||
of ConsensusFork.Capella:
|
|
||||||
var blck = restBlock.capellaData
|
|
||||||
blck.root = hash_tree_root(blck.message)
|
|
||||||
await node.router.routeSignedBeaconBlock(
|
|
||||||
blck, Opt.none(seq[BlobSidecar]))
|
|
||||||
of ConsensusFork.Deneb:
|
|
||||||
var blck = restBlock.denebData.signed_block
|
|
||||||
blck.root = hash_tree_root(blck.message)
|
|
||||||
|
|
||||||
let validity = checkRestBlockBlobsValid(
|
|
||||||
blck, restBlock.denebData.kzg_proofs, restBlock.denebData.blobs)
|
|
||||||
if validity.isErr:
|
|
||||||
return RestApiResponse.jsonError(Http400, validity.error)
|
|
||||||
|
|
||||||
await node.router.routeSignedBeaconBlock(
|
|
||||||
blck, Opt.some(blck.create_blob_sidecars(
|
|
||||||
restBlock.denebData.kzg_proofs, restBlock.denebData.blobs)))
|
|
||||||
|
|
||||||
if res.isErr():
|
if res.isErr():
|
||||||
return RestApiResponse.jsonError(
|
return RestApiResponse.jsonError(
|
||||||
@ -981,51 +939,24 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||||||
if contentBody.isNone():
|
if contentBody.isNone():
|
||||||
return RestApiResponse.jsonError(Http400, EmptyRequestBodyError)
|
return RestApiResponse.jsonError(Http400, EmptyRequestBodyError)
|
||||||
contentBody.get()
|
contentBody.get()
|
||||||
var
|
restBlock = decodeBodyJsonOrSsz(
|
||||||
restBlock = decodeBodyJsonOrSsz(RestPublishedSignedBlockContents,
|
RestPublishedSignedBlockContents, body, version).valueOr:
|
||||||
body, version).valueOr:
|
return RestApiResponse.jsonError(error)
|
||||||
return RestApiResponse.jsonError(error)
|
|
||||||
forked = ForkedSignedBeaconBlock.init(restBlock)
|
|
||||||
|
|
||||||
# TODO (henridf): handle broadcast_validation flag
|
withForkyBlck(restBlock):
|
||||||
if restBlock.kind != node.dag.cfg.consensusForkAtEpoch(
|
# TODO (henridf): handle broadcast_validation flag
|
||||||
getForkedBlockField(forked, slot).epoch):
|
if restBlock.kind != node.dag.cfg.consensusForkAtEpoch(
|
||||||
doAssert strictVerification notin node.dag.updateFlags
|
forkyBlck.message.slot.epoch):
|
||||||
return RestApiResponse.jsonError(Http400, InvalidBlockObjectError)
|
doAssert strictVerification notin node.dag.updateFlags
|
||||||
|
return RestApiResponse.jsonError(Http400, InvalidBlockObjectError)
|
||||||
|
|
||||||
case restBlock.kind
|
when consensusFork >= ConsensusFork.Deneb:
|
||||||
of ConsensusFork.Phase0:
|
await node.router.routeSignedBeaconBlock(
|
||||||
var blck = restBlock.phase0Data
|
forkyBlck, Opt.some(
|
||||||
blck.root = hash_tree_root(blck.message)
|
forkyBlck.create_blob_sidecars(kzg_proofs, blobs)))
|
||||||
await node.router.routeSignedBeaconBlock(
|
else:
|
||||||
blck, Opt.none(seq[BlobSidecar]))
|
await node.router.routeSignedBeaconBlock(
|
||||||
of ConsensusFork.Altair:
|
forkyBlck, Opt.none(seq[BlobSidecar]))
|
||||||
var blck = restBlock.altairData
|
|
||||||
blck.root = hash_tree_root(blck.message)
|
|
||||||
await node.router.routeSignedBeaconBlock(
|
|
||||||
blck, Opt.none(seq[BlobSidecar]))
|
|
||||||
of ConsensusFork.Bellatrix:
|
|
||||||
var blck = restBlock.bellatrixData
|
|
||||||
blck.root = hash_tree_root(blck.message)
|
|
||||||
await node.router.routeSignedBeaconBlock(
|
|
||||||
blck, Opt.none(seq[BlobSidecar]))
|
|
||||||
of ConsensusFork.Capella:
|
|
||||||
var blck = restBlock.capellaData
|
|
||||||
blck.root = hash_tree_root(blck.message)
|
|
||||||
await node.router.routeSignedBeaconBlock(
|
|
||||||
blck, Opt.none(seq[BlobSidecar]))
|
|
||||||
of ConsensusFork.Deneb:
|
|
||||||
var blck = restBlock.denebData.signed_block
|
|
||||||
blck.root = hash_tree_root(blck.message)
|
|
||||||
|
|
||||||
let validity = checkRestBlockBlobsValid(
|
|
||||||
blck, restBlock.denebData.kzg_proofs, restBlock.denebData.blobs)
|
|
||||||
if validity.isErr:
|
|
||||||
return RestApiResponse.jsonError(Http400, validity.error)
|
|
||||||
|
|
||||||
await node.router.routeSignedBeaconBlock(
|
|
||||||
blck, Opt.some(blck.create_blob_sidecars(
|
|
||||||
restBlock.denebData.kzg_proofs, restBlock.denebData.blobs)))
|
|
||||||
|
|
||||||
if res.isErr():
|
if res.isErr():
|
||||||
return RestApiResponse.jsonError(
|
return RestApiResponse.jsonError(
|
||||||
|
@ -2020,44 +2020,8 @@ proc readValue*(reader: var JsonReader[RestJson],
|
|||||||
reader.raiseUnexpectedValue("Field `message` is missing")
|
reader.raiseUnexpectedValue("Field `message` is missing")
|
||||||
|
|
||||||
let blck = ForkedBeaconBlock(message.get())
|
let blck = ForkedBeaconBlock(message.get())
|
||||||
value = RestPublishedSignedBeaconBlock(
|
value = RestPublishedSignedBeaconBlock ForkedSignedBeaconBlock.init(
|
||||||
case blck.kind
|
blck, blck.hash_tree_root(), signature.get())
|
||||||
of ConsensusFork.Phase0:
|
|
||||||
ForkedSignedBeaconBlock.init(
|
|
||||||
phase0.SignedBeaconBlock(
|
|
||||||
message: blck.phase0Data,
|
|
||||||
signature: signature.get()
|
|
||||||
)
|
|
||||||
)
|
|
||||||
of ConsensusFork.Altair:
|
|
||||||
ForkedSignedBeaconBlock.init(
|
|
||||||
altair.SignedBeaconBlock(
|
|
||||||
message: blck.altairData,
|
|
||||||
signature: signature.get()
|
|
||||||
)
|
|
||||||
)
|
|
||||||
of ConsensusFork.Bellatrix:
|
|
||||||
ForkedSignedBeaconBlock.init(
|
|
||||||
bellatrix.SignedBeaconBlock(
|
|
||||||
message: blck.bellatrixData,
|
|
||||||
signature: signature.get()
|
|
||||||
)
|
|
||||||
)
|
|
||||||
of ConsensusFork.Capella:
|
|
||||||
ForkedSignedBeaconBlock.init(
|
|
||||||
capella.SignedBeaconBlock(
|
|
||||||
message: blck.capellaData,
|
|
||||||
signature: signature.get()
|
|
||||||
)
|
|
||||||
)
|
|
||||||
of ConsensusFork.Deneb:
|
|
||||||
ForkedSignedBeaconBlock.init(
|
|
||||||
deneb.SignedBeaconBlock(
|
|
||||||
message: blck.denebData,
|
|
||||||
signature: signature.get()
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
proc readValue*(reader: var JsonReader[RestJson],
|
proc readValue*(reader: var JsonReader[RestJson],
|
||||||
value: var RestPublishedSignedBlockContents) {.
|
value: var RestPublishedSignedBlockContents) {.
|
||||||
@ -2104,17 +2068,6 @@ proc readValue*(reader: var JsonReader[RestJson],
|
|||||||
Opt.none(RestPublishedSignedBeaconBlock)
|
Opt.none(RestPublishedSignedBeaconBlock)
|
||||||
if signed_message.isNone():
|
if signed_message.isNone():
|
||||||
reader.raiseUnexpectedValue("Incorrect signed_block format")
|
reader.raiseUnexpectedValue("Incorrect signed_block format")
|
||||||
|
|
||||||
# Only needed to signal fork to the blck.kind case selection
|
|
||||||
let blck = ForkedSignedBeaconBlock(signed_message.get())
|
|
||||||
message = Opt.some(RestPublishedBeaconBlock(
|
|
||||||
case blck.kind
|
|
||||||
of ConsensusFork.Phase0, ConsensusFork.Altair, ConsensusFork.Bellatrix,
|
|
||||||
ConsensusFork.Capella:
|
|
||||||
reader.raiseUnexpectedValue("Incorrect signed_block format")
|
|
||||||
of ConsensusFork.Deneb:
|
|
||||||
ForkedBeaconBlock.init(blck.denebData.message)
|
|
||||||
))
|
|
||||||
of "kzg_proofs":
|
of "kzg_proofs":
|
||||||
if kzg_proofs.isSome():
|
if kzg_proofs.isSome():
|
||||||
reader.raiseUnexpectedField(
|
reader.raiseUnexpectedField(
|
||||||
@ -2138,69 +2091,49 @@ proc readValue*(reader: var JsonReader[RestJson],
|
|||||||
else:
|
else:
|
||||||
unrecognizedFieldWarning()
|
unrecognizedFieldWarning()
|
||||||
|
|
||||||
if signed_message.isNone():
|
if signed_message.isSome():
|
||||||
# Pre-Deneb; conditions for when signed_message.isSome checked in case body
|
if message.isSome():
|
||||||
if signature.isNone():
|
reader.raiseUnexpectedValue("Field `message` found but unsupported")
|
||||||
reader.raiseUnexpectedValue("Field `signature` is missing")
|
if signature.isSome():
|
||||||
if message.isNone():
|
reader.raiseUnexpectedValue("Field `signature` found but unsupported")
|
||||||
reader.raiseUnexpectedValue("Field `message` is missing")
|
|
||||||
|
|
||||||
let blck = ForkedBeaconBlock(message.get())
|
|
||||||
|
|
||||||
if blck.kind >= ConsensusFork.Deneb:
|
|
||||||
if kzg_proofs.isNone():
|
if kzg_proofs.isNone():
|
||||||
reader.raiseUnexpectedValue("Field `kzg_proofs` is missing")
|
reader.raiseUnexpectedValue("Field `kzg_proofs` is missing")
|
||||||
if blobs.isNone():
|
if blobs.isNone():
|
||||||
reader.raiseUnexpectedValue("Field `blobs` is missing")
|
reader.raiseUnexpectedValue("Field `blobs` is missing")
|
||||||
|
if kzg_proofs.get.len != blobs.get.len:
|
||||||
|
reader.raiseUnexpectedValue("Length mismatch of `kzg_proofs` and `blobs`")
|
||||||
|
|
||||||
|
withBlck(distinctBase(signed_message.get)):
|
||||||
|
when consensusFork >= ConsensusFork.Deneb:
|
||||||
|
template kzg_commitments: untyped =
|
||||||
|
forkyBlck.message.body.blob_kzg_commitments
|
||||||
|
if kzg_proofs.get().len != kzg_commitments.len:
|
||||||
|
reader.raiseUnexpectedValue(
|
||||||
|
"Length mismatch of `kzg_proofs` and `blob_kzg_commitments`")
|
||||||
|
value = RestPublishedSignedBlockContents.init(
|
||||||
|
consensusFork.BlockContents(
|
||||||
|
`block`: forkyBlck.message,
|
||||||
|
kzg_proofs: kzg_proofs.get(),
|
||||||
|
blobs: blobs.get()),
|
||||||
|
forkyBlck.root, forkyBlck.signature)
|
||||||
|
else:
|
||||||
|
reader.raiseUnexpectedValue("`signed_message` supported post-Deneb")
|
||||||
else:
|
else:
|
||||||
|
if signature.isNone():
|
||||||
|
reader.raiseUnexpectedValue("Field `signature` is missing")
|
||||||
|
if message.isNone():
|
||||||
|
reader.raiseUnexpectedValue("Field `message` is missing")
|
||||||
if kzg_proofs.isSome():
|
if kzg_proofs.isSome():
|
||||||
reader.raiseUnexpectedValue("Field `kzg_proofs` found but unsupported")
|
reader.raiseUnexpectedValue("Field `kzg_proofs` found but unsupported")
|
||||||
if blobs.isSome():
|
if blobs.isSome():
|
||||||
reader.raiseUnexpectedValue("Field `blobs` found but unsupported")
|
reader.raiseUnexpectedValue("Field `blobs` found but unsupported")
|
||||||
|
|
||||||
case blck.kind
|
withBlck(distinctBase(message.get)):
|
||||||
of ConsensusFork.Phase0:
|
when consensusFork < ConsensusFork.Deneb:
|
||||||
value = RestPublishedSignedBlockContents(
|
value = RestPublishedSignedBlockContents.init(
|
||||||
kind: ConsensusFork.Phase0,
|
forkyBlck, forkyBlck.hash_tree_root(), signature.get)
|
||||||
phase0Data: phase0.SignedBeaconBlock(
|
else:
|
||||||
message: blck.phase0Data,
|
reader.raiseUnexpectedValue("`message` support stopped at Deneb")
|
||||||
signature: signature.get()
|
|
||||||
)
|
|
||||||
)
|
|
||||||
of ConsensusFork.Altair:
|
|
||||||
value = RestPublishedSignedBlockContents(
|
|
||||||
kind: ConsensusFork.Altair,
|
|
||||||
altairData: altair.SignedBeaconBlock(
|
|
||||||
message: blck.altairData,
|
|
||||||
signature: signature.get()
|
|
||||||
)
|
|
||||||
)
|
|
||||||
of ConsensusFork.Bellatrix:
|
|
||||||
value = RestPublishedSignedBlockContents(
|
|
||||||
kind: ConsensusFork.Bellatrix,
|
|
||||||
bellatrixData: bellatrix.SignedBeaconBlock(
|
|
||||||
message: blck.bellatrixData,
|
|
||||||
signature: signature.get()
|
|
||||||
)
|
|
||||||
)
|
|
||||||
of ConsensusFork.Capella:
|
|
||||||
value = RestPublishedSignedBlockContents(
|
|
||||||
kind: ConsensusFork.Capella,
|
|
||||||
capellaData: capella.SignedBeaconBlock(
|
|
||||||
message: blck.capellaData,
|
|
||||||
signature: signature.get()
|
|
||||||
)
|
|
||||||
)
|
|
||||||
of ConsensusFork.Deneb:
|
|
||||||
value = RestPublishedSignedBlockContents(
|
|
||||||
kind: ConsensusFork.Deneb,
|
|
||||||
denebData: DenebSignedBlockContents(
|
|
||||||
# Constructed to be internally consistent
|
|
||||||
signed_block: signed_message.get().distinctBase.denebData,
|
|
||||||
kzg_proofs: kzg_proofs.get(),
|
|
||||||
blobs: blobs.get()
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
## ForkedSignedBeaconBlock
|
## ForkedSignedBeaconBlock
|
||||||
proc readValue*(reader: var JsonReader[RestJson],
|
proc readValue*(reader: var JsonReader[RestJson],
|
||||||
|
@ -612,6 +612,32 @@ type
|
|||||||
func `==`*(a, b: RestValidatorIndex): bool =
|
func `==`*(a, b: RestValidatorIndex): bool =
|
||||||
uint64(a) == uint64(b)
|
uint64(a) == uint64(b)
|
||||||
|
|
||||||
|
template withForkyBlck*(
|
||||||
|
x: RestPublishedSignedBlockContents, body: untyped): untyped =
|
||||||
|
case x.kind
|
||||||
|
of ConsensusFork.Deneb:
|
||||||
|
const consensusFork {.inject, used.} = ConsensusFork.Deneb
|
||||||
|
template forkyBlck: untyped {.inject, used.} = x.denebData.signed_block
|
||||||
|
template kzg_proofs: untyped {.inject, used.} = x.denebData.kzg_proofs
|
||||||
|
template blobs: untyped {.inject, used.} = x.denebData.blobs
|
||||||
|
body
|
||||||
|
of ConsensusFork.Capella:
|
||||||
|
const consensusFork {.inject, used.} = ConsensusFork.Capella
|
||||||
|
template forkyBlck: untyped {.inject, used.} = x.capellaData
|
||||||
|
body
|
||||||
|
of ConsensusFork.Bellatrix:
|
||||||
|
const consensusFork {.inject, used.} = ConsensusFork.Bellatrix
|
||||||
|
template forkyBlck: untyped {.inject, used.} = x.bellatrixData
|
||||||
|
body
|
||||||
|
of ConsensusFork.Altair:
|
||||||
|
const consensusFork {.inject, used.} = ConsensusFork.Altair
|
||||||
|
template forkyBlck: untyped {.inject, used.} = x.altairData
|
||||||
|
body
|
||||||
|
of ConsensusFork.Phase0:
|
||||||
|
const consensusFork {.inject, used.} = ConsensusFork.Phase0
|
||||||
|
template forkyBlck: untyped {.inject, used.} = x.phase0Data
|
||||||
|
body
|
||||||
|
|
||||||
func init*(T: type ForkedSignedBeaconBlock,
|
func init*(T: type ForkedSignedBeaconBlock,
|
||||||
contents: RestPublishedSignedBlockContents): T =
|
contents: RestPublishedSignedBlockContents): T =
|
||||||
return
|
return
|
||||||
|
Loading…
x
Reference in New Issue
Block a user