gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-exchange] branch master updated: finish taler-exchange-drain impl


From: gnunet
Subject: [taler-exchange] branch master updated: finish taler-exchange-drain implementation
Date: Sat, 30 Jul 2022 22:54:27 +0200

This is an automated email from the git hooks/post-receive script.

grothoff pushed a commit to branch master
in repository exchange.

The following commit(s) were added to refs/heads/master by this push:
     new 15091769 finish taler-exchange-drain implementation
15091769 is described below

commit 150917694a4dc3709319fc9586e502eb4b05151f
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Sat Jul 30 22:54:21 2022 +0200

    finish taler-exchange-drain implementation
---
 src/exchange/taler-exchange-aggregator.c |   6 +-
 src/exchange/taler-exchange-drain.c      | 180 ++++++++++++++++++++++++++++---
 src/exchange/taler-exchange-httpd.c      |   6 +-
 src/include/taler_exchangedb_plugin.h    |  38 +++++++
 4 files changed, 213 insertions(+), 17 deletions(-)

diff --git a/src/exchange/taler-exchange-aggregator.c 
b/src/exchange/taler-exchange-aggregator.c
index 9568f011..3d30ccd0 100644
--- a/src/exchange/taler-exchange-aggregator.c
+++ b/src/exchange/taler-exchange-aggregator.c
@@ -234,12 +234,12 @@ shutdown_task (void *cls)
 
 
 /**
- * Parse the configuration for wirewatch.
+ * Parse the configuration for aggregator.
  *
  * @return #GNUNET_OK on success
  */
 static enum GNUNET_GenericReturnValue
