Skip to content

funding: add fundmax flag to OpenChannelRequest#6903

Merged
Roasbeef merged 10 commits intolightningnetwork:masterfrom
hieblmi:fundmax-flag
Apr 6, 2023
Merged

funding: add fundmax flag to OpenChannelRequest#6903
Roasbeef merged 10 commits intolightningnetwork:masterfrom
hieblmi:fundmax-flag

Conversation

@hieblmi
Copy link
Copy Markdown
Collaborator

@hieblmi hieblmi commented Sep 8, 2022

CC @bjarnemagnussen, @saubyk, @positiveblue: This PR continues the work of PR #4029. I am pasting the previous PR description below to make adjustments.

The original PR is related to #4024.

Description

This PR introduces a new flag fundmax for OpenChannelRequest, which when opening a new channel uses the whole available wallet balance for the channel capacity up to the allowed maximum funding limit (~0.16 BTC by default, 10 BTC if wumbo channels are enabled) while considering channel funding fees and an optional anchor reserve.

Motivation

A frequently requested feature of lnd is the ability to spend all available wallet funds towards a channel opening. This would allow to put the maximum available balance towards a node operation not leaving any funds idle. For reference see:

To achieve a similar behavior users today manually select amounts that slightly undershoot the optimal sweep amount which leaves the required reserve plus a small residual balance in the wallet. Ideally that small balance, a consequence of the undershooting, should go towards the channel opening.

The SendCoins RPC offers a send_all flag that attempts to send all the coins under control of the internal wallet to a specified address. Similarly, OpenChannel should implement functionality to use all available wallet funds towards a channel opening.

Implementation

A new FundMax flag is added to the OpenChannel RPC, --fundmax to lncli openchannel respectively. As of now this flag cannot be used in combination with psbt.
When using this flag the implementation ensures that the channel capacity adheres on the lower end to the user specified minimum channel size, or if not defined, to lnd's default minimum channel size(20_000 sats). The maximum channel size is bound by either the user specified maximum channel size or lnd's default maximum channel size, ~16M sats, and 10BTC if wumbo channels are enabled.

New coin select function

To select coins that represent this narrowed down balance, a new coin select function CoinSelectUpToAmount has been introduced. It selects coins up to the requested amount, or below if there are not sufficient funds available. More specifically the function

  1. first checks if the fundmax amount is available exclusive of funding transaction fee and optional anchor channel reserve.
  2. if the first check fails the function will try to subtract fees and anchor reserve from the total wallet balance and see if that fulfils our fundmax request.

If the coin selection succeeds in any of the two cases then the function additionally checks if the remaining wallet balance is below the dust limit and if so it will add it to the channel funding amount.

fundmax behavior for anchor channels and future channel types

Since anchor channels require an extra wallet reserve to ensure the ability to fee-bump stuck transactions the implementation reserves sufficient funds for public anchor channels. Since private anchor channels are mostly used as last hops in a route and usually do not take part in routing activity they are not considered for an anchor reserve.

To remind future channel-type developers to consider the required reserve of the fundmax flow a new sanity test has been added to the funding manager(see TestCommitmentTypeFundmaxSanityCheck). Whenever a new channel type is added to the proto files this test fails unless consciously handled by the implementer.

Considerations

This implementation should be concurrent safe, becuase it locks the coins prior to selecting them, as currently done by the wallet assembler for the coin select subroutine.

@hieblmi
Copy link
Copy Markdown
Collaborator Author

hieblmi commented Sep 8, 2022

This PR so far has only taken #4029 and rebased it with the latest master. Next steps are to make the build pipeline checks succeed and then address the comments in this PR's predecessor.

@saubyk saubyk linked an issue Sep 8, 2022 that may be closed by this pull request
@saubyk saubyk requested a review from guggero September 8, 2022 23:40
@guggero
Copy link
Copy Markdown
Collaborator

guggero commented Sep 9, 2022

Thanks for picking up this PR! I think you should attribute the original author in the commits. At least those that you took over more or less unchanged.

@hieblmi
Copy link
Copy Markdown
Collaborator Author

hieblmi commented Sep 9, 2022

Thanks @guggero, yes good point. I will attribute the commits to Bjarne.

@hieblmi hieblmi force-pushed the fundmax-flag branch 4 times, most recently from 3d67cf2 to dff8e88 Compare September 11, 2022 03:31
@hieblmi hieblmi mentioned this pull request Sep 11, 2022
11 tasks
@hieblmi
Copy link
Copy Markdown
Collaborator Author

