add some push raises, ElectraBeaconStateNoImmutableValidators, and ELECTRA_FORK_VERSION/EPOCH (#5949)

This commit is contained in:
tersec 2024-02-24 05:08:22 +00:00 committed by GitHub
parent bf6b5a316f
commit e865817d44
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 191 additions and 75 deletions

View File

@ -327,3 +327,73 @@ type
# Deep history valid from Capella onwards
historical_summaries*:
HashList[HistoricalSummary, Limit HISTORICAL_ROOTS_LIMIT]
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/capella/beacon-chain.md#beaconstate
# with indirect changes via ExecutionPayloadHeader
# Memory-representation-equivalent to a Deneb BeaconState for in-place SSZ
# reading and writing
ElectraBeaconStateNoImmutableValidators* = object
# Versioning
genesis_time*: uint64
genesis_validators_root*: Eth2Digest
slot*: Slot
fork*: Fork
# History
latest_block_header*: BeaconBlockHeader
## `latest_block_header.state_root == ZERO_HASH` temporarily
block_roots*: HashArray[Limit SLOTS_PER_HISTORICAL_ROOT, Eth2Digest]
## Needed to process attestations, older to newer
state_roots*: HashArray[Limit SLOTS_PER_HISTORICAL_ROOT, Eth2Digest]
historical_roots*: HashList[Eth2Digest, Limit HISTORICAL_ROOTS_LIMIT]
## Frozen in Capella, replaced by historical_summaries
# Eth1
eth1_data*: Eth1Data
eth1_data_votes*:
HashList[Eth1Data, Limit(EPOCHS_PER_ETH1_VOTING_PERIOD * SLOTS_PER_EPOCH)]
eth1_deposit_index*: uint64
# Registry
validators*:
HashList[ValidatorStatusCapella, Limit VALIDATOR_REGISTRY_LIMIT]
balances*: HashList[Gwei, Limit VALIDATOR_REGISTRY_LIMIT]
# Randomness
randao_mixes*: HashArray[Limit EPOCHS_PER_HISTORICAL_VECTOR, Eth2Digest]
# Slashings
slashings*: HashArray[Limit EPOCHS_PER_SLASHINGS_VECTOR, Gwei]
## Per-epoch sums of slashed effective balances
# Participation
previous_epoch_participation*: EpochParticipationFlags
current_epoch_participation*: EpochParticipationFlags
# Finality
justification_bits*: JustificationBits
## Bit set for every recent justified epoch
previous_justified_checkpoint*: Checkpoint
current_justified_checkpoint*: Checkpoint
finalized_checkpoint*: Checkpoint
# Inactivity
inactivity_scores*: HashList[uint64, Limit VALIDATOR_REGISTRY_LIMIT]
# Light client sync committees
current_sync_committee*: SyncCommittee
next_sync_committee*: SyncCommittee
# Execution
latest_execution_payload_header*: deneb.ExecutionPayloadHeader
# Withdrawals
next_withdrawal_index*: WithdrawalIndex
next_withdrawal_validator_index*: uint64
# Deep history valid from Capella onwards
historical_summaries*:
HashList[HistoricalSummary, Limit HISTORICAL_ROOTS_LIMIT]

View File

@ -5,6 +5,8 @@
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [].}
import std/[tables, os, strutils]
import serialization, json_serialization,
json_serialization/std/[options, net],

View File

@ -5,6 +5,8 @@
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [].}
import
std/[typetraits, sequtils, sets],
stew/[results, base10],

View File

@ -4,6 +4,8 @@
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [].}
import std/[typetraits, sets, sequtils]
import stew/[results, base10], chronicles
import ".."/[beacon_chain_db, beacon_node],

View File

@ -60,6 +60,8 @@ type
CAPELLA_FORK_EPOCH*: Epoch
DENEB_FORK_VERSION*: Version
DENEB_FORK_EPOCH*: Epoch
ELECTRA_FORK_VERSION*: Version
ELECTRA_FORK_EPOCH*: Epoch
# Time parameters
# TODO SECONDS_PER_SLOT*: uint64
@ -194,6 +196,9 @@ when const_preset == "mainnet":
# Deneb
DENEB_FORK_VERSION: Version [byte 0x04, 0x00, 0x00, 0x00],
DENEB_FORK_EPOCH: FAR_FUTURE_EPOCH,
# Electra
ELECTRA_FORK_VERSION: Version [byte 0x05, 0x00, 0x00, 0x00],
ELECTRA_FORK_EPOCH: FAR_FUTURE_EPOCH,
# Time parameters
# ---------------------------------------------------------------
@ -338,6 +343,9 @@ elif const_preset == "gnosis":
# Deneb
DENEB_FORK_VERSION: Version [byte 0x04, 0x00, 0x00, 0x64],
DENEB_FORK_EPOCH: FAR_FUTURE_EPOCH,
# Electra
ELECTRA_FORK_VERSION: Version [byte 0x05, 0x00, 0x00, 0x64],
ELECTRA_FORK_EPOCH: FAR_FUTURE_EPOCH,
# Time parameters
@ -478,6 +486,9 @@ elif const_preset == "minimal":
# Deneb
DENEB_FORK_VERSION: Version [byte 0x04, 0x00, 0x00, 0x01],
DENEB_FORK_EPOCH: Epoch(uint64.high),
# Electra
ELECTRA_FORK_VERSION: Version [byte 0x05, 0x00, 0x00, 0x01],
ELECTRA_FORK_EPOCH: Epoch(uint64.high),
# Time parameters

View File

@ -255,7 +255,6 @@ proc getMissingBlobs(rman: RequestManager): seq[BlobIdentifier] =
var fetches: seq[BlobIdentifier]
for blobless in rman.quarantine[].peekBlobless():
# give blobs a chance to arrive over gossip
if blobless.message.slot == wallSlot and delay < waitDur:
debug "Not handling missing blobs early in slot"

View File

@ -593,6 +593,7 @@ proc getBlockSignature*(v: AttachedValidator, fork: Fork,
proofs)
elif blck is ForkedMaybeBlindedBeaconBlock:
withForkyMaybeBlindedBlck(blck):
# TODO why isn't this a case statement
when consensusFork < ConsensusFork.Bellatrix:
return SignatureResult.err("Invalid beacon block fork version")
elif consensusFork == ConsensusFork.Bellatrix:

View File

