summaryrefslogtreecommitdiff
path: root/src/exchangedb/plugin_exchangedb_postgres.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/exchangedb/plugin_exchangedb_postgres.c')
-rw-r--r--src/exchangedb/plugin_exchangedb_postgres.c16600
1 files changed, 570 insertions, 16030 deletions
diff --git a/src/exchangedb/plugin_exchangedb_postgres.c b/src/exchangedb/plugin_exchangedb_postgres.c
index cbacebbd6..108b55219 100644
--- a/src/exchangedb/plugin_exchangedb_postgres.c
+++ b/src/exchangedb/plugin_exchangedb_postgres.c
@@ -1,6 +1,6 @@
/*
This file is part of TALER
- Copyright (C) 2014--2022 Taler Systems SA
+ Copyright (C) 2014--2023 Taler Systems SA
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
@@ -21,47 +21,213 @@
* @author Christian Grothoff
* @author Sree Harsha Totakura
* @author Marcello Stanisci
+ * @author Özgür Kesim
*/
#include "platform.h"
+#include <poll.h>
+#include <pthread.h>
+#include <libpq-fe.h>
#include "taler_error_codes.h"
#include "taler_dbevents.h"
#include "taler_pq_lib.h"
#include "taler_util.h"
#include "taler_json_lib.h"
#include "taler_exchangedb_plugin.h"
-#include <poll.h>
-#include <pthread.h>
-#include <libpq-fe.h>
-
-#include "plugin_exchangedb_common.c"
+#include "plugin_exchangedb_common.h"
+#include "pg_delete_aggregation_transient.h"
+#include "pg_get_link_data.h"
+#include "pg_helper.h"
+#include "pg_do_reserve_open.h"
+#include "pg_get_coin_transactions.h"
+#include "pg_get_expired_reserves.h"
+#include "pg_get_purse_request.h"
+#include "pg_get_reserve_history.h"
+#include "pg_get_unfinished_close_requests.h"
+#include "pg_insert_close_request.h"
+#include "pg_insert_records_by_table.h"
+#include "pg_insert_reserve_open_deposit.h"
+#include "pg_get_pending_kyc_requirement_process.h"
+#include "pg_iterate_kyc_reference.h"
+#include "pg_iterate_reserve_close_info.h"
+#include "pg_lookup_records_by_table.h"
+#include "pg_lookup_serial_by_table.h"
+#include "pg_select_account_merges_above_serial_id.h"
+#include "pg_select_aml_threshold.h"
+#include "pg_select_all_purse_decisions_above_serial_id.h"
+#include "pg_select_purse.h"
+#include "pg_select_purse_deposits_above_serial_id.h"
+#include "pg_select_purse_merges_above_serial_id.h"
+#include "pg_select_purse_requests_above_serial_id.h"
+#include "pg_select_reserve_close_info.h"
+#include "pg_select_reserve_closed_above_serial_id.h"
+#include "pg_select_reserve_open_above_serial_id.h"
+#include "pg_insert_purse_request.h"
+#include "pg_iterate_active_signkeys.h"
+#include "pg_preflight.h"
+#include "pg_commit.h"
+#include "pg_drop_tables.h"
+#include "pg_select_satisfied_kyc_processes.h"
+#include "pg_select_aggregation_amounts_for_kyc_check.h"
+#include "pg_kyc_provider_account_lookup.h"
+#include "pg_lookup_kyc_requirement_by_row.h"
+#include "pg_insert_kyc_requirement_for_account.h"
+#include "pg_lookup_kyc_process_by_account.h"
+#include "pg_update_kyc_process_by_row.h"
+#include "pg_insert_kyc_requirement_process.h"
+#include "pg_select_withdraw_amounts_for_kyc_check.h"
+#include "pg_select_merge_amounts_for_kyc_check.h"
+#include "pg_profit_drains_set_finished.h"
+#include "pg_profit_drains_get_pending.h"
+#include "pg_get_drain_profit.h"
+#include "pg_get_purse_deposit.h"
+#include "pg_insert_contract.h"
+#include "pg_insert_kyc_failure.h"
+#include "pg_select_contract.h"
+#include "pg_select_purse_merge.h"
+#include "pg_select_contract_by_purse.h"
+#include "pg_insert_drain_profit.h"
+#include "pg_do_reserve_purse.h"
+#include "pg_lookup_global_fee_by_time.h"
+#include "pg_do_purse_deposit.h"
+#include "pg_activate_signing_key.h"
+#include "pg_update_auditor.h"
+#include "pg_begin_revolving_shard.h"
+#include "pg_get_extension_manifest.h"
+#include "pg_do_purse_delete.h"
+#include "pg_do_purse_merge.h"
+#include "pg_start_read_committed.h"
+#include "pg_start_read_only.h"
+#include "pg_insert_denomination_info.h"
+#include "pg_do_batch_withdraw_insert.h"
+#include "pg_lookup_wire_fee_by_time.h"
+#include "pg_start.h"
+#include "pg_rollback.h"
+#include "pg_create_tables.h"
+#include "pg_event_listen.h"
+#include "pg_event_listen_cancel.h"
+#include "pg_event_notify.h"
+#include "pg_get_denomination_info.h"
+#include "pg_iterate_denomination_info.h"
+#include "pg_iterate_denominations.h"
+#include "pg_iterate_active_auditors.h"
+#include "pg_iterate_auditor_denominations.h"
+#include "pg_reserves_get.h"
+#include "pg_reserves_get_origin.h"
+#include "pg_drain_kyc_alert.h"
+#include "pg_reserves_in_insert.h"
+#include "pg_get_withdraw_info.h"
+#include "pg_get_age_withdraw.h"
+#include "pg_do_batch_withdraw.h"
+#include "pg_do_age_withdraw.h"
+#include "pg_get_policy_details.h"
+#include "pg_persist_policy_details.h"
+#include "pg_do_deposit.h"
+#include "pg_get_wire_hash_for_contract.h"
+#include "pg_add_policy_fulfillment_proof.h"
+#include "pg_do_melt.h"
+#include "pg_do_refund.h"
+#include "pg_do_recoup.h"
+#include "pg_do_recoup_refresh.h"
+#include "pg_get_reserve_balance.h"
+#include "pg_count_known_coins.h"
+#include "pg_ensure_coin_known.h"
+#include "pg_get_known_coin.h"
+#include "pg_get_signature_for_known_coin.h"
+#include "pg_get_coin_denomination.h"
+#include "pg_have_deposit2.h"
+#include "pg_aggregate.h"
+#include "pg_create_aggregation_transient.h"
+#include "pg_select_aggregation_transient.h"
+#include "pg_find_aggregation_transient.h"
+#include "pg_update_aggregation_transient.h"
+#include "pg_get_ready_deposit.h"
+#include "pg_insert_refund.h"
+#include "pg_select_refunds_by_coin.h"
+#include "pg_get_melt.h"
+#include "pg_insert_refresh_reveal.h"
+#include "pg_get_refresh_reveal.h"
+#include "pg_lookup_wire_transfer.h"
+#include "pg_lookup_transfer_by_deposit.h"
+#include "pg_insert_wire_fee.h"
+#include "pg_insert_global_fee.h"
+#include "pg_get_wire_fee.h"
+#include "pg_get_global_fee.h"
+#include "pg_get_global_fees.h"
+#include "pg_insert_reserve_closed.h"
+#include "pg_wire_prepare_data_insert.h"
+#include "pg_wire_prepare_data_mark_finished.h"
+#include "pg_wire_prepare_data_mark_failed.h"
+#include "pg_wire_prepare_data_get.h"
+#include "pg_start_deferred_wire_out.h"
+#include "pg_store_wire_transfer_out.h"
+#include "pg_gc.h"
+#include "pg_inject_auditor_triggers.h"
+#include "pg_select_coin_deposits_above_serial_id.h"
+#include "pg_select_purse_decisions_above_serial_id.h"
+#include "pg_select_purse_deposits_by_purse.h"
+#include "pg_select_refreshes_above_serial_id.h"
+#include "pg_select_refunds_above_serial_id.h"
+#include "pg_select_reserves_in_above_serial_id.h"
+#include "pg_select_reserves_in_above_serial_id_by_account.h"
+#include "pg_select_withdrawals_above_serial_id.h"
+#include "pg_select_wire_out_above_serial_id.h"
+#include "pg_select_wire_out_above_serial_id_by_account.h"
+#include "pg_select_recoup_above_serial_id.h"
+#include "pg_select_recoup_refresh_above_serial_id.h"
+#include "pg_get_reserve_by_h_blind.h"
+#include "pg_get_old_coin_by_h_blind.h"
+#include "pg_insert_denomination_revocation.h"
+#include "pg_get_denomination_revocation.h"
+#include "pg_select_batch_deposits_missing_wire.h"
+#include "pg_select_justification_for_missing_wire.h"
+#include "pg_select_aggregations_above_serial.h"
+#include "pg_lookup_auditor_timestamp.h"
+#include "pg_lookup_auditor_status.h"
+#include "pg_insert_auditor.h"
+#include "pg_lookup_wire_timestamp.h"
+#include "pg_insert_wire.h"
+#include "pg_update_wire.h"
+#include "pg_get_wire_accounts.h"
+#include "pg_get_wire_fees.h"
+#include "pg_insert_signkey_revocation.h"
+#include "pg_lookup_signkey_revocation.h"
+#include "pg_lookup_denomination_key.h"
+#include "pg_insert_auditor_denom_sig.h"
+#include "pg_select_auditor_denom_sig.h"
+#include "pg_add_denomination_key.h"
+#include "pg_lookup_signing_key.h"
+#include "pg_begin_shard.h"
+#include "pg_abort_shard.h"
+#include "pg_complete_shard.h"
+#include "pg_release_revolving_shard.h"
+#include "pg_delete_shard_locks.h"
+#include "pg_set_extension_manifest.h"
+#include "pg_insert_partner.h"
+#include "pg_expire_purse.h"
+#include "pg_select_purse_by_merge_pub.h"
+#include "pg_set_purse_balance.h"
+#include "pg_reserves_update.h"
+#include "pg_setup_wire_target.h"
+#include "pg_compute_shard.h"
+#include "pg_insert_kyc_attributes.h"
+#include "pg_select_similar_kyc_attributes.h"
+#include "pg_select_kyc_attributes.h"
+#include "pg_insert_aml_officer.h"
+#include "pg_test_aml_officer.h"
+#include "pg_lookup_aml_officer.h"
+#include "pg_trigger_aml_process.h"
+#include "pg_select_aml_process.h"
+#include "pg_select_aml_history.h"
+#include "pg_insert_aml_decision.h"
+#include "pg_batch_ensure_coin_known.h"
/**
* Set to 1 to enable Postgres auto_explain module. This will
* slow down things a _lot_, but also provide extensive logging
* in the Postgres database logger for performance analysis.
*/
-#define AUTO_EXPLAIN 1
-
-/**
- * Wrapper macro to add the currency from the plugin's state
- * when fetching amounts from the database.
- *
- * @param field name of the database field to fetch amount from
- * @param[out] amountp pointer to amount to set
- */
-#define TALER_PQ_RESULT_SPEC_AMOUNT(field,amountp) TALER_PQ_result_spec_amount ( \
- field,pg->currency,amountp)
+#define AUTO_EXPLAIN 0
-/**
- * Wrapper macro to add the currency from the plugin's state
- * when fetching amounts from the database. NBO variant.
- *
- * @param field name of the database field to fetch amount from
- * @param[out] amountp pointer to amount to set
- */
-#define TALER_PQ_RESULT_SPEC_AMOUNT_NBO(field, \
- amountp) TALER_PQ_result_spec_amount_nbo ( \
- field,pg->currency,amountp)
/**
* Log a really unexpected PQ error with all the details we can get hold of.
@@ -82,4201 +248,13 @@
/**
- * Type of the "cls" argument given to each of the functions in
- * our API.
- */
-struct PostgresClosure
-{
-
- /**
- * Our configuration.
- */
- const struct GNUNET_CONFIGURATION_Handle *cfg;
-
- /**
- * Directory with SQL statements to run to create tables.
- */
- char *sql_dir;
-
- /**
- * After how long should idle reserves be closed?
- */
- struct GNUNET_TIME_Relative idle_reserve_expiration_time;
-
- /**
- * After how long should reserves that have seen withdraw operations
- * be garbage collected?
- */
- struct GNUNET_TIME_Relative legal_reserve_expiration_time;
-
- /**
- * What delay should we introduce before ready transactions
- * are actually aggregated?
- */
- struct GNUNET_TIME_Relative aggregator_shift;
-
- /**
- * Which currency should we assume all amounts to be in?
- */
- char *currency;
-
- /**
- * Our base URL.
- */
- char *exchange_url;
-
- /**
- * Postgres connection handle.
- */
- struct GNUNET_PQ_Context *conn;
-
- /**
- * Name of the current transaction, for debugging.
- */
- const char *transaction_name;
-
- /**
- * Did we initialize the prepared statements
- * for this session?
- */
- bool init;
-
-};
-
-
-/**
- * Drop all Taler tables. This should only be used by testcases.
- *
- * @param cls the `struct PostgresClosure` with the plugin-specific state
- * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure
- */
-static enum GNUNET_GenericReturnValue
-postgres_drop_tables (void *cls)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_Context *conn;
-
- conn = GNUNET_PQ_connect_with_cfg (pg->cfg,
- "exchangedb-postgres",
- "drop",
- NULL,
- NULL);
- if (NULL == conn)
- return GNUNET_SYSERR;
- GNUNET_PQ_disconnect (conn);
- if (NULL != pg->conn)
- {
- GNUNET_PQ_disconnect (pg->conn);
- pg->conn = NULL;
- pg->init = false;
- }
- return GNUNET_OK;
-}
-
-
-/**
- * Drop all Taler shard tables. This should only be used by testcases.
- *
- * @param cls the `struct PostgresClosure` with the plugin-specific state
- * @param old_idx the index which was used when the shard database was initialized
- * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure
- */
-static enum GNUNET_GenericReturnValue
-postgres_drop_shard_tables (void *cls,
- uint32_t old_idx)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_Context *conn;
- enum GNUNET_GenericReturnValue ret = GNUNET_OK;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_uint32 (&old_idx),
- GNUNET_PQ_query_param_end
- };
- struct GNUNET_PQ_PreparedStatement ps[] = {
- GNUNET_PQ_make_prepare ("drop_shard_tables",
- "SELECT"
- " drop_shard"
- " ($1);",
- 1),
- GNUNET_PQ_PREPARED_STATEMENT_END
- };
- conn = GNUNET_PQ_connect_with_cfg (pg->cfg,
- "exchangedb-postgres",
- NULL,
- NULL,
- ps);
- if (NULL == conn)
- return GNUNET_SYSERR;
- if (0 > GNUNET_PQ_eval_prepared_non_select (conn,
- "drop_shard_tables",
- params))
- ret = GNUNET_SYSERR;
- GNUNET_PQ_disconnect (conn);
-
- conn = GNUNET_PQ_connect_with_cfg (pg->cfg,
- "exchangedb-postgres",
- "shard-drop",
- NULL,
- NULL);
- if (NULL == conn)
- return GNUNET_SYSERR;
- GNUNET_PQ_disconnect (conn);
- if (NULL != pg->conn)
- {
- GNUNET_PQ_disconnect (pg->conn);
- pg->conn = NULL;
- pg->init = false;
- }
- return ret;
-}
-
-
-/**
- * Create the necessary tables if they are not present
- *
- * @param cls the `struct PostgresClosure` with the plugin-specific state
- * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure
- */
-static enum GNUNET_GenericReturnValue
-postgres_create_tables (void *cls)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_Context *conn;
-
- conn = GNUNET_PQ_connect_with_cfg (pg->cfg,
- "exchangedb-postgres",
- "exchange-",
- NULL,
- NULL);
- if (NULL == conn)
- return GNUNET_SYSERR;
- GNUNET_PQ_disconnect (conn);
- return GNUNET_OK;
-}
-
-
-/**
- * Create tables of a shard node with index idx
- *
- * @param cls the `struct PostgresClosure` with the plugin-specific state
- * @param idx the shards index, will be appended as suffix to all tables
- * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure
- */
-static enum GNUNET_GenericReturnValue
-postgres_create_shard_tables (void *cls,
- uint32_t idx)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_Context *conn;
- enum GNUNET_GenericReturnValue ret = GNUNET_OK;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_uint32 (&idx),
- GNUNET_PQ_query_param_end
- };
- struct GNUNET_PQ_PreparedStatement ps[] = {
- GNUNET_PQ_make_prepare ("create_shard_tables",
- "SELECT"
- " setup_shard"
- " ($1);",
- 1),
- GNUNET_PQ_PREPARED_STATEMENT_END
- };
-
- conn = GNUNET_PQ_connect_with_cfg (pg->cfg,
- "exchangedb-postgres",
- "shard-",
- NULL,
- ps);
- if (NULL == conn)
- return GNUNET_SYSERR;
- if (0 > GNUNET_PQ_eval_prepared_non_select (conn,
- "create_shard_tables",
- params))
- ret = GNUNET_SYSERR;
- GNUNET_PQ_disconnect (conn);
- return ret;
-}
-
-
-/**
- * Setup partitions of already existing tables
- *
- * @param cls the `struct PostgresClosure` with the plugin-specific state
- * @param num the number of partitions to create for each partitioned table
- * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure
- */
-static enum GNUNET_GenericReturnValue
-postgres_setup_partitions (void *cls,
- uint32_t num)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_Context *conn;
- enum GNUNET_GenericReturnValue ret = GNUNET_OK;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_uint32 (&num),
- GNUNET_PQ_query_param_end
- };
- struct GNUNET_PQ_PreparedStatement ps[] = {
- GNUNET_PQ_make_prepare ("setup_partitions",
- "SELECT"
- " create_partitions"
- " ($1);",
- 1),
- GNUNET_PQ_PREPARED_STATEMENT_END
- };
-
- conn = GNUNET_PQ_connect_with_cfg (pg->cfg,
- "exchangedb-postgres",
- NULL,
- NULL,
- ps);
- if (NULL == conn)
- return GNUNET_SYSERR;
- ret = GNUNET_OK;
- if (0 > GNUNET_PQ_eval_prepared_non_select (conn,
- "setup_partitions",
- params))
- ret = GNUNET_SYSERR;
- GNUNET_PQ_disconnect (conn);
- return ret;
-}
-
-
-/**
- * Setup foreign servers (shards) for already existing tables
- *
- * @param cls the `struct PostgresClosure` with the plugin-specific state
- * @param num the number of foreign servers (shards) to create for each partitioned table
- * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure
- */
-static enum GNUNET_GenericReturnValue
-postgres_setup_foreign_servers (void *cls,
- uint32_t num)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_Context *conn;
- enum GNUNET_GenericReturnValue ret = GNUNET_OK;
- char *shard_domain = NULL;
- char *remote_user = NULL;
- char *remote_user_pw = NULL;
-
- if (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_string (pg->cfg,
- "exchange",
- "SHARD_DOMAIN",
- &shard_domain))
- {
- GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
- "exchange",
- "SHARD_DOMAIN");
- return GNUNET_SYSERR;
- }
- if (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_string (pg->cfg,
- "exchangedb-postgres",
- "SHARD_REMOTE_USER",
- &remote_user))
- {
- GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
- "exchangedb-postgres",
- "SHARD_REMOTE_USER");
- GNUNET_free (shard_domain);
- return GNUNET_SYSERR;
- }
- if (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_string (pg->cfg,
- "exchangedb-postgres",
- "SHARD_REMOTE_USER_PW",
- &remote_user_pw))
- {
- GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
- "exchangedb-postgres",
- "SHARD_REMOTE_USER_PW");
- GNUNET_free (shard_domain);
- GNUNET_free (remote_user);
- return GNUNET_SYSERR;
- }
-
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_uint32 (&num),
- GNUNET_PQ_query_param_string (shard_domain),
- GNUNET_PQ_query_param_string (remote_user),
- GNUNET_PQ_query_param_string (remote_user_pw),
- GNUNET_PQ_query_param_end
- };
-
- struct GNUNET_PQ_PreparedStatement ps[] = {
- GNUNET_PQ_make_prepare ("create_foreign_servers",
- "SELECT"
- " create_foreign_servers"
- " ($1, $2, $3, $4);",
- 4),
- GNUNET_PQ_PREPARED_STATEMENT_END
- };
-
- conn = GNUNET_PQ_connect_with_cfg (pg->cfg,
- "exchangedb-postgres",
- NULL,
- NULL,
- ps);
- if (NULL == conn)
- {
- ret = GNUNET_SYSERR;
- }
- else if (0 > GNUNET_PQ_eval_prepared_non_select (conn,
- "create_foreign_servers",
- params))
- {
- ret = GNUNET_SYSERR;
- }
- GNUNET_free (shard_domain);
- GNUNET_free (remote_user);
- GNUNET_free (remote_user_pw);
- GNUNET_PQ_disconnect (conn);
- return ret;
-}
-
-
-/**
- * Initialize prepared statements for @a pg.
- *
- * @param[in,out] pg connection to initialize
- * @return #GNUNET_OK on success
- */
-static enum GNUNET_GenericReturnValue
-prepare_statements (struct PostgresClosure *pg)
-{
- enum GNUNET_GenericReturnValue ret;
- struct GNUNET_PQ_PreparedStatement ps[] = {
- /* Used in #postgres_insert_denomination_info() and
- #postgres_add_denomination_key() */
- GNUNET_PQ_make_prepare (
- "denomination_insert",
- "INSERT INTO denominations "
- "(denom_pub_hash"
- ",denom_pub"
- ",master_sig"
- ",valid_from"
- ",expire_withdraw"
- ",expire_deposit"
- ",expire_legal"
- ",coin_val" /* value of this denom */
- ",coin_frac" /* fractional value of this denom */
- ",fee_withdraw_val"
- ",fee_withdraw_frac"
- ",fee_deposit_val"
- ",fee_deposit_frac"
- ",fee_refresh_val"
- ",fee_refresh_frac"
- ",fee_refund_val"
- ",fee_refund_frac"
- ",age_mask"
- ") VALUES "
- "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10,"
- " $11, $12, $13, $14, $15, $16, $17, $18);",
- 18),
- /* Used in #postgres_iterate_denomination_info() */
- GNUNET_PQ_make_prepare (
- "denomination_iterate",
- "SELECT"
- " master_sig"
- ",denom_pub_hash"
- ",valid_from"
- ",expire_withdraw"
- ",expire_deposit"
- ",expire_legal"
- ",coin_val" /* value of this denom */
- ",coin_frac" /* fractional value of this denom */
- ",fee_withdraw_val"
- ",fee_withdraw_frac"
- ",fee_deposit_val"
- ",fee_deposit_frac"
- ",fee_refresh_val"
- ",fee_refresh_frac"
- ",fee_refund_val"
- ",fee_refund_frac"
- ",denom_pub"
- ",age_mask"
- " FROM denominations;",
- 0),
- /* Used in #postgres_iterate_denominations() */
- GNUNET_PQ_make_prepare (
- "select_denominations",
- "SELECT"
- " denominations.master_sig"
- ",denom_revocations_serial_id IS NOT NULL AS revoked"
- ",valid_from"
- ",expire_withdraw"
- ",expire_deposit"
- ",expire_legal"
- ",coin_val" /* value of this denom */
- ",coin_frac" /* fractional value of this denom */
- ",fee_withdraw_val"
- ",fee_withdraw_frac"
- ",fee_deposit_val"
- ",fee_deposit_frac"
- ",fee_refresh_val"
- ",fee_refresh_frac"
- ",fee_refund_val"
- ",fee_refund_frac"
- ",denom_type"
- ",age_mask"
- ",denom_pub"
- " FROM denominations"
- " LEFT JOIN "
- " denomination_revocations USING (denominations_serial);",
- 0),
- /* Used in #postgres_iterate_active_signkeys() */
- GNUNET_PQ_make_prepare (
- "select_signkeys",
- "SELECT"
- " master_sig"
- ",exchange_pub"
- ",valid_from"
- ",expire_sign"
- ",expire_legal"
- " FROM exchange_sign_keys esk"
- " WHERE"
- " expire_sign > $1"
- " AND NOT EXISTS "
- " (SELECT esk_serial "
- " FROM signkey_revocations skr"
- " WHERE esk.esk_serial = skr.esk_serial);",
- 1),
- /* Used in #postgres_iterate_auditor_denominations() */
- GNUNET_PQ_make_prepare (
- "select_auditor_denoms",
- "SELECT"
- " auditors.auditor_pub"
- ",denominations.denom_pub_hash"
- ",auditor_denom_sigs.auditor_sig"
- " FROM auditor_denom_sigs"
- " JOIN auditors USING (auditor_uuid)"
- " JOIN denominations USING (denominations_serial)"
- " WHERE auditors.is_active;",
- 0),
- /* Used in #postgres_iterate_active_auditors() */
- GNUNET_PQ_make_prepare (
- "select_auditors",
- "SELECT"
- " auditor_pub"
- ",auditor_url"
- ",auditor_name"
- " FROM auditors"
- " WHERE"
- " is_active;",
- 0),
- /* Used in #postgres_get_denomination_info() */
- GNUNET_PQ_make_prepare (
- "denomination_get",
- "SELECT"
- " master_sig"
- ",valid_from"
- ",expire_withdraw"
- ",expire_deposit"
- ",expire_legal"
- ",coin_val" /* value of this denom */
- ",coin_frac" /* fractional value of this denom */
- ",fee_withdraw_val"
- ",fee_withdraw_frac"
- ",fee_deposit_val"
- ",fee_deposit_frac"
- ",fee_refresh_val"
- ",fee_refresh_frac"
- ",fee_refund_val"
- ",fee_refund_frac"
- ",age_mask"
- " FROM denominations"
- " WHERE denom_pub_hash=$1;",
- 1),
- /* Used in #postgres_insert_denomination_revocation() */
- GNUNET_PQ_make_prepare (
- "denomination_revocation_insert",
- "INSERT INTO denomination_revocations "
- "(denominations_serial"
- ",master_sig"
- ") SELECT denominations_serial,$2"
- " FROM denominations"
- " WHERE denom_pub_hash=$1;",
- 2),
- /* Used in #postgres_get_denomination_revocation() */
- GNUNET_PQ_make_prepare (
- "denomination_revocation_get",
- "SELECT"
- " master_sig"
- ",denom_revocations_serial_id"
- " FROM denomination_revocations"
- " WHERE denominations_serial="
- " (SELECT denominations_serial"
- " FROM denominations"
- " WHERE denom_pub_hash=$1);",
- 1),
- /* Used in #postgres_reserves_get() */
- GNUNET_PQ_make_prepare (
- "reserves_get_with_kyc",
- "SELECT"
- " current_balance_val"
- ",current_balance_frac"
- ",expiration_date"
- ",gc_date"
- ",kyc_ok"
- ",wire_target_serial_id AS payment_target_uuid"
- " FROM reserves"
- " JOIN reserves_in ri USING (reserve_pub)"
- " JOIN wire_targets wt "
- " ON (ri.wire_source_h_payto = wt.wire_target_h_payto)"
- " WHERE reserve_pub=$1"
- " LIMIT 1;",
- 1),
- /* Used in #postgres_set_kyc_ok() */
- GNUNET_PQ_make_prepare (
- "set_kyc_ok",
- "UPDATE wire_targets"
- " SET kyc_ok=TRUE"
- ",external_id=$2"
- " WHERE wire_target_h_payto=$1",
- 2),
- GNUNET_PQ_make_prepare (
- "get_kyc_h_payto",
- "SELECT"
- " wire_target_h_payto"
- " FROM wire_targets"
- " WHERE wire_target_h_payto=$1"
- " LIMIT 1;",
- 1),
- /* Used in #postgres_insert_partner() */
- GNUNET_PQ_make_prepare (
- "insert_partner",
- "INSERT INTO partners"
- " (partner_master_pub"
- " ,start_date"
- " ,end_date"
- " ,wad_frequency"
- " ,wad_fee_val"
- " ,wad_fee_frac"
- " ,master_sig"
- " ,partner_base_url"
- " ) VALUES "
- " ($1, $2, $3, $4, $5, $6, $7, $8);",
- 8),
- /* Used in #postgres_inselect_wallet_kyc_status() */
- GNUNET_PQ_make_prepare (
- "insert_kyc_status",
- "INSERT INTO wire_targets"
- " (wire_target_h_payto"
- " ,payto_uri"
- " ) VALUES "
- " ($1, $2)"
- " RETURNING wire_target_serial_id",
- 2),
- GNUNET_PQ_make_prepare (
- "select_kyc_status_by_payto",
- "SELECT "
- " kyc_ok"
- ",wire_target_serial_id"
- " FROM wire_targets"
- " WHERE wire_target_h_payto=$1;",
- 1),
- /* Used in #reserves_get() */
- GNUNET_PQ_make_prepare (
- "reserves_get",
- "SELECT"
- " current_balance_val"
- ",current_balance_frac"
- ",expiration_date"
- ",gc_date"
- " FROM reserves"
- " WHERE reserve_pub=$1"
- " LIMIT 1;",
- 1),
- GNUNET_PQ_make_prepare (
- "reserve_create",
- "INSERT INTO reserves "
- "(reserve_pub"
- ",current_balance_val"
- ",current_balance_frac"
- ",expiration_date"
- ",gc_date"
- ") VALUES "
- "($1, $2, $3, $4, $5)"
- " ON CONFLICT DO NOTHING"
- " RETURNING reserve_uuid;",
- 5),
- /* Used in #postgres_insert_reserve_closed() */
- GNUNET_PQ_make_prepare (
- "reserves_close_insert",
- "INSERT INTO reserves_close "
- "(reserve_pub"
- ",execution_date"
- ",wtid"
- ",wire_target_h_payto"
- ",amount_val"
- ",amount_frac"
- ",closing_fee_val"
- ",closing_fee_frac"
- ") VALUES ($1, $2, $3, $4, $5, $6, $7, $8);",
- 8),
- /* Used in #reserves_update() when the reserve is updated */
- GNUNET_PQ_make_prepare (
- "reserve_update",
- "UPDATE reserves"
- " SET"
- " expiration_date=$1"
- ",gc_date=$2"
- ",current_balance_val=$3"
- ",current_balance_frac=$4"
- " WHERE reserve_pub=$5;",
- 5),
- /* Used in #postgres_reserves_in_insert() to store transaction details */
- GNUNET_PQ_make_prepare (
- "reserves_in_add_transaction",
- "INSERT INTO reserves_in "
- "(reserve_pub"
- ",wire_reference"
- ",credit_val"
- ",credit_frac"
- ",exchange_account_section"
- ",wire_source_h_payto"
- ",execution_date"
- ") VALUES ($1, $2, $3, $4, $5, $6, $7)"
- " ON CONFLICT DO NOTHING;",
- 7),
- /* Used in postgres_select_reserves_in_above_serial_id() to obtain inbound
- transactions for reserves with serial id '\geq' the given parameter */
- GNUNET_PQ_make_prepare (
- "audit_reserves_in_get_transactions_incr",
- "SELECT"
- " reserves.reserve_pub"
- ",wire_reference"
- ",credit_val"
- ",credit_frac"
- ",execution_date"
- ",payto_uri AS sender_account_details"
- ",reserve_in_serial_id"
- " FROM reserves_in"
- " JOIN reserves"
- " USING (reserve_pub)"
- " JOIN wire_targets"
- " ON (wire_source_h_payto = wire_target_h_payto)"
- " WHERE reserve_in_serial_id>=$1"
- " ORDER BY reserve_in_serial_id;",
- 1),
- /* Used in postgres_select_reserves_in_above_serial_id() to obtain inbound
- transactions for reserves with serial id '\geq' the given parameter */
- GNUNET_PQ_make_prepare (
- "audit_reserves_in_get_transactions_incr_by_account",
- "SELECT"
- " reserves.reserve_pub"
- ",wire_reference"
- ",credit_val"
- ",credit_frac"
- ",execution_date"
- ",payto_uri AS sender_account_details"
- ",reserve_in_serial_id"
- " FROM reserves_in"
- " JOIN reserves "
- " USING (reserve_pub)"
- " JOIN wire_targets"
- " ON (wire_source_h_payto = wire_target_h_payto)"
- " WHERE reserve_in_serial_id>=$1 AND exchange_account_section=$2"
- " ORDER BY reserve_in_serial_id;",
- 2),
- /* Used in #postgres_get_reserve_history() to obtain inbound transactions
- for a reserve */
- GNUNET_PQ_make_prepare (
- "reserves_in_get_transactions",
- /*
- "SELECT"
- " wire_reference"
- ",credit_val"
- ",credit_frac"
- ",execution_date"
- ",payto_uri AS sender_account_details"
- " FROM reserves_in"
- " JOIN wire_targets"
- " ON (wire_source_h_payto = wire_target_h_payto)"
- " WHERE reserve_pub=$1;",
- */
- "WITH ri AS MATERIALIZED ( "
- " SELECT * "
- " FROM reserves_in "
- " WHERE reserve_pub = $1 "
- ") "
- "SELECT "
- " wire_reference "
- " ,credit_val "
- " ,credit_frac "
- " ,execution_date "
- " ,payto_uri AS sender_account_details "
- "FROM wire_targets "
- "JOIN ri "
- " ON (wire_target_h_payto = wire_source_h_payto) "
- "WHERE wire_target_h_payto = ( "
- " SELECT wire_source_h_payto FROM ri "
- "); ",
- 1),
- /* Used in #postgres_do_withdraw() to store
- the signature of a blinded coin with the blinded coin's
- details before returning it during /reserve/withdraw. We store
- the coin's denomination information (public key, signature)
- and the blinded message as well as the reserve that the coin
- is being withdrawn from and the signature of the message
- authorizing the withdrawal. */
- GNUNET_PQ_make_prepare (
- "call_withdraw",
- "SELECT "
- " reserve_found"
- ",balance_ok"
- ",kycok AS kyc_ok"
- ",account_uuid AS payment_target_uuid"
- ",ruuid"
- " FROM exchange_do_withdraw"
- " ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10);",
- 10),
- /* Used in #postgres_do_batch_withdraw() to
- update the reserve balance and check its status */
- GNUNET_PQ_make_prepare (
- "call_batch_withdraw",
- "SELECT "
- " reserve_found"
- ",balance_ok"
- ",kycok AS kyc_ok"
- ",account_uuid AS payment_target_uuid"
- ",ruuid"
- " FROM exchange_do_batch_withdraw"
- " ($1,$2,$3,$4,$5);",
- 5),
- /* Used in #postgres_do_batch_withdraw_insert() to store
- the signature of a blinded coin with the blinded coin's
- details. */
- GNUNET_PQ_make_prepare (
- "call_batch_withdraw_insert",
- "SELECT "
- " out_denom_unknown AS denom_unknown"
- ",out_conflict AS conflict"
- ",out_nonce_reuse AS nonce_reuse"
- " FROM exchange_do_batch_withdraw_insert"
- " ($1,$2,$3,$4,$5,$6,$7,$8,$9);",
- 9),
- /* Used in #postgres_do_withdraw_limit_check() to check
- if the withdrawals remain below the limit under which
- KYC is not required. */
- GNUNET_PQ_make_prepare (
- "call_withdraw_limit_check",
- "SELECT "
- " below_limit"
- " FROM exchange_do_withdraw_limit_check"
- " ($1,$2,$3,$4);",
- 4),
- /* Used in #postgres_do_deposit() to execute a deposit,
- checking the coin's balance in the process as needed. */
- GNUNET_PQ_make_prepare (
- "call_deposit",
- "SELECT "
- " out_exchange_timestamp AS exchange_timestamp"
- ",out_balance_ok AS balance_ok"
- ",out_conflict AS conflicted"
- " FROM exchange_do_deposit"
- " ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17);",
- 17),
- /* used in postgres_do_purse_deposit() */
- GNUNET_PQ_make_prepare (
- "call_purse_deposit",
- "SELECT "
- " out_balance_ok AS balance_ok"
- ",out_conflict AS conflict"
- " FROM exchange_do_purse_deposit"
- " ($1,$2,$3,$4,$5,$6,$7,$8);",
- 8),
- /* Used in #postgres_update_aggregation_transient() */
- GNUNET_PQ_make_prepare (
- "set_purse_balance",
- "UPDATE purse_requests"
- " SET balance_val=$2"
- " ,balance_frac=$3"
- " WHERE purse_pub=$1;",
- 3),
- /* used in #postgres_expire_purse() */
- GNUNET_PQ_make_prepare (
- "call_expire_purse",
- "SELECT "
- " out_found AS found"
- " FROM exchange_do_expire_purse"
- " ($1,$2);",
- 2),
- /* Used in #postgres_do_melt() to melt a coin. */
- GNUNET_PQ_make_prepare (
- "call_melt",
- "SELECT "
- " out_balance_ok AS balance_ok"
- ",out_zombie_bad AS zombie_required"
- ",out_noreveal_index AS noreveal_index"
- " FROM exchange_do_melt"
- " ($1,$2,$3,$4,$5,$6,$7,$8,$9);",
- 9),
- /* Used in #postgres_do_refund() to refund a deposit. */
- GNUNET_PQ_make_prepare (
- "call_refund",
- "SELECT "
- " out_not_found AS not_found"
- ",out_refund_ok AS refund_ok"
- ",out_gone AS gone"
- ",out_conflict AS conflict"
- " FROM exchange_do_refund"
- " ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13);",
- 13),
- /* Used in #postgres_do_recoup() to recoup a coin to a reserve. */
- GNUNET_PQ_make_prepare (
- "call_recoup",
- "SELECT "
- " out_recoup_timestamp AS recoup_timestamp"
- ",out_recoup_ok AS recoup_ok"
- ",out_internal_failure AS internal_failure"
- " FROM exchange_do_recoup_to_reserve"
- " ($1,$2,$3,$4,$5,$6,$7,$8,$9);",
- 9),
- /* Used in #postgres_do_recoup_refresh() to recoup a coin to a zombie coin. */
- GNUNET_PQ_make_prepare (
- "call_recoup_refresh",
- "SELECT "
- " out_recoup_timestamp AS recoup_timestamp"
- ",out_recoup_ok AS recoup_ok"
- ",out_internal_failure AS internal_failure"
- " FROM exchange_do_recoup_to_coin"
- " ($1,$2,$3,$4,$5,$6,$7);",
- 7),
- /* Used in #postgres_get_withdraw_info() to
- locate the response for a /reserve/withdraw request
- using the hash of the blinded message. Used to
- make sure /reserve/withdraw requests are idempotent. */
- GNUNET_PQ_make_prepare (
- "get_withdraw_info",
- "SELECT"
- " denom.denom_pub_hash"
- ",denom_sig"
- ",reserve_sig"
- ",reserves.reserve_pub"
- ",execution_date"
- ",h_blind_ev"
- ",amount_with_fee_val"
- ",amount_with_fee_frac"
- ",denom.fee_withdraw_val"
- ",denom.fee_withdraw_frac"
- " FROM reserves_out"
- " JOIN reserves"
- " USING (reserve_uuid)"
- " JOIN denominations denom"
- " USING (denominations_serial)"
- " WHERE h_blind_ev=$1;",
- 1),
- /* Used during #postgres_get_reserve_history() to
- obtain all of the /reserve/withdraw operations that
- have been performed on a given reserve. (i.e. to
- demonstrate double-spending) */
- GNUNET_PQ_make_prepare (
- "get_reserves_out",
- /*
- "SELECT"
- " ro.h_blind_ev"
- ",denom.denom_pub_hash"
- ",ro.denom_sig"
- ",ro.reserve_sig"
- ",ro.execution_date"
- ",ro.amount_with_fee_val"
- ",ro.amount_with_fee_frac"
- ",denom.fee_withdraw_val"
- ",denom.fee_withdraw_frac"
- " FROM reserves res"
- " JOIN reserves_out_by_reserve ror"
- " ON (res.reserve_uuid = ror.reserve_uuid)"
- " JOIN reserves_out ro"
- " ON (ro.h_blind_ev = ror.h_blind_ev)"
- " JOIN denominations denom"
- " ON (ro.denominations_serial = denom.denominations_serial)"
- " WHERE res.reserve_pub=$1;",
- */
- "WITH robr AS MATERIALIZED ( "
- " SELECT h_blind_ev "
- " FROM reserves_out_by_reserve "
- " WHERE reserve_uuid= ( "
- " SELECT reserve_uuid "
- " FROM reserves "
- " WHERE reserve_pub = $1 "
- " ) "
- ") SELECT "
- " ro.h_blind_ev "
- " ,denom.denom_pub_hash "
- " ,ro.denom_sig "
- " ,ro.reserve_sig "
- " ,ro.execution_date "
- " ,ro.amount_with_fee_val "
- " ,ro.amount_with_fee_frac "
- " ,denom.fee_withdraw_val "
- " ,denom.fee_withdraw_frac "
- "FROM robr "
- "JOIN reserves_out ro "
- " ON (ro.h_blind_ev = robr.h_blind_ev) "
- "JOIN denominations denom "
- " ON (ro.denominations_serial = denom.denominations_serial); ",
- 1),
- /* Used in #postgres_select_withdrawals_above_serial_id() */
-
- GNUNET_PQ_make_prepare (
- "get_reserve_balance",
- "SELECT"
- " current_balance_val"
- ",current_balance_frac"
- " FROM reserves"
- " WHERE reserve_pub=$1;",
- 1),
- /* Fetch deposits with rowid '\geq' the given parameter */
-
- GNUNET_PQ_make_prepare (
- "audit_get_reserves_out_incr",
- "SELECT"
- " h_blind_ev"
- ",denom.denom_pub"
- ",reserve_sig"
- ",reserves.reserve_pub"
- ",execution_date"
- ",amount_with_fee_val"
- ",amount_with_fee_frac"
- ",reserve_out_serial_id"
- " FROM reserves_out"
- " JOIN reserves"
- " USING (reserve_uuid)"
- " JOIN denominations denom"
- " USING (denominations_serial)"
- " WHERE reserve_out_serial_id>=$1"
- " ORDER BY reserve_out_serial_id ASC;",
- 1),
-
- /* Used in #postgres_count_known_coins() */
- GNUNET_PQ_make_prepare (
- "count_known_coins",
- "SELECT"
- " COUNT(*) AS count"
- " FROM known_coins"
- " WHERE denominations_serial="
- " (SELECT denominations_serial"
- " FROM denominations"
- " WHERE denom_pub_hash=$1);",
- 1),
- /* Used in #postgres_get_known_coin() to fetch
- the denomination public key and signature for
- a coin known to the exchange. */
- GNUNET_PQ_make_prepare (
- "get_known_coin",
- "SELECT"
- " denominations.denom_pub_hash"
- ",age_commitment_hash"
- ",denom_sig"
- " FROM known_coins"
- " JOIN denominations USING (denominations_serial)"
- " WHERE coin_pub=$1;",
- 1),
- /* Used in #postgres_ensure_coin_known() */
- GNUNET_PQ_make_prepare (
- "get_known_coin_dh",
- "SELECT"
- " denominations.denom_pub_hash"
- " FROM known_coins"
- " JOIN denominations USING (denominations_serial)"
- " WHERE coin_pub=$1;",
- 1),
- /* Used in #postgres_get_coin_denomination() to fetch
- the denomination public key hash for
- a coin known to the exchange. */
- GNUNET_PQ_make_prepare (
- "get_coin_denomination",
- "SELECT"
- " denominations.denom_pub_hash"
- ",known_coin_id"
- " FROM known_coins"
- " JOIN denominations USING (denominations_serial)"
- " WHERE coin_pub=$1"
- " FOR SHARE;",
- 1),
- /* Used in #postgres_insert_known_coin() to store the denomination public
- key and signature for a coin known to the exchange.
-
- See also:
- https://stackoverflow.com/questions/34708509/how-to-use-returning-with-on-conflict-in-postgresql/37543015#37543015
- */
- GNUNET_PQ_make_prepare (
- "insert_known_coin",
- "WITH dd"
- " (denominations_serial"
- " ,coin_val"
- " ,coin_frac"
- " ) AS ("
- " SELECT "
- " denominations_serial"
- " ,coin_val"
- " ,coin_frac"
- " FROM denominations"
- " WHERE denom_pub_hash=$2"
- " ), input_rows"
- " (coin_pub) AS ("
- " VALUES ($1::BYTEA)"
- " ), ins AS ("
- " INSERT INTO known_coins "
- " (coin_pub"
- " ,denominations_serial"
- " ,age_commitment_hash"
- " ,denom_sig"
- " ,remaining_val"
- " ,remaining_frac"
- " ) SELECT "
- " $1"
- " ,denominations_serial"
- " ,$3"
- " ,$4"
- " ,coin_val"
- " ,coin_frac"
- " FROM dd"
- " ON CONFLICT DO NOTHING" /* CONFLICT on (coin_pub) */
- " RETURNING "
- " known_coin_id"
- " ) "
- "SELECT "
- " FALSE AS existed"
- " ,known_coin_id"
- " ,NULL AS denom_pub_hash"
- " ,NULL AS age_commitment_hash"
- " FROM ins "
- "UNION ALL "
- "SELECT "
- " TRUE AS existed"
- " ,known_coin_id"
- " ,denom_pub_hash"
- " ,kc.age_commitment_hash"
- " FROM input_rows"
- " JOIN known_coins kc USING (coin_pub)"
- " JOIN denominations USING (denominations_serial)"
- " LIMIT 1",
- 4),
-
- /* Used in #postgres_get_melt() to fetch
- high-level information about a melt operation */
- GNUNET_PQ_make_prepare (
- "get_melt",
- /* "SELECT"
- " denoms.denom_pub_hash"
- ",denoms.fee_refresh_val"
- ",denoms.fee_refresh_frac"
- ",old_coin_pub"
- ",old_coin_sig"
- ",kc.age_commitment_hash"
- ",amount_with_fee_val"
- ",amount_with_fee_frac"
- ",noreveal_index"
- ",melt_serial_id"
- " FROM refresh_commitments"
- " JOIN known_coins kc"
- " ON (old_coin_pub = kc.coin_pub)"
- " JOIN denominations denoms"
- " ON (kc.denominations_serial = denoms.denominations_serial)"
- " WHERE rc=$1;", */
- "WITH rc AS MATERIALIZED ( "
- " SELECT"
- " * FROM refresh_commitments"
- " WHERE rc=$1"
- ")"
- "SELECT"
- " denoms.denom_pub_hash"
- ",denoms.fee_refresh_val"
- ",denoms.fee_refresh_frac"
- ",rc.old_coin_pub"
- ",rc.old_coin_sig"
- ",kc.age_commitment_hash"
- ",amount_with_fee_val"
- ",amount_with_fee_frac"
- ",noreveal_index"
- ",melt_serial_id "
- "FROM ("
- " SELECT"
- " * "
- " FROM known_coins"
- " WHERE coin_pub=(SELECT old_coin_pub from rc)"
- ") kc "
- "JOIN rc"
- " ON (kc.coin_pub=rc.old_coin_pub) "
- "JOIN denominations denoms"
- " USING (denominations_serial);",
- 1),
- /* Used in #postgres_select_refreshes_above_serial_id() to fetch
- refresh session with id '\geq' the given parameter */
- GNUNET_PQ_make_prepare (
- "audit_get_refresh_commitments_incr",
- "SELECT"
- " denom.denom_pub"
- ",kc.coin_pub AS old_coin_pub"
- ",kc.age_commitment_hash"
- ",old_coin_sig"
- ",amount_with_fee_val"
- ",amount_with_fee_frac"
- ",noreveal_index"
- ",melt_serial_id"
- ",rc"
- " FROM refresh_commitments"
- " JOIN known_coins kc"
- " ON (refresh_commitments.old_coin_pub = kc.coin_pub)"
- " JOIN denominations denom"
- " ON (kc.denominations_serial = denom.denominations_serial)"
- " WHERE melt_serial_id>=$1"
- " ORDER BY melt_serial_id ASC;",
- 1),
- /* Query the 'refresh_commitments' by coin public key,
- used in #postgres_get_coin_transactions() */
- GNUNET_PQ_make_prepare (
- "get_refresh_session_by_coin",
- "SELECT"
- " rc"
- ",old_coin_sig"
- ",amount_with_fee_val"
- ",amount_with_fee_frac"
- ",denoms.denom_pub_hash"
- ",denoms.fee_refresh_val"
- ",denoms.fee_refresh_frac"
- ",kc.age_commitment_hash"
- ",melt_serial_id"
- " FROM refresh_commitments"
- " JOIN known_coins kc"
- " ON (refresh_commitments.old_coin_pub = kc.coin_pub)"
- " JOIN denominations denoms"
- " USING (denominations_serial)"
- " WHERE old_coin_pub=$1;",
- 1),
- /* Find purse deposits by coin,
- used in #postgres_get_coin_transactions() */
- GNUNET_PQ_make_prepare (
- "get_purse_deposit_by_coin_pub",
- "SELECT"
- " partner_base_url"
- ",pd.amount_with_fee_val"
- ",pd.amount_with_fee_frac"
- ",denoms.fee_deposit_val"
- ",denoms.fee_deposit_frac"
- ",pd.purse_pub"
- ",kc.age_commitment_hash"
- ",pd.coin_sig"
- ",pd.purse_deposit_serial_id"
- ",pr.refunded"
- " FROM purse_deposits pd"
- " LEFT JOIN partners"
- " USING (partner_serial_id)"
- " JOIN purse_requests pr"
- " USING (purse_pub)"
- " JOIN known_coins kc"
- " ON (pd.coin_pub = kc.coin_pub)"
- " JOIN denominations denoms"
- " USING (denominations_serial)"
- // FIXME: use to-be-created materialized index
- // on coin_pub (query crosses partitions!)
- " WHERE pd.coin_pub=$1;",
- 1),
- /* Store information about the desired denominations for a
- refresh operation, used in #postgres_insert_refresh_reveal() */
- GNUNET_PQ_make_prepare (
- "insert_refresh_revealed_coin",
- "INSERT INTO refresh_revealed_coins "
- "(melt_serial_id "
- ",freshcoin_index "
- ",link_sig "
- ",denominations_serial "
- ",coin_ev"
- ",ewv"
- ",h_coin_ev"
- ",ev_sig"
- ") SELECT $1, $2, $3, "
- " denominations_serial, $5, $6, $7, $8"
- " FROM denominations"
- " WHERE denom_pub_hash=$4"
- " ON CONFLICT DO NOTHING;",
- 8),
- /* Obtain information about the coins created in a refresh
- operation, used in #postgres_get_refresh_reveal() */
- GNUNET_PQ_make_prepare (
- "get_refresh_revealed_coins",
- "SELECT "
- " rrc.freshcoin_index"
- ",denom.denom_pub_hash"
- ",rrc.h_coin_ev"
- ",rrc.link_sig"
- ",rrc.coin_ev"
- ",rrc.ewv"
- ",rrc.ev_sig"
- " FROM refresh_commitments"
- " JOIN refresh_revealed_coins rrc"
- " USING (melt_serial_id)"
- " JOIN denominations denom "
- " USING (denominations_serial)"
- " WHERE rc=$1;",
- 1),
-
- /* Used in #postgres_insert_refresh_reveal() to store the transfer
- keys we learned */
- GNUNET_PQ_make_prepare (
- "insert_refresh_transfer_keys",
- "INSERT INTO refresh_transfer_keys "
- "(melt_serial_id"
- ",transfer_pub"
- ",transfer_privs"
- ") VALUES ($1, $2, $3)"
- " ON CONFLICT DO NOTHING;",
- 3),
- /* Used in #postgres_insert_refund() to store refund information */
- GNUNET_PQ_make_prepare (
- "insert_refund",
- "INSERT INTO refunds "
- "(coin_pub "
- ",deposit_serial_id"
- ",merchant_sig "
- ",rtransaction_id "
- ",amount_with_fee_val "
- ",amount_with_fee_frac "
- ") SELECT $1, deposit_serial_id, $3, $5, $6, $7"
- " FROM deposits"
- " WHERE coin_pub=$1"
- " AND h_contract_terms=$4"
- " AND merchant_pub=$2",
- 7),
- /* Query the 'refunds' by coin public key */
- GNUNET_PQ_make_prepare (
- "get_refunds_by_coin",
- "SELECT"
- " dep.merchant_pub"
- ",ref.merchant_sig"
- ",dep.h_contract_terms"
- ",ref.rtransaction_id"
- ",ref.amount_with_fee_val"
- ",ref.amount_with_fee_frac"
- ",denom.fee_refund_val "
- ",denom.fee_refund_frac "
- ",ref.refund_serial_id"
- " FROM refunds ref"
- " JOIN deposits dep"
- " ON (ref.coin_pub = dep.coin_pub AND ref.deposit_serial_id = dep.deposit_serial_id)"
- " JOIN known_coins kc"
- " ON (ref.coin_pub = kc.coin_pub)"
- " JOIN denominations denom"
- " USING (denominations_serial)"
- " WHERE ref.coin_pub=$1;",
- 1),
- /* Query the 'refunds' by coin public key, merchant_pub and contract hash */
- GNUNET_PQ_make_prepare (
- "get_refunds_by_coin_and_contract",
- "SELECT"
- " ref.amount_with_fee_val"
- ",ref.amount_with_fee_frac"
- " FROM refunds ref"
- " JOIN deposits dep"
- " USING (coin_pub,deposit_serial_id)"
- " WHERE ref.coin_pub=$1"
- " AND dep.merchant_pub=$2"
- " AND dep.h_contract_terms=$3;",
- 3),
- /* Fetch refunds with rowid '\geq' the given parameter */
- GNUNET_PQ_make_prepare (
- "audit_get_refunds_incr",
- "SELECT"
- " dep.merchant_pub"
- ",ref.merchant_sig"
- ",dep.h_contract_terms"
- ",ref.rtransaction_id"
- ",denom.denom_pub"
- ",kc.coin_pub"
- ",ref.amount_with_fee_val"
- ",ref.amount_with_fee_frac"
- ",ref.refund_serial_id"
- " FROM refunds ref"
- " JOIN deposits dep"
- " ON (ref.coin_pub=dep.coin_pub AND ref.deposit_serial_id=dep.deposit_serial_id)"
- " JOIN known_coins kc"
- " ON (dep.coin_pub=kc.coin_pub)"
- " JOIN denominations denom"
- " ON (kc.denominations_serial=denom.denominations_serial)"
- " WHERE ref.refund_serial_id>=$1"
- " ORDER BY ref.refund_serial_id ASC;",
- 1),
- GNUNET_PQ_make_prepare (
- "test_refund_full",
- "SELECT"
- " CAST(SUM(CAST(ref.amount_with_fee_frac AS INT8)) AS INT8) AS s_f"
- ",CAST(SUM(ref.amount_with_fee_val) AS INT8) AS s_v"
- ",dep.amount_with_fee_val"
- ",dep.amount_with_fee_frac"
- " FROM refunds ref"
- " JOIN deposits dep"
- " ON (ref.coin_pub=dep.coin_pub AND ref.deposit_serial_id=dep.deposit_serial_id)"
- " WHERE ref.refund_serial_id=$1"
- " GROUP BY (dep.amount_with_fee_val, dep.amount_with_fee_frac);",
- 1),
-
- /* Store information about a /deposit the exchange is to execute.
- Used in #postgres_insert_deposit(). Only used in test cases. */
- GNUNET_PQ_make_prepare (
- "insert_deposit",
- "INSERT INTO deposits "
- "(known_coin_id"
- ",coin_pub"
- ",amount_with_fee_val"
- ",amount_with_fee_frac"
- ",wallet_timestamp"
- ",refund_deadline"
- ",wire_deadline"
- ",merchant_pub"
- ",h_contract_terms"
- ",wire_salt"
- ",wire_target_h_payto"
- ",coin_sig"
- ",exchange_timestamp"
- ",shard"
- ") SELECT known_coin_id, $1, $2, $3, $4, $5, $6, "
- " $7, $8, $9, $10, $11, $12, $13"
- " FROM known_coins"
- " WHERE coin_pub=$1"
- " ON CONFLICT DO NOTHING;",
- 13),
- /* Fetch an existing deposit request, used to ensure idempotency
- during /deposit processing. Used in #postgres_have_deposit(). */
- GNUNET_PQ_make_prepare (
- "get_deposit",
- "SELECT"
- " dep.amount_with_fee_val"
- ",dep.amount_with_fee_frac"
- ",denominations.fee_deposit_val"
- ",denominations.fee_deposit_frac"
- ",dep.wallet_timestamp"
- ",dep.exchange_timestamp"
- ",dep.refund_deadline"
- ",dep.wire_deadline"
- ",dep.h_contract_terms"
- ",dep.wire_salt"
- ",wt.payto_uri AS receiver_wire_account"
- " FROM deposits dep"
- " JOIN known_coins kc ON (kc.coin_pub = dep.coin_pub)"
- " JOIN denominations USING (denominations_serial)"
- " JOIN wire_targets wt USING (wire_target_h_payto)"
- " WHERE dep.coin_pub=$1"
- " AND dep.merchant_pub=$3"
- " AND dep.h_contract_terms=$2;",
- 3),
- /* Fetch deposits with rowid '\geq' the given parameter */
- GNUNET_PQ_make_prepare (
- "audit_get_deposits_incr",
- "SELECT"
- " amount_with_fee_val"
- ",amount_with_fee_frac"
- ",wallet_timestamp"
- ",exchange_timestamp"
- ",merchant_pub"
- ",denom.denom_pub"
- ",kc.coin_pub"
- ",kc.age_commitment_hash"
- ",coin_sig"
- ",refund_deadline"
- ",wire_deadline"
- ",h_contract_terms"
- ",wire_salt"
- ",payto_uri AS receiver_wire_account"
- ",done"
- ",deposit_serial_id"
- " FROM deposits"
- " JOIN wire_targets USING (wire_target_h_payto)"
- " JOIN known_coins kc USING (coin_pub)"
- " JOIN denominations denom USING (denominations_serial)"
- " WHERE ("
- " (deposit_serial_id>=$1)"
- " )"
- " ORDER BY deposit_serial_id ASC;",
- 1),
- /* Fetch purse deposits with rowid '\geq' the given parameter */
- GNUNET_PQ_make_prepare (
- "audit_get_purse_deposits_incr",
- "SELECT"
- " pd.amount_with_fee_val"
- ",pd.amount_with_fee_frac"
- ",pr.amount_with_fee_val AS total_val"
- ",pr.amount_with_fee_frac AS total_frac"
- ",pr.balance_val"
- ",pr.balance_frac"
- ",pr.flags"
- ",pd.purse_pub"
- ",pd.coin_sig"
- ",partner_base_url"
- ",denom.denom_pub"
- ",pm.reserve_pub"
- ",kc.coin_pub"
- ",kc.age_commitment_hash"
- ",pd.purse_deposit_serial_id"
- " FROM purse_deposits pd"
- " LEFT JOIN partners USING (partner_serial_id)"
- " LEFT JOIN purse_merges pm USING (purse_pub)"
- " JOIN purse_requests pr USING (purse_pub)"
- " JOIN known_coins kc USING (coin_pub)"
- " JOIN denominations denom USING (denominations_serial)"
- " WHERE ("
- " (purse_deposit_serial_id>=$1)"
- " )"
- " ORDER BY purse_deposit_serial_id ASC;",
- 1),
-
- GNUNET_PQ_make_prepare (
- "audit_get_account_merge_incr",
- "SELECT"
- " am.account_merge_request_serial_id"
- ",am.reserve_pub"
- ",am.purse_pub"
- ",pr.h_contract_terms"
- ",pr.purse_expiration"
- ",pr.amount_with_fee_val"
- ",pr.amount_with_fee_frac"
- ",pr.age_limit"
- ",pr.flags"
- ",pr.purse_fee_val"
- ",pr.purse_fee_frac"
- ",pm.merge_timestamp"
- ",am.reserve_sig"
- " FROM account_merges am"
- " JOIN purse_requests pr USING (purse_pub)"
- " JOIN purse_merges pm USING (purse_pub)"
- " WHERE ("
- " (account_merge_request_serial_id>=$1)"
- " )"
- " ORDER BY account_merge_request_serial_id ASC;",
- 1),
-
- GNUNET_PQ_make_prepare (
- "audit_get_purse_merge_incr",
- "SELECT"
- " pm.purse_merge_request_serial_id"
- ",partner_base_url"
- ",pr.amount_with_fee_val"
- ",pr.amount_with_fee_frac"
- ",pr.balance_val"
- ",pr.balance_frac"
- ",pr.flags"
- ",pr.merge_pub"
- ",pm.reserve_pub"
- ",pm.merge_sig"
- ",pm.purse_pub"
- ",pm.merge_timestamp"
- " FROM purse_merges pm"
- " JOIN purse_requests pr USING (purse_pub)"
- " LEFT JOIN partners USING (partner_serial_id)"
- " WHERE ("
- " (purse_merge_request_serial_id>=$1)"
- " )"
- " ORDER BY purse_merge_request_serial_id ASC;",
- 1),
-
- GNUNET_PQ_make_prepare (
- "audit_get_history_requests_incr",
- "SELECT"
- " history_request_serial_id"
- ",history_fee_val"
- ",history_fee_frac"
- ",request_timestamp"
- ",reserve_pub"
- ",reserve_sig"
- " FROM history_requests"
- " WHERE ("
- " (history_request_serial_id>=$1)"
- " )"
- " ORDER BY history_request_serial_id ASC;",
- 1),
-
-
- GNUNET_PQ_make_prepare (
- "audit_get_purse_deposits_by_purse",
- "SELECT"
- " pd.purse_deposit_serial_id"
- ",pd.amount_with_fee_val"
- ",pd.amount_with_fee_frac"
- ",pd.coin_pub"
- ",denom.denom_pub"
- " FROM purse_deposits pd"
- " JOIN known_coins kc USING (coin_pub)"
- " JOIN denominations denom USING (denominations_serial)"
- " WHERE purse_pub=$1;",
- 1),
- GNUNET_PQ_make_prepare (
- "audit_get_purse_refunds_incr",
- "SELECT"
- " purse_pub"
- ",purse_refunds_serial_id"
- " FROM purse_refunds"
- " WHERE ("
- " (purse_refunds_serial_id>=$1)"
- " )"
- " ORDER BY purse_refunds_serial_id ASC;",
- 1),
- /* Fetch an existing deposit request.
- Used in #postgres_lookup_transfer_by_deposit(). */
- GNUNET_PQ_make_prepare (
- "get_deposit_without_wtid",
- "SELECT"
- " wt.kyc_ok"
- ",wt.wire_target_serial_id AS payment_target_uuid"
- ",dep.wire_salt"
- ",wt.payto_uri"
- ",dep.amount_with_fee_val"
- ",dep.amount_with_fee_frac"
- ",denom.fee_deposit_val"
- ",denom.fee_deposit_frac"
- ",dep.wire_deadline"
- " FROM deposits dep"
- " JOIN wire_targets wt USING (wire_target_h_payto)"
- " JOIN known_coins kc ON (kc.coin_pub = dep.coin_pub)"
- " JOIN denominations denom USING (denominations_serial)"
- " WHERE dep.coin_pub=$1"
- " AND dep.merchant_pub=$3"
- " AND dep.h_contract_terms=$2;",
- 3),
- /* Used in #postgres_get_ready_deposit() */
- GNUNET_PQ_make_prepare (
- "deposits_get_ready",
- "SELECT"
- " payto_uri"
- ",merchant_pub"
- " FROM deposits_by_ready dbr"
- " JOIN deposits dep"
- " ON (dbr.coin_pub = dep.coin_pub AND dbr.deposit_serial_id = dep.deposit_serial_id)"
- " JOIN wire_targets wt"
- " USING (wire_target_h_payto)"
- " WHERE dbr.wire_deadline<=$1"
- " AND dbr.shard >= $2"
- " AND dbr.shard <= $3"
- " AND (wt.kyc_ok OR $4)"
- " ORDER BY "
- " dbr.wire_deadline ASC"
- " ,dbr.shard ASC"
- " LIMIT 1;",
- 4),
- /* Used in #postgres_aggregate() */
- GNUNET_PQ_make_prepare (
- "aggregate",
- "WITH rdy AS (" /* find deposits ready by merchant */
- " SELECT"
- " coin_pub"
- " FROM deposits_for_matching"
- " WHERE refund_deadline<$1" /* filter by shard, only actually executable deposits */
- " AND merchant_pub=$2" /* filter by target merchant */
- " ORDER BY refund_deadline ASC" /* ordering is not critical */
- " LIMIT "
- TALER_QUOTE (TALER_EXCHANGEDB_MATCHING_DEPOSITS_LIMIT) /* limits transaction size */
- " )"
- " ,dep AS (" /* restrict to our merchant and account and mark as done */
- " UPDATE deposits"
- " SET done=TRUE"
- " WHERE coin_pub IN (SELECT coin_pub FROM rdy)"
- " AND merchant_pub=$2" /* theoretically, same coin could be spent at another merchant */
- " AND wire_target_h_payto=$3" /* merchant could have a 2nd bank account */
- " AND done=FALSE" /* theoretically, same coin could be spend at the same merchant a 2nd time */
- " RETURNING"
- " deposit_serial_id"
- " ,coin_pub"
- " ,amount_with_fee_val AS amount_val"
- " ,amount_with_fee_frac AS amount_frac)"
- " ,ref AS (" /* find applicable refunds -- NOTE: may do a full join on the master, maybe find a left-join way to integrate with query above to push it to the shards? */
- " SELECT"
- " amount_with_fee_val AS refund_val"
- " ,amount_with_fee_frac AS refund_frac"
- " ,coin_pub"
- " ,deposit_serial_id" /* theoretically, coin could be in multiple refunded transactions */
- " FROM refunds"
- " WHERE coin_pub IN (SELECT coin_pub FROM dep)"
- " AND deposit_serial_id IN (SELECT deposit_serial_id FROM dep))"
- " ,coins_with_fees AS (" /* find coins for which deposit fees apply */
- " SELECT"
- " coin_pub"
- " ,deposit_serial_id" /* ensures that if the same coin is deposited twice, it is in the list twice */
- " FROM dep"
- " WHERE deposit_serial_id NOT IN (SELECT deposit_serial_id FROM ref))"
- " ,fees AS (" /* find deposit fees for non-refunded deposits */
- " SELECT"
- " denom.fee_deposit_val AS fee_val"
- " ,denom.fee_deposit_frac AS fee_frac"
- " ,cs.deposit_serial_id" /* ensures we get the fee for each coin, not once per denomination */
- " FROM coins_with_fees cs"
- " JOIN known_coins kc" /* NOTE: may do a full join on the master, maybe find a left-join way to integrate with query above to push it to the shards? */
- " USING (coin_pub)"
- " JOIN denominations denom"
- " USING (denominations_serial))"
- " ,dummy AS (" /* add deposits to aggregation_tracking */
- " INSERT INTO aggregation_tracking"
- " (deposit_serial_id"
- " ,wtid_raw)"
- " SELECT deposit_serial_id,$4"
- " FROM dep)"
- "SELECT" /* calculate totals (deposits, refunds and fees) */
- " CAST(COALESCE(SUM(dep.amount_val),0) AS INT8) AS sum_deposit_value" /* cast needed, otherwise we get NUMBER */
- " ,COALESCE(SUM(dep.amount_frac),0) AS sum_deposit_fraction" /* SUM over INT returns INT8 */
- " ,CAST(COALESCE(SUM(ref.refund_val),0) AS INT8) AS sum_refund_value"
- " ,COALESCE(SUM(ref.refund_frac),0) AS sum_refund_fraction"
- " ,CAST(COALESCE(SUM(fees.fee_val),0) AS INT8) AS sum_fee_value"
- " ,COALESCE(SUM(fees.fee_frac),0) AS sum_fee_fraction"
- " FROM dep "
- " FULL OUTER JOIN ref ON (FALSE)" /* We just want all sums */
- " FULL OUTER JOIN fees ON (FALSE);",
- 4),
-
-
- /* Used in #postgres_create_aggregation_transient() */
- GNUNET_PQ_make_prepare (
- "create_aggregation_transient",
- "INSERT INTO aggregation_transient"
- " (amount_val"
- " ,amount_frac"
- " ,wire_target_h_payto"
- " ,exchange_account_section"
- " ,wtid_raw)"
- " VALUES ($1, $2, $3, $4, $5);",
- 5),
- /* Used in #postgres_select_aggregation_transient() */
- GNUNET_PQ_make_prepare (
- "select_aggregation_transient",
- "SELECT"
- " amount_val"
- " ,amount_frac"
- " ,wtid_raw"
- " FROM aggregation_transient"
- " WHERE wire_target_h_payto=$1"
- " AND exchange_account_section=$2;",
- 2),
- /* Used in #postgres_update_aggregation_transient() */
- GNUNET_PQ_make_prepare (
- "update_aggregation_transient",
- "UPDATE aggregation_transient"
- " SET amount_val=$1"
- " ,amount_frac=$2"
- " WHERE wire_target_h_payto=$3"
- " AND wtid_raw=$4",
- 4),
- /* Used in #postgres_delete_aggregation_transient() */
- GNUNET_PQ_make_prepare (
- "delete_aggregation_transient",
- "DELETE FROM aggregation_transient"
- " WHERE wire_target_h_payto=$1"
- " AND wtid_raw=$2",
- 2),
-
- /* Used in #postgres_get_coin_transactions() to obtain information
- about how a coin has been spend with /deposit requests. */
- GNUNET_PQ_make_prepare (
- "get_deposit_with_coin_pub",
- "SELECT"
- " dep.amount_with_fee_val"
- ",dep.amount_with_fee_frac"
- ",denoms.fee_deposit_val"
- ",denoms.fee_deposit_frac"
- ",denoms.denom_pub_hash"
- ",kc.age_commitment_hash"
- ",dep.wallet_timestamp"
- ",dep.refund_deadline"
- ",dep.wire_deadline"
- ",dep.merchant_pub"
- ",dep.h_contract_terms"
- ",dep.wire_salt"
- ",wt.payto_uri"
- ",dep.coin_sig"
- ",dep.deposit_serial_id"
- ",dep.done"
- " FROM deposits dep"
- " JOIN wire_targets wt"
- " USING (wire_target_h_payto)"
- " JOIN known_coins kc"
- " ON (kc.coin_pub = dep.coin_pub)"
- " JOIN denominations denoms"
- " USING (denominations_serial)"
- " WHERE dep.coin_pub=$1;",
- 1),
-
- /* Used in #postgres_get_link_data(). */
- GNUNET_PQ_make_prepare (
- "get_link",
- "SELECT "
- " tp.transfer_pub"
- ",denoms.denom_pub"
- ",rrc.ev_sig"
- ",rrc.ewv"
- ",rrc.link_sig"
- ",rrc.freshcoin_index"
- ",rrc.coin_ev"
- " FROM refresh_commitments"
- " JOIN refresh_revealed_coins rrc"
- " USING (melt_serial_id)"
- " JOIN refresh_transfer_keys tp"
- " USING (melt_serial_id)"
- " JOIN denominations denoms"
- " ON (rrc.denominations_serial = denoms.denominations_serial)"
- " WHERE old_coin_pub=$1"
- " ORDER BY tp.transfer_pub, rrc.freshcoin_index ASC",
- 1),
- /* Used in #postgres_lookup_wire_transfer */
- GNUNET_PQ_make_prepare (
- "lookup_transactions",
- "SELECT"
- " aggregation_serial_id"
- ",deposits.h_contract_terms"
- ",payto_uri"
- ",wire_targets.wire_target_h_payto"
- ",kc.coin_pub"
- ",deposits.merchant_pub"
- ",wire_out.execution_date"
- ",deposits.amount_with_fee_val"
- ",deposits.amount_with_fee_frac"
- ",denom.fee_deposit_val"
- ",denom.fee_deposit_frac"
- ",denom.denom_pub"
- " FROM aggregation_tracking"
- " JOIN deposits"
- " USING (deposit_serial_id)"
- " JOIN wire_targets"
- " USING (wire_target_h_payto)"
- " JOIN known_coins kc"
- " USING (coin_pub)"
- " JOIN denominations denom"
- " USING (denominations_serial)"
- " JOIN wire_out"
- " USING (wtid_raw)"
- " WHERE wtid_raw=$1;",
- 1),
- /* Used in #postgres_lookup_transfer_by_deposit */
- GNUNET_PQ_make_prepare (
- "lookup_deposit_wtid",
- "SELECT"
- " aggregation_tracking.wtid_raw"
- ",wire_out.execution_date"
- ",dep.amount_with_fee_val"
- ",dep.amount_with_fee_frac"
- ",dep.wire_salt"
- ",wt.payto_uri"
- ",denom.fee_deposit_val"
- ",denom.fee_deposit_frac"
- " FROM deposits dep"
- " JOIN wire_targets wt"
- " USING (wire_target_h_payto)"
- " JOIN aggregation_tracking"
- " USING (deposit_serial_id)"
- " JOIN known_coins kc"
- " ON (kc.coin_pub = dep.coin_pub)"
- " JOIN denominations denom"
- " USING (denominations_serial)"
- " JOIN wire_out"
- " USING (wtid_raw)"
- " WHERE dep.coin_pub=$1"
- " AND dep.merchant_pub=$3"
- " AND dep.h_contract_terms=$2",
- 3),
- /* Used in #postgres_insert_aggregation_tracking */
- GNUNET_PQ_make_prepare (
- "insert_aggregation_tracking",
- "INSERT INTO aggregation_tracking "
- "(deposit_serial_id"
- ",wtid_raw"
- ") VALUES "
- "($1, $2);",
- 2),
- /* Used in #postgres_get_wire_fee() */
- GNUNET_PQ_make_prepare (
- "get_wire_fee",
- "SELECT "
- " start_date"
- ",end_date"
- ",wire_fee_val"
- ",wire_fee_frac"
- ",closing_fee_val"
- ",closing_fee_frac"
- ",wad_fee_val"
- ",wad_fee_frac"
- ",master_sig"
- " FROM wire_fee"
- " WHERE wire_method=$1"
- " AND start_date <= $2"
- " AND end_date > $2;",
- 2),
- /* Used in #postgres_get_global_fee() */
- GNUNET_PQ_make_prepare (
- "get_global_fee",
- "SELECT "
- " start_date"
- ",end_date"
- ",history_fee_val"
- ",history_fee_frac"
- ",kyc_fee_val"
- ",kyc_fee_frac"
- ",account_fee_val"
- ",account_fee_frac"
- ",purse_fee_val"
- ",purse_fee_frac"
- ",purse_timeout"
- ",kyc_timeout"
- ",history_expiration"
- ",purse_account_limit"
- ",master_sig"
- " FROM global_fee"
- " WHERE start_date <= $1"
- " AND end_date > $1;",
- 1),
- /* Used in #postgres_get_global_fees() */
- GNUNET_PQ_make_prepare (
- "get_global_fees",
- "SELECT "
- " start_date"
- ",end_date"
- ",history_fee_val"
- ",history_fee_frac"
- ",kyc_fee_val"
- ",kyc_fee_frac"
- ",account_fee_val"
- ",account_fee_frac"
- ",purse_fee_val"
- ",purse_fee_frac"
- ",purse_timeout"
- ",kyc_timeout"
- ",history_expiration"
- ",purse_account_limit"
- ",master_sig"
- " FROM global_fee"
- " WHERE start_date >= $1",
- 1),
- /* Used in #postgres_insert_wire_fee */
- GNUNET_PQ_make_prepare (
- "insert_wire_fee",
- "INSERT INTO wire_fee "
- "(wire_method"
- ",start_date"
- ",end_date"
- ",wire_fee_val"
- ",wire_fee_frac"
- ",closing_fee_val"
- ",closing_fee_frac"
- ",wad_fee_val"
- ",wad_fee_frac"
- ",master_sig"
- ") VALUES "
- "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10);",
- 10),
- /* Used in #postgres_insert_global_fee */
- GNUNET_PQ_make_prepare (
- "insert_global_fee",
- "INSERT INTO global_fee "
- "(start_date"
- ",end_date"
- ",history_fee_val"
- ",history_fee_frac"
- ",kyc_fee_val"
- ",kyc_fee_frac"
- ",account_fee_val"
- ",account_fee_frac"
- ",purse_fee_val"
- ",purse_fee_frac"
- ",purse_timeout"
- ",kyc_timeout"
- ",history_expiration"
- ",purse_account_limit"
- ",master_sig"
- ") VALUES "
- "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15);",
- 15),
- /* Used in #postgres_store_wire_transfer_out */
- GNUNET_PQ_make_prepare (
- "insert_wire_out",
- "INSERT INTO wire_out "
- "(execution_date"
- ",wtid_raw"
- ",wire_target_h_payto"
- ",exchange_account_section"
- ",amount_val"
- ",amount_frac"
- ") VALUES "
- "($1, $2, $3, $4, $5, $6);",
- 6),
- GNUNET_PQ_make_prepare (
- "insert_into_table_wire_out",
- "INSERT INTO wire_out"
- "(wireout_uuid"
- ",execution_date"
- ",wtid_raw"
- ",wire_target_h_payto"
- ",exchange_account_section"
- ",amount_val"
- ",amount_frac"
- ") VALUES "
- "($1, $2, $3, $4, $5, $6, $7);",
- 7),
- /* Used in #postgres_wire_prepare_data_insert() to store
- wire transfer information before actually committing it with the bank */
- GNUNET_PQ_make_prepare (
- "wire_prepare_data_insert",
- "INSERT INTO prewire "
- "(wire_method"
- ",buf"
- ") VALUES "
- "($1, $2);",
- 2),
- /* Used in #postgres_wire_prepare_data_mark_finished() */
- GNUNET_PQ_make_prepare (
- "wire_prepare_data_mark_done",
- "UPDATE prewire"
- " SET finished=TRUE"
- " WHERE prewire_uuid=$1;",
- 1),
- /* Used in #postgres_wire_prepare_data_mark_failed() */
- GNUNET_PQ_make_prepare (
- "wire_prepare_data_mark_failed",
- "UPDATE prewire"
- " SET failed=TRUE"
- " WHERE prewire_uuid=$1;",
- 1),
- /* Used in #postgres_wire_prepare_data_get() */
- GNUNET_PQ_make_prepare (
- "wire_prepare_data_get",
- "SELECT"
- " prewire_uuid"
- ",wire_method"
- ",buf"
- " FROM prewire"
- " WHERE prewire_uuid >= $1"
- " AND finished=FALSE"
- " AND failed=FALSE"
- " ORDER BY prewire_uuid ASC"
- " LIMIT $2;",
- 2),
- /* Used in #postgres_select_deposits_missing_wire */
- // FIXME: used by the auditor; can probably be done
- // smarter by checking if 'done' or 'blocked'
- // are set correctly when going over deposits, instead
- // of JOINing with refunds.
- GNUNET_PQ_make_prepare (
- "deposits_get_overdue",
- "SELECT"
- " deposit_serial_id"
- ",coin_pub"
- ",amount_with_fee_val"
- ",amount_with_fee_frac"
- ",payto_uri"
- ",wire_deadline"
- ",done"
- " FROM deposits d"
- " JOIN known_coins"
- " USING (coin_pub)"
- " JOIN wire_targets"
- " USING (wire_target_h_payto)"
- " WHERE wire_deadline >= $1"
- " AND wire_deadline < $2"
- " AND NOT (EXISTS (SELECT 1"
- " FROM refunds r"
- " WHERE (r.coin_pub = d.coin_pub) AND (r.deposit_serial_id = d.deposit_serial_id))"
- " OR EXISTS (SELECT 1"
- " FROM aggregation_tracking"
- " WHERE (aggregation_tracking.deposit_serial_id = d.deposit_serial_id)))"
- " ORDER BY wire_deadline ASC",
- 2),
- /* Used in #postgres_select_wire_out_above_serial_id() */
- GNUNET_PQ_make_prepare (
- "audit_get_wire_incr",
- "SELECT"
- " wireout_uuid"
- ",execution_date"
- ",wtid_raw"
- ",payto_uri"
- ",amount_val"
- ",amount_frac"
- " FROM wire_out"
- " JOIN wire_targets"
- " USING (wire_target_h_payto)"
- " WHERE wireout_uuid>=$1"
- " ORDER BY wireout_uuid ASC;",
- 1),
- /* Used in #postgres_select_wire_out_above_serial_id_by_account() */
- GNUNET_PQ_make_prepare (
- "audit_get_wire_incr_by_account",
- "SELECT"
- " wireout_uuid"
- ",execution_date"
- ",wtid_raw"
- ",payto_uri"
- ",amount_val"
- ",amount_frac"
- " FROM wire_out"
- " JOIN wire_targets"
- " USING (wire_target_h_payto)"
- " WHERE "
- " wireout_uuid>=$1 "
- " AND exchange_account_section=$2"
- " ORDER BY wireout_uuid ASC;",
- 2),
- /* Used in #postgres_select_recoup_above_serial_id() to obtain recoup transactions */
- GNUNET_PQ_make_prepare (
- "recoup_get_incr",
- "SELECT"
- " recoup_uuid"
- ",recoup_timestamp"
- ",reserves.reserve_pub"
- ",coins.coin_pub"
- ",coin_sig"
- ",coin_blind"
- ",ro.h_blind_ev"
- ",denoms.denom_pub_hash"
- ",coins.denom_sig"
- ",coins.age_commitment_hash"
- ",denoms.denom_pub"
- ",amount_val"
- ",amount_frac"
- " FROM recoup"
- " JOIN known_coins coins"
- " USING (coin_pub)"
- " JOIN reserves_out ro"
- " USING (reserve_out_serial_id)"
- " JOIN reserves"
- " USING (reserve_uuid)"
- " JOIN denominations denoms"
- " ON (coins.denominations_serial = denoms.denominations_serial)"
- " WHERE recoup_uuid>=$1"
- " ORDER BY recoup_uuid ASC;",
- 1),
- /* Used in #postgres_select_recoup_refresh_above_serial_id() to obtain
- recoup-refresh transactions */
- GNUNET_PQ_make_prepare (
- "recoup_refresh_get_incr",
- "SELECT"
- " recoup_refresh_uuid"
- ",recoup_timestamp"
- ",old_coins.coin_pub AS old_coin_pub"
- ",new_coins.age_commitment_hash"
- ",old_denoms.denom_pub_hash AS old_denom_pub_hash"
- ",new_coins.coin_pub As coin_pub"
- ",coin_sig"
- ",coin_blind"
- ",new_denoms.denom_pub AS denom_pub"
- ",rrc.h_coin_ev AS h_blind_ev"
- ",new_denoms.denom_pub_hash"
- ",new_coins.denom_sig AS denom_sig"
- ",amount_val"
- ",amount_frac"
- " FROM recoup_refresh"
- " INNER JOIN refresh_revealed_coins rrc"
- " USING (rrc_serial)"
- " INNER JOIN refresh_commitments rfc"
- " ON (rrc.melt_serial_id = rfc.melt_serial_id)"
- " INNER JOIN known_coins old_coins"
- " ON (rfc.old_coin_pub = old_coins.coin_pub)"
- " INNER JOIN known_coins new_coins"
- " ON (new_coins.coin_pub = recoup_refresh.coin_pub)"
- " INNER JOIN denominations new_denoms"
- " ON (new_coins.denominations_serial = new_denoms.denominations_serial)"
- " INNER JOIN denominations old_denoms"
- " ON (old_coins.denominations_serial = old_denoms.denominations_serial)"
- " WHERE recoup_refresh_uuid>=$1"
- " ORDER BY recoup_refresh_uuid ASC;",
- 1),
- /* Used in #postgres_select_reserve_closed_above_serial_id() to
- obtain information about closed reserves */
- GNUNET_PQ_make_prepare (
- "reserves_close_get_incr",
- "SELECT"
- " close_uuid"
- ",reserves.reserve_pub"
- ",execution_date"
- ",wtid"
- ",payto_uri AS receiver_account"
- ",amount_val"
- ",amount_frac"
- ",closing_fee_val"
- ",closing_fee_frac"
- " FROM reserves_close"
- " JOIN wire_targets"
- " USING (wire_target_h_payto)"
- " JOIN reserves"
- " USING (reserve_pub)"
- " WHERE close_uuid>=$1"
- " ORDER BY close_uuid ASC;",
- 1),
- /* Used in #postgres_get_reserve_history() to obtain recoup transactions
- for a reserve - query optimization should be disabled i.e.
- BEGIN; SET LOCAL join_collapse_limit=1; query; COMMIT; */
- GNUNET_PQ_make_prepare (
- "recoup_by_reserve",
- /*
- "SELECT"
- " recoup.coin_pub"
- ",recoup.coin_sig"
- ",recoup.coin_blind"
- ",recoup.amount_val"
- ",recoup.amount_frac"
- ",recoup.recoup_timestamp"
- ",denominations.denom_pub_hash"
- ",known_coins.denom_sig"
- " FROM denominations"
- " JOIN (known_coins"
- " JOIN recoup "
- " ON (recoup.coin_pub = known_coins.coin_pub))"
- " ON (known_coins.denominations_serial = denominations.denominations_serial)"
- " WHERE recoup.coin_pub"
- " IN (SELECT coin_pub"
- " FROM recoup_by_reserve"
- " JOIN (reserves_out"
- " JOIN (reserves_out_by_reserve"
- " JOIN reserves"
- " ON (reserves.reserve_uuid = reserves_out_by_reserve.reserve_uuid))"
- " ON (reserves_out_by_reserve.h_blind_ev = reserves_out.h_blind_ev))"
- " ON (recoup_by_reserve.reserve_out_serial_id = reserves_out.reserve_out_serial_id)"
- " WHERE reserves.reserve_pub=$1);",
- */
- "SELECT robr.coin_pub "
- " ,robr.coin_sig "
- " ,robr.coin_blind "
- " ,robr.amount_val "
- " ,robr.amount_frac "
- " ,robr.recoup_timestamp "
- " ,denominations.denom_pub_hash "
- " ,robr.denom_sig "
- "FROM denominations "
- " JOIN exchange_do_recoup_by_reserve($1) robr"
- " USING (denominations_serial);",
- 1),
- /* Used in #postgres_get_coin_transactions() to obtain recoup transactions
- affecting old coins of refreshed coins */
- GNUNET_PQ_make_prepare (
- "recoup_by_old_coin",
- "SELECT"
- " coins.coin_pub"
- ",coin_sig"
- ",coin_blind"
- ",amount_val"
- ",amount_frac"
- ",recoup_timestamp"
- ",denoms.denom_pub_hash"
- ",coins.denom_sig"
- ",recoup_refresh_uuid"
- " FROM recoup_refresh"
- " JOIN known_coins coins"
- " USING (coin_pub)"
- " JOIN denominations denoms"
- " USING (denominations_serial)"
- " WHERE rrc_serial IN"
- " (SELECT rrc.rrc_serial"
- " FROM refresh_commitments"
- " JOIN refresh_revealed_coins rrc"
- " USING (melt_serial_id)"
- " WHERE old_coin_pub=$1);",
- 1),
- /* Used in #postgres_get_reserve_history() */
- GNUNET_PQ_make_prepare (
- "close_by_reserve",
- "SELECT"
- " amount_val"
- ",amount_frac"
- ",closing_fee_val"
- ",closing_fee_frac"
- ",execution_date"
- ",payto_uri AS receiver_account"
- ",wtid"
- " FROM reserves_close"
- " JOIN wire_targets"
- " USING (wire_target_h_payto)"
- " WHERE reserve_pub=$1;",
- 1),
- /* Used in #postgres_get_reserve_history() */
- GNUNET_PQ_make_prepare (
- "merge_by_reserve",
- "SELECT"
- " pr.amount_with_fee_val"
- ",pr.amount_with_fee_frac"
- ",pr.balance_val"
- ",pr.balance_frac"
- ",pr.purse_fee_val"
- ",pr.purse_fee_frac"
- ",pr.h_contract_terms"
- ",pr.merge_pub"
- ",am.reserve_sig"
- ",pm.purse_pub"
- ",pm.merge_timestamp"
- ",pr.purse_expiration"
- ",pr.age_limit"
- ",pr.flags"
- " FROM purse_merges pm"
- " JOIN purse_requests pr"
- " USING (purse_pub)"
- " JOIN account_merges am"
- " ON (am.purse_pub = pm.purse_pub AND"
- " am.reserve_pub = pm.reserve_pub)"
- " WHERE pm.reserve_pub=$1"
- " AND pm.partner_serial_id=0" /* must be local! */
- " AND pr.finished"
- " AND NOT pr.refunded;",
- 1),
- /* Used in #postgres_get_reserve_history() */
- GNUNET_PQ_make_prepare (
- "history_by_reserve",
- "SELECT"
- " history_fee_val"
- ",history_fee_frac"
- ",request_timestamp"
- ",reserve_sig"
- " FROM history_requests"
- " WHERE reserve_pub=$1;",
- 1),
- /* Used in #postgres_get_expired_reserves() */
- GNUNET_PQ_make_prepare (
- "get_expired_reserves",
- /*
- "SELECT"
- " expiration_date"
- ",payto_uri AS account_details"
- ",reserve_pub"
- ",current_balance_val"
- ",current_balance_frac"
- " FROM reserves"
- " JOIN reserves_in ri"
- " USING (reserve_pub)"
- " JOIN wire_targets wt"
- " ON (ri.wire_source_h_payto = wt.wire_target_h_payto)"
- " WHERE expiration_date<=$1"
- " AND (current_balance_val != 0 "
- " OR current_balance_frac != 0)"
- " ORDER BY expiration_date ASC"
- " LIMIT 1;",
- */
- "WITH ed AS MATERIALIZED ( "
- " SELECT * "
- " FROM reserves "
- " WHERE expiration_date <= $1 "
- " AND (current_balance_val != 0 OR current_balance_frac != 0) "
- " ORDER BY expiration_date ASC "
- " LIMIT 1 "
- ") "
- "SELECT "
- " ed.expiration_date "
- " ,payto_uri AS account_details "
- " ,ed.reserve_pub "
- " ,current_balance_val "
- " ,current_balance_frac "
- "FROM ( "
- " SELECT "
- " * "
- " FROM reserves_in "
- " WHERE reserve_pub = ( "
- " SELECT reserve_pub FROM ed) "
- " ) ri "
- "JOIN wire_targets wt ON (ri.wire_source_h_payto = wt.wire_target_h_payto) "
- "JOIN ed ON (ri.reserve_pub = ed.reserve_pub); ",
- 1),
- /* Used in #postgres_get_coin_transactions() to obtain recoup transactions
- for a coin */
- GNUNET_PQ_make_prepare (
- "recoup_by_coin",
- "SELECT"
- " reserves.reserve_pub"
- ",denoms.denom_pub_hash"
- ",coin_sig"
- ",coin_blind"
- ",amount_val"
- ",amount_frac"
- ",recoup_timestamp"
- ",recoup_uuid"
- " FROM recoup rcp"
- /* NOTE: suboptimal JOIN follows: crosses shards!
- Could theoretically be improved via a materialized
- index. But likely not worth it (query is rare and
- number of reserve shards might be limited) */
- " JOIN reserves_out ro"
- " USING (reserve_out_serial_id)"
- " JOIN reserves"
- " USING (reserve_uuid)"
- " JOIN known_coins coins"
- " USING (coin_pub)"
- " JOIN denominations denoms"
- " ON (denoms.denominations_serial = coins.denominations_serial)"
- " WHERE coins.coin_pub=$1;",
- 1),
- /* Used in #postgres_get_coin_transactions() to obtain recoup transactions
- for a refreshed coin */
- GNUNET_PQ_make_prepare (
- "recoup_by_refreshed_coin",
- "SELECT"
- " old_coins.coin_pub AS old_coin_pub"
- ",coin_sig"
- ",coin_blind"
- ",amount_val"
- ",amount_frac"
- ",recoup_timestamp"
- ",denoms.denom_pub_hash"
- ",coins.denom_sig"
- ",recoup_refresh_uuid"
- " FROM recoup_refresh"
- " JOIN refresh_revealed_coins rrc"
- " USING (rrc_serial)"
- " JOIN refresh_commitments rfc"
- " ON (rrc.melt_serial_id = rfc.melt_serial_id)"
- " JOIN known_coins old_coins"
- " ON (rfc.old_coin_pub = old_coins.coin_pub)"
- " JOIN known_coins coins"
- " ON (recoup_refresh.coin_pub = coins.coin_pub)"
- " JOIN denominations denoms"
- " ON (denoms.denominations_serial = coins.denominations_serial)"
- " WHERE coins.coin_pub=$1;",
- 1),
- /* Used in #postgres_get_reserve_by_h_blind() */
- GNUNET_PQ_make_prepare (
- "reserve_by_h_blind",
- "SELECT"
- " reserves.reserve_pub"
- ",reserve_out_serial_id"
- " FROM reserves_out"
- " JOIN reserves"
- " USING (reserve_uuid)"
- " WHERE h_blind_ev=$1"
- " LIMIT 1;",
- 1),
- /* Used in #postgres_get_old_coin_by_h_blind() */
- GNUNET_PQ_make_prepare (
- "old_coin_by_h_blind",
- "SELECT"
- " okc.coin_pub AS old_coin_pub"
- ",rrc_serial"
- " FROM refresh_revealed_coins rrc"
- " JOIN refresh_commitments rcom USING (melt_serial_id)"
- " JOIN known_coins okc ON (rcom.old_coin_pub = okc.coin_pub)"
- " WHERE h_coin_ev=$1"
- " LIMIT 1;",
- 1),
- /* Used in #postgres_lookup_auditor_timestamp() */
- GNUNET_PQ_make_prepare (
- "lookup_auditor_timestamp",
- "SELECT"
- " last_change"
- " FROM auditors"
- " WHERE auditor_pub=$1;",
- 1),
- /* Used in #postgres_lookup_auditor_status() */
- GNUNET_PQ_make_prepare (
- "lookup_auditor_status",
- "SELECT"
- " auditor_url"
- ",is_active"
- " FROM auditors"
- " WHERE auditor_pub=$1;",
- 1),
- /* Used in #postgres_lookup_wire_timestamp() */
- GNUNET_PQ_make_prepare (
- "lookup_wire_timestamp",
- "SELECT"
- " last_change"
- " FROM wire_accounts"
- " WHERE payto_uri=$1;",
- 1),
- /* used in #postgres_insert_auditor() */
- GNUNET_PQ_make_prepare (
- "insert_auditor",
- "INSERT INTO auditors "
- "(auditor_pub"
- ",auditor_name"
- ",auditor_url"
- ",is_active"
- ",last_change"
- ") VALUES "
- "($1, $2, $3, true, $4);",
- 4),
- /* used in #postgres_update_auditor() */
- GNUNET_PQ_make_prepare (
- "update_auditor",
- "UPDATE auditors"
- " SET"
- " auditor_url=$2"
- " ,auditor_name=$3"
- " ,is_active=$4"
- " ,last_change=$5"
- " WHERE auditor_pub=$1",
- 5),
- /* used in #postgres_insert_wire() */
- GNUNET_PQ_make_prepare (
- "insert_wire",
- "INSERT INTO wire_accounts "
- "(payto_uri"
- ",master_sig"
- ",is_active"
- ",last_change"
- ") VALUES "
- "($1, $2, true, $3);",
- 3),
- /* used in #postgres_update_wire() */
- GNUNET_PQ_make_prepare (
- "update_wire",
- "UPDATE wire_accounts"
- " SET"
- " is_active=$2"
- " ,last_change=$3"
- " WHERE payto_uri=$1",
- 3),
- /* used in #postgres_update_wire() */
- GNUNET_PQ_make_prepare (
- "get_wire_accounts",
- "SELECT"
- " payto_uri"
- ",master_sig"
- " FROM wire_accounts"
- " WHERE is_active",
- 0),
- /* used in #postgres_update_wire() */
- GNUNET_PQ_make_prepare (
- "get_wire_fees",
- "SELECT"
- " wire_fee_val"
- ",wire_fee_frac"
- ",closing_fee_val"
- ",closing_fee_frac"
- ",wad_fee_val"
- ",wad_fee_frac"
- ",start_date"
- ",end_date"
- ",master_sig"
- " FROM wire_fee"
- " WHERE wire_method=$1",
- 1),
- /* used in #postgres_insert_signkey_revocation() */
- GNUNET_PQ_make_prepare (
- "insert_signkey_revocation",
- "INSERT INTO signkey_revocations "
- "(esk_serial"
- ",master_sig"
- ") SELECT esk_serial, $2 "
- " FROM exchange_sign_keys"
- " WHERE exchange_pub=$1;",
- 2),
- /* used in #postgres_insert_signkey_revocation() */
- GNUNET_PQ_make_prepare (
- "lookup_signkey_revocation",
- "SELECT "
- " master_sig"
- " FROM signkey_revocations"
- " WHERE esk_serial="
- " (SELECT esk_serial"
- " FROM exchange_sign_keys"
- " WHERE exchange_pub=$1);",
- 1),
- /* used in #postgres_insert_signkey() */
- GNUNET_PQ_make_prepare (
- "insert_signkey",
- "INSERT INTO exchange_sign_keys "
- "(exchange_pub"
- ",valid_from"
- ",expire_sign"
- ",expire_legal"
- ",master_sig"
- ") VALUES "
- "($1, $2, $3, $4, $5);",
- 5),
- /* used in #postgres_lookup_signing_key() */
- GNUNET_PQ_make_prepare (
- "lookup_signing_key",
- "SELECT"
- " valid_from"
- ",expire_sign"
- ",expire_legal"
- " FROM exchange_sign_keys"
- " WHERE exchange_pub=$1",
- 1),
- /* used in #postgres_lookup_denomination_key() */
- GNUNET_PQ_make_prepare (
- "lookup_denomination_key",
- "SELECT"
- " valid_from"
- ",expire_withdraw"
- ",expire_deposit"
- ",expire_legal"
- ",coin_val"
- ",coin_frac"
- ",fee_withdraw_val"
- ",fee_withdraw_frac"
- ",fee_deposit_val"
- ",fee_deposit_frac"
- ",fee_refresh_val"
- ",fee_refresh_frac"
- ",fee_refund_val"
- ",fee_refund_frac"
- ",age_mask"
- " FROM denominations"
- " WHERE denom_pub_hash=$1;",
- 1),
- /* used in #postgres_insert_auditor_denom_sig() */
- GNUNET_PQ_make_prepare (
- "insert_auditor_denom_sig",
- "WITH ax AS"
- " (SELECT auditor_uuid"
- " FROM auditors"
- " WHERE auditor_pub=$1)"
- "INSERT INTO auditor_denom_sigs "
- "(auditor_uuid"
- ",denominations_serial"
- ",auditor_sig"
- ") SELECT ax.auditor_uuid, denominations_serial, $3 "
- " FROM denominations"
- " CROSS JOIN ax"
- " WHERE denom_pub_hash=$2;",
- 3),
- /* used in #postgres_select_auditor_denom_sig() */
- GNUNET_PQ_make_prepare (
- "select_auditor_denom_sig",
- "SELECT"
- " auditor_sig"
- " FROM auditor_denom_sigs"
- " WHERE auditor_uuid="
- " (SELECT auditor_uuid"
- " FROM auditors"
- " WHERE auditor_pub=$1)"
- " AND denominations_serial="
- " (SELECT denominations_serial"
- " FROM denominations"
- " WHERE denom_pub_hash=$2);",
- 2),
- /* used in #postgres_lookup_wire_fee_by_time() */
- GNUNET_PQ_make_prepare (
- "lookup_wire_fee_by_time",
- "SELECT"
- " wire_fee_val"
- ",wire_fee_frac"
- ",closing_fee_val"
- ",closing_fee_frac"
- ",wad_fee_val"
- ",wad_fee_frac"
- " FROM wire_fee"
- " WHERE wire_method=$1"
- " AND end_date > $2"
- " AND start_date < $3;",
- 1),
- /* used in #postgres_lookup_wire_fee_by_time() */
- GNUNET_PQ_make_prepare (
- "lookup_global_fee_by_time",
- "SELECT"
- " history_fee_val"
- ",history_fee_frac"
- ",kyc_fee_val"
- ",kyc_fee_frac"
- ",account_fee_val"
- ",account_fee_frac"
- ",purse_fee_val"
- ",purse_fee_frac"
- ",purse_timeout"
- ",kyc_timeout"
- ",history_expiration"
- ",purse_account_limit"
- " FROM global_fee"
- " WHERE end_date > $1"
- " AND start_date < $2;",
- 1),
- /* used in #postgres_commit */
- GNUNET_PQ_make_prepare (
- "do_commit",
- "COMMIT",
- 0),
- /* used in #postgres_lookup_serial_by_table() */
- GNUNET_PQ_make_prepare (
- "select_serial_by_table_denominations",
- "SELECT"
- " denominations_serial AS serial"
- " FROM denominations"
- " ORDER BY denominations_serial DESC"
- " LIMIT 1;",
- 0),
- GNUNET_PQ_make_prepare (
- "select_serial_by_table_denomination_revocations",
- "SELECT"
- " denom_revocations_serial_id AS serial"
- " FROM denomination_revocations"
- " ORDER BY denom_revocations_serial_id DESC"
- " LIMIT 1;",
- 0),
- GNUNET_PQ_make_prepare (
- "select_serial_by_table_wire_targets",
- "SELECT"
- " wire_target_serial_id AS serial"
- " FROM wire_targets"
- " ORDER BY wire_target_serial_id DESC"
- " LIMIT 1;",
- 0),
- GNUNET_PQ_make_prepare (
- "select_serial_by_table_reserves",
- "SELECT"
- " reserve_uuid AS serial"
- " FROM reserves"
- " ORDER BY reserve_uuid DESC"
- " LIMIT 1;",
- 0),
- GNUNET_PQ_make_prepare (
- "select_serial_by_table_reserves_in",
- "SELECT"
- " reserve_in_serial_id AS serial"
- " FROM reserves_in"
- " ORDER BY reserve_in_serial_id DESC"
- " LIMIT 1;",
- 0),
- GNUNET_PQ_make_prepare (
- "select_serial_by_table_reserves_close",
- "SELECT"
- " close_uuid AS serial"
- " FROM reserves_close"
- " ORDER BY close_uuid DESC"
- " LIMIT 1;",
- 0),
- GNUNET_PQ_make_prepare (
- "select_serial_by_table_reserves_out",
- "SELECT"
- " reserve_out_serial_id AS serial"
- " FROM reserves_out"
- " ORDER BY reserve_out_serial_id DESC"
- " LIMIT 1;",
- 0),
- GNUNET_PQ_make_prepare (
- "select_serial_by_table_auditors",
- "SELECT"
- " auditor_uuid AS serial"
- " FROM auditors"
- " ORDER BY auditor_uuid DESC"
- " LIMIT 1;",
- 0),
- GNUNET_PQ_make_prepare (
- "select_serial_by_table_auditor_denom_sigs",
- "SELECT"
- " auditor_denom_serial AS serial"
- " FROM auditor_denom_sigs"
- " ORDER BY auditor_denom_serial DESC"
- " LIMIT 1;",
- 0),
- GNUNET_PQ_make_prepare (
- "select_serial_by_table_exchange_sign_keys",
- "SELECT"
- " esk_serial AS serial"
- " FROM exchange_sign_keys"
- " ORDER BY esk_serial DESC"
- " LIMIT 1;",
- 0),
- GNUNET_PQ_make_prepare (
- "select_serial_by_table_signkey_revocations",
- "SELECT"
- " signkey_revocations_serial_id AS serial"
- " FROM signkey_revocations"
- " ORDER BY signkey_revocations_serial_id DESC"
- " LIMIT 1;",
- 0),
- GNUNET_PQ_make_prepare (
- "select_serial_by_table_known_coins",
- "SELECT"
- " known_coin_id AS serial"
- " FROM known_coins"
- " ORDER BY known_coin_id DESC"
- " LIMIT 1;",
- 0),
- GNUNET_PQ_make_prepare (
- "select_serial_by_table_refresh_commitments",
- "SELECT"
- " melt_serial_id AS serial"
- " FROM refresh_commitments"
- " ORDER BY melt_serial_id DESC"
- " LIMIT 1;",
- 0),
- GNUNET_PQ_make_prepare (
- "select_serial_by_table_refresh_revealed_coins",
- "SELECT"
- " rrc_serial AS serial"
- " FROM refresh_revealed_coins"
- " ORDER BY rrc_serial DESC"
- " LIMIT 1;",
- 0),
- GNUNET_PQ_make_prepare (
- "select_serial_by_table_refresh_transfer_keys",
- "SELECT"
- " rtc_serial AS serial"
- " FROM refresh_transfer_keys"
- " ORDER BY rtc_serial DESC"
- " LIMIT 1;",
- 0),
- GNUNET_PQ_make_prepare (
- "select_serial_by_table_deposits",
- "SELECT"
- " deposit_serial_id AS serial"
- " FROM deposits"
- " ORDER BY deposit_serial_id DESC"
- " LIMIT 1;",
- 0),
- GNUNET_PQ_make_prepare (
- "select_serial_by_table_refunds",
- "SELECT"
- " refund_serial_id AS serial"
- " FROM refunds"
- " ORDER BY refund_serial_id DESC"
- " LIMIT 1;",
- 0),
- GNUNET_PQ_make_prepare (
- "select_serial_by_table_wire_out",
- "SELECT"
- " wireout_uuid AS serial"
- " FROM wire_out"
- " ORDER BY wireout_uuid DESC"
- " LIMIT 1;",
- 0),
- GNUNET_PQ_make_prepare (
- "select_serial_by_table_aggregation_tracking",
- "SELECT"
- " aggregation_serial_id AS serial"
- " FROM aggregation_tracking"
- " ORDER BY aggregation_serial_id DESC"
- " LIMIT 1;",
- 0),
- GNUNET_PQ_make_prepare (
- "select_serial_by_table_wire_fee",
- "SELECT"
- " wire_fee_serial AS serial"
- " FROM wire_fee"
- " ORDER BY wire_fee_serial DESC"
- " LIMIT 1;",
- 0),
- GNUNET_PQ_make_prepare (
- "select_serial_by_table_global_fee",
- "SELECT"
- " global_fee_serial AS serial"
- " FROM global_fee"
- " ORDER BY global_fee_serial DESC"
- " LIMIT 1;",
- 0),
- GNUNET_PQ_make_prepare (
- "select_serial_by_table_recoup",
- "SELECT"
- " recoup_uuid AS serial"
- " FROM recoup"
- " ORDER BY recoup_uuid DESC"
- " LIMIT 1;",
- 0),
- GNUNET_PQ_make_prepare (
- "select_serial_by_table_recoup_refresh",
- "SELECT"
- " recoup_refresh_uuid AS serial"
- " FROM recoup_refresh"
- " ORDER BY recoup_refresh_uuid DESC"
- " LIMIT 1;",
- 0),
- GNUNET_PQ_make_prepare (
- "select_serial_by_table_extensions",
- "SELECT"
- " extension_id AS serial"
- " FROM extensions"
- " ORDER BY extension_id DESC"
- " LIMIT 1;",
- 0),
- GNUNET_PQ_make_prepare (
- "select_serial_by_table_extension_details",
- "SELECT"
- " extension_details_serial_id AS serial"
- " FROM extension_details"
- " ORDER BY extension_details_serial_id DESC"
- " LIMIT 1;",
- 0),
- GNUNET_PQ_make_prepare (
- "select_serial_by_table_purse_requests",
- "SELECT"
- " purse_requests_serial_id AS serial"
- " FROM purse_requests"
- " ORDER BY purse_requests_serial_id DESC"
- " LIMIT 1;",
- 0),
- GNUNET_PQ_make_prepare (
- "select_serial_by_table_purse_refunds",
- "SELECT"
- " purse_refunds_serial_id AS serial"
- " FROM purse_refunds"
- " ORDER BY purse_refunds_serial_id DESC"
- " LIMIT 1;",
- 0),
- GNUNET_PQ_make_prepare (
- "select_serial_by_table_purse_merges",
- "SELECT"
- " purse_merge_request_serial_id AS serial"
- " FROM purse_merges"
- " ORDER BY purse_merge_request_serial_id DESC"
- " LIMIT 1;",
- 0),
- GNUNET_PQ_make_prepare (
- "select_serial_by_table_purse_deposits",
- "SELECT"
- " purse_deposit_serial_id AS serial"
- " FROM purse_deposits"
- " ORDER BY purse_deposit_serial_id DESC"
- " LIMIT 1;",
- 0),
- GNUNET_PQ_make_prepare (
- "select_serial_by_table_account_merges",
- "SELECT"
- " account_merge_request_serial_id AS serial"
- " FROM account_merges"
- " ORDER BY account_merge_request_serial_id DESC"
- " LIMIT 1;",
- 0),
- GNUNET_PQ_make_prepare (
- "select_serial_by_table_history_requests",
- "SELECT"
- " history_request_serial_id AS serial"
- " FROM history_requests"
- " ORDER BY history_request_serial_id DESC"
- " LIMIT 1;",
- 0),
- GNUNET_PQ_make_prepare (
- "select_serial_by_table_close_requests",
- "SELECT"
- " close_request_serial_id AS serial"
- " FROM close_requests"
- " ORDER BY close_request_serial_id DESC"
- " LIMIT 1;",
- 0),
- GNUNET_PQ_make_prepare (
- "select_serial_by_table_wads_out",
- "SELECT"
- " wad_out_serial_id AS serial"
- " FROM wads_out"
- " ORDER BY wad_out_serial_id DESC"
- " LIMIT 1;",
- 0),
- GNUNET_PQ_make_prepare (
- "select_serial_by_table_wads_out_entries",
- "SELECT"
- " wad_out_entry_serial_id AS serial"
- " FROM wad_out_entries"
- " ORDER BY wad_out_entry_serial_id DESC"
- " LIMIT 1;",
- 0),
- GNUNET_PQ_make_prepare (
- "select_serial_by_table_wads_in",
- "SELECT"
- " wad_in_serial_id AS serial"
- " FROM wads_in"
- " ORDER BY wad_in_serial_id DESC"
- " LIMIT 1;",
- 0),
- GNUNET_PQ_make_prepare (
- "select_serial_by_table_wads_in_entries",
- "SELECT"
- " wad_in_entry_serial_id AS serial"
- " FROM wad_in_entries"
- " ORDER BY wad_in_entry_serial_id DESC"
- " LIMIT 1;",
- 0),
- /* For postgres_lookup_records_by_table */
- GNUNET_PQ_make_prepare (
- "select_above_serial_by_table_denominations",
- "SELECT"
- " denominations_serial AS serial"
- ",denom_type"
- ",denom_pub"
- ",master_sig"
- ",valid_from"
- ",expire_withdraw"
- ",expire_deposit"
- ",expire_legal"
- ",coin_val"
- ",coin_frac"
- ",fee_withdraw_val"
- ",fee_withdraw_frac"
- ",fee_deposit_val"
- ",fee_deposit_frac"
- ",fee_refresh_val"
- ",fee_refresh_frac"
- ",fee_refund_val"
- ",fee_refund_frac"
- ",age_mask"
- " FROM denominations"
- " WHERE denominations_serial > $1"
- " ORDER BY denominations_serial ASC;",
- 1),
- GNUNET_PQ_make_prepare (
- "select_above_serial_by_table_denomination_revocations",
- "SELECT"
- " denom_revocations_serial_id AS serial"
- ",master_sig"
- ",denominations_serial"
- " FROM denomination_revocations"
- " WHERE denom_revocations_serial_id > $1"
- " ORDER BY denom_revocations_serial_id ASC;",
- 1),
- GNUNET_PQ_make_prepare (
- "select_above_serial_by_table_wire_targets",
- "SELECT"
- " wire_target_serial_id AS serial"
- ",payto_uri"
- ",kyc_ok"
- ",external_id"
- " FROM wire_targets"
- " WHERE wire_target_serial_id > $1"
- " ORDER BY wire_target_serial_id ASC;",
- 1),
- GNUNET_PQ_make_prepare (
- "select_above_serial_by_table_reserves",
- "SELECT"
- " reserve_uuid AS serial"
- ",reserve_pub"
- ",expiration_date"
- ",gc_date"
- " FROM reserves"
- " WHERE reserve_uuid > $1"
- " ORDER BY reserve_uuid ASC;",
- 1),
- GNUNET_PQ_make_prepare (
- "select_above_serial_by_table_reserves_in",
- "SELECT"
- " reserve_in_serial_id AS serial"
- ",reserve_pub"
- ",wire_reference"
- ",credit_val"
- ",credit_frac"
- ",wire_source_h_payto"
- ",exchange_account_section"
- ",execution_date"
- " FROM reserves_in"
- " WHERE reserve_in_serial_id > $1"
- " ORDER BY reserve_in_serial_id ASC;",
- 1),
- GNUNET_PQ_make_prepare (
- "select_above_serial_by_table_reserves_close",
- "SELECT"
- " close_uuid AS serial"
- ",reserve_pub"
- ",execution_date"
- ",wtid"
- ",wire_target_h_payto"
- ",amount_val"
- ",amount_frac"
- ",closing_fee_val"
- ",closing_fee_frac"
- " FROM reserves_close"
- " WHERE close_uuid > $1"
- " ORDER BY close_uuid ASC;",
- 1),
- GNUNET_PQ_make_prepare (
- "select_above_serial_by_table_reserves_out",
- "SELECT"
- " reserve_out_serial_id AS serial"
- ",h_blind_ev"
- ",denominations_serial"
- ",denom_sig"
- ",reserve_uuid"
- ",reserve_sig"
- ",execution_date"
- ",amount_with_fee_val"
- ",amount_with_fee_frac"
- " FROM reserves_out"
- " JOIN reserves USING (reserve_uuid)"
- " WHERE reserve_out_serial_id > $1"
- " ORDER BY reserve_out_serial_id ASC;",
- 1),
- GNUNET_PQ_make_prepare (
- "select_above_serial_by_table_auditors",
- "SELECT"
- " auditor_uuid AS serial"
- ",auditor_pub"
- ",auditor_name"
- ",auditor_url"
- ",is_active"
- ",last_change"
- " FROM auditors"
- " WHERE auditor_uuid > $1"
- " ORDER BY auditor_uuid ASC;",
- 1),
- GNUNET_PQ_make_prepare (
- "select_above_serial_by_table_auditor_denom_sigs",
- "SELECT"
- " auditor_denom_serial AS serial"
- ",auditor_uuid"
- ",denominations_serial"
- ",auditor_sig"
- " FROM auditor_denom_sigs"
- " WHERE auditor_denom_serial > $1"
- " ORDER BY auditor_denom_serial ASC;",
- 1),
- GNUNET_PQ_make_prepare (
- "select_above_serial_by_table_exchange_sign_keys",
- "SELECT"
- " esk_serial AS serial"
- ",exchange_pub"
- ",master_sig"
- ",valid_from"
- ",expire_sign"
- ",expire_legal"
- " FROM exchange_sign_keys"
- " WHERE esk_serial > $1"
- " ORDER BY esk_serial ASC;",
- 1),
- GNUNET_PQ_make_prepare (
- "select_above_serial_by_table_signkey_revocations",
- "SELECT"
- " signkey_revocations_serial_id AS serial"
- ",esk_serial"
- ",master_sig"
- " FROM signkey_revocations"
- " WHERE signkey_revocations_serial_id > $1"
- " ORDER BY signkey_revocations_serial_id ASC;",
- 1),
- GNUNET_PQ_make_prepare (
- "select_above_serial_by_table_known_coins",
- "SELECT"
- " known_coin_id AS serial"
- ",coin_pub"
- ",denom_sig"
- ",denominations_serial"
- " FROM known_coins"
- " WHERE known_coin_id > $1"
- " ORDER BY known_coin_id ASC;",
- 1),
- GNUNET_PQ_make_prepare (
- "select_above_serial_by_table_refresh_commitments",
- "SELECT"
- " melt_serial_id AS serial"
- ",rc"
- ",old_coin_sig"
- ",amount_with_fee_val"
- ",amount_with_fee_frac"
- ",noreveal_index"
- ",old_coin_pub"
- " FROM refresh_commitments"
- " WHERE melt_serial_id > $1"
- " ORDER BY melt_serial_id ASC;",
- 1),
- GNUNET_PQ_make_prepare (
- "select_above_serial_by_table_refresh_revealed_coins",
- "SELECT"
- " rrc_serial AS serial"
- ",freshcoin_index"
- ",link_sig"
- ",coin_ev"
- ",ev_sig"
- ",ewv"
- ",denominations_serial"
- ",melt_serial_id"
- " FROM refresh_revealed_coins"
- " WHERE rrc_serial > $1"
- " ORDER BY rrc_serial ASC;",
- 1),
- GNUNET_PQ_make_prepare (
- "select_above_serial_by_table_refresh_transfer_keys",
- "SELECT"
- " rtc_serial AS serial"
- ",transfer_pub"
- ",transfer_privs"
- ",melt_serial_id"
- " FROM refresh_transfer_keys"
- " WHERE rtc_serial > $1"
- " ORDER BY rtc_serial ASC;",
- 1),
- GNUNET_PQ_make_prepare (
- "select_above_serial_by_table_deposits",
- "SELECT"
- " deposit_serial_id AS serial"
- ",shard"
- ",coin_pub"
- ",known_coin_id"
- ",amount_with_fee_val"
- ",amount_with_fee_frac"
- ",wallet_timestamp"
- ",exchange_timestamp"
- ",refund_deadline"
- ",wire_deadline"
- ",merchant_pub"
- ",h_contract_terms"
- ",coin_sig"
- ",wire_salt"
- ",wire_target_h_payto"
- ",done"
- ",extension_blocked"
- ",extension_details_serial_id"
- " FROM deposits"
- " WHERE deposit_serial_id > $1"
- " ORDER BY deposit_serial_id ASC;",
- 1),
- GNUNET_PQ_make_prepare (
- "select_above_serial_by_table_refunds",
- "SELECT"
- " refund_serial_id AS serial"
- ",coin_pub"
- ",merchant_sig"
- ",rtransaction_id"
- ",amount_with_fee_val"
- ",amount_with_fee_frac"
- ",deposit_serial_id"
- " FROM refunds"
- " WHERE refund_serial_id > $1"
- " ORDER BY refund_serial_id ASC;",
- 1),
- GNUNET_PQ_make_prepare (
- "select_above_serial_by_table_wire_out",
- "SELECT"
- " wireout_uuid AS serial"
- ",execution_date"
- ",wtid_raw"
- ",wire_target_h_payto"
- ",exchange_account_section"
- ",amount_val"
- ",amount_frac"
- " FROM wire_out"
- " WHERE wireout_uuid > $1"
- " ORDER BY wireout_uuid ASC;",
- 1),
- GNUNET_PQ_make_prepare (
- "select_above_serial_by_table_aggregation_tracking",
- "SELECT"
- " aggregation_serial_id AS serial"
- ",deposit_serial_id"
- ",wtid_raw"
- " FROM aggregation_tracking"
- " WHERE aggregation_serial_id > $1"
- " ORDER BY aggregation_serial_id ASC;",
- 1),
- GNUNET_PQ_make_prepare (
- "select_above_serial_by_table_wire_fee",
- "SELECT"
- " wire_fee_serial AS serial"
- ",wire_method"
- ",start_date"
- ",end_date"
- ",wire_fee_val"
- ",wire_fee_frac"
- ",closing_fee_val"
- ",closing_fee_frac"
- ",wad_fee_val"
- ",wad_fee_frac"
- ",master_sig"
- " FROM wire_fee"
- " WHERE wire_fee_serial > $1"
- " ORDER BY wire_fee_serial ASC;",
- 1),
- GNUNET_PQ_make_prepare (
- "select_above_serial_by_table_global_fee",
- "SELECT"
- " global_fee_serial AS serial"
- ",start_date"
- ",end_date"
- ",history_fee_val"
- ",history_fee_frac"
- ",kyc_fee_val"
- ",kyc_fee_frac"
- ",account_fee_val"
- ",account_fee_frac"
- ",purse_fee_val"
- ",purse_fee_frac"
- ",purse_timeout"
- ",kyc_timeout"
- ",history_expiration"
- ",purse_account_limit"
- ",master_sig"
- " FROM global_fee"
- " WHERE global_fee_serial > $1"
- " ORDER BY global_fee_serial ASC;",
- 1),
- GNUNET_PQ_make_prepare (
- "select_above_serial_by_table_recoup",
- "SELECT"
- " recoup_uuid AS serial"
- ",coin_sig"
- ",coin_blind"
- ",amount_val"
- ",amount_frac"
- ",recoup_timestamp"
- ",coin_pub"
- ",reserve_out_serial_id"
- " FROM recoup"
- " WHERE recoup_uuid > $1"
- " ORDER BY recoup_uuid ASC;",
- 1),
- GNUNET_PQ_make_prepare (
- "select_above_serial_by_table_recoup_refresh",
- "SELECT"
- " recoup_refresh_uuid AS serial"
- ",coin_sig"
- ",coin_blind"
- ",amount_val"
- ",amount_frac"
- ",recoup_timestamp"
- ",coin_pub"
- ",known_coin_id"
- ",rrc_serial"
- " FROM recoup_refresh"
- " WHERE recoup_refresh_uuid > $1"
- " ORDER BY recoup_refresh_uuid ASC;",
- 1),
-
-
- GNUNET_PQ_make_prepare (
- "select_above_serial_by_table_purse_requests",
- "SELECT"
- " purse_requests_serial_id"
- ",purse_pub"
- ",merge_pub"
- ",purse_creation"
- ",purse_expiration"
- ",h_contract_terms"
- ",age_limit"
- ",flags"
- ",amount_with_fee_val"
- ",amount_with_fee_frac"
- ",purse_fee_val"
- ",purse_fee_frac"
- ",purse_sig"
- " FROM purse_requests"
- " WHERE purse_requests_serial_id > $1"
- " ORDER BY purse_requests_serial_id ASC;",
- 1),
- GNUNET_PQ_make_prepare (
- "select_above_serial_by_table_purse_refunds",
- "SELECT"
- " purse_refunds_serial_id"
- ",purse_pub"
- " FROM purse_refunds"
- " WHERE purse_refunds_serial_id > $1"
- " ORDER BY purse_refunds_serial_id ASC;",
- 1),
- GNUNET_PQ_make_prepare (
- "select_above_serial_by_table_purse_merges",
- "SELECT"
- " purse_merge_request_serial_id"
- ",partner_serial_id"
- ",reserve_pub"
- ",purse_pub"
- ",merge_sig"
- ",merge_timestamp"
- " FROM purse_merges"
- " WHERE purse_merge_request_serial_id > $1"
- " ORDER BY purse_merge_request_serial_id ASC;",
- 1),
- GNUNET_PQ_make_prepare (
- "select_above_serial_by_table_purse_deposits",
- "SELECT"
- " purse_deposit_serial_id"
- ",partner_serial_id"
- ",purse_pub"
- ",coin_pub"
- ",amount_with_fee_val"
- ",amount_with_fee_frac"
- ",coin_sig"
- " FROM purse_deposits"
- " WHERE purse_deposit_serial_id > $1"
- " ORDER BY purse_deposit_serial_id ASC;",
- 1),
- GNUNET_PQ_make_prepare (
- "select_above_serial_by_table_account_merges",
- "SELECT"
- " account_merge_request_serial_id"
- ",reserve_pub"
- ",reserve_sig"
- ",purse_pub"
- " FROM account_merges"
- " WHERE account_merge_request_serial_id > $1"
- " ORDER BY account_merge_request_serial_id ASC;",
- 1),
- GNUNET_PQ_make_prepare (
- "select_above_serial_by_table_history_requests",
- "SELECT"
- " history_request_serial_id"
- ",reserve_pub"
- ",request_timestamp"
- ",reserve_sig"
- ",history_fee_val"
- ",history_fee_frac"
- " FROM history_requests"
- " WHERE history_request_serial_id > $1"
- " ORDER BY history_request_serial_id ASC;",
- 1),
- GNUNET_PQ_make_prepare (
- "select_above_serial_by_table_close_requests",
- "SELECT"
- " close_request_serial_id"
- ",reserve_pub"
- ",close_timestamp"
- ",reserve_sig"
- ",close_val"
- ",close_frac"
- " FROM close_requests"
- " WHERE close_request_serial_id > $1"
- " ORDER BY close_request_serial_id ASC;",
- 1),
- GNUNET_PQ_make_prepare (
- "select_above_serial_by_table_wads_out",
- "SELECT"
- " wad_out_serial_id"
- ",wad_id"
- ",partner_serial_id"
- ",amount_val"
- ",amount_frac"
- ",execution_time"
- " FROM wads_out"
- " WHERE wad_out_serial_id > $1"
- " ORDER BY wad_out_serial_id ASC;",
- 1),
- GNUNET_PQ_make_prepare (
- "select_above_serial_by_table_wads_out_entries",
- "SELECT"
- " wad_out_entry_serial_id"
- ",reserve_pub"
- ",purse_pub"
- ",h_contract"
- ",purse_expiration"
- ",merge_timestamp"
- ",amount_with_fee_val"
- ",amount_with_fee_frac"
- ",wad_fee_val"
- ",wad_fee_frac"
- ",deposit_fees_val"
- ",deposit_fees_frac"
- ",reserve_sig"
- ",purse_sig"
- " FROM wad_out_entries"
- " WHERE wad_out_entry_serial_id > $1"
- " ORDER BY wad_out_entry_serial_id ASC;",
- 1),
- GNUNET_PQ_make_prepare (
- "select_above_serial_by_table_wads_in",
- "SELECT"
- " wad_in_serial_id"
- ",wad_id"
- ",origin_exchange_url"
- ",amount_val"
- ",amount_frac"
- ",arrival_time"
- " FROM wads_in"
- " WHERE wad_in_serial_id > $1"
- " ORDER BY wad_in_serial_id ASC;",
- 1),
- GNUNET_PQ_make_prepare (
- "select_above_serial_by_table_wads_in_entries",
- "SELECT"
- " wad_in_entry_serial_id"
- ",reserve_pub"
- ",purse_pub"
- ",h_contract"
- ",purse_expiration"
- ",merge_timestamp"
- ",amount_with_fee_val"
- ",amount_with_fee_frac"
- ",wad_fee_val"
- ",wad_fee_frac"
- ",deposit_fees_val"
- ",deposit_fees_frac"
- ",reserve_sig"
- ",purse_sig"
- " FROM wad_in_entries"
- " WHERE wad_in_entry_serial_id > $1"
- " ORDER BY wad_in_entry_serial_id ASC;",
- 1),
- /* For postgres_insert_records_by_table */
- GNUNET_PQ_make_prepare (
- "insert_into_table_denominations",
- "INSERT INTO denominations"
- "(denominations_serial"
- ",denom_pub_hash"
- ",denom_type"
- ",age_mask"
- ",denom_pub"
- ",master_sig"
- ",valid_from"
- ",expire_withdraw"
- ",expire_deposit"
- ",expire_legal"
- ",coin_val"
- ",coin_frac"
- ",fee_withdraw_val"
- ",fee_withdraw_frac"
- ",fee_deposit_val"
- ",fee_deposit_frac"
- ",fee_refresh_val"
- ",fee_refresh_frac"
- ",fee_refund_val"
- ",fee_refund_frac"
- ") VALUES "
- "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10,"
- " $11, $12, $13, $14, $15, $16, $17, $18, $19, $20);",
- 20),
- GNUNET_PQ_make_prepare (
- "insert_into_table_denomination_revocations",
- "INSERT INTO denomination_revocations"
- "(denom_revocations_serial_id"
- ",master_sig"
- ",denominations_serial"
- ") VALUES "
- "($1, $2, $3);",
- 3),
- GNUNET_PQ_make_prepare (
- "insert_into_table_wire_targets",
- "INSERT INTO wire_targets"
- "(wire_target_serial_id"
- ",wire_target_h_payto"
- ",payto_uri"
- ",kyc_ok"
- ",external_id"
- ") VALUES "
- "($1, $2, $3, $4, $5);",
- 5),
- GNUNET_PQ_make_prepare (
- "insert_into_table_reserves",
- "INSERT INTO reserves"
- "(reserve_uuid"
- ",reserve_pub"
- ",expiration_date"
- ",gc_date"
- ") VALUES "
- "($1, $2, $3, $4);",
- 4),
- GNUNET_PQ_make_prepare (
- "insert_into_table_reserves_in",
- "INSERT INTO reserves_in"
- "(reserve_in_serial_id"
- ",wire_reference"
- ",credit_val"
- ",credit_frac"
- ",wire_source_h_payto"
- ",exchange_account_section"
- ",execution_date"
- ",reserve_pub"
- ") VALUES "
- "($1, $2, $3, $4, $5, $6, $7, $8);",
- 8),
- GNUNET_PQ_make_prepare (
- "insert_into_table_reserves_close",
- "INSERT INTO reserves_close"
- "(close_uuid"
- ",execution_date"
- ",wtid"
- ",wire_target_h_payto"
- ",amount_val"
- ",amount_frac"
- ",closing_fee_val"
- ",closing_fee_frac"
- ",reserve_pub"
- ") VALUES "
- "($1, $2, $3, $4, $5, $6, $7, $8, $9);",
- 9),
- GNUNET_PQ_make_prepare (
- "insert_into_table_reserves_out",
- "INSERT INTO reserves_out"
- "(reserve_out_serial_id"
- ",h_blind_ev"
- ",denominations_serial"
- ",denom_sig"
- ",reserve_uuid"
- ",reserve_sig"
- ",execution_date"
- ",amount_with_fee_val"
- ",amount_with_fee_frac"
- ") VALUES "
- "($1, $2, $3, $4, $5, $6, $7, $8, $9);",
- 9),
- GNUNET_PQ_make_prepare (
- "insert_into_table_auditors",
- "INSERT INTO auditors"
- "(auditor_uuid"
- ",auditor_pub"
- ",auditor_name"
- ",auditor_url"
- ",is_active"
- ",last_change"
- ") VALUES "
- "($1, $2, $3, $4, $5, $6);",
- 6),
- GNUNET_PQ_make_prepare (
- "insert_into_table_auditor_denom_sigs",
- "INSERT INTO auditor_denom_sigs"
- "(auditor_denom_serial"
- ",auditor_uuid"
- ",denominations_serial"
- ",auditor_sig"
- ") VALUES "
- "($1, $2, $3, $4);",
- 4),
- GNUNET_PQ_make_prepare (
- "insert_into_table_exchange_sign_keys",
- "INSERT INTO exchange_sign_keys"
- "(esk_serial"
- ",exchange_pub"
- ",master_sig"
- ",valid_from"
- ",expire_sign"
- ",expire_legal"
- ") VALUES "
- "($1, $2, $3, $4, $5, $6);",
- 6),
- GNUNET_PQ_make_prepare (
- "insert_into_table_signkey_revocations",
- "INSERT INTO signkey_revocations"
- "(signkey_revocations_serial_id"
- ",esk_serial"
- ",master_sig"
- ") VALUES "
- "($1, $2, $3);",
- 3),
- GNUNET_PQ_make_prepare (
- "insert_into_table_known_coins",
- "INSERT INTO known_coins"
- "(known_coin_id"
- ",coin_pub"
- ",denom_sig"
- ",denominations_serial"
- ") VALUES "
- "($1, $2, $3, $4);",
- 4),
- GNUNET_PQ_make_prepare (
- "insert_into_table_refresh_commitments",
- "INSERT INTO refresh_commitments"
- "(melt_serial_id"
- ",rc"
- ",old_coin_sig"
- ",amount_with_fee_val"
- ",amount_with_fee_frac"
- ",noreveal_index"
- ",old_coin_pub"
- ") VALUES "
- "($1, $2, $3, $4, $5, $6, $7);",
- 7),
- GNUNET_PQ_make_prepare (
- "insert_into_table_refresh_revealed_coins",
- "INSERT INTO refresh_revealed_coins"
- "(rrc_serial"
- ",freshcoin_index"
- ",link_sig"
- ",coin_ev"
- ",h_coin_ev"
- ",ev_sig"
- ",ewv"
- ",denominations_serial"
- ",melt_serial_id"
- ") VALUES "
- "($1, $2, $3, $4, $5, $6, $7, $8, $9);",
- 9),
- GNUNET_PQ_make_prepare (
- "insert_into_table_refresh_transfer_keys",
- "INSERT INTO refresh_transfer_keys"
- "(rtc_serial"
- ",transfer_pub"
- ",transfer_privs"
- ",melt_serial_id"
- ") VALUES "
- "($1, $2, $3, $4);",
- 4),
- GNUNET_PQ_make_prepare (
- "insert_into_table_deposits",
- "INSERT INTO deposits"
- "(deposit_serial_id"
- ",shard"
- ",known_coin_id"
- ",coin_pub"
- ",amount_with_fee_val"
- ",amount_with_fee_frac"
- ",wallet_timestamp"
- ",exchange_timestamp"
- ",refund_deadline"
- ",wire_deadline"
- ",merchant_pub"
- ",h_contract_terms"
- ",coin_sig"
- ",wire_salt"
- ",wire_target_h_payto"
- ",extension_blocked"
- ",extension_details_serial_id"
- ") VALUES "
- "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10,"
- " $11, $12, $13, $14, $15, $16, $17);",
- 17),
- GNUNET_PQ_make_prepare (
- "insert_into_table_refunds",
- "INSERT INTO refunds"
- "(refund_serial_id"
- ",coin_pub"
- ",merchant_sig"
- ",rtransaction_id"
- ",amount_with_fee_val"
- ",amount_with_fee_frac"
- ",deposit_serial_id"
- ") VALUES "
- "($1, $2, $3, $4, $5, $6, $7);",
- 7),
- GNUNET_PQ_make_prepare (
- "insert_into_table_aggregation_tracking",
- "INSERT INTO aggregation_tracking"
- "(aggregation_serial_id"
- ",deposit_serial_id"
- ",wtid_raw"
- ") VALUES "
- "($1, $2, $3);",
- 3),
- GNUNET_PQ_make_prepare (
- "insert_into_table_wire_fee",
- "INSERT INTO wire_fee"
- "(wire_fee_serial"
- ",wire_method"
- ",start_date"
- ",end_date"
- ",wire_fee_val"
- ",wire_fee_frac"
- ",closing_fee_val"
- ",closing_fee_frac"
- ",wad_fee_val"
- ",wad_fee_frac"
- ",master_sig"
- ") VALUES "
- "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11);",
- 11),
- GNUNET_PQ_make_prepare (
- "insert_into_table_global_fee",
- "INSERT INTO global_fee"
- "(global_fee_serial"
- ",start_date"
- ",end_date"
- ",history_fee_val"
- ",history_fee_frac"
- ",kyc_fee_val"
- ",kyc_fee_frac"
- ",account_fee_val"
- ",account_fee_frac"
- ",purse_fee_val"
- ",purse_fee_frac"
- ",purse_timeout"
- ",kyc_timeout"
- ",history_expiration"
- ",purse_account_limit"
- ",master_sig"
- ") VALUES "
- "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16);",
- 16),
- GNUNET_PQ_make_prepare (
- "insert_into_table_recoup",
- "INSERT INTO recoup"
- "(recoup_uuid"
- ",coin_sig"
- ",coin_blind"
- ",amount_val"
- ",amount_frac"
- ",recoup_timestamp"
- ",coin_pub"
- ",reserve_out_serial_id"
- ") VALUES "
- "($1, $2, $3, $4, $5, $6, $7, $8);",
- 8),
- GNUNET_PQ_make_prepare (
- "insert_into_table_recoup_refresh",
- "INSERT INTO recoup_refresh"
- "(recoup_refresh_uuid"
- ",coin_sig"
- ",coin_blind"
- ",amount_val"
- ",amount_frac"
- ",recoup_timestamp"
- ",known_coin_id"
- ",coin_pub"
- ",rrc_serial"
- ") VALUES "
- "($1, $2, $3, $4, $5, $6, $7, $8, $9);",
- 9),
- GNUNET_PQ_make_prepare (
- "insert_into_table_extensions",
- "INSERT INTO extensions"
- "(extension_id"
- ",name"
- ",config"
- ") VALUES "
- "($1, $2, $3);",
- 3),
- GNUNET_PQ_make_prepare (
- "insert_into_table_extension_details",
- "INSERT INTO extension_details"
- "(extension_details_serial_id"
- ",extension_options"
- ") VALUES "
- "($1, $2);",
- 2),
-
- GNUNET_PQ_make_prepare (
- "insert_into_table_purse_requests",
- "INSERT INTO purse_requests"
- "(purse_requests_serial_id"
- ",purse_pub"
- ",merge_pub"
- ",purse_creation"
- ",purse_expiration"
- ",h_contract_terms"
- ",age_limit"
- ",flags"
- ",amount_with_fee_val"
- ",amount_with_fee_frac"
- ",purse_fee_val"
- ",purse_fee_frac"
- ",purse_sig"
- ") VALUES "
- "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13);",
- 13),
- GNUNET_PQ_make_prepare (
- "insert_into_table_purse_refunds",
- "INSERT INTO purse_refunds"
- "(purse_refunds_serial_id"
- ",purse_pub"
- ") VALUES "
- "($1, $2);",
- 2),
- GNUNET_PQ_make_prepare (
- "insert_into_table_purse_merges",
- "INSERT INTO purse_merges"
- "(purse_merge_request_serial_id"
- ",partner_serial_id"
- ",reserve_pub"
- ",purse_pub"
- ",merge_sig"
- ",merge_timestamp"
- ") VALUES "
- "($1, $2, $3, $4, $5, $6);",
- 6),
- GNUNET_PQ_make_prepare (
- "insert_into_table_purse_deposits",
- "INSERT INTO purse_deposits"
- "(purse_deposit_serial_id"
- ",partner_serial_id"
- ",purse_pub"
- ",coin_pub"
- ",amount_with_fee_val"
- ",amount_with_fee_frac"
- ",coin_sig"
- ") VALUES "
- "($1, $2, $3, $4, $5, $6, $7);",
- 7),
- GNUNET_PQ_make_prepare (
- "insert_into_table_account_merges",
- "INSERT INTO account_merges"
- "(account_merge_request_serial_id"
- ",reserve_pub"
- ",reserve_sig"
- ",purse_pub"
- ") VALUES "
- "($1, $2, $3, $4);",
- 4),
- GNUNET_PQ_make_prepare (
- "insert_into_table_history_requests",
- "INSERT INTO history_requests"
- "(history_request_serial_id"
- ",reserve_pub"
- ",request_timestamp"
- ",reserve_sig"
- ",history_fee_val"
- ",history_fee_frac"
- ") VALUES "
- "($1, $2, $3, $4, $5, $6);",
- 6),
- GNUNET_PQ_make_prepare (
- "insert_into_table_close_requests",
- "INSERT INTO close_requests"
- "(close_request_serial_id"
- ",reserve_pub"
- ",close_timestamp"
- ",reserve_sig"
- ",close_val"
- ",close_frac"
- ") VALUES "
- "($1, $2, $3, $4, $5, $6);",
- 6),
- GNUNET_PQ_make_prepare (
- "insert_into_table_wads_out",
- "INSERT INTO wads_out"
- "(wad_out_serial_id"
- ",wad_id"
- ",partner_serial_id"
- ",amount_val"
- ",amount_frac"
- ",execution_time"
- ") VALUES "
- "($1, $2, $3, $4, $5, $6);",
- 6),
- GNUNET_PQ_make_prepare (
- "insert_into_table_wad_out_entries",
- "INSERT INTO wad_out_entries"
- "(wad_out_entry_serial_id"
- ",wad_out_serial_id"
- ",reserve_pub"
- ",purse_pub"
- ",h_contract"
- ",purse_expiration"
- ",merge_timestamp"
- ",amount_with_fee_val"
- ",amount_with_fee_frac"
- ",wad_fee_val"
- ",wad_fee_frac"
- ",deposit_fees_val"
- ",deposit_fees_frac"
- ",reserve_sig"
- ",purse_sig"
- ") VALUES "
- "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15);",
- 15),
- GNUNET_PQ_make_prepare (
- "insert_into_table_wads_in",
- "INSERT INTO wads_in"
- "(wad_in_serial_id"
- ",wad_id"
- ",origin_exchange_url"
- ",amount_val"
- ",amount_frac"
- ",arrival_time"
- ") VALUES "
- "($1, $2, $3, $4, $5, $6);",
- 6),
- GNUNET_PQ_make_prepare (
- "insert_into_table_wad_in_entries",
- "INSERT INTO wad_in_entries"
- "(wad_in_entry_serial_id"
- ",wad_in_serial_id"
- ",reserve_pub"
- ",purse_pub"
- ",h_contract"
- ",purse_expiration"
- ",merge_timestamp"
- ",amount_with_fee_val"
- ",amount_with_fee_frac"
- ",wad_fee_val"
- ",wad_fee_frac"
- ",deposit_fees_val"
- ",deposit_fees_frac"
- ",reserve_sig"
- ",purse_sig"
- ") VALUES "
- "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15);",
- 3),
-
- /* Used in #postgres_begin_shard() */
- GNUNET_PQ_make_prepare (
- "get_open_shard",
- "SELECT"
- " start_row"
- ",end_row"
- " FROM work_shards"
- " WHERE job_name=$1"
- " AND completed=FALSE"
- " AND last_attempt<$2"
- " ORDER BY last_attempt ASC"
- " LIMIT 1;",
- 2),
- /* Used in #postgres_begin_revolving_shard() */
- GNUNET_PQ_make_prepare (
- "get_open_revolving_shard",
- "SELECT"
- " start_row"
- ",end_row"
- " FROM revolving_work_shards"
- " WHERE job_name=$1"
- " AND active=FALSE"
- " ORDER BY last_attempt ASC"
- " LIMIT 1;",
- 2),
- /* Used in #postgres_begin_shard() */
- GNUNET_PQ_make_prepare (
- "reclaim_shard",
- "UPDATE work_shards"
- " SET last_attempt=$2"
- " WHERE job_name=$1"
- " AND start_row=$3"
- " AND end_row=$4",
- 4),
- /* Used in #postgres_begin_revolving_shard() */
- GNUNET_PQ_make_prepare (
- "reclaim_revolving_shard",
- "UPDATE revolving_work_shards"
- " SET last_attempt=$2"
- " ,active=TRUE"
- " WHERE job_name=$1"
- " AND start_row=$3"
- " AND end_row=$4",
- 4),
- /* Used in #postgres_begin_shard() */
- GNUNET_PQ_make_prepare (
- "get_last_shard",
- "SELECT"
- " end_row"
- " FROM work_shards"
- " WHERE job_name=$1"
- " ORDER BY end_row DESC"
- " LIMIT 1;",
- 1),
- /* Used in #postgres_begin_revolving_shard() */
- GNUNET_PQ_make_prepare (
- "get_last_revolving_shard",
- "SELECT"
- " end_row"
- " FROM revolving_work_shards"
- " WHERE job_name=$1"
- " ORDER BY end_row DESC"
- " LIMIT 1;",
- 1),
- /* Used in #postgres_abort_shard() */
- GNUNET_PQ_make_prepare (
- "abort_shard",
- "UPDATE work_shards"
- " SET last_attempt=0"
- " WHERE job_name = $1 "
- " AND start_row = $2 "
- " AND end_row = $3;",
- 3),
- /* Used in #postgres_begin_shard() */
- GNUNET_PQ_make_prepare (
- "claim_next_shard",
- "INSERT INTO work_shards"
- "(job_name"
- ",last_attempt"
- ",start_row"
- ",end_row"
- ") VALUES "
- "($1, $2, $3, $4);",
- 4),
- /* Used in #postgres_claim_revolving_shard() */
- GNUNET_PQ_make_prepare (
- "create_revolving_shard",
- "INSERT INTO revolving_work_shards"
- "(job_name"
- ",last_attempt"
- ",start_row"
- ",end_row"
- ",active"
- ") VALUES "
- "($1, $2, $3, $4, TRUE);",
- 4),
- /* Used in #postgres_complete_shard() */
- GNUNET_PQ_make_prepare (
- "complete_shard",
- "UPDATE work_shards"
- " SET completed=TRUE"
- " WHERE job_name=$1"
- " AND start_row=$2"
- " AND end_row=$3",
- 3),
- /* Used in #postgres_complete_shard() */
- GNUNET_PQ_make_prepare (
- "release_revolving_shard",
- "UPDATE revolving_work_shards"
- " SET active=FALSE"
- " WHERE job_name=$1"
- " AND start_row=$2"
- " AND end_row=$3",
- 3),
- /* Used in #postgres_set_extension_config */
- GNUNET_PQ_make_prepare (
- "set_extension_config",
- "INSERT INTO extensions (name, config) VALUES ($1, $2) "
- "ON CONFLICT (name) "
- "DO UPDATE SET config=$2",
- 2),
- /* Used in #postgres_get_extension_config */
- GNUNET_PQ_make_prepare (
- "get_extension_config",
- "SELECT "
- " config "
- "FROM extensions"
- " WHERE name=$1;",
- 1),
- /* Used in #postgres_insert_contract() */
- GNUNET_PQ_make_prepare (
- "insert_contract",
- "INSERT INTO contracts"
- " (purse_pub"
- " ,pub_ckey"
- " ,e_contract"
- " ,contract_sig"
- " ,purse_expiration"
- " ) SELECT "
- " $1, $2, $3, $4, purse_expiration"
- " FROM purse_requests"
- " WHERE purse_pub=$1"
- " ON CONFLICT DO NOTHING;",
- 4),
- /* Used in #postgres_select_contract */
- GNUNET_PQ_make_prepare (
- "select_contract",
- "SELECT "
- " purse_pub"
- ",e_contract"
- ",contract_sig"
- " FROM contracts"
- " WHERE pub_ckey=$1;",
- 1),
- /* Used in #postgres_select_contract_by_purse */
- GNUNET_PQ_make_prepare (
- "select_contract_by_purse",
- "SELECT "
- " pub_ckey"
- ",e_contract"
- ",contract_sig"
- " FROM contracts"
- " WHERE purse_pub=$1;",
- 1),
- /* Used in #postgres_insert_purse_request() */
- GNUNET_PQ_make_prepare (
- "insert_purse_request",
- "INSERT INTO purse_requests"
- " (purse_pub"
- " ,merge_pub"
- " ,purse_creation"
- " ,purse_expiration"
- " ,h_contract_terms"
- " ,age_limit"
- " ,flags"
- " ,in_reserve_quota"
- " ,amount_with_fee_val"
- " ,amount_with_fee_frac"
- " ,purse_fee_val"
- " ,purse_fee_frac"
- " ,purse_sig"
- " ) VALUES "
- " ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)"
- " ON CONFLICT DO NOTHING;",
- 13),
- /* Used in #postgres_select_purse */
- GNUNET_PQ_make_prepare (
- "select_purse",
- "SELECT "
- " merge_pub"
- ",purse_expiration"
- ",h_contract_terms"
- ",amount_with_fee_val"
- ",amount_with_fee_frac"
- ",balance_val"
- ",balance_frac"
- ",merge_timestamp"
- " FROM purse_requests"
- " LEFT JOIN purse_merges USING (purse_pub)"
- " WHERE purse_pub=$1;",
- 1),
- /* Used in #postgres_select_purse_request */
- GNUNET_PQ_make_prepare (
- "select_purse_request",
- "SELECT "
- " merge_pub"
- ",purse_expiration"
- ",h_contract_terms"
- ",age_limit"
- ",amount_with_fee_val"
- ",amount_with_fee_frac"
- ",balance_val"
- ",balance_frac"
- ",purse_sig"
- " FROM purse_requests"
- " WHERE purse_pub=$1;",
- 1),
- /* Used in #postgres_select_purse_by_merge_pub */
- GNUNET_PQ_make_prepare (
- "select_purse_by_merge_pub",
- "SELECT "
- " purse_pub"
- ",purse_expiration"
- ",h_contract_terms"
- ",age_limit"
- ",amount_with_fee_val"
- ",amount_with_fee_frac"
- ",balance_val"
- ",balance_frac"
- ",purse_sig"
- " FROM purse_requests"
- " WHERE merge_pub=$1;",
- 1),
- /* Used in #postgres_get_purse_deposit */
- GNUNET_PQ_make_prepare (
- "select_purse_deposit_by_coin_pub",
- "SELECT "
- " coin_sig"
- ",amount_with_fee_val"
- ",amount_with_fee_frac"
- ",denom_pub_hash"
- ",age_commitment_hash"
- ",partner_base_url"
- " FROM purse_deposits"
- " LEFT JOIN partners USING (partner_serial_id)"
- " JOIN known_coins kc USING (coin_pub)"
- " JOIN denominations USING (denominations_serial)"
- " WHERE coin_pub=$2"
- " AND purse_pub=$1;",
- 2),
- /* Used in #postgres_do_purse_merge() */
- GNUNET_PQ_make_prepare (
- "call_purse_merge",
- "SELECT"
- " out_no_partner AS no_partner"
- ",out_no_balance AS no_balance"
- ",out_no_kyc AS no_kyc"
- ",out_no_reserve AS no_reserve"
- ",out_conflict AS conflict"
- " FROM exchange_do_purse_merge"
- " ($1, $2, $3, $4, $5, $6, $7);",
- 7),
- /* Used in #postgres_do_reserve_purse() */
- GNUNET_PQ_make_prepare (
- "call_reserve_purse",
- "SELECT"
- " out_no_funds AS insufficient_funds"
- ",out_no_reserve AS no_reserve"
- ",out_no_kyc AS no_kyc"
- ",out_conflict AS conflict"
- " FROM exchange_do_reserve_purse"
- " ($1, $2, $3, $4, $5, $6, $7, $8, $9);",
- 9),
- /* Used in #postgres_select_purse_merge */
- GNUNET_PQ_make_prepare (
- "select_purse_merge",
- "SELECT "
- " reserve_pub"
- ",merge_sig"
- ",merge_timestamp"
- ",partner_base_url"
- " FROM purse_merges"
- " LEFT JOIN partners USING (partner_serial_id)"
- " WHERE purse_pub=$1;",
- 1),
- /* Used in #postgres_do_account_merge() */
- GNUNET_PQ_make_prepare (
- "call_account_merge",
- "SELECT 1"
- " FROM exchange_do_account_merge"
- " ($1, $2, $3);",
- 3),
- /* Used in #postgres_insert_history_request() */
- GNUNET_PQ_make_prepare (
- "call_history_request",
- "SELECT"
- " out_balance_ok AS balance_ok"
- " ,out_idempotent AS idempotent"
- " FROM exchange_do_history_request"
- " ($1, $2, $3, $4, $5)",
- 5),
- /* Used in #postgres_insert_close_request() */
- GNUNET_PQ_make_prepare (
- "call_account_close",
- "SELECT "
- " out_final_balance_val"
- ",out_final_balance_frac"
- " FROM exchange_do_close_request"
- " ($1, $2, $3)",
- 3),
-
- GNUNET_PQ_PREPARED_STATEMENT_END
- };
-
- ret = GNUNET_PQ_prepare_statements (pg->conn,
- ps);
- if (GNUNET_OK != ret)
- return ret;
- pg->init = true;
- return GNUNET_OK;
-}
-
-
-/**
* Connect to the database if the connection does not exist yet.
*
* @param pg the plugin-specific state
- * @param skip_prepare true if we should skip prepared statement setup
* @return #GNUNET_OK on success
*/
-static enum GNUNET_GenericReturnValue
-internal_setup (struct PostgresClosure *pg,
- bool skip_prepare)
+enum GNUNET_GenericReturnValue
+TEH_PG_internal_setup (struct PostgresClosure *pg)
{
if (NULL == pg->conn)
{
@@ -4294,6 +272,9 @@ internal_setup (struct PostgresClosure *pg,
"SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL SERIALIZABLE;"),
GNUNET_PQ_make_try_execute ("SET enable_sort=OFF;"),
GNUNET_PQ_make_try_execute ("SET enable_seqscan=OFF;"),
+ GNUNET_PQ_make_try_execute ("SET search_path TO exchange;"),
+ /* Mergejoin causes issues, see Postgres #18380 */
+ GNUNET_PQ_make_try_execute ("SET enable_mergejoin=OFF;"),
GNUNET_PQ_EXECUTE_STATEMENT_END
};
#else
@@ -4302,7 +283,9 @@ internal_setup (struct PostgresClosure *pg,
"SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL SERIALIZABLE;"),
GNUNET_PQ_make_try_execute ("SET enable_sort=OFF;"),
GNUNET_PQ_make_try_execute ("SET enable_seqscan=OFF;"),
- GNUNET_PQ_make_try_execute ("SET autocommit=OFF;"),
+ /* Mergejoin causes issues, see Postgres #18380 */
+ GNUNET_PQ_make_try_execute ("SET enable_mergejoin=OFF;"),
+ GNUNET_PQ_make_try_execute ("SET search_path TO exchange;"),
GNUNET_PQ_EXECUTE_STATEMENT_END
};
#endif
@@ -4315,11630 +298,17 @@ internal_setup (struct PostgresClosure *pg,
NULL);
if (NULL == db_conn)
return GNUNET_SYSERR;
+
+ pg->prep_gen++;
pg->conn = db_conn;
}
if (NULL == pg->transaction_name)
GNUNET_PQ_reconnect_if_down (pg->conn);
- if (pg->init)
- return GNUNET_OK;
- if (skip_prepare)
- return GNUNET_OK;
- return prepare_statements (pg);
-}
-
-
-/**
- * Do a pre-flight check that we are not in an uncommitted transaction.
- * If we are, try to commit the previous transaction and output a warning.
- * Does not return anything, as we will continue regardless of the outcome.
- *
- * @param cls the `struct PostgresClosure` with the plugin-specific state
- * @return #GNUNET_OK if everything is fine
- * #GNUNET_NO if a transaction was rolled back
- * #GNUNET_SYSERR on hard errors
- */
-static enum GNUNET_GenericReturnValue
-postgres_preflight (void *cls)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_ExecuteStatement es[] = {
- GNUNET_PQ_make_execute ("ROLLBACK"),
- GNUNET_PQ_EXECUTE_STATEMENT_END
- };
-
- if (! pg->init)
- {
- if (GNUNET_OK !=
- internal_setup (pg,
- false))
- return GNUNET_SYSERR;
- }
- if (NULL == pg->transaction_name)
- return GNUNET_OK; /* all good */
- if (GNUNET_OK ==
- GNUNET_PQ_exec_statements (pg->conn,
- es))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "BUG: Preflight check rolled back transaction `%s'!\n",
- pg->transaction_name);
- }
- else
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "BUG: Preflight check failed to rollback transaction `%s'!\n",
- pg->transaction_name);
- }
- pg->transaction_name = NULL;
- return GNUNET_NO;
-}
-
-
-/**
- * Start a transaction.
- *
- * @param cls the `struct PostgresClosure` with the plugin-specific state
- * @param name unique name identifying the transaction (for debugging)
- * must point to a constant
- * @return #GNUNET_OK on success
- */
-static enum GNUNET_GenericReturnValue
-postgres_start (void *cls,
- const char *name)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_ExecuteStatement es[] = {
- GNUNET_PQ_make_execute ("START TRANSACTION ISOLATION LEVEL SERIALIZABLE"),
- GNUNET_PQ_EXECUTE_STATEMENT_END
- };
-
- GNUNET_assert (NULL != name);
- if (GNUNET_SYSERR ==
- postgres_preflight (pg))
- return GNUNET_SYSERR;
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Starting transaction `%s'\n",
- name);
- if (GNUNET_OK !=
- GNUNET_PQ_exec_statements (pg->conn,
- es))
- {
- TALER_LOG_ERROR ("Failed to start transaction\n");
- GNUNET_break (0);
- return GNUNET_SYSERR;
- }
- pg->transaction_name = name;
- return GNUNET_OK;
-}
-
-
-/**
- * Start a READ COMMITTED transaction.
- *
- * @param cls the `struct PostgresClosure` with the plugin-specific state
- * @param name unique name identifying the transaction (for debugging)
- * must point to a constant
- * @return #GNUNET_OK on success
- */
-static enum GNUNET_GenericReturnValue
-postgres_start_read_committed (void *cls,
- const char *name)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_ExecuteStatement es[] = {
- GNUNET_PQ_make_execute ("START TRANSACTION ISOLATION LEVEL READ COMMITTED"),
- GNUNET_PQ_EXECUTE_STATEMENT_END
- };
-
- GNUNET_assert (NULL != name);
- if (GNUNET_SYSERR ==
- postgres_preflight (pg))
- return GNUNET_SYSERR;
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Starting READ COMMITTED transaction `%s`\n",
- name);
- if (GNUNET_OK !=
- GNUNET_PQ_exec_statements (pg->conn,
- es))
- {
- TALER_LOG_ERROR ("Failed to start transaction\n");
- GNUNET_break (0);
- return GNUNET_SYSERR;
- }
- pg->transaction_name = name;
- return GNUNET_OK;
-}
-
-
-/**
- * Roll back the current transaction of a database connection.
- *
- * @param cls the `struct PostgresClosure` with the plugin-specific state
- */
-static void
-postgres_rollback (void *cls)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_ExecuteStatement es[] = {
- GNUNET_PQ_make_execute ("ROLLBACK"),
- GNUNET_PQ_EXECUTE_STATEMENT_END
- };
-
- if (NULL == pg->transaction_name)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Skipping rollback, no transaction active\n");
- return;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Rolling back transaction\n");
- GNUNET_break (GNUNET_OK ==
- GNUNET_PQ_exec_statements (pg->conn,
- es));
- pg->transaction_name = NULL;
-}
-
-
-/**
- * Commit the current transaction of a database connection.
- *
- * @param cls the `struct PostgresClosure` with the plugin-specific state
- * @return final transaction status
- */
-static enum GNUNET_DB_QueryStatus
-postgres_commit (void *cls)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_end
- };
- enum GNUNET_DB_QueryStatus qs;
-
- GNUNET_break (NULL != pg->transaction_name);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Committing transaction `%s'\n",
- pg->transaction_name);
- qs = GNUNET_PQ_eval_prepared_non_select (pg->conn,
- "do_commit",
- params);
- pg->transaction_name = NULL;
- return qs;
-}
-
-
-/**
- * Register callback to be invoked on events of type @a es.
- *
- * @param cls database context to use
- * @param timeout how long until to generate a timeout event
- * @param es specification of the event to listen for
- * @param cb function to call when the event happens, possibly
- * multiple times (until cancel is invoked)
- * @param cb_cls closure for @a cb
- * @return handle useful to cancel the listener
- */
-static struct GNUNET_DB_EventHandler *
-postgres_event_listen (void *cls,
- struct GNUNET_TIME_Relative timeout,
- const struct GNUNET_DB_EventHeaderP *es,
- GNUNET_DB_EventCallback cb,
- void *cb_cls)
-{
- struct PostgresClosure *pg = cls;
-
- return GNUNET_PQ_event_listen (pg->conn,
- es,
- timeout,
- cb,
- cb_cls);
-}
-
-
-/**
- * Stop notifications.
- *
- * @param cls the plugin's `struct PostgresClosure`
- * @param eh handle to unregister.
- */
-static void
-postgres_event_listen_cancel (void *cls,
- struct GNUNET_DB_EventHandler *eh)
-{
- (void) cls;
- GNUNET_PQ_event_listen_cancel (eh);
-}
-
-
-/**
- * Notify all that listen on @a es of an event.
- *
- * @param cls database context to use
- * @param es specification of the event to generate
- * @param extra additional event data provided
- * @param extra_size number of bytes in @a extra
- */
-static void
-postgres_event_notify (void *cls,
- const struct GNUNET_DB_EventHeaderP *es,
- const void *extra,
- size_t extra_size)
-{
- struct PostgresClosure *pg = cls;
-
- GNUNET_PQ_event_notify (pg->conn,
- es,
- extra,
- extra_size);
-}
-
-
-/**
- * Insert a denomination key's public information into the database for
- * reference by auditors and other consistency checks.
- *
- * @param cls the @e cls of this struct with the plugin-specific state
- * @param denom_pub the public key used for signing coins of this denomination
- * @param issue issuing information with value, fees and other info about the coin
- * @return status of the query
- */
-static enum GNUNET_DB_QueryStatus
-postgres_insert_denomination_info (
- void *cls,
- const struct TALER_DenominationPublicKey *denom_pub,
- const struct TALER_EXCHANGEDB_DenominationKeyInformation *issue)
-{
- struct PostgresClosure *pg = cls;
- struct TALER_DenominationHashP denom_hash;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (&issue->denom_hash),
- TALER_PQ_query_param_denom_pub (denom_pub),
- GNUNET_PQ_query_param_auto_from_type (&issue->signature),
- GNUNET_PQ_query_param_timestamp (&issue->start),
- GNUNET_PQ_query_param_timestamp (&issue->expire_withdraw),
- GNUNET_PQ_query_param_timestamp (&issue->expire_deposit),
- GNUNET_PQ_query_param_timestamp (&issue->expire_legal),
- TALER_PQ_query_param_amount (&issue->value),
- TALER_PQ_query_param_amount (&issue->fees.withdraw),
- TALER_PQ_query_param_amount (&issue->fees.deposit),
- TALER_PQ_query_param_amount (&issue->fees.refresh),
- TALER_PQ_query_param_amount (&issue->fees.refund),
- GNUNET_PQ_query_param_uint32 (&denom_pub->age_mask.bits),
- GNUNET_PQ_query_param_end
- };
-
- GNUNET_assert (denom_pub->age_mask.bits ==
- issue->age_mask.bits);
- TALER_denom_pub_hash (denom_pub,
- &denom_hash);
- GNUNET_assert (0 ==
- GNUNET_memcmp (&denom_hash,
- &issue->denom_hash));
- GNUNET_assert (! GNUNET_TIME_absolute_is_zero (
- issue->start.abs_time));
- GNUNET_assert (! GNUNET_TIME_absolute_is_zero (
- issue->expire_withdraw.abs_time));
- GNUNET_assert (! GNUNET_TIME_absolute_is_zero (
- issue->expire_deposit.abs_time));
- GNUNET_assert (! GNUNET_TIME_absolute_is_zero (
- issue->expire_legal.abs_time));
- /* check fees match denomination currency */
- GNUNET_assert (GNUNET_YES ==
- TALER_denom_fee_check_currency (
- issue->value.currency,
- &issue->fees));
- return GNUNET_PQ_eval_prepared_non_select (pg->conn,
- "denomination_insert",
- params);
-}
-
-
-/**
- * Fetch information about a denomination key.
- *
- * @param cls the @e cls of this struct with the plugin-specific state
- * @param denom_pub_hash hash of the public key used for signing coins of this denomination
- * @param[out] issue set to issue information with value, fees and other info about the coin
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_get_denomination_info (
- void *cls,
- const struct TALER_DenominationHashP *denom_pub_hash,
- struct TALER_EXCHANGEDB_DenominationKeyInformation *issue)
-{
- struct PostgresClosure *pg = cls;
- enum GNUNET_DB_QueryStatus qs;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (denom_pub_hash),
- GNUNET_PQ_query_param_end
- };
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_auto_from_type ("master_sig",
- &issue->signature),
- GNUNET_PQ_result_spec_timestamp ("valid_from",
- &issue->start),
- GNUNET_PQ_result_spec_timestamp ("expire_withdraw",
- &issue->expire_withdraw),
- GNUNET_PQ_result_spec_timestamp ("expire_deposit",
- &issue->expire_deposit),
- GNUNET_PQ_result_spec_timestamp ("expire_legal",
- &issue->expire_legal),
- TALER_PQ_RESULT_SPEC_AMOUNT ("coin",
- &issue->value),
- TALER_PQ_RESULT_SPEC_AMOUNT ("fee_withdraw",
- &issue->fees.withdraw),
- TALER_PQ_RESULT_SPEC_AMOUNT ("fee_deposit",
- &issue->fees.deposit),
- TALER_PQ_RESULT_SPEC_AMOUNT ("fee_refresh",
- &issue->fees.refresh),
- TALER_PQ_RESULT_SPEC_AMOUNT ("fee_refund",
- &issue->fees.refund),
- GNUNET_PQ_result_spec_uint32 ("age_mask",
- &issue->age_mask.bits),
- GNUNET_PQ_result_spec_end
- };
-
- qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "denomination_get",
- params,
- rs);
- if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs)
- return qs;
- issue->denom_hash = *denom_pub_hash;
- return qs;
-}
-
-
-/**
- * Closure for #domination_cb_helper()
- */
-struct DenomIteratorContext
-{
- /**
- * Function to call with the results.
- */
- TALER_EXCHANGEDB_DenominationCallback cb;
-
- /**
- * Closure to pass to @e cb
- */
- void *cb_cls;
-
- /**
- * Plugin context.
- */
- struct PostgresClosure *pg;
-};
-
-
-/**
- * Helper function for #postgres_iterate_denomination_info().
- * Calls the callback with each denomination key.
- *
- * @param cls a `struct DenomIteratorContext`
- * @param result db results
- * @param num_results number of results in @a result
- */
-static void
-domination_cb_helper (void *cls,
- PGresult *result,
- unsigned int num_results)
-{
- struct DenomIteratorContext *dic = cls;
- struct PostgresClosure *pg = dic->pg;
-
- for (unsigned int i = 0; i<num_results; i++)
- {
- struct TALER_EXCHANGEDB_DenominationKeyInformation issue;
- struct TALER_DenominationPublicKey denom_pub;
- struct TALER_DenominationHashP denom_hash;
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_auto_from_type ("master_sig",
- &issue.signature),
- GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash",
- &denom_hash),
- GNUNET_PQ_result_spec_timestamp ("valid_from",
- &issue.start),
- GNUNET_PQ_result_spec_timestamp ("expire_withdraw",
- &issue.expire_withdraw),
- GNUNET_PQ_result_spec_timestamp ("expire_deposit",
- &issue.expire_deposit),
- GNUNET_PQ_result_spec_timestamp ("expire_legal",
- &issue.expire_legal),
- TALER_PQ_RESULT_SPEC_AMOUNT ("coin",
- &issue.value),
- TALER_PQ_RESULT_SPEC_AMOUNT ("fee_withdraw",
- &issue.fees.withdraw),
- TALER_PQ_RESULT_SPEC_AMOUNT ("fee_deposit",
- &issue.fees.deposit),
- TALER_PQ_RESULT_SPEC_AMOUNT ("fee_refresh",
- &issue.fees.refresh),
- TALER_PQ_RESULT_SPEC_AMOUNT ("fee_refund",
- &issue.fees.refund),
- TALER_PQ_result_spec_denom_pub ("denom_pub",
- &denom_pub),
- GNUNET_PQ_result_spec_uint32 ("age_mask",
- &issue.age_mask.bits),
- GNUNET_PQ_result_spec_end
- };
-
- if (GNUNET_OK !=
- GNUNET_PQ_extract_result (result,
- rs,
- i))
- {
- GNUNET_break (0);
- return;
- }
-
- /* Unfortunately we have to carry the age mask in both, the
- * TALER_DenominationPublicKey and
- * TALER_EXCHANGEDB_DenominationKeyInformation at different times.
- * Here we use _both_ so let's make sure the values are the same. */
- denom_pub.age_mask = issue.age_mask;
- TALER_denom_pub_hash (&denom_pub,
- &issue.denom_hash);
- if (0 !=
- GNUNET_memcmp (&issue.denom_hash,
- &denom_hash))
- {
- GNUNET_break (0);
- }
- else
- {
- dic->cb (dic->cb_cls,
- &denom_pub,
- &issue);
- }
- TALER_denom_pub_free (&denom_pub);
- }
-}
-
-
-/**
- * Fetch information about all known denomination keys.
- *
- * @param cls the @e cls of this struct with the plugin-specific state
- * @param cb function to call on each denomination key
- * @param cb_cls closure for @a cb
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_iterate_denomination_info (void *cls,
- TALER_EXCHANGEDB_DenominationCallback cb,
- void *cb_cls)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_end
- };
- struct DenomIteratorContext dic = {
- .cb = cb,
- .cb_cls = cb_cls,
- .pg = pg
- };
-
- return GNUNET_PQ_eval_prepared_multi_select (pg->conn,
- "denomination_iterate",
- params,
- &domination_cb_helper,
- &dic);
-}
-
-
-/**
- * Closure for #dominations_cb_helper()
- */
-struct DenomsIteratorContext
-{
- /**
- * Function to call with the results.
- */
- TALER_EXCHANGEDB_DenominationsCallback cb;
-
- /**
- * Closure to pass to @e cb
- */
- void *cb_cls;
-
- /**
- * Plugin context.
- */
- struct PostgresClosure *pg;
-};
-
-
-/**
- * Helper function for #postgres_iterate_denominations().
- * Calls the callback with each denomination key.
- *
- * @param cls a `struct DenomsIteratorContext`
- * @param result db results
- * @param num_results number of results in @a result
- */
-static void
-dominations_cb_helper (void *cls,
- PGresult *result,
- unsigned int num_results)
-{
- struct DenomsIteratorContext *dic = cls;
- struct PostgresClosure *pg = dic->pg;
-
- for (unsigned int i = 0; i<num_results; i++)
- {
- struct TALER_EXCHANGEDB_DenominationKeyMetaData meta = {0};
- struct TALER_DenominationPublicKey denom_pub = {0};
- struct TALER_MasterSignatureP master_sig = {0};
- struct TALER_DenominationHashP h_denom_pub = {0};
- bool revoked;
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_auto_from_type ("master_sig",
- &master_sig),
- GNUNET_PQ_result_spec_bool ("revoked",
- &revoked),
- GNUNET_PQ_result_spec_timestamp ("valid_from",
- &meta.start),
- GNUNET_PQ_result_spec_timestamp ("expire_withdraw",
- &meta.expire_withdraw),
- GNUNET_PQ_result_spec_timestamp ("expire_deposit",
- &meta.expire_deposit),
- GNUNET_PQ_result_spec_timestamp ("expire_legal",
- &meta.expire_legal),
- TALER_PQ_RESULT_SPEC_AMOUNT ("coin",
- &meta.value),
- TALER_PQ_RESULT_SPEC_AMOUNT ("fee_withdraw",
- &meta.fees.withdraw),
- TALER_PQ_RESULT_SPEC_AMOUNT ("fee_deposit",
- &meta.fees.deposit),
- TALER_PQ_RESULT_SPEC_AMOUNT ("fee_refresh",
- &meta.fees.refresh),
- TALER_PQ_RESULT_SPEC_AMOUNT ("fee_refund",
- &meta.fees.refund),
- TALER_PQ_result_spec_denom_pub ("denom_pub",
- &denom_pub),
- GNUNET_PQ_result_spec_uint32 ("age_mask",
- &meta.age_mask.bits),
- GNUNET_PQ_result_spec_end
- };
-
- if (GNUNET_OK !=
- GNUNET_PQ_extract_result (result,
- rs,
- i))
- {
- GNUNET_break (0);
- return;
- }
-
- /* make sure the mask information is the same */
- denom_pub.age_mask = meta.age_mask;
-
- TALER_denom_pub_hash (&denom_pub,
- &h_denom_pub);
- dic->cb (dic->cb_cls,
- &denom_pub,
- &h_denom_pub,
- &meta,
- &master_sig,
- revoked);
- GNUNET_PQ_cleanup_result (rs);
- }
-}
-
-
-/**
- * Function called to invoke @a cb on every known denomination key (revoked
- * and non-revoked) that has been signed by the master key. Runs in its own
- * read-only transaction.
- *
- *
- * @param cls the @e cls of this struct with the plugin-specific state
- * @param cb function to call on each denomination key
- * @param cb_cls closure for @a cb
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_iterate_denominations (void *cls,
- TALER_EXCHANGEDB_DenominationsCallback cb,
- void *cb_cls)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_end
- };
- struct DenomsIteratorContext dic = {
- .cb = cb,
- .cb_cls = cb_cls,
- .pg = pg
- };
-
- return GNUNET_PQ_eval_prepared_multi_select (pg->conn,
- "select_denominations",
- params,
- &dominations_cb_helper,
- &dic);
-}
-
-
-/**
- * Closure for #signkeys_cb_helper()
- */
-struct SignkeysIteratorContext
-{
- /**
- * Function to call with the results.
- */
- TALER_EXCHANGEDB_ActiveSignkeysCallback cb;
-
- /**
- * Closure to pass to @e cb
- */
- void *cb_cls;
-
-};
-
-
-/**
- * Helper function for #postgres_iterate_active_signkeys().
- * Calls the callback with each signkey.
- *
- * @param cls a `struct SignkeysIteratorContext`
- * @param result db results
- * @param num_results number of results in @a result
- */
-static void
-signkeys_cb_helper (void *cls,
- PGresult *result,
- unsigned int num_results)
-{
- struct SignkeysIteratorContext *dic = cls;
-
- for (unsigned int i = 0; i<num_results; i++)
- {
- struct TALER_EXCHANGEDB_SignkeyMetaData meta;
- struct TALER_ExchangePublicKeyP exchange_pub;
- struct TALER_MasterSignatureP master_sig;
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_auto_from_type ("master_sig",
- &master_sig),
- GNUNET_PQ_result_spec_auto_from_type ("exchange_pub",
- &exchange_pub),
- GNUNET_PQ_result_spec_timestamp ("valid_from",
- &meta.start),
- GNUNET_PQ_result_spec_timestamp ("expire_sign",
- &meta.expire_sign),
- GNUNET_PQ_result_spec_timestamp ("expire_legal",
- &meta.expire_legal),
- GNUNET_PQ_result_spec_end
- };
-
- if (GNUNET_OK !=
- GNUNET_PQ_extract_result (result,
- rs,
- i))
- {
- GNUNET_break (0);
- return;
- }
- dic->cb (dic->cb_cls,
- &exchange_pub,
- &meta,
- &master_sig);
- }
-}
-
-
-/**
- * Function called to invoke @a cb on every non-revoked exchange signing key
- * that has been signed by the master key. Revoked and (for signing!)
- * expired keys are skipped. Runs in its own read-only transaction.
- *
- * @param cls the @e cls of this struct with the plugin-specific state
- * @param cb function to call on each signing key
- * @param cb_cls closure for @a cb
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_iterate_active_signkeys (void *cls,
- TALER_EXCHANGEDB_ActiveSignkeysCallback cb,
- void *cb_cls)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_TIME_Absolute now = {0};
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_absolute_time (&now),
- GNUNET_PQ_query_param_end
- };
- struct SignkeysIteratorContext dic = {
- .cb = cb,
- .cb_cls = cb_cls,
- };
-
- now = GNUNET_TIME_absolute_get ();
- return GNUNET_PQ_eval_prepared_multi_select (pg->conn,
- "select_signkeys",
- params,
- &signkeys_cb_helper,
- &dic);
-}
-
-
-/**
- * Closure for #auditors_cb_helper()
- */
-struct AuditorsIteratorContext
-{
- /**
- * Function to call with the results.
- */
- TALER_EXCHANGEDB_AuditorsCallback cb;
-
- /**
- * Closure to pass to @e cb
- */
- void *cb_cls;
-
-};
-
-
-/**
- * Helper function for #postgres_iterate_active_auditors().
- * Calls the callback with each auditor.
- *
- * @param cls a `struct SignkeysIteratorContext`
- * @param result db results
- * @param num_results number of results in @a result
- */
-static void
-auditors_cb_helper (void *cls,
- PGresult *result,
- unsigned int num_results)
-{
- struct AuditorsIteratorContext *dic = cls;
-
- for (unsigned int i = 0; i<num_results; i++)
- {
- struct TALER_AuditorPublicKeyP auditor_pub;
- char *auditor_url;
- char *auditor_name;
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_auto_from_type ("auditor_pub",
- &auditor_pub),
- GNUNET_PQ_result_spec_string ("auditor_url",
- &auditor_url),
- GNUNET_PQ_result_spec_string ("auditor_name",
- &auditor_name),
- GNUNET_PQ_result_spec_end
- };
-
- if (GNUNET_OK !=
- GNUNET_PQ_extract_result (result,
- rs,
- i))
- {
- GNUNET_break (0);
- return;
- }
- dic->cb (dic->cb_cls,
- &auditor_pub,
- auditor_url,
- auditor_name);
- GNUNET_PQ_cleanup_result (rs);
- }
-}
-
-
-/**
- * Function called to invoke @a cb on every active auditor. Disabled
- * auditors are skipped. Runs in its own read-only transaction.
- *
- * @param cls the @e cls of this struct with the plugin-specific state
- * @param cb function to call on each active auditor
- * @param cb_cls closure for @a cb
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_iterate_active_auditors (void *cls,
- TALER_EXCHANGEDB_AuditorsCallback cb,
- void *cb_cls)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_end
- };
- struct AuditorsIteratorContext dic = {
- .cb = cb,
- .cb_cls = cb_cls,
- };
-
- return GNUNET_PQ_eval_prepared_multi_select (pg->conn,
- "select_auditors",
- params,
- &auditors_cb_helper,
- &dic);
-}
-
-
-/**
- * Closure for #auditor_denoms_cb_helper()
- */
-struct AuditorDenomsIteratorContext
-{
- /**
- * Function to call with the results.
- */
- TALER_EXCHANGEDB_AuditorDenominationsCallback cb;
-
- /**
- * Closure to pass to @e cb
- */
- void *cb_cls;
-};
-
-
-/**
- * Helper function for #postgres_iterate_auditor_denominations().
- * Calls the callback with each auditor and denomination pair.
- *
- * @param cls a `struct AuditorDenomsIteratorContext`
- * @param result db results
- * @param num_results number of results in @a result
- */
-static void
-auditor_denoms_cb_helper (void *cls,
- PGresult *result,
- unsigned int num_results)
-{
- struct AuditorDenomsIteratorContext *dic = cls;
-
- for (unsigned int i = 0; i<num_results; i++)
- {
- struct TALER_AuditorPublicKeyP auditor_pub;
- struct TALER_DenominationHashP h_denom_pub;
- struct TALER_AuditorSignatureP auditor_sig;
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_auto_from_type ("auditor_pub",
- &auditor_pub),
- GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash",
- &h_denom_pub),
- GNUNET_PQ_result_spec_auto_from_type ("auditor_sig",
- &auditor_sig),
- GNUNET_PQ_result_spec_end
- };
-
- if (GNUNET_OK !=
- GNUNET_PQ_extract_result (result,
- rs,
- i))
- {
- GNUNET_break (0);
- return;
- }
- dic->cb (dic->cb_cls,
- &auditor_pub,
- &h_denom_pub,
- &auditor_sig);
- }
-}
-
-
-/**
- * Function called to invoke @a cb on every denomination with an active
- * auditor. Disabled auditors and denominations without auditor are
- * skipped. Runs in its own read-only transaction.
- *
- * @param cls the @e cls of this struct with the plugin-specific state
- * @param cb function to call on each active auditor
- * @param cb_cls closure for @a cb
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_iterate_auditor_denominations (
- void *cls,
- TALER_EXCHANGEDB_AuditorDenominationsCallback cb,
- void *cb_cls)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_end
- };
- struct AuditorDenomsIteratorContext dic = {
- .cb = cb,
- .cb_cls = cb_cls,
- };
-
- return GNUNET_PQ_eval_prepared_multi_select (pg->conn,
- "select_auditor_denoms",
- params,
- &auditor_denoms_cb_helper,
- &dic);
-}
-
-
-/**
- * Get the summary of a reserve.
- *
- * @param cls the `struct PostgresClosure` with the plugin-specific state
- * @param[in,out] reserve the reserve data. The public key of the reserve should be
- * set in this structure; it is used to query the database. The balance
- * and expiration are then filled accordingly.
- * @param[out] kyc set to the KYC status of the reserve
- * @return transaction status
- */
-static enum GNUNET_DB_QueryStatus
-postgres_reserves_get (void *cls,
- struct TALER_EXCHANGEDB_Reserve *reserve,
- struct TALER_EXCHANGEDB_KycStatus *kyc)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (&reserve->pub),
- GNUNET_PQ_query_param_end
- };
- struct GNUNET_PQ_ResultSpec rs[] = {
- TALER_PQ_RESULT_SPEC_AMOUNT ("current_balance",
- &reserve->balance),
- GNUNET_PQ_result_spec_timestamp ("expiration_date",
- &reserve->expiry),
- GNUNET_PQ_result_spec_timestamp ("gc_date",
- &reserve->gc),
- GNUNET_PQ_result_spec_uint64 ("payment_target_uuid",
- &kyc->payment_target_uuid),
- GNUNET_PQ_result_spec_bool ("kyc_ok",
- &kyc->ok),
- GNUNET_PQ_result_spec_end
- };
-
- kyc->type = TALER_EXCHANGEDB_KYC_WITHDRAW;
- return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "reserves_get_with_kyc",
- params,
- rs);
-}
-
-
-/**
- * Set the KYC status to "OK" for a bank account.
- *
- * @param cls the @e cls of this struct with the plugin-specific state
- * @param h_payto which account has been checked
- * @param id external ID to persist
- * @return transaction status
- */
-static enum GNUNET_DB_QueryStatus
-postgres_set_kyc_ok (void *cls,
- const struct TALER_PaytoHashP *h_payto,
- const char *id)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (h_payto),
- GNUNET_PQ_query_param_end
- };
- struct GNUNET_PQ_QueryParam params2[] = {
- GNUNET_PQ_query_param_auto_from_type (h_payto),
- GNUNET_PQ_query_param_string (id),
- GNUNET_PQ_query_param_end
- };
- struct TALER_KycCompletedEventP rep = {
- .header.size = htons (sizeof (rep)),
- .header.type = htons (TALER_DBEVENT_EXCHANGE_KYC_COMPLETED)
- };
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_auto_from_type ("wire_target_h_payto",
- &rep.h_payto),
- GNUNET_PQ_result_spec_end
- };
- enum GNUNET_DB_QueryStatus qs;
-
- qs = GNUNET_PQ_eval_prepared_non_select (pg->conn,
- "set_kyc_ok",
- params2);
- if (qs <= 0)
- return qs;
- qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "get_kyc_h_payto",
- params,
- rs);
- if (qs <= 0)
- return qs;
- postgres_event_notify (pg,
- &rep.header,
- NULL,
- 0);
- return qs;
-}
-
-
-/**
- * Get the @a kyc status and @a h_payto by UUID.
- *
- * @param cls the @e cls of this struct with the plugin-specific state
- * @param h_payto set to the hash of the account's payto URI (unsalted)
- * @param[out] kyc set to the KYC status of the account
- * @return transaction status
- */
-static enum GNUNET_DB_QueryStatus
-postgres_select_kyc_status (void *cls,
- const struct TALER_PaytoHashP *h_payto,
- struct TALER_EXCHANGEDB_KycStatus *kyc)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (h_payto),
- GNUNET_PQ_query_param_end
- };
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_uint64 ("wire_target_serial_id",
- &kyc->payment_target_uuid),
- GNUNET_PQ_result_spec_bool ("kyc_ok",
- &kyc->ok),
- GNUNET_PQ_result_spec_end
- };
-
- kyc->type = TALER_EXCHANGEDB_KYC_UNKNOWN;
- return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "select_kyc_status_by_payto",
- params,
- rs);
-}
-
-
-/**
- * Compute the hash of the @a payto_uri and use it to get the KYC status for a
- * wallet. If the status is unknown, inserts a new status record (hence
- * INsertSELECT).
- *
- * @param pg the plugin-specific state
- * @param payto_uri the payto URI to check
- * @param[out] h_payto set to the hash of @a payto_uri
- * @param[out] kyc set to the KYC status of the wallet
- * @return transaction status
- */
-static enum GNUNET_DB_QueryStatus
-inselect_account_kyc_status (
- struct PostgresClosure *pg,
- const char *payto_uri,
- struct TALER_PaytoHashP *h_payto,
- struct TALER_EXCHANGEDB_KycStatus *kyc)
-{
- enum GNUNET_DB_QueryStatus qs;
-
- TALER_payto_hash (payto_uri,
- h_payto);
- {
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (h_payto),
- GNUNET_PQ_query_param_end
- };
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_uint64 ("wire_target_serial_id",
- &kyc->payment_target_uuid),
- GNUNET_PQ_result_spec_bool ("kyc_ok",
- &kyc->ok),
- GNUNET_PQ_result_spec_end
- };
-
- qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "select_kyc_status_by_payto",
- params,
- rs);
- if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
- {
- struct GNUNET_PQ_QueryParam iparams[] = {
- GNUNET_PQ_query_param_auto_from_type (h_payto),
- GNUNET_PQ_query_param_string (payto_uri),
- GNUNET_PQ_query_param_end
- };
- struct GNUNET_PQ_ResultSpec irs[] = {
- GNUNET_PQ_result_spec_uint64 ("wire_target_serial_id",
- &kyc->payment_target_uuid),
- GNUNET_PQ_result_spec_end
- };
-
- qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "insert_kyc_status",
- iparams,
- irs);
- if (qs < 0)
- return qs;
- if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
- return GNUNET_DB_STATUS_SOFT_ERROR;
- kyc->ok = false;
- }
- }
- kyc->type = TALER_EXCHANGEDB_KYC_BALANCE;
- return qs;
-}
-
-
-/**
- * Get the KYC status for a wallet. If the status is unknown,
- * inserts a new status record (hence INsertSELECT).
- *
- * @param cls the @e cls of this struct with the plugin-specific state
- * @param reserve_pub public key of the wallet
- * @param[out] kyc set to the KYC status of the wallet
- * @return transaction status
- */
-static enum GNUNET_DB_QueryStatus
-postgres_inselect_wallet_kyc_status (
- void *cls,
- const struct TALER_ReservePublicKeyP *reserve_pub,
- struct TALER_EXCHANGEDB_KycStatus *kyc)
-{
- struct PostgresClosure *pg = cls;
- char *payto_uri;
- enum GNUNET_DB_QueryStatus qs;
- struct TALER_PaytoHashP h_payto;
-
- payto_uri = TALER_payto_from_reserve (pg->exchange_url,
- reserve_pub);
- qs = inselect_account_kyc_status (pg,
- payto_uri,
- &h_payto,
- kyc);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Wire account for `%s' is %llu\n",
- payto_uri,
- (unsigned long long) kyc->payment_target_uuid);
- GNUNET_free (payto_uri);
- return qs;
-}
-
-
-/**
- * Get the summary of a reserve.
- *
- * @param cls the `struct PostgresClosure` with the plugin-specific state
- * @param[in,out] reserve the reserve data. The public key of the reserve should be
- * set in this structure; it is used to query the database. The balance
- * and expiration are then filled accordingly.
- * @return transaction status
- */
-static enum GNUNET_DB_QueryStatus
-reserves_get_internal (void *cls,
- struct TALER_EXCHANGEDB_Reserve *reserve)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (&reserve->pub),
- GNUNET_PQ_query_param_end
- };
- struct GNUNET_PQ_ResultSpec rs[] = {
- TALER_PQ_RESULT_SPEC_AMOUNT ("current_balance",
- &reserve->balance),
- GNUNET_PQ_result_spec_timestamp ("expiration_date",
- &reserve->expiry),
- GNUNET_PQ_result_spec_timestamp ("gc_date",
- &reserve->gc),
- GNUNET_PQ_result_spec_end
- };
-
- return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "reserves_get",
- params,
- rs);
-}
-
-
-/**
- * Updates a reserve with the data from the given reserve structure.
- *
- * @param cls the `struct PostgresClosure` with the plugin-specific state
- * @param reserve the reserve structure whose data will be used to update the
- * corresponding record in the database.
- * @return transaction status
- */
-static enum GNUNET_DB_QueryStatus
-reserves_update (void *cls,
- const struct TALER_EXCHANGEDB_Reserve *reserve)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_timestamp (&reserve->expiry),
- GNUNET_PQ_query_param_timestamp (&reserve->gc),
- TALER_PQ_query_param_amount (&reserve->balance),
- GNUNET_PQ_query_param_auto_from_type (&reserve->pub),
- GNUNET_PQ_query_param_end
- };
-
- return GNUNET_PQ_eval_prepared_non_select (pg->conn,
- "reserve_update",
- params);
-}
-
-
-/**
- * Generate event notification for the reserve
- * change.
- *
- * @param pg plugin state
- * @param reserve_pub reserve to notfiy on
- */
-static void
-notify_on_reserve (struct PostgresClosure *pg,
- const struct TALER_ReservePublicKeyP *reserve_pub)
-{
- struct TALER_ReserveEventP rep = {
- .header.size = htons (sizeof (rep)),
- .header.type = htons (TALER_DBEVENT_EXCHANGE_RESERVE_INCOMING),
- .reserve_pub = *reserve_pub
- };
-
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Notifying on reserve!\n");
- postgres_event_notify (pg,
- &rep.header,
- NULL,
- 0);
-}
-
-
-/**
- * Insert an incoming transaction into reserves. New reserves are also
- * created through this function. Started within the scope of an ongoing
- * transaction.
- *
- * @param cls the `struct PostgresClosure` with the plugin-specific state
- * @param reserve_pub public key of the reserve
- * @param balance the amount that has to be added to the reserve
- * @param execution_time when was the amount added
- * @param sender_account_details account information for the sender (payto://-URL)
- * @param exchange_account_section name of the section in the configuration for the exchange's
- * account into which the deposit was made
- * @param wire_ref unique reference identifying the wire transfer
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_reserves_in_insert (void *cls,
- const struct TALER_ReservePublicKeyP *reserve_pub,
- const struct TALER_Amount *balance,
- struct GNUNET_TIME_Timestamp execution_time,
- const char *sender_account_details,
- const char *exchange_account_section,
- uint64_t wire_ref)
-{
- struct PostgresClosure *pg = cls;
- enum GNUNET_DB_QueryStatus qs1;
- struct TALER_EXCHANGEDB_Reserve reserve;
- struct GNUNET_TIME_Timestamp expiry;
- struct GNUNET_TIME_Timestamp gc;
- uint64_t reserve_uuid;
-
- reserve.pub = *reserve_pub;
- expiry = GNUNET_TIME_absolute_to_timestamp (
- GNUNET_TIME_absolute_add (execution_time.abs_time,
- pg->idle_reserve_expiration_time));
- gc = GNUNET_TIME_absolute_to_timestamp (
- GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (),
- pg->legal_reserve_expiration_time));
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Creating reserve %s with expiration in %s\n",
- TALER_B2S (reserve_pub),
- GNUNET_STRINGS_relative_time_to_string (
- pg->idle_reserve_expiration_time,
- GNUNET_NO));
- /* Optimistically assume this is a new reserve, create balance for the first
- time; we do this before adding the actual transaction to "reserves_in",
- as for a new reserve it can't be a duplicate 'add' operation, and as
- the 'add' operation needs the reserve entry as a foreign key. */
- {
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (reserve_pub),
- TALER_PQ_query_param_amount (balance),
- GNUNET_PQ_query_param_timestamp (&expiry),
- GNUNET_PQ_query_param_timestamp (&gc),
- GNUNET_PQ_query_param_end
- };
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_uint64 ("reserve_uuid",
- &reserve_uuid),
- GNUNET_PQ_result_spec_end
- };
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Reserve does not exist; creating a new one\n");
- /* Note: query uses 'on conflict do nothing' */
- qs1 = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "reserve_create",
- params,
- rs);
- if (qs1 < 0)
- return qs1;
- }
-
- /* Create new incoming transaction, "ON CONFLICT DO NOTHING"
- is again used to guard against duplicates. */
- {
- enum GNUNET_DB_QueryStatus qs2;
- struct TALER_EXCHANGEDB_KycStatus kyc;
- enum GNUNET_DB_QueryStatus qs3;
- struct TALER_PaytoHashP h_payto;
-
- memset (&kyc,
- 0,
- sizeof (kyc));
- qs3 = inselect_account_kyc_status (pg,
- sender_account_details,
- &h_payto,
- &kyc);
- if (qs3 <= 0)
- {
- GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs3);
- return qs3;
- }
- GNUNET_assert (0 != kyc.payment_target_uuid);
- /* We do not have the UUID, so insert by public key */
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (&reserve.pub),
- GNUNET_PQ_query_param_uint64 (&wire_ref),
- TALER_PQ_query_param_amount (balance),
- GNUNET_PQ_query_param_string (exchange_account_section),
- GNUNET_PQ_query_param_auto_from_type (&h_payto),
- GNUNET_PQ_query_param_timestamp (&execution_time),
- GNUNET_PQ_query_param_end
- };
-
- qs2 = GNUNET_PQ_eval_prepared_non_select (pg->conn,
- "reserves_in_add_transaction",
- params);
- /* qs2 could be 0 as statement used 'ON CONFLICT DO NOTHING' */
- if (0 >= qs2)
- {
- if ( (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs2) &&
- (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != qs1) )
- {
- /* Conflict for the transaction, but the reserve was
- just now created, that should be impossible. */
- GNUNET_break (0); /* should be impossible: reserve was fresh,
- but transaction already known */
- return GNUNET_DB_STATUS_HARD_ERROR;
- }
- /* Transaction was already known or error. We are finished. */
- return qs2;
- }
- }
- if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs1)
- {
- /* New reserve, we are finished */
- notify_on_reserve (pg,
- reserve_pub);
- return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
- }
-
- /* we were wrong with our optimistic assumption:
- reserve did already exist, need to do an update instead */
- {
- /* We need to move away from 'read committed' to serializable.
- Also, we know that it should be safe to commit at this point.
- (We are only run in a larger transaction for performance.) */
- enum GNUNET_DB_QueryStatus cs;
-
- cs = postgres_commit (pg);
- if (cs < 0)
- return cs;
- if (GNUNET_OK !=
- postgres_start (pg,
- "reserve-update-serializable"))
- {
- GNUNET_break (0);
- return GNUNET_DB_STATUS_HARD_ERROR;
- }
- }
- {
- enum GNUNET_DB_QueryStatus reserve_exists;
-
- reserve_exists = reserves_get_internal (pg,
- &reserve);
- switch (reserve_exists)
- {
- case GNUNET_DB_STATUS_HARD_ERROR:
- GNUNET_break (0);
- return reserve_exists;
- case GNUNET_DB_STATUS_SOFT_ERROR:
- return reserve_exists;
- case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
- /* First we got a conflict, but then we cannot select? Very strange. */
- GNUNET_break (0);
- return GNUNET_DB_STATUS_SOFT_ERROR;
- case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
- /* continued below */
- break;
- }
- }
-
- {
- struct TALER_EXCHANGEDB_Reserve updated_reserve;
- enum GNUNET_DB_QueryStatus qs3;
-
- /* If the reserve already existed, we need to still update the
- balance; we do this after checking for duplication, as
- otherwise we might have to actually pay the cost to roll this
- back for duplicate transactions; like this, we should virtually
- never actually have to rollback anything. */
- updated_reserve.pub = reserve.pub;
- if (0 >
- TALER_amount_add (&updated_reserve.balance,
- &reserve.balance,
- balance))
- {
- /* currency overflow or incompatible currency */
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Attempt to deposit incompatible amount into reserve\n");
- return GNUNET_DB_STATUS_HARD_ERROR;
- }
- updated_reserve.expiry = GNUNET_TIME_timestamp_max (expiry,
- reserve.expiry);
- updated_reserve.gc = GNUNET_TIME_timestamp_max (gc,
- reserve.gc);
- qs3 = reserves_update (pg,
- &updated_reserve);
- switch (qs3)
- {
- case GNUNET_DB_STATUS_HARD_ERROR:
- GNUNET_break (0);
- return qs3;
- case GNUNET_DB_STATUS_SOFT_ERROR:
- return qs3;
- case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
- /* How can the UPDATE not work here? Very strange. */
- GNUNET_break (0);
- return GNUNET_DB_STATUS_HARD_ERROR;
- case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
- /* continued below */
- break;
- }
- }
- notify_on_reserve (pg,
- reserve_pub);
- /* Go back to original transaction mode */
- {
- enum GNUNET_DB_QueryStatus cs;
-
- cs = postgres_commit (pg);
- if (cs < 0)
- return cs;
- if (GNUNET_OK !=
- postgres_start_read_committed (pg,
- "reserve-insert-continued"))
- {
- GNUNET_break (0);
- return GNUNET_DB_STATUS_HARD_ERROR;
- }
- }
- return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
-}
-
-
-/**
- * Locate the response for a /reserve/withdraw request under the
- * key of the hash of the blinded message.
- *
- * @param cls the `struct PostgresClosure` with the plugin-specific state
- * @param bch hash that uniquely identifies the withdraw operation
- * @param collectable corresponding collectable coin (blind signature)
- * if a coin is found
- * @return statement execution status
- */
-static enum GNUNET_DB_QueryStatus
-postgres_get_withdraw_info (
- void *cls,
- const struct TALER_BlindedCoinHashP *bch,
- struct TALER_EXCHANGEDB_CollectableBlindcoin *collectable)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (bch),
- GNUNET_PQ_query_param_end
- };
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash",
- &collectable->denom_pub_hash),
- TALER_PQ_result_spec_blinded_denom_sig ("denom_sig",
- &collectable->sig),
- GNUNET_PQ_result_spec_auto_from_type ("reserve_sig",
- &collectable->reserve_sig),
- GNUNET_PQ_result_spec_auto_from_type ("reserve_pub",
- &collectable->reserve_pub),
- GNUNET_PQ_result_spec_auto_from_type ("h_blind_ev",
- &collectable->h_coin_envelope),
- TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee",
- &collectable->amount_with_fee),
- TALER_PQ_RESULT_SPEC_AMOUNT ("fee_withdraw",
- &collectable->withdraw_fee),
- GNUNET_PQ_result_spec_end
- };
-
- return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "get_withdraw_info",
- params,
- rs);
-}
-
-
-/**
- * Perform withdraw operation, checking for sufficient balance
- * and possibly persisting the withdrawal details.
- *
- * @param cls the `struct PostgresClosure` with the plugin-specific state
- * @param nonce client-contributed input for CS denominations that must be checked for idempotency, or NULL for non-CS withdrawals
- * @param[in,out] collectable corresponding collectable coin (blind signature) if a coin is found; possibly updated if a (different) signature exists already
- * @param now current time (rounded)
- * @param[out] found set to true if the reserve was found
- * @param[out] balance_ok set to true if the balance was sufficient
- * @param[out] kyc set to true if the kyc status of the reserve is satisfied
- * @param[out] ruuid set to the reserve's UUID (reserves table row)
- * @return query execution status
- */
-static enum GNUNET_DB_QueryStatus
-postgres_do_withdraw (
- void *cls,
- const struct TALER_CsNonce *nonce,
- const struct TALER_EXCHANGEDB_CollectableBlindcoin *collectable,
- struct GNUNET_TIME_Timestamp now,
- bool *found,
- bool *balance_ok,
- struct TALER_EXCHANGEDB_KycStatus *kyc,
- uint64_t *ruuid)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_TIME_Timestamp gc;
- struct GNUNET_PQ_QueryParam params[] = {
- NULL == nonce
- ? GNUNET_PQ_query_param_null ()
- : GNUNET_PQ_query_param_auto_from_type (nonce),
- TALER_PQ_query_param_amount (&collectable->amount_with_fee),
- GNUNET_PQ_query_param_auto_from_type (&collectable->denom_pub_hash),
- GNUNET_PQ_query_param_auto_from_type (&collectable->reserve_pub),
- GNUNET_PQ_query_param_auto_from_type (&collectable->reserve_sig),
- GNUNET_PQ_query_param_auto_from_type (&collectable->h_coin_envelope),
- TALER_PQ_query_param_blinded_denom_sig (&collectable->sig),
- GNUNET_PQ_query_param_timestamp (&now),
- GNUNET_PQ_query_param_timestamp (&gc),
- GNUNET_PQ_query_param_end
- };
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_bool ("reserve_found",
- found),
- GNUNET_PQ_result_spec_bool ("balance_ok",
- balance_ok),
- GNUNET_PQ_result_spec_bool ("kyc_ok",
- &kyc->ok),
- GNUNET_PQ_result_spec_uint64 ("payment_target_uuid",
- &kyc->payment_target_uuid),
- GNUNET_PQ_result_spec_uint64 ("ruuid",
- ruuid),
- GNUNET_PQ_result_spec_end
- };
-
- gc = GNUNET_TIME_absolute_to_timestamp (
- GNUNET_TIME_absolute_add (now.abs_time,
- pg->legal_reserve_expiration_time));
- kyc->type = TALER_EXCHANGEDB_KYC_WITHDRAW;
- return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "call_withdraw",
- params,
- rs);
-}
-
-
-/**
- * Perform reserve update as part of a batch withdraw operation, checking
- * for sufficient balance. Persisting the withdrawal details is done
- * separately!
- *
- * @param cls the `struct PostgresClosure` with the plugin-specific state
- * @param now current time (rounded)
- * @param reserve_pub public key of the reserve to debit
- * @param amount total amount to withdraw
- * @param[out] found set to true if the reserve was found
- * @param[out] balance_ok set to true if the balance was sufficient
- * @param[out] kyc set to the KYC status of the reserve
- * @param[out] ruuid set to the reserve's UUID (reserves table row)
- * @return query execution status
- */
-static enum GNUNET_DB_QueryStatus
-postgres_do_batch_withdraw (
- void *cls,
- struct GNUNET_TIME_Timestamp now,
- const struct TALER_ReservePublicKeyP *reserve_pub,
- const struct TALER_Amount *amount,
- bool *found,
- bool *balance_ok,
- struct TALER_EXCHANGEDB_KycStatus *kyc,
- uint64_t *ruuid)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_TIME_Timestamp gc;
- struct GNUNET_PQ_QueryParam params[] = {
- TALER_PQ_query_param_amount (amount),
- GNUNET_PQ_query_param_auto_from_type (reserve_pub),
- GNUNET_PQ_query_param_timestamp (&now),
- GNUNET_PQ_query_param_timestamp (&gc),
- GNUNET_PQ_query_param_end
- };
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_bool ("reserve_found",
- found),
- GNUNET_PQ_result_spec_bool ("balance_ok",
- balance_ok),
- GNUNET_PQ_result_spec_bool ("kyc_ok",
- &kyc->ok),
- GNUNET_PQ_result_spec_uint64 ("payment_target_uuid",
- &kyc->payment_target_uuid),
- GNUNET_PQ_result_spec_uint64 ("ruuid",
- ruuid),
- GNUNET_PQ_result_spec_end
- };
-
- gc = GNUNET_TIME_absolute_to_timestamp (
- GNUNET_TIME_absolute_add (now.abs_time,
- pg->legal_reserve_expiration_time));
- kyc->type = TALER_EXCHANGEDB_KYC_WITHDRAW;
- return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "call_batch_withdraw",
- params,
- rs);
-}
-
-
-/**
- * Perform insert as part of a batch withdraw operation, and persisting the
- * withdrawal details.
- *
- * @param cls the `struct PostgresClosure` with the plugin-specific state
- * @param nonce client-contributed input for CS denominations that must be checked for idempotency, or NULL for non-CS withdrawals
- * @param collectable corresponding collectable coin (blind signature)
- * @param now current time (rounded)
- * @param ruuid reserve UUID
- * @param[out] denom_unknown set if the denomination is unknown in the DB
- * @param[out] conflict if the envelope was already in the DB
- * @param[out] nonce_reuse if @a nonce was non-NULL and reused
- * @return query execution status
- */
-static enum GNUNET_DB_QueryStatus
-postgres_do_batch_withdraw_insert (
- void *cls,
- const struct TALER_CsNonce *nonce,
- const struct TALER_EXCHANGEDB_CollectableBlindcoin *collectable,
- struct GNUNET_TIME_Timestamp now,
- uint64_t ruuid,
- bool *denom_unknown,
- bool *conflict,
- bool *nonce_reuse)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- NULL == nonce
- ? GNUNET_PQ_query_param_null ()
- : GNUNET_PQ_query_param_auto_from_type (nonce),
- TALER_PQ_query_param_amount (&collectable->amount_with_fee),
- GNUNET_PQ_query_param_auto_from_type (&collectable->denom_pub_hash),
- GNUNET_PQ_query_param_uint64 (&ruuid),
- GNUNET_PQ_query_param_auto_from_type (&collectable->reserve_sig),
- GNUNET_PQ_query_param_auto_from_type (&collectable->h_coin_envelope),
- TALER_PQ_query_param_blinded_denom_sig (&collectable->sig),
- GNUNET_PQ_query_param_timestamp (&now),
- GNUNET_PQ_query_param_end
- };
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_bool ("denom_unknown",
- denom_unknown),
- GNUNET_PQ_result_spec_bool ("conflict",
- conflict),
- GNUNET_PQ_result_spec_bool ("nonce_reuse",
- nonce_reuse),
- GNUNET_PQ_result_spec_end
- };
-
- return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "call_batch_withdraw_insert",
- params,
- rs);
-}
-
-
-/**
- * Check that reserve remains below threshold for KYC
- * checks after withdraw operation.
- *
- * @param cls the `struct PostgresClosure` with the plugin-specific state
- * @param ruuid reserve to check
- * @param withdraw_start starting point to accumulate from
- * @param upper_limit maximum amount allowed
- * @param[out] below_limit set to true if the limit was not exceeded
- * @return query execution status
- */
-static enum GNUNET_DB_QueryStatus
-postgres_do_withdraw_limit_check (
- void *cls,
- uint64_t ruuid,
- struct GNUNET_TIME_Absolute withdraw_start,
- const struct TALER_Amount *upper_limit,
- bool *below_limit)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_uint64 (&ruuid),
- GNUNET_PQ_query_param_absolute_time (&withdraw_start),
- TALER_PQ_query_param_amount (upper_limit),
- GNUNET_PQ_query_param_end
- };
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_bool ("below_limit",
- below_limit),
- GNUNET_PQ_result_spec_end
- };
-
- return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "call_withdraw_limit_check",
- params,
- rs);
-}
-
-
-/**
- * Compute the shard number of a given @a merchant_pub.
- *
- * @param merchant_pub merchant public key to compute shard for
- * @return shard number
- */
-static uint64_t
-compute_shard (const struct TALER_MerchantPublicKeyP *merchant_pub)
-{
- uint32_t res;
-
- GNUNET_assert (GNUNET_YES ==
- GNUNET_CRYPTO_kdf (&res,
- sizeof (res),
- merchant_pub,
- sizeof (*merchant_pub),
- "VOID",
- 4,
- NULL, 0));
- /* interpret hash result as NBO for platform independence,
- convert to HBO and map to [0..2^31-1] range */
- res = ntohl (res);
- if (res > INT32_MAX)
- res += INT32_MIN;
- GNUNET_assert (res <= INT32_MAX);
- return (uint64_t) res;
-}
-
-
-/**
- * Perform deposit operation, checking for sufficient balance
- * of the coin and possibly persisting the deposit details.
- *
- * @param cls the `struct PostgresClosure` with the plugin-specific state
- * @param deposit deposit operation details
- * @param known_coin_id row of the coin in the known_coins table
- * @param h_payto hash of the merchant's bank account details
- * @param extension_blocked true if an extension is blocking the wire transfer
- * @param[in,out] exchange_timestamp time to use for the deposit (possibly updated)
- * @param[out] balance_ok set to true if the balance was sufficient
- * @param[out] in_conflict set to true if the deposit conflicted
- * @return query execution status
- */
-static enum GNUNET_DB_QueryStatus
-postgres_do_deposit (
- void *cls,
- const struct TALER_EXCHANGEDB_Deposit *deposit,
- uint64_t known_coin_id,
- const struct TALER_PaytoHashP *h_payto,
- bool extension_blocked,
- struct GNUNET_TIME_Timestamp *exchange_timestamp,
- bool *balance_ok,
- bool *in_conflict)
-{
- struct PostgresClosure *pg = cls;
- uint64_t deposit_shard = compute_shard (&deposit->merchant_pub);
- struct GNUNET_PQ_QueryParam params[] = {
- TALER_PQ_query_param_amount (&deposit->amount_with_fee),
- GNUNET_PQ_query_param_auto_from_type (&deposit->h_contract_terms),
- GNUNET_PQ_query_param_auto_from_type (&deposit->wire_salt),
- GNUNET_PQ_query_param_timestamp (&deposit->timestamp),
- GNUNET_PQ_query_param_timestamp (exchange_timestamp),
- GNUNET_PQ_query_param_timestamp (&deposit->refund_deadline),
- GNUNET_PQ_query_param_timestamp (&deposit->wire_deadline),
- GNUNET_PQ_query_param_auto_from_type (&deposit->merchant_pub),
- GNUNET_PQ_query_param_string (deposit->receiver_wire_account),
- GNUNET_PQ_query_param_auto_from_type (h_payto),
- GNUNET_PQ_query_param_uint64 (&known_coin_id),
- GNUNET_PQ_query_param_auto_from_type (&deposit->coin.coin_pub),
- GNUNET_PQ_query_param_auto_from_type (&deposit->csig),
- GNUNET_PQ_query_param_uint64 (&deposit_shard),
- GNUNET_PQ_query_param_bool (extension_blocked),
- (NULL == deposit->extension_details)
- ? GNUNET_PQ_query_param_null ()
- : TALER_PQ_query_param_json (deposit->extension_details),
- GNUNET_PQ_query_param_end
- };
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_bool ("balance_ok",
- balance_ok),
- GNUNET_PQ_result_spec_bool ("conflicted",
- in_conflict),
- GNUNET_PQ_result_spec_timestamp ("exchange_timestamp",
- exchange_timestamp),
- GNUNET_PQ_result_spec_end
- };
-
- return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "call_deposit",
- params,
- rs);
-}
-
-
-/**
- * Perform melt operation, checking for sufficient balance
- * of the coin and possibly persisting the melt details.
- *
- * @param cls the `struct PostgresClosure` with the plugin-specific state
- * @param rms client-contributed input for CS denominations that must be checked for idempotency, or NULL for non-CS withdrawals
- * @param[in,out] refresh refresh operation details; the noreveal_index
- * is set in case the coin was already melted before
- * @param known_coin_id row of the coin in the known_coins table
- * @param[in,out] zombie_required true if the melt must only succeed if the coin is a zombie, set to false if the requirement was satisfied
- * @param[out] balance_ok set to true if the balance was sufficient
- * @return query execution status
- */
-static enum GNUNET_DB_QueryStatus
-postgres_do_melt (
- void *cls,
- const struct TALER_RefreshMasterSecretP *rms,
- struct TALER_EXCHANGEDB_Refresh *refresh,
- uint64_t known_coin_id,
- bool *zombie_required,
- bool *balance_ok)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- NULL == rms
- ? GNUNET_PQ_query_param_null ()
- : GNUNET_PQ_query_param_auto_from_type (rms),
- TALER_PQ_query_param_amount (&refresh->amount_with_fee),
- GNUNET_PQ_query_param_auto_from_type (&refresh->rc),
- GNUNET_PQ_query_param_auto_from_type (&refresh->coin.coin_pub),
- GNUNET_PQ_query_param_auto_from_type (&refresh->coin_sig),
- GNUNET_PQ_query_param_uint64 (&known_coin_id),
- GNUNET_PQ_query_param_uint32 (&refresh->noreveal_index),
- GNUNET_PQ_query_param_bool (*zombie_required),
- GNUNET_PQ_query_param_end
- };
- bool is_null;
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_bool ("balance_ok",
- balance_ok),
- GNUNET_PQ_result_spec_bool ("zombie_required",
- zombie_required),
- GNUNET_PQ_result_spec_allow_null (
- GNUNET_PQ_result_spec_uint32 ("noreveal_index",
- &refresh->noreveal_index),
- &is_null),
- GNUNET_PQ_result_spec_end
- };
- enum GNUNET_DB_QueryStatus qs;
-
- qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "call_melt",
- params,
- rs);
- if (is_null)
- refresh->noreveal_index = UINT32_MAX; /* set to very invalid value */
- return qs;
-}
-
-
-/**
- * Perform refund operation, checking for sufficient deposits
- * of the coin and possibly persisting the refund details.
- *
- * @param cls the `struct PostgresClosure` with the plugin-specific state
- * @param refund refund operation details
- * @param deposit_fee deposit fee applicable for the coin, possibly refunded
- * @param known_coin_id row of the coin in the known_coins table
- * @param[out] not_found set if the deposit was not found
- * @param[out] refund_ok set if the refund succeeded (below deposit amount)
- * @param[out] gone if the merchant was already paid
- * @param[out] conflict set if the refund ID was re-used
- * @return query execution status
- */
-static enum GNUNET_DB_QueryStatus
-postgres_do_refund (
- void *cls,
- const struct TALER_EXCHANGEDB_Refund *refund,
- const struct TALER_Amount *deposit_fee,
- uint64_t known_coin_id,
- bool *not_found,
- bool *refund_ok,
- bool *gone,
- bool *conflict)
-{
- struct PostgresClosure *pg = cls;
- uint64_t deposit_shard = compute_shard (&refund->details.merchant_pub);
- struct TALER_Amount amount_without_fee;
- struct GNUNET_PQ_QueryParam params[] = {
- TALER_PQ_query_param_amount (&refund->details.refund_amount),
- TALER_PQ_query_param_amount (&amount_without_fee),
- TALER_PQ_query_param_amount (deposit_fee),
- GNUNET_PQ_query_param_auto_from_type (&refund->details.h_contract_terms),
- GNUNET_PQ_query_param_uint64 (&refund->details.rtransaction_id),
- GNUNET_PQ_query_param_uint64 (&deposit_shard),
- GNUNET_PQ_query_param_uint64 (&known_coin_id),
- GNUNET_PQ_query_param_auto_from_type (&refund->coin.coin_pub),
- GNUNET_PQ_query_param_auto_from_type (&refund->details.merchant_pub),
- GNUNET_PQ_query_param_auto_from_type (&refund->details.merchant_sig),
- GNUNET_PQ_query_param_end
- };
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_bool ("not_found",
- not_found),
- GNUNET_PQ_result_spec_bool ("refund_ok",
- refund_ok),
- GNUNET_PQ_result_spec_bool ("gone",
- gone),
- GNUNET_PQ_result_spec_bool ("conflict",
- conflict),
- GNUNET_PQ_result_spec_end
- };
-
- if (0 >
- TALER_amount_subtract (&amount_without_fee,
- &refund->details.refund_amount,
- &refund->details.refund_fee))
- {
- GNUNET_break (0);
- return GNUNET_DB_STATUS_HARD_ERROR;
- }
- return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "call_refund",
- params,
- rs);
-}
-
-
-/**
- * Perform recoup operation, checking for sufficient deposits
- * of the coin and possibly persisting the recoup details.
- *
- * @param cls the `struct PostgresClosure` with the plugin-specific state
- * @param reserve_pub public key of the reserve to credit
- * @param reserve_out_serial_id row in the reserves_out table justifying the recoup
- * @param coin_bks coin blinding key secret to persist
- * @param coin_pub public key of the coin being recouped
- * @param known_coin_id row of the @a coin_pub in the known_coins table
- * @param coin_sig signature of the coin requesting the recoup
- * @param[in,out] recoup_timestamp recoup timestamp, set if recoup existed
- * @param[out] recoup_ok set if the recoup succeeded (balance ok)
- * @param[out] internal_failure set on internal failures
- * @return query execution status
- */
-static enum GNUNET_DB_QueryStatus
-postgres_do_recoup (
- void *cls,
- const struct TALER_ReservePublicKeyP *reserve_pub,
- uint64_t reserve_out_serial_id,
- const union TALER_DenominationBlindingKeyP *coin_bks,
- const struct TALER_CoinSpendPublicKeyP *coin_pub,
- uint64_t known_coin_id,
- const struct TALER_CoinSpendSignatureP *coin_sig,
- struct GNUNET_TIME_Timestamp *recoup_timestamp,
- bool *recoup_ok,
- bool *internal_failure)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_TIME_Timestamp reserve_gc
- = GNUNET_TIME_relative_to_timestamp (pg->legal_reserve_expiration_time);
- struct GNUNET_TIME_Timestamp reserve_expiration
- = GNUNET_TIME_relative_to_timestamp (pg->idle_reserve_expiration_time);
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (reserve_pub),
- GNUNET_PQ_query_param_uint64 (&reserve_out_serial_id),
- GNUNET_PQ_query_param_auto_from_type (coin_bks),
- GNUNET_PQ_query_param_auto_from_type (coin_pub),
- GNUNET_PQ_query_param_uint64 (&known_coin_id),
- GNUNET_PQ_query_param_auto_from_type (coin_sig),
- GNUNET_PQ_query_param_timestamp (&reserve_gc),
- GNUNET_PQ_query_param_timestamp (&reserve_expiration),
- GNUNET_PQ_query_param_timestamp (recoup_timestamp),
- GNUNET_PQ_query_param_end
- };
- bool is_null;
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_allow_null (
- GNUNET_PQ_result_spec_timestamp ("recoup_timestamp",
- recoup_timestamp),
- &is_null),
- GNUNET_PQ_result_spec_bool ("recoup_ok",
- recoup_ok),
- GNUNET_PQ_result_spec_bool ("internal_failure",
- internal_failure),
- GNUNET_PQ_result_spec_end
- };
-
- return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "call_recoup",
- params,
- rs);
-}
-
-
-/**
- * Perform recoup-refresh operation, checking for sufficient deposits of the
- * coin and possibly persisting the recoup-refresh details.
- *
- * @param cls the `struct PostgresClosure` with the plugin-specific state
- * @param old_coin_pub public key of the old coin to credit
- * @param rrc_serial row in the refresh_revealed_coins table justifying the recoup-refresh
- * @param coin_bks coin blinding key secret to persist
- * @param coin_pub public key of the coin being recouped
- * @param known_coin_id row of the @a coin_pub in the known_coins table
- * @param coin_sig signature of the coin requesting the recoup
- * @param[in,out] recoup_timestamp recoup timestamp, set if recoup existed
- * @param[out] recoup_ok set if the recoup-refresh succeeded (balance ok)
- * @param[out] internal_failure set on internal failures
- * @return query execution status
- */
-static enum GNUNET_DB_QueryStatus
-postgres_do_recoup_refresh (
- void *cls,
- const struct TALER_CoinSpendPublicKeyP *old_coin_pub,
- uint64_t rrc_serial,
- const union TALER_DenominationBlindingKeyP *coin_bks,
- const struct TALER_CoinSpendPublicKeyP *coin_pub,
- uint64_t known_coin_id,
- const struct TALER_CoinSpendSignatureP *coin_sig,
- struct GNUNET_TIME_Timestamp *recoup_timestamp,
- bool *recoup_ok,
- bool *internal_failure)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (old_coin_pub),
- GNUNET_PQ_query_param_uint64 (&rrc_serial),
- GNUNET_PQ_query_param_auto_from_type (coin_bks),
- GNUNET_PQ_query_param_auto_from_type (coin_pub),
- GNUNET_PQ_query_param_uint64 (&known_coin_id),
- GNUNET_PQ_query_param_auto_from_type (coin_sig),
- GNUNET_PQ_query_param_timestamp (recoup_timestamp),
- GNUNET_PQ_query_param_end
- };
- bool is_null;
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_allow_null (
- GNUNET_PQ_result_spec_timestamp ("recoup_timestamp",
- recoup_timestamp),
- &is_null),
- GNUNET_PQ_result_spec_bool ("recoup_ok",
- recoup_ok),
- GNUNET_PQ_result_spec_bool ("internal_failure",
- internal_failure),
- GNUNET_PQ_result_spec_end
- };
-
- return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "call_recoup_refresh",
- params,
- rs);
-}
-
-
-/**
- * Closure for callbacks invoked via #postgres_get_reserve_history.
- */
-struct ReserveHistoryContext
-{
-
- /**
- * Which reserve are we building the history for?
- */
- const struct TALER_ReservePublicKeyP *reserve_pub;
-
- /**
- * Where we build the history.
- */
- struct TALER_EXCHANGEDB_ReserveHistory *rh;
-
- /**
- * Tail of @e rh list.
- */
- struct TALER_EXCHANGEDB_ReserveHistory *rh_tail;
-
- /**
- * Plugin context.
- */
- struct PostgresClosure *pg;
-
- /**
- * Sum of all credit transactions.
- */
- struct TALER_Amount balance_in;
-
- /**
- * Sum of all debit transactions.
- */
- struct TALER_Amount balance_out;
-
- /**
- * Set to #GNUNET_SYSERR on serious internal errors during
- * the callbacks.
- */
- enum GNUNET_GenericReturnValue status;
-};
-
-
-/**
- * Append and return a fresh element to the reserve
- * history kept in @a rhc.
- *
- * @param rhc where the history is kept
- * @return the fresh element that was added
- */
-static struct TALER_EXCHANGEDB_ReserveHistory *
-append_rh (struct ReserveHistoryContext *rhc)
-{
- struct TALER_EXCHANGEDB_ReserveHistory *tail;
-
- tail = GNUNET_new (struct TALER_EXCHANGEDB_ReserveHistory);
- if (NULL != rhc->rh_tail)
- {
- rhc->rh_tail->next = tail;
- rhc->rh_tail = tail;
- }
- else
- {
- rhc->rh_tail = tail;
- rhc->rh = tail;
- }
- return tail;
-}
-
-
-/**
- * Add bank transfers to result set for #postgres_get_reserve_history.
- *
- * @param cls a `struct ReserveHistoryContext *`
- * @param result SQL result
- * @param num_results number of rows in @a result
- */
-static void
-add_bank_to_exchange (void *cls,
- PGresult *result,
- unsigned int num_results)
-{
- struct ReserveHistoryContext *rhc = cls;
- struct PostgresClosure *pg = rhc->pg;
-
- while (0 < num_results)
- {
- struct TALER_EXCHANGEDB_BankTransfer *bt;
- struct TALER_EXCHANGEDB_ReserveHistory *tail;
-
- bt = GNUNET_new (struct TALER_EXCHANGEDB_BankTransfer);
- {
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_uint64 ("wire_reference",
- &bt->wire_reference),
- TALER_PQ_RESULT_SPEC_AMOUNT ("credit",
- &bt->amount),
- GNUNET_PQ_result_spec_timestamp ("execution_date",
- &bt->execution_date),
- GNUNET_PQ_result_spec_string ("sender_account_details",
- &bt->sender_account_details),
- GNUNET_PQ_result_spec_end
- };
-
- if (GNUNET_OK !=
- GNUNET_PQ_extract_result (result,
- rs,
- --num_results))
- {
- GNUNET_break (0);
- GNUNET_free (bt);
- rhc->status = GNUNET_SYSERR;
- return;
- }
- }
- GNUNET_assert (0 <=
- TALER_amount_add (&rhc->balance_in,
- &rhc->balance_in,
- &bt->amount));
- bt->reserve_pub = *rhc->reserve_pub;
- tail = append_rh (rhc);
- tail->type = TALER_EXCHANGEDB_RO_BANK_TO_EXCHANGE;
- tail->details.bank = bt;
- } /* end of 'while (0 < rows)' */
-}
-
-
-/**
- * Add coin withdrawals to result set for #postgres_get_reserve_history.
- *
- * @param cls a `struct ReserveHistoryContext *`
- * @param result SQL result
- * @param num_results number of rows in @a result
- */
-static void
-add_withdraw_coin (void *cls,
- PGresult *result,
- unsigned int num_results)
-{
- struct ReserveHistoryContext *rhc = cls;
- struct PostgresClosure *pg = rhc->pg;
-
- while (0 < num_results)
- {
- struct TALER_EXCHANGEDB_CollectableBlindcoin *cbc;
- struct TALER_EXCHANGEDB_ReserveHistory *tail;
-
- cbc = GNUNET_new (struct TALER_EXCHANGEDB_CollectableBlindcoin);
- {
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_auto_from_type ("h_blind_ev",
- &cbc->h_coin_envelope),
- GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash",
- &cbc->denom_pub_hash),
- TALER_PQ_result_spec_blinded_denom_sig ("denom_sig",
- &cbc->sig),
- GNUNET_PQ_result_spec_auto_from_type ("reserve_sig",
- &cbc->reserve_sig),
- TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee",
- &cbc->amount_with_fee),
- TALER_PQ_RESULT_SPEC_AMOUNT ("fee_withdraw",
- &cbc->withdraw_fee),
- GNUNET_PQ_result_spec_end
- };
-
- if (GNUNET_OK !=
- GNUNET_PQ_extract_result (result,
- rs,
- --num_results))
- {
- GNUNET_break (0);
- GNUNET_free (cbc);
- rhc->status = GNUNET_SYSERR;
- return;
- }
- }
- GNUNET_assert (0 <=
- TALER_amount_add (&rhc->balance_out,
- &rhc->balance_out,
- &cbc->amount_with_fee));
- cbc->reserve_pub = *rhc->reserve_pub;
- tail = append_rh (rhc);
- tail->type = TALER_EXCHANGEDB_RO_WITHDRAW_COIN;
- tail->details.withdraw = cbc;
- }
-}
-
-
-/**
- * Add recoups to result set for #postgres_get_reserve_history.
- *
- * @param cls a `struct ReserveHistoryContext *`
- * @param result SQL result
- * @param num_results number of rows in @a result
- */
-static void
-add_recoup (void *cls,
- PGresult *result,
- unsigned int num_results)
-{
- struct ReserveHistoryContext *rhc = cls;
- struct PostgresClosure *pg = rhc->pg;
-
- while (0 < num_results)
- {
- struct TALER_EXCHANGEDB_Recoup *recoup;
- struct TALER_EXCHANGEDB_ReserveHistory *tail;
-
- recoup = GNUNET_new (struct TALER_EXCHANGEDB_Recoup);
- {
- struct GNUNET_PQ_ResultSpec rs[] = {
- TALER_PQ_RESULT_SPEC_AMOUNT ("amount",
- &recoup->value),
- GNUNET_PQ_result_spec_auto_from_type ("coin_pub",
- &recoup->coin.coin_pub),
- GNUNET_PQ_result_spec_auto_from_type ("coin_blind",
- &recoup->coin_blind),
- GNUNET_PQ_result_spec_auto_from_type ("coin_sig",
- &recoup->coin_sig),
- GNUNET_PQ_result_spec_timestamp ("recoup_timestamp",
- &recoup->timestamp),
- GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash",
- &recoup->coin.denom_pub_hash),
- TALER_PQ_result_spec_denom_sig (
- "denom_sig",
- &recoup->coin.denom_sig),
- GNUNET_PQ_result_spec_end
- };
-
- if (GNUNET_OK !=
- GNUNET_PQ_extract_result (result,
- rs,
- --num_results))
- {
- GNUNET_break (0);
- GNUNET_free (recoup);
- rhc->status = GNUNET_SYSERR;
- return;
- }
- }
- GNUNET_assert (0 <=
- TALER_amount_add (&rhc->balance_in,
- &rhc->balance_in,
- &recoup->value));
- recoup->reserve_pub = *rhc->reserve_pub;
- tail = append_rh (rhc);
- tail->type = TALER_EXCHANGEDB_RO_RECOUP_COIN;
- tail->details.recoup = recoup;
- } /* end of 'while (0 < rows)' */
-}
-
-
-/**
- * Add exchange-to-bank transfers to result set for
- * #postgres_get_reserve_history.
- *
- * @param cls a `struct ReserveHistoryContext *`
- * @param result SQL result
- * @param num_results number of rows in @a result
- */
-static void
-add_exchange_to_bank (void *cls,
- PGresult *result,
- unsigned int num_results)
-{
- struct ReserveHistoryContext *rhc = cls;
- struct PostgresClosure *pg = rhc->pg;
-
- while (0 < num_results)
- {
- struct TALER_EXCHANGEDB_ClosingTransfer *closing;
- struct TALER_EXCHANGEDB_ReserveHistory *tail;
-
- closing = GNUNET_new (struct TALER_EXCHANGEDB_ClosingTransfer);
- {
- struct GNUNET_PQ_ResultSpec rs[] = {
- TALER_PQ_RESULT_SPEC_AMOUNT ("amount",
- &closing->amount),
- TALER_PQ_RESULT_SPEC_AMOUNT ("closing_fee",
- &closing->closing_fee),
- GNUNET_PQ_result_spec_timestamp ("execution_date",
- &closing->execution_date),
- GNUNET_PQ_result_spec_string ("receiver_account",
- &closing->receiver_account_details),
- GNUNET_PQ_result_spec_auto_from_type ("wtid",
- &closing->wtid),
- GNUNET_PQ_result_spec_end
- };
-
- if (GNUNET_OK !=
- GNUNET_PQ_extract_result (result,
- rs,
- --num_results))
- {
- GNUNET_break (0);
- GNUNET_free (closing);
- rhc->status = GNUNET_SYSERR;
- return;
- }
- }
- GNUNET_assert (0 <=
- TALER_amount_add (&rhc->balance_out,
- &rhc->balance_out,
- &closing->amount));
- closing->reserve_pub = *rhc->reserve_pub;
- tail = append_rh (rhc);
- tail->type = TALER_EXCHANGEDB_RO_EXCHANGE_TO_BANK;
- tail->details.closing = closing;
- } /* end of 'while (0 < rows)' */
-}
-
-
-/**
- * Add purse merge transfers to result set for
- * #postgres_get_reserve_history.
- *
- * @param cls a `struct ReserveHistoryContext *`
- * @param result SQL result
- * @param num_results number of rows in @a result
- */
-static void
-add_p2p_merge (void *cls,
- PGresult *result,
- unsigned int num_results)
-{
- struct ReserveHistoryContext *rhc = cls;
- struct PostgresClosure *pg = rhc->pg;
-
- while (0 < num_results)
- {
- struct TALER_EXCHANGEDB_PurseMerge *merge;
- struct TALER_EXCHANGEDB_ReserveHistory *tail;
-
- merge = GNUNET_new (struct TALER_EXCHANGEDB_PurseMerge);
- {
- uint32_t flags32;
- struct TALER_Amount balance;
- struct GNUNET_PQ_ResultSpec rs[] = {
- TALER_PQ_RESULT_SPEC_AMOUNT ("purse_fee",
- &merge->purse_fee),
- TALER_PQ_RESULT_SPEC_AMOUNT ("balance",
- &balance),
- TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee",
- &merge->amount_with_fee),
- GNUNET_PQ_result_spec_timestamp ("merge_timestamp",
- &merge->merge_timestamp),
- GNUNET_PQ_result_spec_timestamp ("purse_expiration",
- &merge->purse_expiration),
- GNUNET_PQ_result_spec_uint32 ("age_limit",
- &merge->min_age),
- GNUNET_PQ_result_spec_uint32 ("flags",
- &flags32),
- GNUNET_PQ_result_spec_auto_from_type ("h_contract_terms",
- &merge->h_contract_terms),
- GNUNET_PQ_result_spec_auto_from_type ("merge_pub",
- &merge->merge_pub),
- GNUNET_PQ_result_spec_auto_from_type ("purse_pub",
- &merge->purse_pub),
- GNUNET_PQ_result_spec_auto_from_type ("reserve_sig",
- &merge->reserve_sig),
- GNUNET_PQ_result_spec_end
- };
-
- if (GNUNET_OK !=
- GNUNET_PQ_extract_result (result,
- rs,
- --num_results))
- {
- GNUNET_break (0);
- GNUNET_free (merge);
- rhc->status = GNUNET_SYSERR;
- return;
- }
- merge->flags = (enum TALER_WalletAccountMergeFlags) flags32;
- if ( (! GNUNET_TIME_absolute_is_future (
- merge->merge_timestamp.abs_time)) &&
- (-1 != TALER_amount_cmp (&balance,
- &merge->amount_with_fee)) )
- merge->merged = true;
- }
- if (merge->merged)
- GNUNET_assert (0 <=
- TALER_amount_add (&rhc->balance_in,
- &rhc->balance_in,
- &merge->amount_with_fee));
- GNUNET_assert (0 <=
- TALER_amount_add (&rhc->balance_out,
- &rhc->balance_out,
- &merge->purse_fee));
- merge->reserve_pub = *rhc->reserve_pub;
- tail = append_rh (rhc);
- tail->type = TALER_EXCHANGEDB_RO_PURSE_MERGE;
- tail->details.merge = merge;
- }
-}
-
-
-/**
- * Add paid for history requests to result set for
- * #postgres_get_reserve_history.
- *
- * @param cls a `struct ReserveHistoryContext *`
- * @param result SQL result
- * @param num_results number of rows in @a result
- */
-static void
-add_history_requests (void *cls,
- PGresult *result,
- unsigned int num_results)
-{
- struct ReserveHistoryContext *rhc = cls;
- struct PostgresClosure *pg = rhc->pg;
-
- while (0 < num_results)
- {
- struct TALER_EXCHANGEDB_HistoryRequest *history;
- struct TALER_EXCHANGEDB_ReserveHistory *tail;
-
- history = GNUNET_new (struct TALER_EXCHANGEDB_HistoryRequest);
- {
- struct GNUNET_PQ_ResultSpec rs[] = {
- TALER_PQ_RESULT_SPEC_AMOUNT ("history_fee",
- &history->history_fee),
- GNUNET_PQ_result_spec_timestamp ("request_timestamp",
- &history->request_timestamp),
- GNUNET_PQ_result_spec_auto_from_type ("reserve_sig",
- &history->reserve_sig),
- GNUNET_PQ_result_spec_end
- };
-
- if (GNUNET_OK !=
- GNUNET_PQ_extract_result (result,
- rs,
- --num_results))
- {
- GNUNET_break (0);
- GNUNET_free (history);
- rhc->status = GNUNET_SYSERR;
- return;
- }
- }
- GNUNET_assert (0 <=
- TALER_amount_add (&rhc->balance_out,
- &rhc->balance_out,
- &history->history_fee));
- history->reserve_pub = *rhc->reserve_pub;
- tail = append_rh (rhc);
- tail->type = TALER_EXCHANGEDB_RO_HISTORY_REQUEST;
- tail->details.history = history;
- }
-}
-
-
-/**
- * Get all of the transaction history associated with the specified
- * reserve.
- *
- * @param cls the `struct PostgresClosure` with the plugin-specific state
- * @param reserve_pub public key of the reserve
- * @param[out] balance set to the reserve balance
- * @param[out] rhp set to known transaction history (NULL if reserve is unknown)
- * @return transaction status
- */
-static enum GNUNET_DB_QueryStatus
-postgres_get_reserve_history (void *cls,
- const struct TALER_ReservePublicKeyP *reserve_pub,
- struct TALER_Amount *balance,
- struct TALER_EXCHANGEDB_ReserveHistory **rhp)
-{
- struct PostgresClosure *pg = cls;
- struct ReserveHistoryContext rhc;
- struct
- {
- /**
- * Name of the prepared statement to run.
- */
- const char *statement;
- /**
- * Function to use to process the results.
- */
- GNUNET_PQ_PostgresResultHandler cb;
- } work[] = {
- /** #TALER_EXCHANGEDB_RO_BANK_TO_EXCHANGE */
- { "reserves_in_get_transactions",
- add_bank_to_exchange },
- /** #TALER_EXCHANGEDB_RO_WITHDRAW_COIN */
- { "get_reserves_out",
- &add_withdraw_coin },
- /** #TALER_EXCHANGEDB_RO_RECOUP_COIN */
- { "recoup_by_reserve",
- &add_recoup },
- /** #TALER_EXCHANGEDB_RO_EXCHANGE_TO_BANK */
- { "close_by_reserve",
- &add_exchange_to_bank },
- /** #TALER_EXCHANGEDB_RO_PURSE_MERGE */
- { "merge_by_reserve",
- &add_p2p_merge },
- /** #TALER_EXCHANGEDB_RO_HISTORY_REQUEST */
- { "history_by_reserve",
- &add_history_requests },
- /* List terminator */
- { NULL,
- NULL }
- };
- enum GNUNET_DB_QueryStatus qs;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (reserve_pub),
- GNUNET_PQ_query_param_end
- };
-
- rhc.reserve_pub = reserve_pub;
- rhc.rh = NULL;
- rhc.rh_tail = NULL;
- rhc.pg = pg;
- rhc.status = GNUNET_OK;
- GNUNET_assert (GNUNET_OK ==
- TALER_amount_set_zero (pg->currency,
- &rhc.balance_in));
- GNUNET_assert (GNUNET_OK ==
- TALER_amount_set_zero (pg->currency,
- &rhc.balance_out));
- qs = GNUNET_DB_STATUS_SUCCESS_NO_RESULTS; /* make static analysis happy */
- for (unsigned int i = 0; NULL != work[i].cb; i++)
- {
- qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
- work[i].statement,
- params,
- work[i].cb,
- &rhc);
- if ( (0 > qs) ||
- (GNUNET_OK != rhc.status) )
- break;
- }
- if ( (qs < 0) ||
- (rhc.status != GNUNET_OK) )
- {
- common_free_reserve_history (cls,
- rhc.rh);
- rhc.rh = NULL;
- if (qs >= 0)
- {
- /* status == SYSERR is a very hard error... */
- qs = GNUNET_DB_STATUS_HARD_ERROR;
- }
- }
- *rhp = rhc.rh;
- GNUNET_assert (0 <=
- TALER_amount_subtract (balance,
- &rhc.balance_in,
- &rhc.balance_out));
- return qs;
-}
-
-
-/**
- * Get a truncated transaction history associated with the specified
- * reserve.
- *
- * @param cls the `struct PostgresClosure` with the plugin-specific state
- * @param reserve_pub public key of the reserve
- * @param[out] balance set to the reserve balance
- * @param[out] rhp set to known transaction history (NULL if reserve is unknown)
- * @return transaction status
- */
-static enum GNUNET_DB_QueryStatus
-postgres_get_reserve_status (void *cls,
- const struct TALER_ReservePublicKeyP *reserve_pub,
- struct TALER_Amount *balance,
- struct TALER_EXCHANGEDB_ReserveHistory **rhp)
-{
- struct PostgresClosure *pg = cls;
- struct ReserveHistoryContext rhc;
- struct
- {
- /**
- * Name of the prepared statement to run.
- */
- const char *statement;
- /**
- * Function to use to process the results.
- */
- GNUNET_PQ_PostgresResultHandler cb;
- } work[] = {
- /** #TALER_EXCHANGEDB_RO_BANK_TO_EXCHANGE */
- { "reserves_in_get_transactions",
- add_bank_to_exchange },
- /** #TALER_EXCHANGEDB_RO_WITHDRAW_COIN */
- { "get_reserves_out",
- &add_withdraw_coin },
- /** #TALER_EXCHANGEDB_RO_RECOUP_COIN */
- { "recoup_by_reserve",
- &add_recoup },
- /** #TALER_EXCHANGEDB_RO_EXCHANGE_TO_BANK */
- { "close_by_reserve",
- &add_exchange_to_bank },
- /** #TALER_EXCHANGEDB_RO_PURSE_MERGE */
- { "merge_by_reserve",
- &add_p2p_merge },
- /** #TALER_EXCHANGEDB_RO_HISTORY_REQUEST */
- { "history_by_reserve",
- &add_history_requests },
- /* List terminator */
- { NULL,
- NULL }
- };
- enum GNUNET_DB_QueryStatus qs;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (reserve_pub),
- GNUNET_PQ_query_param_end
- };
-
- /* FIXME: actually implement reserve history truncation logic! */
- rhc.reserve_pub = reserve_pub;
- rhc.rh = NULL;
- rhc.rh_tail = NULL;
- rhc.pg = pg;
- rhc.status = GNUNET_OK;
- GNUNET_assert (GNUNET_OK ==
- TALER_amount_set_zero (pg->currency,
- &rhc.balance_in));
- GNUNET_assert (GNUNET_OK ==
- TALER_amount_set_zero (pg->currency,
- &rhc.balance_out));
- qs = GNUNET_DB_STATUS_SUCCESS_NO_RESULTS; /* make static analysis happy */
- for (unsigned int i = 0; NULL != work[i].cb; i++)
- {
- qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
- work[i].statement,
- params,
- work[i].cb,
- &rhc);
- if ( (0 > qs) ||
- (GNUNET_OK != rhc.status) )
- break;
- }
- if ( (qs < 0) ||
- (rhc.status != GNUNET_OK) )
- {
- common_free_reserve_history (cls,
- rhc.rh);
- rhc.rh = NULL;
- if (qs >= 0)
- {
- /* status == SYSERR is a very hard error... */
- qs = GNUNET_DB_STATUS_HARD_ERROR;
- }
- }
- *rhp = rhc.rh;
- GNUNET_assert (0 <=
- TALER_amount_subtract (balance,
- &rhc.balance_in,
- &rhc.balance_out));
- return qs;
-}
-
-
-/**
- * Get the balance of the specified reserve.
- *
- * @param cls the `struct PostgresClosure` with the plugin-specific state
- * @param reserve_pub public key of the reserve
- * @param[out] balance set to the reserve balance
- * @return transaction status
- */
-static enum GNUNET_DB_QueryStatus
-postgres_get_reserve_balance (void *cls,
- const struct TALER_ReservePublicKeyP *reserve_pub,
- struct TALER_Amount *balance)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (reserve_pub),
- GNUNET_PQ_query_param_end
- };
- struct GNUNET_PQ_ResultSpec rs[] = {
- TALER_PQ_RESULT_SPEC_AMOUNT ("current_balance",
- balance),
- GNUNET_PQ_result_spec_end
- };
-
- return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "get_reserve_balance",
- params,
- rs);
-}
-
-
-/**
- * Check if we have the specified deposit already in the database.
- *
- * @param cls the `struct PostgresClosure` with the plugin-specific state
- * @param h_contract_terms contract to check for
- * @param h_wire wire hash to check for
- * @param coin_pub public key of the coin to check for
- * @param merchant merchant public key to check for
- * @param refund_deadline expected refund deadline
- * @param[out] deposit_fee set to the deposit fee the exchange charged
- * @param[out] exchange_timestamp set to the time when the exchange received the deposit
- * @return 1 if we know this operation,
- * 0 if this exact deposit is unknown to us,
- * otherwise transaction error status
- */
-static enum GNUNET_DB_QueryStatus
-postgres_have_deposit2 (
- void *cls,
- const struct TALER_PrivateContractHashP *h_contract_terms,
- const struct TALER_MerchantWireHashP *h_wire,
- const struct TALER_CoinSpendPublicKeyP *coin_pub,
- const struct TALER_MerchantPublicKeyP *merchant,
- struct GNUNET_TIME_Timestamp refund_deadline,
- struct TALER_Amount *deposit_fee,
- struct GNUNET_TIME_Timestamp *exchange_timestamp)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (coin_pub),
- GNUNET_PQ_query_param_auto_from_type (h_contract_terms),
- GNUNET_PQ_query_param_auto_from_type (merchant),
- GNUNET_PQ_query_param_end
- };
- struct TALER_EXCHANGEDB_Deposit deposit2;
- struct GNUNET_PQ_ResultSpec rs[] = {
- TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee",
- &deposit2.amount_with_fee),
- GNUNET_PQ_result_spec_timestamp ("wallet_timestamp",
- &deposit2.timestamp),
- GNUNET_PQ_result_spec_timestamp ("exchange_timestamp",
- exchange_timestamp),
- GNUNET_PQ_result_spec_timestamp ("refund_deadline",
- &deposit2.refund_deadline),
- GNUNET_PQ_result_spec_timestamp ("wire_deadline",
- &deposit2.wire_deadline),
- TALER_PQ_RESULT_SPEC_AMOUNT ("fee_deposit",
- deposit_fee),
- GNUNET_PQ_result_spec_auto_from_type ("wire_salt",
- &deposit2.wire_salt),
- GNUNET_PQ_result_spec_string ("receiver_wire_account",
- &deposit2.receiver_wire_account),
- GNUNET_PQ_result_spec_end
- };
- enum GNUNET_DB_QueryStatus qs;
- struct TALER_MerchantWireHashP h_wire2;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Getting deposits for coin %s\n",
- TALER_B2S (coin_pub));
- qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "get_deposit",
- params,
- rs);
- if (0 >= qs)
- return qs;
- TALER_merchant_wire_signature_hash (deposit2.receiver_wire_account,
- &deposit2.wire_salt,
- &h_wire2);
- GNUNET_free (deposit2.receiver_wire_account);
- /* Now we check that the other information in @a deposit
- also matches, and if not report inconsistencies. */
- if ( (GNUNET_TIME_timestamp_cmp (refund_deadline,
- !=,
- deposit2.refund_deadline)) ||
- (0 != GNUNET_memcmp (h_wire,
- &h_wire2) ) )
- {
- /* Inconsistencies detected! Does not match! (We might want to
- expand the API with a 'get_deposit' function to return the
- original transaction details to be used for an error message
- in the future!) FIXME #3838 */
- return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS;
- }
- return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
-}
-
-
-/**
- * Aggregate all matching deposits for @a h_payto and
- * @a merchant_pub, returning the total amounts.
- *
- * @param cls the @e cls of this struct with the plugin-specific state
- * @param h_payto destination of the wire transfer
- * @param merchant_pub public key of the merchant
- * @param wtid wire transfer ID to set for the aggregate
- * @param[out] total set to the sum of the total deposits minus applicable deposit fees and refunds
- * @return transaction status
- */
-static enum GNUNET_DB_QueryStatus
-postgres_aggregate (
- void *cls,
- const struct TALER_PaytoHashP *h_payto,
- const struct TALER_MerchantPublicKeyP *merchant_pub,
- const struct TALER_WireTransferIdentifierRawP *wtid,
- struct TALER_Amount *total)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_TIME_Absolute now = {0};
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_absolute_time (&now),
- GNUNET_PQ_query_param_auto_from_type (merchant_pub),
- GNUNET_PQ_query_param_auto_from_type (h_payto),
- GNUNET_PQ_query_param_auto_from_type (wtid),
- GNUNET_PQ_query_param_end
- };
- uint64_t sum_deposit_value;
- uint64_t sum_deposit_frac;
- uint64_t sum_refund_value;
- uint64_t sum_refund_frac;
- uint64_t sum_fee_value;
- uint64_t sum_fee_frac;
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_uint64 ("sum_deposit_value",
- &sum_deposit_value),
- GNUNET_PQ_result_spec_uint64 ("sum_deposit_fraction",
- &sum_deposit_frac),
- GNUNET_PQ_result_spec_uint64 ("sum_refund_value",
- &sum_refund_value),
- GNUNET_PQ_result_spec_uint64 ("sum_refund_fraction",
- &sum_refund_frac),
- GNUNET_PQ_result_spec_uint64 ("sum_fee_value",
- &sum_fee_value),
- GNUNET_PQ_result_spec_uint64 ("sum_fee_fraction",
- &sum_fee_frac),
- GNUNET_PQ_result_spec_end
- };
- enum GNUNET_DB_QueryStatus qs;
- struct TALER_Amount sum_deposit;
- struct TALER_Amount sum_refund;
- struct TALER_Amount sum_fee;
- struct TALER_Amount delta;
-
- now = GNUNET_TIME_absolute_round_down (GNUNET_TIME_absolute_get (),
- pg->aggregator_shift);
- qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "aggregate",
- params,
- rs);
- if (qs < 0)
- {
- GNUNET_assert (GNUNET_DB_STATUS_SOFT_ERROR == qs);
- return qs;
- }
- if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
- {
- GNUNET_assert (GNUNET_OK ==
- TALER_amount_set_zero (pg->currency,
- total));
- return qs;
- }
- GNUNET_assert (GNUNET_OK ==
- TALER_amount_set_zero (pg->currency,
- &sum_deposit));
- GNUNET_assert (GNUNET_OK ==
- TALER_amount_set_zero (pg->currency,
- &sum_refund));
- GNUNET_assert (GNUNET_OK ==
- TALER_amount_set_zero (pg->currency,
- &sum_fee));
- sum_deposit.value = sum_deposit_frac / TALER_AMOUNT_FRAC_BASE
- + sum_deposit_value;
- sum_deposit.fraction = sum_deposit_frac % TALER_AMOUNT_FRAC_BASE;
- sum_refund.value = sum_refund_frac / TALER_AMOUNT_FRAC_BASE
- + sum_refund_value;
- sum_refund.fraction = sum_refund_frac % TALER_AMOUNT_FRAC_BASE;
- sum_fee.value = sum_fee_frac / TALER_AMOUNT_FRAC_BASE
- + sum_fee_value;
- sum_fee.fraction = sum_fee_frac % TALER_AMOUNT_FRAC_BASE; \
- GNUNET_assert (0 <=
- TALER_amount_subtract (&delta,
- &sum_deposit,
- &sum_refund));
- GNUNET_assert (0 <=
- TALER_amount_subtract (total,
- &delta,
- &sum_fee));
- return qs;
-}
-
-
-/**
- * Create a new entry in the transient aggregation table.
- *
- * @param cls the @e cls of this struct with the plugin-specific state
- * @param h_payto destination of the wire transfer
- * @param exchange_account_section exchange account to use
- * @param wtid the raw wire transfer identifier to be used
- * @param total amount to be wired in the future
- * @return transaction status
- */
-static enum GNUNET_DB_QueryStatus
-postgres_create_aggregation_transient (
- void *cls,
- const struct TALER_PaytoHashP *h_payto,
- const char *exchange_account_section,
- const struct TALER_WireTransferIdentifierRawP *wtid,
- const struct TALER_Amount *total)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- TALER_PQ_query_param_amount (total),
- GNUNET_PQ_query_param_auto_from_type (h_payto),
- GNUNET_PQ_query_param_string (exchange_account_section),
- GNUNET_PQ_query_param_auto_from_type (wtid),
- GNUNET_PQ_query_param_end
- };
-
- return GNUNET_PQ_eval_prepared_non_select (pg->conn,
- "create_aggregation_transient",
- params);
-}
-
-
-/**
- * Find existing entry in the transient aggregation table.
- *
- * @param cls the @e cls of this struct with the plugin-specific state
- * @param h_payto destination of the wire transfer
- * @param exchange_account_section exchange account to use
- * @param[out] wtid set to the raw wire transfer identifier to be used
- * @param[out] total existing amount to be wired in the future
- * @return transaction status
- */
-static enum GNUNET_DB_QueryStatus
-postgres_select_aggregation_transient (
- void *cls,
- const struct TALER_PaytoHashP *h_payto,
- const char *exchange_account_section,
- struct TALER_WireTransferIdentifierRawP *wtid,
- struct TALER_Amount *total)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (h_payto),
- GNUNET_PQ_query_param_string (exchange_account_section),
- GNUNET_PQ_query_param_end
- };
- struct GNUNET_PQ_ResultSpec rs[] = {
- TALER_PQ_RESULT_SPEC_AMOUNT ("amount",
- total),
- GNUNET_PQ_result_spec_auto_from_type ("wtid_raw",
- wtid),
- GNUNET_PQ_result_spec_end
- };
-
- return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "select_aggregation_transient",
- params,
- rs);
-}
-
-
-/**
- * Update existing entry in the transient aggregation table.
- * @a h_payto is only needed for query performance.
- *
- * @param cls the @e cls of this struct with the plugin-specific state
- * @param h_payto destination of the wire transfer
- * @param wtid the raw wire transfer identifier to update
- * @param total new total amount to be wired in the future
- * @return transaction status
- */
-static enum GNUNET_DB_QueryStatus
-postgres_update_aggregation_transient (
- void *cls,
- const struct TALER_PaytoHashP *h_payto,
- const struct TALER_WireTransferIdentifierRawP *wtid,
- const struct TALER_Amount *total)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- TALER_PQ_query_param_amount (total),
- GNUNET_PQ_query_param_auto_from_type (h_payto),
- GNUNET_PQ_query_param_auto_from_type (wtid),
- GNUNET_PQ_query_param_end
- };
-
- return GNUNET_PQ_eval_prepared_non_select (pg->conn,
- "update_aggregation_transient",
- params);
-}
-
-
-/**
- * Delete existing entry in the transient aggregation table.
- * @a h_payto is only needed for query performance.
- *
- * @param cls the @e cls of this struct with the plugin-specific state
- * @param h_payto destination of the wire transfer
- * @param wtid the raw wire transfer identifier to update
- * @return transaction status
- */
-static enum GNUNET_DB_QueryStatus
-postgres_delete_aggregation_transient (
- void *cls,
- const struct TALER_PaytoHashP *h_payto,
- const struct TALER_WireTransferIdentifierRawP *wtid)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (h_payto),
- GNUNET_PQ_query_param_auto_from_type (wtid),
- GNUNET_PQ_query_param_end
- };
-
- return GNUNET_PQ_eval_prepared_non_select (pg->conn,
- "delete_aggregation_transient",
- params);
-}
-
-
-/**
- * Obtain information about deposits that are ready to be executed. Such
- * deposits must not be marked as "done", the execution time must be
- * in the past, and the KYC status must be 'ok'.
- *
- * @param cls the @e cls of this struct with the plugin-specific state
- * @param start_shard_row minimum shard row to select
- * @param end_shard_row maximum shard row to select (inclusive)
- * @param kyc_off true if we should not check the KYC status because
- * this exchange does not need/support KYC checks.
- * @param[out] merchant_pub set to the public key of a merchant with a ready deposit
- * @param[out] payto_uri set to the account of the merchant, to be freed by caller
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_get_ready_deposit (void *cls,
- uint64_t start_shard_row,
- uint64_t end_shard_row,
- bool kyc_off,
- struct TALER_MerchantPublicKeyP *merchant_pub,
- char **payto_uri)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_TIME_Absolute now = {0};
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_absolute_time (&now),
- GNUNET_PQ_query_param_uint64 (&start_shard_row),
- GNUNET_PQ_query_param_uint64 (&end_shard_row),
- GNUNET_PQ_query_param_bool (kyc_off),
- GNUNET_PQ_query_param_end
- };
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_auto_from_type ("merchant_pub",
- merchant_pub),
- GNUNET_PQ_result_spec_string ("payto_uri",
- payto_uri),
- GNUNET_PQ_result_spec_end
- };
-
- now = GNUNET_TIME_absolute_round_down (GNUNET_TIME_absolute_get (),
- pg->aggregator_shift);
- GNUNET_assert (start_shard_row < end_shard_row);
- GNUNET_assert (end_shard_row <= INT32_MAX);
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Finding ready deposits by deadline %s (%llu)\n",
- GNUNET_TIME_absolute2s (now),
- (unsigned long long) now.abs_value_us);
- return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "deposits_get_ready",
- params,
- rs);
-}
-
-
-/**
- * Retrieve the record for a known coin.
- *
- * @param cls the plugin closure
- * @param coin_pub the public key of the coin to search for
- * @param coin_info place holder for the returned coin information object
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_get_known_coin (void *cls,
- const struct TALER_CoinSpendPublicKeyP *coin_pub,
- struct TALER_CoinPublicInfo *coin_info)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (coin_pub),
- GNUNET_PQ_query_param_end
- };
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash",
- &coin_info->denom_pub_hash),
- GNUNET_PQ_result_spec_allow_null (
- GNUNET_PQ_result_spec_auto_from_type ("age_commitment_hash",
- &coin_info->h_age_commitment),
- &coin_info->no_age_commitment),
- TALER_PQ_result_spec_denom_sig ("denom_sig",
- &coin_info->denom_sig),
- GNUNET_PQ_result_spec_end
- };
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Getting known coin data for coin %s\n",
- TALER_B2S (coin_pub));
- coin_info->coin_pub = *coin_pub;
- return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "get_known_coin",
- params,
- rs);
-}
-
-
-/**
- * Retrieve the denomination of a known coin.
- *
- * @param cls the plugin closure
- * @param coin_pub the public key of the coin to search for
- * @param[out] known_coin_id set to the ID of the coin in the known_coins table
- * @param[out] denom_hash where to store the hash of the coins denomination
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_get_coin_denomination (
- void *cls,
- const struct TALER_CoinSpendPublicKeyP *coin_pub,
- uint64_t *known_coin_id,
- struct TALER_DenominationHashP *denom_hash)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (coin_pub),
- GNUNET_PQ_query_param_end
- };
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash",
- denom_hash),
- GNUNET_PQ_result_spec_uint64 ("known_coin_id",
- known_coin_id),
- GNUNET_PQ_result_spec_end
- };
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Getting coin denomination of coin %s\n",
- TALER_B2S (coin_pub));
- return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "get_coin_denomination",
- params,
- rs);
-}
-
-
-/**
- * Count the number of known coins by denomination.
- *
- * @param cls database connection plugin state
- * @param denom_pub_hash denomination to count by
- * @return number of coins if non-negative, otherwise an `enum GNUNET_DB_QueryStatus`
- */
-static long long
-postgres_count_known_coins (void *cls,
- const struct
- TALER_DenominationHashP *denom_pub_hash)
-{
- struct PostgresClosure *pg = cls;
- uint64_t count;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (denom_pub_hash),
- GNUNET_PQ_query_param_end
- };
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_uint64 ("count",
- &count),
- GNUNET_PQ_result_spec_end
- };
- enum GNUNET_DB_QueryStatus qs;
-
- qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "count_known_coins",
- params,
- rs);
- if (0 > qs)
- return (long long) qs;
- return (long long) count;
-}
-
-
-/**
- * Make sure the given @a coin is known to the database.
- *
- * @param cls database connection plugin state
- * @param coin the coin that must be made known
- * @param[out] known_coin_id set to the unique row of the coin
- * @param[out] denom_hash set to the denomination hash of the existing
- * coin (for conflict error reporting)
- * @param[out] h_age_commitment set to the conflicting age commitment hash on conflict
- * @return database transaction status, non-negative on success
- */
-static enum TALER_EXCHANGEDB_CoinKnownStatus
-postgres_ensure_coin_known (void *cls,
- const struct TALER_CoinPublicInfo *coin,
- uint64_t *known_coin_id,
- struct TALER_DenominationHashP *denom_hash,
- struct TALER_AgeCommitmentHash *h_age_commitment)
-{
- struct PostgresClosure *pg = cls;
- enum GNUNET_DB_QueryStatus qs;
- bool existed;
- bool is_denom_pub_hash_null = false;
- bool is_age_hash_null = false;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (&coin->coin_pub),
- GNUNET_PQ_query_param_auto_from_type (&coin->denom_pub_hash),
- GNUNET_PQ_query_param_auto_from_type (&coin->h_age_commitment),
- TALER_PQ_query_param_denom_sig (&coin->denom_sig),
- GNUNET_PQ_query_param_end
- };
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_bool ("existed",
- &existed),
- GNUNET_PQ_result_spec_uint64 ("known_coin_id",
- known_coin_id),
- GNUNET_PQ_result_spec_allow_null (
- GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash",
- denom_hash),
- &is_denom_pub_hash_null),
- GNUNET_PQ_result_spec_allow_null (
- GNUNET_PQ_result_spec_auto_from_type ("age_commitment_hash",
- h_age_commitment),
- &is_age_hash_null),
- GNUNET_PQ_result_spec_end
- };
-
- qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "insert_known_coin",
- params,
- rs);
- switch (qs)
- {
- case GNUNET_DB_STATUS_HARD_ERROR:
- GNUNET_break (0);
- return TALER_EXCHANGEDB_CKS_HARD_FAIL;
- case GNUNET_DB_STATUS_SOFT_ERROR:
- return TALER_EXCHANGEDB_CKS_SOFT_FAIL;
- case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
- GNUNET_break (0); /* should be impossible */
- return TALER_EXCHANGEDB_CKS_HARD_FAIL;
- case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
- if (! existed)
- return TALER_EXCHANGEDB_CKS_ADDED;
- break; /* continued below */
- }
-
- if ( (! is_denom_pub_hash_null) &&
- (0 != GNUNET_memcmp (&denom_hash->hash,
- &coin->denom_pub_hash.hash)) )
- {
- GNUNET_break_op (0);
- return TALER_EXCHANGEDB_CKS_DENOM_CONFLICT;
- }
-
- if ( (! is_age_hash_null) &&
- (0 != GNUNET_memcmp (h_age_commitment,
- &coin->h_age_commitment)) )
- {
- GNUNET_break (GNUNET_is_zero (h_age_commitment));
- GNUNET_break_op (0);
- return TALER_EXCHANGEDB_CKS_AGE_CONFLICT;
- }
-
- return TALER_EXCHANGEDB_CKS_PRESENT;
-}
-
-
-/**
- * Insert information about deposited coin into the database.
- *
- * @param cls the `struct PostgresClosure` with the plugin-specific state
- * @param exchange_timestamp time the exchange received the deposit request
- * @param deposit deposit information to store
- * @return query result status
- */
-static enum GNUNET_DB_QueryStatus
-postgres_insert_deposit (void *cls,
- struct GNUNET_TIME_Timestamp exchange_timestamp,
- const struct TALER_EXCHANGEDB_Deposit *deposit)
-{
- struct PostgresClosure *pg = cls;
- struct TALER_EXCHANGEDB_KycStatus kyc;
- enum GNUNET_DB_QueryStatus qs;
- struct TALER_PaytoHashP h_payto;
-
- qs = inselect_account_kyc_status (pg,
- deposit->receiver_wire_account,
- &h_payto,
- &kyc);
- if (qs <= 0)
- {
- GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
- return qs;
- }
- if (GNUNET_TIME_timestamp_cmp (deposit->wire_deadline,
- <,
- deposit->refund_deadline))
- {
- GNUNET_break (0);
- }
- {
- uint64_t shard = compute_shard (&deposit->merchant_pub);
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (&deposit->coin.coin_pub),
- TALER_PQ_query_param_amount (&deposit->amount_with_fee),
- GNUNET_PQ_query_param_timestamp (&deposit->timestamp),
- GNUNET_PQ_query_param_timestamp (&deposit->refund_deadline),
- GNUNET_PQ_query_param_timestamp (&deposit->wire_deadline),
- GNUNET_PQ_query_param_auto_from_type (&deposit->merchant_pub),
- GNUNET_PQ_query_param_auto_from_type (&deposit->h_contract_terms),
- GNUNET_PQ_query_param_auto_from_type (&deposit->wire_salt),
- GNUNET_PQ_query_param_auto_from_type (&h_payto),
- GNUNET_PQ_query_param_auto_from_type (&deposit->csig),
- GNUNET_PQ_query_param_timestamp (&exchange_timestamp),
- GNUNET_PQ_query_param_uint64 (&shard),
- GNUNET_PQ_query_param_end
- };
-
- GNUNET_assert (shard <= INT32_MAX);
- GNUNET_log (
- GNUNET_ERROR_TYPE_INFO,
- "Inserting deposit to be executed at %s (%llu/%llu)\n",
- GNUNET_TIME_timestamp2s (deposit->wire_deadline),
- (unsigned long long) deposit->wire_deadline.abs_time.abs_value_us,
- (unsigned long long) deposit->refund_deadline.abs_time.abs_value_us);
- return GNUNET_PQ_eval_prepared_non_select (pg->conn,
- "insert_deposit",
- params);
- }
-}
-
-
-/**
- * Insert information about refunded coin into the database.
- *
- * @param cls the @e cls of this struct with the plugin-specific state
- * @param refund refund information to store
- * @return query result status
- */
-static enum GNUNET_DB_QueryStatus
-postgres_insert_refund (void *cls,
- const struct TALER_EXCHANGEDB_Refund *refund)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (&refund->coin.coin_pub),
- GNUNET_PQ_query_param_auto_from_type (&refund->details.merchant_pub),
- GNUNET_PQ_query_param_auto_from_type (&refund->details.merchant_sig),
- GNUNET_PQ_query_param_auto_from_type (&refund->details.h_contract_terms),
- GNUNET_PQ_query_param_uint64 (&refund->details.rtransaction_id),
- TALER_PQ_query_param_amount (&refund->details.refund_amount),
- GNUNET_PQ_query_param_end
- };
-
- GNUNET_assert (GNUNET_YES ==
- TALER_amount_cmp_currency (&refund->details.refund_amount,
- &refund->details.refund_fee));
- return GNUNET_PQ_eval_prepared_non_select (pg->conn,
- "insert_refund",
- params);
-}
-
-
-/**
- * Closure for #get_refunds_cb().
- */
-struct SelectRefundContext
-{
- /**
- * Function to call on each result.
- */
- TALER_EXCHANGEDB_RefundCoinCallback cb;
-
- /**
- * Closure for @a cb.
- */
- void *cb_cls;
-
- /**
- * Plugin context.
- */
- struct PostgresClosure *pg;
-
- /**
- * Set to #GNUNET_SYSERR on error.
- */
- int status;
-};
-
-
-/**
- * Function to be called with the results of a SELECT statement
- * that has returned @a num_results results.
- *
- * @param cls closure of type `struct SelectRefundContext *`
- * @param result the postgres result
- * @param num_results the number of results in @a result
- */
-static void
-get_refunds_cb (void *cls,
- PGresult *result,
- unsigned int num_results)
-{
- struct SelectRefundContext *srctx = cls;
- struct PostgresClosure *pg = srctx->pg;
-
- for (unsigned int i = 0; i<num_results; i++)
- {
- struct TALER_Amount amount_with_fee;
- struct GNUNET_PQ_ResultSpec rs[] = {
- 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,
- i))
- {
- GNUNET_break (0);
- srctx->status = GNUNET_SYSERR;
- return;
- }
- if (GNUNET_OK !=
- srctx->cb (srctx->cb_cls,
- &amount_with_fee))
- return;
- }
-}
-
-
-/**
- * Select refunds by @a coin_pub, @a merchant_pub and @a h_contract.
- *
- * @param cls closure of plugin
- * @param coin_pub coin to get refunds for
- * @param merchant_pub merchant to get refunds for
- * @param h_contract contract (hash) to get refunds for
- * @param cb function to call for each refund found
- * @param cb_cls closure for @a cb
- * @return query result status
- */
-static enum GNUNET_DB_QueryStatus
-postgres_select_refunds_by_coin (
- void *cls,
- const struct TALER_CoinSpendPublicKeyP *coin_pub,
- const struct TALER_MerchantPublicKeyP *merchant_pub,
- const struct TALER_PrivateContractHashP *h_contract,
- TALER_EXCHANGEDB_RefundCoinCallback cb,
- void *cb_cls)
-{
- struct PostgresClosure *pg = cls;
- enum GNUNET_DB_QueryStatus qs;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (coin_pub),
- GNUNET_PQ_query_param_auto_from_type (merchant_pub),
- GNUNET_PQ_query_param_auto_from_type (h_contract),
- GNUNET_PQ_query_param_end
- };
- struct SelectRefundContext srctx = {
- .cb = cb,
- .cb_cls = cb_cls,
- .pg = pg,
- .status = GNUNET_OK
- };
-
- qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
- "get_refunds_by_coin_and_contract",
- params,
- &get_refunds_cb,
- &srctx);
- if (GNUNET_SYSERR == srctx.status)
- return GNUNET_DB_STATUS_HARD_ERROR;
- return qs;
-}
-
-
-/**
- * Lookup refresh melt commitment data under the given @a rc.
- *
- * @param cls the `struct PostgresClosure` with the plugin-specific state
- * @param rc commitment hash to use to locate the operation
- * @param[out] melt where to store the result; note that
- * melt->session.coin.denom_sig will be set to NULL
- * and is not fetched by this routine (as it is not needed by the client)
- * @param[out] melt_serial_id set to the row ID of @a rc in the refresh_commitments table
- * @return transaction status
- */
-static enum GNUNET_DB_QueryStatus
-postgres_get_melt (void *cls,
- const struct TALER_RefreshCommitmentP *rc,
- struct TALER_EXCHANGEDB_Melt *melt,
- uint64_t *melt_serial_id)
-{
- struct PostgresClosure *pg = cls;
- bool h_age_commitment_is_null;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (rc),
- GNUNET_PQ_query_param_end
- };
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash",
- &melt->session.coin.
- denom_pub_hash),
- TALER_PQ_RESULT_SPEC_AMOUNT ("fee_refresh",
- &melt->melt_fee),
- GNUNET_PQ_result_spec_uint32 ("noreveal_index",
- &melt->session.noreveal_index),
- GNUNET_PQ_result_spec_auto_from_type ("old_coin_pub",
- &melt->session.coin.coin_pub),
- GNUNET_PQ_result_spec_auto_from_type ("old_coin_sig",
- &melt->session.coin_sig),
- GNUNET_PQ_result_spec_allow_null (
- GNUNET_PQ_result_spec_auto_from_type ("age_commitment_hash",
- &melt->session.coin.h_age_commitment),
- &h_age_commitment_is_null),
- TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee",
- &melt->session.amount_with_fee),
- GNUNET_PQ_result_spec_uint64 ("melt_serial_id",
- melt_serial_id),
- GNUNET_PQ_result_spec_end
- };
- enum GNUNET_DB_QueryStatus qs;
-
- memset (&melt->session.coin.denom_sig,
- 0,
- sizeof (melt->session.coin.denom_sig));
- qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "get_melt",
- params,
- rs);
- if (h_age_commitment_is_null)
- memset (&melt->session.coin.h_age_commitment,
- 0,
- sizeof(melt->session.coin.h_age_commitment));
-
- melt->session.rc = *rc;
- return qs;
-}
-
-
-/**
- * Store in the database which coin(s) the wallet wanted to create
- * in a given refresh operation and all of the other information
- * we learned or created in the /refresh/reveal step.
- *
- * @param cls the @e cls of this struct with the plugin-specific state
- * @param melt_serial_id row ID of the commitment / melt operation in refresh_commitments
- * @param num_rrcs number of coins to generate, size of the @a rrcs array
- * @param rrcs information about the new coins
- * @param num_tprivs number of entries in @a tprivs, should be #TALER_CNC_KAPPA - 1
- * @param tprivs transfer private keys to store
- * @param tp public key to store
- * @return query status for the transaction
- */
-static enum GNUNET_DB_QueryStatus
-postgres_insert_refresh_reveal (
- void *cls,
- uint64_t melt_serial_id,
- uint32_t num_rrcs,
- const struct TALER_EXCHANGEDB_RefreshRevealedCoin *rrcs,
- unsigned int num_tprivs,
- const struct TALER_TransferPrivateKeyP *tprivs,
- const struct TALER_TransferPublicKeyP *tp)
-{
- struct PostgresClosure *pg = cls;
-
- if (TALER_CNC_KAPPA != num_tprivs + 1)
- {
- GNUNET_break (0);
- return GNUNET_DB_STATUS_HARD_ERROR;
- }
- for (uint32_t i = 0; i<num_rrcs; i++)
- {
- const struct TALER_EXCHANGEDB_RefreshRevealedCoin *rrc = &rrcs[i];
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_uint64 (&melt_serial_id),
- GNUNET_PQ_query_param_uint32 (&i),
- GNUNET_PQ_query_param_auto_from_type (&rrc->orig_coin_link_sig),
- GNUNET_PQ_query_param_auto_from_type (&rrc->h_denom_pub),
- TALER_PQ_query_param_blinded_planchet (&rrc->blinded_planchet),
- TALER_PQ_query_param_exchange_withdraw_values (&rrc->exchange_vals),
- GNUNET_PQ_query_param_auto_from_type (&rrc->coin_envelope_hash),
- TALER_PQ_query_param_blinded_denom_sig (&rrc->coin_sig),
- GNUNET_PQ_query_param_end
- };
- enum GNUNET_DB_QueryStatus qs;
-
- qs = GNUNET_PQ_eval_prepared_non_select (pg->conn,
- "insert_refresh_revealed_coin",
- params);
- if (0 > qs)
- return qs;
- }
-
- {
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_uint64 (&melt_serial_id),
- GNUNET_PQ_query_param_auto_from_type (tp),
- GNUNET_PQ_query_param_fixed_size (
- tprivs,
- num_tprivs * sizeof (struct TALER_TransferPrivateKeyP)),
- GNUNET_PQ_query_param_end
- };
-
- return GNUNET_PQ_eval_prepared_non_select (pg->conn,
- "insert_refresh_transfer_keys",
- params);
- }
-}
-
-
-/**
- * Context where we aggregate data from the database.
- * Closure for #add_revealed_coins().
- */
-struct GetRevealContext
-{
- /**
- * Array of revealed coins we obtained from the DB.
- */
- struct TALER_EXCHANGEDB_RefreshRevealedCoin *rrcs;
-
- /**
- * Length of the @a rrcs array.
- */
- unsigned int rrcs_len;
-
- /**
- * Set to an error code if we ran into trouble.
- */
- enum GNUNET_DB_QueryStatus qs;
-};
-
-
-/**
- * Function to be called with the results of a SELECT statement
- * that has returned @a num_results results.
- *
- * @param cls closure of type `struct GetRevealContext`
- * @param result the postgres result
- * @param num_results the number of results in @a result
- */
-static void
-add_revealed_coins (void *cls,
- PGresult *result,
- unsigned int num_results)
-{
- struct GetRevealContext *grctx = cls;
-
- if (0 == num_results)
- return;
- grctx->rrcs = GNUNET_new_array (num_results,
- struct TALER_EXCHANGEDB_RefreshRevealedCoin);
- grctx->rrcs_len = num_results;
- for (unsigned int i = 0; i < num_results; i++)
- {
- uint32_t off;
- struct GNUNET_PQ_ResultSpec rso[] = {
- GNUNET_PQ_result_spec_uint32 ("freshcoin_index",
- &off),
- GNUNET_PQ_result_spec_end
- };
-
- if (GNUNET_OK !=
- GNUNET_PQ_extract_result (result,
- rso,
- i))
- {
- GNUNET_break (0);
- grctx->qs = GNUNET_DB_STATUS_HARD_ERROR;
- return;
- }
- if (off >= num_results)
- {
- GNUNET_break (0);
- grctx->qs = GNUNET_DB_STATUS_HARD_ERROR;
- return;
- }
- {
- struct TALER_EXCHANGEDB_RefreshRevealedCoin *rrc = &grctx->rrcs[off];
- struct GNUNET_PQ_ResultSpec rsi[] = {
- /* NOTE: freshcoin_index selected and discarded here... */
- GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash",
- &rrc->h_denom_pub),
- GNUNET_PQ_result_spec_auto_from_type ("link_sig",
- &rrc->orig_coin_link_sig),
- GNUNET_PQ_result_spec_auto_from_type ("h_coin_ev",
- &rrc->coin_envelope_hash),
- TALER_PQ_result_spec_blinded_planchet ("coin_ev",
- &rrc->blinded_planchet),
- TALER_PQ_result_spec_exchange_withdraw_values ("ewv",
- &rrc->exchange_vals),
- TALER_PQ_result_spec_blinded_denom_sig ("ev_sig",
- &rrc->coin_sig),
- GNUNET_PQ_result_spec_end
- };
-
- if (TALER_DENOMINATION_INVALID != rrc->blinded_planchet.cipher)
- {
- /* duplicate offset, not allowed */
- GNUNET_break (0);
- grctx->qs = GNUNET_DB_STATUS_HARD_ERROR;
- return;
- }
- if (GNUNET_OK !=
- GNUNET_PQ_extract_result (result,
- rsi,
- i))
- {
- GNUNET_break (0);
- grctx->qs = GNUNET_DB_STATUS_HARD_ERROR;
- return;
- }
- }
- }
-}
-
-
-/**
- * Lookup in the database the coins that we want to
- * create in the given refresh operation.
- *
- * @param cls the `struct PostgresClosure` with the plugin-specific state
- * @param rc identify commitment and thus refresh operation
- * @param cb function to call with the results
- * @param cb_cls closure for @a cb
- * @return transaction status
- */
-static enum GNUNET_DB_QueryStatus
-postgres_get_refresh_reveal (void *cls,
- const struct TALER_RefreshCommitmentP *rc,
- TALER_EXCHANGEDB_RefreshCallback cb,
- void *cb_cls)
-{
- struct PostgresClosure *pg = cls;
- struct GetRevealContext grctx;
- enum GNUNET_DB_QueryStatus qs;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (rc),
- GNUNET_PQ_query_param_end
- };
-
- memset (&grctx,
- 0,
- sizeof (grctx));
- qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
- "get_refresh_revealed_coins",
- params,
- &add_revealed_coins,
- &grctx);
- switch (qs)
- {
- case GNUNET_DB_STATUS_HARD_ERROR:
- case GNUNET_DB_STATUS_SOFT_ERROR:
- case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
- goto cleanup;
- case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
- default: /* can have more than one result */
- break;
- }
- switch (grctx.qs)
- {
- case GNUNET_DB_STATUS_HARD_ERROR:
- case GNUNET_DB_STATUS_SOFT_ERROR:
- goto cleanup;
- case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
- case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: /* should be impossible */
- break;
- }
-
- /* Pass result back to application */
- cb (cb_cls,
- grctx.rrcs_len,
- grctx.rrcs);
-cleanup:
- for (unsigned int i = 0; i < grctx.rrcs_len; i++)
- {
- struct TALER_EXCHANGEDB_RefreshRevealedCoin *rrc = &grctx.rrcs[i];
-
- TALER_blinded_denom_sig_free (&rrc->coin_sig);
- TALER_blinded_planchet_free (&rrc->blinded_planchet);
- }
- GNUNET_free (grctx.rrcs);
- return qs;
-}
-
-
-/**
- * Closure for #add_ldl().
- */
-struct LinkDataContext
-{
- /**
- * Function to call on each result.
- */
- TALER_EXCHANGEDB_LinkCallback ldc;
-
- /**
- * Closure for @e ldc.
- */
- void *ldc_cls;
-
- /**
- * Last transfer public key for which we have information in @e last.
- * Only valid if @e last is non-NULL.
- */
- struct TALER_TransferPublicKeyP transfer_pub;
-
- /**
- * Link data for @e transfer_pub
- */
- struct TALER_EXCHANGEDB_LinkList *last;
-
- /**
- * Status, set to #GNUNET_SYSERR on errors,
- */
- int status;
-};
-
-
-/**
- * Free memory of the link data list.
- *
- * @param cls the @e cls of this struct with the plugin-specific state (unused)
- * @param ldl link data list to release
- */
-static void
-free_link_data_list (void *cls,
- struct TALER_EXCHANGEDB_LinkList *ldl)
-{
- struct TALER_EXCHANGEDB_LinkList *next;
-
- (void) cls;
- while (NULL != ldl)
- {
- next = ldl->next;
- TALER_denom_pub_free (&ldl->denom_pub);
- TALER_blinded_denom_sig_free (&ldl->ev_sig);
- GNUNET_free (ldl);
- ldl = next;
- }
-}
-
-
-/**
- * Function to be called with the results of a SELECT statement
- * that has returned @a num_results results.
- *
- * @param cls closure of type `struct LinkDataContext *`
- * @param result the postgres result
- * @param num_results the number of results in @a result
- */
-static void
-add_ldl (void *cls,
- PGresult *result,
- unsigned int num_results)
-{
- struct LinkDataContext *ldctx = cls;
-
- for (int i = num_results - 1; i >= 0; i--)
- {
- struct TALER_EXCHANGEDB_LinkList *pos;
- struct TALER_TransferPublicKeyP transfer_pub;
-
- pos = GNUNET_new (struct TALER_EXCHANGEDB_LinkList);
- {
- struct TALER_BlindedPlanchet bp;
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_auto_from_type ("transfer_pub",
- &transfer_pub),
- GNUNET_PQ_result_spec_auto_from_type ("link_sig",
- &pos->orig_coin_link_sig),
- TALER_PQ_result_spec_blinded_denom_sig ("ev_sig",
- &pos->ev_sig),
- GNUNET_PQ_result_spec_uint32 ("freshcoin_index",
- &pos->coin_refresh_offset),
- TALER_PQ_result_spec_exchange_withdraw_values ("ewv",
- &pos->alg_values),
- TALER_PQ_result_spec_denom_pub ("denom_pub",
- &pos->denom_pub),
- TALER_PQ_result_spec_blinded_planchet ("coin_ev",
- &bp),
- GNUNET_PQ_result_spec_end
- };
-
- if (GNUNET_OK !=
- GNUNET_PQ_extract_result (result,
- rs,
- i))
- {
- GNUNET_break (0);
- GNUNET_free (pos);
- ldctx->status = GNUNET_SYSERR;
- return;
- }
- if (TALER_DENOMINATION_CS == bp.cipher)
- {
- pos->nonce = bp.details.cs_blinded_planchet.nonce;
- pos->have_nonce = true;
- }
- TALER_blinded_planchet_free (&bp);
- }
- if ( (NULL != ldctx->last) &&
- (0 == GNUNET_memcmp (&transfer_pub,
- &ldctx->transfer_pub)) )
- {
- pos->next = ldctx->last;
- }
- else
- {
- if (NULL != ldctx->last)
- {
- ldctx->ldc (ldctx->ldc_cls,
- &ldctx->transfer_pub,
- ldctx->last);
- free_link_data_list (cls,
- ldctx->last);
- }
- ldctx->transfer_pub = transfer_pub;
- }
- ldctx->last = pos;
- }
-}
-
-
-/**
- * Obtain the link data of a coin, that is the encrypted link
- * information, the denomination keys and the signatures.
- *
- * @param cls the `struct PostgresClosure` with the plugin-specific state
- * @param coin_pub public key of the coin
- * @param ldc function to call for each session the coin was melted into
- * @param ldc_cls closure for @a tdc
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_get_link_data (void *cls,
- const struct TALER_CoinSpendPublicKeyP *coin_pub,
- TALER_EXCHANGEDB_LinkCallback ldc,
- void *ldc_cls)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (coin_pub),
- GNUNET_PQ_query_param_end
- };
- enum GNUNET_DB_QueryStatus qs;
- struct LinkDataContext ldctx;
-
- ldctx.ldc = ldc;
- ldctx.ldc_cls = ldc_cls;
- ldctx.last = NULL;
- ldctx.status = GNUNET_OK;
- qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
- "get_link",
- params,
- &add_ldl,
- &ldctx);
- if (NULL != ldctx.last)
- {
- if (GNUNET_OK == ldctx.status)
- {
- /* call callback one more time! */
- ldc (ldc_cls,
- &ldctx.transfer_pub,
- ldctx.last);
- }
- free_link_data_list (cls,
- ldctx.last);
- ldctx.last = NULL;
- }
- if (GNUNET_OK != ldctx.status)
- return GNUNET_DB_STATUS_HARD_ERROR;
- return qs;
-}
-
-
-/**
- * Closure for callbacks called from #postgres_get_coin_transactions()
- */
-struct CoinHistoryContext
-{
- /**
- * Head of the coin's history list.
- */
- struct TALER_EXCHANGEDB_TransactionList *head;
-
- /**
- * Public key of the coin we are building the history for.
- */
- const struct TALER_CoinSpendPublicKeyP *coin_pub;
-
- /**
- * Closure for all callbacks of this database plugin.
- */
- void *db_cls;
-
- /**
- * Plugin context.
- */
- struct PostgresClosure *pg;
-
- /**
- * Set to 'true' if the transaction failed.
- */
- bool failed;
-
- /**
- * Set to 'true' if we found a deposit or melt (for invariant check).
- */
- bool have_deposit_or_melt;
-};
-
-
-/**
- * Function to be called with the results of a SELECT statement
- * that has returned @a num_results results.
- *
- * @param cls closure of type `struct CoinHistoryContext`
- * @param result the postgres result
- * @param num_results the number of results in @a result
- */
-static void
-add_coin_deposit (void *cls,
- PGresult *result,
- unsigned int num_results)
-{
- struct CoinHistoryContext *chc = cls;
- struct PostgresClosure *pg = chc->pg;
-
- for (unsigned int i = 0; i < num_results; i++)
- {
- struct TALER_EXCHANGEDB_DepositListEntry *deposit;
- struct TALER_EXCHANGEDB_TransactionList *tl;
- uint64_t serial_id;
-
- chc->have_deposit_or_melt = true;
- deposit = GNUNET_new (struct TALER_EXCHANGEDB_DepositListEntry);
- {
- struct GNUNET_PQ_ResultSpec rs[] = {
- TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee",
- &deposit->amount_with_fee),
- TALER_PQ_RESULT_SPEC_AMOUNT ("fee_deposit",
- &deposit->deposit_fee),
- GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash",
- &deposit->h_denom_pub),
- GNUNET_PQ_result_spec_allow_null (
- GNUNET_PQ_result_spec_auto_from_type ("age_commitment_hash",
- &deposit->h_age_commitment),
- &deposit->no_age_commitment),
- GNUNET_PQ_result_spec_timestamp ("wallet_timestamp",
- &deposit->timestamp),
- GNUNET_PQ_result_spec_timestamp ("refund_deadline",
- &deposit->refund_deadline),
- GNUNET_PQ_result_spec_timestamp ("wire_deadline",
- &deposit->wire_deadline),
- GNUNET_PQ_result_spec_auto_from_type ("merchant_pub",
- &deposit->merchant_pub),
- GNUNET_PQ_result_spec_auto_from_type ("h_contract_terms",
- &deposit->h_contract_terms),
- GNUNET_PQ_result_spec_auto_from_type ("wire_salt",
- &deposit->wire_salt),
- GNUNET_PQ_result_spec_string ("payto_uri",
- &deposit->receiver_wire_account),
- GNUNET_PQ_result_spec_auto_from_type ("coin_sig",
- &deposit->csig),
- GNUNET_PQ_result_spec_uint64 ("deposit_serial_id",
- &serial_id),
- GNUNET_PQ_result_spec_auto_from_type ("done",
- &deposit->done),
- GNUNET_PQ_result_spec_end
- };
-
- if (GNUNET_OK !=
- GNUNET_PQ_extract_result (result,
- rs,
- i))
- {
- GNUNET_break (0);
- GNUNET_free (deposit);
- chc->failed = true;
- return;
- }
- }
- tl = GNUNET_new (struct TALER_EXCHANGEDB_TransactionList);
- tl->next = chc->head;
- tl->type = TALER_EXCHANGEDB_TT_DEPOSIT;
- tl->details.deposit = deposit;
- tl->serial_id = serial_id;
- chc->head = tl;
- }
-}
-
-
-/**
- * Function to be called with the results of a SELECT statement
- * that has returned @a num_results results.
- *
- * @param cls closure of type `struct CoinHistoryContext`
- * @param result the postgres result
- * @param num_results the number of results in @a result
- */
-static void
-add_coin_purse_deposit (void *cls,
- PGresult *result,
- unsigned int num_results)
-{
- struct CoinHistoryContext *chc = cls;
- struct PostgresClosure *pg = chc->pg;
-
- for (unsigned int i = 0; i < num_results; i++)
- {
- struct TALER_EXCHANGEDB_PurseDepositListEntry *deposit;
- struct TALER_EXCHANGEDB_TransactionList *tl;
- uint64_t serial_id;
-
- chc->have_deposit_or_melt = true;
- deposit = GNUNET_new (struct TALER_EXCHANGEDB_PurseDepositListEntry);
- {
- struct GNUNET_PQ_ResultSpec rs[] = {
- TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee",
- &deposit->amount),
- TALER_PQ_RESULT_SPEC_AMOUNT ("fee_deposit",
- &deposit->deposit_fee),
- GNUNET_PQ_result_spec_auto_from_type ("purse_pub",
- &deposit->purse_pub),
- GNUNET_PQ_result_spec_uint64 ("purse_deposit_serial_id",
- &serial_id),
- GNUNET_PQ_result_spec_allow_null (
- GNUNET_PQ_result_spec_string ("partner_base_url",
- &deposit->exchange_base_url),
- NULL),
- GNUNET_PQ_result_spec_auto_from_type ("coin_sig",
- &deposit->coin_sig),
- GNUNET_PQ_result_spec_auto_from_type ("age_commitment_hash",
- &deposit->h_age_commitment),
- GNUNET_PQ_result_spec_bool ("refunded",
- &deposit->refunded),
- GNUNET_PQ_result_spec_end
- };
-
- if (GNUNET_OK !=
- GNUNET_PQ_extract_result (result,
- rs,
- i))
- {
- GNUNET_break (0);
- GNUNET_free (deposit);
- chc->failed = true;
- return;
- }
- deposit->no_age_commitment = GNUNET_is_zero (&deposit->h_age_commitment);
- }
- tl = GNUNET_new (struct TALER_EXCHANGEDB_TransactionList);
- tl->next = chc->head;
- tl->type = TALER_EXCHANGEDB_TT_PURSE_DEPOSIT;
- tl->details.purse_deposit = deposit;
- tl->serial_id = serial_id;
- chc->head = tl;
- }
-}
-
-
-/**
- * Function to be called with the results of a SELECT statement
- * that has returned @a num_results results.
- *
- * @param cls closure of type `struct CoinHistoryContext`
- * @param result the postgres result
- * @param num_results the number of results in @a result
- */
-static void
-add_coin_melt (void *cls,
- PGresult *result,
- unsigned int num_results)
-{
- struct CoinHistoryContext *chc = cls;
- struct PostgresClosure *pg = chc->pg;
-
- for (unsigned int i = 0; i<num_results; i++)
- {
- struct TALER_EXCHANGEDB_MeltListEntry *melt;
- struct TALER_EXCHANGEDB_TransactionList *tl;
- uint64_t serial_id;
-
- chc->have_deposit_or_melt = true;
- melt = GNUNET_new (struct TALER_EXCHANGEDB_MeltListEntry);
- {
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_auto_from_type ("rc",
- &melt->rc),
- /* oldcoin_index not needed */
- GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash",
- &melt->h_denom_pub),
- GNUNET_PQ_result_spec_auto_from_type ("old_coin_sig",
- &melt->coin_sig),
- TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee",
- &melt->amount_with_fee),
- TALER_PQ_RESULT_SPEC_AMOUNT ("fee_refresh",
- &melt->melt_fee),
- GNUNET_PQ_result_spec_allow_null (
- GNUNET_PQ_result_spec_auto_from_type ("age_commitment_hash",
- &melt->h_age_commitment),
- &melt->no_age_commitment),
- GNUNET_PQ_result_spec_uint64 ("melt_serial_id",
- &serial_id),
- GNUNET_PQ_result_spec_end
- };
-
- if (GNUNET_OK !=
- GNUNET_PQ_extract_result (result,
- rs,
- i))
- {
- GNUNET_break (0);
- GNUNET_free (melt);
- chc->failed = true;
- return;
- }
- }
- tl = GNUNET_new (struct TALER_EXCHANGEDB_TransactionList);
- tl->next = chc->head;
- tl->type = TALER_EXCHANGEDB_TT_MELT;
- tl->details.melt = melt;
- tl->serial_id = serial_id;
- chc->head = tl;
- }
-}
-
-
-/**
- * Function to be called with the results of a SELECT statement
- * that has returned @a num_results results.
- *
- * @param cls closure of type `struct CoinHistoryContext`
- * @param result the postgres result
- * @param num_results the number of results in @a result
- */
-static void
-add_coin_refund (void *cls,
- PGresult *result,
- unsigned int num_results)
-{
- struct CoinHistoryContext *chc = cls;
- struct PostgresClosure *pg = chc->pg;
-
- for (unsigned int i = 0; i<num_results; i++)
- {
- struct TALER_EXCHANGEDB_RefundListEntry *refund;
- struct TALER_EXCHANGEDB_TransactionList *tl;
- uint64_t serial_id;
-
- refund = GNUNET_new (struct TALER_EXCHANGEDB_RefundListEntry);
- {
- 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_terms",
- &refund->h_contract_terms),
- GNUNET_PQ_result_spec_uint64 ("rtransaction_id",
- &refund->rtransaction_id),
- TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee",
- &refund->refund_amount),
- TALER_PQ_RESULT_SPEC_AMOUNT ("fee_refund",
- &refund->refund_fee),
- GNUNET_PQ_result_spec_uint64 ("refund_serial_id",
- &serial_id),
- GNUNET_PQ_result_spec_end
- };
-
- if (GNUNET_OK !=
- GNUNET_PQ_extract_result (result,
- rs,
- i))
- {
- GNUNET_break (0);
- GNUNET_free (refund);
- chc->failed = true;
- return;
- }
- }
- tl = GNUNET_new (struct TALER_EXCHANGEDB_TransactionList);
- tl->next = chc->head;
- tl->type = TALER_EXCHANGEDB_TT_REFUND;
- tl->details.refund = refund;
- tl->serial_id = serial_id;
- chc->head = tl;
- }
-}
-
-
-/**
- * Function to be called with the results of a SELECT statement
- * that has returned @a num_results results.
- *
- * @param cls closure of type `struct CoinHistoryContext`
- * @param result the postgres result
- * @param num_results the number of results in @a result
- */
-static void
-add_old_coin_recoup (void *cls,
- PGresult *result,
- unsigned int num_results)
-{
- struct CoinHistoryContext *chc = cls;
- struct PostgresClosure *pg = chc->pg;
-
- for (unsigned int i = 0; i<num_results; i++)
- {
- struct TALER_EXCHANGEDB_RecoupRefreshListEntry *recoup;
- struct TALER_EXCHANGEDB_TransactionList *tl;
- uint64_t serial_id;
-
- recoup = GNUNET_new (struct TALER_EXCHANGEDB_RecoupRefreshListEntry);
- {
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_auto_from_type ("coin_pub",
- &recoup->coin.coin_pub),
- GNUNET_PQ_result_spec_auto_from_type ("coin_sig",
- &recoup->coin_sig),
- GNUNET_PQ_result_spec_auto_from_type ("coin_blind",
- &recoup->coin_blind),
- TALER_PQ_RESULT_SPEC_AMOUNT ("amount",
- &recoup->value),
- GNUNET_PQ_result_spec_timestamp ("recoup_timestamp",
- &recoup->timestamp),
- GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash",
- &recoup->coin.denom_pub_hash),
- TALER_PQ_result_spec_denom_sig ("denom_sig",
- &recoup->coin.denom_sig),
- GNUNET_PQ_result_spec_uint64 ("recoup_refresh_uuid",
- &serial_id),
- GNUNET_PQ_result_spec_end
- };
-
- if (GNUNET_OK !=
- GNUNET_PQ_extract_result (result,
- rs,
- i))
- {
- GNUNET_break (0);
- GNUNET_free (recoup);
- chc->failed = true;
- return;
- }
- recoup->old_coin_pub = *chc->coin_pub;
- }
- tl = GNUNET_new (struct TALER_EXCHANGEDB_TransactionList);
- tl->next = chc->head;
- tl->type = TALER_EXCHANGEDB_TT_OLD_COIN_RECOUP;
- tl->details.old_coin_recoup = recoup;
- tl->serial_id = serial_id;
- chc->head = tl;
- }
-}
-
-
-/**
- * Function to be called with the results of a SELECT statement
- * that has returned @a num_results results.
- *
- * @param cls closure of type `struct CoinHistoryContext`
- * @param result the postgres result
- * @param num_results the number of results in @a result
- */
-static void
-add_coin_recoup (void *cls,
- PGresult *result,
- unsigned int num_results)
-{
- struct CoinHistoryContext *chc = cls;
- struct PostgresClosure *pg = chc->pg;
-
- for (unsigned int i = 0; i<num_results; i++)
- {
- struct TALER_EXCHANGEDB_RecoupListEntry *recoup;
- struct TALER_EXCHANGEDB_TransactionList *tl;
- uint64_t serial_id;
-
- recoup = GNUNET_new (struct TALER_EXCHANGEDB_RecoupListEntry);
- {
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_auto_from_type ("reserve_pub",
- &recoup->reserve_pub),
- GNUNET_PQ_result_spec_auto_from_type ("coin_sig",
- &recoup->coin_sig),
- GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash",
- &recoup->h_denom_pub),
- GNUNET_PQ_result_spec_auto_from_type ("coin_blind",
- &recoup->coin_blind),
- TALER_PQ_RESULT_SPEC_AMOUNT ("amount",
- &recoup->value),
- GNUNET_PQ_result_spec_timestamp ("recoup_timestamp",
- &recoup->timestamp),
- GNUNET_PQ_result_spec_uint64 ("recoup_uuid",
- &serial_id),
- GNUNET_PQ_result_spec_end
- };
-
- if (GNUNET_OK !=
- GNUNET_PQ_extract_result (result,
- rs,
- i))
- {
- GNUNET_break (0);
- GNUNET_free (recoup);
- chc->failed = true;
- return;
- }
- }
- tl = GNUNET_new (struct TALER_EXCHANGEDB_TransactionList);
- tl->next = chc->head;
- tl->type = TALER_EXCHANGEDB_TT_RECOUP;
- tl->details.recoup = recoup;
- tl->serial_id = serial_id;
- chc->head = tl;
- }
-}
-
-
-/**
- * Function to be called with the results of a SELECT statement
- * that has returned @a num_results results.
- *
- * @param cls closure of type `struct CoinHistoryContext`
- * @param result the postgres result
- * @param num_results the number of results in @a result
- */
-static void
-add_coin_recoup_refresh (void *cls,
- PGresult *result,
- unsigned int num_results)
-{
- struct CoinHistoryContext *chc = cls;
- struct PostgresClosure *pg = chc->pg;
-
- for (unsigned int i = 0; i<num_results; i++)
- {
- struct TALER_EXCHANGEDB_RecoupRefreshListEntry *recoup;
- struct TALER_EXCHANGEDB_TransactionList *tl;
- uint64_t serial_id;
-
- recoup = GNUNET_new (struct TALER_EXCHANGEDB_RecoupRefreshListEntry);
- {
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_auto_from_type ("old_coin_pub",
- &recoup->old_coin_pub),
- GNUNET_PQ_result_spec_auto_from_type ("coin_sig",
- &recoup->coin_sig),
- GNUNET_PQ_result_spec_auto_from_type ("coin_blind",
- &recoup->coin_blind),
- TALER_PQ_RESULT_SPEC_AMOUNT ("amount",
- &recoup->value),
- GNUNET_PQ_result_spec_timestamp ("recoup_timestamp",
- &recoup->timestamp),
- GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash",
- &recoup->coin.denom_pub_hash),
- TALER_PQ_result_spec_denom_sig ("denom_sig",
- &recoup->coin.denom_sig),
- GNUNET_PQ_result_spec_uint64 ("recoup_refresh_uuid",
- &serial_id),
- GNUNET_PQ_result_spec_end
- };
-
- if (GNUNET_OK !=
- GNUNET_PQ_extract_result (result,
- rs,
- i))
- {
- GNUNET_break (0);
- GNUNET_free (recoup);
- chc->failed = true;
- return;
- }
- recoup->coin.coin_pub = *chc->coin_pub;
- }
- tl = GNUNET_new (struct TALER_EXCHANGEDB_TransactionList);
- tl->next = chc->head;
- tl->type = TALER_EXCHANGEDB_TT_RECOUP_REFRESH;
- tl->details.recoup_refresh = recoup;
- tl->serial_id = serial_id;
- chc->head = tl;
- }
-}
-
-
-/**
- * Work we need to do.
- */
-struct Work
-{
- /**
- * SQL prepared statement name.
- */
- const char *statement;
-
- /**
- * Function to call to handle the result(s).
- */
- GNUNET_PQ_PostgresResultHandler cb;
-};
-
-
-/**
- * Compile a list of all (historic) transactions performed with the given coin
- * (/refresh/melt, /deposit, /refund and /recoup operations).
- *
- * @param cls the `struct PostgresClosure` with the plugin-specific state
- * @param coin_pub coin to investigate
- * @param include_recoup should recoup transactions be included in the @a tlp
- * @param[out] tlp set to list of transactions, NULL if coin is fresh
- * @return database transaction status
- */
-static enum GNUNET_DB_QueryStatus
-postgres_get_coin_transactions (
- void *cls,
- const struct TALER_CoinSpendPublicKeyP *coin_pub,
- bool include_recoup,
- struct TALER_EXCHANGEDB_TransactionList **tlp)
-{
- struct PostgresClosure *pg = cls;
- static const struct Work work_op[] = {
- /** #TALER_EXCHANGEDB_TT_DEPOSIT */
- { "get_deposit_with_coin_pub",
- &add_coin_deposit },
- /** #TALER_EXCHANGEDB_TT_MELT */
- { "get_refresh_session_by_coin",
- &add_coin_melt },
- /** #TALER_EXCHANGEDB_TT_PURSE_DEPOSIT */
- { "get_purse_deposit_by_coin_pub",
- &add_coin_purse_deposit },
- /** #TALER_EXCHANGEDB_TT_REFUND */
- { "get_refunds_by_coin",
- &add_coin_refund },
- { NULL, NULL }
- };
- static const struct Work work_wp[] = {
- /** #TALER_EXCHANGEDB_TT_DEPOSIT */
- { "get_deposit_with_coin_pub",
- &add_coin_deposit },
- /** #TALER_EXCHANGEDB_TT_MELT */
- { "get_refresh_session_by_coin",
- &add_coin_melt },
- /** #TALER_EXCHANGEDB_TT_PURSE_DEPOSIT */
- { "get_purse_deposit_by_coin_pub",
- &add_coin_purse_deposit },
- /** #TALER_EXCHANGEDB_TT_REFUND */
- { "get_refunds_by_coin",
- &add_coin_refund },
- /** #TALER_EXCHANGEDB_TT_OLD_COIN_RECOUP */
- { "recoup_by_old_coin",
- &add_old_coin_recoup },
- /** #TALER_EXCHANGEDB_TT_RECOUP */
- { "recoup_by_coin",
- &add_coin_recoup },
- /** #TALER_EXCHANGEDB_TT_RECOUP_REFRESH */
- { "recoup_by_refreshed_coin",
- &add_coin_recoup_refresh },
- { NULL, NULL }
- };
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (coin_pub),
- GNUNET_PQ_query_param_end
- };
- enum GNUNET_DB_QueryStatus qs;
- const struct Work *work;
- struct CoinHistoryContext chc = {
- .head = NULL,
- .coin_pub = coin_pub,
- .pg = pg,
- .db_cls = cls
- };
-
- work = (GNUNET_YES == include_recoup) ? work_wp : work_op;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Getting transactions for coin %s\n",
- TALER_B2S (coin_pub));
- for (unsigned int i = 0; NULL != work[i].statement; i++)
- {
- qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
- work[i].statement,
- params,
- work[i].cb,
- &chc);
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Coin %s yielded %d transactions of type %s\n",
- TALER_B2S (coin_pub),
- qs,
- work[i].statement);
- if ( (0 > qs) ||
- (chc.failed) )
- {
- if (NULL != chc.head)
- common_free_coin_transaction_list (cls,
- chc.head);
- *tlp = NULL;
- if (chc.failed)
- qs = GNUNET_DB_STATUS_HARD_ERROR;
- return qs;
- }
- }
- *tlp = chc.head;
- if (NULL == chc.head)
- return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS;
- return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
-}
-
-
-/**
- * Closure for #handle_wt_result.
- */
-struct WireTransferResultContext
-{
- /**
- * Function to call on each result.
- */
- TALER_EXCHANGEDB_AggregationDataCallback cb;
-
- /**
- * Closure for @e cb.
- */
- void *cb_cls;
-
- /**
- * Plugin context.
- */
- struct PostgresClosure *pg;
-
- /**
- * Set to #GNUNET_SYSERR on serious errors.
- */
- int status;
-};
-
-
-/**
- * Function to be called with the results of a SELECT statement
- * that has returned @a num_results results. Helper function
- * for #postgres_lookup_wire_transfer().
- *
- * @param cls closure of type `struct WireTransferResultContext *`
- * @param result the postgres result
- * @param num_results the number of results in @a result
- */
-static void
-handle_wt_result (void *cls,
- PGresult *result,
- unsigned int num_results)
-{
- struct WireTransferResultContext *ctx = cls;
- struct PostgresClosure *pg = ctx->pg;
-
- for (unsigned int i = 0; i<num_results; i++)
- {
- uint64_t rowid;
- struct TALER_PrivateContractHashP h_contract_terms;
- struct TALER_CoinSpendPublicKeyP coin_pub;
- struct TALER_PaytoHashP h_payto;
- struct TALER_MerchantPublicKeyP merchant_pub;
- struct GNUNET_TIME_Timestamp exec_time;
- struct TALER_Amount amount_with_fee;
- struct TALER_Amount deposit_fee;
- struct TALER_DenominationPublicKey denom_pub;
- char *payto_uri;
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_uint64 ("aggregation_serial_id", &rowid),
- GNUNET_PQ_result_spec_auto_from_type ("h_contract_terms",
- &h_contract_terms),
- GNUNET_PQ_result_spec_string ("payto_uri",
- &payto_uri),
- GNUNET_PQ_result_spec_auto_from_type ("wire_target_h_payto",
- &h_payto),
- TALER_PQ_result_spec_denom_pub ("denom_pub",
- &denom_pub),
- GNUNET_PQ_result_spec_auto_from_type ("coin_pub",
- &coin_pub),
- GNUNET_PQ_result_spec_auto_from_type ("merchant_pub",
- &merchant_pub),
- GNUNET_PQ_result_spec_timestamp ("execution_date",
- &exec_time),
- TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee",
- &amount_with_fee),
- TALER_PQ_RESULT_SPEC_AMOUNT ("fee_deposit",
- &deposit_fee),
- GNUNET_PQ_result_spec_end
- };
-
- if (GNUNET_OK !=
- GNUNET_PQ_extract_result (result,
- rs,
- i))
- {
- GNUNET_break (0);
- ctx->status = GNUNET_SYSERR;
- return;
- }
- ctx->cb (ctx->cb_cls,
- rowid,
- &merchant_pub,
- payto_uri,
- &h_payto,
- exec_time,
- &h_contract_terms,
- &denom_pub,
- &coin_pub,
- &amount_with_fee,
- &deposit_fee);
- GNUNET_PQ_cleanup_result (rs);
- }
-}
-
-
-/**
- * Lookup the list of Taler transactions that were aggregated
- * into a wire transfer by the respective @a wtid.
- *
- * @param cls closure
- * @param wtid the raw wire transfer identifier we used
- * @param cb function to call on each transaction found
- * @param cb_cls closure for @a cb
- * @return query status of the transaction
- */
-static enum GNUNET_DB_QueryStatus
-postgres_lookup_wire_transfer (
- void *cls,
- const struct TALER_WireTransferIdentifierRawP *wtid,
- TALER_EXCHANGEDB_AggregationDataCallback cb,
- void *cb_cls)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (wtid),
- GNUNET_PQ_query_param_end
- };
- struct WireTransferResultContext ctx;
- enum GNUNET_DB_QueryStatus qs;
-
- ctx.cb = cb;
- ctx.cb_cls = cb_cls;
- ctx.pg = pg;
- ctx.status = GNUNET_OK;
- /* check if the melt record exists and get it */
- qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
- "lookup_transactions",
- params,
- &handle_wt_result,
- &ctx);
- if (GNUNET_OK != ctx.status)
- return GNUNET_DB_STATUS_HARD_ERROR;
- return qs;
-}
-
-
-/**
- * Try to find the wire transfer details for a deposit operation.
- * If we did not execute the deposit yet, return when it is supposed
- * to be executed.
- *
- * @param cls closure
- * @param h_contract_terms hash of the proposal data
- * @param h_wire hash of merchant wire details
- * @param coin_pub public key of deposited coin
- * @param merchant_pub merchant public key
- * @param[out] pending set to true if the transaction is still pending
- * @param[out] wtid wire transfer identifier, only set if @a pending is false
- * @param[out] exec_time when was the transaction done, or
- * when we expect it to be done (if @a pending is false)
- * @param[out] amount_with_fee set to the total deposited amount
- * @param[out] deposit_fee set to how much the exchange did charge for the deposit
- * @param[out] kyc set to the kyc status of the receiver (if @a pending)
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_lookup_transfer_by_deposit (
- void *cls,
- const struct TALER_PrivateContractHashP *h_contract_terms,
- const struct TALER_MerchantWireHashP *h_wire,
- const struct TALER_CoinSpendPublicKeyP *coin_pub,
- const struct TALER_MerchantPublicKeyP *merchant_pub,
- bool *pending,
- struct TALER_WireTransferIdentifierRawP *wtid,
- struct GNUNET_TIME_Timestamp *exec_time,
- struct TALER_Amount *amount_with_fee,
- struct TALER_Amount *deposit_fee,
- struct TALER_EXCHANGEDB_KycStatus *kyc)
-{
- struct PostgresClosure *pg = cls;
- enum GNUNET_DB_QueryStatus qs;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (coin_pub),
- GNUNET_PQ_query_param_auto_from_type (h_contract_terms),
- GNUNET_PQ_query_param_auto_from_type (merchant_pub),
- GNUNET_PQ_query_param_end
- };
- char *payto_uri;
- struct TALER_WireSaltP wire_salt;
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_auto_from_type ("wtid_raw",
- wtid),
- GNUNET_PQ_result_spec_auto_from_type ("wire_salt",
- &wire_salt),
- GNUNET_PQ_result_spec_string ("payto_uri",
- &payto_uri),
- GNUNET_PQ_result_spec_timestamp ("execution_date",
- exec_time),
- TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee",
- amount_with_fee),
- TALER_PQ_RESULT_SPEC_AMOUNT ("fee_deposit",
- deposit_fee),
- GNUNET_PQ_result_spec_end
- };
-
- /* check if the aggregation record exists and get it */
- qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "lookup_deposit_wtid",
- params,
- rs);
- if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs)
- {
- struct TALER_MerchantWireHashP wh;
-
- TALER_merchant_wire_signature_hash (payto_uri,
- &wire_salt,
- &wh);
- GNUNET_PQ_cleanup_result (rs);
- if (0 ==
- GNUNET_memcmp (&wh,
- h_wire))
- {
- *pending = false;
- memset (kyc,
- 0,
- sizeof (*kyc));
- kyc->type = TALER_EXCHANGEDB_KYC_DEPOSIT;
- kyc->ok = true;
- return qs;
- }
- qs = GNUNET_DB_STATUS_SUCCESS_NO_RESULTS;
- }
- if (0 > qs)
- return qs;
- *pending = true;
- memset (wtid,
- 0,
- sizeof (*wtid));
- GNUNET_assert (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "lookup_deposit_wtid returned 0 matching rows\n");
- {
- /* Check if transaction exists in deposits, so that we just
- do not have a WTID yet. In that case, return without wtid
- (by setting 'pending' true). */
- struct GNUNET_PQ_ResultSpec rs2[] = {
- GNUNET_PQ_result_spec_auto_from_type ("wire_salt",
- &wire_salt),
- GNUNET_PQ_result_spec_string ("payto_uri",
- &payto_uri),
- GNUNET_PQ_result_spec_uint64 ("payment_target_uuid",
- &kyc->payment_target_uuid),
- GNUNET_PQ_result_spec_auto_from_type ("kyc_ok",
- &kyc->ok),
- TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee",
- amount_with_fee),
- TALER_PQ_RESULT_SPEC_AMOUNT ("fee_deposit",
- deposit_fee),
- GNUNET_PQ_result_spec_timestamp ("wire_deadline",
- exec_time),
- GNUNET_PQ_result_spec_end
- };
-
- qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "get_deposit_without_wtid",
- params,
- rs2);
- if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs)
- {
- struct TALER_MerchantWireHashP wh;
-
- TALER_merchant_wire_signature_hash (payto_uri,
- &wire_salt,
- &wh);
- GNUNET_PQ_cleanup_result (rs);
- if (0 !=
- GNUNET_memcmp (&wh,
- h_wire))
- return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS;
- }
- kyc->type = TALER_EXCHANGEDB_KYC_DEPOSIT;
- return qs;
- }
-}
-
-
-/**
- * Function called to insert aggregation information into the DB.
- *
- * @param cls closure
- * @param wtid the raw wire transfer identifier we used
- * @param deposit_serial_id row in the deposits table for which this is aggregation data
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_insert_aggregation_tracking (
- void *cls,
- const struct TALER_WireTransferIdentifierRawP *wtid,
- unsigned long long deposit_serial_id)
-{
- struct PostgresClosure *pg = cls;
- uint64_t rid = deposit_serial_id;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_uint64 (&rid),
- GNUNET_PQ_query_param_auto_from_type (wtid),
- GNUNET_PQ_query_param_end
- };
-
- return GNUNET_PQ_eval_prepared_non_select (pg->conn,
- "insert_aggregation_tracking",
- params);
-}
-
-
-/**
- * Obtain wire fee from database.
- *
- * @param cls closure
- * @param type type of wire transfer the fee applies for
- * @param date for which date do we want the fee?
- * @param[out] start_date when does the fee go into effect
- * @param[out] end_date when does the fee end being valid
- * @param[out] fees how high are the wire fees
- * @param[out] master_sig signature over the above by the exchange master key
- * @return status of the transaction
- */
-static enum GNUNET_DB_QueryStatus
-postgres_get_wire_fee (void *cls,
- const char *type,
- struct GNUNET_TIME_Timestamp date,
- struct GNUNET_TIME_Timestamp *start_date,
- struct GNUNET_TIME_Timestamp *end_date,
- struct TALER_WireFeeSet *fees,
- struct TALER_MasterSignatureP *master_sig)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_string (type),
- GNUNET_PQ_query_param_timestamp (&date),
- GNUNET_PQ_query_param_end
- };
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_timestamp ("start_date",
- start_date),
- GNUNET_PQ_result_spec_timestamp ("end_date",
- end_date),
- TALER_PQ_RESULT_SPEC_AMOUNT ("wire_fee",
- &fees->wire),
- TALER_PQ_RESULT_SPEC_AMOUNT ("wad_fee",
- &fees->wad),
- TALER_PQ_RESULT_SPEC_AMOUNT ("closing_fee",
- &fees->closing),
- GNUNET_PQ_result_spec_auto_from_type ("master_sig",
- master_sig),
- GNUNET_PQ_result_spec_end
- };
-
- return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "get_wire_fee",
- params,
- rs);
-}
-
-
-/**
- * Obtain global fees from database.
- *
- * @param cls closure
- * @param date for which date do we want the fee?
- * @param[out] start_date when does the fee go into effect
- * @param[out] end_date when does the fee end being valid
- * @param[out] fees how high are the wire fees
- * @param[out] purse_timeout set to how long we keep unmerged purses
- * @param[out] kyc_timeout set to how long we keep accounts without KYC
- * @param[out] history_expiration set to how long we keep account histories
- * @param[out] purse_account_limit set to the number of free purses per account
- * @param[out] master_sig signature over the above by the exchange master key
- * @return status of the transaction
- */
-static enum GNUNET_DB_QueryStatus
-postgres_get_global_fee (void *cls,
- struct GNUNET_TIME_Timestamp date,
- struct GNUNET_TIME_Timestamp *start_date,
- struct GNUNET_TIME_Timestamp *end_date,
- struct TALER_GlobalFeeSet *fees,
- struct GNUNET_TIME_Relative *purse_timeout,
- struct GNUNET_TIME_Relative *kyc_timeout,
- struct GNUNET_TIME_Relative *history_expiration,
- uint32_t *purse_account_limit,
- struct TALER_MasterSignatureP *master_sig)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_timestamp (&date),
- GNUNET_PQ_query_param_end
- };
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_timestamp ("start_date",
- start_date),
- GNUNET_PQ_result_spec_timestamp ("end_date",
- end_date),
- TALER_PQ_RESULT_SPEC_AMOUNT ("history_fee",
- &fees->history),
- TALER_PQ_RESULT_SPEC_AMOUNT ("kyc_fee",
- &fees->kyc),
- TALER_PQ_RESULT_SPEC_AMOUNT ("account_fee",
- &fees->account),
- TALER_PQ_RESULT_SPEC_AMOUNT ("purse_fee",
- &fees->purse),
- GNUNET_PQ_result_spec_relative_time ("purse_timeout",
- purse_timeout),
- GNUNET_PQ_result_spec_relative_time ("kyc_timeout",
- kyc_timeout),
- GNUNET_PQ_result_spec_relative_time ("history_expiration",
- history_expiration),
- GNUNET_PQ_result_spec_uint32 ("purse_account_limit",
- purse_account_limit),
- GNUNET_PQ_result_spec_auto_from_type ("master_sig",
- master_sig),
- GNUNET_PQ_result_spec_end
- };
-
- return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "get_global_fee",
- params,
- rs);
-}
-
-
-/**
- * Closure for #global_fees_cb().
- */
-struct GlobalFeeContext
-{
- /**
- * Function to call for each global fee block.
- */
- TALER_EXCHANGEDB_GlobalFeeCallback cb;
-
- /**
- * Closure to give to @e rec.
- */
- void *cb_cls;
-
- /**
- * Plugin context.
- */
- struct PostgresClosure *pg;
-
- /**
- * Set to #GNUNET_SYSERR on error.
- */
- enum GNUNET_GenericReturnValue status;
-};
-
-
-/**
- * Function to be called with the results of a SELECT statement
- * that has returned @a num_results results.
- *
- * @param cls closure
- * @param result the postgres result
- * @param num_results the number of results in @a result
- */
-static void
-global_fees_cb (void *cls,
- PGresult *result,
- unsigned int num_results)
-{
- struct GlobalFeeContext *gctx = cls;
- struct PostgresClosure *pg = gctx->pg;
-
- for (unsigned int i = 0; i<num_results; i++)
- {
- struct TALER_GlobalFeeSet fees;
- struct GNUNET_TIME_Relative purse_timeout;
- struct GNUNET_TIME_Relative kyc_timeout;
- struct GNUNET_TIME_Relative history_expiration;
- uint32_t purse_account_limit;
- struct GNUNET_TIME_Timestamp start_date;
- struct GNUNET_TIME_Timestamp end_date;
- struct TALER_MasterSignatureP master_sig;
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_timestamp ("start_date",
- &start_date),
- GNUNET_PQ_result_spec_timestamp ("end_date",
- &end_date),
- TALER_PQ_RESULT_SPEC_AMOUNT ("history_fee",
- &fees.history),
- TALER_PQ_RESULT_SPEC_AMOUNT ("kyc_fee",
- &fees.kyc),
- TALER_PQ_RESULT_SPEC_AMOUNT ("account_fee",
- &fees.account),
- TALER_PQ_RESULT_SPEC_AMOUNT ("purse_fee",
- &fees.purse),
- GNUNET_PQ_result_spec_relative_time ("purse_timeout",
- &purse_timeout),
- GNUNET_PQ_result_spec_relative_time ("kyc_timeout",
- &kyc_timeout),
- GNUNET_PQ_result_spec_relative_time ("history_expiration",
- &history_expiration),
- GNUNET_PQ_result_spec_uint32 ("purse_account_limit",
- &purse_account_limit),
- GNUNET_PQ_result_spec_auto_from_type ("master_sig",
- &master_sig),
- GNUNET_PQ_result_spec_end
- };
- if (GNUNET_OK !=
- GNUNET_PQ_extract_result (result,
- rs,
- i))
- {
- GNUNET_break (0);
- gctx->status = GNUNET_SYSERR;
- break;
- }
- gctx->cb (gctx->cb_cls,
- &fees,
- purse_timeout,
- kyc_timeout,
- history_expiration,
- purse_account_limit,
- start_date,
- end_date,
- &master_sig);
- GNUNET_PQ_cleanup_result (rs);
- }
-}
-
-
-/**
- * Obtain global fees from database.
- *
- * @param cls closure
- * @param cb function to call on each fee entry
- * @param cb_cls closure for @a cb
- * @return status of the transaction
- */
-static enum GNUNET_DB_QueryStatus
-postgres_get_global_fees (void *cls,
- TALER_EXCHANGEDB_GlobalFeeCallback cb,
- void *cb_cls)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_TIME_Timestamp date
- = GNUNET_TIME_absolute_to_timestamp (
- GNUNET_TIME_absolute_subtract (
- GNUNET_TIME_absolute_get (),
- GNUNET_TIME_UNIT_YEARS));
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_timestamp (&date),
- GNUNET_PQ_query_param_end
- };
- struct GlobalFeeContext gctx = {
- .cb = cb,
- .cb_cls = cb_cls,
- .pg = pg,
- .status = GNUNET_OK
- };
-
- return GNUNET_PQ_eval_prepared_multi_select (pg->conn,
- "get_global_fees",
- params,
- &global_fees_cb,
- &gctx);
-}
-
-
-/**
- * Insert wire transfer fee into database.
- *
- * @param cls closure
- * @param type type of wire transfer this fee applies for
- * @param start_date when does the fee go into effect
- * @param end_date when does the fee end being valid
- * @param fees how high are the wire fees
- * @param master_sig signature over the above by the exchange master key
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_insert_wire_fee (void *cls,
- const char *type,
- struct GNUNET_TIME_Timestamp start_date,
- struct GNUNET_TIME_Timestamp end_date,
- const struct TALER_WireFeeSet *fees,
- const struct TALER_MasterSignatureP *master_sig)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_string (type),
- GNUNET_PQ_query_param_timestamp (&start_date),
- GNUNET_PQ_query_param_timestamp (&end_date),
- TALER_PQ_query_param_amount (&fees->wire),
- TALER_PQ_query_param_amount (&fees->closing),
- TALER_PQ_query_param_amount (&fees->wad),
- GNUNET_PQ_query_param_auto_from_type (master_sig),
- GNUNET_PQ_query_param_end
- };
- struct TALER_WireFeeSet wx;
- struct TALER_MasterSignatureP sig;
- struct GNUNET_TIME_Timestamp sd;
- struct GNUNET_TIME_Timestamp ed;
- enum GNUNET_DB_QueryStatus qs;
-
- qs = postgres_get_wire_fee (pg,
- type,
- start_date,
- &sd,
- &ed,
- &wx,
- &sig);
- if (qs < 0)
- return qs;
- if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs)
- {
- if (0 != GNUNET_memcmp (&sig,
- master_sig))
- {
- GNUNET_break (0);
- return GNUNET_DB_STATUS_HARD_ERROR;
- }
- if (0 !=
- TALER_wire_fee_set_cmp (fees,
- &wx))
- {
- GNUNET_break (0);
- return GNUNET_DB_STATUS_HARD_ERROR;
- }
- if ( (GNUNET_TIME_timestamp_cmp (sd,
- !=,
- start_date)) ||
- (GNUNET_TIME_timestamp_cmp (ed,
- !=,
- end_date)) )
- {
- GNUNET_break (0);
- return GNUNET_DB_STATUS_HARD_ERROR;
- }
- /* equal record already exists */
- return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS;
- }
-
- return GNUNET_PQ_eval_prepared_non_select (pg->conn,
- "insert_wire_fee",
- params);
-}
-
-
-/**
- * Insert global fee data into database.
- *
- * @param cls closure
- * @param start_date when does the fees go into effect
- * @param end_date when does the fees end being valid
- * @param fees how high is are the global fees
- * @param purse_timeout when do purses time out
- * @param kyc_timeout when do reserves without KYC time out
- * @param history_expiration how long are account histories preserved
- * @param purse_account_limit how many purses are free per account
- * @param master_sig signature over the above by the exchange master key
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_insert_global_fee (void *cls,
- struct GNUNET_TIME_Timestamp start_date,
- struct GNUNET_TIME_Timestamp end_date,
- const struct TALER_GlobalFeeSet *fees,
- struct GNUNET_TIME_Relative purse_timeout,
- struct GNUNET_TIME_Relative kyc_timeout,
- struct GNUNET_TIME_Relative history_expiration,
- uint32_t purse_account_limit,
- const struct TALER_MasterSignatureP *master_sig)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_timestamp (&start_date),
- GNUNET_PQ_query_param_timestamp (&end_date),
- TALER_PQ_query_param_amount (&fees->history),
- TALER_PQ_query_param_amount (&fees->kyc),
- TALER_PQ_query_param_amount (&fees->account),
- TALER_PQ_query_param_amount (&fees->purse),
- GNUNET_PQ_query_param_relative_time (&purse_timeout),
- GNUNET_PQ_query_param_relative_time (&kyc_timeout),
- GNUNET_PQ_query_param_relative_time (&history_expiration),
- GNUNET_PQ_query_param_uint32 (&purse_account_limit),
- GNUNET_PQ_query_param_auto_from_type (master_sig),
- GNUNET_PQ_query_param_end
- };
- struct TALER_GlobalFeeSet wx;
- struct TALER_MasterSignatureP sig;
- struct GNUNET_TIME_Timestamp sd;
- struct GNUNET_TIME_Timestamp ed;
- enum GNUNET_DB_QueryStatus qs;
- struct GNUNET_TIME_Relative pt;
- struct GNUNET_TIME_Relative kt;
- struct GNUNET_TIME_Relative he;
- uint32_t pal;
-
- qs = postgres_get_global_fee (pg,
- start_date,
- &sd,
- &ed,
- &wx,
- &pt,
- &kt,
- &he,
- &pal,
- &sig);
- if (qs < 0)
- return qs;
- if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs)
- {
- if (0 != GNUNET_memcmp (&sig,
- master_sig))
- {
- GNUNET_break (0);
- return GNUNET_DB_STATUS_HARD_ERROR;
- }
- if (0 !=
- TALER_global_fee_set_cmp (fees,
- &wx))
- {
- GNUNET_break (0);
- return GNUNET_DB_STATUS_HARD_ERROR;
- }
- if ( (GNUNET_TIME_timestamp_cmp (sd,
- !=,
- start_date)) ||
- (GNUNET_TIME_timestamp_cmp (ed,
- !=,
- end_date)) )
- {
- GNUNET_break (0);
- return GNUNET_DB_STATUS_HARD_ERROR;
- }
- if ( (GNUNET_TIME_relative_cmp (purse_timeout,
- !=,
- pt)) ||
- (GNUNET_TIME_relative_cmp (kyc_timeout,
- !=,
- kt)) ||
- (GNUNET_TIME_relative_cmp (history_expiration,
- !=,
- he)) )
- {
- GNUNET_break (0);
- return GNUNET_DB_STATUS_HARD_ERROR;
- }
- if (purse_account_limit != pal)
- {
- GNUNET_break (0);
- return GNUNET_DB_STATUS_HARD_ERROR;
- }
- /* equal record already exists */
- return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS;
- }
-
- return GNUNET_PQ_eval_prepared_non_select (pg->conn,
- "insert_global_fee",
- params);
-}
-
-
-/**
- * Closure for #reserve_expired_cb().
- */
-struct ExpiredReserveContext
-{
- /**
- * Function to call for each expired reserve.
- */
- TALER_EXCHANGEDB_ReserveExpiredCallback rec;
-
- /**
- * Closure to give to @e rec.
- */
- void *rec_cls;
-
- /**
- * Plugin context.
- */
- struct PostgresClosure *pg;
-
- /**
- * Set to #GNUNET_SYSERR on error.
- */
- enum GNUNET_GenericReturnValue status;
-};
-
-
-/**
- * Function to be called with the results of a SELECT statement
- * that has returned @a num_results results.
- *
- * @param cls closure
- * @param result the postgres result
- * @param num_results the number of results in @a result
- */
-static void
-reserve_expired_cb (void *cls,
- PGresult *result,
- unsigned int num_results)
-{
- struct ExpiredReserveContext *erc = cls;
- struct PostgresClosure *pg = erc->pg;
- enum GNUNET_GenericReturnValue ret;
-
- ret = GNUNET_OK;
- for (unsigned int i = 0; i<num_results; i++)
- {
- struct GNUNET_TIME_Timestamp exp_date;
- char *account_details;
- struct TALER_ReservePublicKeyP reserve_pub;
- struct TALER_Amount remaining_balance;
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_timestamp ("expiration_date",
- &exp_date),
- GNUNET_PQ_result_spec_string ("account_details",
- &account_details),
- GNUNET_PQ_result_spec_auto_from_type ("reserve_pub",
- &reserve_pub),
- TALER_PQ_RESULT_SPEC_AMOUNT ("current_balance",
- &remaining_balance),
- GNUNET_PQ_result_spec_end
- };
-
- if (GNUNET_OK !=
- GNUNET_PQ_extract_result (result,
- rs,
- i))
- {
- GNUNET_break (0);
- ret = GNUNET_SYSERR;
- break;
- }
- ret = erc->rec (erc->rec_cls,
- &reserve_pub,
- &remaining_balance,
- account_details,
- exp_date);
- GNUNET_PQ_cleanup_result (rs);
- if (GNUNET_OK != ret)
- break;
- }
- erc->status = ret;
-}
-
-
-/**
- * Obtain information about expired reserves and their
- * remaining balances.
- *
- * @param cls closure of the plugin
- * @param now timestamp based on which we decide expiration
- * @param rec function to call on expired reserves
- * @param rec_cls closure for @a rec
- * @return transaction status
- */
-static enum GNUNET_DB_QueryStatus
-postgres_get_expired_reserves (void *cls,
- struct GNUNET_TIME_Timestamp now,
- TALER_EXCHANGEDB_ReserveExpiredCallback rec,
- void *rec_cls)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_timestamp (&now),
- GNUNET_PQ_query_param_end
- };
- struct ExpiredReserveContext ectx = {
- .rec = rec,
- .rec_cls = rec_cls,
- .pg = pg,
- .status = GNUNET_OK
- };
- enum GNUNET_DB_QueryStatus qs;
-
- qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
- "get_expired_reserves",
- params,
- &reserve_expired_cb,
- &ectx);
- if (GNUNET_OK != ectx.status)
- return GNUNET_DB_STATUS_HARD_ERROR;
- return qs;
-}
-
-
-/**
- * Insert reserve close operation into database.
- *
- * @param cls closure
- * @param reserve_pub which reserve is this about?
- * @param execution_date when did we perform the transfer?
- * @param receiver_account to which account do we transfer?
- * @param wtid wire transfer details
- * @param amount_with_fee amount we charged to the reserve
- * @param closing_fee how high is the closing fee
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_insert_reserve_closed (
- void *cls,
- const struct TALER_ReservePublicKeyP *reserve_pub,
- struct GNUNET_TIME_Timestamp execution_date,
- const char *receiver_account,
- const struct TALER_WireTransferIdentifierRawP *wtid,
- const struct TALER_Amount *amount_with_fee,
- const struct TALER_Amount *closing_fee)
-{
- struct PostgresClosure *pg = cls;
- struct TALER_EXCHANGEDB_Reserve reserve;
- struct TALER_EXCHANGEDB_KycStatus kyc;
- enum GNUNET_DB_QueryStatus qs;
- struct TALER_PaytoHashP h_payto;
-
- qs = inselect_account_kyc_status (pg,
- receiver_account,
- &h_payto,
- &kyc);
- if (qs <= 0)
- {
- GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs);
- GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
- return qs;
- }
- {
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (reserve_pub),
- GNUNET_PQ_query_param_timestamp (&execution_date),
- GNUNET_PQ_query_param_auto_from_type (wtid),
- GNUNET_PQ_query_param_auto_from_type (&h_payto),
- TALER_PQ_query_param_amount (amount_with_fee),
- TALER_PQ_query_param_amount (closing_fee),
- GNUNET_PQ_query_param_end
- };
-
- qs = GNUNET_PQ_eval_prepared_non_select (pg->conn,
- "reserves_close_insert",
- params);
- }
- if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs)
- return qs;
-
- /* update reserve balance */
- reserve.pub = *reserve_pub;
- if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
- (qs = reserves_get_internal (cls,
- &reserve)))
- {
- /* Existence should have been checked before we got here... */
- GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
- if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
- qs = GNUNET_DB_STATUS_HARD_ERROR;
- return qs;
- }
- {
- enum TALER_AmountArithmeticResult ret;
-
- ret = TALER_amount_subtract (&reserve.balance,
- &reserve.balance,
- amount_with_fee);
- if (ret < 0)
- {
- /* The reserve history was checked to make sure there is enough of a balance
- left before we tried this; however, concurrent operations may have changed
- the situation by now. We should re-try the transaction. */
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Closing of reserve `%s' refused due to balance mismatch. Retrying.\n",
- TALER_B2S (reserve_pub));
- return GNUNET_DB_STATUS_HARD_ERROR;
- }
- GNUNET_break (TALER_AAR_RESULT_ZERO == ret);
- }
- return reserves_update (cls,
- &reserve);
-}
-
-
-/**
- * Function called to insert wire transfer commit data into the DB.
- *
- * @param cls closure
- * @param type type of the wire transfer (i.e. "iban")
- * @param buf buffer with wire transfer preparation data
- * @param buf_size number of bytes in @a buf
- * @return query status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_wire_prepare_data_insert (void *cls,
- const char *type,
- const char *buf,
- size_t buf_size)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_string (type),
- GNUNET_PQ_query_param_fixed_size (buf, buf_size),
- GNUNET_PQ_query_param_end
- };
-
- return GNUNET_PQ_eval_prepared_non_select (pg->conn,
- "wire_prepare_data_insert",
- params);
-}
-
-
-/**
- * Function called to mark wire transfer commit data as finished.
- *
- * @param cls closure
- * @param rowid which entry to mark as finished
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_wire_prepare_data_mark_finished (
- void *cls,
- uint64_t rowid)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_uint64 (&rowid),
- GNUNET_PQ_query_param_end
- };
-
- return GNUNET_PQ_eval_prepared_non_select (pg->conn,
- "wire_prepare_data_mark_done",
- params);
-}
-
-
-/**
- * Function called to mark wire transfer commit data as failed.
- *
- * @param cls closure
- * @param rowid which entry to mark as failed
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_wire_prepare_data_mark_failed (
- void *cls,
- uint64_t rowid)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_uint64 (&rowid),
- GNUNET_PQ_query_param_end
- };
-
- return GNUNET_PQ_eval_prepared_non_select (pg->conn,
- "wire_prepare_data_mark_failed",
- params);
-}
-
-
-/**
- * Closure for #prewire_cb().
- */
-struct PrewireContext
-{
- /**
- * Function to call on each result.
- */
- TALER_EXCHANGEDB_WirePreparationIterator cb;
-
- /**
- * Closure for @a cb.
- */
- void *cb_cls;
-
- /**
- * #GNUNET_OK if everything went fine.
- */
- enum GNUNET_GenericReturnValue status;
-};
-
-
-/**
- * Invoke the callback for each result.
- *
- * @param cls a `struct MissingWireContext *`
- * @param result SQL result
- * @param num_results number of rows in @a result
- */
-static void
-prewire_cb (void *cls,
- PGresult *result,
- unsigned int num_results)
-{
- struct PrewireContext *pc = cls;
-
- for (unsigned int i = 0; i < num_results; i++)
- {
- uint64_t prewire_uuid;
- char *wire_method;
- void *buf = NULL;
- size_t buf_size;
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_uint64 ("prewire_uuid",
- &prewire_uuid),
- GNUNET_PQ_result_spec_string ("wire_method",
- &wire_method),
- GNUNET_PQ_result_spec_variable_size ("buf",
- &buf,
- &buf_size),
- GNUNET_PQ_result_spec_end
- };
-
- if (GNUNET_OK !=
- GNUNET_PQ_extract_result (result,
- rs,
- i))
- {
- GNUNET_break (0);
- pc->status = GNUNET_SYSERR;
- return;
- }
- pc->cb (pc->cb_cls,
- prewire_uuid,
- wire_method,
- buf,
- buf_size);
- GNUNET_PQ_cleanup_result (rs);
- }
-}
-
-
-/**
- * Function called to get an unfinished wire transfer
- * preparation data. Fetches at most one item.
- *
- * @param cls closure
- * @param start_row offset to query table at
- * @param limit maximum number of results to return
- * @param cb function to call for ONE unfinished item
- * @param cb_cls closure for @a cb
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_wire_prepare_data_get (void *cls,
- uint64_t start_row,
- uint64_t limit,
- TALER_EXCHANGEDB_WirePreparationIterator cb,
- void *cb_cls)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_uint64 (&start_row),
- GNUNET_PQ_query_param_uint64 (&limit),
- GNUNET_PQ_query_param_end
- };
- struct PrewireContext pc = {
- .cb = cb,
- .cb_cls = cb_cls,
- .status = GNUNET_OK
- };
- enum GNUNET_DB_QueryStatus qs;
-
- qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
- "wire_prepare_data_get",
- params,
- &prewire_cb,
- &pc);
- if (GNUNET_OK != pc.status)
- return GNUNET_DB_STATUS_HARD_ERROR;
- return qs;
-}
-
-
-/**
- * Starts a READ COMMITTED transaction where we transiently violate the foreign
- * constraints on the "wire_out" table as we insert aggregations
- * and only add the wire transfer out at the end.
- *
- * @param cls the @e cls of this struct with the plugin-specific state
- * @return #GNUNET_OK on success
- */
-static enum GNUNET_GenericReturnValue
-postgres_start_deferred_wire_out (void *cls)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_ExecuteStatement es[] = {
- GNUNET_PQ_make_execute (
- "START TRANSACTION ISOLATION LEVEL READ COMMITTED;"),
- GNUNET_PQ_make_execute ("SET CONSTRAINTS ALL DEFERRED;"),
- GNUNET_PQ_EXECUTE_STATEMENT_END
- };
-
- if (GNUNET_SYSERR ==
- postgres_preflight (pg))
- return GNUNET_SYSERR;
- if (GNUNET_OK !=
- GNUNET_PQ_exec_statements (pg->conn,
- es))
- {
- TALER_LOG_ERROR (
- "Failed to defer wire_out_ref constraint on transaction\n");
- GNUNET_break (0);
- postgres_rollback (pg);
- return GNUNET_SYSERR;
- }
- pg->transaction_name = "deferred wire out";
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Starting READ COMMITTED DEFERRED transaction `%s'\n",
- pg->transaction_name);
return GNUNET_OK;
}
/**
- * Store information about an outgoing wire transfer that was executed.
- *
- * @param cls closure
- * @param date time of the wire transfer
- * @param wtid subject of the wire transfer
- * @param h_payto identifies the receiver account of the wire transfer
- * @param exchange_account_section configuration section of the exchange specifying the
- * exchange's bank account being used
- * @param amount amount that was transmitted
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_store_wire_transfer_out (
- void *cls,
- struct GNUNET_TIME_Timestamp date,
- const struct TALER_WireTransferIdentifierRawP *wtid,
- const struct TALER_PaytoHashP *h_payto,
- const char *exchange_account_section,
- const struct TALER_Amount *amount)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_timestamp (&date),
- GNUNET_PQ_query_param_auto_from_type (wtid),
- GNUNET_PQ_query_param_auto_from_type (h_payto),
- GNUNET_PQ_query_param_string (exchange_account_section),
- TALER_PQ_query_param_amount (amount),
- GNUNET_PQ_query_param_end
- };
-
- return GNUNET_PQ_eval_prepared_non_select (pg->conn,
- "insert_wire_out",
- params);
-}
-
-
-/**
- * Function called to perform "garbage collection" on the
- * database, expiring records we no longer require.
- *
- * @param cls closure
- * @return #GNUNET_OK on success,
- * #GNUNET_SYSERR on DB errors
- */
-static enum GNUNET_GenericReturnValue
-postgres_gc (void *cls)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get ();
- struct GNUNET_TIME_Absolute long_ago;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_absolute_time (&long_ago),
- GNUNET_PQ_query_param_absolute_time (&now),
- GNUNET_PQ_query_param_end
- };
- struct GNUNET_PQ_Context *conn;
- enum GNUNET_GenericReturnValue ret;
-
- /* Keep wire fees for 10 years, that should always
- be enough _and_ they are tiny so it does not
- matter to make this tight */
- long_ago = GNUNET_TIME_absolute_subtract (
- now,
- GNUNET_TIME_relative_multiply (
- GNUNET_TIME_UNIT_YEARS,
- 10));
- {
- struct GNUNET_PQ_PreparedStatement ps[] = {
- /* Used in #postgres_gc() */
- GNUNET_PQ_make_prepare ("run_gc",
- "CALL"
- " exchange_do_gc"
- " ($1,$2);",
- 2),
- GNUNET_PQ_PREPARED_STATEMENT_END
- };
-
- conn = GNUNET_PQ_connect_with_cfg (pg->cfg,
- "exchangedb-postgres",
- NULL,
- NULL,
- ps);
- }
- if (NULL == conn)
- return GNUNET_SYSERR;
- ret = GNUNET_OK;
- if (0 > GNUNET_PQ_eval_prepared_non_select (conn,
- "run_gc",
- params))
- ret = GNUNET_SYSERR;
- GNUNET_PQ_disconnect (conn);
- return ret;
-}
-
-
-/**
- * Closure for #deposit_serial_helper_cb().
- */
-struct DepositSerialContext
-{
-
- /**
- * Callback to call.
- */
- TALER_EXCHANGEDB_DepositCallback cb;
-
- /**
- * Closure for @e cb.
- */
- void *cb_cls;
-
- /**
- * Plugin context.
- */
- struct PostgresClosure *pg;
-
- /**
- * Status code, set to #GNUNET_SYSERR on hard errors.
- */
- enum GNUNET_GenericReturnValue status;
-};
-
-
-/**
- * Helper function to be called with the results of a SELECT statement
- * that has returned @a num_results results.
- *
- * @param cls closure of type `struct DepositSerialContext`
- * @param result the postgres result
- * @param num_results the number of results in @a result
- */
-static void
-deposit_serial_helper_cb (void *cls,
- PGresult *result,
- unsigned int num_results)
-{
- struct DepositSerialContext *dsc = cls;
- struct PostgresClosure *pg = dsc->pg;
-
- for (unsigned int i = 0; i<num_results; i++)
- {
- struct TALER_EXCHANGEDB_Deposit deposit;
- struct GNUNET_TIME_Timestamp exchange_timestamp;
- struct TALER_DenominationPublicKey denom_pub;
- bool done;
- uint64_t rowid;
- struct GNUNET_PQ_ResultSpec rs[] = {
- TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee",
- &deposit.amount_with_fee),
- GNUNET_PQ_result_spec_timestamp ("wallet_timestamp",
- &deposit.timestamp),
- GNUNET_PQ_result_spec_timestamp ("exchange_timestamp",
- &exchange_timestamp),
- GNUNET_PQ_result_spec_auto_from_type ("merchant_pub",
- &deposit.merchant_pub),
- TALER_PQ_result_spec_denom_pub ("denom_pub",
- &denom_pub),
- GNUNET_PQ_result_spec_auto_from_type ("coin_pub",
- &deposit.coin.coin_pub),
- GNUNET_PQ_result_spec_allow_null (
- GNUNET_PQ_result_spec_auto_from_type ("age_commitment_hash",
- &deposit.coin.h_age_commitment),
- &deposit.coin.no_age_commitment),
- GNUNET_PQ_result_spec_auto_from_type ("coin_sig",
- &deposit.csig),
- GNUNET_PQ_result_spec_timestamp ("refund_deadline",
- &deposit.refund_deadline),
- GNUNET_PQ_result_spec_timestamp ("wire_deadline",
- &deposit.wire_deadline),
- GNUNET_PQ_result_spec_auto_from_type ("h_contract_terms",
- &deposit.h_contract_terms),
- GNUNET_PQ_result_spec_auto_from_type ("wire_salt",
- &deposit.wire_salt),
- GNUNET_PQ_result_spec_string ("receiver_wire_account",
- &deposit.receiver_wire_account),
- GNUNET_PQ_result_spec_bool ("done",
- &done),
- GNUNET_PQ_result_spec_uint64 ("deposit_serial_id",
- &rowid),
- GNUNET_PQ_result_spec_end
- };
- enum GNUNET_GenericReturnValue ret;
-
- memset (&deposit,
- 0,
- sizeof (deposit));
- if (GNUNET_OK !=
- GNUNET_PQ_extract_result (result,
- rs,
- i))
- {
- GNUNET_break (0);
- dsc->status = GNUNET_SYSERR;
- return;
- }
- ret = dsc->cb (dsc->cb_cls,
- rowid,
- exchange_timestamp,
- &deposit,
- &denom_pub,
- done);
- GNUNET_PQ_cleanup_result (rs);
- if (GNUNET_OK != ret)
- break;
- }
-}
-
-
-/**
- * Select deposits above @a serial_id in monotonically increasing
- * order.
- *
- * @param cls closure
- * @param serial_id highest serial ID to exclude (select strictly larger)
- * @param cb function to call on each result
- * @param cb_cls closure for @a cb
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_select_deposits_above_serial_id (
- void *cls,
- uint64_t serial_id,
- TALER_EXCHANGEDB_DepositCallback cb,
- void *cb_cls)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_uint64 (&serial_id),
- GNUNET_PQ_query_param_end
- };
- struct DepositSerialContext dsc = {
- .cb = cb,
- .cb_cls = cb_cls,
- .pg = pg,
- .status = GNUNET_OK
- };
- enum GNUNET_DB_QueryStatus qs;
-
- qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
- "audit_get_deposits_incr",
- params,
- &deposit_serial_helper_cb,
- &dsc);
- if (GNUNET_OK != dsc.status)
- return GNUNET_DB_STATUS_HARD_ERROR;
- return qs;
-}
-
-
-/**
- * Closure for #purse_deposit_serial_helper_cb().
- */
-struct PurseDepositSerialContext
-{
-
- /**
- * Callback to call.
- */
- TALER_EXCHANGEDB_PurseDepositCallback cb;
-
- /**
- * Closure for @e cb.
- */
- void *cb_cls;
-
- /**
- * Plugin context.
- */
- struct PostgresClosure *pg;
-
- /**
- * Status code, set to #GNUNET_SYSERR on hard errors.
- */
- enum GNUNET_GenericReturnValue status;
-};
-
-
-/**
- * Helper function to be called with the results of a SELECT statement
- * that has returned @a num_results results.
- *
- * @param cls closure of type `struct DepositSerialContext`
- * @param result the postgres result
- * @param num_results the number of results in @a result
- */
-static void
-purse_deposit_serial_helper_cb (void *cls,
- PGresult *result,
- unsigned int num_results)
-{
- struct PurseDepositSerialContext *dsc = cls;
- struct PostgresClosure *pg = dsc->pg;
-
- for (unsigned int i = 0; i<num_results; i++)
- {
- struct TALER_EXCHANGEDB_PurseDeposit deposit = {
- .exchange_base_url = NULL
- };
- struct TALER_DenominationPublicKey denom_pub;
- uint64_t rowid;
- uint32_t flags32;
- struct TALER_ReservePublicKeyP reserve_pub;
- bool not_merged = false;
- struct TALER_Amount purse_balance;
- struct TALER_Amount purse_total;
- struct GNUNET_PQ_ResultSpec rs[] = {
- TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee",
- &deposit.amount),
- TALER_PQ_RESULT_SPEC_AMOUNT ("balance",
- &purse_balance),
- TALER_PQ_RESULT_SPEC_AMOUNT ("total",
- &purse_total),
- TALER_PQ_RESULT_SPEC_AMOUNT ("deposit_fee",
- &deposit.deposit_fee),
- GNUNET_PQ_result_spec_allow_null (
- GNUNET_PQ_result_spec_string ("partner_base_url",
- &deposit.exchange_base_url),
- NULL),
- GNUNET_PQ_result_spec_allow_null (
- GNUNET_PQ_result_spec_auto_from_type ("reserve_pub",
- &reserve_pub),
- &not_merged),
- TALER_PQ_result_spec_denom_pub ("denom_pub",
- &denom_pub),
- GNUNET_PQ_result_spec_auto_from_type ("purse_pub",
- &deposit.purse_pub),
- GNUNET_PQ_result_spec_auto_from_type ("coin_sig",
- &deposit.coin_sig),
- GNUNET_PQ_result_spec_uint32 ("flags",
- &flags32),
- GNUNET_PQ_result_spec_auto_from_type ("coin_pub",
- &deposit.coin_pub),
- GNUNET_PQ_result_spec_allow_null (
- GNUNET_PQ_result_spec_auto_from_type ("age_commitment_hash",
- &deposit.h_age_commitment),
- &deposit.no_age_commitment),
- GNUNET_PQ_result_spec_uint64 ("purse_deposit_serial_id",
- &rowid),
- GNUNET_PQ_result_spec_end
- };
- enum GNUNET_GenericReturnValue ret;
-
- memset (&deposit,
- 0,
- sizeof (deposit));
- if (GNUNET_OK !=
- GNUNET_PQ_extract_result (result,
- rs,
- i))
- {
- GNUNET_break (0);
- dsc->status = GNUNET_SYSERR;
- return;
- }
- ret = dsc->cb (dsc->cb_cls,
- rowid,
- &deposit,
- not_merged ? NULL : &reserve_pub,
- (enum TALER_WalletAccountMergeFlags) flags32,
- &purse_balance,
- &purse_total,
- &denom_pub);
- GNUNET_PQ_cleanup_result (rs);
- if (GNUNET_OK != ret)
- break;
- }
-}
-
-
-/**
- * Select deposits above @a serial_id in monotonically increasing
- * order.
- *
- * @param cls closure
- * @param serial_id highest serial ID to exclude (select strictly larger)
- * @param cb function to call on each result
- * @param cb_cls closure for @a cb
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_select_purse_deposits_above_serial_id (
- void *cls,
- uint64_t serial_id,
- TALER_EXCHANGEDB_PurseDepositCallback cb,
- void *cb_cls)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_uint64 (&serial_id),
- GNUNET_PQ_query_param_end
- };
- struct PurseDepositSerialContext dsc = {
- .cb = cb,
- .cb_cls = cb_cls,
- .pg = pg,
- .status = GNUNET_OK
- };
- enum GNUNET_DB_QueryStatus qs;
-
- qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
- "audit_get_purse_deposits_incr",
- params,
- &purse_deposit_serial_helper_cb,
- &dsc);
- if (GNUNET_OK != dsc.status)
- return GNUNET_DB_STATUS_HARD_ERROR;
- return qs;
-}
-
-
-/**
- * Closure for #account_merge_serial_helper_cb().
- */
-struct AccountMergeSerialContext
-{
-
- /**
- * Callback to call.
- */
- TALER_EXCHANGEDB_AccountMergeCallback cb;
-
- /**
- * Closure for @e cb.
- */
- void *cb_cls;
-
- /**
- * Plugin context.
- */
- struct PostgresClosure *pg;
-
- /**
- * Status code, set to #GNUNET_SYSERR on hard errors.
- */
- enum GNUNET_GenericReturnValue status;
-};
-
-
-/**
- * Helper function to be called with the results of a SELECT statement
- * that has returned @a num_results results.
- *
- * @param cls closure of type `struct AccountMergeSerialContext`
- * @param result the postgres result
- * @param num_results the number of results in @a result
- */
-static void
-account_merge_serial_helper_cb (void *cls,
- PGresult *result,
- unsigned int num_results)
-{
- struct AccountMergeSerialContext *dsc = cls;
- struct PostgresClosure *pg = dsc->pg;
-
- for (unsigned int i = 0; i<num_results; i++)
- {
- struct TALER_ReservePublicKeyP reserve_pub;
- struct TALER_PurseContractPublicKeyP purse_pub;
- struct TALER_PrivateContractHashP h_contract_terms;
- struct GNUNET_TIME_Timestamp purse_expiration;
- struct TALER_Amount amount;
- uint32_t min_age;
- uint32_t flags32;
- enum TALER_WalletAccountMergeFlags flags;
- struct TALER_Amount purse_fee;
- struct GNUNET_TIME_Timestamp merge_timestamp;
- struct TALER_ReserveSignatureP reserve_sig;
- uint64_t rowid;
- struct GNUNET_PQ_ResultSpec rs[] = {
- TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee",
- &amount),
- TALER_PQ_RESULT_SPEC_AMOUNT ("purse_fee",
- &purse_fee),
- GNUNET_PQ_result_spec_uint32 ("flags",
- &flags32),
- GNUNET_PQ_result_spec_uint32 ("age_limit",
- &min_age),
- GNUNET_PQ_result_spec_timestamp ("purse_expiration",
- &purse_expiration),
- GNUNET_PQ_result_spec_timestamp ("merge_timestamp",
- &merge_timestamp),
- GNUNET_PQ_result_spec_auto_from_type ("h_contract_terms",
- &h_contract_terms),
- GNUNET_PQ_result_spec_auto_from_type ("purse_pub",
- &purse_pub),
- GNUNET_PQ_result_spec_auto_from_type ("reserve_sig",
- &reserve_sig),
- GNUNET_PQ_result_spec_auto_from_type ("reserve_pub",
- &reserve_pub),
- GNUNET_PQ_result_spec_uint64 ("account_merge_request_serial_id",
- &rowid),
- GNUNET_PQ_result_spec_end
- };
- enum GNUNET_GenericReturnValue ret;
-
- if (GNUNET_OK !=
- GNUNET_PQ_extract_result (result,
- rs,
- i))
- {
- GNUNET_break (0);
- dsc->status = GNUNET_SYSERR;
- return;
- }
- flags = (enum TALER_WalletAccountMergeFlags) flags32;
- ret = dsc->cb (dsc->cb_cls,
- rowid,
- &reserve_pub,
- &purse_pub,
- &h_contract_terms,
- purse_expiration,
- &amount,
- min_age,
- flags,
- &purse_fee,
- merge_timestamp,
- &reserve_sig);
- GNUNET_PQ_cleanup_result (rs);
- if (GNUNET_OK != ret)
- break;
- }
-}
-
-
-/**
- * Select account merges above @a serial_id in monotonically increasing
- * order.
- *
- * @param cls closure
- * @param serial_id highest serial ID to exclude (select strictly larger)
- * @param cb function to call on each result
- * @param cb_cls closure for @a cb
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_select_account_merges_above_serial_id (
- void *cls,
- uint64_t serial_id,
- TALER_EXCHANGEDB_AccountMergeCallback cb,
- void *cb_cls)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_uint64 (&serial_id),
- GNUNET_PQ_query_param_end
- };
- struct AccountMergeSerialContext dsc = {
- .cb = cb,
- .cb_cls = cb_cls,
- .pg = pg,
- .status = GNUNET_OK
- };
- enum GNUNET_DB_QueryStatus qs;
-
- qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
- "audit_get_account_merge_incr",
- params,
- &account_merge_serial_helper_cb,
- &dsc);
- if (GNUNET_OK != dsc.status)
- return GNUNET_DB_STATUS_HARD_ERROR;
- return qs;
-}
-
-
-/**
- * Closure for #purse_deposit_serial_helper_cb().
- */
-struct PurseMergeSerialContext
-{
-
- /**
- * Callback to call.
- */
- TALER_EXCHANGEDB_PurseMergeCallback cb;
-
- /**
- * Closure for @e cb.
- */
- void *cb_cls;
-
- /**
- * Plugin context.
- */
- struct PostgresClosure *pg;
-
- /**
- * Status code, set to #GNUNET_SYSERR on hard errors.
- */
- enum GNUNET_GenericReturnValue status;
-};
-
-
-/**
- * Helper function to be called with the results of a SELECT statement
- * that has returned @a num_results results.
- *
- * @param cls closure of type `struct PurseMergeSerialContext`
- * @param result the postgres result
- * @param num_results the number of results in @a result
- */
-static void
-purse_merges_serial_helper_cb (void *cls,
- PGresult *result,
- unsigned int num_results)
-{
- struct PurseMergeSerialContext *dsc = cls;
- struct PostgresClosure *pg = dsc->pg;
-
- for (unsigned int i = 0; i<num_results; i++)
- {
- uint64_t rowid;
- char *partner_base_url = NULL;
- struct TALER_Amount amount;
- struct TALER_Amount balance;
- uint32_t flags32;
- enum TALER_WalletAccountMergeFlags flags;
- struct TALER_PurseMergePublicKeyP merge_pub;
- struct TALER_ReservePublicKeyP reserve_pub;
- struct TALER_PurseMergeSignatureP merge_sig;
- struct TALER_PurseContractPublicKeyP purse_pub;
- struct GNUNET_TIME_Timestamp merge_timestamp;
- struct GNUNET_PQ_ResultSpec rs[] = {
- TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee",
- &amount),
- TALER_PQ_RESULT_SPEC_AMOUNT ("balance",
- &balance),
- GNUNET_PQ_result_spec_allow_null (
- GNUNET_PQ_result_spec_string ("partner_base_url",
- &partner_base_url),
- NULL),
- GNUNET_PQ_result_spec_uint32 ("flags",
- &flags32),
- GNUNET_PQ_result_spec_timestamp ("merge_timestamp",
- &merge_timestamp),
- GNUNET_PQ_result_spec_auto_from_type ("purse_pub",
- &purse_pub),
- GNUNET_PQ_result_spec_auto_from_type ("reserve_pub",
- &reserve_pub),
- GNUNET_PQ_result_spec_auto_from_type ("merge_sig",
- &merge_sig),
- GNUNET_PQ_result_spec_auto_from_type ("merge_pub",
- &merge_pub),
- GNUNET_PQ_result_spec_uint64 ("purse_merge_request_serial_id",
- &rowid),
- GNUNET_PQ_result_spec_end
- };
- enum GNUNET_GenericReturnValue ret;
-
- if (GNUNET_OK !=
- GNUNET_PQ_extract_result (result,
- rs,
- i))
- {
- GNUNET_break (0);
- dsc->status = GNUNET_SYSERR;
- return;
- }
- flags = (enum TALER_WalletAccountMergeFlags) flags32;
- ret = dsc->cb (dsc->cb_cls,
- rowid,
- partner_base_url,
- &amount,
- &balance,
- flags,
- &merge_pub,
- &reserve_pub,
- &merge_sig,
- &purse_pub,
- merge_timestamp);
- GNUNET_PQ_cleanup_result (rs);
- if (GNUNET_OK != ret)
- break;
- }
-}
-
-
-/**
- * Select purse merges deposits above @a serial_id in monotonically increasing
- * order.
- *
- * @param cls closure
- * @param serial_id highest serial ID to exclude (select strictly larger)
- * @param cb function to call on each result
- * @param cb_cls closure for @a cb
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_select_purse_merges_above_serial_id (
- void *cls,
- uint64_t serial_id,
- TALER_EXCHANGEDB_PurseMergeCallback cb,
- void *cb_cls)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_uint64 (&serial_id),
- GNUNET_PQ_query_param_end
- };
- struct PurseMergeSerialContext dsc = {
- .cb = cb,
- .cb_cls = cb_cls,
- .pg = pg,
- .status = GNUNET_OK
- };
- enum GNUNET_DB_QueryStatus qs;
-
- qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
- "audit_get_purse_merge_incr",
- params,
- &purse_merges_serial_helper_cb,
- &dsc);
- if (GNUNET_OK != dsc.status)
- return GNUNET_DB_STATUS_HARD_ERROR;
- return qs;
-}
-
-
-/**
- * Closure for #purse_deposit_serial_helper_cb().
- */
-struct HistoryRequestSerialContext
-{
-
- /**
- * Callback to call.
- */
- TALER_EXCHANGEDB_HistoryRequestCallback cb;
-
- /**
- * Closure for @e cb.
- */
- void *cb_cls;
-
- /**
- * Plugin context.
- */
- struct PostgresClosure *pg;
-
- /**
- * Status code, set to #GNUNET_SYSERR on hard errors.
- */
- enum GNUNET_GenericReturnValue status;
-};
-
-
-/**
- * Helper function to be called with the results of a SELECT statement
- * that has returned @a num_results results.
- *
- * @param cls closure of type `struct HistoryRequestSerialContext`
- * @param result the postgres result
- * @param num_results the number of results in @a result
- */
-static void
-history_request_serial_helper_cb (void *cls,
- PGresult *result,
- unsigned int num_results)
-{
- struct HistoryRequestSerialContext *dsc = cls;
- struct PostgresClosure *pg = dsc->pg;
-
- for (unsigned int i = 0; i<num_results; i++)
- {
- uint64_t rowid;
- struct TALER_Amount history_fee;
- struct GNUNET_TIME_Timestamp ts;
- struct TALER_ReservePublicKeyP reserve_pub;
- struct TALER_ReserveSignatureP reserve_sig;
- struct GNUNET_PQ_ResultSpec rs[] = {
- TALER_PQ_RESULT_SPEC_AMOUNT ("history_fee",
- &history_fee),
- 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_uint64 ("history_request_serial_id",
- &rowid),
- GNUNET_PQ_result_spec_timestamp ("request_timestamp",
- &ts),
- GNUNET_PQ_result_spec_end
- };
- enum GNUNET_GenericReturnValue ret;
-
- if (GNUNET_OK !=
- GNUNET_PQ_extract_result (result,
- rs,
- i))
- {
- GNUNET_break (0);
- dsc->status = GNUNET_SYSERR;
- return;
- }
- ret = dsc->cb (dsc->cb_cls,
- rowid,
- &history_fee,
- ts,
- &reserve_pub,
- &reserve_sig);
- GNUNET_PQ_cleanup_result (rs);
- if (GNUNET_OK != ret)
- break;
- }
-}
-
-
-/**
- * Select history requests above @a serial_id in monotonically increasing
- * order.
- *
- * @param cls closure
- * @param serial_id highest serial ID to exclude (select strictly larger)
- * @param cb function to call on each result
- * @param cb_cls closure for @a cb
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_select_history_requests_above_serial_id (
- void *cls,
- uint64_t serial_id,
- TALER_EXCHANGEDB_HistoryRequestCallback cb,
- void *cb_cls)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_uint64 (&serial_id),
- GNUNET_PQ_query_param_end
- };
- struct HistoryRequestSerialContext dsc = {
- .cb = cb,
- .cb_cls = cb_cls,
- .pg = pg,
- .status = GNUNET_OK
- };
- enum GNUNET_DB_QueryStatus qs;
-
- qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
- "audit_get_history_requests_incr",
- params,
- &history_request_serial_helper_cb,
- &dsc);
- if (GNUNET_OK != dsc.status)
- return GNUNET_DB_STATUS_HARD_ERROR;
- return qs;
-}
-
-
-/**
- * Closure for #purse_refund_serial_helper_cb().
- */
-struct PurseRefundSerialContext
-{
-
- /**
- * Callback to call.
- */
- TALER_EXCHANGEDB_PurseRefundCallback cb;
-
- /**
- * Closure for @e cb.
- */
- void *cb_cls;
-
- /**
- * Plugin context.
- */
- struct PostgresClosure *pg;
-
- /**
- * Status code, set to #GNUNET_SYSERR on hard errors.
- */
- enum GNUNET_GenericReturnValue status;
-};
-
-
-/**
- * Helper function to be called with the results of a SELECT statement
- * that has returned @a num_results results.
- *
- * @param cls closure of type `struct PurseRefundSerialContext`
- * @param result the postgres result
- * @param num_results the number of results in @a result
- */
-static void
-purse_refund_serial_helper_cb (void *cls,
- PGresult *result,
- unsigned int num_results)
-{
- struct PurseRefundSerialContext *dsc = cls;
-
- for (unsigned int i = 0; i<num_results; i++)
- {
- struct TALER_PurseContractPublicKeyP purse_pub;
- uint64_t rowid;
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_auto_from_type ("purse_pub",
- &purse_pub),
- GNUNET_PQ_result_spec_uint64 ("purse_deposit_serial_id",
- &rowid),
- GNUNET_PQ_result_spec_end
- };
- enum GNUNET_GenericReturnValue ret;
-
- if (GNUNET_OK !=
- GNUNET_PQ_extract_result (result,
- rs,
- i))
- {
- GNUNET_break (0);
- dsc->status = GNUNET_SYSERR;
- return;
- }
- ret = dsc->cb (dsc->cb_cls,
- rowid,
- &purse_pub);
- GNUNET_PQ_cleanup_result (rs);
- if (GNUNET_OK != ret)
- break;
- }
-}
-
-
-/**
- * Select purse refunds above @a serial_id in monotonically increasing
- * order.
- *
- * @param cls closure
- * @param serial_id highest serial ID to exclude (select strictly larger)
- * @param cb function to call on each result
- * @param cb_cls closure for @a cb
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_select_purse_refunds_above_serial_id (
- void *cls,
- uint64_t serial_id,
- TALER_EXCHANGEDB_PurseRefundCallback cb,
- void *cb_cls)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_uint64 (&serial_id),
- GNUNET_PQ_query_param_end
- };
- struct PurseRefundSerialContext dsc = {
- .cb = cb,
- .cb_cls = cb_cls,
- .pg = pg,
- .status = GNUNET_OK
- };
- enum GNUNET_DB_QueryStatus qs;
-
- qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
- "audit_get_purse_refunds_incr",
- params,
- &purse_refund_serial_helper_cb,
- &dsc);
- if (GNUNET_OK != dsc.status)
- return GNUNET_DB_STATUS_HARD_ERROR;
- return qs;
-}
-
-
-/**
- * Closure for #purse_refund_coin_helper_cb().
- */
-struct PurseRefundCoinContext
-{
-
- /**
- * Callback to call.
- */
- TALER_EXCHANGEDB_PurseRefundCoinCallback cb;
-
- /**
- * Closure for @e cb.
- */
- void *cb_cls;
-
- /**
- * Plugin context.
- */
- struct PostgresClosure *pg;
-
- /**
- * Status code, set to #GNUNET_SYSERR on hard errors.
- */
- enum GNUNET_GenericReturnValue status;
-};
-
-
-/**
- * Helper function to be called with the results of a SELECT statement
- * that has returned @a num_results results.
- *
- * @param cls closure of type `struct PurseRefundCoinContext`
- * @param result the postgres result
- * @param num_results the number of results in @a result
- */
-static void
-purse_refund_coin_helper_cb (void *cls,
- PGresult *result,
- unsigned int num_results)
-{
- struct PurseRefundCoinContext *dsc = cls;
- struct PostgresClosure *pg = dsc->pg;
-
- for (unsigned int i = 0; i<num_results; i++)
- {
- struct TALER_Amount amount_with_fee;
- struct TALER_CoinSpendPublicKeyP coin_pub;
- struct TALER_DenominationPublicKey denom_pub;
- uint64_t rowid;
- struct GNUNET_PQ_ResultSpec rs[] = {
- TALER_PQ_result_spec_denom_pub ("denom_pub",
- &denom_pub),
- TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee",
- &amount_with_fee),
- GNUNET_PQ_result_spec_auto_from_type ("coin_pub",
- &coin_pub),
- GNUNET_PQ_result_spec_uint64 ("purse_deposit_serial_id",
- &rowid),
- GNUNET_PQ_result_spec_end
- };
- enum GNUNET_GenericReturnValue ret;
-
- if (GNUNET_OK !=
- GNUNET_PQ_extract_result (result,
- rs,
- i))
- {
- GNUNET_break (0);
- dsc->status = GNUNET_SYSERR;
- return;
- }
- ret = dsc->cb (dsc->cb_cls,
- rowid,
- &amount_with_fee,
- &coin_pub,
- &denom_pub);
- GNUNET_PQ_cleanup_result (rs);
- if (GNUNET_OK != ret)
- break;
- }
-}
-
-
-/**
- * Select coin affected by purse refund.
- *
- * @param cls closure
- * @param purse_pub purse that was refunded
- * @param cb function to call on each result
- * @param cb_cls closure for @a cb
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_select_purse_deposits_by_purse (
- void *cls,
- const struct TALER_PurseContractPublicKeyP *purse_pub,
- TALER_EXCHANGEDB_PurseRefundCoinCallback cb,
- void *cb_cls)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (purse_pub),
- GNUNET_PQ_query_param_end
- };
- struct PurseRefundCoinContext dsc = {
- .cb = cb,
- .cb_cls = cb_cls,
- .pg = pg,
- .status = GNUNET_OK
- };
- enum GNUNET_DB_QueryStatus qs;
-
- qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
- "audit_get_purse_deposits_by_purse",
- params,
- &purse_refund_coin_helper_cb,
- &dsc);
- if (GNUNET_OK != dsc.status)
- return GNUNET_DB_STATUS_HARD_ERROR;
- return qs;
-}
-
-
-/**
- * Closure for #refreshs_serial_helper_cb().
- */
-struct RefreshsSerialContext
-{
-
- /**
- * Callback to call.
- */
- TALER_EXCHANGEDB_RefreshesCallback cb;
-
- /**
- * Closure for @e cb.
- */
- void *cb_cls;
-
- /**
- * Plugin context.
- */
- struct PostgresClosure *pg;
-
- /**
- * Status code, set to #GNUNET_SYSERR on hard errors.
- */
- enum GNUNET_GenericReturnValue status;
-};
-
-
-/**
- * Helper function to be called with the results of a SELECT statement
- * that has returned @a num_results results.
- *
- * @param cls closure of type `struct RefreshsSerialContext`
- * @param result the postgres result
- * @param num_results the number of results in @a result
- */
-static void
-refreshs_serial_helper_cb (void *cls,
- PGresult *result,
- unsigned int num_results)
-{
- struct RefreshsSerialContext *rsc = cls;
- struct PostgresClosure *pg = rsc->pg;
-
- for (unsigned int i = 0; i<num_results; i++)
- {
- struct TALER_DenominationPublicKey denom_pub;
- struct TALER_CoinSpendPublicKeyP coin_pub;
- struct TALER_CoinSpendSignatureP coin_sig;
- struct TALER_AgeCommitmentHash h_age_commitment;
- bool ac_isnull;
- struct TALER_Amount amount_with_fee;
- uint32_t noreveal_index;
- uint64_t rowid;
- struct TALER_RefreshCommitmentP rc;
- struct GNUNET_PQ_ResultSpec rs[] = {
- TALER_PQ_result_spec_denom_pub ("denom_pub",
- &denom_pub),
- GNUNET_PQ_result_spec_allow_null (
- GNUNET_PQ_result_spec_auto_from_type ("age_commitment_hash",
- &h_age_commitment),
- &ac_isnull),
- 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_uint32 ("noreveal_index",
- &noreveal_index),
- GNUNET_PQ_result_spec_uint64 ("melt_serial_id",
- &rowid),
- GNUNET_PQ_result_spec_auto_from_type ("rc",
- &rc),
- GNUNET_PQ_result_spec_end
- };
- enum GNUNET_GenericReturnValue ret;
-
- if (GNUNET_OK !=
- GNUNET_PQ_extract_result (result,
- rs,
- i))
- {
- GNUNET_break (0);
- rsc->status = GNUNET_SYSERR;
- return;
- }
-
- ret = rsc->cb (rsc->cb_cls,
- rowid,
- &denom_pub,
- ac_isnull ? NULL : &h_age_commitment,
- &coin_pub,
- &coin_sig,
- &amount_with_fee,
- noreveal_index,
- &rc);
- GNUNET_PQ_cleanup_result (rs);
- if (GNUNET_OK != ret)
- break;
- }
-}
-
-
-/**
- * Select refresh sessions above @a serial_id in monotonically increasing
- * order.
- *
- * @param cls closure
- * @param serial_id highest serial ID to exclude (select strictly larger)
- * @param cb function to call on each result
- * @param cb_cls closure for @a cb
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_select_refreshes_above_serial_id (
- void *cls,
- uint64_t serial_id,
- TALER_EXCHANGEDB_RefreshesCallback cb,
- void *cb_cls)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_uint64 (&serial_id),
- GNUNET_PQ_query_param_end
- };
- struct RefreshsSerialContext rsc = {
- .cb = cb,
- .cb_cls = cb_cls,
- .pg = pg,
- .status = GNUNET_OK
- };
- enum GNUNET_DB_QueryStatus qs;
-
- qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
- "audit_get_refresh_commitments_incr",
- params,
- &refreshs_serial_helper_cb,
- &rsc);
- if (GNUNET_OK != rsc.status)
- return GNUNET_DB_STATUS_HARD_ERROR;
- return qs;
-}
-
-
-/**
- * Closure for #refunds_serial_helper_cb().
- */
-struct RefundsSerialContext
-{
-
- /**
- * Callback to call.
- */
- TALER_EXCHANGEDB_RefundCallback cb;
-
- /**
- * Closure for @e cb.
- */
- void *cb_cls;
-
- /**
- * Plugin context.
- */
- struct PostgresClosure *pg;
-
- /**
- * Status code, set to #GNUNET_SYSERR on hard errors.
- */
- enum GNUNET_GenericReturnValue status;
-};
-
-
-/**
- * Helper function to be called with the results of a SELECT statement
- * that has returned @a num_results results.
- *
- * @param cls closure of type `struct RefundsSerialContext`
- * @param result the postgres result
- * @param num_results the number of results in @a result
- */
-static void
-refunds_serial_helper_cb (void *cls,
- PGresult *result,
- unsigned int num_results)
-{
- struct RefundsSerialContext *rsc = cls;
- struct PostgresClosure *pg = rsc->pg;
-
- for (unsigned int i = 0; i<num_results; i++)
- {
- struct TALER_EXCHANGEDB_Refund refund;
- struct TALER_DenominationPublicKey denom_pub;
- uint64_t rowid;
- bool full_refund;
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_auto_from_type ("merchant_pub",
- &refund.details.merchant_pub),
- GNUNET_PQ_result_spec_auto_from_type ("merchant_sig",
- &refund.details.merchant_sig),
- GNUNET_PQ_result_spec_auto_from_type ("h_contract_terms",
- &refund.details.h_contract_terms),
- GNUNET_PQ_result_spec_uint64 ("rtransaction_id",
- &refund.details.rtransaction_id),
- TALER_PQ_result_spec_denom_pub ("denom_pub",
- &denom_pub),
- GNUNET_PQ_result_spec_auto_from_type ("coin_pub",
- &refund.coin.coin_pub),
- TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee",
- &refund.details.refund_amount),
- GNUNET_PQ_result_spec_uint64 ("refund_serial_id",
- &rowid),
- GNUNET_PQ_result_spec_end
- };
- enum GNUNET_GenericReturnValue ret;
-
- if (GNUNET_OK !=
- GNUNET_PQ_extract_result (result,
- rs,
- i))
- {
- GNUNET_break (0);
- rsc->status = GNUNET_SYSERR;
- return;
- }
- {
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_uint64 (&rowid),
- GNUNET_PQ_query_param_end
- };
- struct TALER_Amount amount_with_fee;
- uint64_t s_f;
- uint64_t s_v;
- struct GNUNET_PQ_ResultSpec rs2[] = {
- GNUNET_PQ_result_spec_uint64 ("s_v",
- &s_v),
- GNUNET_PQ_result_spec_uint64 ("s_f",
- &s_f),
- TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee",
- &amount_with_fee),
- GNUNET_PQ_result_spec_end
- };
- enum GNUNET_DB_QueryStatus qs;
-
- qs = GNUNET_PQ_eval_prepared_singleton_select (
- pg->conn,
- "test_refund_full",
- params,
- rs2);
- if (qs <= 0)
- {
- GNUNET_break (0);
- rsc->status = GNUNET_SYSERR;
- return;
- }
- /* normalize */
- s_v += s_f / TALER_AMOUNT_FRAC_BASE;
- s_f %= TALER_AMOUNT_FRAC_BASE;
- full_refund = (s_v >= amount_with_fee.value) &&
- (s_f >= amount_with_fee.fraction);
- }
- ret = rsc->cb (rsc->cb_cls,
- rowid,
- &denom_pub,
- &refund.coin.coin_pub,
- &refund.details.merchant_pub,
- &refund.details.merchant_sig,
- &refund.details.h_contract_terms,
- refund.details.rtransaction_id,
- full_refund,
- &refund.details.refund_amount);
- GNUNET_PQ_cleanup_result (rs);
- if (GNUNET_OK != ret)
- break;
- }
-}
-
-
-/**
- * Select refunds above @a serial_id in monotonically increasing
- * order.
- *
- * @param cls closure
- * @param serial_id highest serial ID to exclude (select strictly larger)
- * @param cb function to call on each result
- * @param cb_cls closure for @a cb
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_select_refunds_above_serial_id (
- void *cls,
- uint64_t serial_id,
- TALER_EXCHANGEDB_RefundCallback cb,
- void *cb_cls)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_uint64 (&serial_id),
- GNUNET_PQ_query_param_end
- };
- struct RefundsSerialContext rsc = {
- .cb = cb,
- .cb_cls = cb_cls,
- .pg = pg,
- .status = GNUNET_OK
- };
- enum GNUNET_DB_QueryStatus qs;
-
- qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
- "audit_get_refunds_incr",
- params,
- &refunds_serial_helper_cb,
- &rsc);
- if (GNUNET_OK != rsc.status)
- return GNUNET_DB_STATUS_HARD_ERROR;
- return qs;
-}
-
-
-/**
- * Closure for #reserves_in_serial_helper_cb().
- */
-struct ReservesInSerialContext
-{
-
- /**
- * Callback to call.
- */
- TALER_EXCHANGEDB_ReserveInCallback cb;
-
- /**
- * Closure for @e cb.
- */
- void *cb_cls;
-
- /**
- * Plugin context.
- */
- struct PostgresClosure *pg;
-
- /**
- * Status code, set to #GNUNET_SYSERR on hard errors.
- */
- enum GNUNET_GenericReturnValue status;
-};
-
-
-/**
- * Helper function to be called with the results of a SELECT statement
- * that has returned @a num_results results.
- *
- * @param cls closure of type `struct ReservesInSerialContext`
- * @param result the postgres result
- * @param num_results the number of results in @a result
- */
-static void
-reserves_in_serial_helper_cb (void *cls,
- PGresult *result,
- unsigned int num_results)
-{
- struct ReservesInSerialContext *risc = cls;
- struct PostgresClosure *pg = risc->pg;
-
- for (unsigned int i = 0; i<num_results; i++)
- {
- struct TALER_ReservePublicKeyP reserve_pub;
- struct TALER_Amount credit;
- char *sender_account_details;
- struct GNUNET_TIME_Timestamp execution_date;
- uint64_t rowid;
- uint64_t wire_reference;
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_auto_from_type ("reserve_pub",
- &reserve_pub),
- GNUNET_PQ_result_spec_uint64 ("wire_reference",
- &wire_reference),
- TALER_PQ_RESULT_SPEC_AMOUNT ("credit",
- &credit),
- GNUNET_PQ_result_spec_timestamp ("execution_date",
- &execution_date),
- GNUNET_PQ_result_spec_string ("sender_account_details",
- &sender_account_details),
- GNUNET_PQ_result_spec_uint64 ("reserve_in_serial_id",
- &rowid),
- GNUNET_PQ_result_spec_end
- };
- enum GNUNET_GenericReturnValue ret;
-
- if (GNUNET_OK !=
- GNUNET_PQ_extract_result (result,
- rs,
- i))
- {
- GNUNET_break (0);
- risc->status = GNUNET_SYSERR;
- return;
- }
- ret = risc->cb (risc->cb_cls,
- rowid,
- &reserve_pub,
- &credit,
- sender_account_details,
- wire_reference,
- execution_date);
- GNUNET_PQ_cleanup_result (rs);
- if (GNUNET_OK != ret)
- break;
- }
-}
-
-
-/**
- * Select inbound wire transfers into reserves_in above @a serial_id
- * in monotonically increasing order.
- *
- * @param cls closure
- * @param serial_id highest serial ID to exclude (select strictly larger)
- * @param cb function to call on each result
- * @param cb_cls closure for @a cb
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_select_reserves_in_above_serial_id (
- void *cls,
- uint64_t serial_id,
- TALER_EXCHANGEDB_ReserveInCallback cb,
- void *cb_cls)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_uint64 (&serial_id),
- GNUNET_PQ_query_param_end
- };
- struct ReservesInSerialContext risc = {
- .cb = cb,
- .cb_cls = cb_cls,
- .pg = pg,
- .status = GNUNET_OK
- };
- enum GNUNET_DB_QueryStatus qs;
-
- qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
- "audit_reserves_in_get_transactions_incr",
- params,
- &reserves_in_serial_helper_cb,
- &risc);
- if (GNUNET_OK != risc.status)
- return GNUNET_DB_STATUS_HARD_ERROR;
- return qs;
-}
-
-
-/**
- * Select inbound wire transfers into reserves_in above @a serial_id
- * in monotonically increasing order by account.
- *
- * @param cls closure
- * @param account_name name of the account to select by
- * @param serial_id highest serial ID to exclude (select strictly larger)
- * @param cb function to call on each result
- * @param cb_cls closure for @a cb
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_select_reserves_in_above_serial_id_by_account (
- void *cls,
- const char *account_name,
- uint64_t serial_id,
- TALER_EXCHANGEDB_ReserveInCallback cb,
- void *cb_cls)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_uint64 (&serial_id),
- GNUNET_PQ_query_param_string (account_name),
- GNUNET_PQ_query_param_end
- };
- struct ReservesInSerialContext risc = {
- .cb = cb,
- .cb_cls = cb_cls,
- .pg = pg,
- .status = GNUNET_OK
- };
- enum GNUNET_DB_QueryStatus qs;
-
- qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
- "audit_reserves_in_get_transactions_incr_by_account",
- params,
- &reserves_in_serial_helper_cb,
- &risc);
- if (GNUNET_OK != risc.status)
- return GNUNET_DB_STATUS_HARD_ERROR;
- return qs;
-}
-
-
-/**
- * Closure for #reserves_out_serial_helper_cb().
- */
-struct ReservesOutSerialContext
-{
-
- /**
- * Callback to call.
- */
- TALER_EXCHANGEDB_WithdrawCallback cb;
-
- /**
- * Closure for @e cb.
- */
- void *cb_cls;
-
- /**
- * Plugin context.
- */
- struct PostgresClosure *pg;
-
- /**
- * Status code, set to #GNUNET_SYSERR on hard errors.
- */
- enum GNUNET_GenericReturnValue status;
-};
-
-
-/**
- * Helper function to be called with the results of a SELECT statement
- * that has returned @a num_results results.
- *
- * @param cls closure of type `struct ReservesOutSerialContext`
- * @param result the postgres result
- * @param num_results the number of results in @a result
- */
-static void
-reserves_out_serial_helper_cb (void *cls,
- PGresult *result,
- unsigned int num_results)
-{
- struct ReservesOutSerialContext *rosc = cls;
- struct PostgresClosure *pg = rosc->pg;
-
- for (unsigned int i = 0; i<num_results; i++)
- {
- struct TALER_BlindedCoinHashP h_blind_ev;
- struct TALER_DenominationPublicKey denom_pub;
- struct TALER_ReservePublicKeyP reserve_pub;
- struct TALER_ReserveSignatureP reserve_sig;
- struct GNUNET_TIME_Timestamp execution_date;
- struct TALER_Amount amount_with_fee;
- uint64_t rowid;
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_auto_from_type ("h_blind_ev",
- &h_blind_ev),
- TALER_PQ_result_spec_denom_pub ("denom_pub",
- &denom_pub),
- 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_timestamp ("execution_date",
- &execution_date),
- TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee",
- &amount_with_fee),
- GNUNET_PQ_result_spec_uint64 ("reserve_out_serial_id",
- &rowid),
- GNUNET_PQ_result_spec_end
- };
- enum GNUNET_GenericReturnValue ret;
-
- if (GNUNET_OK !=
- GNUNET_PQ_extract_result (result,
- rs,
- i))
- {
- GNUNET_break (0);
- rosc->status = GNUNET_SYSERR;
- return;
- }
- ret = rosc->cb (rosc->cb_cls,
- rowid,
- &h_blind_ev,
- &denom_pub,
- &reserve_pub,
- &reserve_sig,
- execution_date,
- &amount_with_fee);
- GNUNET_PQ_cleanup_result (rs);
- if (GNUNET_OK != ret)
- break;
- }
-}
-
-
-/**
- * Select withdraw operations from reserves_out above @a serial_id
- * in monotonically increasing order.
- *
- * @param cls closure
- * @param serial_id highest serial ID to exclude (select strictly larger)
- * @param cb function to call on each result
- * @param cb_cls closure for @a cb
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_select_withdrawals_above_serial_id (
- void *cls,
- uint64_t serial_id,
- TALER_EXCHANGEDB_WithdrawCallback cb,
- void *cb_cls)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_uint64 (&serial_id),
- GNUNET_PQ_query_param_end
- };
- struct ReservesOutSerialContext rosc = {
- .cb = cb,
- .cb_cls = cb_cls,
- .pg = pg,
- .status = GNUNET_OK
- };
- enum GNUNET_DB_QueryStatus qs;
-
- qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
- "audit_get_reserves_out_incr",
- params,
- &reserves_out_serial_helper_cb,
- &rosc);
- if (GNUNET_OK != rosc.status)
- return GNUNET_DB_STATUS_HARD_ERROR;
- return qs;
-}
-
-
-/**
- * Closure for #wire_out_serial_helper_cb().
- */
-struct WireOutSerialContext
-{
-
- /**
- * Callback to call.
- */
- TALER_EXCHANGEDB_WireTransferOutCallback cb;
-
- /**
- * Closure for @e cb.
- */
- void *cb_cls;
-
- /**
- * Plugin context.
- */
- struct PostgresClosure *pg;
-
- /**
- * Status code, set to #GNUNET_SYSERR on hard errors.
- */
- int status;
-};
-
-
-/**
- * Helper function to be called with the results of a SELECT statement
- * that has returned @a num_results results.
- *
- * @param cls closure of type `struct WireOutSerialContext`
- * @param result the postgres result
- * @param num_results the number of results in @a result
- */
-static void
-wire_out_serial_helper_cb (void *cls,
- PGresult *result,
- unsigned int num_results)
-{
- struct WireOutSerialContext *wosc = cls;
- struct PostgresClosure *pg = wosc->pg;
-
- for (unsigned int i = 0; i<num_results; i++)
- {
- uint64_t rowid;
- struct GNUNET_TIME_Timestamp date;
- struct TALER_WireTransferIdentifierRawP wtid;
- char *payto_uri;
- struct TALER_Amount amount;
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_uint64 ("wireout_uuid",
- &rowid),
- GNUNET_PQ_result_spec_timestamp ("execution_date",
- &date),
- GNUNET_PQ_result_spec_auto_from_type ("wtid_raw",
- &wtid),
- GNUNET_PQ_result_spec_string ("payto_uri",
- &payto_uri),
- TALER_PQ_RESULT_SPEC_AMOUNT ("amount",
- &amount),
- GNUNET_PQ_result_spec_end
- };
- int ret;
-
- if (GNUNET_OK !=
- GNUNET_PQ_extract_result (result,
- rs,
- i))
- {
- GNUNET_break (0);
- wosc->status = GNUNET_SYSERR;
- return;
- }
- ret = wosc->cb (wosc->cb_cls,
- rowid,
- date,
- &wtid,
- payto_uri,
- &amount);
- GNUNET_PQ_cleanup_result (rs);
- if (GNUNET_OK != ret)
- break;
- }
-}
-
-
-/**
- * Function called to select all wire transfers the exchange
- * executed.
- *
- * @param cls closure
- * @param serial_id highest serial ID to exclude (select strictly larger)
- * @param cb function to call for ONE unfinished item
- * @param cb_cls closure for @a cb
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_select_wire_out_above_serial_id (
- void *cls,
- uint64_t serial_id,
- TALER_EXCHANGEDB_WireTransferOutCallback cb,
- void *cb_cls)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_uint64 (&serial_id),
- GNUNET_PQ_query_param_end
- };
- struct WireOutSerialContext wosc = {
- .cb = cb,
- .cb_cls = cb_cls,
- .pg = pg,
- .status = GNUNET_OK
- };
- enum GNUNET_DB_QueryStatus qs;
-
- qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
- "audit_get_wire_incr",
- params,
- &wire_out_serial_helper_cb,
- &wosc);
- if (GNUNET_OK != wosc.status)
- return GNUNET_DB_STATUS_HARD_ERROR;
- return qs;
-}
-
-
-/**
- * Function called to select all wire transfers the exchange
- * executed by account.
- *
- * @param cls closure
- * @param account_name account to select
- * @param serial_id highest serial ID to exclude (select strictly larger)
- * @param cb function to call for ONE unfinished item
- * @param cb_cls closure for @a cb
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_select_wire_out_above_serial_id_by_account (
- void *cls,
- const char *account_name,
- uint64_t serial_id,
- TALER_EXCHANGEDB_WireTransferOutCallback cb,
- void *cb_cls)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_uint64 (&serial_id),
- GNUNET_PQ_query_param_string (account_name),
- GNUNET_PQ_query_param_end
- };
- struct WireOutSerialContext wosc = {
- .cb = cb,
- .cb_cls = cb_cls,
- .pg = pg,
- .status = GNUNET_OK
- };
- enum GNUNET_DB_QueryStatus qs;
-
- qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
- "audit_get_wire_incr_by_account",
- params,
- &wire_out_serial_helper_cb,
- &wosc);
- if (GNUNET_OK != wosc.status)
- return GNUNET_DB_STATUS_HARD_ERROR;
- return qs;
-}
-
-
-/**
- * Closure for #recoup_serial_helper_cb().
- */
-struct RecoupSerialContext
-{
-
- /**
- * Callback to call.
- */
- TALER_EXCHANGEDB_RecoupCallback cb;
-
- /**
- * Closure for @e cb.
- */
- void *cb_cls;
-
- /**
- * Plugin context.
- */
- struct PostgresClosure *pg;
-
- /**
- * Status code, set to #GNUNET_SYSERR on hard errors.
- */
- enum GNUNET_GenericReturnValue status;
-};
-
-
-/**
- * Helper function to be called with the results of a SELECT statement
- * that has returned @a num_results results.
- *
- * @param cls closure of type `struct RecoupSerialContext`
- * @param result the postgres result
- * @param num_results the number of results in @a result
- */
-static void
-recoup_serial_helper_cb (void *cls,
- PGresult *result,
- unsigned int num_results)
-{
- struct RecoupSerialContext *psc = cls;
- struct PostgresClosure *pg = psc->pg;
-
- for (unsigned int i = 0; i<num_results; i++)
- {
- uint64_t rowid;
- struct TALER_ReservePublicKeyP reserve_pub;
- struct TALER_CoinPublicInfo coin;
- struct TALER_CoinSpendSignatureP coin_sig;
- union TALER_DenominationBlindingKeyP coin_blind;
- struct TALER_Amount amount;
- struct TALER_DenominationPublicKey denom_pub;
- struct TALER_BlindedCoinHashP h_blind_ev;
- struct GNUNET_TIME_Timestamp timestamp;
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_uint64 ("recoup_uuid",
- &rowid),
- GNUNET_PQ_result_spec_timestamp ("recoup_timestamp",
- &timestamp),
- GNUNET_PQ_result_spec_auto_from_type ("reserve_pub",
- &reserve_pub),
- GNUNET_PQ_result_spec_auto_from_type ("coin_pub",
- &coin.coin_pub),
- TALER_PQ_result_spec_denom_pub ("denom_pub",
- &denom_pub),
- GNUNET_PQ_result_spec_auto_from_type ("coin_sig",
- &coin_sig),
- GNUNET_PQ_result_spec_auto_from_type ("coin_blind",
- &coin_blind),
- GNUNET_PQ_result_spec_auto_from_type ("h_blind_ev",
- &h_blind_ev),
- GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash",
- &coin.denom_pub_hash),
- GNUNET_PQ_result_spec_allow_null (
- GNUNET_PQ_result_spec_auto_from_type ("age_commitment_hash",
- &coin.h_age_commitment),
- &coin.no_age_commitment),
- TALER_PQ_result_spec_denom_sig ("denom_sig",
- &coin.denom_sig),
- TALER_PQ_RESULT_SPEC_AMOUNT ("amount",
- &amount),
- GNUNET_PQ_result_spec_end
- };
- int ret;
-
- if (GNUNET_OK !=
- GNUNET_PQ_extract_result (result,
- rs,
- i))
- {
- GNUNET_break (0);
- psc->status = GNUNET_SYSERR;
- return;
- }
- ret = psc->cb (psc->cb_cls,
- rowid,
- timestamp,
- &amount,
- &reserve_pub,
- &coin,
- &denom_pub,
- &coin_sig,
- &coin_blind);
- GNUNET_PQ_cleanup_result (rs);
- if (GNUNET_OK != ret)
- break;
- }
-}
-
-
-/**
- * Function called to select recoup requests the exchange
- * received, ordered by serial ID (monotonically increasing).
- *
- * @param cls closure
- * @param serial_id lowest serial ID to include (select larger or equal)
- * @param cb function to call for ONE unfinished item
- * @param cb_cls closure for @a cb
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_select_recoup_above_serial_id (
- void *cls,
- uint64_t serial_id,
- TALER_EXCHANGEDB_RecoupCallback cb,
- void *cb_cls)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_uint64 (&serial_id),
- GNUNET_PQ_query_param_end
- };
- struct RecoupSerialContext psc = {
- .cb = cb,
- .cb_cls = cb_cls,
- .pg = pg,
- .status = GNUNET_OK
- };
- enum GNUNET_DB_QueryStatus qs;
-
- qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
- "recoup_get_incr",
- params,
- &recoup_serial_helper_cb,
- &psc);
- if (GNUNET_OK != psc.status)
- return GNUNET_DB_STATUS_HARD_ERROR;
- return qs;
-}
-
-
-/**
- * Closure for #recoup_refresh_serial_helper_cb().
- */
-struct RecoupRefreshSerialContext
-{
-
- /**
- * Callback to call.
- */
- TALER_EXCHANGEDB_RecoupRefreshCallback cb;
-
- /**
- * Closure for @e cb.
- */
- void *cb_cls;
-
- /**
- * Plugin context.
- */
- struct PostgresClosure *pg;
-
- /**
- * Status code, set to #GNUNET_SYSERR on hard errors.
- */
- enum GNUNET_GenericReturnValue status;
-};
-
-
-/**
- * Helper function to be called with the results of a SELECT statement
- * that has returned @a num_results results.
- *
- * @param cls closure of type `struct RecoupRefreshSerialContext`
- * @param result the postgres result
- * @param num_results the number of results in @a result
- */
-static void
-recoup_refresh_serial_helper_cb (void *cls,
- PGresult *result,
- unsigned int num_results)
-{
- struct RecoupRefreshSerialContext *psc = cls;
- struct PostgresClosure *pg = psc->pg;
-
- for (unsigned int i = 0; i<num_results; i++)
- {
- uint64_t rowid;
- struct TALER_CoinSpendPublicKeyP old_coin_pub;
- struct TALER_CoinPublicInfo coin;
- struct TALER_CoinSpendSignatureP coin_sig;
- union TALER_DenominationBlindingKeyP coin_blind;
- struct TALER_DenominationPublicKey denom_pub;
- struct TALER_DenominationHashP old_denom_pub_hash;
- struct TALER_Amount amount;
- struct TALER_BlindedCoinHashP h_blind_ev;
- struct GNUNET_TIME_Timestamp timestamp;
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_uint64 ("recoup_refresh_uuid",
- &rowid),
- GNUNET_PQ_result_spec_timestamp ("recoup_timestamp",
- &timestamp),
- GNUNET_PQ_result_spec_auto_from_type ("old_coin_pub",
- &old_coin_pub),
- GNUNET_PQ_result_spec_auto_from_type ("old_denom_pub_hash",
- &old_denom_pub_hash),
- GNUNET_PQ_result_spec_auto_from_type ("coin_pub",
- &coin.coin_pub),
- GNUNET_PQ_result_spec_auto_from_type ("coin_sig",
- &coin_sig),
- GNUNET_PQ_result_spec_auto_from_type ("coin_blind",
- &coin_blind),
- TALER_PQ_result_spec_denom_pub ("denom_pub",
- &denom_pub),
- GNUNET_PQ_result_spec_auto_from_type ("h_blind_ev",
- &h_blind_ev),
- GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash",
- &coin.denom_pub_hash),
- GNUNET_PQ_result_spec_allow_null (
- GNUNET_PQ_result_spec_auto_from_type ("age_commitment_hash",
- &coin.h_age_commitment),
- &coin.no_age_commitment),
- TALER_PQ_result_spec_denom_sig ("denom_sig",
- &coin.denom_sig),
- TALER_PQ_RESULT_SPEC_AMOUNT ("amount",
- &amount),
- GNUNET_PQ_result_spec_end
- };
- enum GNUNET_GenericReturnValue ret;
-
- if (GNUNET_OK !=
- GNUNET_PQ_extract_result (result,
- rs,
- i))
- {
- GNUNET_break (0);
- psc->status = GNUNET_SYSERR;
- return;
- }
- ret = psc->cb (psc->cb_cls,
- rowid,
- timestamp,
- &amount,
- &old_coin_pub,
- &old_denom_pub_hash,
- &coin,
- &denom_pub,
- &coin_sig,
- &coin_blind);
- GNUNET_PQ_cleanup_result (rs);
- if (GNUNET_OK != ret)
- break;
- }
-}
-
-
-/**
- * Function called to select recoup requests the exchange received for
- * refreshed coins, ordered by serial ID (monotonically increasing).
- *
- * @param cls closure
- * @param serial_id lowest serial ID to include (select larger or equal)
- * @param cb function to call for ONE unfinished item
- * @param cb_cls closure for @a cb
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_select_recoup_refresh_above_serial_id (
- void *cls,
- uint64_t serial_id,
- TALER_EXCHANGEDB_RecoupRefreshCallback cb,
- void *cb_cls)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_uint64 (&serial_id),
- GNUNET_PQ_query_param_end
- };
- struct RecoupRefreshSerialContext psc = {
- .cb = cb,
- .cb_cls = cb_cls,
- .pg = pg,
- .status = GNUNET_OK
- };
- enum GNUNET_DB_QueryStatus qs;
-
- qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
- "recoup_refresh_get_incr",
- params,
- &recoup_refresh_serial_helper_cb,
- &psc);
- if (GNUNET_OK != psc.status)
- return GNUNET_DB_STATUS_HARD_ERROR;
- return qs;
-}
-
-
-/**
- * Closure for #reserve_closed_serial_helper_cb().
- */
-struct ReserveClosedSerialContext
-{
-
- /**
- * Callback to call.
- */
- TALER_EXCHANGEDB_ReserveClosedCallback cb;
-
- /**
- * Closure for @e cb.
- */
- void *cb_cls;
-
- /**
- * Plugin's context.
- */
- struct PostgresClosure *pg;
-
- /**
- * Status code, set to #GNUNET_SYSERR on hard errors.
- */
- enum GNUNET_GenericReturnValue status;
-};
-
-
-/**
- * Helper function to be called with the results of a SELECT statement
- * that has returned @a num_results results.
- *
- * @param cls closure of type `struct ReserveClosedSerialContext`
- * @param result the postgres result
- * @param num_results the number of results in @a result
- */
-static void
-reserve_closed_serial_helper_cb (void *cls,
- PGresult *result,
- unsigned int num_results)
-{
- struct ReserveClosedSerialContext *rcsc = cls;
- struct PostgresClosure *pg = rcsc->pg;
-
- for (unsigned int i = 0; i<num_results; i++)
- {
- uint64_t rowid;
- struct TALER_ReservePublicKeyP reserve_pub;
- char *receiver_account;
- struct TALER_WireTransferIdentifierRawP wtid;
- struct TALER_Amount amount_with_fee;
- struct TALER_Amount closing_fee;
- struct GNUNET_TIME_Timestamp execution_date;
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_uint64 ("close_uuid",
- &rowid),
- GNUNET_PQ_result_spec_auto_from_type ("reserve_pub",
- &reserve_pub),
- GNUNET_PQ_result_spec_timestamp ("execution_date",
- &execution_date),
- GNUNET_PQ_result_spec_auto_from_type ("wtid",
- &wtid),
- GNUNET_PQ_result_spec_string ("receiver_account",
- &receiver_account),
- TALER_PQ_RESULT_SPEC_AMOUNT ("amount",
- &amount_with_fee),
- TALER_PQ_RESULT_SPEC_AMOUNT ("closing_fee",
- &closing_fee),
- GNUNET_PQ_result_spec_end
- };
- enum GNUNET_GenericReturnValue ret;
-
- if (GNUNET_OK !=
- GNUNET_PQ_extract_result (result,
- rs,
- i))
- {
- GNUNET_break (0);
- rcsc->status = GNUNET_SYSERR;
- return;
- }
- ret = rcsc->cb (rcsc->cb_cls,
- rowid,
- execution_date,
- &amount_with_fee,
- &closing_fee,
- &reserve_pub,
- receiver_account,
- &wtid);
- GNUNET_PQ_cleanup_result (rs);
- if (GNUNET_OK != ret)
- break;
- }
-}
-
-
-/**
- * Function called to select reserve close operations the aggregator
- * triggered, ordered by serial ID (monotonically increasing).
- *
- * @param cls closure
- * @param serial_id lowest serial ID to include (select larger or equal)
- * @param cb function to call for ONE unfinished item
- * @param cb_cls closure for @a cb
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_select_reserve_closed_above_serial_id (
- void *cls,
- uint64_t serial_id,
- TALER_EXCHANGEDB_ReserveClosedCallback cb,
- void *cb_cls)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_uint64 (&serial_id),
- GNUNET_PQ_query_param_end
- };
- struct ReserveClosedSerialContext rcsc = {
- .cb = cb,
- .cb_cls = cb_cls,
- .pg = pg,
- .status = GNUNET_OK
- };
- enum GNUNET_DB_QueryStatus qs;
-
- qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
- "reserves_close_get_incr",
- params,
- &reserve_closed_serial_helper_cb,
- &rcsc);
- if (GNUNET_OK != rcsc.status)
- return GNUNET_DB_STATUS_HARD_ERROR;
- return qs;
-}
-
-
-/**
- * Obtain information about which reserve a coin was generated
- * from given the hash of the blinded coin.
- *
- * @param cls closure
- * @param bch hash that uniquely identifies the withdraw request
- * @param[out] reserve_pub set to information about the reserve (on success only)
- * @param[out] reserve_out_serial_id set to row of the @a h_blind_ev in reserves_out
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_get_reserve_by_h_blind (
- void *cls,
- const struct TALER_BlindedCoinHashP *bch,
- struct TALER_ReservePublicKeyP *reserve_pub,
- uint64_t *reserve_out_serial_id)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (bch),
- GNUNET_PQ_query_param_end
- };
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_auto_from_type ("reserve_pub",
- reserve_pub),
- GNUNET_PQ_result_spec_uint64 ("reserve_out_serial_id",
- reserve_out_serial_id),
- GNUNET_PQ_result_spec_end
- };
-
- return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "reserve_by_h_blind",
- params,
- rs);
-}
-
-
-/**
- * Obtain information about which old coin a coin was refreshed
- * given the hash of the blinded (fresh) coin.
- *
- * @param cls closure
- * @param h_blind_ev hash of the blinded coin
- * @param[out] old_coin_pub set to information about the old coin (on success only)
- * @param[out] rrc_serial set to serial number of the entry in the database
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_get_old_coin_by_h_blind (
- void *cls,
- const struct TALER_BlindedCoinHashP *h_blind_ev,
- struct TALER_CoinSpendPublicKeyP *old_coin_pub,
- uint64_t *rrc_serial)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (h_blind_ev),
- GNUNET_PQ_query_param_end
- };
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_auto_from_type ("old_coin_pub",
- old_coin_pub),
- GNUNET_PQ_result_spec_uint64 ("rrc_serial",
- rrc_serial),
- GNUNET_PQ_result_spec_end
- };
-
- return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "old_coin_by_h_blind",
- params,
- rs);
-}
-
-
-/**
- * Store information that a denomination key was revoked
- * in the database.
- *
- * @param cls closure
- * @param denom_pub_hash hash of the revoked denomination key
- * @param master_sig signature affirming the revocation
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_insert_denomination_revocation (
- void *cls,
- const struct TALER_DenominationHashP *denom_pub_hash,
- const struct TALER_MasterSignatureP *master_sig)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (denom_pub_hash),
- GNUNET_PQ_query_param_auto_from_type (master_sig),
- GNUNET_PQ_query_param_end
- };
-
- return GNUNET_PQ_eval_prepared_non_select (pg->conn,
- "denomination_revocation_insert",
- params);
-}
-
-
-/**
- * Obtain information about a denomination key's revocation from
- * the database.
- *
- * @param cls closure
- * @param denom_pub_hash hash of the revoked denomination key
- * @param[out] master_sig signature affirming the revocation
- * @param[out] rowid row where the information is stored
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_get_denomination_revocation (
- void *cls,
- const struct TALER_DenominationHashP *denom_pub_hash,
- struct TALER_MasterSignatureP *master_sig,
- uint64_t *rowid)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (denom_pub_hash),
- GNUNET_PQ_query_param_end
- };
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_auto_from_type ("master_sig",
- master_sig),
- GNUNET_PQ_result_spec_uint64 ("denom_revocations_serial_id",
- rowid),
- GNUNET_PQ_result_spec_end
- };
-
- return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "denomination_revocation_get",
- params,
- rs);
-}
-
-
-/**
- * Closure for #missing_wire_cb().
- */
-struct MissingWireContext
-{
- /**
- * Function to call per result.
- */
- TALER_EXCHANGEDB_WireMissingCallback cb;
-
- /**
- * Closure for @e cb.
- */
- void *cb_cls;
-
- /**
- * Plugin context.
- */
- struct PostgresClosure *pg;
-
- /**
- * Set to #GNUNET_SYSERR on error.
- */
- enum GNUNET_GenericReturnValue status;
-};
-
-
-/**
- * Invoke the callback for each result.
- *
- * @param cls a `struct MissingWireContext *`
- * @param result SQL result
- * @param num_results number of rows in @a result
- */
-static void
-missing_wire_cb (void *cls,
- PGresult *result,
- unsigned int num_results)
-{
- struct MissingWireContext *mwc = cls;
- struct PostgresClosure *pg = mwc->pg;
-
- while (0 < num_results)
- {
- uint64_t rowid;
- struct TALER_CoinSpendPublicKeyP coin_pub;
- struct TALER_Amount amount;
- char *payto_uri;
- struct GNUNET_TIME_Timestamp deadline;
- bool done;
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_uint64 ("deposit_serial_id",
- &rowid),
- GNUNET_PQ_result_spec_auto_from_type ("coin_pub",
- &coin_pub),
- TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee",
- &amount),
- GNUNET_PQ_result_spec_string ("payto_uri",
- &payto_uri),
- GNUNET_PQ_result_spec_timestamp ("wire_deadline",
- &deadline),
- GNUNET_PQ_result_spec_bool ("done",
- &done),
- GNUNET_PQ_result_spec_end
- };
-
- if (GNUNET_OK !=
- GNUNET_PQ_extract_result (result,
- rs,
- --num_results))
- {
- GNUNET_break (0);
- mwc->status = GNUNET_SYSERR;
- return;
- }
- mwc->cb (mwc->cb_cls,
- rowid,
- &coin_pub,
- &amount,
- payto_uri,
- deadline,
- done);
- GNUNET_PQ_cleanup_result (rs);
- }
-}
-
-
-/**
- * Select all of those deposits in the database for which we do
- * not have a wire transfer (or a refund) and which should have
- * been deposited between @a start_date and @a end_date.
- *
- * @param cls closure
- * @param start_date lower bound on the requested wire execution date
- * @param end_date upper bound on the requested wire execution date
- * @param cb function to call on all such deposits
- * @param cb_cls closure for @a cb
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_select_deposits_missing_wire (void *cls,
- struct GNUNET_TIME_Timestamp start_date,
- struct GNUNET_TIME_Timestamp end_date,
- TALER_EXCHANGEDB_WireMissingCallback cb,
- void *cb_cls)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_timestamp (&start_date),
- GNUNET_PQ_query_param_timestamp (&end_date),
- GNUNET_PQ_query_param_end
- };
- struct MissingWireContext mwc = {
- .cb = cb,
- .cb_cls = cb_cls,
- .pg = pg,
- .status = GNUNET_OK
- };
- enum GNUNET_DB_QueryStatus qs;
-
- qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
- "deposits_get_overdue",
- params,
- &missing_wire_cb,
- &mwc);
- if (GNUNET_OK != mwc.status)
- return GNUNET_DB_STATUS_HARD_ERROR;
- return qs;
-}
-
-
-/**
- * Check the last date an auditor was modified.
- *
- * @param cls closure
- * @param auditor_pub key to look up information for
- * @param[out] last_date last modification date to auditor status
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_lookup_auditor_timestamp (
- void *cls,
- const struct TALER_AuditorPublicKeyP *auditor_pub,
- struct GNUNET_TIME_Timestamp *last_date)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (auditor_pub),
- GNUNET_PQ_query_param_end
- };
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_timestamp ("last_change",
- last_date),
- GNUNET_PQ_result_spec_end
- };
-
- return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "lookup_auditor_timestamp",
- params,
- rs);
-}
-
-
-/**
- * Lookup current state of an auditor.
- *
- * @param cls closure
- * @param auditor_pub key to look up information for
- * @param[out] auditor_url set to the base URL of the auditor's REST API; memory to be
- * released by the caller!
- * @param[out] enabled set if the auditor is currently in use
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_lookup_auditor_status (
- void *cls,
- const struct TALER_AuditorPublicKeyP *auditor_pub,
- char **auditor_url,
- bool *enabled)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (auditor_pub),
- GNUNET_PQ_query_param_end
- };
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_string ("auditor_url",
- auditor_url),
- GNUNET_PQ_result_spec_bool ("is_active",
- enabled),
- GNUNET_PQ_result_spec_end
- };
-
- return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "lookup_auditor_status",
- params,
- rs);
-}
-
-
-/**
- * Insert information about an auditor that will audit this exchange.
- *
- * @param cls closure
- * @param auditor_pub key of the auditor
- * @param auditor_url base URL of the auditor's REST service
- * @param auditor_name name of the auditor (for humans)
- * @param start_date date when the auditor was added by the offline system
- * (only to be used for replay detection)
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_insert_auditor (void *cls,
- const struct TALER_AuditorPublicKeyP *auditor_pub,
- const char *auditor_url,
- const char *auditor_name,
- struct GNUNET_TIME_Timestamp start_date)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (auditor_pub),
- GNUNET_PQ_query_param_string (auditor_name),
- GNUNET_PQ_query_param_string (auditor_url),
- GNUNET_PQ_query_param_timestamp (&start_date),
- GNUNET_PQ_query_param_end
- };
-
- return GNUNET_PQ_eval_prepared_non_select (pg->conn,
- "insert_auditor",
- params);
-}
-
-
-/**
- * Update information about an auditor that will audit this exchange.
- *
- * @param cls closure
- * @param auditor_pub key of the auditor (primary key for the existing record)
- * @param auditor_url base URL of the auditor's REST service, to be updated
- * @param auditor_name name of the auditor (for humans)
- * @param change_date date when the auditor status was last changed
- * (only to be used for replay detection)
- * @param enabled true to enable, false to disable
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_update_auditor (void *cls,
- const struct TALER_AuditorPublicKeyP *auditor_pub,
- const char *auditor_url,
- const char *auditor_name,
- struct GNUNET_TIME_Timestamp change_date,
- bool enabled)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (auditor_pub),
- GNUNET_PQ_query_param_string (auditor_url),
- GNUNET_PQ_query_param_string (auditor_name),
- GNUNET_PQ_query_param_bool (enabled),
- GNUNET_PQ_query_param_timestamp (&change_date),
- GNUNET_PQ_query_param_end
- };
-
- return GNUNET_PQ_eval_prepared_non_select (pg->conn,
- "update_auditor",
- params);
-}
-
-
-/**
- * Check the last date an exchange wire account was modified.
- *
- * @param cls closure
- * @param payto_uri key to look up information for
- * @param[out] last_date last modification date to auditor status
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_lookup_wire_timestamp (void *cls,
- const char *payto_uri,
- struct GNUNET_TIME_Timestamp *last_date)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_string (payto_uri),
- GNUNET_PQ_query_param_end
- };
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_timestamp ("last_change",
- last_date),
- GNUNET_PQ_result_spec_end
- };
-
- return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "lookup_wire_timestamp",
- params,
- rs);
-}
-
-
-/**
- * Insert information about an wire account used by this exchange.
- *
- * @param cls closure
- * @param payto_uri wire account of the exchange
- * @param start_date date when the account was added by the offline system
- * (only to be used for replay detection)
- * @param master_sig public signature affirming the existence of the account,
- * must be of purpose #TALER_SIGNATURE_MASTER_WIRE_DETAILS
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_insert_wire (void *cls,
- const char *payto_uri,
- struct GNUNET_TIME_Timestamp start_date,
- const struct TALER_MasterSignatureP *master_sig)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_string (payto_uri),
- GNUNET_PQ_query_param_auto_from_type (master_sig),
- GNUNET_PQ_query_param_timestamp (&start_date),
- GNUNET_PQ_query_param_end
- };
-
- return GNUNET_PQ_eval_prepared_non_select (pg->conn,
- "insert_wire",
- params);
-}
-
-
-/**
- * Update information about a wire account of the exchange.
- *
- * @param cls closure
- * @param payto_uri account the update is about
- * @param change_date date when the account status was last changed
- * (only to be used for replay detection)
- * @param enabled true to enable, false to disable (the actual change)
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_update_wire (void *cls,
- const char *payto_uri,
- struct GNUNET_TIME_Timestamp change_date,
- bool enabled)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_string (payto_uri),
- GNUNET_PQ_query_param_bool (enabled),
- GNUNET_PQ_query_param_timestamp (&change_date),
- GNUNET_PQ_query_param_end
- };
-
- return GNUNET_PQ_eval_prepared_non_select (pg->conn,
- "update_wire",
- params);
-}
-
-
-/**
- * Closure for #get_wire_accounts_cb().
- */
-struct GetWireAccountsContext
-{
- /**
- * Function to call per result.
- */
- TALER_EXCHANGEDB_WireAccountCallback cb;
-
- /**
- * Closure for @e cb.
- */
- void *cb_cls;
-
- /**
- * Flag set to #GNUNET_OK as long as everything is fine.
- */
- enum GNUNET_GenericReturnValue status;
-
-};
-
-
-/**
- * Invoke the callback for each result.
- *
- * @param cls a `struct MissingWireContext *`
- * @param result SQL result
- * @param num_results number of rows in @a result
- */
-static void
-get_wire_accounts_cb (void *cls,
- PGresult *result,
- unsigned int num_results)
-{
- struct GetWireAccountsContext *ctx = cls;
-
- for (unsigned int i = 0; i < num_results; i++)
- {
- char *payto_uri;
- struct TALER_MasterSignatureP master_sig;
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_string ("payto_uri",
- &payto_uri),
- GNUNET_PQ_result_spec_auto_from_type ("master_sig",
- &master_sig),
- GNUNET_PQ_result_spec_end
- };
-
- if (GNUNET_OK !=
- GNUNET_PQ_extract_result (result,
- rs,
- i))
- {
- GNUNET_break (0);
- ctx->status = GNUNET_SYSERR;
- return;
- }
- ctx->cb (ctx->cb_cls,
- payto_uri,
- &master_sig);
- GNUNET_PQ_cleanup_result (rs);
- }
-}
-
-
-/**
- * Obtain information about the enabled wire accounts of the exchange.
- *
- * @param cls closure
- * @param cb function to call on each account
- * @param cb_cls closure for @a cb
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_get_wire_accounts (void *cls,
- TALER_EXCHANGEDB_WireAccountCallback cb,
- void *cb_cls)
-{
- struct PostgresClosure *pg = cls;
- struct GetWireAccountsContext ctx = {
- .cb = cb,
- .cb_cls = cb_cls,
- .status = GNUNET_OK
- };
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_end
- };
- enum GNUNET_DB_QueryStatus qs;
-
- qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
- "get_wire_accounts",
- params,
- &get_wire_accounts_cb,
- &ctx);
- if (GNUNET_OK != ctx.status)
- return GNUNET_DB_STATUS_HARD_ERROR;
- return qs;
-
-}
-
-
-/**
- * Closure for #get_wire_fees_cb().
- */
-struct GetWireFeesContext
-{
- /**
- * Function to call per result.
- */
- TALER_EXCHANGEDB_WireFeeCallback cb;
-
- /**
- * Closure for @e cb.
- */
- void *cb_cls;
-
- /**
- * Plugin context.
- */
- struct PostgresClosure *pg;
-
- /**
- * Flag set to #GNUNET_OK as long as everything is fine.
- */
- enum GNUNET_GenericReturnValue status;
-
-};
-
-
-/**
- * Invoke the callback for each result.
- *
- * @param cls a `struct MissingWireContext *`
- * @param result SQL result
- * @param num_results number of rows in @a result
- */
-static void
-get_wire_fees_cb (void *cls,
- PGresult *result,
- unsigned int num_results)
-{
- struct GetWireFeesContext *ctx = cls;
- struct PostgresClosure *pg = ctx->pg;
-
- for (unsigned int i = 0; i < num_results; i++)
- {
- struct TALER_MasterSignatureP master_sig;
- struct TALER_WireFeeSet fees;
- struct GNUNET_TIME_Timestamp start_date;
- struct GNUNET_TIME_Timestamp end_date;
- struct GNUNET_PQ_ResultSpec rs[] = {
- TALER_PQ_RESULT_SPEC_AMOUNT ("wire_fee",
- &fees.wire),
- TALER_PQ_RESULT_SPEC_AMOUNT ("closing_fee",
- &fees.closing),
- TALER_PQ_RESULT_SPEC_AMOUNT ("wad_fee",
- &fees.wad),
- GNUNET_PQ_result_spec_timestamp ("start_date",
- &start_date),
- GNUNET_PQ_result_spec_timestamp ("end_date",
- &end_date),
- GNUNET_PQ_result_spec_auto_from_type ("master_sig",
- &master_sig),
- GNUNET_PQ_result_spec_end
- };
-
- if (GNUNET_OK !=
- GNUNET_PQ_extract_result (result,
- rs,
- i))
- {
- GNUNET_break (0);
- ctx->status = GNUNET_SYSERR;
- return;
- }
- ctx->cb (ctx->cb_cls,
- &fees,
- start_date,
- end_date,
- &master_sig);
- GNUNET_PQ_cleanup_result (rs);
- }
-}
-
-
-/**
- * Obtain information about the fee structure of the exchange for
- * a given @a wire_method
- *
- * @param cls closure
- * @param wire_method which wire method to obtain fees for
- * @param cb function to call on each account
- * @param cb_cls closure for @a cb
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_get_wire_fees (void *cls,
- const char *wire_method,
- TALER_EXCHANGEDB_WireFeeCallback cb,
- void *cb_cls)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_string (wire_method),
- GNUNET_PQ_query_param_end
- };
- struct GetWireFeesContext ctx = {
- .cb = cb,
- .cb_cls = cb_cls,
- .pg = pg,
- .status = GNUNET_OK
- };
- enum GNUNET_DB_QueryStatus qs;
-
- qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
- "get_wire_fees",
- params,
- &get_wire_fees_cb,
- &ctx);
- if (GNUNET_OK != ctx.status)
- return GNUNET_DB_STATUS_HARD_ERROR;
- return qs;
-}
-
-
-/**
- * Store information about a revoked online signing key.
- *
- * @param cls closure
- * @param exchange_pub exchange online signing key that was revoked
- * @param master_sig signature affirming the revocation
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_insert_signkey_revocation (
- void *cls,
- const struct TALER_ExchangePublicKeyP *exchange_pub,
- const struct TALER_MasterSignatureP *master_sig)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (exchange_pub),
- GNUNET_PQ_query_param_auto_from_type (master_sig),
- GNUNET_PQ_query_param_end
- };
-
- return GNUNET_PQ_eval_prepared_non_select (pg->conn,
- "insert_signkey_revocation",
- params);
-}
-
-
-/**
- * Obtain information about a revoked online signing key.
- *
- * @param cls closure
- * @param exchange_pub exchange online signing key
- * @param[out] master_sig set to signature affirming the revocation (if revoked)
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_lookup_signkey_revocation (
- void *cls,
- const struct TALER_ExchangePublicKeyP *exchange_pub,
- struct TALER_MasterSignatureP *master_sig)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (exchange_pub),
- GNUNET_PQ_query_param_end
- };
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_auto_from_type ("master_sig",
- master_sig),
- GNUNET_PQ_result_spec_end
- };
-
- return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "lookup_signkey_revocation",
- params,
- rs);
-}
-
-
-/**
- * Lookup information about current denomination key.
- *
- * @param cls closure
- * @param h_denom_pub hash of the denomination public key
- * @param[out] meta set to various meta data about the key
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_lookup_denomination_key (
- void *cls,
- const struct TALER_DenominationHashP *h_denom_pub,
- struct TALER_EXCHANGEDB_DenominationKeyMetaData *meta)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (h_denom_pub),
- GNUNET_PQ_query_param_end
- };
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_timestamp ("valid_from",
- &meta->start),
- GNUNET_PQ_result_spec_timestamp ("expire_withdraw",
- &meta->expire_withdraw),
- GNUNET_PQ_result_spec_timestamp ("expire_deposit",
- &meta->expire_deposit),
- GNUNET_PQ_result_spec_timestamp ("expire_legal",
- &meta->expire_legal),
- TALER_PQ_RESULT_SPEC_AMOUNT ("coin",
- &meta->value),
- TALER_PQ_RESULT_SPEC_AMOUNT ("fee_withdraw",
- &meta->fees.withdraw),
- TALER_PQ_RESULT_SPEC_AMOUNT ("fee_deposit",
- &meta->fees.deposit),
- TALER_PQ_RESULT_SPEC_AMOUNT ("fee_refresh",
- &meta->fees.refresh),
- TALER_PQ_RESULT_SPEC_AMOUNT ("fee_refund",
- &meta->fees.refund),
- GNUNET_PQ_result_spec_uint32 ("age_mask",
- &meta->age_mask.bits),
- GNUNET_PQ_result_spec_end
- };
-
- return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "lookup_denomination_key",
- params,
- rs);
-}
-
-
-/**
- * Activate denomination key, turning it into a "current" or "valid"
- * denomination key by adding the master signature.
- *
- * @param cls closure
- * @param h_denom_pub hash of the denomination public key
- * @param denom_pub the actual denomination key
- * @param meta meta data about the denomination
- * @param master_sig master signature to add
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_add_denomination_key (
- void *cls,
- const struct TALER_DenominationHashP *h_denom_pub,
- const struct TALER_DenominationPublicKey *denom_pub,
- const struct TALER_EXCHANGEDB_DenominationKeyMetaData *meta,
- const struct TALER_MasterSignatureP *master_sig)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam iparams[] = {
- GNUNET_PQ_query_param_auto_from_type (h_denom_pub),
- TALER_PQ_query_param_denom_pub (denom_pub),
- GNUNET_PQ_query_param_auto_from_type (master_sig),
- GNUNET_PQ_query_param_timestamp (&meta->start),
- GNUNET_PQ_query_param_timestamp (&meta->expire_withdraw),
- GNUNET_PQ_query_param_timestamp (&meta->expire_deposit),
- GNUNET_PQ_query_param_timestamp (&meta->expire_legal),
- TALER_PQ_query_param_amount (&meta->value),
- TALER_PQ_query_param_amount (&meta->fees.withdraw),
- TALER_PQ_query_param_amount (&meta->fees.deposit),
- TALER_PQ_query_param_amount (&meta->fees.refresh),
- TALER_PQ_query_param_amount (&meta->fees.refund),
- GNUNET_PQ_query_param_uint32 (&meta->age_mask.bits),
- GNUNET_PQ_query_param_end
- };
-
- /* Sanity check: ensure fees match coin currency */
- GNUNET_assert (GNUNET_YES ==
- TALER_denom_fee_check_currency (meta->value.currency,
- &meta->fees));
- return GNUNET_PQ_eval_prepared_non_select (pg->conn,
- "denomination_insert",
- iparams);
-}
-
-
-/**
- * Add signing key.
- *
- * @param cls closure
- * @param exchange_pub the exchange online signing public key
- * @param meta meta data about @a exchange_pub
- * @param master_sig master signature to add
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_activate_signing_key (
- void *cls,
- const struct TALER_ExchangePublicKeyP *exchange_pub,
- const struct TALER_EXCHANGEDB_SignkeyMetaData *meta,
- const struct TALER_MasterSignatureP *master_sig)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam iparams[] = {
- GNUNET_PQ_query_param_auto_from_type (exchange_pub),
- GNUNET_PQ_query_param_timestamp (&meta->start),
- GNUNET_PQ_query_param_timestamp (&meta->expire_sign),
- GNUNET_PQ_query_param_timestamp (&meta->expire_legal),
- GNUNET_PQ_query_param_auto_from_type (master_sig),
- GNUNET_PQ_query_param_end
- };
-
- return GNUNET_PQ_eval_prepared_non_select (pg->conn,
- "insert_signkey",
- iparams);
-}
-
-
-/**
- * Lookup signing key meta data.
- *
- * @param cls closure
- * @param exchange_pub the exchange online signing public key
- * @param[out] meta meta data about @a exchange_pub
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_lookup_signing_key (
- void *cls,
- const struct TALER_ExchangePublicKeyP *exchange_pub,
- struct TALER_EXCHANGEDB_SignkeyMetaData *meta)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (exchange_pub),
- GNUNET_PQ_query_param_end
- };
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_timestamp ("valid_from",
- &meta->start),
- GNUNET_PQ_result_spec_timestamp ("expire_sign",
- &meta->expire_sign),
- GNUNET_PQ_result_spec_timestamp ("expire_legal",
- &meta->expire_legal),
- GNUNET_PQ_result_spec_end
- };
-
- return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "lookup_signing_key",
- params,
- rs);
-}
-
-
-/**
- * Insert information about an auditor auditing a denomination key.
- *
- * @param cls closure
- * @param h_denom_pub the audited denomination
- * @param auditor_pub the auditor's key
- * @param auditor_sig signature affirming the auditor's audit activity
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_insert_auditor_denom_sig (
- void *cls,
- const struct TALER_DenominationHashP *h_denom_pub,
- const struct TALER_AuditorPublicKeyP *auditor_pub,
- const struct TALER_AuditorSignatureP *auditor_sig)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (auditor_pub),
- GNUNET_PQ_query_param_auto_from_type (h_denom_pub),
- GNUNET_PQ_query_param_auto_from_type (auditor_sig),
- GNUNET_PQ_query_param_end
- };
-
- return GNUNET_PQ_eval_prepared_non_select (pg->conn,
- "insert_auditor_denom_sig",
- params);
-}
-
-
-/**
- * Select information about an auditor auditing a denomination key.
- *
- * @param cls closure
- * @param h_denom_pub the audited denomination
- * @param auditor_pub the auditor's key
- * @param[out] auditor_sig set to signature affirming the auditor's audit activity
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_select_auditor_denom_sig (
- void *cls,
- const struct TALER_DenominationHashP *h_denom_pub,
- const struct TALER_AuditorPublicKeyP *auditor_pub,
- struct TALER_AuditorSignatureP *auditor_sig)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (auditor_pub),
- GNUNET_PQ_query_param_auto_from_type (h_denom_pub),
- GNUNET_PQ_query_param_end
- };
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_auto_from_type ("auditor_sig",
- auditor_sig),
- GNUNET_PQ_result_spec_end
- };
-
- return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "select_auditor_denom_sig",
- params,
- rs);
-}
-
-
-/**
- * Closure for #wire_fee_by_time_helper()
- */
-struct WireFeeLookupContext
-{
-
- /**
- * Set to the wire fees. Set to invalid if fees conflict over
- * the given time period.
- */
- struct TALER_WireFeeSet *fees;
-
- /**
- * Plugin context.
- */
- struct PostgresClosure *pg;
-};
-
-
-/**
- * Helper function for #postgres_lookup_wire_fee_by_time().
- * Calls the callback with the wire fee structure.
- *
- * @param cls a `struct WireFeeLookupContext`
- * @param result db results
- * @param num_results number of results in @a result
- */
-static void
-wire_fee_by_time_helper (void *cls,
- PGresult *result,
- unsigned int num_results)
-{
- struct WireFeeLookupContext *wlc = cls;
- struct PostgresClosure *pg = wlc->pg;
-
- for (unsigned int i = 0; i<num_results; i++)
- {
- struct TALER_WireFeeSet fs;
- struct GNUNET_PQ_ResultSpec rs[] = {
- TALER_PQ_RESULT_SPEC_AMOUNT ("wire_fee",
- &fs.wire),
- TALER_PQ_RESULT_SPEC_AMOUNT ("closing_fee",
- &fs.closing),
- TALER_PQ_RESULT_SPEC_AMOUNT ("wad_fee",
- &fs.wad),
- GNUNET_PQ_result_spec_end
- };
-
- if (GNUNET_OK !=
- GNUNET_PQ_extract_result (result,
- rs,
- i))
- {
- GNUNET_break (0);
- /* invalidate */
- memset (wlc->fees,
- 0,
- sizeof (struct TALER_WireFeeSet));
- return;
- }
- if (0 == i)
- {
- *wlc->fees = fs;
- continue;
- }
- if (0 !=
- TALER_wire_fee_set_cmp (&fs,
- wlc->fees))
- {
- /* invalidate */
- memset (wlc->fees,
- 0,
- sizeof (struct TALER_WireFeeSet));
- return;
- }
- }
-}
-
-
-/**
- * Lookup information about known wire fees. Finds all applicable
- * fees in the given range. If they are identical, returns the
- * respective @a fees. If any of the fees
- * differ between @a start_time and @a end_time, the transaction
- * succeeds BUT returns an invalid amount for both fees.
- *
- * @param cls closure
- * @param wire_method the wire method to lookup fees for
- * @param start_time starting time of fee
- * @param end_time end time of fee
- * @param[out] fees wire fees for that time period; if
- * different fees exists within this time
- * period, an 'invalid' amount is returned.
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_lookup_wire_fee_by_time (
- void *cls,
- const char *wire_method,
- struct GNUNET_TIME_Timestamp start_time,
- struct GNUNET_TIME_Timestamp end_time,
- struct TALER_WireFeeSet *fees)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_string (wire_method),
- GNUNET_PQ_query_param_timestamp (&start_time),
- GNUNET_PQ_query_param_timestamp (&end_time),
- GNUNET_PQ_query_param_end
- };
- struct WireFeeLookupContext wlc = {
- .fees = fees,
- .pg = pg
- };
-
- return GNUNET_PQ_eval_prepared_multi_select (pg->conn,
- "lookup_wire_fee_by_time",
- params,
- &wire_fee_by_time_helper,
- &wlc);
-}
-
-
-/**
- * Closure for #global_fee_by_time_helper()
- */
-struct GlobalFeeLookupContext
-{
-
- /**
- * Set to the wire fees. Set to invalid if fees conflict over
- * the given time period.
- */
- struct TALER_GlobalFeeSet *fees;
-
- /**
- * Set to timeout of unmerged purses
- */
- struct GNUNET_TIME_Relative *purse_timeout;
-
- /**
- * Set to timeout of accounts without kyc.
- */
- struct GNUNET_TIME_Relative *kyc_timeout;
-
- /**
- * Set to history expiration for reserves.
- */
- struct GNUNET_TIME_Relative *history_expiration;
-
- /**
- * Set to number of free purses per account.
- */
- uint32_t *purse_account_limit;
-
- /**
- * Plugin context.
- */
- struct PostgresClosure *pg;
-};
-
-
-/**
- * Helper function for #postgres_lookup_global_fee_by_time().
- * Calls the callback with each denomination key.
- *
- * @param cls a `struct GlobalFeeLookupContext`
- * @param result db results
- * @param num_results number of results in @a result
- */
-static void
-global_fee_by_time_helper (void *cls,
- PGresult *result,
- unsigned int num_results)
-{
- struct GlobalFeeLookupContext *wlc = cls;
- struct PostgresClosure *pg = wlc->pg;
-
- for (unsigned int i = 0; i<num_results; i++)
- {
- struct TALER_GlobalFeeSet fs;
- struct GNUNET_TIME_Relative purse_timeout;
- struct GNUNET_TIME_Relative kyc_timeout;
- struct GNUNET_TIME_Relative history_expiration;
- uint32_t purse_account_limit;
- struct GNUNET_PQ_ResultSpec rs[] = {
- TALER_PQ_RESULT_SPEC_AMOUNT ("history_fee",
- &fs.history),
- TALER_PQ_RESULT_SPEC_AMOUNT ("kyc_fee",
- &fs.kyc),
- TALER_PQ_RESULT_SPEC_AMOUNT ("account_fee",
- &fs.account),
- TALER_PQ_RESULT_SPEC_AMOUNT ("purse_fee",
- &fs.purse),
- GNUNET_PQ_result_spec_relative_time ("purse_timeout",
- &purse_timeout),
- GNUNET_PQ_result_spec_relative_time ("kyc_timeout",
- &kyc_timeout),
- GNUNET_PQ_result_spec_relative_time ("history_expiration",
- &history_expiration),
- GNUNET_PQ_result_spec_uint32 ("purse_account_limit",
- &purse_account_limit),
- GNUNET_PQ_result_spec_end
- };
-
- if (GNUNET_OK !=
- GNUNET_PQ_extract_result (result,
- rs,
- i))
- {
- GNUNET_break (0);
- /* invalidate */
- memset (wlc->fees,
- 0,
- sizeof (struct TALER_GlobalFeeSet));
- return;
- }
- if (0 == i)
- {
- *wlc->fees = fs;
- *wlc->purse_timeout = purse_timeout;
- *wlc->kyc_timeout = kyc_timeout;
- *wlc->history_expiration = history_expiration;
- *wlc->purse_account_limit = purse_account_limit;
- continue;
- }
- if ( (0 !=
- TALER_global_fee_set_cmp (&fs,
- wlc->fees)) ||
- (purse_account_limit != *wlc->purse_account_limit) ||
- (GNUNET_TIME_relative_cmp (purse_timeout,
- !=,
- *wlc->purse_timeout)) ||
- (GNUNET_TIME_relative_cmp (kyc_timeout,
- !=,
- *wlc->kyc_timeout)) ||
- (GNUNET_TIME_relative_cmp (history_expiration,
- !=,
- *wlc->history_expiration)) )
- {
- /* invalidate */
- memset (wlc->fees,
- 0,
- sizeof (struct TALER_GlobalFeeSet));
- return;
- }
- }
-}
-
-
-/**
- * Lookup information about known global fees.
- *
- * @param cls closure
- * @param start_time starting time of fee
- * @param end_time end time of fee
- * @param[out] fees set to wire fees for that time period; if
- * different global fee exists within this time
- * period, an 'invalid' amount is returned.
- * @param[out] purse_timeout set to when unmerged purses expire
- * @param[out] kyc_timeout set to when reserves without kyc expire
- * @param[out] history_expiration set to when we expire reserve histories
- * @param[out] purse_account_limit set to number of free purses
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_lookup_global_fee_by_time (
- void *cls,
- struct GNUNET_TIME_Timestamp start_time,
- struct GNUNET_TIME_Timestamp end_time,
- struct TALER_GlobalFeeSet *fees,
- struct GNUNET_TIME_Relative *purse_timeout,
- struct GNUNET_TIME_Relative *kyc_timeout,
- struct GNUNET_TIME_Relative *history_expiration,
- uint32_t *purse_account_limit)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_timestamp (&start_time),
- GNUNET_PQ_query_param_timestamp (&end_time),
- GNUNET_PQ_query_param_end
- };
- struct GlobalFeeLookupContext wlc = {
- .fees = fees,
- .purse_timeout = purse_timeout,
- .kyc_timeout = kyc_timeout,
- .history_expiration = history_expiration,
- .purse_account_limit = purse_account_limit,
- .pg = pg
- };
-
- return GNUNET_PQ_eval_prepared_multi_select (pg->conn,
- "lookup_global_fee_by_time",
- params,
- &global_fee_by_time_helper,
- &wlc);
-}
-
-
-/**
- * Lookup the latest serial number of @a table. Used in
- * exchange-auditor database replication.
- *
- * @param cls closure
- * @param table table for which we should return the serial
- * @param[out] serial latest serial number in use
- * @return transaction status code, GNUNET_DB_STATUS_HARD_ERROR if
- * @a table does not have a serial number
- */
-static enum GNUNET_DB_QueryStatus
-postgres_lookup_serial_by_table (void *cls,
- enum TALER_EXCHANGEDB_ReplicatedTable table,
- uint64_t *serial)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_end
- };
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_uint64 ("serial",
- serial),
- GNUNET_PQ_result_spec_end
- };
- const char *statement;
-
- switch (table)
- {
- case TALER_EXCHANGEDB_RT_DENOMINATIONS:
- statement = "select_serial_by_table_denominations";
- break;
- case TALER_EXCHANGEDB_RT_DENOMINATION_REVOCATIONS:
- statement = "select_serial_by_table_denomination_revocations";
- break;
- case TALER_EXCHANGEDB_RT_WIRE_TARGETS:
- statement = "select_serial_by_table_wire_targets";
- break;
- case TALER_EXCHANGEDB_RT_RESERVES:
- statement = "select_serial_by_table_reserves";
- break;
- case TALER_EXCHANGEDB_RT_RESERVES_IN:
- statement = "select_serial_by_table_reserves_in";
- break;
- case TALER_EXCHANGEDB_RT_RESERVES_CLOSE:
- statement = "select_serial_by_table_reserves_close";
- break;
- case TALER_EXCHANGEDB_RT_RESERVES_OUT:
- statement = "select_serial_by_table_reserves_out";
- break;
- case TALER_EXCHANGEDB_RT_AUDITORS:
- statement = "select_serial_by_table_auditors";
- break;
- case TALER_EXCHANGEDB_RT_AUDITOR_DENOM_SIGS:
- statement = "select_serial_by_table_auditor_denom_sigs";
- break;
- case TALER_EXCHANGEDB_RT_EXCHANGE_SIGN_KEYS:
- statement = "select_serial_by_table_exchange_sign_keys";
- break;
- case TALER_EXCHANGEDB_RT_SIGNKEY_REVOCATIONS:
- statement = "select_serial_by_table_signkey_revocations";
- break;
- case TALER_EXCHANGEDB_RT_KNOWN_COINS:
- statement = "select_serial_by_table_known_coins";
- break;
- case TALER_EXCHANGEDB_RT_REFRESH_COMMITMENTS:
- statement = "select_serial_by_table_refresh_commitments";
- break;
- case TALER_EXCHANGEDB_RT_REFRESH_REVEALED_COINS:
- statement = "select_serial_by_table_refresh_revealed_coins";
- break;
- case TALER_EXCHANGEDB_RT_REFRESH_TRANSFER_KEYS:
- statement = "select_serial_by_table_refresh_transfer_keys";
- break;
- case TALER_EXCHANGEDB_RT_DEPOSITS:
- statement = "select_serial_by_table_deposits";
- break;
- case TALER_EXCHANGEDB_RT_REFUNDS:
- statement = "select_serial_by_table_refunds";
- break;
- case TALER_EXCHANGEDB_RT_WIRE_OUT:
- statement = "select_serial_by_table_wire_out";
- break;
- case TALER_EXCHANGEDB_RT_AGGREGATION_TRACKING:
- statement = "select_serial_by_table_aggregation_tracking";
- break;
- case TALER_EXCHANGEDB_RT_WIRE_FEE:
- statement = "select_serial_by_table_wire_fee";
- break;
- case TALER_EXCHANGEDB_RT_GLOBAL_FEE:
- statement = "select_serial_by_table_global_fee";
- break;
- case TALER_EXCHANGEDB_RT_RECOUP:
- statement = "select_serial_by_table_recoup";
- break;
- case TALER_EXCHANGEDB_RT_RECOUP_REFRESH:
- statement = "select_serial_by_table_recoup_refresh";
- break;
- case TALER_EXCHANGEDB_RT_EXTENSIONS:
- statement = "select_serial_by_table_extensions";
- break;
- case TALER_EXCHANGEDB_RT_EXTENSION_DETAILS:
- statement = "select_serial_by_table_extension_details";
- break;
- case TALER_EXCHANGEDB_RT_PURSE_REQUESTS:
- statement = "select_serial_by_table_purse_requests";
- break;
- case TALER_EXCHANGEDB_RT_PURSE_REFUNDS:
- statement = "select_serial_by_table_purse_refunds";
- break;
- case TALER_EXCHANGEDB_RT_PURSE_MERGES:
- statement = "select_serial_by_table_purse_merges";
- break;
- case TALER_EXCHANGEDB_RT_PURSE_DEPOSITS:
- statement = "select_serial_by_table_purse_deposits";
- break;
- case TALER_EXCHANGEDB_RT_ACCOUNT_MERGES:
- statement = "select_serial_by_table_account_merges";
- break;
- case TALER_EXCHANGEDB_RT_HISTORY_REQUESTS:
- statement = "select_serial_by_table_history_requests";
- break;
- case TALER_EXCHANGEDB_RT_CLOSE_REQUESTS:
- statement = "select_serial_by_table_close_requests";
- break;
- case TALER_EXCHANGEDB_RT_WADS_OUT:
- statement = "select_serial_by_table_wads_out";
- break;
- case TALER_EXCHANGEDB_RT_WADS_OUT_ENTRIES:
- statement = "select_serial_by_table_wads_out_entries";
- break;
- case TALER_EXCHANGEDB_RT_WADS_IN:
- statement = "select_serial_by_table_wads_in";
- break;
- case TALER_EXCHANGEDB_RT_WADS_IN_ENTRIES:
- statement = "select_serial_by_table_wads_in_entries";
- break;
- default:
- GNUNET_break (0);
- return GNUNET_DB_STATUS_HARD_ERROR;
- }
-
- return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- statement,
- params,
- rs);
-}
-
-
-/**
- * Closure for callbacks used by #postgres_lookup_records_by_table.
- */
-struct LookupRecordsByTableContext
-{
- /**
- * Plugin context.
- */
- struct PostgresClosure *pg;
-
- /**
- * Function to call with the results.
- */
- TALER_EXCHANGEDB_ReplicationCallback cb;
-
- /**
- * Closure for @a cb.
- */
- void *cb_cls;
-
- /**
- * Set to true on errors.
- */
- bool error;
-};
-
-
-#include "lrbt_callbacks.c"
-
-
-/**
- * Lookup records above @a serial number in @a table. Used in
- * exchange-auditor database replication.
- *
- * @param cls closure
- * @param table table for which we should return the serial
- * @param serial largest serial number to exclude
- * @param cb function to call on the records
- * @param cb_cls closure for @a cb
- * @return transaction status code, GNUNET_DB_STATUS_HARD_ERROR if
- * @a table does not have a serial number
- */
-static enum GNUNET_DB_QueryStatus
-postgres_lookup_records_by_table (void *cls,
- enum TALER_EXCHANGEDB_ReplicatedTable table,
- uint64_t serial,
- TALER_EXCHANGEDB_ReplicationCallback cb,
- void *cb_cls)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_uint64 (&serial),
- GNUNET_PQ_query_param_end
- };
- struct LookupRecordsByTableContext ctx = {
- .pg = pg,
- .cb = cb,
- .cb_cls = cb_cls
- };
- GNUNET_PQ_PostgresResultHandler rh;
- const char *statement;
- enum GNUNET_DB_QueryStatus qs;
-
- switch (table)
- {
- case TALER_EXCHANGEDB_RT_DENOMINATIONS:
- statement = "select_above_serial_by_table_denominations";
- rh = &lrbt_cb_table_denominations;
- break;
- case TALER_EXCHANGEDB_RT_DENOMINATION_REVOCATIONS:
- statement = "select_above_serial_by_table_denomination_revocations";
- rh = &lrbt_cb_table_denomination_revocations;
- break;
- case TALER_EXCHANGEDB_RT_WIRE_TARGETS:
- statement = "select_above_serial_by_table_wire_targets";
- rh = &lrbt_cb_table_wire_targets;
- break;
- case TALER_EXCHANGEDB_RT_RESERVES:
- statement = "select_above_serial_by_table_reserves";
- rh = &lrbt_cb_table_reserves;
- break;
- case TALER_EXCHANGEDB_RT_RESERVES_IN:
- statement = "select_above_serial_by_table_reserves_in";
- rh = &lrbt_cb_table_reserves_in;
- break;
- case TALER_EXCHANGEDB_RT_RESERVES_CLOSE:
- statement = "select_above_serial_by_table_reserves_close";
- rh = &lrbt_cb_table_reserves_close;
- break;
- case TALER_EXCHANGEDB_RT_RESERVES_OUT:
- statement = "select_above_serial_by_table_reserves_out";
- rh = &lrbt_cb_table_reserves_out;
- break;
- case TALER_EXCHANGEDB_RT_AUDITORS:
- statement = "select_above_serial_by_table_auditors";
- rh = &lrbt_cb_table_auditors;
- break;
- case TALER_EXCHANGEDB_RT_AUDITOR_DENOM_SIGS:
- statement = "select_above_serial_by_table_auditor_denom_sigs";
- rh = &lrbt_cb_table_auditor_denom_sigs;
- break;
- case TALER_EXCHANGEDB_RT_EXCHANGE_SIGN_KEYS:
- statement = "select_above_serial_by_table_exchange_sign_keys";
- rh = &lrbt_cb_table_exchange_sign_keys;
- break;
- case TALER_EXCHANGEDB_RT_SIGNKEY_REVOCATIONS:
- statement = "select_above_serial_by_table_signkey_revocations";
- rh = &lrbt_cb_table_signkey_revocations;
- break;
- case TALER_EXCHANGEDB_RT_KNOWN_COINS:
- statement = "select_above_serial_by_table_known_coins";
- rh = &lrbt_cb_table_known_coins;
- break;
- case TALER_EXCHANGEDB_RT_REFRESH_COMMITMENTS:
- statement = "select_above_serial_by_table_refresh_commitments";
- rh = &lrbt_cb_table_refresh_commitments;
- break;
- case TALER_EXCHANGEDB_RT_REFRESH_REVEALED_COINS:
- statement = "select_above_serial_by_table_refresh_revealed_coins";
- rh = &lrbt_cb_table_refresh_revealed_coins;
- break;
- case TALER_EXCHANGEDB_RT_REFRESH_TRANSFER_KEYS:
- statement = "select_above_serial_by_table_refresh_transfer_keys";
- rh = &lrbt_cb_table_refresh_transfer_keys;
- break;
- case TALER_EXCHANGEDB_RT_DEPOSITS:
- statement = "select_above_serial_by_table_deposits";
- rh = &lrbt_cb_table_deposits;
- break;
- case TALER_EXCHANGEDB_RT_REFUNDS:
- statement = "select_above_serial_by_table_refunds";
- rh = &lrbt_cb_table_refunds;
- break;
- case TALER_EXCHANGEDB_RT_WIRE_OUT:
- statement = "select_above_serial_by_table_wire_out";
- rh = &lrbt_cb_table_wire_out;
- break;
- case TALER_EXCHANGEDB_RT_AGGREGATION_TRACKING:
- statement = "select_above_serial_by_table_aggregation_tracking";
- rh = &lrbt_cb_table_aggregation_tracking;
- break;
- case TALER_EXCHANGEDB_RT_WIRE_FEE:
- statement = "select_above_serial_by_table_wire_fee";
- rh = &lrbt_cb_table_wire_fee;
- break;
- case TALER_EXCHANGEDB_RT_GLOBAL_FEE:
- statement = "select_above_serial_by_table_global_fee";
- rh = &lrbt_cb_table_global_fee;
- break;
- case TALER_EXCHANGEDB_RT_RECOUP:
- statement = "select_above_serial_by_table_recoup";
- rh = &lrbt_cb_table_recoup;
- break;
- case TALER_EXCHANGEDB_RT_RECOUP_REFRESH:
- statement = "select_above_serial_by_table_recoup_refresh";
- rh = &lrbt_cb_table_recoup_refresh;
- break;
- case TALER_EXCHANGEDB_RT_EXTENSIONS:
- statement = "select_above_serial_by_table_extensions";
- rh = &lrbt_cb_table_extensions;
- break;
- case TALER_EXCHANGEDB_RT_EXTENSION_DETAILS:
- statement = "select_above_serial_by_table_extension_details";
- rh = &lrbt_cb_table_extension_details;
- break;
- case TALER_EXCHANGEDB_RT_PURSE_REQUESTS:
- statement = "select_above_serial_by_table_purse_requests";
- rh = &lrbt_cb_table_purse_requests;
- break;
- case TALER_EXCHANGEDB_RT_PURSE_REFUNDS:
- statement = "select_above_serial_by_table_purse_refunds";
- rh = &lrbt_cb_table_purse_refunds;
- break;
- case TALER_EXCHANGEDB_RT_PURSE_MERGES:
- statement = "select_above_serial_by_table_purse_merges";
- rh = &lrbt_cb_table_purse_merges;
- break;
- case TALER_EXCHANGEDB_RT_PURSE_DEPOSITS:
- statement = "select_above_serial_by_table_purse_deposits";
- rh = &lrbt_cb_table_purse_deposits;
- break;
- case TALER_EXCHANGEDB_RT_ACCOUNT_MERGES:
- statement = "select_above_serial_by_table_account_merges";
- rh = &lrbt_cb_table_account_merges;
- break;
- case TALER_EXCHANGEDB_RT_HISTORY_REQUESTS:
- statement = "select_above_serial_by_table_history_requests";
- rh = &lrbt_cb_table_history_requests;
- break;
- case TALER_EXCHANGEDB_RT_CLOSE_REQUESTS:
- statement = "select_above_serial_by_table_close_requests";
- rh = &lrbt_cb_table_close_requests;
- break;
- case TALER_EXCHANGEDB_RT_WADS_OUT:
- statement = "select_above_serial_by_table_wads_out";
- rh = &lrbt_cb_table_wads_out;
- break;
- case TALER_EXCHANGEDB_RT_WADS_OUT_ENTRIES:
- statement = "select_above_serial_by_table_wads_out_entries";
- rh = &lrbt_cb_table_wads_out_entries;
- break;
- case TALER_EXCHANGEDB_RT_WADS_IN:
- statement = "select_above_serial_by_table_wads_in";
- rh = &lrbt_cb_table_wads_in;
- break;
- case TALER_EXCHANGEDB_RT_WADS_IN_ENTRIES:
- statement = "select_above_serial_by_table_wads_in_entries";
- rh = &lrbt_cb_table_wads_in_entries;
- break;
- default:
- GNUNET_break (0);
- return GNUNET_DB_STATUS_HARD_ERROR;
- }
-
- qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
- statement,
- params,
- rh,
- &ctx);
- if (qs < 0)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Failed to run `%s'\n",
- statement);
- return qs;
- }
- if (ctx.error)
- {
- GNUNET_break (0);
- return GNUNET_DB_STATUS_HARD_ERROR;
- }
- return qs;
-}
-
-
-/**
- * Signature of helper functions of #postgres_insert_records_by_table.
- *
- * @param pg plugin context
- * @param td record to insert
- * @return transaction status code
- */
-typedef enum GNUNET_DB_QueryStatus
-(*InsertRecordCallback)(struct PostgresClosure *pg,
- const struct TALER_EXCHANGEDB_TableData *td);
-
-
-#include "irbt_callbacks.c"
-
-
-/**
- * Insert record set into @a table. Used in exchange-auditor database
- * replication.
- *
- * @param cls closure
- * @param td table data to insert
- * @return transaction status code, #GNUNET_DB_STATUS_HARD_ERROR if
- * @e table in @a tr is not supported
- */
-static enum GNUNET_DB_QueryStatus
-postgres_insert_records_by_table (void *cls,
- const struct TALER_EXCHANGEDB_TableData *td)
-{
- struct PostgresClosure *pg = cls;
- InsertRecordCallback rh;
-
- switch (td->table)
- {
- case TALER_EXCHANGEDB_RT_DENOMINATIONS:
- rh = &irbt_cb_table_denominations;
- break;
- case TALER_EXCHANGEDB_RT_DENOMINATION_REVOCATIONS:
- rh = &irbt_cb_table_denomination_revocations;
- break;
- case TALER_EXCHANGEDB_RT_WIRE_TARGETS:
- rh = &irbt_cb_table_wire_targets;
- break;
- case TALER_EXCHANGEDB_RT_RESERVES:
- rh = &irbt_cb_table_reserves;
- break;
- case TALER_EXCHANGEDB_RT_RESERVES_IN:
- rh = &irbt_cb_table_reserves_in;
- break;
- case TALER_EXCHANGEDB_RT_RESERVES_CLOSE:
- rh = &irbt_cb_table_reserves_close;
- break;
- case TALER_EXCHANGEDB_RT_RESERVES_OUT:
- rh = &irbt_cb_table_reserves_out;
- break;
- case TALER_EXCHANGEDB_RT_AUDITORS:
- rh = &irbt_cb_table_auditors;
- break;
- case TALER_EXCHANGEDB_RT_AUDITOR_DENOM_SIGS:
- rh = &irbt_cb_table_auditor_denom_sigs;
- break;
- case TALER_EXCHANGEDB_RT_EXCHANGE_SIGN_KEYS:
- rh = &irbt_cb_table_exchange_sign_keys;
- break;
- case TALER_EXCHANGEDB_RT_SIGNKEY_REVOCATIONS:
- rh = &irbt_cb_table_signkey_revocations;
- break;
- case TALER_EXCHANGEDB_RT_KNOWN_COINS:
- rh = &irbt_cb_table_known_coins;
- break;
- case TALER_EXCHANGEDB_RT_REFRESH_COMMITMENTS:
- rh = &irbt_cb_table_refresh_commitments;
- break;
- case TALER_EXCHANGEDB_RT_REFRESH_REVEALED_COINS:
- rh = &irbt_cb_table_refresh_revealed_coins;
- break;
- case TALER_EXCHANGEDB_RT_REFRESH_TRANSFER_KEYS:
- rh = &irbt_cb_table_refresh_transfer_keys;
- break;
- case TALER_EXCHANGEDB_RT_DEPOSITS:
- rh = &irbt_cb_table_deposits;
- break;
- case TALER_EXCHANGEDB_RT_REFUNDS:
- rh = &irbt_cb_table_refunds;
- break;
- case TALER_EXCHANGEDB_RT_WIRE_OUT:
- rh = &irbt_cb_table_wire_out;
- break;
- case TALER_EXCHANGEDB_RT_AGGREGATION_TRACKING:
- rh = &irbt_cb_table_aggregation_tracking;
- break;
- case TALER_EXCHANGEDB_RT_WIRE_FEE:
- rh = &irbt_cb_table_wire_fee;
- break;
- case TALER_EXCHANGEDB_RT_GLOBAL_FEE:
- rh = &irbt_cb_table_global_fee;
- break;
- case TALER_EXCHANGEDB_RT_RECOUP:
- rh = &irbt_cb_table_recoup;
- break;
- case TALER_EXCHANGEDB_RT_RECOUP_REFRESH:
- rh = &irbt_cb_table_recoup_refresh;
- break;
- case TALER_EXCHANGEDB_RT_EXTENSIONS:
- rh = &irbt_cb_table_extensions;
- break;
- case TALER_EXCHANGEDB_RT_EXTENSION_DETAILS:
- rh = &irbt_cb_table_extension_details;
- break;
- case TALER_EXCHANGEDB_RT_PURSE_REQUESTS:
- rh = &irbt_cb_table_purse_requests;
- break;
- case TALER_EXCHANGEDB_RT_PURSE_REFUNDS:
- rh = &irbt_cb_table_purse_refunds;
- break;
- case TALER_EXCHANGEDB_RT_PURSE_MERGES:
- rh = &irbt_cb_table_purse_merges;
- break;
- case TALER_EXCHANGEDB_RT_PURSE_DEPOSITS:
- rh = &irbt_cb_table_purse_deposits;
- break;
- case TALER_EXCHANGEDB_RT_ACCOUNT_MERGES:
- rh = &irbt_cb_table_account_mergers;
- break;
- case TALER_EXCHANGEDB_RT_HISTORY_REQUESTS:
- rh = &irbt_cb_table_history_requests;
- break;
- case TALER_EXCHANGEDB_RT_CLOSE_REQUESTS:
- rh = &irbt_cb_table_close_requests;
- break;
- case TALER_EXCHANGEDB_RT_WADS_OUT:
- rh = &irbt_cb_table_wads_out;
- break;
- case TALER_EXCHANGEDB_RT_WADS_OUT_ENTRIES:
- rh = &irbt_cb_table_wads_out_entries;
- break;
- case TALER_EXCHANGEDB_RT_WADS_IN:
- rh = &irbt_cb_table_wads_in;
- break;
- case TALER_EXCHANGEDB_RT_WADS_IN_ENTRIES:
- rh = &irbt_cb_table_wads_in_entries;
- break;
- default:
- GNUNET_break (0);
- return GNUNET_DB_STATUS_HARD_ERROR;
- }
- return rh (pg,
- td);
-}
-
-
-/**
- * Function called to grab a work shard on an operation @a op. Runs in its
- * own transaction.
- *
- * @param cls the @e cls of this struct with the plugin-specific state
- * @param job_name name of the operation to grab a word shard for
- * @param delay minimum age of a shard to grab
- * @param shard_size desired shard size
- * @param[out] start_row inclusive start row of the shard (returned)
- * @param[out] end_row exclusive end row of the shard (returned)
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_begin_shard (void *cls,
- const char *job_name,
- struct GNUNET_TIME_Relative delay,
- uint64_t shard_size,
- uint64_t *start_row,
- uint64_t *end_row)
-{
- struct PostgresClosure *pg = cls;
-
- for (unsigned int retries = 0; retries<10; retries++)
- {
- if (GNUNET_OK !=
- postgres_start (pg,
- "begin_shard"))
- {
- GNUNET_break (0);
- return GNUNET_DB_STATUS_HARD_ERROR;
- }
-
- {
- struct GNUNET_TIME_Absolute past;
- enum GNUNET_DB_QueryStatus qs;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_string (job_name),
- GNUNET_PQ_query_param_absolute_time (&past),
- GNUNET_PQ_query_param_end
- };
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_uint64 ("start_row",
- start_row),
- GNUNET_PQ_result_spec_uint64 ("end_row",
- end_row),
- GNUNET_PQ_result_spec_end
- };
-
- past = GNUNET_TIME_absolute_get ();
- qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "get_open_shard",
- params,
- rs);
- switch (qs)
- {
- case GNUNET_DB_STATUS_HARD_ERROR:
- GNUNET_break (0);
- postgres_rollback (pg);
- return qs;
- case GNUNET_DB_STATUS_SOFT_ERROR:
- postgres_rollback (pg);
- continue;
- case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
- {
- enum GNUNET_DB_QueryStatus qs;
- struct GNUNET_TIME_Absolute now;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_string (job_name),
- GNUNET_PQ_query_param_absolute_time (&now),
- GNUNET_PQ_query_param_uint64 (start_row),
- GNUNET_PQ_query_param_uint64 (end_row),
- GNUNET_PQ_query_param_end
- };
-
- now = GNUNET_TIME_relative_to_absolute (delay);
- qs = GNUNET_PQ_eval_prepared_non_select (pg->conn,
- "reclaim_shard",
- params);
- switch (qs)
- {
- case GNUNET_DB_STATUS_HARD_ERROR:
- GNUNET_break (0);
- postgres_rollback (pg);
- return qs;
- case GNUNET_DB_STATUS_SOFT_ERROR:
- postgres_rollback (pg);
- continue;
- case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
- goto commit;
- case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
- GNUNET_break (0); /* logic error, should be impossible */
- postgres_rollback (pg);
- return GNUNET_DB_STATUS_HARD_ERROR;
- }
- }
- break; /* actually unreachable */
- case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
- break; /* continued below */
- }
- } /* get_open_shard */
-
- /* No open shard, find last 'end_row' */
- {
- enum GNUNET_DB_QueryStatus qs;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_string (job_name),
- GNUNET_PQ_query_param_end
- };
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_uint64 ("end_row",
- start_row),
- GNUNET_PQ_result_spec_end
- };
-
- qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "get_last_shard",
- params,
- rs);
- switch (qs)
- {
- case GNUNET_DB_STATUS_HARD_ERROR:
- GNUNET_break (0);
- postgres_rollback (pg);
- return qs;
- case GNUNET_DB_STATUS_SOFT_ERROR:
- postgres_rollback (pg);
- continue;
- case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
- break;
- case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
- *start_row = 0; /* base-case: no shards yet */
- break; /* continued below */
- }
- *end_row = *start_row + shard_size;
- } /* get_last_shard */
-
- /* Claim fresh shard */
- {
- enum GNUNET_DB_QueryStatus qs;
- struct GNUNET_TIME_Absolute now;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_string (job_name),
- GNUNET_PQ_query_param_absolute_time (&now),
- GNUNET_PQ_query_param_uint64 (start_row),
- GNUNET_PQ_query_param_uint64 (end_row),
- GNUNET_PQ_query_param_end
- };
-
- now = GNUNET_TIME_relative_to_absolute (delay);
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Trying to claim shard (%llu-%llu]\n",
- (unsigned long long) *start_row,
- (unsigned long long) *end_row);
- qs = GNUNET_PQ_eval_prepared_non_select (pg->conn,
- "claim_next_shard",
- params);
- switch (qs)
- {
- case GNUNET_DB_STATUS_HARD_ERROR:
- GNUNET_break (0);
- postgres_rollback (pg);
- return qs;
- case GNUNET_DB_STATUS_SOFT_ERROR:
- postgres_rollback (pg);
- continue;
- case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
- /* continued below */
- break;
- case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
- /* someone else got this shard already,
- try again */
- postgres_rollback (pg);
- continue;
- }
- } /* claim_next_shard */
-
- /* commit */
-commit:
- {
- enum GNUNET_DB_QueryStatus qs;
-
- qs = postgres_commit (pg);
- switch (qs)
- {
- case GNUNET_DB_STATUS_HARD_ERROR:
- GNUNET_break (0);
- postgres_rollback (pg);
- return qs;
- case GNUNET_DB_STATUS_SOFT_ERROR:
- postgres_rollback (pg);
- continue;
- case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
- case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
- return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
- }
- }
- } /* retry 'for' loop */
- return GNUNET_DB_STATUS_SOFT_ERROR;
-}
-
-
-/**
- * Function called to abort work on a shard.
- *
- * @param cls the @e cls of this struct with the plugin-specific state
- * @param job_name name of the operation to abort a word shard for
- * @param start_row inclusive start row of the shard
- * @param end_row exclusive end row of the shard
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_abort_shard (void *cls,
- const char *job_name,
- uint64_t start_row,
- uint64_t end_row)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_string (job_name),
- GNUNET_PQ_query_param_uint64 (&start_row),
- GNUNET_PQ_query_param_uint64 (&end_row),
- GNUNET_PQ_query_param_end
- };
-
- return GNUNET_PQ_eval_prepared_non_select (pg->conn,
- "abort_shard",
- params);
-}
-
-
-/**
- * Function called to persist that work on a shard was completed.
- *
- * @param cls the @e cls of this struct with the plugin-specific state
- * @param job_name name of the operation to grab a word shard for
- * @param start_row inclusive start row of the shard
- * @param end_row exclusive end row of the shard
- * @return transaction status code
- */
-enum GNUNET_DB_QueryStatus
-postgres_complete_shard (void *cls,
- const char *job_name,
- uint64_t start_row,
- uint64_t end_row)
-{
- struct PostgresClosure *pg = cls;
-
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_string (job_name),
- GNUNET_PQ_query_param_uint64 (&start_row),
- GNUNET_PQ_query_param_uint64 (&end_row),
- GNUNET_PQ_query_param_end
- };
-
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Completing shard %llu-%llu\n",
- (unsigned long long) start_row,
- (unsigned long long) end_row);
- return GNUNET_PQ_eval_prepared_non_select (pg->conn,
- "complete_shard",
- params);
-}
-
-
-/**
- * Function called to grab a revolving work shard on an operation @a op. Runs
- * in its own transaction. Returns the oldest inactive shard.
- *
- * @param cls the @e cls of this struct with the plugin-specific state
- * @param job_name name of the operation to grab a revolving shard for
- * @param shard_size desired shard size
- * @param shard_limit exclusive end of the shard range
- * @param[out] start_row inclusive start row of the shard (returned)
- * @param[out] end_row inclusive end row of the shard (returned)
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_begin_revolving_shard (void *cls,
- const char *job_name,
- uint32_t shard_size,
- uint32_t shard_limit,
- uint32_t *start_row,
- uint32_t *end_row)
-{
- struct PostgresClosure *pg = cls;
-
- GNUNET_assert (shard_limit <= 1U + (uint32_t) INT_MAX);
- GNUNET_assert (shard_limit > 0);
- GNUNET_assert (shard_size > 0);
- for (unsigned int retries = 0; retries<3; retries++)
- {
- if (GNUNET_OK !=
- postgres_start (pg,
- "begin_revolving_shard"))
- {
- GNUNET_break (0);
- return GNUNET_DB_STATUS_HARD_ERROR;
- }
-
- /* First, find last 'end_row' */
- {
- enum GNUNET_DB_QueryStatus qs;
- uint32_t last_end;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_string (job_name),
- GNUNET_PQ_query_param_end
- };
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_uint32 ("end_row",
- &last_end),
- GNUNET_PQ_result_spec_end
- };
-
- qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "get_last_revolving_shard",
- params,
- rs);
- switch (qs)
- {
- case GNUNET_DB_STATUS_HARD_ERROR:
- GNUNET_break (0);
- postgres_rollback (pg);
- return qs;
- case GNUNET_DB_STATUS_SOFT_ERROR:
- postgres_rollback (pg);
- continue;
- case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
- *start_row = 1U + last_end;
- break;
- case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
- *start_row = 0; /* base-case: no shards yet */
- break; /* continued below */
- }
- } /* get_last_shard */
-
- if (*start_row < shard_limit)
- {
- /* Claim fresh shard */
- enum GNUNET_DB_QueryStatus qs;
- struct GNUNET_TIME_Absolute now;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_string (job_name),
- GNUNET_PQ_query_param_absolute_time (&now),
- GNUNET_PQ_query_param_uint32 (start_row),
- GNUNET_PQ_query_param_uint32 (end_row),
- GNUNET_PQ_query_param_end
- };
-
- *end_row = GNUNET_MIN (shard_limit,
- *start_row + shard_size - 1);
- now = GNUNET_TIME_absolute_get ();
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Trying to claim shard %llu-%llu\n",
- (unsigned long long) *start_row,
- (unsigned long long) *end_row);
- qs = GNUNET_PQ_eval_prepared_non_select (pg->conn,
- "create_revolving_shard",
- params);
- switch (qs)
- {
- case GNUNET_DB_STATUS_HARD_ERROR:
- GNUNET_break (0);
- postgres_rollback (pg);
- return qs;
- case GNUNET_DB_STATUS_SOFT_ERROR:
- postgres_rollback (pg);
- continue;
- case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
- /* continued below (with commit) */
- break;
- case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
- /* someone else got this shard already,
- try again */
- postgres_rollback (pg);
- continue;
- }
- } /* end create fresh reovlving shard */
- else
- {
- /* claim oldest existing shard */
- enum GNUNET_DB_QueryStatus qs;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_string (job_name),
- GNUNET_PQ_query_param_end
- };
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_uint32 ("start_row",
- start_row),
- GNUNET_PQ_result_spec_uint32 ("end_row",
- end_row),
- GNUNET_PQ_result_spec_end
- };
-
- qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "get_open_revolving_shard",
- params,
- rs);
- switch (qs)
- {
- case GNUNET_DB_STATUS_HARD_ERROR:
- GNUNET_break (0);
- postgres_rollback (pg);
- return qs;
- case GNUNET_DB_STATUS_SOFT_ERROR:
- postgres_rollback (pg);
- continue;
- case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
- /* no open shards available */
- postgres_rollback (pg);
- return qs;
- case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
- {
- enum GNUNET_DB_QueryStatus qs;
- struct GNUNET_TIME_Timestamp now;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_string (job_name),
- GNUNET_PQ_query_param_timestamp (&now),
- GNUNET_PQ_query_param_uint32 (start_row),
- GNUNET_PQ_query_param_uint32 (end_row),
- GNUNET_PQ_query_param_end
- };
-
- now = GNUNET_TIME_timestamp_get ();
- qs = GNUNET_PQ_eval_prepared_non_select (pg->conn,
- "reclaim_revolving_shard",
- params);
- switch (qs)
- {
- case GNUNET_DB_STATUS_HARD_ERROR:
- GNUNET_break (0);
- postgres_rollback (pg);
- return qs;
- case GNUNET_DB_STATUS_SOFT_ERROR:
- postgres_rollback (pg);
- continue;
- case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
- break; /* continue with commit */
- case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
- GNUNET_break (0); /* logic error, should be impossible */
- postgres_rollback (pg);
- return GNUNET_DB_STATUS_HARD_ERROR;
- }
- }
- break; /* continue with commit */
- }
- } /* end claim oldest existing shard */
-
- /* commit */
- {
- enum GNUNET_DB_QueryStatus qs;
-
- qs = postgres_commit (pg);
- switch (qs)
- {
- case GNUNET_DB_STATUS_HARD_ERROR:
- GNUNET_break (0);
- postgres_rollback (pg);
- return qs;
- case GNUNET_DB_STATUS_SOFT_ERROR:
- postgres_rollback (pg);
- continue;
- case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
- case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
- return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
- }
- }
- } /* retry 'for' loop */
- return GNUNET_DB_STATUS_SOFT_ERROR;
-}
-
-
-/**
- * Function called to release a revolving shard
- * back into the work pool. Clears the
- * "completed" flag.
- *
- * @param cls the @e cls of this struct with the plugin-specific state
- * @param job_name name of the operation to grab a word shard for
- * @param start_row inclusive start row of the shard
- * @param end_row exclusive end row of the shard
- * @return transaction status code
- */
-enum GNUNET_DB_QueryStatus
-postgres_release_revolving_shard (void *cls,
- const char *job_name,
- uint32_t start_row,
- uint32_t end_row)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_string (job_name),
- GNUNET_PQ_query_param_uint32 (&start_row),
- GNUNET_PQ_query_param_uint32 (&end_row),
- GNUNET_PQ_query_param_end
- };
-
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Releasing revolving shard %s %u-%u\n",
- job_name,
- (unsigned int) start_row,
- (unsigned int) end_row);
- return GNUNET_PQ_eval_prepared_non_select (pg->conn,
- "release_revolving_shard",
- params);
-}
-
-
-/**
- * Function called to delete all revolving shards.
- * To be used after a crash or when the shard size is
- * changed.
- *
- * @param cls the @e cls of this struct with the plugin-specific state
- * @return transaction status code
- */
-enum GNUNET_DB_QueryStatus
-postgres_delete_shard_locks (void *cls)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_ExecuteStatement es[] = {
- GNUNET_PQ_make_execute ("DELETE FROM work_shards;"),
- GNUNET_PQ_make_execute ("DELETE FROM revolving_work_shards;"),
- GNUNET_PQ_EXECUTE_STATEMENT_END
- };
-
- return GNUNET_PQ_exec_statements (pg->conn,
- es);
-}
-
-
-/**
- * Function called to save the configuration of an extension
- * (age-restriction, peer2peer, ...). After successful storage of the
- * configuration it triggers the corresponding event.
- *
- * @param cls the @e cls of this struct with the plugin-specific state
- * @param extension_name the name of the extension
- * @param config JSON object of the configuration as string
- * @return transaction status code
- */
-enum GNUNET_DB_QueryStatus
-postgres_set_extension_config (void *cls,
- const char *extension_name,
- const char *config)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam pcfg =
- (NULL == config || 0 == *config)
- ? GNUNET_PQ_query_param_null ()
- : GNUNET_PQ_query_param_string (config);
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_string (extension_name),
- pcfg,
- GNUNET_PQ_query_param_end
- };
-
- return GNUNET_PQ_eval_prepared_non_select (pg->conn,
- "set_extension_config",
- params);
-}
-
-
-/**
- * Function called to get the configuration of an extension
- * (age-restriction, peer2peer, ...)
- *
- * @param cls the @e cls of this struct with the plugin-specific state
- * @param extension_name the name of the extension
- * @param[out] config JSON object of the configuration as string
- * @return transaction status code
- */
-enum GNUNET_DB_QueryStatus
-postgres_get_extension_config (void *cls,
- const char *extension_name,
- char **config)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_string (extension_name),
- GNUNET_PQ_query_param_end
- };
- bool is_null;
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_allow_null (
- GNUNET_PQ_result_spec_string ("config",
- config),
- &is_null),
- GNUNET_PQ_result_spec_end
- };
-
- *config = NULL;
- return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "get_extension_config",
- params,
- rs);
-}
-
-
-/**
- * Function called to store configuration data about a partner
- * exchange that we are federated with.
- *
- * @param cls the @e cls of this struct with the plugin-specific state
- * @param master_pub public offline signing key of the partner exchange
- * @param start_date when does the following data start to be valid
- * @param end_date when does the validity end (exclusive)
- * @param wad_frequency how often do we do exchange-to-exchange settlements?
- * @param wad_fee how much do we charge for transfers to the partner
- * @param partner_base_url base URL of the partner exchange
- * @param master_sig signature with our offline signing key affirming the above
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_insert_partner (void *cls,
- const struct TALER_MasterPublicKeyP *master_pub,
- struct GNUNET_TIME_Timestamp start_date,
- struct GNUNET_TIME_Timestamp end_date,
- struct GNUNET_TIME_Relative wad_frequency,
- const struct TALER_Amount *wad_fee,
- const char *partner_base_url,
- const struct TALER_MasterSignatureP *master_sig)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (master_pub),
- GNUNET_PQ_query_param_timestamp (&start_date),
- GNUNET_PQ_query_param_timestamp (&end_date),
- GNUNET_PQ_query_param_relative_time (&wad_frequency),
- TALER_PQ_query_param_amount (wad_fee),
- GNUNET_PQ_query_param_auto_from_type (master_sig),
- GNUNET_PQ_query_param_string (partner_base_url),
- GNUNET_PQ_query_param_end
- };
-
- return GNUNET_PQ_eval_prepared_non_select (pg->conn,
- "insert_partner",
- params);
-}
-
-
-/**
- * Function called to retrieve an encrypted contract.
- *
- * @param cls the @e cls of this struct with the plugin-specific state
- * @param purse_pub key to lookup the contract by
- * @param[out] pub_ckey set to the ephemeral DH used to encrypt the contract
- * @param[out] econtract_sig set to the signature over the encrypted contract
- * @param[out] econtract_size set to the number of bytes in @a econtract
- * @param[out] econtract set to the encrypted contract on success, to be freed by the caller
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_select_contract (void *cls,
- const struct TALER_ContractDiffiePublicP *pub_ckey,
- struct TALER_PurseContractPublicKeyP *purse_pub,
- struct TALER_PurseContractSignatureP *econtract_sig,
- size_t *econtract_size,
- void **econtract)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (pub_ckey),
- GNUNET_PQ_query_param_end
- };
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_auto_from_type ("purse_pub",
- purse_pub),
- GNUNET_PQ_result_spec_auto_from_type ("contract_sig",
- econtract_sig),
- GNUNET_PQ_result_spec_variable_size ("e_contract",
- econtract,
- econtract_size),
- GNUNET_PQ_result_spec_end
- };
-
- return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "select_contract",
- params,
- rs);
-
-}
-
-
-/**
- * Function called to retrieve an encrypted contract.
- *
- * @param cls the @e cls of this struct with the plugin-specific state
- * @param purse_pub key to lookup the contract by
- * @param[out] econtract set to the encrypted contract on success, to be freed by the caller
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_select_contract_by_purse (
- void *cls,
- const struct TALER_PurseContractPublicKeyP *purse_pub,
- struct TALER_EncryptedContract *econtract)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (purse_pub),
- GNUNET_PQ_query_param_end
- };
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_auto_from_type ("pub_ckey",
- &econtract->contract_pub),
- GNUNET_PQ_result_spec_auto_from_type ("contract_sig",
- &econtract->econtract_sig),
- GNUNET_PQ_result_spec_variable_size ("e_contract",
- &econtract->econtract,
- &econtract->econtract_size),
- GNUNET_PQ_result_spec_end
- };
-
- return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "select_contract_by_purse",
- params,
- rs);
-
-}
-
-
-/**
- * Function called to persist an encrypted contract associated with a reserve.
- *
- * @param cls the @e cls of this struct with the plugin-specific state
- * @param purse_pub the purse the contract is associated with (must exist)
- * @param econtract the encrypted contract
- * @param[out] in_conflict set to true if @a econtract
- * conflicts with an existing contract;
- * in this case, the return value will be
- * #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT despite the failure
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_insert_contract (
- void *cls,
- const struct TALER_PurseContractPublicKeyP *purse_pub,
- const struct TALER_EncryptedContract *econtract,
- bool *in_conflict)
-{
- struct PostgresClosure *pg = cls;
- enum GNUNET_DB_QueryStatus qs;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (purse_pub),
- GNUNET_PQ_query_param_auto_from_type (&econtract->contract_pub),
- GNUNET_PQ_query_param_fixed_size (econtract->econtract,
- econtract->econtract_size),
- GNUNET_PQ_query_param_auto_from_type (&econtract->econtract_sig),
- GNUNET_PQ_query_param_end
- };
-
- *in_conflict = false;
- qs = GNUNET_PQ_eval_prepared_non_select (pg->conn,
- "insert_contract",
- params);
- if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != qs)
- return qs;
- {
- struct TALER_EncryptedContract econtract2;
-
- qs = postgres_select_contract_by_purse (pg,
- purse_pub,
- &econtract2);
- if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs)
- {
- GNUNET_break (0);
- return GNUNET_DB_STATUS_HARD_ERROR;
- }
- if ( (0 == GNUNET_memcmp (&econtract->contract_pub,
- &econtract2.contract_pub)) &&
- (econtract2.econtract_size ==
- econtract->econtract_size) &&
- (0 == memcmp (econtract2.econtract,
- econtract->econtract,
- econtract->econtract_size)) )
- {
- GNUNET_free (econtract2.econtract);
- return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS;
- }
- GNUNET_free (econtract2.econtract);
- *in_conflict = true;
- return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
- }
-}
-
-
-/**
- * Function called to return meta data about a purse by the
- * purse public key.
- *
- * @param cls the @e cls of this struct with the plugin-specific state
- * @param purse_pub public key of the purse
- * @param[out] merge_pub public key representing the merge capability
- * @param[out] purse_expiration when would an unmerged purse expire
- * @param[out] h_contract_terms contract associated with the purse
- * @param[out] age_limit the age limit for deposits into the purse
- * @param[out] target_amount amount to be put into the purse
- * @param[out] balance amount put so far into the purse
- * @param[out] purse_sig signature of the purse over the initialization data
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_select_purse_request (
- void *cls,
- const struct TALER_PurseContractPublicKeyP *purse_pub,
- struct TALER_PurseMergePublicKeyP *merge_pub,
- struct GNUNET_TIME_Timestamp *purse_expiration,
- struct TALER_PrivateContractHashP *h_contract_terms,
- uint32_t *age_limit,
- struct TALER_Amount *target_amount,
- struct TALER_Amount *balance,
- struct TALER_PurseContractSignatureP *purse_sig)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (purse_pub),
- GNUNET_PQ_query_param_end
- };
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_auto_from_type ("merge_pub",
- merge_pub),
- GNUNET_PQ_result_spec_timestamp ("purse_expiration",
- purse_expiration),
- GNUNET_PQ_result_spec_auto_from_type ("h_contract_terms",
- h_contract_terms),
- GNUNET_PQ_result_spec_uint32 ("age_limit",
- age_limit),
- TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee",
- target_amount),
- TALER_PQ_RESULT_SPEC_AMOUNT ("balance",
- balance),
- GNUNET_PQ_result_spec_auto_from_type ("purse_sig",
- purse_sig),
- GNUNET_PQ_result_spec_end
- };
- return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "select_purse_request",
- params,
- rs);
-}
-
-
-/**
- * Function called to create a new purse with certain meta data.
- *
- * @param cls the @e cls of this struct with the plugin-specific state
- * @param purse_pub public key of the new purse
- * @param merge_pub public key providing the merge capability
- * @param purse_expiration time when the purse will expire
- * @param h_contract_terms hash of the contract for the purse
- * @param age_limit age limit to enforce for payments into the purse
- * @param flags flags for the operation
- * @param purse_fee fee we are allowed to charge to the reserve (depending on @a flags)
- * @param amount target amount (with fees) to be put into the purse
- * @param purse_sig signature with @a purse_pub's private key affirming the above
- * @param[out] in_conflict set to true if the meta data
- * conflicts with an existing purse;
- * in this case, the return value will be
- * #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT despite the failure
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_insert_purse_request (
- void *cls,
- const struct TALER_PurseContractPublicKeyP *purse_pub,
- const struct TALER_PurseMergePublicKeyP *merge_pub,
- struct GNUNET_TIME_Timestamp purse_expiration,
- const struct TALER_PrivateContractHashP *h_contract_terms,
- uint32_t age_limit,
- enum TALER_WalletAccountMergeFlags flags,
- const struct TALER_Amount *purse_fee,
- const struct TALER_Amount *amount,
- const struct TALER_PurseContractSignatureP *purse_sig,
- bool *in_conflict)
-{
- struct PostgresClosure *pg = cls;
- enum GNUNET_DB_QueryStatus qs;
- struct GNUNET_TIME_Timestamp now = GNUNET_TIME_timestamp_get ();
- uint32_t flags32 = (uint32_t) flags;
- bool in_reserve_quota = (TALER_WAMF_MODE_CREATE_FROM_PURSE_QUOTA
- == (flags & TALER_WAMF_MERGE_MODE_MASK));
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (purse_pub),
- GNUNET_PQ_query_param_auto_from_type (merge_pub),
- GNUNET_PQ_query_param_timestamp (&now),
- GNUNET_PQ_query_param_timestamp (&purse_expiration),
- GNUNET_PQ_query_param_auto_from_type (h_contract_terms),
- GNUNET_PQ_query_param_uint32 (&age_limit),
- GNUNET_PQ_query_param_uint32 (&flags32),
- GNUNET_PQ_query_param_bool (in_reserve_quota),
- TALER_PQ_query_param_amount (amount),
- TALER_PQ_query_param_amount (purse_fee),
- GNUNET_PQ_query_param_auto_from_type (purse_sig),
- GNUNET_PQ_query_param_end
- };
-
- *in_conflict = false;
- qs = GNUNET_PQ_eval_prepared_non_select (pg->conn,
- "insert_purse_request",
- params);
- if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != qs)
- return qs;
- {
- struct TALER_PurseMergePublicKeyP merge_pub2;
- struct GNUNET_TIME_Timestamp purse_expiration2;
- struct TALER_PrivateContractHashP h_contract_terms2;
- uint32_t age_limit2;
- struct TALER_Amount amount2;
- struct TALER_Amount balance;
- struct TALER_PurseContractSignatureP purse_sig2;
-
- qs = postgres_select_purse_request (pg,
- purse_pub,
- &merge_pub2,
- &purse_expiration2,
- &h_contract_terms2,
- &age_limit2,
- &amount2,
- &balance,
- &purse_sig2);
- if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs)
- {
- GNUNET_break (0);
- return GNUNET_DB_STATUS_HARD_ERROR;
- }
- if ( (age_limit2 == age_limit) &&
- (0 == TALER_amount_cmp (amount,
- &amount2)) &&
- (0 == GNUNET_memcmp (&h_contract_terms2,
- h_contract_terms)) &&
- (0 == GNUNET_memcmp (&merge_pub2,
- merge_pub)) )
- {
- return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS;
- }
- *in_conflict = true;
- return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
- }
-}
-
-
-/**
- * Function called to clean up one expired purse.
- *
- * @param cls the @e cls of this struct with the plugin-specific state
- * @param start_time select purse expired after this time
- * @param end_time select purse expired before this time
- * @return transaction status code (#GNUNET_DB_STATUS_SUCCESS_NO_RESULTS if no purse expired in the given time interval).
- */
-static enum GNUNET_DB_QueryStatus
-postgres_expire_purse (
- void *cls,
- struct GNUNET_TIME_Absolute start_time,
- struct GNUNET_TIME_Absolute end_time)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_absolute_time (&start_time),
- GNUNET_PQ_query_param_absolute_time (&end_time),
- GNUNET_PQ_query_param_end
- };
- bool found = false;
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_bool ("found",
- &found),
- GNUNET_PQ_result_spec_end
- };
- enum GNUNET_DB_QueryStatus qs;
-
- qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "call_expire_purse",
- params,
- rs);
- if (qs < 0)
- return qs;
- GNUNET_assert (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs);
- return found
- ? GNUNET_DB_STATUS_SUCCESS_ONE_RESULT
- : GNUNET_DB_STATUS_SUCCESS_NO_RESULTS;
-}
-
-
-/**
- * Function called to obtain information about a purse.
- *
- * @param cls the @e cls of this struct with the plugin-specific state
- * @param purse_pub public key of the new purse
- * @param[out] purse_expiration set to time when the purse will expire
- * @param[out] amount set to target amount (with fees) to be put into the purse
- * @param[out] deposited set to actual amount put into the purse so far
- * @param[out] h_contract_terms set to hash of the contract for the purse
- * @param[out] merge_timestamp set to time when the purse was merged, or NEVER if not
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_select_purse (
- void *cls,
- const struct TALER_PurseContractPublicKeyP *purse_pub,
- struct GNUNET_TIME_Timestamp *purse_expiration,
- struct TALER_Amount *amount,
- struct TALER_Amount *deposited,
- struct TALER_PrivateContractHashP *h_contract_terms,
- struct GNUNET_TIME_Timestamp *merge_timestamp)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (purse_pub),
- GNUNET_PQ_query_param_end
- };
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_timestamp ("purse_expiration",
- purse_expiration),
- TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee",
- amount),
- TALER_PQ_RESULT_SPEC_AMOUNT ("balance",
- deposited),
- GNUNET_PQ_result_spec_auto_from_type ("h_contract_terms",
- h_contract_terms),
- GNUNET_PQ_result_spec_allow_null (
- GNUNET_PQ_result_spec_timestamp ("merge_timestamp",
- merge_timestamp),
- NULL),
- GNUNET_PQ_result_spec_end
- };
-
- *merge_timestamp = GNUNET_TIME_UNIT_FOREVER_TS;
- return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "select_purse",
- params,
- rs);
-}
-
-
-/**
- * Function called to return meta data about a purse by the
- * merge capability key.
- *
- * @param cls the @e cls of this struct with the plugin-specific state
- * @param merge_pub public key representing the merge capability
- * @param[out] purse_pub public key of the purse
- * @param[out] purse_expiration when would an unmerged purse expire
- * @param[out] h_contract_terms contract associated with the purse
- * @param[out] age_limit the age limit for deposits into the purse
- * @param[out] target_amount amount to be put into the purse
- * @param[out] balance amount put so far into the purse
- * @param[out] purse_sig signature of the purse over the initialization data
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_select_purse_by_merge_pub (
- void *cls,
- const struct TALER_PurseMergePublicKeyP *merge_pub,
- struct TALER_PurseContractPublicKeyP *purse_pub,
- struct GNUNET_TIME_Timestamp *purse_expiration,
- struct TALER_PrivateContractHashP *h_contract_terms,
- uint32_t *age_limit,
- struct TALER_Amount *target_amount,
- struct TALER_Amount *balance,
- struct TALER_PurseContractSignatureP *purse_sig)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (merge_pub),
- GNUNET_PQ_query_param_end
- };
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_auto_from_type ("purse_pub",
- purse_pub),
- GNUNET_PQ_result_spec_timestamp ("purse_expiration",
- purse_expiration),
- GNUNET_PQ_result_spec_auto_from_type ("h_contract_terms",
- h_contract_terms),
- GNUNET_PQ_result_spec_uint32 ("age_limit",
- age_limit),
- TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee",
- target_amount),
- TALER_PQ_RESULT_SPEC_AMOUNT ("balance",
- balance),
- GNUNET_PQ_result_spec_auto_from_type ("purse_sig",
- purse_sig),
- GNUNET_PQ_result_spec_end
- };
- return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "select_purse_by_merge_pub",
- params,
- rs);
-}
-
-
-/**
- * Function called to execute a transaction crediting
- * a purse with @a amount from @a coin_pub. Reduces the
- * value of @a coin_pub and increase the balance of
- * the @a purse_pub purse. If the balance reaches the
- * target amount and the purse has been merged, triggers
- * the updates of the reserve/account balance.
- *
- * @param cls the @e cls of this struct with the plugin-specific state
- * @param purse_pub purse to credit
- * @param coin_pub coin to deposit (debit)
- * @param amount fraction of the coin's value to deposit
- * @param coin_sig signature affirming the operation
- * @param amount_minus_fee amount to add to the purse
- * @param[out] balance_ok set to false if the coin's
- * remaining balance is below @a amount;
- * in this case, the return value will be
- * #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT despite the failure
- * @param[out] conflict set to true if the deposit failed due to a conflict (coin already spent,
- * or deposited into this purse with a different amount)
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_do_purse_deposit (
- void *cls,
- const struct TALER_PurseContractPublicKeyP *purse_pub,
- const struct TALER_CoinSpendPublicKeyP *coin_pub,
- const struct TALER_Amount *amount,
- const struct TALER_CoinSpendSignatureP *coin_sig,
- const struct TALER_Amount *amount_minus_fee,
- bool *balance_ok,
- bool *conflict)
-{
- struct PostgresClosure *pg = cls;
- uint64_t partner_id = 0; /* FIXME: WAD support... */
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_uint64 (&partner_id),
- GNUNET_PQ_query_param_auto_from_type (purse_pub),
- TALER_PQ_query_param_amount (amount),
- GNUNET_PQ_query_param_auto_from_type (coin_pub),
- GNUNET_PQ_query_param_auto_from_type (coin_sig),
- TALER_PQ_query_param_amount (amount_minus_fee),
- GNUNET_PQ_query_param_end
- };
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_bool ("balance_ok",
- balance_ok),
- GNUNET_PQ_result_spec_bool ("conflict",
- conflict),
- GNUNET_PQ_result_spec_end
- };
-
- return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "call_purse_deposit",
- params,
- rs);
-}
-
-
-/**
- * Set the current @a balance in the purse
- * identified by @a purse_pub. Used by the auditor
- * to update the balance as calculated by the auditor.
- *
- * @param cls closure
- * @param purse_pub public key of a purse
- * @param balance new balance to store under the purse
- * @return transaction status
- */
-static enum GNUNET_DB_QueryStatus
-postgres_set_purse_balance (
- void *cls,
- const struct TALER_PurseContractPublicKeyP *purse_pub,
- const struct TALER_Amount *balance)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (purse_pub),
- TALER_PQ_query_param_amount (balance),
- GNUNET_PQ_query_param_end
- };
-
- return GNUNET_PQ_eval_prepared_non_select (pg->conn,
- "set_purse_balance",
- params);
-}
-
-
-/**
- * Function called to obtain a coin deposit data from
- * depositing the coin into a purse.
- *
- * @param cls the @e cls of this struct with the plugin-specific state
- * @param purse_pub purse to credit
- * @param coin_pub coin to deposit (debit)
- * @param[out] amount set fraction of the coin's value that was deposited (with fee)
- * @param[out] h_denom_pub set to hash of denomination of the coin
- * @param[out] phac set to hash of age restriction on the coin
- * @param[out] coin_sig set to signature affirming the operation
- * @param[out] partner_url set to the URL of the partner exchange, or NULL for ourselves, must be freed by caller
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_get_purse_deposit (
- void *cls,
- const struct TALER_PurseContractPublicKeyP *purse_pub,
- const struct TALER_CoinSpendPublicKeyP *coin_pub,
- struct TALER_Amount *amount,
- struct TALER_DenominationHashP *h_denom_pub,
- struct TALER_AgeCommitmentHash *phac,
- struct TALER_CoinSpendSignatureP *coin_sig,
- char **partner_url)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (purse_pub),
- GNUNET_PQ_query_param_auto_from_type (coin_pub),
- GNUNET_PQ_query_param_end
- };
- bool is_null;
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash",
- h_denom_pub),
- GNUNET_PQ_result_spec_auto_from_type ("age_commitment_hash",
- phac),
- GNUNET_PQ_result_spec_auto_from_type ("coin_sig",
- coin_sig),
- TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee",
- amount),
- GNUNET_PQ_result_spec_allow_null (
- GNUNET_PQ_result_spec_string ("partner_base_url",
- partner_url),
- &is_null),
- GNUNET_PQ_result_spec_end
- };
-
- *partner_url = NULL;
- return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "select_purse_deposit_by_coin_pub",
- params,
- rs);
-}
-
-
-/**
- * Function called to approve merging a purse into a
- * reserve by the respective purse merge key.
- *
- * @param cls the @e cls of this struct with the plugin-specific state
- * @param purse_pub purse to merge
- * @param merge_sig signature affirming the merge
- * @param merge_timestamp time of the merge
- * @param reserve_sig signature of the reserve affirming the merge
- * @param partner_url URL of the partner exchange, can be NULL if the reserves lives with us
- * @param reserve_pub public key of the reserve to credit
- * @param require_kyc true if we should check for KYC
- * @param[out] no_partner set to true if @a partner_url is unknown
- * @param[out] no_balance set to true if the @a purse_pub is not paid up yet
- * @param[out] no_reserve set to true if the @a reserve_pub is not known
- * @param[out] no_kyc set to true if the @a reserve_pub lacks KYC
- * @param[out] in_conflict set to true if @a purse_pub was merged into a different reserve already
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_do_purse_merge (
- void *cls,
- const struct TALER_PurseContractPublicKeyP *purse_pub,
- const struct TALER_PurseMergeSignatureP *merge_sig,
- const struct GNUNET_TIME_Timestamp merge_timestamp,
- const struct TALER_ReserveSignatureP *reserve_sig,
- const char *partner_url,
- const struct TALER_ReservePublicKeyP *reserve_pub,
- bool require_kyc,
- bool *no_partner,
- bool *no_balance,
- bool *no_reserve,
- bool *no_kyc,
- bool *in_conflict)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (purse_pub),
- GNUNET_PQ_query_param_auto_from_type (merge_sig),
- GNUNET_PQ_query_param_timestamp (&merge_timestamp),
- GNUNET_PQ_query_param_auto_from_type (reserve_sig),
- (NULL == partner_url)
- ? GNUNET_PQ_query_param_null ()
- : GNUNET_PQ_query_param_string (partner_url),
- GNUNET_PQ_query_param_auto_from_type (reserve_pub),
- GNUNET_PQ_query_param_bool (require_kyc),
- GNUNET_PQ_query_param_end
- };
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_bool ("no_partner",
- no_partner),
- GNUNET_PQ_result_spec_bool ("no_balance",
- no_balance),
- GNUNET_PQ_result_spec_bool ("no_kyc",
- no_kyc),
- GNUNET_PQ_result_spec_bool ("no_reserve",
- no_reserve),
- GNUNET_PQ_result_spec_bool ("conflict",
- in_conflict),
- GNUNET_PQ_result_spec_end
- };
-
- return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "call_purse_merge",
- params,
- rs);
-}
-
-
-/**
- * Function called insert request to merge a purse into a reserve by the
- * respective purse merge key. The purse must not have been merged into a
- * different reserve.
- *
- * @param cls the @e cls of this struct with the plugin-specific state
- * @param purse_pub purse to merge
- * @param merge_sig signature affirming the merge
- * @param merge_timestamp time of the merge
- * @param reserve_sig signature of the reserve affirming the merge
- * @param purse_fee amount to charge the reserve for the purse creation, NULL to use the quota
- * @param reserve_pub public key of the reserve to credit
- * @param require_kyc true if we should check for KYC
- * @param[out] in_conflict set to true if @a purse_pub was merged into a different reserve already
- * @param[out] no_reserve set to true if @a reserve_pub is not a known reserve
- * @param[out] no_kyc set to true if @a reserve_pub has not passed KYC checks
- * @param[out] insufficient_funds set to true if @a reserve_pub has insufficient capacity to create another purse
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_do_reserve_purse (
- void *cls,
- const struct TALER_PurseContractPublicKeyP *purse_pub,
- const struct TALER_PurseMergeSignatureP *merge_sig,
- const struct GNUNET_TIME_Timestamp merge_timestamp,
- const struct TALER_ReserveSignatureP *reserve_sig,
- const struct TALER_Amount *purse_fee,
- const struct TALER_ReservePublicKeyP *reserve_pub,
- bool require_kyc,
- bool *in_conflict,
- bool *no_reserve,
- bool *no_kyc,
- bool *insufficient_funds)
-{
- struct PostgresClosure *pg = cls;
- struct TALER_Amount zero_fee;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (purse_pub),
- GNUNET_PQ_query_param_auto_from_type (merge_sig),
- GNUNET_PQ_query_param_timestamp (&merge_timestamp),
- GNUNET_PQ_query_param_auto_from_type (reserve_sig),
- GNUNET_PQ_query_param_bool (NULL == purse_fee),
- TALER_PQ_query_param_amount (NULL == purse_fee
- ? &zero_fee
- : purse_fee),
- GNUNET_PQ_query_param_auto_from_type (reserve_pub),
- GNUNET_PQ_query_param_bool (require_kyc),
- GNUNET_PQ_query_param_end
- };
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_bool ("insufficient_funds",
- insufficient_funds),
- GNUNET_PQ_result_spec_bool ("conflict",
- in_conflict),
- GNUNET_PQ_result_spec_bool ("no_kyc",
- no_kyc),
- GNUNET_PQ_result_spec_bool ("no_reserve",
- no_reserve),
- GNUNET_PQ_result_spec_end
- };
-
- GNUNET_assert (GNUNET_OK ==
- TALER_amount_set_zero (pg->currency,
- &zero_fee));
- return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "call_reserve_purse",
- params,
- rs);
-}
-
-
-/**
- * Function called to approve merging of a purse with
- * an account, made by the receiving account.
- *
- * @param cls the @e cls of this struct with the plugin-specific state
- * @param purse_pub public key of the purse
- * @param[out] merge_sig set to the signature confirming the merge
- * @param[out] merge_timestamp set to the time of the merge
- * @param[out] partner_url set to the URL of the target exchange, or NULL if the target exchange is us. To be freed by the caller.
- * @param[out] reserve_pub set to the public key of the reserve/account being credited
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_select_purse_merge (
- void *cls,
- const struct TALER_PurseContractPublicKeyP *purse_pub,
- struct TALER_PurseMergeSignatureP *merge_sig,
- struct GNUNET_TIME_Timestamp *merge_timestamp,
- char **partner_url,
- struct TALER_ReservePublicKeyP *reserve_pub)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (purse_pub),
- GNUNET_PQ_query_param_end
- };
- bool is_null;
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_auto_from_type ("merge_sig",
- merge_sig),
- GNUNET_PQ_result_spec_auto_from_type ("reserve_pub",
- reserve_pub),
- GNUNET_PQ_result_spec_timestamp ("merge_timestamp",
- merge_timestamp),
- GNUNET_PQ_result_spec_allow_null (
- GNUNET_PQ_result_spec_string ("partner_base_url",
- partner_url),
- &is_null),
- GNUNET_PQ_result_spec_end
- };
-
- *partner_url = NULL;
- return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "select_purse_merge",
- params,
- rs);
-}
-
-
-/**
- * Function called to persist a signature that
- * prove that the client requested an
- * account history. Debits the @a history_fee from
- * the reserve (if possible).
- *
- * @param cls the @e cls of this struct with the plugin-specific state
- * @param reserve_pub account that the history was requested for
- * @param reserve_sig signature affirming the request
- * @param request_timestamp when was the request made
- * @param history_fee how much should the @a reserve_pub be charged for the request
- * @param[out] balance_ok set to TRUE if the reserve balance
- * was sufficient
- * @param[out] idempotent set to TRUE if the request is already in the DB
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_insert_history_request (
- void *cls,
- const struct TALER_ReservePublicKeyP *reserve_pub,
- const struct TALER_ReserveSignatureP *reserve_sig,
- struct GNUNET_TIME_Timestamp request_timestamp,
- const struct TALER_Amount *history_fee,
- bool *balance_ok,
- bool *idempotent)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (reserve_pub),
- GNUNET_PQ_query_param_auto_from_type (reserve_sig),
- GNUNET_PQ_query_param_timestamp (&request_timestamp),
- TALER_PQ_query_param_amount (history_fee),
- GNUNET_PQ_query_param_end
- };
- struct GNUNET_PQ_ResultSpec rs[] = {
- GNUNET_PQ_result_spec_bool ("balance_ok",
- balance_ok),
- GNUNET_PQ_result_spec_bool ("idempotent",
- idempotent),
- GNUNET_PQ_result_spec_end
- };
-
- return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "call_history_request",
- params,
- rs);
-}
-
-
-/**
- * Function called to initiate closure of an account.
- *
- * @param cls the @e cls of this struct with the plugin-specific state
- * @param reserve_pub public key of the account to close
- * @param reserve_sig signature affiming that the account is to be closed
- * @param[out] final_balance set to the final balance in the account that will be wired back to the origin account
- * @return transaction status code
- */
-static enum GNUNET_DB_QueryStatus
-postgres_insert_close_request (
- void *cls,
- const struct TALER_ReservePublicKeyP *reserve_pub,
- const struct TALER_ReserveSignatureP *reserve_sig,
- struct GNUNET_TIME_Timestamp request_timestamp,
- struct TALER_Amount *final_balance)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (reserve_pub),
- GNUNET_PQ_query_param_timestamp (&request_timestamp),
- GNUNET_PQ_query_param_auto_from_type (reserve_sig),
- GNUNET_PQ_query_param_end
- };
- struct GNUNET_PQ_ResultSpec rs[] = {
- TALER_PQ_RESULT_SPEC_AMOUNT ("out_final_balance",
- final_balance),
- GNUNET_PQ_result_spec_end
- };
-
- return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
- "call_account_close",
- params,
- rs);
-}
-
-
-/**
* Initialize Postgres database subsystem.
*
* @param cls a configuration instance
@@ -15951,6 +321,7 @@ libtaler_plugin_exchangedb_postgres_init (void *cls)
const struct GNUNET_CONFIGURATION_Handle *cfg = cls;
struct PostgresClosure *pg;
struct TALER_EXCHANGEDB_Plugin *plugin;
+ unsigned long long dpl;
pg = GNUNET_new (struct PostgresClosure);
pg->cfg = cfg;
@@ -15962,7 +333,7 @@ libtaler_plugin_exchangedb_postgres_init (void *cls)
{
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
"exchangedb-postgres",
- "CONFIG");
+ "SQL_DIR");
GNUNET_free (pg);
return NULL;
}
@@ -15979,21 +350,29 @@ libtaler_plugin_exchangedb_postgres_init (void *cls)
GNUNET_free (pg);
return NULL;
}
- if ( (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_time (cfg,
- "exchangedb",
- "IDLE_RESERVE_EXPIRATION_TIME",
- &pg->idle_reserve_expiration_time))
- ||
- (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_time (cfg,
- "exchangedb",
- "LEGAL_RESERVE_EXPIRATION_TIME",
- &pg->legal_reserve_expiration_time)) )
+ if (GNUNET_OK !=
+ GNUNET_CONFIGURATION_get_value_time (cfg,
+ "exchangedb",
+ "IDLE_RESERVE_EXPIRATION_TIME",
+ &pg->idle_reserve_expiration_time))
{
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
"exchangedb",
- "LEGAL/IDLE_RESERVE_EXPIRATION_TIME");
+ "IDLE_RESERVE_EXPIRATION_TIME");
+ GNUNET_free (pg->exchange_url);
+ GNUNET_free (pg->sql_dir);
+ GNUNET_free (pg);
+ return NULL;
+ }
+ if (GNUNET_OK !=
+ GNUNET_CONFIGURATION_get_value_time (cfg,
+ "exchangedb",
+ "LEGAL_RESERVE_EXPIRATION_TIME",
+ &pg->legal_reserve_expiration_time))
+ {
+ GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
+ "exchangedb",
+ "LEGAL_RESERVE_EXPIRATION_TIME");
GNUNET_free (pg->exchange_url);
GNUNET_free (pg->sql_dir);
GNUNET_free (pg);
@@ -16009,6 +388,21 @@ libtaler_plugin_exchangedb_postgres_init (void *cls)
"exchangedb",
"AGGREGATOR_SHIFT");
}
+ if (GNUNET_OK !=
+ GNUNET_CONFIGURATION_get_value_number (cfg,
+ "exchangedb",
+ "DEFAULT_PURSE_LIMIT",
+ &dpl))
+ {
+ GNUNET_log_config_missing (GNUNET_ERROR_TYPE_WARNING,
+ "exchangedb",
+ "DEFAULT_PURSE_LIMIT");
+ pg->def_purse_limit = 1;
+ }
+ else
+ {
+ pg->def_purse_limit = (uint32_t) dpl;
+ }
if (GNUNET_OK !=
TALER_config_get_currency (cfg,
@@ -16020,8 +414,7 @@ libtaler_plugin_exchangedb_postgres_init (void *cls)
return NULL;
}
if (GNUNET_OK !=
- internal_setup (pg,
- true))
+ TEH_PG_internal_setup (pg))
{
GNUNET_free (pg->exchange_url);
GNUNET_free (pg->currency);
@@ -16029,231 +422,378 @@ libtaler_plugin_exchangedb_postgres_init (void *cls)
GNUNET_free (pg);
return NULL;
}
-
plugin = GNUNET_new (struct TALER_EXCHANGEDB_Plugin);
plugin->cls = pg;
- plugin->drop_tables = &postgres_drop_tables;
- plugin->drop_shard_tables = &postgres_drop_shard_tables;
- plugin->create_tables = &postgres_create_tables;
- plugin->create_shard_tables = &postgres_create_shard_tables;
- plugin->setup_partitions = &postgres_setup_partitions;
- plugin->setup_foreign_servers = &postgres_setup_foreign_servers;
- plugin->start = &postgres_start;
- plugin->start_read_committed = &postgres_start_read_committed;
- plugin->commit = &postgres_commit;
- plugin->preflight = &postgres_preflight;
- plugin->rollback = &postgres_rollback;
- plugin->event_listen = &postgres_event_listen;
- plugin->event_listen_cancel = &postgres_event_listen_cancel;
- plugin->event_notify = &postgres_event_notify;
- plugin->insert_denomination_info = &postgres_insert_denomination_info;
- plugin->get_denomination_info = &postgres_get_denomination_info;
- plugin->iterate_denomination_info = &postgres_iterate_denomination_info;
- plugin->iterate_denominations = &postgres_iterate_denominations;
- plugin->iterate_active_signkeys = &postgres_iterate_active_signkeys;
- plugin->iterate_active_auditors = &postgres_iterate_active_auditors;
- plugin->iterate_auditor_denominations =
- &postgres_iterate_auditor_denominations;
- plugin->select_kyc_status = &postgres_select_kyc_status;
- plugin->reserves_get = &postgres_reserves_get;
- plugin->set_kyc_ok = &postgres_set_kyc_ok;
- plugin->inselect_wallet_kyc_status = &postgres_inselect_wallet_kyc_status;
- plugin->reserves_in_insert = &postgres_reserves_in_insert;
- plugin->get_withdraw_info = &postgres_get_withdraw_info;
- plugin->do_withdraw = &postgres_do_withdraw;
- plugin->do_batch_withdraw = &postgres_do_batch_withdraw;
- plugin->do_batch_withdraw_insert = &postgres_do_batch_withdraw_insert;
- plugin->do_withdraw_limit_check = &postgres_do_withdraw_limit_check;
- plugin->do_deposit = &postgres_do_deposit;
- plugin->do_melt = &postgres_do_melt;
- plugin->do_refund = &postgres_do_refund;
- plugin->do_recoup = &postgres_do_recoup;
- plugin->do_recoup_refresh = &postgres_do_recoup_refresh;
- plugin->get_reserve_balance = &postgres_get_reserve_balance;
- plugin->get_reserve_history = &postgres_get_reserve_history;
- plugin->get_reserve_status = &postgres_get_reserve_status;
- plugin->free_reserve_history = &common_free_reserve_history;
- plugin->count_known_coins = &postgres_count_known_coins;
- plugin->ensure_coin_known = &postgres_ensure_coin_known;
- plugin->get_known_coin = &postgres_get_known_coin;
- plugin->get_coin_denomination = &postgres_get_coin_denomination;
- plugin->have_deposit2 = &postgres_have_deposit2;
- plugin->aggregate = &postgres_aggregate;
- plugin->create_aggregation_transient
- = &postgres_create_aggregation_transient;
- plugin->select_aggregation_transient
- = &postgres_select_aggregation_transient;
- plugin->update_aggregation_transient
- = &postgres_update_aggregation_transient;
+ plugin->do_reserve_open
+ = &TEH_PG_do_reserve_open;
+ plugin->drop_tables
+ = &TEH_PG_drop_tables;
+ plugin->free_coin_transaction_list
+ = &TEH_COMMON_free_coin_transaction_list;
+ plugin->free_reserve_history
+ = &TEH_COMMON_free_reserve_history;
+ plugin->get_coin_transactions
+ = &TEH_PG_get_coin_transactions;
+ plugin->get_expired_reserves
+ = &TEH_PG_get_expired_reserves;
+ plugin->get_purse_request
+ = &TEH_PG_get_purse_request;
+ plugin->get_reserve_history
+ = &TEH_PG_get_reserve_history;
+ plugin->get_unfinished_close_requests
+ = &TEH_PG_get_unfinished_close_requests;
+ plugin->insert_records_by_table
+ = &TEH_PG_insert_records_by_table;
+ plugin->insert_reserve_open_deposit
+ = &TEH_PG_insert_reserve_open_deposit;
+ plugin->insert_close_request
+ = &TEH_PG_insert_close_request;
plugin->delete_aggregation_transient
- = &postgres_delete_aggregation_transient;
- plugin->get_ready_deposit = &postgres_get_ready_deposit;
- plugin->insert_deposit = &postgres_insert_deposit;
- plugin->insert_refund = &postgres_insert_refund;
- plugin->select_refunds_by_coin = &postgres_select_refunds_by_coin;
- plugin->get_melt = &postgres_get_melt;
- plugin->insert_refresh_reveal = &postgres_insert_refresh_reveal;
- plugin->get_refresh_reveal = &postgres_get_refresh_reveal;
- plugin->get_link_data = &postgres_get_link_data;
- plugin->get_coin_transactions = &postgres_get_coin_transactions;
- plugin->free_coin_transaction_list = &common_free_coin_transaction_list;
- plugin->lookup_wire_transfer = &postgres_lookup_wire_transfer;
- plugin->lookup_transfer_by_deposit = &postgres_lookup_transfer_by_deposit;
- plugin->insert_aggregation_tracking = &postgres_insert_aggregation_tracking;
- plugin->insert_wire_fee = &postgres_insert_wire_fee;
- plugin->insert_global_fee = &postgres_insert_global_fee;
- plugin->get_wire_fee = &postgres_get_wire_fee;
- plugin->get_global_fee = &postgres_get_global_fee;
- plugin->get_global_fees = &postgres_get_global_fees;
- plugin->get_expired_reserves = &postgres_get_expired_reserves;
- plugin->insert_reserve_closed = &postgres_insert_reserve_closed;
- plugin->wire_prepare_data_insert = &postgres_wire_prepare_data_insert;
- plugin->wire_prepare_data_mark_finished =
- &postgres_wire_prepare_data_mark_finished;
- plugin->wire_prepare_data_mark_failed =
- &postgres_wire_prepare_data_mark_failed;
- plugin->wire_prepare_data_get = &postgres_wire_prepare_data_get;
- plugin->start_deferred_wire_out = &postgres_start_deferred_wire_out;
- plugin->store_wire_transfer_out = &postgres_store_wire_transfer_out;
- plugin->gc = &postgres_gc;
- plugin->select_deposits_above_serial_id
- = &postgres_select_deposits_above_serial_id;
- plugin->select_purse_deposits_above_serial_id
- = &postgres_select_purse_deposits_above_serial_id;
+ = &TEH_PG_delete_aggregation_transient;
+ plugin->get_link_data
+ = &TEH_PG_get_link_data;
+ plugin->iterate_reserve_close_info
+ = &TEH_PG_iterate_reserve_close_info;
+ plugin->iterate_kyc_reference
+ = &TEH_PG_iterate_kyc_reference;
+ plugin->lookup_records_by_table
+ = &TEH_PG_lookup_records_by_table;
+ plugin->lookup_serial_by_table
+ = &TEH_PG_lookup_serial_by_table;
plugin->select_account_merges_above_serial_id
- = &postgres_select_account_merges_above_serial_id;
+ = &TEH_PG_select_account_merges_above_serial_id;
+ plugin->select_all_purse_decisions_above_serial_id
+ = &TEH_PG_select_all_purse_decisions_above_serial_id;
+ plugin->select_aml_threshold
+ = &TEH_PG_select_aml_threshold;
+ plugin->select_purse
+ = &TEH_PG_select_purse;
+ plugin->select_purse_deposits_above_serial_id
+ = &TEH_PG_select_purse_deposits_above_serial_id;
plugin->select_purse_merges_above_serial_id
- = &postgres_select_purse_merges_above_serial_id;
- plugin->select_history_requests_above_serial_id
- = &postgres_select_history_requests_above_serial_id;
- plugin->select_purse_refunds_above_serial_id
- = &postgres_select_purse_refunds_above_serial_id;
+ = &TEH_PG_select_purse_merges_above_serial_id;
+ plugin->select_purse_requests_above_serial_id
+ = &TEH_PG_select_purse_requests_above_serial_id;
+ plugin->select_reserve_close_info
+ = &TEH_PG_select_reserve_close_info;
+ plugin->select_reserve_closed_above_serial_id
+ = &TEH_PG_select_reserve_closed_above_serial_id;
+ plugin->select_reserve_open_above_serial_id
+ = &TEH_PG_select_reserve_open_above_serial_id;
+ plugin->insert_purse_request
+ = &TEH_PG_insert_purse_request;
+ plugin->iterate_active_signkeys
+ = &TEH_PG_iterate_active_signkeys;
+ plugin->commit
+ = &TEH_PG_commit;
+ plugin->preflight
+ = &TEH_PG_preflight;
+ plugin->select_aggregation_amounts_for_kyc_check
+ = &TEH_PG_select_aggregation_amounts_for_kyc_check;
+ plugin->select_satisfied_kyc_processes
+ = &TEH_PG_select_satisfied_kyc_processes;
+ plugin->kyc_provider_account_lookup
+ = &TEH_PG_kyc_provider_account_lookup;
+ plugin->lookup_kyc_requirement_by_row
+ = &TEH_PG_lookup_kyc_requirement_by_row;
+ plugin->insert_kyc_requirement_for_account
+ = &TEH_PG_insert_kyc_requirement_for_account;
+ plugin->lookup_kyc_process_by_account
+ = &TEH_PG_lookup_kyc_process_by_account;
+ plugin->update_kyc_process_by_row
+ = &TEH_PG_update_kyc_process_by_row;
+ plugin->insert_kyc_requirement_process
+ = &TEH_PG_insert_kyc_requirement_process;
+ plugin->select_withdraw_amounts_for_kyc_check
+ = &TEH_PG_select_withdraw_amounts_for_kyc_check;
+ plugin->select_merge_amounts_for_kyc_check
+ = &TEH_PG_select_merge_amounts_for_kyc_check;
+ plugin->profit_drains_set_finished
+ = &TEH_PG_profit_drains_set_finished;
+ plugin->profit_drains_get_pending
+ = &TEH_PG_profit_drains_get_pending;
+ plugin->get_drain_profit
+ = &TEH_PG_get_drain_profit;
+ plugin->get_purse_deposit
+ = &TEH_PG_get_purse_deposit;
+ plugin->insert_contract
+ = &TEH_PG_insert_contract;
+ plugin->select_contract
+ = &TEH_PG_select_contract;
+ plugin->select_purse_merge
+ = &TEH_PG_select_purse_merge;
+ plugin->select_contract_by_purse
+ = &TEH_PG_select_contract_by_purse;
+ plugin->insert_drain_profit
+ = &TEH_PG_insert_drain_profit;
+ plugin->do_reserve_purse
+ = &TEH_PG_do_reserve_purse;
+ plugin->lookup_global_fee_by_time
+ = &TEH_PG_lookup_global_fee_by_time;
+ plugin->do_purse_deposit
+ = &TEH_PG_do_purse_deposit;
+ plugin->activate_signing_key
+ = &TEH_PG_activate_signing_key;
+ plugin->update_auditor
+ = &TEH_PG_update_auditor;
+ plugin->begin_revolving_shard
+ = &TEH_PG_begin_revolving_shard;
+ plugin->get_extension_manifest
+ = &TEH_PG_get_extension_manifest;
+ plugin->do_purse_merge
+ = &TEH_PG_do_purse_merge;
+ plugin->do_purse_delete
+ = &TEH_PG_do_purse_delete;
+ plugin->start_read_committed
+ = &TEH_PG_start_read_committed;
+ plugin->start_read_only
+ = &TEH_PG_start_read_only;
+ plugin->insert_denomination_info
+ = &TEH_PG_insert_denomination_info;
+ plugin->do_batch_withdraw_insert
+ = &TEH_PG_do_batch_withdraw_insert;
+ plugin->lookup_wire_fee_by_time
+ = &TEH_PG_lookup_wire_fee_by_time;
+ plugin->start
+ = &TEH_PG_start;
+ plugin->rollback
+ = &TEH_PG_rollback;
+ plugin->create_tables
+ = &TEH_PG_create_tables;
+ plugin->event_listen
+ = &TEH_PG_event_listen;
+ plugin->event_listen_cancel
+ = &TEH_PG_event_listen_cancel;
+ plugin->event_notify
+ = &TEH_PG_event_notify;
+ plugin->get_denomination_info
+ = &TEH_PG_get_denomination_info;
+ plugin->iterate_denomination_info
+ = &TEH_PG_iterate_denomination_info;
+ plugin->iterate_denominations
+ = &TEH_PG_iterate_denominations;
+ plugin->iterate_active_auditors
+ = &TEH_PG_iterate_active_auditors;
+ plugin->iterate_auditor_denominations
+ = &TEH_PG_iterate_auditor_denominations;
+ plugin->reserves_get
+ = &TEH_PG_reserves_get;
+ plugin->reserves_get_origin
+ = &TEH_PG_reserves_get_origin;
+ plugin->drain_kyc_alert
+ = &TEH_PG_drain_kyc_alert;
+ plugin->reserves_in_insert
+ = &TEH_PG_reserves_in_insert;
+ plugin->get_withdraw_info
+ = &TEH_PG_get_withdraw_info;
+ plugin->do_batch_withdraw
+ = &TEH_PG_do_batch_withdraw;
+ plugin->do_age_withdraw
+ = &TEH_PG_do_age_withdraw;
+ plugin->get_age_withdraw
+ = &TEH_PG_get_age_withdraw;
+ plugin->get_policy_details
+ = &TEH_PG_get_policy_details;
+ plugin->persist_policy_details
+ = &TEH_PG_persist_policy_details;
+ plugin->do_deposit
+ = &TEH_PG_do_deposit;
+ plugin->get_wire_hash_for_contract
+ = &TEH_PG_get_wire_hash_for_contract;
+ plugin->add_policy_fulfillment_proof
+ = &TEH_PG_add_policy_fulfillment_proof;
+ plugin->do_melt
+ = &TEH_PG_do_melt;
+ plugin->do_refund
+ = &TEH_PG_do_refund;
+ plugin->do_recoup
+ = &TEH_PG_do_recoup;
+ plugin->do_recoup_refresh
+ = &TEH_PG_do_recoup_refresh;
+ plugin->get_reserve_balance
+ = &TEH_PG_get_reserve_balance;
+ plugin->count_known_coins
+ = &TEH_PG_count_known_coins;
+ plugin->ensure_coin_known
+ = &TEH_PG_ensure_coin_known;
+ plugin->get_known_coin
+ = &TEH_PG_get_known_coin;
+ plugin->get_signature_for_known_coin
+ = &TEH_PG_get_signature_for_known_coin;
+ plugin->get_coin_denomination
+ = &TEH_PG_get_coin_denomination;
+ plugin->have_deposit2
+ = &TEH_PG_have_deposit2;
+ plugin->aggregate
+ = &TEH_PG_aggregate;
+ plugin->create_aggregation_transient
+ = &TEH_PG_create_aggregation_transient;
+ plugin->select_aggregation_transient
+ = &TEH_PG_select_aggregation_transient;
+ plugin->find_aggregation_transient
+ = &TEH_PG_find_aggregation_transient;
+ plugin->update_aggregation_transient
+ = &TEH_PG_update_aggregation_transient;
+ plugin->get_ready_deposit
+ = &TEH_PG_get_ready_deposit;
+ plugin->insert_refund
+ = &TEH_PG_insert_refund;
+ plugin->select_refunds_by_coin
+ = &TEH_PG_select_refunds_by_coin;
+ plugin->get_melt
+ = &TEH_PG_get_melt;
+ plugin->insert_refresh_reveal
+ = &TEH_PG_insert_refresh_reveal;
+ plugin->get_refresh_reveal
+ = &TEH_PG_get_refresh_reveal;
+ plugin->lookup_wire_transfer
+ = &TEH_PG_lookup_wire_transfer;
+ plugin->lookup_transfer_by_deposit
+ = &TEH_PG_lookup_transfer_by_deposit;
+ plugin->insert_wire_fee
+ = &TEH_PG_insert_wire_fee;
+ plugin->insert_global_fee
+ = &TEH_PG_insert_global_fee;
+ plugin->get_wire_fee
+ = &TEH_PG_get_wire_fee;
+ plugin->get_global_fee
+ = &TEH_PG_get_global_fee;
+ plugin->get_global_fees
+ = &TEH_PG_get_global_fees;
+ plugin->insert_reserve_closed
+ = &TEH_PG_insert_reserve_closed;
+ plugin->wire_prepare_data_insert
+ = &TEH_PG_wire_prepare_data_insert;
+ plugin->wire_prepare_data_mark_finished
+ = &TEH_PG_wire_prepare_data_mark_finished;
+ plugin->wire_prepare_data_mark_failed
+ = &TEH_PG_wire_prepare_data_mark_failed;
+ plugin->wire_prepare_data_get
+ = &TEH_PG_wire_prepare_data_get;
+ plugin->start_deferred_wire_out
+ = &TEH_PG_start_deferred_wire_out;
+ plugin->store_wire_transfer_out
+ = &TEH_PG_store_wire_transfer_out;
+ plugin->gc
+ = &TEH_PG_gc;
+ plugin->select_coin_deposits_above_serial_id
+ = &TEH_PG_select_coin_deposits_above_serial_id;
+ plugin->select_purse_decisions_above_serial_id
+ = &TEH_PG_select_purse_decisions_above_serial_id;
plugin->select_purse_deposits_by_purse
- = &postgres_select_purse_deposits_by_purse;
+ = &TEH_PG_select_purse_deposits_by_purse;
plugin->select_refreshes_above_serial_id
- = &postgres_select_refreshes_above_serial_id;
+ = &TEH_PG_select_refreshes_above_serial_id;
plugin->select_refunds_above_serial_id
- = &postgres_select_refunds_above_serial_id;
+ = &TEH_PG_select_refunds_above_serial_id;
plugin->select_reserves_in_above_serial_id
- = &postgres_select_reserves_in_above_serial_id;
+ = &TEH_PG_select_reserves_in_above_serial_id;
plugin->select_reserves_in_above_serial_id_by_account
- = &postgres_select_reserves_in_above_serial_id_by_account;
+ = &TEH_PG_select_reserves_in_above_serial_id_by_account;
plugin->select_withdrawals_above_serial_id
- = &postgres_select_withdrawals_above_serial_id;
+ = &TEH_PG_select_withdrawals_above_serial_id;
plugin->select_wire_out_above_serial_id
- = &postgres_select_wire_out_above_serial_id;
+ = &TEH_PG_select_wire_out_above_serial_id;
plugin->select_wire_out_above_serial_id_by_account
- = &postgres_select_wire_out_above_serial_id_by_account;
+ = &TEH_PG_select_wire_out_above_serial_id_by_account;
plugin->select_recoup_above_serial_id
- = &postgres_select_recoup_above_serial_id;
+ = &TEH_PG_select_recoup_above_serial_id;
plugin->select_recoup_refresh_above_serial_id
- = &postgres_select_recoup_refresh_above_serial_id;
- plugin->select_reserve_closed_above_serial_id
- = &postgres_select_reserve_closed_above_serial_id;
+ = &TEH_PG_select_recoup_refresh_above_serial_id;
plugin->get_reserve_by_h_blind
- = &postgres_get_reserve_by_h_blind;
+ = &TEH_PG_get_reserve_by_h_blind;
plugin->get_old_coin_by_h_blind
- = &postgres_get_old_coin_by_h_blind;
+ = &TEH_PG_get_old_coin_by_h_blind;
plugin->insert_denomination_revocation
- = &postgres_insert_denomination_revocation;
+ = &TEH_PG_insert_denomination_revocation;
plugin->get_denomination_revocation
- = &postgres_get_denomination_revocation;
- plugin->select_deposits_missing_wire
- = &postgres_select_deposits_missing_wire;
+ = &TEH_PG_get_denomination_revocation;
+ plugin->select_batch_deposits_missing_wire
+ = &TEH_PG_select_batch_deposits_missing_wire;
+ plugin->select_justification_for_missing_wire
+ = &TEH_PG_select_justification_for_missing_wire;
+ plugin->select_aggregations_above_serial
+ = &TEH_PG_select_aggregations_above_serial;
plugin->lookup_auditor_timestamp
- = &postgres_lookup_auditor_timestamp;
+ = &TEH_PG_lookup_auditor_timestamp;
plugin->lookup_auditor_status
- = &postgres_lookup_auditor_status;
+ = &TEH_PG_lookup_auditor_status;
plugin->insert_auditor
- = &postgres_insert_auditor;
- plugin->update_auditor
- = &postgres_update_auditor;
+ = &TEH_PG_insert_auditor;
plugin->lookup_wire_timestamp
- = &postgres_lookup_wire_timestamp;
+ = &TEH_PG_lookup_wire_timestamp;
plugin->insert_wire
- = &postgres_insert_wire;
+ = &TEH_PG_insert_wire;
plugin->update_wire
- = &postgres_update_wire;
+ = &TEH_PG_update_wire;
plugin->get_wire_accounts
- = &postgres_get_wire_accounts;
+ = &TEH_PG_get_wire_accounts;
plugin->get_wire_fees
- = &postgres_get_wire_fees;
+ = &TEH_PG_get_wire_fees;
plugin->insert_signkey_revocation
- = &postgres_insert_signkey_revocation;
+ = &TEH_PG_insert_signkey_revocation;
plugin->lookup_signkey_revocation
- = &postgres_lookup_signkey_revocation;
+ = &TEH_PG_lookup_signkey_revocation;
plugin->lookup_denomination_key
- = &postgres_lookup_denomination_key;
+ = &TEH_PG_lookup_denomination_key;
plugin->insert_auditor_denom_sig
- = &postgres_insert_auditor_denom_sig;
+ = &TEH_PG_insert_auditor_denom_sig;
plugin->select_auditor_denom_sig
- = &postgres_select_auditor_denom_sig;
- plugin->lookup_wire_fee_by_time
- = &postgres_lookup_wire_fee_by_time;
- plugin->lookup_global_fee_by_time
- = &postgres_lookup_global_fee_by_time;
+ = &TEH_PG_select_auditor_denom_sig;
plugin->add_denomination_key
- = &postgres_add_denomination_key;
- plugin->activate_signing_key
- = &postgres_activate_signing_key;
+ = &TEH_PG_add_denomination_key;
plugin->lookup_signing_key
- = &postgres_lookup_signing_key;
- plugin->lookup_serial_by_table
- = &postgres_lookup_serial_by_table;
- plugin->lookup_records_by_table
- = &postgres_lookup_records_by_table;
- plugin->insert_records_by_table
- = &postgres_insert_records_by_table;
+ = &TEH_PG_lookup_signing_key;
plugin->begin_shard
- = &postgres_begin_shard;
+ = &TEH_PG_begin_shard;
plugin->abort_shard
- = &postgres_abort_shard;
+ = &TEH_PG_abort_shard;
+ plugin->insert_kyc_failure
+ = &TEH_PG_insert_kyc_failure;
plugin->complete_shard
- = &postgres_complete_shard;
- plugin->begin_revolving_shard
- = &postgres_begin_revolving_shard;
+ = &TEH_PG_complete_shard;
plugin->release_revolving_shard
- = &postgres_release_revolving_shard;
+ = &TEH_PG_release_revolving_shard;
plugin->delete_shard_locks
- = &postgres_delete_shard_locks;
- plugin->set_extension_config
- = &postgres_set_extension_config;
- plugin->get_extension_config
- = &postgres_get_extension_config;
+ = &TEH_PG_delete_shard_locks;
+ plugin->set_extension_manifest
+ = &TEH_PG_set_extension_manifest;
plugin->insert_partner
- = &postgres_insert_partner;
- plugin->insert_contract
- = &postgres_insert_contract;
- plugin->select_contract
- = &postgres_select_contract;
- plugin->select_contract_by_purse
- = &postgres_select_contract_by_purse;
- plugin->insert_purse_request
- = &postgres_insert_purse_request;
- plugin->select_purse_request
- = &postgres_select_purse_request;
+ = &TEH_PG_insert_partner;
plugin->expire_purse
- = &postgres_expire_purse;
- plugin->select_purse
- = &postgres_select_purse;
+ = &TEH_PG_expire_purse;
plugin->select_purse_by_merge_pub
- = &postgres_select_purse_by_merge_pub;
- plugin->do_purse_deposit
- = &postgres_do_purse_deposit;
+ = &TEH_PG_select_purse_by_merge_pub;
plugin->set_purse_balance
- = &postgres_set_purse_balance;
- plugin->get_purse_deposit
- = &postgres_get_purse_deposit;
- plugin->do_purse_merge
- = &postgres_do_purse_merge;
- plugin->do_reserve_purse
- = &postgres_do_reserve_purse;
- plugin->select_purse_merge
- = &postgres_select_purse_merge;
- plugin->insert_history_request
- = &postgres_insert_history_request;
- plugin->insert_close_request
- = &postgres_insert_close_request;
+ = &TEH_PG_set_purse_balance;
+ plugin->get_pending_kyc_requirement_process
+ = &TEH_PG_get_pending_kyc_requirement_process;
+ plugin->insert_kyc_attributes
+ = &TEH_PG_insert_kyc_attributes;
+ plugin->select_similar_kyc_attributes
+ = &TEH_PG_select_similar_kyc_attributes;
+ plugin->select_kyc_attributes
+ = &TEH_PG_select_kyc_attributes;
+ plugin->insert_aml_officer
+ = &TEH_PG_insert_aml_officer;
+ plugin->test_aml_officer
+ = &TEH_PG_test_aml_officer;
+ plugin->lookup_aml_officer
+ = &TEH_PG_lookup_aml_officer;
+ plugin->trigger_aml_process
+ = &TEH_PG_trigger_aml_process;
+ plugin->select_aml_process
+ = &TEH_PG_select_aml_process;
+ plugin->select_aml_history
+ = &TEH_PG_select_aml_history;
+ plugin->insert_aml_decision
+ = &TEH_PG_insert_aml_decision;
+
+ plugin->batch_ensure_coin_known
+ = &TEH_PG_batch_ensure_coin_known;
+ plugin->inject_auditor_triggers
+ = &TEH_PG_inject_auditor_triggers;
+
return plugin;
}