[sui][sui-adapter] Restrict TxContext usage in PTB Move call signatures - #27451
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
Pull request overview
Adds signature-level restrictions to the static Programmable Transaction Block (PTB) verifier to prevent unsafe or forgeable TxContext usage in Move call signatures. The rules are gated by a new protocol feature flag (ptb_tx_context_restrictions, protocol version 132) and are validated on the instantiated (post-generic) signature for each Move call.
Changes:
- Enforce new PTB verifier rules:
TxContextcannot be taken by value,&mut TxContextcan appear at most once (and must be the onlyTxContextparameter), andTxContextcan never appear in return position (by value or reference). - Add
Type::is_tx_context_by_value()to support by-value detection in instantiated signatures. - Introduce and enable the
ptb_tx_context_restrictionsprotocol feature flag (v132) and update transactional tests/snapshots to cover by-value, return-position, and generic-instantiation cases (including dev-inspect).
Reviewed changes
Copilot reviewed 27 out of 27 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| sui-execution/latest/sui-adapter/src/static_programmable_transactions/typing/verify/move_functions.rs | Adds check_tx_context to enforce TxContext parameter/return signature restrictions under a protocol feature flag. |
| sui-execution/latest/sui-adapter/src/static_programmable_transactions/loading/ast.rs | Adds Type::is_tx_context_by_value() helper for direct by-value TxContext detection. |
| crates/sui-protocol-config/src/snapshots/sui_protocol_config__test__version_132.snap | Enables ptb_tx_context_restrictions in v132 snapshot. |
| crates/sui-protocol-config/src/snapshots/sui_protocol_config__test__Testnet_version_132.snap | Enables ptb_tx_context_restrictions in v132 Testnet snapshot. |
| crates/sui-protocol-config/src/snapshots/sui_protocol_config__test__Mainnet_version_132.snap | Enables ptb_tx_context_restrictions in v132 Mainnet snapshot. |
| crates/sui-protocol-config/src/lib.rs | Adds the new feature flag definition and enables it in the protocol v132 config block with version-history documentation. |
| crates/sui-open-rpc/tests/snapshots/generate_spec__openrpc.snap.json | Updates OpenRPC-generated protocol config schema snapshot to include the new feature flag. |
| crates/sui-adapter-transactional-tests/tests/programmable/tx_context_return_invalid.snap | New snapshot covering rejection of TxContext in return position (including dev-inspect and generics). |
| crates/sui-adapter-transactional-tests/tests/programmable/tx_context_return_invalid.move | New transactional test Move module for invalid TxContext returns. |
| crates/sui-adapter-transactional-tests/tests/programmable/tx_context_result_borrow_invalid.snap | Updates snapshot to reflect new return-position restriction behavior under allow_references_in_ptbs. |
| crates/sui-adapter-transactional-tests/tests/programmable/tx_context_result_borrow_invalid.move | Extends test to cover generic reference returns unifying to TxContext. |
| crates/sui-adapter-transactional-tests/tests/programmable/tx_context_multiple_borrows_valid.snap | Updates snapshot; adds case for generic &T unifying to &TxContext alongside a concrete &TxContext. |
| crates/sui-adapter-transactional-tests/tests/programmable/tx_context_multiple_borrows_valid.move | Adds generic immutable-usage case to validate multiple immutable TxContext references remain allowed. |
| crates/sui-adapter-transactional-tests/tests/programmable/tx_context_multiple_borrows_invalid.snap | Updates snapshot to include clearer error source and new generic-injection invalid cases. |
| crates/sui-adapter-transactional-tests/tests/programmable/tx_context_multiple_borrows_invalid.move | Adds generic cases that unify to mutable/immutable TxContext alongside concrete TxContext refs. |
| crates/sui-adapter-transactional-tests/tests/programmable/tx_context_generic_mixed_arity.snap | Updates snapshot to reflect revised arity-failure shape (no longer relying on allow_references_in_ptbs). |
| crates/sui-adapter-transactional-tests/tests/programmable/tx_context_generic_mixed_arity.move | Simplifies generic mixed-arity test while retaining injected-slot arity validation. |
| crates/sui-adapter-transactional-tests/tests/programmable/tx_context_generic_arity.snap | Updates snapshot due to function/test reshaping while preserving “generic unifies to TxContext => injection” behavior. |
| crates/sui-adapter-transactional-tests/tests/programmable/tx_context_generic_arity.move | Simplifies generic arity test modules (no longer returning references) while keeping injection behavior assertions. |
| crates/sui-adapter-transactional-tests/tests/programmable/tx_context_generic_arity_invalid.snap | Snapshot updates to align with clarified ordering/behavior notes (arity vs signature checks). |
| crates/sui-adapter-transactional-tests/tests/programmable/tx_context_generic_arity_invalid.move | Updates commentary to reflect that arity checks happen during translation and return-position rules block standalone reference-return cases. |
| crates/sui-adapter-transactional-tests/tests/programmable/tx_context_by_value_invalid.snap | New snapshot covering rejection of by-value TxContext parameters (notably in dev-inspect). |
| crates/sui-adapter-transactional-tests/tests/programmable/tx_context_by_value_invalid.move | New transactional test ensuring TxContext by-value parameters are rejected (including via generic instantiation). |
| crates/sui-adapter-transactional-tests/tests/dev_inspect/tx_context_result_owned.snap | Updates dev-inspect snapshot to reflect that owned TxContext flows are now rejected by signature rules. |
| crates/sui-adapter-transactional-tests/tests/dev_inspect/tx_context_result_owned.move | Updates dev-inspect test commentary to reflect new signature restrictions even when arbitrary values are allowed. |
| crates/sui-adapter-transactional-tests/tests/dev_inspect/tx_context_result_borrow_invalid.snap | Snapshot line-number/task-count shifts consistent with updated transactional test layout and rule ordering notes. |
| crates/sui-adapter-transactional-tests/tests/dev_inspect/tx_context_result_borrow_invalid.move | Updates commentary to reflect arity-check ordering and linkage to the new TxContext return restriction tests. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
tnowacki
left a comment
There was a problem hiding this comment.
Overall looks fine, but if we can, we might want to just replace these errors with InvalidTxContext usage. In the summary it is stated that these changes preserve previous errors, but that isn't entirely true since the ordering of things has changed.
As such, we might want to consider providing a better error message if it is convenient.
It might also be good to add compiler warnings for these (if we don't already)
4ab962f to
529f556
Compare
529f556 to
dbf3428
Compare
Adds the INVALID_TX_CONTEXT error kind emitted by the adapter's new PTB TxContext signature restrictions (MystenLabs/sui#27451).
) Adds the InvalidTxContext error variant emitted by the adapter's new PTB TxContext signature restrictions (MystenLabs/sui#27451): TxContext can only be used by reference, at most one &mut TxContext parameter, and TxContext can never be returned from a Move call.
83737b1 to
71e7450
Compare
71e7450 to
102aa90
Compare
bcbd150 to
b3086f4
Compare
Adds TxContext signature rules to the static PTB verifier, gated by the new ptb_tx_context_restrictions feature flag (protocol version 132): - In parameters, TxContext may appear at most once as &mut TxContext, or any number of times as &TxContext, and never by value. This makes the mutable-uniqueness rule an up-front signature check (previously only caught downstream by memory safety) and closes the dev-inspect hole where an owned TxContext could be forged from arbitrary pure bytes. - TxContext may never appear in return position, by value or by reference, so it can never become a PTB result. This holds even in dev-inspect and under allow_references_in_ptbs. The rules are checked on the instantiated signature, so generic parameters and returns that unify to TxContext are covered. Existing error kinds are reused (InvalidReferenceArgument, TypeMismatch, InvalidPublicFunctionReturnType), so no effects-visible enums change.
The strip tests from #27134 now run with ptb_tx_context_restrictions enabled: the double-mut rejections move up front to InvalidTxContext (snapshot update), and tx_context_returned_mut_ctx_coexists is deleted -- its ctx-returning call is now rejected outright, which tx_context_return_invalid already covers.
b3086f4 to
bb1b7cb
Compare
Description
The static PTB verifier had no signature-level rules for
TxContext: duplicate mutable usages were only caught downstream by memory safety, dev-inspect could forge an ownedTxContextfrom arbitrary pure bytes, and (under the not-yet-enabledallow_references_in_ptbs) a call returning&mut TxContextbecame a usable PTB result.This adds two rules, checked up-front on the instantiated signature of each Move call and gated by the new
ptb_tx_context_restrictionsfeature flag (protocol version 135):TxContextmay appear at most once as&mut TxContext, or any number of times as&TxContext, and never by value.TxContextmay never appear in return position, by value or by reference, so it can never become a PTB result. This holds in all execution modes, including dev-inspect.All violations report a new
CommandArgumentError::InvalidTxContext(added in last position, emitted only when the feature flag is enabled), with a source message distinguishing the by-value, duplicate-&mut, mixed-reference, and return-position cases. The variant landed upstream in MystenLabs/sui-apis#32 and MystenLabs/sui-rust-sdk#297; this PR bumps the pinnedsui-rust-sdkrev so the proto and sdk-types conversions map it 1:1.Test plan
New transactional tests
tx_context_by_value_invalidandtx_context_return_invalidcover by-value parameters (reachable only via dev-inspect), by-value and by-reference returns, and generic instantiations of both; the existingtx_context_*tests gain generic-injection cases for the parameter rules, andtx_context_multiple_borrows_invaliddistinguishes the duplicate-&muterror (reported at the second occurrence) from the mixed&mut/&error (reported at the&mut), including when both apply. Note that chained shapes likemut_id(); use(Result(0))still fail withArityMismatchbecause arity is checked during translation, before the verify passes; the snapshots document this ordering.Release notes
ptb_tx_context_restrictions(protocol version 135).TxContextin a PTB Move call signature may appear at most once as&mut TxContextor any number of times as&TxContext, never by value, and never in return position. Transactions calling functions that violate these rules now fail up front with the newInvalidTxContextcommand argument error (previously they failed with borrow-checking, arity, or serialization errors, or in dev-inspect could partially succeed).