Merge pull request #9039 from ellemouton/htlcPersistenceAcrossRestart

lnwallet: correctly set UpdateAddHTLC.BlindingPoint on reload from disk
This commit is contained in:
Oliver Gugger 2024-08-27 12:45:27 -06:00 committed by GitHub
commit 64b8c6299a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 75 additions and 1 deletions

View File

@ -76,6 +76,11 @@ blinded path expiry.
* [Fixed](https://github.com/lightningnetwork/lnd/pull/9021) an issue with some
command-line arguments not being passed when running `make itest-parallel`.
* [Fix a bug](https://github.com/lightningnetwork/lnd/pull/9039) that would
cause UpdateAddHTLC message with blinding point fields to not be re-forwarded
correctly on restart.
# New Features
## Functional Enhancements
## RPC Additions

View File

@ -582,6 +582,10 @@ var allTestCases = []*lntest.TestCase{
Name: "update pending open channels",
TestFunc: testUpdateOnPendingOpenChannels,
},
{
Name: "blinded payment htlc re-forward",
TestFunc: testBlindedPaymentHTLCReForward,
},
{
Name: "query blinded route",
TestFunc: testQueryBlindedRoutes,

View File

@ -1420,3 +1420,68 @@ func testMPPToMultipleBlindedPaths(ht *lntest.HarnessTest) {
ht.AssertNumWaitingClose(hn, 0)
}
}
// testBlindedPaymentHTLCReForward tests that an UpdateAddHTLC message is
// correctly persisted, reloaded and resent to the next peer on restart in the
// case where the sending peer does not get a chance to send the message before
// restarting. This test specifically tests that this is done correctly for
// a blinded path payment since this adds a new blinding point field to
// UpdateAddHTLC which we need to ensure gets included in the message on
// restart.
func testBlindedPaymentHTLCReForward(ht *lntest.HarnessTest) {
// Setup a test case.
ctx, testCase := newBlindedForwardTest(ht)
defer testCase.cleanup()
// Set up network with carol interceptor.
testCase.setupNetwork(ctx, true)
// Let dave create invoice.
blindedPaymentPath := testCase.buildBlindedPath()
route := testCase.createRouteToBlinded(10_000_000, blindedPaymentPath)
// Once our interceptor is set up, we can send the blinded payment.
hash := sha256.Sum256(testCase.preimage[:])
sendReq := &routerrpc.SendToRouteRequest{
PaymentHash: hash[:],
Route: route,
}
// In a goroutine, we let Alice pay the invoice from dave.
done := make(chan struct{})
go func() {
defer close(done)
htlcAttempt, err := testCase.ht.Alice.RPC.Router.SendToRouteV2(
ctx, sendReq,
)
require.NoError(testCase.ht, err)
require.Equal(
testCase.ht, lnrpc.HTLCAttempt_SUCCEEDED,
htlcAttempt.Status,
)
}()
// Wait for the HTLC to be active on Alice and Bob's channels.
ht.AssertOutgoingHTLCActive(ht.Alice, testCase.channels[0], hash[:])
ht.AssertOutgoingHTLCActive(ht.Bob, testCase.channels[1], hash[:])
// Intercept the forward on Carol's link. At this point, we know she
// has received the HTLC and so will persist this packet.
_, err := testCase.carolInterceptor.Recv()
require.NoError(ht, err)
// Now, restart Carol. This time, don't require an interceptor. This
// means that Carol should load up any previously persisted
// UpdateAddHTLC messages and continue the processing of them.
ht.RestartNodeWithExtraArgs(
testCase.carol, []string{"--bitcoin.timelockdelta=18"},
)
// Now, wait for the payment to complete.
select {
case <-done:
case <-time.After(defaultTimeout):
require.Fail(ht, "timeout waiting for sending payment")
}
}

View File

@ -205,7 +205,7 @@ func PayDescsFromRemoteLogUpdates(chanID lnwire.ShortChannelID, height uint64,
Height: height,
Index: uint16(i),
},
BlindingPoint: pd.BlindingPoint,
BlindingPoint: wireMsg.BlindingPoint,
}
pd.OnionBlob = make([]byte, len(wireMsg.OnionBlob))
copy(pd.OnionBlob[:], wireMsg.OnionBlob[:])