gnunet-svn
[Top][All Lists]
Advanced

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

[taler-anastasis] branch master updated: try to fix truth upload logic:


From: gnunet
Subject: [taler-anastasis] branch master updated: try to fix truth upload logic: store success status, and on resuming possibly retry upload
Date: Wed, 17 Mar 2021 18:45:07 +0100

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

grothoff pushed a commit to branch master
in repository anastasis.

The following commit(s) were added to refs/heads/master by this push:
     new 91a7eff  try to fix truth upload logic: store success status, and on 
resuming possibly retry upload
91a7eff is described below

commit 91a7eff05106573893d32ebfc588c404e8820a39
Author: Christian Grothoff <grothoff@gnunet.org>
AuthorDate: Wed Mar 17 18:44:50 2021 +0100

    try to fix truth upload logic: store success status, and on resuming 
possibly retry upload
---
 src/backend/anastasis-httpd_truth_upload.c |  12 ++
 src/include/anastasis.h                    |  29 ++++
 src/lib/anastasis_backup.c                 |  98 ++++++++---
 src/reducer/anastasis_api_backup_redux.c   | 266 +++++++++++++++++++++--------
 4 files changed, 309 insertions(+), 96 deletions(-)

diff --git a/src/backend/anastasis-httpd_truth_upload.c 
b/src/backend/anastasis-httpd_truth_upload.c
index 64e7088..1082fe8 100644
--- a/src/backend/anastasis-httpd_truth_upload.c
+++ b/src/backend/anastasis-httpd_truth_upload.c
@@ -197,6 +197,9 @@ make_payment_request (struct TruthUploadContext *tuc)
                   MHD_add_response_header (resp,
                                            ANASTASIS_HTTP_HEADER_TALER,
                                            hdr));
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "TRUTH payment request made: %s\n",
+                hdr);
     GNUNET_free (hdr);
   }
   tuc->resp = resp;
@@ -546,7 +549,16 @@ AH_handler_truth_post (
         if ( (0 == qs) ||
              (0 ==
               GNUNET_TIME_absolute_get_remaining (paid_until).rel_value_us) )
+        {
+          GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                      "TRUTH payment require!\n");
           return begin_payment (tuc);
+        }
+        GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                    "TRUTH paid until %llu (%d)!\n",
+                    (unsigned long long) GNUNET_TIME_absolute_get_remaining (
+                      paid_until).rel_value_us,
+                    qs);
       }
     }
 
diff --git a/src/include/anastasis.h b/src/include/anastasis.h
index d6cac02..ca277d8 100644
--- a/src/include/anastasis.h
+++ b/src/include/anastasis.h
@@ -649,6 +649,35 @@ ANASTASIS_truth_upload2 (struct GNUNET_CURL_Context *ctx,
                          void *tc_cls);
 
 
+/**
+ * Retries upload of truth data to an escrow provider using an
+ * existing truth object. If payment is required, it is requested via
+ * the @a tc callback.
+ *
+ * @param ctx the CURL context used to connect to the backend
+ * @param user_id user identifier derived from user data and backend salt
+ * @param[in] t truth details, reference is consumed
+ * @param truth_data contains the truth for this challenge i.e. phone number, 
email address
+ * @param truth_data_size size of the data
+ * @param payment_requested true if the client wants to pay more for the 
account now
+ * @param paid_order_id payment identifier of last payment
+ * @param pay_timeout how long to wait for payment
+ * @param tc opens the truth callback which contains the status of the upload
+ * @param tc_cls closure for the callback
+ */
+struct ANASTASIS_TruthUpload *
+ANASTASIS_truth_upload3 (struct GNUNET_CURL_Context *ctx,
+                         const struct ANASTASIS_CRYPTO_UserIdentifierP 
*user_id,
+                         struct ANASTASIS_Truth *t,
+                         const void *truth_data,
+                         size_t truth_data_size,
+                         bool payment_requested,
+                         const struct ANASTASIS_PaymentSecretP *paid_order_id,
+                         struct GNUNET_TIME_Relative pay_timeout,
+                         ANASTASIS_TruthCallback tc,
+                         void *tc_cls);
+
+
 /**
  * Cancels a truth upload process.
  *
diff --git a/src/lib/anastasis_backup.c b/src/lib/anastasis_backup.c
index 429a36e..10ccd2e 100644
--- a/src/lib/anastasis_backup.c
+++ b/src/lib/anastasis_backup.c
@@ -225,28 +225,35 @@ truth_store_callback (void *cls,
 }
 
 
+/**
+ * Retries upload of truth data to an escrow provider using an
+ * existing truth object. If payment is required, it is requested via
+ * the @a tc callback.
+ *
+ * @param ctx the CURL context used to connect to the backend
+ * @param user_id user identifier derived from user data and backend salt
+ * @param[in] t truth details, reference is consumed
+ * @param truth_data contains the truth for this challenge i.e. phone number, 
email address
+ * @param truth_data_size size of the data
+ * @param payment_requested true if the client wants to pay more for the 
account now
+ * @param paid_order_id payment identifier of last payment
+ * @param pay_timeout how long to wait for payment
+ * @param tc opens the truth callback which contains the status of the upload
+ * @param tc_cls closure for the callback
+ */
 struct ANASTASIS_TruthUpload *