-parse_wirewatch_config (void)
+parse_aggregator_config (void)
 {
   if (GNUNET_OK !=
       GNUNET_CONFIGURATION_get_value_string (cfg,
@@ -811,7 +811,7 @@ run (void *cls,
   (void) cfgfile;
 
   cfg = c;
-  if (GNUNET_OK != parse_wirewatch_config ())
+  if (GNUNET_OK != parse_aggregator_config ())
   {
     cfg = NULL;
     global_ret = EXIT_NOTCONFIGURED;
diff --git a/src/exchange/taler-exchange-drain.c 
b/src/exchange/taler-exchange-drain.c
index 71656412..d409487c 100644
--- a/src/exchange/taler-exchange-drain.c
+++ b/src/exchange/taler-exchange-drain.c
@@ -39,11 +39,21 @@ static const struct GNUNET_CONFIGURATION_Handle *cfg;
  */
 static struct TALER_EXCHANGEDB_Plugin *db_plugin;
 
+/**
+ * Our master public key.
+ */
+static struct TALER_MasterPublicKeyP master_pub;
+
 /**
  * Next task to run, if any.
  */
 static struct GNUNET_SCHEDULER_Task *task;
 
+/**
+ * Base URL of this exchange.
+ */
+static char *exchange_base_url;
+
 /**
  * Value to return from main(). 0 on success, non-zero on errors.
  */
@@ -82,6 +92,47 @@ shutdown_task (void *cls)
 static enum GNUNET_GenericReturnValue
 parse_drain_config (void)
 {
+  if (GNUNET_OK !=
+      GNUNET_CONFIGURATION_get_value_string (cfg,
+                                             "exchange",
+                                             "BASE_URL",
+                                             &exchange_base_url))
+  {
+    GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
+                               "exchange",
+                               "BASE_URL");
+    return GNUNET_SYSERR;
+  }
+
+  {
+    char *master_public_key_str;
+
+    if (GNUNET_OK !=
+        GNUNET_CONFIGURATION_get_value_string (cfg,
+                                               "exchange",
+                                               "MASTER_PUBLIC_KEY",
+                                               &master_public_key_str))
+    {
+      GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
+                                 "exchange",
+                                 "MASTER_PUBLIC_KEY");
+      return GNUNET_SYSERR;
+    }
+    if (GNUNET_OK !=
+        GNUNET_CRYPTO_eddsa_public_key_from_string (master_public_key_str,
+                                                    strlen (
+                                                      master_public_key_str),
+                                                    &master_pub.eddsa_pub))
+    {
+      GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
+                                 "exchange",
+                                 "MASTER_PUBLIC_KEY",
+                                 "invalid base32 encoding for a master public 
key");
+      GNUNET_free (master_public_key_str);
+      return GNUNET_SYSERR;
+    }
+    GNUNET_free (master_public_key_str);
+  }
   if (NULL ==
       (db_plugin = TALER_EXCHANGEDB_plugin_load (cfg)))
   {
@@ -134,6 +185,13 @@ static void
 run_drain (void *cls)
 {
   enum GNUNET_DB_QueryStatus qs;
+  uint64_t serial;
+  struct TALER_WireTransferIdentifierRawP wtid;
+  char *account_section;
+  char *payto_uri;
+  struct GNUNET_TIME_Timestamp request_timestamp;
+  struct TALER_Amount amount;
+  struct TALER_MasterSignatureP master_sig;
 
   (void) cls;
   task = NULL;
@@ -147,11 +205,14 @@ run_drain (void *cls)
     GNUNET_SCHEDULER_shutdown ();
     return;
   }
-#if 0
-  qs = db_plugin->profit_drains_get_pending (db_plugin->cls);
-#else
-  qs = -1;
-#endif
+  qs = db_plugin->profit_drains_get_pending (db_plugin->cls,
+                                             &serial,
+                                             &wtid,
+                                             &account_section,
+                                             &payto_uri,
+                                             &request_timestamp,
+                                             &amount,
+                                             &master_sig);
   switch (qs)
   {
   case GNUNET_DB_STATUS_HARD_ERROR:
@@ -161,7 +222,6 @@ run_drain (void *cls)
     GNUNET_SCHEDULER_shutdown ();
     return;
   case GNUNET_DB_STATUS_SOFT_ERROR:
-    /* try again */
     db_plugin->rollback (db_plugin->cls);
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                 "Serialization failure on simple SELECT!?\n");
@@ -169,7 +229,7 @@ run_drain (void *cls)
     GNUNET_SCHEDULER_shutdown ();
     return;
   case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
-    /* no more profit drains, go sleep a bit! */
+    /* no profit drains, finished */
     db_plugin->rollback (db_plugin->cls);
     GNUNET_assert (NULL == task);
     GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
@@ -180,11 +240,107 @@ run_drain (void *cls)
     /* continued below */
     break;
   }
-  // FIXME: check signature (again!)
-  // FIMXE: display for human check
-  // FIXME: insert into pre-wire
-  // FIXME: mark as done
-  // FIXME: commit transaction + report success + exit
+  /* Check signature (again, this is a critical operation!) */
+  if (GNUNET_OK !=
+      TALER_exchange_offline_profit_drain_verify (
+        &wtid,
+        request_timestamp,
+        &amount,
+        account_section,
+        payto_uri,
+        &master_pub,
+        &master_sig))
+  {
+    GNUNET_break (0);
+    global_ret = EXIT_FAILURE;
+    db_plugin->rollback (db_plugin->cls);
+    GNUNET_assert (NULL == task);
+    GNUNET_SCHEDULER_shutdown ();
+    return;
+  }
+
+  /* Display data for manual human check */
+  fprintf (stdout,
+           "Critical operation. MANUAL CHECK REQUIRED.\n");
+  fprintf (stdout,
+           "We will wire %s to `%s'\n based on instructions from %s.\n",
+           TALER_amount2s (&amount),
+           payto_uri,
+           GNUNET_TIME_timestamp2s (request_timestamp));
+  fprintf (stdout,
+           "Press ENTER to confirm, CTRL-D to abort.\n");
+  while (1)
+  {
+    int key;
+
+    key = getchar ();
+    if (EOF == key)
+    {
+      fprintf (stdout,
+               "Transfer aborted.\n"
+               "Re-run 'taler-exchange-drain' to try it again.\n"
+               "Contact Taler Systems SA to cancel it for good.\n"
+               "Exiting.\n");
+      db_plugin->rollback (db_plugin->cls);
+      GNUNET_assert (NULL == task);
+      GNUNET_SCHEDULER_shutdown ();
+      global_ret = EXIT_FAILURE;
+      return;
+    }
+    if ('\n' == key)
+      break;
+  }
+
+  /* Note: account_section ignored for now, we
+     might want to use it here in the future... */
+  (void) account_section;
+  {
+    char *method;
+    void *buf;
+    size_t buf_size;
+
+    TALER_BANK_prepare_transfer (payto_uri,
+                                 &amount,
+                                 exchange_base_url,
+                                 &wtid,
+                                 &buf,
+                                 &buf_size);
+    method = TALER_payto_get_method (payto_uri);
+    qs = db_plugin->wire_prepare_data_insert (db_plugin->cls,
+                                              method,
+                                              buf,
+                                              buf_size);
+    GNUNET_free (method);
+    GNUNET_free (buf);
+  }
+  qs = db_plugin->profit_drains_set_finished (db_plugin->cls,
+                                              serial);
+  switch (qs)
+  {
+  case GNUNET_DB_STATUS_HARD_ERROR:
+    db_plugin->rollback (db_plugin->cls);
+    GNUNET_break (0);
+    global_ret = EXIT_FAILURE;
+    GNUNET_SCHEDULER_shutdown ();
+    return;
+  case GNUNET_DB_STATUS_SOFT_ERROR:
+    db_plugin->rollback (db_plugin->cls);
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Failed: database serialization issue\n");
+    global_ret = EXIT_FAILURE;
+    GNUNET_SCHEDULER_shutdown ();
+    return;
+  case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
+    db_plugin->rollback (db_plugin->cls);
+    GNUNET_assert (NULL == task);
+    GNUNET_break (0);
+    GNUNET_SCHEDULER_shutdown ();
+    return;
+  default:
+    /* continued below */
+    break;
+  }
+  /* commit transaction + report success + exit */
   if (0 >= commit_or_warn ())
     GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
                 "Profit drain triggered. Exiting.\n");
diff --git a/src/exchange/taler-exchange-httpd.c 
b/src/exchange/taler-exchange-httpd.c
index 2d659058..14cc8c1c 100644
--- a/src/exchange/taler-exchange-httpd.c
+++ b/src/exchange/taler-exchange-httpd.c
@@ -1836,8 +1836,10 @@ exchange_serve_process_config (void)
                                                     &TEH_master_public_key.
                                                     eddsa_pub))
     {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  "Invalid master public key given in exchange 
configuration.");
+      GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
+                                 "exchange",
+                                 "MASTER_PUBLIC_KEY",
+                                 "invalid base32 encoding for a master public 
key");
       GNUNET_free (master_public_key_str);
       return GNUNET_SYSERR;
     }
diff --git a/src/include/taler_exchangedb_plugin.h 
b/src/include/taler_exchangedb_plugin.h
index 7f31752d..2ffa8486 100644
--- a/src/include/taler_exchangedb_plugin.h
+++ b/src/include/taler_exchangedb_plugin.h
@@ -5545,6 +5545,44 @@ struct TALER_EXCHANGEDB_Plugin
                          const struct TALER_MasterSignatureP *master_sig);
 
 
