fix: clarity tuple field validation - #7461
Conversation
There was a problem hiding this comment.
Pull request overview
This PR fixes an epoch-gated (Epoch 4.1+) type-soundness issue in Clarity typed-tuple deserialization, where consensus buffer deserialization could accept duplicate tuple keys and produce tuples that violate their declared type. The change introduces epoch-aware deserialization entry points and threads a strict tuple-field enforcement flag so from-consensus-buff? and DB reads reject malformed typed tuples starting in Epoch 4.1 while preserving legacy behavior in earlier epochs.
Changes:
- Add Epoch 4.1 gate (
enforces_exact_typed_tuple_field_set) and plumb it through epoch-aware deserialization APIs. - Enforce strict typed-tuple field rules (no duplicates; exact declared field set after sanitization) during typed tuple construction/deserialization when the epoch gate is active.
- Add targeted tests covering
from-consensus-buff?, typed tuple deserialization behavior across epochs, and the DB read path gating; add a changelog fragment.
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| stackslib/src/chainstate/tests/runtime_analysis_tests.rs | Updates test commentary to reference the new epoch-aware exact-deserialization entry point. |
| stacks-common/src/types/mod.rs | Introduces an Epoch 4.1+ helper to gate strict typed-tuple field-set enforcement. |
| clarity/src/vm/tests/conversions.rs | Adds an epoch-gated regression test ensuring from-consensus-buff? rejects duplicate typed-tuple fields at Epoch 4.1+. |
| clarity/src/vm/functions/conversions.rs | Switches from-consensus-buff? to epoch-aware exact deserialization so enforcement is driven by execution epoch. |
| clarity/src/vm/database/key_value_wrapper.rs | Switches DB value deserialization to an epoch-aware entry point. |
| clarity/src/vm/database/clarity_db.rs | Adds a regression test ensuring DB reads reject malformed typed tuples at Epoch 4.1+. |
| clarity-types/src/types/serialization.rs | Threads strict_tuple_fields through the deserializer and adds epoch-aware deserialization APIs (bytes/hex, exact + non-exact). |
| clarity-types/src/types/mod.rs | Extends TupleData::from_data_typed with a strict option to reject duplicates and enforce exact field sets. |
| clarity-types/src/tests/types/serialization.rs | Adds comprehensive epoch-gated tests for duplicate/missing/extra tuple field handling (including nesting + trailing bytes). |
| clarity-types/src/tests/types/mod.rs | Updates and adds unit tests for strict TupleData::from_data_typed behavior. |
| changelog.d/typed-tuple-deserialization.fixed | Documents the Epoch 4.1 behavior change for from-consensus-buff?. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
brice-stacks
left a comment
There was a problem hiding this comment.
lgtm! just one performance nit.
Description
Fixes a bug in
from-consensus-buff?that currently makes it possible to create a clarity tuple with duplicate keys of the same type. When such a buffer is deserialized, it's converted into a tuple that violates its own declared type.The fix is gated behind 4.1. Now a duplicate will cause
from-consensus-buff?to returnNone.TupleData::from_data_typednow derives the actual type viafrom_data(which rejects duplicates) and requires the value to contain exactly the declared field set before caching the expected signature.strict_tuple_fieldsflag, which is controlled based on the epoch.from-consensus-buff?and the DB read path (RollbackWrapper::get_value) now both use the epoch-aware entry.Applicable issues
Additional info (benefits, drawbacks, caveats)
Checklist
docs/property-testing.md)changelog.d/README.md)rpc/openapi.yamlfor RPC endpoints,event-dispatcher.mdfor new events)clarity-benchmarkingrepo