-ANASTASIS_truth_upload2 (struct GNUNET_CURL_Context *ctx,
+ANASTASIS_truth_upload3 (struct GNUNET_CURL_Context *ctx,
                          const struct ANASTASIS_CRYPTO_UserIdentifierP 
*user_id,
-                         const char *provider_url,
-                         const char *type,
-                         const char *instructions,
-                         const char *mime_type,
-                         const struct ANASTASIS_CRYPTO_PowSalt *provider_salt,
+                         struct ANASTASIS_Truth *t,
                          const void *truth_data,
                          size_t truth_data_size,
                          bool payment_requested,
                          const struct ANASTASIS_PaymentSecretP *paid_order_id,
                          struct GNUNET_TIME_Relative pay_timeout,
-                         const struct ANASTASIS_CRYPTO_TruthUUIDP *uuid,
-                         const struct ANASTASIS_CRYPTO_PowSalt *salt,
-                         const struct ANASTASIS_CRYPTO_TruthKeyP *truth_key,
-                         const struct ANASTASIS_CRYPTO_KeyShareP *key_share,
                          ANASTASIS_TruthCallback tc,
                          void *tc_cls)
 {
   struct ANASTASIS_TruthUpload *tu;
-  struct ANASTASIS_Truth *t;
   struct ANASTASIS_CRYPTO_EncryptedKeyShareP encrypted_key_share;
   struct GNUNET_HashCode nt;
   void *encrypted_truth;
@@ -259,26 +266,12 @@ ANASTASIS_truth_upload2 (struct GNUNET_CURL_Context *ctx,
   tu->id = *user_id;
   tu->tc = tc;
   tu->tc_cls = tc_cls;
-  t = GNUNET_new (struct ANASTASIS_Truth);
-  t->url = GNUNET_strdup (provider_url);
-  t->type = GNUNET_strdup (type);
-  t->instructions = (NULL != instructions)
-    ? GNUNET_strdup (instructions)
-    : NULL;
-  t->mime_type = (NULL != mime_type)
-    ? GNUNET_strdup (mime_type)
-    : NULL;
-  t->provider_salt = *provider_salt;
   tu->t = t;
-  t->salt = *salt;
-  t->uuid = *uuid;
-  t->truth_key = *truth_key;
-  t->key_share = *key_share;
   ANASTASIS_CRYPTO_keyshare_encrypt (&t->key_share,
                                      &tu->id,
                                      &encrypted_key_share);
   if (0 == strcmp ("question",
-                   type))
+                   t->type))
   {
     char *answer;
 
@@ -310,9 +303,9 @@ ANASTASIS_truth_upload2 (struct GNUNET_CURL_Context *ctx,
   tu->tso = ANASTASIS_truth_store (tu->ctx,
                                    t->url,
                                    &t->uuid,
-                                   type,
+                                   t->type,
                                    &encrypted_key_share,
-                                   mime_type,
+                                   t->mime_type,
                                    encrypted_truth_size,
                                    encrypted_truth,
                                    payment_requested,
@@ -332,6 +325,55 @@ ANASTASIS_truth_upload2 (struct GNUNET_CURL_Context *ctx,
 }
 
 
+struct ANASTASIS_TruthUpload *
+ANASTASIS_truth_upload2 (struct GNUNET_CURL_Context *ctx,
+                         const struct ANASTASIS_CRYPTO_UserIdentifierP 
*user_id,
+                         const char *provider_url,
+                         const char *type,
+                         const char *instructions,
+                         const char *mime_type,
+                         const struct ANASTASIS_CRYPTO_PowSalt *provider_salt,
+                         const void *truth_data,
+                         size_t truth_data_size,
+                         bool payment_requested,
+                         const struct ANASTASIS_PaymentSecretP *paid_order_id,
+                         struct GNUNET_TIME_Relative pay_timeout,
+                         const struct ANASTASIS_CRYPTO_TruthUUIDP *uuid,
+                         const struct ANASTASIS_CRYPTO_PowSalt *salt,
+                         const struct ANASTASIS_CRYPTO_TruthKeyP *truth_key,
+                         const struct ANASTASIS_CRYPTO_KeyShareP *key_share,
+                         ANASTASIS_TruthCallback tc,
+                         void *tc_cls)
+{
+  struct ANASTASIS_Truth *t;
+
+  t = GNUNET_new (struct ANASTASIS_Truth);
+  t->url = GNUNET_strdup (provider_url);
+  t->type = GNUNET_strdup (type);
+  t->instructions = (NULL != instructions)
+    ? GNUNET_strdup (instructions)
+    : NULL;
+  t->mime_type = (NULL != mime_type)
+    ? GNUNET_strdup (mime_type)
+    : NULL;
+  t->provider_salt = *provider_salt;
+  t->salt = *salt;
+  t->uuid = *uuid;
+  t->truth_key = *truth_key;
+  t->key_share = *key_share;
+  return ANASTASIS_truth_upload3 (ctx,
+                                  user_id,
+                                  t,
+                                  truth_data,
+                                  truth_data_size,
+                                  payment_requested,
+                                  paid_order_id,
+                                  pay_timeout,
+                                  tc,
+                                  tc_cls);
+}
+
+
 struct ANASTASIS_TruthUpload *
 ANASTASIS_truth_upload (struct GNUNET_CURL_Context *ctx,
                         const struct ANASTASIS_CRYPTO_UserIdentifierP *user_id,
diff --git a/src/reducer/anastasis_api_backup_redux.c 
b/src/reducer/anastasis_api_backup_redux.c
index ea43203..dd31284 100644
--- a/src/reducer/anastasis_api_backup_redux.c
+++ b/src/reducer/anastasis_api_backup_redux.c
@@ -1285,6 +1285,11 @@ struct UploadContext
    */
   struct TruthUpload *tues_tail;
 
+  /**
+   * Timeout to use for the operation, from the arguments.
+   */
+  struct GNUNET_TIME_Relative timeout;
+
 };
 
 
@@ -1885,6 +1890,7 @@ truth_upload_cb (void *cls,
                  const struct ANASTASIS_UploadDetails *ud)
 {
   struct TruthUpload *tue = cls;
+  json_t *policies;
 
   tue->tu = NULL;
   tue->t = t;
@@ -1895,6 +1901,27 @@ truth_upload_cb (void *cls,
       ud->details.payment.payment_request);
     tue->ps = ud->details.payment.ps;
   }
+  /* persist upload status for later */
+  policies = json_object_get (tue->uc->state,
+                              "policies");
+  for (unsigned int i = 0; i<tue->policies_length; i++)
+  {
+    const struct PolicyMethodReference *pmr = &tue->policies[i];
+    json_t *policy = json_array_get (policies,
+                                     pmr->policy_index);
+    json_t *methods = json_object_get (policy,
+                                       "methods");
+    json_t *method = json_array_get (methods,
+                                     pmr->method_index);
+
+    GNUNET_assert (NULL != policy);
+    GNUNET_assert (NULL != methods);
+    GNUNET_assert (NULL != method);
+    GNUNET_assert (0 ==
+                   json_object_set_new (method,
+                                        "upload_status",
+                                        json_integer (ud->us)));
+  }
   check_upload_finished (tue->uc);
 }
 
@@ -1911,69 +1938,157 @@ truth_upload_cb (void *cls,
  *                     the truth to, used to check for existing entries
  * @param am_idx index of the authentication method, used to check for 
existing entries
  * @param[in] truth object representing already uploaded truth, reference 
captured!
+ * @param must_upload true if the upload was not yet completed and should be 
attempted
+ * @param[in,out] async_truth pointer to counter with the number of ongoing 
uploads,
+ *                updated
+ * @param auth_method object with the challenge details, to generate the truth
  * @return #GNUNET_SYSERR error requiring abort,
- *         #GNUNET_NO if truth uploads remain unchanged (@a pmr was only 
appended)
- *         #GNUNET_OK if an existing truth upload was cancelled (!)
+ *         #GNUNET_OK on success
  */
 static int
 add_truth_object (struct UploadContext *uc,
                   const struct PolicyMethodReference *pmr,
                   const char *provider_url,
                   uint32_t am_idx,
-                  json_t *truth)
+                  json_t *truth,
+                  bool must_upload,
+                  unsigned int *async_truth,
+                  json_t *auth_method)
 {
   /* check if we are already uploading this truth */
+  struct TruthUpload *tue;
+
+  for (tue = uc->tues_head;
+       NULL != tue;
+       tue = tue->next)
   {
-    for (struct TruthUpload *tue = uc->tues_head;
-         NULL != tue;
-         tue = tue->next)
+    if ( (0 == strcmp (tue->provider_url,
+                       provider_url)) &&
+         (am_idx == tue->am_idx) )
     {
-      if ( (0 == strcmp (tue->provider_url,
-                         provider_url)) &&
-           (am_idx == tue->am_idx) )
-      {
-        GNUNET_array_append (tue->policies,
-                             tue->policies_length,
-                             *pmr);
-        if (NULL == tue->t)
-        {
-          if (NULL != tue->tu)
-          {
-            ANASTASIS_truth_upload_cancel (tue->tu);
-            tue->tu = NULL;
-            return GNUNET_OK;
-          }
-        }
-        else
-        {
-          json_decref (truth);
-        }
-        return GNUNET_NO;
-      }
+      GNUNET_array_append (tue->policies,
+                           tue->policies_length,
+                           *pmr);
+      break;
     }
   }
 
-  /* Create new entry */
+  if (NULL == tue)
   {
-    struct TruthUpload *tue = GNUNET_new (struct TruthUpload);
+    /* Create new entry */
+    tue = GNUNET_new (struct TruthUpload);
 
     GNUNET_CONTAINER_DLL_insert (uc->tues_head,
                                  uc->tues_tail,
                                  tue);
-    tue->t = ANASTASIS_truth_from_json (truth);
-    if (NULL == tue->t)
-    {
-      GNUNET_break (0);
-      return GNUNET_SYSERR;
-    }
     tue->uc = uc;
     tue->policies = GNUNET_new (struct PolicyMethodReference);
     *tue->policies = *pmr;
     tue->provider_url = GNUNET_strdup (provider_url);
     tue->am_idx = am_idx;
     tue->policies_length = 1;
-    return GNUNET_NO;
   }
+
+  if (NULL == tue->t)
+  {
+    tue->t = ANASTASIS_truth_from_json (truth);
+    if (NULL == tue->t)
+    {
+      GNUNET_break (0);
+      return GNUNET_SYSERR;
+    }
+  }
+
+  if ( (NULL != tue->tu) &&
+       (! must_upload) )
+  {
+    ANASTASIS_truth_upload_cancel (tue->tu);
+    (*async_truth)--;
+    tue->tu = NULL;
+    return GNUNET_OK;
+  }
+
+  if ( (NULL == tue->tu) &&
+       (must_upload) )
+  {
+    struct ANASTASIS_CRYPTO_PowSalt salt;
+    struct ANASTASIS_CRYPTO_UserIdentifierP id;
+    bool force_payment = false;
+    void *truth_data;
+    size_t truth_data_size;
+    const char *payment_request = NULL;
+    struct GNUNET_JSON_Specification spec[] = {
+      GNUNET_JSON_spec_mark_optional (
+        GNUNET_JSON_spec_bool ("force_pay",
+                               &force_payment)),
+      GNUNET_JSON_spec_mark_optional (
+        GNUNET_JSON_spec_string ("payment_request",
+                                 &payment_request)),
+      GNUNET_JSON_spec_mark_optional (
+        GNUNET_JSON_spec_fixed_auto ("payment_secret",
+                                     &tue->ps)),
+      GNUNET_JSON_spec_varsize ("challenge",
+                                &truth_data,
+                                &truth_data_size),
+      GNUNET_JSON_spec_end ()
+    };
+
+    if (GNUNET_OK !=
+        lookup_salt (uc->state,
+                     provider_url,
+                     &salt))
+    {
+      GNUNET_break (0);
+      return GNUNET_SYSERR;
+    }
+    if (GNUNET_OK !=
+        GNUNET_JSON_parse (auth_method,
+                           spec,
+                           NULL, NULL))
+    {
+      json_dumpf (auth_method,
+                  stderr,
+                  JSON_INDENT (2));
+      GNUNET_break (0);
+      return GNUNET_SYSERR;
+    }
+    {
+      json_t *user_id;
+
+      user_id = json_object_get (uc->state,
+                                 "identity_attributes");
+      if (! json_is_object (user_id))
+      {
+        GNUNET_break (0);
+        return GNUNET_SYSERR;
+      }
+      ANASTASIS_CRYPTO_user_identifier_derive (user_id,
+                                               &salt,
+                                               &id);
+    }
+    tue->tu = ANASTASIS_truth_upload3 (ANASTASIS_REDUX_ctx_,
+                                       &id,
+                                       tue->t,
+                                       truth_data,
+                                       truth_data_size,
+                                       force_payment,
+                                       &tue->ps,
+                                       uc->timeout,
+                                       &truth_upload_cb,
+                                       tue);
+    GNUNET_JSON_parse_free (spec);
+    tue->t = NULL;
+    (*async_truth)++;
+  }
+
+  if ( (NULL != tue->tu) &&
+       (NULL != tue->t) )
+  {
+    /* no point in having both */
+    ANASTASIS_truth_free (tue->t);
+    tue->t = NULL;
+  }
+  return GNUNET_OK;
 }
 
 
@@ -2001,7 +2116,6 @@ check_truth_upload (struct UploadContext *uc,
                     json_t *auth_method)
 {
   json_t *user_id;
-  struct GNUNET_TIME_Relative timeout = GNUNET_TIME_UNIT_ZERO;
   json_t *jtruth;
 
   user_id = json_object_get (uc->state,
@@ -2028,31 +2142,6 @@ check_truth_upload (struct UploadContext *uc,
     }
   }
 
-  {
-    json_t *args;
-    struct GNUNET_JSON_Specification pspec[] = {
-      GNUNET_JSON_spec_mark_optional (
-        GNUNET_JSON_spec_relative_time ("timeout",
-                                        &timeout)),
-      GNUNET_JSON_spec_end ()
-    };
-
-    args = json_object_get (uc->state,
-                            "pay-arguments");
-    if ( (NULL != args) &&
-         (GNUNET_OK !=
-          GNUNET_JSON_parse (args,
-                             pspec,
-                             NULL, NULL)) )
-    {
-      json_dumpf (args,
-                  stderr,
-                  JSON_INDENT (2));
-      GNUNET_break (0);
-      return GNUNET_SYSERR;
-    }
-  }
-
   {
     json_t *policies = json_object_get (uc->state,
                                         "policies");
@@ -2172,7 +2261,7 @@ check_truth_upload (struct UploadContext *uc,
                                           (NULL != payment_request)
                                           ? &tue->ps
                                           : NULL,
-                                          timeout,
+                                          uc->timeout,
                                           &truth_upload_cb,
                                           tue);
       }
@@ -2191,7 +2280,7 @@ check_truth_upload (struct UploadContext *uc,
                                            (NULL != payment_request)
                                           ? &tue->ps
                                           : NULL,
-                                           timeout,
+                                           uc->timeout,
                                            &uuid,
                                            &salt,
                                            &truth_key,
@@ -2261,6 +2350,37 @@ upload (json_t *state,
   uc->cb = cb;
   uc->cb_cls = cb_cls;
   uc->state = json_incref (state);
+
+  {
+    json_t *args;
+    struct GNUNET_JSON_Specification pspec[] = {
+      GNUNET_JSON_spec_mark_optional (
+        GNUNET_JSON_spec_relative_time ("timeout",
+                                        &uc->timeout)),
+      GNUNET_JSON_spec_end ()
+    };
+
+    args = json_object_get (uc->state,
+                            "pay-arguments");
+    if ( (NULL != args) &&
+         (GNUNET_OK !=
+          GNUNET_JSON_parse (args,
+                             pspec,
+                             NULL, NULL)) )
+    {
+      json_dumpf (args,
+                  stderr,
+                  JSON_INDENT (2));
+      GNUNET_break (0);
+      ANASTASIS_redux_fail_ (cb,
+                             cb_cls,
+                             TALER_EC_ANASTASIS_REDUCER_INPUT_INVALID,
+                             "'timeout' must be valid delay");
+
+      return NULL;
+    }
+  }
+
   {
     json_t *policy;
     size_t pindex;
@@ -2288,11 +2408,15 @@ upload (json_t *state,
         uint32_t am_idx;
         const char *provider_url;
         json_t *truth = NULL;
+        uint32_t status = UINT32_MAX;
         struct GNUNET_JSON_Specification spec[] = {
           GNUNET_JSON_spec_string ("provider",
                                    &provider_url),
           GNUNET_JSON_spec_uint32 ("authentication_method",
                                    &am_idx),
+          GNUNET_JSON_spec_mark_optional (
+            GNUNET_JSON_spec_uint32 ("upload_status",
+                                     &status)),
           GNUNET_JSON_spec_mark_optional (
             GNUNET_JSON_spec_json ("truth",
                                    &truth)),
@@ -2327,6 +2451,7 @@ upload (json_t *state,
                                    TALER_EC_ANASTASIS_REDUCER_STATE_INVALID,
                                    "'authentication_method' refers to invalid 
authorization index malformed");
             upload_cancel_cb (uc);
+            GNUNET_JSON_parse_free (spec);
             return NULL;
           }
           if (NULL == truth)
@@ -2340,6 +2465,7 @@ upload (json_t *state,
                                       amj);
             if (GNUNET_SYSERR == ret)
             {
+              GNUNET_JSON_parse_free (spec);
               ANASTASIS_redux_fail_ (cb,
                                      cb_cls,
                                      TALER_EC_ANASTASIS_REDUCER_STATE_INVALID,
@@ -2352,24 +2478,28 @@ upload (json_t *state,
           else
           {
             int ret;
+            bool must_upload = (ANASTASIS_US_SUCCESS != status);
 
             ret = add_truth_object (uc,
                                     &pmr,
                                     provider_url,
                                     am_idx,
-                                    truth);
+                                    truth,
+                                    must_upload,
+                                    &async_truth,
+                                    amj);
             if (GNUNET_SYSERR == ret)
             {
+              GNUNET_JSON_parse_free (spec);
               ANASTASIS_redux_fail_ (cb,
                                      cb_cls,
                                      TALER_EC_ANASTASIS_REDUCER_STATE_INVALID,
                                      NULL);
               return NULL;
             }
-            if (GNUNET_OK == ret)
-              async_truth--;
           }
         }
+        GNUNET_JSON_parse_free (spec);
       } /* end for all methods of policy */
     } /* end for all policies */
     if (async_truth > 0)

-- 
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]