exchange

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

commit ffdbf19f3a1724d1217de1a8f5ff67271f1f2e12
parent 7056e60230bf49e31c10eb32ee7ab938f5ce7d5f
Author: Christian Grothoff <christian@grothoff.org>
Date:   Wed, 11 Jun 2025 20:33:44 +0200

possible fix for #10093 (untested)

Diffstat:
Msrc/exchange/taler-exchange-httpd_common_kyc.c | 3+++
Asrc/exchangedb/exchange_do_get_kyc_rules.sql | 70++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/exchangedb/pg_get_kyc_rules.c | 27++++++++-------------------
Msrc/exchangedb/pg_get_kyc_rules.h | 4++++
Msrc/exchangedb/procedures.sql.in | 3++-
Msrc/include/taler_exchangedb_plugin.h | 4++++
6 files changed, 91 insertions(+), 20 deletions(-)

diff --git a/src/exchange/taler-exchange-httpd_common_kyc.c b/src/exchange/taler-exchange-httpd_common_kyc.c @@ -1584,6 +1584,9 @@ legitimization_check_run ( qs = TEH_plugin->get_kyc_rules ( TEH_plugin->cls, &lch->h_payto, + lch->have_merchant_pub + ? &lch->merchant_pub + : NULL, &no_account_pub, &lch->lcr.kyc.account_pub, &no_reserve_pub, diff --git a/src/exchangedb/exchange_do_get_kyc_rules.sql b/src/exchangedb/exchange_do_get_kyc_rules.sql @@ -0,0 +1,70 @@ +-- +-- This file is part of TALER +-- Copyright (C) 2023-2025 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_get_kyc_rules; + +CREATE FUNCTION exchange_do_get_kyc_rules( + IN in_h_payto BYTEA, + IN in_now INT8, + IN in_merchant_pub BYTEA, -- possibly NULL + OUT out_target_pub BYTEA, -- possibly NULL + OUT out_reserve_pub BYTEA, -- possibly NULL + OUT out_jnew_rules TEXT -- possibly NULL + ) +LANGUAGE plpgsql +AS $$ +DECLARE + my_found BOOL; +BEGIN + IF in_merchant_pub IS NOT NULL + THEN + PERFORM FROM reserves_in + WHERE wire_source_h_payto = in_h_payto + AND reserve_pub=in_merchant_pub; + my_found = FOUND; + ELSE + my_found = FALSE; + END IF; + IF FOUND + THEN + -- The merchant_pub used by the client matches, use that + out_reserve_pub = in_merchant_pub; + ELSE + -- If multiple reserves_in match, we pick the latest one + SELECT reserve_pub + INTO out_reserve_pub + FROM reserves_in + WHERE wire_source_h_payto = in_h_payto + ORDER BY execution_date DESC + LIMIT 1; + END IF; + + SELECT target_pub + INTO out_target_pub + FROM kyc_targets + WHERE h_normalized_payto = in_h_payto; + + SELECT jnew_rules + INTO out_jnew_rules + FROM legitimization_outcomes + WHERE h_payto = in_h_payto + AND COALESCE(expiration_time >= $2, TRUE) + AND COALESCE(is_active, TRUE) + -- technically only one should ever be active, but we can be conservative + ORDER BY expiration_time DESC + LIMIT 1; + + +END $$; diff --git a/src/exchangedb/pg_get_kyc_rules.c b/src/exchangedb/pg_get_kyc_rules.c @@ -30,6 +30,7 @@ enum GNUNET_DB_QueryStatus TEH_PG_get_kyc_rules ( void *cls, const struct TALER_NormalizedPaytoHashP *h_payto, + const struct TALER_MerchantPublicKeyP *merchant_pub, bool *no_account_pub, union TALER_AccountPublicKeyP *account_pub, bool *no_reserve_pub, @@ -42,6 +43,9 @@ TEH_PG_get_kyc_rules ( struct GNUNET_PQ_QueryParam params[] = { GNUNET_PQ_query_param_auto_from_type (h_payto), GNUNET_PQ_query_param_timestamp (&now), + NULL != merchant_pub + ? GNUNET_PQ_query_param_auto_from_type (merchant_pub) + : GNUNET_PQ_query_param_null (), GNUNET_PQ_query_param_end }; struct GNUNET_PQ_ResultSpec rs[] = { @@ -72,25 +76,10 @@ TEH_PG_get_kyc_rules ( PREPARE (pg, "get_kyc_rules", "SELECT" - " kt.target_pub" - " ,lo.jnew_rules" - " ,ri.reserve_pub" - " FROM kyc_targets kt" - /* This may result in multiple matches */ - " JOIN wire_targets wt" - " USING (h_normalized_payto)" - /* zero or more matches, reserve_pub will be NULL if no match */ - " LEFT JOIN reserves_in ri" - " ON (ri.wire_source_h_payto = wt.wire_target_h_payto)" - /* zero or more matches, jnew_rules will be NULL if no match */ - " LEFT JOIN legitimization_outcomes lo" - " ON (lo.h_payto = kt.h_normalized_payto)" - " WHERE kt.h_normalized_payto=$1" - " AND COALESCE(lo.expiration_time >= $2, TRUE)" - " AND COALESCE(lo.is_active, TRUE)" - /* If multiple reserves_in match, we pick the latest one */ - " ORDER BY ri.execution_date DESC" - " LIMIT 1;"); + " out_target_pub AS target_pub" + " ,out_jnew_rules AS jnew_rules" + " ,out_reserve_pub AS reserve_pub" + " FROM exchange_do_get_kyc_rules ($1,$2,$3);"); return GNUNET_PQ_eval_prepared_singleton_select ( pg->conn, "get_kyc_rules", diff --git a/src/exchangedb/pg_get_kyc_rules.h b/src/exchangedb/pg_get_kyc_rules.h @@ -31,6 +31,9 @@ * * @param cls the @e cls of this struct with the plugin-specific state * @param h_payto account identifier + * @param merchant_pub merchant public key used by the client, or NULL + * if not available; if multiple @a reserve_pub values could be returned, + * we should use this one * @param[out] no_account_pub set to true if no @a account_pub is available * @param[out] account_pub set to account public key the rules * apply to (because this key was used in KYC auth) @@ -46,6 +49,7 @@ enum GNUNET_DB_QueryStatus TEH_PG_get_kyc_rules ( void *cls, const struct TALER_NormalizedPaytoHashP *h_payto, + const struct TALER_MerchantPublicKeyP *merchant_pub, bool *no_account_pub, union TALER_AccountPublicKeyP *account_pub, bool *no_reserve_pub, diff --git a/src/exchangedb/procedures.sql.in b/src/exchangedb/procedures.sql.in @@ -1,6 +1,6 @@ -- -- This file is part of TALER --- Copyright (C) 2014--2024 Taler Systems SA +-- Copyright (C) 2014--2025 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 @@ -64,6 +64,7 @@ SET search_path TO exchange; #include "exchange_trigger_withdraw_insert.sql" #include "exchange_trigger_reserves_in_insert.sql" #include "exchange_trigger_purse_decision_insert.sql" +#include "exchange_do_get_kyc_rules.sql" DROP PROCEDURE IF EXISTS exchange_do_gc; CREATE PROCEDURE exchange_do_gc( diff --git a/src/include/taler_exchangedb_plugin.h b/src/include/taler_exchangedb_plugin.h @@ -7284,6 +7284,9 @@ struct TALER_EXCHANGEDB_Plugin * * @param cls the @e cls of this struct with the plugin-specific state * @param h_payto account identifier + * @param merchant_pub merchant public key used by the client, or NULL + * if not available; if multiple @a reserve_pub values could be returned, + * we should use this one * @param[out] no_account_pub set to true if no @a account_pub is available * @param[out] account_pub set to account public key the rules * apply to (because this key was used in KYC auth) @@ -7299,6 +7302,7 @@ struct TALER_EXCHANGEDB_Plugin (*get_kyc_rules)( void *cls, const struct TALER_NormalizedPaytoHashP *h_payto, + const struct TALER_MerchantPublicKeyP *merchant_pub, bool *no_account_pub, union TALER_AccountPublicKeyP *account_pub, bool *no_reserve_pub,