aboutsummaryrefslogtreecommitdiff
path: root/packages/taler-util/src
diff options
context:
space:
mode:
authorFlorian Dold <florian@dold.me>2023-05-26 12:19:32 +0200
committerFlorian Dold <florian@dold.me>2023-05-26 12:19:32 +0200
commitcd8f76db61f4a1ab1a8a8a4d29b2f3e863b59854 (patch)
tree423ed7c6fc42ec5e05f655eb093b3b4bdc885996 /packages/taler-util/src
parent557dcec30db6573c5d11ca26432008ac6621642e (diff)
downloadwallet-core-cd8f76db61f4a1ab1a8a8a4d29b2f3e863b59854.tar.xz
taler-util,wallet-core: implement TalerPreciseTimestamp
Fixes #7703
Diffstat (limited to 'packages/taler-util/src')
-rw-r--r--packages/taler-util/src/backup-types.ts36
-rw-r--r--packages/taler-util/src/time.ts58
-rw-r--r--packages/taler-util/src/transactions-types.ts4
3 files changed, 72 insertions, 26 deletions
diff --git a/packages/taler-util/src/backup-types.ts b/packages/taler-util/src/backup-types.ts
index f7bf5ef30..2bfe6b886 100644
--- a/packages/taler-util/src/backup-types.ts
+++ b/packages/taler-util/src/backup-types.ts
@@ -63,7 +63,7 @@
* Imports.
*/
import { DenominationPubKey, UnblindedSignature } from "./taler-types.js";
-import { TalerProtocolDuration, TalerProtocolTimestamp } from "./time.js";
+import { TalerProtocolDuration, TalerProtocolTimestamp, TalerPreciseTimestamp } from "./time.js";
export const BACKUP_TAG = "gnu-taler-wallet-backup-content" as const;
/**
@@ -148,7 +148,7 @@ export interface WalletBackupContentV1 {
* This timestamp should only be advanced if the content
* of the backup changes.
*/
- timestamp: TalerProtocolTimestamp;
+ timestamp: TalerPreciseTimestamp;
/**
* Per-exchange data sorted by exchange master public key.
@@ -274,14 +274,14 @@ export type BackupWgInfo =
*
* Set to undefined if that hasn't happened yet.
*/
- timestamp_reserve_info_posted?: TalerProtocolTimestamp;
+ timestamp_reserve_info_posted?: TalerPreciseTimestamp;
/**
* Time when the reserve was confirmed by the bank.
*
* Set to undefined if not confirmed yet.
*/
- timestamp_bank_confirmed?: TalerProtocolTimestamp;
+ timestamp_bank_confirmed?: TalerPreciseTimestamp;
}
| {
type: BackupWgType.PeerPullCredit;
@@ -315,9 +315,9 @@ export interface BackupWithdrawalGroup {
exchange_base_url: string;
- timestamp_created: TalerProtocolTimestamp;
+ timestamp_created: TalerPreciseTimestamp;
- timestamp_finish?: TalerProtocolTimestamp;
+ timestamp_finish?: TalerPreciseTimestamp;
operation_status: BackupOperationStatus;
@@ -473,9 +473,9 @@ export interface BackupRecoupGroup {
/**
* Timestamp when the recoup was started.
*/
- timestamp_created: TalerProtocolTimestamp;
+ timestamp_created: TalerPreciseTimestamp;
- timestamp_finish?: TalerProtocolTimestamp;
+ timestamp_finish?: TalerPreciseTimestamp;
finish_clock?: TalerProtocolTimestamp;
// FIXME: Use some enum here!
finish_is_failure?: boolean;
@@ -633,14 +633,14 @@ export interface BackupTip {
* Has the user accepted the tip? Only after the tip has been accepted coins
* withdrawn from the tip may be used.
*/
- timestamp_accepted: TalerProtocolTimestamp | undefined;
+ timestamp_accepted: TalerPreciseTimestamp | undefined;
/**
* When was the tip first scanned by the wallet?
*/
- timestamp_created: TalerProtocolTimestamp;
+ timestamp_created: TalerPreciseTimestamp;
- timestamp_finished?: TalerProtocolTimestamp;
+ timestamp_finished?: TalerPreciseTimestamp;
finish_is_failure?: boolean;
/**
@@ -765,9 +765,9 @@ export interface BackupRefreshGroup {
*/
old_coins: BackupRefreshOldCoin[];
- timestamp_created: TalerProtocolTimestamp;
+ timestamp_created: TalerPreciseTimestamp;
- timestamp_finish?: TalerProtocolTimestamp;
+ timestamp_finish?: TalerPreciseTimestamp;
finish_is_failure?: boolean;
}
@@ -940,7 +940,7 @@ export interface BackupPurchase {
* Timestamp of the first time that sending a payment to the merchant
* for this purchase was successful.
*/
- timestamp_first_successful_pay: TalerProtocolTimestamp | undefined;
+ timestamp_first_successful_pay: TalerPreciseTimestamp | undefined;
/**
* Signature by the merchant confirming the payment.
@@ -952,13 +952,13 @@ export interface BackupPurchase {
*/
pos_confirmation: string | undefined;
- timestamp_proposed: TalerProtocolTimestamp;
+ timestamp_proposed: TalerPreciseTimestamp;
/**
* When was the purchase made?
* Refers to the time that the user accepted.
*/
- timestamp_accepted: TalerProtocolTimestamp | undefined;
+ timestamp_accepted: TalerPreciseTimestamp | undefined;
/**
* Pending refunds for the purchase. A refund is pending
@@ -1186,7 +1186,7 @@ export interface BackupExchange {
*
* Used to facilitate automatic merging.
*/
- update_clock: TalerProtocolTimestamp;
+ update_clock: TalerPreciseTimestamp;
}
/**
@@ -1258,7 +1258,7 @@ export interface BackupExchangeDetails {
/**
* Timestamp when the ToS has been accepted.
*/
- tos_accepted_timestamp: TalerProtocolTimestamp | undefined;
+ tos_accepted_timestamp: TalerPreciseTimestamp | undefined;
}
export enum BackupProposalStatus {
diff --git a/packages/taler-util/src/time.ts b/packages/taler-util/src/time.ts
index 6ada13e25..697bde5c0 100644
--- a/packages/taler-util/src/time.ts
+++ b/packages/taler-util/src/time.ts
@@ -25,8 +25,9 @@ import { Codec, renderContext, Context } from "./codec.js";
declare const flavor_AbsoluteTime: unique symbol;
declare const flavor_TalerProtocolTimestamp: unique symbol;
-declare const flavor_TalerWalletDbTimestamp: unique symbol;
+declare const flavor_TalerPreciseTimestamp: unique symbol;
+// FIXME: Make this opaque!
export interface AbsoluteTime {
/**
* Timestamp in milliseconds.
@@ -45,7 +46,7 @@ export interface TalerProtocolTimestamp {
readonly _flavor?: typeof flavor_TalerProtocolTimestamp;
}
-export interface TalerWalletDbTimestamp {
+export interface TalerPreciseTimestamp {
/**
* Seconds (as integer) since epoch.
*/
@@ -56,12 +57,32 @@ export interface TalerWalletDbTimestamp {
*/
readonly off_us?: number;
- readonly _flavor?: typeof flavor_TalerWalletDbTimestamp;
+ readonly _flavor?: typeof flavor_TalerPreciseTimestamp;
+}
+
+export namespace TalerPreciseTimestamp {
+ export function now(): TalerPreciseTimestamp {
+ const absNow = AbsoluteTime.now();
+ return AbsoluteTime.toPreciseTimestamp(absNow);
+ }
+
+ export function round(t: TalerPreciseTimestamp): TalerProtocolTimestamp {
+ return {
+ t_s: t.t_s,
+ }
+ }
+
+ export function fromSeconds(s: number): TalerPreciseTimestamp {
+ return {
+ t_s: Math.floor(s),
+ off_us: (s - Math.floor(s)) / 1000 / 1000,
+ };
+ }
}
export namespace TalerProtocolTimestamp {
export function now(): TalerProtocolTimestamp {
- return AbsoluteTime.toTimestamp(AbsoluteTime.now());
+ return AbsoluteTime.toProtocolTimestamp(AbsoluteTime.now());
}
export function zero(): TalerProtocolTimestamp {
@@ -81,6 +102,7 @@ export namespace TalerProtocolTimestamp {
t_s: s,
};
}
+
export function min(
t1: TalerProtocolTimestamp,
t2: TalerProtocolTimestamp,
@@ -309,7 +331,7 @@ export namespace AbsoluteTime {
return cmp(t, now()) <= 0;
}
- export function fromTimestamp(t: TalerProtocolTimestamp): AbsoluteTime {
+ export function fromProtocolTimestamp(t: TalerProtocolTimestamp): AbsoluteTime {
if (t.t_s === "never") {
return { t_ms: "never" };
}
@@ -318,7 +340,31 @@ export namespace AbsoluteTime {
};
}
- export function toTimestamp(at: AbsoluteTime): TalerProtocolTimestamp {
+ export function fromPreciseTimestamp(t: TalerPreciseTimestamp): AbsoluteTime {
+ if (t.t_s === "never") {
+ return { t_ms: "never" };
+ }
+ const offsetUs = t.off_us ?? 0;
+ return {
+ t_ms: t.t_s * 1000 + offsetUs / 1000,
+ };
+ }
+
+ export function toPreciseTimestamp(at: AbsoluteTime): TalerPreciseTimestamp {
+ if (at.t_ms == "never") {
+ return {
+ t_s: "never",
+ };
+ }
+ const t_s = Math.floor(at.t_ms / 1000);
+ const off_us = Math.floor(1000 * (at.t_ms - t_s * 1000));
+ return {
+ t_s,
+ off_us,
+ }
+ }
+
+ export function toProtocolTimestamp(at: AbsoluteTime): TalerProtocolTimestamp {
if (at.t_ms === "never") {
return { t_s: "never" };
}
diff --git a/packages/taler-util/src/transactions-types.ts b/packages/taler-util/src/transactions-types.ts
index 03c894fe6..38cbea736 100644
--- a/packages/taler-util/src/transactions-types.ts
+++ b/packages/taler-util/src/transactions-types.ts
@@ -24,7 +24,7 @@
/**
* Imports.
*/
-import { TalerProtocolTimestamp } from "./time.js";
+import { TalerPreciseTimestamp, TalerProtocolTimestamp } from "./time.js";
import {
AmountString,
Product,
@@ -141,7 +141,7 @@ export interface TransactionCommon {
type: TransactionType;
// main timestamp of the transaction
- timestamp: TalerProtocolTimestamp;
+ timestamp: TalerPreciseTimestamp;
/**
* Transaction state, as per DD37.