Types and scaffolding for EIP-4844 (#4365)

* Types and scaffolding for EIP-4844

This commit adds the EIP-4844 spec types, and fills in
scaffolding/boilerplate for the use of these types across the repo.

None of the actual EIP-4844 logic is introduced yet.

This follows the pattern used by @tersec when introducing Capella (#4276).

* use eth2-networks fork

* review feedback: add static check EIP4844_FORK_EPOCH == FAR_FUTURE_EPOCH

* review feedback: remove EIP4844 from /eth/v1/config/spec response

* Cleanup / review feedback

* Fix REST test
This commit is contained in:
henridf 2022-12-05 17:29:09 +01:00 committed by GitHub
parent 7e5f40e04c
commit f0329b2212
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 499 additions and 29 deletions

View File

@ -21,6 +21,7 @@ import
"."/[beacon_chain_db_light_client, filepath]
from ./spec/datatypes/capella import BeaconState
from ./spec/datatypes/eip4844 import TrustedSignedBeaconBlock
export
phase0, altair, eth2_ssz_serialization, eth2_merkleization, kvstore,
@ -487,7 +488,8 @@ proc new*(T: type BeaconChainDB,
kvStore db.openKvStore("blocks").expectDb(),
kvStore db.openKvStore("altair_blocks").expectDb(),
kvStore db.openKvStore("bellatrix_blocks").expectDb(),
kvStore db.openKvStore("capella_blocks").expectDb()]
kvStore db.openKvStore("capella_blocks").expectDb(),
kvStore db.openKvStore("eip4844_blocks").expectDb()]
stateRoots = kvStore db.openKvStore("state_roots", true).expectDb()
@ -884,7 +886,7 @@ proc getBlock*(
result.err()
proc getBlock*[
X: bellatrix.TrustedSignedBeaconBlock | capella.TrustedSignedBeaconBlock](
X: bellatrix.TrustedSignedBeaconBlock | capella.TrustedSignedBeaconBlock | eip4844.TrustedSignedBeaconBlock](
db: BeaconChainDB, key: Eth2Digest,
T: type X): Opt[T] =
# We only store blocks that we trust in the database
@ -960,6 +962,9 @@ proc getBlockSSZ*(
getBlockSSZ(db, key, data, bellatrix.TrustedSignedBeaconBlock)
of BeaconBlockFork.Capella:
getBlockSSZ(db, key, data, capella.TrustedSignedBeaconBlock)
of BeaconBlockFork.EIP4844:
raiseAssert $eip4844ImplementationMissing
proc getBlockSZ*(
db: BeaconChainDB, key: Eth2Digest, data: var seq[byte],
@ -1005,6 +1010,9 @@ proc getBlockSZ*(
getBlockSZ(db, key, data, bellatrix.TrustedSignedBeaconBlock)
of BeaconBlockFork.Capella:
getBlockSZ(db, key, data, capella.TrustedSignedBeaconBlock)
of BeaconBlockFork.EIP4844:
raiseAssert $eip4844ImplementationMissing
proc getStateOnlyMutableValidators(
immutableValidators: openArray[ImmutableValidatorData2],
@ -1244,7 +1252,7 @@ proc containsBlock*(db: BeaconChainDB, key: Eth2Digest, fork: BeaconBlockFork):
else: db.blocks[fork].contains(key.data).expectDb()
proc containsBlock*(db: BeaconChainDB, key: Eth2Digest): bool =
static: doAssert high(BeaconBlockFork) == BeaconBlockFork.Capella
static: doAssert high(BeaconBlockFork) == BeaconBlockFork.EIP4844
db.containsBlock(key, capella.TrustedSignedBeaconBlock) or
db.containsBlock(key, bellatrix.TrustedSignedBeaconBlock) or
db.containsBlock(key, altair.TrustedSignedBeaconBlock) or

View File

@ -16,11 +16,11 @@ import
metrics, snappy, chronicles,
../spec/[beaconstate, eth2_merkleization, eth2_ssz_serialization, helpers,
state_transition, validator],
../spec/datatypes/[phase0, altair, bellatrix],
../spec/datatypes/[phase0, altair, bellatrix, capella],
".."/[beacon_chain_db, era_db],
"."/[block_pools_types, block_quarantine]
from ../spec/datatypes/capella import shortLog
from ../spec/datatypes/eip4844 import shortLog
export
eth2_merkleization, eth2_ssz_serialization,
@ -859,6 +859,12 @@ proc applyBlock(
state_transition(
dag.cfg, state, data, cache, info,
dag.updateFlags + {slotProcessed}, noRollback)
of BeaconBlockFork.EIP4844:
let data = getBlock(dag, bid, eip4844.TrustedSignedBeaconBlock).valueOr:
return err("Block load failed")
state_transition(
dag.cfg, state, data, cache, info,
dag.updateFlags + {slotProcessed}, noRollback)
proc init*(T: type ChainDAGRef, cfg: RuntimeConfig, db: BeaconChainDB,
validatorMonitor: ref ValidatorMonitor, updateFlags: UpdateFlags,

View File

@ -272,6 +272,8 @@ proc installConfigApiHandlers*(router: var RestRouter, node: BeaconNode) =
"/eth/v1/config/spec") do () -> RestApiResponse:
return RestApiResponse.response(cachedConfigSpec, Http200,
"application/json")
# EIP4844_FORK_EPOCH and EIP4844_FORK_VERSION not yet in config
discard $eip4844ImplementationMissing
# https://ethereum.github.io/beacon-APIs/#/Config/getDepositContract
router.api(MethodGet,

View File

@ -290,7 +290,7 @@ proc getBlockOptimistic*(node: BeaconNode,
case blck.kind
of BeaconBlockFork.Phase0, BeaconBlockFork.Altair:
some[bool](false)
of BeaconBlockFork.Bellatrix, BeaconBlockFork.Capella:
of BeaconBlockFork.Bellatrix, BeaconBlockFork.Capella, BeaconBlockFork.EIP4844:
some[bool](node.dag.is_optimistic(blck.root))
else:
none[bool]()
@ -302,6 +302,9 @@ proc getBlockRefOptimistic*(node: BeaconNode, blck: BlockRef): bool =
false
of BeaconBlockFork.Bellatrix, BeaconBlockFork.Capella:
node.dag.is_optimistic(blck.root)
of BeaconBlockFork.EIP4844:
if true: raiseAssert $eip4844ImplementationMissing
true
const
jsonMediaType* = MediaType.init("application/json")

View File

@ -953,11 +953,14 @@ func clear*(cache: var StateCache) =
cache.sync_committees.clear
func checkForkConsistency*(cfg: RuntimeConfig) =
doAssert cfg.EIP4844_FORK_EPOCH == FAR_FUTURE_EPOCH
doAssert cfg.SHARDING_FORK_EPOCH == FAR_FUTURE_EPOCH
let forkVersions =
[cfg.GENESIS_FORK_VERSION, cfg.ALTAIR_FORK_VERSION,
cfg.BELLATRIX_FORK_VERSION, cfg.CAPELLA_FORK_VERSION]
cfg.BELLATRIX_FORK_VERSION, cfg.CAPELLA_FORK_VERSION,
cfg.EIP4844_FORK_VERSION]
for i in 0 ..< forkVersions.len:
for j in i+1 ..< forkVersions.len:
doAssert distinctBase(forkVersions[i]) != distinctBase(forkVersions[j])
@ -973,9 +976,12 @@ func checkForkConsistency*(cfg: RuntimeConfig) =
assertForkEpochOrder(cfg.ALTAIR_FORK_EPOCH, cfg.BELLATRIX_FORK_EPOCH)
assertForkEpochOrder(cfg.BELLATRIX_FORK_EPOCH, cfg.CAPELLA_FORK_EPOCH)
assertForkEpochOrder(cfg.CAPELLA_FORK_EPOCH, cfg.EIP4844_FORK_EPOCH)
# This is a readily/uniquely searchable token of where a false assertion is
# due to Capella implementation missing. checkForkConsistency() checks that
# Nimbus does not actually run any non-FAR_FUTURE_EPOCH Capella network, so
# such cases won't be hit.
const capellaImplementationMissing* = false
const eip4844ImplementationMissing* = false

View File

@ -0,0 +1,315 @@
# beacon_chain
# Copyright (c) 2022 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.
# Types specific to capella (ie known to have changed across hard forks) - see
# `base` for types and guidelines common across forks
# TODO Careful, not nil analysis is broken / incomplete and the semantics will
# likely change in future versions of the language:
# https://github.com/nim-lang/RFCs/issues/250
{.experimental: "notnil".}
when (NimMajor, NimMinor) < (1, 4):
{.push raises: [Defect].}
else:
{.push raises: [].}
import
json_serialization,
ssz_serialization/types as sszTypes,
../digest,
"."/[base, phase0, altair, bellatrix, capella]
export json_serialization, base
type
# this block belongs elsewhere - will figure out after implementing c-kzg bindings
KZGCommitment* = array[48, byte]
KZGProof* = array[48, byte]
BLSFieldElement* = array[32, byte]
Blob* = List[BLSFieldElement, Limit FIELD_ELEMENTS_PER_BLOB]
BlobsSideCar* = object
beacon_block_root*: Eth2Digest
beacon_block_slot*: Slot
blobs*: List[Blob, Limit MAX_BLOBS_PER_BLOCK]
kzg_aggregated_proof*: KZGProof
SignedBeaconBlockAndBlobsSidecar* = object
beacon_block*: SignedBeaconBlock
blobs_sidecar*: BlobsSidecar
# https://github.com/ethereum/consensus-specs/blob/v1.3.0-alpha.0/specs/eip4844/beacon-chain.md#executionpayload
ExecutionPayload* = object
parent_hash*: Eth2Digest
fee_recipient*: ExecutionAddress # 'beneficiary' in the yellow paper
state_root*: Eth2Digest
receipts_root*: Eth2Digest # 'receipts root' in the yellow paper
logs_bloom*: BloomLogs
prev_randao*: Eth2Digest # 'difficulty' in the yellow paper
block_number*: uint64 # 'number' in the yellow paper
gas_limit*: uint64
gas_used*: uint64
timestamp*: uint64
extra_data*: List[byte, MAX_EXTRA_DATA_BYTES]
base_fee_per_gas*: UInt256
excess_data_gas*: UInt256 # [New in EIP-4844]
# Extra payload fields
block_hash*: Eth2Digest # Hash of execution block
transactions*: List[Transaction, MAX_TRANSACTIONS_PER_PAYLOAD]
withdrawals*: List[Withdrawal, MAX_WITHDRAWALS_PER_PAYLOAD]
# https://github.com/ethereum/consensus-specs/blob/v1.3.0-alpha.0/specs/eip4844/beacon-chain.md#executionpayloadheader
ExecutionPayloadHeader* = object
parent_hash*: Eth2Digest
fee_recipient*: ExecutionAddress
state_root*: Eth2Digest
receipts_root*: Eth2Digest
logs_bloom*: BloomLogs
prev_randao*: Eth2Digest
block_number*: uint64
gas_limit*: uint64
gas_used*: uint64
timestamp*: uint64
extra_data*: List[byte, MAX_EXTRA_DATA_BYTES]
base_fee_per_gas*: UInt256
excess_data_gas*: UInt256 # [New in EIP-4844]
# Extra payload fields
block_hash*: Eth2Digest # Hash of execution block
transactions_root*: Eth2Digest
withdrawals_root*: Eth2Digest
ExecutePayload* = proc(
execution_payload: ExecutionPayload): bool {.gcsafe, raises: [Defect].}
# https://github.com/ethereum/consensus-specs/blob/v1.3.0-alpha.0/specs/phase0/beacon-chain.md#beaconblock
BeaconBlock* = object
## For each slot, a proposer is chosen from the validator pool to propose
## a new block. Once the block as been proposed, it is transmitted to
## validators that will have a chance to vote on it through attestations.
## Each block collects attestations, or votes, on past blocks, thus a chain
## is formed.
slot*: Slot
proposer_index*: uint64 # `ValidatorIndex` after validation
parent_root*: Eth2Digest
## Root hash of the previous block
state_root*: Eth2Digest
## The state root, _after_ this block has been processed
body*: BeaconBlockBody
SigVerifiedBeaconBlock* = object
## A BeaconBlock that contains verified signatures
## but that has not been verified for state transition
slot*: Slot
proposer_index*: uint64 # `ValidatorIndex` after validation
parent_root*: Eth2Digest
## Root hash of the previous block
state_root*: Eth2Digest
## The state root, _after_ this block has been processed
body*: SigVerifiedBeaconBlockBody
TrustedBeaconBlock* = object
## When we receive blocks from outside sources, they are untrusted and go
## through several layers of validation. Blocks that have gone through
## validations can be trusted to be well-formed, with a correct signature,
## having a parent and applying cleanly to the state that their parent
## left them with.
##
## When loading such blocks from the database, to rewind states for example,
## it is expensive to redo the validations (in particular, the signature
## checks), thus `TrustedBlock` uses a `TrustedSig` type to mark that these
## checks can be skipped.
##
## TODO this could probably be solved with some type trickery, but there
## too many bugs in nim around generics handling, and we've used up
## the trickery budget in the serialization library already. Until
## then, the type must be manually kept compatible with its untrusted
## cousin.
slot*: Slot
proposer_index*: uint64 # `ValidatorIndex` after validation
parent_root*: Eth2Digest
state_root*: Eth2Digest
body*: TrustedBeaconBlockBody
# https://github.com/ethereum/consensus-specs/blob/v1.3.0-alpha.0/specs/capella/beacon-chain.md#beaconblockbody
BeaconBlockBody* = object
randao_reveal*: ValidatorSig
eth1_data*: Eth1Data
## Eth1 data vote
graffiti*: GraffitiBytes
## Arbitrary data
# Operations
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
execution_payload*: ExecutionPayload
# Capella operations
bls_to_execution_changes*: SignedBLSToExecutionChangeList
SigVerifiedBeaconBlockBody* = object
## A BeaconBlock body with signatures verified
## including:
## - Randao reveal
## - Attestations
## - ProposerSlashing (SignedBeaconBlockHeader)
## - AttesterSlashing (IndexedAttestation)
## - SignedVoluntaryExits
## - SyncAggregate
##
## However:
## - ETH1Data (Deposits) can contain invalid BLS signatures
##
## The block state transition has NOT been verified
randao_reveal*: TrustedSig
eth1_data*: Eth1Data
## Eth1 data vote
graffiti*: GraffitiBytes
## Arbitrary data
# Operations
proposer_slashings*: List[TrustedProposerSlashing, Limit MAX_PROPOSER_SLASHINGS]
attester_slashings*: List[TrustedAttesterSlashing, Limit MAX_ATTESTER_SLASHINGS]
attestations*: List[TrustedAttestation, Limit MAX_ATTESTATIONS]
deposits*: List[Deposit, Limit MAX_DEPOSITS]
voluntary_exits*: List[TrustedSignedVoluntaryExit, Limit MAX_VOLUNTARY_EXITS]
sync_aggregate*: TrustedSyncAggregate
# Execution
execution_payload*: ExecutionPayload
# Capella operations
bls_to_execution_changes*: SignedBLSToExecutionChangeList
TrustedBeaconBlockBody* = object
## A full verified block
randao_reveal*: TrustedSig
eth1_data*: Eth1Data
## Eth1 data vote
graffiti*: GraffitiBytes
## Arbitrary data
# Operations
proposer_slashings*: List[TrustedProposerSlashing, Limit MAX_PROPOSER_SLASHINGS]
attester_slashings*: List[TrustedAttesterSlashing, Limit MAX_ATTESTER_SLASHINGS]
attestations*: List[TrustedAttestation, Limit MAX_ATTESTATIONS]
deposits*: List[Deposit, Limit MAX_DEPOSITS]
voluntary_exits*: List[TrustedSignedVoluntaryExit, Limit MAX_VOLUNTARY_EXITS]
sync_aggregate*: TrustedSyncAggregate
# Execution
execution_payload*: ExecutionPayload
# Capella operations
bls_to_execution_changes*: SignedBLSToExecutionChangeList
# https://github.com/ethereum/consensus-specs/blob/v1.3.0-alpha.0/specs/phase0/beacon-chain.md#signedbeaconblock
SignedBeaconBlock* = object
message*: BeaconBlock
signature*: ValidatorSig
root* {.dontSerialize.}: Eth2Digest # cached root of signed beacon block
SigVerifiedSignedBeaconBlock* = object
## A SignedBeaconBlock with signatures verified
## including:
## - Block signature
## - BeaconBlockBody
## - Randao reveal
## - Attestations
## - ProposerSlashing (SignedBeaconBlockHeader)
## - AttesterSlashing (IndexedAttestation)
## - SignedVoluntaryExits
##
## - ETH1Data (Deposits) can contain invalid BLS signatures
##
## The block state transition has NOT been verified
message*: SigVerifiedBeaconBlock
signature*: TrustedSig
root* {.dontSerialize.}: Eth2Digest # cached root of signed beacon block
MsgTrustedSignedBeaconBlock* = object
message*: TrustedBeaconBlock
signature*: ValidatorSig
root* {.dontSerialize.}: Eth2Digest # cached root of signed beacon block
TrustedSignedBeaconBlock* = object
message*: TrustedBeaconBlock
signature*: TrustedSig
root* {.dontSerialize.}: Eth2Digest # cached root of signed beacon block
SomeSignedBeaconBlock* =
SignedBeaconBlock |
SigVerifiedSignedBeaconBlock |
MsgTrustedSignedBeaconBlock |
TrustedSignedBeaconBlock
SomeBeaconBlock* =
BeaconBlock |
SigVerifiedBeaconBlock |
TrustedBeaconBlock
SomeBeaconBlockBody* =
BeaconBlockBody |
SigVerifiedBeaconBlockBody |
TrustedBeaconBlockBody
BlockParams = object
parentHash*: string
timestamp*: string
template asSigned*(
x: SigVerifiedSignedBeaconBlock |
MsgTrustedSignedBeaconBlock |
TrustedSignedBeaconBlock): SignedBeaconBlock =
isomorphicCast[SignedBeaconBlock](x)
template asSigVerified*(
x: SignedBeaconBlock |
MsgTrustedSignedBeaconBlock |
TrustedSignedBeaconBlock): SigVerifiedSignedBeaconBlock =
isomorphicCast[SigVerifiedSignedBeaconBlock](x)
template asSigVerified*(
x: BeaconBlock | TrustedBeaconBlock): SigVerifiedBeaconBlock =
isomorphicCast[SigVerifiedBeaconBlock](x)
template asMsgTrusted*(
x: SignedBeaconBlock |
SigVerifiedSignedBeaconBlock |
TrustedSignedBeaconBlock): MsgTrustedSignedBeaconBlock =
isomorphicCast[MsgTrustedSignedBeaconBlock](x)
template asTrusted*(
x: SignedBeaconBlock |
SigVerifiedSignedBeaconBlock |
MsgTrustedSignedBeaconBlock): TrustedSignedBeaconBlock =
isomorphicCast[TrustedSignedBeaconBlock](x)

View File

@ -979,6 +979,8 @@ proc readValue*[BlockType: ForkedBeaconBlock](
if res.isNone():
reader.raiseUnexpectedValue("Incorrect capella block format")
value = ForkedBeaconBlock.init(res.get()).BlockType
of BeaconBlockFork.EIP4844:
reader.raiseUnexpectedValue($eip4844ImplementationMissing)
proc readValue*[BlockType: ForkedBlindedBeaconBlock](
reader: var JsonReader[RestJson],
@ -1031,6 +1033,9 @@ proc readValue*[BlockType: ForkedBlindedBeaconBlock](
of BeaconBlockFork.Capella:
reader.raiseUnexpectedValue($capellaImplementationMissing)
of BeaconBlockFork.EIP4844:
reader.raiseUnexpectedValue($eip4844ImplementationMissing)
proc readValue*[BlockType: Web3SignerForkedBeaconBlock](
reader: var JsonReader[RestJson],
value: var BlockType) {.raises: [IOError, SerializationError, Defect].} =
@ -1098,6 +1103,9 @@ proc readValue*[BlockType: Web3SignerForkedBeaconBlock](
value = Web3SignerForkedBeaconBlock(
kind: BeaconBlockFork.Capella,
capellaData: res.get())
of BeaconBlockFork.EIP4844:
reader.raiseUnexpectedValue($eip4844ImplementationMissing)
proc writeValue*[
BlockType: Web3SignerForkedBeaconBlock|ForkedBeaconBlock|ForkedBlindedBeaconBlock](
@ -1124,6 +1132,8 @@ proc writeValue*[
of BeaconBlockFork.Capella:
writer.writeField("version", forkIdentifier "capella")
writer.writeField("data", value.capellaData)
of BeaconBlockFork.EIP4844:
raiseAssert $eip4844ImplementationMissing
writer.endRecord()
## RestPublishedBeaconBlockBody
@ -1280,6 +1290,8 @@ proc readValue*(reader: var JsonReader[RestJson],
)
of BeaconBlockFork.Capella:
reader.raiseUnexpectedValue($capellaImplementationMissing)
of BeaconBlockFork.EIP4844:
reader.raiseUnexpectedValue($eip4844ImplementationMissing)
## RestPublishedBeaconBlock
proc readValue*(reader: var JsonReader[RestJson],
@ -1376,6 +1388,8 @@ proc readValue*(reader: var JsonReader[RestJson],
body: body.capellaBody
)
)
of BeaconBlockFork.EIP4844:
reader.raiseUnexpectedValue($eip4844ImplementationMissing)
)
## RestPublishedSignedBeaconBlock
@ -1435,6 +1449,8 @@ proc readValue*(reader: var JsonReader[RestJson],
signature: signature.get()
)
)
of BeaconBlockFork.EIP4844:
reader.raiseUnexpectedValue($eip4844ImplementationMissing)
)
## ForkedSignedBeaconBlock
@ -1525,6 +1541,8 @@ proc readValue*(reader: var JsonReader[RestJson],
if res.isNone():
reader.raiseUnexpectedValue("Incorrect capella block format")
value = ForkedSignedBeaconBlock.init(res.get())
of BeaconBlockFork.EIP4844:
reader.raiseUnexpectedValue($eip4844ImplementationMissing)
withBlck(value):
blck.root = hash_tree_root(blck.message)
@ -1545,6 +1563,8 @@ proc writeValue*(writer: var JsonWriter[RestJson],
of BeaconBlockFork.Capella:
writer.writeField("version", "capella")
writer.writeField("data", value.capellaData)
of BeaconBlockFork.EIP4844:
raiseAssert $eip4844ImplementationMissing
writer.endRecord()
# ForkedHashedBeaconState is used where a `ForkedBeaconState` normally would
@ -2552,6 +2572,8 @@ proc decodeBody*(
except CatchableError:
return err("Unexpected deserialization error")
ok(RestPublishedSignedBeaconBlock(ForkedSignedBeaconBlock.init(blck)))
of BeaconBlockFork.EIP4844:
return err($eip4844ImplementationMissing)
else:
return err("Unsupported or invalid content media type")

View File

@ -20,7 +20,7 @@ import
std/json,
stew/base10, web3/ethtypes,
".."/forks,
".."/datatypes/[phase0, altair, bellatrix],
".."/datatypes/[phase0, altair, bellatrix, eip4844],
".."/mev/bellatrix_mev
from ".."/datatypes/capella import BeaconBlockBody
@ -266,6 +266,7 @@ type
of BeaconBlockFork.Altair: altairBody*: altair.BeaconBlockBody
of BeaconBlockFork.Bellatrix: bellatrixBody*: bellatrix.BeaconBlockBody
of BeaconBlockFork.Capella: capellaBody*: capella.BeaconBlockBody
of BeaconBlockFork.EIP4844: eip4844Body*: eip4844.BeaconBlockBody
RestSpec* = object
# https://github.com/ethereum/consensus-specs/blob/v1.3.0-alpha.1/presets/mainnet/phase0.yaml
@ -337,6 +338,8 @@ type
BELLATRIX_FORK_EPOCH*: uint64
CAPELLA_FORK_VERSION*: Version
CAPELLA_FORK_EPOCH*: uint64
EIP4844_FORK_VERSION*: Version
EIP4844_FORK_EPOCH*: uint64
SECONDS_PER_SLOT*: uint64
SECONDS_PER_ETH1_BLOCK*: uint64
MIN_VALIDATOR_WITHDRAWABILITY_DELAY*: uint64

View File

@ -15,7 +15,7 @@ import
chronicles,
../extras,
"."/[block_id, eth2_merkleization, eth2_ssz_serialization, presets],
./datatypes/[phase0, altair, bellatrix, capella],
./datatypes/[phase0, altair, bellatrix, capella, eip4844],
./mev/bellatrix_mev
# TODO re-export capella, but for now it could cause knock-on effects, so stage
@ -67,28 +67,32 @@ type
of BeaconStateFork.Capella: capellaData*: capella.HashedBeaconState
BeaconBlockFork* {.pure.} = enum
Phase0
Altair
Phase0,
Altair,
Bellatrix,
Capella
Capella,
EIP4844
ForkyBeaconBlockBody* =
phase0.BeaconBlockBody |
altair.BeaconBlockBody |
bellatrix.BeaconBlockBody |
capella.BeaconBlockBody
capella.BeaconBlockBody |
eip4844.BeaconBlockBody
ForkySigVerifiedBeaconBlockBody* =
phase0.SigVerifiedBeaconBlockBody |
altair.SigVerifiedBeaconBlockBody |
bellatrix.SigVerifiedBeaconBlockBody |
capella.SigVerifiedBeaconBlockBody
capella.SigVerifiedBeaconBlockBody |
eip4844.SigVerifiedBeaconBlockBody
ForkyTrustedBeaconBlockBody* =
phase0.TrustedBeaconBlockBody |
altair.TrustedBeaconBlockBody |
bellatrix.TrustedBeaconBlockBody |
capella.TrustedBeaconBlockBody
capella.TrustedBeaconBlockBody |
eip4844.TrustedBeaconBlockBody
SomeForkyBeaconBlockBody* =
ForkyBeaconBlockBody |
@ -99,19 +103,22 @@ type
phase0.BeaconBlock |
altair.BeaconBlock |
bellatrix.BeaconBlock |
capella.BeaconBlock
capella.BeaconBlock |
eip4844.BeaconBlock
ForkySigVerifiedBeaconBlock* =
phase0.SigVerifiedBeaconBlock |
altair.SigVerifiedBeaconBlock |
bellatrix.SigVerifiedBeaconBlock |
capella.SigVerifiedBeaconBlock
capella.SigVerifiedBeaconBlock |
eip4844.SigVerifiedBeaconBlock
ForkyTrustedBeaconBlock* =
phase0.TrustedBeaconBlock |
altair.TrustedBeaconBlock |
bellatrix.TrustedBeaconBlock |
capella.TrustedBeaconBlock
capella.TrustedBeaconBlock |
eip4844.TrustedBeaconBlock
SomeForkyBeaconBlock* =
ForkyBeaconBlock |
@ -124,6 +131,7 @@ type
of BeaconBlockFork.Altair: altairData*: altair.BeaconBlock
of BeaconBlockFork.Bellatrix: bellatrixData*: bellatrix.BeaconBlock
of BeaconBlockFork.Capella: capellaData*: capella.BeaconBlock
of BeaconBlockFork.EIP4844: eip4844Data*: eip4844.BeaconBlock
Web3SignerForkedBeaconBlock* = object
case kind*: BeaconBlockFork
@ -131,6 +139,7 @@ type
of BeaconBlockFork.Altair: altairData*: altair.BeaconBlock
of BeaconBlockFork.Bellatrix: bellatrixData*: BeaconBlockHeader
of BeaconBlockFork.Capella: capellaData*: BeaconBlockHeader
of BeaconBlockFork.EIP4844: eip4844Data*: BeaconBlockHeader
ForkedBlindedBeaconBlock* = object
case kind*: BeaconBlockFork
@ -138,6 +147,7 @@ type
of BeaconBlockFork.Altair: altairData*: altair.BeaconBlock
of BeaconBlockFork.Bellatrix: bellatrixData*: BlindedBeaconBlock
of BeaconBlockFork.Capella: capellaData*: BlindedBeaconBlock
of BeaconBlockFork.EIP4844: eip4844Data*: BlindedBeaconBlock
ForkedTrustedBeaconBlock* = object
case kind*: BeaconBlockFork
@ -145,12 +155,14 @@ type
of BeaconBlockFork.Altair: altairData*: altair.TrustedBeaconBlock
of BeaconBlockFork.Bellatrix: bellatrixData*: bellatrix.TrustedBeaconBlock
of BeaconBlockFork.Capella: capellaData*: capella.TrustedBeaconBlock
of BeaconBlockFork.EIP4844: eip4844Data*: eip4844.TrustedBeaconBlock
ForkySignedBeaconBlock* =
phase0.SignedBeaconBlock |
altair.SignedBeaconBlock |
bellatrix.SignedBeaconBlock |
capella.SignedBeaconBlock
capella.SignedBeaconBlock |
eip4844.SignedBeaconBlock
ForkedSignedBeaconBlock* = object
case kind*: BeaconBlockFork
@ -158,6 +170,7 @@ type
of BeaconBlockFork.Altair: altairData*: altair.SignedBeaconBlock
of BeaconBlockFork.Bellatrix: bellatrixData*: bellatrix.SignedBeaconBlock
of BeaconBlockFork.Capella: capellaData*: capella.SignedBeaconBlock
of BeaconBlockFork.EIP4844: eip4844Data*: eip4844.SignedBeaconBlock
ForkySignedBlindedBeaconBlock* =
phase0.SignedBeaconBlock |
@ -170,24 +183,28 @@ type
of BeaconBlockFork.Altair: altairData*: altair.SignedBeaconBlock
of BeaconBlockFork.Bellatrix: bellatrixData*: SignedBlindedBeaconBlock
of BeaconBlockFork.Capella: capellaData*: SignedBlindedBeaconBlock
of BeaconBlockFork.EIP4844: eip4844Data*: SignedBlindedBeaconBlock
ForkySigVerifiedSignedBeaconBlock* =
phase0.SigVerifiedSignedBeaconBlock |
altair.SigVerifiedSignedBeaconBlock |
bellatrix.SigVerifiedSignedBeaconBlock |
capella.SigVerifiedSignedBeaconBlock
capella.SigVerifiedSignedBeaconBlock |
eip4844.SigVerifiedSignedBeaconBlock
ForkyMsgTrustedSignedBeaconBlock* =
phase0.MsgTrustedSignedBeaconBlock |
altair.MsgTrustedSignedBeaconBlock |
bellatrix.MsgTrustedSignedBeaconBlock |
capella.MsgTrustedSignedBeaconBlock
capella.MsgTrustedSignedBeaconBlock |
eip4844.MsgTrustedSignedBeaconBlock
ForkyTrustedSignedBeaconBlock* =
phase0.TrustedSignedBeaconBlock |
altair.TrustedSignedBeaconBlock |
bellatrix.TrustedSignedBeaconBlock |
capella.TrustedSignedBeaconBlock
capella.TrustedSignedBeaconBlock |
eip4844.TrustedSignedBeaconBlock
ForkedMsgTrustedSignedBeaconBlock* = object
case kind*: BeaconBlockFork
@ -195,6 +212,7 @@ type
of BeaconBlockFork.Altair: altairData*: altair.MsgTrustedSignedBeaconBlock
of BeaconBlockFork.Bellatrix: bellatrixData*: bellatrix.MsgTrustedSignedBeaconBlock
of BeaconBlockFork.Capella: capellaData*: capella.MsgTrustedSignedBeaconBlock
of BeaconBlockFork.EIP4844: eip4844Data*: eip4844.MsgTrustedSignedBeaconBlock
ForkedTrustedSignedBeaconBlock* = object
case kind*: BeaconBlockFork
@ -202,6 +220,7 @@ type
of BeaconBlockFork.Altair: altairData*: altair.TrustedSignedBeaconBlock
of BeaconBlockFork.Bellatrix: bellatrixData*: bellatrix.TrustedSignedBeaconBlock
of BeaconBlockFork.Capella: capellaData*: capella.TrustedSignedBeaconBlock
of BeaconBlockFork.EIP4844: eip4844Data*: eip4844.TrustedSignedBeaconBlock
SomeForkySignedBeaconBlock* =
ForkySignedBeaconBlock |
@ -225,6 +244,7 @@ type
altair*: ForkDigest
bellatrix*: ForkDigest
capella*: ForkDigest
eip4844*: ForkDigest
template toFork*[T: phase0.BeaconState | phase0.HashedBeaconState](
t: type T): BeaconStateFork =
@ -275,6 +295,8 @@ template init*(T: type ForkedSignedBeaconBlock, blck: bellatrix.SignedBeaconBloc
T(kind: BeaconBlockFork.Bellatrix, bellatrixData: blck)
template init*(T: type ForkedSignedBeaconBlock, blck: capella.SignedBeaconBlock): T =
T(kind: BeaconBlockFork.Capella, capellaData: blck)
template init*(T: type ForkedSignedBeaconBlock, blck: eip4844.SignedBeaconBlock): T =
T(kind: BeaconBlockFork.EIP4844, eip4844Data: blck)
func init*(T: type ForkedSignedBeaconBlock, forked: ForkedBeaconBlock,
blockRoot: Eth2Digest, signature: ValidatorSig): T =
@ -299,6 +321,11 @@ func init*(T: type ForkedSignedBeaconBlock, forked: ForkedBeaconBlock,
capellaData: capella.SignedBeaconBlock(message: forked.capellaData,
root: blockRoot,
signature: signature))
of BeaconBlockFork.EIP4844:
T(kind: BeaconBlockFork.EIP4844,
eip4844Data: eip4844.SignedBeaconBlock(message: forked.eip4844Data,
root: blockRoot,
signature: signature))
func init*(T: type ForkedSignedBlindedBeaconBlock,
forked: ForkedBlindedBeaconBlock, blockRoot: Eth2Digest,
@ -322,6 +349,10 @@ func init*(T: type ForkedSignedBlindedBeaconBlock,
T(kind: BeaconBlockFork.Capella,
capellaData: SignedBlindedBeaconBlock(message: forked.capellaData,
signature: signature))
of BeaconBlockFork.EIP4844:
T(kind: BeaconBlockFork.EIP4844,
eip4844Data: SignedBlindedBeaconBlock(message: forked.eip4844Data,
signature: signature))
template init*(T: type ForkedMsgTrustedSignedBeaconBlock, blck: phase0.MsgTrustedSignedBeaconBlock): T =
T(kind: BeaconBlockFork.Phase0, phase0Data: blck)
@ -331,6 +362,9 @@ template init*(T: type ForkedMsgTrustedSignedBeaconBlock, blck: bellatrix.MsgTru
T(kind: BeaconBlockFork.Bellatrix, bellatrixData: blck)
template init*(T: type ForkedMsgTrustedSignedBeaconBlock, blck: capella.MsgTrustedSignedBeaconBlock): T =
T(kind: BeaconBlockFork.Capella, capellaData: blck)
template init*(T: type ForkedMsgTrustedSignedBeaconBlock, blck: eip4844.MsgTrustedSignedBeaconBlock): T =
T(kind: BeaconBlockFork.EIP4844, eip4844Data: blck)
template init*(T: type ForkedTrustedSignedBeaconBlock, blck: phase0.TrustedSignedBeaconBlock): T =
T(kind: BeaconBlockFork.Phase0, phase0Data: blck)
@ -340,6 +374,8 @@ template init*(T: type ForkedTrustedSignedBeaconBlock, blck: bellatrix.TrustedSi
T(kind: BeaconBlockFork.Bellatrix, bellatrixData: blck)
template init*(T: type ForkedTrustedSignedBeaconBlock, blck: capella.TrustedSignedBeaconBlock): T =
T(kind: BeaconBlockFork.Capella, capellaData: blck)
template init*(T: type ForkedTrustedSignedBeaconBlock, blck: eip4844.TrustedSignedBeaconBlock): T =
T(kind: BeaconBlockFork.EIP4844, eip4844Data: blck)
template toString*(kind: BeaconBlockFork): string =
case kind
@ -351,6 +387,8 @@ template toString*(kind: BeaconBlockFork): string =
"bellatrix"
of BeaconBlockFork.Capella:
"capella"
of BeaconBlockFork.EIP4844:
"eip4844"
template toString*(kind: BeaconStateFork): string =
case kind
@ -400,6 +438,16 @@ template toFork*[T:
t: type T): BeaconBlockFork =
BeaconBlockFork.Capella
template toFork*[T:
eip4844.BeaconBlock |
eip4844.SignedBeaconBlock |
eip4844.TrustedBeaconBlock |
eip4844.SigVerifiedSignedBeaconBlock |
eip4844.MsgTrustedSignedBeaconBlock |
eip4844.TrustedSignedBeaconBlock](
t: type T): BeaconBlockFork =
BeaconBlockFork.EIP4844
template init*(T: type ForkedEpochInfo, info: phase0.EpochInfo): T =
T(kind: EpochInfoFork.Phase0, phase0Data: info)
template init*(T: type ForkedEpochInfo, info: altair.EpochInfo): T =
@ -594,6 +642,10 @@ template withBlck*(
const stateFork {.inject, used.} = BeaconStateFork.Capella
template blck: untyped {.inject.} = x.capellaData
body
of BeaconBlockFork.EIP4844:
const stateFork {.inject, used.} = BeaconStateFork.Capella
template blck: untyped {.inject.} = x.capellaData
body
func proposer_index*(x: ForkedBeaconBlock): uint64 =
withBlck(x): blck.proposer_index
@ -612,7 +664,8 @@ template getForkedBlockField*(
of BeaconBlockFork.Phase0: unsafeAddr x.phase0Data.message.y
of BeaconBlockFork.Altair: unsafeAddr x.altairData.message.y
of BeaconBlockFork.Bellatrix: unsafeAddr x.bellatrixData.message.y
of BeaconBlockFork.Capella: unsafeAddr x.capellaData.message.y)[]
of BeaconBlockFork.Capella: unsafeAddr x.capellaData.message.y
of BeaconBlockFork.EIP4844: unsafeAddr x.eip4844Data.message.y)[]
template signature*(x: ForkedSignedBeaconBlock |
ForkedMsgTrustedSignedBeaconBlock |
@ -719,6 +772,12 @@ func capellaFork*(cfg: RuntimeConfig): Fork =
current_version: cfg.CAPELLA_FORK_VERSION,
epoch: cfg.CAPELLA_FORK_EPOCH)
func eip4844Fork*(cfg: RuntimeConfig): Fork =
Fork(
previous_version: cfg.CAPELLA_FORK_VERSION,
current_version: cfg.EIP4844_FORK_VERSION,
epoch: cfg.EIP4844_FORK_EPOCH)
func forkAtEpoch*(cfg: RuntimeConfig, epoch: Epoch): Fork =
case cfg.stateForkAtEpoch(epoch)
of BeaconStateFork.Capella: cfg.capellaFork

View File

@ -55,6 +55,8 @@ type
BELLATRIX_FORK_EPOCH*: Epoch
CAPELLA_FORK_VERSION*: Version
CAPELLA_FORK_EPOCH*: Epoch
EIP4844_FORK_VERSION*: Version
EIP4844_FORK_EPOCH*: Epoch
SHARDING_FORK_VERSION*: Version
SHARDING_FORK_EPOCH*: Epoch
@ -160,8 +162,11 @@ when const_preset == "mainnet":
# Capella
CAPELLA_FORK_VERSION: Version [byte 0x03, 0x00, 0x00, 0x00],
CAPELLA_FORK_EPOCH: FAR_FUTURE_EPOCH,
# eip4844
EIP4844_FORK_VERSION: Version [byte 0x04, 0x00, 0x00, 0x00],
EIP4844_FORK_EPOCH: FAR_FUTURE_EPOCH,
# Sharding
SHARDING_FORK_VERSION: Version [byte 0x04, 0x00, 0x00, 0x00],
SHARDING_FORK_VERSION: Version [byte 0x05, 0x00, 0x00, 0x00],
SHARDING_FORK_EPOCH: FAR_FUTURE_EPOCH,
# Time parameters
@ -260,8 +265,11 @@ elif const_preset == "minimal":
# Capella
CAPELLA_FORK_VERSION: Version [byte 0x03, 0x00, 0x00, 0x01],
CAPELLA_FORK_EPOCH: Epoch(uint64.high),
# eip4844
EIP4844_FORK_VERSION: Version [byte 0x04, 0x00, 0x00, 0x00],
EIP4844_FORK_EPOCH: Epoch(uint64.high),
# Sharding
SHARDING_FORK_VERSION: Version [byte 0x04, 0x00, 0x00, 0x01],
SHARDING_FORK_VERSION: Version [byte 0x05, 0x00, 0x00, 0x00],
SHARDING_FORK_EPOCH: Epoch(uint64.high),

View File

@ -1,4 +1,4 @@
import
./mainnet/[altair_preset, bellatrix_preset, capella_preset, phase0_preset]
./mainnet/[altair_preset, bellatrix_preset, capella_preset, eip4844_preset, phase0_preset]
export altair_preset, bellatrix_preset, capella_preset, phase0_preset
export altair_preset, bellatrix_preset, capella_preset, eip4844_preset, phase0_preset

View File

@ -0,0 +1,7 @@
# Mainnet preset - EIP-4844
# https://github.com/ethereum/consensus-specs/blob/v1.3.0-alpha.1/presets/mainnet/eip4844.yaml
const
# `uint64(4096)`
FIELD_ELEMENTS_PER_BLOB*: uint64 = 4096
# `uint64(2**4)` (= 16)
MAX_BLOBS_PER_BLOCK*: uint64 = 16

View File

@ -1,4 +1,4 @@
import
./minimal/[altair_preset, bellatrix_preset, capella_preset, phase0_preset]
./minimal/[altair_preset, bellatrix_preset, capella_preset, eip4844_preset, phase0_preset]
export altair_preset, bellatrix_preset, capella_preset, phase0_preset
export altair_preset, bellatrix_preset, capella_preset, eip4844_preset, phase0_preset

View File

@ -0,0 +1,7 @@
# Minimal preset - EIP-4844
# https://github.com/ethereum/consensus-specs/blob/v1.3.0-alpha.1/presets/mainnet/eip4844.yaml
const
# `uint64(4096)`
FIELD_ELEMENTS_PER_BLOB*: uint64 = 4096
# `uint64(2**4)` (= 16)
MAX_BLOBS_PER_BLOCK*: uint64 = 16

View File

@ -1687,6 +1687,9 @@ proc publishBlock*(
publishBlock(it, data.bellatrixData)
of BeaconBlockFork.Capella:
publishBlock(it, data.capellaData)
of BeaconBlockFork.EIP4844:
raiseAssert $eip4844ImplementationMissing
do:
if apiResponse.isErr():
debug ErrorMessage, endpoint = node, error = apiResponse.error()
@ -1736,6 +1739,8 @@ proc publishBlock*(
publishBlock(it, data.bellatrixData)
of BeaconBlockFork.Capella:
publishBlock(it, data.capellaData)
of BeaconBlockFork.EIP4844:
raiseAssert $eip4844ImplementationMissing
do:
if apiResponse.isErr():
debug ErrorMessage, endpoint = node, error = apiResponse.error()
@ -1881,6 +1886,8 @@ proc publishBlindedBlock*(
publishBlindedBlock(it, data.bellatrixData)
of BeaconBlockFork.Capella:
publishBlindedBlock(it, data.capellaData)
of BeaconBlockFork.EIP4844:
raiseAssert $eip4844ImplementationMissing
do:
if apiResponse.isErr():
debug ErrorMessage, endpoint = node, error = apiResponse.error()
@ -1930,6 +1937,8 @@ proc publishBlindedBlock*(
publishBlindedBlock(it, data.bellatrixData)
of BeaconBlockFork.Capella:
publishBlindedBlock(it, data.capellaData)
of BeaconBlockFork.EIP4844:
raiseAssert $eip4844ImplementationMissing
do:
if apiResponse.isErr():
debug ErrorMessage, endpoint = node, error = apiResponse.error()

View File

@ -357,6 +357,8 @@ proc getBlockSignature*(v: AttachedValidator, fork: Fork,
Web3SignerForkedBeaconBlock(
kind: BeaconBlockFork.Capella,
capellaData: blck.capellaData.toBeaconBlockHeader)
of BeaconBlockFork.EIP4844:
raiseAssert $eip4844ImplementationMissing
request = Web3SignerRequest.init(
fork, genesis_validators_root, web3SignerBlock)
@ -388,6 +390,8 @@ proc getBlockSignature*(v: AttachedValidator, fork: Fork,
Web3SignerForkedBeaconBlock(
kind: BeaconBlockFork.Capella,
capellaData: blck.capellaData.toBeaconBlockHeader)
of BeaconBlockFork.EIP4844:
raiseAssert $eip4844ImplementationMissing
request = Web3SignerRequest.init(
fork, genesis_validators_root, web3SignerBlock)

View File

@ -260,6 +260,8 @@ proc cmdBench(conf: DbConf, cfg: RuntimeConfig) =
of BeaconBlockFork.Capella:
blocks[3].add dag.db.getBlock(
blck.root, capella.TrustedSignedBeaconBlock).get()
of BeaconBlockFork.EIP4844:
raiseAssert $eip4844ImplementationMissing
let stateData = newClone(dag.headState)

View File

@ -203,6 +203,8 @@ cli do(validatorsDir: string, secretsDir: string,
fork, genesis_validators_root, slot, blockRoot,
validators[proposer]).toValidatorSig())
dump(".", signedBlock)
of BeaconBlockFork.EIP4844:
raiseAssert $eip4844ImplementationMissing
notice "Block proposed", message, blockRoot
aggregates.setLen(0)

View File

@ -210,6 +210,8 @@ suite "Gossip validation - Extra": # Not based on preset config
of BeaconBlockFork.Capella:
const nilCallback = OnCapellaBlockAdded(nil)
dag.addHeadBlock(verifier, blck.capellaData, nilCallback)
of BeaconBlockFork.EIP4844:
raiseAssert $eip4844ImplementationMissing
check: added.isOk()
dag.updateHead(added[], quarantine[])
dag

View File

@ -70,6 +70,9 @@ suite "Light client" & preset():
of BeaconBlockFork.Capella:
const nilCallback = OnCapellaBlockAdded(nil)
dag.addHeadBlock(verifier, blck.capellaData, nilCallback)
of BeaconBlockFork.EIP4844:
raiseAssert $eip4844ImplementationMissing
check: added.isOk()
dag.updateHead(added[], quarantine)

View File

@ -55,6 +55,8 @@ suite "Light client processor" & preset():
of BeaconBlockFork.Capella:
const nilCallback = OnCapellaBlockAdded(nil)
dag.addHeadBlock(verifier, blck.capellaData, nilCallback)
of BeaconBlockFork.EIP4844:
raiseAssert $eip4844ImplementationMissing
doAssert added.isOk()
dag.updateHead(added[], quarantine[])