Skip to content

UniqueVotesWithSameTarget caller contract: cmpVotes must be seat-index-aware #240

@dnadales

Description

@dnadales

Problem

PR #2020 made UniqueVotesWithSameTarget a properly opaque carrier whose construction checks for duplicates, replacing the silent-dedup hazard at the type level (option (a) of the original forgeCert dedup concern).
The remaining concern is at the caller side: uniqueness is parameterized by the cmpVotes :: Vote crypto committee -> Vote crypto committee -> Ordering function the caller supplies, so the duplicate-rejection guarantee is only as strong as that comparator.

For WFALS and EveryoneVotes the underlying hazard is two votes sharing a SeatIndex but differing in signature / VRF output:

  • WFALS.implForgeCert (WFALS.hs:456) calls NEMap.fromAscList voters while signatures are aggregated separately.
    If two voters entries share a SeatIndex, the cert's seat-index map has fewer entries than the signature aggregate, and downstream verifyCert fails with the opaque "number of keys and signatures do not match" error.
  • EveryoneVotes.implForgeCert (EveryoneVotes.hs:265) has the same shape via NESet.fromList voters.

The Peras integration site that builds UniqueVotesWithSameTarget from inbound votes must therefore choose a cmpVotes that returns EQ for any two votes that would collide at the seat-index level (or, more conservatively, on underlying voter identity).

Proposed fix

  • Locate the call site that builds UniqueVotesWithSameTarget for the Peras voting committee.
  • Confirm cmpVotes orders EQ on shared SeatIndex for both persistent and non-persistent variants of WFALS and EveryoneVotes Vote constructors.
  • Add a property test that generates votes with seeded seat-index collisions and asserts ensureUniqueVotesWithSameTarget returns Left (DuplicateVotes …) for them.

References

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions