intermediary step on auditor-aggregation cleanup
This commit is contained in:
parent
66fa3559c8
commit
d3dc8c8c7d
@ -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));
|
||||||
|
Loading…
Reference in New Issue
Block a user