|
==================================
|
|
RFC 010: Peer to Peer Light Client
|
|
==================================
|
|
|
|
Changelog
|
|
---------
|
|
|
|
- 2022-01-21: Initial draft (@tychoish)
|
|
|
|
Abstract
|
|
--------
|
|
|
|
The dependency on access to the RPC system makes running or using the light
|
|
client more complicated than it should be, because in practice node operators
|
|
choose to restrict access to these end points (often correctly.) There is no
|
|
deep dependency for the light client on the RPC system, and there is a
|
|
persistent notion that "make a p2p light client" is a solution to this
|
|
operational limitation. This document explores the implications and
|
|
requirements of implementing a p2p-based light client, as well as the
|
|
possibilities afforded by this implementation.
|
|
|
|
Background
|
|
----------
|
|
|
|
High Level Design
|
|
~~~~~~~~~~~~~~~~~
|
|
|
|
From a high level, the light client P2P implementation, is relatively straight
|
|
forward, but is orthogonal to the P2P-backed statesync implementation that
|
|
took place during the 0.35 cycle. The light client only really needs to be
|
|
able to request (and receive) a `LightBlock` at a given height. To support
|
|
this, a new Reactor would run on every full node and validator which would be
|
|
able to service these requests. The workload would be entirely
|
|
request-response, and the implementation of the reactor would likely be very
|
|
straight forward, and the implementation of the provider is similarly
|
|
relatively simple.
|
|
|
|
The complexity of the project focuses around peer discovery, handling when
|
|
peers disconnect from the light clients, and how to change the current P2P
|
|
code to appropriately handle specialized nodes.
|
|
|
|
I believe it's safe to assume that much of the current functionality of the
|
|
current ``light`` mode would *not* need to be maintained: there is no need to
|
|
proxy the RPC endpoints over the P2P layer and there may be no need to run a
|
|
node/process for the p2p light client (e.g. all use of this will be as a
|
|
client.)
|
|
|
|
The ability to run light clients using the RPC system will continue to be
|
|
maintained.
|
|
|
|
LibP2P
|
|
~~~~~~
|
|
|
|
While some aspects of the P2P light client implementation are orthogonal to
|
|
LibP2P project, it's useful to think about the ways that these efforts may
|
|
combine or interact.
|
|
|
|
We expect to be able to leverage libp2p tools to provide some kind of service
|
|
discovery for tendermint-based networks. This means that it will be possible
|
|
for the p2p stack to easily identify specialized nodes, (e.g. light clients)
|
|
thus obviating many of the design challenges with providing this feature in
|
|
the context of the current stack.
|
|
|
|
Similarly, libp2p makes it possible for a project to be able back their non-Go
|
|
light clients, without the major task of first implementing Tendermint's p2p
|
|
connection handling. We should identify if there exist users (e.g. the go IBC
|
|
relayer, it's maintainers, and operators) who would be able to take advantage
|
|
of p2p light client, before switching to libp2p. To our knowledge there are
|
|
limited implementations of this p2p protocol (a simple implementation without
|
|
secret connection support exists in rust but it has not been used in
|
|
production), and it seems unlikely that a team would implement this directly
|
|
ahead of its impending removal.
|
|
|
|
User Cases
|
|
~~~~~~~~~~
|
|
|
|
This RFC makes a few assumptions about the use cases and users of light
|
|
clients in tendermint.
|
|
|
|
The most active and delicate use cases for light clients is in the
|
|
implementation of the IBC relayer. Thus, we expect that providing P2P light
|
|
clients might increase the reliability of relayers and reduce the cost of
|
|
running a relayer, because relayer operators won't have to decide between rely
|
|
on public RPC endpoints (unreliable) or running their own full nodes
|
|
(expensive.) This also assumes that there are *no* other uses of the RPC in
|
|
the relayer, and unless the relayers have the option of dropping all RPC use,
|
|
it's unclear if a P2P light client will actually be able to successfully
|
|
remove the dependency on the RPC system.
|
|
|
|
Given that the primary relayer implementation is Hermes (rust,) it might be
|
|
safe to deliver a version of Tendermint that adds a light client rector in
|
|
the full nodes, but that does not provide an implementation of a Go light
|
|
client. This either means that the rust implementation would need support for
|
|
the legacy P2P connection protocol or wait for the libp2p implementation.
|
|
|
|
Client side light client (e.g. wallets, etc.) users may always want to use (a
|
|
subset) of the RPC rather than connect to the P2P network for an ephemeral
|
|
use.
|
|
|
|
Discussion
|
|
----------
|
|
|
|
Implementation Questions
|
|
~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
Most of the complication in the is how to have a long lived light client node
|
|
that *only* runs the light client reactor, as this raises a few questions:
|
|
|
|
- would users specify a single P2P node to connect to when creating a light
|
|
client or would they also need/want to discover peers?
|
|
|
|
- **answer**: most light client use cases won't care much about selecting
|
|
peers (and those that do can either disable PEX and specify persistent
|
|
peers, *or* use the RPC light client.)
|
|
|
|
- how do we prevent full nodes and validators from allowing their peer slots,
|
|
which are typically limited, from filling with light clients? If
|
|
light-clients aren't limited, how do we prevent light clients from consuming
|
|
resources on consensus nodes?
|
|
|
|
- **answer**: I think we can institute an internal cap on number of light
|
|
client connections to accept and also elide light client nodes from PEX
|
|
(pre-libp2p, if we implement this.) I believe that libp2p should provide
|
|
us with the kind of service discovery semantics for network connectivity
|
|
that would obviate this issue.
|
|
|
|
- when a light client disconnects from its peers will it need to reset its
|
|
internal state (cache)? does this change if it connects to the same peers?
|
|
|
|
- **answer**: no, the internal state only needs to be reset if the light
|
|
client detects an invalid block or other divergence, and changing
|
|
witnesses--which will be more common with a p2p light client--need not
|
|
invalidate the cache.
|
|
|
|
These issues are primarily present given that the current peer management later
|
|
does not have a particularly good service discovery mechanism nor does it have
|
|
a very sophisticated way of identifying nodes of different types or modes.
|
|
|
|
Report Evidence
|
|
~~~~~~~~~~~~~~~
|
|
|
|
The current light client implementation currently has the ability to report
|
|
observed evidence. Either the notional light client reactor needs to be able
|
|
to handle these kinds of requests *or* all light client nodes need to also run
|
|
the evidence reactor. This could be configured at runtime.
|