gnunet-svn
[Top][All Lists]
Advanced

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

[taler-merchant] branch master updated: add merchant backend support for


From: gnunet
Subject: [taler-merchant] branch master updated: add merchant backend support for STEFAN curves
Date: Thu, 24 Aug 2023 22:09:18 +0200

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

grothoff pushed a commit to branch master
in repository merchant.

The following commit(s) were added to refs/heads/master by this push:
     new b4dbf7bc add merchant backend support for STEFAN curves
b4dbf7bc is described below

commit b4dbf7bcf38e183c0ddd39b48e911221bdd9d36c
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Thu Aug 24 22:09:13 2023 +0200

    add merchant backend support for STEFAN curves
---
 src/backend/taler-merchant-httpd_exchanges.h       |   2 +
 .../taler-merchant-httpd_private-post-orders.c     | 211 +++++++++++++++------
 src/testing/test_kyc_api.conf                      |   1 +
 src/testing/test_merchant_api.conf                 |   1 +
 4 files changed, 154 insertions(+), 61 deletions(-)

diff --git a/src/backend/taler-merchant-httpd_exchanges.h 
b/src/backend/taler-merchant-httpd_exchanges.h
index b0f2d879..d8202922 100644
--- a/src/backend/taler-merchant-httpd_exchanges.h
+++ b/src/backend/taler-merchant-httpd_exchanges.h
@@ -125,6 +125,7 @@ void
 TMH_exchange_get_trusted (TMH_ExchangeCallback cb,
                           void *cb_cls);
 
+
 /**
  * Return the master public key of the given @a exchange.
  * Will be returned from configuration for trusted
@@ -137,6 +138,7 @@ const struct TALER_MasterPublicKeyP *
 TMH_EXCHANGES_get_master_pub (
   const struct TMH_Exchange *exchange);
 
+
 /**
  * Lookup current wire fee by @a exchange_url and
  * @a wire_method.
diff --git a/src/backend/taler-merchant-httpd_private-post-orders.c 
b/src/backend/taler-merchant-httpd_private-post-orders.c
index 370050d4..409c3eec 100644
--- a/src/backend/taler-merchant-httpd_private-post-orders.c
+++ b/src/backend/taler-merchant-httpd_private-post-orders.c
@@ -175,6 +175,24 @@ struct OrderContext
    */
   json_t *order;
 
+  /**
+   * Maximum fee for @e order based on STEFAN curves.
+   * Used to set @e max_fee if not provided as part of
+   * @e order.
+   */
+  struct TALER_Amount max_stefan_fee;
+
+  /**
+   * Maximum fee as given by the client request.
+   */
+  struct TALER_Amount max_fee;
+
+  /**
+   * Gross amount value of the contract. Used to
+   * compute @e max_stefan_fee.
+   */
+  struct TALER_Amount brutto;
+
   /**
    * Array of exchanges we find acceptable for this
    * order.
@@ -265,6 +283,7 @@ struct OrderContext
     ORDER_PHASE_ADD_PAYMENT_DETAILS,
     ORDER_PHASE_PATCH_ORDER,
     ORDER_PHASE_SET_EXCHANGES,
+    ORDER_PHASE_SET_MAX_FEE,
     ORDER_PHASE_CHECK_CONTRACT,
     ORDER_PHASE_EXECUTE_ORDER,
 
@@ -532,7 +551,6 @@ execute_order (struct OrderContext *oc)
 {
   const struct TALER_MERCHANTDB_InstanceSettings *settings =
     &oc->hc->instance->settings;
-  struct TALER_Amount total;
   const char *summary;
   const char *fulfillment_msg = NULL;
   const json_t *products;
@@ -541,9 +559,6 @@ execute_order (struct OrderContext *oc)
   struct GNUNET_TIME_Timestamp refund_deadline = { 0 };
   struct GNUNET_TIME_Timestamp wire_transfer_deadline;
   struct GNUNET_JSON_Specification spec[] = {
-    TALER_JSON_spec_amount ("amount",
-                            TMH_currency,
-                            &total),
     GNUNET_JSON_spec_string ("order_id",
                              &oc->order_id),
     TALER_JSON_spec_i18n_str ("summary",
@@ -856,6 +871,47 @@ check_contract (struct OrderContext *oc)
 }
 
 
+/**
+ * Update MAX STEFAN fees based on @a keys.
+ *
+ * @param[in,out] oc order context to update
+ * @param keys keys to derive STEFAN fees from
+ */
+static void
+update_stefan (struct OrderContext *oc,
+               const struct TALER_EXCHANGE_Keys *keys)
+{
+  struct TALER_Amount net;
+
+  if (0 == keys->num_denom_keys)
+    sleep (600);
+  if (GNUNET_SYSERR !=
+      TALER_EXCHANGE_keys_stefan_b2n (keys,
+                                      &oc->brutto,
+                                      &net))
+  {
+    struct TALER_Amount fee;
+
+    TALER_EXCHANGE_keys_stefan_round (keys,
+                                      &net);
+    GNUNET_assert (0 <=
+                   TALER_amount_subtract (&fee,
+                                          &oc->brutto,
+                                          &net));
+    if ( (GNUNET_OK !=
+          TALER_amount_is_valid (&oc->max_stefan_fee)) ||
+         (-1 == TALER_amount_cmp (&oc->max_stefan_fee,
+                                  &fee)) )
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                  "Updated STEFAN-based fee to %s\n",
+                  TALER_amount2s (&fee));
+      oc->max_stefan_fee = fee;
+    }
+  }
+}
+
+
 /**
  * Compute the set of exchanges that would be acceptable
  * for this order.
@@ -918,13 +974,15 @@ get_acceptable (void *cls,
  * @param exchange representation of the exchange
  */
 static void