hieblmi commented Sep 11, 2022

I've went through the parent PR top to bottom and now have a better grasp of what the difficulties were up to this stage and how some of them were addressed even though it still feels a little complex.

The parent PR has been rebased here with all its commits attributed to @bjarnemagnussen. Some linter issues and variable contexts have been adjusted so that all tests are passing.

I will now pick up the work from @guggero's last change requests -> #4029 (review), try and make CoinSelectUpToAmount more legible and add the requested tests.

@guggero
Copy link
Copy Markdown
Collaborator

guggero commented Sep 12, 2022

I will now pick up the work from @guggero's last change requests -> #4029 (review), try and make CoinSelectUpToAmount more legible and add the requested tests.

Sounds good to me! Can you please re-request review once you've submitted the changes? Going to remove the review request for now as the PR is still work in progress.

@guggero guggero removed their request for review September 12, 2022 05:46
@hieblmi hieblmi force-pushed the fundmax-flag branch 7 times, most recently from b9d8b32 to 96ab85a Compare September 14, 2022 01:45
@saubyk
Copy link
Copy Markdown
Collaborator

saubyk commented Sep 14, 2022

@guggero If the open channel is being invoked with a psbt(e.g. for a specific UTXO) and fundmax flag is specified, is it possible to open the channel with just the amount in the UTXO (minus fee)?

@hieblmi have you covered this scenario in your testing? From the description on the PR it appears that the scope of fundmax is only to ensure that entire wallet balance is used up for opening the channel.

@hieblmi
Copy link
Copy Markdown
Collaborator Author

hieblmi commented Sep 15, 2022

@saubyk I don't see psbt scenarios covered in the parent PR. I am currently incorporating requested changes to the itest and am at this stage to add a test for the anchor reserve: https://github.com/lightningnetwork/lnd/pull/4029/files/2a2d6ca9c66038f3bad15a9818c978ed05285a56..827685603340218c103a492efeca97f37ce7e45e#r794496922.

It makes sense to use the fundmax flag in the context of a psbt channel opening but don't think that this has been considered in this PR so far.

@guggero
Copy link
Copy Markdown
Collaborator

guggero commented Sep 15, 2022

@guggero If the open channel is being invoked with a psbt(e.g. for a specific UTXO) and fundmax flag is specified, is it possible to open the channel with just the amount in the UTXO (minus fee)?

I'm not sure. I think the PSBT funding bypasses the whole coin selection process and therefore most of the changes in this PR. But I think that question would make for an excellent integration test case in this PR.

@hieblmi hieblmi force-pushed the fundmax-flag branch 4 times, most recently from 6c4930c to 60ddaa7 Compare September 21, 2022 01:47
Copy link
Copy Markdown
Collaborator

@ziggie1984 ziggie1984 left a comment

Choose a reason for hiding this comment

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

Looks really good now, just had some additonal minor comments, if they are addressed I am good :)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

nit: Not sure why we need this Reserve Check here, isn't it done upstream in the VerifyConstraints function ?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Hmm ok, so yeah the check in the lncli is good, but because we do the check for fundmax in the backend, I think doing it in the VerifyContraints is enough or ? But decide by yourself, one additonal check does not harm anyone

Copy link
Copy Markdown
Collaborator Author

@hieblmi hieblmi Mar 6, 2023

Choose a reason for hiding this comment

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

Oh now I see it. Yes, VerifyConstraints tests exactly this. I will remove RemoteChanReserve and the redundant check I added in the wallet.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

maybe outputt the expected error here ?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

nit: If more than 20% of all outputs go to fees (funds in general is a bit vague could be sum of all inputs?)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I will call it 'available wallet funds'. Sould be clear in the fundmax context imo

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Q: Is it common in itests to replicate the functions in the codebase rather then use them here?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I doubt that this is a common pattern.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

is it better to replicate the code rather than using the feecalculation form the actual code? Asking out of curiosity how to do this testing, my suggestion would come with the risk of testing way too "whitetesty" but depending on why you wrote this function you basically looked how the real source is doing it an replicated it so not sure whats the best way to test in such circumstances ?

Copy link
Copy Markdown
Collaborator Author

@hieblmi hieblmi Mar 8, 2023

Choose a reason for hiding this comment

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

Edit: @ziggie1984 Yes good point. I think initially this function was added for brevity and to work around the private scope of calculateFees in coin_select.go.

We'd have to export the private function to be able to test it. Or adjust the test fee function in case the calculation in the implementation changes, as was done during this PR when the default P2TR change outputs were introduced.

