fix(xrpl): use deep amount comparison in handleDeliverMax (#3313)#3338
fix(xrpl): use deep amount comparison in handleDeliverMax (#3313)#3338satyakwok wants to merge 3 commits into
Conversation
`handleDeliverMax` used `tx.Amount !== tx.DeliverMax` (reference
equality). For IOU and MPT amounts (objects like
`{currency, issuer, value}`), two distinct objects with identical
fields always compare not-equal, so every IOU payment that set both
`Amount` and `DeliverMax` as separate object literals threw a spurious
`PaymentTransaction: Amount and DeliverMax fields must be identical
when both are provided` validation error.
Reuse the existing `amountsEqual` helper from `client/partialPayment.ts`
(handles XRP / IOU / MPT and uses `BigNumber` for value comparison so
`"1"` and `"1.0"` are treated as equal). Exported it for cross-module
use; same callable, no behaviour change inside `partialPayment.ts`.
Adds two regression tests in `test/client/autofill.test.ts`:
- identical IOU `Amount` and `DeliverMax` as separate objects → must
autofill cleanly (this is the bug; fails on `main`).
- differing IOU `value` with same currency/issuer → must still throw
(companion check that the fix didn't loosen validation).
All 23 autofill unit tests pass.
|
ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
✅ Files skipped from review due to trivial changes (1)
WalkthroughExports a semantic equality utility ChangesDeliverMax Validation
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
packages/xrpl/test/client/autofill.test.ts (1)
108-131: ⚡ Quick winAdd MPT regression coverage for the same bug path.
Nice IOU coverage. Since issue scope also includes MPT amount objects, add one matching/non-matching MPT pair to guard
handleDeliverMaxagainst future regressions there too.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/xrpl/test/client/autofill.test.ts` around lines 108 - 131, Add two new test cases mirroring the existing IOU tests but using MPT-format amount objects to cover the MPT code path in handleDeliverMax: one where paymentTx.Amount and paymentTx.DeliverMax are distinct MPT amount objects with identical fields (assert autofill returns Amount and drops DeliverMax), and a companion where the MPT objects differ in value (assert autofill rejects with ValidationError). Place them alongside the existing "Validate Payment transaction API v2" tests and reference the same testContext.client.autofill call and the handleDeliverMax behavior so future changes to handleDeliverMax/MPT handling are guarded.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/xrpl/test/client/autofill.test.ts`:
- Around line 109-112: The comment describing the regression is incorrect about
reference-equality behavior; update the wording around the `tx.Amount !==
tx.DeliverMax` mention (in the autofill test) to state that distinct
IssuedCurrencyAmount object literals evaluate true with `!==` (i.e., different
references cause the comparison to be true), and clarify that this caused IOU
payments to be rejected when both fields were set even though their contents
matched; locate the comment that includes `tx.Amount !== tx.DeliverMax` and
rewrite it to correctly describe the inverted result.
---
Nitpick comments:
In `@packages/xrpl/test/client/autofill.test.ts`:
- Around line 108-131: Add two new test cases mirroring the existing IOU tests
but using MPT-format amount objects to cover the MPT code path in
handleDeliverMax: one where paymentTx.Amount and paymentTx.DeliverMax are
distinct MPT amount objects with identical fields (assert autofill returns
Amount and drops DeliverMax), and a companion where the MPT objects differ in
value (assert autofill rejects with ValidationError). Place them alongside the
existing "Validate Payment transaction API v2" tests and reference the same
testContext.client.autofill call and the handleDeliverMax behavior so future
changes to handleDeliverMax/MPT handling are guarded.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 564d4571-aedb-4c46-9c8c-4aa8a759a10c
📒 Files selected for processing (3)
packages/xrpl/src/client/partialPayment.tspackages/xrpl/src/sugar/autofill.tspackages/xrpl/test/client/autofill.test.ts
Reorganises Upstream contributions into three subsections: - Consensus & execution layer (Rust) — adds bluealloy/revm#3671 (AlloyDB EIP-161 state-clear fix via eth_getProof codeHash check) alongside the existing reth / cometbft / tendermint-rs / alloy patches. - XRPL SDKs (Rust + TypeScript) — 7 PRs at XRPLF/xrpl-rust covering Wallet Debug-leak redaction, OsRng for seed entropy, Ed25519 verify_strict, secp256k1 range fix, exact-prefix strip, GHA SHA pinning, integration-test coverage; plus XRPLF/xrpl.js#3338 (handleDeliverMax deep amount equality). - TUI / CLI tooling & registries — unchanged set. Adds a one-line lead-in noting the verification discipline: regression test per patch, host commit-message conventions, audit-report findings hand-verified rather than rubber-stamped.
CodeRabbit caught it: the previous comment said `!==` returned `false` for distinct object literals; it actually returns `true` (reference inequality), which is precisely why the validation throw fired. No code change — comment-only correction.
|
Thanks @coderabbitai — both fair. 1. Comment wording ( 2. MPT regression coverage — held off intentionally. |
|
Tip For best results, initiate chat on the files or code changes.
✏️ Learnings added
|
Closes #3313.
Summary
handleDeliverMaxinsrc/sugar/autofill.tscompared the two fields with!==(reference equality). For IOU and MPT amounts — objects like{currency, issuer, value}— two distinct object literals with identical fields always compare not-equal, so every IOU payment that set both `Amount` and `DeliverMax` as separate object literals threw a spurious validation error:This silently broke any IOU payment flow that built the two fields independently (e.g. one constructed by the caller, the other autofilled from a higher-level helper).
Fix
Reuse the existing
amountsEqualhelper fromsrc/client/partialPayment.ts. It already handles all three amount shapes correctly:===currency+issuer+BigNumber(value)(so"1.0"and"1"compare equal)mpt_issuance_id+BigNumber(value)Only change to
partialPayment.tsis makingamountsEqualexported (was previously file-local). Same implementation, just visible to other modules.Tests
Two new tests in
packages/xrpl/test/client/autofill.test.ts:AmountandDeliverMaxas separate object literals → must autofill cleanly. Fails onmain(throws the spuriousValidationError), passes after.valuewith samecurrency/issuer→ must still throw. Pins that the fix didn't loosen validation.The pre-existing tests for the
=== stringpath and the same-reference IOU case (paymentTx.DeliverMax = paymentTx.Amount) still pass.Smoke gate
npm run buildfrom repo root — all 6 workspaces build clean.npx jest --config=jest.config.unit.js --testPathPatterns autofill— 23 passed, 0 failed.