Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

eip7251: Do not change creds type on consolidation #4020

Merged
merged 5 commits into from
Dec 3, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions presets/mainnet/electra.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ WHISTLEBLOWER_REWARD_QUOTIENT_ELECTRA: 4096
MAX_ATTESTER_SLASHINGS_ELECTRA: 1
# `uint64(2**3)` (= 8)
MAX_ATTESTATIONS_ELECTRA: 8
# `uint64(2**0)` (= 1)
MAX_CONSOLIDATION_REQUESTS_PER_PAYLOAD: 1
# `uint64(2**1)` (= 2)
MAX_CONSOLIDATION_REQUESTS_PER_PAYLOAD: 2

# Execution
# ---------------------------------------------------------------
Expand Down
4 changes: 2 additions & 2 deletions presets/minimal/electra.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ WHISTLEBLOWER_REWARD_QUOTIENT_ELECTRA: 4096
MAX_ATTESTER_SLASHINGS_ELECTRA: 1
# `uint64(2**3)` (= 8)
MAX_ATTESTATIONS_ELECTRA: 8
# `uint64(2**0)` (= 1)
MAX_CONSOLIDATION_REQUESTS_PER_PAYLOAD: 1
# `uint64(2**1)` (= 2)
MAX_CONSOLIDATION_REQUESTS_PER_PAYLOAD: 2

# Execution
# ---------------------------------------------------------------
Expand Down
10 changes: 3 additions & 7 deletions specs/electra/beacon-chain.md
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ The following values are (non-configurable) constants used throughout the specif
| - | - | - |
| `MAX_DEPOSIT_REQUESTS_PER_PAYLOAD` | `uint64(2**13)` (= 8,192) | *[New in Electra:EIP6110]* Maximum number of deposit receipts allowed in each payload |
| `MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD` | `uint64(2**4)` (= 16)| *[New in Electra:EIP7002]* Maximum number of execution layer withdrawal requests in each payload |
| `MAX_CONSOLIDATION_REQUESTS_PER_PAYLOAD` | `uint64(1)` (= 1) | *[New in Electra:EIP7251]* Maximum number of execution layer consolidation requests in each payload |
| `MAX_CONSOLIDATION_REQUESTS_PER_PAYLOAD` | `uint64(2**1)` (= 2) | *[New in Electra:EIP7251]* Maximum number of execution layer consolidation requests in each payload |

### Withdrawals processing

Expand Down Expand Up @@ -1643,8 +1643,8 @@ def process_consolidation_request(
if not (has_correct_credential and is_correct_source_address):
return

# Verify that target has execution withdrawal credentials
if not has_execution_withdrawal_credential(target_validator):
# Verify that target has compounding withdrawal credentials
if not has_compounding_withdrawal_credential(target_validator):
return

# Verify the source and the target are active
Expand Down Expand Up @@ -1676,10 +1676,6 @@ def process_consolidation_request(
source_index=source_index,
target_index=target_index
))

