From 4beb890385eefc6e8f9d7f578c611720b5148cb4 Mon Sep 17 00:00:00 2001 From: Pedro Miranda <32689555+pedromiguelmiranda@users.noreply.github.com> Date: Sat, 28 Sep 2024 01:00:26 +0100 Subject: [PATCH] new pool attester slashings endpoint version (V2) for electra (#6585) * new pool attester slashings endpoint version (V2) for electra * formatting --------- Co-authored-by: Pedro Miranda --- beacon_chain/rpc/rest_beacon_api.nim | 49 +++++++++++++++++++ .../spec/eth2_apis/rest_beacon_calls.nim | 16 +++++- beacon_chain/validators/message_router.nim | 3 +- ncli/resttest-rules.json | 12 +++++ 4 files changed, 78 insertions(+), 2 deletions(-) diff --git a/beacon_chain/rpc/rest_beacon_api.nim b/beacon_chain/rpc/rest_beacon_api.nim index 66c22bcef..c97a77048 100644 --- a/beacon_chain/rpc/rest_beacon_api.nim +++ b/beacon_chain/rpc/rest_beacon_api.nim @@ -1509,6 +1509,55 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) = $res.error) RestApiResponse.jsonMsgResponse(AttesterSlashingValidationSuccess) + # https://ethereum.github.io/beacon-APIs/?urls.primaryName=dev#/Beacon/getPoolAttesterSlashingsV2 + router.api2(MethodGet, "/eth/v2/beacon/pool/attester_slashings") do ( + ) -> RestApiResponse: + + let contextFork = + node.dag.cfg.consensusForkAtEpoch(node.currentSlot.epoch) + + withConsensusFork(contextFork): + when consensusFork < ConsensusFork.Electra: + RestApiResponse.jsonResponseWVersion( + toSeq(node.validatorChangePool.phase0_attester_slashings), + contextFork) + else: + RestApiResponse.jsonResponseWVersion( + toSeq(node.validatorChangePool.electra_attester_slashings), + contextFork) + + # https://ethereum.github.io/beacon-APIs/?urls.primaryName=dev#/Beacon/submitPoolAttesterSlashingsV2 + router.api(MethodPost, "/eth/v2/beacon/pool/attester_slashings") do ( + contentBody: Option[ContentBody]) -> RestApiResponse: + + let + headerVersion = request.headers.getString("Eth-Consensus-Version") + consensusVersion = ConsensusFork.init(headerVersion) + if consensusVersion.isNone(): + return RestApiResponse.jsonError(Http400, FailedToObtainConsensusForkError) + + if contentBody.isNone(): + return RestApiResponse.jsonError(Http400, EmptyRequestBodyError) + + template decodeAttesterSlashing(AttesterSlashingType: untyped) = + let dres = decodeBody(AttesterSlashingType, contentBody.get()) + if dres.isErr(): + return RestApiResponse.jsonError(Http400, + InvalidAttesterSlashingObjectError, + $dres.error) + let res = await node.router.routeAttesterSlashing(dres.get()) + if res.isErr(): + return RestApiResponse.jsonError(Http400, + AttesterSlashingValidationError, + $res.error) + return RestApiResponse.jsonMsgResponse(AttesterSlashingValidationSuccess) + + case consensusVersion.get(): + of ConsensusFork.Phase0 .. ConsensusFork.Deneb: + decodeAttesterSlashing(phase0.AttesterSlashing) + of ConsensusFork.Electra: + decodeAttesterSlashing(electra.AttesterSlashing) + # https://ethereum.github.io/beacon-APIs/#/Beacon/getPoolProposerSlashings router.api2(MethodGet, "/eth/v1/beacon/pool/proposer_slashings") do ( ) -> RestApiResponse: diff --git a/beacon_chain/spec/eth2_apis/rest_beacon_calls.nim b/beacon_chain/spec/eth2_apis/rest_beacon_calls.nim index 4620ccaba..4acb4b41a 100644 --- a/beacon_chain/spec/eth2_apis/rest_beacon_calls.nim +++ b/beacon_chain/spec/eth2_apis/rest_beacon_calls.nim @@ -359,6 +359,18 @@ proc submitPoolAttesterSlashings*(body: phase0.AttesterSlashing): meth: MethodPost.} ## https://ethereum.github.io/beacon-APIs/#/Beacon/submitPoolAttesterSlashings +proc getPoolAttesterSlashingsV2Plain*(): RestPlainResponse {. + rest, endpoint: "/eth/v2/beacon/pool/attester_slashings", + meth: MethodGet.} + ## https://ethereum.github.io/beacon-APIs/?urls.primaryName=dev#/Beacon/getPoolAttesterSlashingsV2 + +proc submitPoolAttesterSlashings*( + body: phase0.AttesterSlashing | electra.AttesterSlashing + ): RestPlainResponse {. + rest, endpoint: "/eth/v1/beacon/pool/attester_slashings", + meth: MethodPost.} + ## https://ethereum.github.io/beacon-APIs/#/Beacon/submitPoolAttesterSlashings + proc getPoolProposerSlashings*(): RestResponse[GetPoolProposerSlashingsResponse] {. rest, endpoint: "/eth/v1/beacon/pool/proposer_slashings", meth: MethodGet.} @@ -369,7 +381,9 @@ proc submitPoolProposerSlashings*(body: ProposerSlashing): RestPlainResponse {. meth: MethodPost.} ## https://ethereum.github.io/beacon-APIs/#/Beacon/submitPoolProposerSlashings -proc submitPoolSyncCommitteeSignatures*(body: seq[RestSyncCommitteeMessage]): RestPlainResponse {. +proc submitPoolSyncCommitteeSignatures*( + body: seq[RestSyncCommitteeMessage] + ): RestPlainResponse {. rest, endpoint: "/eth/v1/beacon/pool/sync_committees", meth: MethodPost.} ## https://ethereum.github.io/beacon-APIs/#/Beacon/submitPoolSyncCommitteeSignatures diff --git a/beacon_chain/validators/message_router.nim b/beacon_chain/validators/message_router.nim index 7a65774fa..5cde690eb 100644 --- a/beacon_chain/validators/message_router.nim +++ b/beacon_chain/validators/message_router.nim @@ -483,7 +483,8 @@ proc routeSignedVoluntaryExit*( return ok() proc routeAttesterSlashing*( - router: ref MessageRouter, slashing: phase0.AttesterSlashing): + router: ref MessageRouter, + slashing: phase0.AttesterSlashing | electra.AttesterSlashing): Future[SendResult] {.async: (raises: [CancelledError]).} = block: let res = diff --git a/ncli/resttest-rules.json b/ncli/resttest-rules.json index b65a70234..427373fda 100644 --- a/ncli/resttest-rules.json +++ b/ncli/resttest-rules.json @@ -3975,6 +3975,18 @@ "body": [{"operator": "jstructcmps", "start": ["data"],"value": [{"attestation_1": {"attesting_indices": [""], "signature": "", "data": {"slot": "", "index": "", "beacon_block_root": "", "source": {"epoch": "", "root": ""}, "target": {"epoch": "", "root": ""}}}, "attestation_2": {"attesting_indices": [""], "signature": "", "data": {"slot": "", "index": "", "beacon_block_root": "", "source": {"epoch": "", "root": ""}, "target": {"epoch": "", "root": ""}}}}]}] } }, + { + "topics": ["beacon", "pool_attester_slashings_electra"], + "request": { + "url": "/eth/v2/beacon/pool/attester_slashings", + "headers": {"Accept": "application/json"} + }, + "response": { + "status": {"operator": "equals", "value": "200"}, + "headers": [{"key": "Content-Type", "value": "application/json", "operator": "equals"}, {"key": "eth-consensus-version", "value": ["phase0", "altair", "bellatrix"], "operator": "oneof"}], + "body": [{"operator": "jstructcmps", "start": ["data"],"value": [{"attestation_1": {"attesting_indices": [""], "signature": "", "data": {"slot": "", "index": "", "beacon_block_root": "", "source": {"epoch": "", "root": ""}, "target": {"epoch": "", "root": ""}}}, "attestation_2": {"attesting_indices": [""], "signature": "", "data": {"slot": "", "index": "", "beacon_block_root": "", "source": {"epoch": "", "root": ""}, "target": {"epoch": "", "root": ""}}}}]}] + } + }, { "topics": ["beacon", "pool_proposer_slashings"], "request": {