Repository navigation
feat(id): operator block list — blocks table (part 1 of #2245) - #4874
Conversation
…task 5848 part 1) Adds the blocks table to the per-node redb event store: Block/BlockKind (peer_key | ip | topic_tag) with added_at, reason, and optional expires_at (null = permanent). add_block/remove_block/blocks/active_block/is_blocked; expiry is exclusive and expired rows stay listed but unenforced. Pre-existing stores gain the table on open (additive, no format change). Enforcement seams (session admission, blob gate, gossip/pull) are the remaining part of task 5848. Tests: persist-across-restart, expired-listed-not-enforced, remove — written, to be verified in CI (laptop compile was contended this shift).
|
Warning Review limit reachedYou've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Next included review available in 28 minutes. View limit details
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. CodeRabbit Verify
|
The enforcement seams consult the store's blocks table through BlockList (peer_blocked / topic_tag_blocked / ip_blocked), implemented for EventStore and for SharedEventStore under its read lock. The trait reads the list live and judges expiry against the wall clock (crate::time::unix_ms), the epoch Block timestamps are stamped in, so seams need no clock of their own — the abuse evaluator's clock is monotonic and could not judge a wall-clock expiry. A read error invents no block. Tests: the trait answers peer/topic/IP from the store, an expired block is not enforced through it, and the #2245 invariant is pinned — a blocked author's already-signed events are still ingested and applied.
…2245, task 5848) PullGate gains with_blocks(): a peer blocked by key is refused under every policy, and a gate whose world name is a blocked topic tag serves nothing — composition narrows the policy only, and a gate without a list is unchanged. Both session seams already check the gate before any event is sent (range sync in event_store::sync, the handshake in log_sync::answer), so they enforce endpoint blocks with their existing refusal shapes (PullRefused / Answer::Refuse). log_sync::answer additionally checks the requested topic's hash bytes as a topic tag, the form that seam names a topic in. server_config docs note the block list is store-resident, not config. Tests: gate unit tests (blocked peer under Open, blocked topic tag, real store list with permanent vs expired rows), a blocked-peer range session, and blocked-peer and blocked-topic log sessions — each refused with no event crossing.
decide_with_blocks() composes the operator block list over membership: a requester blocked by endpoint key is refused fetch and observe alike; decide() delegates with no list, unchanged. blob_events_with_blocks() routes get/get_many/observe verdicts through it, so a blocked endpoint gets the same AbortReason::Permission as a non-member and the refusal does not reveal which rule made it. Push verdicts are untouched: writes are ingest, and a block never rejects what a peer sends, only what it is served. Test: a blocked member is refused fetch and observe; a list blocking someone else changes nothing.
…5848) AbuseEvaluator gains with_block_list(): open_connection refuses a blocked endpoint first, with Refusal::blocked_by_operator() — the seam's existing Refusal return type — registering no connection. WorldProtocol gains with_blocks() and its accept() branches on BlockedByOperator: it logs an operator block, closes with that reason, and does not count the refusal against the per-peer connection cap. Frame/byte checks are unchanged: a block refuses new sessions, it does not drop a session already open. Test: the evaluator refuses a blocked endpoint (BlockedByOperator, no retry, no connection registered) and admits an unblocked one.
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
Part 1 of #2245 (queue task 5848) — not merge-ready: enforcement seams still to come in this task.
What this adds
The persisted operator block list in the per-node event store (
pkgs/id/src/event_store/mod.rs):blocksredb table: one row per block, keyed by kind tag + value, holdingadded_at,reason, and optionalexpires_at(None= permanent) — the packet's{kind: peer_key | ip | topic_tag, value, added_at, reason, expires_at}shape.Block/BlockKindtypes withadd_block/remove_block/blocks/active_block/is_blockedonEventStore. Expiry is exclusive; expired rows stay listed (the operator's record) but are never enforced.Tests
New unit tests: persist-across-restart, expired-block-listed-but-not-enforced, remove-block. Written this shift; local verification was blocked by laptop compile contention (multiple fleet cargo builds), so CI on this PR is the verification of record — treat a red run as the next fix target.
Still to come (task 5848 remains open, parked for resume)
Refusal::blocked_by_operator(): new-session admission, blob serving (blob_gate.rs), gossip/pull (pull_policy.rs, sync paths).PullPolicy.🤖 Queue worker lane A, task 5848 (resuming lane K's worktree + seam map).
Open in [code]smith · Need help on this PR? Tag
@codesmith-botwith what you need.