LCOV - code coverage report
Current view: top level - testing - testing_api_cmd_insert_deposit.c (source / functions) Hit Total Coverage
Test: GNU Taler exchange coverage report Lines: 76 85 89.4 %
Date: 2021-08-30 06:43:37 Functions: 4 5 80.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :   This file is part of TALER
       3             :   Copyright (C) 2018 Taler Systems SA
       4             : 
       5             :   TALER is free software; you can redistribute it and/or modify it
       6             :   under the terms of the GNU General Public License as published
       7             :   by the Free Software Foundation; either version 3, or (at your
       8             :   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,
      17             :   see <http://www.gnu.org/licenses/>
      18             : */
      19             : /**
      20             :  * @file testing/testing_api_cmd_insert_deposit.c
      21             :  * @brief deposit a coin directly into the database.
      22             :  * @author Marcello Stanisci
      23             :  * @author Christian Grothoff
      24             :  */
      25             : #include "platform.h"
      26             : #include "taler_util.h"
      27             : #include "taler_json_lib.h"
      28             : #include <gnunet/gnunet_curl_lib.h>
      29             : #include "taler_signatures.h"
      30             : #include "taler_testing_lib.h"
      31             : #include "taler_exchangedb_plugin.h"
      32             : 
      33             : 
      34             : /**
      35             :  * State for a "insert-deposit" CMD.
      36             :  */
      37             : struct InsertDepositState
      38             : {
      39             :   /**
      40             :    * Configuration file used by the command.
      41             :    */
      42             :   const struct TALER_TESTING_DatabaseConnection *dbc;
      43             : 
      44             :   /**
      45             :    * Human-readable name of the shop.
      46             :    */
      47             :   const char *merchant_name;
      48             : 
      49             :   /**
      50             :    * Merchant account name (NOT a payto-URI).
      51             :    */
      52             :   const char *merchant_account;
      53             : 
      54             :   /**
      55             :    * Deadline before which the aggregator should
      56             :    * send the payment to the merchant.
      57             :    */
      58             :   struct GNUNET_TIME_Relative wire_deadline;
      59             : 
      60             :   /**
      61             :    * When did the exchange receive the deposit?
      62             :    */
      63             :   struct GNUNET_TIME_Absolute exchange_timestamp;
      64             : 
      65             :   /**
      66             :    * Amount to deposit, inclusive of deposit fee.
      67             :    */
      68             :   const char *amount_with_fee;
      69             : 
      70             :   /**
      71             :    * Deposit fee.
      72             :    */
      73             :   const char *deposit_fee;
      74             : };
      75             : 
      76             : /**
      77             :  * Setup (fake) information about a coin used in deposit.
      78             :  *
      79             :  * @param[out] issue information to initialize with "valid" data
      80             :  */
      81             : static void
      82          24 : fake_issue (struct TALER_EXCHANGEDB_DenominationKeyInformationP *issue)
      83             : {
      84             :   struct GNUNET_TIME_Absolute now;
      85             : 
      86          24 :   memset (issue,
      87             :           0,
      88             :           sizeof (struct TALER_EXCHANGEDB_DenominationKeyInformationP));
      89          24 :   now = GNUNET_TIME_absolute_get ();
      90          24 :   (void) GNUNET_TIME_round_abs (&now);
      91             :   issue->properties.start
      92          24 :     = GNUNET_TIME_absolute_hton (now);
      93             :   issue->properties.expire_withdraw
      94          24 :     = GNUNET_TIME_absolute_hton (
      95             :         GNUNET_TIME_absolute_add (now,
      96             :                                   GNUNET_TIME_UNIT_MINUTES));
      97             :   issue->properties.expire_deposit
      98          24 :     = GNUNET_TIME_absolute_hton (
      99             :         GNUNET_TIME_absolute_add (now,
     100             :                                   GNUNET_TIME_UNIT_HOURS));
     101             :   issue->properties.expire_legal
     102          24 :     = GNUNET_TIME_absolute_hton (
     103             :         GNUNET_TIME_absolute_add (now,
     104             :                                   GNUNET_TIME_UNIT_DAYS));
     105          24 :   GNUNET_assert (GNUNET_OK ==
     106             :                  TALER_string_to_amount_nbo ("EUR:1",
     107             :                                              &issue->properties.value));
     108          24 :   GNUNET_assert (GNUNET_OK ==
     109             :                  TALER_string_to_amount_nbo ("EUR:0.1",
     110             :                                              &issue->properties.fee_withdraw));
     111          24 :   GNUNET_assert (GNUNET_OK ==
     112             :                  TALER_string_to_amount_nbo ("EUR:0.1",
     113             :                                              &issue->properties.fee_deposit));
     114          24 :   GNUNET_assert (GNUNET_OK ==
     115             :                  TALER_string_to_amount_nbo ("EUR:0.1",
     116             :                                              &issue->properties.fee_refresh));
     117          24 :   GNUNET_assert (GNUNET_OK ==
     118             :                  TALER_string_to_amount_nbo ("EUR:0.1",
     119             :                                              &issue->properties.fee_refund));
     120          24 : }
     121             : 
     122             : 
     123             : /**
     124             :  * Run the command.
     125             :  *
     126             :  * @param cls closure.
     127             :  * @param cmd the commaind being run.
     128             :  * @param is interpreter state.
     129             :  */
     130             : static void
     131          24 : insert_deposit_run (void *cls,
     132             :                     const struct TALER_TESTING_Command *cmd,
     133             :                     struct TALER_TESTING_Interpreter *is)
     134             : {
     135          24 :   struct InsertDepositState *ids = cls;
     136             :   struct TALER_EXCHANGEDB_Deposit deposit;
     137             :   struct TALER_MerchantPrivateKeyP merchant_priv;
     138             :   struct TALER_EXCHANGEDB_DenominationKeyInformationP issue;
     139             :   struct TALER_DenominationPublicKey dpk;
     140             :   struct GNUNET_CRYPTO_RsaPrivateKey *denom_priv;
     141             :   struct GNUNET_HashCode hc;
     142             : 
     143             :   // prepare and store issue first.
     144          24 :   fake_issue (&issue);
     145          24 :   denom_priv = GNUNET_CRYPTO_rsa_private_key_create (1024);
     146          24 :   dpk.rsa_public_key = GNUNET_CRYPTO_rsa_private_key_get_public (denom_priv);
     147          24 :   GNUNET_CRYPTO_rsa_public_key_hash (dpk.rsa_public_key,
     148             :                                      &issue.properties.denom_hash);
     149             : 
     150          24 :   if ( (GNUNET_OK !=
     151          24 :         ids->dbc->plugin->start (ids->dbc->plugin->cls,
     152          24 :                                  "talertestinglib: denomination insertion")) ||
     153             :        (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
     154          24 :         ids->dbc->plugin->insert_denomination_info (ids->dbc->plugin->cls,
     155             :                                                     &dpk,
     156          24 :                                                     &issue)) ||
     157             :        (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=
     158          24 :         ids->dbc->plugin->commit (ids->dbc->plugin->cls)) )
     159             :   {
     160           0 :     TALER_TESTING_interpreter_fail (is);
     161           0 :     return;
     162             :   }
     163             : 
     164             :   /* prepare and store deposit now. */
     165          24 :   memset (&deposit,
     166             :           0,
     167             :           sizeof (deposit));
     168             : 
     169          24 :   GNUNET_CRYPTO_kdf (&merchant_priv,
     170             :                      sizeof (struct TALER_MerchantPrivateKeyP),
     171             :                      "merchant-priv",
     172             :                      strlen ("merchant-priv"),
     173          24 :                      ids->merchant_name,
     174             :                      strlen (ids->merchant_name),
     175             :                      NULL,
     176             :                      0);
     177          24 :   GNUNET_CRYPTO_eddsa_key_get_public (&merchant_priv.eddsa_priv,
     178             :                                       &deposit.merchant_pub.eddsa_pub);
     179          24 :   GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_WEAK,
     180             :                                     &deposit.h_contract_terms);
     181          24 :   if ( (GNUNET_OK !=
     182          24 :         TALER_string_to_amount (ids->amount_with_fee,
     183          24 :                                 &deposit.amount_with_fee)) ||
     184             :        (GNUNET_OK !=
     185          24 :         TALER_string_to_amount (ids->deposit_fee,
     186             :                                 &deposit.deposit_fee)) )
     187             :   {
     188           0 :     TALER_TESTING_interpreter_fail (is);
     189           0 :     return;
     190             :   }
     191             : 
     192          24 :   GNUNET_CRYPTO_rsa_public_key_hash (dpk.rsa_public_key,
     193             :                                      &deposit.coin.denom_pub_hash);
     194          24 :   GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
     195             :                               &deposit.coin.coin_pub,
     196             :                               sizeof (deposit.coin.coin_pub));
     197          24 :   GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_WEAK,
     198             :                                     &hc);
     199          24 :   deposit.coin.denom_sig.rsa_signature = GNUNET_CRYPTO_rsa_sign_fdh (denom_priv,
     200             :                                                                      &hc);
     201             :   {
     202             :     char *str;
     203             : 
     204          24 :     GNUNET_asprintf (&str,
     205             :                      "payto://x-taler-bank/localhost/%s",
     206             :                      ids->merchant_account);
     207             :     deposit.receiver_wire_account
     208          24 :       = GNUNET_JSON_PACK (
     209             :           GNUNET_JSON_pack_string ("salt",
     210             :                                    "this-is-a-salt-value"),
     211             :           GNUNET_JSON_pack_string ("payto_uri",
     212             :                                    str));
     213          24 :     GNUNET_free (str);
     214             :   }
     215             : 
     216          24 :   GNUNET_assert (GNUNET_OK ==
     217             :                  TALER_JSON_merchant_wire_signature_hash (
     218             :                    deposit.receiver_wire_account,
     219             :                    &deposit.h_wire));
     220          24 :   deposit.timestamp = GNUNET_TIME_absolute_get ();
     221          24 :   (void) GNUNET_TIME_round_abs (&deposit.timestamp);
     222          24 :   deposit.wire_deadline = GNUNET_TIME_relative_to_absolute (ids->wire_deadline);
     223          24 :   (void) GNUNET_TIME_round_abs (&deposit.wire_deadline);
     224             : 
     225             :   /* finally, actually perform the DB operation */
     226          24 :   if ( (GNUNET_OK !=
     227          24 :         ids->dbc->plugin->start (ids->dbc->plugin->cls,
     228          24 :                                  "libtalertesting: insert deposit")) ||
     229             :        (0 >
     230          24 :         ids->dbc->plugin->ensure_coin_known (ids->dbc->plugin->cls,
     231          24 :                                              &deposit.coin)) ||
     232             :        (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
     233          24 :         ids->dbc->plugin->insert_deposit (ids->dbc->plugin->cls,
     234             :                                           ids->exchange_timestamp,
     235          24 :                                           &deposit)) ||
     236             :        (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=
     237          24 :         ids->dbc->plugin->commit (ids->dbc->plugin->cls)) )
     238             :   {
     239           0 :     GNUNET_break (0);
     240           0 :     ids->dbc->plugin->rollback (ids->dbc->plugin->cls);
     241           0 :     TALER_TESTING_interpreter_fail (is);
     242             :   }
     243             : 
     244          24 :   GNUNET_CRYPTO_rsa_signature_free (deposit.coin.denom_sig.rsa_signature);
     245          24 :   GNUNET_CRYPTO_rsa_public_key_free (dpk.rsa_public_key);
     246          24 :   GNUNET_CRYPTO_rsa_private_key_free (denom_priv);
     247          24 :   json_decref (deposit.receiver_wire_account);
     248             : 
     249          24 :   TALER_TESTING_interpreter_next (is);
     250             : }
     251             : 
     252             : 
     253             : /**
     254             :  * Free the state of a "auditor-dbinit" CMD, and possibly kills its
     255             :  * process if it did not terminate correctly.
     256             :  *
     257             :  * @param cls closure.
     258             :  * @param cmd the command being freed.
     259             :  */
     260             : static void
     261          24 : insert_deposit_cleanup (void *cls,
     262             :                         const struct TALER_TESTING_Command *cmd)
     263             : {
     264          24 :   struct InsertDepositState *ids = cls;
     265             : 
     266          24 :   GNUNET_free (ids);
     267          24 : }
     268             : 
     269             : 
     270             : /**
     271             :  * Offer "insert-deposit" CMD internal data to other commands.
     272             :  *
     273             :  * @param cls closure.
     274             :  * @param[out] ret result
     275             :  * @param trait name of the trait.
     276             :  * @param index index number of the object to offer.
     277             :  * @return #GNUNET_OK on success.
     278             :  */
     279             : static int
     280           0 : insert_deposit_traits (void *cls,
     281             :                        const void **ret,
     282             :                        const char *trait,
     283             :                        unsigned int index)
     284             : {
     285             :   (void) cls;
     286             :   (void) ret;
     287             :   (void) trait;
     288             :   (void) index;
     289           0 :   return GNUNET_NO;
     290             : }
     291             : 
     292             : 
     293             : /**
     294             :  * Make the "insert-deposit" CMD.
     295             :  *
     296             :  * @param label command label.
     297             :  * @param dbc collects database plugin
     298             :  * @param merchant_name Human-readable name of the merchant.
     299             :  * @param merchant_account merchant's account name (NOT a payto:// URI)
     300             :  * @param exchange_timestamp when did the exchange receive the deposit
     301             :  * @param wire_deadline point in time where the aggregator should have
     302             :  *        wired money to the merchant.
     303             :  * @param amount_with_fee amount to deposit (inclusive of deposit fee)
     304             :  * @param deposit_fee deposit fee
     305             :  * @return the command.
     306             :  */
     307             : struct TALER_TESTING_Command
     308          24 : TALER_TESTING_cmd_insert_deposit (
     309             :   const char *label,
     310             :   const struct TALER_TESTING_DatabaseConnection *dbc,
     311             :   const char *merchant_name,
     312             :   const char *merchant_account,
     313             :   struct GNUNET_TIME_Absolute exchange_timestamp,
     314             :   struct GNUNET_TIME_Relative wire_deadline,
     315             :   const char *amount_with_fee,
     316             :   const char *deposit_fee)
     317             : {
     318             :   struct InsertDepositState *ids;
     319             : 
     320          24 :   GNUNET_TIME_round_abs (&exchange_timestamp);
     321          24 :   ids = GNUNET_new (struct InsertDepositState);
     322          24 :   ids->dbc = dbc;
     323          24 :   ids->merchant_name = merchant_name;
     324          24 :   ids->merchant_account = merchant_account;
     325          24 :   ids->exchange_timestamp = exchange_timestamp;
     326          24 :   ids->wire_deadline = wire_deadline;
     327          24 :   ids->amount_with_fee = amount_with_fee;
     328          24 :   ids->deposit_fee = deposit_fee;
     329             : 
     330             :   {
     331          24 :     struct TALER_TESTING_Command cmd = {
     332             :       .cls = ids,
     333             :       .label = label,
     334             :       .run = &insert_deposit_run,
     335             :       .cleanup = &insert_deposit_cleanup,
     336             :       .traits = &insert_deposit_traits
     337             :     };
     338             : 
     339          24 :     return cmd;
     340             :   }
     341             : }
     342             : 
     343             : 
     344             : /* end of testing_api_cmd_insert_deposit.c */

Generated by: LCOV version 1.14