fix reserve state machine bug, use simpler denominations in revocation test
This commit is contained in:
parent
657c4b6377
commit
6293de7bfa
@ -45,8 +45,11 @@ import {
|
||||
ConfirmPayResultType,
|
||||
ContractTerms,
|
||||
} from "taler-wallet-core";
|
||||
import { FaultInjectedExchangeService, FaultInjectedMerchantService } from "./faultInjection";
|
||||
import { defaultCoinConfig } from "./denomStructures";
|
||||
import {
|
||||
FaultInjectedExchangeService,
|
||||
FaultInjectedMerchantService,
|
||||
} from "./faultInjection";
|
||||
import { CoinConfig, defaultCoinConfig } from "./denomStructures";
|
||||
|
||||
export interface SimpleTestEnvironment {
|
||||
commonDb: DbInfo;
|
||||
@ -63,6 +66,7 @@ export interface SimpleTestEnvironment {
|
||||
*/
|
||||
export async function createSimpleTestkudosEnvironment(
|
||||
t: GlobalTestState,
|
||||
coinConfig: CoinConfig[] = defaultCoinConfig.map((x) => x("TESTKUDOS")),
|
||||
): Promise<SimpleTestEnvironment> {
|
||||
const db = await setupDb(t);
|
||||
|
||||
@ -99,7 +103,7 @@ export async function createSimpleTestkudosEnvironment(
|
||||
|
||||
await bank.pingUntilAvailable();
|
||||
|
||||
exchange.addOfferedCoins(defaultCoinConfig);
|
||||
exchange.addCoinConfigList(coinConfig);
|
||||
|
||||
await exchange.start();
|
||||
await exchange.pingUntilAvailable();
|
||||
@ -139,7 +143,7 @@ export interface FaultyMerchantTestEnvironment {
|
||||
commonDb: DbInfo;
|
||||
bank: BankService;
|
||||
exchange: ExchangeService;
|
||||
faultyExchange: FaultInjectedExchangeService,
|
||||
faultyExchange: FaultInjectedExchangeService;
|
||||
exchangeBankAccount: ExchangeBankAccount;
|
||||
merchant: MerchantService;
|
||||
faultyMerchant: FaultInjectedMerchantService;
|
||||
@ -185,7 +189,10 @@ export async function createFaultInjectedMerchantTestkudosEnvironment(
|
||||
);
|
||||
exchange.addBankAccount("1", exchangeBankAccount);
|
||||
|
||||
bank.setSuggestedExchange(faultyExchange, exchangeBankAccount.accountPaytoUri);
|
||||
bank.setSuggestedExchange(
|
||||
faultyExchange,
|
||||
exchangeBankAccount.accountPaytoUri,
|
||||
);
|
||||
|
||||
await bank.start();
|
||||
|
||||
|
@ -17,6 +17,7 @@
|
||||
/**
|
||||
* Imports.
|
||||
*/
|
||||
import { CoinConfig } from "./denomStructures";
|
||||
import {
|
||||
GlobalTestState,
|
||||
ExchangeService,
|
||||
@ -28,7 +29,6 @@ import {
|
||||
withdrawViaBank,
|
||||
makeTestPayment,
|
||||
} from "./helpers";
|
||||
import { CoinDumpJson } from "taler-wallet-core";
|
||||
|
||||
async function revokeAllWalletCoins(req: {
|
||||
wallet: WalletCli;
|
||||
@ -45,7 +45,9 @@ async function revokeAllWalletCoins(req: {
|
||||
for (const x of usedDenomHashes.values()) {
|
||||
await exchange.revokeDenomination(x);
|
||||
}
|
||||
|
||||
await exchange.stop();
|
||||
await exchange.start();
|
||||
await exchange.pingUntilAvailable();
|
||||
await exchange.keyup();
|
||||
await exchange.pingUntilAvailable();
|
||||
await merchant.stop();
|
||||
@ -59,12 +61,25 @@ async function revokeAllWalletCoins(req: {
|
||||
export async function runRevocationTest(t: GlobalTestState) {
|
||||
// Set up test environment
|
||||
|
||||
const coin_u1: CoinConfig = {
|
||||
durationLegal: "3 years",
|
||||
durationSpend: "2 years",
|
||||
durationWithdraw: "7 days",
|
||||
rsaKeySize: 1024,
|
||||
name: `$TESTKUDOS_u1`,
|
||||
value: `TESTKUDOS:1`,
|
||||
feeDeposit: `TESTKUDOS:0`,
|
||||
feeRefresh: `TESTKUDOS:0`,
|
||||
feeRefund: `TESTKUDOS:0`,
|
||||
feeWithdraw: `TESTKUDOS:0`,
|
||||
};
|
||||
|
||||
const {
|
||||
wallet,
|
||||
bank,
|
||||
exchange,
|
||||
merchant,
|
||||
} = await createSimpleTestkudosEnvironment(t);
|
||||
} = await createSimpleTestkudosEnvironment(t, [coin_u1]);
|
||||
|
||||
// Withdraw digital cash into the wallet.
|
||||
|
||||
|
@ -170,7 +170,7 @@ export async function runTests(spec: TestRunSpec) {
|
||||
testRootDir,
|
||||
};
|
||||
|
||||
currentChild = child_process.fork(__filename, {
|
||||
currentChild = child_process.fork(__filename, ["__TWCLI_TESTWORKER"], {
|
||||
env: {
|
||||
TWCLI_RUN_TEST_INSTRUCTION: JSON.stringify(testInstr),
|
||||
...process.env,
|
||||
@ -251,9 +251,9 @@ export function getTestInfo(): TestInfo[] {
|
||||
}
|
||||
|
||||
const runTestInstrStr = process.env["TWCLI_RUN_TEST_INSTRUCTION"];
|
||||
if (runTestInstrStr) {
|
||||
if (runTestInstrStr && process.argv.includes("__TWCLI_TESTWORKER")) {
|
||||
// Test will call taler-wallet-cli, so we must not propagate this variable.
|
||||
delete process.env["TWCLI_RUN_TEST_NAME"];
|
||||
delete process.env["TWCLI_RUN_TEST_INSTRUCTION"];
|
||||
const { testRootDir, testName } = JSON.parse(
|
||||
runTestInstrStr,
|
||||
) as RunTestChildInstruction;
|
||||
|
@ -83,6 +83,9 @@ async function putGroupAsFinished(
|
||||
recoupGroup: RecoupGroupRecord,
|
||||
coinIdx: number,
|
||||
): Promise<void> {
|
||||
logger.trace(
|
||||
`setting coin ${coinIdx} of ${recoupGroup.coinPubs.length} as finished`,
|
||||
);
|
||||
if (recoupGroup.timestampFinished) {
|
||||
return;
|
||||
}
|
||||
@ -94,6 +97,7 @@ async function putGroupAsFinished(
|
||||
}
|
||||
}
|
||||
if (allFinished) {
|
||||
logger.trace("all recoups of recoup group are finished");
|
||||
recoupGroup.timestampFinished = getTimestampNow();
|
||||
recoupGroup.retryInfo = initRetryInfo(false);
|
||||
recoupGroup.lastError = undefined;
|
||||
@ -230,7 +234,7 @@ async function recoupRefreshCoin(
|
||||
|
||||
const recoupRequest = await ws.cryptoApi.createRecoupRequest(coin);
|
||||
const reqUrl = new URL(`/coins/${coin.coinPub}/recoup`, coin.exchangeBaseUrl);
|
||||
logger.trace("making recoup request");
|
||||
logger.trace(`making recoup request for ${coin.coinPub}`);
|
||||
|
||||
const resp = await ws.http.postJson(reqUrl.href, recoupRequest);
|
||||
const recoupConfirmation = await readSuccessResponseJsonOrThrow(
|
||||
@ -244,12 +248,14 @@ async function recoupRefreshCoin(
|
||||
|
||||
const exchange = await ws.db.get(Stores.exchanges, coin.exchangeBaseUrl);
|
||||
if (!exchange) {
|
||||
logger.warn("exchange for recoup does not exist anymore");
|
||||
// FIXME: report inconsistency?
|
||||
return;
|
||||
}
|
||||
const exchangeDetails = exchange.details;
|
||||
if (!exchangeDetails) {
|
||||
// FIXME: report inconsistency?
|
||||
logger.warn("exchange details for recoup not found");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -272,9 +278,11 @@ async function recoupRefreshCoin(
|
||||
const oldCoin = await tx.get(Stores.coins, cs.oldCoinPub);
|
||||
const revokedCoin = await tx.get(Stores.coins, coin.coinPub);
|
||||
if (!revokedCoin) {
|
||||
logger.warn("revoked coin for recoup not found");
|
||||
return;
|
||||
}
|
||||
if (!oldCoin) {
|
||||
logger.warn("refresh old coin for recoup not found");
|
||||
return;
|
||||
}
|
||||
revokedCoin.status = CoinStatus.Dormant;
|
||||
|
@ -604,37 +604,50 @@ async function updateReserve(
|
||||
denoms,
|
||||
);
|
||||
|
||||
if (denomSelInfo.selectedDenoms.length > 0) {
|
||||
let withdrawalGroupId: string;
|
||||
|
||||
if (!newReserve.initialWithdrawalStarted) {
|
||||
withdrawalGroupId = newReserve.initialWithdrawalGroupId;
|
||||
newReserve.initialWithdrawalStarted = true;
|
||||
} else {
|
||||
withdrawalGroupId = encodeCrock(randomBytes(32));
|
||||
}
|
||||
|
||||
const withdrawalRecord: WithdrawalGroupRecord = {
|
||||
withdrawalGroupId: withdrawalGroupId,
|
||||
exchangeBaseUrl: reserve.exchangeBaseUrl,
|
||||
reservePub: reserve.reservePub,
|
||||
rawWithdrawalAmount: remainingAmount,
|
||||
timestampStart: getTimestampNow(),
|
||||
retryInfo: initRetryInfo(),
|
||||
lastError: undefined,
|
||||
denomsSel: denomSelectionInfoToState(denomSelInfo),
|
||||
secretSeed: encodeCrock(getRandomBytes(64)),
|
||||
};
|
||||
logger.trace(
|
||||
`Remaining unclaimed amount in reseve is ${Amounts.stringify(
|
||||
remainingAmount,
|
||||
)} and can be withdrawn with ${
|
||||
denomSelInfo.selectedDenoms.length
|
||||
} coins`,
|
||||
);
|
||||
|
||||
if (denomSelInfo.selectedDenoms.length === 0) {
|
||||
newReserve.reserveStatus = ReserveRecordStatus.DORMANT;
|
||||
newReserve.lastError = undefined;
|
||||
newReserve.retryInfo = initRetryInfo(false);
|
||||
newReserve.reserveStatus = ReserveRecordStatus.DORMANT;
|
||||
|
||||
await tx.put(Stores.reserves, newReserve);
|
||||
await tx.put(Stores.withdrawalGroups, withdrawalRecord);
|
||||
return withdrawalRecord;
|
||||
return;
|
||||
}
|
||||
return;
|
||||
|
||||
let withdrawalGroupId: string;
|
||||
|
||||
if (!newReserve.initialWithdrawalStarted) {
|
||||
withdrawalGroupId = newReserve.initialWithdrawalGroupId;
|
||||
newReserve.initialWithdrawalStarted = true;
|
||||
} else {
|
||||
withdrawalGroupId = encodeCrock(randomBytes(32));
|
||||
}
|
||||
|
||||
const withdrawalRecord: WithdrawalGroupRecord = {
|
||||
withdrawalGroupId: withdrawalGroupId,
|
||||
exchangeBaseUrl: reserve.exchangeBaseUrl,
|
||||
reservePub: reserve.reservePub,
|
||||
rawWithdrawalAmount: remainingAmount,
|
||||
timestampStart: getTimestampNow(),
|
||||
retryInfo: initRetryInfo(),
|
||||
lastError: undefined,
|
||||
denomsSel: denomSelectionInfoToState(denomSelInfo),
|
||||
secretSeed: encodeCrock(getRandomBytes(64)),
|
||||
};
|
||||
|
||||
newReserve.lastError = undefined;
|
||||
newReserve.retryInfo = initRetryInfo(false);
|
||||
newReserve.reserveStatus = ReserveRecordStatus.DORMANT;
|
||||
|
||||
await tx.put(Stores.reserves, newReserve);
|
||||
await tx.put(Stores.withdrawalGroups, withdrawalRecord);
|
||||
return withdrawalRecord;
|
||||
},
|
||||
);
|
||||
|
||||
@ -645,8 +658,6 @@ async function updateReserve(
|
||||
withdrawalGroupId: newWithdrawalGroup.withdrawalGroupId,
|
||||
});
|
||||
await processWithdrawGroup(ws, newWithdrawalGroup.withdrawalGroupId);
|
||||
} else {
|
||||
console.trace("withdraw session already existed");
|
||||
}
|
||||
|
||||
return { ready: true };
|
||||
|
Loading…
Reference in New Issue
Block a user