Skip to content

Instantly share code, notes, and snippets.

@tyler-smith
Last active December 19, 2019 19:34
Show Gist options
  • Save tyler-smith/dfae488b9850ebd8da22dabea80c59ce to your computer and use it in GitHub Desktop.
Save tyler-smith/dfae488b9850ebd8da22dabea80c59ce to your computer and use it in GitHub Desktop.
A draft spec for the Snowglobe pre/post concensus protocol.

NOTE: This document is an unfinished work in progress, working toward v0.1.0!

  Title: Active local state reconcilation using Avalanche
  Author: Tyler Smith (tcrypt) 
  Status: Draft
  Created: 2019-10-01
  License: MIT

Abstract

This document specifies a protocol for nodes of a Nakamoto Consensus network to actively work to reconcile their local states with those of their peers. It enables nodes to sample each others' state in order to determine which item of a conflict set is currently chosen by the most nodes, and to work toward a super majority of nodes chosing the same item. An Avalanche-based consensus algorithm is used for this processing affording the protocol asyncrony, metastability, and quiescent finality.

This document will not go into the details of the Avalanche algorithms and knowledge of them is assumed of the reader.

Motivation

Nakamoto Concensus has the proptery of objectivity which is required for nodes wishing to join the consensus trustlessly. This is acheived using proof of work to give every state a real-world weight. Unfortunately this imposes some non-ideal requirements on the system such syncrony, artificial latency, and indefinite continued maintance of the consensus, i.e. a state change is never 100% finalized.

By recognizing that the vast majority of nodes making up the mining and large payment infrastructures are always online and very rarely need to join consensus more than once, we can design a protocol that allows them to very quickly come to aggrement on the state of the network from their viewpoints. The miners of the network continue their task of solidifying their local states into the canonical global state which enables new aganets to join the consensus trustlessly.

Goals

We want our protocol to be:

fast robust byzantine fault tolerant permissionless

Protocol Overview

We consider every block and transaction to be a member of conflict set of 1 or more items and use the Avalanche algorithm to resolve each set into exactly 1 item. The set of all items chosen for their respective conflict sets is used by participants as their local states which greatly minimizes the information entropy across these nodes.

Each peer keeps a list as many other participants as it can and for as long as there are unresolved conflict sets a peer will pick a random other peer and send them a query for all unresolved conflict sets. Responses are fed into a vote accumulator based on the Snowball algorithm and once the confidence reaches a threshold that conflict set is resolved. This process continues any time there are unresolved conflicts sets and works constantly until there are no more sets to resolve.

Sybil resistances is added by requiring peers to commit to a set of UTXOs that contain a sufficient coins age, and by weighting the random selection of peers by the committed coin ages.

Specification

Security Parameters

Sybil resistance via coin age

Sybil resistance is provided by requiring peers offering the Query service to commit to a set of UTXOs that have a sufficient coin amount times block age, which we denote with the unit "Coin Blocks", or CB. If a Join message received by a Query peer does not meet the sufficient Coin Blocks threshold that peer must not be added to the Snowglobe Pool and should be banned.

The initial temporary amount required is 1440 Coin Blocks.

DAG and conflict-set Formation

The heart of Avalanche's efficiency is in the DAG that allows us to accept or reject entire chains of states with a single Snowball instance. The more connected the graph is the fewer Snowball instances need to be performed to finalize all states, however if forming the graph is too complex much or all of these gains will be used up constructing graph edges.

The solution is to use all naturally forming, objective edges already present in the chain already and no more. We define the edges of the graph recursively by defining the incoming edges for a given vertex. The edges for a vertex depends on its type and are as follows:

  • Transactions: A transaction has incoming edges from each parent transaction.

These are:

  1. The flow of UTXOS, i.e. When transaction B spends a UTXO created by transaction A then there is a single edge going from A to B.
  2. The chain of blocks, i.e. There is edge going from a blocks' parent to the block.

Support signaling

The follow serivce bit should be used by clients to signal to that they understand the protocol:

NODE_SNOWGLOBE = (1 << 26)

New p2p messages

Join

When a node wants to advertise to a protocol-aware client that it is offering its local state for sampling, it should send them a Join message built as follows:

Size Name Type Description
1 version uint8 The version of the protocol supported by this peer.
8 sequence uint16 The sequence of this Join message. Used to invalidate pervious Join messages.
33 identityPubkey [33]uint8 The identity key of this peer.
[]36 outpoints [][36]uint8 A list of outpoints for sybil resistance.
32 identitySignature uint8 A signature for this message, without signatures, signed by identityPubkey.
[]32 outpoints [][32]uint8 A list of signatures for this message, without signatures, signed by the pubkey with control over the outpoint at the same index of outpoints.

Query

When a client wants to sample a node for a set of vertices it should send them a Query message build as follows:

Size Name Type Description
8 queryID uint64 An identifier for the sender to use to relate answers to queries.
[]36 invs [][36]uint8 A list of inventory vectors for the vertices being queried about.

QueryResponse

When a client wants to sample a node for a set of vertices it should send them a Query message build as follows:

Size Name Type Description
8 queryID uint64 An identifier for the sender to use to relate answers to queries.
[]36 invs [][36]uint8 A list of inventory vectors for the vertices being queried about.

Joining Full Consensus

When a client first starts up it should refresh its pool of nodes available for sampling. It can do this with a combination of checking nodes they know with the appropriate service bit set, a domain-specific DNS seed, and other standard techniques for finding peers on a p2p network.

Next a client must sync to the tip block; the one with the most proof of work visible to the client. From here the client should begin iteratively checking blocks backwards, from tip to Genesis, until it finds a block that has been accepted by the client's queriable peers. They now know that block, all of its ancestors, and every transaction contained within those blocks, have been finalized by the network.

Maintaining Consensus

Future Improvements

The following items are things that would improve the protocol but have been omitted for now to keep the protocol simple.

Deduplicated UTXO signatures

Currently ever UTXO in a Join message must have a matching signature, however each signature covers the same data and many UTXOs may be controlled by a single pubkey. In this case it would be acceptable to have only one signature for all of these UTXOs.

Short IDs

Query requests currently use full 32 byte transaction and block identifiers but this can be reduced significantly using various "short ID" mechanisms. This is a clear improvement to be made on memory and bandwidth consumption.

Noise authenticated tunnel

The current protocol requires signing every query response to validate its authenticity which is likely to become a bottleneck at scale. We can improve this situation by having peers connect using an authenticated communication tunnel.

Using a protocol conforming to the Noise[?] framework using QUIC for transport is under development by Bitcoin ABC.

Implementations

There is a WIP implementation in Go based on the bchd full node: https://github.com/gcash/bchd/tree/snowglobe/

Bitcoin ABC's WIP implementation that this protocol was largely developed around is available here:

Acknowledgments

Team Rocket, deadalnix, Chris, Emin, Colin

References

TODO: Links and reference markers in text

  • Snowflake to Avalanche
  • Preconensus and Markets
  • Chris' Avalanche article
  • Noise Protocol

Copyright

This document is placed in the public domain.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment