167 lines
4.8 KiB
Nim
167 lines
4.8 KiB
Nim
import std/os
|
|
import std/options
|
|
import std/math
|
|
import std/times
|
|
import std/sequtils
|
|
import std/importutils
|
|
|
|
import pkg/chronos
|
|
import pkg/stew/byteutils
|
|
import pkg/datastore
|
|
import pkg/questionable
|
|
import pkg/questionable/results
|
|
import pkg/stint
|
|
import pkg/poseidon2
|
|
import pkg/poseidon2/io
|
|
|
|
import pkg/nitro
|
|
import pkg/codexdht/discv5/protocol as discv5
|
|
|
|
import pkg/codex/logutils
|
|
import pkg/codex/stores
|
|
import pkg/codex/clock
|
|
import pkg/codex/contracts
|
|
import pkg/codex/systemclock
|
|
import pkg/codex/blockexchange
|
|
import pkg/codex/chunker
|
|
import pkg/codex/slots
|
|
import pkg/codex/manifest
|
|
import pkg/codex/discovery
|
|
import pkg/codex/erasure
|
|
import pkg/codex/merkletree
|
|
import pkg/codex/blocktype as bt
|
|
|
|
import pkg/codex/node {.all.}
|
|
|
|
import ../../asynctest
|
|
import ../examples
|
|
import ../helpers
|
|
import ../helpers/mockmarket
|
|
import ../helpers/mockclock
|
|
|
|
import ./helpers
|
|
|
|
privateAccess(CodexNodeRef) # enable access to private fields
|
|
|
|
asyncchecksuite "Test Node - Basic":
|
|
setupAndTearDown()
|
|
|
|
test "Fetch Manifest":
|
|
let
|
|
manifest = await storeDataGetManifest(localStore, chunker)
|
|
|
|
manifestBlock = bt.Block.new(
|
|
manifest.encode().tryGet(),
|
|
codec = ManifestCodec).tryGet()
|
|
|
|
(await localStore.putBlock(manifestBlock)).tryGet()
|
|
|
|
let
|
|
fetched = (await node.fetchManifest(manifestBlock.cid)).tryGet()
|
|
|
|
check:
|
|
fetched == manifest
|
|
|
|
test "Should not lookup non-existing blocks twice":
|
|
# https://github.com/codex-storage/nim-codex/issues/699
|
|
let
|
|
cstore = CountingStore.new(engine, localStore)
|
|
node = CodexNodeRef.new(switch, cstore, engine, blockDiscovery)
|
|
missingCid = Cid.init(
|
|
"zDvZRwzmCvtiyubW9AecnxgLnXK8GrBvpQJBDzToxmzDN6Nrc2CZ").get()
|
|
|
|
engine.blockFetchTimeout = timer.milliseconds(100)
|
|
|
|
discard await node.retrieve(missingCid, local = false)
|
|
|
|
let lookupCount = cstore.lookups.getOrDefault(missingCid)
|
|
check lookupCount == 1
|
|
|
|
test "Block Batching":
|
|
let manifest = await storeDataGetManifest(localStore, chunker)
|
|
|
|
for batchSize in 1..12:
|
|
(await node.fetchBatched(
|
|
manifest,
|
|
batchSize = batchSize,
|
|
proc(blocks: seq[bt.Block]): Future[?!void] {.gcsafe, async.} =
|
|
check blocks.len > 0 and blocks.len <= batchSize
|
|
return success()
|
|
)).tryGet()
|
|
|
|
test "Store and retrieve Data Stream":
|
|
let
|
|
stream = BufferStream.new()
|
|
storeFut = node.store(stream)
|
|
oddChunkSize = math.trunc(DefaultBlockSize.float / 3.14).NBytes # Let's check that node.store can correctly rechunk these odd chunks
|
|
oddChunker = FileChunker.new(file = file, chunkSize = oddChunkSize, pad = false) # TODO: doesn't work with pad=tue
|
|
|
|
var
|
|
original: seq[byte]
|
|
|
|
try:
|
|
while (
|
|
let chunk = await oddChunker.getBytes();
|
|
chunk.len > 0):
|
|
original &= chunk
|
|
await stream.pushData(chunk)
|
|
finally:
|
|
await stream.pushEof()
|
|
await stream.close()
|
|
|
|
let
|
|
manifestCid = (await storeFut).tryGet()
|
|
manifestBlock = (await localStore.getBlock(manifestCid)).tryGet()
|
|
localManifest = Manifest.decode(manifestBlock).tryGet()
|
|
data = await (await node.retrieve(manifestCid)).drain()
|
|
|
|
check:
|
|
data.len == localManifest.datasetSize.int
|
|
data.len == original.len
|
|
sha256.digest(data) == sha256.digest(original)
|
|
|
|
test "Retrieve One Block":
|
|
let
|
|
testString = "Block 1"
|
|
blk = bt.Block.new(testString.toBytes).tryGet()
|
|
|
|
(await localStore.putBlock(blk)).tryGet()
|
|
let stream = (await node.retrieve(blk.cid)).tryGet()
|
|
defer: await stream.close()
|
|
|
|
var data = newSeq[byte](testString.len)
|
|
await stream.readExactly(addr data[0], data.len)
|
|
check string.fromBytes(data) == testString
|
|
|
|
test "Setup purchase request":
|
|
let
|
|
erasure = Erasure.new(store, leoEncoderProvider, leoDecoderProvider)
|
|
manifest = await storeDataGetManifest(localStore, chunker)
|
|
manifestBlock = bt.Block.new(
|
|
manifest.encode().tryGet(),
|
|
codec = ManifestCodec).tryGet()
|
|
protected = (await erasure.encode(manifest, 3, 2)).tryGet()
|
|
builder = Poseidon2Builder.new(localStore, protected).tryGet()
|
|
verifiable = (await builder.buildManifest()).tryGet()
|
|
verifiableBlock = bt.Block.new(
|
|
verifiable.encode().tryGet(),
|
|
codec = ManifestCodec).tryGet()
|
|
|
|
(await localStore.putBlock(manifestBlock)).tryGet()
|
|
|
|
let
|
|
request = (await node.setupRequest(
|
|
cid = manifestBlock.cid,
|
|
nodes = 5,
|
|
tolerance = 2,
|
|
duration = 100.u256,
|
|
reward = 2.u256,
|
|
proofProbability = 3.u256,
|
|
expiry = 200.u256,
|
|
collateral = 200.u256)).tryGet
|
|
|
|
check:
|
|
(await verifiableBlock.cid in localStore) == true
|
|
request.content.cid == $verifiableBlock.cid
|
|
request.content.merkleRoot == builder.verifyRoot.get.toBytes
|