aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2024-07-16 15:03:44 +0200
committerChristian Grothoff <christian@grothoff.org>2024-07-29 12:18:45 +0200
commitfa22c593f4c8ca85978329c22dcfdd5da9ba6d7b (patch)
treea524059d059e8e864b6c80a71557224200d51fe5
parentb74676950a547f203459c9d274646c356bf07e7c (diff)
start with wire-gateway API v1 implementation
-rw-r--r--src/auditor/taler-helper-auditor-wire.c147
-rw-r--r--src/bank-lib/Makefile.am5
-rw-r--r--src/bank-lib/bank_api_admin_add_incoming.c (renamed from src/bank-lib/bank_api_admin.c)4
-rw-r--r--src/bank-lib/bank_api_admin_add_kycauth.c260
-rw-r--r--src/bank-lib/bank_api_credit.c71
-rw-r--r--src/bank-lib/taler-exchange-wire-gateway-client.c33
-rw-r--r--src/exchange/taler-exchange-wirewatch.c121
-rw-r--r--src/include/taler_bank_service.h258
-rw-r--r--src/include/taler_exchangedb_plugin.h44
-rw-r--r--src/testing/testing_api_cmd_bank_history_credit.c162
10 files changed, 938 insertions, 167 deletions
diff --git a/src/auditor/taler-helper-auditor-wire.c b/src/auditor/taler-helper-auditor-wire.c
index d63e741a2..3d6f04ebf 100644
--- a/src/auditor/taler-helper-auditor-wire.c
+++ b/src/auditor/taler-helper-auditor-wire.c
@@ -361,7 +361,7 @@ struct ReserveInInfo
* The member "account_url" is to be allocated
* at the end of this struct!
*/
- struct TALER_BANK_CreditDetails details;
+ struct TALER_BANK_CreditDetails credit_details;
/**
* RowID in reserves_in table.
@@ -2151,10 +2151,11 @@ reserve_in_cb (void *cls,
slen = strlen (sender_account_details) + 1;
rii = GNUNET_malloc (sizeof (struct ReserveInInfo) + slen);
rii->rowid = rowid;
- rii->details.amount = *credit;
- rii->details.execution_date = execution_date;
- rii->details.reserve_pub = *reserve_pub;
- rii->details.debit_account_uri = (const char *) &rii[1];
+ rii->credit_details.type = TALER_BANK_CT_RESERVE;
+ rii->credit_details.amount = *credit;
+ rii->credit_details.execution_date = execution_date;
+ rii->credit_details.details.reserve.reserve_pub = *reserve_pub;
+ rii->credit_details.debit_account_uri = (const char *) &rii[1];
GNUNET_memcpy (&rii[1],
sender_account_details,
slen);
@@ -2237,19 +2238,22 @@ complain_in_not_found (void *cls,
{
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
}
+ GNUNET_assert (TALER_BANK_CT_RESERVE ==
+ rii->credit_details.type);
TALER_ARL_report (
report_reserve_in_inconsistencies,
GNUNET_JSON_PACK (
GNUNET_JSON_pack_uint64 ("row",
rii->rowid),
TALER_JSON_pack_amount ("amount_exchange_expected",
- &rii->details.amount),
+ &rii->credit_details.amount),
TALER_JSON_pack_amount ("amount_wired",
&zero),
GNUNET_JSON_pack_data_auto ("reserve_pub",
- &rii->details.reserve_pub),
+ &rii->credit_details.reserve.reserve_pub),
TALER_JSON_pack_time_abs_human ("timestamp",
- rii->details.execution_date.abs_time),
+ rii->credit_details.execution_date.
+ abs_time),
GNUNET_JSON_pack_string ("account",
wa->ai->section_name),
GNUNET_JSON_pack_string ("diagnostic",
@@ -2257,7 +2261,7 @@ complain_in_not_found (void *cls,
#endif
TALER_ARL_amount_add (&total_bad_amount_in_minus,
&total_bad_amount_in_minus,
- &rii->details.amount);
+ &rii->credit_details.amount);
return GNUNET_OK;
}
@@ -2306,8 +2310,9 @@ conclude_account (struct WireAccount *wa)
* @return true on success, false to stop loop at this point
*/
static bool
-analyze_credit (struct WireAccount *wa,
- const struct TALER_BANK_CreditDetails *details)
+analyze_credit (
+ struct WireAccount *wa,
+ const struct TALER_BANK_CreditDetails *credit_details)
{
struct ReserveInInfo *rii;
struct GNUNET_HashCode key;
@@ -2318,13 +2323,15 @@ analyze_credit (struct WireAccount *wa,
// struct TALER_AUDITORDB_MisattributionInInconsistency mii;
// struct TALER_AUDITORDB_RowMinorInconsistencies rmi;
+ GNUNET_assert (TALER_BANK_CT_RESERVE ==
+ credit_details->type);
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Analyzing bank CREDIT at %s of %s with Reserve-pub %s\n",
- GNUNET_TIME_timestamp2s (details->execution_date),
- TALER_amount2s (&details->amount),
- TALER_B2S (&details->reserve_pub));
- GNUNET_CRYPTO_hash (&details->serial_id,
- sizeof (details->serial_id),
+ GNUNET_TIME_timestamp2s (credit_details->execution_date),
+ TALER_amount2s (&credit_details->amount),
+ TALER_B2S (&credit_details->details.reserve.reserve_pub));
+ GNUNET_CRYPTO_hash (&credit_details->serial_id,
+ sizeof (credit_details->serial_id),
&key);
rii = GNUNET_CONTAINER_multihashmap_get (in_map,
&key);
@@ -2332,24 +2339,24 @@ analyze_credit (struct WireAccount *wa,
{
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Failed to find wire transfer at `%s' in exchange database. Audit ends at this point in time.\n",
- GNUNET_TIME_timestamp2s (details->execution_date));
+ GNUNET_TIME_timestamp2s (credit_details->execution_date));
process_credits (wa->next);
return false; /* not an error, just end of processing */
}
/* Update offset */
- wa->wire_off_in = details->serial_id;
+ wa->wire_off_in = credit_details->serial_id;
/* compare records with expected data */
- if (0 != GNUNET_memcmp (&details->reserve_pub,
- &rii->details.reserve_pub))
+ if (0 != GNUNET_memcmp (&credit_details->details.reserve.reserve_pub,
+ &rii->credit_details.details.reserve.reserve_pub))
{
#if FIXME
riiDb.diagnostic = "wire subject does not match";
riiDb.account = details->serial_id;
- riiDb.amount_exchange_expected = &rii->details.amount;
+ riiDb.amount_exchange_expected = &rii->credit_details.amount;
riiDb.amount_wired = &zero;
- riiDb.reserve_pub = &rii->details.reserve_pub;
- riiDb.timestamp = rii->details.execution_date.abs_time;
+ riiDb.reserve_pub = &rii->credit_details.detaisl.reserve.reserve_pub;
+ riiDb.timestamp = rii->credit_details.execution_date.abs_time;
qs = TALER_ARL_adb->insert_reserve_in_inconsistency (
TALER_ARL_adb->cls,
@@ -2365,28 +2372,30 @@ analyze_credit (struct WireAccount *wa,
GNUNET_JSON_pack_uint64 ("row",
rii->rowid),
GNUNET_JSON_pack_uint64 ("bank_row",
- details->serial_id),
+ credit_details->serial_id),
TALER_JSON_pack_amount ("amount_exchange_expected",
- &rii->details.amount),
+ &rii->credit_details.amount),
TALER_JSON_pack_amount ("amount_wired",
&zero),
GNUNET_JSON_pack_data_auto ("reserve_pub",
- &rii->details.reserve_pub),
+ &rii->credit_details.details.reserve.
+ reserve_pub),
TALER_JSON_pack_time_abs_human ("timestamp",
- rii->details.execution_date.abs_time),
+ rii->credit_details.execution_date.
+ abs_time),
GNUNET_JSON_pack_string ("diagnostic",
"wire subject does not match")));
#endif
TALER_ARL_amount_add (&total_bad_amount_in_minus,
&total_bad_amount_in_minus,
- &rii->details.amount);
+ &rii->credit_details.amount);
#if FIXME
riiDb2.diagnostic = "wire subject does not match";
- riiDb2.account = details->serial_id;
- riiDb2.amount_exchange_expected = &rii->details.amount;
+ riiDb2.account = credit_details->serial_id;
+ riiDb2.amount_exchange_expected = &rii->credit_details.amount;
riiDb2.amount_wired = &zero;
- riiDb2.reserve_pub = &rii->details.reserve_pub;
- riiDb2.timestamp = rii->details.execution_date.abs_time;
+ riiDb2.reserve_pub = &rii->credit_details.details.reserve.reserve_pub;
+ riiDb2.timestamp = rii->credit_details.execution_date.abs_time;
qs = TALER_ARL_adb->insert_reserve_in_inconsistency (
TALER_ARL_adb->cls,
@@ -2402,33 +2411,35 @@ analyze_credit (struct WireAccount *wa,
GNUNET_JSON_pack_uint64 ("row",
rii->rowid),
GNUNET_JSON_pack_uint64 ("bank_row",
- details->serial_id),
+ credit_details->serial_id),
TALER_JSON_pack_amount ("amount_exchange_expected",
&zero),
TALER_JSON_pack_amount ("amount_wired",
- &details->amount),
+ &credit_details->amount),
GNUNET_JSON_pack_data_auto ("reserve_pub",
- &details->reserve_pub),
+ &credit_details->details.reserve.reserve_pub
+ ),
TALER_JSON_pack_time_abs_human ("timestamp",
- details->execution_date.abs_time),
+ credit_details->execution_date.abs_time)
+ ,
GNUNET_JSON_pack_string ("diagnostic",
"wire subject does not match")));
#endif
TALER_ARL_amount_add (&total_bad_amount_in_plus,
&total_bad_amount_in_plus,
- &details->amount);
+ &credit_details->amount);
goto cleanup;
}
- if (0 != TALER_amount_cmp (&rii->details.amount,
- &details->amount))
+ if (0 != TALER_amount_cmp (&rii->credit_details.amount,
+ &credit_details->amount))
{
#if FIXME
riiDb3.diagnostic = "wire amount does not match";
- riiDb3.account = details->serial_id;
- riiDb3.amount_exchange_expected = &rii->details.amount;
- riiDb3.amount_wired = &details->amount;
- riiDb3.reserve_pub = &rii->details.reserve_pub;
- riiDb3.timestamp = rii->details.execution_date.abs_time;
+ riiDb3.account = credit_details->serial_id;
+ riiDb3.amount_exchange_expected = &rii->credit_details.amount;
+ riiDb3.amount_wired = &credit_details->amount;
+ riiDb3.reserve_pub = &rii->credit_details.details.reserve.reserve_pub;
+ riiDb3.timestamp = rii->credit_details.execution_date.abs_time;
qs = TALER_ARL_adb->insert_reserve_in_inconsistency (
TALER_ARL_adb->cls,
@@ -2444,27 +2455,29 @@ analyze_credit (struct WireAccount *wa,
GNUNET_JSON_pack_uint64 ("row",
rii->rowid),
GNUNET_JSON_pack_uint64 ("bank_row",
- details->serial_id),
+ credit_details->serial_id),
TALER_JSON_pack_amount ("amount_exchange_expected",
- &rii->details.amount),
+ &rii->credit_details.amount),
TALER_JSON_pack_amount ("amount_wired",
- &details->amount),
+ &credit_details->amount),
GNUNET_JSON_pack_data_auto ("reserve_pub",
- &details->reserve_pub),
+ &credit_details->details.reserve.reserve_pub
+ ),
TALER_JSON_pack_time_abs_human ("timestamp",
- details->execution_date.abs_time),
+ credit_details->execution_date.abs_time)
+ ,
GNUNET_JSON_pack_string ("diagnostic",
"wire amount does not match")));
#endif
- if (0 < TALER_amount_cmp (&details->amount,
- &rii->details.amount))
+ if (0 < TALER_amount_cmp (&credit_details->amount,
+ &rii->credit_details.amount))
{
/* details->amount > rii->details.amount: wire transfer was larger than it should have been */
struct TALER_Amount delta;
TALER_ARL_amount_subtract (&delta,
- &details->amount,
- &rii->details.amount);
+ &credit_details->amount,
+ &rii->credit_details.amount);
TALER_ARL_amount_add (&total_bad_amount_in_plus,
&total_bad_amount_in_plus,
&delta);
@@ -2475,21 +2488,21 @@ analyze_credit (struct WireAccount *wa,
struct TALER_Amount delta;
TALER_ARL_amount_subtract (&delta,
- &rii->details.amount,
- &details->amount);
+ &rii->credit_details.amount,
+ &credit_details->amount);
TALER_ARL_amount_add (&total_bad_amount_in_minus,
&total_bad_amount_in_minus,
&delta);
}
goto cleanup;
}
- if (0 != strcasecmp (details->debit_account_uri,
- rii->details.debit_account_uri))
+ if (0 != strcasecmp (credit_details->debit_account_uri,
+ rii->credit_details.debit_account_uri))
{
#if FIXME
- mii.reserve_pub = &rii->details.reserve_pub;
- mii.amount = &rii->details.amount;
- mii.bank_row = details->serial_id;
+ mii.reserve_pub = &rii->credit_details.details.reserve.reserve_pub;
+ mii.amount = &rii->credit_details.amount;
+ mii.bank_row = credit_details->serial_id;
qs = TALER_ARL_adb->insert_misattribution_in_inconsistency (
TALER_ARL_adb->cls,
@@ -2502,22 +2515,22 @@ analyze_credit (struct WireAccount *wa,
TALER_ARL_report (report_misattribution_in_inconsistencies,
GNUNET_JSON_PACK (
TALER_JSON_pack_amount ("amount",
- &rii->details.amount),
+ &rii->credit_details.amount),
GNUNET_JSON_pack_uint64 ("row",
rii->rowid),
GNUNET_JSON_pack_uint64 ("bank_row",
- details->serial_id),
+ credit_details->serial_id),
GNUNET_JSON_pack_data_auto (
"reserve_pub",
- &rii->details.reserve_pub)));
+ &rii->credit_details.details.reserve.reserve_pub)));
#endif
TALER_ARL_amount_add (&total_misattribution_in,
&total_misattribution_in,
- &rii->details.amount);
+ &rii->credit_details.amount);
}
- if (GNUNET_TIME_timestamp_cmp (details->execution_date,
+ if (GNUNET_TIME_timestamp_cmp (credit_details->execution_date,
!=,
- rii->details.execution_date))
+ rii->credit_details.execution_date))
{
#if FIXME
rmi.diagnostic = "execution date mismatch";
@@ -2538,7 +2551,7 @@ analyze_credit (struct WireAccount *wa,
GNUNET_JSON_pack_uint64 ("row",
rii->rowid),
GNUNET_JSON_pack_uint64 ("bank_row",
- details->serial_id),
+ credit_details->serial_id),
GNUNET_JSON_pack_string ("diagnostic",
"execution date mismatch")));
#endif
diff --git a/src/bank-lib/Makefile.am b/src/bank-lib/Makefile.am
index ef7704684..816395cdd 100644
--- a/src/bank-lib/Makefile.am
+++ b/src/bank-lib/Makefile.am
@@ -34,10 +34,11 @@ lib_LTLIBRARIES = \
libtalerfakebank.la
libtalerbank_la_LDFLAGS = \
- -version-info 1:0:0 \
+ -version-info 2:0:0 \
-no-undefined
libtalerbank_la_SOURCES = \
- bank_api_admin.c \
+ bank_api_admin_add_incoming.c \
+ bank_api_admin_add_kycauth.c \
bank_api_common.c bank_api_common.h \
bank_api_credit.c \
bank_api_debit.c \
diff --git a/src/bank-lib/bank_api_admin.c b/src/bank-lib/bank_api_admin_add_incoming.c
index f12ab6ee2..ffc89ccc5 100644
--- a/src/bank-lib/bank_api_admin.c
+++ b/src/bank-lib/bank_api_admin_add_incoming.c
@@ -15,7 +15,7 @@
<http://www.gnu.org/licenses/>
*/
/**
- * @file bank-lib/bank_api_admin.c
+ * @file bank-lib/bank_api_admin_add_incoming.c
* @brief Implementation of the /admin/add-incoming requests of the bank's HTTP API
* @author Christian Grothoff
*/
@@ -262,4 +262,4 @@ TALER_BANK_admin_add_incoming_cancel (
}
-/* end of bank_api_admin.c */
+/* end of bank_api_admin_add_incoming.c */
diff --git a/src/bank-lib/bank_api_admin_add_kycauth.c b/src/bank-lib/bank_api_admin_add_kycauth.c
new file mode 100644
index 000000000..1660305b1
--- /dev/null
+++ b/src/bank-lib/bank_api_admin_add_kycauth.c
@@ -0,0 +1,260 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2015--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 bank-lib/bank_api_admin_add_kycauth.c
+ * @brief Implementation of the /admin/add-kycauth requests of the bank's HTTP API
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include "bank_api_common.h"
+#include <microhttpd.h> /* just for HTTP status codes */
+#include "taler_signatures.h"
+#include "taler_curl_lib.h"
+
+
+/**
+ * @brief An /admin/add-kycauth Handle
+ */
+struct TALER_BANK_AdminAddKycauthHandle
+{
+
+ /**
+ * The url for this request.
+ */
+ char *request_url;
+
+ /**
+ * POST context.
+ */
+ struct TALER_CURL_PostContext post_ctx;
+
+ /**
+ * Handle for the request.
+ */
+ struct GNUNET_CURL_Job *job;
+
+ /**
+ * Function to call with the result.
+ */
+ TALER_BANK_AdminAddKycauthCallback cb;
+
+ /**
+ * Closure for @a cb.
+ */
+ void *cb_cls;
+
+};
+
+
+/**
+ * Function called when we're done processing the
+ * HTTP /admin/add-kycauth request.
+ *
+ * @param cls the `struct TALER_BANK_AdminAddKycauthHandle`
+ * @param response_code HTTP response code, 0 on error
+ * @param response parsed JSON result, NULL on error
+ */
+static void
+handle_admin_add_kycauth_finished (void *cls,
+ long response_code,
+ const void *response)
+{
+ struct TALER_BANK_AdminAddKycauthHandle *aai = cls;
+ const json_t *j = response;
+ struct TALER_BANK_AdminAddKycauthResponse ir = {
+ .http_status = response_code,
+ .response = response
+ };
+
+ aai->job = NULL;
+ switch (response_code)
+ {
+ case 0:
+ ir.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
+ break;
+ case MHD_HTTP_OK:
+ {
+ struct GNUNET_JSON_Specification spec[] = {
+ GNUNET_JSON_spec_uint64 ("row_id",
+ &ir.details.ok.serial_id),
+ GNUNET_JSON_spec_timestamp ("timestamp",
+ &ir.details.ok.timestamp),
+ GNUNET_JSON_spec_end ()
+ };
+
+ if (GNUNET_OK !=
+ GNUNET_JSON_parse (j,
+ spec,
+ NULL, NULL))
+ {
+ GNUNET_break_op (0);
+ ir.http_status = 0;
+ ir.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
+ break;
+ }
+ }
+ break;
+ case MHD_HTTP_BAD_REQUEST:
+ /* This should never happen, either us or the bank is buggy
+ (or API version conflict); just pass JSON reply to the application */
+ GNUNET_break_op (0);
+ ir.ec = TALER_JSON_get_error_code (j);
+ break;
+ case MHD_HTTP_FORBIDDEN:
+ /* Access denied */
+ ir.ec = TALER_JSON_get_error_code (j);
+ break;
+ case MHD_HTTP_UNAUTHORIZED:
+ /* Nothing really to verify, bank says the password is invalid; we should
+ pass the JSON reply to the application */
+ ir.ec = TALER_JSON_get_error_code (j);
+ break;
+ case MHD_HTTP_NOT_FOUND:
+ /* Nothing really to verify, maybe account really does not exist.
+ We should pass the JSON reply to the application */
+ ir.ec = TALER_JSON_get_error_code (j);
+ break;
+ case MHD_HTTP_INTERNAL_SERVER_ERROR:
+ /* Server had an internal issue; we should retry, but this API
+ leaves this to the application */
+ ir.ec = TALER_JSON_get_error_code (j);
+ break;
+ default:
+ /* unexpected response code */
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Unexpected response code %u\n",
+ (unsigned int) response_code);
+ GNUNET_break (0);
+ ir.ec = TALER_JSON_get_error_code (j);
+ break;
+ }
+ aai->cb (aai->cb_cls,
+ &ir);
+ TALER_BANK_admin_add_kycauth_cancel (aai);
+}
+
+
+struct TALER_BANK_AdminAddKycauthHandle *
+TALER_BANK_admin_add_kycauth (
+ struct GNUNET_CURL_Context *ctx,
+ const struct TALER_BANK_AuthenticationData *auth,
+ const union TALER_AccountPublicKeyP *account_pub,
+ const struct TALER_Amount *amount,
+ const char *debit_account,
+ TALER_BANK_AdminAddKycauthCallback res_cb,
+ void *res_cb_cls)
+{
+ struct TALER_BANK_AdminAddKycauthHandle *aai;
+ json_t *admin_obj;
+ CURL *eh;
+
+ if (NULL == debit_account)
+ {
+ GNUNET_break (0);
+ return NULL;
+ }
+ if (NULL == account_pub)
+ {
+ GNUNET_break (0);
+ return NULL;
+ }
+ if (NULL == amount)
+ {
+ GNUNET_break (0);
+ return NULL;
+ }
+ admin_obj = GNUNET_JSON_PACK (
+ GNUNET_JSON_pack_data_auto ("account_pub",
+ account_pub),
+ TALER_JSON_pack_amount ("amount",
+ amount),
+ GNUNET_JSON_pack_string ("debit_account",
+ debit_account));
+ if (NULL == admin_obj)
+ {
+ GNUNET_break (0);
+ return NULL;
+ }
+ aai = GNUNET_new (struct TALER_BANK_AdminAddKycauthHandle);
+ aai->cb = res_cb;
+ aai->cb_cls = res_cb_cls;
+ aai->request_url = TALER_url_join (auth->wire_gateway_url,
+ "admin/add-kycauth",
+ NULL);
+ if (NULL == aai->request_url)
+ {
+ GNUNET_free (aai);
+ json_decref (admin_obj);
+ return NULL;
+ }
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Requesting administrative transaction at `%s' for account %s\n",
+ aai->request_url,
+ TALER_B2S (account_pub));
+ aai->post_ctx.headers
+ = curl_slist_append (
+ aai->post_ctx.headers,
+ "Content-Type: application/json");
+
+ eh = curl_easy_init ();
+ if ( (NULL == eh) ||
+ (GNUNET_OK !=
+ TALER_BANK_setup_auth_ (eh,
+ auth)) ||
+ (CURLE_OK !=
+ curl_easy_setopt (eh,
+ CURLOPT_URL,
+ aai->request_url)) ||
+ (GNUNET_OK !=
+ TALER_curl_easy_post (&aai->post_ctx,
+ eh,
+ admin_obj)) )
+ {
+ GNUNET_break (0);
+ TALER_BANK_admin_add_kycauth_cancel (aai);
+ if (NULL != eh)
+ curl_easy_cleanup (eh);
+ json_decref (admin_obj);
+ return NULL;
+ }
+ json_decref (admin_obj);
+
+ aai->job = GNUNET_CURL_job_add2 (ctx,
+ eh,
+ aai->post_ctx.headers,
+ &handle_admin_add_kycauth_finished,
+ aai);
+ return aai;
+}
+
+
+void
+TALER_BANK_admin_add_kycauth_cancel (
+ struct TALER_BANK_AdminAddKycauthHandle *aai)
+{
+ if (NULL != aai->job)
+ {
+ GNUNET_CURL_job_cancel (aai->job);
+ aai->job = NULL;
+ }
+ TALER_curl_easy_post_finished (&aai->post_ctx);
+ GNUNET_free (aai->request_url);
+ GNUNET_free (aai);
+}
+
+
+/* end of bank_api_admin_add_kycauth.c */
diff --git a/src/bank-lib/bank_api_credit.c b/src/bank-lib/bank_api_credit.c
index 124415b80..ebcdb56cc 100644
--- a/src/bank-lib/bank_api_credit.c
+++ b/src/bank-lib/bank_api_credit.c
@@ -1,6 +1,6 @@
/*
This file is part of TALER
- Copyright (C) 2017--2023 Taler Systems SA
+ Copyright (C) 2017--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
@@ -108,15 +108,16 @@ parse_account_history (struct TALER_BANK_CreditHistoryHandle *hh,
for (size_t i = 0; i<len; i++)
{
struct TALER_BANK_CreditDetails *td = &cd[i];
+ const char *type;
struct GNUNET_JSON_Specification hist_spec[] = {
+ GNUNET_JSON_spec_string ("type",
+ &type),
TALER_JSON_spec_amount_any ("amount",
&td->amount),
GNUNET_JSON_spec_timestamp ("date",
&td->execution_date),
GNUNET_JSON_spec_uint64 ("row_id",
&td->serial_id),
- GNUNET_JSON_spec_fixed_auto ("reserve_pub",
- &td->reserve_pub),
GNUNET_JSON_spec_string ("debit_account",
&td->debit_account_uri),
GNUNET_JSON_spec_end ()
@@ -133,6 +134,70 @@ parse_account_history (struct TALER_BANK_CreditHistoryHandle *hh,
GNUNET_break_op (0);
return GNUNET_SYSERR;
}
+ if (0 == strcasecmp ("RESERVE",
+ type))
+ {
+ struct GNUNET_JSON_Specification reserve_spec[] = {
+ GNUNET_JSON_spec_fixed_auto ("reserve_pub",
+ &td->details.reserve.reserve_pub),
+ GNUNET_JSON_spec_end ()
+ };
+
+ if (GNUNET_OK !=
+ GNUNET_JSON_parse (transaction,
+ reserve_spec,
+ NULL,
+ NULL))
+ {
+ GNUNET_break_op (0);
+ return GNUNET_SYSERR;
+ }
+ }
+ else if (0 == strcasecmp ("KYCAUTH",
+ type))
+ {
+ struct GNUNET_JSON_Specification kycauth_spec[] = {
+ GNUNET_JSON_spec_fixed_auto ("account_pub",
+ &td->details.kycauth.account_pub),
+ GNUNET_JSON_spec_end ()
+ };
+
+ if (GNUNET_OK !=
+ GNUNET_JSON_parse (transaction,
+ kycauth_spec,
+ NULL,
+ NULL))
+ {
+ GNUNET_break_op (0);
+ return GNUNET_SYSERR;
+ }
+ }
+ else if (0 == strcasecmp ("WAD",
+ type))
+ {
+ struct GNUNET_JSON_Specification wad_spec[] = {
+ GNUNET_JSON_spec_string ("origin_exchange_url",
+ &td->details.wad.origin_exchange_url),
+ GNUNET_JSON_spec_fixed_auto ("wad_id",
+ &td->details.wad.wad_id),
+ GNUNET_JSON_spec_end ()
+ };
+
+ if (GNUNET_OK !=
+ GNUNET_JSON_parse (transaction,
+ wad_spec,
+ NULL,
+ NULL))
+ {
+ GNUNET_break_op (0);
+ return GNUNET_SYSERR;
+ }
+ }
+ else
+ {
+ GNUNET_break_op (0);
+ return GNUNET_SYSERR;
+ }
}
chr.details.ok.details_length = len;
chr.details.ok.details = cd;
diff --git a/src/bank-lib/taler-exchange-wire-gateway-client.c b/src/bank-lib/taler-exchange-wire-gateway-client.c
index b0d387b71..81b63401c 100644
--- a/src/bank-lib/taler-exchange-wire-gateway-client.c
+++ b/src/bank-lib/taler-exchange-wire-gateway-client.c
@@ -193,14 +193,31 @@ credit_history_cb (void *cls,
(0 != strcasecmp (debit_account,
cd->debit_account_uri) ) )
continue;
- fprintf (stdout,
- "%llu: %s->%s (%s) over %s at %s\n",
- (unsigned long long) cd->serial_id,
- cd->debit_account_uri,
- reply->details.ok.credit_account_uri,
- TALER_B2S (&cd->reserve_pub),
- TALER_amount2s (&cd->amount),
- GNUNET_TIME_timestamp2s (cd->execution_date));
+ switch (cd->type)
+ {
+ case TALER_BANK_CT_RESERVE:
+ fprintf (stdout,
+ "%llu: %s->%s (%s) over %s at %s\n",
+ (unsigned long long) cd->serial_id,
+ cd->debit_account_uri,
+ reply->details.ok.credit_account_uri,
+ TALER_B2S (&cd->details.reserve.reserve_pub),
+ TALER_amount2s (&cd->amount),
+ GNUNET_TIME_timestamp2s (cd->execution_date));
+ break;
+ case TALER_BANK_CT_KYCAUTH:
+ fprintf (stdout,
+ "%llu: %s->%s (KYC:%s) over %s at %s\n",
+ (unsigned long long) cd->serial_id,
+ cd->debit_account_uri,
+ reply->details.ok.credit_account_uri,
+ TALER_B2S (&cd->details.kycauth.account_pub),
+ TALER_amount2s (&cd->amount),
+ GNUNET_TIME_timestamp2s (cd->execution_date));
+ case TALER_BANK_CT_WAD:
+ GNUNET_break (0); // FIXME
+ break;
+ }
}
global_ret = 0;
break;
diff --git a/src/exchange/taler-exchange-wirewatch.c b/src/exchange/taler-exchange-wirewatch.c
index da5d9c098..12aebbcae 100644
--- a/src/exchange/taler-exchange-wirewatch.c
+++ b/src/exchange/taler-exchange-wirewatch.c
@@ -563,6 +563,7 @@ process_reply (const struct TALER_BANK_CreditDetails *details,
{
enum GNUNET_DB_QueryStatus qss[details_length];
struct TALER_EXCHANGEDB_ReserveInInfo reserves[details_length];
+ unsigned int j = 0;
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Importing %u transactions\n",
@@ -570,39 +571,107 @@ process_reply (const struct TALER_BANK_CreditDetails *details,
for (unsigned int i = 0; i<details_length; i++)
{
const struct TALER_BANK_CreditDetails *cd = &details[i];
- struct TALER_EXCHANGEDB_ReserveInInfo *res = &reserves[i];
-
- res->reserve_pub = &cd->reserve_pub;
- res->balance = &cd->amount;
- res->execution_time = cd->execution_date;
- res->sender_account_details = cd->debit_account_uri;
- res->exchange_account_name = ai->section_name;
- res->wire_reference = cd->serial_id;
+
+ switch (cd->type)
+ {
+ case TALER_BANK_CT_RESERVE:
+ {
+ struct TALER_EXCHANGEDB_ReserveInInfo *res = &reserves[j++];
+
+ /* add to batch, do later */
+ res->reserve_pub = &cd->details.reserve.reserve_pub;
+ res->balance = &cd->amount;
+ res->execution_time = cd->execution_date;
+ res->sender_account_details = cd->debit_account_uri;
+ res->exchange_account_name = ai->section_name;
+ res->wire_reference = cd->serial_id;
+ }
+ break;
+ case TALER_BANK_CT_KYCAUTH:
+ {
+ qs = db_plugin->kycauth_in_insert (
+ db_plugin->cls,
+ &cd->details.kycauth.account_pub,
+ cd->execution_date,
+ cd->debit_account_uri,
+ ai->section_name,
+ cd->serial_id);
+ switch (qs)
+ {
+ case GNUNET_DB_STATUS_HARD_ERROR:
+ GNUNET_break (0);
+ GNUNET_SCHEDULER_shutdown ();
+ return;
+ case GNUNET_DB_STATUS_SOFT_ERROR:
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Got DB soft error for kycauth_in_insert (%u). Rolling back.\n",
+ i);
+ handle_soft_error ();
+ return;
+ default:
+ break;
+ }
+ break;
+ }
+ case TALER_BANK_CT_WAD:
+ {
+ qs = db_plugin->wad_in_insert (
+ db_plugin->cls,
+ &cd->details.wad.wad_id,
+ cd->details.wad.origin_exchange_url,
+ cd->execution_date,
+ cd->debit_account_uri,
+ ai->section_name,
+ cd->serial_id);
+ switch (qs)
+ {
+ case GNUNET_DB_STATUS_HARD_ERROR:
+ GNUNET_break (0);
+ GNUNET_SCHEDULER_shutdown ();
+ return;
+ case GNUNET_DB_STATUS_SOFT_ERROR:
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Got DB soft error for wad_in_insert (%u). Rolling back.\n",
+ i);
+ handle_soft_error ();
+ return;
+ default:
+ break;
+ }
+
+ }
+ }
}
- qs = db_plugin->reserves_in_insert (db_plugin->cls,
- reserves,
- details_length,
- qss);
- switch (qs)
+ if (j > 0)
{
- case GNUNET_DB_STATUS_HARD_ERROR:
- GNUNET_break (0);
- GNUNET_SCHEDULER_shutdown ();
- return;
- case GNUNET_DB_STATUS_SOFT_ERROR:
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Got DB soft error for reserves_in_insert (%u). Rolling back.\n",
- details_length);
- handle_soft_error ();
- return;
- default:
- break;
+ qs = db_plugin->reserves_in_insert (db_plugin->cls,
+ reserves,
+ j,
+ qss);
+ switch (qs)
+ {
+ case GNUNET_DB_STATUS_HARD_ERROR:
+ GNUNET_break (0);
+ GNUNET_SCHEDULER_shutdown ();
+ return;
+ case GNUNET_DB_STATUS_SOFT_ERROR:
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Got DB soft error for reserves_in_insert (%u). Rolling back.\n",
+ details_length);
+ handle_soft_error ();
+ return;
+ default:
+ break;
+ }
}
+ j = 0;
for (unsigned int i = 0; i<details_length; i++)
{
const struct TALER_BANK_CreditDetails *cd = &details[i];
- switch (qss[i])
+ if (TALER_BANK_CT_RESERVE != cd->type)
+ continue;
+ switch (qss[j++])
{
case GNUNET_DB_STATUS_HARD_ERROR:
GNUNET_break (0);
diff --git a/src/include/taler_bank_service.h b/src/include/taler_bank_service.h
index e8e32947b..5cf7d8ca9 100644
--- a/src/include/taler_bank_service.h
+++ b/src/include/taler_bank_service.h
@@ -1,6 +1,6 @@
/*
This file is part of TALER
- Copyright (C) 2015-2021 Taler Systems SA
+ Copyright (C) 2015-2024 Taler Systems SA
TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU Affero General Public License as published by the Free Software
@@ -27,6 +27,11 @@
#include "taler_util.h"
#include "taler_error_codes.h"
+/**
+ * Version of the Bank API, in hex.
+ * Thus 0.12.0-0 = 0x000C0000.
+ */
+#define TALER_BANK_SERVICE_API_VERSION 0x000C0000
/**
* Authentication method types.
@@ -163,8 +168,7 @@ typedef void
/**
* Perform a wire transfer from some account to the exchange to fill a
* reserve. Note that this API is usually only used for testing (with
- * fakebank and our Python bank) and thus may not be accessible in a
- * production setting.
+ * fakebank) and thus may not be accessible in a production setting.
*
* @param ctx curl context for the event loop
* @param auth authentication data to send to the bank
@@ -192,13 +196,119 @@ TALER_BANK_admin_add_incoming (
* Cancel an add incoming operation. This function cannot be used on a
* request handle if a response is already served for it.
*
- * @param aai the admin add incoming request handle
+ * @param[in] aai the admin add incoming request handle
*/
void
TALER_BANK_admin_add_incoming_cancel (
struct TALER_BANK_AdminAddIncomingHandle *aai);
+/**
+ * @brief A /admin/add-kycauth Handle
+ */
+struct TALER_BANK_AdminAddKycauthHandle;
+
+
+/**
+ * Response details for a history request.
+ */
+struct TALER_BANK_AdminAddKycauthResponse
+{
+
+ /**
+ * HTTP status.
+ */
+ unsigned int http_status;
+
+ /**
+ * Taler error code, #TALER_EC_NONE on success.
+ */
+ enum TALER_ErrorCode ec;
+
+ /**
+ * Full response, NULL if body was not in JSON format.
+ */
+ const json_t *response;
+
+ /**
+ * Details returned depending on the @e http_status.
+ */
+ union
+ {
+
+ /**
+ * Details if status was #MHD_HTTP_OK
+ */
+ struct
+ {
+ /**
+ * unique ID of the wire transfer in the bank's records
+ */
+ uint64_t serial_id;
+
+ /**
+ * time when the transaction was made.
+ */
+ struct GNUNET_TIME_Timestamp timestamp;
+
+ } ok;
+
+ } details;
+
+};
+
+/**
+ * Callbacks of this type are used to return the result of submitting
+ * a request to transfer funds to the exchange.
+ *
+ * @param cls closure
+ * @param air response details
+ */
+typedef void
+(*TALER_BANK_AdminAddKycauthCallback) (
+ void *cls,
+ const struct TALER_BANK_AdminAddKycauthResponse *air);
+
+
+/**
+ * Perform a wire transfer from some account to the exchange to register a
+ * public key for KYC authentication of the origin account. Note that this
+ * API is usually only used for testing (with fakebank) and thus may not be
+ * accessible in a production setting.
+ *
+ * @param ctx curl context for the event loop
+ * @param auth authentication data to send to the bank
+ * @param account_pub wire transfer subject for the transfer
+ * @param amount amount that is to be deposited
+ * @param debit_account account to deposit from (payto URI, but used as 'payfrom')
+ * @param res_cb the callback to call when the final result for this request is available
+ * @param res_cb_cls closure for the above callback
+ * @return NULL
+ * if the inputs are invalid (i.e. invalid amount) or internal errors.
+ * In this case, the callback is not called.
+ */
+struct TALER_BANK_AdminAddKycauthHandle *
+TALER_BANK_admin_add_kycauth (
+ struct GNUNET_CURL_Context *ctx,
+ const struct TALER_BANK_AuthenticationData *auth,
+ const union TALER_AccountPublicKeyP *account_pub,
+ const struct TALER_Amount *amount,
+ const char *debit_account,
+ TALER_BANK_AdminAddKycauthCallback res_cb,
+ void *res_cb_cls);
+
+
+/**
+ * Cancel an add kycauth operation. This function cannot be used on a
+ * request handle if a response is already served for it.
+ *
+ * @param[in] aai the admin add kycauth request handle
+ */
+void
+TALER_BANK_admin_add_kycauth_cancel (
+ struct TALER_BANK_AdminAddKycauthHandle *aai);
+
+
/* ********************* /transfer *********************** */
/**
@@ -302,12 +412,13 @@ typedef void
* @return NULL on error
*/
struct TALER_BANK_TransferHandle *
-TALER_BANK_transfer (struct GNUNET_CURL_Context *ctx,
- const struct TALER_BANK_AuthenticationData *auth,
- const void *buf,
- size_t buf_size,
- TALER_BANK_TransferCallback cc,
- void *cc_cls);
+TALER_BANK_transfer (
+ struct GNUNET_CURL_Context *ctx,
+ const struct TALER_BANK_AuthenticationData *auth,
+ const void *buf,
+ size_t buf_size,
+ TALER_BANK_TransferCallback cc,
+ void *cc_cls);
/**
@@ -323,15 +434,40 @@ TALER_BANK_transfer (struct GNUNET_CURL_Context *ctx,
* This function cannot be used on a request handle if a response is already
* served for it.
*
- * @param th handle of the wire transfer request to cancel
+ * @param[in] th handle of the wire transfer request to cancel
*/
void
-TALER_BANK_transfer_cancel (struct TALER_BANK_TransferHandle *th);
+TALER_BANK_transfer_cancel (
+ struct TALER_BANK_TransferHandle *th);
/* ********************* /history/incoming *********************** */
/**
+ * Different types of wire transfers that might be
+ * credited to an exchange account.
+ */
+enum TALER_BANK_CreditType
+{
+ /**
+ * Common wire transfer into a reserve account.
+ */
+ TALER_BANK_CT_RESERVE,
+
+ /**
+ * KYC authentication wire transfer with an account
+ * public key.
+ */
+ TALER_BANK_CT_KYCAUTH,
+
+ /**
+ * WAD transfer between exchanges.
+ */
+ TALER_BANK_CT_WAD
+
+};
+
+/**
* Handle for querying the bank for transactions
* made to the exchange.
*/
@@ -342,6 +478,12 @@ struct TALER_BANK_CreditHistoryHandle;
*/
struct TALER_BANK_CreditDetails
{
+
+ /**
+ * Type of the wire transfer.
+ */
+ enum TALER_BANK_CreditType type;
+
/**
* Serial ID of the wire transfer.
*/
@@ -358,14 +500,61 @@ struct TALER_BANK_CreditDetails
struct GNUNET_TIME_Timestamp execution_date;
/**
- * Reserve public key encoded in the wire transfer subject.
+ * payto://-URL of the source account that send the funds.
*/
- struct TALER_ReservePublicKeyP reserve_pub;
+ const char *debit_account_uri;
/**
- * payto://-URL of the source account that send the funds.
+ * Details that depend on the @e type.
*/
- const char *debit_account_uri;
+ union
+ {
+
+ /**
+ * Details for @e type #TALER_BANK_CT_RESERVE.
+ */
+ struct
+ {
+
+ /**
+ * Reserve public key encoded in the wire transfer subject.
+ */
+ struct TALER_ReservePublicKeyP reserve_pub;
+
+ } reserve;
+
+ /**
+ * Details for @e type #TALER_BANK_CT_KYCAUTH.
+ */
+ struct
+ {
+
+ /**
+ * Public key to associate with the owner of the
+ * origin bank account.
+ */
+ union TALER_AccountPublicKeyP account_pub;
+
+ } kycauth;
+
+ /**
+ * Details for @e type #TALER_BANK_CT_WAD.
+ */
+ struct
+ {
+
+ /**
+ * WAD identifier for the transfer.
+ */
+ struct TALER_WadIdentifierP wad_id;
+
+ /**
+ * Base URL of the exchange originating the transfer.
+ */
+ const char *origin_exchange_url;
+ } wad;
+
+ } details;
};
@@ -473,10 +662,11 @@ TALER_BANK_credit_history (
* handle if the last response (anything with a status code other than
* 200) is already served for it.
*
- * @param hh the history request handle
+ * @param[in] hh the history request handle
*/
void
-TALER_BANK_credit_history_cancel (struct TALER_BANK_CreditHistoryHandle *hh);
+TALER_BANK_credit_history_cancel (
+ struct TALER_BANK_CreditHistoryHandle *hh);
/* ********************* /history/outgoing *********************** */
@@ -614,13 +804,14 @@ typedef void
* In this case, the callback is not called.
*/
struct TALER_BANK_DebitHistoryHandle *
-TALER_BANK_debit_history (struct GNUNET_CURL_Context *ctx,
- const struct TALER_BANK_AuthenticationData *auth,
- uint64_t start_row,
- int64_t num_results,
- struct GNUNET_TIME_Relative timeout,
- TALER_BANK_DebitHistoryCallback hres_cb,
- void *hres_cb_cls);
+TALER_BANK_debit_history (
+ struct GNUNET_CURL_Context *ctx,
+ const struct TALER_BANK_AuthenticationData *auth,
+ uint64_t start_row,
+ int64_t num_results,
+ struct GNUNET_TIME_Relative timeout,
+ TALER_BANK_DebitHistoryCallback hres_cb,
+ void *hres_cb_cls);
/**
@@ -628,10 +819,11 @@ TALER_BANK_debit_history (struct GNUNET_CURL_Context *ctx,
* handle if the last response (anything with a status code other than
* 200) is already served for it.
*
- * @param hh the history request handle
+ * @param[in] hh the history request handle
*/
void
-TALER_BANK_debit_history_cancel (struct TALER_BANK_DebitHistoryHandle *hh);
+TALER_BANK_debit_history_cancel (
+ struct TALER_BANK_DebitHistoryHandle *hh);
/* ******************** Convenience functions **************** */
@@ -647,19 +839,21 @@ TALER_BANK_debit_history_cancel (struct TALER_BANK_DebitHistoryHandle *hh);
* @return #GNUNET_OK on success
*/
enum GNUNET_GenericReturnValue
-TALER_BANK_auth_parse_cfg (const struct GNUNET_CONFIGURATION_Handle *cfg,
- const char *section,
- struct TALER_BANK_AuthenticationData *auth);
+TALER_BANK_auth_parse_cfg (
+ const struct GNUNET_CONFIGURATION_Handle *cfg,
+ const char *section,
+ struct TALER_BANK_AuthenticationData *auth);
/**
* Free memory inside of @a auth (but not @a auth itself).
* Dual to #TALER_BANK_auth_parse_cfg().
*
- * @param auth authentication data to free
+ * @param[in,out] auth authentication data to free
*/
void
-TALER_BANK_auth_free (struct TALER_BANK_AuthenticationData *auth);
+TALER_BANK_auth_free (
+ struct TALER_BANK_AuthenticationData *auth);
#endif /* _TALER_BANK_SERVICE_H */
diff --git a/src/include/taler_exchangedb_plugin.h b/src/include/taler_exchangedb_plugin.h
index 98cf36569..0594461d0 100644
--- a/src/include/taler_exchangedb_plugin.h
+++ b/src/include/taler_exchangedb_plugin.h
@@ -3891,6 +3891,50 @@ struct TALER_EXCHANGEDB_Plugin
/**
+ * Insert an incoming KCYAUTH wire transfer into
+ * the database and update the authentication key
+ * for the origin account.
+ *
+ * @param cls the @e cls of this struct with the plugin-specific state
+ * @param account_pub public key of the account
+ * @param execution_date when was the transfer made
+ * @param debit_account_uri URI of the debit account
+ * @param section_name section of the exchange bank account that received the transfer
+ * @param serial_id bank-specific row identifying the transfer
+ */
+ enum GNUNET_DB_QueryStatus
+ (*kycauth_in_insert)(
+ void *cls,
+ const union TALER_AccountPublicKeyP *account_pub,
+ struct GNUNET_TIME_Timestamp execution_date,
+ const char *debit_account_uri,
+ const char *section_name,
+ uint64_t serial_id);
+
+
+ /**
+ * Insert an incoming WAD wire transfer into the database.
+ *
+ * @param cls the @e cls of this struct with the plugin-specific state
+ * @param wad_id WAD identifier
+ * @param origin_exchange_url exchange base URL originating the transfer
+ * @param execution_date when was the transfer made
+ * @param debit_account_uri URI of the debit account
+ * @param section_name section of the exchange bank account that received the transfer
+ * @param serial_id bank-specific row identifying the transfer
+ */
+ enum GNUNET_DB_QueryStatus
+ (*wad_in_insert)(
+ void *cls,
+ const struct TALER_WadIdentifierP *wad_id,
+ const char *origin_exchange_url,
+ struct GNUNET_TIME_Timestamp execution_date,
+ const char *debit_account_uri,
+ const char *section_name,
+ uint64_t serial_id);
+
+
+ /**
* Locate a nonce for use with a particular public key.
*
* @param cls the @e cls of this struct with the plugin-specific state
diff --git a/src/testing/testing_api_cmd_bank_history_credit.c b/src/testing/testing_api_cmd_bank_history_credit.c
index 956e6c857..81b538b2a 100644
--- a/src/testing/testing_api_cmd_bank_history_credit.c
+++ b/src/testing/testing_api_cmd_bank_history_credit.c
@@ -1,6 +1,6 @@
/*
This file is part of TALER
- Copyright (C) 2018-2021 Taler Systems SA
+ Copyright (C) 2018-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
@@ -41,7 +41,7 @@ struct History
/**
* Wire details.
*/
- struct TALER_BANK_CreditDetails details;
+ struct TALER_BANK_CreditDetails credit_details;
/**
* Serial ID of the wire transfer.
@@ -136,14 +136,42 @@ print_expected (struct History *h,
"Expected history:\n");
for (unsigned int i = 0; i<h_len; i++)
{
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "H(%u): %s (serial: %llu, subject: %s,"
- " counterpart: %s)\n",
- i,
- TALER_amount2s (&h[i].details.amount),
- (unsigned long long) h[i].row_id,
- TALER_B2S (&h[i].details.reserve_pub),
- h[i].details.debit_account_uri);
+ const struct TALER_BANK_CreditDetails *cd = &h[i].credit_details;
+
+ switch (cd->type)
+ {
+ case TALER_BANK_CT_RESERVE:
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "H(%u): %s (serial: %llu, RES: %s,"
+ " counterpart: %s)\n",
+ i,
+ TALER_amount2s (&cd->amount),
+ (unsigned long long) h[i].row_id,
+ TALER_B2S (&cd->details.reserve.reserve_pub),
+ cd->debit_account_uri);
+ break;
+ case TALER_BANK_CT_KYCAUTH:
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "H(%u): %s (serial: %llu, KYC: %s,"
+ " counterpart: %s)\n",
+ i,
+ TALER_amount2s (&cd->amount),
+ (unsigned long long) h[i].row_id,
+ TALER_B2S (&cd->details.kycauth.account_pub),
+ cd->debit_account_uri);
+ break;
+ case TALER_BANK_CT_WAD:
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "H(%u): %s (serial: %llu, WAD: %s-%s,"
+ " counterpart: %s)\n",
+ i,
+ TALER_amount2s (&cd->amount),
+ (unsigned long long) h[i].row_id,
+ TALER_B2S (&cd->details.wad.wad_id),
+ cd->details.wad.origin_exchange_url,
+ cd->debit_account_uri);
+ break;
+ }
}
}
@@ -233,6 +261,8 @@ command_cb (void *cls,
cmd,
&exchange_credit_url)) )
return; // Not an interesting event
+ // FIXME: support KYCAUTH transfer events!
+ // FIXME: support WAD transfer events!
/**
* Is the interesting event a match with regard to
@@ -272,10 +302,11 @@ command_cb (void *cls,
ic->total,
ic->pos * 2);
ic->h[ic->pos].url = GNUNET_strdup (debit_account);
- ic->h[ic->pos].details.debit_account_uri = ic->h[ic->pos].url;
- ic->h[ic->pos].details.amount = *amount;
ic->h[ic->pos].row_id = *row_id;
- ic->h[ic->pos].details.reserve_pub = *reserve_pub;
+ ic->h[ic->pos].credit_details.type = TALER_BANK_CT_RESERVE;
+ ic->h[ic->pos].credit_details.debit_account_uri = ic->h[ic->pos].url;
+ ic->h[ic->pos].credit_details.amount = *amount;
+ ic->h[ic->pos].credit_details.details.reserve.reserve_pub = *reserve_pub;
ic->pos++;
}
@@ -409,14 +440,14 @@ normalize (const char *in)
* @param total length of @a h
* @param off the offset (of the CMD list) where the command
* to check is.
- * @param details the expected transaction details.
+ * @param credit_details the expected transaction details.
* @return #GNUNET_OK if the transaction is what we expect.
*/
static enum GNUNET_GenericReturnValue
check_result (struct History *h,
unsigned int total,
unsigned int off,
- const struct TALER_BANK_CreditDetails *details)
+ const struct TALER_BANK_CreditDetails *credit_details)
{
char *u1;
char *u2;
@@ -433,33 +464,31 @@ check_result (struct History *h,
off);
return GNUNET_SYSERR;
}
- u1 = normalize (h[off].details.debit_account_uri);
+ u1 = normalize (h[off].credit_details.debit_account_uri);
if (NULL == u1)
return GNUNET_SYSERR;
- u2 = normalize (details->debit_account_uri);
+ u2 = normalize (credit_details->debit_account_uri);
if (NULL == u2)
{
GNUNET_free (u1);
return GNUNET_SYSERR;
}
- if ( (0 != GNUNET_memcmp (&h[off].details.reserve_pub,
- &details->reserve_pub)) ||
- (0 != TALER_amount_cmp (&h[off].details.amount,
- &details->amount)) ||
+ if ( (h[off].credit_details.type !=
+ credit_details->type) ||
+ (0 != TALER_amount_cmp (&h[off].credit_details.amount,
+ &credit_details->amount)) ||
(0 != strcasecmp (u1,
u2)) )
{
GNUNET_break (0);
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "expected debit_account_uri: %s with %s for %s\n",
+ "expected debit_account_uri: %s with %s\n",
u1,
- TALER_amount2s (&h[off].details.amount),
- TALER_B2S (&h[off].details.reserve_pub));
+ TALER_amount2s (&h[off].credit_details.amount));
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "actual debit_account_uri: %s with %s for %s\n",
+ "actual debit_account_uri: %s with %s\n",
u2,
- TALER_amount2s (&details->amount),
- TALER_B2S (&details->reserve_pub));
+ TALER_amount2s (&credit_details->amount));
print_expected (h,
total,
off);
@@ -467,6 +496,85 @@ check_result (struct History *h,
GNUNET_free (u2);
return GNUNET_SYSERR;
}
+ switch (credit_details->type)
+ {
+ case TALER_BANK_CT_RESERVE:
+ if (0 != GNUNET_memcmp (&h[off].credit_details.details.reserve.reserve_pub,
+ &credit_details->details.reserve.reserve_pub))
+ {
+ GNUNET_break (0);
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "expected debit_account_uri: %s with %s for %s\n",
+ u1,
+ TALER_amount2s (&h[off].credit_details.amount),
+ TALER_B2S (&h[off].credit_details.details.reserve.reserve_pub)
+ );
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "actual debit_account_uri: %s with %s for %s\n",
+ u2,
+ TALER_amount2s (&credit_details->amount),
+ TALER_B2S (&credit_details->details.reserve.reserve_pub));
+ print_expected (h,
+ total,
+ off);
+ GNUNET_free (u1);
+ GNUNET_free (u2);
+ return GNUNET_SYSERR;
+ }
+ break;
+ case TALER_BANK_CT_KYCAUTH:
+ if (0 != GNUNET_memcmp (&h[off].credit_details.details.kycauth.account_pub,
+ &credit_details->details.kycauth.account_pub))
+ {
+ GNUNET_break (0);
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "expected debit_account_uri: %s with %s for %s\n",
+ u1,
+ TALER_amount2s (&h[off].credit_details.amount),
+ TALER_B2S (&h[off].credit_details.details.kycauth.account_pub)
+ );
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "actual debit_account_uri: %s with %s for %s\n",
+ u2,
+ TALER_amount2s (&credit_details->amount),
+ TALER_B2S (&credit_details->details.kycauth.account_pub));
+ print_expected (h,
+ total,
+ off);
+ GNUNET_free (u1);
+ GNUNET_free (u2);
+ return GNUNET_SYSERR;
+ }
+ break;
+ case TALER_BANK_CT_WAD:
+ if ( (0 != GNUNET_memcmp (&h[off].credit_details.details.wad.wad_id,
+ &credit_details->details.wad.wad_id)) ||
+ (0 != strcmp (h[off].credit_details.details.wad.origin_exchange_url,
+ credit_details->details.wad.origin_exchange_url)) )
+ {
+ GNUNET_break (0);
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "expected debit_account_uri: %s with %s for %s-%s\n",
+ u1,
+ TALER_amount2s (&h[off].credit_details.amount),
+ h[off].credit_details.details.wad.origin_exchange_url,
+ TALER_B2S (&h[off].credit_details.details.wad.wad_id));
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "actual debit_account_uri: %s with %s for %s-%s\n",
+ u2,
+ TALER_amount2s (&credit_details->amount),
+ credit_details->details.wad.origin_exchange_url,
+ TALER_B2S (&credit_details->details.wad.wad_id));
+ print_expected (h,
+ total,
+ off);
+ GNUNET_free (u1);
+ GNUNET_free (u2);
+ return GNUNET_SYSERR;
+ }
+ break;
+ }
+
GNUNET_free (u1);
GNUNET_free (u2);
return GNUNET_OK;