gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] [taler-exchange] branch master updated: fixing #4980


From: gnunet
Subject: [GNUnet-SVN] [taler-exchange] branch master updated: fixing #4980
Date: Tue, 18 Apr 2017 21:05:34 +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 5e8ef38  fixing #4980
5e8ef38 is described below

commit 5e8ef386803c399c1b6d780181b0b8662c418db0
Author: Christian Grothoff <address@hidden>
AuthorDate: Tue Apr 18 21:05:27 2017 +0200

    fixing #4980
---
 src/exchange-lib/exchange_api_common.c        | 147 +++++-------
 src/exchange-lib/exchange_api_reserve.c       |  68 +++---
 src/exchange/taler-exchange-httpd_responses.c | 311 ++++++++++++++------------
 src/include/taler_exchangedb_plugin.h         |  57 ++++-
 src/include/taler_json_lib.h                  |  12 +
 src/include/taler_signatures.h                |   5 +
 src/json/json_helper.c                        |  89 +++++++-
 7 files changed, 406 insertions(+), 283 deletions(-)

diff --git a/src/exchange-lib/exchange_api_common.c 
b/src/exchange-lib/exchange_api_common.c
index 29d0f6d..d9d0a6d 100644
--- a/src/exchange-lib/exchange_api_common.c
+++ b/src/exchange-lib/exchange_api_common.c
@@ -89,13 +89,22 @@ TALER_EXCHANGE_verify_coin_history (const char *currency,
                          "DEPOSIT"))
     {
       struct TALER_DepositRequestPS dr;
-      struct TALER_Amount dr_amount;
       struct TALER_CoinSpendSignatureP sig;
       struct GNUNET_JSON_Specification spec[] = {
-        GNUNET_JSON_spec_fixed_auto ("signature",
+        GNUNET_JSON_spec_fixed_auto ("coin_sig",
                                      &sig),
-        GNUNET_JSON_spec_fixed_auto ("details",
-                                     &dr),
+        GNUNET_JSON_spec_fixed_auto ("h_proposal_data",
+                                     &dr.h_proposal_data),
+        GNUNET_JSON_spec_fixed_auto ("h_wire",
+                                     &dr.h_wire),
+        GNUNET_JSON_spec_absolute_time_nbo ("timestamp",
+                                           &dr.timestamp),
+        GNUNET_JSON_spec_absolute_time_nbo ("refund_deadline",
+                                           &dr.refund_deadline),
+        TALER_JSON_spec_amount_nbo ("deposit_fee",
+                                   &dr.deposit_fee),
+        GNUNET_JSON_spec_fixed_auto ("merchant_pub",
+                                     &dr.merchant),
         GNUNET_JSON_spec_end()
       };
 
@@ -107,12 +116,11 @@ TALER_EXCHANGE_verify_coin_history (const char *currency,
         GNUNET_break_op (0);
         return GNUNET_SYSERR;
       }
-      /* TODO #4980 */
-      if (sizeof (dr) != ntohl (dr.purpose.size))
-      {
-        GNUNET_break_op (0);
-        return GNUNET_SYSERR;
-      }
+      dr.purpose.size = htonl (sizeof (dr));
+      dr.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_DEPOSIT);
+      TALER_amount_hton (&dr.amount_with_fee,
+                        &amount);
+      dr.coin_pub = *coin_pub;
       if (GNUNET_OK !=
           GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_DEPOSIT,
                                       &dr.purpose,
@@ -122,28 +130,22 @@ TALER_EXCHANGE_verify_coin_history (const char *currency,
         GNUNET_break_op (0);
         return GNUNET_SYSERR;
       }
-      TALER_amount_ntoh (&dr_amount,
-                         &dr.amount_with_fee);
-      /* TODO #4980 */
-      if (0 != TALER_amount_cmp (&dr_amount,
-                                 &amount))
-      {
-        GNUNET_break (0);
-        return GNUNET_SYSERR;
-      }
+      /* TODO: check that deposit fee and coin value match
+        our expectations from /keys! */
       add = GNUNET_YES;
     }
     else if (0 == strcasecmp (type,
                               "MELT"))
     {
       struct TALER_RefreshMeltCoinAffirmationPS rm;
-      struct TALER_Amount rm_amount;
       struct TALER_CoinSpendSignatureP sig;
       struct GNUNET_JSON_Specification spec[] = {
-        GNUNET_JSON_spec_fixed_auto ("signature",
+        GNUNET_JSON_spec_fixed_auto ("coin_sig",
                                      &sig),
-        GNUNET_JSON_spec_fixed_auto ("details",
-                                     &rm),
+        GNUNET_JSON_spec_fixed_auto ("session_hash",
+                                     &rm.session_hash),
+        TALER_JSON_spec_amount_nbo ("melt_fee",
+                                   &rm.melt_fee),
         GNUNET_JSON_spec_end()
       };
 
@@ -155,12 +157,11 @@ TALER_EXCHANGE_verify_coin_history (const char *currency,
         GNUNET_break_op (0);
         return GNUNET_SYSERR;
       }
-      /* TODO #4980 */
-      if (sizeof (rm) != ntohl (rm.purpose.size))
-      {
-        GNUNET_break_op (0);
-        return GNUNET_SYSERR;
-      }
+      rm.purpose.size = htonl (sizeof (rm));
+      rm.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_MELT);
+      TALER_amount_hton (&rm.amount_with_fee,
+                        &amount);
+      rm.coin_pub = *coin_pub;
       if (GNUNET_OK !=
           GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_MELT,
                                       &rm.purpose,
@@ -170,30 +171,26 @@ TALER_EXCHANGE_verify_coin_history (const char *currency,
         GNUNET_break_op (0);
         return GNUNET_SYSERR;
       }
-      TALER_amount_ntoh (&rm_amount,
-                         &rm.amount_with_fee);
-      /* TODO #4980 */
-      if (0 != TALER_amount_cmp (&rm_amount,
-                                 &amount))
-      {
-        GNUNET_break_op (0);
-        return GNUNET_SYSERR;
-      }
+      /* TODO: check that deposit fee and coin value match
+        our expectations from /keys! */
       add = GNUNET_YES;
     }
     else if (0 == strcasecmp (type,
                               "REFUND"))
     {
       struct TALER_RefundRequestPS rr;
-      struct TALER_Amount rr_amount;
-      struct TALER_Amount rr_fee;
-      struct TALER_Amount rr_delta;
-      struct TALER_CoinSpendSignatureP sig;
+      struct TALER_MerchantSignatureP sig;
       struct GNUNET_JSON_Specification spec[] = {
-        GNUNET_JSON_spec_fixed_auto ("signature",
+        GNUNET_JSON_spec_fixed_auto ("merchant_sig",
                                      &sig),
-        GNUNET_JSON_spec_fixed_auto ("details",
-                                     &rr),
+        GNUNET_JSON_spec_fixed_auto ("h_proposal_data",
+                                     &rr.h_proposal_data),
+        GNUNET_JSON_spec_fixed_auto ("merchant_pub",
+                                     &rr.merchant),
+        GNUNET_JSON_spec_uint64 ("rtransaction_id",
+                                &rr.rtransaction_id),
+        TALER_JSON_spec_amount_nbo ("refund_fee",
+                                   &rr.refund_fee),
         GNUNET_JSON_spec_end()
       };
 
@@ -205,38 +202,20 @@ TALER_EXCHANGE_verify_coin_history (const char *currency,
         GNUNET_break_op (0);
         return GNUNET_SYSERR;
       }
-      /* TODO #4980 */
-      if (sizeof (rr) != ntohl (rr.purpose.size))
-      {
-        GNUNET_break_op (0);
-        return GNUNET_SYSERR;
-      }
+      rr.purpose.size = htonl (sizeof (rr));
+      rr.purpose.purpose = htonl (TALER_SIGNATURE_MERCHANT_REFUND);
+      rr.coin_pub = *coin_pub;
+      TALER_amount_hton (&rr.refund_amount,
+                        &amount);
       if (GNUNET_OK !=
           GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MERCHANT_REFUND,
                                       &rr.purpose,
-                                      &sig.eddsa_signature,
+                                      &sig.eddsa_sig,
                                       &rr.merchant.eddsa_pub))
       {
         GNUNET_break_op (0);
         return GNUNET_SYSERR;
       }
-      TALER_amount_ntoh (&rr_amount,
-                         &rr.refund_amount);
-      if (GNUNET_OK !=
-          TALER_amount_subtract (&rr_delta,
-                                 &rr_amount,
-                                 &rr_fee))
-      {
-        GNUNET_break_op (0);
-        return GNUNET_SYSERR;
-      }
-      /* TODO #4980 */
-      if (0 != TALER_amount_cmp (&rr_delta,
-                                 &amount))
-      {
-        GNUNET_break_op (0);
-        return GNUNET_SYSERR;
-      }
       /* NOTE: theoretically, we could also check that the given
          merchant_pub and h_proposal_data appear in the
          history under deposits.  However, there is really no benefit
@@ -244,13 +223,14 @@ TALER_EXCHANGE_verify_coin_history (const char *currency,
          (an auditor ought to check, though). Then again, we similarly
          had no reason to check the merchant's signature (other than a
          well-formendess check). */
+      /* TODO: check that deposit fee and coin value match
+        our expectations from /keys! */
       add = GNUNET_NO;
     }
     else if (0 == strcasecmp (type,
                               "PAYBACK"))
     {
       struct TALER_PaybackConfirmationPS pc;
-      struct TALER_Amount pc_amount;
       struct TALER_ExchangePublicKeyP exchange_pub;
       struct TALER_ExchangeSignatureP exchange_sig;
       struct GNUNET_JSON_Specification spec[] = {
@@ -258,8 +238,10 @@ TALER_EXCHANGE_verify_coin_history (const char *currency,
                                      &exchange_sig),
         GNUNET_JSON_spec_fixed_auto ("exchange_pub",
                                      &exchange_pub),
-        GNUNET_JSON_spec_fixed_auto ("details",
-                                     &pc),
+        GNUNET_JSON_spec_fixed_auto ("reserve_pub",
+                                     &pc.reserve_pub),
+       GNUNET_JSON_spec_absolute_time_nbo ("timestamp",
+                                           &pc.timestamp),
         GNUNET_JSON_spec_end()
       };
 
@@ -271,13 +253,11 @@ TALER_EXCHANGE_verify_coin_history (const char *currency,
         GNUNET_break_op (0);
         return GNUNET_SYSERR;
       }
-
-      /* TODO #4980 */
-      if (sizeof (pc) != ntohl (pc.purpose.size))
-      {
-        GNUNET_break_op (0);
-        return GNUNET_SYSERR;
-      }
+      pc.purpose.size = htonl (sizeof (pc));
+      pc.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_PAYBACK);
+      pc.coin_pub = *coin_pub;
+      TALER_amount_hton (&pc.payback_amount,
+                        &amount);
       if (GNUNET_OK !=
           GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_CONFIRM_PAYBACK,
                                       &pc.purpose,
@@ -287,15 +267,6 @@ TALER_EXCHANGE_verify_coin_history (const char *currency,
         GNUNET_break_op (0);
         return GNUNET_SYSERR;
       }
-      TALER_amount_ntoh (&pc_amount,
-                         &pc.payback_amount);
-      /* TODO #4980 */
-      if (0 != TALER_amount_cmp (&pc_amount,
-                                 &amount))
-      {
-        GNUNET_break_op (0);
-        return GNUNET_SYSERR;
-      }
       add = GNUNET_YES;
     }
     else
diff --git a/src/exchange-lib/exchange_api_reserve.c 
b/src/exchange-lib/exchange_api_reserve.c
index 0ed8cca..98f15dc 100644
--- a/src/exchange-lib/exchange_api_reserve.c
+++ b/src/exchange-lib/exchange_api_reserve.c
@@ -184,12 +184,15 @@ parse_reserve_history (struct TALER_EXCHANGE_Handle 
*exchange,
     {
       struct TALER_ReserveSignatureP sig;
       struct TALER_WithdrawRequestPS withdraw_purpose;
-      struct TALER_Amount amount_from_purpose;
       struct GNUNET_JSON_Specification withdraw_spec[] = {
-        GNUNET_JSON_spec_fixed_auto ("signature",
+        GNUNET_JSON_spec_fixed_auto ("reserve_sig",
                                      &sig),
-        GNUNET_JSON_spec_fixed_auto ("details",
-                                     &withdraw_purpose),
+       TALER_JSON_spec_amount_nbo ("withdraw_fee",
+                                   &withdraw_purpose.withdraw_fee),
+        GNUNET_JSON_spec_fixed_auto ("h_denom_pub",
+                                     &withdraw_purpose.h_denomination_pub),
+        GNUNET_JSON_spec_fixed_auto ("h_coin_envelope",
+                                     &withdraw_purpose.h_coin_envelope),
         GNUNET_JSON_spec_end()
       };
       unsigned int i;
@@ -203,6 +206,13 @@ parse_reserve_history (struct TALER_EXCHANGE_Handle 
*exchange,
         GNUNET_break_op (0);
         return GNUNET_SYSERR;
       }
+      withdraw_purpose.purpose.size
+       = htonl (sizeof (withdraw_purpose));
+      withdraw_purpose.purpose.purpose
+       = htonl (TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW);
+      withdraw_purpose.reserve_pub = *reserve_pub;
+      TALER_amount_hton (&withdraw_purpose.amount_with_fee,
+                        &amount);
       /* Check that the signature is a valid withdraw request */
       if (GNUNET_OK !=
           GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW,
@@ -214,18 +224,10 @@ parse_reserve_history (struct TALER_EXCHANGE_Handle 
*exchange,
         GNUNET_JSON_parse_free (withdraw_spec);
         return GNUNET_SYSERR;
       }
-      TALER_amount_ntoh (&amount_from_purpose,
-                         &withdraw_purpose.amount_with_fee);
-      /* TODO #4980 */
-      if (0 != TALER_amount_cmp (&amount,
-                                 &amount_from_purpose))
-      {
-        GNUNET_break_op (0);
-        GNUNET_JSON_parse_free (withdraw_spec);
-        return GNUNET_SYSERR;
-      }
-      rhistory[off].details.out_authorization_sig = json_object_get 
(transaction,
-                                                                     
"signature");
+      /* TODO: check that withdraw fee matches expectations! */
+      rhistory[off].details.out_authorization_sig
+       = json_object_get (transaction,
+                          "signature");
       /* Check check that the same withdraw transaction
          isn't listed twice by the exchange. We use the
          "uuid" array to remember the hashes of all
@@ -263,25 +265,22 @@ parse_reserve_history (struct TALER_EXCHANGE_Handle 
*exchange,
                               "PAYBACK"))
     {
       struct TALER_PaybackConfirmationPS pc;
-      struct TALER_Amount amount_from_purpose;
-      struct GNUNET_TIME_Absolute timestamp_from_purpose;
       struct GNUNET_TIME_Absolute timestamp;
       const struct TALER_EXCHANGE_Keys *key_state;
       struct GNUNET_JSON_Specification payback_spec[] = {
-        GNUNET_JSON_spec_fixed_auto ("details",
-                                     &pc),
+        GNUNET_JSON_spec_fixed_auto ("coin_pub",
+                                     &pc.coin_pub),
         GNUNET_JSON_spec_fixed_auto ("exchange_sig",
                                      
&rhistory[off].details.payback_details.exchange_sig),
         GNUNET_JSON_spec_fixed_auto ("exchange_pub",
                                      
&rhistory[off].details.payback_details.exchange_pub),
-        GNUNET_JSON_spec_absolute_time ("timestamp",
-                                        &timestamp),
-        TALER_JSON_spec_amount ("amount",
-                                &rhistory[off].amount),
+        GNUNET_JSON_spec_absolute_time_nbo ("timestamp",
+                                           &pc.timestamp),
         GNUNET_JSON_spec_end()
       };
 
       rhistory[off].type = TALER_EXCHANGE_RTT_PAYBACK;
+      rhistory[off].amount = amount;
       if (GNUNET_OK !=
           GNUNET_JSON_parse (transaction,
                              payback_spec,
@@ -291,22 +290,13 @@ parse_reserve_history (struct TALER_EXCHANGE_Handle 
*exchange,
         return GNUNET_SYSERR;
       }
       rhistory[off].details.payback_details.coin_pub = pc.coin_pub;
-      TALER_amount_ntoh (&amount_from_purpose,
-                         &pc.payback_amount);
+      TALER_amount_hton (&pc.payback_amount,
+                        &amount);
+      pc.purpose.size = htonl (sizeof (pc));
+      pc.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_PAYBACK);
+      pc.reserve_pub = *reserve_pub;
+      timestamp = GNUNET_TIME_absolute_ntoh (pc.timestamp);
       rhistory[off].details.payback_details.timestamp = timestamp;
-      timestamp_from_purpose = GNUNET_TIME_absolute_ntoh (pc.timestamp);
-      /* TODO #4980 */
-      if ( (0 != memcmp (&pc.reserve_pub,
-                         reserve_pub,
-                         sizeof (*reserve_pub))) ||
-           (timestamp_from_purpose.abs_value_us !=
-            timestamp.abs_value_us) ||
-           (0 != TALER_amount_cmp (&amount_from_purpose,
-                                   &rhistory[off].amount)) )
-      {
-        GNUNET_break_op (0);
-        return GNUNET_SYSERR;
-      }
 
       key_state = TALER_EXCHANGE_get_keys (exchange);
       if (GNUNET_OK !=
diff --git a/src/exchange/taler-exchange-httpd_responses.c 
b/src/exchange/taler-exchange-httpd_responses.c
index c67c885..a335e44 100644
--- a/src/exchange/taler-exchange-httpd_responses.c
+++ b/src/exchange/taler-exchange-httpd_responses.c
@@ -307,7 +307,7 @@ TEH_RESPONSE_reply_arg_missing (struct MHD_Connection 
*connection,
 {
   return TEH_RESPONSE_reply_json_pack (connection,
                                        MHD_HTTP_BAD_REQUEST,
-                                       "{ s:s, s:I, s:s}",
+                                       "{s:s, s:I, s:s}",
                                        "error", "missing parameter",
                                       "code", (json_int_t) ec,
                                        "parameter", param_name);
@@ -524,20 +524,15 @@ TEH_RESPONSE_reply_deposit_success (struct MHD_Connection 
*connection,
 static json_t *
 compile_transaction_history (const struct TALER_EXCHANGEDB_TransactionList *tl)
 {
-  json_t *details;
-  const char *type;
-  struct TALER_Amount value;
   json_t *history;
-  const struct GNUNET_CRYPTO_EddsaSignature *sig;
-  const struct TALER_EXCHANGEDB_TransactionList *pos;
-
+  
   history = json_array ();
   if (NULL == history)
   {
     GNUNET_break (0); /* out of memory!? */
     return NULL;
   }
-  for (pos = tl; NULL != pos; pos = pos->next)
+  for (const struct TALER_EXCHANGEDB_TransactionList *pos = tl; NULL != pos; 
pos = pos->next)
   {
     switch (pos->type)
     {
@@ -546,8 +541,6 @@ compile_transaction_history (const struct 
TALER_EXCHANGEDB_TransactionList *tl)
         struct TALER_DepositRequestPS dr;
         const struct TALER_EXCHANGEDB_Deposit *deposit = pos->details.deposit;
 
-        type = "DEPOSIT";
-        value = deposit->amount_with_fee;
         dr.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_DEPOSIT);
         dr.purpose.size = htonl (sizeof (struct TALER_DepositRequestPS));
         dr.h_proposal_data = deposit->h_proposal_data;
@@ -560,12 +553,11 @@ compile_transaction_history (const struct 
TALER_EXCHANGEDB_TransactionList *tl)
                            &deposit->deposit_fee);
         dr.merchant = deposit->merchant_pub;
         dr.coin_pub = deposit->coin.coin_pub;
-        sig = &deposit->csig.eddsa_signature;
        /* internal sanity check before we hand out a bogus sig... */
         if (GNUNET_OK !=
             GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_DEPOSIT,
                                         &dr.purpose,
-                                        sig,
+                                        &deposit->csig.eddsa_signature,
                                         &deposit->coin.coin_pub.eddsa_pub))
        {
          GNUNET_break (0);
@@ -573,16 +565,25 @@ compile_transaction_history (const struct 
TALER_EXCHANGEDB_TransactionList *tl)
          return NULL;
        }
 
-        details = GNUNET_JSON_from_data_auto (&dr);
-        break;
+       GNUNET_assert (0 ==
+                      json_array_append_new (history,
+                                             json_pack ("{s:s, s:o, s:o, s:o, 
s:o, s:o, s:o, s:o, s:o}",
+                                                        "type", "DEPOSIT",
+                                                        "amount", 
TALER_JSON_from_amount (&deposit->amount_with_fee),
+                                                        "deposit_fee", 
TALER_JSON_from_amount (&deposit->deposit_fee),
+                                                        "timestamp", 
GNUNET_JSON_from_time_abs (deposit->timestamp),
+                                                        "refund_deadline", 
GNUNET_JSON_from_time_abs (deposit->refund_deadline),
+                                                        "merchant_pub", 
GNUNET_JSON_from_data_auto (&deposit->merchant_pub),
+                                                        "h_proposal_data", 
GNUNET_JSON_from_data_auto (&deposit->h_proposal_data),
+                                                        "h_wire", 
GNUNET_JSON_from_data_auto (&deposit->h_wire),
+                                                        "coin_sig", 
GNUNET_JSON_from_data_auto (&deposit->csig))));
+       break;
       }
     case TALER_EXCHANGEDB_TT_REFRESH_MELT:
       {
         struct TALER_RefreshMeltCoinAffirmationPS ms;
         const struct TALER_EXCHANGEDB_RefreshMelt *melt = pos->details.melt;
 
-        type = "MELT";
-        value = melt->amount_with_fee;
         ms.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_MELT);
         ms.purpose.size = htonl (sizeof (struct 
TALER_RefreshMeltCoinAffirmationPS));
         ms.session_hash = melt->session_hash;
@@ -591,12 +592,11 @@ compile_transaction_history (const struct 
TALER_EXCHANGEDB_TransactionList *tl)
         TALER_amount_hton (&ms.melt_fee,
                            &melt->melt_fee);
         ms.coin_pub = melt->coin.coin_pub;
-        sig = &melt->coin_sig.eddsa_signature;
        /* internal sanity check before we hand out a bogus sig... */
         if (GNUNET_OK !=
             GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_MELT,
                                         &ms.purpose,
-                                        sig,
+                                        &melt->coin_sig.eddsa_signature,
                                         &melt->coin.coin_pub.eddsa_pub))
        {
          GNUNET_break (0);
@@ -604,15 +604,22 @@ compile_transaction_history (const struct 
TALER_EXCHANGEDB_TransactionList *tl)
          return NULL;
        }
 
-        details = GNUNET_JSON_from_data_auto (&ms);
+       GNUNET_assert (0 ==
+                      json_array_append_new (history,
+                                             json_pack ("{s:s, s:o, s:o, s:o, 
s:o}",
+                                                        "type", "MELT",
+                                                        "amount", 
TALER_JSON_from_amount (&melt->amount_with_fee),
+                                                        "melt_fee", 
TALER_JSON_from_amount (&melt->melt_fee),
+                                                        "session_hash", 
GNUNET_JSON_from_data_auto (&melt->session_hash),
+                                                        "coin_sig", 
GNUNET_JSON_from_data_auto (&melt->coin_sig))));
       }
       break;
     case TALER_EXCHANGEDB_TT_REFUND:
       {
         struct TALER_RefundRequestPS rr;
         const struct TALER_EXCHANGEDB_Refund *refund = pos->details.refund;
+       struct TALER_Amount value;
 
-        type = "REFUND";
         if (GNUNET_OK !=
             TALER_amount_subtract (&value,
                                    &refund->refund_amount,
@@ -633,18 +640,27 @@ compile_transaction_history (const struct 
TALER_EXCHANGEDB_TransactionList *tl)
         TALER_amount_hton (&rr.refund_fee,
                            &refund->refund_fee);
        /* internal sanity check before we hand out a bogus sig... */
-        sig = &refund->merchant_sig.eddsa_sig;
         if (GNUNET_OK !=
             GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MERCHANT_REFUND,
                                         &rr.purpose,
-                                        sig,
+                                        &refund->merchant_sig.eddsa_sig,
                                         &refund->merchant_pub.eddsa_pub))
        {
          GNUNET_break (0);
          json_decref (history);
          return NULL;
        }
-        details = GNUNET_JSON_from_data_auto (&rr);
+       
+       GNUNET_assert (0 ==
+                      json_array_append_new (history,
+                                             json_pack ("{s:s, s:o, s:o, s:o, 
s:o, s:I, s:o}",
+                                                        "type", "REFUND",
+                                                        "amount", 
TALER_JSON_from_amount (&value),
+                                                        "refund_fee", 
TALER_JSON_from_amount (&refund->refund_fee),
+                                                        "h_proposal_data", 
GNUNET_JSON_from_data_auto (&refund->h_proposal_data),
+                                                        "merchant_pub", 
GNUNET_JSON_from_data_auto (&refund->merchant_pub),
+                                                        "rtransaction_id", 
(json_int_t) refund->rtransaction_id,
+                                                        "merchant_sig", 
GNUNET_JSON_from_data_auto (&refund->merchant_sig))));
       }
       break;
     case TALER_EXCHANGEDB_TT_PAYBACK:
@@ -654,8 +670,6 @@ compile_transaction_history (const struct 
TALER_EXCHANGEDB_TransactionList *tl)
         struct TALER_ExchangePublicKeyP epub;
         struct TALER_ExchangeSignatureP esig;
 
-        type = "PAYBACK";
-        value = payback->value;
         pc.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_PAYBACK);
         pc.purpose.size = htonl (sizeof (pc));
         pc.timestamp = GNUNET_TIME_absolute_hton (payback->timestamp);
@@ -666,28 +680,20 @@ compile_transaction_history (const struct 
TALER_EXCHANGEDB_TransactionList *tl)
         TEH_KS_sign (&pc.purpose,
                      &epub,
                      &esig);
-        details = GNUNET_JSON_from_data_auto (&pc);
         GNUNET_assert (0 ==
                        json_array_append_new (history,
-                                              json_pack ("{s:s, s:o, s:o, s:o, 
s:o}",
-                                                         "type", type,
-                                                         "amount", 
TALER_JSON_from_amount (&value),
+                                              json_pack ("{s:s, s:o, s:o, s:o, 
s:o, s:o}",
+                                                         "type", "PAYBACK",
+                                                         "amount", 
TALER_JSON_from_amount (&payback->value),
                                                          "exchange_sig", 
GNUNET_JSON_from_data_auto (&esig),
                                                          "exchange_pub", 
GNUNET_JSON_from_data_auto (&epub),
-                                                         "details", details)));
+                                                        "reserve_pub", 
GNUNET_JSON_from_data_auto (&payback->reserve_pub),
+                                                        "timestamp", 
GNUNET_JSON_from_time_abs (payback->timestamp))));
       }
