Protocol
Sui Protocol Version in this release: 140
#28271: Adds bulk vector operations: replace_range, keep_range, copy_range, remove_range, and truncate
#27829: Adds bulk vector operations: replace_range, keep_range, copy_range, remove_range, and truncate
#28144: Adds the shuffle_consensus_commit_blocks feature flag (devnet only in version 140). When enabled, consensus orders the blocks within each round of a commit by a hash seeded from the leader block digest instead of by authority index.
#28291: References returned from Move functions can now be used in PTBs.
#28265: Disables the ID leak verifier
#28290: Protocol version 140 enables check_object_funds_withdraw_in_execution on mainnet. Object funds withdrawals that exceed the available balance now fail with a Move abort (EObjectFundsInsufficient in sui::funds_accumulator) instead of the post-execution InsufficientFundsForWithdraw error, and the failure is decided during execution rather than by re-execution.
#28410: Protocol version 140 enables disable_effects_tx_dependencies on mainnet. Transaction effects no longer report transaction dependencies; the effects encoding retains an empty dependency vector, and object versions and per-object previous-transaction metadata are unchanged.
Nodes (Validators and Full nodes)
#28301: tidehunter nodes now keep up to 2 GiB of hot objects-index blobs in memory once they age out of the mmap window; set TH_INDEX_BLOB_CACHE_BYTES=0 to disable or another value to resize.
#28413: Fullnodes no longer run ML-DSA-65 signature verification on networks where mldsa65_auth is off; such transactions are rejected at verification instead of after it.
#28313: validators now cap the user transaction bytes they propose to consensus, defaulting to two full blocks per second. Set consensus-transaction-pool.max-user-bytes-per-second to change it or consensus-transaction-pool.rate-limit-user-bytes: false to turn it off.
gRPC
#28314: When SimulateTransaction gas selection can't find enough SUI to cover the gas budget, the INVALID_ARGUMENT error carries a google.rpc.ErrorInfo with reason INSUFFICIENT_GAS_BALANCE (domain sui.io) and metadata owner, requiredBudget, coinBalance and addressBalance, so clients can read the required budget without parsing the message. If the server estimated the budget and the transaction fails in that estimation, the error instead reports the execution failure ("Transaction fails in simulation: …") with an ErrorInfo of reason TRANSACTION_EXECUTION_FAILED (metadata kind, command) and the ExecutionError detail.
#28345: SubscribeTransactions and SubscribeCheckpoints now fill effects object types, clever errors and event json when the read mask requests them, matching GetTransaction. ListTransactions and ListEvents requests below the node's retention now return OUT_OF_RANGE instead of INTERNAL.
#28308: kv-rpc's ListEvents, ListTransactions and ListCheckpoints no longer start and cancel a checkpoint lookup per progress watermark, the source of the too_many_internal_resets failures, and they are faster on large and sparse requests. While a scan finds no items, it sends a progress-only frame after every 256 buckets of scan work, where reopening a filter's scan past a gap counts as 50. Operators: the read-stage defaults change (table above), and the stage settings are renamed: chunk-size is max-seeks-per-read and min-split-size is min-seeks-per-split-read, with no alias, so old keys are ignored. On tx-seq-digest and the new tx-cp-resolve stage, seeks are buckets of 1,000 transactions rather than keys, and the new max-keys-per-read caps keys per read. New settings: ledger-history.watermark-beacon-buckets and max-keys-per-read. New metrics: kv_rpc_bigtable_reads_started_total and kv_rpc_bigtable_reads_finished_total. On full nodes and kv-rpc, ListCheckpoints, ListTransactions and ListEvents return OUT_OF_RANGE for a starting cursor past the server's indexed tip, instead of an empty page whose cursor is behind the one sent; the request can be retried once the server catches up.
#28394: GetEpoch now lists mldsa65_auth among protocol feature flags.
#28391: ListTransactions and ListEvents cursors can be sent back in either ordering without skipping items. A page that resumes at its window's edge ends with the window's end reason and claims the window's edge checkpoint. These requests return OutOfRange instead of an empty or clamped result: a descending after cursor past the latest indexed checkpoint; and a descending ListTransactions, ListEvents, or ListCheckpoints request whose end_checkpoint is above the latest indexed checkpoint + 1, or whose start_checkpoint is above the latest indexed checkpoint with no end_checkpoint. On a pruning fullnode, every request that needs data below the pruning floor returns OutOfRange. A descending request with no start_checkpoint streams everything down to the floor, then a watermark at the floor, before the error.
GraphQL
#28249: Nullable, fallible multi-gets now return successful entries alongside indexed errors for failed keys instead of failing the entire batch. No schema changes or client migration are required.
#28362: Fix NameRecord.contents.json decoding and return only the NameRecord value in contents.bcs, matching contents.type.
#28343: Objects and packages resolved inside subscription, executeTransaction and simulateTransaction results no longer resolve to an unrelated object when the requested ID was not written by that transaction or checkpoint. Live subscription events now report the correct transactionModule.package.address.
#28355: Subscriptions resumed with after or afterCheckpoint no longer skip a checkpoint at the backfill-to-live handoff, and no longer drop the remaining matches in the resume cursor's checkpoint when the serving replica lags. A backfill waiting on a ledger that stops advancing now disconnects with the usual reconnect error after 3 minutes.
#28353: checkpoints with an after cursor at or below filter.afterCheckpoint, or a before cursor at or above filter.beforeCheckpoint, now returns the checkpoints within the bound instead of an empty page.
#28383: Transaction and event connections served by the List APIs no longer report hasNextPage: true (or hasPreviousPage: true) when a page exactly fits the remaining data, and paging backwards from a last + after page no longer skips the item at the after cursor.
#28394: protocolConfigs.featureFlags and featureFlag(key: "mldsa65_auth") now report the flag.
#28391: Transaction and event connections served by the List APIs derive hasNextPage/hasPreviousPage from the end reason. A page that resumes at its window's edge, or at the latest indexed checkpoint from a cursor other than that checkpoint's own boundary, reports no further page where it reported one before. A last/after page whose after cursor sits exactly at the latest indexed checkpoint reports hasPreviousPage: true where it reported false before.
#28367: Filtered transactions and events subscriptions take a new progress: Boolean = false argument. When enabled, the subscription interleaves progress payloads whose node is null and that carry only a cursor, letting a client on a sparse filter advance its resume point without a match; a null node with no errors is progress, while a null node with errors is a match that failed to resolve. The subscription fields now return TransactionSubscriptionEdge / EventSubscriptionEdge (nullable node) rather than the paginated TransactionEdge / EventEdge; existing { cursor node { ... } } selections stay valid. Clients that leave progress off see no behavior change; subscribers that opt in must handle node: null.
Indexing Framework
#28369: When --streaming-url also serves LedgerService (any Sui fullnode does), checkpoints between the indexer and a newly connected stream are fetched from it with GetCheckpoint, at the configured ingest-concurrency, instead of from the ingestion source. Endpoints that don't serve LedgerService keep the previous behavior. IngestionService::new is now async, and IngestionService::with_clients and Indexer::with_ingestion_clients take an optional gap-fill client (None keeps the previous behavior).