From cd8f76db61f4a1ab1a8a8a4d29b2f3e863b59854 Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Fri, 26 May 2023 12:19:32 +0200 Subject: taler-util,wallet-core: implement TalerPreciseTimestamp Fixes #7703 --- .../taler-wallet-core/src/operations/attention.ts | 3 ++- .../src/operations/backup/export.ts | 5 ++-- .../src/operations/backup/import.ts | 5 ++-- .../src/operations/backup/index.ts | 21 +++++++++-------- .../taler-wallet-core/src/operations/deposits.ts | 27 +++++++++++----------- .../taler-wallet-core/src/operations/exchanges.ts | 23 ++++++++++-------- .../src/operations/pay-merchant.ts | 19 +++++++-------- .../taler-wallet-core/src/operations/pay-peer.ts | 17 +++++++------- .../taler-wallet-core/src/operations/pending.ts | 6 ++--- .../taler-wallet-core/src/operations/recoup.ts | 5 ++-- .../taler-wallet-core/src/operations/refresh.ts | 19 +++++++-------- .../taler-wallet-core/src/operations/testing.ts | 4 ++-- packages/taler-wallet-core/src/operations/tip.ts | 7 +++--- .../src/operations/transactions.ts | 7 +++--- .../taler-wallet-core/src/operations/withdraw.ts | 19 +++++++-------- 15 files changed, 102 insertions(+), 85 deletions(-) (limited to 'packages/taler-wallet-core/src/operations') diff --git a/packages/taler-wallet-core/src/operations/attention.ts b/packages/taler-wallet-core/src/operations/attention.ts index 95db7bde0..b802b15cd 100644 --- a/packages/taler-wallet-core/src/operations/attention.ts +++ b/packages/taler-wallet-core/src/operations/attention.ts @@ -22,6 +22,7 @@ import { AttentionInfo, Logger, TalerProtocolTimestamp, + TalerPreciseTimestamp, UserAttentionByIdRequest, UserAttentionPriority, UserAttentionsCountResponse, @@ -95,7 +96,7 @@ export async function markAttentionRequestAsRead( if (!ua) throw Error("attention request not found"); tx.userAttention.put({ ...ua, - read: TalerProtocolTimestamp.now(), + read: TalerPreciseTimestamp.now(), }); }); } diff --git a/packages/taler-wallet-core/src/operations/backup/export.ts b/packages/taler-wallet-core/src/operations/backup/export.ts index 7b245a4eb..ff5f1e177 100644 --- a/packages/taler-wallet-core/src/operations/backup/export.ts +++ b/packages/taler-wallet-core/src/operations/backup/export.ts @@ -62,6 +62,7 @@ import { Logger, stringToBytes, WalletBackupContentV1, + TalerPreciseTimestamp, } from "@gnu-taler/taler-util"; import { CoinSourceType, @@ -521,7 +522,7 @@ export async function exportBackup( }); }); - const ts = AbsoluteTime.toTimestamp(AbsoluteTime.now()); + const ts = TalerPreciseTimestamp.now(); if (!bs.lastBackupTimestamp) { bs.lastBackupTimestamp = ts; @@ -565,7 +566,7 @@ export async function exportBackup( bs.lastBackupNonce = encodeCrock(getRandomBytes(32)); logger.trace( `setting timestamp to ${AbsoluteTime.toIsoString( - AbsoluteTime.fromTimestamp(ts), + AbsoluteTime.fromPreciseTimestamp(ts), )} and nonce to ${bs.lastBackupNonce}`, ); await tx.config.put({ diff --git a/packages/taler-wallet-core/src/operations/backup/import.ts b/packages/taler-wallet-core/src/operations/backup/import.ts index 5375a58bb..6d78b2be0 100644 --- a/packages/taler-wallet-core/src/operations/backup/import.ts +++ b/packages/taler-wallet-core/src/operations/backup/import.ts @@ -35,6 +35,7 @@ import { PayCoinSelection, RefreshReason, TalerProtocolTimestamp, + TalerPreciseTimestamp, WalletBackupContentV1, WireInfo, } from "@gnu-taler/taler-util"; @@ -349,8 +350,8 @@ export async function importBackup( }, permanent: true, lastUpdate: undefined, - nextUpdate: TalerProtocolTimestamp.now(), - nextRefreshCheck: TalerProtocolTimestamp.now(), + nextUpdate: TalerPreciseTimestamp.now(), + nextRefreshCheck: TalerPreciseTimestamp.now(), lastKeysEtag: undefined, lastWireEtag: undefined, }); diff --git a/packages/taler-wallet-core/src/operations/backup/index.ts b/packages/taler-wallet-core/src/operations/backup/index.ts index 59e99b505..f726167da 100644 --- a/packages/taler-wallet-core/src/operations/backup/index.ts +++ b/packages/taler-wallet-core/src/operations/backup/index.ts @@ -71,6 +71,7 @@ import { TalerErrorCode, TalerErrorDetail, TalerProtocolTimestamp, + TalerPreciseTimestamp, URL, WalletBackupContentV1, } from "@gnu-taler/taler-util"; @@ -246,9 +247,9 @@ interface BackupForProviderArgs { backupProviderBaseUrl: string; } -function getNextBackupTimestamp(): TalerProtocolTimestamp { +function getNextBackupTimestamp(): TalerPreciseTimestamp { // FIXME: Randomize! - return AbsoluteTime.toTimestamp( + return AbsoluteTime.toPreciseTimestamp( AbsoluteTime.addDuration( AbsoluteTime.now(), durationFromSpec({ minutes: 5 }), @@ -329,7 +330,7 @@ async function runBackupCycleForProvider( if (!prov) { return; } - prov.lastBackupCycleTimestamp = TalerProtocolTimestamp.now(); + prov.lastBackupCycleTimestamp = TalerPreciseTimestamp.now(); prov.state = { tag: BackupProviderStateTag.Ready, nextBackupTimestamp: getNextBackupTimestamp(), @@ -442,7 +443,7 @@ async function runBackupCycleForProvider( return; } prov.lastBackupHash = encodeCrock(currentBackupHash); - prov.lastBackupCycleTimestamp = TalerProtocolTimestamp.now(); + prov.lastBackupCycleTimestamp = TalerPreciseTimestamp.now(); prov.state = { tag: BackupProviderStateTag.Ready, nextBackupTimestamp: getNextBackupTimestamp(), @@ -676,7 +677,7 @@ export async function addBackupProvider( if (req.activate) { oldProv.state = { tag: BackupProviderStateTag.Ready, - nextBackupTimestamp: TalerProtocolTimestamp.now(), + nextBackupTimestamp: TalerPreciseTimestamp.now(), }; logger.info("setting existing backup provider to active"); await tx.backupProviders.put(oldProv); @@ -698,7 +699,7 @@ export async function addBackupProvider( if (req.activate) { state = { tag: BackupProviderStateTag.Ready, - nextBackupTimestamp: TalerProtocolTimestamp.now(), + nextBackupTimestamp: TalerPreciseTimestamp.now(), }; } else { state = { @@ -773,8 +774,8 @@ export interface ProviderInfo { * Last communication issue with the provider. */ lastError?: TalerErrorDetail; - lastSuccessfulBackupTimestamp?: TalerProtocolTimestamp; - lastAttemptedBackupTimestamp?: TalerProtocolTimestamp; + lastSuccessfulBackupTimestamp?: TalerPreciseTimestamp; + lastAttemptedBackupTimestamp?: TalerPreciseTimestamp; paymentProposalIds: string[]; backupProblem?: BackupProblem; paymentStatus: ProviderPaymentStatus; @@ -894,7 +895,7 @@ async function getProviderPaymentInfo( return { type: ProviderPaymentType.Paid, paidUntil: AbsoluteTime.addDuration( - AbsoluteTime.fromTimestamp(status.contractTerms.timestamp), + AbsoluteTime.fromProtocolTimestamp(status.contractTerms.timestamp), durationFromSpec({ years: 1 }), //FIXME: take this from the contract term ), }; @@ -1010,7 +1011,7 @@ async function backupRecoveryTheirs( shouldRetryFreshProposal: false, state: { tag: BackupProviderStateTag.Ready, - nextBackupTimestamp: TalerProtocolTimestamp.now(), + nextBackupTimestamp: TalerPreciseTimestamp.now(), }, uids: [encodeCrock(getRandomBytes(32))], }); diff --git a/packages/taler-wallet-core/src/operations/deposits.ts b/packages/taler-wallet-core/src/operations/deposits.ts index a36091165..de881ddd2 100644 --- a/packages/taler-wallet-core/src/operations/deposits.ts +++ b/packages/taler-wallet-core/src/operations/deposits.ts @@ -51,6 +51,7 @@ import { stringToBytes, TalerErrorCode, TalerProtocolTimestamp, + TalerPreciseTimestamp, TrackTransaction, TransactionMajorState, TransactionMinorState, @@ -779,7 +780,7 @@ export async function processDepositGroup( } } if (allDepositedAndWired) { - dg.timestampFinished = TalerProtocolTimestamp.now(); + dg.timestampFinished = TalerPreciseTimestamp.now(); dg.operationStatus = DepositOperationStatus.Finished; await tx.depositGroups.put(dg); } @@ -858,9 +859,9 @@ async function getExchangeWireFee( } const fee = fees.find((x) => { return AbsoluteTime.isBetween( - AbsoluteTime.fromTimestamp(time), - AbsoluteTime.fromTimestamp(x.startStamp), - AbsoluteTime.fromTimestamp(x.endStamp), + AbsoluteTime.fromProtocolTimestamp(time), + AbsoluteTime.fromProtocolTimestamp(x.startStamp), + AbsoluteTime.fromProtocolTimestamp(x.endStamp), ); }); if (!fee) { @@ -952,7 +953,7 @@ export async function prepareDepositGroup( }); const now = AbsoluteTime.now(); - const nowRounded = AbsoluteTime.toTimestamp(now); + const nowRounded = AbsoluteTime.toProtocolTimestamp(now); const contractTerms: MerchantContractTerms = { exchanges: exchangeInfos, amount: req.amount, @@ -966,7 +967,7 @@ export async function prepareDepositGroup( wire_transfer_deadline: nowRounded, order_id: "", h_wire: "", - pay_deadline: AbsoluteTime.toTimestamp( + pay_deadline: AbsoluteTime.toProtocolTimestamp( AbsoluteTime.addDuration(now, durationFromSpec({ hours: 1 })), ), merchant: { @@ -1066,7 +1067,7 @@ export async function createDepositGroup( }); const now = AbsoluteTime.now(); - const nowRounded = AbsoluteTime.toTimestamp(now); + const nowRounded = AbsoluteTime.toProtocolTimestamp(now); const noncePair = await ws.cryptoApi.createEddsaKeypair({}); const merchantPair = await ws.cryptoApi.createEddsaKeypair({}); const wireSalt = encodeCrock(getRandomBytes(16)); @@ -1084,7 +1085,7 @@ export async function createDepositGroup( wire_transfer_deadline: nowRounded, order_id: "", h_wire: wireHash, - pay_deadline: AbsoluteTime.toTimestamp( + pay_deadline: AbsoluteTime.toProtocolTimestamp( AbsoluteTime.addDuration(now, durationFromSpec({ hours: 1 })), ), merchant: { @@ -1150,7 +1151,7 @@ export async function createDepositGroup( depositGroupId, noncePriv: noncePair.priv, noncePub: noncePair.pub, - timestampCreated: AbsoluteTime.toTimestamp(now), + timestampCreated: AbsoluteTime.toPreciseTimestamp(now), timestampFinished: undefined, transactionPerCoin: payCoinSel.coinSel.coinPubs.map( () => DepositElementStatus.Unknown, @@ -1260,8 +1261,8 @@ export async function getCounterpartyEffectiveDepositAmount( const fee = exchangeDetails.wireInfo.feesForType[wireType].find((x) => { return AbsoluteTime.isBetween( AbsoluteTime.now(), - AbsoluteTime.fromTimestamp(x.startStamp), - AbsoluteTime.fromTimestamp(x.endStamp), + AbsoluteTime.fromProtocolTimestamp(x.startStamp), + AbsoluteTime.fromProtocolTimestamp(x.endStamp), ); })?.wireFee; if (fee) { @@ -1337,8 +1338,8 @@ export async function getTotalFeesForDepositAmount( (x) => { return AbsoluteTime.isBetween( AbsoluteTime.now(), - AbsoluteTime.fromTimestamp(x.startStamp), - AbsoluteTime.fromTimestamp(x.endStamp), + AbsoluteTime.fromProtocolTimestamp(x.startStamp), + AbsoluteTime.fromProtocolTimestamp(x.endStamp), ); }, )?.wireFee; diff --git a/packages/taler-wallet-core/src/operations/exchanges.ts b/packages/taler-wallet-core/src/operations/exchanges.ts index d8fb95755..142e0cf03 100644 --- a/packages/taler-wallet-core/src/operations/exchanges.ts +++ b/packages/taler-wallet-core/src/operations/exchanges.ts @@ -43,6 +43,7 @@ import { Recoup, TalerError, TalerErrorCode, + TalerPreciseTimestamp, TalerProtocolDuration, TalerProtocolTimestamp, URL, @@ -229,7 +230,7 @@ export async function acceptExchangeTermsOfService( if (d) { d.tosAccepted = { etag: etag || d.tosCurrentEtag, - timestamp: TalerProtocolTimestamp.now(), + timestamp: TalerPreciseTimestamp.now(), }; await tx.exchangeDetails.put(d); } @@ -407,8 +408,8 @@ export async function provideExchangeRecordInTx( baseUrl: baseUrl, detailsPointer: undefined, lastUpdate: undefined, - nextUpdate: AbsoluteTime.toTimestamp(now), - nextRefreshCheck: AbsoluteTime.toTimestamp(now), + nextUpdate: AbsoluteTime.toPreciseTimestamp(now), + nextRefreshCheck: AbsoluteTime.toPreciseTimestamp(now), lastKeysEtag: undefined, lastWireEtag: undefined, }; @@ -497,7 +498,7 @@ async function downloadExchangeKeysInfo( protocolVersion: exchangeKeysJsonUnchecked.version, signingKeys: exchangeKeysJsonUnchecked.signkeys, reserveClosingDelay: exchangeKeysJsonUnchecked.reserve_closing_delay, - expiry: AbsoluteTime.toTimestamp( + expiry: AbsoluteTime.toProtocolTimestamp( getExpiry(resp, { minDuration: durationFromSpec({ hours: 1 }), }), @@ -601,7 +602,9 @@ export async function updateExchangeFromUrlHandler( if ( !forceNow && exchangeDetails !== undefined && - !AbsoluteTime.isExpired(AbsoluteTime.fromTimestamp(exchange.nextUpdate)) + !AbsoluteTime.isExpired( + AbsoluteTime.fromPreciseTimestamp(exchange.nextUpdate), + ) ) { logger.info("using existing exchange info"); return { @@ -724,15 +727,17 @@ export async function updateExchangeFromUrlHandler( if (existingDetails?.rowId) { newDetails.rowId = existingDetails.rowId; } - r.lastUpdate = TalerProtocolTimestamp.now(); - r.nextUpdate = keysInfo.expiry; + r.lastUpdate = TalerPreciseTimestamp.now(); + r.nextUpdate = AbsoluteTime.toPreciseTimestamp( + AbsoluteTime.fromProtocolTimestamp(keysInfo.expiry), + ); // New denominations might be available. - r.nextRefreshCheck = TalerProtocolTimestamp.now(); + r.nextRefreshCheck = TalerPreciseTimestamp.now(); if (detailsPointerChanged) { r.detailsPointer = { currency: newDetails.currency, masterPublicKey: newDetails.masterPublicKey, - updateClock: TalerProtocolTimestamp.now(), + updateClock: TalerPreciseTimestamp.now(), }; } await tx.exchanges.put(r); diff --git a/packages/taler-wallet-core/src/operations/pay-merchant.ts b/packages/taler-wallet-core/src/operations/pay-merchant.ts index 854202b6a..4ea41c695 100644 --- a/packages/taler-wallet-core/src/operations/pay-merchant.ts +++ b/packages/taler-wallet-core/src/operations/pay-merchant.ts @@ -66,6 +66,7 @@ import { TalerError, TalerErrorCode, TalerErrorDetail, + TalerPreciseTimestamp, TalerProtocolTimestamp, TalerProtocolViolationError, TalerUriAction, @@ -621,7 +622,7 @@ async function createPurchase( noncePriv: priv, noncePub: pub, claimToken, - timestamp: AbsoluteTime.toTimestamp(AbsoluteTime.now()), + timestamp: TalerPreciseTimestamp.now(), merchantBaseUrl, orderId, proposalId: proposalId, @@ -682,7 +683,7 @@ async function storeFirstPaySuccess( tag: TransactionType.Payment, proposalId, }); - const now = AbsoluteTime.toTimestamp(AbsoluteTime.now()); + const now = AbsoluteTime.toPreciseTimestamp(AbsoluteTime.now()); const transitionInfo = await ws.db .mktx((x) => [x.purchases, x.contractTerms]) .runReadWrite(async (tx) => { @@ -721,7 +722,7 @@ async function storeFirstPaySuccess( const ar = Duration.fromTalerProtocolDuration(protoAr); logger.info("auto_refund present"); purchase.purchaseStatus = PurchaseStatus.QueryingAutoRefund; - purchase.autoRefundDeadline = AbsoluteTime.toTimestamp( + purchase.autoRefundDeadline = AbsoluteTime.toProtocolTimestamp( AbsoluteTime.addDuration(AbsoluteTime.now(), ar), ); } @@ -923,7 +924,7 @@ async function unblockBackup( .forEachAsync(async (bp) => { bp.state = { tag: BackupProviderStateTag.Ready, - nextBackupTimestamp: TalerProtocolTimestamp.now(), + nextBackupTimestamp: TalerPreciseTimestamp.now(), }; tx.backupProviders.put(bp); }); @@ -1422,7 +1423,7 @@ export async function confirmPay( totalPayCost: Amounts.stringify(payCostInfo), }; p.lastSessionId = sessionId; - p.timestampAccept = TalerProtocolTimestamp.now(); + p.timestampAccept = TalerPreciseTimestamp.now(); p.purchaseStatus = PurchaseStatus.Paying; await tx.purchases.put(p); await spendCoins(ws, tx, { @@ -1925,7 +1926,7 @@ async function processPurchaseAutoRefund( if ( !purchase.autoRefundDeadline || AbsoluteTime.isExpired( - AbsoluteTime.fromTimestamp(purchase.autoRefundDeadline), + AbsoluteTime.fromProtocolTimestamp(purchase.autoRefundDeadline), ) ) { const transitionInfo = await ws.db @@ -2068,9 +2069,9 @@ async function processPurchaseAbortingRefund( coin_pub: payCoinSelection.coinPubs[i], refund_amount: Amounts.stringify(payCoinSelection.coinContributions[i]), rtransaction_id: 0, - execution_time: AbsoluteTime.toTimestamp( + execution_time: AbsoluteTime.toProtocolTimestamp( AbsoluteTime.addDuration( - AbsoluteTime.fromTimestamp(download.contractData.timestamp), + AbsoluteTime.fromProtocolTimestamp(download.contractData.timestamp), Duration.fromSpec({ seconds: 1 }), ), ), @@ -2267,7 +2268,7 @@ async function storeRefunds( }); const newRefundGroupId = encodeCrock(randomBytes(32)); - const now = TalerProtocolTimestamp.now(); + const now = TalerPreciseTimestamp.now(); const download = await expectProposalDownload(ws, purchase); const currency = Amounts.currencyOf(download.contractData.amount); diff --git a/packages/taler-wallet-core/src/operations/pay-peer.ts b/packages/taler-wallet-core/src/operations/pay-peer.ts index 108be7339..f464948f8 100644 --- a/packages/taler-wallet-core/src/operations/pay-peer.ts +++ b/packages/taler-wallet-core/src/operations/pay-peer.ts @@ -78,6 +78,7 @@ import { TransactionState, TransactionMajorState, TransactionMinorState, + TalerPreciseTimestamp, } from "@gnu-taler/taler-util"; import { SpendCoinDetails } from "../crypto/cryptoImplementation.js"; import { @@ -728,7 +729,7 @@ export async function initiatePeerPushDebit( purseExpiration: purseExpiration, pursePriv: pursePair.priv, pursePub: pursePair.pub, - timestampCreated: TalerProtocolTimestamp.now(), + timestampCreated: TalerPreciseTimestamp.now(), status: PeerPushPaymentInitiationStatus.PendingCreatePurse, contractTerms: contractTerms, coinSel: { @@ -889,7 +890,7 @@ export async function preparePeerPushCredit( exchangeBaseUrl: exchangeBaseUrl, mergePriv: dec.mergePriv, pursePub: pursePub, - timestamp: TalerProtocolTimestamp.now(), + timestamp: TalerPreciseTimestamp.now(), contractTermsHash, status: PeerPushPaymentIncomingStatus.Proposed, withdrawalGroupId, @@ -1450,7 +1451,7 @@ export async function preparePeerPullDebit( contractPriv: contractPriv, exchangeBaseUrl: exchangeBaseUrl, pursePub: pursePub, - timestampCreated: TalerProtocolTimestamp.now(), + timestampCreated: TalerPreciseTimestamp.now(), contractTerms, status: PeerPullPaymentIncomingStatus.Proposed, totalCostEstimated: Amounts.stringify(totalAmount), @@ -1668,7 +1669,7 @@ export async function processPeerPullCredit( contractTermsHash: pullIni.contractTermsHash, flags: WalletAccountMergeFlags.CreateWithPurseFee, mergePriv: pullIni.mergePriv, - mergeTimestamp: pullIni.mergeTimestamp, + mergeTimestamp: TalerPreciseTimestamp.round(pullIni.mergeTimestamp), purseAmount: pullIni.contractTerms.amount, purseExpiration: purseExpiration, purseFee: purseFee, @@ -1680,7 +1681,7 @@ export async function processPeerPullCredit( const reservePurseReqBody: ExchangeReservePurseRequest = { merge_sig: sigRes.mergeSig, - merge_timestamp: pullIni.mergeTimestamp, + merge_timestamp: TalerPreciseTimestamp.round(pullIni.mergeTimestamp), h_contract_terms: pullIni.contractTermsHash, merge_pub: pullIni.mergePub, min_age: 0, @@ -1788,8 +1789,8 @@ async function getPreferredExchangeForCurrency( if (candidate.lastWithdrawal && e.lastWithdrawal) { if ( AbsoluteTime.cmp( - AbsoluteTime.fromTimestamp(e.lastWithdrawal), - AbsoluteTime.fromTimestamp(candidate.lastWithdrawal), + AbsoluteTime.fromPreciseTimestamp(e.lastWithdrawal), + AbsoluteTime.fromPreciseTimestamp(candidate.lastWithdrawal), ) > 0 ) { candidate = e; @@ -1874,7 +1875,7 @@ export async function initiatePeerPullPayment( exchangeBaseUrl: exchangeBaseUrl, }); - const mergeTimestamp = TalerProtocolTimestamp.now(); + const mergeTimestamp = TalerPreciseTimestamp.now(); const pursePair = await ws.cryptoApi.createEddsaKeypair({}); const mergePair = await ws.cryptoApi.createEddsaKeypair({}); diff --git a/packages/taler-wallet-core/src/operations/pending.ts b/packages/taler-wallet-core/src/operations/pending.ts index 54b12383b..7e098b19c 100644 --- a/packages/taler-wallet-core/src/operations/pending.ts +++ b/packages/taler-wallet-core/src/operations/pending.ts @@ -79,7 +79,7 @@ async function gatherExchangePending( const opTag = TaskIdentifiers.forExchangeUpdate(exch); let opr = await tx.operationRetries.get(opTag); const timestampDue = - opr?.retryInfo.nextRetry ?? AbsoluteTime.fromTimestamp(exch.nextUpdate); + opr?.retryInfo.nextRetry ?? AbsoluteTime.fromPreciseTimestamp(exch.nextUpdate); resp.pendingOperations.push({ type: PendingTaskType.ExchangeUpdate, ...getPendingCommon(ws, opTag, timestampDue), @@ -94,7 +94,7 @@ async function gatherExchangePending( resp.pendingOperations.push({ type: PendingTaskType.ExchangeCheckRefresh, ...getPendingCommon(ws, opTag, timestampDue), - timestampDue: AbsoluteTime.fromTimestamp(exch.nextRefreshCheck), + timestampDue: AbsoluteTime.fromPreciseTimestamp(exch.nextRefreshCheck), givesLifeness: false, exchangeBaseUrl: exch.baseUrl, }); @@ -333,7 +333,7 @@ async function gatherBackupPending( const opId = TaskIdentifiers.forBackup(bp); const retryRecord = await tx.operationRetries.get(opId); if (bp.state.tag === BackupProviderStateTag.Ready) { - const timestampDue = AbsoluteTime.fromTimestamp( + const timestampDue = AbsoluteTime.fromPreciseTimestamp( bp.state.nextBackupTimestamp, ); resp.pendingOperations.push({ diff --git a/packages/taler-wallet-core/src/operations/recoup.ts b/packages/taler-wallet-core/src/operations/recoup.ts index 982f3cf8c..1f36117ee 100644 --- a/packages/taler-wallet-core/src/operations/recoup.ts +++ b/packages/taler-wallet-core/src/operations/recoup.ts @@ -36,6 +36,7 @@ import { NotificationType, RefreshReason, TalerProtocolTimestamp, + TalerPreciseTimestamp, URL, } from "@gnu-taler/taler-util"; import { @@ -424,7 +425,7 @@ export async function processRecoupGroupHandler( if (!rg2) { return; } - rg2.timestampFinished = TalerProtocolTimestamp.now(); + rg2.timestampFinished = TalerPreciseTimestamp.now(); if (rg2.scheduleRefreshCoins.length > 0) { const refreshGroupId = await createRefreshGroup( ws, @@ -460,7 +461,7 @@ export async function createRecoupGroup( exchangeBaseUrl: exchangeBaseUrl, coinPubs: coinPubs, timestampFinished: undefined, - timestampStarted: TalerProtocolTimestamp.now(), + timestampStarted: TalerPreciseTimestamp.now(), recoupFinishedPerCoin: coinPubs.map(() => false), scheduleRefreshCoins: [], }; diff --git a/packages/taler-wallet-core/src/operations/refresh.ts b/packages/taler-wallet-core/src/operations/refresh.ts index 14556f3c0..c46344313 100644 --- a/packages/taler-wallet-core/src/operations/refresh.ts +++ b/packages/taler-wallet-core/src/operations/refresh.ts @@ -48,6 +48,7 @@ import { RefreshReason, TalerErrorCode, TalerErrorDetail, + TalerPreciseTimestamp, TalerProtocolTimestamp, TransactionMajorState, TransactionState, @@ -156,10 +157,10 @@ function updateGroupStatus(rg: RefreshGroupRecord): void { ); if (allDone) { if (anyFrozen) { - rg.timestampFinished = AbsoluteTime.toTimestamp(AbsoluteTime.now()); + rg.timestampFinished = TalerPreciseTimestamp.now(); rg.operationStatus = RefreshOperationStatus.FinishedWithError; } else { - rg.timestampFinished = AbsoluteTime.toTimestamp(AbsoluteTime.now()); + rg.timestampFinished = TalerPreciseTimestamp.now(); rg.operationStatus = RefreshOperationStatus.Finished; } } @@ -1046,12 +1047,12 @@ export async function createRefreshGroup( estimatedOutputPerCoin: estimatedOutputPerCoin.map((x) => Amounts.stringify(x), ), - timestampCreated: TalerProtocolTimestamp.now(), + timestampCreated: TalerPreciseTimestamp.now(), }; if (oldCoinPubs.length == 0) { logger.warn("created refresh group with zero coins"); - refreshGroup.timestampFinished = TalerProtocolTimestamp.now(); + refreshGroup.timestampFinished = TalerPreciseTimestamp.now(); refreshGroup.operationStatus = RefreshOperationStatus.Finished; } @@ -1075,8 +1076,8 @@ export async function createRefreshGroup( * Timestamp after which the wallet would do the next check for an auto-refresh. */ function getAutoRefreshCheckThreshold(d: DenominationRecord): AbsoluteTime { - const expireWithdraw = AbsoluteTime.fromTimestamp(d.stampExpireWithdraw); - const expireDeposit = AbsoluteTime.fromTimestamp(d.stampExpireDeposit); + const expireWithdraw = AbsoluteTime.fromProtocolTimestamp(d.stampExpireWithdraw); + const expireDeposit = AbsoluteTime.fromProtocolTimestamp(d.stampExpireDeposit); const delta = AbsoluteTime.difference(expireWithdraw, expireDeposit); const deltaDiv = durationMul(delta, 0.75); return AbsoluteTime.addDuration(expireWithdraw, deltaDiv); @@ -1086,8 +1087,8 @@ function getAutoRefreshCheckThreshold(d: DenominationRecord): AbsoluteTime { * Timestamp after which the wallet would do an auto-refresh. */ function getAutoRefreshExecuteThreshold(d: DenominationRecord): AbsoluteTime { - const expireWithdraw = AbsoluteTime.fromTimestamp(d.stampExpireWithdraw); - const expireDeposit = AbsoluteTime.fromTimestamp(d.stampExpireDeposit); + const expireWithdraw = AbsoluteTime.fromProtocolTimestamp(d.stampExpireWithdraw); + const expireDeposit = AbsoluteTime.fromProtocolTimestamp(d.stampExpireDeposit); const delta = AbsoluteTime.difference(expireWithdraw, expireDeposit); const deltaDiv = durationMul(delta, 0.5); return AbsoluteTime.addDuration(expireWithdraw, deltaDiv); @@ -1174,7 +1175,7 @@ export async function autoRefresh( logger.info( `next refresh check at ${AbsoluteTime.toIsoString(minCheckThreshold)}`, ); - exchange.nextRefreshCheck = AbsoluteTime.toTimestamp(minCheckThreshold); + exchange.nextRefreshCheck = AbsoluteTime.toPreciseTimestamp(minCheckThreshold); await tx.exchanges.put(exchange); }); return OperationAttemptResult.finishedEmpty(); diff --git a/packages/taler-wallet-core/src/operations/testing.ts b/packages/taler-wallet-core/src/operations/testing.ts index e5794ad93..ef5aa907d 100644 --- a/packages/taler-wallet-core/src/operations/testing.ts +++ b/packages/taler-wallet-core/src/operations/testing.ts @@ -536,7 +536,7 @@ export async function runIntegrationTest2( partialContractTerms: { amount: `${currency}:1`, summary: "Payment Peer Push Test", - purse_expiration: AbsoluteTime.toTimestamp( + purse_expiration: AbsoluteTime.toProtocolTimestamp( AbsoluteTime.addDuration( AbsoluteTime.now(), Duration.fromSpec({ hours: 1 }), @@ -557,7 +557,7 @@ export async function runIntegrationTest2( partialContractTerms: { amount: `${currency}:1`, summary: "Payment Peer Pull Test", - purse_expiration: AbsoluteTime.toTimestamp( + purse_expiration: AbsoluteTime.toProtocolTimestamp( AbsoluteTime.addDuration( AbsoluteTime.now(), Duration.fromSpec({ hours: 1 }), diff --git a/packages/taler-wallet-core/src/operations/tip.ts b/packages/taler-wallet-core/src/operations/tip.ts index 417f06dc2..524970faa 100644 --- a/packages/taler-wallet-core/src/operations/tip.ts +++ b/packages/taler-wallet-core/src/operations/tip.ts @@ -33,6 +33,7 @@ import { parseTipUri, PrepareTipResult, TalerErrorCode, + TalerPreciseTimestamp, TalerProtocolTimestamp, TipPlanchetDetail, TransactionMajorState, @@ -160,7 +161,7 @@ export async function prepareTip( exchangeBaseUrl: tipPickupStatus.exchange_url, next_url: tipPickupStatus.next_url, merchantBaseUrl: res.merchantBaseUrl, - createdTimestamp: TalerProtocolTimestamp.now(), + createdTimestamp: TalerPreciseTimestamp.now(), merchantTipId: res.merchantTipId, tipAmountEffective: Amounts.stringify(selectedDenoms.totalCoinValue), denomsSel: selectedDenoms, @@ -365,7 +366,7 @@ export async function processTip( if (tr.pickedUpTimestamp) { return; } - tr.pickedUpTimestamp = TalerProtocolTimestamp.now(); + tr.pickedUpTimestamp = TalerPreciseTimestamp.now(); await tx.tips.put(tr); for (const cr of newCoinRecords) { await makeCoinAvailable(ws, tx, cr); @@ -390,7 +391,7 @@ export async function acceptTip( logger.error("tip not found"); return undefined; } - tipRecord.acceptedTimestamp = TalerProtocolTimestamp.now(); + tipRecord.acceptedTimestamp = TalerPreciseTimestamp.now(); await tx.tips.put(tipRecord); return tipRecord; diff --git a/packages/taler-wallet-core/src/operations/transactions.ts b/packages/taler-wallet-core/src/operations/transactions.ts index 894becca7..481ffe8bb 100644 --- a/packages/taler-wallet-core/src/operations/transactions.ts +++ b/packages/taler-wallet-core/src/operations/transactions.ts @@ -30,6 +30,7 @@ import { stringifyPayPullUri, stringifyPayPushUri, TalerErrorCode, + TalerPreciseTimestamp, TalerProtocolTimestamp, Transaction, TransactionByIdRequest, @@ -472,7 +473,7 @@ function buildTransactionForPeerPullCredit( amountRaw: Amounts.stringify(wsr.instructedAmount), exchangeBaseUrl: wsr.exchangeBaseUrl, // Old transactions don't have it! - timestamp: pullCredit.mergeTimestamp ?? TalerProtocolTimestamp.now(), + timestamp: pullCredit.mergeTimestamp ?? TalerPreciseTimestamp.now(), info: { expiration: wsr.wgInfo.contractTerms.purse_expiration, summary: wsr.wgInfo.contractTerms.summary, @@ -1171,8 +1172,8 @@ export async function getTransactions( const txCmp = (h1: Transaction, h2: Transaction) => { const tsCmp = AbsoluteTime.cmp( - AbsoluteTime.fromTimestamp(h1.timestamp), - AbsoluteTime.fromTimestamp(h2.timestamp), + AbsoluteTime.fromPreciseTimestamp(h1.timestamp), + AbsoluteTime.fromPreciseTimestamp(h2.timestamp), ); if (tsCmp === 0) { return Math.sign(txOrder[h1.type] - txOrder[h2.type]); diff --git a/packages/taler-wallet-core/src/operations/withdraw.ts b/packages/taler-wallet-core/src/operations/withdraw.ts index c0566bf4d..586aa50f5 100644 --- a/packages/taler-wallet-core/src/operations/withdraw.ts +++ b/packages/taler-wallet-core/src/operations/withdraw.ts @@ -66,6 +66,7 @@ import { TransactionState, TransactionMajorState, TransactionMinorState, + TalerPreciseTimestamp, } from "@gnu-taler/taler-util"; import { EddsaKeypair } from "../crypto/cryptoImplementation.js"; import { @@ -1327,7 +1328,7 @@ export async function processWithdrawalGroup( } const txStatusOld = computeWithdrawalTransactionStatus(wg); wg.status = WithdrawalGroupStatus.Finished; - wg.timestampFinish = TalerProtocolTimestamp.now(); + wg.timestampFinish = TalerPreciseTimestamp.now(); const txStatusNew = computeWithdrawalTransactionStatus(wg); await tx.withdrawalGroups.put(wg); return { @@ -1428,7 +1429,7 @@ export async function processWithdrawalGroup( logger.info(`now withdrawn ${numFinished} of ${numTotalCoins} coins`); if (wg.timestampFinish === undefined && numFinished === numTotalCoins) { finishedForFirstTime = true; - wg.timestampFinish = TalerProtocolTimestamp.now(); + wg.timestampFinish = TalerPreciseTimestamp.now(); wg.status = WithdrawalGroupStatus.Finished; } @@ -1613,8 +1614,8 @@ export async function getExchangeWithdrawalInfo( } if ( AbsoluteTime.cmp( - AbsoluteTime.fromTimestamp(expireDeposit), - AbsoluteTime.fromTimestamp(earliestDepositExpiration), + AbsoluteTime.fromProtocolTimestamp(expireDeposit), + AbsoluteTime.fromProtocolTimestamp(earliestDepositExpiration), ) < 0 ) { earliestDepositExpiration = expireDeposit; @@ -1910,7 +1911,7 @@ async function registerReserveWithBank( if (r.wgInfo.withdrawalType !== WithdrawalRecordType.BankIntegrated) { throw Error("invariant failed"); } - r.wgInfo.bankInfo.timestampReserveInfoPosted = AbsoluteTime.toTimestamp( + r.wgInfo.bankInfo.timestampReserveInfoPosted = AbsoluteTime.toPreciseTimestamp( AbsoluteTime.now(), ); const oldTxState = computeWithdrawalTransactionStatus(r); @@ -1994,7 +1995,7 @@ async function processReserveBankStatus( if (r.wgInfo.withdrawalType !== WithdrawalRecordType.BankIntegrated) { throw Error("invariant failed"); } - const now = AbsoluteTime.toTimestamp(AbsoluteTime.now()); + const now = AbsoluteTime.toPreciseTimestamp(AbsoluteTime.now()); const oldTxState = computeWithdrawalTransactionStatus(r); r.wgInfo.bankInfo.timestampBankConfirmed = now; r.status = WithdrawalGroupStatus.FailedBankAborted; @@ -2044,7 +2045,7 @@ async function processReserveBankStatus( const oldTxState = computeWithdrawalTransactionStatus(r); if (status.transfer_done) { logger.info("withdrawal: transfer confirmed by bank."); - const now = AbsoluteTime.toTimestamp(AbsoluteTime.now()); + const now = AbsoluteTime.toPreciseTimestamp(AbsoluteTime.now()); r.wgInfo.bankInfo.timestampBankConfirmed = now; r.status = WithdrawalGroupStatus.PendingQueryingStatus; // FIXME: Notification is deprecated with DD37. @@ -2105,7 +2106,7 @@ export async function internalCreateWithdrawalGroup( ): Promise { const reserveKeyPair = args.reserveKeyPair ?? (await ws.cryptoApi.createEddsaKeypair({})); - const now = AbsoluteTime.toTimestamp(AbsoluteTime.now()); + const now = AbsoluteTime.toPreciseTimestamp(AbsoluteTime.now()); const secretSeed = encodeCrock(getRandomBytes(32)); const canonExchange = canonicalizeBaseUrl(args.exchangeBaseUrl); const amount = args.amount; @@ -2200,7 +2201,7 @@ export async function internalCreateWithdrawalGroup( const exchange = await tx.exchanges.get(withdrawalGroup.exchangeBaseUrl); if (exchange) { - exchange.lastWithdrawal = TalerProtocolTimestamp.now(); + exchange.lastWithdrawal = TalerPreciseTimestamp.now(); await tx.exchanges.put(exchange); } -- cgit v1.2.3