wallet-core: compute residual amount for recoup properly
This commit is contained in:
parent
87bc4a6fcd
commit
fe011321a4
@ -534,6 +534,8 @@ export interface BackupRefreshCoinSource {
|
|||||||
* Public key of the coin that was refreshed into this coin.
|
* Public key of the coin that was refreshed into this coin.
|
||||||
*/
|
*/
|
||||||
old_coin_pub: string;
|
old_coin_pub: string;
|
||||||
|
|
||||||
|
refresh_group_id: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -181,6 +181,7 @@ export async function runRevocationTest(t: GlobalTestState) {
|
|||||||
await makeTestPayment(t, { wallet, merchant, order });
|
await makeTestPayment(t, { wallet, merchant, order });
|
||||||
|
|
||||||
wallet.deleteDatabase();
|
wallet.deleteDatabase();
|
||||||
|
|
||||||
await withdrawViaBank(t, { wallet, bank, exchange, amount: "TESTKUDOS:15" });
|
await withdrawViaBank(t, { wallet, bank, exchange, amount: "TESTKUDOS:15" });
|
||||||
|
|
||||||
const coinDump = await wallet.client.call(WalletApiOperation.DumpCoins, {});
|
const coinDump = await wallet.client.call(WalletApiOperation.DumpCoins, {});
|
||||||
|
@ -640,6 +640,7 @@ export interface WithdrawCoinSource {
|
|||||||
|
|
||||||
export interface RefreshCoinSource {
|
export interface RefreshCoinSource {
|
||||||
type: CoinSourceType.Refresh;
|
type: CoinSourceType.Refresh;
|
||||||
|
refreshGroupId: string;
|
||||||
oldCoinPub: string;
|
oldCoinPub: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -240,6 +240,7 @@ export async function exportBackup(
|
|||||||
bcs = {
|
bcs = {
|
||||||
type: BackupCoinSourceType.Refresh,
|
type: BackupCoinSourceType.Refresh,
|
||||||
old_coin_pub: coin.coinSource.oldCoinPub,
|
old_coin_pub: coin.coinSource.oldCoinPub,
|
||||||
|
refresh_group_id: coin.coinSource.refreshGroupId,
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
case CoinSourceType.Tip:
|
case CoinSourceType.Tip:
|
||||||
|
@ -250,6 +250,7 @@ export async function importCoin(
|
|||||||
coinSource = {
|
coinSource = {
|
||||||
type: CoinSourceType.Refresh,
|
type: CoinSourceType.Refresh,
|
||||||
oldCoinPub: backupCoin.coin_source.old_coin_pub,
|
oldCoinPub: backupCoin.coin_source.old_coin_pub,
|
||||||
|
refreshGroupId: backupCoin.coin_source.refresh_group_id,
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
case BackupCoinSourceType.Tip:
|
case BackupCoinSourceType.Tip:
|
||||||
|
@ -279,11 +279,21 @@ async function recoupRefreshCoin(
|
|||||||
checkDbInvariant(!!oldCoinDenom);
|
checkDbInvariant(!!oldCoinDenom);
|
||||||
checkDbInvariant(!!revokedCoinDenom);
|
checkDbInvariant(!!revokedCoinDenom);
|
||||||
revokedCoin.status = CoinStatus.Dormant;
|
revokedCoin.status = CoinStatus.Dormant;
|
||||||
recoupGroup.scheduleRefreshCoins.push({
|
if (!revokedCoin.spendAllocation) {
|
||||||
coinPub: oldCoin.coinPub,
|
// We don't know what happened to this coin
|
||||||
//amount: Amounts.sub(oldCoinDenom.value, revokedCoinDenom.value).amount,
|
logger.error(
|
||||||
amount: revokedCoinDenom.value,
|
`can't refresh-recoup coin ${revokedCoin.coinPub}, no spendAllocation known`,
|
||||||
});
|
);
|
||||||
|
} else {
|
||||||
|
let residualAmount = Amounts.sub(
|
||||||
|
revokedCoinDenom.value,
|
||||||
|
revokedCoin.spendAllocation.amount,
|
||||||
|
).amount;
|
||||||
|
recoupGroup.scheduleRefreshCoins.push({
|
||||||
|
coinPub: oldCoin.coinPub,
|
||||||
|
amount: residualAmount,
|
||||||
|
});
|
||||||
|
}
|
||||||
await tx.coins.put(revokedCoin);
|
await tx.coins.put(revokedCoin);
|
||||||
await tx.coins.put(oldCoin);
|
await tx.coins.put(oldCoin);
|
||||||
await putGroupAsFinished(ws, tx, recoupGroup, coinIdx);
|
await putGroupAsFinished(ws, tx, recoupGroup, coinIdx);
|
||||||
|
@ -687,6 +687,7 @@ async function refreshReveal(
|
|||||||
status: CoinStatus.Fresh,
|
status: CoinStatus.Fresh,
|
||||||
coinSource: {
|
coinSource: {
|
||||||
type: CoinSourceType.Refresh,
|
type: CoinSourceType.Refresh,
|
||||||
|
refreshGroupId,
|
||||||
oldCoinPub: refreshGroup.oldCoinPubs[coinIndex],
|
oldCoinPub: refreshGroup.oldCoinPubs[coinIndex],
|
||||||
},
|
},
|
||||||
coinEvHash: pc.coinEvHash,
|
coinEvHash: pc.coinEvHash,
|
||||||
@ -838,10 +839,6 @@ async function processRefreshSession(
|
|||||||
* Refreshes the remaining amount on the coin, effectively capturing the remaining
|
* Refreshes the remaining amount on the coin, effectively capturing the remaining
|
||||||
* value in the refresh group.
|
* value in the refresh group.
|
||||||
*
|
*
|
||||||
* The caller must ensure that
|
|
||||||
* the remaining amount was updated correctly before the coin was deposited or
|
|
||||||
* credited.
|
|
||||||
*
|
|
||||||
* The caller must also ensure that the coins that should be refreshed exist
|
* The caller must also ensure that the coins that should be refreshed exist
|
||||||
* in the current database transaction.
|
* in the current database transaction.
|
||||||
*/
|
*/
|
||||||
@ -893,6 +890,10 @@ export async function createRefreshGroup(
|
|||||||
);
|
);
|
||||||
switch (coin.status) {
|
switch (coin.status) {
|
||||||
case CoinStatus.Dormant:
|
case CoinStatus.Dormant:
|
||||||
|
coin.spendAllocation = {
|
||||||
|
amount: Amounts.stringify(ocp.amount),
|
||||||
|
id: `txn:refresh:${refreshGroupId}`,
|
||||||
|
};
|
||||||
break;
|
break;
|
||||||
case CoinStatus.Fresh: {
|
case CoinStatus.Fresh: {
|
||||||
coin.status = CoinStatus.Dormant;
|
coin.status = CoinStatus.Dormant;
|
||||||
@ -911,6 +912,10 @@ export async function createRefreshGroup(
|
|||||||
// For suspended coins, we don't have to adjust coin
|
// For suspended coins, we don't have to adjust coin
|
||||||
// availability, as they are not counted as available.
|
// availability, as they are not counted as available.
|
||||||
coin.status = CoinStatus.Dormant;
|
coin.status = CoinStatus.Dormant;
|
||||||
|
coin.spendAllocation = {
|
||||||
|
amount: Amounts.stringify(ocp.amount),
|
||||||
|
id: `txn:refresh:${refreshGroupId}`,
|
||||||
|
};
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
Loading…
Reference in New Issue
Block a user