gnunet-svn
[Top][All Lists]
Advanced

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

[taler-exchange] branch master updated (c05f8320 -> 6107e995)


From: gnunet
Subject: [taler-exchange] branch master updated (c05f8320 -> 6107e995)
Date: Mon, 10 Jul 2023 10:28:38 +0200

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

oec pushed a change to branch master
in repository exchange.

    from c05f8320 -current use is good
     new 7e9f5324 -loglevel INFO
     new 9d706a01 added expected HTTP-code to logger
     new 3024dc9f fix memory leaks reported by valgrind
     new 6107e995 Merge branch 'master' of ssh://git.taler.net/exchange

The 4 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 src/extensions/age_restriction/age_restriction.c   |  8 +--
 src/extensions/extensions.c                        | 13 ++--
 src/include/taler_crypto_lib.h                     | 33 ++++++++--
 src/include/taler_exchange_service.h               |  9 +--
 src/include/taler_testing_lib.h                    | 30 ++++++++-
 src/include/taler_util.h                           |  7 +-
 src/lib/exchange_api_link.c                        | 33 ++++++----
 src/lib/exchange_api_melt.c                        | 17 ++---
 src/lib/exchange_api_refresh_common.c              | 25 +++++---
 src/lib/exchange_api_refresh_common.h              |  5 +-
 src/lib/exchange_api_refreshes_reveal.c            | 66 ++++++++++---------
 src/testing/test_bank_api.c                        |  3 +
 src/testing/test_exchange_api.c                    |  1 -
 src/testing/testing_api_cmd_auditor_add.c          |  3 +-
 .../testing_api_cmd_auditor_add_denom_sig.c        |  3 +-
 src/testing/testing_api_cmd_auditor_del.c          |  3 +-
 .../testing_api_cmd_auditor_deposit_confirmation.c |  3 +-
 src/testing/testing_api_cmd_auditor_exchanges.c    |  3 +-
 src/testing/testing_api_cmd_bank_transfer.c        |  3 +-
 src/testing/testing_api_cmd_batch_deposit.c        |  3 +-
 src/testing/testing_api_cmd_batch_withdraw.c       | 40 +++++-------
 src/testing/testing_api_cmd_check_aml_decision.c   |  3 +-
 src/testing/testing_api_cmd_check_aml_decisions.c  |  3 +-
 src/testing/testing_api_cmd_contract_get.c         |  3 +-
 src/testing/testing_api_cmd_deposit.c              | 41 +++++++-----
 src/testing/testing_api_cmd_deposits_get.c         |  3 +-
 src/testing/testing_api_cmd_get_auditor.c          |  3 +-
 src/testing/testing_api_cmd_kyc_check_get.c        |  3 +-
 src/testing/testing_api_cmd_kyc_proof.c            |  3 +-
 src/testing/testing_api_cmd_kyc_wallet_get.c       |  3 +-
 src/testing/testing_api_cmd_purse_create_deposit.c |  3 +-
 src/testing/testing_api_cmd_purse_delete.c         |  3 +-
 src/testing/testing_api_cmd_purse_deposit.c        |  3 +-
 src/testing/testing_api_cmd_purse_merge.c          |  3 +-
 src/testing/testing_api_cmd_recoup.c               |  3 +-
 src/testing/testing_api_cmd_recoup_refresh.c       |  3 +-
 src/testing/testing_api_cmd_refresh.c              | 57 +++++++++++-----
 src/testing/testing_api_cmd_refund.c               |  3 +-
 src/testing/testing_api_cmd_reserve_purse.c        |  3 +-
 src/testing/testing_api_cmd_revoke_denom_key.c     |  3 +-
 src/testing/testing_api_cmd_revoke_sign_key.c      |  3 +-
 src/testing/testing_api_cmd_run_fakebank.c         |  1 +
 src/testing/testing_api_cmd_set_officer.c          |  3 +-
 src/testing/testing_api_cmd_set_wire_fee.c         |  3 +-
 src/testing/testing_api_cmd_take_aml_decision.c    |  3 +-
 src/testing/testing_api_cmd_transfer_get.c         |  3 +-
 src/testing/testing_api_cmd_wire_add.c             |  3 +-
 src/testing/testing_api_cmd_wire_del.c             |  4 +-
 src/testing/testing_api_cmd_withdraw.c             | 43 +++++--------
 src/util/age_restriction.c                         | 75 +++++++++++++++++-----
 50 files changed, 380 insertions(+), 221 deletions(-)

diff --git a/src/extensions/age_restriction/age_restriction.c 
b/src/extensions/age_restriction/age_restriction.c
index 481cb133..644a4ac6 100644
--- a/src/extensions/age_restriction/age_restriction.c
+++ b/src/extensions/age_restriction/age_restriction.c
@@ -94,7 +94,7 @@ age_restriction_load_config (
   ext->config = &AR_config;
   ext->enabled = true;
 
-  GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
               "loaded new age restriction config with age groups: %s\n",
               TALER_age_mask_to_string (&mask));
 
