From 00e376aee7e72bae6374e3879afff6673eda3bec Mon Sep 17 00:00:00 2001 From: benbierens Date: Tue, 5 Dec 2023 15:25:38 +0100 Subject: [PATCH] finding number of pad cells --- codex/slotbuilder/slotbuilder.nim | 36 ++++++++++++++ tests/codex/slotbuilder/testslotbuilder.nim | 55 ++++++++++++++++++--- 2 files changed, 83 insertions(+), 8 deletions(-) diff --git a/codex/slotbuilder/slotbuilder.nim b/codex/slotbuilder/slotbuilder.nim index 8cc6f102..0aa2c476 100644 --- a/codex/slotbuilder/slotbuilder.nim +++ b/codex/slotbuilder/slotbuilder.nim @@ -1,3 +1,4 @@ +import std/math import pkg/libp2p import pkg/chronos import pkg/chronicles @@ -6,6 +7,12 @@ import ../merkletree import ../stores import ../manifest +let + # TODO: Unified with the CellSize specified in branch "data-sampler" + # Number of bytes in a cell. A cell is the smallest unit of data used + # in the proving circuit. + CellSize* = 2048 + type SlotBuilder* = object of RootObj blockStore: BlockStore @@ -57,6 +64,33 @@ proc selectSlotBlocks*(self: SlotBuilder, datasetSlotIndex: int): Future[?!seq[C return success(cids) +proc findNextPowerOfTwo*(i: int): int = + # TODO: this is just a copy of the test implementation. + # If anyone wants to try to make a faster version, plz do. + # constantine has one in bithacks.nim 'nextPowerOfTwo_vartime' + if i < 1: + return 1 + let + logtwo = log2(i.float) + roundUp = ceil(logtwo) + nextPow = pow(2.float, roundUp) + return nextPow.int + +proc calculateNumberOfPaddingCells*(self: SlotBuilder, numberOfSlotBlocks: int): int = + let + blockSize = self.manifest.blockSize.int + expectZero = blockSize mod CellSize + + if expectZero != 0: + raiseAssert("BlockSize should always be divisable by Cell size (2kb).") + + let + cellsPerBlock = blockSize div CellSize + numberOfCells = numberOfSlotBlocks * cellsPerBlock + nextPowerOfTwo = findNextPowerOfTwo(numberOfCells) + + return nextPowerOfTwo - numberOfCells + proc createAndSaveSlotTree*(self: SlotBuilder, datasetSlotIndex: int): Future[?!MerkleTree] {.async.} = without var builder =? MerkleTreeBuilder.init(), err: return failure(err) @@ -66,6 +100,8 @@ proc createAndSaveSlotTree*(self: SlotBuilder, datasetSlotIndex: int): Future[?! # select slot blocks # pad till cells are power of two + # -> get number of padding cells + # -> convert to number of padding blocks # build tree diff --git a/tests/codex/slotbuilder/testslotbuilder.nim b/tests/codex/slotbuilder/testslotbuilder.nim index 5f749a6b..29a52675 100644 --- a/tests/codex/slotbuilder/testslotbuilder.nim +++ b/tests/codex/slotbuilder/testslotbuilder.nim @@ -1,4 +1,5 @@ import std/sequtils +import std/math import pkg/chronos import pkg/asynctest import pkg/questionable/results @@ -91,17 +92,55 @@ asyncchecksuite "Slot builder": check: SlotBuilder.new(localStore, mismatchManifest).isErr - for i in 0 ..< numberOfSlots: - test "Can select slot block CIDs (index: " & $i & ")": - let - steppedStrategy = SteppedIndexingStrategy.new(0, numberOfDatasetBlocks - 1, numberOfSlots) - expectedDatasetBlockIndicies = steppedStrategy.getIndicies(i) - expectedBlockCids = expectedDatasetBlockIndicies.mapIt(datasetBlocks[it].cid) + proc getNextPowerOfTwo(i: int): int = + if i < 1: + return 1 + let + logtwo = log2(i.float) + roundUp = ceil(logtwo) + nextPow = pow(2.float, roundUp) + return nextPow.int - slotBlockCids = (await slotBuilder.selectSlotBlocks(i)).tryGet() + for i in 0 ..< 20: + test "Check efficient findNextPowerOfTwo (" & $i & ")": + let + expected = getNextPowerOfTwo(i) + actual = findNextPowerOfTwo(i) check: - expectedBlockCids == slotBlockCids + expected == actual + + for nSlotBlocks in [1, 12, 123, 1234, 12345]: + test "Can calculate the number of padding cells (" & $nSlotBlocks & ")": + let + nPadCells = slotBuilder.calculateNumberOfPaddingCells(nSlotBlocks) + totalSlotBytes = nSlotBlocks * blockSize + totalSlotCells = totalSlotBytes div CellSize + nextPowerOfTwo = getNextPowerOfTwo(totalSlotCells) + expectedPadCells = nextPowerOfTwo - totalSlotCells + check: + expectedPadCells == nPadCells + + + + # for i in 0 ..< numberOfSlots: + # test "Can select slot block CIDs (index: " & $i & ")": + # let + # steppedStrategy = SteppedIndexingStrategy.new(0, numberOfDatasetBlocks - 1, numberOfSlots) + # expectedDatasetBlockIndicies = steppedStrategy.getIndicies(i) + # expectedBlockCids = expectedDatasetBlockIndicies.mapIt(datasetBlocks[it].cid) + + # slotBlockCids = (await slotBuilder.selectSlotBlocks(i)).tryGet() + + # check: + # expectedBlockCids == slotBlockCids + + + + + + + # for i in 0 ..< numberOfSlots: # test "Can create slot tree given index (" & $i & ")":