Our biweekly updates written by the entire Prysmatic Labs team on the Ethereum Serenity roadmap.

Interoperability Event Recap: Success

Interop was a success! Great job on everyone that participated in this retreat and special thanks to Consensys for taking care of the logistics. The teams were able to interop 7 different implementations together by communicating information over libp2p. That alone was a massive feat, not to mention the clients were syncing blocks, attestation and finalizing the chains together. We are super pumped on the out come and beyond excited on what’s more to come!

Preparing for Devcon V

Post interop, with more anticipated work, the team’s top priorities are focusing on sync resilience, meaning a node can disconnect for a few slots, come back online and catch up with its peers. Another priority is to enhance our sync strategy from requesting blocks from a single peer to requesting blocks from multiple peers in a round robin style. Second tier priorities are SSZ resilience, test coverage improvements and UX improvements.

Merged Code, Pull Requests, and Issues

Aligned With the Latest Networking Spec

We have completed alignment of the Prysm repo with the latest and greatest official networking specification for Ethereum Serenity. Having a standard, upgradeable networking spec is key for clients to communicate seamlessly and ensure we have a nice way to handle the important functionality of Eth2 at a p2p level. The latest networking spec gives us better handling of initial handshakes between nodes, as well as sending streams with chunks of data between nodes for faster communication. With block responses now being chunked instead of being sent as a whole response, this allows nodes to terminate streams from peers which are sending bad data early. You can see the full suite of changes in this tracking issue here.

Performance Improvements With Attestations

Attestations are the most frequently seen network object in ethereum 2.0. A node may be processing dozens of attestations per second so these code paths are a clear candidate for optimization. Since the interop event last week, we have been profiling and carefully reviewing code for any optimization opportunities such as parallel processing of distinct attestations whenever possible. As we bring the test network to full mainnet scale, these optimizations will be increasingly important.

Client Interoperability Utilities Built Into Prysm

In preparation for interop, we needed to be aligned with the standards for how to quickly spin up a Prysm client deterministically for others to use. One of the important features was to be able to launch the beacon node from a genesis state file, which could then be used across clients to test out various pieces of functionality.

Another important piece was being able to do a quick and easy “cold start”, which means you simply specify the number of validators and a genesis time, and the system spins up extremely fast with nothing else needed. We included the two features since the last update and they proved to be critical for easy prototyping in interop and even for us to do local development on a daily basis. If you want to read more about this functionality and how to setup Prysm this way, head on over to our interop documentation here.

Upcoming Work

BLS Cryptography Moving Forward

It’s a given that our BLS signature verification library, https://github.com/phoreproject/bls, is THE biggest bottleneck in Prysm and the really major thing preventing us from scaling to a massive number of validators. Just take a look at this flamegraph from our teammate Ivan showing how long BLS takes when we process a block and its underlying data.

Yes, BLS takes approximately 99.9% of our runtime…

We truly need an alternative as we move forward into production readiness, and we have kept an eye on https://github.com/herumi/bls as an alternative for a while, but it became unwieldy to integrate into Prysm due to the limitations of cgo and its transitive dependencies. BLS is quickly becoming a priority for us and we will keep exploring options these next few months.

Greater Test Coverage, Fuzzing, Load Testing

Part of getting ready for production means moving beyond just testing the “happy paths” of an Ethereum beacon chain runtime and also accounting for unexpected scenarios, bad data, spam data, and malicious activity. A lot of the official Ethereum Serenity specification tests ensure every client has the same behavior with respect to computing the state transition among other things, but the spec tests are definitely not fuzz tests, which are what we desperately need.

Fuzz Testing

In a few words, fuzz testing means feeding in random data into your system to make sure it doesn’t blow up. For example, a block with weirdly formatted information, RPC endpoints receiving randomly-formed requests, etc. Fuzz testing is used extensively for utilities such as serialization libraries or other general tools which are supposed to handle, well, “general” data in some shape or form. We are now exploring extensive fuzzing capabilities to test Prysm and determine its edge cases.

Another important aspect of being ready for production is load testing the beacon node. The key questions are, can a few people spamming your node’s open endpoints kill the node? Are there built in DoS protections? Can we identify subtle attack vectors this way? Typically, publicly accessible web servers are load tested before being put into production, and releasing Ethereum Serenity is no exception. Expect more work from us on this front alongside some interesting results.

Archival Beacon Node Functionality

Eth1 nodes have the option to run in an ` — archive` mode, which stores the entire state of the Ethereum blockchain, including all account and contract data beyond that which is needed for consensus. Typically, this functionality is desired by block explorers or other data intensive applications that are built to track historical information of the Ethereum network. We believe it is an important feature for Eth2 as well, which is why we have designed our beacon chain RPC endpoints to query old data if requested. For this, we put together a design for archival data storage here and began work by designing our DB API for this here.

Instead of storing every beacon state, most of the archival information needed amounts to validator set changes, such as validator activations, slashings, voluntary exits, and more. We decided to store the following data structure:

message ArchivedActiveSetChanges { repeated uint64 activated = 1; repeated uint64 exited = 2; repeated uint64 ejected = 3; repeated uint64 proposers_slashed = 4; repeated uint64 attesters_slashed = 5; repeated VoluntaryExit voluntary_exits = 6; repeated ProposerSlashing proposer_slashings = 7; repeated AttesterSlashing attester_slashings = 8; }

Each epoch along with the active validator indices and their balances. We are now working on ensuring our entire backend is archive-enabled, making our RPC API even more useful for third party use cases.

Round Robin Network Sync

Photo credit: preact.co.uk

In an effort to increase the effectiveness and decrease the individual burden on our fellow peers, Prysm is utilizing a round robin sync strategy for retrieving blocks. This mechanism will divide the batch block request amongst the peers evenly. Syncing with multiple peers reduces the attack opportunity of a single peer serving a forked chain or purposeful invalid blocks. Additionally, it decreases the load on a single peer as they would only serve a subset of the whole request. We expect this strategy to provide a faster and more secure initial block synchronization when joining the network.

Using Exponential Backoff for State Generation

One client functionality that is very important for a system built with weak subjectivity (like ETH2.0) is state generation. ETH2 clients have to be designed to regenerate past state until at least the most recent finalized state. This is needed in order to reorganize our chain to align with a fork. We can also regenerate a prior state for an RPC call or anything else that relies on us having a certain past state.

We’ll be using a strategy called exponential backoff to generate the state, meaning we only save states that are a power of 2 from current state, until the most recent finalized state. For example, if we have 2 full epochs (128 slots) since the last finalized state, we would save the states at 128, 64, 32, 16, 8, 4, and 2 slots back. Since we save all blocks from the finalized point, we can use those to regenerate the state from the saved point forward. This is much more lightweight than saving the state for every slot as reorgs most commonly happen within the recent state.

Interested in Contributing?

We are always looking for devs interested in helping us out. If you know Go or Solidity and want to contribute to the forefront of research on Ethereum, please drop us a line and we’d be more than happy to help onboard you :).

Check out our contributing guidelines and our open projects on Github. Each task and issue is grouped into the Phase 0 milestone along with a specific project it belongs to.

As always, follow us on Twitter or join our Discord server and let us know what you want to help with.

Official, Prysmatic Labs Ether Donation Address

0x9B984D5a03980D8dc0a24506c968465424c81DbE

Official, Prysmatic Labs ENS Name

prysmatic.eth