Skip to content

Commit

Permalink
feat(mpay): add pagination to mpay-list (#650)
Browse files Browse the repository at this point in the history
  • Loading branch information
maybeast authored Aug 23, 2024
1 parent 03f2cf5 commit 000fd5c
Show file tree
Hide file tree
Showing 10 changed files with 190 additions and 128 deletions.
2 changes: 1 addition & 1 deletion tools/plugins/hold/protos/hold_pb2_grpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import hold_pb2 as hold__pb2

GRPC_GENERATED_VERSION = '1.65.4'
GRPC_GENERATED_VERSION = '1.65.5'
GRPC_VERSION = grpc.__version__
EXPECTED_ERROR_RELEASE = '1.66.0'
SCHEDULED_RELEASE_DATE = 'August 6, 2024'
Expand Down
23 changes: 20 additions & 3 deletions tools/plugins/mpay/data/payments.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from __future__ import annotations

from typing import Iterator

from sqlalchemy import select
Expand All @@ -9,14 +11,23 @@
class Payments:
@staticmethod
def fetch(s: Session, payment_hash: str) -> Iterator[Payment]:
return Payments._fetch(s, payment_hash)
return Payments._fetch(s, payment_hash, None, None)

@staticmethod
def fetch_all(s: Session) -> Iterator[Payment]:
return Payments._fetch(s, None)
return Payments._fetch(s, None, None, None)

@staticmethod
def fetch_paginated(s: Session, start_id: int, offset: int) -> Iterator[Payment]:
return Payments._fetch(s, None, start_id, offset)

@staticmethod
def _fetch(s: Session, payment_hash: str | None) -> Iterator[Payment]:
def _fetch(
s: Session,
payment_hash: str | None,
offset: int | None,
limit: int | None,
) -> Iterator[Payment]:
query = (
select(Payment)
.order_by(Payment.created_at)
Expand All @@ -26,5 +37,11 @@ def _fetch(s: Session, payment_hash: str | None) -> Iterator[Payment]:
if payment_hash is not None:
query = query.where(Payment.payment_hash == payment_hash)

if offset is not None:
query = query.where(Payment.id > offset)

if limit is not None:
query = query.limit(limit)

for row in s.execute(query).unique():
yield row[0]
6 changes: 6 additions & 0 deletions tools/plugins/mpay/protos/mpay.proto
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,15 @@ message ListPaymentsRequest {
oneof identifier {
string bolt11 = 1;
string payment_hash = 2;
PaginationParams pagination = 3;
}
}

message PaginationParams {
uint64 offset = 1;
uint32 limit = 2;
}

message ListPaymentsResponse {
message Payment {
message Attempt {
Expand Down
42 changes: 22 additions & 20 deletions tools/plugins/mpay/protos/mpay_pb2.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 12 additions & 2 deletions tools/plugins/mpay/protos/mpay_pb2.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,22 @@ class GetRoutesResponse(_message.Message):
def __init__(self, routes: _Optional[_Mapping[str, GetRoutesResponse.Routes]] = ...) -> None: ...

class ListPaymentsRequest(_message.Message):
__slots__ = ("bolt11", "payment_hash")
__slots__ = ("bolt11", "payment_hash", "pagination")
BOLT11_FIELD_NUMBER: _ClassVar[int]
PAYMENT_HASH_FIELD_NUMBER: _ClassVar[int]
PAGINATION_FIELD_NUMBER: _ClassVar[int]
bolt11: str
payment_hash: str
def __init__(self, bolt11: _Optional[str] = ..., payment_hash: _Optional[str] = ...) -> None: ...
pagination: PaginationParams
def __init__(self, bolt11: _Optional[str] = ..., payment_hash: _Optional[str] = ..., pagination: _Optional[_Union[PaginationParams, _Mapping]] = ...) -> None: ...

class PaginationParams(_message.Message):
__slots__ = ("offset", "limit")
OFFSET_FIELD_NUMBER: _ClassVar[int]
LIMIT_FIELD_NUMBER: _ClassVar[int]
offset: int
limit: int
def __init__(self, offset: _Optional[int] = ..., limit: _Optional[int] = ...) -> None: ...

class ListPaymentsResponse(_message.Message):
__slots__ = ("payments",)
Expand Down
2 changes: 1 addition & 1 deletion tools/plugins/mpay/protos/mpay_pb2_grpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import mpay_pb2 as mpay__pb2

GRPC_GENERATED_VERSION = '1.65.4'
GRPC_GENERATED_VERSION = '1.65.5'
GRPC_VERSION = grpc.__version__
EXPECTED_ERROR_RELEASE = '1.66.0'
SCHEDULED_RELEASE_DATE = 'August 6, 2024'
Expand Down
9 changes: 8 additions & 1 deletion tools/plugins/mpay/rpc/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,14 @@ def ListPayments( # noqa: N802
payment_hash = bolt11_decode(request.bolt11).payment_hash

with Session(self._db.engine) as s:
res = Payments.fetch(s, payment_hash) if payment_hash != "" else Payments.fetch_all(s)
if payment_hash != "":
res = Payments.fetch(s, payment_hash)
elif request.HasField("pagination"):
res = Payments.fetch_paginated(
s, request.pagination.offset, request.pagination.limit
)
else:
res = Payments.fetch_all(s)
return ListPaymentsResponse(payments=[payment_to_grpc(payment) for payment in res])

def ResetPathMemory( # noqa: N802
Expand Down
19 changes: 18 additions & 1 deletion tools/plugins/mpay/rpc/tests/test_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
GetRoutesResponse,
ListPaymentsRequest,
ListPaymentsResponse,
PaginationParams,
PayRequest,
PayResponse,
ResetPathMemoryRequest,
Expand Down Expand Up @@ -107,7 +108,7 @@ def test_get_routes_min_success(
assert len(res.routes) == 0

def test_list_payments(self, cl: MpayStub) -> None:
res: ListPaymentsResponse = cl.ListPayments(ListPaymentsResponse())
res: ListPaymentsResponse = cl.ListPayments(ListPaymentsRequest())
assert len(res.payments) == 2

for i, payment in enumerate(res.payments):
Expand All @@ -121,6 +122,22 @@ def test_list_payments(self, cl: MpayStub) -> None:
assert payment.ok
assert len(payment.attempts) > 0

res: ListPaymentsResponse = cl.ListPayments(
ListPaymentsRequest(
pagination=PaginationParams(offset=0, limit=1),
)
)
assert len(res.payments) == 1
assert res.payments[0].id == 1

res: ListPaymentsResponse = cl.ListPayments(
ListPaymentsRequest(
pagination=PaginationParams(offset=1, limit=1),
)
)
assert len(res.payments) == 1
assert res.payments[0].id == 2

def test_list_payments_payment_hash(self, cl: MpayStub) -> None:
payment_hash = cln_con("listpays")["pays"][-1]["payment_hash"]
res: ListPaymentsResponse = cl.ListPayments(ListPaymentsRequest(payment_hash=payment_hash))
Expand Down
Loading

0 comments on commit 000fd5c

Please sign in to comment.