channeldb: replace fetch channels booleans with optional filters

This changes replaces the pending an waiting booleans in fetchChannels
with optional filters which can be more flexibly used. This change
allows filtering of channels without having to reason about the matrix
of possible boolean combinations. A test is added to ensure that the
combinations of these filters act as expected.
This commit is contained in:
carla
2020-02-06 10:21:12 +02:00
parent c5c2fc27f9
commit ed81c88239
3 changed files with 267 additions and 54 deletions

View File

@@ -500,3 +500,196 @@ func TestAbandonChannel(t *testing.T) {
t.Fatalf("unable to abandon channel: %v", err)
}
}
// TestFetchChannels tests the filtering of open channels in fetchChannels.
// It tests the case where no filters are provided (which is equivalent to
// FetchAllOpenChannels) and every combination of pending and waiting close.
func TestFetchChannels(t *testing.T) {
// Create static channel IDs for each kind of channel retrieved by
// fetchChannels so that the expected channel IDs can be set in tests.
var (
// Pending is a channel that is pending open, and has not had
// a close initiated.
pendingChan = lnwire.NewShortChanIDFromInt(1)
// pendingWaitingClose is a channel that is pending open and
// has has its closing transaction broadcast.
pendingWaitingChan = lnwire.NewShortChanIDFromInt(2)
// openChan is a channel that has confirmed on chain.
openChan = lnwire.NewShortChanIDFromInt(3)
// openWaitingChan is a channel that has confirmed on chain,
// and it waiting for its close transaction to confirm.
openWaitingChan = lnwire.NewShortChanIDFromInt(4)
)
tests := []struct {
name string
filters []fetchChannelsFilter
expectedChannels map[lnwire.ShortChannelID]bool
}{
{
name: "get all channels",
filters: []fetchChannelsFilter{},
expectedChannels: map[lnwire.ShortChannelID]bool{
pendingChan: true,
pendingWaitingChan: true,
openChan: true,
openWaitingChan: true,
},
},
{
name: "pending channels",
filters: []fetchChannelsFilter{
pendingChannelFilter(true),
},
expectedChannels: map[lnwire.ShortChannelID]bool{
pendingChan: true,
pendingWaitingChan: true,
},
},
{
name: "open channels",
filters: []fetchChannelsFilter{
pendingChannelFilter(false),
},
expectedChannels: map[lnwire.ShortChannelID]bool{
openChan: true,
openWaitingChan: true,
},
},
{
name: "waiting close channels",
filters: []fetchChannelsFilter{
waitingCloseFilter(true),
},
expectedChannels: map[lnwire.ShortChannelID]bool{
pendingWaitingChan: true,
openWaitingChan: true,
},
},
{
name: "not waiting close channels",
filters: []fetchChannelsFilter{
waitingCloseFilter(false),
},
expectedChannels: map[lnwire.ShortChannelID]bool{
pendingChan: true,
openChan: true,
},
},
{
name: "pending waiting",
filters: []fetchChannelsFilter{
pendingChannelFilter(true),
waitingCloseFilter(true),
},
expectedChannels: map[lnwire.ShortChannelID]bool{
pendingWaitingChan: true,
},
},
{
name: "pending, not waiting",
filters: []fetchChannelsFilter{
pendingChannelFilter(true),
waitingCloseFilter(false),
},
expectedChannels: map[lnwire.ShortChannelID]bool{
pendingChan: true,
},
},
{
name: "open waiting",
filters: []fetchChannelsFilter{
pendingChannelFilter(false),
waitingCloseFilter(true),
},
expectedChannels: map[lnwire.ShortChannelID]bool{
openWaitingChan: true,
},
},
{
name: "open, not waiting",
filters: []fetchChannelsFilter{
pendingChannelFilter(false),
waitingCloseFilter(false),
},
expectedChannels: map[lnwire.ShortChannelID]bool{
openChan: true,
},
},
}
for _, test := range tests {
test := test
t.Run(test.name, func(t *testing.T) {
t.Parallel()
cdb, cleanUp, err := makeTestDB()
if err != nil {
t.Fatalf("unable to make test "+
"database: %v", err)
}
defer cleanUp()
// Create a pending channel that is not awaiting close.
createTestChannel(
t, cdb, channelIDOption(pendingChan),
)
// Create a pending channel which has has been marked as
// broadcast, indicating that its closing transaction is
// waiting to confirm.
pendingClosing := createTestChannel(
t, cdb,
channelIDOption(pendingWaitingChan),
)
err = pendingClosing.MarkCoopBroadcasted(nil)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
// Create a open channel that is not awaiting close.
createTestChannel(
t, cdb,
channelIDOption(openChan),
openChannelOption(),
)
// Create a open channel which has has been marked as
// broadcast, indicating that its closing transaction is
// waiting to confirm.
openClosing := createTestChannel(
t, cdb,
channelIDOption(openWaitingChan),
openChannelOption(),
)
err = openClosing.MarkCoopBroadcasted(nil)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
channels, err := fetchChannels(cdb, test.filters...)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if len(channels) != len(test.expectedChannels) {
t.Fatalf("expected: %v channels, "+
"got: %v", len(test.expectedChannels),
len(channels))
}
for _, ch := range channels {
_, ok := test.expectedChannels[ch.ShortChannelID]
if !ok {
t.Fatalf("fetch channels unexpected "+
"channel: %v", ch.ShortChannelID)
}
}
})
}
}