lnd+lnwallet: fundmax flag for openchannel

This commit is contained in:
Slyghtning
2023-01-10 13:42:22 +10:30
parent 0e5b3e77cb
commit 5d88693852
3 changed files with 206 additions and 25 deletions

View File

@@ -710,7 +710,7 @@ func openChannel(t *testing.T, alice, bob *testNode, localFundingAmt,
*wire.OutPoint, *wire.MsgTx) {
publ := fundChannel(
t, alice, bob, localFundingAmt, pushAmt, false, numConfs,
t, alice, bob, localFundingAmt, pushAmt, false, 0, 0, numConfs,
updateChan, announceChan, nil,
)
fundingOutPoint := &wire.OutPoint{
@@ -723,7 +723,8 @@ func openChannel(t *testing.T, alice, bob *testNode, localFundingAmt,
// fundChannel takes the funding process to the point where the funding
// transaction is confirmed on-chain. Returns the funding tx.
func fundChannel(t *testing.T, alice, bob *testNode, localFundingAmt,
pushAmt btcutil.Amount, subtractFees bool, numConfs uint32,
pushAmt btcutil.Amount, subtractFees bool, fundUpToMaxAmt,
minFundAmt btcutil.Amount, numConfs uint32, //nolint:unparam
updateChan chan *lnrpc.OpenStatusUpdate, announceChan bool,
chanType *lnwire.ChannelType) *wire.MsgTx {
@@ -734,6 +735,8 @@ func fundChannel(t *testing.T, alice, bob *testNode, localFundingAmt,
TargetPubkey: bob.privKey.PubKey(),
ChainHash: *fundingNetParams.GenesisHash,
SubtractFees: subtractFees,
FundUpToMaxAmt: fundUpToMaxAmt,
MinFundAmt: minFundAmt,
LocalFundingAmt: localFundingAmt,
PushAmt: lnwire.NewMSatFromSatoshis(pushAmt),
FundingFeePerKw: 1000,
@@ -3730,7 +3733,7 @@ func TestFundingManagerFundAll(t *testing.T) {
// Initiate a fund channel, and inspect the funding tx.
pushAmt := btcutil.Amount(0)
fundingTx := fundChannel(
t, alice, bob, test.spendAmt, pushAmt, true, 1,
t, alice, bob, test.spendAmt, pushAmt, true, 0, 0, 1,
updateChan, true, nil,
)
@@ -3761,6 +3764,157 @@ func TestFundingManagerFundAll(t *testing.T) {
}
}
// TestFundingManagerFundMax tests that we can initiate a funding request to use
// the maximum allowed funds remaining in the wallet.
func TestFundingManagerFundMax(t *testing.T) {
t.Parallel()
// Helper function to create a test utxos
constructTestUtxos := func(values ...btcutil.Amount) []*lnwallet.Utxo {
var utxos []*lnwallet.Utxo
for _, value := range values {
utxos = append(utxos, &lnwallet.Utxo{
AddressType: lnwallet.WitnessPubKey,
Value: value,
PkScript: mock.CoinPkScript,
OutPoint: wire.OutPoint{
Hash: chainhash.Hash{},
Index: 0,
},
})
}
return utxos
}
tests := []struct {
name string
coins []*lnwallet.Utxo
fundUpToMaxAmt btcutil.Amount
minFundAmt btcutil.Amount
pushAmt btcutil.Amount
change bool
}{
{
// We will spend all the funds in the wallet, and expect
// no change output due to the dust limit.
coins: constructTestUtxos(
MaxBtcFundingAmount + 1,
),
fundUpToMaxAmt: MaxBtcFundingAmount,
minFundAmt: MinChanFundingSize,
pushAmt: 0,
change: false,
},
{
// We spend less than the funds in the wallet, so a
// change output should be created.
coins: constructTestUtxos(
2 * MaxBtcFundingAmount,
),
fundUpToMaxAmt: MaxBtcFundingAmount,
minFundAmt: MinChanFundingSize,
pushAmt: 0,
change: true,
},
{
// We spend less than the funds in the wallet when
// setting a smaller channel size, so a change output
// should be created.
coins: constructTestUtxos(
MaxBtcFundingAmount,
),
fundUpToMaxAmt: MaxBtcFundingAmount / 2,
minFundAmt: MinChanFundingSize,
pushAmt: 0,
change: true,
},
{
// We are using the entirety of two inputs for the
// funding of a channel, hence expect no change output.
coins: constructTestUtxos(
MaxBtcFundingAmount/2, MaxBtcFundingAmount/2,
),
fundUpToMaxAmt: MaxBtcFundingAmount,
minFundAmt: MinChanFundingSize,
pushAmt: 0,
change: false,
},
{
// We are using a fraction of two inputs for the funding
// of our channel, hence expect a change output.
coins: constructTestUtxos(
MaxBtcFundingAmount/2, MaxBtcFundingAmount/2,
),
fundUpToMaxAmt: MaxBtcFundingAmount / 2,
minFundAmt: MinChanFundingSize,
pushAmt: 0,
change: true,
},
{
// We are funding a channel with half of the balance in
// our wallet hence expect a change output. Furthermore
// we push half of the funding amount to the remote end
// which we expect to succeed.
coins: constructTestUtxos(MaxBtcFundingAmount),
fundUpToMaxAmt: MaxBtcFundingAmount / 2,
minFundAmt: MinChanFundingSize / 4,
pushAmt: MaxBtcFundingAmount / 4,
change: true,
},
}
for _, test := range tests {
test := test
t.Run(test.name, func(t *testing.T) {
t.Parallel()
// We set up our mock wallet to control a list of UTXOs
// that sum to more than the max channel size.
addFunds := func(fundingCfg *Config) {
wc := fundingCfg.Wallet.WalletController
mockWc, ok := wc.(*mock.WalletController)
if ok {
mockWc.Utxos = test.coins
}
}
alice, bob := setupFundingManagers(t, addFunds)
defer tearDownFundingManagers(t, alice, bob)
// We will consume the channel updates as we go, so no
// buffering is needed.
updateChan := make(chan *lnrpc.OpenStatusUpdate)
// Initiate a fund channel, and inspect the funding tx.
pushAmt := test.pushAmt
fundingTx := fundChannel(
t, alice, bob, 0, pushAmt, false,
test.fundUpToMaxAmt, test.minFundAmt, 1,
updateChan, true, nil,
)
// Check whether the expected change output is present.
if test.change {
require.EqualValues(t, 2, len(fundingTx.TxOut))
}
if !test.change {
require.EqualValues(t, 1, len(fundingTx.TxOut))
}
// Inputs should be all funds in the wallet.
require.Equal(t, len(test.coins), len(fundingTx.TxIn))
for i, txIn := range fundingTx.TxIn {
require.Equal(
t, test.coins[i].OutPoint,
txIn.PreviousOutPoint,
)
}
})
}
}
// TestGetUpfrontShutdown tests different combinations of inputs for getting a
// shutdown script. It varies whether the peer has the feature set, whether
// the user has provided a script and our local configuration to test that
@@ -4212,8 +4366,8 @@ func TestFundingManagerZeroConf(t *testing.T) {
// Call fundChannel with the zero-conf ChannelType.
fundingTx := fundChannel(
t, alice, bob, fundingAmt, pushAmt, false, 1, updateChan, true,
&channelType,
t, alice, bob, fundingAmt, pushAmt, false, 0, 0, 1, updateChan,
true, &channelType,
)
fundingOp := &wire.OutPoint{
Hash: fundingTx.TxHash(),