mirror of
https://github.com/status-im/nim-codex.git
synced 2025-01-18 23:01:43 +00:00
Merge branch 'master' into feature/blockexc-cleanup-blockaddrs-handling
This commit is contained in:
commit
22d4924735
35
.github/actions/nimbus-build-system/action.yml
vendored
35
.github/actions/nimbus-build-system/action.yml
vendored
@ -11,13 +11,16 @@ inputs:
|
||||
default: "amd64"
|
||||
nim_version:
|
||||
description: "Nim version"
|
||||
default: "version-1-6"
|
||||
default: "v2.0.14"
|
||||
rust_version:
|
||||
description: "Rust version"
|
||||
default: "1.79.0"
|
||||
shell:
|
||||
description: "Shell to run commands in"
|
||||
default: "bash --noprofile --norc -e -o pipefail"
|
||||
coverage:
|
||||
description: "True if the process is used for coverage"
|
||||
default: false
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
@ -31,8 +34,8 @@ runs:
|
||||
if: inputs.os == 'linux' && (inputs.cpu == 'amd64' || inputs.cpu == 'arm64')
|
||||
shell: ${{ inputs.shell }} {0}
|
||||
run: |
|
||||
sudo apt-fast update -qq
|
||||
sudo DEBIAN_FRONTEND='noninteractive' apt-fast install \
|
||||
sudo apt-get update -qq
|
||||
sudo DEBIAN_FRONTEND='noninteractive' apt-get install \
|
||||
--no-install-recommends -yq lcov
|
||||
|
||||
- name: APT (Linux i386)
|
||||
@ -40,8 +43,8 @@ runs:
|
||||
shell: ${{ inputs.shell }} {0}
|
||||
run: |
|
||||
sudo dpkg --add-architecture i386
|
||||
sudo apt-fast update -qq
|
||||
sudo DEBIAN_FRONTEND='noninteractive' apt-fast install \
|
||||
sudo apt-get update -qq
|
||||
sudo DEBIAN_FRONTEND='noninteractive' apt-get install \
|
||||
--no-install-recommends -yq gcc-multilib g++-multilib
|
||||
|
||||
- name: Homebrew (macOS)
|
||||
@ -78,11 +81,21 @@ runs:
|
||||
mingw-w64-i686-ntldd-git
|
||||
mingw-w64-i686-rust
|
||||
|
||||
- name: MSYS2 (Windows All) - Downgrade to gcc 13
|
||||
- name: MSYS2 (Windows All) - Update to gcc 14
|
||||
if: inputs.os == 'windows'
|
||||
shell: ${{ inputs.shell }} {0}
|
||||
run: |
|
||||
pacman -U --noconfirm https://repo.msys2.org/mingw/ucrt64/mingw-w64-ucrt-x86_64-gcc-13.2.0-6-any.pkg.tar.zst https://repo.msys2.org/mingw/ucrt64/mingw-w64-ucrt-x86_64-gcc-libs-13.2.0-6-any.pkg.tar.zst
|
||||
pacman -U --noconfirm https://repo.msys2.org/mingw/ucrt64/mingw-w64-ucrt-x86_64-gcc-14.2.0-2-any.pkg.tar.zst https://repo.msys2.org/mingw/ucrt64/mingw-w64-ucrt-x86_64-gcc-libs-14.2.0-2-any.pkg.tar.zst
|
||||
|
||||
- name: Install gcc 14 on Linux
|
||||
# We don't want to install gcc 14 for coverage (Ubuntu 20.04)
|
||||
if : ${{ inputs.os == 'linux' && !inputs.coverage }}
|
||||
shell: ${{ inputs.shell }} {0}
|
||||
run: |
|
||||
# Add GCC-14 to alternatives
|
||||
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-14 14
|
||||
# Set GCC-14 as the default
|
||||
sudo update-alternatives --set gcc /usr/bin/gcc-14
|
||||
|
||||
- name: Derive environment variables
|
||||
shell: ${{ inputs.shell }} {0}
|
||||
@ -159,6 +172,7 @@ runs:
|
||||
- name: Restore Nim toolchain binaries from cache
|
||||
id: nim-cache
|
||||
uses: actions/cache@v4
|
||||
if : ${{ !inputs.coverage }}
|
||||
with:
|
||||
path: NimBinaries
|
||||
key: ${{ inputs.os }}-${{ inputs.cpu }}-nim-${{ inputs.nim_version }}-cache-${{ env.cache_nonce }}-${{ github.run_id }}
|
||||
@ -168,9 +182,16 @@ runs:
|
||||
shell: ${{ inputs.shell }} {0}
|
||||
run: echo "NIM_COMMIT=${{ inputs.nim_version }}" >> ${GITHUB_ENV}
|
||||
|
||||
- name: MSYS2 (Windows All) - Disable git symbolic links (since miniupnp 2.2.5)
|
||||
if: inputs.os == 'windows'
|
||||
shell: ${{ inputs.shell }} {0}
|
||||
run: |
|
||||
git config --global core.symlinks false
|
||||
|
||||
- name: Build Nim and Codex dependencies
|
||||
shell: ${{ inputs.shell }} {0}
|
||||
run: |
|
||||
gcc --version
|
||||
make -j${ncpu} CI_CACHE=NimBinaries ${ARCH_OVERRIDE} QUICK_AND_DIRTY_COMPILER=1 update
|
||||
echo
|
||||
./env.sh nim --version
|
||||
|
1
.github/workflows/ci-reusable.yml
vendored
1
.github/workflows/ci-reusable.yml
vendored
@ -40,6 +40,7 @@ jobs:
|
||||
os: ${{ matrix.os }}
|
||||
shell: ${{ matrix.shell }}
|
||||
nim_version: ${{ matrix.nim_version }}
|
||||
coverage: false
|
||||
|
||||
## Part 1 Tests ##
|
||||
- name: Unit tests
|
||||
|
15
.github/workflows/ci.yml
vendored
15
.github/workflows/ci.yml
vendored
@ -9,7 +9,7 @@ on:
|
||||
|
||||
env:
|
||||
cache_nonce: 0 # Allows for easily busting actions/cache caches
|
||||
nim_version: pinned
|
||||
nim_version: v2.0.14
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref || github.run_id }}
|
||||
@ -27,10 +27,10 @@ jobs:
|
||||
uses: fabiocaccamo/create-matrix-action@v4
|
||||
with:
|
||||
matrix: |
|
||||
os {linux}, cpu {amd64}, builder {ubuntu-20.04}, tests {unittest}, nim_version {${{ env.nim_version }}}, shell {bash --noprofile --norc -e -o pipefail}
|
||||
os {linux}, cpu {amd64}, builder {ubuntu-20.04}, tests {contract}, nim_version {${{ env.nim_version }}}, shell {bash --noprofile --norc -e -o pipefail}
|
||||
os {linux}, cpu {amd64}, builder {ubuntu-20.04}, tests {integration}, nim_version {${{ env.nim_version }}}, shell {bash --noprofile --norc -e -o pipefail}
|
||||
os {linux}, cpu {amd64}, builder {ubuntu-20.04}, tests {tools}, nim_version {${{ env.nim_version }}}, shell {bash --noprofile --norc -e -o pipefail}
|
||||
os {linux}, cpu {amd64}, builder {ubuntu-latest}, tests {unittest}, nim_version {${{ env.nim_version }}}, shell {bash --noprofile --norc -e -o pipefail}
|
||||
os {linux}, cpu {amd64}, builder {ubuntu-latest}, tests {contract}, nim_version {${{ env.nim_version }}}, shell {bash --noprofile --norc -e -o pipefail}
|
||||
os {linux}, cpu {amd64}, builder {ubuntu-latest}, tests {integration}, nim_version {${{ env.nim_version }}}, shell {bash --noprofile --norc -e -o pipefail}
|
||||
os {linux}, cpu {amd64}, builder {ubuntu-latest}, tests {tools}, nim_version {${{ env.nim_version }}}, shell {bash --noprofile --norc -e -o pipefail}
|
||||
os {macos}, cpu {amd64}, builder {macos-13}, tests {unittest}, nim_version {${{ env.nim_version }}}, shell {bash --noprofile --norc -e -o pipefail}
|
||||
os {macos}, cpu {amd64}, builder {macos-13}, tests {contract}, nim_version {${{ env.nim_version }}}, shell {bash --noprofile --norc -e -o pipefail}
|
||||
os {macos}, cpu {amd64}, builder {macos-13}, tests {integration}, nim_version {${{ env.nim_version }}}, shell {bash --noprofile --norc -e -o pipefail}
|
||||
@ -48,6 +48,10 @@ jobs:
|
||||
cache_nonce: ${{ needs.matrix.outputs.cache_nonce }}
|
||||
|
||||
coverage:
|
||||
# Force to stick to ubuntu 20.04 for coverage because
|
||||
# lcov was updated to 2.x version in ubuntu-latest
|
||||
# and cause a lot of issues.
|
||||
# See https://github.com/linux-test-project/lcov/issues/238
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
@ -61,6 +65,7 @@ jobs:
|
||||
with:
|
||||
os: linux
|
||||
nim_version: ${{ env.nim_version }}
|
||||
coverage: true
|
||||
|
||||
- name: Generate coverage data
|
||||
run: |
|
||||
|
4
Makefile
4
Makefile
@ -15,8 +15,8 @@
|
||||
#
|
||||
# If NIM_COMMIT is set to "nimbusbuild", this will use the
|
||||
# version pinned by nimbus-build-system.
|
||||
PINNED_NIM_VERSION := 38640664088251bbc88917b4bacfd86ec53014b8 # 1.6.21
|
||||
|
||||
#PINNED_NIM_VERSION := 38640664088251bbc88917b4bacfd86ec53014b8 # 1.6.21
|
||||
PINNED_NIM_VERSION := v2.0.14
|
||||
ifeq ($(NIM_COMMIT),)
|
||||
NIM_COMMIT := $(PINNED_NIM_VERSION)
|
||||
else ifeq ($(NIM_COMMIT),pinned)
|
||||
|
@ -47,7 +47,7 @@ when isMainModule:
|
||||
let config = CodexConf.load(
|
||||
version = codexFullVersion,
|
||||
envVarsPrefix = "codex",
|
||||
secondarySources = proc (config: CodexConf, sources: auto) =
|
||||
secondarySources = proc (config: CodexConf, sources: auto) {.gcsafe, raises: [ConfigurationError].} =
|
||||
if configFile =? config.configFile:
|
||||
sources.addConfigFile(Toml, configFile)
|
||||
)
|
||||
|
@ -8,7 +8,7 @@ type
|
||||
SecondsSince1970* = int64
|
||||
Timeout* = object of CatchableError
|
||||
|
||||
method now*(clock: Clock): SecondsSince1970 {.base, upraises: [].} =
|
||||
method now*(clock: Clock): SecondsSince1970 {.base, gcsafe, upraises: [].} =
|
||||
raiseAssert "not implemented"
|
||||
|
||||
method waitUntil*(clock: Clock, time: SecondsSince1970) {.base, async.} =
|
||||
|
@ -11,7 +11,6 @@ import std/sequtils
|
||||
import std/strutils
|
||||
import std/os
|
||||
import std/tables
|
||||
import std/cpuinfo
|
||||
|
||||
import pkg/chronos
|
||||
import pkg/presto
|
||||
@ -24,7 +23,6 @@ import pkg/stew/shims/net as stewnet
|
||||
import pkg/datastore
|
||||
import pkg/ethers except Rng
|
||||
import pkg/stew/io2
|
||||
import pkg/taskpools
|
||||
|
||||
import ./node
|
||||
import ./conf
|
||||
@ -56,7 +54,6 @@ type
|
||||
codexNode: CodexNodeRef
|
||||
repoStore: RepoStore
|
||||
maintenance: BlockMaintainer
|
||||
taskpool: Taskpool
|
||||
|
||||
CodexPrivateKey* = libp2p.PrivateKey # alias
|
||||
EthWallet = ethers.Wallet
|
||||
@ -174,10 +171,6 @@ proc start*(s: CodexServer) {.async.} =
|
||||
proc stop*(s: CodexServer) {.async.} =
|
||||
notice "Stopping codex node"
|
||||
|
||||
|
||||
s.taskpool.syncAll()
|
||||
s.taskpool.shutdown()
|
||||
|
||||
await allFuturesThrowing(
|
||||
s.restServer.stop(),
|
||||
s.codexNode.switch.stop(),
|
||||
@ -266,15 +259,12 @@ proc new*(
|
||||
else:
|
||||
none Prover
|
||||
|
||||
taskpool = Taskpool.new(num_threads = countProcessors())
|
||||
|
||||
codexNode = CodexNodeRef.new(
|
||||
switch = switch,
|
||||
networkStore = store,
|
||||
engine = engine,
|
||||
prover = prover,
|
||||
discovery = discovery,
|
||||
taskpool = taskpool)
|
||||
prover = prover)
|
||||
|
||||
restServer = RestServerRef.new(
|
||||
codexNode.initRestApi(config, repoStore, config.apiCorsAllowedOrigin),
|
||||
@ -290,5 +280,4 @@ proc new*(
|
||||
codexNode: codexNode,
|
||||
restServer: restServer,
|
||||
repoStore: repoStore,
|
||||
maintenance: maintenance,
|
||||
taskpool: taskpool)
|
||||
maintenance: maintenance)
|
||||
|
@ -43,6 +43,7 @@ import ./units
|
||||
import ./utils
|
||||
import ./nat
|
||||
import ./utils/natutils
|
||||
|
||||
from ./validationconfig import MaxSlots, ValidationGroups
|
||||
|
||||
export units, net, codextypes, logutils, completeCmdArg, parseCmdArg, NatConfig
|
||||
@ -119,9 +120,9 @@ type
|
||||
|
||||
metricsAddress* {.
|
||||
desc: "Listening address of the metrics server"
|
||||
defaultValue: ValidIpAddress.init("127.0.0.1")
|
||||
defaultValue: defaultAddress(config)
|
||||
defaultValueDesc: "127.0.0.1"
|
||||
name: "metrics-address" }: ValidIpAddress
|
||||
name: "metrics-address" }: IpAddress
|
||||
|
||||
metricsPort* {.
|
||||
desc: "Listening HTTP port of the metrics server"
|
||||
@ -147,7 +148,7 @@ type
|
||||
nat* {.
|
||||
desc: "Specify method to use for determining public address. " &
|
||||
"Must be one of: any, none, upnp, pmp, extip:<IP>"
|
||||
defaultValue: NatConfig(hasExtIp: false, nat: NatAny)
|
||||
defaultValue: defaultNatConfig()
|
||||
defaultValueDesc: "any"
|
||||
name: "nat" }: NatConfig
|
||||
|
||||
@ -410,6 +411,12 @@ type
|
||||
logutils.formatIt(LogFormat.textLines, EthAddress): it.short0xHexLog
|
||||
logutils.formatIt(LogFormat.json, EthAddress): %it
|
||||
|
||||
func defaultAddress*(conf: CodexConf): IpAddress =
|
||||
result = static parseIpAddress("127.0.0.1")
|
||||
|
||||
func defaultNatConfig*(): NatConfig =
|
||||
result = NatConfig(hasExtIp: false, nat: NatStrategy.NatAny)
|
||||
|
||||
func persistence*(self: CodexConf): bool =
|
||||
self.cmd == StartUpCmd.persistence
|
||||
|
||||
@ -442,13 +449,17 @@ const
|
||||
|
||||
proc parseCmdArg*(T: typedesc[MultiAddress],
|
||||
input: string): MultiAddress
|
||||
{.upraises: [ValueError, LPError].} =
|
||||
{.upraises: [ValueError] .} =
|
||||
var ma: MultiAddress
|
||||
let res = MultiAddress.init(input)
|
||||
if res.isOk:
|
||||
ma = res.get()
|
||||
else:
|
||||
warn "Invalid MultiAddress", input=input, error = res.error()
|
||||
try:
|
||||
let res = MultiAddress.init(input)
|
||||
if res.isOk:
|
||||
ma = res.get()
|
||||
else:
|
||||
warn "Invalid MultiAddress", input=input, error = res.error()
|
||||
quit QuitFailure
|
||||
except LPError as exc:
|
||||
warn "Invalid MultiAddress uri", uri = input, error = exc.msg
|
||||
quit QuitFailure
|
||||
ma
|
||||
|
||||
@ -458,6 +469,9 @@ proc parseCmdArg*(T: type SignedPeerRecord, uri: string): T =
|
||||
if not res.fromURI(uri):
|
||||
warn "Invalid SignedPeerRecord uri", uri = uri
|
||||
quit QuitFailure
|
||||
except LPError as exc:
|
||||
warn "Invalid SignedPeerRecord uri", uri = uri, error = exc.msg
|
||||
quit QuitFailure
|
||||
except CatchableError as exc:
|
||||
warn "Invalid SignedPeerRecord uri", uri = uri, error = exc.msg
|
||||
quit QuitFailure
|
||||
@ -476,7 +490,7 @@ func parseCmdArg*(T: type NatConfig, p: string): T {.raises: [ValueError].} =
|
||||
else:
|
||||
if p.startsWith("extip:"):
|
||||
try:
|
||||
let ip = ValidIpAddress.init(p[6..^1])
|
||||
let ip = parseIpAddress(p[6..^1])
|
||||
NatConfig(hasExtIp: true, extIp: ip)
|
||||
except ValueError:
|
||||
let error = "Not a valid IP address: " & p[6..^1]
|
||||
@ -516,7 +530,11 @@ proc readValue*(r: var TomlReader, val: var SignedPeerRecord) =
|
||||
error "invalid SignedPeerRecord configuration value", error = err.msg
|
||||
quit QuitFailure
|
||||
|
||||
val = SignedPeerRecord.parseCmdArg(uri)
|
||||
try:
|
||||
val = SignedPeerRecord.parseCmdArg(uri)
|
||||
except LPError as err:
|
||||
warn "Invalid SignedPeerRecord uri", uri = uri, error = err.msg
|
||||
quit QuitFailure
|
||||
|
||||
proc readValue*(r: var TomlReader, val: var MultiAddress) =
|
||||
without input =? r.readValue(string).catch, err:
|
||||
|
@ -17,6 +17,7 @@ import pkg/questionable/results
|
||||
import pkg/stew/shims/net
|
||||
import pkg/contractabi/address as ca
|
||||
import pkg/codexdht/discv5/[routing_table, protocol as discv5]
|
||||
from pkg/nimcrypto import keccak256
|
||||
|
||||
import ./rng
|
||||
import ./errors
|
||||
@ -124,7 +125,7 @@ method provide*(d: Discovery, host: ca.Address) {.async, base.} =
|
||||
|
||||
method removeProvider*(
|
||||
d: Discovery,
|
||||
peerId: PeerId): Future[void] {.base.} =
|
||||
peerId: PeerId): Future[void] {.base, gcsafe.} =
|
||||
## Remove provider from providers table
|
||||
##
|
||||
|
||||
@ -169,7 +170,7 @@ proc stop*(d: Discovery) {.async.} =
|
||||
proc new*(
|
||||
T: type Discovery,
|
||||
key: PrivateKey,
|
||||
bindIp = ValidIpAddress.init(IPv4_any()),
|
||||
bindIp = IPv4_any(),
|
||||
bindPort = 0.Port,
|
||||
announceAddrs: openArray[MultiAddress],
|
||||
bootstrapNodes: openArray[SignedPeerRecord] = [],
|
||||
@ -199,7 +200,7 @@ proc new*(
|
||||
|
||||
self.protocol = newProtocol(
|
||||
key,
|
||||
bindIp = bindIp.toNormalIp,
|
||||
bindIp = bindIp,
|
||||
bindPort = bindPort,
|
||||
record = self.providerRecord.get,
|
||||
bootstrapRecords = bootstrapNodes,
|
||||
|
@ -22,7 +22,7 @@ type
|
||||
EncoderBackend* = ref object of ErasureBackend
|
||||
DecoderBackend* = ref object of ErasureBackend
|
||||
|
||||
method release*(self: ErasureBackend) {.base.} =
|
||||
method release*(self: ErasureBackend) {.base, gcsafe.} =
|
||||
## release the backend
|
||||
##
|
||||
raiseAssert("not implemented!")
|
||||
@ -31,7 +31,7 @@ method encode*(
|
||||
self: EncoderBackend,
|
||||
buffers,
|
||||
parity: var openArray[seq[byte]]
|
||||
): Result[void, cstring] {.base.} =
|
||||
): Result[void, cstring] {.base, gcsafe.} =
|
||||
## encode buffers using a backend
|
||||
##
|
||||
raiseAssert("not implemented!")
|
||||
@ -41,7 +41,7 @@ method decode*(
|
||||
buffers,
|
||||
parity,
|
||||
recovered: var openArray[seq[byte]]
|
||||
): Result[void, cstring] {.base.} =
|
||||
): Result[void, cstring] {.base, gcsafe.} =
|
||||
## decode buffers using a backend
|
||||
##
|
||||
raiseAssert("not implemented!")
|
||||
|
@ -17,7 +17,6 @@ import std/sugar
|
||||
import pkg/chronos
|
||||
import pkg/libp2p/[multicodec, cid, multihash]
|
||||
import pkg/libp2p/protobuf/minprotobuf
|
||||
import pkg/taskpools
|
||||
|
||||
import ../logutils
|
||||
import ../manifest
|
||||
@ -32,7 +31,6 @@ import ../errors
|
||||
import pkg/stew/byteutils
|
||||
|
||||
import ./backend
|
||||
import ./asyncbackend
|
||||
|
||||
export backend
|
||||
|
||||
@ -73,7 +71,6 @@ type
|
||||
encoderProvider*: EncoderProvider
|
||||
decoderProvider*: DecoderProvider
|
||||
store*: BlockStore
|
||||
taskpool: Taskpool
|
||||
|
||||
EncodingParams = object
|
||||
ecK: Natural
|
||||
@ -295,23 +292,30 @@ proc encodeData(
|
||||
# TODO: Don't allocate a new seq every time, allocate once and zero out
|
||||
var
|
||||
data = seq[seq[byte]].new() # number of blocks to encode
|
||||
parityData = newSeqWith[seq[byte]](params.ecM, newSeq[byte](manifest.blockSize.int))
|
||||
|
||||
data[].setLen(params.ecK)
|
||||
# TODO: this is a tight blocking loop so we sleep here to allow
|
||||
# other events to be processed, this should be addressed
|
||||
# by threading
|
||||
await sleepAsync(10.millis)
|
||||
|
||||
without resolved =?
|
||||
(await self.prepareEncodingData(manifest, params, step, data, cids, emptyBlock)), err:
|
||||
trace "Unable to prepare data", error = err.msg
|
||||
return failure(err)
|
||||
|
||||
trace "Erasure coding data", data = data[].len, parity = params.ecM
|
||||
trace "Erasure coding data", data = data[].len, parity = parityData.len
|
||||
|
||||
without parity =? await asyncEncode(self.taskpool, encoder, data, manifest.blockSize.int, params.ecM), err:
|
||||
trace "Error encoding data", err = err.msg
|
||||
return failure(err)
|
||||
if (
|
||||
let res = encoder.encode(data[], parityData);
|
||||
res.isErr):
|
||||
trace "Unable to encode manifest!", error = $res.error
|
||||
return failure($res.error)
|
||||
|
||||
var idx = params.rounded + step
|
||||
for j in 0..<params.ecM:
|
||||
without blk =? bt.Block.new(parity[j]), error:
|
||||
without blk =? bt.Block.new(parityData[j]), error:
|
||||
trace "Unable to create parity block", err = error.msg
|
||||
return failure(error)
|
||||
|
||||
@ -396,15 +400,21 @@ proc decode*(
|
||||
cids[].setLen(encoded.blocksCount)
|
||||
try:
|
||||
for step in 0..<encoded.steps:
|
||||
# TODO: this is a tight blocking loop so we sleep here to allow
|
||||
# other events to be processed, this should be addressed
|
||||
# by threading
|
||||
await sleepAsync(10.millis)
|
||||
|
||||
var
|
||||
data = seq[seq[byte]].new()
|
||||
parity = seq[seq[byte]].new()
|
||||
parityData = seq[seq[byte]].new()
|
||||
recovered = newSeqWith[seq[byte]](encoded.ecK, newSeq[byte](encoded.blockSize.int))
|
||||
|
||||
data[].setLen(encoded.ecK) # set len to K
|
||||
parity[].setLen(encoded.ecM) # set len to M
|
||||
parityData[].setLen(encoded.ecM) # set len to M
|
||||
|
||||
without (dataPieces, _) =?
|
||||
(await self.prepareDecodingData(encoded, step, data, parity, cids, emptyBlock)), err:
|
||||
(await self.prepareDecodingData(encoded, step, data, parityData, cids, emptyBlock)), err:
|
||||
trace "Unable to prepare data", error = err.msg
|
||||
return failure(err)
|
||||
|
||||
@ -414,9 +424,11 @@ proc decode*(
|
||||
|
||||
trace "Erasure decoding data"
|
||||
|
||||
without recovered =? await asyncDecode(self.taskpool, decoder, data, parity, encoded.blockSize.int), err:
|
||||
trace "Error decoding data", err = err.msg
|
||||
return failure(err)
|
||||
if (
|
||||
let err = decoder.decode(data[], parityData[], recovered);
|
||||
err.isErr):
|
||||
trace "Unable to decode data!", err = $err.error
|
||||
return failure($err.error)
|
||||
|
||||
for i in 0..<encoded.ecK:
|
||||
let idx = i * encoded.steps + step
|
||||
@ -470,13 +482,11 @@ proc new*(
|
||||
T: type Erasure,
|
||||
store: BlockStore,
|
||||
encoderProvider: EncoderProvider,
|
||||
decoderProvider: DecoderProvider,
|
||||
taskpool: Taskpool): Erasure =
|
||||
decoderProvider: DecoderProvider): Erasure =
|
||||
## Create a new Erasure instance for encoding and decoding manifests
|
||||
##
|
||||
|
||||
Erasure(
|
||||
store: store,
|
||||
encoderProvider: encoderProvider,
|
||||
decoderProvider: decoderProvider,
|
||||
taskpool: taskpool)
|
||||
decoderProvider: decoderProvider)
|
||||
|
@ -38,6 +38,29 @@ func toFailure*[T](exp: Option[T]): Result[T, ref CatchableError] {.inline.} =
|
||||
else:
|
||||
T.failure("Option is None")
|
||||
|
||||
# allFuturesThrowing was moved to the tests in libp2p
|
||||
proc allFuturesThrowing*[T](args: varargs[Future[T]]): Future[void] =
|
||||
var futs: seq[Future[T]]
|
||||
for fut in args:
|
||||
futs &= fut
|
||||
proc call() {.async.} =
|
||||
var first: ref CatchableError = nil
|
||||
futs = await allFinished(futs)
|
||||
for fut in futs:
|
||||
if fut.failed:
|
||||
let err = fut.readError()
|
||||
if err of Defect:
|
||||
raise err
|
||||
else:
|
||||
if err of CancelledError:
|
||||
raise err
|
||||
if isNil(first):
|
||||
first = err
|
||||
if not isNil(first):
|
||||
raise first
|
||||
|
||||
return call()
|
||||
|
||||
proc allFutureResult*[T](fut: seq[Future[T]]): Future[?!void] {.async.} =
|
||||
try:
|
||||
await allFuturesThrowing(fut)
|
||||
|
@ -47,6 +47,14 @@ type
|
||||
CodexProof* = ref object of ByteProof
|
||||
mcodec*: MultiCodec
|
||||
|
||||
# CodeHashes is not exported from libp2p
|
||||
# So we need to recreate it instead of
|
||||
proc initMultiHashCodeTable(): Table[MultiCodec, MHash] {.compileTime.} =
|
||||
for item in HashesList:
|
||||
result[item.mcodec] = item
|
||||
|
||||
const CodeHashes = initMultiHashCodeTable()
|
||||
|
||||
func mhash*(mcodec: MultiCodec): ?!MHash =
|
||||
let
|
||||
mhash = CodeHashes.getOrDefault(mcodec)
|
||||
|
@ -24,10 +24,10 @@ import ./merkletree
|
||||
export merkletree, poseidon2
|
||||
|
||||
const
|
||||
KeyNoneF = F.fromhex("0x0")
|
||||
KeyBottomLayerF = F.fromhex("0x1")
|
||||
KeyOddF = F.fromhex("0x2")
|
||||
KeyOddAndBottomLayerF = F.fromhex("0x3")
|
||||
KeyNoneF = F.fromHex("0x0")
|
||||
KeyBottomLayerF = F.fromHex("0x1")
|
||||
KeyOddF = F.fromHex("0x2")
|
||||
KeyOddAndBottomLayerF = F.fromHex("0x3")
|
||||
|
||||
Poseidon2Zero* = zero
|
||||
|
||||
|
@ -73,6 +73,8 @@ proc getExternalIP*(natStrategy: NatStrategy, quiet = false): Option[IpAddress]
|
||||
msg = "Internet Gateway Device found but it's not connected. Trying anyway."
|
||||
of NotAnIGD:
|
||||
msg = "Some device found, but it's not recognised as an Internet Gateway Device. Trying anyway."
|
||||
of IGDIpNotRoutable:
|
||||
msg = "Internet Gateway Device found and is connected, but with a reserved or non-routable IP. Trying anyway."
|
||||
if not quiet:
|
||||
debug "UPnP", msg
|
||||
if canContinue:
|
||||
@ -115,7 +117,7 @@ proc getExternalIP*(natStrategy: NatStrategy, quiet = false): Option[IpAddress]
|
||||
# default) is a public IP. That's a long shot, because code paths involving a
|
||||
# user-provided bind address are not supposed to get here.
|
||||
proc getRoutePrefSrc(
|
||||
bindIp: ValidIpAddress): (Option[ValidIpAddress], PrefSrcStatus) =
|
||||
bindIp: IpAddress): (Option[IpAddress], PrefSrcStatus) =
|
||||
let bindAddress = initTAddress(bindIp, Port(0))
|
||||
|
||||
if bindAddress.isAnyLocal():
|
||||
@ -124,18 +126,18 @@ proc getRoutePrefSrc(
|
||||
# No route was found, log error and continue without IP.
|
||||
error "No routable IP address found, check your network connection",
|
||||
error = ip.error
|
||||
return (none(ValidIpAddress), NoRoutingInfo)
|
||||
return (none(IpAddress), NoRoutingInfo)
|
||||
elif ip.get().isGlobalUnicast():
|
||||
return (some(ip.get()), PrefSrcIsPublic)
|
||||
else:
|
||||
return (none(ValidIpAddress), PrefSrcIsPrivate)
|
||||
return (none(IpAddress), PrefSrcIsPrivate)
|
||||
elif bindAddress.isGlobalUnicast():
|
||||
return (some(ValidIpAddress.init(bindIp)), BindAddressIsPublic)
|
||||
return (some(bindIp), BindAddressIsPublic)
|
||||
else:
|
||||
return (none(ValidIpAddress), BindAddressIsPrivate)
|
||||
return (none(IpAddress), BindAddressIsPrivate)
|
||||
|
||||
# Try to detect a public IP assigned to this host, before trying NAT traversal.
|
||||
proc getPublicRoutePrefSrcOrExternalIP*(natStrategy: NatStrategy, bindIp: ValidIpAddress, quiet = true): Option[ValidIpAddress] =
|
||||
proc getPublicRoutePrefSrcOrExternalIP*(natStrategy: NatStrategy, bindIp: IpAddress, quiet = true): Option[IpAddress] =
|
||||
let (prefSrcIp, prefSrcStatus) = getRoutePrefSrc(bindIp)
|
||||
|
||||
case prefSrcStatus:
|
||||
@ -144,7 +146,7 @@ proc getPublicRoutePrefSrcOrExternalIP*(natStrategy: NatStrategy, bindIp: ValidI
|
||||
of PrefSrcIsPrivate, BindAddressIsPrivate:
|
||||
let extIp = getExternalIP(natStrategy, quiet)
|
||||
if extIp.isSome:
|
||||
return some(ValidIpAddress.init(extIp.get))
|
||||
return some(extIp.get)
|
||||
|
||||
proc doPortMapping(tcpPort, udpPort: Port, description: string): Option[(Port, Port)] {.gcsafe.} =
|
||||
var
|
||||
@ -294,14 +296,14 @@ proc redirectPorts*(tcpPort, udpPort: Port, description: string): Option[(Port,
|
||||
|
||||
proc setupNat*(natStrategy: NatStrategy, tcpPort, udpPort: Port,
|
||||
clientId: string):
|
||||
tuple[ip: Option[ValidIpAddress], tcpPort, udpPort: Option[Port]] =
|
||||
tuple[ip: Option[IpAddress], tcpPort, udpPort: Option[Port]] =
|
||||
## Setup NAT port mapping and get external IP address.
|
||||
## If any of this fails, we don't return any IP address but do return the
|
||||
## original ports as best effort.
|
||||
## TODO: Allow for tcp or udp port mapping to be optional.
|
||||
let extIp = getExternalIP(natStrategy)
|
||||
if extIp.isSome:
|
||||
let ip = ValidIpAddress.init(extIp.get)
|
||||
let ip = extIp.get
|
||||
let extPorts = ({.gcsafe.}:
|
||||
redirectPorts(tcpPort = tcpPort,
|
||||
udpPort = udpPort,
|
||||
@ -311,20 +313,20 @@ proc setupNat*(natStrategy: NatStrategy, tcpPort, udpPort: Port,
|
||||
(ip: some(ip), tcpPort: some(extTcpPort), udpPort: some(extUdpPort))
|
||||
else:
|
||||
warn "UPnP/NAT-PMP available but port forwarding failed"
|
||||
(ip: none(ValidIpAddress), tcpPort: some(tcpPort), udpPort: some(udpPort))
|
||||
(ip: none(IpAddress), tcpPort: some(tcpPort), udpPort: some(udpPort))
|
||||
else:
|
||||
warn "UPnP/NAT-PMP not available"
|
||||
(ip: none(ValidIpAddress), tcpPort: some(tcpPort), udpPort: some(udpPort))
|
||||
(ip: none(IpAddress), tcpPort: some(tcpPort), udpPort: some(udpPort))
|
||||
|
||||
type
|
||||
NatConfig* = object
|
||||
case hasExtIp*: bool
|
||||
of true: extIp*: ValidIpAddress
|
||||
of true: extIp*: IpAddress
|
||||
of false: nat*: NatStrategy
|
||||
|
||||
proc setupAddress*(natConfig: NatConfig, bindIp: ValidIpAddress,
|
||||
proc setupAddress*(natConfig: NatConfig, bindIp: IpAddress,
|
||||
tcpPort, udpPort: Port, clientId: string):
|
||||
tuple[ip: Option[ValidIpAddress], tcpPort, udpPort: Option[Port]]
|
||||
tuple[ip: Option[IpAddress], tcpPort, udpPort: Option[Port]]
|
||||
{.gcsafe.} =
|
||||
## Set-up of the external address via any of the ways as configured in
|
||||
## `NatConfig`. In case all fails an error is logged and the bind ports are
|
||||
@ -353,10 +355,10 @@ proc setupAddress*(natConfig: NatConfig, bindIp: ValidIpAddress,
|
||||
return (prefSrcIp, some(tcpPort), some(udpPort))
|
||||
of PrefSrcIsPrivate:
|
||||
error "No public IP address found. Should not use --nat:none option"
|
||||
return (none(ValidIpAddress), some(tcpPort), some(udpPort))
|
||||
return (none(IpAddress), some(tcpPort), some(udpPort))
|
||||
of BindAddressIsPrivate:
|
||||
error "Bind IP is not a public IP address. Should not use --nat:none option"
|
||||
return (none(ValidIpAddress), some(tcpPort), some(udpPort))
|
||||
return (none(IpAddress), some(tcpPort), some(udpPort))
|
||||
of NatStrategy.NatUpnp, NatStrategy.NatPmp:
|
||||
return setupNat(natConfig.nat, tcpPort, udpPort, clientId)
|
||||
|
||||
|
@ -13,7 +13,6 @@ import std/options
|
||||
import std/sequtils
|
||||
import std/strformat
|
||||
import std/sugar
|
||||
import std/cpuinfo
|
||||
import times
|
||||
|
||||
import pkg/questionable
|
||||
@ -27,7 +26,6 @@ import pkg/libp2p/stream/bufferstream
|
||||
# TODO: remove once exported by libp2p
|
||||
import pkg/libp2p/routing_record
|
||||
import pkg/libp2p/signed_envelope
|
||||
import pkg/taskpools
|
||||
|
||||
import ./chunker
|
||||
import ./slots
|
||||
@ -71,7 +69,6 @@ type
|
||||
contracts*: Contracts
|
||||
clock*: Clock
|
||||
storage*: Contracts
|
||||
taskpool*: Taskpool
|
||||
|
||||
CodexNodeRef* = ref CodexNode
|
||||
|
||||
@ -213,7 +210,7 @@ proc fetchBatched*(
|
||||
proc streamSingleBlock(
|
||||
self: CodexNodeRef,
|
||||
cid: Cid
|
||||
): Future[?!LPstream] {.async.} =
|
||||
): Future[?!LPStream] {.async.} =
|
||||
## Streams the contents of a single block.
|
||||
##
|
||||
trace "Streaming single block", cid = cid
|
||||
@ -253,8 +250,7 @@ proc streamEntireDataset(
|
||||
erasure = Erasure.new(
|
||||
self.networkStore,
|
||||
leoEncoderProvider,
|
||||
leoDecoderProvider,
|
||||
self.taskpool)
|
||||
leoDecoderProvider)
|
||||
without _ =? (await erasure.decode(manifest)), error:
|
||||
error "Unable to erasure decode manifest", manifestCid, exc = error.msg
|
||||
return failure(error)
|
||||
@ -424,8 +420,7 @@ proc setupRequest(
|
||||
erasure = Erasure.new(
|
||||
self.networkStore.localStore,
|
||||
leoEncoderProvider,
|
||||
leoDecoderProvider,
|
||||
self.taskpool)
|
||||
leoDecoderProvider)
|
||||
|
||||
without encoded =? (await erasure.encode(manifest, ecK, ecM)), error:
|
||||
trace "Unable to erasure code dataset"
|
||||
@ -761,8 +756,7 @@ proc new*(
|
||||
engine: BlockExcEngine,
|
||||
discovery: Discovery,
|
||||
prover = Prover.none,
|
||||
contracts = Contracts.default,
|
||||
taskpool = Taskpool.new(num_threads = countProcessors())): CodexNodeRef =
|
||||
contracts = Contracts.default): CodexNodeRef =
|
||||
## Create new instance of a Codex self, call `start` to run it
|
||||
##
|
||||
|
||||
@ -772,5 +766,4 @@ proc new*(
|
||||
engine: engine,
|
||||
prover: prover,
|
||||
discovery: discovery,
|
||||
contracts: contracts,
|
||||
taskpool: taskpool)
|
||||
contracts: contracts)
|
||||
|
@ -90,7 +90,7 @@ proc init*(_: type RestNode, node: dn.Node): RestNode =
|
||||
peerId: node.record.data.peerId,
|
||||
record: node.record,
|
||||
address: node.address,
|
||||
seen: node.seen
|
||||
seen: node.seen > 0.5
|
||||
)
|
||||
|
||||
proc init*(_: type RestRoutingTable, routingTable: rt.RoutingTable): RestRoutingTable =
|
||||
|
@ -36,7 +36,7 @@ method run(state: SaleFilling, machine: Machine): Future[?State] {.async.} =
|
||||
slotIndex = data.slotIndex
|
||||
|
||||
let slotState = await market.slotState(slotId(data.requestId, data.slotIndex))
|
||||
var collateral: Uint256
|
||||
var collateral: UInt256
|
||||
|
||||
if slotState == SlotState.Repair:
|
||||
# When repairing the node gets "discount" on the collateral that it needs to
|
||||
|
@ -43,7 +43,7 @@ proc zkeyFilePath(config: CodexConf): string =
|
||||
|
||||
proc initializeFromCircuitDirFiles(
|
||||
config: CodexConf,
|
||||
utils: BackendUtils): ?!AnyBackend =
|
||||
utils: BackendUtils): ?!AnyBackend {.gcsafe.} =
|
||||
if fileExists(config.r1csFilePath) and
|
||||
fileExists(config.wasmFilePath) and
|
||||
fileExists(config.zkeyFilePath):
|
||||
|
@ -76,7 +76,7 @@ proc release*(self: CircomCompat) =
|
||||
##
|
||||
|
||||
if not isNil(self.backendCfg):
|
||||
self.backendCfg.unsafeAddr.releaseCfg()
|
||||
self.backendCfg.unsafeAddr.release_cfg()
|
||||
|
||||
if not isNil(self.vkp):
|
||||
self.vkp.unsafeAddr.release_key()
|
||||
@ -102,9 +102,9 @@ proc prove[H](
|
||||
|
||||
defer:
|
||||
if ctx != nil:
|
||||
ctx.addr.releaseCircomCompat()
|
||||
ctx.addr.release_circom_compat()
|
||||
|
||||
if initCircomCompat(
|
||||
if init_circom_compat(
|
||||
self.backendCfg,
|
||||
addr ctx) != ERR_OK or ctx == nil:
|
||||
raiseAssert("failed to initialize CircomCompat ctx")
|
||||
@ -114,27 +114,27 @@ proc prove[H](
|
||||
dataSetRoot = input.datasetRoot.toBytes
|
||||
slotRoot = input.slotRoot.toBytes
|
||||
|
||||
if ctx.pushInputU256Array(
|
||||
if ctx.push_input_u256_array(
|
||||
"entropy".cstring, entropy[0].addr, entropy.len.uint32) != ERR_OK:
|
||||
return failure("Failed to push entropy")
|
||||
|
||||
if ctx.pushInputU256Array(
|
||||
if ctx.push_input_u256_array(
|
||||
"dataSetRoot".cstring, dataSetRoot[0].addr, dataSetRoot.len.uint32) != ERR_OK:
|
||||
return failure("Failed to push data set root")
|
||||
|
||||
if ctx.pushInputU256Array(
|
||||
if ctx.push_input_u256_array(
|
||||
"slotRoot".cstring, slotRoot[0].addr, slotRoot.len.uint32) != ERR_OK:
|
||||
return failure("Failed to push data set root")
|
||||
|
||||
if ctx.pushInputU32(
|
||||
if ctx.push_input_u32(
|
||||
"nCellsPerSlot".cstring, input.nCellsPerSlot.uint32) != ERR_OK:
|
||||
return failure("Failed to push nCellsPerSlot")
|
||||
|
||||
if ctx.pushInputU32(
|
||||
if ctx.push_input_u32(
|
||||
"nSlotsPerDataSet".cstring, input.nSlotsPerDataSet.uint32) != ERR_OK:
|
||||
return failure("Failed to push nSlotsPerDataSet")
|
||||
|
||||
if ctx.pushInputU32(
|
||||
if ctx.push_input_u32(
|
||||
"slotIndex".cstring, input.slotIndex.uint32) != ERR_OK:
|
||||
return failure("Failed to push slotIndex")
|
||||
|
||||
@ -143,7 +143,7 @@ proc prove[H](
|
||||
|
||||
doAssert(slotProof.len == self.datasetDepth)
|
||||
# arrays are always flattened
|
||||
if ctx.pushInputU256Array(
|
||||
if ctx.push_input_u256_array(
|
||||
"slotProof".cstring,
|
||||
slotProof[0].addr,
|
||||
uint (slotProof[0].len * slotProof.len)) != ERR_OK:
|
||||
@ -154,13 +154,13 @@ proc prove[H](
|
||||
merklePaths = s.merklePaths.mapIt( it.toBytes )
|
||||
data = s.cellData.mapIt( @(it.toBytes) ).concat
|
||||
|
||||
if ctx.pushInputU256Array(
|
||||
if ctx.push_input_u256_array(
|
||||
"merklePaths".cstring,
|
||||
merklePaths[0].addr,
|
||||
uint (merklePaths[0].len * merklePaths.len)) != ERR_OK:
|
||||
return failure("Failed to push merkle paths")
|
||||
|
||||
if ctx.pushInputU256Array(
|
||||
if ctx.push_input_u256_array(
|
||||
"cellData".cstring,
|
||||
data[0].addr,
|
||||
data.len.uint) != ERR_OK:
|
||||
@ -172,7 +172,7 @@ proc prove[H](
|
||||
let proof =
|
||||
try:
|
||||
if (
|
||||
let res = self.backendCfg.proveCircuit(ctx, proofPtr.addr);
|
||||
let res = self.backendCfg.prove_circuit(ctx, proofPtr.addr);
|
||||
res != ERR_OK) or
|
||||
proofPtr == nil:
|
||||
return failure("Failed to prove - err code: " & $res)
|
||||
@ -180,7 +180,7 @@ proc prove[H](
|
||||
proofPtr[]
|
||||
finally:
|
||||
if proofPtr != nil:
|
||||
proofPtr.addr.releaseProof()
|
||||
proofPtr.addr.release_proof()
|
||||
|
||||
success proof
|
||||
|
||||
@ -202,7 +202,7 @@ proc verify*[H](
|
||||
inputs = inputs.toCircomInputs()
|
||||
|
||||
try:
|
||||
let res = verifyCircuit(proofPtr, inputs.addr, self.vkp)
|
||||
let res = verify_circuit(proofPtr, inputs.addr, self.vkp)
|
||||
if res == ERR_OK:
|
||||
success true
|
||||
elif res == ERR_FAILED_TO_VERIFY_PROOF:
|
||||
@ -228,18 +228,18 @@ proc init*(
|
||||
var cfg: ptr CircomBn254Cfg
|
||||
var zkey = if zkeyPath.len > 0: zkeyPath.cstring else: nil
|
||||
|
||||
if initCircomConfig(
|
||||
if init_circom_config(
|
||||
r1csPath.cstring,
|
||||
wasmPath.cstring,
|
||||
zkey, cfg.addr) != ERR_OK or cfg == nil:
|
||||
if cfg != nil: cfg.addr.releaseCfg()
|
||||
if cfg != nil: cfg.addr.release_cfg()
|
||||
raiseAssert("failed to initialize circom compat config")
|
||||
|
||||
var
|
||||
vkpPtr: ptr VerifyingKey = nil
|
||||
|
||||
if cfg.getVerifyingKey(vkpPtr.addr) != ERR_OK or vkpPtr == nil:
|
||||
if vkpPtr != nil: vkpPtr.addr.releaseKey()
|
||||
if cfg.get_verifying_key(vkpPtr.addr) != ERR_OK or vkpPtr == nil:
|
||||
if vkpPtr != nil: vkpPtr.addr.release_key()
|
||||
raiseAssert("Failed to get verifying key")
|
||||
|
||||
CircomCompat(
|
||||
|
@ -8,5 +8,5 @@ method initializeCircomBackend*(
|
||||
r1csFile: string,
|
||||
wasmFile: string,
|
||||
zKeyFile: string
|
||||
): AnyBackend {.base.} =
|
||||
): AnyBackend {.base, gcsafe.}=
|
||||
CircomCompat.init(r1csFile, wasmFile, zKeyFile)
|
||||
|
@ -33,13 +33,13 @@ type
|
||||
BlockStore* = ref object of RootObj
|
||||
onBlockStored*: ?CidCallback
|
||||
|
||||
method getBlock*(self: BlockStore, cid: Cid): Future[?!Block] {.base.} =
|
||||
method getBlock*(self: BlockStore, cid: Cid): Future[?!Block] {.base, gcsafe.} =
|
||||
## Get a block from the blockstore
|
||||
##
|
||||
|
||||
raiseAssert("getBlock by cid not implemented!")
|
||||
|
||||
method getBlock*(self: BlockStore, treeCid: Cid, index: Natural): Future[?!Block] {.base.} =
|
||||
method getBlock*(self: BlockStore, treeCid: Cid, index: Natural): Future[?!Block] {.base, gcsafe.} =
|
||||
## Get a block from the blockstore
|
||||
##
|
||||
|
||||
@ -50,13 +50,13 @@ method getCid*(self: BlockStore, treeCid: Cid, index: Natural): Future[?!Cid] {.
|
||||
##
|
||||
raiseAssert("getCid by treecid not implemented!")
|
||||
|
||||
method getBlock*(self: BlockStore, address: BlockAddress): Future[?!Block] {.base.} =
|
||||
method getBlock*(self: BlockStore, address: BlockAddress): Future[?!Block] {.base, gcsafe.} =
|
||||
## Get a block from the blockstore
|
||||
##
|
||||
|
||||
raiseAssert("getBlock by addr not implemented!")
|
||||
|
||||
method getBlockAndProof*(self: BlockStore, treeCid: Cid, index: Natural): Future[?!(Block, CodexProof)] {.base.} =
|
||||
method getBlockAndProof*(self: BlockStore, treeCid: Cid, index: Natural): Future[?!(Block, CodexProof)] {.base, gcsafe.} =
|
||||
## Get a block and associated inclusion proof by Cid of a merkle tree and an index of a leaf in a tree
|
||||
##
|
||||
|
||||
@ -65,7 +65,7 @@ method getBlockAndProof*(self: BlockStore, treeCid: Cid, index: Natural): Future
|
||||
method putBlock*(
|
||||
self: BlockStore,
|
||||
blk: Block,
|
||||
ttl = Duration.none): Future[?!void] {.base.} =
|
||||
ttl = Duration.none): Future[?!void] {.base, gcsafe.} =
|
||||
## Put a block to the blockstore
|
||||
##
|
||||
|
||||
@ -76,7 +76,7 @@ method putCidAndProof*(
|
||||
treeCid: Cid,
|
||||
index: Natural,
|
||||
blockCid: Cid,
|
||||
proof: CodexProof): Future[?!void] {.base.} =
|
||||
proof: CodexProof): Future[?!void] {.base, gcsafe.} =
|
||||
## Put a block proof to the blockstore
|
||||
##
|
||||
|
||||
@ -85,7 +85,7 @@ method putCidAndProof*(
|
||||
method getCidAndProof*(
|
||||
self: BlockStore,
|
||||
treeCid: Cid,
|
||||
index: Natural): Future[?!(Cid, CodexProof)] {.base.} =
|
||||
index: Natural): Future[?!(Cid, CodexProof)] {.base, gcsafe.} =
|
||||
## Get a block proof from the blockstore
|
||||
##
|
||||
|
||||
@ -94,7 +94,7 @@ method getCidAndProof*(
|
||||
method ensureExpiry*(
|
||||
self: BlockStore,
|
||||
cid: Cid,
|
||||
expiry: SecondsSince1970): Future[?!void] {.base.} =
|
||||
expiry: SecondsSince1970): Future[?!void] {.base, gcsafe.} =
|
||||
## Ensure that block's assosicated expiry is at least given timestamp
|
||||
## If the current expiry is lower then it is updated to the given one, otherwise it is left intact
|
||||
##
|
||||
@ -105,32 +105,32 @@ method ensureExpiry*(
|
||||
self: BlockStore,
|
||||
treeCid: Cid,
|
||||
index: Natural,
|
||||
expiry: SecondsSince1970): Future[?!void] {.base.} =
|
||||
expiry: SecondsSince1970): Future[?!void] {.base, gcsafe.} =
|
||||
## Ensure that block's associated expiry is at least given timestamp
|
||||
## If the current expiry is lower then it is updated to the given one, otherwise it is left intact
|
||||
##
|
||||
|
||||
raiseAssert("Not implemented!")
|
||||
|
||||
method delBlock*(self: BlockStore, cid: Cid): Future[?!void] {.base.} =
|
||||
method delBlock*(self: BlockStore, cid: Cid): Future[?!void] {.base, gcsafe.} =
|
||||
## Delete a block from the blockstore
|
||||
##
|
||||
|
||||
raiseAssert("delBlock not implemented!")
|
||||
|
||||
method delBlock*(self: BlockStore, treeCid: Cid, index: Natural): Future[?!void] {.base.} =
|
||||
method delBlock*(self: BlockStore, treeCid: Cid, index: Natural): Future[?!void] {.base, gcsafe.} =
|
||||
## Delete a block from the blockstore
|
||||
##
|
||||
|
||||
raiseAssert("delBlock not implemented!")
|
||||
|
||||
method hasBlock*(self: BlockStore, cid: Cid): Future[?!bool] {.base.} =
|
||||
method hasBlock*(self: BlockStore, cid: Cid): Future[?!bool] {.base, gcsafe.} =
|
||||
## Check if the block exists in the blockstore
|
||||
##
|
||||
|
||||
raiseAssert("hasBlock not implemented!")
|
||||
|
||||
method hasBlock*(self: BlockStore, tree: Cid, index: Natural): Future[?!bool] {.base.} =
|
||||
method hasBlock*(self: BlockStore, tree: Cid, index: Natural): Future[?!bool] {.base, gcsafe.} =
|
||||
## Check if the block exists in the blockstore
|
||||
##
|
||||
|
||||
@ -138,13 +138,13 @@ method hasBlock*(self: BlockStore, tree: Cid, index: Natural): Future[?!bool] {.
|
||||
|
||||
method listBlocks*(
|
||||
self: BlockStore,
|
||||
blockType = BlockType.Manifest): Future[?!AsyncIter[?Cid]] {.base.} =
|
||||
blockType = BlockType.Manifest): Future[?!AsyncIter[?Cid]] {.base, gcsafe.} =
|
||||
## Get the list of blocks in the BlockStore. This is an intensive operation
|
||||
##
|
||||
|
||||
raiseAssert("listBlocks not implemented!")
|
||||
|
||||
method close*(self: BlockStore): Future[void] {.base.} =
|
||||
method close*(self: BlockStore): Future[void] {.base, gcsafe.} =
|
||||
## Close the blockstore, cleaning up resources managed by it.
|
||||
## For some implementations this may be a no-op
|
||||
##
|
||||
|
@ -323,15 +323,16 @@ method getBlockExpirations*(
|
||||
return failure(err)
|
||||
|
||||
let
|
||||
filteredIter = await asyncQueryIter.filterSuccess()
|
||||
blockExpIter = await mapFilter[KeyVal[BlockMetadata], BlockExpiration](filteredIter,
|
||||
proc (kv: KeyVal[BlockMetadata]): Future[?BlockExpiration] {.async.} =
|
||||
without cid =? Cid.init(kv.key.value).mapFailure, err:
|
||||
error "Failed decoding cid", err = err.msg
|
||||
return BlockExpiration.none
|
||||
filteredIter: AsyncIter[KeyVal[BlockMetadata]] = await asyncQueryIter.filterSuccess()
|
||||
|
||||
BlockExpiration(cid: cid, expiry: kv.value.expiry).some
|
||||
)
|
||||
proc mapping (kv: KeyVal[BlockMetadata]): Future[?BlockExpiration] {.async.} =
|
||||
without cid =? Cid.init(kv.key.value).mapFailure, err:
|
||||
error "Failed decoding cid", err = err.msg
|
||||
return BlockExpiration.none
|
||||
|
||||
BlockExpiration(cid: cid, expiry: kv.value.expiry).some
|
||||
|
||||
let blockExpIter = await mapFilter[KeyVal[BlockMetadata], BlockExpiration](filteredIter, mapping)
|
||||
|
||||
success(blockExpIter)
|
||||
|
||||
|
@ -64,7 +64,7 @@ method readOnce*(
|
||||
self: AsyncStreamWrapper,
|
||||
pbytes: pointer,
|
||||
nbytes: int
|
||||
): Future[int] {.async.} =
|
||||
): Future[int] {.async: (raises: [CancelledError, LPStreamError]).} =
|
||||
|
||||
trace "Reading bytes from reader", bytes = nbytes
|
||||
if isNil(self.reader):
|
||||
@ -118,7 +118,7 @@ method closed*(self: AsyncStreamWrapper): bool =
|
||||
method atEof*(self: AsyncStreamWrapper): bool =
|
||||
self.reader.atEof()
|
||||
|
||||
method closeImpl*(self: AsyncStreamWrapper) {.async.} =
|
||||
method closeImpl*(self: AsyncStreamWrapper) {.async: (raises: []).} =
|
||||
try:
|
||||
trace "Shutting down async chronos stream"
|
||||
if not self.closed():
|
||||
@ -130,7 +130,7 @@ method closeImpl*(self: AsyncStreamWrapper) {.async.} =
|
||||
|
||||
trace "Shutdown async chronos stream"
|
||||
except CancelledError as exc:
|
||||
raise exc
|
||||
error "Error received cancelled error when closing chronos stream", msg = exc.msg
|
||||
except CatchableError as exc:
|
||||
trace "Error closing async chronos stream", msg = exc.msg
|
||||
|
||||
|
@ -73,11 +73,20 @@ proc `size=`*(self: StoreStream, size: int)
|
||||
method atEof*(self: StoreStream): bool =
|
||||
self.offset >= self.size
|
||||
|
||||
type LPStreamReadError* = object of LPStreamError
|
||||
par*: ref CatchableError
|
||||
|
||||
proc newLPStreamReadError*(p: ref CatchableError): ref LPStreamReadError =
|
||||
var w = newException(LPStreamReadError, "Read stream failed")
|
||||
w.msg = w.msg & ", originated from [" & $p.name & "] " & p.msg
|
||||
w.par = p
|
||||
result = w
|
||||
|
||||
method readOnce*(
|
||||
self: StoreStream,
|
||||
pbytes: pointer,
|
||||
nbytes: int
|
||||
): Future[int] {.async.} =
|
||||
): Future[int] {.async: (raises: [CancelledError, LPStreamError]).} =
|
||||
## Read `nbytes` from current position in the StoreStream into output buffer pointed by `pbytes`.
|
||||
## Return how many bytes were actually read before EOF was encountered.
|
||||
## Raise exception if we are already at EOF.
|
||||
@ -100,8 +109,9 @@ method readOnce*(
|
||||
self.manifest.blockSize.int - blockOffset])
|
||||
address = BlockAddress(leaf: true, treeCid: self.manifest.treeCid, index: blockNum)
|
||||
|
||||
|
||||
# Read contents of block `blockNum`
|
||||
without blk =? await self.store.getBlock(address), error:
|
||||
without blk =? (await self.store.getBlock(address)).tryGet.catch, error:
|
||||
raise newLPStreamReadError(error)
|
||||
|
||||
trace "Reading bytes from store stream", manifestCid = self.manifest.cid.get(), numBlocks = self.manifest.blocksCount, blockNum, blkCid = blk.cid, bytes = readBytes, blockOffset
|
||||
|
@ -19,7 +19,7 @@ import pkg/stew/endians2
|
||||
|
||||
func remapAddr*(
|
||||
address: MultiAddress,
|
||||
ip: Option[ValidIpAddress] = ValidIpAddress.none,
|
||||
ip: Option[IpAddress] = IpAddress.none,
|
||||
port: Option[Port] = Port.none
|
||||
): MultiAddress =
|
||||
## Remap addresses to new IP and/or Port
|
||||
@ -41,7 +41,7 @@ func remapAddr*(
|
||||
MultiAddress.init(parts.join("/"))
|
||||
.expect("Should construct multiaddress")
|
||||
|
||||
proc getMultiAddrWithIPAndUDPPort*(ip: ValidIpAddress, port: Port): MultiAddress =
|
||||
proc getMultiAddrWithIPAndUDPPort*(ip: IpAddress, port: Port): MultiAddress =
|
||||
## Creates a MultiAddress with the specified IP address and UDP port
|
||||
##
|
||||
## Parameters:
|
||||
@ -54,7 +54,7 @@ proc getMultiAddrWithIPAndUDPPort*(ip: ValidIpAddress, port: Port): MultiAddress
|
||||
let ipFamily = if ip.family == IpAddressFamily.IPv4: "/ip4/" else: "/ip6/"
|
||||
return MultiAddress.init(ipFamily & $ip & "/udp/" & $port).expect("valid multiaddr")
|
||||
|
||||
proc getAddressAndPort*(ma: MultiAddress): tuple[ip: Option[ValidIpAddress], port: Option[Port]] =
|
||||
proc getAddressAndPort*(ma: MultiAddress): tuple[ip: Option[IpAddress], port: Option[Port]] =
|
||||
try:
|
||||
# Try IPv4 first
|
||||
let ipv4Result = ma[multiCodec("ip4")]
|
||||
@ -63,7 +63,7 @@ proc getAddressAndPort*(ma: MultiAddress): tuple[ip: Option[ValidIpAddress], por
|
||||
.protoArgument()
|
||||
.expect("Invalid IPv4 format")
|
||||
let ipArray = [ipBytes[0], ipBytes[1], ipBytes[2], ipBytes[3]]
|
||||
some(ipv4(ipArray))
|
||||
some(IpAddress(family: IPv4, address_v4: ipArray))
|
||||
else:
|
||||
# Try IPv6 if IPv4 not found
|
||||
let ipv6Result = ma[multiCodec("ip6")]
|
||||
@ -74,9 +74,9 @@ proc getAddressAndPort*(ma: MultiAddress): tuple[ip: Option[ValidIpAddress], por
|
||||
var ipArray: array[16, byte]
|
||||
for i in 0..15:
|
||||
ipArray[i] = ipBytes[i]
|
||||
some(ipv6(ipArray))
|
||||
some(IpAddress(family: IPv6, address_v6: ipArray))
|
||||
else:
|
||||
none(ValidIpAddress)
|
||||
none(IpAddress)
|
||||
|
||||
# Get TCP Port
|
||||
let portResult = ma[multiCodec("tcp")]
|
||||
@ -89,4 +89,4 @@ proc getAddressAndPort*(ma: MultiAddress): tuple[ip: Option[ValidIpAddress], por
|
||||
none(Port)
|
||||
(ip: ip, port: port)
|
||||
except Exception:
|
||||
(ip: none(ValidIpAddress), port: none(Port))
|
||||
(ip: none(IpAddress), port: none(Port))
|
||||
|
@ -22,7 +22,7 @@ logScope:
|
||||
proc new*[T: Machine](_: type T): T =
|
||||
T(trackedFutures: TrackedFutures.new())
|
||||
|
||||
method `$`*(state: State): string {.base.} =
|
||||
method `$`*(state: State): string {.base, gcsafe.} =
|
||||
raiseAssert "not implemented"
|
||||
|
||||
proc transition(_: type Event, previous, next: State): Event =
|
||||
|
@ -16,14 +16,14 @@ type
|
||||
type
|
||||
IpLimits* = object
|
||||
limit*: uint
|
||||
ips: Table[ValidIpAddress, uint]
|
||||
ips: Table[IpAddress, uint]
|
||||
|
||||
func hash*(ip: ValidIpAddress): Hash =
|
||||
func hash*(ip: IpAddress): Hash =
|
||||
case ip.family
|
||||
of IpAddressFamily.IPv6: hash(ip.address_v6)
|
||||
of IpAddressFamily.IPv4: hash(ip.address_v4)
|
||||
|
||||
func inc*(ipLimits: var IpLimits, ip: ValidIpAddress): bool =
|
||||
func inc*(ipLimits: var IpLimits, ip: IpAddress): bool =
|
||||
let val = ipLimits.ips.getOrDefault(ip, 0)
|
||||
if val < ipLimits.limit:
|
||||
ipLimits.ips[ip] = val + 1
|
||||
@ -31,7 +31,7 @@ func inc*(ipLimits: var IpLimits, ip: ValidIpAddress): bool =
|
||||
else:
|
||||
false
|
||||
|
||||
func dec*(ipLimits: var IpLimits, ip: ValidIpAddress) =
|
||||
func dec*(ipLimits: var IpLimits, ip: IpAddress) =
|
||||
let val = ipLimits.ips.getOrDefault(ip, 0)
|
||||
if val == 1:
|
||||
ipLimits.ips.del(ip)
|
||||
@ -48,7 +48,7 @@ func isGlobalUnicast*(address: IpAddress): bool =
|
||||
let a = initTAddress(address, Port(0))
|
||||
a.isGlobalUnicast()
|
||||
|
||||
proc getRouteIpv4*(): Result[ValidIpAddress, cstring] =
|
||||
proc getRouteIpv4*(): Result[IpAddress, cstring] =
|
||||
# Avoiding Exception with initTAddress and can't make it work with static.
|
||||
# Note: `publicAddress` is only used an "example" IP to find the best route,
|
||||
# no data is send over the network to this IP!
|
||||
@ -65,4 +65,4 @@ proc getRouteIpv4*(): Result[ValidIpAddress, cstring] =
|
||||
# This should not occur really.
|
||||
error "Address conversion error", exception = e.name, msg = e.msg
|
||||
return err("Invalid IP address")
|
||||
ok(ValidIpAddress.init(ip))
|
||||
ok(ip)
|
@ -8,6 +8,14 @@ proc `as`*[T](value: T, U: type): ?U =
|
||||
## Casts a value to another type, returns an Option.
|
||||
## When the cast succeeds, the option will contain the casted value.
|
||||
## When the cast fails, the option will have no value.
|
||||
|
||||
# In Nim 2.0.x, check 42.some as int == none(int)
|
||||
# Maybe because some 42.some looks like Option[Option[int]]
|
||||
# So we check first that the value is an option of the expected type.
|
||||
# In that case, we do not need to do anything, just return the value as it is.
|
||||
when value is Option[U]:
|
||||
return value
|
||||
|
||||
when value is U:
|
||||
return some value
|
||||
elif value is ref object:
|
||||
|
@ -40,7 +40,7 @@ proc timerLoop(timer: Timer) {.async: (raises: []).} =
|
||||
except CatchableError as exc:
|
||||
error "Timer caught unhandled exception: ", name=timer.name, msg=exc.msg
|
||||
|
||||
method start*(timer: Timer, callback: TimerCallback, interval: Duration) {.base.} =
|
||||
method start*(timer: Timer, callback: TimerCallback, interval: Duration) {.gcsafe, base.} =
|
||||
if timer.loopFuture != nil:
|
||||
return
|
||||
trace "Timer starting: ", name=timer.name
|
||||
|
@ -41,7 +41,7 @@ when defined(windows):
|
||||
|
||||
# The dynamic Chronicles output currently prevents us from using colors on Windows
|
||||
# because these require direct manipulations of the stdout File object.
|
||||
switch("define", "chronicles_colors=off")
|
||||
switch("define", "chronicles_colors=NoColors")
|
||||
|
||||
# This helps especially for 32-bit x86, which sans SSE2 and newer instructions
|
||||
# requires quite roundabout code generation for cryptography, and other 64-bit
|
||||
@ -85,6 +85,8 @@ when (NimMajor, NimMinor) >= (1, 6):
|
||||
--warning:"DotLikeOps:off"
|
||||
when (NimMajor, NimMinor, NimPatch) >= (1, 6, 11):
|
||||
--warning:"BareExcept:off"
|
||||
when (NimMajor, NimMinor) >= (2, 0):
|
||||
--mm:refc
|
||||
|
||||
switch("define", "withoutPCRE")
|
||||
|
||||
|
36
flake.lock
generated
36
flake.lock
generated
@ -2,14 +2,16 @@
|
||||
"nodes": {
|
||||
"circom-compat": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs"
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1732627240,
|
||||
"narHash": "sha256-GvJTiBWBv799i5ZCCc4gF86bnQY/nZvx0vCPi1+OPD4=",
|
||||
"lastModified": 1736521871,
|
||||
"narHash": "sha256-d34XNLg9NGPEOARHW+BIOAWalkHdEUAwsv3mpLZQxds=",
|
||||
"owner": "codex-storage",
|
||||
"repo": "circom-compat-ffi",
|
||||
"rev": "297c46fdc7d8a8fd53c8076b0be77334e4a54447",
|
||||
"rev": "8cd4ed44fdafe59d4ec1184420639cae4c4dbab9",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -20,32 +22,16 @@
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1731386116,
|
||||
"narHash": "sha256-lKA770aUmjPHdTaJWnP3yQ9OI1TigenUqVC3wweqZuI=",
|
||||
"lastModified": 1736200483,
|
||||
"narHash": "sha256-JO+lFN2HsCwSLMUWXHeOad6QUxOuwe9UOAF/iSl1J4I=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "689fed12a013f56d4c4d3f612489634267d86529",
|
||||
"rev": "3f0a8ac25fb674611b98089ca3a5dd6480175751",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-24.05",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_2": {
|
||||
"locked": {
|
||||
"lastModified": 1729449015,
|
||||
"narHash": "sha256-Gf04dXB0n4q0A9G5nTGH3zuMGr6jtJppqdeljxua1fo=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "89172919243df199fe237ba0f776c3e3e3d72367",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-24.05",
|
||||
"ref": "nixos-24.11",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
@ -53,7 +39,7 @@
|
||||
"root": {
|
||||
"inputs": {
|
||||
"circom-compat": "circom-compat",
|
||||
"nixpkgs": "nixpkgs_2"
|
||||
"nixpkgs": "nixpkgs"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
51
flake.nix
51
flake.nix
@ -1,9 +1,12 @@
|
||||
{
|
||||
description = "Codex build flake";
|
||||
|
||||
description = "Nim Codex build flake";
|
||||
|
||||
inputs = {
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.05";
|
||||
circom-compat.url = "github:codex-storage/circom-compat-ffi";
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.11";
|
||||
circom-compat = {
|
||||
url = "github:codex-storage/circom-compat-ffi";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
};
|
||||
|
||||
outputs = { self, nixpkgs, circom-compat}:
|
||||
@ -17,27 +20,57 @@
|
||||
in rec {
|
||||
packages = forAllSystems (system: let
|
||||
circomCompatPkg = circom-compat.packages.${system}.default;
|
||||
buildTarget = pkgsFor.${system}.callPackage ./nix/default.nix {
|
||||
buildTarget = pkgsFor.${system}.callPackage ./nix/default.nix rec {
|
||||
inherit stableSystems circomCompatPkg;
|
||||
src = self;
|
||||
src = pkgsFor.${system}.lib.traceValFn (v: "self.submodules: ${toString v.submodules}") self;
|
||||
};
|
||||
build = targets: buildTarget.override { inherit targets; };
|
||||
in rec {
|
||||
codex = build ["all"];
|
||||
default = codex;
|
||||
nim-codex = build ["all"];
|
||||
default = nim-codex;
|
||||
});
|
||||
|
||||
nixosModules.nim-codex = { config, lib, pkgs, ... }: import ./nix/service.nix {
|
||||
inherit config lib pkgs self;
|
||||
circomCompatPkg = circom-compat.packages.${pkgs.system}.default;
|
||||
};
|
||||
|
||||
devShells = forAllSystems (system: let
|
||||
pkgs = pkgsFor.${system};
|
||||
in {
|
||||
default = pkgs.mkShell {
|
||||
inputsFrom = [
|
||||
packages.${system}.codex
|
||||
packages.${system}.nim-codex
|
||||
circom-compat.packages.${system}.default
|
||||
];
|
||||
# Not using buildInputs to override fakeGit and fakeCargo.
|
||||
nativeBuildInputs = with pkgs; [ git cargo nodejs_18 ];
|
||||
};
|
||||
});
|
||||
|
||||
checks = forAllSystems (system: let
|
||||
pkgs = pkgsFor.${system};
|
||||
in {
|
||||
nim-codex-test = pkgs.nixosTest {
|
||||
name = "nim-codex-test";
|
||||
nodes = {
|
||||
server = { config, pkgs, ... }: {
|
||||
imports = [ self.nixosModules.nim-codex ];
|
||||
services.nim-codex.enable = true;
|
||||
services.nim-codex.settings = {
|
||||
data-dir = "/var/lib/nim-codex-test";
|
||||
};
|
||||
systemd.services.nim-codex.serviceConfig.StateDirectory = "nim-codex-test";
|
||||
};
|
||||
};
|
||||
testScript = ''
|
||||
print("Starting test: nim-codex-test")
|
||||
machine.start()
|
||||
machine.wait_for_unit("nim-codex.service")
|
||||
machine.succeed("test -d /var/lib/nim-codex-test")
|
||||
machine.wait_until_succeeds("journalctl -u nim-codex.service | grep 'Started codex node'", 10)
|
||||
'';
|
||||
};
|
||||
});
|
||||
};
|
||||
}
|
@ -11,7 +11,7 @@ nix develop
|
||||
|
||||
To build a Codex you can use:
|
||||
```sh
|
||||
nix build '.?submodules=1#codex'
|
||||
nix build '.?submodules=1#default'
|
||||
```
|
||||
The `?submodules=1` part should eventually not be necessary.
|
||||
For more details see:
|
||||
@ -19,11 +19,17 @@ https://github.com/NixOS/nix/issues/4423
|
||||
|
||||
It can be also done without even cloning the repo:
|
||||
```sh
|
||||
nix build 'github:codex-storage/nim-codex?submodules=1'
|
||||
nix build 'git+https://github.com/codex-storage/nim-codex?submodules=1#'
|
||||
```
|
||||
|
||||
## Running
|
||||
|
||||
```sh
|
||||
nix run 'github:codex-storage/nim-codex?submodules=1'
|
||||
nix run 'git+https://github.com/codex-storage/nim-codex?submodules=1#''
|
||||
```
|
||||
|
||||
## Testing
|
||||
|
||||
```sh
|
||||
nix flake check ".?submodules=1#"
|
||||
```
|
@ -17,18 +17,21 @@
|
||||
).packages.${builtins.currentSystem}.default
|
||||
}:
|
||||
|
||||
assert pkgs.lib.assertMsg ((src.submodules or true) == true)
|
||||
"Unable to build without submodules. Append '?submodules=1#' to the URI.";
|
||||
|
||||
let
|
||||
inherit (pkgs) stdenv lib writeScriptBin callPackage;
|
||||
|
||||
|
||||
revision = lib.substring 0 8 (src.rev or "dirty");
|
||||
|
||||
tools = callPackage ./tools.nix {};
|
||||
in pkgs.gcc11Stdenv.mkDerivation rec {
|
||||
|
||||
|
||||
pname = "codex";
|
||||
|
||||
version = "${tools.findKeyValue "version = \"([0-9]+\.[0-9]+\.[0-9]+)\"" ../codex.nimble}-${revision}";
|
||||
|
||||
|
||||
inherit src;
|
||||
|
||||
# Dependencies that should exist in the runtime environment.
|
||||
@ -69,16 +72,16 @@ in pkgs.gcc11Stdenv.mkDerivation rec {
|
||||
configurePhase = ''
|
||||
patchShebangs . > /dev/null
|
||||
'';
|
||||
|
||||
|
||||
installPhase = ''
|
||||
mkdir -p $out/bin
|
||||
cp build/codex $out/bin/
|
||||
'';
|
||||
|
||||
meta = with pkgs.lib; {
|
||||
description = "Codex storage system";
|
||||
description = "Nim Codex storage system";
|
||||
homepage = "https://github.com/codex-storage/nim-codex";
|
||||
license = licenses.mit;
|
||||
platforms = stableSystems;
|
||||
};
|
||||
}
|
||||
}
|
57
nix/service.nix
Normal file
57
nix/service.nix
Normal file
@ -0,0 +1,57 @@
|
||||
{ self, config, lib, pkgs, circomCompatPkg, ... }:
|
||||
|
||||
let
|
||||
inherit (lib)
|
||||
types mkEnableOption mkOption mkIf literalExpression
|
||||
mdDoc;
|
||||
|
||||
toml = pkgs.formats.toml { };
|
||||
|
||||
cfg = config.services.nim-codex;
|
||||
in
|
||||
{
|
||||
options = {
|
||||
services.nim-codex = {
|
||||
enable = mkEnableOption "Nim Codex Node service.";
|
||||
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.callPackage ./default.nix { src = self; inherit circomCompatPkg; };
|
||||
defaultText = literalExpression "pkgs.codex";
|
||||
description = mdDoc "Package to use as Nim Codex node.";
|
||||
};
|
||||
|
||||
settings = mkOption {
|
||||
default = { };
|
||||
type = toml.type;
|
||||
description = ''Structured settings object that will be used to generate a TOML config file.'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
environment.etc = {
|
||||
"nim-codex/config.toml".source = toml.generate "config.toml" cfg.settings;
|
||||
};
|
||||
systemd.services.nim-codex = {
|
||||
description = "Nim Codex Node";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
requires = [ "network.target" ];
|
||||
serviceConfig = {
|
||||
DynamicUser = true;
|
||||
PrivateTmp = true;
|
||||
ProtectHome = true;
|
||||
ProtectSystem = "full";
|
||||
NoNewPrivileges = true;
|
||||
PrivateDevices = true;
|
||||
MemoryDenyWriteExecute = true;
|
||||
ExecStart = "${cfg.package}/bin/codex --config-file=/etc/nim-codex/config.toml";
|
||||
Restart = "on-failure";
|
||||
};
|
||||
restartIfChanged = true;
|
||||
restartTriggers = [
|
||||
"/etc/nim-codex/config.toml"
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
@ -46,7 +46,8 @@ proc generateNodes*(
|
||||
networkStore = NetworkStore.new(engine, localStore)
|
||||
|
||||
switch.mount(network)
|
||||
result.add((
|
||||
|
||||
let nc : NodesComponents = (
|
||||
switch,
|
||||
discovery,
|
||||
wallet,
|
||||
@ -56,7 +57,9 @@ proc generateNodes*(
|
||||
pendingBlocks,
|
||||
blockDiscovery,
|
||||
engine,
|
||||
networkStore))
|
||||
networkStore)
|
||||
|
||||
result.add(nc)
|
||||
|
||||
proc connectNodes*(nodes: seq[Switch]) {.async.} =
|
||||
for dialer in nodes:
|
||||
|
@ -5,7 +5,7 @@ import ../helpers
|
||||
|
||||
export merkletree, helpers
|
||||
|
||||
converter toBool*(x: CtBool): bool =
|
||||
converter toBool*(x: CTBool): bool =
|
||||
bool(x)
|
||||
|
||||
proc `==`*(a, b: Poseidon2Tree): bool =
|
||||
|
@ -70,8 +70,8 @@ template setupAndTearDown*() {.dirty.} =
|
||||
network: BlockExcNetwork
|
||||
clock: Clock
|
||||
localStore: RepoStore
|
||||
localStoreRepoDs: DataStore
|
||||
localStoreMetaDs: DataStore
|
||||
localStoreRepoDs: Datastore
|
||||
localStoreMetaDs: Datastore
|
||||
engine: BlockExcEngine
|
||||
store: NetworkStore
|
||||
node: CodexNodeRef
|
||||
@ -80,7 +80,6 @@ template setupAndTearDown*() {.dirty.} =
|
||||
pendingBlocks: PendingBlocksManager
|
||||
discovery: DiscoveryEngine
|
||||
advertiser: Advertiser
|
||||
taskpool: Taskpool
|
||||
|
||||
let
|
||||
path = currentSourcePath().parentDir
|
||||
@ -110,14 +109,12 @@ template setupAndTearDown*() {.dirty.} =
|
||||
advertiser = Advertiser.new(localStore, blockDiscovery)
|
||||
engine = BlockExcEngine.new(localStore, wallet, network, discovery, advertiser, peerStore, pendingBlocks)
|
||||
store = NetworkStore.new(engine, localStore)
|
||||
taskpool = Taskpool.new(num_threads = countProcessors())
|
||||
node = CodexNodeRef.new(
|
||||
switch = switch,
|
||||
networkStore = store,
|
||||
engine = engine,
|
||||
prover = Prover.none,
|
||||
discovery = blockDiscovery,
|
||||
taskpool = taskpool)
|
||||
discovery = blockDiscovery)
|
||||
|
||||
teardown:
|
||||
close(file)
|
||||
|
@ -2,7 +2,6 @@ import std/os
|
||||
import std/options
|
||||
import std/times
|
||||
import std/importutils
|
||||
import std/cpuinfo
|
||||
|
||||
import pkg/chronos
|
||||
import pkg/datastore
|
||||
@ -76,7 +75,7 @@ asyncchecksuite "Test Node - Host contracts":
|
||||
manifestBlock = bt.Block.new(
|
||||
manifest.encode().tryGet(),
|
||||
codec = ManifestCodec).tryGet()
|
||||
erasure = Erasure.new(store, leoEncoderProvider, leoDecoderProvider, taskpool)
|
||||
erasure = Erasure.new(store, leoEncoderProvider, leoDecoderProvider)
|
||||
|
||||
manifestCid = manifestBlock.cid
|
||||
manifestCidStr = $(manifestCid)
|
||||
|
@ -2,7 +2,6 @@ import std/os
|
||||
import std/options
|
||||
import std/math
|
||||
import std/importutils
|
||||
import std/cpuinfo
|
||||
|
||||
import pkg/chronos
|
||||
import pkg/stew/byteutils
|
||||
@ -13,7 +12,6 @@ import pkg/questionable/results
|
||||
import pkg/stint
|
||||
import pkg/poseidon2
|
||||
import pkg/poseidon2/io
|
||||
import pkg/taskpools
|
||||
|
||||
import pkg/nitro
|
||||
import pkg/codexdht/discv5/protocol as discv5
|
||||
@ -139,7 +137,7 @@ asyncchecksuite "Test Node - Basic":
|
||||
|
||||
test "Setup purchase request":
|
||||
let
|
||||
erasure = Erasure.new(store, leoEncoderProvider, leoDecoderProvider, taskpool)
|
||||
erasure = Erasure.new(store, leoEncoderProvider, leoDecoderProvider)
|
||||
manifest = await storeDataGetManifest(localStore, chunker)
|
||||
manifestBlock = bt.Block.new(
|
||||
manifest.encode().tryGet(),
|
||||
|
@ -101,7 +101,7 @@ asyncchecksuite "Sales agent":
|
||||
clock.set(market.requestExpiry[request.id] + 1)
|
||||
check eventually onCancelCalled
|
||||
|
||||
for requestState in {RequestState.New, Started, Finished, Failed}:
|
||||
for requestState in {RequestState.New, RequestState.Started, RequestState.Finished, RequestState.Failed}:
|
||||
test "onCancelled is not called when request state is " & $requestState:
|
||||
agent.start(MockState.new())
|
||||
await agent.subscribe()
|
||||
@ -110,7 +110,7 @@ asyncchecksuite "Sales agent":
|
||||
await sleepAsync(100.millis)
|
||||
check not onCancelCalled
|
||||
|
||||
for requestState in {RequestState.Started, Finished, Failed}:
|
||||
for requestState in {RequestState.Started, RequestState.Finished, RequestState.Failed}:
|
||||
test "cancelled future is finished when request state is " & $requestState:
|
||||
agent.start(MockState.new())
|
||||
await agent.subscribe()
|
||||
|
@ -96,11 +96,11 @@ proc createProtectedManifest*(
|
||||
protectedTreeCid = protectedTree.rootCid().tryGet()
|
||||
|
||||
for index, cid in cids[0..<numDatasetBlocks]:
|
||||
let proof = datasetTree.getProof(index).tryget()
|
||||
let proof = datasetTree.getProof(index).tryGet()
|
||||
(await store.putCidAndProof(datasetTreeCid, index, cid, proof)).tryGet
|
||||
|
||||
for index, cid in cids:
|
||||
let proof = protectedTree.getProof(index).tryget()
|
||||
let proof = protectedTree.getProof(index).tryGet()
|
||||
(await store.putCidAndProof(protectedTreeCid, index, cid, proof)).tryGet
|
||||
|
||||
let
|
||||
|
@ -7,6 +7,7 @@ import pkg/codex/conf
|
||||
import pkg/codex/slots/proofs/backends
|
||||
import pkg/codex/slots/proofs/backendfactory
|
||||
import pkg/codex/slots/proofs/backendutils
|
||||
import pkg/codex/utils/natutils
|
||||
|
||||
import ../helpers
|
||||
import ../examples
|
||||
@ -50,7 +51,7 @@ suite "Test BackendFactory":
|
||||
nat: NatConfig(
|
||||
hasExtIp: false,
|
||||
nat: NatNone),
|
||||
metricsAddress: ValidIpAddress.init("127.0.0.1"),
|
||||
metricsAddress: parseIpAddress("127.0.0.1"),
|
||||
persistenceCmd: PersistenceCmd.prover,
|
||||
marketplaceAddress: EthAddress.example.some,
|
||||
circomR1cs: InputFile("tests/circuits/fixtures/proof_main.r1cs"),
|
||||
@ -72,7 +73,7 @@ suite "Test BackendFactory":
|
||||
nat: NatConfig(
|
||||
hasExtIp: false,
|
||||
nat: NatNone),
|
||||
metricsAddress: ValidIpAddress.init("127.0.0.1"),
|
||||
metricsAddress: parseIpAddress("127.0.0.1"),
|
||||
persistenceCmd: PersistenceCmd.prover,
|
||||
marketplaceAddress: EthAddress.example.some,
|
||||
|
||||
@ -95,7 +96,7 @@ suite "Test BackendFactory":
|
||||
nat: NatConfig(
|
||||
hasExtIp: false,
|
||||
nat: NatNone),
|
||||
metricsAddress: ValidIpAddress.init("127.0.0.1"),
|
||||
metricsAddress: parseIpAddress("127.0.0.1"),
|
||||
persistenceCmd: PersistenceCmd.prover,
|
||||
marketplaceAddress: EthAddress.example.some,
|
||||
circuitDir: OutDir(circuitDir)
|
||||
|
@ -13,6 +13,7 @@ import pkg/confutils/defs
|
||||
import pkg/poseidon2/io
|
||||
import pkg/codex/utils/poseidon2digest
|
||||
import pkg/codex/nat
|
||||
import pkg/codex/utils/natutils
|
||||
import ./helpers
|
||||
import ../helpers
|
||||
|
||||
@ -38,7 +39,7 @@ suite "Test Prover":
|
||||
nat: NatConfig(
|
||||
hasExtIp: false,
|
||||
nat: NatNone),
|
||||
metricsAddress: ValidIpAddress.init("127.0.0.1"),
|
||||
metricsAddress: parseIpAddress("127.0.0.1"),
|
||||
persistenceCmd: PersistenceCmd.prover,
|
||||
circomR1cs: InputFile("tests/circuits/fixtures/proof_main.r1cs"),
|
||||
circomWasm: InputFile("tests/circuits/fixtures/proof_main.wasm"),
|
||||
|
@ -163,8 +163,9 @@ asyncchecksuite "Asynchronous Tests":
|
||||
|
||||
test "Test update":
|
||||
var heap = newAsyncHeapQueue[Task](5)
|
||||
let data = [("a", 4), ("b", 3), ("c", 2)]
|
||||
|
||||
for item in [("a", 4), ("b", 3), ("c", 2)]:
|
||||
for item in data:
|
||||
check heap.pushNoWait(item).isOk
|
||||
|
||||
check heap[0] == (name: "c", priority: 2)
|
||||
@ -173,8 +174,9 @@ asyncchecksuite "Asynchronous Tests":
|
||||
|
||||
test "Test pushOrUpdate - update":
|
||||
var heap = newAsyncHeapQueue[Task](3)
|
||||
let data = [("a", 4), ("b", 3), ("c", 2)]
|
||||
|
||||
for item in [("a", 4), ("b", 3), ("c", 2)]:
|
||||
for item in data:
|
||||
check heap.pushNoWait(item).isOk
|
||||
|
||||
check heap[0] == (name: "c", priority: 2)
|
||||
@ -183,8 +185,9 @@ asyncchecksuite "Asynchronous Tests":
|
||||
|
||||
test "Test pushOrUpdate - push":
|
||||
var heap = newAsyncHeapQueue[Task](2)
|
||||
let data = [("a", 4), ("b", 3)]
|
||||
|
||||
for item in [("a", 4), ("b", 3)]:
|
||||
for item in data:
|
||||
check heap.pushNoWait(item).isOk
|
||||
|
||||
check heap[0] == ("b", 3) # sanity check for order
|
||||
|
@ -6,16 +6,23 @@ import pkg/chronos
|
||||
import ../asynctest
|
||||
import ./helpers
|
||||
|
||||
# Trying to use a CancelledError or LPStreamError value for toRaise
|
||||
# will produce a compilation error;
|
||||
# Error: only a 'ref object' can be raised
|
||||
# This is because they are not ref object but plain object.
|
||||
# CancelledError* = object of FutureError
|
||||
# LPStreamError* = object of LPError
|
||||
|
||||
type
|
||||
CrashingStreamWrapper* = ref object of LPStream
|
||||
toRaise*: ref CatchableError
|
||||
toRaise*: proc(): void {.gcsafe, raises: [CancelledError, LPStreamError].}
|
||||
|
||||
method readOnce*(
|
||||
self: CrashingStreamWrapper,
|
||||
pbytes: pointer,
|
||||
nbytes: int
|
||||
): Future[int] {.async.} =
|
||||
raise self.toRaise
|
||||
): Future[int] {.gcsafe, async: (raises: [CancelledError, LPStreamError]).} =
|
||||
self.toRaise()
|
||||
|
||||
asyncchecksuite "Chunking":
|
||||
test "should return proper size chunks":
|
||||
@ -88,13 +95,14 @@ asyncchecksuite "Chunking":
|
||||
string.fromBytes(data) == readFile(path)
|
||||
fileChunker.offset == data.len
|
||||
|
||||
proc raiseStreamException(exc: ref CatchableError) {.async.} =
|
||||
proc raiseStreamException(exc: ref CancelledError | ref LPStreamError) {.async.} =
|
||||
let stream = CrashingStreamWrapper.new()
|
||||
let chunker = LPStreamChunker.new(
|
||||
stream = stream,
|
||||
chunkSize = 2'nb)
|
||||
|
||||
stream.toRaise = exc
|
||||
stream.toRaise = proc(): void {.raises: [CancelledError, LPStreamError].} =
|
||||
raise exc
|
||||
discard (await chunker.getBytes())
|
||||
|
||||
test "stream should forward LPStreamError":
|
||||
@ -110,8 +118,4 @@ asyncchecksuite "Chunking":
|
||||
|
||||
test "stream should forward LPStreamError":
|
||||
expect LPStreamError:
|
||||
await raiseStreamException(newException(LPStreamError, "test error"))
|
||||
|
||||
test "stream should convert other exceptions to defect":
|
||||
expect Defect:
|
||||
await raiseStreamException(newException(CatchableError, "test error"))
|
||||
await raiseStreamException(newException(LPStreamError, "test error"))
|
@ -1,6 +1,5 @@
|
||||
import std/sequtils
|
||||
import std/sugar
|
||||
import std/cpuinfo
|
||||
|
||||
import pkg/chronos
|
||||
import pkg/questionable/results
|
||||
@ -12,7 +11,6 @@ import pkg/codex/blocktype as bt
|
||||
import pkg/codex/rng
|
||||
import pkg/codex/utils
|
||||
import pkg/codex/indexingstrategy
|
||||
import pkg/taskpools
|
||||
|
||||
import ../asynctest
|
||||
import ./helpers
|
||||
@ -27,7 +25,6 @@ suite "Erasure encode/decode":
|
||||
var manifest: Manifest
|
||||
var store: BlockStore
|
||||
var erasure: Erasure
|
||||
var taskpool: Taskpool
|
||||
let repoTmp = TempLevelDb.new()
|
||||
let metaTmp = TempLevelDb.new()
|
||||
|
||||
@ -38,8 +35,7 @@ suite "Erasure encode/decode":
|
||||
rng = Rng.instance()
|
||||
chunker = RandomChunker.new(rng, size = dataSetSize, chunkSize = BlockSize)
|
||||
store = RepoStore.new(repoDs, metaDs)
|
||||
taskpool = Taskpool.new(num_threads = countProcessors())
|
||||
erasure = Erasure.new(store, leoEncoderProvider, leoDecoderProvider, taskpool)
|
||||
erasure = Erasure.new(store, leoEncoderProvider, leoDecoderProvider)
|
||||
manifest = await storeDataGetManifest(store, chunker)
|
||||
|
||||
teardown:
|
||||
|
@ -15,7 +15,7 @@ suite "NAT Address Tests":
|
||||
udpPort = Port(1234)
|
||||
natConfig = NatConfig(
|
||||
hasExtIp: true,
|
||||
extIp:ValidIpAddress.init("8.8.8.8"))
|
||||
extIp: parseIpAddress("8.8.8.8"))
|
||||
|
||||
# Create test addresses
|
||||
localAddr = MultiAddress.init("/ip4/127.0.0.1/tcp/5000").expect("valid multiaddr")
|
||||
|
@ -2,6 +2,7 @@ import pkg/ethers
|
||||
import codex/contracts/deployment
|
||||
import codex/conf
|
||||
import codex/contracts
|
||||
import pkg/codex/utils/natutils
|
||||
|
||||
import ../asynctest
|
||||
import ../checktest
|
||||
@ -18,7 +19,7 @@ proc configFactory(): CodexConf =
|
||||
nat: NatConfig(
|
||||
hasExtIp: false,
|
||||
nat: NatNone),
|
||||
metricsAddress: ValidIpAddress.init("127.0.0.1"))
|
||||
metricsAddress: parseIpAddress("127.0.0.1"))
|
||||
|
||||
proc configFactory(marketplace: Option[EthAddress]): CodexConf =
|
||||
CodexConf(
|
||||
@ -26,7 +27,7 @@ proc configFactory(marketplace: Option[EthAddress]): CodexConf =
|
||||
nat: NatConfig(
|
||||
hasExtIp: false,
|
||||
nat: NatNone),
|
||||
metricsAddress: ValidIpAddress.init("127.0.0.1"),
|
||||
metricsAddress: parseIpAddress("127.0.0.1"),
|
||||
marketplaceAddress: marketplace)
|
||||
|
||||
asyncchecksuite "Deployment":
|
||||
|
@ -14,9 +14,9 @@ var number = 0
|
||||
proc newDb*(self: TempLevelDb): Datastore =
|
||||
if self.currentPath.len > 0:
|
||||
raiseAssert("TempLevelDb already active.")
|
||||
self.currentPath = getTempDir() / "templeveldb" / $number / $getmonotime()
|
||||
self.currentPath = getTempDir() / "templeveldb" / $number / $getMonoTime()
|
||||
inc number
|
||||
createdir(self.currentPath)
|
||||
createDir(self.currentPath)
|
||||
self.ds = LevelDbDatastore.new(self.currentPath).tryGet()
|
||||
return self.ds
|
||||
|
||||
@ -26,5 +26,5 @@ proc destroyDb*(self: TempLevelDb): Future[void] {.async.} =
|
||||
try:
|
||||
(await self.ds.close()).tryGet()
|
||||
finally:
|
||||
removedir(self.currentPath)
|
||||
removeDir(self.currentPath)
|
||||
self.currentPath = ""
|
||||
|
@ -26,22 +26,22 @@ type
|
||||
name*: string
|
||||
NodeProcessError* = object of CatchableError
|
||||
|
||||
method workingDir(node: NodeProcess): string {.base.} =
|
||||
method workingDir(node: NodeProcess): string {.base, gcsafe.} =
|
||||
raiseAssert "not implemented"
|
||||
|
||||
method executable(node: NodeProcess): string {.base.} =
|
||||
method executable(node: NodeProcess): string {.base, gcsafe.} =
|
||||
raiseAssert "not implemented"
|
||||
|
||||
method startedOutput(node: NodeProcess): string {.base.} =
|
||||
method startedOutput(node: NodeProcess): string {.base, gcsafe.} =
|
||||
raiseAssert "not implemented"
|
||||
|
||||
method processOptions(node: NodeProcess): set[AsyncProcessOption] {.base.} =
|
||||
method processOptions(node: NodeProcess): set[AsyncProcessOption] {.base, gcsafe.} =
|
||||
raiseAssert "not implemented"
|
||||
|
||||
method outputLineEndings(node: NodeProcess): string {.base, raises: [].} =
|
||||
method outputLineEndings(node: NodeProcess): string {.base, gcsafe raises: [].} =
|
||||
raiseAssert "not implemented"
|
||||
|
||||
method onOutputLineCaptured(node: NodeProcess, line: string) {.base, raises: [].} =
|
||||
method onOutputLineCaptured(node: NodeProcess, line: string) {.base, gcsafe, raises: [].} =
|
||||
raiseAssert "not implemented"
|
||||
|
||||
method start*(node: NodeProcess) {.base, async.} =
|
||||
|
2
vendor/asynctest
vendored
2
vendor/asynctest
vendored
@ -1 +1 @@
|
||||
Subproject commit 8e2f4e73b97123be0f0041c129942b32df23ecb1
|
||||
Subproject commit 5154c0d79dd8bb086ab418cc659e923330ac24f2
|
2
vendor/codex-storage-proofs-circuits
vendored
2
vendor/codex-storage-proofs-circuits
vendored
@ -1 +1 @@
|
||||
Subproject commit c03b43221d68e34bd5015a4e4ee1a0ad3299f8ef
|
||||
Subproject commit ac8d3667526862458b162bee71dd5dcf6170c209
|
2
vendor/combparser
vendored
2
vendor/combparser
vendored
@ -1 +1 @@
|
||||
Subproject commit ba4464c005d7617c008e2ed2ebc1ba52feb469c6
|
||||
Subproject commit e582c436e8750b60253370fd77960509d36e3738
|
2
vendor/constantine
vendored
2
vendor/constantine
vendored
@ -1 +1 @@
|
||||
Subproject commit 8367d7d19cdbba874aab961b70d272e742184c37
|
||||
Subproject commit bc3845aa492b52f7fef047503b1592e830d1a774
|
2
vendor/nim-bearssl
vendored
2
vendor/nim-bearssl
vendored
@ -1 +1 @@
|
||||
Subproject commit 99fcb3405c55b27cfffbf60f5368c55da7346f23
|
||||
Subproject commit 667b40440a53a58e9f922e29e20818720c62d9ac
|
2
vendor/nim-blscurve
vendored
2
vendor/nim-blscurve
vendored
@ -1 +1 @@
|
||||
Subproject commit 48d8668c5a9a350d3a7ee0c3713ef9a11980a40d
|
||||
Subproject commit de2d3c79264bba18dbea469c8c5c4b3bb3c8bc55
|
2
vendor/nim-chronicles
vendored
2
vendor/nim-chronicles
vendored
@ -1 +1 @@
|
||||
Subproject commit c9c8e58ec3f89b655a046c485f622f9021c68b61
|
||||
Subproject commit 81a4a7a360c78be9c80c8f735c76b6d4a1517304
|
2
vendor/nim-chronos
vendored
2
vendor/nim-chronos
vendored
@ -1 +1 @@
|
||||
Subproject commit 035ae11ba92369e7722e649db597e79134fd06b9
|
||||
Subproject commit c04576d829b8a0a1b12baaa8bc92037501b3a4a0
|
2
vendor/nim-codex-dht
vendored
2
vendor/nim-codex-dht
vendored
@ -1 +1 @@
|
||||
Subproject commit 63822e83561ea1c6396d0f3eca583b038f5d44c6
|
||||
Subproject commit 4bd3a39e0030f8ee269ef217344b6b59ec2be6dc
|
2
vendor/nim-confutils
vendored
2
vendor/nim-confutils
vendored
@ -1 +1 @@
|
||||
Subproject commit 2028b41602b3abf7c9bf450744efde7b296707a2
|
||||
Subproject commit cb858a27f4347be949d10ed74b58713d687936d2
|
2
vendor/nim-contract-abi
vendored
2
vendor/nim-contract-abi
vendored
@ -1 +1 @@
|
||||
Subproject commit 61f8f59b3917d8e27c6eb4330a6d8cf428e98b2d
|
||||
Subproject commit 842f48910be4f388bcbf8abf1f02aba1d5e2ee64
|
2
vendor/nim-datastore
vendored
2
vendor/nim-datastore
vendored
@ -1 +1 @@
|
||||
Subproject commit 3ab6b84a634a7b2ee8c0144f050bf5893cd47c17
|
||||
Subproject commit d67860add63fd23cdacde1d3da8f4739c2660c2d
|
2
vendor/nim-eth
vendored
2
vendor/nim-eth
vendored
@ -1 +1 @@
|
||||
Subproject commit 15a09fab737d08a2545284c727199c377bb0f4b7
|
||||
Subproject commit dcfbc4291d39b59563828c3e32be4d51a2f25931
|
2
vendor/nim-ethers
vendored
2
vendor/nim-ethers
vendored
@ -1 +1 @@
|
||||
Subproject commit 2808a05488152c8b438d947dc871445164fa1278
|
||||
Subproject commit 1cfccb9695fa47860bf7ef3d75da9019096a3933
|
2
vendor/nim-faststreams
vendored
2
vendor/nim-faststreams
vendored
@ -1 +1 @@
|
||||
Subproject commit 720fc5e5c8e428d9d0af618e1e27c44b42350309
|
||||
Subproject commit cf8d4d22636b8e514caf17e49f9c786ac56b0e85
|
2
vendor/nim-http-utils
vendored
2
vendor/nim-http-utils
vendored
@ -1 +1 @@
|
||||
Subproject commit be57dbc902d36f37540897e98c69aa80f868cb45
|
||||
Subproject commit 8bb1acbaa4b86eb866145b0d468eff64a57d1897
|
2
vendor/nim-json-rpc
vendored
2
vendor/nim-json-rpc
vendored
@ -1 +1 @@
|
||||
Subproject commit 0408795be95c00d75e96eaef6eae8a9c734014f5
|
||||
Subproject commit 274372132de497e6b7b793c9d5d5474b71bf80a2
|
2
vendor/nim-json-serialization
vendored
2
vendor/nim-json-serialization
vendored
@ -1 +1 @@
|
||||
Subproject commit 5127b26ee58076e9369e7c126c196793c2b12e73
|
||||
Subproject commit 6eadb6e939ffa7882ff5437033c11a9464d3385c
|
2
vendor/nim-leopard
vendored
2
vendor/nim-leopard
vendored
@ -1 +1 @@
|
||||
Subproject commit 895ff24ca6615d577acfb11811cdd5465f596c97
|
||||
Subproject commit 3e09d8113f874f3584c3fe93818541b2ff9fb9c3
|
2
vendor/nim-libbacktrace
vendored
2
vendor/nim-libbacktrace
vendored
@ -1 +1 @@
|
||||
Subproject commit b29c22ba0ef13de50b779c776830dbea1d50cd33
|
||||
Subproject commit 6da0cda88ab7780bd5fd342327adb91ab84692aa
|
2
vendor/nim-libp2p
vendored
2
vendor/nim-libp2p
vendored
@ -1 +1 @@
|
||||
Subproject commit b239791c568d9f9a76fd66d2322b2754700b6cc5
|
||||
Subproject commit 036e110a6080fba1a1662c58cfd8c21f9a548021
|
2
vendor/nim-metrics
vendored
2
vendor/nim-metrics
vendored
@ -1 +1 @@
|
||||
Subproject commit 6142e433fc8ea9b73379770a788017ac528d46ff
|
||||
Subproject commit cacfdc12454a0804c65112b9f4f50d1375208dcd
|
2
vendor/nim-nat-traversal
vendored
2
vendor/nim-nat-traversal
vendored
@ -1 +1 @@
|
||||
Subproject commit 27d314d65c9078924b3239fe4e2f5af0c512b28c
|
||||
Subproject commit 5e4059746e9095e1731b02eeaecd62a70fbe664d
|
2
vendor/nim-nitro
vendored
2
vendor/nim-nitro
vendored
@ -1 +1 @@
|
||||
Subproject commit 6b4c455bf4dad7449c1580055733a1738fcd5aec
|
||||
Subproject commit e3719433d5ace25947c468787c805969642b3913
|
2
vendor/nim-poseidon2
vendored
2
vendor/nim-poseidon2
vendored
@ -1 +1 @@
|
||||
Subproject commit 0346982f2c6891bcedd03d552af3a3bd57b2c1f9
|
||||
Subproject commit 4e2c6e619b2f2859aaa4b2aed2f346ea4d0c67a3
|
2
vendor/nim-presto
vendored
2
vendor/nim-presto
vendored
@ -1 +1 @@
|
||||
Subproject commit c17bfdda2c60cf5fadb043feb22e328b7659c719
|
||||
Subproject commit 92b1c7ff141e6920e1f8a98a14c35c1fa098e3be
|
2
vendor/nim-protobuf-serialization
vendored
2
vendor/nim-protobuf-serialization
vendored
@ -1 +1 @@
|
||||
Subproject commit 28214b3e40c755a9886d2ec8f261ec48fbb6bec6
|
||||
Subproject commit 5a31137a82c2b6a989c9ed979bb636c7a49f570e
|
2
vendor/nim-results
vendored
2
vendor/nim-results
vendored
@ -1 +1 @@
|
||||
Subproject commit f3c666a272c69d70cb41e7245e7f6844797303ad
|
||||
Subproject commit df8113dda4c2d74d460a8fa98252b0b771bf1f27
|
2
vendor/nim-serde
vendored
2
vendor/nim-serde
vendored
@ -1 +1 @@
|
||||
Subproject commit 83e4a2ccf621d3040c6e7e0267393ca2d205988e
|
||||
Subproject commit 69a7a0111addaa4aad885dd4bd7b5ee4684a06de
|
2
vendor/nim-serialization
vendored
2
vendor/nim-serialization
vendored
@ -1 +1 @@
|
||||
Subproject commit f709bd9e16b1b6870fe3e4401196479e014a2ef6
|
||||
Subproject commit 2086c99608b4bf472e1ef5fe063710f280243396
|
2
vendor/nim-sqlite3-abi
vendored
2
vendor/nim-sqlite3-abi
vendored
@ -1 +1 @@
|
||||
Subproject commit 362e1bd9f689ad9f5380d9d27f0705b3d4dfc7d3
|
||||
Subproject commit 05bbff1af4e8fe2d972ba4b0667b89ca94d3ebba
|
2
vendor/nim-stew
vendored
2
vendor/nim-stew
vendored
@ -1 +1 @@
|
||||
Subproject commit 7afe7e3c070758cac1f628e4330109f3ef6fc853
|
||||
Subproject commit a6e198132097fb544d04959aeb3b839e1408f942
|
2
vendor/nim-taskpools
vendored
2
vendor/nim-taskpools
vendored
@ -1 +1 @@
|
||||
Subproject commit b3673c7a7a959ccacb393bd9b47e997bbd177f5a
|
||||
Subproject commit 66585e2e960b7695e48ea60377fb3aeac96406e8
|
2
vendor/nim-testutils
vendored
2
vendor/nim-testutils
vendored
@ -1 +1 @@
|
||||
Subproject commit b56a5953e37fc5117bd6ea6dfa18418c5e112815
|
||||
Subproject commit 4d37244f9f5e1acd8592a4ceb5c3fc47bc160181
|
2
vendor/nim-toml-serialization
vendored
2
vendor/nim-toml-serialization
vendored
@ -1 +1 @@
|
||||
Subproject commit 86d477136f105f04bfd0dd7c0e939593d81fc581
|
||||
Subproject commit fea85b27f0badcf617033ca1bc05444b5fd8aa7a
|
2
vendor/nim-unittest2
vendored
2
vendor/nim-unittest2
vendored
@ -1 +1 @@
|
||||
Subproject commit b178f47527074964f76c395ad0dfc81cf118f379
|
||||
Subproject commit 845b6af28b9f68f02d320e03ad18eccccea7ddb9
|
2
vendor/nim-websock
vendored
2
vendor/nim-websock
vendored
@ -1 +1 @@
|
||||
Subproject commit 2c3ae3137f3c9cb48134285bd4a47186fa51f0e8
|
||||
Subproject commit ebe308a79a7b440a11dfbe74f352be86a3883508
|
2
vendor/nim-zlib
vendored
2
vendor/nim-zlib
vendored
@ -1 +1 @@
|
||||
Subproject commit f34ca261efd90f118dc1647beefd2f7a69b05d93
|
||||
Subproject commit 91cf360b1aeb2e0c753ff8bac6de22a41c5ed8cd
|
2
vendor/nimbus-build-system
vendored
2
vendor/nimbus-build-system
vendored
@ -1 +1 @@
|
||||
Subproject commit fe9bc3f3759ae1add6bf8c899db2e75327f03782
|
||||
Subproject commit 4c6ff070c116450bb2c285691724ac9e6202cb28
|
2
vendor/nimcrypto
vendored
2
vendor/nimcrypto
vendored
@ -1 +1 @@
|
||||
Subproject commit 24e006df85927f64916e60511620583b11403178
|
||||
Subproject commit dc07e3058c6904eef965394493b6ea99aa2adefc
|
2
vendor/npeg
vendored
2
vendor/npeg
vendored
@ -1 +1 @@
|
||||
Subproject commit b15a10e388b91b898c581dbbcb6a718d46b27d2f
|
||||
Subproject commit 409f6796d0e880b3f0222c964d1da7de6e450811
|
2
vendor/stint
vendored
2
vendor/stint
vendored
@ -1 +1 @@
|
||||
Subproject commit 86621eced1dcfb5e25903019ebcfc76ed9128ec5
|
||||
Subproject commit 5c5e01cef089a261474b7abfe246b37447aaa8ed
|
2
vendor/upraises
vendored
2
vendor/upraises
vendored
@ -1 +1 @@
|
||||
Subproject commit ff4f8108e44fba9b35cac535ab63d3927e8fd3c2
|
||||
Subproject commit bc2628989b63854d980e92dadbd58f83e34b6f25
|
Loading…
x
Reference in New Issue
Block a user