syntax = "proto3"; package tidal.replication.v1; // Globally unique identifier for a WAL segment. message WalSegmentId { uint32 region_id = 1; uint32 shard_id = 2; uint64 seqno = 3; } // A WAL segment ready for shipping to a peer shard. message ShipSegmentRequest { WalSegmentId id = 1; bytes payload = 2; uint64 event_count = 3; // The segment's authoritative last WAL sequence number, computed by the // leader from the ORIGINAL (pre-community-overlay-filter) bytes. Lets the // receiver advance its replication-lag leader high-water-mark even for an // all-local segment that filters to an empty payload (obs-REPL-1). A 0 value // (e.g. from an older sender that omits this field) means "unknown" and the // receiver falls back to the per-batch boundaries it decodes. uint64 leader_last_seq = 4; // The shipping stream's baseline (m11p2): the WAL seqno at which this // leader's stream STARTED. Non-zero only on catch-up stream chunks from a // promoted leader; seqnos at or below it are pre-stream history the // receiver jumps its frontier past instead of treating as a gap. 0 (the // default, and what every live unary ship carries) means "stream from the // beginning". uint64 stream_baseline = 5; // The sender's leadership term (m11p4 fencing). 0 = the topology era or a // pre-m11p4 sender; a receiver at term >= 1 rejects term-0 traffic, and any // receiver rejects a term below its own (FAILED_PRECONDITION) — a deposed // leader's ships can never apply. uint64 term = 6; // The region claiming leadership of `term` (m11p4). uint32 leader_region = 7; } // Response to a segment shipment. message ShipSegmentResponse { bool accepted = 1; // The receiver's contiguous applied seqno for the request's source shard at // acceptance time (m11p2): a monotonic hint the sender folds into its acked // frontier so retries of already-applied data prune and heal needs no // separate status fetch. 0 = unknown (older peer / no applied source wired). uint64 applied_seqno = 2; // The receiver's current term (m11p4): a value above the sender's term is // the sender's step-down signal. uint64 term = 3; } // Request to stream segments from a given sequence number. message StreamRequest { uint32 shard_id = 1; uint64 from_seqno = 2; // The puller's current term (m11p4). The source serves only when the terms // match: a stale puller must rejoin first, and a stale SOURCE must step // down rather than serve its possibly-divergent tail. uint64 term = 3; } // Heartbeat request matching ControlPlane's ShardStats. message HeartbeatRequest { uint32 shard_id = 1; uint32 region_id = 2; uint64 entity_count = 3; double signal_throughput_eps = 4; uint64 disk_bytes = 5; // Replication lag per peer region (region_id -> lag in events). map replication_lag = 6; uint64 last_heartbeat_ns = 7; // The sender's leadership term (m11p4): a leader heartbeat is the lease // assertion + failure-detector input. 0 = the topology era / a non-leader // health probe. uint64 term = 8; // The region asserting leadership of `term` (m11p4). uint32 leader_region = 9; // The asserted term's activation stream baseline (m11p4): immutable for // the term; a joining follower jumps its applied frontier for the leader's // stream to it (seqnos at or below are pre-stream history). uint64 stream_baseline = 10; // The leader's ELECTION-TIME log position (m11p4): the term and frontier // of its log in the PREVIOUS stream's numbering — the same pair the vote // restriction compares. A joining node is DIVERGENT iff its own position // exceeds this lexicographically (it holds entries the new leadership's // history does not subsume). uint64 prev_log_term = 11; uint64 prev_log_seq = 12; } // Heartbeat acknowledgement. message HeartbeatResponse { bool acknowledged = 1; // The responder's current term (m11p4): above the sender's term = the // sender's step-down signal. uint64 term = 2; // Whether the responder accepted the sender's leadership assertion // (false = the sender's term is stale). bool accepted = 3; } // A follower's self-report of its durable frontier (m11p3). // // Pushed by the receiver once per apply round — fully decoupled from ship // acks, so the leader's quorum commit index stays fresh even when its // outbound ships stall (gap-parked follower, quiet leader, pull catch-up). message AppliedReport { // The reporting node's shard id. uint32 reporter_shard = 1; // The stream's source shard (the leader being reported to). uint32 source_shard = 2; // The reporter's contiguous durably-applied seqno for that stream. uint64 applied_seqno = 3; // The reporter's current term (m11p4): the leader folds a report into its // quorum commit index ONLY when this matches the index's activation term — // a stale or cross-leadership report can never advance commitment. uint64 reporter_term = 4; } // Applied-report acknowledgement. message AppliedReportAck { bool acknowledged = 1; } // A pre-vote or vote request (m11p4 leader election). message VoteRequest { // The term votes are requested for. For a pre-vote this is the PROPOSED // term (candidate's current + 1) — nothing has been bumped. uint64 term = 1; uint32 candidate_region = 2; // The candidate's log position for the up-to-date restriction, // compared lexicographically: (last_log_term, last_log_seq). uint64 last_log_term = 3; uint64 last_log_seq = 4; // Pre-vote probe: changes no voter state, never inflates terms. bool prevote = 5; // Leadership-transfer election (`TimeoutNow`): voters skip the // leader-freshness refusal — the current leader sanctioned this. bool transfer = 6; } // A vote (or pre-vote) reply. message VoteResponse { // The voter's current term (above the candidate's = step-down signal). uint64 term = 1; bool granted = 2; } // The current leader tells `target` to start an immediate transfer election // (m11p4 fenced promote). message TimeoutNowRequest { // The sanctioning leader's current term. uint64 term = 1; uint32 leader_region = 2; } message TimeoutNowResponse { // Whether the target started an election. bool accepted = 1; } // WAL segment shipping service between tidalDB shards. service WalShipping { // Ship a single WAL segment to a peer shard (unary). rpc ShipSegment(ShipSegmentRequest) returns (ShipSegmentResponse); // Stream WAL segments from a given sequence number (server-streaming). rpc StreamSegments(StreamRequest) returns (stream ShipSegmentRequest); // Periodic health check for the ControlPlane; with m11p4, the leader's // lease assertion and the failure detector's input. rpc Heartbeat(HeartbeatRequest) returns (HeartbeatResponse); // Follower -> leader durable-frontier report (m11p3 quorum acks). rpc ReportApplied(AppliedReport) returns (AppliedReportAck); // Pre-vote / vote (m11p4 leader election). rpc RequestVote(VoteRequest) returns (VoteResponse); // Fenced leadership transfer: start an immediate election (m11p4). rpc TimeoutNow(TimeoutNowRequest) returns (TimeoutNowResponse); }