Lighthouse Update #01

We're excited to share progress on our Ethereum 2.0 implementation over the past two weeks. If you're after a TL;DR, go no further than this section!

Our progress:

  • Block pre-processing implemented.
  • BLS aggregate signatures implemented (but still unsafe).
  • SimpleSerialize (SSZ) implemented.
  • Draft SSZ specification produced by SigP and merged in to the ethereum/eth2.0-specs repo.

Works over the next couple of weeks:

  • Fuzzing framework initially targeting block pre-processing.
  • Connecting to a libp2p daemon.
  • Works on state transition logic.
  • Implementation of the FFG fork choice rule.

We're actively looking for community contributors! We've re-written our main readme to provide more information about the project and would love to have your support! We promise we won't bite and we'll help you develop your Rust skills and Ethereum 2.0 knowledge. Checkout the lighthouse repo and get in-touch on the sigp/lighthouse gitter!

Block Pre-Processing Implemented

One of our most significant achievements this fortnight has been implementing a block pre-processing function and benchmarking it.

Block pre-processing involves accepting a serialized block from some untrusted source (e.g., the network) and deeming it valid and worthy of full processing. Pre-processing aims to be as quick and as cheap as possible to reduce the impact that malicious blocks might have upon our system.

Pre-processing a block involves many things, the most expensive of which is validating the attestations inside of it. We process the attestations concurrently, de-serializing each record immediately before it is validated so we can fail-fast on a bad attestation. A single invalid attestation invalidates the entire block so we avoid de-serializing them all up-front.

Examples of pre-processing conditions:

  • Are the BLS aggregate signatures on all AttestationRecords valid?
  • Is the block slot valid?
  • Is the block's parent known?
  • Do we agree with the blocks that are being attested to?
  • Many more...

Examples of full processing procedures:

  • Applying the block to the current view of the chain.
  • Performing state transitions.
  • Running the FFG fork choice rule.
  • Many more...

Adrian Manning (Sigma Prime) is presently reviewing the pre-processing code alongside Danny Ryan and we will likely merge it into master in the next few days.

Pre-Processing Benchmarks Performed

We benchmarked block pre-processing on a consumer laptop (X1 Carbon, i5) and posted the results in the Block processing time estimates at scale issue. The results are also posted below:

attestations_per_block validators_per_attestation total_validators total_deposits_eth block_process_seconds
16 305 312500 10,000,000 0.066773104
16 3051 3125000 100,000,000 0.249065226

We test two scenarios here: 10M ETH staked and 100M ETH staked. The former is a reasonable scenario we'd hope to achieve and the latter is an extreme scenario where practically all present ETH is staked -- such a scenario is unlikely and undesired. As you can see, more ETH staked means more validators, which means more signatures which take more time to validate.

We're very happy with these results as they prove that the signature scheme in ETH is sensible and can scale. As Péter Szilágyi pointed out, this is much slower than the present 0.006s required by Ethash. However, this time discrepancy is not a roadblock - PoS has weak subjectivity which means verifying the entire chain is not the best way to sync from scratch (as mentioned by Danny Ryan in the same thread). Nevertheless, we'll work to shrink these block processing times even more.

In summary, present benchmarks are promising and confirm the expectations of the signature scheme. It's slower than PoW, but we expected that and it's manageable.

BLS Aggregate Signatures Implemented

We have implemented BLS aggregate signatures into the Lighthouse code-base! Because of this we were able to use real signature verification and provide the pre-processing benchmarks.

The Sigma Prime BLS aggregates implementation can be found at Our implementation was gratefully forked from a repository by @lovesh. Both of these libraries use the milagro-crypto/amcl library which provides all the underlying curve operations (e.g., add, multiply).

@lovesh did great work building a Rust "wrapper" around the Milagro code and implementing the higher-level aggregation schemes. Our fork takes their proof-of-concept code, adds further tests and makes it more convenient to use as a Rust crate.

Please note that we're still awaiting a review of our cryptography library - it should be considered unsafe until it is reviewed.

Which BLS Aggregate Scheme?

We've observed some confusion in the community about exactly which BLS aggregation scheme is used in Eth 2.0:

Ethereum 2.0 uses the "old" scheme described in BGLS03. The new scheme mitigates the "rouge-key attack" and allows signatures across distinct messages but is slower. Eth 2.0 protects against the rouge-key attack by requiring a bls_proof_of_possession on validator registration and naturally requires all signed messages to be identical (non-distinct). Put simply, the "old" scheme is faster and we don't need the features of the "new" scheme.

You can read Justin Drake's comments on these two schemes in this post.

SimpleSerialize (SSZ) Implemented

We've made progress with SSZ and implemented it Rust here. We also built some snazzy helpers to make block pre-processing quicker; they allow reading information directly from the serialized bytes. You can find the helpers here.

First Draft of SSZ Specification Published

Chris Natoli (Sigma Prime) drafted a specification for SSZ and it has been merged into the ethereum/eth2.0-specs repository! You can read it here.

We're excited to be helping the specification outside of simply building our own client.

Future Works

In the next fortnight we can expect to see the following progress:

  • Mehdi Zerouali (Sigma Prime) developing a fuzzing framework and initially targeting block pre-processing.
  • Chris Natoli working on connecting Lighthouse to a libp2p/gossipsub daemon. This is a stop-gap until libp2p-rust is ready-for-purpose.
  • Adrian Manning building out state and dynasty transition logic.
  • Paul Hauner (myself) working on implementing the FFG fork-choice rule.

We'd love to include some more contributors in the next post, so please feel free to jump on the repo and get involved!