Phase B3 (part 2): C++<->TS interop — a C++ node joins a TS-driven DHT#78
Merged
Conversation
…dht from npm Completes the milestone B exit criterion against the real TypeScript implementation: a C++ DhtNode joins a layer-0 DHT whose entry point is @streamr/dht 103.8.0-rc.3 (the TS pin) installed from npm and run in a child node process, over real websockets on 127.0.0.1. - test/ts-interop/entryPoint.js: node driver that starts a TS DhtNode entry point (mirroring the TS Layer0.test.ts construction), prints its PeerDescriptor as protobuf-binary hex (exact wire fidelity — the C++ side parses it with the PeerDescriptor protobuf), then reports its DHT neighbor set every 500 ms. region is passed explicitly because without it TS start() does a GeoIP/CDN lookup over the real network. - test/ts-interop/package.json + package-lock.json: the harness depends on the granular published npm package at the pin — the TS monorepo checkout is never built. - test/ts-interop/TsInteropTest.cpp: spawns the driver, joins the DHT from a serverless C++ node (which also exercises the B1 connectivity request/response protocol against the TS server), and asserts mutual visibility: the TS entry point is the C++ node's closest contact with a live connection, and the TS node lists the C++ node id among its neighbors. npm ci runs on demand when node_modules is absent. Only a missing node runtime (>= 20, required by the pinned package's dependencies) skips the test; all other failures are hard failures. - validate.yml: actions/setup-node (node 22) before the test step so all three CI legs run the interop test. - lint.sh: exclude npm-vendored third-party C++ sources under node_modules from the sweep; TsInteropTest.cpp joins the documented std-type-unification exclusion list (compiler builds and runs it, clang-format still checks it). Local: interop 6/6 runs, unit 181/181, integration 43/43, e2e 7/7, lint rc=0. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Completes the milestone B exit criterion against the real TypeScript implementation: a C++
DhtNodejoins a layer-0 DHT whose entry point is@streamr/dht@103.8.0-rc.3(exactly the TS pin) installed from npm and run in a childnodeprocess, over real websockets on127.0.0.1. Mutual visibility is asserted from both sides.How the harness works
test/ts-interop/entryPoint.js— node driver that starts a TSDhtNodeentry point (constructed exactly like the TSLayer0.test.tsentry point at the pin), joins its own DHT, then speaks a line protocol on stdout:DESCRIPTOR <hex>(the protobuf-binaryPeerDescriptor— exact wire fidelity, no field mapping) followed byNEIGHBORS <id,...>every 500 ms.regionis passed explicitly because TSstart()otherwise does a GeoIP/CDN lookup over the real network.test/ts-interop/package.json+ lockfile — per the granular-packages direction: the harness depends only on the published npm package at the pin; the TS monorepo checkout is never built.npm ciruns on demand from the test itself whennode_modulesis absent.test/ts-interop/TsInteropTest.cpp(newstreamr-dht-test-ts-interoptarget) — spawns the driver, reads the descriptor, starts a serverless C++ node with the TS node as entry point, and joins. The serverless start also exercises the B1 connectivity request/response protocol against the TS websocket server for real. Asserts:Node runtime discovery:
$STREAMR_TS_INTEROP_NODE, then PATHnodeif >= 20 (required by the pinned package's dependencies), then the newest~/.nvminstall. Only a missing runtime skips the test; every other failure (npm ci, driver crash, join failure) is a hard failure.CI:
actions/setup-node(node 22) added to the validate workflow so all three legs run the interop test.lint: npm-vendored third-party C++ under
node_modulesexcluded from the sweep;TsInteropTest.cppjoins the documented std-type-unification exclusion list (the compiler builds and runs it; clang-format still checks it).Test results (local, arm64 mac)
SingleLayer1Dhtthis run)With this, milestone B is complete: C++ nodes interoperate over websocket + WebRTC with each other (part 1, #77) and over websocket with the pinned TS implementation (this PR). Known follow-up (pre-existing, documented in #77): the occasional
Layer1ScaleTest.SingleLayer1Dhtneighbor-count flake.🤖 Generated with Claude Code