From 0b8811c98d508cd68149647918a6ec688a967820 Mon Sep 17 00:00:00 2001 From: Ben Bierens <39762930+benbierens@users.noreply.github.com> Date: Fri, 26 Jan 2024 00:34:38 +0100 Subject: [PATCH] Debug/sampling (#681) * Extra logging in sampler * wip: Fixing sampling issue in padded slot cells * Cleanup * Restores tests --- codex/slots/builder/builder.nim | 34 ++++-- codex/slots/sampler/sampler.nim | 116 +++++++++++++-------- codex/slots/sampler/utils.nim | 4 +- tests/codex/slots/provingtestenv.nim | 41 ++++++-- tests/codex/slots/testsampler.nim | 52 +++++++-- tests/codex/slots/testsampler_expected.nim | 18 ++-- tests/codex/slots/testslotbuilder.nim | 2 +- tests/codex/slots/testutils.nim | 16 +-- 8 files changed, 195 insertions(+), 88 deletions(-) diff --git a/codex/slots/builder/builder.nim b/codex/slots/builder/builder.nim index 3488fb58..353ef2d0 100644 --- a/codex/slots/builder/builder.nim +++ b/codex/slots/builder/builder.nim @@ -129,6 +129,12 @@ func numBlockCells*(self: SlotsBuilder): Natural = (self.manifest.blockSize div self.cellSize).Natural +func numBlockCellsPadded*(self: SlotsBuilder): Natural = + ## Number of cells per block including padding. + ## + + nextPowerOfTwo(self.numBlockCells.int).Natural + func cellSize*(self: SlotsBuilder): NBytes = ## Cell size. ## @@ -141,6 +147,18 @@ func numSlotCells*(self: SlotsBuilder): Natural = self.numBlockCells * self.numSlotBlocks +func numSlotCellsPadded*(self: SlotsBuilder): Natural = + ## Number of cells per slot including padding. + ## + + nextPowerOfTwo(self.numBlockCellsPadded.int * self.numSlotBlocks.int).Natural + +func emptyDigestTree*(self: SlotsBuilder): Poseidon2Tree {.inline.} = + ## Returns the tree of a padding block. + ## + + self.emptyDigestTree + func slotIndiciesIter*(self: SlotsBuilder, slot: Natural): ?!Iter[int] = ## Returns the slot indices. ## @@ -180,7 +198,7 @@ proc buildBlockTree*( success (blk.data, tree) -proc getCellHashes*( +proc getBlockHashes*( self: SlotsBuilder, slotIndex: Natural): Future[?!seq[Poseidon2Hash]] {.async.} = @@ -201,9 +219,9 @@ proc getCellHashes*( for blkIdx in self.strategy.getIndicies(slotIndex): trace "Getting block CID for tree at index" - without (_, tree) =? (await self.buildBlockTree(blkIdx)) and - digest =? tree.root, err: - error "Failed to get block CID for tree at index", err = err.msg + without (_, blockTree) =? (await self.buildBlockTree(blkIdx)) and + digest =? blockTree.root, err: + error "Failed to get block CID for block tree at index", err = err.msg return failure(err) digest @@ -213,11 +231,11 @@ proc getCellHashes*( proc buildSlotTree*( self: SlotsBuilder, slotIndex: Natural): Future[?!Poseidon2Tree] {.async.} = - without cellHashes =? (await self.getCellHashes(slotIndex)), err: + without blockHashes =? (await self.getBlockHashes(slotIndex)), err: error "Failed to select slot blocks", err = err.msg return failure(err) - Poseidon2Tree.init(cellHashes & self.slotsPadLeafs) + Poseidon2Tree.init(blockHashes & self.slotsPadLeafs) proc buildSlot*( self: SlotsBuilder, @@ -331,8 +349,8 @@ proc new*( # all trees have to be padded to power of two numBlockCells = (manifest.blockSize div cellSize).int # number of cells per block blockPadBytes = newSeq[byte](numBlockCells.nextPowerOfTwoPad * cellSize.int) # power of two padding for blocks - numSlotLeafs = (manifest.blocksCount div manifest.numSlots) - slotsPadLeafs = newSeqWith(numSlotLeafs.nextPowerOfTwoPad, Poseidon2Zero) # power of two padding for block roots + numSlotBlocks = (manifest.blocksCount div manifest.numSlots) + slotsPadLeafs = newSeqWith(numSlotBlocks.nextPowerOfTwoPad, Poseidon2Zero) # power of two padding for block roots rootsPadLeafs = newSeqWith(manifest.numSlots.nextPowerOfTwoPad, Poseidon2Zero) emptyDigestTree = ? Poseidon2Tree.digestTree(DefaultEmptyBlock & blockPadBytes, DefaultCellSize.int) diff --git a/codex/slots/sampler/sampler.nim b/codex/slots/sampler/sampler.nim index f93bbec4..802ebdf1 100644 --- a/codex/slots/sampler/sampler.nim +++ b/codex/slots/sampler/sampler.nim @@ -80,6 +80,66 @@ proc getCell*(self: DataSampler, blkBytes: seq[byte], blkCellIdx: Natural): Cell dataEnd = dataStart + cellSize return blkBytes[dataStart ..< dataEnd] +proc createProofSample(self: DataSampler, slotTreeCid: Cid, cellIdx: Natural): Future[?!Sample] {.async.} = + let + cellsPerBlock = self.builder.numBlockCells + blkCellIdx = cellIdx.toBlockCellIdx(cellsPerBlock) + slotBlkIdx = cellIdx.toBlockIdx(cellsPerBlock) + + logScope: + cellIdx = cellIdx + slotBlkIdx = slotBlkIdx + blkCellIdx = blkCellIdx + + without (cid, proof) =? await self.blockStore.getCidAndProof( + slotTreeCid, + slotBlkIdx.Natural), err: + error "Failed to get block from block store", err = err.msg + return failure(err) + + without slotProof =? proof.toVerifiableProof(), err: + error "Unable to convert slot proof to poseidon proof", error = err.msg + return failure(err) + + # If the cell index is greater than or equal to the UNPADDED number of slot cells, + # Then we're sampling inside a padded block. + # In this case, we use the pre-generated zero-data and pre-generated padding-proof for this cell index. + if cellIdx >= self.builder.numSlotCells: + trace "Sampling a padded block" + + without blockProof =? self.builder.emptyDigestTree.getProof(blkCellIdx), err: + error "Failed to get proof from empty block tree", err = err.msg + return failure(err) + + success(Sample( + data: newSeq[byte](self.builder.cellSize.int), + slotProof: slotProof, + cellProof: blockProof, + slotBlockIdx: slotBlkIdx.Natural, + blockCellIdx: blkCellIdx.Natural)) + + else: + trace "Sampling a dataset block" + # This converts our slotBlockIndex to a datasetBlockIndex using the + # indexing-strategy used by the builder. + # We need this to fetch the block data. We can't do it by slotTree + slotBlkIdx. + let datasetBlockIndex = self.builder.slotIndicies(self.index)[slotBlkIdx] + + without (bytes, blkTree) =? await self.builder.buildBlockTree(datasetBlockIndex), err: + error "Failed to build block tree", err = err.msg + return failure(err) + + without blockProof =? blkTree.getProof(blkCellIdx), err: + error "Failed to get proof from block tree", err = err.msg + return failure(err) + + success(Sample( + data: self.getCell(bytes, blkCellIdx), + slotProof: slotProof, + cellProof: blockProof, + slotBlockIdx: slotBlkIdx.Natural, + blockCellIdx: blkCellIdx.Natural)) + proc getProofInput*( self: DataSampler, entropy: ProofChallenge, @@ -97,61 +157,27 @@ proc getProofInput*( error "Failed to get slot proof from verify tree", err = err.msg return failure(err) - let - slotTreeCid = self.builder.manifest.slotRoots[self.index] - cellsPerBlock = self.builder.numBlockCells - cellIdxs = entropy.cellIndices( - self.builder.slotRoots[self.index], - self.builder.numSlotCells, - nSamples) + let slotTreeCid = self.builder.manifest.slotRoots[self.index] logScope: index = self.index samples = nSamples - cells = cellIdxs slotTreeCid = slotTreeCid trace "Collecting input for proof" + + let cellIdxs = entropy.cellIndices( + self.builder.slotRoots[self.index], + self.builder.numSlotCellsPadded, + nSamples) + + trace "Found cell indices", cellIdxs let samples = collect(newSeq): for cellIdx in cellIdxs: - let - blkCellIdx = cellIdx.toBlockCellIdx(cellsPerBlock) # block cell index - slotCellIdx = cellIdx.toBlockIdx(cellsPerBlock) # slot tree index - - logScope: - cellIdx = cellIdx - slotCellIdx = slotCellIdx - blkCellIdx = blkCellIdx - - without (cid, proof) =? await self.blockStore.getCidAndProof( - slotTreeCid, - slotCellIdx.Natural), err: - error "Failed to get block from block store", err = err.msg + without sample =? (await self.createProofSample(slotTreeCid, cellIdx)), err: + error "Failed to create proof sample", error = err.msg return failure(err) - - without slotProof =? proof.toVerifiableProof(), err: - error "Unable to convert slot proof to poseidon proof", error = err.msg - return failure(err) - - # This converts our slotBlockIndex to a datasetBlockIndex using the - # indexing-strategy used by the builder. - # We need this to fetch the block data. We can't do it by slotTree + slotBlkIdx. - let datasetBlockIndex = self.builder.slotIndicies(self.index)[slotCellIdx] - - without (bytes, blkTree) =? await self.builder.buildBlockTree(datasetBlockIndex), err: - error "Failed to build block tree", err = err.msg - return failure(err) - - without blockProof =? blkTree.getProof(blkCellIdx), err: - error "Failed to get proof from block tree", err = err.msg - return failure(err) - - Sample( - data: self.getCell(bytes, blkCellIdx), - slotProof: slotProof, - cellProof: blockProof, - slotBlockIdx: slotCellIdx.Natural, - blockCellIdx: blkCellIdx.Natural) + sample success ProofInput( entropy: entropy, diff --git a/codex/slots/sampler/utils.nim b/codex/slots/sampler/utils.nim index c73f7b95..0379fb07 100644 --- a/codex/slots/sampler/utils.nim +++ b/codex/slots/sampler/utils.nim @@ -10,6 +10,7 @@ import std/sugar import std/bitops +import pkg/chronicles import pkg/poseidon2 import pkg/poseidon2/io @@ -67,7 +68,6 @@ func cellIndex*( doAssert( 1 shl log2 == numCells , "`numCells` is assumed to be a power of two" ) let hash = Sponge.digest( @[ slotRoot, entropy, counter.toF ], rate = 2 ) - return int( extractLowBits(hash, log2) ) func cellIndices*( @@ -75,6 +75,8 @@ func cellIndices*( slotRoot: Poseidon2Hash, numCells: Natural, nSamples: Natural): seq[Natural] = + trace "Calculating cell indices", numCells, nSamples + var indices: seq[Natural] while (indices.len < nSamples): let idx = cellIndex(entropy, slotRoot, numCells, indices.len + 1) diff --git a/tests/codex/slots/provingtestenv.nim b/tests/codex/slots/provingtestenv.nim index 85fbab91..8e0ca86d 100644 --- a/tests/codex/slots/provingtestenv.nim +++ b/tests/codex/slots/provingtestenv.nim @@ -1,4 +1,5 @@ import std/sequtils +import std/math import pkg/questionable/results import pkg/poseidon2/io @@ -28,7 +29,8 @@ const # in the dataset. bytesPerBlock* = 64 * 1024 cellsPerBlock* = bytesPerBlock div DefaultCellSize.int - numberOfSlotBlocks* = 4 + numberOfSlotBlocks* = 3 + numberOfSlotBlocksPadded* = numberOfSlotBlocks.nextPowerOfTwo totalNumberOfSlots* = 2 datasetSlotIndex* = 1 cellsPerSlot* = (bytesPerBlock * numberOfSlotBlocks) div DefaultCellSize.int @@ -37,7 +39,14 @@ const type ProvingTestEnvironment* = ref object # Invariant: - challenge*: Poseidon2Hash + # These challenges are chosen such that with the testenv default values + # and nSamples=3, they will land on [3x data cells + 0x padded cell], + # and [2x data cells + 1x padded cell] respectively: + challengeNoPad*: Poseidon2Hash + challengeOnePad*: Poseidon2Hash + blockPadBytes*: seq[byte] + emptyBlockTree*: Poseidon2Tree + emptyBlockCid*: Cid # Variant: localStore*: CacheStore manifest*: Manifest @@ -79,17 +88,19 @@ proc createSlotTree(self: ProvingTestEnvironment, dSlotIndex: uint64): Future[Po let slotBlocks = datasetBlockIndices.mapIt(self.datasetBlocks[it]) - numBlockCells = bytesPerBlock.int div DefaultCellSize.int - blockPadBytes = newSeq[byte](numBlockCells.nextPowerOfTwoPad * DefaultCellSize.int) - slotBlockRoots = slotBlocks.mapIt(Poseidon2Tree.digest(it.data & blockPadBytes, DefaultCellSize.int).tryGet()) - tree = Poseidon2Tree.init(slotBlockRoots).tryGet() + slotBlockRoots = slotBlocks.mapIt(Poseidon2Tree.digest(it.data & self.blockPadBytes, DefaultCellSize.int).tryGet()) + slotBlockRootPads = newSeqWith((slotBlockRoots.len).nextPowerOfTwoPad, Poseidon2Zero) + tree = Poseidon2Tree.init(slotBlockRoots & slotBlockRootPads).tryGet() treeCid = tree.root().tryGet().toSlotCid().tryGet() - for i in 0 ..< numberOfSlotBlocks: - let + for i in 0 ..< numberOfSlotBlocksPadded: + var blkCid: Cid + if i < slotBlockRoots.len: blkCid = slotBlockRoots[i].toCellCid().tryGet() - proof = tree.getProof(i).tryGet().toEncodableProof().tryGet() + else: + blkCid = self.emptyBlockCid + let proof = tree.getProof(i).tryGet().toEncodableProof().tryGet() discard await self.localStore.putCidAndProof(treeCid, i, blkCid, proof) return tree @@ -159,8 +170,18 @@ proc createSlot(self: ProvingTestEnvironment): void = ) proc createProvingTestEnvironment*(): Future[ProvingTestEnvironment] {.async.} = + let + numBlockCells = bytesPerBlock.int div DefaultCellSize.int + blockPadBytes = newSeq[byte](numBlockCells.nextPowerOfTwoPad * DefaultCellSize.int) + emptyBlockTree = Poseidon2Tree.digestTree(DefaultEmptyBlock & blockPadBytes, DefaultCellSize.int).tryGet() + emptyBlockCid = emptyBlockTree.root.tryGet().toCellCid().tryGet() + var testEnv = ProvingTestEnvironment( - challenge: toF(12345) + challengeNoPad: toF(6), + challengeOnePad: toF(9), + blockPadBytes: blockPadBytes, + emptyBlockTree: emptyBlockTree, + emptyBlockCid: emptyBlockCid ) testEnv.localStore = CacheStore.new() diff --git a/tests/codex/slots/testsampler.nim b/tests/codex/slots/testsampler.nim index 6cf687c5..a2898b67 100644 --- a/tests/codex/slots/testsampler.nim +++ b/tests/codex/slots/testsampler.nim @@ -73,7 +73,7 @@ asyncchecksuite "Test DataSampler": test "Can gather proof input": let nSamples = 3 - challengeBytes = env.challenge.toBytes() + challengeBytes = env.challengeNoPad.toBytes() input = (await dataSampler.getProofInput(challengeBytes, nSamples)).tryget() proc equal(a: Poseidon2Hash, b: Poseidon2Hash): bool = @@ -91,29 +91,65 @@ asyncchecksuite "Test DataSampler": check: equal(input.verifyRoot, env.datasetRootHash) - equal(input.entropy, env.challenge) + equal(input.entropy, env.challengeNoPad) input.numCells == ((bytesPerBlock * numberOfSlotBlocks) div DefaultCellSize.int).Natural input.numSlots == totalNumberOfSlots.Natural input.slotIndex == env.slot.slotIndex.truncate(Natural) input.verifyProof == expectedProof # block-slot proofs - input.samples[0].slotBlockIdx == 2 + input.samples[0].slotBlockIdx == 1 input.samples[1].slotBlockIdx == 2 - input.samples[2].slotBlockIdx == 0 + input.samples[2].slotBlockIdx == 1 toStr(input.samples[0].slotProof) == expectedBlockSlotProofs[0] toStr(input.samples[1].slotProof) == expectedBlockSlotProofs[1] toStr(input.samples[2].slotProof) == expectedBlockSlotProofs[2] # cell-block proofs - input.samples[0].blockCellIdx == 26 - input.samples[1].blockCellIdx == 29 - input.samples[2].blockCellIdx == 29 + input.samples[0].blockCellIdx == 25 + input.samples[1].blockCellIdx == 18 + input.samples[2].blockCellIdx == 17 toStr(input.samples[0].cellProof) == expectedCellBlockProofs[0] toStr(input.samples[1].cellProof) == expectedCellBlockProofs[1] toStr(input.samples[2].cellProof) == expectedCellBlockProofs[2] - # # cell data + # cell data nimcrypto.toHex(input.samples[0].data) == expectedCellData[0] nimcrypto.toHex(input.samples[1].data) == expectedCellData[1] nimcrypto.toHex(input.samples[2].data) == expectedCellData[2] + + test "Can select samples in padded cells": + let + nSamples = 3 + challengeBytes = env.challengeOnePad.toBytes() + input = (await dataSampler.getProofInput(challengeBytes, nSamples)).tryget() + + proc equal(a: Poseidon2Hash, b: Poseidon2Hash): bool = + a.toDecimal() == b.toDecimal() + + proc toStr(proof: Poseidon2Proof): string = + let a = proof.path.mapIt(toHex(it)) + join(a) + + let expectedProof = env.datasetToSlotTree.getProof(datasetSlotIndex).tryGet() + + check: + equal(input.verifyRoot, env.datasetRootHash) + equal(input.entropy, env.challengeOnePad) + input.numCells == ((bytesPerBlock * numberOfSlotBlocks) div DefaultCellSize.int).Natural + input.numSlots == totalNumberOfSlots.Natural + input.slotIndex == env.slot.slotIndex.truncate(Natural) + input.verifyProof == expectedProof + + input.samples[0].slotBlockIdx == 2 + input.samples[1].slotBlockIdx == 2 + input.samples[2].slotBlockIdx == 3 + # The third sample is a padded sample + toStr(input.samples[2].slotProof) == toStr(env.slotTree.getProof(3).tryGet()) + + input.samples[0].blockCellIdx == 29 + input.samples[1].blockCellIdx == 26 + input.samples[2].blockCellIdx == 30 + toStr(input.samples[2].cellProof) == toStr(env.emptyBlockTree.getProof(30).tryGet()) + + input.samples[2].data == newSeq[byte](DefaultCellSize.int) diff --git a/tests/codex/slots/testsampler_expected.nim b/tests/codex/slots/testsampler_expected.nim index 7d041f86..7be9b129 100644 --- a/tests/codex/slots/testsampler_expected.nim +++ b/tests/codex/slots/testsampler_expected.nim @@ -5,21 +5,21 @@ import pkg/codex/codextypes proc getExpectedCellBlockProofs*(): seq[string] = @[ - "0x189890bedf2a40f2757554c5f089811e07601543a576e2d40d68a1bd295adbee0x059f227fe687a7abd9c3d9878c0b812aa7829c85d30c23154b8824a907909b060x2c685fc951f1684fd3979f7e3a558fa6aeed3f960ef0a9e2ba51cc62cff7de0e0x10ebae3fb12d502044216e40319726ed36308b9ae4ab3fb0a36c77e5614c6fbd0x1decd3fb7ff458261149731115657cecd7eb2fe4a6cf84f3c6761aa8b0dd6b9a", - "0x2567cd93b3fe058b31908656c05d3a09fd33cc0d7df3c7c005d991a8cda60ba80x16e4788105082295706c49c604216518f16ca9dd106012c7c98e6ee138893f6e0x1c258af996aecf9bba249130182ccfe44a9090bc58fe59063a06db67efb7b5240x10ebae3fb12d502044216e40319726ed36308b9ae4ab3fb0a36c77e5614c6fbd0x1decd3fb7ff458261149731115657cecd7eb2fe4a6cf84f3c6761aa8b0dd6b9a", - "0x0568735989a51526104eddbcf386b8aaef186a2d31afce0c2671c8ce8dd8cd1a0x20d06082668338924981a9e0e4f18e7ec6e2b7912e7fb74c1b6dc921b824def60x2fd45662152ae87192971a0e9b7d50de48d7bc8ab22e5711680173a302120bf00x0f528a58c839889e4bb9195e2bcbc2addb7022e47c8fb11bbdeba0a0e9c6f4cb0x0edf43ec0f277500371537a4d566f3f352d0c49bfa9d4659e07d776ffe119437" + "0x13935d7f73028fd425e557b8e0b737fcba3f8bcda0e07a9047868bc7c5a2519e0x17d36c9bcef9febb77b129e8bbe971b754d7b3e1df8c7d881b64bf0aa055f5570x02610a45fa39d4859e5c0c53bda9cc6bd627ae4b5aa462f9e86f47f3db96b2700x27a362c0f92c887d74ee77df2df5e51f0f66b0564a2af8b1c11b02dab0a34f780x095eb3c0d166c19f9cac8ea0e6ba274dfeef802cf7d01c90378585fd4d788e56", + "0x128b43cb1f87736d5b826c5a440d373c0e4c147a81a0edc40b106abd2c10af960x2160ba1c1ed893685b849a8f1be6d32bb11a6ebb8690c5af95e0ce0e9d72b6580x1332185d0ef7b76e55c7464f37df96d41f256249d74678d8191030912036b7aa0x0522383db3f9cb9c75d5b209bd795566e9cffa632819628194416a479998a4270x1decd3fb7ff458261149731115657cecd7eb2fe4a6cf84f3c6761aa8b0dd6b9a", + "0x2a2c8663e354dbc1857a654134de3b690d73ffedcc7c0ba770a39f3e48675ee10x01914d98d4103889ea59ce6e970dae95f7e463350184c5f7f3806997e10748520x10e8f6235ac7e95af5aea6fc77ebe60e1028b48eb84027ea46d403d809852b6b0x04bd51be7ff42db27a7605124d3d2d1c4cbca43f93d1997060ac8a1009fa48b40x095eb3c0d166c19f9cac8ea0e6ba274dfeef802cf7d01c90378585fd4d788e56" ] proc getExpectedBlockSlotProofs*(): seq[string] = @[ - "0x0684458ea77eca59be05e368bb26b7ca318b8e836100c415e60136876c01ba170x2a66917fa49371e835376fcece0d854c77008ac1195740963b1ac4491ee1aaf1", - "0x0684458ea77eca59be05e368bb26b7ca318b8e836100c415e60136876c01ba170x2a66917fa49371e835376fcece0d854c77008ac1195740963b1ac4491ee1aaf1", - "0x03883ad2637a4c68f29bc0910400259291d9c3d730de7e3925adbf26c80b7f440x2d6a888f50b14b0c686f64c4bd0d8389cd555cdf0e3d6f387682c4722ac2a674" + "0x008fccffc5d2e5010a44bc718fed80d4d891e6517c022ba1bff65763dd79dbb90x117662f365386ee6784274dfa3a3b35126291cdf013c5e90d07bee79f32b2f40", + "0x00000000000000000000000000000000000000000000000000000000000000000x2a66917fa49371e835376fcece0d854c77008ac1195740963b1ac4491ee1aaf1", + "0x008fccffc5d2e5010a44bc718fed80d4d891e6517c022ba1bff65763dd79dbb90x117662f365386ee6784274dfa3a3b35126291cdf013c5e90d07bee79f32b2f40" ] proc getExpectedCellData*(): seq[string] = @[ - "BA".repeat(DefaultCellSize.int), - "BD".repeat(DefaultCellSize.int), - "3D".repeat(DefaultCellSize.int) + "79".repeat(DefaultCellSize.int), + "B2".repeat(DefaultCellSize.int), + "71".repeat(DefaultCellSize.int) ] diff --git a/tests/codex/slots/testslotbuilder.nim b/tests/codex/slots/testslotbuilder.nim index 8022e07a..bf710f76 100644 --- a/tests/codex/slots/testslotbuilder.nim +++ b/tests/codex/slots/testslotbuilder.nim @@ -217,7 +217,7 @@ suite "Slot builder": for blk in expectedBlock: SpongeMerkle.digest(blk.data & blockPadBytes, cellSize.int) - cellHashes = (await slotBuilder.getCellHashes(i)).tryGet() + cellHashes = (await slotBuilder.getBlockHashes(i)).tryGet() check: expectedHashes == cellHashes diff --git a/tests/codex/slots/testutils.nim b/tests/codex/slots/testutils.nim index 04e38b40..52e8f58f 100644 --- a/tests/codex/slots/testutils.nim +++ b/tests/codex/slots/testutils.nim @@ -2,6 +2,7 @@ import std/sequtils import std/sugar import std/random import std/strutils +import std/math import pkg/questionable/results import pkg/constantine/math/arithmetic @@ -27,17 +28,19 @@ import ../merkletree/helpers import ./provingtestenv asyncchecksuite "Test proof sampler utils": - let knownIndices: seq[Natural] = @[90, 93, 29] + let knownIndices: seq[Natural] = @[57, 82, 49] var env: ProvingTestEnvironment slotRoot: Poseidon2Hash numCells: Natural + numCellsPadded: Natural setup: env = await createProvingTestEnvironment() slotRoot = env.slotRoots[datasetSlotIndex] numCells = cellsPerSlot + numCellsPadded = numCells.nextPowerOfTwo teardown: reset(env) @@ -61,14 +64,15 @@ asyncchecksuite "Test proof sampler utils": test "Can find single slot-cell index": proc slotCellIndex(i: Natural): Natural = - return cellIndex(env.challenge, slotRoot, numCells, i) + return cellIndex(env.challengeNoPad, slotRoot, numCellsPadded, i) proc getExpectedIndex(i: int): Natural = let numberOfCellsInSlot = (bytesPerBlock * numberOfSlotBlocks) div DefaultCellSize.uint64.int - hash = Sponge.digest(@[slotRoot, env.challenge, toF(i)], rate = 2) + numberOfCellsInSlotPadded = numberOfCellsInSlot.nextPowerOfTwo + hash = Sponge.digest(@[slotRoot, env.challengeNoPad, toF(i)], rate = 2) - return int(extractLowBits(hash.toBig(), ceilingLog2(numberOfCellsInSlot))) + return int(extractLowBits(hash.toBig(), ceilingLog2(numberOfCellsInSlotPadded))) check: slotCellIndex(1) == getExpectedIndex(1) @@ -80,10 +84,10 @@ asyncchecksuite "Test proof sampler utils": test "Can find sequence of slot-cell indices": proc slotCellIndices(n: int): seq[Natural] = - cellIndices(env.challenge, slotRoot, numCells, n) + cellIndices(env.challengeNoPad, slotRoot, numCellsPadded, n) proc getExpectedIndices(n: int): seq[Natural] = - return collect(newSeq, (for i in 1..n: cellIndex(env.challenge, slotRoot, numCells, i))) + return collect(newSeq, (for i in 1..n: cellIndex(env.challengeNoPad, slotRoot, numCellsPadded, i))) check: slotCellIndices(3) == getExpectedIndices(3)