I am curious to hear more thoughts on this.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

nit: see my comment above I don't think we need this check here its already done in a higher level

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I think its a good idea to have such a check, or we include a reserve for all types except the one we no don't need one ?

Copy link
Copy Markdown
Collaborator

@ziggie1984 ziggie1984 left a comment

Choose a reason for hiding this comment

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

LGTM, thanks for tackling this one !

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

is it better to replicate the code rather than using the feecalculation form the actual code? Asking out of curiosity how to do this testing, my suggestion would come with the risk of testing way too "whitetesty" but depending on why you wrote this function you basically looked how the real source is doing it an replicated it so not sure whats the best way to test in such circumstances ?

Copy link
Copy Markdown
Collaborator

@ellemouton ellemouton left a comment

Choose a reason for hiding this comment

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

Incredible work on this PR 🔥 The test coverage and PR description also deserve a special shout out 🚀

I think this is good to go. All my comments are non-blocking.

The reason the itests are failing is actually cause the itest that runs right before the one you added does not clean up its channel properly. The following diff will fix it:

diff --git a/itest/lnd_htlc_test.go b/itest/lnd_htlc_test.go
index 4e73a385b..fc04fe8d0 100644
--- a/itest/lnd_htlc_test.go
+++ b/itest/lnd_htlc_test.go
@@ -24,6 +24,7 @@ func testLookupHtlcResolution(ht *lntest.HarnessTest) {
 	cp := ht.OpenChannel(
 		alice, carol, lntest.OpenChannelParams{Amt: chanAmt},
 	)
+	defer ht.CloseChannel(alice, cp)
 
 	// Channel should be ready for payments.
 	const payAmt = 100

Will approve this once the above diff is in ✅

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

doesnt seem like they were reverted? also, no need to revert them, can just put them in a separate commit :)

@ellemouton
Copy link
Copy Markdown
Collaborator

Once #7511 is in, then the diff I posted will no longer be necessary :)

@hieblmi
Copy link
Copy Markdown
Collaborator Author

hieblmi commented Mar 14, 2023

Incredible work on this PR 🔥 The test coverage and PR description also deserve a special shout out 🚀

Thank you @ellemouton, I've submitted my changes but it still looks like an itest is not cleaning up properly. Is lookup_htlc_resolution the culprit?

@guggero
Copy link
Copy Markdown
Collaborator

guggero commented Mar 15, 2023

@hieblmi we started a new parallel development branch 0-16-1-staging. If you update your PR to use that as a base (can be done by clicking "Edit" next to the PR title) and rebase on top of that branch, the fix for the itest cleanup should already be there. And if you do that, we can also get the PR merged before the final version of lnd 0.16.0-beta is out (once the PR is approved).

@hieblmi
Copy link
Copy Markdown
Collaborator Author

hieblmi commented Mar 15, 2023

Thx for the instructions @guggero, I've just rebased with this dev branch. Would be awesome if we get it into v0.16.0.

@guggero
Copy link
Copy Markdown
Collaborator

guggero commented Mar 15, 2023

Thx for the instructions @guggero, I've just rebased with this dev branch. Would be awesome if we get it into v0.16.0.

Since 0.16.0 is already in RC3 (which might or might not be the last one), that ship has sailed, unfortunately. But this looks to be very much on track for 0.16.1 (hence the dev branch).

@hieblmi
Copy link
Copy Markdown
Collaborator Author

hieblmi commented Mar 15, 2023

Got it, I misread/misunderstood the branching concept here. It makes sense and thx for clarifying.

Copy link
Copy Markdown
Collaborator

@ellemouton ellemouton left a comment

Choose a reason for hiding this comment

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

A very well deserved LGTM 🔥 Excellent work on this - your test coverage is fantastic!!

Just needs a rebase onto the 0-16-1-staging branch

Copy link
Copy Markdown
Collaborator

@Crypt-iQ Crypt-iQ left a comment

Choose a reason for hiding this comment

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

The reserve still needs to be checked remoteChanReserve >= localFundingAmt/5

@lightninglabs-deploy
Copy link
Copy Markdown
Collaborator

@hieblmi, remember to re-request review from reviewers when ready

Copy link
Copy Markdown
Collaborator

@Crypt-iQ Crypt-iQ left a comment

Choose a reason for hiding this comment

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

last comment

Copy link
Copy Markdown
Collaborator

@Crypt-iQ Crypt-iQ left a comment

Choose a reason for hiding this comment

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

great work 🌮

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.

[Request] sendcoins all / openchannel all