mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-10-09 21:43:17 +02:00
htlcswitch: introduce resolutionStore to persist cnct messages
This commit is contained in:
154
htlcswitch/resolution_store_test.go
Normal file
154
htlcswitch/resolution_store_test.go
Normal file
@@ -0,0 +1,154 @@
|
||||
package htlcswitch
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/lightningnetwork/lnd/contractcourt"
|
||||
"github.com/lightningnetwork/lnd/kvdb"
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
// TestInsertAndDelete tests that an inserted resolution message can be
|
||||
// deleted.
|
||||
func TestInsertAndDelete(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
scid := lnwire.NewShortChanIDFromInt(1)
|
||||
|
||||
failResMsg := &contractcourt.ResolutionMsg{
|
||||
SourceChan: scid,
|
||||
HtlcIndex: 2,
|
||||
Failure: &lnwire.FailTemporaryChannelFailure{},
|
||||
}
|
||||
|
||||
settleBytes := [32]byte{
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
|
||||
}
|
||||
|
||||
settleResMsg := &contractcourt.ResolutionMsg{
|
||||
SourceChan: scid,
|
||||
HtlcIndex: 3,
|
||||
PreImage: &settleBytes,
|
||||
}
|
||||
|
||||
// Create the backend database and use it to create the resolution
|
||||
// store.
|
||||
dbDir, err := ioutil.TempDir("", "resolutionStore")
|
||||
require.NoError(t, err)
|
||||
|
||||
dbPath := filepath.Join(dbDir, "testdb")
|
||||
db, err := kvdb.Create(
|
||||
kvdb.BoltBackendName, dbPath, true, kvdb.DefaultDBTimeout,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
cleanUp := func() {
|
||||
db.Close()
|
||||
os.RemoveAll(dbDir)
|
||||
}
|
||||
defer cleanUp()
|
||||
|
||||
resStore := newResolutionStore(db)
|
||||
|
||||
// We'll add the failure resolution message first, then check that it
|
||||
// exists in the store.
|
||||
err = resStore.addResolutionMsg(failResMsg)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Assert that checkResolutionMsg returns nil, signalling that the
|
||||
// resolution message was properly stored.
|
||||
outKey := &CircuitKey{
|
||||
ChanID: failResMsg.SourceChan,
|
||||
HtlcID: failResMsg.HtlcIndex,
|
||||
}
|
||||
err = resStore.checkResolutionMsg(outKey)
|
||||
require.NoError(t, err)
|
||||
|
||||
resMsgs, err := resStore.fetchAllResolutionMsg()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 1, len(resMsgs))
|
||||
|
||||
// It should match failResMsg above.
|
||||
require.Equal(t, failResMsg.SourceChan, resMsgs[0].SourceChan)
|
||||
require.Equal(t, failResMsg.HtlcIndex, resMsgs[0].HtlcIndex)
|
||||
require.NotNil(t, resMsgs[0].Failure)
|
||||
require.Nil(t, resMsgs[0].PreImage)
|
||||
|
||||
// We'll add the settleResMsg now.
|
||||
err = resStore.addResolutionMsg(settleResMsg)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Check that checkResolutionMsg returns nil for the settle CircuitKey.
|
||||
outKey.ChanID = settleResMsg.SourceChan
|
||||
outKey.HtlcID = settleResMsg.HtlcIndex
|
||||
err = resStore.checkResolutionMsg(outKey)
|
||||
require.NoError(t, err)
|
||||
|
||||
// We should have two resolution messages in the store, one failure and
|
||||
// one success.
|
||||
resMsgs, err = resStore.fetchAllResolutionMsg()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 2, len(resMsgs))
|
||||
|
||||
// The first resolution message should be the failure.
|
||||
require.Equal(t, failResMsg.SourceChan, resMsgs[0].SourceChan)
|
||||
require.Equal(t, failResMsg.HtlcIndex, resMsgs[0].HtlcIndex)
|
||||
require.NotNil(t, resMsgs[0].Failure)
|
||||
require.Nil(t, resMsgs[0].PreImage)
|
||||
|
||||
// The second resolution message should be the success.
|
||||
require.Equal(t, settleResMsg.SourceChan, resMsgs[1].SourceChan)
|
||||
require.Equal(t, settleResMsg.HtlcIndex, resMsgs[1].HtlcIndex)
|
||||
require.Nil(t, resMsgs[1].Failure)
|
||||
require.Equal(t, settleBytes, *resMsgs[1].PreImage)
|
||||
|
||||
// We'll now delete the failure resolution message and assert that only
|
||||
// the success is left.
|
||||
failKey := &CircuitKey{
|
||||
ChanID: scid,
|
||||
HtlcID: failResMsg.HtlcIndex,
|
||||
}
|
||||
|
||||
err = resStore.deleteResolutionMsg(failKey)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Assert that checkResolutionMsg returns errResMsgNotFound.
|
||||
err = resStore.checkResolutionMsg(failKey)
|
||||
require.ErrorIs(t, err, errResMsgNotFound)
|
||||
|
||||
resMsgs, err = resStore.fetchAllResolutionMsg()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 1, len(resMsgs))
|
||||
|
||||
// Assert that the success is left.
|
||||
require.Equal(t, settleResMsg.SourceChan, resMsgs[0].SourceChan)
|
||||
require.Equal(t, settleResMsg.HtlcIndex, resMsgs[0].HtlcIndex)
|
||||
require.Nil(t, resMsgs[0].Failure)
|
||||
require.Equal(t, settleBytes, *resMsgs[0].PreImage)
|
||||
|
||||
// Now we'll delete the settle resolution message and assert that the
|
||||
// store is empty.
|
||||
settleKey := &CircuitKey{
|
||||
ChanID: scid,
|
||||
HtlcID: settleResMsg.HtlcIndex,
|
||||
}
|
||||
|
||||
err = resStore.deleteResolutionMsg(settleKey)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Assert that checkResolutionMsg returns errResMsgNotFound for the
|
||||
// settle key.
|
||||
err = resStore.checkResolutionMsg(settleKey)
|
||||
require.ErrorIs(t, err, errResMsgNotFound)
|
||||
|
||||
resMsgs, err = resStore.fetchAllResolutionMsg()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 0, len(resMsgs))
|
||||
}
|
Reference in New Issue
Block a user