channeldb+lnd: rpc server filters invoices by date

This commit is contained in:
yyforyongyu 2022-11-16 02:03:16 +08:00
parent cfa2cb01d0
commit 234b9a3d97
No known key found for this signature in database
GPG key ID: 9BCD95C4FF296868
3 changed files with 165 additions and 1 deletions

View file

@ -1090,6 +1090,9 @@ func TestQueryInvoices(t *testing.T) {
for i := 1; i <= numInvoices; i++ {
amt := lnwire.MilliSatoshi(i)
invoice, err := randInvoice(amt)
invoice.CreationDate = invoice.CreationDate.Add(
time.Duration(i-1) * time.Second,
)
if err != nil {
t.Fatalf("unable to create invoice: %v", err)
}
@ -1337,6 +1340,116 @@ func TestQueryInvoices(t *testing.T) {
},
expected: invoices,
},
// Fetch invoices <= 25 by creation date.
{
query: InvoiceQuery{
NumMaxInvoices: numInvoices,
CreationDateEnd: time.Unix(25, 0),
},
expected: invoices[:25],
},
// Fetch invoices >= 26 creation date.
{
query: InvoiceQuery{
NumMaxInvoices: numInvoices,
CreationDateStart: time.Unix(26, 0),
},
expected: invoices[25:],
},
// Fetch pending invoices <= 25 by creation date.
{
query: InvoiceQuery{
PendingOnly: true,
NumMaxInvoices: numInvoices,
CreationDateEnd: time.Unix(25, 0),
},
expected: pendingInvoices[:13],
},
// Fetch pending invoices >= 26 creation date.
{
query: InvoiceQuery{
PendingOnly: true,
NumMaxInvoices: numInvoices,
CreationDateStart: time.Unix(26, 0),
},
expected: pendingInvoices[13:],
},
// Fetch pending invoices with offset and end creation date.
{
query: InvoiceQuery{
IndexOffset: 20,
NumMaxInvoices: numInvoices,
CreationDateEnd: time.Unix(30, 0),
},
// Since we're skipping to invoice 20 and iterating
// to invoice 30, we'll expect those invoices.
expected: invoices[20:30],
},
// Fetch pending invoices with offset and start creation date
// in reversed order.
{
query: InvoiceQuery{
IndexOffset: 21,
Reversed: true,
NumMaxInvoices: numInvoices,
CreationDateStart: time.Unix(11, 0),
},
// Since we're skipping to invoice 20 and iterating
// backward to invoice 10, we'll expect those invoices.
expected: invoices[10:20],
},
// Fetch invoices with start and end creation date.
{
query: InvoiceQuery{
NumMaxInvoices: numInvoices,
CreationDateStart: time.Unix(11, 0),
CreationDateEnd: time.Unix(20, 0),
},
expected: invoices[10:20],
},
// Fetch pending invoices with start and end creation date.
{
query: InvoiceQuery{
PendingOnly: true,
NumMaxInvoices: numInvoices,
CreationDateStart: time.Unix(11, 0),
CreationDateEnd: time.Unix(20, 0),
},
expected: pendingInvoices[5:10],
},
// Fetch invoices with start and end creation date in reverse
// order.
{
query: InvoiceQuery{
Reversed: true,
NumMaxInvoices: numInvoices,
CreationDateStart: time.Unix(11, 0),
CreationDateEnd: time.Unix(20, 0),
},
expected: invoices[10:20],
},
// Fetch pending invoices with start and end creation date in
// reverse order.
{
query: InvoiceQuery{
PendingOnly: true,
Reversed: true,
NumMaxInvoices: numInvoices,
CreationDateStart: time.Unix(11, 0),
CreationDateEnd: time.Unix(20, 0),
},
expected: pendingInvoices[5:10],
},
// Fetch invoices with a start date greater than end date
// should result in an empty slice.
{
query: InvoiceQuery{
NumMaxInvoices: numInvoices,
CreationDateStart: time.Unix(20, 0),
CreationDateEnd: time.Unix(11, 0),
},
expected: nil,
},
}
for i, testCase := range testCases {

View file

@ -1279,6 +1279,14 @@ type InvoiceQuery struct {
// Reversed, if set, indicates that the invoices returned should start
// from the IndexOffset and go backwards.
Reversed bool
// CreationDateStart, if set, filters out all invoices with a creation
// date greater than or euqal to it.
CreationDateStart time.Time
// CreationDateEnd, if set, filters out all invoices with a creation
// date less than or euqal to it.
CreationDateEnd time.Time
}
// InvoiceSlice is the response to a invoice query. It includes the original
@ -1309,7 +1317,11 @@ type InvoiceSlice struct {
// QueryInvoices allows a caller to query the invoice database for invoices
// within the specified add index range.
func (d *DB) QueryInvoices(q InvoiceQuery) (InvoiceSlice, error) {
var resp InvoiceSlice
var (
resp InvoiceSlice
startDateSet = !q.CreationDateStart.IsZero()
endDateSet = !q.CreationDateEnd.IsZero()
)
err := kvdb.View(d, func(tx kvdb.RTx) error {
// If the bucket wasn't found, then there aren't any invoices
@ -1349,6 +1361,24 @@ func (d *DB) QueryInvoices(q InvoiceQuery) (InvoiceSlice, error) {
return false, nil
}
// Skip any invoices that were created before the
// specified time.
if startDateSet && invoice.CreationDate.Before(
q.CreationDateStart,
) {
return false, nil
}
// Skip any invoices that were created after the
// specified time.
if endDateSet && invoice.CreationDate.After(
q.CreationDateEnd,
) {
return false, nil
}
// At this point, we've exhausted the offset, so we'll
// begin collecting invoices found within the range.
resp.Invoices = append(resp.Invoices, invoice)

View file

@ -5516,6 +5516,16 @@ func (r *rpcServer) ListInvoices(ctx context.Context,
req.NumMaxInvoices = 100
}
// If both dates are set, we check that the start date is less than the
// end date, otherwise we'll get an empty result.
if req.CreationDateStart != 0 && req.CreationDateEnd != 0 {
if req.CreationDateStart >= req.CreationDateEnd {
return nil, fmt.Errorf("start date(%v) must be before "+
"end date(%v)", req.CreationDateStart,
req.CreationDateEnd)
}
}
// Next, we'll map the proto request into a format that is understood by
// the database.
q := channeldb.InvoiceQuery{
@ -5524,6 +5534,17 @@ func (r *rpcServer) ListInvoices(ctx context.Context,
PendingOnly: req.PendingOnly,
Reversed: req.Reversed,
}
// Attach the start date if set.
if req.CreationDateStart != 0 {
q.CreationDateStart = time.Unix(int64(req.CreationDateStart), 0)
}
// Attach the end date if set.
if req.CreationDateEnd != 0 {
q.CreationDateEnd = time.Unix(int64(req.CreationDateEnd), 0)
}
invoiceSlice, err := r.server.miscDB.QueryInvoices(q)
if err != nil {
return nil, fmt.Errorf("unable to query invoices: %v", err)