rename fest on refactored auditor logic

This commit is contained in:
Christian Grothoff 2020-03-21 11:05:51 +01:00
parent 66616a97d7
commit 2ace9969b7
No known key found for this signature in database
GPG Key ID: 939E6BE1E29FC3CC
10 changed files with 1519 additions and 1516 deletions

View File

@ -13,3 +13,8 @@ test-wire-audit-inc.json
wirefees/ wirefees/
bank.err bank.err
libauditor.a libauditor.a
taler-helper-auditor-aggregation
taler-helper-auditor-coins
taler-helper-auditor-deposits
taler-helper-auditor-reserves
taler-helper-auditor-wire

View File

@ -13,11 +13,11 @@ pkgcfg_DATA = \
bin_PROGRAMS = \ bin_PROGRAMS = \
taler-auditor \ taler-auditor \
taler-auditor-reserves \ taler-helper-auditor-reserves \
taler-auditor-coins \ taler-helper-auditor-coins \
taler-auditor-aggregation \ taler-helper-auditor-aggregation \
taler-auditor-deposits \ taler-helper-auditor-deposits \
taler-wire-auditor \ taler-helper-auditor-wire \
taler-auditor-exchange \ taler-auditor-exchange \
taler-auditor-httpd \ taler-auditor-httpd \
taler-auditor-sign \ taler-auditor-sign \
@ -44,9 +44,9 @@ taler_auditor_dbinit_CPPFLAGS = \
-I$(top_srcdir)/src/pq/ \ -I$(top_srcdir)/src/pq/ \
$(POSTGRESQL_CPPFLAGS) $(POSTGRESQL_CPPFLAGS)
taler_auditor_reserves_SOURCES = \ taler_helper_auditor_reserves_SOURCES = \
taler-auditor-reserves.c taler-helper-auditor-reserves.c
taler_auditor_reserves_LDADD = \ taler_helper_auditor_reserves_LDADD = \
$(LIBGCRYPT_LIBS) \ $(LIBGCRYPT_LIBS) \
$(top_builddir)/src/util/libtalerutil.la \ $(top_builddir)/src/util/libtalerutil.la \
$(top_builddir)/src/json/libtalerjson.la \ $(top_builddir)/src/json/libtalerjson.la \
@ -58,9 +58,9 @@ taler_auditor_reserves_LDADD = \
-lgnunetjson \ -lgnunetjson \
-lgnunetutil -lgnunetutil
taler_auditor_coins_SOURCES = \ taler_helper_auditor_coins_SOURCES = \
taler-auditor-coins.c taler-helper-auditor-coins.c
taler_auditor_coins_LDADD = \ taler_helper_auditor_coins_LDADD = \
$(LIBGCRYPT_LIBS) \ $(LIBGCRYPT_LIBS) \
$(top_builddir)/src/util/libtalerutil.la \ $(top_builddir)/src/util/libtalerutil.la \
$(top_builddir)/src/json/libtalerjson.la \ $(top_builddir)/src/json/libtalerjson.la \
@ -72,9 +72,9 @@ taler_auditor_coins_LDADD = \
-lgnunetjson \ -lgnunetjson \
-lgnunetutil -lgnunetutil
taler_auditor_aggregation_SOURCES = \ taler_helper_auditor_aggregation_SOURCES = \
taler-auditor-aggregation.c taler-helper-auditor-aggregation.c
taler_auditor_aggregation_LDADD = \ taler_helper_auditor_aggregation_LDADD = \
$(LIBGCRYPT_LIBS) \ $(LIBGCRYPT_LIBS) \
$(top_builddir)/src/util/libtalerutil.la \ $(top_builddir)/src/util/libtalerutil.la \
$(top_builddir)/src/json/libtalerjson.la \ $(top_builddir)/src/json/libtalerjson.la \
@ -86,9 +86,9 @@ taler_auditor_aggregation_LDADD = \
-lgnunetjson \ -lgnunetjson \
-lgnunetutil -lgnunetutil
taler_auditor_deposits_SOURCES = \ taler_helper_auditor_deposits_SOURCES = \
taler-auditor-deposits.c taler-helper-auditor-deposits.c
taler_auditor_deposits_LDADD = \ taler_helper_auditor_deposits_LDADD = \
$(LIBGCRYPT_LIBS) \ $(LIBGCRYPT_LIBS) \
$(top_builddir)/src/util/libtalerutil.la \ $(top_builddir)/src/util/libtalerutil.la \
$(top_builddir)/src/json/libtalerjson.la \ $(top_builddir)/src/json/libtalerjson.la \
@ -100,6 +100,22 @@ taler_auditor_deposits_LDADD = \
-lgnunetjson \ -lgnunetjson \
-lgnunetutil -lgnunetutil
taler_helper_auditor_wire_SOURCES = \
taler-helper-auditor-wire.c
taler_helper_auditor_wire_LDADD = \
$(LIBGCRYPT_LIBS) \
$(top_builddir)/src/util/libtalerutil.la \
$(top_builddir)/src/json/libtalerjson.la \
$(top_builddir)/src/bank-lib/libtalerbank.la \
$(top_builddir)/src/exchangedb/libtalerexchangedb.la \
$(top_builddir)/src/auditordb/libtalerauditordb.la \
libauditor.a \
-ljansson \
-lgnunetjson \
-lgnunetcurl \
-lgnunetutil
taler_auditor_SOURCES = \ taler_auditor_SOURCES = \
taler-auditor.c taler-auditor.c
taler_auditor_LDADD = \ taler_auditor_LDADD = \
@ -131,20 +147,6 @@ taler_auditor_httpd_LDADD = \
-lgnunetutil \ -lgnunetutil \
-lz -lz
taler_wire_auditor_SOURCES = \
taler-wire-auditor.c
taler_wire_auditor_LDADD = \
$(LIBGCRYPT_LIBS) \
$(top_builddir)/src/util/libtalerutil.la \
$(top_builddir)/src/json/libtalerjson.la \
$(top_builddir)/src/bank-lib/libtalerbank.la \
$(top_builddir)/src/exchangedb/libtalerexchangedb.la \
$(top_builddir)/src/auditordb/libtalerauditordb.la \
-ljansson \
-lgnunetjson \
-lgnunetcurl \
-lgnunetutil
taler_auditor_sign_SOURCES = \ taler_auditor_sign_SOURCES = \
taler-auditor-sign.c taler-auditor-sign.c
taler_auditor_sign_LDADD = \ taler_auditor_sign_LDADD = \

View File

