summaryrefslogtreecommitdiff
path: root/src/exchange
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2020-01-11 15:19:56 +0100
committerChristian Grothoff <christian@grothoff.org>2020-01-11 15:20:17 +0100
commit9443c10d7feb0d91323869dd08ec61ca781564f4 (patch)
treefd617ea56cc1d2ea370ce7e5467574a536b52d28 /src/exchange
parent554da10133eb491b352a106b98ebeaed797133bb (diff)
downloadexchange-9443c10d7feb0d91323869dd08ec61ca781564f4.tar.gz
exchange-9443c10d7feb0d91323869dd08ec61ca781564f4.tar.bz2
exchange-9443c10d7feb0d91323869dd08ec61ca781564f4.zip
major refactoring, eliminating wire-plugins and moving towards new bank API. main code compiles, testcases known to fail, code sure not to fully work yet
Diffstat (limited to 'src/exchange')
-rw-r--r--src/exchange/Makefile.am5
-rw-r--r--src/exchange/taler-exchange-aggregator.c448
-rw-r--r--src/exchange/taler-exchange-httpd_deposit.c13
-rw-r--r--src/exchange/taler-exchange-httpd_validation.c142
-rw-r--r--src/exchange/taler-exchange-wirewatch.c271
5 files changed, 296 insertions, 583 deletions
diff --git a/src/exchange/Makefile.am b/src/exchange/Makefile.am
index 3453683ae..b08c85c6f 100644
--- a/src/exchange/Makefile.am
+++ b/src/exchange/Makefile.am
@@ -29,9 +29,11 @@ taler_exchange_aggregator_LDADD = \
$(LIBGCRYPT_LIBS) \
$(top_builddir)/src/json/libtalerjson.la \
$(top_builddir)/src/util/libtalerutil.la \
+ $(top_builddir)/src/bank-lib/libtalerbank.la \
$(top_builddir)/src/wire/libtalerwire.la \
$(top_builddir)/src/exchangedb/libtalerexchangedb.la \
-ljansson \
+ -lgnunetcurl \
-lgnunetutil
taler_exchange_wirewatch_SOURCES = \
@@ -40,9 +42,11 @@ taler_exchange_wirewatch_LDADD = \
$(LIBGCRYPT_LIBS) \
$(top_builddir)/src/json/libtalerjson.la \
$(top_builddir)/src/util/libtalerutil.la \
+ $(top_builddir)/src/bank-lib/libtalerbank.la \
$(top_builddir)/src/wire/libtalerwire.la \
$(top_builddir)/src/exchangedb/libtalerexchangedb.la \
-ljansson \
+ -lgnunetcurl \
-lgnunetutil
taler_exchange_httpd_SOURCES = \
@@ -66,6 +70,7 @@ taler_exchange_httpd_SOURCES = \
taler-exchange-httpd_validation.c taler-exchange-httpd_validation.h
taler_exchange_httpd_LDADD = \
$(LIBGCRYPT_LIBS) \
+ $(top_builddir)/src/bank-lib/libtalerbank.la \
$(top_builddir)/src/wire/libtalerwire.la \
$(top_builddir)/src/mhd/libtalermhd.la \
$(top_builddir)/src/json/libtalerjson.la \
diff --git a/src/exchange/taler-exchange-aggregator.c b/src/exchange/taler-exchange-aggregator.c
index 71a3efd7d..2704f5910 100644
--- a/src/exchange/taler-exchange-aggregator.c
+++ b/src/exchange/taler-exchange-aggregator.c
@@ -1,6 +1,6 @@
/*
This file is part of TALER
- Copyright (C) 2016-2018 Taler Systems SA
+ Copyright (C) 2016-2020 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
@@ -26,6 +26,7 @@
#include "taler_exchangedb_lib.h"
#include "taler_exchangedb_plugin.h"
#include "taler_json_lib.h"
+#include "taler_bank_service.h"
#include "taler_wire_lib.h"
@@ -45,9 +46,14 @@ struct WireAccount
struct WireAccount *prev;
/**
- * Handle to the plugin.
+ * Account information.
*/
- struct TALER_WIRE_Plugin *wire_plugin;
+ struct TALER_Account account;
+
+ /**
+ * Authentication data.
+ */
+ struct TALER_BANK_AuthenticationData auth;
/**
* Wire transfer fee structure.
@@ -59,6 +65,11 @@ struct WireAccount
*/
char *section_name;
+ /**
+ * Name of the wire method underlying the account.
+ */
+ char *method;
+
};
@@ -77,7 +88,7 @@ struct WirePrepareData
/**
* Wire execution handle.
*/
- struct TALER_WIRE_ExecuteHandle *eh;
+ struct TALER_BANK_WireExecuteHandle *eh;
/**
* Wire plugin used for this preparation.
@@ -187,10 +198,6 @@ struct AggregationUnit
*/
struct CloseTransferContext
{
- /**
- * Handle for preparing the wire transfer.
- */
- struct TALER_WIRE_PrepareHandle *ph;
/**
* Our database session.
@@ -263,6 +270,16 @@ static struct WirePrepareData *wpd;
static struct AggregationUnit *au;
/**
+ * Handle to the context for interacting with the bank.
+ */
+static struct GNUNET_CURL_Context *ctx;
+
+/**
+ * Scheduler context for running the @e ctx.
+ */
+static struct GNUNET_CURL_RescheduleContext *rc;
+
+/**
* Value to return from main(). #GNUNET_OK on success, #GNUNET_SYSERR
* on serious errors.
*/
@@ -339,7 +356,7 @@ update_fees (struct WireAccount *wa,
return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
/* Let's try to load it from disk... */
wa->af = TALER_EXCHANGEDB_fees_read (cfg,
- wa->wire_plugin->method);
+ wa->method);
advance_fees (wa,
now);
for (struct TALER_EXCHANGEDB_AggregateFees *p = wa->af;
@@ -348,7 +365,7 @@ update_fees (struct WireAccount *wa,
{
qs = db_plugin->insert_wire_fee (db_plugin->cls,
session,
- wa->wire_plugin->method,
+ wa->method,
p->start_date,
p->end_date,
&p->wire_fee,
@@ -365,7 +382,7 @@ update_fees (struct WireAccount *wa,
return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Failed to find current wire transfer fees for `%s'\n",
- wa->wire_plugin->method);
+ wa->method);
return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS;
}
@@ -381,7 +398,7 @@ find_account_by_method (const char *method)
{
for (struct WireAccount *wa = wa_head; NULL != wa; wa = wa->next)
if (0 == strcmp (method,
- wa->wire_plugin->method))
+ wa->method))
return wa;
return NULL;
}
@@ -431,13 +448,40 @@ add_account_cb (void *cls,
if (GNUNET_YES != ai->debit_enabled)
return; /* not enabled for us, skip */
wa = GNUNET_new (struct WireAccount);
- wa->wire_plugin = TALER_WIRE_plugin_load (cfg,
- ai->plugin_name);
- if (NULL == wa->wire_plugin)
+ if (GNUNET_OK !=
+ GNUNET_CONFIGURATION_get_value_string (cfg,
+ ai->section_name,
+ "METHOD",
+ &wa->method))
{
- fprintf (stderr,
- "Failed to load wire plugin for `%s'\n",
- ai->plugin_name);
+ GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
+ ai->section_name,
+ "METHOD");
+ GNUNET_free (wa);
+ return;
+ }
+ if (GNUNET_OK !=
+ TALER_BANK_auth_parse_cfg (cfg,
+ ai->section_name,
+ &wa->auth))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
+ "Failed to load account `%s'\n",
+ ai->section_name);
+ GNUNET_free (wa->method);
+ GNUNET_free (wa);
+ return;
+ }
+ if (GNUNET_OK !=
+ TALER_BANK_account_parse_cfg (cfg,
+ ai->section_name,
+ &wa->account))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
+ "Failed to load account `%s'\n",
+ ai->section_name);
+ TALER_BANK_auth_free (&wa->auth);
+ GNUNET_free (wa->method);
GNUNET_free (wa);
return;
}
@@ -476,6 +520,16 @@ static void
shutdown_task (void *cls)
{
(void) cls;
+ if (NULL != ctx)
+ {
+ GNUNET_CURL_fini (ctx);
+ ctx = NULL;
+ }
+ if (NULL != rc)
+ {
+ GNUNET_CURL_gnunet_rc_destroy (rc);
+ rc = NULL;
+ }
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Running shutdown\n");
if (NULL != task)
@@ -487,9 +541,7 @@ shutdown_task (void *cls)
{
if (NULL != wpd->eh)
{
- wpd->wa->wire_plugin->execute_wire_transfer_cancel (
- wpd->wa->wire_plugin->cls,
- wpd->eh);
+ TALER_BANK_execute_wire_transfer_cancel (wpd->eh);
wpd->eh = NULL;
}
db_plugin->rollback (db_plugin->cls,
@@ -499,23 +551,12 @@ shutdown_task (void *cls)
}
if (NULL != au)
{
- if (NULL != au->ph)
- {
- au->wa->wire_plugin->prepare_wire_transfer_cancel (
- au->wa->wire_plugin->cls,
- au->ph);
- au->ph = NULL;
- }
db_plugin->rollback (db_plugin->cls,
au->session);
cleanup_au ();
}
if (NULL != ctc)
{
- ctc->wa->wire_plugin->prepare_wire_transfer_cancel (
- ctc->wa->wire_plugin->cls,
- ctc->ph);
- ctc->ph = NULL;
db_plugin->rollback (db_plugin->cls,
ctc->session);
GNUNET_free (ctc->method);
@@ -532,9 +573,11 @@ shutdown_task (void *cls)
GNUNET_CONTAINER_DLL_remove (wa_head,
wa_tail,
wa);
- TALER_WIRE_plugin_unload (wa->wire_plugin);
+ TALER_WIRE_account_free (&wa->account);
+ TALER_BANK_auth_free (&wa->auth);
TALER_EXCHANGEDB_fees_free (wa->af);
GNUNET_free (wa->section_name);
+ GNUNET_free (wa->method);
GNUNET_free (wa);
}
}
@@ -922,20 +965,6 @@ aggregate_cb (void *cls,
/**
- * Function to be called with the prepared transfer data
- * when running an aggregation on a merchant.
- *
- * @param cls closure with the `struct AggregationUnit`
- * @param buf transaction data to persist, NULL on error
- * @param buf_size number of bytes in @a buf, 0 on error
- */
-static void
-prepare_cb (void *cls,
- const char *buf,
- size_t buf_size);
-
-
-/**
* Main work function that finds and triggers transfers for reserves
* closures.
*
@@ -989,83 +1018,6 @@ commit_or_warn (struct TALER_EXCHANGEDB_Session *session)
/**
- * Function to be called with the prepared transfer data
- * when closing a reserve.
- *
- * @param cls closure with a `struct CloseTransferContext`
- * @param buf transaction data to persist, NULL on error
- * @param buf_size number of bytes in @a buf, 0 on error
- */
-static void
-prepare_close_cb (void *cls,
- const char *buf,
- size_t buf_size)
-{
- enum GNUNET_DB_QueryStatus qs;
-
- GNUNET_assert (cls == ctc);
-
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Prepared for reserve closing\n");
- ctc->ph = NULL;
- if (NULL == buf)
- {
- GNUNET_break (0); /* why? how to best recover? */
- db_plugin->rollback (db_plugin->cls,
- ctc->session);
- /* start again */
- GNUNET_free (ctc->method);
- GNUNET_free (ctc);
- ctc = NULL;
- task = GNUNET_SCHEDULER_add_now (&run_aggregation,
- NULL);
- return;
- }
-
- /* Commit our intention to execute the wire transfer! */
- qs = db_plugin->wire_prepare_data_insert (db_plugin->cls,
- ctc->session,
- ctc->method,
- buf,
- buf_size);
- if (GNUNET_DB_STATUS_HARD_ERROR == qs)
- {
- GNUNET_break (0);
- db_plugin->rollback (db_plugin->cls,
- ctc->session);
- global_ret = GNUNET_SYSERR;
- GNUNET_SCHEDULER_shutdown ();
- GNUNET_free (ctc->method);
- GNUNET_free (ctc);
- ctc = NULL;
- return;
- }
- if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
- {
- db_plugin->rollback (db_plugin->cls,
- ctc->session);
- /* start again */
- task = GNUNET_SCHEDULER_add_now (&run_aggregation,
- NULL);
- GNUNET_free (ctc->method);
- GNUNET_free (ctc);
- ctc = NULL;
- return;
- }
-
- /* finally commit */
- (void) commit_or_warn (ctc->session);
- GNUNET_free (ctc->method);
- GNUNET_free (ctc);
- ctc = NULL;
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Reserve closure committed, running transfer\n");
- task = GNUNET_SCHEDULER_add_now (&run_transfers,
- NULL);
-}
-
-
-/**
* Closure for #expired_reserve_cb().
*/
struct ExpiredReserveContext
@@ -1113,6 +1065,8 @@ expired_reserve_cb (void *cls,
int ret;
enum GNUNET_DB_QueryStatus qs;
struct WireAccount *wa;
+ void *buf;
+ size_t buf_size;
/* NOTE: potential optimization: use custom SQL API to not
fetch this: */
@@ -1121,7 +1075,7 @@ expired_reserve_cb (void *cls,
now = GNUNET_TIME_absolute_get ();
(void) GNUNET_TIME_round_abs (&now);
- /* lookup wire plugin */
+ /* lookup account we should use */
wa = find_account_by_url (account_details);
if (NULL == wa)
{
@@ -1161,6 +1115,18 @@ expired_reserve_cb (void *cls,
TALER_amount_get_zero (left->currency,
&amount_without_fee));
}
+ /* round down to enable transfer */
+ if (GNUNET_SYSERR ==
+ TALER_WIRE_amount_round (&amount_without_fee))
+ {
+ GNUNET_break (0);
+ global_ret = GNUNET_SYSERR;
+ GNUNET_SCHEDULER_shutdown ();
+ return GNUNET_DB_STATUS_HARD_ERROR;
+ }
+ if ( (0 == amount_without_fee.value) &&
+ (0 == amount_without_fee.fraction) )
+ ret = GNUNET_NO;
/* NOTE: sizeof (*reserve_pub) == sizeof (wtid) right now, but to
be future-compatible, we use the memset + min construction */
@@ -1171,61 +1137,23 @@ expired_reserve_cb (void *cls,
reserve_pub,
GNUNET_MIN (sizeof (wtid),
sizeof (*reserve_pub)));
-
- qs = db_plugin->insert_reserve_closed (db_plugin->cls,
- session,
- reserve_pub,
- now,
- account_details,
- &wtid,
- left,
- closing_fee);
-
+ if (GNUNET_SYSERR != ret)
+ qs = db_plugin->insert_reserve_closed (db_plugin->cls,
+ session,
+ reserve_pub,
+ now,
+ account_details,
+ &wtid,
+ left,
+ closing_fee);
+ else
+ ret = GNUNET_DB_STATUS_HARD_ERROR;
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Closing reserve %s over %s (%d, %d)\n",
TALER_B2S (reserve_pub),
TALER_amount2s (left),
ret,
qs);
- if ( (GNUNET_OK == ret) &&
- (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs) )
- {
- /* success, perform wire transfer */
- if (GNUNET_SYSERR ==
- wa->wire_plugin->amount_round (wa->wire_plugin->cls,
- &amount_without_fee))
- {
- GNUNET_break (0);
- global_ret = GNUNET_SYSERR;
- GNUNET_SCHEDULER_shutdown ();
- return GNUNET_DB_STATUS_HARD_ERROR;
- }
- ctc = GNUNET_new (struct CloseTransferContext);
- ctc->wa = wa;
- ctc->session = session;
- ctc->method = TALER_WIRE_payto_get_method (account_details);
- ctc->ph
- = wa->wire_plugin->prepare_wire_transfer (wa->wire_plugin->cls,
- wa->section_name,
- account_details,
- &amount_without_fee,
- exchange_base_url,
- &wtid,
- &prepare_close_cb,
- ctc);
- if (NULL == ctc->ph)
- {
- GNUNET_break (0);
- global_ret = GNUNET_SYSERR;
- GNUNET_SCHEDULER_shutdown ();
- GNUNET_free (ctc->method);
- GNUNET_free (ctc);
- ctc = NULL;
- return GNUNET_DB_STATUS_HARD_ERROR;
- }
- erc->async_cont = GNUNET_YES;
- return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
- }
/* Check for hard failure */
if ( (GNUNET_SYSERR == ret) ||
(GNUNET_DB_STATUS_HARD_ERROR == qs) )
@@ -1235,10 +1163,59 @@ expired_reserve_cb (void *cls,
GNUNET_SCHEDULER_shutdown ();
return GNUNET_DB_STATUS_HARD_ERROR;
}
- /* Reserve balance was almost zero OR soft error */
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Reserve was virtually empty, moving on\n");
- return qs;
+ if ( (GNUNET_OK != ret) ||
+ (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs) )
+ {
+ /* Reserve balance was almost zero OR soft error */
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Reserve was virtually empty, moving on\n");
+ (void) commit_or_warn (ctc->session);
+ GNUNET_free (ctc->method);
+ GNUNET_free (ctc);
+ ctc = NULL;
+ task = GNUNET_SCHEDULER_add_now (&run_transfers,
+ NULL);
+ return qs;
+ }
+
+ /* success, perform wire transfer */
+ ctc = GNUNET_new (struct CloseTransferContext);
+ ctc->wa = wa;
+ ctc->session = session;
+ ctc->method = TALER_WIRE_payto_get_method (account_details);
+ TALER_BANK_prepare_wire_transfer (account_details,
+ &amount_without_fee,
+ exchange_base_url,
+ &wtid,
+ &buf,
+ &buf_size);
+ /* Commit our intention to execute the wire transfer! */
+ qs = db_plugin->wire_prepare_data_insert (db_plugin->cls,
+ ctc->session,
+ ctc->method,
+ buf,
+ buf_size);
+ GNUNET_free (buf);
+ if (GNUNET_DB_STATUS_HARD_ERROR == qs)
+ {
+ GNUNET_break (0);
+ GNUNET_free (ctc->method);
+ GNUNET_free (ctc);
+ ctc = NULL;
+ return GNUNET_DB_STATUS_HARD_ERROR;
+ }
+ if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
+ {
+ /* start again */
+ GNUNET_free (ctc->method);
+ GNUNET_free (ctc);
+ ctc = NULL;
+ return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS;
+ }
+ erc->async_cont = GNUNET_YES;
+ task = GNUNET_SCHEDULER_add_now (&run_transfers,
+ NULL);
+ return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
}
@@ -1344,6 +1321,8 @@ run_aggregation (void *cls)
struct TALER_EXCHANGEDB_Session *session;
enum GNUNET_DB_QueryStatus qs;
const struct GNUNET_SCHEDULER_TaskContext *tc;
+ void *buf;
+ size_t buf_size;
(void) cls;
task = NULL;
@@ -1470,8 +1449,7 @@ run_aggregation (void *cls)
&au->total_amount,
&au->wire_fee)) ||
(GNUNET_SYSERR ==
- au->wa->wire_plugin->amount_round (au->wa->wire_plugin->cls,
- &au->final_amount)) ||
+ TALER_WIRE_amount_round (&au->final_amount)) ||
( (0 == au->final_amount.value) &&
(0 == au->final_amount.fraction) ) )
{
@@ -1555,70 +1533,26 @@ run_aggregation (void *cls)
char *url;
url = TALER_JSON_wire_to_payto (au->wire);
- au->ph = au->wa->wire_plugin->prepare_wire_transfer (
- au->wa->wire_plugin->cls,
- au->wa->section_name,
- url,
- &au->final_amount,
- exchange_base_url,
- &au->wtid,
- &prepare_cb,
- au);
+ TALER_BANK_prepare_wire_transfer (url,
+ &au->final_amount,
+ exchange_base_url,
+ &au->wtid,
+ &buf,
+ &buf_size);
GNUNET_free (url);
}
- if (NULL == au->ph)
- {
- /* something went very wrong, likely bad configuration,
- abort */
- db_plugin->rollback (db_plugin->cls,
- session);
- cleanup_au ();
- GNUNET_SCHEDULER_shutdown ();
- return;
- }
- /* otherwise we continue with #prepare_cb(), see below */
-}
-
-
-/**
- * Function to be called with the prepared transfer data.
- *
- * @param cls NULL
- * @param buf transaction data to persist, NULL on error
- * @param buf_size number of bytes in @a buf, 0 on error
- */
-static void
-prepare_cb (void *cls,
- const char *buf,
- size_t buf_size)
-{
- struct TALER_EXCHANGEDB_Session *session = au->session;
- enum GNUNET_DB_QueryStatus qs;
-
- (void) cls;
GNUNET_free_non_null (au->additional_rows);
au->additional_rows = NULL;
- if (NULL == buf)
- {
- GNUNET_break (0); /* why? how to best recover? */
- db_plugin->rollback (db_plugin->cls,
- session);
- /* start again */
- task = GNUNET_SCHEDULER_add_now (&run_aggregation,
- NULL);
- cleanup_au ();
- return;
- }
-
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Storing %u bytes of wire prepare data\n",
(unsigned int) buf_size);
/* Commit our intention to execute the wire transfer! */
qs = db_plugin->wire_prepare_data_insert (db_plugin->cls,
session,
- au->wa->wire_plugin->method,
+ au->wa->method,
buf,
buf_size);
+ GNUNET_free (buf);
/* Commit the WTID data to 'wire_out' to finally satisfy aggregation
table constraints */
if (qs >= 0)
@@ -1691,29 +1625,30 @@ prepare_cb (void *cls,
* Function called with the result from the execute step.
*
* @param cls NULL
- * @param success #GNUNET_OK on success, #GNUNET_SYSERR on failure
- * @param serial_id unique ID of the wire transfer in the bank's records; UINT64_MAX on error
- * @param emsg NULL on success, otherwise an error message
+ * @param http_status_code #MHD_HTTP_OK on success
+ * @param ec taler error code
+ * @param row_id unique ID of the wire transfer in the bank's records
+ * @param wire_timestamp when did the transfer happen
*/
static void
wire_confirm_cb (void *cls,
- int success,
- const void *row_id,
- size_t row_id_size,
- const char *emsg)
+ unsigned int http_status_code,
+ enum TALER_ErrorCode ec,
+ uint64_t row_id,
+ struct GNUNET_TIME_Absolute wire_timestamp)
{
struct TALER_EXCHANGEDB_Session *session = wpd->session;
enum GNUNET_DB_QueryStatus qs;
(void) cls;
(void) row_id;
- (void) row_id_size;
wpd->eh = NULL;
- if (GNUNET_SYSERR == success)
+ if (MHD_HTTP_OK != http_status_code)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Wire transaction failed: %s\n",
- emsg);
+ "Wire transaction failed: %u/%d\n",
+ http_status_code,
+ ec);
db_plugin->rollback (db_plugin->cls,
session);
global_ret = GNUNET_SYSERR;
@@ -1792,6 +1727,8 @@ wire_prepare_cb (void *cls,
const char *buf,
size_t buf_size)
{
+ struct WireAccount *wa;
+
(void) cls;
wpd->row_id = rowid;
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
@@ -1811,12 +1748,15 @@ wire_prepare_cb (void *cls,
wpd = NULL;
return;
}
- wpd->eh = wpd->wa->wire_plugin->execute_wire_transfer (
- wpd->wa->wire_plugin->cls,
- buf,
- buf_size,
- &wire_confirm_cb,
- NULL);
+ wa = wpd->wa;
+ wpd->eh = TALER_BANK_execute_wire_transfer (ctx,
+ wa->account.details.x_taler_bank.
+ account_base_url,
+ &wa->auth,
+ buf,
+ buf_size,
+ &wire_confirm_cb,
+ NULL);
if (NULL == wpd->eh)
{
GNUNET_break (0); /* why? how to best recover? */
@@ -1927,6 +1867,7 @@ run (void *cls,
(void) cls;
(void) args;
(void) cfgfile;
+
if (GNUNET_OK !=
GNUNET_CONFIGURATION_get_value_string (c,
"exchange",
@@ -1947,6 +1888,15 @@ run (void *cls,
global_ret = 1;
return;
}
+ ctx = GNUNET_CURL_init (&GNUNET_CURL_gnunet_scheduler_reschedule,
+ &rc);
+ rc = GNUNET_CURL_gnunet_rc_create (ctx);
+ if (NULL == ctx)
+ {
+ GNUNET_break (0);
+ return;
+ }
+
task = GNUNET_SCHEDULER_add_now (&run_transfers,
NULL);
GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
diff --git a/src/exchange/taler-exchange-httpd_deposit.c b/src/exchange/taler-exchange-httpd_deposit.c
index 024482389..96e30e437 100644
--- a/src/exchange/taler-exchange-httpd_deposit.c
+++ b/src/exchange/taler-exchange-httpd_deposit.c
@@ -400,7 +400,6 @@ TEH_DEPOSIT_handler_deposit (struct TEH_RequestHandler *rh,
json_t *json;
int res;
json_t *wire;
- char *emsg;
enum TALER_ErrorCode ec;
unsigned int hc;
struct TALER_EXCHANGEDB_Deposit deposit;
@@ -460,18 +459,6 @@ TEH_DEPOSIT_handler_deposit (struct TEH_RequestHandler *rh,
"refund_deadline");
}
- if (TALER_EC_NONE !=
- (ec = TEH_json_validate_wireformat (wire,
- &emsg)))
- {
- GNUNET_JSON_parse_free (spec);
- res = TALER_MHD_reply_with_error (connection,
- MHD_HTTP_BAD_REQUEST,
- ec,
- emsg);
- GNUNET_free (emsg);
- return res;
- }
if (GNUNET_OK !=
check_timestamp_current (deposit.timestamp))
{
diff --git a/src/exchange/taler-exchange-httpd_validation.c b/src/exchange/taler-exchange-httpd_validation.c
index 23dbbf249..d0371e930 100644
--- a/src/exchange/taler-exchange-httpd_validation.c
+++ b/src/exchange/taler-exchange-httpd_validation.c
@@ -1,6 +1,6 @@
/*
This file is part of TALER
- Copyright (C) 2016, 2017, 2018 Taler Systems SA
+ Copyright (C) 2016-2020 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
@@ -30,40 +30,6 @@
/**
- * Information we keep for each plugin.
- */
-struct Plugin
-{
-
- /**
- * We keep plugins in a DLL.
- */
- struct Plugin *next;
-
- /**
- * We keep plugins in a DLL.
- */
- struct Plugin *prev;
-
- /**
- * Pointer to the plugin.
- */
- struct TALER_WIRE_Plugin *plugin;
-
-};
-
-
-/**
- * Head of DLL of wire plugins.
- */
-static struct Plugin *wire_head;
-
-/**
- * Tail of DLL of wire plugins.
- */
-static struct Plugin *wire_tail;
-
-/**
* Array of wire methods supported by this exchange.
*/
static json_t *wire_accounts_array;
@@ -191,9 +157,8 @@ load_account (void *cls,
else
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Wire fees not specified for `%s', ignoring plugin %s\n",
- method,
- ai->plugin_name);
+ "Wire fees not specified for `%s'\n",
+ method);
*ret = GNUNET_SYSERR;
}
GNUNET_free (method);
@@ -201,35 +166,15 @@ load_account (void *cls,
if (GNUNET_YES == ai->debit_enabled)
{
- struct Plugin *p;
-
- p = GNUNET_new (struct Plugin);
- p->plugin = TALER_WIRE_plugin_load (cfg,
- ai->plugin_name);
- if (NULL == p->plugin)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Failed to load plugin %s\n",
- ai->plugin_name);
- GNUNET_free (p);
- *ret = GNUNET_SYSERR;
- return;
- }
if (GNUNET_OK !=
- load_fee (p->plugin->method))
+ load_fee (ai->method))
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Disabling plugin `%s' as wire transfer fees for `%s' are not given correctly\n",
- ai->plugin_name,
- p->plugin->method);
- TALER_WIRE_plugin_unload (p->plugin);
- GNUNET_free (p);
+ "Wire transfer fees for `%s' are not given correctly\n",
+ ai->method);
*ret = GNUNET_SYSERR;
return;
}
- GNUNET_CONTAINER_DLL_insert (wire_head,
- wire_tail,
- p);
}
}
@@ -251,12 +196,6 @@ TEH_VALIDATION_init (const struct GNUNET_CONFIGURATION_Handle *cfg)
TALER_EXCHANGEDB_find_accounts (cfg,
&load_account,
&ret);
- if (NULL == wire_head)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Failed to find properly configured wire transfer method\n");
- ret = GNUNET_SYSERR;
- }
if (GNUNET_OK != ret)
TEH_VALIDATION_done ();
return ret;
@@ -269,16 +208,6 @@ TEH_VALIDATION_init (const struct GNUNET_CONFIGURATION_Handle *cfg)
void
TEH_VALIDATION_done ()
{
- struct Plugin *p;
-
- while (NULL != (p = wire_head))
- {
- GNUNET_CONTAINER_DLL_remove (wire_head,
- wire_tail,
- p);
- TALER_WIRE_plugin_unload (p->plugin);
- GNUNET_free (p);
- }
json_decref (wire_fee_object);
wire_fee_object = NULL;
json_decref (wire_accounts_array);
@@ -287,65 +216,6 @@ TEH_VALIDATION_done ()
/**
- * Check if the given wire format JSON object is correctly formatted as
- * a wire address.
- *
- * @param wire the JSON wire format object
- * @param[out] emsg set to error message if we return an error code
- * @return #TALER_EC_NONE if correctly formatted; otherwise error code
- */
-enum TALER_ErrorCode
-TEH_json_validate_wireformat (const json_t *wire,
- char **emsg)
-{
- const char *payto_url;
- json_error_t error;
- char *method;
-
- *emsg = NULL;
- if (0 != json_unpack_ex ((json_t *) wire,
- &error, 0,
- "{s:s}",
- "url", &payto_url))
- {
- GNUNET_asprintf (emsg,
- "No `url' specified in the wire details\n");
- return TALER_EC_DEPOSIT_INVALID_WIRE_FORMAT_TYPE_MISSING;
- }
- method = TALER_WIRE_payto_get_method (payto_url);
- if (NULL == method)
- {
- GNUNET_asprintf (emsg,
- "Malformed payto URL `%s'\n",
- payto_url);
- return TALER_EC_PAYTO_MALFORMED;
- }
- for (struct Plugin *p = wire_head; NULL != p; p = p->next)
- {
- if (0 == strcasecmp (p->plugin->method,
- method))
- {
- enum TALER_ErrorCode ec;
-
- GNUNET_free (method);
- ec = p->plugin->wire_validate (p->plugin->cls,
- payto_url);
- if (TALER_EC_NONE != ec)
- GNUNET_asprintf (emsg,
- "Payto URL `%s' rejected by plugin\n",
- payto_url);
- return ec;
- }
- }
- GNUNET_asprintf (emsg,
- "Wire format type `%s' is not supported by this exchange\n",
- method);
- GNUNET_free (method);
- return TALER_EC_DEPOSIT_INVALID_WIRE_FORMAT_TYPE_UNSUPPORTED;
-}
-
-
-/**
* Obtain JSON response for /wire
*
* @return JSON array with the supported validation methods, NULL on error
diff --git a/src/exchange/taler-exchange-wirewatch.c b/src/exchange/taler-exchange-wirewatch.c
index 21f62cd82..091f4ba20 100644
--- a/src/exchange/taler-exchange-wirewatch.c
+++ b/src/exchange/taler-exchange-wirewatch.c
@@ -27,6 +27,7 @@
#include "taler_exchangedb_lib.h"
#include "taler_exchangedb_plugin.h"
#include "taler_json_lib.h"
+#include "taler_bank_service.h"
#include "taler_wire_lib.h"
/**
@@ -37,23 +38,6 @@
/**
- * Closure for #reject_cb().
- */
-struct RejectContext
-{
- /**
- * Wire transfer subject that was illformed.
- */
- char *wtid_s;
-
- /**
- * Database session that encountered the problem.
- */
- struct TALER_EXCHANGEDB_Session *session;
-};
-
-
-/**
* Information we keep for each supported account.
*/
struct WireAccount
@@ -69,14 +53,19 @@ struct WireAccount
struct WireAccount *prev;
/**
- * Handle to the plugin.
+ * Name of the section that configures this account.
*/
- struct TALER_WIRE_Plugin *wire_plugin;
+ char *section_name;
/**
- * Name of the section that configures this account.
+ * Account information.
*/
- char *section_name;
+ struct TALER_Account account;
+
+ /**
+ * Authentication data.
+ */
+ struct TALER_BANK_AuthenticationData auth;
/**
* Are we running from scratch and should re-process all transactions
@@ -108,6 +97,16 @@ static struct WireAccount *wa_tail;
static struct WireAccount *wa_pos;
/**
+ * Handle to the context for interacting with the bank.
+ */
+static struct GNUNET_CURL_Context *ctx;
+
+/**
+ * Scheduler context for running the @e ctx.
+ */
+static struct GNUNET_CURL_RescheduleContext *rc;
+
+/**
* Which currency is used by this exchange?
*/
static char *exchange_currency_string;
@@ -132,23 +131,13 @@ static int global_ret;
* Encoded offset in the wire transfer list from where
* to start the next query with the bank.
*/
-static void *last_row_off;
-
-/**
- * Number of bytes in #last_row_off.
- */
-static size_t last_row_off_size;
+static uint64_t last_row_off;
/**
* Latest row offset seen in this transaction, becomes
* the new #last_row_off upon commit.
*/
-static void *latest_row_off;
-
-/**
- * Number of bytes in #latest_row_off.
- */
-static size_t latest_row_off_size;
+static uint64_t latest_row_off;
/**
* Should we delay the next request to the wire plugin a bit?
@@ -183,12 +172,7 @@ static struct GNUNET_SCHEDULER_Task *task;
/**
* Active request for history.
*/
-static struct TALER_WIRE_HistoryHandle *hh;
-
-/**
- * Active request to reject a wire transfer.
- */
-static struct TALER_WIRE_RejectHandle *rt;
+static struct TALER_BANK_CreditHistoryHandle *hh;
/**
@@ -202,6 +186,16 @@ shutdown_task (void *cls)
struct WireAccount *wa;
(void) cls;
+ if (NULL != ctx)
+ {
+ GNUNET_CURL_fini (ctx);
+ ctx = NULL;
+ }
+ if (NULL != rc)
+ {
+ GNUNET_CURL_gnunet_rc_destroy (rc);
+ rc = NULL;
+ }
if (NULL != task)
{
GNUNET_SCHEDULER_cancel (task);
@@ -209,20 +203,9 @@ shutdown_task (void *cls)
}
if (NULL != hh)
{
- wa_pos->wire_plugin->get_history_cancel (wa_pos->wire_plugin->cls,
- hh);
+ TALER_BANK_credit_history_cancel (hh);
hh = NULL;
}
- if (NULL != rt)
- {
- char *wtid_s;
-
- wtid_s = wa_pos->wire_plugin->reject_transfer_cancel (
- wa_pos->wire_plugin->cls,
- rt);
- rt = NULL;
- GNUNET_free (wtid_s);
- }
TALER_EXCHANGEDB_plugin_unload (db_plugin);
db_plugin = NULL;
while (NULL != (wa = wa_head))
@@ -230,14 +213,13 @@ shutdown_task (void *cls)
GNUNET_CONTAINER_DLL_remove (wa_head,
wa_tail,
wa);
- TALER_WIRE_plugin_unload (wa->wire_plugin);
+ TALER_WIRE_account_free (&wa->account);
+ TALER_BANK_auth_free (&wa->auth);
GNUNET_free (wa->section_name);
GNUNET_free (wa);
}
wa_pos = NULL;
- GNUNET_free_non_null (last_row_off);
- last_row_off = NULL;
- last_row_off_size = 0;
+ last_row_off = 0;
}
@@ -259,13 +241,26 @@ add_account_cb (void *cls,
return; /* not enabled for us, skip */
wa = GNUNET_new (struct WireAccount);
wa->reset_mode = reset_mode;
- wa->wire_plugin = TALER_WIRE_plugin_load (cfg,
- ai->plugin_name);
- if (NULL == wa->wire_plugin)
+ if (GNUNET_OK !=
+ TALER_BANK_auth_parse_cfg (cfg,
+ ai->section_name,
+ &wa->auth))
{
GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
- "Failed to load wire plugin for `%s'\n",
- ai->plugin_name);
+ "Failed to load account `%s'\n",
+ ai->section_name);
+ GNUNET_free (wa);
+ return;
+ }
+ if (GNUNET_OK !=
+ TALER_BANK_account_parse_cfg (cfg,
+ ai->section_name,
+ &wa->account))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
+ "Failed to load account `%s'\n",
+ ai->section_name);
+ TALER_BANK_auth_free (&wa->auth);
GNUNET_free (wa);
return;
}
@@ -336,70 +331,28 @@ find_transfers (void *cls);
/**
- * Function called upon completion of the rejection of a wire transfer.
- *
- * @param cls closure with the `struct RejectContext`
- * @param ec error code for the operation
- */
-static void
-reject_cb (void *cls,
- enum TALER_ErrorCode ec)
-{
- struct RejectContext *rtc = cls;
- enum GNUNET_DB_QueryStatus qs;
-
- rt = NULL;
- if (TALER_EC_NONE != ec)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Failed to wire back transfer `%s': %d\n",
- rtc->wtid_s,
- ec);
- GNUNET_free (rtc->wtid_s);
- db_plugin->rollback (db_plugin->cls,
- rtc->session);
- GNUNET_free (rtc);
- GNUNET_SCHEDULER_shutdown ();
- return;
- }
- GNUNET_free (rtc->wtid_s);
- qs = db_plugin->commit (db_plugin->cls,
- rtc->session);
- GNUNET_break (0 <= qs);
- GNUNET_free (rtc);
- task = GNUNET_SCHEDULER_add_now (&find_transfers,
- NULL);
-}
-
-
-/**
* Callbacks of this type are used to serve the result of asking
* the bank for the transaction history.
*
* @param cls closure with the `struct TALER_EXCHANGEDB_Session *`
* @param ec taler error code
- * @param dir direction of the transfer
- * @param row_off identification of the position at which we are querying
- * @param row_off_size number of bytes in @a row_off
+ * @param serial_id identification of the position at which we are querying
* @param details details about the wire transfer
+ * @param json raw JSON response
* @return #GNUNET_OK to continue, #GNUNET_SYSERR to abort iteration
*/
static int
history_cb (void *cls,
+ unsigned int http_status,
enum TALER_ErrorCode ec,
- enum TALER_BANK_Direction dir,
- const void *row_off,
- size_t row_off_size,
- const struct TALER_WIRE_TransferDetails *details)
+ uint64_t serial_id,
+ const struct TALER_BANK_CreditDetails *details,
+ const json_t *json)
{
struct TALER_EXCHANGEDB_Session *session = cls;
enum GNUNET_DB_QueryStatus qs;
- struct TALER_ReservePublicKeyP reserve_pub;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Got history callback, direction %u!\n",
- (unsigned int) dir);
- if (TALER_BANK_DIRECTION_NONE == dir)
+ if (NULL == details)
{
hh = NULL;
if (TALER_EC_NONE != ec)
@@ -428,11 +381,8 @@ history_cb (void *cls,
if (0 < qs)
{
/* transaction success, update #last_row_off */
- GNUNET_free_non_null (last_row_off);
last_row_off = latest_row_off;
- last_row_off_size = latest_row_off_size;
- latest_row_off = NULL;
- latest_row_off_size = 0;
+ latest_row_off = 0;
/* if successful at limit, try increasing transaction batch size (AIMD) */
if (current_batch_size == batch_size)
@@ -462,49 +412,10 @@ history_cb (void *cls,
NULL);
return GNUNET_OK; /* will be ignored anyway */
}
- if (NULL != details->wtid_s)
- {
- struct RejectContext *rtc;
-
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "Wire transfer over %s has invalid subject `%s', sending it back!\n",
- TALER_amount2s (&details->amount),
- details->wtid_s);
- GNUNET_break (0 != row_off_size);
- if (latest_row_off_size != row_off_size)
- {
- GNUNET_free_non_null (latest_row_off);
- latest_row_off = GNUNET_malloc (row_off_size);
- latest_row_off_size = row_off_size;
- }
- memcpy (latest_row_off,
- row_off,
- row_off_size);
- rtc = GNUNET_new (struct RejectContext);
- rtc->session = session;
- rtc->wtid_s = GNUNET_strdup (details->wtid_s);
- rt = wa_pos->wire_plugin->reject_transfer (wa_pos->wire_plugin->cls,
- wa_pos->section_name,
- row_off,
- row_off_size,
- &reject_cb,
- rtc);
- if (NULL == rt)
- {
- GNUNET_break (0);
- db_plugin->rollback (db_plugin->cls,
- session);
- GNUNET_assert (NULL == task);
- task = GNUNET_SCHEDULER_add_now (&find_transfers,
- NULL);
- }
- return GNUNET_SYSERR; /* will continue later... */
- }
-
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Adding wire transfer over %s with (hashed) subject `%s'\n",
TALER_amount2s (&details->amount),
- TALER_B2S (&details->wtid));
+ TALER_B2S (&details->reserve_pub));
/**
* Debug block.
@@ -515,8 +426,8 @@ history_cb (void *cls,
char wtid_s[PUBSIZE];
GNUNET_break
- (NULL != GNUNET_STRINGS_data_to_string (&details->wtid,
- sizeof (details->wtid),
+ (NULL != GNUNET_STRINGS_data_to_string (&details->reserve_pub,
+ sizeof (details->reserve_pub),
&wtid_s[0],
PUBSIZE));
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
@@ -525,20 +436,14 @@ history_cb (void *cls,
}
current_batch_size++;
- /* Wire transfer identifier == reserve public key */
- GNUNET_assert (sizeof (reserve_pub) == sizeof (details->wtid));
- memcpy (&reserve_pub,
- &details->wtid,
- sizeof (reserve_pub));
qs = db_plugin->reserves_in_insert (db_plugin->cls,
session,
- &reserve_pub,
+ &details->reserve_pub,
&details->amount,
details->execution_date,
details->account_url,
wa_pos->section_name,
- row_off,
- row_off_size);
+ serial_id);
if (GNUNET_DB_STATUS_HARD_ERROR == qs)
{
GNUNET_break (0);
@@ -560,15 +465,7 @@ history_cb (void *cls,
return GNUNET_SYSERR;
}
- if (latest_row_off_size != row_off_size)
- {
- GNUNET_free_non_null (latest_row_off);
- latest_row_off = GNUNET_malloc (row_off_size);
- latest_row_off_size = row_off_size;
- }
- memcpy (latest_row_off,
- row_off,
- row_off_size);
+ latest_row_off = serial_id;
return GNUNET_OK;
}
@@ -615,8 +512,7 @@ find_transfers (void *cls)
qs = db_plugin->get_latest_reserve_in_reference (db_plugin->cls,
session,
wa_pos->section_name,
- &last_row_off,
- &last_row_off_size);
+ &last_row_off);
if (GNUNET_DB_STATUS_HARD_ERROR == qs)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
@@ -638,20 +534,17 @@ find_transfers (void *cls)
}
}
wa_pos->reset_mode = GNUNET_NO;
- GNUNET_assert ( (NULL == last_row_off) ||
- ( (NULL != last_row_off) &&
- (0 != last_row_off_size) ) );
delay = GNUNET_YES;
current_batch_size = 0;
- hh = wa_pos->wire_plugin->get_history (wa_pos->wire_plugin->cls,
- wa_pos->section_name,
- TALER_BANK_DIRECTION_CREDIT,
- last_row_off,
- last_row_off_size,
- batch_size,
- &history_cb,
- session);
+ hh = TALER_BANK_credit_history (ctx,
+ wa_pos->account.details.x_taler_bank.
+ account_base_url,
+ &wa_pos->auth,
+ last_row_off,
+ batch_size,
+ &history_cb,
+ session);
if (NULL == hh)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
@@ -695,6 +588,14 @@ run (void *cls,
NULL);
GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
cls);
+ ctx = GNUNET_CURL_init (&GNUNET_CURL_gnunet_scheduler_reschedule,
+ &rc);
+ rc = GNUNET_CURL_gnunet_rc_create (ctx);
+ if (NULL == ctx)
+ {
+ GNUNET_break (0);
+ return;
+ }
}