taler-typescript-core

Wallet core logic and WebUIs for various components
Log | Files | Refs | Submodules | README | LICENSE

commit c2d7afb6b12d09b6317592eea09932c63d9061bb
parent 789181404c493761a407d0190b0a0a5f11723428
Author: Florian Dold <dold@taler.net>
Date:   Wed, 22 Jul 2026 15:35:09 +0200

wallet: walk the ordered list when listing transactions forwards

The timestamp index is not unique, so continuing after the timestamp of the
last record of a page drops the records that share it.  The descending case
already walked the list for this reason; both directions now share that path.

Diffstat:
Mpackages/taler-wallet-core/src/transactions.ts | 37+++++++++----------------------------
1 file changed, 9 insertions(+), 28 deletions(-)

diff --git a/packages/taler-wallet-core/src/transactions.ts b/packages/taler-wallet-core/src/transactions.ts @@ -376,12 +376,18 @@ export async function getTransactionsV2( onlyActive: false, }); await addFiltered(wex, tx, transactionsRequest, resultTransactions, res); - } else if (!forwards) { - // Descending, backwards request. + } else { // Slow implementation. Doing it properly would require using cursors, // which are also slow in IndexedDB. + // + // The list is walked rather than paged through the timestamp index, + // because that index is not unique: a bound on the timestamp alone + // cannot separate two transactions that share one, so paging on it + // skips the rest of a run that a page ended in the middle of. const res = await tx.listTransactionMetaByTimestamp({}); - res.reverse(); + if (!forwards) { + res.reverse(); + } let start: number; if (offsetMtx != null) { const needleTxId = offsetMtx.transactionId; @@ -402,31 +408,6 @@ export async function getTransactionsV2( res[i], ]); } - } else { - // Forward request - let afterTimestamp: DbPreciseTimestamp | undefined = - offsetMtx != null ? offsetMtx.timestamp : undefined; - while (true) { - const res = await tx.listTransactionMetaByTimestamp({ - afterTimestamp, - limit, - }); - if (res.length === 0) { - break; - } - await addFiltered( - wex, - tx, - transactionsRequest, - resultTransactions, - res, - ); - if (limit != null && resultTransactions.length >= limit) { - break; - } - // Continue after last result - afterTimestamp = res[res.length - 1].timestamp; - } } });