initial Electra support skeleton (#5946)
This commit is contained in:
parent
feec45ba76
commit
d09bf3b587
|
@ -508,7 +508,8 @@ proc new*(T: type BeaconChainDB,
|
|||
kvStore db.openKvStore("altair_blocks").expectDb(),
|
||||
kvStore db.openKvStore("bellatrix_blocks").expectDb(),
|
||||
kvStore db.openKvStore("capella_blocks").expectDb(),
|
||||
kvStore db.openKvStore("deneb_blocks").expectDb()]
|
||||
kvStore db.openKvStore("deneb_blocks").expectDb(),
|
||||
kvStore db.openKvStore("electra_blocks").expectDb()]
|
||||
|
||||
stateRoots = kvStore db.openKvStore("state_roots", true).expectDb()
|
||||
|
||||
|
@ -517,7 +518,8 @@ proc new*(T: type BeaconChainDB,
|
|||
kvStore db.openKvStore("altair_state_no_validators").expectDb(),
|
||||
kvStore db.openKvStore("bellatrix_state_no_validators").expectDb(),
|
||||
kvStore db.openKvStore("capella_state_no_validator_pubkeys").expectDb(),
|
||||
kvStore db.openKvStore("deneb_state_no_validator_pubkeys").expectDb()]
|
||||
kvStore db.openKvStore("deneb_state_no_validator_pubkeys").expectDb(),
|
||||
kvStore db.openKvStore("electra_state_no_validator_pubkeys").expectDb()]
|
||||
|
||||
stateDiffs = kvStore db.openKvStore("state_diffs").expectDb()
|
||||
summaries = kvStore db.openKvStore("beacon_block_summaries", true).expectDb()
|
||||
|
@ -789,7 +791,8 @@ proc putBlock*(
|
|||
proc putBlock*(
|
||||
db: BeaconChainDB,
|
||||
value: bellatrix.TrustedSignedBeaconBlock |
|
||||
capella.TrustedSignedBeaconBlock | deneb.TrustedSignedBeaconBlock) =
|
||||
capella.TrustedSignedBeaconBlock | deneb.TrustedSignedBeaconBlock |
|
||||
electra.TrustedSignedBeaconBlock) =
|
||||
db.withManyWrites:
|
||||
db.blocks[type(value).kind].putSZSSZ(value.root.data, value)
|
||||
db.putBeaconBlockSummary(value.root, value.message.toBeaconBlockSummary())
|
||||
|
@ -839,6 +842,10 @@ template toBeaconStateNoImmutableValidators(state: deneb.BeaconState):
|
|||
DenebBeaconStateNoImmutableValidators =
|
||||
isomorphicCast[DenebBeaconStateNoImmutableValidators](state)
|
||||
|
||||
template toBeaconStateNoImmutableValidators(state: electra.BeaconState):
|
||||
ElectraBeaconStateNoImmutableValidators =
|
||||
isomorphicCast[ElectraBeaconStateNoImmutableValidators](state)
|
||||
|
||||
proc putState*(
|
||||
db: BeaconChainDB, key: Eth2Digest,
|
||||
value: phase0.BeaconState | altair.BeaconState) =
|
||||
|
@ -848,7 +855,8 @@ proc putState*(
|
|||
|
||||
proc putState*(
|
||||
db: BeaconChainDB, key: Eth2Digest,
|
||||
value: bellatrix.BeaconState | capella.BeaconState | deneb.BeaconState) =
|
||||
value: bellatrix.BeaconState | capella.BeaconState | deneb.BeaconState |
|
||||
electra.BeaconState) =
|
||||
db.updateImmutableValidators(value.validators.asSeq())
|
||||
db.statesNoVal[type(value).kind].putSZSSZ(
|
||||
key.data, toBeaconStateNoImmutableValidators(value))
|
||||
|
@ -976,7 +984,7 @@ proc getBlock*(
|
|||
|
||||
proc getBlock*[
|
||||
X: bellatrix.TrustedSignedBeaconBlock | capella.TrustedSignedBeaconBlock |
|
||||
deneb.TrustedSignedBeaconBlock](
|
||||
deneb.TrustedSignedBeaconBlock | electra.TrustedSignedBeaconBlock](
|
||||
db: BeaconChainDB, key: Eth2Digest,
|
||||
T: type X): Opt[T] =
|
||||
# We only store blocks that we trust in the database
|
||||
|
@ -1031,7 +1039,7 @@ proc getBlockSSZ*(
|
|||
|
||||
proc getBlockSSZ*[
|
||||
X: bellatrix.TrustedSignedBeaconBlock | capella.TrustedSignedBeaconBlock |
|
||||
deneb.TrustedSignedBeaconBlock](
|
||||
deneb.TrustedSignedBeaconBlock | electra.TrustedSignedBeaconBlock](
|
||||
db: BeaconChainDB, key: Eth2Digest, data: var seq[byte], T: type X): bool =
|
||||
let dataPtr = addr data # Short-lived
|
||||
var success = true
|
||||
|
@ -1080,7 +1088,7 @@ proc getBlockSZ*(
|
|||
|
||||
proc getBlockSZ*[
|
||||
X: bellatrix.TrustedSignedBeaconBlock | capella.TrustedSignedBeaconBlock |
|
||||
deneb.TrustedSignedBeaconBlock](
|
||||
deneb.TrustedSignedBeaconBlock | electra.TrustedSignedBeaconBlock](
|
||||
db: BeaconChainDB, key: Eth2Digest, data: var seq[byte], T: type X): bool =
|
||||
let dataPtr = addr data # Short-lived
|
||||
func decode(data: openArray[byte]) =
|
||||
|
@ -1178,7 +1186,8 @@ proc getStateOnlyMutableValidators(
|
|||
proc getStateOnlyMutableValidators(
|
||||
immutableValidators: openArray[ImmutableValidatorData2],
|
||||
store: KvStoreRef, key: openArray[byte],
|
||||
output: var (capella.BeaconState | deneb.BeaconState),
|
||||
output: var (capella.BeaconState | deneb.BeaconState |
|
||||
electra.BeaconState),
|
||||
rollback: RollbackProc): bool =
|
||||
## Load state into `output` - BeaconState is large so we want to avoid
|
||||
## re-allocating it if possible
|
||||
|
@ -1263,7 +1272,8 @@ proc getState*(
|
|||
proc getState*(
|
||||
db: BeaconChainDB, key: Eth2Digest,
|
||||
output: var (altair.BeaconState | bellatrix.BeaconState |
|
||||
capella.BeaconState | deneb.BeaconState),
|
||||
capella.BeaconState | deneb.BeaconState |
|
||||
electra.BeaconState),
|
||||
rollback: RollbackProc): bool =
|
||||
## Load state into `output` - BeaconState is large so we want to avoid
|
||||
## re-allocating it if possible
|
||||
|
@ -1483,7 +1493,7 @@ iterator getAncestorSummaries*(db: BeaconChainDB, root: Eth2Digest):
|
|||
|
||||
# Backwards compat for reading old databases, or those that for whatever
|
||||
# reason lost a summary along the way..
|
||||
static: doAssert ConsensusFork.high == ConsensusFork.Deneb
|
||||
static: doAssert ConsensusFork.high == ConsensusFork.Electra
|
||||
while true:
|
||||
if db.v0.backend.getSnappySSZ(
|
||||
subkey(BeaconBlockSummary, res.root), res.summary) == GetResult.found:
|
||||
|
@ -1498,6 +1508,8 @@ iterator getAncestorSummaries*(db: BeaconChainDB, root: Eth2Digest):
|
|||
res.summary = blck.get().message.toBeaconBlockSummary()
|
||||
elif (let blck = db.getBlock(res.root, deneb.TrustedSignedBeaconBlock); blck.isSome()):
|
||||
res.summary = blck.get().message.toBeaconBlockSummary()
|
||||
elif (let blck = db.getBlock(res.root, electra.TrustedSignedBeaconBlock); blck.isSome()):
|
||||
res.summary = blck.get().message.toBeaconBlockSummary()
|
||||
else:
|
||||
break
|
||||
|
||||
|
|
|
@ -77,6 +77,8 @@ proc initLightClient*(
|
|||
|
||||
case node.dag.cfg.consensusForkAtEpoch(
|
||||
forkyBlck.message.slot.epoch)
|
||||
of ConsensusFork.Electra:
|
||||
debugRaiseAssert "initLightClient"
|
||||
of ConsensusFork.Deneb:
|
||||
callForkchoiceUpdated(PayloadAttributesV3)
|
||||
of ConsensusFork.Capella:
|
||||
|
|
|
@ -483,7 +483,8 @@ func init(
|
|||
func init(
|
||||
T: type AttestationCache,
|
||||
state: altair.HashedBeaconState | bellatrix.HashedBeaconState |
|
||||
capella.HashedBeaconState | deneb.HashedBeaconState,
|
||||
capella.HashedBeaconState | deneb.HashedBeaconState |
|
||||
electra.HashedBeaconState,
|
||||
cache: var StateCache): T =
|
||||
# Load attestations that are scheduled for being given rewards for
|
||||
let
|
||||
|
|
|
@ -69,7 +69,8 @@ func hasBlob*(
|
|||
|
||||
func popBlobs*(
|
||||
quarantine: var BlobQuarantine, digest: Eth2Digest,
|
||||
blck: deneb.SignedBeaconBlock): seq[ref BlobSidecar] =
|
||||
blck: deneb.SignedBeaconBlock | electra.SignedBeaconBlock):
|
||||
seq[ref BlobSidecar] =
|
||||
var r: seq[ref BlobSidecar] = @[]
|
||||
for idx, kzg_commitment in blck.message.body.blob_kzg_commitments:
|
||||
var b: ref BlobSidecar
|
||||
|
@ -77,8 +78,9 @@ func popBlobs*(
|
|||
r.add(b)
|
||||
r
|
||||
|
||||
func hasBlobs*(quarantine: BlobQuarantine, blck: deneb.SignedBeaconBlock):
|
||||
bool =
|
||||
func hasBlobs*(
|
||||
quarantine: BlobQuarantine,
|
||||
blck: deneb.SignedBeaconBlock | electra.SignedBeaconBlock): bool =
|
||||
for idx, kzg_commitment in blck.message.body.blob_kzg_commitments:
|
||||
if (blck.root, BlobIndex idx, kzg_commitment) notin quarantine.blobs:
|
||||
return false
|
||||
|
|
|
@ -73,7 +73,8 @@ func init*(
|
|||
T: type BlockRef, root: Eth2Digest, executionValid: bool,
|
||||
blck: bellatrix.SomeBeaconBlock | bellatrix.TrustedBeaconBlock |
|
||||
capella.SomeBeaconBlock | capella.TrustedBeaconBlock |
|
||||
deneb.SomeBeaconBlock | deneb.TrustedBeaconBlock): BlockRef =
|
||||
deneb.SomeBeaconBlock | deneb.TrustedBeaconBlock |
|
||||
electra.SomeBeaconBlock | electra.TrustedBeaconBlock): BlockRef =
|
||||
BlockRef.init(
|
||||
root, Opt.some Eth2Digest(blck.body.execution_payload.block_hash),
|
||||
executionValid =
|
||||
|
|
|
@ -293,10 +293,11 @@ type
|
|||
OnBellatrixBlockAdded* = OnBlockAdded[bellatrix.TrustedSignedBeaconBlock]
|
||||
OnCapellaBlockAdded* = OnBlockAdded[capella.TrustedSignedBeaconBlock]
|
||||
OnDenebBlockAdded* = OnBlockAdded[deneb.TrustedSignedBeaconBlock]
|
||||
OnElectraBlockAdded* = OnBlockAdded[electra.TrustedSignedBeaconBlock]
|
||||
|
||||
OnForkyBlockAdded* =
|
||||
OnPhase0BlockAdded | OnAltairBlockAdded | OnBellatrixBlockAdded |
|
||||
OnCapellaBlockAdded | OnDenebBlockAdded
|
||||
OnCapellaBlockAdded | OnDenebBlockAdded | OnElectraBlockAdded
|
||||
|
||||
HeadChangeInfoObject* = object
|
||||
slot*: Slot
|
||||
|
@ -328,7 +329,9 @@ type
|
|||
optimistic* {.serializedFieldName: "execution_optimistic".}: Option[bool]
|
||||
|
||||
template OnBlockAddedCallback*(kind: static ConsensusFork): auto =
|
||||
when kind == ConsensusFork.Deneb:
|
||||
when kind == ConsensusFork.Electra:
|
||||
typedesc[OnElectraBlockAdded]
|
||||
elif kind == ConsensusFork.Deneb:
|
||||
typedesc[OnDenebBlockAdded]
|
||||
elif kind == ConsensusFork.Capella:
|
||||
typedesc[OnCapellaBlockAdded]
|
||||
|
|
|
@ -294,8 +294,7 @@ iterator pop*(quarantine: var Quarantine, root: Eth2Digest):
|
|||
|
||||
proc addBlobless*(
|
||||
quarantine: var Quarantine, finalizedSlot: Slot,
|
||||
signedBlock: deneb.SignedBeaconBlock): bool =
|
||||
|
||||
signedBlock: deneb.SignedBeaconBlock | electra.SignedBeaconBlock): bool =
|
||||
if not isViable(finalizedSlot, signedBlock.message.slot):
|
||||
quarantine.addUnviable(signedBlock.root)
|
||||
return false
|
||||
|
@ -306,6 +305,8 @@ proc addBlobless*(
|
|||
return true
|
||||
|
||||
debug "block quarantine: Adding blobless", blck = shortLog(signedBlock)
|
||||
debugRaiseAssert "addBlobless; needs consideration how to handle deneb and electra"
|
||||
when not (signedBlock is electra.SignedBeaconBlock):
|
||||
quarantine.blobless[signedBlock.root] = signedBlock
|
||||
quarantine.missing.del(signedBlock.root)
|
||||
true
|
||||
|
|
|
@ -268,8 +268,11 @@ proc getForkedBlock*(db: BeaconChainDB, root: Eth2Digest):
|
|||
Opt[ForkedTrustedSignedBeaconBlock] =
|
||||
# When we only have a digest, we don't know which fork it's from so we try
|
||||
# them one by one - this should be used sparingly
|
||||
static: doAssert high(ConsensusFork) == ConsensusFork.Deneb
|
||||
if (let blck = db.getBlock(root, deneb.TrustedSignedBeaconBlock);
|
||||
static: doAssert high(ConsensusFork) == ConsensusFork.Electra
|
||||
if (let blck = db.getBlock(root, electra.TrustedSignedBeaconBlock);
|
||||
blck.isSome()):
|
||||
ok(ForkedTrustedSignedBeaconBlock.init(blck.get()))
|
||||
elif (let blck = db.getBlock(root, deneb.TrustedSignedBeaconBlock);
|
||||
blck.isSome()):
|
||||
ok(ForkedTrustedSignedBeaconBlock.init(blck.get()))
|
||||
elif (let blck = db.getBlock(root, capella.TrustedSignedBeaconBlock);
|
||||
|
@ -1002,6 +1005,12 @@ proc applyBlock(
|
|||
state_transition(
|
||||
dag.cfg, state, data, cache, info,
|
||||
dag.updateFlags + {slotProcessed}, noRollback)
|
||||
of ConsensusFork.Electra:
|
||||
let data = getBlock(dag, bid, electra.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,
|
||||
|
@ -1160,6 +1169,7 @@ proc init*(T: type ChainDAGRef, cfg: RuntimeConfig, db: BeaconChainDB,
|
|||
of ConsensusFork.Bellatrix: bellatrixFork(cfg)
|
||||
of ConsensusFork.Capella: capellaFork(cfg)
|
||||
of ConsensusFork.Deneb: denebFork(cfg)
|
||||
of ConsensusFork.Electra: electraFork(cfg)
|
||||
stateFork = getStateField(dag.headState, fork)
|
||||
|
||||
# Here, we check only the `current_version` field because the spec
|
||||
|
@ -2398,6 +2408,8 @@ proc updateHead*(
|
|||
of ConsensusFork.Deneb:
|
||||
if dag.vanityLogs.onUpgradeToDeneb != nil:
|
||||
dag.vanityLogs.onUpgradeToDeneb()
|
||||
of ConsensusFork.Electra:
|
||||
debugRaiseAssert "updateHead"
|
||||
|
||||
if dag.vanityLogs.onKnownBlsToExecutionChange != nil and
|
||||
checkBlsToExecutionChanges(
|
||||
|
|
|
@ -379,7 +379,16 @@ proc runProposalForkchoiceUpdated*(
|
|||
payloadAttributes = some fcPayloadAttributes)
|
||||
debug "Fork-choice updated for proposal", status
|
||||
|
||||
static: doAssert high(ConsensusFork) == ConsensusFork.Deneb
|
||||
static: doAssert high(ConsensusFork) == ConsensusFork.Electra
|
||||
when consensusFork >= ConsensusFork.Electra:
|
||||
debugRaiseAssert "runProposalForkchoiceUpdated, probably will be a new payload attributes type here"
|
||||
callForkchoiceUpdated(PayloadAttributesV3(
|
||||
timestamp: Quantity timestamp,
|
||||
prevRandao: FixedBytes[32] randomData,
|
||||
suggestedFeeRecipient: feeRecipient,
|
||||
withdrawals:
|
||||
toEngineWithdrawals get_expected_withdrawals(forkyState.data),
|
||||
parentBeaconBlockRoot: beaconHead.blck.bid.root.asBlockHash))
|
||||
when consensusFork >= ConsensusFork.Deneb:
|
||||
callForkchoiceUpdated(PayloadAttributesV3(
|
||||
timestamp: Quantity timestamp,
|
||||
|
|
|
@ -561,6 +561,32 @@ func asEngineExecutionPayload*(executionPayload: deneb.ExecutionPayload):
|
|||
blobGasUsed: Quantity(executionPayload.blob_gas_used),
|
||||
excessBlobGas: Quantity(executionPayload.excess_blob_gas))
|
||||
|
||||
func asEngineExecutionPayload*(executionPayload: electra.ExecutionPayload):
|
||||
ExecutionPayloadV3 =
|
||||
debugRaiseAssert "asEngineExecutionPayload for electra.ExecutionPayload probably won't use ExecutionPayloadV3"
|
||||
template getTypedTransaction(tt: bellatrix.Transaction): TypedTransaction =
|
||||
TypedTransaction(tt.distinctBase)
|
||||
|
||||
engine_api.ExecutionPayloadV3(
|
||||
parentHash: executionPayload.parent_hash.asBlockHash,
|
||||
feeRecipient: Address(executionPayload.fee_recipient.data),
|
||||
stateRoot: executionPayload.state_root.asBlockHash,
|
||||
receiptsRoot: executionPayload.receipts_root.asBlockHash,
|
||||
logsBloom:
|
||||
FixedBytes[BYTES_PER_LOGS_BLOOM](executionPayload.logs_bloom.data),
|
||||
prevRandao: executionPayload.prev_randao.asBlockHash,
|
||||
blockNumber: Quantity(executionPayload.block_number),
|
||||
gasLimit: Quantity(executionPayload.gas_limit),
|
||||
gasUsed: Quantity(executionPayload.gas_used),
|
||||
timestamp: Quantity(executionPayload.timestamp),
|
||||
extraData: DynamicBytes[0, MAX_EXTRA_DATA_BYTES](executionPayload.extra_data),
|
||||
baseFeePerGas: executionPayload.base_fee_per_gas,
|
||||
blockHash: executionPayload.block_hash.asBlockHash,
|
||||
transactions: mapIt(executionPayload.transactions, it.getTypedTransaction),
|
||||
withdrawals: mapIt(executionPayload.withdrawals, it.asEngineWithdrawal),
|
||||
blobGasUsed: Quantity(executionPayload.blob_gas_used),
|
||||
excessBlobGas: Quantity(executionPayload.excess_blob_gas))
|
||||
|
||||
func isConnected(connection: ELConnection): bool =
|
||||
connection.web3.isSome
|
||||
|
||||
|
@ -752,6 +778,10 @@ template EngineApiResponseType*(T: type capella.ExecutionPayloadForSigning): typ
|
|||
template EngineApiResponseType*(T: type deneb.ExecutionPayloadForSigning): type =
|
||||
engine_api.GetPayloadV3Response
|
||||
|
||||
template EngineApiResponseType*(T: type electra.ExecutionPayloadForSigning): type =
|
||||
debugRaiseAssert "EngineApiResponseType electra.ExecutionPayloadForSigning; presumably will be a GetPayloadV4Response"
|
||||
engine_api.GetPayloadV3Response
|
||||
|
||||
template toEngineWithdrawals*(withdrawals: seq[capella.Withdrawal]): seq[WithdrawalV1] =
|
||||
mapIt(withdrawals, toEngineWithdrawal(it))
|
||||
|
||||
|
@ -850,10 +880,16 @@ proc getPayload*(m: ELManager,
|
|||
|
||||
deadline.cancelSoon()
|
||||
|
||||
when PayloadType.kind != ConsensusFork.Electra:
|
||||
if bestPayloadIdx.isSome:
|
||||
return ok requests[bestPayloadIdx.get].value().asConsensusType
|
||||
else:
|
||||
return err()
|
||||
else:
|
||||
# right now, asConsensusType is confused by Deneb and Electra sharing a
|
||||
# Payload type. this will probably be resolved in time naturally.
|
||||
debugRaiseAssert "getPayload ForkyExecutionPayloadForSigning"
|
||||
return err()
|
||||
|
||||
proc waitELToSyncDeposits(connection: ELConnection,
|
||||
minimalRequiredBlock: BlockHash) {.async.} =
|
||||
|
|
|
@ -447,6 +447,8 @@ iterator getBlockIds*(
|
|||
if not getPartialState(
|
||||
db, historical_roots, historical_summaries, stateSlot, state[]):
|
||||
state = nil # No `return` in iterators
|
||||
of ConsensusFork.Electra:
|
||||
debugRaiseAssert "getBlockIds"
|
||||
|
||||
if state == nil:
|
||||
break
|
||||
|
|
|
@ -328,7 +328,7 @@ proc newExecutionPayload*(
|
|||
proc getExecutionValidity(
|
||||
elManager: ELManager,
|
||||
blck: bellatrix.SignedBeaconBlock | capella.SignedBeaconBlock |
|
||||
deneb.SignedBeaconBlock):
|
||||
deneb.SignedBeaconBlock | electra.SignedBeaconBlock):
|
||||
Future[NewPayloadStatus] {.async: (raises: [CancelledError]).} =
|
||||
if not blck.message.is_execution_block:
|
||||
return NewPayloadStatus.valid # vacuously
|
||||
|
@ -361,8 +361,9 @@ proc getExecutionValidity(
|
|||
blck = shortLog(blck)
|
||||
return NewPayloadStatus.noResponse
|
||||
|
||||
proc checkBloblessSignature(self: BlockProcessor,
|
||||
signed_beacon_block: deneb.SignedBeaconBlock):
|
||||
proc checkBloblessSignature(
|
||||
self: BlockProcessor,
|
||||
signed_beacon_block: deneb.SignedBeaconBlock | electra.SignedBeaconBlock):
|
||||
Result[void, cstring] =
|
||||
let dag = self.consensusManager.dag
|
||||
let parent = dag.getBlockRef(signed_beacon_block.message.parent_root).valueOr:
|
||||
|
@ -674,6 +675,9 @@ proc storeBlock(
|
|||
template callForkChoiceUpdated: auto =
|
||||
case self.consensusManager.dag.cfg.consensusForkAtEpoch(
|
||||
newHead.get.blck.bid.slot.epoch)
|
||||
of ConsensusFork.Electra:
|
||||
debugRaiseAssert "storeBlock, probably will become PayloadAttributesV3"
|
||||
callExpectValidFCU(payloadAttributeType = PayloadAttributesV3)
|
||||
of ConsensusFork.Deneb:
|
||||
callExpectValidFCU(payloadAttributeType = PayloadAttributesV3)
|
||||
of ConsensusFork.Capella:
|
||||
|
|
|
@ -268,7 +268,8 @@ template validateBeaconBlockBellatrix(
|
|||
signed_beacon_block:
|
||||
bellatrix.SignedBeaconBlock |
|
||||
capella.SignedBeaconBlock |
|
||||
deneb.SignedBeaconBlock,
|
||||
deneb.SignedBeaconBlock |
|
||||
electra.SignedBeaconBlock,
|
||||
parent: BlockRef): untyped =
|
||||
# If the execution is enabled for the block -- i.e.
|
||||
# is_execution_enabled(state, block.body) then validate the following:
|
||||
|
|
|
@ -830,7 +830,7 @@ template gossipMaxSize(T: untyped): uint32 =
|
|||
when isFixedSize(T):
|
||||
fixedPortionSize(T).uint32
|
||||
elif T is bellatrix.SignedBeaconBlock or T is capella.SignedBeaconBlock or
|
||||
T is deneb.SignedBeaconBlock:
|
||||
T is deneb.SignedBeaconBlock or T is electra.SignedBeaconBlock:
|
||||
GOSSIP_MAX_SIZE
|
||||
# TODO https://github.com/status-im/nim-ssz-serialization/issues/20 for
|
||||
# Attestation, AttesterSlashing, and SignedAggregateAndProof, which all
|
||||
|
@ -2637,6 +2637,12 @@ proc broadcastBeaconBlock*(
|
|||
let topic = getBeaconBlocksTopic(node.forkDigests.deneb)
|
||||
node.broadcast(topic, blck)
|
||||
|
||||
proc broadcastBeaconBlock*(
|
||||
node: Eth2Node, blck: electra.SignedBeaconBlock):
|
||||
Future[SendResult] {.async: (raises: [CancelledError], raw: true).} =
|
||||
let topic = getBeaconBlocksTopic(node.forkDigests.electra)
|
||||
node.broadcast(topic, blck)
|
||||
|
||||
proc broadcastBlobSidecar*(
|
||||
node: Eth2Node, subnet_id: BlobId, blob: deneb.BlobSidecar):
|
||||
Future[SendResult] {.async: (raises: [CancelledError], raw: true).} =
|
||||
|
|
|
@ -275,7 +275,8 @@ when const_preset == "gnosis":
|
|||
doAssert network.cfg.BELLATRIX_FORK_EPOCH < FAR_FUTURE_EPOCH
|
||||
doAssert network.cfg.CAPELLA_FORK_EPOCH < FAR_FUTURE_EPOCH
|
||||
doAssert network.cfg.DENEB_FORK_EPOCH < FAR_FUTURE_EPOCH
|
||||
static: doAssert ConsensusFork.high == ConsensusFork.Deneb
|
||||
doAssert network.cfg.ELECTRA_FORK_EPOCH == FAR_FUTURE_EPOCH
|
||||
static: doAssert ConsensusFork.high == ConsensusFork.Electra
|
||||
|
||||
elif const_preset == "mainnet":
|
||||
when incbinEnabled:
|
||||
|
@ -340,7 +341,8 @@ elif const_preset == "mainnet":
|
|||
doAssert network.cfg.BELLATRIX_FORK_EPOCH < FAR_FUTURE_EPOCH
|
||||
doAssert network.cfg.CAPELLA_FORK_EPOCH < FAR_FUTURE_EPOCH
|
||||
doAssert network.cfg.DENEB_FORK_EPOCH < FAR_FUTURE_EPOCH
|
||||
static: doAssert ConsensusFork.high == ConsensusFork.Deneb
|
||||
doAssert network.cfg.ELECTRA_FORK_EPOCH == FAR_FUTURE_EPOCH
|
||||
static: doAssert ConsensusFork.high == ConsensusFork.Electra
|
||||
|
||||
proc getMetadataForNetwork*(networkName: string): Eth2NetworkMetadata =
|
||||
template loadRuntimeMetadata(): auto =
|
||||
|
|
|
@ -137,6 +137,9 @@ func getVanityLogs(stdoutKind: StdoutLogKind): VanityLogs =
|
|||
|
||||
func getVanityMascot(consensusFork: ConsensusFork): string =
|
||||
case consensusFork
|
||||
of ConsensusFork.Electra:
|
||||
debugRaiseAssert "getVanityMascot"
|
||||
" "
|
||||
of ConsensusFork.Deneb:
|
||||
"🐟"
|
||||
of ConsensusFork.Capella:
|
||||
|
@ -860,7 +863,8 @@ func forkDigests(node: BeaconNode): auto =
|
|||
node.dag.forkDigests.altair,
|
||||
node.dag.forkDigests.bellatrix,
|
||||
node.dag.forkDigests.capella,
|
||||
node.dag.forkDigests.deneb]
|
||||
node.dag.forkDigests.deneb,
|
||||
node.dag.forkDigests.electra]
|
||||
forkDigestsArray
|
||||
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/phase0/p2p-interface.md#attestation-subnet-subscription
|
||||
|
@ -1293,7 +1297,8 @@ proc updateGossipStatus(node: BeaconNode, slot: Slot) {.async.} =
|
|||
removeAltairMessageHandlers,
|
||||
removeAltairMessageHandlers, # bellatrix (altair handlers, different forkDigest)
|
||||
removeCapellaMessageHandlers,
|
||||
removeDenebMessageHandlers
|
||||
removeDenebMessageHandlers,
|
||||
removeDenebMessageHandlers # Electra (Deneb handler, different forkDigest)
|
||||
]
|
||||
|
||||
for gossipFork in oldGossipForks:
|
||||
|
@ -1304,7 +1309,8 @@ proc updateGossipStatus(node: BeaconNode, slot: Slot) {.async.} =
|
|||
addAltairMessageHandlers,
|
||||
addAltairMessageHandlers, # bellatrix (altair handlers, different forkDigest)
|
||||
addCapellaMessageHandlers,
|
||||
addDenebMessageHandlers
|
||||
addDenebMessageHandlers,
|
||||
addDenebMessageHandlers # Electra (Deneb handler, different forkDigest)
|
||||
]
|
||||
|
||||
for gossipFork in newGossipForks:
|
||||
|
|
|
@ -237,6 +237,9 @@ proc installApiHandlers*(node: SigningNodeRef) =
|
|||
(GeneralizedIndex(401), request.beaconBlockHeader.data)
|
||||
of ConsensusFork.Deneb:
|
||||
(GeneralizedIndex(801), request.beaconBlockHeader.data)
|
||||
of ConsensusFork.Electra:
|
||||
debugRaiseAssert "/api/v1/eth2/sign/{validator_key} TODO verify correctness"
|
||||
(GeneralizedIndex(801), request.beaconBlockHeader.data)
|
||||
|
||||
if request.proofs.isNone() or len(request.proofs.get()) == 0:
|
||||
return errorResponse(Http400, MissingMerkleProofError)
|
||||
|
|
|
@ -929,6 +929,13 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
await node.router.routeSignedBeaconBlock(
|
||||
blck, Opt.some(blck.create_blob_sidecars(
|
||||
restBlock.denebData.kzg_proofs, restBlock.denebData.blobs)))
|
||||
of ConsensusFork.Electra:
|
||||
debugRaiseAssert "/eth/v1/beacon/blocks POST; can't reach here unless in Electra per check above, but this keeps return value consistent"
|
||||
var blck = restBlock.denebData.signed_block
|
||||
blck.root = hash_tree_root(blck.message)
|
||||
await node.router.routeSignedBeaconBlock(
|
||||
blck, Opt.some(blck.create_blob_sidecars(
|
||||
restBlock.denebData.kzg_proofs, restBlock.denebData.blobs)))
|
||||
|
||||
if res.isErr():
|
||||
return RestApiResponse.jsonError(
|
||||
|
@ -1005,6 +1012,13 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
await node.router.routeSignedBeaconBlock(
|
||||
blck, Opt.some(blck.create_blob_sidecars(
|
||||
restBlock.denebData.kzg_proofs, restBlock.denebData.blobs)))
|
||||
of ConsensusFork.Electra:
|
||||
debugRaiseAssert "electra missing; /eth/v2/beacon/blocks will only trigger this codepath when in Electra"
|
||||
var blck = restBlock.denebData.signed_block
|
||||
blck.root = hash_tree_root(blck.message)
|
||||
await node.router.routeSignedBeaconBlock(
|
||||
blck, Opt.some(blck.create_blob_sidecars(
|
||||
restBlock.denebData.kzg_proofs, restBlock.denebData.blobs)))
|
||||
|
||||
if res.isErr():
|
||||
return RestApiResponse.jsonError(
|
||||
|
@ -1051,7 +1065,10 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
RestApiResponse.jsonError(Http500, InvalidAcceptError)
|
||||
|
||||
withBlck(bdata.asSigned()):
|
||||
when consensusFork <= ConsensusFork.Altair:
|
||||
when consensusFork == ConsensusFork.Electra:
|
||||
debugRaiseAssert "/eth/v1/beacon/blinded_block POST"
|
||||
RestApiResponse.jsonError(Http500, "electra missing")
|
||||
elif consensusFork <= ConsensusFork.Altair:
|
||||
respondSszOrJson(forkyBlck, consensusFork)
|
||||
else:
|
||||
respondSszOrJson(toSignedBlindedBeaconBlock(forkyBlck), consensusFork)
|
||||
|
@ -1082,7 +1099,11 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
return RestApiResponse.jsonError(Http400, BlockIncorrectFork)
|
||||
|
||||
withConsensusFork(currentEpochFork):
|
||||
when consensusFork >= ConsensusFork.Capella:
|
||||
when consensusFork >= ConsensusFork.Electra:
|
||||
debugRaiseAssert "/eth/v1/beacon/blinded_blocks POST"
|
||||
return RestApiResponse.jsonError(
|
||||
Http400, $consensusFork & " builder API unsupported")
|
||||
elif consensusFork >= ConsensusFork.Capella:
|
||||
let
|
||||
restBlock = decodeBodyJsonOrSsz(
|
||||
consensusFork.SignedBlindedBeaconBlock, body).valueOr:
|
||||
|
|
|
@ -408,7 +408,13 @@ proc installValidatorApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
return
|
||||
withBlck(message.blck):
|
||||
let data =
|
||||
when consensusFork >= ConsensusFork.Deneb:
|
||||
when consensusFork >= ConsensusFork.Electra:
|
||||
debugRaiseAssert "/eth/v2/validator/blocks/{slot} GET"
|
||||
let blobsBundle = message.blobsBundleOpt.get()
|
||||
deneb.BlockContents(
|
||||
kzg_proofs: blobsBundle.proofs,
|
||||
blobs: blobsBundle.blobs)
|
||||
elif consensusFork >= ConsensusFork.Deneb:
|
||||
let blobsBundle = message.blobsBundleOpt.get()
|
||||
deneb.BlockContents(
|
||||
`block`: forkyBlck,
|
||||
|
@ -522,7 +528,11 @@ proc installValidatorApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
contextFork = node.dag.cfg.consensusForkAtEpoch(node.currentSlot.epoch)
|
||||
|
||||
withConsensusFork(contextFork):
|
||||
when consensusFork >= ConsensusFork.Capella:
|
||||
when consensusFork >= ConsensusFork.Electra:
|
||||
debugRaiseAssert "/eth/v1/validator/blinded_blocks/{slot} GET 1"
|
||||
return RestApiResponse.jsonError(
|
||||
Http400, "Electra builder API not yet supported")
|
||||
elif consensusFork >= ConsensusFork.Capella:
|
||||
let res = await makeBlindedBeaconBlockForHeadAndSlot[
|
||||
consensusFork.BlindedBeaconBlock](
|
||||
node, payloadBuilderClient, qrandao,
|
||||
|
@ -541,6 +551,10 @@ proc installValidatorApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
if res.isErr():
|
||||
return RestApiResponse.jsonError(Http400, res.error())
|
||||
withBlck(res.get().blck):
|
||||
when consensusFork >= ConsensusFork.Electra:
|
||||
debugRaiseAssert "/eth/v1/validator/blinded_blocks/{slot} GET 2"
|
||||
return RestApiResponse.jsonError(Http400, "")
|
||||
else:
|
||||
return responseVersioned(forkyBlck, contextFork)
|
||||
|
||||
func getMaybeBlindedHeaders(
|
||||
|
@ -632,7 +646,10 @@ proc installValidatorApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
return RestApiResponse.jsonError(Http400, InvalidRandaoRevealValue)
|
||||
|
||||
withConsensusFork(node.dag.cfg.consensusForkAtEpoch(qslot.epoch)):
|
||||
when consensusFork >= ConsensusFork.Capella:
|
||||
when consensusFork >= ConsensusFork.Electra:
|
||||
debugRaiseAssert "/eth/v3/validator/blocks/{slot} GET 1"
|
||||
return RestApiResponse.jsonError(Http500, "")
|
||||
elif consensusFork >= ConsensusFork.Capella:
|
||||
let
|
||||
message = (await node.makeMaybeBlindedBeaconBlockForHeadAndSlot(
|
||||
consensusFork, qrandao, qgraffiti, qhead, qslot)).valueOr:
|
||||
|
|
|
@ -84,8 +84,8 @@ func get_validator_churn_limit*(
|
|||
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.7/specs/deneb/beacon-chain.md#new-get_validator_activation_churn_limit
|
||||
func get_validator_activation_churn_limit*(
|
||||
cfg: RuntimeConfig, state: deneb.BeaconState, cache: var StateCache):
|
||||
uint64 =
|
||||
cfg: RuntimeConfig, state: deneb.BeaconState | electra.BeaconState,
|
||||
cache: var StateCache): uint64 =
|
||||
## Return the validator activation churn limit for the current epoch.
|
||||
min(
|
||||
cfg.MAX_PER_EPOCH_ACTIVATION_CHURN_LIMIT,
|
||||
|
@ -154,7 +154,7 @@ func get_slashing_penalty*(state: ForkyBeaconState,
|
|||
elif state is altair.BeaconState:
|
||||
validator_effective_balance div MIN_SLASHING_PENALTY_QUOTIENT_ALTAIR
|
||||
elif state is bellatrix.BeaconState or state is capella.BeaconState or
|
||||
state is deneb.BeaconState:
|
||||
state is deneb.BeaconState or state is electra.BeaconState:
|
||||
validator_effective_balance div MIN_SLASHING_PENALTY_QUOTIENT_BELLATRIX
|
||||
else:
|
||||
{.fatal: "invalid BeaconState type".}
|
||||
|
@ -172,7 +172,8 @@ func get_proposer_reward(state: ForkyBeaconState, whistleblower_reward: Gwei): G
|
|||
when state is phase0.BeaconState:
|
||||
whistleblower_reward div PROPOSER_REWARD_QUOTIENT
|
||||
elif state is altair.BeaconState or state is bellatrix.BeaconState or
|
||||
state is capella.BeaconState or state is deneb.BeaconState:
|
||||
state is capella.BeaconState or state is deneb.BeaconState or
|
||||
state is electra.BeaconState:
|
||||
whistleblower_reward * PROPOSER_WEIGHT div WEIGHT_DENOMINATOR
|
||||
else:
|
||||
{.fatal: "invalid BeaconState type".}
|
||||
|
@ -292,6 +293,20 @@ func get_initial_beacon_block*(state: deneb.HashedBeaconState):
|
|||
deneb.TrustedSignedBeaconBlock(
|
||||
message: message, root: hash_tree_root(message))
|
||||
|
||||
from ./datatypes/electra import HashedBeaconState, TrustedSignedBeaconBlock
|
||||
|
||||
# TODO spec link here when it exists
|
||||
func get_initial_beacon_block*(state: electra.HashedBeaconState):
|
||||
electra.TrustedSignedBeaconBlock =
|
||||
# The genesis block is implicitly trusted
|
||||
let message = electra.TrustedBeaconBlock(
|
||||
slot: state.data.slot,
|
||||
state_root: state.root)
|
||||
# parent_root, randao_reveal, eth1_data, signature, and body automatically
|
||||
# initialized to default values.
|
||||
electra.TrustedSignedBeaconBlock(
|
||||
message: message, root: hash_tree_root(message))
|
||||
|
||||
func get_initial_beacon_block*(state: ForkedHashedBeaconState):
|
||||
ForkedTrustedSignedBeaconBlock =
|
||||
withState(state):
|
||||
|
@ -549,7 +564,7 @@ func get_attestation_participation_flag_indices(
|
|||
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.7/specs/deneb/beacon-chain.md#modified-get_attestation_participation_flag_indices
|
||||
func get_attestation_participation_flag_indices(
|
||||
state: deneb.BeaconState,
|
||||
state: deneb.BeaconState | electra.BeaconState,
|
||||
data: AttestationData, inclusion_delay: uint64): set[TimelyFlag] =
|
||||
## Return the flag indices that are satisfied by an attestation.
|
||||
let justified_checkpoint =
|
||||
|
@ -613,7 +628,7 @@ func get_base_reward_per_increment*(
|
|||
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.7/specs/altair/beacon-chain.md#get_base_reward
|
||||
func get_base_reward(
|
||||
state: altair.BeaconState | bellatrix.BeaconState | capella.BeaconState |
|
||||
deneb.BeaconState,
|
||||
deneb.BeaconState | electra.BeaconState,
|
||||
index: ValidatorIndex, base_reward_per_increment: Gwei): Gwei =
|
||||
## Return the base reward for the validator defined by ``index`` with respect
|
||||
## to the current ``state``.
|
||||
|
@ -658,7 +673,8 @@ proc check_attestation*(
|
|||
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/capella/beacon-chain.md#new-process_bls_to_execution_change
|
||||
proc check_bls_to_execution_change*(
|
||||
genesisFork: Fork, state: capella.BeaconState | deneb.BeaconState,
|
||||
genesisFork: Fork,
|
||||
state: capella.BeaconState | deneb.BeaconState | electra.BeaconState,
|
||||
signed_address_change: SignedBLSToExecutionChange, flags: UpdateFlags):
|
||||
Result[void, cstring] =
|
||||
let address_change = signed_address_change.message
|
||||
|
@ -746,7 +762,8 @@ proc process_attestation*(
|
|||
else:
|
||||
addPendingAttestation(state.previous_epoch_attestations)
|
||||
elif state is altair.BeaconState or state is bellatrix.BeaconState or
|
||||
state is capella.BeaconState or state is deneb.BeaconState:
|
||||
state is capella.BeaconState or state is deneb.BeaconState or
|
||||
state is electra.BeaconState:
|
||||
template updateParticipationFlags(epoch_participation: untyped) =
|
||||
let proposer_reward = get_proposer_reward(
|
||||
state, attestation, base_reward_per_increment, cache, epoch_participation)
|
||||
|
@ -765,7 +782,7 @@ proc process_attestation*(
|
|||
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.7/specs/altair/beacon-chain.md#get_next_sync_committee_indices
|
||||
func get_next_sync_committee_keys(
|
||||
state: altair.BeaconState | bellatrix.BeaconState | capella.BeaconState |
|
||||
deneb.BeaconState):
|
||||
deneb.BeaconState | electra.BeaconState):
|
||||
array[SYNC_COMMITTEE_SIZE, ValidatorPubKey] =
|
||||
## Return the sequence of sync committee indices, with possible duplicates,
|
||||
## for the next sync committee.
|
||||
|
@ -825,7 +842,8 @@ func is_partially_withdrawable_validator(
|
|||
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/capella/beacon-chain.md#new-get_expected_withdrawals
|
||||
func get_expected_withdrawals*(
|
||||
state: capella.BeaconState | deneb.BeaconState): seq[Withdrawal] =
|
||||
state: capella.BeaconState | deneb.BeaconState | electra.BeaconState):
|
||||
seq[Withdrawal] =
|
||||
let
|
||||
epoch = get_current_epoch(state)
|
||||
num_validators = lenu64(state.validators)
|
||||
|
@ -862,7 +880,7 @@ func get_expected_withdrawals*(
|
|||
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.7/specs/altair/beacon-chain.md#get_next_sync_committee
|
||||
func get_next_sync_committee*(
|
||||
state: altair.BeaconState | bellatrix.BeaconState | capella.BeaconState |
|
||||
deneb.BeaconState):
|
||||
deneb.BeaconState | electra.BeaconState):
|
||||
SyncCommittee =
|
||||
## Return the next sync committee, with possible pubkey duplicates.
|
||||
var res: SyncCommittee
|
||||
|
@ -1436,7 +1454,7 @@ func latest_block_root*(state: ForkedHashedBeaconState): Eth2Digest =
|
|||
|
||||
func get_sync_committee_cache*(
|
||||
state: altair.BeaconState | bellatrix.BeaconState | capella.BeaconState |
|
||||
deneb.BeaconState,
|
||||
deneb.BeaconState | electra.BeaconState,
|
||||
cache: var StateCache): SyncCommitteeCache =
|
||||
let period = state.slot.sync_committee_period()
|
||||
|
||||
|
|
|
@ -603,6 +603,7 @@ func kzg_commitment_inclusion_proof_gindex*(
|
|||
# The first member (`randao_reveal`) is 16, subsequent members +1 each.
|
||||
# If there are ever more than 16 members in `BeaconBlockBody`, indices change!
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.7/ssz/merkle-proofs.md
|
||||
debugRaiseAssert "kzg_commitment_inclusion_proof_gindex; ensure still applies to Electra after whatever changes happen"
|
||||
const
|
||||
# blob_kzg_commitments
|
||||
BLOB_KZG_COMMITMENTS_GINDEX =
|
||||
|
|
|
@ -608,6 +608,8 @@ proc jsonResponseBlock*(t: typedesc[RestApiResponse],
|
|||
writer.writeField("execution_optimistic", execOpt.get())
|
||||
writer.writeField("finalized", finalized)
|
||||
withBlck(data):
|
||||
debugRaiseAssert "jsonResponseBlock: ForkedSignedBeaconBlock"
|
||||
when consensusFork != ConsensusFork.Electra:
|
||||
writer.writeField("data", forkyBlck)
|
||||
writer.endRecord()
|
||||
stream.getOutput(seq[byte])
|
||||
|
@ -633,6 +635,8 @@ proc jsonResponseState*(t: typedesc[RestApiResponse],
|
|||
if execOpt.isSome():
|
||||
writer.writeField("execution_optimistic", execOpt.get())
|
||||
withState(data):
|
||||
debugRaiseAssert "jsonResponseBlock: ForkedHashedBeaconState"
|
||||
when consensusFork != ConsensusFork.Electra:
|
||||
writer.writeField("data", forkyState.data)
|
||||
writer.endRecord()
|
||||
stream.getOutput(seq[byte])
|
||||
|
@ -1559,6 +1563,9 @@ proc readValue*[BlockType: ProduceBlockResponseV2](
|
|||
reader.raiseUnexpectedValue("Incorrect deneb block format")
|
||||
value = ProduceBlockResponseV2(kind: ConsensusFork.Deneb,
|
||||
denebData: res.get())
|
||||
of ConsensusFork.Electra:
|
||||
debugRaiseAssert "readValue ProduceBlockResponseV2"
|
||||
reader.raiseUnexpectedValue("Incorrect electra block format")
|
||||
|
||||
proc readValue*[BlockType: ForkedBlindedBeaconBlock](
|
||||
reader: var JsonReader[RestJson],
|
||||
|
@ -1625,6 +1632,9 @@ proc readValue*[BlockType: ForkedBlindedBeaconBlock](
|
|||
exc.formatMsg("BlindedBlock") & "]")
|
||||
value = ForkedBlindedBeaconBlock(kind: ConsensusFork.Deneb,
|
||||
denebData: res)
|
||||
of ConsensusFork.Electra:
|
||||
debugRaiseAssert "readValue ForkedBlindedBeaconBlock"
|
||||
reader.raiseUnexpectedValue("Electra blinded block format unsupported")
|
||||
|
||||
proc readValue*[BlockType: Web3SignerForkedBeaconBlock](
|
||||
reader: var JsonReader[RestJson],
|
||||
|
@ -1927,6 +1937,8 @@ proc readValue*(reader: var JsonReader[RestJson],
|
|||
assign(
|
||||
value.denebBody.execution_payload.excess_blob_gas,
|
||||
ep_src.excess_blob_gas.get())
|
||||
of ConsensusFork.Electra:
|
||||
debugRaiseAssert "readValue"
|
||||
|
||||
## RestPublishedBeaconBlock
|
||||
proc readValue*(reader: var JsonReader[RestJson],
|
||||
|
@ -2033,6 +2045,16 @@ proc readValue*(reader: var JsonReader[RestJson],
|
|||
body: body.denebBody
|
||||
)
|
||||
)
|
||||
of ConsensusFork.Electra:
|
||||
ForkedBeaconBlock.init(
|
||||
electra.BeaconBlock(
|
||||
slot: slot.get(),
|
||||
proposer_index: proposer_index.get(),
|
||||
parent_root: parent_root.get(),
|
||||
state_root: state_root.get(),
|
||||
body: body.electraBody
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
## RestPublishedSignedBeaconBlock
|
||||
|
@ -2099,6 +2121,13 @@ proc readValue*(reader: var JsonReader[RestJson],
|
|||
signature: signature.get()
|
||||
)
|
||||
)
|
||||
of ConsensusFork.Electra:
|
||||
ForkedSignedBeaconBlock.init(
|
||||
electra.SignedBeaconBlock(
|
||||
message: blck.electraData,
|
||||
signature: signature.get()
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
proc readValue*(reader: var JsonReader[RestJson],
|
||||
|
@ -2156,6 +2185,8 @@ proc readValue*(reader: var JsonReader[RestJson],
|
|||
reader.raiseUnexpectedValue("Incorrect signed_block format")
|
||||
of ConsensusFork.Deneb:
|
||||
ForkedBeaconBlock.init(blck.denebData.message)
|
||||
of ConsensusFork.Electra:
|
||||
ForkedBeaconBlock.init(blck.electraData.message)
|
||||
))
|
||||
of "kzg_proofs":
|
||||
if kzg_proofs.isSome():
|
||||
|
@ -2243,6 +2274,16 @@ proc readValue*(reader: var JsonReader[RestJson],
|
|||
blobs: blobs.get()
|
||||
)
|
||||
)
|
||||
of ConsensusFork.Electra:
|
||||
value = RestPublishedSignedBlockContents(
|
||||
kind: ConsensusFork.Electra,
|
||||
electraData: ElectraSignedBlockContents(
|
||||
# Constructed to be internally consistent
|
||||
signed_block: signed_message.get().distinctBase.electraData,
|
||||
kzg_proofs: kzg_proofs.get(),
|
||||
blobs: blobs.get()
|
||||
)
|
||||
)
|
||||
|
||||
## ForkedSignedBeaconBlock
|
||||
proc readValue*(reader: var JsonReader[RestJson],
|
||||
|
@ -2346,6 +2387,9 @@ proc readValue*(reader: var JsonReader[RestJson],
|
|||
if res.isNone():
|
||||
reader.raiseUnexpectedValue("Incorrect deneb block format")
|
||||
value = ForkedSignedBeaconBlock.init(res.get())
|
||||
of ConsensusFork.Electra:
|
||||
debugRaiseAssert "readValue 3"
|
||||
reader.raiseUnexpectedValue("Incorrect electra block format")
|
||||
withBlck(value):
|
||||
forkyBlck.root = hash_tree_root(forkyBlck.message)
|
||||
|
||||
|
@ -2369,6 +2413,10 @@ proc writeValue*(
|
|||
of ConsensusFork.Deneb:
|
||||
writer.writeField("version", "deneb")
|
||||
writer.writeField("data", value.denebData)
|
||||
of ConsensusFork.Electra:
|
||||
writer.writeField("version", "electra")
|
||||
debugRaiseAssert "writeValue ForkedSignedBeaconBlock"
|
||||
#writer.writeField("data", value.electraData)
|
||||
writer.endRecord()
|
||||
|
||||
# ForkedHashedBeaconState is used where a `ForkedBeaconState` normally would
|
||||
|
@ -2472,6 +2520,9 @@ proc readValue*(reader: var JsonReader[RestJson],
|
|||
except SerializationError:
|
||||
reader.raiseUnexpectedValue("Incorrect deneb beacon state format")
|
||||
toValue(denebData)
|
||||
of ConsensusFork.Electra:
|
||||
debugRaiseAssert "readValue ForkedHashedBeaconState"
|
||||
reader.raiseUnexpectedValue("Incorrect electra beacon state format")
|
||||
|
||||
proc writeValue*(
|
||||
writer: var JsonWriter[RestJson], value: ForkedHashedBeaconState
|
||||
|
@ -2493,6 +2544,10 @@ proc writeValue*(
|
|||
of ConsensusFork.Deneb:
|
||||
writer.writeField("version", "deneb")
|
||||
writer.writeField("data", value.denebData.data)
|
||||
of ConsensusFork.Electra:
|
||||
writer.writeField("version", "electra")
|
||||
debugRaiseAssert "writeValue ForkedHashedBeaconState"
|
||||
#writer.writeField("data", value.electraData.data)
|
||||
writer.endRecord()
|
||||
|
||||
## SomeForkedLightClientObject
|
||||
|
@ -3405,6 +3460,8 @@ proc writeValue*(writer: var JsonWriter[RestJson],
|
|||
value: ProduceBlockResponseV3) {.raises: [IOError].} =
|
||||
writer.beginRecord()
|
||||
withForkyMaybeBlindedBlck(value):
|
||||
debugRaiseAssert "writeValue ProduceBlockResponseV3"
|
||||
when consensusFork != ConsensusFork.Electra:
|
||||
writer.writeField("version", consensusFork.toString())
|
||||
when isBlinded:
|
||||
writer.writeField("execution_payload_blinded", "true")
|
||||
|
@ -3442,7 +3499,9 @@ proc readValue*(reader: var JsonReader[RestJson],
|
|||
reader.raiseUnexpectedValue("Field `data` is missing")
|
||||
|
||||
withConsensusFork(version.get):
|
||||
when consensusFork >= ConsensusFork.Capella:
|
||||
when consensusFork >= ConsensusFork.Electra:
|
||||
debugRaiseAssert "readValue ProduceBlockResponseV3"
|
||||
elif consensusFork >= ConsensusFork.Capella:
|
||||
if blinded.get:
|
||||
value = ForkedMaybeBlindedBeaconBlock.init(
|
||||
RestJson.decode(
|
||||
|
@ -3560,6 +3619,10 @@ proc decodeBody*(
|
|||
return err(RestErrorMessage.init(Http400, UnexpectedDecodeError,
|
||||
[version, $exc.msg]))
|
||||
ok(RestPublishedSignedBeaconBlock(ForkedSignedBeaconBlock.init(blck)))
|
||||
of ConsensusFork.Electra:
|
||||
debugRaiseAssert "decodeBody RestPublishedSignedBeaconBlock"
|
||||
return err(RestErrorMessage.init(Http400, UnexpectedDecodeError,
|
||||
[version]))
|
||||
else:
|
||||
err(RestErrorMessage.init(Http415, "Invalid content type",
|
||||
[version, $body.contentType]))
|
||||
|
@ -3650,6 +3713,10 @@ proc decodeBody*(
|
|||
[version, $exc.msg]))
|
||||
ok(RestPublishedSignedBlockContents(
|
||||
kind: ConsensusFork.Deneb, denebData: blckContents))
|
||||
of ConsensusFork.Electra:
|
||||
debugRaiseAssert "decodeBody RestPublishedSignedBlockContents"
|
||||
return err(RestErrorMessage.init(
|
||||
Http400, "electra missing", [version]))
|
||||
else:
|
||||
err(RestErrorMessage.init(Http415, "Invalid content type",
|
||||
[version, $body.contentType]))
|
||||
|
@ -3779,6 +3846,11 @@ proc decodeBodyJsonOrSsz*(
|
|||
[version, $exc.msg]))
|
||||
ok(RestPublishedSignedBlockContents(
|
||||
kind: ConsensusFork.Deneb, denebData: blckContents))
|
||||
of ConsensusFork.Electra:
|
||||
debugRaiseAssert "decodeBodyJsonOrSsz RestPublishedSignedBlockContents"
|
||||
return err(
|
||||
RestErrorMessage.init(Http400, "electra missing",
|
||||
[version]))
|
||||
else:
|
||||
err(RestErrorMessage.init(Http415, "Invalid content type",
|
||||
[version, $body.contentType]))
|
||||
|
@ -3922,6 +3994,9 @@ proc decodeBytes*[T: DecodeConsensysTypes](
|
|||
let fork = ConsensusFork.decodeString(consensusVersion).valueOr:
|
||||
return err("Invalid or Unsupported consensus version")
|
||||
case fork
|
||||
of ConsensusFork.Electra:
|
||||
debugRaiseAssert "decodeBytes, DecodeConsensysTypes"
|
||||
return err("Invalid or Unsupported consensus version")
|
||||
of ConsensusFork.Deneb:
|
||||
let blckContents = ? readSszResBytes(deneb.BlockContents, value)
|
||||
ok(ProduceBlockResponseV2(kind: ConsensusFork.Deneb,
|
||||
|
@ -3946,6 +4021,9 @@ proc decodeBytes*[T: DecodeConsensysTypes](
|
|||
let fork = ConsensusFork.decodeString(consensusVersion).valueOr:
|
||||
return err("Invalid or Unsupported consensus version")
|
||||
case fork
|
||||
of ConsensusFork.Electra:
|
||||
debugRaiseAssert "decodeBytes DecodeConsensysTypes"
|
||||
err("Unable to decode blinded block for Electra fork")
|
||||
of ConsensusFork.Deneb:
|
||||
let
|
||||
blck = ? readSszResBytes(deneb_mev.BlindedBeaconBlock, value)
|
||||
|
@ -4018,7 +4096,10 @@ proc decodeBytes*[T: ProduceBlockResponseV3](
|
|||
except ValueError:
|
||||
return err("Incorrect `Eth-Consensus-Block-Value` header value")
|
||||
withConsensusFork(fork):
|
||||
when consensusFork >= ConsensusFork.Capella:
|
||||
when consensusFork >= ConsensusFork.Electra:
|
||||
debugRaiseAssert "decodeBytes ProduceBlockV3"
|
||||
return err("decodeBytes ProduceBlockV3")
|
||||
elif consensusFork >= ConsensusFork.Capella:
|
||||
if blinded:
|
||||
let contents =
|
||||
? readSszResBytes(consensusFork.BlindedBlockContents, value)
|
||||
|
|
|
@ -17,7 +17,7 @@ import
|
|||
std/[json, tables],
|
||||
stew/base10, web3/primitives, httputils,
|
||||
".."/forks,
|
||||
".."/datatypes/[phase0, altair, bellatrix, deneb],
|
||||
".."/datatypes/[phase0, altair, bellatrix, deneb, electra],
|
||||
".."/mev/[capella_mev, deneb_mev]
|
||||
|
||||
from ".."/datatypes/capella import BeaconBlockBody
|
||||
|
@ -331,6 +331,11 @@ type
|
|||
kzg_proofs*: deneb.KzgProofs
|
||||
blobs*: deneb.Blobs
|
||||
|
||||
ElectraSignedBlockContents* = object
|
||||
signed_block*: electra.SignedBeaconBlock
|
||||
kzg_proofs*: deneb.KzgProofs
|
||||
blobs*: deneb.Blobs
|
||||
|
||||
RestPublishedSignedBlockContents* = object
|
||||
case kind*: ConsensusFork
|
||||
of ConsensusFork.Phase0: phase0Data*: phase0.SignedBeaconBlock
|
||||
|
@ -338,6 +343,7 @@ type
|
|||
of ConsensusFork.Bellatrix: bellatrixData*: bellatrix.SignedBeaconBlock
|
||||
of ConsensusFork.Capella: capellaData*: capella.SignedBeaconBlock
|
||||
of ConsensusFork.Deneb: denebData*: DenebSignedBlockContents
|
||||
of ConsensusFork.Electra: electraData*: ElectraSignedBlockContents
|
||||
|
||||
RestPublishedBeaconBlock* = distinct ForkedBeaconBlock
|
||||
|
||||
|
@ -348,6 +354,7 @@ type
|
|||
of ConsensusFork.Bellatrix: bellatrixBody*: bellatrix.BeaconBlockBody
|
||||
of ConsensusFork.Capella: capellaBody*: capella.BeaconBlockBody
|
||||
of ConsensusFork.Deneb: denebBody*: deneb.BeaconBlockBody
|
||||
of ConsensusFork.Electra: electraBody*: electra.BeaconBlockBody
|
||||
|
||||
ProduceBlockResponseV2* = object
|
||||
case kind*: ConsensusFork
|
||||
|
@ -356,6 +363,7 @@ type
|
|||
of ConsensusFork.Bellatrix: bellatrixData*: bellatrix.BeaconBlock
|
||||
of ConsensusFork.Capella: capellaData*: capella.BeaconBlock
|
||||
of ConsensusFork.Deneb: denebData*: deneb.BlockContents
|
||||
of ConsensusFork.Electra: electraData*: electra.BlockContents
|
||||
|
||||
ProduceBlockResponseV3* = ForkedMaybeBlindedBeaconBlock
|
||||
|
||||
|
@ -632,6 +640,8 @@ func init*(T: type ForkedSignedBeaconBlock,
|
|||
ForkedSignedBeaconBlock.init(contents.capellaData)
|
||||
of ConsensusFork.Deneb:
|
||||
ForkedSignedBeaconBlock.init(contents.denebData.signed_block)
|
||||
of ConsensusFork.Electra:
|
||||
ForkedSignedBeaconBlock.init(contents.electraData.signed_block)
|
||||
|
||||
func init*(t: typedesc[RestPublishedSignedBlockContents],
|
||||
blck: phase0.BeaconBlock, root: Eth2Digest,
|
||||
|
@ -689,6 +699,12 @@ func init*(t: typedesc[RestPublishedSignedBlockContents],
|
|||
)
|
||||
)
|
||||
|
||||
func init*(t: typedesc[RestPublishedSignedBlockContents],
|
||||
contents: electra.BeaconBlock, root: Eth2Digest,
|
||||
signature: ValidatorSig): RestPublishedSignedBlockContents =
|
||||
debugRaiseAssert "init*(t: typedesc[RestPublishedSignedBlockContents],"
|
||||
default(RestPublishedSignedBlockContents)
|
||||
|
||||
func init*(t: typedesc[StateIdent], v: StateIdentType): StateIdent =
|
||||
StateIdent(kind: StateQueryKind.Named, value: v)
|
||||
|
||||
|
@ -1025,3 +1041,7 @@ template withBlck*(x: ProduceBlockResponseV2,
|
|||
const consensusFork {.inject, used.} = ConsensusFork.Deneb
|
||||
template blck: untyped {.inject.} = x.denebData.blck
|
||||
body
|
||||
of ConsensusFork.Electra:
|
||||
const consensusFork {.inject, used.} = ConsensusFork.Electra
|
||||
template blck: untyped {.inject.} = x.electraData.blck
|
||||
body
|
||||
|
|
|
@ -46,7 +46,8 @@ type
|
|||
Altair,
|
||||
Bellatrix,
|
||||
Capella,
|
||||
Deneb
|
||||
Deneb,
|
||||
Electra
|
||||
|
||||
ForkyBeaconState* =
|
||||
phase0.BeaconState |
|
||||
|
@ -71,6 +72,7 @@ type
|
|||
of ConsensusFork.Bellatrix: bellatrixData*: bellatrix.HashedBeaconState
|
||||
of ConsensusFork.Capella: capellaData*: capella.HashedBeaconState
|
||||
of ConsensusFork.Deneb: denebData*: deneb.HashedBeaconState
|
||||
of ConsensusFork.Electra: electraData*: electra.HashedBeaconState
|
||||
|
||||
ForkyExecutionPayload* =
|
||||
bellatrix.ExecutionPayload |
|
||||
|
@ -158,6 +160,7 @@ type
|
|||
of ConsensusFork.Bellatrix: bellatrixData*: bellatrix.BeaconBlock
|
||||
of ConsensusFork.Capella: capellaData*: capella.BeaconBlock
|
||||
of ConsensusFork.Deneb: denebData*: deneb.BeaconBlock
|
||||
of ConsensusFork.Electra: electraData*: electra.BeaconBlock
|
||||
|
||||
ForkedMaybeBlindedBeaconBlock* = object
|
||||
case kind*: ConsensusFork
|
||||
|
@ -171,6 +174,8 @@ type
|
|||
capellaData*: capella_mev.MaybeBlindedBeaconBlock
|
||||
of ConsensusFork.Deneb:
|
||||
denebData*: deneb_mev.MaybeBlindedBeaconBlock
|
||||
of ConsensusFork.Electra:
|
||||
electraData*: electra.BeaconBlock
|
||||
consensusValue*: Opt[UInt256]
|
||||
executionValue*: Opt[UInt256]
|
||||
|
||||
|
@ -185,6 +190,7 @@ type
|
|||
of ConsensusFork.Bellatrix: bellatrixData*: bellatrix_mev.BlindedBeaconBlock
|
||||
of ConsensusFork.Capella: capellaData*: capella_mev.BlindedBeaconBlock
|
||||
of ConsensusFork.Deneb: denebData*: deneb_mev.BlindedBeaconBlock
|
||||
of ConsensusFork.Electra: electraData*: electra.BeaconBlock
|
||||
|
||||
ForkedTrustedBeaconBlock* = object
|
||||
case kind*: ConsensusFork
|
||||
|
@ -193,6 +199,7 @@ type
|
|||
of ConsensusFork.Bellatrix: bellatrixData*: bellatrix.TrustedBeaconBlock
|
||||
of ConsensusFork.Capella: capellaData*: capella.TrustedBeaconBlock
|
||||
of ConsensusFork.Deneb: denebData*: deneb.TrustedBeaconBlock
|
||||
of ConsensusFork.Electra: electraData*: electra.TrustedBeaconBlock
|
||||
|
||||
ForkySignedBeaconBlock* =
|
||||
phase0.SignedBeaconBlock |
|
||||
|
@ -209,6 +216,7 @@ type
|
|||
of ConsensusFork.Bellatrix: bellatrixData*: bellatrix.SignedBeaconBlock
|
||||
of ConsensusFork.Capella: capellaData*: capella.SignedBeaconBlock
|
||||
of ConsensusFork.Deneb: denebData*: deneb.SignedBeaconBlock
|
||||
of ConsensusFork.Electra: electraData*: electra.SignedBeaconBlock
|
||||
|
||||
ForkySignedBlindedBeaconBlock* =
|
||||
phase0.SignedBeaconBlock |
|
||||
|
@ -224,6 +232,7 @@ type
|
|||
of ConsensusFork.Bellatrix: bellatrixData*: bellatrix_mev.SignedBlindedBeaconBlock
|
||||
of ConsensusFork.Capella: capellaData*: capella_mev.SignedBlindedBeaconBlock
|
||||
of ConsensusFork.Deneb: denebData*: deneb_mev.SignedBlindedBeaconBlock
|
||||
of ConsensusFork.Electra: electraData*: electra.SignedBeaconBlock
|
||||
|
||||
ForkySigVerifiedSignedBeaconBlock* =
|
||||
phase0.SigVerifiedSignedBeaconBlock |
|
||||
|
@ -256,6 +265,7 @@ type
|
|||
of ConsensusFork.Bellatrix: bellatrixData*: bellatrix.MsgTrustedSignedBeaconBlock
|
||||
of ConsensusFork.Capella: capellaData*: capella.MsgTrustedSignedBeaconBlock
|
||||
of ConsensusFork.Deneb: denebData*: deneb.MsgTrustedSignedBeaconBlock
|
||||
of ConsensusFork.Electra: electraData*: electra.MsgTrustedSignedBeaconBlock
|
||||
|
||||
ForkedTrustedSignedBeaconBlock* = object
|
||||
case kind*: ConsensusFork
|
||||
|
@ -264,6 +274,7 @@ type
|
|||
of ConsensusFork.Bellatrix: bellatrixData*: bellatrix.TrustedSignedBeaconBlock
|
||||
of ConsensusFork.Capella: capellaData*: capella.TrustedSignedBeaconBlock
|
||||
of ConsensusFork.Deneb: denebData*: deneb.TrustedSignedBeaconBlock
|
||||
of ConsensusFork.Electra: electraData*: electra.TrustedSignedBeaconBlock
|
||||
|
||||
SomeForkySignedBeaconBlock* =
|
||||
ForkySignedBeaconBlock |
|
||||
|
@ -377,8 +388,28 @@ template kind*(
|
|||
deneb_mev.SignedBlindedBeaconBlock]): ConsensusFork =
|
||||
ConsensusFork.Deneb
|
||||
|
||||
template kind*(
|
||||
x: typedesc[
|
||||
electra.BeaconState |
|
||||
electra.HashedBeaconState |
|
||||
electra.ExecutionPayload |
|
||||
electra.ExecutionPayloadForSigning |
|
||||
electra.ExecutionPayloadHeader |
|
||||
electra.BeaconBlock |
|
||||
electra.SignedBeaconBlock |
|
||||
electra.TrustedBeaconBlock |
|
||||
electra.BeaconBlockBody |
|
||||
electra.SigVerifiedBeaconBlockBody |
|
||||
electra.TrustedBeaconBlockBody |
|
||||
electra.SigVerifiedSignedBeaconBlock |
|
||||
electra.MsgTrustedSignedBeaconBlock |
|
||||
electra.TrustedSignedBeaconBlock]): ConsensusFork =
|
||||
ConsensusFork.Electra
|
||||
|
||||
template BeaconState*(kind: static ConsensusFork): auto =
|
||||
when kind == ConsensusFork.Deneb:
|
||||
when kind == ConsensusFork.Electra:
|
||||
typedesc[electra.BeaconState]
|
||||
elif kind == ConsensusFork.Deneb:
|
||||
typedesc[deneb.BeaconState]
|
||||
elif kind == ConsensusFork.Capella:
|
||||
typedesc[capella.BeaconState]
|
||||
|
@ -392,7 +423,9 @@ template BeaconState*(kind: static ConsensusFork): auto =
|
|||
static: raiseAssert "Unreachable"
|
||||
|
||||
template BeaconBlock*(kind: static ConsensusFork): auto =
|
||||
when kind == ConsensusFork.Deneb:
|
||||
when kind == ConsensusFork.Electra:
|
||||
typedesc[electra.BeaconBlock]
|
||||
elif kind == ConsensusFork.Deneb:
|
||||
typedesc[deneb.BeaconBlock]
|
||||
elif kind == ConsensusFork.Capella:
|
||||
typedesc[capella.BeaconBlock]
|
||||
|
@ -406,7 +439,9 @@ template BeaconBlock*(kind: static ConsensusFork): auto =
|
|||
static: raiseAssert "Unreachable"
|
||||
|
||||
template BeaconBlockBody*(kind: static ConsensusFork): auto =
|
||||
when kind == ConsensusFork.Deneb:
|
||||
when kind == ConsensusFork.Electra:
|
||||
typedesc[electra.BeaconBlockBody]
|
||||
elif kind == ConsensusFork.Deneb:
|
||||
typedesc[deneb.BeaconBlockBody]
|
||||
elif kind == ConsensusFork.Capella:
|
||||
typedesc[capella.BeaconBlockBody]
|
||||
|
@ -420,7 +455,9 @@ template BeaconBlockBody*(kind: static ConsensusFork): auto =
|
|||
static: raiseAssert "Unreachable"
|
||||
|
||||
template SignedBeaconBlock*(kind: static ConsensusFork): auto =
|
||||
when kind == ConsensusFork.Deneb:
|
||||
when kind == ConsensusFork.Electra:
|
||||
typedesc[electra.SignedBeaconBlock]
|
||||
elif kind == ConsensusFork.Deneb:
|
||||
typedesc[deneb.SignedBeaconBlock]
|
||||
elif kind == ConsensusFork.Capella:
|
||||
typedesc[capella.SignedBeaconBlock]
|
||||
|
@ -434,7 +471,9 @@ template SignedBeaconBlock*(kind: static ConsensusFork): auto =
|
|||
static: raiseAssert "Unreachable"
|
||||
|
||||
template TrustedSignedBeaconBlock*(kind: static ConsensusFork): auto =
|
||||
when kind == ConsensusFork.Deneb:
|
||||
when kind == ConsensusFork.Electra:
|
||||
typedesc[electra.TrustedSignedBeaconBlock]
|
||||
elif kind == ConsensusFork.Deneb:
|
||||
typedesc[deneb.TrustedSignedBeaconBlock]
|
||||
elif kind == ConsensusFork.Capella:
|
||||
typedesc[capella.TrustedSignedBeaconBlock]
|
||||
|
@ -448,7 +487,9 @@ template TrustedSignedBeaconBlock*(kind: static ConsensusFork): auto =
|
|||
static: raiseAssert "Unreachable"
|
||||
|
||||
template ExecutionPayloadForSigning*(kind: static ConsensusFork): auto =
|
||||
when kind == ConsensusFork.Deneb:
|
||||
when kind == ConsensusFork.Electra:
|
||||
typedesc[electra.ExecutionPayloadForSigning]
|
||||
elif kind == ConsensusFork.Deneb:
|
||||
typedesc[deneb.ExecutionPayloadForSigning]
|
||||
elif kind == ConsensusFork.Capella:
|
||||
typedesc[capella.ExecutionPayloadForSigning]
|
||||
|
@ -489,7 +530,10 @@ template SignedBlindedBeaconBlock*(kind: static ConsensusFork): auto =
|
|||
|
||||
template withAll*(
|
||||
x: typedesc[ConsensusFork], body: untyped): untyped =
|
||||
static: doAssert ConsensusFork.high == ConsensusFork.Deneb
|
||||
static: doAssert ConsensusFork.high == ConsensusFork.Electra
|
||||
block:
|
||||
const consensusFork {.inject, used.} = ConsensusFork.Electra
|
||||
body
|
||||
block:
|
||||
const consensusFork {.inject, used.} = ConsensusFork.Deneb
|
||||
body
|
||||
|
@ -509,6 +553,9 @@ template withAll*(
|
|||
template withConsensusFork*(
|
||||
x: ConsensusFork, body: untyped): untyped =
|
||||
case x
|
||||
of ConsensusFork.Electra:
|
||||
const consensusFork {.inject, used.} = ConsensusFork.Electra
|
||||
body
|
||||
of ConsensusFork.Deneb:
|
||||
const consensusFork {.inject, used.} = ConsensusFork.Deneb
|
||||
body
|
||||
|
@ -567,8 +614,9 @@ template PayloadAttributes*(
|
|||
{.error: "PayloadAttributes does not support " & $kind.}
|
||||
|
||||
# `eth2_merkleization` cannot import `forks` (circular), so the check is here
|
||||
static: doAssert ConsensusFork.high == ConsensusFork.Deneb,
|
||||
"eth2_merkleization has been checked and `hash_tree_root` is up to date"
|
||||
debugRaiseAssert "eth2_merkleization has been checked and `hash_tree_root` is up to date"
|
||||
static: doAssert ConsensusFork.high == ConsensusFork.Electra,
|
||||
"eth2_merkleization has been checked and `hash_tree_root` is up to date" # TODO
|
||||
|
||||
# TODO when https://github.com/nim-lang/Nim/issues/21086 fixed, use return type
|
||||
# `ref T`
|
||||
|
@ -592,6 +640,10 @@ func new*(T: type ForkedHashedBeaconState, data: deneb.BeaconState):
|
|||
ref ForkedHashedBeaconState =
|
||||
(ref T)(kind: ConsensusFork.Deneb, denebData: deneb.HashedBeaconState(
|
||||
data: data, root: hash_tree_root(data)))
|
||||
func new*(T: type ForkedHashedBeaconState, data: electra.BeaconState):
|
||||
ref ForkedHashedBeaconState =
|
||||
(ref T)(kind: ConsensusFork.Electra, electraData: electra.HashedBeaconState(
|
||||
data: data, root: hash_tree_root(data)))
|
||||
|
||||
template init*(T: type ForkedBeaconBlock, blck: phase0.BeaconBlock): T =
|
||||
T(kind: ConsensusFork.Phase0, phase0Data: blck)
|
||||
|
@ -603,7 +655,10 @@ template init*(T: type ForkedBeaconBlock, blck: capella.BeaconBlock): T =
|
|||
T(kind: ConsensusFork.Capella, capellaData: blck)
|
||||
template init*(T: type ForkedBeaconBlock, blck: deneb.BeaconBlock): T =
|
||||
T(kind: ConsensusFork.Deneb, denebData: blck)
|
||||
template init*(T: type ForkedBeaconBlock, blck: electra.BeaconBlock): T =
|
||||
T(kind: ConsensusFork.Electra, electraData: blck)
|
||||
|
||||
# TODO are these still used?
|
||||
template init*(T: type ForkedTrustedBeaconBlock, blck: phase0.TrustedBeaconBlock): T =
|
||||
T(kind: ConsensusFork.Phase0, phase0Data: blck)
|
||||
template init*(T: type ForkedTrustedBeaconBlock, blck: altair.TrustedBeaconBlock): T =
|
||||
|
@ -623,6 +678,8 @@ template init*(T: type ForkedSignedBeaconBlock, blck: capella.SignedBeaconBlock)
|
|||
T(kind: ConsensusFork.Capella, capellaData: blck)
|
||||
template init*(T: type ForkedSignedBeaconBlock, blck: deneb.SignedBeaconBlock): T =
|
||||
T(kind: ConsensusFork.Deneb, denebData: blck)
|
||||
template init*(T: type ForkedSignedBeaconBlock, blck: electra.SignedBeaconBlock): T =
|
||||
T(kind: ConsensusFork.Electra, electraData: blck)
|
||||
|
||||
func init*(T: type ForkedSignedBeaconBlock, forked: ForkedBeaconBlock,
|
||||
blockRoot: Eth2Digest, signature: ValidatorSig): T =
|
||||
|
@ -652,6 +709,11 @@ func init*(T: type ForkedSignedBeaconBlock, forked: ForkedBeaconBlock,
|
|||
denebData: deneb.SignedBeaconBlock(message: forked.denebData,
|
||||
root: blockRoot,
|
||||
signature: signature))
|
||||
of ConsensusFork.Electra:
|
||||
T(kind: ConsensusFork.Electra,
|
||||
electraData: electra.SignedBeaconBlock(message: forked.electraData,
|
||||
root: blockRoot,
|
||||
signature: signature))
|
||||
|
||||
func init*(T: type ForkedSignedBlindedBeaconBlock,
|
||||
forked: ForkedBlindedBeaconBlock, blockRoot: Eth2Digest,
|
||||
|
@ -678,6 +740,9 @@ func init*(T: type ForkedSignedBlindedBeaconBlock,
|
|||
T(kind: ConsensusFork.Deneb,
|
||||
denebData: deneb_mev.SignedBlindedBeaconBlock(message: forked.denebData,
|
||||
signature: signature))
|
||||
of ConsensusFork.Electra:
|
||||
debugRaiseAssert "init*(T: type ForkedSignedBlindedBeaconBlock"
|
||||
T(kind: ConsensusFork.Electra)
|
||||
|
||||
template init*(T: type ForkedSignedBlindedBeaconBlock,
|
||||
blck: capella_mev.BlindedBeaconBlock, blockRoot: Eth2Digest,
|
||||
|
@ -703,6 +768,8 @@ template init*(T: type ForkedMsgTrustedSignedBeaconBlock, blck: capella.MsgTrust
|
|||
T(kind: ConsensusFork.Capella, capellaData: blck)
|
||||
template init*(T: type ForkedMsgTrustedSignedBeaconBlock, blck: deneb.MsgTrustedSignedBeaconBlock): T =
|
||||
T(kind: ConsensusFork.Deneb, denebData: blck)
|
||||
template init*(T: type ForkedMsgTrustedSignedBeaconBlock, blck: electra.MsgTrustedSignedBeaconBlock): T =
|
||||
T(kind: ConsensusFork.Electra, electraData: blck)
|
||||
|
||||
template init*(T: type ForkedTrustedSignedBeaconBlock, blck: phase0.TrustedSignedBeaconBlock): T =
|
||||
T(kind: ConsensusFork.Phase0, phase0Data: blck)
|
||||
|
@ -714,6 +781,8 @@ template init*(T: type ForkedTrustedSignedBeaconBlock, blck: capella.TrustedSign
|
|||
T(kind: ConsensusFork.Capella, capellaData: blck)
|
||||
template init*(T: type ForkedTrustedSignedBeaconBlock, blck: deneb.TrustedSignedBeaconBlock): T =
|
||||
T(kind: ConsensusFork.Deneb, denebData: blck)
|
||||
template init*(T: type ForkedTrustedSignedBeaconBlock, blck: electra.TrustedSignedBeaconBlock): T =
|
||||
T(kind: ConsensusFork.Electra, electraData: blck)
|
||||
|
||||
template toString*(kind: ConsensusFork): string =
|
||||
case kind
|
||||
|
@ -727,9 +796,13 @@ template toString*(kind: ConsensusFork): string =
|
|||
"capella"
|
||||
of ConsensusFork.Deneb:
|
||||
"deneb"
|
||||
of ConsensusFork.Electra:
|
||||
"electra"
|
||||
|
||||
template init*(T: typedesc[ConsensusFork], value: string): Opt[ConsensusFork] =
|
||||
case value
|
||||
of "electra":
|
||||
Opt.some ConsensusFork.Electra
|
||||
of "deneb":
|
||||
Opt.some ConsensusFork.Deneb
|
||||
of "capella":
|
||||
|
@ -754,6 +827,10 @@ template init*(T: type ForkedEpochInfo, info: altair.EpochInfo): T =
|
|||
|
||||
template withState*(x: ForkedHashedBeaconState, body: untyped): untyped =
|
||||
case x.kind
|
||||
of ConsensusFork.Electra:
|
||||
const consensusFork {.inject, used.} = ConsensusFork.Electra
|
||||
template forkyState: untyped {.inject, used.} = x.electraData
|
||||
body
|
||||
of ConsensusFork.Deneb:
|
||||
const consensusFork {.inject, used.} = ConsensusFork.Deneb
|
||||
template forkyState: untyped {.inject, used.} = x.denebData
|
||||
|
@ -780,7 +857,9 @@ template forky*(
|
|||
ForkedBeaconBlock |
|
||||
ForkedHashedBeaconState,
|
||||
kind: static ConsensusFork): untyped =
|
||||
when kind == ConsensusFork.Deneb:
|
||||
when kind == ConsensusFork.Electra:
|
||||
x.electraData
|
||||
elif kind == ConsensusFork.Deneb:
|
||||
x.denebData
|
||||
elif kind == ConsensusFork.Capella:
|
||||
x.capellaData
|
||||
|
@ -855,6 +934,8 @@ func setStateRoot*(x: var ForkedHashedBeaconState, root: Eth2Digest) =
|
|||
func consensusForkEpoch*(
|
||||
cfg: RuntimeConfig, consensusFork: ConsensusFork): Epoch =
|
||||
case consensusFork
|
||||
of ConsensusFork.Electra:
|
||||
cfg.ELECTRA_FORK_EPOCH
|
||||
of ConsensusFork.Deneb:
|
||||
cfg.DENEB_FORK_EPOCH
|
||||
of ConsensusFork.Capella:
|
||||
|
@ -869,14 +950,16 @@ func consensusForkEpoch*(
|
|||
func consensusForkAtEpoch*(cfg: RuntimeConfig, epoch: Epoch): ConsensusFork =
|
||||
## Return the current fork for the given epoch.
|
||||
static:
|
||||
doAssert high(ConsensusFork) == ConsensusFork.Deneb
|
||||
doAssert high(ConsensusFork) == ConsensusFork.Electra
|
||||
doAssert ConsensusFork.Electra > ConsensusFork.Deneb
|
||||
doAssert ConsensusFork.Deneb > ConsensusFork.Capella
|
||||
doAssert ConsensusFork.Capella > ConsensusFork.Bellatrix
|
||||
doAssert ConsensusFork.Bellatrix > ConsensusFork.Altair
|
||||
doAssert ConsensusFork.Altair > ConsensusFork.Phase0
|
||||
doAssert GENESIS_EPOCH == 0
|
||||
|
||||
if epoch >= cfg.DENEB_FORK_EPOCH: ConsensusFork.Deneb
|
||||
if epoch >= cfg.ELECTRA_FORK_EPOCH: ConsensusFork.Electra
|
||||
elif epoch >= cfg.DENEB_FORK_EPOCH: ConsensusFork.Deneb
|
||||
elif epoch >= cfg.CAPELLA_FORK_EPOCH: ConsensusFork.Capella
|
||||
elif epoch >= cfg.BELLATRIX_FORK_EPOCH: ConsensusFork.Bellatrix
|
||||
elif epoch >= cfg.ALTAIR_FORK_EPOCH: ConsensusFork.Altair
|
||||
|
@ -884,8 +967,10 @@ func consensusForkAtEpoch*(cfg: RuntimeConfig, epoch: Epoch): ConsensusFork =
|
|||
|
||||
func consensusForkForDigest*(
|
||||
forkDigests: ForkDigests, forkDigest: ForkDigest): Opt[ConsensusFork] =
|
||||
static: doAssert high(ConsensusFork) == ConsensusFork.Deneb
|
||||
if forkDigest == forkDigests.deneb:
|
||||
static: doAssert high(ConsensusFork) == ConsensusFork.Electra
|
||||
if forkDigest == forkDigests.electra:
|
||||
ok ConsensusFork.Electra
|
||||
elif forkDigest == forkDigests.deneb:
|
||||
ok ConsensusFork.Deneb
|
||||
elif forkDigest == forkDigests.capella:
|
||||
ok ConsensusFork.Capella
|
||||
|
@ -901,6 +986,8 @@ func consensusForkForDigest*(
|
|||
func atConsensusFork*(
|
||||
forkDigests: ForkDigests, consensusFork: ConsensusFork): ForkDigest =
|
||||
case consensusFork
|
||||
of ConsensusFork.Electra:
|
||||
forkDigests.electra
|
||||
of ConsensusFork.Deneb:
|
||||
forkDigests.deneb
|
||||
of ConsensusFork.Capella:
|
||||
|
@ -979,6 +1066,10 @@ template withBlck*(
|
|||
const consensusFork {.inject, used.} = ConsensusFork.Deneb
|
||||
template forkyBlck: untyped {.inject, used.} = x.denebData
|
||||
body
|
||||
of ConsensusFork.Electra:
|
||||
const consensusFork {.inject, used.} = ConsensusFork.Electra
|
||||
template forkyBlck: untyped {.inject, used.} = x.electraData
|
||||
body
|
||||
|
||||
func proposer_index*(x: ForkedBeaconBlock): uint64 =
|
||||
withBlck(x): forkyBlck.proposer_index
|
||||
|
@ -1002,7 +1093,8 @@ template getForkedBlockField*(
|
|||
of ConsensusFork.Altair: unsafeAddr x.altairData.message.y
|
||||
of ConsensusFork.Bellatrix: unsafeAddr x.bellatrixData.message.y
|
||||
of ConsensusFork.Capella: unsafeAddr x.capellaData.message.y
|
||||
of ConsensusFork.Deneb: unsafeAddr x.denebData.message.y)[]
|
||||
of ConsensusFork.Deneb: unsafeAddr x.denebData.message.y
|
||||
of ConsensusFork.Electra: unsafeAddr x.electraData.message.y)[]
|
||||
|
||||
template signature*(x: ForkedSignedBeaconBlock |
|
||||
ForkedMsgTrustedSignedBeaconBlock |
|
||||
|
@ -1040,6 +1132,12 @@ template withForkyMaybeBlindedBlck*(
|
|||
b: ForkedMaybeBlindedBeaconBlock,
|
||||
body: untyped): untyped =
|
||||
case b.kind
|
||||
of ConsensusFork.Electra:
|
||||
const
|
||||
consensusFork {.inject, used.} = ConsensusFork.Electra
|
||||
isBlinded {.inject, used.} = false
|
||||
template forkyMaybeBlindedBlck: untyped {.inject, used.} = b.electraData
|
||||
body
|
||||
of ConsensusFork.Deneb:
|
||||
const consensusFork {.inject, used.} = ConsensusFork.Deneb
|
||||
template d: untyped = b.denebData
|
||||
|
@ -1090,6 +1188,11 @@ template withStateAndBlck*(
|
|||
ForkedTrustedSignedBeaconBlock,
|
||||
body: untyped): untyped =
|
||||
case s.kind
|
||||
of ConsensusFork.Electra:
|
||||
const consensusFork {.inject, used.} = ConsensusFork.Electra
|
||||
template forkyState: untyped {.inject.} = s.electraData
|
||||
template forkyBlck: untyped {.inject.} = b.electraData
|
||||
body
|
||||
of ConsensusFork.Deneb:
|
||||
const consensusFork {.inject, used.} = ConsensusFork.Deneb
|
||||
template forkyState: untyped {.inject.} = s.denebData
|
||||
|
@ -1188,6 +1291,7 @@ func electraFork*(cfg: RuntimeConfig): Fork =
|
|||
|
||||
func forkAtEpoch*(cfg: RuntimeConfig, epoch: Epoch): Fork =
|
||||
case cfg.consensusForkAtEpoch(epoch)
|
||||
of ConsensusFork.Electra: cfg.electraFork
|
||||
of ConsensusFork.Deneb: cfg.denebFork
|
||||
of ConsensusFork.Capella: cfg.capellaFork
|
||||
of ConsensusFork.Bellatrix: cfg.bellatrixFork
|
||||
|
@ -1196,6 +1300,7 @@ func forkAtEpoch*(cfg: RuntimeConfig, epoch: Epoch): Fork =
|
|||
|
||||
func forkVersionAtEpoch*(cfg: RuntimeConfig, epoch: Epoch): Version =
|
||||
case cfg.consensusForkAtEpoch(epoch)
|
||||
of ConsensusFork.Electra: cfg.ELECTRA_FORK_VERSION
|
||||
of ConsensusFork.Deneb: cfg.DENEB_FORK_VERSION
|
||||
of ConsensusFork.Capella: cfg.CAPELLA_FORK_VERSION
|
||||
of ConsensusFork.Bellatrix: cfg.BELLATRIX_FORK_VERSION
|
||||
|
@ -1203,9 +1308,9 @@ func forkVersionAtEpoch*(cfg: RuntimeConfig, epoch: Epoch): Version =
|
|||
of ConsensusFork.Phase0: cfg.GENESIS_FORK_VERSION
|
||||
|
||||
func nextForkEpochAtEpoch*(cfg: RuntimeConfig, epoch: Epoch): Epoch =
|
||||
static: doAssert high(ConsensusFork) == ConsensusFork.Deneb
|
||||
case cfg.consensusForkAtEpoch(epoch)
|
||||
of ConsensusFork.Deneb: FAR_FUTURE_EPOCH
|
||||
of ConsensusFork.Electra: FAR_FUTURE_EPOCH
|
||||
of ConsensusFork.Deneb: cfg.ELECTRA_FORK_EPOCH
|
||||
of ConsensusFork.Capella: cfg.DENEB_FORK_EPOCH
|
||||
of ConsensusFork.Bellatrix: cfg.CAPELLA_FORK_EPOCH
|
||||
of ConsensusFork.Altair: cfg.BELLATRIX_FORK_EPOCH
|
||||
|
@ -1218,6 +1323,7 @@ func forkVersion*(cfg: RuntimeConfig, consensusFork: ConsensusFork): Version =
|
|||
of ConsensusFork.Bellatrix: cfg.BELLATRIX_FORK_VERSION
|
||||
of ConsensusFork.Capella: cfg.CAPELLA_FORK_VERSION
|
||||
of ConsensusFork.Deneb: cfg.DENEB_FORK_VERSION
|
||||
of ConsensusFork.Electra: cfg.ELECTRA_FORK_VERSION
|
||||
|
||||
func lcDataForkAtConsensusFork*(
|
||||
consensusFork: ConsensusFork): LightClientDataFork =
|
||||
|
@ -1325,7 +1431,7 @@ func compute_fork_digest*(current_version: Version,
|
|||
func init*(T: type ForkDigests,
|
||||
cfg: RuntimeConfig,
|
||||
genesis_validators_root: Eth2Digest): T =
|
||||
static: doAssert high(ConsensusFork) == ConsensusFork.Deneb
|
||||
static: doAssert high(ConsensusFork) == ConsensusFork.Electra
|
||||
T(
|
||||
phase0:
|
||||
compute_fork_digest(cfg.GENESIS_FORK_VERSION, genesis_validators_root),
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
{.push raises: [].}
|
||||
|
||||
import
|
||||
./datatypes/[phase0, altair, bellatrix, capella, deneb],
|
||||
./datatypes/[phase0, altair, bellatrix, capella, deneb, electra],
|
||||
./eth2_merkleization
|
||||
|
||||
type
|
||||
|
@ -957,9 +957,14 @@ func toLightClientHeader*(
|
|||
altair.SignedBeaconBlock | altair.TrustedSignedBeaconBlock |
|
||||
bellatrix.SignedBeaconBlock | bellatrix.TrustedSignedBeaconBlock |
|
||||
capella.SignedBeaconBlock | capella.TrustedSignedBeaconBlock |
|
||||
deneb.SignedBeaconBlock | deneb.TrustedSignedBeaconBlock,
|
||||
deneb.SignedBeaconBlock | deneb.TrustedSignedBeaconBlock |
|
||||
electra.SignedBeaconBlock | electra.TrustedSignedBeaconBlock,
|
||||
kind: static LightClientDataFork): auto =
|
||||
when kind == LightClientDataFork.Deneb:
|
||||
when blck is electra.SignedBeaconBlock or
|
||||
blck is electra.TrustedSignedBeaconBlock:
|
||||
debugRaiseAssert "toLightClientHeader"
|
||||
default(deneb.LightClientHeader)
|
||||
elif kind == LightClientDataFork.Deneb:
|
||||
blck.toDenebLightClientHeader()
|
||||
elif kind == LightClientDataFork.Capella:
|
||||
blck.toCapellaLightClientHeader()
|
||||
|
|
|
@ -228,7 +228,7 @@ func verify_blob_sidecar_inclusion_proof*(
|
|||
ok()
|
||||
|
||||
func create_blob_sidecars*(
|
||||
forkyBlck: deneb.SignedBeaconBlock,
|
||||
forkyBlck: deneb.SignedBeaconBlock | electra.SignedBeaconBlock,
|
||||
kzg_proofs: KzgProofs,
|
||||
blobs: Blobs): seq[BlobSidecar] =
|
||||
template kzg_commitments: untyped =
|
||||
|
@ -382,7 +382,8 @@ func contextEpoch*(update: SomeForkyLightClientUpdate): Epoch =
|
|||
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.7/specs/bellatrix/beacon-chain.md#is_merge_transition_complete
|
||||
func is_merge_transition_complete*(
|
||||
state: bellatrix.BeaconState | capella.BeaconState | deneb.BeaconState): bool =
|
||||
state: bellatrix.BeaconState | capella.BeaconState | deneb.BeaconState |
|
||||
electra.BeaconState): bool =
|
||||
const defaultExecutionPayloadHeader =
|
||||
default(typeof(state.latest_execution_payload_header))
|
||||
state.latest_execution_payload_header != defaultExecutionPayloadHeader
|
||||
|
@ -398,26 +399,32 @@ func is_execution_block*(blck: SomeForkyBeaconBlock): bool =
|
|||
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.7/specs/bellatrix/beacon-chain.md#is_merge_transition_block
|
||||
func is_merge_transition_block(
|
||||
state: bellatrix.BeaconState | capella.BeaconState | deneb.BeaconState,
|
||||
state: bellatrix.BeaconState | capella.BeaconState | deneb.BeaconState |
|
||||
electra.BeaconState,
|
||||
body: bellatrix.BeaconBlockBody | bellatrix.TrustedBeaconBlockBody |
|
||||
bellatrix.SigVerifiedBeaconBlockBody |
|
||||
capella.BeaconBlockBody | capella.TrustedBeaconBlockBody |
|
||||
capella.SigVerifiedBeaconBlockBody |
|
||||
deneb.BeaconBlockBody | deneb.TrustedBeaconBlockBody |
|
||||
deneb.SigVerifiedBeaconBlockBody): bool =
|
||||
deneb.SigVerifiedBeaconBlockBody |
|
||||
electra.BeaconBlockBody | electra.TrustedBeaconBlockBody |
|
||||
electra.SigVerifiedBeaconBlockBody): bool =
|
||||
const defaultExecutionPayload = default(typeof(body.execution_payload))
|
||||
not is_merge_transition_complete(state) and
|
||||
body.execution_payload != defaultExecutionPayload
|
||||
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.7/specs/bellatrix/beacon-chain.md#is_execution_enabled
|
||||
func is_execution_enabled*(
|
||||
state: bellatrix.BeaconState | capella.BeaconState | deneb.BeaconState,
|
||||
state: bellatrix.BeaconState | capella.BeaconState | deneb.BeaconState |
|
||||
electra.BeaconState,
|
||||
body: bellatrix.BeaconBlockBody | bellatrix.TrustedBeaconBlockBody |
|
||||
bellatrix.SigVerifiedBeaconBlockBody |
|
||||
capella.BeaconBlockBody | capella.TrustedBeaconBlockBody |
|
||||
capella.SigVerifiedBeaconBlockBody |
|
||||
deneb.BeaconBlockBody | deneb.TrustedBeaconBlockBody |
|
||||
deneb.SigVerifiedBeaconBlockBody): bool =
|
||||
deneb.SigVerifiedBeaconBlockBody |
|
||||
electra.BeaconBlockBody | electra.TrustedBeaconBlockBody |
|
||||
electra.SigVerifiedBeaconBlockBody): bool =
|
||||
is_merge_transition_block(state, body) or is_merge_transition_complete(state)
|
||||
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.7/specs/bellatrix/beacon-chain.md#compute_timestamp_at_slot
|
||||
|
@ -449,8 +456,8 @@ func toExecutionWithdrawal*(
|
|||
|
||||
# https://eips.ethereum.org/EIPS/eip-4895
|
||||
proc computeWithdrawalsTrieRoot*(
|
||||
payload: capella.ExecutionPayload | deneb.ExecutionPayload
|
||||
): ExecutionHash256 =
|
||||
payload: capella.ExecutionPayload | deneb.ExecutionPayload |
|
||||
electra.ExecutionPayload): ExecutionHash256 =
|
||||
if payload.withdrawals.len == 0:
|
||||
return EMPTY_ROOT_HASH
|
||||
|
||||
|
|
|
@ -159,18 +159,15 @@ func noRollback*(state: var altair.HashedBeaconState) =
|
|||
func noRollback*(state: var bellatrix.HashedBeaconState) =
|
||||
trace "Skipping rollback of broken Bellatrix state"
|
||||
|
||||
from ./datatypes/capella import
|
||||
ExecutionPayload, HashedBeaconState, SignedBLSToExecutionChangeList,
|
||||
asSigVerified
|
||||
|
||||
func noRollback*(state: var capella.HashedBeaconState) =
|
||||
trace "Skipping rollback of broken Capella state"
|
||||
|
||||
from ./datatypes/deneb import HashedBeaconState
|
||||
|
||||
func noRollback*(state: var deneb.HashedBeaconState) =
|
||||
trace "Skipping rollback of broken Deneb state"
|
||||
|
||||
func noRollback*(state: var electra.HashedBeaconState) =
|
||||
trace "Skipping rollback of broken Electra state"
|
||||
|
||||
func maybeUpgradeStateToAltair(
|
||||
cfg: RuntimeConfig, state: var ForkedHashedBeaconState) =
|
||||
# Both process_slots() and state_transition_block() call this, so only run it
|
||||
|
@ -225,6 +222,7 @@ func maybeUpgradeState*(
|
|||
cfg.maybeUpgradeStateToBellatrix(state)
|
||||
cfg.maybeUpgradeStateToCapella(state)
|
||||
cfg.maybeUpgradeStateToDeneb(state)
|
||||
# TODO cfg.maybeUpgradeStateToElectra
|
||||
|
||||
proc process_slots*(
|
||||
cfg: RuntimeConfig, state: var ForkedHashedBeaconState, slot: Slot,
|
||||
|
@ -477,6 +475,8 @@ proc makeBeaconBlock*(
|
|||
])
|
||||
else:
|
||||
raiseAssert "Attempt to use non-Deneb payload with post-Deneb state"
|
||||
elif consensusFork == ConsensusFork.Electra:
|
||||
debugRaiseAssert "makeBeaconBlock"
|
||||
else:
|
||||
static: raiseAssert "Unreachable"
|
||||
|
||||
|
@ -501,6 +501,10 @@ proc makeBeaconBlock*(
|
|||
case state.kind
|
||||
of ConsensusFork.Deneb: makeBeaconBlock(deneb)
|
||||
else: raiseAssert "Attempt to use Deneb payload with non-Deneb state"
|
||||
elif payloadFork == ConsensusFork.Electra:
|
||||
case state.kind
|
||||
of ConsensusFork.Electra: makeBeaconBlock(electra)
|
||||
else: raiseAssert "Attempt to use Electra payload with non-Electra state"
|
||||
else:
|
||||
{.error: "Unsupported fork".}
|
||||
|
||||
|
|
|
@ -415,7 +415,8 @@ proc process_voluntary_exit*(
|
|||
ok()
|
||||
|
||||
proc process_bls_to_execution_change*(
|
||||
cfg: RuntimeConfig, state: var (capella.BeaconState | deneb.BeaconState),
|
||||
cfg: RuntimeConfig,
|
||||
state: var (capella.BeaconState | deneb.BeaconState | electra.BeaconState),
|
||||
signed_address_change: SignedBLSToExecutionChange): Result[void, cstring] =
|
||||
? check_bls_to_execution_change(
|
||||
cfg.genesisFork, state, signed_address_change, {})
|
||||
|
@ -486,7 +487,7 @@ func get_proposer_reward*(participant_reward: Gwei): Gwei =
|
|||
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.7/specs/altair/beacon-chain.md#sync-aggregate-processing
|
||||
proc process_sync_aggregate*(
|
||||
state: var (altair.BeaconState | bellatrix.BeaconState |
|
||||
capella.BeaconState | deneb.BeaconState),
|
||||
capella.BeaconState | deneb.BeaconState | electra.BeaconState),
|
||||
sync_aggregate: SomeSyncAggregate, total_active_balance: Gwei,
|
||||
flags: UpdateFlags,
|
||||
cache: var StateCache):
|
||||
|
@ -687,10 +688,67 @@ proc process_execution_payload*(
|
|||
|
||||
ok()
|
||||
|
||||
# TODO workaround for https://github.com/nim-lang/Nim/issues/18095
|
||||
# copy of datatypes/electra.nim
|
||||
type SomeElectraBeaconBlockBody =
|
||||
electra.BeaconBlockBody | electra.SigVerifiedBeaconBlockBody |
|
||||
electra.TrustedBeaconBlockBody
|
||||
|
||||
# TODO spec ref URL when available
|
||||
proc process_execution_payload*(
|
||||
state: var electra.BeaconState, body: SomeElectraBeaconBlockBody,
|
||||
notify_new_payload: electra.ExecutePayload): Result[void, cstring] =
|
||||
template payload: auto = body.execution_payload
|
||||
|
||||
# Verify consistency of the parent hash with respect to the previous
|
||||
# execution payload header
|
||||
if not (payload.parent_hash ==
|
||||
state.latest_execution_payload_header.block_hash):
|
||||
return err("process_execution_payload: payload and state parent hash mismatch")
|
||||
|
||||
# Verify prev_randao
|
||||
if not (payload.prev_randao == get_randao_mix(state, get_current_epoch(state))):
|
||||
return err("process_execution_payload: payload and state randomness mismatch")
|
||||
|
||||
# Verify timestamp
|
||||
if not (payload.timestamp == compute_timestamp_at_slot(state, state.slot)):
|
||||
return err("process_execution_payload: invalid timestamp")
|
||||
|
||||
# [New in Deneb] Verify commitments are under limit
|
||||
if not (lenu64(body.blob_kzg_commitments) <= MAX_BLOBS_PER_BLOCK):
|
||||
return err("process_execution_payload: too many KZG commitments")
|
||||
|
||||
# Verify the execution payload is valid
|
||||
if not notify_new_payload(payload):
|
||||
return err("process_execution_payload: execution payload invalid")
|
||||
|
||||
# Cache execution payload header
|
||||
state.latest_execution_payload_header = electra.ExecutionPayloadHeader(
|
||||
parent_hash: payload.parent_hash,
|
||||
fee_recipient: payload.fee_recipient,
|
||||
state_root: payload.state_root,
|
||||
receipts_root: payload.receipts_root,
|
||||
logs_bloom: payload.logs_bloom,
|
||||
prev_randao: payload.prev_randao,
|
||||
block_number: payload.block_number,
|
||||
gas_limit: payload.gas_limit,
|
||||
gas_used: payload.gas_used,
|
||||
timestamp: payload.timestamp,
|
||||
base_fee_per_gas: payload.base_fee_per_gas,
|
||||
block_hash: payload.block_hash,
|
||||
extra_data: payload.extra_data,
|
||||
transactions_root: hash_tree_root(payload.transactions),
|
||||
withdrawals_root: hash_tree_root(payload.withdrawals),
|
||||
blob_gas_used: payload.blob_gas_used,
|
||||
excess_blob_gas: payload.excess_blob_gas)
|
||||
|
||||
ok()
|
||||
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.7/specs/capella/beacon-chain.md#new-process_withdrawals
|
||||
func process_withdrawals*(
|
||||
state: var (capella.BeaconState | deneb.BeaconState),
|
||||
payload: capella.ExecutionPayload | deneb.ExecutionPayload):
|
||||
state: var (capella.BeaconState | deneb.BeaconState | electra.BeaconState),
|
||||
payload: capella.ExecutionPayload | deneb.ExecutionPayload |
|
||||
electra.ExecutionPayload):
|
||||
Result[void, cstring] =
|
||||
let expected_withdrawals = get_expected_withdrawals(state)
|
||||
|
||||
|
@ -902,3 +960,38 @@ proc process_block*(
|
|||
state, blck.body.sync_aggregate, total_active_balance, flags, cache)
|
||||
|
||||
ok()
|
||||
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.3.0/specs/deneb/beacon-chain.md#block-processing
|
||||
# TODO workaround for https://github.com/nim-lang/Nim/issues/18095
|
||||
type SomeElectraBlock =
|
||||
electra.BeaconBlock | electra.SigVerifiedBeaconBlock | electra.TrustedBeaconBlock
|
||||
proc process_block*(
|
||||
cfg: RuntimeConfig,
|
||||
state: var electra.BeaconState, blck: SomeElectraBlock,
|
||||
flags: UpdateFlags, cache: var StateCache): Result[void, cstring]=
|
||||
## When there's a new block, we need to verify that the block is sane and
|
||||
## update the state accordingly - the state is left in an unknown state when
|
||||
## block application fails (!)
|
||||
|
||||
? process_block_header(state, blck, flags, cache)
|
||||
|
||||
# Consensus specs v1.4.0 unconditionally assume is_execution_enabled is
|
||||
# true, but intentionally keep such a check.
|
||||
if is_execution_enabled(state, blck.body):
|
||||
? process_withdrawals(state, blck.body.execution_payload)
|
||||
? process_execution_payload(
|
||||
state, blck.body,
|
||||
func(_: electra.ExecutionPayload): bool = true)
|
||||
? process_randao(state, blck.body, flags, cache)
|
||||
? process_eth1_data(state, blck.body)
|
||||
|
||||
let
|
||||
total_active_balance = get_total_active_balance(state, cache)
|
||||
base_reward_per_increment =
|
||||
get_base_reward_per_increment(total_active_balance)
|
||||
? process_operations(
|
||||
cfg, state, blck.body, base_reward_per_increment, flags, cache)
|
||||
? process_sync_aggregate(
|
||||
state, blck.body.sync_aggregate, total_active_balance, flags, cache)
|
||||
|
||||
ok()
|
||||
|
|
|
@ -177,7 +177,8 @@ from ./datatypes/deneb import BeaconState
|
|||
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.7/specs/altair/beacon-chain.md#get_unslashed_participating_indices
|
||||
func get_unslashed_participating_balances*(
|
||||
state: altair.BeaconState | bellatrix.BeaconState | capella.BeaconState |
|
||||
deneb.BeaconState): UnslashedParticipatingBalances =
|
||||
deneb.BeaconState | electra.BeaconState):
|
||||
UnslashedParticipatingBalances =
|
||||
let
|
||||
previous_epoch = get_previous_epoch(state)
|
||||
current_epoch = get_current_epoch(state)
|
||||
|
@ -228,7 +229,7 @@ func get_unslashed_participating_balances*(
|
|||
|
||||
func is_unslashed_participating_index(
|
||||
state: altair.BeaconState | bellatrix.BeaconState | capella.BeaconState |
|
||||
deneb.BeaconState,
|
||||
deneb.BeaconState | electra.BeaconState,
|
||||
flag_index: TimelyFlag, epoch: Epoch, validator_index: ValidatorIndex): bool =
|
||||
doAssert epoch in [get_previous_epoch(state), get_current_epoch(state)]
|
||||
# TODO hoist this conditional
|
||||
|
@ -445,7 +446,7 @@ proc compute_unrealized_finality*(
|
|||
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.7/specs/altair/beacon-chain.md#justification-and-finalization
|
||||
proc process_justification_and_finalization*(
|
||||
state: var (altair.BeaconState | bellatrix.BeaconState |
|
||||
capella.BeaconState | deneb.BeaconState),
|
||||
capella.BeaconState | deneb.BeaconState | electra.BeaconState),
|
||||
balances: UnslashedParticipatingBalances,
|
||||
flags: UpdateFlags = {}) =
|
||||
# Initial FFG checkpoint values have a `0x00` stub for `root`.
|
||||
|
@ -467,7 +468,7 @@ proc process_justification_and_finalization*(
|
|||
|
||||
proc compute_unrealized_finality*(
|
||||
state: altair.BeaconState | bellatrix.BeaconState | capella.BeaconState |
|
||||
deneb.BeaconState): FinalityCheckpoints =
|
||||
deneb.BeaconState | electra.BeaconState): FinalityCheckpoints =
|
||||
if get_current_epoch(state) <= GENESIS_EPOCH + 1:
|
||||
return FinalityCheckpoints(
|
||||
justified: state.current_justified_checkpoint,
|
||||
|
@ -658,7 +659,7 @@ func get_attestation_deltas(
|
|||
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.7/specs/altair/beacon-chain.md#get_base_reward
|
||||
func get_base_reward_increment*(
|
||||
state: altair.BeaconState | bellatrix.BeaconState | capella.BeaconState |
|
||||
deneb.BeaconState,
|
||||
deneb.BeaconState | electra.BeaconState,
|
||||
index: ValidatorIndex, base_reward_per_increment: Gwei): Gwei =
|
||||
## Return the base reward for the validator defined by ``index`` with respect
|
||||
## to the current ``state``.
|
||||
|
@ -669,7 +670,7 @@ func get_base_reward_increment*(
|
|||
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.7/specs/altair/beacon-chain.md#get_flag_index_deltas
|
||||
func get_flag_index_reward*(
|
||||
state: altair.BeaconState | bellatrix.BeaconState | capella.BeaconState |
|
||||
deneb.BeaconState,
|
||||
deneb.BeaconState | electra.BeaconState,
|
||||
base_reward: Gwei, active_increments: Gwei,
|
||||
unslashed_participating_increments: Gwei,
|
||||
weight, finality_delay: uint64): Gwei =
|
||||
|
@ -697,7 +698,7 @@ func get_active_increments*(
|
|||
iterator get_flag_and_inactivity_deltas*(
|
||||
cfg: RuntimeConfig,
|
||||
state: altair.BeaconState | bellatrix.BeaconState | capella.BeaconState |
|
||||
deneb.BeaconState,
|
||||
deneb.BeaconState | electra.BeaconState,
|
||||
base_reward_per_increment: Gwei, info: var altair.EpochInfo,
|
||||
finality_delay: uint64):
|
||||
(ValidatorIndex, Gwei, Gwei, Gwei, Gwei, Gwei, Gwei) =
|
||||
|
@ -807,7 +808,7 @@ func process_rewards_and_penalties*(
|
|||
func process_rewards_and_penalties*(
|
||||
cfg: RuntimeConfig,
|
||||
state: var (altair.BeaconState | bellatrix.BeaconState |
|
||||
capella.BeaconState | deneb.BeaconState),
|
||||
capella.BeaconState | deneb.BeaconState | electra.BeaconState),
|
||||
info: var altair.EpochInfo) =
|
||||
if get_current_epoch(state) == GENESIS_EPOCH:
|
||||
return
|
||||
|
@ -914,7 +915,7 @@ func get_adjusted_total_slashing_balance*(
|
|||
elif state is altair.BeaconState:
|
||||
PROPORTIONAL_SLASHING_MULTIPLIER_ALTAIR
|
||||
elif state is bellatrix.BeaconState or state is capella.BeaconState or
|
||||
state is deneb.BeaconState:
|
||||
state is deneb.BeaconState or state is electra.BeaconState:
|
||||
PROPORTIONAL_SLASHING_MULTIPLIER_BELLATRIX
|
||||
else:
|
||||
{.fatal: "process_slashings: incorrect BeaconState type".}
|
||||
|
@ -1037,7 +1038,8 @@ func process_participation_record_updates*(state: var phase0.BeaconState) =
|
|||
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.7/specs/altair/beacon-chain.md#participation-flags-updates
|
||||
func process_participation_flag_updates*(
|
||||
state: var (altair.BeaconState | bellatrix.BeaconState |
|
||||
capella.BeaconState | deneb.BeaconState)) =
|
||||
capella.BeaconState | deneb.BeaconState |
|
||||
electra.BeaconState)) =
|
||||
state.previous_epoch_participation = state.current_epoch_participation
|
||||
|
||||
const zero = 0.ParticipationFlags
|
||||
|
@ -1051,7 +1053,8 @@ func process_participation_flag_updates*(
|
|||
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.7/specs/altair/beacon-chain.md#sync-committee-updates
|
||||
func process_sync_committee_updates*(
|
||||
state: var (altair.BeaconState | bellatrix.BeaconState |
|
||||
capella.BeaconState | deneb.BeaconState)) =
|
||||
capella.BeaconState | deneb.BeaconState |
|
||||
electra.BeaconState)) =
|
||||
let next_epoch = get_current_epoch(state) + 1
|
||||
if next_epoch.is_sync_committee_period():
|
||||
state.current_sync_committee = state.next_sync_committee
|
||||
|
@ -1060,7 +1063,7 @@ func process_sync_committee_updates*(
|
|||
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.7/specs/altair/beacon-chain.md#inactivity-scores
|
||||
template compute_inactivity_update(
|
||||
state: altair.BeaconState | bellatrix.BeaconState | capella.BeaconState |
|
||||
deneb.BeaconState,
|
||||
deneb.BeaconState | electra.BeaconState,
|
||||
info: altair.EpochInfo, pre_inactivity_score: Gwei): Gwei =
|
||||
if not is_eligible_validator(info.validators[index]):
|
||||
continue
|
||||
|
@ -1086,7 +1089,7 @@ template compute_inactivity_update(
|
|||
func process_inactivity_updates*(
|
||||
cfg: RuntimeConfig,
|
||||
state: var (altair.BeaconState | bellatrix.BeaconState |
|
||||
capella.BeaconState | deneb.BeaconState),
|
||||
capella.BeaconState | deneb.BeaconState | electra.BeaconState),
|
||||
info: altair.EpochInfo) =
|
||||
# Score updates based on previous epoch participation, skip genesis epoch
|
||||
if get_current_epoch(state) == GENESIS_EPOCH:
|
||||
|
@ -1108,7 +1111,7 @@ func process_inactivity_updates*(
|
|||
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/capella/beacon-chain.md#historical-summaries-updates
|
||||
func process_historical_summaries_update*(
|
||||
state: var (capella.BeaconState | deneb.BeaconState)):
|
||||
state: var (capella.BeaconState | deneb.BeaconState | electra.BeaconState)):
|
||||
Result[void, cstring] =
|
||||
# Set historical block root accumulator.
|
||||
let next_epoch = get_current_epoch(state) + 1
|
||||
|
@ -1159,7 +1162,7 @@ proc process_epoch*(
|
|||
func init*(
|
||||
info: var altair.EpochInfo,
|
||||
state: altair.BeaconState | bellatrix.BeaconState | capella.BeaconState |
|
||||
deneb.BeaconState) =
|
||||
deneb.BeaconState | electra.BeaconState) =
|
||||
# init participation, overwriting the full structure
|
||||
info.balances = get_unslashed_participating_balances(state)
|
||||
info.validators.setLen(state.validators.len())
|
||||
|
@ -1229,7 +1232,7 @@ proc process_epoch*(
|
|||
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/capella/beacon-chain.md#epoch-processing
|
||||
proc process_epoch*(
|
||||
cfg: RuntimeConfig,
|
||||
state: var (capella.BeaconState | deneb.BeaconState),
|
||||
state: var (capella.BeaconState | deneb.BeaconState | electra.BeaconState),
|
||||
flags: UpdateFlags, cache: var StateCache, info: var altair.EpochInfo):
|
||||
Result[void, cstring] =
|
||||
let epoch = get_current_epoch(state)
|
||||
|
|
|
@ -2259,6 +2259,9 @@ proc publishBlock*(
|
|||
publishBlock(it, data.capellaData)
|
||||
of ConsensusFork.Deneb:
|
||||
publishBlock(it, data.denebData)
|
||||
of ConsensusFork.Electra:
|
||||
debugRaiseAssert "publishBlock RestPublishedSignedBlockContents; denebData will assert via mismatched case object discriminator"
|
||||
publishBlock(it, data.denebData)
|
||||
do:
|
||||
if apiResponse.isErr():
|
||||
handleCommunicationError()
|
||||
|
@ -2305,6 +2308,9 @@ proc publishBlock*(
|
|||
publishBlock(it, data.capellaData)
|
||||
of ConsensusFork.Deneb:
|
||||
publishBlock(it, data.denebData)
|
||||
of ConsensusFork.Electra:
|
||||
debugRaiseAssert "publishBlock RestPublishedSignedBlockContents; denebData will create invalid case discriminator"
|
||||
publishBlock(it, data.denebData)
|
||||
|
||||
do:
|
||||
if apiResponse.isErr():
|
||||
|
@ -2461,6 +2467,9 @@ proc publishBlindedBlock*(
|
|||
publishBlindedBlock(it, data.capellaData)
|
||||
of ConsensusFork.Deneb:
|
||||
publishBlindedBlock(it, data.denebData)
|
||||
of ConsensusFork.Electra:
|
||||
debugRaiseAssert "publishBlindedBlock ForkedSignedBlindedBeaconBlock; denebData mismatches discriminator"
|
||||
publishBlindedBlock(it, data.denebData)
|
||||
do:
|
||||
if apiResponse.isErr():
|
||||
handleCommunicationError()
|
||||
|
@ -2506,6 +2515,9 @@ proc publishBlindedBlock*(
|
|||
publishBlindedBlock(it, data.capellaData)
|
||||
of ConsensusFork.Deneb:
|
||||
publishBlindedBlock(it, data.denebData)
|
||||
of ConsensusFork.Electra:
|
||||
debugRaiseAssert "publishBlindedBlock ForkedSignedBlindedBeaconBlock; denebData mismatches discriminator"
|
||||
publishBlindedBlock(it, data.denebData)
|
||||
do:
|
||||
if apiResponse.isErr():
|
||||
handleCommunicationError()
|
||||
|
|
|
@ -96,6 +96,9 @@ proc produceBlock(
|
|||
data: ForkedBeaconBlock.init(blck),
|
||||
kzgProofsOpt: Opt.some(kzgProofs),
|
||||
blobsOpt: Opt.some(blobs)))
|
||||
of ConsensusFork.Electra:
|
||||
debugRaiseAssert "produceBlock in block_service.nim"
|
||||
return Opt.none(PreparedBeaconBlock)
|
||||
|
||||
proc produceBlindedBlock(
|
||||
vc: ValidatorClientRef,
|
||||
|
@ -305,8 +308,11 @@ proc publishBlockV3(vc: ValidatorClientRef, currentSlot, slot: Slot,
|
|||
blockRoot = hash_tree_root(
|
||||
when consensusFork < ConsensusFork.Deneb:
|
||||
forkyMaybeBlindedBlck
|
||||
else:
|
||||
elif consensusFork < ConsensusFork.Electra:
|
||||
forkyMaybeBlindedBlck.`block`
|
||||
else:
|
||||
debugRaiseAssert "publishBlockV3 1"
|
||||
default(Attestation)
|
||||
)
|
||||
signingRoot =
|
||||
compute_block_signing_root(fork, genesisRoot, slot, blockRoot)
|
||||
|
@ -318,8 +324,11 @@ proc publishBlockV3(vc: ValidatorClientRef, currentSlot, slot: Slot,
|
|||
blck = shortLog(
|
||||
when consensusFork < ConsensusFork.Deneb:
|
||||
forkyMaybeBlindedBlck
|
||||
else:
|
||||
elif consensusFork < ConsensusFork.Electra:
|
||||
forkyMaybeBlindedBlck.`block`
|
||||
else:
|
||||
debugRaiseAssert "publishBlockV3 2"
|
||||
default(bellatrix.BeaconBlock)
|
||||
)
|
||||
block_root = shortLog(blockRoot)
|
||||
signing_root = shortLog(signingRoot)
|
||||
|
@ -572,6 +581,9 @@ proc publishBlockV2(vc: ValidatorClientRef, currentSlot, slot: Slot,
|
|||
signature: signature),
|
||||
kzg_proofs: preparedBlock.kzgProofsOpt.get,
|
||||
blobs: preparedBlock.blobsOpt.get))
|
||||
of ConsensusFork.Electra:
|
||||
debugRaiseAssert "publishBlockV2 2"
|
||||
default(RestPublishedSignedBlockContents)
|
||||
|
||||
res =
|
||||
try:
|
||||
|
|
|
@ -1316,7 +1316,10 @@ proc proposeBlock(node: BeaconNode,
|
|||
genesis_validators_root, node.config.localBlockValueBoost)
|
||||
|
||||
return withConsensusFork(node.dag.cfg.consensusForkAtEpoch(slot.epoch)):
|
||||
when consensusFork >= ConsensusFork.Capella:
|
||||
when consensusFork >= ConsensusFork.Electra:
|
||||
debugRaiseAssert "proposeBlock; fill in Electra support"
|
||||
default(BlockRef)
|
||||
elif consensusFork >= ConsensusFork.Capella:
|
||||
proposeBlockContinuation(
|
||||
consensusFork.SignedBlindedBeaconBlock,
|
||||
consensusFork.ExecutionPayloadForSigning)
|
||||
|
|
|
@ -565,6 +565,9 @@ proc getBlockSignature*(v: AttachedValidator, fork: Fork,
|
|||
Web3SignerForkedBeaconBlock(kind: ConsensusFork.Deneb,
|
||||
data: blck.denebData.toBeaconBlockHeader),
|
||||
proofs)
|
||||
of ConsensusFork.Electra:
|
||||
debugRaiseAssert "getBlockSignature 2"
|
||||
default(Web3SignerRequest)
|
||||
elif blck is capella_mev.BlindedBeaconBlock:
|
||||
case v.data.remoteType
|
||||
of RemoteSignerType.Web3Signer:
|
||||
|
@ -668,6 +671,9 @@ proc getBlockSignature*(v: AttachedValidator, fork: Fork,
|
|||
Web3SignerForkedBeaconBlock(kind: ConsensusFork.Deneb,
|
||||
data: forkyMaybeBlindedBlck.`block`.toBeaconBlockHeader),
|
||||
proofs)
|
||||
elif consensusFork == ConsensusFork.Electra:
|
||||
debugRaiseAssert "getBlockSignature 1"
|
||||
default(Web3SignerRequest)
|
||||
else:
|
||||
case blck.kind
|
||||
of ConsensusFork.Phase0, ConsensusFork.Altair:
|
||||
|
@ -711,6 +717,9 @@ proc getBlockSignature*(v: AttachedValidator, fork: Fork,
|
|||
Web3SignerForkedBeaconBlock(kind: ConsensusFork.Deneb,
|
||||
data: blck.denebData.toBeaconBlockHeader),
|
||||
proofs)
|
||||
of ConsensusFork.Electra:
|
||||
debugRaiseAssert "getBlockSignature"
|
||||
return SignatureResult.err("Invalid beacon block fork version")
|
||||
await v.signData(web3signerRequest)
|
||||
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.7/specs/phase0/validator.md#aggregate-signature
|
||||
|
|
|
@ -98,6 +98,7 @@ template saveSSZFile(filename: string, value: ForkedHashedBeaconState) =
|
|||
of ConsensusFork.Bellatrix: SSZ.saveFile(filename, value.bellatrixData.data)
|
||||
of ConsensusFork.Capella: SSZ.saveFile(filename, value.capellaData.data)
|
||||
of ConsensusFork.Deneb: SSZ.saveFile(filename, value.denebData.data)
|
||||
of ConsensusFork.Electra: SSZ.saveFile(filename, value.electraData.data)
|
||||
except IOError:
|
||||
raiseAssert "error saving SSZ file"
|
||||
|
||||
|
|
|
@ -274,7 +274,7 @@ proc collectEpochRewardsAndPenalties*(
|
|||
proc collectEpochRewardsAndPenalties*(
|
||||
rewardsAndPenalties: var seq[RewardsAndPenalties],
|
||||
state: var (altair.BeaconState | bellatrix.BeaconState |
|
||||
capella.BeaconState | deneb.BeaconState),
|
||||
capella.BeaconState | deneb.BeaconState | electra.BeaconState),
|
||||
cache: var StateCache, cfg: RuntimeConfig, flags: UpdateFlags) =
|
||||
if get_current_epoch(state) == GENESIS_EPOCH:
|
||||
return
|
||||
|
|
|
@ -240,7 +240,8 @@ proc cmdBench(conf: DbConf, cfg: RuntimeConfig) =
|
|||
seq[altair.TrustedSignedBeaconBlock],
|
||||
seq[bellatrix.TrustedSignedBeaconBlock],
|
||||
seq[capella.TrustedSignedBeaconBlock],
|
||||
seq[deneb.TrustedSignedBeaconBlock])
|
||||
seq[deneb.TrustedSignedBeaconBlock],
|
||||
seq[electra.TrustedSignedBeaconBlock])
|
||||
|
||||
echo "Loaded head slot ", dag.head.slot,
|
||||
" selected ", blockRefs.len, " blocks"
|
||||
|
@ -266,6 +267,9 @@ proc cmdBench(conf: DbConf, cfg: RuntimeConfig) =
|
|||
of ConsensusFork.Deneb:
|
||||
blocks[4].add dag.db.getBlock(
|
||||
blck.root, deneb.TrustedSignedBeaconBlock).get()
|
||||
of ConsensusFork.Electra:
|
||||
blocks[5].add dag.db.getBlock(
|
||||
blck.root, electra.TrustedSignedBeaconBlock).get()
|
||||
|
||||
let stateData = newClone(dag.headState)
|
||||
|
||||
|
@ -277,7 +281,8 @@ proc cmdBench(conf: DbConf, cfg: RuntimeConfig) =
|
|||
(ref altair.HashedBeaconState)(),
|
||||
(ref bellatrix.HashedBeaconState)(),
|
||||
(ref capella.HashedBeaconState)(),
|
||||
(ref deneb.HashedBeaconState)())
|
||||
(ref deneb.HashedBeaconState)(),
|
||||
(ref electra.HashedBeaconState)())
|
||||
|
||||
withTimer(timers[tLoadState]):
|
||||
doAssert dag.updateState(
|
||||
|
@ -338,6 +343,9 @@ proc cmdBench(conf: DbConf, cfg: RuntimeConfig) =
|
|||
of ConsensusFork.Deneb:
|
||||
doAssert dbBenchmark.getState(
|
||||
forkyState.root, loadedState[4][].data, noRollback)
|
||||
of ConsensusFork.Electra:
|
||||
doAssert dbBenchmark.getState(
|
||||
forkyState.root, loadedState[5][].data, noRollback)
|
||||
|
||||
if forkyState.data.slot.epoch mod 16 == 0:
|
||||
let loadedRoot = case consensusFork
|
||||
|
@ -346,6 +354,7 @@ proc cmdBench(conf: DbConf, cfg: RuntimeConfig) =
|
|||
of ConsensusFork.Bellatrix: hash_tree_root(loadedState[2][].data)
|
||||
of ConsensusFork.Capella: hash_tree_root(loadedState[3][].data)
|
||||
of ConsensusFork.Deneb: hash_tree_root(loadedState[4][].data)
|
||||
of ConsensusFork.Electra: hash_tree_root(loadedState[5][].data)
|
||||
doAssert hash_tree_root(forkyState.data) == loadedRoot
|
||||
|
||||
processBlocks(blocks[0])
|
||||
|
@ -353,6 +362,7 @@ proc cmdBench(conf: DbConf, cfg: RuntimeConfig) =
|
|||
processBlocks(blocks[2])
|
||||
processBlocks(blocks[3])
|
||||
processBlocks(blocks[4])
|
||||
processBlocks(blocks[5])
|
||||
|
||||
printTimers(false, timers)
|
||||
|
||||
|
@ -366,6 +376,7 @@ proc cmdDumpState(conf: DbConf) =
|
|||
bellatrixState = (ref bellatrix.HashedBeaconState)()
|
||||
capellaState = (ref capella.HashedBeaconState)()
|
||||
denebState = (ref deneb.HashedBeaconState)()
|
||||
electraState = (ref electra.HashedBeaconState)()
|
||||
|
||||
for stateRoot in conf.stateRoot:
|
||||
if shouldShutDown: quit QuitSuccess
|
||||
|
@ -428,6 +439,8 @@ proc cmdDumpBlock(conf: DbConf) =
|
|||
dump("./", blck.get())
|
||||
elif (let blck = db.getBlock(root, deneb.TrustedSignedBeaconBlock); blck.isSome):
|
||||
dump("./", blck.get())
|
||||
elif (let blck = db.getBlock(root, electra.TrustedSignedBeaconBlock); blck.isSome):
|
||||
dump("./", blck.get())
|
||||
else:
|
||||
echo "Couldn't load ", blockRoot
|
||||
except CatchableError as e:
|
||||
|
|
|
@ -142,6 +142,49 @@ proc makeSimulationBlock(
|
|||
|
||||
ok(blck)
|
||||
|
||||
proc makeSimulationBlock(
|
||||
cfg: RuntimeConfig,
|
||||
state: var electra.HashedBeaconState,
|
||||
proposer_index: ValidatorIndex,
|
||||
randao_reveal: ValidatorSig,
|
||||
eth1_data: Eth1Data,
|
||||
graffiti: GraffitiBytes,
|
||||
attestations: seq[Attestation],
|
||||
deposits: seq[Deposit],
|
||||
exits: BeaconBlockValidatorChanges,
|
||||
sync_aggregate: SyncAggregate,
|
||||
execution_payload: electra.ExecutionPayloadForSigning,
|
||||
bls_to_execution_changes: SignedBLSToExecutionChangeList,
|
||||
rollback: RollbackHashedProc[electra.HashedBeaconState],
|
||||
cache: var StateCache,
|
||||
# TODO:
|
||||
# `verificationFlags` is needed only in tests and can be
|
||||
# removed if we don't use invalid signatures there
|
||||
verificationFlags: UpdateFlags = {}): Result[electra.BeaconBlock, cstring] =
|
||||
## Create a block for the given state. The latest block applied to it will
|
||||
## be used for the parent_root value, and the slot will be take from
|
||||
## state.slot meaning process_slots must be called up to the slot for which
|
||||
## the block is to be created.
|
||||
|
||||
# To create a block, we'll first apply a partial block to the state, skipping
|
||||
# some validations.
|
||||
|
||||
var blck = partialBeaconBlock(
|
||||
cfg, state, proposer_index, randao_reveal, eth1_data, graffiti,
|
||||
attestations, deposits, exits, sync_aggregate, execution_payload)
|
||||
|
||||
let res = process_block(
|
||||
cfg, state.data, blck.asSigVerified(), verificationFlags, cache)
|
||||
|
||||
if res.isErr:
|
||||
rollback(state)
|
||||
return err(res.error())
|
||||
|
||||
state.root = hash_tree_root(state.data)
|
||||
blck.state_root = state.root
|
||||
|
||||
ok(blck)
|
||||
|
||||
# TODO confutils is an impenetrable black box. how can a help text be added here?
|
||||
cli do(slots = SLOTS_PER_EPOCH * 7,
|
||||
validators = SLOTS_PER_EPOCH * 500,
|
||||
|
@ -343,6 +386,8 @@ cli do(slots = SLOTS_PER_EPOCH * 7,
|
|||
addr state.capellaData
|
||||
elif T is deneb.SignedBeaconBlock:
|
||||
addr state.denebData
|
||||
elif T is electra.SignedBeaconBlock:
|
||||
addr state.electraData
|
||||
else:
|
||||
static: doAssert false
|
||||
message = makeSimulationBlock(
|
||||
|
@ -359,7 +404,9 @@ cli do(slots = SLOTS_PER_EPOCH * 7,
|
|||
eth1ProposalData.deposits,
|
||||
BeaconBlockValidatorChanges(),
|
||||
sync_aggregate,
|
||||
when T is deneb.SignedBeaconBlock:
|
||||
when T is electra.SignedBeaconBlock:
|
||||
default(electra.ExecutionPayloadForSigning)
|
||||
elif T is deneb.SignedBeaconBlock:
|
||||
default(deneb.ExecutionPayloadForSigning)
|
||||
elif T is capella.SignedBeaconBlock:
|
||||
default(capella.ExecutionPayloadForSigning)
|
||||
|
@ -432,6 +479,28 @@ cli do(slots = SLOTS_PER_EPOCH * 7,
|
|||
do:
|
||||
raiseAssert "withUpdatedState failed"
|
||||
|
||||
proc proposeElectraBlock(slot: Slot) =
|
||||
if rand(r, 1.0) > blockRatio:
|
||||
return
|
||||
|
||||
dag.withUpdatedState(tmpState[], dag.getBlockIdAtSlot(slot).expect("block")) do:
|
||||
let
|
||||
newBlock = getNewBlock[electra.SignedBeaconBlock](updatedState, slot, cache)
|
||||
added = dag.addHeadBlock(verifier, newBlock) do (
|
||||
blckRef: BlockRef, signedBlock: electra.TrustedSignedBeaconBlock,
|
||||
epochRef: EpochRef, unrealized: FinalityCheckpoints):
|
||||
# Callback add to fork choice if valid
|
||||
attPool.addForkChoice(
|
||||
epochRef, blckRef, unrealized, signedBlock.message,
|
||||
blckRef.slot.start_beacon_time)
|
||||
|
||||
dag.updateHead(added[], quarantine[], [])
|
||||
if dag.needStateCachesAndForkChoicePruning():
|
||||
dag.pruneStateCachesDAG()
|
||||
attPool.prune()
|
||||
do:
|
||||
raiseAssert "withUpdatedState failed"
|
||||
|
||||
var
|
||||
lastEth1BlockAt = genesisTime
|
||||
eth1BlockNum = 1000
|
||||
|
@ -472,6 +541,7 @@ cli do(slots = SLOTS_PER_EPOCH * 7,
|
|||
if blockRatio > 0.0:
|
||||
withTimer(timers[t]):
|
||||
case dag.cfg.consensusForkAtEpoch(slot.epoch)
|
||||
of ConsensusFork.Electra: proposeElectraBlock(slot)
|
||||
of ConsensusFork.Deneb: proposeDenebBlock(slot)
|
||||
of ConsensusFork.Capella: proposeCapellaBlock(slot)
|
||||
of ConsensusFork.Bellatrix, ConsensusFork.Altair, ConsensusFork.Phase0:
|
||||
|
|
|
@ -221,6 +221,15 @@ cli do(validatorsDir: string, secretsDir: string,
|
|||
fork, genesis_validators_root, slot, blockRoot,
|
||||
validators[proposer]).toValidatorSig())
|
||||
dump(".", signedBlock)
|
||||
of ConsensusFork.Electra:
|
||||
blockRoot = hash_tree_root(message.electraData)
|
||||
let signedBlock = electra.SignedBeaconBlock(
|
||||
message: message.electraData,
|
||||
root: blockRoot,
|
||||
signature: get_block_signature(
|
||||
fork, genesis_validators_root, slot, blockRoot,
|
||||
validators[proposer]).toValidatorSig())
|
||||
dump(".", signedBlock)
|
||||
except CatchableError:
|
||||
raiseAssert "unreachable"
|
||||
notice "Block proposed", message, blockRoot
|
||||
|
|
|
@ -47,6 +47,12 @@ func readValue*(r: var JsonReader, a: var seq[byte]) =
|
|||
func genesisTestRuntimeConfig*(consensusFork: ConsensusFork): RuntimeConfig =
|
||||
var res = defaultRuntimeConfig
|
||||
case consensusFork
|
||||
of ConsensusFork.Electra:
|
||||
res.ELECTRA_FORK_EPOCH = GENESIS_EPOCH
|
||||
res.DENEB_FORK_EPOCH = GENESIS_EPOCH
|
||||
res.CAPELLA_FORK_EPOCH = GENESIS_EPOCH
|
||||
res.BELLATRIX_FORK_EPOCH = GENESIS_EPOCH
|
||||
res.ALTAIR_FORK_EPOCH = GENESIS_EPOCH
|
||||
of ConsensusFork.Deneb:
|
||||
res.DENEB_FORK_EPOCH = GENESIS_EPOCH
|
||||
res.CAPELLA_FORK_EPOCH = GENESIS_EPOCH
|
||||
|
|
|
@ -94,4 +94,5 @@ template runForkBlockTests(consensusFork: static ConsensusFork) =
|
|||
RandomDir, suiteName, path)
|
||||
|
||||
withAll(ConsensusFork):
|
||||
when consensusFork != ConsensusFork.Electra:
|
||||
runForkBlockTests(consensusFork)
|
||||
|
|
|
@ -25,12 +25,14 @@ suite "Light client" & preset():
|
|||
headPeriod = 3.SyncCommitteePeriod
|
||||
let
|
||||
cfg = block: # Fork schedule so that each `LightClientDataFork` is covered
|
||||
static: doAssert ConsensusFork.high == ConsensusFork.Deneb
|
||||
static: doAssert ConsensusFork.high == ConsensusFork.Electra
|
||||
var res = defaultRuntimeConfig
|
||||
res.ALTAIR_FORK_EPOCH = 1.Epoch
|
||||
res.BELLATRIX_FORK_EPOCH = 2.Epoch
|
||||
res.CAPELLA_FORK_EPOCH = (EPOCHS_PER_SYNC_COMMITTEE_PERIOD * 1).Epoch
|
||||
res.DENEB_FORK_EPOCH = (EPOCHS_PER_SYNC_COMMITTEE_PERIOD * 2).Epoch
|
||||
debugRaiseAssert "light client test; when this is tested, enable Electra"
|
||||
res.ELECTRA_FORK_EPOCH = FAR_FUTURE_EPOCH
|
||||
res
|
||||
altairStartSlot = cfg.ALTAIR_FORK_EPOCH.start_slot
|
||||
|
||||
|
|
|
@ -28,12 +28,14 @@ suite "Light client processor" & preset():
|
|||
highPeriod = 5.SyncCommitteePeriod
|
||||
let
|
||||
cfg = block: # Fork schedule so that each `LightClientDataFork` is covered
|
||||
static: doAssert ConsensusFork.high == ConsensusFork.Deneb
|
||||
static: doAssert ConsensusFork.high == ConsensusFork.Electra
|
||||
var res = defaultRuntimeConfig
|
||||
res.ALTAIR_FORK_EPOCH = 1.Epoch
|
||||
res.BELLATRIX_FORK_EPOCH = 2.Epoch
|
||||
res.CAPELLA_FORK_EPOCH = (EPOCHS_PER_SYNC_COMMITTEE_PERIOD * 1).Epoch
|
||||
res.DENEB_FORK_EPOCH = (EPOCHS_PER_SYNC_COMMITTEE_PERIOD * 2).Epoch
|
||||
res.ELECTRA_FORK_EPOCH = FAR_FUTURE_EPOCH
|
||||
debugRaiseAssert "Light client processor test, once define/works add Electra to tests"
|
||||
res
|
||||
|
||||
const numValidators = SLOTS_PER_EPOCH
|
||||
|
|
|
@ -17,6 +17,7 @@ import
|
|||
|
||||
from std/os import getEnv, osErrorMsg
|
||||
|
||||
{.push raises: [].}
|
||||
{.used.}
|
||||
|
||||
const
|
||||
|
@ -97,9 +98,13 @@ func init(T: type ForkedBeaconBlock, contents: ProduceBlockResponseV2): T =
|
|||
return ForkedBeaconBlock.init(contents.capellaData)
|
||||
of ConsensusFork.Deneb:
|
||||
return ForkedBeaconBlock.init(contents.denebData.`block`)
|
||||
of ConsensusFork.Electra:
|
||||
return ForkedBeaconBlock.init(contents.electraData.`block`)
|
||||
|
||||
proc getBlock(fork: ConsensusFork,
|
||||
feeRecipient = SigningExpectedFeeRecipient): ForkedBeaconBlock =
|
||||
try:
|
||||
debugRaiseAssert "getBlock; ConsensusFork.Electra shouldn't use DenebBlockContents, but not tested, so do that together"
|
||||
let
|
||||
blckData =
|
||||
case fork
|
||||
|
@ -108,6 +113,7 @@ proc getBlock(fork: ConsensusFork,
|
|||
of ConsensusFork.Bellatrix: BellatrixBlock % [feeRecipient]
|
||||
of ConsensusFork.Capella: CapellaBlock % [feeRecipient]
|
||||
of ConsensusFork.Deneb: DenebBlockContents % [feeRecipient]
|
||||
of ConsensusFork.Electra: DenebBlockContents % [feeRecipient]
|
||||
contentType = ContentTypeData(
|
||||
mediaType: MediaType.init("application/json"))
|
||||
|
||||
|
@ -117,6 +123,8 @@ proc getBlock(fork: ConsensusFork,
|
|||
Opt.some(contentType),
|
||||
$fork).tryGet()
|
||||
ForkedBeaconBlock.init(b)
|
||||
except ValueError:
|
||||
raiseAssert "unreachable"
|
||||
|
||||
func init(t: typedesc[Web3SignerForkedBeaconBlock],
|
||||
forked: ForkedBeaconBlock): Web3SignerForkedBeaconBlock =
|
||||
|
@ -135,6 +143,11 @@ func init(t: typedesc[Web3SignerForkedBeaconBlock],
|
|||
Web3SignerForkedBeaconBlock(
|
||||
kind: ConsensusFork.Deneb,
|
||||
data: forked.denebData.toBeaconBlockHeader)
|
||||
of ConsensusFork.Electra:
|
||||
debugRaiseAssert "init typedesc[Web3SignerForkedBeaconBlock]"
|
||||
Web3SignerForkedBeaconBlock(
|
||||
kind: ConsensusFork.Deneb,
|
||||
data: forked.electraData.toBeaconBlockHeader)
|
||||
|
||||
proc createKeystore(dataDir, pubkey,
|
||||
store, password: string): Result[void, string] =
|
||||
|
|
|
@ -64,7 +64,7 @@ proc getTestStates*(
|
|||
info = ForkedEpochInfo()
|
||||
cfg = defaultRuntimeConfig
|
||||
|
||||
static: doAssert high(ConsensusFork) == ConsensusFork.Deneb
|
||||
static: doAssert high(ConsensusFork) == ConsensusFork.Electra
|
||||
if consensusFork >= ConsensusFork.Altair:
|
||||
cfg.ALTAIR_FORK_EPOCH = 1.Epoch
|
||||
if consensusFork >= ConsensusFork.Bellatrix:
|
||||
|
@ -73,6 +73,8 @@ proc getTestStates*(
|
|||
cfg.CAPELLA_FORK_EPOCH = 3.Epoch
|
||||
if consensusFork >= ConsensusFork.Deneb:
|
||||
cfg.DENEB_FORK_EPOCH = 4.Epoch
|
||||
if consensusFork >= ConsensusFork.Electra:
|
||||
cfg.DENEB_FORK_EPOCH = 5.Epoch
|
||||
|
||||
for i, epoch in stateEpochs:
|
||||
let slot = epoch.Epoch.start_slot
|
||||
|
|
Loading…
Reference in New Issue