Skip to content

Commit

Permalink
Merge pull request #3818 from mkalinin/deposit-queue
Browse files Browse the repository at this point in the history
eip6110: Queue deposit requests and apply them during epoch processing
  • Loading branch information
jtraglia authored Oct 4, 2024
2 parents 233afd5 + ad42273 commit 7df1ce3
Show file tree
Hide file tree
Showing 25 changed files with 1,519 additions and 712 deletions.
7 changes: 6 additions & 1 deletion presets/mainnet/electra.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ MAX_EFFECTIVE_BALANCE_ELECTRA: 2048000000000
# State list lengths
# ---------------------------------------------------------------
# `uint64(2**27)` (= 134,217,728)
PENDING_BALANCE_DEPOSITS_LIMIT: 134217728
PENDING_DEPOSITS_LIMIT: 134217728
# `uint64(2**27)` (= 134,217,728)
PENDING_PARTIAL_WITHDRAWALS_LIMIT: 134217728
# `uint64(2**18)` (= 262,144)
Expand Down Expand Up @@ -43,3 +43,8 @@ MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD: 16
# ---------------------------------------------------------------
# 2**3 ( = 8) pending withdrawals
MAX_PENDING_PARTIALS_PER_WITHDRAWALS_SWEEP: 8

# Pending deposits processing
# ---------------------------------------------------------------
# 2**4 ( = 4) pending deposits
MAX_PENDING_DEPOSITS_PER_EPOCH: 16
7 changes: 6 additions & 1 deletion presets/minimal/electra.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ MAX_EFFECTIVE_BALANCE_ELECTRA: 2048000000000
# State list lengths
# ---------------------------------------------------------------
# `uint64(2**27)` (= 134,217,728)
PENDING_BALANCE_DEPOSITS_LIMIT: 134217728
PENDING_DEPOSITS_LIMIT: 134217728
# [customized] `uint64(2**6)` (= 64)
PENDING_PARTIAL_WITHDRAWALS_LIMIT: 64
# [customized] `uint64(2**6)` (= 64)
Expand Down Expand Up @@ -43,3 +43,8 @@ MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD: 2
# ---------------------------------------------------------------
# 2**1 ( = 2) pending withdrawals
MAX_PENDING_PARTIALS_PER_WITHDRAWALS_SWEEP: 2

# Pending deposits processing
# ---------------------------------------------------------------
# 2**4 ( = 4) pending deposits
MAX_PENDING_DEPOSITS_PER_EPOCH: 16
2 changes: 1 addition & 1 deletion specs/_features/eip7732/beacon-chain.md
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ class BeaconState(Container):
earliest_exit_epoch: Epoch
consolidation_balance_to_consume: Gwei
earliest_consolidation_epoch: Epoch
pending_balance_deposits: List[PendingBalanceDeposit, PENDING_BALANCE_DEPOSITS_LIMIT]
pending_deposits: List[PendingDeposit, PENDING_DEPOSITS_LIMIT]
pending_partial_withdrawals: List[PendingPartialWithdrawal, PENDING_PARTIAL_WITHDRAWALS_LIMIT]
pending_consolidations: List[PendingConsolidation, PENDING_CONSOLIDATIONS_LIMIT]
# PBS
Expand Down
2 changes: 1 addition & 1 deletion specs/_features/eip7732/fork.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ def upgrade_to_eip7732(pre: electra.BeaconState) -> BeaconState:
earliest_exit_epoch=pre.earliest_exit_epoch,
consolidation_balance_to_consume=pre.consolidation_balance_to_consume,
earliest_consolidation_epoch=pre.earliest_consolidation_epoch,
pending_balance_deposits=pre.pending_balance_deposits,
pending_deposits=pre.pending_deposits,
pending_partial_withdrawals=pre.pending_partial_withdrawals,
pending_consolidations=pre.pending_consolidations,
# ePBS
Expand Down
272 changes: 197 additions & 75 deletions specs/electra/beacon-chain.md

