Makes rootHash private to Manifest object. (#488)

* Makes rootHash private to Manifest object.

* Locks down all fields of Manifest.

* Review comments by Mark
This commit is contained in:
Ben Bierens 2023-07-19 16:06:59 +02:00 committed by GitHub
parent 3bb5960739
commit 6708202a5f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 136 additions and 44 deletions

View File

@ -26,7 +26,7 @@ import ../errors
import ../blocktype import ../blocktype
import ./types import ./types
func encode*(_: DagPBCoder, manifest: Manifest): ?!seq[byte] = proc encode*(_: DagPBCoder, manifest: Manifest): ?!seq[byte] =
## Encode the manifest into a ``ManifestCodec`` ## Encode the manifest into a ``ManifestCodec``
## multicodec container (Dag-pb) for now ## multicodec container (Dag-pb) for now
## ##
@ -60,7 +60,7 @@ func encode*(_: DagPBCoder, manifest: Manifest): ?!seq[byte] =
# ``` # ```
# #
let cid = !manifest.rootHash let cid = ? manifest.cid
var header = initProtoBuffer() var header = initProtoBuffer()
header.write(1, cid.data.buffer) header.write(1, cid.data.buffer)
header.write(2, manifest.blockSize.uint32) header.write(2, manifest.blockSize.uint32)
@ -145,22 +145,31 @@ func decode*(_: DagPBCoder, data: openArray[byte]): ?!Manifest =
if blocksLen.int != blocks.len: if blocksLen.int != blocks.len:
return failure("Total blocks and length of blocks in header don't match!") return failure("Total blocks and length of blocks in header don't match!")
var let
self = Manifest( self = if pbErasureInfo.buffer.len > 0:
rootHash: rootHashCid.some, Manifest.new(
originalBytes: originalBytes.NBytes, rootHash = rootHashCid,
blockSize: blockSize.NBytes, originalBytes = originalBytes.NBytes,
blocks: blocks, blockSize = blockSize.NBytes,
hcodec: (? rootHashCid.mhash.mapFailure).mcodec, blocks = blocks,
codec: rootHashCid.mcodec, version = rootHashCid.cidver,
version: rootHashCid.cidver, hcodec = (? rootHashCid.mhash.mapFailure).mcodec,
protected: pbErasureInfo.buffer.len > 0) codec = rootHashCid.mcodec,
ecK = ecK.int,
if self.protected: ecM = ecM.int,
self.ecK = ecK.int originalCid = ? Cid.init(originalCid).mapFailure,
self.ecM = ecM.int originalLen = originalLen.int
self.originalCid = ? Cid.init(originalCid).mapFailure )
self.originalLen = originalLen.int else:
Manifest.new(
rootHash = rootHashCid,
originalBytes = originalBytes.NBytes,
blockSize = blockSize.NBytes,
blocks = blocks,
version = rootHashCid.cidver,
hcodec = (? rootHashCid.mhash.mapFailure).mcodec,
codec = rootHashCid.mcodec
)
? self.verify() ? self.verify()
self.success self.success
@ -172,9 +181,6 @@ proc encode*(
## Encode a manifest using `encoder` ## Encode a manifest using `encoder`
## ##
if self.rootHash.isNone:
? self.makeRoot()
encoder.encode(self) encoder.encode(self)
func decode*( func decode*(

View File

@ -27,6 +27,58 @@ import ./types
export types export types
type
Manifest* = ref object of RootObj
rootHash: ?Cid # Root (tree) hash of the contained data set
originalBytes*: NBytes # Exact size of the original (uploaded) file
blockSize: NBytes # Size of each contained block (might not be needed if blocks are len-prefixed)
blocks: seq[Cid] # Block Cid
version: CidVersion # Cid version
hcodec: MultiCodec # Multihash codec
codec: MultiCodec # Data set codec
case protected: bool # Protected datasets have erasure coded info
of true:
ecK: int # Number of blocks to encode
ecM: int # Number of resulting parity blocks
originalCid: Cid # The original Cid of the dataset being erasure coded
originalLen: int # The length of the original manifest
else:
discard
############################################################
# Accessors
############################################################
proc blockSize*(self: Manifest): NBytes =
self.blockSize
proc blocks*(self: Manifest): seq[Cid] =
self.blocks
proc version*(self: Manifest): CidVersion =
self.version
proc hcodec*(self: Manifest): MultiCodec =
self.hcodec
proc codec*(self: Manifest): MultiCodec =
self.codec
proc protected*(self: Manifest): bool =
self.protected
proc ecK*(self: Manifest): int =
self.ecK
proc ecM*(self: Manifest): int =
self.ecM
proc originalCid*(self: Manifest): Cid =
self.originalCid
proc originalLen*(self: Manifest): int =
self.originalLen
############################################################ ############################################################
# Operations on block list # Operations on block list
############################################################ ############################################################
@ -233,3 +285,53 @@ proc new*(
## Create a manifest instance from given data ## Create a manifest instance from given data
## ##
Manifest.decode(data, decoder) Manifest.decode(data, decoder)
proc new*(
T: type Manifest,
rootHash: Cid,
originalBytes: NBytes,
blockSize: NBytes,
blocks: seq[Cid],
version: CidVersion,
hcodec: MultiCodec,
codec: MultiCodec,
ecK: int,
ecM: int,
originalCid: Cid,
originalLen: int
): Manifest =
Manifest(
rootHash: rootHash.some,
originalBytes: originalBytes,
blockSize: blockSize,
blocks: blocks,
version: version,
hcodec: hcodec,
codec: codec,
protected: true,
ecK: ecK,
ecM: ecM,
originalCid: originalCid,
originalLen: originalLen
)
proc new*(
T: type Manifest,
rootHash: Cid,
originalBytes: NBytes,
blockSize: NBytes,
blocks: seq[Cid],
version: CidVersion,
hcodec: MultiCodec,
codec: MultiCodec
): Manifest =
Manifest(
rootHash: rootHash.some,
originalBytes: originalBytes,
blockSize: blockSize,
blocks: blocks,
version: version,
hcodec: hcodec,
codec: codec,
protected: false,
)

View File

@ -28,21 +28,3 @@ const
ManifestContainers* = { ManifestContainers* = {
$DagPBCodec: DagPBCoder() $DagPBCodec: DagPBCoder()
}.toTable }.toTable
type
Manifest* = ref object of RootObj
rootHash*: ?Cid # Root (tree) hash of the contained data set
originalBytes*: NBytes # Exact size of the original (uploaded) file
blockSize*: NBytes # Size of each contained block (might not be needed if blocks are len-prefixed)
blocks*: seq[Cid] # Block Cid
version*: CidVersion # Cid version
hcodec*: MultiCodec # Multihash codec
codec*: MultiCodec # Data set codec
case protected*: bool # Protected datasets have erasure coded info
of true:
ecK*: int # Number of blocks to encode
ecM*: int # Number of resulting parity blocks
originalCid*: Cid # The original Cid of the dataset being erasure coded
originalLen*: int # The length of the original manifest
else:
discard

View File

@ -221,7 +221,7 @@ proc store*(
await stream.close() await stream.close()
# Generate manifest # Generate manifest
blockManifest.originalBytes = NBytes chunker.offset # store the exact file size blockManifest.originalBytes = NBytes(chunker.offset) # store the exact file size
without data =? blockManifest.encode(): without data =? blockManifest.encode():
return failure( return failure(
newException(CodexError, "Could not generate dataset manifest!")) newException(CodexError, "Could not generate dataset manifest!"))

View File

@ -62,6 +62,8 @@ checksuite "Manifest":
Block.new(("Block " & $it).toBytes).tryGet().cid Block.new(("Block " & $it).toBytes).tryGet().cid
) )
manifest = Manifest.new(blocks).tryGet() manifest = Manifest.new(blocks).tryGet()
var
protected = Manifest.new(manifest, 2, 2).tryGet() protected = Manifest.new(manifest, 2, 2).tryGet()
check: check:
@ -72,7 +74,7 @@ checksuite "Manifest":
# fill up with empty Cid's # fill up with empty Cid's
for i in protected.rounded..<protected.len: for i in protected.rounded..<protected.len:
protected.blocks[i] = EmptyCid[manifest.version] protected[i] = EmptyCid[manifest.version]
.catch .catch
.get()[manifest.hcodec] .get()[manifest.hcodec]
.catch .catch