routing+migration32: update MC encoding to use pure TLV

In this commit, we update an existing migration which at the time of
writing has not been included in a release. We update it so that it
converts the format used for MissionControl result encoding to use pure
TLV instead. The 3 structs that have been updated are: `mcHop`,
`mcRoute` and `paymentResult`.
This commit is contained in:
Elle Mouton committed 2024-11-01 12:28:06 +02:00
1 parent d9a073ad7e
commit 5370c90906
7 files changed
+1612 -690

No files matched your search

+85 -61
View File
@@ -11,27 +11,25 @@ import (
"github.com/lightningnetwork/lnd/lntest/wait"
"github.com/lightningnetwork/lnd/lnwire"
"github.com/lightningnetwork/lnd/routing/route"
"github.com/lightningnetwork/lnd/tlv"
"github.com/stretchr/testify/require"
)
const testMaxRecords = 2
var (
// mcStoreTestRoute is a test route for the mission control store tests.
mcStoreTestRoute = mcRoute{
totalAmount: lnwire.MilliSatoshi(5),
sourcePubKey: route.Vertex{1},
hops: []*mcHop{
{
pubKeyBytes: route.Vertex{2},
channelID: 4,
amtToFwd: lnwire.MilliSatoshi(7),
hasCustomRecords: true,
hasBlindingPoint: false,
},
// mcStoreTestRoute is a test route for the mission control store tests.
var mcStoreTestRoute = extractMCRoute(&route.Route{
TotalAmount: lnwire.MilliSatoshi(5),
SourcePubKey: route.Vertex{1},
Hops: []*route.Hop{
{
PubKeyBytes: route.Vertex{2},
ChannelID: 4,
AmtToForward: lnwire.MilliSatoshi(7),
CustomRecords: make(map[uint64][]byte),
},
}
)
},
})
// mcStoreTestHarness is the harness for a MissonControlStore test.
type mcStoreTestHarness struct {
@@ -84,28 +82,31 @@ func TestMissionControlStore(t *testing.T) {
failureSourceIdx := 1
result1 := paymentResult{
route: &mcStoreTestRoute,
failure: lnwire.NewFailIncorrectDetails(100, 1000),
failureSourceIdx: &failureSourceIdx,
id: 99,
timeReply: testTime,
timeFwd: testTime.Add(-time.Minute),
}
result1 := newPaymentResult(
99, mcStoreTestRoute, testTime, testTime,
newPaymentFailure(
&failureSourceIdx,
lnwire.NewFailIncorrectDetails(100, 1000),
),
)
result2 := result1
result2.timeReply = result1.timeReply.Add(time.Hour)
result2.timeFwd = result1.timeReply.Add(time.Hour)
result2.id = 2
result2 := newPaymentResult(
2, mcStoreTestRoute, testTime.Add(time.Hour),
testTime.Add(time.Hour),
newPaymentFailure(
&failureSourceIdx,
lnwire.NewFailIncorrectDetails(100, 1000),
),
)
// Store result.
store.AddResult(&result2)
store.AddResult(result2)
// Store again to test idempotency.
store.AddResult(&result2)
store.AddResult(result2)
// Store second result which has an earlier timestamp.
store.AddResult(&result1)
store.AddResult(result1)
require.NoError(t, store.storeResults())
results, err = store.fetchAll()
@@ -113,8 +114,8 @@ func TestMissionControlStore(t *testing.T) {
require.Len(t, results, 2)
// Check that results are stored in chronological order.
require.Equal(t, &result1, results[0])
require.Equal(t, &result2, results[1])
require.Equal(t, result1, results[0])
require.Equal(t, result2, results[1])
// Recreate store to test pruning.
store, err = newMissionControlStore(
@@ -124,12 +125,20 @@ func TestMissionControlStore(t *testing.T) {
// Add a newer result which failed due to mpp timeout.
result3 := result1
result3.timeReply = result1.timeReply.Add(2 * time.Hour)
result3.timeFwd = result1.timeReply.Add(2 * time.Hour)
result3.timeReply = tlv.NewPrimitiveRecord[tlv.TlvType1](
uint64(testTime.Add(2 * time.Hour).UnixNano()),
)
result3.timeFwd = tlv.NewPrimitiveRecord[tlv.TlvType0](
uint64(testTime.Add(2 * time.Hour).UnixNano()),
)
result3.id = 3
result3.failure = &lnwire.FailMPPTimeout{}
result3.failure = tlv.SomeRecordT(
tlv.NewRecordT[tlv.TlvType3](*newPaymentFailure(
&failureSourceIdx, &lnwire.FailMPPTimeout{},
)),
)
store.AddResult(&result3)
store.AddResult(result3)
require.NoError(t, store.storeResults())
// Check that results are pruned.
@@ -137,8 +146,25 @@ func TestMissionControlStore(t *testing.T) {
require.NoError(t, err)
require.Len(t, results, 2)
require.Equal(t, &result2, results[0])
require.Equal(t, &result3, results[1])
require.Equal(t, result2, results[0])
require.Equal(t, result3, results[1])
// Also demonstrate the persistence of a success result.
result4 := newPaymentResult(
5, mcStoreTestRoute, testTime.Add(3*time.Hour),
testTime.Add(3*time.Hour), nil,
)
store.AddResult(result4)
require.NoError(t, store.storeResults())
// We should still only have 2 results.
results, err = store.fetchAll()
require.NoError(t, err)
require.Len(t, results, 2)
// The two latest results should have been returned.
require.Equal(t, result3, results[0])
require.Equal(t, result4, results[1])
}
// TestMissionControlStoreFlushing asserts the periodic flushing of the store
@@ -156,14 +182,11 @@ func TestMissionControlStoreFlushing(t *testing.T) {
)
nextResult := func() *paymentResult {
lastID += 1
return &paymentResult{
route: &mcStoreTestRoute,
failure: failureDetails,
failureSourceIdx: &failureSourceIdx,
id: lastID,
timeReply: testTime,
timeFwd: testTime.Add(-time.Minute),
}
return newPaymentResult(
lastID, mcStoreTestRoute, testTime.Add(-time.Hour),
testTime,
newPaymentFailure(&failureSourceIdx, failureDetails),
)
}
// Helper to assert the number of results is correct.
@@ -260,14 +283,14 @@ func BenchmarkMissionControlStoreFlushing(b *testing.B) {
var lastID uint64
for i := 0; i < testMaxRecords; i++ {
lastID++
result := &paymentResult{
route: &mcStoreTestRoute,
failure: failureDetails,
failureSourceIdx: &failureSourceIdx,
id: lastID,
timeReply: testTime,
timeFwd: testTimeFwd,
}
result := newPaymentResult(
lastID, mcStoreTestRoute, testTimeFwd,
testTime,
newPaymentFailure(
&failureSourceIdx,
failureDetails,
),
)
store.AddResult(result)
}
@@ -278,13 +301,14 @@ func BenchmarkMissionControlStoreFlushing(b *testing.B) {
// Create the additional results.
results := make([]*paymentResult, tc)
for i := 0; i < len(results); i++ {
results[i] = &paymentResult{
route: &mcStoreTestRoute,
failure: failureDetails,
failureSourceIdx: &failureSourceIdx,
timeReply: testTime,
timeFwd: testTimeFwd,
}
results[i] = newPaymentResult(
0, mcStoreTestRoute, testTimeFwd,
testTime,
newPaymentFailure(
&failureSourceIdx,
failureDetails,
),
)
}
// Run the actual benchmark.