aboutsummaryrefslogtreecommitdiff
path: root/src/exchangedb
diff options
context:
space:
mode:
Diffstat (limited to 'src/exchangedb')
-rw-r--r--src/exchangedb/0002-reserves.sql8
-rw-r--r--src/exchangedb/0004-kyc_attributes.sql44
-rw-r--r--src/exchangedb/Makefile.am1
-rw-r--r--src/exchangedb/exchange-0004.sql.in3
-rw-r--r--src/exchangedb/exchange_do_insert_kyc_attributes.sql92
-rw-r--r--src/exchangedb/exchange_do_reserves_in_insert.sql136
-rw-r--r--src/exchangedb/pg_insert_kyc_attributes.c69
-rw-r--r--src/exchangedb/pg_insert_kyc_attributes.h21
-rw-r--r--src/exchangedb/pg_insert_records_by_table.c7
-rw-r--r--src/exchangedb/pg_lookup_records_by_table.c6
-rw-r--r--src/exchangedb/pg_reserves_in_insert.c281
-rw-r--r--src/exchangedb/pg_select_kyc_attributes.c7
-rw-r--r--src/exchangedb/pg_select_similar_kyc_attributes.c7
-rw-r--r--src/exchangedb/pg_update_kyc_attributes.c68
-rw-r--r--src/exchangedb/pg_update_kyc_attributes.h57
-rw-r--r--src/exchangedb/pg_update_kyc_process_by_row.c3
-rw-r--r--src/exchangedb/plugin_exchangedb_postgres.c3
-rw-r--r--src/exchangedb/procedures.sql.in1
18 files changed, 630 insertions, 184 deletions
diff --git a/src/exchangedb/0002-reserves.sql b/src/exchangedb/0002-reserves.sql
index 03d17aee2..df5b6c3db 100644
--- a/src/exchangedb/0002-reserves.sql
+++ b/src/exchangedb/0002-reserves.sql
@@ -31,7 +31,7 @@ BEGIN
',current_balance_frac INT4 NOT NULL DEFAULT(0)'
',purses_active INT8 NOT NULL DEFAULT(0)'
',purses_allowed INT8 NOT NULL DEFAULT(0)'
- ',max_age INT4 NOT NULL DEFAULT(120)'
+ ',max_age INT4 NOT NULL DEFAULT(0)'
',expiration_date INT8 NOT NULL'
',gc_date INT8 NOT NULL'
') %s ;'
@@ -80,6 +80,12 @@ BEGIN
,table_name
,partition_suffix
);
+ PERFORM comment_partitioned_column(
+ 'Birthday of the user in days after 1970, or 0 if user is an adult and is not subject to age restrictions'
+ ,'max_age'
+ ,table_name
+ ,partition_suffix
+ );
END
$$;
diff --git a/src/exchangedb/0004-kyc_attributes.sql b/src/exchangedb/0004-kyc_attributes.sql
new file mode 100644
index 000000000..e45d46b3b
--- /dev/null
+++ b/src/exchangedb/0004-kyc_attributes.sql
@@ -0,0 +1,44 @@
+--
+-- 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 <http://www.gnu.org/licenses/>
+--
+
+CREATE OR REPLACE FUNCTION master_table_kyc_attributes_V2()
+RETURNS VOID
+LANGUAGE plpgsql
+AS $$
+DECLARE
+ table_name VARCHAR DEFAULT 'kyc_attributes';
+BEGIN
+ EXECUTE FORMAT (
+ 'ALTER TABLE ' || table_name ||
+ ' DROP COLUMN birthdate;'
+ );
+END $$;
+
+COMMENT ON FUNCTION master_table_kyc_attributes_V2
+ IS 'Removes birthdate column from the kyc_attributes table';
+
+INSERT INTO exchange_tables
+ (name
+ ,version
+ ,action
+ ,partitioned
+ ,by_range)
+ VALUES
+ ('kyc_attributes_V2'
+ ,'exchange-0004'
+ ,'master'
+ ,TRUE
+ ,FALSE);
diff --git a/src/exchangedb/Makefile.am b/src/exchangedb/Makefile.am
index ee78b87f7..4df9cb406 100644
--- a/src/exchangedb/Makefile.am
+++ b/src/exchangedb/Makefile.am
@@ -144,7 +144,6 @@ libtaler_plugin_exchangedb_postgres_la_SOURCES = \
pg_aggregate.h pg_aggregate.c \
pg_create_aggregation_transient.h pg_create_aggregation_transient.c \
pg_insert_kyc_attributes.h pg_insert_kyc_attributes.c \
- pg_update_kyc_attributes.h pg_update_kyc_attributes.c \
pg_select_similar_kyc_attributes.h pg_select_similar_kyc_attributes.c \
pg_select_kyc_attributes.h pg_select_kyc_attributes.c \
pg_insert_aml_officer.h pg_insert_aml_officer.c \
diff --git a/src/exchangedb/exchange-0004.sql.in b/src/exchangedb/exchange-0004.sql.in
index 00979e193..02bdf017a 100644
--- a/src/exchangedb/exchange-0004.sql.in
+++ b/src/exchangedb/exchange-0004.sql.in
@@ -1,6 +1,6 @@
--
-- This file is part of TALER
--- Copyright (C) 2014--2023 Taler Systems SA
+-- 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
@@ -19,6 +19,7 @@ BEGIN;
SELECT _v.register_patch('exchange-0004', NULL, NULL);
SET search_path TO exchange;
+#include "0004-kyc_attributes.sql"
#include "0004-wire_accounts.sql"
COMMIT;
diff --git a/src/exchangedb/exchange_do_insert_kyc_attributes.sql b/src/exchangedb/exchange_do_insert_kyc_attributes.sql
new file mode 100644
index 000000000..f1959a66e
--- /dev/null
+++ b/src/exchangedb/exchange_do_insert_kyc_attributes.sql
@@ -0,0 +1,92 @@
+--
+-- 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 <http://www.gnu.org/licenses/>
+--
+
+CREATE OR REPLACE FUNCTION exchange_do_insert_kyc_attributes(
+ IN in_process_row INT8,
+ IN in_h_payto BYTEA,
+ IN in_kyc_prox BYTEA,
+ IN in_provider_section VARCHAR,
+ IN in_birthday INT4,
+ IN in_provider_account_id VARCHAR,
+ IN in_provider_legitimization_id VARCHAR,
+ IN in_collection_time_ts INT8,
+ IN in_expiration_time INT8,
+ IN in_expiration_time_ts INT8,
+ IN in_enc_attributes BYTEA,
+ IN in_require_aml BOOLEAN,
+ IN in_kyc_completed_notify_s VARCHAR,
+ OUT out_ok BOOLEAN)
+LANGUAGE plpgsql
+AS $$
+BEGIN
+
+INSERT INTO exchange.kyc_attributes
+ (h_payto
+ ,kyc_prox
+ ,provider
+ ,collection_time
+ ,expiration_time
+ ,encrypted_attributes
+ ) VALUES
+ (in_h_payto
+ ,in_kyc_prox
+ ,in_provider_section
+ ,in_collection_time_ts
+ ,in_expiration_time_ts
+ ,in_enc_attributes);
+
+-- FIXME-Oec: modify to 'return' the reserve_pub here
+-- (requires of course to modify other code to store
+-- the reserve pub in the right table in the first place)
+UPDATE exchange.legitimization_processes
+ SET provider_user_id=in_provider_account_id
+ ,provider_legitimization_id=in_provider_legitimization_id
+ ,expiration_time=GREATEST(expiration_time,in_expiration_time)
+ WHERE h_payto=in_h_payto
+ AND legitimization_process_serial_id=in_process_row
+ AND provider_section=in_provider_section;
+out_ok = FOUND;
+
+-- FIXME-Oec: update exchange reserve table to store in_birthday here!
+-- UPDATE exchange.reserves SET max_age=in_birthday WHERE reserve_pub=X;
+
+IF in_require_aml
+THEN
+ INSERT INTO exchange.aml_status
+ (h_payto
+ ,status)
+ VALUES
+ (in_h_payto
+ ,1)
+ ON CONFLICT (h_payto) DO
+ UPDATE SET status=EXCLUDED.status | 1;
+END IF;
+
+-- Wake up everyone who might care...
+PERFORM pg_notify (in_kyc_completed_notify_s, NULL);
+
+INSERT INTO kyc_alerts
+ (h_payto
+ ,trigger_type)
+ VALUES
+ (in_h_payto,1);
+
+
+END $$;
+
+
+COMMENT ON FUNCTION exchange_do_insert_kyc_attributes(INT8, BYTEA, BYTEA, VARCHAR, INT4, VARCHAR, VARCHAR, INT8, INT8, INT8, BYTEA, BOOL, VARCHAR)
+ IS 'Inserts new KYC attributes and updates the status of the legitimization process and the AML status for the account';
diff --git a/src/exchangedb/exchange_do_reserves_in_insert.sql b/src/exchangedb/exchange_do_reserves_in_insert.sql
index dffcd8b55..cf57d8e81 100644
--- a/src/exchangedb/exchange_do_reserves_in_insert.sql
+++ b/src/exchangedb/exchange_do_reserves_in_insert.sql
@@ -963,3 +963,139 @@ BEGIN
CLOSE curs_transaction_exist;
RETURN;
END $$;
+
+
+
+
+
+
+
+DO $$
+BEGIN
+ CREATE TYPE exchange_do_array_reserve_insert_return_type
+ AS
+ (transaction_duplicate BOOLEAN
+ ,ruuid INT8);
+EXCEPTION
+ WHEN duplicate_object THEN null;
+END
+$$;
+
+CREATE OR REPLACE FUNCTION exchange_do_array_reserves_insert(
+ IN in_gc_date INT8,
+ IN in_reserve_expiration INT8,
+ IN ina_reserve_pub BYTEA[],
+ IN ina_wire_ref INT8[],
+ IN ina_credit_val INT8[],
+ IN ina_credit_frac INT4[],
+ IN ina_exchange_account_name VARCHAR[],
+ IN ina_execution_date INT8[],
+ IN ina_wire_source_h_payto BYTEA[],
+ IN ina_payto_uri VARCHAR[],
+ IN ina_notify TEXT[])
+RETURNS SETOF exchange_do_array_reserve_insert_return_type
+LANGUAGE plpgsql
+AS $$
+DECLARE
+ curs REFCURSOR;
+DECLARE
+ conflict BOOL;
+DECLARE
+ dup BOOL;
+DECLARE
+ uuid INT8;
+DECLARE
+ i RECORD;
+BEGIN
+
+ INSERT INTO wire_targets
+ (wire_target_h_payto
+ ,payto_uri)
+ SELECT
+ wire_source_h_payto
+ ,payto_uri
+ FROM
+ UNNEST (ina_wire_source_h_payto) AS wire_source_h_payto
+ ,UNNEST (ina_payto_uri) AS payto_uri
+ ON CONFLICT DO NOTHING;
+
+ FOR i IN
+ SELECT
+ reserve_pub
+ ,wire_ref
+ ,credit_val
+ ,credit_frac
+ ,exchange_account_name
+ ,execution_date
+ ,wire_source_h_payto
+ ,payto_uri
+ ,notify
+ FROM
+ UNNEST (ina_reserve_pub) AS reserve_pub
+ ,UNNEST (ina_wire_ref) AS wire_ref
+ ,UNNEST (ina_credit_val) AS credit_val
+ ,UNNEST (ina_credit_frac) AS credit_frac
+ ,UNNEST (ina_exchange_account_name) AS exchange_account_name
+ ,UNNEST (ina_execution_date) AS execution_date
+ ,UNNEST (ina_wire_source_h_payto) AS wire_source_h_payto
+ ,UNNEST (ina_notify) AS notify
+ LOOP
+ INSERT INTO reserves
+ (reserve_pub
+ ,current_balance_val
+ ,current_balance_frac
+ ,expiration_date
+ ,gc_date
+ ) VALUES (
+ i.reserve_pub
+ ,i.credit_val
+ ,i.credit_frac
+ ,in_reserve_expiration
+ ,in_gc_date
+ )
+ ON CONFLICT DO NOTHING
+ RETURNING reserve_uuid
+ INTO uuid;
+ conflict = NOT FOUND;
+
+ INSERT INTO reserves_in
+ (reserve_pub
+ ,wire_reference
+ ,credit_val
+ ,credit_frac
+ ,exchange_account_section
+ ,wire_source_h_payto
+ ,execution_date
+ ) VALUES (
+ i.reserve_pub
+ ,i.wire_reference
+ ,i.credit_val
+ ,i.credit_frac
+ ,i.exchange_account_section
+ ,i.wire_source_h_payto
+ ,i.execution_date
+ )
+ ON CONFLICT DO NOTHING;
+
+ IF NOT FOUND
+ THEN
+ IF conflict
+ THEN
+ dup = TRUE;
+ else
+ dup = FALSE;
+ END IF;
+ ELSE
+ IF NOT conflict
+ THEN
+ EXECUTE FORMAT (
+ 'NOTIFY %s'
+ ,i.notify);
+ END IF;
+ dup = FALSE;
+ END IF;
+ RETURN NEXT (dup,uuid);
+ END LOOP;
+
+ RETURN;
+END $$;
diff --git a/src/exchangedb/pg_insert_kyc_attributes.c b/src/exchangedb/pg_insert_kyc_attributes.c
index fd90950fd..361f491e8 100644
--- a/src/exchangedb/pg_insert_kyc_attributes.c
+++ b/src/exchangedb/pg_insert_kyc_attributes.c
@@ -1,6 +1,6 @@
/*
This file is part of TALER
- Copyright (C) 2022 Taler Systems SA
+ Copyright (C) 2022, 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
@@ -29,43 +29,72 @@
enum GNUNET_DB_QueryStatus
TEH_PG_insert_kyc_attributes (
void *cls,
+ uint64_t process_row,
const struct TALER_PaytoHashP *h_payto,
const struct GNUNET_ShortHashCode *kyc_prox,
const char *provider_section,
- const char *birthdate,
+ uint32_t birthday,
struct GNUNET_TIME_Timestamp collection_time,
- struct GNUNET_TIME_Timestamp expiration_time,
+ const char *provider_account_id,
+ const char *provider_legitimization_id,
+ struct GNUNET_TIME_Absolute expiration_time,
size_t enc_attributes_size,
- const void *enc_attributes)
+ const void *enc_attributes,
+ bool require_aml)
{
struct PostgresClosure *pg = cls;
+ struct GNUNET_TIME_Timestamp expiration
+ = GNUNET_TIME_absolute_to_timestamp (expiration_time);
+ struct TALER_KycCompletedEventP rep = {
+ .header.size = htons (sizeof (rep)),
+ .header.type = htons (TALER_DBEVENT_EXCHANGE_KYC_COMPLETED),
+ .h_payto = *h_payto
+ };
+ char *kyc_completed_notify_s
+ = GNUNET_PG_get_event_notify_channel (&rep.header);
struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_uint64 (&process_row),
GNUNET_PQ_query_param_auto_from_type (h_payto),
GNUNET_PQ_query_param_auto_from_type (kyc_prox),
GNUNET_PQ_query_param_string (provider_section),
- (NULL == birthdate)
+ GNUNET_PQ_query_param_uint32 (&birthday),
+ (NULL == provider_account_id)
+ ? GNUNET_PQ_query_param_null ()
+ : GNUNET_PQ_query_param_string (provider_account_id),
+ (NULL == provider_legitimization_id)
? GNUNET_PQ_query_param_null ()
- : GNUNET_PQ_query_param_string (birthdate),
+ : GNUNET_PQ_query_param_string (provider_legitimization_id),
GNUNET_PQ_query_param_timestamp (&collection_time),
- GNUNET_PQ_query_param_timestamp (&expiration_time),
+ GNUNET_PQ_query_param_absolute_time (&expiration_time),
+ GNUNET_PQ_query_param_timestamp (&expiration),
GNUNET_PQ_query_param_fixed_size (enc_attributes,
enc_attributes_size),
+ GNUNET_PQ_query_param_bool (require_aml),
+ GNUNET_PQ_query_param_string (kyc_completed_notify_s),
GNUNET_PQ_query_param_end
};
+ bool ok;
+ struct GNUNET_PQ_ResultSpec rs[] = {
+ GNUNET_PQ_result_spec_bool ("out_ok",
+ &ok),
+ GNUNET_PQ_result_spec_end
+ };
+ enum GNUNET_DB_QueryStatus qs;
PREPARE (pg,
"insert_kyc_attributes",
- "INSERT INTO kyc_attributes "
- "(h_payto"
- ",kyc_prox"
- ",provider"
- ",birthdate"
- ",collection_time"
- ",expiration_time"
- ",encrypted_attributes"
- ") VALUES "
- "($1, $2, $3, $4, $5, $6, $7);");
- return GNUNET_PQ_eval_prepared_non_select (pg->conn,
- "insert_kyc_attributes",
- params);
+ "SELECT "
+ " out_ok"
+ " FROM exchange_do_insert_kyc_attributes "
+ "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13);");
+ qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
+ "insert_kyc_attributes",
+ params,
+ rs);
+ GNUNET_free (kyc_completed_notify_s);
+ if (qs < 0)
+ return qs;
+ if (! ok)
+ return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS;
+ return qs;
}
diff --git a/src/exchangedb/pg_insert_kyc_attributes.h b/src/exchangedb/pg_insert_kyc_attributes.h
index 8ee307d7d..c1aad0eb5 100644
--- a/src/exchangedb/pg_insert_kyc_attributes.h
+++ b/src/exchangedb/pg_insert_kyc_attributes.h
@@ -27,30 +27,39 @@
/**
- * Store KYC attribute data.
+ * Store KYC attribute data, update KYC process status and
+ * AML status for the given account.
*
* @param cls closure
+ * @param process_row KYC process row to update
* @param h_payto account for which the attribute data is stored
* @param kyc_prox key for similarity search
* @param provider_section provider that must be checked
- * @param birthdate birthdate of user, in format YYYY-MM-DD; can be NULL;
- * digits can be 0 if exact day, month or year are unknown
+ * @param provider_account_id provider account ID
+ * @param provider_legitimization_id provider legitimization ID
+ * @param birthday birthdate of user, in days after 1990, or 0 if unknown or definitively adult
* @param collection_time when was the data collected
* @param expiration_time when does the data expire
* @param enc_attributes_size number of bytes in @a enc_attributes
* @param enc_attributes encrypted attribute data
+ * @param require_aml true to trigger AML
* @return database transaction status
*/
enum GNUNET_DB_QueryStatus
TEH_PG_insert_kyc_attributes (
void *cls,
+ uint64_t process_row,
const struct TALER_PaytoHashP *h_payto,
const struct GNUNET_ShortHashCode *kyc_prox,
const char *provider_section,
- const char *birthdate,
+ uint32_t birthday,
struct GNUNET_TIME_Timestamp collection_time,
- struct GNUNET_TIME_Timestamp expiration_time,
+ const char *provider_account_id,
+ const char *provider_legitimization_id,
+ struct GNUNET_TIME_Absolute expiration_time,
size_t enc_attributes_size,
- const void *enc_attributes);
+ const void *enc_attributes,
+ bool require_aml);
+
#endif
diff --git a/src/exchangedb/pg_insert_records_by_table.c b/src/exchangedb/pg_insert_records_by_table.c
index e16a4b74f..9baaf3b1a 100644
--- a/src/exchangedb/pg_insert_records_by_table.c
+++ b/src/exchangedb/pg_insert_records_by_table.c
@@ -1995,10 +1995,6 @@ irbt_cb_table_kyc_attributes (struct PostgresClosure *pg,
&td->details.kyc_attributes.kyc_prox),
GNUNET_PQ_query_param_string (
td->details.kyc_attributes.provider),
- (NULL == td->details.kyc_attributes.birthdate)
- ? GNUNET_PQ_query_param_null ()
- : GNUNET_PQ_query_param_string (
- td->details.kyc_attributes.birthdate),
GNUNET_PQ_query_param_timestamp (
&td->details.kyc_attributes.collection_time),
GNUNET_PQ_query_param_timestamp (
@@ -2016,12 +2012,11 @@ irbt_cb_table_kyc_attributes (struct PostgresClosure *pg,
",h_payto"
",kyc_prox"
",provider"
- ",birthdate"
",collection_time"
",expiration_time"
",encrypted_attributes"
") VALUES "
- "($1, $2, $3, $4, $5, $6, $7, $8);");
+ "($1, $2, $3, $4, $5, $6, $7);");
return GNUNET_PQ_eval_prepared_non_select (pg->conn,
"insert_into_table_kyc_attributes",
params);
diff --git a/src/exchangedb/pg_lookup_records_by_table.c b/src/exchangedb/pg_lookup_records_by_table.c
index 534e9a1d2..3fcad58c0 100644
--- a/src/exchangedb/pg_lookup_records_by_table.c
+++ b/src/exchangedb/pg_lookup_records_by_table.c
@@ -2684,11 +2684,6 @@ lrbt_cb_table_kyc_attributes (void *cls,
GNUNET_PQ_result_spec_string (
"provider",
&td.details.kyc_attributes.provider),
- GNUNET_PQ_result_spec_allow_null (
- GNUNET_PQ_result_spec_string (
- "birthdate",
- &td.details.kyc_attributes.birthdate),
- NULL),
GNUNET_PQ_result_spec_timestamp (
"collection_time",
&td.details.kyc_attributes.collection_time),
@@ -3577,7 +3572,6 @@ TEH_PG_lookup_records_by_table (void *cls,
",h_payto"
",kyc_prox"
",provider"
- ",birthdate"
",collection_time"
",expiration_time"
",encrypted_attributes"
diff --git a/src/exchangedb/pg_reserves_in_insert.c b/src/exchangedb/pg_reserves_in_insert.c
index 691c57d38..72fde7499 100644
--- a/src/exchangedb/pg_reserves_in_insert.c
+++ b/src/exchangedb/pg_reserves_in_insert.c
@@ -615,3 +615,284 @@ TEH_PG_reserves_in_insert (
GNUNET_free (rrs[i].notify_s);
return qs;
}
+
+
+#if 0
+
+/**
+ * Closure for our helper_cb()
+ */
+struct Context
+{
+ /**
+ * Array of reserve UUIDs to initialize.
+ */
+ uint64_t *reserve_uuids;
+
+ /**
+ * Array with entries set to 'true' for duplicate transactions.
+ */
+ bool *transaction_duplicates;
+
+ /**
+ * Array with entries set to 'true' for rows with conflicts.
+ */
+ bool *conflicts;
+
+ /**
+ * Set to #GNUNET_SYSERR on failures.
+ */
+ struct GNUNET_GenericReturnValue status;
+
+ /**
+ * Single value (no array) set to true if we need
+ * to follow-up with an update.
+ */
+ bool *needs_update;
+};
+
+
+/**
+ * Helper function to be called with the results of a SELECT statement
+ * that has returned @a num_results results.
+ *
+ * @param cls closure of type `struct Context *`
+ * @param result the postgres result
+ * @param num_results the number of results in @a result
+ */
+static void
+helper_cb (void *cls,
+ PGresult *result,
+ unsigned int num_results)
+{
+ struct Context *ctx = cls;
+
+ for (unsigned int i = 0; i<num_results; i++)
+ {
+ struct GNUNET_PQ_ResultSpec rs[] = {
+ GNUNET_PQ_result_spec_bool (
+ "transaction_duplicate",
+ &ctx->transaction_duplicates[i]),
+ GNUNET_PQ_result_spec_allow_null (
+ GNUNET_PQ_result_spec_uint64 ("ruuid",
+ &ctx->reserve_uuids[i]),
+ &ctx->conflicts[i]),
+ GNUNET_PQ_result_spec_end
+ };
+
+ if (GNUNET_OK !=
+ GNUNET_PQ_extract_result (result,
+ rs,
+ i))
+ {
+ GNUNET_break (0);
+ ctx->status = GNUNET_SYSERR;
+ return;
+ }
+ *ctx->need_update |= ctx->conflicts[i];
+ }
+}
+
+
+enum GNUNET_DB_QueryStatus
+TEH_PG_reserves_in_insertN (
+ void *cls,
+ const struct TALER_EXCHANGEDB_ReserveInInfo *reserves,
+ unsigned int reserves_length,
+ enum GNUNET_DB_QueryStatus *results)
+{
+ struct PostgresClosure *pg = cls;
+ struct TALER_PaytoHashP h_paytos[GNUNET_NZL (reserves_length)];
+ char *notify_s[GNUNET_NZL (reserves_length)];
+ struct TALER_ReservePublicKeyP *reserve_pubs[GNUNET_NZL (reserves_length)];
+ struct TALER_Amount *balances[GNUNET_NZL (reserves_length)];
+ struct GNUNET_TIME_Timestamp execution_times[GNUNET_NZL (reserves_length)];
+ const char *sender_account_details[GNUNET_NZL (reserves_length)];
+ const char *exchange_account_names[GNUNET_NZL (reserves_length)];
+ uint64_t wire_references[GNUNET_NZL (reserves_length)];
+ uint64_t reserve_uuids[GNUNET_NZL (reserves_length)];
+ bool transaction_duplicates[GNUNET_NZL (reserves_length)];
+ bool conflicts[GNUNET_NZL (reserves_length)];
+ struct GNUNET_TIME_Timestamp reserve_expiration
+ = GNUNET_TIME_relative_to_timestamp (pg->idle_reserve_expiration_time);
+ struct GNUNET_TIME_Timestamp gc
+ = GNUNET_TIME_relative_to_timestamp (pg->legal_reserve_expiration_time);
+ bool needs_update = false;
+ enum GNUNET_DB_QueryStatus qs;
+
+ for (unsigned int i = 0; i<reserves_length; i++)
+ {
+ const struct TALER_EXCHANGEDB_ReserveInInfo *reserve = &reserves[i];
+
+ TALER_payto_hash (reserve->sender_account_details,
+ &h_paytos[i]);
+ notify_s[i] = compute_notify_on_reserve (reserve->reserve_pub);
+ reserve_pubs[i] = &reserve->reserve_pub;
+ balances[i] = &reserve->balance;
+ execution_times[i] = reserve->execution_time;
+ sender_account_details[i] = reserve->sender_account_details;
+ exchange_account_names[i] = reserve->exchange_account_name;
+ wire_references[i] = reserve->wire_reference;
+ }
+
+ /* NOTE: kind-of pointless to explicitly start a transaction here... */
+ if (GNUNET_OK !=
+ TEH_PG_preflight (pg))
+ {
+ GNUNET_break (0);
+ qs = GNUNET_DB_STATUS_HARD_ERROR;
+ goto finished;
+ }
+
+ if (GNUNET_OK !=
+ TEH_PG_start_read_committed (pg,
+ "READ_COMMITED"))
+ {
+ GNUNET_break (0);
+ qs = GNUNET_DB_STATUS_HARD_ERROR;
+ goto finished;
+ }
+
+ PREPARE (pg,
+ "reserves_insert_with_array",
+ "SELECT"
+ " transaction_duplicate"
+ ",ruuid"
+ "FROM exchange_do_array_reserves_insert"
+ " ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10);");
+ {
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_timestamp (&gc),
+ GNUNET_PQ_query_param_timestamp (&reserve_expiration),
+ GNUNET_PQ_query_param_array_auto_from_type (reserves_length,
+ reserve_pubs,
+ pg->conn),
+ GNUNET_PQ_query_param_array_uint64 (reserves_length,
+ wire_references,
+ pg->conn),
+ TALER_PQ_query_param_array_amount (reserves_length,
+ balances,
+ pg->conn),
+ GNUNET_PQ_query_param_array_string (reserves_length,
+ exchange_account_names,
+ pg->conn),
+ GNUNET_PQ_query_param_array_timestamp (reserves_length,
+ execution_times,
+ pg->conn),
+ GNUNET_PQ_query_param_array_bytes_same_size_cont_auto (
+ reserves_length,
+ h_paytos,
+ sizeof (struct GNUNET_PaytoHashP),
+ pg->conn),
+ GNUNET_PQ_query_param_array_string (reserves_length,
+ sender_account_details,
+ pg->conn),
+ GNUNET_PQ_query_param_array_string (reserves_length,
+ notify_s,
+ pg->conn),
+ GNUNET_PQ_query_param_end
+ };
+ struct Context ctx = {
+ .reserve_uuids = reserve_uuids,
+ .transaction_duplicates = transaction_duplicates,
+ .conflicts = conflicts,
+ .needs_update = &needs_update,
+ .status = GNUNET_OK
+ };
+
+ qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
+ "reserves_insert_with_array",
+ params,
+ &multi_res,
+ &ctx);
+ if ( (qs < 0) ||
+ (GNUNET_OK != ctx.status) )
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ "Failed to insert into reserves (%d)\n",
+ qs);
+ goto finished;
+ }
+ }
+
+ {
+ enum GNUNET_DB_QueryStatus cs;
+
+ cs = TEH_PG_commit (pg);
+ if (cs < 0)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ "Failed to commit\n");
+ qs = cs;
+ goto finished;
+ }
+ }
+ for (unsigned int i = 0; i<reserves_length; i++)
+ {
+ results[i] = transaction_duplicates[i]
+ ? GNUNET_DB_STATUS_SUCCESS_NO_RESULTS
+ : GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
+ }
+
+ if (! need_update)
+ {
+ qs = reserves_length;
+ goto finished;
+ }
+ if (GNUNET_OK !=
+ TEH_PG_start (pg,
+ "reserve-insert-continued"))
+ {
+ GNUNET_break (0);
+ qs = GNUNET_DB_STATUS_HARD_ERROR;
+ goto finished;
+ }
+
+ for (unsigned int i = 0; i<reserves_length; i++)
+ {
+ if (! conflicts[i])
+ continue;
+ {
+ bool duplicate;
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_auto_from_type (reserve_pubs[i]),
+ GNUNET_PQ_query_param_timestamp (&reserve_expiration),
+ GNUNET_PQ_query_param_uint64 (&wire_reference[i]),
+ TALER_PQ_query_param_amount (balances[i]),
+ GNUNET_PQ_query_param_string (exchange_account_names[i]),
+ GNUNET_PQ_query_param_auto_from_type (h_paytos[i]),
+ GNUNET_PQ_query_param_string (notify_s[i]),
+ GNUNET_PQ_query_param_end
+ };
+ struct GNUNET_PQ_ResultSpec rs[] = {
+ GNUNET_PQ_result_spec_bool ("duplicate",
+ &duplicate),
+ GNUNET_PQ_result_spec_end
+ };
+ enum GNUNET_DB_QueryStatus qs;
+
+ qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
+ "reserves_update",
+ params,
+ rs);
+ if (qs < 0)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ "Failed to update reserves (%d)\n",
+ qs);
+ results[i] = qs;
+ goto finished;
+ }
+ results[i] = duplicate
+ ? GNUNET_DB_STATUS_SUCCESS_NO_RESULTS
+ : GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
+ }
+ }
+finished:
+ for (unsigned int i = 0; i<reserves_length; i++)
+ GNUNET_free (rrs[i].notify_s);
+ return qs;
+}
+
+
+#endif
diff --git a/src/exchangedb/pg_select_kyc_attributes.c b/src/exchangedb/pg_select_kyc_attributes.c
index c9b992da2..99ac43b3e 100644
--- a/src/exchangedb/pg_select_kyc_attributes.c
+++ b/src/exchangedb/pg_select_kyc_attributes.c
@@ -80,14 +80,9 @@ get_attributes_cb (void *cls,
size_t enc_attributes_size;
void *enc_attributes;
char *provider;
- char *birthdate = NULL;
struct GNUNET_PQ_ResultSpec rs[] = {
GNUNET_PQ_result_spec_string ("provider",
&provider),
- GNUNET_PQ_result_spec_allow_null (
- GNUNET_PQ_result_spec_string ("birthdate",
- &birthdate),
- NULL),
GNUNET_PQ_result_spec_timestamp ("collection_time",
&collection_time),
GNUNET_PQ_result_spec_timestamp ("expiration_time",
@@ -110,7 +105,6 @@ get_attributes_cb (void *cls,
ctx->cb (ctx->cb_cls,
ctx->h_payto,
provider,
- birthdate,
collection_time,
expiration_time,
enc_attributes_size,
@@ -145,7 +139,6 @@ TEH_PG_select_kyc_attributes (
"select_kyc_attributes",
"SELECT "
" provider"
- ",birthdate"
",collection_time"
",expiration_time"
",encrypted_attributes"
diff --git a/src/exchangedb/pg_select_similar_kyc_attributes.c b/src/exchangedb/pg_select_similar_kyc_attributes.c
index a07f2a147..342f9ef33 100644
--- a/src/exchangedb/pg_select_similar_kyc_attributes.c
+++ b/src/exchangedb/pg_select_similar_kyc_attributes.c
@@ -76,16 +76,11 @@ get_attributes_cb (void *cls,
size_t enc_attributes_size;
void *enc_attributes;
char *provider;
- char *birthdate = NULL;
struct GNUNET_PQ_ResultSpec rs[] = {
GNUNET_PQ_result_spec_auto_from_type ("h_payto",
&h_payto),
GNUNET_PQ_result_spec_string ("provider",
&provider),
- GNUNET_PQ_result_spec_allow_null (
- GNUNET_PQ_result_spec_string ("birthdate",
- &birthdate),
- NULL),
GNUNET_PQ_result_spec_timestamp ("collection_time",
&collection_time),
GNUNET_PQ_result_spec_timestamp ("expiration_time",
@@ -108,7 +103,6 @@ get_attributes_cb (void *cls,
ctx->cb (ctx->cb_cls,
&h_payto,
provider,
- birthdate,
collection_time,
expiration_time,
enc_attributes_size,
@@ -143,7 +137,6 @@ TEH_PG_select_similar_kyc_attributes (
"SELECT "
" h_payto"
",provider"
- ",birthdate"
",collection_time"
",expiration_time"
",encrypted_attributes"
diff --git a/src/exchangedb/pg_update_kyc_attributes.c b/src/exchangedb/pg_update_kyc_attributes.c
deleted file mode 100644
index f77eb2bfc..000000000
--- a/src/exchangedb/pg_update_kyc_attributes.c
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2022 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_update_kyc_attributes.c
- * @brief Implementation of the update_kyc_attributes 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_update_kyc_attributes.h"
-#include "pg_helper.h"
-
-
-enum GNUNET_DB_QueryStatus
-TEH_PG_update_kyc_attributes (
- void *cls,
- const struct TALER_PaytoHashP *h_payto,
- const struct GNUNET_ShortHashCode *kyc_prox,
- const char *provider_section,
- const char *birthdate,
- struct GNUNET_TIME_Timestamp collection_time,
- struct GNUNET_TIME_Timestamp expiration_time,
- size_t enc_attributes_size,
- const void *enc_attributes)
-{
- struct PostgresClosure *pg = cls;
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (h_payto),
- GNUNET_PQ_query_param_auto_from_type (kyc_prox),
- GNUNET_PQ_query_param_string (provider_section),
- (NULL == birthdate)
- ? GNUNET_PQ_query_param_null ()
- : GNUNET_PQ_query_param_string (birthdate),
- GNUNET_PQ_query_param_timestamp (&collection_time),
- GNUNET_PQ_query_param_timestamp (&expiration_time),
- GNUNET_PQ_query_param_fixed_size (enc_attributes,
- enc_attributes_size),
- GNUNET_PQ_query_param_end
- };
-
- PREPARE (pg,
- "update_kyc_attributes",
- "UPDATE kyc_attributes SET "
- " kyc_prox=$2"
- ",birthdate=$4"
- ",collection_time=$5"
- ",expiration_time=$6"
- ",encrypted_attributes=$7"
- " WHERE h_payto=$1 AND provider_section=$3;");
- return GNUNET_PQ_eval_prepared_non_select (pg->conn,
- "update_kyc_attributes",
- params);
-}
diff --git a/src/exchangedb/pg_update_kyc_attributes.h b/src/exchangedb/pg_update_kyc_attributes.h
deleted file mode 100644
index 5d17eb7fa..000000000
--- a/src/exchangedb/pg_update_kyc_attributes.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2022 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_update_kyc_attributes.h
- * @brief implementation of the update_kyc_attributes function for Postgres
- * @author Christian Grothoff
- */
-#ifndef PG_UPDATE_KYC_ATTRIBUTES_H
-#define PG_UPDATE_KYC_ATTRIBUTES_H
-
-#include "taler_util.h"
-#include "taler_json_lib.h"
-#include "taler_exchangedb_plugin.h"
-
-
-/**
- * Update KYC attribute data.
- *
- * @param cls closure
- * @param h_payto account for which the attribute data is stored
- * @param kyc_prox key for similarity search
- * @param provider_section provider that must be checked
- * @param birthdate birthdate of user, in format YYYY-MM-DD; can be NULL;
- * digits can be 0 if exact day, month or year are unknown
- * @param collection_time when was the data collected
- * @param expiration_time when does the data expire
- * @param enc_attributes_size number of bytes in @a enc_attributes
- * @param enc_attributes encrypted attribute data
- * @return database transaction status
- */
-enum GNUNET_DB_QueryStatus
-TEH_PG_update_kyc_attributes (
- void *cls,
- const struct TALER_PaytoHashP *h_payto,
- const struct GNUNET_ShortHashCode *kyc_prox,
- const char *provider_section,
- const char *birthdate,
- struct GNUNET_TIME_Timestamp collection_time,
- struct GNUNET_TIME_Timestamp expiration_time,
- size_t enc_attributes_size,
- const void *enc_attributes);
-
-
-#endif
diff --git a/src/exchangedb/pg_update_kyc_process_by_row.c b/src/exchangedb/pg_update_kyc_process_by_row.c
index 4ae44ce53..711f47802 100644
--- a/src/exchangedb/pg_update_kyc_process_by_row.c
+++ b/src/exchangedb/pg_update_kyc_process_by_row.c
@@ -68,7 +68,8 @@ TEH_PG_update_kyc_process_by_row (
if (qs <= 0)
{
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "Failed to update legitimization process: %d\n",
+ "Failed to update legitimization process %llu: %d\n",
+ (unsigned long long) process_row,
qs);
return qs;
}
diff --git a/src/exchangedb/plugin_exchangedb_postgres.c b/src/exchangedb/plugin_exchangedb_postgres.c
index b3ebc7547..006484198 100644
--- a/src/exchangedb/plugin_exchangedb_postgres.c
+++ b/src/exchangedb/plugin_exchangedb_postgres.c
@@ -207,7 +207,6 @@
#include "pg_setup_wire_target.h"
#include "pg_compute_shard.h"
#include "pg_insert_kyc_attributes.h"
-#include "pg_update_kyc_attributes.h"
#include "pg_select_similar_kyc_attributes.h"
#include "pg_select_kyc_attributes.h"
#include "pg_insert_aml_officer.h"
@@ -754,8 +753,6 @@ libtaler_plugin_exchangedb_postgres_init (void *cls)
= &TEH_PG_set_purse_balance;
plugin->insert_kyc_attributes
= &TEH_PG_insert_kyc_attributes;
- plugin->update_kyc_attributes
- = &TEH_PG_update_kyc_attributes;
plugin->select_similar_kyc_attributes
= &TEH_PG_select_similar_kyc_attributes;
plugin->select_kyc_attributes
diff --git a/src/exchangedb/procedures.sql.in b/src/exchangedb/procedures.sql.in
index 12ec3656f..c9277ea60 100644
--- a/src/exchangedb/procedures.sql.in
+++ b/src/exchangedb/procedures.sql.in
@@ -39,6 +39,7 @@ SET search_path TO exchange;
#include "exchange_do_insert_or_update_policy_details.sql"
#include "exchange_do_insert_aml_decision.sql"
#include "exchange_do_insert_aml_officer.sql"
+#include "exchange_do_insert_kyc_attributes.sql"
#include "exchange_do_reserves_in_insert.sql"
#include "exchange_do_batch_reserves_update.sql"
#include "exchange_do_refund_by_coin.sql"