-      /* do not go to the default handler, we already appended! */
-      continue;
+      break;
     default:
       GNUNET_assert (0);
     }
-    GNUNET_assert (0 ==
-                   json_array_append_new (history,
-                                          json_pack ("{s:s, s:o, s:o, s:o}",
-                                                     "type", type,
-                                                     "amount", 
TALER_JSON_from_amount (&value),
-                                                     "signature", 
GNUNET_JSON_from_data_auto (sig),
-                                                     "details", details)));
   }
   return history;
 }
@@ -739,20 +745,12 @@ compile_reserve_history (const struct 
TALER_EXCHANGEDB_ReserveHistory *rh,
 {
   struct TALER_Amount deposit_total;
   struct TALER_Amount withdraw_total;
-  struct TALER_Amount value;
   json_t *json_history;
   int ret;
-  const struct TALER_EXCHANGEDB_ReserveHistory *pos;
-  struct TALER_WithdrawRequestPS wr;
-  const struct TALER_EXCHANGEDB_Payback *payback;
-  struct TALER_PaybackConfirmationPS pc;
-  struct TALER_ReserveCloseConfirmationPS rcc;
-  struct TALER_ExchangePublicKeyP pub;
-  struct TALER_ExchangeSignatureP sig;
 
   json_history = json_array ();
   ret = 0;
-  for (pos = rh; NULL != pos; pos = pos->next)
+  for (const struct TALER_EXCHANGEDB_ReserveHistory *pos = rh; NULL != pos; 
pos = pos->next)
   {
     switch (pos->type)
     {
@@ -778,115 +776,130 @@ compile_reserve_history (const struct 
TALER_EXCHANGEDB_ReserveHistory *rh,
                                                        "amount", 
TALER_JSON_from_amount (&pos->details.bank->amount))));
       break;
     case TALER_EXCHANGEDB_RO_WITHDRAW_COIN:
-      value = pos->details.withdraw->amount_with_fee;
-      if (0 == (2 & ret))
       {
-        withdraw_total = value;
-      }
-      else
-      {
-        if (GNUNET_OK !=
-            TALER_amount_add (&withdraw_total,
-                              &withdraw_total,
-                              &value))
-        {
-          json_decref (json_history);
-          return NULL;
-        }
+       struct GNUNET_HashCode h_denom_pub;
+       struct TALER_Amount value;
+       
+       value = pos->details.withdraw->amount_with_fee;
+       if (0 == (2 & ret))
+       {
+         withdraw_total = value;
+       }
+       else
+       {
+         if (GNUNET_OK !=
+             TALER_amount_add (&withdraw_total,
+                               &withdraw_total,
+                               &value))
+         {
+           json_decref (json_history);
+           return NULL;
+         }
+       }
+       ret |= 2;
+       GNUNET_CRYPTO_rsa_public_key_hash 
(pos->details.withdraw->denom_pub.rsa_public_key,
+                                          &h_denom_pub);
+       GNUNET_assert (0 ==
+                      json_array_append_new (json_history,
+                                             json_pack ("{s:s, s:o, s:o, s:o, 
s:o, s:o}",
+                                                        "type", "WITHDRAW",
+                                                        "reserve_sig", 
GNUNET_JSON_from_data_auto (&pos->details.withdraw->reserve_sig),
+                                                        "h_coin_envelope", 
GNUNET_JSON_from_data_auto (&pos->details.withdraw->h_coin_envelope),
+                                                        "h_denom_pub", 
GNUNET_JSON_from_data_auto (&h_denom_pub),
+                                                        "withdraw_fee", 
TALER_JSON_from_amount (&pos->details.withdraw->withdraw_fee),
+                                                        "amount", 
TALER_JSON_from_amount (&value))));
       }
-      ret |= 2;
-      wr.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW);
-      wr.purpose.size = htonl (sizeof (struct TALER_WithdrawRequestPS));
-      wr.reserve_pub = pos->details.withdraw->reserve_pub;
-      TALER_amount_hton (&wr.amount_with_fee,
-                         &value);
-      TALER_amount_hton (&wr.withdraw_fee,
-                         &pos->details.withdraw->withdraw_fee);
-      GNUNET_CRYPTO_rsa_public_key_hash 
(pos->details.withdraw->denom_pub.rsa_public_key,
-                                         &wr.h_denomination_pub);
-      wr.h_coin_envelope = pos->details.withdraw->h_coin_envelope;
-      GNUNET_assert (0 ==
-                     json_array_append_new (json_history,
-                                            json_pack ("{s:s, s:o, s:o, s:o}",
-                                                       "type", "WITHDRAW",
-                                                       "signature", 
GNUNET_JSON_from_data_auto (&pos->details.withdraw->reserve_sig),
-                                                       "details", 
GNUNET_JSON_from_data_auto (&wr),
-
-                                                       "amount", 
TALER_JSON_from_amount (&value))));
       break;
     case TALER_EXCHANGEDB_RO_PAYBACK_COIN:
-      payback = pos->details.payback;
-      if (0 == (1 & ret))
-        deposit_total = payback->value;
-      else
-        if (GNUNET_OK !=
-            TALER_amount_add (&deposit_total,
-                              &deposit_total,
-                              &payback->value))
-        {
-          json_decref (json_history);
-          return NULL;
-        }
-      ret |= 1;
-      pc.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_PAYBACK);
-      pc.purpose.size = htonl (sizeof (struct TALER_PaybackConfirmationPS));
-      pc.timestamp = GNUNET_TIME_absolute_hton (payback->timestamp);
-      TALER_amount_hton (&pc.payback_amount,
-                         &payback->value);
-      pc.coin_pub = payback->coin.coin_pub;
-      pc.reserve_pub = payback->reserve_pub;
-      TEH_KS_sign (&pc.purpose,
-                   &pub,
-                   &sig);
-
-      GNUNET_assert (0 ==
-                     json_array_append_new (json_history,
-                                            json_pack ("{s:s, s:o, s:o, s:o, 
s:o, s:o}",
-                                                       "type", "PAYBACK",
-                                                       "exchange_pub", 
GNUNET_JSON_from_data_auto (&pub),
-                                                       "exchange_sig", 
GNUNET_JSON_from_data_auto (&sig),
-                                                       "timestamp", 
GNUNET_JSON_from_time_abs (payback->timestamp),
-                                                       "amount", 
TALER_JSON_from_amount (&payback->value),
-                                                       "details", 
GNUNET_JSON_from_data_auto (&pc))));
-      break;
-    case TALER_EXCHANGEDB_RO_EXCHANGE_TO_BANK:
-      value = pos->details.bank->amount;
-      if (0 == (2 & ret))
       {
-        withdraw_total = value;
+       const struct TALER_EXCHANGEDB_Payback *payback;
+       struct TALER_PaybackConfirmationPS pc;
+       struct TALER_ExchangePublicKeyP pub;
+       struct TALER_ExchangeSignatureP sig;
+
+       payback = pos->details.payback;
+       if (0 == (1 & ret))
+         deposit_total = payback->value;
+       else
+         if (GNUNET_OK !=
+             TALER_amount_add (&deposit_total,
+                               &deposit_total,
+                               &payback->value))
+         {
+           json_decref (json_history);
+           return NULL;
+         }
+       ret |= 1;
+       pc.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_PAYBACK);
+       pc.purpose.size = htonl (sizeof (struct TALER_PaybackConfirmationPS));
+       pc.timestamp = GNUNET_TIME_absolute_hton (payback->timestamp);
+       TALER_amount_hton (&pc.payback_amount,
+                          &payback->value);
+       pc.coin_pub = payback->coin.coin_pub;
+       pc.reserve_pub = payback->reserve_pub;
+       TEH_KS_sign (&pc.purpose,
+                    &pub,
+                    &sig);
+
+       GNUNET_assert (0 ==
+                      json_array_append_new (json_history,
+                                             json_pack ("{s:s, s:o, s:o, s:o, 
s:o, s:o}",
+                                                        "type", "PAYBACK",
+                                                        "exchange_pub", 
GNUNET_JSON_from_data_auto (&pub),
+                                                        "exchange_sig", 
GNUNET_JSON_from_data_auto (&sig),
+                                                        "timestamp", 
GNUNET_JSON_from_time_abs (payback->timestamp),
+                                                        "amount", 
TALER_JSON_from_amount (&payback->value),
+                                                        "coin_pub", 
GNUNET_JSON_from_data_auto (&payback->coin.coin_pub))));
       }