-keys_forced (
+keys_cb (
   void *cls,
   struct TALER_EXCHANGE_Keys *keys,
   struct TMH_Exchange *exchange)
 {
   struct RekeyExchange *rx = cls;
   struct OrderContext *oc = rx->oc;
+  const struct TALER_MERCHANTDB_InstanceSettings *settings =
+    &oc->hc->instance->settings;
 
   rx->fo = NULL;
   GNUNET_CONTAINER_DLL_remove (oc->pending_reload_head,
@@ -936,6 +994,14 @@ keys_forced (
                 "Failed to download %s/keys\n",
                 rx->url);
   }
+  else
+  {
+    if ( (settings->use_stefan) &&
+         (GNUNET_OK !=
+          TALER_amount_is_valid (&oc->max_fee)) )
+      update_stefan (oc,
+                     keys);
+  }
   get_acceptable (oc,
                   rx->url,
                   exchange);
@@ -966,9 +1032,9 @@ keys_forced (
  * @param exchange internal handle for the exchange
  */
 static void
-rekey_exchanges (void *cls,
-                 const char *url,
-                 const struct TMH_Exchange *exchange)
+get_exchange_keys (void *cls,
+                   const char *url,
+                   const struct TMH_Exchange *exchange)
 {
   struct OrderContext *oc = cls;
   struct RekeyExchange *rx;
@@ -983,12 +1049,48 @@ rekey_exchanges (void *cls,
               "Forcing download of %s/keys\n",
               url);
   rx->fo = TMH_EXCHANGES_keys4exchange (url,
-                                        true,
-                                        &keys_forced,
+                                        oc->forced_reload,
+                                        &keys_cb,
                                         rx);
 }
 
 
+/**
+ * Set max_fee in @a oc based on STEFAN value if
+ * not yet present.
+ *
+ * @param[in,out] oc order context
+ */
+static void
+set_max_fee (struct OrderContext *oc)
+{
+  const struct TALER_MERCHANTDB_InstanceSettings *settings =
+    &oc->hc->instance->settings;
+
+  if (GNUNET_OK !=
+      TALER_amount_is_valid (&oc->max_fee))
+  {
+    struct TALER_Amount stefan;
+
+    if ( (settings->use_stefan) &&
+         (GNUNET_OK ==
+          TALER_amount_is_valid (&oc->max_stefan_fee)) )
+      stefan = oc->max_stefan_fee;
+    else
+      GNUNET_assert (GNUNET_OK ==
+                     TALER_amount_set_zero (TMH_currency,
+                                            &stefan));
+    GNUNET_assert (0 ==
+                   json_object_set_new (
+                     oc->order,
+                     "max_fee",
+                     TALER_JSON_from_amount (&stefan)));
+  }
+
+  oc->phase++;
+}
+
+
 /**
  * Set list of acceptable exchanges in @a oc.
  *
@@ -1002,41 +1104,46 @@ set_exchanges (struct OrderContext *oc)
      expensive; could likely consider caching the result if it starts to
      matter. */
   if (NULL == oc->exchanges)
+  {
     oc->exchanges = json_array ();
-  TMH_exchange_get_trusted (&get_acceptable,
-                            oc);
-  if (! oc->exchange_good)
+    TMH_exchange_get_trusted (&get_exchange_keys,
+                              oc);
+  }
+  else if (! oc->exchange_good)
   {
     if (! oc->forced_reload)
     {
       oc->forced_reload = true;
       GNUNET_assert (0 ==
                      json_array_clear (oc->exchanges));
-      TMH_exchange_get_trusted (&rekey_exchanges,
+      TMH_exchange_get_trusted (&get_exchange_keys,
                                 oc);
     }
-    if (NULL != oc->pending_reload_head)
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-                  "Still trying to re-load /keys\n");
-      MHD_suspend_connection (oc->connection);
-      oc->suspended = GNUNET_YES;
-      GNUNET_CONTAINER_DLL_insert (oc_head,
-                                   oc_tail,
-                                   oc);
-      return true; /* reloads pending */
-    }
-    if (0 == json_array_size (oc->exchanges))
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                  "Cannot create order: lacking trusted exchanges\n");
-      reply_with_error (
-        oc,
-        MHD_HTTP_CONFLICT,
-        TALER_EC_MERCHANT_PRIVATE_POST_ORDERS_NO_EXCHANGES_FOR_WIRE_METHOD,
-        oc->wm->wire_method);
-      return false;
-    }
+  }
+  if (NULL != oc->pending_reload_head)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                "Still trying to re-load /keys\n");
+    MHD_suspend_connection (oc->connection);
+    oc->suspended = GNUNET_YES;
+    GNUNET_CONTAINER_DLL_insert (oc_head,
+                                 oc_tail,
+                                 oc);
+    return true; /* reloads pending */
+  }
+  if (0 == json_array_size (oc->exchanges))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                "Cannot create order: lacking trusted exchanges\n");
+    reply_with_error (
+      oc,
+      MHD_HTTP_CONFLICT,
+      TALER_EC_MERCHANT_PRIVATE_POST_ORDERS_NO_EXCHANGES_FOR_WIRE_METHOD,
+      oc->wm->wire_method);
+    return false;
+  }
+  if (! oc->exchange_good)
+  {
     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                 "Creating order, but possibly without usable trusted 
exchanges\n");
   }
