preloader

Helping client diversity

BY Jim McDonald ON Feb 15, 2022

The Ethereum blockchain, like all blockchains, relies on a consensus mechanism to bring the members of the network to agreement on the state of the chain. Ethereum’s beacon chain uses a mechanism based on proof of stake, where validators stake Ether that is used as a weighting for their votes on the state of the chain. The validators’ view of the chain is informed by their beacon node, which contains a local copy of the state. For the chain to progress, a supermajority must agree on the current state of the chain so that the next block can be generated on that basis.

A supermajority is defined as \(\frac{2}{3}\) of the active validators, rounded up. For example, if there were 1,000 active validators the supermajority would be 667. If a supermajority agrees on the state of the chain then that becomes canonical, with no realistic way of reversing it1. If, however, a supermajority across the whole chain can be obtained from the validators using only single client, it can cause a critical failure in the chain.

Put simply, the problem with one client having a supermajority is that it alone can decide if a block is considered canonical. Although many validators across different locations are coming to consensus, their use of the same client means they do so based on the same assumptions. If the supermajority client has a bug that creates a block that is not valid according to the Ethereum consensus specifications there will not be enough validators using different clients without that bug to counter the super majority, and the chain will fork in to a continuing but invalid chain on the one hand, and a valid but halted chain on the other.

The commonly proposed solution to this problem is to switch away from a supermajority client, but that is proving difficult for many. Small operators such as solo stakers are justifiably wary of learning a new piece of software, and larger operators such as staking services have often put significant effort in to systems surrounding the client software for monitoring, reporting and similar. This also ignores the fact that many stakers will have chosen the supermajority client for their own good reasons, which remain valid. So when swapping is not the solution, what is?

How Vouch can help

Vouch is a multi-node validator built by Attestant. If you are unfamiliar with Vouch you may wish to read our introduction to Vouch to understand the product and its capabilities.

When it is time for Vouch to propose a block, it fetches proposals from all connected beacon nodes to select the best block to sign2. This process is shown below.

Vouch obtains block proposals from all beacon nodes

Figure 1: Vouch obtains block proposals from all beacon nodes

Vouch will carry out various levels of testing to ensure that the block is considered valid, for example confirming that the slot of the proposed block is as expected and ensuring that its head is a known block in the chain. However, it is limited in its ability to find all possible validity errors, and as such it is possible that it will accept an invalid block as the “best” option.

An option here is to not ask the beacon node with the supermajority client for a block proposal. However, although this means that Vouch would not propose a block by the majority client it does not stop it from attesting to a block proposed by another validator running the supermajority client and accepted by the local supermajority client.

The way to stop Vouch from attesting to an invalid block proposed by a supermajority client is to exclude that client from providing attestation data. Although only one validator proposes a block, \(\frac{1}{32}\) of the validators will attest to the state of the chain every 12 seconds, and it is this cumulative weight of votes that cements a block’s place in the chain.

The data in an attestation says “this is the current head of the chain3”. If node C proposed a block that it thought was valid, but the other nodes do not, then when asking for attestation data from node C we would obtain the information:

The view of beacon node C

Figure 2: The view of beacon node C

In the above case, beacon node C proposed block ‘1003’ and although invalid according to the beacon node specification the client considers it valid, so when asked for the head of the chain it will return ‘1003’.

However, node D has rejected the block as invalid so it will ignore that block and instead report on the latest head of the chain as it sees it:

The view of beacon node D

Figure 3: The view of beacon node D

In the above case, beacon node D will return ‘1002’ as the head of the chain, as block ‘1003’ has been rejected.

It can be seen from the above that the issue is not a supermajority client proposing a block, but all of the other supermajority clients attesting to it as the head of the chain. So a solution is to continue to allow the supermajority client to propose blocks, but not to provide data which clients use as the basis of attestations.

Vouch obtains attestation data from all beacon nodes except the supermajority client

Figure 4: Vouch obtains attestation data from all beacon nodes except the supermajority client

