-
Notifications
You must be signed in to change notification settings - Fork 87
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
Verification of beacon LightClientBootstrap objects #296
Comments
Based on my understanding, a client needs to bring their own
I also think that it is valid to have these objects available from the network, but a client should only grab one from the network after they have already synced/connected with their own object. This way a client that reconnects to the network at least once every |
How to bootstrap the beacon networkAccording to light client Altair specs, the light client starts syncing by fetching a
A safe weak subjectivity period is considered to be ~4 months. Some of the already mentioned options to configure the trusted block root are:
If we agree that when most of the nodes are in sync, all bootstraps pushed into the network will be validated, then I think that using option 1 and trusting only one single bootstrap to be valid for a set period of time (3-4 months) should be a good strategy to bootstrap the network. After this initial period, we can enable a feature flag that will start validating all bootstraps, bridges can start pushing those objects into the network and we will remove the embedded block root. Users can then configure their nodes' trusted block root via CLI. How to validate
|
I should have clarified better in the issue that the verification steps explained there are specifically required for the gossiping of bootstrap data (the offer/accept flow), and not for requesting of a specific bootstrap, e.g. when starting the LC sync. When starting a beacon LC client, typically a trusted block root needs to be provided, and the bootstrap for this gets requested on the network. This can be validated with that block root, see: https://github.com/ethereum/consensus-specs/blob/812ac2ce8fd436c757bb22d4aa5c90bf4923b664/specs/altair/light-client/sync-protocol.md?plain=1#L290C5-L290C34 This issue is rather about what a client can and cannot accept to store of bootstraps, and how it can decide on this. We've talked in the past about starting with some simple solutions such as only storing 1/few bootstraps (for example trusted-block-root that it provides at startup) or some centralized (continuously updated) list of some bootstraps or their block roots. But this is quite limited and the latter solution is not even that simple from deployment PoV. However, as described in the issue, I believe it is not really that complicated to add validation.
Possible solution for light client sync bootstrapping and clients are free to do this, but I don't like it that much (and probably won't put it in Fluffy as long as there are better options) as a) it requires clients to update these bootstraps in their releases and b) more importantly, it can cause users that did not update their software in a while to fail startup if a
That is a fair option to provide but from UX point of view the option of providing just the trusted block root and being able to retrieve the bootstrap from the network is a UX step up.
As I mention up, I believe the distributed option is of similar (or less) complexity to deploy at this point in time.
Same thoughts as I mention above regarding baked in bootstrap
Yes, that is the idea. Getting those bootstraps updated so that a user does not have to re-provide a trusted block root each time unless they went offline for a really long time (another UX step-up) |
Further thinking about this, as long as there is a |
Beacon LC bootstrap verification
Currently beacon
LightClientBootstrap
objects are not being verified.In order not to spam the network with these bootstraps, we should define and implement verification.
The
LightClientHeader
in the bootstrap object can be verified as is described by theis_valid_light_client_header
call, see consensus specs: https://github.com/ethereum/consensus-specs/blob/84c4aebfa8acbabcc23561b4d04910363795861d/specs/deneb/light-client/sync-protocol.md?plain=1#L66The
current_sync_committee
of the bootstrap object can be verified with ais_valid_merkle_branch
check with the providedcurrent_sync_committee_branch
against theheader.beacon.state_root
.That just leaves us with the requirement of verifying whether the
BeaconBlockHeader
in the bootstrap is canonical.I currently see two ways to verify this, and both ways require for the node to be at least beacon LC synced.
Step 1
From the consensus light client spec:
Bridge nodes SHOULD inject a
LightClientBootstrap
for each finalized epoch boundary block. Nodes that are beacon LC synced should have the latestLightClientFinalityUpdate
and thus be able to verify the header.If a node is not yet synced, it would not be able to verify and thus store content.
Which does leave us with a chicken and egg situation:
How can this network start if it requires nodes to LC sync to be able to accept data, but for LC sync it is required to retrieve that exact same data to be on the network?
Some possible solutions or a mix of solutions to this:
Step 2:
With just step 1, a node would not be able to backfill bootstrap data. If a bridge node injects older bootstraps, even an LC synced node would not be able verify it is canonical, unless it walks back all blocks.
Is backfill required in the first place?
The network might just work fine without it but perhaps not in all conditions.
When the network gets started with a set of nodes + bridge nodes and these nodes run long enough before other nodes try to join, there might not be immediate problems, depending on how long back of a bootstrap gets requested.
However, this is not ideal. And side issues might disrupt this, e.g. Bridge issues leaving gaps in the range, forks occurring, network issues/overload/DoS, or just the fact that a (sudden) larger set of nodes that don't have the history of bootstraps could make it more difficult to find them (This issue would be aggravated in case we want bootstraps to be stored by distance to node id, which is currently not the case however).
Solution:
Add a block_roots proof that can be verified by using the roots in historical_summaries.
This works the same way as for how headers in the history network are verified from Capella onwards. See PR #291
The proof is slightly simpler however and would look something like this:
Or just:
Important to mention that LC sync is still required as in order to get historical_summaries and verify those, we need to know the head of the chain.
Then it should also be decided if we want to store it with the proof or not (and thus provide it for retrieval also with proof or not).
The text was updated successfully, but these errors were encountered: