fix(core): verify gossip source matches claimed peer_id in auction bids/receipts - #10
Merged
ralyodio merged 1 commit intoJul 12, 2026
Conversation
JobBid.bidder_peer_id and JobReceipt.worker_peer_id are self-reported strings inside the gossip payload. run_auction() only checked these strings against job_id / the chosen winner — it never checked them against GossipMessage.source, the libp2p-authenticated sender identity that's already available on every message and can't be forged. Since JobAccept (naming the winning bidder) is broadcast publicly on the job topic, any peer can see who won and race to publish a bid or a completion receipt claiming to be that peer_id. A forged receipt that arrives before the real winner's would be accepted as-is (wrong worker credited, or the real worker's later genuine receipt ignored since run_auction() already returned). capabilities.rs's ad registry already keys its ad table by msg.source for exactly this reason — this brings the auction path in line with that same discipline as a stopgap ahead of the DID-signature scheme mentioned in JobReceipt's doc comment. Couldn't run `cargo test -p c0mpute-core` in my environment (no Rust toolchain available) — traced types by hand (GossipMessage.source is already Option<PeerId>, PeerId::to_base58() is already used elsewhere in this same file) but please double check on a real build.
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.
Fixes #9.
run_auction()matched incomingJobBid/JobReceiptgossip messages only on the self-reportedbidder_peer_id/worker_peer_idfield inside the JSON payload, never againstGossipMessage.source— the libp2p-authenticated sender identity that's already attached to every message and can't be forged.capabilities.rs's capability-ad registry already keys offsourcefor exactly this reason; the auction path didn't follow the same pattern.Since
JobAccept(naming the winning bidder) is broadcast publicly, any peer can see who won a job and race to publish a bid or completion receipt claiming to be that peer —run_auction()returns on the first message matching job_id + the claimed string, forged or not.Change
Added
source_matches_claim()and call it before accepting a bid (bid-collection loop) or a receipt (receipt-wait loop). Mismatches are discarded with awarn!log, same style as the existing discard-and-log pattern already used elsewhere in this file and incapabilities.rs.This is independent of and doesn't replace the DID-signature scheme mentioned in
JobReceipt.signature's doc comment (that's presumably still coming from CoinPay) — it's a free, already-available authentication check that should hold regardless.Testing
I don't have a Rust toolchain in my environment to run
cargo test -p c0mpute-coreorcargo check, so I traced the types by hand instead of compiling:GossipMessage.source: Option<PeerId>(c0mpute-net/src/swarm.rs) — already imported via the existinguse c0mpute_net::{GossipMessage, Libp2pNetwork};.PeerId::to_base58()— already used earlier in the same file (net.peer_id().to_base58()), so it's the right method.Please run the test suite before merging since I couldn't verify it compiles locally — happy to fix anything that doesn't build.