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

CheckCashMakesTrustLine amendment #3823

Closed
wants to merge 5 commits into from

Conversation

scottschurr
Copy link
Collaborator

High Level Overview of Change

With this amendment, the CheckCash transaction creates a trust line if needed. The change is modeled after Offer crossing. And, similar to Offer crossing, cashing a Check allows an account to exceed its trust line limit.

Context of Change

It has been determined that the user experience of needing to create a trust line prior to cashing a Check was both inconvenient and not necessary. Similar to an Offer, anyone who cashes a Check clearly wants to accept the funds involved. Automatically creating the trust line, if necessary, would be convenient and has precedent with Offer crossing.

Therefore this amendment introduces two changes to the behavior of cashing a Check:

  1. If the account cashing the Check does not already have a trust line for the currency being received, then that trust line is created if possible. It usually is possible.

    Reasons it might not be possible to create the trust line include:

    • The account cashing the check does not have sufficient XRP to meet the reserve required to create the trust line.
    • Rippling would be required to transfer the funds and the issuing account has not set the lsfDefaultRipple flag.
    • The account issuing the currency has set the lsfGlobalFreeze flag.
    • The account issuing the currency has set the lsfRequireAuth flag, so an automatically created trust line would not be authorized.
  2. The currency being brought into the account by the Check is allowed to exceed any limit specified the in trust line. There are three reasons for this:

    • If the account is explicitly cashing the Check then they must want the currency in question.
    • Offers have the same behavior. It makes sense to limit the number of unique behaviors on the ledger.
    • An automatically created trust line has limits of zero. If we didn't have this rule then the automatically created trust line would be useless.

If cashing the Check fails for any reason, then the trust line is not added to the account.

Type of Change

  • Breaking change (a feature that would cause existing functionality to not work as expected)
  • Tests (added unit tests)
  • Documentation updates will be required

If this change is merged then documentation will need to be updated to cover the behavior changes. This change will also need to be mentioned in the release notes.

Test Plan

Unit tests were added to verify that prior to the introduction of the amendment cashing a Check without a pre-existing trust line would fail. After the introduction of the amendment cashing a Check without a pre-existing trust line succeeds by adding the necessary trust line to the ledger.

A number of different scenarios were tested including:

  • Cashing a Check that was created by the issuer of the currency in question.
  • Cashing a Check written by an account other than the issuer.
  • A variety of AccountRoot flags were tested which either allowed or prevented the automatic trust line creation.
  • Trust lines automatically created by Offer crossing were compared to trust lines automatically created by Check cashing and found to be very similar (as intended).

Requests of Reviewers

Please consider situations I might have forgotten which might affect creation of a trust line. I tested the account root flags I thought would matter. Did I miss important account root flags? Are there conditions other than account root flags that need to be tested? Thanks for the help.

Future Tasks

Once a trust line is added to the ledger, it can be challenging for a ledger user to remove the trust line. It may be useful to explore ways for non-issuer accounts to more easily remove trust lines.

// Set the delivered_amount metadata.
ctx_.deliver(result.actualAmountOut);
}
// Set the delivered amount metadata in all cases, not just
Copy link
Collaborator

Choose a reason for hiding this comment

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

Prior to checkCashMakesTrustLine, why was the delivered amount metadata set only if DeliverMin was used?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Hi @intelliot, I believe that was a bug. As part of this pull request I added some unit tests. I expected that in all cases the result of a successful CheckCash transactions would include a delivered_amount field. I found that delivered_amount was not always set. I surmised delivered_amount was not set because DeliveredAmount was not always set due to the conditional above.

When I changed the code so setting DeliveredAmount was only conditional on the amendment then the unit tests returned a delivery_amount field in all of the tested cases.

src/ripple/app/tx/impl/CashCheck.cpp Outdated Show resolved Hide resolved
src/ripple/app/tx/impl/CashCheck.cpp Outdated Show resolved Hide resolved
src/test/app/Check_test.cpp Outdated Show resolved Hide resolved
src/test/app/Check_test.cpp Outdated Show resolved Hide resolved
src/test/app/Check_test.cpp Outdated Show resolved Hide resolved
src/test/app/Check_test.cpp Show resolved Hide resolved
src/test/app/Check_test.cpp Outdated Show resolved Hide resolved
src/test/jtx/impl/Env.cpp Show resolved Hide resolved
Copy link
Collaborator Author

@scottschurr scottschurr left a comment

Choose a reason for hiding this comment

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

Thanks for the great review @ximinez! I've pushed a commit that I believe addresses your comments. Please let me know if I missed anything.

I've also rebased on top of #3840 since it has passed and provides functionality that I'm using. I anticipate that #3840 will be merged before this pull request is.

Any future reviewers will want to skip the commits below the one named Introduce CheckCashMakesTrustLine amendment.

