nim-codex/codex/storageproofs/stpstore.nim

122 lines
3.1 KiB
Nim

## Nim-Dagger
## Copyright (c) 2022 Status Research & Development GmbH
## Licensed under either of
## * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE))
## * MIT license ([LICENSE-MIT](LICENSE-MIT))
## at your option.
## This file may not be copied, modified, or distributed except according to
## those terms.
import std/os
import std/strformat
import pkg/libp2p
import pkg/chronos
import pkg/chronicles
import pkg/stew/io2
import pkg/questionable
import pkg/questionable/results
import pkg/protobuf_serialization
import ./stpproto
import ./por
type
StpStore* = object
authDir*: string
postfixLen*: int
template stpPath*(self: StpStore, cid: Cid): string =
self.authDir / ($cid)[^self.postfixLen..^1] / $cid
proc retrieve*(
self: StpStore,
cid: Cid): Future[?!PorMessage] {.async.} =
## Retrieve authenticators from data store
##
let path = self.stpPath(cid) / "por"
var data: seq[byte]
if (
let res = io2.readFile(path, data);
res.isErr):
let error = io2.ioErrorMsg(res.error)
trace "Cannot retrieve storage proof data from fs", path , error
return failure("Cannot retrieve storage proof data from fs")
return Protobuf.decode(data, PorMessage).success
proc store*(
self: StpStore,
por: PorMessage,
cid: Cid): Future[?!void] {.async.} =
## Persist storage proofs
##
let
dir = self.stpPath(cid)
if io2.createPath(dir).isErr:
trace "Unable to create storage proofs prefix dir", dir
return failure(&"Unable to create storage proofs prefix dir ${dir}")
let path = dir / "por"
if (
let res = io2.writeFile(path, Protobuf.encode(por));
res.isErr):
let error = io2.ioErrorMsg(res.error)
trace "Unable to store storage proofs", path, cid = cid, error
return failure(
&"Unable to store storage proofs - path = ${path} cid = ${$cid} error = ${error}")
return success()
proc retrieve*(
self: StpStore,
cid: Cid,
blocks: seq[int]): Future[?!seq[Tag]] {.async.} =
var tags: seq[Tag]
for b in blocks:
var tag = Tag(idx: b)
let path = self.stpPath(cid) / $b
if (
let res = io2.readFile(path, tag.tag);
res.isErr):
let error = io2.ioErrorMsg(res.error)
trace "Cannot retrieve tags from fs", path , error
return failure("Cannot retrieve tags from fs")
tags.add(tag)
return tags.success
proc store*(
self: StpStore,
tags: seq[Tag],
cid: Cid): Future[?!void] {.async.} =
let
dir = self.stpPath(cid)
if io2.createPath(dir).isErr:
trace "Unable to create storage proofs prefix dir", dir
return failure(&"Unable to create storage proofs prefix dir ${dir}")
for t in tags:
let path = dir / $t.idx
if (
let res = io2.writeFile(path, t.tag);
res.isErr):
let error = io2.ioErrorMsg(res.error)
trace "Unable to store tags", path, cid = cid, error
return failure(
&"Unable to store tags - path = ${path} cid = ${$cid} error = ${error}")
return success()
proc init*(
T: type StpStore,
authDir: string,
postfixLen: int = 2): StpStore =
T(
authDir: authDir,
postfixLen: postfixLen)