exchange

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

fakebank_api_check.c (8390B)


      1 /*
      2   This file is part of TALER
      3   (C) 2016-2023 Taler Systems SA
      4 
      5   TALER is free software; you can redistribute it and/or
      6   modify it under the terms of the GNU General Public License
      7   as published by the Free Software Foundation; either version 3,
      8   or (at your option) any later version.
      9 
     10   TALER is distributed in the hope that it will be useful,
     11   but 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 bank-lib/fakebank_api_check.c
     21  * @brief library that fakes being a Taler bank for testcases
     22  * @author Christian Grothoff <christian@grothoff.org>
     23  */
     24 #include "taler/taler_fakebank_lib.h"
     25 #include "taler/taler_bank_service.h"
     26 #include "taler/taler_mhd_lib.h"
     27 #include <gnunet/gnunet_mhd_compat.h>
     28 #include "fakebank.h"
     29 #include "fakebank_common_lookup.h"
     30 
     31 
     32 /**
     33  * Generate log messages for failed check operation.
     34  *
     35  * @param h handle to output transaction log for
     36  */
     37 static void
     38 check_log (struct TALER_FAKEBANK_Handle *h)
     39 {
     40   for (uint64_t i = 0; i<h->ram_limit; i++)
     41   {
     42     struct Transaction *t = h->transactions[i];
     43 
     44     if (NULL == t)
     45       continue;
     46     if (! t->unchecked)
     47       continue;
     48     switch (t->type)
     49     {
     50     case T_DEBIT:
     51       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     52                   "%s -> %s (%s) %s (%s)\n",
     53                   t->debit_account->account_name,
     54                   t->credit_account->account_name,
     55                   TALER_amount2s (&t->amount),
     56                   t->subject.debit.exchange_base_url,
     57                   "DEBIT");
     58       break;
     59     case T_CREDIT:
     60       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     61                   "%s -> %s (%s) %s (%s)\n",
     62                   t->debit_account->account_name,
     63                   t->credit_account->account_name,
     64                   TALER_amount2s (&t->amount),
     65                   TALER_B2S (&t->subject.credit.reserve_pub),
     66                   "CREDIT");
     67       break;
     68     case T_AUTH:
     69       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     70                   "%s -> %s (%s) %s (%s)\n",
     71                   t->debit_account->account_name,
     72                   t->credit_account->account_name,
     73                   TALER_amount2s (&t->amount),
     74                   TALER_B2S (&t->subject.auth.account_pub),
     75                   "AUTH");
     76       break;
     77     case T_WAD:
     78       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     79                   "%s -> %s (%s) %s[%s] (%s)\n",
     80                   t->debit_account->account_name,
     81                   t->credit_account->account_name,
     82                   TALER_amount2s (&t->amount),
     83                   t->subject.wad.origin_base_url,
     84                   TALER_B2S (&t->subject.wad),
     85                   "WAD");
     86       break;
     87     }
     88   }
     89 }
     90 
     91 
     92 enum GNUNET_GenericReturnValue
     93 TALER_FAKEBANK_check_debit (struct TALER_FAKEBANK_Handle *h,
     94                             const struct TALER_Amount *want_amount,
     95                             const char *want_debit,
     96                             const char *want_credit,
     97                             const char *exchange_base_url,
     98                             struct TALER_WireTransferIdentifierRawP *wtid)
     99 {
    100   struct Account *debit_account;
    101   struct Account *credit_account;
    102 
    103   GNUNET_assert (0 ==
    104                  strcasecmp (want_amount->currency,
    105                              h->currency));
    106   debit_account = TALER_FAKEBANK_lookup_account_ (h,
    107                                                   want_debit,
    108                                                   NULL);
    109   credit_account = TALER_FAKEBANK_lookup_account_ (h,
    110                                                    want_credit,
    111                                                    NULL);
    112   if (NULL == debit_account)
    113   {
    114     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
    115                 "I wanted: %s->%s (%s) from exchange %s (DEBIT), but debit account does not even exist!\n",
    116                 want_debit,
    117                 want_credit,
    118                 TALER_amount2s (want_amount),
    119                 exchange_base_url);
    120     return GNUNET_SYSERR;
    121   }
    122   if (NULL == credit_account)
    123   {
    124     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
    125                 "I wanted: %s->%s (%s) from exchange %s (DEBIT), but credit account does not even exist!\n",
    126                 want_debit,
    127                 want_credit,
    128                 TALER_amount2s (want_amount),
    129                 exchange_base_url);
    130     return GNUNET_SYSERR;
    131   }
    132   for (struct Transaction *t = debit_account->out_tail;
    133        NULL != t;
    134        t = t->prev_out)
    135   {
    136     if ( (t->unchecked) &&
    137          (credit_account == t->credit_account) &&
    138          (T_DEBIT == t->type) &&
    139          (0 == TALER_amount_cmp (want_amount,
    140                                  &t->amount)) &&
    141          (0 == strcasecmp (exchange_base_url,
    142                            t->subject.debit.exchange_base_url)) )
    143     {
    144       *wtid = t->subject.debit.wtid;
    145       t->unchecked = false;
    146       return GNUNET_OK;
    147     }
    148   }
    149   GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
    150               "Did not find matching transaction! I have:\n");
    151   check_log (h);
    152   GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
    153               "I wanted: %s->%s (%s) from exchange %s (DEBIT)\n",
    154               want_debit,
    155               want_credit,
    156               TALER_amount2s (want_amount),
    157               exchange_base_url);
    158   return GNUNET_SYSERR;
    159 }
    160 
    161 
    162 enum GNUNET_GenericReturnValue
    163 TALER_FAKEBANK_check_credit (struct TALER_FAKEBANK_Handle *h,
    164                              const struct TALER_Amount *want_amount,
    165                              const char *want_debit,
    166                              const char *want_credit,
    167                              const struct TALER_ReservePublicKeyP *reserve_pub)
    168 {
    169   struct Account *debit_account;
    170   struct Account *credit_account;
    171 
    172   GNUNET_assert (0 == strcasecmp (want_amount->currency,
    173                                   h->currency));
    174   debit_account = TALER_FAKEBANK_lookup_account_ (h,
    175                                                   want_debit,
    176                                                   NULL);
    177   credit_account = TALER_FAKEBANK_lookup_account_ (h,
    178                                                    want_credit,
    179                                                    NULL);
    180   if (NULL == debit_account)
    181   {
    182     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
    183                 "I wanted:\n%s -> %s (%s) with subject %s (CREDIT) but debit account is unknown.\n",
    184                 want_debit,
    185                 want_credit,
    186                 TALER_amount2s (want_amount),
    187                 TALER_B2S (reserve_pub));
    188     return GNUNET_SYSERR;
    189   }
    190   if (NULL == credit_account)
    191   {
    192     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
    193                 "I wanted:\n%s -> %s (%s) with subject %s (CREDIT) but credit account is unknown.\n",
    194                 want_debit,
    195                 want_credit,
    196                 TALER_amount2s (want_amount),
    197                 TALER_B2S (reserve_pub));
    198     return GNUNET_SYSERR;
    199   }
    200   for (struct Transaction *t = credit_account->in_tail;
    201        NULL != t;
    202        t = t->prev_in)
    203   {
    204     if ( (t->unchecked) &&
    205          (debit_account == t->debit_account) &&
    206          (T_CREDIT == t->type) &&
    207          (0 == TALER_amount_cmp (want_amount,
    208                                  &t->amount)) &&
    209          (0 == GNUNET_memcmp (reserve_pub,
    210                               &t->subject.credit.reserve_pub)) )
    211     {
    212       t->unchecked = false;
    213       return GNUNET_OK;
    214     }
    215   }
    216   GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
    217               "Did not find matching transaction!\nI have:\n");
    218   check_log (h);
    219   GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
    220               "I wanted:\n%s -> %s (%s) with subject %s (CREDIT)\n",
    221               want_debit,
    222               want_credit,
    223               TALER_amount2s (want_amount),
    224               TALER_B2S (reserve_pub));
    225   return GNUNET_SYSERR;
    226 }
    227 
    228 
    229 enum GNUNET_GenericReturnValue
    230 TALER_FAKEBANK_check_empty (struct TALER_FAKEBANK_Handle *h)
    231 {
    232   for (uint64_t i = 0; i<h->ram_limit; i++)
    233   {
    234     struct Transaction *t = h->transactions[i];
    235 
    236     if ( (NULL != t) &&
    237          (t->unchecked) )
    238     {
    239       if (T_AUTH == t->type)
    240         continue; /* ignore */
    241       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
    242                   "Expected empty transaction set, but I have:\n");
    243       check_log (h);
    244       return GNUNET_SYSERR;
    245     }
    246   }
    247   return GNUNET_OK;
    248 }