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/mint/Makefile.am | 1 + src/mint/taler-mint-aggregator.c | 164 +++++++++++++++++++++++++++++++++++++-- 2 files changed, 160 insertions(+), 5 deletions(-) (limited to 'src/mint') 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; } -- cgit v1.2.3