aboutsummaryrefslogtreecommitdiff
path: root/src/exchangedb
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2024-07-26 15:31:18 +0200
committerChristian Grothoff <christian@grothoff.org>2024-07-29 12:18:48 +0200
commit97df3b30de69df738c8904d5c9917de77241d590 (patch)
tree31f5d6c6feab824863d209061c1207a7843ff4f2 /src/exchangedb
parent012973ca977179e2d4f801aa06c77ca9052c5990 (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.sql18
-rw-r--r--src/exchangedb/Makefile.am2
-rw-r--r--src/exchangedb/exchange_do_trigger_kyc_rule_for_account.sql3
-rw-r--r--src/exchangedb/pg_get_coin_transactions.c2
-rw-r--r--src/exchangedb/pg_insert_kyc_failure.c9
-rw-r--r--src/exchangedb/pg_insert_kyc_failure.h6
-rw-r--r--src/exchangedb/pg_lookup_aml_history.c170
-rw-r--r--src/exchangedb/pg_lookup_aml_history.h47
-rw-r--r--src/exchangedb/pg_lookup_kyc_history.c195
-rw-r--r--src/exchangedb/pg_lookup_kyc_history.h46
-rw-r--r--src/exchangedb/pg_trigger_kyc_rule_for_account.c4
-rw-r--r--src/exchangedb/pg_trigger_kyc_rule_for_account.h4
-rw-r--r--src/exchangedb/plugin_exchangedb_postgres.c6
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