From 83631bc98fe70dd73f212581fb54ab3a82560686 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Thu, 12 Mar 2020 10:11:24 +0100 Subject: split reserve closing from main aggregation logic --- src/exchangedb/Makefile.am | 3 +- src/exchangedb/exchangedb_accounts.c | 161 +++++++++++++++++++++++++++++++++++ src/exchangedb/exchangedb_fees.c | 83 ++++++++++++++++++ 3 files changed, 245 insertions(+), 2 deletions(-) (limited to 'src/exchangedb') diff --git a/src/exchangedb/Makefile.am b/src/exchangedb/Makefile.am index aa681918b..c3d0b4302 100644 --- a/src/exchangedb/Makefile.am +++ b/src/exchangedb/Makefile.am @@ -56,11 +56,10 @@ libtalerexchangedb_la_SOURCES = \ exchangedb_plugin.c \ exchangedb_signkeys.c \ exchangedb_transactions.c - libtalerexchangedb_la_LIBADD = \ + $(top_builddir)/src/bank-lib/libtalerbank.la \ $(top_builddir)/src/util/libtalerutil.la \ -lgnunetutil $(XLIB) - libtalerexchangedb_la_LDFLAGS = \ $(POSTGRESQL_LDFLAGS) \ -version-info 1:0:0 \ diff --git a/src/exchangedb/exchangedb_accounts.c b/src/exchangedb/exchangedb_accounts.c index 2943adb24..db23eafca 100644 --- a/src/exchangedb/exchangedb_accounts.c +++ b/src/exchangedb/exchangedb_accounts.c @@ -22,6 +22,17 @@ #include "taler_exchangedb_lib.h" +/** + * Head of list of wire accounts of the exchange. + */ +static struct TALER_EXCHANGEDB_WireAccount *wa_head; + +/** + * Tail of list of wire accounts of the exchange. + */ +static struct TALER_EXCHANGEDB_WireAccount *wa_tail; + + /** * Closure of #check_for_account. */ @@ -141,4 +152,154 @@ TALER_EXCHANGEDB_find_accounts (const struct GNUNET_CONFIGURATION_Handle *cfg, } +/** + * Find the wire plugin for the given payto:// URL + * + * @param method wire method we need an account for + * @return NULL on error + */ +struct TALER_EXCHANGEDB_WireAccount * +TALER_EXCHANGEDB_find_account_by_method (const char *method) +{ + for (struct TALER_EXCHANGEDB_WireAccount *wa = wa_head; NULL != wa; wa = + wa->next) + if (0 == strcmp (method, + wa->method)) + return wa; + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "No wire account known for method `%s'\n", + method); + return NULL; +} + + +/** + * Find the wire plugin for the given payto:// URL + * + * @param url wire address we need an account for + * @return NULL on error + */ +struct TALER_EXCHANGEDB_WireAccount * +TALER_EXCHANGEDB_find_account_by_payto_uri (const char *url) +{ + char *method; + struct TALER_EXCHANGEDB_WireAccount *wa; + + method = TALER_payto_get_method (url); + if (NULL == method) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Invalid payto:// URL `%s'\n", + url); + return NULL; + } + wa = TALER_EXCHANGEDB_find_account_by_method (method); + GNUNET_free (method); + return wa; +} + + +/** + * Function called with information about a wire account. Adds + * the account to our list. + * + * @param cls closure, a `struct GNUNET_CONFIGURATION_Handle` + * @param ai account information + */ +static void +add_account_cb (void *cls, + const struct TALER_EXCHANGEDB_AccountInfo *ai) +{ + const struct GNUNET_CONFIGURATION_Handle *cfg = cls; + struct TALER_EXCHANGEDB_WireAccount *wa; + char *payto_uri; + + (void) cls; + if (GNUNET_YES != ai->debit_enabled) + return; /* not enabled for us, skip */ + wa = GNUNET_new (struct TALER_EXCHANGEDB_WireAccount); + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_string (cfg, + ai->section_name, + "PAYTO_URI", + &payto_uri)) + { + GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, + ai->section_name, + "PAYTO_URI"); + GNUNET_free (wa); + return; + } + wa->method = TALER_payto_get_method (payto_uri); + if (NULL == wa->method) + { + GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, + ai->section_name, + "PAYTO_URI", + "could not obtain wire method from URI"); + GNUNET_free (wa); + return; + } + GNUNET_free (payto_uri); + if (GNUNET_OK != + TALER_BANK_auth_parse_cfg (cfg, + ai->section_name, + &wa->auth)) + { + GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, + "Failed to load exchange account `%s'\n", + ai->section_name); + GNUNET_free (wa->method); + GNUNET_free (wa); + return; + } + wa->section_name = GNUNET_strdup (ai->section_name); + GNUNET_CONTAINER_DLL_insert (wa_head, + wa_tail, + wa); +} + + +/** + * Load account information opf the exchange from + * @a cfg. + * + * @param cfg configuration to load from + * @return #GNUNET_OK on success, #GNUNET_NO if no accounts are configured + */ +int +TALER_EXCHANGEDB_load_accounts (const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + TALER_EXCHANGEDB_find_accounts (cfg, + &add_account_cb, + (void *) cfg); + if (NULL == wa_head) + return GNUNET_NO; + return GNUNET_OK; +} + + +/** + * Free resources allocated by + * #TALER_EXCHANGEDB_load_accounts(). + */ +void +TALER_EXCHANGEDB_unload_accounts (void) +{ + struct TALER_EXCHANGEDB_WireAccount *wa; + + while (NULL != (wa = wa_head)) + { + GNUNET_CONTAINER_DLL_remove (wa_head, + wa_tail, + wa); + TALER_BANK_auth_free (&wa->auth); + TALER_EXCHANGEDB_fees_free (wa->af); + GNUNET_free (wa->section_name); + GNUNET_free (wa->method); + GNUNET_free (wa); + } +} + + /* end of exchangedb_accounts.c */ diff --git a/src/exchangedb/exchangedb_fees.c b/src/exchangedb/exchangedb_fees.c index 75bb13cef..070f16eee 100644 --- a/src/exchangedb/exchangedb_fees.c +++ b/src/exchangedb/exchangedb_fees.c @@ -326,4 +326,87 @@ TALER_EXCHANGEDB_fees_free (struct TALER_EXCHANGEDB_AggregateFees *af) } +/** + * Find the record valid at time @a now in the fee structure. + * + * @param wa wire transfer fee data structure to update + * @param now timestamp to update fees to + * @return fee valid at @a now, or NULL if unknown + */ +static struct TALER_EXCHANGEDB_AggregateFees * +advance_fees (struct TALER_EXCHANGEDB_WireAccount *wa, + struct GNUNET_TIME_Absolute now) +{ + struct TALER_EXCHANGEDB_AggregateFees *af; + + af = wa->af; + while ( (NULL != af) && + (af->end_date.abs_value_us < now.abs_value_us) ) + af = af->next; + return af; +} + + +/** + * Update wire transfer fee data structure in @a wa. + * + * @param cfg configuration to use + * @param db_plugin database plugin to use + * @param wa wire account data structure to update + * @param now timestamp to update fees to + * @param session DB session to use + * @return fee valid at @a now, or NULL if unknown + */ +struct TALER_EXCHANGEDB_AggregateFees * +TALER_EXCHANGEDB_update_fees (const struct GNUNET_CONFIGURATION_Handle *cfg, + struct TALER_EXCHANGEDB_Plugin *db_plugin, + struct TALER_EXCHANGEDB_WireAccount *wa, + struct GNUNET_TIME_Absolute now, + struct TALER_EXCHANGEDB_Session *session) +{ + enum GNUNET_DB_QueryStatus qs; + struct TALER_EXCHANGEDB_AggregateFees *af; + + af = advance_fees (wa, + now); + if (NULL != af) + return af; + /* Let's try to load it from disk... */ + wa->af = TALER_EXCHANGEDB_fees_read (cfg, + wa->method); + for (struct TALER_EXCHANGEDB_AggregateFees *p = wa->af; + NULL != p; + p = p->next) + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Persisting fees starting at %s in database\n", + GNUNET_STRINGS_absolute_time_to_string (p->start_date)); + qs = db_plugin->insert_wire_fee (db_plugin->cls, + session, + wa->method, + p->start_date, + p->end_date, + &p->wire_fee, + &p->closing_fee, + &p->master_sig); + if (qs < 0) + { + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + TALER_EXCHANGEDB_fees_free (wa->af); + wa->af = NULL; + return NULL; + } + } + af = advance_fees (wa, + now); + if (NULL != af) + return af; + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Failed to find current wire transfer fees for `%s' at %s\n", + wa->method, + GNUNET_STRINGS_absolute_time_to_string (now)); + return NULL; +} + + /* end of exchangedb_fees.c */ -- cgit v1.2.3