gnunet-svn
[Top][All Lists]
Advanced

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

[taler-exchange] branch master updated (54a19689 -> a162761c)


From: gnunet
Subject: [taler-exchange] branch master updated (54a19689 -> a162761c)
Date: Fri, 22 Dec 2023 22:18:19 +0100

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

oec pushed a change to branch master
in repository exchange.

    from 54a19689 -fix error handling
     new 1217a57e [ci] use "localhost/$REPO_NAME" as default JOB_CONTAINER
     new f7745020 [wip, #7267] added first test to detect denom-conflict on 
deposit
     new a162761c Merge branch 'master' of ssh://git.taler.net/exchange

The 3 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:
 contrib/ci/ci.sh                                   |   2 +-
 src/include/taler_testing_lib.h                    | 414 ++++++++++++---------
 src/testing/.gitignore                             |   2 +
 src/testing/Makefile.am                            |  33 ++
 ...cs.conf => test_exchange_api_conflicts-cs.conf} |   2 +-
 ...a.conf => test_exchange_api_conflicts-rsa.conf} |   2 +-
 src/testing/test_exchange_api_conflicts.c          | 220 +++++++++++
 ...ction.conf => test_exchange_api_conflicts.conf} |  40 +-
 src/testing/testing_api_cmd_batch_withdraw.c       |  72 ++--
 9 files changed, 538 insertions(+), 249 deletions(-)
 copy src/testing/{test_auditor_api-cs.conf => 
test_exchange_api_conflicts-cs.conf} (59%)
 copy src/testing/{test_exchange_api-rsa.conf => 
test_exchange_api_conflicts-rsa.conf} (60%)
 create mode 100644 src/testing/test_exchange_api_conflicts.c
 copy src/testing/{test_exchange_api_age_restriction.conf => 
test_exchange_api_conflicts.conf} (65%)

diff --git a/contrib/ci/ci.sh b/contrib/ci/ci.sh
index dd7277c0..f0be8424 100755
--- a/contrib/ci/ci.sh
+++ b/contrib/ci/ci.sh
@@ -5,7 +5,7 @@ set -exvuo pipefail
 OCI_RUNTIME=$(which podman)
 REPO_NAME=$(basename "${PWD}")
 JOB_NAME="${1}"
-JOB_CONTAINER=$((grep CONTAINER_NAME contrib/ci/jobs/${JOB_NAME}/config.ini | 
cut -d' ' -f 3) || echo "${REPO_NAME}")
+JOB_CONTAINER=$((grep CONTAINER_NAME contrib/ci/jobs/${JOB_NAME}/config.ini | 
cut -d' ' -f 3) || echo "localhost/${REPO_NAME}")
 JOB_ARCH=$((grep CONTAINER_ARCH contrib/ci/jobs/${JOB_NAME}/config.ini | cut 
-d' ' -f 3) || echo "${2:-amd64}")
 CONTAINER_BUILD=$((grep CONTAINER_BUILD contrib/ci/jobs/${JOB_NAME}/config.ini 
| cut -d' ' -f 3) || echo "True")
 
diff --git a/src/include/taler_testing_lib.h b/src/include/taler_testing_lib.h
index 90f6ade8..e8977961 100644
--- a/src/include/taler_testing_lib.h
+++ b/src/include/taler_testing_lib.h
@@ -43,12 +43,12 @@
  * quite any time after the command "run" method has been called.
  */
 #define TALER_TESTING_FAIL(is) \
-  do \
-  { \
-    GNUNET_break (0); \
-    TALER_TESTING_interpreter_fail (is); \
-    return; \
-  } while (0)
+        do \
+        { \
+          GNUNET_break (0); \
+          TALER_TESTING_interpreter_fail (is); \
+          return; \
+        } while (0)
 
 
 /**
@@ -60,16 +60,16 @@
  * @param expected expected HTTP status code
  */
 #define TALER_TESTING_unexpected_status(is,status,expected)             \
-  do {                                                                  \
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,                                \
-                "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)
+        do {                                                                  \
+          GNUNET_log (GNUNET_ERROR_TYPE_ERROR,                                \
+                      "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
@@ -82,18 +82,18 @@
  * @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)
+        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)
 
 
 /**
@@ -104,14 +104,14 @@
  * @param label command label of the incomplete command
  */
 #define TALER_TESTING_command_incomplete(is,label)                      \
-  do {                                                                  \
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,                                \
-                "Command %s (%s:%u) did not complete (at %s)\n",        \
-                label,                                                  \
-                __FILE__,                                               \
-                __LINE__,                                               \
-                TALER_TESTING_interpreter_get_current_label (is));      \
-  } while (0)
+        do {                                                                  \
+          GNUNET_log (GNUNET_ERROR_TYPE_ERROR,                                \
+                      "Command %s (%s:%u) did not complete (at %s)\n",        \
+                      label,                                                  \
+                      __FILE__,                                               \
+                      __LINE__,                                               \
+                      TALER_TESTING_interpreter_get_current_label (is));      \
+        } while (0)
 
 
 /**
@@ -311,10 +311,10 @@ struct TALER_TESTING_Command
    * @return #GNUNET_OK on success
    */
   enum GNUNET_GenericReturnValue
