pagination: add pagination to wallet transactions#8998
pagination: add pagination to wallet transactions#8998guggero merged 5 commits intolightningnetwork:masterfrom
Conversation
|
Important Review skippedAuto reviews are limited to specific labels. 🏷️ Labels to auto review (1)
Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
guggero
left a comment
There was a problem hiding this comment.
Thanks for the PR. Looks pretty good already, have a bit of early feedback.
lnwallet/interface.go
Outdated
| // empty, transactions of all wallet accounts are returned. | ||
| ListTransactionDetails(startHeight, endHeight int32, | ||
| accountFilter string) ([]*TransactionDetail, error) | ||
| accountFilter string, indexOffset int, maxTnxs int) ([]*TransactionDetail, error) |
There was a problem hiding this comment.
nit: break before maxTnxs to avoid too long line. Also, should be spelled maxTxns?
There was a problem hiding this comment.
Avoiding a long line was why I named it maxTnx, but after breaking the line, I now renamed it to maxTransactions
There was a problem hiding this comment.
Looks like this is still unaddressed?
There was a problem hiding this comment.
Oh I see, I unintentionally addressed this in another commit
rpcserver.go
Outdated
| } | ||
|
|
||
| // To remain backward compatible, If the number of transactions was not | ||
| // specified, then we'll default to returning the entire transactions |
There was a problem hiding this comment.
nit: missing full stop at end of sentence.
There was a problem hiding this comment.
Unresolving this issue as it's not addressed.
Thanks for taking a look. I will address the feedback you left. |
21fb0a8 to
a6609f5
Compare
I've addressed the feedback you left, added a few changes too. |
guggero
left a comment
There was a problem hiding this comment.
Thanks for adding the extra parameters. Still needs a few updates before I'll start manual testing. But getting there 👍
lnwallet/interface.go
Outdated
| // empty, transactions of all wallet accounts are returned. | ||
| ListTransactionDetails(startHeight, endHeight int32, | ||
| accountFilter string) ([]*TransactionDetail, error) | ||
| accountFilter string, indexOffset int, maxTnxs int) ([]*TransactionDetail, error) |
There was a problem hiding this comment.
Looks like this is still unaddressed?
31aed37 to
594f3f1
Compare
594f3f1 to
e4c47bb
Compare
|
@Abdulkbk, remember to re-request review from reviewers when ready |
e4c47bb to
e5458b9
Compare
|
Approved CI run |
guggero
left a comment
There was a problem hiding this comment.
Thanks for the updates! Did another pass, we're definitely getting closer.
lnwallet/btcwallet/btcwallet.go
Outdated
| return txDetails[indexOffset:end], nil | ||
| txDetails = txDetails[indexOffset:end] | ||
|
|
||
| return txDetails, uint64(firstIdx), uint64(lastIdx), nil |
There was a problem hiding this comment.
Why do we need these two extra variables at all? Shouldn't firstIdx = indexOffset and lastIdx = end-1?
There was a problem hiding this comment.
If my previous comment is correct, then this wouldn't be the case. However, I can replace the end variable with lastIdx, since they are the same?.
There was a problem hiding this comment.
We'll want zero-based indexes here. See my other comment, unfortunately the invoices template you looked at has a special case with 0 that we don't need to port over to this.
There was a problem hiding this comment.
I updated it to use a zero-based index.
lnwallet/btcwallet/btcwallet.go
Outdated
| // If maxTransactions is set to -1, then we'll return all transactions | ||
| // starting from the offset. | ||
| if maxTransactions == -1 { | ||
| lastIdx = len(txDetails) |
There was a problem hiding this comment.
This is incorrect. The last index is len(txDetails)-1. But for the slice access ([a:b]) it's correct, since b is exclusive.
There was a problem hiding this comment.
My understanding is that first_index_offset and last_index_offset are 1-based indices. I am using the implementation found here as a reference, and it states here that the AddIndex starts from 1.
Also since the last_index_offset will be used as the new index_offset for the next call, wouldn't returning len(txDetails)-1 result in repeating the last transaction from the previous call as the first transaction in the new call? This is because the slice access [indexOffset: ...] is inclusive.
There was a problem hiding this comment.
Unfortunately the example from the invoices is a bad one. There the add index has a special meaning and zero is kind of a special case...
But an index in a pagination should always return the exact indexes of the first and last entry. Then my pagination query can just look something like this (pseudo code):
offset := 0
pageSize := 20
result := nil
for {
result = query(offset, pageSize)
if len(result) < pageSize {
return
}
offset = result.last_index + 1
}
36a59ed to
650de87
Compare
|
Thank you, @guggero. I have addressed your feedback and left some questions. |
lnwallet/btcwallet/btcwallet.go
Outdated
| // If maxTransactions is set to -1, then we'll return all transactions | ||
| // starting from the offset. | ||
| if maxTransactions == -1 { | ||
| lastIdx = len(txDetails) |
There was a problem hiding this comment.
Unfortunately the example from the invoices is a bad one. There the add index has a special meaning and zero is kind of a special case...
But an index in a pagination should always return the exact indexes of the first and last entry. Then my pagination query can just look something like this (pseudo code):
offset := 0
pageSize := 20
result := nil
for {
result = query(offset, pageSize)
if len(result) < pageSize {
return
}
offset = result.last_index + 1
}
lnwallet/btcwallet/btcwallet.go
Outdated
| return txDetails[indexOffset:end], nil | ||
| txDetails = txDetails[indexOffset:end] | ||
|
|
||
| return txDetails, uint64(firstIdx), uint64(lastIdx), nil |
There was a problem hiding this comment.
We'll want zero-based indexes here. See my other comment, unfortunately the invoices template you looked at has a special case with 0 that we don't need to port over to this.
yyforyongyu
left a comment
There was a problem hiding this comment.
Very useful feature! Left some comments re how to test it more to make it robust.
lnrpc/lightning.proto
Outdated
| The maximal number of transactions returned in the response to this query. | ||
| This value should be set to -1 to return all transactions. | ||
| */ | ||
| int32 max_transactions = 5; |
There was a problem hiding this comment.
hmmm as a user I would be a bit confused here...why would i ever wanna the RPC to return zero num of txns? Should we instead use 0 as the default, and return all the txns if max_transactions is not set(hence 0)?
Think using 0 also has the benefit of setting this to uint32, so it's never negative - one less case to worry about.
There was a problem hiding this comment.
Yes, I believe this makes a lot of sense.
rpcserver.go
Outdated
| } | ||
|
|
||
| // To remain backward compatible, If the number of transactions was not | ||
| // specified, then we'll default to returning the entire transactions |
There was a problem hiding this comment.
Unresolving this issue as it's not addressed.
lnwallet/test/test_interface.go
Outdated
| t.Fatalf("expected 0 transactions, got: %v", len(txDetails)) | ||
| } | ||
|
|
||
| // Next we try to query for only 5 transactions. |
There was a problem hiding this comment.
seems a perfect fit for table-driven tests, if it's easier, we can copy the part where we create all the txns in testListTransactionDetails, create a new test testListTransactionDetailsOffset, and check all the cases.
- when there are no txns, a larger
index_offsetshould give us nothing. - when there are no txns, a larger
max_transactionsshould give us nothing. - when there are no txns, larger
max_transactionsandindex_offsetshould give us nothing. - when there are 10 txns, check
index_offset=0, max_transactions=-1for the default case - when there are 10 txns, check
index_offset=5, max_transactions=-1for a within bound offset - when there are 10 txns, check
index_offset=9, max_transactions=-1for an edge offset - when there are 10 txns, check
index_offset=10, max_transactions=-1for an outbound offset - when there are 10 txns, check
index_offset=0, max_transactions=1for a within bound max num - when there are 10 txns, check
index_offset=0, max_transactions=10for an edge max num - when there are 10 txns, check
index_offset=0, max_transactions=11for an outbound max num
There was a problem hiding this comment.
I have created a new commit and added a new test as you suggested.
650de87 to
7c8cf9d
Compare
5f6fef4 to
35b8812
Compare
|
Thank you, @guggero and @yyforyongyu, for your review. I have addressed the feedback you left. |
guggero
left a comment
There was a problem hiding this comment.
One last nit. And an entry in the docs/release-notes/release-notes-0.19.0.md file would be nice, then this can land 🎉
35b8812 to
61ed760
Compare
|
Thank you, @guggero. I have addressed your feedback and added a release note. |
This commit adds index_offset and max_transactions to the list of parameters passed during gettransactions call. index_offset specify transactions to skip and max_transactions the total transactions returned
61ed760 to
d131218
Compare
|
approved CI run, which take a final look when it is completed! |
d131218 to
cf1fb70
Compare
noticed the linter reported unnecessary trailing space in the code, so I fixed that. |
yyforyongyu
left a comment
There was a problem hiding this comment.
One final thing re the unit test, then it's good to go!
lnwallet/test/test_interface.go
Outdated
| startHeight, chainTip, "", 0, 10, | ||
| ) | ||
| require.NoError(t, err) | ||
| require.Less(t, len(txDetails), 10) |
There was a problem hiding this comment.
that's do a strict check to be safu? require.Len(t, txDetails, 5)
This commit modifies listtransactiondetails method definition to take in additional params: index_offset and maxTxn
In this commit we introduce first and last indices for the tranasctions returned which can be used to seek for further transactions in a pagination style. Signed-off-by: Abdullahi Yunus <abdoollahikbk@gmail.com>
In this commit, we test for different values of index_offset and max_transactions settings when getting transactions to make sure the right number of transactions are returned along with the right first and last indices.
cf1fb70 to
1c6790b
Compare
|
I've addressed the feedback you left @yyforyongyu |
fixes #4719
Change Description
This PR adds pagination to getting transactions RPC calls by introducing index_offset and max_transactions
to specify the number of transactions to skip and the maximum number of transactions to return respectively.
Steps to Test
Steps for reviewers to follow to test the change.
lncli listchaintxns -index_offset=n -max_transactions=mwhere n and m are any numbersnnumbers of transactions and withmtransactionsPull Request Checklist
Testing
Code Style and Documentation
[skip ci]in the commit message for small changes.📝 Please see our Contribution Guidelines for further guidance.