+  /**
+   * Get profit drain operation ready to execute.
+   *
+   * @param cls the @e cls of this struct with the plugin-specific state
+   * @param[out] serial set to serial ID of the entry
+   * @param[out] wtid set set to wire transfer ID to use
+   * @param[out] account_section set to  account to drain
+   * @param[out] payto_uri set to account to wire funds to
+   * @param[out] request_timestamp set to time of the signature
+   * @param[out] amount set to amount to wire
+   * @param[out] master_sig set to signature affirming the operation
+   * @return transaction status code
+   */
+  enum GNUNET_DB_QueryStatus
+  (*profit_drains_get_pending)(
+    void *cls,
+    uint64_t *serial,
+    struct TALER_WireTransferIdentifierRawP *wtid,
+    char **account_section,
+    char **payto_uri,
+    struct GNUNET_TIME_Timestamp *request_timestamp,
+    struct TALER_Amount *amount,
+    struct TALER_MasterSignatureP *master_sig);
+
+
+  /**
+   * Set profit drain operation to finished.
+   *
+   * @param cls the @e cls of this struct with the plugin-specific state
+   * @param serial serial ID of the entry to mark finished
+   * @return transaction status code
+   */
+  enum GNUNET_DB_QueryStatus
+  (*profit_drains_set_finished)(
+    void *cls,
+    uint64_t serial);
+
+
 };
 
 #endif /* _TALER_EXCHANGE_DB_H */

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]