Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions docs/craft/rpcs.md
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,10 @@ previously answered as one.
it — `craft::wire::op` stops at 14 — so it is deferred at the *wire*, not merely at the transport. It need not
ride the same channel as the client plane: these calls are node-to-node, and HomeBlocks may prefer its existing
inter-node RPC. See `craft_client/docs/peer-plane.md` for the interface (`craft_peer`) and what remains.
Whatever it ends up being, it **must be timeout-bounded**: the catch-up call site
(`CraftPeerFetcher::fetch_from_peer`, used by `SyncRSCommitLSN` apply) already carries a `timeout_ms`
parameter (`peer_fetch_timeout_ms` in `home_blks_config.fbs`, default 5000ms) for the real transport to
enforce — a peer that misses it is treated as unreachable, same as any other hard failure.

Note the asymmetry this creates, because it is easy to get backwards: HomeBlocks is **both ends** of the peer
plane (it initiates on RAFT commit *and* serves peers) but **only the far end** of the client plane (it never
Expand Down
1 change: 1 addition & 0 deletions docs/craft/subtasks.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ and enforce single-writer exclusivity without data flowing through the RAFT log.
- RAFT entry carries `{rs_commit_lsn, client_token, empty_slots[]}`
- **Leader pre-resolution:** before proposing `N`, the leader resolves every unresolved slot ≤ `N`: fetch it from any holder, or record an `Empty` verdict on quorum-lacks evidence (leader counts itself; non-responders never count); it must not propose past an unresolved slot
- On apply: verify token; mark `empty_slots` Empty, **discarding any local data held there** (reconciliation); if behind, `fetch_data()` the remaining missing slots from peers; then `commit_lsn = rs_commit_lsn`. **Apply never truncates** and replicas **never declare Empty unilaterally**
- Peer catch-up (`CraftPeerFetcher::fetch_from_peer`) is **timeout-bounded**: every call passes `peer_fetch_timeout_ms` (`home_blks_config.fbs`, default 5000ms); a peer that misses the deadline is treated as a hard failure, same as any other fetch failure (best-effort — `commit_lsn` still advances, unresolved LSNs stay missing). The interface only carries the deadline; enforcing it against a real wire call is S9's (the transport's)
- `append(sync_to, client_token)` proposes this entry via RAFT
- Triggers: periodic every N LSNs (configurable via `home_blks_config.fbs`, default 128), watchdog, login, **client-requested (after a failed sub-quorum write)** — the client's `Resolve` RPC lands on `CraftReplDev::request_resolution(term, upto)`, which runs this same leader pre-resolution and returns the Empty verdicts ≤ `upto` (`craft::resolution_result`). The client broadcasts it to every member (it cannot know the leader mid-session); a follower returns `NOT_LEADER`

Expand Down
Loading