-
Notifications
You must be signed in to change notification settings - Fork 0
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
In-protocol consolidation - target not liable #9
In-protocol consolidation - target not liable #9
Conversation
a9a4eea
to
036f5dc
Compare
036f5dc
to
ee0bda4
Compare
target_validator = state[consolidation.target_index] | ||
source_validator = state[consolidation.source_index] | ||
|
||
assert is_active_validator(target_validator) and not target_validator.slashed and not is_consolidated(target_validator) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All these conditions for the target validator may not be required but look sensible on a first approach
source_validator = state[consolidation.source_index] | ||
|
||
assert is_active_validator(target_validator) and not target_validator.slashed and not is_consolidated(target_validator) | ||
assert not source_validator.slashed and not is_consolidated(source_validator) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Must not be slashed otherwise the stake can escape latter correlated penalties.
- Cannot be consolidated twice
|
||
# verify source withdrawal credentials, which have authority over validating keys | ||
assert source_validator.withdrawal_credentials[:1] == ETH1_ADDRESS_WITHDRAWAL_PREFIX | ||
assert source_validator.withdrawal_credentials[12:] == consolidation.source_address |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A mechanism similar to EIP-7002 should add the consolidation message on-chain, setting msg.sender to source address. A consolidation operation is only available to validators with 0x01 credentials.
# Fork-agnostic domain since address changes are valid across forks | ||
domain = compute_domain(DOMAIN_CONSOLIDATION, genesis_validators_root=state.genesis_validators_root) | ||
signing_root = compute_signing_root(source_validator.pubkey, domain) | ||
assert bls.Verify(target_validator.pubkey, signing_root, consolidation.target_signature) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Target validator authorizes the consolidation. Since the target validator is not liable for source's actions this check may not be strictly necessary but sounds sensible of a first approach. Target validator signs over the public key of the source validator, not the index to prevent replay if source's validator index is ever re-used. There may be some other replay edge cases not covered by the current signed message
source_validator.consolidated_balance = consolidated_balance | ||
# Balance is not exiting the active set, do not apply churn | ||
source_validator.exit_epoch = get_current_epoch(state) | ||
source_validator.withdrawable_epoch = Epoch(source_validator.exit_epoch + config.MIN_VALIDATOR_WITHDRAWABILITY_DELAY) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Source validator record with 0 balance should exit the validator set immediately. Otherwise it will be ejected on the next epoch transition. Since its balance is not exiting the validator set it can bypass the churn. withdrawable_epoch must be set sufficiently into the future to allow time to submit slashable offenses.
Closing in favour of |
Extends MaxEB #3 to allow in-protocol consolidation.
A
Consolidation
operation moves all balance from validatorsource
to validatortarget
without leaving the active set. This operation is authorized by the source withdrawal credentials, and the target validating key.Slashing liability
In this implementation
Rationale
To get around the binary nature of slashed status, if the source validator is slashed, it is "un-consolidated" from the target validator. The un-consolidated validator transitions from exited to slashed and active. It will not participate in duties but it will re-use the existing validator record to track exit queue churn and correlated penalties