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 (8418B)


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