@ -5,6 +5,8 @@
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [].}
import
std/strutils,
confutils, json_serialization,
@ -89,27 +91,34 @@ type
desc: "Filename of state resulting from applying blck to preState"}: string
template saveSSZFile(filename: string, value: ForkedHashedBeaconState) =
case value.kind:
of ConsensusFork.Phase0: SSZ.saveFile(filename, value.phase0Data.data)
of ConsensusFork.Altair: SSZ.saveFile(filename, value.altairData.data)
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)
try:
case value.kind:
of ConsensusFork.Phase0: SSZ.saveFile(filename, value.phase0Data.data)
of ConsensusFork.Altair: SSZ.saveFile(filename, value.altairData.data)
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)
except IOError:
raiseAssert "error saving SSZ file"
proc loadFile(filename: string, bytes: openArray[byte], T: type): T =
let
ext = splitFile(filename).ext
if cmpIgnoreCase(ext, ".ssz") == 0:
SSZ.decode(bytes, T)
elif cmpIgnoreCase(ext, ".ssz_snappy") == 0:
SSZ.decode(snappy.decode(bytes), T)
elif cmpIgnoreCase(ext, ".json") == 0:
# JSON.loadFile(file, t)
echo "TODO needs porting to RestJson"
quit 1
else:
echo "Unknown file type: ", ext
try:
if cmpIgnoreCase(ext, ".ssz") == 0:
SSZ.decode(bytes, T)
elif cmpIgnoreCase(ext, ".ssz_snappy") == 0:
SSZ.decode(snappy.decode(bytes), T)
elif cmpIgnoreCase(ext, ".json") == 0:
# JSON.loadFile(file, t)
echo "TODO needs porting to RestJson"
quit 1
else:
echo "Unknown file type: ", ext
quit 1
except CatchableError:
echo "failed to load SSZ file"
quit 1
proc doTransition(conf: NcliConf) =
@ -123,10 +132,17 @@ proc doTransition(conf: NcliConf) =
let
cfg = getRuntimeConfig(conf.eth2Network)
stateY = withTimerRet(timers[tLoadState]):
newClone(readSszForkedHashedBeaconState(
cfg, readAllBytes(conf.preState).tryGet()))
blckX = readSszForkedSignedBeaconBlock(
cfg, readAllBytes(conf.blck).tryGet())
try:
newClone(readSszForkedHashedBeaconState(
cfg, readAllBytes(conf.preState).tryGet()))
except CatchableError:
raiseAssert "error reading hashed beacon state"
blckX =
try:
readSszForkedSignedBeaconBlock(
cfg, readAllBytes(conf.blck).tryGet())
except CatchableError:
raiseAssert "error reading signed beacon block"
flags = if not conf.verifyStateRoot: {skipStateRootValidation} else: {}
var
@ -157,8 +173,11 @@ proc doSlots(conf: NcliConf) =
let
cfg = getRuntimeConfig(conf.eth2Network)
stateY = withTimerRet(timers[tLoadState]):
newClone(readSszForkedHashedBeaconState(
cfg, readAllBytes(conf.preState2).tryGet()))
try:
newClone(readSszForkedHashedBeaconState(
cfg, readAllBytes(conf.preState2).tryGet()))
except CatchableError:
raiseAssert "error reading hashed beacon state"
var
cache = StateCache()
info = ForkedEpochInfo()

View File

