122 lines
3.3 KiB
Nim
122 lines
3.3 KiB
Nim
import std/tables
|
|
import std/times
|
|
|
|
import pkg/libp2p
|
|
import pkg/chronos
|
|
|
|
import pkg/codex/codextypes
|
|
import pkg/codex/chunker
|
|
import pkg/codex/stores
|
|
import pkg/codex/slots
|
|
|
|
import ../../asynctest
|
|
|
|
type CountingStore* = ref object of NetworkStore
|
|
lookups*: Table[Cid, int]
|
|
|
|
proc new*(T: type CountingStore,
|
|
engine: BlockExcEngine, localStore: BlockStore): CountingStore =
|
|
# XXX this works cause NetworkStore.new is trivial
|
|
result = CountingStore(engine: engine, localStore: localStore)
|
|
|
|
method getBlock*(self: CountingStore,
|
|
address: BlockAddress): Future[?!Block] {.async.} =
|
|
|
|
self.lookups.mgetOrPut(address.cid, 0).inc
|
|
await procCall getBlock(NetworkStore(self), address)
|
|
|
|
proc toTimesDuration*(d: chronos.Duration): times.Duration =
|
|
initDuration(seconds = d.seconds)
|
|
|
|
proc drain*(
|
|
stream: LPStream | Result[lpstream.LPStream, ref CatchableError]):
|
|
Future[seq[byte]] {.async.} =
|
|
|
|
let
|
|
stream =
|
|
when typeof(stream) is Result[lpstream.LPStream, ref CatchableError]:
|
|
stream.tryGet()
|
|
else:
|
|
stream
|
|
|
|
defer:
|
|
await stream.close()
|
|
|
|
var data: seq[byte]
|
|
while not stream.atEof:
|
|
var
|
|
buf = newSeq[byte](DefaultBlockSize.int)
|
|
res = await stream.readOnce(addr buf[0], DefaultBlockSize.int)
|
|
check res <= DefaultBlockSize.int
|
|
buf.setLen(res)
|
|
data &= buf
|
|
|
|
data
|
|
|
|
proc pipeChunker*(stream: BufferStream, chunker: Chunker) {.async.} =
|
|
try:
|
|
while (
|
|
let chunk = await chunker.getBytes();
|
|
chunk.len > 0):
|
|
await stream.pushData(chunk)
|
|
finally:
|
|
await stream.pushEof()
|
|
await stream.close()
|
|
|
|
template setupAndTearDown*() {.dirty.} =
|
|
var
|
|
file: File
|
|
chunker: Chunker
|
|
switch: Switch
|
|
wallet: WalletRef
|
|
network: BlockExcNetwork
|
|
clock: Clock
|
|
localStore: RepoStore
|
|
localStoreRepoDs: DataStore
|
|
localStoreMetaDs: DataStore
|
|
engine: BlockExcEngine
|
|
store: NetworkStore
|
|
node: CodexNodeRef
|
|
blockDiscovery: Discovery
|
|
peerStore: PeerCtxStore
|
|
pendingBlocks: PendingBlocksManager
|
|
discovery: DiscoveryEngine
|
|
|
|
let
|
|
path = currentSourcePath().parentDir
|
|
|
|
setup:
|
|
file = open(path /../ "" /../ "fixtures" / "test.jpg")
|
|
chunker = FileChunker.new(file = file, chunkSize = DefaultBlockSize)
|
|
switch = newStandardSwitch()
|
|
wallet = WalletRef.new(EthPrivateKey.random())
|
|
network = BlockExcNetwork.new(switch)
|
|
|
|
clock = SystemClock.new()
|
|
localStoreMetaDs = SQLiteDatastore.new(Memory).tryGet()
|
|
localStoreRepoDs = SQLiteDatastore.new(Memory).tryGet()
|
|
localStore = RepoStore.new(localStoreRepoDs, localStoreMetaDs, clock = clock)
|
|
await localStore.start()
|
|
|
|
blockDiscovery = Discovery.new(
|
|
switch.peerInfo.privateKey,
|
|
announceAddrs = @[MultiAddress.init("/ip4/127.0.0.1/tcp/0")
|
|
.expect("Should return multiaddress")])
|
|
peerStore = PeerCtxStore.new()
|
|
pendingBlocks = PendingBlocksManager.new()
|
|
discovery = DiscoveryEngine.new(localStore, peerStore, network, blockDiscovery, pendingBlocks)
|
|
engine = BlockExcEngine.new(localStore, wallet, network, discovery, peerStore, pendingBlocks)
|
|
store = NetworkStore.new(engine, localStore)
|
|
node = CodexNodeRef.new(
|
|
switch = switch,
|
|
networkStore = store,
|
|
engine = engine,
|
|
prover = Prover.none,
|
|
discovery = blockDiscovery)
|
|
|
|
await node.start()
|
|
|
|
teardown:
|
|
close(file)
|
|
await node.stop()
|