intermediary step on auditor-aggregation cleanup

This commit is contained in:
Christian Grothoff 2020-03-22 15:17:11 +01:00
parent 66fa3559c8
commit d3dc8c8c7d
No known key found for this signature in database
GPG Key ID: 939E6BE1E29FC3CC

View File

@ -370,14 +370,14 @@ struct WireCheckContext
* the amounts for the aggregation table and checks that the total * the amounts for the aggregation table and checks that the total
* claimed coin value is within the value of the coin's denomination. * claimed coin value is within the value of the coin's denomination.
* *
* @param coin_pub public key of the coin (for TALER_ARL_reporting) * @param coin_pub public key of the coin (for reporting)
* @param h_contract_terms hash of the proposal for which we calculate the amount * @param h_contract_terms hash of the proposal for which we calculate the amount
* @param merchant_pub public key of the merchant (who is allowed to issue refunds) * @param merchant_pub public key of the merchant (who is allowed to issue refunds)
* @param issue denomination information about the coin * @param issue denomination information about the coin
* @param tl_head head of transaction history to verify * @param tl_head head of transaction history to verify
* @param[out] merchant_gain amount the coin contributes to the wire transfer to the merchant * @param[out] merchant_gain amount the coin contributes to the wire transfer to the merchant
* @param[out] deposit_gain amount the coin contributes excluding refunds * @param[out] deposit_gain amount the coin contributes excluding refunds
* @return #GNUNET_OK on success, #GNUNET_SYSERR on error * @return #GNUNET_OK on success, #GNUNET_SYSERR if the transaction must fail (hard error)
*/ */
static int static int
check_transaction_history_for_deposit ( check_transaction_history_for_deposit (
@ -392,17 +392,13 @@ check_transaction_history_for_deposit (
struct TALER_Amount expenditures; struct TALER_Amount expenditures;
struct TALER_Amount refunds; struct TALER_Amount refunds;
struct TALER_Amount spent; struct TALER_Amount spent;
struct TALER_Amount value;
struct TALER_Amount merchant_loss; struct TALER_Amount merchant_loss;
struct TALER_Amount final_gain;
const struct TALER_Amount *deposit_fee; const struct TALER_Amount *deposit_fee;
int refund_deposit_fee; int refund_deposit_fee;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Checking transaction history of coin %s\n", "Checking transaction history of coin %s\n",
TALER_B2S (coin_pub)); TALER_B2S (coin_pub));
GNUNET_assert (NULL != tl_head);
GNUNET_assert (GNUNET_OK == GNUNET_assert (GNUNET_OK ==
TALER_amount_get_zero (TALER_ARL_currency, TALER_amount_get_zero (TALER_ARL_currency,
&expenditures)); &expenditures));
@ -415,10 +411,11 @@ check_transaction_history_for_deposit (
GNUNET_assert (GNUNET_OK == GNUNET_assert (GNUNET_OK ==
TALER_amount_get_zero (TALER_ARL_currency, TALER_amount_get_zero (TALER_ARL_currency,
&merchant_loss)); &merchant_loss));
/* Go over transaction history to compute totals; note that we do not /* Go over transaction history to compute totals; note that we do not bother
know the order, so instead of subtracting we compute positive to reconstruct the order of the events, so instead of subtracting we
(deposit, melt) and negative (refund) values separately here, compute positive (deposit, melt) and negative (refund) values separately
and then subtract the negative from the positive after the loop. */ here, and then subtract the negative from the positive at the end (after
the loops). *///
refund_deposit_fee = GNUNET_NO; refund_deposit_fee = GNUNET_NO;
deposit_fee = NULL; deposit_fee = NULL;
for (const struct TALER_EXCHANGEDB_TransactionList *tl = tl_head; for (const struct TALER_EXCHANGEDB_TransactionList *tl = tl_head;
@ -426,9 +423,7 @@ check_transaction_history_for_deposit (
tl = tl->next) tl = tl->next)
{ {
const struct TALER_Amount *amount_with_fee; const struct TALER_Amount *amount_with_fee;
const struct TALER_Amount *fee; const struct TALER_Amount *fee_claimed;
const struct TALER_AmountNBO *fee_dki;
struct TALER_Amount tmp;
switch (tl->type) switch (tl->type)
{ {
@ -444,7 +439,7 @@ check_transaction_history_for_deposit (
{ {
report_row_inconsistency ("deposits", report_row_inconsistency ("deposits",
tl->serial_id, tl->serial_id,
"wire value malformed"); "wire account given is malformed");
} }
else if (0 != else if (0 !=
GNUNET_memcmp (&hw, GNUNET_memcmp (&hw,
@ -455,9 +450,8 @@ check_transaction_history_for_deposit (
"h(wire) does not match wire"); "h(wire) does not match wire");
} }
} }
amount_with_fee = &tl->details.deposit->amount_with_fee; amount_with_fee = &tl->details.deposit->amount_with_fee; /* according to exchange*/
fee = &tl->details.deposit->deposit_fee; fee_claimed = &tl->details.deposit->deposit_fee; /* Fee according to exchange DB */
fee_dki = &issue->fee_deposit;
if (GNUNET_OK != if (GNUNET_OK !=
TALER_amount_add (&expenditures, TALER_amount_add (&expenditures,
&expenditures, &expenditures,
@ -478,7 +472,7 @@ check_transaction_history_for_deposit (
if (GNUNET_OK != if (GNUNET_OK !=
TALER_amount_subtract (&amount_without_fee, TALER_amount_subtract (&amount_without_fee,
amount_with_fee, amount_with_fee,
fee)) fee_claimed))
{ {
GNUNET_break (0); GNUNET_break (0);
return GNUNET_SYSERR; return GNUNET_SYSERR;
@ -494,24 +488,30 @@ check_transaction_history_for_deposit (
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Detected applicable deposit of %s\n", "Detected applicable deposit of %s\n",
TALER_amount2s (&amount_without_fee)); TALER_amount2s (&amount_without_fee));
deposit_fee = fee; deposit_fee = fee_claimed; /* We had a deposit, remember the fee, we may need it */
} }
/* Check that the fees given in the transaction list and in dki match */ /* Check that the fees given in the transaction list and in dki match */
TALER_amount_ntoh (&tmp,
fee_dki);
if (0 !=
TALER_amount_cmp (&tmp,
fee))
{ {
/* Disagreement in fee structure within DB, should be impossible! */ struct TALER_Amount fee_expected;
GNUNET_break (0);
return GNUNET_SYSERR; TALER_amount_ntoh (&fee_expected,
&issue->fee_deposit);
if (0 !=
TALER_amount_cmp (&fee_expected,
fee_claimed))
{
/* Disagreement in fee structure between auditor and exchange DB! */
report_amount_arithmetic_inconsistency ("deposit fee",
UINT64_MAX,
fee_claimed,
&fee_expected,
1);
}
} }
break; break;
case TALER_EXCHANGEDB_TT_MELT: case TALER_EXCHANGEDB_TT_MELT:
amount_with_fee = &tl->details.melt->amount_with_fee; amount_with_fee = &tl->details.melt->amount_with_fee;
fee = &tl->details.melt->melt_fee; fee_claimed = &tl->details.melt->melt_fee;
fee_dki = &issue->fee_refresh;
if (GNUNET_OK != if (GNUNET_OK !=
TALER_amount_add (&expenditures, TALER_amount_add (&expenditures,
&expenditures, &expenditures,
@ -520,22 +520,28 @@ check_transaction_history_for_deposit (
GNUNET_break (0); GNUNET_break (0);
return GNUNET_SYSERR; return GNUNET_SYSERR;
} }
/* Check that the fees given in the transaction list and in dki match */
TALER_amount_ntoh (&tmp,
fee_dki);
if (0 !=
TALER_amount_cmp (&tmp,
fee))
{ {
/* Disagreement in fee structure within DB, should be impossible! */ struct TALER_Amount fee_expected;
GNUNET_break (0);
return GNUNET_SYSERR; /* Check that the fees given in the transaction list and in dki match */
TALER_amount_ntoh (&fee_expected,
&issue->fee_refresh);
if (0 !=
TALER_amount_cmp (&fee_expected,
fee_claimed))
{
/* Disagreement in fee structure between exchange and auditor */
report_amount_arithmetic_inconsistency ("melt fee",
UINT64_MAX,
fee_claimed,
&fee_expected,
1);
}
} }
break; break;
case TALER_EXCHANGEDB_TT_REFUND: case TALER_EXCHANGEDB_TT_REFUND:
amount_with_fee = &tl->details.refund->refund_amount; amount_with_fee = &tl->details.refund->refund_amount;
fee = &tl->details.refund->refund_fee; fee_claimed = &tl->details.refund->refund_fee;
fee_dki = &issue->fee_refund;
if (GNUNET_OK != if (GNUNET_OK !=
TALER_amount_add (&refunds, TALER_amount_add (&refunds,
&refunds, &refunds,
@ -547,7 +553,7 @@ check_transaction_history_for_deposit (
if (GNUNET_OK != if (GNUNET_OK !=
TALER_amount_add (&expenditures, TALER_amount_add (&expenditures,
&expenditures, &expenditures,
fee)) fee_claimed))
{ {
GNUNET_break (0); GNUNET_break (0);
return GNUNET_SYSERR; return GNUNET_SYSERR;
@ -572,19 +578,28 @@ check_transaction_history_for_deposit (
} }
refund_deposit_fee = GNUNET_YES; refund_deposit_fee = GNUNET_YES;
} }
/* Check that the fees given in the transaction list and in dki match */
TALER_amount_ntoh (&tmp,
fee_dki);
if (0 !=
TALER_amount_cmp (&tmp,
fee))
{ {
/* Disagreement in fee structure within DB, should be impossible! */ struct TALER_Amount fee_expected;
GNUNET_break (0);
return GNUNET_SYSERR; /* Check that the fees given in the transaction list and in dki match */
TALER_amount_ntoh (&fee_expected,
&issue->fee_refund);
if (0 !=
TALER_amount_cmp (&fee_expected,
fee_claimed))
{
/* Disagreement in fee structure between exchange and auditor! */
report_amount_arithmetic_inconsistency ("refund fee",
UINT64_MAX,
fee_claimed,
&fee_expected,
1);
}
} }
break; break;
case TALER_EXCHANGEDB_TT_OLD_COIN_RECOUP: case TALER_EXCHANGEDB_TT_OLD_COIN_RECOUP:
/* We count recoups of the coin as expenditures, as it
equivalently decreases the remaining value of the recouped coin. */
amount_with_fee = &tl->details.old_coin_recoup->value; amount_with_fee = &tl->details.old_coin_recoup->value;
if (GNUNET_OK != if (GNUNET_OK !=
TALER_amount_add (&refunds, TALER_amount_add (&refunds,
@ -643,19 +658,22 @@ check_transaction_history_for_deposit (
return GNUNET_SYSERR; return GNUNET_SYSERR;
} }
/* Now check that 'spent' is less or equal than the total coin value */
TALER_amount_ntoh (&value,
&issue->value);
if (1 == TALER_amount_cmp (&spent,
&value))
{ {
/* spent > value */ struct TALER_Amount value;
report_coin_arithmetic_inconsistency ("spend", /* Now check that 'spent' is less or equal than the total coin value */
coin_pub, TALER_amount_ntoh (&value,
&spent, &issue->value);
&value, if (1 == TALER_amount_cmp (&spent,
-1); &value))
return GNUNET_SYSERR; {
/* spent > value */
report_coin_arithmetic_inconsistency ("spend",
coin_pub,
&spent,
&value,
-1);
return GNUNET_SYSERR;
}
} }
/* Finally, update @a merchant_gain by subtracting what he "lost" /* Finally, update @a merchant_gain by subtracting what he "lost"
@ -674,20 +692,24 @@ check_transaction_history_for_deposit (
merchant_gain, merchant_gain,
deposit_fee)); deposit_fee));
} }
if (GNUNET_SYSERR ==
TALER_amount_subtract (&final_gain,
merchant_gain,
&merchant_loss))
{ {
/* refunds above deposits? Bad! */ struct TALER_Amount final_gain;
report_coin_arithmetic_inconsistency ("refund (merchant)",
coin_pub, if (GNUNET_SYSERR ==
merchant_gain, TALER_amount_subtract (&final_gain,
&merchant_loss, merchant_gain,
1); &merchant_loss))
return GNUNET_SYSERR; {
/* refunds above deposits? Bad! */
report_coin_arithmetic_inconsistency ("refund (merchant)",
coin_pub,
merchant_gain,
&merchant_loss,
1);
return GNUNET_SYSERR;
}
*merchant_gain = final_gain;
} }
*merchant_gain = final_gain;
GNUNET_log (GNUNET_ERROR_TYPE_INFO, GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Final merchant gain after refunds is %s\n", "Final merchant gain after refunds is %s\n",
TALER_amount2s (deposit_gain)); TALER_amount2s (deposit_gain));