Skip to content

Commit 444021f

Browse files
GeorgeTsagkguggero
authored andcommitted
itest: custom channels flakes fixes
1 parent 9d3f02e commit 444021f

File tree

2 files changed

+140
-65
lines changed

2 files changed

+140
-65
lines changed

itest/litd_custom_channels_test.go

Lines changed: 95 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,9 @@ var (
9999
)
100100

101101
const (
102-
fundingAmount = 50_000
102+
fundingAmount = 50_000
103+
eventuallyTimeout = time.Second * 30
104+
eventuallyTicker = time.Millisecond * 250
103105
)
104106

105107
// testCustomChannels tests that we can create a network with custom channels
@@ -380,13 +382,23 @@ func testCustomChannels(_ context.Context, net *NetworkHarness,
380382
assertAssetChan(t.t, dave, yara, daveFundingAmount, assetID)
381383
assertAssetChan(t.t, erin, fabia, erinFundingAmount, assetID)
382384

385+
// Before we start sending out payments, let's make sure each node can
386+
// see the other one in the graph and has all required features.
387+
require.NoError(t.t, t.lndHarness.AssertNodeKnown(charlie, dave))
388+
require.NoError(t.t, t.lndHarness.AssertNodeKnown(dave, charlie))
389+
require.NoError(t.t, t.lndHarness.AssertNodeKnown(dave, yara))
390+
require.NoError(t.t, t.lndHarness.AssertNodeKnown(yara, dave))
391+
require.NoError(t.t, t.lndHarness.AssertNodeKnown(erin, fabia))
392+
require.NoError(t.t, t.lndHarness.AssertNodeKnown(fabia, erin))
393+
require.NoError(t.t, t.lndHarness.AssertNodeKnown(charlie, erin))
394+
383395
// Print initial channel balances.
384396
logBalance(t.t, nodes, assetID, "initial")
385397

386398
// ------------
387399
// Test case 1: Send a direct keysend payment from Charlie to Dave.
388400
// ------------
389-
const keySendAmount = 100
401+
const keySendAmount = 1000
390402
sendAssetKeySendPayment(
391403
t.t, charlie, dave, keySendAmount, assetID, fn.None[int64](),
392404
)
@@ -395,6 +407,12 @@ func testCustomChannels(_ context.Context, net *NetworkHarness,
395407
charlieAssetBalance -= keySendAmount
396408
daveAssetBalance += keySendAmount
397409

410+
require.Eventually(t.t, func() bool {
411+
local, _ := getAssetChannelBalance(t.t, dave, assetID, false)
412+
413+
return local == daveAssetBalance
414+
}, eventuallyTimeout, eventuallyTicker)
415+
398416
// We should be able to send the 100 assets back immediately, because
399417
// there is enough on-chain balance on Dave's side to be able to create
400418
// an HTLC.
@@ -723,18 +741,16 @@ func testCustomChannelsGroupedAsset(_ context.Context, net *NetworkHarness,
723741
fabiaTap := newTapClient(t.t, fabia)
724742
yaraTap := newTapClient(t.t, yara)
725743

726-
groupAsset := itestAsset
727-
groupAsset.NewGroupedAsset = true
744+
groupAssetReq := itest.CopyRequest(&mintrpc.MintAssetRequest{
745+
Asset: itestAsset,
746+
})
747+
groupAssetReq.Asset.NewGroupedAsset = true
728748

729749
// Mint an asset on Charlie and sync all nodes to Charlie as the
730750
// universe.
731751
mintedAssets := itest.MintAssetsConfirmBatch(
732752
t.t, t.lndHarness.Miner.Client, charlieTap,
733-
[]*mintrpc.MintAssetRequest{
734-
{
735-
Asset: groupAsset,
736-
},
737-
},
753+
[]*mintrpc.MintAssetRequest{groupAssetReq},
738754
)
739755

740756
cents := mintedAssets[0]
@@ -924,13 +940,23 @@ func testCustomChannelsGroupedAsset(_ context.Context, net *NetworkHarness,
924940
assertAssetChan(t.t, dave, yara, daveFundingAmount, assetID)
925941
assertAssetChan(t.t, erin, fabia, erinFundingAmount, assetID)
926942

943+
// Before we start sending out payments, let's make sure each node can
944+
// see the other one in the graph and has all required features.
945+
require.NoError(t.t, t.lndHarness.AssertNodeKnown(charlie, dave))
946+
require.NoError(t.t, t.lndHarness.AssertNodeKnown(dave, charlie))
947+
require.NoError(t.t, t.lndHarness.AssertNodeKnown(dave, yara))
948+
require.NoError(t.t, t.lndHarness.AssertNodeKnown(yara, dave))
949+
require.NoError(t.t, t.lndHarness.AssertNodeKnown(erin, fabia))
950+
require.NoError(t.t, t.lndHarness.AssertNodeKnown(fabia, erin))
951+
require.NoError(t.t, t.lndHarness.AssertNodeKnown(charlie, erin))
952+
927953
// Print initial channel balances.
928954
logBalance(t.t, nodes, assetID, "initial")
929955

930956
// ------------
931957
// Test case 1: Send a direct keysend payment from Charlie to Dave.
932958
// ------------
933-
const keySendAmount = 100
959+
const keySendAmount = 1000
934960
sendAssetKeySendPayment(
935961
t.t, charlie, dave, keySendAmount, assetID, fn.None[int64](),
936962
)
@@ -939,6 +965,12 @@ func testCustomChannelsGroupedAsset(_ context.Context, net *NetworkHarness,
939965
charlieAssetBalance -= keySendAmount
940966
daveAssetBalance += keySendAmount
941967

968+
require.Eventually(t.t, func() bool {
969+
local, _ := getAssetChannelBalance(t.t, dave, assetID, false)
970+
971+
return local == daveAssetBalance
972+
}, eventuallyTimeout, eventuallyTicker)
973+
942974
// We should be able to send the 100 assets back immediately, because
943975
// there is enough on-chain balance on Dave's side to be able to create
944976
// an HTLC.
@@ -1261,7 +1293,7 @@ func testCustomChannelsForceClose(_ context.Context, net *NetworkHarness,
12611293
t.Logf("Funded channel between Charlie and Dave: %v", assetFundResp)
12621294

12631295
// With the channel open, mine a block to confirm it.
1264-
mineBlocks(t, net, 6, 1)
1296+
mineBlocksSlow(t, net, 6, 1)
12651297

12661298
// A transfer for the funding transaction should be found in Charlie's
12671299
// DB.
@@ -1276,9 +1308,7 @@ func testCustomChannelsForceClose(_ context.Context, net *NetworkHarness,
12761308

12771309
// Charlie's balance should reflect that the funding asset was added to
12781310
// the DB.
1279-
assertAssetBalance(
1280-
t.t, charlieTap, assetID, uint64(itestAsset.Amount),
1281-
)
1311+
assertAssetBalance(t.t, charlieTap, assetID, itestAsset.Amount)
12821312

12831313
// Make sure that Charlie properly uploaded funding proof to the
12841314
// Universe server.
@@ -1291,6 +1321,14 @@ func testCustomChannelsForceClose(_ context.Context, net *NetworkHarness,
12911321
),
12921322
)
12931323

1324+
// Make sure the channel shows the correct asset information.
1325+
assertAssetChan(t.t, charlie, dave, fundingAmount, assetID)
1326+
1327+
// Before we start sending out payments, let's make sure each node can
1328+
// see the other one in the graph and has all required features.
1329+
require.NoError(t.t, t.lndHarness.AssertNodeKnown(charlie, dave))
1330+
require.NoError(t.t, t.lndHarness.AssertNodeKnown(dave, charlie))
1331+
12941332
// We'll also have dave sync with Charlie+Zane to ensure he has the
12951333
// proof for the funding output. We sync the transfers as well so he
12961334
// has all the proofs needed.
@@ -1441,22 +1479,6 @@ func testCustomChannelsForceClose(_ context.Context, net *NetworkHarness,
14411479
t.t, charlieSweepTransfer,
14421480
))
14431481

1444-
charlieUTXOs, err := charlieTap.ListUtxos(
1445-
ctxb, &taprpc.ListUtxosRequest{},
1446-
)
1447-
require.NoError(t.t, err)
1448-
1449-
t.Logf("Charlie UTXOs: %v", toProtoJSON(t.t, charlieUTXOs))
1450-
1451-
daveUTXOs, err := daveTap.ListUtxos(
1452-
ctxb, &taprpc.ListUtxosRequest{},
1453-
)
1454-
require.NoError(t.t, err)
1455-
1456-
t.Logf("Dave UTXOs: %v", toProtoJSON(t.t, daveUTXOs))
1457-
1458-
// TODO(roasbeef): assert 2 charlie UTXOs
1459-
14601482
// Both sides should now reflect their updated asset balances.
14611483
daveBalance := uint64(numPayments * keySendAmount)
14621484
charlieBalance := itestAsset.Amount - daveBalance
@@ -1465,26 +1487,12 @@ func testCustomChannelsForceClose(_ context.Context, net *NetworkHarness,
14651487

14661488
// Dave should have a single managed UTXO that shows he has a new asset
14671489
// UTXO he can use.
1468-
err = wait.NoError(func() error {
1469-
daveUTXOs, err = daveTap.ListUtxos(
1470-
ctxb, &taprpc.ListUtxosRequest{},
1471-
)
1472-
if err != nil {
1473-
return err
1474-
}
1475-
1476-
if len(daveUTXOs.ManagedUtxos) != 1 {
1477-
return fmt.Errorf("expected 1 UTXO, got %d",
1478-
len(daveUTXOs.ManagedUtxos))
1479-
}
1480-
1481-
return nil
1482-
}, defaultTimeout)
1483-
require.NoError(t.t, err)
1484-
1485-
t.Logf("Dave UTXOs: %v", toProtoJSON(t.t, daveUTXOs))
1490+
assertNumAssetUTXOs(t.t, daveTap, 1)
1491+
assertNumAssetUTXOs(t.t, charlieTap, 2)
14861492
}
14871493

1494+
// testCustomChannelsBreach tests a force close scenario that breaches an old
1495+
// state, after both parties have an active asset balance.
14881496
func testCustomChannelsBreach(_ context.Context, net *NetworkHarness,
14891497
t *harnessTest) {
14901498

@@ -1528,6 +1536,7 @@ func testCustomChannelsBreach(_ context.Context, net *NetworkHarness,
15281536
connectAllNodes(t.t, net, nodes)
15291537
fundAllNodes(t.t, net, nodes)
15301538

1539+
universeTap := newTapClient(t.t, zane)
15311540
charlieTap := newTapClient(t.t, charlie)
15321541
daveTap := newTapClient(t.t, dave)
15331542

@@ -1569,7 +1578,39 @@ func testCustomChannelsBreach(_ context.Context, net *NetworkHarness,
15691578
// With the channel open, mine a block to confirm it.
15701579
mineBlocks(t, net, 6, 1)
15711580

1572-
time.Sleep(time.Second * 1)
1581+
// A transfer for the funding transaction should be found in Charlie's
1582+
// DB.
1583+
fundingTxid, err := chainhash.NewHashFromStr(assetFundResp.Txid)
1584+
require.NoError(t.t, err)
1585+
assetFundingTransfer := locateAssetTransfers(
1586+
t.t, charlieTap, *fundingTxid,
1587+
)
1588+
1589+
t.Logf("Channel funding transfer: %v",
1590+
toProtoJSON(t.t, assetFundingTransfer))
1591+
1592+
// Charlie's balance should reflect that the funding asset was added to
1593+
// the DB.
1594+
assertAssetBalance(t.t, charlieTap, assetID, itestAsset.Amount)
1595+
1596+
// Make sure that Charlie properly uploaded funding proof to the
1597+
// Universe server.
1598+
fundingScriptTree := tapchannel.NewFundingScriptTree()
1599+
fundingScriptKey := fundingScriptTree.TaprootKey
1600+
fundingScriptTreeBytes := fundingScriptKey.SerializeCompressed()
1601+
assertUniverseProofExists(
1602+
t.t, universeTap, assetID, fundingScriptTreeBytes, fmt.Sprintf(
1603+
"%v:%v", assetFundResp.Txid, assetFundResp.OutputIndex,
1604+
),
1605+
)
1606+
1607+
// Make sure the channel shows the correct asset information.
1608+
assertAssetChan(t.t, charlie, dave, fundingAmount, assetID)
1609+
1610+
// Before we start sending out payments, let's make sure each node can
1611+
// see the other one in the graph and has all required features.
1612+
require.NoError(t.t, t.lndHarness.AssertNodeKnown(charlie, dave))
1613+
require.NoError(t.t, t.lndHarness.AssertNodeKnown(dave, charlie))
15731614

15741615
// Next, we'll make keysend payments from Charlie to Dave. we'll use
15751616
// this to reach a state where both parties have funds in the channel.
@@ -1672,8 +1713,10 @@ func assertNumAssetUTXOs(t *testing.T, tapdClient *tapClient,
16721713

16731714
ctxb := context.Background()
16741715

1716+
var clientUTXOs *taprpc.ListUtxosResponse
16751717
err := wait.NoError(func() error {
1676-
clientUTXOs, err := tapdClient.ListUtxos(
1718+
var err error
1719+
clientUTXOs, err = tapdClient.ListUtxos(
16771720
ctxb, &taprpc.ListUtxosRequest{},
16781721
)
16791722
if err != nil {
@@ -1687,21 +1730,8 @@ func assertNumAssetUTXOs(t *testing.T, tapdClient *tapClient,
16871730

16881731
return nil
16891732
}, defaultTimeout)
1690-
1691-
clientUTXOs, err2 := tapdClient.ListUtxos(
1692-
ctxb, &taprpc.ListUtxosRequest{},
1693-
)
1694-
require.NoError(t, err2)
1695-
1696-
if err != nil {
1697-
t.Logf("wrong amount of UTXOs, got %d, expected %d: %v",
1698-
len(clientUTXOs.ManagedUtxos), numUTXOs,
1699-
toProtoJSON(t, clientUTXOs))
1700-
1701-
t.Fatalf("failed to assert UTXOs: %v", err)
1702-
1703-
return nil
1704-
}
1733+
require.NoErrorf(t, err, "failed to assert UTXOs: %v, last state: %v",
1734+
err, clientUTXOs)
17051735

17061736
return clientUTXOs
17071737
}

itest/network_harness.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
"github.com/lightningnetwork/lnd/lntest/node"
2626
"github.com/lightningnetwork/lnd/lntest/port"
2727
"github.com/lightningnetwork/lnd/lntest/wait"
28+
"github.com/lightningnetwork/lnd/lnwire"
2829
"github.com/stretchr/testify/require"
2930
"golang.org/x/sync/errgroup"
3031
"google.golang.org/grpc/grpclog"
@@ -1180,6 +1181,50 @@ func (n *NetworkHarness) AssertChannelExists(node *HarnessNode,
11801181
}, lntest.DefaultTimeout)
11811182
}
11821183

1184+
// AssertNodeKnown makes sure the given node knows about the target node in the
1185+
// network graph.
1186+
func (n *NetworkHarness) AssertNodeKnown(node, target *HarnessNode) error {
1187+
ctxb := context.Background()
1188+
ctxt, cancel := context.WithTimeout(ctxb, wait.DefaultTimeout)
1189+
defer cancel()
1190+
1191+
req := &lnrpc.NodeInfoRequest{
1192+
PubKey: hex.EncodeToString(
1193+
target.PubKey[:],
1194+
),
1195+
}
1196+
return wait.NoError(func() error {
1197+
info, err := node.GetNodeInfo(ctxt, req)
1198+
if err != nil {
1199+
return err
1200+
}
1201+
1202+
if info.Node == nil {
1203+
return fmt.Errorf("node %x has no info about %x",
1204+
node.PubKey[:], target.PubKey[:])
1205+
}
1206+
1207+
if len(info.Node.Features) == 0 {
1208+
return fmt.Errorf("node %x has no features for %x",
1209+
node.PubKey[:], target.PubKey[:])
1210+
}
1211+
1212+
_, optional := info.Node.Features[uint32(
1213+
lnwire.TLVOnionPayloadOptional,
1214+
)]
1215+
_, required := info.Node.Features[uint32(
1216+
lnwire.TLVOnionPayloadRequired,
1217+
)]
1218+
if !optional && !required {
1219+
return fmt.Errorf("node %x has no onion payload "+
1220+
"features for %x", node.PubKey[:],
1221+
target.PubKey[:])
1222+
}
1223+
1224+
return nil
1225+
}, lntest.DefaultTimeout)
1226+
}
1227+
11831228
// DumpLogs reads the current logs generated by the passed node, and returns
11841229
// the logs as a single string. This function is useful for examining the logs
11851230
// of a particular node in the case of a test failure.

0 commit comments

Comments
 (0)