itest: add batch funding test

This commit is contained in:
Oliver Gugger 2021-08-24 11:21:58 +02:00
parent bb079f746b
commit 7a9ee48cf1
No known key found for this signature in database
GPG Key ID: 8E4256593F177720
3 changed files with 129 additions and 2 deletions

@ -26,7 +26,6 @@ import (
// conditions. Finally, the chain itself is checked to ensure the closing
// transaction was mined.
func testBasicChannelFunding(net *lntest.NetworkHarness, t *harnessTest) {
// Run through the test with combinations of all the different
// commitment types.
allTypes := []lnrpc.CommitmentType{
@ -366,7 +365,7 @@ func testUnconfirmedChannelFunding(net *lntest.NetworkHarness, t *harnessTest) {
closeChannelAndAssert(t, net, carol, chanPoint, false)
}
// testexternalfundingchanpoint tests that we're able to carry out a normal
// testExternalFundingChanPoint tests that we're able to carry out a normal
// channel funding workflow given a channel point that was constructed outside
// the main daemon.
func testExternalFundingChanPoint(net *lntest.NetworkHarness, t *harnessTest) {
@ -744,3 +743,122 @@ func deriveFundingShim(net *lntest.NetworkHarness, t *harnessTest,
return fundingShim, chanPoint, txid
}
// testBatchChanFunding makes sure multiple channels can be opened in one batch
// transaction in an atomic way.
func testBatchChanFunding(net *lntest.NetworkHarness, t *harnessTest) {
ctxb := context.Background()
// First, we'll create two new nodes that we'll use to open channels
// to during this test. Carol has a high minimum funding amount that
// we'll use to trigger an error during the batch channel open.
carol := net.NewNode(t.t, "carol", []string{"--minchansize=200000"})
defer shutdownAndAssert(net, t, carol)
dave := net.NewNode(t.t, "dave", nil)
defer shutdownAndAssert(net, t, dave)
// Before we start the test, we'll ensure Alice is connected to Carol
// and Dave so she can open channels to both of them (and Bob).
net.EnsureConnected(t.t, net.Alice, net.Bob)
net.EnsureConnected(t.t, net.Alice, carol)
net.EnsureConnected(t.t, net.Alice, dave)
// Let's create our batch TX request. This first one should fail as we
// open a channel to Carol that is too small for her min chan size.
batchReq := &lnrpc.BatchOpenChannelRequest{
SatPerVbyte: 12,
MinConfs: 1,
Channels: []*lnrpc.BatchOpenChannel{{
NodePubkey: net.Bob.PubKey[:],
LocalFundingAmount: 100_000,
}, {
NodePubkey: carol.PubKey[:],
LocalFundingAmount: 100_000,
}, {
NodePubkey: dave.PubKey[:],
LocalFundingAmount: 100_000,
}},
}
ctxt, cancel := context.WithTimeout(ctxb, defaultTimeout)
defer cancel()
_, err := net.Alice.BatchOpenChannel(ctxt, batchReq)
require.Error(t.t, err)
require.Contains(t.t, err.Error(), "initial negotiation failed")
// Let's fix the minimum amount for Carol now and try again.
batchReq.Channels[1].LocalFundingAmount = 200_000
ctxt, cancel = context.WithTimeout(ctxb, defaultTimeout)
defer cancel()
batchResp, err := net.Alice.BatchOpenChannel(ctxt, batchReq)
require.NoError(t.t, err)
require.Len(t.t, batchResp.PendingChannels, 3)
txHash, err := chainhash.NewHash(batchResp.PendingChannels[0].Txid)
require.NoError(t.t, err)
chanPoint1 := &lnrpc.ChannelPoint{
FundingTxid: &lnrpc.ChannelPoint_FundingTxidBytes{
FundingTxidBytes: batchResp.PendingChannels[0].Txid,
},
OutputIndex: batchResp.PendingChannels[0].OutputIndex,
}
chanPoint2 := &lnrpc.ChannelPoint{
FundingTxid: &lnrpc.ChannelPoint_FundingTxidBytes{
FundingTxidBytes: batchResp.PendingChannels[1].Txid,
},
OutputIndex: batchResp.PendingChannels[1].OutputIndex,
}
chanPoint3 := &lnrpc.ChannelPoint{
FundingTxid: &lnrpc.ChannelPoint_FundingTxidBytes{
FundingTxidBytes: batchResp.PendingChannels[2].Txid,
},
OutputIndex: batchResp.PendingChannels[2].OutputIndex,
}
block := mineBlocks(t, net, 6, 1)[0]
assertTxInBlock(t, block, txHash)
ctxt, cancel = context.WithTimeout(ctxb, defaultTimeout)
defer cancel()
err = net.Alice.WaitForNetworkChannelOpen(ctxt, chanPoint1)
require.NoError(t.t, err)
err = net.Alice.WaitForNetworkChannelOpen(ctxt, chanPoint2)
require.NoError(t.t, err)
err = net.Alice.WaitForNetworkChannelOpen(ctxt, chanPoint3)
require.NoError(t.t, err)
// With the channel open, ensure that it is counted towards Carol's
// total channel balance.
balReq := &lnrpc.ChannelBalanceRequest{}
ctxt, cancel = context.WithTimeout(ctxb, defaultTimeout)
defer cancel()
balRes, err := net.Alice.ChannelBalance(ctxt, balReq)
require.NoError(t.t, err)
require.NotEqual(t.t, int64(0), balRes.LocalBalance.Sat)
// Next, to make sure the channel functions as normal, we'll make some
// payments within the channel.
payAmt := btcutil.Amount(100000)
invoice := &lnrpc.Invoice{
Memo: "new chans",
Value: int64(payAmt),
}
ctxt, cancel = context.WithTimeout(ctxb, defaultTimeout)
defer cancel()
resp, err := carol.AddInvoice(ctxt, invoice)
require.NoError(t.t, err)
err = completePaymentRequests(
net.Alice, net.Alice.RouterClient,
[]string{resp.PaymentRequest}, true,
)
require.NoError(t.t, err)
// To conclude, we'll close the newly created channel between Carol and
// Dave. This function will also block until the channel is closed and
// will additionally assert the relevant channel closing post
// conditions.
closeChannelAndAssert(t, net, net.Alice, chanPoint1, false)
closeChannelAndAssert(t, net, net.Alice, chanPoint2, false)
closeChannelAndAssert(t, net, net.Alice, chanPoint3, false)
}

@ -274,6 +274,10 @@ var allTestCases = []*testCase{
name: "psbt channel funding",
test: testPsbtChanFunding,
},
{
name: "batch channel funding",
test: testBatchChanFunding,
},
{
name: "sendtoroute multi path payment",
test: testSendToRouteMultiPath,

@ -70,6 +70,8 @@
<time> [ERR] FNDG: received funding error from <hex>: chan_id=<hex>, err=chan size of 10.00000001 BTC exceeds maximum chan size of 10 BTC
<time> [ERR] FNDG: received funding error from <hex>: chan_id=<hex>, err=Number of pending channels exceed maximum
<time> [ERR] FNDG: received funding error from <hex>: chan_id=<hex>, err=Synchronizing blockchain
<time> [ERR] FNDG: received funding error from <hex>: chan_id=<hex>, err=chan size of 0.001 BTC is below min chan size of 0.002 BTC
<time> [ERR] FNDG: received funding error from <hex>: chan_id=<hex>, err=funding failed due to internal error
<time> [ERR] FNDG: Unable to add new channel <chan_point> with peer <hex>: canceled adding new channel
<time> [ERR] FNDG: Unable to add new channel <chan_point> with peer <hex>: peer exiting
<time> [ERR] FNDG: Unable to add new channel <chan_point> with peer <hex>: unable to get best block: the client has been shutdown
@ -92,6 +94,7 @@
<time> [ERR] FNDG: Unable to advance state(<chan_point>): failed sending fundingLocked: funding manager shutting down
<time> [ERR] FNDG: Unable to advance state(<chan_point>): funding manager shutting down
<time> [ERR] FNDG: unable to cancel reservation: no active reservations for peer(<hex>)
<time> [ERR] FNDG: Unable to handle funding accept message for peer_key=<hex>, pending_chan_id=<hex>: aborting PSBT flow: user canceled funding
<time> [ERR] FNDG: unable to report short chan id: link <hex> not found
<time> [ERR] FNDG: Unable to send channel proof: channel announcement proof for short_chan_id=<cid> isn't valid: can't verify first bitcoin signature
<time> [ERR] FNDG: Unable to send channel proof: gossiper is shutting down
@ -99,6 +102,7 @@
<time> [ERR] FNDG: Unable to send channel proof: unable add proof to the channel chanID=<hex>: edge not found
<time> [ERR] FNDG: Unable to send node announcement: gossiper is shutting down
<time> [ERR] FNDG: Unable to send node announcement: router shutting down
<time> [ERR] FNDG: unable to open channel to NodeKey(<hex>): remote canceled funding, possibly timed out: received funding error from <hex>: chan_id=<hex>, err=chan size of 0.001 BTC is below min chan size of 0.002 BTC
<time> [ERR] HSWC: AmountBelowMinimum(amt=<amt>, update=(lnwire.ChannelUpdate) {
<time> [ERR] HSWC: ChannelLink(<chan_point>): failing link: ChannelPoint(<chan_point>): received error from peer: chan_id=<hex>, err=internal error with error: remote error
<time> [ERR] HSWC: ChannelLink(<chan_point>): failing link: ChannelPoint(<chan_point>): received error from peer: chan_id=<hex>, err=invalid update with error: remote error
@ -188,6 +192,7 @@
<time> [ERR] RPCS: Failed sending response: rpc error: code = Canceled desc = context canceled
<time> [ERR] RPCS: Failed sending response: rpc error: code = Internal desc = transport: transport: the stream is done or WriteHeader was already called
<time> [ERR] RPCS: [/invoicesrpc.Invoices/SubscribeSingleInvoice]: rpc error: code = Canceled desc = context canceled
<time> [ERR] RPCS: [/lnrpc.Lightning/BatchOpenChannel]: batch funding failed: error batch opening channel, initial negotiation failed: remote canceled funding, possibly timed out: received funding error from <hex>: chan_id=<hex>, err=chan size of 0.001 BTC is below min chan size of 0.002 BTC
<time> [ERR] RPCS: [/lnrpc.Lightning/BakeMacaroon]: invalid permission action. supported actions are [read write generate], supported entities are [onchain offchain address message peers info invoices signer macaroon uri]
<time> [ERR] RPCS: [/lnrpc.Lightning/BakeMacaroon]: invalid permission entity. supported actions are [read write generate], supported entities are [onchain offchain address message peers info invoices signer macaroon uri]
<time> [ERR] RPCS: [/lnrpc.Lightning/BakeMacaroon]: permission list cannot be empty. specify at least one action/entity pair. supported actions are [read write generate], supported entities are [onchain offchain address message peers info invoices signer macaroon uri]