dragon

package module
v0.0.0-...-e2998bb Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 27, 2025 License: Apache-2.0 Imports: 22 Imported by: 0

README

DRAGON

DRAGON stands for Decentralized Routing Across Generic Overlay Network. It implements a peer-to-peer mesh network. Consumers have access to the connections between peers, receiving notifications as connections are established with new peers or as peers disconnect from our node. Consumers are currently expected to develop their own custom messaging primitives; DRAGON automatically handles peer membership and connectivity.

DRAGON was written for use in the Gordian consensus engine, but it should be usable in almost any project that needs a p2p mesh network.

Therefore, our initial goals are to implement specific messaging patterns directly in the Gordian project first. As we have success with applying those patterns, we will figure out how to expose new primitives in DRAGON to reduce the required boilerplate for other applications.

Implementation details

DRAGON is built on HyParView. It follows all the standard HyParView messages.

Modularity

DRAGON is modular and lets you provide custom implementations for some core parts of the HyParView stack.

For example, you can provide a dview.Manager to make application-specific decisions about managing your active and passive peers. (We provide dviewrand.Manager to make random decisions, closely following the behavior detailed in the whitepaper.)

We have plans to experiment with a view manager that uses geographic IP lookup to enforce geographic diversity of peers, while simultaneously applying some preference of geographically close peers.

You can control how often your node initiates shuffles through the dragon.NodeConfig.ShuffleSignal channel.

Divergence from the HyParView whitepaper

One distinction from plain HyParView is that nodes have an explicit whitelist of trusted certificate authorities. Any incoming connection must present a client certificate belonging to one of the trusted CAs; and by default, one node will not connect to more than one peer belonging to the same CA. This allows one operating entity to maintain multiple peers in the network but without risk of causing an overwhelming number of connections relative to the number of CAs represented within the network.

The list of trusted CAs is expected to be a one-to-one mapping with active validators on the blockchain that DRAGON is assisting. A validator leaving the active set should cause all its corresponding nodes to be disconnected. Furthermore, separating the p2p layer's encryption from validation signing reduces the attack surface for validators' private keys.

DRAGON uses QUIC for the transport layer (implemented with the quic-go project). The key features of QUIC that led to deciding its use as the transport layer are:

  • Built-in TLS support, so we can enforce authentication of every peer in the network
  • Native support for multiplexing many streams over a single connection, so that no single stream of data directly blocks sending or receiving another stream
  • The ability to send unreliable datagrams, which allows for some very specific cases of optimistic data transfers

In QUIC, clean disconnects are accompanied with a numeric exit code and a textual reason; therefore we use QUIC disconnects in place of a standalone "disconnect" message.

Protocols included
breathcast

See the breathcast package for a custom broadcast protocol.

One node on the network provides an arbitrary set of data and some details on how it is to be transfered, to create an "origination". The origination includes an erasure-coding of the input data The erasure-coded shards also include corresponding Merkle proofs; therefore, clients who have the Merkle root can verify that they have correctly received a shard of the original data.

The broadcast originator opens a QUIC stream to its peers. The originator sends a synchronous protocol and application header. The receiver parses those headers to determine details about the broadcast, such as the count of data and parity shards, the size of each shard, and the Merkle root for the shards. The headers also include application-specific data that must be parsed. In Gordian for instance, the application header would include the block height, the voting round, the block hash, and so on.

If the receiver chooses to accept the broadcast, the receiver sends a bitset indicating which shards it already has. Next, the originator sends unreliable datagrams for each missing shard. Ideally, enough of those shards reach the peer successfully such that the peer is able to fully reconstruct the data. If the receiver does reconstruct the data, it closes the broadcast stream. If not, the originator sends a message indicating that the unreliable transmission has completed; the receiver replies with an updated bitset, and the originator sends remaining shards over the reliable stream, allowing the receiver to reconstruct the original data.

While the originator is broadcasting the data to its immediate peers, those receivers open connections to their own peers in order to forward the headers and the data shards to their own immediate peers. As a relaying peer receives an individual data shard, it sends that shard as an unreliable datagram to a receiving peer. The receiving peer periodically sends bitsets to the relayer indicating what shards it already has. Following the unreliable transmission of a particular data shard, if the relayer does not see its acknowledgement within two bitset updates, the relayer falls back to sending the shard over the reliable stream.

Once a relaying peer receives enough shards to reconstruct the original data, it acts like an originating broadcaster, sending remaining shards over unreliable transport and then sending anything else missed over the reliable stream.

Documentation

Overview

Package dragon contains the core APIs for instantiating a DRAGON node.

DRAGON stands for Decentralized Routing Across Geographic Overlay Network. It is a peer-to-peer network built with the HyParView framework, with variations that encourage the network to naturally cluster where multiple nodes are present in nearby geography.

See the README for a more detailed specification.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func DefaultQUICConfig

func DefaultQUICConfig() *quic.Config

DefaultQUICConfig is the default QUIC configuration for a NodeConfig.

Types

type AlreadyConnectedToAddrError

type AlreadyConnectedToAddrError struct {
	Addr string
}

