capella validator withdrawal credentials aren't immutable (#4455)

This commit is contained in:
tersec 2023-01-03 19:04:59 +00:00 committed by GitHub
parent 9e699fd2fc
commit 45654984a9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 74 additions and 16 deletions

View File

@ -509,8 +509,8 @@ proc new*(T: type BeaconChainDB,
kvStore db.openKvStore("state_no_validators2").expectDb(), kvStore db.openKvStore("state_no_validators2").expectDb(),
kvStore db.openKvStore("altair_state_no_validators").expectDb(), kvStore db.openKvStore("altair_state_no_validators").expectDb(),
kvStore db.openKvStore("bellatrix_state_no_validators").expectDb(), kvStore db.openKvStore("bellatrix_state_no_validators").expectDb(),
kvStore db.openKvStore("capella_state_no_validators").expectDb(), kvStore db.openKvStore("capella_state_no_validator_pubkeys").expectDb(),
kvStore db.openKvStore("eip4844_state_no_validators").expectDb()] kvStore db.openKvStore("eip4844_state_no_validator_pubkeys").expectDb()]
stateDiffs = kvStore db.openKvStore("state_diffs").expectDb() stateDiffs = kvStore db.openKvStore("state_diffs").expectDb()
summaries = kvStore db.openKvStore("beacon_block_summaries", true).expectDb() summaries = kvStore db.openKvStore("beacon_block_summaries", true).expectDb()
@ -1114,8 +1114,45 @@ proc getStateOnlyMutableValidators(
proc getStateOnlyMutableValidators( proc getStateOnlyMutableValidators(
immutableValidators: openArray[ImmutableValidatorData2], immutableValidators: openArray[ImmutableValidatorData2],
store: KvStoreRef, key: openArray[byte], store: KvStoreRef, key: openArray[byte],
output: var (bellatrix.BeaconState | capella.BeaconState | output: var bellatrix.BeaconState, rollback: RollbackProc): bool =
eip4844.BeaconState), ## Load state into `output` - BeaconState is large so we want to avoid
## re-allocating it if possible
## Return `true` iff the entry was found in the database and `output` was
## overwritten.
## Rollback will be called only if output was partially written - if it was
## not found at all, rollback will not be called
# TODO rollback is needed to deal with bug - use `noRollback` to ignore:
# https://github.com/nim-lang/Nim/issues/14126
# TODO RVO is inefficient for large objects:
# https://github.com/nim-lang/Nim/issues/13879
case store.getSZSSZ(key, toBeaconStateNoImmutableValidators(output))
of GetResult.found:
let numValidators = output.validators.len
doAssert immutableValidators.len >= numValidators
for i in 0 ..< numValidators:
# Bypass hash cache invalidation
let dstValidator = addr output.validators.data[i]
assign(dstValidator.pubkey, immutableValidators[i].pubkey.toPubKey())
assign(
dstValidator.withdrawal_credentials,
immutableValidators[i].withdrawal_credentials)
output.validators.resetCache()
true
of GetResult.notFound:
false
of GetResult.corrupted:
rollback()
false
proc getStateOnlyMutableValidators(
immutableValidators: openArray[ImmutableValidatorData2],
store: KvStoreRef, key: openArray[byte],
output: var (capella.BeaconState | eip4844.BeaconState),
rollback: RollbackProc): bool = rollback: RollbackProc): bool =
## Load state into `output` - BeaconState is large so we want to avoid ## Load state into `output` - BeaconState is large so we want to avoid
## re-allocating it if possible ## re-allocating it if possible
@ -1134,16 +1171,9 @@ proc getStateOnlyMutableValidators(
doAssert immutableValidators.len >= numValidators doAssert immutableValidators.len >= numValidators
for i in 0 ..< numValidators: for i in 0 ..< numValidators:
let # Bypass hash cache invalidation
# Bypass hash cache invalidation let dstValidator = addr output.validators.data[i]
dstValidator = addr output.validators.data[i] assign(dstValidator.pubkey, immutableValidators[i].pubkey.toPubKey())
assign(
dstValidator.pubkey,
immutableValidators[i].pubkey.toPubKey())
assign(
dstValidator.withdrawal_credentials,
immutableValidators[i].withdrawal_credentials)
output.validators.resetCache() output.validators.resetCache()

View File

@ -214,7 +214,8 @@ type
eth1_deposit_index*: uint64 eth1_deposit_index*: uint64
# Registry # Registry
validators*: HashList[ValidatorStatus, Limit VALIDATOR_REGISTRY_LIMIT] validators*:
HashList[ValidatorStatusCapella, Limit VALIDATOR_REGISTRY_LIMIT]
balances*: HashList[Gwei, Limit VALIDATOR_REGISTRY_LIMIT] balances*: HashList[Gwei, Limit VALIDATOR_REGISTRY_LIMIT]
# Randomness # Randomness
@ -279,7 +280,8 @@ type
eth1_deposit_index*: uint64 eth1_deposit_index*: uint64
# Registry # Registry
validators*: HashList[ValidatorStatus, Limit VALIDATOR_REGISTRY_LIMIT] validators*:
HashList[ValidatorStatusCapella, Limit VALIDATOR_REGISTRY_LIMIT]
balances*: HashList[Gwei, Limit VALIDATOR_REGISTRY_LIMIT] balances*: HashList[Gwei, Limit VALIDATOR_REGISTRY_LIMIT]
# Randomness # Randomness

View File

@ -443,6 +443,32 @@ type
withdrawable_epoch*: Epoch withdrawable_epoch*: Epoch
## When validator can withdraw or transfer funds ## When validator can withdraw or transfer funds
# https://github.com/ethereum/consensus-specs/blob/v1.3.0-alpha.2/specs/phase0/beacon-chain.md#validator
ValidatorStatusCapella* = object
# This is a validator without the expensive, immutable, append-only parts
# serialized. They're represented in memory to allow in-place SSZ reading
# and writing compatibly with the full Validator object.
pubkey* {.dontSerialize.}: ValidatorPubKey
withdrawal_credentials*: Eth2Digest
## Commitment to pubkey for withdrawals and transfers
effective_balance*: Gwei
## Balance at stake
slashed*: bool
# Status epochs
activation_eligibility_epoch*: Epoch
## When criteria for activation were met
activation_epoch*: Epoch
exit_epoch*: Epoch
withdrawable_epoch*: Epoch
## When validator can withdraw or transfer funds
# https://github.com/ethereum/consensus-specs/blob/v1.3.0-alpha.2/specs/phase0/p2p-interface.md#eth2-field # https://github.com/ethereum/consensus-specs/blob/v1.3.0-alpha.2/specs/phase0/p2p-interface.md#eth2-field
ENRForkID* = object ENRForkID* = object
fork_digest*: ForkDigest fork_digest*: ForkDigest