LPsLux Proposals
Research
LP-6420

LuxRelay Gossipsub Protocol

Draft

LuxRelay Gossipsub Protocol specification for LuxDA Bus

Category
Core
Created
2026-01-02

Abstract

This LP defines the LuxRelay gossip protocol for fast message propagation across the LuxDA Bus network. LuxRelay provides best-effort, low-latency delivery of headers and blobs before consensus finalization.

Motivation

Fast message propagation is essential for:

  1. Low-latency messaging applications (chat, notifications)
  2. Efficient consensus (validators receive headers quickly)
  3. Blob dispersal (DA operators receive data promptly)
  4. User experience (preconfirmations depend on fast propagation)

Specification

1. Network Topology

1.1 Node Types

TypeRoleRequirements
ValidatorConsensus participationFull relay + header chain
RelayGossip propagationFull relay, no consensus
LightSubscribe onlySelective relay
DA OperatorBlob storageFull relay + DA

1.2 Peer Discovery

Nodes discover peers via:

  1. Bootstrap nodes (hardcoded list)
  2. DHT (Kademlia-based)
  3. PEX (Peer Exchange)
type PeerDiscovery struct {
    BootstrapNodes []string
    DHTEnabled     bool
    PEXEnabled     bool
    MaxPeers       int
    MinPeers       int
}

Default configuration:

  • MaxPeers: 50
  • MinPeers: 10
  • BootstrapNodes: Network-specific list

1.3 Connection Management

type ConnectionManager struct {
    // Target number of outbound connections
    OutboundTarget int

    // Maximum inbound connections
    MaxInbound int

    // Connection rotation interval
    RotationInterval time.Duration

    // Peer scoring threshold
    ScoreThreshold float64
}

2. Topic Structure

2.1 Topic Naming

Topics follow a hierarchical naming scheme:

/lux/<network>/relay/<topic_type>/<identifier>

Examples:

  • /lux/mainnet/relay/headers/global
  • /lux/mainnet/relay/namespace/0x1234...
  • /lux/mainnet/relay/blobs/available

2.2 Global Topics

TopicContentSubscribers
headers/globalAll headersValidators, indexers
blocks/proposedProposed blocksValidators
blocks/finalizedFinalized blocksAll nodes
blobs/availableBlob availability hintsDA operators

2.3 Namespace Topics

Each namespace has a dedicated topic:

/lux/<network>/relay/namespace/<namespaceId>

Nodes subscribe to namespaces they're interested in:

  • Application nodes: Subscribe to app namespaces
  • Validators: Subscribe to all active namespaces
  • Light clients: Subscribe selectively

3. Message Types

3.1 Header Announcement

type HeaderAnnouncement struct {
    Header    MsgHeader
    Source    PeerID
    Timestamp uint64
    Signature []byte  // Sender's relay signature
}

3.2 Blob Availability Hint

type BlobAvailabilityHint struct {
    BlobCommitment [32]byte
    BlobLen        uint32
    Providers      []PeerID
    ExpiresAt      uint64
}

3.3 Block Announcement

type BlockAnnouncement struct {
    BlockHash   [32]byte
    BlockHeight uint64
    Proposer    PeerID
    Timestamp   uint64
    // Headers not included - fetch separately
}

4. Gossip Protocol

4.1 Message Propagation

Gossipsub with modifications for LuxDA:

type GossipConfig struct {
    // Gossipsub parameters
    D        int     // Target outbound degree (6)
    DLo      int     // Low watermark (4)
    DHi      int     // High watermark (12)
    DScore   int     // Peers to emit to based on score (4)
    DOut     int     // Outbound quota (2)
    DLazy    int     // Lazy gossip peers (6)

    // Timing
    HeartbeatInterval  time.Duration  // 700ms
    FanoutTTL          time.Duration  // 60s

    // History
    HistoryLength  int  // 5
    HistoryGossip  int  // 3
}

4.2 Message Flow

Sender → Local Validation → Mesh Peers → Lazy Peers
                ↓
          Cache message
                ↓
          IHAVE to gossip peers

4.3 Deduplication

Messages are deduplicated by ID:

func MessageID(msg *RelayMessage) []byte {
    switch msg.Type {
    case TypeHeaderAnnouncement:
        return sha3.Sum256(msg.Header.NamespaceId, msg.Header.Seq)
    case TypeBlobHint:
        return sha3.Sum256(msg.BlobCommitment)
    case TypeBlockAnnouncement:
        return sha3.Sum256(msg.BlockHash)
    }
}

5. Peer Scoring

5.1 Score Components

type PeerScore struct {
    // Topic-specific scores
    TopicScores map[string]float64

    // Application-specific score
    AppScore float64

    // IP colocation penalty
    IPColocationPenalty float64

    // Behavioral score
    BehaviorPenalty float64
}

func ComputeScore(peer *Peer) float64 {
    score := 0.0

    // Topic scores
    for topic, weight := range TopicWeights {
        score += peer.TopicScores[topic] * weight
    }

    // Application score
    score += peer.AppScore * AppScoreWeight

    // Penalties
    score -= peer.IPColocationPenalty
    score -= peer.BehaviorPenalty

    return score
}

5.2 Topic Score Parameters

type TopicScoreParams struct {
    // Time in topic mesh
    TimeInMeshWeight  float64
    TimeInMeshQuantum time.Duration
    TimeInMeshCap     float64

    // First message deliveries
    FirstMessageDeliveriesWeight float64
    FirstMessageDeliveriesDecay  float64
    FirstMessageDeliveriesCap    float64

    // Message delivery rate
    MeshMessageDeliveriesWeight    float64
    MeshMessageDeliveriesDecay     float64
    MeshMessageDeliveriesThreshold float64
    MeshMessageDeliveriesWindow    time.Duration
    MeshMessageDeliveriesActivation time.Duration

    // Invalid messages
    InvalidMessageDeliveriesWeight float64
    InvalidMessageDeliveriesDecay  float64
}

5.3 Score Thresholds

ThresholdValueAction
Gossip0Include in gossip
Publish0Publish to peer
Graylist-1000Remove from mesh
Accept-2500Accept messages
Reject-5000Reject connections

6. Anti-Eclipse Measures

6.1 Peer Diversity

Enforce diversity in peer selection:

type DiversityConstraints struct {
    // Maximum peers from same /16 subnet
    MaxFromSubnet int

    // Maximum peers from same ASN
    MaxFromASN int

    // Minimum geographic diversity
    MinGeoRegions int

    // Outbound-only quotas
    OutboundMinFromDistinct int
}

6.2 Connection Rotation

Periodically rotate peers to prevent stale connections:

func RotatePeers(manager *ConnectionManager) {
    // Identify low-scoring peers
    for _, peer := range manager.Peers() {
        if peer.Score < RotationThreshold {
            manager.Disconnect(peer)
        }
    }

    // Connect to new random peers
    newPeers := manager.Discovery.RandomPeers(RotationCount)
    for _, peer := range newPeers {
        manager.Connect(peer)
    }
}

7. Wire Protocol

7.1 Message Envelope

RelayMessageV1 := {
    version:     uint8    [1 byte]
    type:        uint8    [1 byte]
    topicLen:    uint16   [2 bytes]
    topic:       bytes    [topicLen bytes]
    payloadLen:  uint32   [4 bytes]
    payload:     bytes    [payloadLen bytes]
    signatureLen: uint16  [2 bytes]
    signature:   bytes    [signatureLen bytes]
}

7.2 Control Messages

const (
    CtrlIHave    = 1  // Have these messages
    CtrlIWant    = 2  // Want these messages
    CtrlGraft    = 3  // Add to mesh
    CtrlPrune    = 4  // Remove from mesh
    CtrlPing     = 5  // Keepalive
    CtrlPong     = 6  // Keepalive response
)

8. Subscription Management

8.1 Namespace Subscription

type SubscriptionManager struct {
    // Subscribed namespaces
    Namespaces map[[20]byte]SubscriptionOpts

    // Global subscriptions
    GlobalTopics []string

    // Callback handlers
    OnHeader func(*MsgHeader)
    OnBlob   func(*BlobHint)
}

type SubscriptionOpts struct {
    // Include blob hints
    WantBlobs bool

    // Filter by sender
    SenderFilter []Identity

    // Rate limit
    MaxRate int
}

8.2 Dynamic Subscription

func (sm *SubscriptionManager) Subscribe(nsId [20]byte, opts SubscriptionOpts) error {
    topic := fmt.Sprintf("/lux/%s/relay/namespace/%x", network, nsId)

    if err := sm.gossipsub.Join(topic); err != nil {
        return err
    }

    sm.Namespaces[nsId] = opts
    return nil
}

func (sm *SubscriptionManager) Unsubscribe(nsId [20]byte) error {
    topic := fmt.Sprintf("/lux/%s/relay/namespace/%x", network, nsId)

    if err := sm.gossipsub.Leave(topic); err != nil {
        return err
    }

    delete(sm.Namespaces, nsId)
    return nil
}

9. Metrics

9.1 Propagation Metrics

MetricDescription
relay_message_latency_msTime from send to receive
relay_messages_receivedMessages received per topic
relay_messages_publishedMessages published per topic
relay_duplicate_ratioRatio of duplicate messages
relay_invalid_ratioRatio of invalid messages

9.2 Peer Metrics

MetricDescription
relay_peer_countActive peer connections
relay_peer_score_distributionScore distribution histogram
relay_mesh_sizeSize of mesh per topic
relay_connection_durationDuration of peer connections

Rationale

Why Gossipsub?

  • Battle-tested in Ethereum and Filecoin
  • Efficient message propagation with bounded amplification
  • Built-in peer scoring for Sybil resistance
  • Supports topic-based routing

Why Namespace Topics?

  • Applications subscribe only to relevant traffic
  • Reduces bandwidth for focused nodes
  • Enables namespace-specific rate limiting

Why Separate from Consensus?

  • Relay is best-effort, fast
  • Consensus is guaranteed, slower
  • Separation allows optimization of each layer

Security Considerations

Sybil Attacks

Mitigated by:

  • Peer scoring penalizes bad behavior
  • Connection diversity requirements
  • Stake-weighted gossip for validators

Message Flooding

Mitigated by:

  • Per-namespace rate limits
  • Topic-level bandwidth quotas
  • Invalid message scoring

Eclipse Attacks

Mitigated by:

  • Outbound connection diversity
  • Geographic/ASN diversity requirements
  • Connection rotation

Test Plan

Unit Tests

  1. Topic Routing: Messages route to correct subscribers
  2. Deduplication: Duplicate messages filtered
  3. Scoring: Peer scores update correctly

Integration Tests

  1. Propagation Latency: Measure message propagation across network
  2. Mesh Formation: Verify mesh forms with correct degree
  3. Recovery: Network recovers from node failures

Chaos Tests

  1. Churn: High peer churn rate
  2. Partition: Network partition and recovery
  3. Flood: Message flooding attack

References


LP-6420 v1.0.0 - 2026-01-02