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,
|
ConfirmPayResultType,
|
||||||
ContractTerms,
|
ContractTerms,
|
||||||
} from "taler-wallet-core";
|
} from "taler-wallet-core";
|
||||||
import { FaultInjectedExchangeService, FaultInjectedMerchantService } from "./faultInjection";
|
import {
|
||||||
import { defaultCoinConfig } from "./denomStructures";
|
FaultInjectedExchangeService,
|
||||||
|
FaultInjectedMerchantService,
|
||||||
|
} from "./faultInjection";
|
||||||
|
import { CoinConfig, defaultCoinConfig } from "./denomStructures";
|
||||||
|
|
||||||
export interface SimpleTestEnvironment {
|
export interface SimpleTestEnvironment {
|
||||||
commonDb: DbInfo;
|
commonDb: DbInfo;
|
||||||
@ -63,6 +66,7 @@ export interface SimpleTestEnvironment {
|
|||||||
*/
|
*/
|
||||||
export async function createSimpleTestkudosEnvironment(
|
export async function createSimpleTestkudosEnvironment(
|
||||||
t: GlobalTestState,
|
t: GlobalTestState,
|
||||||
|
coinConfig: CoinConfig[] = defaultCoinConfig.map((x) => x("TESTKUDOS")),
|
||||||
): Promise<SimpleTestEnvironment> {
|
): Promise<SimpleTestEnvironment> {
|
||||||
const db = await setupDb(t);
|
const db = await setupDb(t);
|
||||||
|
|
||||||
@ -99,7 +103,7 @@ export async function createSimpleTestkudosEnvironment(
|
|||||||
|
|
||||||
await bank.pingUntilAvailable();
|
await bank.pingUntilAvailable();
|
||||||
|
|
||||||
exchange.addOfferedCoins(defaultCoinConfig);
|
exchange.addCoinConfigList(coinConfig);
|
||||||
|
|
||||||
await exchange.start();
|
await exchange.start();
|
||||||
await exchange.pingUntilAvailable();
|
await exchange.pingUntilAvailable();
|
||||||
@ -139,7 +143,7 @@ export interface FaultyMerchantTestEnvironment {
|
|||||||
commonDb: DbInfo;
|
commonDb: DbInfo;
|
||||||
bank: BankService;
|
bank: BankService;
|
||||||
exchange: ExchangeService;
|
exchange: ExchangeService;
|
||||||
faultyExchange: FaultInjectedExchangeService,
|
faultyExchange: FaultInjectedExchangeService;
|
||||||
exchangeBankAccount: ExchangeBankAccount;
|
exchangeBankAccount: ExchangeBankAccount;
|
||||||
merchant: MerchantService;
|
merchant: MerchantService;
|
||||||
faultyMerchant: FaultInjectedMerchantService;
|
faultyMerchant: FaultInjectedMerchantService;
|
||||||
@ -185,7 +189,10 @@ export async function createFaultInjectedMerchantTestkudosEnvironment(
|
|||||||
);
|
);
|
||||||
exchange.addBankAccount("1", exchangeBankAccount);
|
exchange.addBankAccount("1", exchangeBankAccount);
|
||||||
|
|
||||||
bank.setSuggestedExchange(faultyExchange, exchangeBankAccount.accountPaytoUri);
|
bank.setSuggestedExchange(
|
||||||
|
faultyExchange,
|
||||||
|
exchangeBankAccount.accountPaytoUri,
|
||||||
|
);
|
||||||
|
|
||||||
await bank.start();
|
await bank.start();
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
/**
|
/**
|
||||||
* Imports.
|
* Imports.
|
||||||
*/
|
*/
|
||||||
|
import { CoinConfig } from "./denomStructures";
|
||||||
import {
|
import {
|
||||||
GlobalTestState,
|
GlobalTestState,
|
||||||
ExchangeService,
|
ExchangeService,
|
||||||
@ -28,7 +29,6 @@ import {
|
|||||||
withdrawViaBank,
|
withdrawViaBank,
|
||||||
makeTestPayment,
|
makeTestPayment,
|
||||||
} from "./helpers";
|
} from "./helpers";
|
||||||
import { CoinDumpJson } from "taler-wallet-core";
|
|
||||||
|
|
||||||
async function revokeAllWalletCoins(req: {
|
async function revokeAllWalletCoins(req: {
|
||||||
wallet: WalletCli;
|
wallet: WalletCli;
|
||||||
@ -45,7 +45,9 @@ async function revokeAllWalletCoins(req: {
|
|||||||
for (const x of usedDenomHashes.values()) {
|
for (const x of usedDenomHashes.values()) {
|
||||||
await exchange.revokeDenomination(x);
|
await exchange.revokeDenomination(x);
|
||||||
}
|
}
|
||||||
|
await exchange.stop();
|
||||||
|
await exchange.start();
|
||||||
|
await exchange.pingUntilAvailable();
|
||||||
await exchange.keyup();
|
await exchange.keyup();
|
||||||
await exchange.pingUntilAvailable();
|
await exchange.pingUntilAvailable();
|
||||||
await merchant.stop();
|
await merchant.stop();
|
||||||
@ -59,12 +61,25 @@ async function revokeAllWalletCoins(req: {
|
|||||||
export async function runRevocationTest(t: GlobalTestState) {
|
export async function runRevocationTest(t: GlobalTestState) {
|
||||||
// Set up test environment
|
// 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 {
|
const {
|
||||||
wallet,
|
wallet,
|
||||||
bank,
|
bank,
|
||||||
exchange,
|
exchange,
|
||||||
merchant,
|
merchant,
|
||||||
} = await createSimpleTestkudosEnvironment(t);
|
} = await createSimpleTestkudosEnvironment(t, [coin_u1]);
|
||||||
|
|
||||||
// Withdraw digital cash into the wallet.
|
// Withdraw digital cash into the wallet.
|
||||||
|
|
||||||
|
@ -170,7 +170,7 @@ export async function runTests(spec: TestRunSpec) {
|
|||||||
testRootDir,
|
testRootDir,
|
||||||
};
|
};
|
||||||
|
|
||||||
currentChild = child_process.fork(__filename, {
|
currentChild = child_process.fork(__filename, ["__TWCLI_TESTWORKER"], {
|
||||||
env: {
|
env: {
|
||||||
TWCLI_RUN_TEST_INSTRUCTION: JSON.stringify(testInstr),
|
TWCLI_RUN_TEST_INSTRUCTION: JSON.stringify(testInstr),
|
||||||
...process.env,
|
...process.env,
|
||||||
@ -251,9 +251,9 @@ export function getTestInfo(): TestInfo[] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const runTestInstrStr = process.env["TWCLI_RUN_TEST_INSTRUCTION"];
|
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.
|
// 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(
|
const { testRootDir, testName } = JSON.parse(
|
||||||
runTestInstrStr,
|
runTestInstrStr,
|
||||||
) as RunTestChildInstruction;
|
) as RunTestChildInstruction;
|
||||||
|
@ -83,6 +83,9 @@ async function putGroupAsFinished(
|
|||||||
recoupGroup: RecoupGroupRecord,
|
recoupGroup: RecoupGroupRecord,
|
||||||
coinIdx: number,
|
coinIdx: number,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
|
logger.trace(
|
||||||
|
`setting coin ${coinIdx} of ${recoupGroup.coinPubs.length} as finished`,
|
||||||
|
);
|
||||||
if (recoupGroup.timestampFinished) {
|
if (recoupGroup.timestampFinished) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -94,6 +97,7 @@ async function putGroupAsFinished(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (allFinished) {
|
if (allFinished) {
|
||||||
|
logger.trace("all recoups of recoup group are finished");
|
||||||
recoupGroup.timestampFinished = getTimestampNow();
|
recoupGroup.timestampFinished = getTimestampNow();
|
||||||
recoupGroup.retryInfo = initRetryInfo(false);
|
recoupGroup.retryInfo = initRetryInfo(false);
|
||||||
recoupGroup.lastError = undefined;
|
recoupGroup.lastError = undefined;
|
||||||
@ -230,7 +234,7 @@ async function recoupRefreshCoin(
|
|||||||
|
|
||||||
const recoupRequest = await ws.cryptoApi.createRecoupRequest(coin);
|
const recoupRequest = await ws.cryptoApi.createRecoupRequest(coin);
|
||||||
const reqUrl = new URL(`/coins/${coin.coinPub}/recoup`, coin.exchangeBaseUrl);
|
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 resp = await ws.http.postJson(reqUrl.href, recoupRequest);
|
||||||
const recoupConfirmation = await readSuccessResponseJsonOrThrow(
|
const recoupConfirmation = await readSuccessResponseJsonOrThrow(
|
||||||
@ -244,12 +248,14 @@ async function recoupRefreshCoin(
|
|||||||
|
|
||||||
const exchange = await ws.db.get(Stores.exchanges, coin.exchangeBaseUrl);
|
const exchange = await ws.db.get(Stores.exchanges, coin.exchangeBaseUrl);
|
||||||
if (!exchange) {
|
if (!exchange) {
|
||||||
|
logger.warn("exchange for recoup does not exist anymore");
|
||||||
// FIXME: report inconsistency?
|
// FIXME: report inconsistency?
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const exchangeDetails = exchange.details;
|
const exchangeDetails = exchange.details;
|
||||||
if (!exchangeDetails) {
|
if (!exchangeDetails) {
|
||||||
// FIXME: report inconsistency?
|
// FIXME: report inconsistency?
|
||||||
|
logger.warn("exchange details for recoup not found");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -272,9 +278,11 @@ async function recoupRefreshCoin(
|
|||||||
const oldCoin = await tx.get(Stores.coins, cs.oldCoinPub);
|
const oldCoin = await tx.get(Stores.coins, cs.oldCoinPub);
|
||||||
const revokedCoin = await tx.get(Stores.coins, coin.coinPub);
|
const revokedCoin = await tx.get(Stores.coins, coin.coinPub);
|
||||||
if (!revokedCoin) {
|
if (!revokedCoin) {
|
||||||
|
logger.warn("revoked coin for recoup not found");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!oldCoin) {
|
if (!oldCoin) {
|
||||||
|
logger.warn("refresh old coin for recoup not found");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
revokedCoin.status = CoinStatus.Dormant;
|
revokedCoin.status = CoinStatus.Dormant;
|
||||||
|
@ -604,7 +604,22 @@ async function updateReserve(
|
|||||||
denoms,
|
denoms,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (denomSelInfo.selectedDenoms.length > 0) {
|
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);
|
||||||
|
await tx.put(Stores.reserves, newReserve);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let withdrawalGroupId: string;
|
let withdrawalGroupId: string;
|
||||||
|
|
||||||
if (!newReserve.initialWithdrawalStarted) {
|
if (!newReserve.initialWithdrawalStarted) {
|
||||||
@ -633,8 +648,6 @@ async function updateReserve(
|
|||||||
await tx.put(Stores.reserves, newReserve);
|
await tx.put(Stores.reserves, newReserve);
|
||||||
await tx.put(Stores.withdrawalGroups, withdrawalRecord);
|
await tx.put(Stores.withdrawalGroups, withdrawalRecord);
|
||||||
return withdrawalRecord;
|
return withdrawalRecord;
|
||||||
}
|
|
||||||
return;
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -645,8 +658,6 @@ async function updateReserve(
|
|||||||
withdrawalGroupId: newWithdrawalGroup.withdrawalGroupId,
|
withdrawalGroupId: newWithdrawalGroup.withdrawalGroupId,
|
||||||
});
|
});
|
||||||
await processWithdrawGroup(ws, newWithdrawalGroup.withdrawalGroupId);
|
await processWithdrawGroup(ws, newWithdrawalGroup.withdrawalGroupId);
|
||||||
} else {
|
|
||||||
console.trace("withdraw session already existed");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return { ready: true };
|
return { ready: true };
|
||||||
|
Loading…
Reference in New Issue
Block a user