@ -9,6 +9,8 @@
# beacon chain running with the given validators producing blocks
# and attesting when they're supposed to.
{.push raises: [].}
import
std/[strformat, sequtils, tables],
chronicles,
@ -31,7 +33,7 @@ template findIt*(s: openArray, predicate: untyped): int =
break
res
proc findValidator(validators: seq[Validator], pubKey: ValidatorPubKey):
func findValidator(validators: seq[Validator], pubKey: ValidatorPubKey):
Opt[ValidatorIndex] =
let idx = validators.findIt(it.pubkey == pubKey)
if idx == -1:
@ -47,8 +49,11 @@ cli do(validatorsDir: string, secretsDir: string,
let
cfg = getMetadataForNetwork(network).cfg
state =
newClone(readSszForkedHashedBeaconState(
cfg, readAllBytes(startState).tryGet()))
try:
newClone(readSszForkedHashedBeaconState(
cfg, readAllBytes(startState).tryGet()))
except CatchableError:
raiseAssert "failed to read hashed beacon state"
var
clock = BeaconClock.init(getStateField(state[], genesis_time)).valueOr:
@ -151,14 +156,16 @@ cli do(validatorsDir: string, secretsDir: string,
slot <= it.data.slot + SLOTS_PER_EPOCH)
randao_reveal = get_epoch_signature(
fork, genesis_validators_root, slot.epoch,
validators[proposer]).toValidatorSig()
# should never fall back to default value
validators.getOrDefault(
proposer, default(ValidatorPrivKey))).toValidatorSig()
message = makeBeaconBlock(
cfg,
state[],
proposer,
randao_reveal,
getStateField(state[], eth1_data),
GraffitiBytes.init("insecura"),
static(GraffitiBytes.init("insecura")),
blockAggregates,
@[],
BeaconBlockValidatorChanges(),
@ -167,52 +174,55 @@ cli do(validatorsDir: string, secretsDir: string,
noRollback,
cache).get()
case message.kind
of ConsensusFork.Phase0:
blockRoot = hash_tree_root(message.phase0Data)
let signedBlock = phase0.SignedBeaconBlock(
message: message.phase0Data,
root: blockRoot,
signature: get_block_signature(
fork, genesis_validators_root, slot, blockRoot,
validators[proposer]).toValidatorSig())
dump(".", signedBlock)
of ConsensusFork.Altair:
blockRoot = hash_tree_root(message.altairData)
let signedBlock = altair.SignedBeaconBlock(
message: message.altairData,
root: blockRoot,
signature: get_block_signature(
fork, genesis_validators_root, slot, blockRoot,
validators[proposer]).toValidatorSig())
dump(".", signedBlock)
of ConsensusFork.Bellatrix:
blockRoot = hash_tree_root(message.bellatrixData)
let signedBlock = bellatrix.SignedBeaconBlock(
message: message.bellatrixData,
root: blockRoot,
signature: get_block_signature(
fork, genesis_validators_root, slot, blockRoot,
validators[proposer]).toValidatorSig())
dump(".", signedBlock)
of ConsensusFork.Capella:
blockRoot = hash_tree_root(message.capellaData)
let signedBlock = capella.SignedBeaconBlock(
message: message.capellaData,
root: blockRoot,
signature: get_block_signature(
fork, genesis_validators_root, slot, blockRoot,
validators[proposer]).toValidatorSig())
dump(".", signedBlock)
of ConsensusFork.Deneb:
blockRoot = hash_tree_root(message.denebData)
let signedBlock = deneb.SignedBeaconBlock(
message: message.denebData,
root: blockRoot,
signature: get_block_signature(
fork, genesis_validators_root, slot, blockRoot,
validators[proposer]).toValidatorSig())
dump(".", signedBlock)
try:
case message.kind
of ConsensusFork.Phase0:
blockRoot = hash_tree_root(message.phase0Data)
let signedBlock = phase0.SignedBeaconBlock(
message: message.phase0Data,
root: blockRoot,
signature: get_block_signature(
fork, genesis_validators_root, slot, blockRoot,
validators[proposer]).toValidatorSig())
dump(".", signedBlock)
of ConsensusFork.Altair:
blockRoot = hash_tree_root(message.altairData)
let signedBlock = altair.SignedBeaconBlock(
message: message.altairData,
root: blockRoot,
signature: get_block_signature(
fork, genesis_validators_root, slot, blockRoot,
validators[proposer]).toValidatorSig())
dump(".", signedBlock)
of ConsensusFork.Bellatrix:
blockRoot = hash_tree_root(message.bellatrixData)
let signedBlock = bellatrix.SignedBeaconBlock(
message: message.bellatrixData,
root: blockRoot,
signature: get_block_signature(
fork, genesis_validators_root, slot, blockRoot,
validators[proposer]).toValidatorSig())
dump(".", signedBlock)
of ConsensusFork.Capella:
blockRoot = hash_tree_root(message.capellaData)
let signedBlock = capella.SignedBeaconBlock(
message: message.capellaData,
root: blockRoot,
signature: get_block_signature(
fork, genesis_validators_root, slot, blockRoot,
validators[proposer]).toValidatorSig())
dump(".", signedBlock)
of ConsensusFork.Deneb:
blockRoot = hash_tree_root(message.denebData)
let signedBlock = deneb.SignedBeaconBlock(
message: message.denebData,
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
aggregates.setLen(0)
@ -240,7 +250,7 @@ cli do(validatorsDir: string, secretsDir: string,
let
signature = get_attestation_signature(
fork, genesis_validators_root, attestation.data,
validators[validator_index])
validators.getOrDefault(validator_index, default(ValidatorPrivKey)))
if attestation.aggregation_bits.isZeros:
agg = AggregateSignature.init(signature)
else: