dedis/popstellar

Validity of PoP Token for Social Media

arnauds5 opened this issue · 0 comments

It's possible that this is not a bug and is a feature ?

Description (Actual behavior)

Old reactions to a chirp are counted in the total even if a new rollcall happened.

Expected behavior

Only display the count of reactions that were sent using a token of the latest rollcall ?

How to reproduce

  1. Participate in rollcall_1 with token_1
  2. Add a chirp with token_1
  3. Upvote the chirp (with token_1)
  4. Participate in rollcall_2 with token_2
  5. Upvote the chirp (with token_2)
  6. The upvotes count will be 2

Version & Environment

This bug was reproduced on:

Front-ends:
  • Fe1-Web (please include browser's names & version)
  • Fe2-Android (please specify if phone or emulation, and Android version)
  • Not applicable
Back-ends:
  • Be1-Go
  • Be2-Scala
  • Not applicable

Impact

One user can accumulate multiple reactions on an old chirp using PoP tokens from consecutive rollcall.

Possible root cause

// all reactions for 'serializedChirpId'
const reactions = byLaoId.reactionsByChirpId[serializedChirpId].map(
(reactionId) => byLaoId.reactionsById[reactionId],
);
// count them by codepoint
return reactions.reduce<Record<string, number>>(
(counts, reaction) => {
if (counts[reaction.codepoint]) {
counts[reaction.codepoint] += 1;
} else {
counts[reaction.codepoint] = 1;
}
return counts;
},
{ '👍': 0, '👎': 0, '❤️': 0 },
);
});
export const makeReactedSelector = (laoId: Hash, chirpId: Hash, user?: PublicKey) =>

// Map the reactions to the chirp into <codepoint, list of senders' pk>
val codepointToSendersMap =
reactions
.stream() // Filter just non deleted reactions
.filter { reaction: Reaction ->
!reaction.isDeleted
} // Then collect by emoji type and count the occurrences
.collect(
Collectors.groupingBy(
Reaction::codepoint,
Collectors.mapping(
{ reaction: Reaction -> reaction.sender.encoded },
Collectors.toSet())))
// Extract the number of reactions by emoji
val upVotes = codepointToSendersMap[ReactionEmoji.UPVOTE.code] ?: HashSet(0)
val downVotes = codepointToSendersMap[ReactionEmoji.DOWNVOTE.code] ?: HashSet(0)
val hearts = codepointToSendersMap[ReactionEmoji.HEART.code] ?: HashSet(0)
upvoteCounter.text = String.format(Locale.US, "%d", upVotes.size)
downvoteCounter.text = String.format(Locale.US, "%d", downVotes.size)
heartCounter.text = String.format(Locale.US, "%d", hearts.size)

Collectors.toSet())))
// Extract the number of reactions by emoji
val upVotes = codepointToSendersMap[ReactionEmoji.UPVOTE.code] ?: HashSet(0)
val downVotes = codepointToSendersMap[ReactionEmoji.DOWNVOTE.code] ?: HashSet(0)
val hearts = codepointToSendersMap[ReactionEmoji.HEART.code] ?: HashSet(0)
upvoteCounter.text = String.format(Locale.US, "%d", upVotes.size)
downvoteCounter.text = String.format(Locale.US, "%d", downVotes.size)
heartCounter.text = String.format(Locale.US, "%d", hearts.size)