diff --git a/beacon_chain/rpc/rest_beacon_api.nim b/beacon_chain/rpc/rest_beacon_api.nim index 5a7e0fe5f..0a24dad32 100644 --- a/beacon_chain/rpc/rest_beacon_api.nim +++ b/beacon_chain/rpc/rest_beacon_api.nim @@ -1034,11 +1034,7 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) = return RestApiResponse.jsonError(Http400, BlockIncorrectFork) withConsensusFork(currentEpochFork): - when consensusFork >= ConsensusFork.Electra: - debugRaiseAssert "beacon API builder API" - return RestApiResponse.jsonError( - Http400, $consensusFork & " builder API unsupported") - elif consensusFork >= ConsensusFork.Deneb: + when consensusFork >= ConsensusFork.Deneb: let restBlock = decodeBodyJsonOrSsz( consensusFork.SignedBlindedBeaconBlock, body).valueOr: diff --git a/beacon_chain/spec/eth2_apis/eth2_rest_serialization.nim b/beacon_chain/spec/eth2_apis/eth2_rest_serialization.nim index 978c6d05c..19af7c3ab 100644 --- a/beacon_chain/spec/eth2_apis/eth2_rest_serialization.nim +++ b/beacon_chain/spec/eth2_apis/eth2_rest_serialization.nim @@ -173,6 +173,7 @@ RestJson.useDefaultSerializationFor( SignedValidatorRegistrationV1, SignedVoluntaryExit, SubmitBlindedBlockResponseDeneb, + SubmitBlindedBlockResponseElectra, SyncAggregate, SyncAggregatorSelectionData, SyncCommittee, @@ -328,6 +329,7 @@ type bellatrix_mev.SignedBlindedBeaconBlock | capella_mev.SignedBlindedBeaconBlock | deneb_mev.SignedBlindedBeaconBlock | + electra_mev.SignedBlindedBeaconBlock | SignedValidatorRegistrationV1 | SignedVoluntaryExit | Web3SignerRequest | diff --git a/beacon_chain/spec/eth2_apis/rest_types.nim b/beacon_chain/spec/eth2_apis/rest_types.nim index 6ceca88a3..0a9050016 100644 --- a/beacon_chain/spec/eth2_apis/rest_types.nim +++ b/beacon_chain/spec/eth2_apis/rest_types.nim @@ -574,6 +574,7 @@ type ProduceBlindedBlockResponse* = ForkedBlindedBeaconBlock ProduceSyncCommitteeContributionResponse* = DataEnclosedObject[SyncCommitteeContribution] SubmitBlindedBlockResponseDeneb* = DataEnclosedObject[deneb_mev.ExecutionPayloadAndBlobsBundle] + SubmitBlindedBlockResponseElectra* = DataEnclosedObject[electra_mev.ExecutionPayloadAndBlobsBundle] GetValidatorsActivityResponse* = DataEnclosedObject[seq[RestActivityItem]] GetValidatorsLivenessResponse* = DataEnclosedObject[seq[RestLivenessItem]] SubmitBeaconCommitteeSelectionsResponse* = DataEnclosedObject[seq[RestBeaconCommitteeSelection]] diff --git a/beacon_chain/spec/forks.nim b/beacon_chain/spec/forks.nim index 1c2229c6c..504d390af 100644 --- a/beacon_chain/spec/forks.nim +++ b/beacon_chain/spec/forks.nim @@ -393,7 +393,8 @@ template kind*( electra.TrustedBeaconBlockBody | electra.SigVerifiedSignedBeaconBlock | electra.MsgTrustedSignedBeaconBlock | - electra.TrustedSignedBeaconBlock]): ConsensusFork = + electra.TrustedSignedBeaconBlock | + electra_mev.SignedBlindedBeaconBlock]): ConsensusFork = ConsensusFork.Electra template BeaconState*(kind: static ConsensusFork): auto = @@ -507,7 +508,9 @@ template MaybeBlindedBeaconBlock*(kind: static ConsensusFork): auto = static: raiseAssert "Unreachable" template SignedBlindedBeaconBlock*(kind: static ConsensusFork): auto = - when kind == ConsensusFork.Deneb: + when kind == ConsensusFork.Electra: + typedesc[electra_mev.SignedBlindedBeaconBlock] + elif kind == ConsensusFork.Deneb: typedesc[deneb_mev.SignedBlindedBeaconBlock] elif kind == ConsensusFork.Capella or kind == ConsensusFork.Bellatrix: static: raiseAssert "Unsupported" diff --git a/beacon_chain/spec/mev/rest_electra_mev_calls.nim b/beacon_chain/spec/mev/rest_electra_mev_calls.nim new file mode 100644 index 000000000..fd58ad193 --- /dev/null +++ b/beacon_chain/spec/mev/rest_electra_mev_calls.nim @@ -0,0 +1,20 @@ +# beacon_chain +# Copyright (c) 2024 Status Research & Development GmbH +# Licensed and distributed under either of +# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT). +# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0). +# at your option. This file may not be copied, modified, or distributed except according to those terms. + +{.push raises: [].} + +import + chronos, presto/client, + ".."/eth2_apis/[rest_types, eth2_rest_serialization] + +export chronos, client, rest_types, eth2_rest_serialization + +proc submitBlindedBlock*(body: electra_mev.SignedBlindedBeaconBlock + ): RestPlainResponse {. + rest, endpoint: "/eth/v1/builder/blinded_blocks", + meth: MethodPost, connection: {Dedicated, Close}.} + ## https://github.com/ethereum/builder-specs/blob/v0.4.0/apis/builder/blinded_blocks.yaml diff --git a/beacon_chain/validators/beacon_validators.nim b/beacon_chain/validators/beacon_validators.nim index 436db1617..d57be0817 100644 --- a/beacon_chain/validators/beacon_validators.nim +++ b/beacon_chain/validators/beacon_validators.nim @@ -42,7 +42,7 @@ import ".."/[conf, beacon_clock, beacon_node], "."/[ keystore_management, slashing_protection, validator_duties, validator_pool], - ".."/spec/mev/rest_deneb_mev_calls + ".."/spec/mev/[rest_deneb_mev_calls, rest_electra_mev_calls] from std/sequtils import countIt, foldl, mapIt from eth/async_utils import awaitWithTimeout diff --git a/beacon_chain/validators/message_router_mev.nim b/beacon_chain/validators/message_router_mev.nim index 2957bf01d..28834f27e 100644 --- a/beacon_chain/validators/message_router_mev.nim +++ b/beacon_chain/validators/message_router_mev.nim @@ -15,6 +15,7 @@ import ../beacon_node from eth/async_utils import awaitWithTimeout from ../spec/datatypes/bellatrix import SignedBeaconBlock from ../spec/mev/rest_deneb_mev_calls import submitBlindedBlock +from ../spec/mev/rest_electra_mev_calls import submitBlindedBlock const BUILDER_BLOCK_SUBMISSION_DELAY_TOLERANCE = 5.seconds @@ -43,7 +44,9 @@ macro copyFields*( proc unblindAndRouteBlockMEV*( node: BeaconNode, payloadBuilderRestClient: RestClientRef, - blindedBlock: deneb_mev.SignedBlindedBeaconBlock): + blindedBlock: + deneb_mev.SignedBlindedBeaconBlock | + electra_mev.SignedBlindedBeaconBlock): Future[Result[Opt[BlockRef], string]] {.async: (raises: [CancelledError]).} = const consensusFork = typeof(blindedBlock).kind @@ -76,14 +79,19 @@ proc unblindAndRouteBlockMEV*( return err("submitBlindedBlock failed with HTTP error code " & $response.status & ": " & $shortLog(blindedBlock)) - let - res = decodeBytes( + when blindedBlock is deneb_mev.SignedBlindedBeaconBlock: + let res = decodeBytes( SubmitBlindedBlockResponseDeneb, response.data, response.contentType) + elif blindedBlock is electra_mev.SignedBlindedBeaconBlock: + let res = decodeBytes( + SubmitBlindedBlockResponseElectra, response.data, response.contentType) + else: + static: doAssert false - bundle = res.valueOr: - return err("Could not decode " & $consensusFork & " blinded block: " & $res.error & - " with HTTP status " & $response.status & ", Content-Type " & - $response.contentType & " and content " & $response.data) + let bundle = res.valueOr: + return err("Could not decode " & $consensusFork & " blinded block: " & $res.error & + " with HTTP status " & $response.status & ", Content-Type " & + $response.contentType & " and content " & $response.data) template execution_payload: untyped = bundle.data.execution_payload