exchange

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

commit bc30273e1810d4f78b199a3fbbed774d8518edcb
parent 53fe2cc9d1cc7417361925b1861075c79d3a0250
Author: Christian Grothoff <christian@grothoff.org>
Date:   Sun,  8 Dec 2024 19:15:13 +0100

implement #9303

Diffstat:
Msrc/exchangedb/Makefile.am | 2++
Asrc/exchangedb/exchange_do_set_aml_lock.sql | 46++++++++++++++++++++++++++++++++++++++++++++++
Msrc/exchangedb/exchangedb_aml.c | 200+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------
Asrc/exchangedb/pg_clear_aml_lock.c | 50++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/pg_clear_aml_lock.h | 46++++++++++++++++++++++++++++++++++++++++++++++
Msrc/exchangedb/pg_insert_kyc_requirement_process.c | 1+
Asrc/exchangedb/pg_set_aml_lock.c | 74++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/exchangedb/pg_set_aml_lock.h | 48++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/exchangedb/pg_update_auditor.c | 2+-
Msrc/exchangedb/plugin_exchangedb_postgres.c | 6++++++
Msrc/exchangedb/procedures.sql.in | 1+
Msrc/include/taler_exchangedb_plugin.h | 38++++++++++++++++++++++++++++++++++++++
Msrc/include/taler_kyclogic_lib.h | 10++++++++++
Msrc/kyclogic/kyclogic_api.c | 18+++++++++++++++++-
14 files changed, 527 insertions(+), 15 deletions(-)