@ -22,49 +22,49 @@
#include "report-lib.h" #include "report-lib.h"
/** /**
* Command-line option "-r": restart audit from scratch * Command-line option "-r": TALER_ARL_restart audit from scratch
*/ */
int restart; int TALER_ARL_restart;
/** /**
* Handle to access the exchange's database. * Handle to access the exchange's database.
*/ */
struct TALER_EXCHANGEDB_Plugin *edb; struct TALER_EXCHANGEDB_Plugin *TALER_ARL_edb;
/** /**
* Which currency are we doing the audit for? * Which TALER_ARL_currency are we doing the audit for?
*/ */
char *currency; char *TALER_ARL_currency;
/** /**
* How many fractional digits does the currency use? * How many fractional digits does the TALER_ARL_currency use?
*/ */
struct TALER_Amount currency_round_unit; struct TALER_Amount TALER_ARL_currency_round_unit;
/** /**
* Our configuration. * Our configuration.
*/ */
const struct GNUNET_CONFIGURATION_Handle *cfg; const struct GNUNET_CONFIGURATION_Handle *TALER_ARL_cfg;
/** /**
* Our session with the #edb. * Our session with the #TALER_ARL_edb.
*/ */
struct TALER_EXCHANGEDB_Session *esession; struct TALER_EXCHANGEDB_Session *TALER_ARL_esession;
/** /**
* Handle to access the auditor's database. * Handle to access the auditor's database.
*/ */
struct TALER_AUDITORDB_Plugin *adb; struct TALER_AUDITORDB_Plugin *TALER_ARL_adb;
/** /**
* Our session with the #adb. * Our session with the #TALER_ARL_adb.
*/ */
struct TALER_AUDITORDB_Session *asession; struct TALER_AUDITORDB_Session *TALER_ARL_asession;
/** /**
* Master public key of the exchange to audit. * Master public key of the exchange to audit.
*/ */
struct TALER_MasterPublicKeyP master_pub; struct TALER_MasterPublicKeyP TALER_ARL_master_pub;
/** /**
* At what time did the auditor process start? * At what time did the auditor process start?
@ -85,7 +85,7 @@ static struct GNUNET_CONTAINER_MultiHashMap *denominations;
* @return human-readable string representing the time * @return human-readable string representing the time
*/ */
json_t * json_t *
json_from_time_abs_nbo (struct GNUNET_TIME_AbsoluteNBO at) TALER_ARL_TALER_ARL_json_from_time_abs_nbo (struct GNUNET_TIME_AbsoluteNBO at)
{ {
return json_string return json_string
(GNUNET_STRINGS_absolute_time_to_string (GNUNET_STRINGS_absolute_time_to_string
@ -100,7 +100,7 @@ json_from_time_abs_nbo (struct GNUNET_TIME_AbsoluteNBO at)
* @return human-readable string representing the time * @return human-readable string representing the time
*/ */
json_t * json_t *
json_from_time_abs (struct GNUNET_TIME_Absolute at) TALER_ARL_json_from_time_abs (struct GNUNET_TIME_Absolute at)
{ {
return json_string return json_string
(GNUNET_STRINGS_absolute_time_to_string (at)); (GNUNET_STRINGS_absolute_time_to_string (at));
@ -108,14 +108,14 @@ json_from_time_abs (struct GNUNET_TIME_Absolute at)
/** /**
* Add @a object to the report @a array. Fail hard if this fails. * Add @a object to the TALER_ARL_report @a array. Fail hard if this fails.
* *
* @param array report array to append @a object to * @param array TALER_ARL_report array to append @a object to
* @param object object to append, should be check that it is not NULL * @param object object to append, should be check that it is not NULL
*/ */
void void
report (json_t *array, TALER_ARL_report (json_t *array,
json_t *object) json_t *object)
{ {
GNUNET_assert (NULL != object); GNUNET_assert (NULL != object);
GNUNET_assert (0 == GNUNET_assert (0 ==
@ -185,9 +185,9 @@ add_denomination (void *cls,
* @return transaction status code * @return transaction status code
*/ */
enum GNUNET_DB_QueryStatus enum GNUNET_DB_QueryStatus
get_denomination_info_by_hash (const struct GNUNET_HashCode *dh, TALER_ARL_get_denomination_info_by_hash (const struct GNUNET_HashCode *dh,
const struct const struct
TALER_DenominationKeyValidityPS **issue) TALER_DenominationKeyValidityPS **issue)
{ {
const struct TALER_DenominationKeyValidityPS *i; const struct TALER_DenominationKeyValidityPS *i;
enum GNUNET_DB_QueryStatus qs; enum GNUNET_DB_QueryStatus qs;
@ -196,11 +196,11 @@ get_denomination_info_by_hash (const struct GNUNET_HashCode *dh,
{ {
denominations = GNUNET_CONTAINER_multihashmap_create (256, denominations = GNUNET_CONTAINER_multihashmap_create (256,
GNUNET_NO); GNUNET_NO);
qs = adb->select_denomination_info (adb->cls, qs = TALER_ARL_adb->select_denomination_info (TALER_ARL_adb->cls,
asession, TALER_ARL_asession,
&master_pub, &TALER_ARL_master_pub,
&add_denomination, &add_denomination,
NULL); NULL);
if (0 > qs) if (0 > qs)
{ {
*issue = NULL; *issue = NULL;
@ -216,11 +216,11 @@ get_denomination_info_by_hash (const struct GNUNET_HashCode *dh,
return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT; return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
} }
/* maybe database changed since we last iterated, give it one more shot */ /* maybe database changed since we last iterated, give it one more shot */
qs = adb->select_denomination_info (adb->cls, qs = TALER_ARL_adb->select_denomination_info (TALER_ARL_adb->cls,
asession, TALER_ARL_asession,
&master_pub, &TALER_ARL_master_pub,
&add_denomination, &add_denomination,
NULL); NULL);
if (qs <= 0) if (qs <= 0)
{ {
if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
@ -255,10 +255,11 @@ get_denomination_info_by_hash (const struct GNUNET_HashCode *dh,
* @return transaction status code * @return transaction status code
*/ */
enum GNUNET_DB_QueryStatus enum GNUNET_DB_QueryStatus
get_denomination_info (const struct TALER_DenominationPublicKey *denom_pub, TALER_ARL_get_denomination_info (const struct
const struct TALER_DenominationPublicKey *denom_pub,
TALER_DenominationKeyValidityPS **issue, const struct
struct GNUNET_HashCode *dh) TALER_DenominationKeyValidityPS **issue,
struct GNUNET_HashCode *dh)
{ {
struct GNUNET_HashCode hc; struct GNUNET_HashCode hc;
@ -266,8 +267,8 @@ get_denomination_info (const struct TALER_DenominationPublicKey *denom_pub,
dh = &hc; dh = &hc;
GNUNET_CRYPTO_rsa_public_key_hash (denom_pub->rsa_public_key, GNUNET_CRYPTO_rsa_public_key_hash (denom_pub->rsa_public_key,
dh); dh);
return get_denomination_info_by_hash (dh, return TALER_ARL_get_denomination_info_by_hash (dh,
issue); issue);
} }
@ -281,25 +282,25 @@ get_denomination_info (const struct TALER_DenominationPublicKey *denom_pub,
* #GNUNET_NO if we had an error on commit (retry may help) * #GNUNET_NO if we had an error on commit (retry may help)
* #GNUNET_SYSERR on hard errors * #GNUNET_SYSERR on hard errors
*/ */
int static int
transact (Analysis analysis, transact (TALER_ARL_Analysis analysis,
void *analysis_cls) void *analysis_cls)
{ {
int ret; int ret;
enum GNUNET_DB_QueryStatus qs; enum GNUNET_DB_QueryStatus qs;
ret = adb->start (adb->cls, ret = TALER_ARL_adb->start (TALER_ARL_adb->cls,
asession); TALER_ARL_asession);
if (GNUNET_OK != ret) if (GNUNET_OK != ret)
{ {
GNUNET_break (0); GNUNET_break (0);
return GNUNET_SYSERR; return GNUNET_SYSERR;
} }
edb->preflight (edb->cls, TALER_ARL_edb->preflight (TALER_ARL_edb->cls,
esession); TALER_ARL_esession);
ret = edb->start (edb->cls, ret = TALER_ARL_edb->start (TALER_ARL_edb->cls,
esession, TALER_ARL_esession,
"auditor"); "auditor");
if (GNUNET_OK != ret) if (GNUNET_OK != ret)
{ {
GNUNET_break (0); GNUNET_break (0);
@ -308,20 +309,20 @@ transact (Analysis analysis,
qs = analysis (analysis_cls); qs = analysis (analysis_cls);
if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs) if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs)
{ {
qs = edb->commit (edb->cls, qs = TALER_ARL_edb->commit (TALER_ARL_edb->cls,
esession); TALER_ARL_esession);
if (0 > qs) if (0 > qs)
{ {
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
GNUNET_log (GNUNET_ERROR_TYPE_ERROR, GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Exchange DB commit failed, rolling back transaction\n"); "Exchange DB commit failed, rolling back transaction\n");
adb->rollback (adb->cls, TALER_ARL_adb->rollback (TALER_ARL_adb->cls,
asession); TALER_ARL_asession);
} }
else else
{ {
qs = adb->commit (adb->cls, qs = TALER_ARL_adb->commit (TALER_ARL_adb->cls,
asession); TALER_ARL_asession);
if (0 > qs) if (0 > qs)
{ {
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
@ -334,10 +335,10 @@ transact (Analysis analysis,
{ {
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Processing failed (or no changes), rolling back transaction\n"); "Processing failed (or no changes), rolling back transaction\n");
adb->rollback (adb->cls, TALER_ARL_adb->rollback (TALER_ARL_adb->cls,
asession); TALER_ARL_asession);
edb->rollback (edb->cls, TALER_ARL_edb->rollback (TALER_ARL_edb->cls,
esession); TALER_ARL_esession);
} }
switch (qs) switch (qs)
{ {
@ -362,18 +363,18 @@ transact (Analysis analysis,
* @return #GNUNET_OK on success * @return #GNUNET_OK on success
*/ */
int int
setup_sessions_and_run (Analysis ana, TALER_ARL_setup_sessions_and_run (TALER_ARL_Analysis ana,
void *ana_cls) void *ana_cls)
{ {
esession = edb->get_session (edb->cls); TALER_ARL_esession = TALER_ARL_edb->get_session (TALER_ARL_edb->cls);
if (NULL == esession) if (NULL == TALER_ARL_esession)
{ {
fprintf (stderr, fprintf (stderr,
"Failed to initialize exchange session.\n"); "Failed to initialize exchange session.\n");
return GNUNET_SYSERR; return GNUNET_SYSERR;
} }
asession = adb->get_session (adb->cls); TALER_ARL_asession = TALER_ARL_adb->get_session (TALER_ARL_adb->cls);
if (NULL == asession) if (NULL == TALER_ARL_asession)
{ {
fprintf (stderr, fprintf (stderr,
"Failed to initialize auditor session.\n"); "Failed to initialize auditor session.\n");
@ -388,7 +389,7 @@ setup_sessions_and_run (Analysis ana,
/** /**
* Test if the given @a mpub matches the #master_pub. * Test if the given @a mpub matches the #TALER_ARL_master_pub.
* If so, set "found" to GNUNET_YES. * If so, set "found" to GNUNET_YES.
* *
* @param cls a `int *` pointing to "found" * @param cls a `int *` pointing to "found"
@ -404,29 +405,35 @@ test_master_present (void *cls,
(void) exchange_url; (void) exchange_url;
if (0 == GNUNET_memcmp (mpub, if (0 == GNUNET_memcmp (mpub,
&master_pub)) &TALER_ARL_master_pub))
*found = GNUNET_YES; *found = GNUNET_YES;
} }
/**
* Setup global variables based on configuration.
*
* @param c configuration to use
* @return #GNUNET_OK on success
*/
int int
setup_globals (const struct GNUNET_CONFIGURATION_Handle *c) TALER_ARL_init (const struct GNUNET_CONFIGURATION_Handle *c)
{ {
int found; int found;
struct TALER_AUDITORDB_Session *as; struct TALER_AUDITORDB_Session *as;
cfg = c; TALER_ARL_cfg = c;
start_time = GNUNET_TIME_absolute_get (); start_time = GNUNET_TIME_absolute_get ();
if (0 == GNUNET_is_zero (&master_pub)) if (0 == GNUNET_is_zero (&TALER_ARL_master_pub))
{ {
/* -m option not given, try configuration */ /* -m option not given, try configuration */
char *master_public_key_str; char *TALER_ARL_master_public_key_str;
if (GNUNET_OK != if (GNUNET_OK !=
GNUNET_CONFIGURATION_get_value_string (cfg, GNUNET_CONFIGURATION_get_value_string (TALER_ARL_cfg,
"exchange", "exchange",
"MASTER_PUBLIC_KEY", "MASTER_PUBLIC_KEY",
&master_public_key_str)) &TALER_ARL_master_public_key_str))
{ {
fprintf (stderr, fprintf (stderr,
"Pass option -m or set it in the configuration!\n"); "Pass option -m or set it in the configuration!\n");
@ -436,35 +443,37 @@ setup_globals (const struct GNUNET_CONFIGURATION_Handle *c)
return GNUNET_SYSERR; return GNUNET_SYSERR;
} }
if (GNUNET_OK != if (GNUNET_OK !=
GNUNET_CRYPTO_eddsa_public_key_from_string (master_public_key_str, GNUNET_CRYPTO_eddsa_public_key_from_string (
strlen ( TALER_ARL_master_public_key_str,
master_public_key_str), strlen (
&master_pub.eddsa_pub)) TALER_ARL_master_public_key_str),
&TALER_ARL_master_pub.
eddsa_pub))
{ {
fprintf (stderr, fprintf (stderr,
"Invalid master public key given in configuration file."); "Invalid master public key given in configuration file.");
GNUNET_free (master_public_key_str); GNUNET_free (TALER_ARL_master_public_key_str);
return GNUNET_SYSERR; return GNUNET_SYSERR;
} }
GNUNET_free (master_public_key_str); GNUNET_free (TALER_ARL_master_public_key_str);
} /* end of -m not given */ } /* end of -m not given */
GNUNET_log (GNUNET_ERROR_TYPE_INFO, GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Taler auditor running for exchange master public key %s\n", "Taler auditor running for exchange master public key %s\n",
TALER_B2S (&master_pub)); TALER_B2S (&TALER_ARL_master_pub));
if (GNUNET_OK != if (GNUNET_OK !=
TALER_config_get_currency (cfg, TALER_config_get_currency (TALER_ARL_cfg,
&currency)) &TALER_ARL_currency))
{ {
return GNUNET_SYSERR; return GNUNET_SYSERR;
} }
{ {
if (GNUNET_OK != if (GNUNET_OK !=
TALER_config_get_amount (cfg, TALER_config_get_amount (TALER_ARL_cfg,
"taler", "taler",
"CURRENCY_ROUND_UNIT", "CURRENCY_ROUND_UNIT",
&currency_round_unit)) &TALER_ARL_currency_round_unit))
{ {
GNUNET_log (GNUNET_ERROR_TYPE_ERROR, GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Invalid or missing amount in `TALER' under `CURRENCY_ROUND_UNIT'\n"); "Invalid or missing amount in `TALER' under `CURRENCY_ROUND_UNIT'\n");
@ -472,78 +481,86 @@ setup_globals (const struct GNUNET_CONFIGURATION_Handle *c)
} }
} }
if (NULL == if (NULL ==
(edb = TALER_EXCHANGEDB_plugin_load (cfg))) (TALER_ARL_edb = TALER_EXCHANGEDB_plugin_load (TALER_ARL_cfg)))
{ {
fprintf (stderr, fprintf (stderr,
"Failed to initialize exchange database plugin.\n"); "Failed to initialize exchange database plugin.\n");
return GNUNET_SYSERR; return GNUNET_SYSERR;
} }
if (NULL == if (NULL ==
(adb = TALER_AUDITORDB_plugin_load (cfg))) (TALER_ARL_adb = TALER_AUDITORDB_plugin_load (TALER_ARL_cfg)))
{ {
fprintf (stderr, fprintf (stderr,
"Failed to initialize auditor database plugin.\n"); "Failed to initialize auditor database plugin.\n");
TALER_EXCHANGEDB_plugin_unload (edb); TALER_EXCHANGEDB_plugin_unload (TALER_ARL_edb);
return GNUNET_SYSERR; return GNUNET_SYSERR;
} }
found = GNUNET_NO; found = GNUNET_NO;
as = adb->get_session (adb->cls); as = TALER_ARL_adb->get_session (TALER_ARL_adb->cls);
if (NULL == as) if (NULL == as)
{ {
fprintf (stderr, fprintf (stderr,
"Failed to start session with auditor database.\n"); "Failed to start session with auditor database.\n");
TALER_AUDITORDB_plugin_unload (adb); TALER_AUDITORDB_plugin_unload (TALER_ARL_adb);
TALER_EXCHANGEDB_plugin_unload (edb); TALER_EXCHANGEDB_plugin_unload (TALER_ARL_edb);
return GNUNET_SYSERR; return GNUNET_SYSERR;
} }
(void) adb->list_exchanges (adb->cls, (void) TALER_ARL_adb->list_exchanges (TALER_ARL_adb->cls,
as, as,
&test_master_present, &test_master_present,
&found); &found);
if (GNUNET_NO == found) if (GNUNET_NO == found)
{ {
fprintf (stderr, fprintf (stderr,
"Exchange's master public key `%s' not known to auditor DB. Did you forget to run `taler-auditor-exchange`?\n", "Exchange's master public key `%s' not known to auditor DB. Did you forget to run `taler-auditor-exchange`?\n",
GNUNET_p2s (&master_pub.eddsa_pub)); GNUNET_p2s (&TALER_ARL_master_pub.eddsa_pub));
TALER_AUDITORDB_plugin_unload (adb); TALER_AUDITORDB_plugin_unload (TALER_ARL_adb);
TALER_EXCHANGEDB_plugin_unload (edb); TALER_EXCHANGEDB_plugin_unload (TALER_ARL_edb);
return GNUNET_SYSERR; return GNUNET_SYSERR;
} }
if (restart) if (TALER_ARL_restart)
{ {
GNUNET_log (GNUNET_ERROR_TYPE_WARNING, GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
"Full audit restart requested, dropping old audit data.\n"); "Full audit TALER_ARL_restart requested, dropping old audit data.\n");
GNUNET_break (GNUNET_OK == GNUNET_break (GNUNET_OK ==
adb->drop_tables (adb->cls, TALER_ARL_adb->drop_tables (TALER_ARL_adb->cls,
GNUNET_NO)); GNUNET_NO));
TALER_AUDITORDB_plugin_unload (adb); TALER_AUDITORDB_plugin_unload (TALER_ARL_adb);
if (NULL == if (NULL ==
(adb = TALER_AUDITORDB_plugin_load (cfg))) (TALER_ARL_adb = TALER_AUDITORDB_plugin_load (TALER_ARL_cfg)))
{ {
fprintf (stderr, fprintf (stderr,
"Failed to initialize auditor database plugin after drop.\n"); "Failed to initialize auditor database plugin after drop.\n");
TALER_EXCHANGEDB_plugin_unload (edb); TALER_EXCHANGEDB_plugin_unload (TALER_ARL_edb);
return GNUNET_SYSERR; return GNUNET_SYSERR;
} }
GNUNET_break (GNUNET_OK == GNUNET_break (GNUNET_OK ==
adb->create_tables (adb->cls)); TALER_ARL_adb->create_tables (TALER_ARL_adb->cls));
} }
return GNUNET_OK; return GNUNET_OK;
} }
/**
* Generate the report and close connectios to the database.
*
* @param report the report to output, may be NULL for no report
*/
void void
finish_report (json_t *report) TALER_ARL_done (json_t *report)
{ {
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 (TALER_ARL_adb);
adb = NULL; TALER_ARL_adb = NULL;
TALER_EXCHANGEDB_plugin_unload (edb); TALER_EXCHANGEDB_plugin_unload (TALER_ARL_edb);
edb = NULL; TALER_ARL_edb = NULL;
json_dumpf (report, if (NULL != report)
stdout, {
JSON_INDENT (2)); json_dumpf (report,
json_decref (report); stdout,
JSON_INDENT (2));
json_decref (report);
}
} }

View File

@ -30,49 +30,49 @@
/** /**
* Command-line option "-r": restart audit from scratch * Command-line option "-r": TALER_ARL_restart audit from scratch
*/ */
extern int restart; extern int TALER_ARL_restart;
/** /**
* Handle to access the exchange's database. * Handle to access the exchange's database.
*/ */
extern struct TALER_EXCHANGEDB_Plugin *edb; extern struct TALER_EXCHANGEDB_Plugin *TALER_ARL_edb;
/** /**
* Which currency are we doing the audit for? * Which TALER_ARL_currency are we doing the audit for?
*/ */
extern char *currency; extern char *TALER_ARL_currency;
/** /**
* How many fractional digits does the currency use? * How many fractional digits does the TALER_ARL_currency use?
*/ */
extern struct TALER_Amount currency_round_unit; extern struct TALER_Amount TALER_ARL_currency_round_unit;
/** /**
* Our configuration. * Our configuration.
*/ */
extern const struct GNUNET_CONFIGURATION_Handle *cfg; extern const struct GNUNET_CONFIGURATION_Handle *TALER_ARL_cfg;
/** /**
* Our session with the #edb. * Our session with the #TALER_ARL_edb.
*/ */
extern struct TALER_EXCHANGEDB_Session *esession; extern struct TALER_EXCHANGEDB_Session *TALER_ARL_esession;
/** /**
* Handle to access the auditor's database. * Handle to access the auditor's database.
*/ */
extern struct TALER_AUDITORDB_Plugin *adb; extern struct TALER_AUDITORDB_Plugin *TALER_ARL_adb;
/** /**
* Our session with the #adb. * Our session with the #TALER_ARL_adb.
*/ */
extern struct TALER_AUDITORDB_Session *asession; extern struct TALER_AUDITORDB_Session *TALER_ARL_asession;
/** /**
* Master public key of the exchange to audit. * Master public key of the exchange to audit.
*/ */
extern struct TALER_MasterPublicKeyP master_pub; extern struct TALER_MasterPublicKeyP TALER_ARL_master_pub;
/** /**
* At what time did the auditor process start? * At what time did the auditor process start?
@ -87,7 +87,7 @@ extern struct GNUNET_TIME_Absolute start_time;
* @return human-readable string representing the time * @return human-readable string representing the time
*/ */
json_t * json_t *
json_from_time_abs_nbo (struct GNUNET_TIME_AbsoluteNBO at); TALER_ARL_TALER_ARL_json_from_time_abs_nbo (struct GNUNET_TIME_AbsoluteNBO at);
/** /**
@ -97,18 +97,18 @@ json_from_time_abs_nbo (struct GNUNET_TIME_AbsoluteNBO at);
* @return human-readable string representing the time * @return human-readable string representing the time
*/ */
json_t * json_t *
json_from_time_abs (struct GNUNET_TIME_Absolute at); TALER_ARL_json_from_time_abs (struct GNUNET_TIME_Absolute at);
/** /**
* Add @a object to the report @a array. Fail hard if this fails. * Add @a object to the TALER_ARL_report @a array. Fail hard if this fails.
* *
* @param array report array to append @a object to * @param array TALER_ARL_report array to append @a object to
* @param object object to append, should be check that it is not NULL * @param object object to append, should be check that it is not NULL
*/ */
void void
report (json_t *array, TALER_ARL_report (json_t *array,
json_t *object); json_t *object);
/** /**
@ -117,10 +117,10 @@ report (json_t *array,
* @param dh hash of the denomination public key to look up * @param dh hash of the denomination public key to look up
* @param[out] issue set to detailed information about @a denom_pub, NULL if not found, must * @param[out] issue set to detailed information about @a denom_pub, NULL if not found, must
* NOT be freed by caller * NOT be freed by caller
* @return transaction status code * @return TALER_ARL_transaction status code
*/ */
enum GNUNET_DB_QueryStatus enum GNUNET_DB_QueryStatus
get_denomination_info_by_hash ( TALER_ARL_get_denomination_info_by_hash (
const struct GNUNET_HashCode *dh, const struct GNUNET_HashCode *dh,
const struct TALER_DenominationKeyValidityPS **issue); const struct TALER_DenominationKeyValidityPS **issue);
@ -132,14 +132,15 @@ get_denomination_info_by_hash (
* @param[out] issue set to detailed information about @a denom_pub, NULL if not found, must * @param[out] issue set to detailed information about @a denom_pub, NULL if not found, must
* NOT be freed by caller * NOT be freed by caller
* @param[out] dh set to the hash of @a denom_pub, may be NULL * @param[out] dh set to the hash of @a denom_pub, may be NULL
* @return transaction status code * @return TALER_ARL_transaction status code
*/ */
enum GNUNET_DB_QueryStatus enum GNUNET_DB_QueryStatus
get_denomination_info ( TALER_ARL_get_denomination_info (
const struct TALER_DenominationPublicKey *denom_pub, const struct TALER_DenominationPublicKey *denom_pub,
const struct TALER_DenominationKeyValidityPS **issue, const struct TALER_DenominationKeyValidityPS **issue,
struct GNUNET_HashCode *dh); struct GNUNET_HashCode *dh);
/** /**
* Type of an analysis function. Each analysis function runs in * Type of an analysis function. Each analysis function runs in
* its own transaction scope and must thus be internally consistent. * its own transaction scope and must thus be internally consistent.
@ -148,22 +149,7 @@ get_denomination_info (
* @return transaction status code * @return transaction status code
*/ */
typedef enum GNUNET_DB_QueryStatus typedef enum GNUNET_DB_QueryStatus
(*Analysis)(void *cls); (*TALER_ARL_Analysis)(void *cls);
/**
* Perform the given @a analysis within a transaction scope.
* Commit on success.
*
* @param analysis analysis to run
* @param analysis_cls closure for @a analysis
* @return #GNUNET_OK if @a analysis succeessfully committed,
* #GNUNET_NO if we had an error on commit (retry may help)
* #GNUNET_SYSERR on hard errors
*/
int
transact (Analysis analysis,
void *analysis_cls);
/** /**
@ -174,15 +160,26 @@ transact (Analysis analysis,
* @return #GNUNET_OK on success * @return #GNUNET_OK on success
*/ */
int int
setup_sessions_and_run (Analysis ana, TALER_ARL_setup_sessions_and_run (TALER_ARL_Analysis ana,
void *ana_cls); void *ana_cls);
/**
* Setup global variables based on configuration.
*
* @param c configuration to use
* @return #GNUNET_OK on success
*/
int int
setup_globals (const struct GNUNET_CONFIGURATION_Handle *c); TALER_ARL_init (const struct GNUNET_CONFIGURATION_Handle *c);
/**
* Generate the report and close connectios to the database.
*
* @param report the report to output, may be NULL for no report
*/
void void
finish_report (json_t *report); TALER_ARL_done (json_t *report);
#endif #endif

View File

@ -14,7 +14,7 @@
TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/ */
/** /**
* @file auditor/taler-auditor-aggregation.c * @file auditor/taler-helper-auditor-aggregation.c
* @brief audits an exchange's aggregations. * @brief audits an exchange's aggregations.
* @author Christian Grothoff * @author Christian Grothoff
*/ */
@ -133,8 +133,10 @@ static struct TALER_Amount total_bad_sig_loss;
static void static void
report_amount_arithmetic_inconsistency (const char *operation, report_amount_arithmetic_inconsistency (const char *operation,
uint64_t rowid, uint64_t rowid,
const struct TALER_Amount *exchange, const struct
const struct TALER_Amount *auditor, TALER_Amount *exchange,
const struct
TALER_Amount *auditor,
int profitable) int profitable)
{ {
struct TALER_Amount delta; struct TALER_Amount delta;
@ -158,13 +160,13 @@ report_amount_arithmetic_inconsistency (const char *operation,
auditor, auditor,
exchange)); exchange));
} }
report (report_amount_arithmetic_inconsistencies, TALER_ARL_report (report_amount_arithmetic_inconsistencies,
json_pack ("{s:s, s:I, s:o, s:o, s:I}", json_pack ("{s:s, s:I, s:o, s:o, s:I}",
"operation", operation, "operation", operation,
"rowid", (json_int_t) rowid, "rowid", (json_int_t) rowid,
"exchange", TALER_JSON_from_amount (exchange), "exchange", TALER_JSON_from_amount (exchange),
"auditor", TALER_JSON_from_amount (auditor), "auditor", TALER_JSON_from_amount (auditor),
"profitable", (json_int_t) profitable)); "profitable", (json_int_t) profitable));
if (0 != profitable) if (0 != profitable)
{ {
target = (1 == profitable) target = (1 == profitable)
@ -194,9 +196,12 @@ report_amount_arithmetic_inconsistency (const char *operation,
static void static void
report_coin_arithmetic_inconsistency (const char *operation, report_coin_arithmetic_inconsistency (const char *operation,
const struct const struct
TALER_CoinSpendPublicKeyP *coin_pub, TALER_CoinSpendPublicKeyP *
const struct TALER_Amount *exchange, coin_pub,
const struct TALER_Amount *auditor, const struct
TALER_Amount *exchange,
const struct
TALER_Amount *auditor,
int profitable) int profitable)
{ {
struct TALER_Amount delta; struct TALER_Amount delta;
@ -220,13 +225,14 @@ report_coin_arithmetic_inconsistency (const char *operation,
auditor, auditor,
exchange)); exchange));
} }
report (report_coin_inconsistencies, TALER_ARL_report (report_coin_inconsistencies,
json_pack ("{s:s, s:o, s:o, s:o, s:I}", json_pack ("{s:s, s:o, s:o, s:o, s:I}",
"operation", operation, "operation", operation,
"coin_pub", GNUNET_JSON_from_data_auto (coin_pub), "coin_pub", GNUNET_JSON_from_data_auto (
"exchange", TALER_JSON_from_amount (exchange), coin_pub),
"auditor", TALER_JSON_from_amount (auditor), "exchange", TALER_JSON_from_amount (exchange),
"profitable", (json_int_t) profitable)); "auditor", TALER_JSON_from_amount (auditor),
"profitable", (json_int_t) profitable));
if (0 != profitable) if (0 != profitable)
{ {
target = (1 == profitable) target = (1 == profitable)
@ -252,11 +258,11 @@ report_row_inconsistency (const char *table,
uint64_t rowid, uint64_t rowid,
const char *diagnostic) const char *diagnostic)
{ {
report (report_row_inconsistencies, TALER_ARL_report (report_row_inconsistencies,
json_pack ("{s:s, s:I, s:s}", json_pack ("{s:s, s:I, s:s}",
"table", table, "table", table,
"row", (json_int_t) rowid, "row", (json_int_t) rowid,
"diagnostic", diagnostic)); "diagnostic", diagnostic));
} }
@ -368,7 +374,7 @@ 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 reporting) * @param coin_pub public key of the coin (for TALER_ARL_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
@ -379,17 +385,24 @@ struct WireCheckContext
*/ */
static int static int
check_transaction_history_for_deposit (const struct check_transaction_history_for_deposit (const struct
TALER_CoinSpendPublicKeyP *coin_pub, TALER_CoinSpendPublicKeyP *
coin_pub,
const struct const struct
GNUNET_HashCode *h_contract_terms, GNUNET_HashCode *
h_contract_terms,
const struct const struct
TALER_MerchantPublicKeyP *merchant_pub, TALER_MerchantPublicKeyP *
merchant_pub,
const struct const struct
TALER_DenominationKeyValidityPS *issue, TALER_DenominationKeyValidityPS
*issue,
const struct const struct
TALER_EXCHANGEDB_TransactionList *tl_head, TALER_EXCHANGEDB_TransactionList
struct TALER_Amount *merchant_gain, *tl_head,
struct TALER_Amount *deposit_gain) struct TALER_Amount *
merchant_gain,
struct TALER_Amount *
deposit_gain)
{ {
struct TALER_Amount expenditures; struct TALER_Amount expenditures;
struct TALER_Amount refunds; struct TALER_Amount refunds;
@ -406,16 +419,16 @@ check_transaction_history_for_deposit (const struct
GNUNET_assert (NULL != tl_head); GNUNET_assert (NULL != tl_head);
GNUNET_assert (GNUNET_OK == GNUNET_assert (GNUNET_OK ==
TALER_amount_get_zero (currency, TALER_amount_get_zero (TALER_ARL_currency,
&expenditures)); &expenditures));
GNUNET_assert (GNUNET_OK == GNUNET_assert (GNUNET_OK ==
TALER_amount_get_zero (currency, TALER_amount_get_zero (TALER_ARL_currency,
&refunds)); &refunds));
GNUNET_assert (GNUNET_OK == GNUNET_assert (GNUNET_OK ==
TALER_amount_get_zero (currency, TALER_amount_get_zero (TALER_ARL_currency,
merchant_gain)); merchant_gain));
GNUNET_assert (GNUNET_OK == GNUNET_assert (GNUNET_OK ==
TALER_amount_get_zero (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
know the order, so instead of subtracting we compute positive know the order, so instead of subtracting we compute positive
@ -762,11 +775,11 @@ wire_transfer_information_cb (
} }
/* Obtain coin's transaction history */ /* Obtain coin's transaction history */
qs = edb->get_coin_transactions (edb->cls, qs = TALER_ARL_edb->get_coin_transactions (TALER_ARL_edb->cls,
esession, TALER_ARL_esession,
coin_pub, coin_pub,
GNUNET_YES, GNUNET_YES,
&tl); &tl);
if ( (qs < 0) || if ( (qs < 0) ||
(NULL == tl) ) (NULL == tl) )
{ {
@ -776,10 +789,10 @@ wire_transfer_information_cb (
"no transaction history for coin claimed in aggregation"); "no transaction history for coin claimed in aggregation");
return; return;
} }
qs = edb->get_known_coin (edb->cls, qs = TALER_ARL_edb->get_known_coin (TALER_ARL_edb->cls,
esession, TALER_ARL_esession,
coin_pub, coin_pub,
&coin); &coin);
if (qs < 0) if (qs < 0)
{ {
GNUNET_break (0); /* this should be a foreign key violation at this point! */ GNUNET_break (0); /* this should be a foreign key violation at this point! */
@ -790,13 +803,13 @@ wire_transfer_information_cb (
return; return;
} }
qs = get_denomination_info_by_hash (&coin.denom_pub_hash, qs = TALER_ARL_get_denomination_info_by_hash (&coin.denom_pub_hash,
&issue); &issue);
if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs) if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs)
{ {
GNUNET_CRYPTO_rsa_signature_free (coin.denom_sig.rsa_signature); GNUNET_CRYPTO_rsa_signature_free (coin.denom_sig.rsa_signature);
edb->free_coin_transaction_list (edb->cls, TALER_ARL_edb->free_coin_transaction_list (TALER_ARL_edb->cls,
tl); tl);
if (0 == qs) if (0 == qs)
report_row_inconsistency ("aggregation", report_row_inconsistency ("aggregation",
rowid, rowid,
@ -809,20 +822,20 @@ wire_transfer_information_cb (
TALER_test_coin_valid (&coin, TALER_test_coin_valid (&coin,
denom_pub)) denom_pub))
{ {
report (report_bad_sig_losses, TALER_ARL_report (report_bad_sig_losses,
json_pack ("{s:s, s:I, s:o, s:o}", json_pack ("{s:s, s:I, s:o, s:o}",
"operation", "wire", "operation", "wire",
"row", (json_int_t) rowid, "row", (json_int_t) rowid,
"loss", TALER_JSON_from_amount (coin_value), "loss", TALER_JSON_from_amount (coin_value),
"key_pub", GNUNET_JSON_from_data_auto ( "key_pub", GNUNET_JSON_from_data_auto (
&issue->denom_hash))); &issue->denom_hash)));
GNUNET_break (GNUNET_OK == GNUNET_break (GNUNET_OK ==
TALER_amount_add (&total_bad_sig_loss, TALER_amount_add (&total_bad_sig_loss,
&total_bad_sig_loss, &total_bad_sig_loss,
coin_value)); coin_value));
GNUNET_CRYPTO_rsa_signature_free (coin.denom_sig.rsa_signature); GNUNET_CRYPTO_rsa_signature_free (coin.denom_sig.rsa_signature);
edb->free_coin_transaction_list (edb->cls, TALER_ARL_edb->free_coin_transaction_list (TALER_ARL_edb->cls,
tl); tl);
wcc->qs = GNUNET_DB_STATUS_HARD_ERROR; wcc->qs = GNUNET_DB_STATUS_HARD_ERROR;
report_row_inconsistency ("deposit", report_row_inconsistency ("deposit",
rowid, rowid,
@ -841,7 +854,8 @@ wire_transfer_information_cb (
issue, issue,
tl, tl,
&computed_value, &computed_value,
&total_deposit_without_refunds)) &
total_deposit_without_refunds))
{ {
wcc->qs = GNUNET_DB_STATUS_HARD_ERROR; wcc->qs = GNUNET_DB_STATUS_HARD_ERROR;
report_row_inconsistency ("coin history", report_row_inconsistency ("coin history",
@ -858,11 +872,12 @@ wire_transfer_information_cb (
deposit_fee)) deposit_fee))
{ {
wcc->qs = GNUNET_DB_STATUS_HARD_ERROR; wcc->qs = GNUNET_DB_STATUS_HARD_ERROR;
report_amount_arithmetic_inconsistency ("aggregation (fee structure)", report_amount_arithmetic_inconsistency (
rowid, "aggregation (fee structure)",
coin_value, rowid,
deposit_fee, coin_value,
-1); deposit_fee,
-1);
return; return;
} }
if (0 != if (0 !=
@ -873,14 +888,16 @@ wire_transfer_information_cb (
"Expected coin contribution of %s to aggregate\n", "Expected coin contribution of %s to aggregate\n",
TALER_amount2s (&coin_value_without_fee)); TALER_amount2s (&coin_value_without_fee));
wcc->qs = GNUNET_DB_STATUS_HARD_ERROR; wcc->qs = GNUNET_DB_STATUS_HARD_ERROR;
report_amount_arithmetic_inconsistency ("aggregation (contribution)", report_amount_arithmetic_inconsistency (
rowid, "aggregation (contribution)",
&coin_value_without_fee, rowid,
&total_deposit_without_refunds, &coin_value_without_fee,
-1); &
total_deposit_without_refunds,
-1);
} }
edb->free_coin_transaction_list (edb->cls, TALER_ARL_edb->free_coin_transaction_list (TALER_ARL_edb->cls,
tl); tl);
/* Check other details of wire transfer match */ /* Check other details of wire transfer match */
if (0 != GNUNET_memcmp (h_wire, if (0 != GNUNET_memcmp (h_wire,
@ -949,15 +966,15 @@ get_wire_fee (struct AggregationContext *ac,
/* Lookup fee in exchange database */ /* Lookup fee in exchange database */
wfi = GNUNET_new (struct WireFeeInfo); wfi = GNUNET_new (struct WireFeeInfo);
if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
edb->get_wire_fee (edb->cls, TALER_ARL_edb->get_wire_fee (TALER_ARL_edb->cls,
esession, TALER_ARL_esession,
method, method,
timestamp, timestamp,
&wfi->start_date, &wfi->start_date,
&wfi->end_date, &wfi->end_date,
&wfi->wire_fee, &wfi->wire_fee,
&wfi->closing_fee, &wfi->closing_fee,
&master_sig)) &master_sig))
{ {
GNUNET_break (0); GNUNET_break (0);
GNUNET_free (wfi); GNUNET_free (wfi);
@ -985,7 +1002,7 @@ get_wire_fee (struct AggregationContext *ac,
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MASTER_WIRE_FEES, GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MASTER_WIRE_FEES,
&wf.purpose, &wf.purpose,
&master_sig.eddsa_signature, &master_sig.eddsa_signature,
&master_pub.eddsa_pub)) &TALER_ARL_master_pub.eddsa_pub))
{ {
report_row_inconsistency ("wire-fee", report_row_inconsistency ("wire-fee",
timestamp.abs_value_us, timestamp.abs_value_us,
@ -1012,20 +1029,24 @@ get_wire_fee (struct AggregationContext *ac,
if ( (NULL != wfi->prev) && if ( (NULL != wfi->prev) &&
(wfi->prev->end_date.abs_value_us > wfi->start_date.abs_value_us) ) (wfi->prev->end_date.abs_value_us > wfi->start_date.abs_value_us) )
{ {
report (report_fee_time_inconsistencies, TALER_ARL_report (report_fee_time_inconsistencies,
json_pack ("{s:s, s:s, s:o}", json_pack ("{s:s, s:s, s:o}",
"type", method, "type", method,
"diagnostic", "start date before previous end date", "diagnostic",
"time", json_from_time_abs (wfi->start_date))); "start date before previous end date",
"time", TALER_ARL_json_from_time_abs (
wfi->start_date)));
} }
if ( (NULL != wfi->next) && if ( (NULL != wfi->next) &&
(wfi->next->start_date.abs_value_us >= wfi->end_date.abs_value_us) ) (wfi->next->start_date.abs_value_us >= wfi->end_date.abs_value_us) )
{ {
report (report_fee_time_inconsistencies, TALER_ARL_report (report_fee_time_inconsistencies,
json_pack ("{s:s, s:s, s:o}", json_pack ("{s:s, s:s, s:o}",
"type", method, "type", method,
"diagnostic", "end date date after next start date", "diagnostic",
"time", json_from_time_abs (wfi->end_date))); "end date date after next start date",
"time", TALER_ARL_json_from_time_abs (
wfi->end_date)));
} }
return &wfi->wire_fee; return &wfi->wire_fee;
} }
@ -1089,11 +1110,11 @@ check_wire_out_cb (void *cls,
GNUNET_free (method); GNUNET_free (method);
return GNUNET_SYSERR; return GNUNET_SYSERR;
} }
qs = edb->lookup_wire_transfer (edb->cls, qs = TALER_ARL_edb->lookup_wire_transfer (TALER_ARL_edb->cls,
esession, TALER_ARL_esession,
wtid, wtid,
&wire_transfer_information_cb, &wire_transfer_information_cb,
&wcc); &wcc);
if (0 > qs) if (0 > qs)
{ {
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
@ -1133,11 +1154,12 @@ check_wire_out_cb (void *cls,
&wcc.total_deposits, &wcc.total_deposits,
wire_fee)) wire_fee))
{ {
report_amount_arithmetic_inconsistency ("wire out (fee structure)", report_amount_arithmetic_inconsistency (
rowid, "wire out (fee structure)",
&wcc.total_deposits, rowid,
wire_fee, &wcc.total_deposits,
-1); wire_fee,
-1);
/* If fee arithmetic fails, we just assume the fee is zero */ /* If fee arithmetic fails, we just assume the fee is zero */
final_amount = wcc.total_deposits; final_amount = wcc.total_deposits;
} }
@ -1147,7 +1169,7 @@ check_wire_out_cb (void *cls,
/* Round down to amount supported by wire method */ /* Round down to amount supported by wire method */
GNUNET_break (GNUNET_SYSERR != GNUNET_break (GNUNET_SYSERR !=
TALER_amount_round_down (&final_amount, TALER_amount_round_down (&final_amount,
&currency_round_unit)); &TALER_ARL_currency_round_unit));
/* Calculate the exchange's gain as the fees plus rounding differences! */ /* Calculate the exchange's gain as the fees plus rounding differences! */
if (GNUNET_SYSERR == if (GNUNET_SYSERR ==
@ -1203,14 +1225,14 @@ check_wire_out_cb (void *cls,
&delta)); &delta));
} }
report (report_wire_out_inconsistencies, TALER_ARL_report (report_wire_out_inconsistencies,
json_pack ("{s:O, s:I, s:o, s:o}", json_pack ("{s:O, s:I, s:o, s:o}",
"destination_account", wire, "destination_account", wire,
"rowid", (json_int_t) rowid, "rowid", (json_int_t) rowid,
"expected", "expected",
TALER_JSON_from_amount (&final_amount), TALER_JSON_from_amount (&final_amount),
"claimed", "claimed",
TALER_JSON_from_amount (amount))); TALER_JSON_from_amount (amount)));
return GNUNET_OK; return GNUNET_OK;
} }
GNUNET_log (GNUNET_ERROR_TYPE_INFO, GNUNET_log (GNUNET_ERROR_TYPE_INFO,
@ -1238,10 +1260,10 @@ analyze_aggregations (void *cls)
(void) cls; (void) cls;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Analyzing aggregations\n"); "Analyzing aggregations\n");
qsp = adb->get_auditor_progress_aggregation (adb->cls, qsp = TALER_ARL_adb->get_auditor_progress_aggregation (TALER_ARL_adb->cls,
asession, TALER_ARL_asession,
&master_pub, &TALER_ARL_master_pub,
&ppa); &ppa);
if (0 > qsp) if (0 > qsp)
{ {
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qsp); GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qsp);
@ -1264,21 +1286,22 @@ analyze_aggregations (void *cls)
memset (&ac, memset (&ac,
0, 0,
sizeof (ac)); sizeof (ac));
qsx = adb->get_wire_fee_summary (adb->cls, qsx = TALER_ARL_adb->get_wire_fee_summary (TALER_ARL_adb->cls,
asession, TALER_ARL_asession,
&master_pub, &TALER_ARL_master_pub,
&total_aggregation_fee_income); &total_aggregation_fee_income);
if (0 > qsx) if (0 > qsx)
{ {
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qsx); GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qsx);
return qsx; return qsx;
} }
ac.qs = GNUNET_DB_STATUS_SUCCESS_ONE_RESULT; ac.qs = GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
qs = edb->select_wire_out_above_serial_id (edb->cls, qs = TALER_ARL_edb->select_wire_out_above_serial_id (TALER_ARL_edb->cls,
esession, TALER_ARL_esession,
ppa.last_wire_out_serial_id, ppa.
&check_wire_out_cb, last_wire_out_serial_id,
&ac); &check_wire_out_cb,
&ac);
if (0 > qs) if (0 > qs)
{ {
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
@ -1302,30 +1325,34 @@ analyze_aggregations (void *cls)
return ac.qs; return ac.qs;
} }
if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qsx) if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qsx)
ac.qs = adb->insert_wire_fee_summary (adb->cls, ac.qs = TALER_ARL_adb->insert_wire_fee_summary (TALER_ARL_adb->cls,
asession, TALER_ARL_asession,
&master_pub, &TALER_ARL_master_pub,
&total_aggregation_fee_income); &
total_aggregation_fee_income);
else else
ac.qs = adb->update_wire_fee_summary (adb->cls, ac.qs = TALER_ARL_adb->update_wire_fee_summary (TALER_ARL_adb->cls,
asession, TALER_ARL_asession,
&master_pub, &TALER_ARL_master_pub,
&total_aggregation_fee_income); &
total_aggregation_fee_income);
if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != ac.qs) if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != ac.qs)
{ {
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == ac.qs); GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == ac.qs);
return ac.qs; return ac.qs;
} }
if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qsp) if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qsp)
qs = adb->update_auditor_progress_aggregation (adb->cls, qs = TALER_ARL_adb->update_auditor_progress_aggregation (TALER_ARL_adb->cls,
asession, TALER_ARL_asession,
&master_pub, &
&ppa); TALER_ARL_master_pub,
&ppa);
else else
qs = adb->insert_auditor_progress_aggregation (adb->cls, qs = TALER_ARL_adb->insert_auditor_progress_aggregation (TALER_ARL_adb->cls,
asession, TALER_ARL_asession,
&master_pub, &
&ppa); TALER_ARL_master_pub,
&ppa);
if (0 >= qs) if (0 >= qs)
{ {
GNUNET_log (GNUNET_ERROR_TYPE_INFO, GNUNET_log (GNUNET_ERROR_TYPE_INFO,
@ -1346,24 +1373,24 @@ analyze_aggregations (void *cls)
* *
* @param cls closure * @param cls closure
* @param args remaining command-line arguments * @param args remaining command-line arguments
* @param cfgfile name of the configuration file used (for saving, can be NULL!) * @param TALER_ARL_cfgfile name of the configuration file used (for saving, can be NULL!)
* @param c configuration * @param c configuration
*/ */
static void static void
run (void *cls, run (void *cls,
char *const *args, char *const *args,
const char *cfgfile, const char *TALER_ARL_cfgfile,
const struct GNUNET_CONFIGURATION_Handle *c) const struct GNUNET_CONFIGURATION_Handle *c)
{ {
json_t *report; json_t *report;
(void) cls; (void) cls;
(void) args; (void) args;
(void) cfgfile; (void) TALER_ARL_cfgfile;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Launching auditor\n"); "Launching auditor\n");
if (GNUNET_OK != if (GNUNET_OK !=
setup_globals (c)) TALER_ARL_init (c))
{ {
global_ret = 1; global_ret = 1;
return; return;
@ -1371,28 +1398,28 @@ run (void *cls,
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Starting audit\n"); "Starting audit\n");
GNUNET_assert (GNUNET_OK == GNUNET_assert (GNUNET_OK ==
TALER_amount_get_zero (currency, TALER_amount_get_zero (TALER_ARL_currency,
&total_aggregation_fee_income)); &total_aggregation_fee_income));
GNUNET_assert (GNUNET_OK == GNUNET_assert (GNUNET_OK ==
TALER_amount_get_zero (currency, TALER_amount_get_zero (TALER_ARL_currency,
&total_wire_out_delta_plus)); &total_wire_out_delta_plus));
GNUNET_assert (GNUNET_OK == GNUNET_assert (GNUNET_OK ==
TALER_amount_get_zero (currency, TALER_amount_get_zero (TALER_ARL_currency,
&total_wire_out_delta_minus)); &total_wire_out_delta_minus));
GNUNET_assert (GNUNET_OK == GNUNET_assert (GNUNET_OK ==
TALER_amount_get_zero (currency, TALER_amount_get_zero (TALER_ARL_currency,
&total_arithmetic_delta_plus)); &total_arithmetic_delta_plus));
GNUNET_assert (GNUNET_OK == GNUNET_assert (GNUNET_OK ==
TALER_amount_get_zero (currency, TALER_amount_get_zero (TALER_ARL_currency,
&total_arithmetic_delta_minus)); &total_arithmetic_delta_minus));
GNUNET_assert (GNUNET_OK == GNUNET_assert (GNUNET_OK ==
TALER_amount_get_zero (currency, TALER_amount_get_zero (TALER_ARL_currency,
&total_coin_delta_plus)); &total_coin_delta_plus));
GNUNET_assert (GNUNET_OK == GNUNET_assert (GNUNET_OK ==
TALER_amount_get_zero (currency, TALER_amount_get_zero (TALER_ARL_currency,
&total_coin_delta_minus)); &total_coin_delta_minus));
GNUNET_assert (GNUNET_OK == GNUNET_assert (GNUNET_OK ==
TALER_amount_get_zero (currency, TALER_amount_get_zero (TALER_ARL_currency,
&total_bad_sig_loss)); &total_bad_sig_loss));
GNUNET_assert (NULL != GNUNET_assert (NULL !=
(report_row_inconsistencies = json_array ())); (report_row_inconsistencies = json_array ()));
@ -1401,13 +1428,14 @@ run (void *cls,
GNUNET_assert (NULL != GNUNET_assert (NULL !=
(report_coin_inconsistencies = json_array ())); (report_coin_inconsistencies = json_array ()));
GNUNET_assert (NULL != GNUNET_assert (NULL !=
(report_amount_arithmetic_inconsistencies = json_array ())); (report_amount_arithmetic_inconsistencies =
json_array ()));
GNUNET_assert (NULL != GNUNET_assert (NULL !=
(report_bad_sig_losses = json_array ())); (report_bad_sig_losses = json_array ()));
GNUNET_assert (NULL != GNUNET_assert (NULL !=
(report_fee_time_inconsistencies = json_array ())); (report_fee_time_inconsistencies = json_array ()));
setup_sessions_and_run (&analyze_aggregations, TALER_ARL_setup_sessions_and_run (&analyze_aggregations,
NULL); NULL);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Audit complete\n"); "Audit complete\n");
report = json_pack ("{s:o, s:o, s:o, s:o, s:o," report = json_pack ("{s:o, s:o, s:o, s:o, s:o,"
@ -1418,9 +1446,11 @@ run (void *cls,
"wire_out_inconsistencies", "wire_out_inconsistencies",
report_wire_out_inconsistencies, report_wire_out_inconsistencies,
"total_wire_out_delta_plus", "total_wire_out_delta_plus",
TALER_JSON_from_amount (&total_wire_out_delta_plus), TALER_JSON_from_amount (
&total_wire_out_delta_plus),
"total_wire_out_delta_minus", "total_wire_out_delta_minus",
TALER_JSON_from_amount (&total_wire_out_delta_minus), TALER_JSON_from_amount (
&total_wire_out_delta_minus),
/* Tested in test-auditor.sh #4/#5/#6/#7/#13 */ /* Tested in test-auditor.sh #4/#5/#6/#7/#13 */
"bad_sig_losses", "bad_sig_losses",
report_bad_sig_losses, report_bad_sig_losses,
@ -1436,27 +1466,34 @@ run (void *cls,
"total_coin_delta_plus", "total_coin_delta_plus",
TALER_JSON_from_amount (&total_coin_delta_plus), TALER_JSON_from_amount (&total_coin_delta_plus),
"total_coin_delta_minus", "total_coin_delta_minus",
TALER_JSON_from_amount (&total_coin_delta_minus), TALER_JSON_from_amount (
&total_coin_delta_minus),
"amount_arithmetic_inconsistencies", "amount_arithmetic_inconsistencies",
report_amount_arithmetic_inconsistencies, report_amount_arithmetic_inconsistencies,
/* block #3 */ /* block #3 */
"total_arithmetic_delta_plus", "total_arithmetic_delta_plus",
TALER_JSON_from_amount (&total_arithmetic_delta_plus), TALER_JSON_from_amount (
&total_arithmetic_delta_plus),
"total_arithmetic_delta_minus", "total_arithmetic_delta_minus",
TALER_JSON_from_amount (&total_arithmetic_delta_minus), TALER_JSON_from_amount (
&total_arithmetic_delta_minus),
"total_aggregation_fee_income", "total_aggregation_fee_income",
TALER_JSON_from_amount (&total_aggregation_fee_income), TALER_JSON_from_amount (
&total_aggregation_fee_income),
"start_ppa_wire_out_serial_id", "start_ppa_wire_out_serial_id",
(json_int_t) ppa_start.last_wire_out_serial_id, (json_int_t) ppa_start.last_wire_out_serial_id,
"end_ppa_wire_out_serial_id", "end_ppa_wire_out_serial_id",
(json_int_t) ppa.last_wire_out_serial_id, (json_int_t) ppa.last_wire_out_serial_id,
/* block #4 */ /* block #4 */
"auditor_start_time", json_from_time_abs (start_time), "auditor_start_time",
"auditor_end_time", json_from_time_abs ( TALER_ARL_json_from_time_abs (
start_time),
"auditor_end_time",
TALER_ARL_json_from_time_abs (
GNUNET_TIME_absolute_get ()) GNUNET_TIME_absolute_get ())
); );
GNUNET_break (NULL != report); GNUNET_break (NULL != report);
finish_report (report); TALER_ARL_done (report);
} }
@ -1477,11 +1514,11 @@ main (int argc,
"exchange-key", "exchange-key",
"KEY", "KEY",
"public key of the exchange (Crockford base32 encoded)", "public key of the exchange (Crockford base32 encoded)",
&master_pub), &TALER_ARL_master_pub),
GNUNET_GETOPT_option_flag ('r', GNUNET_GETOPT_option_flag ('r',
"restart", "TALER_ARL_restart",
"restart audit from the beginning (required on first run)", "TALER_ARL_restart audit from the beginning (required on first run)",
&restart), &TALER_ARL_restart),
GNUNET_GETOPT_option_timetravel ('T', GNUNET_GETOPT_option_timetravel ('T',
"timetravel"), "timetravel"),
GNUNET_GETOPT_OPTION_END GNUNET_GETOPT_OPTION_END

View File

@ -34,7 +34,7 @@
static int global_ret; static int global_ret;
/** /**
* Array of reports about missing deposit confirmations. * Array of TALER_ARL_reports about missing deposit confirmations.
*/ */
static json_t *report_deposit_confirmation_inconsistencies; static json_t *report_deposit_confirmation_inconsistencies;
@ -58,7 +58,7 @@ struct DepositConfirmationContext
{ {
/** /**
* How many deposit confirmations did we NOT find in the #edb? * How many deposit confirmations did we NOT find in the #TALER_ARL_edb?
*/ */
unsigned long long missed_count; unsigned long long missed_count;
@ -89,8 +89,8 @@ struct DepositConfirmationContext
/** /**
* Given a deposit confirmation from #adb, check that it is also * Given a deposit confirmation from #TALER_ARL_adb, check that it is also
* in #edb. Update the deposit confirmation context accordingly. * in #TALER_ARL_edb. Update the deposit confirmation context accordingly.
* *
* @param cls our `struct DepositConfirmationContext` * @param cls our `struct DepositConfirmationContext`
* @param serial_id row of the @a dc in the database * @param serial_id row of the @a dc in the database
@ -115,10 +115,10 @@ test_dc (void *cls,
dep.h_wire = dc->h_wire; dep.h_wire = dc->h_wire;
dep.refund_deadline = dc->refund_deadline; dep.refund_deadline = dc->refund_deadline;
qs = edb->have_deposit (edb->cls, qs = TALER_ARL_edb->have_deposit (TALER_ARL_edb->cls,
esession, TALER_ARL_esession,
&dep, &dep,
GNUNET_NO /* do not check refund deadline */); GNUNET_NO /* do not check refund deadline */);
if (qs > 0) if (qs > 0)
{ {
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@ -132,17 +132,17 @@ test_dc (void *cls,
dcc->qs = qs; dcc->qs = qs;
return; return;
} }
/* deposit confirmation missing! report! */ /* deposit confirmation missing! TALER_ARL_report! */
report (report_deposit_confirmation_inconsistencies, TALER_ARL_report (report_deposit_confirmation_inconsistencies,
json_pack ("{s:o, s:o, s:I, s:o}", json_pack ("{s:o, s:o, s:I, s:o}",
"timestamp", "timestamp",
json_from_time_abs (dc->timestamp), TALER_ARL_json_from_time_abs (dc->timestamp),
"amount", "amount",
TALER_JSON_from_amount (&dc->amount_without_fee), TALER_JSON_from_amount (&dc->amount_without_fee),
"rowid", "rowid",
(json_int_t) serial_id, (json_int_t) serial_id,
"account", "account",
GNUNET_JSON_from_data_auto (&dc->h_wire))); GNUNET_JSON_from_data_auto (&dc->h_wire)));
dcc->first_missed_coin_serial = GNUNET_MIN (dcc->first_missed_coin_serial, dcc->first_missed_coin_serial = GNUNET_MIN (dcc->first_missed_coin_serial,
serial_id); serial_id);
dcc->missed_count++; dcc->missed_count++;
@ -154,7 +154,7 @@ test_dc (void *cls,
/** /**
* Check that the deposit-confirmations that were reported to * Check that the deposit-confirmations that were TALER_ARL_reported to
* us by merchants are also in the exchange's database. * us by merchants are also in the exchange's database.
* *
* @param cls closure * @param cls closure
@ -173,10 +173,12 @@ analyze_deposit_confirmations (void *cls)
GNUNET_log (GNUNET_ERROR_TYPE_INFO, GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Analyzing deposit confirmations\n"); "Analyzing deposit confirmations\n");
ppdc.last_deposit_confirmation_serial_id = 0; ppdc.last_deposit_confirmation_serial_id = 0;
qsp = adb->get_auditor_progress_deposit_confirmation (adb->cls, qsp = TALER_ARL_adb->get_auditor_progress_deposit_confirmation (
asession, TALER_ARL_adb->cls,
&master_pub, TALER_ARL_asession,
&ppdc); &
TALER_ARL_master_pub,
&ppdc);
if (0 > qsp) if (0 > qsp)
{ {
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qsp); GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qsp);
@ -197,17 +199,18 @@ analyze_deposit_confirmations (void *cls)
/* setup 'cc' */ /* setup 'cc' */
GNUNET_assert (GNUNET_OK == GNUNET_assert (GNUNET_OK ==
TALER_amount_get_zero (currency, TALER_amount_get_zero (TALER_ARL_currency,
&dcc.missed_amount)); &dcc.missed_amount));
dcc.qs = GNUNET_DB_STATUS_SUCCESS_ONE_RESULT; dcc.qs = GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
dcc.missed_count = 0LLU; dcc.missed_count = 0LLU;
dcc.first_missed_coin_serial = UINT64_MAX; dcc.first_missed_coin_serial = UINT64_MAX;
qsx = adb->get_deposit_confirmations (adb->cls, qsx = TALER_ARL_adb->get_deposit_confirmations (TALER_ARL_adb->cls,
asession, TALER_ARL_asession,
&master_pub, &TALER_ARL_master_pub,
ppdc.last_deposit_confirmation_serial_id, ppdc.
&test_dc, last_deposit_confirmation_serial_id,
&dcc); &test_dc,
&dcc);
if (0 > qsx) if (0 > qsx)
{ {
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qsx); GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qsx);
@ -229,15 +232,19 @@ analyze_deposit_confirmations (void *cls)
/* sync 'cc' back to disk */ /* sync 'cc' back to disk */
if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qsp) if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qsp)
qs = adb->update_auditor_progress_deposit_confirmation (adb->cls, qs = TALER_ARL_adb->update_auditor_progress_deposit_confirmation (
asession, TALER_ARL_adb->cls,
&master_pub, TALER_ARL_asession,
&ppdc); &
TALER_ARL_master_pub,
&ppdc);
else else
qs = adb->insert_auditor_progress_deposit_confirmation (adb->cls, qs = TALER_ARL_adb->insert_auditor_progress_deposit_confirmation (
asession, TALER_ARL_adb->cls,
&master_pub, TALER_ARL_asession,
&ppdc); &
TALER_ARL_master_pub,
&ppdc);
if (0 >= qs) if (0 >= qs)
{ {
GNUNET_log (GNUNET_ERROR_TYPE_INFO, GNUNET_log (GNUNET_ERROR_TYPE_INFO,
@ -260,24 +267,22 @@ analyze_deposit_confirmations (void *cls)
* *
* @param cls closure * @param cls closure
* @param args remaining command-line arguments * @param args remaining command-line arguments
* @param cfgfile name of the configuration file used (for saving, can be NULL!) * @param TALER_ARL_cfgfile name of the configuration file used (for saving, can be NULL!)
* @param c configuration * @param c configuration
*/ */
static void static void
run (void *cls, run (void *cls,
char *const *args, char *const *args,
const char *cfgfile, const char *TALER_ARL_cfgfile,
const struct GNUNET_CONFIGURATION_Handle *c) const struct GNUNET_CONFIGURATION_Handle *c)
{ {
json_t *report;
(void) cls; (void) cls;
(void) args; (void) args;
(void) cfgfile; (void) TALER_ARL_cfgfile;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Launching auditor\n"); "Launching auditor\n");
if (GNUNET_OK != if (GNUNET_OK !=
setup_globals (c)) TALER_ARL_init (c))
{ {
global_ret = 1; global_ret = 1;
return; return;
@ -287,25 +292,29 @@ run (void *cls,
GNUNET_assert (NULL != GNUNET_assert (NULL !=
(report_deposit_confirmation_inconsistencies = json_array ())); (report_deposit_confirmation_inconsistencies = json_array ()));
if (GNUNET_OK != if (GNUNET_OK !=
setup_sessions_and_run (&analyze_deposit_confirmations, TALER_ARL_setup_sessions_and_run (&analyze_deposit_confirmations,
NULL)) NULL))
{ {
global_ret = 1; global_ret = 1;
return; return;
} }
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Audit complete\n"); "Audit complete\n");
report = json_pack ("{s:o, s:o, s:I}", {
"deposit_confirmation_inconsistencies", json_t *report;
report_deposit_confirmation_inconsistencies,
"missing_deposit_confirmation_count", report = json_pack ("{s:o, s:o, s:I}",
(json_int_t) number_missed_deposit_confirmations, "deposit_confirmation_inconsistencies",
"missing_deposit_confirmation_total", report_deposit_confirmation_inconsistencies,
TALER_JSON_from_amount ( "missing_deposit_confirmation_count",
&total_missed_deposit_confirmations) (json_int_t) number_missed_deposit_confirmations,
); "missing_deposit_confirmation_total",
GNUNET_break (NULL != report); TALER_JSON_from_amount (
finish_report (report); &total_missed_deposit_confirmations)
);
GNUNET_break (NULL != report);
TALER_ARL_done (report);
}
} }
@ -326,11 +335,11 @@ main (int argc,
"exchange-key", "exchange-key",
"KEY", "KEY",
"public key of the exchange (Crockford base32 encoded)", "public key of the exchange (Crockford base32 encoded)",
&master_pub), &TALER_ARL_master_pub),
GNUNET_GETOPT_option_flag ('r', GNUNET_GETOPT_option_flag ('r',
"restart", "TALER_ARL_restart",
"restart audit from the beginning (required on first run)", "TALER_ARL_restart audit from the beginning (required on first run)",
&restart), &TALER_ARL_restart),
GNUNET_GETOPT_option_timetravel ('T', GNUNET_GETOPT_option_timetravel ('T',
"timetravel"), "timetravel"),
GNUNET_GETOPT_OPTION_END GNUNET_GETOPT_OPTION_END

View File

@ -14,7 +14,7 @@
TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/ */
/** /**
* @file auditor/taler-auditor-reserves.c * @file auditor/taler-helper-auditor-reserves.c
* @brief audits the reserves of an exchange database * @brief audits the reserves of an exchange database
* @author Christian Grothoff * @author Christian Grothoff
*/ */
@ -162,8 +162,10 @@ static struct TALER_Amount total_bad_sig_loss;
static void static void
report_amount_arithmetic_inconsistency (const char *operation, report_amount_arithmetic_inconsistency (const char *operation,
uint64_t rowid, uint64_t rowid,
const struct TALER_Amount *exchange, const struct
const struct TALER_Amount *auditor, TALER_Amount *exchange,
const struct
TALER_Amount *auditor,
int profitable) int profitable)
{ {
struct TALER_Amount delta; struct TALER_Amount delta;
@ -187,13 +189,13 @@ report_amount_arithmetic_inconsistency (const char *operation,
auditor, auditor,
exchange)); exchange));
} }
report (report_amount_arithmetic_inconsistencies, TALER_ARL_report (report_amount_arithmetic_inconsistencies,
json_pack ("{s:s, s:I, s:o, s:o, s:I}", json_pack ("{s:s, s:I, s:o, s:o, s:I}",
"operation", operation, "operation", operation,
"rowid", (json_int_t) rowid, "rowid", (json_int_t) rowid,
"exchange", TALER_JSON_from_amount (exchange), "exchange", TALER_JSON_from_amount (exchange),
"auditor", TALER_JSON_from_amount (auditor), "auditor", TALER_JSON_from_amount (auditor),
"profitable", (json_int_t) profitable)); "profitable", (json_int_t) profitable));
if (0 != profitable) if (0 != profitable)
{ {
target = (1 == profitable) target = (1 == profitable)
@ -219,11 +221,11 @@ report_row_inconsistency (const char *table,
uint64_t rowid, uint64_t rowid,
const char *diagnostic) const char *diagnostic)
{ {
report (report_row_inconsistencies, TALER_ARL_report (report_row_inconsistencies,
json_pack ("{s:s, s:I, s:s}", json_pack ("{s:s, s:I, s:s}",
"table", table, "table", table,
"row", (json_int_t) rowid, "row", (json_int_t) rowid,
"diagnostic", diagnostic)); "diagnostic", diagnostic));
} }
@ -306,15 +308,15 @@ load_auditor_reserve_summary (struct ReserveSummary *rs)
enum GNUNET_DB_QueryStatus qs; enum GNUNET_DB_QueryStatus qs;
uint64_t rowid; uint64_t rowid;
qs = adb->get_reserve_info (adb->cls, qs = TALER_ARL_adb->get_reserve_info (TALER_ARL_adb->cls,
asession, TALER_ARL_asession,
&rs->reserve_pub, &rs->reserve_pub,
&master_pub, &TALER_ARL_master_pub,
&rowid, &rowid,
&rs->a_balance, &rs->a_balance,
&rs->a_withdraw_fee_balance, &rs->a_withdraw_fee_balance,
&rs->a_expiration_date, &rs->a_expiration_date,
&rs->sender_account); &rs->sender_account);
if (0 > qs) if (0 > qs)
{ {
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
@ -502,9 +504,9 @@ handle_reserve_out (void *cls,
ppr.last_reserve_out_serial_id = rowid + 1; ppr.last_reserve_out_serial_id = rowid + 1;
/* lookup denomination pub data (make sure denom_pub is valid, establish fees) */ /* lookup denomination pub data (make sure denom_pub is valid, establish fees) */
qs = get_denomination_info (denom_pub, qs = TALER_ARL_get_denomination_info (denom_pub,
&issue, &issue,
&wsrd.h_denomination_pub); &wsrd.h_denomination_pub);
if (0 > qs) if (0 > qs)
{ {
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
@ -535,14 +537,15 @@ handle_reserve_out (void *cls,
if ( (valid_start.abs_value_us > execution_date.abs_value_us) || if ( (valid_start.abs_value_us > execution_date.abs_value_us) ||
(expire_withdraw.abs_value_us < execution_date.abs_value_us) ) (expire_withdraw.abs_value_us < execution_date.abs_value_us) )
{ {
report (denomination_key_validity_withdraw_inconsistencies, TALER_ARL_report (denomination_key_validity_withdraw_inconsistencies,
json_pack ("{s:I, s:o, s:o, s:o}", json_pack ("{s:I, s:o, s:o, s:o}",
"row", (json_int_t) rowid, "row", (json_int_t) rowid,
"execution_date", "execution_date",
json_from_time_abs (execution_date), TALER_ARL_json_from_time_abs (execution_date),
"reserve_pub", GNUNET_JSON_from_data_auto (reserve_pub), "reserve_pub", GNUNET_JSON_from_data_auto (
"denompub_h", GNUNET_JSON_from_data_auto ( reserve_pub),
&wsrd.h_denomination_pub))); "denompub_h", GNUNET_JSON_from_data_auto (
&wsrd.h_denomination_pub)));
} }
/* check reserve_sig */ /* check reserve_sig */
@ -559,12 +562,14 @@ handle_reserve_out (void *cls,
&reserve_sig->eddsa_signature, &reserve_sig->eddsa_signature,
&reserve_pub->eddsa_pub)) &reserve_pub->eddsa_pub))
{ {
report (report_bad_sig_losses, TALER_ARL_report (report_bad_sig_losses,
json_pack ("{s:s, s:I, s:o, s:o}", json_pack ("{s:s, s:I, s:o, s:o}",
"operation", "withdraw", "operation", "withdraw",
"row", (json_int_t) rowid, "row", (json_int_t) rowid,
"loss", TALER_JSON_from_amount (amount_with_fee), "loss", TALER_JSON_from_amount (
"key_pub", GNUNET_JSON_from_data_auto (reserve_pub))); amount_with_fee),
"key_pub", GNUNET_JSON_from_data_auto (
reserve_pub)));
GNUNET_break (GNUNET_OK == GNUNET_break (GNUNET_OK ==
TALER_amount_add (&total_bad_sig_loss, TALER_amount_add (&total_bad_sig_loss,
&total_bad_sig_loss, &total_bad_sig_loss,
@ -682,13 +687,13 @@ handle_recoup_by_reserve (void *cls,
&coin_sig->eddsa_signature, &coin_sig->eddsa_signature,
&coin->coin_pub.eddsa_pub)) &coin->coin_pub.eddsa_pub))
{ {
report (report_bad_sig_losses, TALER_ARL_report (report_bad_sig_losses,
json_pack ("{s:s, s:I, s:o, s:o}", json_pack ("{s:s, s:I, s:o, s:o}",
"operation", "recoup", "operation", "recoup",
"row", (json_int_t) rowid, "row", (json_int_t) rowid,
"loss", TALER_JSON_from_amount (amount), "loss", TALER_JSON_from_amount (amount),
"key_pub", GNUNET_JSON_from_data_auto ( "key_pub", GNUNET_JSON_from_data_auto (
&coin->coin_pub))); &coin->coin_pub)));
GNUNET_break (GNUNET_OK == GNUNET_break (GNUNET_OK ==
TALER_amount_add (&total_bad_sig_loss, TALER_amount_add (&total_bad_sig_loss,
&total_bad_sig_loss, &total_bad_sig_loss,
@ -700,11 +705,11 @@ handle_recoup_by_reserve (void *cls,
&pr.h_denom_pub); &pr.h_denom_pub);
if (NULL == rev) if (NULL == rev)
{ {
qs = edb->get_denomination_revocation (edb->cls, qs = TALER_ARL_edb->get_denomination_revocation (TALER_ARL_edb->cls,
esession, TALER_ARL_esession,
&pr.h_denom_pub, &pr.h_denom_pub,
&msig, &msig,
&rev_rowid); &rev_rowid);
if (0 > qs) if (0 > qs)
{ {
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
@ -735,7 +740,7 @@ handle_recoup_by_reserve (void *cls,
TALER_SIGNATURE_MASTER_DENOMINATION_KEY_REVOKED, TALER_SIGNATURE_MASTER_DENOMINATION_KEY_REVOKED,
&kr.purpose, &kr.purpose,
&msig.eddsa_signature, &msig.eddsa_signature,
&master_pub.eddsa_pub)) &TALER_ARL_master_pub.eddsa_pub))
{ {
rev = "master signature invalid"; rev = "master signature invalid";
} }
@ -757,12 +762,13 @@ handle_recoup_by_reserve (void *cls,
if ( (NULL != rev) && if ( (NULL != rev) &&
(0 == strcmp (rev, "master signature invalid")) ) (0 == strcmp (rev, "master signature invalid")) )
{ {
report (report_bad_sig_losses, TALER_ARL_report (report_bad_sig_losses,
json_pack ("{s:s, s:I, s:o, s:o}", json_pack ("{s:s, s:I, s:o, s:o}",
"operation", "recoup-master", "operation", "recoup-master",
"row", (json_int_t) rev_rowid, "row", (json_int_t) rev_rowid,
"loss", TALER_JSON_from_amount (amount), "loss", TALER_JSON_from_amount (amount),
"key_pub", GNUNET_JSON_from_data_auto (&master_pub))); "key_pub", GNUNET_JSON_from_data_auto (
&TALER_ARL_master_pub)));
GNUNET_break (GNUNET_OK == GNUNET_break (GNUNET_OK ==
TALER_amount_add (&total_bad_sig_loss, TALER_amount_add (&total_bad_sig_loss,
&total_bad_sig_loss, &total_bad_sig_loss,
@ -843,15 +849,15 @@ get_closing_fee (const char *receiver_account,
"Method is `%s'\n", "Method is `%s'\n",
method); method);
if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
edb->get_wire_fee (edb->cls, TALER_ARL_edb->get_wire_fee (TALER_ARL_edb->cls,
esession, TALER_ARL_esession,
method, method,
atime, atime,
&start_date, &start_date,
&end_date, &end_date,
&wire_fee, &wire_fee,
fee, fee,
&master_sig)) &master_sig))
{ {
report_row_inconsistency ("closing-fee", report_row_inconsistency ("closing-fee",
atime.abs_value_us, atime.abs_value_us,
@ -950,11 +956,12 @@ handle_reserve_closed (void *cls,
else if (0 != TALER_amount_cmp (&expected_fee, else if (0 != TALER_amount_cmp (&expected_fee,
closing_fee)) closing_fee))
{ {
report_amount_arithmetic_inconsistency ("closing aggregation fee", report_amount_arithmetic_inconsistency (
rowid, "closing aggregation fee",
closing_fee, rowid,
&expected_fee, closing_fee,
1); &expected_fee,
1);
} }
} }
if (NULL == rs->sender_account) if (NULL == rs->sender_account)
@ -1006,9 +1013,9 @@ verify_reserve_balance (void *cls,
ret = GNUNET_OK; ret = GNUNET_OK;
reserve.pub = rs->reserve_pub; reserve.pub = rs->reserve_pub;
qs = edb->reserves_get (edb->cls, qs = TALER_ARL_edb->reserves_get (TALER_ARL_edb->cls,
esession, TALER_ARL_esession,
&reserve); &reserve);
if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs) if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs)
{ {
char *diag; char *diag;
@ -1053,12 +1060,13 @@ verify_reserve_balance (void *cls,
TALER_amount_add (&total_balance_insufficient_loss, TALER_amount_add (&total_balance_insufficient_loss,
&total_balance_insufficient_loss, &total_balance_insufficient_loss,
&loss)); &loss));
report (report_reserve_balance_insufficient_inconsistencies, TALER_ARL_report (
json_pack ("{s:o, s:o}", report_reserve_balance_insufficient_inconsistencies,
"reserve_pub", json_pack ("{s:o, s:o}",
GNUNET_JSON_from_data_auto (&rs->reserve_pub), "reserve_pub",
"loss", GNUNET_JSON_from_data_auto (&rs->reserve_pub),
TALER_JSON_from_amount (&loss))); "loss",
TALER_JSON_from_amount (&loss)));
goto cleanup; goto cleanup;
} }
if (0 != TALER_amount_cmp (&nbalance, if (0 != TALER_amount_cmp (&nbalance,
@ -1091,14 +1099,15 @@ verify_reserve_balance (void *cls,
&total_balance_summary_delta_minus, &total_balance_summary_delta_minus,
&delta)); &delta));
} }
report (report_reserve_balance_summary_wrong_inconsistencies, TALER_ARL_report (
json_pack ("{s:o, s:o, s:o}", report_reserve_balance_summary_wrong_inconsistencies,
"reserve_pub", json_pack ("{s:o, s:o, s:o}",
GNUNET_JSON_from_data_auto (&rs->reserve_pub), "reserve_pub",
"exchange", GNUNET_JSON_from_data_auto (&rs->reserve_pub),
TALER_JSON_from_amount (&reserve.balance), "exchange",
"auditor", TALER_JSON_from_amount (&reserve.balance),
TALER_JSON_from_amount (&nbalance))); "auditor",
TALER_JSON_from_amount (&nbalance)));
goto cleanup; goto cleanup;
} }
@ -1120,14 +1129,16 @@ verify_reserve_balance (void *cls,
TALER_amount_add (&total_balance_reserve_not_closed, TALER_amount_add (&total_balance_reserve_not_closed,
&total_balance_reserve_not_closed, &total_balance_reserve_not_closed,
&nbalance)); &nbalance));
report (report_reserve_not_closed_inconsistencies, TALER_ARL_report (report_reserve_not_closed_inconsistencies,
json_pack ("{s:o, s:o, s:o}", json_pack ("{s:o, s:o, s:o}",
"reserve_pub", "reserve_pub",
GNUNET_JSON_from_data_auto (&rs->reserve_pub), GNUNET_JSON_from_data_auto (
"balance", &rs->reserve_pub),
TALER_JSON_from_amount (&nbalance), "balance",
"expiration_time", TALER_JSON_from_amount (&nbalance),
json_from_time_abs (rs->a_expiration_date))); "expiration_time",
TALER_ARL_json_from_time_abs (
rs->a_expiration_date)));
} }
} }
else else
@ -1136,16 +1147,18 @@ verify_reserve_balance (void *cls,
TALER_amount_add (&total_balance_reserve_not_closed, TALER_amount_add (&total_balance_reserve_not_closed,
&total_balance_reserve_not_closed, &total_balance_reserve_not_closed,
&nbalance)); &nbalance));
report (report_reserve_not_closed_inconsistencies, TALER_ARL_report (report_reserve_not_closed_inconsistencies,
json_pack ("{s:o, s:o, s:o, s:s}", json_pack ("{s:o, s:o, s:o, s:s}",
"reserve_pub", "reserve_pub",
GNUNET_JSON_from_data_auto (&rs->reserve_pub), GNUNET_JSON_from_data_auto (
"balance", &rs->reserve_pub),
TALER_JSON_from_amount (&nbalance), "balance",
"expiration_time", TALER_JSON_from_amount (&nbalance),
json_from_time_abs (rs->a_expiration_date), "expiration_time",
"diagnostic", TALER_ARL_json_from_time_abs (
"could not determine closing fee")); rs->a_expiration_date),
"diagnostic",
"could not determine closing fee"));
} }
} }
@ -1191,10 +1204,10 @@ verify_reserve_balance (void *cls,
"Final balance of reserve `%s' is %s, dropping it\n", "Final balance of reserve `%s' is %s, dropping it\n",
TALER_B2S (&rs->reserve_pub), TALER_B2S (&rs->reserve_pub),
TALER_amount2s (&nbalance)); TALER_amount2s (&nbalance));
qs = adb->del_reserve_info (adb->cls, qs = TALER_ARL_adb->del_reserve_info (TALER_ARL_adb->cls,
asession, TALER_ARL_asession,
&rs->reserve_pub, &rs->reserve_pub,
&master_pub); &TALER_ARL_master_pub);
if (0 >= qs) if (0 >= qs)
{ {
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
@ -1220,22 +1233,22 @@ verify_reserve_balance (void *cls,
TALER_amount2s (&nbalance)); TALER_amount2s (&nbalance));
if (rs->had_ri) if (rs->had_ri)
qs = adb->update_reserve_info (adb->cls, qs = TALER_ARL_adb->update_reserve_info (TALER_ARL_adb->cls,
asession, TALER_ARL_asession,
&rs->reserve_pub, &rs->reserve_pub,
&master_pub, &TALER_ARL_master_pub,
&nbalance, &nbalance,
&rs->a_withdraw_fee_balance, &rs->a_withdraw_fee_balance,
rs->a_expiration_date); rs->a_expiration_date);
else else
qs = adb->insert_reserve_info (adb->cls, qs = TALER_ARL_adb->insert_reserve_info (TALER_ARL_adb->cls,
asession, TALER_ARL_asession,
&rs->reserve_pub, &rs->reserve_pub,
&master_pub, &TALER_ARL_master_pub,
&nbalance, &nbalance,
&rs->a_withdraw_fee_balance, &rs->a_withdraw_fee_balance,
rs->a_expiration_date, rs->a_expiration_date,
rs->sender_account); rs->sender_account);
if (0 >= qs) if (0 >= qs)
{ {
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
@ -1270,10 +1283,10 @@ analyze_reserves (void *cls)
(void) cls; (void) cls;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Analyzing reserves\n"); "Analyzing reserves\n");
qsp = adb->get_auditor_progress_reserve (adb->cls, qsp = TALER_ARL_adb->get_auditor_progress_reserve (TALER_ARL_adb->cls,
asession, TALER_ARL_asession,
&master_pub, &TALER_ARL_master_pub,
&ppr); &ppr);
if (0 > qsp) if (0 > qsp)
{ {
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qsp); GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qsp);
@ -1296,11 +1309,11 @@ analyze_reserves (void *cls)
(unsigned long long) ppr.last_reserve_close_serial_id); (unsigned long long) ppr.last_reserve_close_serial_id);
} }
rc.qs = GNUNET_DB_STATUS_SUCCESS_ONE_RESULT; rc.qs = GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
qsx = adb->get_reserve_summary (adb->cls, qsx = TALER_ARL_adb->get_reserve_summary (TALER_ARL_adb->cls,
asession, TALER_ARL_asession,
&master_pub, &TALER_ARL_master_pub,
&total_escrow_balance, &total_escrow_balance,
&total_withdraw_fee_income); &total_withdraw_fee_income);
if (qsx < 0) if (qsx < 0)
{ {
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qsx); GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qsx);
@ -1311,42 +1324,46 @@ analyze_reserves (void *cls)
rc.revoked = GNUNET_CONTAINER_multihashmap_create (4, rc.revoked = GNUNET_CONTAINER_multihashmap_create (4,
GNUNET_NO); GNUNET_NO);
qs = edb->select_reserves_in_above_serial_id (edb->cls, qs = TALER_ARL_edb->select_reserves_in_above_serial_id (TALER_ARL_edb->cls,
esession, TALER_ARL_esession,
ppr.last_reserve_in_serial_id, ppr.
&handle_reserve_in, last_reserve_in_serial_id,
&rc); &handle_reserve_in,
&rc);
if (qs < 0) if (qs < 0)
{ {
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
return qs; return qs;
} }
qs = edb->select_withdrawals_above_serial_id (edb->cls, qs = TALER_ARL_edb->select_withdrawals_above_serial_id (TALER_ARL_edb->cls,
esession, TALER_ARL_esession,
ppr.last_reserve_out_serial_id, ppr.
&handle_reserve_out, last_reserve_out_serial_id,
&rc); &handle_reserve_out,
&rc);
if (qs < 0) if (qs < 0)
{ {
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
return qs; return qs;
} }
qs = edb->select_recoup_above_serial_id (edb->cls, qs = TALER_ARL_edb->select_recoup_above_serial_id (TALER_ARL_edb->cls,
esession, TALER_ARL_esession,
ppr.last_reserve_recoup_serial_id, ppr.
&handle_recoup_by_reserve, last_reserve_recoup_serial_id,
&rc); &handle_recoup_by_reserve,
&rc);
if (qs < 0) if (qs < 0)
{ {
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
return qs; return qs;
} }
qs = edb->select_reserve_closed_above_serial_id (edb->cls, qs = TALER_ARL_edb->select_reserve_closed_above_serial_id (TALER_ARL_edb->cls,
esession, TALER_ARL_esession,
ppr. ppr.
last_reserve_close_serial_id, last_reserve_close_serial_id,
&handle_reserve_closed, &
&rc); handle_reserve_closed,
&rc);
if (qs < 0) if (qs < 0)
{ {
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
@ -1366,19 +1383,19 @@ analyze_reserves (void *cls)
if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qsx) if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qsx)
{ {
qs = adb->insert_reserve_summary (adb->cls, qs = TALER_ARL_adb->insert_reserve_summary (TALER_ARL_adb->cls,
asession, TALER_ARL_asession,
&master_pub, &TALER_ARL_master_pub,
&total_escrow_balance, &total_escrow_balance,
&total_withdraw_fee_income); &total_withdraw_fee_income);
} }
else else
{ {
qs = adb->update_reserve_summary (adb->cls, qs = TALER_ARL_adb->update_reserve_summary (TALER_ARL_adb->cls,
asession, TALER_ARL_asession,
&master_pub, &TALER_ARL_master_pub,
&total_escrow_balance, &total_escrow_balance,
&total_withdraw_fee_income); &total_withdraw_fee_income);
} }
if (0 >= qs) if (0 >= qs)
{ {
@ -1386,15 +1403,15 @@ analyze_reserves (void *cls)
return qs; return qs;
} }
if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qsp) if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qsp)
qs = adb->update_auditor_progress_reserve (adb->cls, qs = TALER_ARL_adb->update_auditor_progress_reserve (TALER_ARL_adb->cls,
asession, TALER_ARL_asession,
&master_pub, &TALER_ARL_master_pub,
&ppr); &ppr);
else else
qs = adb->insert_auditor_progress_reserve (adb->cls, qs = TALER_ARL_adb->insert_auditor_progress_reserve (TALER_ARL_adb->cls,
asession, TALER_ARL_asession,
&master_pub, &TALER_ARL_master_pub,
&ppr); &ppr);
if (0 >= qs) if (0 >= qs)
{ {
GNUNET_log (GNUNET_ERROR_TYPE_INFO, GNUNET_log (GNUNET_ERROR_TYPE_INFO,
@ -1417,36 +1434,34 @@ analyze_reserves (void *cls)
* *
* @param cls closure * @param cls closure
* @param args remaining command-line arguments * @param args remaining command-line arguments
* @param cfgfile name of the configuration file used (for saving, can be NULL!) * @param TALER_ARL_cfgfile name of the configuration file used (for saving, can be NULL!)
* @param c configuration * @param c configuration
*/ */
static void static void
run (void *cls, run (void *cls,
char *const *args, char *const *args,
const char *cfgfile, const char *TALER_ARL_cfgfile,
const struct GNUNET_CONFIGURATION_Handle *c) const struct GNUNET_CONFIGURATION_Handle *c)
{ {
json_t *report;
(void) cls; (void) cls;
(void) args; (void) args;
(void) cfgfile; (void) TALER_ARL_cfgfile;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Launching auditor\n"); "Launching auditor\n");
if (GNUNET_OK != if (GNUNET_OK !=
setup_globals (cfg)) TALER_ARL_init (TALER_ARL_cfg))
{ {
global_ret = 1; global_ret = 1;
return; return;
} }
if (GNUNET_OK != if (GNUNET_OK !=
GNUNET_CONFIGURATION_get_value_time (cfg, GNUNET_CONFIGURATION_get_value_time (TALER_ARL_cfg,
"exchangedb", "exchangTALER_ARL_edb",
"IDLE_RESERVE_EXPIRATION_TIME", "IDLE_RESERVE_EXPIRATION_TIME",
&idle_reserve_expiration_time)) &idle_reserve_expiration_time))
{ {
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
"exchangedb", "exchangTALER_ARL_edb",
"IDLE_RESERVE_EXPIRATION_TIME"); "IDLE_RESERVE_EXPIRATION_TIME");
global_ret = 1; global_ret = 1;
return; return;
@ -1454,34 +1469,34 @@ run (void *cls,
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Starting audit\n"); "Starting audit\n");
GNUNET_assert (GNUNET_OK == GNUNET_assert (GNUNET_OK ==
TALER_amount_get_zero (currency, TALER_amount_get_zero (TALER_ARL_currency,
&total_escrow_balance)); &total_escrow_balance));
GNUNET_assert (GNUNET_OK == GNUNET_assert (GNUNET_OK ==
TALER_amount_get_zero (currency, TALER_amount_get_zero (TALER_ARL_currency,
&total_irregular_recoups)); &total_irregular_recoups));
GNUNET_assert (GNUNET_OK == GNUNET_assert (GNUNET_OK ==
TALER_amount_get_zero (currency, TALER_amount_get_zero (TALER_ARL_currency,
&total_withdraw_fee_income)); &total_withdraw_fee_income));
GNUNET_assert (GNUNET_OK == GNUNET_assert (GNUNET_OK ==
TALER_amount_get_zero (currency, TALER_amount_get_zero (TALER_ARL_currency,
&total_balance_insufficient_loss)); &total_balance_insufficient_loss));
GNUNET_assert (GNUNET_OK == GNUNET_assert (GNUNET_OK ==
TALER_amount_get_zero (currency, TALER_amount_get_zero (TALER_ARL_currency,
&total_balance_summary_delta_plus)); &total_balance_summary_delta_plus));
GNUNET_assert (GNUNET_OK == GNUNET_assert (GNUNET_OK ==
TALER_amount_get_zero (currency, TALER_amount_get_zero (TALER_ARL_currency,
&total_balance_summary_delta_minus)); &total_balance_summary_delta_minus));
GNUNET_assert (GNUNET_OK == GNUNET_assert (GNUNET_OK ==
TALER_amount_get_zero (currency, TALER_amount_get_zero (TALER_ARL_currency,
&total_arithmetic_delta_plus)); &total_arithmetic_delta_plus));
GNUNET_assert (GNUNET_OK == GNUNET_assert (GNUNET_OK ==
TALER_amount_get_zero (currency, TALER_amount_get_zero (TALER_ARL_currency,
&total_arithmetic_delta_minus)); &total_arithmetic_delta_minus));
GNUNET_assert (GNUNET_OK == GNUNET_assert (GNUNET_OK ==
TALER_amount_get_zero (currency, TALER_amount_get_zero (TALER_ARL_currency,
&total_balance_reserve_not_closed)); &total_balance_reserve_not_closed));
GNUNET_assert (GNUNET_OK == GNUNET_assert (GNUNET_OK ==
TALER_amount_get_zero (currency, TALER_amount_get_zero (TALER_ARL_currency,
&total_bad_sig_loss)); &total_bad_sig_loss));
GNUNET_assert (NULL != GNUNET_assert (NULL !=
(report_row_inconsistencies = json_array ())); (report_row_inconsistencies = json_array ()));
@ -1489,104 +1504,122 @@ run (void *cls,
(denomination_key_validity_withdraw_inconsistencies = (denomination_key_validity_withdraw_inconsistencies =
json_array ())); json_array ()));
GNUNET_assert (NULL != GNUNET_assert (NULL !=
(report_reserve_balance_summary_wrong_inconsistencies = (report_reserve_balance_summary_wrong_inconsistencies
=
json_array ()));
GNUNET_assert (NULL !=
(report_reserve_balance_insufficient_inconsistencies
=
json_array ()));
GNUNET_assert (NULL !=
(report_reserve_not_closed_inconsistencies =
json_array ())); json_array ()));
GNUNET_assert (NULL != GNUNET_assert (NULL !=
(report_reserve_balance_insufficient_inconsistencies = (report_amount_arithmetic_inconsistencies =
json_array ())); json_array ()));
GNUNET_assert (NULL !=
(report_reserve_not_closed_inconsistencies = json_array ()));
GNUNET_assert (NULL !=
(report_amount_arithmetic_inconsistencies = json_array ()));
GNUNET_assert (NULL != GNUNET_assert (NULL !=
(report_bad_sig_losses = json_array ())); (report_bad_sig_losses = json_array ()));
if (GNUNET_OK != if (GNUNET_OK !=
setup_sessions_and_run (&analyze_reserves, TALER_ARL_setup_sessions_and_run (&analyze_reserves,
NULL)) NULL))
{ {
global_ret = 1; global_ret = 1;
return; return;
} }
report = json_pack ("{s:o, s:o, s:o, s:o, s:o," {
" s:o, s:o, s:o, s:o, s:o," json_t *report;
" s:o, s:o, s:o, s:o, s:o,"
" s:o, s:o, s:o, s:o, s:I," report = json_pack ("{s:o, s:o, s:o, s:o, s:o,"
" s:I, s:I, s:I, s:I, s:I," " s:o, s:o, s:o, s:o, s:o,"
" s:I, s:I }", " s:o, s:o, s:o, s:o, s:o,"
/* blocks #1 */ " s:o, s:o, s:o, s:o, s:I,"
"reserve_balance_insufficient_inconsistencies", " s:I, s:I, s:I, s:I, s:I,"
report_reserve_balance_insufficient_inconsistencies, " s:I, s:I }",
/* Tested in test-auditor.sh #3 */ /* blocks #1 */
"total_loss_balance_insufficient", "reserve_balance_insufficient_inconsistencies",
TALER_JSON_from_amount (&total_balance_insufficient_loss), report_reserve_balance_insufficient_inconsistencies,
/* Tested in test-auditor.sh #3 */ /* Tested in test-auditor.sh #3 */
"reserve_balance_summary_wrong_inconsistencies", "total_loss_balance_insufficient",
report_reserve_balance_summary_wrong_inconsistencies, TALER_JSON_from_amount (
"total_balance_summary_delta_plus", &total_balance_insufficient_loss),
TALER_JSON_from_amount ( /* Tested in test-auditor.sh #3 */
&total_balance_summary_delta_plus), "reserve_balance_summary_wrong_inconsistencies",
"total_balance_summary_delta_minus", report_reserve_balance_summary_wrong_inconsistencies,
TALER_JSON_from_amount ( "total_balance_summary_delta_plus",
&total_balance_summary_delta_minus), TALER_JSON_from_amount (
/* blocks #2 */ &total_balance_summary_delta_plus),
"total_escrow_balance", "total_balance_summary_delta_minus",
TALER_JSON_from_amount (&total_escrow_balance), TALER_JSON_from_amount (
"total_withdraw_fee_income", &total_balance_summary_delta_minus),
TALER_JSON_from_amount (&total_withdraw_fee_income), /* blocks #2 */
/* Tested in test-auditor.sh #21 */ "total_escrow_balance",
"reserve_not_closed_inconsistencies", TALER_JSON_from_amount (&total_escrow_balance),
report_reserve_not_closed_inconsistencies, "total_withdraw_fee_income",
/* Tested in test-auditor.sh #21 */ TALER_JSON_from_amount (
"total_balance_reserve_not_closed", &total_withdraw_fee_income),
TALER_JSON_from_amount ( /* Tested in test-auditor.sh #21 */
&total_balance_reserve_not_closed), "reserve_not_closed_inconsistencies",
/* Tested in test-auditor.sh #4/#5/#6/#7/#13 */ report_reserve_not_closed_inconsistencies,
"bad_sig_losses", /* Tested in test-auditor.sh #21 */
report_bad_sig_losses, "total_balance_reserve_not_closed",
/* blocks #3 */ TALER_JSON_from_amount (
/* Tested in test-auditor.sh #4/#5/#6/#7/#13 */ &total_balance_reserve_not_closed),
"total_bad_sig_loss", /* Tested in test-auditor.sh #4/#5/#6/#7/#13 */
TALER_JSON_from_amount (&total_bad_sig_loss), "bad_sig_losses",
/* Tested in test-auditor.sh #14/#15 */ report_bad_sig_losses,
"row_inconsistencies", /* blocks #3 */
report_row_inconsistencies, /* Tested in test-auditor.sh #4/#5/#6/#7/#13 */
/* Tested in test-auditor.sh #23 */ "total_bad_sig_loss",
"denomination_key_validity_withdraw_inconsistencies", TALER_JSON_from_amount (&total_bad_sig_loss),
denomination_key_validity_withdraw_inconsistencies, /* Tested in test-auditor.sh #14/#15 */
"amount_arithmetic_inconsistencies", "row_inconsistencies",
report_amount_arithmetic_inconsistencies, report_row_inconsistencies,
"total_arithmetic_delta_plus", /* Tested in test-auditor.sh #23 */
TALER_JSON_from_amount (&total_arithmetic_delta_plus), "denomination_key_validity_withdraw_inconsistencies",
/* blocks #4 */ denomination_key_validity_withdraw_inconsistencies,
"total_arithmetic_delta_minus", "amount_arithmetic_inconsistencies",
TALER_JSON_from_amount (&total_arithmetic_delta_minus), report_amount_arithmetic_inconsistencies,
"auditor_start_time", "total_arithmetic_delta_plus",
json_from_time_abs (start_time), TALER_JSON_from_amount (
"auditor_end_time", &total_arithmetic_delta_plus),
json_from_time_abs (GNUNET_TIME_absolute_get ()), /* blocks #4 */
"total_irregular_recoups", "total_arithmetic_delta_minus",
TALER_JSON_from_amount (&total_irregular_recoups), TALER_JSON_from_amount (
"start_ppr_reserve_in_serial_id", &total_arithmetic_delta_minus),
(json_int_t) ppr_start.last_reserve_in_serial_id, "auditor_start_time",
/* blocks #5 */ TALER_ARL_json_from_time_abs (
"start_ppr_reserve_out_serial_id", start_time),
(json_int_t) ppr_start.last_reserve_out_serial_id, "auditor_end_time",
"start_ppr_reserve_recoup_serial_id", TALER_ARL_json_from_time_abs (
(json_int_t) ppr_start.last_reserve_recoup_serial_id, GNUNET_TIME_absolute_get ()),
"start_ppr_reserve_close_serial_id", "total_irregular_recoups",
(json_int_t) ppr_start.last_reserve_close_serial_id, TALER_JSON_from_amount (
"end_ppr_reserve_in_serial_id", &total_irregular_recoups),
(json_int_t) ppr.last_reserve_in_serial_id, "start_ppr_reserve_in_serial_id",
"end_ppr_reserve_out_serial_id", (json_int_t) ppr_start.last_reserve_in_serial_id,
(json_int_t) ppr.last_reserve_out_serial_id, /* blocks #5 */
/* blocks #6 */ "start_ppr_reserve_out_serial_id",
"end_ppr_reserve_recoup_serial_id", (json_int_t) ppr_start.
(json_int_t) ppr.last_reserve_recoup_serial_id, last_reserve_out_serial_id,
"end_ppr_reserve_close_serial_id", "start_ppr_reserve_recoup_serial_id",
(json_int_t) ppr.last_reserve_close_serial_id (json_int_t) ppr_start.
); last_reserve_recoup_serial_id,
GNUNET_break (NULL != report); "start_ppr_reserve_close_serial_id",
finish_report (report); (json_int_t) ppr_start.
last_reserve_close_serial_id,
"end_ppr_reserve_in_serial_id",
(json_int_t) ppr.last_reserve_in_serial_id,
"end_ppr_reserve_out_serial_id",
(json_int_t) ppr.last_reserve_out_serial_id,
/* blocks #6 */
"end_ppr_reserve_recoup_serial_id",
(json_int_t) ppr.last_reserve_recoup_serial_id,
"end_ppr_reserve_close_serial_id",
(json_int_t) ppr.last_reserve_close_serial_id
);
GNUNET_break (NULL != report);
TALER_ARL_done (report);
}
} }
@ -1607,11 +1640,11 @@ main (int argc,
"exchange-key", "exchange-key",
"KEY", "KEY",
"public key of the exchange (Crockford base32 encoded)", "public key of the exchange (Crockford base32 encoded)",
&master_pub), &TALER_ARL_master_pub),
GNUNET_GETOPT_option_flag ('r', GNUNET_GETOPT_option_flag ('r',
"restart", "TALER_ARL_restart",
"restart audit from the beginning (required on first run)", "TALER_ARL_restart audit from the beginning (required on first run)",
&restart), &TALER_ARL_restart),
GNUNET_GETOPT_option_timetravel ('T', GNUNET_GETOPT_option_timetravel ('T',
"timetravel"), "timetravel"),
GNUNET_GETOPT_OPTION_END GNUNET_GETOPT_OPTION_END

View File

@ -84,10 +84,10 @@ function audit_only () {
# Also do incremental run # Also do incremental run
$VALGRIND taler-auditor -L DEBUG -c $CONF -m $MASTER_PUB > test-audit-inc.json 2> test-audit-inc.log || exit_fail "auditor failed" $VALGRIND taler-auditor -L DEBUG -c $CONF -m $MASTER_PUB > test-audit-inc.json 2> test-audit-inc.log || exit_fail "auditor failed"
echo -n "." echo -n "."
$VALGRIND taler-wire-auditor -L DEBUG -r -c $CONF -m $MASTER_PUB > test-wire-audit.json 2> test-wire-audit.log || exit_fail "wire auditor failed" $VALGRIND taler-helper-auditor-wire -L DEBUG -r -c $CONF -m $MASTER_PUB > test-wire-audit.json 2> test-wire-audit.log || exit_fail "wire auditor failed"
# Also do incremental run # Also do incremental run
echo -n "." echo -n "."
$VALGRIND taler-wire-auditor -L DEBUG -c $CONF -m $MASTER_PUB > test-wire-audit-inc.json 2> test-wire-audit-inc.log || exit_fail "wire auditor failed" $VALGRIND taler-helper-auditor-wire -L DEBUG -c $CONF -m $MASTER_PUB > test-wire-audit-inc.json 2> test-wire-audit-inc.log || exit_fail "wire auditor failed"
echo " DONE" echo " DONE"
} }
@ -255,7 +255,7 @@ echo -n "Check for lag detection... "
# NOTE: This test is EXPECTED to fail for ~1h after # NOTE: This test is EXPECTED to fail for ~1h after
# re-generating the test database as we do not # re-generating the test database as we do not
# report lag of less than 1h (see GRACE_PERIOD in # report lag of less than 1h (see GRACE_PERIOD in
# taler-wire-auditor.c) # taler-helper-auditor-wire.c)
if [ $DATABASE_AGE -gt 3600 ] if [ $DATABASE_AGE -gt 3600 ]
then then
jq -e .lag_details[0] < test-wire-audit.json > /dev/null || exit_fail "Lag not detected in run without aggregator at age $DELTA" jq -e .lag_details[0] < test-wire-audit.json > /dev/null || exit_fail "Lag not detected in run without aggregator at age $DELTA"
@ -893,7 +893,7 @@ echo "===========15: deposit wire hash wrong================="
# NOTE: This test is EXPECTED to fail for ~1h after # NOTE: This test is EXPECTED to fail for ~1h after
# re-generating the test database as we do not # re-generating the test database as we do not
# report lag of less than 1h (see GRACE_PERIOD in # report lag of less than 1h (see GRACE_PERIOD in
# taler-wire-auditor.c) # taler-helper-auditor-wire.c)
if [ $DATABASE_AGE -gt 3600 ] if [ $DATABASE_AGE -gt 3600 ]
then then
@ -930,7 +930,7 @@ echo "===========16: incorrect wire_out amount================="
# NOTE: This test is EXPECTED to fail for ~1h after # NOTE: This test is EXPECTED to fail for ~1h after
# re-generating the test database as we do not # re-generating the test database as we do not
# report lag of less than 1h (see GRACE_PERIOD in # report lag of less than 1h (see GRACE_PERIOD in
# taler-wire-auditor.c) # taler-helper-auditor-wire.c)
if [ $DATABASE_AGE -gt 3600 ] if [ $DATABASE_AGE -gt 3600 ]
then then
@ -1023,7 +1023,7 @@ echo "===========17: incorrect wire_out timestamp================="
# NOTE: This test is EXPECTED to fail for ~1h after # NOTE: This test is EXPECTED to fail for ~1h after
# re-generating the test database as we do not # re-generating the test database as we do not
# report lag of less than 1h (see GRACE_PERIOD in # report lag of less than 1h (see GRACE_PERIOD in
# taler-wire-auditor.c) # taler-helper-auditor-wire.c)
if [ $DATABASE_AGE -gt 3600 ] if [ $DATABASE_AGE -gt 3600 ]
then then
@ -1115,7 +1115,7 @@ echo "===========19: reserve closure done properly ================="
# NOTE: This test is EXPECTED to fail for ~1h after # NOTE: This test is EXPECTED to fail for ~1h after
# re-generating the test database as we do not # re-generating the test database as we do not
# report lag of less than 1h (see GRACE_PERIOD in # report lag of less than 1h (see GRACE_PERIOD in
# taler-wire-auditor.c) # taler-helper-auditor-wire.c)
if [ $DATABASE_AGE -gt 3600 ] if [ $DATABASE_AGE -gt 3600 ]
then then
@ -1193,7 +1193,7 @@ echo "===========21: reserve closure missreported ================="
# NOTE: This test is EXPECTED to fail for ~1h after # NOTE: This test is EXPECTED to fail for ~1h after
# re-generating the test database as we do not # re-generating the test database as we do not
# report lag of less than 1h (see GRACE_PERIOD in # report lag of less than 1h (see GRACE_PERIOD in
# taler-wire-auditor.c) # taler-helper-auditor-wire.c)
if [ $DATABASE_AGE -gt 3600 ] if [ $DATABASE_AGE -gt 3600 ]
then then
@ -1279,7 +1279,7 @@ echo "===========23: wire out calculations ================="
# NOTE: This test is EXPECTED to fail for ~1h after # NOTE: This test is EXPECTED to fail for ~1h after
# re-generating the test database as we do not # re-generating the test database as we do not
# report lag of less than 1h (see GRACE_PERIOD in # report lag of less than 1h (see GRACE_PERIOD in
# taler-wire-auditor.c) # taler-helper-auditor-wire.c)
if [ $DATABASE_AGE -gt 3600 ] if [ $DATABASE_AGE -gt 3600 ]
then then
@ -1400,7 +1400,7 @@ echo "=========25: inconsistent coin history========="
# NOTE: This test is EXPECTED to fail for ~1h after # NOTE: This test is EXPECTED to fail for ~1h after
# re-generating the test database as we do not # re-generating the test database as we do not
# report lag of less than 1h (see GRACE_PERIOD in # report lag of less than 1h (see GRACE_PERIOD in
# taler-wire-auditor.c) # taler-helper-auditor-wire.c)
if [ $DATABASE_AGE -gt 3600 ] if [ $DATABASE_AGE -gt 3600 ]
then then
@ -1493,7 +1493,7 @@ echo "===========27: duplicate WTID detection ================="
# NOTE: This test is EXPECTED to fail for ~1h after # NOTE: This test is EXPECTED to fail for ~1h after
# re-generating the test database as we do not # re-generating the test database as we do not
# report lag of less than 1h (see GRACE_PERIOD in # report lag of less than 1h (see GRACE_PERIOD in
# taler-wire-auditor.c) # taler-helper-auditor-wire.c)
if [ $DATABASE_AGE -gt 3600 ] if [ $DATABASE_AGE -gt 3600 ]
then then