initial implementation of capella MEV (#4567)
This commit is contained in:
parent
b79d267b8f
commit
ebb45e10da
|
@ -856,7 +856,8 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
||||||
of ConsensusFork.Bellatrix:
|
of ConsensusFork.Bellatrix:
|
||||||
let res =
|
let res =
|
||||||
block:
|
block:
|
||||||
let restBlock = decodeBodyJsonOrSsz(SignedBlindedBeaconBlock, body).valueOr:
|
let restBlock = decodeBodyJsonOrSsz(
|
||||||
|
bellatrix_mev.SignedBlindedBeaconBlock, body).valueOr:
|
||||||
return RestApiResponse.jsonError(Http400, InvalidBlockObjectError,
|
return RestApiResponse.jsonError(Http400, InvalidBlockObjectError,
|
||||||
$error)
|
$error)
|
||||||
await node.unblindAndRouteBlockMEV(restBlock)
|
await node.unblindAndRouteBlockMEV(restBlock)
|
||||||
|
|
|
@ -13,7 +13,7 @@ import stew/[assign2, results, base10, byteutils], presto/common,
|
||||||
import ".."/[eth2_ssz_serialization, forks, keystore],
|
import ".."/[eth2_ssz_serialization, forks, keystore],
|
||||||
".."/../consensus_object_pools/block_pools_types,
|
".."/../consensus_object_pools/block_pools_types,
|
||||||
".."/datatypes/[phase0, altair, bellatrix],
|
".."/datatypes/[phase0, altair, bellatrix],
|
||||||
".."/mev/bellatrix_mev,
|
".."/mev/[bellatrix_mev, capella_mev],
|
||||||
".."/../validators/slashing_protection_common,
|
".."/../validators/slashing_protection_common,
|
||||||
"."/[rest_types, rest_keymanager_types]
|
"."/[rest_types, rest_keymanager_types]
|
||||||
import nimcrypto/utils as ncrutils
|
import nimcrypto/utils as ncrutils
|
||||||
|
@ -85,7 +85,8 @@ type
|
||||||
PrepareBeaconProposer |
|
PrepareBeaconProposer |
|
||||||
ProposerSlashing |
|
ProposerSlashing |
|
||||||
SetFeeRecipientRequest |
|
SetFeeRecipientRequest |
|
||||||
SignedBlindedBeaconBlock |
|
bellatrix_mev.SignedBlindedBeaconBlock |
|
||||||
|
capella_mev.SignedBlindedBeaconBlock |
|
||||||
SignedValidatorRegistrationV1 |
|
SignedValidatorRegistrationV1 |
|
||||||
SignedVoluntaryExit |
|
SignedVoluntaryExit |
|
||||||
Web3SignerRequest
|
Web3SignerRequest
|
||||||
|
|
|
@ -143,7 +143,8 @@ proc publishBlindedBlock*(body: altair.SignedBeaconBlock): RestPlainResponse {.
|
||||||
meth: MethodPost.}
|
meth: MethodPost.}
|
||||||
## https://ethereum.github.io/beacon-APIs/#/Beacon/publishBlindedBlock
|
## 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",
|
rest, endpoint: "/eth/v1/beacon/blinded_blocks",
|
||||||
meth: MethodPost.}
|
meth: MethodPost.}
|
||||||
## https://ethereum.github.io/beacon-APIs/#/Beacon/publishBlindedBlock
|
## https://ethereum.github.io/beacon-APIs/#/Beacon/publishBlindedBlock
|
||||||
|
|
|
@ -18,11 +18,11 @@ import
|
||||||
stew/base10, web3/ethtypes,
|
stew/base10, web3/ethtypes,
|
||||||
".."/forks,
|
".."/forks,
|
||||||
".."/datatypes/[phase0, altair, bellatrix, eip4844],
|
".."/datatypes/[phase0, altair, bellatrix, eip4844],
|
||||||
".."/mev/bellatrix_mev
|
".."/mev/[bellatrix_mev, capella_mev]
|
||||||
|
|
||||||
from ".."/datatypes/capella import BeaconBlockBody
|
from ".."/datatypes/capella import BeaconBlockBody
|
||||||
|
|
||||||
export forks, phase0, altair, bellatrix, capella, bellatrix_mev
|
export forks, phase0, altair, bellatrix, capella, bellatrix_mev, capella_mev
|
||||||
|
|
||||||
const
|
const
|
||||||
# https://github.com/ethereum/eth2.0-APIs/blob/master/apis/beacon/states/validator_balances.yaml#L17
|
# 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]]
|
GetEpochCommitteesResponse* = DataEnclosedObject[seq[RestBeaconStatesCommittees]]
|
||||||
GetForkScheduleResponse* = DataEnclosedObject[seq[Fork]]
|
GetForkScheduleResponse* = DataEnclosedObject[seq[Fork]]
|
||||||
GetGenesisResponse* = DataEnclosedObject[RestGenesis]
|
GetGenesisResponse* = DataEnclosedObject[RestGenesis]
|
||||||
GetHeaderResponse* = DataVersionEnclosedObject[SignedBuilderBid]
|
GetHeaderResponse* = DataVersionEnclosedObject[bellatrix_mev.SignedBuilderBid]
|
||||||
GetNetworkIdentityResponse* = DataEnclosedObject[RestNetworkIdentity]
|
GetNetworkIdentityResponse* = DataEnclosedObject[RestNetworkIdentity]
|
||||||
GetPeerCountResponse* = DataMetaEnclosedObject[RestPeerCount]
|
GetPeerCountResponse* = DataMetaEnclosedObject[RestPeerCount]
|
||||||
GetPeerResponse* = DataMetaEnclosedObject[RestNodePeer]
|
GetPeerResponse* = DataMetaEnclosedObject[RestNodePeer]
|
||||||
|
@ -659,7 +659,8 @@ type
|
||||||
ProduceBlockResponseV2* = ForkedBeaconBlock
|
ProduceBlockResponseV2* = ForkedBeaconBlock
|
||||||
ProduceBlindedBlockResponse* = ForkedBlindedBeaconBlock
|
ProduceBlindedBlockResponse* = ForkedBlindedBeaconBlock
|
||||||
ProduceSyncCommitteeContributionResponse* = DataEnclosedObject[SyncCommitteeContribution]
|
ProduceSyncCommitteeContributionResponse* = DataEnclosedObject[SyncCommitteeContribution]
|
||||||
SubmitBlindedBlockResponse* = DataEnclosedObject[bellatrix.ExecutionPayload]
|
SubmitBlindedBlockResponseBellatrix* = DataEnclosedObject[bellatrix.ExecutionPayload]
|
||||||
|
SubmitBlindedBlockResponseCapella* = DataEnclosedObject[capella.ExecutionPayload]
|
||||||
GetValidatorsActivityResponse* = DataEnclosedObject[seq[RestActivityItem]]
|
GetValidatorsActivityResponse* = DataEnclosedObject[seq[RestActivityItem]]
|
||||||
GetValidatorsLivenessResponse* = DataEnclosedObject[seq[RestLivenessItem]]
|
GetValidatorsLivenessResponse* = DataEnclosedObject[seq[RestLivenessItem]]
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
)
|
|
@ -27,8 +27,8 @@ proc getHeader*(slot: Slot,
|
||||||
meth: MethodGet, connection: {Dedicated, Close}.}
|
meth: MethodGet, connection: {Dedicated, Close}.}
|
||||||
## https://github.com/ethereum/builder-specs/blob/v0.2.0/apis/builder/header.yaml
|
## https://github.com/ethereum/builder-specs/blob/v0.2.0/apis/builder/header.yaml
|
||||||
|
|
||||||
proc submitBlindedBlock*(body: SignedBlindedBeaconBlock
|
proc submitBlindedBlock*(body: bellatrix_mev.SignedBlindedBeaconBlock
|
||||||
): RestResponse[SubmitBlindedBlockResponse] {.
|
): RestResponse[SubmitBlindedBlockResponseBellatrix] {.
|
||||||
rest, endpoint: "/eth/v1/builder/blinded_blocks",
|
rest, endpoint: "/eth/v1/builder/blinded_blocks",
|
||||||
meth: MethodPost, connection: {Dedicated, Close}.}
|
meth: MethodPost, connection: {Dedicated, Close}.}
|
||||||
## https://github.com/ethereum/builder-specs/blob/v0.2.0/apis/builder/blinded_blocks.yaml
|
## https://github.com/ethereum/builder-specs/blob/v0.2.0/apis/builder/blinded_blocks.yaml
|
||||||
|
|
|
@ -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
|
|
@ -14,6 +14,7 @@ import ../beacon_node
|
||||||
from eth/async_utils import awaitWithTimeout
|
from eth/async_utils import awaitWithTimeout
|
||||||
from ../spec/datatypes/bellatrix import SignedBeaconBlock
|
from ../spec/datatypes/bellatrix import SignedBeaconBlock
|
||||||
from ../spec/mev/rest_bellatrix_mev_calls import submitBlindedBlock
|
from ../spec/mev/rest_bellatrix_mev_calls import submitBlindedBlock
|
||||||
|
from ../spec/mev/rest_capella_mev_calls import submitBlindedBlock
|
||||||
|
|
||||||
const
|
const
|
||||||
BUILDER_BLOCK_SUBMISSION_DELAY_TOLERANCE = 4.seconds
|
BUILDER_BLOCK_SUBMISSION_DELAY_TOLERANCE = 4.seconds
|
||||||
|
@ -41,7 +42,7 @@ macro copyFields*(
|
||||||
newDotExpr(dst, ident(name)), newDotExpr(src, ident(name)))
|
newDotExpr(dst, ident(name)), newDotExpr(src, ident(name)))
|
||||||
|
|
||||||
proc unblindAndRouteBlockMEV*(
|
proc unblindAndRouteBlockMEV*(
|
||||||
node: BeaconNode, blindedBlock: SignedBlindedBeaconBlock):
|
node: BeaconNode, blindedBlock: bellatrix_mev.SignedBlindedBeaconBlock):
|
||||||
Future[Result[Opt[BlockRef], string]] {.async.} =
|
Future[Result[Opt[BlockRef], string]] {.async.} =
|
||||||
# By time submitBlindedBlock is called, must already have done slashing
|
# By time submitBlindedBlock is called, must already have done slashing
|
||||||
# protection check
|
# protection check
|
||||||
|
|
|
@ -38,7 +38,7 @@ import
|
||||||
../gossip_processing/block_processor,
|
../gossip_processing/block_processor,
|
||||||
".."/[conf, beacon_clock, beacon_node],
|
".."/[conf, beacon_clock, beacon_node],
|
||||||
"."/[slashing_protection, validator_pool, keystore_management],
|
"."/[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
|
from eth/async_utils import awaitWithTimeout
|
||||||
|
|
||||||
|
@ -86,7 +86,7 @@ logScope: topics = "beacval"
|
||||||
|
|
||||||
type
|
type
|
||||||
ForkedBlockResult* = Result[ForkedBeaconBlock, string]
|
ForkedBlockResult* = Result[ForkedBeaconBlock, string]
|
||||||
BlindedBlockResult* = Result[BlindedBeaconBlock, string]
|
BlindedBlockResult* = Result[bellatrix_mev.BlindedBeaconBlock, string]
|
||||||
|
|
||||||
SyncStatus* {.pure.} = enum
|
SyncStatus* {.pure.} = enum
|
||||||
synced
|
synced
|
||||||
|
@ -749,11 +749,12 @@ proc proposeBlockMEV(
|
||||||
|
|
||||||
# This is only substantively asynchronous with a remote key signer
|
# This is only substantively asynchronous with a remote key signer
|
||||||
let blindedBlock = awaitWithTimeout(
|
let blindedBlock = awaitWithTimeout(
|
||||||
getBlindedBeaconBlock[SignedBlindedBeaconBlock](
|
getBlindedBeaconBlock[bellatrix_mev.SignedBlindedBeaconBlock](
|
||||||
node, slot, validator, validator_index, forkedBlck,
|
node, slot, validator, validator_index, forkedBlck,
|
||||||
executionPayloadHeader),
|
executionPayloadHeader),
|
||||||
500.milliseconds):
|
500.milliseconds):
|
||||||
Result[SignedBlindedBeaconBlock, string].err "getBlindedBlock timed out"
|
Result[bellatrix_mev.SignedBlindedBeaconBlock, string].err(
|
||||||
|
"getBlindedBlock timed out")
|
||||||
|
|
||||||
if blindedBlock.isErr:
|
if blindedBlock.isErr:
|
||||||
info "proposeBlockMEV: getBlindedBeaconBlock failed",
|
info "proposeBlockMEV: getBlindedBeaconBlock failed",
|
||||||
|
@ -815,7 +816,7 @@ proc makeBlindedBeaconBlockForHeadAndSlot*(
|
||||||
return err("Unable to create blinded block")
|
return err("Unable to create blinded block")
|
||||||
|
|
||||||
let (executionPayloadHeader, forkedBlck) = blindedBlockParts.get
|
let (executionPayloadHeader, forkedBlck) = blindedBlockParts.get
|
||||||
return ok constructPlainBlindedBlock[BlindedBeaconBlock](
|
return ok constructPlainBlindedBlock[bellatrix_mev.BlindedBeaconBlock](
|
||||||
forkedBlck, executionPayloadHeader)
|
forkedBlck, executionPayloadHeader)
|
||||||
|
|
||||||
from ../spec/datatypes/eip4844 import shortLog
|
from ../spec/datatypes/eip4844 import shortLog
|
||||||
|
|
|
@ -355,7 +355,7 @@ proc getBlockSignature*(v: AttachedValidator, fork: Fork,
|
||||||
genesis_validators_root: Eth2Digest, slot: Slot,
|
genesis_validators_root: Eth2Digest, slot: Slot,
|
||||||
block_root: Eth2Digest,
|
block_root: Eth2Digest,
|
||||||
blck: ForkedBeaconBlock | ForkedBlindedBeaconBlock |
|
blck: ForkedBeaconBlock | ForkedBlindedBeaconBlock |
|
||||||
BlindedBeaconBlock
|
bellatrix_mev.BlindedBeaconBlock
|
||||||
): Future[SignatureResult] {.async.} =
|
): Future[SignatureResult] {.async.} =
|
||||||
return
|
return
|
||||||
case v.kind
|
case v.kind
|
||||||
|
|
Loading…
Reference in New Issue