diff --git a/src/exchangedb/Makefile.am b/src/exchangedb/Makefile.am @@ -131,6 +131,7 @@ libtaler_plugin_exchangedb_postgres_la_SOURCES = \ pg_batch_ensure_coin_known.h pg_batch_ensure_coin_known.c \ pg_begin_revolving_shard.h pg_begin_revolving_shard.c \ pg_begin_shard.h pg_begin_shard.c \ + pg_clear_aml_lock.h pg_clear_aml_lock.c \ pg_commit.h pg_commit.c \ pg_complete_shard.h pg_complete_shard.c \ pg_compute_shard.h pg_compute_shard.c \ @@ -304,6 +305,7 @@ libtaler_plugin_exchangedb_postgres_la_SOURCES = \ pg_select_wire_out_above_serial_id_by_account.h pg_select_wire_out_above_serial_id_by_account.c \ pg_select_withdraw_amounts_for_kyc_check.h pg_select_withdraw_amounts_for_kyc_check.c \ pg_select_withdrawals_above_serial_id.h pg_select_withdrawals_above_serial_id.c \ + pg_set_aml_lock.h pg_set_aml_lock.c \ pg_set_extension_manifest.h pg_set_extension_manifest.c \ pg_set_purse_balance.h pg_set_purse_balance.c \ pg_start.h pg_start.c \ diff --git a/src/exchangedb/exchange_do_set_aml_lock.sql b/src/exchangedb/exchange_do_set_aml_lock.sql @@ -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/> +-- + +DROP FUNCTION IF EXISTS exchange_do_set_aml_lock; +CREATE FUNCTION exchange_do_set_aml_lock ( + IN in_h_payto BYTEA, + IN in_now INT8, + IN in_expiration INT8, + OUT out_aml_program_lock_timeout INT8) -- set if we have an existing lock +LANGUAGE plpgsql +AS $$ +BEGIN + +UPDATE wire_targets + SET aml_program_lock_timeout=in_expiration + WHERE h_normalized_payto=in_h_payto + AND ( (aml_program_lock_timeout IS NULL) + OR (aml_program_lock_timeout < in_now) ); +IF NOT FOUND +THEN + SELECT aml_program_lock_timeout + INTO out_aml_program_lock_timeout + FROM wire_targets + WHERE h_normalized_payto=in_h_payto; +ELSE + out_aml_program_lock_timeout = 0; +END IF; + +END $$; + + +COMMENT ON FUNCTION exchange_do_set_aml_lock(BYTEA, INT8, INT8) + IS 'Tries to lock an account for running an AML program. Returns the timeout of the existing lock, 0 if there is no existing lock, and NULL if we do not know the account.'; diff --git a/src/exchangedb/exchangedb_aml.c b/src/exchangedb/exchangedb_aml.c @@ -22,6 +22,7 @@ #include "taler_exchangedb_lib.h" #include "taler_kyclogic_lib.h" #include "taler_json_lib.h" +#include "taler_dbevents.h" #include <gnunet/gnunet_common.h> /** @@ -31,6 +32,13 @@ */ #define MAX_DEPTH 16 +/** + * How long do we allow an AML program to run for at most? + * If an AML program runs longer, we kill it and mark it as + * failed. + */ +#define MAX_AML_PROGRAM_RUNTIME GNUNET_TIME_UNIT_MINUTES + enum GNUNET_DB_QueryStatus TALER_EXCHANGEDB_persist_aml_program_result ( @@ -41,13 +49,9 @@ TALER_EXCHANGEDB_persist_aml_program_result ( { enum GNUNET_DB_QueryStatus qs; -#if 0 - /* FIXME: also clear lock on AML program (#9303) */ qs = plugin->clear_aml_lock ( plugin->cls, - account_id, - lock_id); -#endif + account_id); switch (apr->status) { case TALER_KYCLOGIC_AMLR_FAILURE: @@ -116,11 +120,23 @@ struct TALER_EXCHANGEDB_RuleUpdater struct GNUNET_SCHEDULER_Task *t; /** + * Handler waiting notification that (previous) AML program + * finished. + */ + struct GNUNET_DB_EventHandler *eh; + + /** * Handle to running AML program. */ struct TALER_KYCLOGIC_AmlProgramRunnerHandle *amlh; /** + * Name of the AML program we were running asynchronously, + * for diagnostics. + */ + char *aml_program_name; + + /** * Error hint to return with @e ec. */ const char *hint; @@ -227,6 +243,8 @@ aml_result_callback ( enum GNUNET_GenericReturnValue res; ru->amlh = NULL; + GNUNET_SCHEDULER_cancel (ru->t); + ru->t = NULL; res = ru->plugin->start (ru->plugin->cls, "aml-persist-aml-program-result"); if (GNUNET_OK != res) @@ -304,6 +322,121 @@ aml_result_callback ( static void +aml_program_timeout (void *cls) +{ + struct TALER_EXCHANGEDB_RuleUpdater *ru = cls; + struct TALER_KYCLOGIC_AmlProgramResult apr = { + .status = TALER_KYCLOGIC_AMLR_FAILURE, + .details.failure.fallback_measure + = TALER_KYCLOGIC_get_aml_program_fallback (ru->aml_program_name), + .details.failure.error_message = ru->aml_program_name, + .details.failure.ec = TALER_EC_EXCHANGE_KYC_GENERIC_AML_PROGRAM_TIMEOUT + }; + enum GNUNET_GenericReturnValue res; + enum GNUNET_DB_QueryStatus qs; + + ru->t = NULL; + TALER_KYCLOGIC_run_aml_program_cancel (ru->amlh); + ru->amlh = NULL; + GNUNET_assert (NULL != apr.details.failure.fallback_measure); + res = ru->plugin->start (ru->plugin->cls, + "aml-persist-aml-program-timeout"); + if (GNUNET_OK != res) + { + GNUNET_break (0); + fail_update (ru, + TALER_EC_GENERIC_DB_START_FAILED, + "aml-persist-aml-program-timeout"); + return; + } + /* Update database update based on result */ + qs = TALER_EXCHANGEDB_persist_aml_program_result ( + ru->plugin, + 0LLU, /* 0: no existing legitimization process, creates new row */ + &ru->account, + &apr); + switch (qs) + { + case GNUNET_DB_STATUS_HARD_ERROR: + GNUNET_break (0); + fail_update (ru, + TALER_EC_GENERIC_DB_STORE_FAILED, + "persist_aml_program_timeout"); + return; + case GNUNET_DB_STATUS_SOFT_ERROR: + /* Bad, couldn't persist AML result. Try again... */ + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Serialization issue persisting timeout of AML program. Restarting.\n"); + fail_update (ru, + TALER_EC_GENERIC_DB_SOFT_FAILURE, + "persist_aml_program_timeout"); + return; + case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: + /* Strange, but let's just continue */ + break; + case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: + /* normal case */ + break; + } + { + const char *fmn = apr.details.failure.fallback_measure; + const struct TALER_KYCLOGIC_Measure *m; + + m = TALER_KYCLOGIC_get_measure (ru->lrs, + fmn); + if (NULL == m) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Fallback measure `%s' does not exist (anymore?).\n", + fmn); + TALER_KYCLOGIC_rules_free (ru->lrs); + ru->lrs = NULL; + return_result (ru); + return; + } + run_measure (ru, + m); + return; + } +} + + +/** + * Entrypoint that fetches the latest rules from the database + * and starts processing them. Called without an open database + * transaction, will start one. + * + * @param[in] cls the `struct TALER_EXCHANGEDB_RuleUpdater *` to run + */ +static void +fetch_latest_rules (void *cls); + + +/** + * Notification called when we either timeout on the AML program lock + * or when the (previous) AML program finished and we can thus try again. + * + * @param cls the `struct TALER_EXCHANGEDB_RuleUpdater *` to continue + * @param extra additional event data provided (unused) + * @param extra_size number of bytes in @a extra (unused) + */ +static void +trigger_fetch_latest_rules (void *cls, + const void *extra, + size_t extra_size) +{ + struct TALER_EXCHANGEDB_RuleUpdater *ru = cls; + + (void) extra; + (void) extra_size; + if (NULL != ru->t) + return; /* multiple events triggered us, ignore */ + ru->t = GNUNET_SCHEDULER_add_now (&fetch_latest_rules, + ru); +} + + +static void run_measure (struct TALER_EXCHANGEDB_RuleUpdater *ru, const struct TALER_KYCLOGIC_Measure *m) { @@ -334,8 +467,37 @@ run_measure (struct TALER_EXCHANGEDB_RuleUpdater *ru, .attribute_key = &ru->attribute_key }; enum GNUNET_DB_QueryStatus qs; + struct GNUNET_TIME_Absolute xlock; - // FIXME: #9303 logic here? + /* Free previous one, in case we are iterating... */ + GNUNET_free (ru->aml_program_name); + ru->aml_program_name = GNUNET_strdup (m->prog_name); + qs = ru->plugin->set_aml_lock ( + ru->plugin->cls, + &ru->account, + GNUNET_TIME_relative_multiply (MAX_AML_PROGRAM_RUNTIME, + 2), + &xlock); + if (GNUNET_TIME_absolute_is_future (xlock)) + { + struct TALER_KycCompletedEventP eh = { + .header.size = htons (sizeof (eh)), + .header.type = htons (TALER_DBEVENT_EXCHANGE_KYC_COMPLETED), + .h_payto = ru->account + }; + /* Wait for either timeout or notification */ + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "AML program already running, waiting for it to finish\n"); + ru->plugin->rollback (ru->plugin->cls); + ru->eh + = ru->plugin->event_listen ( + ru->plugin->cls, + GNUNET_TIME_absolute_get_remaining (xlock), + &eh.header, + &trigger_fetch_latest_rules, + ru); + return; + } qs = ru->plugin->commit (ru->plugin->cls); if (qs < 0) { @@ -350,6 +512,11 @@ run_measure (struct TALER_EXCHANGEDB_RuleUpdater *ru, GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Check is of type 'skip', running AML program %s.\n", m->prog_name); + GNUNET_assert (NULL == ru->t); + ru->t = GNUNET_SCHEDULER_add_delayed ( + MAX_AML_PROGRAM_RUNTIME, + &aml_program_timeout, + ru); ru->amlh = TALER_KYCLOGIC_run_aml_program3 ( m, &TALER_EXCHANGEDB_current_attributes_builder, @@ -476,13 +643,6 @@ check_rules (struct TALER_EXCHANGEDB_RuleUpdater *ru) } -/** - * Entrypoint that fetches the latest rules from the database - * and starts processing them. Called without an open database - * transaction, will start one. - * - * @param[in] cls the `struct TALER_EXCHANGEDB_RuleUpdater *` to run - */ static void fetch_latest_rules (void *cls) { @@ -492,6 +652,13 @@ fetch_latest_rules (void *cls) enum GNUNET_GenericReturnValue res; ru->t = NULL; + if (NULL != ru->eh) + { + /* cancel event listener, if we have one */ + ru->plugin->event_listen_cancel (ru->plugin->cls, + ru->eh); + ru->eh = NULL; + } GNUNET_break (NULL == ru->lrs); res = ru->plugin->start (ru->plugin->cls, "aml-begin-lookup-rules-by-access-token"); @@ -568,5 +735,12 @@ TALER_EXCHANGEDB_update_rules_cancel ( TALER_KYCLOGIC_rules_free (ru->lrs); ru->lrs = NULL; } + if (NULL != ru->eh) + { + ru->plugin->event_listen_cancel (ru->plugin->cls, + ru->eh); + ru->eh = NULL; + } + GNUNET_free (ru->aml_program_name); GNUNET_free (ru); } diff --git a/src/exchangedb/pg_clear_aml_lock.c b/src/exchangedb/pg_clear_aml_lock.c @@ -0,0 +1,50 @@ +/* + 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_clear_aml_lock.c + * @brief Implementation of the clear_aml_lock 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_clear_aml_lock.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +TEH_PG_clear_aml_lock ( + void *cls, + const struct TALER_NormalizedPaytoHashP *h_payto) +{ + struct PostgresClosure *pg = cls; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (h_payto), + + GNUNET_PQ_query_param_end + }; + + PREPARE (pg, + "clear_aml_lock", + "UPDATE wire_targets" + " SET" + " aml_program_lock_timeout=NULL" + " WHERE h_normalized_payto=$1"); + return GNUNET_PQ_eval_prepared_non_select (pg->conn, + "clear_aml_lock", + params); +} diff --git a/src/exchangedb/pg_clear_aml_lock.h b/src/exchangedb/pg_clear_aml_lock.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_clear_aml_lock.h + * @brief implementation of the clear_aml_lock function for Postgres + * @author Christian Grothoff + */ +#ifndef PG_CLEAR_AML_LOCK_H +#define PG_CLEAR_AML_LOCK_H + +#include "taler_util.h" +#include "taler_json_lib.h" +#include "taler_exchangedb_plugin.h" + + +/** + * Clear a lock on running AML programs for the @a h_payto + * account. Returns 0 if @a h_payto is not known; does not + * actually care if there was a lock. Also does not by + * itself notify clients waiting for the lock, that + * notification the caller must do separately after finishing + * the database update. + * + * @param cls closure + * @param h_payto account to clear the lock for + * @return transaction status + */ +enum GNUNET_DB_QueryStatus +TEH_PG_clear_aml_lock ( + void *cls, + const struct TALER_NormalizedPaytoHashP *h_payto); + +#endif diff --git a/src/exchangedb/pg_insert_kyc_requirement_process.c b/src/exchangedb/pg_insert_kyc_requirement_process.c @@ -26,6 +26,7 @@ #include "pg_helper.h" #include <gnunet/gnunet_pq_lib.h> + enum GNUNET_DB_QueryStatus TEH_PG_insert_kyc_requirement_process ( void *cls, diff --git a/src/exchangedb/pg_set_aml_lock.c b/src/exchangedb/pg_set_aml_lock.c @@ -0,0 +1,74 @@ +/* + 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_set_aml_lock.c + * @brief Implementation of the set_aml_lock 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_set_aml_lock.h" +#include "pg_helper.h" + + +enum GNUNET_DB_QueryStatus +TEH_PG_set_aml_lock ( + void *cls, + const struct TALER_NormalizedPaytoHashP *h_payto, + struct GNUNET_TIME_Relative lock_duration, + struct GNUNET_TIME_Absolute *existing_lock) +{ + + struct PostgresClosure *pg = cls; + struct GNUNET_TIME_Absolute expires + = GNUNET_TIME_relative_to_absolute (lock_duration); + struct GNUNET_TIME_Absolute now + = GNUNET_TIME_absolute_get (); + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (h_payto), + GNUNET_PQ_query_param_absolute_time (&now), + GNUNET_PQ_query_param_absolute_time (&expires), + GNUNET_PQ_query_param_end + }; + bool nx; /* true if the *account* is not known */ + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_allow_null ( + GNUNET_PQ_result_spec_absolute_time ("out_aml_program_lock_timeout", + existing_lock), + &nx), + GNUNET_PQ_result_spec_end + }; + enum GNUNET_DB_QueryStatus qs; + + PREPARE (pg, + "set_aml_lock", + "SELECT out_aml_program_lock_timeout" + " FROM exchange_do_set_aml_lock($1,$2,$3);"); + qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn, + "set_aml_lock", + params, + rs); + if (qs <= 0) + return qs; + if (nx) + { + *existing_lock = GNUNET_TIME_UNIT_ZERO_ABS; + return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS; + } + return qs; +} diff --git a/src/exchangedb/pg_set_aml_lock.h b/src/exchangedb/pg_set_aml_lock.h @@ -0,0 +1,48 @@ +/* + 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_set_aml_lock.h + * @brief implementation of the set_aml_lock function for Postgres + * @author Christian Grothoff + */ +#ifndef PG_SET_AML_LOCK_H +#define PG_SET_AML_LOCK_H + +#include "taler_util.h" +#include "taler_json_lib.h" +#include "taler_exchangedb_plugin.h" + +/** + * Set a lock for @a lock_duration on running AML programs for the @a h_payto + * account. If a lock already exists, returns the timeout of the + * @a existing_lock. Returns 0 if @a h_payto is not known. + * + * @param cls closure + * @param h_payto account to lock + * @param lock_duration how long to lock the account + * @param[out] existing_lock set to timeout of existing lock, or + * to zero if there is no existing lock + * @return transaction status + */ +enum GNUNET_DB_QueryStatus +TEH_PG_set_aml_lock ( + void *cls, + const struct TALER_NormalizedPaytoHashP *h_payto, + struct GNUNET_TIME_Relative lock_duration, + struct GNUNET_TIME_Absolute *existing_lock); + + +#endif diff --git a/src/exchangedb/pg_update_auditor.c b/src/exchangedb/pg_update_auditor.c @@ -43,7 +43,7 @@ TEH_PG_update_auditor (void *cls, GNUNET_PQ_query_param_timestamp (&change_date), GNUNET_PQ_query_param_end }; - /* used in #postgres_update_auditor() */ + PREPARE (pg, "update_auditor", "UPDATE auditors" diff --git a/src/exchangedb/plugin_exchangedb_postgres.c b/src/exchangedb/plugin_exchangedb_postgres.c @@ -35,6 +35,7 @@ #include "pg_batch_ensure_coin_known.h" #include "pg_begin_revolving_shard.h" #include "pg_begin_shard.h" +#include "pg_clear_aml_lock.h" #include "pg_commit.h" #include "pg_complete_shard.h" #include "pg_compute_shard.h" @@ -208,6 +209,7 @@ #include "pg_select_wire_out_above_serial_id_by_account.h" #include "pg_select_withdraw_amounts_for_kyc_check.h" #include "pg_select_withdrawals_above_serial_id.h" +#include "pg_set_aml_lock.h" #include "pg_set_extension_manifest.h" #include "pg_set_purse_balance.h" #include "pg_start.h" @@ -771,6 +773,10 @@ libtaler_plugin_exchangedb_postgres_init (void *cls) = &TEH_PG_insert_aml_program_failure; plugin->persist_kyc_attributes = &TEH_PG_persist_kyc_attributes; + plugin->clear_aml_lock + = &TEH_PG_clear_aml_lock; + plugin->set_aml_lock + = &TEH_PG_set_aml_lock; return plugin; } diff --git a/src/exchangedb/procedures.sql.in b/src/exchangedb/procedures.sql.in @@ -58,5 +58,6 @@ SET search_path TO exchange; #include "exchange_do_select_aggregations_above_serial.sql" #include "exchange_do_persist_kyc_attributes.sql" #include "exchange_do_insert_aml_program_failure.sql" +#include "exchange_do_set_aml_lock.sql" COMMIT; diff --git a/src/include/taler_exchangedb_plugin.h b/src/include/taler_exchangedb_plugin.h @@ -7798,6 +7798,44 @@ struct TALER_EXCHANGEDB_Plugin enum GNUNET_GenericReturnValue (*inject_auditor_triggers)(void *cls); + + /** + * Set a lock for @a lock_duration on running AML programs for the @a h_payto + * account. If a lock already exists, returns the timeout of the + * @a existing_lock. Returns 0 if @a h_payto is not known. + * + * @param cls closure + * @param h_payto account to lock + * @param lock_duration how long to lock the account + * @param[out] existing_lock set to timeout of existing lock, or + * to zero if there is no existing lock + * @return transaction status + */ + enum GNUNET_DB_QueryStatus + (*set_aml_lock) ( + void *cls, + const struct TALER_NormalizedPaytoHashP *h_payto, + struct GNUNET_TIME_Relative lock_duration, + struct GNUNET_TIME_Absolute *existing_lock); + + + /** + * Clear a lock on running AML programs for the @a h_payto + * account. Returns 0 if @a h_payto is not known; does not + * actually care if there was a lock. Also does not by + * itself notify clients waiting for the lock, that + * notification the caller must do separately after finishing + * the database update. + * + * @param cls closure + * @param h_payto account to clear the lock for + * @return transaction status + */ + enum GNUNET_DB_QueryStatus + (*clear_aml_lock) ( + void *cls, + const struct TALER_NormalizedPaytoHashP *h_payto); + }; #endif /* _TALER_EXCHANGE_DB_H */ diff --git a/src/include/taler_kyclogic_lib.h b/src/include/taler_kyclogic_lib.h @@ -410,6 +410,16 @@ TALER_KYCLOGIC_get_zero_limits (void); /** + * Obtain the fallback measure to be run if @a prog_name fails + * + * @param prog_name name of an AML program + * @return NULL if @a prog_name is unknown + */ +const char * +TALER_KYCLOGIC_get_aml_program_fallback (const char *prog_name); + + +/** * Obtain set of all measures that * could be triggered at an amount of zero and that * thus might be requested before a client even diff --git a/src/kyclogic/kyclogic_api.c b/src/kyclogic/kyclogic_api.c @@ -1291,7 +1291,8 @@ TALER_KYCLOGIC_get_measure ( const struct TALER_KYCLOGIC_LegitimizationRuleSet *lrs, const char *measure_name) { - return find_measure (lrs, measure_name); + return find_measure (lrs, + measure_name); } @@ -3745,6 +3746,21 @@ TALER_KYCLOGIC_check_form ( } +const char * +TALER_KYCLOGIC_get_aml_program_fallback (const char *prog_name) +{ + struct TALER_KYCLOGIC_AmlProgram *prog; + + prog = find_program (prog_name); + if (NULL == prog) + { + GNUNET_break (0); + return NULL; + } + return prog->fallback; +} + + const struct TALER_KYCLOGIC_KycProvider * TALER_KYCLOGIC_check_to_provider (const char *check_name) {