work on #4963 for taler-auditor

This commit is contained in:
Christian Grothoff 2017-10-16 11:49:32 +02:00
parent 88cdaf70c9
commit 2cddf524a8
No known key found for this signature in database
GPG Key ID: 939E6BE1E29FC3CC
2 changed files with 173 additions and 67 deletions

View File

@ -26,6 +26,7 @@ taler_auditor_LDADD = \
$(top_builddir)/src/exchangedb/libtalerexchangedb.la \ $(top_builddir)/src/exchangedb/libtalerexchangedb.la \
$(top_builddir)/src/auditordb/libtalerauditordb.la \ $(top_builddir)/src/auditordb/libtalerauditordb.la \
-ljansson \ -ljansson \
-lgnunetjson \
-lgnunetutil -lgnunetutil
taler_wire_auditor_SOURCES = \ taler_wire_auditor_SOURCES = \

View File

@ -114,10 +114,73 @@ static struct TALER_MasterPublicKeyP master_pub;
*/ */
static struct TALER_AUDITORDB_ProgressPoint pp; static struct TALER_AUDITORDB_ProgressPoint pp;
/**
* Array of reports about denomination keys with an
* emergency (more deposited than withdrawn)
*/
static json_t *report_emergencies;
/**
* Array of reports about row inconsitencies.
*/
static json_t *report_row_inconsistencies;
/**
* Array of reports about minor row inconcistencies.
*/
static json_t *report_row_minor_inconsistencies;
/**
* Array of reports about reserve inconsitencies.
*/
static json_t *report_reserve_inconsistencies;
/**
* Array of reports about irregular wire out entries.
*/
static json_t *report_wire_out_inconsistencies;
/**
* Array of reports about inconsistencies about coins.
*/
static json_t *report_coin_inconsistencies;
/**
* Report about expected reserve balances.
*/
static json_t *report_reserve_balances;
/**
* Report about aggregate wire transfer fee profits.
*/
static json_t *report_aggregation_fee_balances;
/**
* Report about denomination fee balances.
*/
static json_t *report_denomination_balances;
/* ***************************** Report logic **************************** */ /* ***************************** Report logic **************************** */
/**
* Add @a object to the report @a array. Fail hard if this fails.
*
* @param array report array to append @a object to
* @param object object to append, should be check that it is not NULL
*/
static void
report (json_t *array,
json_t *object)
{
GNUNET_assert (NULL != object);
GNUNET_assert (0 ==
json_array_append_new (array,
object));
}
/** /**
* Called in case we detect an emergency situation where the exchange * Called in case we detect an emergency situation where the exchange
* is paying out a larger amount on a denomination than we issued in * is paying out a larger amount on a denomination than we issued in
@ -131,14 +194,10 @@ static struct TALER_AUDITORDB_ProgressPoint pp;
static void static void
report_emergency (const struct TALER_EXCHANGEDB_DenominationKeyInformationP *dki) report_emergency (const struct TALER_EXCHANGEDB_DenominationKeyInformationP *dki)
{ {
char *dhks; report (report_emergencies,
json_pack ("{s:o}",
dhks = GNUNET_STRINGS_data_to_string_alloc (&dki->properties.denom_hash, "denompub_hash",
sizeof (struct GNUNET_HashCode)); GNUNET_JSON_from_data_auto (&dki->properties.denom_hash)));
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Emergency detected. Exchange must revoke key using `taler-auditor -r %s`\n",
dhks);
GNUNET_free (dhks);
} }
@ -154,12 +213,11 @@ report_row_inconsistency (const char *table,
uint64_t rowid, uint64_t rowid,
const char *diagnostic) const char *diagnostic)
{ {
// TODO (#4963): implement proper reporting logic writing to file. report (report_row_inconsistencies,
GNUNET_log (GNUNET_ERROR_TYPE_ERROR, json_pack ("{s:s, s:I, s:s}",
"Database inconsistency detected in table %s at row %llu: %s\n", "table", table,
table, "row", (json_int_t) rowid,
(unsigned long long) rowid, "diagnostic", diagnostic));
diagnostic);
} }
@ -176,12 +234,11 @@ report_row_minor_inconsistency (const char *table,
uint64_t rowid, uint64_t rowid,
const char *diagnostic) const char *diagnostic)
{ {
// TODO (#4963): implement proper reporting logic writing to file. report (report_row_minor_inconsistencies,
GNUNET_log (GNUNET_ERROR_TYPE_ERROR, json_pack ("{s:s, s:I, s:s}",
"Minor inconsistency detected in table %s at row %llu: %s\n", "table", table,
table, "row", (json_int_t) rowid,
(unsigned long long) rowid, "diagnostic", diagnostic));
diagnostic);
} }
@ -199,11 +256,16 @@ report_reserve_inconsistency (const struct TALER_ReservePublicKeyP *reserve_pub,
const struct TALER_Amount *observed, const struct TALER_Amount *observed,
const char *diagnostic) const char *diagnostic)
{ {
// TODO (#4963): implement proper reporting logic writing to file, include amounts. report (report_reserve_inconsistencies,
GNUNET_log (GNUNET_ERROR_TYPE_ERROR, json_pack ("{s:o, s:o, s:o, s:s}",
"Reserve inconsistency detected affecting reserve %s: %s\n", "reserve_pub",
TALER_B2S (reserve_pub), GNUNET_JSON_from_data_auto (reserve_pub),
diagnostic); "expected",
TALER_JSON_from_amount (expected),
"observed",
TALER_JSON_from_amount (observed),
"diagnostic",
diagnostic));
} }
@ -223,10 +285,18 @@ report_wire_out_inconsistency (const json_t *destination,
const struct TALER_Amount *observed, const struct TALER_Amount *observed,
const char *diagnostic) const char *diagnostic)
{ {
// TODO (#4963): implement proper reporting logic writing to file, include amounts. report (report_wire_out_inconsistencies,
GNUNET_log (GNUNET_ERROR_TYPE_ERROR, json_pack ("{s:O, s:I, s:o, s:o, s:s}",
"Wire out inconsistency detected: %s\n", "destination_account",
diagnostic); destination,
"rowid",
(json_int_t) rowid,
"expected",
TALER_JSON_from_amount (expected),
"observed",
TALER_JSON_from_amount (observed),
"diagnostic",
diagnostic));
} }
@ -244,10 +314,16 @@ report_coin_inconsistency (const struct TALER_CoinSpendPublicKeyP *coin_pub,
const struct TALER_Amount *observed, const struct TALER_Amount *observed,
const char *diagnostic) const char *diagnostic)
{ {
// TODO (#4963): implement proper reporting logic writing to file, include amounts. report (report_coin_inconsistencies,
GNUNET_log (GNUNET_ERROR_TYPE_ERROR, json_pack ("{s:o, s:o, s:o, s:s}",
"Coin inconsistency detected: %s\n", "coin_pub",
diagnostic); GNUNET_JSON_from_data_auto (coin_pub),
"expected",
TALER_JSON_from_amount (expected),
"observed",
TALER_JSON_from_amount (observed),
"diagnostic",
diagnostic));
} }
@ -271,13 +347,12 @@ static void
report_reserve_balance (const struct TALER_Amount *total_balance, report_reserve_balance (const struct TALER_Amount *total_balance,
const struct TALER_Amount *total_fee_balance) const struct TALER_Amount *total_fee_balance)
{ {
// TODO (#4963): implement proper reporting logic writing to file. report (report_reserve_balances,
GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, json_pack ("{s:o, s:o}",
"Escrow balance to be held for reserves is %s\n", "total_escrow_balance",
TALER_amount2s (total_balance)); TALER_JSON_from_amount (total_balance),
GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, "total_withdraw_fee_income",
"Withdraw fees income is %s\n", TALER_JSON_from_amount (total_fee_balance)));
TALER_amount2s (total_fee_balance));
} }
@ -294,10 +369,10 @@ report_reserve_balance (const struct TALER_Amount *total_balance,
static void static void
report_aggregation_fee_balance (const struct TALER_Amount *total_fee_balance) report_aggregation_fee_balance (const struct TALER_Amount *total_fee_balance)
{ {
// TODO (#4963): implement proper reporting logic writing to file. report (report_aggregation_fee_balances,
GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, json_pack ("{s:o}",
"Aggregation fees income is %s\n", "total_aggregation_fee_income",
TALER_amount2s (total_fee_balance)); TALER_JSON_from_amount (total_fee_balance)));
} }
@ -317,22 +392,18 @@ report_denomination_balance (const struct TALER_Amount *total_balance,
const struct TALER_Amount *melt_fees, const struct TALER_Amount *melt_fees,
const struct TALER_Amount *refund_fees) const struct TALER_Amount *refund_fees)
{ {
// TODO (#4963/4962): implement proper reporting logic writing to file. report (report_denomination_balances,
GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, json_pack ("{s:o, s:o, s:o, s:o, s:o}",
"Escrow balance for issued coins is %s\n", "total_escrow_balance",
TALER_amount2s (total_balance)); TALER_JSON_from_amount (total_balance),
GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, "total_active_risk",
"Risk from active operations is %s\n", TALER_JSON_from_amount (total_risk),
TALER_amount2s (total_risk)); "total_deposit_fee_income",
GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, TALER_JSON_from_amount (deposit_fees),
"Deposit fee income is %s\n", "total_melt_fee_income",
TALER_amount2s (deposit_fees)); TALER_JSON_from_amount (melt_fees),
GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, "total_refund_fee_income",
"Melt fee income is %s\n", TALER_JSON_from_amount (refund_fees)));
TALER_amount2s (melt_fees));
GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
"Refund fee income is %s\n",
TALER_amount2s (refund_fees));
} }
@ -3723,6 +3794,8 @@ run (void *cls,
const char *cfgfile, const char *cfgfile,
const struct GNUNET_CONFIGURATION_Handle *c) const struct GNUNET_CONFIGURATION_Handle *c)
{ {
json_t *report;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Launching auditor\n"); "Launching auditor\n");
cfg = c; cfg = c;
@ -3789,11 +3862,43 @@ run (void *cls,
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Starting audit\n"); "Starting audit\n");
GNUNET_assert (NULL !=
(report_emergencies = json_array ()));
GNUNET_assert (NULL !=
(report_row_inconsistencies = json_array ()));
GNUNET_assert (NULL !=
(report_row_minor_inconsistencies = json_array ()));
GNUNET_assert (NULL !=
(report_reserve_inconsistencies = json_array ()));
GNUNET_assert (NULL !=
(report_wire_out_inconsistencies = json_array ()));
GNUNET_assert (NULL !=
(report_coin_inconsistencies = json_array ()));
GNUNET_assert (NULL !=
(report_reserve_balances = json_array ()));
GNUNET_assert (NULL !=
(report_aggregation_fee_balances = json_array ()));
GNUNET_assert (NULL !=
(report_denomination_balances = json_array ()));
setup_sessions_and_run (); setup_sessions_and_run ();
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Audit complete\n"); "Audit complete\n");
TALER_AUDITORDB_plugin_unload (adb); TALER_AUDITORDB_plugin_unload (adb);
TALER_EXCHANGEDB_plugin_unload (edb); TALER_EXCHANGEDB_plugin_unload (edb);
report = json_pack ("{s:o, s:o, s:o, s:o, s:o, s:o, s:o, s:o, s:o}",
"emergencies", report_emergencies,
"row-inconsistencies", report_row_inconsistencies,
"row-minor-inconsistencies", report_row_minor_inconsistencies,
"reserve-inconsistencies", report_reserve_inconsistencies,
"wire-out-inconsistencies", report_wire_out_inconsistencies,
"coin_inconsistencies", report_coin_inconsistencies,
"reserve_balance", report_reserve_balances,
"aggregation_fee_balance", report_aggregation_fee_balances,
"report_denomination_balance", report_denomination_balances);
json_dumpf (report,
stdout,
JSON_INDENT (2));
json_decref (report);
} }
@ -3812,14 +3917,14 @@ main (int argc,
const struct GNUNET_GETOPT_CommandLineOption options[] = { const struct GNUNET_GETOPT_CommandLineOption options[] = {
GNUNET_GETOPT_option_mandatory GNUNET_GETOPT_option_mandatory
(GNUNET_GETOPT_option_base32_auto ('m', (GNUNET_GETOPT_option_base32_auto ('m',
"exchange-key", "exchange-key",
"KEY", "KEY",
"public key of the exchange (Crockford base32 encoded)", "public key of the exchange (Crockford base32 encoded)",
&master_pub)), &master_pub)),
GNUNET_GETOPT_option_flag ('r', GNUNET_GETOPT_option_flag ('r',
"restart", "restart",
"restart audit from the beginning (required on first run)", "restart audit from the beginning (required on first run)",
&restart), &restart),
GNUNET_GETOPT_OPTION_END GNUNET_GETOPT_OPTION_END
}; };