In the above example, beacon node C is an instance of the supermajority client so Vouch does not fetch data from it. This means that not only would node C create an invalid block, but at least one other beacon node would have to consider it valid for Vouch to attest to it being a valid head of the chain. This provides protection against a supermajority client providing bad data.

Configuring Vouch

Configuring Vouch to use all of the beacon nodes for proposals but not the supermajority client for attestations is a simple case of listing the nodes that can be used for each operation. Continuing the example above where beacon node C is the supermajority client, inside your .vouch.yml file you would configure the strategies as follows:

strategies:
  beaconblockproposal:
    style: best
    beacon-node-addresses:
      - nodeA_host:nodeA_port
      - nodeB_host:nodeB_port
      - nodeC_host:nodeC_port
      - nodeD_host:nodeD_port
  attestationdata:
    style: best
    beacon-node-addresses:
      - nodeA_host:nodeA_port
      - nodeB_host:nodeB_port
      - nodeD_host:nodeD_port

Other strategies (aggregateattestation, syncommitteecontribution) should follow the same strategy as beaconblockproposal. For more details about configuring Vouch, please see the configuration documentation.

This seems like a fair bit of work, so why not just drop the supermajority client entirely?

Limitations and considerations

The above configuration has a couple of limitations. Firstly, there is no on-chain information about which validators are run on which clients, which means that Vouch cannot detect if there is a supermajority client, and if so which one it may be. As such, Vouch must be configured manually to implement this strategy.

Secondly, this configuration does not pick up an issue that runs across multiple clients. For example, if beacon node A accepted the invalid block it would provide Vouch with attestation data that could result in the invalid block being incorporated in to the canonical chain. A possible solution here would be for Vouch to wait for multiple beacon nodes to come to agreement on the head of the chain before proceeding, however this would come with downsides during normal operation. Beacon nodes are part of a peer-to-peer network, with updates such as new blocks being passed from one node to another until they have reached all of the nodes. But each node takes time to read the block, verify it, filter it and pass it on to its connected nodes and this can result in there being a significant delay between a block arriving at one node and the next. Unfortunately the beacon chain is not forgiving of delays in proposals and attestations, which means that such a solution would be more likely to create orphan blocks4 and missed attestations. Ultimately, given the risk of multiple clients not only having a consensus-breaking bug, but the same consensus-breaking bug, this would likely have too high an impact on the normal operation of the chain to be considered a worthwhile strategy.

Dropping the supermajority client

Although the threat posed by a supermajority client is real, it remains theoretical in that to date there has been no sign of a bug, in either the supermajority client or any other, that allows invalid blocks to propagate across the network. This is not to dismiss the possibility, but it must be balanced against the benefits the client brings. Any reduction in the number of nodes on the network has its own impact on chain health, for example if the supermajority client sometimes proposes the best blocks via a highly efficient aggregate packing algorithm or faster processing of late attestations then the entire network suffers when it is not proposing blocks.

Removing any client also reduces the resilience and performance of Vouch’s work to secure the chain: apart from block proposals and attestations, clients carry out additional duties such as sync committee generation and attestation aggregation. Removing all of these features from the network when only one of them is potentially disruptive would be counter-productive.

Finally, although unlikely, it is possible that a significant reduction in the use of a single client could eventually result in that client being abandoned, leaving the entire ecosystem poorer (and weaker) for it, perhaps, giving rise to a new supermajority client that would be harder to dislodge as stakers would have fewer options to which to switch.

Retaining a maximally diversified environment brings benefits to all, and should not be discarded lightly.

Conclusion

It is possible to use a supermajority client safely in a multi-node Vouch environment with appropriate configuration, using its data for most operations but not allowing it to provide voting information for attestations. This ensures maximum diversity without risking a catastrophic failure of the chain itself.


  1. Outside of at least half of the supermajority providing a subsequent conflicting vote and losing their funds.↩︎

  2. Other strategies are available.↩︎

  3. Amongst other things.↩︎

  4. An orphan is a block which is proposed but not included on the chain.↩︎

Share: