Skip to content

v0.37.0

Pre-release
Pre-release

Choose a tag to compare

@sdbondi sdbondi released this 21 Jul 13:14
f4bd9bd

Closes the network's unpriced-work gaps: native crypto verification is metered and counted against
the block compute budget, the transaction ingress path is bounded before any fee is charged, and
invalid gossip is withheld from the mesh and scored against its sender. On the wallet side, a
create/approve/submit transaction-request flow and exact stealth-input selection.

⚠️ Coordinated upgrade required

[#2350] and [#2370] change block validity and which transactions trap, and neither is epoch-gated —
the execution budgets are compile-time constants, applied the moment a node restarts. All
validators must upgrade together at a block boundary.
A mixed-version network splits: an upgraded
voter counts native points toward the block budget and rejects blocks a v0.36.0 leader thought
valid, and metering changes fee outcomes → substates → the state merkle root.

Engine

  • Native verification is metered ([#2350]) — stealth transfers, confidential withdraws, mints,
    burn claims and value proofs are priced in WASM-point equivalents and drawn from the payment-funded
    compute allowance. Previously unmetered, so a transaction could stuff its fee intent with garbage
    proofs (invalid proofs cost the same to verify and are free to construct), extract hundreds of
    milliseconds of verification, then reject unpaid at the fee checkpoint.
  • Free-compute credit scoped to the fee intent ([#2364]) — FREE_COMPUTE_GRACE_POINTS was added
    to the allowance unconditionally, so the credit meant to let a transaction source its fee also
    funded the main instruction body: a trivial max_fee bought up to 32M metering points the
    validator absorbs when the transaction fails to pay.
  • Calibration is cross-machine comparable ([#2369]) — native_points_calibrate gains --json,
    --label and --compare; sampling raised to 100 native / 11 engine trials, holding the derived
    transfer cost to ~3% against ~2× before. Now reports a conservative safety bound and an amortised
    user-facing price separately. Committed constants untouched.

Consensus & networking

  • Native points reach the block budget ([#2370]) — ExecuteResult gains
    native_execution_points / total_execution_points(), enforced at both budget sites. Adds
    MAX_NATIVE_POINTS_PER_TRANSACTION (2.4e9) and removes WEIGHT_PER_OUTPUT, which was charging an
    output for its verification a third time. The ceiling a misbehaving leader can impose drops from
    ~9.5e9 (~3.1 s) to 7.1e9 (~2.3 s). Renames max_block_wasm_points
    max_block_execution_points, max_block_validation_wasm_points
    max_block_validation_execution_points, NoVoteReason::BlockWasmPointsExceeded
    BlockExecutionPointsExceeded — in-code only, no wire or serde change.
  • Signature verification bounded ([#2361]) — signing-message derivation hoisted out of the
    per-signature loop (135 ms → 8.8 ms for 128 signatures over a 1 MiB blob), blob commitments
    derived once and shared (7 → 3 derivations on JSON-RPC, 5 → 2 on gossip), and a new
    MAX_SIGNATURES_PER_TRANSACTION (16) where the weight cap previously permitted hundreds of
    thousands.
  • Invalid transactions withheld from gossip ([#2362]) — the networking worker reported
    MessageAcceptance::Accept before the application saw the message, so every invalid transaction
    was relayed to and validated by every node before anyone rejected it.
  • Peer scoring on invalid gossip ([#2367]) — gossipsub now runs with peer scoring, giving those
    verdicts a consequence. Narrowed to what the sender is answerable for: a transaction referencing an
    unsynced template no longer counts against a peer that is simply ahead of us.
  • Inbound queues bounded ([#2363]) — transaction gossip (which grew before validation: only
    arrival required), consensus gossip, and direct consensus messaging were all unbounded and drained
    serially.
  • Scheduled validator claim-key rotation ([#2347]) — the oracle wrote a claim key once at
    activation and never revisited it, leaving no supported way to move where leader fees accrue.
    Rotation is scheduled to an epoch boundary: a voter re-derives the fee pool address from its own
    global DB, so any disagreement window is a merkle root split.

Wallet

  • Transaction requests ([#2348]) — a limited-permission tool proposes, a separately-permissioned
    principal approves, and only then is the transaction sealed and submitted:
    Pending → Approved → Submitted, Rejected releasing locks, Expired derived on read (30 min
    TTL). New transaction_requests:create / :approve permissions; inputs frozen at create. Closes
    half of [#2343].
  • Exact stealth-input selection ([#2351], [#2353]) — StealthOutputsApi::lock_specific_outputs,
    surfaced as InputSelection::Specific on accounts.create_stealth_transfer_statement. Requires
    scoped StealthUtxos(Read, account) on top of Transfer(Create, account); preserves input order,
    locks atomically, releases on failure, and maps invalid selections to one privacy-safe
    InvalidParams. TypeScript binding updated.
  • Encrypted config API removed ([#2371]) — ConfigApi::set_encrypted ignored its key, wrote
    plaintext, and set is_encrypted = true. TODO stubs with no call sites, so no exposure — but a
    loaded gun for the next caller storing a secret. The column and the get guard are kept.
  • NFT ID display ([#2357]) — string-based NonFungibleId rendered as NFT #Item #1; now
    NFT: Item #1. Numeric IDs keep the #. Closes [#1873].

Build, CI & dependencies

  • Linux release binaries build again ([#2346]) — the build_binaries linux legs run on
    ubuntu-22.04, whose apt protobuf-compiler (3.12.4) predates proto3 optional support, so every
    tagged release since has shipped without linux binaries.
  • Least-privilege test-results publishing ([#2368]) — test_results.yml runs on workflow_run,
    in the trusted base-repo context with write scopes, consuming artifacts that are
    attacker-controlled for a fork PR.
  • minotari/tari on published 5.5.0 crates ([#2360]) — off the git-rev pin; drops unused
    minotari_ledger_wallet_common, swaps serde_yaml for yaml_serde 0.10 in integration_tests.
  • Dependabot: serde_with 3.21.0 ([#2349]), dtolnay/rust-toolchain ([#2359]),
    actions/setup-node 7.0.0 ([#2358]), astro/starlight ([#2365]), eslint + brace-expansion
    ([#2366]).

Published crates

Workspace rolls to 0.37.0. tari_ootle_wallet_crypto 0.38.0, tari_indexer_client 0.36; the rest
(tari_engine, tari_ootle_wallet_sdk, tari_ootle_wallet_storage_sqlite,
tari_template_test_tooling, tari_transaction_manifest, tari_validator_rollback,
tari_ootle_walletd_client, tari_consensus_types, tari_ootle_common_types, tari_engine_types,
tari_template_builtin, tari_ootle_transaction) at 0.37.

What's Changed

  • fix(ci): install a protoc that supports proto3 optional on the linux legs by @sdbondi in #2346
  • feat(epoch-oracles): support scheduled validator claim key rotation by @sdbondi in #2347
  • chore(deps): bump serde_with from 3.16.1 to 3.21.0 by @dependabot[bot] in #2349
  • feat(wallet-sdk): lock specific stealth outputs by @GSXRspartan in #2351
  • feat(walletd): transaction request create/approve/submit by @sdbondi in #2348
  • feat(engine): meter native verification against the payment-funded compute allowance by @sdbondi in #2350
  • fix(wallet-ui): use colon separator for string-based NFT ID display (closes #1873) by @webhop123 in #2357
  • chore(deps): bump actions/setup-node from 6.4.0 to 7.0.0 by @dependabot[bot] in #2358
  • chore(deps): bump dtolnay/rust-toolchain to 2c7215f132e9ebf062739d9130488b56d53c060c by @dependabot[bot] in #2359
  • feat(walletd): select specific stealth inputs by @GSXRspartan in #2353
  • chore(deps): use published minotari 5.5.0 crates by @sdbondi in #2360
  • fix(transaction): bound per-transaction signature verification work by @sdbondi in #2361
  • fix(mempool): withhold invalid transactions from gossip propagation by @sdbondi in #2362
  • fix(mempool): bound inbound gossip queues and the seen-transaction cache by @sdbondi in #2363
  • chore(deps): bump astro, @astrojs/cloudflare and @astrojs/starlight in /docs/developer-docs by @dependabot[bot] in #2365
  • fix(engine): scope the free-compute credit to the fee intent by @sdbondi in #2364
  • feat(p2p): score peers on invalid gossip deliveries by @sdbondi in #2367
  • chore(deps): bump brace-expansion, eslint-plugin, and eslint in swarmd webui by @dependabot[bot] in #2366
  • ci: least-privilege test results publishing by @sdbondi in #2368
  • chore(engine): make the native-points calibration cross-machine comparable by @sdbondi in #2369
  • fix(consensus): bound native verification with the block execution budget by @sdbondi in #2370
  • chore(wallet): remove unimplemented encrypted config API by @sdbondi in #2371

New Contributors

Full Changelog: v0.36.0...v0.37.0