-  (*traits)(void *cls,
-            const void **ret,
-            const char *trait,
-            unsigned int index);
+    (*traits)(void *cls,
+              const void **ret,
+              const char *trait,
+              unsigned int index);
 
   /**
    * When did the execution of this command start?
@@ -1079,12 +1079,53 @@ TALER_TESTING_cmd_withdraw_amount (const char *label,
                                    uint8_t age,
                                    unsigned int expected_response_code);
 
+/**
+ * Force a conflict
+   * 0: no conflict
+   * 1: multiple coins with same private key, different denominations
+   * 2: multiple coins with same private key and different age restriction
+   */
+enum TALER_TESTING_CoinConflictType
+{
+  Conflict_None = 0,
+  Conflict_Denom = 1,
+  Conflict_Age = 2
+};
+
+/**
+ * Create a batch withdraw command, letting the caller specify the type of
+ * conflict between the coins and the desired amounts as string.
+ *
+ * Takes a variable, non-empty list of the denomination amounts via VARARGS,
+ * similar to #TALER_TESTING_cmd_withdraw_amount(), just using a batch
+ * withdraw.
+ *
+ * @param label command label.
+ * @param reserve_reference command providing us with a reserve to withdraw 
from
+ * @param conflict type of conflict for the coins
+ * @param age if > 0, age restriction applies (same for all coins)
+ * @param expected_response_code which HTTP response code
+ *        we expect from the exchange.
+ * @param amount how much we withdraw for the first coin
+ * @param ... NULL-terminated list of additional amounts to withdraw (one per 
coin)
+ * @return the withdraw command to be executed by the interpreter.
+ */
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_batch_withdraw_with_conflict (
+  const char *label,
+  const char *reserve_reference,
+  enum TALER_TESTING_CoinConflictType conflict,
+  uint8_t age,
+  unsigned int expected_response_code,
+  const char *amount,
+  ...);
 
 /**
  * Create a batch withdraw command, letting the caller specify
  * the desired amounts as string.  Takes a variable, non-empty
  * list of the denomination amounts via VARARGS, similar to
  * #TALER_TESTING_cmd_withdraw_amount(), just using a batch withdraw.
+ * The coins are generated without a conflict (different private keys).
  *
  * @param label command label.
  * @param reserve_reference command providing us with a reserve to withdraw 
from
@@ -1095,13 +1136,20 @@ TALER_TESTING_cmd_withdraw_amount (const char *label,
  * @param ... NULL-terminated list of additional amounts to withdraw (one per 
coin)
  * @return the withdraw command to be executed by the interpreter.
  */
-struct TALER_TESTING_Command
-TALER_TESTING_cmd_batch_withdraw (const char *label,
-                                  const char *reserve_reference,
-                                  uint8_t age,
-                                  unsigned int expected_response_code,
-                                  const char *amount,
-                                  ...);
+#define TALER_TESTING_cmd_batch_withdraw(label, \
+                                         reserve_reference, \
+                                         age, \
+                                         expected_response_code, \
+                                         amount, \
+                                         ...) \
+        TALER_TESTING_cmd_batch_withdraw_with_conflict ( \
+          (label), \
+          (reserve_reference), \
+          Conflict_None, \
+          (age), \
+          (expected_response_code), \
+          (amount), \
+          __VA_ARGS__)
 
 /**
  * Create an age-withdraw command, letting the caller specify
@@ -2231,7 +2279,7 @@ TALER_TESTING_cmd_oauth_with_birthdate (const char *label,
  * @param port the TCP port to listen on
  */
 #define TALER_TESTING_cmd_oauth(label, port) \
-  TALER_TESTING_cmd_oauth_with_birthdate ((label), NULL, (port))
+        TALER_TESTING_cmd_oauth_with_birthdate ((label), NULL, (port))
 
 
 /* ****************** P2P payment commands ****************** */
@@ -2560,13 +2608,13 @@ TALER_TESTING_get_trait (const struct 
TALER_TESTING_Trait *traits,
  * statically allocated data of type @a type.
  */
 #define TALER_TESTING_MAKE_DECL_SIMPLE_TRAIT(name,type)   \
-  enum GNUNET_GenericReturnValue                          \
-    TALER_TESTING_get_trait_ ## name (                    \
-    const struct TALER_TESTING_Command *cmd,              \
-    type **ret);                                          \
-  struct TALER_TESTING_Trait                              \
-    TALER_TESTING_make_trait_ ## name (                   \
-    type * value);
+        enum GNUNET_GenericReturnValue                          \
+        TALER_TESTING_get_trait_ ## name (                    \
+          const struct TALER_TESTING_Command *cmd,              \
+          type **ret);                                          \
+        struct TALER_TESTING_Trait                              \
+        TALER_TESTING_make_trait_ ## name (                   \
+          type * value);
 
 
 /**
@@ -2574,27 +2622,27 @@ TALER_TESTING_get_trait (const struct 
TALER_TESTING_Trait *traits,
  * allocated data of type @a type.
  */
 #define TALER_TESTING_MAKE_IMPL_SIMPLE_TRAIT(name,type)  \
-  enum GNUNET_GenericReturnValue                         \
-    TALER_TESTING_get_trait_ ## name (                   \
-    const struct TALER_TESTING_Command *cmd,             \
-    type **ret)                                          \
-  {                                                      \
-    if (NULL == cmd->traits) return GNUNET_SYSERR;       \
-    return cmd->traits (cmd->cls,                        \
-                        (const void **) ret,             \
-                        TALER_S (name),                  \
-                        0);                              \
-  }                                                      \
-  struct TALER_TESTING_Trait                             \
-    TALER_TESTING_make_trait_ ## name (                  \
-    type * value)                                        \
-  {                                                      \
-    struct TALER_TESTING_Trait ret = {                   \
-      .trait_name = TALER_S (name),                      \
-      .ptr = (const void *) value                        \
-    };                                                   \
-    return ret;                                          \
-  }
+        enum GNUNET_GenericReturnValue                         \
+        TALER_TESTING_get_trait_ ## name (                   \
+          const struct TALER_TESTING_Command *cmd,             \
+          type * *ret)                                          \
+        {                                                      \
+          if (NULL == cmd->traits) return GNUNET_SYSERR;       \
+          return cmd->traits (cmd->cls,                        \
+                              (const void **) ret,             \
+                              TALER_S (name),                  \
+                              0);                              \
+        }                                                      \
+        struct TALER_TESTING_Trait                             \
+        TALER_TESTING_make_trait_ ## name (                  \
+          type * value)                                        \
+        {                                                      \
+          struct TALER_TESTING_Trait ret = {                   \
+            .trait_name = TALER_S (name),                      \
+            .ptr = (const void *) value                        \
+          };                                                   \
+          return ret;                                          \
+        }
 
 
 /**
@@ -2602,15 +2650,15 @@ TALER_TESTING_get_trait (const struct 
TALER_TESTING_Trait *traits,
  * statically allocated data of type @a type.
  */
 #define TALER_TESTING_MAKE_DECL_INDEXED_TRAIT(name,type)  \