@@ -112,7 +112,6 @@ static json_t *
 age_restriction_manifest (
   const struct TALER_Extension *ext)
 {
-  char *mask_str;
   json_t *conf;
 
   GNUNET_assert (NULL != ext);
@@ -124,12 +123,11 @@ age_restriction_manifest (
     return json_null ();
   }
 
-  mask_str = TALER_age_mask_to_string (&AR_config.mask);
   conf = GNUNET_JSON_PACK (
-    GNUNET_JSON_pack_string ("age_groups", mask_str)
+    GNUNET_JSON_pack_string ("age_groups",
+                             TALER_age_mask_to_string (&AR_config.mask))
     );
 
-  free (mask_str);
 
   return GNUNET_JSON_PACK (
     GNUNET_JSON_pack_bool ("critical", ext->critical),
diff --git a/src/extensions/extensions.c b/src/extensions/extensions.c
index 731ccfd0..fbbe874f 100644
--- a/src/extensions/extensions.c
+++ b/src/extensions/extensions.c
@@ -184,7 +184,7 @@ configure_extension (
 {
   struct LoadConfClosure *col = cls;
   const char *name;
-  char *lib_name;
+  char lib_name[1024] = {0};
   struct TALER_Extension *extension;
 
   if (GNUNET_OK != col->error)
@@ -199,17 +199,16 @@ configure_extension (
 
 
   /* Load the extension library */
-  GNUNET_asprintf (&lib_name,
+  GNUNET_snprintf (lib_name,
+                   sizeof(lib_name),
                    "libtaler_extension_%s",
                    name);
   /* Lower-case extension name, config is case-insensitive */
   for (unsigned int i = 0; i < strlen (lib_name); i++)
-  {
     lib_name[i] = tolower (lib_name[i]);
-  }
-  extension = GNUNET_PLUGIN_load (
-    lib_name,
-    (void *) col->cfg);
+
+  extension = GNUNET_PLUGIN_load (lib_name,
+                                  (void *) col->cfg);
   if (NULL == extension)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
diff --git a/src/include/taler_crypto_lib.h b/src/include/taler_crypto_lib.h
index 3ad441cb..373fc5c2 100644
--- a/src/include/taler_crypto_lib.h
+++ b/src/include/taler_crypto_lib.h
@@ -5947,33 +5947,54 @@ TALER_age_commitment_verify (
 /**
  * @brief helper function to free memory of a struct TALER_AgeCommitment
  *
- * @param p the commitment from which all memory should be freed.
+ * @param ac the commitment from which all memory should be freed.
  */
 void
 TALER_age_commitment_free (
-  struct TALER_AgeCommitment *p);
+  struct TALER_AgeCommitment *ac);
 
 
 /**
  * @brief helper function to free memory of a struct TALER_AgeProof
  *
- * @param p the proof of commitment from which all memory should be freed.
+ * @param ap the proof of commitment from which all memory should be freed.
  */
 void
 TALER_age_proof_free (
-  struct TALER_AgeProof *p);
+  struct TALER_AgeProof *ap);
 
 
 /**
  * @brief helper function to free memory of a struct TALER_AgeCommitmentProof
  *
- * @param p the commitment and its proof from which all memory should be freed.
+ * @param acp the commitment and its proof from which all memory should be 
freed.
  */
 void
 TALER_age_commitment_proof_free (
-  struct TALER_AgeCommitmentProof *p);
+  struct TALER_AgeCommitmentProof *acp);
 
 
+/**
+ * @brief helper function to allocate and copy a struct 
TALER_AgeCommitmentProof
+ *
+ * @param[in] acp The original age commitment proof
+ * @return The deep copy of @e acp, allocated
+ */
+struct TALER_AgeCommitmentProof *
+TALER_age_commitment_proof_duplicate (
+  const struct TALER_AgeCommitmentProof *acp);
+
+/**
+ * @brief helper function to copy a struct TALER_AgeCommitmentProof
+ *
+ * @param[in] acp The original age commitment proof
+ * @param[out] nacp The struct to copy the data into, with freshly allocated 
and copied keys.
+ */
+void
+TALER_age_commitment_proof_deep_copy (
+  const struct TALER_AgeCommitmentProof *acp,
+  struct TALER_AgeCommitmentProof *nacp);
+
 /**
  * @brief For age-withdraw, clients have to prove that the public keys for all
  * age groups larger than the allowed maximum age group are derived by scalar
diff --git a/src/include/taler_exchange_service.h 
b/src/include/taler_exchange_service.h
index 1f3bbffe..77705379 100644
--- a/src/include/taler_exchange_service.h
+++ b/src/include/taler_exchange_service.h
@@ -3053,7 +3053,7 @@ struct TALER_EXCHANGE_RevealedCoinInfo
    * Age commitment and its hash of the coin, might be NULL.
    */
   struct TALER_AgeCommitmentProof *age_commitment_proof;
-  struct TALER_AgeCommitmentHash *h_age_commitment;
+  struct TALER_AgeCommitmentHash h_age_commitment;
 
   /**
    * Blinding keys used to blind the fresh coin.
@@ -3197,10 +3197,11 @@ struct TALER_EXCHANGE_LinkedCoinInfo
   struct TALER_CoinSpendPrivateKeyP coin_priv;
 
   /**
-   * Age commitment and its hash, if applicable.  Might be NULL.
+   * Age commitment and its hash, if applicable.
    */
-  struct TALER_AgeCommitmentProof *age_commitment_proof;
-  struct TALER_AgeCommitmentHash *h_age_commitment;
+  bool has_age_commitment;
+  struct TALER_AgeCommitmentProof age_commitment_proof;
+  struct TALER_AgeCommitmentHash h_age_commitment;
 
   /**
    * Master secret of this coin.
diff --git a/src/include/taler_testing_lib.h b/src/include/taler_testing_lib.h
index 4996fbe2..d8793f4a 100644
--- a/src/include/taler_testing_lib.h
+++ b/src/include/taler_testing_lib.h
@@ -57,18 +57,44 @@
  *
  * @param is interpreter to fail
  * @param status unexpected HTTP status code received
+ * @param expected expected HTTP status code
  */
-#define TALER_TESTING_unexpected_status(is,status)                      \
+#define TALER_TESTING_unexpected_status(is,status, expected)            \
   do {                                                                  \
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,                                \
-                "Unexpected response code %u to command %s in %s:%u\n", \
+                "Unexpected response code %u (expected: %u) to command %s in 
%s:%u\n", \
                 status,                                                 \
+                expected,                                               \
                 TALER_TESTING_interpreter_get_current_label (is),       \
                 __FILE__,                                               \
                 __LINE__);                                              \
     TALER_TESTING_interpreter_fail (is);                                \
   } while (0)
 
+/**
+ * Log an error message about us receiving an unexpected HTTP
+ * status code at the current command and fail the test and print the response
+ * body (expected as json).
+ *
+ * @param is interpreter to fail
+ * @param status unexpected HTTP status code received
+ * @param expected expected HTTP status code
+ * @param body received JSON-reply
+ */
+#define TALER_TESTING_unexpected_status_with_body(is,status, expected, body) \
+  do {                                                                  \
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,                                \
+                "Unexpected response code %u (expected: %u) to "        \
+                "command %s in %s:%u\nwith body:\n>>%s<<\n",            \
+                status,                                                 \
+                expected,                                               \
+                TALER_TESTING_interpreter_get_current_label (is),       \
+                __FILE__,                                               \
+                __LINE__,                                               \
+                json_dumps (body, JSON_INDENT (2)));                    \
+    TALER_TESTING_interpreter_fail (is);                                \
+  } while (0)
+
 
 /**
  * Log an error message about a command not having
diff --git a/src/include/taler_util.h b/src/include/taler_util.h
index e0473bff..8762f7dc 100644
--- a/src/include/taler_util.h
+++ b/src/include/taler_util.h
@@ -578,11 +578,14 @@ TALER_parse_age_group_string (
 /**
  * @brief Encodes the age mask into a string, like "8:10:12:14:16:18:21"
  *
+ * NOTE: This function uses a static buffer.  It is not safe to call this
+ * function concurrently.
+ *
  * @param mask Age mask
- * @return String representation of the age mask, allocated by GNUNET_malloc.
+ * @return String representation of the age mask.
  *         Can be used as value in the TALER config.
  */
-char *
+const char *
 TALER_age_mask_to_string (
   const struct TALER_AgeMask *mask);
 
diff --git a/src/lib/exchange_api_link.c b/src/lib/exchange_api_link.c
index 04beeb29..86637683 100644
--- a/src/lib/exchange_api_link.c
+++ b/src/lib/exchange_api_link.c
@@ -114,6 +114,7 @@ parse_link_coin (const struct TALER_EXCHANGE_LinkHandle *lh,
   struct TALER_TransferSecretP secret;
   struct TALER_PlanchetDetail pd;
   struct TALER_CoinPubHashP c_hash;
+  struct TALER_AgeCommitmentHash *pach = NULL;
 
   /* parse reply */
   if (GNUNET_OK !=
@@ -137,34 +138,35 @@ parse_link_coin (const struct TALER_EXCHANGE_LinkHandle 
*lh,
                                          &alg_values,
                                          &bks);
 
-  lci->age_commitment_proof = NULL;
-  lci->h_age_commitment = NULL;
+  lci->has_age_commitment = false;
 
   /* Derive the age commitment and calculate the hash */
   if (NULL != lh->age_commitment_proof)
   {
-    lci->age_commitment_proof = GNUNET_new (struct TALER_AgeCommitmentProof);
-    lci->h_age_commitment = GNUNET_new (struct TALER_AgeCommitmentHash);
 
     GNUNET_assert (GNUNET_OK ==
                    TALER_age_commitment_derive (
                      lh->age_commitment_proof,
                      &secret.key,
-                     lci->age_commitment_proof));
+                     &lci->age_commitment_proof));
 
     TALER_age_commitment_hash (
-      &(lci->age_commitment_proof->commitment),
-      lci->h_age_commitment);
+      &lci->age_commitment_proof.commitment,
+      &lci->h_age_commitment);
+
+    lci->has_age_commitment = true;
+    pach = &lci->h_age_commitment;
   }
 
   if (GNUNET_OK !=
-      TALER_planchet_prepare (&rpub,
-                              &alg_values,
-                              &bks,
-                              &lci->coin_priv,
-                              lci->h_age_commitment,
-                              &c_hash,
-                              &pd))
+      TALER_planchet_prepare (
+        &rpub,
+        &alg_values,
+        &bks,
+        &lci->coin_priv,
+        pach,
+        &c_hash,
+        &pd))
   {
     GNUNET_break (0);
     GNUNET_JSON_parse_free (spec);
@@ -364,6 +366,8 @@ parse_link_ok (struct TALER_EXCHANGE_LinkHandle *lh,
     {
       TALER_denom_sig_free (&lcis[i].sig);
       TALER_denom_pub_free (&lcis[i].pub);
+      if (lcis[i].has_age_commitment)
+        TALER_age_commitment_proof_free (&lcis[i].age_commitment_proof);
     }
   }
   return ret;
@@ -513,6 +517,7 @@ TALER_EXCHANGE_link_cancel (struct 
TALER_EXCHANGE_LinkHandle *lh)
     GNUNET_CURL_job_cancel (lh->job);
     lh->job = NULL;
   }
+
   GNUNET_free (lh->url);
   GNUNET_free (lh);
 }
diff --git a/src/lib/exchange_api_melt.c b/src/lib/exchange_api_melt.c
index 1da4184d..7fbd2114 100644
--- a/src/lib/exchange_api_melt.c
+++ b/src/lib/exchange_api_melt.c
@@ -336,13 +336,14 @@ start_melt (struct TALER_EXCHANGE_MeltHandle *mh)
   }
   TALER_denom_pub_hash (&mh->md.melted_coin.pub_key,
                         &h_denom_pub);
-  TALER_wallet_melt_sign (&mh->md.melted_coin.melt_amount_with_fee,
-                          &mh->md.melted_coin.fee_melt,
-                          &mh->md.rc,
-                          &h_denom_pub,
-                          mh->md.melted_coin.h_age_commitment,
-                          &mh->md.melted_coin.coin_priv,
-                          &mh->coin_sig);
+  TALER_wallet_melt_sign (
+    &mh->md.melted_coin.melt_amount_with_fee,
+    &mh->md.melted_coin.fee_melt,
+    &mh->md.rc,
+    &h_denom_pub,
+    mh->md.melted_coin.h_age_commitment,
+    &mh->md.melted_coin.coin_priv,
+    &mh->coin_sig);
   GNUNET_CRYPTO_eddsa_key_get_public (&mh->md.melted_coin.coin_priv.eddsa_priv,
                                       &mh->coin_pub.eddsa_pub);
   melt_obj = GNUNET_JSON_PACK (
@@ -357,7 +358,7 @@ start_melt (struct TALER_EXCHANGE_MeltHandle *mh)
     GNUNET_JSON_pack_data_auto ("rc",
                                 &mh->md.rc),
     GNUNET_JSON_pack_allow_null (
-      mh->md.melted_coin.h_age_commitment
+      (NULL != mh->md.melted_coin.h_age_commitment)
       ? GNUNET_JSON_pack_data_auto ("age_commitment_hash",
                                     mh->md.melted_coin.h_age_commitment)
       : GNUNET_JSON_pack_string ("age_commitment_hash",
diff --git a/src/lib/exchange_api_refresh_common.c 
b/src/lib/exchange_api_refresh_common.c
index 581e2115..04c58022 100644
--- a/src/lib/exchange_api_refresh_common.c
+++ b/src/lib/exchange_api_refresh_common.c
@@ -45,6 +45,11 @@ TALER_EXCHANGE_free_melt_data_ (struct MeltData *md)
       struct FreshCoinData *fcd = &md->fcds[j];
 
       TALER_denom_pub_free (&fcd->fresh_pk);
+      for (size_t i = 0; i < TALER_CNC_KAPPA; i++)
+      {
+        TALER_age_commitment_proof_free (fcd->age_commitment_proofs[i]);
+        GNUNET_free (fcd->age_commitment_proofs[i]);
+      }
     }
     GNUNET_free (md->fcds);
   }
@@ -168,7 +173,8 @@ TALER_EXCHANGE_get_melt_data_ (
       union TALER_DenominationBlindingKeyP *bks = &fcd->bks[i];
       struct TALER_PlanchetDetail pd;
       struct TALER_CoinPubHashP c_hash;
-      struct TALER_AgeCommitmentHash *ach = NULL;
+      struct TALER_AgeCommitmentHash ach;
+      struct TALER_AgeCommitmentHash *pach = NULL;
 
       TALER_transfer_secret_to_planchet_secret (&trans_sec,
                                                 j,
@@ -182,22 +188,21 @@ TALER_EXCHANGE_get_melt_data_ (
                                              &alg_values[j],
                                              bks);
 
-      /* Handle age commitment, if present */
-      if (NULL != md->melted_coin.age_commitment_proof)
+      if (NULL != rd->melt_age_commitment_proof)
       {
-        fcd->age_commitment_proof[i] = GNUNET_new (struct
-                                                   TALER_AgeCommitmentProof);
-        ach = GNUNET_new (struct TALER_AgeCommitmentHash);
+        fcd->age_commitment_proofs[i] = GNUNET_new (struct
+                                                    TALER_AgeCommitmentProof);
 
         GNUNET_assert (GNUNET_OK ==
                        TALER_age_commitment_derive (
                          md->melted_coin.age_commitment_proof,
                          &trans_sec.key,
-                         fcd->age_commitment_proof[i]));
+                         fcd->age_commitment_proofs[i]));
 
         TALER_age_commitment_hash (
-          &fcd->age_commitment_proof[i]->commitment,
-          ach);
+          &fcd->age_commitment_proofs[i]->commitment,
+          &ach);
+        pach = &ach;
       }
 
       if (TALER_DENOMINATION_CS == alg_values[j].cipher)
