summaryrefslogtreecommitdiff
path: root/src/exchangedb
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2020-03-12 10:11:24 +0100
committerChristian Grothoff <christian@grothoff.org>2020-03-12 10:11:24 +0100
commit83631bc98fe70dd73f212581fb54ab3a82560686 (patch)
tree058fd4b741f2dc650da5aee21af61df3ddf3d98b /src/exchangedb
parenta1db41e09a618c3a9797242ee593da1331175c14 (diff)
downloadexchange-83631bc98fe70dd73f212581fb54ab3a82560686.tar.gz
exchange-83631bc98fe70dd73f212581fb54ab3a82560686.tar.bz2
exchange-83631bc98fe70dd73f212581fb54ab3a82560686.zip
split reserve closing from main aggregation logic
Diffstat (limited to 'src/exchangedb')
-rw-r--r--src/exchangedb/Makefile.am3
-rw-r--r--src/exchangedb/exchangedb_accounts.c161
-rw-r--r--src/exchangedb/exchangedb_fees.c83
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 */