From 0c51e31d1c69479e5d97db73e1a78ca6e44dd716 Mon Sep 17 00:00:00 2001 From: "Johan T. Halseth" Date: Fri, 28 Sep 2018 12:29:03 +0200 Subject: [PATCH] channeldb/invoices+test: don't return invoices on reversed query at index 1 Previously a call to QueryInvoices with reversed=true and index_offset=1 would make the cursor point to the first available invoice (num 1) that would be returned as part of the response. This is inconsistent with the othre indexes, so we instead just return an empty list in this case. A test case for this situation is also added. --- channeldb/invoice_test.go | 21 +++++++++++++++++++++ channeldb/invoices.go | 23 +++++++++++++++++++++-- 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/channeldb/invoice_test.go b/channeldb/invoice_test.go index 5c648112b..3d659c56f 100644 --- a/channeldb/invoice_test.go +++ b/channeldb/invoice_test.go @@ -460,6 +460,27 @@ func TestQueryInvoices(t *testing.T) { }, expected: invoices[10:], }, + // Fetch one invoice, at index 1, reversed. Since invoice#1 is + // the very first, there won't be any left in a reverse search, + // so we expect no invoices to be returned. + { + query: InvoiceQuery{ + IndexOffset: 1, + Reversed: true, + NumMaxInvoices: 1, + }, + expected: nil, + }, + // Same as above, but don't restrict the number of invoices to + // 1. + { + query: InvoiceQuery{ + IndexOffset: 1, + Reversed: true, + NumMaxInvoices: numInvoices, + }, + expected: nil, + }, // Fetch all pending invoices with a single query. { query: InvoiceQuery{ diff --git a/channeldb/invoices.go b/channeldb/invoices.go index e9149c4d6..4b0edffed 100644 --- a/channeldb/invoices.go +++ b/channeldb/invoices.go @@ -484,9 +484,28 @@ func (d *DB) QueryInvoices(q InvoiceQuery) (InvoiceSlice, error) { // our cursor depending on the parameters set within the query. c := invoiceAddIndex.Cursor() invoiceKey := keyForIndex(c, q.IndexOffset+1) + + // If the query is specifying reverse iteration, then we must + // handle a few offset cases. if q.Reversed { - _, invoiceKey = c.Last() - if q.IndexOffset != 0 { + switch q.IndexOffset { + + // This indicates the default case, where no offset was + // specified. In that case we just start from the last + // invoice. + case 0: + _, invoiceKey = c.Last() + + // This indicates the offset being set to the very + // first invoice. Since there are no invoices before + // this offset, and the direction is reversed, we can + // return without adding any invoices to the response. + case 1: + return nil + + // Otherwise we start iteration at the invoice prior to + // the offset. + default: invoiceKey = keyForIndex(c, q.IndexOffset-1) } }