@@ -208,7 +213,7 @@ TALER_EXCHANGE_get_melt_data_ (
                                   &alg_values[j],
                                   bks,
                                   coin_priv,
-                                  ach,
+                                  pach,
                                   &c_hash,
                                   &pd))
       {
diff --git a/src/lib/exchange_api_refresh_common.h 
b/src/lib/exchange_api_refresh_common.h
index c06824fe..0cb80f17 100644
--- a/src/lib/exchange_api_refresh_common.h
+++ b/src/lib/exchange_api_refresh_common.h
@@ -101,10 +101,9 @@ struct FreshCoinData
 
   /**
    * Arrays of age commitments and proofs to be created, one for each
-   * cut-and-choose dimension.  The entries in each list might be NULL and
-   * indicate no age commitment/restriction on the particular coin.
+   * cut-and-choose dimension.  NULL if age restriction is not applicable.
    */
-  struct TALER_AgeCommitmentProof *age_commitment_proof[TALER_CNC_KAPPA];
+  struct TALER_AgeCommitmentProof *age_commitment_proofs[TALER_CNC_KAPPA];
 
   /**
    * Blinding key secrets for the coins, depending on the
diff --git a/src/lib/exchange_api_refreshes_reveal.c 
b/src/lib/exchange_api_refreshes_reveal.c
index 291c3be1..3360accd 100644
--- a/src/lib/exchange_api_refreshes_reveal.c
+++ b/src/lib/exchange_api_refreshes_reveal.c
@@ -125,8 +125,7 @@ refresh_reveal_ok (struct 
TALER_EXCHANGE_RefreshesRevealHandle *rrh,
   }
   for (unsigned int i = 0; i<rrh->md.num_fresh_coins; i++)
   {
-    struct TALER_EXCHANGE_RevealedCoinInfo *rci =
-      &rcis[i];
+    struct TALER_EXCHANGE_RevealedCoinInfo *rci = &rcis[i];
     const struct FreshCoinData *fcd = &rrh->md.fcds[i];
     const struct TALER_DenominationPublicKey *pk;
     json_t *jsonai;
@@ -140,25 +139,25 @@ refresh_reveal_ok (struct 
TALER_EXCHANGE_RefreshesRevealHandle *rrh,
     };
     struct TALER_FreshCoin coin;
     union TALER_DenominationBlindingKeyP bks;
+    const struct TALER_AgeCommitmentHash *pach = NULL;
 
     rci->ps = fcd->ps[rrh->noreveal_index];
     rci->bks = fcd->bks[rrh->noreveal_index];
-    rci->age_commitment_proof = fcd->age_commitment_proof[rrh->noreveal_index];
-    rci->h_age_commitment = NULL;
+    rci->age_commitment_proof = NULL;
+
     pk = &fcd->fresh_pk;
     jsonai = json_array_get (jsona, i);
 
     GNUNET_assert (NULL != jsonai);
-    GNUNET_assert (
-      (NULL != rrh->md.melted_coin.age_commitment_proof) ==
-      (NULL != rci->age_commitment_proof));
 
-    if (NULL != rci->age_commitment_proof)
+    if (NULL != rrh->md.melted_coin.age_commitment_proof)
     {
-      rci->h_age_commitment = GNUNET_new (struct TALER_AgeCommitmentHash);
-      TALER_age_commitment_hash (
-        &rci->age_commitment_proof->commitment,
-        rci->h_age_commitment);
+      rci->age_commitment_proof =
+        fcd->age_commitment_proofs[rrh->noreveal_index];
+
+      TALER_age_commitment_hash (&rci->age_commitment_proof->commitment,
+                                 &rci->h_age_commitment);
+      pach = &rci->h_age_commitment;
     }
 
     if (GNUNET_OK !=
@@ -180,18 +179,20 @@ refresh_reveal_ok (struct 
TALER_EXCHANGE_RefreshesRevealHandle *rrh,
        hence recomputing it here... */
     GNUNET_CRYPTO_eddsa_key_get_public (&rci->coin_priv.eddsa_priv,
                                         &coin_pub.eddsa_pub);
-    TALER_coin_pub_hash (&coin_pub,
-                         rci->h_age_commitment,
-                         &coin_hash);
+    TALER_coin_pub_hash (
+      &coin_pub,
+      pach,
+      &coin_hash);
     if (GNUNET_OK !=
-        TALER_planchet_to_coin (pk,
-                                &blind_sig,
-                                &bks,
-                                &rci->coin_priv,
-                                rci->h_age_commitment,
-                                &coin_hash,
-                                &rrh->alg_values[i],
-                                &coin))
+        TALER_planchet_to_coin (
+          pk,
+          &blind_sig,
+          &bks,
+          &rci->coin_priv,
+          pach,
+          &coin_hash,
+          &rrh->alg_values[i],
+          &coin))
     {
       GNUNET_break_op (0);
       GNUNET_JSON_parse_free (spec);
@@ -257,7 +258,10 @@ handle_refresh_reveal_finished (void *cls,
         rrh->reveal_cb = NULL;
       }
       for (unsigned int i = 0; i<rrh->md.num_fresh_coins; i++)
+      {
         TALER_denom_sig_free (&rcis[i].sig);
+        TALER_age_commitment_proof_free (rcis[i].age_commitment_proof);
+      }
       TALER_EXCHANGE_refreshes_reveal_cancel (rrh);
       return;
     }
@@ -303,7 +307,6 @@ handle_refresh_reveal_finished (void *cls,
 }
 
 
