diff --git a/src/exchange/taler-exchange-aggregator.c b/src/exchange/taler-exchange-aggregator.c
index af3e111dd..d196ff268 100644
--- a/src/exchange/taler-exchange-aggregator.c
+++ b/src/exchange/taler-exchange-aggregator.c
@@ -582,6 +582,8 @@ aml_satisfied (struct AggregationUnit *au_active)
{
enum GNUNET_DB_QueryStatus qs;
struct TALER_Amount total;
+ struct TALER_Amount threshold;
+ enum TALER_AmlDecisionState decision;
total = au_active->final_amount;
qs = db_plugin->select_aggregation_amounts_for_kyc_check (
@@ -596,20 +598,48 @@ aml_satisfied (struct AggregationUnit *au_active)
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
return false;
}
- if (0 >= TALER_amount_cmp (&total,
- &aml_threshold))
- {
- /* total <= aml_threshold, do nothing */
- return true;
- }
- qs = db_plugin->trigger_aml_process (db_plugin->cls,
- &au_active->h_payto,
- &total);
+ qs = db_plugin->select_aml_threshold (db_plugin->cls,
+ &au_active->h_payto,
+ &decision,
+ &threshold);
if (qs < 0)
{
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
return false;
}
+ if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
+ {
+ threshold = aml_threshold; /* use default */
+ decision = TALER_AML_NORMAL;
+ }
+ switch (decision)
+ {
+ case TALER_AML_NORMAL:
+ if (0 >= TALER_amount_cmp (&total,
+ &threshold))
+ {
+ /* total <= threshold, do nothing */
+ return true;
+ }
+ qs = db_plugin->trigger_aml_process (db_plugin->cls,
+ &au_active->h_payto,
+ &total);
+ if (qs < 0)
+ {
+ GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
+ return false;
+ }
+ return false;
+ case TALER_AML_PENDING:
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "AML already pending, doing nothing\n");
+ return false;
+ case TALER_AML_FROZEN:
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Account frozen, doing nothing\n");
+ return false;
+ }
+ GNUNET_assert (0);
return false;
}
diff --git a/src/exchangedb/Makefile.am b/src/exchangedb/Makefile.am
index 71c058c13..98e9bd90d 100644
--- a/src/exchangedb/Makefile.am
+++ b/src/exchangedb/Makefile.am
@@ -96,6 +96,7 @@ libtaler_plugin_exchangedb_postgres_la_SOURCES = \
pg_get_drain_profit.h pg_get_drain_profit.c \
pg_get_purse_deposit.h pg_get_purse_deposit.c \
pg_insert_contract.h pg_insert_contract.c \
+ pg_select_aml_threshold.h pg_select_aml_threshold.c \
pg_select_contract.h pg_select_contract.c \
pg_select_purse_merge.h pg_select_purse_merge.c \
pg_select_contract_by_purse.h pg_select_contract_by_purse.c \
diff --git a/src/exchangedb/pg_select_aml_threshold.c b/src/exchangedb/pg_select_aml_threshold.c
new file mode 100644
index 000000000..723524adf
--- /dev/null
+++ b/src/exchangedb/pg_select_aml_threshold.c
@@ -0,0 +1,64 @@
+/*
+ This file is part of TALER
+ Copyright (C) 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
+ 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
+ */
+/**
+ * @file exchangedb/pg_select_aml_threshold.c
+ * @brief Implementation of the select_aml_threshold 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_select_aml_threshold.h"
+#include "pg_helper.h"
+
+
+enum GNUNET_DB_QueryStatus
+TEH_PG_select_aml_threshold (
+ void *cls,
+ const struct TALER_PaytoHashP *h_payto,
+ enum TALER_AmlDecisionState *decision,
+ struct TALER_Amount *threshold)
+{
+ struct PostgresClosure *pg = cls;
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_auto_from_type (h_payto),
+ GNUNET_PQ_query_param_end
+ };
+ uint32_t status32 = TALER_AML_NORMAL;
+ struct GNUNET_PQ_ResultSpec rs[] = {
+ TALER_PQ_RESULT_SPEC_AMOUNT ("threshold",
+ &threshold),
+ GNUNET_PQ_result_spec_uint32 ("status",
+ &status32),
+ GNUNET_PQ_result_spec_end
+ };
+ enum GNUNET_DB_QueryStatus qs;
+
+ PREPARE (pg,
+ "select_aml_threshold",
+ "SELECT"
+ " threshold_val"
+ ",threshold_frac"
+ " FROM aml_status"
+ " WHERE h_payto=$1;");
+ qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
+ "select_aml_threshold",
+ params,
+ rs);
+ *decision = (enum TALER_AmlDecisionState) status32;
+ return qs;
+}
diff --git a/src/exchangedb/pg_select_aml_threshold.h b/src/exchangedb/pg_select_aml_threshold.h
new file mode 100644
index 000000000..618eb1c75
--- /dev/null
+++ b/src/exchangedb/pg_select_aml_threshold.h
@@ -0,0 +1,46 @@
+/*
+ This file is part of TALER
+ Copyright (C) 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
+ 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
+ */
+/**
+ * @file exchangedb/pg_select_aml_threshold.h
+ * @brief implementation of the select_aml_threshold function for Postgres
+ * @author Christian Grothoff
+ */
+#ifndef PG_SELECT_AML_THRESHOLD_H
+#define PG_SELECT_AML_THRESHOLD_H
+
+#include "taler_util.h"
+#include "taler_json_lib.h"
+#include "taler_exchangedb_plugin.h"
+
+
+/**
+ * Obtain the current AML threshold set for an account.
+ *
+ * @param cls closure
+ * @param h_payto account for which the AML threshold is stored
+ * @param[out] decision set to current AML decision
+ * @param[out] threshold set to the existing threshold
+ * @return database transaction status, 0 if no threshold was set
+ */
+enum GNUNET_DB_QueryStatus
+TEH_PG_select_aml_threshold (
+ void *cls,
+ const struct TALER_PaytoHashP *h_payto,
+ enum TALER_AmlDecisionState *decision,
+ struct TALER_Amount *threshold);
+
+
+#endif
diff --git a/src/exchangedb/plugin_exchangedb_postgres.c b/src/exchangedb/plugin_exchangedb_postgres.c
index b201ef554..bbf061258 100644
--- a/src/exchangedb/plugin_exchangedb_postgres.c
+++ b/src/exchangedb/plugin_exchangedb_postgres.c
@@ -51,6 +51,7 @@
#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"
@@ -451,6 +452,8 @@ libtaler_plugin_exchangedb_postgres_init (void *cls)
= &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
diff --git a/src/include/taler_exchangedb_plugin.h b/src/include/taler_exchangedb_plugin.h
index 50a5c0efe..125254612 100644
--- a/src/include/taler_exchangedb_plugin.h
+++ b/src/include/taler_exchangedb_plugin.h
@@ -6605,6 +6605,23 @@ struct TALER_EXCHANGEDB_Plugin
struct GNUNET_TIME_Absolute *last_change);
+ /**
+ * Obtain the current AML threshold set for an account.
+ *
+ * @param cls closure
+ * @param h_payto account for which the AML threshold is stored
+ * @param[out] decision set to current AML decision
+ * @param[out] threshold set to the existing threshold
+ * @return database transaction status, 0 if no threshold was set
+ */
+ enum GNUNET_DB_QueryStatus
+ (*select_aml_threshold)(
+ void *cls,
+ const struct TALER_PaytoHashP *h_payto,
+ enum TALER_AmlDecisionState *decision,
+ struct TALER_Amount *threshold);
+
+
/**
* Trigger AML process, an account has crossed the threshold. Inserts or
* updates the AML status.