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

Changes for devnet-8 #4518

Merged
merged 9 commits into from
Aug 9, 2023
Merged

Conversation

ethDreamer
Copy link
Member

@ethDreamer ethDreamer commented Jul 18, 2023

ExecutionPayload::Capella(payload) => Ok(Self::Capella(NewPayloadRequestCapella {
execution_payload: payload,
})),
ExecutionPayload::Deneb(_) => Err(Self::Error::IncorrectStateVariant),
Copy link
Member

Choose a reason for hiding this comment

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

Is there a reason why this returns an error?

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 deneb, you can't convert only an ExecutionPayload into a NewPayloadRequest, you also need the parent_beacon_block_root. This conversion is only used for tests thus far. Lighthouse is always using the code above to convert from a BeaconBlockRef to a NewPayloadRequest.

Copy link
Member

Choose a reason for hiding this comment

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

Related to this: ethereum/consensus-specs#3454
it's a pain point for lodestar I guess, has it impacted our tests?

Copy link
Member Author

Choose a reason for hiding this comment

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

This is just here to make some testing code (which currently doesn't bother to test post-merge forks) more concise. It only impacts some merge fork tests (thus the error condition isn't triggered). There's TODO's in the code to consider making those tests fork-aware / test multiple forks. I we decide to do that, this code will be revisited.

Copy link
Member

Choose a reason for hiding this comment

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

If it's only used in tests, I wonder if it's worth adding #[cfg(test)] to make it more explicit and ensure we don't later use this in production code?

Copy link
Member Author

Choose a reason for hiding this comment

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

Unfortunately we don't have our code structured that way. It's used in the mock_execution_engine as well as the execution engine integration tests. I believe the later isn't run with cfg(test) enabled. Fixing up these tests is beyond the scope of this PR. I'd be happy to look into doing this but I'm not sure it should be done before we get deneb-free-blobs merged into unstable as it would only make the review even worse.

Copy link
Member Author

Choose a reason for hiding this comment

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

As it stands it's not really the worst thing in the world. I would be worried if it were a panic but an error isn't bad.

Copy link
Member

Choose a reason for hiding this comment

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

ah yeah that wouldn't work for integration tests, got it thanks :)

@jimmygchen
Copy link
Member

jimmygchen commented Jul 19, 2023

I think we may also need to add the engine_forkchoiceUpdatedV3 method calls to support the new PayloadAttributes