-/* FIXME: refactor this to use struct TALER_EXCHANGE_Handle */
 struct TALER_EXCHANGE_RefreshesRevealHandle *
 TALER_EXCHANGE_refreshes_reveal (
   struct GNUNET_CURL_Context *ctx,
@@ -408,20 +411,19 @@ TALER_EXCHANGE_refreshes_reveal (
   }
 
   /* build array of old age commitment, if applicable */
-  GNUNET_assert ((NULL == rd->melt_age_commitment_proof) ==
-                 (NULL == rd->melt_h_age_commitment));
   if (NULL != rd->melt_age_commitment_proof)
   {
+    GNUNET_assert (NULL != rd->melt_h_age_commitment);
     GNUNET_assert (NULL != (old_age_commitment = json_array ()));
 
     for (size_t i = 0; i < rd->melt_age_commitment_proof->commitment.num; i++)
     {
-      GNUNET_assert (0 ==
-                     json_array_append_new (
-                       old_age_commitment,
-                       GNUNET_JSON_from_data_auto (
-                         &rd->melt_age_commitment_proof->
-                         commitment.keys[i])));
+      enum GNUNET_GenericReturnValue ret;
+      ret = json_array_append_new (
+        old_age_commitment,
+        GNUNET_JSON_from_data_auto (
+          &rd->melt_age_commitment_proof->commitment.keys[i]));
+      GNUNET_assert (0 == ret);
     }
   }
 
diff --git a/src/testing/test_bank_api.c b/src/testing/test_bank_api.c
index e197b152..8f1fe296 100644
--- a/src/testing/test_bank_api.c
+++ b/src/testing/test_bank_api.c
@@ -78,6 +78,9 @@ run (void *cls,
   case TALER_TESTING_BS_IBAN:
     ssoptions = "-ns";
     break;
+  default:
+    ssoptions = NULL;
+    break;
   }
   memset (&wtid,
           42,
diff --git a/src/testing/test_exchange_api.c b/src/testing/test_exchange_api.c
index 0ff9aa6e..21891350 100644
--- a/src/testing/test_exchange_api.c
+++ b/src/testing/test_exchange_api.c
@@ -660,7 +660,6 @@ run (void *cls,
                             "refresh-reveal-age-1",
                             MHD_HTTP_CONFLICT,
                             NULL),
-
     TALER_TESTING_cmd_end ()
   };
 
diff --git a/src/testing/testing_api_cmd_auditor_add.c 
b/src/testing/testing_api_cmd_auditor_add.c
index aaa95552..ac9c2c8f 100644
--- a/src/testing/testing_api_cmd_auditor_add.c
+++ b/src/testing/testing_api_cmd_auditor_add.c
@@ -76,7 +76,8 @@ auditor_add_cb (
   if (ds->expected_response_code != hr->http_status)
   {
     TALER_TESTING_unexpected_status (ds->is,
-                                     hr->http_status);
+                                     hr->http_status,
+                                     ds->expected_response_code);
     return;
   }
   TALER_TESTING_interpreter_next (ds->is);
diff --git a/src/testing/testing_api_cmd_auditor_add_denom_sig.c 
b/src/testing/testing_api_cmd_auditor_add_denom_sig.c
index 2df15fde..6b777689 100644
--- a/src/testing/testing_api_cmd_auditor_add_denom_sig.c
+++ b/src/testing/testing_api_cmd_auditor_add_denom_sig.c
@@ -81,7 +81,8 @@ denom_sig_add_cb (
   if (ds->expected_response_code != hr->http_status)
   {
     TALER_TESTING_unexpected_status (ds->is,
-                                     hr->http_status);
+                                     hr->http_status,
+                                     ds->expected_response_code);
     return;
   }
   TALER_TESTING_interpreter_next (ds->is);
diff --git a/src/testing/testing_api_cmd_auditor_del.c 
b/src/testing/testing_api_cmd_auditor_del.c
index df878f8e..8256bc1c 100644
--- a/src/testing/testing_api_cmd_auditor_del.c
+++ b/src/testing/testing_api_cmd_auditor_del.c
@@ -77,7 +77,8 @@ auditor_del_cb (
   if (ds->expected_response_code != hr->http_status)
   {
     TALER_TESTING_unexpected_status (ds->is,
-                                     hr->http_status);
+                                     hr->http_status,
+                                     ds->expected_response_code);
     return;
   }
   TALER_TESTING_interpreter_next (ds->is);
diff --git a/src/testing/testing_api_cmd_auditor_deposit_confirmation.c 
b/src/testing/testing_api_cmd_auditor_deposit_confirmation.c
index 252e8f52..1e5a6344 100644
--- a/src/testing/testing_api_cmd_auditor_deposit_confirmation.c
+++ b/src/testing/testing_api_cmd_auditor_deposit_confirmation.c
@@ -170,7 +170,8 @@ deposit_confirmation_cb (
       }
     }
     TALER_TESTING_unexpected_status (dcs->is,
-                                     hr->http_status);
+                                     hr->http_status,
+                                     dcs->expected_response_code);
     return;
   }
   TALER_TESTING_interpreter_next (dcs->is);
diff --git a/src/testing/testing_api_cmd_auditor_exchanges.c 
b/src/testing/testing_api_cmd_auditor_exchanges.c
index aa9a1bfb..29d3726a 100644
--- a/src/testing/testing_api_cmd_auditor_exchanges.c
+++ b/src/testing/testing_api_cmd_auditor_exchanges.c
@@ -160,7 +160,8 @@ exchanges_cb (void *cls,
       }
     }
     TALER_TESTING_unexpected_status (es->is,
-                                     hr->http_status);
+                                     hr->http_status,
+                                     es->expected_response_code);
     return;
   }
   if (MHD_HTTP_OK != hr->http_status)
diff --git a/src/testing/testing_api_cmd_bank_transfer.c 
b/src/testing/testing_api_cmd_bank_transfer.c
index 7b9d588c..bfb29e12 100644
--- a/src/testing/testing_api_cmd_bank_transfer.c
+++ b/src/testing/testing_api_cmd_bank_transfer.c
@@ -199,7 +199,8 @@ confirmation_cb (void *cls,
       }
     }
     TALER_TESTING_unexpected_status (is,
-                                     tr->http_status);
+                                     tr->http_status,
+                                     MHD_HTTP_OK);
     return;
   }
 
diff --git a/src/testing/testing_api_cmd_batch_deposit.c 
b/src/testing/testing_api_cmd_batch_deposit.c
index 0a4fbd25..77bfd4d5 100644
--- a/src/testing/testing_api_cmd_batch_deposit.c
+++ b/src/testing/testing_api_cmd_batch_deposit.c
@@ -199,7 +199,8 @@ batch_deposit_cb (void *cls,
   if (ds->expected_response_code != dr->hr.http_status)
   {
     TALER_TESTING_unexpected_status (ds->is,
-                                     dr->hr.http_status);
+                                     dr->hr.http_status,
+                                     ds->expected_response_code);
     return;
   }
   if (MHD_HTTP_OK == dr->hr.http_status)
diff --git a/src/testing/testing_api_cmd_batch_withdraw.c 
b/src/testing/testing_api_cmd_batch_withdraw.c
index 7f680949..da43a9aa 100644
--- a/src/testing/testing_api_cmd_batch_withdraw.c
+++ b/src/testing/testing_api_cmd_batch_withdraw.c
@@ -79,10 +79,10 @@ struct CoinState
 
   /**
    * If age > 0, put here the corresponding age commitment with its proof and
-   * its hash, respectivelly, NULL otherwise.
+   * its hash, respectivelly.
    */
