finish review of coins auditor analysis logic, improve error handling

This commit is contained in:
Christian Grothoff 2020-03-23 22:27:31 +01:00
parent 0bd53ed443
commit 240b23684d
No known key found for this signature in database
GPG Key ID: 939E6BE1E29FC3CC

View File

@ -910,13 +910,13 @@ reveal_data_cb (void *cls,
report_row_inconsistency ("refresh_reveal", report_row_inconsistency ("refresh_reveal",
rctx->rowid, rctx->rowid,
"denomination key not found"); "denomination key not found");
rctx->err = GNUNET_NO; /* terminate, but return "OK" */ rctx->err = GNUNET_NO; /* terminate here, but return "OK" to commit transaction */
} }
else if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs) else if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs)
{ {
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
rctx->qs = qs; rctx->qs = qs;
rctx->err = GNUNET_SYSERR; /* terminate, return GNUNET_SYSERR */ rctx->err = GNUNET_SYSERR; /* terminate, return #GNUNET_SYSERR: abort transaction */
} }
} }
} }
@ -1101,9 +1101,9 @@ refresh_session_cb (void *cls,
if ( (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) || if ( (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) ||
(0 == reveal_ctx.num_freshcoins) ) (0 == reveal_ctx.num_freshcoins) )
{ {
/* This can happen if reveal was not yet called or only /* This can legitimately happen if reveal was not yet called or only
with invalid data, even if the exchange is correctly with invalid data, even if the exchange is correctly operating. We
operating. We still report it. */ still report it. */
TALER_ARL_report (report_refreshs_hanging, TALER_ARL_report (report_refreshs_hanging,
json_pack ("{s:I, s:o, s:o}", json_pack ("{s:I, s:o, s:o}",
"row", (json_int_t) rowid, "row", (json_int_t) rowid,
@ -1162,15 +1162,22 @@ refresh_session_cb (void *cls,
amount_with_fee, amount_with_fee,
&melt_fee)) &melt_fee))
{ {
// FIXME: handle properly! /* Melt fee higher than contribution of melted coin; this makes
GNUNET_break (0); no sense (exchange should never have accepted the operation) */
cc->qs = GNUNET_DB_STATUS_HARD_ERROR; report_amount_arithmetic_inconsistency ("melt contribution vs. fee",
GNUNET_free_non_null (reveal_ctx.new_issues); rowid,
return GNUNET_SYSERR; amount_with_fee,
&melt_fee,
-1);
/* To continue, best assumption is the melted coin contributed
nothing (=> all withdrawal amounts will be counted as losses) */
GNUNET_assert (GNUNET_OK ==
TALER_amount_get_zero (TALER_ARL_currency,
&amount_without_fee));
} }
} }
/* check old coin covers complete expenses */ /* check old coin covers complete expenses (of withdraw operations) */
if (1 == TALER_amount_cmp (&refresh_cost, if (1 == TALER_amount_cmp (&refresh_cost,
&amount_without_fee)) &amount_without_fee))
{ {
@ -1184,7 +1191,7 @@ refresh_session_cb (void *cls,
return GNUNET_OK; return GNUNET_OK;
} }
/* update outstanding denomination amounts */ /* update outstanding denomination amounts for fresh coins withdrawn */
for (unsigned int i = 0; i<reveal_ctx.num_freshcoins; i++) for (unsigned int i = 0; i<reveal_ctx.num_freshcoins; i++)
{ {
struct DenominationSummary *dsi; struct DenominationSummary *dsi;
@ -1195,9 +1202,12 @@ refresh_session_cb (void *cls,
&reveal_ctx.new_issues[i]->denom_hash); &reveal_ctx.new_issues[i]->denom_hash);
if (NULL == dsi) if (NULL == dsi)
{ {
GNUNET_break (0); report_row_inconsistency ("refresh_reveal",
return GNUNET_SYSERR; rowid,
"denomination key for fresh coin unknown to auditor");
} }
else
{
TALER_amount_ntoh (&value, TALER_amount_ntoh (&value,
&reveal_ctx.new_issues[i]->value); &reveal_ctx.new_issues[i]->value);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@ -1226,6 +1236,7 @@ refresh_session_cb (void *cls,
&total_risk, &total_risk,
&value)); &value));
} }
}
GNUNET_free_non_null (reveal_ctx.new_issues); GNUNET_free_non_null (reveal_ctx.new_issues);
} }
@ -1235,10 +1246,12 @@ refresh_session_cb (void *cls,
&issue->denom_hash); &issue->denom_hash);
if (NULL == dso) if (NULL == dso)
{ {
// FIXME: handle more nicely!?! report_row_inconsistency ("refresh_reveal",
GNUNET_break (0); rowid,
return GNUNET_SYSERR; "denomination key for dirty coin unknown to auditor");
} }
else
{
if (GNUNET_SYSERR == if (GNUNET_SYSERR ==
TALER_amount_subtract (&tmp, TALER_amount_subtract (&tmp,
&dso->denom_balance, &dso->denom_balance,
@ -1262,7 +1275,8 @@ refresh_session_cb (void *cls,
accepted a forged coin (i.e. emergency situation after accepted a forged coin (i.e. emergency situation after
private key compromise). In that case, we cannot even private key compromise). In that case, we cannot even
subtract the profit we make from the fee from the escrow subtract the profit we make from the fee from the escrow
balance. Tested as part of test-auditor.sh, case #18 */report_amount_arithmetic_inconsistency ( balance. Tested as part of test-auditor.sh, case #18 *///
report_amount_arithmetic_inconsistency (
"subtracting refresh fee from escrow balance", "subtracting refresh fee from escrow balance",
rowid, rowid,
&total_escrow_balance, &total_escrow_balance,
@ -1276,11 +1290,11 @@ refresh_session_cb (void *cls,
&total_escrow_balance, &total_escrow_balance,
amount_with_fee)); amount_with_fee));
} }
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"New balance of denomination `%s' after melt is %s\n", "New balance of denomination `%s' after melt is %s\n",
GNUNET_h2s (&issue->denom_hash), GNUNET_h2s (&issue->denom_hash),
TALER_amount2s (&dso->denom_balance)); TALER_amount2s (&dso->denom_balance));
}
/* update global melt fees */ /* update global melt fees */
{ {
@ -1440,10 +1454,12 @@ deposit_cb (void *cls,
&issue->denom_hash); &issue->denom_hash);
if (NULL == ds) if (NULL == ds)
{ {
GNUNET_break (0); report_row_inconsistency ("deposit",
// FIXME: handle/report more nicely!??! rowid,
return GNUNET_SYSERR; "denomination key for deposited coin unknown to auditor");
} }
else
{
if (GNUNET_SYSERR == if (GNUNET_SYSERR ==
TALER_amount_subtract (&tmp, TALER_amount_subtract (&tmp,
&ds->denom_balance, &ds->denom_balance,
@ -1488,6 +1504,7 @@ deposit_cb (void *cls,
"New balance of denomination `%s' after deposit is %s\n", "New balance of denomination `%s' after deposit is %s\n",
GNUNET_h2s (&issue->denom_hash), GNUNET_h2s (&issue->denom_hash),
TALER_amount2s (&ds->denom_balance)); TALER_amount2s (&ds->denom_balance));
}
/* update global deposit fees */ /* update global deposit fees */
{ {
@ -1622,10 +1639,12 @@ refund_cb (void *cls,
&issue->denom_hash); &issue->denom_hash);
if (NULL == ds) if (NULL == ds)
{ {
GNUNET_break (0); report_row_inconsistency ("refund",
// FIXME: handle more nicely!?!? rowid,
return GNUNET_SYSERR; "denomination key for refunded coin unknown to auditor");
} }
else
{
GNUNET_assert (GNUNET_OK == GNUNET_assert (GNUNET_OK ==
TALER_amount_add (&ds->denom_balance, TALER_amount_add (&ds->denom_balance,
&ds->denom_balance, &ds->denom_balance,
@ -1646,7 +1665,7 @@ refund_cb (void *cls,
"New balance of denomination `%s' after refund is %s\n", "New balance of denomination `%s' after refund is %s\n",
GNUNET_h2s (&issue->denom_hash), GNUNET_h2s (&issue->denom_hash),
TALER_amount2s (&ds->denom_balance)); TALER_amount2s (&ds->denom_balance));
}
/* update total refund fee balance */ /* update total refund fee balance */
GNUNET_assert (GNUNET_OK == GNUNET_assert (GNUNET_OK ==
TALER_amount_add (&total_refund_fee_income, TALER_amount_add (&total_refund_fee_income,
@ -1743,6 +1762,14 @@ check_recoup (struct CoinContext *cc,
ds = get_denomination_summary (cc, ds = get_denomination_summary (cc,
issue, issue,
&issue->denom_hash); &issue->denom_hash);
if (NULL == ds)
{
report_row_inconsistency ("recoup",
rowid,
"denomination key for recouped coin unknown to auditor");
}
else
{
if (GNUNET_NO == ds->was_revoked) if (GNUNET_NO == ds->was_revoked)
{ {
/* Woopsie, we allowed recoup on non-revoked denomination!? */ /* Woopsie, we allowed recoup on non-revoked denomination!? */
@ -1763,6 +1790,7 @@ check_recoup (struct CoinContext *cc,
TALER_amount_add (&total_recoup_loss, TALER_amount_add (&total_recoup_loss,
&total_recoup_loss, &total_recoup_loss,
amount)); amount));
}
return GNUNET_OK; return GNUNET_OK;
} }