Block.init should return Result (#37)

* Block.init should return Result

* use get() instead of tryGet()
This commit is contained in:
Dmitriy Ryajov 2022-01-10 20:25:13 -06:00 committed by GitHub
parent 9d17c91d4c
commit a9721dd65f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 92 additions and 68 deletions

View File

@ -131,7 +131,7 @@ proc broadcastWantList*(
proc handleBlocks( proc handleBlocks(
b: BlockExcNetwork, b: BlockExcNetwork,
peer: NetworkPeer, peer: NetworkPeer,
blocks: seq[auto]): Future[void] = blocks: seq[pb.Block]): Future[void] =
## Handle incoming blocks ## Handle incoming blocks
## ##
@ -141,13 +141,14 @@ proc handleBlocks(
trace "Handling blocks for peer", peer = peer.id trace "Handling blocks for peer", peer = peer.id
var blks: seq[bt.Block] var blks: seq[bt.Block]
for blk in blocks: for blob in blocks:
when blk is pb.Block: without cid =? Cid.init(blob.prefix):
blks.add(bt.Block.init(Cid.init(blk.prefix).get(), blk.data)) trace "Unable to initialize Cid from protobuf message"
elif blk is seq[byte]:
blks.add(bt.Block.init(Cid.init(blk).get(), blk)) without blk =? bt.Block.init(cid, blob.data, verify = true):
else: trace "Unable to initialize Block from data"
error("Invalid block type")
blks.add(blk)
b.handlers.onBlocks(peer.id, blks) b.handlers.onBlocks(peer.id, blks)

View File

@ -11,6 +11,10 @@
import pkg/libp2p import pkg/libp2p
import pkg/stew/byteutils import pkg/stew/byteutils
import pkg/questionable
import pkg/questionable/results
import ./errors
type type
Block* = object of RootObj Block* = object of RootObj
@ -25,18 +29,32 @@ func init*(
T: type Block, T: type Block,
data: openArray[byte] = [], data: openArray[byte] = [],
version = CIDv1, version = CIDv1,
hcodec = multiCodec("sha2-256"), mcodec = multiCodec("sha2-256"),
codec = multiCodec("raw")): T = codec = multiCodec("raw")): ?!T =
let hash = MultiHash.digest($hcodec, data).get()
Block( let
cid: Cid.init(version, codec, hash).get(), hash = ? MultiHash.digest($mcodec, data).mapFailure
cid = ? Cid.init(version, codec, hash).mapFailure
success Block(
cid: cid,
data: @data) data: @data)
func init*( func init*(
T: type Block, T: type Block,
cid: Cid, cid: Cid,
data: openArray[byte] = [], data: openArray[byte],
verify: bool = false): T = verify: bool = false): ?!T =
Block(
cid: cid, let
data: @data) mhash = ? cid.mhash.mapFailure
b = ? Block.init(
data = @data,
version = cid.cidver,
codec = cid.mcodec,
mcodec = mhash.mcodec)
if verify and cid != b.cid:
return failure "Cid's don't match!"
success b

View File

@ -133,8 +133,8 @@ proc store*(
chunk.len > 0): chunk.len > 0):
trace "Got data from stream", len = chunk.len trace "Got data from stream", len = chunk.len
let without blk =? bt.Block.init(chunk):
blk = bt.Block.init(chunk) return failure("Unable to init block from chunk!")
blockManifest.put(blk.cid) blockManifest.put(blk.cid)
if not (await node.blockStore.putBlock(blk)): if not (await node.blockStore.putBlock(blk)):
@ -154,7 +154,10 @@ proc store*(
newException(DaggerError, "Could not generate dataset manifest!")) newException(DaggerError, "Could not generate dataset manifest!"))
# Store as a dag-pb block # Store as a dag-pb block
let manifest = bt.Block.init(data = data, codec = ManifestCodec) without manifest =? bt.Block.init(data = data, codec = ManifestCodec):
trace "Unable to init block from manifest data!"
return failure("Unable to init block from manifest data!")
if not (await node.blockStore.putBlock(manifest)): if not (await node.blockStore.putBlock(manifest)):
trace "Unable to store manifest", cid = manifest.cid trace "Unable to store manifest", cid = manifest.cid
return failure("Unable to store manifest " & $manifest.cid) return failure("Unable to store manifest " & $manifest.cid)
@ -165,8 +168,8 @@ proc store*(
return failure(cid.error.msg) return failure(cid.error.msg)
trace "Stored data", manifestCid = manifest.cid, trace "Stored data", manifestCid = manifest.cid,
contentCid = !cid, contentCid = !cid,
blocks = blockManifest.len blocks = blockManifest.len
return manifest.cid.success return manifest.cid.success

View File

@ -54,7 +54,7 @@ method getBlock*(
trace "Cannot read file from fs store", path , error trace "Cannot read file from fs store", path , error
return Block.failure("Cannot read file from fs store") return Block.failure("Cannot read file from fs store")
return Block.init(cid, data).success return Block.init(cid, data)
method putBlock*( method putBlock*(
self: FSStore, self: FSStore,

View File

@ -41,14 +41,14 @@ suite "NetworkStore engine - 2 nodes":
if chunk.len <= 0: if chunk.len <= 0:
break break
blocks1.add(bt.Block.init(chunk)) blocks1.add(bt.Block.init(chunk).get())
while true: while true:
let chunk = await chunker2.getBytes() let chunk = await chunker2.getBytes()
if chunk.len <= 0: if chunk.len <= 0:
break break
blocks2.add(bt.Block.init(chunk)) blocks2.add(bt.Block.init(chunk).get())
switch1 = newStandardSwitch() switch1 = newStandardSwitch()
switch2 = newStandardSwitch() switch2 = newStandardSwitch()
@ -119,7 +119,7 @@ suite "NetworkStore engine - 2 nodes":
check peerCtx2.account.?address == pricing2.address.some check peerCtx2.account.?address == pricing2.address.some
test "should send want-have for block": test "should send want-have for block":
let blk = bt.Block.init("Block 1".toBytes) let blk = bt.Block.init("Block 1".toBytes).get()
check await blockexc2.engine.localStore.putBlock(blk) check await blockexc2.engine.localStore.putBlock(blk)
let entry = Entry( let entry = Entry(
@ -144,7 +144,7 @@ suite "NetworkStore engine - 2 nodes":
check blocks.mapIt( !it.read ) == blocks2 check blocks.mapIt( !it.read ) == blocks2
test "remote should send blocks when available": test "remote should send blocks when available":
let blk = bt.Block.init("Block 1".toBytes) let blk = bt.Block.init("Block 1".toBytes).get()
# should fail retrieving block from remote # should fail retrieving block from remote
check not await blockexc1.getBlock(blk.cid) check not await blockexc1.getBlock(blk.cid)
@ -183,7 +183,7 @@ suite "NetworkStore - multiple nodes":
if chunk.len <= 0: if chunk.len <= 0:
break break
blocks.add(bt.Block.init(chunk)) blocks.add(bt.Block.init(chunk).get())
for e in generateNodes(5): for e in generateNodes(5):
switch.add(e.switch) switch.add(e.switch)

View File

@ -20,8 +20,8 @@ import ../examples
suite "NetworkStore engine basic": suite "NetworkStore engine basic":
let let
rng = Rng.instance() rng = Rng.instance()
seckey = PrivateKey.random(rng[]).tryGet() seckey = PrivateKey.random(rng[]).get()
peerId = PeerID.init(seckey.getPublicKey().tryGet()).tryGet() peerId = PeerID.init(seckey.getPublicKey().get()).get()
chunker = RandomChunker.new(Rng.instance(), size = 1024, chunkSize = 256) chunker = RandomChunker.new(Rng.instance(), size = 1024, chunkSize = 256)
wallet = WalletRef.example wallet = WalletRef.example
@ -35,7 +35,7 @@ suite "NetworkStore engine basic":
if chunk.len <= 0: if chunk.len <= 0:
break break
blocks.add(bt.Block.init(chunk)) blocks.add(bt.Block.init(chunk).get())
done = newFuture[void]() done = newFuture[void]()
@ -87,8 +87,8 @@ suite "NetworkStore engine basic":
suite "NetworkStore engine handlers": suite "NetworkStore engine handlers":
let let
rng = Rng.instance() rng = Rng.instance()
seckey = PrivateKey.random(rng[]).tryGet() seckey = PrivateKey.random(rng[]).get()
peerId = PeerID.init(seckey.getPublicKey().tryGet()).tryGet() peerId = PeerID.init(seckey.getPublicKey().get()).get()
chunker = RandomChunker.new(Rng.instance(), size = 1024, chunkSize = 256) chunker = RandomChunker.new(Rng.instance(), size = 1024, chunkSize = 256)
wallet = WalletRef.example wallet = WalletRef.example
@ -104,7 +104,7 @@ suite "NetworkStore engine handlers":
if chunk.len <= 0: if chunk.len <= 0:
break break
blocks.add(bt.Block.init(chunk)) blocks.add(bt.Block.init(chunk).get())
done = newFuture[void]() done = newFuture[void]()
engine = BlockExcEngine.new(MemoryStore.new(), wallet, BlockExcNetwork()) engine = BlockExcEngine.new(MemoryStore.new(), wallet, BlockExcNetwork())
@ -228,15 +228,15 @@ suite "Task Handler":
if chunk.len <= 0: if chunk.len <= 0:
break break
blocks.add(bt.Block.init(chunk)) blocks.add(bt.Block.init(chunk).get())
done = newFuture[void]() done = newFuture[void]()
engine = BlockExcEngine.new(MemoryStore.new(), wallet, BlockExcNetwork()) engine = BlockExcEngine.new(MemoryStore.new(), wallet, BlockExcNetwork())
peersCtx = @[] peersCtx = @[]
for i in 0..3: for i in 0..3:
let seckey = PrivateKey.random(rng[]).tryGet() let seckey = PrivateKey.random(rng[]).get()
peers.add(PeerID.init(seckey.getPublicKey().tryGet()).tryGet()) peers.add(PeerID.init(seckey.getPublicKey().get()).get())
peersCtx.add(BlockExcPeerCtx( peersCtx.add(BlockExcPeerCtx(
id: peers[i] id: peers[i]
@ -282,7 +282,7 @@ suite "Task Handler":
test "Should send presence": test "Should send presence":
let present = blocks let present = blocks
let missing = @[bt.Block.init("missing".toBytes)] let missing = @[bt.Block.init("missing".toBytes).get()]
let price = (!engine.pricing).price let price = (!engine.pricing).price
proc sendPresence(id: PeerID, presence: seq[BlockPresence]) = proc sendPresence(id: PeerID, presence: seq[BlockPresence]) =

View File

@ -20,8 +20,8 @@ import ../examples
suite "NetworkStore network": suite "NetworkStore network":
let let
rng = Rng.instance() rng = Rng.instance()
seckey = PrivateKey.random(rng[]).tryGet() seckey = PrivateKey.random(rng[]).get()
peerId = PeerID.init(seckey.getPublicKey().tryGet()).tryGet() peerId = PeerID.init(seckey.getPublicKey().get()).get()
chunker = RandomChunker.new(Rng.instance(), size = 1024, chunkSize = 256) chunker = RandomChunker.new(Rng.instance(), size = 1024, chunkSize = 256)
var var
@ -40,7 +40,7 @@ suite "NetworkStore network":
if chunk.len <= 0: if chunk.len <= 0:
break break
blocks.add(bt.Block.init(chunk)) blocks.add(bt.Block.init(chunk).get())
done = newFuture[void]() done = newFuture[void]()
buffer = BufferStream.new() buffer = BufferStream.new()
@ -156,7 +156,7 @@ suite "NetworkStore Network - e2e":
if chunk.len <= 0: if chunk.len <= 0:
break break
blocks.add(bt.Block.init(chunk)) blocks.add(bt.Block.init(chunk).get())
done = newFuture[void]() done = newFuture[void]()
switch1 = newStandardSwitch() switch1 = newStandardSwitch()

View File

@ -42,7 +42,7 @@ proc example*(_: type Pricing): Pricing =
proc example*(_: type Block): Block = proc example*(_: type Block): Block =
let length = rand(4096) let length = rand(4096)
let bytes = newSeqWith(length, rand(uint8)) let bytes = newSeqWith(length, rand(uint8))
Block.init(bytes) Block.init(bytes).get()
proc example*(_: type PeerId): PeerID = proc example*(_: type PeerId): PeerID =
let key = PrivateKey.random(Rng.instance[]).get let key = PrivateKey.random(Rng.instance[]).get

View File

@ -23,7 +23,7 @@ suite "FS Store":
var var
store: FSStore store: FSStore
repoDir: string repoDir: string
newBlock = Block.init("New Block".toBytes()) newBlock = Block.init("New Block".toBytes()).get()
setup: setup:
repoDir = path.parentDir / "repo" repoDir = path.parentDir / "repo"

View File

@ -15,7 +15,7 @@ import ../helpers
suite "Memory Store tests": suite "Memory Store tests":
test "putBlock": test "putBlock":
let let
newBlock = Block.init("New Block".toBytes()) newBlock = Block.init("New Block".toBytes()).get()
store = MemoryStore.new() store = MemoryStore.new()
check await store.putBlock(newBlock) check await store.putBlock(newBlock)
@ -23,7 +23,7 @@ suite "Memory Store tests":
test "getBlock": test "getBlock":
let let
newBlock = Block.init("New Block".toBytes()) newBlock = Block.init("New Block".toBytes()).get()
store = MemoryStore.new(@[newBlock]) store = MemoryStore.new(@[newBlock])
let blk = await store.getBlock(newBlock.cid) let blk = await store.getBlock(newBlock.cid)
@ -32,7 +32,7 @@ suite "Memory Store tests":
test "fail getBlock": test "fail getBlock":
let let
newBlock = Block.init("New Block".toBytes()) newBlock = Block.init("New Block".toBytes()).get()
store = MemoryStore.new(@[]) store = MemoryStore.new(@[])
let blk = await store.getBlock(newBlock.cid) let blk = await store.getBlock(newBlock.cid)
@ -40,21 +40,21 @@ suite "Memory Store tests":
test "hasBlock": test "hasBlock":
let let
newBlock = Block.init("New Block".toBytes()) newBlock = Block.init("New Block".toBytes()).get()
store = MemoryStore.new(@[newBlock]) store = MemoryStore.new(@[newBlock])
check store.hasBlock(newBlock.cid) check store.hasBlock(newBlock.cid)
test "fail hasBlock": test "fail hasBlock":
let let
newBlock = Block.init("New Block".toBytes()) newBlock = Block.init("New Block".toBytes()).get()
store = MemoryStore.new(@[]) store = MemoryStore.new(@[])
check not store.hasBlock(newBlock.cid) check not store.hasBlock(newBlock.cid)
test "delBlock": test "delBlock":
let let
newBlock = Block.init("New Block".toBytes()) newBlock = Block.init("New Block".toBytes()).get()
store = MemoryStore.new(@[newBlock]) store = MemoryStore.new(@[newBlock])
check await store.delBlock(newBlock.cid) check await store.delBlock(newBlock.cid)

View File

@ -17,13 +17,13 @@ suite "Manifest":
test "Should produce valid tree hash checksum": test "Should produce valid tree hash checksum":
without var manifest =? BlocksManifest.init( without var manifest =? BlocksManifest.init(
blocks = @[ blocks = @[
Block.init("Block 1".toBytes).cid, Block.init("Block 1".toBytes).get().cid,
Block.init("Block 2".toBytes).cid, Block.init("Block 2".toBytes).get().cid,
Block.init("Block 3".toBytes).cid, Block.init("Block 3".toBytes).get().cid,
Block.init("Block 4".toBytes).cid, Block.init("Block 4".toBytes).get().cid,
Block.init("Block 5".toBytes).cid, Block.init("Block 5".toBytes).get().cid,
Block.init("Block 6".toBytes).cid, Block.init("Block 6".toBytes).get().cid,
Block.init("Block 7".toBytes).cid, Block.init("Block 7".toBytes).get().cid,
]): ]):
fail() fail()
@ -42,7 +42,9 @@ suite "Manifest":
test "Should encode/decode to/from manifest": test "Should encode/decode to/from manifest":
let let
blocks = (0..<1000).mapIt( Block.init(("Block " & $it).toBytes).cid ) blocks = (0..<1000).mapIt(
Block.init(("Block " & $it).toBytes).get().cid
)
var var
manifest = BlocksManifest.init(blocks).get() manifest = BlocksManifest.init(blocks).get()

View File

@ -56,27 +56,27 @@ suite "Test Node":
storeFut = node.store(stream) storeFut = node.store(stream)
var var
manifest = BlocksManifest.init().tryGet() manifest = BlocksManifest.init().get()
try: try:
while ( while (
let chunk = await chunker.getBytes(); let chunk = await chunker.getBytes();
chunk.len > 0): chunk.len > 0):
await stream.pushData(chunk) await stream.pushData(chunk)
manifest.put(bt.Block.init(chunk).cid) manifest.put(bt.Block.init(chunk).get().cid)
finally: finally:
await stream.pushEof() await stream.pushEof()
await stream.close() await stream.close()
let let
manifestCid = (await storeFut).tryGet() manifestCid = (await storeFut).get()
check: check:
manifestCid in localStore manifestCid in localStore
var var
manifestBlock = (await localStore.getBlock(manifestCid)).get() manifestBlock = (await localStore.getBlock(manifestCid)).get()
localManifest = BlocksManifest.init(manifestBlock).tryGet() localManifest = BlocksManifest.init(manifestBlock).get()
check: check:
manifest.len == localManifest.len manifest.len == localManifest.len
@ -84,7 +84,7 @@ suite "Test Node":
test "Retrieve Data Stream": test "Retrieve Data Stream":
var var
manifest = BlocksManifest.init().tryGet() manifest = BlocksManifest.init().get()
original: seq[byte] original: seq[byte]
while ( while (
@ -92,7 +92,7 @@ suite "Test Node":
chunk.len > 0): chunk.len > 0):
let let
blk = bt.Block.init(chunk) blk = bt.Block.init(chunk).get()
original &= chunk original &= chunk
check await localStore.putBlock(blk) check await localStore.putBlock(blk)
@ -100,8 +100,8 @@ suite "Test Node":
let let
manifestBlock = bt.Block.init( manifestBlock = bt.Block.init(
manifest.encode().tryGet(), manifest.encode().get(),
codec = ManifestCodec) codec = ManifestCodec).get()
check await localStore.putBlock(manifestBlock) check await localStore.putBlock(manifestBlock)
@ -125,7 +125,7 @@ suite "Test Node":
test "Retrieve One Block": test "Retrieve One Block":
let let
testString = "Block 1" testString = "Block 1"
blk = bt.Block.init(testString.toBytes) blk = bt.Block.init(testString.toBytes).get()
var var
stream = BufferStream.new() stream = BufferStream.new()