-  struct TALER_AgeCommitmentProof *age_commitment_proof;
-  struct TALER_AgeCommitmentHash *h_age_commitment;
+  struct TALER_AgeCommitmentProof age_commitment_proof;
+  struct TALER_AgeCommitmentHash h_age_commitment;
 
   /**
    * Reserve history entry that corresponds to this coin.
@@ -190,7 +190,8 @@ reserve_batch_withdraw_cb (void *cls,
   if (ws->expected_response_code != wr->hr.http_status)
   {
     TALER_TESTING_unexpected_status (is,
-                                     wr->hr.http_status);
+                                     wr->hr.http_status,
+                                     ws->expected_response_code);
     return;
   }
   switch (wr->hr.http_status)
@@ -315,7 +316,7 @@ batch_withdraw_run (void *cls,
 
     wci->pk = cs->pk;
     wci->ps = &cs->ps;
-    wci->ach = cs->h_age_commitment;
+    wci->ach = &cs->h_age_commitment;
   }
   ws->wsh = TALER_EXCHANGE_batch_withdraw (
     TALER_TESTING_interpreter_get_context (is),
@@ -365,13 +366,8 @@ batch_withdraw_cleanup (void *cls,
       TALER_EXCHANGE_destroy_denomination_key (cs->pk);
       cs->pk = NULL;
     }
-    if (NULL != cs->age_commitment_proof)
-    {
-      TALER_age_commitment_proof_free (cs->age_commitment_proof);
-      cs->age_commitment_proof = NULL;
-    }
-    if (NULL != cs->h_age_commitment)
-      GNUNET_free (cs->h_age_commitment);
+    if (0 < ws->age)
+      TALER_age_commitment_proof_free (&cs->age_commitment_proof);
   }
   GNUNET_free (ws->coins);
   GNUNET_free (ws->exchange_url);
@@ -423,9 +419,13 @@ batch_withdraw_traits (void *cls,
     TALER_TESTING_make_trait_payto_uri (ws->reserve_payto_uri),
     TALER_TESTING_make_trait_exchange_url (ws->exchange_url),
     TALER_TESTING_make_trait_age_commitment_proof (index,
-                                                   cs->age_commitment_proof),
+                                                   ws->age > 0 ?
+                                                   &cs->age_commitment_proof:
+                                                   NULL),
     TALER_TESTING_make_trait_h_age_commitment (index,
-                                               cs->h_age_commitment),
+                                               ws->age > 0 ?
+                                               &cs->h_age_commitment :
+                                               NULL),
     TALER_TESTING_trait_end ()
   };
 
@@ -472,13 +472,9 @@ TALER_TESTING_cmd_batch_withdraw (const char *label,
 
     if (0 < age)
     {
-      struct TALER_AgeCommitmentProof *acp;
-      struct TALER_AgeCommitmentHash *hac;
       struct GNUNET_HashCode seed;
       struct TALER_AgeMask mask;
 
-      acp = GNUNET_new (struct TALER_AgeCommitmentProof);
-      hac = GNUNET_new (struct TALER_AgeCommitmentHash);
       mask = TALER_extensions_get_age_restriction_mask ();
       GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
                                   &seed,
@@ -489,7 +485,7 @@ TALER_TESTING_cmd_batch_withdraw (const char *label,
             &mask,
             age,
             &seed,
-            acp))
+            &cs->age_commitment_proof))
       {
         GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                     "Failed to generate age commitment for age %d at %s\n",
@@ -498,10 +494,8 @@ TALER_TESTING_cmd_batch_withdraw (const char *label,
         GNUNET_assert (0);
       }
 
-      TALER_age_commitment_hash (&acp->commitment,
-                                 hac);
-      cs->age_commitment_proof = acp;
-      cs->h_age_commitment = hac;
+      TALER_age_commitment_hash (&cs->age_commitment_proof.commitment,
+                                 &cs->h_age_commitment);
     }
 
     if (GNUNET_OK !=
diff --git a/src/testing/testing_api_cmd_check_aml_decision.c 
b/src/testing/testing_api_cmd_check_aml_decision.c
index 1f0ada7b..fa0981e0 100644
--- a/src/testing/testing_api_cmd_check_aml_decision.c
+++ b/src/testing/testing_api_cmd_check_aml_decision.c
@@ -80,7 +80,8 @@ check_aml_decision_cb (void *cls,
   if (ds->expected_http_status != adr->hr.http_status)
   {
     TALER_TESTING_unexpected_status (ds->is,
-                                     adr->hr.http_status);
+                                     adr->hr.http_status,
+                                     ds->expected_http_status);
     return;
   }
   if (MHD_HTTP_OK == adr->hr.http_status)
diff --git a/src/testing/testing_api_cmd_check_aml_decisions.c 
b/src/testing/testing_api_cmd_check_aml_decisions.c
index 4d206485..c8c2ec3f 100644
--- a/src/testing/testing_api_cmd_check_aml_decisions.c
+++ b/src/testing/testing_api_cmd_check_aml_decisions.c
@@ -80,7 +80,8 @@ check_aml_decisions_cb (void *cls,
   if (ds->expected_http_status != adr->hr.http_status)
   {
     TALER_TESTING_unexpected_status (ds->is,
-                                     adr->hr.http_status);
+                                     adr->hr.http_status,
+                                     ds->expected_http_status);
     return;
   }
   TALER_TESTING_interpreter_next (ds->is);
diff --git a/src/testing/testing_api_cmd_contract_get.c 
b/src/testing/testing_api_cmd_contract_get.c
index 902ec4a4..fa83d83f 100644
--- a/src/testing/testing_api_cmd_contract_get.c
+++ b/src/testing/testing_api_cmd_contract_get.c
@@ -102,7 +102,8 @@ get_cb (void *cls,
   if (ds->expected_response_code != dr->hr.http_status)
   {
     TALER_TESTING_unexpected_status (ds->is,
-                                     dr->hr.http_status);
+                                     dr->hr.http_status,
+                                     ds->expected_response_code);
     return;
   }
   ref = TALER_TESTING_interpreter_lookup_command (ds->is,
diff --git a/src/testing/testing_api_cmd_deposit.c 
b/src/testing/testing_api_cmd_deposit.c
index f2a3a269..5c98f91a 100644
--- a/src/testing/testing_api_cmd_deposit.c
+++ b/src/testing/testing_api_cmd_deposit.c
@@ -248,8 +248,12 @@ deposit_cb (void *cls,
         return;
       }
     }
-    TALER_TESTING_unexpected_status (ds->is,
-                                     dr->hr.http_status);
+    TALER_TESTING_unexpected_status_with_body (
+      ds->is,
+      dr->hr.http_status,
+      ds->expected_response_code,
+      dr->hr.reply);
+
     return;
   }
   if (MHD_HTTP_OK == dr->hr.http_status)
@@ -280,8 +284,7 @@ deposit_run (void *cls,
   const struct TALER_TESTING_Command *coin_cmd;
   const struct TALER_CoinSpendPrivateKeyP *coin_priv;
   struct TALER_CoinSpendPublicKeyP coin_pub;
-  const struct TALER_AgeCommitmentProof *age_commitment_proof = NULL;
-  struct TALER_AgeCommitmentHash h_age_commitment = {0};
+  const struct TALER_AgeCommitmentHash *phac;
   const struct TALER_EXCHANGE_DenomPublicKey *denom_pub;
   const struct TALER_DenominationSignature *denom_pub_sig;
   struct TALER_CoinSpendSignatureP coin_sig;
@@ -385,9 +388,9 @@ deposit_run (void *cls,
                                            ds->coin_index,
                                            &coin_priv)) ||
        (GNUNET_OK !=
-        TALER_TESTING_get_trait_age_commitment_proof (coin_cmd,
-                                                      ds->coin_index,
-                                                      &age_commitment_proof)) 
||
+        TALER_TESTING_get_trait_h_age_commitment (coin_cmd,
+                                                  ds->coin_index,
+                                                  &phac)) ||
        (GNUNET_OK !=
         TALER_TESTING_get_trait_denom_pub (coin_cmd,
                                            ds->coin_index,
@@ -405,11 +408,6 @@ deposit_run (void *cls,
     return;
   }
 
-  if (NULL != age_commitment_proof)
-  {
-    TALER_age_commitment_hash (&age_commitment_proof->commitment,
-                               &h_age_commitment);
-  }
   ds->deposit_fee = denom_pub->fees.deposit;
   GNUNET_CRYPTO_eddsa_key_get_public (&coin_priv->eddsa_priv,
                                       &coin_pub.eddsa_pub);
@@ -443,7 +441,7 @@ deposit_run (void *cls,
                                &denom_pub->fees.deposit,
                                &h_wire,
                                &h_contract_terms,
-                               &h_age_commitment,
+                               phac,
                                NULL, /* FIXME #7270: add hash of extensions */
                                &denom_pub->h_key,
                                ds->wallet_timestamp,
