Repository navigation
[2.x] Cross account links with an explicit data segment - #1231
Conversation
This stack of pull requests is managed by Graphite. Learn more about stacking. |
|
34d4479 to
a16f8dc
Compare
trevor-cortex
left a comment
There was a problem hiding this comment.
Summary
Moves account-link crossing in path expressions behind an explicit .data segment, matching spec#202. A linked public key now behaves like an account node: .data enters its decoded data (whole data, struct or not), and any other segment is reserved and throws. The five path walkers are updated in lockstep:
resolveTypePath(visitors-core):.dataon a linked public key resolves to[...accountPath, account.data]; since every hop now consumes a segment, thefollowedAccountsself-link guard is gone and the self-link test flips from "throws" to "follows one hop per.data".getDecodedNodeAtPath(dynamic-codecs): same shape; the crossing moved out ofresolveContainerinto the main loop, somint.datareturns the account's decoded data node.getValueAtPath(dynamic-address-resolution): crossing nowcontinues after consuming the.datasegment and re-seedstypePathwith the account data, which is what makespointer.data.data.mintAuthoritywork.createPathResolver(visitors): the public-key hop is pulled out of the defined-typewhileinto its own block gated on.data;followedAccountsdropped for the same reason.- validators: the friendlier "must not cross an account link" message is now only emitted when the failing segment is
data;mint.decimalsfalls through to the generic unresolvable-path message.
I traced the loop-termination argument in all four walkers and it holds: the only way to re-enter an account is via a .data segment, and paths are finite. The non-struct account data case (counter.data → u64) and the pointer-to-pointer case are both covered by tests.
Things to watch
- Changeset. I don't see a
.changeset/*.mdin the file list, and this is a user-facing grammar change across@codama/visitors-core,@codama/visitors,@codama/validators,@codama/dynamic-codecsand@codama/dynamic-address-resolution. CONTRIBUTING asks for one per concern — is it coming in this PR, or is the stack carrying a single one elsewhere? - Spec pin. The PR references spec#202. If that change is doc-only in the spec, nothing to do; if it moved the
@codama/specversion, does the pin inpackages/spec-generators/package.jsonneed to follow (even with no generated diff) so the pin stays aligned with the grammar this branch implements? - Reserved segments on the display side.
getDataMemberPathindynamic-instructions/src/display/fields.tscallsgetDecodedNodeAtPathwithresolveAccountLink: () => undefinedand stops at the firstundefined. With this PR, a reserved segment likemint.lamportsnow throws there instead of returningundefined(previously any field segment crossed the link). That's fine today since validators reject those paths, but whenlamports& co. land that function will need to learn the reserved set. Just flagging so it isn't a surprise later.
Notes for other reviewers
- The diff GitHub serves for
dynamic-instructions/src/display/{accounts,dictionary,fields}.tsandtest/display/account-data.test.tsincludes the parent PR in the stack; only the.data-grammar lines (comments, test paths) belong to this PR. DecodedAccountNode.datais required indecoded.ts, so the newcurrent = account.datainpath.tsis safe without the!current.dataguard thatresolveContainerapplies to instructions/events/variants.- Small asymmetry worth knowing about, not a problem:
accountDataValueNode('mint')(no path) yields theDecodedAccountNode, whereasmint.datayields itsdatatype node.getValueNodeininjected-values.tsunwraps both, so consumers see the same thing.
a16f8dc to
0c5bdd2
Compare

This PR makes paths cross account links with an explicit
.datasegment, following the matching spec change (codama-idl/spec#202). A linked public key now behaves like an account:.dataenters its decoded data, and other segments are reserved for future attributes of the account, such as its lamports.visitors-core:resolveTypePath({ followAccountLinks })crosses a linked public key on a.datasegment, resolving to the account's data type. Each hop now consumes a segment, so the self-link guard is no longer needed.dynamic-codecs:getDecodedNodeAtPathcallsresolveAccountLinkon a.datasegment, andmint.datareturns the account's decoded data.dynamic-address-resolution: data paths fetch the linked account on a.datasegment, including from data that is itself a linked address, e.g.pointer.data.data.mintAuthority.visitors: renames follow account links on.datasegments only.validators: field discriminators reportmust not cross an account linkfor.datasegments, and other segments applied to a linked public key as unresolvable paths.getDecodedNodeAtPath, and docs and tests use the new grammar.