grapevine 1.0.0

A modern, asynchronous peer-to-peer gossip protocol library and application
Documentation
# Grapevine Architecture

This document describes the internal architecture of Grapevine.

## Overview

Grapevine is structured in layers:

┌─────────────────────────────────┐
│          Application            │
├─────────────────────────────────┤
│           Node API              │
├─────────────────────────────────┤
│         Protocol Engine         │
│(gossip, epidemic, anti-entropy) │
├─────────────────────────────────┤
│        Transport Layer          │
│       (TCP, QUIC, etc)          │
├─────────────────────────────────┤
│          Core Types             │
└─────────────────────────────────┘

## Components

### Core Types (`src/core/`)

- **Message**: Gossip message structure with ID, TTL, and payload variants
- **MessageCodec**: Length-prefixed framing and bincode serialization
  - Message size limit: 1MB default (configurable)
- **Peer**: Represents a connected peer with health tracking
- **PeerInfo**: Peer metadata with health score, failure tracking, state machine
- **RateLimiter**: Per-peer token bucket rate limiting (100 capacity, 50 tokens/sec)

### Transport Layer (`src/transport/`)

- **TcpTransport**: TCP-based transport with connection pooling
- Note: QUIC transport planned for `v1.1+`

### Protocol Engine (`src/protocol/`)

- **Gossip**: Main protocol engine with background tasks
- **Epidemic**: Probabilistic broadcast (70% forward probability, max 5 forwards)
- **Anti-Entropy**: Periodic digest exchange and repair (every 30s)

## Message Flow

1. Application calls `node.broadcast(data)`
2. Protocol creates `Message` with unique ID (origin + sequence + timestamp)
3. Message stored in `seen_messages` cache with metadata
4. Message serialized via `MessageCodec`
5. Transport sends to random subset of peers (fan-out)
6. Receiving nodes:
   - Rate limiting check (token bucket per peer)
   - Deserialize message via `MessageCodec`
   - Check if already seen (deduplication via `MessageId`)
   - Store in `seen_messages` with `MessageEntry` metadata
   - Forward to application handler (if `Application` payload)
   - Probabilistic forwarding decision (70% probability)
   - Re-gossip to other peers (if TTL > 1 and forward count < 5)

## Peer Discovery

1. Node connects to bootstrap peers
2. Requests peer list via `PeerListRequest`
3. Receives `PeerListResponse` with known peers
4. Connects to discovered peers
5. Repeats until reaching `max_peers`

## Heartbeat & Peer Health

- Nodes send periodic heartbeats (configurable interval)
- `last_seen` timestamp updated on any message
- Peer state machine: Connecting => Connected => Stale => Disconnected
- Health score based on:
  - Success/failure ratio
  - Connection age (older connections get bonus)
  - Consecutive failures (penalty)
- Peers with 5 consecutive failures are disconnected
- Peer maintenance runs every 10 seconds
- Stale peers marked after `peer_timeout` (default: 30s)

## Configuration

All behavior is configurable via `NodeConfig`:

- `gossip_interval`: How often to send heartbeats (default: 5s)
- `fanout`: Number of peers per gossip round (default: 3)
- `max_peers`: Maximum peer connections (default: 50)
- `peer_timeout`: Stale peer timeout (default: 30s)
- `message_dedup_ttl`: How long to remember seen messages (default: 5 minutes)
- `anti_entropy`: Anti-entropy protocol configuration
  - `enabled`: Enable/disable anti-entropy (default: true)
  - `interval`: How often to sync (default: 30s)
  - `fanout`: Peers to sync with (default: 3)
- `epidemic`: Epidemic broadcast configuration
  - `forward_probability`: Probability of forwarding (default: 0.7)
  - `max_forwards`: Maximum forwards per message (default: 5)
- `rate_limit`: Rate limiting configuration
  - `enabled`: Enable/disable rate limiting (default: true)
  - `capacity`: Token bucket capacity (default: 100)
  - `refill_rate`: Tokens per second (default: 50)

See `NodeConfig` and `NodeConfigBuilder` documentation for all options and validation rules.