@@ -456,11 +454,11 @@ deposit_run (void *cls,
   {
     struct TALER_EXCHANGE_CoinDepositDetail cdd = {
       .amount = ds->amount,
-      .h_age_commitment = h_age_commitment,
       .coin_pub = coin_pub,
       .coin_sig = coin_sig,
       .denom_sig = *denom_pub_sig,
-      .h_denom_pub = denom_pub->h_key
+      .h_denom_pub = denom_pub->h_key,
+      .h_age_commitment = {{{0}}},
     };
     struct TALER_EXCHANGE_DepositContractDetail dcd = {
       .wire_deadline = ds->wire_deadline,
@@ -473,6 +471,9 @@ deposit_run (void *cls,
       .refund_deadline = ds->refund_deadline
     };
 
+    if (NULL != phac)
+      cdd.h_age_commitment = *phac;
+
     ds->dh = TALER_EXCHANGE_batch_deposit (
       TALER_TESTING_interpreter_get_context (is),
       exchange_url,
@@ -547,6 +548,7 @@ deposit_traits (void *cls,
   /* Will point to coin cmd internals. */
   const struct TALER_CoinSpendPrivateKeyP *coin_spent_priv;
   const struct TALER_AgeCommitmentProof *age_commitment_proof;
+  const struct TALER_AgeCommitmentHash *h_age_commitment;
 
   if (GNUNET_YES != ds->command_initialized)
   {
@@ -571,12 +573,17 @@ deposit_traits (void *cls,
        (GNUNET_OK !=
         TALER_TESTING_get_trait_age_commitment_proof (coin_cmd,
                                                       ds->coin_index,
-                                                      &age_commitment_proof)) )
+                                                      &age_commitment_proof)) 
||
+       (GNUNET_OK !=
+        TALER_TESTING_get_trait_h_age_commitment (coin_cmd,
+                                                  ds->coin_index,
+                                                  &h_age_commitment)) )
   {
     GNUNET_break (0);
     TALER_TESTING_interpreter_fail (ds->is);
     return GNUNET_NO;
   }
+
   {
     struct TALER_TESTING_Trait traits[] = {
       /* First two traits are only available if
@@ -590,6 +597,8 @@ deposit_traits (void *cls,
                                           coin_spent_priv),
       TALER_TESTING_make_trait_age_commitment_proof (0,
                                                      age_commitment_proof),
+      TALER_TESTING_make_trait_h_age_commitment (0,
+                                                 h_age_commitment),
       TALER_TESTING_make_trait_wire_details (ds->wire_details),
       TALER_TESTING_make_trait_contract_terms (ds->contract_terms),
       TALER_TESTING_make_trait_merchant_priv (&ds->merchant_priv),
diff --git a/src/testing/testing_api_cmd_deposits_get.c 
b/src/testing/testing_api_cmd_deposits_get.c
index 165af9b1..5d4436e2 100644
--- a/src/testing/testing_api_cmd_deposits_get.c
+++ b/src/testing/testing_api_cmd_deposits_get.c
@@ -117,7 +117,8 @@ deposit_wtid_cb (void *cls,
   if (tts->expected_response_code != dr->hr.http_status)
   {
     TALER_TESTING_unexpected_status (is,
-                                     dr->hr.http_status);
+                                     dr->hr.http_status,
+                                     tts->expected_response_code);
     return;
   }
   switch (dr->hr.http_status)
diff --git a/src/testing/testing_api_cmd_get_auditor.c 
b/src/testing/testing_api_cmd_get_auditor.c
index e1ae8ba5..ab4e3266 100644
--- a/src/testing/testing_api_cmd_get_auditor.c
+++ b/src/testing/testing_api_cmd_get_auditor.c
@@ -83,7 +83,8 @@ version_cb (
   if (MHD_HTTP_OK != vr->hr.http_status)
   {
     TALER_TESTING_unexpected_status (gas->is,
-                                     vr->hr.http_status);
+                                     vr->hr.http_status,
+                                     MHD_HTTP_OK);
     return;
   }
   if ( (NULL != gas->priv_file) &&
diff --git a/src/testing/testing_api_cmd_kyc_check_get.c 
b/src/testing/testing_api_cmd_kyc_check_get.c
index bbbd9214..25c7e98b 100644
--- a/src/testing/testing_api_cmd_kyc_check_get.c
+++ b/src/testing/testing_api_cmd_kyc_check_get.c
@@ -78,7 +78,8 @@ check_kyc_cb (void *cls,
   if (kcg->expected_response_code != ks->http_status)
   {
     TALER_TESTING_unexpected_status (is,
-                                     ks->http_status);
+                                     ks->http_status,
+                                     kcg->expected_response_code);
     return;
   }
   switch (ks->http_status)
diff --git a/src/testing/testing_api_cmd_kyc_proof.c 
b/src/testing/testing_api_cmd_kyc_proof.c
index c0fe7495..b079fffc 100644
--- a/src/testing/testing_api_cmd_kyc_proof.c
+++ b/src/testing/testing_api_cmd_kyc_proof.c
@@ -88,7 +88,8 @@ proof_kyc_cb (void *cls,
   if (kcg->expected_response_code != kpr->http_status)
   {
     TALER_TESTING_unexpected_status (is,
-                                     kpr->http_status);
+                                     kpr->http_status,
+                                     kcg->expected_response_code);
     return;
   }
   switch (kpr->http_status)
diff --git a/src/testing/testing_api_cmd_kyc_wallet_get.c 
b/src/testing/testing_api_cmd_kyc_wallet_get.c
index fa6edab2..ffb143ff 100644
--- a/src/testing/testing_api_cmd_kyc_wallet_get.c
+++ b/src/testing/testing_api_cmd_kyc_wallet_get.c
@@ -109,7 +109,8 @@ wallet_kyc_cb (void *cls,
   if (kwg->expected_response_code != wkr->http_status)
   {
     TALER_TESTING_unexpected_status (is,
-                                     wkr->http_status);
+                                     wkr->http_status,
+                                     kwg->expected_response_code);
     return;
   }
   switch (wkr->http_status)
diff --git a/src/testing/testing_api_cmd_purse_create_deposit.c 
b/src/testing/testing_api_cmd_purse_create_deposit.c
index 36dbfbff..cf992946 100644
--- a/src/testing/testing_api_cmd_purse_create_deposit.c
+++ b/src/testing/testing_api_cmd_purse_create_deposit.c
@@ -163,7 +163,8 @@ deposit_cb (void *cls,
   if (ds->expected_response_code != dr->hr.http_status)
   {
     TALER_TESTING_unexpected_status (ds->is,
-                                     dr->hr.http_status);
+                                     dr->hr.http_status,
+                                     ds->expected_response_code);
     return;
   }
   if (MHD_HTTP_OK == dr->hr.http_status)
diff --git a/src/testing/testing_api_cmd_purse_delete.c 
b/src/testing/testing_api_cmd_purse_delete.c
index f6b7d573..26037359 100644
--- a/src/testing/testing_api_cmd_purse_delete.c
+++ b/src/testing/testing_api_cmd_purse_delete.c
@@ -75,7 +75,8 @@ purse_delete_cb (void *cls,
   if (pds->expected_response_code != pdr->hr.http_status)
   {
     TALER_TESTING_unexpected_status (pds->is,
-                                     pdr->hr.http_status);
+                                     pdr->hr.http_status,
+                                     pds->expected_response_code);
     return;
   }
   TALER_TESTING_interpreter_next (pds->is);
diff --git a/src/testing/testing_api_cmd_purse_deposit.c 
b/src/testing/testing_api_cmd_purse_deposit.c
index eafe3342..8533e25c 100644
--- a/src/testing/testing_api_cmd_purse_deposit.c
+++ b/src/testing/testing_api_cmd_purse_deposit.c
@@ -138,7 +138,8 @@ deposit_cb (void *cls,
   if (ds->expected_response_code != dr->hr.http_status)
   {
     TALER_TESTING_unexpected_status (ds->is,
-                                     dr->hr.http_status);
+                                     dr->hr.http_status,
+                                     ds->expected_response_code);
     return;
   }
   if (MHD_HTTP_OK == dr->hr.http_status)
diff --git a/src/testing/testing_api_cmd_purse_merge.c 
b/src/testing/testing_api_cmd_purse_merge.c
index 503ef162..cf9d4f99 100644
--- a/src/testing/testing_api_cmd_purse_merge.c
+++ b/src/testing/testing_api_cmd_purse_merge.c
@@ -178,7 +178,8 @@ merge_cb (void *cls,
   if (ds->expected_response_code != dr->hr.http_status)
   {
     TALER_TESTING_unexpected_status (ds->is,
-                                     dr->hr.http_status);
+                                     dr->hr.http_status,
+                                     ds->expected_response_code);
     return;
   }
   TALER_TESTING_interpreter_next (ds->is);
diff --git a/src/testing/testing_api_cmd_recoup.c 
b/src/testing/testing_api_cmd_recoup.c
index 263a3303..c4e72333 100644
--- a/src/testing/testing_api_cmd_recoup.c
+++ b/src/testing/testing_api_cmd_recoup.c
@@ -90,7 +90,8 @@ recoup_cb (void *cls,
   if (ps->expected_response_code != hr->http_status)
   {
     TALER_TESTING_unexpected_status (is,
-                                     hr->http_status);
+                                     hr->http_status,
+                                     ps->expected_response_code);
     return;
   }
 
diff --git a/src/testing/testing_api_cmd_recoup_refresh.c 
b/src/testing/testing_api_cmd_recoup_refresh.c
index 7de5b96d..f2fc3b6c 100644
--- a/src/testing/testing_api_cmd_recoup_refresh.c
+++ b/src/testing/testing_api_cmd_recoup_refresh.c
@@ -89,7 +89,8 @@ recoup_refresh_cb (void *cls,
   if (rrs->expected_response_code != hr->http_status)
   {
     TALER_TESTING_unexpected_status (is,
-                                     hr->http_status);
+                                     hr->http_status,
+                                     rrs->expected_response_code);
     return;
   }
 
diff --git a/src/testing/testing_api_cmd_refresh.c 
b/src/testing/testing_api_cmd_refresh.c
index 6449c538..3b35a73b 100644
--- a/src/testing/testing_api_cmd_refresh.c
+++ b/src/testing/testing_api_cmd_refresh.c
@@ -75,7 +75,7 @@ struct TALER_TESTING_FreshCoinData
    * applicable.
    */
   struct TALER_AgeCommitmentProof *age_commitment_proof;
-  struct TALER_AgeCommitmentHash *h_age_commitment;
+  struct TALER_AgeCommitmentHash h_age_commitment;
 
   /**
    * The blinding key (needed for recoup operations).
@@ -402,7 +402,8 @@ reveal_cb (void *cls,
       }
     }
     TALER_TESTING_unexpected_status (rrs->is,
-                                     hr->http_status);
+                                     hr->http_status,
+                                     rrs->expected_response_code);
     return;
   }
   melt_cmd = TALER_TESTING_interpreter_lookup_command (rrs->is,
@@ -439,8 +440,13 @@ reveal_cb (void *cls,
         return;
       }
       fc->coin_priv = coin->coin_priv;
-      fc->age_commitment_proof = coin->age_commitment_proof;
-      fc->h_age_commitment = coin->h_age_commitment;
+
+      if (NULL != coin->age_commitment_proof)
+      {
+        fc->age_commitment_proof =
+          TALER_age_commitment_proof_duplicate (coin->age_commitment_proof);
+        fc->h_age_commitment = coin->h_age_commitment;
+      }
 
       TALER_denom_sig_deep_copy (&fc->sig,
                                  &coin->sig);
@@ -558,7 +564,11 @@ refresh_reveal_cleanup (void *cls,
   }
 
   for (unsigned int j = 0; j < rrs->num_fresh_coins; j++)
+  {
     TALER_denom_sig_free (&rrs->fresh_coins[j].sig);
+    TALER_age_commitment_proof_free (rrs->fresh_coins[j].age_commitment_proof);
+    GNUNET_free (rrs->fresh_coins[j].age_commitment_proof);
+  }
 
   GNUNET_free (rrs->fresh_coins);
   GNUNET_free (rrs->psa);
@@ -646,7 +656,8 @@ link_cb (void *cls,
       }
     }
     TALER_TESTING_unexpected_status (rls->is,
-                                     hr->http_status);
+                                     hr->http_status,
+                                     rls->expected_response_code);
     return;
   }
   reveal_cmd = TALER_TESTING_interpreter_lookup_command (rls->is,
@@ -937,8 +948,10 @@ melt_cb (void *cls,
         return;
       }
     }
-    TALER_TESTING_unexpected_status (rms->is,
-                                     hr->http_status);
+    TALER_TESTING_unexpected_status_with_body (rms->is,
+                                               hr->http_status,
+                                               rms->expected_response_code,
+                                               hr->reply);
     return;
   }
   if (MHD_HTTP_OK == hr->http_status)
@@ -1020,12 +1033,12 @@ melt_run (void *cls,
   {
     struct TALER_Amount melt_amount;
     struct TALER_Amount fresh_amount;
-    const struct TALER_AgeCommitmentProof *age_commitment_proof;
-    const struct TALER_AgeCommitmentHash *h_age_commitment;
+    const struct TALER_AgeCommitmentProof *age_commitment_proof = NULL;
+    const struct TALER_AgeCommitmentHash *h_age_commitment = NULL;
     const struct TALER_DenominationSignature *melt_sig;
     const struct TALER_EXCHANGE_DenomPublicKey *melt_denom_pub;
     const struct TALER_TESTING_Command *coin_command;
-    bool age_restricted;
+    bool age_restricted_denom;
 
     if (NULL == (coin_command
                    = TALER_TESTING_interpreter_lookup_command (
@@ -1090,7 +1103,10 @@ melt_run (void *cls,
     /* Melt amount starts with the melt fee of the old coin; we'll add the
        values and withdraw fees of the fresh coins next */
     melt_amount = melt_denom_pub->fees.refresh;
-    age_restricted = melt_denom_pub->key.age_mask.bits != 0;
+    age_restricted_denom = melt_denom_pub->key.age_mask.bits != 0;
+    GNUNET_assert (age_restricted_denom == (NULL != age_commitment_proof));
+    GNUNET_assert ((NULL == age_commitment_proof) ||
+                   (0 < age_commitment_proof->commitment.num));
     for (unsigned int i = 0; i<num_fresh_coins; i++)
     {
       const struct TALER_EXCHANGE_DenomPublicKey *fresh_pk;
@@ -1109,7 +1125,7 @@ melt_run (void *cls,
       }
       fresh_pk = TALER_TESTING_find_pk (TALER_TESTING_get_keys (rms->is),
                                         &fresh_amount,
-                                        age_restricted);
+                                        age_restricted_denom);
       if (NULL == fresh_pk)
       {
         GNUNET_break (0);
@@ -1135,13 +1151,20 @@ melt_run (void *cls,
     rms->refresh_data.melt_amount = melt_amount;
     rms->refresh_data.melt_sig = *melt_sig;
     rms->refresh_data.melt_pk = *melt_denom_pub;
-    rms->refresh_data.melt_age_commitment_proof = age_commitment_proof;
-    rms->refresh_data.melt_h_age_commitment = h_age_commitment;
+
+    if (NULL != age_commitment_proof)
+    {
+      GNUNET_assert (NULL != h_age_commitment);
+      rms->refresh_data.melt_age_commitment_proof = age_commitment_proof;
+      rms->refresh_data.melt_h_age_commitment = h_age_commitment;
+    }
     rms->refresh_data.fresh_pks = rms->fresh_pks;
     rms->refresh_data.fresh_pks_len = num_fresh_coins;
 
-    GNUNET_assert (age_restricted ==
+    GNUNET_assert (age_restricted_denom ==
                    (NULL != age_commitment_proof));
+    GNUNET_assert ((NULL == age_commitment_proof) ||
+                   (0 < age_commitment_proof->commitment.num));
 
     rms->rmh = TALER_EXCHANGE_melt (
       TALER_TESTING_interpreter_get_context (is),
@@ -1194,6 +1217,7 @@ melt_cleanup (void *cls,
       TALER_denom_pub_free (&rms->fresh_pks[i].key);
     GNUNET_free (rms->fresh_pks);
   }
+
   GNUNET_free (rms->mbds);
   GNUNET_free (rms->melt_fresh_amounts);
   GNUNET_free (rms);
@@ -1405,7 +1429,7 @@ refresh_reveal_traits (void *cls,
         rrs->fresh_coins[index].age_commitment_proof),
       TALER_TESTING_make_trait_h_age_commitment (
         index,
-        rrs->fresh_coins[index].h_age_commitment),
+        &rrs->fresh_coins[index].h_age_commitment),
       TALER_TESTING_make_trait_denom_pub (
         index,
         rrs->fresh_coins[index].pk),
@@ -1423,6 +1447,7 @@ refresh_reveal_traits (void *cls,
                                                  &rrs->psa[index]),
       TALER_TESTING_trait_end ()
     };
+
     return TALER_TESTING_get_trait (traits,
                                     ret,
                                     trait,
diff --git a/src/testing/testing_api_cmd_refund.c 
b/src/testing/testing_api_cmd_refund.c
index b8ce85f9..5a218bcf 100644
--- a/src/testing/testing_api_cmd_refund.c
+++ b/src/testing/testing_api_cmd_refund.c
@@ -83,7 +83,8 @@ refund_cb (void *cls,
   if (rs->expected_response_code != hr->http_status)
   {
     TALER_TESTING_unexpected_status (rs->is,
-                                     hr->http_status);
+                                     hr->http_status,
+                                     rs->expected_response_code);
     return;
   }
   TALER_TESTING_interpreter_next (rs->is);
diff --git a/src/testing/testing_api_cmd_reserve_purse.c 
b/src/testing/testing_api_cmd_reserve_purse.c
index 511e2d49..ef6964f2 100644
--- a/src/testing/testing_api_cmd_reserve_purse.c
+++ b/src/testing/testing_api_cmd_reserve_purse.c
@@ -154,7 +154,8 @@ purse_cb (void *cls,
   if (ds->expected_response_code != dr->hr.http_status)
   {
     TALER_TESTING_unexpected_status (ds->is,
-                                     dr->hr.http_status);
+                                     dr->hr.http_status,
+                                     ds->expected_response_code);
     return;
   }
   switch (dr->hr.http_status)
diff --git a/src/testing/testing_api_cmd_revoke_denom_key.c 
b/src/testing/testing_api_cmd_revoke_denom_key.c
index 8bbfda63..2663c538 100644
--- a/src/testing/testing_api_cmd_revoke_denom_key.c
+++ b/src/testing/testing_api_cmd_revoke_denom_key.c
@@ -79,7 +79,8 @@ success_cb (
   if (rs->expected_response_code != hr->http_status)
   {
     TALER_TESTING_unexpected_status (rs->is,
-                                     hr->http_status);
+                                     hr->http_status,
+                                     rs->expected_response_code);
     return;
   }
   TALER_TESTING_interpreter_next (rs->is);
diff --git a/src/testing/testing_api_cmd_revoke_sign_key.c 
b/src/testing/testing_api_cmd_revoke_sign_key.c
index 477ffbe8..65b80b4c 100644
--- a/src/testing/testing_api_cmd_revoke_sign_key.c
+++ b/src/testing/testing_api_cmd_revoke_sign_key.c
@@ -79,7 +79,8 @@ success_cb (
   if (rs->expected_response_code != hr->http_status)
   {
     TALER_TESTING_unexpected_status (rs->is,
-                                     hr->http_status);
+                                     hr->http_status,
+                                     rs->expected_response_code);
     return;
   }
   TALER_TESTING_interpreter_next (rs->is);
diff --git a/src/testing/testing_api_cmd_run_fakebank.c 
b/src/testing/testing_api_cmd_run_fakebank.c
index 03b36763..7739d3c0 100644
--- a/src/testing/testing_api_cmd_run_fakebank.c
+++ b/src/testing/testing_api_cmd_run_fakebank.c
@@ -195,6 +195,7 @@ TALER_TESTING_cmd_run_fakebank (
                      (unsigned int) fakebank_port,
                      exchange_xtalerbank_account);
     GNUNET_free (exchange_xtalerbank_account);
+    GNUNET_free (exchange_payto_uri);
   }
   GNUNET_free (exchange_payto_uri);
   rfs->ba.method = TALER_BANK_AUTH_NONE;
diff --git a/src/testing/testing_api_cmd_set_officer.c 
b/src/testing/testing_api_cmd_set_officer.c
index f2464c8a..4fbe5e36 100644
--- a/src/testing/testing_api_cmd_set_officer.c
+++ b/src/testing/testing_api_cmd_set_officer.c
@@ -98,7 +98,8 @@ set_officer_cb (void *cls,
   if (MHD_HTTP_NO_CONTENT != hr->http_status)
   {
     TALER_TESTING_unexpected_status (ds->is,
-                                     hr->http_status);
+                                     hr->http_status,
+                                     MHD_HTTP_NO_CONTENT);
     return;
   }
   TALER_TESTING_interpreter_next (ds->is);
diff --git a/src/testing/testing_api_cmd_set_wire_fee.c 
b/src/testing/testing_api_cmd_set_wire_fee.c
index b2002e0f..460a71e4 100644
--- a/src/testing/testing_api_cmd_set_wire_fee.c
+++ b/src/testing/testing_api_cmd_set_wire_fee.c
@@ -90,7 +90,8 @@ wire_add_cb (void *cls,
   if (ds->expected_response_code != hr->http_status)
   {
     TALER_TESTING_unexpected_status (ds->is,
-                                     hr->http_status);
+                                     hr->http_status,
+                                     ds->expected_response_code);
     return;
   }
   TALER_TESTING_interpreter_next (ds->is);
diff --git a/src/testing/testing_api_cmd_take_aml_decision.c 
b/src/testing/testing_api_cmd_take_aml_decision.c
index eb758397..c0e23de2 100644
--- a/src/testing/testing_api_cmd_take_aml_decision.c
+++ b/src/testing/testing_api_cmd_take_aml_decision.c
@@ -108,7 +108,8 @@ take_aml_decision_cb (
   if (ds->expected_response != hr->http_status)
   {
     TALER_TESTING_unexpected_status (ds->is,
-                                     hr->http_status);
+                                     hr->http_status,
+                                     ds->expected_response);
     return;
   }
   TALER_TESTING_interpreter_next (ds->is);
diff --git a/src/testing/testing_api_cmd_transfer_get.c 
b/src/testing/testing_api_cmd_transfer_get.c
index da3585d6..405c8b7f 100644
--- a/src/testing/testing_api_cmd_transfer_get.c
+++ b/src/testing/testing_api_cmd_transfer_get.c
@@ -133,7 +133,8 @@ track_transfer_cb (void *cls,
   if (tts->expected_response_code != hr->http_status)
   {
     TALER_TESTING_unexpected_status (is,
-                                     hr->http_status);
+                                     hr->http_status,
+                                     tts->expected_response_code);
     return;
   }
 
diff --git a/src/testing/testing_api_cmd_wire_add.c 
b/src/testing/testing_api_cmd_wire_add.c
index b19cca1e..09d4579c 100644
--- a/src/testing/testing_api_cmd_wire_add.c
+++ b/src/testing/testing_api_cmd_wire_add.c
@@ -80,7 +80,8 @@ wire_add_cb (void *cls,
   if (ds->expected_response_code != hr->http_status)
   {
     TALER_TESTING_unexpected_status (ds->is,
-                                     hr->http_status);
+                                     hr->http_status,
+                                     ds->expected_response_code);
     return;
   }
   TALER_TESTING_interpreter_next (ds->is);
diff --git a/src/testing/testing_api_cmd_wire_del.c 
b/src/testing/testing_api_cmd_wire_del.c
index 61405e6e..50ebfc7c 100644
--- a/src/testing/testing_api_cmd_wire_del.c
+++ b/src/testing/testing_api_cmd_wire_del.c
@@ -80,7 +80,9 @@ wire_del_cb (void *cls,
   if (ds->expected_response_code != hr->http_status)
   {
     TALER_TESTING_unexpected_status (ds->is,
-                                     hr->http_status);
+                                     hr->http_status,
+                                     ds->expected_response_code);
+
     return;
   }
   TALER_TESTING_interpreter_next (ds->is);
diff --git a/src/testing/testing_api_cmd_withdraw.c 
b/src/testing/testing_api_cmd_withdraw.c
index 3e735ad0..2550e55a 100644
--- a/src/testing/testing_api_cmd_withdraw.c
+++ b/src/testing/testing_api_cmd_withdraw.c
@@ -144,10 +144,10 @@ struct WithdrawState
 
   /**
    * If age > 0, put here the corresponding age commitment with its proof and
-   * its hash, respectivelly, NULL otherwise.
+   * its hash, respectivelly.
    */
-  struct TALER_AgeCommitmentProof *age_commitment_proof;
-  struct TALER_AgeCommitmentHash *h_age_commitment;
+  struct TALER_AgeCommitmentProof age_commitment_proof;
+  struct TALER_AgeCommitmentHash h_age_commitment;
 
   /**
    * Reserve history entry that corresponds to this operation.
@@ -284,7 +284,8 @@ reserve_withdraw_cb (void *cls,
       }
     }
     TALER_TESTING_unexpected_status (is,
-                                     wr->hr.http_status);
+                                     wr->hr.http_status,
+                                     ws->expected_response_code);
     return;
   }
   switch (wr->hr.http_status)
@@ -437,7 +438,7 @@ withdraw_run (void *cls,
     struct TALER_EXCHANGE_WithdrawCoinInput wci = {
       .pk = ws->pk,
       .ps = &ws->ps,
-      .ach = ws->h_age_commitment
+      .ach = 0 < ws->age ? &ws->h_age_commitment : NULL
     };
     ws->wsh = TALER_EXCHANGE_withdraw (
       TALER_TESTING_interpreter_get_context (is),
@@ -488,16 +489,8 @@ withdraw_cleanup (void *cls,
     TALER_EXCHANGE_destroy_denomination_key (ws->pk);
     ws->pk = NULL;
   }
-  if (NULL != ws->age_commitment_proof)
-  {
-    TALER_age_commitment_proof_free (ws->age_commitment_proof);
-    ws->age_commitment_proof = NULL;
-  }
-  if (NULL != ws->h_age_commitment)
-  {
-    GNUNET_free (ws->h_age_commitment);
-    ws->h_age_commitment = NULL;
-  }
+  if (ws->age > 0)
+    TALER_age_commitment_proof_free (&ws->age_commitment_proof);
   GNUNET_free (ws->exchange_url);
   GNUNET_free (ws->reserve_payto_uri);
   GNUNET_free (ws);
@@ -544,9 +537,13 @@ withdraw_traits (void *cls,
     TALER_TESTING_make_trait_payto_uri (ws->reserve_payto_uri),
     TALER_TESTING_make_trait_exchange_url (ws->exchange_url),
     TALER_TESTING_make_trait_age_commitment_proof (0,
-                                                   ws->age_commitment_proof),
+                                                   0 < ws->age
+                                                   ? &ws->age_commitment_proof
+                                                   : NULL),
     TALER_TESTING_make_trait_h_age_commitment (0,
-                                               ws->h_age_commitment),
+                                               0 < ws->age
+                                               ? &ws->h_age_commitment
+                                               : NULL),
     TALER_TESTING_trait_end ()
   };
 
@@ -572,13 +569,9 @@ TALER_TESTING_cmd_withdraw_amount (const char *label,
   ws->age = age;
   if (0 < age)
   {
-    struct TALER_AgeCommitmentProof *acp;
-    struct TALER_AgeCommitmentHash *hac;
     struct GNUNET_HashCode seed;
     struct TALER_AgeMask mask;
 
-    acp = GNUNET_new (struct TALER_AgeCommitmentProof);
-    hac = GNUNET_new (struct TALER_AgeCommitmentHash);
     mask = TALER_extensions_get_age_restriction_mask ();
     GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
                                 &seed,
@@ -589,7 +582,7 @@ TALER_TESTING_cmd_withdraw_amount (const char *label,
           &mask,
           age,
           &seed,
-          acp))
+          &ws->age_commitment_proof))
     {
       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                   "Failed to generate age commitment for age %d at %s\n",
@@ -597,10 +590,8 @@ TALER_TESTING_cmd_withdraw_amount (const char *label,
                   label);
       GNUNET_assert (0);
     }
-    TALER_age_commitment_hash (&acp->commitment,
-                               hac);
-    ws->age_commitment_proof = acp;
-    ws->h_age_commitment = hac;
+    TALER_age_commitment_hash (&ws->age_commitment_proof.commitment,
+                               &ws->h_age_commitment);
   }
 
   ws->reserve_reference = reserve_reference;
diff --git a/src/util/age_restriction.c b/src/util/age_restriction.c
index 6f070229..eec0c834 100644
--- a/src/util/age_restriction.c
+++ b/src/util/age_restriction.c
@@ -464,6 +464,9 @@ void
 TALER_age_proof_free (
   struct TALER_AgeProof *proof)
 {
+  if (NULL == proof)
+    return;
+
   if (NULL != proof->keys)
   {
     GNUNET_CRYPTO_zero_keys (
@@ -479,26 +482,71 @@ TALER_age_proof_free (
 
 void
 TALER_age_commitment_proof_free (
-  struct TALER_AgeCommitmentProof *cp)
+  struct TALER_AgeCommitmentProof *acp)
 {
-  if (NULL != cp->proof.keys)
+  if (NULL == acp)
+    return;
+
+  if (NULL != acp->proof.keys)
   {
     GNUNET_CRYPTO_zero_keys (
-      cp->proof.keys,
-      sizeof(*cp->proof.keys) * cp->proof.num);
+      acp->proof.keys,
+      sizeof(*acp->proof.keys) * acp->proof.num);
 
-    GNUNET_free (cp->proof.keys);
-    cp->proof.keys = NULL;
+    GNUNET_free (acp->proof.keys);
+    acp->proof.keys = NULL;
   }
 
-  if (NULL != cp->commitment.keys)
+  if (NULL != acp->commitment.keys)
   {
-    GNUNET_free (cp->commitment.keys);
-    cp->commitment.keys = NULL;
+    GNUNET_free (acp->commitment.keys);
+    acp->commitment.keys = NULL;
   }
 }
 
 
+struct TALER_AgeCommitmentProof *
+TALER_age_commitment_proof_duplicate (
+  const struct TALER_AgeCommitmentProof *acp)
+{
+  struct TALER_AgeCommitmentProof *nacp;
+
+  GNUNET_assert (NULL != acp);
+  GNUNET_assert (__builtin_popcount (acp->commitment.mask.bits) - 1 ==
+                 (int) acp->commitment.num);
+
+  nacp = GNUNET_new (struct TALER_AgeCommitmentProof);
+
+  TALER_age_commitment_proof_deep_copy (acp,nacp);
+  return nacp;
+}
+
+
+void
+TALER_age_commitment_proof_deep_copy (
+  const struct TALER_AgeCommitmentProof *acp,
+  struct TALER_AgeCommitmentProof *nacp)
+{
+  GNUNET_assert (NULL != acp);
+  GNUNET_assert (__builtin_popcount (acp->commitment.mask.bits) - 1 ==
+                 (int) acp->commitment.num);
+
+  *nacp = *acp;
+  nacp->commitment.keys =
+    GNUNET_new_array (acp->commitment.num,
+                      struct TALER_AgeCommitmentPublicKeyP);
+  nacp->proof.keys =
+    GNUNET_new_array (acp->proof.num,
+                      struct TALER_AgeCommitmentPrivateKeyP);
+
+  for (size_t i = 0; i < acp->commitment.num; i++)
+    nacp->commitment.keys[i] = acp->commitment.keys[i];
+
+  for (size_t i = 0; i < acp->proof.num; i++)
+    nacp->proof.keys[i] = acp->proof.keys[i];
+}
+
+
 enum GNUNET_GenericReturnValue
 TALER_JSON_parse_age_groups (const json_t *root,
                              struct TALER_AgeMask *mask)
@@ -571,19 +619,16 @@ TALER_parse_age_group_string (
 }
 
 
-char *
+const char *
 TALER_age_mask_to_string (
   const struct TALER_AgeMask *mask)
 {
+  static char buf[256] = {0};
   uint32_t bits = mask->bits;
   unsigned int n = 0;
-  char *buf = GNUNET_malloc (32 * 3); // max characters possible
   char *pos = buf;
 
-  if (NULL == buf)
-  {
-    return buf;
-  }
+  memset (buf, 0, sizeof(buf));
 
   while (bits != 0)
   {

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