gnunet-svn
[Top][All Lists]
Advanced

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

[taler-exchange] branch master updated: complete taler-exchange-httpd_re


From: gnunet
Subject: [taler-exchange] branch master updated: complete taler-exchange-httpd_reserves_open.c logic (first pass, still without DB logic or tests)
Date: Sun, 02 Oct 2022 22:47:31 +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 4a36ed7f complete taler-exchange-httpd_reserves_open.c logic (first 
pass, still without DB logic or tests)
4a36ed7f is described below

commit 4a36ed7fbfcaa220d1b2605851b38fc1a386e7d3
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Sun Oct 2 22:47:28 2022 +0200

    complete taler-exchange-httpd_reserves_open.c logic (first pass, still 
without DB logic or tests)
---
 src/exchange/taler-exchange-httpd_reserves_open.c | 96 ++++++++++++++++++++---
 src/include/taler_crypto_lib.h                    | 12 +--
 src/include/taler_exchangedb_plugin.h             | 49 ++++++++++++
 src/lib/exchange_api_reserves_open.c              | 15 ++--
 src/util/wallet_signatures.c                      | 21 ++---
 5 files changed, 152 insertions(+), 41 deletions(-)

diff --git a/src/exchange/taler-exchange-httpd_reserves_open.c 
b/src/exchange/taler-exchange-httpd_reserves_open.c
index 2bc450ee..c9f5e401 100644
--- a/src/exchange/taler-exchange-httpd_reserves_open.c
+++ b/src/exchange/taler-exchange-httpd_reserves_open.c
@@ -83,6 +83,11 @@ struct ReserveOpenContext
    */
   struct TALER_Amount open_cost;
 
+  /**
+   * Total amount that was deposited.
+   */
+  struct TALER_Amount total;
+
   /**
    * Information about payments by coin.
    */
