From fabd2e20a8f71d7bb7e326b509478a8cfab8a2a7 Mon Sep 17 00:00:00 2001 From: benbierens Date: Fri, 1 Dec 2023 08:49:36 +0100 Subject: [PATCH] wip --- codex/manifest/manifest.nim | 6 ++ codex/slotbuilder/slotbuilder.nim | 96 ++++++++++++++++++++- codex/stores/blockstore.nim | 5 ++ codex/stores/repostore.nim | 2 +- tests/codex/slotbuilder/testslotbuilder.nim | 22 ++++- 5 files changed, 123 insertions(+), 8 deletions(-) diff --git a/codex/manifest/manifest.nim b/codex/manifest/manifest.nim index fcc2a704..a9b97c83 100644 --- a/codex/manifest/manifest.nim +++ b/codex/manifest/manifest.nim @@ -46,6 +46,12 @@ type else: discard + # WIP: + isSlot* {.serialize.}: bool + datasetSlotIndex*: int + originalProtectedTreeCid*: Cid + originalProtectedDatasetSize*: NBytes + ############################################################ # Accessors ############################################################ diff --git a/codex/slotbuilder/slotbuilder.nim b/codex/slotbuilder/slotbuilder.nim index fe0d6126..c2e02b04 100644 --- a/codex/slotbuilder/slotbuilder.nim +++ b/codex/slotbuilder/slotbuilder.nim @@ -1,7 +1,8 @@ import pkg/libp2p +import pkg/chronos +import pkg/chronicles import pkg/questionable/results -import pkg/codex/blocktype as bt -import ../blocktype +import ../merkletree import ../stores import ../manifest @@ -30,6 +31,93 @@ proc new*( numberOfSlotBlocks: numberOfSlotBlocks )) -proc getSlotBlocks*(self: SlotBuilder, datasetSlotIndex: uint64): seq[bt.Block] = - raiseAssert("a") +proc getTreeLeaf(self: SlotBuilder, datasetTreeCid: Cid, datasetBlockIndex: int): Future[?!MultiHash] {.async.} = + without slotBlockCid =? await self.blockStore.getCid(datasetTreeCid, datasetBlockIndex), err: + error "Failed to get block for tree at index", index=datasetBlockIndex, tree=datasetTreeCid + return failure(err) + without slotBlockLeaf =? slotBlockCid.mhash: + error "Failed to get multihash from slot block CID", slotBlockCid + return failure("Failed to get multihash from slot block CID") + + return success(slotBlockLeaf) + +proc createAndSaveSlotTree(self: SlotBuilder, datasetSlotIndex: int): Future[?!MerkleTree] {.async.} = + without var builder =? MerkleTreeBuilder.init(), err: + return failure(err) + + let + datasetTreeCid = self.manifest.treeCid + datasetBlockIndexStart = datasetSlotIndex * self.numberOfSlotBlocks + datasetBlockIndexEnd = datasetBlockIndexStart + self.numberOfSlotBlocks + + for index in datasetBlockIndexStart ..< datasetBlockIndexEnd: + without slotBlockLeaf =? await self.getTreeLeaf(datasetTreeCid, index), err: + return failure(err) + if builder.addLeaf(slotBlockLeaf).isErr: + error "Failed to add slotBlockCid to slot tree builder" + return failure("Failed to add slotBlockCid to slot tree builder") + + without slotTree =? builder.build(), err: + error "Failed to build slot tree" + return failure(err) + + if (await self.blockStore.putAllProofs(slotTree)).isErr: + error "Failed to store slot tree" + return failure("Failed to store slot tree") + + return success(slotTree) + +proc createSlotManifest*(self: SlotBuilder, datasetSlotIndex: int): Future[?!Manifest] {.async.} = + without slotTree =? await self.createAndSaveSlotTree(datasetSlotIndex), err: + error "Failed to create slot tree" + return failure(err) + + without slotTreeRootCid =? slotTree.rootCid, err: + error "Failed to get root CID from slot tree" + return failure(err) + + var slotManifest = Manifest.new( + treeCid = slotTreeRootCid, + datasetSize = self.numberOfSlotBlocks.NBytes * self.manifest.blockSize, + blockSize = self.manifest.blockSize, + version = self.manifest.version, + hcodec = self.manifest.hcodec, + codec = self.manifest.codec, + ecK = self.manifest.ecK, # should change this = EC params of first ECing. there's be another! + ecM = self.manifest.ecK, + originalTreeCid = self.manifest.originalTreeCid, + originalDatasetSize = self.manifest.originalDatasetSize + ) + + #treeCid: Cid + # datasetSize: NBytes + # blockSize: NBytes + # version: CidVersion + # hcodec: MultiCodec + # codex: MultiCodec + # ecK: int + # ecM: int + # originalTreeCid: Cid + # originalDatasetSize: NBytes + +# treeCid: Cid +# datasetSize: NBytes +# blockSize: NBytes +# version: CidVersion +# hcodec: MultiCodec +# codec: MultiCodec +# ecK: int +# ecM: int +# originalTreeCid: Cid +# originalDatasetSize: NBytes): Manifest +# first type mismatch at position: 7 + + + + slotManifest.isSlot = true + slotManifest.datasetSlotIndex = datasetSlotIndex + slotManifest.originalProtectedTreeCid = self.manifest.treeCid + slotManifest.originalProtectedDatasetSize = self.manifest.datasetSize + + return success(slotManifest) diff --git a/codex/stores/blockstore.nim b/codex/stores/blockstore.nim index 80c7bde2..ac646d80 100644 --- a/codex/stores/blockstore.nim +++ b/codex/stores/blockstore.nim @@ -43,6 +43,11 @@ method getBlock*(self: BlockStore, treeCid: Cid, index: Natural): Future[?!Block raiseAssert("getBlock by treecid not implemented!") +method getCid*(self: BlockStore, treeCid: Cid, index: Natural): Future[?!Cid] {.base.} = + ## Get a cid given a tree and index + ## + raiseAssert("getCid by treecid not implemented!") + method getBlock*(self: BlockStore, address: BlockAddress): Future[?!Block] {.base.} = ## Get a block from the blockstore ## diff --git a/codex/stores/repostore.nim b/codex/stores/repostore.nim index c91263b2..5833dac4 100644 --- a/codex/stores/repostore.nim +++ b/codex/stores/repostore.nim @@ -146,7 +146,7 @@ proc getCidAndProof( trace "Got cid and proof for block", cid, proof = $proof return success (cid, proof) -proc getCid( +method getCid*( self: RepoStore, treeCid: Cid, index: Natural): Future[?!Cid] {.async.} = diff --git a/tests/codex/slotbuilder/testslotbuilder.nim b/tests/codex/slotbuilder/testslotbuilder.nim index 20d1da4a..742a254c 100644 --- a/tests/codex/slotbuilder/testslotbuilder.nim +++ b/tests/codex/slotbuilder/testslotbuilder.nim @@ -90,12 +90,28 @@ asyncchecksuite "Slot builder": SlotBuilder.new(localStore, mismatchManifest).isErr for i in 0 ..< numberOfSlots: - test "Can get the protected slot blocks given a slot index (" & $i & ")": + test "Can create slot manifest given index (" & $i & ")": let selectStart = i * numberOfSlotBlocks selectEnd = selectStart + numberOfSlotBlocks expectedCids = datasetBlocks.mapIt(it.cid)[selectStart ..< selectEnd] - blocks = slotBuilder.getSlotBlocks(i.uint64) + m = (await slotBuilder.createSlotIntermediateManifest(i)).tryGet() check: - blocks.mapIt(it.cid) == expectedCids + m.treeCid # check + m.datasetSize == (numberOfSlotBlocks * blockSize).NBytes + m.blockSize == blockSize + m.version == manifest.version + m.hcodec == manifest.hcodec + m.codec == manifest.codec + #m.ecK == ?? + #m.ecM == ?? + m.originalTreeCid == manifest.originalTreeCid + m.originalDatasetSize = manifest.originalDatasetSize + + m.isSlot == true + m.datasetSlotIndex == i + m.originalProtectedTreeCide == manifest.treeCid + m.originalProtectedDatasetSize == manifest.datasetSize + +