mirror of
https://github.com/jcreek/CosmicClash.git
synced 2026-09-11 00:14:00 +00:00
6d3490da14
ProposalParticipantExpireSQL marked every PENDING participant on a proposal TIMED_OUT unconditionally -- it took a proposal_id and 'now' but never actually compared 'now' against the proposal's expires_at, unlike its sibling ProposalExpireSQL (which does gate on 'expires_at <= $2'). Both GetProposal and RespondToProposal run this statement on every call as a recovery step, so the very first RespondToProposal for any proposal timed out every participant (including the one about to respond) before checking their response, then rejected the real accept/decline with ErrConflict. Add the same expiry gate via an EXISTS against proposals.expires_at, matching ProposalExpireSQL's own condition, and update the SQL-fragment test to assert the gate is present. Verified end to end against a real PostgreSQL instance: TestPostgreSQLProposalClaimAndResponseAreAtomic now passes a two-participant accept/accept sequence that previously failed on the first response.