-
Notifications
You must be signed in to change notification settings - Fork 567
Fix serialization of Issue type when asset is MPT #3090
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 4 commits
5506fe2
4672d43
479ad37
ed7b7b8
e7286ef
516c320
9fb03f8
903daa8
1169182
30039bd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -151,13 +151,7 @@ class STObject extends SerializedType { | |
| ? STArray.from(xAddressDecoded[field.name], definitions) | ||
| : field.type.name === 'UInt64' | ||
| ? UInt64.from(xAddressDecoded[field.name], field.name) | ||
| : field.associatedType?.from | ||
| ? field.associatedType.from(xAddressDecoded[field.name]) | ||
| : (() => { | ||
| throw new Error( | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This error is useful when rippled has a new internal type but xrpl.js is missing an implementation for such a new type.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We already throw an error from base class SerializedType if the subclass does not overrides this method. |
||
| `Type ${field.type.name} for field ${field.name} is missing associatedType.from`, | ||
| ) | ||
| })() | ||
| : field.associatedType.from(xAddressDecoded[field.name]) | ||
|
|
||
| if (associatedValue == undefined) { | ||
| throw new TypeError( | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
Detecting MPT by parser.size() assumes sized sub‑parsers
This relies on the caller providing a parser whose size equals the field width (44 for MPT). If any call site passes a shared parser (with remaining >44), MPT parsing will silently fall back to the XRP/IOU path and misread bytes.
If all call sites now pass a sized parser, great—otherwise consider keeping an optional width hint or plumbing field width to avoid ambiguity.
To confirm, please check call sites of Issue.fromParser:
Expected: invocation with a subparser (or previously: width hint removed everywhere).
🏁 Script executed:
Length of output: 2294
🏁 Script executed:
Length of output: 25347
🏁 Script executed:
Length of output: 14143
Don't detect MPT with parser.size() — it misparses MPT when the parser is shared
Issue.fromParser uses
parser.size() === MPT_WIDTHto detect MPT, but BinaryParser.readFieldValue calls type.fromParser(this, ...) with the shared parser (not a sized subparser), so an MPT field inside a larger STObject will be parsed as an IOU (consume 40 bytes, leave 4 bytes) — tests construct sized parsers and hide this.Locations: packages/ripple-binary-codec/src/types/issue.ts (fromParser), packages/ripple-binary-codec/src/serdes/binary-parser.ts (readFieldValue); tests: packages/ripple-binary-codec/test/issue.test.ts
🤖 Prompt for AI Agents
✅ Addressed in commits 710849a to 1169182
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fromParsergets called based on theassociatedTypeof the field. In this case it'sIssue. The Issue sub-classesfromParseronly gets called once we identify theassociatedTypeis Issue. So the binary parser should exactly point to either MPT/XRP/IOU asset and these checks are in-place while parsing.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
Length of output: 1889
🏁 Script executed:
Length of output: 7117
🏁 Script executed:
Length of output: 293
🏁 Script executed:
Length of output: 10428
@Patel-Raj11, thank you for the explanation! I understand your reasoning about the parser pointing exactly to the field data. However, after examining the
BinaryParserimplementation, I found a discrepancy that concerns me.Looking at the code flow:
type.fromParser(this, sizeHint)- passing the full parser instance, not a sized subparserBinaryParser.read(n)consumes bytes from the front and advances position, butparser.size()returns the total remaining bytesThe current logic
parser.size() === MPT_WIDTHwould only work correctly if:For an Issue field in the middle of a transaction,
parser.size()would return the total remaining bytes (potentially hundreds), not just the 44 bytes for the current field.This could cause MPT fields to be incorrectly parsed as IOU fields (consuming 40 bytes instead of 44), leaving 4 bytes unconsumed and potentially corrupting subsequent field parsing.
Could you help me understand how this size detection works correctly in practice? Are there integration tests that serialize/deserialize transactions with MPT Issue fields in the middle of the transaction data that I could look at to verify the behavior?
✏ Learnings added
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Patel-Raj11 I agree with the rabbit's suggestion. Since the
Issuetype is shared by IOU/XRP/MPT types, how can you determine the appropriate size of the parser?If we are provided with a sufficiently long buffer of bytes (say a serialized transaction), the size of the parser will mislead us, because we can read 44 bytes (for an MPT), 40 bytes ( for an IOU) or 20 bytes (for XRP representation).
This suggestion from the AI is more robust:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense, addressed here 1169182