-
Notifications
You must be signed in to change notification settings - Fork 8
Description
When a contest has a discrepancy, and requires a second round of auditing, and the random selection has multiple duplicates, it is possible for the system to enter an infinite loop during the audit.
This would happen at the end of the second round, because the system thinks, incorrectly, that there is still more auditing to do. It causes the web interface to be unresponsive, and freeze, while the county is waiting for an (unnecessary) third round to launch. The loop would be in ComparisonAuditController.java at while (sorted_deduplicated_new_cvrs.isEmpty()) {
Lines 541 to 564 in 430c0d7
| while (sorted_deduplicated_new_cvrs.isEmpty()) { | |
| expected_prefix_length = computeEstimatedSamplesToAudit(the_cdb); | |
| if (the_cdb.auditedPrefixLength() < expected_prefix_length) { | |
| final List<CastVoteRecord> extra_cvrs = | |
| getCVRsInAuditSequence(the_cdb.county(), start_index, | |
| expected_prefix_length - 1); | |
| new_cvrs.addAll(extra_cvrs); | |
| Persistence.saveOrUpdate(the_cdb); | |
| sorted_deduplicated_new_cvrs.addAll(new_cvrs); | |
| final Set<Long> unique_new_cvr_ids = new HashSet<>(); | |
| for (final CastVoteRecord cvr : sorted_deduplicated_new_cvrs) { | |
| unique_new_cvr_ids.add(cvr.id()); | |
| } | |
| for (final Round round : the_cdb.rounds()) { | |
| for (final Long cvr_id : round.ballotSequence()) { | |
| if (unique_new_cvr_ids.contains(cvr_id)) { | |
| unique_new_cvr_ids.remove(cvr_id); | |
| sorted_deduplicated_new_cvrs.remove(Persistence.getByID(cvr_id, | |
| CastVoteRecord.class)); | |
| } | |
| } | |
| } | |
| } |
The fix is to delete the line
cvrai.setCounted(cvrai.counted() + multiplicity);
in ComparisonAuditController.java as shown in democracyworks@ec87ea6
See a more detailed explanation, and the fix in context, in the DemocracyWorks fork: democracyworks#17