Skip to content

Commit 64b8c62

Browse files
authored
Merge pull request #9039 from ellemouton/htlcPersistenceAcrossRestart
lnwallet: correctly set UpdateAddHTLC.BlindingPoint on reload from disk
2 parents 8939a21 + 6c7be5b commit 64b8c62

File tree

4 files changed

+75
-1
lines changed

4 files changed

+75
-1
lines changed

docs/release-notes/release-notes-0.18.3.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,11 @@ blinded path expiry.
7676
* [Fixed](https://github.com/lightningnetwork/lnd/pull/9021) an issue with some
7777
command-line arguments not being passed when running `make itest-parallel`.
7878

79+
80+
* [Fix a bug](https://github.com/lightningnetwork/lnd/pull/9039) that would
81+
cause UpdateAddHTLC message with blinding point fields to not be re-forwarded
82+
correctly on restart.
83+
7984
# New Features
8085
## Functional Enhancements
8186
## RPC Additions

itest/list_on_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -582,6 +582,10 @@ var allTestCases = []*lntest.TestCase{
582582
Name: "update pending open channels",
583583
TestFunc: testUpdateOnPendingOpenChannels,
584584
},
585+
{
586+
Name: "blinded payment htlc re-forward",
587+
TestFunc: testBlindedPaymentHTLCReForward,
588+
},
585589
{
586590
Name: "query blinded route",
587591
TestFunc: testQueryBlindedRoutes,

itest/lnd_route_blinding_test.go

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1420,3 +1420,68 @@ func testMPPToMultipleBlindedPaths(ht *lntest.HarnessTest) {
14201420
ht.AssertNumWaitingClose(hn, 0)
14211421
}
14221422
}
1423+
1424+
// testBlindedPaymentHTLCReForward tests that an UpdateAddHTLC message is
1425+
// correctly persisted, reloaded and resent to the next peer on restart in the
1426+
// case where the sending peer does not get a chance to send the message before
1427+
// restarting. This test specifically tests that this is done correctly for
1428+
// a blinded path payment since this adds a new blinding point field to
1429+
// UpdateAddHTLC which we need to ensure gets included in the message on
1430+
// restart.
1431+
func testBlindedPaymentHTLCReForward(ht *lntest.HarnessTest) {
1432+
// Setup a test case.
1433+
ctx, testCase := newBlindedForwardTest(ht)
1434+
defer testCase.cleanup()
1435+
1436+
// Set up network with carol interceptor.
1437+
testCase.setupNetwork(ctx, true)
1438+
1439+
// Let dave create invoice.
1440+
blindedPaymentPath := testCase.buildBlindedPath()
1441+
route := testCase.createRouteToBlinded(10_000_000, blindedPaymentPath)
1442+
1443+
// Once our interceptor is set up, we can send the blinded payment.
1444+
hash := sha256.Sum256(testCase.preimage[:])
1445+
sendReq := &routerrpc.SendToRouteRequest{
1446+
PaymentHash: hash[:],
1447+
Route: route,
1448+
}
1449+
1450+
// In a goroutine, we let Alice pay the invoice from dave.
1451+
done := make(chan struct{})
1452+
go func() {
1453+
defer close(done)
1454+
1455+
htlcAttempt, err := testCase.ht.Alice.RPC.Router.SendToRouteV2(
1456+
ctx, sendReq,
1457+
)
1458+
require.NoError(testCase.ht, err)
1459+
require.Equal(
1460+
testCase.ht, lnrpc.HTLCAttempt_SUCCEEDED,
1461+
htlcAttempt.Status,
1462+
)
1463+
}()
1464+
1465+
// Wait for the HTLC to be active on Alice and Bob's channels.
1466+
ht.AssertOutgoingHTLCActive(ht.Alice, testCase.channels[0], hash[:])
1467+
ht.AssertOutgoingHTLCActive(ht.Bob, testCase.channels[1], hash[:])
1468+
1469+
// Intercept the forward on Carol's link. At this point, we know she
1470+
// has received the HTLC and so will persist this packet.
1471+
_, err := testCase.carolInterceptor.Recv()
1472+
require.NoError(ht, err)
1473+
1474+
// Now, restart Carol. This time, don't require an interceptor. This
1475+
// means that Carol should load up any previously persisted
1476+
// UpdateAddHTLC messages and continue the processing of them.
1477+
ht.RestartNodeWithExtraArgs(
1478+
testCase.carol, []string{"--bitcoin.timelockdelta=18"},
1479+
)
1480+
1481+
// Now, wait for the payment to complete.
1482+
select {
1483+
case <-done:
1484+
case <-time.After(defaultTimeout):
1485+
require.Fail(ht, "timeout waiting for sending payment")
1486+
}
1487+
}

lnwallet/channel.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ func PayDescsFromRemoteLogUpdates(chanID lnwire.ShortChannelID, height uint64,
205205
Height: height,
206206
Index: uint16(i),
207207
},
208-
BlindingPoint: pd.BlindingPoint,
208+
BlindingPoint: wireMsg.BlindingPoint,
209209
}
210210
pd.OnionBlob = make([]byte, len(wireMsg.OnionBlob))
211211
copy(pd.OnionBlob[:], wireMsg.OnionBlob[:])

0 commit comments

Comments
 (0)