diff options
-rw-r--r-- | contrib/auditor-report.tex.j2 | 6 | ||||
-rw-r--r-- | src/auditor/taler-auditor.c | 183 | ||||
-rw-r--r-- | src/auditordb/plugin_auditordb_postgres.c | 294 | ||||
-rw-r--r-- | src/auditordb/test_auditordb.c | 111 | ||||
-rw-r--r-- | src/include/taler_auditordb_plugin.h | 88 |
5 files changed, 300 insertions, 382 deletions
diff --git a/contrib/auditor-report.tex.j2 b/contrib/auditor-report.tex.j2 index 6abb0d47b..45b049f28 100644 --- a/contrib/auditor-report.tex.j2 +++ b/contrib/auditor-report.tex.j2 @@ -55,6 +55,10 @@ be {\bf {{ data.total_escrow_balance }}}. The active operational risk stands at {\bf {{ data.total_active_risk }}}. +\noindent +Loss (actualized risk from paybacks) is +{\bf {{ data.total_payback_loss }}}. + \section{Income} @@ -200,6 +204,8 @@ exposure} is the amount of coins in circulation for a particular denominatin and the maximum loss for the exchange from this type of compromise. +% FIXME: expand to include actual losses (materizlied risk)! + {% if data.emergencies|length() == 0 %} {\bf No emergencies detected.} {% else %} diff --git a/src/auditor/taler-auditor.c b/src/auditor/taler-auditor.c index a09fb0496..6b46faeab 100644 --- a/src/auditor/taler-auditor.c +++ b/src/auditor/taler-auditor.c @@ -24,7 +24,16 @@ * - Similarly, we do not check that the outgoing wire transfers match those * given in the 'wire_out' table. This needs to be checked separately! * + * * KNOWN BUGS: + * - TT_PAYBACK cases should be checked in check_transaction_history (and + * maybe other places?) + * - we also seem to nowhere check the denomination signatures over the coins + * (While as the exchange could easily falsify those, we should + * probably check as otherwise insider *without* RSA private key + * access could still create false paybacks to drain exchange funds!) + * - we don't check that for payback operations the denomination was actually + * revoked (FIXME exists!) * - error handling if denomination keys are used that are not known to the * auditor is, eh, awful / non-existent. We just throw the DB's constraint * violation back at the user. Great UX. @@ -266,6 +275,11 @@ static struct TALER_Amount total_escrow_balance; static struct TALER_Amount total_risk; /** + * Actualized risk (= loss) from paybacks. + */ +static struct TALER_Amount total_payback_loss; + +/** * Total withdraw fees earned. */ static struct TALER_Amount total_withdraw_fee_income; @@ -1276,13 +1290,13 @@ handle_payback_by_reserve (void *cls, */ static int handle_reserve_closed (void *cls, - uint64_t rowid, - struct GNUNET_TIME_Absolute execution_date, - const struct TALER_Amount *amount_with_fee, - const struct TALER_Amount *closing_fee, - const struct TALER_ReservePublicKeyP *reserve_pub, - const char *receiver_account, - const struct TALER_WireTransferIdentifierRawP *transfer_details) + uint64_t rowid, + struct GNUNET_TIME_Absolute execution_date, + const struct TALER_Amount *amount_with_fee, + const struct TALER_Amount *closing_fee, + const struct TALER_ReservePublicKeyP *reserve_pub, + const char *receiver_account, + const struct TALER_WireTransferIdentifierRawP *transfer_details) { struct ReserveContext *rc = cls; struct GNUNET_HashCode key; @@ -2256,7 +2270,7 @@ wire_transfer_information_cb (void *cls, esession, coin_pub, GNUNET_YES, - &tl); + &tl); if ( (qs < 0) || (NULL == tl) ) { @@ -2835,6 +2849,11 @@ struct DenominationSummary struct TALER_Amount denom_risk; /** + * Total value of coins subjected to payback with this denomination key. + */ + struct TALER_Amount denom_payback; + + /** * How many coins (not their amount!) of this denomination * did the exchange issue overall? */ @@ -2896,6 +2915,7 @@ init_denomination (const struct GNUNET_HashCode *denom_hash, denom_hash, &ds->denom_balance, &ds->denom_risk, + &ds->denom_payback, &ds->num_issued); if (0 > qs) { @@ -2917,6 +2937,9 @@ init_denomination (const struct GNUNET_HashCode *denom_hash, GNUNET_assert (GNUNET_OK == TALER_amount_get_zero (currency, &ds->denom_risk)); + GNUNET_assert (GNUNET_OK == + TALER_amount_get_zero (currency, + &ds->denom_payback)); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting balance for denomination `%s' is %s\n", GNUNET_h2s (denom_hash), @@ -3029,11 +3052,12 @@ sync_denomination (void *cls, TALER_amount2s (&ds->denom_balance)); if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != (qs = adb->insert_historic_denom_revenue (adb->cls, - asession, - &master_pub, - denom_hash, - expire_deposit, - &ds->denom_balance))) + asession, + &master_pub, + denom_hash, + expire_deposit, + &ds->denom_balance, + &ds->denom_payback))) { /* Failed to store profits? Bad database */ GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); @@ -3075,6 +3099,7 @@ sync_denomination (void *cls, denom_hash, &ds->denom_balance, &ds->denom_risk, + &ds->denom_payback, ds->num_issued); else qs = adb->insert_denomination_balance (adb->cls, @@ -3082,6 +3107,7 @@ sync_denomination (void *cls, denom_hash, &ds->denom_balance, &ds->denom_risk, + &ds->denom_payback, ds->num_issued); } } @@ -3146,6 +3172,8 @@ withdraw_cb (void *cls, &dh); if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs) { + /* The key not existing should be prevented by foreign key constraints, + so must be a transient DB error. */ GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); cc->qs = qs; return GNUNET_SYSERR; @@ -3907,9 +3935,84 @@ refund_cb (void *cls, /** + * Check that the payback operation was properly initiated by a coin + * and update the denomination's losses accordingly. + * + * @param cls a `struct CoinContext *` + * @param rowid row identifier used to uniquely identify the payback operation + * @param amount how much should be added back to the reserve + * @param coin public information about the coin + * @param coin_sig signature with @e coin_pub of type #TALER_SIGNATURE_WALLET_COIN_PAYBACK + * @param coin_blind blinding factor used to blind the coin + * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop + */ +static int +check_payback (struct CoinContext *cc, + uint64_t rowid, + const struct TALER_Amount *amount, + const struct TALER_CoinPublicInfo *coin, + const struct TALER_DenominationPublicKey *denom_pub, + const struct TALER_CoinSpendSignatureP *coin_sig, + const struct TALER_DenominationBlindingKeyP *coin_blind) +{ + struct TALER_PaybackRequestPS pr; + struct DenominationSummary *ds; + enum GNUNET_DB_QueryStatus qs; + const struct TALER_EXCHANGEDB_DenominationKeyInformationP *dki; + + qs = get_denomination_info (denom_pub, + &dki, + &pr.h_denom_pub); + if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs) + { + /* The key not existing should be prevented by foreign key constraints, + so must be a transient DB error. */ + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + cc->qs = qs; + return GNUNET_SYSERR; + } + pr.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_PAYBACK); + pr.purpose.size = htonl (sizeof (pr)); + pr.coin_pub = coin->coin_pub; + pr.coin_blind = *coin_blind; + if (GNUNET_OK != + GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_PAYBACK, + &pr.purpose, + &coin_sig->eddsa_signature, + &coin->coin_pub.eddsa_pub)) + { + report (report_bad_sig_losses, + json_pack ("{s:s, s:I, s:o, s:o}", + "operation", "payback", + "row", (json_int_t) rowid, + "loss", TALER_JSON_from_amount (amount), + "coin_pub", GNUNET_JSON_from_data_auto (&coin->coin_pub))); + GNUNET_break (GNUNET_OK == + TALER_amount_add (&total_bad_sig_loss, + &total_bad_sig_loss, + amount)); + return GNUNET_OK; + } + ds = get_denomination_summary (cc, + dki, + &dki->properties.denom_hash); + /* FIXME: should check that denomination was actually revoked! */ + GNUNET_break (GNUNET_OK == + TALER_amount_add (&ds->denom_payback, + &ds->denom_payback, + amount)); + GNUNET_break (GNUNET_OK == + TALER_amount_add (&total_payback_loss, + &total_payback_loss, + amount)); + return GNUNET_OK; +} + + +/** * Function called about paybacks the exchange has to perform. * - * @param cls closure + * @param cls a `struct CoinContext *` * @param rowid row identifier used to uniquely identify the payback operation * @param timestamp when did we receive the payback request * @param amount how much should be added back to the reserve @@ -3928,10 +4031,17 @@ payback_cb (void *cls, const struct TALER_CoinPublicInfo *coin, const struct TALER_DenominationPublicKey *denom_pub, const struct TALER_CoinSpendSignatureP *coin_sig, - const struct TALER_DenominationBlindingKeyP *coin_blind) + const struct TALER_DenominationBlindingKeyP *coin_blind) { - GNUNET_assert (0); // #5777: NOT implemented! (updated losses from payback/denomination) - return GNUNET_SYSERR; + struct CoinContext *cc = cls; + + return check_payback (cc, + rowid, + amount, + coin, + denom_pub, + coin_sig, + coin_blind); } @@ -3939,7 +4049,7 @@ payback_cb (void *cls, * Function called about paybacks on refreshed coins the exchange has to * perform. * - * @param cls closure + * @param cls a `struct CoinContext *` * @param rowid row identifier used to uniquely identify the payback operation * @param timestamp when did we receive the payback request * @param amount how much should be added back to the reserve @@ -3960,8 +4070,15 @@ payback_refresh_cb (void *cls, const struct TALER_CoinSpendSignatureP *coin_sig, const struct TALER_DenominationBlindingKeyP *coin_blind) { - GNUNET_assert (0); // #5777: NOT implemented! (updated denom gains from payback) - return GNUNET_SYSERR; + struct CoinContext *cc = cls; + + return check_payback (cc, + rowid, + amount, + coin, + denom_pub, + coin_sig, + coin_blind); } @@ -4017,7 +4134,8 @@ analyze_coins (void *cls) &total_deposit_fee_income, &total_melt_fee_income, &total_refund_fee_income, - &total_risk); + &total_risk, + &total_payback_loss); if (0 > qsx) { GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qsx); @@ -4113,7 +4231,8 @@ analyze_coins (void *cls) &total_deposit_fee_income, &total_melt_fee_income, &total_refund_fee_income, - &total_risk); + &total_risk, + &total_payback_loss); else qs = adb->insert_balance_summary (adb->cls, asession, @@ -4122,7 +4241,8 @@ analyze_coins (void *cls) &total_deposit_fee_income, &total_melt_fee_income, &total_refund_fee_income, - &total_risk); + &total_risk, + &total_payback_loss); if (0 >= qs) { GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); @@ -4147,11 +4267,12 @@ analyze_coins (void *cls) return qs; } GNUNET_log (GNUNET_ERROR_TYPE_INFO, - _("Concluded coin audit step at %llu/%llu/%llu/%llu\n"), + _("Concluded coin audit step at %llu/%llu/%llu/%llu/%llu\n"), (unsigned long long) ppc.last_deposit_serial_id, (unsigned long long) ppc.last_melt_serial_id, (unsigned long long) ppc.last_refund_serial_id, - (unsigned long long) ppc.last_withdraw_serial_id); + (unsigned long long) ppc.last_withdraw_serial_id, + (unsigned long long) ppc.last_payback_refresh_serial_id); return qs; } @@ -4651,6 +4772,9 @@ run (void *cls, &total_risk)); GNUNET_assert (GNUNET_OK == TALER_amount_get_zero (currency, + &total_payback_loss)); + GNUNET_assert (GNUNET_OK == + TALER_amount_get_zero (currency, &total_withdraw_fee_income)); GNUNET_assert (GNUNET_OK == TALER_amount_get_zero (currency, @@ -4753,7 +4877,7 @@ run (void *cls, " s:o, s:o, s:o, s:o, s:o," " s:o, s:o, s:o, s:o, s:o," " s:o, s:o, s:o, s:o, s:I," - " s:o }", + " s:o, s:o }", /* blocks of 5 for easier counting/matching to format string */ /* block */ "reserve_balance_insufficient_inconsistencies", @@ -4791,7 +4915,7 @@ run (void *cls, /* block */ "total_balance_reserve_not_closed", TALER_JSON_from_amount (&total_balance_reserve_not_closed), - "wire_out_inconsistencies", + "wire_out_inconsistencies", report_wire_out_inconsistencies, "total_wire_out_delta_plus", TALER_JSON_from_amount (&total_wire_out_delta_plus), @@ -4834,7 +4958,10 @@ run (void *cls, (json_int_t) number_missed_deposit_confirmations, /* block */ "missing_deposit_confirmation_total", - TALER_JSON_from_amount (&total_missed_deposit_confirmations)); + TALER_JSON_from_amount (&total_missed_deposit_confirmations), + "total_payback_loss", + TALER_JSON_from_amount (&total_payback_loss) + ); GNUNET_break (NULL != report); json_dumpf (report, stdout, diff --git a/src/auditordb/plugin_auditordb_postgres.c b/src/auditordb/plugin_auditordb_postgres.c index e5e3764a6..67a8d7a88 100644 --- a/src/auditordb/plugin_auditordb_postgres.c +++ b/src/auditordb/plugin_auditordb_postgres.c @@ -142,7 +142,6 @@ postgres_drop_tables (void *cls, struct GNUNET_PQ_ExecuteStatement es[] = { GNUNET_PQ_make_execute ("DROP TABLE IF EXISTS auditor_predicted_result;"), GNUNET_PQ_make_execute ("DROP TABLE IF EXISTS auditor_historic_ledger;"), - GNUNET_PQ_make_execute ("DROP TABLE IF EXISTS auditor_historic_losses;"), GNUNET_PQ_make_execute ("DROP TABLE IF EXISTS auditor_historic_denomination_revenue;"), GNUNET_PQ_make_execute ("DROP TABLE IF EXISTS auditor_balance_summary;"), GNUNET_PQ_make_execute ("DROP TABLE IF EXISTS auditor_denomination_pending;"), @@ -329,6 +328,9 @@ postgres_create_tables (void *cls) ",denom_risk_val INT8 NOT NULL" ",denom_risk_frac INT4 NOT NULL" ",denom_risk_curr VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL" + ",payback_loss_val INT8 NOT NULL" + ",payback_loss_frac INT4 NOT NULL" + ",payback_loss_curr VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL" ")"), /* Table with the sum of the outstanding coins from "auditor_denomination_pending" (denom_pubs must belong to the @@ -353,6 +355,9 @@ postgres_create_tables (void *cls) ",risk_val INT8 NOT NULL" ",risk_frac INT4 NOT NULL" ",risk_curr VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL" + ",loss_val INT8 NOT NULL" + ",loss_frac INT4 NOT NULL" + ",loss_curr VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL" ")"), /* Table with historic profits; basically, when a denom_pub has expired and everything associated with it is garbage collected, @@ -370,16 +375,6 @@ 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" - ")"), - /* Table with historic losses; basically, when we need to - invalidate a denom_pub because the denom_priv was - compromised, we incur a loss. These losses are totaled - up here. (NOTE: the 'bankrupcy' protocol is not yet - implemented, so right now this table is not used.) */ - GNUNET_PQ_make_execute ("CREATE TABLE IF NOT EXISTS auditor_historic_losses" - "(master_pub BYTEA CONSTRAINT master_pub_ref REFERENCES auditor_exchanges(master_pub) ON DELETE CASCADE" - ",denom_pub_hash BYTEA PRIMARY KEY CHECK (LENGTH(denom_pub_hash)=64)" - ",loss_timestamp INT8 NOT NULL" ",loss_balance_val INT8 NOT NULL" ",loss_balance_frac INT4 NOT NULL" ",loss_balance_curr VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL" @@ -440,8 +435,8 @@ postgres_create_tables (void *cls) ")"), GNUNET_PQ_make_try_execute ("CREATE INDEX history_ledger_by_master_pub_and_time " "ON auditor_historic_ledger(master_pub,timestamp)"), - /* Table with the sum of the ledger, auditor_historic_revenue, - auditor_historic_losses and the auditor_reserve_balance. This is the + /* Table with the sum of the ledger, auditor_historic_revenue and + the auditor_reserve_balance. This is the final amount that the exchange should have in its bank account right now. */ GNUNET_PQ_make_execute ("CREATE TABLE IF NOT EXISTS auditor_predicted_result" @@ -855,8 +850,11 @@ postgres_prepare (PGconn *db_conn) ",denom_risk_val" ",denom_risk_frac" ",denom_risk_curr" - ") VALUES ($1,$2,$3,$4,$5,$6,$7,$8);", - 8), + ",payback_loss_val" + ",payback_loss_frac" + ",payback_loss_curr" + ") VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11);", + 11), /* Used in #postgres_update_denomination_balance() */ GNUNET_PQ_make_prepare ("auditor_denomination_pending_update", "UPDATE auditor_denomination_pending SET" @@ -867,8 +865,11 @@ postgres_prepare (PGconn *db_conn) ",denom_risk_val=$5" ",denom_risk_frac=$6" ",denom_risk_curr=$7" - " WHERE denom_pub_hash=$8", - 8), + ",payback_loss_val=$8" + ",payback_loss_frac=$9" + ",payback_loss_curr=$10" + " WHERE denom_pub_hash=$11", + 11), /* Used in #postgres_get_denomination_balance() */ GNUNET_PQ_make_prepare ("auditor_denomination_pending_select", "SELECT" @@ -879,6 +880,9 @@ postgres_prepare (PGconn *db_conn) ",denom_risk_val" ",denom_risk_frac" ",denom_risk_curr" + ",payback_loss_val" + ",payback_loss_frac" + ",payback_loss_curr" " FROM auditor_denomination_pending" " WHERE denom_pub_hash=$1", 1), @@ -899,10 +903,14 @@ postgres_prepare (PGconn *db_conn) ",refund_fee_balance_frac" ",refund_fee_balance_curr" ",risk_val" - ",risk_frac" + ",risk_frac" ",risk_curr" - ") VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16);", - 16), + ",loss_val" + ",loss_frac" + ",loss_curr" + ") VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10," + " $11,$12,$13,$14,$15,$16,$17,$18,$19);", + 19), /* Used in #postgres_update_balance_summary() */ GNUNET_PQ_make_prepare ("auditor_balance_summary_update", "UPDATE auditor_balance_summary SET" @@ -921,8 +929,11 @@ postgres_prepare (PGconn *db_conn) ",risk_val=$13" ",risk_frac=$14" ",risk_curr=$15" - " WHERE master_pub=$16;", - 16), + ",loss_val=$16" + ",loss_frac=$17" + ",loss_curr=$18" + " WHERE master_pub=$19;", + 19), /* Used in #postgres_get_balance_summary() */ GNUNET_PQ_make_prepare ("auditor_balance_summary_select", "SELECT" @@ -941,6 +952,9 @@ postgres_prepare (PGconn *db_conn) ",risk_val" ",risk_frac" ",risk_curr" + ",loss_val" + ",loss_frac" + ",loss_curr" " FROM auditor_balance_summary" " WHERE master_pub=$1;", 1), @@ -953,8 +967,11 @@ postgres_prepare (PGconn *db_conn) ",revenue_balance_val" ",revenue_balance_frac" ",revenue_balance_curr" - ") VALUES ($1,$2,$3,$4,$5,$6);", - 6), + ",loss_balance_val" + ",loss_balance_frac" + ",loss_balance_curr" + ") VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9);", + 9), /* Used in #postgres_select_historic_denom_revenue() */ GNUNET_PQ_make_prepare ("auditor_historic_denomination_revenue_select", "SELECT" @@ -963,29 +980,10 @@ postgres_prepare (PGconn *db_conn) ",revenue_balance_val" ",revenue_balance_frac" ",revenue_balance_curr" - " FROM auditor_historic_denomination_revenue" - " WHERE master_pub=$1;", - 1), - /* Used in #postgres_insert_historic_losses() */ - GNUNET_PQ_make_prepare ("auditor_historic_losses_insert", - "INSERT INTO auditor_historic_losses" - "(master_pub" - ",denom_pub_hash" - ",loss_timestamp" - ",loss_balance_val" - ",loss_balance_frac" - ",loss_balance_curr" - ") VALUES ($1,$2,$3,$4,$5,$6);", - 6), - /* Used in #postgres_select_historic_losses() */ - GNUNET_PQ_make_prepare ("auditor_historic_losses_select", - "SELECT" - " denom_pub_hash" - ",loss_timestamp" ",loss_balance_val" ",loss_balance_frac" ",loss_balance_curr" - " FROM auditor_historic_losses" + " FROM auditor_historic_denomination_revenue" " WHERE master_pub=$1;", 1), /* Used in #postgres_insert_historic_reserve_revenue() */ @@ -2640,6 +2638,7 @@ postgres_get_wire_fee_summary (void *cls, * @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 + * @param payback_loss losses from payback (if this denomination was revoked) * @param num_issued how many coins of this denomination did the exchange blind-sign * @return transaction status code */ @@ -2649,6 +2648,7 @@ postgres_insert_denomination_balance (void *cls, const struct GNUNET_HashCode *denom_pub_hash, const struct TALER_Amount *denom_balance, const struct TALER_Amount *denom_risk, + const struct TALER_Amount *payback_loss, uint64_t num_issued) { struct GNUNET_PQ_QueryParam params[] = { @@ -2656,6 +2656,7 @@ postgres_insert_denomination_balance (void *cls, TALER_PQ_query_param_amount (denom_balance), GNUNET_PQ_query_param_uint64 (&num_issued), TALER_PQ_query_param_amount (denom_risk), + TALER_PQ_query_param_amount (payback_loss), GNUNET_PQ_query_param_end }; @@ -2674,6 +2675,7 @@ postgres_insert_denomination_balance (void *cls, * @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 + * @param payback_loss losses from payback (if this denomination was revoked) * @param num_issued how many coins of this denomination did the exchange blind-sign * @return transaction status code */ @@ -2683,12 +2685,14 @@ postgres_update_denomination_balance (void *cls, const struct GNUNET_HashCode *denom_pub_hash, const struct TALER_Amount *denom_balance, const struct TALER_Amount *denom_risk, + const struct TALER_Amount *payback_loss, uint64_t num_issued) { struct GNUNET_PQ_QueryParam params[] = { TALER_PQ_query_param_amount (denom_balance), GNUNET_PQ_query_param_uint64 (&num_issued), TALER_PQ_query_param_amount (denom_risk), + TALER_PQ_query_param_amount (payback_loss), GNUNET_PQ_query_param_auto_from_type (denom_pub_hash), GNUNET_PQ_query_param_end }; @@ -2707,6 +2711,7 @@ postgres_update_denomination_balance (void *cls, * @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 + * @param[out] payback_loss losses from payback (if this denomination was revoked) * @param[out] num_issued how many coins of this denomination did the exchange blind-sign * @return transaction status code */ @@ -2716,6 +2721,7 @@ postgres_get_denomination_balance (void *cls, const struct GNUNET_HashCode *denom_pub_hash, struct TALER_Amount *denom_balance, struct TALER_Amount *denom_risk, + struct TALER_Amount *payback_loss, uint64_t *num_issued) { struct GNUNET_PQ_QueryParam params[] = { @@ -2725,6 +2731,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), + TALER_PQ_result_spec_amount ("payback_loss", payback_loss), GNUNET_PQ_result_spec_uint64 ("num_issued", num_issued), GNUNET_PQ_result_spec_end }; @@ -2748,6 +2755,7 @@ postgres_get_denomination_balance (void *cls, * @param melt_fee_balance total melt fees collected for this DK * @param refund_fee_balance total refund fees collected for this DK * @param risk maximum risk exposure of the exchange + * @param loss materialized @a risk from payback * @return transaction status code */ static enum GNUNET_DB_QueryStatus @@ -2758,7 +2766,8 @@ postgres_insert_balance_summary (void *cls, 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 *risk) + const struct TALER_Amount *risk, + const struct TALER_Amount *loss) { struct GNUNET_PQ_QueryParam params[] = { GNUNET_PQ_query_param_auto_from_type (master_pub), @@ -2767,6 +2776,7 @@ postgres_insert_balance_summary (void *cls, TALER_PQ_query_param_amount (melt_fee_balance), TALER_PQ_query_param_amount (refund_fee_balance), TALER_PQ_query_param_amount (risk), + TALER_PQ_query_param_amount (loss), GNUNET_PQ_query_param_end }; @@ -2800,6 +2810,7 @@ postgres_insert_balance_summary (void *cls, * @param melt_fee_balance total melt fees collected for this DK * @param refund_fee_balance total refund fees collected for this DK * @param risk maximum risk exposure of the exchange + * @param loss materialized @a risk from payback * @return transaction status code */ static enum GNUNET_DB_QueryStatus @@ -2810,7 +2821,8 @@ postgres_update_balance_summary (void *cls, 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 *risk) + const struct TALER_Amount *risk, + const struct TALER_Amount *loss) { struct GNUNET_PQ_QueryParam params[] = { TALER_PQ_query_param_amount (denom_balance), @@ -2818,6 +2830,7 @@ postgres_update_balance_summary (void *cls, TALER_PQ_query_param_amount (melt_fee_balance), TALER_PQ_query_param_amount (refund_fee_balance), TALER_PQ_query_param_amount (risk), + TALER_PQ_query_param_amount (loss), GNUNET_PQ_query_param_auto_from_type (master_pub), GNUNET_PQ_query_param_end }; @@ -2839,6 +2852,7 @@ postgres_update_balance_summary (void *cls, * @param[out] melt_fee_balance total melt fees collected for this DK * @param[out] refund_fee_balance total refund fees collected for this DK * @param[out] risk maximum risk exposure of the exchange + * @param[out] loss losses from payback (on revoked denominations) * @return transaction status code */ static enum GNUNET_DB_QueryStatus @@ -2849,7 +2863,8 @@ postgres_get_balance_summary (void *cls, struct TALER_Amount *deposit_fee_balance, struct TALER_Amount *melt_fee_balance, struct TALER_Amount *refund_fee_balance, - struct TALER_Amount *risk) + struct TALER_Amount *risk, + struct TALER_Amount *loss) { struct GNUNET_PQ_QueryParam params[] = { GNUNET_PQ_query_param_auto_from_type (master_pub), @@ -2861,13 +2876,14 @@ postgres_get_balance_summary (void *cls, TALER_PQ_result_spec_amount ("melt_fee_balance", melt_fee_balance), TALER_PQ_result_spec_amount ("refund_fee_balance", refund_fee_balance), TALER_PQ_result_spec_amount ("risk", risk), + TALER_PQ_result_spec_amount ("loss", loss), GNUNET_PQ_result_spec_end }; return GNUNET_PQ_eval_prepared_singleton_select (session->conn, - "auditor_balance_summary_select", - params, - rs); + "auditor_balance_summary_select", + params, + rs); } @@ -2891,13 +2907,15 @@ 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 *revenue_balance, + const struct TALER_Amount *loss_balance) { struct GNUNET_PQ_QueryParam params[] = { GNUNET_PQ_query_param_auto_from_type (master_pub), GNUNET_PQ_query_param_auto_from_type (denom_pub_hash), TALER_PQ_query_param_absolute_time (&revenue_timestamp), TALER_PQ_query_param_amount (revenue_balance), + TALER_PQ_query_param_amount (loss_balance), GNUNET_PQ_query_param_end }; @@ -2950,10 +2968,12 @@ historic_denom_revenue_cb (void *cls, struct GNUNET_HashCode denom_pub_hash; struct GNUNET_TIME_Absolute revenue_timestamp; struct TALER_Amount revenue_balance; + struct TALER_Amount loss; struct GNUNET_PQ_ResultSpec rs[] = { GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash", &denom_pub_hash), TALER_PQ_result_spec_absolute_time ("revenue_timestamp", &revenue_timestamp), TALER_PQ_result_spec_amount ("revenue_balance", &revenue_balance), + TALER_PQ_result_spec_amount ("loss_balance", &loss), GNUNET_PQ_result_spec_end }; @@ -2970,9 +2990,10 @@ historic_denom_revenue_cb (void *cls, hrc->qs = i + 1; if (GNUNET_OK != hrc->cb (hrc->cb_cls, - &denom_pub_hash, - revenue_timestamp, - &revenue_balance)) + &denom_pub_hash, + revenue_timestamp, + &revenue_balance, + &loss)) break; } } @@ -3018,152 +3039,6 @@ postgres_select_historic_denom_revenue (void *cls, /** - * Insert information about an exchange's historic - * losses (from compromised denomination keys). - * - * Note yet used, need to implement exchange's bankrupcy - * protocol (and tables!) first. - * - * @param cls the @e cls of this struct with the plugin-specific state - * @param session connection to use - * @param master_pub master key of the exchange - * @param denom_pub_hash hash of the denomination key - * @param loss_timestamp when did this profit get realized - * @param loss_balance what was the total loss - * @return transaction status code - */ -static enum GNUNET_DB_QueryStatus -postgres_insert_historic_losses (void *cls, - struct TALER_AUDITORDB_Session *session, - const struct TALER_MasterPublicKeyP *master_pub, - const struct GNUNET_HashCode *denom_pub_hash, - struct GNUNET_TIME_Absolute loss_timestamp, - const struct TALER_Amount *loss_balance) -{ - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_auto_from_type (master_pub), - GNUNET_PQ_query_param_auto_from_type (denom_pub_hash), - TALER_PQ_query_param_absolute_time (&loss_timestamp), - TALER_PQ_query_param_amount (loss_balance), - GNUNET_PQ_query_param_end - }; - - return GNUNET_PQ_eval_prepared_non_select (session->conn, - "auditor_historic_losses_insert", - params); -} - - -/** - * Closure for #losses_cb. - */ -struct LossContext -{ - /** - * Function to call for each result. - */ - TALER_AUDITORDB_HistoricLossesDataCallback cb; - - /** - * Closure for @e cb. - */ - void *cb_cls; - - /** - * Status code to return. - */ - enum GNUNET_DB_QueryStatus qs; -}; - - -/** - * Helper function for #postgres_select_historic_denom_revenue(). - * To be called with the results of a SELECT statement - * that has returned @a num_results results. - * - * @param cls closure of type `struct HistoricRevenueContext *` - * @param result the postgres result - * @param num_result the number of results in @a result - */ -static void -losses_cb (void *cls, - PGresult *result, - unsigned int num_results) -{ - struct LossContext *lctx = cls; - - for (unsigned int i = 0; i < num_results; i++) - { - struct GNUNET_HashCode denom_pub_hash; - struct GNUNET_TIME_Absolute loss_timestamp; - struct TALER_Amount loss_balance; - struct GNUNET_PQ_ResultSpec rs[] = { - GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash", &denom_pub_hash), - TALER_PQ_result_spec_absolute_time ("loss_timestamp", &loss_timestamp), - TALER_PQ_result_spec_amount ("loss_balance", &loss_balance), - GNUNET_PQ_result_spec_end - }; - - if (GNUNET_OK != - GNUNET_PQ_extract_result (result, - rs, - i)) - { - GNUNET_break (0); - lctx->qs = GNUNET_DB_STATUS_HARD_ERROR; - return; - } - lctx->qs = i + 1; - if (GNUNET_OK != - lctx->cb (lctx->cb_cls, - &denom_pub_hash, - loss_timestamp, - &loss_balance)) - break; - } -} - - -/** - * Obtain all of the historic denomination key losses - * of the given @a master_pub. - * - * @param cls the @e cls of this struct with the plugin-specific state - * @param session connection to use - * @param master_pub master key of the exchange - * @param cb function to call with the results - * @param cb_cls closure for @a cb - * @return transaction status code - */ -static enum GNUNET_DB_QueryStatus -postgres_select_historic_losses (void *cls, - struct TALER_AUDITORDB_Session *session, - const struct TALER_MasterPublicKeyP *master_pub, - TALER_AUDITORDB_HistoricLossesDataCallback cb, - void *cb_cls) -{ - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_auto_from_type (master_pub), - GNUNET_PQ_query_param_end - }; - struct LossContext lctx = { - .cb = cb, - .cb_cls = cb_cls - }; - enum GNUNET_DB_QueryStatus qs; - - qs = GNUNET_PQ_eval_prepared_multi_select (session->conn, - "auditor_historic_losses_select", - params, - &losses_cb, - &lctx); - if (qs <= 0) - return qs; - return lctx.qs; -} - - -/** * Insert information about an exchange's historic revenue from reserves. * * @param cls the @e cls of this struct with the plugin-specific state @@ -3191,8 +3066,8 @@ postgres_insert_historic_reserve_revenue (void *cls, }; return GNUNET_PQ_eval_prepared_non_select (session->conn, - "auditor_historic_reserve_summary_insert", - params); + "auditor_historic_reserve_summary_insert", + params); } @@ -3229,8 +3104,8 @@ struct HistoricReserveRevenueContext */ static void historic_reserve_revenue_cb (void *cls, - PGresult *result, - unsigned int num_results) + PGresult *result, + unsigned int num_results) { struct HistoricReserveRevenueContext *hrc = cls; @@ -3294,10 +3169,10 @@ postgres_select_historic_reserve_revenue (void *cls, }; qs = GNUNET_PQ_eval_prepared_multi_select (session->conn, - "auditor_historic_reserve_summary_select", - params, - &historic_reserve_revenue_cb, - &hrc); + "auditor_historic_reserve_summary_select", + params, + &historic_reserve_revenue_cb, + &hrc); if (0 >= qs) return qs; return hrc.qs; @@ -3495,9 +3370,6 @@ libtaler_plugin_auditordb_postgres_init (void *cls) plugin->select_historic_denom_revenue = &postgres_select_historic_denom_revenue; plugin->insert_historic_denom_revenue = &postgres_insert_historic_denom_revenue; - plugin->select_historic_losses = &postgres_select_historic_losses; - plugin->insert_historic_losses = &postgres_insert_historic_losses; - plugin->select_historic_reserve_revenue = &postgres_select_historic_reserve_revenue; plugin->insert_historic_reserve_revenue = &postgres_insert_historic_reserve_revenue; diff --git a/src/auditordb/test_auditordb.c b/src/auditordb/test_auditordb.c index 191043754..80c442a9a 100644 --- a/src/auditordb/test_auditordb.c +++ b/src/auditordb/test_auditordb.c @@ -371,6 +371,8 @@ run (void *cls) struct TALER_Amount refund_fee_balance2; struct TALER_Amount rbalance; struct TALER_Amount rbalance2; + struct TALER_Amount loss; + struct TALER_Amount loss2; uint64_t nissued; GNUNET_assert (GNUNET_OK == @@ -388,6 +390,9 @@ run (void *cls) GNUNET_assert (GNUNET_OK == TALER_string_to_amount (CURRENCY ":13.57986", &rbalance)); + GNUNET_assert (GNUNET_OK == + TALER_string_to_amount (CURRENCY ":1.6", + &loss)); FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != plugin->insert_denomination_balance (plugin->cls, @@ -395,6 +400,7 @@ run (void *cls) &denom_pub_hash, &denom_balance, &rbalance, + &loss, 42)); GNUNET_log (GNUNET_ERROR_TYPE_INFO, @@ -411,6 +417,7 @@ run (void *cls) &denom_pub_hash, &denom_balance, &rbalance, + &loss, 62)); GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Test: get_denomination_balance\n"); @@ -421,6 +428,7 @@ run (void *cls) &denom_pub_hash, &denom_balance2, &rbalance2, + &loss2, &nissued)); FAILIF (0 != GNUNET_memcmp (&denom_balance2, &denom_balance)); @@ -439,7 +447,8 @@ run (void *cls) &melt_fee_balance, &deposit_fee_balance, &denom_balance, - &rbalance)); + &rbalance, + &loss)); GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Test: update_balance_summary\n"); @@ -452,7 +461,8 @@ run (void *cls) &deposit_fee_balance, &melt_fee_balance, &refund_fee_balance, - &rbalance)); + &rbalance, + &loss)); GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Test: get_balance_summary\n"); @@ -462,6 +472,7 @@ run (void *cls) ZR_BLK (&melt_fee_balance2); ZR_BLK (&refund_fee_balance2); ZR_BLK (&rbalance2); + ZR_BLK (&loss2); FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != plugin->get_balance_summary (plugin->cls, @@ -471,7 +482,8 @@ run (void *cls) &deposit_fee_balance2, &melt_fee_balance2, &refund_fee_balance2, - &rbalance2)); + &rbalance2, + &loss2)); FAILIF ( (0 != GNUNET_memcmp (&denom_balance2, &denom_balance) ) || @@ -483,6 +495,8 @@ run (void *cls) &refund_fee_balance)) ); FAILIF (0 != GNUNET_memcmp (&rbalance2, &rbalance)); + FAILIF (0 != GNUNET_memcmp (&loss2, + &loss)); GNUNET_log (GNUNET_ERROR_TYPE_INFO, @@ -494,7 +508,8 @@ run (void *cls) &master_pub, &denom_pub_hash, past, - &rbalance)); + &rbalance, + &loss)); FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != plugin->insert_historic_denom_revenue (plugin->cls, @@ -502,7 +517,8 @@ run (void *cls) &master_pub, &rnd_hash, now, - &rbalance)); + &rbalance, + &loss)); GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Test: select_historic_denom_revenue\n"); @@ -511,7 +527,8 @@ 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 *revenue_balance2, + const struct TALER_Amount *loss2) { static int n = 0; @@ -524,7 +541,8 @@ run (void *cls) && 0 != GNUNET_memcmp (&revenue_timestamp2, &now)) || (0 != GNUNET_memcmp (denom_pub_hash2, &denom_pub_hash) && 0 != GNUNET_memcmp (denom_pub_hash2, &rnd_hash)) - || 0 != GNUNET_memcmp (revenue_balance2, &rbalance)) + || 0 != GNUNET_memcmp (revenue_balance2, &rbalance) + || 0 != GNUNET_memcmp (loss2, &loss)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "select_historic_denom_revenue_result: result does not match\n"); @@ -542,63 +560,6 @@ run (void *cls) NULL)); GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Test: insert_historic_losses\n"); - - FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != - plugin->insert_historic_losses (plugin->cls, - session, - &master_pub, - &denom_pub_hash, - past, - &rbalance)); - - FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != - plugin->insert_historic_losses (plugin->cls, - session, - &master_pub, - &rnd_hash, - past, - &rbalance)); - - - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Test: select_historic_losses\n"); - - int - select_historic_losses_result (void *cls, - const struct GNUNET_HashCode *denom_pub_hash2, - struct GNUNET_TIME_Absolute loss_timestamp2, - const struct TALER_Amount *loss_balance2) - { - static int n = 0; - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "select_historic_losses_result: row %u\n", n); - - if (2 <= n++ - || cls != NULL - || (0 != GNUNET_memcmp (&loss_timestamp2, &past) - && 0 != GNUNET_memcmp (&loss_timestamp2, &now)) - || (0 != GNUNET_memcmp (denom_pub_hash2, &denom_pub_hash) - && 0 != GNUNET_memcmp (denom_pub_hash2, &rnd_hash)) - || 0 != GNUNET_memcmp (loss_balance2, &rbalance)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "select_historic_denom_revenue_result: result does not match\n"); - GNUNET_break (0); - return GNUNET_SYSERR; - } - return GNUNET_OK; - } - - FAILIF (0 >= - plugin->select_historic_losses (plugin->cls, - session, - &master_pub, - select_historic_losses_result, - NULL)); - - GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Test: insert_historic_reserve_revenue\n"); struct TALER_Amount reserve_profits; @@ -744,20 +705,18 @@ drop: { plugin->rollback (plugin->cls, session); - - GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Test: auditor_delete_exchange\n"); - FAILIF (GNUNET_OK != - plugin->start (plugin->cls, - session)); - FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != - plugin->delete_exchange (plugin->cls, - session, - &master_pub)); - FAILIF (0 > - plugin->commit (plugin->cls, - session)); + GNUNET_break (GNUNET_OK == + plugin->start (plugin->cls, + session)); + GNUNET_break (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == + plugin->delete_exchange (plugin->cls, + session, + &master_pub)); + GNUNET_break (0 <= + plugin->commit (plugin->cls, + session)); } GNUNET_break (GNUNET_OK == plugin->drop_tables (plugin->cls, diff --git a/src/include/taler_auditordb_plugin.h b/src/include/taler_auditordb_plugin.h index 887e51e38..dab548e6e 100644 --- a/src/include/taler_auditordb_plugin.h +++ b/src/include/taler_auditordb_plugin.h @@ -68,6 +68,7 @@ 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 loss_balance what was the total loss * @return sets the return value of select_denomination_info(), * #GNUNET_OK to continue, * #GNUNET_NO to stop processing further rows @@ -77,27 +78,8 @@ 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); - - -/** - * Function called with the results of select_historic_losses() - * - * @param cls closure - * @param denom_pub_hash hash of the denomination key - * @param loss_timestamp when did this profit get realized - * @param loss_balance what was the total loss - * - * @return sets the return value of select_denomination_info(), - * #GNUNET_OK to continue, - * #GNUNET_NO to stop processing further rows - * #GNUNET_SYSERR or other values on error. - */ -typedef int -(*TALER_AUDITORDB_HistoricLossesDataCallback)(void *cls, - const struct GNUNET_HashCode *denom_pub_hash, - struct GNUNET_TIME_Absolute loss_timestamp, - const struct TALER_Amount *loss_balance); + const struct TALER_Amount *revenue_balance, + const struct TALER_Amount *loss_balance); /** @@ -1086,6 +1068,7 @@ struct TALER_AUDITORDB_Plugin * @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 + * @param denom_payback value of coins paid back if this denomination key was revoked * @param num_issued how many coins of this denomination did the exchange blind-sign * @return transaction status code */ @@ -1095,6 +1078,7 @@ struct TALER_AUDITORDB_Plugin const struct GNUNET_HashCode *denom_pub_hash, const struct TALER_Amount *denom_balance, const struct TALER_Amount *denom_risk, + const struct TALER_Amount *payback_loss, uint64_t num_issued); @@ -1107,6 +1091,7 @@ struct TALER_AUDITORDB_Plugin * @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 + * @param denom_payback value of coins paid back if this denomination key was revoked * @param num_issued how many coins of this denomination did the exchange blind-sign * @return transaction status code */ @@ -1116,6 +1101,7 @@ struct TALER_AUDITORDB_Plugin const struct GNUNET_HashCode *denom_pub_hash, const struct TALER_Amount *denom_balance, const struct TALER_Amount *denom_risk, + const struct TALER_Amount *payback_loss, uint64_t num_issued); @@ -1127,6 +1113,7 @@ struct TALER_AUDITORDB_Plugin * @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 + * @param[out] denom_payback value of coins paid back if this denomination key was revoked * @param[out] num_issued how many coins of this denomination did the exchange blind-sign * @return transaction status code */ @@ -1136,6 +1123,7 @@ struct TALER_AUDITORDB_Plugin const struct GNUNET_HashCode *denom_pub_hash, struct TALER_Amount *denom_balance, struct TALER_Amount *denom_risk, + struct TALER_Amount *payback_loss, uint64_t *num_issued); @@ -1165,6 +1153,7 @@ struct TALER_AUDITORDB_Plugin * @param melt_fee_balance total melt fees collected for this DK * @param refund_fee_balance total refund fees collected for this DK * @param risk maximum risk exposure of the exchange + * @param payback_loss actual losses from payback (actualized @a risk) * @return transaction status code */ enum GNUNET_DB_QueryStatus @@ -1175,7 +1164,8 @@ struct TALER_AUDITORDB_Plugin 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 *risk); + const struct TALER_Amount *risk, + const struct TALER_Amount *payback_loss); /** @@ -1190,6 +1180,7 @@ struct TALER_AUDITORDB_Plugin * @param melt_fee_balance total melt fees collected for this DK * @param refund_fee_balance total refund fees collected for this DK * @param risk maximum risk exposure of the exchange + * @param payback_loss actual losses from payback (actualized @a risk) * @return transaction status code */ enum GNUNET_DB_QueryStatus @@ -1200,7 +1191,8 @@ struct TALER_AUDITORDB_Plugin 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 *risk); + const struct TALER_Amount *risk, + const struct TALER_Amount *payback_loss); /** @@ -1214,6 +1206,7 @@ struct TALER_AUDITORDB_Plugin * @param[out] melt_fee_balance total melt fees collected for this DK * @param[out] refund_fee_balance total refund fees collected for this DK * @param[out] risk maximum risk exposure of the exchange + * @param[out] payback_loss actual losses from payback (actualized @a risk) * @return transaction status code */ enum GNUNET_DB_QueryStatus @@ -1224,7 +1217,8 @@ struct TALER_AUDITORDB_Plugin struct TALER_Amount *deposit_fee_balance, struct TALER_Amount *melt_fee_balance, struct TALER_Amount *refund_fee_balance, - struct TALER_Amount *risk); + struct TALER_Amount *risk, + struct TALER_Amount *payback_loss); /** @@ -1239,6 +1233,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 payback_loss_balance total losses from paybacks of revoked denominations * @return transaction status code */ enum GNUNET_DB_QueryStatus @@ -1247,7 +1242,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 *revenue_balance, + const struct TALER_Amount *payback_loss_balance); /** @@ -1270,48 +1266,6 @@ struct TALER_AUDITORDB_Plugin /** - * Insert information about an exchange's historic - * losses (from compromised denomination keys). - * - * Note yet used, need to implement exchange's bankrupcy - * protocol (and tables!) first. - * - * @param cls the @e cls of this struct with the plugin-specific state - * @param session connection to use - * @param master_pub master key of the exchange - * @param denom_pub_hash hash of the denomination key - * @param loss_timestamp when did this profit get realized - * @param loss_balance what was the total loss - * @return transaction status code - */ - enum GNUNET_DB_QueryStatus - (*insert_historic_losses)(void *cls, - struct TALER_AUDITORDB_Session *session, - const struct TALER_MasterPublicKeyP *master_pub, - const struct GNUNET_HashCode *denom_pub_hash, - struct GNUNET_TIME_Absolute loss_timestamp, - const struct TALER_Amount *loss_balance); - - /** - * Obtain all of the historic denomination key losses - * of the given @a master_pub. - * - * @param cls the @e cls of this struct with the plugin-specific state - * @param session connection to use - * @param master_pub master key of the exchange - * @param cb function to call with the results - * @param cb_cls closure for @a cb - * @return transaction status code - */ - enum GNUNET_DB_QueryStatus - (*select_historic_losses)(void *cls, - struct TALER_AUDITORDB_Session *session, - const struct TALER_MasterPublicKeyP *master_pub, - TALER_AUDITORDB_HistoricLossesDataCallback cb, - void *cb_cls); - - - /** * Insert information about an exchange's historic revenue from reserves. * * @param cls the @e cls of this struct with the plugin-specific state |