-      else
+      break;
+    case TALER_EXCHANGEDB_RO_EXCHANGE_TO_BANK:
       {
-        if (GNUNET_OK !=
-            TALER_amount_add (&withdraw_total,
-                              &withdraw_total,
-                              &value))
-        {
-          json_decref (json_history);
-          return NULL;
-        }
+       struct TALER_ReserveCloseConfirmationPS rcc;
+       struct TALER_ExchangePublicKeyP pub;
+       struct TALER_ExchangeSignatureP sig;
+       struct TALER_Amount value;
+
+       value = pos->details.closing->amount;
+       if (0 == (2 & ret))
+       {
+         withdraw_total = value;
+       }
+       else
+       {
+         if (GNUNET_OK !=
+             TALER_amount_add (&withdraw_total,
+                               &withdraw_total,
+                               &value))
+         {
+           json_decref (json_history);
+           return NULL;
+         }
+       }
+       ret |= 2;
+       rcc.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_RESERVE_CLOSED);
+       rcc.purpose.size = htonl (sizeof (struct 
TALER_ReserveCloseConfirmationPS));
+       rcc.timestamp = GNUNET_TIME_absolute_hton 
(pos->details.closing->execution_date);
+       TALER_amount_hton (&rcc.closing_amount,
+                          &value);
+       TALER_amount_hton (&rcc.closing_fee,
+                          &pos->details.closing->closing_fee);
+       rcc.reserve_pub = pos->details.closing->reserve_pub;
+       TALER_JSON_hash (pos->details.closing->receiver_account_details,
+                        &rcc.h_wire);
+       TEH_KS_sign (&rcc.purpose,
+                    &pub,
+                    &sig);
+       GNUNET_assert (0 ==
+                      json_array_append_new (json_history,
+                                             json_pack ("{s:s, s:o, s:o, s:o, 
s:o}",
+                                                        "type", "CLOSING",
+                                                        "exchange_pub", 
GNUNET_JSON_from_data_auto (&pub),
+                                                        "exchange_sig", 
GNUNET_JSON_from_data_auto (&sig),
+                                                        "timestamp", 
GNUNET_JSON_from_time_abs (pos->details.closing->execution_date),
+                                                        "h_wire", 
GNUNET_JSON_from_data_auto (&rcc.h_wire),
+                                                        "amount", 
TALER_JSON_from_amount (&value),
+                                                        "closing_fee", 
TALER_JSON_from_amount (&pos->details.closing->closing_fee))));
       }
-      ret |= 2;
-
-      rcc.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_RESERVE_CLOSED);
-      rcc.purpose.size = htonl (sizeof (struct 
TALER_ReserveCloseConfirmationPS));
-      rcc.timestamp = GNUNET_TIME_absolute_hton 
(pos->details.bank->execution_date);
-      TALER_amount_hton (&rcc.closing_amount,
-                         &value);
-      rcc.reserve_pub = pos->details.bank->reserve_pub;
-      TALER_JSON_hash (pos->details.bank->sender_account_details,
-                       &rcc.h_wire);
-      TEH_KS_sign (&rcc.purpose,
-                   &pub,
-                   &sig);
-      GNUNET_assert (0 ==
-                     json_array_append_new (json_history,
-                                            json_pack ("{s:s, s:o, s:o, s:o, 
s:o}",
-                                                       "type", "CLOSING",
-                                                       "exchange_pub", 
GNUNET_JSON_from_data_auto (&pub),
-                                                       "exchange_sig", 
GNUNET_JSON_from_data_auto (&sig),
-                                                       "details", 
GNUNET_JSON_from_data_auto (&rcc),
-                                                       "amount", 
TALER_JSON_from_amount (&value))));
       break;
     }
   }
diff --git a/src/include/taler_exchangedb_plugin.h 
b/src/include/taler_exchangedb_plugin.h
index fe08bd2..b9c3d79 100644
--- a/src/include/taler_exchangedb_plugin.h
+++ b/src/include/taler_exchangedb_plugin.h
@@ -28,14 +28,13 @@
 
 
 /**
- * @brief Information we keep on bank transfer(s) that established or
- * closed a reserve.
+ * @brief Information we keep on bank transfer(s) that established a reserve.
  */
 struct TALER_EXCHANGEDB_BankTransfer
 {
 
   /**
-   * Public key of the reserve that was filled or depleted.
+   * Public key of the reserve that was filled.
    */
   struct TALER_ReservePublicKeyP reserve_pub;
 
@@ -52,7 +51,7 @@ struct TALER_EXCHANGEDB_BankTransfer
   struct GNUNET_TIME_Absolute execution_date;
 
   /**
-   * Detailed wire information about the sending (or receiving) account.
+   * Detailed wire information about the sending account.
    */
   json_t *sender_account_details;
 
@@ -66,6 +65,47 @@ struct TALER_EXCHANGEDB_BankTransfer
 
 
 /**
+ * @brief Information we keep on bank transfer(s) that 
+ * closed a reserve.
+ */
+struct TALER_EXCHANGEDB_ClosingTransfer
+{
+
+  /**
+   * Public key of the reserve that was depleted.
+   */
+  struct TALER_ReservePublicKeyP reserve_pub;
+
+  /**
+   * Amount that was transferred to the exchange.
+   */
+  struct TALER_Amount amount;
+
+  /**
+   * Amount that was charged by the exchange.
+   */
+  struct TALER_Amount closing_fee;
+
+  /**
+   * When did the exchange execute the transaction?
+   */
+  struct GNUNET_TIME_Absolute execution_date;
+
+  /**
+   * Detailed wire information about the receiving account.
+   */
+  json_t *receiver_account_details;
+
+  /**
+   * Detailed wire transfer information that uniquely identifies the
+   * wire transfer.
+   */
+  json_t *transfer_details;
+
+};
+
+
+/**
  * @brief A summary of a Reserve
  */
 struct TALER_EXCHANGEDB_Reserve
@@ -244,8 +284,7 @@ struct TALER_EXCHANGEDB_ReserveHistory
 
     /**
      * Details about a bank transfer to the exchange (reserve
-     * was established) or from the exchange (reserve was
-     * closed).
+     * was established).
      */
     struct TALER_EXCHANGEDB_BankTransfer *bank;
 
@@ -259,6 +298,12 @@ struct TALER_EXCHANGEDB_ReserveHistory
      */
     struct TALER_EXCHANGEDB_Payback *payback;
 
+    /**
+     * Details about a bank transfer from the exchange (reserve
+     * was closed).
+     */
+    struct TALER_EXCHANGEDB_ClosingTransfer *closing;
+
   } details;
 
 };
