Skip to Content

Network topology and information flow

Requirements and design rationale

Actors and requirements

Actors

Gummiworm involves three types of actors:

Head peers: Core participants who are in charge of the head’s operations, own the head equity, and, in some use cases, deposit their own funds into the head. Head peers are the only entry points for the head: all head-related operations are performed by interacting with them.

Coil peers: Nodes that together act as custodians of the head’s funds by verifying and collectively approving the head’s operations. They form a much wider safety net whose role is to ensure that no malicious actions get executed in the head, even if all head peers colluded.

Note

In the single-head deployment described in this whitepaper, the head operator selects their own coil peers, so incentive alignment is negotiated directly between the parties. A formalized incentive model becomes necessary when coil peers are drawn from a shared, permissionless network. See Coil incentives for the planned design.

Users: External parties who interact with Gummiworm-based applications by depositing their funds, transacting and withdrawing funds. Users are the most vulnerable participants, who are particularly interested in censorship resistance. Once they deposit their funds into the head’s custody, they want to be sure they can control their funds in the head and be able to withdraw or evacuate them.

Requirements

R1. Veto power for head peers: Because head peers have financial stake in the system (owning head equity and potentially depositing funds), it is important that each head peer has veto power over all decisions that the head takes (though in some cases this requirement can be relaxed; this is currently out of scope).

R2. Censorship resistance:

  • For head peers: Each head peer can submit their requests directly through their own node
  • For users: Censoring a user’s request requires all head peers to collude, which is significantly more difficult than censoring with a single head peer

R3. Fast head advancement: The head should be able to advance fast, without waiting for coil peers to finish their work on verifying head decisions. Head peers must be able to progress through fast consensus independently of coil peer availability or responsiveness.

R4. Low latency for head operations: Head peers should minimize communication latency for fast consensus operations to ensure quick user request processing and block production.

R5. Scalable verification layer: The system should support a large number of coil peers (M-of-N quorum) to provide a wide safety net, without impacting head peer performance.

R6. Coil peer flexibility: Coil peers should not be required to be available at all times. Only a threshold number of coil peers need to be available to confirm effects.

R7. Head peer high availability: All head peers are expected to be continuously available. If any head peer becomes unresponsive for long enough, the head must switch into rules-based regime to evacuate the funds.

R8. Independent verification: Both head peers and coil peers should be able to independently verify effects and submit them to the L1 network once they have the necessary messages.

R9. Resilient effect submission: Any peer (head or coil) should be able to independently submit verified effects to the L1 network. Having multiple peers capable of submission increases the likelihood that effects are submitted successfully even if some peers fail, are censored, or act maliciously.

R10. Resilient evacuation capability: Every peer (head or coil) should be able to independently evacuate funds from an aborted head after a dispute is resolved on L1. To enable this, all peers must receive all messages so that any peer can calculate the proper evacuation map and execute the evacuation process. Having multiple peers capable of evacuation increases the likelihood of successful fund recovery even if some peers fail or act maliciously.

Since Gummiworm’s distributed system consists of two distinct types of peers with different roles in the consensus protocol, which impose different requirements on their operation and availability, we split up the whole network into two parts - the head network and the coil network. This addresses R3, R4, R5, and R6.

The head network uses a fully-connected mesh topology, while the coil network uses a star topology with head peers as hubs. Both networks are static—all peers and their addresses are listed explicitly in the configuration with which the head is initialized.

The diagram below shows three head peers in a mesh, each a hub for four coil peers. Four coil peers are down (red), but the remaining eight meet the assumed 8/12 quorum, so slow consensus can still proceed:

Mesh of three head peers, each hub of four coil peers in star topology; four of twelve coil peers down, 8/12 quorum holds.

Head network

Fast consensus is unanimous (R1) and must be as fast as possible (R4). All head peers are expected to be available all the time to participate in this consensus. If any peer becomes unresponsive for long enough that a fallback effect becomes valid, the head switches to rules-based regime, which is an emergency mode that doesn’t require peer interaction.

The following reasoning shapes the head network design:

  • The number of head peers should be relatively small to keep consensus stable and fast. Every additional head peer increases the chances of consensus breakdown and slows it down.
  • Communication latency should be minimized to keep the consensus fast.

The fully-connected mesh topology best satisfies these requirements. Every head peer has a bidirectional communication channel with every other head peer, resulting in O(N²) connections total across the network. This topology avoids multi-hop message delivery while the small number of head peers keeps the O(N²) connection overhead manageable.

Coil network

Unlike head peers, coil peers are not expected to be available all the time (R6). The coil network consists of a large number of coil peers in comparison to the number of head peers (R5). The slow consensus involves both head peers and coil peers. Unanimous consent of head peers is required, and a quorum of coil peers defined by the CoilQuorum head parameter is needed to confirm effects.

The simplest topology that allows having a dynamic set of coil peers without implementing communication between coil peers and dynamic routing in the upcoming version (see Future improvements) is a star topology with each coil peer being connected to exactly one arbitrary head peer (hub). Hubs are always available; coil peers may disappear and re-appear by connecting to any head peer. The number of coil peer connections to a head peer should be limited to avoid overloading head peers.

Information flow

Different roles of head and coil peers imply that peers produce different kinds of data and messages. However, the ultimate goal of the Gummiworm networking layer is to deliver all messages to all nodes to make R8, R9, and R10 possible - every peer should be able to verify any action independently, submit effects to L1, and evacuate funds if needed. This naturally translates to the idea of a “replicated log” of events across all participants. Both head peers and coil peers should eventually receive the same sets of messages from all head and coil peers.

Replicated log

A replicated log is a fundamental distributed systems concept where all nodes maintain consistent copies of a sequence of entries. In consensus protocols like Raft, each log entry is assigned a sequential index, and the system ensures that all nodes eventually hold the same entries at the same indices.

Gummiworm adapts this concept: instead of maintaining a single shared log with global indices, each peer maintains their own sequences of messages, and other peers replicate these sequences. Each message is uniquely identified by:

  • The peer ID (HeadPeerId or CoilPeerId) of the message author
  • A sequential number within that peer’s sequence (some message types may have gaps)

Each message type maintains its own independent sequence of indices. For example, a head peer’s user requests are indexed separately from their block briefs, which are indexed separately from their soft/hard acknowledgements.

The goal is for all nodes to eventually replicate the same set of messages from all head and coil peers, enabling independent verification, effect submission, and evacuation (R8, R9, R10).

The next subsections describe the kind of data that different types of peers produce.

Peer identifiers

Head peers are identified by a HeadPeerId, which is a pair containing:

  • The head peer number (starting from 0)
  • The total number of head peers

The total number is used to determine head peers’ leader turns in the consensus protocol.

Coil peers use a different identifier type (since they never lead consensus and the total number of coil peers is not relevant for leader selection).

For illustrative purposes, head peers are referred to using Greek letters (Alpha, Beta, Gamma, etc.), while coil peers use common names (Alice, Bob, Carol, etc.).

Head peer log entries

Head peers can produce the following types of log entries:

User requests: Upon receiving a well-formed user request, a head peer tags it with a request ID, which is a pair consisting of:

  • The head peer ID
  • A peer-specific sequential number (no gaps)

Block briefs: According to the fast consensus leadership schedule, head peers produce blocks and advertise block briefs. Each block brief is tagged with:

  • The head peer ID
  • A block number (gaps are allowed)

Soft acknowledgements: Head peers acknowledge blocks. Each soft acknowledgement is tagged with:

  • The head peer ID
  • A block number (no gaps—acknowledgements are required for every block from every peer)

Hard acknowledgements: Head peers produce hard acknowledgements for block stacks. Each hard acknowledgement is tagged with:

  • The head peer ID
  • An acknowledgement number (no gaps—head peers must sign every block unconditionally; note that there may be multiple acknowledgements per block for major blocks)

Coil peer log entries

Coil peers can produce only one type of log entries:

Hard acknowledgements: Coil peers produce hard acknowledgements for block stacks. Each hard acknowledgement is tagged with:

  • The coil peer ID
  • An acknowledgement number (no gaps in the sequence—each coil peer increments their counter only when producing an acknowledgement; however, coil peers may skip acknowledging blocks entirely since not all are available at all times, and there is no reason to sign a block that has already been confirmed)

Head peer communication

The communication protocol is inspired by the Raft consensus protocol. Each peer can send only two types of messages to other peers: GetMsgBatch and NewMsgBatch. The first is used to request the next batch of messages, and the second is used as a response.

Communication flow

Each head peer maintains a dedicated HeadPeerLiaison actor for communication with each other head peer. The communication operates as a continuous request-response cycle.

In the GetMsgBatch structure, the calling peer (e.g., Alpha) requests the next batch of messages from another peer (e.g., Beta) by indicating the index of the last batch that Alpha received from Beta and indices for all types of data: blocks, soft acknowledgements, and user requests.

