- 2020-03-15: Initial draft.
The light client protocol provides a method for verifying application state without the execution of all preceding transactions. The protocol for the light client is described in English while the rust implementation is described in ADR-002. This ADR outlines the next iteration of the light client implementation in rust in which multiple modules (Peer Exchange, Requester, Verifier, etc) operate concurrently.
The basis for this work comes from the learnings of the Reactor Experiments as well as the Blockchain Reactor Refactor. The key take aways from that work are:
- Communicate with events and not state
- Separate concerns into independently verifiable (by humans as well as computers) components.
- Push IO to the edge of the system to allow simulation of components as well as integration between components.
Model the Peer Exchange, Requester, Detector and Verifier as separate independently verifiable components. Each component is a finite state machine with internal state. Communication between components is done by event dispatching to a routing layer. The routing layer handles input and output by routing to/from peers to components and between components. The routing layer will provide the necessary abstraction to allow simulation of individual components as well as integration between components and peers.
This architecture outlines components that have been described in previous ADRs and will only be expanded upon here.
The light clients requires an expanding set of peers to get headers from. The larger and more diverse the set of peers; the better the chances that the light client will detect a fork. The peer list can be seeded with peers from configuration and will can crawl the network.
The light client requests validator sets and signed headers from peers. The order of data requested from peers is determined by the specific verification algorithm being followed. Specifically either sequential or bisection. Additionally the Requester is expected to request signed header for a specific height from different peers in order to detect forks. The current documentation refers to a primary and set of backup node but it will be beneficial to fetch the requisite data from multiple peers concurrently. In this way the Requester acts as a request scheduling finite state machine informed by feedback from peers as well as other components.
The detector component will accumulate headers received from peers and be responsible for detecting forks according to the (under active development) Fork Detection Specification.
The verifier will perform the core verificaiton
protocol
without performing IO. Essentially will use VerifySingle
function in
the spec and communicate failure via events to the Requester to decide
which header to process next.
The routing layer will route events based on type between components similar to previous experiments. Messages to and from peers will be handled via a minimal peer layer wrapping the RPC client.
Proposed
- Better isolation of concerns
- Parallelism can be handled by dispatching to a thread pool without changing the interface between components.
- Non shared state means some state will be replicated. ie. the peer exchange component will have a list of peers. That list of peers also be represented in the peer to peer layer.
- Inconsistencies between state representations must be handled explicitly instead of implicitly. In the case above, we must consider that we have the address of peer which is off-line.
- {reference link}