channeldb+lnd: rpc server filters payments by date

This commit is contained in:
yyforyongyu 2022-11-16 02:15:24 +08:00
parent b7c829f792
commit e9269c2093
No known key found for this signature in database
GPG Key ID: 9BCD95C4FF296868
3 changed files with 100 additions and 1 deletions

View File

@ -536,6 +536,14 @@ type PaymentsQuery struct {
// CountTotal indicates that all payments currently present in the // CountTotal indicates that all payments currently present in the
// payment index (complete and incomplete) should be counted. // payment index (complete and incomplete) should be counted.
CountTotal bool CountTotal bool
// CreationDateStart, if set, filters out all payments with a creation
// date greater than or euqal to it.
CreationDateStart time.Time
// CreationDateEnd, if set, filters out all payments with a creation
// date less than or euqal to it.
CreationDateEnd time.Time
} }
// PaymentsResponse contains the result of a query to the payments database. // PaymentsResponse contains the result of a query to the payments database.
@ -570,7 +578,11 @@ type PaymentsResponse struct {
// to a subset of payments by the payments query, containing an offset // to a subset of payments by the payments query, containing an offset
// index and a maximum number of returned payments. // index and a maximum number of returned payments.
func (d *DB) QueryPayments(query PaymentsQuery) (PaymentsResponse, error) { func (d *DB) QueryPayments(query PaymentsQuery) (PaymentsResponse, error) {
var resp PaymentsResponse var (
resp PaymentsResponse
startDateSet = !query.CreationDateStart.IsZero()
endDateSet = !query.CreationDateEnd.IsZero()
)
if err := kvdb.View(d, func(tx kvdb.RTx) error { if err := kvdb.View(d, func(tx kvdb.RTx) error {
// Get the root payments bucket. // Get the root payments bucket.
@ -615,6 +627,24 @@ func (d *DB) QueryPayments(query PaymentsQuery) (PaymentsResponse, error) {
return false, err return false, err
} }
// Skip any payments that were created before the
// specified time.
if startDateSet && payment.Info.CreationTime.Before(
query.CreationDateStart,
) {
return false, nil
}
// Skip any payments that were created after the
// specified time.
if endDateSet && payment.Info.CreationTime.After(
query.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.Payments = append(resp.Payments, payment) resp.Payments = append(resp.Payments, payment)

View File

@ -391,6 +391,48 @@ func TestQueryPayments(t *testing.T) {
lastIndex: 4, lastIndex: 4,
expectedSeqNrs: []uint64{3, 4}, expectedSeqNrs: []uint64{3, 4},
}, },
{
name: "query in forwards order, with start creation " +
"time",
query: PaymentsQuery{
IndexOffset: 0,
MaxPayments: 2,
Reversed: false,
IncludeIncomplete: true,
CreationDateStart: time.Unix(0, 5),
},
firstIndex: 5,
lastIndex: 6,
expectedSeqNrs: []uint64{5, 6},
},
{
name: "query in forwards order, with start creation " +
"time at end, overflow",
query: PaymentsQuery{
IndexOffset: 0,
MaxPayments: 2,
Reversed: false,
IncludeIncomplete: true,
CreationDateStart: time.Unix(0, 7),
},
firstIndex: 7,
lastIndex: 7,
expectedSeqNrs: []uint64{7},
},
{
name: "query with start and end creation time",
query: PaymentsQuery{
IndexOffset: 9,
MaxPayments: math.MaxUint64,
Reversed: true,
IncludeIncomplete: true,
CreationDateStart: time.Unix(0, 3),
CreationDateEnd: time.Unix(0, 5),
},
firstIndex: 3,
lastIndex: 5,
expectedSeqNrs: []uint64{3, 4, 5},
},
} }
for _, tt := range tests { for _, tt := range tests {
@ -426,6 +468,9 @@ func TestQueryPayments(t *testing.T) {
t.Fatalf("unable to create test "+ t.Fatalf("unable to create test "+
"payment: %v", err) "payment: %v", err)
} }
// Override creation time to allow for testing
// of CreationDateStart and CreationDateEnd.
info.CreationTime = time.Unix(0, int64(i+1))
// Create a new payment entry in the database. // Create a new payment entry in the database.
err = pControl.InitPayment(info.PaymentIdentifier, info) err = pControl.InitPayment(info.PaymentIdentifier, info)

View File

@ -6359,6 +6359,16 @@ func (r *rpcServer) ListPayments(ctx context.Context,
rpcsLog.Debugf("[ListPayments]") rpcsLog.Debugf("[ListPayments]")
// 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)
}
}
query := channeldb.PaymentsQuery{ query := channeldb.PaymentsQuery{
IndexOffset: req.IndexOffset, IndexOffset: req.IndexOffset,
MaxPayments: req.MaxPayments, MaxPayments: req.MaxPayments,
@ -6367,6 +6377,20 @@ func (r *rpcServer) ListPayments(ctx context.Context,
CountTotal: req.CountTotalPayments, CountTotal: req.CountTotalPayments,
} }
// Attach the start date if set.
if req.CreationDateStart != 0 {
query.CreationDateStart = time.Unix(
int64(req.CreationDateStart), 0,
)
}
// Attach the end date if set.
if req.CreationDateEnd != 0 {
query.CreationDateEnd = time.Unix(
int64(req.CreationDateEnd), 0,
)
}
// If the maximum number of payments wasn't specified, then we'll // If the maximum number of payments wasn't specified, then we'll
// default to return the maximal number of payments representable. // default to return the maximal number of payments representable.
if req.MaxPayments == 0 { if req.MaxPayments == 0 {