final case class GetMsgBatch( batchNum: Batch.Number, softAckNum: AckNumber, blockNum: BlockNumber, requestNum: RequestNumber )

In response, the calling peer expects to receive the next batch via NewMsgBatch when it is ready—that is, when at least one new message is available.

final case class NewMsgBatch( batchNum: Batch.Number, softAck: Option[AckBlock], blockBrief: Option[BlockBrief.Next], requests: List[UserRequestWithId] )

Beta determines what to include in the batch based on the indices provided in GetMsgBatch:

  • softAck: The next soft acknowledgement after softAckNum (if available)
  • blockBrief: The next block brief after blockNum (if available)
  • requests: User requests starting from requestNum
Note

Batches must arrive sequentially with no gaps. If the peer’s response batchNum does not match the request batchNum, the batch is ignored and the request is sent again.

The request-response cycle proceeds as follows:

  1. Alpha sends a GetMsgBatch request to Beta, indicating the last message indices Alpha has received from Beta
  2. Beta waits until at least one new message is available (a soft acknowledgement, block brief, or user request)
  3. Beta responds with a NewMsgBatch containing the new messages
  4. Alpha verifies the batch:
    • The batchNum matches the request
    • The soft acknowledgement number (if present) is exactly one more than requested
    • The block number (if present) is the next expected leader block from Beta
    • User request numbers (if present) form a consecutive sequence starting from one more than requested
  5. If verification succeeds, Alpha forwards the messages to the appropriate local actors and sends the next GetMsgBatch request
  6. If verification fails, Alpha re-sends the same GetMsgBatch request

Outbox queues and confirmation

Each HeadPeerLiaison maintains three separate outbox queues for messages to be sent to the remote peer:

  • A queue for soft acknowledgements
  • A queue for block briefs
  • A queue for user requests

Messages remain in these queues until they are confirmed in blocks. When a block is confirmed, the HeadPeerLiaison removes all messages up to and including those referenced in that block from the outbox queues. This ensures that messages can be retransmitted if needed during recovery scenarios.

Waiting for new messages

When Beta receives a GetMsgBatch request but has no new messages to send, rather than responding immediately with an empty batch, Beta retains the request and sets a flag. When a new message becomes available in any of Beta’s outbox queues, Beta immediately constructs and sends a NewMsgBatch response. This design minimizes unnecessary empty responses while ensuring low latency when new messages arrive.

Disseminating coil peer hard acknowledgements

Since each coil peer connects to only one head peer, only that head peer receives the coil peer’s hard acknowledgements directly. To ensure all head and coil peers can collect sufficient hard acknowledgements to confirm block stacks, head peers disseminate coil peer hard acknowledgements among themselves and to coil peers during their communication.

Different peers may receive different subsets of coil peer hard acknowledgements. As long as each head peer receives acknowledgements from enough coil peers to meet the configured threshold, the system functions correctly.

This asymmetry is acceptable because the transaction ID of native-script-based transactions (such as settlement, fallback, or finalization effects on Cardano) does not depend on the particular signatures used to authorize it—only that a sufficient number of valid signatures exist. On other L1 blockchains, this property may not hold, which could pose an issue.

Piggybacking on head peer communication

Coil peer hard acknowledgements are disseminated by extending the GetMsgBatch and NewMsgBatch structures to include a map of indices tracking which hard acknowledgements each peer has received from each coil peer.

The GetMsgBatch structure is extended with:

coilHardAcks: Map[CoilPeerId, HardAck.Number]

This map indicates the latest hard acknowledgement number from each coil peer that the requesting peer (Alpha) is aware of . When Beta receives this request, Beta can determine which coil peer hard acknowledgements Alpha is missing by comparing Alpha’s map with Beta’s own received hard acknowledgements.

Similarly, the NewMsgBatch response is extended to include:

coilHardAcks: List[CoilHardAck]

This list contains hard acknowledgements from coil peers that Beta has received but Alpha has not yet seen, based on the indices provided in Alpha’s GetMsgBatch request.

By piggybacking on the existing head peer communication protocol, coil peer hard acknowledgements are efficiently disseminated across all peers without requiring a separate synchronization mechanism. Each head peer gradually accumulates hard acknowledgements from all coil peers until the configured threshold is met for each block stack, allowing the block stack to be confirmed.

Note

Since multiple head peers may forward the same hard acknowledgement, peers can receive duplicate hard acknowledgements from different sources. Duplicates are identified by their CoilPeerId and HardAck.Number and are simply ignored.

Coil peer communication

Coil peer communication follows the same request-response pattern as head peer communication, but adapted for the star topology where each coil peer maintains a connection with exactly one head peer.

Communication flow

Each coil peer maintains a HeadPeerLiaison actor for communication with its connected head peer. The protocol uses the same GetMsgBatch and NewMsgBatch message types, operating as a continuous request-response cycle.

The coil peer’s GetMsgBatch request indicates which messages the coil peer has already received:

final case class GetMsgBatch( batchNum: Batch.Number, softAckNum: Map[HeadPeerId, AckNumber], blockNum: Map[HeadPeerId, BlockNumber], requestNum: Map[HeadPeerId, RequestNumber], headHardAckNum: Map[HeadPeerId, HardAck.Number], coilHardAckNum: Map[CoilPeerId, HardAck.Number] )

Unlike head-to-head communication where a peer tracks messages from one specific peer, coil peers must track messages from all head peers (and all other coil peers for hard acknowledgements). Therefore, the indices are organized as maps keyed by peer ID.

The head peer responds with a NewMsgBatch containing new messages from any head or coil peer:

final case class NewMsgBatch( batchNum: Batch.Number, softAcks: List[AckBlock], blockBriefs: List[BlockBrief.Next], requests: List[UserRequestWithId], headHardAcks: List[HeadHardAck], coilHardAcks: List[CoilHardAck] )

The head peer aggregates messages from all sources—collecting messages from all head peers (via head-to-head communication) and from all coil peers (via coil-to-head communication)—and forwards them to the requesting coil peer.

Reverse flow: Coil peer hard acknowledgements

Coil peers produce hard acknowledgements and send them to their connected head peer. The head peer then disseminates these hard acknowledgements to other head peers (as described in Disseminating coil peer hard acknowledgements) and to other coil peers (by including them in NewMsgBatch responses).

The coil peer’s hard acknowledgements are sent as part of the response to the head peer’s requests. This means the head peer also sends GetMsgBatch requests to the coil peer, requesting the next hard acknowledgement:

final case class GetMsgBatch( batchNum: Batch.Number, hardAckNum: HardAck.Number )

The coil peer responds when a new hard acknowledgement is available:

final case class NewMsgBatch( batchNum: Batch.Number, hardAck: Option[CoilHardAck] )

This bidirectional communication ensures that:

  • Coil peers receive all messages needed to maintain the replicated log and perform independent verification (R8)
  • Head peers receive hard acknowledgements from connected coil peers for slow consensus
  • All messages flow through the star topology efficiently without requiring direct coil-to-coil communication

Wire format

Gummiworm distinguishes three encoding domains, each chosen to match the constraints of its consumer:

  • Peer-to-peer transport carries the GetMsgBatch and NewMsgBatch exchanges defined above, along with their nested message types — block briefs, soft and hard acknowledgements, and user requests. Current implementations use a verbose JSON serialization for ease of debugging and rapid iteration during prototyping. We anticipate migrating to a compact binary format (CBOR) once the protocol stabilizes; this is expected to reduce inter-peer bandwidth materially and improve end-to-end throughput, as discussed in Results.
  • L2 payloads are opaque to Gummiworm itself and inherit their encoding from the ledger they target. Sugar Rush expects JSON-encoded payloads. The Cardano EUTXO ledger-as-L2 expects CBOR-serialized Cardano transactions. Each ledger plug-in defines its own payload schema independently of the consensus layer.
  • L1 artifacts follow each chain’s native conventions. On Cardano, that means CBOR for transactions, native scripts, datums, and witness data, and fixed-size byte strings for KZG commitments and proofs.

Configuration files (bootstrap config, head config) use JSON with comments (jsonc) to give operators a readable, hand-edited input format. See Cardano initialization for examples.

These choices align with the Cardano ecosystem’s norm: CBOR where determinism and compactness matter (on-chain and signed artifacts), JSON where developer experience and tooling matter (control plane, configuration). No exotic codec is introduced; every encoding used is widely deployed and has mature library support across implementation languages.

Future improvements

  1. Decentralized gossip protocol for coil network: Replace the current star topology (where each coil peer connects only to one head peer) with a peer-to-peer gossip protocol. This would enable coil peers to share hard acknowledgements and other messages directly, reducing head peer load and increasing resilience.
  2. Membership change for both networks
  3. M-of-N consensus for head peers
Last updated on