import std/sequtils import std/sugar import std/random import pkg/questionable/results import pkg/constantine/math/arithmetic import pkg/poseidon2/types import pkg/poseidon2 import pkg/chronos import pkg/asynctest import pkg/codex/stores/cachestore import pkg/codex/chunker import pkg/codex/stores import pkg/codex/blocktype as bt import pkg/codex/contracts/requests import pkg/codex/contracts import pkg/codex/merkletree import pkg/codex/stores/cachestore import pkg/codex/proof/datasampler import pkg/codex/proof/misc import pkg/codex/proof/types import pkg/codex/proof/indexing import ../helpers import ../examples import testdatasampler_expected let bytesPerBlock = 64 * 1024 challenge: DSFieldElement = toF(12345) slotRootHash: DSFieldElement = toF(6789) asyncchecksuite "Test proof datasampler - components": let numberOfSlotBlocks = 16 slot = Slot( request: StorageRequest( ask: StorageAsk( slots: 10, slotSize: u256(bytesPerBlock * numberOfSlotBlocks), ), content: StorageContent( cid: $Cid.example ) ), slotIndex: u256(3) ) test "Number of cells is a power of two": # This is to check that the data used for testing is sane. proc isPow2(value: int): bool = let log2 = ceilingLog2(value) return (1 shl log2) == value let numberOfCells = getNumberOfCellsInSlot(slot).int check: isPow2(numberOfCells) test "Extract low bits": proc extract(value: int, nBits: int): uint64 = let big = toF(value).toBig() return extractLowBits(big, nBits) check: extract(0x88, 4) == 0x8.uint64 extract(0x88, 7) == 0x8.uint64 extract(0x9A, 5) == 0x1A.uint64 extract(0x9A, 7) == 0x1A.uint64 extract(0x1248, 10) == 0x248.uint64 extract(0x1248, 12) == 0x248.uint64 # extract(0x1248306A560C9AC0, 10) == 0x2C0.uint64 # extract(0x1248306A560C9AC0, 12) == 0xAC0.uint64 # extract(0x1248306A560C9AC0, 50) == 0x306A560C9AC0.uint64 # extract(0x1248306A560C9AC0, 52) == 0x8306A560C9AC0.uint64 test "Should calculate total number of cells in Slot": let slotSizeInBytes = (slot.request.ask.slotSize).truncate(uint64) expectedNumberOfCells = slotSizeInBytes div CellSize check: expectedNumberOfCells == 512 expectedNumberOfCells == getNumberOfCellsInSlot(slot) let knownIndices = @[178.uint64, 277.uint64, 366.uint64] test "Can find single slot-cell index": let numberOfCells = getNumberOfCellsInSlot(slot) proc slotCellIndex(i: int): DSSlotCellIndex = let counter: DSFieldElement = toF(i) return findSlotCellIndex(slotRootHash, challenge, counter, numberOfCells) proc getExpectedIndex(i: int): DSSlotCellIndex = let hash = Sponge.digest(@[slotRootHash, challenge, toF(i)], rate = 2) return extractLowBits(hash.toBig(), ceilingLog2(numberOfCells.int)) check: slotCellIndex(1) == getExpectedIndex(1) slotCellIndex(1) == knownIndices[0] slotCellIndex(2) == getExpectedIndex(2) slotCellIndex(2) == knownIndices[1] slotCellIndex(3) == getExpectedIndex(3) slotCellIndex(3) == knownIndices[2] test "Can find sequence of slot-cell indices": proc slotCellIndices(n: int): seq[DSSlotCellIndex] = findSlotCellIndices(slot, slotRootHash, challenge, n) let numberOfCells = getNumberOfCellsInSlot(slot) proc getExpectedIndices(n: int): seq[DSSlotCellIndex] = return collect(newSeq, (for i in 1..n: findSlotCellIndex(slotRootHash, challenge, toF(i), numberOfCells))) check: slotCellIndices(3) == getExpectedIndices(3) slotCellIndices(3) == knownIndices test "Can get cell from block": let blockSize = CellSize * 3 bytes = newSeqWith(blockSize.int, rand(uint8)) blk = bt.Block.new(bytes).tryGet() sample0 = getCellFromBlock(blk, 0, blockSize.uint64) sample1 = getCellFromBlock(blk, 1, blockSize.uint64) sample2 = getCellFromBlock(blk, 2, blockSize.uint64) check: sample0 == bytes[0..