Local validator proposals (#5137)
* Implement local validator block proposals * Address review feedback * Fix rebase issue
This commit is contained in:
parent
ba94dc849f
commit
99264d7507
|
@ -564,6 +564,7 @@ func asConsensusType*(payload: engine_api.GetPayloadV3Response):
|
||||||
# types for KZG commitments and Blobs in the `web3` and the `deneb` spec types.
|
# types for KZG commitments and Blobs in the `web3` and the `deneb` spec types.
|
||||||
# Both are defined as `array[N, byte]` under the hood.
|
# Both are defined as `array[N, byte]` under the hood.
|
||||||
kzgs: KzgCommitments payload.blobsBundle.commitments.mapIt(it.bytes),
|
kzgs: KzgCommitments payload.blobsBundle.commitments.mapIt(it.bytes),
|
||||||
|
proofs: payload.blobsBundle.proofs.mapIt(it.bytes),
|
||||||
blobs: Blobs payload.blobsBundle.blobs.mapIt(it.bytes)
|
blobs: Blobs payload.blobsBundle.blobs.mapIt(it.bytes)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -109,6 +109,7 @@ type
|
||||||
executionPayload*: ExecutionPayload
|
executionPayload*: ExecutionPayload
|
||||||
blockValue*: Wei
|
blockValue*: Wei
|
||||||
kzgs*: KzgCommitments
|
kzgs*: KzgCommitments
|
||||||
|
proofs*:seq[KZGProof]
|
||||||
blobs*: Blobs
|
blobs*: Blobs
|
||||||
|
|
||||||
# https://github.com/ethereum/consensus-specs/blob/v1.3.0/specs/deneb/beacon-chain.md#executionpayloadheader
|
# https://github.com/ethereum/consensus-specs/blob/v1.3.0/specs/deneb/beacon-chain.md#executionpayloadheader
|
||||||
|
|
|
@ -18,12 +18,12 @@ import
|
||||||
stew/base10, web3/ethtypes,
|
stew/base10, web3/ethtypes,
|
||||||
".."/forks,
|
".."/forks,
|
||||||
".."/datatypes/[phase0, altair, bellatrix, deneb],
|
".."/datatypes/[phase0, altair, bellatrix, deneb],
|
||||||
".."/mev/[bellatrix_mev, capella_mev]
|
".."/mev/[bellatrix_mev, capella_mev, deneb_mev]
|
||||||
|
|
||||||
from ".."/datatypes/capella import BeaconBlockBody
|
from ".."/datatypes/capella import BeaconBlockBody
|
||||||
|
|
||||||
export forks, phase0, altair, bellatrix, capella, bellatrix_mev, capella_mev,
|
export forks, phase0, altair, bellatrix, capella, bellatrix_mev, capella_mev,
|
||||||
tables
|
deneb_mev, tables
|
||||||
|
|
||||||
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
|
||||||
|
@ -652,6 +652,7 @@ type
|
||||||
GetGenesisResponse* = DataEnclosedObject[RestGenesis]
|
GetGenesisResponse* = DataEnclosedObject[RestGenesis]
|
||||||
GetHeaderResponseBellatrix* = DataVersionEnclosedObject[bellatrix_mev.SignedBuilderBid]
|
GetHeaderResponseBellatrix* = DataVersionEnclosedObject[bellatrix_mev.SignedBuilderBid]
|
||||||
GetHeaderResponseCapella* = DataVersionEnclosedObject[capella_mev.SignedBuilderBid]
|
GetHeaderResponseCapella* = DataVersionEnclosedObject[capella_mev.SignedBuilderBid]
|
||||||
|
GetHeaderResponseDeneb* = DataVersionEnclosedObject[deneb_mev.SignedBuilderBid]
|
||||||
GetNetworkIdentityResponse* = DataEnclosedObject[RestNetworkIdentity]
|
GetNetworkIdentityResponse* = DataEnclosedObject[RestNetworkIdentity]
|
||||||
GetPeerCountResponse* = DataMetaEnclosedObject[RestPeerCount]
|
GetPeerCountResponse* = DataMetaEnclosedObject[RestPeerCount]
|
||||||
GetPeerResponse* = DataMetaEnclosedObject[RestNodePeer]
|
GetPeerResponse* = DataMetaEnclosedObject[RestNodePeer]
|
||||||
|
@ -680,6 +681,7 @@ type
|
||||||
ProduceSyncCommitteeContributionResponse* = DataEnclosedObject[SyncCommitteeContribution]
|
ProduceSyncCommitteeContributionResponse* = DataEnclosedObject[SyncCommitteeContribution]
|
||||||
SubmitBlindedBlockResponseBellatrix* = DataEnclosedObject[bellatrix.ExecutionPayload]
|
SubmitBlindedBlockResponseBellatrix* = DataEnclosedObject[bellatrix.ExecutionPayload]
|
||||||
SubmitBlindedBlockResponseCapella* = DataEnclosedObject[capella.ExecutionPayload]
|
SubmitBlindedBlockResponseCapella* = DataEnclosedObject[capella.ExecutionPayload]
|
||||||
|
SubmitBlindedBlockResponseDeneb* = DataEnclosedObject[deneb.ExecutionPayload]
|
||||||
GetValidatorsActivityResponse* = DataEnclosedObject[seq[RestActivityItem]]
|
GetValidatorsActivityResponse* = DataEnclosedObject[seq[RestActivityItem]]
|
||||||
GetValidatorsLivenessResponse* = DataEnclosedObject[seq[RestLivenessItem]]
|
GetValidatorsLivenessResponse* = DataEnclosedObject[seq[RestLivenessItem]]
|
||||||
|
|
||||||
|
|
|
@ -17,12 +17,12 @@ import
|
||||||
block_id, eth2_merkleization, eth2_ssz_serialization,
|
block_id, eth2_merkleization, eth2_ssz_serialization,
|
||||||
forks_light_client, presets],
|
forks_light_client, presets],
|
||||||
./datatypes/[phase0, altair, bellatrix, capella, deneb],
|
./datatypes/[phase0, altair, bellatrix, capella, deneb],
|
||||||
./mev/bellatrix_mev, ./mev/capella_mev
|
./mev/bellatrix_mev, ./mev/capella_mev, ./mev/deneb_mev
|
||||||
|
|
||||||
export
|
export
|
||||||
extras, block_id, phase0, altair, bellatrix, capella, deneb,
|
extras, block_id, phase0, altair, bellatrix, capella, deneb,
|
||||||
eth2_merkleization, eth2_ssz_serialization, forks_light_client,
|
eth2_merkleization, eth2_ssz_serialization, forks_light_client,
|
||||||
presets, bellatrix_mev, capella_mev
|
presets, bellatrix_mev, capella_mev, deneb_mev
|
||||||
|
|
||||||
# This file contains helpers for dealing with forks - we have two ways we can
|
# This file contains helpers for dealing with forks - we have two ways we can
|
||||||
# deal with forks:
|
# deal with forks:
|
||||||
|
@ -851,7 +851,8 @@ template withStateAndBlck*(
|
||||||
|
|
||||||
func toBeaconBlockHeader*(
|
func toBeaconBlockHeader*(
|
||||||
blck: SomeForkyBeaconBlock | bellatrix_mev.BlindedBeaconBlock |
|
blck: SomeForkyBeaconBlock | bellatrix_mev.BlindedBeaconBlock |
|
||||||
capella_mev.BlindedBeaconBlock): BeaconBlockHeader =
|
capella_mev.BlindedBeaconBlock | deneb_mev.BlindedBeaconBlock):
|
||||||
|
BeaconBlockHeader =
|
||||||
## Reduce a given `BeaconBlock` to its `BeaconBlockHeader`.
|
## Reduce a given `BeaconBlock` to its `BeaconBlockHeader`.
|
||||||
BeaconBlockHeader(
|
BeaconBlockHeader(
|
||||||
slot: blck.slot,
|
slot: blck.slot,
|
||||||
|
|
|
@ -0,0 +1,87 @@
|
||||||
|
# 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, deneb]
|
||||||
|
from stew/byteutils import to0xHex
|
||||||
|
|
||||||
|
{.push raises: [].}
|
||||||
|
|
||||||
|
type
|
||||||
|
# https://github.com/ethereum/builder-specs/blob/v0.3.0/specs/bellatrix/builder.md#builderbid
|
||||||
|
# https://github.com/ethereum/builder-specs/blob/v0.3.0/specs/capella/builder.md#executionpayloadheader
|
||||||
|
BuilderBid* = object
|
||||||
|
header*: deneb.ExecutionPayloadHeader
|
||||||
|
value*: UInt256
|
||||||
|
pubkey*: ValidatorPubKey
|
||||||
|
|
||||||
|
# https://github.com/ethereum/builder-specs/blob/v0.3.0/specs/bellatrix/builder.md#signedbuilderbid
|
||||||
|
# https://github.com/ethereum/builder-specs/blob/v0.3.0/specs/capella/builder.md#executionpayloadheader
|
||||||
|
SignedBuilderBid* = object
|
||||||
|
message*: BuilderBid
|
||||||
|
signature*: ValidatorSig
|
||||||
|
|
||||||
|
# https://github.com/ethereum/builder-specs/blob/v0.3.0/specs/capella/builder.md#blindedbeaconblockbody
|
||||||
|
# https://github.com/ethereum/builder-specs/blob/0b913daaa491cd889083827375977a6285e684bd/specs/deneb/builder.md#blindedbeaconblockbody
|
||||||
|
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
|
||||||
|
bls_to_execution_changes*:
|
||||||
|
List[SignedBLSToExecutionChange,
|
||||||
|
Limit MAX_BLS_TO_EXECUTION_CHANGES]
|
||||||
|
blob_kzg_commitments*: KzgCommitments # [New in Deneb]
|
||||||
|
|
||||||
|
# https://github.com/ethereum/builder-specs/blob/v0.3.0/specs/bellatrix/builder.md#blindedbeaconblock
|
||||||
|
# https://github.com/ethereum/builder-specs/blob/v0.3.0/specs/capella/builder.md#blindedbeaconblockbody
|
||||||
|
# https://github.com/ethereum/builder-specs/blob/0b913daaa491cd889083827375977a6285e684bd/specs/deneb/builder.md#blindedbeaconblockbody
|
||||||
|
BlindedBeaconBlock* = object
|
||||||
|
slot*: Slot
|
||||||
|
proposer_index*: uint64
|
||||||
|
parent_root*: Eth2Digest
|
||||||
|
state_root*: Eth2Digest
|
||||||
|
body*: BlindedBeaconBlockBody # [Modified in Deneb]
|
||||||
|
|
||||||
|
# https://github.com/ethereum/builder-specs/blob/v0.3.0/specs/bellatrix/builder.md#signedblindedbeaconblock
|
||||||
|
# https://github.com/ethereum/builder-specs/blob/v0.3.0/specs/capella/builder.md#blindedbeaconblockbody
|
||||||
|
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(),
|
||||||
|
blob_kzg_commitments_len: 0, # Deneb compat
|
||||||
|
)
|
||||||
|
|
||||||
|
func shortLog*(v: SignedBlindedBeaconBlock): auto =
|
||||||
|
(
|
||||||
|
blck: shortLog(v.message),
|
||||||
|
signature: shortLog(v.signature)
|
||||||
|
)
|
|
@ -0,0 +1,27 @@
|
||||||
|
# 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
|
||||||
|
|
||||||
|
proc getHeaderDeneb*(slot: Slot,
|
||||||
|
parent_hash: Eth2Digest,
|
||||||
|
pubkey: ValidatorPubKey
|
||||||
|
): RestResponse[GetHeaderResponseDeneb] {.
|
||||||
|
rest, endpoint: "/eth/v1/builder/header/{slot}/{parent_hash}/{pubkey}",
|
||||||
|
meth: MethodGet, connection: {Dedicated, Close}.}
|
||||||
|
## https://github.com/ethereum/builder-specs/blob/v0.3.0/apis/builder/header.yaml
|
||||||
|
|
||||||
|
proc submitBlindedBlock*(body: deneb_mev.SignedBlindedBeaconBlock
|
||||||
|
): RestResponse[SubmitBlindedBlockResponseDeneb] {.
|
||||||
|
rest, endpoint: "/eth/v1/builder/blinded_blocks",
|
||||||
|
meth: MethodPost, connection: {Dedicated, Close}.}
|
||||||
|
## https://github.com/ethereum/builder-specs/blob/v0.3.0/apis/builder/blinded_blocks.yaml
|
|
@ -369,7 +369,7 @@ proc verify_contribution_and_proof_signature*(
|
||||||
func compute_builder_signing_root(
|
func compute_builder_signing_root(
|
||||||
fork: Fork,
|
fork: Fork,
|
||||||
msg: bellatrix_mev.BuilderBid | capella_mev.BuilderBid |
|
msg: bellatrix_mev.BuilderBid | capella_mev.BuilderBid |
|
||||||
ValidatorRegistrationV1): Eth2Digest =
|
deneb_mev.BuilderBid | ValidatorRegistrationV1): Eth2Digest =
|
||||||
# Uses genesis fork version regardless
|
# Uses genesis fork version regardless
|
||||||
doAssert fork.current_version == fork.previous_version
|
doAssert fork.current_version == fork.previous_version
|
||||||
|
|
||||||
|
@ -384,7 +384,8 @@ proc get_builder_signature*(
|
||||||
blsSign(privkey, signing_root.data)
|
blsSign(privkey, signing_root.data)
|
||||||
|
|
||||||
proc verify_builder_signature*(
|
proc verify_builder_signature*(
|
||||||
fork: Fork, msg: bellatrix_mev.BuilderBid | capella_mev.BuilderBid,
|
fork: Fork, msg: bellatrix_mev.BuilderBid | capella_mev.BuilderBid |
|
||||||
|
deneb_mev.BuilderBid,
|
||||||
pubkey: ValidatorPubKey | CookedPubKey, signature: SomeSig): bool =
|
pubkey: ValidatorPubKey | CookedPubKey, signature: SomeSig): bool =
|
||||||
let signing_root = compute_builder_signing_root(fork, msg)
|
let signing_root = compute_builder_signing_root(fork, msg)
|
||||||
blsVerify(pubkey, signing_root.data, signature)
|
blsVerify(pubkey, signing_root.data, signature)
|
||||||
|
|
|
@ -192,3 +192,10 @@ proc unblindAndRouteBlockMEV*(
|
||||||
# local build process as a fallback, even in the event of some failure
|
# local build process as a fallback, even in the event of some failure
|
||||||
# with the external buildernetwork.
|
# with the external buildernetwork.
|
||||||
return err("unblindAndRouteBlockMEV error")
|
return err("unblindAndRouteBlockMEV error")
|
||||||
|
|
||||||
|
|
||||||
|
proc unblindAndRouteBlockMEV*(
|
||||||
|
node: BeaconNode, payloadBuilderRestClient: RestClientRef,
|
||||||
|
blindedBlock: deneb_mev.SignedBlindedBeaconBlock):
|
||||||
|
Future[Result[Opt[BlockRef], string]] {.async.} =
|
||||||
|
debugRaiseAssert $denebImplementationMissing & ": makeBlindedBeaconBlockForHeadAndSlot"
|
||||||
|
|
|
@ -23,6 +23,7 @@ import
|
||||||
eth/db/kvstore,
|
eth/db/kvstore,
|
||||||
eth/p2p/discoveryv5/[protocol, enr],
|
eth/p2p/discoveryv5/[protocol, enr],
|
||||||
web3/ethtypes,
|
web3/ethtypes,
|
||||||
|
kzg4844,
|
||||||
|
|
||||||
# Local modules
|
# Local modules
|
||||||
../spec/datatypes/[phase0, altair, bellatrix],
|
../spec/datatypes/[phase0, altair, bellatrix],
|
||||||
|
@ -85,8 +86,13 @@ declarePublicGauge(attached_validator_balance_total,
|
||||||
logScope: topics = "beacval"
|
logScope: topics = "beacval"
|
||||||
|
|
||||||
type
|
type
|
||||||
|
BlobsBundle = tuple[blobs: deneb.Blobs,
|
||||||
|
kzgs: KzgCommitments,
|
||||||
|
proofs: seq[kzg_abi.KZGProof]]
|
||||||
ForkedBlockResult =
|
ForkedBlockResult =
|
||||||
Result[tuple[blck: ForkedBeaconBlock, blockValue: Wei], string]
|
Result[tuple[blck: ForkedBeaconBlock,
|
||||||
|
blockValue: Wei,
|
||||||
|
blobsBundleOpt: Opt[BlobsBundle]], string]
|
||||||
BlindedBlockResult[SBBB] =
|
BlindedBlockResult[SBBB] =
|
||||||
Result[tuple[blindedBlckPart: SBBB, blockValue: UInt256], string]
|
Result[tuple[blindedBlckPart: SBBB, blockValue: UInt256], string]
|
||||||
|
|
||||||
|
@ -432,8 +438,14 @@ proc makeBeaconBlockForHeadAndSlot*(
|
||||||
slot, head = shortLog(head), error
|
slot, head = shortLog(head), error
|
||||||
$error
|
$error
|
||||||
|
|
||||||
|
var blobsBundleOpt = Opt.none(BlobsBundle)
|
||||||
|
when payload is deneb.ExecutionPayloadForSigning:
|
||||||
|
let bb: BlobsBundle = (blobs: payload.blobs,
|
||||||
|
kzgs: payload.kzgs,
|
||||||
|
proofs: payload.proofs)
|
||||||
|
blobsBundleOpt = Opt.some(bb)
|
||||||
return if blck.isOk:
|
return if blck.isOk:
|
||||||
ok((blck.get, payload.blockValue))
|
ok((blck.get, payload.blockValue, blobsBundleOpt))
|
||||||
else:
|
else:
|
||||||
err(blck.error)
|
err(blck.error)
|
||||||
|
|
||||||
|
@ -452,11 +464,16 @@ proc makeBeaconBlockForHeadAndSlot*(
|
||||||
withdrawals_root = Opt.none(Eth2Digest))
|
withdrawals_root = Opt.none(Eth2Digest))
|
||||||
|
|
||||||
proc getBlindedExecutionPayload[
|
proc getBlindedExecutionPayload[
|
||||||
EPH: bellatrix.ExecutionPayloadHeader | capella.ExecutionPayloadHeader](
|
EPH: bellatrix.ExecutionPayloadHeader | capella.ExecutionPayloadHeader |
|
||||||
|
deneb.ExecutionPayloadHeader](
|
||||||
node: BeaconNode, payloadBuilderClient: RestClientRef, slot: Slot,
|
node: BeaconNode, payloadBuilderClient: RestClientRef, slot: Slot,
|
||||||
executionBlockRoot: Eth2Digest, pubkey: ValidatorPubKey):
|
executionBlockRoot: Eth2Digest, pubkey: ValidatorPubKey):
|
||||||
Future[BlindedBlockResult[EPH]] {.async.} =
|
Future[BlindedBlockResult[EPH]] {.async.} =
|
||||||
when EPH is capella.ExecutionPayloadHeader:
|
when EPH is deneb.ExecutionPayloadHeader:
|
||||||
|
let blindedHeader = default(RestResponse[GetHeaderResponseDeneb])
|
||||||
|
debugRaiseAssert $denebImplementationMissing &
|
||||||
|
": makeBlindedBeaconBlockForHeadAndSlot"
|
||||||
|
elif EPH is capella.ExecutionPayloadHeader:
|
||||||
let blindedHeader = awaitWithTimeout(
|
let blindedHeader = awaitWithTimeout(
|
||||||
payloadBuilderClient.getHeaderCapella(slot, executionBlockRoot, pubkey),
|
payloadBuilderClient.getHeaderCapella(slot, executionBlockRoot, pubkey),
|
||||||
BUILDER_PROPOSAL_DELAY_TOLERANCE):
|
BUILDER_PROPOSAL_DELAY_TOLERANCE):
|
||||||
|
@ -558,11 +575,13 @@ proc blindedBlockCheckSlashingAndSign[T](
|
||||||
|
|
||||||
proc getUnsignedBlindedBeaconBlock[
|
proc getUnsignedBlindedBeaconBlock[
|
||||||
T: bellatrix_mev.SignedBlindedBeaconBlock |
|
T: bellatrix_mev.SignedBlindedBeaconBlock |
|
||||||
capella_mev.SignedBlindedBeaconBlock](
|
capella_mev.SignedBlindedBeaconBlock |
|
||||||
|
deneb_mev.SignedBlindedBeaconBlock](
|
||||||
node: BeaconNode, slot: Slot, validator: AttachedValidator,
|
node: BeaconNode, slot: Slot, validator: AttachedValidator,
|
||||||
validator_index: ValidatorIndex, forkedBlock: ForkedBeaconBlock,
|
validator_index: ValidatorIndex, forkedBlock: ForkedBeaconBlock,
|
||||||
executionPayloadHeader: bellatrix.ExecutionPayloadHeader |
|
executionPayloadHeader: bellatrix.ExecutionPayloadHeader |
|
||||||
capella.ExecutionPayloadHeader): Result[T, string] =
|
capella.ExecutionPayloadHeader |
|
||||||
|
deneb.ExecutionPayloadHeader): Result[T, string] =
|
||||||
withBlck(forkedBlock):
|
withBlck(forkedBlock):
|
||||||
when consensusFork >= ConsensusFork.Deneb:
|
when consensusFork >= ConsensusFork.Deneb:
|
||||||
debugRaiseAssert $denebImplementationMissing & ": getUnsignedBlindedBeaconBlock"
|
debugRaiseAssert $denebImplementationMissing & ": getUnsignedBlindedBeaconBlock"
|
||||||
|
@ -622,7 +641,8 @@ proc getBlindedBlockParts[EPH: ForkyExecutionPayloadHeader](
|
||||||
Opt.some executionPayloadHeader.get.blindedBlckPart.withdrawals_root
|
Opt.some executionPayloadHeader.get.blindedBlckPart.withdrawals_root
|
||||||
elif EPH is deneb.ExecutionPayloadHeader:
|
elif EPH is deneb.ExecutionPayloadHeader:
|
||||||
type PayloadType = deneb.ExecutionPayloadForSigning
|
type PayloadType = deneb.ExecutionPayloadForSigning
|
||||||
let withdrawals_root = Opt.some executionPayloadHeader.get.withdrawals_root
|
let withdrawals_root =
|
||||||
|
Opt.some executionPayloadHeader.get.blindedBlckPart.withdrawals_root
|
||||||
else:
|
else:
|
||||||
static: doAssert false
|
static: doAssert false
|
||||||
|
|
||||||
|
@ -656,7 +676,8 @@ proc getBlindedBlockParts[EPH: ForkyExecutionPayloadHeader](
|
||||||
|
|
||||||
proc getBuilderBid[
|
proc getBuilderBid[
|
||||||
SBBB: bellatrix_mev.SignedBlindedBeaconBlock |
|
SBBB: bellatrix_mev.SignedBlindedBeaconBlock |
|
||||||
capella_mev.SignedBlindedBeaconBlock](
|
capella_mev.SignedBlindedBeaconBlock |
|
||||||
|
deneb_mev.SignedBlindedBeaconBlock](
|
||||||
node: BeaconNode, payloadBuilderClient: RestClientRef, head: BlockRef,
|
node: BeaconNode, payloadBuilderClient: RestClientRef, head: BlockRef,
|
||||||
validator: AttachedValidator, slot: Slot, randao: ValidatorSig,
|
validator: AttachedValidator, slot: Slot, randao: ValidatorSig,
|
||||||
validator_index: ValidatorIndex):
|
validator_index: ValidatorIndex):
|
||||||
|
@ -667,6 +688,8 @@ proc getBuilderBid[
|
||||||
type EPH = bellatrix.ExecutionPayloadHeader
|
type EPH = bellatrix.ExecutionPayloadHeader
|
||||||
elif SBBB is capella_mev.SignedBlindedBeaconBlock:
|
elif SBBB is capella_mev.SignedBlindedBeaconBlock:
|
||||||
type EPH = capella.ExecutionPayloadHeader
|
type EPH = capella.ExecutionPayloadHeader
|
||||||
|
elif SBBB is deneb_mev.SignedBlindedBeaconBlock:
|
||||||
|
type EPH = deneb.ExecutionPayloadHeader
|
||||||
else:
|
else:
|
||||||
static: doAssert false
|
static: doAssert false
|
||||||
|
|
||||||
|
@ -784,13 +807,6 @@ proc makeBlindedBeaconBlockForHeadAndSlot*[
|
||||||
else:
|
else:
|
||||||
return err("Attempt to create pre-Bellatrix blinded block")
|
return err("Attempt to create pre-Bellatrix blinded block")
|
||||||
|
|
||||||
# TODO remove BlobsSidecar; it's not in consensus specs anymore
|
|
||||||
type BlobsSidecar = object
|
|
||||||
beacon_block_root*: Eth2Digest
|
|
||||||
beacon_block_slot*: Slot
|
|
||||||
blobs*: Blobs
|
|
||||||
kzg_aggregated_proof*: kzg_abi.KzgProof
|
|
||||||
|
|
||||||
proc proposeBlockAux(
|
proc proposeBlockAux(
|
||||||
SBBB: typedesc, EPS: typedesc, node: BeaconNode,
|
SBBB: typedesc, EPS: typedesc, node: BeaconNode,
|
||||||
validator: AttachedValidator, validator_index: ValidatorIndex,
|
validator: AttachedValidator, validator_index: ValidatorIndex,
|
||||||
|
@ -920,17 +936,6 @@ proc proposeBlockAux(
|
||||||
var forkedBlck = engineBlockFut.read.get().blck
|
var forkedBlck = engineBlockFut.read.get().blck
|
||||||
|
|
||||||
withBlck(forkedBlck):
|
withBlck(forkedBlck):
|
||||||
var blobs_sidecar = BlobsSidecar(
|
|
||||||
beacon_block_slot: slot,
|
|
||||||
)
|
|
||||||
when blck is deneb.BeaconBlock:
|
|
||||||
# TODO: The blobs_sidecar variable is not currently used.
|
|
||||||
# It could be initialized in makeBeaconBlockForHeadAndSlot
|
|
||||||
# where the required information is available.
|
|
||||||
# blobs_sidecar.blobs = forkedBlck.blobs
|
|
||||||
# blobs_sidecar.kzg_aggregated_proof = kzg_aggregated_proof
|
|
||||||
discard
|
|
||||||
|
|
||||||
let
|
let
|
||||||
blockRoot = hash_tree_root(blck)
|
blockRoot = hash_tree_root(blck)
|
||||||
signingRoot = compute_block_signing_root(
|
signingRoot = compute_block_signing_root(
|
||||||
|
@ -940,7 +945,30 @@ proc proposeBlockAux(
|
||||||
.slashingProtection
|
.slashingProtection
|
||||||
.registerBlock(validator_index, validator.pubkey, slot, signingRoot)
|
.registerBlock(validator_index, validator.pubkey, slot, signingRoot)
|
||||||
|
|
||||||
blobs_sidecar.beacon_block_root = blockRoot
|
let blobSidecarsOpt =
|
||||||
|
when blck is deneb.BeaconBlock:
|
||||||
|
var sidecars: seq[BlobSidecar]
|
||||||
|
let bundle = engineBlockFut.read.get().blobsBundleOpt.get()
|
||||||
|
let (blobs, kzgs, proofs) = (bundle.blobs, bundle.kzgs, bundle.proofs)
|
||||||
|
for i in 0..<blobs.len:
|
||||||
|
var sidecar = BlobSidecar(
|
||||||
|
block_root: blockRoot,
|
||||||
|
index: BlobIndex(i),
|
||||||
|
slot: slot,
|
||||||
|
block_parent_root: blck.parent_root,
|
||||||
|
proposer_index: blck.proposer_index,
|
||||||
|
blob: blobs[i],
|
||||||
|
kzg_commitment: kzgs[i],
|
||||||
|
kzg_proof: proofs[i]
|
||||||
|
)
|
||||||
|
sidecars.add(sidecar)
|
||||||
|
Opt.some(sidecars)
|
||||||
|
elif blck is phase0.BeaconBlock or blck is altair.BeaconBlock or
|
||||||
|
blck is bellatrix.BeaconBlock or blck is capella.BeaconBlock:
|
||||||
|
Opt.none(seq[BlobSidecar])
|
||||||
|
else:
|
||||||
|
static: doAssert "Unknown BeaconBlock type"
|
||||||
|
|
||||||
if notSlashable.isErr:
|
if notSlashable.isErr:
|
||||||
warn "Slashing protection activated for block proposal",
|
warn "Slashing protection activated for block proposal",
|
||||||
blockRoot = shortLog(blockRoot), blck = shortLog(blck),
|
blockRoot = shortLog(blockRoot), blck = shortLog(blck),
|
||||||
|
@ -974,12 +1002,34 @@ proc proposeBlockAux(
|
||||||
capella.SignedBeaconBlock(
|
capella.SignedBeaconBlock(
|
||||||
message: blck, signature: signature, root: blockRoot)
|
message: blck, signature: signature, root: blockRoot)
|
||||||
elif blck is deneb.BeaconBlock:
|
elif blck is deneb.BeaconBlock:
|
||||||
# TODO: also route blobs
|
deneb.SignedBeaconBlock(
|
||||||
deneb.SignedBeaconBlock(message: blck, signature: signature, root: blockRoot)
|
message: blck, signature: signature, root: blockRoot)
|
||||||
else:
|
else:
|
||||||
static: doAssert "Unknown SignedBeaconBlock type"
|
static: doAssert "Unknown SignedBeaconBlock type"
|
||||||
newBlockRef = (await node.router.routeSignedBeaconBlock(
|
signedBlobs =
|
||||||
signedBlock, Opt.none(SignedBlobSidecars))).valueOr:
|
when blck is phase0.BeaconBlock or blck is altair.BeaconBlock or
|
||||||
|
blck is bellatrix.BeaconBlock or blck is capella.BeaconBlock:
|
||||||
|
Opt.none(SignedBlobSidecars)
|
||||||
|
elif blck is deneb.BeaconBlock:
|
||||||
|
var signed: seq[SignedBlobSidecar]
|
||||||
|
let blobSidecars = blobSidecarsOpt.get()
|
||||||
|
for i in 0..<blobs.len:
|
||||||
|
let res = validator.getBlobSignature(fork, genesis_validators_root,
|
||||||
|
slot, blobSidecars[i])
|
||||||
|
if res.isErr():
|
||||||
|
warn "Unable to sign blob",
|
||||||
|
reason = res.error()
|
||||||
|
return
|
||||||
|
let signature = res.get()
|
||||||
|
signed.add(deneb.SignedBlobSidecar(
|
||||||
|
message: blobSidecars[i],
|
||||||
|
signature: signature))
|
||||||
|
Opt.some(signed)
|
||||||
|
else:
|
||||||
|
static: doAssert "Unknown SignedBeaconBlock type"
|
||||||
|
|
||||||
|
newBlockRef =
|
||||||
|
(await node.router.routeSignedBeaconBlock(signedBlock, signedBlobs)).valueOr:
|
||||||
return head # Errors logged in router
|
return head # Errors logged in router
|
||||||
|
|
||||||
if newBlockRef.isNone():
|
if newBlockRef.isNone():
|
||||||
|
@ -1028,7 +1078,7 @@ proc proposeBlock(node: BeaconNode,
|
||||||
if slot.epoch >= node.dag.cfg.DENEB_FORK_EPOCH:
|
if slot.epoch >= node.dag.cfg.DENEB_FORK_EPOCH:
|
||||||
debugRaiseAssert $denebImplementationMissing & ": proposeBlock"
|
debugRaiseAssert $denebImplementationMissing & ": proposeBlock"
|
||||||
proposeBlockContinuation(
|
proposeBlockContinuation(
|
||||||
capella_mev.SignedBlindedBeaconBlock, deneb.ExecutionPayloadForSigning)
|
deneb_mev.SignedBlindedBeaconBlock, deneb.ExecutionPayloadForSigning)
|
||||||
elif slot.epoch >= node.dag.cfg.CAPELLA_FORK_EPOCH:
|
elif slot.epoch >= node.dag.cfg.CAPELLA_FORK_EPOCH:
|
||||||
proposeBlockContinuation(
|
proposeBlockContinuation(
|
||||||
capella_mev.SignedBlindedBeaconBlock, capella.ExecutionPayloadForSigning)
|
capella_mev.SignedBlindedBeaconBlock, capella.ExecutionPayloadForSigning)
|
||||||
|
|
|
@ -435,14 +435,16 @@ proc getBlockSignature*(v: AttachedValidator, fork: Fork,
|
||||||
block_root: Eth2Digest,
|
block_root: Eth2Digest,
|
||||||
blck: ForkedBeaconBlock | ForkedBlindedBeaconBlock |
|
blck: ForkedBeaconBlock | ForkedBlindedBeaconBlock |
|
||||||
bellatrix_mev.BlindedBeaconBlock |
|
bellatrix_mev.BlindedBeaconBlock |
|
||||||
capella_mev.BlindedBeaconBlock
|
capella_mev.BlindedBeaconBlock |
|
||||||
|
deneb_mev.BlindedBeaconBlock
|
||||||
): Future[SignatureResult] {.async.} =
|
): Future[SignatureResult] {.async.} =
|
||||||
type SomeBlockBody =
|
type SomeBlockBody =
|
||||||
bellatrix.BeaconBlockBody |
|
bellatrix.BeaconBlockBody |
|
||||||
capella.BeaconBlockBody |
|
capella.BeaconBlockBody |
|
||||||
deneb.BeaconBlockBody |
|
deneb.BeaconBlockBody |
|
||||||
bellatrix_mev.BlindedBeaconBlockBody |
|
bellatrix_mev.BlindedBeaconBlockBody |
|
||||||
capella_mev.BlindedBeaconBlockBody
|
capella_mev.BlindedBeaconBlockBody |
|
||||||
|
deneb_mev.BlindedBeaconBlockBody
|
||||||
|
|
||||||
template blockPropertiesProofs(blockBody: SomeBlockBody,
|
template blockPropertiesProofs(blockBody: SomeBlockBody,
|
||||||
forkIndexField: untyped): seq[Web3SignerMerkleProof] =
|
forkIndexField: untyped): seq[Web3SignerMerkleProof] =
|
||||||
|
@ -538,9 +540,20 @@ proc getBlockSignature*(v: AttachedValidator, fork: Fork,
|
||||||
Web3SignerForkedBeaconBlock(kind: ConsensusFork.Capella,
|
Web3SignerForkedBeaconBlock(kind: ConsensusFork.Capella,
|
||||||
data: blck.toBeaconBlockHeader),
|
data: blck.toBeaconBlockHeader),
|
||||||
proofs)
|
proofs)
|
||||||
|
elif blck is deneb_mev.BlindedBeaconBlock:
|
||||||
|
case v.data.remoteType
|
||||||
|
of RemoteSignerType.Web3Signer:
|
||||||
|
Web3SignerRequest.init(fork, genesis_validators_root,
|
||||||
|
Web3SignerForkedBeaconBlock(kind: ConsensusFork.Deneb,
|
||||||
|
data: blck.toBeaconBlockHeader))
|
||||||
|
of RemoteSignerType.VerifyingWeb3Signer:
|
||||||
|
let proofs = blockPropertiesProofs(
|
||||||
|
blck.body, denebIndex)
|
||||||
|
Web3SignerRequest.init(fork, genesis_validators_root,
|
||||||
|
Web3SignerForkedBeaconBlock(kind: ConsensusFork.Deneb,
|
||||||
|
data: blck.toBeaconBlockHeader),
|
||||||
|
proofs)
|
||||||
else:
|
else:
|
||||||
# There should be a deneb_mev module just like the ones above
|
|
||||||
discard denebImplementationMissing
|
|
||||||
case blck.kind
|
case blck.kind
|
||||||
of ConsensusFork.Phase0, ConsensusFork.Altair:
|
of ConsensusFork.Phase0, ConsensusFork.Altair:
|
||||||
return SignatureResult.err("Invalid beacon block fork version")
|
return SignatureResult.err("Invalid beacon block fork version")
|
||||||
|
|
Loading…
Reference in New Issue