gnunet-svn
[Top][All Lists]
Advanced

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

[taler-anastasis] branch master updated: -implement provider_sync transi


From: gnunet
Subject: [taler-anastasis] branch master updated: -implement provider_sync transition
Date: Fri, 21 Jan 2022 18:56:01 +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 77ccde7  -implement provider_sync transition
77ccde7 is described below

commit 77ccde74a92c64f5fb4d164b67effd26e244c123
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Fri Jan 21 18:55:19 2022 +0100

    -implement provider_sync transition
---
 src/reducer/anastasis_api_recovery_redux.c | 321 ++++++++++++++++++++---------
 1 file changed, 220 insertions(+), 101 deletions(-)

diff --git a/src/reducer/anastasis_api_recovery_redux.c 
b/src/reducer/anastasis_api_recovery_redux.c
index 791ed9f..86f05e4 100644
--- a/src/reducer/anastasis_api_recovery_redux.c
+++ b/src/reducer/anastasis_api_recovery_redux.c
@@ -1888,6 +1888,221 @@ select_challenge (json_t *state,
 }
 
 
+/**
+ * Main data structure for sync_providers().
+ */
+struct MasterSync;
+
+
+/**
+ * Data structure for one provider we are syncing /config with.
+ */
+struct SyncEntry
+{
+  /**
+   * Kept in a DLL.
+   */
+  struct SyncEntry *next;
+
+  /**
+   * Kept in a DLL.
+   */
+  struct SyncEntry *prev;
+
+  /**
+   * Sync operation we are part of.
+   */
+  struct MasterSync *ms;
+
+  /**
+   * Redux action for this provider.
+   */
+  struct ANASTASIS_ReduxAction *ra;
+};
+
+/**
+ * Main data structure for sync_providers().
+ */
+struct MasterSync
+{
+  /**
+   * Our own sync action we expose externally.
+   */
+  struct ANASTASIS_ReduxAction ra;
+  /**
+   * Head of DLL with entries per provider.
+   */
+  struct SyncEntry *se_head;
+  /**
+   * Tail of DLL with entries per provider.
+   */
+  struct SyncEntry *se_tail;
+
+  /**
+   * Function to call with the result.
+   */
+  ANASTASIS_ActionCallback cb;
+
+  /**
+   * Closure for @e cb.
+   */
+  void *cb_cls;
+
+};
+
+
+/**
+ * Free @a cls data structure.
+ *
+ * @param[in] cls data structure to free, must be a `struct MasterSync *`
+ */
+static void
+clean_sync (void *cls)
+{
+  struct MasterSync *ms = cls;
+  struct SyncEntry *se;
+
+  while (NULL != (se = ms->se_head))
+  {
+    GNUNET_CONTAINER_DLL_remove (ms->se_head,
+                                 ms->se_tail,
+                                 se);
+    se->ra->cleanup (se->ra->cleanup_cls);
+    GNUNET_free (se);
+  }
+  GNUNET_free (ms);
+}
+
+
+/**
+ * Function called when we have made progress on any of the
+ * providers we are trying to sync with.
+ *
+ * @param cls closure
+ * @param error error code, #TALER_EC_NONE if @a new_bs is the new successful 
state
+ * @param new_state the new state of the operation (client should 
json_incref() to keep an alias)
+ */
+static void
+sync_progress (void *cls,
+               enum TALER_ErrorCode error,
+               json_t *new_state)
+{
+  struct SyncEntry *se = cls;
+  struct MasterSync *ms = se->ms;
+
+  ms->cb (ms->cb_cls,
+          error,
+          new_state);
+  clean_sync (ms);
+}
+
+
+/**
+ * Check if we have information on all providers involved in
+ * a recovery procedure, and if not, try to obtain it. Upon
+ * success, call @a cb with the updated provider status data.
+ *
+ * @param[in] state we are in
+ * @param arguments our arguments with the solution
+ * @param cb functiont o call with the new state
+ * @param cb_cls closure for @a cb
+ * @return handle to cancel challenge selection step
+ */
+static struct ANASTASIS_ReduxAction *
+sync_providers (json_t *state,
+                const json_t *arguments,
+                ANASTASIS_ActionCallback cb,
+                void *cb_cls)
+{
+  json_t *rd;
+  json_t *cs_arr;
+  struct MasterSync *ms;
+
+  rd = json_object_get (state,
+                        "recovery_document");
+  if (NULL == rd)
+  {
+    GNUNET_break (0);
+    ANASTASIS_redux_fail_ (cb,
+                           cb_cls,
+                           TALER_EC_ANASTASIS_REDUCER_STATE_INVALID,
+                           "'recovery_document' missing");
+    return NULL;
+  }
+  cs_arr = json_object_get (rd,
+                            "cs");
+  if (! json_is_array (cs_arr))
+  {
+    GNUNET_break_op (0);
+    ANASTASIS_redux_fail_ (cb,
+                           cb_cls,
+                           TALER_EC_ANASTASIS_REDUCER_STATE_INVALID,
+                           "'recovery_document' must be an array");
+    return NULL;
+  }
+  ms = GNUNET_new (struct MasterSync);
+  ms->cb = cb;
+  ms->cb_cls = cb_cls;
+  {
+    json_t *cs;
+    unsigned int n_index;
+
+    json_array_foreach (cs_arr, n_index, cs)
+    {
+      const char *provider_url;
+      struct GNUNET_JSON_Specification spec[] = {
+        GNUNET_JSON_spec_string ("url",
+                                 &provider_url),
+        GNUNET_JSON_spec_end ()
+      };
+      struct ANASTASIS_CRYPTO_ProviderSaltP salt;
+      struct SyncEntry *se;
+
+      if (GNUNET_OK !=
+          GNUNET_JSON_parse (cs,
+                             spec,
+                             NULL, NULL))
+      {
+        GNUNET_break_op (0);
+        ANASTASIS_redux_fail_ (cb,
+                               cb_cls,
+                               TALER_EC_ANASTASIS_REDUCER_STATE_INVALID,
+                               "'recovery_document' missing");
+        clean_sync (ms);
+        return NULL;
+      }
+      if (GNUNET_OK ==
+          ANASTASIS_reducer_lookup_salt_ (state,
+                                          provider_url,
+                                          &salt))
+        continue; /* provider already ready */
+      se = GNUNET_new (struct SyncEntry);
+      se->ms = ms;
+      GNUNET_CONTAINER_DLL_insert (ms->se_head,
+                                   ms->se_tail,
+                                   se);
+      se->ra = ANASTASIS_REDUX_add_provider_to_state_ (provider_url,
+                                                       state,
+                                                       &sync_progress,
+                                                       se);
+    }
+  }
+  if (NULL == ms->se_head)
+  {
+    /* everything already synced */
+    clean_sync (ms);
+    ANASTASIS_redux_fail_ (cb,
+                           cb_cls,
+                           TALER_EC_ANASTASIS_REDUCER_ACTION_INVALID,
+                           "already in sync");
+    return NULL;
+  }
+  ms->ra.cleanup = &clean_sync;
+  ms->ra.cleanup_cls = ms;
+  return &ms->ra;
+}
+
+
 /**
  * The user pressed "back" during challenge solving.
  * Transition back to selecting another challenge.
@@ -2013,104 +2228,6 @@ return_no_policy (struct PolicyDownloadEntry *pd,
 }
 
 
-/**
- * Determine recovery @a cost of solving a challenge of type @a type
- * at @a provider_url by inspecting @a state.
- *
- * @param state the state to inspect
- * @param provider_url the provider to lookup config info from
- * @param type the method to lookup the cost of
- * @param[out] cost the recovery cost to return
- * @param[out] ec set to the error code
- * @return #GNUNET_OK on success, #GNUNET_NO if not found, #GNUNET_SYSERR on 
state error
- */
-static enum GNUNET_GenericReturnValue
-lookup_cost (const json_t *state,
-             const char *provider_url,
-             const char *type,
-             struct TALER_Amount *cost,
-             enum TALER_ErrorCode *ec)
-{
-  const json_t *providers;
-  const json_t *provider;
-  const json_t *methods;
-
-  *ec = TALER_EC_NONE;
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-              "Looking up cost for provider `%s' and method `%s'\n",
-              provider_url,
-              type);
-  providers = json_object_get (state,
-                               "authentication_providers");
-  if (NULL == providers)
-  {
-    *ec = TALER_EC_ANASTASIS_REDUCER_STATE_INVALID;
-    GNUNET_break (0);
-    return GNUNET_SYSERR;
-  }
-  provider = json_object_get (providers,
-                              provider_url);
-  if (NULL == provider)
-  {
-    *ec = TALER_EC_ANASTASIS_REDUCER_STATE_INVALID;
-    GNUNET_break (0);
-    return GNUNET_SYSERR;
-  }
-  if (MHD_HTTP_OK !=
-      json_integer_value (json_object_get (provider,
-                                           "http_status")))
-  {
-    json_t *eco;
-
-    eco = json_object_get (provider,
-                           "error_code");
-    if (NULL != eco)
-      *ec = json_integer_value (eco);
-    else
-      *ec = TALER_EC_ANASTASIS_REDUCER_PROVIDER_INVALID_CONFIG;
-    return GNUNET_NO;
-  }
-  methods = json_object_get (provider,
-                             "methods");
-  if ( (NULL == methods) ||
-       (! json_is_array (methods)) )
-  {
-    *ec = TALER_EC_ANASTASIS_REDUCER_STATE_INVALID;
-    GNUNET_break (0);
-    return GNUNET_SYSERR;
-  }
-  {
-    size_t index;
-    json_t *method;
-
-    json_array_foreach (methods, index, method) {
-      const char *t;
-      struct GNUNET_JSON_Specification spec[] = {
-        GNUNET_JSON_spec_string ("type",
-                                 &t),
-        TALER_JSON_spec_amount_any ("usage_fee",
-                                    cost),
-        GNUNET_JSON_spec_end ()
-      };
-
-      if (GNUNET_OK !=
-          GNUNET_JSON_parse (method,
-                             spec,
-                             NULL, NULL))
-      {
-        GNUNET_break (0);
-        *ec = TALER_EC_ANASTASIS_REDUCER_STATE_INVALID;
-        continue;
-      }
-      if (0 == strcmp (t,
-                       type))
-        return GNUNET_OK;
-    }
-  }
-  return GNUNET_NO; /* not found */
-}
-
-
 /**
  * Callback which passes back the recovery document and its possible
  * policies. Also passes back the version of the document for the user
@@ -2177,9 +2294,6 @@ policy_lookup_cb (void *cls,
     struct ANASTASIS_Challenge *c = ri->cs[i];
     const struct ANASTASIS_ChallengeDetails *cd;
     json_t *cj;
-    struct TALER_Amount cost;
-    enum GNUNET_GenericReturnValue ret;
-    enum TALER_ErrorCode ec;
 
     cd = ANASTASIS_challenge_get_details (c);
     cj = GNUNET_JSON_PACK (
@@ -2489,6 +2603,11 @@ ANASTASIS_recovery_action_ (json_t *state,
       "select_challenge",
       &select_challenge
     },
+    {
+      ANASTASIS_RECOVERY_STATE_CHALLENGE_SELECTING,
+      "sync_providers",
+      &sync_providers
+    },
     {
       ANASTASIS_RECOVERY_STATE_CHALLENGE_SELECTING,
       "poll",

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