fix(concord): an already-expired v2 message is refused at ingest - #94
Merged
JSKitty merged 1 commit intoOct 2, 2026
Merged
Conversation
CORD-08 §3 says a reader must refuse an already-expired rumor at ingest and never store it. The DM path already drops it in rumor.rs. The v2 Message arm now uses the same already_expired check. The wrap's expiration tag is for relays only; readers judge by the rumor's copy (CORD-08 §2). A wrap re-published without the outer tag still reaches apply_chat_to_state. Closes VectorPrivacy#93
JSKitty
approved these changes
Oct 2, 2026
JSKitty
left a comment
There was a problem hiding this comment.
Appreciate the PR! This was a great catch, I'll additionally cover events such as Edits/Reactions/etc in a follow up commit, you will be included in the Release Notes for our next v0.5.0 release. 🙏 💚
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.
An already-expired message in a Concord v2 channel is no longer saved or passed to
on_community_message. Closes #93.Change
apply_chat_to_state, Message arm: returnNonewhen the rumor's NIP-40expirationis already in the past. CORD-08 §3: "MUST refuse an already-expired rumor at ingest — never store it".rumor::already_expiredis nowpub(crate), so v2 uses the same check as the DM path.Test
an_already_expired_message_is_refused_at_ingestincommunity/v2/inbound.rs:expirationtag (what a member who re-wraps the seal can send).persist_chat_eventreturnsNone. The event is not in the DB and not in STATE.New.Without the fix, the test fails on the
Nonecheck.Verified at
9525cf5a8ae6+ this commit, on Windows:cd crates && cargo test -p vector-core: 1999 passed, 0 failed, plus the integration and doc tests.cargo test -p vector-core --lib -- --ignored guarded_key: 7 passed, 0 failed.Not covered
self_destruct::start_sweeperhas no caller). That is a separate change.Own sends
publish_chatwrites the local echo through the same function. If the expiry passes during the publish, a headless sender (SDK) does not store its own copy. The app keeps its copy, becauseTauriSendCallback::on_persistsaves the sent row.Base branch
widescreen, where current work lands. The Message arm is the same onmaster.