[Alphanet] v1.31.0-alpha
Pre-releaseProtocol
This release introduces protocol version 34
On alphanet, this protocol version can be enabled no earlier than 2026-08-29 01:03 UTC (start of epoch 113). Please ensure that you update your validators before this epoch change. Otherwise, if the upgrade threshold is reached, the protocol will remove you from the committee, and both you and your delegators will lose rewards.
#12685: Enable leader schedule redesign on testnet: sliding window and absolute-score bad node selection
#12297: Adds the max_concurrent_execution_workers parameter (execution-worker congestion control). Declared only — not set in any protocol version, so no behaviour change on any network. Setting it requires enable_pcool_flow, per-object congestion control (max_accumulated_txn_cost_per_object_in_mysticeti_commit), and separate_gas_price_feedback_mechanism_for_randomness to be off; all three are enforced by assertions.
#12517: Opens protocol version 33, which adds the dormant iota::transaction_deny_rules system module at reserved object ID 0xDE9 (inactive until deny-rule governance is enabled).
#12661: Adds pcool_skip_immutable_object_locks (new protocol version 34): immutable transaction inputs no longer acquire owned-object locks in post-consensus conflict resolution. Inert unless the P-COOL flow is enabled.
Nodes (Validators and Full nodes)
#12666: a config with policy-config: null or grpc-api-config: null stays disabled when the config is re-serialized, instead of silently re-enabling.
#12297: Adds execution-worker congestion control to the post-consensus sequencer, inactive until max_concurrent_execution_workers is set. When active:
- All transactions, including owned-object-only ones, are scheduled against a bounded worker pool. Transactions that do not fit are deferred, and cancelled once the deferral limit is reached; cancelled transactions are charged gas and recorded in checkpoints with a suggested gas price for resubmission.
- A single congestion tracker and suggested gas price calculator schedule all transactions — regular and randomness-using — in one gas-price order, replacing the separate per-kind trackers used previously.
- A new execution error variant
ExecutionCanceledDueToExecutionWorkerCongestionis introduced for when execution-worker pool is the binding constraint: always for owned-object-only transactions, and for shared-object transactions whose objects fit within the per-commit limit. consensus_handler_max_object_costs{randomness_commit}reports0, since there is no separate randomness tracker;{regular_commit}now also accounts for execution-worker occupancy, so it is non-zero for commits containing only owned-object-only transactions.
#12663: Full nodes now follow the P-COOL enablement at the epoch boundary without a restart, and stop sending latency pings and health checks while the P-COOL flow is disabled. Full nodes that started while P-COOL was enabled require a restart before serving the certificate flow after a rollback; until then their submissions fail and the fullnode log states that a restart is required.
#12682: Full nodes no longer count transaction-not-found responses toward the error policy. Zero-weight tallies are never sampled.
#12720: Traffic control dry-run now also covers remote firewall delegation. No blocks are sent to the firewall while dry-run is enabled. Please set dry-run: false to keep delegating.
#12741: A node that fails during startup now exits with the actual error logged instead of aborting with an unrelated panic.
#12661: Fixes transactions being rejected with ObjectLockConflict against an immutable input (e.g. a CoinMetadata) for the remainder of an epoch under the P-COOL flow.
#12784: a syncing node no longer re-downloads and re-verifies checkpoint summaries the checkpoint-archive sync has already stored, so catching up does less redundant work and asks less of its peers.
Indexer
#12669: iota_dryRunTransactionBlock and iota_devInspectTransactionBlock now behave the way the node's own JSON-RPC does.
- Gas the caller leaves unset is resolved by the node rather than by the indexer: no payment gets a mock gas coin, a zero
gas_pricethe epoch's reference gas price, and a zerogas_budgetwhat the gas coins can back. - The reported transaction carries what the simulation charged — the price, the resolved budget, and the mock gas coin — instead of the transaction as sent.
- A gasless
iota_dryRunTransactionBlockreports the digest of what ran, so created object IDs change accordingly, and no longer attributes a balance change to the mock gas coin. - Event and type resolution now covers packages the simulated transaction itself published, so a dry run that publishes a package can decode the events its
initemits.
#12699: 🪛 restore operations, where the tables for transactions and events would grow indefinitely eluding the pruner, without partitioning their data. Operators that are running an Indexer instance restored from a formal snapshot, are advised to upgrade immediately to the new version of the software, so that self-healing of the partitions will take effect with the next epoch. Some downtime on the read path should be expected while the self healing is in progress.
At any case, the affected partitions {transactions,events}_partition_0 must be dropped manually, when the data therein fall beyond the configured retention period, if any.
#12548: Removed the deprecated --objects-snapshot-min-checkpoint-lag / --objects-snapshot-sleep-duration CLI flags and the OBJECTS_SNAPSHOT_MIN_CHECKPOINT_LAG env var which currently were no-ops.
JSON-RPC
#12682: iota_getTransactionBlock now returns error code -32003 when a transaction is not found.
#12540: Adds the TransactionDenyRulesUpdate transaction block kind and the TransactionDenyRulesCreate end-of-epoch kind to the API types (never emitted until deny-rule governance is enabled).
GraphQL
#12662: objects(filter: { type }) no longer times out for types with many objects.
#11949: new optional CLI flags --fallback-kv-url, --fallback-kv-multi-fetch-batch-size, --fallback-kv-concurrent-fetches, --fallback-kv-cache-size for the archival fallback. Setting --fallback-kv-url enables fallback to KV store for data pruned from postgres DB.
#11989: checkpoint queries (Query.checkpoint, Query.checkpoints, Epoch.checkpoints) can now read pruned checkpoints from the fallback KV store when it is configured.
#12074: Query.transactionBlock(digest) and Query.transactionBlocksByDigests can now read pruned transactions from the fallback KV store when it is configured.
#12184: Query.transactionBlocks(filter: { atCheckpoint }) and Checkpoint.transactionBlocks can now read pruned transactions from the fallback KV store when it is configured.
#12214: Added the affectedAddress filter on transactionBlocks and the AFFECTED relation on Address.transactionBlocks. They list transactions where the address is the sender or a recipient, providing the same functionality as FromOrToAddress filter in the JSON-RPC.
#12272: Query.events(filter: { transactionDigest }) now supports fallback for pruned transactions.
#12300: Query.object(address, version) and dynamic field look-ups at a rootVersion resolve pruned object versions from the archival store when the historical fallback is configured; look-ups that cannot be served return a DATA_PRUNED error instead of resolving as non-existent.
#12553: Query.transactionBlocks(filter: { affectedAddress }) and Address.transactionBlocks with the AFFECTED relation resolve pruned history from the archival store when the historical fallback is configured, and report DATA_PRUNED otherwise.
#12684: added a transactionsByDigests query that returns transactions in pages, one entry per requested digest in input order (null when not found), with forward-only cursor/limit pagination. It includes both old transactions from fallback and fresh transactions just executed via GraphQL. transactionBlocksByDigests is deprecated and will be removed in v1.38.
#12677:
scanLimit as the support for the combination of two or more complex filters (on function, recipient, input object, changed object, affected address, or wrapped or deleted object) will stop after more than three months with the v1.38 release. Users are kindly requested to adapt their dependent logic accordingly within this transition period.
#12540: Adds the corresponding transaction kind types to the TransactionBlockKind and EndOfEpochTransactionKind unions (never emitted until deny-rule governance is enabled).
CLI
#12667: iota-localnet node ports are now fixed instead of random — fullnode 9184 metrics, 9185 admin interface, 9186 p2p, and validator i on the ten ports starting at 9200 + 10 * i (+0 network, +1 p2p, +2 metrics, +3 primary, +4 admin). JSON-RPC (9000), faucet (9123), indexer (9124), GraphQL (9125) and gRPC (50051) are unchanged. A local network now fails to start if another one already holds those ports.
#12659: iota client publish and iota client upgrade now build transactions via the gRPC API; the active environment needs a grpc URL (default environments already include one, older config files must add it).
#12707: iota client ptb now resolves objects and builds transactions via the gRPC API; the active environment needs a grpc URL (default environments already include one, older config files must add it).
#12722: --display now excludes the transaction effects from the response when effects is not part of the selection; previously effects were always returned and printed.
#12779: For iota-localnet start --with-graphql, The GraphQL Prometheus endpoint moves from 0.0.0.0:9184, which the fullnode metrics endpoint holds, to 127.0.0.1:9126.
#12784: iota-tool db-tool set-checkpoint-watermark --highest-verified now lowers the watermark as documented; it previously accepted the value and left it unchanged.
Rust SDK
#12297: A new execution error variant ExecutionCanceledDueToExecutionWorkerCongestion is introduced for when transactions are cancelled in the sequencer due to congestion on execution workers instead of shared objects.
#12682: JSON-RPC errors expose and identify the transaction-not-found error code.