pub async fn forkchoice_updated(
&self,
forkchoice_state: ForkchoiceState,
payload_attributes: Option<PayloadAttributes>,
) -> Result<ForkchoiceUpdatedResponse, Error> {
let engine_capabilities = self.get_engine_capabilities(None).await?;
if engine_capabilities.forkchoice_updated_v2 {
self.forkchoice_updated_v2(forkchoice_state, payload_attributes)
.await
} else if engine_capabilities.forkchoice_updated_v1 {
self.forkchoice_updated_v1(forkchoice_state, payload_attributes)
.await
} else {

Copy link
Member

@realbigsean realbigsean left a comment

Choose a reason for hiding this comment

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

Nice! A few things:

beacon_node/execution_layer/src/engine_api.rs Show resolved Hide resolved
} else {
// TODO: determine an actual heuristic for when we take the
Copy link
Member

Choose a reason for hiding this comment

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

If we just make this BUILDER_PROFIT_THRESHOLD configurable (we should rename it though because we already have a --builder-profit-threshold flag) and expose it with a flag, this seems like enough for now. We could also just make it a binary option to listen to the EL suggestion or not

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 not sure if this is something we necessarily want to treat in the same way as the --builder-profit-threshold setting. It's a difficult question of when do we listen to the execution layer for overriding the builder. I put this trivial mechanism in purely as a safety measure so users won't lose a super valuable block. I think there needs to be more discussion around this involving both EL & CL before we decide how to properly deal with this.

Copy link
Member

Choose a reason for hiding this comment

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

I think we should just ignore should_override_builder for now then, and maybe just log a warning until we have a better idea of how we should interpret 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.

okay I've updated this to have a new flag:

ignore-builder-override-suggestion-threshold which is a percentage difference to be exceeded by the builder payload in order to override this. I gave it a default value of 10%

@jimmygchen
Copy link
Member

Oh good point, we also need to update voluntary exit signing in the VC API:

pub async fn sign_voluntary_exit(
&self,
validator_pubkey: PublicKeyBytes,
voluntary_exit: VoluntaryExit,
) -> Result<SignedVoluntaryExit, Error> {
let signing_epoch = voluntary_exit.epoch;
let signing_context = self.signing_context(Domain::VoluntaryExit, signing_epoch);
let signing_method = self.doppelganger_bypassed_signing_method(validator_pubkey)?;

@jimmygchen jimmygchen added deneb deneb-devnet-8 consensus An issue/PR that touches consensus code, such as state_processing or block verification. labels Jul 20, 2023
@ethDreamer ethDreamer force-pushed the devnet-8 branch 8 times, most recently from 9fa5e27 to 4b47258 Compare July 30, 2023 21:26
@ethDreamer ethDreamer force-pushed the devnet-8 branch 2 times, most recently from 4ebd3db to 9585d41 Compare August 1, 2023 21:56
Copy link
Member

@realbigsean realbigsean left a comment

Choose a reason for hiding this comment

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

So the consensus changes for EIP-7045 are very minor but end up creating a decent amount of code duplication. I'm wondering if we think it's worth making an effort to try to reduce the duplication to make it easier to review on the deneb merge to unstable. If not I think we should probably make it a bit easier to understand what exactly about these methods should be different, maybe by pointing out specifics in method docs. What are your thoughts?

@@ -666,7 +666,19 @@ impl<T: SlotClock + 'static, E: EthSpec> ValidatorStore<T, E> {
voluntary_exit: VoluntaryExit,
) -> Result<SignedVoluntaryExit, Error> {
let signing_epoch = voluntary_exit.epoch;
let signing_context = self.signing_context(Domain::VoluntaryExit, signing_epoch);
let mut signing_context = self.signing_context(Domain::VoluntaryExit, signing_epoch);
match self.spec.fork_name_at_epoch(signing_epoch) {
Copy link
Member

Choose a reason for hiding this comment

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

do you think it's worth moving this logic to the self.signing_context() method? in case it's ever used elsewhere with Domain::VoluntaryExit

Copy link
Member Author

Choose a reason for hiding this comment

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

yes i can do that

Copy link
Member Author

Choose a reason for hiding this comment

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

BeaconState::Base(_)
| BeaconState::Altair(_)
| BeaconState::Merge(_)
| BeaconState::Capella(_) => spec.get_domain(
Copy link
Member

Choose a reason for hiding this comment

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

Similar to the other comment - should we move fork specific logic into spec.get_domain so that other potential usages with the voluntary exit domain don't break? Since we pass in fork I think we have enough info

Copy link
Member Author

@ethDreamer ethDreamer Aug 3, 2023

Choose a reason for hiding this comment

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

Not in this case because get_domain is a spec-defined function & changes of this type are done via bypassing this function to instead go straight to compute_domain. Compare process_voluntary_exit in:

this puts the change in the spec in approximately the same place as the change in our code and makes our code more spec-conformant overall

Copy link
Member

Choose a reason for hiding this comment

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

Right! Makes sense

beacon_node/execution_layer/src/engine_api/http.rs Outdated Show resolved Hide resolved
EE may make this suggestion depend on the EE's implementation, with the \
primary intent being to safeguard against potential censorship attacks \
from builders. Setting this flag to 0 will cause Lighthouse to always \
ignore the EE's suggestion. Default: 10 (equivalent to 10%).")
Copy link
Member

Choose a reason for hiding this comment

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

since this parses to an f32, this would also accept decimals right? might be worth making that explict

Copy link
Member Author

Choose a reason for hiding this comment

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

good idea :)

Copy link
Member Author

@ethDreamer ethDreamer Aug 4, 2023

Choose a reason for hiding this comment

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

@ethDreamer
Copy link
Member Author

ethDreamer commented Aug 3, 2023

So the consensus changes for EIP-7045 are very minor but end up creating a decent amount of code duplication. I'm wondering if we think it's worth making an effort to try to reduce the duplication to make it easier to review on the deneb merge to unstable.

I was also kind of annoyed by the code duplication, however I think the code is significantly more readable. If attestation processing has changed in deneb, I think it would be much more confusing to be calling methods like compute_beacon_block_attestation_reward_altair, new_for_altair, altair::process_attestations, within the deneb fork.

As far as removing some duplication, I suppose you could make the argument for making get_attestation_participation_flag_indices universal (fork-agnostic). But doing this would make the code for compute_beacon_block_attestation_reward_altair identical to compute_beacon_block_attestation_reward_deneb which is a problem because the fork subscript is required here to differentiate it from compute_beacon_block_attestation_reward_base. Thus we would be calling compute_beacon_block_attestation_reward_altair from within deneb and hiding that it actually behaves differently.

If not I think we should probably make it a bit easier to understand what exactly about these methods should be different, maybe by pointing out specifics in method docs. What are your thoughts?

I can add comments to the functions if that's what you mean

@ethDreamer ethDreamer force-pushed the devnet-8 branch 2 times, most recently from e0106ff to 82b3ed4 Compare August 4, 2023 15:29
Copy link
Member

@realbigsean realbigsean left a comment

Choose a reason for hiding this comment

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

LGTM

@realbigsean
Copy link
Member

realbigsean commented Aug 4, 2023

We're testing some testing networking stuff on devnet 7 still so I think we should wait to merge this for a bit

@realbigsean
Copy link
Member

There's a couple merge conflicts, but I can make a devnet-7 branch and we can merge this once that's resolved

Add override threshold flag
Added tests for Override Threshold Flag
Override default shown in decimal
Addressed Jimmy's Comments
No need for matches
Fix Mock Execution Engine Tests
Fix clippy
fix fcuv3 bug
Attestation Verification Post-Deneb
Fix Gossip Attestation Verification Test
Fix Exit Signing for EIP-7044
Fix cross exit test
Move 7044 Logic to signing_context()
@ethDreamer
Copy link
Member Author

alright I believe I've gotten rid of the duplicated code :)

Copy link
Member

@realbigsean realbigsean left a comment

Choose a reason for hiding this comment

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

LGTM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
consensus An issue/PR that touches consensus code, such as state_processing or block verification. deneb deneb-devnet-8
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants