Skip to content

Commit 013f5c9

Browse files
authored
Merge pull request #10455 from ziggie1984/fix-onchain-timeout-terminal
Fix flaky itest multihop testcase
2 parents 91423ee + c493f7d commit 013f5c9

File tree

2 files changed

+50
-10
lines changed

2 files changed

+50
-10
lines changed

itest/lnd_multi-hop_force_close_test.go

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -517,19 +517,25 @@ func runLocalClaimOutgoingHTLC(ht *lntest.HarnessTest,
517517
// Now that Bob has claimed his HTLCs, Alice should mark the two
518518
// payments as failed.
519519
//
520-
// Alice will mark this payment as failed with no route as the only
521-
// route she has is Alice->Bob->Carol. This won't be the case if she
522-
// has a second route, as another attempt will be tried.
523-
//
524-
// TODO(yy): we should instead mark this payment as timed out if she has
525-
// a second route to try this payment, which is the timeout set by Alice
526-
// when sending the payment.
527-
expectedReason := lnrpc.PaymentFailureReason_FAILURE_REASON_NO_ROUTE
528-
p := ht.AssertPaymentFailureReason(alice, preimage, expectedReason)
520+
// Alice's payment can fail with either NO_ROUTE or TIMEOUT depending
521+
// on timing. There's a race between:
522+
// 1. The channel closure propagating to Alice's graph (-> NO_ROUTE)
523+
// 2. The payment attempt timeout firing (-> TIMEOUT)
524+
// Both failure reasons are correct.
525+
p := ht.AssertPaymentFailureReasonAny(alice, preimage,
526+
lnrpc.PaymentFailureReason_FAILURE_REASON_NO_ROUTE,
527+
lnrpc.PaymentFailureReason_FAILURE_REASON_TIMEOUT,
528+
)
529+
530+
// The HTLC-level failure code should be PERMANENT_CHANNEL_FAILURE
531+
// regardless of which payment-level failure reason we got.
529532
require.Equal(ht, lnrpc.Failure_PERMANENT_CHANNEL_FAILURE,
530533
p.Htlcs[0].Failure.Code)
531534

532-
p = ht.AssertPaymentFailureReason(alice, preimageDust, expectedReason)
535+
p = ht.AssertPaymentFailureReasonAny(alice, preimageDust,
536+
lnrpc.PaymentFailureReason_FAILURE_REASON_NO_ROUTE,
537+
lnrpc.PaymentFailureReason_FAILURE_REASON_TIMEOUT,
538+
)
533539
require.Equal(ht, lnrpc.Failure_PERMANENT_CHANNEL_FAILURE,
534540
p.Htlcs[0].Failure.Code)
535541
}

lntest/harness_assertion.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1648,6 +1648,40 @@ func (h *HarnessTest) AssertPaymentFailureReason(
16481648
return payment
16491649
}
16501650

1651+
// AssertPaymentFailureReasonAny asserts that the given node lists a payment
1652+
// with the given preimage which has one of the expected failure reasons.
1653+
func (h *HarnessTest) AssertPaymentFailureReasonAny(
1654+
hn *node.HarnessNode, preimage lntypes.Preimage,
1655+
reasons ...lnrpc.PaymentFailureReason) *lnrpc.Payment {
1656+
1657+
var payment *lnrpc.Payment
1658+
1659+
payHash := preimage.Hash()
1660+
err := wait.NoError(func() error {
1661+
p, err := h.findPayment(hn, payHash.String())
1662+
if err != nil {
1663+
return err
1664+
}
1665+
1666+
payment = p
1667+
1668+
// Check if the payment failure reason matches any of the
1669+
// expected reasons.
1670+
for _, reason := range reasons {
1671+
if reason == p.FailureReason {
1672+
return nil
1673+
}
1674+
}
1675+
1676+
return fmt.Errorf("payment: %v failure reason not match, "+
1677+
"want one of %v, got %s(%d)", payHash, reasons,
1678+
p.FailureReason, p.FailureReason)
1679+
}, DefaultTimeout)
1680+
require.NoError(h, err, "timeout checking payment failure reason")
1681+
1682+
return payment
1683+
}
1684+
16511685
// AssertActiveNodesSynced asserts all active nodes have synced to the chain.
16521686
func (h *HarnessTest) AssertActiveNodesSynced() {
16531687
for _, node := range h.manager.activeNodes {

0 commit comments

Comments
 (0)