Skip to content

SOST V16.2.1 — CLI money paths through the strict parser (node/miner unchanged)

Choose a tag to compare

@Neob1844 Neob1844 released this 23 Sep 00:30
· 311 commits to main since this release

Only sost-cli changes. sost-node and sost-miner are byte-identical to v16.2.0 — the same published hashes — so a node or miner already running v16.2.0 replaces just the CLI and never restarts. No mining time is lost by this release.

Consensus is unchanged, for the third release running: V16 activates at #30,000, first DTD Jackpot V2 #30,186.

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

Install on your node AND your miner, inside that window. Download and verify the hashes before it opens.

Official SHA-256

b253e4a9c352ea4b8557eec78d57e1c7619ab267af228c3e8f24bf8d7b69b897  sost-node   (identical to v16.2.0)
2ef9d0a77f243224ac088460818d6b360c689a7a3fa9555738e2b3b3e0112fe2  sost-miner  (identical to v16.2.0)
f50952bb3a02e061f239eca27a9d28a9267c5ee63ada714354357f433728b292  sost-cli    (new in v16.2.1)
sha256sum -c SHA256SUMS

Built on Ubuntu 22.04.5, gcc 11.4.0, glibc 2.35, x86_64. 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 for this release from two different directories. Cross-machine reproducibility is not claimed.

What it fixes

An audit asked which paths actually used the strict JSON parser shipped in v16.2.0. The money paths did not.

  • rpc_call could not read a large answer. It stopped as soon as a buffer happened to end with } whenever it did not find a literal Content-Length: header — and HTTP header names are case-insensitive, and a gateway in front of a node answers with Transfer-Encoding: chunked and no Content-Length at all. Every UTXO object ends in }, so a large getaddressutxos was cut at a chunk boundary and surfaced as bad_json — on exactly the command a miner uses to look at their own coins. Now: case-insensitive header, chunked decoding, read-to-close, socket timeout.
  • send bypassed rpc_call entirely — its own socket, one read() into a 4 KB buffer, and "the node accepted it" decided by finding "result":" anywhere in the reply. That decision marks your coins spent locally.
  • Balances, UTXO import, broadcast, sendmany, bump-fee, the mempool check and the chain height were parsed by substring search. query_chain_height called std::stoll on whatever followed "blocks": — which throws and aborts on a non-numeric body, and that height decides which coinbase outputs are mature enough to spend.

All of them now go through the strict parser: 23 call sites, zero remaining "result" substring searches. A broadcast counts as accepted only when the JSON-RPC result is a string txid. When an answer cannot be read, the wallet leaves the inputs unspent and says not confirmed — not rejected — and points you at getrawmempool before you build another transaction, because resending blind is how the same coins get spent twice.

sost-cli also gained --rpc-pass-file and --rpc-pass-fd, which the node and the miner already had.

Verified

  • unit suite 119/119 in the release worktree
  • tests/audit_v162_listunspent.sh — 24/24 against a node that misbehaves on purpose (401, 500, garbage, truncation, RPC error, wrong shape, duplicate keys, 200-deep nesting, out-of-range integer, missing amount, unreachable node, 5,000 UTXOs plain and chunked) plus a read-only query of a real mining address (2,989 UTXOs, 2,111 mature)
  • tests/audit_v162_secrets.sh — 43/43 against these binaries
  • JSON parser under ASan + UBSan + LeakSanitizer: 46/46 unit, 17/17 adversarial (200,000 deterministic mutations, truncation at every byte), 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.0 and v16.1.0 stay downloadable. 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.