lntemp+itest: refactor testOptionScidAlias

This commit is contained in:
yyforyongyu committed 2023-01-18 10:53:55 +08:00
1 parent 15da2a3459
commit 6b82676ca2
4 files changed
+132 -87

No files matched your search

+82 -12
View File
@@ -885,24 +885,76 @@ func (h *HarnessTest) OpenChannelAssertStream(srcNode,
} }
// OpenChannel attempts to open a channel with the specified parameters // OpenChannel attempts to open a channel with the specified parameters
// extended from Alice to Bob. Additionally, the following items are asserted, // extended from Alice to Bob. Additionally, for public channels, it will mine
// - 6 blocks will be mined so the channel will be announced if it's public. // extra blocks so they are announced to the network. In specific, the
// - the funding transaction should be found in the first block. // following items are asserted,
// - for non-zero conf channel, 1 blocks will be mined to confirm the funding
// tx.
// - both nodes should see the channel edge update in their network graph. // - both nodes should see the channel edge update in their network graph.
// - both nodes can report the status of the new channel from ListChannels. // - both nodes can report the status of the new channel from ListChannels.
// - extra blocks are mined if it's a public channel.
func (h *HarnessTest) OpenChannel(alice, bob *node.HarnessNode, func (h *HarnessTest) OpenChannel(alice, bob *node.HarnessNode,
p OpenChannelParams) *lnrpc.ChannelPoint { p OpenChannelParams) *lnrpc.ChannelPoint {
// First, open the channel without announcing it.
cp := h.OpenChannelNoAnnounce(alice, bob, p)
// If this is a private channel, there's no need to mine extra blocks
// since it will never be announced to the network.
if p.Private {
return cp
}
// Mine extra blocks to announce the channel.
if p.ZeroConf {
// For a zero-conf channel, no blocks have been mined so we
// need to mine 6 blocks.
//
// Mine 1 block to confirm the funding transaction.
h.MineBlocksAndAssertNumTxes(numBlocksOpenChannel, 1)
} else {
// For a regular channel, 1 block has already been mined to
// confirm the funding transaction, so we mine 5 blocks.
h.MineBlocks(numBlocksOpenChannel - 1)
}
return cp
}
// OpenChannelNoAnnounce attempts to open a channel with the specified
// parameters extended from Alice to Bob without mining the necessary blocks to
// announce the channel. Additionally, the following items are asserted,
// - for non-zero conf channel, 1 blocks will be mined to confirm the funding
// tx.
// - both nodes should see the channel edge update in their network graph.
// - both nodes can report the status of the new channel from ListChannels.
func (h *HarnessTest) OpenChannelNoAnnounce(alice, bob *node.HarnessNode,
p OpenChannelParams) *lnrpc.ChannelPoint {
chanOpenUpdate := h.OpenChannelAssertStream(alice, bob, p) chanOpenUpdate := h.OpenChannelAssertStream(alice, bob, p)
// Mine 6 blocks, then wait for Alice's node to notify us that the // Open a zero conf channel.
// channel has been opened. The funding transaction should be found if p.ZeroConf {
// within the first newly mined block. We mine 6 blocks so that in the return h.openChannelZeroConf(alice, bob, chanOpenUpdate)
// case that the channel is public, it is announced to the network. }
block := h.MineBlocksAndAssertNumTxes(numBlocksOpenChannel, 1)[0]
// Open a non-zero conf channel.
return h.openChannel(alice, bob, chanOpenUpdate)
}
// openChannel attempts to open a channel with the specified parameters
// extended from Alice to Bob. Additionally, the following items are asserted,
// - 1 block is mined and the funding transaction should be found in it.
// - both nodes should see the channel edge update in their network graph.
// - both nodes can report the status of the new channel from ListChannels.
func (h *HarnessTest) openChannel(alice, bob *node.HarnessNode,
stream rpc.OpenChanClient) *lnrpc.ChannelPoint {
// Mine 1 block to confirm the funding transaction.
block := h.MineBlocksAndAssertNumTxes(1, 1)[0]
// Wait for the channel open event. // Wait for the channel open event.
fundingChanPoint := h.WaitForChannelOpenEvent(chanOpenUpdate) fundingChanPoint := h.WaitForChannelOpenEvent(stream)
// Check that the funding tx is found in the first block. // Check that the funding tx is found in the first block.
fundingTxID := h.GetChanPointFundingTxid(fundingChanPoint) fundingTxID := h.GetChanPointFundingTxid(fundingChanPoint)
@@ -917,9 +969,27 @@ func (h *HarnessTest) OpenChannel(alice, bob *node.HarnessNode,
h.AssertChannelExists(alice, fundingChanPoint) h.AssertChannelExists(alice, fundingChanPoint)
h.AssertChannelExists(bob, fundingChanPoint) h.AssertChannelExists(bob, fundingChanPoint)
// Finally, check the blocks are synced. return fundingChanPoint
h.WaitForBlockchainSync(alice) }
h.WaitForBlockchainSync(bob)
// openChannelZeroConf attempts to open a channel with the specified parameters
// extended from Alice to Bob. Additionally, the following items are asserted,
// - both nodes should see the channel edge update in their network graph.
// - both nodes can report the status of the new channel from ListChannels.
func (h *HarnessTest) openChannelZeroConf(alice, bob *node.HarnessNode,
stream rpc.OpenChanClient) *lnrpc.ChannelPoint {
// Wait for the channel open event.
fundingChanPoint := h.WaitForChannelOpenEvent(stream)
// Check that both alice and bob have seen the channel from their
// network topology.
h.AssertTopologyChannelOpen(alice, fundingChanPoint)
h.AssertTopologyChannelOpen(bob, fundingChanPoint)
// Finally, check that the channel can be seen in their ListChannels.
h.AssertChannelExists(alice, fundingChanPoint)
h.AssertChannelExists(bob, fundingChanPoint)
return fundingChanPoint return fundingChanPoint
} }
+4
View File
@@ -421,4 +421,8 @@ var allTestCasesTemp = []*lntemp.TestCase{
Name: "zero conf channel open", Name: "zero conf channel open",
TestFunc: testZeroConfChannelOpen, TestFunc: testZeroConfChannelOpen,
}, },
{
Name: "option scid alias",
TestFunc: testOptionScidAlias,
},
} }
-4
View File
@@ -56,10 +56,6 @@ var allTestCases = []*testCase{
name: "taproot", name: "taproot",
test: testTaproot, test: testTaproot,
}, },
{
name: "option scid alias",
test: testOptionScidAlias,
},
{ {
name: "scid alias channel update", name: "scid alias channel update",
test: testUpdateChannelPolicyScidAlias, test: testUpdateChannelPolicyScidAlias,
+46 -71
View File
@@ -189,7 +189,7 @@ func testZeroConfChannelOpen(ht *lntemp.HarnessTest) {
// testOptionScidAlias checks that opening an option_scid_alias channel-type // testOptionScidAlias checks that opening an option_scid_alias channel-type
// channel or w/o the channel-type works properly. // channel or w/o the channel-type works properly.
func testOptionScidAlias(net *lntest.NetworkHarness, t *harnessTest) { func testOptionScidAlias(ht *lntemp.HarnessTest) {
type scidTestCase struct { type scidTestCase struct {
name string name string
@@ -220,10 +220,10 @@ func testOptionScidAlias(net *lntest.NetworkHarness, t *harnessTest) {
for _, testCase := range testCases { for _, testCase := range testCases {
testCase := testCase testCase := testCase
success := t.t.Run(testCase.name, func(t *testing.T) { success := ht.Run(testCase.name, func(t *testing.T) {
h := newHarnessTest(t, net) st := ht.Subtest(t)
optionScidAliasScenario( optionScidAliasScenario(
net, h, testCase.chantype, testCase.private, st, testCase.chantype, testCase.private,
) )
}) })
if !success { if !success {
@@ -232,110 +232,89 @@ func testOptionScidAlias(net *lntest.NetworkHarness, t *harnessTest) {
} }
} }
func optionScidAliasScenario(net *lntest.NetworkHarness, t *harnessTest, func optionScidAliasScenario(ht *lntemp.HarnessTest, chantype, private bool) {
chantype, private bool) {
ctxb := context.Background()
// Option-scid-alias is opt-in, as is anchors. // Option-scid-alias is opt-in, as is anchors.
scidAliasArgs := []string{ scidAliasArgs := []string{
"--protocol.option-scid-alias", "--protocol.option-scid-alias",
"--protocol.anchors", "--protocol.anchors",
} }
carol := net.NewNode(t.t, "Carol", scidAliasArgs) bob := ht.Bob
defer shutdownAndAssert(net, t, carol) carol := ht.NewNode("Carol", scidAliasArgs)
dave := ht.NewNode("Dave", scidAliasArgs)
dave := net.NewNode(t.t, "Dave", scidAliasArgs)
defer shutdownAndAssert(net, t, dave)
// Ensure Bob, Carol are connected. // Ensure Bob, Carol are connected.
net.EnsureConnected(t.t, net.Bob, carol) ht.EnsureConnected(bob, carol)
// Ensure Carol, Dave are connected. // Ensure Carol, Dave are connected.
net.EnsureConnected(t.t, carol, dave) ht.EnsureConnected(carol, dave)
// Give Carol some coins so she can open the channel. // Give Carol some coins so she can open the channel.
net.SendCoins(t.t, btcutil.SatoshiPerBitcoin, carol) ht.FundCoins(btcutil.SatoshiPerBitcoin, carol)
chanAmt := btcutil.Amount(1_000_000) chanAmt := btcutil.Amount(1_000_000)
params := lntest.OpenChannelParams{ params := lntemp.OpenChannelParams{
Amt: chanAmt, Amt: chanAmt,
Private: private, Private: private,
CommitmentType: lnrpc.CommitmentType_ANCHORS, CommitmentType: lnrpc.CommitmentType_ANCHORS,
ScidAlias: chantype, ScidAlias: chantype,
} }
fundingPoint := openChannelAndAssert(t, net, carol, dave, params) fundingPoint := ht.OpenChannel(carol, dave, params)
// Make sure Bob knows this channel if it's public.
if !private { if !private {
err := net.Bob.WaitForNetworkChannelOpen(fundingPoint) ht.AssertTopologyChannelOpen(bob, fundingPoint)
require.NoError(t.t, err, "bob didn't report channel")
} }
err := carol.WaitForNetworkChannelOpen(fundingPoint)
require.NoError(t.t, err, "carol didn't report channel")
err = dave.WaitForNetworkChannelOpen(fundingPoint)
require.NoError(t.t, err, "dave didn't report channel")
// Assert that a payment from Carol to Dave works as expected. // Assert that a payment from Carol to Dave works as expected.
daveInvoiceParams := &lnrpc.Invoice{ daveInvoiceParams := &lnrpc.Invoice{
Value: int64(10_000), Value: int64(10_000),
Private: true, Private: true,
} }
daveInvoiceResp, err := dave.AddInvoice(ctxb, daveInvoiceParams) daveInvoiceResp := dave.RPC.AddInvoice(daveInvoiceParams)
require.NoError(t.t, err) ht.CompletePaymentRequests(
_ = sendAndAssertSuccess( carol, []string{daveInvoiceResp.PaymentRequest},
t, carol, &routerrpc.SendPaymentRequest{
PaymentRequest: daveInvoiceResp.PaymentRequest,
TimeoutSeconds: 60,
FeeLimitMsat: noFeeLimitMsat,
},
) )
// We'll now open a regular public channel between Bob and Carol and // We'll now open a regular public channel between Bob and Carol and
// assert that Bob can pay Dave. We'll also assert that the invoice // assert that Bob can pay Dave. We'll also assert that the invoice
// Dave issues has the startingAlias as a hop hint. // Dave issues has the startingAlias as a hop hint.
fundingPoint2 := openChannelAndAssert( p := lntemp.OpenChannelParams{
t, net, net.Bob, carol, Amt: chanAmt,
lntest.OpenChannelParams{ }
Amt: chanAmt, fundingPoint2 := ht.OpenChannel(bob, carol, p)
},
)
err = net.Bob.WaitForNetworkChannelOpen(fundingPoint2) defer func() {
require.NoError(t.t, err) // TODO(yy): remove the sleep once the following bug is fixed.
err = carol.WaitForNetworkChannelOpen(fundingPoint2) // When the payment is reported as settled by Bob, it's
require.NoError(t.t, err) // expected the commitment dance is finished and all subsequent
// states have been updated. Yet we'd receive the error `cannot
// co-op close channel with active htlcs` or `link failed to
// shutdown` if we close the channel. We need to investigate
// the order of settling the payments and updating commitments
// to understand and fix.
time.Sleep(2 * time.Second)
// Close standby node's channels.
ht.CloseChannel(bob, fundingPoint2)
}()
// Wait until Dave receives the Bob<->Carol channel. // Wait until Dave receives the Bob<->Carol channel.
err = dave.WaitForNetworkChannelOpen(fundingPoint2) ht.AssertTopologyChannelOpen(dave, fundingPoint2)
require.NoError(t.t, err)
daveInvoiceResp2, err := dave.AddInvoice(ctxb, daveInvoiceParams) daveInvoiceResp2 := dave.RPC.AddInvoice(daveInvoiceParams)
require.NoError(t.t, err) decodedReq := dave.RPC.DecodePayReq(daveInvoiceResp2.PaymentRequest)
davePayReq := &lnrpc.PayReqString{
PayReq: daveInvoiceResp2.PaymentRequest,
}
decodedReq, err := dave.DecodePayReq(ctxb, davePayReq)
require.NoError(t.t, err)
if !private { if !private {
require.Equal(t.t, 0, len(decodedReq.RouteHints)) require.Len(ht, decodedReq.RouteHints, 0)
payReq := daveInvoiceResp2.PaymentRequest payReq := daveInvoiceResp2.PaymentRequest
_ = sendAndAssertSuccess( ht.CompletePaymentRequests(bob, []string{payReq})
t, net.Bob, &routerrpc.SendPaymentRequest{
PaymentRequest: payReq,
TimeoutSeconds: 60,
FeeLimitMsat: noFeeLimitMsat,
},
)
return return
} }
require.Equal(t.t, 1, len(decodedReq.RouteHints)) require.Len(ht, decodedReq.RouteHints, 1)
require.Equal(t.t, 1, len(decodedReq.RouteHints[0].HopHints)) require.Len(ht, decodedReq.RouteHints[0].HopHints, 1)
startingAlias := lnwire.ShortChannelID{ startingAlias := lnwire.ShortChannelID{
BlockHeight: 16_000_000, BlockHeight: 16_000_000,
@@ -344,14 +323,10 @@ func optionScidAliasScenario(net *lntest.NetworkHarness, t *harnessTest,
} }
daveHopHint := decodedReq.RouteHints[0].HopHints[0].ChanId daveHopHint := decodedReq.RouteHints[0].HopHints[0].ChanId
require.Equal(t.t, startingAlias.ToUint64(), daveHopHint) require.Equal(ht, startingAlias.ToUint64(), daveHopHint)
_ = sendAndAssertSuccess( ht.CompletePaymentRequests(
t, net.Bob, &routerrpc.SendPaymentRequest{ bob, []string{daveInvoiceResp2.PaymentRequest},
PaymentRequest: daveInvoiceResp2.PaymentRequest,
TimeoutSeconds: 60,
FeeLimitMsat: noFeeLimitMsat,
},
) )
} }