@@ -111,9 +116,16 @@ static MHD_RESULT
 reply_reserve_open_success (struct MHD_Connection *connection,
                             const struct ReserveOpenContext *rsc)
 {
+  unsigned int status;
+
+  status = MHD_HTTP_OK;
+  if (GNUNET_TIME_timestamp_cmp (rsc->reserve_expiration,
+                                 <,
+                                 rsc->desired_expiration))
+    status = MHD_HTTP_PAYMENT_REQUIRED;
   return TALER_MHD_REPLY_JSON_PACK (
     connection,
-    MHD_HTTP_OK,
+    status,
     GNUNET_JSON_pack_timestamp ("reserve_expiration",
                                 rsc->reserve_expiration),
     TALER_JSON_pack_amount ("open_cost",
@@ -150,7 +162,7 @@ cleanup_rsc (struct ReserveOpenContext *rsc)
  * @param cls a `struct ReserveOpenContext *`
  * @param connection MHD request which triggered the transaction
  * @param[out] mhd_ret set to MHD response status for @a connection,
- *             if transaction failed (!); unused
+ *             if transaction failed (!)
  * @return transaction status
  */
 static enum GNUNET_DB_QueryStatus
@@ -161,15 +173,63 @@ reserve_open_transaction (void *cls,
   struct ReserveOpenContext *rsc = cls;
   enum GNUNET_DB_QueryStatus qs;
 
-  (void) rsc;
-#if 0
-  // FIXME: implement!
+  for (unsigned int i = 0; i<rsc->payments_len; i++)
+  {
+    struct TEH_PurseDepositedCoin *coin = &rsc->payments[i];
+    bool insufficient_funds = true;
+
+    qs = TEH_make_coin_known (&coin->cpi,
+                              connection,
+                              &coin->known_coin_id,
+                              mhd_ret);
+    if (qs < 0)
+      return qs;
+    qs = TEH_plugin->insert_reserve_open_deposit (
+      TEH_plugin->cls,
+      &coin->cpi,
+      &coin->coin_sig,
+      coin->known_coin_id,
+      &coin->amount,
+      &rsc->reserve_sig,
+      &insufficient_funds);
+    /* 0 == qs is fine, then the coin was already
+       spent for this very operation as identified
+       by reserve_sig! */
+    if (qs < 0)
+    {
+      if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
+        return qs;
+      GNUNET_break (0);
+      *mhd_ret = TALER_MHD_reply_with_error (connection,
+                                             MHD_HTTP_INTERNAL_SERVER_ERROR,
+                                             TALER_EC_GENERIC_DB_STORE_FAILED,
+                                             "insert_reserve_open_deposit");
+      return qs;
+    }
+    if (insufficient_funds)
+    {
+      *mhd_ret
+        = TEH_RESPONSE_reply_coin_insufficient_funds (
+            connection,
+            TALER_EC_EXCHANGE_GENERIC_INSUFFICIENT_FUNDS,
+            &coin->cpi.denom_pub_hash,
+            &coin->cpi.coin_pub);
+      return GNUNET_DB_STATUS_HARD_ERROR;
+    }
+  }
+
   qs = TEH_plugin->do_reserve_open (TEH_plugin->cls,
+                                    /* inputs */
                                     rsc->reserve_pub,
-                                    ...);
-#else
-  qs = GNUNET_DB_STATUS_HARD_ERROR;
-#endif
+                                    &rsc->total,
+                                    rsc->purse_limit,
+                                    &rsc->reserve_sig,
+                                    rsc->desired_expiration,
+                                    rsc->timestamp,
+                                    &rsc->gf->fees.account,
+                                    /* outputs */
+                                    &rsc->open_cost,
+                                    &rsc->reserve_expiration);
   switch (qs)
   {
   case GNUNET_DB_STATUS_HARD_ERROR:
@@ -178,7 +238,7 @@ reserve_open_transaction (void *cls,
       = TALER_MHD_reply_with_error (connection,
                                     MHD_HTTP_INTERNAL_SERVER_ERROR,
                                     TALER_EC_GENERIC_DB_FETCH_FAILED,
-                                    "get_reserve_open");
+                                    "do_reserve_open");
     return GNUNET_DB_STATUS_HARD_ERROR;
   case GNUNET_DB_STATUS_SOFT_ERROR:
     return qs;
@@ -258,6 +318,7 @@ TEH_handler_reserves_open (struct TEH_RequestContext *rc,
   rsc.payments_len = json_array_size (payments);
   rsc.payments = GNUNET_new_array (rsc.payments_len,
                                    struct TEH_PurseDepositedCoin);
+  rsc.total = rsc.reserve_payment;
   for (unsigned int i = 0; i<rsc.payments_len; i++)
   {
     struct TEH_PurseDepositedCoin *coin = &rsc.payments[i];
@@ -280,6 +341,21 @@ TEH_handler_reserves_open (struct TEH_RequestContext *rc,
       cleanup_rsc (&rsc);
       return MHD_YES;   /* failure */
     }
+    /* FIXME-DOLD: Alternatively, we could here add coin->amount_minus_fee and
+       thereby charge the deposit fee even when paying the reserve-open fee.
+       To be decided... */
+    if (0 >
+        TALER_amount_add (&rsc.total,
+                          &rsc.total,
+                          &coin->amount))
+    {
+      GNUNET_break (0);
+      cleanup_rsc (&rsc);
+      return TALER_MHD_reply_with_error (rc->connection,
+                                         MHD_HTTP_INTERNAL_SERVER_ERROR,
+                                         
TALER_EC_GENERIC_FAILED_COMPUTE_AMOUNT,
+                                         NULL);
+    }
   }
 
   {
diff --git a/src/include/taler_crypto_lib.h b/src/include/taler_crypto_lib.h
index 09e386cd..a861563b 100644
--- a/src/include/taler_crypto_lib.h
+++ b/src/include/taler_crypto_lib.h
@@ -3107,16 +3107,14 @@ TALER_wallet_reserve_open_verify (
  * Sign to deposit coin to pay for keeping a reserve open.
  *
  * @param coin_contribution how much the coin should contribute
- * @param reserve_pub public key of the reserve
- * @param request_timestamp time of the open request
+ * @param reserve_sig signature over the reserve open operation
  * @param coin_priv private key of the coin
  * @param[out] coin_sig signature by the coin
  */
 void
 TALER_wallet_reserve_open_deposit_sign (
   const struct TALER_Amount *coin_contribution,
-  const struct TALER_ReservePublicKeyP *reserve_pub,
-  struct GNUNET_TIME_Timestamp request_timestamp,
+  const struct TALER_ReserveSignatureP *reserve_sig,
   const struct TALER_CoinSpendPrivateKeyP *coin_priv,
   struct TALER_CoinSpendSignatureP *coin_sig);
 
@@ -3125,8 +3123,7 @@ TALER_wallet_reserve_open_deposit_sign (
  * Verify signature that deposits coin to pay for keeping a reserve open.
  *
  * @param coin_contribution how much the coin should contribute
- * @param reserve_pub public key of the reserve
- * @param request_timestamp time of the open request
+ * @param reserve_sig signature over the reserve open operation
  * @param coin_pub public key of the coin
  * @param coin_sig signature by the coin
  * @return #GNUNET_OK if the signature is valid
@@ -3134,8 +3131,7 @@ TALER_wallet_reserve_open_deposit_sign (
 enum GNUNET_GenericReturnValue
 TALER_wallet_reserve_open_deposit_verify (
   const struct TALER_Amount *coin_contribution,
-  const struct TALER_ReservePublicKeyP *reserve_pub,
-  struct GNUNET_TIME_Timestamp request_timestamp,
+  const struct TALER_ReserveSignatureP *reserve_sig,
   const struct TALER_CoinSpendPublicKeyP *coin_pub,
   const struct TALER_CoinSpendSignatureP *coin_sig);
 
diff --git a/src/include/taler_exchangedb_plugin.h 
b/src/include/taler_exchangedb_plugin.h
index 261ffb18..e6c38ad9 100644
--- a/src/include/taler_exchangedb_plugin.h
+++ b/src/include/taler_exchangedb_plugin.h
@@ -4043,6 +4043,55 @@ struct TALER_EXCHANGEDB_Plugin
                           void *rec_cls);
 
 
+  /**
+   * Insert reserve open coin deposit data into database.
+   * Subtracts the @a coin_total from the coin's balance.
+   *
+   * @param cls closure
+   * @param cpi public information about the coin
+   * @param coin_sig signature with @e coin_pub of type 
#TALER_SIGNATURE_WALLET_RESERVE_OPEN_DEPOSIT
+   * @param known_coin_id ID of the coin in the known_coins table
+   * @param coin_total amount to be spent of the coin (including deposit fee)
+   * @param reserve_sig signature by the reserve affirming the open operation
+   * @param[out] insufficient_funds set to true if the coin's balance is 
insufficient, otherwise to false
+   * @return transaction status code, 0 if operation is already in the DB
+   */
+  enum GNUNET_DB_QueryStatus
+  (*insert_reserve_open_deposit)(
+    void *cls,
+    const struct TALER_CoinPublicInfo *cpi,
+    const struct TALER_CoinSpendSignatureP *coin_sig,
+    uint64_t known_coin_id,
+    const struct TALER_Amount *coin_total,
+    const struct TALER_ReserveSignatureP *reserve_sig,
+    bool *insufficient_funds);
+
+
+  /**
+   * Insert reserve close operation into database.
+   *
+   * @param cls closure
+   * @param reserve_pub which reserve is this about?
+   * @param execution_date when did we perform the transfer?
+   * @param receiver_account to which account do we transfer, in 
payto://-format
+   * @param wtid identifier for the wire transfer
+   * @param amount_with_fee amount we charged to the reserve
+   * @param closing_fee how high is the closing fee
+   * @return transaction status code
+   */
+  enum GNUNET_DB_QueryStatus
+  (*do_reserve_open)(void *cls,
+                     const struct TALER_ReservePublicKeyP *reserve_pub,
+                     const struct TALER_Amount *total_paid,
+                     uint32_t min_purse_limit,
+                     const struct TALER_ReserveSignatureP *reserve_sig,
+                     struct GNUNET_TIME_Timestamp desired_expiration,
+                     struct GNUNET_TIME_Timestamp now,
+                     const struct TALER_Amount *open_fee,
+                     struct TALER_Amount *open_cost,
+                     const struct GNUNET_TIME_Timestamp *final_expiration);
+
+
   /**
    * Insert reserve close operation into database.
    *
diff --git a/src/lib/exchange_api_reserves_open.c 
b/src/lib/exchange_api_reserves_open.c
index eb63f8fe..08d267fb 100644
--- a/src/lib/exchange_api_reserves_open.c
+++ b/src/lib/exchange_api_reserves_open.c
@@ -393,6 +393,12 @@ TALER_EXCHANGE_reserves_open (
     GNUNET_free (roh);
     return NULL;
   }
+  TALER_wallet_reserve_open_sign (reserve_contribution,
+                                  roh->ts,
+                                  expiration_time,
+                                  min_purses,
+                                  reserve_priv,
+                                  &roh->reserve_sig);
   cpa = json_array ();
   GNUNET_assert (NULL != cpa);
   for (unsigned int i = 0; i<coin_payments_length; i++)
@@ -412,8 +418,7 @@ TALER_EXCHANGE_reserves_open (
       achp = &ahac;
     }
     TALER_wallet_reserve_open_deposit_sign (&pd->amount,
-                                            &roh->reserve_pub,
-                                            roh->ts,
+                                            &roh->reserve_sig,
                                             &pd->coin_priv,
                                             &coin_sig);
     GNUNET_CRYPTO_eddsa_key_get_public (&pd->coin_priv.eddsa_priv,
@@ -437,12 +442,6 @@ TALER_EXCHANGE_reserves_open (
                    json_array_append_new (cpa,
                                           cp));
   }
-  TALER_wallet_reserve_open_sign (reserve_contribution,
-                                  roh->ts,
-                                  expiration_time,
-                                  min_purses,
-                                  reserve_priv,
-                                  &roh->reserve_sig);
   {
     json_t *open_obj = GNUNET_JSON_PACK (
       GNUNET_JSON_pack_timestamp ("request_timestamp",
diff --git a/src/util/wallet_signatures.c b/src/util/wallet_signatures.c
index 4e4932a2..c57506bd 100644
--- a/src/util/wallet_signatures.c
+++ b/src/util/wallet_signatures.c
@@ -1342,14 +1342,9 @@ struct TALER_ReserveOpenDepositPS
   struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
 
   /**
-   * When was the request created.
-   */
-  struct GNUNET_TIME_TimestampNBO request_timestamp;
-
-  /**
-   * Which reserve's opening should be paid for?
+   * Which reserve's opening signature should be paid for?
    */
-  struct TALER_ReservePublicKeyP reserve_pub;
+  struct TALER_ReserveSignatureP reserve_sig;
 
   /**
    * Specifies how much of the coin's value should be spent on opening this
@@ -1364,16 +1359,14 @@ GNUNET_NETWORK_STRUCT_END
 void
 TALER_wallet_reserve_open_deposit_sign (
   const struct TALER_Amount *coin_contribution,
-  const struct TALER_ReservePublicKeyP *reserve_pub,
-  struct GNUNET_TIME_Timestamp request_timestamp,
+  const struct TALER_ReserveSignatureP *reserve_sig,
   const struct TALER_CoinSpendPrivateKeyP *coin_priv,
   struct TALER_CoinSpendSignatureP *coin_sig)
 {
   struct TALER_ReserveOpenDepositPS rod = {
     .purpose.size = htonl (sizeof (rod)),
     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_OPEN_DEPOSIT),
-    .request_timestamp = GNUNET_TIME_timestamp_hton (request_timestamp),
-    .reserve_pub = *reserve_pub
+    .reserve_sig = *reserve_sig
   };
 
   TALER_amount_hton (&rod.coin_contribution,
@@ -1388,16 +1381,14 @@ TALER_wallet_reserve_open_deposit_sign (
 enum GNUNET_GenericReturnValue
 TALER_wallet_reserve_open_deposit_verify (
   const struct TALER_Amount *coin_contribution,
-  const struct TALER_ReservePublicKeyP *reserve_pub,
-  struct GNUNET_TIME_Timestamp request_timestamp,
+  const struct TALER_ReserveSignatureP *reserve_sig,
   const struct TALER_CoinSpendPublicKeyP *coin_pub,
   const struct TALER_CoinSpendSignatureP *coin_sig)
 {
   struct TALER_ReserveOpenDepositPS rod = {
     .purpose.size = htonl (sizeof (rod)),
     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_OPEN_DEPOSIT),
-    .request_timestamp = GNUNET_TIME_timestamp_hton (request_timestamp),
-    .reserve_pub = *reserve_pub
+    .reserve_sig = *reserve_sig
   };
 
   TALER_amount_hton (&rod.coin_contribution,

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