implement /config in fakebank and taler_bank_lib.h (#6066)

This commit is contained in:
Christian Grothoff 2020-02-04 21:59:43 +01:00
parent e6d6987e56
commit 42bc31744b
No known key found for this signature in database
GPG Key ID: 939E6BE1E29FC3CC
13 changed files with 564 additions and 115 deletions

View File

@ -38,6 +38,7 @@ libtalerbank_la_LDFLAGS = \
libtalerbank_la_SOURCES = \
bank_api_admin.c \
bank_api_common.c bank_api_common.h \
bank_api_config.c \
bank_api_credit.c \
bank_api_debit.c \
bank_api_transfer.c \

View File

@ -0,0 +1,255 @@
/*
This file is part of TALER
Copyright (C) 2017--2020 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_config.c
* @brief Implementation of the /config request
* @author Christian Grothoff
*/
#include "platform.h"
#include "bank_api_common.h"
#include <microhttpd.h> /* just for HTTP status codes */
#include "taler_signatures.h"
/**
* Protocol version we implement.
*/
#define BANK_PROTOCOL_CURRENT 0
/**
* How many revisions back are we compatible to.
*/
#define BANK_PROTOCOL_AGE 0
/**
* @brief A /config Handle
*/
struct TALER_BANK_ConfigHandle
{
/**
* The url for this request.
*/
char *request_url;
/**
* Handle for the request.
*/
struct GNUNET_CURL_Job *job;
/**
* Function to call with the result.
*/
TALER_BANK_ConfigCallback hcb;
/**
* Closure for @a cb.
*/
void *hcb_cls;
};
/**
* Parse configuration given in JSON format and invoke the callback on each item.
*
* @param ch handle to the account configuration request
* @param config JSON object with the configuration
* @return #GNUNET_OK if configuration was valid and @a rconfiguration and @a balance
* were set,
* #GNUNET_SYSERR if there was a protocol violation in @a configuration
*/
static int
parse_config (struct TALER_BANK_ConfigHandle *ch,
const json_t *config)
{
struct TALER_BANK_Configuration cfg;
struct GNUNET_JSON_Specification spec[] = {
GNUNET_JSON_spec_string ("version",
&cfg.version),
GNUNET_JSON_spec_string ("currency",
&cfg.version),
GNUNET_JSON_spec_end ()
};
if (GNUNET_OK !=
GNUNET_JSON_parse (config,
spec,
NULL, NULL))
{
GNUNET_break_op (0);
return GNUNET_SYSERR;
}
ch->hcb (ch->hcb_cls,
MHD_HTTP_OK,
TALER_EC_NONE,
&cfg);
GNUNET_JSON_parse_free (spec);
return GNUNET_OK;
}
/**
* Function called when we're done processing the
* HTTP /config request.
*
* @param cls the `struct TALER_BANK_ConfigHandle`
* @param response_code HTTP response code, 0 on error
* @param response parsed JSON result, NULL on error
*/
static void
handle_configuration_finished (void *cls,
long response_code,
const void *response)
{
struct TALER_BANK_ConfigHandle *ch = cls;
enum TALER_ErrorCode ec;
const json_t *j = response;
ch->job = NULL;
switch (response_code)
{
case 0:
ec = TALER_EC_INVALID_RESPONSE;
break;
case MHD_HTTP_OK:
if (GNUNET_OK !=
parse_config (ch,
j))
{
GNUNET_break_op (0);
response_code = 0;
ec = TALER_EC_INVALID_RESPONSE;
break;
}
response_code = MHD_HTTP_NO_CONTENT; /* signal end of list */
ec = TALER_EC_NONE;
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);
ec = TALER_JSON_get_error_code (j);
break;
case MHD_HTTP_UNAUTHORIZED:
/* Nothing really to verify, bank says the HTTP Authentication
failed. May happen if HTTP authentication is used and the
user supplied a wrong username/password combination. */
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 */
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_op (0);
ec = TALER_JSON_get_error_code (j);
response_code = 0;
break;
}
ch->hcb (ch->hcb_cls,
response_code,
ec,
NULL);
TALER_BANK_configuration_cancel (ch);
}
/**
* Request the configuration of the bank.
*
* @param ctx curl context for the event loop
* @param auth authentication data to use
* @param hres_cb the callback to call with the
* configuration
* @param hres_cb_cls closure for the above callback
* @return NULL if the inputs are invalid
*/
struct TALER_BANK_ConfigHandle *
TALER_BANK_configuration (struct GNUNET_CURL_Context *ctx,
const struct TALER_BANK_AuthenticationData *auth,
TALER_BANK_ConfigCallback hres_cb,
void *hres_cb_cls)
{
struct TALER_BANK_ConfigHandle *ch;
CURL *eh;
ch = GNUNET_new (struct TALER_BANK_ConfigHandle);
ch->hcb = hres_cb;
ch->hcb_cls = hres_cb_cls;
ch->request_url = TALER_url_join (auth->wire_gateway_url,
"config",
NULL);
if (NULL == ch->request_url)
{
GNUNET_free (ch);
GNUNET_break (0);
return NULL;
}
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Requesting configuration at `%s'\n",
ch->request_url);
eh = curl_easy_init ();
if ( (GNUNET_OK !=
TALER_BANK_setup_auth_ (eh,
auth)) ||
(CURLE_OK !=
curl_easy_setopt (eh,
CURLOPT_URL,
ch->request_url)) )
{
GNUNET_break (0);
TALER_BANK_configuration_cancel (ch);
curl_easy_cleanup (eh);
return NULL;
}
ch->job = GNUNET_CURL_job_add2 (ctx,
eh,
NULL,
&handle_configuration_finished,
ch);
return ch;
}
/**
* Cancel a configuration request. This function cannot be
* used on a request handle if a response is already
* served for it.
*
* @param ch the configuration request handle
*/
void
TALER_BANK_configuration_cancel (struct TALER_BANK_ConfigHandle *ch)
{
if (NULL != ch->job)
{
GNUNET_CURL_job_cancel (ch->job);
ch->job = NULL;
}
GNUNET_free (ch->request_url);
GNUNET_free (ch);
}
/* end of bank_api_config.c */

View File

@ -26,6 +26,24 @@
#include "taler_bank_service.h"
#include "taler_mhd_lib.h"
/**
* Taler protocol version in the format CURRENT:REVISION:AGE
* as used by GNU libtool. See
* https://www.gnu.org/software/libtool/manual/html_node/Libtool-versioning.html
*
* Please be very careful when updating and follow
* https://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html#Updating-version-info
* precisely. Note that this version has NOTHING to do with the
* release version, and the format is NOT the same that semantic
* versioning uses either.
*
* When changing this version, you likely want to also update
* #BANK_PROTOCOL_CURRENT and #BANK_PROTOCOL_AGE in
* bank_api_config.c!
*/
#define BANK_PROTOCOL_VERSION "0:0:0"
/**
* Maximum POST request size (for /admin/add-incoming)
*/
@ -172,6 +190,11 @@ struct TALER_FAKEBANK_Handle
*/
uint64_t serial_counter;
/**
* Currency used by the fakebank.
*/
char *currency;
/**
* BaseURL of the fakebank.
*/
@ -527,6 +550,7 @@ TALER_FAKEBANK_stop (struct TALER_FAKEBANK_Handle *h)
h->mhd_bank = NULL;
}
GNUNET_free (h->my_baseurl);
GNUNET_free (h->currency);
GNUNET_free (h);
}
@ -776,7 +800,7 @@ handle_transfer (struct TALER_FAKEBANK_Handle *h,
/**
* Handle incoming HTTP request for /history
* Handle incoming HTTP request for / (home page).
*
* @param h the fakebank handle
* @param connection the connection
@ -808,6 +832,29 @@ handle_home_page (struct TALER_FAKEBANK_Handle *h,
}
/**
* Handle incoming HTTP request for /config
*
* @param h the fakebank handle
* @param connection the connection
* @param con_cls place to store state, not used
* @return MHD result code
*/
static int
handle_config (struct TALER_FAKEBANK_Handle *h,
struct MHD_Connection *connection,
void **con_cls)
{
return TALER_MHD_reply_json_pack (connection,
MHD_HTTP_OK,
"{s:s, s:s}",
"currency",
h->currency,
"version"
BANK_PROTOCOL_VERSION);
}
/**
* This is the "base" structure for both the /history and the
* /history-range API calls.
@ -1202,6 +1249,13 @@ serve (struct TALER_FAKEBANK_Handle *h,
return handle_home_page (h,
connection,
con_cls);
if ( (0 == strcmp (url,
"/config")) &&
(0 == strcasecmp (method,
MHD_HTTP_METHOD_GET)) )
return handle_config (h,
connection,
con_cls);
if ( (0 == strcmp (url,
"/admin/add-incoming")) &&
(0 == strcasecmp (method,
@ -1433,15 +1487,19 @@ run_mhd (void *cls)
* would have issued the correct wire transfer orders.
*
* @param port port to listen to
* @param currency currency the bank uses
* @return NULL on error
*/
struct TALER_FAKEBANK_Handle *
TALER_FAKEBANK_start (uint16_t port)
TALER_FAKEBANK_start (uint16_t port,
const char *currency)
{
struct TALER_FAKEBANK_Handle *h;
GNUNET_assert (strlen (currency) < TALER_CURRENCY_LEN);
h = GNUNET_new (struct TALER_FAKEBANK_Handle);
h->port = port;
h->currency = GNUNET_strdup (currency);
GNUNET_asprintf (&h->my_baseurl,
"http://localhost:%u/",
(unsigned int) port);
@ -1462,6 +1520,7 @@ TALER_FAKEBANK_start (uint16_t port)
MHD_OPTION_END);
if (NULL == h->mhd_bank)
{
GNUNET_free (h->currency);
GNUNET_free (h);
return NULL;
}

View File

@ -43,12 +43,38 @@ run (void *cls,
const char *cfgfile,
const struct GNUNET_CONFIGURATION_Handle *cfg)
{
char *currency_string;
(void) cls;
(void) args;
(void) cfgfile;
(void) cfg;
if (NULL == TALER_FAKEBANK_start (8082))
if (GNUNET_OK !=
GNUNET_CONFIGURATION_get_value_string (cfg,
"taler",
"CURRENCY",
&currency_string))
{
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
"taler",
"CURRENCY");
ret = 1;
return;
}
if (strlen (currency_string) >= TALER_CURRENCY_LEN)
{
GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
"taler",
"CURRENCY",
"Value is too long");
GNUNET_free (currency_string);
ret = 1;
return;
}
if (NULL == TALER_FAKEBANK_start (8082,
currency_string))
ret = 1;
GNUNET_free (currency_string);
ret = 0;
}

View File

@ -156,9 +156,9 @@ static char *mode_str;
static enum BenchmarkMode mode;
/**
* Config filename.
* Configuration.
*/
static char *cfg_filename;
static struct GNUNET_CONFIGURATION_Handle *cfg;
/**
* Currency used.
@ -445,7 +445,8 @@ launch_fakebank (void *cls)
(void) cls;
fakebank
= TALER_TESTING_run_fakebank (exchange_bank_account.wire_gateway_url);
= TALER_TESTING_run_fakebank (exchange_bank_account.wire_gateway_url,
currency);
if (NULL == fakebank)
{
GNUNET_break (0);
@ -624,12 +625,11 @@ parallel_benchmark (TALER_TESTING_Main main_cb,
NULL == loglev ? "INFO" : loglev,
logfile);
result = TALER_TESTING_setup
(main_cb,
main_cb_cls,
cfg_filename,
exchanged,
GNUNET_YES);
result = TALER_TESTING_setup (main_cb,
main_cb_cls,
cfg,
exchanged,
GNUNET_YES);
if (GNUNET_OK != result)
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Failure in child process test suite!\n");
@ -746,7 +746,7 @@ int
main (int argc,
char *const *argv)
{
struct GNUNET_CONFIGURATION_Handle *cfg;
char *cfg_filename = NULL;
struct GNUNET_GETOPT_CommandLineOption options[] = {
GNUNET_GETOPT_option_mandatory
(GNUNET_GETOPT_option_cfgfile (&cfg_filename)),
@ -798,6 +798,7 @@ main (int argc,
argc,
argv)))
{
GNUNET_free_non_null (cfg_filename);
return BAD_CLI_ARG;
}
GNUNET_log_setup ("taler-exchange-benchmark",
@ -814,6 +815,7 @@ main (int argc,
else
{
TALER_LOG_ERROR ("Unknown mode given: '%s'\n", mode_str);
GNUNET_free_non_null (cfg_filename);
return BAD_CONFIG_FILE;
}
if (NULL == cfg_filename)
@ -825,8 +827,10 @@ main (int argc,
cfg_filename))
{
TALER_LOG_ERROR ("Could not parse configuration\n");
GNUNET_free (cfg_filename);
return BAD_CONFIG_FILE;
}
GNUNET_free (cfg_filename);
if (GNUNET_OK !=
GNUNET_CONFIGURATION_get_value_string (cfg,
"taler",
@ -839,6 +843,16 @@ main (int argc,
GNUNET_CONFIGURATION_destroy (cfg);
return BAD_CONFIG_FILE;
}
if (strlen (currency) >= TALER_CURRENCY_LEN)
{
GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
"taler",
"CURRENCY",
"Value is too long");
GNUNET_CONFIGURATION_destroy (cfg);
return BAD_CONFIG_FILE;
}
if (howmany_clients > 10240)
{
TALER_LOG_ERROR ("-p option value given is too large\n");
@ -950,11 +964,11 @@ main (int argc,
return BAD_CONFIG_FILE;
}
}
GNUNET_CONFIGURATION_destroy (cfg);
result = parallel_benchmark (&run,
NULL,
cfg_filename);
GNUNET_CONFIGURATION_destroy (cfg);
/* If we're the exchange worker, we're done now. No need to print results */
if (MODE_EXCHANGE == mode)

View File

@ -89,6 +89,73 @@ struct TALER_BANK_AuthenticationData
};
/* ********************* /config *********************** */
/**
* @brief A /config Handle
*/
struct TALER_BANK_ConfigHandle;
/**
* Configuration data provided by the bank.
*/
struct TALER_BANK_Configuration
{
/**
* Current protocol version. Libtool style.
*/
const char *version;
/**
* Currency used by the bank.
*/
const char *currency;
};
/**
* Function called with configuration details from the bank.
*
* @param cls closure
* @param http status code
* @param ec taler error code
* @param config the configuration, NULL on error
*/
typedef void
(*TALER_BANK_ConfigCallback)(void *cls,
unsigned int http_status,
enum TALER_ErrorCode ec,
const struct TALER_BANK_Configuration *config);
/**
* Request the configuration of the bank.
*
* @param ctx curl context for the event loop
* @param auth authentication data to use
* @param hres_cb the callback to call with the
* configuration
* @param hres_cb_cls closure for the above callback
* @return NULL if the inputs are invalid (i.e. zero value for
* @e num_results). In this case, the callback is not
* called.
*/
struct TALER_BANK_ConfigHandle *
TALER_BANK_configuration (struct GNUNET_CURL_Context *ctx,
const struct TALER_BANK_AuthenticationData *auth,
TALER_BANK_ConfigCallback hres_cb,
void *hres_cb_cls);
/**
* Cancel a configuration request. This function cannot be
* used on a request handle if a response is already
* served for it.
*
* @param ch the configuration request handle
*/
void
TALER_BANK_configuration_cancel (struct TALER_BANK_ConfigHandle *ch);
/* ********************* /admin/add/incoming *********************** */
@ -160,7 +227,7 @@ TALER_BANK_admin_add_incoming_cancel (struct
TALER_BANK_AdminAddIncomingHandle *aai);
/* ********************* /taler/transfer *********************** */
/* ********************* /transfer *********************** */
/**
* Prepare for exeuction of a wire transfer.
@ -243,7 +310,7 @@ TALER_BANK_execute_wire_transfer_cancel (struct
TALER_BANK_WireExecuteHandle *weh);
/* ********************* /taler/credits *********************** */
/* ********************* /history/incoming *********************** */
/**
* Handle for querying the bank for transactions
@ -347,7 +414,7 @@ void
TALER_BANK_credit_history_cancel (struct TALER_BANK_CreditHistoryHandle *hh);
/* ********************* /taler/debits *********************** */
/* ********************* /history/outgoing *********************** */
/**
* Handle for querying the bank for transactions

View File

@ -44,10 +44,12 @@ struct TALER_FAKEBANK_Handle;
* would have issued the correct wire transfer orders.
*
* @param port port to listen to
* @param currency which currency should the bank offer
* @return NULL on error
*/
struct TALER_FAKEBANK_Handle *
TALER_FAKEBANK_start (uint16_t port);
TALER_FAKEBANK_start (uint16_t port,
const char *currency);
/**

View File

@ -635,7 +635,7 @@ typedef void
* @param main_cb the "run" method which coontains all the
* commands.
* @param main_cb_cls a closure for "run", typically NULL.
* @param config_filename configuration filename.
* @param cfg configuration to use
* @param exchanged exchange process handle: will be put in the
* state as some commands - e.g. revoke - need to send
* signal to it, for example to let it know to reload the
@ -650,7 +650,7 @@ typedef void
int
TALER_TESTING_setup (TALER_TESTING_Main main_cb,
void *main_cb_cls,
const char *config_filename,
const struct GNUNET_CONFIGURATION_Handle *cfg,
struct GNUNET_OS_Process *exchanged,
int exchange_connect);
@ -789,11 +789,13 @@ TALER_TESTING_run_bank (const char *config_filename,
* from the base URL.
*
* @param bank_url bank's base URL.
* @param currency currency the bank uses
* @return the fakebank process handle, or NULL if any
* error occurs.
*/
struct TALER_FAKEBANK_Handle *
TALER_TESTING_run_fakebank (const char *bank_url);
TALER_TESTING_run_fakebank (const char *bank_url,
const char *currency);
/**

View File

@ -52,6 +52,7 @@ static struct GNUNET_OS_Process *bankd;
*/
static int with_fakebank;
/**
* Main function that will tell the interpreter what commands to
* run.
@ -116,12 +117,32 @@ run (void *cls,
}
/**
* Runs #TALER_TESTING_setup() using the configuration.
*
* @param cls unused
* @param cfg configuration to use
* @return status code
*/
static int
setup_with_cfg (void *cls,
const struct GNUNET_CONFIGURATION_Handle *cfg)
{
(void) cls;
return TALER_TESTING_setup (&run,
NULL,
cfg,
NULL,
GNUNET_NO);
}
int
main (int argc,
char *const *argv)
{
int rv;
const char *cfgfilename;
int rv;
/* These environment variables get in the way... */
unsetenv ("XDG_DATA_HOME");
@ -165,12 +186,13 @@ main (int argc,
return 77;
}
}
rv = (GNUNET_OK == TALER_TESTING_setup (&run,
NULL,
cfgfilename,
NULL,
GNUNET_NO)) ? 0 : 1;
if (GNUNET_OK !=
GNUNET_CONFIGURATION_parse_and_run (cfgfilename,
&setup_with_cfg,
NULL))
rv = 1;
else
rv = 0;
if (GNUNET_NO == with_fakebank)
{

View File

@ -57,36 +57,6 @@ static char *config_filename;
#define USER42_ACCOUNT "42"
/**
* @return GNUNET_NO if database could not be prepared,
* otherwise GNUNET_OK
*/
static int
prepare_database (void *cls,
const struct GNUNET_CONFIGURATION_Handle *cfg)
{
dbc.plugin = TALER_EXCHANGEDB_plugin_load (cfg);
if (NULL == dbc.plugin)
{
GNUNET_break (0);
result = 77;
return GNUNET_NO;
}
if (GNUNET_OK !=
dbc.plugin->create_tables (dbc.plugin->cls))
{
GNUNET_break (0);
TALER_EXCHANGEDB_plugin_unload (dbc.plugin);
dbc.plugin = NULL;
result = 77;
return GNUNET_NO;
}
dbc.session = dbc.plugin->get_session (dbc.plugin->cls);
GNUNET_assert (NULL != dbc.session);
return GNUNET_OK;
}
/**
* Collects all the tests.
@ -454,6 +424,48 @@ run (void *cls,
}
/**
* Prepare database an launch the test.
*
* @param cls unused
* @param cfg our configuration
* @return #GNUNET_NO if database could not be prepared,
* otherwise #GNUNET_OK
*/
static int
prepare_database (void *cls,
const struct GNUNET_CONFIGURATION_Handle *cfg)
{
dbc.plugin = TALER_EXCHANGEDB_plugin_load (cfg);
if (NULL == dbc.plugin)
{
GNUNET_break (0);
result = 77;
return GNUNET_NO;
}
if (GNUNET_OK !=
dbc.plugin->create_tables (dbc.plugin->cls))
{
GNUNET_break (0);
TALER_EXCHANGEDB_plugin_unload (dbc.plugin);
dbc.plugin = NULL;
result = 77;
return GNUNET_NO;
}
dbc.session = dbc.plugin->get_session (dbc.plugin->cls);
GNUNET_assert (NULL != dbc.session);
result = TALER_TESTING_setup (&run,
NULL,
cfg,
NULL, // no exchange process handle.
GNUNET_NO); // do not try to connect to the exchange
return GNUNET_OK;
}
int
main (int argc,
char *const argv[])
@ -507,12 +519,6 @@ main (int argc,
return result;
}
result = TALER_TESTING_setup (&run,
NULL,
config_filename,
NULL, // no exchange process handle.
GNUNET_NO); // do not try to connect to the exchange
GNUNET_free (config_filename);
GNUNET_free (testname);
dbc.plugin->drop_tables (dbc.plugin->cls);

View File

@ -36,11 +36,13 @@
* from the base URL.
*
* @param bank_url bank's base URL.
* @param currency currency the bank uses
* @return the fakebank process handle, or NULL if any
* error occurs.
*/
struct TALER_FAKEBANK_Handle *
TALER_TESTING_run_fakebank (const char *bank_url)
TALER_TESTING_run_fakebank (const char *bank_url,
const char *currency)
{
const char *port;
long pnum;
@ -56,7 +58,8 @@ TALER_TESTING_run_fakebank (const char *bank_url)
"Starting Fakebank on port %u (%s)\n",
(unsigned int) pnum,
bank_url);
fakebankd = TALER_FAKEBANK_start ((uint16_t) pnum);
fakebankd = TALER_FAKEBANK_start ((uint16_t) pnum,
currency);
if (NULL == fakebankd)
{
GNUNET_break (0);

View File

@ -788,7 +788,7 @@ TALER_TESTING_setup_with_exchange_cfg (void *cls,
/* NOTE: this call blocks. */
result = TALER_TESTING_setup (setup_ctx->main_cb,
setup_ctx->main_cb_cls,
setup_ctx->config_filename,
cfg,
exchanged,
GNUNET_YES);
GNUNET_break (0 ==

View File

@ -124,7 +124,33 @@ TALER_TESTING_run_with_fakebank (struct TALER_TESTING_Interpreter *is,
struct TALER_TESTING_Command *commands,
const char *bank_url)
{
is->fakebank = TALER_TESTING_run_fakebank (bank_url);
char *currency;
if (GNUNET_OK !=
GNUNET_CONFIGURATION_get_value_string (is->cfg,
"taler",
"CURRENCY",
&currency))
{
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
"taler",
"CURRENCY");
is->result = GNUNET_SYSERR;
return;
}
if (strlen (currency) >= TALER_CURRENCY_LEN)
{
GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
"taler",
"CURRENCY",
"Value is too long");
GNUNET_free (currency);
is->result = GNUNET_SYSERR;
return;
}
is->fakebank = TALER_TESTING_run_fakebank (bank_url,
currency);
GNUNET_free (currency);
if (NULL == is->fakebank)
{
GNUNET_break (0);
@ -529,14 +555,6 @@ struct MainContext
*/
struct TALER_TESTING_Interpreter *is;
/**
* Configuration filename. The wrapper uses it to fetch
* the exchange port number; We could have passed the port
* number here, but having the config filename seems more
* generic.
*/
const char *config_filename;
/**
* URL of the exchange.
*/
@ -683,18 +701,16 @@ do_abort (void *cls)
* and responsible to run the "run" method.
*
* @param cls a `struct MainContext *`
* @param cfg configuration to use
*/
static int
main_exchange_connect_with_cfg (void *cls,
const struct GNUNET_CONFIGURATION_Handle *cfg)
static void
main_wrapper_exchange_connect (void *cls)
{
struct MainContext *main_ctx = cls;
struct TALER_TESTING_Interpreter *is = main_ctx->is;
char *exchange_url;
if (GNUNET_OK !=
GNUNET_CONFIGURATION_get_value_string (cfg,
GNUNET_CONFIGURATION_get_value_string (is->cfg,
"exchange",
"BASE_URL",
&exchange_url))
@ -702,40 +718,18 @@ main_exchange_connect_with_cfg (void *cls,
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
"exchange",
"BASE_URL");
return GNUNET_SYSERR;
return;
}
main_ctx->exchange_url = exchange_url;
is->cfg = cfg;
is->timeout_task = GNUNET_SCHEDULER_add_shutdown (&do_abort,
main_ctx);
GNUNET_break
(NULL != (is->exchange = TALER_EXCHANGE_connect
(is->ctx,
exchange_url,
&TALER_TESTING_cert_cb,
main_ctx,
TALER_EXCHANGE_OPTION_END)));
is->cfg = NULL;
return GNUNET_OK;
}
/**
* Initialize scheduler loop and curl context for the testcase,
* and responsible to run the "run" method.
*
* @param cls a `struct MainContext *`
*/
static void
main_wrapper_exchange_connect (void *cls)
{
struct MainContext *main_ctx = cls;
GNUNET_break (GNUNET_OK ==
GNUNET_CONFIGURATION_parse_and_run (main_ctx->config_filename,
&
main_exchange_connect_with_cfg,
main_ctx));
(NULL != (is->exchange =
TALER_EXCHANGE_connect (is->ctx,
exchange_url,
&TALER_TESTING_cert_cb,
main_ctx,
TALER_EXCHANGE_OPTION_END)));
}
@ -746,7 +740,7 @@ main_wrapper_exchange_connect (void *cls)
* @param main_cb the "run" method which contains all the
* commands.
* @param main_cb_cls a closure for "run", typically NULL.
* @param config_filename configuration filename.
* @param cfg configuration to use
* @param exchanged exchange process handle: will be put in the
* state as some commands - e.g. revoke - need to send
* signal to it, for example to let it know to reload the
@ -761,7 +755,7 @@ main_wrapper_exchange_connect (void *cls)
int
TALER_TESTING_setup (TALER_TESTING_Main main_cb,
void *main_cb_cls,
const char *config_filename,
const struct GNUNET_CONFIGURATION_Handle *cfg,
struct GNUNET_OS_Process *exchanged,
int exchange_connect)
{
@ -771,9 +765,6 @@ TALER_TESTING_setup (TALER_TESTING_Main main_cb,
.main_cb_cls = main_cb_cls,
/* needed to init the curl ctx */
.is = &is,
/* needed to read values like exchange port
* number to construct the exchange url.*/
.config_filename = config_filename
};
struct GNUNET_SIGNAL_Context *shc_chld;
@ -781,6 +772,7 @@ TALER_TESTING_setup (TALER_TESTING_Main main_cb,
0,
sizeof (is));
is.exchanged = exchanged;
is.cfg = cfg;
sigpipe = GNUNET_DISK_pipe (GNUNET_NO, GNUNET_NO,
GNUNET_NO, GNUNET_NO);
GNUNET_assert (NULL != sigpipe);