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

rpc: anchor reserve check for SendOutputs #7631

Merged
merged 4 commits into from
May 4, 2023

Conversation

hieblmi
Copy link
Collaborator

@hieblmi hieblmi commented Apr 23, 2023

Fixes #7591.

This PR adds a check to the SendOutputs RPC to prevent it from undershooting the anchor reserve requirement.

@hieblmi hieblmi changed the title Sendoutputs reserve rpc: anchor reserve check for SendOutputs Apr 23, 2023
@hieblmi hieblmi force-pushed the sendoutputs-reserve branch 2 times, most recently from 16f47eb to 7e1fecf Compare April 23, 2023 18:29
itest/list_on_test.go Outdated Show resolved Hide resolved
@@ -1666,7 +1673,9 @@ func parseAddrType(addrType AddressType,
switch addrType {
case AddressType_UNKNOWN:
if required {
return nil, errors.New("an address type must be specified")
return nil, errors.New(
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: for errors we'd format it similar to fmt.Errorf.

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 I missed this style fix. Will add.

itest/lnd_onchain_test.go Show resolved Hide resolved
MinConfs: 1,
}

// We try to send the reserve violating transaction...
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
// We try to send the reserve violating transaction...
// We try to send the reserve violating transaction.


// We'll get the currently required reserve amount.
reserve, err := w.RequiredReserve(
ctx, &RequiredReserveRequest{AdditionalPublicChannels: 0},
Copy link
Collaborator

Choose a reason for hiding this comment

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

hmm what if we need more public channels?

Copy link
Collaborator

Choose a reason for hiding this comment

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

The AdditionalPublicChannels is just an RPC parameter that allows you to plan ahead if you intend to open more channels in the near future. Not really related to this feature, as we just need to check the reserve for the current number of channels, so just remove that parameter as the default is 0 anyway?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Cool got it, yeah make sense to use the default.

lnrpc/walletrpc/walletkit_server.go Show resolved Hide resolved
Copy link
Collaborator

@yyforyongyu yyforyongyu left a comment

Choose a reason for hiding this comment

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

Very close! Just a new nits in the itest.

ht.EnsureConnected(alice, bob)

// We'll get the anchor reserve that is required for a single channel.
reserve, _ := alice.RPC.WalletKit.RequiredReserve(
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can we add RequiredReserve to wallet_kit.go and access it via alice.RPC.RequiredReserve to avoid checking the RPC error?

}

// We try to send the reserve violating transaction.
_, err := alice.RPC.WalletKit.SendOutputs(context.Background(), req)
Copy link
Collaborator

Choose a reason for hiding this comment

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

We need to use a timeout context here to avoid it hanging, tho almost will never happen, just in case. And we can use ht.Context() here.

ht.MineBlocksAndAssertNumTxes(1, 0)

// We expect SendOutputs to return the respective error.
require.ErrorContains(ht, err, "the outputs to be send would leave "+
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: move the error check next to the rpc call

ht.MineBlocksAndAssertNumTxes(1, 1)

// This second transaction should be published correctly.
require.NoError(ht, err)
Copy link
Collaborator

Choose a reason for hiding this comment

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

same here re moving the error check, so we can skip mining and assertion if there does return an error, otherwise we won't see the NoError fail because ht.MineBlocksAndAssertNumTxes will fail first.

Copy link
Collaborator

@guggero guggero left a comment

Choose a reason for hiding this comment

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

LGTM, only nits 🎉


// We'll get the currently required reserve amount.
reserve, err := w.RequiredReserve(
ctx, &RequiredReserveRequest{},
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: can now fit on a single line.

}

// Then we check if our current wallet balance undershoots the required
// reserve if we'd send out the outputs sepcified in the request.
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: typo in the word "specified".

// Then we check if our current wallet balance undershoots the required
// reserve if we'd send out the outputs sepcified in the request.
if int64(walletBalance)-totalOutputValue < reserve.RequiredReserve {
return nil, fmt.Errorf("the outputs to be send would leave " +
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: s/send/sent/. Also, should we mention anchor channels? E.g. "would leave insufficient reserves for anchor channels".

@@ -717,7 +719,8 @@ func (w *WalletKit) SendOutputs(ctx context.Context,
// requirement, we can request that the wallet attempts to create this
// transaction.
tx, err := w.cfg.Wallet.SendOutputs(
outputsToCreate, chainfee.SatPerKWeight(req.SatPerKw), minConfs, label,
outputsToCreate, chainfee.SatPerKWeight(req.SatPerKw), minConfs,
Copy link
Collaborator

Choose a reason for hiding this comment

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

🙏

itest/lnd_onchain_test.go Show resolved Hide resolved
// Alice opens an anchor channel and keeps twice the amount of the
// anchor reserve in her wallet.
chanAmt := fundingAmount - 2*btcutil.Amount(reserve.RequiredReserve)
outpoint := ht.OpenChannel(
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: could use the compact form here, since things seem to fit on one line:

	outpoint := ht.OpenChannel(alice, bob, lntest.OpenChannelParams{
		Amt:            chanAmt,
		CommitmentType: lnrpc.CommitmentType_ANCHORS,
		SatPerVByte:    1,
	})

ht.MineBlocksAndAssertNumTxes(1, 0)

// We expect SendOutputs to return the respective error.
require.ErrorContains(ht, err, "the outputs to be send would leave "+
Copy link
Collaborator

Choose a reason for hiding this comment

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

Also, we should probably define this as an exported error, then we can string match on it here to shorten the line and also avoid braking the test when the message is updated.

@hieblmi hieblmi force-pushed the sendoutputs-reserve branch 2 times, most recently from d1c64ea to 79a06d1 Compare April 29, 2023 20:44
Copy link
Collaborator

@yyforyongyu yyforyongyu left a comment

Choose a reason for hiding this comment

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

LGTM⛵️

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.

[bug]: wallet balance below required reserve
4 participants