-  enum GNUNET_GenericReturnValue                          \
-    TALER_TESTING_get_trait_ ## name (                    \
-    const struct TALER_TESTING_Command *cmd,              \
-    unsigned int index,                                   \
-    type **ret);                                          \
-  struct TALER_TESTING_Trait                              \
-    TALER_TESTING_make_trait_ ## name (                   \
-    unsigned int index,                                   \
-    type * value);
+        enum GNUNET_GenericReturnValue                          \
+        TALER_TESTING_get_trait_ ## name (                    \
+          const struct TALER_TESTING_Command *cmd,              \
+          unsigned int index,                                   \
+          type **ret);                                          \
+        struct TALER_TESTING_Trait                              \
+        TALER_TESTING_make_trait_ ## name (                   \
+          unsigned int index,                                   \
+          type *value);
 
 
 /**
@@ -2618,116 +2666,116 @@ TALER_TESTING_get_trait (const struct 
TALER_TESTING_Trait *traits,
  * allocated data of type @a type.
  */
 #define TALER_TESTING_MAKE_IMPL_INDEXED_TRAIT(name,type) \
-  enum GNUNET_GenericReturnValue                         \
-    TALER_TESTING_get_trait_ ## name (                   \
-    const struct TALER_TESTING_Command *cmd,             \
-    unsigned int index,                                  \
-    type **ret)                                          \
-  {                                                      \
-    if (NULL == cmd->traits) return GNUNET_SYSERR;       \
-    return cmd->traits (cmd->cls,                        \
-                        (const void **) ret,             \
-                        TALER_S (name),                  \
-                        index);                          \
-  }                                                      \
-  struct TALER_TESTING_Trait                             \
-    TALER_TESTING_make_trait_ ## name (                  \
-    unsigned int index,                                  \
-    type * value)                                        \
-  {                                                      \
-    struct TALER_TESTING_Trait ret = {                   \
-      .index = index,                                    \
-      .trait_name = TALER_S (name),                      \
-      .ptr = (const void *) value                        \
-    };                                                   \
-    return ret;                                          \
-  }
+        enum GNUNET_GenericReturnValue                         \
+        TALER_TESTING_get_trait_ ## name (                   \
+          const struct TALER_TESTING_Command *cmd,             \
+          unsigned int index,                                  \
+          type * *ret)                                          \
+        {                                                      \
+          if (NULL == cmd->traits) return GNUNET_SYSERR;       \
+          return cmd->traits (cmd->cls,                        \
+                              (const void **) ret,             \
+                              TALER_S (name),                  \
+                              index);                          \
+        }                                                      \
+        struct TALER_TESTING_Trait                             \
+        TALER_TESTING_make_trait_ ## name (                  \
+          unsigned int index,                                  \
+          type * value)                                        \
+        {                                                      \
+          struct TALER_TESTING_Trait ret = {                   \
+            .index = index,                                    \
+            .trait_name = TALER_S (name),                      \
+            .ptr = (const void *) value                        \
+          };                                                   \
+          return ret;                                          \
+        }
 
 
 /**
  * Call #op on all simple traits.
  */
 #define TALER_TESTING_SIMPLE_TRAITS(op) \
-  op (bank_row, const uint64_t)                                    \
-  op (officer_pub, const struct TALER_AmlOfficerPublicKeyP)        \
-  op (officer_priv, const struct TALER_AmlOfficerPrivateKeyP)      \
-  op (officer_name, const char)                                    \
-  op (aml_decision, enum TALER_AmlDecisionState)                   \
-  op (aml_justification, const char)                               \
-  op (auditor_priv, const struct TALER_AuditorPrivateKeyP)         \
-  op (auditor_pub, const struct TALER_AuditorPublicKeyP)           \
-  op (master_priv, const struct TALER_MasterPrivateKeyP)           \
-  op (master_pub, const struct TALER_MasterPublicKeyP)             \
-  op (purse_priv, const struct TALER_PurseContractPrivateKeyP)     \
-  op (purse_pub, const struct TALER_PurseContractPublicKeyP)       \
-  op (merge_priv, const struct TALER_PurseMergePrivateKeyP)        \
-  op (merge_pub, const struct TALER_PurseMergePublicKeyP)          \
-  op (contract_priv, const struct TALER_ContractDiffiePrivateP)    \
-  op (reserve_priv, const struct TALER_ReservePrivateKeyP)         \
-  op (reserve_sig, const struct TALER_ReserveSignatureP)           \
-  op (h_payto, const struct TALER_PaytoHashP)                      \
-  op (planchet_secret, const struct TALER_PlanchetMasterSecretP)   \
-  op (refresh_secret, const struct TALER_RefreshMasterSecretP)     \
-  op (reserve_pub, const struct TALER_ReservePublicKeyP)           \
-  op (merchant_priv, const struct TALER_MerchantPrivateKeyP)       \
-  op (merchant_pub, const struct TALER_MerchantPublicKeyP)         \
-  op (merchant_sig, const struct TALER_MerchantSignatureP)         \
-  op (wtid, const struct TALER_WireTransferIdentifierRawP)         \
-  op (bank_auth_data, const struct TALER_BANK_AuthenticationData)  \
-  op (contract_terms, const json_t)                                \
-  op (wire_details, const json_t)                                  \
-  op (exchange_url, const char)                                    \
-  op (auditor_url, const char)                                     \
-  op (exchange_bank_account_url, const char)                       \
-  op (taler_uri, const char)                                       \
-  op (payto_uri, const char)                                       \
-  op (kyc_url, const char)                                         \
-  op (web_url, const char)                                         \
-  op (row, const uint64_t)                                         \
-  op (legi_requirement_row, const uint64_t)                        \
-  op (array_length, const unsigned int)                            \
-  op (credit_payto_uri, const char)                                \
-  op (debit_payto_uri, const char)                                 \
-  op (order_id, const char)                                        \
-  op (amount, const struct TALER_Amount)                           \
-  op (amount_with_fee, const struct TALER_Amount)                  \
-  op (batch_cmds, struct TALER_TESTING_Command)                    \
-  op (uuid, const struct GNUNET_Uuid)                              \
-  op (fresh_coins, const struct TALER_TESTING_FreshCoinData *)     \
-  op (claim_token, const struct TALER_ClaimTokenP)                 \
-  op (relative_time, const struct GNUNET_TIME_Relative)            \
-  op (fakebank, struct TALER_FAKEBANK_Handle)                      \
-  op (keys, struct TALER_EXCHANGE_Keys)                            \
-  op (process, struct GNUNET_OS_Process *)
+        op (bank_row, const uint64_t)                                    \
+        op (officer_pub, const struct TALER_AmlOfficerPublicKeyP)        \
+        op (officer_priv, const struct TALER_AmlOfficerPrivateKeyP)      \
+        op (officer_name, const char)                                    \
+        op (aml_decision, enum TALER_AmlDecisionState)                   \
+        op (aml_justification, const char)                               \
+        op (auditor_priv, const struct TALER_AuditorPrivateKeyP)         \
+        op (auditor_pub, const struct TALER_AuditorPublicKeyP)           \
+        op (master_priv, const struct TALER_MasterPrivateKeyP)           \
+        op (master_pub, const struct TALER_MasterPublicKeyP)             \
+        op (purse_priv, const struct TALER_PurseContractPrivateKeyP)     \
+        op (purse_pub, const struct TALER_PurseContractPublicKeyP)       \
+        op (merge_priv, const struct TALER_PurseMergePrivateKeyP)        \
+        op (merge_pub, const struct TALER_PurseMergePublicKeyP)          \
+        op (contract_priv, const struct TALER_ContractDiffiePrivateP)    \
+        op (reserve_priv, const struct TALER_ReservePrivateKeyP)         \
+        op (reserve_sig, const struct TALER_ReserveSignatureP)           \
+        op (h_payto, const struct TALER_PaytoHashP)                      \
+        op (planchet_secret, const struct TALER_PlanchetMasterSecretP)   \
+        op (refresh_secret, const struct TALER_RefreshMasterSecretP)     \
+        op (reserve_pub, const struct TALER_ReservePublicKeyP)           \
+        op (merchant_priv, const struct TALER_MerchantPrivateKeyP)       \
+        op (merchant_pub, const struct TALER_MerchantPublicKeyP)         \
+        op (merchant_sig, const struct TALER_MerchantSignatureP)         \
+        op (wtid, const struct TALER_WireTransferIdentifierRawP)         \
+        op (bank_auth_data, const struct TALER_BANK_AuthenticationData)  \
+        op (contract_terms, const json_t)                                \
+        op (wire_details, const json_t)                                  \
+        op (exchange_url, const char)                                    \
+        op (auditor_url, const char)                                     \
+        op (exchange_bank_account_url, const char)                       \
+        op (taler_uri, const char)                                       \
+        op (payto_uri, const char)                                       \
+        op (kyc_url, const char)                                         \
+        op (web_url, const char)                                         \
+        op (row, const uint64_t)                                         \
+        op (legi_requirement_row, const uint64_t)                        \
+        op (array_length, const unsigned int)                            \
+        op (credit_payto_uri, const char)                                \
+        op (debit_payto_uri, const char)                                 \
+        op (order_id, const char)                                        \
+        op (amount, const struct TALER_Amount)                           \
+        op (amount_with_fee, const struct TALER_Amount)                  \
+        op (batch_cmds, struct TALER_TESTING_Command)                    \
+        op (uuid, const struct GNUNET_Uuid)                              \
+        op (fresh_coins, const struct TALER_TESTING_FreshCoinData *)     \
+        op (claim_token, const struct TALER_ClaimTokenP)                 \
+        op (relative_time, const struct GNUNET_TIME_Relative)            \
+        op (fakebank, struct TALER_FAKEBANK_Handle)                      \
+        op (keys, struct TALER_EXCHANGE_Keys)                            \
+        op (process, struct GNUNET_OS_Process *)
 
 
 /**
  * Call #op on all indexed traits.
  */
 #define TALER_TESTING_INDEXED_TRAITS(op)                                \
-  op (denom_pub, const struct TALER_EXCHANGE_DenomPublicKey)            \
-  op (denom_sig, const struct TALER_DenominationSignature)              \
-  op (amounts, const struct TALER_Amount)                               \
-  op (deposit_amount, const struct TALER_Amount)                        \
-  op (deposit_fee_amount, const struct TALER_Amount)                    \
-  op (age_commitment, const struct TALER_AgeCommitment)                 \
-  op (age_commitment_proof, const struct TALER_AgeCommitmentProof)      \
-  op (h_age_commitment, const struct TALER_AgeCommitmentHash)           \
-  op (reserve_history, const struct TALER_EXCHANGE_ReserveHistoryEntry) \
-  op (coin_history, const struct TALER_EXCHANGE_CoinHistoryEntry) \
-  op (planchet_secrets, const struct TALER_PlanchetMasterSecretP)       \
-  op (exchange_wd_value, const struct TALER_ExchangeWithdrawValues)     \
-  op (coin_priv, const struct TALER_CoinSpendPrivateKeyP)               \
-  op (coin_pub, const struct TALER_CoinSpendPublicKeyP)                 \
-  op (coin_sig, const struct TALER_CoinSpendSignatureP)                 \
-  op (absolute_time, const struct GNUNET_TIME_Absolute)                 \
-  op (timestamp, const struct GNUNET_TIME_Timestamp)                    \
-  op (wire_deadline, const struct GNUNET_TIME_Timestamp)                \
-  op (refund_deadline, const struct GNUNET_TIME_Timestamp)              \
-  op (exchange_pub, const struct TALER_ExchangePublicKeyP)              \
-  op (exchange_sig, const struct TALER_ExchangeSignatureP)              \
-  op (blinding_key, const union GNUNET_CRYPTO_BlindingSecretP)         \
-  op (h_blinded_coin, const struct TALER_BlindedCoinHashP)
+        op (denom_pub, const struct TALER_EXCHANGE_DenomPublicKey)            \
+        op (denom_sig, const struct TALER_DenominationSignature)              \
+        op (amounts, const struct TALER_Amount)                               \
+        op (deposit_amount, const struct TALER_Amount)                        \
+        op (deposit_fee_amount, const struct TALER_Amount)                    \
+        op (age_commitment, const struct TALER_AgeCommitment)                 \
+        op (age_commitment_proof, const struct TALER_AgeCommitmentProof)      \
+        op (h_age_commitment, const struct TALER_AgeCommitmentHash)           \
+        op (reserve_history, const struct TALER_EXCHANGE_ReserveHistoryEntry) \
+        op (coin_history, const struct TALER_EXCHANGE_CoinHistoryEntry) \
+        op (planchet_secrets, const struct TALER_PlanchetMasterSecretP)       \
+        op (exchange_wd_value, const struct TALER_ExchangeWithdrawValues)     \
+        op (coin_priv, const struct TALER_CoinSpendPrivateKeyP)               \
+        op (coin_pub, const struct TALER_CoinSpendPublicKeyP)                 \
+        op (coin_sig, const struct TALER_CoinSpendSignatureP)                 \
+        op (absolute_time, const struct GNUNET_TIME_Absolute)                 \
+        op (timestamp, const struct GNUNET_TIME_Timestamp)                    \
+        op (wire_deadline, const struct GNUNET_TIME_Timestamp)                \
+        op (refund_deadline, const struct GNUNET_TIME_Timestamp)              \
+        op (exchange_pub, const struct TALER_ExchangePublicKeyP)              \
+        op (exchange_sig, const struct TALER_ExchangeSignatureP)              \
+        op (blinding_key, const union GNUNET_CRYPTO_BlindingSecretP)         \
+        op (h_blinded_coin, const struct TALER_BlindedCoinHashP)
 
 TALER_TESTING_SIMPLE_TRAITS (TALER_TESTING_MAKE_DECL_SIMPLE_TRAIT)
 
diff --git a/src/testing/.gitignore b/src/testing/.gitignore
index 6cac81c8..e1075ab1 100644
--- a/src/testing/.gitignore
+++ b/src/testing/.gitignore
@@ -10,6 +10,8 @@ test_exchange_api_revocation_cs
 test_exchange_api_revocation_rsa
 test_exchange_api_age_restriction_cs
 test_exchange_api_age_restriction_rsa
+test_exchange_api_conflicts_cs
+test_exchange_api_conflicts_rsa
 report*
 test_exchange_management_api_cs
 test_exchange_management_api_rsa
diff --git a/src/testing/Makefile.am b/src/testing/Makefile.am
index 6a07c933..03118d77 100644
--- a/src/testing/Makefile.am
+++ b/src/testing/Makefile.am
@@ -155,6 +155,7 @@ check_PROGRAMS = \
   test_exchange_api_rsa \
   test_exchange_api_age_restriction_cs \
   test_exchange_api_age_restriction_rsa \
+  test_exchange_api_conflicts_rsa \
   test_exchange_api_keys_cherry_picking_cs \
   test_exchange_api_keys_cherry_picking_rsa \
   test_exchange_api_revocation_cs \
@@ -307,6 +308,38 @@ test_exchange_api_age_restriction_rsa_LDADD = \
   -ljansson \
   $(XLIB)
 
+test_exchange_api_conflicts_cs_SOURCES = \
+  test_exchange_api_conflicts.c
+test_exchange_api_conflicts_cs_LDADD = \
+  libtalertesting.la \
+  $(top_builddir)/src/lib/libtalerexchange.la \
+  $(LIBGCRYPT_LIBS) \
+  $(top_builddir)/src/bank-lib/libtalerfakebank.la \
+  $(top_builddir)/src/bank-lib/libtalerbank.la \
+  $(top_builddir)/src/json/libtalerjson.la \
+  $(top_builddir)/src/util/libtalerutil.la \
+  $(top_builddir)/src/extensions/libtalerextensions.la \
+  -lgnunetcurl \
+  -lgnunetutil \
+  -ljansson \
+  $(XLIB)
+
+test_exchange_api_conflicts_rsa_SOURCES = \
+  test_exchange_api_conflicts.c
+test_exchange_api_conflicts_rsa_LDADD = \
+  libtalertesting.la \
+  $(top_builddir)/src/lib/libtalerexchange.la \
+  $(LIBGCRYPT_LIBS) \
+  $(top_builddir)/src/bank-lib/libtalerfakebank.la \
+  $(top_builddir)/src/bank-lib/libtalerbank.la \
+  $(top_builddir)/src/json/libtalerjson.la \
+  $(top_builddir)/src/util/libtalerutil.la \
+  $(top_builddir)/src/extensions/libtalerextensions.la \
+  -lgnunetcurl \
+  -lgnunetutil \
+  -ljansson \
+  $(XLIB)
+
 test_exchange_p2p_cs_SOURCES = \
   test_exchange_p2p.c
 test_exchange_p2p_cs_LDADD = \
