initial implementation of capella MEV (#4567)

This commit is contained in:
tersec 2023-02-06 19:07:30 +01:00 committed by GitHub
parent b79d267b8f
commit ebb45e10da
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 130 additions and 17 deletions

View File

@ -856,7 +856,8 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
of ConsensusFork.Bellatrix:
let res =
block:
let restBlock = decodeBodyJsonOrSsz(SignedBlindedBeaconBlock, body).valueOr:
let restBlock = decodeBodyJsonOrSsz(
bellatrix_mev.SignedBlindedBeaconBlock, body).valueOr:
return RestApiResponse.jsonError(Http400, InvalidBlockObjectError,
$error)
await node.unblindAndRouteBlockMEV(restBlock)

View File

@ -13,7 +13,7 @@ import stew/[assign2, results, base10, byteutils], presto/common,
import ".."/[eth2_ssz_serialization, forks, keystore],
".."/../consensus_object_pools/block_pools_types,
".."/datatypes/[phase0, altair, bellatrix],
".."/mev/bellatrix_mev,
".."/mev/[bellatrix_mev, capella_mev],
".."/../validators/slashing_protection_common,
"."/[rest_types, rest_keymanager_types]
import nimcrypto/utils as ncrutils
@ -85,7 +85,8 @@ type
PrepareBeaconProposer |
ProposerSlashing |
SetFeeRecipientRequest |
SignedBlindedBeaconBlock |
bellatrix_mev.SignedBlindedBeaconBlock |
capella_mev.SignedBlindedBeaconBlock |
SignedValidatorRegistrationV1 |
SignedVoluntaryExit |
Web3SignerRequest

View File

@ -143,7 +143,8 @@ proc publishBlindedBlock*(body: altair.SignedBeaconBlock): RestPlainResponse {.
meth: MethodPost.}
## https://ethereum.github.io/beacon-APIs/#/Beacon/publishBlindedBlock
proc publishBlindedBlock*(body: SignedBlindedBeaconBlock): RestPlainResponse {.
proc publishBlindedBlock*(body: bellatrix_mev.SignedBlindedBeaconBlock):
RestPlainResponse {.
rest, endpoint: "/eth/v1/beacon/blinded_blocks",
meth: MethodPost.}
## https://ethereum.github.io/beacon-APIs/#/Beacon/publishBlindedBlock

View File

@ -18,11 +18,11 @@ import
stew/base10, web3/ethtypes,
".."/forks,
".."/datatypes/[phase0, altair, bellatrix, eip4844],
".."/mev/bellatrix_mev
".."/mev/[bellatrix_mev, capella_mev]
from ".."/datatypes/capella import BeaconBlockBody
export forks, phase0, altair, bellatrix, capella, bellatrix_mev
export forks, phase0, altair, bellatrix, capella, bellatrix_mev, capella_mev
const
# https://github.com/ethereum/eth2.0-APIs/blob/master/apis/beacon/states/validator_balances.yaml#L17
@ -633,7 +633,7 @@ type
GetEpochCommitteesResponse* = DataEnclosedObject[seq[RestBeaconStatesCommittees]]
GetForkScheduleResponse* = DataEnclosedObject[seq[Fork]]
GetGenesisResponse* = DataEnclosedObject[RestGenesis]
GetHeaderResponse* = DataVersionEnclosedObject[SignedBuilderBid]
GetHeaderResponse* = DataVersionEnclosedObject[bellatrix_mev.SignedBuilderBid]
GetNetworkIdentityResponse* = DataEnclosedObject[RestNetworkIdentity]
GetPeerCountResponse* = DataMetaEnclosedObject[RestPeerCount]
GetPeerResponse* = DataMetaEnclosedObject[RestNodePeer]
@ -659,7 +659,8 @@ type
ProduceBlockResponseV2* = ForkedBeaconBlock
ProduceBlindedBlockResponse* = ForkedBlindedBeaconBlock
ProduceSyncCommitteeContributionResponse* = DataEnclosedObject[SyncCommitteeContribution]
SubmitBlindedBlockResponse* = DataEnclosedObject[bellatrix.ExecutionPayload]
SubmitBlindedBlockResponseBellatrix* = DataEnclosedObject[bellatrix.ExecutionPayload]
SubmitBlindedBlockResponseCapella* = DataEnclosedObject[capella.ExecutionPayload]
GetValidatorsActivityResponse* = DataEnclosedObject[seq[RestActivityItem]]
GetValidatorsLivenessResponse* = DataEnclosedObject[seq[RestLivenessItem]]

View File

@ -0,0 +1,79 @@
# beacon_chain
# Copyright (c) 2023 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.
import ".."/datatypes/[altair, capella]
from stew/byteutils import to0xHex
{.push raises: [].}
type
# https://github.com/jimmygchen/builder-specs/blob/0e15394bc239d3fee1ba9e42f4ce67ff6565537b/specs/builder.md#builderbid-1
BuilderBid* = object
header*: capella.ExecutionPayloadHeader # [Modified in Capella]
value*: UInt256
pubkey*: ValidatorPubKey
# https://github.com/jimmygchen/builder-specs/blob/0e15394bc239d3fee1ba9e42f4ce67ff6565537b/specs/builder.md#signedbuilderbid-1
SignedBuilderBid* = object
message*: BuilderBid # [Modified in Capella]
signature*: ValidatorSig
# https://github.com/jimmygchen/builder-specs/blob/0e15394bc239d3fee1ba9e42f4ce67ff6565537b/specs/builder.md#blindedbeaconblockbody-1
BlindedBeaconBlockBody = object
randao_reveal*: ValidatorSig
eth1_data*: Eth1Data
graffiti*: GraffitiBytes
proposer_slashings*: List[ProposerSlashing, Limit MAX_PROPOSER_SLASHINGS]
attester_slashings*: List[AttesterSlashing, Limit MAX_ATTESTER_SLASHINGS]
attestations*: List[Attestation, Limit MAX_ATTESTATIONS]
deposits*: List[Deposit, Limit MAX_DEPOSITS]
voluntary_exits*: List[SignedVoluntaryExit, Limit MAX_VOLUNTARY_EXITS]
sync_aggregate*: SyncAggregate
execution_payload_header*:
capella.ExecutionPayloadHeader # [Modified in Capella]
bls_to_execution_changes*:
List[SignedBLSToExecutionChange,
Limit MAX_BLS_TO_EXECUTION_CHANGES] # [New in Capella]
# https://github.com/jimmygchen/builder-specs/blob/0e15394bc239d3fee1ba9e42f4ce67ff6565537b/specs/builder.md#blindedbeaconblock-1
BlindedBeaconBlock* = object
slot*: Slot
proposer_index*: uint64
parent_root*: Eth2Digest
state_root*: Eth2Digest
body*: BlindedBeaconBlockBody # [Modified in Capella]
# https://github.com/jimmygchen/builder-specs/blob/0e15394bc239d3fee1ba9e42f4ce67ff6565537b/specs/builder.md#signedblindedbeaconblock-1
SignedBlindedBeaconBlock* = object
message*: BlindedBeaconBlock
signature*: ValidatorSig
func shortLog*(v: BlindedBeaconBlock): auto =
(
slot: shortLog(v.slot),
proposer_index: v.proposer_index,
parent_root: shortLog(v.parent_root),
state_root: shortLog(v.state_root),
eth1data: v.body.eth1_data,
graffiti: $v.body.graffiti,
proposer_slashings_len: v.body.proposer_slashings.len(),
attester_slashings_len: v.body.attester_slashings.len(),
attestations_len: v.body.attestations.len(),
deposits_len: v.body.deposits.len(),
voluntary_exits_len: v.body.voluntary_exits.len(),
sync_committee_participants: v.body.sync_aggregate.num_active_participants,
block_number: v.body.execution_payload_header.block_number,
# TODO checksum hex? shortlog?
fee_recipient: to0xHex(v.body.execution_payload_header.fee_recipient.data),
bls_to_execution_changes_len: v.body.bls_to_execution_changes.len()
)
func shortLog*(v: SignedBlindedBeaconBlock): auto =
(
blck: shortLog(v.message),
signature: shortLog(v.signature)
)

View File

@ -27,8 +27,8 @@ proc getHeader*(slot: Slot,
meth: MethodGet, connection: {Dedicated, Close}.}
## https://github.com/ethereum/builder-specs/blob/v0.2.0/apis/builder/header.yaml
proc submitBlindedBlock*(body: SignedBlindedBeaconBlock
): RestResponse[SubmitBlindedBlockResponse] {.
proc submitBlindedBlock*(body: bellatrix_mev.SignedBlindedBeaconBlock
): RestResponse[SubmitBlindedBlockResponseBellatrix] {.
rest, endpoint: "/eth/v1/builder/blinded_blocks",
meth: MethodPost, connection: {Dedicated, Close}.}
## https://github.com/ethereum/builder-specs/blob/v0.2.0/apis/builder/blinded_blocks.yaml

View File

@ -0,0 +1,28 @@
# Copyright (c) 2023 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
# TODO
#proc getHeader*(slot: Slot,
# parent_hash: Eth2Digest,
# pubkey: ValidatorPubKey
# ): RestResponse[GetHeaderResponse] {.
# rest, endpoint: "/eth/v1/builder/header/{slot}/{parent_hash}/{pubkey}",
# meth: MethodGet, connection: {Dedicated, Close}.}
# ## https://github.com/jimmygchen/builder-specs/blob/0e15394bc239d3fee1ba9e42f4ce67ff6565537b/apis/builder/header.yaml
proc submitBlindedBlock*(body: capella_mev.SignedBlindedBeaconBlock
): RestResponse[SubmitBlindedBlockResponseCapella] {.
rest, endpoint: "/eth/v1/builder/blinded_blocks",
meth: MethodPost, connection: {Dedicated, Close}.}
## https://github.com/jimmygchen/builder-specs/blob/0e15394bc239d3fee1ba9e42f4ce67ff6565537b/apis/builder/blinded_blocks.yaml

View File

@ -14,6 +14,7 @@ import ../beacon_node
from eth/async_utils import awaitWithTimeout
from ../spec/datatypes/bellatrix import SignedBeaconBlock
from ../spec/mev/rest_bellatrix_mev_calls import submitBlindedBlock
from ../spec/mev/rest_capella_mev_calls import submitBlindedBlock
const
BUILDER_BLOCK_SUBMISSION_DELAY_TOLERANCE = 4.seconds
@ -41,7 +42,7 @@ macro copyFields*(
newDotExpr(dst, ident(name)), newDotExpr(src, ident(name)))
proc unblindAndRouteBlockMEV*(
node: BeaconNode, blindedBlock: SignedBlindedBeaconBlock):
node: BeaconNode, blindedBlock: bellatrix_mev.SignedBlindedBeaconBlock):
Future[Result[Opt[BlockRef], string]] {.async.} =
# By time submitBlindedBlock is called, must already have done slashing
# protection check

View File

@ -38,7 +38,7 @@ import
../gossip_processing/block_processor,
".."/[conf, beacon_clock, beacon_node],
"."/[slashing_protection, validator_pool, keystore_management],
".."/spec/mev/rest_bellatrix_mev_calls
".."/spec/mev/[rest_bellatrix_mev_calls, rest_capella_mev_calls]
from eth/async_utils import awaitWithTimeout
@ -86,7 +86,7 @@ logScope: topics = "beacval"
type
ForkedBlockResult* = Result[ForkedBeaconBlock, string]
BlindedBlockResult* = Result[BlindedBeaconBlock, string]
BlindedBlockResult* = Result[bellatrix_mev.BlindedBeaconBlock, string]
SyncStatus* {.pure.} = enum
synced
@ -749,11 +749,12 @@ proc proposeBlockMEV(
# This is only substantively asynchronous with a remote key signer
let blindedBlock = awaitWithTimeout(
getBlindedBeaconBlock[SignedBlindedBeaconBlock](
getBlindedBeaconBlock[bellatrix_mev.SignedBlindedBeaconBlock](
node, slot, validator, validator_index, forkedBlck,
executionPayloadHeader),
500.milliseconds):
Result[SignedBlindedBeaconBlock, string].err "getBlindedBlock timed out"
Result[bellatrix_mev.SignedBlindedBeaconBlock, string].err(
"getBlindedBlock timed out")
if blindedBlock.isErr:
info "proposeBlockMEV: getBlindedBeaconBlock failed",
@ -815,7 +816,7 @@ proc makeBlindedBeaconBlockForHeadAndSlot*(
return err("Unable to create blinded block")
let (executionPayloadHeader, forkedBlck) = blindedBlockParts.get
return ok constructPlainBlindedBlock[BlindedBeaconBlock](
return ok constructPlainBlindedBlock[bellatrix_mev.BlindedBeaconBlock](
forkedBlck, executionPayloadHeader)
from ../spec/datatypes/eip4844 import shortLog

View File

@ -355,7 +355,7 @@ proc getBlockSignature*(v: AttachedValidator, fork: Fork,
genesis_validators_root: Eth2Digest, slot: Slot,
block_root: Eth2Digest,
blck: ForkedBeaconBlock | ForkedBlindedBeaconBlock |
BlindedBeaconBlock
bellatrix_mev.BlindedBeaconBlock
): Future[SignatureResult] {.async.} =
return
case v.kind