From e4a4a7e193705a12e04ab6b4a3360168ffb4b27a Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sat, 18 Mar 2017 23:03:00 +0100 Subject: finish sync_denomination() implementation --- src/auditor/taler-auditor.c | 70 ++++++++++++++++++++++++------- src/auditordb/plugin_auditordb_postgres.c | 66 +++-------------------------- src/auditordb/test_auditordb.c | 20 ++------- src/include/taler_auditordb_plugin.h | 20 ++------- 4 files changed, 68 insertions(+), 108 deletions(-) (limited to 'src') diff --git a/src/auditor/taler-auditor.c b/src/auditor/taler-auditor.c index eb633b04d..186b29eb8 100644 --- a/src/auditor/taler-auditor.c +++ b/src/auditor/taler-auditor.c @@ -26,7 +26,6 @@ * * TODO: * - FIXME: do proper transaction history check in #check_transaction_history() - * - COMPLETE: deal with risk / expired denomination keys in #sync_denomination() * - SANITY: rename functions/operations to better describe what they do! * - OPTIMIZE/SIMPLIFY: modify auditordb to return DK when we inquire about deposit/refresh/refund, * so we can avoid the costly #get_coin_summary with the transaction history building @@ -57,6 +56,11 @@ */ #define MAX_COIN_SUMMARIES 4 +/** + * Use a 1 day grace period to deal with clocks not being perfectly synchronized. + */ +#define DEPOSIT_GRACE_PERIOD GNUNET_TIME_UNIT_DAYS + /** * Return value from main(). */ @@ -305,11 +309,11 @@ get_denomination_info (const struct TALER_DenominationPublicKey *denom_pub, dkip = GNUNET_CONTAINER_multihashmap_get (denominations, dh); if (NULL != dkip) - { - /* cache hit */ - *dki = dkip; - return GNUNET_OK; - } + { + /* cache hit */ + *dki = dkip; + return GNUNET_OK; + } dkip = GNUNET_new (struct TALER_EXCHANGEDB_DenominationKeyInformationP); ret = edb->get_denomination_info (edb->cls, esession, @@ -1018,6 +1022,11 @@ struct DenominationSummary */ struct TALER_Amount denom_risk; + /** + * Denomination key information for this denomination. + */ + const struct TALER_EXCHANGEDB_DenominationKeyInformationP *dki; + /** * #GNUNET_YES if this record already existed in the DB. * Used to decide between insert/update in @@ -1133,11 +1142,13 @@ init_denomination (const struct GNUNET_HashCode *denom_hash, * Obtain the denomination summary for the given @a dh * * @param cc our execution context + * @param dki denomination key information for @a dh * @param dh the denomination hash to use for the lookup * @return NULL on error */ static struct DenominationSummary * get_denomination_summary (struct CoinContext *cc, + const struct TALER_EXCHANGEDB_DenominationKeyInformationP *dki, const struct GNUNET_HashCode *dh) { struct DenominationSummary *ds; @@ -1147,6 +1158,7 @@ get_denomination_summary (struct CoinContext *cc, if (NULL != ds) return ds; ds = GNUNET_new (struct DenominationSummary); + ds->dki = dki; if (GNUNET_OK != init_denomination (dh, ds)) @@ -1181,13 +1193,21 @@ sync_denomination (void *cls, { struct CoinContext *cc = cls; struct DenominationSummary *ds = value; + const struct TALER_EXCHANGEDB_DenominationKeyInformationP *dki = ds->dki; + struct GNUNET_TIME_Absolute now; + struct GNUNET_TIME_Absolute expire_deposit; + struct GNUNET_TIME_Absolute expire_deposit_grace; int ret; - - // COMPLETE: if expired, insert remaining balance historic denomination revenue, - // DELETE denomination balance, and REDUCE cc->risk exposure! - if (0 /* COMPLETE: add expiration check! */) + now = GNUNET_TIME_absolute_get (); + expire_deposit = GNUNET_TIME_absolute_ntoh (dki->properties.expire_deposit); + /* add day grace period to deal with clocks not being perfectly synchronized */ + expire_deposit_grace = GNUNET_TIME_absolute_add (expire_deposit, + DEPOSIT_GRACE_PERIOD); + if (now.abs_value_us > expire_deposit_grace.abs_value_us) { + /* Denominationkey has expired, book remaining balance of + outstanding coins as revenue; and reduce cc->risk exposure. */ if (ds->in_db) ret = adb->del_denomination_balance (adb->cls, asession, @@ -1195,9 +1215,7 @@ sync_denomination (void *cls, else ret = GNUNET_OK; if ( (GNUNET_OK == ret) && - ( (0 != ds->denom_balance.value) || - (0 != ds->denom_balance.fraction) || - (0 != ds->denom_risk.value) || + ( (0 != ds->denom_risk.value) || (0 != ds->denom_risk.fraction) ) ) { /* The denomination expired and carried a balance; we can now @@ -1214,8 +1232,25 @@ sync_denomination (void *cls, cc->ret = GNUNET_SYSERR; return GNUNET_OK; } - - // TODO: book denom_balance expiration profits! + } + if ( (GNUNET_OK == ret) && + ( (0 != ds->denom_balance.value) || + (0 != ds->denom_balance.fraction) ) ) + { + /* book denom_balance coin expiration profits! */ + if (GNUNET_OK != + adb->insert_historic_denom_revenue (adb->cls, + asession, + &master_pub, + denom_hash, + expire_deposit, + &ds->denom_balance)) + { + /* Failed to store profits? Bad database */ + GNUNET_break (0); + cc->ret = GNUNET_SYSERR; + return GNUNET_OK; + } } } else @@ -1412,6 +1447,7 @@ withdraw_cb (void *cls, return GNUNET_SYSERR; } ds = get_denomination_summary (cc, + dki, &dh); TALER_amount_ntoh (&value, &dki->properties.value); @@ -1590,6 +1626,7 @@ refresh_session_cb (void *cls, struct TALER_Amount value; dsi = get_denomination_summary (cc, + new_dki[i], &new_dki[i]->properties.denom_hash); TALER_amount_ntoh (&value, &new_dki[i]->properties.value); @@ -1614,6 +1651,7 @@ refresh_session_cb (void *cls, /* update old coin's denomination balance */ dso = get_denomination_summary (cc, + dki, &dki->properties.denom_hash); if (GNUNET_OK != TALER_amount_subtract (&dso->denom_balance, @@ -1729,6 +1767,7 @@ deposit_cb (void *cls, /* update old coin's denomination balance */ ds = get_denomination_summary (cc, + dki, &dki->properties.denom_hash); if (GNUNET_OK != TALER_amount_subtract (&ds->denom_balance, @@ -1842,6 +1881,7 @@ refund_cb (void *cls, /* update coin's denomination balance */ ds = get_denomination_summary (cc, + dki, &dki->properties.denom_hash); if (GNUNET_OK != TALER_amount_add (&ds->denom_balance, diff --git a/src/auditordb/plugin_auditordb_postgres.c b/src/auditordb/plugin_auditordb_postgres.c index 58f1152fb..ddacca657 100644 --- a/src/auditordb/plugin_auditordb_postgres.c +++ b/src/auditordb/plugin_auditordb_postgres.c @@ -375,15 +375,7 @@ postgres_create_tables (void *cls) ",revenue_balance_val INT8 NOT NULL" ",revenue_balance_frac INT4 NOT NULL" ",revenue_balance_curr VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL" - ",deposit_fee_balance_val INT8 NOT NULL" - ",deposit_fee_balance_frac INT4 NOT NULL" - ",deposit_fee_balance_curr VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL" - ",melt_fee_balance_val INT8 NOT NULL" - ",melt_fee_balance_frac INT4 NOT NULL" - ",melt_fee_balance_curr VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL" - ",refund_fee_balance_val INT8 NOT NULL" - ",refund_fee_balance_frac INT4 NOT NULL" - ",refund_fee_balance_curr VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL" ")"); + ")"); /* Table with historic losses; basically, when we need to @@ -779,17 +771,8 @@ postgres_prepare (PGconn *db_conn) ",revenue_balance_val" ",revenue_balance_frac" ",revenue_balance_curr" - ",deposit_fee_balance_val" - ",deposit_fee_balance_frac" - ",deposit_fee_balance_curr" - ",melt_fee_balance_val" - ",melt_fee_balance_frac" - ",melt_fee_balance_curr" - ",refund_fee_balance_val" - ",refund_fee_balance_frac" - ",refund_fee_balance_curr" - ") VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15);", - 15, NULL); + ") VALUES ($1,$2,$3,$4,$5,$6);", + 6, NULL); /* Used in #postgres_select_historic_denom_revenue() */ PREPARE ("historic_denomination_revenue_select", @@ -799,15 +782,6 @@ postgres_prepare (PGconn *db_conn) ",revenue_balance_val" ",revenue_balance_frac" ",revenue_balance_curr" - ",deposit_fee_balance_val" - ",deposit_fee_balance_frac" - ",deposit_fee_balance_curr" - ",melt_fee_balance_val" - ",melt_fee_balance_frac" - ",melt_fee_balance_curr" - ",refund_fee_balance_val" - ",refund_fee_balance_frac" - ",refund_fee_balance_curr" " FROM historic_denomination_revenue" " WHERE master_pub=$1;", 1, NULL); @@ -2133,9 +2107,6 @@ postgres_get_denomination_summary (void *cls, * @param revenue_balance what was the total profit made from * deposit fees, melting fees, refresh fees * and coins that were never returned? - * @param deposit_fee_balance total profits from deposit fees - * @param melt_fee_balance total profits from melting fees - * @param refund_fee_balance total profits from refund fees * @return #GNUNET_OK on success; #GNUNET_SYSERR on failure */ static int @@ -2144,10 +2115,7 @@ postgres_insert_historic_denom_revenue (void *cls, const struct TALER_MasterPublicKeyP *master_pub, const struct GNUNET_HashCode *denom_pub_hash, struct GNUNET_TIME_Absolute revenue_timestamp, - const struct TALER_Amount *revenue_balance, - const struct TALER_Amount *deposit_fee_balance, - const struct TALER_Amount *melt_fee_balance, - const struct TALER_Amount *refund_fee_balance) + const struct TALER_Amount *revenue_balance) { PGresult *result; int ret; @@ -2156,24 +2124,9 @@ postgres_insert_historic_denom_revenue (void *cls, GNUNET_PQ_query_param_auto_from_type (denom_pub_hash), GNUNET_PQ_query_param_auto_from_type (&revenue_timestamp), TALER_PQ_query_param_amount (revenue_balance), - TALER_PQ_query_param_amount (deposit_fee_balance), - TALER_PQ_query_param_amount (melt_fee_balance), - TALER_PQ_query_param_amount (refund_fee_balance), GNUNET_PQ_query_param_end }; - GNUNET_assert (GNUNET_YES == - TALER_amount_cmp_currency (revenue_balance, - deposit_fee_balance)); - - GNUNET_assert (GNUNET_YES == - TALER_amount_cmp_currency (revenue_balance, - melt_fee_balance)); - - GNUNET_assert (GNUNET_YES == - TALER_amount_cmp_currency (revenue_balance, - refund_fee_balance)); - result = GNUNET_PQ_exec_prepared (session->conn, "historic_denomination_revenue_insert", params); @@ -2240,16 +2193,10 @@ postgres_select_historic_denom_revenue (void *cls, struct GNUNET_HashCode denom_pub_hash; struct GNUNET_TIME_Absolute revenue_timestamp; struct TALER_Amount revenue_balance; - struct TALER_Amount deposit_fee_balance; - struct TALER_Amount melt_fee_balance; - struct TALER_Amount refund_fee_balance; struct GNUNET_PQ_ResultSpec rs[] = { GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash", &denom_pub_hash), GNUNET_PQ_result_spec_auto_from_type ("revenue_timestamp", &revenue_timestamp), TALER_PQ_result_spec_amount ("revenue_balance", &revenue_balance), - TALER_PQ_result_spec_amount ("deposit_fee_balance", &deposit_fee_balance), - TALER_PQ_result_spec_amount ("melt_fee_balance", &melt_fee_balance), - TALER_PQ_result_spec_amount ("refund_fee_balance", &refund_fee_balance), GNUNET_PQ_result_spec_end }; @@ -2264,10 +2211,7 @@ postgres_select_historic_denom_revenue (void *cls, ret = cb (cb_cls, &denom_pub_hash, revenue_timestamp, - &revenue_balance, - &deposit_fee_balance, - &melt_fee_balance, - &refund_fee_balance); + &revenue_balance); switch (ret) { case GNUNET_OK: diff --git a/src/auditordb/test_auditordb.c b/src/auditordb/test_auditordb.c index 03ceb609d..24184aee9 100644 --- a/src/auditordb/test_auditordb.c +++ b/src/auditordb/test_auditordb.c @@ -461,10 +461,7 @@ run (void *cls) &master_pub, &denom_pub_hash, past, - &rbalance, - &deposit_fee_balance, - &melt_fee_balance, - &refund_fee_balance)); + &rbalance)); FAILIF (GNUNET_OK != plugin->insert_historic_denom_revenue (plugin->cls, @@ -472,10 +469,7 @@ run (void *cls) &master_pub, &rnd_hash, now, - &rbalance, - &deposit_fee_balance, - &melt_fee_balance, - &refund_fee_balance)); + &rbalance)); GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Test: select_historic_denom_revenue\n"); @@ -484,10 +478,7 @@ run (void *cls) select_historic_denom_revenue_result (void *cls, const struct GNUNET_HashCode *denom_pub_hash2, struct GNUNET_TIME_Absolute revenue_timestamp2, - const struct TALER_Amount *revenue_balance2, - const struct TALER_Amount *deposit_fee_balance2, - const struct TALER_Amount *melt_fee_balance2, - const struct TALER_Amount *refund_fee_balance2) + const struct TALER_Amount *revenue_balance2) { static int n = 0; @@ -500,10 +491,7 @@ run (void *cls) && 0 != memcmp (&revenue_timestamp2, &now, sizeof (now))) || (0 != memcmp (denom_pub_hash2, &denom_pub_hash, sizeof (denom_pub_hash)) && 0 != memcmp (denom_pub_hash2, &rnd_hash, sizeof (rnd_hash))) - || 0 != memcmp (revenue_balance2, &rbalance, sizeof (rbalance)) - || 0 != memcmp (deposit_fee_balance2, &deposit_fee_balance, sizeof (deposit_fee_balance)) - || 0 != memcmp (melt_fee_balance2, &melt_fee_balance, sizeof (melt_fee_balance)) - || 0 != memcmp (refund_fee_balance2, &refund_fee_balance, sizeof (refund_fee_balance))) + || 0 != memcmp (revenue_balance2, &rbalance, sizeof (rbalance))) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "select_historic_denom_revenue_result: result does not match\n"); diff --git a/src/include/taler_auditordb_plugin.h b/src/include/taler_auditordb_plugin.h index a947012df..4443ba5ff 100644 --- a/src/include/taler_auditordb_plugin.h +++ b/src/include/taler_auditordb_plugin.h @@ -53,10 +53,6 @@ typedef int * @param revenue_balance what was the total profit made from * deposit fees, melting fees, refresh fees * and coins that were never returned? - * @param deposit_fee_balance total profits from deposit fees - * @param melt_fee_balance total profits from melting fees - * @param refund_fee_balance total profits from refund fees - * * @return sets the return value of select_denomination_info(), * #GNUNET_OK to continue, * #GNUNET_NO to stop processing further rows @@ -66,10 +62,7 @@ typedef int (*TALER_AUDITORDB_HistoricDenominationRevenueDataCallback)(void *cls, const struct GNUNET_HashCode *denom_pub_hash, struct GNUNET_TIME_Absolute revenue_timestamp, - const struct TALER_Amount *revenue_balance, - const struct TALER_Amount *deposit_fee_balance, - const struct TALER_Amount *melt_fee_balance, - const struct TALER_Amount *refund_fee_balance); + const struct TALER_Amount *revenue_balance); /** @@ -650,10 +643,7 @@ struct TALER_AUDITORDB_Plugin * @param revenue_balance what was the total profit made from * deposit fees, melting fees, refresh fees * and coins that were never returned? - * @param deposit_fee_balance total profits from deposit fees - * @param melt_fee_balance total profits from melting fees - * @param refund_fee_balance total profits from refund fees - * @return #GNUNET_OK on success; #GNUNET_SYSERR on failure + * @return #GNUNET_OK on success; #GNUNET_SYSERR on failure */ int (*insert_historic_denom_revenue)(void *cls, @@ -661,10 +651,8 @@ struct TALER_AUDITORDB_Plugin const struct TALER_MasterPublicKeyP *master_pub, const struct GNUNET_HashCode *denom_pub_hash, struct GNUNET_TIME_Absolute revenue_timestamp, - const struct TALER_Amount *revenue_balance, - const struct TALER_Amount *deposit_fee_balance, - const struct TALER_Amount *melt_fee_balance, - const struct TALER_Amount *refund_fee_balance); + const struct TALER_Amount *revenue_balance); + /** * Obtain all of the historic denomination key revenue -- cgit v1.2.3