add check for #coins depoisted exceeding #coins issued (not just by amount), fixes #5446
This commit is contained in:
parent
33441042a9
commit
332341cb7b
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
This file is part of TALER
|
This file is part of TALER
|
||||||
Copyright (C) 2016, 2017 Taler Systems SA
|
Copyright (C) 2016, 2017, 2018 Taler Systems SA
|
||||||
|
|
||||||
TALER is free software; you can redistribute it and/or modify it under the
|
TALER is free software; you can redistribute it and/or modify it under the
|
||||||
terms of the GNU Affero Public License as published by the Free Software
|
terms of the GNU Affero Public License as published by the Free Software
|
||||||
@ -329,8 +329,8 @@ report (json_t *array,
|
|||||||
* @param risk maximum risk that might have just become real (coins created by this @a dki)
|
* @param risk maximum risk that might have just become real (coins created by this @a dki)
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
report_emergency (const struct TALER_EXCHANGEDB_DenominationKeyInformationP *dki,
|
report_emergency_by_amount (const struct TALER_EXCHANGEDB_DenominationKeyInformationP *dki,
|
||||||
const struct TALER_Amount *risk)
|
const struct TALER_Amount *risk)
|
||||||
{
|
{
|
||||||
report (report_emergencies,
|
report (report_emergencies,
|
||||||
json_pack ("{s:o, s:o, s:s, s:s, s:o}",
|
json_pack ("{s:o, s:o, s:s, s:s, s:o}",
|
||||||
@ -351,6 +351,49 @@ report_emergency (const struct TALER_EXCHANGEDB_DenominationKeyInformationP *dki
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called in case we detect an emergency situation where the exchange
|
||||||
|
* is paying out a larger NUMBER of coins of a denomination than we
|
||||||
|
* issued in that denomination. This means that the exchange's
|
||||||
|
* private keys might have gotten compromised, and that we need to
|
||||||
|
* trigger an emergency request to all wallets to deposit pending
|
||||||
|
* coins for the denomination (and as an exchange suffer a huge
|
||||||
|
* financial loss).
|
||||||
|
*
|
||||||
|
* @param dki denomination key where the loss was detected
|
||||||
|
* @param num_issued number of coins that were issued
|
||||||
|
* @param num_known number of coins that have been deposited
|
||||||
|
* @param risk amount that is at risk
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
report_emergency_by_count (const struct TALER_EXCHANGEDB_DenominationKeyInformationP *dki,
|
||||||
|
uint64_t num_issued,
|
||||||
|
uint64_t num_known,
|
||||||
|
const struct TALER_Amount *risk)
|
||||||
|
{
|
||||||
|
report (report_emergencies,
|
||||||
|
json_pack ("{s:o, s:I, s:I, s:o, s:s, s:s, s:o}",
|
||||||
|
"denompub_hash",
|
||||||
|
GNUNET_JSON_from_data_auto (&dki->properties.denom_hash),
|
||||||
|
"num_issued",
|
||||||
|
(json_int_t) num_issued,
|
||||||
|
"num_known",
|
||||||
|
(json_int_t) num_known,
|
||||||
|
"denom_risk",
|
||||||
|
TALER_JSON_from_amount (risk),
|
||||||
|
"start",
|
||||||
|
GNUNET_STRINGS_absolute_time_to_string (GNUNET_TIME_absolute_ntoh (dki->properties.start)),
|
||||||
|
"deposit_end",
|
||||||
|
GNUNET_STRINGS_absolute_time_to_string (GNUNET_TIME_absolute_ntoh (dki->properties.expire_deposit)),
|
||||||
|
"value",
|
||||||
|
TALER_JSON_from_amount_nbo (&dki->properties.value)));
|
||||||
|
GNUNET_assert (GNUNET_OK ==
|
||||||
|
TALER_amount_add (&reported_emergency_sum,
|
||||||
|
&reported_emergency_sum,
|
||||||
|
risk));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Report a (serious) inconsistency in the exchange's database with
|
* Report a (serious) inconsistency in the exchange's database with
|
||||||
* respect to calculations involving amounts.
|
* respect to calculations involving amounts.
|
||||||
@ -2962,24 +3005,47 @@ sync_denomination (void *cls,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
long long cnt;
|
||||||
|
|
||||||
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||||
"Final balance for denomination `%s' is %s\n",
|
"Final balance for denomination `%s' is %s (%llu)\n",
|
||||||
GNUNET_h2s (denom_hash),
|
GNUNET_h2s (denom_hash),
|
||||||
TALER_amount2s (&ds->denom_balance));
|
TALER_amount2s (&ds->denom_balance),
|
||||||
if (ds->in_db)
|
(unsigned long long) ds->num_issued);
|
||||||
qs = adb->update_denomination_balance (adb->cls,
|
cnt = edb->count_known_coins (edb->cls,
|
||||||
asession,
|
esession,
|
||||||
denom_hash,
|
denom_hash);
|
||||||
&ds->denom_balance,
|
if (0 > cnt)
|
||||||
&ds->denom_risk,
|
{
|
||||||
ds->num_issued);
|
/* Failed to obtain count? Bad database */
|
||||||
|
qs = (enum GNUNET_DB_QueryStatus) cnt;
|
||||||
|
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
|
||||||
|
cc->qs = qs;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
qs = adb->insert_denomination_balance (adb->cls,
|
{
|
||||||
asession,
|
if (ds->num_issued > (uint64_t) cnt)
|
||||||
denom_hash,
|
{
|
||||||
&ds->denom_balance,
|
report_emergency_by_count (dki,
|
||||||
&ds->denom_risk,
|
cnt,
|
||||||
ds->num_issued);
|
ds->num_issued,
|
||||||
|
&ds->denom_risk);
|
||||||
|
}
|
||||||
|
if (ds->in_db)
|
||||||
|
qs = adb->update_denomination_balance (adb->cls,
|
||||||
|
asession,
|
||||||
|
denom_hash,
|
||||||
|
&ds->denom_balance,
|
||||||
|
&ds->denom_risk,
|
||||||
|
ds->num_issued);
|
||||||
|
else
|
||||||
|
qs = adb->insert_denomination_balance (adb->cls,
|
||||||
|
asession,
|
||||||
|
denom_hash,
|
||||||
|
&ds->denom_balance,
|
||||||
|
&ds->denom_risk,
|
||||||
|
ds->num_issued);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs)
|
if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs)
|
||||||
{
|
{
|
||||||
@ -3272,7 +3338,6 @@ refresh_session_cb (void *cls,
|
|||||||
amount_with_fee));
|
amount_with_fee));
|
||||||
return GNUNET_OK;
|
return GNUNET_OK;
|
||||||
}
|
}
|
||||||
// FIXME: free reveal_ctx.num_newcoins later!
|
|
||||||
|
|
||||||
{
|
{
|
||||||
const struct TALER_EXCHANGEDB_DenominationKeyInformationP *new_dkis[reveal_ctx.num_newcoins];
|
const struct TALER_EXCHANGEDB_DenominationKeyInformationP *new_dkis[reveal_ctx.num_newcoins];
|
||||||
@ -3436,8 +3501,9 @@ refresh_session_cb (void *cls,
|
|||||||
&dso->denom_balance,
|
&dso->denom_balance,
|
||||||
amount_with_fee))
|
amount_with_fee))
|
||||||
{
|
{
|
||||||
report_emergency (dki,
|
report_emergency_by_amount (dki,
|
||||||
&dso->denom_risk);
|
&dso->denom_risk);
|
||||||
|
/* FIXME: we can't exactly just stop here! */
|
||||||
return GNUNET_SYSERR;
|
return GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
dso->denom_balance = tmp;
|
dso->denom_balance = tmp;
|
||||||
@ -3593,8 +3659,9 @@ deposit_cb (void *cls,
|
|||||||
&ds->denom_balance,
|
&ds->denom_balance,
|
||||||
amount_with_fee))
|
amount_with_fee))
|
||||||
{
|
{
|
||||||
report_emergency (dki,
|
report_emergency_by_amount (dki,
|
||||||
&ds->denom_risk);
|
&ds->denom_risk);
|
||||||
|
/* FIXME: we can't exactly just stop here like this! */
|
||||||
cc->qs = GNUNET_DB_STATUS_HARD_ERROR;
|
cc->qs = GNUNET_DB_STATUS_HARD_ERROR;
|
||||||
return GNUNET_SYSERR;
|
return GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user