Large diffs are not rendered by default.

14 changes: 10 additions & 4 deletions specs/electra/fork.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ def upgrade_to_electra(pre: deneb.BeaconState) -> BeaconState:
earliest_exit_epoch=earliest_exit_epoch,
consolidation_balance_to_consume=0,
earliest_consolidation_epoch=compute_activation_exit_epoch(get_current_epoch(pre)),
pending_balance_deposits=[],
pending_deposits=[],
pending_partial_withdrawals=[],
pending_consolidations=[],
)
Expand All @@ -157,9 +157,15 @@ def upgrade_to_electra(pre: deneb.BeaconState) -> BeaconState:
validator = post.validators[index]
validator.effective_balance = 0
validator.activation_eligibility_epoch = FAR_FUTURE_EPOCH
post.pending_balance_deposits.append(
PendingBalanceDeposit(index=index, amount=balance)
)
# Use bls.G2_POINT_AT_INFINITY as a signature field placeholder
# and GENESIS_SLOT to distinguish from a pending deposit request
post.pending_deposits.append(PendingDeposit(
pubkey=validator.pubkey,
withdrawal_credentials=validator.withdrawal_credentials,
amount=balance,
signature=bls.G2_POINT_AT_INFINITY,
slot=GENESIS_SLOT,
))

# Ensure early adopters of compounding credentials go through the activation churn
for index, validator in enumerate(post.validators):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,13 @@ def test_success_top_up_to_withdrawn_validator(spec, state):
yield from run_deposit_processing(spec, state, deposit, validator_index)

if is_post_electra(spec):
pending_balance_deposits_len = len(state.pending_balance_deposits)
pending_balance_deposit = state.pending_balance_deposits[pending_balance_deposits_len - 1]
assert pending_balance_deposit.amount == amount
assert pending_balance_deposit.index == validator_index
pending_deposits_len = len(state.pending_deposits)
pending_deposit = state.pending_deposits[pending_deposits_len - 1]
assert pending_deposit.pubkey == deposit.data.pubkey
assert pending_deposit.withdrawal_credentials == deposit.data.withdrawal_credentials
assert pending_deposit.amount == deposit.data.amount
assert pending_deposit.signature == deposit.data.signature
assert pending_deposit.slot == spec.GENESIS_SLOT
else:
assert state.balances[validator_index] == amount
assert state.validators[validator_index].effective_balance == 0
Expand All @@ -47,7 +50,7 @@ def test_success_top_up_to_withdrawn_validator(spec, state):
if is_post_electra(spec):
has_execution_withdrawal = spec.has_execution_withdrawal_credential(validator)
is_withdrawable = validator.withdrawable_epoch <= current_epoch
has_non_zero_balance = pending_balance_deposit.amount > 0
has_non_zero_balance = pending_deposit.amount > 0
# NOTE: directly compute `is_fully_withdrawable_validator` conditions here
# to work around how the epoch processing changed balance updates
assert has_execution_withdrawal and is_withdrawable and has_non_zero_balance
Expand Down
9 changes: 6 additions & 3 deletions tests/core/pyspec/eth2spec/test/capella/sanity/test_blocks.py
Original file line number Diff line number Diff line change
Expand Up @@ -365,8 +365,11 @@ def test_top_up_and_partial_withdrawable_validator(spec, state):
yield 'post', state

if is_post_electra(spec):
assert state.pending_balance_deposits[0].amount == amount
assert state.pending_balance_deposits[0].index == validator_index
assert state.pending_deposits[0].pubkey == deposit.data.pubkey
assert state.pending_deposits[0].withdrawal_credentials == deposit.data.withdrawal_credentials
assert state.pending_deposits[0].amount == deposit.data.amount
assert state.pending_deposits[0].signature == deposit.data.signature
assert state.pending_deposits[0].slot == spec.GENESIS_SLOT
else:
# Since withdrawals happen before deposits, it becomes partially withdrawable after state transition.
validator = state.validators[validator_index]
Expand Down Expand Up @@ -405,7 +408,7 @@ def test_top_up_to_fully_withdrawn_validator(spec, state):

