summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2016-11-07 14:39:15 +0100
committerChristian Grothoff <christian@grothoff.org>2016-11-07 14:39:15 +0100
commit1d740824fa8914e21c402abefc5f3d5a8cdfa4ca (patch)
tree74223d7b8931806183f5b5d8b09222c00d8a62c7 /src
parent6d6a9dac39bd6c24a7d527186aaa2a1eec2d8c36 (diff)
parent247b8e33b3ea20407910929c78232ff0d44e8d9a (diff)
downloadexchange-1d740824fa8914e21c402abefc5f3d5a8cdfa4ca.tar.gz
exchange-1d740824fa8914e21c402abefc5f3d5a8cdfa4ca.tar.bz2
exchange-1d740824fa8914e21c402abefc5f3d5a8cdfa4ca.zip
resolving merge issue
Diffstat (limited to 'src')
-rw-r--r--src/auditordb/Makefile.am23
-rw-r--r--src/auditordb/plugin_auditordb_postgres.c1824
-rw-r--r--src/auditordb/test-auditor-db-postgres.conf7
-rw-r--r--src/auditordb/test_auditordb.c798
-rw-r--r--src/bank-lib/test_bank_api.c32
-rw-r--r--src/benchmark/taler-exchange-benchmark.c10
-rw-r--r--src/exchange-lib/Makefile.am2
-rw-r--r--src/exchange-lib/exchange_api_admin.c3
-rw-r--r--src/exchange-lib/exchange_api_common.c5
-rw-r--r--src/exchange-lib/exchange_api_common.h41
-rw-r--r--src/exchange-lib/exchange_api_deposit.c2
-rw-r--r--src/exchange-lib/exchange_api_refresh.c9
-rw-r--r--src/exchange-lib/exchange_api_refresh_link.c7
-rw-r--r--src/exchange-lib/exchange_api_refund.c2
-rw-r--r--src/exchange-lib/exchange_api_reserve.c11
-rw-r--r--src/exchange-lib/exchange_api_track_transaction.c2
-rw-r--r--src/exchange-lib/exchange_api_track_transfer.c3
-rw-r--r--src/exchange-lib/exchange_api_wire.c2
-rw-r--r--src/exchange-lib/test_exchange_api.c41
-rw-r--r--src/exchange/taler-exchange-httpd_admin.c2
-rw-r--r--src/exchange/taler-exchange-httpd_db.c179
-rw-r--r--src/exchange/taler-exchange-httpd_deposit.c88
-rw-r--r--src/exchange/taler-exchange-httpd_parsing.c12
-rw-r--r--src/exchange/taler-exchange-httpd_refresh.c24
-rw-r--r--src/exchange/taler-exchange-httpd_refund.c7
-rw-r--r--src/exchange/taler-exchange-httpd_reserve.c4
-rw-r--r--src/exchange/taler-exchange-httpd_responses.c104
-rw-r--r--src/exchange/taler-exchange-httpd_responses.h36
-rw-r--r--src/exchange/taler-exchange-httpd_test.c7
-rw-r--r--src/exchange/taler-exchange-httpd_tracking.c1
-rw-r--r--src/exchangedb/plugin_exchangedb_postgres.c490
-rw-r--r--src/exchangedb/test_exchangedb.c229
-rw-r--r--src/include/taler_auditordb_plugin.h171
-rw-r--r--src/include/taler_error_codes.h1089
-rw-r--r--src/include/taler_exchange_service.h25
-rw-r--r--src/include/taler_json_lib.h12
-rw-r--r--src/include/taler_util.h2
-rw-r--r--src/json/json.c29
38 files changed, 4986 insertions, 349 deletions
diff --git a/src/auditordb/Makefile.am b/src/auditordb/Makefile.am
index e8ec40272..640f95f25 100644
--- a/src/auditordb/Makefile.am
+++ b/src/auditordb/Makefile.am
@@ -12,7 +12,8 @@ pkgcfg_DATA = \
auditordb-postgres.conf
EXTRA_DIST = \
- auditordb-postgres.conf
+ auditordb-postgres.conf \
+ test-auditor-db-postgres.conf
plugindir = $(libdir)/taler
@@ -49,5 +50,21 @@ libtalerauditordb_la_LDFLAGS = \
-no-undefined
-EXTRA_test_auditordb_postgres_DEPENDENCIES = \
- libtaler_plugin_auditordb_postgres.la
+#EXTRA_test_auditordb_postgres_DEPENDENCIES = \
+# libtaler_plugin_auditordb_postgres.la
+
+
+check_PROGRAMS = \
+ test-auditordb-postgres
+
+AM_TESTS_ENVIRONMENT=export TALER_PREFIX=$${TALER_PREFIX:-@libdir@};export PATH=$${TALER_PREFIX:-@prefix@}/bin:$$PATH;
+TESTS = \
+ test-auditordb-postgres
+
+test_auditordb_postgres_SOURCES = \
+ test_auditordb.c
+test_auditordb_postgres_LDADD = \
+ libtalerauditordb.la \
+ $(top_srcdir)/src/pq/libtalerpq.la \
+ $(top_srcdir)/src/util/libtalerutil.la \
+ -lgnunetutil
diff --git a/src/auditordb/plugin_auditordb_postgres.c b/src/auditordb/plugin_auditordb_postgres.c
index 3205d489c..81c1b4369 100644
--- a/src/auditordb/plugin_auditordb_postgres.c
+++ b/src/auditordb/plugin_auditordb_postgres.c
@@ -17,9 +17,8 @@
/**
* @file plugin_auditordb_postgres.c
* @brief Low-level (statement-level) Postgres database access for the auditor
- * @author Florian Dold
* @author Christian Grothoff
- * @author Sree Harsha Totakura
+ * @author Gabor X Toth
*/
#include "platform.h"
#include "taler_pq_lib.h"
@@ -326,7 +325,7 @@ postgres_create_tables (void *cls)
of; "refund_serial_id" tells us the last entry in "refunds"
for this denom_pub that the auditor is aware of. */
SQLEXEC ("CREATE TABLE IF NOT EXISTS denomination_pending"
- "(denom_pub_hash BYTEA PRIMARY KEY REFERENCES denominations (denom_pub_hash) ON DELETE CASCADE"
+ "(denom_pub_hash BYTEA PRIMARY KEY REFERENCES auditor_denominations (denom_pub_hash) ON DELETE CASCADE"
",denom_balance_val INT8 NOT NULL"
",denom_balance_frac INT4 NOT NULL"
",denom_balance_curr VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL"
@@ -435,8 +434,8 @@ postgres_create_tables (void *cls)
",reserve_profits_curr VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL"
")");
- SQLEXEC_INDEX("CREATE INDEX historic_reserve_summary_by_master_pub_start_date"
- " ON historic_ledger(master_pub,start_date)");
+ SQLEXEC_INDEX("CREATE INDEX historic_reserve_summary_by_master_pub_start_date "
+ "ON historic_reserve_summary(master_pub,start_date)");
/* Table with historic business ledger; basically, when the exchange
@@ -510,13 +509,457 @@ postgres_prepare (PGconn *db_conn)
PQclear (result); result = NULL; \
} while (0);
- /* Used in #postgres_XXX() */
- PREPARE ("test_insert",
- "INSERT INTO test "
- "(test_pub"
- ") VALUES "
- "($1);",
+ /* Used in #postgres_insert_denomination_info() */
+ PREPARE ("auditor_denominations_insert",
+ "INSERT INTO auditor_denominations "
+ "(denom_pub_hash"
+ ",master_pub"
+ ",valid_from"
+ ",expire_withdraw"
+ ",expire_deposit"
+ ",expire_legal"
+ ",coin_val"
+ ",coin_frac"
+ ",coin_curr"
+ ",fee_withdraw_val"
+ ",fee_withdraw_frac"
+ ",fee_withdraw_curr"
+ ",fee_deposit_val"
+ ",fee_deposit_frac"
+ ",fee_deposit_curr"
+ ",fee_refresh_val"
+ ",fee_refresh_frac"
+ ",fee_refresh_curr"
+ ",fee_refund_val"
+ ",fee_refund_frac"
+ ",fee_refund_curr"
+ ") VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20,$21);",
+ 21, NULL);
+
+ /* Used in #postgres_insert_denomination_info() */
+ PREPARE ("auditor_denominations_select",
+ "SELECT"
+ " denom_pub_hash"
+ ",valid_from"
+ ",expire_withdraw"
+ ",expire_deposit"
+ ",expire_legal"
+ ",coin_val"
+ ",coin_frac"
+ ",coin_curr"
+ ",fee_withdraw_val"
+ ",fee_withdraw_frac"
+ ",fee_withdraw_curr"
+ ",fee_deposit_val"
+ ",fee_deposit_frac"
+ ",fee_deposit_curr"
+ ",fee_refresh_val"
+ ",fee_refresh_frac"
+ ",fee_refresh_curr"
+ ",fee_refund_val"
+ ",fee_refund_frac"
+ ",fee_refund_curr"
+ " FROM auditor_denominations"
+ " WHERE master_pub=$1;",
1, NULL);
+
+ /* Used in #postgres_insert_auditor_progress() */
+ PREPARE ("auditor_progress_insert",
+ "INSERT INTO auditor_progress "
+ "(master_pub"
+ ",last_reserve_in_serial_id"
+ ",last_reserve_out_serial_id"
+ ",last_deposit_serial_id"
+ ",last_melt_serial_id"
+ ",last_refund_serial_id"
+ ",last_prewire_serial_id"
+ ") VALUES ($1,$2,$3,$4,$5,$6,$7);",
+ 7, NULL);
+
+ /* Used in #postgres_update_auditor_progress() */
+ PREPARE ("auditor_progress_update",
+ "UPDATE auditor_progress SET "
+ " last_reserve_in_serial_id=$1"
+ ",last_reserve_out_serial_id=$2"
+ ",last_deposit_serial_id=$3"
+ ",last_melt_serial_id=$4"
+ ",last_refund_serial_id=$5"
+ ",last_prewire_serial_id=$6"
+ " WHERE master_pub=$7",
+ 7, NULL);
+
+ /* Used in #postgres_get_auditor_progress() */
+ PREPARE ("auditor_progress_select",
+ "SELECT"
+ " last_reserve_in_serial_id"
+ ",last_reserve_out_serial_id"
+ ",last_deposit_serial_id"
+ ",last_melt_serial_id"
+ ",last_refund_serial_id"
+ ",last_prewire_serial_id"
+ " FROM auditor_progress"
+ " WHERE master_pub=$1;",
+ 1, NULL);
+
+ /* Used in #postgres_insert_reserve_info() */
+ PREPARE ("auditor_reserves_insert",
+ "INSERT INTO auditor_reserves "
+ "(reserve_pub"
+ ",master_pub"
+ ",reserve_balance_val"
+ ",reserve_balance_frac"
+ ",reserve_balance_curr"
+ ",withdraw_fee_balance_val"
+ ",withdraw_fee_balance_frac"
+ ",withdraw_fee_balance_curr"
+ ",expiration_date"
+ ",last_reserve_in_serial_id"
+ ",last_reserve_out_serial_id"
+ ") VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11);",
+ 11, NULL);
+
+ /* Used in #postgres_update_reserve_info() */
+ PREPARE ("auditor_reserves_update",
+ "UPDATE auditor_reserves SET"
+ " reserve_balance_val=$1"
+ ",reserve_balance_frac=$2"
+ ",reserve_balance_curr=$3"
+ ",withdraw_fee_balance_val=$4"
+ ",withdraw_fee_balance_frac=$5"
+ ",withdraw_fee_balance_curr=$6"
+ ",expiration_date=$7"
+ ",last_reserve_in_serial_id=$8"
+ ",last_reserve_out_serial_id=$9"
+ " WHERE reserve_pub=$10 AND master_pub=$11;",
+ 11, NULL);
+
+ /* Used in #postgres_get_reserve_info() */
+ PREPARE ("auditor_reserves_select",
+ "SELECT"
+ " reserve_balance_val"
+ ",reserve_balance_frac"
+ ",reserve_balance_curr"
+ ",withdraw_fee_balance_val"
+ ",withdraw_fee_balance_frac"
+ ",withdraw_fee_balance_curr"
+ ",expiration_date"
+ ",last_reserve_in_serial_id"
+ ",last_reserve_out_serial_id"
+ " FROM auditor_reserves"
+ " WHERE reserve_pub=$1 AND master_pub=$2;",
+ 2, NULL);
+
+ /* Used in #postgres_insert_reserve_summary() */
+ PREPARE ("auditor_reserve_balance_insert",
+ "INSERT INTO auditor_reserve_balance"
+ "(master_pub"
+ ",reserve_balance_val"
+ ",reserve_balance_frac"
+ ",reserve_balance_curr"
+ ",withdraw_fee_balance_val"
+ ",withdraw_fee_balance_frac"
+ ",withdraw_fee_balance_curr"
+ ") VALUES ($1,$2,$3,$4,$5,$6,$7)",
+ 7, NULL);
+
+ /* Used in #postgres_update_reserve_summary() */
+ PREPARE ("auditor_reserve_balance_update",
+ "UPDATE auditor_reserve_balance SET"
+ " reserve_balance_val=$1"
+ ",reserve_balance_frac=$2"
+ ",reserve_balance_curr=$3"
+ ",withdraw_fee_balance_val=$4"
+ ",withdraw_fee_balance_frac=$5"
+ ",withdraw_fee_balance_curr=$6"
+ " WHERE master_pub=$7;",
+ 7, NULL);
+
+ /* Used in #postgres_get_reserve_summary() */
+ PREPARE ("auditor_reserve_balance_select",
+ "SELECT"
+ " reserve_balance_val"
+ ",reserve_balance_frac"
+ ",reserve_balance_curr"
+ ",withdraw_fee_balance_val"
+ ",withdraw_fee_balance_frac"
+ ",withdraw_fee_balance_curr"
+ " FROM auditor_reserve_balance"
+ " WHERE master_pub=$1;",
+ 1, NULL);
+
+ /* Used in #postgres_insert_denomination_balance() */
+ PREPARE ("denomination_pending_insert",
+ "INSERT INTO denomination_pending "
+ "(denom_pub_hash"
+ ",denom_balance_val"
+ ",denom_balance_frac"
+ ",denom_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"
+ ",last_reserve_out_serial_id"
+ ",last_deposit_serial_id"
+ ",last_melt_serial_id"
+ ",last_refund_serial_id"
+ ") VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17);",
+ 17, NULL);
+
+ /* Used in #postgres_update_denomination_balance() */
+ PREPARE ("denomination_pending_update",
+ "UPDATE denomination_pending SET"
+ " denom_balance_val=$1"
+ ",denom_balance_frac=$2"
+ ",denom_balance_curr=$3"
+ ",deposit_fee_balance_val=$4"
+ ",deposit_fee_balance_frac=$5"
+ ",deposit_fee_balance_curr=$6"
+ ",melt_fee_balance_val=$7"
+ ",melt_fee_balance_frac=$8"
+ ",melt_fee_balance_curr=$9"
+ ",refund_fee_balance_val=$10"
+ ",refund_fee_balance_frac=$11"
+ ",refund_fee_balance_curr=$12"
+ ",last_reserve_out_serial_id=$13"
+ ",last_deposit_serial_id=$14"
+ ",last_melt_serial_id=$15"
+ ",last_refund_serial_id=$16"
+ " WHERE denom_pub_hash=$17",
+ 18, NULL);
+
+ /* Used in #postgres_get_denomination_balance() */
+ PREPARE ("denomination_pending_select",
+ "SELECT"
+ " denom_balance_val"
+ ",denom_balance_frac"
+ ",denom_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"
+ ",last_reserve_out_serial_id"
+ ",last_deposit_serial_id"
+ ",last_melt_serial_id"
+ ",last_refund_serial_id"
+ " FROM denomination_pending"
+ " WHERE denom_pub_hash=$1",
+ 1, NULL);
+
+ /* Used in #postgres_insert_denomination_summary() */
+ PREPARE ("total_liabilities_insert",
+ "INSERT INTO total_liabilities "
+ "(master_pub"
+ ",denom_balance_val"
+ ",denom_balance_frac"
+ ",denom_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);",
+ 13, NULL);
+
+ /* Used in #postgres_update_denomination_summary() */
+ PREPARE ("total_liabilities_update",
+ "UPDATE total_liabilities SET"
+ " denom_balance_val=$1"
+ ",denom_balance_frac=$2"
+ ",denom_balance_curr=$3"
+ ",deposit_fee_balance_val=$4"
+ ",deposit_fee_balance_frac=$5"
+ ",deposit_fee_balance_curr=$6"
+ ",melt_fee_balance_val=$7"
+ ",melt_fee_balance_frac=$8"
+ ",melt_fee_balance_curr=$9"
+ ",refund_fee_balance_val=$10"
+ ",refund_fee_balance_frac=$11"
+ ",refund_fee_balance_curr=$12"
+ " WHERE master_pub=$13;",
+ 13, NULL);
+
+ /* Used in #postgres_get_denomination_summary() */
+ PREPARE ("total_liabilities_select",
+ "SELECT"
+ " denom_balance_val"
+ ",denom_balance_frac"
+ ",denom_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 total_liabilities"
+ " WHERE master_pub=$1;",
+ 1, NULL);
+
+ /* Used in #postgres_insert_risk_summary() */
+ PREPARE ("total_risk_insert",
+ "INSERT INTO total_risk"
+ "(master_pub"
+ ",risk_val"
+ ",risk_frac"
+ ",risk_curr"
+ ") VALUES ($1,$2,$3,$4);",
+ 4, NULL);
+
+ /* Used in #postgres_update_risk_summary() */
+ PREPARE ("total_risk_update",
+ "UPDATE total_risk SET "
+ " risk_val=$1"
+ ",risk_frac=$2"
+ ",risk_curr=$3"
+ " WHERE master_pub=$4;",
+ 4, NULL);
+
+ /* Used in #postgres_get_risk_summary() */
+ PREPARE ("total_risk_select",
+ "SELECT"
+ " risk_val"
+ ",risk_frac"
+ ",risk_curr"
+ " FROM total_risk"
+ " WHERE master_pub=$1;",
+ 1, NULL);
+
+
+ /* Used in #postgres_insert_historic_denom_revenue() */
+ PREPARE ("historic_denomination_revenue_insert",
+ "INSERT INTO historic_denomination_revenue"
+ "(master_pub"
+ ",denom_pub_hash"
+ ",revenue_timestamp"
+ ",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);
+
+ /* Used in #postgres_select_historic_denom_revenue() */
+ PREPARE ("historic_denomination_revenue_select",
+ "SELECT"
+ " denom_pub_hash"
+ ",revenue_timestamp"
+ ",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);
+
+ /* Used in #postgres_insert_historic_losses() */
+ PREPARE ("historic_losses_insert",
+ "INSERT INTO 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, NULL);
+
+ /* Used in #postgres_select_historic_losses() */
+ PREPARE ("historic_losses_select",
+ "SELECT"
+ " denom_pub_hash"
+ ",loss_timestamp"
+ ",loss_balance_val"
+ ",loss_balance_frac"
+ ",loss_balance_curr"
+ " FROM historic_losses"
+ " WHERE master_pub=$1;",
+ 1, NULL);
+
+ /* Used in #postgres_insert_historic_reserve_revenue() */
+ PREPARE ("historic_reserve_summary_insert",
+ "INSERT INTO historic_reserve_summary"
+ "(master_pub"
+ ",start_date"
+ ",end_date"
+ ",reserve_profits_val"
+ ",reserve_profits_frac"
+ ",reserve_profits_curr"
+ ") VALUES ($1,$2,$3,$4,$5,$6);",
+ 6, NULL);
+
+ /* Used in #postgres_select_historic_reserve_revenue() */
+ PREPARE ("historic_reserve_summary_select",
+ "SELECT"
+ " start_date"
+ ",end_date"
+ ",reserve_profits_val"
+ ",reserve_profits_frac"
+ ",reserve_profits_curr"
+ " FROM historic_reserve_summary"
+ " WHERE master_pub=$1;",
+ 1, NULL);
+
+ /* Used in #postgres_insert_predicted_result() */
+ PREPARE ("predicted_result_insert",
+ "INSERT INTO predicted_result"
+ "(master_pub"
+ ",balance_val"
+ ",balance_frac"
+ ",balance_curr"
+ ") VALUES ($1,$2,$3,$4);",
+ 4, NULL);
+
+ /* Used in #postgres_update_predicted_result() */
+ PREPARE ("predicted_result_update",
+ "UPDATE predicted_result SET"
+ " balance_val=$1"
+ ",balance_frac=$2"
+ ",balance_curr=$3"
+ " WHERE master_pub=$4;",
+ 4, NULL);
+
+ /* Used in #postgres_get_predicted_balance() */
+ PREPARE ("predicted_result_select",
+ "SELECT"
+ " balance_val"
+ ",balance_frac"
+ ",balance_curr"
+ " FROM predicted_result"
+ " WHERE master_pub=$1;",
+ 1, NULL);
+
return GNUNET_OK;
#undef PREPARE
}
@@ -743,8 +1186,55 @@ postgres_insert_denomination_info (void *cls,
struct TALER_AUDITORDB_Session *session,
const struct TALER_DenominationKeyValidityPS *issue)
{
- GNUNET_break (0); // FIXME: not implemented
- return GNUNET_SYSERR;
+ PGresult *result;
+ int ret;
+
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_auto_from_type (&issue->denom_hash),
+ GNUNET_PQ_query_param_auto_from_type (&issue->master),
+
+ GNUNET_PQ_query_param_auto_from_type (&issue->start),
+ GNUNET_PQ_query_param_auto_from_type (&issue->expire_withdraw),
+ GNUNET_PQ_query_param_auto_from_type (&issue->expire_deposit),
+ GNUNET_PQ_query_param_auto_from_type (&issue->expire_legal),
+
+ TALER_PQ_query_param_amount_nbo (&issue->value),
+ TALER_PQ_query_param_amount_nbo (&issue->fee_withdraw),
+ TALER_PQ_query_param_amount_nbo (&issue->fee_deposit),
+ TALER_PQ_query_param_amount_nbo (&issue->fee_refresh),
+ TALER_PQ_query_param_amount_nbo (&issue->fee_refund),
+
+ GNUNET_PQ_query_param_end
+ };
+
+ /* check fees match coin currency */
+ GNUNET_assert (GNUNET_YES ==
+ TALER_amount_cmp_currency_nbo (&issue->value,
+ &issue->fee_withdraw));
+ GNUNET_assert (GNUNET_YES ==
+ TALER_amount_cmp_currency_nbo (&issue->value,
+ &issue->fee_deposit));
+ GNUNET_assert (GNUNET_YES ==
+ TALER_amount_cmp_currency_nbo (&issue->value,
+ &issue->fee_refresh));
+ GNUNET_assert (GNUNET_YES ==
+ TALER_amount_cmp_currency_nbo (&issue->value,
+ &issue->fee_refund));
+
+ result = GNUNET_PQ_exec_prepared (session->conn,
+ "auditor_denominations_insert",
+ params);
+ if (PGRES_COMMAND_OK != PQresultStatus (result))
+ {
+ ret = GNUNET_SYSERR;
+ BREAK_DB_ERR (result);
+ }
+ else
+ {
+ ret = GNUNET_OK;
+ }
+ PQclear (result);
+ return ret;
}
@@ -762,11 +1252,265 @@ static int
postgres_select_denomination_info (void *cls,
struct TALER_AUDITORDB_Session *session,
const struct TALER_MasterPublicKeyP *master_pub,
- void *cb, /* FIXME: type! */
+ TALER_AUDITORDB_DenominationInfoDataCallback cb,
void *cb_cls)
{
- GNUNET_break (0); // FIXME: not implemented
- return GNUNET_SYSERR;
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_auto_from_type (master_pub),
+
+ GNUNET_PQ_query_param_end
+ };
+ PGresult *result;
+ result = GNUNET_PQ_exec_prepared (session->conn,
+ "auditor_denominations_select",
+ params);
+ if (PGRES_TUPLES_OK !=
+ PQresultStatus (result))
+ {
+ BREAK_DB_ERR (result);
+ PQclear (result);
+ return GNUNET_SYSERR;
+ }
+
+ int ret = GNUNET_OK;
+ int nrows = PQntuples (result);
+ if (0 == nrows)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "postgres_select_denomination_info() returned 0 matching rows\n");
+ PQclear (result);
+ return GNUNET_NO;
+ }
+ for (int i = 0; i < nrows; i++)
+ {
+ struct TALER_DenominationKeyValidityPS issue = { .master = *master_pub };
+
+ struct GNUNET_PQ_ResultSpec rs[] = {
+ GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash", &issue.denom_hash),
+
+ GNUNET_PQ_result_spec_auto_from_type ("valid_from", &issue.start),
+ GNUNET_PQ_result_spec_auto_from_type ("expire_withdraw", &issue.expire_withdraw),
+ GNUNET_PQ_result_spec_auto_from_type ("expire_deposit", &issue.expire_deposit),
+ GNUNET_PQ_result_spec_auto_from_type ("expire_legal", &issue.expire_legal),
+
+ TALER_PQ_result_spec_amount_nbo ("coin", &issue.value),
+ TALER_PQ_result_spec_amount_nbo ("fee_withdraw", &issue.fee_withdraw),
+ TALER_PQ_result_spec_amount_nbo ("fee_deposit", &issue.fee_deposit),
+ TALER_PQ_result_spec_amount_nbo ("fee_refresh", &issue.fee_refresh),
+ TALER_PQ_result_spec_amount_nbo ("fee_refund", &issue.fee_refund),
+
+ GNUNET_PQ_result_spec_end
+ };
+ if (GNUNET_OK !=
+ GNUNET_PQ_extract_result (result, rs, 0))
+ {
+ GNUNET_break (0);
+ PQclear (result);
+ return GNUNET_SYSERR;
+ }
+ ret = cb (cb_cls,
+ &issue);
+ switch (ret)
+ {
+ case GNUNET_OK:
+ break;
+
+ default:
+ i = nrows;
+ }
+ }
+ PQclear (result);
+ return ret;
+}
+
+
+/**
+ * Insert information about the auditor's progress with an exchange's
+ * data.
+ *
+ * @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 last_reserve_in_serial_id serial ID of the last reserve_in transfer the auditor processed
+ * @param last_reserve_out_serial_id serial ID of the last withdraw the auditor processed
+ * @param last_deposit_serial_id serial ID of the last deposit the auditor processed
+ * @param last_melt_serial_id serial ID of the last refresh the auditor processed
+ * @param last_prewire_serial_id serial ID of the last prewire transfer the auditor processed
+ * @return #GNUNET_OK on success; #GNUNET_SYSERR on failure
+ */
+int
+postgres_insert_auditor_progress (void *cls,
+ struct TALER_AUDITORDB_Session *session,
+ const struct TALER_MasterPublicKeyP *master_pub,
+ uint64_t last_reserve_in_serial_id,
+ uint64_t last_reserve_out_serial_id,
+ uint64_t last_deposit_serial_id,
+ uint64_t last_melt_serial_id,
+ uint64_t last_refund_serial_id,
+ uint64_t last_prewire_serial_id)
+{
+ PGresult *result;
+ int ret;
+
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_auto_from_type (master_pub),
+
+ GNUNET_PQ_query_param_uint64 (&last_reserve_in_serial_id),
+ GNUNET_PQ_query_param_uint64 (&last_reserve_out_serial_id),
+ GNUNET_PQ_query_param_uint64 (&last_deposit_serial_id),
+ GNUNET_PQ_query_param_uint64 (&last_melt_serial_id),
+ GNUNET_PQ_query_param_uint64 (&last_refund_serial_id),
+ GNUNET_PQ_query_param_uint64 (&last_prewire_serial_id),
+
+ GNUNET_PQ_query_param_end
+ };
+
+ result = GNUNET_PQ_exec_prepared (session->conn,
+ "auditor_progress_insert",
+ params);
+ if (PGRES_COMMAND_OK != PQresultStatus (result))
+ {
+ ret = GNUNET_SYSERR;
+ BREAK_DB_ERR (result);
+ }
+ else
+ {
+ ret = GNUNET_OK;
+ }
+ PQclear (result);
+ return ret;
+}
+
+
+/**
+ * Update information about the progress of the auditor. There
+ * must be an existing record for the exchange.
+ *
+ * @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 last_reserve_in_serial_id serial ID of the last reserve_in transfer the auditor processed
+ * @param last_reserve_out_serial_id serial ID of the last withdraw the auditor processed
+ * @param last_deposit_serial_id serial ID of the last deposit the auditor processed
+ * @param last_melt_serial_id serial ID of the last refresh the auditor processed
+ * @param last_prewire_serial_id serial ID of the last prewire transfer the auditor processed
+ * @return #GNUNET_OK on success; #GNUNET_SYSERR on failure
+ */
+int
+postgres_update_auditor_progress (void *cls,
+ struct TALER_AUDITORDB_Session *session,
+ const struct TALER_MasterPublicKeyP *master_pub,
+ uint64_t last_reserve_in_serial_id,
+ uint64_t last_reserve_out_serial_id,
+ uint64_t last_deposit_serial_id,
+ uint64_t last_melt_serial_id,
+ uint64_t last_refund_serial_id,
+ uint64_t last_prewire_serial_id)
+{
+ PGresult *result;
+ int ret;
+
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_uint64 (&last_reserve_in_serial_id),
+ GNUNET_PQ_query_param_uint64 (&last_reserve_out_serial_id),
+ GNUNET_PQ_query_param_uint64 (&last_deposit_serial_id),
+ GNUNET_PQ_query_param_uint64 (&last_melt_serial_id),
+ GNUNET_PQ_query_param_uint64 (&last_refund_serial_id),
+ GNUNET_PQ_query_param_uint64 (&last_prewire_serial_id),
+
+ GNUNET_PQ_query_param_auto_from_type (master_pub),
+
+ GNUNET_PQ_query_param_end
+ };
+
+ result = GNUNET_PQ_exec_prepared (session->conn,
+ "auditor_progress_update",
+ params);
+ if (PGRES_COMMAND_OK != PQresultStatus (result))
+ {
+ ret = GNUNET_SYSERR;
+ BREAK_DB_ERR (result);
+ }
+ else
+ {
+ ret = GNUNET_OK;
+ }
+ PQclear (result);
+ return ret;
+}
+
+
+/**
+ * Get information about the progress of the auditor.
+ *
+ * @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[out] last_reserve_in_serial_id serial ID of the last reserve_in transfer the auditor processed
+ * @param[out] last_reserve_out_serial_id serial ID of the last withdraw the auditor processed
+ * @param[out] last_deposit_serial_id serial ID of the last deposit the auditor processed
+ * @param[out] last_melt_serial_id serial ID of the last refresh the auditor processed
+ * @param[out] last_prewire_serial_id serial ID of the last prewire transfer the auditor processed
+ * @return #GNUNET_OK on success; #GNUNET_SYSERR on failure;
+ * #GNUNET_NO if we have no records for the @a master_pub
+ */
+int
+postgres_get_auditor_progress (void *cls,
+ struct TALER_AUDITORDB_Session *session,
+ const struct TALER_MasterPublicKeyP *master_pub,
+ uint64_t *last_reserve_in_serial_id,
+ uint64_t *last_reserve_out_serial_id,
+ uint64_t *last_deposit_serial_id,
+ uint64_t *last_melt_serial_id,
+ uint64_t *last_refund_serial_id,
+ uint64_t *last_prewire_serial_id)
+{
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_auto_from_type (master_pub),
+
+ GNUNET_PQ_query_param_end
+ };
+ PGresult *result;
+ result = GNUNET_PQ_exec_prepared (session->conn,
+ "auditor_progress_select",
+ params);
+ if (PGRES_TUPLES_OK !=
+ PQresultStatus (result))
+ {
+ BREAK_DB_ERR (result);
+ PQclear (result);
+ return GNUNET_SYSERR;
+ }
+
+ int nrows = PQntuples (result);
+ if (0 == nrows)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "postgres_get_auditor_progress() returned 0 matching rows\n");
+ PQclear (result);
+ return GNUNET_NO;
+ }
+ GNUNET_assert (1 == nrows);
+
+ struct GNUNET_PQ_ResultSpec rs[] = {
+ GNUNET_PQ_result_spec_uint64 ("last_reserve_in_serial_id", last_reserve_in_serial_id),
+ GNUNET_PQ_result_spec_uint64 ("last_reserve_out_serial_id", last_reserve_out_serial_id),
+ GNUNET_PQ_result_spec_uint64 ("last_deposit_serial_id", last_deposit_serial_id),
+ GNUNET_PQ_result_spec_uint64 ("last_melt_serial_id", last_melt_serial_id),
+ GNUNET_PQ_result_spec_uint64 ("last_refund_serial_id", last_refund_serial_id),
+ GNUNET_PQ_result_spec_uint64 ("last_prewire_serial_id", last_prewire_serial_id),
+
+ GNUNET_PQ_result_spec_end
+ };
+ if (GNUNET_OK !=
+ GNUNET_PQ_extract_result (result, rs, 0))
+ {
+ GNUNET_break (0);
+ PQclear (result);
+ return GNUNET_SYSERR;
+ }
+ PQclear (result);
+ return GNUNET_OK;
}
@@ -799,8 +1543,42 @@ postgres_insert_reserve_info (void *cls,
uint64_t last_reserve_in_serial_id,
uint64_t last_reserve_out_serial_id)
{
- GNUNET_break (0); // FIXME: not implemented
- return GNUNET_SYSERR;
+ PGresult *result;
+ int ret;
+
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_auto_from_type (reserve_pub),
+ GNUNET_PQ_query_param_auto_from_type (master_pub),
+
+ TALER_PQ_query_param_amount (reserve_balance),
+ TALER_PQ_query_param_amount (withdraw_fee_balance),
+
+ GNUNET_PQ_query_param_auto_from_type (&expiration_date),
+
+ GNUNET_PQ_query_param_uint64 (&last_reserve_in_serial_id),
+ GNUNET_PQ_query_param_uint64 (&last_reserve_out_serial_id),
+
+ GNUNET_PQ_query_param_end
+ };
+
+ GNUNET_assert (GNUNET_YES ==
+ TALER_amount_cmp_currency (reserve_balance,
+ withdraw_fee_balance));
+
+ result = GNUNET_PQ_exec_prepared (session->conn,
+ "auditor_reserves_insert",
+ params);
+ if (PGRES_COMMAND_OK != PQresultStatus (result))
+ {
+ ret = GNUNET_SYSERR;
+ BREAK_DB_ERR (result);
+ }
+ else
+ {
+ ret = GNUNET_OK;
+ }
+ PQclear (result);
+ return ret;
}
@@ -833,8 +1611,42 @@ postgres_update_reserve_info (void *cls,
uint64_t last_reserve_in_serial_id,
uint64_t last_reserve_out_serial_id)
{
- GNUNET_break (0); // FIXME: not implemented
- return GNUNET_SYSERR;
+ PGresult *result;
+ int ret;
+
+ struct GNUNET_PQ_QueryParam params[] = {
+ TALER_PQ_query_param_amount (reserve_balance),
+ TALER_PQ_query_param_amount (withdraw_fee_balance),
+
+ GNUNET_PQ_query_param_auto_from_type (&expiration_date),
+
+ GNUNET_PQ_query_param_uint64 (&last_reserve_in_serial_id),
+ GNUNET_PQ_query_param_uint64 (&last_reserve_out_serial_id),
+
+ GNUNET_PQ_query_param_auto_from_type (reserve_pub),
+ GNUNET_PQ_query_param_auto_from_type (master_pub),
+
+ GNUNET_PQ_query_param_end
+ };
+
+ GNUNET_assert (GNUNET_YES ==
+ TALER_amount_cmp_currency (reserve_balance,
+ withdraw_fee_balance));
+
+ result = GNUNET_PQ_exec_prepared (session->conn,
+ "auditor_reserves_update",
+ params);
+ if (PGRES_COMMAND_OK != PQresultStatus (result))
+ {
+ ret = GNUNET_SYSERR;
+ BREAK_DB_ERR (result);
+ }
+ else
+ {
+ ret = GNUNET_OK;
+ }
+ PQclear (result);
+ return ret;
}
@@ -867,8 +1679,54 @@ postgres_get_reserve_info (void *cls,
uint64_t *last_reserve_in_serial_id,
uint64_t *last_reserve_out_serial_id)
{
- GNUNET_break (0); // FIXME: not implemented
- return GNUNET_SYSERR;
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_auto_from_type (reserve_pub),
+ GNUNET_PQ_query_param_auto_from_type (master_pub),
+
+ GNUNET_PQ_query_param_end
+ };
+ PGresult *result;
+ result = GNUNET_PQ_exec_prepared (session->conn,
+ "auditor_reserves_select",
+ params);
+ if (PGRES_TUPLES_OK !=
+ PQresultStatus (result))
+ {
+ BREAK_DB_ERR (result);
+ PQclear (result);
+ return GNUNET_SYSERR;
+ }
+
+ int nrows = PQntuples (result);
+ if (0 == nrows)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "postgres_get_reserve_info() returned 0 matching rows\n");
+ PQclear (result);
+ return GNUNET_NO;
+ }
+ GNUNET_assert (1 == nrows);
+
+ struct GNUNET_PQ_ResultSpec rs[] = {
+ TALER_PQ_result_spec_amount ("reserve_balance", reserve_balance),
+ TALER_PQ_result_spec_amount ("withdraw_fee_balance", withdraw_fee_balance),
+
+ GNUNET_PQ_result_spec_auto_from_type ("expiration_date", expiration_date),
+
+ GNUNET_PQ_result_spec_uint64 ("last_reserve_in_serial_id", last_reserve_in_serial_id),
+ GNUNET_PQ_result_spec_uint64 ("last_reserve_out_serial_id", last_reserve_out_serial_id),
+
+ GNUNET_PQ_result_spec_end
+ };
+ if (GNUNET_OK !=
+ GNUNET_PQ_extract_result (result, rs, 0))
+ {
+ GNUNET_break (0);
+ PQclear (result);
+ return GNUNET_SYSERR;
+ }
+ PQclear (result);
+ return GNUNET_OK;
}
@@ -891,8 +1749,36 @@ postgres_insert_reserve_summary (void *cls,
const struct TALER_Amount *reserve_balance,
const struct TALER_Amount *withdraw_fee_balance)
{
- GNUNET_break (0); // FIXME: not implemented
- return GNUNET_SYSERR;
+ PGresult *result;
+ int ret;
+
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_auto_from_type (master_pub),
+
+ TALER_PQ_query_param_amount (reserve_balance),
+ TALER_PQ_query_param_amount (withdraw_fee_balance),
+
+ GNUNET_PQ_query_param_end
+ };
+
+ GNUNET_assert (GNUNET_YES ==
+ TALER_amount_cmp_currency (reserve_balance,
+ withdraw_fee_balance));
+
+ result = GNUNET_PQ_exec_prepared (session->conn,
+ "auditor_reserve_balance_insert",
+ params);
+ if (PGRES_COMMAND_OK != PQresultStatus (result))
+ {
+ ret = GNUNET_SYSERR;
+ BREAK_DB_ERR (result);
+ }
+ else
+ {
+ ret = GNUNET_OK;
+ }
+ PQclear (result);
+ return ret;
}
@@ -915,8 +1801,32 @@ postgres_update_reserve_summary (void *cls,
const struct TALER_Amount *reserve_balance,
const struct TALER_Amount *withdraw_fee_balance)
{
- GNUNET_break (0); // FIXME: not implemented
- return GNUNET_SYSERR;
+ PGresult *result;
+ int ret;
+
+ struct GNUNET_PQ_QueryParam params[] = {
+ TALER_PQ_query_param_amount (reserve_balance),
+ TALER_PQ_query_param_amount (withdraw_fee_balance),
+
+ GNUNET_PQ_query_param_auto_from_type (master_pub),
+
+ GNUNET_PQ_query_param_end
+ };
+
+ result = GNUNET_PQ_exec_prepared (session->conn,
+ "auditor_reserve_balance_update",
+ params);
+ if (PGRES_COMMAND_OK != PQresultStatus (result))
+ {
+ ret = GNUNET_SYSERR;
+ BREAK_DB_ERR (result);
+ }
+ else
+ {
+ ret = GNUNET_OK;
+ }
+ PQclear (result);
+ return ret;
}
@@ -939,8 +1849,48 @@ postgres_get_reserve_summary (void *cls,
struct TALER_Amount *reserve_balance,
struct TALER_Amount *withdraw_fee_balance)
{
- GNUNET_break (0); // FIXME: not implemented
- return GNUNET_SYSERR;
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_auto_from_type (master_pub),
+
+ GNUNET_PQ_query_param_end
+ };
+ PGresult *result;
+ result = GNUNET_PQ_exec_prepared (session->conn,
+ "auditor_reserve_balance_select",
+ params);
+ if (PGRES_TUPLES_OK !=
+ PQresultStatus (result))
+ {
+ BREAK_DB_ERR (result);
+ PQclear (result);
+ return GNUNET_SYSERR;
+ }
+
+ int nrows = PQntuples (result);
+ if (0 == nrows)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "postgres_get_reserve_summary() returned 0 matching rows\n");
+ PQclear (result);
+ return GNUNET_NO;
+ }
+ GNUNET_assert (1 == nrows);
+
+ struct GNUNET_PQ_ResultSpec rs[] = {
+ TALER_PQ_result_spec_amount ("reserve_balance", reserve_balance),
+ TALER_PQ_result_spec_amount ("withdraw_fee_balance", withdraw_fee_balance),
+
+ GNUNET_PQ_result_spec_end
+ };
+ if (GNUNET_OK !=
+ GNUNET_PQ_extract_result (result, rs, 0))
+ {
+ GNUNET_break (0);
+ PQclear (result);
+ return GNUNET_SYSERR;
+ }
+ PQclear (result);
+ return GNUNET_OK;
}
@@ -978,8 +1928,51 @@ postgres_insert_denomination_balance (void *cls,
uint64_t last_melt_serial_id,
uint64_t last_refund_serial_id)
{
- GNUNET_break (0); // FIXME: not implemented
- return GNUNET_SYSERR;
+ 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 (deposit_fee_balance),
+ TALER_PQ_query_param_amount (melt_fee_balance),
+ TALER_PQ_query_param_amount (refund_fee_balance),
+
+ GNUNET_PQ_query_param_uint64 (&last_reserve_out_serial_id),
+ GNUNET_PQ_query_param_uint64 (&last_deposit_serial_id),
+ GNUNET_PQ_query_param_uint64 (&last_melt_serial_id),
+ GNUNET_PQ_query_param_uint64 (&last_refund_serial_id),
+
+ GNUNET_PQ_query_param_end
+ };
+
+ GNUNET_assert (GNUNET_YES ==
+ TALER_amount_cmp_currency (denom_balance,
+ deposit_fee_balance));
+
+ GNUNET_assert (GNUNET_YES ==
+ TALER_amount_cmp_currency (denom_balance,
+ melt_fee_balance));
+
+ GNUNET_assert (GNUNET_YES ==
+ TALER_amount_cmp_currency (denom_balance,
+ refund_fee_balance));
+
+ result = GNUNET_PQ_exec_prepared (session->conn,
+ "denomination_pending_insert",
+ params);
+ if (PGRES_COMMAND_OK != PQresultStatus (result))
+ {
+ ret = GNUNET_SYSERR;
+ BREAK_DB_ERR (result);
+ }
+ else
+ {
+ ret = GNUNET_OK;
+ }
+ PQclear (result);
+ return ret;
}
@@ -1017,8 +2010,39 @@ postgres_update_denomination_balance (void *cls,
uint64_t last_melt_serial_id,
uint64_t last_refund_serial_id)
{
- GNUNET_break (0); // FIXME: not implemented
- return GNUNET_SYSERR;
+ PGresult *result;
+ int ret;
+
+ struct GNUNET_PQ_QueryParam params[] = {
+ TALER_PQ_query_param_amount (denom_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_uint64 (&last_reserve_out_serial_id),
+ GNUNET_PQ_query_param_uint64 (&last_deposit_serial_id),
+ GNUNET_PQ_query_param_uint64 (&last_melt_serial_id),
+ GNUNET_PQ_query_param_uint64 (&last_refund_serial_id),
+
+ GNUNET_PQ_query_param_auto_from_type (denom_pub_hash),
+
+ GNUNET_PQ_query_param_end
+ };
+
+ result = GNUNET_PQ_exec_prepared (session->conn,
+ "denomination_pending_update",
+ params);
+ if (PGRES_COMMAND_OK != PQresultStatus (result))
+ {
+ ret = GNUNET_SYSERR;
+ BREAK_DB_ERR (result);
+ }
+ else
+ {
+ ret = GNUNET_OK;
+ }
+ PQclear (result);
+ return ret;
}
@@ -1055,8 +2079,55 @@ postgres_get_denomination_balance (void *cls,
uint64_t *last_melt_serial_id,
uint64_t *last_refund_serial_id)
{
- GNUNET_break (0); // FIXME: not implemented
- return GNUNET_SYSERR;
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_auto_from_type (denom_pub_hash),
+
+ GNUNET_PQ_query_param_end
+ };
+ PGresult *result;
+ result = GNUNET_PQ_exec_prepared (session->conn,
+ "denomination_pending_select",
+ params);
+ if (PGRES_TUPLES_OK !=
+ PQresultStatus (result))
+ {
+ BREAK_DB_ERR (result);
+ PQclear (result);
+ return GNUNET_SYSERR;
+ }
+
+ int nrows = PQntuples (result);
+ if (0 == nrows)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "postgres_get_denomination_balance() returned 0 matching rows\n");
+ PQclear (result);
+ return GNUNET_NO;
+ }
+ GNUNET_assert (1 == nrows);
+
+ struct GNUNET_PQ_ResultSpec rs[] = {
+ TALER_PQ_result_spec_amount ("denom_balance", denom_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_uint64 ("last_reserve_out_serial_id", last_reserve_out_serial_id),
+ GNUNET_PQ_result_spec_uint64 ("last_deposit_serial_id", last_deposit_serial_id),
+ GNUNET_PQ_result_spec_uint64 ("last_melt_serial_id", last_melt_serial_id),
+ GNUNET_PQ_result_spec_uint64 ("last_refund_serial_id", last_refund_serial_id),
+
+ GNUNET_PQ_result_spec_end
+ };
+ if (GNUNET_OK !=
+ GNUNET_PQ_extract_result (result, rs, 0))
+ {
+ GNUNET_break (0);
+ PQclear (result);
+ return GNUNET_SYSERR;
+ }
+ PQclear (result);
+ return GNUNET_OK;
}
@@ -1082,8 +2153,46 @@ postgres_insert_denomination_summary (void *cls,
const struct TALER_Amount *melt_fee_balance,
const struct TALER_Amount *refund_fee_balance)
{
- GNUNET_break (0); // FIXME: not implemented
- return GNUNET_SYSERR;
+ PGresult *result;
+ int ret;
+
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_auto_from_type (master_pub),
+
+ TALER_PQ_query_param_amount (denom_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 (denom_balance,
+ deposit_fee_balance));
+
+ GNUNET_assert (GNUNET_YES ==
+ TALER_amount_cmp_currency (denom_balance,
+ melt_fee_balance));
+
+ GNUNET_assert (GNUNET_YES ==
+ TALER_amount_cmp_currency (denom_balance,
+ refund_fee_balance));
+
+ result = GNUNET_PQ_exec_prepared (session->conn,
+ "total_liabilities_insert",
+ params);
+ if (PGRES_COMMAND_OK != PQresultStatus (result))
+ {
+ ret = GNUNET_SYSERR;
+ BREAK_DB_ERR (result);
+ }
+ else
+ {
+ ret = GNUNET_OK;
+ }
+ PQclear (result);
+ return ret;
}
@@ -1109,8 +2218,34 @@ postgres_update_denomination_summary (void *cls,
const struct TALER_Amount *melt_fee_balance,
const struct TALER_Amount *refund_fee_balance)
{
- GNUNET_break (0); // FIXME: not implemented
- return GNUNET_SYSERR;
+ PGresult *result;
+ int ret;
+
+ struct GNUNET_PQ_QueryParam params[] = {
+ TALER_PQ_query_param_amount (denom_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_auto_from_type (master_pub),
+
+ GNUNET_PQ_query_param_end
+ };
+
+ result = GNUNET_PQ_exec_prepared (session->conn,
+ "total_liabilities_update",
+ params);
+ if (PGRES_COMMAND_OK != PQresultStatus (result))
+ {
+ ret = GNUNET_SYSERR;
+ BREAK_DB_ERR (result);
+ }
+ else
+ {
+ ret = GNUNET_OK;
+ }
+ PQclear (result);
+ return ret;
}
@@ -1136,8 +2271,50 @@ postgres_get_denomination_summary (void *cls,
struct TALER_Amount *melt_fee_balance,
struct TALER_Amount *refund_fee_balance)
{
- GNUNET_break (0); // FIXME: not implemented
- return GNUNET_SYSERR;
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_auto_from_type (master_pub),
+
+ GNUNET_PQ_query_param_end
+ };
+ PGresult *result;
+ result = GNUNET_PQ_exec_prepared (session->conn,
+ "total_liabilities_select",
+ params);
+ if (PGRES_TUPLES_OK !=
+ PQresultStatus (result))
+ {
+ BREAK_DB_ERR (result);
+ PQclear (result);
+ return GNUNET_SYSERR;
+ }
+
+ int nrows = PQntuples (result);
+ if (0 == nrows)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "postgres_get_denomination_summary() returned 0 matching rows\n");
+ PQclear (result);
+ return GNUNET_NO;
+ }
+ GNUNET_assert (1 == nrows);
+
+ struct GNUNET_PQ_ResultSpec rs[] = {
+ TALER_PQ_result_spec_amount ("denom_balance", denom_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
+ };
+ if (GNUNET_OK !=
+ GNUNET_PQ_extract_result (result, rs, 0))
+ {
+ GNUNET_break (0);
+ PQclear (result);
+ return GNUNET_SYSERR;
+ }
+ PQclear (result);
+ return GNUNET_OK;
}
@@ -1157,8 +2334,31 @@ postgres_insert_risk_summary (void *cls,
const struct TALER_MasterPublicKeyP *master_pub,
const struct TALER_Amount *risk)
{
- GNUNET_break (0); // FIXME: not implemented
- return GNUNET_SYSERR;
+ PGresult *result;
+ int ret;
+
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_auto_from_type (master_pub),
+
+ TALER_PQ_query_param_amount (risk),
+
+ GNUNET_PQ_query_param_end
+ };
+
+ result = GNUNET_PQ_exec_prepared (session->conn,
+ "total_risk_insert",
+ params);
+ if (PGRES_COMMAND_OK != PQresultStatus (result))
+ {
+ ret = GNUNET_SYSERR;
+ BREAK_DB_ERR (result);
+ }
+ else
+ {
+ ret = GNUNET_OK;
+ }
+ PQclear (result);
+ return ret;
}
@@ -1178,8 +2378,31 @@ postgres_update_risk_summary (void *cls,
const struct TALER_MasterPublicKeyP *master_pub,
const struct TALER_Amount *risk)
{
- GNUNET_break (0); // FIXME: not implemented
- return GNUNET_SYSERR;
+ PGresult *result;
+ int ret;
+
+ struct GNUNET_PQ_QueryParam params[] = {
+ TALER_PQ_query_param_amount (risk),
+
+ GNUNET_PQ_query_param_auto_from_type (master_pub),
+
+ GNUNET_PQ_query_param_end
+ };
+
+ result = GNUNET_PQ_exec_prepared (session->conn,
+ "total_risk_update",
+ params);
+ if (PGRES_COMMAND_OK != PQresultStatus (result))
+ {
+ ret = GNUNET_SYSERR;
+ BREAK_DB_ERR (result);
+ }
+ else
+ {
+ ret = GNUNET_OK;
+ }
+ PQclear (result);
+ return ret;
}
@@ -1199,8 +2422,47 @@ postgres_get_risk_summary (void *cls,
const struct TALER_MasterPublicKeyP *master_pub,
struct TALER_Amount *risk)
{
- GNUNET_break (0); // FIXME: not implemented
- return GNUNET_SYSERR;
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_auto_from_type (master_pub),
+
+ GNUNET_PQ_query_param_end
+ };
+ PGresult *result;
+ result = GNUNET_PQ_exec_prepared (session->conn,
+ "total_risk_select",
+ params);
+ if (PGRES_TUPLES_OK !=
+ PQresultStatus (result))
+ {
+ BREAK_DB_ERR (result);
+ PQclear (result);
+ return GNUNET_SYSERR;
+ }
+
+ int nrows = PQntuples (result);
+ if (0 == nrows)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "postgres_get_risk_summary() returned 0 matching rows\n");
+ PQclear (result);
+ return GNUNET_NO;
+ }
+ GNUNET_assert (1 == nrows);
+
+ struct GNUNET_PQ_ResultSpec rs[] = {
+ TALER_PQ_result_spec_amount ("risk", risk),
+
+ GNUNET_PQ_result_spec_end
+ };
+ if (GNUNET_OK !=
+ GNUNET_PQ_extract_result (result, rs, 0))
+ {
+ GNUNET_break (0);
+ PQclear (result);
+ return GNUNET_SYSERR;
+ }
+ PQclear (result);
+ return GNUNET_OK;
}
@@ -1232,8 +2494,49 @@ postgres_insert_historic_denom_revenue (void *cls,
const struct TALER_Amount *melt_fee_balance,
const struct TALER_Amount *refund_fee_balance)
{
- GNUNET_break (0); // FIXME: not implemented
- return GNUNET_SYSERR;
+ PGresult *result;
+ int ret;
+
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_auto_from_type (master_pub),
+ 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);
+ if (PGRES_COMMAND_OK != PQresultStatus (result))
+ {
+ ret = GNUNET_SYSERR;
+ BREAK_DB_ERR (result);
+ }
+ else
+ {
+ ret = GNUNET_OK;
+ }
+ PQclear (result);
+ return ret;
}
@@ -1252,11 +2555,82 @@ static int
postgres_select_historic_denom_revenue (void *cls,
struct TALER_AUDITORDB_Session *session,
const struct TALER_MasterPublicKeyP *master_pub,
- void *cb, /* FIXME: fix type */
+ TALER_AUDITORDB_HistoricDenominationRevenueDataCallback cb,
void *cb_cls)
{
- GNUNET_break (0); // FIXME: not implemented
- return GNUNET_SYSERR;
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_auto_from_type (master_pub),
+
+ GNUNET_PQ_query_param_end
+ };
+ PGresult *result;
+ result = GNUNET_PQ_exec_prepared (session->conn,
+ "historic_denomination_revenue_select",
+ params);
+ if (PGRES_TUPLES_OK !=
+ PQresultStatus (result))
+ {
+ BREAK_DB_ERR (result);
+ PQclear (result);
+ return GNUNET_SYSERR;
+ }
+
+ int ret = GNUNET_OK;
+ int nrows = PQntuples (result);
+ if (0 == nrows)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "postgres_select_historic_denom_revenue() returned 0 matching rows\n");
+ PQclear (result);
+ return GNUNET_NO;
+ }
+ for (int i = 0; i < nrows; i++)
+ {
+ 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
+ };
+ if (GNUNET_OK !=
+ GNUNET_PQ_extract_result (result, rs, 0))
+ {
+ GNUNET_break (0);
+ PQclear (result);
+ return GNUNET_SYSERR;
+ }
+
+ ret = cb (cb_cls,
+ &denom_pub_hash,
+ revenue_timestamp,
+ &revenue_balance,
+ &deposit_fee_balance,
+ &melt_fee_balance,
+ &refund_fee_balance);
+ switch (ret)
+ {
+ case GNUNET_OK:
+ break;
+
+ default:
+ i = nrows;
+ }
+ }
+ PQclear (result);
+ return ret;
}
@@ -1283,8 +2657,34 @@ postgres_insert_historic_losses (void *cls,
struct GNUNET_TIME_Absolute loss_timestamp,
const struct TALER_Amount *loss_balance)
{
- GNUNET_break (0); // FIXME: not implemented
- return GNUNET_SYSERR;
+ PGresult *result;
+ int ret;
+
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_auto_from_type (master_pub),
+ GNUNET_PQ_query_param_auto_from_type (denom_pub_hash),
+
+ GNUNET_PQ_query_param_auto_from_type (&loss_timestamp),
+
+ TALER_PQ_query_param_amount (loss_balance),
+
+ GNUNET_PQ_query_param_end
+ };
+
+ result = GNUNET_PQ_exec_prepared (session->conn,
+ "historic_losses_insert",
+ params);
+ if (PGRES_COMMAND_OK != PQresultStatus (result))
+ {
+ ret = GNUNET_SYSERR;
+ BREAK_DB_ERR (result);
+ }
+ else
+ {
+ ret = GNUNET_OK;
+ }
+ PQclear (result);
+ return ret;
}
@@ -1303,11 +2703,72 @@ static int
postgres_select_historic_losses (void *cls,
struct TALER_AUDITORDB_Session *session,
const struct TALER_MasterPublicKeyP *master_pub,
- void *cb, /* FIXME: fix type */
+ TALER_AUDITORDB_HistoricLossesDataCallback cb,
void *cb_cls)
{
- GNUNET_break (0); // FIXME: not implemented
- return GNUNET_SYSERR;
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_auto_from_type (master_pub),
+
+ GNUNET_PQ_query_param_end
+ };
+ PGresult *result;
+ result = GNUNET_PQ_exec_prepared (session->conn,
+ "historic_losses_select",
+ params);
+ if (PGRES_TUPLES_OK !=
+ PQresultStatus (result))
+ {
+ BREAK_DB_ERR (result);
+ PQclear (result);
+ return GNUNET_SYSERR;
+ }
+
+ int ret = GNUNET_OK;
+ int nrows = PQntuples (result);
+ if (0 == nrows)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "postgres_select_historic_losses() returned 0 matching rows\n");
+ PQclear (result);
+ return GNUNET_NO;
+ }
+ for (int i = 0; i < nrows; 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),
+
+ GNUNET_PQ_result_spec_auto_from_type ("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, 0))
+ {
+ GNUNET_break (0);
+ PQclear (result);
+ return GNUNET_SYSERR;
+ }
+ ret = cb (cb_cls,
+ &denom_pub_hash,
+ loss_timestamp,
+ &loss_balance);
+ switch (ret)
+ {
+ case GNUNET_OK:
+ break;
+
+ default:
+ i = nrows;
+ }
+ }
+ PQclear (result);
+ return ret;
}
@@ -1330,8 +2791,34 @@ postgres_insert_historic_reserve_revenue (void *cls,
struct GNUNET_TIME_Absolute end_time,
const struct TALER_Amount *reserve_profits)
{
- GNUNET_break (0); // FIXME: not implemented
- return GNUNET_SYSERR;
+ PGresult *result;
+ int ret;
+
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_auto_from_type (master_pub),
+
+ GNUNET_PQ_query_param_auto_from_type (&start_time),
+ GNUNET_PQ_query_param_auto_from_type (&end_time),
+
+ TALER_PQ_query_param_amount (reserve_profits),
+
+ GNUNET_PQ_query_param_end
+ };
+
+ result = GNUNET_PQ_exec_prepared (session->conn,
+ "historic_reserve_summary_insert",
+ params);
+ if (PGRES_COMMAND_OK != PQresultStatus (result))
+ {
+ ret = GNUNET_SYSERR;
+ BREAK_DB_ERR (result);
+ }
+ else
+ {
+ ret = GNUNET_OK;
+ }
+ PQclear (result);
+ return ret;
}
@@ -1349,11 +2836,71 @@ static int
postgres_select_historic_reserve_revenue (void *cls,
struct TALER_AUDITORDB_Session *session,
const struct TALER_MasterPublicKeyP *master_pub,
- void *cb, /* FIXME: type */
+ TALER_AUDITORDB_HistoricReserveRevenueDataCallback cb,
void *cb_cls)
{
- GNUNET_break (0); // FIXME: not implemented
- return GNUNET_SYSERR;
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_auto_from_type (master_pub),
+
+ GNUNET_PQ_query_param_end
+ };
+ PGresult *result;
+ result = GNUNET_PQ_exec_prepared (session->conn,
+ "historic_reserve_summary_select",
+ params);
+ if (PGRES_TUPLES_OK !=
+ PQresultStatus (result))
+ {
+ BREAK_DB_ERR (result);
+ PQclear (result);
+ return GNUNET_SYSERR;
+ }
+
+ int ret = GNUNET_OK;
+ int nrows = PQntuples (result);
+ if (0 == nrows)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "postgres_select_historic_reserve_revenue() returned 0 matching rows\n");
+ PQclear (result);
+ return GNUNET_NO;
+ }
+ for (int i = 0; i < nrows; i++)
+ {
+ struct GNUNET_TIME_Absolute start_date;
+ struct GNUNET_TIME_Absolute end_date;
+ struct TALER_Amount reserve_profits;
+
+ struct GNUNET_PQ_ResultSpec rs[] = {
+ GNUNET_PQ_result_spec_auto_from_type ("start_date", &start_date),
+ GNUNET_PQ_result_spec_auto_from_type ("end_date", &end_date),
+
+ TALER_PQ_result_spec_amount ("reserve_profits", &reserve_profits),
+
+ GNUNET_PQ_result_spec_end
+ };
+ if (GNUNET_OK !=
+ GNUNET_PQ_extract_result (result, rs, 0))
+ {
+ GNUNET_break (0);
+ PQclear (result);
+ return GNUNET_SYSERR;
+ }
+ ret = cb (cb_cls,
+ start_date,
+ end_date,
+ &reserve_profits);
+ switch (ret)
+ {
+ case GNUNET_OK:
+ break;
+
+ default:
+ i = nrows;
+ }
+ }
+ PQclear (result);
+ return ret;
}
@@ -1373,8 +2920,30 @@ postgres_insert_predicted_result (void *cls,
const struct TALER_MasterPublicKeyP *master_pub,
const struct TALER_Amount *balance)
{
- GNUNET_break (0); // FIXME: not implemented
- return GNUNET_SYSERR;
+ PGresult *result;
+ int ret;
+
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_auto_from_type (master_pub),
+ TALER_PQ_query_param_amount (balance),
+
+ GNUNET_PQ_query_param_end
+ };
+
+ result = GNUNET_PQ_exec_prepared (session->conn,
+ "predicted_result_insert",
+ params);
+ if (PGRES_COMMAND_OK != PQresultStatus (result))
+ {
+ ret = GNUNET_SYSERR;
+ BREAK_DB_ERR (result);
+ }
+ else
+ {
+ ret = GNUNET_OK;
+ }
+ PQclear (result);
+ return ret;
}
@@ -1394,8 +2963,30 @@ postgres_update_predicted_result (void *cls,
const struct TALER_MasterPublicKeyP *master_pub,
const struct TALER_Amount *balance)
{
- GNUNET_break (0); // FIXME: not implemented
- return GNUNET_SYSERR;
+ PGresult *result;
+ int ret;
+
+ struct GNUNET_PQ_QueryParam params[] = {
+ TALER_PQ_query_param_amount (balance),
+ GNUNET_PQ_query_param_auto_from_type (master_pub),
+
+ GNUNET_PQ_query_param_end
+ };
+
+ result = GNUNET_PQ_exec_prepared (session->conn,
+ "predicted_result_update",
+ params);
+ if (PGRES_COMMAND_OK != PQresultStatus (result))
+ {
+ ret = GNUNET_SYSERR;
+ BREAK_DB_ERR (result);
+ }
+ else
+ {
+ ret = GNUNET_OK;
+ }
+ PQclear (result);
+ return ret;
}
@@ -1415,8 +3006,47 @@ postgres_get_predicted_balance (void *cls,
const struct TALER_MasterPublicKeyP *master_pub,
struct TALER_Amount *balance)
{
- GNUNET_break (0); // FIXME: not implemented
- return GNUNET_SYSERR;
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_auto_from_type (master_pub),
+
+ GNUNET_PQ_query_param_end
+ };
+ PGresult *result;
+ result = GNUNET_PQ_exec_prepared (session->conn,
+ "predicted_result_select",
+ params);
+ if (PGRES_TUPLES_OK !=
+ PQresultStatus (result))
+ {
+ BREAK_DB_ERR (result);
+ PQclear (result);
+ return GNUNET_SYSERR;
+ }
+
+ int nrows = PQntuples (result);
+ if (0 == nrows)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "postgres_get_predicted_balance() returned 0 matching rows\n");
+ PQclear (result);
+ return GNUNET_NO;
+ }
+ GNUNET_assert (1 == nrows);
+
+ struct GNUNET_PQ_ResultSpec rs[] = {
+ TALER_PQ_result_spec_amount ("balance", balance),
+
+ GNUNET_PQ_result_spec_end
+ };
+ if (GNUNET_OK !=
+ GNUNET_PQ_extract_result (result, rs, 0))
+ {
+ GNUNET_break (0);
+ PQclear (result);
+ return GNUNET_SYSERR;
+ }
+ PQclear (result);
+ return GNUNET_OK;
}
@@ -1472,32 +3102,46 @@ libtaler_plugin_auditordb_postgres_init (void *cls)
plugin->commit = &postgres_commit;
plugin->rollback = &postgres_rollback;
plugin->gc = &postgres_gc;
- plugin->get_predicted_balance = &postgres_get_predicted_balance;
- plugin->update_predicted_result = &postgres_update_predicted_result;
- plugin->insert_predicted_result = &postgres_insert_predicted_result;
- plugin->select_historic_reserve_revenue = &postgres_select_historic_reserve_revenue;
- plugin->insert_historic_reserve_revenue = &postgres_insert_historic_reserve_revenue;
- plugin->select_historic_losses = &postgres_select_historic_losses;
- plugin->insert_historic_losses = &postgres_insert_historic_losses;
- plugin->select_historic_denom_revenue = &postgres_select_historic_denom_revenue;
- plugin->insert_historic_denom_revenue = &postgres_insert_historic_denom_revenue;
- plugin->get_risk_summary = &postgres_get_risk_summary;
- plugin->update_risk_summary = &postgres_update_risk_summary;
- plugin->insert_risk_summary = &postgres_insert_risk_summary;
- plugin->get_denomination_summary = &postgres_get_denomination_summary;
- plugin->update_denomination_summary = &postgres_update_denomination_summary;
- plugin->insert_denomination_summary = &postgres_insert_denomination_summary;
- plugin->get_denomination_balance = &postgres_get_denomination_balance;
- plugin->update_denomination_balance = &postgres_update_denomination_balance;
- plugin->insert_denomination_balance = &postgres_insert_denomination_balance;
- plugin->get_reserve_summary = &postgres_get_reserve_summary;
- plugin->update_reserve_summary = &postgres_update_reserve_summary;
- plugin->insert_reserve_summary = &postgres_insert_reserve_summary;
+
+ plugin->select_denomination_info = &postgres_select_denomination_info;
+ plugin->insert_denomination_info = &postgres_insert_denomination_info;
+
+ plugin->get_auditor_progress = &postgres_get_auditor_progress;
+ plugin->update_auditor_progress = &postgres_update_auditor_progress;
+ plugin->insert_auditor_progress = &postgres_insert_auditor_progress;
+
plugin->get_reserve_info = &postgres_get_reserve_info;
plugin->update_reserve_info = &postgres_update_reserve_info;
plugin->insert_reserve_info = &postgres_insert_reserve_info;
- plugin->select_denomination_info = &postgres_select_denomination_info;
- plugin->insert_denomination_info = &postgres_insert_denomination_info;
+
+ plugin->get_reserve_summary = &postgres_get_reserve_summary;
+ plugin->update_reserve_summary = &postgres_update_reserve_summary;
+ plugin->insert_reserve_summary = &postgres_insert_reserve_summary;
+
+ plugin->get_denomination_balance = &postgres_get_denomination_balance;
+ plugin->update_denomination_balance = &postgres_update_denomination_balance;
+ plugin->insert_denomination_balance = &postgres_insert_denomination_balance;
+
+ plugin->get_denomination_summary = &postgres_get_denomination_summary;
+ plugin->update_denomination_summary = &postgres_update_denomination_summary;
+ plugin->insert_denomination_summary = &postgres_insert_denomination_summary;
+
+ plugin->get_risk_summary = &postgres_get_risk_summary;
+ plugin->update_risk_summary = &postgres_update_risk_summary;
+ plugin->insert_risk_summary = &postgres_insert_risk_summary;
+
+ 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;
+
+ plugin->get_predicted_balance = &postgres_get_predicted_balance;
+ plugin->update_predicted_result = &postgres_update_predicted_result;
+ plugin->insert_predicted_result = &postgres_insert_predicted_result;
return plugin;
}
diff --git a/src/auditordb/test-auditor-db-postgres.conf b/src/auditordb/test-auditor-db-postgres.conf
new file mode 100644
index 000000000..5c1e7fbc1
--- /dev/null
+++ b/src/auditordb/test-auditor-db-postgres.conf
@@ -0,0 +1,7 @@
+[auditor]
+# Which database backend do we use for the auditor?
+DB = postgres
+
+[auditordb-postgres]
+# Argument for Postgres for how to connect to the database.
+DB_CONN_STR = "postgres:///talercheck"
diff --git a/src/auditordb/test_auditordb.c b/src/auditordb/test_auditordb.c
new file mode 100644
index 000000000..93c279384
--- /dev/null
+++ b/src/auditordb/test_auditordb.c
@@ -0,0 +1,798 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2016 GNUnet e.V. and INRIA
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+*/
+/**
+ * @file auditordb/test_auditordb.c
+ * @brief test cases for DB interaction functions
+ * @author Gabor X Toth
+ */
+#include "platform.h"
+#include "taler_auditordb_lib.h"
+#include "taler_auditordb_plugin.h"
+
+
+/**
+ * Global result from the testcase.
+ */
+static int result = -1;
+
+/**
+ * Report line of error if @a cond is true, and jump to label "drop".
+ */
+#define FAILIF(cond) \
+ do { \
+ if (!(cond)){ break;} \
+ GNUNET_break (0); \
+ goto drop; \
+ } while (0)
+
+
+/**
+ * Initializes @a ptr with random data.
+ */
+#define RND_BLK(ptr) \
+ GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, ptr, sizeof (*ptr))
+
+/**
+ * Initializes @a ptr with zeros.
+ */
+#define ZR_BLK(ptr) \
+ memset (ptr, 0, sizeof (*ptr))
+
+
+/**
+ * Currency we use.
+ */
+#define CURRENCY "EUR"
+
+/**
+ * Database plugin under test.
+ */
+static struct TALER_AUDITORDB_Plugin *plugin;
+
+
+/**
+ * Main function that will be run by the scheduler.
+ *
+ * @param cls closure with config
+ */
+static void
+run (void *cls)
+{
+ struct GNUNET_CONFIGURATION_Handle *cfg = cls;
+ struct TALER_AUDITORDB_Session *session;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "loading database plugin\n");
+
+ if (NULL ==
+ (plugin = TALER_AUDITORDB_plugin_load (cfg)))
+ {
+ result = 77;
+ return;
+ }
+
+ (void) plugin->drop_tables (plugin->cls);
+ if (GNUNET_OK !=
+ plugin->create_tables (plugin->cls))
+ {
+ result = 77;
+ goto drop;
+ }
+ if (NULL ==
+ (session = plugin->get_session (plugin->cls)))
+ {
+ result = 77;
+ goto drop;
+ }
+
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "initializing\n");
+
+ struct TALER_Amount value, fee_withdraw, fee_deposit, fee_refresh, fee_refund;
+
+ GNUNET_assert (GNUNET_OK ==
+ TALER_string_to_amount (CURRENCY ":1.000010",
+ &value));
+ GNUNET_assert (GNUNET_OK ==
+ TALER_string_to_amount (CURRENCY ":0.000011",
+ &fee_withdraw));
+ GNUNET_assert (GNUNET_OK ==
+ TALER_string_to_amount (CURRENCY ":0.000012",
+ &fee_deposit));
+ GNUNET_assert (GNUNET_OK ==
+ TALER_string_to_amount (CURRENCY ":0.000013",
+ &fee_refresh));
+ GNUNET_assert (GNUNET_OK ==
+ TALER_string_to_amount (CURRENCY ":0.000014",
+ &fee_refund));
+
+ struct TALER_MasterPublicKeyP master_pub;
+ struct TALER_ReservePublicKeyP reserve_pub;
+ struct GNUNET_HashCode rnd_hash;
+ RND_BLK (&master_pub);
+ RND_BLK (&reserve_pub);
+ RND_BLK (&rnd_hash);
+
+ struct TALER_DenominationPrivateKey denom_priv;
+ struct TALER_DenominationPublicKey denom_pub;
+ struct GNUNET_HashCode denom_pub_hash;
+ denom_priv.rsa_private_key = GNUNET_CRYPTO_rsa_private_key_create (1024);
+ denom_pub.rsa_public_key = GNUNET_CRYPTO_rsa_private_key_get_public (denom_priv.rsa_private_key);
+ GNUNET_CRYPTO_rsa_public_key_hash (denom_pub.rsa_public_key, &denom_pub_hash);
+
+ struct GNUNET_TIME_Absolute now, past, future, date;
+ now = GNUNET_TIME_absolute_get ();
+ past = GNUNET_TIME_absolute_subtract (now,
+ GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS,
+ 4));
+ future = GNUNET_TIME_absolute_add (now,
+ GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS,
+ 4));
+
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Test: insert_denomination_info\n");
+
+ struct TALER_DenominationKeyValidityPS issue = { 0 };
+ issue.master = master_pub;
+ issue.denom_hash = denom_pub_hash;
+
+ issue.start = GNUNET_TIME_absolute_hton (now);
+ issue.expire_withdraw = GNUNET_TIME_absolute_hton
+ (GNUNET_TIME_absolute_add (now,
+ GNUNET_TIME_UNIT_HOURS));
+ issue.expire_deposit = GNUNET_TIME_absolute_hton
+ (GNUNET_TIME_absolute_add
+ (now,
+ GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 2)));
+ issue.expire_legal = GNUNET_TIME_absolute_hton
+ (GNUNET_TIME_absolute_add
+ (now,
+ GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 3)));
+ TALER_amount_hton (&issue.value, &value);
+ TALER_amount_hton (&issue.fee_withdraw, &fee_withdraw);
+ TALER_amount_hton (&issue.fee_deposit, &fee_deposit);
+ TALER_amount_hton (&issue.fee_refresh, &fee_refresh);
+ TALER_amount_hton (&issue.fee_refund, &fee_refund);
+
+ FAILIF (GNUNET_OK !=
+ plugin->insert_denomination_info (plugin->cls,
+ session,
+ &issue));
+
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Test: select_denomination_info\n");
+
+ int
+ select_denomination_info_result (void *cls,
+ const struct TALER_DenominationKeyValidityPS *issue2)
+ {
+ const struct TALER_DenominationKeyValidityPS *issue1 = cls;
+
+ if (0 != memcmp (issue1, issue2, sizeof (*issue2)))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "select_denomination_info_result: issue does not match\n");
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ return GNUNET_OK;
+ }
+
+ FAILIF (GNUNET_OK !=
+ plugin->select_denomination_info (plugin->cls,
+ session,
+ &master_pub,
+ select_denomination_info_result,
+ &issue));
+
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Test: insert_auditor_progress\n");
+
+ uint64_t
+ last_reserve_in_serial_id = 1234,
+ last_reserve_out_serial_id = 5678,
+ last_deposit_serial_id = 123,
+ last_melt_serial_id = 456,
+ last_refund_serial_id = 789,
+ last_prewire_serial_id = 555,
+
+ last_reserve_in_serial_id2 = 0,
+ last_reserve_out_serial_id2 = 0,
+ last_deposit_serial_id2 = 0,
+ last_melt_serial_id2 = 0,
+ last_refund_serial_id2 = 0,
+ last_prewire_serial_id2 = 0;
+
+ FAILIF (GNUNET_OK !=
+ plugin->insert_auditor_progress (plugin->cls,
+ session,
+ &master_pub,
+ last_reserve_in_serial_id,
+ last_reserve_out_serial_id,
+ last_deposit_serial_id,
+ last_melt_serial_id,
+ last_refund_serial_id,
+ last_prewire_serial_id));
+
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Test: update_auditor_progress\n");
+
+ last_reserve_in_serial_id++;
+ last_reserve_out_serial_id++;
+ last_deposit_serial_id2++;
+ last_melt_serial_id2++;
+ last_refund_serial_id2++;
+ last_prewire_serial_id2++;
+
+ FAILIF (GNUNET_OK !=
+ plugin->update_auditor_progress (plugin->cls,
+ session,
+ &master_pub,
+ last_reserve_in_serial_id,
+ last_reserve_out_serial_id,
+ last_deposit_serial_id,
+ last_melt_serial_id,
+ last_refund_serial_id,
+ last_prewire_serial_id));
+
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Test: get_auditor_progress\n");
+
+ FAILIF (GNUNET_OK !=
+ plugin->get_auditor_progress (plugin->cls,
+ session,
+ &master_pub,
+ &last_reserve_in_serial_id2,
+ &last_reserve_out_serial_id2,
+ &last_deposit_serial_id2,
+ &last_melt_serial_id2,
+ &last_refund_serial_id2,
+ &last_prewire_serial_id2));
+
+ FAILIF (last_reserve_in_serial_id2 != last_reserve_in_serial_id
+ || last_reserve_out_serial_id2 != last_reserve_out_serial_id
+ || last_deposit_serial_id2 != last_deposit_serial_id
+ || last_melt_serial_id2 != last_melt_serial_id
+ || last_refund_serial_id2 != last_refund_serial_id
+ || last_prewire_serial_id2 != last_prewire_serial_id);
+
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Test: insert_reserve_info\n");
+
+ struct TALER_Amount reserve_balance, withdraw_fee_balance;
+ struct TALER_Amount reserve_balance2 = {}, withdraw_fee_balance2 = {};
+
+ GNUNET_assert (GNUNET_OK ==
+ TALER_string_to_amount (CURRENCY ":12.345678",
+ &reserve_balance));
+ GNUNET_assert (GNUNET_OK ==
+ TALER_string_to_amount (CURRENCY ":23.456789",
+ &withdraw_fee_balance));
+
+ FAILIF (GNUNET_OK !=
+ plugin->insert_reserve_info (plugin->cls,
+ session,
+ &reserve_pub,
+ &master_pub,
+ &reserve_balance,
+ &withdraw_fee_balance,
+ past,
+ last_reserve_in_serial_id,
+ last_reserve_out_serial_id));
+
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Test: update_reserve_info\n");
+
+ last_reserve_in_serial_id++;
+ last_reserve_out_serial_id++;
+
+ FAILIF (GNUNET_OK !=
+ plugin->update_reserve_info (plugin->cls,
+ session,
+ &reserve_pub,
+ &master_pub,
+ &reserve_balance,
+ &withdraw_fee_balance,
+ future,
+ last_reserve_in_serial_id,
+ last_reserve_out_serial_id));
+
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Test: get_reserve_info\n");
+
+ FAILIF (GNUNET_OK !=
+ plugin->get_reserve_info (plugin->cls,
+ session,
+ &reserve_pub,
+ &master_pub,
+ &reserve_balance2,
+ &withdraw_fee_balance2,
+ &date,
+ &last_reserve_in_serial_id2,
+ &last_reserve_out_serial_id2));
+
+ FAILIF (0 != memcmp (&date, &future, sizeof (future))
+ || 0 != memcmp (&reserve_balance2, &reserve_balance, sizeof (reserve_balance))
+ || 0 != memcmp (&withdraw_fee_balance2, &withdraw_fee_balance, sizeof (withdraw_fee_balance))
+ || last_reserve_in_serial_id2 != last_reserve_in_serial_id
+ || last_reserve_out_serial_id2 != last_reserve_out_serial_id);
+
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Test: insert_reserve_summary\n");
+
+ FAILIF (GNUNET_OK !=
+ plugin->insert_reserve_summary (plugin->cls,
+ session,
+ &master_pub,
+ &withdraw_fee_balance,
+ &reserve_balance));
+
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Test: update_reserve_summary\n");
+
+ FAILIF (GNUNET_OK !=
+ plugin->update_reserve_summary (plugin->cls,
+ session,
+ &master_pub,
+ &reserve_balance,
+ &withdraw_fee_balance));
+
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Test: get_reserve_summary\n");
+
+ ZR_BLK (&reserve_balance2);
+ ZR_BLK (&withdraw_fee_balance2);
+
+ FAILIF (GNUNET_OK !=
+ plugin->get_reserve_summary (plugin->cls,
+ session,
+ &master_pub,
+ &reserve_balance2,
+ &withdraw_fee_balance2));
+
+ FAILIF (0 != memcmp (&reserve_balance2, &reserve_balance, sizeof (reserve_balance))
+ || 0 != memcmp (&withdraw_fee_balance2, &withdraw_fee_balance, sizeof (withdraw_fee_balance)));
+
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Test: insert_denomination_balance\n");
+
+ struct TALER_Amount denom_balance, deposit_fee_balance, melt_fee_balance, refund_fee_balance;
+ struct TALER_Amount denom_balance2, deposit_fee_balance2, melt_fee_balance2, refund_fee_balance2;
+
+ GNUNET_assert (GNUNET_OK ==
+ TALER_string_to_amount (CURRENCY ":12.345678",
+ &denom_balance));
+ GNUNET_assert (GNUNET_OK ==
+ TALER_string_to_amount (CURRENCY ":23.456789",
+ &deposit_fee_balance));
+ GNUNET_assert (GNUNET_OK ==
+ TALER_string_to_amount (CURRENCY ":34.567890",
+ &melt_fee_balance));
+ GNUNET_assert (GNUNET_OK ==
+ TALER_string_to_amount (CURRENCY ":45.678901",
+ &refund_fee_balance));
+
+ FAILIF (GNUNET_OK !=
+ plugin->insert_denomination_balance (plugin->cls,
+ session,
+ &denom_pub_hash,
+ &refund_fee_balance,
+ &melt_fee_balance,
+ &deposit_fee_balance,
+ &denom_balance,
+ last_reserve_out_serial_id,
+ last_deposit_serial_id,
+ last_melt_serial_id,
+ last_refund_serial_id));
+
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Test: update_denomination_balance\n");
+
+ last_reserve_out_serial_id++;
+ last_deposit_serial_id++;
+ last_melt_serial_id++;
+ last_refund_serial_id++;
+
+ FAILIF (GNUNET_OK !=
+ plugin->update_denomination_balance (plugin->cls,
+ session,
+ &denom_pub_hash,
+ &denom_balance,
+ &deposit_fee_balance,
+ &melt_fee_balance,
+ &refund_fee_balance,
+ last_reserve_out_serial_id,
+ last_deposit_serial_id,
+ last_melt_serial_id,
+ last_refund_serial_id));
+
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Test: get_denomination_balance\n");
+
+ FAILIF (GNUNET_OK !=
+ plugin->get_denomination_balance (plugin->cls,
+ session,
+ &denom_pub_hash,
+ &denom_balance2,
+ &deposit_fee_balance2,
+ &melt_fee_balance2,
+ &refund_fee_balance2,
+ &last_reserve_out_serial_id2,
+ &last_deposit_serial_id2,
+ &last_melt_serial_id2,
+ &last_refund_serial_id2));
+
+ FAILIF (0 != memcmp (&denom_balance2, &denom_balance, sizeof (denom_balance))
+ || 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))
+ || last_reserve_out_serial_id2 != last_reserve_out_serial_id
+ || last_deposit_serial_id2 != last_deposit_serial_id
+ || last_melt_serial_id2 != last_melt_serial_id
+ || last_refund_serial_id2 != last_refund_serial_id);
+
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Test: insert_denomination_summary\n");
+
+ FAILIF (GNUNET_OK !=
+ plugin->insert_denomination_summary (plugin->cls,
+ session,
+ &master_pub,
+ &refund_fee_balance,
+ &melt_fee_balance,
+ &deposit_fee_balance,
+ &denom_balance));
+
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Test: update_denomination_summary\n");
+
+ FAILIF (GNUNET_OK !=
+ plugin->update_denomination_summary (plugin->cls,
+ session,
+ &master_pub,
+ &denom_balance,
+ &deposit_fee_balance,
+ &melt_fee_balance,
+ &refund_fee_balance));
+
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Test: get_denomination_summary\n");
+
+ ZR_BLK (&denom_balance2);
+ ZR_BLK (&deposit_fee_balance2);
+ ZR_BLK (&melt_fee_balance2);
+ ZR_BLK (&refund_fee_balance2);
+
+ FAILIF (GNUNET_OK !=
+ plugin->get_denomination_summary (plugin->cls,
+ session,
+ &master_pub,
+ &denom_balance2,
+ &deposit_fee_balance2,
+ &melt_fee_balance2,
+ &refund_fee_balance2));
+
+ FAILIF (0 != memcmp (&denom_balance2, &denom_balance, sizeof (denom_balance))
+ || 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)));
+
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Test: insert_risk_summary\n");
+
+ struct TALER_Amount balance, balance2;
+
+ GNUNET_assert (GNUNET_OK ==
+ TALER_string_to_amount (CURRENCY ":13.57986",
+ &balance));
+
+ FAILIF (GNUNET_OK !=
+ plugin->insert_risk_summary (plugin->cls,
+ session,
+ &master_pub,
+ &balance));
+
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Test: update_risk_summary\n");
+
+ GNUNET_assert (GNUNET_OK ==
+ TALER_string_to_amount (CURRENCY ":57.310986",
+ &balance));
+
+ FAILIF (GNUNET_OK !=
+ plugin->update_risk_summary (plugin->cls,
+ session,
+ &master_pub,
+ &balance));
+
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Test: get_risk_summary\n");
+
+ FAILIF (GNUNET_OK !=
+ plugin->get_risk_summary (plugin->cls,
+ session,
+ &master_pub,
+ &balance2));
+
+ FAILIF (0 != memcmp (&balance2, &balance, sizeof (balance)));
+
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Test: insert_historic_denom_revenue\n");
+
+ FAILIF (GNUNET_OK !=
+ plugin->insert_historic_denom_revenue (plugin->cls,
+ session,
+ &master_pub,
+ &denom_pub_hash,
+ past,
+ &balance,
+ &deposit_fee_balance,
+ &melt_fee_balance,
+ &refund_fee_balance));
+
+ FAILIF (GNUNET_OK !=
+ plugin->insert_historic_denom_revenue (plugin->cls,
+ session,
+ &master_pub,
+ &rnd_hash,
+ now,
+ &balance,
+ &deposit_fee_balance,
+ &melt_fee_balance,
+ &refund_fee_balance));
+
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Test: select_historic_denom_revenue\n");
+
+ int
+ 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)
+ {
+ static int n = 0;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "select_historic_denom_revenue_result: row %u\n", n);
+
+ if (2 <= n++
+ || cls != NULL
+ || (0 != memcmp (&revenue_timestamp2, &past, sizeof (past))
+ && 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, &balance, sizeof (balance))
+ || 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)))
+ {
+ 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 (GNUNET_OK !=
+ plugin->select_historic_denom_revenue (plugin->cls,
+ session,
+ &master_pub,
+ select_historic_denom_revenue_result,
+ NULL));
+
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Test: insert_historic_losses\n");
+
+ FAILIF (GNUNET_OK !=
+ plugin->insert_historic_losses (plugin->cls,
+ session,
+ &master_pub,
+ &denom_pub_hash,
+ past,
+ &balance));
+
+ FAILIF (GNUNET_OK !=
+ plugin->insert_historic_losses (plugin->cls,
+ session,
+ &master_pub,
+ &rnd_hash,
+ past,
+ &balance));
+
+ 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 != memcmp (&loss_timestamp2, &past, sizeof (past))
+ && 0 != memcmp (&loss_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 (loss_balance2, &balance, sizeof (balance)))
+ {
+ 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 (GNUNET_OK !=
+ 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;
+ GNUNET_assert (GNUNET_OK ==
+ TALER_string_to_amount (CURRENCY ":56.789012",
+ &reserve_profits));
+
+ FAILIF (GNUNET_OK !=
+ plugin->insert_historic_reserve_revenue (plugin->cls,
+ session,
+ &master_pub,
+ past,
+ future,
+ &reserve_profits));
+
+ FAILIF (GNUNET_OK !=
+ plugin->insert_historic_reserve_revenue (plugin->cls,
+ session,
+ &master_pub,
+ now,
+ future,
+ &reserve_profits));
+
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Test: select_historic_reserve_revenue\n");
+
+ int
+ select_historic_reserve_revenue_result (void *cls,
+ struct GNUNET_TIME_Absolute start_time2,
+ struct GNUNET_TIME_Absolute end_time2,
+ const struct TALER_Amount *reserve_profits2)
+ {
+ static int n = 0;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "select_historic_reserve_revenue_result: row %u\n", n);
+
+ if (2 <= n++
+ || cls != NULL
+ || (0 != memcmp (&start_time2, &past, sizeof (past))
+ && 0 != memcmp (&start_time2, &now, sizeof (now)))
+ || 0 != memcmp (&end_time2, &future, sizeof (future))
+ || 0 != memcmp (reserve_profits2, &reserve_profits, sizeof (reserve_profits)))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "select_historic_reserve_revenue_result: result does not match\n");
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ return GNUNET_OK;
+ }
+
+ FAILIF (GNUNET_OK !=
+ plugin->select_historic_reserve_revenue (plugin->cls,
+ session,
+ &master_pub,
+ select_historic_reserve_revenue_result,
+ NULL));
+
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Test: insert_predicted_result\n");
+
+ FAILIF (GNUNET_OK !=
+ plugin->insert_predicted_result (plugin->cls,
+ session,
+ &master_pub,
+ &balance));
+
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Test: update_predicted_result\n");
+
+ GNUNET_assert (GNUNET_OK ==
+ TALER_string_to_amount (CURRENCY ":78.901234",
+ &balance));
+
+ FAILIF (GNUNET_OK !=
+ plugin->update_predicted_result (plugin->cls,
+ session,
+ &master_pub,
+ &balance));
+
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Test: get_predicted_balance\n");
+
+ FAILIF (GNUNET_OK !=
+ plugin->get_predicted_balance (plugin->cls,
+ session,
+ &master_pub,
+ &balance2));
+
+ FAILIF (0 != memcmp (&balance2, &balance, sizeof (balance)));
+
+ result = 0;
+
+drop:
+
+ GNUNET_break (GNUNET_OK ==
+ plugin->drop_tables (plugin->cls));
+ TALER_AUDITORDB_plugin_unload (plugin);
+ plugin = NULL;
+}
+
+
+int
+main (int argc,
+ char *const argv[])
+{
+ const char *plugin_name;
+ char *config_filename;
+ char *testname;
+ struct GNUNET_CONFIGURATION_Handle *cfg;
+
+ result = -1;
+ if (NULL == (plugin_name = strrchr (argv[0], (int) '-')))
+ {
+ GNUNET_break (0);
+ return -1;
+ }
+ GNUNET_log_setup (argv[0],
+ "WARNING",
+ NULL);
+ plugin_name++;
+ (void) GNUNET_asprintf (&testname,
+ "test-auditor-db-%s", plugin_name);
+ (void) GNUNET_asprintf (&config_filename,
+ "%s.conf", testname);
+ cfg = GNUNET_CONFIGURATION_create ();
+ if (GNUNET_OK !=
+ GNUNET_CONFIGURATION_parse (cfg,
+ config_filename))
+ {
+ GNUNET_break (0);
+ GNUNET_free (config_filename);
+ GNUNET_free (testname);
+ return 2;
+ }
+ GNUNET_SCHEDULER_run (&run, cfg);
+ GNUNET_CONFIGURATION_destroy (cfg);
+ GNUNET_free (config_filename);
+ GNUNET_free (testname);
+ return result;
+}
diff --git a/src/bank-lib/test_bank_api.c b/src/bank-lib/test_bank_api.c
index 88fe82451..88ca2fd24 100644
--- a/src/bank-lib/test_bank_api.c
+++ b/src/bank-lib/test_bank_api.c
@@ -67,22 +67,35 @@ main (int argc,
char * const *argv)
{
struct GNUNET_OS_Process *bankd;
+ struct GNUNET_OS_Process *bankd_admin;
unsigned int cnt;
int result;
GNUNET_log_setup ("test-bank-api",
"WARNING",
NULL);
+ bankd_admin = GNUNET_OS_start_process (GNUNET_NO,
+ GNUNET_OS_INHERIT_STD_ALL,
+ NULL, NULL, NULL,
+ "taler-bank-manage",
+ "taler-bank-manage",
+ "--admin",
+ "serve-http",
+ "--port", "8081",
+ NULL);
bankd = GNUNET_OS_start_process (GNUNET_NO,
GNUNET_OS_INHERIT_STD_ALL,
NULL, NULL, NULL,
"taler-bank-manage",
"taler-bank-manage",
"serve-http",
- "--port", "8081",
+ "--port", "8080",
NULL);
- if (NULL == bankd)
+
+
+ if ((NULL == bankd_admin) || (NULL == bankd))
{
+ /*FIXME: More accurate error message?*/
fprintf (stderr,
"taler-bank-manage not found, skipping test\n");
return 77; /* report 'skip' */
@@ -99,13 +112,26 @@ main (int argc,
if (cnt > 30)
break;
}
- while (0 != system ("wget -q -t 1 -T 1 http://127.0.0.1:8081/ -o /dev/null -O /dev/null"));
+ while (0 != system ("wget -q -t 1 -T 1 http://127.0.0.1:8080/ -o /dev/null -O /dev/null"));
+
+ do
+ {
+ fprintf (stderr, ".");
+ sleep (1);
+ cnt++;
+ if (cnt > 30)
+ break;
+ }
+ while (0 != system ("wget -q -t 1 -T 1 http://127.0.0.1:8081/admin/add/incoming -o /dev/null -O /dev/null"));
+
fprintf (stderr, "\n");
result = GNUNET_SYSERR;
if (cnt <= 30)
GNUNET_SCHEDULER_run (&run, &result);
GNUNET_OS_process_kill (bankd,
SIGTERM);
+ GNUNET_OS_process_kill (bankd_admin,
+ SIGTERM);
GNUNET_OS_process_wait (bankd);
GNUNET_OS_process_destroy (bankd);
if (cnt > 30)
diff --git a/src/benchmark/taler-exchange-benchmark.c b/src/benchmark/taler-exchange-benchmark.c
index 40e5818bf..7b143a189 100644
--- a/src/benchmark/taler-exchange-benchmark.c
+++ b/src/benchmark/taler-exchange-benchmark.c
@@ -541,6 +541,7 @@ find_pk (const struct TALER_EXCHANGE_Keys *keys,
* @param cls closure with the `struct Coin *`
* @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful status request
* 0 if the exchange's reply is bogus (fails to follow the protocol)
+ * @param ec taler-specific error code, #TALER_EC_NONE on success
* @param num_coins number of fresh coins created, length of the @a sigs and @a coin_privs arrays, 0 if the operation failed
* @param coin_privs array of @a num_coins private keys for the coins that were created, NULL on error
* @param sigs array of signature over @a num_coins coins, NULL on error
@@ -549,6 +550,7 @@ find_pk (const struct TALER_EXCHANGE_Keys *keys,
static void
reveal_cb (void *cls,
unsigned int http_status,
+ enum TALER_ErrorCode ec,
unsigned int num_coins,
const struct TALER_CoinSpendPrivateKeyP *coin_privs,
const struct TALER_DenominationSignature *sigs,
@@ -617,6 +619,7 @@ reveal_cb (void *cls,
* @param cls closure with the `struct Coin *`
* @param http_status HTTP response code, never #MHD_HTTP_OK (200) as for successful intermediate response this callback is skipped.
* 0 if the exchange's reply is bogus (fails to follow the protocol)
+ * @param ec taler-specific error code, #TALER_EC_NONE on success
* @param noreveal_index choice by the exchange in the cut-and-choose protocol,
* UINT16_MAX on error
* @param exchange_pub public key the exchange used for signing
@@ -625,6 +628,7 @@ reveal_cb (void *cls,
static void
melt_cb (void *cls,
unsigned int http_status,
+ enum TALER_ErrorCode ec,
uint16_t noreveal_index,
const struct TALER_ExchangePublicKeyP *exchange_pub,
const json_t *full_response)
@@ -776,6 +780,7 @@ refresh_coin (struct Coin *coin)
* @param cls closure with the `struct Coin` that we are processing
* @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful deposit;
* 0 if the exchange's reply is bogus (fails to follow the protocol)
+ * @param ec taler-specific error code, #TALER_EC_NONE on success
* @param exchange_pub public key used by the exchange for signing
* @param obj the received JSON reply, should be kept as proof (and, in case of errors,
* be forwarded to the customer)
@@ -783,6 +788,7 @@ refresh_coin (struct Coin *coin)
static void
deposit_cb (void *cls,
unsigned int http_status,
+ enum TALER_ErrorCode ec,
const struct TALER_ExchangePublicKeyP *exchange_pub,
const json_t *obj)
{
@@ -935,12 +941,14 @@ spend_coin (struct Coin *coin,
* @param cls closure with our `struct Coin`
* @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful status request
* 0 if the exchange's reply is bogus (fails to follow the protocol)
+ * @param ec taler-specific error code, #TALER_EC_NONE on success
* @param sig signature over the coin, NULL on error
* @param full_response full response from the exchange (for logging, in case of errors)
*/
static void
reserve_withdraw_cb (void *cls,
unsigned int http_status,
+ enum TALER_ErrorCode ec,
const struct TALER_DenominationSignature *sig,
const json_t *full_response)
{
@@ -1027,11 +1035,13 @@ withdraw_coin (struct Coin *coin)
* @param cls closure with the `struct Reserve *`
* @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful status request
* 0 if the exchange's reply is bogus (fails to follow the protocol)
+ * @param ec taler-specific error code, #TALER_EC_NONE on success
* @param full_response full response from the exchange (for logging, in case of errors)
*/
static void
add_incoming_cb (void *cls,
unsigned int http_status,
+ enum TALER_ErrorCode ec,
const json_t *full_response)
{
struct Reserve *r = cls;
diff --git a/src/exchange-lib/Makefile.am b/src/exchange-lib/Makefile.am
index 83fcf1475..19c36744d 100644
--- a/src/exchange-lib/Makefile.am
+++ b/src/exchange-lib/Makefile.am
@@ -14,7 +14,7 @@ libtalerexchange_la_LDFLAGS = \
-no-undefined
libtalerexchange_la_SOURCES = \
- exchange_api_common.c exchange_api_common.h \
+ exchange_api_common.c \
exchange_api_handle.c exchange_api_handle.h \
exchange_api_admin.c \
exchange_api_deposit.c \
diff --git a/src/exchange-lib/exchange_api_admin.c b/src/exchange-lib/exchange_api_admin.c
index 524916e68..e6cb8101c 100644
--- a/src/exchange-lib/exchange_api_admin.c
+++ b/src/exchange-lib/exchange_api_admin.c
@@ -1,6 +1,6 @@
/*
This file is part of TALER
- Copyright (C) 2014, 2015 GNUnet e.V.
+ Copyright (C) 2014, 2015, 2016 GNUnet e.V.
TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
@@ -129,6 +129,7 @@ handle_admin_add_incoming_finished (void *cls,
}
aai->cb (aai->cb_cls,
response_code,
+ TALER_JSON_get_error_code (json),
json);
TALER_EXCHANGE_admin_add_incoming_cancel (aai);
}
diff --git a/src/exchange-lib/exchange_api_common.c b/src/exchange-lib/exchange_api_common.c
index acf90fce6..a531b1c39 100644
--- a/src/exchange-lib/exchange_api_common.c
+++ b/src/exchange-lib/exchange_api_common.c
@@ -20,7 +20,6 @@
* @author Christian Grothoff
*/
#include "platform.h"
-#include "exchange_api_common.h"
#include "taler_json_lib.h"
#include <gnunet/gnunet_curl_lib.h>
#include "exchange_api_handle.h"
@@ -38,8 +37,8 @@
*/
int
TALER_EXCHANGE_verify_coin_history (const char *currency,
- const struct TALER_CoinSpendPublicKeyP *coin_pub,
- json_t *history,
+ const struct TALER_CoinSpendPublicKeyP *coin_pub,
+ json_t *history,
struct TALER_Amount *total)
{
size_t len;
diff --git a/src/exchange-lib/exchange_api_common.h b/src/exchange-lib/exchange_api_common.h
deleted file mode 100644
index 5655f5d3b..000000000
--- a/src/exchange-lib/exchange_api_common.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2015 GNUnet e.V.
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the Free Software
- Foundation; either version 3, or (at your option) any later version.
-
- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- TALER; see the file COPYING. If not, see
- <http://www.gnu.org/licenses/>
-*/
-/**
- * @file exchange-lib/exchange_api_common.h
- * @brief common functions for the exchange API
- * @author Christian Grothoff
- */
-#include <jansson.h>
-#include <gnunet/gnunet_util_lib.h>
-#include "taler_exchange_service.h"
-
-/**
- * Verify a coins transaction history as returned by the exchange.
- *
- * @param currency expected currency for the coin
- * @param coin_pub public key of the coin
- * @param history history of the coin in json encoding
- * @param[out] total how much of the coin has been spent according to @a history
- * @return #GNUNET_OK if @a history is valid, #GNUNET_SYSERR if not
- */
-int
-TALER_EXCHANGE_verify_coin_history (const char *currency,
- const struct TALER_CoinSpendPublicKeyP *coin_pub,
- json_t *history,
- struct TALER_Amount *total);
-
-/* end of exchange_api_common.h */
diff --git a/src/exchange-lib/exchange_api_deposit.c b/src/exchange-lib/exchange_api_deposit.c
index aa7e07ed8..9282bbfd1 100644
--- a/src/exchange-lib/exchange_api_deposit.c
+++ b/src/exchange-lib/exchange_api_deposit.c
@@ -29,7 +29,6 @@
#include <gnunet/gnunet_curl_lib.h>
#include "taler_json_lib.h"
#include "taler_exchange_service.h"
-#include "exchange_api_common.h"
#include "exchange_api_handle.h"
#include "taler_signatures.h"
@@ -262,6 +261,7 @@ handle_deposit_finished (void *cls,
}
dh->cb (dh->cb_cls,
response_code,
+ TALER_JSON_get_error_code (json),
ep,
json);
TALER_EXCHANGE_deposit_cancel (dh);
diff --git a/src/exchange-lib/exchange_api_refresh.c b/src/exchange-lib/exchange_api_refresh.c
index 6d12a718c..c3216a6e6 100644
--- a/src/exchange-lib/exchange_api_refresh.c
+++ b/src/exchange-lib/exchange_api_refresh.c
@@ -28,7 +28,6 @@
#include <gnunet/gnunet_curl_lib.h>
#include "taler_json_lib.h"
#include "taler_exchange_service.h"
-#include "exchange_api_common.h"
#include "exchange_api_handle.h"
#include "taler_signatures.h"
@@ -1115,6 +1114,7 @@ handle_refresh_melt_finished (void *cls,
{
rmh->melt_cb (rmh->melt_cb_cls,
response_code,
+ TALER_JSON_get_error_code (json),
noreveal_index,
(0 == response_code) ? NULL : &exchange_pub,
json);
@@ -1160,6 +1160,7 @@ handle_refresh_melt_finished (void *cls,
if (NULL != rmh->melt_cb)
rmh->melt_cb (rmh->melt_cb_cls,
response_code,
+ TALER_JSON_get_error_code (json),
UINT16_MAX,
NULL,
json);
@@ -1598,6 +1599,7 @@ handle_refresh_reveal_finished (void *cls,
{
rrh->reveal_cb (rrh->reveal_cb_cls,
MHD_HTTP_OK,
+ TALER_EC_NONE,
rrh->md->num_fresh_coins,
coin_privs,
sigs,
@@ -1634,7 +1636,10 @@ handle_refresh_reveal_finished (void *cls,
if (NULL != rrh->reveal_cb)
rrh->reveal_cb (rrh->reveal_cb_cls,
response_code,
- 0, NULL, NULL,
+ TALER_JSON_get_error_code (json),
+ 0,
+ NULL,
+ NULL,
json);
TALER_EXCHANGE_refresh_reveal_cancel (rrh);
}
diff --git a/src/exchange-lib/exchange_api_refresh_link.c b/src/exchange-lib/exchange_api_refresh_link.c
index a1dba9938..9b825138e 100644
--- a/src/exchange-lib/exchange_api_refresh_link.c
+++ b/src/exchange-lib/exchange_api_refresh_link.c
@@ -265,6 +265,7 @@ parse_refresh_link_ok (struct TALER_EXCHANGE_RefreshLinkHandle *rlh,
{
rlh->link_cb (rlh->link_cb_cls,
MHD_HTTP_OK,
+ TALER_EC_NONE,
num_coins,
coin_privs,
sigs,
@@ -345,7 +346,11 @@ handle_refresh_link_finished (void *cls,
if (NULL != rlh->link_cb)
rlh->link_cb (rlh->link_cb_cls,
response_code,
- 0, NULL, NULL, NULL,
+ TALER_JSON_get_error_code (json),
+ 0,
+ NULL,
+ NULL,
+ NULL,
json);
TALER_EXCHANGE_refresh_link_cancel (rlh);
}
diff --git a/src/exchange-lib/exchange_api_refund.c b/src/exchange-lib/exchange_api_refund.c
index f712f126a..be080c57b 100644
--- a/src/exchange-lib/exchange_api_refund.c
+++ b/src/exchange-lib/exchange_api_refund.c
@@ -28,7 +28,6 @@
#include <gnunet/gnunet_curl_lib.h>
#include "taler_json_lib.h"
#include "taler_exchange_service.h"
-#include "exchange_api_common.h"
#include "exchange_api_handle.h"
#include "taler_signatures.h"
@@ -196,6 +195,7 @@ handle_refund_finished (void *cls,
}
rh->cb (rh->cb_cls,
response_code,
+ TALER_JSON_get_error_code (json),
ep,
json);
TALER_EXCHANGE_refund_cancel (rh);
diff --git a/src/exchange-lib/exchange_api_reserve.c b/src/exchange-lib/exchange_api_reserve.c
index 0bff767e6..28f329c42 100644
--- a/src/exchange-lib/exchange_api_reserve.c
+++ b/src/exchange-lib/exchange_api_reserve.c
@@ -314,7 +314,8 @@ handle_reserve_status_finished (void *cls,
if (GNUNET_OK !=
GNUNET_JSON_parse (json,
spec,
- NULL, NULL))
+ NULL,
+ NULL))
{
GNUNET_break_op (0);
response_code = 0;
@@ -355,6 +356,7 @@ handle_reserve_status_finished (void *cls,
}
wsh->cb (wsh->cb_cls,
response_code,
+ TALER_EC_NONE,
json,
&balance,
len,
@@ -387,6 +389,7 @@ handle_reserve_status_finished (void *cls,
if (NULL != wsh->cb)
wsh->cb (wsh->cb_cls,
response_code,
+ TALER_JSON_get_error_code (json),
json,
NULL,
0, NULL);
@@ -589,6 +592,7 @@ reserve_withdraw_ok (struct TALER_EXCHANGE_ReserveWithdrawHandle *wsh,
dsig.rsa_signature = sig;
wsh->cb (wsh->cb_cls,
MHD_HTTP_OK,
+ TALER_EC_NONE,
&dsig,
json);
/* make sure callback isn't called again after return */
@@ -599,7 +603,7 @@ reserve_withdraw_ok (struct TALER_EXCHANGE_ReserveWithdrawHandle *wsh,
/**
- * We got a 402 PAYMENT REQUIRED response for the /reserve/withdraw operation.
+ * We got a 403 FORBIDDEN response for the /reserve/withdraw operation.
* Check the signatures on the withdraw transactions in the provided
* history and that the balances add up. We don't do anything directly
* with the information, as the JSON will be returned to the application.
@@ -723,7 +727,7 @@ handle_reserve_withdraw_finished (void *cls,
/* This should never happen, either us or the exchange is buggy
(or API version conflict); just pass JSON reply to the application */
break;
- case MHD_HTTP_PAYMENT_REQUIRED:
+ case MHD_HTTP_FORBIDDEN:
/* The exchange says that the reserve has insufficient funds;
check the signatures in the history... */
if (GNUNET_OK !=
@@ -762,6 +766,7 @@ handle_reserve_withdraw_finished (void *cls,
if (NULL != wsh->cb)
wsh->cb (wsh->cb_cls,
response_code,
+ TALER_JSON_get_error_code (json),
NULL,
json);
TALER_EXCHANGE_reserve_withdraw_cancel (wsh);
diff --git a/src/exchange-lib/exchange_api_track_transaction.c b/src/exchange-lib/exchange_api_track_transaction.c
index c05115d57..7fd2efb21 100644
--- a/src/exchange-lib/exchange_api_track_transaction.c
+++ b/src/exchange-lib/exchange_api_track_transaction.c
@@ -28,7 +28,6 @@
#include <gnunet/gnunet_curl_lib.h>
#include "taler_json_lib.h"
#include "taler_exchange_service.h"
-#include "exchange_api_common.h"
#include "exchange_api_handle.h"
#include "taler_signatures.h"
@@ -239,6 +238,7 @@ handle_deposit_wtid_finished (void *cls,
}
dwh->cb (dwh->cb_cls,
response_code,
+ TALER_JSON_get_error_code (json),
ep,
json,
wtid,
diff --git a/src/exchange-lib/exchange_api_track_transfer.c b/src/exchange-lib/exchange_api_track_transfer.c
index ffcb19b59..8ed5865d7 100644
--- a/src/exchange-lib/exchange_api_track_transfer.c
+++ b/src/exchange-lib/exchange_api_track_transfer.c
@@ -26,7 +26,6 @@
#include <gnunet/gnunet_util_lib.h>
#include <gnunet/gnunet_curl_lib.h>
#include "taler_exchange_service.h"
-#include "exchange_api_common.h"
#include "taler_json_lib.h"
#include "exchange_api_handle.h"
#include "taler_signatures.h"
@@ -183,6 +182,7 @@ check_track_transfer_response_ok (struct TALER_EXCHANGE_TrackTransferHandle *wdh
}
wdh->cb (wdh->cb_cls,
MHD_HTTP_OK,
+ TALER_EC_NONE,
&exchange_pub,
json,
&h_wire,
@@ -253,6 +253,7 @@ handle_track_transfer_finished (void *cls,
}
wdh->cb (wdh->cb_cls,
response_code,
+ TALER_JSON_get_error_code (json),
NULL,
json,
NULL,
diff --git a/src/exchange-lib/exchange_api_wire.c b/src/exchange-lib/exchange_api_wire.c
index cb8df4944..7401e66d4 100644
--- a/src/exchange-lib/exchange_api_wire.c
+++ b/src/exchange-lib/exchange_api_wire.c
@@ -28,7 +28,6 @@
#include "taler_exchange_service.h"
#include "taler_json_lib.h"
#include "taler_wire_plugin.h"
-#include "exchange_api_common.h"
#include "exchange_api_handle.h"
@@ -210,6 +209,7 @@ handle_wire_finished (void *cls,
}
wh->cb (wh->cb_cls,
response_code,
+ TALER_JSON_get_error_code (json),
(NULL != keep) ? keep : json);
if (NULL != keep)
json_decref (keep);
diff --git a/src/exchange-lib/test_exchange_api.c b/src/exchange-lib/test_exchange_api.c
index 541a621d2..e25fa66cd 100644
--- a/src/exchange-lib/test_exchange_api.c
+++ b/src/exchange-lib/test_exchange_api.c
@@ -761,11 +761,13 @@ next_command (struct InterpreterState *is)
* @param cls closure with the interpreter state
* @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful status request
* 0 if the exchange's reply is bogus (fails to follow the protocol)
+ * @param ec taler-specific error code, #TALER_EC_NONE on success
* @param full_response full response from the exchange (for logging, in case of errors)
*/
static void
add_incoming_cb (void *cls,
unsigned int http_status,
+ enum TALER_ErrorCode ec,
const json_t *full_response)
{
struct InterpreterState *is = cls;
@@ -857,6 +859,7 @@ compare_reserve_withdraw_history (const struct TALER_EXCHANGE_ReserveHistory *h,
* @param cls closure with the interpreter state
* @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful status request
* 0 if the exchange's reply is bogus (fails to follow the protocol)
+ * @param ec taler-specific error code, #TALER_EC_NONE on success
* @param[in] json original response in JSON format (useful only for diagnostics)
* @param balance current balance in the reserve, NULL on error
* @param history_length number of entries in the transaction history, 0 on error
@@ -865,6 +868,7 @@ compare_reserve_withdraw_history (const struct TALER_EXCHANGE_ReserveHistory *h,
static void
reserve_status_cb (void *cls,
unsigned int http_status,
+ enum TALER_ErrorCode ec,
const json_t *json,
const struct TALER_Amount *balance,
unsigned int history_length,
@@ -924,7 +928,7 @@ reserve_status_cb (void *cls,
{
if (GNUNET_OK !=
compare_reserve_withdraw_history (&history[j],
- rel))
+ rel))
{
GNUNET_break (0);
fail (is);
@@ -973,12 +977,14 @@ reserve_status_cb (void *cls,
* @param cls closure with the interpreter state
* @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful status request
* 0 if the exchange's reply is bogus (fails to follow the protocol)
+ * @param ec taler-specific error code, #TALER_EC_NONE on success
* @param sig signature over the coin, NULL on error
* @param full_response full response from the exchange (for logging, in case of errors)
*/
static void
reserve_withdraw_cb (void *cls,
unsigned int http_status,
+ enum TALER_ErrorCode ec,
const struct TALER_DenominationSignature *sig,
const json_t *full_response)
{
@@ -1009,7 +1015,7 @@ reserve_withdraw_cb (void *cls,
cmd->details.reserve_withdraw.sig.rsa_signature
= GNUNET_CRYPTO_rsa_signature_dup (sig->rsa_signature);
break;
- case MHD_HTTP_PAYMENT_REQUIRED:
+ case MHD_HTTP_FORBIDDEN:
/* nothing to check */
break;
default:
@@ -1027,6 +1033,7 @@ reserve_withdraw_cb (void *cls,
* @param cls closure with the interpreter state
* @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful deposit;
* 0 if the exchange's reply is bogus (fails to follow the protocol)
+ * @param ec taler-specific error code, #TALER_EC_NONE on success
* @param exchange_pub public key the exchange used for signing
* @param obj the received JSON reply, should be kept as proof (and, in case of errors,
* be forwarded to the customer)
@@ -1034,6 +1041,7 @@ reserve_withdraw_cb (void *cls,
static void
deposit_cb (void *cls,
unsigned int http_status,
+ enum TALER_ErrorCode ec,
const struct TALER_ExchangePublicKeyP *exchange_pub,
const json_t *obj)
{
@@ -1061,6 +1069,7 @@ deposit_cb (void *cls,
* @param cls closure with the interpreter state
* @param http_status HTTP response code, never #MHD_HTTP_OK (200) as for successful intermediate response this callback is skipped.
* 0 if the exchange's reply is bogus (fails to follow the protocol)
+ * @param ec taler-specific error code, #TALER_EC_NONE on success
* @param noreveal_index choice by the exchange in the cut-and-choose protocol,
* UINT16_MAX on error
* @param exchange_pub public key the exchange used for signing
@@ -1069,6 +1078,7 @@ deposit_cb (void *cls,
static void
melt_cb (void *cls,
unsigned int http_status,
+ enum TALER_ErrorCode ec,
uint16_t noreveal_index,
const struct TALER_ExchangePublicKeyP *exchange_pub,
const json_t *full_response)
@@ -1098,6 +1108,7 @@ melt_cb (void *cls,
* @param cls closure with the interpreter state
* @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful status request
* 0 if the exchange's reply is bogus (fails to follow the protocol)
+ * @param ec taler-specific error code, #TALER_EC_NONE on success
* @param num_coins number of fresh coins created, length of the @a sigs and @a coin_privs arrays, 0 if the operation failed
* @param coin_privs array of @a num_coins private keys for the coins that were created, NULL on error
* @param sigs array of signature over @a num_coins coins, NULL on error
@@ -1106,6 +1117,7 @@ melt_cb (void *cls,
static void
reveal_cb (void *cls,
unsigned int http_status,
+ enum TALER_ErrorCode ec,
unsigned int num_coins,
const struct TALER_CoinSpendPrivateKeyP *coin_privs,
const struct TALER_DenominationSignature *sigs,
@@ -1160,6 +1172,7 @@ reveal_cb (void *cls,
* @param cls closure with the interpreter state
* @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful status request
* 0 if the exchange's reply is bogus (fails to follow the protocol)
+ * @param ec taler-specific error code, #TALER_EC_NONE on success
* @param num_coins number of fresh coins created, length of the @a sigs and @a coin_privs arrays, 0 if the operation failed
* @param coin_privs array of @a num_coins private keys for the coins that were created, NULL on error
* @param sigs array of signature over @a num_coins coins, NULL on error
@@ -1169,6 +1182,7 @@ reveal_cb (void *cls,
static void
link_cb (void *cls,
unsigned int http_status,
+ enum TALER_ErrorCode ec,
unsigned int num_coins,
const struct TALER_CoinSpendPrivateKeyP *coin_privs,
const struct TALER_DenominationSignature *sigs,
@@ -1336,12 +1350,14 @@ find_pk (const struct TALER_EXCHANGE_Keys *keys,
* @param cls closure with the interpreter state
* @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful request;
* 0 if the exchange's reply is bogus (fails to follow the protocol)
+ * @param ec taler-specific error code, #TALER_EC_NONE on success
* @param obj the received JSON reply, if successful this should be the wire
* format details as provided by /wire.
*/
static void
wire_cb (void *cls,
unsigned int http_status,
+ enum TALER_ErrorCode ec,
const json_t *obj)
{
struct InterpreterState *is = cls;
@@ -1391,6 +1407,7 @@ wire_cb (void *cls,
*
* @param cls closure
* @param http_status HTTP status code we got, 0 on exchange protocol violation
+ * @param ec taler-specific error code, #TALER_EC_NONE on success
* @param exchange_pub public key the exchange used for signing
* @param json original json reply (may include signatures, those have then been
* validated already)
@@ -1404,6 +1421,7 @@ wire_cb (void *cls,
static void
wire_deposits_cb (void *cls,
unsigned int http_status,
+ enum TALER_ErrorCode ec,
const struct TALER_ExchangePublicKeyP *exchange_pub,
const json_t *json,
const struct GNUNET_HashCode *h_wire,
@@ -1521,6 +1539,7 @@ wire_deposits_cb (void *cls,
*
* @param cls closure
* @param http_status HTTP status code we got, 0 on exchange protocol violation
+ * @param ec taler-specific error code, #TALER_EC_NONE on success
* @param exchange_pub public key the exchange used for signing
* @param json original json reply (may include signatures, those have then been
* validated already)
@@ -1534,6 +1553,7 @@ wire_deposits_cb (void *cls,
static void
deposit_wtid_cb (void *cls,
unsigned int http_status,
+ enum TALER_ErrorCode ec,
const struct TALER_ExchangePublicKeyP *exchange_pub,
const json_t *json,
const struct TALER_WireTransferIdentifierRawP *wtid,
@@ -1588,6 +1608,7 @@ deposit_wtid_cb (void *cls,
* @param cls closure
* @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful deposit;
* 0 if the exchange's reply is bogus (fails to follow the protocol)
+ * @param ec taler-specific error code, #TALER_EC_NONE on success
* @param exchange_pub public key the exchange used for signing @a obj
* @param obj the received JSON reply, should be kept as proof (and, in particular,
* be forwarded to the customer)
@@ -1595,6 +1616,7 @@ deposit_wtid_cb (void *cls,
static void
refund_cb (void *cls,
unsigned int http_status,
+ enum TALER_ErrorCode ec,
const struct TALER_ExchangePublicKeyP *exchange_pub,
const json_t *obj)
{
@@ -1782,9 +1804,9 @@ interpreter_run (void *cls)
&reserve_pub.eddsa_pub);
cmd->details.reserve_status.wsh
= TALER_EXCHANGE_reserve_status (exchange,
- &reserve_pub,
- &reserve_status_cb,
- is);
+ &reserve_pub,
+ &reserve_status_cb,
+ is);
return;
case OC_WITHDRAW_SIGN:
GNUNET_assert (NULL !=
@@ -2737,7 +2759,7 @@ run (void *cls)
/* Try to overdraw funds ... */
{ .oc = OC_WITHDRAW_SIGN,
.label = "withdraw-coin-2",
- .expected_response_code = MHD_HTTP_PAYMENT_REQUIRED,
+ .expected_response_code = MHD_HTTP_FORBIDDEN,
.details.reserve_withdraw.reserve_reference = "create-reserve-1",
.details.reserve_withdraw.amount = "EUR:5" },
@@ -3051,8 +3073,11 @@ main (int argc,
unsigned long code;
GNUNET_log_setup ("test-exchange-api",
- "WARNING",
- NULL);
+ "DEBUG",
+ "/tmp/logs");
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test log\n");
+ return 0;
+
/* These might get in the way... */
unsetenv ("XDG_DATA_HOME");
unsetenv ("XDG_CONFIG_HOME");
diff --git a/src/exchange/taler-exchange-httpd_admin.c b/src/exchange/taler-exchange-httpd_admin.c
index e99448f87..72cdcb7d6 100644
--- a/src/exchange/taler-exchange-httpd_admin.c
+++ b/src/exchange/taler-exchange-httpd_admin.c
@@ -89,6 +89,7 @@ TEH_ADMIN_handler_admin_add_incoming (struct TEH_RequestHandler *rh,
GNUNET_break_op (0);
GNUNET_JSON_parse_free (spec);
return TEH_RESPONSE_reply_arg_unknown (connection,
+ TALER_EC_ADMIN_ADD_INCOMING_WIREFORMAT_UNSUPPORTED,
"sender_account_details");
}
if (0 != strcasecmp (amount.currency,
@@ -100,6 +101,7 @@ TEH_ADMIN_handler_admin_add_incoming (struct TEH_RequestHandler *rh,
amount.currency);
GNUNET_JSON_parse_free (spec);
return TEH_RESPONSE_reply_arg_invalid (connection,
+ TALER_EC_ADMIN_ADD_INCOMING_CURRENCY_UNSUPPORTED,
"amount:currency");
}
res = TEH_DB_execute_admin_add_incoming (connection,
diff --git a/src/exchange/taler-exchange-httpd_db.c b/src/exchange/taler-exchange-httpd_db.c
index 6b27a22a6..870f7a251 100644
--- a/src/exchange/taler-exchange-httpd_db.c
+++ b/src/exchange/taler-exchange-httpd_db.c
@@ -53,7 +53,8 @@ transaction_start_label: /* we will use goto for retries */ \
session)) \
{ \
GNUNET_break (0); \
- return TEH_RESPONSE_reply_internal_db_error (connection); \
+ return TEH_RESPONSE_reply_internal_db_error (connection, \
+ TALER_EC_DB_START_FAILED); \
}
/**
@@ -73,8 +74,9 @@ transaction_start_label: /* we will use goto for retries */ \
if (GNUNET_SYSERR == transaction_commit_result) \
{ \
TALER_LOG_WARNING ("Transaction commit failed in %s\n", __FUNCTION__); \
- return TEH_RESPONSE_reply_commit_error (connection); \
- } \
+ return TEH_RESPONSE_reply_commit_error (connection, \
+ TALER_EC_DB_COMMIT_FAILED_HARD); \
+ } \
if (GNUNET_NO == transaction_commit_result) \
{ \
TALER_LOG_WARNING ("Transaction commit failed in %s\n", __FUNCTION__); \
@@ -83,7 +85,8 @@ transaction_start_label: /* we will use goto for retries */ \
TALER_LOG_WARNING ("Transaction commit failed %u times in %s\n", \
transaction_retries, \
__FUNCTION__); \
- return TEH_RESPONSE_reply_commit_error (connection); \
+ return TEH_RESPONSE_reply_commit_error (connection, \
+ TALER_EC_DB_COMMIT_FAILED_ON_RETRY); \
} \
} /* end of scope opened by BEGIN_TRANSACTION */
@@ -197,7 +200,8 @@ TEH_DB_execute_deposit (struct MHD_Connection *connection,
if (NULL == (session = TEH_plugin->get_session (TEH_plugin->cls)))
{
GNUNET_break (0);
- return TEH_RESPONSE_reply_internal_db_error (connection);
+ return TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_DB_SETUP_FAILED);
}
if (GNUNET_YES ==
TEH_plugin->have_deposit (TEH_plugin->cls,
@@ -225,8 +229,8 @@ TEH_DB_execute_deposit (struct MHD_Connection *connection,
if (NULL == dki)
{
TEH_KS_release (mks);
- return TEH_RESPONSE_reply_arg_invalid (connection,
- "denom_pub");
+ return TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_DEPOSIT_DB_DENOMINATION_KEY_UNKNOWN);
}
TALER_amount_ntoh (&value,
&dki->issue.properties.value);
@@ -249,7 +253,8 @@ TEH_DB_execute_deposit (struct MHD_Connection *connection,
session);
TEH_plugin->free_coin_transaction_list (TEH_plugin->cls,
tl);
- return TEH_RESPONSE_reply_internal_db_error (connection);
+ return TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_DEPOSIT_HISTORY_DB_ERROR);
}
/* Check that cost of all transactions is smaller than
the value of the coin. */
@@ -274,7 +279,8 @@ TEH_DB_execute_deposit (struct MHD_Connection *connection,
TALER_LOG_WARNING ("Failed to store /deposit information in database\n");
TEH_plugin->rollback (TEH_plugin->cls,
session);
- return TEH_RESPONSE_reply_internal_db_error (connection);
+ return TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_DEPOSIT_STORE_DB_ERROR);
}
COMMIT_TRANSACTION(session, connection);
@@ -324,7 +330,8 @@ TEH_DB_execute_refund (struct MHD_Connection *connection,
if (NULL == (session = TEH_plugin->get_session (TEH_plugin->cls)))
{
GNUNET_break (0);
- return TEH_RESPONSE_reply_internal_db_error (connection);
+ return TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_DB_SETUP_FAILED);
}
dep = NULL;
ref = NULL;
@@ -337,7 +344,8 @@ TEH_DB_execute_refund (struct MHD_Connection *connection,
TEH_plugin->rollback (TEH_plugin->cls,
session);
return TEH_RESPONSE_reply_refund_failure (connection,
- MHD_HTTP_NOT_FOUND);
+ MHD_HTTP_NOT_FOUND,
+ TALER_EC_REFUND_COIN_NOT_FOUND);
}
deposit_found = GNUNET_NO;
refund_found = GNUNET_NO;
@@ -411,7 +419,8 @@ TEH_DB_execute_refund (struct MHD_Connection *connection,
session);
TEH_plugin->free_coin_transaction_list (TEH_plugin->cls,
tl);
- return TEH_RESPONSE_reply_transaction_unknown (connection);
+ return TEH_RESPONSE_reply_transaction_unknown (connection,
+ TALER_EC_REFUND_DEPOSIT_NOT_FOUND);
}
/* handle if conflicting refund found */
if (GNUNET_SYSERR == refund_found)
@@ -449,7 +458,8 @@ TEH_DB_execute_refund (struct MHD_Connection *connection,
TEH_plugin->rollback (TEH_plugin->cls,
session);
return TEH_RESPONSE_reply_refund_failure (connection,
- MHD_HTTP_PRECONDITION_FAILED);
+ MHD_HTTP_PRECONDITION_FAILED,
+ TALER_EC_REFUND_CURRENCY_MISSMATCH);
}
/* check if we already send the money for the /deposit */
@@ -466,6 +476,7 @@ TEH_DB_execute_refund (struct MHD_Connection *connection,
TEH_plugin->rollback (TEH_plugin->cls,
session);
return TEH_RESPONSE_reply_internal_error (connection,
+ TALER_EC_REFUND_DB_INCONSISTENT,
"database inconsistent");
}
if (GNUNET_YES == done)
@@ -476,7 +487,8 @@ TEH_DB_execute_refund (struct MHD_Connection *connection,
TEH_plugin->free_coin_transaction_list (TEH_plugin->cls,
tl);
return TEH_RESPONSE_reply_refund_failure (connection,
- MHD_HTTP_GONE);
+ MHD_HTTP_GONE,
+ TALER_EC_REFUND_MERCHANT_ALREADY_PAID);
}
/* check refund amount is sufficiently low */
@@ -487,7 +499,8 @@ TEH_DB_execute_refund (struct MHD_Connection *connection,
TEH_plugin->free_coin_transaction_list (TEH_plugin->cls,
tl);
return TEH_RESPONSE_reply_refund_failure (connection,
- MHD_HTTP_PRECONDITION_FAILED);
+ MHD_HTTP_PRECONDITION_FAILED,
+ TALER_EC_REFUND_INSUFFICIENT_FUNDS);
}
/* Check refund fee matches fee of denomination key! */
@@ -504,6 +517,7 @@ TEH_DB_execute_refund (struct MHD_Connection *connection,
TEH_plugin->free_coin_transaction_list (TEH_plugin->cls,
tl);
return TEH_RESPONSE_reply_internal_error (connection,
+ TALER_EC_REFUND_DENOMINATION_KEY_NOT_FOUND,
"denomination key not found");
}
TALER_amount_ntoh (&expect_fee,
@@ -519,6 +533,7 @@ TEH_DB_execute_refund (struct MHD_Connection *connection,
TEH_plugin->free_coin_transaction_list (TEH_plugin->cls,
tl);
return TEH_RESPONSE_reply_arg_invalid (connection,
+ TALER_EC_REFUND_FEE_TOO_LOW,
"refund_fee");
}
if (1 == fee_cmp)
@@ -538,7 +553,8 @@ TEH_DB_execute_refund (struct MHD_Connection *connection,
TALER_LOG_WARNING ("Failed to store /refund information in database\n");
TEH_plugin->rollback (TEH_plugin->cls,
session);
- return TEH_RESPONSE_reply_internal_db_error (connection);
+ return TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_REFUND_STORE_DB_ERROR);
}
COMMIT_TRANSACTION(session, connection);
@@ -566,7 +582,8 @@ TEH_DB_execute_reserve_status (struct MHD_Connection *connection,
if (NULL == (session = TEH_plugin->get_session (TEH_plugin->cls)))
{
GNUNET_break (0);
- return TEH_RESPONSE_reply_internal_db_error (connection);
+ return TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_DB_SETUP_FAILED);
}
rh = TEH_plugin->get_reserve_history (TEH_plugin->cls,
session,
@@ -637,6 +654,7 @@ execute_reserve_withdraw_transaction (struct MHD_Connection *connection,
TEH_plugin->rollback (TEH_plugin->cls,
session);
return TEH_RESPONSE_reply_arg_unknown (connection,
+ TALER_EC_WITHDRAW_RESERVE_UNKNOWN,
"reserve_pub");
}
@@ -653,7 +671,8 @@ execute_reserve_withdraw_transaction (struct MHD_Connection *connection,
{
TEH_plugin->rollback (TEH_plugin->cls,
session);
- return TEH_RESPONSE_reply_internal_db_error (connection);
+ return TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_WITHDRAW_AMOUNT_FEE_OVERFLOW);
}
/* calculate balance of the reserve */
@@ -673,7 +692,8 @@ execute_reserve_withdraw_transaction (struct MHD_Connection *connection,
{
TEH_plugin->rollback (TEH_plugin->cls,
session);
- return TEH_RESPONSE_reply_internal_db_error (connection);
+ return TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_WITHDRAW_AMOUNT_DEPOSITS_OVERFLOW);
}
res |= 1;
break;
@@ -686,7 +706,8 @@ execute_reserve_withdraw_transaction (struct MHD_Connection *connection,
GNUNET_break (0);
TEH_plugin->rollback (TEH_plugin->cls,
session);
- return TEH_RESPONSE_reply_internal_db_error (connection);
+ return TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_WITHDRAW_HISTORIC_DENOMINATION_KEY_NOT_FOUND);
}
TALER_amount_ntoh (&value,
&tdki->issue.properties.value);
@@ -700,7 +721,8 @@ execute_reserve_withdraw_transaction (struct MHD_Connection *connection,
{
TEH_plugin->rollback (TEH_plugin->cls,
session);
- return TEH_RESPONSE_reply_internal_db_error (connection);
+ return TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_WITHDRAW_AMOUNT_WITHDRAWALS_OVERFLOW);
}
res |= 2;
break;
@@ -708,9 +730,10 @@ execute_reserve_withdraw_transaction (struct MHD_Connection *connection,
}
if (0 == (res & 1))
{
- /* did not encounter any deposit operations, how can we have a reserve? */
+ /* did not encounter any wire transfer operations, how can we have a reserve? */
GNUNET_break (0);
- return TEH_RESPONSE_reply_internal_db_error (connection);
+ return TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_WITHDRAW_RESERVE_WITHOUT_WIRE_TRANSFER);
}
if (0 == (res & 2))
{
@@ -748,6 +771,7 @@ execute_reserve_withdraw_transaction (struct MHD_Connection *connection,
TEH_plugin->rollback (TEH_plugin->cls,
session);
return TEH_RESPONSE_reply_internal_error (connection,
+ TALER_EC_WITHDRAW_SIGNATURE_FAILED,
"Internal error");
}
collectable.sig = *denom_sig;
@@ -765,7 +789,8 @@ execute_reserve_withdraw_transaction (struct MHD_Connection *connection,
GNUNET_break (0);
TEH_plugin->rollback (TEH_plugin->cls,
session);
- return TEH_RESPONSE_reply_internal_db_error (connection);
+ return TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_WITHDRAW_DB_STORE_ERROR);
}
COMMIT_TRANSACTION (session, connection);
@@ -811,7 +836,8 @@ TEH_DB_execute_reserve_withdraw (struct MHD_Connection *connection,
if (NULL == (session = TEH_plugin->get_session (TEH_plugin->cls)))
{
GNUNET_break (0);
- return TEH_RESPONSE_reply_internal_db_error (connection);
+ return TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_DB_SETUP_FAILED);
}
res = TEH_plugin->get_withdraw_info (TEH_plugin->cls,
session,
@@ -820,7 +846,8 @@ TEH_DB_execute_reserve_withdraw (struct MHD_Connection *connection,
if (GNUNET_SYSERR == res)
{
GNUNET_break (0);
- return TEH_RESPONSE_reply_internal_db_error (connection);
+ return TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_WITHDRAW_DB_FETCH_ERROR);
}
/* Don't sign again if we have already signed the coin */
@@ -834,6 +861,7 @@ TEH_DB_execute_reserve_withdraw (struct MHD_Connection *connection,
}
GNUNET_assert (GNUNET_NO == res);
+ /* FIXME: do we have to do this a second time here? */
key_state = TEH_KS_acquire ();
dki = TEH_KS_denomination_key_lookup (key_state,
denomination_pub,
@@ -843,9 +871,11 @@ TEH_DB_execute_reserve_withdraw (struct MHD_Connection *connection,
TEH_KS_release (key_state);
return TEH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_NOT_FOUND,
- "{s:s}",
+ "{s:s, s:I}",
"error",
- "Denomination not found");
+ "Denomination not found",
+ "code",
+ (json_int_t) TALER_EC_WITHDRAW_DENOMINATION_KEY_NOT_FOUND);
}
denom_sig.rsa_signature = NULL;
res = execute_reserve_withdraw_transaction (connection,
@@ -901,8 +931,9 @@ refresh_check_melt (struct MHD_Connection *connection,
TEH_KS_DKU_DEPOSIT);
if (NULL == dk)
return (MHD_YES ==
- TEH_RESPONSE_reply_arg_unknown (connection,
- "denom_pub"))
+ TEH_RESPONSE_reply_internal_error (connection,
+ TALER_EC_REFRESH_MELT_DB_DENOMINATION_KEY_NOT_FOUND,
+ "denomination key no longer available while executing transaction"))
? GNUNET_NO : GNUNET_SYSERR;
dki = &dk->issue;
TALER_amount_ntoh (&coin_value,
@@ -922,7 +953,8 @@ refresh_check_melt (struct MHD_Connection *connection,
TEH_plugin->free_coin_transaction_list (TEH_plugin->cls,
tl);
return (MHD_YES ==
- TEH_RESPONSE_reply_internal_db_error (connection))
+ TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_REFRESH_MELT_COIN_HISTORY_COMPUTATION_FAILED))
? GNUNET_NO : GNUNET_SYSERR;
}
/* Refuse to refresh when the coin's value is insufficient
@@ -995,7 +1027,8 @@ TEH_DB_execute_refresh_melt (struct MHD_Connection *connection,
if (NULL == (session = TEH_plugin->get_session (TEH_plugin->cls)))
{
GNUNET_break (0);
- return TEH_RESPONSE_reply_internal_db_error (connection);
+ return TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_DB_SETUP_FAILED);
}
START_TRANSACTION (session, connection);
res = TEH_plugin->get_refresh_session (TEH_plugin->cls,
@@ -1015,14 +1048,15 @@ TEH_DB_execute_refresh_melt (struct MHD_Connection *connection,
{
TEH_plugin->rollback (TEH_plugin->cls,
session);
- return TEH_RESPONSE_reply_internal_db_error (connection);
+ return TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_REFRESH_MELT_DB_FETCH_ERROR);
}
/* store 'global' session data */
refresh_session.num_newcoins = num_new_denoms;
refresh_session.noreveal_index
- = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_STRONG,
- TALER_CNC_KAPPA);
+ = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_STRONG,
+ TALER_CNC_KAPPA);
key_state = TEH_KS_acquire ();
if (GNUNET_OK !=
(res = refresh_check_melt (connection,
@@ -1047,7 +1081,8 @@ TEH_DB_execute_refresh_melt (struct MHD_Connection *connection,
{
TEH_plugin->rollback (TEH_plugin->cls,
session);
- return TEH_RESPONSE_reply_internal_db_error (connection);
+ return TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_REFRESH_MELT_DB_STORE_SESSION_ERROR);
}
/* store requested new denominations */
@@ -1060,7 +1095,8 @@ TEH_DB_execute_refresh_melt (struct MHD_Connection *connection,
{
TEH_plugin->rollback (TEH_plugin->cls,
session);
- return TEH_RESPONSE_reply_internal_db_error (connection);
+ return TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_REFRESH_MELT_DB_STORE_ORDER_ERROR);
}
if (GNUNET_OK !=
@@ -1072,7 +1108,8 @@ TEH_DB_execute_refresh_melt (struct MHD_Connection *connection,
{
TEH_plugin->rollback (TEH_plugin->cls,
session);
- return TEH_RESPONSE_reply_internal_db_error (connection);
+ return TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_REFRESH_MELT_DB_STORE_ORDER_ERROR);
}
if (GNUNET_OK !=
TEH_plugin->insert_refresh_transfer_public_key (TEH_plugin->cls,
@@ -1082,7 +1119,8 @@ TEH_DB_execute_refresh_melt (struct MHD_Connection *connection,
{
TEH_plugin->rollback (TEH_plugin->cls,
session);
- return TEH_RESPONSE_reply_internal_db_error (connection);
+ return TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_REFRESH_MELT_DB_STORE_TRANSFER_ERROR);
}
COMMIT_TRANSACTION (session, connection);
@@ -1126,8 +1164,6 @@ check_commitment (struct MHD_Connection *connection,
struct TALER_TransferSecretP transfer_secret;
unsigned int j;
- /* FIXME: instead of consulting DB, reconstruct everything
- from transfer_priv here! */
TALER_link_reveal_transfer_secret (transfer_priv,
&melt->coin.coin_pub,
&transfer_secret);
@@ -1158,8 +1194,10 @@ check_commitment (struct MHD_Connection *connection,
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Blind failed (bad denomination key!?)\n");
- return (MHD_YES == TEH_RESPONSE_reply_internal_error (connection,
- "Blinding error"))
+ return (MHD_YES ==
+ TEH_RESPONSE_reply_internal_error (connection,
+ TALER_EC_REFRESH_REVEAL_BLINDING_ERROR,
+ "Blinding error"))
? GNUNET_NO : GNUNET_SYSERR;
}
GNUNET_CRYPTO_hash_context_read (hash_context,
@@ -1274,7 +1312,8 @@ execute_refresh_reveal_transaction (struct MHD_Connection *connection,
j);
if (NULL == ev_sigs[j].rsa_signature)
{
- ret = TEH_RESPONSE_reply_internal_db_error (connection);
+ ret = TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_REFRESH_REVEAL_SIGNING_ERROR);
goto cleanup;
}
}
@@ -1323,7 +1362,8 @@ TEH_DB_execute_refresh_reveal (struct MHD_Connection *connection,
if (NULL == (session = TEH_plugin->get_session (TEH_plugin->cls)))
{
GNUNET_break (0);
- return TEH_RESPONSE_reply_internal_db_error (connection);
+ return TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_DB_SETUP_FAILED);
}
res = TEH_plugin->get_refresh_session (TEH_plugin->cls,
@@ -1332,10 +1372,12 @@ TEH_DB_execute_refresh_reveal (struct MHD_Connection *connection,
&refresh_session);
if (GNUNET_NO == res)
return TEH_RESPONSE_reply_arg_invalid (connection,
+ TALER_EC_REFRESH_REVEAL_SESSION_UNKNOWN,
"session_hash");
if ( (GNUNET_SYSERR == res) ||
(refresh_session.noreveal_index >= TALER_CNC_KAPPA) )
- return TEH_RESPONSE_reply_internal_db_error (connection);
+ return TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_REFRESH_REVEAL_DB_FETCH_SESSION_ERROR);
denom_pubs = GNUNET_new_array (refresh_session.num_newcoins,
struct TALER_DenominationPublicKey);
if (GNUNET_OK !=
@@ -1349,7 +1391,8 @@ TEH_DB_execute_refresh_reveal (struct MHD_Connection *connection,
GNUNET_free (denom_pubs);
GNUNET_CRYPTO_rsa_signature_free (refresh_session.melt.coin.denom_sig.rsa_signature);
GNUNET_CRYPTO_rsa_public_key_free (refresh_session.melt.coin.denom_pub.rsa_public_key);
- return (MHD_YES == TEH_RESPONSE_reply_internal_db_error (connection))
+ return (MHD_YES == TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_REFRESH_REVEAL_DB_FETCH_ORDER_ERROR))
? GNUNET_NO : GNUNET_SYSERR;
}
@@ -1373,7 +1416,8 @@ TEH_DB_execute_refresh_reveal (struct MHD_Connection *connection,
GNUNET_CRYPTO_rsa_signature_free (refresh_session.melt.coin.denom_sig.rsa_signature);
GNUNET_CRYPTO_rsa_public_key_free (refresh_session.melt.coin.denom_pub.rsa_public_key);
GNUNET_CRYPTO_hash_context_abort (hash_context);
- return (MHD_YES == TEH_RESPONSE_reply_internal_db_error (connection))
+ return (MHD_YES == TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_REFRESH_REVEAL_DB_FETCH_TRANSFER_ERROR))
? GNUNET_NO : GNUNET_SYSERR;
}
GNUNET_CRYPTO_hash_context_read (hash_context,
@@ -1410,7 +1454,8 @@ TEH_DB_execute_refresh_reveal (struct MHD_Connection *connection,
GNUNET_CRYPTO_rsa_signature_free (refresh_session.melt.coin.denom_sig.rsa_signature);
GNUNET_CRYPTO_rsa_public_key_free (refresh_session.melt.coin.denom_pub.rsa_public_key);
GNUNET_CRYPTO_hash_context_abort (hash_context);
- return (MHD_YES == TEH_RESPONSE_reply_internal_db_error (connection))
+ return (MHD_YES == TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_REFRESH_REVEAL_DB_FETCH_ORDER_ERROR))
? GNUNET_NO : GNUNET_SYSERR;
}
for (i=0;i<refresh_session.num_newcoins;i++)
@@ -1463,7 +1508,8 @@ TEH_DB_execute_refresh_reveal (struct MHD_Connection *connection,
GNUNET_CRYPTO_rsa_signature_free (refresh_session.melt.coin.denom_sig.rsa_signature);
GNUNET_CRYPTO_rsa_public_key_free (refresh_session.melt.coin.denom_pub.rsa_public_key);
GNUNET_CRYPTO_hash_context_abort (hash_context);
- return TEH_RESPONSE_reply_internal_db_error (connection);
+ return TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_REFRESH_REVEAL_DB_FETCH_COMMIT_ERROR);
}
/* add envelopes to hash_context */
for (j=0;j<refresh_session.num_newcoins;j++)
@@ -1656,7 +1702,8 @@ TEH_DB_execute_refresh_link (struct MHD_Connection *connection,
if (NULL == (ctx.session = TEH_plugin->get_session (TEH_plugin->cls)))
{
GNUNET_break (0);
- return TEH_RESPONSE_reply_internal_db_error (connection);
+ return TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_DB_SETUP_FAILED);
}
ctx.connection = connection;
ctx.num_sessions = 0;
@@ -1680,6 +1727,7 @@ TEH_DB_execute_refresh_link (struct MHD_Connection *connection,
GNUNET_assert (GNUNET_OK == ctx.status);
if (0 == ctx.num_sessions)
return TEH_RESPONSE_reply_arg_unknown (connection,
+ TALER_EC_REFRESH_LINK_COIN_UNKNOWN,
"coin_pub");
res = TEH_RESPONSE_reply_refresh_link_success (connection,
ctx.num_sessions,
@@ -1720,7 +1768,8 @@ TEH_DB_execute_admin_add_incoming (struct MHD_Connection *connection,
if (NULL == (session = TEH_plugin->get_session (TEH_plugin->cls)))
{
GNUNET_break (0);
- return TEH_RESPONSE_reply_internal_db_error (connection);
+ return TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_DB_SETUP_FAILED);
}
ret = TEH_plugin->reserves_in_insert (TEH_plugin->cls,
session,
@@ -1732,7 +1781,8 @@ TEH_DB_execute_admin_add_incoming (struct MHD_Connection *connection,
if (GNUNET_SYSERR == ret)
{
GNUNET_break (0);
- return TEH_RESPONSE_reply_internal_db_error (connection);
+ return TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_ADMIN_ADD_INCOMING_DB_STORE);
}
return TEH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_OK,
@@ -1913,7 +1963,8 @@ TEH_DB_execute_track_transfer (struct MHD_Connection *connection,
if (NULL == (session = TEH_plugin->get_session (TEH_plugin->cls)))
{
GNUNET_break (0);
- return TEH_RESPONSE_reply_internal_db_error (connection);
+ return TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_DB_SETUP_FAILED);
}
ctx.is_valid = GNUNET_NO;
ctx.wdd_head = NULL;
@@ -1926,18 +1977,21 @@ TEH_DB_execute_track_transfer (struct MHD_Connection *connection,
if (GNUNET_SYSERR == ret)
{
GNUNET_break (0);
- ret = TEH_RESPONSE_reply_internal_db_error (connection);
+ ret = TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_TRACK_TRANSFER_DB_FETCH_FAILED);
goto cleanup;
}
if (GNUNET_SYSERR == ctx.is_valid)
{
GNUNET_break (0);
- ret = TEH_RESPONSE_reply_internal_db_error (connection);
+ ret = TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_TRACK_TRANSFER_DB_INCONSISTENT);
goto cleanup;
}
if (GNUNET_NO == ctx.is_valid)
{
ret = TEH_RESPONSE_reply_arg_unknown (connection,
+ TALER_EC_TRACK_TRANSFER_WTID_NOT_FOUND,
"wtid");
goto cleanup;
}
@@ -2035,7 +2089,8 @@ handle_wtid_data (void *cls,
coin_fee))
{
GNUNET_break (0);
- ctx->res = TEH_RESPONSE_reply_internal_db_error (ctx->connection);
+ ctx->res = TEH_RESPONSE_reply_internal_db_error (ctx->connection,
+ TALER_EC_TRACK_TRANSACTION_DB_FEE_INCONSISTENT);
}
else
{
@@ -2079,7 +2134,8 @@ TEH_DB_execute_track_transaction (struct MHD_Connection *connection,
if (NULL == (session = TEH_plugin->get_session (TEH_plugin->cls)))
{
GNUNET_break (0);
- return TEH_RESPONSE_reply_internal_db_error (connection);
+ return TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_DB_SETUP_FAILED);
}
ctx.connection = connection;
ctx.h_contract = *h_contract;
@@ -2100,17 +2156,20 @@ TEH_DB_execute_track_transaction (struct MHD_Connection *connection,
{
GNUNET_break (0);
GNUNET_break (GNUNET_SYSERR == ctx.res);
- return TEH_RESPONSE_reply_internal_db_error (connection);
+ return TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_TRACK_TRANSACTION_DB_FETCH_FAILED);
}
if (GNUNET_NO == ret)
{
GNUNET_break (GNUNET_SYSERR == ctx.res);
- return TEH_RESPONSE_reply_transaction_unknown (connection);
+ return TEH_RESPONSE_reply_transaction_unknown (connection,
+ TALER_EC_TRACK_TRANSACTION_NOT_FOUND);
}
if (GNUNET_SYSERR == ctx.res)
{
GNUNET_break (0);
return TEH_RESPONSE_reply_internal_error (connection,
+ TALER_EC_TRACK_TRANSACTION_WTID_RESOLUTION_ERROR,
"bug resolving deposit wtid");
}
return ctx.res;
diff --git a/src/exchange/taler-exchange-httpd_deposit.c b/src/exchange/taler-exchange-httpd_deposit.c
index a97dd0514..b0ab42e7f 100644
--- a/src/exchange/taler-exchange-httpd_deposit.c
+++ b/src/exchange/taler-exchange-httpd_deposit.c
@@ -48,12 +48,9 @@
*/
static int
verify_and_execute_deposit (struct MHD_Connection *connection,
- const struct TALER_EXCHANGEDB_Deposit *deposit)
+ const struct TALER_EXCHANGEDB_Deposit *deposit)
{
- struct TEH_KS_StateHandle *key_state;
struct TALER_DepositRequestPS dr;
- struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki;
- struct TALER_Amount fee_deposit;
dr.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_DEPOSIT);
dr.purpose.size = htonl (sizeof (struct TALER_DepositRequestPS));
@@ -76,39 +73,9 @@ verify_and_execute_deposit (struct MHD_Connection *connection,
{
TALER_LOG_WARNING ("Invalid signature on /deposit request\n");
return TEH_RESPONSE_reply_signature_invalid (connection,
+ TALER_EC_DEPOSIT_COIN_SIGNATURE_INVALID,
"coin_sig");
}
- /* check denomination exists and is valid */
- key_state = TEH_KS_acquire ();
- dki = TEH_KS_denomination_key_lookup (key_state,
- &deposit->coin.denom_pub,
- TEH_KS_DKU_DEPOSIT);
- if (NULL == dki)
- {
- TEH_KS_release (key_state);
- TALER_LOG_WARNING ("Unknown denomination key in /deposit request\n");
- return TEH_RESPONSE_reply_arg_unknown (connection,
- "denom_pub");
- }
- /* check coin signature */
- if (GNUNET_YES !=
- TALER_test_coin_valid (&deposit->coin))
- {
- TALER_LOG_WARNING ("Invalid coin passed for /deposit\n");
- TEH_KS_release (key_state);
- return TEH_RESPONSE_reply_signature_invalid (connection,
- "ub_sig");
- }
- TALER_amount_ntoh (&fee_deposit,
- &dki->issue.properties.fee_deposit);
- if (0 < TALER_amount_cmp (&fee_deposit,
- &deposit->amount_with_fee))
- {
- TEH_KS_release (key_state);
- return TEH_RESPONSE_reply_external_error (connection,
- "deposited amount smaller than depositing fee");
- }
- TEH_KS_release (key_state);
return TEH_DB_execute_deposit (connection,
deposit);
@@ -141,12 +108,11 @@ TEH_DEPOSIT_handler_deposit (struct TEH_RequestHandler *rh,
json_t *wire;
struct TALER_EXCHANGEDB_Deposit deposit;
struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki;
- struct TEH_KS_StateHandle *ks;
+ struct TEH_KS_StateHandle *key_state;
struct GNUNET_HashCode my_h_wire;
- struct TALER_Amount amount;
struct GNUNET_JSON_Specification spec[] = {
GNUNET_JSON_spec_json ("wire", &wire),
- TALER_JSON_spec_amount ("f", &amount),
+ TALER_JSON_spec_amount ("f", &deposit.amount_with_fee),
TALER_JSON_spec_denomination_public_key ("denom_pub", &deposit.coin.denom_pub),
TALER_JSON_spec_denomination_signature ("ub_sig", &deposit.coin.denom_sig),
GNUNET_JSON_spec_fixed_auto ("coin_pub", &deposit.coin.coin_pub),
@@ -180,11 +146,13 @@ TEH_DEPOSIT_handler_deposit (struct TEH_RequestHandler *rh,
if (GNUNET_NO == res)
return MHD_YES; /* failure */
+ deposit.receiver_wire_account = wire;
if (deposit.refund_deadline.abs_value_us > deposit.wire_deadline.abs_value_us)
{
GNUNET_break_op (0);
GNUNET_JSON_parse_free (spec);
return TEH_RESPONSE_reply_arg_invalid (connection,
+ TALER_EC_DEPOSIT_REFUND_DEADLINE_AFTER_WIRE_DEADLINE,
"refund_deadline");
}
@@ -194,6 +162,7 @@ TEH_DEPOSIT_handler_deposit (struct TEH_RequestHandler *rh,
{
GNUNET_JSON_parse_free (spec);
return TEH_RESPONSE_reply_arg_unknown (connection,
+ TALER_EC_DEPOSIT_INVALID_WIRE_FORMAT,
"wire");
}
if (GNUNET_OK !=
@@ -203,6 +172,7 @@ TEH_DEPOSIT_handler_deposit (struct TEH_RequestHandler *rh,
TALER_LOG_WARNING ("Failed to parse JSON wire format specification for /deposit request\n");
GNUNET_JSON_parse_free (spec);
return TEH_RESPONSE_reply_arg_invalid (connection,
+ TALER_EC_DEPOSIT_INVALID_WIRE_FORMAT_JSON,
"wire");
}
if (0 != memcmp (&deposit.h_wire,
@@ -212,32 +182,48 @@ TEH_DEPOSIT_handler_deposit (struct TEH_RequestHandler *rh,
/* Client hashed contract differently than we did, reject */
GNUNET_JSON_parse_free (spec);
return TEH_RESPONSE_reply_arg_invalid (connection,
+ TALER_EC_DEPOSIT_INVALID_WIRE_FORMAT_CONTRACT_HASH_CONFLICT,
"H_wire");
}
- ks = TEH_KS_acquire ();
- dki = TEH_KS_denomination_key_lookup (ks,
+
+ /* check denomination exists and is valid */
+ key_state = TEH_KS_acquire ();
+ dki = TEH_KS_denomination_key_lookup (key_state,
&deposit.coin.denom_pub,
TEH_KS_DKU_DEPOSIT);
if (NULL == dki)
{
- TEH_KS_release (ks);
- GNUNET_JSON_parse_free (spec);
+ TEH_KS_release (key_state);
+ TALER_LOG_WARNING ("Unknown denomination key in /deposit request\n");
return TEH_RESPONSE_reply_arg_unknown (connection,
+ TALER_EC_DEPOSIT_DENOMINATION_KEY_UNKNOWN,
"denom_pub");
}
TALER_amount_ntoh (&deposit.deposit_fee,
&dki->issue.properties.fee_deposit);
- TEH_KS_release (ks);
- deposit.receiver_wire_account = wire;
- deposit.amount_with_fee = amount;
- if (-1 == TALER_amount_cmp (&deposit.amount_with_fee,
- &deposit.deposit_fee))
+ /* check coin signature */
+ if (GNUNET_YES !=
+ TALER_test_coin_valid (&deposit.coin))
{
- /* Total amount smaller than fee, invalid */
- GNUNET_JSON_parse_free (spec);
- return TEH_RESPONSE_reply_arg_invalid (connection,
- "f");
+ TALER_LOG_WARNING ("Invalid coin passed for /deposit\n");
+ TEH_KS_release (key_state);
+ return TEH_RESPONSE_reply_signature_invalid (connection,
+ TALER_EC_DEPOSIT_DENOMINATION_SIGNATURE_INVALID,
+ "ub_sig");
+ }
+ TALER_amount_ntoh (&deposit.deposit_fee,
+ &dki->issue.properties.fee_deposit);
+ TEH_KS_release (key_state);
+
+ if (0 < TALER_amount_cmp (&deposit.deposit_fee,
+ &deposit.amount_with_fee))
+ {
+ GNUNET_break_op (0);
+ return TEH_RESPONSE_reply_external_error (connection,
+ TALER_EC_DEPOSIT_NEGATIVE_VALUE_AFTER_FEE,
+ "deposited amount smaller than depositing fee");
}
+
res = verify_and_execute_deposit (connection,
&deposit);
GNUNET_JSON_parse_free (spec);
diff --git a/src/exchange/taler-exchange-httpd_parsing.c b/src/exchange/taler-exchange-httpd_parsing.c
index c7118c462..e9c38eb82 100644
--- a/src/exchange/taler-exchange-httpd_parsing.c
+++ b/src/exchange/taler-exchange-httpd_parsing.c
@@ -79,6 +79,7 @@ TEH_PARSE_post_json (struct MHD_Connection *connection,
case GNUNET_JSON_PR_OUT_OF_MEMORY:
return (MHD_NO ==
TEH_RESPONSE_reply_internal_error (connection,
+ TALER_EC_PARSER_OUT_OF_MEMORY,
"out of memory"))
? GNUNET_SYSERR : GNUNET_NO;
case GNUNET_JSON_PR_CONTINUE:
@@ -144,7 +145,9 @@ TEH_PARSE_mhd_request_arg_data (struct MHD_Connection *connection,
if (NULL == str)
{
return (MHD_NO ==
- TEH_RESPONSE_reply_arg_missing (connection, param_name))
+ TEH_RESPONSE_reply_arg_missing (connection,
+ TALER_EC_PARAMETER_MISSING,
+ param_name))
? GNUNET_SYSERR : GNUNET_NO;
}
if (GNUNET_OK !=
@@ -153,7 +156,9 @@ TEH_PARSE_mhd_request_arg_data (struct MHD_Connection *connection,
out_data,
out_size))
return (MHD_NO ==
- TEH_RESPONSE_reply_arg_invalid (connection, param_name))
+ TEH_RESPONSE_reply_arg_invalid (connection,
+ TALER_EC_PARAMETER_MALFORMED,
+ param_name))
? GNUNET_SYSERR : GNUNET_NO;
return GNUNET_OK;
}
@@ -193,8 +198,9 @@ TEH_PARSE_json_data (struct MHD_Connection *connection,
ret = (MHD_YES ==
TEH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_BAD_REQUEST,
- "{s:s, s:s, s:I}",
+ "{s:s, s:I, s:s, s:I}",
"error", "parse error",
+ "code", (json_int_t) TALER_EC_JSON_INVALID_WITH_DETAILS,
"field", error_json_name,
"line", (json_int_t) error_line))
? GNUNET_NO : GNUNET_SYSERR;
diff --git a/src/exchange/taler-exchange-httpd_refresh.c b/src/exchange/taler-exchange-httpd_refresh.c
index 0c500920d..3a8875f44 100644
--- a/src/exchange/taler-exchange-httpd_refresh.c
+++ b/src/exchange/taler-exchange-httpd_refresh.c
@@ -69,7 +69,7 @@ handle_refresh_melt_binary (struct MHD_Connection *connection,
struct TALER_Amount total_melt;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "melt request for session %s\n",
+ "/refresh/melt request for session %s\n",
GNUNET_h2s (session_hash));
GNUNET_assert (GNUNET_OK ==
@@ -86,6 +86,7 @@ handle_refresh_melt_binary (struct MHD_Connection *connection,
GNUNET_break_op (0);
TEH_KS_release (key_state);
return TEH_RESPONSE_reply_arg_invalid (connection,
+ TALER_EC_REFRESH_MELT_FRESH_DENOMINATION_KEY_NOT_FOUND,
"new_denoms");
}
dki = &dk->issue;
@@ -105,6 +106,7 @@ handle_refresh_melt_binary (struct MHD_Connection *connection,
GNUNET_break_op (0);
TEH_KS_release (key_state);
return TEH_RESPONSE_reply_internal_error (connection,
+ TALER_EC_REFRESH_MELT_COST_CALCULATION_OVERFLOW,
"cost calculation failure");
}
}
@@ -115,8 +117,9 @@ handle_refresh_melt_binary (struct MHD_Connection *connection,
if (NULL == dk)
{
GNUNET_break (0);
- return TEH_RESPONSE_reply_arg_invalid (connection,
- "denom_pub");
+ return TEH_RESPONSE_reply_arg_unknown (connection,
+ TALER_EC_REFRESH_MELT_DENOMINATION_KEY_NOT_FOUND,
+ "denom_pub");
}
dki = &dk->issue;
TALER_amount_ntoh (&fee_melt,
@@ -129,6 +132,7 @@ handle_refresh_melt_binary (struct MHD_Connection *connection,
GNUNET_break_op (0);
TEH_KS_release (key_state);
return TEH_RESPONSE_reply_external_error (connection,
+ TALER_EC_REFRESH_MELT_FEES_EXCEED_CONTRIBUTION,
"Melt contribution below melting fee");
}
TEH_KS_release (key_state);
@@ -141,8 +145,9 @@ handle_refresh_melt_binary (struct MHD_Connection *connection,
total value of coins being generated to match! */
return TEH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_BAD_REQUEST,
- "{s:s}",
- "error", "value mismatch");
+ "{s:s, s:I}",
+ "error", "value mismatch",
+ "code", (json_int_t) TALER_EC_REFRESH_MELT_FEES_MISSMATCH);
}
return TEH_DB_execute_refresh_melt (connection,
session_hash,
@@ -203,6 +208,7 @@ get_coin_public_info (struct MHD_Connection *connection,
r_melt_detail->coin_info.denom_pub.rsa_public_key = NULL;
return (MHD_YES ==
TEH_RESPONSE_reply_signature_invalid (connection,
+ TALER_EC_REFRESH_MELT_DENOMINATION_SIGNATURE_INVALID,
"denom_sig"))
? GNUNET_NO : GNUNET_SYSERR;
}
@@ -237,6 +243,8 @@ verify_coin_public_info (struct MHD_Connection *connection,
struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki;
struct TALER_Amount fee_refresh;
+ /* FIXME: we lookup the dki twice during /refresh/melt.
+ This should be avoided. */
key_state = TEH_KS_acquire ();
dki = TEH_KS_denomination_key_lookup (key_state,
&melt_detail->coin_info.denom_pub,
@@ -246,6 +254,7 @@ verify_coin_public_info (struct MHD_Connection *connection,
TEH_KS_release (key_state);
TALER_LOG_WARNING ("Unknown denomination key in /refresh/melt request\n");
return TEH_RESPONSE_reply_arg_unknown (connection,
+ TALER_EC_REFRESH_MELT_DENOMINATION_KEY_NOT_FOUND,
"denom_pub");
}
TALER_amount_ntoh (&fee_refresh,
@@ -266,6 +275,7 @@ verify_coin_public_info (struct MHD_Connection *connection,
TEH_KS_release (key_state);
return (MHD_YES ==
TEH_RESPONSE_reply_external_error (connection,
+ TALER_EC_REFRESH_MELT_AMOUNT_INSUFFICIENT,
"melt amount smaller than melting fee"))
? GNUNET_NO : GNUNET_SYSERR;
}
@@ -280,6 +290,7 @@ verify_coin_public_info (struct MHD_Connection *connection,
GNUNET_break_op (0);
if (MHD_YES !=
TEH_RESPONSE_reply_signature_invalid (connection,
+ TALER_EC_REFRESH_MELT_COIN_SIGNATURE_INVALID,
"confirm_sig"))
return GNUNET_SYSERR;
return GNUNET_NO;
@@ -565,6 +576,7 @@ TEH_REFRESH_handler_refresh_melt (struct TEH_RequestHandler *rh,
GNUNET_break_op (0);
GNUNET_JSON_parse_free (spec);
return TEH_RESPONSE_reply_arg_invalid (connection,
+ TALER_EC_REFRESH_MELT_CNC_COIN_ARRAY_SIZE_INVALID,
"coin_evs");
}
if (TALER_CNC_KAPPA != json_array_size (transfer_pubs))
@@ -572,6 +584,7 @@ TEH_REFRESH_handler_refresh_melt (struct TEH_RequestHandler *rh,
GNUNET_break_op (0);
GNUNET_JSON_parse_free (spec);
return TEH_RESPONSE_reply_arg_invalid (connection,
+ TALER_EC_REFRESH_MELT_CNC_TRANSFER_ARRAY_SIZE_INVALID,
"transfer_pubs");
}
res = handle_refresh_melt_json (connection,
@@ -694,6 +707,7 @@ TEH_REFRESH_handler_refresh_reveal (struct TEH_RequestHandler *rh,
GNUNET_JSON_parse_free (spec);
GNUNET_break_op (0);
return TEH_RESPONSE_reply_arg_invalid (connection,
+ TALER_EC_REFRESH_REVEAL_CNC_TRANSFER_ARRAY_SIZE_INVALID,
"transfer_privs");
}
res = handle_refresh_reveal_json (connection,
diff --git a/src/exchange/taler-exchange-httpd_refund.c b/src/exchange/taler-exchange-httpd_refund.c
index fdb6f8b76..591bb188d 100644
--- a/src/exchange/taler-exchange-httpd_refund.c
+++ b/src/exchange/taler-exchange-httpd_refund.c
@@ -69,14 +69,16 @@ verify_and_execute_refund (struct MHD_Connection *connection,
{
GNUNET_break_op (0);
return TEH_RESPONSE_reply_arg_invalid (connection,
+ TALER_EC_REFUND_FEE_CURRENCY_MISSMATCH,
"refund_fee");
}
if (-1 == TALER_amount_cmp (&refund->refund_amount,
&refund->refund_fee) )
{
GNUNET_break_op (0);
- return TEH_RESPONSE_reply_signature_invalid (connection,
- "refund_amount");
+ return TEH_RESPONSE_reply_arg_invalid (connection,
+ TALER_EC_REFUND_FEE_ABOVE_AMOUNT,
+ "refund_amount");
}
if (GNUNET_OK !=
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MERCHANT_REFUND,
@@ -86,6 +88,7 @@ verify_and_execute_refund (struct MHD_Connection *connection,
{
TALER_LOG_WARNING ("Invalid signature on /refund request\n");
return TEH_RESPONSE_reply_signature_invalid (connection,
+ TALER_EC_REFUND_MERCHANT_SIGNATURE_INVALID,
"merchant_sig");
}
return TEH_DB_execute_refund (connection,
diff --git a/src/exchange/taler-exchange-httpd_reserve.c b/src/exchange/taler-exchange-httpd_reserve.c
index 7098e99a2..0abe37c5a 100644
--- a/src/exchange/taler-exchange-httpd_reserve.c
+++ b/src/exchange/taler-exchange-httpd_reserve.c
@@ -1,6 +1,6 @@
/*
This file is part of TALER
- Copyright (C) 2014,2015 GNUnet e.V.
+ Copyright (C) 2014, 2015, 2016 GNUnet e.V.
TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU Affero General Public License as published by the Free Software
@@ -138,6 +138,7 @@ TEH_RESERVE_handler_reserve_withdraw (struct TEH_RequestHandler *rh,
GNUNET_JSON_parse_free (spec);
TEH_KS_release (ks);
return TEH_RESPONSE_reply_arg_unknown (connection,
+ TALER_EC_WITHDRAW_DENOMINATION_KEY_NOT_FOUND,
"denom_pub");
}
TALER_amount_ntoh (&amount,
@@ -171,6 +172,7 @@ TEH_RESERVE_handler_reserve_withdraw (struct TEH_RequestHandler *rh,
TALER_LOG_WARNING ("Client supplied invalid signature for /reserve/withdraw request\n");
GNUNET_JSON_parse_free (spec);
return TEH_RESPONSE_reply_signature_invalid (connection,
+ TALER_EC_WITHDRAW_RESERVE_SIGNATURE_INVALID,
"reserve_sig");
}
res = TEH_DB_execute_reserve_withdraw (connection,
diff --git a/src/exchange/taler-exchange-httpd_responses.c b/src/exchange/taler-exchange-httpd_responses.c
index cacd933f1..b31f22e10 100644
--- a/src/exchange/taler-exchange-httpd_responses.c
+++ b/src/exchange/taler-exchange-httpd_responses.c
@@ -132,17 +132,20 @@ TEH_RESPONSE_reply_json_pack (struct MHD_Connection *connection,
* Send a response indicating an invalid argument.
*
* @param connection the MHD connection to use
+ * @param ec error code uniquely identifying the error
* @param param_name the parameter that is invalid
* @return a MHD result code
*/
int
TEH_RESPONSE_reply_arg_invalid (struct MHD_Connection *connection,
+ enum TALER_ErrorCode ec,
const char *param_name)
{
return TEH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_BAD_REQUEST,
- "{s:s, s:s}",
+ "{s:s, s:I, s:s}",
"error", "invalid parameter",
+ "code", (json_int_t) ec,
"parameter", param_name);
}
@@ -153,17 +156,20 @@ TEH_RESPONSE_reply_arg_invalid (struct MHD_Connection *connection,
* denomination key).
*
* @param connection the MHD connection to use
+ * @param ec error code uniquely identifying the error
* @param param_name the parameter that is invalid
* @return a MHD result code
*/
int
TEH_RESPONSE_reply_arg_unknown (struct MHD_Connection *connection,
+ enum TALER_ErrorCode ec,
const char *param_name)
{
return TEH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_NOT_FOUND,
- "{s:s, s:s}",
+ "{s:s, s:I, s:s}",
"error", "unknown entity referenced",
+ "code", (json_int_t) ec,
"parameter", param_name);
}
@@ -172,17 +178,20 @@ TEH_RESPONSE_reply_arg_unknown (struct MHD_Connection *connection,
* Send a response indicating an invalid signature.
*
* @param connection the MHD connection to use
+ * @param ec error code uniquely identifying the error
* @param param_name the parameter that is invalid
* @return a MHD result code
*/
int
TEH_RESPONSE_reply_signature_invalid (struct MHD_Connection *connection,
+ enum TALER_ErrorCode ec,
const char *param_name)
{
return TEH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_UNAUTHORIZED,
- "{s:s, s:s}",
+ "{s:s, s:I, s:s}",
"error", "invalid signature",
+ "code", (json_int_t) ec,
"parameter", param_name);
}
@@ -191,17 +200,20 @@ TEH_RESPONSE_reply_signature_invalid (struct MHD_Connection *connection,
* Send a response indicating a missing argument.
*
* @param connection the MHD connection to use
+ * @param ec error code uniquely identifying the error
* @param param_name the parameter that is missing
* @return a MHD result code
*/
int
TEH_RESPONSE_reply_arg_missing (struct MHD_Connection *connection,
+ enum TALER_ErrorCode ec,
const char *param_name)
{
return TEH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_BAD_REQUEST,
- "{ s:s, s:s}",
+ "{ s:s, s:I, s:s}",
"error", "missing parameter",
+ "code", (json_int_t) ec,
"parameter", param_name);
}
@@ -210,17 +222,20 @@ TEH_RESPONSE_reply_arg_missing (struct MHD_Connection *connection,
* Send a response indicating permission denied.
*
* @param connection the MHD connection to use
+ * @param ec error code uniquely identifying the error
* @param hint hint about why access was denied
* @return a MHD result code
*/
int
TEH_RESPONSE_reply_permission_denied (struct MHD_Connection *connection,
+ enum TALER_ErrorCode ec,
const char *hint)
{
return TEH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_FORBIDDEN,
- "{s:s, s:s}",
+ "{s:s, s:I, s:s}",
"error", "permission denied",
+ "code", (json_int_t) ec,
"hint", hint);
}
@@ -229,17 +244,20 @@ TEH_RESPONSE_reply_permission_denied (struct MHD_Connection *connection,
* Send a response indicating an internal error.
*
* @param connection the MHD connection to use
+ * @param ec error code uniquely identifying the error
* @param hint hint about the internal error's nature
* @return a MHD result code
*/
int
TEH_RESPONSE_reply_internal_error (struct MHD_Connection *connection,
+ enum TALER_ErrorCode ec,
const char *hint)
{
return TEH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_INTERNAL_SERVER_ERROR,
- "{s:s, s:s}",
+ "{s:s, s:I, s:s}",
"error", "internal error",
+ "code", (json_int_t) ec,
"hint", hint);
}
@@ -248,17 +266,20 @@ TEH_RESPONSE_reply_internal_error (struct MHD_Connection *connection,
* Send a response indicating an external error.
*
* @param connection the MHD connection to use
+ * @param ec error code uniquely identifying the error
* @param hint hint about the error's nature
* @return a MHD result code
*/
int
TEH_RESPONSE_reply_external_error (struct MHD_Connection *connection,
+ enum TALER_ErrorCode ec,
const char *hint)
{
return TEH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_BAD_REQUEST,
- "{s:s, s:s}",
+ "{s:s, s:I, s:s}",
"error", "client error",
+ "code", (json_int_t) ec,
"hint", hint);
}
@@ -268,15 +289,18 @@ TEH_RESPONSE_reply_external_error (struct MHD_Connection *connection,
* transaction (concurrent interference).
*
* @param connection the MHD connection to use
+ * @param ec error code uniquely identifying the error
* @return a MHD result code
*/
int
-TEH_RESPONSE_reply_commit_error (struct MHD_Connection *connection)
+TEH_RESPONSE_reply_commit_error (struct MHD_Connection *connection,
+ enum TALER_ErrorCode ec)
{
return TEH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_BAD_REQUEST,
- "{s:s}",
- "error", "commit failure");
+ "{s:s, s:I}",
+ "error", "commit failure",
+ "code", (json_int_t) ec);
}
@@ -285,12 +309,15 @@ TEH_RESPONSE_reply_commit_error (struct MHD_Connection *connection)
* database.
*
* @param connection the MHD connection to use
+ * @param ec error code uniquely identifying the error
* @return a MHD result code
*/
int
-TEH_RESPONSE_reply_internal_db_error (struct MHD_Connection *connection)
+TEH_RESPONSE_reply_internal_db_error (struct MHD_Connection *connection,
+ enum TALER_ErrorCode ec)
{
return TEH_RESPONSE_reply_internal_error (connection,
+ ec,
"Failed to connect to database");
}
@@ -332,9 +359,9 @@ TEH_RESPONSE_reply_invalid_json (struct MHD_Connection *connection)
{
return TEH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_BAD_REQUEST,
- "{s:s}",
- "error",
- "invalid json");
+ "{s:s, s:I}",
+ "error", "invalid json",
+ "code", (json_int_t) TALER_EC_JSON_INVALID);
}
@@ -556,11 +583,13 @@ TEH_RESPONSE_reply_deposit_insufficient_funds (struct MHD_Connection *connection
history = compile_transaction_history (tl);
if (NULL == history)
- return TEH_RESPONSE_reply_internal_db_error (connection);
+ return TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_DEPOSIT_HISTORY_DB_ERROR_INSUFFICIENT_FUNDS);
return TEH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_FORBIDDEN,
- "{s:s, s:o}",
+ "{s:s, s:I, s:o}",
"error", "insufficient funds",
+ "code", (json_int_t) TALER_EC_DEPOSIT_INSUFFICIENT_FUNDS,
"history", history);
}
@@ -696,8 +725,9 @@ TEH_RESPONSE_reply_refund_conflict (struct MHD_Connection *connection,
{
return TEH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_CONFLICT,
- "{s:s, s:o}",
+ "{s:s, s:I, s:o}",
"status", "conflicting refund",
+ "code", (json_int_t) TALER_EC_REFUND_CONFLICT,
"history", compile_transaction_history (tl));
}
@@ -708,17 +738,19 @@ TEH_RESPONSE_reply_refund_conflict (struct MHD_Connection *connection,
*
* @param connection connection to the client
* @param response_code response code to generate
+ * @param ec taler error code to include
* @return MHD result code
*/
int
TEH_RESPONSE_reply_refund_failure (struct MHD_Connection *connection,
- unsigned int response_code)
+ unsigned int response_code,
+ enum TALER_ErrorCode ec)
{
return TEH_RESPONSE_reply_json_pack (connection,
response_code,
- "{s:s}",
- "error",
- "no details");
+ "{s:s, s:I}",
+ "status", "refund failure",
+ "code", (json_int_t) ec);
}
@@ -779,6 +811,7 @@ TEH_RESPONSE_reply_reserve_status_success (struct MHD_Connection *connection,
&balance);
if (NULL == json_history)
return TEH_RESPONSE_reply_internal_error (connection,
+ TALER_EC_RESERVE_STATUS_DB_ERROR,
"balance calculation failure");
json_balance = TALER_JSON_from_amount (&balance);
return TEH_RESPONSE_reply_json_pack (connection,
@@ -810,12 +843,14 @@ TEH_RESPONSE_reply_reserve_withdraw_insufficient_funds (struct MHD_Connection *c
&balance);
if (NULL == json_history)
return TEH_RESPONSE_reply_internal_error (connection,
+ TALER_EC_WITHDRAW_HISTORY_DB_ERROR_INSUFFICIENT_FUNDS,
"balance calculation failure");
json_balance = TALER_JSON_from_amount (&balance);
return TEH_RESPONSE_reply_json_pack (connection,
- MHD_HTTP_PAYMENT_REQUIRED,
- "{s:s, s:o, s:o}",
+ MHD_HTTP_FORBIDDEN,
+ "{s:s, s:I, s:o, s:o}",
"error", "Insufficient funds",
+ "code", (json_int_t) TALER_EC_WITHDRAW_INSUFFICIENT_FUNDS,
"balance", json_balance,
"history", json_history);
}
@@ -830,7 +865,7 @@ TEH_RESPONSE_reply_reserve_withdraw_insufficient_funds (struct MHD_Connection *c
*/
int
TEH_RESPONSE_reply_reserve_withdraw_success (struct MHD_Connection *connection,
- const struct TALER_EXCHANGEDB_CollectableBlindcoin *collectable)
+ const struct TALER_EXCHANGEDB_CollectableBlindcoin *collectable)
{
json_t *sig_json;
@@ -869,12 +904,15 @@ TEH_RESPONSE_reply_refresh_melt_insufficient_funds (struct MHD_Connection *conne
history = compile_transaction_history (tl);
if (NULL == history)
- return TEH_RESPONSE_reply_internal_db_error (connection);
+ return TEH_RESPONSE_reply_internal_db_error (connection,
+ TALER_EC_REFRESH_MELT_HISTORY_DB_ERROR_INSUFFICIENT_FUNDS);
return TEH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_FORBIDDEN,
- "{s:s, s:o, s:o, s:o, s:o, s:o}",
+ "{s:s, s:I, s:o, s:o, s:o, s:o, s:o}",
"error",
- "insufficient funds",
+ "insufficient funds",
+ "code",
+ (json_int_t) TALER_EC_REFRESH_MELT_INSUFFICIENT_FUNDS,
"coin_pub",
GNUNET_JSON_from_data_auto (coin_pub),
"original_value",
@@ -1011,8 +1049,9 @@ TEH_RESPONSE_reply_refresh_reveal_missmatch (struct MHD_Connection *connection,
}
return TEH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_CONFLICT,
- "{s:s, s:o, s:o, s:o, s:o, s:o, s:o, s:o, s:i}",
+ "{s:s, s:I, s:o, s:o, s:o, s:o, s:o, s:o, s:o, s:i}",
"error", "commitment violation",
+ "code", (json_int_t) TALER_EC_REFRESH_REVEAL_COMMITMENT_VIOLATION,
"coin_sig", GNUNET_JSON_from_data_auto (&session->melt.coin_sig),
"coin_pub", GNUNET_JSON_from_data_auto (&session->melt.coin.coin_pub),
"melt_amount_with_fee", TALER_JSON_from_amount (&session->melt.amount_with_fee),
@@ -1089,15 +1128,18 @@ TEH_RESPONSE_reply_refresh_link_success (struct MHD_Connection *connection,
* 404 reply.
*
* @param connection connection to the client
+ * @param ec Taler error code
* @return MHD result code
*/
int
-TEH_RESPONSE_reply_transaction_unknown (struct MHD_Connection *connection)
+TEH_RESPONSE_reply_transaction_unknown (struct MHD_Connection *connection,
+ enum TALER_ErrorCode ec)
{
return TEH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_NOT_FOUND,
- "{s:s}",
- "error", "Deposit unknown");
+ "{s:s, s:I}",
+ "error", "Deposit unknown",
+ "code", (json_int_t) ec);
}
diff --git a/src/exchange/taler-exchange-httpd_responses.h b/src/exchange/taler-exchange-httpd_responses.h
index 742a95b91..70d384fe4 100644
--- a/src/exchange/taler-exchange-httpd_responses.h
+++ b/src/exchange/taler-exchange-httpd_responses.h
@@ -29,6 +29,7 @@
#include <jansson.h>
#include <microhttpd.h>
#include <pthread.h>
+#include "taler_error_codes.h"
#include "taler-exchange-httpd.h"
#include "taler-exchange-httpd_db.h"
@@ -78,11 +79,13 @@ TEH_RESPONSE_reply_json_pack (struct MHD_Connection *connection,
* Send a response indicating an invalid signature.
*
* @param connection the MHD connection to use
+ * @param ec error code uniquely identifying the error
* @param param_name the parameter that is invalid
* @return a MHD result code
*/
int
TEH_RESPONSE_reply_signature_invalid (struct MHD_Connection *connection,
+ enum TALER_ErrorCode ec,
const char *param_name);
@@ -90,11 +93,13 @@ TEH_RESPONSE_reply_signature_invalid (struct MHD_Connection *connection,
* Send a response indicating an invalid argument.
*
* @param connection the MHD connection to use
+ * @param ec error code uniquely identifying the error
* @param param_name the parameter that is invalid
* @return MHD result code
*/
int
TEH_RESPONSE_reply_arg_invalid (struct MHD_Connection *connection,
+ enum TALER_ErrorCode ec,
const char *param_name);
@@ -104,11 +109,13 @@ TEH_RESPONSE_reply_arg_invalid (struct MHD_Connection *connection,
* denomination key).
*
* @param connection the MHD connection to use
+ * @param ec error code uniquely identifying the error
* @param param_name the parameter that is invalid
* @return a MHD result code
*/
int
TEH_RESPONSE_reply_arg_unknown (struct MHD_Connection *connection,
+ enum TALER_ErrorCode ec,
const char *param_name);
@@ -116,11 +123,13 @@ TEH_RESPONSE_reply_arg_unknown (struct MHD_Connection *connection,
* Send a response indicating a missing argument.
*
* @param connection the MHD connection to use
+ * @param ec error code uniquely identifying the error
* @param param_name the parameter that is missing
* @return a MHD result code
*/
int
TEH_RESPONSE_reply_arg_missing (struct MHD_Connection *connection,
+ enum TALER_ErrorCode ec,
const char *param_name);
@@ -128,11 +137,13 @@ TEH_RESPONSE_reply_arg_missing (struct MHD_Connection *connection,
* Send a response indicating permission denied.
*
* @param connection the MHD connection to use
+ * @param ec error code uniquely identifying the error
* @param hint hint about why access was denied
* @return a MHD result code
*/
int
TEH_RESPONSE_reply_permission_denied (struct MHD_Connection *connection,
+ enum TALER_ErrorCode ec,
const char *hint);
@@ -140,11 +151,13 @@ TEH_RESPONSE_reply_permission_denied (struct MHD_Connection *connection,
* Send a response indicating an internal error.
*
* @param connection the MHD connection to use
+ * @param ec error code uniquely identifying the error
* @param hint hint about the internal error's nature
* @return a MHD result code
*/
int
TEH_RESPONSE_reply_internal_error (struct MHD_Connection *connection,
+ enum TALER_ErrorCode ec,
const char *hint);
@@ -152,11 +165,13 @@ TEH_RESPONSE_reply_internal_error (struct MHD_Connection *connection,
* Send a response indicating an external error.
*
* @param connection the MHD connection to use
+ * @param ec error code uniquely identifying the error
* @param hint hint about the error's nature
* @return a MHD result code
*/
int
TEH_RESPONSE_reply_external_error (struct MHD_Connection *connection,
+ enum TALER_ErrorCode ec,
const char *hint);
@@ -165,21 +180,24 @@ TEH_RESPONSE_reply_external_error (struct MHD_Connection *connection,
* transaction (concurrent interference).
*
* @param connection the MHD connection to use
+ * @param ec error code uniquely identifying the error
* @return a MHD result code
*/
int
-TEH_RESPONSE_reply_commit_error (struct MHD_Connection *connection);
-
+TEH_RESPONSE_reply_commit_error (struct MHD_Connection *connection,
+ enum TALER_ErrorCode ec);
/**
* Send a response indicating a failure to talk to the Exchange's
* database.
*
* @param connection the MHD connection to use
+ * @param ec error code uniquely identifying the error
* @return a MHD result code
*/
int
-TEH_RESPONSE_reply_internal_db_error (struct MHD_Connection *connection);
+TEH_RESPONSE_reply_internal_db_error (struct MHD_Connection *connection,
+ enum TALER_ErrorCode ec);
/**
@@ -199,7 +217,7 @@ TEH_RESPONSE_reply_request_too_large (struct MHD_Connection *connection);
* @return a MHD result code
*/
int
-TEH_RESPONSE_reply_invalid_json (struct MHD_Connection *connection);
+TEH_RESPONSE_reply_invalid_json (struct MHD_Connection *connectionx);
/**
@@ -266,11 +284,13 @@ TEH_RESPONSE_reply_refund_conflict (struct MHD_Connection *connection,
*
* @param connection connection to the client
* @param response_code response code to generate
+ * @param ec error code uniquely identifying the error
* @return MHD result code
*/
int
TEH_RESPONSE_reply_refund_failure (struct MHD_Connection *connection,
- unsigned int response_code);
+ unsigned int response_code,
+ enum TALER_ErrorCode ec);
/**
@@ -291,10 +311,12 @@ TEH_RESPONSE_reply_refund_success (struct MHD_Connection *connection,
* 404 reply.
*
* @param connection connection to the client
+ * @param ec Taler error code
* @return MHD result code
*/
int
-TEH_RESPONSE_reply_transaction_unknown (struct MHD_Connection *connection);
+TEH_RESPONSE_reply_transaction_unknown (struct MHD_Connection *connection,
+ enum TALER_ErrorCode ec);
/**
@@ -307,7 +329,7 @@ TEH_RESPONSE_reply_transaction_unknown (struct MHD_Connection *connection);
*/
int
TEH_RESPONSE_reply_transfer_pending (struct MHD_Connection *connection,
- struct GNUNET_TIME_Absolute planned_exec_time);
+ struct GNUNET_TIME_Absolute planned_exec_time);
/**
diff --git a/src/exchange/taler-exchange-httpd_test.c b/src/exchange/taler-exchange-httpd_test.c
index 7c3252b10..731da36ce 100644
--- a/src/exchange/taler-exchange-httpd_test.c
+++ b/src/exchange/taler-exchange-httpd_test.c
@@ -295,6 +295,7 @@ TEH_TEST_handler_test_ecdhe (struct TEH_RequestHandler *rh,
{
GNUNET_JSON_parse_free (spec);
return TEH_RESPONSE_reply_internal_error (connection,
+ TALER_EC_TEST_ECDH_ERROR,
"Failed to perform ECDH");
}
GNUNET_JSON_parse_free (spec);
@@ -365,6 +366,7 @@ TEH_TEST_handler_test_eddsa (struct TEH_RequestHandler *rh,
{
GNUNET_JSON_parse_free (spec);
return TEH_RESPONSE_reply_signature_invalid (connection,
+ TALER_EC_TEST_EDDSA_INVALID,
"eddsa_sig");
}
GNUNET_JSON_parse_free (spec);
@@ -377,6 +379,7 @@ TEH_TEST_handler_test_eddsa (struct TEH_RequestHandler *rh,
{
GNUNET_free (pk);
return TEH_RESPONSE_reply_internal_error (connection,
+ TALER_EC_TEST_EDDSA_ERROR,
"Failed to EdDSA-sign");
}
GNUNET_CRYPTO_eddsa_key_get_public (pk,
@@ -419,6 +422,7 @@ TEH_TEST_handler_test_rsa_get (struct TEH_RequestHandler *rh,
{
GNUNET_break (0);
return TEH_RESPONSE_reply_internal_error (connection,
+ TALER_EC_TEST_RSA_GEN_ERROR,
"Failed to create RSA key");
}
pub = GNUNET_CRYPTO_rsa_private_key_get_public (rsa_pk);
@@ -426,6 +430,7 @@ TEH_TEST_handler_test_rsa_get (struct TEH_RequestHandler *rh,
{
GNUNET_break (0);
return TEH_RESPONSE_reply_internal_error (connection,
+ TALER_EC_TEST_RSA_PUB_ERROR,
"Failed to get public RSA key");
}
res = TEH_RESPONSE_reply_json_pack (connection,
@@ -489,6 +494,7 @@ TEH_TEST_handler_test_rsa_sign (struct TEH_RequestHandler *rh,
GNUNET_break (0);
GNUNET_JSON_parse_free (spec);
return TEH_RESPONSE_reply_internal_error (connection,
+ TALER_EC_TEST_RSA_GEN_ERROR,
"Failed to create RSA key");
}
sig = GNUNET_CRYPTO_rsa_sign_blinded (rsa_pk,
@@ -499,6 +505,7 @@ TEH_TEST_handler_test_rsa_sign (struct TEH_RequestHandler *rh,
GNUNET_break (0);
GNUNET_JSON_parse_free (spec);
return TEH_RESPONSE_reply_internal_error (connection,
+ TALER_EC_TEST_RSA_SIGN_ERROR,
"Failed to RSA-sign");
}
GNUNET_JSON_parse_free (spec);
diff --git a/src/exchange/taler-exchange-httpd_tracking.c b/src/exchange/taler-exchange-httpd_tracking.c
index 1c7c24557..04b50132c 100644
--- a/src/exchange/taler-exchange-httpd_tracking.c
+++ b/src/exchange/taler-exchange-httpd_tracking.c
@@ -88,6 +88,7 @@ check_and_handle_track_transaction_request (struct MHD_Connection *connection,
{
GNUNET_break_op (0);
return TEH_RESPONSE_reply_signature_invalid (connection,
+ TALER_EC_TRACK_TRANSACTION_MERCHANT_SIGNATURE_INVALID,
"merchant_sig");
}
return TEH_DB_execute_track_transaction (connection,
diff --git a/src/exchangedb/plugin_exchangedb_postgres.c b/src/exchangedb/plugin_exchangedb_postgres.c
index 972d70808..461184c7e 100644
--- a/src/exchangedb/plugin_exchangedb_postgres.c
+++ b/src/exchangedb/plugin_exchangedb_postgres.c
@@ -20,6 +20,7 @@
* @author Florian Dold
* @author Christian Grothoff
* @author Sree Harsha Totakura
+ * @author Marcello Stanisci
*/
#include "platform.h"
#include "taler_pq_lib.h"
@@ -627,6 +628,23 @@ postgres_prepare (PGconn *db_conn)
"($1, $2, $3, $4, $5, $6, $7);",
7, NULL);
+
+ /* Used in postgres_select_reserves_in_above_serial_id() to obtain inbound
+ transactions for reserves with serial id '\geq' the given parameter */
+ PREPARE ("audit_reserves_in_get_transactions_incr",
+ "SELECT"
+ " reserve_pub"
+ ",credit_val"
+ ",credit_frac"
+ ",credit_curr"
+ ",execution_date"
+ ",sender_account_details"
+ ",transfer_details"
+ " FROM reserves_in"
+ " WHERE reserve_in_serial_id>=$1"
+ " ORDER BY reserve_in_serial_id",
+ 1, NULL);
+
/* Used in #postgres_get_reserve_history() to obtain inbound transactions
for a reserve */
PREPARE ("reserves_in_get_transactions",
@@ -707,6 +725,23 @@ postgres_prepare (PGconn *db_conn)
" WHERE reserve_pub=$1;",
1, NULL);
+ /* Used in #postgres_select_reserves_out_above_serial_id() */
+ PREPARE ("audit_get_reserves_out_incr",
+ "SELECT"
+ " h_blind_ev"
+ ",denom_pub"
+ ",denom_sig"
+ ",reserve_sig"
+ ",reserve_pub"
+ ",execution_date"
+ ",amount_with_fee_val"
+ ",amount_with_fee_frac"
+ ",amount_with_fee_curr"
+ " FROM reserves_out"
+ " WHERE reserve_out_serial_id>=$1"
+ " ORDER BY reserve_out_serial_id ASC",
+ 1, NULL);
+
/* Used in #postgres_get_refresh_session() to fetch
high-level information about a refresh session */
PREPARE ("get_refresh_session",
@@ -727,6 +762,22 @@ postgres_prepare (PGconn *db_conn)
" WHERE session_hash=$1 ",
1, NULL);
+ /* Used in #postgres_select_refreshs_above_serial_id() to fetch
+ refresh session with id '\geq' the given parameter */
+ PREPARE ("audit_get_refresh_sessions_incr",
+ "SELECT"
+ " old_coin_pub"
+ ",old_coin_sig"
+ ",amount_with_fee_val"
+ ",amount_with_fee_frac"
+ ",amount_with_fee_curr"
+ ",num_newcoins"
+ ",noreveal_index"
+ " FROM refresh_sessions"
+ " WHERE melt_serial_id>=$1"
+ " ORDER BY melt_serial_id ASC",
+ 1, NULL);
+
/* Used in #postgres_create_refresh_session() to store
high-level information about a refresh session */
PREPARE ("insert_refresh_session",
@@ -802,6 +853,23 @@ postgres_prepare (PGconn *db_conn)
" WHERE old_coin_pub=$1",
1, NULL);
+ /* Fetch refunds with rowid '\geq' the given parameter */
+ PREPARE ("audit_get_refunds_incr",
+ "SELECT"
+ " merchant_pub"
+ ",merchant_sig"
+ ",h_contract"
+ ",transaction_id"
+ ",rtransaction_id"
+ ",coin_pub"
+ ",amount_with_fee_val"
+ ",amount_with_fee_frac"
+ ",amount_with_fee_curr"
+ " FROM refunds"
+ " WHERE refund_serial_id>=$1"
+ " ORDER BY refund_serial_id ASC",
+ 1, NULL);
+
/* Query the 'refunds' by coin public key */
PREPARE ("get_refunds_by_coin",
"SELECT"
@@ -823,6 +891,7 @@ postgres_prepare (PGconn *db_conn)
1, NULL);
+
/* Used in #postgres_insert_transfer_public_key() to
store commitments */
PREPARE ("insert_transfer_public_key",
@@ -921,8 +990,7 @@ postgres_prepare (PGconn *db_conn)
" )",
3, NULL);
- /* Fetch an existing deposit request, used to ensure idempotency
- during /deposit processing. Used in #postgres_have_deposit(). */
+ /* Fetch deposits with rowid '\geq' the given parameter */
PREPARE ("audit_get_deposits_incr",
"SELECT"
" amount_with_fee_val"
@@ -937,11 +1005,12 @@ postgres_prepare (PGconn *db_conn)
",wire_deadline"
",h_contract"
",wire"
+ ",done"
" FROM deposits"
" WHERE ("
" (deposit_serial_id>=$1)"
" )"
- " ORDER BY deposit_serial_id",
+ " ORDER BY deposit_serial_id ASC",
1, NULL);
/* Fetch an existing deposit request.
@@ -1207,6 +1276,18 @@ postgres_prepare (PGconn *db_conn)
" FROM prewire"
" WHERE finished=true",
0, NULL);
+
+ /* Used in #postgres_select_prepare_above_serial_id() */
+ PREPARE ("audit_get_wire_incr",
+ "SELECT"
+ " type"
+ ",buf"
+ ",finished"
+ " FROM prewire"
+ " WHERE prewire_uuid>=$1"
+ " ORDER BY prewire_uuid ASC",
+ 1, NULL);
+
PREPARE ("gc_denominations",
"DELETE"
" FROM denominations"
@@ -4291,9 +4372,9 @@ postgres_select_deposits_above_serial_id (void *cls,
};
PGresult *result;
result = GNUNET_PQ_exec_prepared (session->conn,
- "audit_get_deposits_incr",
- params);
- if (PGRES_COMMAND_OK !=
+ "audit_get_deposits_incr",
+ params);
+ if (PGRES_TUPLES_OK !=
PQresultStatus (result))
{
BREAK_DB_ERR (result);
@@ -4307,20 +4388,62 @@ postgres_select_deposits_above_serial_id (void *cls,
if (0 == nrows)
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "audit_get_deposit_incr() returned 0 matching rows\n");
+ "select_deposits_above_serial_id() returned 0 matching rows\n");
PQclear (result);
return GNUNET_NO;
}
for (i=0;i<nrows;i++)
{
+ struct TALER_EXCHANGEDB_Deposit deposit;
+ uint8_t done = 0;
+ struct GNUNET_PQ_ResultSpec rs[] = {
+ TALER_PQ_result_spec_amount ("amount_with_fee",
+ &deposit.amount_with_fee),
+ GNUNET_PQ_result_spec_absolute_time ("timestamp",
+ &deposit.timestamp),
+ GNUNET_PQ_result_spec_auto_from_type ("merchant_pub",
+ &deposit.merchant_pub),
+ GNUNET_PQ_result_spec_auto_from_type ("coin_pub",
+ &deposit.coin.coin_pub),
+ GNUNET_PQ_result_spec_auto_from_type ("coin_sig",
+ &deposit.csig),
+ GNUNET_PQ_result_spec_uint64 ("transaction_id",
+ &deposit.transaction_id),
+ GNUNET_PQ_result_spec_absolute_time ("refund_deadline",
+ &deposit.refund_deadline),
+ GNUNET_PQ_result_spec_absolute_time ("wire_deadline",
+ &deposit.wire_deadline),
+ GNUNET_PQ_result_spec_auto_from_type ("h_contract",
+ &deposit.h_contract),
+ TALER_PQ_result_spec_json ("wire",
+ &deposit.receiver_wire_account),
+ GNUNET_PQ_result_spec_auto_from_type ("done",
+ &done),
+ GNUNET_PQ_result_spec_end
+ };
+ if (GNUNET_OK !=
+ GNUNET_PQ_extract_result (result, rs, 0))
+ {
+ GNUNET_break (0);
+ PQclear (result);
+ return GNUNET_SYSERR;
+ }
+ cb (cb_cls,
+ serial_id,
+ &deposit.merchant_pub,
+ &deposit.coin.coin_pub,
+ &deposit.csig,
+ &deposit.amount_with_fee,
+ deposit.transaction_id,
+ &deposit.h_contract,
+ deposit.refund_deadline,
+ deposit.wire_deadline,
+ deposit.receiver_wire_account,
+ done);
}
-
PQclear (result);
return GNUNET_OK;
-
- GNUNET_break (0); // FIXME: not implemented
- return GNUNET_SYSERR;
}
@@ -4343,8 +4466,72 @@ postgres_select_refreshs_above_serial_id (void *cls,
TALER_EXCHANGEDB_RefreshSessionCallback cb,
void *cb_cls)
{
- GNUNET_break (0); // FIXME: not implemented
- return GNUNET_SYSERR;
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_uint64 (&serial_id),
+ GNUNET_PQ_query_param_end
+ };
+ PGresult *result;
+ result = GNUNET_PQ_exec_prepared (session->conn,
+ "audit_get_refresh_sessions_incr",
+ params);
+
+ if (PGRES_TUPLES_OK !=
+ PQresultStatus (result))
+ {
+ BREAK_DB_ERR (result);
+ PQclear (result);
+ return GNUNET_SYSERR;
+ }
+ int nrows;
+ int i;
+
+ nrows = PQntuples (result);
+ if (0 == nrows)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "select_refreshs_above_serial_id() returned 0 matching rows\n");
+ PQclear (result);
+ return GNUNET_NO;
+ }
+
+ for (i=0;i<nrows;i++)
+ {
+ struct TALER_CoinSpendPublicKeyP coin_pub;
+ struct TALER_CoinSpendSignatureP coin_sig;
+ struct TALER_Amount amount_with_fee;
+ uint16_t num_newcoins;
+ uint16_t noreveal_index;
+
+ struct GNUNET_PQ_ResultSpec rs[] = {
+ GNUNET_PQ_result_spec_auto_from_type ("old_coin_pub",
+ &coin_pub),
+ GNUNET_PQ_result_spec_auto_from_type ("old_coin_sig",
+ &coin_sig),
+ TALER_PQ_result_spec_amount ("amount_with_fee",
+ &amount_with_fee),
+ GNUNET_PQ_result_spec_uint16 ("num_newcoins",
+ &num_newcoins),
+ GNUNET_PQ_result_spec_uint16 ("noreveal_index",
+ &noreveal_index),
+ GNUNET_PQ_result_spec_end
+ };
+ if (GNUNET_OK !=
+ GNUNET_PQ_extract_result (result, rs, 0))
+ {
+ GNUNET_break (0);
+ PQclear (result);
+ return GNUNET_SYSERR;
+ }
+ cb (cb_cls,
+ serial_id,
+ &coin_pub,
+ &coin_sig,
+ &amount_with_fee,
+ num_newcoins,
+ noreveal_index);
+ }
+ PQclear (result);
+ return GNUNET_OK;
}
@@ -4367,8 +4554,72 @@ postgres_select_refunds_above_serial_id (void *cls,
TALER_EXCHANGEDB_RefundCallback cb,
void *cb_cls)
{
- GNUNET_break (0); // FIXME: not implemented
- return GNUNET_SYSERR;
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_uint64 (&serial_id),
+ GNUNET_PQ_query_param_end
+ };
+ PGresult *result;
+ result = GNUNET_PQ_exec_prepared (session->conn,
+ "audit_get_refunds_incr",
+ params);
+ if (PGRES_TUPLES_OK !=
+ PQresultStatus (result))
+ {
+ BREAK_DB_ERR (result);
+ PQclear (result);
+ return GNUNET_SYSERR;
+ }
+ int nrows;
+ int i;
+
+ nrows = PQntuples (result);
+ if (0 == nrows)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "select_refunds_above_serial_id() returned 0 matching rows\n");
+ PQclear (result);
+ return GNUNET_NO;
+ }
+ for (i=0;i<nrows;i++)
+ {
+ struct TALER_EXCHANGEDB_Refund refund;
+
+ struct GNUNET_PQ_ResultSpec rs[] = {
+ GNUNET_PQ_result_spec_auto_from_type ("merchant_pub",
+ &refund.merchant_pub),
+ GNUNET_PQ_result_spec_auto_from_type ("merchant_sig",
+ &refund.merchant_sig),
+ GNUNET_PQ_result_spec_auto_from_type ("h_contract",
+ &refund.h_contract),
+ GNUNET_PQ_result_spec_uint64 ("transaction_id",
+ &refund.transaction_id),
+ GNUNET_PQ_result_spec_uint64 ("rtransaction_id",
+ &refund.rtransaction_id),
+ GNUNET_PQ_result_spec_auto_from_type ("coin_pub",
+ &refund.coin.coin_pub),
+ TALER_PQ_result_spec_amount ("amount_with_fee",
+ &refund.refund_amount),
+ GNUNET_PQ_result_spec_end
+ };
+ if (GNUNET_OK !=
+ GNUNET_PQ_extract_result (result, rs, 0))
+ {
+ GNUNET_break (0);
+ PQclear (result);
+ return GNUNET_SYSERR;
+ }
+ cb (cb_cls,
+ serial_id,
+ &refund.coin.coin_pub,
+ &refund.merchant_pub,
+ &refund.merchant_sig,
+ &refund.h_contract,
+ refund.transaction_id,
+ refund.rtransaction_id,
+ &refund.refund_amount);
+ }
+ PQclear (result);
+ return GNUNET_OK;
}
@@ -4391,8 +4642,73 @@ postgres_select_reserves_in_above_serial_id (void *cls,
TALER_EXCHANGEDB_ReserveInCallback cb,
void *cb_cls)
{
- GNUNET_break (0); // FIXME: not implemented
- return GNUNET_SYSERR;
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_uint64 (&serial_id),
+ GNUNET_PQ_query_param_end
+ };
+ PGresult *result;
+ result = GNUNET_PQ_exec_prepared (session->conn,
+ "audit_reserves_in_get_transactions_incr",
+ params);
+ if (PGRES_TUPLES_OK !=
+ PQresultStatus (result))
+ {
+ BREAK_DB_ERR (result);
+ PQclear (result);
+ return GNUNET_SYSERR;
+ }
+ int nrows;
+ int i;
+
+ nrows = PQntuples (result);
+ if (0 == nrows)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "select_reserves_in_above_serial_id() returned 0 matching rows\n");
+ PQclear (result);
+ return GNUNET_NO;
+ }
+
+ for (i=0;i<nrows;i++)
+ {
+ struct TALER_ReservePublicKeyP reserve_pub;
+ struct TALER_Amount credit;
+ json_t *sender_account_details;
+ json_t *transfer_details;
+ struct GNUNET_TIME_Absolute execution_date;
+
+ struct GNUNET_PQ_ResultSpec rs[] = {
+ GNUNET_PQ_result_spec_auto_from_type ("reserve_pub",
+ &reserve_pub),
+ TALER_PQ_result_spec_amount ("credit",
+ &credit),
+ GNUNET_PQ_result_spec_absolute_time("execution_date",
+ &execution_date),
+ TALER_PQ_result_spec_json ("sender_account_details",
+ &sender_account_details),
+ TALER_PQ_result_spec_json ("transfer_details",
+ &transfer_details),
+ GNUNET_PQ_result_spec_end
+ };
+
+ if (GNUNET_OK !=
+ GNUNET_PQ_extract_result (result, rs, 0))
+ {
+ GNUNET_break (0);
+ PQclear (result);
+ return GNUNET_SYSERR;
+ }
+ cb (cb_cls,
+ serial_id,
+ &reserve_pub,
+ &credit,
+ sender_account_details,
+ transfer_details,
+ execution_date);
+ }
+
+ PQclear (result);
+ return GNUNET_OK;
}
@@ -4415,8 +4731,79 @@ postgres_select_reserves_out_above_serial_id (void *cls,
TALER_EXCHANGEDB_WithdrawCallback cb,
void *cb_cls)
{
- GNUNET_break (0); // FIXME: not implemented
- return GNUNET_SYSERR;
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_uint64 (&serial_id),
+ GNUNET_PQ_query_param_end
+ };
+ PGresult *result;
+ result = GNUNET_PQ_exec_prepared (session->conn,
+ "audit_get_reserves_out_incr",
+ params);
+ if (PGRES_TUPLES_OK !=
+ PQresultStatus (result))
+ {
+ BREAK_DB_ERR (result);
+ PQclear (result);
+ return GNUNET_SYSERR;
+ }
+ int nrows;
+ int i;
+
+ nrows = PQntuples (result);
+ if (0 == nrows)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "select_reserves_out_above_serial_id() returned 0 matching rows\n");
+ PQclear (result);
+ return GNUNET_NO;
+ }
+ for (i=0;i<nrows;i++)
+ {
+ struct GNUNET_HashCode h_blind_ev;
+ struct TALER_DenominationPublicKey denom_pub;
+ struct TALER_DenominationSignature denom_sig;
+ struct TALER_ReservePublicKeyP reserve_pub;
+ struct TALER_ReserveSignatureP reserve_sig;
+ struct GNUNET_TIME_Absolute execution_date;
+ struct TALER_Amount amount_with_fee;
+
+ struct GNUNET_PQ_ResultSpec rs[] = {
+ GNUNET_PQ_result_spec_auto_from_type ("h_blind_ev",
+ &h_blind_ev),
+ GNUNET_PQ_result_spec_rsa_public_key ("denom_pub",
+ &denom_pub.rsa_public_key),
+ GNUNET_PQ_result_spec_rsa_signature ("denom_sig",
+ &denom_sig.rsa_signature),
+ GNUNET_PQ_result_spec_auto_from_type ("reserve_pub",
+ &reserve_pub),
+ GNUNET_PQ_result_spec_auto_from_type ("reserve_sig",
+ &reserve_sig),
+ GNUNET_PQ_result_spec_absolute_time ("execution_date",
+ &execution_date),
+ TALER_PQ_result_spec_amount ("amount_with_fee",
+ &amount_with_fee),
+ GNUNET_PQ_result_spec_end
+ };
+ if (GNUNET_OK !=
+ GNUNET_PQ_extract_result (result, rs, 0))
+ {
+ GNUNET_break (0);
+ PQclear (result);
+ return GNUNET_SYSERR;
+ }
+ cb (cb_cls,
+ serial_id,
+ &h_blind_ev,
+ &denom_pub,
+ &denom_sig,
+ &reserve_pub,
+ &reserve_sig,
+ execution_date,
+ &amount_with_fee);
+ }
+
+ PQclear (result);
+ return GNUNET_OK;
}
@@ -4440,8 +4827,69 @@ postgres_select_prepare_above_serial_id (void *cls,
TALER_EXCHANGEDB_WirePreparationCallback cb,
void *cb_cls)
{
- GNUNET_break (0); // FIXME: not implemented
- return GNUNET_SYSERR;
+
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_uint64 (&serial_id),
+ GNUNET_PQ_query_param_end
+ };
+ PGresult *result;
+ result = GNUNET_PQ_exec_prepared (session->conn,
+ "audit_get_wire_incr",
+ params);
+ if (PGRES_TUPLES_OK !=
+ PQresultStatus (result))
+ {
+ BREAK_DB_ERR (result);
+ PQclear (result);
+ return GNUNET_SYSERR;
+ }
+ int nrows;
+ int i;
+
+ nrows = PQntuples (result);
+ if (0 == nrows)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "select_prepare_above_serial_id() returned 0 matching rows\n");
+ PQclear (result);
+ return GNUNET_NO;
+ }
+ for (i=0;i<nrows;i++)
+ {
+ char *wire_method;
+ void *buf;
+ size_t buf_size;
+ uint8_t finished;
+
+ struct GNUNET_PQ_ResultSpec rs[] = {
+ GNUNET_PQ_result_spec_string ("type",
+ &wire_method),
+ GNUNET_PQ_result_spec_variable_size ("buf",
+ &buf,
+ &buf_size),
+ GNUNET_PQ_result_spec_auto_from_type ("finished",
+ &finished),
+ GNUNET_PQ_result_spec_end
+ };
+
+ if (GNUNET_OK !=
+ GNUNET_PQ_extract_result (result, rs, 0))
+ {
+ GNUNET_break (0);
+ PQclear (result);
+ return GNUNET_SYSERR;
+ }
+
+ cb (cb_cls,
+ serial_id,
+ wire_method,
+ buf,
+ buf_size,
+ finished);
+ }
+
+ PQclear (result);
+ return GNUNET_OK;
}
diff --git a/src/exchangedb/test_exchangedb.c b/src/exchangedb/test_exchangedb.c
index 00c7a9ef6..d0ec63f46 100644
--- a/src/exchangedb/test_exchangedb.c
+++ b/src/exchangedb/test_exchangedb.c
@@ -18,6 +18,7 @@
* @brief test cases for DB interaction functions
* @author Sree Harsha Totakura
* @author Christian Grothoff
+ * @author Marcello Stanisci
*/
#include "platform.h"
#include "taler_exchangedb_lib.h"
@@ -77,6 +78,12 @@ dead_prepare_cb (void *cls,
GNUNET_assert (0);
}
+/**
+ * Counter used in auditor-related db functions. Used to count
+ * expected rows.
+ */
+unsigned int auditor_row_cnt;
+
/**
* Callback that is called with wire prepare data
@@ -103,6 +110,27 @@ mark_prepare_cb (void *cls,
rowid));
}
+/**
+ * Callback with data about a prepared wire transfer.
+ *
+ * @param cls closure
+ * @param rowid row identifier used to mark prepared transaction as done
+ * @param wire_method which wire method is this preparation data for
+ * @param buf transaction data that was persisted, NULL on error
+ * @param buf_size number of bytes in @a buf, 0 on error
+ * @param finished did we complete the transfer yet?
+ */
+void
+audit_wire_cb (void *cls,
+ unsigned long long rowid,
+ const char *wire_method,
+ const char *buf,
+ size_t buf_size,
+ int finished)
+{
+ auditor_row_cnt++;
+ return;
+}
/**
* Test API relating to persisting the wire plugins preparation data.
@@ -134,6 +162,14 @@ test_wire_prepare (struct TALER_EXCHANGEDB_Session *session)
session,
&dead_prepare_cb,
NULL));
+ auditor_row_cnt = 0;
+ FAILIF (GNUNET_OK !=
+ plugin->select_prepare_above_serial_id (plugin->cls,
+ session,
+ 0,
+ &audit_wire_cb,
+ NULL));
+ FAILIF (1 != auditor_row_cnt);
return GNUNET_OK;
drop:
return GNUNET_SYSERR;
@@ -465,6 +501,38 @@ check_transfer_data (void *cls,
*ok = GNUNET_SYSERR;
}
+/**
+ * Function called with details about coins that were melted,
+ * with the goal of auditing the refresh's execution.
+ *
+ * @param cls closure
+ * @param rowid unique serial ID for the refresh session in our DB
+ * @param merchant_pub public key of the merchant
+ * @param coin_pub public key of the coin
+ * @param coin_sig signature from the coin
+ * @param amount_with_fee amount that was deposited including fee
+ * @param transaction_id unique transaction ID chosen by the merchant
+ * @param h_contract hash of the contract between merchant and customer
+ * @param refund_deadline by which the merchant adviced that he might want
+ * to get a refund
+ * @param wire_deadline by which the merchant adviced that he would like the
+ * wire transfer to be executed
+ * @param receiver_wire_account wire details for the merchant, NULL from iterate_matching_deposits()
+ * @param done flag set if the deposit was already executed (or not)
+ * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop
+ */
+int
+audit_refresh_session_cb (void *cls,
+ unsigned long long rowid, /* FIXME: decide data type for serial_id! */
+ const struct TALER_CoinSpendPublicKeyP *coin_pub,
+ const struct TALER_CoinSpendSignatureP *coin_sig,
+ const struct TALER_Amount *amount_with_fee,
+ uint16_t num_newcoins,
+ uint16_t noreveal_index)
+{
+ auditor_row_cnt++;
+ return GNUNET_OK;
+}
/**
* Function to test melting of coins as part of a refresh session
@@ -538,6 +606,14 @@ test_melting (struct TALER_EXCHANGEDB_Session *session)
session,
&session_hash,
&ret_refresh_session));
+
+ auditor_row_cnt = 0;
+ FAILIF (GNUNET_OK != plugin->select_refreshs_above_serial_id (plugin->cls,
+ session,
+ 0,
+ &audit_refresh_session_cb,
+ NULL));
+ FAILIF (1 != auditor_row_cnt);
FAILIF (ret_refresh_session.num_newcoins != refresh_session.num_newcoins);
FAILIF (ret_refresh_session.noreveal_index != refresh_session.noreveal_index);
@@ -874,6 +950,128 @@ deposit_cb (void *cls,
return GNUNET_OK;
}
+/**
+ * Callback for #select_deposits_above_serial_id ()
+ *
+ * @param cls closure
+ * @param rowid unique serial ID for the deposit in our DB
+ * @param merchant_pub public key of the merchant
+ * @param coin_pub public key of the coin
+ * @param coin_sig signature from the coin
+ * @param amount_with_fee amount that was deposited including fee
+ * @param transaction_id unique transaction ID chosen by the merchant
+ * @param h_contract hash of the contract between merchant and customer
+ * @param refund_deadline by which the merchant adviced that he might want
+ * to get a refund
+ * @param wire_deadline by which the merchant adviced that he would like the
+ * wire transfer to be executed
+ * @param receiver_wire_account wire details for the merchant, NULL from iterate_matching_deposits()
+ * @param done flag set if the deposit was already executed (or not)
+ * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop
+ */
+int
+audit_deposit_cb (void *cls,
+ unsigned long long rowid,
+ const struct TALER_MerchantPublicKeyP *merchant_pub,
+ const struct TALER_CoinSpendPublicKeyP *coin_pub,
+ const struct TALER_CoinSpendSignatureP *coin_sig,
+ const struct TALER_Amount *amount_with_fee,
+ uint64_t transaction_id,
+ const struct GNUNET_HashCode *h_contract,
+ struct GNUNET_TIME_Absolute refund_deadline,
+ struct GNUNET_TIME_Absolute wire_deadline,
+ const json_t *receiver_wire_account,
+ int done)
+{
+ auditor_row_cnt++;
+ return GNUNET_OK;
+}
+
+
+/**
+ * Function called with details about coins that were refunding,
+ * with the goal of auditing the refund's execution.
+ *
+ * @param cls closure
+ * @param rowid unique serial ID for the refund in our DB
+ * @param coin_pub public key of the coin
+ * @param merchant_pub public key of the merchant
+ * @param merchant_sig signature of the merchant
+ * @param h_contract hash of the contract between merchant and customer
+ * @param transaction_id original transaction ID chosen by the merchant
+ * @param rtransaction_id refund transaction ID chosen by the merchant
+ * @param amount_with_fee amount that was deposited including fee
+ * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop
+ */
+int
+audit_refund_cb (void *cls,
+ unsigned long long rowid, /* FIXME: decide data type for serial_id! */
+ const struct TALER_CoinSpendPublicKeyP *coin_pub,
+ const struct TALER_MerchantPublicKeyP *merchant_pub,
+ const struct TALER_MerchantSignatureP *merchant_sig,
+ const struct GNUNET_HashCode *h_contract,
+ uint64_t transaction_id,
+ uint64_t rtransaction_id,
+ const struct TALER_Amount *amount_with_fee)
+{
+ auditor_row_cnt++;
+ return GNUNET_OK;
+}
+
+
+/**
+ * Function called with details about incoming wire transfers.
+ *
+ * @param cls closure
+ * @param rowid unique serial ID for the refresh session in our DB
+ * @param reserve_pub public key of the reserve (also the WTID)
+ * @param credit amount that was received
+ * @param sender_account_details information about the sender's bank account
+ * @param transfer_details information that uniquely identifies the wire transfer
+ * @param execution_date when did we receive the funds
+ * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop
+ */
+int
+audit_reserve_in_cb (void *cls,
+ unsigned long long rowid, /* FIXME: decide data type for serial_id! */
+ const struct TALER_ReservePublicKeyP *reserve_pub,
+ const struct TALER_Amount *credit,
+ const json_t *sender_account_details,
+ const json_t *transfer_details,
+ struct GNUNET_TIME_Absolute execution_date)
+{
+ auditor_row_cnt++;
+ return GNUNET_OK;
+}
+
+/**
+ * Function called with details about withdraw operations.
+ *
+ * @param cls closure
+ * @param rowid unique serial ID for the refresh session in our DB
+ * @param h_blind_ev blinded hash of the coin's public key
+ * @param denom_pub public denomination key of the deposited coin
+ * @param denom_sig signature over the deposited coin
+ * @param reserve_pub public key of the reserve
+ * @param reserve_sig signature over the withdraw operation
+ * @param execution_date when did the wallet withdraw the coin
+ * @param amount_with_fee amount that was withdrawn
+ * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop
+ */
+int
+audit_reserve_out_cb (void *cls,
+ unsigned long long rowid, /* FIXME: decide data type for serial_id! */
+ const struct GNUNET_HashCode *h_blind_ev,
+ const struct TALER_DenominationPublicKey *denom_pub,
+ const struct TALER_DenominationSignature *denom_sig,
+ const struct TALER_ReservePublicKeyP *reserve_pub,
+ const struct TALER_ReserveSignatureP *reserve_sig,
+ struct GNUNET_TIME_Absolute execution_date,
+ const struct TALER_Amount *amount_with_fee)
+{
+ auditor_row_cnt++;
+ return GNUNET_OK;
+}
/**
* Test garbage collection.
@@ -1121,6 +1319,21 @@ run (void *cls)
}
}
FAILIF (3 != cnt);
+
+ auditor_row_cnt = 0;
+ FAILIF (GNUNET_OK !=
+ plugin->select_reserves_in_above_serial_id (plugin->cls,
+ session,
+ 0,
+ &audit_reserve_in_cb,
+ NULL));
+ FAILIF (GNUNET_OK !=
+ plugin->select_reserves_out_above_serial_id (plugin->cls,
+ session,
+ 0,
+ &audit_reserve_out_cb,
+ NULL));
+ FAILIF (3 != auditor_row_cnt);
/* Tests for deposits */
memset (&deposit, 0, sizeof (deposit));
RND_BLK (&deposit.coin.coin_pub);
@@ -1145,6 +1358,14 @@ run (void *cls)
plugin->have_deposit (plugin->cls,
session,
&deposit));
+ auditor_row_cnt = 0;
+ FAILIF (GNUNET_OK !=
+ plugin->select_deposits_above_serial_id (plugin->cls,
+ session,
+ 0,
+ &audit_deposit_cb,
+ NULL));
+ FAILIF (1 != auditor_row_cnt);
result = 9;
FAILIF (1 !=
plugin->iterate_matching_deposits (plugin->cls,
@@ -1232,7 +1453,15 @@ run (void *cls)
plugin->insert_refund (plugin->cls,
session,
&refund));
+ auditor_row_cnt = 0;
+ FAILIF (GNUNET_OK !=
+ plugin->select_refunds_above_serial_id (plugin->cls,
+ session,
+ 0,
+ &audit_refund_cb,
+ NULL));
+ FAILIF (1 != auditor_row_cnt);
tl = plugin->get_coin_transactions (plugin->cls,
session,
&refund.coin.coin_pub);
diff --git a/src/include/taler_auditordb_plugin.h b/src/include/taler_auditordb_plugin.h
index cc75fb014..c27295a08 100644
--- a/src/include/taler_auditordb_plugin.h
+++ b/src/include/taler_auditordb_plugin.h
@@ -29,6 +29,90 @@
/**
+ * Function called with the results of select_denomination_info()
+ *
+ * @param cls closure
+ * @param issue issuing information with value, fees and other info about the denomination.
+ *
+ * @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_DenominationInfoDataCallback)(void *cls,
+ const struct TALER_DenominationKeyValidityPS *issue);
+
+
+/**
+ * Function called with the results of select_historic_denom_revenue()
+ *
+ * @param cls closure
+ * @param denom_pub_hash hash of the denomination key
+ * @param revenue_timestamp when did this profit get realized
+ * @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
+ * #GNUNET_SYSERR or other values on error.
+ */
+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);
+
+
+/**
+ * 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);
+
+
+/**
+ * Function called with the results of select_historic_reserve_revenue()
+ *
+ * @param cls closure
+ * @param start_time beginning of aggregated time interval
+ * @param end_time end of aggregated time interval
+ * @param reserve_profits total profits made
+ *
+ * @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_HistoricReserveRevenueDataCallback)(void *cls,
+ struct GNUNET_TIME_Absolute start_time,
+ struct GNUNET_TIME_Absolute end_time,
+ const struct TALER_Amount *reserve_profits);
+
+
+/**
* Handle for one session with the database.
*/
struct TALER_AUDITORDB_Session;
@@ -164,11 +248,89 @@ struct TALER_AUDITORDB_Plugin
(*select_denomination_info)(void *cls,
struct TALER_AUDITORDB_Session *session,
const struct TALER_MasterPublicKeyP *master_pub,
- void *cb, /* FIXME: type! */
+ TALER_AUDITORDB_DenominationInfoDataCallback cb,
void *cb_cls);
/**
+ * Insert information about the auditor's progress with an exchange's
+ * data.
+ *
+ * @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 last_reserve_in_serial_id serial ID of the last reserve_in transfer the auditor processed
+ * @param last_reserve_out_serial_id serial ID of the last withdraw the auditor processed
+ * @param last_deposit_serial_id serial ID of the last deposit the auditor processed
+ * @param last_melt_serial_id serial ID of the last refresh the auditor processed
+ * @param last_prewire_serial_id serial ID of the last prewire transfer the auditor processed
+ * @return #GNUNET_OK on success; #GNUNET_SYSERR on failure
+ */
+ int
+ (*insert_auditor_progress)(void *cls,
+ struct TALER_AUDITORDB_Session *session,
+ const struct TALER_MasterPublicKeyP *master_pub,
+ uint64_t last_reserve_in_serial_id,
+ uint64_t last_reserve_out_serial_id,
+ uint64_t last_deposit_serial_id,
+ uint64_t last_melt_serial_id,
+ uint64_t last_refund_serial_id,
+ uint64_t last_prewire_serial_id);
+
+
+ /**
+ * Update information about the progress of the auditor. There
+ * must be an existing record for the exchange.
+ *
+ * @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 last_reserve_in_serial_id serial ID of the last reserve_in transfer the auditor processed
+ * @param last_reserve_out_serial_id serial ID of the last withdraw the auditor processed
+ * @param last_deposit_serial_id serial ID of the last deposit the auditor processed
+ * @param last_melt_serial_id serial ID of the last refresh the auditor processed
+ * @param last_prewire_serial_id serial ID of the last prewire transfer the auditor processed
+ * @return #GNUNET_OK on success; #GNUNET_SYSERR on failure
+ */
+ int
+ (*update_auditor_progress)(void *cls,
+ struct TALER_AUDITORDB_Session *session,
+ const struct TALER_MasterPublicKeyP *master_pub,
+ uint64_t last_reserve_in_serial_id,
+ uint64_t last_reserve_out_serial_id,
+ uint64_t last_deposit_serial_id,
+ uint64_t last_melt_serial_id,
+ uint64_t last_refund_serial_id,
+ uint64_t last_prewire_serial_id);
+
+
+ /**
+ * Get information about the progress of the auditor.
+ *
+ * @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[out] last_reserve_in_serial_id serial ID of the last reserve_in transfer the auditor processed
+ * @param[out] last_reserve_out_serial_id serial ID of the last withdraw the auditor processed
+ * @param[out] last_deposit_serial_id serial ID of the last deposit the auditor processed
+ * @param[out] last_melt_serial_id serial ID of the last refresh the auditor processed
+ * @param[out] last_prewire_serial_id serial ID of the last prewire transfer the auditor processed
+ * @return #GNUNET_OK on success; #GNUNET_SYSERR on failure;
+ * #GNUNET_NO if we have no records for the @a master_pub
+ */
+ int
+ (*get_auditor_progress)(void *cls,
+ struct TALER_AUDITORDB_Session *session,
+ const struct TALER_MasterPublicKeyP *master_pub,
+ uint64_t *last_reserve_in_serial_id,
+ uint64_t *last_reserve_out_serial_id,
+ uint64_t *last_deposit_serial_id,
+ uint64_t *last_melt_serial_id,
+ uint64_t *last_refund_serial_id,
+ uint64_t *last_prewire_serial_id);
+
+
+ /**
* Insert information about a reserve. There must not be an
* existing record for the reserve.
*
@@ -586,7 +748,7 @@ struct TALER_AUDITORDB_Plugin
(*select_historic_denom_revenue)(void *cls,
struct TALER_AUDITORDB_Session *session,
const struct TALER_MasterPublicKeyP *master_pub,
- void *cb, /* FIXME: fix type */
+ TALER_AUDITORDB_HistoricDenominationRevenueDataCallback cb,
void *cb_cls);
@@ -628,7 +790,7 @@ struct TALER_AUDITORDB_Plugin
(*select_historic_losses)(void *cls,
struct TALER_AUDITORDB_Session *session,
const struct TALER_MasterPublicKeyP *master_pub,
- void *cb, /* FIXME: fix type */
+ TALER_AUDITORDB_HistoricLossesDataCallback cb,
void *cb_cls);
@@ -666,7 +828,7 @@ struct TALER_AUDITORDB_Plugin
(*select_historic_reserve_revenue)(void *cls,
struct TALER_AUDITORDB_Session *session,
const struct TALER_MasterPublicKeyP *master_pub,
- void *cb, /* FIXME: type */
+ TALER_AUDITORDB_HistoricReserveRevenueDataCallback cb,
void *cb_cls);
@@ -721,6 +883,7 @@ struct TALER_AUDITORDB_Plugin
const struct TALER_MasterPublicKeyP *master_pub,
struct TALER_Amount *balance);
+
};
diff --git a/src/include/taler_error_codes.h b/src/include/taler_error_codes.h
index bbb300440..6da76a122 100644
--- a/src/include/taler_error_codes.h
+++ b/src/include/taler_error_codes.h
@@ -33,12 +33,1097 @@ enum TALER_ErrorCode
{
/**
- * Special code to indicate no error.
+ * Special code to indicate no error (or no "code" present).
*/
- TALER_EC_NONE = 0
+ TALER_EC_NONE = 0,
+ /**
+ * Special code to indicate that a non-integer error code was
+ * returned in the JSON response.
+ */
+ TALER_EC_INVALID = 1,
+
+ /**
+ * The response we got from the server was not even in JSON format.
+ */
+ TALER_EC_INVALID_RESPONSE = 2,
+
+
+ /* ********** generic error codes ************* */
+
+ /**
+ * The exchange failed to even just initialize its connection to the
+ * database.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_INTERNAL_SERVER_ERROR.
+ */
+ TALER_EC_DB_SETUP_FAILED = 1001,
+
+ /**
+ * The exchange encountered an error event to just start
+ * the database transaction.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_INTERNAL_SERVER_ERROR.
+ */
+ TALER_EC_DB_START_FAILED = 1002,
+
+ /**
+ * The exchange encountered an error event to commit
+ * the database transaction (hard, unrecoverable error).
+ * This response is provided with HTTP status code
+ * MHD_HTTP_INTERNAL_SERVER_ERROR.
+ */
+ TALER_EC_DB_COMMIT_FAILED_HARD = 1003,
+
+ /**
+ * The exchange encountered an error event to commit
+ * the database transaction, even after repeatedly
+ * retrying it there was always a conflicting transaction.
+ * (This indicates a repeated serialization error; should
+ * only happen if some client maliciously tries to create
+ * conflicting concurrent transactions.)
+ * This response is provided with HTTP status code
+ * MHD_HTTP_INTERNAL_SERVER_ERROR.
+ */
+ TALER_EC_DB_COMMIT_FAILED_ON_RETRY = 1004,
+ /**
+ * The exchange had insufficient memory to parse the request. This
+ * response is provided with HTTP status code
+ * MHD_HTTP_INTERNAL_SERVER_ERROR.
+ */
+ TALER_EC_PARSER_OUT_OF_MEMORY = 1005,
+
+ /**
+ * The JSON in the client's request to the exchange was malformed.
+ * (Generic parse error).
+ * This response is provided with HTTP status code
+ * MHD_HTTP_BAD_REQUEST.
+ */
+ TALER_EC_JSON_INVALID = 1006,
+
+ /**
+ * The JSON in the client's request to the exchange was malformed.
+ * Details about the location of the parse error are provided.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_BAD_REQUEST.
+ */
+ TALER_EC_JSON_INVALID_WITH_DETAILS = 1007,
+
+ /**
+ * A required parameter in the request to the exchange was missing.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_BAD_REQUEST.
+ */
+ TALER_EC_PARAMETER_MISSING = 1008,
+
+ /**
+ * A parameter in the request to the exchange was malformed.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_BAD_REQUEST.
+ */
+ TALER_EC_PARAMETER_MALFORMED = 1009,
+
+ /* ********** request-specific error codes ************* */
+
+ /**
+ * The given reserve does not have sufficient funds to admit the
+ * requested withdraw operation at this time. The response includes
+ * the current "balance" of the reserve as well as the transaction
+ * "history" that lead to this balance. This response is provided
+ * with HTTP status code MHD_HTTP_FORBIDDEN.
+ */
+ TALER_EC_WITHDRAW_INSUFFICIENT_FUNDS = 1100,
+
+ /**
+ * The exchange has no information about the "reserve_pub" that
+ * was given.
+ * This response is provided with HTTP status code MHD_HTTP_NOT_FOUND.
+ */
+ TALER_EC_WITHDRAW_RESERVE_UNKNOWN = 1101,
+
+ /**
+ * The amount to withdraw together with the fee exceeds the
+ * numeric range for Taler amounts. This is not a client
+ * failure, as the coin value and fees come from the exchange's
+ * configuration.
+ * This response is provided with HTTP status code MHD_HTTP_INTERNAL_ERROR.
+ */
+ TALER_EC_WITHDRAW_AMOUNT_FEE_OVERFLOW = 1102,
+
+ /**
+ * All of the deposited amounts into this reserve total up to a
+ * value that is too big for the numeric range for Taler amounts.
+ * This is not a client failure, as the transaction history comes
+ * from the exchange's configuration. This response is provided
+ * with HTTP status code MHD_HTTP_INTERNAL_ERROR.
+ */
+ TALER_EC_WITHDRAW_AMOUNT_DEPOSITS_OVERFLOW = 1103,
+
+ /**
+ * For one of the historic withdrawals from this reserve, the
+ * exchange could not find the denomination key.
+ * This is not a client failure, as the transaction history comes
+ * from the exchange's configuration. This response is provided
+ * with HTTP status code MHD_HTTP_INTERNAL_ERROR.
+ */
+ TALER_EC_WITHDRAW_HISTORIC_DENOMINATION_KEY_NOT_FOUND = 1104,
+
+ /**
+ * All of the withdrawals from reserve total up to a
+ * value that is too big for the numeric range for Taler amounts.
+ * This is not a client failure, as the transaction history comes
+ * from the exchange's configuration. This response is provided
+ * with HTTP status code MHD_HTTP_INTERNAL_ERROR.
+ */
+ TALER_EC_WITHDRAW_AMOUNT_WITHDRAWALS_OVERFLOW = 1105,
+
+ /**
+ * The exchange somehow knows about this reserve, but there seem to
+ * have been no wire transfers made. This is not a client failure,
+ * as this is a database consistency issue of the exchange. This
+ * response is provided with HTTP status code
+ * MHD_HTTP_INTERNAL_ERROR.
+ */
+ TALER_EC_WITHDRAW_RESERVE_WITHOUT_WIRE_TRANSFER = 1106,
+
+ /**
+ * The exchange failed to create the signature using the
+ * denomination key. This response is provided with HTTP status
+ * code MHD_HTTP_INTERNAL_ERROR.
+ */
+ TALER_EC_WITHDRAW_SIGNATURE_FAILED = 1107,
+
+ /**
+ * The exchange failed to store the withdraw operation in its
+ * database. This response is provided with HTTP status code
+ * MHD_HTTP_INTERNAL_ERROR.
+ */
+ TALER_EC_WITHDRAW_DB_STORE_ERROR = 1108,
+
+ /**
+ * The exchange failed to check against historic withdraw data from
+ * database (as part of ensuring the idempotency of the operation).
+ * This response is provided with HTTP status code
+ * MHD_HTTP_INTERNAL_ERROR.
+ */
+ TALER_EC_WITHDRAW_DB_FETCH_ERROR = 1109,
+
+ /**
+ * The exchange is not aware of the denomination key
+ * the wallet requested for the withdrawal.
+ * This response is provided
+ * with HTTP status code MHD_HTTP_NOT_FOUND.
+ */
+ TALER_EC_WITHDRAW_DENOMINATION_KEY_NOT_FOUND = 1110,
+
+ /**
+ * The signature of the reserve is not valid. This response is
+ * provided with HTTP status code MHD_HTTP_BAD_REQUEST.
+ */
+ TALER_EC_WITHDRAW_RESERVE_SIGNATURE_INVALID = 1111,
+
+ /**
+ * The exchange failed to obtain the transaction history of the
+ * given reserve from the database while generating an insufficient
+ * funds errors.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_INTERNAL_SERVER_ERROR.
+ */
+ TALER_EC_WITHDRAW_HISTORY_DB_ERROR_INSUFFICIENT_FUNDS = 1112,
+
+ /**
+ * The exchange failed to obtain the transaction history of the
+ * given reserve from the database.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_INTERNAL_SERVER_ERROR.
+ */
+ TALER_EC_RESERVE_STATUS_DB_ERROR = 1150,
+
+
+ /**
+ * The respective coin did not have sufficient residual value
+ * for the /deposit operation (i.e. due to double spending).
+ * The "history" in the respose provides the transaction history
+ * of the coin proving this fact. This response is provided
+ * with HTTP status code MHD_HTTP_FORBIDDEN.
+ */
+ TALER_EC_DEPOSIT_INSUFFICIENT_FUNDS = 1200,
+
+ /**
+ * The exchange failed to obtain the transaction history of the
+ * given coin from the database (this does not happen merely because
+ * the coin is seen by the exchange for the first time).
+ * This response is provided with HTTP status code
+ * MHD_HTTP_INTERNAL_SERVER_ERROR.
+ */
+ TALER_EC_DEPOSIT_HISTORY_DB_ERROR = 1201,
+
+ /**
+ * The exchange failed to store the /depost information in the
+ * database. This response is provided with HTTP status code
+ * MHD_HTTP_INTERNAL_SERVER_ERROR.
+ */
+ TALER_EC_DEPOSIT_STORE_DB_ERROR = 1202,
+
+ /**
+ * The exchange database is unaware of the denomination key that
+ * signed the coin (however, the exchange process is; this is not
+ * supposed to happen; it can happen if someone decides to purge the
+ * DB behind the back of the exchange process). Hence the deposit
+ * is being refused. This response is provided with HTTP status
+ * code MHD_HTTP_INTERNAL_SERVER_ERROR.
+ */
+ TALER_EC_DEPOSIT_DB_DENOMINATION_KEY_UNKNOWN = 1203,
+
+ /**
+ * The exchange database is unaware of the denomination key that
+ * signed the coin (however, the exchange process is; this is not
+ * supposed to happen; it can happen if someone decides to purge the
+ * DB behind the back of the exchange process). Hence the deposit
+ * is being refused. This response is provided with HTTP status
+ * code MHD_HTTP_NOT_FOUND.
+ */
+ TALER_EC_DEPOSIT_DENOMINATION_KEY_UNKNOWN = 1204,
+
+ /**
+ * The signature of the coin is not valid. This response is
+ * provided with HTTP status code MHD_HTTP_BAD_REQUEST.
+ */
+ TALER_EC_DEPOSIT_COIN_SIGNATURE_INVALID = 1205,
+
+ /**
+ * The signature of the denomination key over the coin is not valid.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_BAD_REQUEST.
+ */
+ TALER_EC_DEPOSIT_DENOMINATION_SIGNATURE_INVALID = 1206,
+
+ /**
+ * The stated value of the coin after the deposit fee is subtracted
+ * would be negative.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_BAD_REQUEST.
+ */
+ TALER_EC_DEPOSIT_NEGATIVE_VALUE_AFTER_FEE = 1207,
+
+ /**
+ * The stated refund deadline is after the wire deadline.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_BAD_REQUEST.
+ */
+ TALER_EC_DEPOSIT_REFUND_DEADLINE_AFTER_WIRE_DEADLINE = 1208,
+
+ /**
+ * The exchange does not recognize the validity of or support the
+ * given wire (bank account) address. This response is provided
+ * with HTTP status code MHD_HTTP_BAD_REQUEST.
+ */
+ TALER_EC_DEPOSIT_INVALID_WIRE_FORMAT = 1209,
+
+ /**
+ * The exchange failed to canonicalize and hash the given wire format.
+ * This response is provided
+ * with HTTP status code MHD_HTTP_BAD_REQUEST.
+ */
+ TALER_EC_DEPOSIT_INVALID_WIRE_FORMAT_JSON = 1210,
+
+ /**
+ * The hash of the given wire address does not match the hash
+ * specified in the contract.
+ * This response is provided
+ * with HTTP status code MHD_HTTP_BAD_REQUEST.
+ */
+ TALER_EC_DEPOSIT_INVALID_WIRE_FORMAT_CONTRACT_HASH_CONFLICT = 1211,
+
+ /**
+ * The exchange failed to obtain the transaction history of the
+ * given coin from the database while generating an insufficient
+ * funds errors.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_INTERNAL_SERVER_ERROR.
+ */
+ TALER_EC_DEPOSIT_HISTORY_DB_ERROR_INSUFFICIENT_FUNDS = 1212,
+
+ /**
+ * The respective coin did not have sufficient residual value
+ * for the /refresh/melt operation. The "history" in this
+ * response provdes the "residual_value" of the coin, which may
+ * be less than its "original_value". This response is provided
+ * with HTTP status code MHD_HTTP_FORBIDDEN.
+ */
+ TALER_EC_REFRESH_MELT_INSUFFICIENT_FUNDS = 1300,
+
+ /**
+ * The exchange is unaware of the denomination key that was
+ * used to sign the melted coin. This response is provided
+ * with HTTP status code MHD_HTTP_NOT_FOUND.
+ */
+ TALER_EC_REFRESH_MELT_DENOMINATION_KEY_NOT_FOUND = 1301,
+
+ /**
+ * The exchange had an internal error reconstructing the
+ * transaction history of the coin that was being melted.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_INTERNAL_SERVER_ERROR.
+ */
+ TALER_EC_REFRESH_MELT_COIN_HISTORY_COMPUTATION_FAILED = 1302,
+
+ /**
+ * The exchange failed to check against historic melt data from
+ * database (as part of ensuring the idempotency of the operation).
+ * This response is provided with HTTP status code
+ * MHD_HTTP_INTERNAL_ERROR.
+ */
+ TALER_EC_REFRESH_MELT_DB_FETCH_ERROR = 1303,
+
+ /**
+ * The exchange failed to store session data in the
+ * database.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_INTERNAL_ERROR.
+ */
+ TALER_EC_REFRESH_MELT_DB_STORE_SESSION_ERROR = 1304,
+
+ /**
+ * The exchange failed to store refresh order data in the
+ * database.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_INTERNAL_ERROR.
+ */
+ TALER_EC_REFRESH_MELT_DB_STORE_ORDER_ERROR = 1305,
+
+ /**
+ * The exchange failed to store commit data in the
+ * database.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_INTERNAL_ERROR.
+ */
+ TALER_EC_REFRESH_MELT_DB_STORE_COMMIT_ERROR = 1306,
+
+ /**
+ * The exchange failed to store transfer keys in the
+ * database.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_INTERNAL_ERROR.
+ */
+ TALER_EC_REFRESH_MELT_DB_STORE_TRANSFER_ERROR = 1307,
+
+ /**
+ * The exchange is unaware of the denomination key that was
+ * requested for one of the fresh coins. This response is provided
+ * with HTTP status code MHD_HTTP_BAD_REQUEST.
+ */
+ TALER_EC_REFRESH_MELT_FRESH_DENOMINATION_KEY_NOT_FOUND = 1308,
+
+ /**
+ * The exchange encountered a numeric overflow totaling up
+ * the cost for the refresh operation. This response is provided
+ * with HTTP status code MHD_HTTP_INTERNAL_SERVER_ERROR.
+ */
+ TALER_EC_REFRESH_MELT_COST_CALCULATION_OVERFLOW = 1309,
+
+ /**
+ * During the transaction phase, the exchange could suddenly
+ * no longer find the denomination key that was
+ * used to sign the melted coin. This response is provided
+ * with HTTP status code MHD_HTTP_INTERNAL_SERVER_ERROR.
+ */
+ TALER_EC_REFRESH_MELT_DB_DENOMINATION_KEY_NOT_FOUND = 1310,
+
+ /**
+ * The exchange encountered melt fees exceeding the melted
+ * coin's contribution. This response is provided
+ * with HTTP status code MHD_HTTP_BAD_REQUEST.
+ */
+ TALER_EC_REFRESH_MELT_FEES_EXCEED_CONTRIBUTION = 1311,
+
+ /**
+ * The exchange's cost calculation does not add up to the
+ * melt fees specified in the request. This response is provided
+ * with HTTP status code MHD_HTTP_BAD_REQUEST.
+ */
+ TALER_EC_REFRESH_MELT_FEES_MISSMATCH = 1312,
+
+ /**
+ * The denomination key signature on the melted coin is invalid.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_BAD_REQUEST.
+ */
+ TALER_EC_REFRESH_MELT_DENOMINATION_SIGNATURE_INVALID = 1313,
+
+ /**
+ * The exchange's cost calculation shows that the melt amount
+ * is below the costs of the transaction. This response is provided
+ * with HTTP status code MHD_HTTP_BAD_REQUEST.
+ */
+ TALER_EC_REFRESH_MELT_AMOUNT_INSUFFICIENT = 1314,
+
+ /**
+ * The signature made with the coin to be melted is invalid.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_BAD_REQUEST.
+ */
+ TALER_EC_REFRESH_MELT_COIN_SIGNATURE_INVALID = 1315,
+
+ /**
+ * The size of the cut-and-choose dimension of the
+ * blinded coins request does not match #TALER_CNC_KAPPA.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_BAD_REQUEST.
+ */
+ TALER_EC_REFRESH_MELT_CNC_COIN_ARRAY_SIZE_INVALID = 1316,
+
+ /**
+ * The size of the cut-and-choose dimension of the
+ * transfer keys request does not match #TALER_CNC_KAPPA.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_BAD_REQUEST.
+ */
+ TALER_EC_REFRESH_MELT_CNC_TRANSFER_ARRAY_SIZE_INVALID = 1317,
+
+ /**
+ * The exchange failed to obtain the transaction history of the
+ * given coin from the database while generating an insufficient
+ * funds errors.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_INTERNAL_SERVER_ERROR.
+ */
+ TALER_EC_REFRESH_MELT_HISTORY_DB_ERROR_INSUFFICIENT_FUNDS = 1318,
+
+ /**
+ * The provided transfer keys do not match up with the
+ * original commitment. Information about the original
+ * commitment is included in the response. This response is
+ * provided with HTTP status code MHD_HTTP_CONFLICT.
+ */
+ TALER_EC_REFRESH_REVEAL_COMMITMENT_VIOLATION = 1350,
+
+ /**
+ * Failed to blind the envelope to reconstruct the blinded
+ * coins for revealation checks.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_INTERNAL_ERROR.
+ */
+ TALER_EC_REFRESH_REVEAL_BLINDING_ERROR = 1351,
+
+ /**
+ * Failed to produce the blinded signatures over the coins
+ * to be returned.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_INTERNAL_ERROR.
+ */
+ TALER_EC_REFRESH_REVEAL_SIGNING_ERROR = 1352,
+
+ /**
+ * The exchange is unaware of the refresh sessino specified in
+ * the request.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_BAD_REQUEST.
+ */
+ TALER_EC_REFRESH_REVEAL_SESSION_UNKNOWN = 1353,
+
+ /**
+ * The exchange failed to retrieve valid session data from the
+ * database.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_INTERNAL_ERROR.
+ */
+ TALER_EC_REFRESH_REVEAL_DB_FETCH_SESSION_ERROR = 1354,
+
+ /**
+ * The exchange failed to retrieve order data from the
+ * database.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_INTERNAL_ERROR.
+ */
+ TALER_EC_REFRESH_REVEAL_DB_FETCH_ORDER_ERROR = 1355,
+
+ /**
+ * The exchange failed to retrieve transfer keys from the
+ * database.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_INTERNAL_ERROR.
+ */
+ TALER_EC_REFRESH_REVEAL_DB_FETCH_TRANSFER_ERROR = 1356,
+
+ /**
+ * The exchange failed to retrieve commitment data from the
+ * database.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_INTERNAL_ERROR.
+ */
+ TALER_EC_REFRESH_REVEAL_DB_FETCH_COMMIT_ERROR = 1357,
+
+ /**
+ * The size of the cut-and-choose dimension of the
+ * private transfer keys request does not match #TALER_CNC_KAPPA - 1.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_BAD_REQUEST.
+ */
+ TALER_EC_REFRESH_REVEAL_CNC_TRANSFER_ARRAY_SIZE_INVALID = 1358,
+
+
+ /**
+ * The coin specified in the link request is unknown to the exchange.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_NOT_FOUND.
+ */
+ TALER_EC_REFRESH_LINK_COIN_UNKNOWN = 1400,
+
+
+ /**
+ * The exchange knows literally nothing about the coin we were asked
+ * to refund. But without a transaction history, we cannot issue a
+ * refund. This is kind-of OK, the owner should just refresh it
+ * directly without executing the refund. This response is provided
+ * with HTTP status code MHD_HTTP_NOT_FOUND.
+ */
+ TALER_EC_REFUND_COIN_NOT_FOUND = 1500,
+
+ /**
+ * We could not process the refund request as the coin's transaction
+ * history does not permit the requested refund at this time. The
+ * "history" in the response proves this. This response is provided
+ * with HTTP status code MHD_HTTP_CONFLICT.
+ */
+ TALER_EC_REFUND_CONFLICT = 1501,
+
+ /**
+ * The exchange knows about the coin we were asked to refund, but
+ * not about the specific /deposit operation. Hence, we cannot
+ * issue a refund (as we do not know if this merchant public key is
+ * authorized to do a refund). This response is provided with HTTP
+ * status code MHD_HTTP_NOT_FOUND.
+ */
+ TALER_EC_REFUND_DEPOSIT_NOT_FOUND = 1503,
+
+ /**
+ * The currency specified for the refund is different from
+ * the currency of the coin. This response is provided with HTTP
+ * status code MHD_HTTP_PRECONDITION_FAILED.
+ */
+ TALER_EC_REFUND_CURRENCY_MISSMATCH = 1504,
+
+ /**
+ * When we tried to check if we already paid out the coin, the
+ * exchange's database suddenly disagreed with data it previously
+ * provided (internal inconsistency).
+ * This response is provided with HTTP status code
+ * MHD_HTTP_INTERNAL_SERVER_ERROR.
+ */
+ TALER_EC_REFUND_DB_INCONSISTENT = 1505,
+ /**
+ * The exchange can no longer refund the customer/coin as the
+ * money was already transferred (paid out) to the merchant.
+ * (It should be past the refund deadline.)
+ * This response is provided with HTTP status code
+ * MHD_HTTP_GONE.
+ */
+ TALER_EC_REFUND_MERCHANT_ALREADY_PAID = 1506,
+
+ /**
+ * The amount the exchange was asked to refund exceeds
+ * (with fees) the total amount of the deposit (including fees).
+ * This response is provided with HTTP status code
+ * MHD_HTTP_PRECONDITION_FAILED.
+ */
+ TALER_EC_REFUND_INSUFFICIENT_FUNDS = 1507,
+
+ /**
+ * The exchange failed to recover information about the
+ * denomination key of the refunded coin (even though it
+ * recognizes the key). Hence it could not check the fee
+ * strucutre.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_INTERNAL_SERVER_ERROR.
+ */
+ TALER_EC_REFUND_DENOMINATION_KEY_NOT_FOUND = 1508,
+
+ /**
+ * The refund fee specified for the request is lower than
+ * the refund fee charged by the exchange for the given
+ * denomination key of the refunded coin.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_BAD_REQUEST.
+ */
+ TALER_EC_REFUND_FEE_TOO_LOW = 1509,
+
+ /**
+ * The exchange failed to store the refund information to
+ * its database.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_INTERNAL_SERVER_ERROR.
+ */
+ TALER_EC_REFUND_STORE_DB_ERROR = 1510,
+
+ /**
+ * The refund fee is specified in a different currency
+ * than the refund amount.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_BAD_REQUEST.
+ */
+ TALER_EC_REFUND_FEE_CURRENCY_MISSMATCH = 1511,
+
+ /**
+ * The refunded amount is smaller than the refund fee,
+ * which would result in a negative refund.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_BAD_REQUEST.
+ */
+ TALER_EC_REFUND_FEE_ABOVE_AMOUNT = 1512,
+
+ /**
+ * The signature of the merchant is invalid.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_BAD_REQUEST.
+ */
+ TALER_EC_REFUND_MERCHANT_SIGNATURE_INVALID = 1513,
+
+
+ /**
+ * The wire format specified in the "sender_account_details"
+ * is not understood or not supported by this exchange.
+ * Returned with an HTTP status code of MHD_HTTP_NOT_FOUND.
+ * (As we did not find an interpretation of the wire format.)
+ */
+ TALER_EC_ADMIN_ADD_INCOMING_WIREFORMAT_UNSUPPORTED = 1600,
+
+ /**
+ * The currency specified in the "amount" parameter is not
+ * supported by this exhange. Returned with an HTTP status
+ * code of MHD_HTTP_BAD_REQUEST.
+ */
+ TALER_EC_ADMIN_ADD_INCOMING_CURRENCY_UNSUPPORTED = 1601,
+
+ /**
+ * The exchange failed to store information about the incoming
+ * transfer in its database. This response is provided with HTTP
+ * status code MHD_HTTP_INTERNAL_SERVER_ERROR.
+ */
+ TALER_EC_ADMIN_ADD_INCOMING_DB_STORE = 1602,
+
+ /**
+ * The exchange encountered an error (that is not about not finding
+ * the wire transfer) trying to lookup a wire transfer identifier
+ * in the database. This response is provided with HTTP
+ * status code MHD_HTTP_INTERNAL_SERVER_ERROR.
+ */
+ TALER_EC_TRACK_TRANSFER_DB_FETCH_FAILED = 1700,
+
+ /**
+ * The exchange found internally inconsistent data when resolving a
+ * wire transfer identifier in the database. This response is
+ * provided with HTTP status code MHD_HTTP_INTERNAL_SERVER_ERROR.
+ */
+ TALER_EC_TRACK_TRANSFER_DB_INCONSISTENT = 1701,
+
+ /**
+ * The exchange did not find information about the specified
+ * wire transfer identifier in the database. This response is
+ * provided with HTTP status code MHD_HTTP_NOT_FOUND.
+ */
+ TALER_EC_TRACK_TRANSFER_WTID_NOT_FOUND = 1702,
+
+
+ /**
+ * The exchange found internally inconsistent fee data when
+ * resolving a transaction in the database. This
+ * response is provided with HTTP status code
+ * MHD_HTTP_INTERNAL_SERVER_ERROR.
+ */
+ TALER_EC_TRACK_TRANSACTION_DB_FEE_INCONSISTENT = 1800,
+
+ /**
+ * The exchange encountered an error (that is not about not finding
+ * the transaction) trying to lookup a transaction
+ * in the database. This response is provided with HTTP
+ * status code MHD_HTTP_INTERNAL_SERVER_ERROR.
+ */
+ TALER_EC_TRACK_TRANSACTION_DB_FETCH_FAILED = 1801,
+
+ /**
+ * The exchange did not find information about the specified
+ * transaction in the database. This response is
+ * provided with HTTP status code MHD_HTTP_NOT_FOUND.
+ */
+ TALER_EC_TRACK_TRANSACTION_NOT_FOUND = 1802,
+
+ /**
+ * The exchange failed to identify the wire transfer of the
+ * transaction (or information about the plan that it was supposed
+ * to still happen in the future). This response is provided with
+ * HTTP status code MHD_HTTP_INTERNAL_SERVER_ERROR.
+ */
+ TALER_EC_TRACK_TRANSACTION_WTID_RESOLUTION_ERROR = 1803,
+
+ /**
+ * The signature of the merchant is invalid.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_BAD_REQUEST.
+ */
+ TALER_EC_TRACK_TRANSACTION_MERCHANT_SIGNATURE_INVALID = 1804,
+
+
+ /* *********** Merchant backend error codes ********* */
+
+ /**
+ * The backend could not find the merchant instance specified
+ * in the request. This response is
+ * provided with HTTP status code MHD_HTTP_NOT_FOUND.
+ */
+ TALER_EC_CONTRACT_INSTANCE_UNKNOWN = 2000,
+
+ /**
+ * The exchange failed to provide a meaningful response
+ * to a /deposit request. This response is provided
+ * with HTTP status code MHD_HTTP_SERVICE_UNAVAILABLE.
+ */
+ TALER_EC_PAY_EXCHANGE_FAILED = 2101,
+
+ /**
+ * The merchant failed to commit the exchanges' response to
+ * a /deposit request to its database. This response is provided
+ * with HTTP status code MHD_HTTP_INTERNAL_SERVER_ERROR.
+ */
+ TALER_EC_PAY_DB_STORE_PAY_ERROR = 2102,
+
+ /**
+ * The specified exchange is not supported/trusted by
+ * this merchant. This response is provided
+ * with HTTP status code MHD_HTTP_PRECONDITION_FAILED.
+ */
+ TALER_EC_PAY_EXCHANGE_REJECTED = 2103,
+
+ /**
+ * The denomination key used for payment is not listed among the
+ * denomination keys of the exchange. This response is provided
+ * with HTTP status code MHD_HTTP_BAD_REQUEST.
+ */
+ TALER_EC_PAY_DENOMINATION_KEY_NOT_FOUND = 2104,
+
+ /**
+ * The denomination key used for payment is not audited by an
+ * auditor approved by the merchant. This response is provided
+ * with HTTP status code MHD_HTTP_BAD_REQUEST.
+ */
+ TALER_EC_PAY_DENOMINATION_KEY_AUDITOR_FAILURE = 2105,
+
+ /**
+ * There was an integer overflow totaling up the amounts or
+ * deposit fees in the payment. This response is provided
+ * with HTTP status code MHD_HTTP_BAD_REQUEST.
+ */
+ TALER_EC_PAY_AMOUNT_OVERFLOW = 2106,
+
+ /**
+ * The deposit fees exceed the total value of the payment.
+ * This response is provided
+ * with HTTP status code MHD_HTTP_BAD_REQUEST.
+ */
+ TALER_EC_PAY_FEES_EXCEED_PAYMENT = 2107,
+
+ /**
+ * After considering deposit fees, the payment is insufficient
+ * to satisfy the required amount for the contract.
+ * This response is provided
+ * with HTTP status code MHD_HTTP_BAD_REQUEST.
+ */
+ TALER_EC_PAY_PAYMENT_INSUFFICIENT_DUE_TO_FEES = 2108,
+
+ /**
+ * While the merchant is happy to cover all applicable deposit fees,
+ * the payment is insufficient to satisfy the required amount for
+ * the contract. This response is provided with HTTP status code
+ * MHD_HTTP_BAD_REQUEST.
+ */
+ TALER_EC_PAY_PAYMENT_INSUFFICIENT = 2109,
+
+ /**
+ * The signature over the contract of one of the coins
+ * was invalid. This response is provided with HTTP status code
+ * MHD_HTTP_BAD_REQUEST.
+ */
+ TALER_EC_PAY_COIN_SIGNATURE_INVALID = 2110,
+
+ /**
+ * We failed to contact the exchange for the /pay request.
+ * This response is provided
+ * with HTTP status code MHD_HTTP_SERVICE_UNAVAILABLE.
+ */
+ TALER_EC_PAY_EXCHANGE_TIMEOUT = 2111,
+
+ /**
+ * The backend could not find the merchant instance specified
+ * in the request. This response is
+ * provided with HTTP status code MHD_HTTP_NOT_FOUND.
+ */
+ TALER_EC_PAY_INSTANCE_UNKNOWN = 2112,
+
+ /**
+ * The signature over the contract of the merchant
+ * was invalid. This response is provided with HTTP status code
+ * MHD_HTTP_BAD_REQUEST.
+ */
+ TALER_EC_PAY_MERCHANT_SIGNATURE_INVALID = 2113,
+
+ /**
+ * The refund deadline was after the transfer deadline.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_BAD_REQUEST.
+ */
+ TALER_EC_PAY_REFUND_DEADLINE_PAST_WIRE_TRANSFER_DEADLINE = 2114,
+
+ /**
+ * The request fails to provide coins for the payment.
+ * This response is provided with HTTP status code
+ * MHD_HTTP_BAD_REQUEST.
+ */
+ TALER_EC_PAY_COINS_ARRAY_EMPTY = 2115,
+
+ /**
+ * The merchant failed to fetch the merchant's previous state with
+ * respect to a /pay request from its database. This response is
+ * provided with HTTP status code MHD_HTTP_INTERNAL_SERVER_ERROR.
+ */
+ TALER_EC_PAY_DB_FETCH_PAY_ERROR = 2116,
+
+ /**
+ * The merchant failed to fetch the merchant's previous state with
+ * respect to transactions from its database. This response is
+ * provided with HTTP status code MHD_HTTP_INTERNAL_SERVER_ERROR.
+ */
+ TALER_EC_PAY_DB_FETCH_TRANSACTION_ERROR = 2117,
+
+ /**
+ * The transaction ID was used for a conflicing transaction before.
+ * This response is
+ * provided with HTTP status code MHD_HTTP_BAD_REQUEST.
+ */
+ TALER_EC_PAY_DB_TRANSACTION_ID_CONFLICT = 2118,
+
+ /**
+ * The merchant failed to store the merchant's state with
+ * respect to the transaction in its database. This response is
+ * provided with HTTP status code MHD_HTTP_INTERNAL_SERVER_ERROR.
+ */
+ TALER_EC_PAY_DB_STORE_TRANSACTION_ERROR = 2119,
+
+ /**
+ * The exchange failed to provide a valid response to
+ * the merchant's /keys request.
+ * This response is provided
+ * with HTTP status code MHD_HTTP_SERVICE_UNAVAILABLE.
+ */
+ TALER_EC_PAY_EXCHANGE_KEYS_FAILURE = 2120,
+
+ /**
+ * The payment is too late, the offer has expired.
+ * This response is
+ * provided with HTTP status code MHD_HTTP_BAD_REQUEST.
+ */
+ TALER_EC_PAY_OFFER_EXPIRED = 2121,
+
+
+ /**
+ * Integer overflow with sepcified timestamp argument detected.
+ * This response is provided
+ * with HTTP status code MHD_HTTP_BAD_REQUEST.
+ */
+ TALER_EC_HISTORY_TIMESTAMP_OVERFLOW = 2200,
+
+ /**
+ * Failed to retrieve history from merchant database.
+ * This response is provided
+ * with HTTP status code MHD_HTTP_INTERNAL_SERVER_ERROR.
+ */
+ TALER_EC_HISTORY_DB_FETCH_ERROR = 2201,
+
+
+ /**
+ * We failed to contact the exchange for the /track/transaction
+ * request. This response is provided with HTTP status code
+ * MHD_HTTP_SERVICE_UNAVAILABLE.
+ */
+ TALER_EC_TRACK_TRANSACTION_EXCHANGE_TIMEOUT = 2300,
+
+ /**
+ * The backend could not find the merchant instance specified
+ * in the request. This response is
+ * provided with HTTP status code MHD_HTTP_NOT_FOUND.
+ */
+ TALER_EC_TRACK_TRANSACTION_INSTANCE_UNKNOWN = 2301,
+
+ /**
+ * The backend could not find the transaction specified
+ * in the request. This response is
+ * provided with HTTP status code MHD_HTTP_NOT_FOUND.
+ */
+ TALER_EC_TRACK_TRANSACTION_TRANSACTION_UNKNOWN = 2302,
+
+ /**
+ * The backend had a database access error trying to
+ * retrieve transaction data from its database.
+ * The response is
+ * provided with HTTP status code MHD_HTTP_INTERNAL_SERVER_ERROR.
+ */
+ TALER_EC_TRACK_TRANSACTION_DB_FETCH_TRANSACTION_ERROR = 2303,
+
+ /**
+ * The backend had a database access error trying to
+ * retrieve payment data from its database.
+ * The response is
+ * provided with HTTP status code MHD_HTTP_INTERNAL_SERVER_ERROR.
+ */
+ TALER_EC_TRACK_TRANSACTION_DB_FETCH_PAYMENT_ERROR = 2304,
+
+ /**
+ * The backend found no applicable deposits in the database.
+ * This is odd, as we know about the transaction, but not
+ * about deposits we made for the transaction. The response is
+ * provided with HTTP status code MHD_HTTP_NOT_FOUND.
+ */
+ TALER_EC_TRACK_TRANSACTION_DB_NO_DEPOSITS_ERROR = 2305,
+
+ /**
+ * We failed to obtain a wire transfer identifier for one
+ * of the coins in the transaction. The response is
+ * provided with HTTP status code MHD_HTTP_FAILED_DEPENDENCY if
+ * the exchange had a hard error, or MHD_HTTP_ACCEPTED if the
+ * exchange signaled that the transfer was in progress.
+ */
+ TALER_EC_TRACK_TRANSACTION_COIN_TRACE_ERROR = 2306,
+
+ /**
+ * We failed to obtain the full wire transfer identifier for the
+ * transfer one of the coins was aggregated into.
+ * The response is
+ * provided with HTTP status code MHD_HTTP_FAILED_DEPENDENCY.
+ */
+ TALER_EC_TRACK_TRANSACTION_WIRE_TRANSFER_TRACE_ERROR = 2307,
+
+ /**
+ * We got conflicting reports from the exhange with
+ * respect to which transfers are included in which
+ * aggregate.
+ * The response is
+ * provided with HTTP status code MHD_HTTP_FAILED_DEPENDENCY.
+ */
+ TALER_EC_TRACK_TRANSACTION_CONFLICTING_REPORTS = 2308,
+
+
+ /**
+ * We failed to contact the exchange for the /track/transfer
+ * request. This response is provided with HTTP status code
+ * MHD_HTTP_SERVICE_UNAVAILABLE.
+ */
+ TALER_EC_TRACK_TRANSFER_EXCHANGE_TIMEOUT = 2400,
+
+ /**
+ * The backend could not find the merchant instance specified
+ * in the request. This response is
+ * provided with HTTP status code MHD_HTTP_NOT_FOUND.
+ */
+ TALER_EC_TRACK_TRANSFER_INSTANCE_UNKNOWN = 2401,
+
+ /**
+ * We failed to persist coin wire transfer information in
+ * our merchant database.
+ * The response is
+ * provided with HTTP status code MHD_HTTP_INTERNAL_SERVER_ERROR.
+ */
+ TALER_EC_TRACK_TRANSFER_DB_STORE_COIN_ERROR = 2402,
+
+ /**
+ * We internally failed to execute the /track/transfer request.
+ * The response is
+ * provided with HTTP status code MHD_HTTP_INTERNAL_SERVER_ERROR.
+ */
+ TALER_EC_TRACK_TRANSFER_REQUEST_ERROR = 2403,
+
+ /**
+ * We failed to persist wire transfer information in
+ * our merchant database.
+ * The response is
+ * provided with HTTP status code MHD_HTTP_INTERNAL_SERVER_ERROR.
+ */
+ TALER_EC_TRACK_TRANSFER_DB_STORE_TRANSFER_ERROR = 2404,
+
+ /**
+ * The exchange returned an error from /track/transfer.
+ * The response is
+ * provided with HTTP status code MHD_HTTP_FAILED_DEPENDENCY.
+ */
+ TALER_EC_TRACK_TRANSFER_EXCHANGE_ERROR = 2405,
+
+ /**
+ * We failed to fetch deposit information from
+ * our merchant database.
+ * The response is
+ * provided with HTTP status code MHD_HTTP_INTERNAL_SERVER_ERROR.
+ */
+ TALER_EC_TRACK_TRANSFER_DB_FETCH_DEPOSIT_ERROR = 2406,
+
+ /**
+ * We encountered an internal logic error.
+ * The response is
+ * provided with HTTP status code MHD_HTTP_INTERNAL_SERVER_ERROR.
+ */
+ TALER_EC_TRACK_TRANSFER_DB_INTERNAL_LOGIC_ERROR = 2407,
+
+ /**
+ * The exchange gave conflicting information about a coin which has
+ * been wire transferred.
+ * The response is
+ * provided with HTTP status code MHD_HTTP_INTERNAL_SERVER_ERROR.
+ */
+ TALER_EC_TRACK_TRANSFER_CONFLICTING_REPORTS = 2408,
+
+ /* ********** /test API error codes ************* */
+
+ /**
+ * The exchange failed to compute ECDH. This response is provided
+ * with HTTP status code MHD_HTTP_INTERNAL_SERVER_ERROR.
+ */
+ TALER_EC_TEST_ECDH_ERROR = 4000,
+
+ /**
+ * The EdDSA test signature is invalid. This response is provided
+ * with HTTP status code MHD_HTTP_BAD_REQUEST.
+ */
+ TALER_EC_TEST_EDDSA_INVALID = 4001,
+
+ /**
+ * The exchange failed to compute the EdDSA test signature. This response is provided
+ * with HTTP status code MHD_HTTP_INTERNAL_SERVER_ERROR.
+ */
+ TALER_EC_TEST_EDDSA_ERROR = 4002,
+
+ /**
+ * The exchange failed to generate an RSA key. This response is provided
+ * with HTTP status code MHD_HTTP_INTERNAL_SERVER_ERROR.
+ */
+ TALER_EC_TEST_RSA_GEN_ERROR = 4003,
+
+ /**
+ * The exchange failed to compute the public RSA key. This response
+ * is provided with HTTP status code MHD_HTTP_INTERNAL_SERVER_ERROR.
+ */
+ TALER_EC_TEST_RSA_PUB_ERROR = 4004,
+
+ /**
+ * The exchange failed to compute the RSA signature. This response
+ * is provided with HTTP status code MHD_HTTP_INTERNAL_SERVER_ERROR.
+ */
+ TALER_EC_TEST_RSA_SIGN_ERROR = 4005,
+
+
+ /**
+ * End of error code range.
+ */
+ TALER_EC_END = 9999
+
};
diff --git a/src/include/taler_exchange_service.h b/src/include/taler_exchange_service.h
index 9e3c48c4c..e368f954c 100644
--- a/src/include/taler_exchange_service.h
+++ b/src/include/taler_exchange_service.h
@@ -24,6 +24,7 @@
#include <jansson.h>
#include "taler_util.h"
+#include "taler_error_codes.h"
#include <gnunet/gnunet_curl_lib.h>
@@ -355,6 +356,7 @@ struct TALER_EXCHANGE_WireHandle;
* @param cls closure
* @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful request;
* 0 if the exchange's reply is bogus (fails to follow the protocol)
+ * @param ec taler-specific error code, #TALER_EC_NONE on success
* @param obj the received JSON reply, if successful this should be the wire
* format details as provided by /wire, or NULL if the
* reply was not in JSON format.
@@ -362,6 +364,7 @@ struct TALER_EXCHANGE_WireHandle;
typedef void
(*TALER_EXCHANGE_WireResultCallback) (void *cls,
unsigned int http_status,
+ enum TALER_ErrorCode ec,
const json_t *obj);
@@ -423,6 +426,7 @@ struct TALER_EXCHANGE_DepositHandle;
typedef void
(*TALER_EXCHANGE_DepositResultCallback) (void *cls,
unsigned int http_status,
+ enum TALER_ErrorCode ec,
const struct TALER_ExchangePublicKeyP *sign_key,
const json_t *obj);
@@ -504,6 +508,7 @@ struct TALER_EXCHANGE_RefundHandle;
* @param cls closure
* @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful deposit;
* 0 if the exchange's reply is bogus (fails to follow the protocol)
+ * @param ec taler-specific error code, #TALER_EC_NONE on success
* @param sign_key exchange key used to sign @a obj, or NULL
* @param obj the received JSON reply, should be kept as proof (and, in particular,
* be forwarded to the customer)
@@ -511,6 +516,7 @@ struct TALER_EXCHANGE_RefundHandle;
typedef void
(*TALER_EXCHANGE_RefundResultCallback) (void *cls,
unsigned int http_status,
+ enum TALER_ErrorCode ec,
const struct TALER_ExchangePublicKeyP *sign_key,
const json_t *obj);
@@ -650,6 +656,7 @@ struct TALER_EXCHANGE_ReserveHistory
* @param cls closure
* @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful status request
* 0 if the exchange's reply is bogus (fails to follow the protocol)
+ * @param ec taler-specific error code, #TALER_EC_NONE on success
* @param[in] json original response in JSON format (useful only for diagnostics)
* @param balance current balance in the reserve, NULL on error
* @param history_length number of entries in the transaction history, 0 on error
@@ -658,6 +665,7 @@ struct TALER_EXCHANGE_ReserveHistory
typedef void
(*TALER_EXCHANGE_ReserveStatusResultCallback) (void *cls,
unsigned int http_status,
+ enum TALER_ErrorCode ec,
const json_t *json,
const struct TALER_Amount *balance,
unsigned int history_length,
@@ -713,12 +721,14 @@ struct TALER_EXCHANGE_ReserveWithdrawHandle;
* @param cls closure
* @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful status request
* 0 if the exchange's reply is bogus (fails to follow the protocol)
+ * @param ec taler-specific error code, #TALER_EC_NONE on success
* @param sig signature over the coin, NULL on error
* @param full_response full response from the exchange (for logging, in case of errors)
*/
typedef void
(*TALER_EXCHANGE_ReserveWithdrawResultCallback) (void *cls,
unsigned int http_status,
+ enum TALER_ErrorCode ec,
const struct TALER_DenominationSignature *sig,
const json_t *full_response);
@@ -835,6 +845,7 @@ struct TALER_EXCHANGE_RefreshMeltHandle;
* @param cls closure
* @param http_status HTTP response code, never #MHD_HTTP_OK (200) as for successful intermediate response this callback is skipped.
* 0 if the exchange's reply is bogus (fails to follow the protocol)
+ * @param ec taler-specific error code, #TALER_EC_NONE on success
* @param noreveal_index choice by the exchange in the cut-and-choose protocol,
* UINT16_MAX on error
* @param sign_key exchange key used to sign @a full_response, or NULL
@@ -843,7 +854,8 @@ struct TALER_EXCHANGE_RefreshMeltHandle;
typedef void
(*TALER_EXCHANGE_RefreshMeltCallback) (void *cls,
unsigned int http_status,
- uint16_t noreveal_index,
+ enum TALER_ErrorCode ec,
+ uint16_t noreveal_index,
const struct TALER_ExchangePublicKeyP *sign_key,
const json_t *full_response);
@@ -900,6 +912,7 @@ TALER_EXCHANGE_refresh_melt_cancel (struct TALER_EXCHANGE_RefreshMeltHandle *rmh
* @param cls closure
* @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful status request
* 0 if the exchange's reply is bogus (fails to follow the protocol)
+ * @param ec taler-specific error code, #TALER_EC_NONE on success
* @param num_coins number of fresh coins created, length of the @a sigs and @a coin_privs arrays, 0 if the operation failed
* @param coin_privs array of @a num_coins private keys for the coins that were created, NULL on error
* @param sigs array of signature over @a num_coins coins, NULL on error
@@ -908,6 +921,7 @@ TALER_EXCHANGE_refresh_melt_cancel (struct TALER_EXCHANGE_RefreshMeltHandle *rmh
typedef void
(*TALER_EXCHANGE_RefreshRevealCallback) (void *cls,
unsigned int http_status,
+ enum TALER_ErrorCode ec,
unsigned int num_coins,
const struct TALER_CoinSpendPrivateKeyP *coin_privs,
const struct TALER_DenominationSignature *sigs,
@@ -979,6 +993,7 @@ struct TALER_EXCHANGE_RefreshLinkHandle;
* @param cls closure
* @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful status request
* 0 if the exchange's reply is bogus (fails to follow the protocol)
+ * @param ec taler-specific error code, #TALER_EC_NONE on success
* @param num_coins number of fresh coins created, length of the @a sigs and @a coin_privs arrays, 0 if the operation failed
* @param coin_privs array of @a num_coins private keys for the coins that were created, NULL on error
* @param sigs array of signature over @a num_coins coins, NULL on error
@@ -988,6 +1003,7 @@ struct TALER_EXCHANGE_RefreshLinkHandle;
typedef void
(*TALER_EXCHANGE_RefreshLinkCallback) (void *cls,
unsigned int http_status,
+ enum TALER_ErrorCode ec,
unsigned int num_coins,
const struct TALER_CoinSpendPrivateKeyP *coin_privs,
const struct TALER_DenominationSignature *sigs,
@@ -1043,11 +1059,13 @@ struct TALER_EXCHANGE_AdminAddIncomingHandle;
* @param cls closure
* @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful status request
* 0 if the exchange's reply is bogus (fails to follow the protocol)
+ * @param ec taler-specific error code, #TALER_EC_NONE on success
* @param full_response full response from the exchange (for logging, in case of errors)
*/
typedef void
(*TALER_EXCHANGE_AdminAddIncomingResultCallback) (void *cls,
unsigned int http_status,
+ enum TALER_ErrorCode ec,
const json_t *full_response);
@@ -1108,6 +1126,7 @@ struct TALER_EXCHANGE_TrackTransferHandle;
*
* @param cls closure
* @param http_status HTTP status code we got, 0 on exchange protocol violation
+ * @param ec taler-specific error code, #TALER_EC_NONE on success
* @param sign_key exchange key used to sign @a json, or NULL
* @param json original json reply (may include signatures, those have then been
* validated already)
@@ -1121,6 +1140,7 @@ struct TALER_EXCHANGE_TrackTransferHandle;
typedef void
(*TALER_EXCHANGE_TrackTransferCallback)(void *cls,
unsigned int http_status,
+ enum TALER_ErrorCode ec,
const struct TALER_ExchangePublicKeyP *sign_key,
const json_t *json,
const struct GNUNET_HashCode *h_wire,
@@ -1171,6 +1191,7 @@ struct TALER_EXCHANGE_TrackTransactionHandle;
*
* @param cls closure
* @param http_status HTTP status code we got, 0 on exchange protocol violation
+ * @param ec taler-specific error code, #TALER_EC_NONE on success
* @param sign_key exchange key used to sign @a json, or NULL
* @param json original json reply (may include signatures, those have then been
* validated already)
@@ -1182,6 +1203,7 @@ struct TALER_EXCHANGE_TrackTransactionHandle;
typedef void
(*TALER_EXCHANGE_TrackTransactionCallback)(void *cls,
unsigned int http_status,
+ enum TALER_ErrorCode ec,
const struct TALER_ExchangePublicKeyP *sign_key,
const json_t *json,
const struct TALER_WireTransferIdentifierRawP *wtid,
@@ -1240,4 +1262,5 @@ TALER_EXCHANGE_verify_coin_history (const char *currency,
json_t *history,
struct TALER_Amount *total);
+
#endif /* _TALER_EXCHANGE_SERVICE_H */
diff --git a/src/include/taler_json_lib.h b/src/include/taler_json_lib.h
index b47aea5b6..b247ba1f5 100644
--- a/src/include/taler_json_lib.h
+++ b/src/include/taler_json_lib.h
@@ -25,6 +25,7 @@
#include <jansson.h>
#include <gnunet/gnunet_json_lib.h>
#include "taler_util.h"
+#include "taler_error_codes.h"
/**
* Print JSON parsing related error information
@@ -92,6 +93,17 @@ int
TALER_JSON_hash (const json_t *json,
struct GNUNET_HashCode *hc);
+/**
+ * Extract the Taler error code from the given @a json object.
+ * Note that #TALER_EC_NONE is returned if no "code" is present.
+ *
+ * @param json response to extract the error code from
+ * @return the "code" value from @a json
+ */
+enum TALER_ErrorCode
+TALER_JSON_get_error_code (const json_t *json);
+
+
#endif /* TALER_JSON_LIB_H_ */
/* End of taler_json_lib.h */
diff --git a/src/include/taler_util.h b/src/include/taler_util.h
index 613f860cd..c115594f5 100644
--- a/src/include/taler_util.h
+++ b/src/include/taler_util.h
@@ -117,4 +117,6 @@ const struct GNUNET_OS_ProjectData *
TALER_project_data_default (void);
+
+
#endif
diff --git a/src/json/json.c b/src/json/json.c
index 8f21447ec..74559e6c5 100644
--- a/src/json/json.c
+++ b/src/json/json.c
@@ -50,4 +50,33 @@ TALER_JSON_hash (const json_t *json,
}
+
+/**
+ * Extract the Taler error code from the given @a json object.
+ * Note that #TALER_EC_NONE is returned if no "code" is present.
+ *
+ * @param json response to extract the error code from
+ * @return the "code" value from @a json
+ */
+enum TALER_ErrorCode
+TALER_JSON_get_error_code (const json_t *json)
+{
+ const json_t *jc;
+
+ if (NULL == json)
+ {
+ GNUNET_break_op (0);
+ return TALER_EC_INVALID_RESPONSE;
+ }
+ jc = json_object_get (json, "code");
+ if (NULL == jc)
+ return TALER_EC_NONE;
+ if (json_is_integer (jc))
+ return (enum TALER_ErrorCode) json_integer_value (jc);
+ GNUNET_break_op (0);
+ return TALER_EC_INVALID;
+}
+
+
+
/* End of json/json.c */