From 57c1d2318f14c4b5c21609cb96f32517d02752e7 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Mon, 25 Jan 2016 14:57:32 +0100 Subject: getting aggregator structure laid out for #4141 --- src/include/Makefile.am | 1 + src/include/taler_mintdb_plugin.h | 8 +- src/mint/Makefile.am | 1 + src/mint/taler-mint-aggregator.c | 164 ++++++++++++++++++++++++++++++++++++-- src/wire/Makefile.am | 13 +++ src/wire/test_sepa_wireformat.c | 53 +----------- 6 files changed, 182 insertions(+), 58 deletions(-) (limited to 'src') diff --git a/src/include/Makefile.am b/src/include/Makefile.am index 2f3973c4f..4d7ae3cb2 100644 --- a/src/include/Makefile.am +++ b/src/include/Makefile.am @@ -21,6 +21,7 @@ talerinclude_HEADERS = \ taler_mintdb_plugin.h \ taler_pq_lib.h \ taler_signatures.h \ + taler_wire_lib.h \ taler_wire_plugin.h endif diff --git a/src/include/taler_mintdb_plugin.h b/src/include/taler_mintdb_plugin.h index e5cf6d6f1..4230a761f 100644 --- a/src/include/taler_mintdb_plugin.h +++ b/src/include/taler_mintdb_plugin.h @@ -1145,10 +1145,10 @@ struct TALER_MINTDB_Plugin */ int (*insert_refresh_out) (void *cls, - struct TALER_MINTDB_Session *session, - const struct GNUNET_HashCode *session_hash, - uint16_t newcoin_index, - const struct TALER_DenominationSignature *ev_sig); + struct TALER_MINTDB_Session *session, + const struct GNUNET_HashCode *session_hash, + uint16_t newcoin_index, + const struct TALER_DenominationSignature *ev_sig); /** diff --git a/src/mint/Makefile.am b/src/mint/Makefile.am index fda014d56..8e2eae77b 100644 --- a/src/mint/Makefile.am +++ b/src/mint/Makefile.am @@ -15,6 +15,7 @@ taler_mint_aggregator_SOURCES = \ taler_mint_aggregator_LDADD = \ $(LIBGCRYPT_LIBS) \ $(top_builddir)/src/util/libtalerutil.la \ + $(top_builddir)/src/wire/libtalerwire.la \ $(top_builddir)/src/mintdb/libtalermintdb.la \ -ljansson \ -lgnunetutil diff --git a/src/mint/taler-mint-aggregator.c b/src/mint/taler-mint-aggregator.c index a739d87e0..d3c66f025 100644 --- a/src/mint/taler-mint-aggregator.c +++ b/src/mint/taler-mint-aggregator.c @@ -23,13 +23,20 @@ #include #include #include -#include "taler_wire_plugin.h" +#include "taler_mintdb_lib.h" +#include "taler_mintdb_plugin.h" +#include "taler_wire_lib.h" /** * Which currency is used by this mint? */ static char *mint_currency_string; +/** + * Which wireformat should be supported by this aggregator? + */ +static char *mint_wireformat; + /** * Base directory of the mint (global) */ @@ -45,6 +52,16 @@ static struct GNUNET_CONFIGURATION_Handle *cfg; */ static struct TALER_MINTDB_Plugin *db_plugin; +/** + * Our wire plugin. + */ +static struct TALER_WIRE_Plugin *wire_plugin; + +/** + * Task for the main #run() function. + */ +static struct GNUNET_SCHEDULER_Task *task; + /** * Load configuration parameters for the mint @@ -56,7 +73,7 @@ static struct TALER_MINTDB_Plugin *db_plugin; static int mint_serve_process_config (const char *mint_directory) { - unsigned long long port; + char *type; cfg = TALER_config_load (mint_directory); if (NULL == cfg) @@ -84,19 +101,151 @@ mint_serve_process_config (const char *mint_directory) (unsigned int) TALER_CURRENCY_LEN); return GNUNET_SYSERR; } + if (NULL != mint_wireformat) + GNUNET_CONFIGURATION_set_value_string (cfg, + "mint", + "wireformat", + mint_wireformat); + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_string (cfg, + "mint", + "wireformat", + &type)) + { + GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, + "mint", + "wireformat"); + return GNUNET_SYSERR; + } if (NULL == (db_plugin = TALER_MINTDB_plugin_load (cfg))) { fprintf (stderr, "Failed to initialize DB subsystem\n"); + GNUNET_free (type); + return GNUNET_SYSERR; + } + + if (NULL == + (wire_plugin = TALER_WIRE_plugin_load (cfg, + type))) + { + fprintf (stderr, + "Failed to load wire plugin for `%s'\n", + type); + GNUNET_free (type); return GNUNET_SYSERR; } + GNUNET_free (type); return GNUNET_OK; } +/** + * Function called with details about deposits that have been made, + * with the goal of executing the corresponding wire transaction. + * + * @param cls closure + * @param id transaction ID (used as future `min_id` to avoid + * iterating over transactions more than once) + * @param amount_with_fee amount that was deposited including fee + * @param deposit_fee amount the mint gets to keep as transaction fees + * @param transaction_id unique transaction ID chosen by the merchant + * @param h_contract hash of the contract between merchant and customer + * @param wire_deadline by which the merchant adviced that he would like the + * wire transfer to be executed + * @param wire wire details for the merchant + * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop + */ +static int +deposit_cb (void *cls, + uint64_t id, + const struct TALER_Amount *amount_with_fee, + const struct TALER_Amount *deposit_fee, + uint64_t transaction_id, + const struct GNUNET_HashCode *h_contract, + struct GNUNET_TIME_Absolute wire_deadline, + const json_t *wire) +{ + /* FIXME: compute aggregates, etc. */ + return GNUNET_OK; +} + + +/** + * Main work function that queries the DB and executes transactions. + */ +static void +run (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + int *global_ret = cls; + struct TALER_MINTDB_Session *session; + int ret; + + if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) + return; + if (NULL == (session = db_plugin->get_session (db_plugin->cls, + GNUNET_NO))) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Failed to obtain database session!\n"); + *global_ret = GNUNET_SYSERR; + return; + } + if (GNUNET_OK != + db_plugin->start (db_plugin->cls, + session)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Failed to start database transaction!\n"); + *global_ret = GNUNET_SYSERR; + return; + } + ret = db_plugin->iterate_deposits (db_plugin->cls, + session, + 0 /* FIXME: remove? */, + 128 /* FIXME: make configurable? */, + &deposit_cb, + NULL); + if (GNUNET_OK != ret) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Failed to execute deposit iteration!\n"); + *global_ret = GNUNET_SYSERR; + db_plugin->rollback (db_plugin->cls, + session); + return; + } + /* FIXME: finish aggregate computation */ + /* FIXME: insert pre-commit data for transaction into DB */ + /* FIXME: mark transactions selected for aggregate as finished */ + + if (GNUNET_OK != + db_plugin->commit (db_plugin->cls, + session)) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Failed to commit database transaction!\n"); + } + + /* FIXME: run 2nd transaction: + - begin + - select pre-commit data from DB + - execute wire transfer + - insert aggregation tracking information into DB + - commit! + */ + + + task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS /* FIXME: adjust! */, + &run, + global_ret); +} + + /** * The main function of the taler-mint-httpd server ("the mint"). * @@ -112,11 +261,14 @@ main (int argc, {'d', "mint-dir", "DIR", "mint directory with configuration and keys for operating the mint", 1, &GNUNET_GETOPT_set_filename, &mint_directory}, + {'f', "format", "WIREFORMAT", + "wireformat to use, overrides WIREFORMAT option in [mint] section", 1, + &GNUNET_GETOPT_set_filename, &mint_wireformat}, TALER_GETOPT_OPTION_HELP ("background process that aggregates and executes wire transfers to merchants"), GNUNET_GETOPT_OPTION_VERSION (VERSION "-" VCS_VERSION), GNUNET_GETOPT_OPTION_END }; - int ret; + int ret = GNUNET_OK; GNUNET_assert (GNUNET_OK == GNUNET_log_setup ("taler-mint-aggregator", @@ -133,14 +285,16 @@ main (int argc, "Mint directory not specified\n"); return 1; } - if (GNUNET_OK != mint_serve_process_config (mint_directory)) + { return 1; + } - + GNUNET_SCHEDULER_run (&run, &ret); TALER_MINTDB_plugin_unload (db_plugin); + TALER_WIRE_plugin_unload (wire_plugin); return (GNUNET_SYSERR == ret) ? 1 : 0; } diff --git a/src/wire/Makefile.am b/src/wire/Makefile.am index 528d91014..fb6f25616 100644 --- a/src/wire/Makefile.am +++ b/src/wire/Makefile.am @@ -15,6 +15,9 @@ plugin_LTLIBRARIES = \ noinst_LTLIBRARIES = \ libtaler_plugin_wire_template.la +lib_LTLIBRARIES = \ + libtalerwire.la + libtaler_plugin_wire_test_la_SOURCES = \ plugin_wire_test.c @@ -47,6 +50,15 @@ libtaler_plugin_wire_template_la_LDFLAGS = \ -lgnunetutil $(XLIB) +libtalerwire_la_SOURCES = \ + wire.c +libtalerwire_la_LIBADD = \ + -lgnunetutil + $(XLIB) +libtalerwire_la_LDFLAGS = \ + -version-info 0:0:0 \ + -export-dynamic -no-undefined + TESTS = \ test_sepa_wireformat @@ -61,4 +73,5 @@ test_sepa_wireformat_SOURCES = \ test_sepa_wireformat_LDADD = \ -lgnunetutil \ -ljansson \ + libtalerwire.la \ $(top_builddir)/src/util/libtalerutil.la diff --git a/src/wire/test_sepa_wireformat.c b/src/wire/test_sepa_wireformat.c index 958aac260..edbe5bc45 100644 --- a/src/wire/test_sepa_wireformat.c +++ b/src/wire/test_sepa_wireformat.c @@ -22,7 +22,7 @@ #include "platform.h" #include "taler_util.h" -#include "taler_wire_plugin.h" +#include "taler_wire_lib.h" /* Valid SEPA data */ @@ -62,51 +62,6 @@ static const char * const unsupported_wire_str = \"address\": \"foobar\"}"; -/** - * Initialize the plugin. - * - * @param cfg configuration to use - * @return #GNUNET_OK on success - */ -static struct TALER_WIRE_Plugin * -wire_plugin_load (const struct GNUNET_CONFIGURATION_Handle *cfg, - const char *plugin_name) -{ - char *lib_name; - struct TALER_WIRE_Plugin *plugin; - - (void) GNUNET_asprintf (&lib_name, - "libtaler_plugin_wire_%s", - plugin_name); - plugin = GNUNET_PLUGIN_load (lib_name, - (void *) cfg); - if (NULL != plugin) - plugin->library_name = lib_name; - else - GNUNET_free (lib_name); - return plugin; -} - - -/** - * Shutdown the plugin. - * - * @param plugin the plugin to unload - */ -static void -wire_plugin_unload (struct TALER_WIRE_Plugin *plugin) -{ - char *lib_name; - - if (NULL == plugin) - return; - lib_name = plugin->library_name; - GNUNET_assert (NULL == GNUNET_PLUGIN_unload (lib_name, - plugin)); - GNUNET_free (lib_name); -} - - int main(int argc, const char *const argv[]) @@ -125,8 +80,8 @@ main(int argc, "mint", "currency", "EUR"); - plugin = wire_plugin_load (cfg, - "sepa"); + plugin = TALER_WIRE_plugin_load (cfg, + "sepa"); GNUNET_assert (NULL != plugin); (void) memset(&error, 0, sizeof(error)); GNUNET_assert (NULL != (wire = json_loads (unsupported_wire_str, 0, NULL))); @@ -141,7 +96,7 @@ main(int argc, GNUNET_assert (NULL != (wire = json_loads (valid_wire_str, 0, &error))); ret = plugin->wire_validate (wire); json_decref (wire); - wire_plugin_unload (plugin); + TALER_WIRE_plugin_unload (plugin); GNUNET_CONFIGURATION_destroy (cfg); if (GNUNET_NO == ret) return 1; -- cgit v1.2.3