Skip to content

Commit a067aa4

Browse files
committed
itest: add flakeInconsistentHTLCView
1 parent 053d63e commit a067aa4

File tree

3 files changed

+41
-0
lines changed

3 files changed

+41
-0
lines changed

itest/flakes.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,3 +104,41 @@ func flakeSkipPendingSweepsCheckDarwin(ht *lntest.HarnessTest,
104104
func isDarwin() bool {
105105
return runtime.GOOS == "darwin"
106106
}
107+
108+
// flakeInconsistentHTLCView documents a flake found that the `ListChannels` RPC
109+
// can give inaccurate HTLC states, which is found when we call
110+
// `AssertHTLCNotActive` after a commitment dance is finished. Suppose Carol is
111+
// settling an invoice with Bob, from Bob's PoV, a typical healthy settlement
112+
// flow goes like this:
113+
//
114+
// [DBG] PEER brontide.go:2412: Peer([Carol]): Received UpdateFulfillHTLC
115+
// [DBG] HSWC switch.go:1315: Closed completed SETTLE circuit for ...
116+
// [INF] HSWC switch.go:3044: Forwarded HTLC...
117+
// [DBG] PEER brontide.go:2412: Peer([Carol]): Received CommitSig
118+
// [DBG] PEER brontide.go:2412: Peer([Carol]): Sending RevokeAndAck
119+
// [DBG] PEER brontide.go:2412: Peer([Carol]): Sending CommitSig
120+
// [DBG] PEER brontide.go:2412: Peer([Carol]): Received RevokeAndAck
121+
// [DBG] HSWC link.go:3617: ChannelLink([ChanPoint: Bob=>Carol]): settle-fail-filter: count=1, filter=[0]
122+
// [DBG] HSWC switch.go:3001: Circuit is closing for packet...
123+
//
124+
// Bob receives the preimage, closes the circuit, and exchanges commit sig and
125+
// revoke msgs with Carol. Once Bob receives the `CommitSig` from Carol, the
126+
// HTLC should be removed from his `LocalCommitment` via
127+
// `RevokeCurrentCommitment`.
128+
//
129+
// However, in the test where `AssertHTLCNotActive` is called, although the
130+
// above process is finished, the `ListChannels“ still finds the HTLC. Also note
131+
// that the RPC makes direct call to the channeldb without any locks, which
132+
// should be fine as the struct `OpenChannel.LocalCommitment` is passed by
133+
// value, although we need to double check.
134+
//
135+
// TODO(yy): In order to fix it, we should make the RPC share the same view of
136+
// our channel state machine. Instead of making DB queries, it should instead
137+
// use `lnwallet.LightningChannel` instead to stay consistent.
138+
//
139+
//nolint:ll
140+
func flakeInconsistentHTLCView() {
141+
// Perform a sleep so the commiment dance can be finished before we call
142+
// the ListChannels.
143+
time.Sleep(2 * time.Second)
144+
}

itest/lnd_route_blinding_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -815,6 +815,7 @@ func testErrorHandlingOnChainFailure(ht *lntest.HarnessTest) {
815815
ht.MineBlocksAndAssertNumTxes(1, 1)
816816

817817
// Assert that the HTLC has cleared.
818+
flakeInconsistentHTLCView()
818819
ht.AssertHTLCNotActive(bob, testCase.channels[0], hash[:])
819820
ht.AssertHTLCNotActive(alice, testCase.channels[0], hash[:])
820821

itest/lnd_sweep_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -499,6 +499,7 @@ func testSweepCPFPAnchorIncomingTimeout(ht *lntest.HarnessTest) {
499499
carol.RPC.SettleInvoice(preimage[:])
500500

501501
// Bob should have settled his outgoing HTLC with Carol.
502+
flakeInconsistentHTLCView()
502503
ht.AssertHTLCNotActive(bob, bcChanPoint, payHash[:])
503504

504505
// We'll now mine enough blocks to trigger Bob to force close channel
@@ -850,6 +851,7 @@ func testSweepHTLCs(ht *lntest.HarnessTest) {
850851
carol.RPC.SettleInvoice(preimageSettled[:])
851852

852853
// Bob should have settled his outgoing HTLC with Carol.
854+
flakeInconsistentHTLCView()
853855
ht.AssertHTLCNotActive(bob, bcChanPoint, payHashSettled[:])
854856

855857
// Let Carol go offline so we can focus on testing Bob's sweeping

0 commit comments

Comments
 (0)