also allow deleting individual refunds, tombstoned by their execution time

This commit is contained in:
Florian Dold 2021-05-20 19:03:49 +02:00
parent 9a861b80ef
commit bb10e038c9
No known key found for this signature in database
GPG Key ID: D2E4F00F29D02A4B

View File

@ -42,7 +42,10 @@ import { getFundingPaytoUris } from "./reserves";
/** /**
* Create an event ID from the type and the primary key for the event. * Create an event ID from the type and the primary key for the event.
*/ */
function makeEventId(type: TransactionType, ...args: string[]): string { function makeEventId(
type: TransactionType | TombstoneTag,
...args: string[]
): string {
return type + ":" + args.map((x) => encodeURIComponent(x)).join(":"); return type + ":" + args.map((x) => encodeURIComponent(x)).join(":");
} }
@ -95,6 +98,7 @@ export async function getTransactions(
Stores.planchets, Stores.planchets,
Stores.recoupGroups, Stores.recoupGroups,
Stores.depositGroups, Stores.depositGroups,
Stores.tombstones,
], ],
// Report withdrawals that are currently in progress. // Report withdrawals that are currently in progress.
async (tx) => { async (tx) => {
@ -282,7 +286,16 @@ export async function getTransactions(
refundGroupKeys.add(groupKey); refundGroupKeys.add(groupKey);
} }
refundGroupKeys.forEach((groupKey: string) => { for (const groupKey of refundGroupKeys.values()) {
const refundTombstoneId = makeEventId(
TombstoneTag.DeleteRefund,
pr.proposalId,
groupKey,
);
const tombstone = await tx.get(Stores.tombstones, refundTombstoneId);
if (tombstone) {
continue;
}
const refundTransactionId = makeEventId( const refundTransactionId = makeEventId(
TransactionType.Refund, TransactionType.Refund,
pr.proposalId, pr.proposalId,
@ -326,7 +339,7 @@ export async function getTransactions(
amountRaw: Amounts.stringify(amountRaw), amountRaw: Amounts.stringify(amountRaw),
pending: false, pending: false,
}); });
}); }
}); });
tx.iter(Stores.tips).forEachAsync(async (tipRecord) => { tx.iter(Stores.tips).forEachAsync(async (tipRecord) => {
@ -374,6 +387,7 @@ export enum TombstoneTag {
DeleteTip = "delete-tip", DeleteTip = "delete-tip",
DeleteRefreshGroup = "delete-refresh-group", DeleteRefreshGroup = "delete-refresh-group",
DeleteDepositGroup = "delete-deposit-group", DeleteDepositGroup = "delete-deposit-group",
DeleteRefund = "delete-refund",
} }
/** /**
@ -480,9 +494,26 @@ export async function deleteTransaction(
}, },
); );
} else if (type === TransactionType.Refund) { } else if (type === TransactionType.Refund) {
// To delete refund transactions, the whole const proposalId = rest[0];
// purchase should be deleted. const executionTimeStr = rest[1];
throw Error("refunds cannot be deleted");
await ws.db.runWithWriteTransaction(
[Stores.proposals, Stores.purchases, Stores.tombstones],
async (tx) => {
const purchase = await tx.get(Stores.purchases, proposalId);
if (purchase) {
// This should just influence the history view,
// but won't delete any actual refund information.
await tx.put(Stores.tombstones, {
id: makeEventId(
TombstoneTag.DeleteRefund,
proposalId,
executionTimeStr,
),
});
}
},
);
} else { } else {
throw Error(`can't delete a '${type}' transaction`); throw Error(`can't delete a '${type}' transaction`);
} }