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

[WIP] Light client protocol + Req/Resp interaction #2267

Closed
wants to merge 11 commits into from
Closed

Conversation

hwwhww
Copy link
Contributor

@hwwhww hwwhww commented Mar 23, 2021

WIP!!!

New and moved files

  • specs/altair/light-client/sync-protocol.md
  • specs/altair/light-client/p2p-interface.md

@hwwhww hwwhww force-pushed the light-client-docs branch from 185f20d to 729ccf2 Compare March 23, 2021 14:21
@hwwhww hwwhww changed the title [WIP] Light client protocol [WIP] Light client protocol + Req/Resp interaction Mar 23, 2021
@@ -23,3 +24,23 @@ def uint_to_bytes(n: uint) -> bytes:
# Helper method for typing copies, and avoiding a example_input.copy() method call, instead of copy(example_input)
def copy(obj: V) -> V:
return obj.copy()


def build_proof(anchor, leaf_index):
Copy link
Contributor Author

Choose a reason for hiding this comment

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

note: it's for the incoming get_light_client_update helper

@hwwhww hwwhww marked this pull request as ready for review April 5, 2021 16:15
)
```

No Response Content.
Copy link
Contributor

Choose a reason for hiding this comment

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

If this is a push-update, and there is no explicit subscription kind of approach for a light-client, then we should spec out when and how often the server pushes the update.

Copy link
Contributor

Choose a reason for hiding this comment

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

Which begs the question -- can we have this by default on gossip?

Even so, I would suspect we need req/resp as backup, but as for the req/resp backup, I would suspect this might need to be pull and have some sort of payload for the request. If my lightclient has been offline for a day, I need to be able to make specific requests to catchup to the head and can't rely entirely on head updates because I'm not yet there

Copy link
Member

@dapplion dapplion Dec 5, 2021

Choose a reason for hiding this comment

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

Relying on LightClientUpdate data structure to update a lightclient head is very wasteful since it only need to get the next_sync_committee pubkeys once every 256 epochs. To be honest the LightClientUpdate data structure works fine in a spec but it's not great in practice. The process of syncing can be split into two steps:

  • Get the pubkeys of the current sync committee. Use req/resp on demand to query LightClientUpdate(s)
  • Get latest SyncAggregate + header. More optimal to be gossiped once or more per slot.

However, gossiping SyncAggregate has an issue of how to decide which messages to accept and ignore. There are many combinations of the same signatures that results in different SyncAggregate objects (i.e. #2183).

Copy link
Contributor

@djrtwo djrtwo left a comment

Choose a reason for hiding this comment

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

A general comments and questions to start

specs/altair/light-client/README.md Outdated Show resolved Hide resolved
specs/altair/light-client/README.md Outdated Show resolved Hide resolved

#### GetLightClientSnapshot

**Protocol ID:** `/eth2/beacon_chain/req/get_light_client_snapshot/1/`
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not certain that this needs to be on the req/resp protocol. Essentially, LightClientSnapshot is something kept locally. A light client starts with some snapshot and then uses iterative LightClientUpdates to transition their local snapshot

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Right, Req/Resp was the simplest way to get a snapshot for MVP.

Alternatively, what do you think about saying that we expect 3rd party to provide LightClientSnapshot + Merkle proofs or multi-proof of each field, where the proof can be verified against WS source?

Copy link
Member

Choose a reason for hiding this comment

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

Alternatively, what do you think about saying that we expect 3rd party to provide LightClientSnapshot + Merkle proofs or multi-proof of each field, where the proof can be verified against WS source?

Agree 👍

)
```

No Response Content.
Copy link
Contributor

Choose a reason for hiding this comment

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

Which begs the question -- can we have this by default on gossip?

Even so, I would suspect we need req/resp as backup, but as for the req/resp backup, I would suspect this might need to be pull and have some sort of payload for the request. If my lightclient has been offline for a day, I need to be able to make specific requests to catchup to the head and can't rely entirely on head updates because I'm not yet there


## Sync protocol

Note that in this syncing mechanism, the server is trusted.
Copy link
Contributor

Choose a reason for hiding this comment

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

Why do you say the server is trusted?

The proofs make this trustless from a safety standpoint (assuming no sync committee corruption)

### Initialization

1. The client sends [`Status` message](./../../phase0/p2p-interface.md#status) to the server to exchange the status information.
2. Instead of sending [`BeaconBlocksByRange` request](./../../phase0/p2p-interface.md#beaconblocksbyrange) in the beacon chain syncing, the client sends [`GetLightClientSnapshot` request](./p2p-interface.md#getlightclientsnapshot) to the server.
Copy link
Contributor

Choose a reason for hiding this comment

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

So a light client must not just trust the server for a good snapshot. They must instead start from a known safe place and transition trustlessly from there

@@ -77,8 +113,7 @@ class LightClientUpdate(Container):
finality_header: BeaconBlockHeader
finality_branch: Vector[Bytes32, floorlog2(FINALIZED_ROOT_INDEX)]
# Sync committee aggregate signature
sync_committee_bits: Bitvector[SYNC_COMMITTEE_SIZE]
sync_committee_signature: BLSSignature
sync_aggregate: SyncAggregate
# Fork version for the aggregate signature
fork_version: Version
Copy link
Member

Choose a reason for hiding this comment

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

I believe almost all consumers of this data structure can compute the fork_version on their own. The only scenario where it could make sense is in LC embedded in blockchains, but even then you can input fork info in other ways.

)
```

The `LightClientSnapshot` SSZ container defined in [light client sync protocol](./sync-protocol.md#lightclientsnapshot).
Copy link
Member

Choose a reason for hiding this comment

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

To initialize a lightclient you don't need the next_sync_committee, but only the current_sync_committee. You can get the next via syncing.

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.

4 participants