Skip to content

Releases: tari-project/tari-ootle

v0.47.0

v0.47.0 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 20 Oct 05:43
v0.47.0
9dabb2a

🚀 Tari Ootle v0.47.0

✨ Highlights

  • ⚠️ Verified wallet reads and finalization — wallets check receipts and substates against the validator set (#2961, #2976, #2977)
  • Validator set handover — end-of-epoch blocks sign the next epoch's validator set (#2937, #2943)
  • ⚠️ Indexer GraphQL server removed (#2926)
  • ⚠️ tari_debug host function removed (#2949)
  • ⚠️ 🔒 Confidential outputs must prove a non-zero value (#2978)

⚠️ Before you upgrade

  • Validators and indexers upgrade and restart together. (#2943, #2996, #2934, #2955, #2978)
  • Upgrade wallets to v0.47.0; older wallets can't read from or transact on the upgraded network. See the wallet setup guide. (#2968, #2978)
  • Indexer GraphQL settings removed: drop graphql_address and web_ui_public_graphql_url, or the config fails to load. (#2926)
  • Templates: engine_debug! / tari_debug removed; rebuild against tari_template_lib 0.35. (#2949)
  • API changes for app developers are listed in the changelog.

👛 Wallet

  • ⚠️ Verified finalization — receipts committed only once proven (#2961)
  • ⚠️ Verified reads — substates read only with a recent proof (#2976)
  • ⚠️ ootle-rs verification against the validator set (#2977)
  • tari_ootle_light_client — walks the validator set handover (#2956)
  • Trusted validator set status in walletd, with a web UI page (#2975, #3000)
  • Account refresh from finalized transactions, 10-minute poll (#3001)
  • ⚡ Batched vault fetch per account (#2999)
  • ⚠️ 🐛 Bounded result waits, submissions deferred until anchored (#2987)
  • 🔒 Signing restricted to account, transaction, nonce and imported keys (#2960)
  • 🔒 Proofs encrypted to destination view key (#2946)
  • 🔒 Transaction-request locks bound to their creator (#2930)
  • 🐛 Referenced substate kinds detected as inputs (#2942)
  • 🐛 Stealth output overflow rejected (#2939, #2983)
  • 🐛 Anchors on the current epoch's validator set before the first checkpoint (#3010)
  • 🐛 Clearer unserved-checkpoint error (#2997)

🛡️ Validator Node

  • Validator set hash per epoch, committed by end-of-epoch blocks (#2932, #2937, #2943, #3005)
  • 🐛 Committees ordered by public key (#2996), certificate signatures sorted (#2912)
  • 🐛 Cross-shard epoch handling — drain before committee change, abort out-of-window (#2957, #2988)
  • 🐛 Transaction sequencing — locked-input deferral, post-sync re-sequencing (#2945, #2964)
  • 🐛 Foreign proposals — only requested, epoch burn rate, duplicate pledge versions (#2920, #2952, #2915)
  • 🔒 Bounded consensus work — future-view messages, parked blocks, ready records, missing-tx responses (#2921, #2929, #2940, #2962)
  • 🔒 Engine metering — engine calls, component loads, fee checkpoint, confidential withdraw (#2925, #2933, #2934, #2955)
  • 🔒 Restricted frames refuse new buckets, proofs and allocations (#2970)
  • 🔒 Bounded RPC and state sync — batch responses, scans, commit epochs, page sizes (#2923, #2935, #2944, #2953, #2966, #2967)
  • 🐛 Reads proven against previous epoch's end block (#2994)
  • 🐛 Transaction proof root check (#2938)
  • 🔒 Transport upgrade timeout, bounded RPC stream idle budget, stalled-reader sessions closed (#2948, #2958, #3004)
  • 🔒 Confidential withdraw with revealed change but no change output rejected (#3006)
  • sync_blocks RPC removed (#2965)

🔎 Indexer

  • ⚠️ Validator set handover served, synced checkpoints verified (#2954)
  • ⚠️ Down proofs over REST (#2968)
  • ⚠️ ⚡ Commit proof once per substate batch (#3002)
  • ⚡ Caching — fresh batch reads, committee proofs, settled checkpoints (#2971, #2972)
  • ⚠️ GraphQL server removed (#2926)
  • 🔒 Template address verified before caching (#2913)
  • 🐛 UTXOs indexed by shard, bounded stream reads (#2989, #2995)
  • 🐛 Previous-epoch checkpoint sync (#2985, #2998)

🧰 Other

  • ⚠️ engine_debug! removed from tari_template_lib (#2949)
  • 🐛 LP contribute returns both remainders (#2928)
  • 🐛 Manifest identifier resolution (#2922)
  • 🐛 Dry-run transactions refused at ingress (#2924)
  • 🐛 Workspace fee payer resolution in ootle_sdk_core (#2931)
  • Swarm hot-reloads [[executables]] (#2974)
  • 🔒 rustls 0.23.46 (#2941)

Changes: v0.46.1...v0.47.0

v0.46.1

v0.46.1 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 14 Oct 08:09
v0.46.1
4a9fc7d

🚀 Tari Ootle v0.46.1

✨ Highlights

  • ⚠️ Expired cross-shard transactions abort instead of staying prepared; validators upgrade together. (#2905)
  • 🐛 Sturdier state sync and RPC streams. (#2910, #2917)
  • ⚠️ Indexer GET /non-fungibles removed. (#2904)

🛡️ Validator Node

  • ⚠️ Expired cross-shard transactions left in LocalPrepared after their max epoch abort. (#2905)
  • 🔒 State sync requires every batch of a state version to carry one epoch. (#2910)
  • 🐛 RPC streams that are abandoned now end. (#2917)
  • Execution time histogram in validator metrics. (#2909)

🔎 Indexer

  • ⚠️ GET /non-fungibles removed, along with get_non_fungibles in the Rust and JS indexer clients. (#2904)
  • 🐛 State following runs on a dedicated RPC session. (#2917)
  • 🐛 Indexed receipts and templates survive conflicting sync updates. (#2901)

🧰 Other

  • 🔒 ruzstd 0.9.1 for RUSTSEC-2026-0344. (#2906)

Changes: v0.46.0...v0.46.1

v0.46.0

v0.46.0 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 13 Oct 10:47
v0.46.0
cc8a83b

🚀 Tari Ootle v0.46.0

✨ Highlights

  • ⚠️ Protocol V2: block headers commit to a transaction merkle root, substate proofs bind to their shard, and foreign pledges are authenticated. Esmeralda activates it at epoch 12220; every other network starts at V2 and must be reset. (#2804, #2762, #2798, #2867)
  • ⚡ Faster validator storage: substate locks, block diffs and pending state tree diffs are held in memory; databases migrate on first start. (#2862, #2863, #2868, #2879)
  • ⚠️ No return values in transaction results: read component state or events instead. (#2859)
  • 👛 Wallet daemon signing requests for out-of-band co-signing, with an approval page. (#2849, #2850)
  • 🔒 Hardening pass: bounds on what peers, templates and transactions can make a node do.

👛 Wallet

  • Signing requests for out-of-band co-signing, with an approval page in the walletd UI. (#2849, #2850)
  • ⚠️🔒 Approving a transaction request needs the wallet's own session; WebRTC apps need --enable-webrtc. (#2855)
  • 🐛 Claimed burn fee capped at the local price. (#2803)
  • 🐛 Transfer proof change nets out the revealed amount. (#2824)
  • 🐛 Confidential outputs finalize against the transaction diff. (#2898)
  • 🐛 Paying fees with a swap needs an explicit swap input. (#2837)
  • 🔒 Indexer failover: bounded requests, and substates that don't match their id are refused. (#2802, #2813)
  • 🔒 detect_inputs refuses signed submissions. (#2854)
  • 🔒 Pending WebAuthn sessions bounded. (#2899)
  • 🐛 Transaction builder signs the finished body. (#2852)

🛡️ Validator Node

  • ⚠️ Transaction merkle root in V2 block headers. (#2804)
  • ⚠️ Shard-bound substate proofs and sound Down proofs. (#2762, #2867)
  • ⚠️🔒 Authenticated foreign pledges and embedded foreign proposals. (#2798, #2827)
  • ⚠️ Claimed burn UTXOs go to the claim key, not the sealer. (#2800)
  • ⚡ In-memory locks, block diffs and tree diffs; databases migrate on first start and can't be opened by an older binary. (#2862, #2863, #2868, #2879)
  • ⚠️ Block and transaction write limits: 4 MiB of state per transaction, bounded bytes per shard, and a 1.5 MiB cap on a transaction's inputs per shard group in cross-shard pledges. (#2821, #2894)
  • ⚠️ Publish fees reflect compile work; oversized modules are refused. (#2881)
  • ⚠️ Duplicate m-of-n requirements rejected. (#2851)
  • ⚠️ State sync liveness hardening, new config settings and a schema version guard. (#2878)
  • 🐛 State sync proves state only at proof points, and pruned blocks stay provable. (#2864, #2876)
  • 🐛 State sync batches split by encoded size. (#2812)
  • 🔒 Engine metering: one compute budget across nested calls, and argument and return-value handling are charged. (#2817, #2858, #2888)
  • 🔒 Engine validation: event topics and view keys checked in full; template log output bounded. (#2880, #2882, #2884, #2895)
  • 🔒 Decode bounds on access rules and call arguments. (#2893)
  • 🔒 Consensus: timeout certificates bound to epoch and view; sync probe bound to the local shard group. (#2835, #2836)
  • 🐛 Proposal packing in random order, with a capped share for oversized transactions. (#2866)
  • 🐛 Leader-skip walk saturates at the top of the height range. (#2825)
  • 🐛 Committees reassigned when the epoch hash is corrected. (#2810)
  • 🐛 Proof pruning: down, state version and commit proofs pruned once unused. (#2874, #2877)
  • 🐛 Block commands held in a validated canonical list. (#2869)
  • 🔒 Networking: idle RPC sessions close, inbound connections and peer relays capped, direct messages decoded in the consumer. (#2816, #2856, #2887, #2896)
  • ⚠️ Metrics on their own listener (default 127.0.0.1:18201), no longer on JSON-RPC. (#2815)

🔎 Indexer

  • 🔒 Transaction results need committee agreement. (#2838)
  • 🔒 Verified substate reads need a recent anchor. (#2885)
  • 🔒 Rate limits on all public read routes; checkpoint pages capped at 20. (#2823)
  • 🐛 "database is locked" no longer fails submit bursts. (#2865)
  • 🐛 Cached component state keeps null. (#2870)

🧰 Other

  • 🐛 Liquidity pool rejects confidential deposits. (#2900)
  • 🐛 Account vault map bounded. (#2853)
  • 🐛 Template constructors returning a tuple compile. (#2871)
  • 🔒 Dependencies: wasmer 7.5.0; event-listener, cxx and gix-hash past unsound releases. (#2828, #2829, #2830, #2831, #2834)
  • Metrics reference docs for the validator node and indexer. (#2809)

What's Changed

  • chore(deps): bump hickory to 0.26.3 by @sdbondi in #2805
  • fix(engine)!: mint a claimed burn UTXO to the claim key, not the sealer by @sdbondi in #2800
  • feat(consensus)!: commit each block's finalized transactions to a transaction merkle root by @sdbondi in #2804
  • fix(wallet): bound indexer requests so an unresponsive indexer fails over by @sdbondi in #2802
  • test(smoke): add claim_burn stage by @sdbondi in #2806
  • test(storage): fix broken test by @sdbondi in #2807
  • fix(walletd): cap a burn claim's revealed fee at its local price by @sdbondi in #2803
  • docs: metrics reference for validator node and indexer by @sdbondi in #2809
  • docs: clarify covenant scope and OutputTo payment semantics by @sdbondi in #2811
  • fix(epoch_manager): reassign committees when correcting the current epoch's hash by @sdbondi in #2810
  • fix(validator): split metrics server from json rpc by @sdbondi in #2815
  • fix(validator): split state sync batches by encoded size by @sdbondi in #2812
  • fix(engine): share one WASM budget across nested template calls by @sdbondi in #2817
  • fix(networking): close idle RPC sessions and cap inbound connections by @sdbondi in #2816
  • fix(wallet): refuse indexer substates whose value does not match their id by @sdbondi in #2813
  • chore(deps): bump sharp from 0.35.4 to 0.35.5 in /docs/developer-docs by @dependabot[bot] in #2819
  • chore(deps): bump source-map-js from 1.2.1 to 1.2.2 in /docs/developer-docs by @dependabot[bot] in #2818
  • fix(consensus): bound bytes written per transaction and per shard per block by @sdbondi in #2821
  • fix(consensus): saturate the leader-skip walk at the top of the height range by @sdbondi in #2825
  • fix(walletd): net revealed amount out of transfer proof change by @sdbondi in #2824
  • fix(indexer): rate limit the remaining public read routes and cap checkpoint pages by @sdbondi in #2823
  • fix(consensus): install a high certificate only at its block's height and epoch by @sdbondi in #2822
  • fix(consensus): refuse commands in blocks that extend the end-of-epoch block by @sdbondi in #2820
  • chore: release v0.46.0 by @sdbondi in #2826
  • fix(deps): bump cxx to 1.0.195 by @sdbondi in #2831
  • fix(deps): move gix-hash to 0.18 to pick up faster-hex 0.10.1 by @sdbondi in #2829
  • fix(engine): drop tracing-subscriber 0.2 from the dependency graph by @sdbondi in #2830
  • fix(deps): bump event-listener to 5.4.2 and ban the unsound releases by @sdbondi in #2828
  • fix(consensus): bind a block's timeout certificate to its epoch and preceding view by @sdbondi in #2835
  • fix(integration_tests): wait on conditions with deadlines instead of fixed sleep loops by @sdbondi in #2833
  • chore(deps): bump wasmer to 7.5.0 by @sdbondi in #2834
  • fix(consensus)!: authenticate foreign pledge values and embedded foreign proposals by @sdbondi in #2798
  • fix(state-tree)!: bind substate value proofs to the substate's shard by @sdbondi in #2762
  • fix(consensus): reuse a stored foreign proposal's authentication only for its exact commit proof by @sdbondi in #2827
  • fix(wallet): require an explicit swap input when paying the fee with a swap by @sdbondi in #2837
  • fix(consensus): bind the future-epoch sync probe to the local shard group by @sdbondi in #2836
  • fix(indexer): require committee agreement on transaction results by @sdbondi in #2838
  • fix(transaction): sign the finished body in the builder's Signable impl by @sdbondi in #2852
  • feat(walletd): add signing requests for out-of-band co-signing by @sdbondi in #2849
  • fix(template_lib)!: reject m_of_n rules that list a requir...
Read more

v0.45.0

v0.45.0 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 06 Oct 11:28
v0.45.0
9c62606

Updates the minotari dependencies to 6.1.0-pre.0 and tari_crypto to 0.24.

⚠️ Upgrade notes

  • V1 block IDs change. Networks already running V1 upgrade together; esmeralda, still on V0
    until epoch 11925, is unaffected now but must run 0.45.0 before activation. (#2799)
  • Validator L1 registration and exit signatures commit to the network, and an exit also
    commits to the activation epoch of the registration it exits. Exit payload files written by an
    older validator no longer load. (#2799)

Other

  • chore! — minotari 6.1.0-pre.0 and tari_crypto 0.24. (#2799)

v0.44.0

v0.44.0 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 06 Oct 10:29
v0.44.0
5bf0d8d

Introduces protocol version V1, which commits each shard's state version in the state merkle root
and lets state sync verify streamed state incrementally. Esmeralda activates V1 at epoch 11925;
every other network starts at V1. Also tightens resource authorization and bounds several peer and
indexer inputs.

⚠️ Upgrade notes

  • Every esmeralda validator upgrades before epoch 11925. V1 activates there and changes the state
    merkle root; a node still on 0.43.x forks off. (#2784)
  • A synced node below its checkpoint version must resync. (#2795)
  • Non-fungible data updates are denied to non-owners by default. ResourceAccessRules::new()
    sets update_nft_data to DenyAll; templates that relied on the open default must allow it
    explicitly. (#2786)
  • The resource auth hook runs on stealth and confidential actions. AuthHookCaller::template()
    returns Option — None when a transaction instruction performed the action. (#2787)
  • Only a liquidity pool may mint or burn its LP tokens. Pools created before this release keep
    their old rules. (#2759)
  • Wallet daemon settings take indexer_urls. settings.get also returns the configured list.
    (#2753)

Consensus

  • feat! — Each shard's state version is committed in the state merkle root under V1. (#2784)
  • fix — A transaction is voted forward only once its shard groups are ready. (#2771)
  • fix — Requested transactions are decoded only once the response is matched. (#2788)

State sync

  • feat — Streamed state is verified incrementally with state version proofs. (#2796)
  • fix! — Synced shards end at the checkpoint version. (#2795)
  • fix — Synced state that never matches the checkpoint is discarded. (#2765)
  • fix — Only a signed same-group QC counts as stall-probe progress. (#2774)

Engine

  • fix! — Non-fungible data updates are denied to non-owners by default. (#2786)
  • fix — The resource auth hook runs on stealth and confidential actions. (#2787)
  • fix — Scalar inversion is priced as an exponentiation. (#2794)
  • fix! — Only the pool may mint or burn its LP tokens, and swaps are rejected while either
    reserve is empty. (#2759, #2763)

Validator node and networking

  • fix — Transaction decode is bounded by byte size and instruction count. (#2761)
  • fix — A history sync request is bounded in the epoch it may ask for. (#2776)
  • fix — A peer can hold a messaging stream only for a bounded time. (#2770)
  • fix — A failed RPC session start releases its per-client slot. (#2764)

Indexer

  • feat! — Substate and transaction receipt proofs are served on request with include_proofs.
    (#2760)
  • feat — Receipts and events have a retention period, and SQLite contention is reported as
    metrics. (#2757)
  • feat — The economics page reports the fees validators can claim. (#2756)
  • fix — State versions accepted from sync peers are bounded. (#2767)
  • fix — Checkpoint exhaust burns are bounded and overflowing economic totals refused. (#2789)
  • fix — Rate limits key on CF-Connecting-IP or the last X-Forwarded-For entry. (#2755)
  • fix — The UI shows transactions whose execution result validators have pruned. (#2768)

Wallet

  • feat — The wallet daemon takes several indexers and fails over between them. (#2753)
  • fix — nfts.transfer requires transfer scope on the fee payer. (#2785)

Other

  • fix — tari_bor escapes text-keyed maps holding a reserved key in the JSON form. (#2777)
  • fix — A blob! name that is not an identifier is a manifest error. (#2766)
  • feat — A swarm smoke test script. (#2782)

🚀 Tari Ootle v0.43.0

Pre-release

Choose a tag to compare

@github-actions github-actions released this 02 Oct 05:13
v0.43.0
392d805

21 PRs merged since v0.42.0.

✨ Highlights

  • ⚠️ Coordinated upgrade required: consensus rules changed; no state store deletion needed
  • 🔒 Empty proofs no longer grant access: zero-amount and empty proofs fail resource access rules (GHSA-pp4v)
  • 🔒⚠️ Covenant proofs and template compiles metered: covenant balance proofs charged; templates capped at 2,048 functions (#2739, #2747)
  • ⚠️ 1,024 declared-input cap: enforced at ingress and in block validation (#2744)
  • 🔒 Hardened consensus messaging: malformed, unauthorised and mis-committee'd messages dropped (#2737, #2738)

👛 Wallet

  • 🐛 Seed recovery cleanup: unused recovered accounts removed (#2735)
  • Stealth input headroom: transfers select at most 992 stealth inputs (#2744)
  • 🐛 Auto-claim retries: not-yet-claimable burn claims resubmitted; consensus epoch used (#2749)
  • Indexer failover: indexer client and ootle-rs provider switch endpoints at runtime (#2750)

🛡️ Validator Node

  • 🔒 Empty proofs no longer grant access: zero-amount and empty proofs rejected (GHSA-pp4v)
  • 🔒⚠️ Covenant balance proofs metered: duplicate and out-of-range covenant claims rejected (#2739)
  • 🔒⚠️ Template compile caps: 2,048 functions and 512Ki variables, priced by function count (#2747)
  • ⚠️ 1,024 declared-input cap per transaction (#2744)
  • 🔒 Foreign proposal verification: checked against the named shard group's committee (#2737)
  • 🔒 Peer message admission: malformed and unauthorised messages dropped (#2738)
  • 🐛 State sync serving: bounded requests served only for history the node holds (#2733)
  • 🐛 Epoch resume after restart: unfinalised leaf epoch resumed correctly (#2746)
  • 🐛 Faster catch-up: lagging replica syncs as soon as a proposal shows it is behind (#2743)

🔎 Indexer

  • 🔒⚠️ Bounded dry-runs: structural validation, batched input lookups, 400 on missing inputs (#2744)
  • 🔒 Dry-run concurrency cap: compute-weighted rate limit, 503 when saturated (#2745)
  • ⚠️ Rate limits on by default: set trust_proxy_headers behind a reverse proxy (#2744)
  • 🔒 Bounded event queries: capped scans and before_id cursor paging (#2742)
  • 🐛 Wildcard topic filters: underscores matched literally (#2740)
  • 🐛 Consensus epoch: dry-runs execute in it; reported as consensus_epoch (#2749)

🧰 Other

  • ⚠️ C FFI ABI tag: bumped to ootle-sdk-ffi-c/17 (#2736)
  • 🐛 Swarm claim key: created before validators start, reused if present (#2741, #2752)
  • 🐛 macOS binaries: OpenSSL vendored (#2751)

Full Changelog: v0.42.0...v0.43.0

🚀 Tari Ootle v0.42.0

Pre-release

Choose a tag to compare

@github-actions github-actions released this 30 Sep 12:37
v0.42.0
a43773e

53 PRs merged since v0.41.2.

✨ Highlights

  • ⚠️ Testnet reset
  • ⚠️ Empty tTARI faucet: get tTARI by burning Minotari (#2724)
  • ⚡ Faster execution: WASM instance reuse and memory pooling (#2697, #2701)
  • 🔒 Protocol security fixes/hardening
  • 🛡️ Validator storage: soundness fixes, durable votes persistence, faster RocksDB access and GC

👛 Wallet

  • ⚠️ Empty faucet on public testnets (#2724)
  • resources.get / resources.get_many: new JSON-RPC methods (#2700)
  • Manifest list arguments: list values and list-valued variables (#2717)
  • 🐛 JS client: covers every walletd JSON-RPC route (#2699)

🛡️ Validator Node

  • ⚠️ Web UI on the JSON-RPC port: CORS now opt-in (#2726)
  • ⚠️ L1 template registrations removed: no global templates table (#2725)
  • ⚠️ L1 block_output_mr stored with each base-layer header (#2707)
  • ⚠️ Timeout certificates: bind the high QC; header commits to the TC (#2636, #2642)
  • ⚠️ Dummy block ids commit to is_dummy (#2694)
  • ⚠️ LocalOnly commands drop evidence (#2688)
  • ⚠️ Receipts list down-only substates (#2692)
  • ⚠️ Validator fee pools kept out of the transaction diff (#2693)
  • ⚠️ Claims: "must wait" distinct from "invalid" (#2686)
  • ⚠️ Substate version widened to u64 (#2596, #2687)
  • ⚠️🐛 Substate lock fixes: per-chain, per-epoch lock resolution (#2711, #2716, #2720, #2722)
  • 🐛 Votes and proposals fsynced before sending (#2721)
  • 🐛 Deferrable lock conflicts no longer cause block refusals (#2730)
  • 🐛 Committee assignments: one per validator and epoch (#2732)
  • 🐛 RPC: not-ready peers return Unavailable (#2731)
  • 🐛 Write to read-declared input refused when kept, not locked (#2715)
  • 🐛 Claim burns cite headers from an earlier epoch only (#2706, #2685)
  • 🐛 Clean shutdown: panic recorder releases the state store (#2714)
  • ⚡ Storage performance: cheaper RocksDB lookups, single pending-chain read, chunked GC (#2718, #2719, #2723)
  • ⚡ Batch signature verification (#2695)

🔎 Indexer

  • ⚠️ Stale validator snapshots shown with the probe error (#2691)
  • 🐛 Failed sync peers forgotten on epoch change (#2689)

🧰 Other

  • ⚠️ Read/write intent on transaction inputs (#2640)
  • ⚠️ Metadata values are CBOR; manifest typed values are macros (#2679)
  • ⚠️ Stealth: revealed outputs name their receiver (#2645)

Changes: v0.41.2...v0.42.0

What's Changed

  • test(epoch_oracles): fix timing flake in it_ticks_according_to_relative_time by @sdbondi in #2684
  • fix!: reword the claim-burn "block header not found" error by @sdbondi in #2685
  • feat(substate)!: widen the substate version to u64 by @sdbondi in #2596
  • feat(engine)!: tell a claim that must wait from one that is invalid by @sdbondi in #2686
  • refactor!: introduce a SubstateVersion newtype by @sdbondi in #2687
  • feat(consensus)!: bind the committee's high certificate into the timeout certificate by @sdbondi in #2636
  • feat(consensus)!: commit the block header to its timeout certificate by @sdbondi in #2642
  • feat!: metadata values are CBOR; manifest typed values are macros by @sdbondi in #2679
  • fix(indexer): forget failed sync peers when the epoch moves by @sdbondi in #2689
  • feat(consensus)!: drop evidence from LocalOnly commands by @sdbondi in #2688
  • feat(engine)!: list down-only substates in the transaction receipt by @sdbondi in #2692
  • feat(indexer)!: show stale validator snapshots and the probe error by @sdbondi in #2691
  • fix(engine)!: keep validator fee pools out of the transaction diff by @sdbondi in #2693
  • refactor(transaction): batch-verify signatures with tari_crypto's verify_batch by @sdbondi in #2695
  • fix(consensus)!: commit block ids to whether the block is a dummy by @sdbondi in #2694
  • chore(deps): accept libsqlite3-sys 0.30 through 0.35 by @brianp in #2696
  • test(consensus): unmute the returning validator once its misses suspend it by @sdbondi in #2698
  • feat(transaction)!: declare read or write intent on each transaction input by @sdbondi in #2640
  • fix(clients): cover every walletd JSON-RPC route in the JS client by @sdbondi in #2699
  • feat(walletd): add resources.get and resources.get_many JSON-RPC methods by @sdbondi in #2700
  • perf(engine): pool guest linear-memory reservations across instantiations by @sdbondi in #2697
  • perf(engine): reuse one WASM instance per template within a transaction by @sdbondi in #2701
  • ci: build a validator node + indexer docker image on self-hosted with a registry cache by @sdbondi in #2703
  • chore(deps): bump cloudflare/wrangler-action from 4.0.0 to 4.1.3 by @dependabot[bot] in #2704
  • chore(deps): bump taiki-e/install-action from 2.87.15 to 2.87.20 by @dependabot[bot] in #2705
  • fix(engine): claim burns cite headers from an earlier epoch only by @sdbondi in #2706
  • feat!: store the L1 block_output_mr with each base-layer header by @sdbondi in #2707
  • feat(stealth)!: a revealed output names its receiver by @sdbondi in #2645
  • feat!: collapse ProtocolVersion to a single V0 for the testnet reset by @sdbondi in #2712
  • fix(storage)!: resolve a substate's latest lock from the chain that granted it by @sdbondi in #2711
  • feat!: prove burn claims with the L1 burn output, and require its claim key to sign by @sdbondi in #2709
  • refactor(indexer): drop bincode naming and the bincode workspace dependency by @sdbondi in #2713
  • fix(validator): release the state store held by the panic recorder at shutdown by @sdbondi in #2714
  • fix(storage,consensus): scope the remaining lock reads to one chain by @sdbondi in #2716
  • fix(engine): refuse a write to a read-declared input when it is kept, not when it is locked by @sdbondi in #2715
  • feat(manifest): accept list arguments and list-valued variables by @sdbondi in #2717
  • feat(consensus)!: let a council move the exhaust burn rate without a release by @sdbondi in #2675
  • fix(storage)!: keep every lock a block grants a transaction on one substate by @sdbondi in #2720
  • perf(storage): cheaper RocksDB point lookups and mempool readiness checks by @sdbondi in #2718
  • fix(consensus,storage): fsync votes and proposals before sending; exact multi_get for state sync by @sdbondi in #2721
  • perf(storage,consensus): read the pending chain once per block instead of once per substate by @sdbondi in #2719
  • fix(storage)!: place a lock on the chain by its block's epoch and height by @sdbondi in #2722
  • perf(storage,consensus): run epoch and state tree GC in small transactions by @sdbondi in #2723
  • feat(walletd)!: start public testnets with an empty tTARI faucet by @sdbondi in #2724
  • fix(validator_node)!: serve the web UI from the JSON-RPC port and make CORS opt-in by @sdbondi in #2726
  • refactor!: remove L1 code template registration leftovers and the global templates table by @sdbondi in #2725
  • chore: release v0.42.0 by @sdbondi in #2729
  • chore(deps): bump undici, wrangler and @cloudflare/vite-plugin in /docs/developer-docs by @dependabot[bot] in #2728
  • chore(deps): bump brace-expansion from 5.0.6 to 5.0.12 in /applications/tari_swarm_daemon/webui by @dependabot[bot] in #2727
  • fix(consensus): stop replicas refusing blocks over deferrable lock conflicts by @sdbondi in #2730
  • fix(rpc): signal a peer not ready to serve with an Unavailable status code by @sdbondi in #2731
  • fix(storage): keep one committee assignment per validator and epoch by @sdbondi in #2732
  • chore(deps): upgrade minotari crates to 6.0.1-pre.2 by @sdbondi in htt...
Read more

v0.41.2

v0.41.2 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 23 Sep 11:40
v0.41.2
2a45ff4

The engine and wallet security review release. It closes the ways a crafted template or payload
could crash a validator, a wallet daemon that let anyone enrol an admin credential, and a module
cache that trusted what it read from disk. Also: a validator that stops proposing is skipped as
leader instead of costing the network a timeout, and a component's owner can hand ownership on.

⚠️ Upgrade notes

  • Coordinated upgrade required. Leader selection and execution change in ways that cannot be
    epoch-gated, so every validator and indexer restarts on the new binary together. No reset.
  • Operators — every cached template recompiles once. The on-disk module cache is keyed to the
    new engine fingerprint, so existing artifacts are ignored after the upgrade.
  • Wallet — a WebAuthn wallet accepts no second enrolment. Once one credential is registered,
    webauthn.reg_start and reg_finish refuse, and the requested permissions are no longer taken
    from the caller.
  • Wallet — changing the indexer URL now needs admin. A client holding only settings:update
    can still change every other field of settings.set; the web UI already holds admin.
  • Template authors — ComponentManager::get_owner_proof returns Option<Proof>, and an
    m_of_n rule whose threshold is zero or above its requirement count is rejected.
  • Rust API — ConfidentialViewVaultBalanceResponse and StealthUtxosDecryptValueResponse gain
    a searched field; WalletStoreReader::webauthn_is_user_registered is now
    webauthn_has_any_registration; WebauthnAlreadyRegisteredRequest drops username and
    WebauthnFinishRegisterRequest drops requested_permissions.

Consensus

  • feat! — A validator that stops proposing is skipped as leader instead of costing the network
    a timeout each time its slot comes round. Its votes keep counting, and it gets its slot back once
    it is seen participating again. (#2652)
  • feat — A node withholds its vote from a proposer it caught equivocating. (#2652)

Engine

  • fix! — A deeply nested CBOR payload can no longer crash a validator, including one hidden in
    a published template's definition. (#2666)
  • fix! — CBOR integers the encoder cannot produce are rejected on decode. (#2666)
  • fix! — Removes undefined behaviour in how nested calls share the runtime. (#2667)
  • fix! — A corrupted or stale module cache file is recompiled instead of loaded. (#2668)
  • fix! — Closes the rest of the engine review: a multi-scalar multiplication priced by only
    one of its arguments, amount arithmetic that could wrap, and four panic sites beside the
    execution path. (#2672)
  • feat! — A component's owner can now replace its owner rule, including handing ownership to
    someone else or setting it to None, which is final. (#2677)
  • fix! — ComponentManager::get_owner_proof returns Option<Proof> and no longer panics for a
    component whose owner is not a single public key. (#2677)
  • fix! — An m_of_n rule must require between 1 and all of its requirements. A zero threshold
    used to admit everyone and one above the count admitted no one. (#2678)

Wallet

  • fix! — Any process that could reach a WebAuthn wallet's RPC port could enrol itself as an
    admin.
    Enrolment is now refused once the wallet has a credential. (#2671)
  • fix! — Choosing which indexer the wallet trusts now takes an administrative token. (#2673)
  • fix — JSON-RPC parameters are no longer written to the log, where an imported spending key
    could end up in plaintext. (#2673)
  • fix — One balance-recovery request can no longer occupy a thread indefinitely. (#2673)
  • feat! — A balance recovery now reports which values it searched, so an undecryptable balance
    can be told apart from one the search never reached. (#2673)

Other

  • chore — All open dependency advisories are closed, and advisories now fail CI. (#2670)
  • docs — New guide: burning Minotari and claiming TARI. (#2680)

Packages

  • Crates: workspace 0.41.2; tari_bor 0.16.1, tari_template_abi 0.20.1, tari_template_lib
    0.32.1, tari_template_lib_types 0.32.1, tari_ootle_wallet_sdk 0.43.2,
    tari_ootle_wallet_storage_sqlite 0.43.1, tari_ootle_walletd_client 0.43.1.
  • npm: @tari-project/ootle-ts-bindings 1.54.0, @tari-project/wallet_jrpc_client 1.23.0,
    @tari-project/indexer-client 1.7.0.

Full changelog: v0.41.1...v0.41.2

v0.41.1

v0.41.1 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 21 Sep 10:46
v0.41.1
4732f65

The consensus audit release. It closes the ways a byzantine leader could fork a committee, stall it
or crash its replicas, and stops a peer deciding how much work a node does for it. Also: a wallet
send that could hang the daemon, a disk cache that only ever grew, and a queryable log of what a
validator saw go wrong.

⚠️ Upgrade notes

  • Coordinated upgrade required. Consensus and execution both change in ways that cannot be
    epoch-gated, so every validator and indexer restarts on the new binary together. No reset.
  • Operators — the memory budget rises. The in-memory module cache default moves from 200 MiB to
    1 GiB, taking the node's enforced budget to roughly 2.3 GiB and the RAM it asks of the machine
    from ~2.3 GiB to ~3.5 GiB.
  • Operators — two new config sections: templates.max_disk_cache_size_bytes
    (default 10 GiB, and the indexer gains a templates section of its own) and
    [validator_node.diagnostics].
  • Template authors — a non-fungible's data or mutable_data can no longer hold a BucketId,
    ProofId or address allocation.
  • Rust API — WasmModuleCache::open takes a cap_bytes argument,
    RuntimeError::transient_in_component_state is now transient_value_in_substate, and
    TemplateBlob is MaxBytes<MAX_TEMPLATE_BLOB_WIRE_BYTES>.

Consensus

  • fix! — Fixes a possible committee split, where a byzantine leader could get two conflicting
    branches of the chain committed. (#2635)
  • fix! — A byzantine leader can no longer make replicas vote for a transaction an honest leader
    would have deferred.
    (#2650)
  • fix! — A byzantine leader can no longer crash every replica's consensus worker, repeatedly.
    (#2651)
  • fix! — Substate lock checks are tightened, closing a gap the audit found in how output
    locks are granted. (#2650)
  • fix — A committee member can no longer take back a vote it has already cast to break a
    quorum that is forming. (#2649)
  • feat — Equivocation is recorded as evidence when a committee member votes two ways, visible
    as a diagnostic event, a Prometheus counter and in db-inspector. Nothing acts on it yet. (#2649)
  • fix — A node that crashes just after voting can no longer vote again at that height. (#2649)
  • fix — Only committee members can feed a node's consensus, and a response is accepted only
    from the peer that was asked. (#2646)
  • fix — A peer can no longer decide how much memory and work a node spends on it — catch-up
    responses, buffered messages and stored votes are all bounded. (#2647)
  • fix — A leader that is ahead of the committee can still end its view, where it previously
    had to wait one out. (#2638)
  • refactor — A commit proof is now a fixed size, small enough that a long stall cannot push it
    past what the base layer will verify. (#2643)

Engine

  • fix! — Transaction-scoped ids can no longer be stored in non-fungible data, where they would
    outlive the transaction that named them. (#2634)
  • fix! — Anyone may call deposit_with_auth, which is the point of the method — it was locked
    to the account owner, the one caller who never needs it. (#2627)
  • feat! — The compiled-template caches are bounded. The on-disk one only ever grew, and would
    have reached about 29 GiB at 10,000 templates. (#2619)
  • perf — Templates are compiled before they are needed, and a cached artifact is written
    off the execution path, so a transaction no longer waits on a cold compile or a disk flush.
    (#2660, #2661)
  • refactor — The maximum published-template size can now be changed without making larger
    already-published templates unreadable. (#2629)

Wallet

  • fix — A wallet holding many equal-valued outputs could hang the whole daemon while selecting
    inputs for a send. The search is now capped. (#2639)

Validator observability

  • feat — A validator records its own abnormal moments — leader failures, no-votes, consensus
    errors, sync transitions, panics — in a bounded event log, queryable over JSON-RPC and in the web
    UI. (#2644)

Release tooling and CI

  • feat — Release checklists, plus a pre-tag gate and a post-tag dashboard
    (scripts/release_check.py, scripts/release_status.py). (#2630)
  • fix — The release build selects packages, which is why v0.41.0 shipped no Windows binaries.
    (#2631)
  • fix — A failed required build leg turns the tag run red instead of reporting green over an
    incomplete draft. Tag builds also restore the cargo cache, riscv64 is dropped, and windows-arm64
    links again. (#2632, #2633)
  • fix — The swarm burns funds into the wallet daemon, not the console wallet. (#2628)
  • fix — The tariswap bench stamps a distinct nonce per transaction, so identical calls no
    longer collide on one id. (#2626)

Tests

  • test — Within-epoch catch-up sync has a cucumber scenario, covering over real networking
    what only the in-process harness covered. (#2648)

Full Changelog: v0.41.0...v0.41.1

v0.41.0

v0.41.0 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 16 Sep 12:03
v0.41.0
ac73128

⚠️ Upgrade notes

Wallet

  • feat! — A fragmented balance is spendable again. A key-path stealth spend authorizes each
    input with its own one-time key, so spending n stealth inputs takes n signatures. At a cap of
    16 that made the signature cap — not STEALTH_LIMITS, which admits 1024 inputs — the binding limit
    on a multi-input spend, expressed in the wrong units and in a crate a wallet author reading the
    stealth limits would never consult. A wallet whose balance was split across more than 17 stealth
    UTXOs could not spend it in one transaction, and a coinjoin was capped at 17 participants. The cap
    is now 1024, made affordable by verifying a transaction's whole signature set as one batch: one
    multiscalar multiplication over 2n + 1 terms in place of n double-base multiplications, ~3x at
    the cap with the per-signature cost falling as the set grows, and 2.6x cheaper to refuse an
    invalid set than the per-signature path it replaces. Weights are hash-derived rather than sampled,
    so a validity predicate a committee votes on does not depend on local randomness. A spend at the
    cap costs 22,628 of the 24,000 weight a leader packs, so weight — not the count — is what stops one
    monopolising a block.
  • fix — A transfer and its fee now share one input budget. Selection used
    STEALTH_LIMITS.max_inputs, the cap on a single statement (1000), but what bounds a wallet is
    the per-transaction total (1024) — and a transfer that cannot source its fee from its own
    revealed remainder carries a second statement whose inputs come out of that same total. Both
    selections were capped independently, so a fragmented wallet could build a transaction of up to
    2000 inputs against a ceiling of 1024, which the engine refuses and ingress refuses before that:
    the wallet building what the network will not take. Now MAX_TRANSFER_INPUTS = 960 and a
    FEE_INTENT_INPUT_RESERVE of 64, held back unconditionally — whether a merged statement fits the
    fee-intent credit is only known after selection, and a selection that had already claimed the whole
    budget could not fall back.
  • feat — Transaction finality is driven from the indexer's event stream. The transaction
    service learned of finality only by polling the indexer for every pending transaction every 5 s. It
    now subscribes to /events and queries a transaction's result the moment a TransactionFinalized
    notification names it. An aborted transaction writes no substate and is silent on the stream, so
    the 5 s poll stays as a backstop — but while the stream is connected it only queries transactions
    pending longer than silent_transaction_timeout (10 s). Commits are reported as soon as the
    indexer's stream delivers the receipt, an abort is noticed within ~10 s instead of ~5 s, at a third
    of the previous query load. /events has no replay, so each reconnection requests a full check.
  • fix — A UTXO scan could silently skip outputs — no error, no gap in the frame sequence, and
    nothing to notice after the fact. Two independent causes in the /utxos/stream resume protocol.
    state_version is stamped per sync batch, so every UTXO a block touches on a shard shares one
    version and a LIMIT n cut landing inside a version group reported that group's version as the
    watermark — the next request's > V filter then dropped the rest of the group, and one busy block
    on a shard was enough. And EndOfShard.max_state_version came from MAX(state_version) over the
    whole shard, ignoring from_epoch, unspent_only and truncation, so a truncated pass jumped its
    cursor past its own undelivered remainder. Reads now end on a version boundary, and truncation is
    the server's answer (has_more) rather than each client's inference.
  • fix — A missing substate answers NotFound, not a general error. A caller polling for
    something that does not exist yet — an account it has just created, an input whose creating
    transaction has not reached the indexer — could not distinguish that from the wallet being broken,
    and only one of the two is worth retrying. The distinction was already carried by
    SubstateApiError's IsNotFoundError impl and simply never reached the JSON-RPC layer.
  • fix — X-Accel-Buffering: no on /events, /transactions/events/stream and /utxos/stream;
    nginx and the proxies following its conventions buffer upstream responses by default, which on a
    long-lived SSE stream means indefinitely. /utxos/stream declares its negotiated content type
    (application/x-protobuf or application/x-ndjson) instead of always answering
    application/octet-stream.
  • feat — put_workspace alias on the transaction builder.

Indexer and state sync

  • feat — Follow mode: the indexer stops polling. Each shard group holds a sync_state stream
    open past the validator's tip and receives transitions as they commit, so cache invalidation
    latency drops from one sync round (~60 s) to roughly one block. Shard groups run concurrently
    under a FuturesUnordered; each winds its own stream down between messages on an epoch advance,
    syncs the new epoch's checkpoints, re-resolves its committee and reopens from the cursor it holds.
    A global re-plan happens only when the set of shard groups itself changes. Keepalives re-stamp the
    watermark of every shard a stream has closed off, so a quiet shard stays served for as long as its
    validator keeps answering and state_sync_stream_deadline (now 600 s) is only how often a quiet
    stream is reopened.
  • feat — Per-request deadlines and keepalives made it possible. Both were already per-request
    fields on the wire, but the only way to set either was RpcClientConfig, fixed when the session is
    created — and RpcMultiPool caches one client per peer, so buying a long deadline for one
    long-lived stream applied it to every ordinary read on that session. New ACK keepalive frames let
    an idle streaming response prove liveness within its deadline rather than extending it; before,
    a responder with nothing to send was indistinguishable from one that had died. Restoring the
    framework's dead test suite (~1,900 lines behind two commented-out mod lines) turned up several
    pre-existing bugs, fixed here: read timeouts that restarted on every frame including keepalives,
    so asking for keepalives made the client wait longer and an idle stream never timed out at all; a
    refused session reported as Ok; a fixed budget of twenty discarded stale frames tearing down a
    whole pooled session; and a server that could not be driven without a libp2p transport.
  • fix — A sync_state responder answers only for shards it stores, at the epoch of sending. An
    unbounded request for shards a node no longer serves streamed no transitions — because none arrive
    for those shards any more — and then closed each shard off with a completion marker. The indexer
    takes a completion marker as evidence that a shard is level with its committee, so that silence
    read as freshness and the cache kept serving values it believed current. Follow mode makes this
    load-bearing: a held-open stream spans epoch boundaries, and "peer went quiet" must read as
    unknown, never as caught up. A peer-attributable failure now skips only that shard group rather
    than costing every other group its state sync.
  • fix — Three ways a stale value could be installed as the live head, all closed. A committee
    member that is behind answers with a version this indexer has already watched the substate pass —
    legitimately, from its own point of view — and the transition had already deleted the cached row
    that would have ranked the answer down, so a write below the version the stream has shown is now
    refused. A destroy with no successor no longer admits an Up at the destroyed version while still
    admitting a Down at it. And a finalized transaction result retires what it created or destroyed
    ahead of the stream, which is what the transfer.feature "substate does not exist" failures were:
    the wallet asked whether a destination account existed, that nonexistence was cached, it learned
    the transfer committed, and read back the stale answer.
  • feat — Substates the committee agrees do not exist are cached. DoesNotExist is the most
    expensive lookup the indexer makes: Up and Down return on the first acceptable response, but
    absence has nothing to prove against the state tree, so it is settled by f + 1 agreement and
    walks that many committee members — every time, because it was also the one result the cache would
    not keep. Recorded as a row with no version rather than a sentinel, so Option's own ordering
    gives the head-ranking rule for free. Served only while the shard's stream is demonstrably alive
    (state_sync_keepalive_interval × 3), because a nonexistence is correct at the instant it is taken
    and false ever after; transaction receipts are excluded, since they are the bulk of the stream by
    count and are answered from the indexer's own tables anyway.
  • feat — Committee members are raced on a substate read, up to READ_RACE_WIDTH = 3 in flight,
    settling on the first response that decides the read. Members were asked one at a time, so an
    unreachable first pick waited out the full 10 s connect timeout — on a small committee, a 1-in-n
    chance per read of a multi-second stall. The decision rules move into one CommitteeReadTally, and
    DoesNotExist now settles at f + 1 throughout rather than needing f + 2 on the way through the
    loop.
  • feat! — The batched substate read path carries proofs. get_substate_batch streamed bare
    values, so every batch result was written unverified — and with proof verification on the read path
    refused those entries and refetched singly, so ...
Read more