diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e8dbbe46..9fcb1de7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,7 +7,7 @@ on: workflow_dispatch: env: cache_nonce: 0 # Allows for easily busting actions/cache caches - nim_version: v1.6.10 + nim_version: v1.6.14 jobs: build: strategy: @@ -105,7 +105,9 @@ jobs: nim_version: ${{ env.nim_version }} - name: Generate coverage data - run: make -j${ncpu} coverage + run: | + # make -j${ncpu} coverage + make -j${ncpu} coverage-script shell: bash - name: Upload coverage data to Codecov diff --git a/.gitignore b/.gitignore index 05d53c20..c85aa931 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,8 @@ coverage/ # Nimble packages /vendor/.nimble +/vendor/packages/ +# /vendor/*/ # Nimble user files nimble.develop @@ -36,3 +38,4 @@ nimbus-build-system.paths docker/hostdatadir docker/prometheus-data .DS_Store +nim.cfg diff --git a/.gitmodules b/.gitmodules index b74ec86f..8cc85d0e 100644 --- a/.gitmodules +++ b/.gitmodules @@ -181,3 +181,15 @@ [submodule "vendor/codex-contracts-eth"] path = vendor/codex-contracts-eth url = https://github.com/status-im/codex-contracts-eth +[submodule "vendor/nim-protobuf-serialization"] + path = vendor/nim-protobuf-serialization + url = https://github.com/status-im/nim-protobuf-serialization +[submodule "vendor/nim-results"] + path = vendor/nim-results + url = https://github.com/arnetheduck/nim-results +[submodule "vendor/nim-testutils"] + path = vendor/nim-testutils + url = https://github.com/status-im/nim-testutils +[submodule "vendor/npeg"] + path = vendor/npeg + url = https://github.com/zevv/npeg diff --git a/Makefile b/Makefile index e629d710..0f7545f4 100644 --- a/Makefile +++ b/Makefile @@ -48,7 +48,7 @@ else # "variables.mk" was included. Business as usual until the end of this file # Builds the codex binary all: | build deps echo -e $(BUILD_MSG) "build/$@" && \ - $(ENV_SCRIPT) nim codex $(NIM_PARAMS) codex.nims + $(ENV_SCRIPT) nim codex $(NIM_PARAMS) build.nims # must be included after the default target -include $(BUILD_SYSTEM_DIR)/makefiles/targets.mk @@ -60,15 +60,12 @@ else NIM_PARAMS := $(NIM_PARAMS) -d:release endif -deps: | deps-common nat-libs codex.nims +deps: | deps-common nat-libs ifneq ($(USE_LIBBACKTRACE), 0) deps: | libbacktrace endif -#- deletes and recreates "codex.nims" which on Windows is a copy instead of a proper symlink update: | update-common - rm -rf codex.nims && \ - $(MAKE) codex.nims $(HANDLE_OUTPUT) # detecting the os ifeq ($(OS),Windows_NT) # is Windows_NT on XP, 2000, 7, Vista, 10... @@ -83,26 +80,22 @@ endif # Builds and run a part of the test suite test: | build deps echo -e $(BUILD_MSG) "build/$@" && \ - $(ENV_SCRIPT) nim test $(NIM_PARAMS) codex.nims + $(ENV_SCRIPT) nim test $(NIM_PARAMS) build.nims # Builds and runs the smart contract tests testContracts: | build deps echo -e $(BUILD_MSG) "build/$@" && \ - $(ENV_SCRIPT) nim testContracts $(NIM_PARAMS) codex.nims + $(ENV_SCRIPT) nim testContracts $(NIM_PARAMS) build.nims # Builds and runs the integration tests testIntegration: | build deps echo -e $(BUILD_MSG) "build/$@" && \ - $(ENV_SCRIPT) nim testIntegration $(NIM_PARAMS) codex.nims + $(ENV_SCRIPT) nim testIntegration $(NIM_PARAMS) build.nims # Builds and runs all tests testAll: | build deps echo -e $(BUILD_MSG) "build/$@" && \ - $(ENV_SCRIPT) nim testAll $(NIM_PARAMS) codex.nims - -# symlink -codex.nims: - ln -s codex.nimble $@ + $(ENV_SCRIPT) nim testAll $(NIM_PARAMS) build.nims # nim-libbacktrace LIBBACKTRACE_MAKE_FLAGS := -C vendor/nim-libbacktrace --no-print-directory BUILD_CXX_LIB=0 @@ -127,8 +120,15 @@ coverage: shopt -s globstar && lcov --extract coverage/coverage.info $$(pwd)/codex/{*,**/*}.nim --output-file coverage/coverage.f.info echo -e $(BUILD_MSG) "coverage/report/index.html" genhtml coverage/coverage.f.info --output-directory coverage/report + +show-coverage: if which open >/dev/null; then (echo -e "\e[92mOpening\e[39m HTML coverage report in browser..." && open coverage/report/index.html) || true; fi +coverage-script: build deps + echo -e $(BUILD_MSG) "build/$@" && \ + $(ENV_SCRIPT) nim coverage $(NIM_PARAMS) build.nims + echo "Run `make show-coverage` to view coverage results" + # usual cleaning clean: | clean-common rm -rf build diff --git a/atlas.lock b/atlas.lock new file mode 100644 index 00000000..b37d03e3 --- /dev/null +++ b/atlas.lock @@ -0,0 +1,209 @@ +{ + "clangVersion": "", + "gccVersion": "", + "hostCPU": "arm64", + "hostOS": "macosx", + "items": { + "asynctest": { + "commit": "fe1a34caf572b05f8bdba3b650f1871af9fce31e", + "dir": "vendor/asynctest", + "url": "https://github.com/codex-storage/asynctest" + }, + "dnsclient.nim": { + "commit": "23214235d4784d24aceed99bbfe153379ea557c8", + "dir": "vendor/dnsclient.nim", + "url": "https://github.com/ba0f3/dnsclient.nim" + }, + "lrucache.nim": { + "commit": "8767ade0b76ea5b5d4ce24a52d0c58a6ebeb66cd", + "dir": "vendor/lrucache.nim", + "url": "https://github.com/status-im/lrucache.nim" + }, + "nim-bearssl": { + "commit": "99fcb3405c55b27cfffbf60f5368c55da7346f23", + "dir": "vendor/nim-bearssl", + "url": "https://github.com/status-im/nim-bearssl" + }, + "nim-blscurve": { + "commit": "48d8668c5a9a350d3a7ee0c3713ef9a11980a40d", + "dir": "vendor/nim-blscurve", + "url": "https://github.com/status-im/nim-blscurve" + }, + "nim-chronicles": { + "commit": "c9c8e58ec3f89b655a046c485f622f9021c68b61", + "dir": "vendor/nim-chronicles", + "url": "https://github.com/status-im/nim-chronicles" + }, + "nim-chronos": { + "commit": "0277b65be2c7a365ac13df002fba6e172be55537", + "dir": "vendor/nim-chronos", + "url": "https://github.com/status-im/nim-chronos" + }, + "nim-confutils": { + "commit": "2028b41602b3abf7c9bf450744efde7b296707a2", + "dir": "vendor/nim-confutils", + "url": "https://github.com/status-im/nim-confutils" + }, + "nim-contract-abi": { + "commit": "61f8f59b3917d8e27c6eb4330a6d8cf428e98b2d", + "dir": "vendor/nim-contract-abi", + "url": "https://github.com/status-im/nim-contract-abi" + }, + "nim-datastore": { + "commit": "0cde8aeb67c59fd0ac95496dc6b5e1168d6632aa", + "dir": "vendor/nim-datastore", + "url": "https://github.com/codex-storage/nim-datastore" + }, + "nim-faststreams": { + "commit": "720fc5e5c8e428d9d0af618e1e27c44b42350309", + "dir": "vendor/nim-faststreams", + "url": "https://github.com/status-im/nim-faststreams" + }, + "nim-http-utils": { + "commit": "3b491a40c60aad9e8d3407443f46f62511e63b18", + "dir": "vendor/nim-http-utils", + "url": "https://github.com/status-im/nim-http-utils" + }, + "nim-json-rpc": { + "commit": "0bf2bcbe74a18a3c7a709d57108bb7b51e748a92", + "dir": "vendor/nim-json-rpc", + "url": "https://github.com/status-im/nim-json-rpc" + }, + "nim-json-serialization": { + "commit": "bb53d49caf2a6c6cf1df365ba84af93cdcfa7aa3", + "dir": "vendor/nim-json-serialization", + "url": "https://github.com/status-im/nim-json-serialization" + }, + "nim-leopard": { + "commit": "1a6f2ab7252426a6ac01482a68b75d0c3b134cf0", + "dir": "vendor/nim-leopard", + "url": "https://github.com/status-im/nim-leopard" + }, + "nim-libbacktrace": { + "commit": "b29c22ba0ef13de50b779c776830dbea1d50cd33", + "dir": "vendor/nim-libbacktrace", + "url": "https://github.com/status-im/nim-libbacktrace" + }, + "nim-libp2p": { + "commit": "440461b24b9e66542b34d26a0b908c17f6549d05", + "dir": "vendor/nim-libp2p", + "url": "https://github.com/status-im/nim-libp2p" + }, + "nim-libp2p-dht": { + "commit": "fdd02450aa6979add7dabd29a3ba0f8738bf89f8", + "dir": "vendor/nim-libp2p-dht", + "url": "https://github.com/status-im/nim-libp2p-dht" + }, + "nim-metrics": { + "commit": "6142e433fc8ea9b73379770a788017ac528d46ff", + "dir": "vendor/nim-metrics", + "url": "https://github.com/status-im/nim-metrics" + }, + "nim-nat-traversal": { + "commit": "27d314d65c9078924b3239fe4e2f5af0c512b28c", + "dir": "vendor/nim-nat-traversal", + "url": "https://github.com/status-im/nim-nat-traversal" + }, + "nim-nitro": { + "commit": "6b4c455bf4dad7449c1580055733a1738fcd5aec", + "dir": "vendor/nim-nitro", + "url": "https://github.com/status-im/nim-nitro" + }, + "nim-presto": { + "commit": "3984431dc0fc829eb668e12e57e90542b041d298", + "dir": "vendor/nim-presto", + "url": "https://github.com/status-im/nim-presto" + }, + "nim-protobuf-serialization": { + "commit": "28214b3e40c755a9886d2ec8f261ec48fbb6bec6", + "dir": "vendor/nim-protobuf-serialization", + "url": "https://github.com/status-im/nim-protobuf-serialization" + }, + "nim-results": { + "commit": "f3c666a272c69d70cb41e7245e7f6844797303ad", + "dir": "vendor/nim-results", + "url": "https://github.com/arnetheduck/nim-results" + }, + "nim-secp256k1": { + "commit": "2acbbdcc0e63002a013fff49f015708522875832", + "dir": "vendor/nim-secp256k1", + "url": "https://github.com/status-im/nim-secp256k1" + }, + "nim-serialization": { + "commit": "384eb2561ee755446cff512a8e057325848b86a7", + "dir": "vendor/nim-serialization", + "url": "https://github.com/status-im/nim-serialization" + }, + "nim-sqlite3-abi": { + "commit": "362e1bd9f689ad9f5380d9d27f0705b3d4dfc7d3", + "dir": "vendor/nim-sqlite3-abi", + "url": "https://github.com/arnetheduck/nim-sqlite3-abi" + }, + "nim-stew": { + "commit": "7afe7e3c070758cac1f628e4330109f3ef6fc853", + "dir": "vendor/nim-stew", + "url": "https://github.com/status-im/nim-stew" + }, + "nim-taskpools": { + "commit": "b3673c7a7a959ccacb393bd9b47e997bbd177f5a", + "dir": "vendor/nim-taskpools", + "url": "https://github.com/status-im/nim-taskpools" + }, + "nim-testutils": { + "commit": "b56a5953e37fc5117bd6ea6dfa18418c5e112815", + "dir": "vendor/nim-testutils", + "url": "https://github.com/status-im/nim-testutils" + }, + "nim-toml-serialization": { + "commit": "86d477136f105f04bfd0dd7c0e939593d81fc581", + "dir": "vendor/nim-toml-serialization", + "url": "https://github.com/status-im/nim-toml-serialization" + }, + "nim-unittest2": { + "commit": "b178f47527074964f76c395ad0dfc81cf118f379", + "dir": "vendor/nim-unittest2", + "url": "https://github.com/status-im/nim-unittest2" + }, + "nim-websock": { + "commit": "2c3ae3137f3c9cb48134285bd4a47186fa51f0e8", + "dir": "vendor/nim-websock", + "url": "https://github.com/status-im/nim-websock" + }, + "nim-zlib": { + "commit": "f34ca261efd90f118dc1647beefd2f7a69b05d93", + "dir": "vendor/nim-zlib", + "url": "https://github.com/status-im/nim-zlib" + }, + "nim-stint": { + "dir": "vendor/stint", + "url": "https://github.com/status-im/nim-stint", + "commit": "86621eced1dcfb5e25903019ebcfc76ed9128ec5" + }, + "nimcrypto": { + "commit": "24e006df85927f64916e60511620583b11403178", + "dir": "vendor/nimcrypto", + "url": "https://github.com/status-im/nimcrypto" + }, + "npeg": { + "commit": "b15a10e388b91b898c581dbbcb6a718d46b27d2f", + "dir": "vendor/npeg", + "url": "https://github.com/zevv/npeg" + }, + "questionable": { + "commit": "b3cf35ac450fd42c9ea83dc084f5cba2efc55da3", + "dir": "vendor/questionable", + "url": "https://github.com/codex-storage/questionable" + }, + "upraises": { + "commit": "ff4f8108e44fba9b35cac535ab63d3927e8fd3c2", + "dir": "vendor/upraises", + "url": "https://github.com/markspanbroek/upraises" + } + }, + "nimVersion": "1.6.14", + "nimbleFile": { + "content": "# Package\n\nversion = \"0.3.2\"\nauthor = \"Status Research & Development GmbH\"\ndescription = \"DHT based on the libp2p Kademlia spec\"\nlicense = \"MIT\"\nskipDirs = @[\"tests\"]\n\n\n# Dependencies\nrequires \"nim >= 1.2.0\"\nrequires \"secp256k1#2acbbdcc0e63002a013fff49f015708522875832\" # >= 0.5.2 & < 0.6.0\nrequires \"protobuf_serialization\" # >= 0.2.0 & < 0.3.0\nrequires \"nimcrypto == 0.5.4\"\nrequires \"bearssl#head\"\nrequires \"chronicles >= 0.10.2 & < 0.11.0\"\nrequires \"chronos == 3.2.0\" # >= 3.0.11 & < 3.1.0\nrequires \"libp2p#unstable\"\nrequires \"metrics\"\nrequires \"stew#head\"\nrequires \"stint\"\nrequires \"asynctest >= 0.3.1 & < 0.4.0\"\nrequires \"https://github.com/codex-storage/nim-datastore#head\"\nrequires \"questionable\"\n\ninclude \"build.nims\"\n\n", + "filename": "" + }, + "nimcfg": "############# begin Atlas config section ##########\n--noNimblePath\n--path:\"vendor/nim-secp256k1\"\n--path:\"vendor/nim-protobuf-serialization\"\n--path:\"vendor/nimcrypto\"\n--path:\"vendor/nim-bearssl\"\n--path:\"vendor/nim-chronicles\"\n--path:\"vendor/nim-chronos\"\n--path:\"vendor/nim-libp2p\"\n--path:\"vendor/nim-metrics\"\n--path:\"vendor/nim-stew\"\n--path:\"vendor/nim-stint\"\n--path:\"vendor/asynctest\"\n--path:\"vendor/nim-datastore\"\n--path:\"vendor/questionable\"\n--path:\"vendor/nim-faststreams\"\n--path:\"vendor/nim-serialization\"\n--path:\"vendor/npeg/src\"\n--path:\"vendor/nim-unittest2\"\n--path:\"vendor/nim-testutils\"\n--path:\"vendor/nim-json-serialization\"\n--path:\"vendor/nim-http-utils\"\n--path:\"vendor/dnsclient.nim/src\"\n--path:\"vendor/nim-websock\"\n--path:\"vendor/nim-results\"\n--path:\"vendor/nim-sqlite3-abi\"\n--path:\"vendor/upraises\"\n--path:\"vendor/nim-zlib\"\n############# end Atlas config section ##########\n" +} diff --git a/build.nims b/build.nims new file mode 100644 index 00000000..bf89c0f0 --- /dev/null +++ b/build.nims @@ -0,0 +1,87 @@ +mode = ScriptMode.Verbose + + +### Helper functions +proc buildBinary(name: string, srcDir = "./", params = "", lang = "c") = + if not dirExists "build": + mkDir "build" + # allow something like "nim nimbus --verbosity:0 --hints:off nimbus.nims" + var extra_params = params + when compiles(commandLineParams): + for param in commandLineParams(): + extra_params &= " " & param + else: + for i in 2..= 1.2.0" requires "asynctest >= 0.3.2 & < 0.4.0" @@ -32,47 +31,4 @@ requires "blscurve" requires "libp2pdht" requires "eth" -when declared(namedBin): - namedBin = { - "codex/codex": "codex" - }.toTable() - -### Helper functions -proc buildBinary(name: string, srcDir = "./", params = "", lang = "c") = - if not dirExists "build": - mkDir "build" - # allow something like "nim nimbus --verbosity:0 --hints:off nimbus.nims" - var extra_params = params - when compiles(commandLineParams): - for param in commandLineParams: - extra_params &= " " & param - else: - for i in 2.. ref CatchableError: (ref exc)(msg: $e))) + exp.mapErr(proc (e: V): ref CatchableError = (ref exc)(msg: $e)) + +template mapFailure*[T, V](exp: Result[T, V]): Result[T, ref CatchableError] = + mapFailure(exp, CodexError) diff --git a/codex/formats.nim b/codex/formats.nim index ec79dabe..38881bc9 100644 --- a/codex/formats.nim +++ b/codex/formats.nim @@ -10,7 +10,7 @@ import std/strutils import pkg/chronicles -import pkg/libp2p +import pkg/libp2p/cid func shortLog*(cid: Cid): string = ## Returns compact string representation of ``pid``. diff --git a/codex/manifest/manifest.nim b/codex/manifest/manifest.nim index d231f69c..1bf307ae 100644 --- a/codex/manifest/manifest.nim +++ b/codex/manifest/manifest.nim @@ -101,7 +101,8 @@ func `[]=`*(self: Manifest, i: BackwardsIndex, item: Cid) = self.blocks[self.len - i.int] = item func isManifest*(cid: Cid): ?!bool = - ($(?cid.contentType().mapFailure) in ManifestContainers).success + let res = ?cid.contentType().mapFailure(CodexError) + ($(res) in ManifestContainers).success func isManifest*(mc: MultiCodec): ?!bool = ($mc in ManifestContainers).success @@ -189,11 +190,8 @@ proc makeRoot*(self: Manifest): ?!void = stack.add(mh) if stack.len == 1: - let cid = ? Cid.init( - self.version, - self.codec, - (? EmptyDigests[self.version][self.hcodec].catch)) - .mapFailure + let digest = ? EmptyDigests[self.version][self.hcodec].catch + let cid = ? Cid.init(self.version, self.codec, digest).mapFailure self.rootHash = cid.some @@ -225,8 +223,8 @@ proc new*( ## Create a manifest using an array of `Cid`s ## - if hcodec notin EmptyDigests[version]: - return failure("Unsupported manifest hash codec!") + # if hcodec notin EmptyDigests[version]: + # return failure("Unsupported manifest hash codec!") T( blocks: @blocks, diff --git a/codex/node.nim b/codex/node.nim index ebc3c540..0fe78dc8 100644 --- a/codex/node.nim +++ b/codex/node.nim @@ -16,7 +16,9 @@ import pkg/questionable import pkg/questionable/results import pkg/chronicles import pkg/chronos -import pkg/libp2p + +import pkg/libp2p/switch +import pkg/libp2p/stream/bufferstream # TODO: remove once exported by libp2p import pkg/libp2p/routing_record @@ -60,23 +62,21 @@ type proc findPeer*( node: CodexNodeRef, - peerId: PeerId -): Future[?PeerRecord] {.async.} = + peerId: PeerId): Future[?PeerRecord] {.async.} = ## Find peer using the discovery service from the given CodexNode ## return await node.discovery.findPeer(peerId) proc connect*( - node: CodexNodeRef, - peerId: PeerId, - addrs: seq[MultiAddress] + node: CodexNodeRef, + peerId: PeerId, + addrs: seq[MultiAddress] ): Future[void] = node.switch.connect(peerId, addrs) proc fetchManifest*( - node: CodexNodeRef, - cid: Cid -): Future[?!Manifest] {.async.} = + node: CodexNodeRef, + cid: Cid): Future[?!Manifest] {.async.} = ## Fetch and decode a manifest block ## @@ -100,11 +100,10 @@ proc fetchManifest*( return manifest.success proc fetchBatched*( - node: CodexNodeRef, - manifest: Manifest, - batchSize = FetchBatch, - onBatch: BatchProc = nil -): Future[?!void] {.async, gcsafe.} = + node: CodexNodeRef, + manifest: Manifest, + batchSize = FetchBatch, + onBatch: BatchProc = nil): Future[?!void] {.async, gcsafe.} = ## Fetch manifest in batches of `batchSize` ## @@ -130,9 +129,8 @@ proc fetchBatched*( return success() proc retrieve*( - node: CodexNodeRef, - cid: Cid -): Future[?!LPStream] {.async.} = + node: CodexNodeRef, + cid: Cid): Future[?!LPStream] {.async.} = ## Retrieve by Cid a single block or an entire dataset described by manifest ## @@ -147,47 +145,35 @@ proc retrieve*( trace "Unable to erasure decode manifest", cid, exc = error.msg except CatchableError as exc: trace "Exception decoding manifest", cid, exc = exc.msg - # + asyncSpawn erasureJob() - # else: - # # Prefetch the entire dataset into the local store - # proc prefetchBlocks() {.async, raises: [Defect].} = - # try: - # discard await node.fetchBatched(manifest) - # except CatchableError as exc: - # trace "Exception prefetching blocks", exc = exc.msg - # # - # # asyncSpawn prefetchBlocks() - temporarily commented out - # + # Retrieve all blocks of the dataset sequentially from the local store or network trace "Creating store stream for manifest", cid - return LPStream(StoreStream.new(node.blockStore, manifest, pad = false)).success + LPStream(StoreStream.new(node.blockStore, manifest, pad = false)).success + else: + let + stream = BufferStream.new() - let - stream = BufferStream.new() + without blk =? (await node.blockStore.getBlock(cid)), err: + return failure(err) - without blk =? (await node.blockStore.getBlock(cid)), err: - return failure(err) + proc streamOneBlock(): Future[void] {.async.} = + try: + await stream.pushData(blk.data) + except CatchableError as exc: + trace "Unable to send block", cid, exc = exc.msg + discard + finally: + await stream.pushEof() - proc streamOneBlock(): Future[void] {.async.} = - try: - await stream.pushData(blk.data) - except CatchableError as exc: - trace "Unable to send block", cid, exc = exc.msg - discard - finally: - await stream.pushEof() - - asyncSpawn streamOneBlock() - return LPStream(stream).success() - - return failure("Unable to retrieve Cid!") + asyncSpawn streamOneBlock() + LPStream(stream).success() proc store*( - self: CodexNodeRef, - stream: LPStream, - blockSize = DefaultBlockSize -): Future[?!Cid] {.async.} = + self: CodexNodeRef, + stream: LPStream, + blockSize = DefaultBlockSize): Future[?!Cid] {.async.} = ## Save stream contents as dataset with given blockSize ## to nodes's BlockStore, and return Cid of its manifest ## @@ -249,16 +235,15 @@ proc store*( return manifest.cid.success proc requestStorage*( - self: CodexNodeRef, - cid: Cid, - duration: UInt256, - proofProbability: UInt256, - nodes: uint, - tolerance: uint, - reward: UInt256, - collateral: UInt256, - expiry = UInt256.none -): Future[?!PurchaseId] {.async.} = + self: CodexNodeRef, + cid: Cid, + duration: UInt256, + proofProbability: UInt256, + nodes: uint, + tolerance: uint, + reward: UInt256, + collateral: UInt256, + expiry = UInt256.none): Future[?!PurchaseId] {.async.} = ## Initiate a request for storage sequence, this might ## be a multistep procedure. ## @@ -323,14 +308,13 @@ proc requestStorage*( return success purchase.id proc new*( - T: type CodexNodeRef, - switch: Switch, - store: BlockStore, - engine: BlockExcEngine, - erasure: Erasure, - discovery: Discovery, - contracts = Contracts.default -): CodexNodeRef = + T: type CodexNodeRef, + switch: Switch, + store: BlockStore, + engine: BlockExcEngine, + erasure: Erasure, + discovery: Discovery, + contracts = Contracts.default): CodexNodeRef = ## Create new instance of a Codex node, call `start` to run it ## CodexNodeRef( diff --git a/codex/rest/api.nim b/codex/rest/api.nim index 651d370d..db4e0d9c 100644 --- a/codex/rest/api.nim +++ b/codex/rest/api.nim @@ -27,9 +27,9 @@ import pkg/confutils import pkg/libp2p import pkg/libp2p/routing_record -import pkg/libp2pdht/discv5/spr as spr -import pkg/libp2pdht/discv5/routing_table as rt -import pkg/libp2pdht/discv5/node as dn +import pkg/codexdht/discv5/spr as spr +import pkg/codexdht/discv5/routing_table as rt +import pkg/codexdht/discv5/node as dn import ../node import ../blocktype diff --git a/codex/storageproofs/stpstore.nim b/codex/storageproofs/stpstore.nim index ff9ceb54..b5f979c3 100644 --- a/codex/storageproofs/stpstore.nim +++ b/codex/storageproofs/stpstore.nim @@ -47,7 +47,7 @@ proc retrieve*( trace "Cannot retrieve storage proof data from fs", path , error return failure("Cannot retrieve storage proof data from fs") - return PorMessage.decode(data).mapFailure + return PorMessage.decode(data).mapFailure(CatchableError) proc store*( self: StpStore, diff --git a/codex/stores/blockstore.nim b/codex/stores/blockstore.nim index 32ed91e8..bba95eac 100644 --- a/codex/stores/blockstore.nim +++ b/codex/stores/blockstore.nim @@ -18,7 +18,7 @@ import pkg/questionable/results import ../blocktype -export blocktype, libp2p +export blocktype type BlockNotFoundError* = object of CodexError diff --git a/codex/stores/repostore.nim b/codex/stores/repostore.nim index c9c79f36..75400296 100644 --- a/codex/stores/repostore.nim +++ b/codex/stores/repostore.nim @@ -13,7 +13,7 @@ push: {.upraises: [].} import pkg/chronos import pkg/chronicles -import pkg/libp2p +import pkg/libp2p/cid import pkg/metrics import pkg/questionable import pkg/questionable/results @@ -26,7 +26,7 @@ import ../blocktype import ../clock import ../systemclock -export blocktype, libp2p +export blocktype, cid logScope: topics = "codex repostore" diff --git a/codex/streams/seekablestream.nim b/codex/streams/seekablestream.nim index 54c13380..785d9afe 100644 --- a/codex/streams/seekablestream.nim +++ b/codex/streams/seekablestream.nim @@ -7,11 +7,11 @@ ## This file may not be copied, modified, or distributed except according to ## those terms. -import pkg/libp2p +import pkg/libp2p/stream/lpstream import pkg/chronos import pkg/chronicles -export libp2p, chronos, chronicles +export lpstream, chronos, chronicles logScope: topics = "codex seekablestream" diff --git a/codex/streams/storestream.nim b/codex/streams/storestream.nim index 0f174aee..809d961c 100644 --- a/codex/streams/storestream.nim +++ b/codex/streams/storestream.nim @@ -13,7 +13,6 @@ import pkg/upraises push: {.upraises: [].} -import pkg/libp2p import pkg/chronos import pkg/chronicles import pkg/stew/ptrops diff --git a/codex/utils/keyutils.nim b/codex/utils/keyutils.nim index 6e14f0b0..ef6f6246 100644 --- a/codex/utils/keyutils.nim +++ b/codex/utils/keyutils.nim @@ -12,12 +12,14 @@ push: {.upraises: [].} import pkg/chronicles import pkg/questionable/results -import pkg/libp2p +import pkg/libp2p/crypto/crypto import ./fileutils import ../errors import ../rng +export crypto + type CodexKeyError = object of CodexError CodexKeyUnsafeError = object of CodexKeyError @@ -37,7 +39,6 @@ proc setupKey*(path: string): ?!PrivateKey = warn "The network private key file is not safe, aborting" return failure newException( CodexKeyUnsafeError, "The network private key file is not safe") - - return PrivateKey.init( - ? path.readAllBytes().mapFailure(CodexKeyError)) - .mapFailure(CodexKeyError) + + let kb = ? path.readAllBytes().mapFailure(CodexKeyError) + return PrivateKey.init(kb).mapFailure(CodexKeyError) diff --git a/config.nims b/config.nims index 15a17563..aa0c1f0f 100644 --- a/config.nims +++ b/config.nims @@ -1,8 +1,10 @@ -import std/os +include "build.nims" + +import std/os const currentDir = currentSourcePath()[0 .. ^(len("config.nims") + 1)] -if getEnv("NIMBUS_BUILD_SYSTEM") == "yes" and +when getEnv("NIMBUS_BUILD_SYSTEM") == "yes" and # BEWARE # In Nim 1.6, config files are evaluated with a working directory # matching where the Nim command was invocated. This means that we @@ -10,12 +12,12 @@ if getEnv("NIMBUS_BUILD_SYSTEM") == "yes" and system.fileExists(currentDir & "nimbus-build-system.paths"): include "nimbus-build-system.paths" -if defined(release): +when defined(release): switch("nimcache", joinPath(currentSourcePath.parentDir, "nimcache/release/$projectName")) else: switch("nimcache", joinPath(currentSourcePath.parentDir, "nimcache/debug/$projectName")) -if defined(limitStackUsage): +when defined(limitStackUsage): # This limits stack usage of each individual function to 1MB - the option is # available on some GCC versions but not all - run with `-d:limitStackUsage` # and look for .su files in "./build/", "./nimcache/" or $TMPDIR that list the @@ -23,7 +25,7 @@ if defined(limitStackUsage): switch("passC", "-fstack-usage -Werror=stack-usage=1048576") switch("passL", "-fstack-usage -Werror=stack-usage=1048576") -if defined(windows): +when defined(windows): # https://github.com/nim-lang/Nim/pull/19891 switch("define", "nimRawSetjmp") @@ -47,8 +49,8 @@ if defined(windows): # engineering a more portable binary release, this should be tweaked but still # use at least -msse2 or -msse3. -if defined(disableMarchNative): - if defined(i386) or defined(amd64): +when defined(disableMarchNative): + when defined(i386) or defined(amd64): switch("passC", "-mssse3") elif defined(macosx) and defined(arm64): # Apple's Clang can't handle "-march=native" on M1: https://github.com/status-im/nimbus-eth2/issues/2758 @@ -93,7 +95,7 @@ if not defined(macosx): --define:nimStackTraceOverride switch("import", "libbacktrace") ---define:nimOldCaseObjects # https://github.com/status-im/nim-confutils/issues/9 +switch("define", "codex_enable_proof_failures=true") # `switch("warning[CaseTransition]", "off")` fails with "Error: invalid command line option: '--warning[CaseTransition]'" switch("warning", "CaseTransition:off") diff --git a/tests/codex/blockexchange/discovery/testdiscovery.nim b/tests/codex/blockexchange/discovery/testdiscovery.nim index 94c8ebd2..6a64255a 100644 --- a/tests/codex/blockexchange/discovery/testdiscovery.nim +++ b/tests/codex/blockexchange/discovery/testdiscovery.nim @@ -5,7 +5,6 @@ import std/tables import pkg/asynctest import pkg/chronos -import pkg/libp2p import pkg/libp2p/errors import pkg/codex/rng diff --git a/tests/codex/blockexchange/discovery/testdiscoveryengine.nim b/tests/codex/blockexchange/discovery/testdiscoveryengine.nim index 4273bbb8..c9259768 100644 --- a/tests/codex/blockexchange/discovery/testdiscoveryengine.nim +++ b/tests/codex/blockexchange/discovery/testdiscoveryengine.nim @@ -5,7 +5,6 @@ import std/tables import pkg/asynctest import pkg/chronos -import pkg/libp2p import pkg/codex/rng import pkg/codex/stores diff --git a/tests/codex/blockexchange/engine/testblockexc.nim b/tests/codex/blockexchange/engine/testblockexc.nim index 4b9e7de4..2a4c9d76 100644 --- a/tests/codex/blockexchange/engine/testblockexc.nim +++ b/tests/codex/blockexchange/engine/testblockexc.nim @@ -5,9 +5,6 @@ import pkg/asynctest import pkg/chronos import pkg/stew/byteutils -import pkg/libp2p -import pkg/libp2p/errors - import pkg/codex/rng import pkg/codex/stores import pkg/codex/blockexchange diff --git a/tests/codex/blockexchange/engine/testengine.nim b/tests/codex/blockexchange/engine/testengine.nim index a7c8786a..a4e496ed 100644 --- a/tests/codex/blockexchange/engine/testengine.nim +++ b/tests/codex/blockexchange/engine/testengine.nim @@ -5,9 +5,9 @@ import std/algorithm import pkg/stew/byteutils import pkg/asynctest import pkg/chronos -import pkg/libp2p +import pkg/libp2p/errors import pkg/libp2p/routing_record -import pkg/libp2pdht/discv5/protocol as discv5 +import pkg/codexdht/discv5/protocol as discv5 import pkg/codex/rng import pkg/codex/blockexchange diff --git a/tests/codex/blockexchange/protobuf/testpresence.nim b/tests/codex/blockexchange/protobuf/testpresence.nim index 1eaf476e..e23a51dc 100644 --- a/tests/codex/blockexchange/protobuf/testpresence.nim +++ b/tests/codex/blockexchange/protobuf/testpresence.nim @@ -1,6 +1,5 @@ import pkg/asynctest import pkg/chronos -import pkg/libp2p import pkg/codex/blockexchange/protobuf/presence import ../../examples diff --git a/tests/codex/blockexchange/testnetwork.nim b/tests/codex/blockexchange/testnetwork.nim index 51d197de..6e791032 100644 --- a/tests/codex/blockexchange/testnetwork.nim +++ b/tests/codex/blockexchange/testnetwork.nim @@ -3,8 +3,6 @@ import std/tables import pkg/asynctest import pkg/chronos -import pkg/libp2p -import pkg/libp2p/errors import pkg/codex/rng import pkg/codex/chunker diff --git a/tests/codex/blockexchange/testpendingblocks.nim b/tests/codex/blockexchange/testpendingblocks.nim index f319b562..03634f9b 100644 --- a/tests/codex/blockexchange/testpendingblocks.nim +++ b/tests/codex/blockexchange/testpendingblocks.nim @@ -3,7 +3,6 @@ import std/algorithm import pkg/chronos import pkg/asynctest -import pkg/libp2p import pkg/stew/byteutils import pkg/codex/blocktype as bt diff --git a/tests/codex/helpers.nim b/tests/codex/helpers.nim index 60b1cd14..20734109 100644 --- a/tests/codex/helpers.nim +++ b/tests/codex/helpers.nim @@ -14,6 +14,8 @@ import ../checktest export randomchunker, nodeutils, mockdiscovery, eventually, checktest, manifest +export libp2p except setup, eventually + # NOTE: The meaning of equality for blocks # is changed here, because blocks are now `ref` # types. This is only in tests!!! diff --git a/tests/codex/helpers/eventually.nim b/tests/codex/helpers/eventually.nim index 3d68fc62..20a957e7 100644 --- a/tests/codex/helpers/eventually.nim +++ b/tests/codex/helpers/eventually.nim @@ -1,6 +1,6 @@ import pkg/chronos -template eventually*(condition: untyped, timeout = 5.seconds): bool = +template eventuallyCheck*(condition: untyped, timeout = 5.seconds): bool = proc loop: Future[bool] {.async.} = let start = Moment.now() while true: diff --git a/tests/codex/helpers/nodeutils.nim b/tests/codex/helpers/nodeutils.nim index df4b470e..83e59a69 100644 --- a/tests/codex/helpers/nodeutils.nim +++ b/tests/codex/helpers/nodeutils.nim @@ -2,6 +2,7 @@ import std/sequtils import pkg/chronos import pkg/libp2p +import pkg/libp2p/errors import pkg/codex/discovery import pkg/codex/stores diff --git a/tests/codex/sales/testsales.nim b/tests/codex/sales/testsales.nim index e8d890d3..332e8e25 100644 --- a/tests/codex/sales/testsales.nim +++ b/tests/codex/sales/testsales.nim @@ -113,7 +113,7 @@ asyncchecksuite "Sales": check isOk await reservations.reserve(availability) await market.requestStorage(request) let items = SlotQueueItem.init(request) - check eventually items.allIt(itemsProcessed.contains(it)) + check eventuallyCheck items.allIt(itemsProcessed.contains(it)) test "removes slots from slot queue once RequestCancelled emitted": let request1 = await addRequestToSaturatedQueue() @@ -146,7 +146,7 @@ asyncchecksuite "Sales": market.emitSlotFreed(request.id, 2.u256) let expected = SlotQueueItem.init(request, 2.uint16) - check eventually itemsProcessed.contains(expected) + check eventuallyCheck itemsProcessed.contains(expected) test "request slots are not added to the slot queue when no availabilities exist": var itemsProcessed: seq[SlotQueueItem] = @[] @@ -185,7 +185,7 @@ asyncchecksuite "Sales": # now add matching availability check isOk await reservations.reserve(availability) - check eventually itemsProcessed.len == request.ask.slots.int + check eventuallyCheck itemsProcessed.len == request.ask.slots.int test "makes storage unavailable when downloading a matched request": var used = false @@ -199,7 +199,7 @@ asyncchecksuite "Sales": check isOk await reservations.reserve(availability) await market.requestStorage(request) - check eventually used + check eventuallyCheck used test "reduces remaining availability size after download": let blk = bt.Block.example @@ -212,7 +212,7 @@ asyncchecksuite "Sales": return success() check isOk await reservations.reserve(availability) await market.requestStorage(request) - check eventually getAvailability().?size == success 1.u256 + check eventuallyCheck getAvailability().?size == success 1.u256 test "ignores download when duration not long enough": availability.duration = request.ask.duration - 1 @@ -265,7 +265,7 @@ asyncchecksuite "Sales": return success() check isOk await reservations.reserve(availability) await market.requestStorage(request) - check eventually storingRequest == request + check eventuallyCheck storingRequest == request check storingSlot < request.ask.slots.u256 test "handles errors during state run": @@ -280,7 +280,7 @@ asyncchecksuite "Sales": saleFailed = true check isOk await reservations.reserve(availability) await market.requestStorage(request) - check eventually saleFailed + check eventuallyCheck saleFailed test "makes storage available again when data retrieval fails": let error = newException(IOError, "data retrieval failed") @@ -290,7 +290,7 @@ asyncchecksuite "Sales": return failure(error) check isOk await reservations.reserve(availability) await market.requestStorage(request) - check eventually getAvailability().?used == success false + check eventuallyCheck getAvailability().?used == success false check getAvailability().?size == success availability.size test "generates proof of storage": @@ -301,13 +301,13 @@ asyncchecksuite "Sales": provingSlot = slot.slotIndex check isOk await reservations.reserve(availability) await market.requestStorage(request) - check eventually provingRequest == request + check eventuallyCheck provingRequest == request check provingSlot < request.ask.slots.u256 test "fills a slot": check isOk await reservations.reserve(availability) await market.requestStorage(request) - check eventually market.filled.len == 1 + check eventuallyCheck market.filled.len == 1 check market.filled[0].requestId == request.id check market.filled[0].slotIndex < request.ask.slots.u256 check market.filled[0].proof == proof @@ -325,7 +325,7 @@ asyncchecksuite "Sales": soldSlotIndex = slotIndex check isOk await reservations.reserve(availability) await market.requestStorage(request) - check eventually soldAvailability == availability + check eventuallyCheck soldAvailability == availability check soldRequest == request check soldSlotIndex < request.ask.slots.u256 @@ -342,7 +342,7 @@ asyncchecksuite "Sales": clearedSlotIndex = slotIndex check isOk await reservations.reserve(availability) await market.requestStorage(request) - check eventually clearedRequest == request + check eventuallyCheck clearedRequest == request check clearedSlotIndex < request.ask.slots.u256 test "makes storage available again when other host fills the slot": @@ -356,7 +356,7 @@ asyncchecksuite "Sales": await market.requestStorage(request) for slotIndex in 0.. agent.data == expected) diff --git a/tests/codex/sales/testslotqueue.nim b/tests/codex/sales/testslotqueue.nim index 1d2760ff..b7cc2059 100644 --- a/tests/codex/sales/testslotqueue.nim +++ b/tests/codex/sales/testslotqueue.nim @@ -10,6 +10,7 @@ import pkg/codex/sales/reservations import pkg/codex/sales/slotqueue import pkg/codex/stores +import ../helpers import ../helpers/mockmarket import ../helpers/eventually import ../examples diff --git a/tests/codex/storageproofs/testnetwork.nim b/tests/codex/storageproofs/testnetwork.nim index a56d7d63..538cbfdf 100644 --- a/tests/codex/storageproofs/testnetwork.nim +++ b/tests/codex/storageproofs/testnetwork.nim @@ -2,7 +2,6 @@ import std/sequtils import pkg/asynctest import pkg/chronos -import pkg/libp2p import pkg/libp2p/errors import pkg/contractabi as ca diff --git a/tests/codex/stores/commonstoretests.nim b/tests/codex/stores/commonstoretests.nim index 6aa280b3..d9c66e2b 100644 --- a/tests/codex/stores/commonstoretests.nim +++ b/tests/codex/stores/commonstoretests.nim @@ -4,8 +4,9 @@ import std/options import pkg/chronos import pkg/asynctest -import pkg/libp2p +import pkg/libp2p/multicodec import pkg/stew/byteutils +import pkg/questionable import pkg/questionable/results import pkg/codex/stores/cachestore import pkg/codex/chunker @@ -94,7 +95,7 @@ proc commonBlockStoreTests*(name: string, var count = 0 for c in cids: - if cid =? (await c): + if cid =? await c: check (await store.hasBlock(cid)).tryGet() count.inc diff --git a/tests/codex/stores/testcachestore.nim b/tests/codex/stores/testcachestore.nim index 7f36741c..8c135c11 100644 --- a/tests/codex/stores/testcachestore.nim +++ b/tests/codex/stores/testcachestore.nim @@ -2,7 +2,6 @@ import std/strutils import pkg/chronos import pkg/asynctest -import pkg/libp2p import pkg/stew/byteutils import pkg/questionable/results import pkg/codex/stores/cachestore diff --git a/tests/codex/stores/testkeyutils.nim b/tests/codex/stores/testkeyutils.nim index 70bf5e2a..7b1da450 100644 --- a/tests/codex/stores/testkeyutils.nim +++ b/tests/codex/stores/testkeyutils.nim @@ -10,7 +10,6 @@ import std/random import std/sequtils import pkg/chronos -import pkg/libp2p import pkg/asynctest import pkg/questionable import pkg/questionable/results diff --git a/tests/codex/stores/testmaintenance.nim b/tests/codex/stores/testmaintenance.nim index e4fc2f85..18806721 100644 --- a/tests/codex/stores/testmaintenance.nim +++ b/tests/codex/stores/testmaintenance.nim @@ -8,7 +8,6 @@ ## those terms. import pkg/chronos -import pkg/libp2p import pkg/asynctest import pkg/questionable/results import pkg/codex/blocktype as bt diff --git a/tests/codex/stores/testrepostore.nim b/tests/codex/stores/testrepostore.nim index 7b2f8daa..523f65f0 100644 --- a/tests/codex/stores/testrepostore.nim +++ b/tests/codex/stores/testrepostore.nim @@ -7,7 +7,6 @@ import pkg/questionable/results import pkg/chronos import pkg/asynctest -import pkg/libp2p import pkg/stew/byteutils import pkg/stew/endians2 import pkg/datastore diff --git a/tests/codex/testchunking.nim b/tests/codex/testchunking.nim index efeada27..860e52b6 100644 --- a/tests/codex/testchunking.nim +++ b/tests/codex/testchunking.nim @@ -1,9 +1,9 @@ + import pkg/asynctest import pkg/stew/byteutils import pkg/codex/chunker import pkg/chronicles import pkg/chronos -import pkg/libp2p import ./helpers diff --git a/tests/codex/testerasure.nim b/tests/codex/testerasure.nim index 96dd4c47..94f7c0e8 100644 --- a/tests/codex/testerasure.nim +++ b/tests/codex/testerasure.nim @@ -2,7 +2,6 @@ import std/sequtils import pkg/asynctest import pkg/chronos -import pkg/libp2p import pkg/questionable/results import pkg/codex/erasure diff --git a/tests/codex/testmanifest.nim b/tests/codex/testmanifest.nim index 5c43897e..89cea9c9 100644 --- a/tests/codex/testmanifest.nim +++ b/tests/codex/testmanifest.nim @@ -3,7 +3,6 @@ import std/sequtils import pkg/chronos import pkg/questionable/results import pkg/asynctest -import pkg/libp2p import pkg/stew/byteutils import pkg/codex/chunker diff --git a/tests/codex/testnode.nim b/tests/codex/testnode.nim index abe33763..c61c95aa 100644 --- a/tests/codex/testnode.nim +++ b/tests/codex/testnode.nim @@ -4,11 +4,11 @@ import std/math import pkg/asynctest import pkg/chronos +import pkg/chronicles import pkg/stew/byteutils import pkg/nitro -import pkg/libp2p -import pkg/libp2pdht/discv5/protocol as discv5 +import pkg/codexdht/discv5/protocol as discv5 import pkg/codex/stores import pkg/codex/blockexchange diff --git a/tests/codex/teststorestream.nim b/tests/codex/teststorestream.nim index 4edcc1ff..4226f5eb 100644 --- a/tests/codex/teststorestream.nim +++ b/tests/codex/teststorestream.nim @@ -1,6 +1,5 @@ import pkg/chronos import pkg/asynctest -import pkg/libp2p import pkg/questionable/results import ./helpers diff --git a/tests/codex/utils/testkeyutils.nim b/tests/codex/utils/testkeyutils.nim index be370374..2a33818a 100644 --- a/tests/codex/utils/testkeyutils.nim +++ b/tests/codex/utils/testkeyutils.nim @@ -1,7 +1,6 @@ import std/unittest import std/os -import pkg/libp2p -import pkg/questionable/results +import pkg/questionable import codex/utils/keyutils import ../helpers @@ -18,17 +17,17 @@ checksuite "keyutils": os.removeDir(path) test "creates a key file when it does not exist yet": - check setupKey(path / "keyfile").isSuccess + check setupKey(path / "keyfile").isOk check fileExists(path / "keyfile") test "stores key in a file that's only readable by the user": - discard !setupKey(path / "keyfile") + discard setupKey(path / "keyfile").get() when defined(posix): check getFilePermissions(path / "keyfile") == {fpUserRead, fpUserWrite} when defined(windows): check checkCurrentUserOnlyACL(path / "keyfile").get() test "reads key file when it does exist": - let key = !setupKey(path / "keyfile") - check !setupKey(path / "keyfile") == key + let key = setupKey(path / "keyfile").get() + check setupKey(path / "keyfile").get() == key diff --git a/tests/coverage.nim b/tests/coverage.nim new file mode 100644 index 00000000..832ee0d3 --- /dev/null +++ b/tests/coverage.nim @@ -0,0 +1,2 @@ + +include ./testCodex diff --git a/tests/coverage.nims b/tests/coverage.nims new file mode 100644 index 00000000..19297b60 --- /dev/null +++ b/tests/coverage.nims @@ -0,0 +1,12 @@ + +switch("debugger", "native") +switch("lineDir", "on") +switch("define", "debug") +switch("verbosity", "0") +switch("hints", "off") +switch("warnings", "off") +# switches for compiling with coverage +switch("passC", "-fprofile-arcs") +switch("passC", "-ftest-coverage") +switch("passL", "-fprofile-arcs") +switch("passL", "-ftest-coverage") diff --git a/tests/integration/nodes.nim b/tests/integration/nodes.nim index 513901d2..8257faa4 100644 --- a/tests/integration/nodes.nim +++ b/tests/integration/nodes.nim @@ -13,7 +13,7 @@ type process: Process arguments: seq[string] debug: bool - Role* = enum + Role* {.pure.} = enum Client, Provider, Validator @@ -57,7 +57,7 @@ proc init*(_: type DebugNodes, proc start(node: NodeProcess) = if node.debug: - node.process = startProcess( + node.process = osproc.startProcess( executable, workingDir, node.arguments, @@ -65,7 +65,7 @@ proc start(node: NodeProcess) = ) sleep(1000) else: - node.process = startProcess( + node.process = osproc.startProcess( executable, workingDir, node.arguments diff --git a/tests/integration/testblockexpiration.nim b/tests/integration/testblockexpiration.nim index 3193b470..e1c417e3 100644 --- a/tests/integration/testblockexpiration.nim +++ b/tests/integration/testblockexpiration.nim @@ -1,5 +1,6 @@ import std/os import std/httpclient +from std/net import TimeoutError import pkg/chronos import ../ethertest diff --git a/tests/logging.nim b/tests/logging.nim index 3b1c3771..cf2633d3 100644 --- a/tests/logging.nim +++ b/tests/logging.nim @@ -1,9 +1,10 @@ -import pkg/chronicles +when not defined(nimscript): + import pkg/chronicles -proc ignoreLogging(level: LogLevel, message: LogOutputStr) = - discard + proc ignoreLogging(level: LogLevel, message: LogOutputStr) = + discard -defaultChroniclesStream.output.writer = ignoreLogging + defaultChroniclesStream.output.writer = ignoreLogging -{.warning[UnusedImport]:off.} -{.used.} + {.warning[UnusedImport]:off.} + {.used.} diff --git a/tests/nimlldb.py b/tests/nimlldb.py new file mode 100644 index 00000000..bcc96e0d --- /dev/null +++ b/tests/nimlldb.py @@ -0,0 +1,1381 @@ +import lldb +from collections import OrderedDict +from typing import Union + + +def sbvaluegetitem(self: lldb.SBValue, name: Union[int, str]) -> lldb.SBValue: + if isinstance(name, str): + return self.GetChildMemberWithName(name) + else: + return self.GetChildAtIndex(name) + + +# Make this easier to work with +lldb.SBValue.__getitem__ = sbvaluegetitem + +NIM_IS_V2 = True + + +def get_nti(value: lldb.SBValue, nim_name=None): + name_split = value.type.name.split("_") + type_nim_name = nim_name or name_split[1] + id_string = name_split[-1].split(" ")[0] + + type_info_name = "NTI" + type_nim_name.lower() + "__" + id_string + "_" + nti = value.target.FindFirstGlobalVariable(type_info_name) + if not nti.IsValid(): + type_info_name = "NTI" + "__" + id_string + "_" + nti = value.target.FindFirstGlobalVariable(type_info_name) + if not nti.IsValid(): + print(f"NimEnumPrinter: lookup global symbol: '{type_info_name}' failed for {value.type.name}.\n") + return type_nim_name, nti + + +def enum_to_string(value: lldb.SBValue, int_val=None, nim_name=None): + tname = nim_name or value.type.name.split("_")[1] + + enum_val = value.signed + if int_val is not None: + enum_val = int_val + + default_val = f"{tname}.{str(enum_val)}" + + fn_syms = value.target.FindFunctions("reprEnum") + if not fn_syms.GetSize() > 0: + return default_val + + fn_sym: lldb.SBSymbolContext = fn_syms.GetContextAtIndex(0) + + fn: lldb.SBFunction = fn_sym.function + + fn_type: lldb.SBType = fn.type + arg_types: lldb.SBTypeList = fn_type.GetFunctionArgumentTypes() + if arg_types.GetSize() < 2: + return default_val + + arg1_type: lldb.SBType = arg_types.GetTypeAtIndex(0) + arg2_type: lldb.SBType = arg_types.GetTypeAtIndex(1) + + ty_info_name, nti = get_nti(value, nim_name=tname) + + if not nti.IsValid(): + return default_val + + call = f"{fn.name}(({arg1_type.name}){enum_val}, ({arg2_type.name})" + str(nti.GetLoadAddress()) + ");" + + res = executeCommand(call) + + if res.error.fail: + return default_val + + return f"{tname}.{res.summary[1:-1]}" + + +def to_string(value: lldb.SBValue): + # For getting NimStringDesc * value + value = value.GetNonSyntheticValue() + + # Check if data pointer is Null + if value.type.is_pointer and value.unsigned == 0: + return None + + size = int(value["Sup"]["len"].unsigned) + + if size == 0: + return "" + + if size > 2**14: + return "... (too long) ..." + + data = value["data"] + + # Check if first element is NULL + base_data_type = value.target.FindFirstType("char") + cast = data.Cast(base_data_type) + + if cast.unsigned == 0: + return None + + cast = data.Cast(value.target.FindFirstType("char").GetArrayType(size)) + return bytearray(cast.data.uint8s).decode("utf-8") + + +def to_stringV2(value: lldb.SBValue): + # For getting NimStringV2 value + value = value.GetNonSyntheticValue() + + data = value["p"]["data"] + + # Check if data pointer is Null + if value["p"].unsigned == 0: + return None + + size = int(value["len"].signed) + + if size == 0: + return "" + + if size > 2**14: + return "... (too long) ..." + + # Check if first element is NULL + base_data_type = data.type.GetArrayElementType().GetTypedefedType() + cast = data.Cast(base_data_type) + + if cast.unsigned == 0: + return None + + cast = data.Cast(base_data_type.GetArrayType(size)) + return bytearray(cast.data.uint8s).decode("utf-8") + + +def NimString(value: lldb.SBValue, internal_dict): + if is_local(value): + if not is_in_scope(value): + return "undefined" + + custom_summary = get_custom_summary(value) + if not custom_summary is None: + return custom_summary + + if NIM_IS_V2: + res = to_stringV2(value) + else: + res = to_string(value) + + if res is not None: + return f'"{res}"' + else: + return "nil" + + +def rope_helper(value: lldb.SBValue) -> str: + value = value.GetNonSyntheticValue() + if value.type.is_pointer and value.unsigned == 0: + return "" + + if value["length"].unsigned == 0: + return "" + + if NIM_IS_V2: + str_val = to_stringV2(value["data"]) + else: + str_val = to_string(value["data"]) + + if str_val is None: + str_val = "" + + return rope_helper(value["left"]) + str_val + rope_helper(value["right"]) + + +def Rope(value: lldb.SBValue, internal_dict): + if is_local(value): + if not is_in_scope(value): + return "undefined" + + custom_summary = get_custom_summary(value) + if not custom_summary is None: + return custom_summary + + rope_str = rope_helper(value) + + if len(rope_str) == 0: + rope_str = "nil" + else: + rope_str = f'"{rope_str}"' + + return f"Rope({rope_str})" + + +def NCSTRING(value: lldb.SBValue, internal_dict=None): + if is_local(value): + if not is_in_scope(value): + return "undefined" + + ty = value.Dereference().type + val = value.target.CreateValueFromAddress( + value.name or "temp", lldb.SBAddress(value.unsigned, value.target), ty + ).AddressOf() + return val.summary + + +def ObjectV2(value: lldb.SBValue, internal_dict): + if is_local(value): + if not is_in_scope(value): + return "undefined" + + orig_value = value.GetNonSyntheticValue() + if orig_value.type.is_pointer and orig_value.unsigned == 0: + return "nil" + + custom_summary = get_custom_summary(value) + if custom_summary is not None: + return custom_summary + + while orig_value.type.is_pointer: + orig_value = orig_value.Dereference() + + if "_" in orig_value.type.name: + obj_name = orig_value.type.name.split("_")[1].replace("colonObjectType", "") + else: + obj_name = orig_value.type.name + + num_children = value.num_children + fields = [] + + for i in range(num_children): + fields.append(f"{value[i].name}: {value[i].summary}") + + res = f"{obj_name}(" + ", ".join(fields) + ")" + return res + + +def Number(value: lldb.SBValue, internal_dict): + if is_local(value): + if not is_in_scope(value): + return "undefined" + + if value.type.is_pointer and value.signed == 0: + return "nil" + + custom_summary = get_custom_summary(value) + if not custom_summary is None: + return custom_summary + + return str(value.signed) + + +def Float(value: lldb.SBValue, internal_dict): + if is_local(value): + if not is_in_scope(value): + return "undefined" + + custom_summary = get_custom_summary(value) + if not custom_summary is None: + return custom_summary + + return str(value.value) + + +def UnsignedNumber(value: lldb.SBValue, internal_dict): + if is_local(value): + if not is_in_scope(value): + return "undefined" + + custom_summary = get_custom_summary(value) + if not custom_summary is None: + return custom_summary + + return str(value.unsigned) + + +def Bool(value: lldb.SBValue, internal_dict): + if is_local(value): + if not is_in_scope(value): + return "undefined" + + custom_summary = get_custom_summary(value) + if not custom_summary is None: + return custom_summary + + return str(value.value) + + +def CharArray(value: lldb.SBValue, internal_dict): + if is_local(value): + if not is_in_scope(value): + return "undefined" + + custom_summary = get_custom_summary(value) + if not custom_summary is None: + return custom_summary + + return str([f"'{char}'" for char in value.uint8s]) + + +def Array(value: lldb.SBValue, internal_dict): + if is_local(value): + if not is_in_scope(value): + return "undefined" + + value = value.GetNonSyntheticValue() + custom_summary = get_custom_summary(value) + if not custom_summary is None: + return custom_summary + + value = value.GetNonSyntheticValue() + return "[" + ", ".join([value[i].summary for i in range(value.num_children)]) + "]" + + +def Tuple(value: lldb.SBValue, internal_dict): + if is_local(value): + if not is_in_scope(value): + return "undefined" + + custom_summary = get_custom_summary(value) + if not custom_summary is None: + return custom_summary + + while value.type.is_pointer: + value = value.Dereference() + + num_children = value.num_children + + fields = [] + + for i in range(num_children): + key = value[i].name + val = value[i].summary + if key.startswith("Field"): + fields.append(f"{val}") + else: + fields.append(f"{key}: {val}") + + return "(" + ", ".join(fields) + f")" + + +def is_local(value: lldb.SBValue) -> bool: + line: lldb.SBLineEntry = value.frame.GetLineEntry() + decl: lldb.SBDeclaration = value.GetDeclaration() + + if line.file == decl.file and decl.line != 0: + return True + + return False + + +def is_in_scope(value: lldb.SBValue) -> bool: + line: lldb.SBLineEntry = value.frame.GetLineEntry() + decl: lldb.SBDeclaration = value.GetDeclaration() + + if is_local(value) and decl.line < line.line: + return True + + return False + + +def Enum(value: lldb.SBValue, internal_dict): + if is_local(value): + if not is_in_scope(value): + return "undefined" + + custom_summary = get_custom_value_summary(value) + if custom_summary is not None: + return custom_summary + + return enum_to_string(value) + + +def EnumSet(value: lldb.SBValue, internal_dict): + if is_local(value): + if not is_in_scope(value): + return "undefined" + + custom_summary = get_custom_summary(value) + if not custom_summary is None: + return custom_summary + + vals = [] + max_vals = 7 + for child in value.children: + vals.append(child.summary) + if len(vals) > max_vals: + vals.append("...") + break + + return "{" + ", ".join(vals) + "}" + + +def Set(value: lldb.SBValue, internal_dict): + if is_local(value): + if not is_in_scope(value): + return "undefined" + + custom_summary = get_custom_summary(value) + if custom_summary is not None: + return custom_summary + + vals = [] + max_vals = 7 + for child in value.children: + vals.append(child.value) + if len(vals) > max_vals: + vals.append("...") + break + + return "{" + ", ".join(vals) + "}" + + +def Table(value: lldb.SBValue, internal_dict): + if is_local(value): + if not is_in_scope(value): + return "undefined" + + custom_summary = get_custom_summary(value) + if custom_summary is not None: + return custom_summary + + fields = [] + + for i in range(value.num_children): + key = value[i].name + val = value[i].summary + fields.append(f"{key}: {val}") + + return "Table({" + ", ".join(fields) + "})" + + +def HashSet(value: lldb.SBValue, internal_dict): + if is_local(value): + if not is_in_scope(value): + return "undefined" + + custom_summary = get_custom_summary(value) + if custom_summary is not None: + return custom_summary + + fields = [] + + for i in range(value.num_children): + fields.append(f"{value[i].summary}") + + return "HashSet({" + ", ".join(fields) + "})" + + +def StringTable(value: lldb.SBValue, internal_dict): + if is_local(value): + if not is_in_scope(value): + return "undefined" + + custom_summary = get_custom_summary(value) + if not custom_summary is None: + return custom_summary + + fields = [] + + for i in range(value.num_children - 1): + key = value[i].name + val = value[i].summary + fields.append(f"{key}: {val}") + + mode = value[value.num_children - 1].summary + + return "StringTable({" + ", ".join(fields) + f"}}, mode={mode})" + + +def Sequence(value: lldb.SBValue, internal_dict): + if is_local(value): + if not is_in_scope(value): + return "undefined" + + custom_summary = get_custom_summary(value) + if not custom_summary is None: + return custom_summary + + return "@[" + ", ".join([value[i].summary for i in range(value.num_children)]) + "]" + + +class StringChildrenProvider: + def __init__(self, value: lldb.SBValue, internalDict): + self.value = value + self.data_type: lldb.SBType + if not NIM_IS_V2: + self.data_type = self.value.target.FindFirstType("char") + + self.first_element: lldb.SBValue + self.update() + self.count = 0 + + def num_children(self): + return self.count + + def get_child_index(self, name): + return int(name.lstrip("[").rstrip("]")) + + def get_child_at_index(self, index): + offset = index * self.data_size + return self.first_element.CreateChildAtOffset("[" + str(index) + "]", offset, self.data_type) + + def get_data(self) -> lldb.SBValue: + return self.value["p"]["data"] if NIM_IS_V2 else self.value["data"] + + def get_len(self) -> int: + if NIM_IS_V2: + if self.value["p"].unsigned == 0: + return 0 + + size = int(self.value["len"].signed) + + if size == 0: + return 0 + + data = self.value["p"]["data"] + + # Check if first element is NULL + base_data_type = data.type.GetArrayElementType().GetTypedefedType() + cast = data.Cast(base_data_type) + + if cast.unsigned == 0: + return 0 + else: + if self.value.type.is_pointer and self.value.unsigned == 0: + return 0 + + size = int(self.value["Sup"]["len"].unsigned) + + if size == 0: + return 0 + + data = self.value["data"] + + # Check if first element is NULL + base_data_type = self.value.target.FindFirstType("char") + cast = data.Cast(base_data_type) + + if cast.unsigned == 0: + return 0 + + return size + + def update(self): + if is_local(self.value): + if not is_in_scope(self.value): + return + + data = self.get_data() + size = self.get_len() + + self.count = size + self.first_element = data + + if NIM_IS_V2: + self.data_type = data.type.GetArrayElementType().GetTypedefedType() + + self.data_size = self.data_type.GetByteSize() + + def has_children(self): + return bool(self.num_children()) + + +class ArrayChildrenProvider: + def __init__(self, value: lldb.SBValue, internalDict): + self.value = value + self.data_type: lldb.SBType + self.first_element: lldb.SBValue + self.update() + + def num_children(self): + return self.has_children() and self.value.num_children + + def get_child_index(self, name: str): + return int(name.lstrip("[").rstrip("]")) + + def get_child_at_index(self, index): + offset = index * self.value[index].GetByteSize() + return self.first_element.CreateChildAtOffset("[" + str(index) + "]", offset, self.data_type) + + def update(self): + if not self.has_children(): + return + + self.first_element = self.value[0] + self.data_type = self.value.type.GetArrayElementType() + + def has_children(self): + if is_local(self.value): + if not is_in_scope(self.value): + return False + return bool(self.value.num_children) + + +class SeqChildrenProvider: + def __init__(self, value: lldb.SBValue, internalDict): + self.value = value + self.data_type: lldb.SBType + self.first_element: lldb.SBValue + self.data: lldb.SBValue + self.count = 0 + self.update() + + def num_children(self): + return self.count + + def get_child_index(self, name: str): + return int(name.lstrip("[").rstrip("]")) + + def get_child_at_index(self, index): + offset = index * self.data[index].GetByteSize() + return self.first_element.CreateChildAtOffset("[" + str(index) + "]", offset, self.data_type) + + def get_data(self) -> lldb.SBValue: + return self.value["p"]["data"] if NIM_IS_V2 else self.value["data"] + + def get_len(self) -> lldb.SBValue: + return self.value["len"] if NIM_IS_V2 else self.value["Sup"]["len"] + + def update(self): + self.count = 0 + + if is_local(self.value): + if not is_in_scope(self.value): + return + + self.count = self.get_len().unsigned + + if not self.has_children(): + return + + data = self.get_data() + self.data_type = data.type.GetArrayElementType() + + self.data = data.Cast(self.data_type.GetArrayType(self.num_children())) + self.first_element = self.data + + def has_children(self): + return bool(self.num_children()) + + +class ObjectChildrenProvider: + def __init__(self, value: lldb.SBValue, internalDict): + self.value = value + self.data_type: lldb.SBType + self.first_element: lldb.SBValue + self.data: lldb.SBValue + self.children: OrderedDict[str, int] = OrderedDict() + self.child_list: list[lldb.SBValue] = [] + self.update() + + def num_children(self): + return len(self.children) + + def get_child_index(self, name: str): + return self.children[name] + + def get_child_at_index(self, index): + return self.child_list[index] + + def populate_children(self): + self.children.clear() + self.child_list = [] + + if is_local(self.value): + if not is_in_scope(self.value): + return + + stack = [self.value.GetNonSyntheticValue()] + + index = 0 + + while stack: + cur_val = stack.pop() + if cur_val.type.is_pointer and cur_val.unsigned == 0: + continue + + while cur_val.type.is_pointer: + cur_val = cur_val.Dereference() + + # Add super objects if they exist + if cur_val.num_children > 0 and cur_val[0].name == "Sup" and cur_val[0].type.name.startswith("tyObject"): + stack.append(cur_val[0]) + + for child in cur_val.children: + child = child.GetNonSyntheticValue() + if child.name == "Sup": + continue + self.children[child.name] = index + self.child_list.append(child) + index += 1 + + def update(self): + self.populate_children() + + def has_children(self): + return bool(self.num_children()) + + +class HashSetChildrenProvider: + def __init__(self, value: lldb.SBValue, internalDict): + self.value = value + self.child_list: list[lldb.SBValue] = [] + self.update() + + def num_children(self): + return len(self.child_list) + + def get_child_index(self, name: str): + return int(name.lstrip("[").rstrip("]")) + + def get_child_at_index(self, index): + return self.child_list[index] + + def get_data(self) -> lldb.SBValue: + return self.value["data"]["p"]["data"] if NIM_IS_V2 else self.value["data"]["data"] + + def get_len(self) -> lldb.SBValue: + return self.value["data"]["len"] if NIM_IS_V2 else self.value["data"]["Sup"]["len"] + + def update(self): + self.child_list = [] + + if is_local(self.value): + if not is_in_scope(self.value): + return + + tuple_len = int(self.get_len().unsigned) + tuple = self.get_data() + + base_data_type = tuple.type.GetArrayElementType() + + cast = tuple.Cast(base_data_type.GetArrayType(tuple_len)) + + index = 0 + for i in range(tuple_len): + el = cast[i] + field0 = int(el[0].unsigned) + if field0 == 0: + continue + key = el[1] + child = key.CreateValueFromAddress(f"[{str(index)}]", key.GetLoadAddress(), key.GetType()) + index += 1 + + self.child_list.append(child) + + def has_children(self): + return bool(self.num_children()) + + +class SetCharChildrenProvider: + def __init__(self, value: lldb.SBValue, internalDict): + self.value = value + self.ty = self.value.target.FindFirstType("char") + self.child_list: list[lldb.SBValue] = [] + self.update() + + def num_children(self): + return len(self.child_list) + + def get_child_index(self, name: str): + return int(name.lstrip("[").rstrip("]")) + + def get_child_at_index(self, index): + return self.child_list[index] + + def update(self): + self.child_list = [] + if is_local(self.value): + if not is_in_scope(self.value): + return + + cur_pos = 0 + for child in self.value.children: + child_val = child.signed + if child_val != 0: + temp = child_val + num_bits = 8 + while temp != 0: + is_set = temp & 1 + if is_set == 1: + data = lldb.SBData.CreateDataFromInt(cur_pos) + child = self.value.synthetic_child_from_data(f"[{len(self.child_list)}]", data, self.ty) + self.child_list.append(child) + temp = temp >> 1 + cur_pos += 1 + num_bits -= 1 + cur_pos += num_bits + else: + cur_pos += 8 + + def has_children(self): + return bool(self.num_children()) + + +def create_set_children(value: lldb.SBValue, child_type: lldb.SBType, starting_pos: int) -> list[lldb.SBValue]: + child_list: list[lldb.SBValue] = [] + cur_pos = starting_pos + + if value.num_children > 0: + children = value.children + else: + children = [value] + + for child in children: + child_val = child.signed + if child_val != 0: + temp = child_val + num_bits = 8 + while temp != 0: + is_set = temp & 1 + if is_set == 1: + data = lldb.SBData.CreateDataFromInt(cur_pos) + child = value.synthetic_child_from_data(f"[{len(child_list)}]", data, child_type) + child_list.append(child) + temp = temp >> 1 + cur_pos += 1 + num_bits -= 1 + cur_pos += num_bits + else: + cur_pos += 8 + + return child_list + + +class SetIntChildrenProvider: + def __init__(self, value: lldb.SBValue, internalDict): + self.value = value + self.ty = self.value.target.FindFirstType(f"NI64") + self.child_list: list[lldb.SBValue] = [] + self.update() + + def num_children(self): + return len(self.child_list) + + def get_child_index(self, name: str): + return int(name.lstrip("[").rstrip("]")) + + def get_child_at_index(self, index): + return self.child_list[index] + + def update(self): + self.child_list = [] + if is_local(self.value): + if not is_in_scope(self.value): + return + bits = self.value.GetByteSize() * 8 + starting_pos = -(bits // 2) + self.child_list = create_set_children(self.value, self.ty, starting_pos) + + def has_children(self): + return bool(self.num_children()) + + +class SetUIntChildrenProvider: + def __init__(self, value: lldb.SBValue, internalDict): + self.value = value + self.ty = self.value.target.FindFirstType(f"NU64") + self.child_list: list[lldb.SBValue] = [] + self.update() + + def num_children(self): + return len(self.child_list) + + def get_child_index(self, name: str): + return int(name.lstrip("[").rstrip("]")) + + def get_child_at_index(self, index): + return self.child_list[index] + + def update(self): + self.child_list = [] + if is_local(self.value): + if not is_in_scope(self.value): + return + self.child_list = create_set_children(self.value, self.ty, starting_pos=0) + + def has_children(self): + return bool(self.num_children()) + + +class SetEnumChildrenProvider: + def __init__(self, value: lldb.SBValue, internalDict): + self.value = value + self.ty = self.value.target.FindFirstType(self.value.type.name.replace("tySet_", "")) + self.child_list: list[lldb.SBValue] = [] + self.update() + + def num_children(self): + return len(self.child_list) + + def get_child_index(self, name: str): + return int(name.lstrip("[").rstrip("]")) + + def get_child_at_index(self, index): + return self.child_list[index] + + def update(self): + if is_local(self.value): + if not is_in_scope(self.value): + return + self.child_list = create_set_children(self.value, self.ty, starting_pos=0) + + def has_children(self): + return bool(self.num_children()) + + +class TableChildrenProvider: + def __init__(self, value: lldb.SBValue, internalDict): + self.value = value + self.children: OrderedDict[str, int] = OrderedDict() + self.child_list: list[lldb.SBValue] = [] + + self.update() + + def num_children(self): + return len(self.child_list) + + def get_child_index(self, name: str): + return self.children[name] + + def get_child_at_index(self, index): + return self.child_list[index] + + def get_data(self) -> lldb.SBValue: + return self.value["data"]["p"]["data"] if NIM_IS_V2 else self.value["data"]["data"] + + def get_len(self) -> lldb.SBValue: + return self.value["data"]["len"] if NIM_IS_V2 else self.value["data"]["Sup"]["len"] + + def update(self): + self.child_list = [] + if is_local(self.value): + if not is_in_scope(self.value): + return + + tuple_len = int(self.get_len().unsigned) + tuple = self.get_data() + + base_data_type = tuple.type.GetArrayElementType() + + cast = tuple.Cast(base_data_type.GetArrayType(tuple_len)) + + index = 0 + for i in range(tuple_len): + el = cast[i] + field0 = int(el[0].unsigned) + if field0 == 0: + continue + key = el[1] + val = el[2] + key_summary = key.summary + child = self.value.CreateValueFromAddress(key_summary, val.GetLoadAddress(), val.GetType()) + self.child_list.append(child) + self.children[key_summary] = index + index += 1 + + def has_children(self): + return bool(self.num_children()) + + +class StringTableChildrenProvider: + def __init__(self, value: lldb.SBValue, internalDict): + self.value = value + self.children: OrderedDict[str, int] = OrderedDict() + self.child_list: list[lldb.SBValue] = [] + self.update() + + def num_children(self): + return len(self.child_list) + + def get_child_index(self, name: str): + return self.children[name] + + def get_child_at_index(self, index): + return self.child_list[index] + + def get_data(self) -> lldb.SBValue: + return self.value["data"]["p"]["data"] if NIM_IS_V2 else self.value["data"]["data"] + + def get_len(self) -> lldb.SBValue: + return self.value["data"]["len"] if NIM_IS_V2 else self.value["data"]["Sup"]["len"] + + def update(self): + self.children.clear() + self.child_list = [] + + if is_local(self.value): + if not is_in_scope(self.value): + return + + tuple_len = int(self.get_len().unsigned) + tuple = self.get_data() + + base_data_type = tuple.type.GetArrayElementType() + + cast = tuple.Cast(base_data_type.GetArrayType(tuple_len)) + + index = 0 + for i in range(tuple_len): + el = cast[i] + field0 = int(el[2].unsigned) + if field0 == 0: + continue + key = el[0] + val = el[1] + child = val.CreateValueFromAddress(key.summary, val.GetLoadAddress(), val.GetType()) + self.child_list.append(child) + self.children[key.summary] = index + index += 1 + + self.child_list.append(self.value["mode"]) + self.children["mode"] = index + + def has_children(self): + return bool(self.num_children()) + + +class LLDBDynamicObjectProvider: + def __init__(self, value: lldb.SBValue, internalDict): + value = value.GetNonSyntheticValue() + self.value: lldb.SBValue = value[0] + self.children: OrderedDict[str, int] = OrderedDict() + self.child_list: list[lldb.SBValue] = [] + + while self.value.type.is_pointer: + self.value = self.value.Dereference() + + self.update() + + def num_children(self): + return len(self.child_list) + + def get_child_index(self, name: str): + return self.children[name] + + def get_child_at_index(self, index): + return self.child_list[index] + + def update(self): + self.children.clear() + self.child_list = [] + + for i, child in enumerate(self.value.children): + name = child.name.strip('"') + new_child = child.CreateValueFromAddress(name, child.GetLoadAddress(), child.GetType()) + + self.children[name] = i + self.child_list.append(new_child) + + def has_children(self): + return bool(self.num_children()) + + +class LLDBBasicObjectProvider: + def __init__(self, value: lldb.SBValue, internalDict): + self.value: lldb.SBValue = value + + def num_children(self): + if self.value is not None: + return self.value.num_children + return 0 + + def get_child_index(self, name: str): + return self.value.GetIndexOfChildWithName(name) + + def get_child_at_index(self, index): + return self.value.GetChildAtIndex(index) + + def update(self): + pass + + def has_children(self): + return self.num_children() > 0 + + +class CustomObjectChildrenProvider: + """ + This children provider handles values returned from lldbDebugSynthetic* + Nim procedures + """ + + def __init__(self, value: lldb.SBValue, internalDict): + self.value: lldb.SBValue = get_custom_synthetic(value) or value + if "lldbdynamicobject" in self.value.type.name.lower(): + self.provider = LLDBDynamicObjectProvider(self.value, internalDict) + else: + self.provider = LLDBBasicObjectProvider(self.value, internalDict) + + def num_children(self): + return self.provider.num_children() + + def get_child_index(self, name: str): + return self.provider.get_child_index(name) + + def get_child_at_index(self, index): + return self.provider.get_child_at_index(index) + + def update(self): + self.provider.update() + + def has_children(self): + return self.provider.has_children() + + +def echo(debugger: lldb.SBDebugger, command: str, result, internal_dict): + debugger.HandleCommand("po " + command) + + +SUMMARY_FUNCTIONS: dict[str, lldb.SBFunction] = {} +SYNTHETIC_FUNCTIONS: dict[str, lldb.SBFunction] = {} + + +def get_custom_summary(value: lldb.SBValue) -> Union[str, None]: + """Get a custom summary if a function exists for it""" + value = value.GetNonSyntheticValue() + if value.GetAddress().GetOffset() == 0: + return None + + base_type = get_base_type(value.type) + + fn = SUMMARY_FUNCTIONS.get(base_type.name) + if fn is None: + return None + + fn_type: lldb.SBType = fn.type + + arg_types: lldb.SBTypeList = fn_type.GetFunctionArgumentTypes() + first_type = arg_types.GetTypeAtIndex(0) + + while value.type.is_pointer: + value = value.Dereference() + + if first_type.is_pointer: + command = f"{fn.name}(({first_type.name})" + str(value.GetLoadAddress()) + ");" + else: + command = f"{fn.name}(*({first_type.GetPointerType().name})" + str(value.GetLoadAddress()) + ");" + + res = executeCommand(command) + + if res.error.fail: + return None + + return res.summary.strip('"') + + +def get_custom_value_summary(value: lldb.SBValue) -> Union[str, None]: + """Get a custom summary if a function exists for it""" + + fn: lldb.SBFunction = SUMMARY_FUNCTIONS.get(value.type.name) + if fn is None: + return None + + command = f"{fn.name}(({value.type.name})" + str(value.signed) + ");" + res = executeCommand(command) + + if res.error.fail: + return None + + return res.summary.strip('"') + + +def get_custom_synthetic(value: lldb.SBValue) -> Union[lldb.SBValue, None]: + """Get a custom synthetic object if a function exists for it""" + value = value.GetNonSyntheticValue() + if value.GetAddress().GetOffset() == 0: + return None + + base_type = get_base_type(value.type) + + fn = SYNTHETIC_FUNCTIONS.get(base_type.name) + if fn is None: + return None + + fn_type: lldb.SBType = fn.type + + arg_types: lldb.SBTypeList = fn_type.GetFunctionArgumentTypes() + first_type = arg_types.GetTypeAtIndex(0) + + while value.type.is_pointer: + value = value.Dereference() + + if first_type.is_pointer: + first_arg = f"({first_type.name}){value.GetLoadAddress()}" + else: + first_arg = f"*({first_type.GetPointerType().name}){value.GetLoadAddress()}" + + if arg_types.GetSize() > 1 and fn.GetArgumentName(1) == "Result": + ret_type = arg_types.GetTypeAtIndex(1) + ret_type = get_base_type(ret_type) + + command = f""" + {ret_type.name} lldbT; + nimZeroMem((void*)(&lldbT), sizeof({ret_type.name})); + {fn.name}(({first_arg}), (&lldbT)); + lldbT; + """ + else: + command = f"{fn.name}({first_arg});" + + res = executeCommand(command) + + if res.error.fail: + print(res.error) + return None + + return res + + +def get_base_type(ty: lldb.SBType) -> lldb.SBType: + """Get the base type of the type""" + temp = ty + while temp.IsPointerType(): + temp = temp.GetPointeeType() + return temp + + +def use_base_type(ty: lldb.SBType) -> bool: + types_to_check = [ + "NF", + "NF32", + "NF64", + "NI", + "NI8", + "NI16", + "NI32", + "NI64", + "bool", + "NIM_BOOL", + "NU", + "NU8", + "NU16", + "NU32", + "NU64", + ] + + for type_to_check in types_to_check: + if ty.name.startswith(type_to_check): + return False + + return True + + +def breakpoint_function_wrapper(frame: lldb.SBFrame, bp_loc, internal_dict): + """This allows function calls to Nim for custom object summaries and synthetic children""" + debugger = lldb.debugger + + global SUMMARY_FUNCTIONS + global SYNTHETIC_FUNCTIONS + + global NIM_IS_V2 + + for tname, fn in SYNTHETIC_FUNCTIONS.items(): + debugger.HandleCommand(f"type synthetic delete -w nim {tname}") + + SUMMARY_FUNCTIONS = {} + SYNTHETIC_FUNCTIONS = {} + + target: lldb.SBTarget = debugger.GetSelectedTarget() + + NIM_IS_V2 = target.FindFirstType("TNimTypeV2").IsValid() + + module = frame.GetSymbolContext(lldb.eSymbolContextModule).module + + for sym in module: + if ( + not sym.name.startswith("lldbDebugSummary") + and not sym.name.startswith("lldbDebugSynthetic") + and not sym.name.startswith("dollar___") + ): + continue + + fn_syms: lldb.SBSymbolContextList = target.FindFunctions(sym.name) + if not fn_syms.GetSize() > 0: + continue + + fn_sym: lldb.SBSymbolContext = fn_syms.GetContextAtIndex(0) + + fn: lldb.SBFunction = fn_sym.function + fn_type: lldb.SBType = fn.type + arg_types: lldb.SBTypeList = fn_type.GetFunctionArgumentTypes() + + if arg_types.GetSize() > 1 and fn.GetArgumentName(1) == "Result": + pass # don't continue + elif arg_types.GetSize() != 1: + continue + + arg_type: lldb.SBType = arg_types.GetTypeAtIndex(0) + if use_base_type(arg_type): + arg_type = get_base_type(arg_type) + + if sym.name.startswith("lldbDebugSummary") or sym.name.startswith("dollar___"): + SUMMARY_FUNCTIONS[arg_type.name] = fn + elif sym.name.startswith("lldbDebugSynthetic"): + SYNTHETIC_FUNCTIONS[arg_type.name] = fn + debugger.HandleCommand( + f"type synthetic add -w nim -l {__name__}.CustomObjectChildrenProvider {arg_type.name}" + ) + + +def executeCommand(command, *args): + debugger = lldb.debugger + process = debugger.GetSelectedTarget().GetProcess() + frame: lldb.SBFrame = process.GetSelectedThread().GetSelectedFrame() + + expr_options = lldb.SBExpressionOptions() + expr_options.SetIgnoreBreakpoints(False) + expr_options.SetFetchDynamicValue(lldb.eDynamicCanRunTarget) + expr_options.SetTimeoutInMicroSeconds(30 * 1000 * 1000) # 30 second timeout + expr_options.SetTryAllThreads(True) + expr_options.SetUnwindOnError(False) + expr_options.SetGenerateDebugInfo(True) + expr_options.SetLanguage(lldb.eLanguageTypeC) + expr_options.SetCoerceResultToId(True) + res = frame.EvaluateExpression(command, expr_options) + + return res + + +def __lldb_init_module(debugger, internal_dict): + # fmt: off + print("internal_dict: ", internal_dict.keys()) + debugger.HandleCommand(f"breakpoint command add -F {__name__}.breakpoint_function_wrapper --script-type python 1") + debugger.HandleCommand(f"type summary add -w nim -n sequence -F {__name__}.Sequence -x tySequence_+[[:alnum:]]+$") + debugger.HandleCommand(f"type synthetic add -w nim -l {__name__}.SeqChildrenProvider -x tySequence_+[[:alnum:]]+$") + + debugger.HandleCommand(f"type summary add -w nim -n chararray -F {__name__}.CharArray -x char\s+[\d+]") + debugger.HandleCommand(f"type summary add -w nim -n array -F {__name__}.Array -x tyArray_+[[:alnum:]]+") + debugger.HandleCommand(f"type synthetic add -w nim -l {__name__}.ArrayChildrenProvider -x tyArray_+[[:alnum:]]+") + debugger.HandleCommand(f"type summary add -w nim -n string -F {__name__}.NimString NimStringDesc") + + debugger.HandleCommand(f"type summary add -w nim -n stringv2 -F {__name__}.NimString -x NimStringV2$") + debugger.HandleCommand(f"type synthetic add -w nim -l {__name__}.StringChildrenProvider -x NimStringV2$") + debugger.HandleCommand(f"type synthetic add -w nim -l {__name__}.StringChildrenProvider -x NimStringDesc$") + + debugger.HandleCommand(f"type summary add -w nim -n cstring -F {__name__}.NCSTRING NCSTRING") + + debugger.HandleCommand(f"type summary add -w nim -n object -F {__name__}.ObjectV2 -x tyObject_+[[:alnum:]]+_+[[:alnum:]]+") + debugger.HandleCommand(f"type synthetic add -w nim -l {__name__}.ObjectChildrenProvider -x tyObject_+[[:alnum:]]+_+[[:alnum:]]+$") + + debugger.HandleCommand(f"type summary add -w nim -n tframe -F {__name__}.ObjectV2 -x TFrame$") + + debugger.HandleCommand(f"type summary add -w nim -n rootobj -F {__name__}.ObjectV2 -x RootObj$") + + debugger.HandleCommand(f"type summary add -w nim -n enum -F {__name__}.Enum -x tyEnum_+[[:alnum:]]+_+[[:alnum:]]+") + debugger.HandleCommand(f"type summary add -w nim -n hashset -F {__name__}.HashSet -x tyObject_+HashSet_+[[:alnum:]]+") + debugger.HandleCommand(f"type synthetic add -w nim -l {__name__}.HashSetChildrenProvider -x tyObject_+HashSet_+[[:alnum:]]+") + + debugger.HandleCommand(f"type summary add -w nim -n rope -F {__name__}.Rope -x tyObject_+Rope[[:alnum:]]+_+[[:alnum:]]+") + + debugger.HandleCommand(f"type summary add -w nim -n setuint -F {__name__}.Set -x tySet_+tyInt_+[[:alnum:]]+") + debugger.HandleCommand(f"type synthetic add -w nim -l {__name__}.SetIntChildrenProvider -x tySet_+tyInt[0-9]+_+[[:alnum:]]+") + debugger.HandleCommand(f"type summary add -w nim -n setint -F {__name__}.Set -x tySet_+tyInt[0-9]+_+[[:alnum:]]+") + debugger.HandleCommand(f"type summary add -w nim -n setuint2 -F {__name__}.Set -x tySet_+tyUInt[0-9]+_+[[:alnum:]]+") + debugger.HandleCommand(f"type synthetic add -w nim -l {__name__}.SetUIntChildrenProvider -x tySet_+tyUInt[0-9]+_+[[:alnum:]]+") + debugger.HandleCommand(f"type synthetic add -w nim -l {__name__}.SetUIntChildrenProvider -x tySet_+tyInt_+[[:alnum:]]+") + debugger.HandleCommand(f"type summary add -w nim -n setenum -F {__name__}.EnumSet -x tySet_+tyEnum_+[[:alnum:]]+_+[[:alnum:]]+") + debugger.HandleCommand(f"type synthetic add -w nim -l {__name__}.SetEnumChildrenProvider -x tySet_+tyEnum_+[[:alnum:]]+_+[[:alnum:]]+") + debugger.HandleCommand(f"type summary add -w nim -n setchar -F {__name__}.Set -x tySet_+tyChar_+[[:alnum:]]+") + debugger.HandleCommand(f"type synthetic add -w nim -l {__name__}.SetCharChildrenProvider -x tySet_+tyChar_+[[:alnum:]]+") + debugger.HandleCommand(f"type summary add -w nim -n table -F {__name__}.Table -x tyObject_+Table_+[[:alnum:]]+") + debugger.HandleCommand(f"type synthetic add -w nim -l {__name__}.TableChildrenProvider -x tyObject_+Table_+[[:alnum:]]+") + debugger.HandleCommand(f"type summary add -w nim -n stringtable -F {__name__}.StringTable -x tyObject_+StringTableObj_+[[:alnum:]]+") + debugger.HandleCommand(f"type synthetic add -w nim -l {__name__}.StringTableChildrenProvider -x tyObject_+StringTableObj_+[[:alnum:]]+") + debugger.HandleCommand(f"type summary add -w nim -n tuple2 -F {__name__}.Tuple -x tyObject_+Tuple_+[[:alnum:]]+") + debugger.HandleCommand(f"type summary add -w nim -n tuple -F {__name__}.Tuple -x tyTuple_+[[:alnum:]]+") + + debugger.HandleCommand(f"type summary add -w nim -n float -F {__name__}.Float NF") + debugger.HandleCommand(f"type summary add -w nim -n float32 -F {__name__}.Float NF32") + debugger.HandleCommand(f"type summary add -w nim -n float64 -F {__name__}.Float NF64") + debugger.HandleCommand(f"type summary add -w nim -n integer -F {__name__}.Number -x NI") + debugger.HandleCommand(f"type summary add -w nim -n integer8 -F {__name__}.Number -x NI8") + debugger.HandleCommand(f"type summary add -w nim -n integer16 -F {__name__}.Number -x NI16") + debugger.HandleCommand(f"type summary add -w nim -n integer32 -F {__name__}.Number -x NI32") + debugger.HandleCommand(f"type summary add -w nim -n integer64 -F {__name__}.Number -x NI64") + debugger.HandleCommand(f"type summary add -w nim -n bool -F {__name__}.Bool -x bool") + debugger.HandleCommand(f"type summary add -w nim -n bool2 -F {__name__}.Bool -x NIM_BOOL") + debugger.HandleCommand(f"type summary add -w nim -n uinteger -F {__name__}.UnsignedNumber -x NU") + debugger.HandleCommand(f"type summary add -w nim -n uinteger8 -F {__name__}.UnsignedNumber -x NU8") + debugger.HandleCommand(f"type summary add -w nim -n uinteger16 -F {__name__}.UnsignedNumber -x NU16") + debugger.HandleCommand(f"type summary add -w nim -n uinteger32 -F {__name__}.UnsignedNumber -x NU32") + debugger.HandleCommand(f"type summary add -w nim -n uinteger64 -F {__name__}.UnsignedNumber -x NU64") + debugger.HandleCommand("type category enable nim") + debugger.HandleCommand(f"command script add -f {__name__}.echo echo") + # fmt: on diff --git a/vendor/asynctest b/vendor/asynctest index a236a5f0..fe1a34ca 160000 --- a/vendor/asynctest +++ b/vendor/asynctest @@ -1 +1 @@ -Subproject commit a236a5f0f3031573ac2cb082b63dbf6e170e06e7 +Subproject commit fe1a34caf572b05f8bdba3b650f1871af9fce31e diff --git a/vendor/atlas.workspace b/vendor/atlas.workspace new file mode 100644 index 00000000..812bfb2d --- /dev/null +++ b/vendor/atlas.workspace @@ -0,0 +1,3 @@ +deps="" +resolver="MaxVer" +overrides="urls.rules" diff --git a/vendor/dnsclient.nim b/vendor/dnsclient.nim index fbb76f8a..23214235 160000 --- a/vendor/dnsclient.nim +++ b/vendor/dnsclient.nim @@ -1 +1 @@ -Subproject commit fbb76f8af8a33ab818184a7d4406d9fee20993be +Subproject commit 23214235d4784d24aceed99bbfe153379ea557c8 diff --git a/vendor/nim-bearssl b/vendor/nim-bearssl index f4c4233d..99fcb340 160000 --- a/vendor/nim-bearssl +++ b/vendor/nim-bearssl @@ -1 +1 @@ -Subproject commit f4c4233de453cb7eac0ce3f3ffad6496295f83ab +Subproject commit 99fcb3405c55b27cfffbf60f5368c55da7346f23 diff --git a/vendor/nim-chronicles b/vendor/nim-chronicles index 7631f7b2..c9c8e58e 160000 --- a/vendor/nim-chronicles +++ b/vendor/nim-chronicles @@ -1 +1 @@ -Subproject commit 7631f7b2ee03398cb1512a79923264e8f9410af6 +Subproject commit c9c8e58ec3f89b655a046c485f622f9021c68b61 diff --git a/vendor/nim-chronos b/vendor/nim-chronos index 6525f4ce..0277b65b 160000 --- a/vendor/nim-chronos +++ b/vendor/nim-chronos @@ -1 +1 @@ -Subproject commit 6525f4ce1d1a7eba146e5f1a53f6f105077ae686 +Subproject commit 0277b65be2c7a365ac13df002fba6e172be55537 diff --git a/vendor/nim-eth b/vendor/nim-eth index 5885f638..15a09fab 160000 --- a/vendor/nim-eth +++ b/vendor/nim-eth @@ -1 +1 @@ -Subproject commit 5885f638e47b8607683ef9e1e77fc21ce1aede44 +Subproject commit 15a09fab737d08a2545284c727199c377bb0f4b7 diff --git a/vendor/nim-faststreams b/vendor/nim-faststreams index 1b561a9e..720fc5e5 160000 --- a/vendor/nim-faststreams +++ b/vendor/nim-faststreams @@ -1 +1 @@ -Subproject commit 1b561a9e71b6bdad1c1cdff753418906037e9d09 +Subproject commit 720fc5e5c8e428d9d0af618e1e27c44b42350309 diff --git a/vendor/nim-http-utils b/vendor/nim-http-utils index e88e231d..3b491a40 160000 --- a/vendor/nim-http-utils +++ b/vendor/nim-http-utils @@ -1 +1 @@ -Subproject commit e88e231dfcef4585fe3b2fbd9b664dbd28a88040 +Subproject commit 3b491a40c60aad9e8d3407443f46f62511e63b18 diff --git a/vendor/nim-json-serialization b/vendor/nim-json-serialization index e5b18fb7..bb53d49c 160000 --- a/vendor/nim-json-serialization +++ b/vendor/nim-json-serialization @@ -1 +1 @@ -Subproject commit e5b18fb710c3d0167ec79f3b892f5a7a1bc6d1a4 +Subproject commit bb53d49caf2a6c6cf1df365ba84af93cdcfa7aa3 diff --git a/vendor/nim-libp2p b/vendor/nim-libp2p index 8c2eca18..440461b2 160000 --- a/vendor/nim-libp2p +++ b/vendor/nim-libp2p @@ -1 +1 @@ -Subproject commit 8c2eca18dcc538c57a8fbc0c53fd0b9d24d56cff +Subproject commit 440461b24b9e66542b34d26a0b908c17f6549d05 diff --git a/vendor/nim-libp2p-dht b/vendor/nim-libp2p-dht index bd517f0e..3c940ea8 160000 --- a/vendor/nim-libp2p-dht +++ b/vendor/nim-libp2p-dht @@ -1 +1 @@ -Subproject commit bd517f0e8da38a1b5da15f7deb2d5c652ca389f1 +Subproject commit 3c940ea8901ae6118e66cc4df423b8ff53699eb4 diff --git a/vendor/nim-metrics b/vendor/nim-metrics index 743f81d4..6142e433 160000 --- a/vendor/nim-metrics +++ b/vendor/nim-metrics @@ -1 +1 @@ -Subproject commit 743f81d4f6c6ebf0ac02389f2392ff8b4235bee5 +Subproject commit 6142e433fc8ea9b73379770a788017ac528d46ff diff --git a/vendor/nim-protobuf-serialization b/vendor/nim-protobuf-serialization new file mode 160000 index 00000000..28214b3e --- /dev/null +++ b/vendor/nim-protobuf-serialization @@ -0,0 +1 @@ +Subproject commit 28214b3e40c755a9886d2ec8f261ec48fbb6bec6 diff --git a/vendor/nim-results b/vendor/nim-results new file mode 160000 index 00000000..f3c666a2 --- /dev/null +++ b/vendor/nim-results @@ -0,0 +1 @@ +Subproject commit f3c666a272c69d70cb41e7245e7f6844797303ad diff --git a/vendor/nim-secp256k1 b/vendor/nim-secp256k1 index 5340cf18..2acbbdcc 160000 --- a/vendor/nim-secp256k1 +++ b/vendor/nim-secp256k1 @@ -1 +1 @@ -Subproject commit 5340cf188168d6afcafc8023770d880f067c0b2f +Subproject commit 2acbbdcc0e63002a013fff49f015708522875832 diff --git a/vendor/nim-serialization b/vendor/nim-serialization index 493d18b8..384eb256 160000 --- a/vendor/nim-serialization +++ b/vendor/nim-serialization @@ -1 +1 @@ -Subproject commit 493d18b8292fc03aa4f835fd825dea1183f97466 +Subproject commit 384eb2561ee755446cff512a8e057325848b86a7 diff --git a/vendor/nim-sqlite3-abi b/vendor/nim-sqlite3-abi index fda455cf..362e1bd9 160000 --- a/vendor/nim-sqlite3-abi +++ b/vendor/nim-sqlite3-abi @@ -1 +1 @@ -Subproject commit fda455cfea2df707dde052034411ce63de218453 +Subproject commit 362e1bd9f689ad9f5380d9d27f0705b3d4dfc7d3 diff --git a/vendor/nim-stew b/vendor/nim-stew index e18f5a62..7afe7e3c 160000 --- a/vendor/nim-stew +++ b/vendor/nim-stew @@ -1 +1 @@ -Subproject commit e18f5a62af2ade7a1fd1d39635d4e04d944def08 +Subproject commit 7afe7e3c070758cac1f628e4330109f3ef6fc853 diff --git a/vendor/nim-testutils b/vendor/nim-testutils new file mode 160000 index 00000000..b56a5953 --- /dev/null +++ b/vendor/nim-testutils @@ -0,0 +1 @@ +Subproject commit b56a5953e37fc5117bd6ea6dfa18418c5e112815 diff --git a/vendor/nim-unittest2 b/vendor/nim-unittest2 index 02c49b8a..b178f475 160000 --- a/vendor/nim-unittest2 +++ b/vendor/nim-unittest2 @@ -1 +1 @@ -Subproject commit 02c49b8a994dd3f9eddfaab45262f9b8fa507f8e +Subproject commit b178f47527074964f76c395ad0dfc81cf118f379 diff --git a/vendor/nim-websock b/vendor/nim-websock index 7b2ed397..2c3ae313 160000 --- a/vendor/nim-websock +++ b/vendor/nim-websock @@ -1 +1 @@ -Subproject commit 7b2ed397d6e4c37ea4df08ae82aeac7ff04cd180 +Subproject commit 2c3ae3137f3c9cb48134285bd4a47186fa51f0e8 diff --git a/vendor/nim-zlib b/vendor/nim-zlib index 74cdeb54..f34ca261 160000 --- a/vendor/nim-zlib +++ b/vendor/nim-zlib @@ -1 +1 @@ -Subproject commit 74cdeb54b21bededb5a515d36f608bc1850555a2 +Subproject commit f34ca261efd90f118dc1647beefd2f7a69b05d93 diff --git a/vendor/nimbus-build-system b/vendor/nimbus-build-system index 1cf6a1b1..fe9bc3f3 160000 --- a/vendor/nimbus-build-system +++ b/vendor/nimbus-build-system @@ -1 +1 @@ -Subproject commit 1cf6a1b18ca5aa0d24e7a2861dd85d79ad9cb0cd +Subproject commit fe9bc3f3759ae1add6bf8c899db2e75327f03782 diff --git a/vendor/nimcrypto b/vendor/nimcrypto index a5742a9a..24e006df 160000 --- a/vendor/nimcrypto +++ b/vendor/nimcrypto @@ -1 +1 @@ -Subproject commit a5742a9a214ac33f91615f3862c7b099aec43b00 +Subproject commit 24e006df85927f64916e60511620583b11403178 diff --git a/vendor/npeg b/vendor/npeg new file mode 160000 index 00000000..b15a10e3 --- /dev/null +++ b/vendor/npeg @@ -0,0 +1 @@ +Subproject commit b15a10e388b91b898c581dbbcb6a718d46b27d2f diff --git a/vendor/questionable b/vendor/questionable index 30e4184a..1569ef45 160000 --- a/vendor/questionable +++ b/vendor/questionable @@ -1 +1 @@ -Subproject commit 30e4184a99c8c1ba329925912d2c5d4b09acf8cc +Subproject commit 1569ef4526d118c1bd1c31d8882eb9de6193a096 diff --git a/vendor/stint b/vendor/stint index 036c71d0..86621ece 160000 --- a/vendor/stint +++ b/vendor/stint @@ -1 +1 @@ -Subproject commit 036c71d06a6b22f8f967ba9d54afd2189c3872ca +Subproject commit 86621eced1dcfb5e25903019ebcfc76ed9128ec5 diff --git a/vendor/urls.rules b/vendor/urls.rules new file mode 100644 index 00000000..7636ff34 --- /dev/null +++ b/vendor/urls.rules @@ -0,0 +1,8 @@ +https://github.com/status-im/nim-libp2p-dht.git -> https://github.com/codex-storage/nim-codex-dht.git +https://github.com/markspanbroek/questionable -> https://github.com/codex-storage/questionable +https://github.com/status-im/questionable -> https://github.com/codex-storage/questionable +https://github.com/status-im/asynctest -> https://github.com/codex-storage/asynctest +https://github.com/status-im/nim-datastore -> https://github.com/codex-storage/nim-datastore +https://github.com/cheatfate/nimcrypto -> https://github.com/status-im/nimcrypto +protobufserialization -> protobuf_serialization +protobufserialization -> https://github.com/status-im/nim-protobuf-serialization