history WIP, DB naming

This commit is contained in:
Florian Dold 2019-12-16 16:20:45 +01:00
parent fa4621e70c
commit 35a7b76a7d
No known key found for this signature in database
GPG Key ID: D2E4F00F29D02A4B
15 changed files with 91 additions and 129 deletions

View File

@ -519,9 +519,9 @@ export class CryptoImplementation {
planchetsForGammas: planchetsForGammas,
transferPrivs,
transferPubs,
valueOutput,
valueWithFee,
created: getTimestampNow(),
amountRefreshOutput: valueOutput,
amountRefreshInput: valueWithFee,
timestampCreated: getTimestampNow(),
finishedTimestamp: undefined,
lastError: undefined,
};

View File

@ -87,7 +87,7 @@ export async function getBalances(
await tx.iter(Stores.refreshGroups).forEach(r => {
// Don't count finished refreshes, since the refresh already resulted
// in coins being added to the wallet.
if (r.finishedTimestamp) {
if (r.timestampFinished) {
return;
}
for (let i = 0; i < r.oldCoinPubs.length; i++) {
@ -96,13 +96,13 @@ export async function getBalances(
addTo(
balanceStore,
"pendingIncoming",
session.valueOutput,
session.amountRefreshOutput,
session.exchangeBaseUrl,
);
addTo(
balanceStore,
"pendingIncomingRefresh",
session.valueOutput,
session.amountRefreshOutput,
session.exchangeBaseUrl,
);
}
@ -128,7 +128,7 @@ export async function getBalances(
});
await tx.iter(Stores.purchases).forEach(t => {
if (t.firstSuccessfulPayTimestamp) {
if (t.timestampFirstSuccessfulPay) {
return;
}
for (const c of t.payReq.coins) {

View File

@ -431,6 +431,7 @@ async function updateExchangeFromUrlImpl(
termsOfServiceAcceptedTimestamp: undefined,
termsOfServiceLastEtag: undefined,
termsOfServiceText: undefined,
updateDiff: undefined,
};
await ws.db.put(Stores.exchanges, newExchangeRecord);
} else {

View File

@ -201,7 +201,7 @@ export async function getHistory(
});
tx.iter(Stores.withdrawalSession).forEach(wsr => {
if (wsr.finishTimestamp) {
if (wsr.timestampFinish) {
history.push({
type: HistoryEventType.Withdrawn,
withdrawSessionId: wsr.withdrawSessionId,
@ -212,7 +212,8 @@ export async function getHistory(
amountWithdrawnEffective: Amounts.toString(wsr.totalCoinValue),
amountWithdrawnRaw: Amounts.toString(wsr.rawWithdrawalAmount),
exchangeBaseUrl: wsr.exchangeBaseUrl,
timestamp: wsr.finishTimestamp,
timestamp: wsr.timestampFinish,
withdrawalSource: wsr.source,
});
}
});
@ -239,7 +240,7 @@ export async function getHistory(
});
await tx.iter(Stores.refreshGroups).forEachAsync(async (rg) => {
if (!rg.finishedTimestamp) {
if (!rg.timestampFinished) {
return;
}
let numInputCoins = 0;
@ -252,8 +253,8 @@ export async function getHistory(
numInputCoins++;
if (session) {
numRefreshedInputCoins++;
amountsRaw.push(session.valueWithFee);
amountsEffective.push(session.valueOutput);
amountsRaw.push(session.amountRefreshInput);
amountsEffective.push(session.amountRefreshOutput);
numOutputCoins += session.newDenoms.length;
} else {
const c = await tx.get(Stores.coins, rg.oldCoinPubs[i]);
@ -274,7 +275,7 @@ export async function getHistory(
type: HistoryEventType.Refreshed,
refreshGroupId: rg.refreshGroupId,
eventId: makeEventId(HistoryEventType.Refreshed, rg.refreshGroupId),
timestamp: rg.finishedTimestamp,
timestamp: rg.timestampFinished,
refreshReason: rg.reason,
amountRefreshedEffective: Amounts.toString(amountRefreshedEffective),
amountRefreshedRaw: Amounts.toString(amountRefreshedRaw),
@ -305,7 +306,7 @@ export async function getHistory(
eventId: makeEventId(HistoryEventType.ReserveBalanceUpdated, ru.reserveUpdateId),
amountExpected: ru.amountExpected,
amountReserveBalance: ru.amountReserveBalance,
timestamp: reserve.created,
timestamp: reserve.timestampCreated,
newHistoryTransactions: ru.newHistoryTransactions,
reserveShortInfo: {
exchangeBaseUrl: reserve.exchangeBaseUrl,

View File

@ -345,8 +345,8 @@ async function recordConfirmPay(
lastSessionId: sessionId,
merchantSig: d.merchantSig,
payReq,
acceptTimestamp: getTimestampNow(),
lastRefundStatusTimestamp: undefined,
timestampAccept: getTimestampNow(),
timestampLastRefundStatus: undefined,
proposalId: proposal.proposalId,
lastPayError: undefined,
lastRefundStatusError: undefined,
@ -355,7 +355,7 @@ async function recordConfirmPay(
refundStatusRequested: false,
lastRefundApplyError: undefined,
refundApplyRetryInfo: initRetryInfo(),
firstSuccessfulPayTimestamp: undefined,
timestampFirstSuccessfulPay: undefined,
autoRefundDeadline: undefined,
paymentSubmitPending: true,
refundState: {
@ -421,7 +421,7 @@ export async function abortFailedPayment(
if (!purchase) {
throw Error("Purchase not found, unable to abort with refund");
}
if (purchase.firstSuccessfulPayTimestamp) {
if (purchase.timestampFirstSuccessfulPay) {
throw Error("Purchase already finished, not aborting");
}
if (purchase.abortDone) {
@ -725,8 +725,8 @@ export async function submitPay(
// FIXME: properly display error
throw Error("merchant payment signature invalid");
}
const isFirst = purchase.firstSuccessfulPayTimestamp === undefined;
purchase.firstSuccessfulPayTimestamp = now;
const isFirst = purchase.timestampFirstSuccessfulPay === undefined;
purchase.timestampFirstSuccessfulPay = now;
purchase.paymentSubmitPending = false;
purchase.lastPayError = undefined;
purchase.payRetryInfo = initRetryInfo(false);

View File

@ -158,7 +158,7 @@ async function gatherReservePending(
type: PendingOperationType.Reserve,
givesLifeness: false,
stage: reserve.reserveStatus,
timestampCreated: reserve.created,
timestampCreated: reserve.timestampCreated,
reserveType,
reservePub: reserve.reservePub,
retryInfo: reserve.retryInfo,
@ -180,7 +180,7 @@ async function gatherReservePending(
type: PendingOperationType.Reserve,
givesLifeness: true,
stage: reserve.reserveStatus,
timestampCreated: reserve.created,
timestampCreated: reserve.timestampCreated,
reserveType,
reservePub: reserve.reservePub,
retryInfo: reserve.retryInfo,
@ -208,7 +208,7 @@ async function gatherRefreshPending(
onlyDue: boolean = false,
): Promise<void> {
await tx.iter(Stores.refreshGroups).forEach(r => {
if (r.finishedTimestamp) {
if (r.timestampFinished) {
return;
}
resp.nextRetryDelay = updateRetryDelay(
@ -235,7 +235,7 @@ async function gatherWithdrawalPending(
onlyDue: boolean = false,
): Promise<void> {
await tx.iter(Stores.withdrawalSession).forEach(wsr => {
if (wsr.finishTimestamp) {
if (wsr.timestampFinish) {
return;
}
resp.nextRetryDelay = updateRetryDelay(

View File

@ -168,7 +168,7 @@ async function refreshCreateSession(
if (!c) {
throw Error("coin not found, but marked for refresh");
}
const r = Amounts.sub(c.currentAmount, refreshSession.valueWithFee);
const r = Amounts.sub(c.currentAmount, refreshSession.amountRefreshInput);
if (r.saturated) {
console.log("can't refresh coin, no amount left");
return;
@ -224,7 +224,7 @@ async function refreshMelt(
denom_pub_hash: coin.denomPubHash,
denom_sig: coin.denomSig,
rc: refreshSession.hash,
value_with_fee: refreshSession.valueWithFee,
value_with_fee: refreshSession.amountRefreshInput,
};
logger.trace("melt request:", meltReq);
const resp = await ws.http.postJson(reqUrl.href, meltReq);
@ -414,7 +414,7 @@ async function refreshReveal(
}
}
if (allDone) {
rg.finishedTimestamp = getTimestampNow();
rg.timestampFinished = getTimestampNow();
rg.retryInfo = initRetryInfo(false);
}
for (let coin of coins) {
@ -489,7 +489,7 @@ async function processRefreshGroupImpl(
if (!refreshGroup) {
return;
}
if (refreshGroup.finishedTimestamp) {
if (refreshGroup.timestampFinished) {
return;
}
const ps = refreshGroup.oldCoinPubs.map((x, i) =>
@ -545,7 +545,7 @@ export async function createRefreshGroup(
const refreshGroupId = encodeCrock(getRandomBytes(32));
const refreshGroup: RefreshGroupRecord = {
finishedTimestamp: undefined,
timestampFinished: undefined,
finishedPerCoin: oldCoinPubs.map(x => false),
lastError: undefined,
lastErrorPerCoin: {},

View File

@ -194,14 +194,14 @@ export async function acceptRefundResponse(
}
if (queryDone) {
p.lastRefundStatusTimestamp = getTimestampNow();
p.timestampLastRefundStatus = getTimestampNow();
p.lastRefundStatusError = undefined;
p.refundStatusRetryInfo = initRetryInfo();
p.refundStatusRequested = false;
console.log("refund query done");
} else {
// No error, but we need to try again!
p.lastRefundStatusTimestamp = getTimestampNow();
p.timestampLastRefundStatus = getTimestampNow();
p.refundStatusRetryInfo.retryCounter++;
updateRetryInfoTimeout(p.refundStatusRetryInfo);
p.lastRefundStatusError = undefined;

View File

@ -77,13 +77,13 @@ export async function createReserve(
const currency = req.amount.currency;
const reserveRecord: ReserveRecord = {
created: now,
withdrawAllocatedAmount: Amounts.getZero(currency),
withdrawCompletedAmount: Amounts.getZero(currency),
withdrawRemainingAmount: Amounts.getZero(currency),
timestampCreated: now,
amountWithdrawAllocated: Amounts.getZero(currency),
amountWithdrawCompleted: Amounts.getZero(currency),
amountWithdrawRemaining: Amounts.getZero(currency),
exchangeBaseUrl: canonExchange,
hasPayback: false,
initiallyRequestedAmount: req.amount,
amountInitiallyRequested: req.amount,
reservePriv: keypair.priv,
reservePub: keypair.pub,
senderWire: req.senderWire,
@ -414,20 +414,20 @@ async function updateReserve(
// FIXME: check / compare history!
if (!r.lastSuccessfulStatusQuery) {
// FIXME: check if this matches initial expectations
r.withdrawRemainingAmount = balance;
r.amountWithdrawRemaining = balance;
const reserveUpdate: ReserveUpdatedEventRecord = {
reservePub: r.reservePub,
timestamp: getTimestampNow(),
amountReserveBalance: Amounts.toString(balance),
amountExpected: Amounts.toString(reserve.initiallyRequestedAmount),
amountExpected: Amounts.toString(reserve.amountInitiallyRequested),
newHistoryTransactions,
reserveUpdateId,
};
await tx.put(Stores.reserveUpdatedEvents, reserveUpdate);
} else {
const expectedBalance = Amounts.sub(
r.withdrawAllocatedAmount,
r.withdrawCompletedAmount,
r.amountWithdrawAllocated,
r.amountWithdrawCompleted,
);
const cmp = Amounts.cmp(balance, expectedBalance.amount);
if (cmp == 0) {
@ -436,8 +436,8 @@ async function updateReserve(
}
if (cmp > 0) {
const extra = Amounts.sub(balance, expectedBalance.amount).amount;
r.withdrawRemainingAmount = Amounts.add(
r.withdrawRemainingAmount,
r.amountWithdrawRemaining = Amounts.add(
r.amountWithdrawRemaining,
extra,
).amount;
} else {
@ -549,7 +549,7 @@ async function depleteReserve(
}
logger.trace(`depleting reserve ${reservePub}`);
const withdrawAmount = reserve.withdrawRemainingAmount;
const withdrawAmount = reserve.amountWithdrawRemaining;
logger.trace(`getting denom list`);
@ -585,7 +585,7 @@ async function depleteReserve(
reservePub: reserve.reservePub,
},
rawWithdrawalAmount: withdrawAmount,
startTimestamp: getTimestampNow(),
timestampStart: getTimestampNow(),
denoms: denomsForWithdraw.map(x => x.denomPub),
withdrawn: denomsForWithdraw.map(x => false),
planchets: denomsForWithdraw.map(x => undefined),
@ -603,7 +603,7 @@ async function depleteReserve(
function mutateReserve(r: ReserveRecord): ReserveRecord {
const remaining = Amounts.sub(
r.withdrawRemainingAmount,
r.amountWithdrawRemaining,
totalWithdrawAmount,
);
if (remaining.saturated) {
@ -611,15 +611,15 @@ async function depleteReserve(
throw TransactionAbort;
}
const allocated = Amounts.add(
r.withdrawAllocatedAmount,
r.amountWithdrawAllocated,
totalWithdrawAmount,
);
if (allocated.saturated) {
console.error("can't create planchets, saturated");
throw TransactionAbort;
}
r.withdrawRemainingAmount = remaining.amount;
r.withdrawAllocatedAmount = allocated.amount;
r.amountWithdrawRemaining = remaining.amount;
r.amountWithdrawAllocated = allocated.amount;
r.reserveStatus = ReserveRecordStatus.DORMANT;
r.retryInfo = initRetryInfo(false);
return r;

View File

@ -255,14 +255,14 @@ async function processTipImpl(
type: "tip",
tipId: tipRecord.tipId,
},
startTimestamp: getTimestampNow(),
timestampStart: getTimestampNow(),
withdrawSessionId: withdrawalSessionId,
rawWithdrawalAmount: tipRecord.amount,
withdrawn: planchets.map((x) => false),
totalCoinValue: Amounts.sum(planchets.map((p) => p.coinValue)).amount,
lastErrorPerCoin: {},
retryInfo: initRetryInfo(),
finishTimestamp: undefined,
timestampFinish: undefined,
lastError: undefined,
};

View File

@ -280,7 +280,7 @@ async function processPlanchet(
}
}
if (numDone === ws.denoms.length) {
ws.finishTimestamp = getTimestampNow();
ws.timestampFinish = getTimestampNow();
ws.lastError = undefined;
ws.retryInfo = initRetryInfo(false);
withdrawSessionFinished = true;
@ -289,11 +289,11 @@ async function processPlanchet(
if (!planchet.isFromTip) {
const r = await tx.get(Stores.reserves, planchet.reservePub);
if (r) {
r.withdrawCompletedAmount = Amounts.add(
r.withdrawCompletedAmount,
r.amountWithdrawCompleted = Amounts.add(
r.amountWithdrawCompleted,
Amounts.add(denom.value, denom.feeWithdraw).amount,
).amount;
if (Amounts.cmp(r.withdrawCompletedAmount, r.withdrawAllocatedAmount) == 0) {
if (Amounts.cmp(r.amountWithdrawCompleted, r.amountWithdrawAllocated) == 0) {
reserveDepleted = true;
}
await tx.put(Stores.reserves, r);

View File

@ -154,7 +154,7 @@ export interface ReserveRecord {
/**
* Time when the reserve was created.
*/
created: Timestamp;
timestampCreated: Timestamp;
/**
* Time when the information about this reserve was posted to the bank.
@ -176,23 +176,23 @@ export interface ReserveRecord {
* Amount that's still available for withdrawing
* from this reserve.
*/
withdrawRemainingAmount: AmountJson;
amountWithdrawRemaining: AmountJson;
/**
* Amount allocated for withdrawing.
* The corresponding withdraw operation may or may not
* have been completed yet.
*/
withdrawAllocatedAmount: AmountJson;
amountWithdrawAllocated: AmountJson;
withdrawCompletedAmount: AmountJson;
amountWithdrawCompleted: AmountJson;
/**
* Amount requested when the reserve was created.
* When a reserve is re-used (rare!) the current_amount can
* be higher than the requested_amount
*/
initiallyRequestedAmount: AmountJson;
amountInitiallyRequested: AmountJson;
/**
* We got some payback to this reserve. We'll cease to automatically
@ -469,6 +469,13 @@ export interface ExchangeWireInfo {
accounts: ExchangeBankAccount[];
}
/**
* Summary of updates to the exchange.
*/
export interface ExchangeUpdateDiff {
// FIXME: implement!
}
export const enum ExchangeUpdateReason {
Initial = "initial",
Forced = "forced",
@ -529,9 +536,16 @@ export interface ExchangeRecord {
* undefined if no update is in progress.
*/
updateStarted: Timestamp | undefined;
updateStatus: ExchangeUpdateStatus;
updateReason?: ExchangeUpdateReason;
/**
* Update diff, will be incorporated when the update is finalized.
*/
updateDiff: ExchangeUpdateDiff | undefined;
lastError?: OperationError;
}
@ -898,7 +912,7 @@ export interface RefreshGroupRecord {
/**
* Timestamp when the refresh session finished.
*/
finishedTimestamp: Timestamp | undefined;
timestampFinished: Timestamp | undefined;
}
/**
@ -916,13 +930,13 @@ export interface RefreshSessionRecord {
* How much of the coin's value is melted away
* with this refresh session?
*/
valueWithFee: AmountJson;
amountRefreshInput: AmountJson;
/**
* Sum of the value of denominations we want
* to withdraw in this session, without fees.
*/
valueOutput: AmountJson;
amountRefreshOutput: AmountJson;
/**
* Signature to confirm the melting.
@ -972,7 +986,7 @@ export interface RefreshSessionRecord {
/**
* When has this refresh session been created?
*/
created: Timestamp;
timestampCreated: Timestamp;
/**
* Base URL for the exchange we're doing the refresh with.
@ -1142,13 +1156,13 @@ export interface PurchaseRecord {
* Timestamp of the first time that sending a payment to the merchant
* for this purchase was successful.
*/
firstSuccessfulPayTimestamp: Timestamp | undefined;
timestampFirstSuccessfulPay: Timestamp | undefined;
/**
* When was the purchase made?
* Refers to the time that the user accepted.
*/
acceptTimestamp: Timestamp;
timestampAccept: Timestamp;
/**
* State of refunds for this proposal.
@ -1159,7 +1173,7 @@ export interface PurchaseRecord {
* When was the last refund made?
* Set to 0 if no refund was made on the purchase.
*/
lastRefundStatusTimestamp: Timestamp | undefined;
timestampLastRefundStatus: Timestamp | undefined;
/**
* Last session signature that we submitted to /pay (if any).
@ -1302,12 +1316,12 @@ export interface WithdrawalSessionRecord {
* When was the withdrawal operation started started?
* Timestamp in milliseconds.
*/
startTimestamp: Timestamp;
timestampStart: Timestamp;
/**
* When was the withdrawal operation completed?
*/
finishTimestamp?: Timestamp;
timestampFinish?: Timestamp;
totalCoinValue: AmountJson;

View File

@ -1,5 +1,6 @@
import { Timestamp, RefreshReason } from "./walletTypes";
import { ReserveTransaction } from "./ReserveTransaction";
import { WithdrawalSource } from "./dbTypes";
/*
This file is part of GNU Taler
@ -45,8 +46,6 @@ export const enum HistoryEventType {
Refreshed = "refreshed",
Refund = "refund",
ReserveBalanceUpdated = "reserve-balance-updated",
ReserveWithdrawAllocated = "reserve-withdraw-allocated",
ReserveConfirmed = "reserve-confirmed",
ReserveCreated = "reserve-created",
TipAccepted = "tip-accepted",
TipDeclined = "tip-declined",
@ -104,31 +103,6 @@ export interface HistoryReserveCreatedEvent {
reserveShortInfo: ReserveShortInfo;
}
/**
* The user (or some application / test case) or the bank has confirmed that the
* reserve will indeed become available after a while, because the
* funds are in the process of being transfered to the exchange.
*/
export interface HistoryReserveConfirmeEvent {
type: HistoryEventType.ReserveConfirmed;
/**
* Point in time when the reserve was confirmed.
*/
timestamp: Timestamp;
/**
* Amount that the should appear in the reserve once its status
* is requested from the exchange.
*/
expectedAmount: string;
/**
* Condensed information about the reserve.
*/
reserveShortInfo: ReserveShortInfo;
}
/**
* This event is emitted every time we ask the exchange for the status
* of the reserve, and the status has changed.
@ -160,35 +134,6 @@ export interface HistoryReserveBalanceUpdatedEvent {
amountExpected: string;
}
/**
* This event is emitted every time we ask the exchange for the status
* of the reserve, and the status has changed.
*/
export interface HistoryReserveWithdrawAllocatedEvent {
type: HistoryEventType.ReserveWithdrawAllocated;
/**
* Point in time when the reserve was confirmed.
*/
timestamp: Timestamp;
/**
* Unique identifier to query more information about the withdrawal.
*/
withdrawalSessionId: string;
/**
* Condensed information about the reserve.
*/
reserveShortInfo: ReserveShortInfo;
/**
* Amount that has been allocated for withdrawal from
* this reserve.
*/
amountWithdrawAllocated: string;
}
/**
* History event to indicate that the user has accepted a tip.
*/
@ -549,7 +494,7 @@ export interface HistoryPaymentSent {
/**
* A refund has been applied.
*/
export interface HistoryRefund {
export interface HistoryRefunded {
/**
* Type tag.
*/
@ -635,6 +580,8 @@ export interface HistoryWithdrawnEvent {
*/
withdrawSessionId: string;
withdrawalSource: WithdrawalSource;
/**
* Amount that has been subtracted from the reserve's balance
* for this withdrawal.
@ -689,9 +636,8 @@ export type HistoryEvent = HistoryEventBase &
| HistoryPaymentAbortedEvent
| HistoryPaymentSent
| HistoryRefreshedEvent
| HistoryRefund
| HistoryRefunded
| HistoryReserveBalanceUpdatedEvent
| HistoryReserveConfirmeEvent
| HistoryReserveCreatedEvent
| HistoryTipAcceptedEvent
| HistoryTipDeclinedEvent

View File

@ -724,7 +724,7 @@ export class Wallet {
const totalFees = totalRefundFees;
return {
contractTerms: purchase.contractTerms,
hasRefund: purchase.lastRefundStatusTimestamp !== undefined,
hasRefund: purchase.timestampLastRefundStatus !== undefined,
totalRefundAmount: totalRefundAmount,
totalRefundAndRefreshFees: totalFees,
};

View File

@ -57,7 +57,7 @@ function Payback() {
<div>
{reserves.map(r => (
<div>
<h2>Reserve for ${renderAmount(r.withdrawRemainingAmount)}</h2>
<h2>Reserve for ${renderAmount(r.amountWithdrawRemaining)}</h2>
<ul>
<li>Exchange: ${r.exchangeBaseUrl}</li>
</ul>