From 87ef4d2c0aa09485d2fd062c40c1e4c9115b41e5 Mon Sep 17 00:00:00 2001 From: Markus Bopp Date: Wed, 16 Sep 2026 04:09:59 +0200 Subject: [PATCH] fix(deps): follow trac-msb and trac-peer to hyperdht 6.29.6 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Re-pins both framework dependencies: trac-msb 7220c257 -> ea72a9c8 (Trac-Systems/main_settlement_bus#802) trac-peer 370e81cf -> e4b52ad1 (Trac-Systems/trac-peer#37) Both carry one change: hyperdht 6.27.0 -> 6.29.6, for the null node-id guard released upstream in hyperdht 6.29.4 (holepunchto/hyperdht#242). Without it a long-running peer aborts roughly every few days. hyperdht keeps its persistent request handlers installed for the life of the node, while `dht.id` returns null for as long as the node is ephemeral — and an adaptive node returns to ephemeral on every wakeup or network change. In 6.27.0 the dispatcher checked only that the handlers existed, so an inbound UNANNOUNCE reached `Persistent.onunannounce`, which passes that null into `sodium.crypto_generichash_batch`, where it is dereferenced in C: TypeError: Cannot read properties of null (reading 'buffer') at annSignable (hyperdht/lib/persistent.js:275) at Persistent.onunannounce (hyperdht/lib/persistent.js:62) BOTH PINS MOVE TOGETHER, and that is the point. trac-peer depends on trac-msb at its own exact sha, so bumping only this repo's trac-msb pin installs a SECOND, nested trac-msb under node_modules/trac-peer — still carrying hyperdht 6.27.0. The lockfile then reads as fixed while the peer keeps crashing on the nested copy. Measured: bumping trac-msb alone added 12 lockfile entries including node_modules/trac-peer/node_modules/hyperdht@6.27.0. With both pins moved the tree stays flat — added 0, removed 0, a single hyperdht at 6.29.6, one trac-msb and one trac-peer. tests/startup-source.test.mjs follows the two shas, which is what it is for, and gains a case that pins hyperdht itself: version 6.29.6, exactly one hyperdht and exactly one trac-msb in the lockfile. That last part is the regression guard — it fails on the nested-duplicate tree that a half-finished pin bump produces. Co-Authored-By: Claude Opus 5 (1M context) --- package-lock.json | 47 +++++++++++++++++------------------ package.json | 4 +-- tests/startup-source.test.mjs | 28 ++++++++++++++++++--- 3 files changed, 49 insertions(+), 30 deletions(-) diff --git a/package-lock.json b/package-lock.json index 27cd85a..81567b2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,8 +17,8 @@ "path": "npm:bare-node-path", "pear-runtime": "1.3.1", "protomux": "^3.10.1", - "trac-msb": "github:Trac-Systems/main_settlement_bus#7220c257d8c493456714791e03f7021dbcfc7c85", - "trac-peer": "github:Trac-Systems/trac-peer#370e81cfff52524ac12b789f73fc3b2e6802c7fa", + "trac-msb": "github:Trac-Systems/main_settlement_bus#ea72a9c82a85059c014387cb21f759d2419bed3c", + "trac-peer": "github:Trac-Systems/trac-peer#e4b52ad1e5d3f48aea06f5e19a3830685dcfa441", "trac-wallet": "1.0.1", "util": "npm:bare-node-util" } @@ -1765,9 +1765,10 @@ } }, "node_modules/hyperdht": { - "version": "6.27.0", - "resolved": "https://registry.npmjs.org/hyperdht/-/hyperdht-6.27.0.tgz", - "integrity": "sha512-ZOXPSpsphn83hBxfFcZKNfXcgLLZH3HBWM2G0TAT0vl0hrBY287oEJ/2Nj0NimgxizpzA4J4t8wFsp/LSLs6Sw==", + "version": "6.29.6", + "resolved": "https://registry.npmjs.org/hyperdht/-/hyperdht-6.29.6.tgz", + "integrity": "sha512-bMMtw02fhiALdsTVLNZ/VFmMZuEY8kxb0/Rprl6oYF4/TCS653i3FDjtJeRbqtnAzwAj6dVZ/EwhoNOSCFGaYQ==", + "license": "MIT", "dependencies": { "@hyperswarm/secret-stream": "^6.6.2", "b4a": "^1.3.1", @@ -1775,7 +1776,6 @@ "blind-relay": "^1.3.0", "bogon": "^1.0.0", "compact-encoding": "^2.4.1", - "compact-encoding-net": "^1.0.1", "dht-rpc": "^6.15.1", "hypercore-crypto": "^3.3.0", "hypercore-id-encoding": "^1.2.0", @@ -2877,8 +2877,8 @@ }, "node_modules/trac-msb": { "version": "0.2.21", - "resolved": "git+ssh://git@github.com/Trac-Systems/main_settlement_bus.git#7220c257d8c493456714791e03f7021dbcfc7c85", - "integrity": "sha512-CYicrP7Qw3ERz3j81ZXqFhQop0IS2hcluFAyjSYAnZis0ohPBn+p4mvTaWLI8Zq7eWYE9qoLplWEc/ZyTvuPBA==", + "resolved": "git+ssh://git@github.com/Trac-Systems/main_settlement_bus.git#ea72a9c82a85059c014387cb21f759d2419bed3c", + "integrity": "sha512-AVN0fcaQ7PhA7XofnltN0cmfYKfJ+EeU7Pii18ONkgV4K+zrl1rhlSMMgOkrwB42hRnS+1rP2+8CzhnHMNWIqg==", "dependencies": { "autobase": "7.20.1", "b4a": "1.6.7", @@ -2898,7 +2898,7 @@ "hyperbee": "2.26.5", "hypercore": "11.18.3", "hypercore-crypto": "3.6.1", - "hyperdht": "6.27.0", + "hyperdht": "6.29.6", "hyperschema": "1.17.1", "hyperswarm": "4.14.2", "lodash": "^4.18.1", @@ -3010,8 +3010,8 @@ }, "node_modules/trac-peer": { "version": "0.4.9", - "resolved": "git+ssh://git@github.com/Trac-Systems/trac-peer.git#370e81cfff52524ac12b789f73fc3b2e6802c7fa", - "integrity": "sha512-7aVgElyMs8RmMpxykvyAegjalxTe85oMBg5vL+Wqqmc2rdMBR6peKpGyj4spyzlATygkSj+Mh/1oKn/P//k4fg==", + "resolved": "git+ssh://git@github.com/Trac-Systems/trac-peer.git#e4b52ad1e5d3f48aea06f5e19a3830685dcfa441", + "integrity": "sha512-aiD/CT5stelgronmbm2ohKDmmZxPB6GwXU+Y1/yTycQGA6rPCVLCoHvCe+REN/xSYKrfID+v/7I0TWaEZcTfog==", "dependencies": { "@tracsystems/blake3": "^0.0.15", "assert": "npm:bare-node-assert", @@ -3079,7 +3079,7 @@ "timers": "npm:bare-node-timers", "tls": "npm:bare-node-tls", "trac-crypto-api": "^0.1.5", - "trac-msb": "github:Trac-Systems/main_settlement_bus#7220c257d8c493456714791e03f7021dbcfc7c85", + "trac-msb": "github:Trac-Systems/main_settlement_bus#ea72a9c82a85059c014387cb21f759d2419bed3c", "trac-wallet": "^1.0.4", "url": "npm:bare-node-url", "util": "npm:bare-node-util", @@ -4844,9 +4844,9 @@ } }, "hyperdht": { - "version": "6.27.0", - "resolved": "https://registry.npmjs.org/hyperdht/-/hyperdht-6.27.0.tgz", - "integrity": "sha512-ZOXPSpsphn83hBxfFcZKNfXcgLLZH3HBWM2G0TAT0vl0hrBY287oEJ/2Nj0NimgxizpzA4J4t8wFsp/LSLs6Sw==", + "version": "6.29.6", + "resolved": "https://registry.npmjs.org/hyperdht/-/hyperdht-6.29.6.tgz", + "integrity": "sha512-bMMtw02fhiALdsTVLNZ/VFmMZuEY8kxb0/Rprl6oYF4/TCS653i3FDjtJeRbqtnAzwAj6dVZ/EwhoNOSCFGaYQ==", "requires": { "@hyperswarm/secret-stream": "^6.6.2", "b4a": "^1.3.1", @@ -4854,7 +4854,6 @@ "blind-relay": "^1.3.0", "bogon": "^1.0.0", "compact-encoding": "^2.4.1", - "compact-encoding-net": "^1.0.1", "dht-rpc": "^6.15.1", "hypercore-crypto": "^3.3.0", "hypercore-id-encoding": "^1.2.0", @@ -5803,9 +5802,9 @@ } }, "trac-msb": { - "version": "git+ssh://git@github.com/Trac-Systems/main_settlement_bus.git#7220c257d8c493456714791e03f7021dbcfc7c85", - "integrity": "sha512-CYicrP7Qw3ERz3j81ZXqFhQop0IS2hcluFAyjSYAnZis0ohPBn+p4mvTaWLI8Zq7eWYE9qoLplWEc/ZyTvuPBA==", - "from": "trac-msb@github:Trac-Systems/main_settlement_bus#7220c257d8c493456714791e03f7021dbcfc7c85", + "version": "git+ssh://git@github.com/Trac-Systems/main_settlement_bus.git#ea72a9c82a85059c014387cb21f759d2419bed3c", + "integrity": "sha512-AVN0fcaQ7PhA7XofnltN0cmfYKfJ+EeU7Pii18ONkgV4K+zrl1rhlSMMgOkrwB42hRnS+1rP2+8CzhnHMNWIqg==", + "from": "trac-msb@github:Trac-Systems/main_settlement_bus#ea72a9c82a85059c014387cb21f759d2419bed3c", "requires": { "autobase": "7.20.1", "b4a": "1.6.7", @@ -5825,7 +5824,7 @@ "hyperbee": "2.26.5", "hypercore": "11.18.3", "hypercore-crypto": "3.6.1", - "hyperdht": "6.27.0", + "hyperdht": "6.29.6", "hyperschema": "1.17.1", "hyperswarm": "4.14.2", "lodash": "^4.18.1", @@ -5915,9 +5914,9 @@ } }, "trac-peer": { - "version": "git+ssh://git@github.com/Trac-Systems/trac-peer.git#370e81cfff52524ac12b789f73fc3b2e6802c7fa", - "integrity": "sha512-7aVgElyMs8RmMpxykvyAegjalxTe85oMBg5vL+Wqqmc2rdMBR6peKpGyj4spyzlATygkSj+Mh/1oKn/P//k4fg==", - "from": "trac-peer@github:Trac-Systems/trac-peer#370e81cfff52524ac12b789f73fc3b2e6802c7fa", + "version": "git+ssh://git@github.com/Trac-Systems/trac-peer.git#e4b52ad1e5d3f48aea06f5e19a3830685dcfa441", + "integrity": "sha512-aiD/CT5stelgronmbm2ohKDmmZxPB6GwXU+Y1/yTycQGA6rPCVLCoHvCe+REN/xSYKrfID+v/7I0TWaEZcTfog==", + "from": "trac-peer@github:Trac-Systems/trac-peer#e4b52ad1e5d3f48aea06f5e19a3830685dcfa441", "requires": { "@tracsystems/blake3": "^0.0.15", "assert": "npm:bare-node-assert", @@ -5985,7 +5984,7 @@ "timers": "npm:bare-node-timers", "tls": "npm:bare-node-tls", "trac-crypto-api": "^0.1.5", - "trac-msb": "github:Trac-Systems/main_settlement_bus#7220c257d8c493456714791e03f7021dbcfc7c85", + "trac-msb": "github:Trac-Systems/main_settlement_bus#ea72a9c82a85059c014387cb21f759d2419bed3c", "trac-wallet": "^1.0.4", "url": "npm:bare-node-url", "util": "npm:bare-node-util", diff --git a/package.json b/package.json index a3a13f9..90880d3 100644 --- a/package.json +++ b/package.json @@ -17,8 +17,8 @@ "pear-runtime": "1.3.1", "protomux": "^3.10.1", "hyperschema": "1.17.1", - "trac-msb": "github:Trac-Systems/main_settlement_bus#7220c257d8c493456714791e03f7021dbcfc7c85", - "trac-peer": "github:Trac-Systems/trac-peer#370e81cfff52524ac12b789f73fc3b2e6802c7fa", + "trac-msb": "github:Trac-Systems/main_settlement_bus#ea72a9c82a85059c014387cb21f759d2419bed3c", + "trac-peer": "github:Trac-Systems/trac-peer#e4b52ad1e5d3f48aea06f5e19a3830685dcfa441", "trac-wallet": "1.0.1", "util": "npm:bare-node-util" }, diff --git a/tests/startup-source.test.mjs b/tests/startup-source.test.mjs index 1f84a40..bfba957 100644 --- a/tests/startup-source.test.mjs +++ b/tests/startup-source.test.mjs @@ -31,15 +31,35 @@ test('startup awaits sidechannel and owns the service lifetime', () => { test('intercom depends on pinned trac-peer and patched released trac-msb', () => { assert.equal(packageJson.dependencies['hyperschema'], '1.17.1'); - assert.equal(packageJson.dependencies['trac-peer'], 'github:Trac-Systems/trac-peer#370e81cfff52524ac12b789f73fc3b2e6802c7fa'); - assert.equal(packageJson.dependencies['trac-msb'], 'github:Trac-Systems/main_settlement_bus#7220c257d8c493456714791e03f7021dbcfc7c85'); + assert.equal(packageJson.dependencies['trac-peer'], 'github:Trac-Systems/trac-peer#e4b52ad1e5d3f48aea06f5e19a3830685dcfa441'); + assert.equal(packageJson.dependencies['trac-msb'], 'github:Trac-Systems/main_settlement_bus#ea72a9c82a85059c014387cb21f759d2419bed3c'); assert.equal(packageLock.packages['node_modules/hyperschema'].version, '1.17.1'); assert.equal( packageLock.packages['node_modules/trac-peer'].resolved, - 'git+ssh://git@github.com/Trac-Systems/trac-peer.git#370e81cfff52524ac12b789f73fc3b2e6802c7fa' + 'git+ssh://git@github.com/Trac-Systems/trac-peer.git#e4b52ad1e5d3f48aea06f5e19a3830685dcfa441' ); assert.equal( packageLock.packages['node_modules/trac-msb'].resolved, - 'git+ssh://git@github.com/Trac-Systems/main_settlement_bus.git#7220c257d8c493456714791e03f7021dbcfc7c85' + 'git+ssh://git@github.com/Trac-Systems/main_settlement_bus.git#ea72a9c82a85059c014387cb21f759d2419bed3c' ); }); + +test('the tree resolves one hyperdht, at or past the null node-id guard', () => { + // hyperdht 6.29.4 gated its persistent request dispatcher on the node id + // (holepunchto/hyperdht#242). Before that, an inbound UNANNOUNCE arriving while + // the node was ephemeral reached `onunannounce` with a null `dht.id`, which + // sodium dereferences in C — a long-running peer aborted every few days. + // + // Both Trac pins carry this transitively, and they have to agree: trac-peer + // depends on trac-msb at its own sha, so bumping one pin and not the other + // installs a SECOND, nested trac-msb with the old hyperdht underneath it. The + // lockfile reads as fixed while the peer keeps crashing on the nested copy. + assert.equal(packageLock.packages['node_modules/hyperdht'].version, '6.29.6'); + const nested = Object.keys(packageLock.packages).filter( + (key) => key !== 'node_modules/hyperdht' && key.endsWith('/hyperdht') + ); + assert.deepEqual(nested, [], `hyperdht must resolve to a single copy, found: ${nested.join(', ')}`); + const buses = Object.keys(packageLock.packages).filter((key) => key.endsWith('/trac-msb')); + assert.deepEqual(buses, ['node_modules/trac-msb'], + `trac-msb must resolve to a single copy, found: ${buses.join(', ')}`); +});