mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-01-19 05:45:21 +01:00
itest: refactor testBasicChannelFunding
The test `testExternalFundingChanPoint` is commented out and will be put back in the following commit.
This commit is contained in:
parent
19981ac9bd
commit
773cc8e295
@ -11,4 +11,8 @@ var allTestCasesTemp = []*lntemp.TestCase{
|
|||||||
Name: "update channel status",
|
Name: "update channel status",
|
||||||
TestFunc: testUpdateChanStatus,
|
TestFunc: testUpdateChanStatus,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Name: "basic funding flow",
|
||||||
|
TestFunc: testBasicChannelFunding,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,10 @@ import (
|
|||||||
"github.com/lightningnetwork/lnd/input"
|
"github.com/lightningnetwork/lnd/input"
|
||||||
"github.com/lightningnetwork/lnd/labels"
|
"github.com/lightningnetwork/lnd/labels"
|
||||||
"github.com/lightningnetwork/lnd/lnrpc"
|
"github.com/lightningnetwork/lnd/lnrpc"
|
||||||
|
"github.com/lightningnetwork/lnd/lnrpc/signrpc"
|
||||||
"github.com/lightningnetwork/lnd/lnrpc/walletrpc"
|
"github.com/lightningnetwork/lnd/lnrpc/walletrpc"
|
||||||
|
"github.com/lightningnetwork/lnd/lntemp"
|
||||||
|
"github.com/lightningnetwork/lnd/lntemp/node"
|
||||||
"github.com/lightningnetwork/lnd/lntest"
|
"github.com/lightningnetwork/lnd/lntest"
|
||||||
"github.com/lightningnetwork/lnd/lnwire"
|
"github.com/lightningnetwork/lnd/lnwire"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
@ -25,7 +28,7 @@ import (
|
|||||||
// Bob, then immediately closes the channel after asserting some expected post
|
// Bob, then immediately closes the channel after asserting some expected post
|
||||||
// conditions. Finally, the chain itself is checked to ensure the closing
|
// conditions. Finally, the chain itself is checked to ensure the closing
|
||||||
// transaction was mined.
|
// transaction was mined.
|
||||||
func testBasicChannelFunding(net *lntest.NetworkHarness, t *harnessTest) {
|
func testBasicChannelFunding(ht *lntemp.HarnessTest) {
|
||||||
// Run through the test with combinations of all the different
|
// Run through the test with combinations of all the different
|
||||||
// commitment types.
|
// commitment types.
|
||||||
allTypes := []lnrpc.CommitmentType{
|
allTypes := []lnrpc.CommitmentType{
|
||||||
@ -36,39 +39,35 @@ func testBasicChannelFunding(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
|
|
||||||
// testFunding is a function closure that takes Carol and Dave's
|
// testFunding is a function closure that takes Carol and Dave's
|
||||||
// commitment types and test the funding flow.
|
// commitment types and test the funding flow.
|
||||||
testFunding := func(carolCommitType, daveCommitType lnrpc.CommitmentType) {
|
testFunding := func(ht *lntemp.HarnessTest, carolCommitType,
|
||||||
|
daveCommitType lnrpc.CommitmentType) {
|
||||||
|
|
||||||
// Based on the current tweak variable for Carol, we'll
|
// Based on the current tweak variable for Carol, we'll
|
||||||
// preferentially signal the legacy commitment format. We do
|
// preferentially signal the legacy commitment format. We do
|
||||||
// the same for Dave shortly below.
|
// the same for Dave shortly below.
|
||||||
carolArgs := nodeArgsForCommitType(carolCommitType)
|
carolArgs := nodeArgsForCommitType(carolCommitType)
|
||||||
carol := net.NewNode(t.t, "Carol", carolArgs)
|
carol := ht.NewNode("Carol", carolArgs)
|
||||||
defer shutdownAndAssert(net, t, carol)
|
|
||||||
|
|
||||||
// Each time, we'll send Carol a new set of coins in order to
|
// Each time, we'll send Carol a new set of coins in order to
|
||||||
// fund the channel.
|
// fund the channel.
|
||||||
net.SendCoins(t.t, btcutil.SatoshiPerBitcoin, carol)
|
ht.FundCoins(btcutil.SatoshiPerBitcoin, carol)
|
||||||
|
|
||||||
daveArgs := nodeArgsForCommitType(daveCommitType)
|
daveArgs := nodeArgsForCommitType(daveCommitType)
|
||||||
dave := net.NewNode(t.t, "Dave", daveArgs)
|
dave := ht.NewNode("Dave", daveArgs)
|
||||||
defer shutdownAndAssert(net, t, dave)
|
|
||||||
|
|
||||||
// Before we start the test, we'll ensure both sides are
|
// Before we start the test, we'll ensure both sides are
|
||||||
// connected to the funding flow can properly be executed.
|
// connected to the funding flow can properly be executed.
|
||||||
net.EnsureConnected(t.t, carol, dave)
|
ht.EnsureConnected(carol, dave)
|
||||||
|
|
||||||
carolChan, daveChan, closeChan, err := basicChannelFundingTest(
|
carolChan, daveChan, closeChan := basicChannelFundingTest(
|
||||||
t, net, carol, dave, nil,
|
ht, carol, dave, nil,
|
||||||
)
|
)
|
||||||
require.NoError(t.t, err, "failed funding flow")
|
|
||||||
|
|
||||||
// Both nodes should report the same commitment
|
// Both nodes should report the same commitment
|
||||||
// type.
|
// type.
|
||||||
chansCommitType := carolChan.CommitmentType
|
chansCommitType := carolChan.CommitmentType
|
||||||
require.Equal(
|
require.Equal(ht, chansCommitType, daveChan.CommitmentType,
|
||||||
t.t, chansCommitType,
|
"commit types don't match")
|
||||||
daveChan.CommitmentType,
|
|
||||||
"commit types don't match",
|
|
||||||
)
|
|
||||||
|
|
||||||
// Now check that the commitment type reported
|
// Now check that the commitment type reported
|
||||||
// by both nodes is what we expect. It will be
|
// by both nodes is what we expect. It will be
|
||||||
@ -95,7 +94,7 @@ func testBasicChannelFunding(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
expType = lnrpc.CommitmentType_LEGACY
|
expType = lnrpc.CommitmentType_LEGACY
|
||||||
|
|
||||||
default:
|
default:
|
||||||
t.Fatalf("invalid commit type %v", daveCommitType)
|
ht.Fatalf("invalid commit type %v", daveCommitType)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check that the signalled type matches what we
|
// Check that the signalled type matches what we
|
||||||
@ -111,7 +110,7 @@ func testBasicChannelFunding(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
chansCommitType == lnrpc.CommitmentType_LEGACY:
|
chansCommitType == lnrpc.CommitmentType_LEGACY:
|
||||||
|
|
||||||
default:
|
default:
|
||||||
t.Fatalf("expected nodes to signal "+
|
ht.Fatalf("expected nodes to signal "+
|
||||||
"commit type %v, instead got "+
|
"commit type %v, instead got "+
|
||||||
"%v", expType, chansCommitType)
|
"%v", expType, chansCommitType)
|
||||||
}
|
}
|
||||||
@ -133,15 +132,10 @@ test:
|
|||||||
testName := fmt.Sprintf(
|
testName := fmt.Sprintf(
|
||||||
"carol_commit=%v,dave_commit=%v", cc, dc,
|
"carol_commit=%v,dave_commit=%v", cc, dc,
|
||||||
)
|
)
|
||||||
|
success := ht.Run(testName, func(t *testing.T) {
|
||||||
logLine := fmt.Sprintf(
|
st, cleanup := ht.Subtest(t)
|
||||||
"---- basic channel funding subtest %s ----\n",
|
defer cleanup()
|
||||||
testName,
|
testFunding(st, cc, dc)
|
||||||
)
|
|
||||||
net.Alice.AddToLogf(logLine)
|
|
||||||
|
|
||||||
success := t.t.Run(testName, func(t *testing.T) {
|
|
||||||
testFunding(cc, dc)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
if !success {
|
if !success {
|
||||||
@ -155,22 +149,22 @@ test:
|
|||||||
// test. Given two nodes: Alice and Bob, it'll assert proper channel creation,
|
// test. Given two nodes: Alice and Bob, it'll assert proper channel creation,
|
||||||
// then return a function closure that should be called to assert proper
|
// then return a function closure that should be called to assert proper
|
||||||
// channel closure.
|
// channel closure.
|
||||||
func basicChannelFundingTest(t *harnessTest, net *lntest.NetworkHarness,
|
func basicChannelFundingTest(ht *lntemp.HarnessTest,
|
||||||
alice *lntest.HarnessNode, bob *lntest.HarnessNode,
|
alice, bob *node.HarnessNode,
|
||||||
fundingShim *lnrpc.FundingShim) (*lnrpc.Channel, *lnrpc.Channel,
|
fundingShim *lnrpc.FundingShim) (*lnrpc.Channel,
|
||||||
func(), error) {
|
*lnrpc.Channel, func()) {
|
||||||
|
|
||||||
chanAmt := funding.MaxBtcFundingAmount
|
chanAmt := funding.MaxBtcFundingAmount
|
||||||
pushAmt := btcutil.Amount(100000)
|
pushAmt := btcutil.Amount(100000)
|
||||||
satPerVbyte := btcutil.Amount(1)
|
satPerVbyte := btcutil.Amount(1)
|
||||||
|
|
||||||
// Record nodes' channel balance before testing.
|
// Record nodes' channel balance before testing.
|
||||||
aliceChannelBalance := getChannelBalance(t, alice)
|
aliceChannelBalance := alice.RPC.ChannelBalance()
|
||||||
bobChannelBalance := getChannelBalance(t, bob)
|
bobChannelBalance := bob.RPC.ChannelBalance()
|
||||||
|
|
||||||
// Creates a helper closure to be used below which asserts the proper
|
// Creates a helper closure to be used below which asserts the proper
|
||||||
// response to a channel balance RPC.
|
// response to a channel balance RPC.
|
||||||
checkChannelBalance := func(node *lntest.HarnessNode,
|
checkChannelBalance := func(node *node.HarnessNode,
|
||||||
oldChannelBalance *lnrpc.ChannelBalanceResponse,
|
oldChannelBalance *lnrpc.ChannelBalanceResponse,
|
||||||
local, remote btcutil.Amount) {
|
local, remote btcutil.Amount) {
|
||||||
|
|
||||||
@ -186,7 +180,7 @@ func basicChannelFundingTest(t *harnessTest, net *lntest.NetworkHarness,
|
|||||||
)
|
)
|
||||||
// Deprecated fields.
|
// Deprecated fields.
|
||||||
newResp.Balance += int64(local) // nolint:staticcheck
|
newResp.Balance += int64(local) // nolint:staticcheck
|
||||||
assertChannelBalanceResp(t, node, newResp)
|
ht.AssertChannelBalanceResp(node, newResp)
|
||||||
}
|
}
|
||||||
|
|
||||||
// First establish a channel with a capacity of 0.5 BTC between Alice
|
// First establish a channel with a capacity of 0.5 BTC between Alice
|
||||||
@ -195,9 +189,8 @@ func basicChannelFundingTest(t *harnessTest, net *lntest.NetworkHarness,
|
|||||||
// open or an error occurs in the funding process. A series of
|
// open or an error occurs in the funding process. A series of
|
||||||
// assertions will be executed to ensure the funding process completed
|
// assertions will be executed to ensure the funding process completed
|
||||||
// successfully.
|
// successfully.
|
||||||
chanPoint := openChannelAndAssert(
|
chanPoint := ht.OpenChannel(
|
||||||
t, net, alice, bob,
|
alice, bob, lntemp.OpenChannelParams{
|
||||||
lntest.OpenChannelParams{
|
|
||||||
Amt: chanAmt,
|
Amt: chanAmt,
|
||||||
PushAmt: pushAmt,
|
PushAmt: pushAmt,
|
||||||
FundingShim: fundingShim,
|
FundingShim: fundingShim,
|
||||||
@ -205,14 +198,7 @@ func basicChannelFundingTest(t *harnessTest, net *lntest.NetworkHarness,
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
err := alice.WaitForNetworkChannelOpen(chanPoint)
|
cType := ht.GetChannelCommitType(alice, chanPoint)
|
||||||
require.NoError(t.t, err, "alice didn't report channel")
|
|
||||||
|
|
||||||
err = bob.WaitForNetworkChannelOpen(chanPoint)
|
|
||||||
require.NoError(t.t, err, "bob didn't report channel")
|
|
||||||
|
|
||||||
cType, err := channelCommitType(alice, chanPoint)
|
|
||||||
require.NoError(t.t, err, "unable to get channel type")
|
|
||||||
|
|
||||||
// With the channel open, ensure that the amount specified above has
|
// With the channel open, ensure that the amount specified above has
|
||||||
// properly been pushed to Bob.
|
// properly been pushed to Bob.
|
||||||
@ -224,21 +210,17 @@ func basicChannelFundingTest(t *harnessTest, net *lntest.NetworkHarness,
|
|||||||
bob, bobChannelBalance, pushAmt, aliceLocalBalance,
|
bob, bobChannelBalance, pushAmt, aliceLocalBalance,
|
||||||
)
|
)
|
||||||
|
|
||||||
req := &lnrpc.ListChannelsRequest{}
|
aliceChannel := ht.GetChannelByChanPoint(alice, chanPoint)
|
||||||
aliceChannel, err := alice.ListChannels(context.Background(), req)
|
bobChannel := ht.GetChannelByChanPoint(bob, chanPoint)
|
||||||
require.NoError(t.t, err, "unable to obtain chan")
|
|
||||||
|
|
||||||
bobChannel, err := bob.ListChannels(context.Background(), req)
|
|
||||||
require.NoError(t.t, err, "unable to obtain chan")
|
|
||||||
|
|
||||||
closeChan := func() {
|
closeChan := func() {
|
||||||
// Finally, immediately close the channel. This function will
|
// Finally, immediately close the channel. This function will
|
||||||
// also block until the channel is closed and will additionally
|
// also block until the channel is closed and will additionally
|
||||||
// assert the relevant channel closing post conditions.
|
// assert the relevant channel closing post conditions.
|
||||||
closeChannelAndAssert(t, net, alice, chanPoint, false)
|
ht.CloseChannel(alice, chanPoint, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
return aliceChannel.Channels[0], bobChannel.Channels[0], closeChan, nil
|
return aliceChannel, bobChannel, closeChan
|
||||||
}
|
}
|
||||||
|
|
||||||
// testUnconfirmedChannelFunding tests that our unconfirmed change outputs can
|
// testUnconfirmedChannelFunding tests that our unconfirmed change outputs can
|
||||||
@ -478,122 +460,122 @@ func sendAllCoinsConfirm(net *lntest.NetworkHarness, node *lntest.HarnessNode,
|
|||||||
mineBlocks(t, net, 1, 1)
|
mineBlocks(t, net, 1, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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
|
//// channel funding workflow given a channel point that was constructed outside
|
||||||
// the main daemon.
|
//// the main daemon.
|
||||||
func testExternalFundingChanPoint(net *lntest.NetworkHarness, t *harnessTest) {
|
func testExternalFundingChanPoint(net *lntest.NetworkHarness, t *harnessTest) {
|
||||||
ctxb := context.Background()
|
// ctxb := context.Background()
|
||||||
|
|
||||||
// First, we'll create two new nodes that we'll use to open channel
|
// // First, we'll create two new nodes that we'll use to open channel
|
||||||
// between for this test.
|
// // between for this test.
|
||||||
carol := net.NewNode(t.t, "carol", nil)
|
// carol := net.NewNode(t.t, "carol", nil)
|
||||||
defer shutdownAndAssert(net, t, carol)
|
// defer shutdownAndAssert(net, t, carol)
|
||||||
|
|
||||||
dave := net.NewNode(t.t, "dave", nil)
|
// dave := net.NewNode(t.t, "dave", nil)
|
||||||
defer shutdownAndAssert(net, t, dave)
|
// defer shutdownAndAssert(net, t, dave)
|
||||||
|
|
||||||
// Carol will be funding the channel, so we'll send some coins over to
|
// // Carol will be funding the channel, so we'll send some coins over to
|
||||||
// her and ensure they have enough confirmations before we proceed.
|
// // her and ensure they have enough confirmations before we proceed.
|
||||||
net.SendCoins(t.t, btcutil.SatoshiPerBitcoin, carol)
|
// net.SendCoins(t.t, btcutil.SatoshiPerBitcoin, carol)
|
||||||
|
|
||||||
// Before we start the test, we'll ensure both sides are connected to
|
// // Before we start the test, we'll ensure both sides are connected to
|
||||||
// the funding flow can properly be executed.
|
// // the funding flow can properly be executed.
|
||||||
net.EnsureConnected(t.t, carol, dave)
|
// net.EnsureConnected(t.t, carol, dave)
|
||||||
|
|
||||||
// At this point, we're ready to simulate our external channel funding
|
// // At this point, we're ready to simulate our external channel funding
|
||||||
// flow. To start with, we'll create a pending channel with a shim for
|
// // flow. To start with, we'll create a pending channel with a shim for
|
||||||
// a transaction that will never be published.
|
// // a transaction that will never be published.
|
||||||
const thawHeight uint32 = 10
|
// const thawHeight uint32 = 10
|
||||||
const chanSize = funding.MaxBtcFundingAmount
|
// const chanSize = funding.MaxBtcFundingAmount
|
||||||
fundingShim1, chanPoint1, _ := deriveFundingShimOld(
|
// fundingShim1, chanPoint1, _ := deriveFundingShimOld(
|
||||||
net, t, carol, dave, chanSize, thawHeight, false,
|
// net, t, carol, dave, chanSize, thawHeight, false,
|
||||||
)
|
// )
|
||||||
_ = openChannelStream(
|
// _ = openChannelStream(
|
||||||
t, net, carol, dave, lntest.OpenChannelParams{
|
// t, net, carol, dave, lntest.OpenChannelParams{
|
||||||
Amt: chanSize,
|
// Amt: chanSize,
|
||||||
FundingShim: fundingShim1,
|
// FundingShim: fundingShim1,
|
||||||
},
|
// },
|
||||||
)
|
// )
|
||||||
assertNumOpenChannelsPending(t, carol, dave, 1)
|
// assertNumOpenChannelsPending(t, carol, dave, 1)
|
||||||
|
|
||||||
// That channel is now pending forever and normally would saturate the
|
// // That channel is now pending forever and normally would saturate the
|
||||||
// max pending channel limit for both nodes. But because the channel is
|
// // max pending channel limit for both nodes. But because the channel is
|
||||||
// externally funded, we should still be able to open another one. Let's
|
// // externally funded, we should still be able to open another one. Let's
|
||||||
// do exactly that now. For this one we publish the transaction so we
|
// // do exactly that now. For this one we publish the transaction so we
|
||||||
// can mine it later.
|
// // can mine it later.
|
||||||
fundingShim2, chanPoint2, _ := deriveFundingShimOld(
|
// fundingShim2, chanPoint2, _ := deriveFundingShimOld(
|
||||||
net, t, carol, dave, chanSize, thawHeight, true,
|
// net, t, carol, dave, chanSize, thawHeight, true,
|
||||||
)
|
// )
|
||||||
|
|
||||||
// At this point, we'll now carry out the normal basic channel funding
|
// // At this point, we'll now carry out the normal basic channel funding
|
||||||
// test as everything should now proceed as normal (a regular channel
|
// // test as everything should now proceed as normal (a regular channel
|
||||||
// funding flow).
|
// // funding flow).
|
||||||
carolChan, daveChan, _, err := basicChannelFundingTest(
|
// var carolChan, daveChan lnrpc.Channel
|
||||||
t, net, carol, dave, fundingShim2,
|
// carolChan, daveChan, _, err := basicChannelFundingTest(
|
||||||
)
|
// t, net, carol, dave, fundingShim2,
|
||||||
require.NoError(t.t, err)
|
// )
|
||||||
|
|
||||||
// Both channels should be marked as frozen with the proper thaw
|
// // Both channels should be marked as frozen with the proper thaw
|
||||||
// height.
|
// // height.
|
||||||
require.Equal(
|
// require.Equal(
|
||||||
t.t, thawHeight, carolChan.ThawHeight, "thaw height unmatched",
|
// t.t, thawHeight, carolChan.ThawHeight, "thaw height unmatched",
|
||||||
)
|
// )
|
||||||
require.Equal(
|
// require.Equal(
|
||||||
t.t, thawHeight, daveChan.ThawHeight, "thaw height unmatched",
|
// t.t, thawHeight, daveChan.ThawHeight, "thaw height unmatched",
|
||||||
)
|
// )
|
||||||
|
|
||||||
// Next, to make sure the channel functions as normal, we'll make some
|
// // Next, to make sure the channel functions as normal, we'll make some
|
||||||
// payments within the channel.
|
// // payments within the channel.
|
||||||
payAmt := btcutil.Amount(100000)
|
// payAmt := btcutil.Amount(100000)
|
||||||
invoice := &lnrpc.Invoice{
|
// invoice := &lnrpc.Invoice{
|
||||||
Memo: "new chans",
|
// Memo: "new chans",
|
||||||
Value: int64(payAmt),
|
// Value: int64(payAmt),
|
||||||
}
|
// }
|
||||||
ctxt, _ := context.WithTimeout(ctxb, defaultTimeout)
|
// ctxt, _ := context.WithTimeout(ctxb, defaultTimeout)
|
||||||
resp, err := dave.AddInvoice(ctxt, invoice)
|
// resp, err := dave.AddInvoice(ctxt, invoice)
|
||||||
require.NoError(t.t, err)
|
// require.NoError(t.t, err)
|
||||||
err = completePaymentRequests(
|
// err = completePaymentRequests(
|
||||||
carol, carol.RouterClient, []string{resp.PaymentRequest}, true,
|
// carol, carol.RouterClient, []string{resp.PaymentRequest}, true,
|
||||||
)
|
// )
|
||||||
require.NoError(t.t, err)
|
// require.NoError(t.t, err)
|
||||||
|
|
||||||
// Now that the channels are open, and we've confirmed that they're
|
// // Now that the channels are open, and we've confirmed that they're
|
||||||
// operational, we'll now ensure that the channels are frozen as
|
// // operational, we'll now ensure that the channels are frozen as
|
||||||
// intended (if requested).
|
// // intended (if requested).
|
||||||
//
|
// //
|
||||||
// First, we'll try to close the channel as Carol, the initiator. This
|
// // First, we'll try to close the channel as Carol, the initiator. This
|
||||||
// should fail as a frozen channel only allows the responder to
|
// // should fail as a frozen channel only allows the responder to
|
||||||
// initiate a channel close.
|
// // initiate a channel close.
|
||||||
_, _, err = net.CloseChannel(carol, chanPoint2, false)
|
// _, _, err = net.CloseChannel(carol, chanPoint2, false)
|
||||||
require.Error(t.t, err,
|
// require.Error(t.t, err,
|
||||||
"carol wasn't denied a co-op close attempt "+
|
// "carol wasn't denied a co-op close attempt "+
|
||||||
"for a frozen channel",
|
// "for a frozen channel",
|
||||||
)
|
// )
|
||||||
|
|
||||||
// Next we'll try but this time with Dave (the responder) as the
|
// // Next we'll try but this time with Dave (the responder) as the
|
||||||
// initiator. This time the channel should be closed as normal.
|
// // initiator. This time the channel should be closed as normal.
|
||||||
closeChannelAndAssert(t, net, dave, chanPoint2, false)
|
// closeChannelAndAssert(t, net, dave, chanPoint2, false)
|
||||||
|
|
||||||
// As a last step, we check if we still have the pending channel hanging
|
// // As a last step, we check if we still have the pending channel hanging
|
||||||
// around because we never published the funding TX.
|
// // around because we never published the funding TX.
|
||||||
assertNumOpenChannelsPending(t, carol, dave, 1)
|
// assertNumOpenChannelsPending(t, carol, dave, 1)
|
||||||
|
|
||||||
// Let's make sure we can abandon it.
|
// // Let's make sure we can abandon it.
|
||||||
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
|
// ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
|
||||||
_, err = carol.AbandonChannel(ctxt, &lnrpc.AbandonChannelRequest{
|
// _, err = carol.AbandonChannel(ctxt, &lnrpc.AbandonChannelRequest{
|
||||||
ChannelPoint: chanPoint1,
|
// ChannelPoint: chanPoint1,
|
||||||
PendingFundingShimOnly: true,
|
// PendingFundingShimOnly: true,
|
||||||
})
|
// })
|
||||||
require.NoError(t.t, err)
|
// require.NoError(t.t, err)
|
||||||
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
|
// ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
|
||||||
_, err = dave.AbandonChannel(ctxt, &lnrpc.AbandonChannelRequest{
|
// _, err = dave.AbandonChannel(ctxt, &lnrpc.AbandonChannelRequest{
|
||||||
ChannelPoint: chanPoint1,
|
// ChannelPoint: chanPoint1,
|
||||||
PendingFundingShimOnly: true,
|
// PendingFundingShimOnly: true,
|
||||||
})
|
// })
|
||||||
require.NoError(t.t, err)
|
// require.NoError(t.t, err)
|
||||||
|
|
||||||
// It should now not appear in the pending channels anymore.
|
// // It should now not appear in the pending channels anymore.
|
||||||
assertNumOpenChannelsPending(t, carol, dave, 0)
|
// assertNumOpenChannelsPending(t, carol, dave, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
// testFundingPersistence is intended to ensure that the Funding Manager
|
// testFundingPersistence is intended to ensure that the Funding Manager
|
||||||
@ -971,3 +953,97 @@ func testBatchChanFunding(net *lntest.NetworkHarness, t *harnessTest) {
|
|||||||
closeChannelAndAssert(t, net, net.Alice, chanPoint2, false)
|
closeChannelAndAssert(t, net, net.Alice, chanPoint2, false)
|
||||||
closeChannelAndAssert(t, net, net.Alice, chanPoint3, false)
|
closeChannelAndAssert(t, net, net.Alice, chanPoint3, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// deriveFundingShim creates a channel funding shim by deriving the necessary
|
||||||
|
// keys on both sides.
|
||||||
|
func deriveFundingShim(ht *lntemp.HarnessTest,
|
||||||
|
carol, dave *node.HarnessNode, chanSize btcutil.Amount,
|
||||||
|
thawHeight uint32, publish bool) (*lnrpc.FundingShim,
|
||||||
|
*lnrpc.ChannelPoint, *chainhash.Hash) {
|
||||||
|
|
||||||
|
keyLoc := &signrpc.KeyLocator{KeyFamily: 9999}
|
||||||
|
carolFundingKey := carol.RPC.DeriveKey(keyLoc)
|
||||||
|
daveFundingKey := dave.RPC.DeriveKey(keyLoc)
|
||||||
|
|
||||||
|
// Now that we have the multi-sig keys for each party, we can manually
|
||||||
|
// construct the funding transaction. We'll instruct the backend to
|
||||||
|
// immediately create and broadcast a transaction paying out an exact
|
||||||
|
// amount. Normally this would reside in the mempool, but we just
|
||||||
|
// confirm it now for simplicity.
|
||||||
|
_, fundingOutput, err := input.GenFundingPkScript(
|
||||||
|
carolFundingKey.RawKeyBytes, daveFundingKey.RawKeyBytes,
|
||||||
|
int64(chanSize),
|
||||||
|
)
|
||||||
|
require.NoError(ht, err)
|
||||||
|
|
||||||
|
var txid *chainhash.Hash
|
||||||
|
targetOutputs := []*wire.TxOut{fundingOutput}
|
||||||
|
if publish {
|
||||||
|
txid = ht.Miner.SendOutputsWithoutChange(targetOutputs, 5)
|
||||||
|
} else {
|
||||||
|
tx := ht.Miner.CreateTransaction(targetOutputs, 5)
|
||||||
|
|
||||||
|
txHash := tx.TxHash()
|
||||||
|
txid = &txHash
|
||||||
|
}
|
||||||
|
|
||||||
|
// At this point, we can being our external channel funding workflow.
|
||||||
|
// We'll start by generating a pending channel ID externally that will
|
||||||
|
// be used to track this new funding type.
|
||||||
|
pendingChanID := ht.Random32Bytes()
|
||||||
|
|
||||||
|
// Now that we have the pending channel ID, Dave (our responder) will
|
||||||
|
// register the intent to receive a new channel funding workflow using
|
||||||
|
// the pending channel ID.
|
||||||
|
chanPoint := &lnrpc.ChannelPoint{
|
||||||
|
FundingTxid: &lnrpc.ChannelPoint_FundingTxidBytes{
|
||||||
|
FundingTxidBytes: txid[:],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
chanPointShim := &lnrpc.ChanPointShim{
|
||||||
|
Amt: int64(chanSize),
|
||||||
|
ChanPoint: chanPoint,
|
||||||
|
LocalKey: &lnrpc.KeyDescriptor{
|
||||||
|
RawKeyBytes: daveFundingKey.RawKeyBytes,
|
||||||
|
KeyLoc: &lnrpc.KeyLocator{
|
||||||
|
KeyFamily: daveFundingKey.KeyLoc.KeyFamily,
|
||||||
|
KeyIndex: daveFundingKey.KeyLoc.KeyIndex,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
RemoteKey: carolFundingKey.RawKeyBytes,
|
||||||
|
PendingChanId: pendingChanID,
|
||||||
|
ThawHeight: thawHeight,
|
||||||
|
}
|
||||||
|
fundingShim := &lnrpc.FundingShim{
|
||||||
|
Shim: &lnrpc.FundingShim_ChanPointShim{
|
||||||
|
ChanPointShim: chanPointShim,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
dave.RPC.FundingStateStep(&lnrpc.FundingTransitionMsg{
|
||||||
|
Trigger: &lnrpc.FundingTransitionMsg_ShimRegister{
|
||||||
|
ShimRegister: fundingShim,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
// If we attempt to register the same shim (has the same pending chan
|
||||||
|
// ID), then we should get an error.
|
||||||
|
dave.RPC.FundingStateStepAssertErr(&lnrpc.FundingTransitionMsg{
|
||||||
|
Trigger: &lnrpc.FundingTransitionMsg_ShimRegister{
|
||||||
|
ShimRegister: fundingShim,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
// We'll take the chan point shim we just registered for Dave (the
|
||||||
|
// responder), and swap the local/remote keys before we feed it in as
|
||||||
|
// Carol's funding shim as the initiator.
|
||||||
|
fundingShim.GetChanPointShim().LocalKey = &lnrpc.KeyDescriptor{
|
||||||
|
RawKeyBytes: carolFundingKey.RawKeyBytes,
|
||||||
|
KeyLoc: &lnrpc.KeyLocator{
|
||||||
|
KeyFamily: carolFundingKey.KeyLoc.KeyFamily,
|
||||||
|
KeyIndex: carolFundingKey.KeyLoc.KeyIndex,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
fundingShim.GetChanPointShim().RemoteKey = daveFundingKey.RawKeyBytes
|
||||||
|
|
||||||
|
return fundingShim, chanPoint, txid
|
||||||
|
}
|
||||||
|
@ -24,10 +24,6 @@ var allTestCases = []*testCase{
|
|||||||
name: "onchain fund recovery",
|
name: "onchain fund recovery",
|
||||||
test: testOnchainFundRecovery,
|
test: testOnchainFundRecovery,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: "basic funding flow",
|
|
||||||
test: testBasicChannelFunding,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: "basic funding flow with all input types",
|
name: "basic funding flow with all input types",
|
||||||
test: testChannelFundingInputTypes,
|
test: testChannelFundingInputTypes,
|
||||||
|
Loading…
Reference in New Issue
Block a user