diff --git a/src/testing/test_auditor_api-cs.conf 
b/src/testing/test_exchange_api_conflicts-cs.conf
similarity index 59%
copy from src/testing/test_auditor_api-cs.conf
copy to src/testing/test_exchange_api_conflicts-cs.conf
index b80696fb..c15d5549 100644
--- a/src/testing/test_auditor_api-cs.conf
+++ b/src/testing/test_exchange_api_conflicts-cs.conf
@@ -1,4 +1,4 @@
 # This file is in the public domain.
 #
+@INLINE@ test_exchange_api_conflicts.conf
 @INLINE@ coins-cs.conf
-@INLINE@ test_exchange_api.conf
diff --git a/src/testing/test_exchange_api-rsa.conf 
b/src/testing/test_exchange_api_conflicts-rsa.conf
similarity index 60%
copy from src/testing/test_exchange_api-rsa.conf
copy to src/testing/test_exchange_api_conflicts-rsa.conf
index 351c876d..f56111ee 100644
--- a/src/testing/test_exchange_api-rsa.conf
+++ b/src/testing/test_exchange_api_conflicts-rsa.conf
@@ -1,4 +1,4 @@
 # This file is in the public domain.
 #
+@INLINE@ test_exchange_api_conflicts.conf
 @INLINE@ coins-rsa.conf
