fix(deps): bump @bsv/wallet-toolbox to 2.10.1 for both proof-task deadlock fixes - #78
Conversation
…dlock fixes
2.4.4 contains TWO self-deadlocks that stop proof fetching entirely. Both are the
same mistake: a StorageKnex method drops the caller's transaction token, so its
query asks the pool for a second connection while the caller's transaction holds
the first. knex forces {min:1,max:1} on sqlite, so it can never be granted and the
task dies after acquireConnectionTimeout with
KnexTimeoutError: Timeout acquiring a connection. The pool is probably full.
Are you missing a .transacting(trx) call?
1. getProvenOrRawTx(txid, trx) dropped trx on its findProvenTxs call.
Fixed upstream by ef710c3 (bsv-blockchain/ts-stack#426), published in 2.6.0.
2. readSettings() took no trx at all, so verifyReadyForDatabaseAccess deadlocked
on the same pool. Fixed by 4958767a5 (#444), published in 2.7.0.
TaskCheckForProofs therefore fails before processing any request, which is why an
affected wallet's proven_tx_reqs backlog sits at zero attempts -- the rows are
never reached rather than tried and failed.
Downstream this makes BEEF payment ancestry never terminate at a proven parent, so
x-bsv-payment headers grow without bound until a Cloudflare-fronted origin refuses
the request at its 32KB header cap -- after the wallet has already broadcast and
paid.
Observed on a real wallet running the released build: 2,532 monitor error events,
340 proof requests outstanding at 0 attempts, 433 unproven transactions. Applying
the equivalent fix moved proven_tx_reqs completed 18 -> 119, outstanding 139 -> 38,
and the payment header 33,058 -> 13,666 bytes, with a wallet Cloudflare had been
refusing paying again.
Verified by unpacking the published tarballs rather than trusting release notes:
version getProvenOrRawTx readSettings
2.4.4 drops trx no trx param
2.6.2 trx forwarded no trx param
2.10.1 trx forwarded trx forwarded
Landing 2.6.x would therefore have shipped only half the fix.
@bsv/sdk moves ^2.2.0 -> ^2.4.0 because it has to: wallet-toolbox declares
peerDependencies @bsv/sdk ^2.4.0 from 2.7.0 onwards, which is the same version that
carries the readSettings fix, so the two cannot be separated. Checked that every
other @bsv/* dependency accepts it -- amountinator, btms, btms-permission-module and
message-box-client all ask for ^2.1.6.
2.10.1 also carries 96e888612, which raises minimumDesiredUTXOValue off the historic
32 satoshis. That mismatch against the 96-satoshi dust floor is the other half of the
header-growth problem, so it lands here for free.
@bsv/wallet-toolbox-client is deliberately left at 2.4.4. Its newer releases are
bundled packages whose exports map blocks the deep '/out/src/...' paths this app
imports across six files. That is a separate migration and unrelated to this defect,
which lives in StorageKnex -- Electron main only.
NOTE FOR DEVELOPERS: this raises the effective minimum Node for a local install to
22. @bsv/sdk 2.4.0, @bsv/wallet-toolbox 2.10.1 and better-sqlite3 all declare
engines node >=22, and on Node 20 npm install now dies in the postinstall step
(electron-builder install-app-deps -> @electron/rebuild, itself already requiring
>=22.12.0 on master). Verified on Node 24.13.0.
npm run build passes (renderer tsc + vite, electron tsc). Tests: 15/15 default,
58/58 test:tokens, 32/32 test:stas:db including the four migration tests that
exercise StorageKnex over knex+sqlite.
|
@sirdeggen would you have time to take a look at this one when you get a chance? It is a dependency bump only — Also, whenever someone with write access has a spare minute: @ty-everett — thanks for validating the combination in #79, and for flagging the lockfile. I dug into the missing
Which npm version did you hit the |
|
friendly nudge to look at this when you get the chance @sirdeggen |
|
A current-master refresh aligned to the exact Sigma official-matrix versions is available in #86. It pins Wallet Toolbox 2.10.4 and SDK 2.4.2, refreshes the lockfile, and passes the default, token, STAS/SQLite, and full build gates without force-pushing this upstream branch. |
Every released build of BSV Desktop cannot fetch merkle proofs.
v2.8.1pins@bsv/wallet-toolbox2.4.4, which contains two self-deadlocks inStorageKnex. Both are the same mistake — a method drops the caller's transaction token, so its query asks the pool for a second connection while the caller's transaction holds the first. knex forces{min:1, max:1}on sqlite, so it can never be granted and the task dies afteracquireConnectionTimeout:TaskCheckForProofstherefore fails before processing any request, which is why an affected wallet'sproven_tx_reqsbacklog sits at zero attempts — the rows are never reached rather than tried and failed.Downstream, BEEF payment ancestry never terminates at a proven parent, so
x-bsv-paymentheaders grow without bound until a Cloudflare-fronted origin refuses the request at its 32KB header cap — after the wallet has already broadcast and paid.Why 2.10.1 and not 2.6.x
The two fixes shipped in different releases, and the second one is the reason this PR isn't a smaller bump. Verified by unpacking the published tarballs rather than trusting release notes — the signature of
readSettingsis the tell:getProvenOrRawTxreadSettingstrxreadSettings()— no paramtrxforwardedreadSettings()— no paramtrxforwardedreadSettings(trx)✓Fixed upstream by ts-stack#426 (published 2.6.0) and ts-stack#444 (published 2.7.0). Landing any 2.6.x would ship only half the fix.
The
@bsv/sdkbump is forced, not incidentalwallet-toolboxdeclarespeerDependencies: { "@bsv/sdk": "^2.4.0" }from 2.7.0 onwards — the same release that carries thereadSettingsfix. The two cannot be separated. Checked that every other@bsv/*dependency accepts it:amountinator,btms,btms-permission-moduleandmessage-box-clientall ask for^2.1.6, andbtms-permission-modulewantswallet-toolbox-client ^2.3.3(satisfied by 2.4.4).2.10.1 also carries
96e888612, which raisesminimumDesiredUTXOValueoff the historic 32 satoshis. That mismatch against the 96-satoshi dust floor is the other half of the header-growth problem, so it lands here for free.wallet-toolbox-clientdeliberately stays at 2.4.4Its newer releases are bundled packages whose
exportsmap blocks the deep/out/src/...paths this app imports across six files (config.ts,WalletContext.tsx,StorageElectronIPC.ts,WalletService.ts,AddEntityModal.tsx,TrustedEntity.tsx). That is a separate, mechanical migration and unrelated to this defect, which lives inStorageKnex— Electron main only.Upgrading is one-way — please read before merging
This bump takes the toolbox migration ledger from 17 to 21. They are forward-only, applied on first launch by
electron/storage.ts:156:The last one rewrites change-management settings rather than adding a table, so a user who launches this build and then reinstalls v2.8.1 will not get those settings back. That is inherent to taking the upstream fix, but it should be a deliberate decision rather than a surprise.
No test in this repo opens a populated wallet database, so I exercised the migration path locally against two populated databases — one testnet, one mainnet — reproducing exactly what
electron/storage.ts:150-158does on startup:integrity_checkokintegrity_checkokRow counts in every tracked table (
users,transactions,outputs,proven_txs,proven_tx_reqs,monitor_events) were identical before and after, andPRAGMA integrity_checkreturnedokon both.Developers now need Node ≥ 22
@bsv/sdk2.4.0,@bsv/wallet-toolbox2.10.1 andbetter-sqlite3all declareengines.node >= 22, and on Node 20npm installnow dies inpostinstallatelectron-builder install-app-deps→@electron/rebuild(which already required>=22.12.0onmaster). Verified on 24.13.0. I have deliberately not added anenginesfield or.nvmrchere so this stays a pure dependency bump — happy to follow up with one if you'd like it enforced.Testing
npm run buildpasses — this covers both sides, sincebuild:rendereristsc && vite buildandbuild:electronistsc -p tsconfig.electron.json.npm test15/15 ·npm run test:tokens58/58 ·npm run test:stas:db32/32, including the fourmigration.test.tscases that driveStorageKnexover knex+sqlite.listOutputs/listActionscontinuously, monitor tasks (ReviewProvenTxs,ReconcilePendingTransactions,NewHeader) all recorded events, and zeroKnexTimeoutErroroccurrences.@bsv/wallet-toolbox, plus one orphaned transitive (encoding). 1202 → 1161 entries.Unrelated foot-gun found while verifying
electron/main.ts:144hardcodesmainWindow.loadURL('http://localhost:5173'). If anything already holds that port, vite prints "Port 5173 is in use, trying another one…", moves to 5174, and Electron silently loads whatever is on 5173 — in my case a stale dev server, which nearly invalidated this verification. Not touching it here, but it's worth a separate fix to read the actual port.