diff options
Diffstat (limited to 'src/auditordb')
-rw-r--r-- | src/auditordb/Makefile.am | 23 | ||||
-rw-r--r-- | src/auditordb/plugin_auditordb_postgres.c | 1824 | ||||
-rw-r--r-- | src/auditordb/test-auditor-db-postgres.conf | 7 | ||||
-rw-r--r-- | src/auditordb/test_auditordb.c | 798 |
4 files changed, 2559 insertions, 93 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; +} |