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 --- .../src/crypto/workers/crypto-dispatcher.test.ts | 4 +- packages/taler-wallet-core/src/db.ts | 71 +++++++++++----------- packages/taler-wallet-core/src/dbless.ts | 2 +- .../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 +++--- .../taler-wallet-core/src/util/coinSelection.ts | 4 +- .../src/util/denominations.test.ts | 2 +- .../taler-wallet-core/src/util/denominations.ts | 8 +-- 21 files changed, 148 insertions(+), 130 deletions(-) (limited to 'packages/taler-wallet-core/src') diff --git a/packages/taler-wallet-core/src/crypto/workers/crypto-dispatcher.test.ts b/packages/taler-wallet-core/src/crypto/workers/crypto-dispatcher.test.ts index 1e9d82f66..96e2ee735 100644 --- a/packages/taler-wallet-core/src/crypto/workers/crypto-dispatcher.test.ts +++ b/packages/taler-wallet-core/src/crypto/workers/crypto-dispatcher.test.ts @@ -14,7 +14,7 @@ GNU Taler; see the file COPYING. If not, see */ -import { AbsoluteTime } from "@gnu-taler/taler-util"; +import { AbsoluteTime, TalerErrorCode } from "@gnu-taler/taler-util"; import test from "ava"; import { CryptoDispatcher, CryptoWorkerFactory } from "./crypto-dispatcher.js"; import { @@ -72,7 +72,7 @@ export class MyCryptoWorker implements CryptoWorker { id: msg.id, type: "error", error: { - code: 42, + code: TalerErrorCode.ANASTASIS_EMAIL_INVALID, when: AbsoluteTime.now(), hint: "bla", }, diff --git a/packages/taler-wallet-core/src/db.ts b/packages/taler-wallet-core/src/db.ts index 8d66ee27b..12e799c71 100644 --- a/packages/taler-wallet-core/src/db.ts +++ b/packages/taler-wallet-core/src/db.ts @@ -57,6 +57,7 @@ import { AttentionInfo, Logger, CoinPublicKeyString, + TalerPreciseTimestamp, } from "@gnu-taler/taler-util"; import { DbAccess, @@ -236,14 +237,14 @@ export interface ReserveBankInfo { * * Set to undefined if that hasn't happened yet. */ - timestampReserveInfoPosted: TalerProtocolTimestamp | undefined; + timestampReserveInfoPosted: TalerPreciseTimestamp | undefined; /** * Time when the reserve was confirmed by the bank. * * Set to undefined if not confirmed yet. */ - timestampBankConfirmed: TalerProtocolTimestamp | undefined; + timestampBankConfirmed: TalerPreciseTimestamp | undefined; } /** @@ -516,7 +517,7 @@ export interface ExchangeDetailsRecord { tosAccepted: | { etag: string; - timestamp: TalerProtocolTimestamp; + timestamp: TalerPreciseTimestamp; } | undefined; @@ -556,7 +557,7 @@ export interface ExchangeDetailsPointer { * Timestamp when the (masterPublicKey, currency) pointer * has been updated. */ - updateClock: TalerProtocolTimestamp; + updateClock: TalerPreciseTimestamp; } /** @@ -573,7 +574,7 @@ export interface ExchangeRecord { * * Used mostly in the UI to suggest exchanges. */ - lastWithdrawal?: TalerProtocolTimestamp; + lastWithdrawal?: TalerPreciseTimestamp; /** * Pointer to the current exchange details. @@ -595,14 +596,14 @@ export interface ExchangeRecord { /** * Last time when the exchange was updated (both /keys and /wire). */ - lastUpdate: TalerProtocolTimestamp | undefined; + lastUpdate: TalerPreciseTimestamp | undefined; /** * Next scheduled update for the exchange. * * (This field must always be present, so we can index on the timestamp.) */ - nextUpdate: TalerProtocolTimestamp; + nextUpdate: TalerPreciseTimestamp; lastKeysEtag: string | undefined; @@ -614,7 +615,7 @@ export interface ExchangeRecord { * Updated whenever the exchange's denominations are updated or when * the refresh check has been done. */ - nextRefreshCheck: TalerProtocolTimestamp; + nextRefreshCheck: TalerPreciseTimestamp; /** * Public key of the reserve that we're currently using for @@ -803,7 +804,7 @@ export interface TipRecord { * Has the user accepted the tip? Only after the tip has been accepted coins * withdrawn from the tip may be used. */ - acceptedTimestamp: TalerProtocolTimestamp | undefined; + acceptedTimestamp: TalerPreciseTimestamp | undefined; /** * The tipped amount. @@ -856,7 +857,7 @@ export interface TipRecord { */ merchantTipId: string; - createdTimestamp: TalerProtocolTimestamp; + createdTimestamp: TalerPreciseTimestamp; /** * The url to be redirected after the tip is accepted. @@ -866,7 +867,7 @@ export interface TipRecord { * Timestamp for when the wallet finished picking up the tip * from the merchant. */ - pickedUpTimestamp: TalerProtocolTimestamp | undefined; + pickedUpTimestamp: TalerPreciseTimestamp | undefined; } export enum RefreshCoinStatus { @@ -974,12 +975,12 @@ export interface RefreshGroupRecord { */ statusPerCoin: RefreshCoinStatus[]; - timestampCreated: TalerProtocolTimestamp; + timestampCreated: TalerPreciseTimestamp; /** * Timestamp when the refresh session finished. */ - timestampFinished: TalerProtocolTimestamp | undefined; + timestampFinished: TalerPreciseTimestamp | undefined; } /** @@ -1233,7 +1234,7 @@ export interface PurchaseRecord { * Timestamp of the first time that sending a payment to the merchant * for this purchase was successful. */ - timestampFirstSuccessfulPay: TalerProtocolTimestamp | undefined; + timestampFirstSuccessfulPay: TalerPreciseTimestamp | undefined; merchantPaySig: string | undefined; @@ -1242,13 +1243,13 @@ export interface PurchaseRecord { /** * When was the purchase record created? */ - timestamp: TalerProtocolTimestamp; + timestamp: TalerPreciseTimestamp; /** * When was the purchase made? * Refers to the time that the user accepted. */ - timestampAccept: TalerProtocolTimestamp | undefined; + timestampAccept: TalerPreciseTimestamp | undefined; /** * Pending refunds for the purchase. A refund is pending @@ -1262,7 +1263,7 @@ export interface PurchaseRecord { * When was the last refund made? * Set to 0 if no refund was made on the purchase. */ - timestampLastRefundStatus: TalerProtocolTimestamp | undefined; + timestampLastRefundStatus: TalerPreciseTimestamp | undefined; /** * Last session signature that we submitted to /pay (if any). @@ -1312,12 +1313,12 @@ export interface WalletBackupConfState { /** * Timestamp stored in the last backup. */ - lastBackupTimestamp?: TalerProtocolTimestamp; + lastBackupTimestamp?: TalerPreciseTimestamp; /** * Last time we tried to do a backup. */ - lastBackupCheckTimestamp?: TalerProtocolTimestamp; + lastBackupCheckTimestamp?: TalerPreciseTimestamp; lastBackupNonce?: string; } @@ -1421,12 +1422,12 @@ export interface WithdrawalGroupRecord { * When was the withdrawal operation started started? * Timestamp in milliseconds. */ - timestampStart: TalerProtocolTimestamp; + timestampStart: TalerPreciseTimestamp; /** * When was the withdrawal operation completed? */ - timestampFinish?: TalerProtocolTimestamp; + timestampFinish?: TalerPreciseTimestamp; /** * Current status of the reserve. @@ -1517,9 +1518,9 @@ export interface RecoupGroupRecord { exchangeBaseUrl: string; - timestampStarted: TalerProtocolTimestamp; + timestampStarted: TalerPreciseTimestamp; - timestampFinished: TalerProtocolTimestamp | undefined; + timestampFinished: TalerPreciseTimestamp | undefined; /** * Public keys that identify the coins being recouped @@ -1553,7 +1554,7 @@ export type BackupProviderState = } | { tag: BackupProviderStateTag.Ready; - nextBackupTimestamp: TalerProtocolTimestamp; + nextBackupTimestamp: TalerPreciseTimestamp; } | { tag: BackupProviderStateTag.Retrying; @@ -1598,7 +1599,7 @@ export interface BackupProviderRecord { * Does NOT correspond to the timestamp of the backup, * which only changes when the backup content changes. */ - lastBackupCycleTimestamp?: TalerProtocolTimestamp; + lastBackupCycleTimestamp?: TalerPreciseTimestamp; /** * Proposal that we're currently trying to pay for. @@ -1693,9 +1694,9 @@ export interface DepositGroupRecord { */ effectiveDepositAmount: AmountString; - timestampCreated: TalerProtocolTimestamp; + timestampCreated: TalerPreciseTimestamp; - timestampFinished: TalerProtocolTimestamp | undefined; + timestampFinished: TalerPreciseTimestamp | undefined; operationStatus: DepositOperationStatus; @@ -1728,7 +1729,7 @@ export interface GhostDepositGroupRecord { * When multiple deposits for the same contract terms hash * have a different timestamp, we choose the earliest one. */ - timestamp: TalerProtocolTimestamp; + timestamp: TalerPreciseTimestamp; contractTermsHash: string; @@ -1821,7 +1822,7 @@ export interface PeerPushPaymentInitiationRecord { purseExpiration: TalerProtocolTimestamp; - timestampCreated: TalerProtocolTimestamp; + timestampCreated: TalerPreciseTimestamp; /** * Status of the peer push payment initiation. @@ -1882,7 +1883,7 @@ export interface PeerPullPaymentInitiationRecord { contractTerms: PeerContractTerms; - mergeTimestamp: TalerProtocolTimestamp; + mergeTimestamp: TalerPreciseTimestamp; mergeReserveRowId: number; @@ -1924,7 +1925,7 @@ export interface PeerPushPaymentIncomingRecord { contractPriv: string; - timestamp: TalerProtocolTimestamp; + timestamp: TalerPreciseTimestamp; estimatedAmountEffective: AmountString; @@ -1984,7 +1985,7 @@ export interface PeerPullPaymentIncomingRecord { contractTerms: PeerContractTerms; - timestampCreated: TalerProtocolTimestamp; + timestampCreated: TalerPreciseTimestamp; /** * Contract priv that we got from the other party. @@ -2081,7 +2082,7 @@ export interface UserAttentionRecord { /** * When the user mark this notification as read. */ - read: TalerProtocolTimestamp | undefined; + read: TalerPreciseTimestamp | undefined; } export interface DbExchangeHandle { @@ -2125,7 +2126,7 @@ export interface RefundGroupRecord { /** * Timestamp when the refund group was created. */ - timestampCreated: TalerProtocolTimestamp; + timestampCreated: TalerPreciseTimestamp; proposalId: string; @@ -2180,7 +2181,7 @@ export interface RefundItemRecord { /** * Time when the wallet became aware of the refund. */ - obtainedTime: TalerProtocolTimestamp; + obtainedTime: TalerPreciseTimestamp; refundAmount: AmountString; diff --git a/packages/taler-wallet-core/src/dbless.ts b/packages/taler-wallet-core/src/dbless.ts index 87e3984b6..68cce2b8d 100644 --- a/packages/taler-wallet-core/src/dbless.ts +++ b/packages/taler-wallet-core/src/dbless.ts @@ -256,7 +256,7 @@ export async function depositCoin(args: { const depositPayto = args.depositPayto ?? "payto://x-taler-bank/localhost/foo"; const wireSalt = args.wireSalt ?? encodeCrock(getRandomBytes(16)); - const timestampNow = AbsoluteTime.toTimestamp(AbsoluteTime.now()); + const timestampNow = AbsoluteTime.toProtocolTimestamp(AbsoluteTime.now()); const contractTermsHash = args.contractTermsHash ?? encodeCrock(getRandomBytes(64)); const depositTimestamp = timestampNow; 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); } diff --git a/packages/taler-wallet-core/src/util/coinSelection.ts b/packages/taler-wallet-core/src/util/coinSelection.ts index af6dab2bb..f4066bf51 100644 --- a/packages/taler-wallet-core/src/util/coinSelection.ts +++ b/packages/taler-wallet-core/src/util/coinSelection.ts @@ -577,8 +577,8 @@ export async function selectCandidates( ]?.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 (wireFeeStr) { diff --git a/packages/taler-wallet-core/src/util/denominations.test.ts b/packages/taler-wallet-core/src/util/denominations.test.ts index 551e06a33..25dbda081 100644 --- a/packages/taler-wallet-core/src/util/denominations.test.ts +++ b/packages/taler-wallet-core/src/util/denominations.test.ts @@ -42,7 +42,7 @@ const VALUES: AmountString[] = Array.from({ length: 10 }).map( (undef, t) => `USD:${t}`, ); const TIMESTAMPS = Array.from({ length: 20 }).map((undef, t_s) => ({ t_s })); -const ABS_TIME = TIMESTAMPS.map((m) => AbsoluteTime.fromTimestamp(m)); +const ABS_TIME = TIMESTAMPS.map((m) => AbsoluteTime.fromProtocolTimestamp(m)); function normalize( list: DenominationInfo[], diff --git a/packages/taler-wallet-core/src/util/denominations.ts b/packages/taler-wallet-core/src/util/denominations.ts index 5cc57bdab..ecf8c5671 100644 --- a/packages/taler-wallet-core/src/util/denominations.ts +++ b/packages/taler-wallet-core/src/util/denominations.ts @@ -326,7 +326,7 @@ export function createTimeline( fee: Amounts.stringify(fee), group, id, - moment: AbsoluteTime.fromTimestamp(stampStart), + moment: AbsoluteTime.fromProtocolTimestamp(stampStart), denom, }); ps.push({ @@ -334,7 +334,7 @@ export function createTimeline( fee: Amounts.stringify(fee), group, id, - moment: AbsoluteTime.fromTimestamp(stampEnd), + moment: AbsoluteTime.fromProtocolTimestamp(stampEnd), denom, }); return ps; @@ -457,8 +457,8 @@ export function isWithdrawableDenom( denomselAllowLate?: boolean, ): boolean { const now = AbsoluteTime.now(); - const start = AbsoluteTime.fromTimestamp(d.stampStart); - const withdrawExpire = AbsoluteTime.fromTimestamp(d.stampExpireWithdraw); + const start = AbsoluteTime.fromProtocolTimestamp(d.stampStart); + const withdrawExpire = AbsoluteTime.fromProtocolTimestamp(d.stampExpireWithdraw); const started = AbsoluteTime.cmp(now, start) >= 0; let lastPossibleWithdraw: AbsoluteTime; if (denomselAllowLate) { -- cgit v1.2.3