Skip to content

Commit

Permalink
Find bug (2).
Browse files Browse the repository at this point in the history
Catch exception in EncryptedBallotDeviceIterator and print it out.
Note its using EncryptedBallotDeviceIterator, not EncryptedBallotFileIterator.
try adding READ option.
  • Loading branch information
JohnLCaron committed Oct 26, 2023
1 parent 68ddca7 commit 58f2664
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ class VerifyEncryptedBallots(
val results = mutableListOf<Result<Boolean, String>>()

if (ballot.electionId != extendedBaseHash) {
return Err("Encrypted Ballot has wrong electionId = ${ballot.electionId}; skipping")
return Err("Encrypted Ballot ${ballot.ballotId} has wrong electionId = ${ballot.electionId}; skipping")
}

var ncontests = 0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,39 @@ import electionguard.core.productionGroup
import kotlin.test.Test

class VerifierTest {
/*
for some reason we get exception on github, even though file exists.
2023-10-26T01:07:02.7889741Z java.nio.file.NoSuchFileException: src/commonTest/data/testElectionRecord/remoteWorkflow/electionRecord/encrypted_ballots/testDevice/eballot-id-1181991362.json
2023-10-26T01:07:02.7891376Z at java.base/sun.nio.fs.UnixException.translateToIOException(UnixException.java:92)
2023-10-26T01:07:02.7892486Z at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:106)
2023-10-26T01:07:02.7894159Z at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:111)
2023-10-26T01:07:02.7895286Z at java.base/sun.nio.fs.UnixFileSystemProvider.newByteChannel(UnixFileSystemProvider.java:218)
2023-10-26T01:07:02.7896252Z at java.base/java.nio.file.Files.newByteChannel(Files.java:380)
2023-10-26T01:07:02.7897291Z at java.base/java.nio.file.Files.newByteChannel(Files.java:432)
2023-10-26T01:07:02.7898276Z at java.base/java.nio.file.spi.FileSystemProvider.newInputStream(FileSystemProvider.java:422)
2023-10-26T01:07:02.7899372Z at electionguard.publish.ConsumerJson.readEncryptedBallot(ConsumerJson.kt:165)
2023-10-26T01:07:02.7900522Z at electionguard.publish.ConsumerJson$EncryptedBallotDeviceIterator.computeNext(ConsumerJson.kt:152)
2023-10-26T01:07:02.7901649Z at kotlin.collections.AbstractIterator.tryToComputeNext(AbstractIterator.kt:42)
2023-10-26T01:07:02.7902584Z at kotlin.collections.AbstractIterator.hasNext(AbstractIterator.kt:29)
2023-10-26T01:07:02.7903538Z at electionguard.publish.ConsumerJson$DeviceIterator.computeNext(ConsumerJson.kt:184)
2023-10-26T01:07:02.7904563Z at kotlin.collections.AbstractIterator.tryToComputeNext(AbstractIterator.kt:42)
2023-10-26T01:07:02.7905495Z at kotlin.collections.AbstractIterator.hasNext(AbstractIterator.kt:29)
2023-10-26T01:07:02.7906595Z at electionguard.verifier.VerifyEncryptedBallots$produceBallots$1.invokeSuspend(VerifyEncryptedBallots.kt:219)
2023-10-26T01:07:02.7907836Z at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
2023-10-26T01:07:02.7908802Z at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
2023-10-26T01:07:02.7909836Z at kotlinx.coroutines.EventLoopImplBase.processNextEvent(EventLoop.common.kt:280)
2023-10-26T01:07:02.7910779Z at kotlinx.coroutines.BlockingCoroutine.joinBlocking(Builders.kt:85)
2023-10-26T01:07:02.7911629Z at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking(Builders.kt:59)
2023-10-26T01:07:02.7912419Z at kotlinx.coroutines.BuildersKt.runBlocking(Unknown Source)
2023-10-26T01:07:02.7913245Z at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking$default(Builders.kt:38)
2023-10-26T01:07:02.7914124Z at kotlinx.coroutines.BuildersKt.runBlocking$default(Unknown Source)
2023-10-26T01:07:02.7915139Z at electionguard.verifier.VerifyEncryptedBallots.verifyBallots(VerifyEncryptedBallots.kt:47)
2023-10-26T01:07:02.7916079Z at electionguard.verifier.Verifier.verify(Verifier.kt:60)
2023-10-26T01:07:02.7916864Z at electionguard.cli.RunVerifier$Companion.runVerifier(RunVerifier.kt:52)
2023-10-26T01:07:02.7917781Z at electionguard.cli.RunVerifier$Companion.runVerifier$default(RunVerifier.kt:46)
2023-10-26T01:07:02.7918783Z at electionguard.verifier.VerifierTest.verifyRemoteWorkflow(VerifierTest.kt:17)
*/

@Test
fun verifyRemoteWorkflow() {
Expand Down
2 changes: 1 addition & 1 deletion egklib/src/jvmMain/kotlin/electionguard/cli/RunVerifier.kt
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ class RunVerifier {
}

val tookAll = (getSystemTimeInMillis() - starting)
println("RunVerifier = $allOk took $tookAll msecs alloK = ${allOk}")
println("RunVerifier took $tookAll msecs OK = ${allOk}")
return allOk
}

Expand Down
44 changes: 23 additions & 21 deletions egklib/src/jvmMain/kotlin/electionguard/publish/ConsumerJson.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,7 @@ import kotlinx.serialization.json.Json
import kotlinx.serialization.json.decodeFromStream
import io.github.oshai.kotlinlogging.KotlinLogging
import java.io.ByteArrayInputStream
import java.nio.file.FileSystem
import java.nio.file.FileSystems
import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.*
import java.nio.file.spi.FileSystemProvider
import java.util.function.Predicate
import java.util.stream.Stream
Expand Down Expand Up @@ -72,7 +69,7 @@ actual class ConsumerJson actual constructor(val topDir: String, val group: Grou
// need to use fileSystemProvider for zipped files
val manifestPath = fileSystem.getPath(filename)
val manifestBytes =
fileSystemProvider.newInputStream(manifestPath).use { inp ->
fileSystemProvider.newInputStream(manifestPath, StandardOpenOption.READ).use { inp ->
inp.readAllBytes()
}
return manifestBytes
Expand Down Expand Up @@ -115,7 +112,7 @@ actual class ConsumerJson actual constructor(val topDir: String, val group: Grou
}
return try {
var chain: EncryptedBallotChain
fileSystemProvider.newInputStream(ballotChainPath).use { inp ->
fileSystemProvider.newInputStream(ballotChainPath, StandardOpenOption.READ).use { inp ->
val json = Json.decodeFromStream<EncryptedBallotChainJson>(inp)
chain = json.import()
}
Expand Down Expand Up @@ -149,10 +146,15 @@ actual class ConsumerJson actual constructor(val topDir: String, val group: Grou
while (true) {
if (ballotIds.hasNext()) {
val ballotFilePath = Path.of(jsonPaths.encryptedBallotDevicePath(device, ballotIds.next()))
val encryptedBallot = readEncryptedBallot(ballotFilePath)
if (filter == null || filter.test(encryptedBallot)) {
setNext(encryptedBallot)
return
try {
val encryptedBallot = readEncryptedBallot(ballotFilePath)
if (filter == null || filter.test(encryptedBallot)) {
setNext(encryptedBallot)
return
}
} catch (t : Throwable) {
println("Error reading EncryptedBallot '${ballotFilePath}', skipping.\n ${t.message}")
logger.error { "Error reading EncryptedBallot '${ballotFilePath}', skipping.\n ${t.message}"}
}
} else {
return done()
Expand All @@ -162,7 +164,7 @@ actual class ConsumerJson actual constructor(val topDir: String, val group: Grou
}

fun readEncryptedBallot(ballotFilePath : Path): EncryptedBallot{
fileSystemProvider.newInputStream(ballotFilePath).use { inp ->
fileSystemProvider.newInputStream(ballotFilePath, StandardOpenOption.READ).use { inp ->
val json = Json.decodeFromStream<EncryptedBallotJson>(inp)
return json.import(group)
}
Expand Down Expand Up @@ -269,7 +271,7 @@ actual class ConsumerJson actual constructor(val topDir: String, val group: Grou
override fun computeNext() {
while (idx < pathList.size) {
val file = pathList[idx++]
fileSystemProvider.newInputStream(file).use { inp ->
fileSystemProvider.newInputStream(file, StandardOpenOption.READ).use { inp ->
val json = jsonIgnoreNulls.decodeFromStream<BallotPepJson>(inp)
val pepBallot = json.import(group)
return setNext(pepBallot)
Expand Down Expand Up @@ -299,7 +301,7 @@ actual class ConsumerJson actual constructor(val topDir: String, val group: Grou
}

val constants = try {
fileSystemProvider.newInputStream(constantsPath).use { inp ->
fileSystemProvider.newInputStream(constantsPath, StandardOpenOption.READ).use { inp ->
val json = Json.decodeFromStream<ElectionConstantsJson>(inp)
json.import()
}
Expand All @@ -315,7 +317,7 @@ actual class ConsumerJson actual constructor(val topDir: String, val group: Grou

return try {
var electionConfig: ElectionConfig
fileSystemProvider.newInputStream(configFile).use { inp ->
fileSystemProvider.newInputStream(configFile, StandardOpenOption.READ).use { inp ->
val json = Json.decodeFromStream<ElectionConfigJson>(inp)
electionConfig = json.import(constants, manifestBytes)
}
Expand All @@ -334,7 +336,7 @@ actual class ConsumerJson actual constructor(val topDir: String, val group: Grou
}
return try {
var electionInitialized: ElectionInitialized
fileSystemProvider.newInputStream(initPath).use { inp ->
fileSystemProvider.newInputStream(initPath, StandardOpenOption.READ).use { inp ->
val json = Json.decodeFromStream<ElectionInitializedJson>(inp)
electionInitialized = json.import(group, config)
}
Expand All @@ -349,7 +351,7 @@ actual class ConsumerJson actual constructor(val topDir: String, val group: Grou
return Err("EncryptedTally '$tallyPath' file does not exist ")
}
return try {
fileSystemProvider.newInputStream(tallyPath).use { inp ->
fileSystemProvider.newInputStream(tallyPath, StandardOpenOption.READ).use { inp ->
val json = Json.decodeFromStream<EncryptedTallyJson>(inp)
val encryptedTally = json.import(group)
Ok(TallyResult(init, encryptedTally, emptyList()))
Expand All @@ -367,7 +369,7 @@ actual class ConsumerJson actual constructor(val topDir: String, val group: Grou
return Err("DecryptedTally '$decryptedTallyPath' file does not exist ")
}
return try {
fileSystemProvider.newInputStream(decryptedTallyPath).use { inp ->
fileSystemProvider.newInputStream(decryptedTallyPath, StandardOpenOption.READ).use { inp ->
val json = Json.decodeFromStream<DecryptedTallyOrBallotJson>(inp)
val decryptedTallyOrBallot = json.import(group)
Ok(DecryptionResult(tallyResult, decryptedTallyOrBallot))
Expand All @@ -387,7 +389,7 @@ actual class ConsumerJson actual constructor(val topDir: String, val group: Grou
override fun computeNext() {
while (idx < pathList.size) {
val file = pathList[idx++]
fileSystemProvider.newInputStream(file).use { inp ->
fileSystemProvider.newInputStream(file, StandardOpenOption.READ).use { inp ->
val json = jsonIgnoreNulls.decodeFromStream<PlaintextBallotJson>(inp)
val plaintextBallot = json.import()
if (filter == null || filter.test(plaintextBallot)) {
Expand All @@ -411,7 +413,7 @@ actual class ConsumerJson actual constructor(val topDir: String, val group: Grou
override fun computeNext() {
while (idx < pathList.size) {
val file = pathList[idx++]
fileSystemProvider.newInputStream(file).use { inp ->
fileSystemProvider.newInputStream(file, StandardOpenOption.READ).use { inp ->
val json = Json.decodeFromStream<EncryptedBallotJson>(inp)
val encryptedBallot = json.import(group)
if (filter == null || filter.test(encryptedBallot)) {
Expand All @@ -434,7 +436,7 @@ actual class ConsumerJson actual constructor(val topDir: String, val group: Grou
override fun computeNext() {
while (idx < pathList.size) {
val file = pathList[idx++]
fileSystemProvider.newInputStream(file).use { inp ->
fileSystemProvider.newInputStream(file, StandardOpenOption.READ).use { inp ->
val json = Json.decodeFromStream<DecryptedTallyOrBallotJson>(inp)
val decryptedTallyOrBallot = json.import(group)
setNext(decryptedTallyOrBallot)
Expand All @@ -450,7 +452,7 @@ actual class ConsumerJson actual constructor(val topDir: String, val group: Grou
return Err("readTrustee '$filePath' file does not exist")
}
return try {
fileSystemProvider.newInputStream(filePath).use { inp ->
fileSystemProvider.newInputStream(filePath, StandardOpenOption.READ).use { inp ->
val json = Json.decodeFromStream<TrusteeJson>(inp)
val decryptingTrustee = json.importDecryptingTrustee(group)
Ok(decryptingTrustee)
Expand Down

0 comments on commit 58f2664

Please sign in to comment.