exchange

Base system with REST service to issue digital coins, run by the payment service provider
Log | Files | Refs | Submodules | README | LICENSE

test_exchange_p2p.c (19518B)


      1 /*
      2   This file is part of TALER
      3   Copyright (C) 2014--2024 Taler Systems SA
      4 
      5   TALER is free software; you can redistribute it and/or modify
      6   it under the terms of the GNU General Public License as
      7   published by the Free Software Foundation; either version 3, or
      8   (at your option) any later version.
      9 
     10   TALER is distributed in the hope that it will be useful, but
     11   WITHOUT ANY WARRANTY; without even the implied warranty of
     12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13   GNU General Public License for more details.
     14 
     15   You should have received a copy of the GNU General Public
     16   License along with TALER; see the file COPYING.  If not, see
     17   <http://www.gnu.org/licenses/>
     18 */
     19 /**
     20  * @file testing/test_exchange_p2p.c
     21  * @brief testcase to test exchange's P2P payments
     22  * @author Christian Grothoff
     23  */
     24 #include "taler/taler_util.h"
     25 #include "taler/taler_json_lib.h"
     26 #include <gnunet/gnunet_util_lib.h>
     27 #include <gnunet/gnunet_testing_lib.h>
     28 #include <microhttpd.h>
     29 #include "taler/taler_bank_service.h"
     30 #include "taler/taler_testing_lib.h"
     31 
     32 /**
     33  * Configuration file we use.  One (big) configuration is used
     34  * for the various components for this test.
     35  */
     36 static char *config_file;
     37 
     38 /**
     39  * Our credentials.
     40  */
     41 struct TALER_TESTING_Credentials cred;
     42 
     43 /**
     44  * Some tests behave differently when using CS as we cannot
     45  * reuse the coin private key for different denominations
     46  * due to the derivation of it with the /csr values. Hence
     47  * some tests behave differently in CS mode, hence this
     48  * flag.
     49  */
     50 static bool uses_cs;
     51 
     52 /**
     53  * Execute the taler-exchange-wirewatch command with
     54  * our configuration file.
     55  *
     56  * @param label label to use for the command.
     57  */
     58 #define CMD_EXEC_WIREWATCH(label) \
     59         TALER_TESTING_cmd_exec_wirewatch2 (label, config_file, \
     60                                            "exchange-account-2")
     61 
     62 /**
     63  * Execute the taler-exchange-aggregator, closer and transfer commands with
     64  * our configuration file.
     65  *
     66  * @param label label to use for the command.
     67  */
     68 #define CMD_EXEC_AGGREGATOR(label) \
     69         TALER_TESTING_cmd_sleep ("sleep-before-aggregator", 2), \
     70         TALER_TESTING_cmd_exec_aggregator (label "-aggregator", config_file), \
     71         TALER_TESTING_cmd_exec_transfer (label "-transfer", config_file)
     72 
     73 
     74 /**
     75  * Run wire transfer of funds from some user's account to the
     76  * exchange.
     77  *
     78  * @param label label to use for the command.
     79  * @param amount amount to transfer, i.e. "EUR:1"
     80  */
     81 #define CMD_TRANSFER_TO_EXCHANGE(label,amount)                  \
     82         TALER_TESTING_cmd_admin_add_incoming (label, amount,    \
     83                                               &cred.ba,         \
     84                                               cred.user42_payto)
     85 
     86 /**
     87  * Main function that will tell the interpreter what commands to
     88  * run.
     89  *
     90  * @param cls closure
     91  * @param is interpreter we use to run commands
     92  */
     93 static void
     94 run (void *cls,
     95      struct TALER_TESTING_Interpreter *is)
     96 {
     97   /**
     98    * Test withdrawal plus spending.
     99    */
    100   struct TALER_TESTING_Command withdraw[] = {
    101     /**
    102      * Move money to the exchange's bank account.
    103      */
    104     CMD_TRANSFER_TO_EXCHANGE (
    105       "create-reserve-1",
    106       "EUR:5.04"),
    107     CMD_TRANSFER_TO_EXCHANGE (
    108       "create-reserve-2",
    109       "EUR:5.01"),
    110     TALER_TESTING_cmd_reserve_poll (
    111       "poll-reserve-1",
    112       "create-reserve-1",
    113       "EUR:5.04",
    114       GNUNET_TIME_UNIT_MINUTES,
    115       MHD_HTTP_OK),
    116     TALER_TESTING_cmd_check_bank_admin_transfer (
    117       "check-create-reserve-1",
    118       "EUR:5.04",
    119       cred.user42_payto,
    120       cred.exchange_payto,
    121       "create-reserve-1"),
    122     TALER_TESTING_cmd_check_bank_admin_transfer (
    123       "check-create-reserve-2",
    124       "EUR:5.01",
    125       cred.user42_payto,
    126       cred.exchange_payto,
    127       "create-reserve-2"),
    128     /**
    129      * Make a reserve exist, according to the previous
    130      * transfer.
    131      */
    132     CMD_EXEC_WIREWATCH ("wirewatch-1"),
    133     TALER_TESTING_cmd_reserve_poll_finish (
    134       "finish-poll-reserve-1",
    135       GNUNET_TIME_UNIT_SECONDS,
    136       "poll-reserve-1"),
    137     /**
    138      * Withdraw EUR:5.
    139      */
    140     TALER_TESTING_cmd_withdraw_amount (
    141       "withdraw-coin-1",
    142       "create-reserve-1",
    143       "EUR:5",
    144       0,    /* age restriction off */
    145       MHD_HTTP_OK),
    146     /**
    147      * Check the reserve is depleted.
    148      */
    149     TALER_TESTING_cmd_status (
    150       "status-1",
    151       "create-reserve-1",
    152       "EUR:0.03",
    153       MHD_HTTP_OK),
    154     TALER_TESTING_cmd_end ()
    155   };
    156   struct TALER_TESTING_Command push[] = {
    157     TALER_TESTING_cmd_purse_create_with_deposit (
    158       "purse-with-deposit-for-delete",
    159       MHD_HTTP_OK,
    160       "{\"amount\":\"EUR:1\",\"summary\":\"ice cream\"}",
    161       true, /* upload contract */
    162       GNUNET_TIME_UNIT_MINUTES, /* expiration */
    163       "withdraw-coin-1",
    164       "EUR:1.01",
    165       NULL),
    166     TALER_TESTING_cmd_purse_delete (
    167       "purse-with-deposit-delete",
    168       MHD_HTTP_NO_CONTENT,
    169       "purse-with-deposit-for-delete"),
    170     TALER_TESTING_cmd_purse_create_with_deposit (
    171       "purse-with-deposit",
    172       MHD_HTTP_OK,
    173       "{\"amount\":\"EUR:0.99\",\"summary\":\"ice cream\"}",
    174       true, /* upload contract */
    175       GNUNET_TIME_UNIT_MINUTES, /* expiration */
    176       "withdraw-coin-1",
    177       "EUR:1.00",
    178       NULL),
    179     TALER_TESTING_cmd_purse_poll (
    180       "push-poll-purse-before-merge",
    181       MHD_HTTP_OK,
    182       "purse-with-deposit",
    183       "EUR:0.99",
    184       true,
    185       GNUNET_TIME_UNIT_MINUTES),
    186     TALER_TESTING_cmd_contract_get (
    187       "push-get-contract",
    188       MHD_HTTP_OK,
    189       true, /* for merge */
    190       "purse-with-deposit"),
    191     TALER_TESTING_cmd_purse_merge (
    192       "purse-merge-into-reserve",
    193       MHD_HTTP_OK,
    194       "push-get-contract",
    195       "create-reserve-1"),
    196     TALER_TESTING_cmd_purse_poll_finish (
    197       "push-merge-purse-poll-finish",
    198       GNUNET_TIME_relative_multiply (
    199         GNUNET_TIME_UNIT_SECONDS,
    200         5),
    201       "push-poll-purse-before-merge"),
    202     TALER_TESTING_cmd_status (
    203       "push-check-post-merge-reserve-balance-get",
    204       "create-reserve-1",
    205       "EUR:1.02",
    206       MHD_HTTP_OK),
    207     /* POST history doesn't yet support P2P transfers */
    208     TALER_TESTING_cmd_reserve_history (
    209       "push-check-post-merge-reserve-balance-post",
    210       "create-reserve-1",
    211       "EUR:1.02",
    212       MHD_HTTP_OK),
    213     /* Test conflicting merge */
    214     TALER_TESTING_cmd_purse_merge (
    215       "purse-merge-into-reserve",
    216       MHD_HTTP_CONFLICT,
    217       "push-get-contract",
    218       "create-reserve-2"),
    219 
    220     /**
    221      * A purse expiring after PURSE_EXPIRATION_LIMIT is refused: it would
    222      * refund its coins at a point where the auditor can no longer account
    223      * for the refund.  The limit defaults to the shortest DURATION_LEGAL
    224      * of any denomination, which is 3 years in the test configuration.
    225      */
    226     TALER_TESTING_cmd_purse_create_with_deposit (
    227       "purse-with-deposit-expiring-after-limit",
    228       MHD_HTTP_BAD_REQUEST,
    229       "{\"amount\":\"EUR:1\",\"summary\":\"ice cream\"}",
    230       true, /* upload contract */
    231       GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_YEARS,
    232                                      4), /* expiration */
    233       "withdraw-coin-1",
    234       "EUR:1.01",
    235       NULL),
    236     TALER_TESTING_cmd_end ()
    237   };
    238   struct TALER_TESTING_Command pull[] = {
    239     /**
    240      * The same limit applies to a purse created together with its merge:
    241      * such a purse also refunds the coins deposited into it if it is not
    242      * paid in full by the time it expires.
    243      */
    244     TALER_TESTING_cmd_purse_create_with_reserve (
    245       "purse-create-with-reserve-expiring-after-limit",
    246       MHD_HTTP_BAD_REQUEST,
    247       "{\"amount\":\"EUR:1\",\"summary\":\"ice cream\"}",
    248       true /* upload contract */,
    249       true /* pay purse fee */,
    250       GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_YEARS,
    251                                      4), /* expiration */
    252       "create-reserve-1"),
    253     TALER_TESTING_cmd_purse_create_with_reserve (
    254       "purse-create-with-reserve",
    255       MHD_HTTP_OK,
    256       "{\"amount\":\"EUR:1\",\"summary\":\"ice cream\"}",
    257       true /* upload contract */,
    258       true /* pay purse fee */,
    259       GNUNET_TIME_UNIT_MINUTES, /* expiration */
    260       "create-reserve-1"),
    261     TALER_TESTING_cmd_contract_get (
    262       "pull-get-contract",
    263       MHD_HTTP_OK,
    264       false, /* for deposit */
    265       "purse-create-with-reserve"),
    266     TALER_TESTING_cmd_purse_poll (
    267       "pull-poll-purse-before-deposit",
    268       MHD_HTTP_OK,
    269       "purse-create-with-reserve",
    270       "EUR:1",
    271       false,
    272       GNUNET_TIME_UNIT_MINUTES),
    273     TALER_TESTING_cmd_purse_deposit_coins (
    274       "purse-deposit-coins",
    275       MHD_HTTP_OK,
    276       0 /* min age */,
    277       "purse-create-with-reserve",
    278       "withdraw-coin-1",
    279       "EUR:1.01",
    280       NULL),
    281     TALER_TESTING_cmd_purse_poll_finish (
    282       "pull-deposit-purse-poll-finish",
    283       GNUNET_TIME_relative_multiply (
    284         GNUNET_TIME_UNIT_SECONDS,
    285         5),
    286       "pull-poll-purse-before-deposit"),
    287     TALER_TESTING_cmd_status (
    288       "pull-check-post-merge-reserve-balance-get",
    289       "create-reserve-1",
    290       "EUR:2.02",
    291       MHD_HTTP_OK),
    292     TALER_TESTING_cmd_reserve_history (
    293       "push-check-post-merge-reserve-balance-post",
    294       "create-reserve-1",
    295       "EUR:2.02",
    296       MHD_HTTP_OK),
    297     TALER_TESTING_cmd_purse_deposit_coins (
    298       "purse-deposit-coins-idempotent",
    299       MHD_HTTP_OK,
    300       0 /* min age */,
    301       "purse-create-with-reserve",
    302       "withdraw-coin-1",
    303       "EUR:1.01",
    304       NULL),
    305     /* create 2nd purse for a deposit conflict */
    306     TALER_TESTING_cmd_purse_create_with_reserve (
    307       "purse-create-with-reserve-2",
    308       MHD_HTTP_OK,
    309       "{\"amount\":\"EUR:4\",\"summary\":\"beer\"}",
    310       true /* upload contract */,
    311       true /* pay purse fee */,
    312       GNUNET_TIME_UNIT_MINUTES, /* expiration */
    313       "create-reserve-1"),
    314     TALER_TESTING_cmd_purse_deposit_coins (
    315       "purse-deposit-coins-conflict",
    316       MHD_HTTP_CONFLICT,
    317       0 /* min age */,
    318       "purse-create-with-reserve-2",
    319       "withdraw-coin-1",
    320       "EUR:4.01",
    321       NULL),
    322     TALER_TESTING_cmd_end ()
    323   };
    324 
    325   struct TALER_TESTING_Command expire[] = {
    326     TALER_TESTING_cmd_purse_create_with_reserve (
    327       "purse-create-with-reserve-expire",
    328       MHD_HTTP_OK,
    329       "{\"amount\":\"EUR:2\",\"summary\":\"ice cream\"}",
    330       true /* upload contract */,
    331       true /* pay purse fee */,
    332       GNUNET_TIME_relative_multiply (
    333         GNUNET_TIME_UNIT_SECONDS,
    334         1), /* expiration */
    335       "create-reserve-1"),
    336     TALER_TESTING_cmd_purse_poll (
    337       "pull-poll-purse-before-expire",
    338       MHD_HTTP_GONE,
    339       "purse-create-with-reserve-expire",
    340       "EUR:1",
    341       false,
    342       GNUNET_TIME_UNIT_MINUTES),
    343     TALER_TESTING_cmd_purse_create_with_deposit (
    344       "purse-with-deposit-expire",
    345       MHD_HTTP_OK,
    346       "{\"amount\":\"EUR:1\",\"summary\":\"ice cream\"}",
    347       true, /* upload contract */
    348       GNUNET_TIME_relative_multiply (
    349         GNUNET_TIME_UNIT_SECONDS,
    350         1), /* expiration */
    351       "withdraw-coin-1",
    352       "EUR:1.02",
    353       NULL),
    354     TALER_TESTING_cmd_purse_poll (
    355       "push-poll-purse-before-expire",
    356       MHD_HTTP_GONE,
    357       "purse-with-deposit-expire",
    358       "EUR:1",
    359       true, /* wait for merge */
    360       GNUNET_TIME_UNIT_MINUTES),
    361     /* This should fail, as too much of the coin
    362        is already spend / in a purse */
    363     TALER_TESTING_cmd_purse_create_with_deposit (
    364       "purse-with-deposit-overspending",
    365       MHD_HTTP_CONFLICT,
    366       "{\"amount\":\"EUR:2\",\"summary\":\"ice cream\"}",
    367       true, /* upload contract */
    368       GNUNET_TIME_relative_multiply (
    369         GNUNET_TIME_UNIT_SECONDS,
    370         1), /* expiration */
    371       "withdraw-coin-1",
    372       "EUR:2.01",
    373       NULL),
    374     TALER_TESTING_cmd_sleep (
    375       "sleep",
    376       2 /* seconds */),
    377     TALER_TESTING_cmd_exec_expire (
    378       "exec-expire",
    379       config_file),
    380     TALER_TESTING_cmd_purse_poll_finish (
    381       "push-merge-purse-poll-finish-expire",
    382       GNUNET_TIME_relative_multiply (
    383         GNUNET_TIME_UNIT_SECONDS,
    384         15),
    385       "push-poll-purse-before-expire"),
    386     TALER_TESTING_cmd_purse_poll_finish (
    387       "pull-deposit-purse-poll-expire-finish",
    388       GNUNET_TIME_relative_multiply (
    389         GNUNET_TIME_UNIT_SECONDS,
    390         15),
    391       "pull-poll-purse-before-expire"),
    392     /* coin was refunded, so now this should be OK */
    393     /* This should fail, as too much of the coin
    394        is already spend / in a purse */
    395     TALER_TESTING_cmd_purse_create_with_deposit (
    396       "purse-with-deposit-refunded",
    397       MHD_HTTP_OK,
    398       "{\"amount\":\"EUR:2\",\"summary\":\"ice cream\"}",
    399       true, /* upload contract */
    400       GNUNET_TIME_relative_multiply (
    401         GNUNET_TIME_UNIT_SECONDS,
    402         1), /* expiration */
    403       "withdraw-coin-1",
    404       "EUR:2.01",
    405       NULL),
    406     TALER_TESTING_cmd_end ()
    407   };
    408   struct TALER_TESTING_Command reserves[] = {
    409     CMD_TRANSFER_TO_EXCHANGE (
    410       "create-reserve-100",
    411       "EUR:1.04"),
    412     TALER_TESTING_cmd_check_bank_admin_transfer (
    413       "check-create-reserve-100",
    414       "EUR:1.04",
    415       cred.user42_payto,
    416       cred.exchange_payto,
    417       "create-reserve-100"),
    418     CMD_TRANSFER_TO_EXCHANGE (
    419       "create-reserve-101",
    420       "EUR:1.04"),
    421     TALER_TESTING_cmd_check_bank_admin_transfer (
    422       "check-create-reserve-101",
    423       "EUR:1.04",
    424       cred.user42_payto,
    425       cred.exchange_payto,
    426       "create-reserve-101"),
    427     CMD_EXEC_WIREWATCH ("wirewatch-100"),
    428     TALER_TESTING_cmd_withdraw_amount (
    429       "withdraw-coin-100",
    430       "create-reserve-100",
    431       "EUR:1",
    432       0,       /* age restriction off */
    433       MHD_HTTP_OK),
    434     TALER_TESTING_cmd_reserve_open (
    435       "reserve-open-101-fail",
    436       "create-reserve-101",
    437       "EUR:0",
    438       GNUNET_TIME_UNIT_YEARS,
    439       5,     /* min purses */
    440       MHD_HTTP_PAYMENT_REQUIRED,
    441       NULL,
    442       NULL),
    443     TALER_TESTING_cmd_reserve_open (
    444       "reserve-open-101-ok-a",
    445       "create-reserve-101",
    446       "EUR:0.01",
    447       GNUNET_TIME_UNIT_MONTHS,
    448       1,                               /* min purses */
    449       MHD_HTTP_OK,
    450       NULL,
    451       NULL),
    452     TALER_TESTING_cmd_status (
    453       "status-101-open-paid",
    454       "create-reserve-101",
    455       "EUR:1.03",
    456       MHD_HTTP_OK),
    457     TALER_TESTING_cmd_reserve_open (
    458       "reserve-open-101-ok-b",
    459       "create-reserve-101",
    460       "EUR:0",
    461       GNUNET_TIME_UNIT_MONTHS,
    462       2,            /* min purses */
    463       MHD_HTTP_OK,
    464       "withdraw-coin-100",
    465       "EUR:0.03",  /* 0.02 for the reserve open, 0.01 for deposit fee */
    466       NULL,
    467       NULL),
    468     /* Use purse creation with purse quota here */
    469     TALER_TESTING_cmd_purse_create_with_reserve (
    470       "purse-create-with-reserve-101-a",
    471       MHD_HTTP_OK,
    472       "{\"amount\":\"EUR:1\",\"summary\":\"ice cream\"}",
    473       true /* upload contract */,
    474       false /* pay purse fee */,
    475       GNUNET_TIME_UNIT_MINUTES, /* expiration */
    476       "create-reserve-101"),
    477     TALER_TESTING_cmd_purse_create_with_reserve (
    478       "purse-create-with-reserve-101-b",
    479       MHD_HTTP_OK,
    480       "{\"amount\":\"EUR:1\",\"summary\":\"ice cream\"}",
    481       true /* upload contract */,
    482       false /* pay purse fee */,
    483       GNUNET_TIME_UNIT_MINUTES, /* expiration */
    484       "create-reserve-101"),
    485     TALER_TESTING_cmd_purse_create_with_reserve (
    486       "purse-create-with-reserve-101-fail",
    487       MHD_HTTP_CONFLICT,
    488       "{\"amount\":\"EUR:1\",\"summary\":\"ice cream\"}",
    489       true /* upload contract */,
    490       false /* pay purse fee */,
    491       GNUNET_TIME_UNIT_MINUTES, /* expiration */
    492       "create-reserve-101"),
    493     TALER_TESTING_cmd_reserve_get_attestable (
    494       "reserve-101-attestable",
    495       "create-reserve-101",
    496       MHD_HTTP_NOT_FOUND,
    497       NULL),
    498     TALER_TESTING_cmd_reserve_get_attestable (
    499       "reserve-101-attest",
    500       "create-reserve-101",
    501       MHD_HTTP_NOT_FOUND,
    502       "nx-attribute-name",
    503       NULL),
    504     TALER_TESTING_cmd_oauth_with_birthdate (
    505       "start-oauth-service",
    506       "2015-00-00",
    507       6666),
    508     TALER_TESTING_cmd_reserve_close (
    509       "reserve-101-close-kyc",
    510       "create-reserve-101",
    511       /* 44 => not to origin */
    512       cred.user44_payto,
    513       MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS),
    514     TALER_TESTING_cmd_admin_add_kycauth (
    515       "setup-account-key",
    516       "EUR:0.01",
    517       &cred.ba,
    518       cred.user44_payto,
    519       NULL /* create new key */),
    520     CMD_EXEC_WIREWATCH (
    521       "import-kyc-account"),
    522     TALER_TESTING_cmd_check_kyc_get (
    523       "check-kyc-close-pending",
    524       "reserve-101-close-kyc",
    525       "setup-account-key",
    526       TALER_EXCHANGE_KLPT_KYC_AUTH_TRANSFER,
    527       MHD_HTTP_ACCEPTED),
    528     TALER_TESTING_cmd_get_kyc_info (
    529       "get-kyc-info",
    530       "check-kyc-close-pending",
    531       MHD_HTTP_OK),
    532     TALER_TESTING_cmd_post_kyc_start (
    533       "start-kyc-process",
    534       "get-kyc-info",
    535       0,
    536       MHD_HTTP_OK),
    537     TALER_TESTING_cmd_proof_kyc_oauth2 (
    538       "proof-close-kyc",
    539       "start-kyc-process",
    540       "test-oauth2",
    541       "pass",
    542       MHD_HTTP_SEE_OTHER),
    543     TALER_TESTING_cmd_check_kyc_get (
    544       "check-kyc-close-ok",
    545       "reserve-101-close-kyc",
    546       "setup-account-key",
    547       TALER_EXCHANGE_KLPT_KYC_OK,
    548       MHD_HTTP_OK),
    549     /* Now it should pass */
    550     TALER_TESTING_cmd_reserve_close (
    551       "reserve-101-close",
    552       "create-reserve-101",
    553       /* 44 => not to origin */
    554       cred.user44_payto,
    555       MHD_HTTP_OK),
    556     TALER_TESTING_cmd_exec_closer (
    557       "close-reserves-101",
    558       config_file,
    559       "EUR:1.02",
    560       "EUR:0.01",
    561       "create-reserve-101"),
    562     TALER_TESTING_cmd_exec_transfer (
    563       "close-reserves-101-transfer",
    564       config_file),
    565     TALER_TESTING_cmd_status (
    566       "reserve-101-closed-status",
    567       "create-reserve-101",
    568       "EUR:0",
    569       MHD_HTTP_OK),
    570     TALER_TESTING_cmd_end ()
    571   };
    572 
    573   struct TALER_TESTING_Command commands[] = {
    574     TALER_TESTING_cmd_run_fakebank ("run-fakebank",
    575                                     cred.cfg,
    576                                     "exchange-account-2"),
    577     TALER_TESTING_cmd_system_start ("start-taler",
    578                                     config_file,
    579                                     "-e",
    580                                     NULL),
    581     TALER_TESTING_cmd_get_exchange ("get-exchange",
    582                                     cred.cfg,
    583                                     NULL,
    584                                     true,
    585                                     true),
    586     TALER_TESTING_cmd_batch ("withdraw",
    587                              withdraw),
    588     TALER_TESTING_cmd_batch ("push",
    589                              push),
    590     TALER_TESTING_cmd_batch ("pull",
    591                              pull),
    592     TALER_TESTING_cmd_batch ("expire",
    593                              expire),
    594     TALER_TESTING_cmd_batch ("reserves",
    595                              reserves),
    596     /* End the suite. */
    597     TALER_TESTING_cmd_end ()
    598   };
    599 
    600   (void) cls;
    601   TALER_TESTING_run (is,
    602                      commands);
    603 }
    604 
    605 
    606 int
    607 main (int argc,
    608       char *const *argv)
    609 {
    610   (void) argc;
    611   {
    612     char *cipher;
    613 
    614     cipher = GNUNET_STRINGS_get_suffix_from_binary_name (argv[0]);
    615     GNUNET_assert (NULL != cipher);
    616     uses_cs = (0 == strcmp (cipher, "cs"));
    617     GNUNET_asprintf (&config_file,
    618                      "test_exchange_api-%s.conf",
    619                      cipher);
    620     GNUNET_free (cipher);
    621   }
    622   return TALER_TESTING_main (argv,
    623                              "INFO",
    624                              config_file,
    625                              "exchange-account-2",
    626                              TALER_TESTING_BS_FAKEBANK,
    627                              &cred,
    628                              &run,
    629                              NULL);
    630 }
    631 
    632 
    633 /* end of test_exchange_p2p.c */