A modern, asynchronous peer-to-peer gossip protocol library and application.
- Async/await - Built on Tokio for high-performance async I/O
- Epidemic broadcast - Probabilistic message forwarding for efficient network coverage
- Anti-entropy - Periodic synchronization ensures eventual consistency
- Rate limiting - Per-peer token bucket rate limiting prevents DoS attacks
- Highly configurable - Fine-tune gossip parameters for your use case
- Zero unsafe code - Memory safe and thread safe
To use Grapevine in your Rust project:
cargo add grapevineOr add manually to your Cargo.toml:
[dependencies]
grapevine = "1.0"
tokio = { version = "1", features = ["full"] }
bytes = "1"To install the standalone gossip client binary:
cargo install grapevineThen run:
grapevine --helpuse grapevine::{Node, NodeConfig};
use bytes::Bytes;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Create a node with default configuration
let config = NodeConfig::default();
let node = Node::new(config).await?;
// Set up message handler
node.on_message(|origin, data| {
println!("Received from {origin}: {data:?}");
}).await;
// Start the node
node.start().await?;
// Broadcast a message
node.broadcast(Bytes::from("Hello, gossip!")).await?;
// Keep running until explicit shutdown
tokio::signal::ctrl_c().await?;
node.shutdown().await?;
Ok(())
}use grapevine::{Node, NodeConfig, NodeConfigBuilder};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Create first node
let node1 = Node::new(NodeConfig::default()).await?;
node1.start().await?;
let addr1 = node1.local_addr().await.unwrap();
// Create second node, bootstrapping from first
let config2 = NodeConfigBuilder::new()
.add_bootstrap_peer(addr1)
.fanout(5)
.build()?;
let node2 = Node::new(config2).await?;
node2.start().await?;
// Nodes will automatically discover and connect to each other
Ok(())
}Grapevine is highly configurable. See NodeConfig for all options:
use grapevine::NodeConfigBuilder;
use std::time::Duration;
let config = NodeConfigBuilder::new()
.bind_addr("127.0.0.1:8000".parse().unwrap())
.gossip_interval(Duration::from_secs(5))
.fanout(3)
.max_peers(50)
.max_message_size(1024 * 1024)
.build()?;crypto- Enable message signing and verification (deferred tov1.1)
Note: QUIC transport support is planned for v1.1+
Grapevine implements a push-based gossip protocol with the following components:
- Epidemic Broadcast: Probabilistic message forwarding (default 70% probability, max 5 forwards)
- Anti-Entropy: Periodic digest exchange and repair (every 30s) ensures eventual consistency
- Peer Management: Automatic health monitoring with state machine (Connecting => Connected => Stale => Disconnected)
- Rate Limiting: Per-peer token bucket (100 capacity, 50 tokens/sec) prevents DoS attacks
- Message Deduplication: Time-based eviction (5 minute TTL) prevents duplicates
- Graceful Shutdown: Phased shutdown with goodbye notifications to peers
See Architecture Documentation for details.
# Run all tests
cargo test --all-features
# Run integration tests only
cargo test --test integration
# Run with logging
RUST_LOG=debug cargo testGrapevine includes a standalone binary for running gossip nodes. For a complete guide on starting nodes, joining networks, broadcasting messages, and more, see the CLI Usage Guide.
For a straightforward run, first copy .env.example to .env and customize:
cp .env.example .env
# Edit .env with your configuration
cargo run-H, --host <HOST> Host to bind to [env: BIND_HOST] [default: 127.0.0.1]
-p, --port <PORT> Port to listen on [env: BIND_PORT] [default: 8000]
-b, --peer <PEER> Bootstrap peer addresses [env: BOOTSTRAP_PEERS]
-g, --gossip-interval <SECS> Gossip interval in seconds [env: GOSSIP_INTERVAL_SECS] [default: 5]
-f, --fanout <FANOUT> Fan-out factor [env: FANOUT] [default: 3]
-m, --max-peers <MAX_PEERS> Maximum number of peers [env: MAX_PEERS] [default: 50]
-l, --log-level <LEVEL> Log level (trace, debug, info, warn, error) [env: RUST_LOG] [default: info]# Start a seed node
cargo run
# Join the network from another terminal
cargo run -- --port 8001 --peer 127.0.0.1:8000
# Join with multiple bootstrap peers
cargo run -- --port 8002 \
--peer 127.0.0.1:8000,127.0.0.1:8001
# Start with custom configuration
cargo run -- \
--host 0.0.0.0 \
--port 9000 \
--fanout 5 \
--gossip-interval 3
# Use environment variables
BIND_HOST=0.0.0.0 BIND_PORT=9000 cargo run
# Enable debug logging
cargo run -- --log-level debug
# Graceful shutdown
# Press Ctrl+C to send goodbye messages and cleanly exitSee docs/client.md for:
- Step-by-step setup instructions
- Multi-node cluster examples
- Network tuning parameters
- Troubleshooting common issues
See the examples directory:
simple_node.rs- Single node setupmulti_node_cluster.rs- Multi-node clustercustom_config.rs- Custom configuration
Run an example:
RUST_LOG=info cargo run --example simple_nodeContributions are welcome! Please read our Contributing Guidelines and Code of Conduct.
Licensed under either of
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.