Skip to content

Make MoveStructLayout field accessors fail-closed on unknown tags - #425

Draft
sausagee wants to merge 1 commit into
m1from
cursor/fail-closed-layout-fields-dedf
Draft

sausagee wants to merge 1 commit into
m1from
cursor/fail-closed-layout-fields-dedf

Conversation

@sausagee

@sausagee sausagee commented Sep 6, 2026

Copy link
Copy Markdown

Description

Movement #411 made BCS serialize reject out-of-range RuntimeVariants tags via try_get_variant_field_layouts. The layout accessors themselves still returned an empty slice for a bad or missing tag (fields() / into_fields()), so other walkers could treat that tag as a unit variant.

This is a clean-room completion of the fail-closed layout API (upstream intent only: aptos-labs#20304 fields() -> Option). No aptos-labs code was cherry-picked or copied.

MoveStructLayout::fields and into_fields now return Option:

  • Runtime requires variant == None
  • RuntimeVariants requires Some(idx) in range
  • decorated layouts are not available through the borrowed fields() accessor

Invariant: serialization must not emit an unknown variant tag. An empty field list is a valid unit variant (Some(&[])). Callers must handle None and must not fall back to empty fields.

Call sites updated in move-vm-types: BCS serialize, as_move_value, delayed-field string/DerivedString layout walks, and the value proptest strategy. Feature flags 81/95 are not enabled.

How Has This Been Tested?

Verified locally:

cargo test -p move-core-types -p move-vm-types
# move-core-types: 51 passed
# move-vm-types: 71 passed

New coverage:

  • fields_returns_some_for_consistent_runtime_queries / fields_returns_none_for_unknown_or_inconsistent_tags / into_fields_is_fail_closed_like_fields
  • existing enum_out_of_range_variant_tag_is_not_serializable (Reject out-of-range enum variant tags during value serialization #411)
  • as_move_value_rejects_out_of_range_unit_tag
  • delayed-field tests that enum layouts are not mistaken for String / DerivedStringSnapshot

Key Areas to Review

  • MoveStructLayout::fields / into_fields contract: None vs empty unit variant
  • Serialize path: fields(None) error instead of empty-tuple serialize
  • as_move_value: panics on unknown tag rather than emitting a unit variant
  • Delayed-field is_string_layout / is_derived_string_struct_layout handle None

Type of Change

  • New feature
  • Bug fix
  • Breaking change
  • Performance improvement
  • Refactoring
  • Dependency update
  • Documentation update
  • Tests

Which Components or Systems Does This Change Impact?

  • Validator Node
  • Full Node (API, Indexer, etc.)
  • Move/Aptos Virtual Machine
  • Aptos Framework
  • Aptos CLI/SDK
  • Developer Infrastructure
  • Move Compiler
  • Other (specify)

Checklist

  • I have read and followed the CONTRIBUTING doc
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I identified and added all stakeholders and component owners affected by this change as reviewers
  • I tested both happy and unhappy path of the functionality
  • I have made corresponding changes to the documentation
Open in Web Open in Cursor 

View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

fields() and into_fields() now return Option so an out-of-range or
inconsistent RuntimeVariants query cannot collapse to an empty unit
variant. Callers in move-vm-types treat None as an error. Completes
the #411 serialize-path fix for delayed-field walks and as_move_value.

Co-authored-by: Young Yang Liauw <sausagee@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants