From f4587c44fd6a6d76384cd671550890255c3fe650 Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Wed, 13 Sep 2023 16:08:51 +0200 Subject: wallet-core: use typed microsecond timestamps in DB --- .../taler-wallet-core/src/operations/attention.ts | 3 +- .../src/operations/backup/index.ts | 31 +++++++++++---- .../taler-wallet-core/src/operations/deposits.ts | 9 ++++- .../taler-wallet-core/src/operations/exchanges.ts | 7 ++-- .../src/operations/pay-merchant.ts | 15 ++++--- .../src/operations/pay-peer-pull-credit.ts | 27 +++++++++---- .../src/operations/pay-peer-pull-debit.ts | 3 +- .../src/operations/pay-peer-push-credit.ts | 46 ++++++---------------- .../src/operations/pay-peer-push-debit.ts | 3 +- .../taler-wallet-core/src/operations/pending.ts | 3 +- .../taler-wallet-core/src/operations/recoup.ts | 5 ++- .../taler-wallet-core/src/operations/refresh.ts | 11 ++++-- .../taler-wallet-core/src/operations/reward.ts | 10 +++-- .../src/operations/transactions.ts | 35 ++++++++-------- .../taler-wallet-core/src/operations/withdraw.ts | 29 ++++++-------- 15 files changed, 132 insertions(+), 105 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 7d84b43ef..1030db0a6 100644 --- a/packages/taler-wallet-core/src/operations/attention.ts +++ b/packages/taler-wallet-core/src/operations/attention.ts @@ -31,6 +31,7 @@ import { UserAttentionUnreadList, } from "@gnu-taler/taler-util"; import { InternalWalletState } from "../internal-wallet-state.js"; +import { timestampPreciseToDb } from "../index.js"; const logger = new Logger("operations/attention.ts"); @@ -94,7 +95,7 @@ export async function markAttentionRequestAsRead( if (!ua) throw Error("attention request not found"); tx.userAttention.put({ ...ua, - read: TalerPreciseTimestamp.now(), + read: timestampPreciseToDb(TalerPreciseTimestamp.now()), }); }); } diff --git a/packages/taler-wallet-core/src/operations/backup/index.ts b/packages/taler-wallet-core/src/operations/backup/index.ts index a5e8dbd42..7a2771c57 100644 --- a/packages/taler-wallet-core/src/operations/backup/index.ts +++ b/packages/taler-wallet-core/src/operations/backup/index.ts @@ -84,6 +84,9 @@ import { ConfigRecord, ConfigRecordKey, WalletBackupConfState, + timestampOptionalPreciseFromDb, + timestampPreciseFromDb, + timestampPreciseToDb, } from "../../db.js"; import { InternalWalletState } from "../../internal-wallet-state.js"; import { assertUnreachable } from "../../util/assertUnreachable.js"; @@ -259,10 +262,12 @@ async function runBackupCycleForProvider( if (!prov) { return; } - prov.lastBackupCycleTimestamp = TalerPreciseTimestamp.now(); + prov.lastBackupCycleTimestamp = timestampPreciseToDb( + TalerPreciseTimestamp.now(), + ); prov.state = { tag: BackupProviderStateTag.Ready, - nextBackupTimestamp: getNextBackupTimestamp(), + nextBackupTimestamp: timestampPreciseToDb(getNextBackupTimestamp()), }; await tx.backupProviders.put(prov); }); @@ -361,10 +366,12 @@ async function runBackupCycleForProvider( return; } prov.lastBackupHash = encodeCrock(currentBackupHash); - prov.lastBackupCycleTimestamp = TalerPreciseTimestamp.now(); + prov.lastBackupCycleTimestamp = timestampPreciseToDb( + TalerPreciseTimestamp.now(), + ); prov.state = { tag: BackupProviderStateTag.Ready, - nextBackupTimestamp: getNextBackupTimestamp(), + nextBackupTimestamp: timestampPreciseToDb(getNextBackupTimestamp()), }; await tx.backupProviders.put(prov); }); @@ -594,7 +601,9 @@ export async function addBackupProvider( if (req.activate) { oldProv.state = { tag: BackupProviderStateTag.Ready, - nextBackupTimestamp: TalerPreciseTimestamp.now(), + nextBackupTimestamp: timestampPreciseToDb( + TalerPreciseTimestamp.now(), + ), }; logger.info("setting existing backup provider to active"); await tx.backupProviders.put(oldProv); @@ -616,7 +625,9 @@ export async function addBackupProvider( if (req.activate) { state = { tag: BackupProviderStateTag.Ready, - nextBackupTimestamp: TalerPreciseTimestamp.now(), + nextBackupTimestamp: timestampPreciseToDb( + TalerPreciseTimestamp.now(), + ), }; } else { state = { @@ -840,7 +851,9 @@ export async function getBackupInfo( providers.push({ active: x.provider.state.tag !== BackupProviderStateTag.Provisional, syncProviderBaseUrl: x.provider.baseUrl, - lastSuccessfulBackupTimestamp: x.provider.lastBackupCycleTimestamp, + lastSuccessfulBackupTimestamp: timestampOptionalPreciseFromDb( + x.provider.lastBackupCycleTimestamp, + ), paymentProposalIds: x.provider.paymentProposalIds, lastError: x.provider.state.tag === BackupProviderStateTag.Retrying @@ -917,7 +930,9 @@ async function backupRecoveryTheirs( shouldRetryFreshProposal: false, state: { tag: BackupProviderStateTag.Ready, - nextBackupTimestamp: TalerPreciseTimestamp.now(), + nextBackupTimestamp: timestampPreciseToDb( + 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 2de8f30a1..cb40f8f22 100644 --- a/packages/taler-wallet-core/src/operations/deposits.ts +++ b/packages/taler-wallet-core/src/operations/deposits.ts @@ -73,6 +73,7 @@ import { RefreshOperationStatus, createRefreshGroup, getTotalRefreshCost, + timestampPreciseToDb, } from "../index.js"; import { InternalWalletState } from "../internal-wallet-state.js"; import { assertUnreachable } from "../util/assertUnreachable.js"; @@ -857,7 +858,9 @@ async function processDepositGroupPendingTrack( } } if (allWired) { - dg.timestampFinished = TalerPreciseTimestamp.now(); + dg.timestampFinished = timestampPreciseToDb( + TalerPreciseTimestamp.now(), + ); dg.operationStatus = DepositOperationStatus.Finished; await tx.depositGroups.put(dg); } @@ -1375,7 +1378,9 @@ export async function createDepositGroup( amount: contractData.amount, noncePriv: noncePair.priv, noncePub: noncePair.pub, - timestampCreated: AbsoluteTime.toPreciseTimestamp(now), + timestampCreated: timestampPreciseToDb( + AbsoluteTime.toPreciseTimestamp(now), + ), timestampFinished: undefined, statusPerCoin: payCoinSel.coinSel.coinPubs.map( () => DepositElementStatus.DepositPending, diff --git a/packages/taler-wallet-core/src/operations/exchanges.ts b/packages/taler-wallet-core/src/operations/exchanges.ts index 43a08ed3b..60d55252a 100644 --- a/packages/taler-wallet-core/src/operations/exchanges.ts +++ b/packages/taler-wallet-core/src/operations/exchanges.ts @@ -74,6 +74,7 @@ import { ExchangeEntryDbRecordStatus, ExchangeEntryDbUpdateStatus, isWithdrawableDenom, + timestampPreciseToDb, WalletDbReadWriteTransaction, } from "../index.js"; import { InternalWalletState, TrustInfo } from "../internal-wallet-state.js"; @@ -174,7 +175,7 @@ export async function acceptExchangeTermsOfService( if (d) { d.tosAccepted = { etag: etag || d.tosCurrentEtag, - timestamp: TalerPreciseTimestamp.now(), + timestamp: timestampPreciseToDb(TalerPreciseTimestamp.now()), }; await tx.exchangeDetails.put(d); } @@ -753,7 +754,7 @@ export async function updateExchangeFromUrlHandler( if (existingDetails?.rowId) { newDetails.rowId = existingDetails.rowId; } - r.lastUpdate = TalerPreciseTimestamp.now(); + r.lastUpdate = timestampPreciseToDb(TalerPreciseTimestamp.now()); r.nextUpdateStampMs = AbsoluteTime.toStampMs( AbsoluteTime.fromProtocolTimestamp(keysInfo.expiry), ); @@ -763,7 +764,7 @@ export async function updateExchangeFromUrlHandler( r.detailsPointer = { currency: newDetails.currency, masterPublicKey: newDetails.masterPublicKey, - updateClock: TalerPreciseTimestamp.now(), + updateClock: timestampPreciseToDb(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 fe0cbeda0..97bf6e2a6 100644 --- a/packages/taler-wallet-core/src/operations/pay-merchant.ts +++ b/packages/taler-wallet-core/src/operations/pay-merchant.ts @@ -103,6 +103,7 @@ import { RefundGroupStatus, RefundItemRecord, RefundItemStatus, + timestampPreciseToDb, } from "../index.js"; import { EXCHANGE_COINS_LOCK, @@ -644,7 +645,7 @@ async function createPurchase( noncePriv: priv, noncePub: pub, claimToken, - timestamp: TalerPreciseTimestamp.now(), + timestamp: timestampPreciseToDb(TalerPreciseTimestamp.now()), merchantBaseUrl, orderId, proposalId: proposalId, @@ -717,7 +718,7 @@ async function storeFirstPaySuccess( if (purchase.purchaseStatus === PurchaseStatus.PendingPaying) { purchase.purchaseStatus = PurchaseStatus.Done; } - purchase.timestampFirstSuccessfulPay = now; + purchase.timestampFirstSuccessfulPay = timestampPreciseToDb(now); purchase.lastSessionId = sessionId; purchase.merchantPaySig = payResponse.sig; purchase.posConfirmation = payResponse.pos_confirmation; @@ -941,7 +942,9 @@ async function unblockBackup( .forEachAsync(async (bp) => { bp.state = { tag: BackupProviderStateTag.Ready, - nextBackupTimestamp: TalerPreciseTimestamp.now(), + nextBackupTimestamp: timestampPreciseToDb( + TalerPreciseTimestamp.now(), + ), }; tx.backupProviders.put(bp); }); @@ -1447,7 +1450,7 @@ export async function confirmPay( totalPayCost: Amounts.stringify(payCostInfo), }; p.lastSessionId = sessionId; - p.timestampAccept = TalerPreciseTimestamp.now(); + p.timestampAccept = timestampPreciseToDb(TalerPreciseTimestamp.now()); p.purchaseStatus = PurchaseStatus.PendingPaying; await tx.purchases.put(p); await spendCoins(ws, tx, { @@ -2791,7 +2794,7 @@ async function storeRefunds( proposalId: purchase.proposalId, refundGroupId: newRefundGroupId, status: RefundGroupStatus.Pending, - timestampCreated: now, + timestampCreated: timestampPreciseToDb(now), amountEffective: Amounts.stringify( Amounts.zeroOfCurrency(currency), ), @@ -2802,7 +2805,7 @@ async function storeRefunds( const newItem: RefundItemRecord = { coinPub: rf.coin_pub, executionTime: rf.execution_time, - obtainedTime: now, + obtainedTime: timestampPreciseToDb(now), refundAmount: rf.refund_amount, refundGroupId: newGroup.refundGroupId, rtxid: rf.rtransaction_id, diff --git a/packages/taler-wallet-core/src/operations/pay-peer-pull-credit.ts b/packages/taler-wallet-core/src/operations/pay-peer-pull-credit.ts index 0355eb152..6ec8822ab 100644 --- a/packages/taler-wallet-core/src/operations/pay-peer-pull-credit.ts +++ b/packages/taler-wallet-core/src/operations/pay-peer-pull-credit.ts @@ -60,6 +60,9 @@ import { PeerPullPaymentCreditStatus, WithdrawalGroupStatus, WithdrawalRecordType, + timestampOptionalPreciseFromDb, + timestampPreciseFromDb, + timestampPreciseToDb, updateExchangeFromUrl, } from "../index.js"; import { InternalWalletState } from "../internal-wallet-state.js"; @@ -395,12 +398,14 @@ async function handlePeerPullCreditCreatePurse( nonce: pullIni.contractEncNonce, }); + const mergeTimestamp = timestampPreciseFromDb(pullIni.mergeTimestamp); + const purseExpiration = contractTerms.purse_expiration; const sigRes = await ws.cryptoApi.signReservePurseCreate({ contractTermsHash: pullIni.contractTermsHash, flags: WalletAccountMergeFlags.CreateWithPurseFee, mergePriv: pullIni.mergePriv, - mergeTimestamp: TalerPreciseTimestamp.round(pullIni.mergeTimestamp), + mergeTimestamp: TalerPreciseTimestamp.round(mergeTimestamp), purseAmount: pullIni.amount, purseExpiration: purseExpiration, purseFee: purseFee, @@ -412,7 +417,7 @@ async function handlePeerPullCreditCreatePurse( const reservePurseReqBody: ExchangeReservePurseRequest = { merge_sig: sigRes.mergeSig, - merge_timestamp: TalerPreciseTimestamp.round(pullIni.mergeTimestamp), + merge_timestamp: TalerPreciseTimestamp.round(mergeTimestamp), h_contract_terms: pullIni.contractTermsHash, merge_pub: pullIni.mergePub, min_age: 0, @@ -695,11 +700,17 @@ async function getPreferredExchangeForCurrency( if (candidate.lastWithdrawal && !e.lastWithdrawal) { continue; } - if (candidate.lastWithdrawal && e.lastWithdrawal) { + const exchangeLastWithdrawal = timestampOptionalPreciseFromDb( + e.lastWithdrawal, + ); + const candidateLastWithdrawal = timestampOptionalPreciseFromDb( + candidate.lastWithdrawal, + ); + if (exchangeLastWithdrawal && candidateLastWithdrawal) { if ( AbsoluteTime.cmp( - AbsoluteTime.fromPreciseTimestamp(e.lastWithdrawal), - AbsoluteTime.fromPreciseTimestamp(candidate.lastWithdrawal), + AbsoluteTime.fromPreciseTimestamp(exchangeLastWithdrawal), + AbsoluteTime.fromPreciseTimestamp(candidateLastWithdrawal), ) > 0 ) { candidate = e; @@ -741,8 +752,6 @@ export async function initiatePeerPullPayment( exchangeBaseUrl: exchangeBaseUrl, }); - const mergeTimestamp = TalerPreciseTimestamp.now(); - const pursePair = await ws.cryptoApi.createEddsaKeypair({}); const mergePair = await ws.cryptoApi.createEddsaKeypair({}); @@ -766,6 +775,8 @@ export async function initiatePeerPullPayment( undefined, ); + const mergeTimestamp = TalerPreciseTimestamp.now(); + const transitionInfo = await ws.db .mktx((x) => [x.peerPullCredit, x.contractTerms]) .runReadWrite(async (tx) => { @@ -778,7 +789,7 @@ export async function initiatePeerPullPayment( mergePriv: mergePair.priv, mergePub: mergePair.pub, status: PeerPullPaymentCreditStatus.PendingCreatePurse, - mergeTimestamp, + mergeTimestamp: timestampPreciseToDb(mergeTimestamp), contractEncNonce, mergeReserveRowId: mergeReserveRowId, contractPriv: contractKeyPair.priv, diff --git a/packages/taler-wallet-core/src/operations/pay-peer-pull-debit.ts b/packages/taler-wallet-core/src/operations/pay-peer-pull-debit.ts index 5bcfa3418..48cbf574f 100644 --- a/packages/taler-wallet-core/src/operations/pay-peer-pull-debit.ts +++ b/packages/taler-wallet-core/src/operations/pay-peer-pull-debit.ts @@ -59,6 +59,7 @@ import { PendingTaskType, RefreshOperationStatus, createRefreshGroup, + timestampPreciseToDb, } from "../index.js"; import { assertUnreachable } from "../util/assertUnreachable.js"; import { checkLogicInvariant } from "../util/invariants.js"; @@ -595,7 +596,7 @@ export async function preparePeerPullDebit( contractPriv: contractPriv, exchangeBaseUrl: exchangeBaseUrl, pursePub: pursePub, - timestampCreated: TalerPreciseTimestamp.now(), + timestampCreated: timestampPreciseToDb(TalerPreciseTimestamp.now()), contractTermsHash, amount: contractTerms.amount, status: PeerPullDebitRecordStatus.DialogProposed, diff --git a/packages/taler-wallet-core/src/operations/pay-peer-push-credit.ts b/packages/taler-wallet-core/src/operations/pay-peer-push-credit.ts index 89d9e3b49..e4698c203 100644 --- a/packages/taler-wallet-core/src/operations/pay-peer-push-credit.ts +++ b/packages/taler-wallet-core/src/operations/pay-peer-push-credit.ts @@ -59,6 +59,7 @@ import { PendingTaskType, WithdrawalGroupStatus, WithdrawalRecordType, + timestampPreciseToDb, } from "../index.js"; import { assertUnreachable } from "../util/assertUnreachable.js"; import { checkDbInvariant } from "../util/invariants.js"; @@ -129,12 +130,10 @@ export async function preparePeerPushCredit( amountEffective: existing.existingPushInc.estimatedAmountEffective, amountRaw: existing.existingContractTerms.amount, contractTerms: existing.existingContractTerms, - peerPushCreditId: - existing.existingPushInc.peerPushCreditId, + peerPushCreditId: existing.existingPushInc.peerPushCreditId, transactionId: constructTransactionIdentifier({ tag: TransactionType.PeerPushCredit, - peerPushCreditId: - existing.existingPushInc.peerPushCreditId, + peerPushCreditId: existing.existingPushInc.peerPushCreditId, }), }; } @@ -196,7 +195,7 @@ export async function preparePeerPushCredit( exchangeBaseUrl: exchangeBaseUrl, mergePriv: dec.mergePriv, pursePub: pursePub, - timestamp: TalerPreciseTimestamp.now(), + timestamp: timestampPreciseToDb(TalerPreciseTimestamp.now()), contractTermsHash, status: PeerPushCreditStatus.DialogProposed, withdrawalGroupId, @@ -263,16 +262,11 @@ async function longpollKycStatus( const transitionInfo = await ws.db .mktx((x) => [x.peerPushCredit]) .runReadWrite(async (tx) => { - const peerInc = await tx.peerPushCredit.get( - peerPushCreditId, - ); + const peerInc = await tx.peerPushCredit.get(peerPushCreditId); if (!peerInc) { return; } - if ( - peerInc.status !== - PeerPushCreditStatus.PendingMergeKycRequired - ) { + if (peerInc.status !== PeerPushCreditStatus.PendingMergeKycRequired) { return; } const oldTxState = computePeerPushCreditTransactionState(peerInc); @@ -333,9 +327,7 @@ async function processPeerPushCreditKycRequired( const { transitionInfo, result } = await ws.db .mktx((x) => [x.peerPushCredit]) .runReadWrite(async (tx) => { - const peerInc = await tx.peerPushCredit.get( - peerPushCreditId, - ); + const peerInc = await tx.peerPushCredit.get(peerPushCreditId); if (!peerInc) { return { transitionInfo: undefined, @@ -466,9 +458,7 @@ async function handlePendingMerge( x.exchangeDetails, ]) .runReadWrite(async (tx) => { - const peerInc = await tx.peerPushCredit.get( - peerPushCreditId, - ); + const peerInc = await tx.peerPushCredit.get(peerPushCreditId); if (!peerInc) { return undefined; } @@ -520,9 +510,7 @@ async function handlePendingWithdrawing( const transitionInfo = await ws.db .mktx((x) => [x.peerPushCredit, x.withdrawalGroups]) .runReadWrite(async (tx) => { - const ppi = await tx.peerPushCredit.get( - peerInc.peerPushCreditId, - ); + const ppi = await tx.peerPushCredit.get(peerInc.peerPushCreditId); if (!ppi) { finished = true; return; @@ -631,9 +619,7 @@ export async function confirmPeerPushCredit( } peerPushCreditId = parsedTx.peerPushCreditId; } else { - throw Error( - "no transaction ID (or deprecated peerPushCreditId) provided", - ); + throw Error("no transaction ID (or deprecated peerPushCreditId) provided"); } await ws.db @@ -683,9 +669,7 @@ export async function suspendPeerPushCreditTransaction( const transitionInfo = await ws.db .mktx((x) => [x.peerPushCredit]) .runReadWrite(async (tx) => { - const pushCreditRec = await tx.peerPushCredit.get( - peerPushCreditId, - ); + const pushCreditRec = await tx.peerPushCredit.get(peerPushCreditId); if (!pushCreditRec) { logger.warn(`peer push credit ${peerPushCreditId} not found`); return; @@ -746,9 +730,7 @@ export async function abortPeerPushCreditTransaction( const transitionInfo = await ws.db .mktx((x) => [x.peerPushCredit]) .runReadWrite(async (tx) => { - const pushCreditRec = await tx.peerPushCredit.get( - peerPushCreditId, - ); + const pushCreditRec = await tx.peerPushCredit.get(peerPushCreditId); if (!pushCreditRec) { logger.warn(`peer push credit ${peerPushCreditId} not found`); return; @@ -820,9 +802,7 @@ export async function resumePeerPushCreditTransaction( const transitionInfo = await ws.db .mktx((x) => [x.peerPushCredit]) .runReadWrite(async (tx) => { - const pushCreditRec = await tx.peerPushCredit.get( - peerPushCreditId, - ); + const pushCreditRec = await tx.peerPushCredit.get(peerPushCreditId); if (!pushCreditRec) { logger.warn(`peer push credit ${peerPushCreditId} not found`); return; diff --git a/packages/taler-wallet-core/src/operations/pay-peer-push-debit.ts b/packages/taler-wallet-core/src/operations/pay-peer-push-debit.ts index e80ffc059..b3d0eb132 100644 --- a/packages/taler-wallet-core/src/operations/pay-peer-push-debit.ts +++ b/packages/taler-wallet-core/src/operations/pay-peer-push-debit.ts @@ -55,6 +55,7 @@ import { PeerPushDebitStatus, RefreshOperationStatus, createRefreshGroup, + timestampPreciseToDb, } from "../index.js"; import { InternalWalletState } from "../internal-wallet-state.js"; import { PendingTaskType } from "../pending-types.js"; @@ -669,7 +670,7 @@ export async function initiatePeerPushDebit( purseExpiration: purseExpiration, pursePriv: pursePair.priv, pursePub: pursePair.pub, - timestampCreated: TalerPreciseTimestamp.now(), + timestampCreated: timestampPreciseToDb(TalerPreciseTimestamp.now()), status: PeerPushDebitStatus.PendingCreatePurse, contractEncNonce, coinSel: { diff --git a/packages/taler-wallet-core/src/operations/pending.ts b/packages/taler-wallet-core/src/operations/pending.ts index 6115f848b..120d316ce 100644 --- a/packages/taler-wallet-core/src/operations/pending.ts +++ b/packages/taler-wallet-core/src/operations/pending.ts @@ -47,6 +47,7 @@ import { ExchangeEntryDbUpdateStatus, RefreshOperationStatus, DepositElementStatus, + timestampPreciseFromDb, } from "../db.js"; import { PendingOperationsResponse, @@ -445,7 +446,7 @@ async function gatherBackupPending( const retryRecord = await tx.operationRetries.get(opId); if (bp.state.tag === BackupProviderStateTag.Ready) { const timestampDue = AbsoluteTime.fromPreciseTimestamp( - bp.state.nextBackupTimestamp, + timestampPreciseFromDb(bp.state.nextBackupTimestamp), ); resp.pendingOperations.push({ type: PendingTaskType.Backup, diff --git a/packages/taler-wallet-core/src/operations/recoup.ts b/packages/taler-wallet-core/src/operations/recoup.ts index 6a18e5de6..782e98d1c 100644 --- a/packages/taler-wallet-core/src/operations/recoup.ts +++ b/packages/taler-wallet-core/src/operations/recoup.ts @@ -47,6 +47,7 @@ import { WithdrawCoinSource, WithdrawalGroupStatus, WithdrawalRecordType, + timestampPreciseToDb, } from "../db.js"; import { InternalWalletState } from "../internal-wallet-state.js"; import { checkDbInvariant } from "../util/invariants.js"; @@ -391,7 +392,7 @@ export async function processRecoupGroup( if (!rg2) { return; } - rg2.timestampFinished = TalerPreciseTimestamp.now(); + rg2.timestampFinished = timestampPreciseToDb(TalerPreciseTimestamp.now()); if (rg2.scheduleRefreshCoins.length > 0) { const refreshGroupId = await createRefreshGroup( ws, @@ -424,7 +425,7 @@ export async function createRecoupGroup( exchangeBaseUrl: exchangeBaseUrl, coinPubs: coinPubs, timestampFinished: undefined, - timestampStarted: TalerPreciseTimestamp.now(), + timestampStarted: timestampPreciseToDb(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 75adbc860..dc1d53627 100644 --- a/packages/taler-wallet-core/src/operations/refresh.ts +++ b/packages/taler-wallet-core/src/operations/refresh.ts @@ -80,6 +80,7 @@ import { isWithdrawableDenom, PendingTaskType, RefreshSessionRecord, + timestampPreciseToDb, } from "../index.js"; import { EXCHANGE_COINS_LOCK, @@ -157,10 +158,10 @@ function updateGroupStatus(rg: RefreshGroupRecord): { final: boolean } { ); if (allFinal) { if (anyFailed) { - rg.timestampFinished = TalerPreciseTimestamp.now(); + rg.timestampFinished = timestampPreciseToDb(TalerPreciseTimestamp.now()); rg.operationStatus = RefreshOperationStatus.Failed; } else { - rg.timestampFinished = TalerPreciseTimestamp.now(); + rg.timestampFinished = timestampPreciseToDb(TalerPreciseTimestamp.now()); rg.operationStatus = RefreshOperationStatus.Finished; } return { final: true }; @@ -1099,12 +1100,14 @@ export async function createRefreshGroup( expectedOutputPerCoin: estimatedOutputPerCoin.map((x) => Amounts.stringify(x), ), - timestampCreated: TalerPreciseTimestamp.now(), + timestampCreated: timestampPreciseToDb(TalerPreciseTimestamp.now()), }; if (oldCoinPubs.length == 0) { logger.warn("created refresh group with zero coins"); - refreshGroup.timestampFinished = TalerPreciseTimestamp.now(); + refreshGroup.timestampFinished = timestampPreciseToDb( + TalerPreciseTimestamp.now(), + ); refreshGroup.operationStatus = RefreshOperationStatus.Finished; } diff --git a/packages/taler-wallet-core/src/operations/reward.ts b/packages/taler-wallet-core/src/operations/reward.ts index 6ae021174..3681dc4f5 100644 --- a/packages/taler-wallet-core/src/operations/reward.ts +++ b/packages/taler-wallet-core/src/operations/reward.ts @@ -50,6 +50,8 @@ import { DenominationRecord, RewardRecord, RewardRecordStatus, + timestampPreciseFromDb, + timestampPreciseToDb, } from "../db.js"; import { makeErrorDetail } from "@gnu-taler/taler-util"; import { InternalWalletState } from "../internal-wallet-state.js"; @@ -203,7 +205,7 @@ export async function prepareTip( exchangeBaseUrl: tipPickupStatus.exchange_url, next_url: tipPickupStatus.next_url, merchantBaseUrl: res.merchantBaseUrl, - createdTimestamp: TalerPreciseTimestamp.now(), + createdTimestamp: timestampPreciseToDb(TalerPreciseTimestamp.now()), merchantRewardId: res.merchantRewardId, rewardAmountEffective: Amounts.stringify(selectedDenoms.totalCoinValue), denomsSel: selectedDenoms, @@ -411,7 +413,7 @@ export async function processTip( return; } const oldTxState = computeRewardTransactionStatus(tr); - tr.pickedUpTimestamp = TalerPreciseTimestamp.now(); + tr.pickedUpTimestamp = timestampPreciseToDb(TalerPreciseTimestamp.now()); tr.status = RewardRecordStatus.Done; await tx.rewards.put(tr); const newTxState = computeRewardTransactionStatus(tr); @@ -448,7 +450,9 @@ export async function acceptTip( return { tipRecord }; } const oldTxState = computeRewardTransactionStatus(tipRecord); - tipRecord.acceptedTimestamp = TalerPreciseTimestamp.now(); + tipRecord.acceptedTimestamp = timestampPreciseToDb( + TalerPreciseTimestamp.now(), + ); tipRecord.status = RewardRecordStatus.PendingPickup; await tx.rewards.put(tipRecord); const newTxState = computeRewardTransactionStatus(tipRecord); diff --git a/packages/taler-wallet-core/src/operations/transactions.ts b/packages/taler-wallet-core/src/operations/transactions.ts index d7b277faf..41bdae249 100644 --- a/packages/taler-wallet-core/src/operations/transactions.ts +++ b/packages/taler-wallet-core/src/operations/transactions.ts @@ -65,7 +65,12 @@ import { WithdrawalGroupStatus, WithdrawalRecordType, } from "../db.js"; -import { GetReadOnlyAccess, WalletStoresV1 } from "../index.js"; +import { + GetReadOnlyAccess, + timestampOptionalPreciseFromDb, + timestampPreciseFromDb, + WalletStoresV1, +} from "../index.js"; import { InternalWalletState } from "../internal-wallet-state.js"; import { PendingTaskType } from "../pending-types.js"; import { assertUnreachable } from "../util/assertUnreachable.js"; @@ -470,7 +475,7 @@ function buildTransactionForPushPaymentDebit( expiration: contractTerms.purse_expiration, summary: contractTerms.summary, }, - timestamp: pi.timestampCreated, + timestamp: timestampPreciseFromDb(pi.timestampCreated), talerUri: stringifyPayPushUri({ exchangeBaseUrl: pi.exchangeBaseUrl, contractPriv: pi.contractPriv, @@ -501,7 +506,7 @@ function buildTransactionForPullPaymentDebit( expiration: contractTerms.purse_expiration, summary: contractTerms.summary, }, - timestamp: pi.timestampCreated, + timestamp: timestampPreciseFromDb(pi.timestampCreated), transactionId: constructTransactionIdentifier({ tag: TransactionType.PeerPullDebit, peerPullDebitId: pi.peerPullDebitId, @@ -543,8 +548,7 @@ function buildTransactionForPeerPullCredit( amountEffective: Amounts.stringify(wsr.denomsSel.totalCoinValue), amountRaw: Amounts.stringify(wsr.instructedAmount), exchangeBaseUrl: wsr.exchangeBaseUrl, - // Old transactions don't have it! - timestamp: pullCredit.mergeTimestamp ?? TalerPreciseTimestamp.now(), + timestamp: timestampPreciseFromDb(pullCredit.mergeTimestamp), info: { expiration: peerContractTerms.purse_expiration, summary: peerContractTerms.summary, @@ -575,8 +579,7 @@ function buildTransactionForPeerPullCredit( amountEffective: Amounts.stringify(pullCredit.estimatedAmountEffective), amountRaw: Amounts.stringify(peerContractTerms.amount), exchangeBaseUrl: pullCredit.exchangeBaseUrl, - // Old transactions don't have it! - timestamp: pullCredit.mergeTimestamp ?? TalerProtocolTimestamp.now(), + timestamp: timestampPreciseFromDb(pullCredit.mergeTimestamp), info: { expiration: peerContractTerms.purse_expiration, summary: peerContractTerms.summary, @@ -617,7 +620,7 @@ function buildTransactionForPeerPushCredit( expiration: peerContractTerms.purse_expiration, summary: peerContractTerms.summary, }, - timestamp: wsr.timestampStart, + timestamp: timestampPreciseFromDb(wsr.timestampStart), transactionId: constructTransactionIdentifier({ tag: TransactionType.PeerPushCredit, peerPushCreditId: pushInc.peerPushCreditId, @@ -640,7 +643,7 @@ function buildTransactionForPeerPushCredit( summary: peerContractTerms.summary, }, kycUrl: pushInc.kycUrl, - timestamp: pushInc.timestamp, + timestamp: timestampPreciseFromDb(pushInc.timestamp), transactionId: constructTransactionIdentifier({ tag: TransactionType.PeerPushCredit, peerPushCreditId: pushInc.peerPushCreditId, @@ -673,7 +676,7 @@ function buildTransactionForBankIntegratedWithdraw( }, kycUrl: wgRecord.kycUrl, exchangeBaseUrl: wgRecord.exchangeBaseUrl, - timestamp: wgRecord.timestampStart, + timestamp: timestampPreciseFromDb(wgRecord.timestampStart), transactionId: constructTransactionIdentifier({ tag: TransactionType.Withdrawal, withdrawalGroupId: wgRecord.withdrawalGroupId, @@ -717,7 +720,7 @@ function buildTransactionForManualWithdraw( }, kycUrl: withdrawalGroup.kycUrl, exchangeBaseUrl: withdrawalGroup.exchangeBaseUrl, - timestamp: withdrawalGroup.timestampStart, + timestamp: timestampPreciseFromDb(withdrawalGroup.timestampStart), transactionId: constructTransactionIdentifier({ tag: TransactionType.Withdrawal, withdrawalGroupId: withdrawalGroup.withdrawalGroupId, @@ -748,7 +751,7 @@ function buildTransactionForRefund( tag: TransactionType.Payment, proposalId: refundRecord.proposalId, }), - timestamp: refundRecord.timestampCreated, + timestamp: timestampPreciseFromDb(refundRecord.timestampCreated), transactionId: constructTransactionIdentifier({ tag: TransactionType.Refund, refundGroupId: refundRecord.refundGroupId, @@ -786,7 +789,7 @@ function buildTransactionForRefresh( refreshOutputAmount: Amounts.stringify(outputAmount), originatingTransactionId: refreshGroupRecord.reasonDetails?.originatingTransactionId, - timestamp: refreshGroupRecord.timestampCreated, + timestamp: timestampPreciseFromDb(refreshGroupRecord.timestampCreated), transactionId: constructTransactionIdentifier({ tag: TransactionType.Refresh, refreshGroupId: refreshGroupRecord.refreshGroupId, @@ -812,7 +815,7 @@ function buildTransactionForDeposit( txActions: computeDepositTransactionActions(dg), amountRaw: Amounts.stringify(dg.counterpartyEffectiveDepositAmount), amountEffective: Amounts.stringify(dg.totalPayCost), - timestamp: dg.timestampCreated, + timestamp: timestampPreciseFromDb(dg.timestampCreated), targetPaytoUri: dg.wire.payto_uri, wireTransferDeadline: dg.wireTransferDeadline, transactionId: constructTransactionIdentifier({ @@ -845,7 +848,7 @@ function buildTransactionForTip( txActions: computeTipTransactionActions(tipRecord), amountEffective: Amounts.stringify(tipRecord.rewardAmountEffective), amountRaw: Amounts.stringify(tipRecord.rewardAmountRaw), - timestamp: tipRecord.acceptedTimestamp, + timestamp: timestampPreciseFromDb(tipRecord.acceptedTimestamp), transactionId: constructTransactionIdentifier({ tag: TransactionType.Reward, walletRewardId: tipRecord.walletRewardId, @@ -922,7 +925,7 @@ async function buildTransactionForPurchase( : Amounts.stringify(purchaseRecord.refundAmountAwaiting), refunds, posConfirmation: purchaseRecord.posConfirmation, - timestamp, + timestamp: timestampPreciseFromDb(timestamp), transactionId: constructTransactionIdentifier({ tag: TransactionType.Payment, proposalId: purchaseRecord.proposalId, diff --git a/packages/taler-wallet-core/src/operations/withdraw.ts b/packages/taler-wallet-core/src/operations/withdraw.ts index 32e63f4f6..fb503d75f 100644 --- a/packages/taler-wallet-core/src/operations/withdraw.ts +++ b/packages/taler-wallet-core/src/operations/withdraw.ts @@ -131,6 +131,7 @@ import { ExchangeEntryDbUpdateStatus, PendingTaskType, isWithdrawableDenom, + timestampPreciseToDb, } from "../index.js"; import { TransitionInfo, @@ -1325,7 +1326,7 @@ async function processWithdrawalGroupAbortingBank( } const txStatusOld = computeWithdrawalTransactionStatus(wg); wg.status = WithdrawalGroupStatus.AbortedBank; - wg.timestampFinish = TalerPreciseTimestamp.now(); + wg.timestampFinish = timestampPreciseToDb(TalerPreciseTimestamp.now()); const txStatusNew = computeWithdrawalTransactionStatus(wg); await tx.withdrawalGroups.put(wg); return { @@ -1458,7 +1459,7 @@ async function processWithdrawalGroupPendingReady( } const txStatusOld = computeWithdrawalTransactionStatus(wg); wg.status = WithdrawalGroupStatus.Done; - wg.timestampFinish = TalerPreciseTimestamp.now(); + wg.timestampFinish = timestampPreciseToDb(TalerPreciseTimestamp.now()); const txStatusNew = computeWithdrawalTransactionStatus(wg); await tx.withdrawalGroups.put(wg); return { @@ -1554,7 +1555,7 @@ async function processWithdrawalGroupPendingReady( const oldTxState = computeWithdrawalTransactionStatus(wg); logger.info(`now withdrawn ${numFinished} of ${numTotalCoins} coins`); if (wg.timestampFinish === undefined && numFinished === numTotalCoins) { - wg.timestampFinish = TalerPreciseTimestamp.now(); + wg.timestampFinish = timestampPreciseToDb(TalerPreciseTimestamp.now()); wg.status = WithdrawalGroupStatus.Done; await makeCoinsVisible(ws, tx, transactionId); } @@ -2047,8 +2048,9 @@ async function registerReserveWithBank( if (r.wgInfo.withdrawalType !== WithdrawalRecordType.BankIntegrated) { throw Error("invariant failed"); } - r.wgInfo.bankInfo.timestampReserveInfoPosted = - AbsoluteTime.toPreciseTimestamp(AbsoluteTime.now()); + r.wgInfo.bankInfo.timestampReserveInfoPosted = timestampPreciseToDb( + AbsoluteTime.toPreciseTimestamp(AbsoluteTime.now()), + ); const oldTxState = computeWithdrawalTransactionStatus(r); r.status = WithdrawalGroupStatus.PendingWaitConfirmBank; const newTxState = computeWithdrawalTransactionStatus(r); @@ -2130,7 +2132,7 @@ async function processReserveBankStatus( } const now = AbsoluteTime.toPreciseTimestamp(AbsoluteTime.now()); const oldTxState = computeWithdrawalTransactionStatus(r); - r.wgInfo.bankInfo.timestampBankConfirmed = now; + r.wgInfo.bankInfo.timestampBankConfirmed = timestampPreciseToDb(now); r.status = WithdrawalGroupStatus.FailedBankAborted; const newTxState = computeWithdrawalTransactionStatus(r); await tx.withdrawalGroups.put(r); @@ -2179,7 +2181,7 @@ async function processReserveBankStatus( if (status.transfer_done) { logger.info("withdrawal: transfer confirmed by bank."); const now = AbsoluteTime.toPreciseTimestamp(AbsoluteTime.now()); - r.wgInfo.bankInfo.timestampBankConfirmed = now; + r.wgInfo.bankInfo.timestampBankConfirmed = timestampPreciseToDb(now); r.status = WithdrawalGroupStatus.PendingQueryingStatus; } else { logger.info("withdrawal: transfer not yet confirmed by bank"); @@ -2285,7 +2287,7 @@ export async function internalPrepareCreateWithdrawalGroup( denomsSel: initialDenomSel, exchangeBaseUrl: canonExchange, instructedAmount: Amounts.stringify(amount), - timestampStart: now, + timestampStart: timestampPreciseToDb(now), rawWithdrawalAmount: initialDenomSel.totalWithdrawCost, effectiveWithdrawalAmount: initialDenomSel.totalCoinValue, secretSeed, @@ -2339,8 +2341,7 @@ export async function internalPerformCreateWithdrawalGroup( if (!prep.creationInfo) { return { withdrawalGroup, transitionInfo: undefined }; } - const { amount, canonExchange, exchangeDetails } = - prep.creationInfo; + const { amount, canonExchange, exchangeDetails } = prep.creationInfo; await tx.withdrawalGroups.add(withdrawalGroup); await tx.reserves.put({ @@ -2350,7 +2351,7 @@ export async function internalPerformCreateWithdrawalGroup( const exchange = await tx.exchanges.get(withdrawalGroup.exchangeBaseUrl); if (exchange) { - exchange.lastWithdrawal = TalerPreciseTimestamp.now(); + exchange.lastWithdrawal = timestampPreciseToDb(TalerPreciseTimestamp.now()); exchange.entryStatus = ExchangeEntryDbRecordStatus.Used; await tx.exchanges.put(exchange); } @@ -2541,11 +2542,7 @@ export async function createManualWithdrawal( }); const exchangePaytoUris = await ws.db - .mktx((x) => [ - x.withdrawalGroups, - x.exchanges, - x.exchangeDetails, - ]) + .mktx((x) => [x.withdrawalGroups, x.exchanges, x.exchangeDetails]) .runReadOnly(async (tx) => { return await getFundingPaytoUris(tx, withdrawalGroup.withdrawalGroupId); }); -- cgit v1.2.3