channeldb+lnd: rpc server filters invoices by date
This commit is contained in:
3 files changed
+165
-1
No files matched your search
@@ -1090,6 +1090,9 @@ func TestQueryInvoices(t *testing.T) {
|
|||||||
for i := 1; i <= numInvoices; i++ {
|
for i := 1; i <= numInvoices; i++ {
|
||||||
amt := lnwire.MilliSatoshi(i)
|
amt := lnwire.MilliSatoshi(i)
|
||||||
invoice, err := randInvoice(amt)
|
invoice, err := randInvoice(amt)
|
||||||
|
invoice.CreationDate = invoice.CreationDate.Add(
|
||||||
|
time.Duration(i-1) * time.Second,
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to create invoice: %v", err)
|
t.Fatalf("unable to create invoice: %v", err)
|
||||||
}
|
}
|
||||||
@@ -1337,6 +1340,116 @@ func TestQueryInvoices(t *testing.T) {
|
|||||||
},
|
},
|
||||||
expected: invoices,
|
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 {
|
for i, testCase := range testCases {
|
||||||
|
|||||||
+31
-1
@@ -1279,6 +1279,14 @@ type InvoiceQuery struct {
|
|||||||
// Reversed, if set, indicates that the invoices returned should start
|
// Reversed, if set, indicates that the invoices returned should start
|
||||||
// from the IndexOffset and go backwards.
|
// from the IndexOffset and go backwards.
|
||||||
Reversed bool
|
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
|
// 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
|
// QueryInvoices allows a caller to query the invoice database for invoices
|
||||||
// within the specified add index range.
|
// within the specified add index range.
|
||||||
func (d *DB) QueryInvoices(q InvoiceQuery) (InvoiceSlice, error) {
|
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 {
|
err := kvdb.View(d, func(tx kvdb.RTx) error {
|
||||||
// If the bucket wasn't found, then there aren't any invoices
|
// 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
|
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
|
// At this point, we've exhausted the offset, so we'll
|
||||||
// begin collecting invoices found within the range.
|
// begin collecting invoices found within the range.
|
||||||
resp.Invoices = append(resp.Invoices, invoice)
|
resp.Invoices = append(resp.Invoices, invoice)
|
||||||
|
|||||||
@@ -5516,6 +5516,16 @@ func (r *rpcServer) ListInvoices(ctx context.Context,
|
|||||||
req.NumMaxInvoices = 100
|
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
|
// Next, we'll map the proto request into a format that is understood by
|
||||||
// the database.
|
// the database.
|
||||||
q := channeldb.InvoiceQuery{
|
q := channeldb.InvoiceQuery{
|
||||||
@@ -5524,6 +5534,17 @@ func (r *rpcServer) ListInvoices(ctx context.Context,
|
|||||||
PendingOnly: req.PendingOnly,
|
PendingOnly: req.PendingOnly,
|
||||||
Reversed: req.Reversed,
|
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)
|
invoiceSlice, err := r.server.miscDB.QueryInvoices(q)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("unable to query invoices: %v", err)
|
return nil, fmt.Errorf("unable to query invoices: %v", err)
|
||||||
|
|||||||
Reference in new issue
Block a user