View Issue Details

IDProjectCategoryView StatusLast Update
0006830Anastasiscommand line toolspublic2021-04-11 17:28
ReporterChristian Grothoff Assigned To 
PrioritylowSeverityfeatureReproducibilityN/A
Status confirmedResolutionopen 
Platformi7OSDebian GNU/LinuxOS Versionsqueeze
Product VersionGit master 
Target Version0.2.0 
Summary0006830: re-implement cost-based selection
DescriptionThe attached diff shows the code that had to be retired when we went from single-currency to multi-currency support.
That said, IF multiple providers do use the same currency, we can and should still use the cheaper one if possible. So this code should be rewritten to select the cheapest provider per currency domain, instead of simply ignoring costs.
TagsNo tags attached.

Activities

Christian Grothoff

2021-04-02 21:26

manager  

cost.diff (10,524 bytes)   
diff --git a/src/reducer/anastasis_api_backup_redux.c b/src/reducer/anastasis_api_backup_redux.c
index b1c2543..ec80434 100644
--- a/src/reducer/anastasis_api_backup_redux.c
+++ b/src/reducer/anastasis_api_backup_redux.c
@@ -317,12 +317,6 @@ del_authentication (json_t *state,
  */
 struct PolicyBuilder
 {
-  /**
-   * Financial cost of the providers selected in @e best_sel.
-   * Only valid during the go_with() function.
-   */
-  struct TALER_Amount best_cost;
-
   /**
    * Authentication providers available overall, from our state.
    */
@@ -338,11 +332,6 @@ struct PolicyBuilder
    */
   json_t *policies;
 
-  /**
-   * Currency we are using.
-   */
-  const char *currency;
-
   /**
    * Array of length @e req_methods.
    */
@@ -397,14 +386,8 @@ static void
 eval_provider_selection (struct PolicyBuilder *pb,
                          const char *prov_sel[])
 {
-  struct TALER_Amount curr_cost;
   unsigned int curr_diversity;
 
-  /* most hold here, as invariant passed earlier in go_with() */
-  GNUNET_assert (GNUNET_OK ==
-                 TALER_amount_get_zero (pb->currency,
-                                        &curr_cost));
-
   /* calculate cost */
   for (unsigned int i = 0; i < pb->req_methods; i++)
   {
@@ -450,19 +433,6 @@ eval_provider_selection (struct PolicyBuilder *pb,
       if (0 == strcmp (type,
                        method_type))
       {
-        if ( (GNUNET_YES !=
-              TALER_amount_cmp_currency (&curr_cost,
-                                         &method_cost)) ||
-             (0 >
-              TALER_amount_add (&curr_cost,
-                                &curr_cost,
-                                &method_cost)) )
-        {
-          GNUNET_break (0);
-          pb->ec = TALER_EC_ANASTASIS_REDUCER_STATE_INVALID;
-          pb->hint = "'usage_fee' addition failure";
-          return;
-        }
         found = true;
       }
     }
@@ -493,17 +463,10 @@ eval_provider_selection (struct PolicyBuilder *pb,
   }
   if (curr_diversity < pb->best_diversity)
     return;
-  if ( (GNUNET_YES ==
-        TALER_amount_cmp_currency (&curr_cost,
-                                   &pb->best_cost)) &&
-       (0 < TALER_amount_cmp (&curr_cost,
-                              &pb->best_cost)) )
-    return;
   memcpy (pb->best_sel,
           prov_sel,
           sizeof (const char *) * pb->req_methods);
   pb->best_diversity = curr_diversity;
-  pb->best_cost = curr_cost;
 }
 
 
@@ -554,7 +517,6 @@ static void
 go_with (struct PolicyBuilder *pb)
 {
   const unsigned int *m_idx = pb->m_idx;
-  struct TALER_Amount recovery_cost;
   const char *best_sel[pb->req_methods];
   const char *prov_sel[pb->req_methods];
   json_t *method_arr;
@@ -562,28 +524,9 @@ go_with (struct PolicyBuilder *pb)
   /* compute best provider selection (store in best_sel) */
   pb->best_diversity = 0;
   pb->best_sel = best_sel;
-  memset (&pb->best_cost,
-          0,
-          sizeof (struct TALER_Amount));
   provider_candidate (pb,
                       prov_sel,
                       0);
-  if (GNUNET_OK !=
-      TALER_amount_get_zero (pb->currency,
-                             &recovery_cost))
-  {
-    pb->ec = TALER_EC_ANASTASIS_REDUCER_STATE_INVALID;
-    pb->hint = "'currency' invalid";
-    return;
-  }
-  if (GNUNET_OK !=
-      TALER_amount_is_valid (&pb->best_cost))
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Did not find providers supporting requested authorization methods\n");
-    return;
-  }
-
   /* Convert best_sel to entry in 'policies' array */
   method_arr = json_array ();
   GNUNET_assert (NULL != method_arr);
@@ -599,9 +542,7 @@ go_with (struct PolicyBuilder *pb)
                                           policy_method));
   }
   {
-    json_t *policy = json_pack ("{s:o, s:o}",
-                                "recovery_cost",
-                                TALER_JSON_from_amount (&pb->best_cost),
+    json_t *policy = json_pack ("{s:o}",
                                 "methods",
                                 method_arr);
     GNUNET_assert (NULL != policy);
@@ -667,16 +608,6 @@ done_authentication (json_t *state,
     .ec = TALER_EC_NONE
   };
 
-  pb.currency = json_string_value (json_object_get (state,
-                                                    "currency"));
-  if (NULL == pb.currency)
-  {
-    ANASTASIS_redux_fail_ (cb,
-                           cb_cls,
-                           TALER_EC_ANASTASIS_REDUCER_STATE_INVALID,
-                           "'currency' must be provided");
-    return NULL;
-  }
   pb.providers = json_object_get (state,
                                   "authentication_providers");
   if ( (NULL == pb.providers) ||
@@ -815,8 +746,6 @@ add_policy (json_t *state,
   const json_t *auth_providers;
   const json_t *auth_methods;
   json_t *methods;
-  struct TALER_Amount recovery_cost;
-  const char *currency;
 
   if (NULL == arguments)
   {
@@ -846,19 +775,6 @@ add_policy (json_t *state,
                            "'policies' not an array");
     return NULL;
   }
-  currency = json_string_value (json_object_get (state,
-                                                 "currency"));
-  if ( (NULL == currency) ||
-       (GNUNET_OK !=
-        TALER_amount_get_zero (currency,
-                               &recovery_cost)) )
-  {
-    ANASTASIS_redux_fail_ (cb,
-                           cb_cls,
-                           TALER_EC_ANASTASIS_REDUCER_STATE_INVALID,
-                           "'currency' must be a vaild currency");
-    return NULL;
-  }
   auth_providers = json_object_get (state,
                                     "authentication_providers");
   if (! json_is_object (auth_providers))
@@ -999,18 +915,6 @@ add_policy (json_t *state,
           if (0 != strcmp (type,
                            method_type))
             continue;
-          if (0 >
-              TALER_amount_add (&recovery_cost,
-                                &recovery_cost,
-                                &method_cost))
-          {
-            GNUNET_break (0);
-            ANASTASIS_redux_fail_ (cb,
-                                   cb_cls,
-                                   TALER_EC_ANASTASIS_REDUCER_STATE_INVALID,
-                                   "cost addition failed");
-            return NULL;
-          }
           found = true;
           break;
         }
@@ -1034,9 +938,7 @@ add_policy (json_t *state,
   {
     json_t *policy;
 
-    policy = json_pack ("{s:o, s:o}",
-                        "recovery_cost",
-                        TALER_JSON_from_amount (&recovery_cost),
+    policy = json_pack ("{s:o}",
                         "methods",
                         methods);
     GNUNET_assert (NULL != policy);
diff --git a/src/reducer/anastasis_api_redux.c b/src/reducer/anastasis_api_redux.c
index 1b449fc..73b781f 100644
--- a/src/reducer/anastasis_api_redux.c
+++ b/src/reducer/anastasis_api_redux.c
@@ -660,12 +660,12 @@ check_config (const char *url)
 /**
  * Begin asynchronous check for provider configurations.
  *
- * @param currency the currency to initiate the provider checks for
+ * @param currencies the currencies to initiate the provider checks for
  * @param[in,out] state to set provider list for
  * @return #TALER_EC_NONE on success
  */
 static enum TALER_ErrorCode
-begin_provider_config_check (const char *currency,
+begin_provider_config_check (const json_t *currencies,
                              json_t *state)
 {
   if (NULL == provider_list)
@@ -732,9 +732,27 @@ begin_provider_config_check (const char *currency,
         return TALER_EC_ANASTASIS_REDUCER_RESOURCE_MALFORMED;
       }
 
-      if (0 != strcasecmp (currency,
-                           cur))
-        continue;
+      {
+        bool found = false;
+        json_t *cu;
+        size_t off;
+
+        json_array_foreach (currencies, off, cu)
+        {
+          const char *currency;
+
+          currency = json_string_value (cu);
+          if (NULL == currency)
+          {
+            json_decref (pl);
+            return TALER_EC_ANASTASIS_REDUCER_INPUT_INVALID;
+          }
+          found = (0 == strcasecmp (currency,
+                                    cur));
+        }
+        if (! found)
+          continue;
+      }
       GNUNET_assert (0 ==
                      json_object_set_new (pl,
                                           url,
@@ -966,7 +984,7 @@ select_country (json_t *state,
 {
   const json_t *required_attrs;
   const json_t *country_code;
-  const char *currency;
+  const json_t *currencies;
   const json_t *redux_id_attr;
 
   if (NULL == arguments)
@@ -1016,14 +1034,15 @@ select_country (json_t *state,
     }
   }
 
-  currency = json_string_value (json_object_get (arguments,
-                                                 "currency"));
-  if (NULL == currency)
+  currencies = json_object_get (arguments,
+                                "currencies");
+  if ( (NULL == currencies) ||
+       (! json_is_array (currencies))  )
   {
     ANASTASIS_redux_fail_ (cb,
                            cb_cls,
                            TALER_EC_ANASTASIS_REDUCER_STATE_INVALID,
-                           "'currency' missing");
+                           "'currencies' missing");
     return NULL;
   }
   /* We now have an idea of the currency, begin fetching
@@ -1031,7 +1050,7 @@ select_country (json_t *state,
   {
     enum TALER_ErrorCode ec;
 
-    ec = begin_provider_config_check (currency,
+    ec = begin_provider_config_check (currencies,
                                       state);
     if (TALER_EC_NONE != ec)
     {
@@ -1039,7 +1058,7 @@ select_country (json_t *state,
       ANASTASIS_redux_fail_ (cb,
                              cb_cls,
                              ec,
-                             currency);
+                             NULL);
       return NULL;
     }
   }
@@ -1070,9 +1089,9 @@ select_country (json_t *state,
                                   "selected_country",
                                   (json_t *) country_code));
   GNUNET_assert (0 ==
-                 json_object_set_new (state,
-                                      "currency",
-                                      json_string (currency)));
+                 json_object_set (state,
+                                  "currencies",
+                                  (json_t *) currencies));
   GNUNET_assert (0 ==
                  json_object_set (state,
                                   "required_attributes",
cost.diff (10,524 bytes)   

Issue History

Date Modified Username Field Change
2021-04-02 21:26 Christian Grothoff New Issue
2021-04-02 21:26 Christian Grothoff File Added: cost.diff
2021-04-02 21:26 Christian Grothoff Status new => confirmed
2021-04-02 21:26 Christian Grothoff Target Version => 0.3.0
2021-04-11 17:28 Christian Grothoff Target Version 0.3.0 => 0.2.0