wallet-core: remove deprecated txid parsing

This commit is contained in:
Florian Dold 2023-05-24 14:09:25 +02:00
parent 4627c0781c
commit f14c7e5f2a
No known key found for this signature in database
GPG Key ID: D2E4F00F29D02A4B
6 changed files with 417 additions and 410 deletions

View File

@ -362,42 +362,6 @@ export enum TombstoneTag {
DeletePeerPushCredit = "delete-peer-push-credit",
}
/**
* Create an event ID from the type and the primary key for the event.
*
* @deprecated use constructTransactionIdentifier instead
*/
export function makeTransactionId(
type: TransactionType,
...args: string[]
): string {
return `txn:${type}:${args.map((x) => encodeURIComponent(x)).join(":")}`;
}
export function parseId(
idType: "txn" | "tmb" | "any",
txId: string,
): {
type: TransactionType;
args: string[];
} {
const txnParts = txId.split(":");
if (txnParts.length < 3) {
throw Error("id should have al least 3 parts separated by ':'");
}
const [prefix, typeStr, ...args] = txnParts;
const type = typeStr as TransactionType;
if (idType != "any" && prefix !== idType) {
throw Error(`id should start with ${idType}`);
}
if (args.length === 0) {
throw Error("id should have one or more arguments");
}
return { type, args };
}
/**
* Create an event ID from the type and the primary key for the event.

View File

@ -118,7 +118,6 @@ import {
TaskIdentifiers,
} from "../util/retries.js";
import {
makeTransactionId,
runLongpollAsync,
runOperationWithErrorReporting,
spendCoins,

View File

@ -59,7 +59,7 @@ import {
OperationAttemptResult,
OperationAttemptResultType,
} from "../util/retries.js";
import { makeCoinAvailable, makeTransactionId } from "./common.js";
import { makeCoinAvailable } from "./common.js";
import { updateExchangeFromUrl } from "./exchanges.js";
import {
getCandidateWithdrawalDenoms,

View File

@ -67,7 +67,6 @@ import {
PeerPushPaymentIncomingStatus,
PeerPullPaymentInitiationRecord,
RefundGroupRecord,
ContractTermsRecord,
} from "../db.js";
import { InternalWalletState } from "../internal-wallet-state.js";
import { PendingTaskType } from "../pending-types.js";
@ -76,8 +75,6 @@ import { checkDbInvariant, checkLogicInvariant } from "../util/invariants.js";
import { constructTaskIdentifier, TaskIdentifiers } from "../util/retries.js";
import {
makeTombstoneId,
makeTransactionId,
parseId,
resetOperationTimeout,
runOperationWithErrorReporting,
TombstoneTag,
@ -164,9 +161,15 @@ export async function getTransactionById(
ws: InternalWalletState,
req: TransactionByIdRequest,
): Promise<Transaction> {
const { type, args: rest } = parseId("txn", req.transactionId);
if (type === TransactionType.Withdrawal) {
const withdrawalGroupId = rest[0];
const parsedTx = parseTransactionIdentifier(req.transactionId);
if (!parsedTx) {
throw Error("invalid transaction ID");
}
switch (parsedTx.tag) {
case TransactionType.Withdrawal: {
const withdrawalGroupId = parsedTx.withdrawalGroupId;
return await ws.db
.mktx((x) => [
x.withdrawalGroups,
@ -205,8 +208,10 @@ export async function getTransactionById(
ort,
);
});
} else if (type === TransactionType.Payment) {
const proposalId = rest[0];
}
case TransactionType.Payment: {
const proposalId = parsedTx.proposalId;
return await ws.db
.mktx((x) => [
x.purchases,
@ -229,11 +234,15 @@ export async function getTransactionById(
payRetryRecord,
);
});
} else if (type === TransactionType.Refresh) {
const refreshGroupId = rest[0];
}
case TransactionType.Refresh: {
// FIXME: We should return info about the refresh here!
throw Error(`no tx for refresh`);
} else if (type === TransactionType.Tip) {
const tipId = rest[0];
}
case TransactionType.Tip: {
const tipId = parsedTx.walletTipId;
return await ws.db
.mktx((x) => [x.tips, x.operationRetries])
.runReadWrite(async (tx) => {
@ -245,8 +254,10 @@ export async function getTransactionById(
);
return buildTransactionForTip(tipRecord, retries);
});
} else if (type === TransactionType.Deposit) {
const depositGroupId = rest[0];
}
case TransactionType.Deposit: {
const depositGroupId = parsedTx.depositGroupId;
return await ws.db
.mktx((x) => [x.depositGroups, x.operationRetries])
.runReadWrite(async (tx) => {
@ -258,33 +269,42 @@ export async function getTransactionById(
);
return buildTransactionForDeposit(depositRecord, retries);
});
} else if (type === TransactionType.Refund) {
}
case TransactionType.Refund:
// FIXME!
throw Error("not implemented");
} else if (type === TransactionType.PeerPullDebit) {
const peerPullPaymentIncomingId = rest[0];
case TransactionType.PeerPullDebit: {
return await ws.db
.mktx((x) => [x.peerPullPaymentIncoming])
.runReadWrite(async (tx) => {
const debit = await tx.peerPullPaymentIncoming.get(
peerPullPaymentIncomingId,
parsedTx.peerPullPaymentIncomingId,
);
if (!debit) throw Error("not found");
return buildTransactionForPullPaymentDebit(debit);
});
} else if (type === TransactionType.PeerPushDebit) {
const pursePub = rest[0];
}
case TransactionType.PeerPushDebit: {
return await ws.db
.mktx((x) => [x.peerPushPaymentInitiations, x.contractTerms])
.runReadWrite(async (tx) => {
const debit = await tx.peerPushPaymentInitiations.get(pursePub);
const debit = await tx.peerPushPaymentInitiations.get(
parsedTx.pursePub,
);
if (!debit) throw Error("not found");
const ct = await tx.contractTerms.get(debit.contractTermsHash);
checkDbInvariant(!!ct);
return buildTransactionForPushPaymentDebit(debit, ct.contractTermsRaw);
return buildTransactionForPushPaymentDebit(
debit,
ct.contractTermsRaw,
);
});
} else if (type === TransactionType.PeerPushCredit) {
const peerPushPaymentIncomingId = rest[0];
}
case TransactionType.PeerPushCredit: {
const peerPushPaymentIncomingId = parsedTx.peerPushPaymentIncomingId;
return await ws.db
.mktx((x) => [
x.peerPushPaymentIncoming,
@ -320,8 +340,10 @@ export async function getTransactionById(
wgOrt,
);
});
} else if (type === TransactionType.PeerPullCredit) {
const pursePub = rest[0];
}
case TransactionType.PeerPullCredit: {
const pursePub = parsedTx.pursePub;
return await ws.db
.mktx((x) => [
x.peerPullPaymentInitiations,
@ -356,16 +378,9 @@ export async function getTransactionById(
wgOrt,
);
});
} else {
const unknownTxType: never = type;
throw Error(`can't retrieve a '${unknownTxType}' transaction`);
}
}
// FIXME: Just a marker helper for unknown states until DD37 is fully implemented.
const mkTxStateUnknown = () => ({
major: TransactionMajorState.Unknown,
});
}
function buildTransactionForPushPaymentDebit(
pi: PeerPushPaymentInitiationRecord,
@ -1293,7 +1308,13 @@ export function constructTransactionIdentifier(
export function parseTransactionIdentifier(
transactionId: string,
): ParsedTransactionIdentifier | undefined {
const { type, args: rest } = parseId("any", transactionId);
const txnParts = transactionId.split(":");
if (txnParts.length < 3) {
throw Error("id should have al least 3 parts separated by ':'");
}
const [prefix, type, ...rest] = txnParts;
switch (type) {
case TransactionType.Deposit:
@ -1489,10 +1510,15 @@ export async function deleteTransaction(
ws: InternalWalletState,
transactionId: string,
): Promise<void> {
const { type, args: rest } = parseId("txn", transactionId);
const parsedTx = parseTransactionIdentifier(transactionId);
if (type === TransactionType.PeerPushCredit) {
const peerPushPaymentIncomingId = rest[0];
if (!parsedTx) {
throw Error("invalid transaction ID");
}
switch (parsedTx.tag) {
case TransactionType.PeerPushCredit: {
const peerPushPaymentIncomingId = parsedTx.peerPushPaymentIncomingId;
await ws.db
.mktx((x) => [
x.withdrawalGroups,
@ -1514,18 +1540,24 @@ export async function deleteTransaction(
if (withdrawalGroupRecord) {
await tx.withdrawalGroups.delete(withdrawalGroupId);
await tx.tombstones.put({
id: TombstoneTag.DeleteWithdrawalGroup + ":" + withdrawalGroupId,
id:
TombstoneTag.DeleteWithdrawalGroup + ":" + withdrawalGroupId,
});
}
}
await tx.peerPushPaymentIncoming.delete(peerPushPaymentIncomingId);
await tx.tombstones.put({
id:
TombstoneTag.DeletePeerPushCredit + ":" + peerPushPaymentIncomingId,
TombstoneTag.DeletePeerPushCredit +
":" +
peerPushPaymentIncomingId,
});
});
} else if (type === TransactionType.PeerPullCredit) {
const pursePub = rest[0];
return;
}
case TransactionType.PeerPullCredit: {
const pursePub = parsedTx.pursePub;
await ws.db
.mktx((x) => [
x.withdrawalGroups,
@ -1545,7 +1577,8 @@ export async function deleteTransaction(
if (withdrawalGroupRecord) {
await tx.withdrawalGroups.delete(withdrawalGroupId);
await tx.tombstones.put({
id: TombstoneTag.DeleteWithdrawalGroup + ":" + withdrawalGroupId,
id:
TombstoneTag.DeleteWithdrawalGroup + ":" + withdrawalGroupId,
});
}
}
@ -1554,8 +1587,12 @@ export async function deleteTransaction(
id: TombstoneTag.DeletePeerPullCredit + ":" + pursePub,
});
});
} else if (type === TransactionType.Withdrawal) {
const withdrawalGroupId = rest[0];
return;
}
case TransactionType.Withdrawal: {
const withdrawalGroupId = parsedTx.withdrawalGroupId;
await ws.db
.mktx((x) => [x.withdrawalGroups, x.tombstones])
.runReadWrite(async (tx) => {
@ -1570,8 +1607,11 @@ export async function deleteTransaction(
return;
}
});
} else if (type === TransactionType.Payment) {
const proposalId = rest[0];
return;
}
case TransactionType.Payment: {
const proposalId = parsedTx.proposalId;
await ws.db
.mktx((x) => [x.purchases, x.tombstones])
.runReadWrite(async (tx) => {
@ -1587,8 +1627,11 @@ export async function deleteTransaction(
});
}
});
} else if (type === TransactionType.Refresh) {
const refreshGroupId = rest[0];
return;
}
case TransactionType.Refresh: {
const refreshGroupId = parsedTx.refreshGroupId;
await ws.db
.mktx((x) => [x.refreshGroups, x.tombstones])
.runReadWrite(async (tx) => {
@ -1600,8 +1643,12 @@ export async function deleteTransaction(
});
}
});
} else if (type === TransactionType.Tip) {
const tipId = rest[0];
return;
}
case TransactionType.Tip: {
const tipId = parsedTx.walletTipId;
await ws.db
.mktx((x) => [x.tips, x.tombstones])
.runReadWrite(async (tx) => {
@ -1613,8 +1660,11 @@ export async function deleteTransaction(
});
}
});
} else if (type === TransactionType.Deposit) {
const depositGroupId = rest[0];
return;
}
case TransactionType.Deposit: {
const depositGroupId = parsedTx.depositGroupId;
await ws.db
.mktx((x) => [x.depositGroups, x.tombstones])
.runReadWrite(async (tx) => {
@ -1626,28 +1676,17 @@ export async function deleteTransaction(
});
}
});
} else if (type === TransactionType.Refund) {
const proposalId = rest[0];
const executionTimeStr = rest[1];
await ws.db
.mktx((x) => [x.purchases, x.tombstones])
.runReadWrite(async (tx) => {
const purchase = await tx.purchases.get(proposalId);
if (purchase) {
// This should just influence the history view,
// but won't delete any actual refund information.
await tx.tombstones.put({
id: makeTombstoneId(
TombstoneTag.DeleteRefund,
proposalId,
executionTimeStr,
),
});
return;
}
});
} else if (type === TransactionType.PeerPullDebit) {
const peerPullPaymentIncomingId = rest[0];
case TransactionType.Refund: {
// FIXME: Implement!
return;
}
case TransactionType.PeerPullDebit: {
const peerPullPaymentIncomingId = parsedTx.peerPullPaymentIncomingId;
await ws.db
.mktx((x) => [x.peerPullPaymentIncoming, x.tombstones])
.runReadWrite(async (tx) => {
@ -1664,8 +1703,12 @@ export async function deleteTransaction(
});
}
});
} else if (type === TransactionType.PeerPushDebit) {
const pursePub = rest[0];
return;
}
case TransactionType.PeerPushDebit: {
const pursePub = parsedTx.pursePub;
await ws.db
.mktx((x) => [x.peerPushPaymentInitiations, x.tombstones])
.runReadWrite(async (tx) => {
@ -1677,9 +1720,8 @@ export async function deleteTransaction(
});
}
});
} else {
const unknownTxType: never = type;
throw Error(`can't delete a '${unknownTxType}' transaction`);
return;
}
}
}

View File

@ -118,7 +118,6 @@ import {
WALLET_BANK_INTEGRATION_PROTOCOL_VERSION,
WALLET_EXCHANGE_PROTOCOL_VERSION,
} from "../versions.js";
import { makeTransactionId } from "./common.js";
import {
getExchangeDetails,
getExchangePaytoUri,
@ -1456,10 +1455,10 @@ export async function processWithdrawalGroup(
if (numKycRequired > 0) {
if (kycInfo) {
const txId = makeTransactionId(
TransactionType.Withdrawal,
withdrawalGroup.withdrawalGroupId,
);
const txId = constructTransactionIdentifier({
tag: TransactionType.Withdrawal,
withdrawalGroupId: withdrawalGroup.withdrawalGroupId,
});
await checkWithdrawalKycStatus(
ws,
withdrawalGroup.exchangeBaseUrl,
@ -2050,12 +2049,13 @@ async function processReserveBankStatus(
r.wgInfo.bankInfo.timestampBankConfirmed = now;
r.status = WithdrawalGroupStatus.PendingQueryingStatus;
// FIXME: Notification is deprecated with DD37.
const transactionId = constructTransactionIdentifier({
tag: TransactionType.Withdrawal,
withdrawalGroupId: r.withdrawalGroupId,
});
ws.notify({
type: NotificationType.WithdrawalGroupBankConfirmed,
transactionId: makeTransactionId(
TransactionType.Withdrawal,
r.withdrawalGroupId,
),
transactionId,
});
} else {
logger.info("withdrawal: transfer not yet confirmed by bank");

View File

@ -159,6 +159,7 @@ describe("Withdraw CTA states", () => {
paytoUris: ["payto://"],
tosAccepted: true,
ageRestrictionOptions: [],
numCoins: 42,
},
);
@ -222,6 +223,7 @@ describe("Withdraw CTA states", () => {
paytoUris: ["payto://"],
tosAccepted: false,
ageRestrictionOptions: [],
numCoins: 42,
},
);