Skip to content

feat(id): operator block list — blocks table (part 1 of #2245) - #4874

Merged
dezren39 merged 5 commits into
mainfrom
queue/5848-2245-operator-block-list
Nov 3, 2026
Merged

dezren39 merged 5 commits into
mainfrom
queue/5848-2245-operator-block-list

Conversation

@dezren39

@dezren39 dezren39 commented Nov 3, 2026 •

Copy link
Copy Markdown
Member

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):

  • New blocks redb table: one row per block, keyed by kind tag + value, holding added_at, reason, and optional expires_at (None = permanent) — the packet's {kind: peer_key | ip | topic_tag, value, added_at, reason, expires_at} shape.
  • Block / BlockKind types with add_block / remove_block / blocks / active_block / is_blocked on EventStore. Expiry is exclusive; expired rows stay listed (the operator's record) but are never enforced.
  • Stores created before this table gain it on open — additive, no format-version change, so existing nodes are not refused.
  • The ingest invariant is untouched by construction: this PR adds storage only; a block will change serving/subscribing, never rejection of already-signed objects.

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)

  • Endpoint enforcement via Refusal::blocked_by_operator(): new-session admission, blob serving (blob_gate.rs), gossip/pull (pull_policy.rs, sync paths).
  • IP blocks at the listener; topic/tag composition with PullPolicy.
  • Remaining packet tests: blocked endpoint refused at each seam; signed objects from a blocked endpoint not rejected at ingest.

🤖 Queue worker lane A, task 5848 (resuming lane K's worktree + seam map).


Autofix with [code]smith
Open in [code]smith · Need help on this PR? Tag @codesmith-bot with what you need.

…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).
@coderabbitai

coderabbitai Bot commented Nov 3, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

You'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.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 673ffae9-d3b2-41c7-86d3-17c6b103f4dc
Commits

Reviewing files that changed from the base of the PR and between c19c1d8 and 6855d34.

Files selected for processing: 9
  • pkgs/id/src/abuse.rs
  • pkgs/id/src/blob_gate.rs
  • pkgs/id/src/event_store/mod.rs
  • pkgs/id/src/event_store/sync.rs
  • pkgs/id/src/log_sync.rs
  • pkgs/id/src/pull_policy.rs
  • pkgs/id/src/server_config/mod.rs
  • pkgs/id/src/store_traits.rs
  • pkgs/id/src/world_net.rs
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

Share

CodeRabbit Verify

  • Run CodeRabbit Verify to test the changes in this pull request.

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.
@dezren39
dezren39 marked this pull request as ready for review November 3, 2026 14:33
@dezren39
dezren39 requested a review from a team as a code owner November 3, 2026 14:33
@dezren39
dezren39 merged commit cc5bee0 into main Nov 3, 2026
2 checks passed
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ⚠️ Failed 2026-11-03T14:33:40.305924Z
We couldn’t complete this review. Comment @codex review to try again.
6855d34 Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@dezren39
dezren39 deleted the queue/5848-2245-operator-block-list branch November 3, 2026 14:33
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant