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

delpay: introduced a new rpc method to delete a payment by hash #3899

Merged
merged 2 commits into from
Sep 10, 2020

Conversation

vincenzopalazzo
Copy link
Collaborator

@vincenzopalazzo vincenzopalazzo commented Aug 3, 2020

Hi all.

This Draft implement a new RPC command to delete the payment with the status complete failed marked like good first issue #1995

However, this PR depends from the PR where I proposed to update the result of listpays command with payment_hash inside the result #3888. In addition, with the @cdecker suggestion to add the payment_hash in all cases of types of payments, the command delpay can use only the payment_hash to identify the payment to remove and not bolt11.

This PR is a draft yet because I have some point to clarify with the team, for instance, the type of error that the command should be returned in cases of error. In other words, I see that the LIGHTNINGD error is marked with a FIXME because each command should use the correct error code. I'm not able to find the payment error codes inside the code. maybe we could define the payment error code?

  • Docs update with the change proposed in this Draft
  • Fix error code inside the command implementation

Changelog-Added: JSON-RPC: delpay a new method to delete the payment completed or failed.

Copy link
Collaborator

@ZmnSCPxj ZmnSCPxj left a comment

Choose a reason for hiding this comment

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

I see that the LIGHTNINGD error is marked with a FIXME because each command should use the correct error code. I'm not able to find the payment error codes inside the code. maybe we could define the payment error code?

PAY_NO_SUCH_PAYMENT seems appropriate if the specified hash does not match any payments. Define a new PAY_STATUS_UNEXPECTED for the case where it does not match the expected status.

doc/lightning-delpay.7.md Outdated Show resolved Hide resolved
doc/lightning-delpay.7.md Show resolved Hide resolved
@ZmnSCPxj
Copy link
Collaborator

ZmnSCPxj commented Aug 4, 2020

In addition, it seems to me better to just delete all partids, not delete them one-by-one. Loss of one partid of a multi-part payment is already a loss of information anyway, so just delete them all in one database transaction.

@vincenzopalazzo
Copy link
Collaborator Author

Hi @ZmnSCPxj, thanks to review this PR.

I will make the changes inside the docs and inside the JSON RPC errors, sorry about that.

In addition, about your suggestion.

In addition, it seems to me better to just delete all partid, not delete them one-by-one. Loss of one partid of a multi-part payment is already a loss of information anyway, so just delete them all in one database transaction.

For my code comprehension, to make this work, so, to delete the complete payment and not each payment by partid, I need a new function inside the wallet.c to run the query "DELETE FROM payments WHERE payment_hash=?"

I'm losing something?

Maybe I can use the function wallet_payment_list and run for each element inside the list wallet_payment_delete but I think that the first solution is cleaner but I don't know if it is safe to run on the lightning node the delete query by hash?

@ZmnSCPxj
Copy link
Collaborator

ZmnSCPxj commented Aug 4, 2020

DELETE FROM TABLE payments WHERE payment_hash=? should be fine. You might want to do some check to check if this results in any changes (I think we have a function to check the number of changes a query makes) and if it is 0 that is probably a "payment not found" error.

But you want to check the state of the entire payment first. The logic for a purported "payment state":

  • If any part has succeeded, then the entire payment succeeded.
  • If any part is pending, then the entire payment is pending.
  • Otherwise, all parts are failed, so the entire payment is failed.

It is safe to delete a payment if the entire payment is failed or succeeded, and we should probably disallow deleting pending payments (which might still be operated by pay over in the pay plugin).

Note that if you do not pass control to a function with a callback, then the entire processing is done inside a database transaction, so you are assured that between the check and the deletion, the database state is consistent. But if you pass control to a function with a callback, the database transaction will end at that point, and by the time the callback is called, you are in a new transaction. So do not call into any callback-using functions between checking the state of the payment and deleting the whole payment.

@vincenzopalazzo
Copy link
Collaborator Author

Thanks for the suggestion @ZmnSCPxj.

You might want to do some check to check if this results in any changes (I think we have a function to check the number of changes a query makes) and if it is 0 that is probably a "payment not found" error.

I make the sanity test of input before to call the database function, but I can improve the check maybe I can make the following test:

  1. payment not found: I used the wallet_payment_by_hash to find the payment, I think that is possible use this function to get the payment with hash and partid=0, if exist this part, the payment exists, right?

  2. payment status not valid: from your previous message I understand the payment status is decided from the status of all part, so, I should check the status of all payment find with wallet_payment_list and check the status for each payment and make the correct decision.

of course, there are all checks on the input but, they are not relevant into this description.

It is safe to delete a payment if the entire payment is failed or succeeded, and we should probably disallow deleting pending payments (which might still be operated by pay over in the pay plugin).

Yep, I agree, with my actual logic inside the delpay command you can remove only the payment with the status complete or failed, but of course, with your suggestion the logic change a little.

@ZmnSCPxj
Copy link
Collaborator

ZmnSCPxj commented Aug 5, 2020

partid 0 is for non-split payments. If we split payments at all, there might not be a partid 0.

@vincenzopalazzo
Copy link
Collaborator Author

vincenzopalazzo commented Aug 7, 2020

Rebased 01a82d3 and updated vincenzopalazzo@8fef912

Copy link
Collaborator

@ZmnSCPxj ZmnSCPxj left a comment

Choose a reason for hiding this comment

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

Mostly style nits.

doc/lightning-delpay.7.md Outdated Show resolved Hide resolved
doc/lightning-delpay.7.md Outdated Show resolved Hide resolved
doc/lightning-delpay.7.md Outdated Show resolved Hide resolved
lightningd/pay.c Outdated Show resolved Hide resolved
lightningd/pay.c Outdated Show resolved Hide resolved
lightningd/pay.c Outdated Show resolved Hide resolved
lightningd/pay.c Outdated Show resolved Hide resolved
lightningd/pay.c Outdated Show resolved Hide resolved
wallet/wallet.c Show resolved Hide resolved
lightningd/pay.c Outdated Show resolved Hide resolved
Copy link
Collaborator Author

@vincenzopalazzo vincenzopalazzo left a comment

Choose a reason for hiding this comment

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

@ZmnSCPxj In addition, I need a feedback on this change 😄 sorry about that

lightningd/pay.c Show resolved Hide resolved
tests/test_pay.py Outdated Show resolved Hide resolved
tests/test_pay.py Outdated Show resolved Hide resolved
tests/test_pay.py Outdated Show resolved Hide resolved
tests/test_pay.py Outdated Show resolved Hide resolved
tests/test_pay.py Outdated Show resolved Hide resolved
doc/lightning-delpay.7.md Outdated Show resolved Hide resolved
doc/lightning-delpay.7.md Outdated Show resolved Hide resolved
doc/lightning-delpay.7.md Outdated Show resolved Hide resolved
doc/lightning-delpay.7.md Outdated Show resolved Hide resolved
doc/lightning-delpay.7.md Outdated Show resolved Hide resolved
@niftynei
Copy link
Collaborator

niftynei commented Aug 18, 2020

Mostly grammatical/spelling fixes. In general, for documentation, less words is better :)

@vincenzopalazzo
Copy link
Collaborator Author

Rebase and update with suggestions.

Thanks @niftynei about the fixes and sorry for the spelling errors. I'm still searching somethings where I'm good to do but I'm sure that I'm very bad to write sentences 😄

doc/lightning-delpay.7.md Outdated Show resolved Hide resolved
doc/lightning-delpay.7.md Outdated Show resolved Hide resolved
doc/lightning-delpay.7.md Outdated Show resolved Hide resolved
RETURN VALUE
------------

On success, the command will return a payment object, such as the **listsendpays**. If the payment is aa MPP (multi part payment) the command return a list of
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
On success, the command will return a payment object, such as the **listsendpays**. If the payment is aa MPP (multi part payment) the command return a list of
If successful the command returns a payment object, in the same format as **listsendpays**.
If the payment is a multi-part payment (MPP) the command return a list of

lightningd/pay.c Outdated
Comment on lines 1555 to 1557
if (status == PAYMENT_PENDING)
return command_fail(cmd, JSONRPC2_INVALID_PARAMS, "Invalid status: %s",
payment_status_to_string(status));
Copy link
Member

Choose a reason for hiding this comment

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

Probably it's better to check if we have one of the valid statuses instead of not having the third. If we ever add a new status this is would not cover that fourth state. If you use a switch statement then the compiler will make sure we cover all cases exhaustively.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Thanks for this suggestion, I made the change from if to switch!

Comment on lines 3281 to 3292
# payment unpaid with wrong status (pending status is a illegal input)
with pytest.raises(RpcError):
l2.rpc.delpay(payment_hash, 'pending')
Copy link
Member

Choose a reason for hiding this comment

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

Payment was no attempted at all, so it'd fail for that reason already.

Copy link
Member

Choose a reason for hiding this comment

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

Basically this is testing our sanity check order, and not the underlying pending vs. non-pending cases.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This comment brings me to reflect on the sens of this test!

I moved the pay command to the top of this sanity check, so, with this new situation the unit test has more sense to me because it does the sanity check and the command behavior checks

tests/test_pay.py Outdated Show resolved Hide resolved
tests/test_pay.py Outdated Show resolved Hide resolved
tests/test_pay.py Outdated Show resolved Hide resolved

l1, l2, l3 = node_factory.line_graph(
3, fundamount=10**8, wait_for_announce=True,
opts={'wumbo': None}
Copy link
Member

@cdecker cdecker Aug 24, 2020

Choose a reason for hiding this comment

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

Wumbo is not needed here: MPP_TARGET_SIZE is denominated in msats, whereas the fundamount is denominated in sats. So this creates a channel that is 4 orders of magnitude larger than the amount being transferred:

  • Channel capacity:10**8 * 1000 = 10**11
  • Payment amount: 5 * 10**7

Doesn't hurt though 😉

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Doesn't hurt though

Yes, it is, but it is also my logic error, I discovered only now that fundamount is denominated in sats. I think that 10**5 is enough

@vincenzopalazzo
Copy link
Collaborator Author

vincenzopalazzo commented Aug 25, 2020

Rebase and update with review 3314a05

Waiting to Travis test result

@vincenzopalazzo vincenzopalazzo force-pushed the delpayment branch 5 times, most recently from 4274fe4 to 8879acc Compare August 25, 2020 12:52
@cdecker
Copy link
Member

cdecker commented Sep 9, 2020

Rebased on top of master

Copy link
Member

@cdecker cdecker left a comment

Choose a reason for hiding this comment

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

ACK 56a5dc9

Changelog-Added: JSON-RPC: delpay a new method to delete the payment completed or failed.

Signed-off-by: Vincenzo Palazzo <[email protected]>
@rustyrussell
Copy link
Contributor

Ack db53235

@rustyrussell rustyrussell mentioned this pull request Sep 10, 2020
@rustyrussell rustyrussell merged commit f62d7bb into ElementsProject:master Sep 10, 2020
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.

5 participants