From e59f0f961ec7200e547369a94e274ddc6e211fda Mon Sep 17 00:00:00 2001 From: Mark Spanbroek Date: Mon, 15 Jan 2024 16:25:30 +0100 Subject: [PATCH] Submit proofs as array of bytes --- contracts/Marketplace.sol | 3 +-- contracts/Proofs.sol | 42 ++++++++++++++++++++++----------- test/Marketplace.test.js | 2 +- test/Proofs.test.js | 49 ++++++++++----------------------------- test/proof.js | 38 +++++++++++------------------- 5 files changed, 55 insertions(+), 79 deletions(-) diff --git a/contracts/Marketplace.sol b/contracts/Marketplace.sol index 1cf17b4..d96ebb7 100644 --- a/contracts/Marketplace.sol +++ b/contracts/Marketplace.sol @@ -113,8 +113,7 @@ contract Marketplace is Proofs, StateRetrieval { require(slotState(slotId) == SlotState.Free, "Slot is not free"); _startRequiringProofs(slotId, request.ask.proofProbability); - // TODO: Update call signature - // submitProof(slotId, proof); + submitProof(slotId, proof); slot.host = msg.sender; slot.state = SlotState.Filled; diff --git a/contracts/Proofs.sol b/contracts/Proofs.sol index f0253b2..704d821 100644 --- a/contracts/Proofs.sol +++ b/contracts/Proofs.sol @@ -108,21 +108,35 @@ abstract contract Proofs is Periods { return isRequired && pointer < _config.downtime; } - // TODO: The `pubSignals` should be constructed from information that we already know: - // - external entropy (for example some fresh ethereum block header) - this gives us the unbiased randomness we use to sample which cells to prove - // - the dataset root (which dataset we prove) - // - and the slot index (which slot out of that dataset we prove) - function submitProof( - SlotId id, - uint[2] calldata pA, - uint[2][2] calldata pB, - uint[2] calldata pC, - uint[3] calldata pubSignals - ) public { + function submitProof(SlotId id, bytes calldata proof) public { require(!_received[id][_blockPeriod()], "Proof already submitted"); - require(_verifier.verifyProof(pA, pB, pC, pubSignals), "Invalid proof"); + require(proof.length == 256, "invalid proof length"); + uint256[2] memory a; + uint256[2][2] memory b; + uint256[2] memory c; + a[0] = uint256(bytes32(proof[0:32])); + a[1] = uint256(bytes32(proof[32:64])); + b[0][0] = uint256(bytes32(proof[64:96])); + b[0][1] = uint256(bytes32(proof[96:128])); + b[1][0] = uint256(bytes32(proof[128:160])); + b[1][1] = uint256(bytes32(proof[160:192])); + c[0] = uint256(bytes32(proof[192:224])); + c[1] = uint256(bytes32(proof[224:256])); + + // TODO: The `pubSignals` should be constructed from information that we already know: + // - external entropy (for example some fresh ethereum block header) - this gives us the unbiased randomness we use to sample which cells to prove + // - the dataset root (which dataset we prove) + // - and the slot index (which slot out of that dataset we prove) + uint256[3] memory pubSignals; + pubSignals[0] = 7410779170; + pubSignals[ + 1 + ] = 16074246370508166450132968585287196391860062495017081813239200574579640171677; + pubSignals[2] = 3; + + require(_verifier.verifyProof(a, b, c, pubSignals), "Invalid proof"); _received[id][_blockPeriod()] = true; - emit ProofSubmitted(id, bytes("")); // TODO: Rework ProofSubmitted with the new call signature + emit ProofSubmitted(id); } function _markProofAsMissing(SlotId id, Period missedPeriod) internal { @@ -136,5 +150,5 @@ abstract contract Proofs is Periods { _missed[id] += 1; } - event ProofSubmitted(SlotId id, bytes proof); + event ProofSubmitted(SlotId id); } diff --git a/test/Marketplace.test.js b/test/Marketplace.test.js index 25b7887..77c0760 100644 --- a/test/Marketplace.test.js +++ b/test/Marketplace.test.js @@ -76,7 +76,7 @@ describe("Marketplace constructor", function () { }) describe("Marketplace", function () { - const proof = hexlify(randomBytes(42)) + const proof = hexlify(randomBytes(256)) const config = exampleConfiguration() let marketplace diff --git a/test/Proofs.test.js b/test/Proofs.test.js index 6e7a758..f055b58 100644 --- a/test/Proofs.test.js +++ b/test/Proofs.test.js @@ -200,52 +200,27 @@ describe("Proofs", function () { }) it("submits a correct proof", async function () { - await proofs.submitProof(slotId, ...proof) + await proofs.submitProof(slotId, proof) }) it("fails proof submission when proof is incorrect", async function () { - await expect( - proofs.submitProof( - slotId, - [ - "0x1bcdb9a3c52070f56e8d59b29239f0528817f99745157ce4d03faefddfff6acc", - "0x2496ab7dd8f0596c21653105e4af7e48eb5395ea45e0c876d7db4dd31b4df23e", - ], - [ - [ - "0x002ef03c350ccfbf234bfde498378709edea3a506383d492b58c4c35ffecc508", - "0x174d475745707d35989001e9216201bdb828130b0e78dbf772c4795fa845b5eb", - ], - [ - "0x1f04519f202fac14311c65d827f65f787dbe01985044278292723b9ee77ce5ee", - "0x1c42f4d640e94c28401392031e74426ae68145f4f520cd576ca5e5b9af97c0bb", - ], - ], - [ - "0x1db1e61b32db677f3927ec117569e068f62747986e4ac7f54db8f2acd17e4abc", - "0x20a59e1daca2ab80199c5bca2c5a7d6de6348bd795a0dd999752cc462d851128", - ], - [ - "0x00000000000000000000000000000000000000000000000000000001b9b78422", - "0x2389b3770d31a09a71cda2cb2114c203172eac63b61f76cb9f81db7adbe8fc9d", - "0x0000000000000000000000000000000000000000000000000000000000000003", - ] - ) - ).to.be.revertedWith("Invalid proof") + let invalid = new Uint8Array(proof) + invalid[42] = 42 + await expect(proofs.submitProof(slotId, invalid)).to.be.revertedWith( + "Invalid proof" + ) }) it("emits an event when proof was submitted", async function () { - await expect(proofs.submitProof(slotId, ...proof)).to.emit( - proofs, - "ProofSubmitted" - ) - // .withArgs(slotId, proof) // TODO: Update when ProofSubmitted updated + await expect(proofs.submitProof(slotId, proof)) + .to.emit(proofs, "ProofSubmitted") + .withArgs(slotId) }) it("fails proof submission when already submitted", async function () { await advanceTimeToForNextBlock(periodEnd(periodOf(await currentTime()))) - await proofs.submitProof(slotId, ...proof) - await expect(proofs.submitProof(slotId, ...proof)).to.be.revertedWith( + await proofs.submitProof(slotId, proof) + await expect(proofs.submitProof(slotId, proof)).to.be.revertedWith( "Proof already submitted" ) }) @@ -280,7 +255,7 @@ describe("Proofs", function () { it("does not mark a submitted proof as missing", async function () { await waitUntilProofIsRequired(slotId) let submittedPeriod = periodOf(await currentTime()) - await proofs.submitProof(slotId, ...proof) + await proofs.submitProof(slotId, proof) await advanceTimeToForNextBlock(periodEnd(submittedPeriod)) await mine() await expect( diff --git a/test/proof.js b/test/proof.js index 3118648..6c61e4a 100644 --- a/test/proof.js +++ b/test/proof.js @@ -1,4 +1,6 @@ const fs = require("fs") +const ethers = require("ethers") +const { arrayify } = ethers.utils const BASE_PATH = __dirname + "/../contracts/verifiers" const PROOF_FILE_NAME = "proof.json" @@ -18,31 +20,17 @@ function loadProof(name) { // how to obtain it. //return [proof.pi_a, proof.pi_b, proof.pi_c, public] - return [ - [ - "0x1bcdb9a3c52070f56e8d49b29239f0528817f99745157ce4d03faefddfff6acc", - "0x2496ab7dd8f0596c21653105e4af7e48eb5395ea45e0c876d7db4dd31b4df23e", - ], - [ - [ - "0x002ef03c350ccfbf234bfde498378709edea3a506383d492b58c4c35ffecc508", - "0x174d475745707d35989001e9216201bdb828130b0e78dbf772c4795fa845b5eb", - ], - [ - "0x1f04519f202fac14311c65d827f65f787dbe01985044278292723b9ee77ce5ee", - "0x1c42f4d640e94c28401392031e74426ae68145f4f520cd576ca5e5b9af97c0bb", - ], - ], - [ - "0x1db1e61b32db677f3927ec117569e068f62747986e4ac7f54db8f2acd17e4abc", - "0x20a59e1daca2ab80199c5bca2c5a7d6de6348bd795a0dd999752cc462d851128", - ], - [ - "0x00000000000000000000000000000000000000000000000000000001b9b78422", - "0x2389b3770d31a09a71cda2cb2114c203172eac63b61f76cb9f81db7adbe8fc9d", - "0x0000000000000000000000000000000000000000000000000000000000000003", - ], - ] + return arrayify( + "0x" + + "1bcdb9a3c52070f56e8d49b29239f0528817f99745157ce4d03faefddfff6acc" + + "2496ab7dd8f0596c21653105e4af7e48eb5395ea45e0c876d7db4dd31b4df23e" + + "002ef03c350ccfbf234bfde498378709edea3a506383d492b58c4c35ffecc508" + + "174d475745707d35989001e9216201bdb828130b0e78dbf772c4795fa845b5eb" + + "1f04519f202fac14311c65d827f65f787dbe01985044278292723b9ee77ce5ee" + + "1c42f4d640e94c28401392031e74426ae68145f4f520cd576ca5e5b9af97c0bb" + + "1db1e61b32db677f3927ec117569e068f62747986e4ac7f54db8f2acd17e4abc" + + "20a59e1daca2ab80199c5bca2c5a7d6de6348bd795a0dd999752cc462d851128" + ) } module.exports = { loadProof }