feat(quote): downscore peers that supply bad-bound quotes#77
Open
grumbach wants to merge 2 commits intoWithAutonomi:mainfrom
Open
feat(quote): downscore peers that supply bad-bound quotes#77grumbach wants to merge 2 commits intoWithAutonomi:mainfrom
grumbach wants to merge 2 commits intoWithAutonomi:mainfrom
Conversation
When a peer's storage quote ships a `pub_key` that does not BLAKE3-hash
to the peer's claimed `PeerId` ("crossed-key" / bad-binding), report a
strong negative trust event so the local AdaptiveDHT swaps that peer
out of the routing table on the next admission cycle. This stops the
operator-monopolises-close-K failure mode that took uploads below
quorum on 2026-05-06 (see notes/plan-1-bad-node-eviction.md).
Wires the report at both detection sites in
`ant-core/src/data/client/quote.rs`:
- per-peer `classify_quote_response` (primary defence inside the
async closure) — fires for every BadQuoteBinding verdict;
- post-collection `drop_quotes_with_bad_bindings` (defensive filter)
— fires for every peer whose quote slipped past the per-peer
handler. Should be empty in normal operation; non-empty signals
an upstream regression.
Both sites go through a small `TrustReporter` trait so the wiring can
be unit-tested with a mock recorder rather than a live `P2PNode`.
Production paths use the blanket impl on `Arc<P2PNode>` which
forwards to `P2PNode::report_application_failure(peer, 5.0)`.
The `5.0` weight is sized to drop a peer from neutral 0.5 to ~0.26 in
a single event, well below the production swap-out threshold
(`saorsa_core::adaptive::DEFAULT_SWAP_THRESHOLD = 0.35`). saorsa-core
clamps consumer weights at `MAX_CONSUMER_WEIGHT = 5.0` so this is the
strongest legal signal — appropriate for a verifiable cryptographic
mismatch.
Adds 5 new tests:
- classify_quote_response_reports_trust_event_on_bad_binding (B1)
- classify_quote_response_does_not_report_on_good_binding
- classify_quote_response_does_not_report_on_non_binding_failures
- drop_quotes_with_bad_bindings_reports_one_event_per_dropped_peer (B2)
- bad_binding_does_not_affect_trust_for_other_peers (B3)
Existing tests for `drop_quotes_with_bad_bindings` are updated for the
new return type (`Vec<PeerId>` rather than `usize` count) so the
caller can attribute trust events per peer.
Depends on: saorsa-labs/saorsa-core#XXX
(P2PNode::report_application_failure entry point)
ant-node ships the storer-side mirror of this in a separate PR so
this side and that side apply the same penalty for the same evidence
on each end of the wire.
Open
3 tasks
3 tasks
Routes the workspace's saorsa-core dep through the fork branch carrying saorsa-labs/saorsa-core#114, which adds the `P2PNode::report_application_failure` method this PR's quote.rs depends on. CI was failing because that method does not exist on the upstream rc-2026.4.4 branch yet. REMOVE this patch block once #114 merges and the regular saorsa-core git pin in ant-core/Cargo.toml resolves to a commit that includes the new public method.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
pub_keythat does not BLAKE3-hash to the peer's claimedPeerId, report a strong negative trust event so the localAdaptiveDHTswaps that peer out of the routing table on the next admission cycle. This stops the operator-monopolises-close-K failure mode that took uploads below quorum on 2026-05-06.ant-core/src/data/client/quote.rs:classify_quote_response(primary defence inside the async closure) — fires for everyBadQuoteBindingverdict;drop_quotes_with_bad_bindings(defensive filter) — fires for every peer whose quote slipped past the per-peer handler.TrustReportertrait so the wiring can be unit-tested with a mock recorder rather than a liveP2PNode. Production paths use the blanket impl onArc<P2PNode>which forwards toP2PNode::report_application_failure(peer, 5.0).5.0weight is sized to drop a peer from neutral 0.5 to ~0.26 in a single event, well below the production swap-out threshold (saorsa_core::adaptive::DEFAULT_SWAP_THRESHOLD = 0.35). saorsa-core clamps consumer weights atMAX_CONSUMER_WEIGHT = 5.0so this is the strongest legal signal — appropriate for a verifiable cryptographic mismatch.notes/plan-1-bad-node-eviction.mdfor the full design and the production failure that motivates this work.What's new in tests
classify_quote_response_reports_trust_event_on_bad_binding(B1)classify_quote_response_does_not_report_on_good_bindingclassify_quote_response_does_not_report_on_non_binding_failuresdrop_quotes_with_bad_bindings_reports_one_event_per_dropped_peer(B2)bad_binding_does_not_affect_trust_for_other_peers(B3)Existing tests for
drop_quotes_with_bad_bindingsare updated for the new return type (Vec<PeerId>rather thanusizecount) so the caller can attribute trust events per peer.Test plan
cargo test -p ant-core --lib data::client::quote(25/25 pass)cargo clippy -p ant-core --lib -- -D warningscargo fmt --all -- --checkDependencies
P2PNode::report_application_failure. This PR's CI will fail until that lands and thesaorsa-coregit pin is updated.Cross-links
Behaviour-preservation argument