@@ -332,3 +332,72 @@ func BenchmarkMissionControlStoreFlushing(b *testing.B) {
332332 })
333333 }
334334}
335+
336+ // TestMissionControlStoreSkipsCorruptedEntries tests that fetchAll() skips
337+ // entries that fail to deserialize rather than returning an error.
338+ func TestMissionControlStoreSkipsCorruptedEntries (t * testing.T ) {
339+ h := newMCStoreTestHarness (t , testMaxRecords , time .Second )
340+ store := h .store
341+
342+ failureSourceIdx := 1
343+
344+ // Create two valid results.
345+ result1 := newPaymentResult (
346+ 1 , mcStoreTestRoute , testTime , testTime ,
347+ fn .Some (newPaymentFailure (
348+ & failureSourceIdx ,
349+ lnwire .NewFailIncorrectDetails (100 , 1000 ),
350+ )),
351+ )
352+
353+ result2 := newPaymentResult (
354+ 2 , mcStoreTestRoute , testTime .Add (time .Hour ),
355+ testTime .Add (time .Hour ),
356+ fn .Some (newPaymentFailure (
357+ & failureSourceIdx ,
358+ lnwire .NewFailIncorrectDetails (100 , 1000 ),
359+ )),
360+ )
361+
362+ // Store both results.
363+ store .AddResult (result1 )
364+ store .AddResult (result2 )
365+ require .NoError (t , store .storeResults ())
366+
367+ // Verify both results are stored correctly.
368+ results , err := store .fetchAll ()
369+ require .NoError (t , err )
370+ require .Len (t , results , 2 )
371+
372+ // Now manually insert a corrupted entry into the database.
373+ // We'll create a key that looks valid but has corrupted value data.
374+ err = store .db .update (func (bucket kvdb.RwBucket ) error {
375+ // Create a valid-looking key (8 bytes timestamp + 8 bytes id +
376+ // 33 bytes pubkey).
377+ var corruptedKey [8 + 8 + 33 ]byte
378+ byteOrder .PutUint64 (corruptedKey [:], uint64 (testTime .Add (
379+ 30 * time .Minute ).UnixNano ()),
380+ )
381+ byteOrder .PutUint64 (corruptedKey [8 :], 99 ) // Unique ID.
382+ copy (corruptedKey [16 :], result1 .route .Val .sourcePubKey .Val [:])
383+
384+ // Insert corrupted/invalid TLV data that will fail to
385+ // deserialize.
386+ corruptedValue := []byte {0xFF , 0xFF , 0xFF , 0xFF }
387+
388+ return bucket .Put (corruptedKey [:], corruptedValue )
389+ }, func () {})
390+ require .NoError (t , err )
391+
392+ // Now fetch all results. The corrupted entry should be skipped,
393+ // and we should get back only the two valid results.
394+ results , err = store .fetchAll ()
395+ require .NoError (t , err , "fetchAll should not return an error " +
396+ "even when encountering corrupted entries" )
397+ require .Len (t , results , 2 , "should skip the corrupted entry and " +
398+ "return only valid results" )
399+
400+ // Verify we still have the correct results.
401+ require .Equal (t , result1 , results [0 ])
402+ require .Equal (t , result2 , results [1 ])
403+ }
0 commit comments