exchange

Base system with REST service to issue digital coins, run by the payment service provider
Log | Files | Refs | Submodules | README | LICENSE

plugin_exchangedb_postgres.c (29894B)


      1 /*
      2    This file is part of TALER
      3    Copyright (C) 2014--2025 Taler Systems SA
      4 
      5    TALER is free software; you can redistribute it and/or modify it under the
      6    terms of the GNU General Public License as published by the Free Software
      7    Foundation; either version 3, or (at your option) any later version.
      8 
      9    TALER is distributed in the hope that it will be useful, but WITHOUT ANY
     10    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
     11    A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
     12 
     13    You should have received a copy of the GNU General Public License along with
     14    TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
     15  */
     16 
     17 /**
     18  * @file plugin_exchangedb_postgres.c
     19  * @brief Low-level (statement-level) Postgres database access for the exchange
     20  * @author Florian Dold
     21  * @author Christian Grothoff
     22  * @author Sree Harsha Totakura
     23  * @author Marcello Stanisci
     24  * @author Özgür Kesim
     25  */
     26 #include "taler/platform.h"
     27 #include <poll.h>
     28 #include <pthread.h>
     29 #include <libpq-fe.h>
     30 #include "pg_abort_shard.h"
     31 #include "pg_activate_signing_key.h"
     32 #include "pg_add_denomination_key.h"
     33 #include "pg_add_policy_fulfillment_proof.h"
     34 #include "pg_aggregate.h"
     35 #include "pg_batch_ensure_coin_known.h"
     36 #include "pg_begin_revolving_shard.h"
     37 #include "pg_begin_shard.h"
     38 #include "pg_clear_aml_lock.h"
     39 #include "pg_commit.h"
     40 #include "pg_complete_shard.h"
     41 #include "pg_compute_shard.h"
     42 #include "pg_count_known_coins.h"
     43 #include "pg_create_aggregation_transient.h"
     44 #include "pg_create_tables.h"
     45 #include "pg_delete_aggregation_transient.h"
     46 #include "pg_delete_shard_locks.h"
     47 #include "pg_disable_rules.h"
     48 #include "pg_do_withdraw.h"
     49 #include "pg_do_check_deposit_idempotent.h"
     50 #include "pg_do_deposit.h"
     51 #include "pg_do_melt.h"
     52 #include "pg_do_purse_delete.h"
     53 #include "pg_do_purse_deposit.h"
     54 #include "pg_do_purse_merge.h"
     55 #include "pg_do_recoup.h"
     56 #include "pg_do_recoup_refresh.h"
     57 #include "pg_do_refresh.h"
     58 #include "pg_do_refund.h"
     59 #include "pg_do_reserve_open.h"
     60 #include "pg_do_reserve_purse.h"
     61 #include "pg_drain_kyc_alert.h"
     62 #include "pg_drop_tables.h"
     63 #include "pg_enable_rules.h"
     64 #include "pg_ensure_coin_known.h"
     65 #include "pg_event_listen.h"
     66 #include "pg_event_listen_cancel.h"
     67 #include "pg_event_notify.h"
     68 #include "pg_expire_purse.h"
     69 #include "pg_find_aggregation_transient.h"
     70 #include "pg_gc.h"
     71 #include "pg_get_withdraw.h"
     72 #include "pg_get_coin_denomination.h"
     73 #include "pg_get_coin_transactions.h"
     74 #include "pg_get_denomination_info.h"
     75 #include "pg_get_denomination_by_serial.h"
     76 #include "pg_get_denomination_revocation.h"
     77 #include "pg_get_drain_profit.h"
     78 #include "pg_get_expired_reserves.h"
     79 #include "pg_get_extension_manifest.h"
     80 #include "pg_get_global_fee.h"
     81 #include "pg_get_global_fees.h"
     82 #include "pg_get_known_coin.h"
     83 #include "pg_get_kyc_rules.h"
     84 #include "pg_get_old_coin_by_h_blind.h"
     85 #include "pg_get_pending_kyc_requirement_process.h"
     86 #include "pg_get_policy_details.h"
     87 #include "pg_get_purse_deposit.h"
     88 #include "pg_get_purse_request.h"
     89 #include "pg_get_ready_deposit.h"
     90 #include "pg_get_refresh.h"
     91 #include "pg_get_refresh_reveal.h"
     92 #include "pg_get_reserve_balance.h"
     93 #include "pg_get_reserve_by_h_planchets.h"
     94 #include "pg_get_reserve_history.h"
     95 #include "pg_get_signature_for_known_coin.h"
     96 #include "pg_get_unfinished_close_requests.h"
     97 #include "pg_get_wire_accounts.h"
     98 #include "pg_get_wire_fee.h"
     99 #include "pg_get_wire_fees.h"
    100 #include "pg_get_wire_hash_for_contract.h"
    101 #include "pg_have_deposit2.h"
    102 #include "pg_helper.h"
    103 #include "pg_inject_auditor_triggers.h"
    104 #include "pg_insert_active_legitimization_measure.h"
    105 #include "pg_insert_aml_decision.h"
    106 #include "pg_insert_aml_officer.h"
    107 #include "pg_insert_aml_program_failure.h"
    108 #include "pg_insert_auditor.h"
    109 #include "pg_insert_auditor_denom_sig.h"
    110 #include "pg_insert_close_request.h"
    111 #include "pg_insert_contract.h"
    112 #include "pg_insert_denomination_info.h"
    113 #include "pg_insert_denomination_revocation.h"
    114 #include "pg_insert_drain_profit.h"
    115 #include "pg_insert_global_fee.h"
    116 #include "pg_insert_kyc_failure.h"
    117 #include "pg_insert_kyc_requirement_process.h"
    118 #include "pg_insert_partner.h"
    119 #include "pg_insert_purse_request.h"
    120 #include "pg_insert_records_by_table.h"
    121 #include "pg_insert_refund.h"
    122 #include "pg_insert_reserve_closed.h"
    123 #include "pg_insert_reserve_open_deposit.h"
    124 #include "pg_insert_sanction_list_hit.h"
    125 #include "pg_insert_signkey_revocation.h"
    126 #include "pg_insert_successor_measure.h"
    127 #include "pg_insert_wire.h"
    128 #include "pg_insert_wire_fee.h"
    129 #include "pg_iterate_active_auditors.h"
    130 #include "pg_iterate_active_signkeys.h"
    131 #include "pg_iterate_auditor_denominations.h"
    132 #include "pg_iterate_denomination_info.h"
    133 #include "pg_iterate_denominations.h"
    134 #include "pg_iterate_kyc_reference.h"
    135 #include "pg_iterate_reserve_close_info.h"
    136 #include "pg_kyc_provider_account_lookup.h"
    137 #include "pg_kycauth_in_insert.h"
    138 #include "pg_lookup_active_legitimization.h"
    139 #include "pg_lookup_aml_file_number.h"
    140 #include "pg_lookup_aml_history.h"
    141 #include "pg_lookup_aml_officer.h"
    142 #include "pg_lookup_auditor_status.h"
    143 #include "pg_lookup_auditor_timestamp.h"
    144 #include "pg_lookup_completed_legitimization.h"
    145 #include "pg_lookup_denomination_key.h"
    146 #include "pg_lookup_global_fee_by_time.h"
    147 #include "pg_lookup_h_payto_by_access_token.h"
    148 #include "pg_lookup_kyc_history.h"
    149 #include "pg_lookup_kyc_process_by_account.h"
    150 #include "pg_lookup_kyc_requirement_by_row.h"
    151 #include "pg_lookup_kyc_status_by_token.h"
    152 #include "pg_lookup_pending_legitimization.h"
    153 #include "pg_lookup_records_by_table.h"
    154 #include "pg_lookup_rules_by_access_token.h"
    155 #include "pg_lookup_serial_by_table.h"
    156 #include "pg_lookup_signing_key.h"
    157 #include "pg_lookup_signkey_revocation.h"
    158 #include "pg_lookup_transfer_by_deposit.h"
    159 #include "pg_lookup_wire_fee_by_time.h"
    160 #include "pg_lookup_wire_timestamp.h"
    161 #include "pg_lookup_wire_transfer.h"
    162 #include "pg_persist_kyc_attributes.h"
    163 #include "pg_persist_policy_details.h"
    164 #include "pg_preflight.h"
    165 #include "pg_profit_drains_get_pending.h"
    166 #include "pg_profit_drains_set_finished.h"
    167 #include "pg_release_revolving_shard.h"
    168 #include "pg_reserves_get.h"
    169 #include "pg_reserves_get_origin.h"
    170 #include "pg_reserves_in_insert.h"
    171 #include "pg_reserves_update.h"
    172 #include "pg_rollback.h"
    173 #include "pg_select_account_merges_above_serial_id.h"
    174 #include "pg_select_aggregation_amounts_for_kyc_check.h"
    175 #include "pg_select_aggregation_transient.h"
    176 #include "pg_select_aggregations_above_serial.h"
    177 #include "pg_select_all_kyc_attributes.h"
    178 #include "pg_select_all_purse_decisions_above_serial_id.h"
    179 #include "pg_select_all_purse_deletions_above_serial_id.h"
    180 #include "pg_select_aml_attributes.h"
    181 #include "pg_select_aml_decisions.h"
    182 #include "pg_select_aml_measures.h"
    183 #include "pg_select_aml_statistics.h"
    184 #include "pg_select_auditor_denom_sig.h"
    185 #include "pg_select_batch_deposits_missing_wire.h"
    186 #include "pg_select_coin_deposits_above_serial_id.h"
    187 #include "pg_select_contract.h"
    188 #include "pg_select_contract_by_purse.h"
    189 #include "pg_select_deposit_amounts_for_kyc_check.h"
    190 #include "pg_select_exchange_credit_transfers.h"
    191 #include "pg_select_exchange_debit_transfers.h"
    192 #include "pg_select_exchange_kycauth_transfers.h"
    193 #include "pg_select_kyc_accounts.h"
    194 #include "pg_select_kyc_attributes.h"
    195 #include "pg_select_merge_amounts_for_kyc_check.h"
    196 #include "pg_select_purse.h"
    197 #include "pg_select_purse_by_merge_pub.h"
    198 #include "pg_select_purse_decisions_above_serial_id.h"
    199 #include "pg_select_purse_deposits_above_serial_id.h"
    200 #include "pg_select_purse_deposits_by_purse.h"
    201 #include "pg_select_purse_merge.h"
    202 #include "pg_select_purse_merges_above_serial_id.h"
    203 #include "pg_select_purse_requests_above_serial_id.h"
    204 #include "pg_select_recoup_above_serial_id.h"
    205 #include "pg_select_recoup_refresh_above_serial_id.h"
    206 #include "pg_select_refreshes_above_serial_id.h"
    207 #include "pg_select_refunds_above_serial_id.h"
    208 #include "pg_select_refunds_by_coin.h"
    209 #include "pg_select_reserve_close_info.h"
    210 #include "pg_select_reserve_closed_above_serial_id.h"
    211 #include "pg_select_reserve_open_above_serial_id.h"
    212 #include "pg_select_reserves_in_above_serial_id.h"
    213 #include "pg_select_reserves_in_above_serial_id_by_account.h"
    214 #include "pg_select_wire_out_above_serial_id.h"
    215 #include "pg_select_wire_out_above_serial_id_by_account.h"
    216 #include "pg_select_withdraw_amounts_for_kyc_check.h"
    217 #include "pg_select_withdrawals_above_serial_id.h"
    218 #include "pg_set_aml_lock.h"
    219 #include "pg_set_extension_manifest.h"
    220 #include "pg_set_purse_balance.h"
    221 #include "pg_start.h"
    222 #include "pg_start_deferred_wire_out.h"
    223 #include "pg_start_read_committed.h"
    224 #include "pg_start_read_only.h"
    225 #include "pg_store_wire_transfer_out.h"
    226 #include "pg_test_aml_officer.h"
    227 #include "pg_trigger_kyc_rule_for_account.h"
    228 #include "pg_update_aggregation_transient.h"
    229 #include "pg_update_auditor.h"
    230 #include "pg_update_kyc_process_by_row.h"
    231 #include "pg_update_wire.h"
    232 #include "pg_wad_in_insert.h"
    233 #include "pg_wire_prepare_data_get.h"
    234 #include "pg_wire_prepare_data_insert.h"
    235 #include "pg_wire_prepare_data_mark_failed.h"
    236 #include "pg_wire_prepare_data_mark_finished.h"
    237 #include "plugin_exchangedb_common.h"
    238 #include "plugin_exchangedb_postgres.h"
    239 #include "taler/taler_dbevents.h"
    240 #include "taler/taler_error_codes.h"
    241 #include "taler/taler_exchangedb_plugin.h"
    242 #include "taler/taler_json_lib.h"
    243 #include "taler/taler_pq_lib.h"
    244 #include "taler/taler_util.h"
    245 
    246 /**
    247  * Set to 1 to enable Postgres auto_explain module. This will
    248  * slow down things a _lot_, but also provide extensive logging
    249  * in the Postgres database logger for performance analysis.
    250  */
    251 #define AUTO_EXPLAIN 0
    252 
    253 
    254 /**
    255  * Log a really unexpected PQ error with all the details we can get hold of.
    256  *
    257  * @param result PQ result object of the PQ operation that failed
    258  * @param conn SQL connection that was used
    259  */
    260 #define BREAK_DB_ERR(result,conn) do {                                  \
    261           GNUNET_break (0);                                                   \
    262           GNUNET_log (GNUNET_ERROR_TYPE_ERROR,                                \
    263                       "Database failure: %s/%s/%s/%s/%s",                     \
    264                       PQresultErrorField (result, PG_DIAG_MESSAGE_PRIMARY),   \
    265                       PQresultErrorField (result, PG_DIAG_MESSAGE_DETAIL),    \
    266                       PQresultErrorMessage (result),                          \
    267                       PQresStatus (PQresultStatus (result)),                  \
    268                       PQerrorMessage (conn));                                 \
    269 } while (0)
    270 
    271 
    272 /**
    273  * Initialize Postgres database subsystem.
    274  *
    275  * @param cls a configuration instance
    276  * @return NULL on error, otherwise a `struct
    277  *         TALER_EXCHANGEDB_Plugin`
    278  */
    279 void *
    280 libtaler_plugin_exchangedb_postgres_init (void *cls);
    281 
    282 /* Declaration used to squash compiler warning */
    283 void *
    284 libtaler_plugin_exchangedb_postgres_init (void *cls)
    285 {
    286   const struct GNUNET_CONFIGURATION_Handle *cfg = cls;
    287   struct PostgresClosure *pg;
    288   struct TALER_EXCHANGEDB_Plugin *plugin;
    289   unsigned long long dpl;
    290 
    291   pg = GNUNET_new (struct PostgresClosure);
    292   plugin = GNUNET_new (struct TALER_EXCHANGEDB_Plugin);
    293   pg->cfg = cfg;
    294   if (GNUNET_OK !=
    295       GNUNET_CONFIGURATION_get_value_filename (cfg,
    296                                                "exchangedb-postgres",
    297                                                "SQL_DIR",
    298                                                &pg->sql_dir))
    299   {
    300     GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
    301                                "exchangedb-postgres",
    302                                "SQL_DIR");
    303     goto fail;
    304   }
    305   if (GNUNET_OK !=
    306       GNUNET_CONFIGURATION_get_value_string (cfg,
    307                                              "exchange",
    308                                              "BASE_URL",
    309                                              &pg->exchange_url))
    310   {
    311     GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
    312                                "exchange",
    313                                "BASE_URL");
    314     goto fail;
    315   }
    316   if (GNUNET_OK !=
    317       GNUNET_CONFIGURATION_get_value_time (cfg,
    318                                            "exchangedb",
    319                                            "IDLE_RESERVE_EXPIRATION_TIME",
    320                                            &pg->idle_reserve_expiration_time))
    321   {
    322     GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
    323                                "exchangedb",
    324                                "IDLE_RESERVE_EXPIRATION_TIME");
    325     goto fail;
    326   }
    327   if (GNUNET_OK !=
    328       GNUNET_CONFIGURATION_get_value_time (cfg,
    329                                            "exchangedb",
    330                                            "MAX_AML_PROGRAM_RUNTIME",
    331                                            &plugin->max_aml_program_runtime))
    332   {
    333     GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
    334                                "exchangedb",
    335                                "MAX_AML_PROGRAM_RUNTIME");
    336     goto fail;
    337   }
    338   if (GNUNET_OK !=
    339       GNUNET_CONFIGURATION_get_value_time (cfg,
    340                                            "exchangedb",
    341                                            "LEGAL_RESERVE_EXPIRATION_TIME",
    342                                            &pg->legal_reserve_expiration_time))
    343   {
    344     GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
    345                                "exchangedb",
    346                                "LEGAL_RESERVE_EXPIRATION_TIME");
    347     goto fail;
    348   }
    349   if (GNUNET_OK !=
    350       GNUNET_CONFIGURATION_get_value_time (cfg,
    351                                            "exchangedb",
    352                                            "AGGREGATOR_SHIFT",
    353                                            &pg->aggregator_shift))
    354   {
    355     GNUNET_log_config_missing (GNUNET_ERROR_TYPE_WARNING,
    356                                "exchangedb",
    357                                "AGGREGATOR_SHIFT");
    358   }
    359   if (GNUNET_OK !=
    360       GNUNET_CONFIGURATION_get_value_number (cfg,
    361                                              "exchangedb",
    362                                              "DEFAULT_PURSE_LIMIT",
    363                                              &dpl))
    364   {
    365     GNUNET_log_config_missing (GNUNET_ERROR_TYPE_WARNING,
    366                                "exchangedb",
    367                                "DEFAULT_PURSE_LIMIT");
    368     pg->def_purse_limit = 1;
    369   }
    370   else
    371   {
    372     pg->def_purse_limit = (uint32_t) dpl;
    373   }
    374 
    375   if (GNUNET_OK !=
    376       TALER_config_get_currency (cfg,
    377                                  "exchange",
    378                                  &pg->currency))
    379   {
    380     goto fail;
    381   }
    382   plugin->cls = pg;
    383   plugin->do_reserve_open
    384     = &TEH_PG_do_reserve_open;
    385   plugin->drop_tables
    386     = &TEH_PG_drop_tables;
    387   plugin->free_coin_transaction_list
    388     = &TEH_COMMON_free_coin_transaction_list;
    389   plugin->free_reserve_history
    390     = &TEH_COMMON_free_reserve_history;
    391   plugin->get_coin_transactions
    392     = &TEH_PG_get_coin_transactions;
    393   plugin->get_expired_reserves
    394     = &TEH_PG_get_expired_reserves;
    395   plugin->get_purse_request
    396     = &TEH_PG_get_purse_request;
    397   plugin->get_reserve_history
    398     = &TEH_PG_get_reserve_history;
    399   plugin->get_unfinished_close_requests
    400     = &TEH_PG_get_unfinished_close_requests;
    401   plugin->insert_records_by_table
    402     = &TEH_PG_insert_records_by_table;
    403   plugin->insert_reserve_open_deposit
    404     = &TEH_PG_insert_reserve_open_deposit;
    405   plugin->insert_close_request
    406     = &TEH_PG_insert_close_request;
    407   plugin->delete_aggregation_transient
    408     = &TEH_PG_delete_aggregation_transient;
    409   plugin->iterate_reserve_close_info
    410     = &TEH_PG_iterate_reserve_close_info;
    411   plugin->iterate_kyc_reference
    412     = &TEH_PG_iterate_kyc_reference;
    413   plugin->lookup_records_by_table
    414     = &TEH_PG_lookup_records_by_table;
    415   plugin->lookup_serial_by_table
    416     = &TEH_PG_lookup_serial_by_table;
    417   plugin->select_account_merges_above_serial_id
    418     = &TEH_PG_select_account_merges_above_serial_id;
    419   plugin->select_all_purse_decisions_above_serial_id
    420     = &TEH_PG_select_all_purse_decisions_above_serial_id;
    421   plugin->select_all_purse_deletions_above_serial_id
    422     = &TEH_PG_select_all_purse_deletions_above_serial_id;
    423   plugin->select_purse
    424     = &TEH_PG_select_purse;
    425   plugin->select_purse_deposits_above_serial_id
    426     = &TEH_PG_select_purse_deposits_above_serial_id;
    427   plugin->select_purse_merges_above_serial_id
    428     = &TEH_PG_select_purse_merges_above_serial_id;
    429   plugin->select_purse_requests_above_serial_id
    430     = &TEH_PG_select_purse_requests_above_serial_id;
    431   plugin->select_reserve_close_info
    432     = &TEH_PG_select_reserve_close_info;
    433   plugin->select_reserve_closed_above_serial_id
    434     = &TEH_PG_select_reserve_closed_above_serial_id;
    435   plugin->select_reserve_open_above_serial_id
    436     = &TEH_PG_select_reserve_open_above_serial_id;
    437   plugin->insert_purse_request
    438     = &TEH_PG_insert_purse_request;
    439   plugin->iterate_active_signkeys
    440     = &TEH_PG_iterate_active_signkeys;
    441   plugin->commit
    442     = &TEH_PG_commit;
    443   plugin->preflight
    444     = &TEH_PG_preflight;
    445   plugin->select_aggregation_amounts_for_kyc_check
    446     = &TEH_PG_select_aggregation_amounts_for_kyc_check;
    447   plugin->get_kyc_rules
    448     = &TEH_PG_get_kyc_rules;
    449   plugin->get_kyc_rules2
    450     = &TEH_PG_get_kyc_rules2;
    451   plugin->kyc_provider_account_lookup
    452     = &TEH_PG_kyc_provider_account_lookup;
    453   plugin->lookup_kyc_process_by_account
    454     = &TEH_PG_lookup_kyc_process_by_account;
    455   plugin->update_kyc_process_by_row
    456     = &TEH_PG_update_kyc_process_by_row;
    457   plugin->insert_kyc_requirement_process
    458     = &TEH_PG_insert_kyc_requirement_process;
    459   plugin->select_withdraw_amounts_for_kyc_check
    460     = &TEH_PG_select_withdraw_amounts_for_kyc_check;
    461   plugin->select_merge_amounts_for_kyc_check
    462     = &TEH_PG_select_merge_amounts_for_kyc_check;
    463   plugin->profit_drains_set_finished
    464     = &TEH_PG_profit_drains_set_finished;
    465   plugin->profit_drains_get_pending
    466     = &TEH_PG_profit_drains_get_pending;
    467   plugin->get_drain_profit
    468     = &TEH_PG_get_drain_profit;
    469   plugin->get_purse_deposit
    470     = &TEH_PG_get_purse_deposit;
    471   plugin->insert_contract
    472     = &TEH_PG_insert_contract;
    473   plugin->select_contract
    474     = &TEH_PG_select_contract;
    475   plugin->select_purse_merge
    476     = &TEH_PG_select_purse_merge;
    477   plugin->select_contract_by_purse
    478     = &TEH_PG_select_contract_by_purse;
    479   plugin->insert_drain_profit
    480     = &TEH_PG_insert_drain_profit;
    481   plugin->do_reserve_purse
    482     = &TEH_PG_do_reserve_purse;
    483   plugin->lookup_global_fee_by_time
    484     = &TEH_PG_lookup_global_fee_by_time;
    485   plugin->do_purse_deposit
    486     = &TEH_PG_do_purse_deposit;
    487   plugin->activate_signing_key
    488     = &TEH_PG_activate_signing_key;
    489   plugin->update_auditor
    490     = &TEH_PG_update_auditor;
    491   plugin->begin_revolving_shard
    492     = &TEH_PG_begin_revolving_shard;
    493   plugin->get_extension_manifest
    494     = &TEH_PG_get_extension_manifest;
    495   plugin->do_purse_merge
    496     = &TEH_PG_do_purse_merge;
    497   plugin->do_purse_delete
    498     = &TEH_PG_do_purse_delete;
    499   plugin->start_read_committed
    500     = &TEH_PG_start_read_committed;
    501   plugin->start_read_only
    502     = &TEH_PG_start_read_only;
    503   plugin->insert_denomination_info
    504     = &TEH_PG_insert_denomination_info;
    505   plugin->lookup_wire_fee_by_time
    506     = &TEH_PG_lookup_wire_fee_by_time;
    507   plugin->start
    508     = &TEH_PG_start;
    509   plugin->rollback
    510     = &TEH_PG_rollback;
    511   plugin->create_tables
    512     = &TEH_PG_create_tables;
    513   plugin->event_listen
    514     = &TEH_PG_event_listen;
    515   plugin->event_listen_cancel
    516     = &TEH_PG_event_listen_cancel;
    517   plugin->event_notify
    518     = &TEH_PG_event_notify;
    519   plugin->get_denomination_info
    520     = &TEH_PG_get_denomination_info;
    521   plugin->get_denomination_by_serial
    522     = &TEH_PG_get_denomination_by_serial;
    523   plugin->iterate_denomination_info
    524     = &TEH_PG_iterate_denomination_info;
    525   plugin->iterate_denominations
    526     = &TEH_PG_iterate_denominations;
    527   plugin->iterate_active_auditors
    528     = &TEH_PG_iterate_active_auditors;
    529   plugin->iterate_auditor_denominations
    530     = &TEH_PG_iterate_auditor_denominations;
    531   plugin->lookup_rules_by_access_token
    532     = &TEH_PG_lookup_rules_by_access_token;
    533   plugin->reserves_get
    534     = &TEH_PG_reserves_get;
    535   plugin->reserves_get_origin
    536     = &TEH_PG_reserves_get_origin;
    537   plugin->drain_kyc_alert
    538     = &TEH_PG_drain_kyc_alert;
    539   plugin->reserves_in_insert
    540     = &TEH_PG_reserves_in_insert;
    541   plugin->do_withdraw
    542     = &TEH_PG_do_withdraw;
    543   plugin->get_withdraw
    544     = &TEH_PG_get_withdraw;
    545   plugin->wad_in_insert
    546     = &TEH_PG_wad_in_insert;
    547   plugin->kycauth_in_insert
    548     = &TEH_PG_kycauth_in_insert;
    549   plugin->get_policy_details
    550     = &TEH_PG_get_policy_details;
    551   plugin->persist_policy_details
    552     = &TEH_PG_persist_policy_details;
    553   plugin->do_deposit
    554     = &TEH_PG_do_deposit;
    555   plugin->get_wire_hash_for_contract
    556     = &TEH_PG_get_wire_hash_for_contract;
    557   plugin->add_policy_fulfillment_proof
    558     = &TEH_PG_add_policy_fulfillment_proof;
    559   plugin->do_refresh
    560     = &TEH_PG_do_refresh;
    561   plugin->do_refund
    562     = &TEH_PG_do_refund;
    563   plugin->do_recoup
    564     = &TEH_PG_do_recoup;
    565   plugin->do_recoup_refresh
    566     = &TEH_PG_do_recoup_refresh;
    567   plugin->get_reserve_balance
    568     = &TEH_PG_get_reserve_balance;
    569   plugin->count_known_coins
    570     = &TEH_PG_count_known_coins;
    571   plugin->ensure_coin_known
    572     = &TEH_PG_ensure_coin_known;
    573   plugin->get_known_coin
    574     = &TEH_PG_get_known_coin;
    575   plugin->get_signature_for_known_coin
    576     = &TEH_PG_get_signature_for_known_coin;
    577   plugin->get_coin_denomination
    578     = &TEH_PG_get_coin_denomination;
    579   plugin->have_deposit2
    580     = &TEH_PG_have_deposit2;
    581   plugin->aggregate
    582     = &TEH_PG_aggregate;
    583   plugin->create_aggregation_transient
    584     = &TEH_PG_create_aggregation_transient;
    585   plugin->select_aggregation_transient
    586     = &TEH_PG_select_aggregation_transient;
    587   plugin->find_aggregation_transient
    588     = &TEH_PG_find_aggregation_transient;
    589   plugin->update_aggregation_transient
    590     = &TEH_PG_update_aggregation_transient;
    591   plugin->get_ready_deposit
    592     = &TEH_PG_get_ready_deposit;
    593   plugin->insert_refund
    594     = &TEH_PG_insert_refund;
    595   plugin->select_refunds_by_coin
    596     = &TEH_PG_select_refunds_by_coin;
    597   plugin->select_aml_measures
    598     = &TEH_PG_select_aml_measures;
    599   plugin->get_refresh
    600     = &TEH_PG_get_refresh;
    601   plugin->lookup_wire_transfer
    602     = &TEH_PG_lookup_wire_transfer;
    603   plugin->lookup_transfer_by_deposit
    604     = &TEH_PG_lookup_transfer_by_deposit;
    605   plugin->insert_wire_fee
    606     = &TEH_PG_insert_wire_fee;
    607   plugin->insert_global_fee
    608     = &TEH_PG_insert_global_fee;
    609   plugin->get_wire_fee
    610     = &TEH_PG_get_wire_fee;
    611   plugin->get_global_fee
    612     = &TEH_PG_get_global_fee;
    613   plugin->get_global_fees
    614     = &TEH_PG_get_global_fees;
    615   plugin->insert_reserve_closed
    616     = &TEH_PG_insert_reserve_closed;
    617   plugin->wire_prepare_data_insert
    618     = &TEH_PG_wire_prepare_data_insert;
    619   plugin->wire_prepare_data_mark_finished
    620     = &TEH_PG_wire_prepare_data_mark_finished;
    621   plugin->wire_prepare_data_mark_failed
    622     = &TEH_PG_wire_prepare_data_mark_failed;
    623   plugin->wire_prepare_data_get
    624     = &TEH_PG_wire_prepare_data_get;
    625   plugin->start_deferred_wire_out
    626     = &TEH_PG_start_deferred_wire_out;
    627   plugin->store_wire_transfer_out
    628     = &TEH_PG_store_wire_transfer_out;
    629   plugin->gc
    630     = &TEH_PG_gc;
    631   plugin->select_coin_deposits_above_serial_id
    632     = &TEH_PG_select_coin_deposits_above_serial_id;
    633   plugin->lookup_aml_file_number
    634     = &TEH_PG_lookup_aml_file_number;
    635   plugin->lookup_aml_history
    636     = &TEH_PG_lookup_aml_history;
    637   plugin->lookup_kyc_history
    638     = &TEH_PG_lookup_kyc_history;
    639   plugin->select_purse_decisions_above_serial_id
    640     = &TEH_PG_select_purse_decisions_above_serial_id;
    641   plugin->select_purse_deposits_by_purse
    642     = &TEH_PG_select_purse_deposits_by_purse;
    643   plugin->select_refreshes_above_serial_id
    644     = &TEH_PG_select_refreshes_above_serial_id;
    645   plugin->select_refunds_above_serial_id
    646     = &TEH_PG_select_refunds_above_serial_id;
    647   plugin->select_reserves_in_above_serial_id
    648     = &TEH_PG_select_reserves_in_above_serial_id;
    649   plugin->select_reserves_in_above_serial_id_by_account
    650     = &TEH_PG_select_reserves_in_above_serial_id_by_account;
    651   plugin->select_withdrawals_above_serial_id
    652     = &TEH_PG_select_withdrawals_above_serial_id;
    653   plugin->select_wire_out_above_serial_id
    654     = &TEH_PG_select_wire_out_above_serial_id;
    655   plugin->select_wire_out_above_serial_id_by_account
    656     = &TEH_PG_select_wire_out_above_serial_id_by_account;
    657   plugin->select_recoup_above_serial_id
    658     = &TEH_PG_select_recoup_above_serial_id;
    659   plugin->select_recoup_refresh_above_serial_id
    660     = &TEH_PG_select_recoup_refresh_above_serial_id;
    661   plugin->get_reserve_by_h_planchets
    662     = &TEH_PG_get_reserve_by_h_planchets;
    663   plugin->get_old_coin_by_h_blind
    664     = &TEH_PG_get_old_coin_by_h_blind;
    665   plugin->insert_denomination_revocation
    666     = &TEH_PG_insert_denomination_revocation;
    667   plugin->get_denomination_revocation
    668     = &TEH_PG_get_denomination_revocation;
    669   plugin->select_batch_deposits_missing_wire
    670     = &TEH_PG_select_batch_deposits_missing_wire;
    671   plugin->select_aggregations_above_serial
    672     = &TEH_PG_select_aggregations_above_serial;
    673   plugin->lookup_auditor_timestamp
    674     = &TEH_PG_lookup_auditor_timestamp;
    675   plugin->lookup_auditor_status
    676     = &TEH_PG_lookup_auditor_status;
    677   plugin->insert_auditor
    678     = &TEH_PG_insert_auditor;
    679   plugin->lookup_wire_timestamp
    680     = &TEH_PG_lookup_wire_timestamp;
    681   plugin->insert_wire
    682     = &TEH_PG_insert_wire;
    683   plugin->update_wire
    684     = &TEH_PG_update_wire;
    685   plugin->get_wire_accounts
    686     = &TEH_PG_get_wire_accounts;
    687   plugin->get_wire_fees
    688     = &TEH_PG_get_wire_fees;
    689   plugin->select_aml_decisions
    690     = &TEH_PG_select_aml_decisions;
    691   plugin->select_deposit_amounts_for_kyc_check
    692     = &TEH_PG_select_deposit_amounts_for_kyc_check;
    693   plugin->do_check_deposit_idempotent
    694     = &TEH_PG_do_check_deposit_idempotent;
    695   plugin->insert_signkey_revocation
    696     = &TEH_PG_insert_signkey_revocation;
    697   plugin->select_aml_attributes
    698     = &TEH_PG_select_aml_attributes;
    699   plugin->select_aml_statistics
    700     = &TEH_PG_select_aml_statistics;
    701   plugin->lookup_signkey_revocation
    702     = &TEH_PG_lookup_signkey_revocation;
    703   plugin->lookup_denomination_key
    704     = &TEH_PG_lookup_denomination_key;
    705   plugin->lookup_completed_legitimization
    706     = &TEH_PG_lookup_completed_legitimization;
    707   plugin->lookup_pending_legitimization
    708     = &TEH_PG_lookup_pending_legitimization;
    709   plugin->lookup_active_legitimization
    710     = &TEH_PG_lookup_active_legitimization;
    711   plugin->insert_auditor_denom_sig
    712     = &TEH_PG_insert_auditor_denom_sig;
    713   plugin->select_auditor_denom_sig
    714     = &TEH_PG_select_auditor_denom_sig;
    715   plugin->select_kyc_accounts
    716     = &TEH_PG_select_kyc_accounts;
    717   plugin->add_denomination_key
    718     = &TEH_PG_add_denomination_key;
    719   plugin->lookup_signing_key
    720     = &TEH_PG_lookup_signing_key;
    721   plugin->lookup_h_payto_by_access_token
    722     = &TEH_PG_lookup_h_payto_by_access_token;
    723   plugin->insert_sanction_list_hit
    724     = &TEH_PG_insert_sanction_list_hit;
    725   plugin->select_exchange_debit_transfers
    726     = &TEH_PG_select_exchange_debit_transfers;
    727   plugin->select_exchange_credit_transfers
    728     = &TEH_PG_select_exchange_credit_transfers;
    729   plugin->select_exchange_kycauth_transfers
    730     = &TEH_PG_select_exchange_kycauth_transfers;
    731   plugin->select_all_kyc_attributes
    732     = &TEH_PG_select_all_kyc_attributes;
    733   plugin->begin_shard
    734     = &TEH_PG_begin_shard;
    735   plugin->abort_shard
    736     = &TEH_PG_abort_shard;
    737   plugin->insert_kyc_failure
    738     = &TEH_PG_insert_kyc_failure;
    739   plugin->complete_shard
    740     = &TEH_PG_complete_shard;
    741   plugin->release_revolving_shard
    742     = &TEH_PG_release_revolving_shard;
    743   plugin->delete_shard_locks
    744     = &TEH_PG_delete_shard_locks;
    745   plugin->set_extension_manifest
    746     = &TEH_PG_set_extension_manifest;
    747   plugin->insert_partner
    748     = &TEH_PG_insert_partner;
    749   plugin->expire_purse
    750     = &TEH_PG_expire_purse;
    751   plugin->select_purse_by_merge_pub
    752     = &TEH_PG_select_purse_by_merge_pub;
    753   plugin->set_purse_balance
    754     = &TEH_PG_set_purse_balance;
    755   plugin->get_pending_kyc_requirement_process
    756     = &TEH_PG_get_pending_kyc_requirement_process;
    757   plugin->select_kyc_attributes
    758     = &TEH_PG_select_kyc_attributes;
    759   plugin->insert_aml_officer
    760     = &TEH_PG_insert_aml_officer;
    761   plugin->enable_rules
    762     = &TEH_PG_enable_rules;
    763   plugin->disable_rules
    764     = &TEH_PG_disable_rules;
    765   plugin->test_aml_officer
    766     = &TEH_PG_test_aml_officer;
    767   plugin->lookup_aml_officer
    768     = &TEH_PG_lookup_aml_officer;
    769   plugin->insert_active_legitimization_measure
    770     = &TEH_PG_insert_active_legitimization_measure;
    771   plugin->insert_aml_decision
    772     = &TEH_PG_insert_aml_decision;
    773   plugin->lookup_kyc_requirement_by_row
    774     = &TEH_PG_lookup_kyc_requirement_by_row;
    775   plugin->trigger_kyc_rule_for_account
    776     = &TEH_PG_trigger_kyc_rule_for_account;
    777   plugin->lookup_kyc_status_by_token
    778     = &TEH_PG_lookup_kyc_status_by_token;
    779   plugin->batch_ensure_coin_known
    780     = &TEH_PG_batch_ensure_coin_known;
    781   plugin->inject_auditor_triggers
    782     = &TEH_PG_inject_auditor_triggers;
    783   plugin->insert_successor_measure
    784     = &TEH_PG_insert_successor_measure;
    785   plugin->insert_aml_program_failure
    786     = &TEH_PG_insert_aml_program_failure;
    787   plugin->persist_kyc_attributes
    788     = &TEH_PG_persist_kyc_attributes;
    789   plugin->clear_aml_lock
    790     = &TEH_PG_clear_aml_lock;
    791   plugin->set_aml_lock
    792     = &TEH_PG_set_aml_lock;
    793 
    794   return plugin;
    795 
    796 fail:
    797   GNUNET_free (pg->exchange_url);
    798   GNUNET_free (pg->sql_dir);
    799   GNUNET_free (pg);
    800   GNUNET_free (plugin);
    801   return NULL;
    802 }
    803 
    804 
    805 /**
    806  * Shutdown Postgres database subsystem.
    807  *
    808  * @param cls a `struct TALER_EXCHANGEDB_Plugin`
    809  * @return NULL (always)
    810  */
    811 void *
    812 libtaler_plugin_exchangedb_postgres_done (void *cls);
    813 
    814 /* Declaration used to squash compiler warning */
    815 void *
    816 libtaler_plugin_exchangedb_postgres_done (void *cls)
    817 {
    818   struct TALER_EXCHANGEDB_Plugin *plugin = cls;
    819   struct PostgresClosure *pg = plugin->cls;
    820 
    821   if (NULL != pg->conn)
    822   {
    823     GNUNET_PQ_disconnect (pg->conn);
    824     pg->conn = NULL;
    825   }
    826   GNUNET_free (pg->exchange_url);
    827   GNUNET_free (pg->sql_dir);
    828   GNUNET_free (pg->currency);
    829   GNUNET_free (pg);
    830   GNUNET_free (plugin);
    831   return NULL;
    832 }
    833 
    834 
    835 /* end of plugin_exchangedb_postgres.c */