From 69ac028a13497d9fa0b7ebf5e3c7992a492aab13 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sat, 18 Mar 2017 22:20:48 +0100 Subject: add required separate risk balance per denomination to auditordb --- src/auditor/taler-auditor.c | 54 ++++++++++++++++++++++++------- src/auditordb/plugin_auditordb_postgres.c | 35 ++++++++++++++++---- src/auditordb/test_auditordb.c | 10 ++++-- src/include/taler_auditordb_plugin.h | 19 +++++++---- 4 files changed, 90 insertions(+), 28 deletions(-) diff --git a/src/auditor/taler-auditor.c b/src/auditor/taler-auditor.c index 3939f2801..d128619db 100644 --- a/src/auditor/taler-auditor.c +++ b/src/auditor/taler-auditor.c @@ -1027,10 +1027,16 @@ struct CoinSummary struct DenominationSummary { /** - * Total value of coins issued with this denomination key. + * Total value of outstanding (not deposited) coins issued with this + * denomination key. */ struct TALER_Amount denom_balance; + /** + * Total value of coins issued with this denomination key. + */ + struct TALER_Amount denom_risk; + /** * #GNUNET_YES if this record already existed in the DB. * Used to decide between insert/update in @@ -1120,7 +1126,8 @@ init_denomination (const struct GNUNET_HashCode *denom_hash, ret = adb->get_denomination_balance (adb->cls, asession, denom_hash, - &ds->denom_balance); + &ds->denom_balance, + &ds->denom_risk); if (GNUNET_OK == ret) { ds->in_db = GNUNET_YES; @@ -1134,6 +1141,9 @@ init_denomination (const struct GNUNET_HashCode *denom_hash, GNUNET_assert (GNUNET_OK == TALER_amount_get_zero (currency, &ds->denom_balance)); + GNUNET_assert (GNUNET_OK == + TALER_amount_get_zero (currency, + &ds->denom_risk)); return GNUNET_OK; } @@ -1197,13 +1207,34 @@ sync_denomination (void *cls, // DELETE denomination balance, and REDUCE cc->risk exposure! if (0) { - ret = adb->del_denomination_balance (adb->cls, - asession, - denom_hash); - if (GNUNET_OK == ret) + if (ds->in_db) + ret = adb->del_denomination_balance (adb->cls, + asession, + denom_hash); + 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.fraction) ) ) { - // FIXME: reduce RISK - // FIXME: book denomination expiration profits! + /* The denomination expired and carried a balance; we can now + book the remaining balance as profit, and reduce our risk + exposure by the accumulated risk of the denomination. */ + if (GNUNET_SYSERR == + TALER_amount_subtract (&cc->risk, + &cc->risk, + &ds->denom_risk)) + { + /* Holy smokes, our risk assessment was inconsistent! + This is really, really bad. */ + GNUNET_break (0); + cc->ret = GNUNET_SYSERR; + return GNUNET_OK; + } + + // TODO: book denom_balance expiration profits! } } else @@ -1212,12 +1243,14 @@ sync_denomination (void *cls, ret = adb->update_denomination_balance (adb->cls, asession, denom_hash, - &ds->denom_balance); + &ds->denom_balance, + &ds->denom_risk); else ret = adb->insert_denomination_balance (adb->cls, asession, denom_hash, - &ds->denom_balance); + &ds->denom_balance, + &ds->denom_risk); } if (GNUNET_OK != ret) { @@ -1871,7 +1904,6 @@ analyze_coins (void *cls) /* setup 'cc' */ cc.ret = GNUNET_OK; // FIXME: FIX misnomer "denomination_summary", as this is no longer exactly about denominations! - // FIXME: combine request with the one for the 'risk' summary? dret = adb->get_denomination_summary (adb->cls, asession, &master_pub, diff --git a/src/auditordb/plugin_auditordb_postgres.c b/src/auditordb/plugin_auditordb_postgres.c index 1ef067daf..8c7eca198 100644 --- a/src/auditordb/plugin_auditordb_postgres.c +++ b/src/auditordb/plugin_auditordb_postgres.c @@ -330,6 +330,9 @@ postgres_create_tables (void *cls) ",denom_balance_val INT8 NOT NULL" ",denom_balance_frac INT4 NOT NULL" ",denom_balance_curr VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL" + ",denom_risk_val INT8 NOT NULL" + ",denom_risk_frac INT4 NOT NULL" + ",denom_risk_curr VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL" ")"); /* Table with the sum of the outstanding coins from @@ -679,8 +682,11 @@ postgres_prepare (PGconn *db_conn) ",denom_balance_val" ",denom_balance_frac" ",denom_balance_curr" - ") VALUES ($1,$2,$3,$4);", - 4, NULL); + ",denom_risk_val" + ",denom_risk_frac" + ",denom_risk_curr" + ") VALUES ($1,$2,$3,$4,$5,$6,$7);", + 7, NULL); /* Used in #postgres_update_denomination_balance() */ PREPARE ("denomination_pending_update", @@ -688,8 +694,11 @@ postgres_prepare (PGconn *db_conn) " denom_balance_val=$1" ",denom_balance_frac=$2" ",denom_balance_curr=$3" - " WHERE denom_pub_hash=$4", - 4, NULL); + ",denom_risk_val=$4" + ",denom_risk_frac=$5" + ",denom_risk_curr=$6" + " WHERE denom_pub_hash=$7", + 7, NULL); /* Used in #postgres_get_denomination_balance() */ PREPARE ("denomination_pending_select", @@ -697,6 +706,9 @@ postgres_prepare (PGconn *db_conn) " denom_balance_val" ",denom_balance_frac" ",denom_balance_curr" + ",denom_risk_val" + ",denom_risk_frac" + ",denom_risk_curr" " FROM denomination_pending" " WHERE denom_pub_hash=$1", 1, NULL); @@ -1811,19 +1823,22 @@ postgres_get_reserve_summary (void *cls, * @param session connection to use * @param denom_pub_hash hash of the denomination public key * @param denom_balance value of coins outstanding with this denomination key + * @param denom_risk value of coins issued with this denomination key * @return #GNUNET_OK on success; #GNUNET_SYSERR on failure */ static int postgres_insert_denomination_balance (void *cls, struct TALER_AUDITORDB_Session *session, const struct GNUNET_HashCode *denom_pub_hash, - const struct TALER_Amount *denom_balance) + const struct TALER_Amount *denom_balance, + const struct TALER_Amount *denom_risk) { PGresult *result; int ret; struct GNUNET_PQ_QueryParam params[] = { GNUNET_PQ_query_param_auto_from_type (denom_pub_hash), TALER_PQ_query_param_amount (denom_balance), + TALER_PQ_query_param_amount (denom_risk), GNUNET_PQ_query_param_end }; @@ -1852,18 +1867,21 @@ postgres_insert_denomination_balance (void *cls, * @param session connection to use * @param denom_pub_hash hash of the denomination public key * @param denom_balance value of coins outstanding with this denomination key + * @param denom_risk value of coins issued with this denomination key * @return #GNUNET_OK on success; #GNUNET_SYSERR on failure */ static int postgres_update_denomination_balance (void *cls, struct TALER_AUDITORDB_Session *session, const struct GNUNET_HashCode *denom_pub_hash, - const struct TALER_Amount *denom_balance) + const struct TALER_Amount *denom_balance, + const struct TALER_Amount *denom_risk) { PGresult *result; int ret; struct GNUNET_PQ_QueryParam params[] = { TALER_PQ_query_param_amount (denom_balance), + TALER_PQ_query_param_amount (denom_risk), GNUNET_PQ_query_param_auto_from_type (denom_pub_hash), GNUNET_PQ_query_param_end }; @@ -1892,13 +1910,15 @@ postgres_update_denomination_balance (void *cls, * @param session connection to use * @param denom_pub_hash hash of the denomination public key * @param[out] denom_balance value of coins outstanding with this denomination key + * @param[out] denom_risk value of coins issued with this denomination key * @return #GNUNET_OK on success; #GNUNET_NO if no record found, #GNUNET_SYSERR on failure */ static int postgres_get_denomination_balance (void *cls, struct TALER_AUDITORDB_Session *session, const struct GNUNET_HashCode *denom_pub_hash, - struct TALER_Amount *denom_balance) + struct TALER_Amount *denom_balance, + struct TALER_Amount *denom_risk) { struct GNUNET_PQ_QueryParam params[] = { GNUNET_PQ_query_param_auto_from_type (denom_pub_hash), @@ -1929,6 +1949,7 @@ postgres_get_denomination_balance (void *cls, struct GNUNET_PQ_ResultSpec rs[] = { TALER_PQ_result_spec_amount ("denom_balance", denom_balance), + TALER_PQ_result_spec_amount ("denom_risk", denom_risk), GNUNET_PQ_result_spec_end }; if (GNUNET_OK != diff --git a/src/auditordb/test_auditordb.c b/src/auditordb/test_auditordb.c index 2681a386b..d3e933133 100644 --- a/src/auditordb/test_auditordb.c +++ b/src/auditordb/test_auditordb.c @@ -380,7 +380,8 @@ run (void *cls) plugin->insert_denomination_balance (plugin->cls, session, &denom_pub_hash, - &denom_balance)); + &denom_balance, + &rbalance)); GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Test: update_denomination_balance\n"); @@ -394,7 +395,8 @@ run (void *cls) plugin->update_denomination_balance (plugin->cls, session, &denom_pub_hash, - &denom_balance)); + &denom_balance, + &rbalance)); GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Test: get_denomination_balance\n"); @@ -402,9 +404,11 @@ run (void *cls) plugin->get_denomination_balance (plugin->cls, session, &denom_pub_hash, - &denom_balance2)); + &denom_balance2, + &rbalance2)); FAILIF (0 != memcmp (&denom_balance2, &denom_balance, sizeof (denom_balance))); + FAILIF (0 != memcmp (&rbalance2, &rbalance, sizeof (rbalance))); GNUNET_log (GNUNET_ERROR_TYPE_INFO, diff --git a/src/include/taler_auditordb_plugin.h b/src/include/taler_auditordb_plugin.h index 1a29e5ae5..54e6c5203 100644 --- a/src/include/taler_auditordb_plugin.h +++ b/src/include/taler_auditordb_plugin.h @@ -522,15 +522,16 @@ struct TALER_AUDITORDB_Plugin * @param cls the @e cls of this struct with the plugin-specific state * @param session connection to use * @param denom_pub_hash hash of the denomination public key - * @param denom_balance value of coins outstanding (or issued?) with this denomination key + * @param denom_balance value of coins outstanding with this denomination key + * @param denom_risk value of coins issued with this denomination key * @return #GNUNET_OK on success; #GNUNET_SYSERR on failure */ int (*insert_denomination_balance)(void *cls, struct TALER_AUDITORDB_Session *session, const struct GNUNET_HashCode *denom_pub_hash, - const struct TALER_Amount *denom_balance); - + const struct TALER_Amount *denom_balance, + const struct TALER_Amount *denom_risk); /** @@ -540,14 +541,16 @@ struct TALER_AUDITORDB_Plugin * @param cls the @e cls of this struct with the plugin-specific state * @param session connection to use * @param denom_pub_hash hash of the denomination public key - * @param denom_balance value of coins outstanding (or issued?) with this denomination key + * @param denom_balance value of coins outstanding with this denomination key + * @param denom_risk value of coins issued with this denomination key * @return #GNUNET_OK on success; #GNUNET_SYSERR on failure */ int (*update_denomination_balance)(void *cls, struct TALER_AUDITORDB_Session *session, const struct GNUNET_HashCode *denom_pub_hash, - const struct TALER_Amount *denom_balance); + const struct TALER_Amount *denom_balance, + const struct TALER_Amount *denom_risk); /** @@ -556,14 +559,16 @@ struct TALER_AUDITORDB_Plugin * @param cls the @e cls of this struct with the plugin-specific state * @param session connection to use * @param denom_pub_hash hash of the denomination public key - * @param[out] denom_balance value of coins outstanding (or issued?) with this denomination key + * @param[out] denom_balance value of coins outstanding with this denomination key + * @param[out] denom_risk value of coins issued with this denomination key * @return #GNUNET_OK on success; #GNUNET_NO if no record found, #GNUNET_SYSERR on failure */ int (*get_denomination_balance)(void *cls, struct TALER_AUDITORDB_Session *session, const struct GNUNET_HashCode *denom_pub_hash, - struct TALER_Amount *denom_balance); + struct TALER_Amount *denom_balance, + struct TALER_Amount *denom_risk); /** -- cgit v1.2.3