@@ -1066,7 +1173,6 @@ patch_order (struct OrderContext *oc)
   const char *merchant_base_url = NULL;
   const json_t *jmerchant = NULL;
   const json_t *delivery_location = NULL;
-  struct TALER_Amount max_fee = { 0 };
   struct GNUNET_TIME_Timestamp timestamp
     = GNUNET_TIME_UNIT_ZERO_TS;
   struct GNUNET_TIME_Timestamp delivery_date
@@ -1092,6 +1198,9 @@ patch_order (struct OrderContext *oc)
       GNUNET_JSON_spec_string ("order_id",
                                &order_id),
       NULL),
+    TALER_JSON_spec_amount ("amount",
+                            TMH_currency,
+                            &oc->brutto),
     GNUNET_JSON_spec_mark_optional (
       GNUNET_JSON_spec_string ("fulfillment_url",
                                &fulfillment_url),
@@ -1115,7 +1224,7 @@ patch_order (struct OrderContext *oc)
     GNUNET_JSON_spec_mark_optional (
       TALER_JSON_spec_amount ("max_fee",
                               TMH_currency,
-                              &max_fee),
+                              &oc->max_fee),
       NULL),
     GNUNET_JSON_spec_mark_optional (
       GNUNET_JSON_spec_timestamp ("delivery_date",
@@ -1352,29 +1461,6 @@ patch_order (struct OrderContext *oc)
     return;
   }
 
-  /* Note: total amount currency match checked
-     later in execute_order() */
-  if (GNUNET_OK !=
-      TALER_amount_is_valid (&max_fee))
-  {
-    struct TALER_Amount stefan;
-
-    GNUNET_assert (GNUNET_OK ==
-                   TALER_amount_set_zero (TMH_currency,
-                                          &stefan));
-    if (settings->use_stefan)
-    {
-      /* FIXME: update amount from stefan curve! */
-      stefan.value = 5; // FIXME!
-    }
-
-    GNUNET_assert (0 ==
-                   json_object_set_new (
-                     oc->order,
-                     "max_fee",
-                     TALER_JSON_from_amount (&stefan)));
-  }
-
   if (NULL == merchant_base_url)
   {
     char *url;
@@ -1868,6 +1954,9 @@ TMH_private_post_orders_with_pos_secrets (
       if (set_exchanges (oc))
         return MHD_YES;
       break;
+    case ORDER_PHASE_SET_MAX_FEE:
+      set_max_fee (oc);
+      break;
     case ORDER_PHASE_CHECK_CONTRACT:
       check_contract (oc);
       break;
diff --git a/src/testing/test_kyc_api.conf b/src/testing/test_kyc_api.conf
index f8b7f59f..50195ae0 100644
--- a/src/testing/test_kyc_api.conf
+++ b/src/testing/test_kyc_api.conf
@@ -37,6 +37,7 @@ AML_THRESHOLD = EUR:1000000
 PORT = 8081
 MASTER_PUBLIC_KEY = T1VVFQZZARQ1CMF4BN58EE7SKTW5AV2BS18S87ZEGYS4S29J6DNG
 BASE_URL = "http://localhost:8081/";
+STEFAN_ABS = "EUR:5"
 
 [kyc-provider-test-oauth2]
 COST = 0
diff --git a/src/testing/test_merchant_api.conf 
b/src/testing/test_merchant_api.conf
index e2d88afe..9a9c1297 100644
--- a/src/testing/test_merchant_api.conf
+++ b/src/testing/test_merchant_api.conf
@@ -33,6 +33,7 @@ AML_THRESHOLD = EUR:1000000
 PORT = 8081
 MASTER_PUBLIC_KEY = T1VVFQZZARQ1CMF4BN58EE7SKTW5AV2BS18S87ZEGYS4S29J6DNG
 BASE_URL = "http://localhost:8081/";
+STEFAN_ABS = "EUR:5"
 
 [exchangedb-postgres]
 CONFIG = "postgres:///talercheck"

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