Skip to content

Commit f081b1b

Browse files
authored
Merge pull request #3918 from mkalinin/consolidation-switch-to-comp
2 parents 1329410 + 66f5c37 commit f081b1b

File tree

3 files changed

+434
-88
lines changed

3 files changed

+434
-88
lines changed

specs/electra/beacon-chain.md

Lines changed: 56 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@
9999
- [Deposit requests](#deposit-requests)
100100
- [New `process_deposit_request`](#new-process_deposit_request)
101101
- [Execution layer consolidation requests](#execution-layer-consolidation-requests)
102+
- [New `is_valid_switch_to_compounding_request`](#new-is_valid_switch_to_compounding_request)
102103
- [New `process_consolidation_request`](#new-process_consolidation_request)
103104
- [Testing](#testing)
104105

@@ -627,9 +628,8 @@ def initiate_validator_exit(state: BeaconState, index: ValidatorIndex) -> None:
627628
```python
628629
def switch_to_compounding_validator(state: BeaconState, index: ValidatorIndex) -> None:
629630
validator = state.validators[index]
630-
if has_eth1_withdrawal_credential(validator):
631-
validator.withdrawal_credentials = COMPOUNDING_WITHDRAWAL_PREFIX + validator.withdrawal_credentials[1:]
632-
queue_excess_active_balance(state, index)
631+
validator.withdrawal_credentials = COMPOUNDING_WITHDRAWAL_PREFIX + validator.withdrawal_credentials[1:]
632+
queue_excess_active_balance(state, index)
633633
```
634634

635635
#### New `queue_excess_active_balance`
@@ -858,9 +858,6 @@ def process_pending_consolidations(state: BeaconState) -> None:
858858
if source_validator.withdrawable_epoch > next_epoch:
859859
break
860860

861-
# Churn any target excess active balance of target and raise its max
862-
switch_to_compounding_validator(state, pending_consolidation.target_index)
863-
864861
# Calculate the consolidated balance
865862
max_effective_balance = get_max_effective_balance(source_validator)
866863
source_effective_balance = min(state.balances[pending_consolidation.source_index], max_effective_balance)
@@ -1217,14 +1214,6 @@ def apply_deposit(state: BeaconState,
12171214
state.pending_balance_deposits.append(
12181215
PendingBalanceDeposit(index=index, amount=amount)
12191216
) # [Modified in Electra:EIP7251]
1220-
# Check if valid deposit switch to compounding credentials
1221-
if (
1222-
is_compounding_withdrawal_credential(withdrawal_credentials)
1223-
and has_eth1_withdrawal_credential(state.validators[index])
1224-
and is_valid_deposit_signature(pubkey, withdrawal_credentials, amount, signature)
1225-
):
1226-
switch_to_compounding_validator(state, index)
1227-
12281217
```
12291218

12301219
###### New `is_valid_deposit_signature`
@@ -1396,13 +1385,62 @@ def process_deposit_request(state: BeaconState, deposit_request: DepositRequest)
13961385

13971386
##### Execution layer consolidation requests
13981387

1388+
###### New `is_valid_switch_to_compounding_request`
1389+
1390+
```python
1391+
def is_valid_switch_to_compounding_request(
1392+
state: BeaconState,
1393+
consolidation_request: ConsolidationRequest
1394+
) -> bool:
1395+
# Switch to compounding requires source and target be equal
1396+
if consolidation_request.source_pubkey != consolidation_request.target_pubkey:
1397+
return False
1398+
1399+
# Verify pubkey exists
1400+
source_pubkey = consolidation_request.source_pubkey
1401+
validator_pubkeys = [v.pubkey for v in state.validators]
1402+
if source_pubkey not in validator_pubkeys:
1403+
return False
1404+
1405+
source_validator = state.validators[ValidatorIndex(validator_pubkeys.index(source_pubkey))]
1406+
1407+
# Verify request has been authorized
1408+
if source_validator.withdrawal_credentials[12:] != consolidation_request.source_address:
1409+
return False
1410+
1411+
# Verify source withdrawal credentials
1412+
if not has_eth1_withdrawal_credential(source_validator):
1413+
return False
1414+
1415+
# Verify the source is active
1416+
current_epoch = get_current_epoch(state)
1417+
if not is_active_validator(source_validator, current_epoch):
1418+
return False
1419+
1420+
# Verify exit for source has not been initiated
1421+
if source_validator.exit_epoch != FAR_FUTURE_EPOCH:
1422+
return False
1423+
1424+
return True
1425+
```
1426+
13991427
###### New `process_consolidation_request`
14001428

14011429
```python
14021430
def process_consolidation_request(
14031431
state: BeaconState,
14041432
consolidation_request: ConsolidationRequest
14051433
) -> None:
1434+
if is_valid_switch_to_compounding_request(state, consolidation_request):
1435+
validator_pubkeys = [v.pubkey for v in state.validators]
1436+
request_source_pubkey = consolidation_request.source_pubkey
1437+
source_index = ValidatorIndex(validator_pubkeys.index(request_source_pubkey))
1438+
switch_to_compounding_validator(state, source_index)
1439+
return
1440+
1441+
# Verify that source != target, so a consolidation cannot be used as an exit.
1442+
if consolidation_request.source_pubkey == consolidation_request.target_pubkey:
1443+
return
14061444
# If the pending consolidations queue is full, consolidation requests are ignored
14071445
if len(state.pending_consolidations) == PENDING_CONSOLIDATIONS_LIMIT:
14081446
return
@@ -1423,10 +1461,6 @@ def process_consolidation_request(
14231461
source_validator = state.validators[source_index]
14241462
target_validator = state.validators[target_index]
14251463

1426-
# Verify that source != target, so a consolidation cannot be used as an exit.
1427-
if source_index == target_index:
1428-
return
1429-
14301464
# Verify source withdrawal credentials
14311465
has_correct_credential = has_execution_withdrawal_credential(source_validator)
14321466
is_correct_source_address = (
@@ -1462,6 +1496,10 @@ def process_consolidation_request(
14621496
source_index=source_index,
14631497
target_index=target_index
14641498
))
1499+
1500+
# Churn any target excess active balance of target and raise its max
1501+
if has_eth1_withdrawal_credential(target_validator):
1502+
switch_to_compounding_validator(state, target_index)
14651503
```
14661504

14671505
## Testing

0 commit comments

Comments
 (0)