src/ripple/app/tx/impl/CashCheck.cpp Outdated Show resolved Hide resolved
src/test/app/Check_test.cpp Outdated Show resolved Hide resolved
src/test/app/Check_test.cpp Outdated Show resolved Hide resolved
src/test/app/Check_test.cpp Show resolved Hide resolved
src/test/app/Check_test.cpp Outdated Show resolved Hide resolved
src/test/app/Check_test.cpp Outdated Show resolved Hide resolved
src/test/app/Check_test.cpp Show resolved Hide resolved
@scottschurr
Copy link
Collaborator Author

@ximinez, thanks for the suggestion regarding the macro. I followed your lead but tweaked it a bit. At your convenience take a look and see what you think.

With this amendment, the CheckCash transaction creates a TrustLine
if needed.  The change is modeled after offer crossing.  And,
similar to offer crossing, cashing a check allows an account to
exceed its trust line limit.
@scottschurr
Copy link
Collaborator Author

Rebased to 1.8.0-b3.

Copy link
Collaborator

@ximinez ximinez left a comment

Choose a reason for hiding this comment

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

Sorry for the delay on this followup. The latest changes look good!

Comment on lines +1911 to +1915
suite.expect(
ownerCount(env, acct) == owners,
"Owner count mismatch",
__FILE__,
line);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nice

@scottschurr scottschurr requested review from thejohnfreeman and removed request for nbougalis June 9, 2021 20:17
@scottschurr
Copy link
Collaborator Author

@nbougalis is really busy right now, so I'm swapping in @thejohnfreeman as a technical reviewer. Thanks for the help, @thejohnfreeman!

Copy link
Collaborator

@thejohnfreeman thejohnfreeman left a comment

Choose a reason for hiding this comment

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

Can we add a test that a second check for the same currency can be cashed after one that created a trust line (i.e. that the limits are ignored even when a trust line already existed)?

JLOG(ctx.j.warn())
<< "Cannot cash check for IOU without trustline.";
return tecNO_LINE;
if (!ctx.view.rules().enabled(featureCheckCashMakesTrustLine))
Copy link
Collaborator

Choose a reason for hiding this comment

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

One way to do the changes from line 200 (in the original code) to line 225 that requires fewer actual code changes is to just add && !ctx.view.rules().enabled(featureCheckCashMakesTrustLine) to the condition on line 200, and insert this condition on line 218:

if (!sleTrustLine) {
    return tecNO_AUTH;
}

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, but I'm not really clear on the edit you'd like to see. Can you spell out the proposed change further? Thanks.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Here it is as a commit: thejohnfreeman@d57c0e8

Comment on lines 1972 to 1974
// All remaining tests require featureCheckCashMakesTrustLine.
if (!features[featureCheckCashMakesTrustLine])
return;
Copy link
Collaborator

Choose a reason for hiding this comment

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

With CheckCashMakesTrustLine disabled, this function is only the test above this return, which duplicates a test elsewhere. I personally find it easier to understand if this function is only run with CheckCashMakesTrustLine enabled, without lines 1943 - 1974 (the sanity check and early return), but maybe with an assertion that the feature is enabled.

@scottschurr
Copy link
Collaborator Author

Thanks for the great review @thejohnfreeman. I've pushed a couple of commits that I believe address your comments. Please let me know if there's anything else you'd like addressed.

Copy link
Collaborator

@ximinez ximinez left a comment

Choose a reason for hiding this comment

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

Still looks good. I like the changes.

@thejohnfreeman
Copy link
Collaborator

Looks great! Thank you!

@scottschurr
Copy link
Collaborator Author

@mDuo13 and @intelliot, does this change look reasonable to you? I want to make sure before I mark it passed. Thanks.

@mDuo13
Copy link
Collaborator

mDuo13 commented Jun 18, 2021

Tentatively, looks good.

I certainly appreciate the idea, and the semantics as laid out in the description sound perfect to me. I haven't tested out the changes or looked through the code to confirm that it works as described or that there aren't any relevant edge cases I haven't thought of.

To be clear, when cashing a Check for a "flexible" amount, is the amount it delivers is no longer bounded by the Check recipient's trust limits (even if there's an existing line and trust limits are set to nonzero values)? That's sensible to me, though it may be surprising in at least a couple cases, so it's something to make sure the docs clarify. I guess in that case, the only things that may limit the redemption to less than the Check's full amount are:

(a) the amount the check sender holds, if they aren't the issuer
(b) the transfer fee, if the check sender is not the issuer

Right?

@scottschurr
Copy link
Collaborator Author

@mDuo13, that sounds correct.

@manojsdoshi manojsdoshi added the Passed Passed code review & PR owner thinks it's ready to merge. Perf sign-off may still be required. label Jul 20, 2021
@manojsdoshi manojsdoshi mentioned this pull request Jul 27, 2021
@scottschurr scottschurr deleted the check-trust branch November 3, 2021 16:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Amendment Passed Passed code review & PR owner thinks it's ready to merge. Perf sign-off may still be required.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants