diff options
| author | Christian Grothoff <christian@grothoff.org> | 2020-03-12 10:11:24 +0100 | 
|---|---|---|
| committer | Christian Grothoff <christian@grothoff.org> | 2020-03-12 10:11:24 +0100 | 
| commit | 83631bc98fe70dd73f212581fb54ab3a82560686 (patch) | |
| tree | 058fd4b741f2dc650da5aee21af61df3ddf3d98b /src/exchangedb | |
| parent | a1db41e09a618c3a9797242ee593da1331175c14 (diff) | |
split reserve closing from main aggregation logic
Diffstat (limited to 'src/exchangedb')
| -rw-r--r-- | src/exchangedb/Makefile.am | 3 | ||||
| -rw-r--r-- | src/exchangedb/exchangedb_accounts.c | 161 | ||||
| -rw-r--r-- | src/exchangedb/exchangedb_fees.c | 83 | 
3 files changed, 245 insertions, 2 deletions
| diff --git a/src/exchangedb/Makefile.am b/src/exchangedb/Makefile.am index aa681918..c3d0b430 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 2943adb2..db23eafc 100644 --- a/src/exchangedb/exchangedb_accounts.c +++ b/src/exchangedb/exchangedb_accounts.c @@ -23,6 +23,17 @@  /** + * 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.   */  struct FindAccountContext @@ -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 75bb13ce..070f16ee 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 */ | 
