-
Notifications
You must be signed in to change notification settings - Fork 1
Description
The transactions list on the account details page disables further backwards pagination before the account's entire history has been fetched.
See https://explorer.keeta.com/account/keeta_aabz3d44rtskt2ofgjuiqpym6xmlbjblgi7hax4ipoykrgmdkyf45x3s4mcmeyi for an example:
We can see that the account did a KTA - MURF swap of significant size, but since the history backwards pagination button at the bottom right is disabled, it looks like we are at the end of the account's history and it performed the swap without ever receiving the funds in the first place.
Looking at the API response of the reps we can see that the account has in fact more history than what is shown and that it received the funds before correctly as expected.
Reason
The reason for this bug lies in the way the explorer SDK's transactions function determines whether a next page is available:
explorer/apps/web/src/libs/explorer-sdk.ts
Lines 334 to 344 in 4e181df
| const history = await this.client.getHistory(account, { depth, startBlocksHash }); | |
| const voteStaples = history.flatMap(({ voteStaple }) => { | |
| return voteStaple; | |
| }); | |
| const normalizedOperations = normalizeOperations(voteStaples, account) | |
| const stapleOperations = normalizedOperations.map(normalizedOperationToJSONSerializable); | |
| const nextCursor = (account && stapleOperations.find(op => op.block.$opening && account.comparePublicKey(op.block.account))) ? null : stapleOperations.at(-1)?.voteStapleHash | |
| return({ nextCursor, stapleOperations }); |
When the opening block for an account is found, nextCursor is set to null and the pagination effectively stops.
However, the getHistory endpoint returns all staples that have interacted with this account which includes staples not created by the account directly. So while the opening block is the first block created on the account's chain, there may have been many blocks before that which affected the account as we can see in the example above.
Potential Solution
Per the getHistory docs:
Once all vote staples have been fetched an empty array will be returned.
Therefore, the explorer could always try to fetch one vote staple of the next page via ?limit=1&start={nextCursor} and see if the array returned is empty to determine whether to disable the button or not.