diff --git a/codex/slots/proofs/backendfactory.nim b/codex/slots/proofs/backendfactory.nim deleted file mode 100644 index 7aba27d8..00000000 --- a/codex/slots/proofs/backendfactory.nim +++ /dev/null @@ -1,82 +0,0 @@ -import os -import strutils -import pkg/chronos -import pkg/chronicles -import pkg/questionable -import pkg/confutils/defs -import pkg/stew/io2 -import pkg/ethers - -import ../../conf -import ./backends -import ./backendutils - -proc initializeFromConfig(config: CodexConf, utils: BackendUtils): ?!AnyBackend = - if not fileAccessible($config.circomR1cs, {AccessFlags.Read}) or - not endsWith($config.circomR1cs, ".r1cs"): - return failure("Circom R1CS file not accessible") - - if not fileAccessible($config.circomWasm, {AccessFlags.Read}) or - not endsWith($config.circomWasm, ".wasm"): - return failure("Circom wasm file not accessible") - - if not fileAccessible($config.circomZkey, {AccessFlags.Read}) or - not endsWith($config.circomZkey, ".zkey"): - return failure("Circom zkey file not accessible") - - trace "Initialized prover backend from cli config" - success( - utils.initializeCircomBackend( - $config.circomR1cs, $config.circomWasm, $config.circomZkey - ) - ) - -proc r1csFilePath(config: CodexConf): string = - config.circuitDir / "proof_main.r1cs" - -proc wasmFilePath(config: CodexConf): string = - config.circuitDir / "proof_main.wasm" - -proc zkeyFilePath(config: CodexConf): string = - config.circuitDir / "proof_main.zkey" - -proc initializeFromCircuitDirFiles( - config: CodexConf, utils: BackendUtils -): ?!AnyBackend {.gcsafe.} = - if fileExists(config.r1csFilePath) and fileExists(config.wasmFilePath) and - fileExists(config.zkeyFilePath): - trace "Initialized prover backend from local files" - return success( - utils.initializeCircomBackend( - config.r1csFilePath, config.wasmFilePath, config.zkeyFilePath - ) - ) - - failure("Circuit files not found") - -proc suggestDownloadTool(config: CodexConf) = - without address =? config.marketplaceAddress: - raise (ref Defect)( - msg: "Proving backend initializing while marketplace address not set." - ) - - let - tokens = ["cirdl", "\"" & $config.circuitDir & "\"", config.ethProvider, $address] - instructions = "'./" & tokens.join(" ") & "'" - - warn "Proving circuit files are not found. Please run the following to download them:", - instructions - -proc initializeBackend*( - config: CodexConf, utils: BackendUtils = BackendUtils() -): ?!AnyBackend = - without backend =? initializeFromConfig(config, utils), cliErr: - info "Could not initialize prover backend from CLI options...", msg = cliErr.msg - without backend =? initializeFromCircuitDirFiles(config, utils), localErr: - info "Could not initialize prover backend from circuit dir files...", - msg = localErr.msg - suggestDownloadTool(config) - return failure("CircuitFilesNotFound") - # Unexpected: value of backend does not survive leaving each scope. (definition does though...) - return success(backend) - return success(backend) diff --git a/codex/slots/proofs/backends.nim b/codex/slots/proofs/backends.nim index 3bd2edb6..b0b79b37 100644 --- a/codex/slots/proofs/backends.nim +++ b/codex/slots/proofs/backends.nim @@ -1,5 +1,4 @@ import ./backends/circomcompat +import ./backends/nimgroth16 -export circomcompat - -type AnyBackend* = CircomCompat +export circomcompat, nimgroth16 diff --git a/codex/slots/proofs/backendutils.nim b/codex/slots/proofs/backendutils.nim deleted file mode 100644 index 0e334ace..00000000 --- a/codex/slots/proofs/backendutils.nim +++ /dev/null @@ -1,8 +0,0 @@ -import ./backends - -type BackendUtils* = ref object of RootObj - -method initializeCircomBackend*( - self: BackendUtils, r1csFile: string, wasmFile: string, zKeyFile: string -): AnyBackend {.base, gcsafe.} = - CircomCompat.init(r1csFile, wasmFile, zKeyFile) diff --git a/codex/slots/proofs/prover.nim b/codex/slots/proofs/prover.nim index 1afcd068..861ad627 100644 --- a/codex/slots/proofs/prover.nim +++ b/codex/slots/proofs/prover.nim @@ -12,6 +12,7 @@ import pkg/chronos import pkg/chronicles import pkg/circomcompat import pkg/poseidon2 +import pkg/taskpools import pkg/questionable/results import pkg/libp2p/cid @@ -35,22 +36,24 @@ logScope: topics = "codex prover" type - AnyProof* = CircomProof - - AnySampler* = Poseidon2Sampler - # add any other generic type here, eg. Poseidon2Sampler | ReinforceConcreteSampler - AnyBuilder* = Poseidon2Builder - # add any other generic type here, eg. Poseidon2Builder | ReinforceConcreteBuilder - - AnyProofInputs* = ProofInputs[Poseidon2Hash] - Prover* = ref object of RootObj - backend: AnyBackend - store: BlockStore + Prover* = ref object + case backendKind: ProverBackendCmd + of ProverBackendCmd.nimGroth16: + groth16Backend*: NimGroth16BackendRef + of ProverBackendCmd.circomCompat: + circomCompatBackend*: CircomCompatBackendRef nSamples: int + tp: Taskpool -proc prove*( - self: Prover, slotIdx: int, manifest: Manifest, challenge: ProofChallenge -): Future[?!(AnyProofInputs, AnyProof)] {.async: (raises: [CancelledError]).} = + AnyBackend* = NimGroth16BackendRef or CircomCompatBackendRef + +proc prove*[SomeSampler]( + self: Prover, + sampler: SomeSampler, + manifest: Manifest, + challenge: ProofChallenge, + verify = false, +): Future[?!(Groth16Proof, ?bool)] {.async: (raises: [CancelledError]).} = ## Prove a statement using backend. ## Returns a future that resolves to a proof. @@ -61,33 +64,46 @@ proc prove*( trace "Received proof challenge" - without builder =? AnyBuilder.new(self.store, manifest), err: - error "Unable to create slots builder", err = err.msg - return failure(err) + let + proofInput = ?await sampler.getProofInput(challenge, self.nSamples) + # prove slot - without sampler =? AnySampler.new(slotIdx, self.store, builder), err: - error "Unable to create data sampler", err = err.msg - return failure(err) - - without proofInput =? await sampler.getProofInput(challenge, self.nSamples), err: - error "Unable to get proof input for slot", err = err.msg - return failure(err) - - # prove slot - without proof =? self.backend.prove(proofInput), err: - error "Unable to prove slot", err = err.msg - return failure(err) - - success (proofInput, proof) - -proc verify*( - self: Prover, proof: AnyProof, inputs: AnyProofInputs -): Future[?!bool] {.async: (raises: [CancelledError]).} = - ## Prove a statement using backend. - ## Returns a future that resolves to a proof. - self.backend.verify(proof, inputs) + case self.backendKind + of ProverBackendCmd.nimGroth16: + let + proof = ?await self.groth16Backend.prove(proofInput) + verified = + if verify: + (?await self.groth16Backend.verify(proof)).some + else: + bool.none + return success (proof.toGroth16Proof, verified) + of ProverBackendCmd.circomCompat: + let + proof = ?await self.circomCompatBackend.prove(proofInput) + verified = + if verify: + (?await self.circomCompatBackend.verify(proof, proofInput)).some + else: + bool.none + return success (proof.toGroth16Proof, verified) proc new*( - _: type Prover, store: BlockStore, backend: AnyBackend, nSamples: int + _: type Prover, backend: CircomCompatBackendRef, nSamples: int, tp: Taskpool ): Prover = - Prover(store: store, backend: backend, nSamples: nSamples) + Prover( + circomCompatBackend: backend, + backendKind: ProverBackendCmd.circomCompat, + nSamples: nSamples, + tp: tp, + ) + +proc new*( + _: type Prover, backend: NimGroth16BackendRef, nSamples: int, tp: Taskpool +): Prover = + Prover( + groth16Backend: backend, + backendKind: ProverBackendCmd.nimGroth16, + nSamples: nSamples, + tp: tp, + ) diff --git a/codex/slots/proofs/proverfactory.nim b/codex/slots/proofs/proverfactory.nim new file mode 100644 index 00000000..6f2795d7 --- /dev/null +++ b/codex/slots/proofs/proverfactory.nim @@ -0,0 +1,138 @@ +{.push raises: [].} + +import os +import strutils +import pkg/chronos +import pkg/chronicles +import pkg/questionable +import pkg/confutils/defs +import pkg/stew/io2 +import pkg/ethers +import pkg/taskpools + +import ../../conf +import ./backends +import ./prover + +template graphFilePath(config: CodexConf): string = + config.circuitDir / "proof_main.bin" + +template r1csFilePath(config: CodexConf): string = + config.circuitDir / "proof_main.r1cs" + +template wasmFilePath(config: CodexConf): string = + config.circuitDir / "proof_main.wasm" + +template zkeyFilePath(config: CodexConf): string = + config.circuitDir / "proof_main.zkey" + +proc getGraphFile*(config: CodexConf): ?!string = + if fileAccessible($config.circomGraph, {AccessFlags.Read}) and + endsWith($config.circomGraph, ".bin"): + success $config.circomGraph + elif fileAccessible(config.graphFilePath, {AccessFlags.Read}) and + endsWith(config.graphFilePath, ".bin"): + success config.graphFilePath + else: + failure("Graph file not accessible or not found") + +proc getR1csFile*(config: CodexConf): ?!string = + if fileAccessible($config.circomR1cs, {AccessFlags.Read}) and + endsWith($config.circomR1cs, ".r1cs"): + success $config.circomR1cs + elif fileAccessible(config.r1csFilePath, {AccessFlags.Read}) and + endsWith(config.r1csFilePath, ".r1cs"): + success config.r1csFilePath + else: + failure("R1CS file not accessible or not found") + +proc getWasmFile*(config: CodexConf): ?!string = + if fileAccessible($config.circomWasm, {AccessFlags.Read}) and + endsWith($config.circomWasm, ".wasm"): + success $config.circomWasm + elif fileAccessible(config.wasmFilePath, {AccessFlags.Read}) and + endsWith(config.wasmFilePath, ".wasm"): + success config.wasmFilePath + else: + failure("WASM file not accessible or not found") + +proc getZkeyFile*(config: CodexConf): ?!string = + if fileAccessible($config.circomZkey, {AccessFlags.Read}) and + endsWith($config.circomZkey, ".zkey"): + success $config.circomZkey + elif fileAccessible(config.zkeyFilePath, {AccessFlags.Read}) and + endsWith(config.zkeyFilePath, ".zkey"): + success config.zkeyFilePath + else: + failure("ZKey file not accessible or not found") + +proc suggestDownloadTool(config: CodexConf) = + without address =? config.marketplaceAddress: + raise (ref Defect)( + msg: "Proving backend initializing while marketplace address not set." + ) + + let + tokens = ["cirdl", "\"" & $config.circuitDir & "\"", config.ethProvider, $address] + instructions = "'./" & tokens.join(" ") & "'" + + warn "Proving circuit files are not found. Please run the following to download them:", + instructions + +proc initializeNimGroth16Backend( + config: CodexConf, tp: Taskpool +): ?!NimGroth16BackendRef = + let + graphFile = ?getGraphFile(config) + r1csFile = ?getR1csFile(config) + zkeyFile = ?getZkeyFile(config) + + return NimGroth16BackendRef.new( + $graphFile, + $r1csFile, + $zkeyFile, + config.nimGroth16Curve, + config.maxSlotDepth, + config.maxDatasetDepth, + config.maxBlockDepth, + config.maxCellElms, + config.numProofSamples, + tp, + ) + +proc initializeCircomCompatBackend( + config: CodexConf, tp: Taskpool +): ?!CircomCompatBackendRef = + let + r1csFile = ?getR1csFile(config) + wasmFile = ?getWasmFile(config) + zkeyFile = ?getZkeyFile(config) + + return CircomCompatBackendRef.new( + $r1csFile, + $wasmFile, + $zkeyFile, + config.maxSlotDepth, + config.maxDatasetDepth, + config.maxBlockDepth, + config.maxCellElms, + config.numProofSamples, + ) + +proc initializeProver*(config: CodexConf, tp: Taskpool): ?!Prover = + let prover = + case config.proverBackendCmd + of ProverBackendCmd.nimGroth16: + without backend =? initializeNimGroth16Backend(config, tp), err: + suggestDownloadTool(config) + return failure("Unable to initialize NimGroth16 backend") + + Prover.new(backend, config.numProofSamples, tp) + of ProverBackendCmd.circomCompat: + without backend =? initializeCircomCompatBackend(config, tp), err: + suggestDownloadTool(config) + return failure("Unable to initialize CircomCompat backend") + + Prover.new(backend, config.numProofSamples, tp) + + success prover diff --git a/tests/codex/slots/helpers.nim b/tests/codex/slots/helpers.nim index fced1f1c..9394fd7c 100644 --- a/tests/codex/slots/helpers.nim +++ b/tests/codex/slots/helpers.nim @@ -6,6 +6,7 @@ import pkg/libp2p/cid import pkg/codex/codextypes import pkg/codex/stores import pkg/codex/merkletree +import pkg/codex/utils/poseidon2digest import pkg/codex/manifest import pkg/codex/blocktype as bt import pkg/codex/chunker diff --git a/tests/codex/slots/testbackendfactory.nim b/tests/codex/slots/testbackendfactory.nim deleted file mode 100644 index a24bc41a..00000000 --- a/tests/codex/slots/testbackendfactory.nim +++ /dev/null @@ -1,97 +0,0 @@ -import os -import ../../asynctest - -import pkg/chronos -import pkg/confutils/defs -import pkg/codex/conf -import pkg/codex/slots/proofs/backends -import pkg/codex/slots/proofs/backendfactory -import pkg/codex/slots/proofs/backendutils -import pkg/codex/utils/natutils - -import ../helpers -import ../examples - -type BackendUtilsMock = ref object of BackendUtils - argR1csFile: string - argWasmFile: string - argZKeyFile: string - -method initializeCircomBackend*( - self: BackendUtilsMock, r1csFile: string, wasmFile: string, zKeyFile: string -): AnyBackend = - self.argR1csFile = r1csFile - self.argWasmFile = wasmFile - self.argZKeyFile = zKeyFile - # We return a backend with *something* that's not nil that we can check for. - var - key = VerifyingKey(icLen: 123) - vkpPtr: ptr VerifyingKey = key.addr - return CircomCompat(vkp: vkpPtr) - -suite "Test BackendFactory": - let - utilsMock = BackendUtilsMock() - circuitDir = "testecircuitdir" - - setup: - createDir(circuitDir) - - teardown: - removeDir(circuitDir) - - test "Should create backend from cli config": - let - config = CodexConf( - cmd: StartUpCmd.persistence, - nat: NatConfig(hasExtIp: false, nat: NatNone), - metricsAddress: parseIpAddress("127.0.0.1"), - persistenceCmd: PersistenceCmd.prover, - marketplaceAddress: EthAddress.example.some, - circomR1cs: InputFile("tests/circuits/fixtures/proof_main.r1cs"), - circomWasm: InputFile("tests/circuits/fixtures/proof_main.wasm"), - circomZkey: InputFile("tests/circuits/fixtures/proof_main.zkey"), - ) - backend = config.initializeBackend(utilsMock).tryGet - - check: - backend.vkp != nil - utilsMock.argR1csFile == $config.circomR1cs - utilsMock.argWasmFile == $config.circomWasm - utilsMock.argZKeyFile == $config.circomZkey - - test "Should create backend from local files": - let - config = CodexConf( - cmd: StartUpCmd.persistence, - nat: NatConfig(hasExtIp: false, nat: NatNone), - metricsAddress: parseIpAddress("127.0.0.1"), - persistenceCmd: PersistenceCmd.prover, - marketplaceAddress: EthAddress.example.some, - - # Set the circuitDir such that the tests/circuits/fixtures/ files - # will be picked up as local files: - circuitDir: OutDir("tests/circuits/fixtures"), - ) - backend = config.initializeBackend(utilsMock).tryGet - - check: - backend.vkp != nil - utilsMock.argR1csFile == config.circuitDir / "proof_main.r1cs" - utilsMock.argWasmFile == config.circuitDir / "proof_main.wasm" - utilsMock.argZKeyFile == config.circuitDir / "proof_main.zkey" - - test "Should suggest usage of downloader tool when files not available": - let - config = CodexConf( - cmd: StartUpCmd.persistence, - nat: NatConfig(hasExtIp: false, nat: NatNone), - metricsAddress: parseIpAddress("127.0.0.1"), - persistenceCmd: PersistenceCmd.prover, - marketplaceAddress: EthAddress.example.some, - circuitDir: OutDir(circuitDir), - ) - backendResult = config.initializeBackend(utilsMock) - - check: - backendResult.isErr diff --git a/tests/codex/slots/testbackends.nim b/tests/codex/slots/testbackends.nim index b9994fcd..f8f1b450 100644 --- a/tests/codex/slots/testbackends.nim +++ b/tests/codex/slots/testbackends.nim @@ -1,3 +1,4 @@ import ./backends/testcircomcompat +import ./backends/testnimgroth16 {.warning[UnusedImport]: off.} diff --git a/tests/codex/slots/testprover.nim b/tests/codex/slots/testprover.nim index c567db55..8f7695e5 100644 --- a/tests/codex/slots/testprover.nim +++ b/tests/codex/slots/testprover.nim @@ -13,17 +13,19 @@ import pkg/confutils/defs import pkg/poseidon2/io import pkg/codex/utils/poseidon2digest import pkg/codex/nat +import pkg/taskpools import pkg/codex/utils/natutils import ./helpers import ../helpers -suite "Test Prover": +suite "Test CircomCompat Prover": let samples = 5 blockSize = DefaultBlockSize cellSize = DefaultCellSize repoTmp = TempLevelDb.new() metaTmp = TempLevelDb.new() + tp = Taskpool.new() challenge = 1234567.toF.toBytes.toArray32 var @@ -34,55 +36,60 @@ suite "Test Prover": let repoDs = repoTmp.newDb() metaDs = metaTmp.newDb() - config = CodexConf( - cmd: StartUpCmd.persistence, - nat: NatConfig(hasExtIp: false, nat: NatNone), - metricsAddress: parseIpAddress("127.0.0.1"), - persistenceCmd: PersistenceCmd.prover, - circomR1cs: InputFile("tests/circuits/fixtures/proof_main.r1cs"), - circomWasm: InputFile("tests/circuits/fixtures/proof_main.wasm"), - circomZkey: InputFile("tests/circuits/fixtures/proof_main.zkey"), - numProofSamples: samples, - ) - backend = config.initializeBackend().tryGet() + backend = CircomCompatBackendRef.new( + r1csPath = "tests/circuits/fixtures/proof_main.r1cs", + wasmPath = "tests/circuits/fixtures/proof_main.wasm", + zkeyPath = "tests/circuits/fixtures/proof_main.zkey", + ).tryGet + tp = Taskpool.new() store = RepoStore.new(repoDs, metaDs) - prover = Prover.new(store, backend, config.numProofSamples) + prover = Prover.new(backend, samples, tp) teardown: await repoTmp.destroyDb() await metaTmp.destroyDb() test "Should sample and prove a slot": - let (_, _, verifiable) = await createVerifiableManifest( - store, - 8, # number of blocks in the original dataset (before EC) - 5, # ecK - 3, # ecM - blockSize, - cellSize, - ) + let + (_, _, verifiable) = await createVerifiableManifest( + store, + 8, # number of blocks in the original dataset (before EC) + 5, # ecK + 3, # ecM + blockSize, + cellSize, + ) - let (inputs, proof) = (await prover.prove(1, verifiable, challenge)).tryGet + builder = + Poseidon2Builder.new(store, verifiable, verifiable.verifiableStrategy).tryGet + sampler = Poseidon2Sampler.new(1, store, builder).tryGet + (_, checked) = + (await prover.prove(sampler, verifiable, challenge, verify = true)).tryGet check: - (await prover.verify(proof, inputs)).tryGet == true + checked.isSome and checked.get == true test "Should generate valid proofs when slots consist of single blocks": # To get single-block slots, we just need to set the number of blocks in # the original dataset to be the same as ecK. The total number of blocks # after generating random data for parity will be ecK + ecM, which will # match the number of slots. - let (_, _, verifiable) = await createVerifiableManifest( - store, - 2, # number of blocks in the original dataset (before EC) - 2, # ecK - 1, # ecM - blockSize, - cellSize, - ) + let + (_, _, verifiable) = await createVerifiableManifest( + store, + 2, # number of blocks in the original dataset (before EC) + 2, # ecK + 1, # ecM + blockSize, + cellSize, + ) - let (inputs, proof) = (await prover.prove(1, verifiable, challenge)).tryGet + builder = + Poseidon2Builder.new(store, verifiable, verifiable.verifiableStrategy).tryGet + sampler = Poseidon2Sampler.new(1, store, builder).tryGet + (_, checked) = + (await prover.prove(sampler, verifiable, challenge, verify = true)).tryGet check: - (await prover.verify(proof, inputs)).tryGet == true + checked.isSome and checked.get == true diff --git a/tests/codex/slots/testproverfactory.nim b/tests/codex/slots/testproverfactory.nim new file mode 100644 index 00000000..b6526550 --- /dev/null +++ b/tests/codex/slots/testproverfactory.nim @@ -0,0 +1,111 @@ +import os +import ../../asynctest + +import pkg/chronos +import pkg/taskpools + +import pkg/confutils/defs +import pkg/codex/conf +import pkg/codex/slots/proofs/backends +import pkg/codex/slots/proofs/proverfactory {.all.} +import pkg/codex/utils/natutils + +import ../helpers +import ../examples + +suite "Test BackendFactory": + let circuitDir = "testecircuitdir" + + setup: + createDir(circuitDir) + + teardown: + removeDir(circuitDir) + + test "Should initialize with correct nimGroth16 config files": + let config = CodexConf( + cmd: StartUpCmd.persistence, + nat: NatConfig(hasExtIp: false, nat: NatNone), + metricsAddress: parseIpAddress("127.0.0.1"), + persistenceCmd: PersistenceCmd.prover, + marketplaceAddress: EthAddress.example.some, + proverBackendCmd: ProverBackendCmd.nimGroth16, + circomGraph: InputFile("tests/circuits/fixtures/proof_main.bin"), + circomR1cs: InputFile("tests/circuits/fixtures/proof_main.r1cs"), + circomZkey: InputFile("tests/circuits/fixtures/proof_main.zkey"), + ) + + check: + getGraphFile(config).tryGet == $config.circomGraph + getR1csFile(config).tryGet == $config.circomR1cs + getZkeyFile(config).tryGet == $config.circomZkey + + test "Should initialize with correct circom compat config files": + let config = CodexConf( + cmd: StartUpCmd.persistence, + nat: NatConfig(hasExtIp: false, nat: NatNone), + metricsAddress: parseIpAddress("127.0.0.1"), + persistenceCmd: PersistenceCmd.prover, + marketplaceAddress: EthAddress.example.some, + proverBackendCmd: ProverBackendCmd.circomCompat, + circomWasm: InputFile("tests/circuits/fixtures/proof_main.wasm"), + circomR1cs: InputFile("tests/circuits/fixtures/proof_main.r1cs"), + circomZkey: InputFile("tests/circuits/fixtures/proof_main.zkey"), + ) + + check: + getWasmFile(config).tryGet == $config.circomWasm + getR1csFile(config).tryGet == $config.circomR1cs + getZkeyFile(config).tryGet == $config.circomZkey + + test "Should initialize circom compat from local directory": + let config = CodexConf( + cmd: StartUpCmd.persistence, + nat: NatConfig(hasExtIp: false, nat: NatNone), + metricsAddress: parseIpAddress("127.0.0.1"), + persistenceCmd: PersistenceCmd.prover, + marketplaceAddress: EthAddress.example.some, + proverBackendCmd: ProverBackendCmd.circomCompat, + # Set the circuitDir such that the tests/circuits/fixtures/ files + # will be picked up as local files: + circuitDir: OutDir("tests/circuits/fixtures"), + ) + + check: + getR1csFile(config).tryGet == config.circuitDir / "proof_main.r1cs" + getWasmFile(config).tryGet == config.circuitDir / "proof_main.wasm" + getZKeyFile(config).tryGet == config.circuitDir / "proof_main.zkey" + + test "Should initialize nim groth16 from local directory": + let config = CodexConf( + cmd: StartUpCmd.persistence, + nat: NatConfig(hasExtIp: false, nat: NatNone), + metricsAddress: parseIpAddress("127.0.0.1"), + persistenceCmd: PersistenceCmd.prover, + marketplaceAddress: EthAddress.example.some, + proverBackendCmd: ProverBackendCmd.nimGroth16, + # Set the circuitDir such that the tests/circuits/fixtures/ files + # will be picked up as local files: + circuitDir: OutDir("tests/circuits/fixtures"), + ) + + check: + getGraphFile(config).tryGet == config.circuitDir / "proof_main.bin" + getR1csFile(config).tryGet == config.circuitDir / "proof_main.r1cs" + getZKeyFile(config).tryGet == config.circuitDir / "proof_main.zkey" + + test "Should suggest usage of downloader tool when files not available": + let + config = CodexConf( + cmd: StartUpCmd.persistence, + nat: NatConfig(hasExtIp: false, nat: NatNone), + metricsAddress: parseIpAddress("127.0.0.1"), + persistenceCmd: PersistenceCmd.prover, + proverBackendCmd: ProverBackendCmd.nimGroth16, + marketplaceAddress: EthAddress.example.some, + circuitDir: OutDir(circuitDir), + ) + proverResult = config.initializeProver(Taskpool.new()) + + check: + proverResult.isErr