Major additions: - Community Next.js app (port 18187) for browsing claims with API docs - stemedb-chaos crate: Fault injection, chaos testing, CRDT properties - Latent ingestion system: Reddit/FDA ingesters with ADK-Go agents - Disputed claims handling: Manual review workflows and validation - Aphoria security scanner: New extractors (SQL injection, command injection, weak crypto, TLS version), policy-based ignores, UAT reports - Docker infrastructure: Dockerfile, docker-compose.yml for full stack - VulnBank demo: Intentionally vulnerable multi-language test corpus SDK & API enhancements: - Source registry handlers for tracking data provenance - Metrics endpoint - Skeptic filtering improvements Code quality: - Split 14 large files (>500 lines) into focused modules - All files now under 500-line limit per project guidelines Documentation: - Chaos testing guide, circuit breakers, observability docs - Phase 7 UAT documentation updates - Martin Kleppmann technical writer agent Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
71 lines
1.9 KiB
Rust
71 lines
1.9 KiB
Rust
//! gRPC layer for StemeDB node-to-node replication.
|
|
//!
|
|
//! This crate provides the transport layer for two-node replication:
|
|
//!
|
|
//! - **Gossip**: Push new assertions to peers immediately after ingestion
|
|
//! - **Anti-Entropy**: Periodic Merkle root exchange and diff-based sync
|
|
//!
|
|
//! # Architecture
|
|
//!
|
|
//! ```text
|
|
//! [Node A] [Node B]
|
|
//! | |
|
|
//! |--- GossipRequest -------->| (Push new assertion)
|
|
//! |<-- GossipResponse --------|
|
|
//! | |
|
|
//! |--- ExchangeRoots -------->| (Compare Merkle roots)
|
|
//! |<-- RootsResponse ---------|
|
|
//! | |
|
|
//! |--- FetchAssertions ------>| (Pull missing data)
|
|
//! |<-- AssertionData ---------|
|
|
//! ```
|
|
//!
|
|
//! # Usage
|
|
//!
|
|
//! ## Client
|
|
//!
|
|
//! ```ignore
|
|
//! use stemedb_rpc::client::SyncClient;
|
|
//! use stemedb_rpc::proto::GossipRequest;
|
|
//!
|
|
//! let client = SyncClient::connect("http://peer:18182").await?;
|
|
//! let resp = client.gossip(GossipRequest {
|
|
//! assertion_hash: hash.to_vec(),
|
|
//! assertion_data: data,
|
|
//! hlc_time: ts.time_ntp64,
|
|
//! hlc_counter: 0,
|
|
//! hlc_node_id: node_id.to_vec(),
|
|
//! }).await?;
|
|
//! ```
|
|
//!
|
|
//! ## Server
|
|
//!
|
|
//! ```ignore
|
|
//! use stemedb_rpc::server::{SyncServiceHandler, SyncStorage};
|
|
//! use stemedb_rpc::proto::sync_service_server::SyncServiceServer;
|
|
//! use tonic::transport::Server;
|
|
//!
|
|
//! let handler = SyncServiceHandler::new(my_storage);
|
|
//! Server::builder()
|
|
//! .add_service(SyncServiceServer::new(handler))
|
|
//! .serve("[::1]:18182".parse()?)
|
|
//! .await?;
|
|
//! ```
|
|
|
|
#![forbid(unsafe_code)]
|
|
#![warn(missing_docs)]
|
|
|
|
pub mod client;
|
|
pub mod error;
|
|
pub mod server;
|
|
|
|
/// Generated protobuf types and service definitions.
|
|
#[allow(missing_docs)]
|
|
pub mod proto {
|
|
tonic::include_proto!("stemedb.sync.v1");
|
|
}
|
|
|
|
pub use client::{RetryConfig, SyncClient};
|
|
pub use error::{Result, RpcError};
|
|
pub use server::{SyncServiceHandler, SyncStorage};
|