-@INLINE@ test_exchange_api.conf
\ No newline at end of file
diff --git a/src/testing/test_exchange_api_conflicts.c 
b/src/testing/test_exchange_api_conflicts.c
new file mode 100644
index 00000000..89851446
--- /dev/null
+++ b/src/testing/test_exchange_api_conflicts.c
@@ -0,0 +1,220 @@
+/*
+  This file is part of TALER
+  Copyright (C) 2023 Taler Systems SA
+
+  TALER is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as
+  published by the Free Software Foundation; either version 3, or
+  (at your option) any later version.
+
+  TALER is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public
+  License along with TALER; see the file COPYING.  If not, see
+  <http://www.gnu.org/licenses/>
+*/
+/**
+ * @file testing/test_exchange_api_conflicts.c
+ * @brief testcase to test exchange's handling of coin conflicts: same private
+ *        keys but different denominations or age restrictions
+ * @author Özgür Kesim
+ */
+#include "platform.h"
+#include "taler_util.h"
+#include "taler_signatures.h"
+#include "taler_exchange_service.h"
+#include "taler_json_lib.h"
+#include <gnunet/gnunet_util_lib.h>
+#include <gnunet/gnunet_testing_lib.h>
+#include <microhttpd.h>
+#include "taler_bank_service.h"
+#include "taler_fakebank_lib.h"
+#include "taler_testing_lib.h"
+#include "taler_extensions.h"
+
+/**
+ * Configuration file we use.  One (big) configuration is used
+ * for the various components for this test.
+ */
+static char *config_file;
+
+/**
+ * Our credentials.
+ */
+static struct TALER_TESTING_Credentials cred;
+
+/**
+ * Some tests behave differently when using CS as we cannot
+ * reuse the coin private key for different denominations
+ * due to the derivation of it with the /csr values. Hence
+ * some tests behave differently in CS mode, hence this
+ * flag.
+ */
+static bool uses_cs;
+
+/**
+ * Execute the taler-exchange-wirewatch command with
+ * our configuration file.
+ *
+ * @param label label to use for the command.
+ */
+#define CMD_EXEC_WIREWATCH(label) \
+        TALER_TESTING_cmd_exec_wirewatch2 (label, config_file, \
+                                           "exchange-account-2")
+
+/**
+ * Execute the taler-exchange-aggregator, closer and transfer commands with
+ * our configuration file.
+ *
+ * @param label label to use for the command.
+ */
+#define CMD_EXEC_AGGREGATOR(label) \
+        TALER_TESTING_cmd_sleep ("sleep-before-aggregator", 2), \
+        TALER_TESTING_cmd_exec_aggregator (label "-aggregator", config_file), \
+        TALER_TESTING_cmd_exec_transfer (label "-transfer", config_file)
+
+
+/**
+ * Run wire transfer of funds from some user's account to the
+ * exchange.
+ *
+ * @param label label to use for the command.
+ * @param amount amount to transfer, i.e. "EUR:1"
+ */
+#define CMD_TRANSFER_TO_EXCHANGE(label,amount) \
+        TALER_TESTING_cmd_admin_add_incoming (label, amount, \
+                                              &cred.ba,                \
+                                              cred.user42_payto)
+
+/**
+ * Main function that will tell the interpreter what commands to
+ * run.
+ *
+ * @param cls closure
+ * @param is interpreter we use to run commands
+ */
+static void
+run (void *cls,
+     struct TALER_TESTING_Interpreter *is)
+{
+  (void) cls;
+  /**
+   * Test withdrawal with conflicting coins.
+   */
+  struct TALER_TESTING_Command withdraw_conflict_denom[] = {
+    /**
+     * Move money to the exchange's bank account.
+     */
+    CMD_TRANSFER_TO_EXCHANGE ("create-reserve-denom",
+                              "EUR:21.03"),
+    TALER_TESTING_cmd_check_bank_admin_transfer ("check-create-reserve-denom",
+                                                 "EUR:21.03",
+                                                 cred.user42_payto,
+                                                 cred.exchange_payto,
+                                                 "create-reserve-denom"),
+    /**
+     * Make a reserve exist, according to the previous
+     * transfer.
+     */
+    CMD_EXEC_WIREWATCH ("wirewatch-conflict-denom"),
+    /**
+     * Withdraw EUR:1, EUR:5, EUR:15, but using the same private key each time.
+     */
+    TALER_TESTING_cmd_batch_withdraw_with_conflict ("withdraw-coin-denom-1",
+                                                    "create-reserve-denom",
+                                                    Conflict_Denom,
+                                                    0, /* age */
+                                                    MHD_HTTP_OK,
+                                                    "EUR:1",
+                                                    "EUR:5",
+                                                    "EUR:10",
+                                                    NULL),
+
+    TALER_TESTING_cmd_end ()
+  };
+
+  struct TALER_TESTING_Command spend_conflict_denom[] = {
+    /**
+     * Spend the coin.
+     */
+    TALER_TESTING_cmd_deposit ("deposit",
+                               "withdraw-coin-denom-1",
+                               0,
+                               cred.user42_payto,
+                               "{\"items\":[{\"name\":\"ice 
cream\",\"value\":1}]}",
+                               GNUNET_TIME_UNIT_ZERO,
+                               "EUR:0.99",
+                               MHD_HTTP_OK),
+    TALER_TESTING_cmd_deposit ("deposit-denom-conflict",
+                               "withdraw-coin-denom-1",
+                               1,
+                               cred.user42_payto,
+                               "{\"items\":[{\"name\":\"ice 
cream\",\"value\":1}]}",
+                               GNUNET_TIME_UNIT_ZERO,
+                               "EUR:4.99",
+                               /* FIXME: this fails for cs denominations! */
+                               MHD_HTTP_CONFLICT),
+    TALER_TESTING_cmd_end ()
+  };
+
+
+  {
+    struct TALER_TESTING_Command commands[] = {
+      TALER_TESTING_cmd_run_fakebank ("run-fakebank",
+                                      cred.cfg,
+                                      "exchange-account-2"),
+      TALER_TESTING_cmd_system_start ("start-taler",
+                                      config_file,
+                                      "-e",
+                                      NULL),
+      TALER_TESTING_cmd_get_exchange ("get-exchange",
+                                      cred.cfg,
+                                      NULL,
+                                      true,
+                                      true),
+      TALER_TESTING_cmd_batch ("withdraw-conflict-denom",
+                               withdraw_conflict_denom),
+      TALER_TESTING_cmd_batch ("spend-conflict-denom",
+                               spend_conflict_denom),
+      /* End the suite. */
+      TALER_TESTING_cmd_end ()
+    };
+
+    TALER_TESTING_run (is,
+                       commands);
+  }
+}
+
+
+int
+main (int argc,
+      char *const *argv)
+{
+  (void) argc;
+  {
+    char *cipher;
+
+    cipher = GNUNET_STRINGS_get_suffix_from_binary_name (argv[0]);
+    GNUNET_assert (NULL != cipher);
+    uses_cs = (0 == strcmp (cipher,
+                            "cs"));
+    GNUNET_asprintf (&config_file,
+                     "test_exchange_api_conflicts-%s.conf",
+                     cipher);
+    GNUNET_free (cipher);
+  }
+  return TALER_TESTING_main (argv,
+                             "INFO",
+                             config_file,
+                             "exchange-account-2",
+                             TALER_TESTING_BS_FAKEBANK,
+                             &cred,
+                             &run,
+                             NULL);
+}
+
+
+/* end of test_exchange_api_conflicts.c */
diff --git a/src/testing/test_exchange_api_age_restriction.conf 
b/src/testing/test_exchange_api_conflicts.conf
similarity index 65%
copy from src/testing/test_exchange_api_age_restriction.conf
copy to src/testing/test_exchange_api_conflicts.conf
index 1345fcb1..d04379f0 100644
--- a/src/testing/test_exchange_api_age_restriction.conf
+++ b/src/testing/test_exchange_api_conflicts.conf
@@ -23,8 +23,8 @@ HTTP_PORT = 8082
 [exchange]
 TERMS_ETAG = tos
 PRIVACY_ETAG = 0
-AML_THRESHOLD = EUR:10
 PORT = 8081
+AML_THRESHOLD = "EUR:99999999"
 MASTER_PUBLIC_KEY = 98NJW3CQHZQGQXTY3K85K531XKPAPAVV4Q5V8PYYRR00NJGZWNVG
 DB = postgres
 BASE_URL = "http://localhost:8081/";
@@ -76,44 +76,6 @@ PASSWORD = x
 WIRE_GATEWAY_URL = "http://localhost:8082/accounts/2/taler-wire-gateway/";
 
 
