2023-02-09 12:35:28 +02:00
|
|
|
package wtdb_test
|
|
|
|
|
|
|
|
import (
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/lightningnetwork/lnd/kvdb"
|
2023-11-23 15:45:42 +02:00
|
|
|
"github.com/lightningnetwork/lnd/lnwire"
|
2023-02-09 12:35:28 +02:00
|
|
|
"github.com/lightningnetwork/lnd/watchtower/wtdb"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
)
|
|
|
|
|
|
|
|
// TestDiskQueue ensures that the ClientDBs disk queue methods behave as is
|
|
|
|
// expected of a queue.
|
|
|
|
func TestDiskQueue(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
|
2023-09-13 12:21:04 +02:00
|
|
|
dbCfg := &kvdb.BoltConfig{
|
|
|
|
DBTimeout: kvdb.DefaultDBTimeout,
|
2023-02-09 12:37:57 +02:00
|
|
|
}
|
|
|
|
|
2023-09-13 12:21:04 +02:00
|
|
|
// Construct the ClientDB.
|
|
|
|
bdb, err := wtdb.NewBoltBackendCreator(
|
|
|
|
true, t.TempDir(), "wtclient.db",
|
|
|
|
)(dbCfg)
|
|
|
|
require.NoError(t, err)
|
2023-02-09 12:37:57 +02:00
|
|
|
|
2023-09-13 12:21:04 +02:00
|
|
|
db, err := wtdb.OpenClientDB(bdb)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
t.Cleanup(func() {
|
|
|
|
err = db.Close()
|
|
|
|
require.NoError(t, err)
|
|
|
|
})
|
2023-02-09 12:35:28 +02:00
|
|
|
|
2023-11-23 15:45:42 +02:00
|
|
|
// In order to test that the queue's `onItemWrite` call back (which in
|
|
|
|
// this case will be set to maybeUpdateMaxCommitHeight) is executed as
|
|
|
|
// expected, we need to register a channel so that we can later assert
|
|
|
|
// that it's max height field was updated properly.
|
|
|
|
var chanID lnwire.ChannelID
|
|
|
|
err = db.RegisterChannel(chanID, []byte{})
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
2023-02-09 12:35:28 +02:00
|
|
|
namespace := []byte("test-namespace")
|
|
|
|
queue := db.GetDBQueue(namespace)
|
|
|
|
|
|
|
|
addTasksToTail := func(tasks ...*wtdb.BackupID) {
|
|
|
|
err := queue.Push(tasks...)
|
|
|
|
require.NoError(t, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
addTasksToHead := func(tasks ...*wtdb.BackupID) {
|
|
|
|
err := queue.PushHead(tasks...)
|
|
|
|
require.NoError(t, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
assertNumTasks := func(expNum int) {
|
|
|
|
num, err := queue.Len()
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.EqualValues(t, expNum, num)
|
|
|
|
}
|
|
|
|
|
|
|
|
popAndAssert := func(expTasks ...*wtdb.BackupID) {
|
|
|
|
tasks, err := queue.PopUpTo(len(expTasks))
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.EqualValues(t, expTasks, tasks)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create a few tasks that we use throughout the test.
|
|
|
|
task1 := &wtdb.BackupID{CommitHeight: 1}
|
|
|
|
task2 := &wtdb.BackupID{CommitHeight: 2}
|
|
|
|
task3 := &wtdb.BackupID{CommitHeight: 3}
|
|
|
|
task4 := &wtdb.BackupID{CommitHeight: 4}
|
|
|
|
task5 := &wtdb.BackupID{CommitHeight: 5}
|
|
|
|
task6 := &wtdb.BackupID{CommitHeight: 6}
|
|
|
|
|
|
|
|
// Namespace 1 should initially have no items.
|
|
|
|
assertNumTasks(0)
|
|
|
|
|
|
|
|
// Now add a few items to the tail of the queue.
|
|
|
|
addTasksToTail(task1, task2)
|
|
|
|
|
|
|
|
// Check that the number of tasks is now two.
|
|
|
|
assertNumTasks(2)
|
|
|
|
|
|
|
|
// Pop a task, check that it is task 1 and assert that the number of
|
|
|
|
// items left is now 1.
|
|
|
|
popAndAssert(task1)
|
|
|
|
assertNumTasks(1)
|
|
|
|
|
|
|
|
// Pop a task, check that it is task 2 and assert that the number of
|
|
|
|
// items left is now 0.
|
|
|
|
popAndAssert(task2)
|
|
|
|
assertNumTasks(0)
|
|
|
|
|
|
|
|
// Once again add a few tasks.
|
|
|
|
addTasksToTail(task3, task4)
|
|
|
|
|
|
|
|
// Now push some tasks to the head of the queue.
|
|
|
|
addTasksToHead(task6, task5)
|
|
|
|
|
|
|
|
// Ensure that both the disk queue lengths are added together when
|
|
|
|
// querying the length of the queue.
|
|
|
|
assertNumTasks(4)
|
|
|
|
|
|
|
|
// Ensure that the order that the tasks are popped is correct.
|
|
|
|
popAndAssert(task6, task5, task3, task4)
|
|
|
|
|
|
|
|
// We also want to test that the head queue works as expected and that.
|
|
|
|
// To do this, we first push 4, 5 and 6 to the queue.
|
|
|
|
addTasksToTail(task4, task5, task6)
|
|
|
|
|
|
|
|
// Now we push 1, 2 and 3 to the head.
|
|
|
|
addTasksToHead(task1, task2, task3)
|
|
|
|
|
|
|
|
// Now, only pop item 1 from the queue and then re-add it to the head.
|
|
|
|
popAndAssert(task1)
|
|
|
|
addTasksToHead(task1)
|
|
|
|
|
|
|
|
// This should not have changed the order of the tasks, they should
|
|
|
|
// still appear in the correct order.
|
|
|
|
popAndAssert(task1, task2, task3, task4, task5, task6)
|
2023-11-23 15:45:42 +02:00
|
|
|
|
|
|
|
// Finally, we check that the `onItemWrite` call back was executed by
|
|
|
|
// the queue. We do this by checking that the channel's recorded max
|
|
|
|
// commitment height was set correctly. It should be equal to the height
|
|
|
|
// recorded in task6.
|
|
|
|
infos, err := db.FetchChanInfos()
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Len(t, infos, 1)
|
|
|
|
|
|
|
|
info, ok := infos[chanID]
|
|
|
|
require.True(t, ok)
|
|
|
|
require.True(t, info.MaxHeight.IsSome())
|
|
|
|
info.MaxHeight.WhenSome(func(height uint64) {
|
|
|
|
require.EqualValues(t, task6.CommitHeight, height)
|
|
|
|
})
|
2023-02-09 12:35:28 +02:00
|
|
|
}
|