Skip to content

SOST V16.2.2 — no hand-rolled RPC parsing left in the CLI (node/miner unchanged)

Choose a tag to compare

@Neob1844 Neob1844 released this 23 Sep 07:36
· 287 commits to main since this release

Install this one. Every v16.2.x ships the same sost-node and sost-miner — byte-identical, same published hashes — so if you already run any v16.2.x you replace only the CLI and never restart. Only sost-cli was corrected, twice, after auditing the paths that handle funds.

Consensus is untouched since v16.1.0: V16 activates at #30,000, first DTD Jackpot V2 #30,186.

Update window — after #29,900, before #30,000

Node and miner, inside that window. Download and verify the hashes before it opens.

Official SHA-256

b253e4a9c352ea4b8557eec78d57e1c7619ab267af228c3e8f24bf8d7b69b897  sost-node   (unchanged since v16.2.0)
2ef9d0a77f243224ac088460818d6b360c689a7a3fa9555738e2b3b3e0112fe2  sost-miner  (unchanged since v16.2.0)
39170309cb0d0560f4ca82a225f5dd3b1c3d7eaeda1928273c4824f26141facf  sost-cli    (new in v16.2.2)
sha256sum -c SHA256SUMS

Linux x86_64, Ubuntu 22.04.5 toolchain (gcc 11.4.0, glibc 2.35). Building it yourself: the build directory must be named build — the source path is normalised out of the binary, the build directory name is not. Measured again from two directories. Cross-machine reproducibility is not claimed.

What v16.2.2 closes

Two paths still read the node's answer by scanning text, and one of them decides money.

  • cancel-tx / bump-fee rebuilt the original transaction from the raw reply: "fee" was searched from offset 0 of the whole body (any earlier field of that name won, and fee drives the RBF bump); each vin was delimited by the first }, so a single nested object truncated the input list — and every dropped vin is a prev_value missing from total_in, which is what total_in - new_fee returns to your wallet; and fields were read with std::stoll on raw text, which throws and aborts the process on a null or quoted value.
  • capsule-decrypt counted payload_hex matches in order, guessing which output each belonged to, and read a truncated reply as "no capsule here".

Both now read the parsed tree. A vin missing prev_value or prev_address refuses the whole plan rather than totalling a partial input set. The CLI now has zero substring-scanned RPC answers.

Verified

  • unit suite 119/119
  • tests/audit_v162_rbf.sh — 10/10: truncated body, fee as a string, null fee, missing size, empty vin[], a vin without prev_value, an unreadable mempool answer, and the nested-object vin that used to truncate the list (it now parses through and stops at the ownership check). Nothing signed, nothing broadcast.
  • tests/audit_v162_listunspent.sh 24/24 · tests/audit_v162_secrets.sh 43/43
  • JSON parser under ASan + UBSan + LeakSanitizer: 46/46 unit and 17/17 adversarial (200,000 deterministic mutations, truncation at every byte) with no sanitizer findings
  • devnet E2E 8 harnesses, cross-version equivalence, in-place upgrade and rollback, and the real production chain replayed identically

Rollback

v16.2.1, v16.2.0 and v16.1.0 stay downloadable, each with its own hash list in docs/v16/. Nothing changes the on-disk chain format. One caveat: a wallet encrypted with v16.2.x cannot be read by a pre-v16.2 binary — keep the v1 file until the encrypted one has mined a block.