AlreadyConnectedToAddrError is returned from *Node.DialAndJoin if the given address is already connected to the current node.

func (AlreadyConnectedToAddrError) Error

type AlreadyConnectedToCertError

type AlreadyConnectedToCertError struct {
	Chain dcert.Chain
}

func (AlreadyConnectedToCertError) Error

type Node

type Node struct {
	// contains filtered or unexported fields
}

Node is a node in the p2p layer. It contains a QUIC listener, and a number of live connections to other nodes.

func NewNode

func NewNode(ctx context.Context, log *slog.Logger, cfg NodeConfig) (*Node, error)

NewNode returns a new Node with the given configuration. The ctx parameter controls the lifecycle of the Node; cancel the context to stop the node, and then use [(*Node).Wait] to block until all background work has completed.

NewNode returns runtime errors that happen during initialization. Configuration errors cause a panic.

func (*Node) ActiveViewSize

func (n *Node) ActiveViewSize() int

func (*Node) DialAndJoin

func (n *Node) DialAndJoin(ctx context.Context, addr net.Addr) error

DialAndJoin attempts to join the p2p network by sending a Join mesage to addr.

If the contact node makes a neighbor request back and we successfully peer, the returned error is nil.

If the node already has a connection to the given address, the method returns AlreadyConnectedToAddrError.

If the contact node disconnects, we have no indication of whether they chose to forward the join message to their peers. TODO: we should have DisconnectedError or something to specifically indicate that semi-expected disconnect.

func (*Node) UpdateCAs

func (n *Node) UpdateCAs(certs []*x509.Certificate)

UpdateCAs replaces the existing trusted CAs with the given list.

func (*Node) Wait

func (n *Node) Wait()

Wait blocks until the node has finished all background work.

type NodeConfig

type NodeConfig struct {
	UDPConn *net.UDPConn
	QUIC    *quic.Config

	// The base TLS configuration to use.
	// The Node will clone it and modify the clone.
	TLS *tls.Config

	InitialTrustedCAs []*x509.Certificate

	// The address to advertise for this Node
	// when sending out a Join message.
	AdvertiseAddr string

	// The maximum number of incoming connections that can be live
	// but which have not yet resolved into a peering or have been closed.
	// If zero, a reasonable default will be used.
	IncomingPendingConnectionLimit uint8

	// Manages the active and passive peers.
	ViewManager dview.Manager

	// Externally controlled channel to signal when
	// this node should initiate an outgoing shuffle.
	ShuffleSignal <-chan struct{}

	// Dragon internals write to this channel
	// to notify the application of connection changes in the active view.
	ConnectionChanges chan<- dconn.Change
}

NodeConfig is the configuration for a Node.

Directories

Path Synopsis
Package breathcast contains the "breathcast" protocol, providing a gossiping broadcast optimized for dragon.
Package breathcast contains the "breathcast" protocol, providing a gossiping broadcast optimized for dragon.
bcmerkle
Package bcmerkle contains types related to the Merkle trees required for the breathcast protocol.
Package bcmerkle contains types related to the Merkle trees required for the breathcast protocol.
bcmerkle/bcmerkletest
Package bcmerkletest contains compliance tests for types satisyfing interfaces in the bcmerkle package.
Package bcmerkletest contains compliance tests for types satisyfing interfaces in the bcmerkle package.
bcmerkle/bcsha256
Package bcsha256 contains a SHA256-backed implementation of bcmerkle.Hasher.
Package bcsha256 contains a SHA256-backed implementation of bcmerkle.Hasher.
breathcasttest
Package breathcasttest contains utilities for writing tests against the breathcast broadcast protocol.
Package breathcasttest contains utilities for writing tests against the breathcast broadcast protocol.
internal/bci
Package bci contains internal implementation details of the breathcast package.
Package bci contains internal implementation details of the breathcast package.
internal/merkle/cbmt
Package cbmt contains an internal implementation of a "compact binary Merkle tree".
Package cbmt contains an internal implementation of a "compact binary Merkle tree".
Package daddr contains types relevant to addresses for dragon.
Package daddr contains types relevant to addresses for dragon.
Package dcert contains types for dealing with x509 certificates in the context of dragon.
Package dcert contains types for dealing with x509 certificates in the context of dragon.
dcerttest
Package dcerttest contains test utilities for the dcert package.
Package dcerttest contains test utilities for the dcert package.
Package dconn contains types for exposing QUIC connections to the application running on top of dragon.
Package dconn contains types for exposing QUIC connections to the application running on top of dragon.
Package dpubsub contains types for in-application publish-subscribe patterns.
Package dpubsub contains types for in-application publish-subscribe patterns.
Package dragontest contains utilties for testing the dragon package.
Package dragontest contains utilties for testing the dragon package.
Package dview contains types for managing the active and passive views, i.e.
Package dview contains types for managing the active and passive views, i.e.
dviewrand
Package dviewrand contains a Manager satisfying dview.Manager that attempts to have no bias in the active and passive peer set, thereby closely following the protocol as designed in the HyParView whitepaper.
Package dviewrand contains a Manager satisfying dview.Manager that attempts to have no bias in the active and passive peer set, thereby closely following the protocol as designed in the HyParView whitepaper.
dviewtest
Package dviewtest contains test helpers for working with the dview package.
Package dviewtest contains test helpers for working with the dview package.
internal
dbitset
Package dbitset contains dragon-specific utilities around bitsets.
Package dbitset contains dragon-specific utilities around bitsets.
dcrypto
Package dcrypto contains cryptographic utilities for dragon.
Package dcrypto contains cryptographic utilities for dragon.
dk
Package dk contains the Kernel for the node management.
Package dk contains the Kernel for the node management.
dmsg
Package dmsg contains simple types relating to messages and the transport layer (such as dcert or QUIC connections and streams).
Package dmsg contains simple types relating to messages and the transport layer (such as dcert or QUIC connections and streams).
dpeerset
Package dpeerset contains types for interacting with peer sets.
Package dpeerset contains types for interacting with peer sets.
dpeerset/dfanout
Package dfanout contains types for managing fanout work from the peer sets.
Package dfanout contains types for managing fanout work from the peer sets.
dpeerset/dpeersettest
Package dpeersettest contains helpers for testing the dpeerset package.
Package dpeersettest contains helpers for testing the dpeerset package.
dprotoi
Package dprotoi contains internal protocol messages for dragon.
Package dprotoi contains internal protocol messages for dragon.
dprotoi/dbootstrap
Package dbootstrap contains functionality that is shared between multiple, otherwise independent, other bootstrap-related packages.
Package dbootstrap contains functionality that is shared between multiple, otherwise independent, other bootstrap-related packages.
dprotoi/dbootstrap/dbsacceptjoin
Package dbsacceptjoin contains the types for handling protocol bootstrap, specifically to accept a join message.
Package dbsacceptjoin contains the types for handling protocol bootstrap, specifically to accept a join message.
dprotoi/dbootstrap/dbsacceptneighbor
Package dbsacceptneighbor contains the types for handling protocol bootstrap, specifically to accept a neighbor message.
Package dbsacceptneighbor contains the types for handling protocol bootstrap, specifically to accept a neighbor message.
dprotoi/dbootstrap/dbsinbound
Package dbsinbound contains the types for handling protocol bootstrap, speifically accepting an inbound connection before we have received the first message on the bootstrap stream.
Package dbsinbound contains the types for handling protocol bootstrap, speifically accepting an inbound connection before we have received the first message on the bootstrap stream.
dprotoi/dbootstrap/dbssendjoin
Package dbssendjoin contains the types for handling protocol bootstrap, specifically to send a join message to a contact node.
Package dbssendjoin contains the types for handling protocol bootstrap, specifically to send a join message to a contact node.
dprotoi/dbootstrap/dbssendneighbor
Package dbssendneighbor contains the types for handling protocol bootstrap, specifically to send a neighbor message to a candidate node.
Package dbssendneighbor contains the types for handling protocol bootstrap, specifically to send a neighbor message to a candidate node.
dprotoi/dpadmission
Package dpadmission is the protocol for the admission stream.
Package dpadmission is the protocol for the admission stream.
dprotoi/dpdynamic
Package dpdynamic handles dynamic streams opened on-demand.
Package dpdynamic handles dynamic streams opened on-demand.
dprotoi/dpshuffle
Package dpshuffle contains the protocol to initiate an outbound shuffle on a specific QUIC connection, using a dynamically created stream.
Package dpshuffle contains the protocol to initiate an outbound shuffle on a specific QUIC connection, using a dynamically created stream.
dquic
Package dquic contains common functionality for QUIC types shared in both the root dragon package and some test packages around QUIC.
Package dquic contains common functionality for QUIC types shared in both the root dragon package and some test packages around QUIC.
dquic/dquictest
Package dquictest contains stub implementations of quic interfaces.
Package dquictest contains stub implementations of quic interfaces.
dquicwrap
Package dquicwrap declares QUIC wrapper types to ensure the quic.Connection values exposed to the application are able to interoperate with the low level streams managed internally by the dragon stack.
Package dquicwrap declares QUIC wrapper types to ensure the quic.Connection values exposed to the application are able to interoperate with the low level streams managed internally by the dragon stack.
dtest
Package dtest contains general test helpers.
Package dtest contains general test helpers.
Package wingspan contains the "wingspan" protocol, providing an epidemic-style gossip where the application controls "facts" that need to propagate through the network.
Package wingspan contains the "wingspan" protocol, providing an epidemic-style gossip where the application controls "facts" that need to propagate through the network.
wingspantest
Package wingspantest contains utilities for testing the wingspan package.
Package wingspantest contains utilities for testing the wingspan package.
wspacket
Package wspacket contains types related to managing packets for the [wingspan] package.
Package wspacket contains types related to managing packets for the [wingspan] package.
wspacket/wspackettest
Package wspackettest contains types useful for tests involving the wspacket package.
Package wspackettest contains types useful for tests involving the wspacket package.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL