avoid quadratic behavior exiting validators (#6161)

* avoid quadratic behavior exiting validators

* fix libnfuzz callers
This commit is contained in:
tersec 2024-04-02 12:18:40 +00:00 committed by GitHub
parent 4457334dd0
commit 109007dc93
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 184 additions and 79 deletions

View File

@ -90,18 +90,9 @@ func get_validator_activation_churn_limit*(
cfg.MAX_PER_EPOCH_ACTIVATION_CHURN_LIMIT, cfg.MAX_PER_EPOCH_ACTIVATION_CHURN_LIMIT,
get_validator_churn_limit(cfg, state, cache)) get_validator_churn_limit(cfg, state, cache))
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/phase0/beacon-chain.md#initiate_validator_exit # https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/beacon-chain.md#initiate_validator_exit
func initiate_validator_exit*( func get_state_exit_queue_info*(
cfg: RuntimeConfig, state: var ForkyBeaconState, cfg: RuntimeConfig, state: var ForkyBeaconState, cache: var StateCache): ExitQueueInfo =
index: ValidatorIndex, cache: var StateCache): Result[void, cstring] =
## Initiate the exit of the validator with index ``index``.
if state.validators.item(index).exit_epoch != FAR_FUTURE_EPOCH:
return ok() # Before touching cache
# Return if validator already initiated exit
let validator = addr state.validators.mitem(index)
var var
exit_queue_epoch = compute_activation_exit_epoch(get_current_epoch(state)) exit_queue_epoch = compute_activation_exit_epoch(get_current_epoch(state))
exit_queue_churn: uint64 exit_queue_churn: uint64
@ -125,9 +116,34 @@ func initiate_validator_exit*(
if exit_epoch == exit_queue_epoch: if exit_epoch == exit_queue_epoch:
inc exit_queue_churn inc exit_queue_churn
ExitQueueInfo(
exit_queue_epoch: exit_queue_epoch, exit_queue_churn: exit_queue_churn)
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/beacon-chain.md#initiate_validator_exit
func initiate_validator_exit*(
cfg: RuntimeConfig, state: var ForkyBeaconState,
index: ValidatorIndex, exit_queue_info: ExitQueueInfo, cache: var StateCache):
Result[ExitQueueInfo, cstring] =
## Initiate the exit of the validator with index ``index``.
if state.validators.item(index).exit_epoch != FAR_FUTURE_EPOCH:
return ok(exit_queue_info) # Before touching cache
# Return if validator already initiated exit
let validator = addr state.validators.mitem(index)
var
exit_queue_epoch = exit_queue_info.exit_queue_epoch
exit_queue_churn = exit_queue_info.exit_queue_churn
if exit_queue_churn >= get_validator_churn_limit(cfg, state, cache): if exit_queue_churn >= get_validator_churn_limit(cfg, state, cache):
inc exit_queue_epoch inc exit_queue_epoch
# Bookkeeping for inter-operation caching; include this exit for next time
exit_queue_churn = 1
else:
inc exit_queue_churn
# Set validator exit epoch and withdrawable epoch # Set validator exit epoch and withdrawable epoch
validator.exit_epoch = exit_queue_epoch validator.exit_epoch = exit_queue_epoch
@ -138,7 +154,8 @@ func initiate_validator_exit*(
validator.withdrawable_epoch = validator.withdrawable_epoch =
validator.exit_epoch + cfg.MIN_VALIDATOR_WITHDRAWABILITY_DELAY validator.exit_epoch + cfg.MIN_VALIDATOR_WITHDRAWABILITY_DELAY
ok() ok(ExitQueueInfo(
exit_queue_epoch: exit_queue_epoch, exit_queue_churn: exit_queue_churn))
from ./datatypes/deneb import BeaconState from ./datatypes/deneb import BeaconState
@ -183,23 +200,16 @@ func get_proposer_reward(state: ForkyBeaconState, whistleblower_reward: Gwei): G
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/bellatrix/beacon-chain.md#modified-slash_validator # https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/bellatrix/beacon-chain.md#modified-slash_validator
proc slash_validator*( proc slash_validator*(
cfg: RuntimeConfig, state: var ForkyBeaconState, cfg: RuntimeConfig, state: var ForkyBeaconState,
slashed_index: ValidatorIndex, cache: var StateCache): slashed_index: ValidatorIndex, pre_exit_queue_info: ExitQueueInfo,
Result[Gwei, cstring] = cache: var StateCache): Result[(Gwei, ExitQueueInfo), cstring] =
## Slash the validator with index ``index``. ## Slash the validator with index ``index``.
let epoch = get_current_epoch(state) let
? initiate_validator_exit(cfg, state, slashed_index, cache) epoch = get_current_epoch(state)
post_exit_queue_info = ? initiate_validator_exit(
cfg, state, slashed_index, pre_exit_queue_info, cache)
let validator = addr state.validators.mitem(slashed_index) let validator = addr state.validators.mitem(slashed_index)
trace "slash_validator: ejecting validator via slashing (validator_leaving)",
index = slashed_index,
num_validators = state.validators.len,
current_epoch = get_current_epoch(state),
validator_slashed = validator.slashed,
validator_withdrawable_epoch = validator.withdrawable_epoch,
validator_exit_epoch = validator.exit_epoch,
validator_effective_balance = validator.effective_balance
validator.slashed = true validator.slashed = true
validator.withdrawable_epoch = validator.withdrawable_epoch =
max(validator.withdrawable_epoch, epoch + EPOCHS_PER_SLASHINGS_VECTOR) max(validator.withdrawable_epoch, epoch + EPOCHS_PER_SLASHINGS_VECTOR)
@ -212,7 +222,7 @@ proc slash_validator*(
# The rest doesn't make sense without there being any proposer index, so skip # The rest doesn't make sense without there being any proposer index, so skip
let proposer_index = get_beacon_proposer_index(state, cache).valueOr: let proposer_index = get_beacon_proposer_index(state, cache).valueOr:
debug "No beacon proposer index and probably no active validators" debug "No beacon proposer index and probably no active validators"
return ok(0.Gwei) return ok((0.Gwei, post_exit_queue_info))
# Apply proposer and whistleblower rewards # Apply proposer and whistleblower rewards
let let
@ -223,11 +233,13 @@ proc slash_validator*(
increase_balance(state, proposer_index, proposer_reward) increase_balance(state, proposer_index, proposer_reward)
# TODO: evaluate if spec bug / underflow can be triggered # TODO: evaluate if spec bug / underflow can be triggered
doAssert(whistleblower_reward >= proposer_reward, "Spec bug: underflow in slash_validator") doAssert(
whistleblower_reward >= proposer_reward,
"Spec bug: underflow in slash_validator")
increase_balance( increase_balance(
state, whistleblower_index, whistleblower_reward - proposer_reward) state, whistleblower_index, whistleblower_reward - proposer_reward)
ok(proposer_reward) ok((proposer_reward, post_exit_queue_info))
func genesis_time_from_eth1_timestamp( func genesis_time_from_eth1_timestamp(
cfg: RuntimeConfig, eth1_timestamp: uint64): uint64 = cfg: RuntimeConfig, eth1_timestamp: uint64): uint64 =

View File

@ -580,6 +580,10 @@ type
flags*: set[RewardFlags] flags*: set[RewardFlags]
ExitQueueInfo* = object
exit_queue_epoch*: Epoch
exit_queue_churn*: uint64
func pubkey*(v: HashedValidatorPubKey): ValidatorPubKey = func pubkey*(v: HashedValidatorPubKey): ValidatorPubKey =
if isNil(v.value): if isNil(v.value):
# This should never happen but we guard against it in case a # This should never happen but we guard against it in case a

View File

@ -186,9 +186,10 @@ proc check_proposer_slashing*(
proc process_proposer_slashing*( proc process_proposer_slashing*(
cfg: RuntimeConfig, state: var ForkyBeaconState, cfg: RuntimeConfig, state: var ForkyBeaconState,
proposer_slashing: SomeProposerSlashing, flags: UpdateFlags, proposer_slashing: SomeProposerSlashing, flags: UpdateFlags,
cache: var StateCache): Result[Gwei, cstring] = exit_queue_info: ExitQueueInfo, cache: var StateCache):
Result[(Gwei, ExitQueueInfo), cstring] =
let proposer_index = ? check_proposer_slashing(state, proposer_slashing, flags) let proposer_index = ? check_proposer_slashing(state, proposer_slashing, flags)
slash_validator(cfg, state, proposer_index, cache) slash_validator(cfg, state, proposer_index, exit_queue_info, cache)
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/phase0/beacon-chain.md#is_slashable_attestation_data # https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.6/specs/phase0/beacon-chain.md#is_slashable_attestation_data
func is_slashable_attestation_data( func is_slashable_attestation_data(
@ -250,17 +251,24 @@ proc process_attester_slashing*(
state: var ForkyBeaconState, state: var ForkyBeaconState,
attester_slashing: SomeAttesterSlashing, attester_slashing: SomeAttesterSlashing,
flags: UpdateFlags, flags: UpdateFlags,
cache: var StateCache exit_queue_info: ExitQueueInfo, cache: var StateCache
): Result[Gwei, cstring] = ): Result[(Gwei, ExitQueueInfo), cstring] =
let slashed_attesters = let slashed_attesters =
? check_attester_slashing(state, attester_slashing, flags) ? check_attester_slashing(state, attester_slashing, flags)
var proposer_reward: Gwei var
proposer_reward: Gwei
cur_exit_queue_info = exit_queue_info
for index in slashed_attesters: for index in slashed_attesters:
proposer_reward += ? slash_validator(cfg, state, index, cache) doAssert strictVerification notin flags or
cur_exit_queue_info == get_state_exit_queue_info(cfg, state, cache)
let (new_proposer_reward, new_exit_queue_info) = ? slash_validator(
cfg, state, index, cur_exit_queue_info, cache)
proposer_reward += new_proposer_reward
cur_exit_queue_info = new_exit_queue_info
ok(proposer_reward) ok((proposer_reward, cur_exit_queue_info))
func findValidatorIndex*(state: ForkyBeaconState, pubkey: ValidatorPubKey): func findValidatorIndex*(state: ForkyBeaconState, pubkey: ValidatorPubKey):
Opt[ValidatorIndex] = Opt[ValidatorIndex] =
@ -410,12 +418,12 @@ proc process_voluntary_exit*(
cfg: RuntimeConfig, cfg: RuntimeConfig,
state: var ForkyBeaconState, state: var ForkyBeaconState,
signed_voluntary_exit: SomeSignedVoluntaryExit, signed_voluntary_exit: SomeSignedVoluntaryExit,
flags: UpdateFlags, flags: UpdateFlags, exit_queue_info: ExitQueueInfo,
cache: var StateCache): Result[void, cstring] = cache: var StateCache): Result[ExitQueueInfo, cstring] =
let exited_validator = let exited_validator =
? check_voluntary_exit(cfg, state, signed_voluntary_exit, flags) ? check_voluntary_exit(cfg, state, signed_voluntary_exit, flags)
? initiate_validator_exit(cfg, state, exited_validator, cache) ok(? initiate_validator_exit(
ok() cfg, state, exited_validator, exit_queue_info, cache))
proc process_bls_to_execution_change*( proc process_bls_to_execution_change*(
cfg: RuntimeConfig, cfg: RuntimeConfig,
@ -464,12 +472,25 @@ proc process_operations(cfg: RuntimeConfig,
var operations_rewards: BlockRewards var operations_rewards: BlockRewards
# It costs a full validator set scan to construct these values; only do so if
# there will be some kind of exit.
var exit_queue_info =
if body.proposer_slashings.len + body.attester_slashings.len +
body.voluntary_exits.len > 0:
get_state_exit_queue_info(cfg, state, cache)
else:
default(ExitQueueInfo) # not used
for op in body.proposer_slashings: for op in body.proposer_slashings:
operations_rewards.proposer_slashings += let (proposer_slashing_reward, new_exit_queue_info) =
? process_proposer_slashing(cfg, state, op, flags, cache) ? process_proposer_slashing(cfg, state, op, flags, exit_queue_info, cache)
operations_rewards.proposer_slashings += proposer_slashing_reward
exit_queue_info = new_exit_queue_info
for op in body.attester_slashings: for op in body.attester_slashings:
operations_rewards.attester_slashings += let (attester_slashing_reward, new_exit_queue_info) =
? process_attester_slashing(cfg, state, op, flags, cache) ? process_attester_slashing(cfg, state, op, flags, exit_queue_info, cache)
operations_rewards.attester_slashings += attester_slashing_reward
exit_queue_info = new_exit_queue_info
for op in body.attestations: for op in body.attestations:
operations_rewards.attestations += operations_rewards.attestations +=
? process_attestation(state, op, flags, base_reward_per_increment, cache) ? process_attestation(state, op, flags, base_reward_per_increment, cache)
@ -478,7 +499,8 @@ proc process_operations(cfg: RuntimeConfig,
for op in body.deposits: for op in body.deposits:
? process_deposit(cfg, state, bloom_filter[], op, flags) ? process_deposit(cfg, state, bloom_filter[], op, flags)
for op in body.voluntary_exits: for op in body.voluntary_exits:
? process_voluntary_exit(cfg, state, op, flags, cache) exit_queue_info = ? process_voluntary_exit(
cfg, state, op, flags, exit_queue_info, cache)
when typeof(body).kind >= ConsensusFork.Capella: when typeof(body).kind >= ConsensusFork.Capella:
for op in body.bls_to_execution_changes: for op in body.bls_to_execution_changes:
? process_bls_to_execution_change(cfg, state, op) ? process_bls_to_execution_change(cfg, state, op)

View File

@ -897,6 +897,9 @@ func process_registry_updates*(
get_validator_activation_churn_limit(cfg, state, cache) get_validator_activation_churn_limit(cfg, state, cache)
else: else:
get_validator_churn_limit(cfg, state, cache) get_validator_churn_limit(cfg, state, cache)
var maybe_exit_queue_info: Opt[ExitQueueInfo]
for vidx in state.validators.vindices: for vidx in state.validators.vindices:
if is_eligible_for_activation_queue(state.validators.item(vidx)): if is_eligible_for_activation_queue(state.validators.item(vidx)):
state.validators.mitem(vidx).activation_eligibility_epoch = state.validators.mitem(vidx).activation_eligibility_epoch =
@ -904,7 +907,17 @@ func process_registry_updates*(
if is_active_validator(state.validators.item(vidx), get_current_epoch(state)) and if is_active_validator(state.validators.item(vidx), get_current_epoch(state)) and
state.validators.item(vidx).effective_balance <= cfg.EJECTION_BALANCE.Gwei: state.validators.item(vidx).effective_balance <= cfg.EJECTION_BALANCE.Gwei:
? initiate_validator_exit(cfg, state, vidx, cache) # Typically, there will be no ejected validators, and even more rarely,
# more than one. Therefore, only calculate the information required for
# initiate_validator_exit if there actually is at least one.
let exit_queue_info = maybe_exit_queue_info.valueOr:
let initial_exit_queue_info = get_state_exit_queue_info(
cfg, state, cache)
maybe_exit_queue_info = Opt.some initial_exit_queue_info
initial_exit_queue_info
maybe_exit_queue_info = Opt.some (? initiate_validator_exit(
cfg, state, vidx, exit_queue_info, cache))
let validator = unsafeAddr state.validators.item(vidx) let validator = unsafeAddr state.validators.item(vidx)
if is_eligible_for_activation(state, validator[]): if is_eligible_for_activation(state, validator[]):

View File

@ -108,7 +108,9 @@ proc nfuzz_attestation(input: openArray[byte], xoutput: ptr byte,
proc nfuzz_attester_slashing(input: openArray[byte], xoutput: ptr byte, proc nfuzz_attester_slashing(input: openArray[byte], xoutput: ptr byte,
xoutput_size: ptr uint, disable_bls: bool): bool {.exportc, raises: [FuzzCrashError].} = xoutput_size: ptr uint, disable_bls: bool): bool {.exportc, raises: [FuzzCrashError].} =
decodeAndProcess(AttesterSlashingInput): decodeAndProcess(AttesterSlashingInput):
process_attester_slashing(getRuntimeConfig(some "mainnet"), data.state, data.attesterSlashing, flags, cache).isOk process_attester_slashing(getRuntimeConfig(some "mainnet"), data.state,
data.attesterSlashing, flags, get_state_exit_queue_info(
getRuntimeConfig(some "mainnet"), data.state, cache), cache).isOk
proc nfuzz_block(input: openArray[byte], xoutput: ptr byte, proc nfuzz_block(input: openArray[byte], xoutput: ptr byte,
xoutput_size: ptr uint, disable_bls: bool): bool {.exportc, raises: [FuzzCrashError].} = xoutput_size: ptr uint, disable_bls: bool): bool {.exportc, raises: [FuzzCrashError].} =
@ -152,12 +154,16 @@ proc nfuzz_deposit(input: openArray[byte], xoutput: ptr byte,
proc nfuzz_proposer_slashing(input: openArray[byte], xoutput: ptr byte, proc nfuzz_proposer_slashing(input: openArray[byte], xoutput: ptr byte,
xoutput_size: ptr uint, disable_bls: bool): bool {.exportc, raises: [FuzzCrashError].} = xoutput_size: ptr uint, disable_bls: bool): bool {.exportc, raises: [FuzzCrashError].} =
decodeAndProcess(ProposerSlashingInput): decodeAndProcess(ProposerSlashingInput):
process_proposer_slashing(getRuntimeConfig(some "mainnet"), data.state, data.proposerSlashing, flags, cache).isOk process_proposer_slashing(getRuntimeConfig(some "mainnet"), data.state,
data.proposerSlashing, flags, get_state_exit_queue_info(
getRuntimeConfig(some "mainnet"), data.state, cache), cache).isOk
proc nfuzz_voluntary_exit(input: openArray[byte], xoutput: ptr byte, proc nfuzz_voluntary_exit(input: openArray[byte], xoutput: ptr byte,
xoutput_size: ptr uint, disable_bls: bool): bool {.exportc, raises: [FuzzCrashError].} = xoutput_size: ptr uint, disable_bls: bool): bool {.exportc, raises: [FuzzCrashError].} =
decodeAndProcess(VoluntaryExitInput): decodeAndProcess(VoluntaryExitInput):
process_voluntary_exit(getRuntimeConfig(some "mainnet"), data.state, data.exit, flags, cache).isOk process_voluntary_exit(getRuntimeConfig(some "mainnet"), data.state,
data.exit, flags, get_state_exit_queue_info(
getRuntimeConfig(some "mainnet"), data.state, cache), cache).isOk
# Note: Could also accept raw input pointer and access list_size + seed here. # Note: Could also accept raw input pointer and access list_size + seed here.
# However, list_size needs to be known also outside this proc to allocate xoutput. # However, list_size needs to be known also outside this proc to allocate xoutput.
@ -182,4 +188,4 @@ func nfuzz_shuffle(input_seed: ptr byte, xoutput: var openArray[uint64]): bool
copyMem(offset(addr xoutput, i), shuffled_seq[i].unsafeAddr, copyMem(offset(addr xoutput, i), shuffled_seq[i].unsafeAddr,
sizeof(ValidatorIndex)) sizeof(ValidatorIndex))
true true

View File

@ -95,7 +95,9 @@ suite baseDescription & "Attester Slashing " & preset():
Result[void, cstring] = Result[void, cstring] =
var cache: StateCache var cache: StateCache
doAssert (? process_attester_slashing( doAssert (? process_attester_slashing(
defaultRuntimeConfig, preState, attesterSlashing, {}, cache)) > 0.Gwei defaultRuntimeConfig, preState, attesterSlashing, {strictVerification},
get_state_exit_queue_info(defaultRuntimeConfig, preState, cache),
cache))[0] > 0.Gwei
ok() ok()
for path in walkTests(OpAttSlashingDir): for path in walkTests(OpAttSlashingDir):
@ -134,7 +136,9 @@ suite baseDescription & "Proposer Slashing " & preset():
Result[void, cstring] = Result[void, cstring] =
var cache: StateCache var cache: StateCache
doAssert (? process_proposer_slashing( doAssert (? process_proposer_slashing(
defaultRuntimeConfig, preState, proposerSlashing, {}, cache)) > 0.Gwei defaultRuntimeConfig, preState, proposerSlashing, {},
get_state_exit_queue_info(defaultRuntimeConfig, preState, cache),
cache))[0] > 0.Gwei
ok() ok()
for path in walkTests(OpProposerSlashingDir): for path in walkTests(OpProposerSlashingDir):
@ -162,10 +166,15 @@ suite baseDescription & "Voluntary Exit " & preset():
preState: var altair.BeaconState, voluntaryExit: SignedVoluntaryExit): preState: var altair.BeaconState, voluntaryExit: SignedVoluntaryExit):
Result[void, cstring] = Result[void, cstring] =
var cache: StateCache var cache: StateCache
process_voluntary_exit( if process_voluntary_exit(
defaultRuntimeConfig, preState, voluntaryExit, {}, cache) defaultRuntimeConfig, preState, voluntaryExit, {},
get_state_exit_queue_info(defaultRuntimeConfig, preState, cache),
cache).isOk:
ok()
else:
err("")
for path in walkTests(OpVoluntaryExitDir): for path in walkTests(OpVoluntaryExitDir):
runTest[SignedVoluntaryExit, typeof applyVoluntaryExit]( runTest[SignedVoluntaryExit, typeof applyVoluntaryExit](
OpVoluntaryExitDir, suiteName, "Voluntary Exit", "voluntary_exit", OpVoluntaryExitDir, suiteName, "Voluntary Exit", "voluntary_exit",
applyVoluntaryExit, path) applyVoluntaryExit, path)

View File

@ -24,7 +24,8 @@ import
from std/sequtils import mapIt, toSeq from std/sequtils import mapIt, toSeq
from std/strutils import contains from std/strutils import contains
from ../../../beacon_chain/spec/beaconstate import from ../../../beacon_chain/spec/beaconstate import
get_base_reward_per_increment, get_total_active_balance, process_attestation get_base_reward_per_increment, get_state_exit_queue_info,
get_total_active_balance, process_attestation
const const
OpDir = SszTestsDir/const_preset/"bellatrix"/"operations" OpDir = SszTestsDir/const_preset/"bellatrix"/"operations"
@ -100,7 +101,9 @@ suite baseDescription & "Attester Slashing " & preset():
Result[void, cstring] = Result[void, cstring] =
var cache: StateCache var cache: StateCache
doAssert (? process_attester_slashing( doAssert (? process_attester_slashing(
defaultRuntimeConfig, preState, attesterSlashing, {}, cache)) > 0.Gwei defaultRuntimeConfig, preState, attesterSlashing, {strictVerification},
get_state_exit_queue_info(defaultRuntimeConfig, preState, cache),
cache))[0] > 0.Gwei
ok() ok()
for path in walkTests(OpAttSlashingDir): for path in walkTests(OpAttSlashingDir):
@ -158,7 +161,9 @@ suite baseDescription & "Proposer Slashing " & preset():
Result[void, cstring] = Result[void, cstring] =
var cache: StateCache var cache: StateCache
doAssert (? process_proposer_slashing( doAssert (? process_proposer_slashing(
defaultRuntimeConfig, preState, proposerSlashing, {}, cache)) > 0.Gwei defaultRuntimeConfig, preState, proposerSlashing, {},
get_state_exit_queue_info(defaultRuntimeConfig, preState, cache),
cache))[0] > 0.Gwei
ok() ok()
for path in walkTests(OpProposerSlashingDir): for path in walkTests(OpProposerSlashingDir):
@ -186,10 +191,15 @@ suite baseDescription & "Voluntary Exit " & preset():
preState: var bellatrix.BeaconState, voluntaryExit: SignedVoluntaryExit): preState: var bellatrix.BeaconState, voluntaryExit: SignedVoluntaryExit):
Result[void, cstring] = Result[void, cstring] =
var cache: StateCache var cache: StateCache
process_voluntary_exit( if process_voluntary_exit(
defaultRuntimeConfig, preState, voluntaryExit, {}, cache) defaultRuntimeConfig, preState, voluntaryExit, {},
get_state_exit_queue_info(defaultRuntimeConfig, preState, cache),
cache).isOk:
ok()
else:
err("")
for path in walkTests(OpVoluntaryExitDir): for path in walkTests(OpVoluntaryExitDir):
runTest[SignedVoluntaryExit, typeof applyVoluntaryExit]( runTest[SignedVoluntaryExit, typeof applyVoluntaryExit](
OpVoluntaryExitDir, suiteName, "Voluntary Exit", "voluntary_exit", OpVoluntaryExitDir, suiteName, "Voluntary Exit", "voluntary_exit",
applyVoluntaryExit, path) applyVoluntaryExit, path)

View File

@ -24,7 +24,8 @@ import
from std/sequtils import mapIt, toSeq from std/sequtils import mapIt, toSeq
from std/strutils import contains from std/strutils import contains
from ../../../beacon_chain/spec/beaconstate import from ../../../beacon_chain/spec/beaconstate import
get_base_reward_per_increment, get_total_active_balance, process_attestation get_base_reward_per_increment, get_state_exit_queue_info,
get_total_active_balance, process_attestation
const const
OpDir = SszTestsDir/const_preset/"capella"/"operations" OpDir = SszTestsDir/const_preset/"capella"/"operations"
@ -104,7 +105,9 @@ suite baseDescription & "Attester Slashing " & preset():
Result[void, cstring] = Result[void, cstring] =
var cache: StateCache var cache: StateCache
doAssert (? process_attester_slashing( doAssert (? process_attester_slashing(
defaultRuntimeConfig, preState, attesterSlashing, {}, cache)) > 0.Gwei defaultRuntimeConfig, preState, attesterSlashing, {strictVerification},
get_state_exit_queue_info(defaultRuntimeConfig, preState,
cache), cache))[0] > 0.Gwei
ok() ok()
for path in walkTests(OpAttSlashingDir): for path in walkTests(OpAttSlashingDir):
@ -175,7 +178,9 @@ suite baseDescription & "Proposer Slashing " & preset():
Result[void, cstring] = Result[void, cstring] =
var cache: StateCache var cache: StateCache
doAssert (? process_proposer_slashing( doAssert (? process_proposer_slashing(
defaultRuntimeConfig, preState, proposerSlashing, {}, cache)) > 0.Gwei defaultRuntimeConfig, preState, proposerSlashing, {},
get_state_exit_queue_info(defaultRuntimeConfig, preState, cache),
cache))[0] > 0.Gwei
ok() ok()
for path in walkTests(OpProposerSlashingDir): for path in walkTests(OpProposerSlashingDir):
@ -203,8 +208,13 @@ suite baseDescription & "Voluntary Exit " & preset():
preState: var capella.BeaconState, voluntaryExit: SignedVoluntaryExit): preState: var capella.BeaconState, voluntaryExit: SignedVoluntaryExit):
Result[void, cstring] = Result[void, cstring] =
var cache: StateCache var cache: StateCache
process_voluntary_exit( if process_voluntary_exit(
defaultRuntimeConfig, preState, voluntaryExit, {}, cache) defaultRuntimeConfig, preState, voluntaryExit, {},
get_state_exit_queue_info(defaultRuntimeConfig, preState, cache),
cache).isOk:
ok()
else:
err("")
for path in walkTests(OpVoluntaryExitDir): for path in walkTests(OpVoluntaryExitDir):
runTest[SignedVoluntaryExit, typeof applyVoluntaryExit]( runTest[SignedVoluntaryExit, typeof applyVoluntaryExit](
@ -220,4 +230,4 @@ suite baseDescription & "Withdrawals " & preset():
for path in walkTests(OpWithdrawalsDir): for path in walkTests(OpWithdrawalsDir):
runTest[capella.ExecutionPayload, typeof applyWithdrawals]( runTest[capella.ExecutionPayload, typeof applyWithdrawals](
OpWithdrawalsDir, suiteName, "Withdrawals", "execution_payload", OpWithdrawalsDir, suiteName, "Withdrawals", "execution_payload",
applyWithdrawals, path) applyWithdrawals, path)

View File

@ -24,7 +24,8 @@ import
from std/sequtils import mapIt, toSeq from std/sequtils import mapIt, toSeq
from std/strutils import contains from std/strutils import contains
from ../../../beacon_chain/spec/beaconstate import from ../../../beacon_chain/spec/beaconstate import
get_base_reward_per_increment, get_total_active_balance, process_attestation get_base_reward_per_increment, get_state_exit_queue_info,
get_total_active_balance, process_attestation
const const
OpDir = SszTestsDir/const_preset/"deneb"/"operations" OpDir = SszTestsDir/const_preset/"deneb"/"operations"
@ -90,7 +91,7 @@ suite baseDescription & "Attestation " & preset():
# This returns the proposer reward for including the attestation, which # This returns the proposer reward for including the attestation, which
# isn't tested here. # isn't tested here.
discard ? process_attestation( discard ? process_attestation(
preState, attestation, {}, base_reward_per_increment, cache) preState, attestation, {strictVerification}, base_reward_per_increment, cache)
ok() ok()
for path in walkTests(OpAttestationsDir): for path in walkTests(OpAttestationsDir):
@ -104,7 +105,9 @@ suite baseDescription & "Attester Slashing " & preset():
Result[void, cstring] = Result[void, cstring] =
var cache: StateCache var cache: StateCache
doAssert (? process_attester_slashing( doAssert (? process_attester_slashing(
defaultRuntimeConfig, preState, attesterSlashing, {}, cache)) > 0.Gwei defaultRuntimeConfig, preState, attesterSlashing, {strictVerification},
get_state_exit_queue_info(defaultRuntimeConfig, preState, cache),
cache))[0] > 0.Gwei
ok() ok()
for path in walkTests(OpAttSlashingDir): for path in walkTests(OpAttSlashingDir):
@ -177,7 +180,9 @@ suite baseDescription & "Proposer Slashing " & preset():
Result[void, cstring] = Result[void, cstring] =
var cache: StateCache var cache: StateCache
doAssert (? process_proposer_slashing( doAssert (? process_proposer_slashing(
defaultRuntimeConfig, preState, proposerSlashing, {}, cache)) > 0.Gwei defaultRuntimeConfig, preState, proposerSlashing, {},
get_state_exit_queue_info(defaultRuntimeConfig, preState, cache),
cache))[0] > 0.Gwei
ok() ok()
for path in walkTests(OpProposerSlashingDir): for path in walkTests(OpProposerSlashingDir):
@ -205,8 +210,13 @@ suite baseDescription & "Voluntary Exit " & preset():
preState: var deneb.BeaconState, voluntaryExit: SignedVoluntaryExit): preState: var deneb.BeaconState, voluntaryExit: SignedVoluntaryExit):
Result[void, cstring] = Result[void, cstring] =
var cache: StateCache var cache: StateCache
process_voluntary_exit( if process_voluntary_exit(
defaultRuntimeConfig, preState, voluntaryExit, {}, cache) defaultRuntimeConfig, preState, voluntaryExit, {},
get_state_exit_queue_info(defaultRuntimeConfig, preState, cache),
cache).isOk:
ok()
else:
err("")
for path in walkTests(OpVoluntaryExitDir): for path in walkTests(OpVoluntaryExitDir):
runTest[SignedVoluntaryExit, typeof applyVoluntaryExit]( runTest[SignedVoluntaryExit, typeof applyVoluntaryExit](
@ -222,4 +232,4 @@ suite baseDescription & "Withdrawals " & preset():
for path in walkTests(OpWithdrawalsDir): for path in walkTests(OpWithdrawalsDir):
runTest[deneb.ExecutionPayload, typeof applyWithdrawals]( runTest[deneb.ExecutionPayload, typeof applyWithdrawals](
OpWithdrawalsDir, suiteName, "Withdrawals", "execution_payload", OpWithdrawalsDir, suiteName, "Withdrawals", "execution_payload",
applyWithdrawals, path) applyWithdrawals, path)

View File

@ -86,7 +86,9 @@ suite baseDescription & "Attester Slashing " & preset():
Result[void, cstring] = Result[void, cstring] =
var cache: StateCache var cache: StateCache
doAssert (? process_attester_slashing( doAssert (? process_attester_slashing(
defaultRuntimeConfig, preState, attesterSlashing, {}, cache)) > 0.Gwei defaultRuntimeConfig, preState, attesterSlashing, {strictVerification},
get_state_exit_queue_info(defaultRuntimeConfig, preState, cache),
cache))[0] > 0.Gwei
ok() ok()
for path in walkTests(OpAttSlashingDir): for path in walkTests(OpAttSlashingDir):
@ -126,7 +128,9 @@ suite baseDescription & "Proposer Slashing " & preset():
Result[void, cstring] = Result[void, cstring] =
var cache: StateCache var cache: StateCache
doAssert (? process_proposer_slashing( doAssert (? process_proposer_slashing(
defaultRuntimeConfig, preState, proposerSlashing, {}, cache)) > 0.Gwei defaultRuntimeConfig, preState, proposerSlashing, {},
get_state_exit_queue_info(defaultRuntimeConfig, preState,
cache), cache))[0] > 0.Gwei
ok() ok()
for path in walkTests(OpProposerSlashingDir): for path in walkTests(OpProposerSlashingDir):
@ -139,10 +143,15 @@ suite baseDescription & "Voluntary Exit " & preset():
preState: var phase0.BeaconState, voluntaryExit: SignedVoluntaryExit): preState: var phase0.BeaconState, voluntaryExit: SignedVoluntaryExit):
Result[void, cstring] = Result[void, cstring] =
var cache: StateCache var cache: StateCache
process_voluntary_exit( if process_voluntary_exit(
defaultRuntimeConfig, preState, voluntaryExit, {}, cache) defaultRuntimeConfig, preState, voluntaryExit, {},
get_state_exit_queue_info(defaultRuntimeConfig, preState, cache),
cache).isOk:
ok()
else:
err("")
for path in walkTests(OpVoluntaryExitDir): for path in walkTests(OpVoluntaryExitDir):
runTest[SignedVoluntaryExit, typeof applyVoluntaryExit]( runTest[SignedVoluntaryExit, typeof applyVoluntaryExit](
OpVoluntaryExitDir, suiteName, "Voluntary Exit", "voluntary_exit", OpVoluntaryExitDir, suiteName, "Voluntary Exit", "voluntary_exit",
applyVoluntaryExit, path) applyVoluntaryExit, path)