148 lines
3.9 KiB
Nim
Raw Normal View History

2024-01-15 21:47:06 -06:00
## Nim-Codex
## Copyright (c) 2023 Status Research & Development GmbH
## Licensed under either of
## * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE))
## * MIT license ([LICENSE-MIT](LICENSE-MIT))
## at your option.
## This file may not be copied, modified, or distributed except according to
## those terms.
2023-11-22 10:19:51 +01:00
import std/sugar
2024-01-15 21:47:06 -06:00
import std/sequtils
2023-11-22 09:19:41 +01:00
import pkg/chronicles
import pkg/chronos
import pkg/questionable
import pkg/questionable/results
2023-11-22 09:19:41 +01:00
import pkg/constantine/math/arithmetic
import pkg/poseidon2
2024-01-15 21:47:06 -06:00
import pkg/poseidon2/types
import pkg/poseidon2/io
import ../../market
import ../../blocktype as bt
import ../../merkletree
import ../../manifest
import ../../stores
2023-11-22 09:19:41 +01:00
2024-01-15 21:47:06 -06:00
import ../builder
2024-01-15 21:47:06 -06:00
import ./utils
2023-11-27 12:01:06 +01:00
2023-11-26 17:05:11 +01:00
logScope:
topics = "codex datasampler"
2023-11-27 12:01:06 +01:00
type
2024-01-15 21:47:06 -06:00
Cell* = seq[byte]
Sample* = object
data*: Cell
slotProof*: Poseidon2Proof
cellProof*: Poseidon2Proof
2024-01-15 21:47:06 -06:00
ProofInput* = object
entropy*: Poseidon2Hash
verifyRoot*: Poseidon2Hash
verifyProof*: Poseidon2Proof
2024-01-15 21:47:06 -06:00
numSlots*: Natural
numCells*: Natural
slotIndex*: Natural
samples*: seq[Sample]
2023-11-27 12:01:06 +01:00
DataSampler* = ref object of RootObj
2024-01-15 21:47:06 -06:00
index: Natural
2023-11-27 12:01:06 +01:00
blockStore: BlockStore
# The following data is invariant over time for a given slot:
2024-01-15 13:59:55 -06:00
builder: SlotsBuilder
2023-11-27 12:01:06 +01:00
proc new*(
T: type DataSampler,
2024-01-15 21:47:06 -06:00
index: Natural,
2023-11-27 12:01:06 +01:00
blockStore: BlockStore,
2024-01-15 21:47:06 -06:00
builder: SlotsBuilder): ?!DataSampler =
2024-01-15 13:59:55 -06:00
2024-01-15 21:47:06 -06:00
if index > builder.slotRoots.high:
error "Slot index is out of range"
return failure("Slot index is out of range")
2024-01-15 13:59:55 -06:00
2024-01-15 21:47:06 -06:00
success DataSampler(
index: index,
blockStore: blockStore,
builder: builder)
2023-11-27 12:01:06 +01:00
proc getCell*(self: DataSampler, blkBytes: seq[byte], blkCellIdx: Natural): Cell =
let
cellSize = self.builder.cellSize.uint64
dataStart = cellSize * blkCellIdx.uint64
dataEnd = dataStart + cellSize
return blkBytes[dataStart ..< dataEnd]
proc getProofInput*(
2024-01-15 21:47:06 -06:00
self: DataSampler,
entropy: ProofChallenge,
nSamples: Natural): Future[?!ProofInput] {.async.} =
## Generate proofs as input to the proving circuit.
##
2023-11-22 09:19:41 +01:00
2024-01-15 21:47:06 -06:00
without entropy =? Poseidon2Hash.fromBytes(entropy):
error "Failed to parse entropy"
return failure("Failed to parse entropy")
2023-11-22 09:19:41 +01:00
2024-01-15 21:47:06 -06:00
without verifyTree =? self.builder.verifyTree and
verifyProof =? verifyTree.getProof(self.index) and
2024-01-15 21:47:06 -06:00
verifyRoot =? verifyTree.root(), err:
error "Failed to get slot proof from verify tree", err = err.msg
return failure(err)
2023-11-22 16:14:43 +01:00
let
slotTreeCid = self.builder.manifest.slotRoots[self.index]
2024-01-15 21:47:06 -06:00
cellIdxs = entropy.cellIndices(
self.builder.slotRoots[self.index],
self.builder.numSlotCells,
nSamples)
logScope:
index = self.index
samples = nSamples
cells = cellIdxs
slotTreeCid = slotTreeCid
2024-01-15 21:47:06 -06:00
trace "Collecting input for proof"
2024-01-16 11:20:34 +01:00
let samples = collect(newSeq):
2024-01-15 21:47:06 -06:00
for cellIdx in cellIdxs:
let
blockIdx = cellIdx.toBlockIdx(self.builder.numSlotCells)
blkCellIdx = cellIdx.toBlockCellIdx(self.builder.numBlockCells)
logScope:
cellIdx = cellIdx
blockIdx = blockIdx
blkCellIdx = blkCellIdx
without (cid, slotProof) =? await self.blockStore.getCidAndProof(
slotTreeCid,
2024-01-15 21:47:06 -06:00
blockIdx.Natural), err:
error "Failed to get block from block store", err = err.msg
return failure(err)
without (bytes, blkTree) =? await self.builder.buildBlockTree(blockIdx), 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)
let cellData = self.getCell(bytes, blkCellIdx)
Sample(data: cellData, slotProof: slotProof, cellProof: blockProof)
2024-01-15 21:47:06 -06:00
success ProofInput(
entropy: entropy,
verifyRoot: verifyRoot,
verifyProof: verifyProof,
2024-01-15 21:47:06 -06:00
numSlots: self.builder.numSlots,
numCells: self.builder.numSlotCells,
slotIndex: self.index,
2024-01-16 11:20:34 +01:00
samples: samples)