# Churn any target excess active balance of target and raise its max
if has_eth1_withdrawal_credential(target_validator):
switch_to_compounding_validator(state, target_index)
```

## Testing
Expand Down
mkalinin marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ def test_basic_consolidation_in_current_consolidation_epoch(spec, state):
target_pubkey=state.validators[target_index].pubkey,
)

# Set target to eth1 credentials
set_eth1_withdrawal_credential_with_balance(spec, state, target_index)
# Set target to compounding credentials
set_compounding_withdrawal_credential(spec, state, target_index)

# Set earliest consolidation epoch to the expected exit epoch
expected_exit_epoch = spec.compute_activation_exit_epoch(current_epoch)
Expand Down Expand Up @@ -96,59 +96,7 @@ def test_basic_consolidation_with_excess_target_balance(spec, state):
target_pubkey=state.validators[target_index].pubkey,
)

# Set target to eth1 credentials
set_eth1_withdrawal_credential_with_balance(spec, state, target_index)

# Set earliest consolidation epoch to the expected exit epoch
expected_exit_epoch = spec.compute_activation_exit_epoch(current_epoch)
state.earliest_consolidation_epoch = expected_exit_epoch
consolidation_churn_limit = spec.get_consolidation_churn_limit(state)
# Set the consolidation balance to consume equal to churn limit
state.consolidation_balance_to_consume = consolidation_churn_limit

# Add excess balance
state.balances[target_index] = state.balances[target_index] + spec.EFFECTIVE_BALANCE_INCREMENT

yield from run_consolidation_processing(spec, state, consolidation)

# Check consolidation churn is decremented correctly
assert (
state.consolidation_balance_to_consume
== consolidation_churn_limit - spec.MIN_ACTIVATION_BALANCE
)
# Check exit epoch
assert state.validators[source_index].exit_epoch == expected_exit_epoch


@with_electra_and_later
@with_presets([MINIMAL], "need sufficient consolidation churn limit")
@with_custom_state(
balances_fn=scaled_churn_balances_exceed_activation_exit_churn_limit,
threshold_fn=default_activation_threshold,
)
@spec_test
@single_phase
def test_basic_consolidation_with_excess_target_balance_and_compounding_credentials(spec, state):
# move state forward SHARD_COMMITTEE_PERIOD epochs to allow for consolidation
state.slot += spec.config.SHARD_COMMITTEE_PERIOD * spec.SLOTS_PER_EPOCH
# This state has 256 validators each with 32 ETH in MINIMAL preset, 128 ETH consolidation churn
current_epoch = spec.get_current_epoch(state)
source_index = spec.get_active_validator_indices(state, current_epoch)[0]
target_index = spec.get_active_validator_indices(state, current_epoch)[1]

# Set source to eth1 credentials
source_address = b"\x22" * 20
set_eth1_withdrawal_credential_with_balance(
spec, state, source_index, address=source_address
)
# Make consolidation with source address
consolidation = spec.ConsolidationRequest(
source_address=source_address,
source_pubkey=state.validators[source_index].pubkey,
target_pubkey=state.validators[target_index].pubkey,
)

# Set target to eth1 credentials
# Set target to compounding credentials
set_compounding_withdrawal_credential(spec, state, target_index)

# Set earliest consolidation epoch to the expected exit epoch
Expand Down Expand Up @@ -202,8 +150,8 @@ def test_basic_consolidation_in_new_consolidation_epoch(spec, state):
target_pubkey=state.validators[target_index].pubkey,
)

# Set target to eth1 credentials
set_eth1_withdrawal_credential_with_balance(spec, state, target_index)
# Set target to compounding credentials
set_compounding_withdrawal_credential(spec, state, target_index)

yield from run_consolidation_processing(spec, state, consolidation)

Expand Down Expand Up @@ -247,8 +195,8 @@ def test_basic_consolidation_with_preexisting_churn(spec, state):
target_pubkey=state.validators[target_index].pubkey,
)

# Set target to eth1 credentials
set_eth1_withdrawal_credential_with_balance(spec, state, target_index)
# Set target to compounding credentials
set_compounding_withdrawal_credential(spec, state, target_index)

# Set earliest consolidation epoch to the expected exit epoch
expected_exit_epoch = spec.compute_activation_exit_epoch(current_epoch)
Expand Down Expand Up @@ -296,8 +244,8 @@ def test_basic_consolidation_with_insufficient_preexisting_churn(spec, state):
target_pubkey=state.validators[target_index].pubkey,
)

# Set target to eth1 credentials
set_eth1_withdrawal_credential_with_balance(spec, state, target_index)
# Set target to compounding credentials
set_compounding_withdrawal_credential(spec, state, target_index)

# Set earliest consolidation epoch to the first available epoch
state.earliest_consolidation_epoch = spec.compute_activation_exit_epoch(
Expand Down Expand Up @@ -337,7 +285,7 @@ def test_basic_consolidation_with_compounding_credentials(spec, state):
source_index = spec.get_active_validator_indices(state, current_epoch)[0]
target_index = spec.get_active_validator_indices(state, current_epoch)[1]

# Set source to eth1 credentials
# Set source to compounding credentials
source_address = b"\x22" * 20
set_compounding_withdrawal_credential(
spec, state, source_index, address=source_address
Expand Down Expand Up @@ -396,8 +344,8 @@ def test_consolidation_churn_limit_balance(spec, state):
target_pubkey=state.validators[target_index].pubkey,
)

# Set target to eth1 credentials
set_eth1_withdrawal_credential_with_balance(spec, state, target_index)
# Set target to compounding credentials
set_compounding_withdrawal_credential(spec, state, target_index)

# Set source effective balance to consolidation churn limit
consolidation_churn_limit = spec.get_consolidation_churn_limit(state)
Expand Down Expand Up @@ -446,8 +394,8 @@ def test_consolidation_balance_larger_than_churn_limit(spec, state):
target_pubkey=state.validators[target_index].pubkey,
)

# Set target to eth1 credentials
set_eth1_withdrawal_credential_with_balance(spec, state, target_index)
# Set target to compounding credentials
set_compounding_withdrawal_credential(spec, state, target_index)

# Set source effective balance to 2 * consolidation churn limit
consolidation_churn_limit = spec.get_consolidation_churn_limit(state)
Expand Down Expand Up @@ -495,8 +443,8 @@ def test_consolidation_balance_through_two_churn_epochs(spec, state):
target_pubkey=state.validators[target_index].pubkey,
)

# Set target to eth1 credentials
set_eth1_withdrawal_credential_with_balance(spec, state, target_index)
# Set target to compounding credentials
set_compounding_withdrawal_credential(spec, state, target_index)

# Set source balance higher to 3 * consolidation churn limit
consolidation_churn_limit = spec.get_consolidation_churn_limit(state)
Expand Down Expand Up @@ -857,7 +805,7 @@ def test_incorrect_no_source_execution_withdrawal_credential(spec, state):
)
@spec_test
@single_phase
def test_incorrect_no_target_execution_withdrawal_credential(spec, state):
def test_incorrect_target_with_bls_credential(spec, state):
# move state forward SHARD_COMMITTEE_PERIOD epochs to allow for consolidation
state.slot += spec.config.SHARD_COMMITTEE_PERIOD * spec.SLOTS_PER_EPOCH
# Set up a correct consolidation, but target does not have
Expand All @@ -883,6 +831,39 @@ def test_incorrect_no_target_execution_withdrawal_credential(spec, state):
)


@with_electra_and_later
@with_presets([MINIMAL], "need sufficient consolidation churn limit")
@with_custom_state(
balances_fn=scaled_churn_balances_exceed_activation_exit_churn_limit,
threshold_fn=default_activation_threshold,
)
@spec_test
@single_phase
def test_incorrect_target_with_eth1_credential(spec, state):
# move state forward SHARD_COMMITTEE_PERIOD epochs to allow for consolidation
state.slot += spec.config.SHARD_COMMITTEE_PERIOD * spec.SLOTS_PER_EPOCH
# Set up an otherwise correct consolidation
current_epoch = spec.get_current_epoch(state)
source_index = spec.get_active_validator_indices(state, current_epoch)[0]
target_index = spec.get_active_validator_indices(state, current_epoch)[1]
source_address = b"\x22" * 20
set_eth1_withdrawal_credential_with_balance(
spec, state, source_index, address=source_address
)
consolidation = spec.ConsolidationRequest(
source_address=source_address,
source_pubkey=state.validators[source_index].pubkey,
target_pubkey=state.validators[target_index].pubkey,
)

# Set target to eth1 credentials
set_eth1_withdrawal_credential_with_balance(spec, state, target_index)

yield from run_consolidation_processing(
spec, state, consolidation, success=False
)


@with_electra_and_later
@with_presets([MINIMAL], "need sufficient consolidation churn limit")
@with_custom_state(
Expand Down Expand Up @@ -1228,7 +1209,7 @@ def run_consolidation_processing(spec, state, consolidation, success=True):
pre_exit_epoch_source = source_validator.exit_epoch
pre_exit_epoch_target = target_validator.exit_epoch
pre_pending_consolidations = state.pending_consolidations.copy()
pre_target_withdrawal_credentials = target_validator.withdrawal_credentials
pre_source_balance = state.balances[source_index]
pre_target_balance = state.balances[target_index]
else:
pre_state = state.copy()
Expand Down Expand Up @@ -1266,23 +1247,9 @@ def run_consolidation_processing(spec, state, consolidation, success=True):
target_index=target_index,
)
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:
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 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
# Check no balance move happened
assert state.balances[source_index] == pre_source_balance
assert state.balances[target_index] == pre_target_balance
else:
assert pre_state == state

Expand Down