Dev Update Week 13
This week I continued developing the light client APIs in teku.
I had some time to set up and play with a tool called helios.
- Release announcement
- Helios is an eth2 light client written in Rust. It gives the ability to take an untrusted execution RPC and turn it into a trustless, local RPC with light hardware requirements and fast sync time
- It can be used for example to take an execution node from a centralized provider (such as Alchemy) and verify that the outputs of its RPCs have not been tampered with. In this situation, the client only has to depend on Alchemy for data availability, and no longer for data integrity
- Helios works by engaging in the light client sync protocol from Altair. The details are left out of this update (see instead this description), but the important piece for this EPF project is that helios leverages the light client consensus APIs to efficiently create a view of the latest block header
- Thanks to its use of these APIs, we can use helios to test our light client API implementation in teku
From there I put some thought into a testing plan for the light client APIs.
- We want to demonstrate that a client can use the light client sync protocol backed by teku APIs to sync to the latest consensus block header
- The protocol calls each of four endpoints:
GetLightClientBootstrap
, GetLightClientUpdatesByRange
, GetLightClientFinalityUpdate
, GetLightClientOptimisticUpdate
over the beacon-node REST API. These are the endpoints that we're currently working on in teku
- After the endpoints are implemented, we can leverage helios to execute the protocol
- helios provides two relevant flags:
--execution-rpc
and --consensus-rpc
- We will provide an
--execution-rpc
of our choice. To demonstrate converting an untrusted RPC to a trustless one, we can use something like an Alchemy execution node
- In
--consensus-rpc
we will provide our teku node with light client APIs enabled
In order to do this, we have to set up a teku instance for testing.
- To set up teku for goerli or mainnet, we would ordinarily need to pair with an EL client
- Syncing an EL instance for goerli/mainnet would require a large amount of storage and sync time that would be prohibitive for everyday testing
- However, because the light client APIs are not (currently, pre-Capella) leveraging any EL data, we can get away with pairing teku to a stub execution endpoint, such as an Alchemy node
- We can set up teku in a few ways:
- Small custom testnets
- Full sync in archive mode (we require historical states to derive light client updates) on goerli/mainnet
- Checkpoint sync in archive mode
- Realistically, the best way to sync a teku node with the data we require (historical states in the block retention period, ~5 months) will be to run an archive node from a checkpoint sync
Outside of testing the APIs, I have been working on the implementation of GetLightClientUpdatesByRange
- The data required for this API includes historic beacon states for the block retention period (~5 months). Depending on the recency of the checkpoint a client syncs to via
LightClientBootstrap
, it may need historic LightClientUpdate
s derived from the BeaconState
- In order to support this data, we have to think about how we derive
LightClientUpdate
- The API passes in a sync committee period and a count, asking for the
LightClientUpdate
for that period and for count
periods afterward
- This implies teku will have to store or derive the best
LightClientUpdate
per sync committee period
- There are two ways we can do this:
- Compute the
LightClientUpdate
on the fly per request. This would require querying for the beacon states of a sync commitee period and determining the appropriate light client update. It may be possible in teku, but the only available interface is to query by slot or block root, state root
- Cache
LightClientUpdate
on disk as the chain is synced.
- In the beginning, we may derive
LightClientUpdate
on-the-fly, to verify the end-to-end functionality. Eventually, we certainly want to move to caching, as reading multiple historic beacon states would be an expensive operation.
Next week, I will continue putting work into setting up testing, such as syncing a teku archive node and potentially defining a small custom testnet. Mainly, I'll be working on the implementation of the internals in GetLightClientUpdatesByRange
.