diff options
author | Christian Grothoff <christian@grothoff.org> | 2024-07-26 15:31:18 +0200 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2024-07-29 12:18:48 +0200 |
commit | 97df3b30de69df738c8904d5c9917de77241d590 (patch) | |
tree | 31f5d6c6feab824863d209061c1207a7843ff4f2 /src/exchangedb | |
parent | 012973ca977179e2d4f801aa06c77ca9052c5990 (diff) |
fixes to error handling, logging, and aml/kyc history returning feature
Diffstat (limited to 'src/exchangedb')
-rw-r--r-- | src/exchangedb/0005-legitimization_processes.sql | 18 | ||||
-rw-r--r-- | src/exchangedb/Makefile.am | 2 | ||||
-rw-r--r-- | src/exchangedb/exchange_do_trigger_kyc_rule_for_account.sql | 3 | ||||
-rw-r--r-- | src/exchangedb/pg_get_coin_transactions.c | 2 | ||||
-rw-r--r-- | src/exchangedb/pg_insert_kyc_failure.c | 9 | ||||
-rw-r--r-- | src/exchangedb/pg_insert_kyc_failure.h | 6 | ||||
-rw-r--r-- | src/exchangedb/pg_lookup_aml_history.c | 170 | ||||
-rw-r--r-- | src/exchangedb/pg_lookup_aml_history.h | 47 | ||||
-rw-r--r-- | src/exchangedb/pg_lookup_kyc_history.c | 195 | ||||
-rw-r--r-- | src/exchangedb/pg_lookup_kyc_history.h | 46 | ||||
-rw-r--r-- | src/exchangedb/pg_trigger_kyc_rule_for_account.c | 4 | ||||
-rw-r--r-- | src/exchangedb/pg_trigger_kyc_rule_for_account.h | 4 | ||||
-rw-r--r-- | src/exchangedb/plugin_exchangedb_postgres.c | 6 |
13 files changed, 504 insertions, 8 deletions
diff --git a/src/exchangedb/0005-legitimization_processes.sql b/src/exchangedb/0005-legitimization_processes.sql index a5f66b37a..db81b799d 100644 --- a/src/exchangedb/0005-legitimization_processes.sql +++ b/src/exchangedb/0005-legitimization_processes.sql @@ -24,7 +24,9 @@ BEGIN PERFORM create_partitioned_table( 'ALTER TABLE legitimization_processes' ' ADD COLUMN legitimization_measure_serial_id BIGINT' - ',ADD COLUMN measure_index INT4' + ',ADD COLUMN measure_index INT4 DEFAULT(0)' + ',ADD COLUMN error_code INT4 DEFAULT (0)' + ',ADD COLUMN error_message TEXT DEFAULT NULL' ';' ,'legitimization_processes' ,'' @@ -45,11 +47,23 @@ BEGIN ,shard_suffix ); PERFORM comment_partitioned_column( - 'index of the measure in legitimization_measures that was selected for this KYC setup; NULL if legitimization_measure_serial_id is NULL; enables determination of the context data provided to the external proces' + 'index of the measure in legitimization_measures that was selected for this KYC setup; NULL if legitimization_measure_serial_id is NULL; enables determination of the context data provided to the external process' ,'measure_index' ,'legitimization_processes' ,shard_suffix ); + PERFORM comment_partitioned_column( + 'TALER_ErrorCode set if the process failed, otherwise NULL' + ,'error_code' + ,'legitimization_processes' + ,shard_suffix + ); + PERFORM comment_partitioned_column( + 'human-readable error details set if the process failed, otherwise NULL' + ,'error_message' + ,'legitimization_processes' + ,shard_suffix + ); END $$; diff --git a/src/exchangedb/Makefile.am b/src/exchangedb/Makefile.am index e7619657e..f7e674704 100644 --- a/src/exchangedb/Makefile.am +++ b/src/exchangedb/Makefile.am @@ -115,6 +115,8 @@ libtaler_plugin_exchangedb_postgres_la_SOURCES = \ pg_select_withdraw_amounts_for_kyc_check.h pg_select_withdraw_amounts_for_kyc_check.c \ pg_select_merge_amounts_for_kyc_check.h pg_select_merge_amounts_for_kyc_check.c \ pg_profit_drains_set_finished.h pg_profit_drains_set_finished.c \ + pg_lookup_aml_history.h pg_lookup_aml_history.c \ + pg_lookup_kyc_history.h pg_lookup_kyc_history.c \ pg_profit_drains_get_pending.h pg_profit_drains_get_pending.c \ pg_get_drain_profit.h pg_get_drain_profit.c \ pg_get_purse_deposit.h pg_get_purse_deposit.c \ diff --git a/src/exchangedb/exchange_do_trigger_kyc_rule_for_account.sql b/src/exchangedb/exchange_do_trigger_kyc_rule_for_account.sql index 7fbc0abbe..e681b129b 100644 --- a/src/exchangedb/exchange_do_trigger_kyc_rule_for_account.sql +++ b/src/exchangedb/exchange_do_trigger_kyc_rule_for_account.sql @@ -26,7 +26,8 @@ AS $$ DECLARE my_access_token BYTEA; BEGIN - +-- Note: in_payto_uri is allowed to be NULL *if* +-- in_h_payto is already in wire_targets SELECT access_token INTO diff --git a/src/exchangedb/pg_get_coin_transactions.c b/src/exchangedb/pg_get_coin_transactions.c index 5a6ddcd44..b2db935a5 100644 --- a/src/exchangedb/pg_get_coin_transactions.c +++ b/src/exchangedb/pg_get_coin_transactions.c @@ -38,7 +38,7 @@ #define RETRIES 3 /** - * Closure for callbacks called from #postgres_get_coin_transactions() + * Closure for callbacks called from #TEH_PG_get_coin_transactions() */ struct CoinHistoryContext { diff --git a/src/exchangedb/pg_insert_kyc_failure.c b/src/exchangedb/pg_insert_kyc_failure.c index 903c717ad..b8967c30c 100644 --- a/src/exchangedb/pg_insert_kyc_failure.c +++ b/src/exchangedb/pg_insert_kyc_failure.c @@ -34,9 +34,12 @@ TEH_PG_insert_kyc_failure ( const struct TALER_PaytoHashP *h_payto, const char *provider_name, const char *provider_account_id, - const char *provider_legitimization_id) + const char *provider_legitimization_id, + const char *error_message, + enum TALER_ErrorCode ec) { struct PostgresClosure *pg = cls; + uint32_t ec32 = (uint32_t) ec; struct GNUNET_PQ_QueryParam params[] = { GNUNET_PQ_query_param_uint64 (&process_row), GNUNET_PQ_query_param_auto_from_type (h_payto), @@ -47,6 +50,8 @@ TEH_PG_insert_kyc_failure ( NULL != provider_legitimization_id ? GNUNET_PQ_query_param_string (provider_legitimization_id) : GNUNET_PQ_query_param_null (), + GNUNET_PQ_query_param_uint32 (&ec32), + GNUNET_PQ_query_param_string (error_message), GNUNET_PQ_query_param_end }; enum GNUNET_DB_QueryStatus qs; @@ -58,6 +63,8 @@ TEH_PG_insert_kyc_failure ( " finished=TRUE" " ,provider_user_id=$4" " ,provider_legitimization_id=$5" + " ,error_code=$6" + " ,error_message=$7" " WHERE h_payto=$2" " AND legitimization_process_serial_id=$1" " AND provider_name=$3;"); diff --git a/src/exchangedb/pg_insert_kyc_failure.h b/src/exchangedb/pg_insert_kyc_failure.h index bacdefe99..120718feb 100644 --- a/src/exchangedb/pg_insert_kyc_failure.h +++ b/src/exchangedb/pg_insert_kyc_failure.h @@ -35,6 +35,8 @@ * @param provider_name provider that must be checked * @param provider_account_id provider account ID * @param provider_legitimization_id provider legitimization ID + * @param error_message details about what went wrong + * @param ec error code about the failure * @return database transaction status */ enum GNUNET_DB_QueryStatus @@ -44,7 +46,9 @@ TEH_PG_insert_kyc_failure ( const struct TALER_PaytoHashP *h_payto, const char *provider_name, const char *provider_account_id, - const char *provider_legitimization_id); + const char *provider_legitimization_id, + const char *error_message, + enum TALER_ErrorCode ec); #endif diff --git a/src/exchangedb/pg_lookup_aml_history.c b/src/exchangedb/pg_lookup_aml_history.c new file mode 100644 index 000000000..01744bcdd --- /dev/null +++ b/src/exchangedb/pg_lookup_aml_history.c @@ -0,0 +1,170 @@ +/* + This file is part of TALER + Copyright (C) 2024 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 + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file exchangedb/pg_lookup_aml_history.c + * @brief Implementation of the lookup_aml_history function for Postgres + * @author Christian Grothoff + */ +#include "platform.h" +#include "taler_error_codes.h" +#include "taler_dbevents.h" +#include "taler_pq_lib.h" +#include "pg_lookup_aml_history.h" +#include "pg_helper.h" + + +/** + * Closure for callbacks called from #TEH_PG_lookup_aml_history() + */ +struct AmlHistoryContext +{ + + /** + * Function to call on each result. + */ + TALER_EXCHANGEDB_AmlHistoryCallback cb; + + /** + * Closure for @e cb. + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct PostgresClosure *pg; + + /** + * Set to 'true' if the transaction failed. + */ + bool failed; + +}; + + +/** + * Function to be called with the results of a SELECT statement + * that has returned @a num_results results. + * + * @param cls closure of type `struct AmlHistoryContext` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +handle_aml_entry (void *cls, + PGresult *result, + unsigned int num_results) +{ + struct AmlHistoryContext *ahc = cls; + + for (unsigned int i = 0; i < num_results; i++) + { + struct GNUNET_TIME_Timestamp decision_time; + char *justification; + struct TALER_AmlOfficerPublicKeyP decider_pub; + json_t *jproperties; + json_t *jnew_rules; + bool to_investigate; + bool is_active; + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_timestamp ("decision_time", + &decision_time), + GNUNET_PQ_result_spec_string ("justification", + &justification), + GNUNET_PQ_result_spec_auto_from_type ("decider_pub", + &decider_pub), + TALER_PQ_result_spec_json ("properties", + &jproperties), + TALER_PQ_result_spec_json ("new_rules", + &jnew_rules), + GNUNET_PQ_result_spec_bool ("to_investigate", + &to_investigate), + GNUNET_PQ_result_spec_bool ("is_active", + &is_active), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + ahc->failed = true; + return; + } + ahc->cb (ahc->cb_cls, + decision_time, + justification, + &decider_pub, + jproperties, + jnew_rules, + to_investigate, + is_active); + GNUNET_PQ_cleanup_result (rs); + } +} + + +enum GNUNET_DB_QueryStatus +TEH_PG_lookup_aml_history ( + void *cls, + const struct TALER_PaytoHashP *h_payto, + TALER_EXCHANGEDB_AmlHistoryCallback cb, + void *cb_cls) +{ + struct PostgresClosure *pg = cls; + struct AmlHistoryContext ahc = { + .pg = pg, + .cb = cb, + .cb_cls = cb_cls + }; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (h_payto), + GNUNET_PQ_query_param_end + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (pg, + "lookup_aml_history", + "SELECT" + " ah.decision_time" + ",ah.justification" + ",ah.decider_pub" + ",lo.jproperties" + ",lo.jnew_rules" + ",lo.to_investigate" + ".lo.is_active" + " FROM aml_history ah" + " JOIN legitimization_outcomes lo" + " USING (outcome_serial_id)" + " WHERE h_payto=$1" + " ORDER BY decision_time DESC;"); + qs = GNUNET_PQ_eval_prepared_multi_select ( + pg->conn, + "lookup_aml_history", + params, + &handle_aml_entry, + &ahc); + if (qs <= 0) + return qs; + if (ahc.failed) + { + GNUNET_break (0); + return GNUNET_DB_STATUS_HARD_ERROR; + } + return qs; +} diff --git a/src/exchangedb/pg_lookup_aml_history.h b/src/exchangedb/pg_lookup_aml_history.h new file mode 100644 index 000000000..db146e937 --- /dev/null +++ b/src/exchangedb/pg_lookup_aml_history.h @@ -0,0 +1,47 @@ +/* + This file is part of TALER + Copyright (C) 2024 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 + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file exchangedb/pg_lookup_aml_history.h + * @brief implementation of the lookup_aml_history function for Postgres + * @author Christian Grothoff + */ +#ifndef PG_LOOKUP_AML_HISTORY_H +#define PG_LOOKUP_AML_HISTORY_H + +#include "taler_util.h" +#include "taler_json_lib.h" +#include "taler_exchangedb_plugin.h" + + +/** + * Lookup AML history for an account identified via + * @a h_payto. + * + * @param cls closure + * @param h_payto hash of account to lookup history for + * @param cb function to call on results + * @param cb_cls closure for @a cb + * @return database transaction status + */ +enum GNUNET_DB_QueryStatus +TEH_PG_lookup_aml_history ( + void *cls, + const struct TALER_PaytoHashP *h_payto, + TALER_EXCHANGEDB_AmlHistoryCallback cb, + void *cb_cls); + + +#endif diff --git a/src/exchangedb/pg_lookup_kyc_history.c b/src/exchangedb/pg_lookup_kyc_history.c new file mode 100644 index 000000000..6dc67356b --- /dev/null +++ b/src/exchangedb/pg_lookup_kyc_history.c @@ -0,0 +1,195 @@ +/* + This file is part of TALER + Copyright (C) 2024 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 + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file exchangedb/pg_lookup_kyc_history.c + * @brief Implementation of the lookup_kyc_history function for Postgres + * @author Christian Grothoff + */ +#include "platform.h" +#include "taler_error_codes.h" +#include "taler_dbevents.h" +#include "taler_pq_lib.h" +#include "pg_lookup_kyc_history.h" +#include "pg_helper.h" + +/** + * Closure for callbacks called from #TEH_PG_lookup_kyc_history() + */ +struct KycHistoryContext +{ + + /** + * Function to call on each result. + */ + TALER_EXCHANGEDB_KycHistoryCallback cb; + + /** + * Closure for @e cb. + */ + void *cb_cls; + + /** + * Plugin context. + */ + struct PostgresClosure *pg; + + /** + * Set to 'true' if the transaction failed. + */ + bool failed; + +}; + + +/** + * Function to be called with the results of a SELECT statement + * that has returned @a num_results results. + * + * @param cls closure of type `struct KycHistoryContext` + * @param result the postgres result + * @param num_results the number of results in @a result + */ +static void +handle_kyc_entry (void *cls, + PGresult *result, + unsigned int num_results) +{ + struct KycHistoryContext *khc = cls; + + for (unsigned int i = 0; i < num_results; i++) + { + char *provider_name = NULL; + bool finished; + uint32_t error_code; + char *error_message = NULL; + char *provider_user_id = NULL; + char *provider_legitimization_id = NULL; + struct GNUNET_TIME_Timestamp collection_time; + struct GNUNET_TIME_Absolute expiration_time + = GNUNET_TIME_UNIT_ZERO_ABS; + void *encrypted_attributes; + size_t encrypted_attributes_len; + + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_string ("provider_name", + &provider_name), + NULL), + GNUNET_PQ_result_spec_bool ("finished", + &finished), + GNUNET_PQ_result_spec_uint32 ("error_code", + &error_code), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_string ("error_message", + &error_message), + NULL), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_string ("provider_user_id", + &provider_user_id), + NULL), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_string ("provider_legitimization_id", + &provider_legitimization_id), + NULL), + GNUNET_PQ_result_spec_timestamp ("collection_time", + &collection_time), + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_absolute_time ("expiration_time", + &expiration_time), + NULL), + GNUNET_PQ_result_spec_variable_size ("encrypted_attributes", + &encrypted_attributes, + &encrypted_attributes_len), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + khc->failed = true; + return; + } + khc->cb (khc->cb_cls, + provider_name, + finished, + (enum TALER_ErrorCode) error_code, + error_message, + provider_user_id, + provider_legitimization_id, + collection_time, + expiration_time, + encrypted_attributes_len, + encrypted_attributes); + GNUNET_PQ_cleanup_result (rs); + } +} + + +enum GNUNET_DB_QueryStatus +TEH_PG_lookup_kyc_history ( + void *cls, + const struct TALER_PaytoHashP *h_payto, + TALER_EXCHANGEDB_KycHistoryCallback cb, + void *cb_cls) +{ + struct PostgresClosure *pg = cls; + struct KycHistoryContext khc = { + .pg = pg, + .cb = cb, + .cb_cls = cb_cls + }; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (h_payto), + GNUNET_PQ_query_param_end + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (pg, + "lookup_kyc_history", + "SELECT" + " lp.provider_name" + ",lp.finished" + ",lp.error_code" + ",lp.error_message" + ",lp.provider_user_id" + ",lp.provider_legitimization_id" + ",ka.collection_time" + ",ka.expiration_time" + ",ka.encrypted_attributes" + " FROM kyc_attributes ka" + " JOIN legitimization_processes lp" + " ON (ka.legitimization_serial = lp.legitimization_process_serial)" + " WHERE ka.h_payto=$1" + " ORDER BY collection_time DESC;"); + + qs = GNUNET_PQ_eval_prepared_multi_select ( + pg->conn, + "lookup_kyc_history", + params, + &handle_kyc_entry, + &khc); + if (qs <= 0) + return qs; + if (khc.failed) + { + GNUNET_break (0); + return GNUNET_DB_STATUS_HARD_ERROR; + } + return qs; +} diff --git a/src/exchangedb/pg_lookup_kyc_history.h b/src/exchangedb/pg_lookup_kyc_history.h new file mode 100644 index 000000000..1c47366a5 --- /dev/null +++ b/src/exchangedb/pg_lookup_kyc_history.h @@ -0,0 +1,46 @@ +/* + This file is part of TALER + Copyright (C) 2024 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 + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file exchangedb/pg_lookup_kyc_history.h + * @brief implementation of the lookup_kyc_history function for Postgres + * @author Christian Grothoff + */ +#ifndef PG_LOOKUP_KYC_HISTORY_H +#define PG_LOOKUP_KYC_HISTORY_H + +#include "taler_util.h" +#include "taler_json_lib.h" +#include "taler_exchangedb_plugin.h" + + +/** + * Lookup KYC history for an account identified via + * @a h_payto. + * + * @param cls closure + * @param h_payto hash of account to lookup history for + * @param cb function to call on results + * @param cb_cls closure for @a cb + * @return database transaction status + */ +enum GNUNET_DB_QueryStatus +TEH_PG_lookup_kyc_history ( + void *cls, + const struct TALER_PaytoHashP *h_payto, + TALER_EXCHANGEDB_KycHistoryCallback cb, + void *cb_cls); + +#endif diff --git a/src/exchangedb/pg_trigger_kyc_rule_for_account.c b/src/exchangedb/pg_trigger_kyc_rule_for_account.c index b3be51ecd..7d6753e64 100644 --- a/src/exchangedb/pg_trigger_kyc_rule_for_account.c +++ b/src/exchangedb/pg_trigger_kyc_rule_for_account.c @@ -40,7 +40,9 @@ TEH_PG_trigger_kyc_rule_for_account ( = GNUNET_TIME_absolute_get (); struct GNUNET_PQ_QueryParam params[] = { GNUNET_PQ_query_param_auto_from_type (h_payto), - GNUNET_PQ_query_param_string (payto_uri), + NULL == payto_uri + ? GNUNET_PQ_query_param_null () + : GNUNET_PQ_query_param_string (payto_uri), GNUNET_PQ_query_param_absolute_time (&now), TALER_PQ_query_param_json (jmeasures), GNUNET_PQ_query_param_uint32 (&display_priority), diff --git a/src/exchangedb/pg_trigger_kyc_rule_for_account.h b/src/exchangedb/pg_trigger_kyc_rule_for_account.h index abc756181..e525c6199 100644 --- a/src/exchangedb/pg_trigger_kyc_rule_for_account.h +++ b/src/exchangedb/pg_trigger_kyc_rule_for_account.h @@ -30,7 +30,9 @@ * Insert KYC requirement for @a h_payto account into table. * * @param cls closure - * @param payto_uri account that must be KYC'ed + * @param payto_uri account that must be KYC'ed, + * can be NULL if @a h_payto is already + * guaranteed to be in wire_targets * @param h_payto hash of @a payto_uri * @param jmeasures serialized MeasureSet to put in place * @param display_priority priority of the rule diff --git a/src/exchangedb/plugin_exchangedb_postgres.c b/src/exchangedb/plugin_exchangedb_postgres.c index 3587ed2e0..8b49a8021 100644 --- a/src/exchangedb/plugin_exchangedb_postgres.c +++ b/src/exchangedb/plugin_exchangedb_postgres.c @@ -94,6 +94,8 @@ #include "pg_select_contract_by_purse.h" #include "pg_insert_drain_profit.h" #include "pg_do_reserve_purse.h" +#include "pg_lookup_aml_history.h" +#include "pg_lookup_kyc_history.h" #include "pg_lookup_global_fee_by_time.h" #include "pg_do_purse_deposit.h" #include "pg_activate_signing_key.h" @@ -686,6 +688,10 @@ libtaler_plugin_exchangedb_postgres_init (void *cls) = &TEH_PG_gc; plugin->select_coin_deposits_above_serial_id = &TEH_PG_select_coin_deposits_above_serial_id; + plugin->lookup_aml_history + = &TEH_PG_lookup_aml_history; + plugin->lookup_kyc_history + = &TEH_PG_lookup_kyc_history; plugin->select_purse_decisions_above_serial_id = &TEH_PG_select_purse_decisions_above_serial_id; plugin->select_purse_deposits_by_purse |