-[kyc-provider-test-oauth2]
-COST = 0
-LOGIC = oauth2
-USER_TYPE = INDIVIDUAL
-PROVIDED_CHECKS = DUMMY
-KYC_OAUTH2_VALIDITY = forever
-KYC_OAUTH2_TOKEN_URL = http://localhost:6666/oauth/v2/token
-KYC_OAUTH2_AUTHORIZE_URL = http://localhost:6666/oauth/v2/login
-KYC_OAUTH2_INFO_URL = http://localhost:6666/api/user/me
-KYC_OAUTH2_CLIENT_ID = taler-exchange
-KYC_OAUTH2_CLIENT_SECRET = exchange-secret
-KYC_OAUTH2_POST_URL = http://example.com/
-KYC_OAUTH2_CONVERTER_HELPER = taler-exchange-kyc-oauth2-test-converter.sh
-
-[kyc-legitimization-balance-high]
-OPERATION_TYPE = BALANCE
-REQUIRED_CHECKS = DUMMY
-THRESHOLD = EUR:20
-
-[kyc-legitimization-deposit-any]
-OPERATION_TYPE = DEPOSIT
-REQUIRED_CHECKS = DUMMY
-THRESHOLD = EUR:10
-TIMEFRAME = 1d
-
-[kyc-legitimization-withdraw]
-OPERATION_TYPE = WITHDRAW
-REQUIRED_CHECKS = DUMMY
-THRESHOLD = EUR:15
-TIMEFRAME = 1d
-
-[kyc-legitimization-merge]
-OPERATION_TYPE = MERGE
-REQUIRED_CHECKS = DUMMY
-THRESHOLD = EUR:15
-TIMEFRAME = 1d
-
-
 [exchange-extension-age_restriction]
 ENABLED = YES
 #AGE_GROUPS = "8:10:12:14:16:18:21"
diff --git a/src/testing/testing_api_cmd_batch_withdraw.c 
b/src/testing/testing_api_cmd_batch_withdraw.c
index 75311e7d..a93fadac 100644
--- a/src/testing/testing_api_cmd_batch_withdraw.c
+++ b/src/testing/testing_api_cmd_batch_withdraw.c
@@ -173,6 +173,11 @@ struct BatchWithdrawState
    * Same for all coins in the batch.
    */
   uint8_t age;
+
+  /**
+   * Force a conflict:
+   */
+  enum TALER_TESTING_CoinConflictType force_conflict;
 };
 
 
@@ -264,6 +269,9 @@ batch_withdraw_run (void *cls,
   const struct TALER_TESTING_Command *create_reserve;
   const struct TALER_EXCHANGE_DenomPublicKey *dpk;
   struct TALER_EXCHANGE_WithdrawCoinInput wcis[ws->num_coins];
+  struct TALER_PlanchetMasterSecretP conflict_ps = {0};
+  struct TALER_AgeMask mask = {0};
+  struct GNUNET_HashCode seed = {0};
 
   (void) cmd;
   ws->is = is;
@@ -296,12 +304,42 @@ batch_withdraw_run (void *cls,
     = TALER_reserve_make_payto (ws->exchange_url,
                                 &ws->reserve_pub);
 
+  if (0 < ws->age)
+    mask = TALER_extensions_get_age_restriction_mask ();
+
+  if (Conflict_Denom == ws->force_conflict)
+    TALER_planchet_master_setup_random (&conflict_ps);
+
+  if (Conflict_Age == ws->force_conflict)
+    GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
+                                &seed,
+                                sizeof(seed));
+
   for (unsigned int i = 0; i<ws->num_coins; i++)
   {
     struct CoinState *cs = &ws->coins[i];
     struct TALER_EXCHANGE_WithdrawCoinInput *wci = &wcis[i];
 
-    TALER_planchet_master_setup_random (&cs->ps);
+    if (Conflict_Denom == ws->force_conflict)
+      cs->ps = conflict_ps;
+    else
+      TALER_planchet_master_setup_random (&cs->ps);
+
+    if (0 < ws->age)
+    {
+      if (Conflict_Age != ws->force_conflict)
+        GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
+                                    &seed,
+                                    sizeof(seed));
+      TALER_age_restriction_commit (&mask,
+                                    ws->age,
+                                    &seed,
+                                    &cs->age_commitment_proof);
+      TALER_age_commitment_hash (&cs->age_commitment_proof.commitment,
+                                 &cs->h_age_commitment);
+    }
+
+
     dpk = TALER_TESTING_find_pk (keys,
                                  &cs->amount,
                                  ws->age > 0);
@@ -453,12 +491,14 @@ batch_withdraw_traits (void *cls,
 
 
 struct TALER_TESTING_Command
-TALER_TESTING_cmd_batch_withdraw (const char *label,
-                                  const char *reserve_reference,
-                                  uint8_t age,
-                                  unsigned int expected_response_code,
-                                  const char *amount,
-                                  ...)
+TALER_TESTING_cmd_batch_withdraw_with_conflict (
+  const char *label,
+  const char *reserve_reference,
+  enum TALER_TESTING_CoinConflictType conflict,
+  uint8_t age,
+  unsigned int expected_response_code,
+  const char *amount,
+  ...)
 {
   struct BatchWithdrawState *ws;
   unsigned int cnt;
@@ -468,6 +508,7 @@ TALER_TESTING_cmd_batch_withdraw (const char *label,
   ws->age = age;
   ws->reserve_reference = reserve_reference;
   ws->expected_response_code = expected_response_code;
+  ws->force_conflict = conflict;
 
   cnt = 1;
   va_start (ap,
@@ -485,23 +526,6 @@ TALER_TESTING_cmd_batch_withdraw (const char *label,
   {
     struct CoinState *cs = &ws->coins[i];
 
-    if (0 < age)
-    {
-      struct GNUNET_HashCode seed;
-      struct TALER_AgeMask mask;
-
-      mask = TALER_extensions_get_age_restriction_mask ();
-      GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
-                                  &seed,
-                                  sizeof(seed));
-      TALER_age_restriction_commit (&mask,
-                                    age,
-                                    &seed,
-                                    &cs->age_commitment_proof);
-      TALER_age_commitment_hash (&cs->age_commitment_proof.commitment,
-                                 &cs->h_age_commitment);
-    }
-
     if (GNUNET_OK !=
         TALER_string_to_amount (amount,
                                 &cs->amount))

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