balance = state.balances[validator_index]
if is_post_electra(spec):
balance += state.pending_balance_deposits[0].amount
balance += state.pending_deposits[0].amount

assert spec.is_fully_withdrawable_validator(
state.validators[validator_index],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1148,12 +1148,19 @@ def run_consolidation_processing(spec, state, consolidation, success=True):
assert state.pending_consolidations == pre_pending_consolidations + [expected_new_pending_consolidation]
# Check excess balance is queued if the target switched to compounding
if pre_target_withdrawal_credentials[:1] == spec.ETH1_ADDRESS_WITHDRAWAL_PREFIX:
assert state.validators[target_index].withdrawal_credentials == (
spec.COMPOUNDING_WITHDRAWAL_PREFIX + pre_target_withdrawal_credentials[1:])
post_target_withdrawal_credentials = (
spec.COMPOUNDING_WITHDRAWAL_PREFIX + pre_target_withdrawal_credentials[1:]
)
assert state.validators[target_index].withdrawal_credentials == post_target_withdrawal_credentials
assert state.balances[target_index] == spec.MIN_ACTIVATION_BALANCE
if pre_target_balance > spec.MIN_ACTIVATION_BALANCE:
assert state.pending_balance_deposits == [spec.PendingBalanceDeposit(
index=target_index, amount=(pre_target_balance - spec.MIN_ACTIVATION_BALANCE))]
assert len(state.pending_deposits) == 1
pending_deposit = state.pending_deposits[0]
assert pending_deposit.pubkey == target_validator.pubkey
assert pending_deposit.withdrawal_credentials == post_target_withdrawal_credentials
assert pending_deposit.amount == (pre_target_balance - spec.MIN_ACTIVATION_BALANCE)
assert pending_deposit.signature == spec.G2_POINT_AT_INFINITY
assert pending_deposit.slot == spec.GENESIS_SLOT
else:
assert state.balances[target_index] == pre_target_balance
else:
Expand Down Expand Up @@ -1194,14 +1201,20 @@ def run_switch_to_compounding_processing(spec, state, consolidation, success=Tru
# Check source address in the consolidation fits the withdrawal credentials
assert state.validators[source_index].withdrawal_credentials[12:] == consolidation.source_address
# Check that the source has switched to compounding
assert state.validators[source_index].withdrawal_credentials == (
post_withdrawal_credentials = (
spec.COMPOUNDING_WITHDRAWAL_PREFIX + pre_withdrawal_credentials[1:]
)
assert state.validators[source_index].withdrawal_credentials == post_withdrawal_credentials
# Check excess balance is queued
assert state.balances[source_index] == spec.MIN_ACTIVATION_BALANCE
if pre_balance > spec.MIN_ACTIVATION_BALANCE:
assert state.pending_balance_deposits == [spec.PendingBalanceDeposit(
index=source_index, amount=(pre_balance - spec.MIN_ACTIVATION_BALANCE))]
assert len(state.pending_deposits) == 1
pending_deposit = state.pending_deposits[0]
assert pending_deposit.pubkey == source_validator.pubkey
assert pending_deposit.withdrawal_credentials == post_withdrawal_credentials
assert pending_deposit.amount == (pre_balance - spec.MIN_ACTIVATION_BALANCE)
assert pending_deposit.signature == spec.G2_POINT_AT_INFINITY
assert pending_deposit.slot == spec.GENESIS_SLOT
# Check no consolidation has been initiated
assert state.validators[source_index].exit_epoch == spec.FAR_FUTURE_EPOCH
assert state.pending_consolidations == pre_pending_consolidations
Expand Down
Loading

0 comments on commit 7df1ce3

Please sign in to comment.