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

Electra alpha8 spec updates #6496

Open
wants to merge 30 commits into
base: unstable
Choose a base branch
from

Conversation

pawanjay176
Copy link
Member

Issue Addressed

N/A

Proposed Changes

Implements changes for electra from https://github.com/ethereum/consensus-specs/releases/tag/v1.5.0-alpha.7 and https://github.com/ethereum/consensus-specs/releases/tag/v1.5.0-alpha.8

  1. Fixed partial withdrawals count eip7251: Fix partial withdrawals count ethereum/consensus-specs#3943
  2. Remove get_active_balance EIP-7251: Flatten get_active_balance ethereum/consensus-specs#3949
  3. Remove queue_entire_balance_and_reset_validator Remove queue_entire_balance_and_reset_validator ethereum/consensus-specs#3951
  4. Switch to compounding when consolidating with source==target eip7251: Switch to compounding when consolidating with source==target ethereum/consensus-specs#3918
  5. Queue deposit requests and apply them during epoch processing eip6110: Queue deposit requests and apply them during epoch processing ethereum/consensus-specs#3818

Other changes from the releases are mostly cosmetic/ do not require changes on our end.
Can be reviewed per commit for each change. However, b28d010 contains bug fixes from all the changes

@@ -36,7 +36,7 @@ impl DepositRequest {
pubkey: PublicKeyBytes::empty(),
withdrawal_credentials: Hash256::ZERO,
amount: 0,
signature: Signature::empty(),
signature: SignatureBytes::empty(),
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we change the type to SignatureBytes for the other request types as well for consistency?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

curious why we did this?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because we need to allow for invalid bls signature bytes to be sent over the engine api. Otherwise, it becomes a deserialization error when we get the payload from the EL instead of an invalid deposit during processing

@pawanjay176 pawanjay176 added the ready-for-review The code is ready for review label Oct 16, 2024
}
}
if conf.effective_balance_updates {
// Re-process effective balance updates for validators affected by top-up of new validators.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm very sus about this. Seems to have fixed the deposits processing bug though
cc @michaelsproul

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For some added context, we want deposit processing to work when process_pending_deposits processes 2 deposits where deposit 1 is a new validator and deposit 2 is a topup for the new validator.
Since process_effective_balance_updates happens after process_pending_deposits, we need the effective balance update happening after adding the new validator

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with this assessment of the situation. It's a bit gnarly that we need to do an effective balance update here outside the main single pass loop, but I think it's the best way.

I was thinking it might make sense to put this block of code after the logic for processing pending consolidations because that's the order used by the spec:

process_pending_deposits(state)  # [New in Electra:EIP7251]
process_pending_consolidations(state)  # [New in Electra:EIP7251]
process_effective_balance_updates(state)  # [Modified in Electra:EIP7251]

However, the spec also requires that consolidations are for known validators (both source and target), so that should not interact at all with our newly added validators.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only other thing I would consider doing would be getting rid of the added_validators vec and just running effective balance updates for all the validators from num_validators.. on wards.

Ideally we could even use something like iter_from that returns CoW pointers (iter_cow_from), however this doesn't exist in Milhouse yet.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Opened an issue on Milhouse:

@michaelsproul michaelsproul added the v6.1.0 New release c. Q1 2025 label Dec 2, 2024
Copy link
Member

@michaelsproul michaelsproul left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've reviewed all but 2 files, but one of those files is single_pass 😅 Will come back for that tomorrow

beacon_node/execution_layer/src/block_hash.rs Show resolved Hide resolved
Comment on lines 126 to 137
// iterate over an empty pending_deposits list here and increase balance
let pending_deposits = state.pending_deposits()?.clone();
for pending_deposit in pending_deposits.into_iter() {
if let Some(validator_index) = state.pubkey_cache().get(&pending_deposit.pubkey) {
state
.balances_mut()
.get_mut(validator_index)
.ok_or(Error::UnknownValidator(validator_index))?
.safe_add(pending_deposit.amount)?;
}
}
*state.pending_deposits_mut()? = List::empty();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this doing? How can we be iterating over an empty list -- doesn't this just not do anything?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My understanding was this applies pending_deposits to the state during initialization if the state contains pending_deposits. Here's the part of the spec

for deposit in state.pending_deposits:
        validator_index = ValidatorIndex(validator_pubkeys.index(deposit.pubkey))
        increase_balance(state, validator_index, deposit.amount)
    state.pending_deposits = []

Copy link
Member

@michaelsproul michaelsproul Dec 13, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ohh right, I was confused because we are calling upgrade_state_to_electra immediately prior to this, which sets the pending_deposits to the empty list:

let post = upgrade_state_to_electra(&mut state, Epoch::new(0), Epoch::new(0), spec)?;

pending_deposits: Default::default(),

I think we might need to move the apply_deposit logic after upgrading to Electra, so that the pending_deposits list gets populated. Currently it happens here:

for deposit in deposits.into_iter() {
deposit_tree
.push_leaf(deposit.data.tree_hash_root())
.map_err(BlockProcessingError::MerkleTreeError)?;
state.eth1_data_mut().deposit_root = deposit_tree.root();
let Deposit { proof, data } = deposit;
apply_deposit(&mut state, data, Some(proof), true, spec)?;
}

Or maybe we just delete the whole initialize_beacon_state_from_eth1 function and say we don't support starting from eth1 genesis any more 😅

It's interesting that the EF tests for initialize_beacon_state_from_eth1 already pass. Maybe processing the deposits with the pre-Electra logic is actually equivalent, and we could just delete the code here that loops over pending_deposits?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah i'm okay with that. It seemed redundant to me initially but i just implemented it for completeness.
I'm fine with removing it

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed in d5ec058

consensus/types/src/pending_deposit.rs Show resolved Hide resolved
@michaelsproul michaelsproul added the electra Required for the Electra/Prague fork label Dec 13, 2024
@michaelsproul
Copy link
Member

@pawanjay176 I've optimised and simplified part of the logic in PendingDepositsContext::new. We can avoid looking up the validator index twice, and we also don't need to handle the case for withdrawn validators that are also new, because that's impossible:

@michaelsproul
Copy link
Member

Pushed another commit which I think fixes a consensus bug 🌶️

Let me know if you agree with my reasoning @pawanjay176. The EF tests pass with both versions of the code, which implies test coverage could be improved here.

@michaelsproul michaelsproul added waiting-on-author The reviewer has suggested changes and awaits thier implementation. and removed ready-for-review The code is ready for review labels Dec 13, 2024
@pawanjay176
Copy link
Member Author

Great find 🙌 Turns out there was a spec test to catch this specific case, but it was written incorrectly. This has been fixed in the linked consensus specs PR above

@michaelsproul
Copy link
Member

Nice! Thanks for following that up!

@pawanjay176 pawanjay176 added ready-for-review The code is ready for review and removed waiting-on-author The reviewer has suggested changes and awaits thier implementation. labels Dec 14, 2024
@michaelsproul
Copy link
Member

Some of the tests seem to be failing due to builder stuff. Did you mean to include mock-builder changes in this PR?

@pawanjay176
Copy link
Member Author

Ahh I didn't realise I pushed the mock builder changes to this PR. I'll revert them and fix the tests.
Will make a separate PR for the mock builder changes

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
electra Required for the Electra/Prague fork ready-for-review The code is ready for review v6.1.0 New release c. Q1 2025
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants