diff --git a/contrib/gana b/contrib/gana index f603a7959..df1d19891 160000 --- a/contrib/gana +++ b/contrib/gana @@ -1 +1 @@ -Subproject commit f603a795963748040e41693daceae343b3a972ed +Subproject commit df1d198918cbdd03c18723d818979c8d09f8f231 diff --git a/src/auditor/taler-helper-auditor-purses.c b/src/auditor/taler-helper-auditor-purses.c index 0136a9ec3..13327ccba 100644 --- a/src/auditor/taler-helper-auditor-purses.c +++ b/src/auditor/taler-helper-auditor-purses.c @@ -308,6 +308,14 @@ struct PurseSummary */ bool had_pi; + /** + * Was the purse deleted? FIXME: Not yet handled (do we need to? purse + * might just appear as expired eventually; but in the meantime, exchange + * may seem to have refunded the coins for no good reason...), also we do + * not yet check the deletion signature. + */ + bool purse_deleted; + }; @@ -407,7 +415,8 @@ setup_purse (struct PurseContext *pc, &ps->total_value, &ps->exchange_balance, &ps->h_contract_terms, - &ps->merge_timestamp); + &ps->merge_timestamp, + &ps->purse_deleted); if (0 >= qs) { GNUNET_free (ps); diff --git a/src/exchange/taler-exchange-httpd_purses_delete.c b/src/exchange/taler-exchange-httpd_purses_delete.c index f4106a664..58cc78250 100644 --- a/src/exchange/taler-exchange-httpd_purses_delete.c +++ b/src/exchange/taler-exchange-httpd_purses_delete.c @@ -24,6 +24,7 @@ #include #include #include +#include "taler_dbevents.h" #include "taler_json_lib.h" #include "taler_mhd_lib.h" #include "taler-exchange-httpd_common_deposit.h" @@ -131,6 +132,23 @@ TEH_handler_purses_delete ( TALER_EC_EXCHANGE_PURSE_DELETE_ALREADY_DECIDED, NULL); } + { + /* Possible minor optimization: integrate notification with + transaction above... */ + struct TALER_PurseEventP rep = { + .header.size = htons (sizeof (rep)), + .header.type = htons (TALER_DBEVENT_EXCHANGE_PURSE_DEPOSITED), + .purse_pub = purse_pub + }; + + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Notifying about purse deletion %s\n", + TALER_B2S (&purse_pub)); + TEH_plugin->event_notify (TEH_plugin->cls, + &rep.header, + NULL, + 0); + } /* success */ return TALER_MHD_reply_static (connection, MHD_HTTP_NO_CONTENT, diff --git a/src/exchange/taler-exchange-httpd_purses_deposit.c b/src/exchange/taler-exchange-httpd_purses_deposit.c index 4bebebf6f..291807aaa 100644 --- a/src/exchange/taler-exchange-httpd_purses_deposit.c +++ b/src/exchange/taler-exchange-httpd_purses_deposit.c @@ -374,6 +374,7 @@ TEH_handler_purses_deposit ( enum GNUNET_DB_QueryStatus qs; struct GNUNET_TIME_Timestamp create_timestamp; struct GNUNET_TIME_Timestamp merge_timestamp; + bool was_deleted; qs = TEH_plugin->select_purse ( TEH_plugin->cls, @@ -383,7 +384,8 @@ TEH_handler_purses_deposit ( &pcc.amount, &pcc.deposit_total, &pcc.h_contract_terms, - &merge_timestamp); + &merge_timestamp, + &was_deleted); switch (qs) { case GNUNET_DB_STATUS_HARD_ERROR: @@ -406,12 +408,16 @@ TEH_handler_purses_deposit ( case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: break; /* handled below */ } - if (GNUNET_TIME_absolute_is_past (pcc.purse_expiration.abs_time)) + if (GNUNET_TIME_absolute_is_past (pcc.purse_expiration.abs_time) || + was_deleted) { - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_GONE, - TALER_EC_EXCHANGE_GENERIC_PURSE_EXPIRED, - NULL); + return TALER_MHD_reply_with_error ( + connection, + MHD_HTTP_GONE, + was_deleted + ? TALER_EC_EXCHANGE_GENERIC_PURSE_DELETED + : TALER_EC_EXCHANGE_GENERIC_PURSE_EXPIRED, + GNUNET_TIME_timestamp2s (pcc.purse_expiration)); } } diff --git a/src/exchange/taler-exchange-httpd_purses_get.c b/src/exchange/taler-exchange-httpd_purses_get.c index 8384086b6..e36b9a101 100644 --- a/src/exchange/taler-exchange-httpd_purses_get.c +++ b/src/exchange/taler-exchange-httpd_purses_get.c @@ -207,6 +207,7 @@ TEH_handler_purses_get (struct TEH_RequestContext *rc, const char *const args[2]) { struct GetContext *gc = rc->rh_ctx; + bool purse_deleted; MHD_RESULT res; if (NULL == gc) @@ -312,7 +313,8 @@ TEH_handler_purses_get (struct TEH_RequestContext *rc, &gc->amount, &gc->deposited, &gc->h_contract, - &gc->merge_timestamp); + &gc->merge_timestamp, + &purse_deleted); switch (qs) { case GNUNET_DB_STATUS_HARD_ERROR: @@ -367,11 +369,14 @@ TEH_handler_purses_get (struct TEH_RequestContext *rc, gc->eh = eh2; } } - if (GNUNET_TIME_absolute_is_past (gc->purse_expiration.abs_time)) + if (GNUNET_TIME_absolute_is_past (gc->purse_expiration.abs_time) || + purse_deleted) { return TALER_MHD_reply_with_error (rc->connection, MHD_HTTP_GONE, - TALER_EC_EXCHANGE_GENERIC_PURSE_EXPIRED, + purse_deleted + ? TALER_EC_EXCHANGE_GENERIC_PURSE_DELETED + : TALER_EC_EXCHANGE_GENERIC_PURSE_EXPIRED, GNUNET_TIME_timestamp2s ( gc->purse_expiration)); } diff --git a/src/exchangedb/pg_select_purse.c b/src/exchangedb/pg_select_purse.c index e2a36c33e..9143e8721 100644 --- a/src/exchangedb/pg_select_purse.c +++ b/src/exchangedb/pg_select_purse.c @@ -35,7 +35,8 @@ TEH_PG_select_purse ( struct TALER_Amount *amount, struct TALER_Amount *deposited, struct TALER_PrivateContractHashP *h_contract_terms, - struct GNUNET_TIME_Timestamp *merge_timestamp) + struct GNUNET_TIME_Timestamp *merge_timestamp, + bool *purse_deleted) { struct PostgresClosure *pg = cls; struct GNUNET_PQ_QueryParam params[] = { @@ -57,6 +58,8 @@ TEH_PG_select_purse ( GNUNET_PQ_result_spec_timestamp ("merge_timestamp", merge_timestamp), NULL), + GNUNET_PQ_result_spec_bool ("purse_deleted", + purse_deleted), GNUNET_PQ_result_spec_end }; @@ -72,8 +75,10 @@ TEH_PG_select_purse ( ",balance_val" ",balance_frac" ",merge_timestamp" + ",purse_sig IS NOT NULL AS purse_deleted" " FROM purse_requests" " LEFT JOIN purse_merges USING (purse_pub)" + " LEFT JOIN purse_deletion USING (purse_pub)" " WHERE purse_pub=$1;"); *merge_timestamp = GNUNET_TIME_UNIT_FOREVER_TS; return GNUNET_PQ_eval_prepared_singleton_select (pg->conn, diff --git a/src/exchangedb/pg_select_purse.h b/src/exchangedb/pg_select_purse.h index f522256df..db63f0c90 100644 --- a/src/exchangedb/pg_select_purse.h +++ b/src/exchangedb/pg_select_purse.h @@ -37,6 +37,7 @@ * @param[out] deposited set to actual amount put into the purse so far * @param[out] h_contract_terms set to hash of the contract for the purse * @param[out] merge_timestamp set to time when the purse was merged, or NEVER if not + * @param[out] purse_deleted set to true if purse was deleted * @return transaction status code */ enum GNUNET_DB_QueryStatus @@ -48,7 +49,8 @@ TEH_PG_select_purse ( struct TALER_Amount *amount, struct TALER_Amount *deposited, struct TALER_PrivateContractHashP *h_contract_terms, - struct GNUNET_TIME_Timestamp *merge_timestamp); + struct GNUNET_TIME_Timestamp *merge_timestamp, + bool *purse_deleted); #endif diff --git a/src/include/taler_exchangedb_plugin.h b/src/include/taler_exchangedb_plugin.h index 5a55b5c93..da28262a8 100644 --- a/src/include/taler_exchangedb_plugin.h +++ b/src/include/taler_exchangedb_plugin.h @@ -5827,6 +5827,7 @@ struct TALER_EXCHANGEDB_Plugin * @param[out] deposited set to actual amount put into the purse so far * @param[out] h_contract_terms set to hash of the contract for the purse * @param[out] merge_timestamp set to time when the purse was merged, or NEVER if not + * @param[out] purse_deleted set to true if purse was deleted * @return transaction status code */ enum GNUNET_DB_QueryStatus @@ -5838,7 +5839,8 @@ struct TALER_EXCHANGEDB_Plugin struct TALER_Amount *amount, struct TALER_Amount *deposited, struct TALER_PrivateContractHashP *h_contract_terms, - struct GNUNET_TIME_Timestamp *merge_timestamp); + struct GNUNET_TIME_Timestamp *merge_timestamp, + bool *purse_deleted); /**