Skip to content

Commit dadd22a

Browse files
committed
itest: add account system integration tests
1 parent 3f567a9 commit dadd22a

File tree

5 files changed

+608
-12
lines changed

5 files changed

+608
-12
lines changed

itest/assertions.go

Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
package itest
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
"github.com/btcsuite/btcd/chaincfg/chainhash"
8+
"github.com/btcsuite/btcd/wire"
9+
"github.com/lightningnetwork/lnd/channeldb"
10+
"github.com/lightningnetwork/lnd/lnrpc"
11+
"github.com/lightningnetwork/lnd/lntest"
12+
"github.com/lightningnetwork/lnd/lntest/wait"
13+
"github.com/stretchr/testify/require"
14+
)
15+
16+
// shutdownAndAssert shuts down the given node and asserts that no errors
17+
// occur.
18+
func shutdownAndAssert(net *NetworkHarness, t *harnessTest,
19+
node *HarnessNode) {
20+
21+
// The process may not be in a state to always shutdown immediately, so
22+
// we'll retry up to a hard limit to ensure we eventually shutdown.
23+
err := wait.NoError(func() error {
24+
return net.ShutdownNode(node)
25+
}, defaultTimeout)
26+
require.NoErrorf(t.t, err, "unable to shutdown %v", node.Name())
27+
}
28+
29+
// openChannelAndAssert attempts to open a channel with the specified
30+
// parameters extended from Alice to Bob. Additionally, two items are asserted
31+
// after the channel is considered open: the funding transaction should be
32+
// found within a block, and that Alice can report the status of the new
33+
// channel.
34+
func openChannelAndAssert(t *harnessTest, net *NetworkHarness, alice,
35+
bob *HarnessNode, p lntest.OpenChannelParams) *lnrpc.ChannelPoint {
36+
37+
t.t.Helper()
38+
39+
chanOpenUpdate := openChannelStream(t, net, alice, bob, p)
40+
41+
// Mine 6 blocks, then wait for Alice's node to notify us that the
42+
// channel has been opened. The funding transaction should be found
43+
// within the first newly mined block. We mine 6 blocks so that in the
44+
// case that the channel is public, it is announced to the network.
45+
block := mineBlocks(t, net, 6, 1)[0]
46+
47+
fundingChanPoint, err := net.WaitForChannelOpen(chanOpenUpdate)
48+
require.NoError(t.t, err, "error while waiting for channel open")
49+
50+
fundingTxID, err := lnrpc.GetChanPointFundingTxid(fundingChanPoint)
51+
require.NoError(t.t, err, "unable to get txid")
52+
53+
assertTxInBlock(t, block, fundingTxID)
54+
55+
// The channel should be listed in the peer information returned by
56+
// both peers.
57+
chanPoint := wire.OutPoint{
58+
Hash: *fundingTxID,
59+
Index: fundingChanPoint.OutputIndex,
60+
}
61+
require.NoError(
62+
t.t, net.AssertChannelExists(alice, &chanPoint),
63+
"unable to assert channel existence",
64+
)
65+
require.NoError(
66+
t.t, net.AssertChannelExists(bob, &chanPoint),
67+
"unable to assert channel existence",
68+
)
69+
70+
return fundingChanPoint
71+
}
72+
73+
// openChannelStream blocks until an OpenChannel request for a channel funding
74+
// by alice succeeds. If it does, a stream client is returned to receive events
75+
// about the opening channel.
76+
func openChannelStream(t *harnessTest, net *NetworkHarness, alice,
77+
bob *HarnessNode,
78+
p lntest.OpenChannelParams) lnrpc.Lightning_OpenChannelClient {
79+
80+
t.t.Helper()
81+
82+
// Wait until we are able to fund a channel successfully. This wait
83+
// prevents us from erroring out when trying to create a channel while
84+
// the node is starting up.
85+
var chanOpenUpdate lnrpc.Lightning_OpenChannelClient
86+
err := wait.NoError(func() error {
87+
var err error
88+
chanOpenUpdate, err = net.OpenChannel(alice, bob, p)
89+
return err
90+
}, defaultTimeout)
91+
require.NoError(t.t, err, "unable to open channel")
92+
93+
return chanOpenUpdate
94+
}
95+
96+
// closeChannelAndAssert attempts to close a channel identified by the passed
97+
// channel point owned by the passed Lightning node. A fully blocking channel
98+
// closure is attempted, therefore the passed context should be a child derived
99+
// via timeout from a base parent. Additionally, once the channel has been
100+
// detected as closed, an assertion checks that the transaction is found within
101+
// a block. Finally, this assertion verifies that the node always sends out a
102+
// disable update when closing the channel if the channel was previously
103+
// enabled.
104+
//
105+
// NOTE: This method assumes that the provided funding point is confirmed
106+
// on-chain AND that the edge exists in the node's channel graph. If the funding
107+
// transactions was reorged out at some point, use closeReorgedChannelAndAssert.
108+
func closeChannelAndAssert(t *harnessTest, net *NetworkHarness,
109+
node *HarnessNode, fundingChanPoint *lnrpc.ChannelPoint,
110+
force bool) *chainhash.Hash {
111+
112+
ctxb := context.Background()
113+
ctxt, cancel := context.WithTimeout(ctxb, defaultTimeout)
114+
defer cancel()
115+
116+
closeUpdates, _, err := net.CloseChannel(node, fundingChanPoint, force)
117+
require.NoError(t.t, err, "unable to close channel")
118+
119+
return assertChannelClosed(
120+
ctxt, t, net, node, fundingChanPoint, closeUpdates,
121+
)
122+
}
123+
124+
// assertChannelClosed asserts that the channel is properly cleaned up after
125+
// initiating a cooperative or local close.
126+
func assertChannelClosed(ctx context.Context, t *harnessTest,
127+
net *NetworkHarness, node *HarnessNode,
128+
fundingChanPoint *lnrpc.ChannelPoint,
129+
closeUpdates lnrpc.Lightning_CloseChannelClient) *chainhash.Hash {
130+
131+
txid, err := lnrpc.GetChanPointFundingTxid(fundingChanPoint)
132+
require.NoError(t.t, err, "unable to get txid")
133+
chanPointStr := fmt.Sprintf("%v:%v", txid, fundingChanPoint.OutputIndex)
134+
135+
// If the channel appears in list channels, ensure that its state
136+
// contains ChanStatusCoopBroadcasted.
137+
listChansRequest := &lnrpc.ListChannelsRequest{}
138+
listChansResp, err := node.ListChannels(ctx, listChansRequest)
139+
require.NoError(t.t, err, "unable to query for list channels")
140+
141+
for _, channel := range listChansResp.Channels {
142+
// Skip other channels.
143+
if channel.ChannelPoint != chanPointStr {
144+
continue
145+
}
146+
147+
// Assert that the channel is in coop broadcasted.
148+
require.Contains(
149+
t.t, channel.ChanStatusFlags,
150+
channeldb.ChanStatusCoopBroadcasted.String(),
151+
"channel not coop broadcasted",
152+
)
153+
}
154+
155+
// At this point, the channel should now be marked as being in the
156+
// state of "waiting close".
157+
pendingChansRequest := &lnrpc.PendingChannelsRequest{}
158+
pendingChanResp, err := node.PendingChannels(ctx, pendingChansRequest)
159+
require.NoError(t.t, err, "unable to query for pending channels")
160+
161+
var found bool
162+
for _, pendingClose := range pendingChanResp.WaitingCloseChannels {
163+
if pendingClose.Channel.ChannelPoint == chanPointStr {
164+
found = true
165+
break
166+
}
167+
}
168+
require.True(t.t, found, "channel not marked as waiting close")
169+
170+
// We'll now, generate a single block, wait for the final close status
171+
// update, then ensure that the closing transaction was included in the
172+
// block.
173+
block := mineBlocks(t, net, 1, 1)[0]
174+
175+
closingTxid, err := net.WaitForChannelClose(closeUpdates)
176+
require.NoError(t.t, err, "error while waiting for channel close")
177+
178+
assertTxInBlock(t, block, closingTxid)
179+
180+
// Finally, the transaction should no longer be in the waiting close
181+
// state as we've just mined a block that should include the closing
182+
// transaction.
183+
err = wait.Predicate(func() bool {
184+
pendingChansRequest := &lnrpc.PendingChannelsRequest{}
185+
pendingChanResp, err := node.PendingChannels(
186+
ctx, pendingChansRequest,
187+
)
188+
if err != nil {
189+
return false
190+
}
191+
192+
for _, pendingClose := range pendingChanResp.WaitingCloseChannels {
193+
if pendingClose.Channel.ChannelPoint == chanPointStr {
194+
return false
195+
}
196+
}
197+
198+
return true
199+
}, defaultTimeout)
200+
require.NoError(
201+
t.t, err, "closing transaction not marked as fully closed",
202+
)
203+
204+
return closingTxid
205+
}

0 commit comments

Comments
 (0)