Skip to content

validate-sync uses pure-JS secp256k1 (~25x slower) — WASM secp fails to load in Node #15

@melvincarvalho

Description

@melvincarvalho

The full testnet4 validation took ~17.4h, and ~95% of that was ECDSA signature verification running on the pure-JS secp256k1 fallback instead of the WASM backend.

Root cause

loadSecpWasm() fetches the .wasm via fetch() on a relative path. That works in the browser but fails in Node (no relative-path fetch), so the verify backend silently falls back to the pure-JS secp256k1 — which is roughly 10–25x slower per verification than the WASM/libsecp path.

Impact (estimated)

  • testnet4 has ~31.75M inputs to verify. At pure-JS ~1.8 ms/verify that's ~16h — which is essentially the entire 17.4h run.
  • With WASM secp (~50–75 us/verify) the signature work would be ~40 min, dropping a full validation from ~17h to roughly ~1.5h.
  • This is the realistic baseline; our 17h number is inflated ~10x by the slow fallback. (It also means most of the apparent "SwiftSync speedup" in our runs was actually "we stopped doing slow JS signature checks", not the accumulator.)

Fix

Make the WASM loader work under Node: read secp256k1.wasm from disk (e.g. readFile / fileURLToPath(new URL('./secp256k1.wasm', import.meta.url))) instead of fetch() when running in Node, and confirm the verify backend selects WASM (not the pure-JS fallback). Add a startup log line stating which backend is active so a silent fallback can't hide again.

Where

Engine WASM loader (wasm/secp-wasm.js in the kernel snapshot; canonical in bitcoin-desktop/schema). Symptom surfaces in node src/validate-sync.mjs.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions