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

Fix sync protocol next_sync_committee_branch verification and remove active header #2829

Closed
wants to merge 2 commits into from

Conversation

hwwhww
Copy link
Contributor

@hwwhww hwwhww commented Feb 10, 2022

Discussed with @vbuterin today:

  1. Bugfixes
    1. In the update.next_sync_committee_branch Merkle branch verification, it should be on attested_header rather than using active_header that may be finalized_header.
    2. update_period should be from attested_header rather than using active_header.
  2. Largely simplified by removing "active header"
  3. Extract apply_light_client_update into update_sync_committees_from_update and update_new_finalized_header.
  4. For the LightClientUpdate builder, no need to fill empty next_sync_committee_branch.

From the perspective of a LightClientUpdate builder:

  • Always fill attested_header with the recent block header
    • Note: if it's a finality update, the attested_header state should point to the finalized_checkpoint
  • next_sync_committee and next_sync_committee_branch
    • Set the updated next_sync_committee and next_sync_committee_branch corresponding to attested_header
  • Finality update
    • If it's a finality update
      • Fill finalized_header != BeaconBlockHeader()
      • Fill finality_branch corresponding to the state of the attested_header
    • Else
      • Fill finalized_header with BeaconBlockHeader()
      • Fill finality_branch with [Bytes32() for _ in range(floorlog2(FINALIZED_ROOT_INDEX))]
  • sync_aggregate is always the SyncAggregate of attested_header
  • fork_version is for sync_aggregate

/cc @etan-status @jinfwhuang @dapplion if you have time to review :)

@hwwhww hwwhww marked this pull request as ready for review February 10, 2022 20:04
@hwwhww hwwhww changed the title Fix sync protocol next_sync_committee_branch verification and and remove active header Fix sync protocol next_sync_committee_branch verification and remove active header Feb 10, 2022
@etan-status
Copy link
Contributor

The changes seem a bit rushed to me.

  1. This could be an oversimplification. The previous approach ensured that new sync committees would only be accepted once they have finalized (or, after extended period of non-finality). The new approach optimistically locks in the next_sync_committee as soon as a majority among current_sync_committee signed anything with any finalized checkpoint later than the current one, even when the new sync committee assignments are not yet final (i.e., the new finalized checkpoint is still in the old sync committee period). This could be a problem if there is forking at the beginning of a sync committee period, and the sync committee produces multiple majority signatures for different next_sync_committee branches. The previous approach did not have this problem.

  2. While simplifications are nice, I think that it may lower the overall security properties. The previous sync protocol could also be reliably used to accelerate full node syncing by following a series of finalized_header from a weak-subjectivity checkpoint to the latest finalized block root, then start syncing from there. The new proposal depends on following the correct chain of signatures without any way to ensure that only finalized information is being followed. Overall, while having the two headers was initially a bit difficult to understand, the implementation of it is actually quite straightforward.

  3. I'm not sure if it is correct when there are multiple sync committee periods of non-finality. Like, applying a couple updates using the timeout mechanism follows along their attested_header, then applying a new majority update with a newer update.attested_header.slot but a super old finalized_checkpoint resets store.finalized_header to update.finalized_header which may be several sync committee periods in the past, which desyncs store.current/next_sync_committee from store.finalized_header, failing all future validation of updates.

  4. Yeah, that assert was quite annoying to work with, so it's good to see it gone. However, I think a new assert could be appropriate to ensure that the new update is following the same sync committee chain, if the store has already finalized on one.

Re perspective of builder:

  • Always fill attested_header with the recent block header: Same as in old approach?
  • next_sync_committee and next_sync_committee_branch: See (1) above.
  • Finality update: Same as in old approach?
  • sync_aggregate is always the SyncAggregate of attested_header: That data is unavailable on the blockchain. The sync committee signs the parent block of the previous slot. So, it could be that an attested_header is signed by next_sync_committee (instead of current_sync_committee), and also with a new fork_digest if there were any forks. If there were missed slots around a sync committee period change, it could also become difficult to determine the signing sync committee without trying to verify using both committee keys (sig verify potentially expensive on weak hardware).
  • fork_version is for sync_aggregate: Same as in old approach?

Other related PRs (building on top of the previous approach, but the edge cases are discussed there as well):

@dapplion
Copy link
Collaborator

Agree with @etan-status on most points. In regular mainnet conditions we can always wait for a finalized update which gives you the highest security guarantee at no extra cost

@etan-status
Copy link
Contributor

The work here is covered by #2932

@hwwhww
Copy link
Contributor Author

hwwhww commented Jul 12, 2022

closing in favor of #2932

@hwwhww hwwhww closed this Jul 12, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants