//! 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};