Skip to content

Resumable, crash-safe anonymous vote reveal/decrypt flow #33

Description

@Ehonrie

Difficulty: Research-Required
Category: Edge Case

Context: If a user reveals votes on a large proposal and closes the tab mid-decrypt (or uploads a partially-wrong key and only realizes after minutes of decrypting), all progress is lost — computeAnonymousVotingData has no checkpointing, and the UI flow (VerifyAnonymousVotesModal.tsx) has to restart the entire decrypt-and-tally pass from zero.

// dapp/src/utils/anonymousVoting.ts
export interface RevealProgress {
  proposalId: number;
  decodedSoFar: DecodedVote[];
  remainingVoterIndices: number[];
  partialTallies: bigint[];
  partialSeeds: bigint[];
}

export async function resumeAnonymousTally(
  saved: RevealProgress,
  privateKey: string,
): Promise<AnonymousVotingData> {
  // !todo: Design a checkpointable version of computeAnonymousVotingData that can
  //        persist RevealProgress (e.g. to IndexedDB/sessionStorage) after each voter
  //        and resume from there rather than restarting.
  // !todo: Must detect and reject resuming with a DIFFERENT private key than the one
  //        that produced the saved partial progress (would silently corrupt tallies).
  // !todo: Must handle the on-chain proposal/vote data changing between the interrupted
  //        session and resume (e.g. proposal state advanced) — invalidate stale progress.
  // !todo: Research: appropriate browser storage for potentially-sensitive partial
  //        decrypted vote data (session-only vs. persistent, encryption-at-rest tradeoffs).
  throw new Error("Not implemented");
}

What contributors need to know:

  • Problem: computeAnonymousVotingData (anonymousVoting.ts:83-287) is all-or-nothing with no persisted intermediate state.
  • Related code: VerifyAnonymousVotesModal.tsx, ExportDecodedVotesModal.tsx.
  • Suggested approach: research safe client-side storage for partially-decrypted, privacy-sensitive vote data before implementing persistence; a memory-only "resume within the same session/tab" version may be a safer first milestone than cross-session persistence.
  • Acceptance criteria: interrupting a large-proposal reveal (simulated) and resuming produces identical final tallies to a non-interrupted run; wrong-key resume is rejected with a clear error, not silent corruption.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    edge-caseError recovery, concurrency, race conditionsresearch-requiredDifficulty: Research-Required

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions