rm outdated/semi-duplicate execution layer withdrawal request processing (#6301)
This commit is contained in:
parent
34853ca155
commit
dd452f71d3
|
@ -507,43 +507,86 @@ proc process_bls_to_execution_change*(
|
|||
|
||||
ok()
|
||||
|
||||
# https://github.com/ethereum/consensus-specs/blob/94a0b6c581f2809aa8aca4ef7ee6fbb63f9d74e9/specs/electra/beacon-chain.md#new-process_execution_layer_exit
|
||||
func process_execution_layer_withdrawal_request(
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.2/specs/electra/beacon-chain.md#new-process_execution_layer_withdrawal_request
|
||||
func process_execution_layer_withdrawal_request*(
|
||||
cfg: RuntimeConfig, state: var electra.BeaconState,
|
||||
execution_layer_withdrawal_request: ExecutionLayerWithdrawalRequest,
|
||||
exit_queue_info: ExitQueueInfo, cache: var StateCache):
|
||||
Result[ExitQueueInfo, cstring] =
|
||||
# Verify pubkey exists
|
||||
cache: var StateCache) =
|
||||
let
|
||||
pubkey_to_exit = execution_layer_withdrawal_request.validator_pubkey
|
||||
validator_index = findValidatorIndex(state, pubkey_to_exit).valueOr:
|
||||
return err("process_execution_layer_withdrawal_request: unknown index for validator pubkey")
|
||||
validator = state.validators.item(validator_index)
|
||||
amount = execution_layer_withdrawal_request.amount
|
||||
is_full_exit_request = amount == static(FULL_EXIT_REQUEST_AMOUNT.Gwei)
|
||||
|
||||
# If partial withdrawal queue is full, only full exits are processed
|
||||
if lenu64(state.pending_partial_withdrawals) ==
|
||||
PENDING_PARTIAL_WITHDRAWALS_LIMIT and not is_full_exit_request:
|
||||
return
|
||||
|
||||
let
|
||||
request_pubkey = execution_layer_withdrawal_request.validator_pubkey
|
||||
index = findValidatorIndex(state, request_pubkey).valueOr:
|
||||
return
|
||||
validator = state.validators.item(index)
|
||||
|
||||
# Verify withdrawal credentials
|
||||
let
|
||||
is_execution_address = validator.has_eth1_withdrawal_credential
|
||||
has_correct_credential = has_execution_withdrawal_credential(validator)
|
||||
is_correct_source_address =
|
||||
validator.withdrawal_credentials.data.toOpenArray(12, 31) ==
|
||||
execution_layer_withdrawal_request.source_address.data
|
||||
if not (is_execution_address and is_correct_source_address):
|
||||
return err("process_execution_layer_withdrawal_request: not both execution address and correct source address")
|
||||
|
||||
if not (has_correct_credential and is_correct_source_address):
|
||||
return
|
||||
|
||||
# Verify the validator is active
|
||||
if not is_active_validator(validator, get_current_epoch(state)):
|
||||
return err("process_execution_layer_withdrawal_request: not active validator")
|
||||
return
|
||||
|
||||
# Verify exit has not been initiated
|
||||
if validator.exit_epoch != FAR_FUTURE_EPOCH:
|
||||
return err("process_execution_layer_withdrawal_request: validator exit already initiated")
|
||||
return
|
||||
|
||||
# Verify the validator has been active long enough
|
||||
if get_current_epoch(state) < validator.activation_epoch + cfg.SHARD_COMMITTEE_PERIOD:
|
||||
return err("process_execution_layer_withdrawal_request: validator not active long enough")
|
||||
if get_current_epoch(state) <
|
||||
validator.activation_epoch + cfg.SHARD_COMMITTEE_PERIOD:
|
||||
return
|
||||
|
||||
# Initiate exit
|
||||
ok(? initiate_validator_exit(
|
||||
cfg, state, validator_index, exit_queue_info, cache))
|
||||
let pending_balance_to_withdraw =
|
||||
get_pending_balance_to_withdraw(state, index)
|
||||
|
||||
if is_full_exit_request:
|
||||
# Only exit validator if it has no pending withdrawals in the queue
|
||||
if pending_balance_to_withdraw == 0.Gwei:
|
||||
if initiate_validator_exit(cfg, state, index, default(ExitQueueInfo),
|
||||
cache).isErr():
|
||||
return
|
||||
return
|
||||
|
||||
let
|
||||
has_sufficient_effective_balance =
|
||||
validator.effective_balance >= static(MIN_ACTIVATION_BALANCE.Gwei)
|
||||
has_excess_balance = state.balances.item(index) >
|
||||
static(MIN_ACTIVATION_BALANCE.Gwei) + pending_balance_to_withdraw
|
||||
|
||||
# Only allow partial withdrawals with compounding withdrawal credentials
|
||||
if has_compounding_withdrawal_credential(validator) and
|
||||
has_sufficient_effective_balance and has_excess_balance:
|
||||
let
|
||||
to_withdraw = min(
|
||||
state.balances.item(index) - static(MIN_ACTIVATION_BALANCE.Gwei) -
|
||||
pending_balance_to_withdraw,
|
||||
amount
|
||||
)
|
||||
exit_queue_epoch =
|
||||
compute_exit_epoch_and_update_churn(cfg, state, to_withdraw, cache)
|
||||
withdrawable_epoch =
|
||||
Epoch(exit_queue_epoch + cfg.MIN_VALIDATOR_WITHDRAWABILITY_DELAY)
|
||||
|
||||
# In theory can fail, but failing/early returning here is indistinguishable
|
||||
discard state.pending_partial_withdrawals.add(PendingPartialWithdrawal(
|
||||
index: index.uint64,
|
||||
amount: to_withdraw,
|
||||
withdrawable_epoch: withdrawable_epoch,
|
||||
))
|
||||
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.0/specs/electra/beacon-chain.md#consolidations
|
||||
proc process_consolidation*(
|
||||
|
@ -703,8 +746,8 @@ proc process_operations(
|
|||
# [New in Electra:EIP7002:EIP7251]
|
||||
when typeof(body).kind >= ConsensusFork.Electra:
|
||||
for op in body.execution_payload.withdrawal_requests:
|
||||
discard ? process_execution_layer_withdrawal_request(
|
||||
cfg, state, op, default(ExitQueueInfo), cache)
|
||||
process_execution_layer_withdrawal_request(
|
||||
cfg, state, op, cache)
|
||||
for op in body.execution_payload.deposit_receipts:
|
||||
debugComment "combine with previous bloom filter construction"
|
||||
let bloom_filter = constructBloomFilter(state.validators.asSeq)
|
||||
|
@ -1035,87 +1078,6 @@ func process_withdrawals*(
|
|||
|
||||
ok()
|
||||
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.5.0-alpha.0/specs/electra/beacon-chain.md#new-process_execution_layer_withdrawal_request
|
||||
func process_execution_layer_withdrawal_request*(
|
||||
cfg: RuntimeConfig, state: var electra.BeaconState,
|
||||
execution_layer_withdrawal_request: ExecutionLayerWithdrawalRequest,
|
||||
cache: var StateCache) =
|
||||
let
|
||||
amount = execution_layer_withdrawal_request.amount
|
||||
is_full_exit_request = amount == static(FULL_EXIT_REQUEST_AMOUNT.Gwei)
|
||||
|
||||
# If partial withdrawal queue is full, only full exits are processed
|
||||
if lenu64(state.pending_partial_withdrawals) ==
|
||||
PENDING_PARTIAL_WITHDRAWALS_LIMIT and not is_full_exit_request:
|
||||
return
|
||||
|
||||
let
|
||||
request_pubkey = execution_layer_withdrawal_request.validator_pubkey
|
||||
index = findValidatorIndex(state, request_pubkey).valueOr:
|
||||
return
|
||||
validator = state.validators.item(index)
|
||||
|
||||
# Verify withdrawal credentials
|
||||
let
|
||||
has_correct_credential = has_execution_withdrawal_credential(validator)
|
||||
is_correct_source_address =
|
||||
validator.withdrawal_credentials.data.toOpenArray(12, 31) ==
|
||||
execution_layer_withdrawal_request.source_address.data
|
||||
|
||||
if not (has_correct_credential and is_correct_source_address):
|
||||
return
|
||||
|
||||
# Verify the validator is active
|
||||
if not is_active_validator(validator, get_current_epoch(state)):
|
||||
return
|
||||
|
||||
# Verify exit has not been initiated
|
||||
if validator.exit_epoch != FAR_FUTURE_EPOCH:
|
||||
return
|
||||
|
||||
# Verify the validator has been active long enough
|
||||
if get_current_epoch(state) <
|
||||
validator.activation_epoch + cfg.SHARD_COMMITTEE_PERIOD:
|
||||
return
|
||||
|
||||
let pending_balance_to_withdraw =
|
||||
get_pending_balance_to_withdraw(state, index)
|
||||
|
||||
if is_full_exit_request:
|
||||
# Only exit validator if it has no pending withdrawals in the queue
|
||||
if pending_balance_to_withdraw == 0.Gwei:
|
||||
if initiate_validator_exit(cfg, state, index, default(ExitQueueInfo),
|
||||
cache).isErr():
|
||||
return
|
||||
return
|
||||
|
||||
let
|
||||
has_sufficient_effective_balance =
|
||||
validator.effective_balance >= static(MIN_ACTIVATION_BALANCE.Gwei)
|
||||
has_excess_balance = state.balances.item(index) >
|
||||
static(MIN_ACTIVATION_BALANCE.Gwei) + pending_balance_to_withdraw
|
||||
|
||||
# Only allow partial withdrawals with compounding withdrawal credentials
|
||||
if has_compounding_withdrawal_credential(validator) and
|
||||
has_sufficient_effective_balance and has_excess_balance:
|
||||
let
|
||||
to_withdraw = min(
|
||||
state.balances.item(index) - static(MIN_ACTIVATION_BALANCE.Gwei) -
|
||||
pending_balance_to_withdraw,
|
||||
amount
|
||||
)
|
||||
exit_queue_epoch =
|
||||
compute_exit_epoch_and_update_churn(cfg, state, to_withdraw, cache)
|
||||
withdrawable_epoch =
|
||||
Epoch(exit_queue_epoch + cfg.MIN_VALIDATOR_WITHDRAWABILITY_DELAY)
|
||||
|
||||
# In theory can fail, but failing/early returning here is indistinguishable
|
||||
discard state.pending_partial_withdrawals.add(PendingPartialWithdrawal(
|
||||
index: index.uint64,
|
||||
amount: to_withdraw,
|
||||
withdrawable_epoch: withdrawable_epoch,
|
||||
))
|
||||
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/deneb/beacon-chain.md#kzg_commitment_to_versioned_hash
|
||||
func kzg_commitment_to_versioned_hash*(
|
||||
kzg_commitment: KzgCommitment): VersionedHash =
|
||||
|
|
|
@ -239,16 +239,19 @@ proc doSSZ(conf: NcliConf) =
|
|||
of "bellatrix_signed_block": printit(bellatrix.SignedBeaconBlock)
|
||||
of "capella_signed_block": printit(capella.SignedBeaconBlock)
|
||||
of "deneb_signed_block": printit(deneb.SignedBeaconBlock)
|
||||
of "electra_signed_block": printit(electra.SignedBeaconBlock)
|
||||
of "phase0_block": printit(phase0.BeaconBlock)
|
||||
of "altair_block": printit(altair.BeaconBlock)
|
||||
of "bellatrix_block": printit(bellatrix.BeaconBlock)
|
||||
of "capella_block": printit(capella.BeaconBlock)
|
||||
of "deneb_block": printit(deneb.BeaconBlock)
|
||||
of "electra_block": printit(electra.BeaconBlock)
|
||||
of "phase0_block_body": printit(phase0.BeaconBlockBody)
|
||||
of "altair_block_body": printit(altair.BeaconBlockBody)
|
||||
of "bellatrix_block_body": printit(bellatrix.BeaconBlockBody)
|
||||
of "capella_block_body": printit(capella.BeaconBlockBody)
|
||||
of "deneb_block_body": printit(deneb.BeaconBlockBody)
|
||||
of "electra_block_body": printit(electra.BeaconBlockBody)
|
||||
of "block_header": printit(BeaconBlockHeader)
|
||||
of "deposit": printit(Deposit)
|
||||
of "deposit_data": printit(DepositData)
|
||||
|
@ -258,6 +261,7 @@ proc doSSZ(conf: NcliConf) =
|
|||
of "bellatrix_state": printit(bellatrix.BeaconState)
|
||||
of "capella_state": printit(capella.BeaconState)
|
||||
of "deneb_state": printit(deneb.BeaconState)
|
||||
of "electra_state": printit(electra.BeaconState)
|
||||
of "proposer_slashing": printit(ProposerSlashing)
|
||||
of "voluntary_exit": printit(VoluntaryExit)
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
||||
|
||||
{.push raises: [].}
|
||||
{.used.}
|
||||
|
||||
import unittest2, results, chronos, stint
|
||||
import ../beacon_chain/validators/beacon_validators,
|
||||
|
|
Loading…
Reference in New Issue