Skip to content
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

introduce DeliverMax alias in Payment transactions #2684

Closed
wants to merge 10 commits into from

Conversation

ckeshava
Copy link
Collaborator

High Level Overview of Change

This is a sister PR of the following xrpl-py work: XRPLF/xrpl-py#684

Context of Change

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Refactor (non-breaking change that only restructures code)
  • Tests (You added tests for code that already exists, or your new feature included in this PR)
  • Documentation Updates
  • Release

Did you update HISTORY.md?

  • Yes
  • No, this change does not impact library users

Test Plan

Unit tests have been added, but I am unable to add integration tests. I couldn't find any examples of specifying a JSON representation (not Payment, AccountSet or any SubmittableTransaction type) as an input to the submitTransaction function. This is necessary because DeliverMax is an alias at the RPC level, it is not recognised at the protocol level. Let me know if I'm missing something.

…rithm by default.

This causes breakge in downstrwam de[endencies such as Account class. Account.familySeed makes use of generateSeed
packages/xrpl/src/models/transactions/payment.ts Outdated Show resolved Hide resolved
packages/xrpl/src/models/transactions/payment.ts Outdated Show resolved Hide resolved
packages/xrpl/src/models/transactions/payment.ts Outdated Show resolved Hide resolved
Comment on lines 379 to 394
it(`verifies deliver_max alias in PaymentTransactions`, function () {
assert.doesNotThrow(() => validatePayment(paytxn1))
assert.doesNotThrow(() => validate(paytxn1))

assert.doesNotThrow(() => validatePayment(paytxn2))
assert.doesNotThrow(() => validate(paytxn2))

assert.doesNotThrow(() => validatePayment(paytxn3))
assert.doesNotThrow(() => validate(paytxn3))

assert.throws(() => validatePayment(paytxn4))
assert.throws(() => validate(paytxn4))

assert.throws(() => validatePayment(paytxn5))
assert.throws(() => validate(paytxn5))
})
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Each different test should be separated into its own it() function.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, I've addressed this comment in a8036ae

@ckeshava ckeshava requested a review from khancode April 29, 2024 18:29
@@ -166,6 +166,24 @@ export interface PaymentMetadata extends TransactionMetadataBase {
export function validatePayment(tx: Record<string, unknown>): void {
validateBaseTransaction(tx)

if (tx.Amount == null) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This feels like it's changing the remit of the validate functions, which should only be throwing errors and not mutating the objects.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I agree. But I couldn't find another appropriate place to sneak in this mutation.
Perhaps I could include this change inside ripple-binary-codec. But since this is an RPC-related change and has nothing to do with protocol level serialization/de-serialization, it doesn't feel appropriate.

I'm also questioning the necessity of this change. rippled performs validation checks on the Amount and DeliverMax fields in the Payment transactions. So even if the client libraries send incorrect input, the user should get a tem... error code from rippled.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think having such a check in autofill would be nice.

Yes you get a tem code, but it's better to fail fast. Otherwise, why even bother to have the validate functions in the first place?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe you are referring to this autofill :

public async autofill<T extends SubmittableTransaction>(

It accepts only SubmittableTransaction's. JSON-string representation of certain Payment transactions, which include DeliverMax field are not serialization friendly with encode and decode JS functions.

Please refer to this branch, it has two unit tests demonstrating this issue: d262da9

If we want to insert this change in autofill, we will need to remove Type restrictions of SubmittableTransaction and perform cosmetic changes prior to the call to decode here:

Copy link
Collaborator

@mvadari mvadari May 2, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you're using TS, it'll get caught anyways, so that's not who we're worried about. This is just for the JS users.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's what I'm referring to on TS vs JS. TS will error if you have a DeliverMax field, JS will let you continue because it has no type checking. I think an as any is fine for this check.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A lot of folks call autofill/sign/submit on their own, so updating submit wouldn't do anything.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I have implemented this idea here: https://github.com/ckeshava/xrpl.js/pull/new/autofill-temp

But we are losing transaction model checks, as shown by the last unit test --

it('Validate Payment transaction v2 API: Payment Transaction: both DeliverMax and Amount fields are absent', async function () {

Is this what you had in mind?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What I'm suggesting is that only lines 672-696 use an as any version of the object. The rest of the checks can use the normal transaction.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, here is another PR: #2689

Comment on lines 38 to 152
InvoiceID:
'6F1DFD1D0FE8A32E40E1F2C05CF1C15545BAB56B617F9C6C2D63A6B704BEF59B',
Paths: [
[{ currency: 'BTC', issuer: 'r9vbV3EHvXWjSkeQ6CAcYVPGeq7TuiXY2X' }],
],
SendMax: '100000000',
} as any

// JSON contains only DeliverMax field
paytxn2 = {
TransactionType: 'Payment',
Account: 'rUn84CUYbNjRoTQ6mSW7BVJPSVJNLb1QLo',
DeliverMax: '1234',
Destination: 'rfkE1aSy9G8Upk4JssnwBxhEv5p4mn2KTy',
DestinationTag: 1,
Fee: '12',
Flags: 2147483648,
LastLedgerSequence: 65953073,
Sequence: 65923914,
SigningPubKey:
'02F9E33F16DF9507705EC954E3F94EB5F10D1FC4A354606DBE6297DBB1096FE654',
TxnSignature:
'3045022100E3FAE0EDEC3D6A8FF6D81BC9CF8288A61B7EEDE8071E90FF9314CB4621058D10022043545CF631706D700CEE65A1DB83EFDD185413808292D9D90F14D87D3DC2D8CB',
InvoiceID:
'6F1DFD1D0FE8A32E40E1F2C05CF1C15545BAB56B617F9C6C2D63A6B704BEF59B',
Paths: [
[{ currency: 'BTC', issuer: 'r9vbV3EHvXWjSkeQ6CAcYVPGeq7TuiXY2X' }],
],
SendMax: '100000000',
} as any

// JSON contains identical DeliverMax and Amount fields
paytxn3 = {
TransactionType: 'Payment',
Account: 'rUn84CUYbNjRoTQ6mSW7BVJPSVJNLb1QLo',
DeliverMax: '1234',
Amount: '1234',
Destination: 'rfkE1aSy9G8Upk4JssnwBxhEv5p4mn2KTy',
DestinationTag: 1,
Fee: '12',
Flags: 2147483648,
LastLedgerSequence: 65953073,
Sequence: 65923914,
SigningPubKey:
'02F9E33F16DF9507705EC954E3F94EB5F10D1FC4A354606DBE6297DBB1096FE654',
TxnSignature:
'3045022100E3FAE0EDEC3D6A8FF6D81BC9CF8288A61B7EEDE8071E90FF9314CB4621058D10022043545CF631706D700CEE65A1DB83EFDD185413808292D9D90F14D87D3DC2D8CB',
InvoiceID:
'6F1DFD1D0FE8A32E40E1F2C05CF1C15545BAB56B617F9C6C2D63A6B704BEF59B',
Paths: [
[{ currency: 'BTC', issuer: 'r9vbV3EHvXWjSkeQ6CAcYVPGeq7TuiXY2X' }],
],
SendMax: '100000000',
} as any

// JSON contains different DeliverMax and Amount fields
paytxn4 = {
TransactionType: 'Payment',
Account: 'rUn84CUYbNjRoTQ6mSW7BVJPSVJNLb1QLo',
DeliverMax: '1234',
Amount: '321',
Destination: 'rfkE1aSy9G8Upk4JssnwBxhEv5p4mn2KTy',
DestinationTag: 1,
Fee: '12',
Flags: 2147483648,
LastLedgerSequence: 65953073,
Sequence: 65923914,
SigningPubKey:
'02F9E33F16DF9507705EC954E3F94EB5F10D1FC4A354606DBE6297DBB1096FE654',
TxnSignature:
'3045022100E3FAE0EDEC3D6A8FF6D81BC9CF8288A61B7EEDE8071E90FF9314CB4621058D10022043545CF631706D700CEE65A1DB83EFDD185413808292D9D90F14D87D3DC2D8CB',
InvoiceID:
'6F1DFD1D0FE8A32E40E1F2C05CF1C15545BAB56B617F9C6C2D63A6B704BEF59B',
Paths: [
[{ currency: 'BTC', issuer: 'r9vbV3EHvXWjSkeQ6CAcYVPGeq7TuiXY2X' }],
],
SendMax: '100000000',
} as any

// JSON does not contain either DeliverMax or Amount field
paytxn5 = {
TransactionType: 'Payment',
Account: 'rUn84CUYbNjRoTQ6mSW7BVJPSVJNLb1QLo',
Destination: 'rfkE1aSy9G8Upk4JssnwBxhEv5p4mn2KTy',
DestinationTag: 1,
Fee: '12',
Flags: 2147483648,
LastLedgerSequence: 65953073,
Sequence: 65923914,
SigningPubKey:
'02F9E33F16DF9507705EC954E3F94EB5F10D1FC4A354606DBE6297DBB1096FE654',
TxnSignature:
'3045022100E3FAE0EDEC3D6A8FF6D81BC9CF8288A61B7EEDE8071E90FF9314CB4621058D10022043545CF631706D700CEE65A1DB83EFDD185413808292D9D90F14D87D3DC2D8CB',
InvoiceID:
'6F1DFD1D0FE8A32E40E1F2C05CF1C15545BAB56B617F9C6C2D63A6B704BEF59B',
Paths: [
[{ currency: 'BTC', issuer: 'r9vbV3EHvXWjSkeQ6CAcYVPGeq7TuiXY2X' }],
],
SendMax: '100000000',
} as any
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's more appropriate to put these objects in their corresponding tests.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed in 109a88d

@khancode
Copy link
Collaborator

Closing this since the other solution was merged in - #2689

@khancode khancode closed this Jun 27, 2024
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.

3 participants