/ htlcswitch / resolution_store_test.go
resolution_store_test.go
1 package htlcswitch 2 3 import ( 4 "path/filepath" 5 "testing" 6 7 "github.com/lightningnetwork/lnd/contractcourt" 8 "github.com/lightningnetwork/lnd/kvdb" 9 "github.com/lightningnetwork/lnd/lnwire" 10 "github.com/stretchr/testify/require" 11 ) 12 13 // TestInsertAndDelete tests that an inserted resolution message can be 14 // deleted. 15 func TestInsertAndDelete(t *testing.T) { 16 t.Parallel() 17 18 scid := lnwire.NewShortChanIDFromInt(1) 19 20 failResMsg := &contractcourt.ResolutionMsg{ 21 SourceChan: scid, 22 HtlcIndex: 2, 23 Failure: &lnwire.FailTemporaryChannelFailure{}, 24 } 25 26 settleBytes := [32]byte{ 27 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 28 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 29 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 30 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 31 } 32 33 settleResMsg := &contractcourt.ResolutionMsg{ 34 SourceChan: scid, 35 HtlcIndex: 3, 36 PreImage: &settleBytes, 37 } 38 39 // Create the backend database and use it to create the resolution 40 // store. 41 dbPath := filepath.Join(t.TempDir(), "testdb") 42 db, err := kvdb.Create( 43 kvdb.BoltBackendName, dbPath, true, kvdb.DefaultDBTimeout, 44 false, 45 ) 46 require.NoError(t, err) 47 t.Cleanup(func() { 48 db.Close() 49 }) 50 51 resStore := newResolutionStore(db) 52 53 // We'll add the failure resolution message first, then check that it 54 // exists in the store. 55 err = resStore.addResolutionMsg(failResMsg) 56 require.NoError(t, err) 57 58 // Assert that checkResolutionMsg returns nil, signalling that the 59 // resolution message was properly stored. 60 outKey := &CircuitKey{ 61 ChanID: failResMsg.SourceChan, 62 HtlcID: failResMsg.HtlcIndex, 63 } 64 err = resStore.checkResolutionMsg(outKey) 65 require.NoError(t, err) 66 67 resMsgs, err := resStore.fetchAllResolutionMsg() 68 require.NoError(t, err) 69 require.Equal(t, 1, len(resMsgs)) 70 71 // It should match failResMsg above. 72 require.Equal(t, failResMsg.SourceChan, resMsgs[0].SourceChan) 73 require.Equal(t, failResMsg.HtlcIndex, resMsgs[0].HtlcIndex) 74 require.NotNil(t, resMsgs[0].Failure) 75 require.Nil(t, resMsgs[0].PreImage) 76 77 // We'll add the settleResMsg now. 78 err = resStore.addResolutionMsg(settleResMsg) 79 require.NoError(t, err) 80 81 // Check that checkResolutionMsg returns nil for the settle CircuitKey. 82 outKey.ChanID = settleResMsg.SourceChan 83 outKey.HtlcID = settleResMsg.HtlcIndex 84 err = resStore.checkResolutionMsg(outKey) 85 require.NoError(t, err) 86 87 // We should have two resolution messages in the store, one failure and 88 // one success. 89 resMsgs, err = resStore.fetchAllResolutionMsg() 90 require.NoError(t, err) 91 require.Equal(t, 2, len(resMsgs)) 92 93 // The first resolution message should be the failure. 94 require.Equal(t, failResMsg.SourceChan, resMsgs[0].SourceChan) 95 require.Equal(t, failResMsg.HtlcIndex, resMsgs[0].HtlcIndex) 96 require.NotNil(t, resMsgs[0].Failure) 97 require.Nil(t, resMsgs[0].PreImage) 98 99 // The second resolution message should be the success. 100 require.Equal(t, settleResMsg.SourceChan, resMsgs[1].SourceChan) 101 require.Equal(t, settleResMsg.HtlcIndex, resMsgs[1].HtlcIndex) 102 require.Nil(t, resMsgs[1].Failure) 103 require.Equal(t, settleBytes, *resMsgs[1].PreImage) 104 105 // We'll now delete the failure resolution message and assert that only 106 // the success is left. 107 failKey := &CircuitKey{ 108 ChanID: scid, 109 HtlcID: failResMsg.HtlcIndex, 110 } 111 112 err = resStore.deleteResolutionMsg(failKey) 113 require.NoError(t, err) 114 115 // Assert that checkResolutionMsg returns errResMsgNotFound. 116 err = resStore.checkResolutionMsg(failKey) 117 require.ErrorIs(t, err, errResMsgNotFound) 118 119 resMsgs, err = resStore.fetchAllResolutionMsg() 120 require.NoError(t, err) 121 require.Equal(t, 1, len(resMsgs)) 122 123 // Assert that the success is left. 124 require.Equal(t, settleResMsg.SourceChan, resMsgs[0].SourceChan) 125 require.Equal(t, settleResMsg.HtlcIndex, resMsgs[0].HtlcIndex) 126 require.Nil(t, resMsgs[0].Failure) 127 require.Equal(t, settleBytes, *resMsgs[0].PreImage) 128 129 // Now we'll delete the settle resolution message and assert that the 130 // store is empty. 131 settleKey := &CircuitKey{ 132 ChanID: scid, 133 HtlcID: settleResMsg.HtlcIndex, 134 } 135 136 err = resStore.deleteResolutionMsg(settleKey) 137 require.NoError(t, err) 138 139 // Assert that checkResolutionMsg returns errResMsgNotFound for the 140 // settle key. 141 err = resStore.checkResolutionMsg(settleKey) 142 require.ErrorIs(t, err, errResMsgNotFound) 143 144 resMsgs, err = resStore.fetchAllResolutionMsg() 145 require.NoError(t, err) 146 require.Equal(t, 0, len(resMsgs)) 147 }