diff --git a/src/include/taler_json_lib.h b/src/include/taler_json_lib.h
index b247ba1..248de9c 100644
--- a/src/include/taler_json_lib.h
+++ b/src/include/taler_json_lib.h
@@ -59,6 +59,18 @@ TALER_JSON_spec_amount (const char *name,
 
 
 /**
+ * Provide specification to parse given JSON object to an amount
+ * in network byte order.
+ *
+ * @param name name of the amount field in the JSON
+ * @param[out] r_amount where the amount has to be written
+ */
+struct GNUNET_JSON_Specification
+TALER_JSON_spec_amount_nbo (const char *name,
+                           struct TALER_AmountNBO *r_amount);
+
+
+/**
  * Generate line in parser specification for denomination public key.
  *
  * @param field name of the field
diff --git a/src/include/taler_signatures.h b/src/include/taler_signatures.h
index 70560b4..0b1c7ac 100644
--- a/src/include/taler_signatures.h
+++ b/src/include/taler_signatures.h
@@ -1254,6 +1254,11 @@ struct TALER_ReserveCloseConfirmationPS
   struct TALER_AmountNBO closing_amount;
 
   /**
+   * How much did the exchange charge for closing the reserve?
+   */
+  struct TALER_AmountNBO closing_fee;
+
+  /**
    * Public key of the reserve that received the payback.
    */
   struct TALER_ReservePublicKeyP reserve_pub;
diff --git a/src/json/json_helper.c b/src/json/json_helper.c
index f964f8f..1d2a331 100644
--- a/src/json/json_helper.c
+++ b/src/json/json_helper.c
@@ -119,7 +119,6 @@ parse_amount (void *cls,
 }
 
 
-
 /**
  * Provide specification to parse given JSON object to an amount.
  *
@@ -144,6 +143,94 @@ TALER_JSON_spec_amount (const char *name,
 
 
 /**
+ * Parse given JSON object to Amount in NBO.
+ *
+ * @param cls closure, NULL
+ * @param root the json object representing data
+ * @param[out] spec where to write the data
+ * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
+ */
+static int
+parse_amount_nbo (void *cls,
+              json_t *root,
+              struct GNUNET_JSON_Specification *spec)
+{
+  struct TALER_AmountNBO *r_amount = spec->ptr;
+  struct TALER_Amount amount;
+  json_int_t value;
+  json_int_t fraction;
+  const char *currency;
+
+  memset (&amount,
+          0,
+          sizeof (struct TALER_Amount));
+  if (0 != json_unpack (root,
+                        "{s:I, s:I, s:s}",
+                        "value", &value,
+                        "fraction", &fraction,
+                        "currency", &currency))
+  {
+    char *json_enc;
+
+    if (NULL == (json_enc = json_dumps (root,
+                                        JSON_COMPACT | JSON_ENCODE_ANY)))
+    {
+      GNUNET_break (0);
+      return GNUNET_SYSERR;
+    }
+    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                "Malformed JSON amount: %s\n",
+                json_enc);
+    free (json_enc);
+    return GNUNET_SYSERR;
+  }
+  if ( (value < 0) ||
+       (fraction < 0) ||
+       (value > UINT64_MAX) ||
+       (fraction > UINT32_MAX) )
+  {
+    GNUNET_break_op (0);
+    return GNUNET_SYSERR;
+  }
+  if (strlen (currency) >= TALER_CURRENCY_LEN)
+  {
+    GNUNET_break_op (0);
+    return GNUNET_SYSERR;
+  }
+  amount.value = (uint64_t) value;
+  amount.fraction = (uint32_t) fraction;
+  strcpy (amount.currency, currency);
+  (void) TALER_amount_normalize (&amount);
+  TALER_amount_hton (r_amount,
+                    &amount);
+  return GNUNET_OK;
+}
+
+
+/**
+ * Provide specification to parse given JSON object to an amount.
+ *
+ * @param name name of the amount field in the JSON
+ * @param[out] r_amount where the amount has to be written
+ */
+struct GNUNET_JSON_Specification
+TALER_JSON_spec_amount_nbo (const char *name,
+                           struct TALER_AmountNBO *r_amount)
+{
+  struct GNUNET_JSON_Specification ret = {
+    .parser = &parse_amount_nbo,
+    .cleaner = NULL,
+    .cls = NULL,
+    .field = name,
+    .ptr = r_amount,
+    .ptr_size = 0,
+    .size_ptr = NULL
+  };
+  return ret;
+}
+
+
+/**
  * Generate line in parser specification for denomination public key.
  *
  * @param field name of the field

-- 
To stop receiving notification emails like this one, please contact
address@hidden



reply via email to

[Prev in Thread] Current Thread [Next in Thread]