commit b57f850195d951db1de88c97e15a669e5d2e805b
parent 7e33bc8c4ad2bb8479a6dd66212613963d4d6b08
Author: Florian Dold <florian@dold.me>
Date: Tue, 14 Jan 2025 21:05:11 +0100
wallet-core: only transition exchange entry if update is really required
Diffstat:
1 file changed, 75 insertions(+), 75 deletions(-)
diff --git a/packages/taler-wallet-core/src/exchanges.ts b/packages/taler-wallet-core/src/exchanges.ts
@@ -1155,95 +1155,95 @@ async function startUpdateExchangeEntry(
return provideExchangeRecordInTx(wex.ws, tx, exchangeBaseUrl);
},
);
-
- logger.trace("created exchange record");
-
if (notification) {
wex.ws.notify(notification);
}
- const { oldExchangeState, newExchangeState, taskId } =
- await wex.db.runReadWriteTx(
- { storeNames: ["exchanges", "operationRetries", "denominations"] },
- async (tx) => {
- const r = await tx.exchanges.get(exchangeBaseUrl);
- if (!r) {
- throw Error("exchange not found");
- }
-
- // FIXME: Do not transition at all if the exchange info is recent enough
- // and the request is not forced.
+ const res = await wex.db.runReadWriteTx(
+ { storeNames: ["exchanges", "operationRetries", "denominations"] },
+ async (tx) => {
+ const r = await tx.exchanges.get(exchangeBaseUrl);
+ if (!r) {
+ throw Error("exchange not found");
+ }
- const oldExchangeState = getExchangeState(r);
- switch (r.updateStatus) {
- case ExchangeEntryDbUpdateStatus.UnavailableUpdate:
- r.cachebreakNextUpdate = options.forceUpdate;
- break;
- case ExchangeEntryDbUpdateStatus.Suspended:
- r.cachebreakNextUpdate = options.forceUpdate;
- break;
- case ExchangeEntryDbUpdateStatus.ReadyUpdate: {
- const outdated = await checkExchangeEntryOutdated(
- wex,
- tx,
- exchangeBaseUrl,
- );
- if (outdated) {
- r.updateStatus = ExchangeEntryDbUpdateStatus.OutdatedUpdate;
- } else {
- r.updateStatus = ExchangeEntryDbUpdateStatus.ReadyUpdate;
- }
- r.cachebreakNextUpdate = options.forceUpdate;
- break;
+ const oldExchangeState = getExchangeState(r);
+ switch (r.updateStatus) {
+ case ExchangeEntryDbUpdateStatus.UnavailableUpdate:
+ r.cachebreakNextUpdate = options.forceUpdate;
+ break;
+ case ExchangeEntryDbUpdateStatus.Suspended:
+ r.cachebreakNextUpdate = options.forceUpdate;
+ break;
+ case ExchangeEntryDbUpdateStatus.ReadyUpdate: {
+ const outdated = await checkExchangeEntryOutdated(
+ wex,
+ tx,
+ exchangeBaseUrl,
+ );
+ if (outdated) {
+ r.updateStatus = ExchangeEntryDbUpdateStatus.OutdatedUpdate;
+ } else {
+ r.updateStatus = ExchangeEntryDbUpdateStatus.ReadyUpdate;
}
- case ExchangeEntryDbUpdateStatus.OutdatedUpdate:
- r.cachebreakNextUpdate = options.forceUpdate;
- break;
- case ExchangeEntryDbUpdateStatus.Ready: {
- const nextUpdateTimestamp = AbsoluteTime.fromPreciseTimestamp(
- timestampPreciseFromDb(r.nextUpdateStamp),
- );
- // Only update if entry is outdated or update is forced.
- if (
- options.forceUpdate ||
- AbsoluteTime.isExpired(nextUpdateTimestamp)
- ) {
- const outdated = await checkExchangeEntryOutdated(
- wex,
- tx,
- exchangeBaseUrl,
- );
- if (outdated) {
- r.updateStatus = ExchangeEntryDbUpdateStatus.OutdatedUpdate;
- } else {
- r.updateStatus = ExchangeEntryDbUpdateStatus.ReadyUpdate;
- }
- r.cachebreakNextUpdate = options.forceUpdate;
- }
- break;
+ r.cachebreakNextUpdate = options.forceUpdate;
+ break;
+ }
+ case ExchangeEntryDbUpdateStatus.OutdatedUpdate:
+ r.cachebreakNextUpdate = options.forceUpdate;
+ break;
+ case ExchangeEntryDbUpdateStatus.Ready: {
+ const nextUpdateTimestamp = AbsoluteTime.fromPreciseTimestamp(
+ timestampPreciseFromDb(r.nextUpdateStamp),
+ );
+ // Only update if entry is outdated or update is forced.
+ if (
+ !(
+ options.forceUpdate || AbsoluteTime.isExpired(nextUpdateTimestamp)
+ )
+ ) {
+ return undefined;
}
- case ExchangeEntryDbUpdateStatus.Initial:
- r.cachebreakNextUpdate = options.forceUpdate;
- r.updateStatus = ExchangeEntryDbUpdateStatus.InitialUpdate;
- break;
- case ExchangeEntryDbUpdateStatus.InitialUpdate:
- r.cachebreakNextUpdate = options.forceUpdate;
- break;
+ const outdated = await checkExchangeEntryOutdated(
+ wex,
+ tx,
+ exchangeBaseUrl,
+ );
+ if (outdated) {
+ r.updateStatus = ExchangeEntryDbUpdateStatus.OutdatedUpdate;
+ } else {
+ r.updateStatus = ExchangeEntryDbUpdateStatus.ReadyUpdate;
+ }
+ r.cachebreakNextUpdate = options.forceUpdate;
+ break;
}
- wex.ws.exchangeCache.clear();
- await tx.exchanges.put(r);
- const newExchangeState = getExchangeState(r);
- const taskId = TaskIdentifiers.forExchangeUpdate(r);
- return { oldExchangeState, newExchangeState, taskId };
- },
- );
+ case ExchangeEntryDbUpdateStatus.Initial:
+ r.cachebreakNextUpdate = options.forceUpdate;
+ r.updateStatus = ExchangeEntryDbUpdateStatus.InitialUpdate;
+ break;
+ case ExchangeEntryDbUpdateStatus.InitialUpdate:
+ r.cachebreakNextUpdate = options.forceUpdate;
+ break;
+ }
+ wex.ws.exchangeCache.clear();
+ await tx.exchanges.put(r);
+ const newExchangeState = getExchangeState(r);
+ const taskId = TaskIdentifiers.forExchangeUpdate(r);
+ return { oldExchangeState, newExchangeState, taskId };
+ },
+ );
+ if (!res) {
+ // Exchange entry is already good.
+ return;
+ }
+ const { oldExchangeState, newExchangeState, taskId } = res;
wex.ws.notify({
type: NotificationType.ExchangeStateTransition,
exchangeBaseUrl,
newExchangeState: newExchangeState,
oldExchangeState: oldExchangeState,
});
- logger.info(`start update ${exchangeBaseUrl} task ${taskId}`);
+ logger.info(`updating exchange in task ${taskId}`);
await wex.taskScheduler.resetTaskRetries(taskId);
}