also create key material for planchets in smaller bites

This commit is contained in:
Florian Dold 2020-05-11 20:43:19 +05:30
parent 0240096cf6
commit 4c614429a0
No known key found for this signature in database
GPG Key ID: D2E4F00F29D02A4B
5 changed files with 89 additions and 13 deletions

View File

@ -700,8 +700,7 @@ async function depleteReserve(
totalWithdrawCost: denomsForWithdraw.totalWithdrawCost,
selectedDenoms: denomsForWithdraw.selectedDenoms.map((x) => {
return {
countAllocated: x.count,
countPlanchetCreated: x.count,
count: x.count,
denomPubHash: x.denom.denomPubHash,
};
}),

View File

@ -112,8 +112,7 @@ export async function getTipStatus(
totalWithdrawCost: selectedDenoms.totalWithdrawCost,
selectedDenoms: selectedDenoms.selectedDenoms.map((x) => {
return {
countAllocated: x.count,
countPlanchetCreated: x.count,
count: x.count,
denomPubHash: x.denom.denomPubHash,
};
}),
@ -213,7 +212,7 @@ async function processTipImpl(
if (!denom) {
throw Error("denom does not exist anymore");
}
for (let i = 0; i < sd.countAllocated; i++) {
for (let i = 0; i < sd.count; i++) {
const r = await ws.cryptoApi.createTipPlanchet(denom);
planchets.push(r);
}

View File

@ -25,6 +25,8 @@ import {
updateRetryInfoTimeout,
CoinSourceType,
DenominationSelectionInfo,
PlanchetRecord,
WithdrawalSourceType,
} from "../types/dbTypes";
import {
BankWithdrawDetails,
@ -89,6 +91,7 @@ export function getWithdrawDenomList(
denoms.sort((d1, d2) => Amounts.cmp(d2.value, d1.value));
for (const d of denoms) {
console.log("considering denom", d);
let count = 0;
const cost = Amounts.add(d.value, d.feeWithdraw).amount;
for (;;) {
@ -191,6 +194,63 @@ async function processPlanchet(
coinIdx,
]);
if (!planchet) {
let ci = 0;
let denomPubHash: string | undefined;
for (let di = 0; di < withdrawalGroup.denomsSel.selectedDenoms.length; di++) {
const d = withdrawalGroup.denomsSel.selectedDenoms[di];
if (coinIdx >= ci && coinIdx < ci + d.count) {
denomPubHash = d.denomPubHash;
break;
}
ci += d.count;
}
if (!denomPubHash) {
throw Error("invariant violated");
}
const denom = await ws.db.getIndexed(Stores.denominations.denomPubHashIndex, denomPubHash);
if (!denom) {
throw Error("invariant violated");
}
if (withdrawalGroup.source.type != WithdrawalSourceType.Reserve) {
throw Error("invariant violated");
}
const reserve = await ws.db.get(Stores.reserves, withdrawalGroup.source.reservePub);
if (!reserve) {
throw Error("invariant violated");
}
const r = await ws.cryptoApi.createPlanchet({
denomPub: denom.denomPub,
feeWithdraw: denom.feeWithdraw,
reservePriv: reserve.reservePriv,
reservePub: reserve.reservePub,
value: denom.value,
});
const newPlanchet: PlanchetRecord = {
blindingKey: r.blindingKey,
coinEv: r.coinEv,
coinEvHash: r.coinEvHash,
coinIdx,
coinPriv: r.coinPriv,
coinPub: r.coinPub,
coinValue: r.coinValue,
denomPub: r.denomPub,
denomPubHash: r.denomPubHash,
isFromTip: false,
reservePub: r.reservePub,
withdrawalDone: false,
withdrawSig: r.withdrawSig,
withdrawalGroupId: withdrawalGroupId,
};
await ws.db.runWithWriteTransaction([Stores.planchets], async (tx) => {
const p = await tx.getIndexed(Stores.planchets.byGroupAndIndex, [
withdrawalGroupId,
coinIdx,
]);
if (p) {
return;
}
await tx.put(Stores.planchets, newPlanchet);
});
console.log("processPlanchet: planchet not found");
return;
}
@ -217,6 +277,8 @@ async function processPlanchet(
return;
}
logger.trace(`processing planchet #${coinIdx} in withdrawal ${withdrawalGroupId}`);
const wd: any = {};
wd.denom_pub_hash = planchet.denomPubHash;
wd.reserve_pub = planchet.reservePub;
@ -229,6 +291,8 @@ async function processPlanchet(
const resp = await ws.http.postJson(reqUrl, wd);
const r = await scrutinizeTalerJsonResponse(resp, codecForWithdrawResponse());
logger.trace(`got response for /withdraw`);
const denomSig = await ws.cryptoApi.rsaUnblind(
r.ev_sig,
planchet.blindingKey,
@ -240,10 +304,13 @@ async function processPlanchet(
denomSig,
planchet.denomPub,
);
if (!isValid) {
throw Error("invalid RSA signature by the exchange");
}
logger.trace(`unblinded and verified`);
const coin: CoinRecord = {
blindingKey: planchet.blindingKey,
coinPriv: planchet.coinPriv,
@ -283,15 +350,25 @@ async function processPlanchet(
p.withdrawalDone = true;
await tx.put(Stores.planchets, p);
let numNotDone = 0;
let numTotal = 0;
for (const ds of ws.denomsSel.selectedDenoms) {
numTotal += ds.count;
}
let numDone = 0;
await tx.iterIndexed(Stores.planchets.byGroup, withdrawalGroupId).forEach((x) => {
if (!x.withdrawalDone) {
numNotDone++;
if (x.withdrawalDone) {
numDone++;
}
});
if (numNotDone == 0) {
if (numDone > numTotal) {
throw Error("invariant violated (created more planchets than expected)");
}
if (numDone == numTotal) {
ws.timestampFinish = getTimestampNow();
ws.lastError = undefined;
ws.retryInfo = initRetryInfo(false);
@ -303,6 +380,8 @@ async function processPlanchet(
},
);
logger.trace(`withdrawal result stored in DB`);
if (success) {
ws.notify({
type: NotificationType.CoinWithdrawn,
@ -469,7 +548,7 @@ async function processWithdrawGroupImpl(
const genWork = function*(): Iterator<Promise<void>> {
let coinIdx = 0;
for (let i = 0; i < numDenoms; i++) {
const count = withdrawalGroup.denomsSel.selectedDenoms[i].countAllocated;
const count = withdrawalGroup.denomsSel.selectedDenoms[i].count;
for (let j = 0; j < count; j++) {
yield processPlanchet(ws, withdrawalGroupId, coinIdx);
coinIdx++;

View File

@ -1393,8 +1393,7 @@ export interface DenomSelectionState {
totalWithdrawCost: AmountJson;
selectedDenoms: {
denomPubHash: string;
countAllocated: number;
countPlanchetCreated: number;
count: number;
}[];
}

View File

@ -64,7 +64,7 @@ let outdatedDbVersion: number | undefined;
const walletInit: OpenedPromise<void> = openPromise<void>();
const extendedPermissions = {
permissions: ["webRequest", "webRequestBlocking", "tabs"],
permissions: ["webRequest", "webRequestBlocking"],
origins: ["http://*/*", "https://*/*"],
};