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

beacon rpc sometimes returns LightClientFinalityUpdate with sync_committee length < 2/3 #5491

Open
DragonDev1906 opened this issue Oct 10, 2023 · 5 comments · Fixed by #5602

Comments

@DragonDev1906
Copy link

DragonDev1906 commented Oct 10, 2023

Describe the bug
When requesting a LightClientFinalityUpdate via the beacon_chain RPC the endpoints sometimes returns an update with only a few entries in the sync committee (as shown in the screenshots). I'm not sure if this is a bug in Nimbus, but I can't think of anything where such a FinalityUpdate would be useful.

According to the consensus specs light clients should:

  • check the validity of such updates (see process_light_client_update),
  • update store.best_valid_update
  • update store.current_max_active_participants if the update has more participants set (which should never get this low),
  • update the optimistic header (if the light client wants this updated asap he'd use LightClientOptimisticUpdate and
  • apply the update (and thus the finalized header) if the sync committee is large enough (2/3).

Please correct me if I understood something wrong in the consensus specs or if there is another reason why LightClientFinalityUpdate with less than 2/3 of the sync committee would be useful. My current best guess is that it isn't useful at all and probably shouldn't be returned by the /eth/v1/beacon/light_client/finality_update rpc endpoint. I can easily check for the sync committee size to avoid this issue, instead of just checking the finalized blocknumber, which I mainly do to avoid unnecessary communication internally (I don't care about the optimistic updates/blocks/data).

I don't know if this also affects the subscription (I'll likely change it to use the subscription at some point, but for now I'm polling the rpc endpoint).

It could of course also be that my script is wrong and doesn't decode the sync committee correctly, hence the question of whether I understood something wrong when reading the consensus-specs.

To Reproduce
Steps to reproduce the behavior:

  1. Platform details (OS, architecture): Arch Linux, x86 (shouldn't be relevant since this is about the API and I'm using the http://unstable.prater.beacon-api.nimbus.team/ node.
  2. Branch/commit used: N/A (I don't know which version that node uses currently, I've tested it today).
  3. Commands being executed: Custom code that polls this RPC endpoint every 12 seconds, prints the sync committee size of the update

I additionally gives these updates to a light client if the finalized block number changed. Sometimes this then didn't apply the update, which is how I found this.

Screenshots (logs from my application)
Log output of an application polling the RPC endpoint every 12 seconds and outputting the sync committee size:
2023-10-10-192557_623x596_scrot

Log output showing the situation I've found: A finality update with <2/3 sync_committee (the first one I received with a new finalized_header..execution.block_number), together with debug logs of the light client showing that the sync committee was the reason that the update was not applied.
2023-10-10-195051_1619x304_scrot

Additional Info
This seems to happen quite regularly, most Epochs give me a FinalityUpdate with less than 2/3 sync committees.

@DragonDev1906
Copy link
Author

Here is some more information:
It looks like the FinalityUpdate changes whenever the attested header changes, even if the sync_committee_size is 1. Though I'm still not sure when this would be useful when requesting a LightClientFinalityUpdate.

2023-10-11-123605_921x383_scrot

etan-status added a commit to etan-status/consensus-specs that referenced this issue Nov 15, 2023
When new finality is reached without supermajority sync committee
support, trigger another event push on beacon-API and libp2p once
the new finality gains supermajority support.

Without this, if the first `LightClientFinalityUpdate` that advances
finality has low participation, light clients monitoring gossip would
likely get stuck until the next time when finality advances (1 epoch).

Thanks to @DragonDev1906 for reporting this issue to Nimbus:

- status-im/nimbus-eth2#5491
@etan-status
Copy link
Contributor

@etan-status etan-status linked a pull request Nov 15, 2023 that will close this issue
@etan-status
Copy link
Contributor

It could of course also be that my script is wrong and doesn't decode the sync committee correctly, hence the question of whether I understood something wrong when reading the consensus-specs.

You can check the next block (attested_header.beacon.slot + 1) on a block explorer.

For example, https://prater.beaconcha.in/slot/6709376 contains the sync_aggregate for attested_header.beacon.slot = 6709376, confirming that there was indeed only a single signature included in that block (out of 512).

Keep in mind that the Goerli network is soon deprecated, Sepolia / Holesky should have better performance in that regard.

@DragonDev1906
Copy link
Author

For the /eth/v1/beacon/light_client/finality_update endpoint, part of this is due to some blocks simply not including a good sync aggregate, in this case you have to wait for the next block to see whether it contains better data.

You're right. I wasn't expecting the specs to say that create_light_client_update should completely ignore the sync committee size when creating an update, but it does make sense if the light client is interested in the optimistic header, as the optimistic header is updated with sync_committee_size>=1. 1 Also makes sense since the same code is used for create_light_client_finality_update and create_light_client_optimistic_update.

For some reason I expected create_light_client_finality_update to not bother about updates that did not forward the finalized_header, but they can of course still be used to get optimistic header updates. Though unfortunately this means that it can sometimes be impossible to get a finalized_header through the beacon API until the next block is mined.

The spec even says this (apparently I can't read): Full nodes SHOULD provide the LightClientFinalityUpdate with the highest attested_header.beacon.slot

Keep in mind that the Goerli network is soon deprecated, Sepolia / Holesky should have better performance in that regard.

Yeah, that's why I'm currently testing on both Goerli and Sepolia. Higher chance to get unexpected or not quite normal situations that still can happen.

Footnotes

  1. https://ethereum.github.io/consensus-specs/specs/altair/light-client/sync-protocol/#process_light_client_update

@etan-status
Copy link
Contributor

With #5602 (unstable branch) it should now be possible for you to simply track the eventstream. When monitoring topics=light_client_finality_update, you will now get an update both when new finality is achieved, and additionally when supermajority is available (if the initial update did not have supermajority participation).

Can also try in browser / curl (but have to wait ~5-10 mins for finality to advance to see something)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants