exchange

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

test_auditordb.c (19945B)


      1 /*
      2   This file is part of TALER
      3   Copyright (C) 2016--2022 Taler Systems SA
      4 
      5   TALER is free software; you can redistribute it and/or modify it under the
      6   terms of the GNU General Public License as published by the Free Software
      7   Foundation; either version 3, or (at your option) any later version.
      8 
      9   TALER is distributed in the hope that it will be useful, but WITHOUT ANY
     10   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
     11   A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
     12 
     13   You should have received a copy of the GNU General Public License along with
     14   TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
     15 */
     16 /**
     17  * @file auditordb/test_auditordb.c
     18  * @brief test cases for DB interaction functions
     19  * @author Gabor X Toth
     20  * @author Christian Grothoff
     21  */
     22 #include <gnunet/gnunet_db_lib.h>
     23 #include "auditordb_lib.h"
     24 #include "auditor-database/create_tables.h"
     25 #include "auditor-database/del_reserve_info.h"
     26 #include "auditor-database/delete_auditor_closure_lag.h"
     27 #include "auditor-database/drop_tables.h"
     28 #include "auditor-database/gc.h"
     29 #include "auditor-database/get_denomination_balance.h"
     30 #include "auditor-database/get_reserve_info.h"
     31 #include "auditor-database/insert_auditor_closure_lags.h"
     32 #include "auditor-database/insert_denomination_balance.h"
     33 #include "auditor-database/insert_historic_denom_revenue.h"
     34 #include "auditor-database/insert_historic_reserve_revenue.h"
     35 #include "auditor-database/insert_reserve_info.h"
     36 #include "auditor-database/preflight.h"
     37 #include "auditor-database/select_historic_denom_revenue.h"
     38 #include "auditor-database/select_historic_reserve_revenue.h"
     39 #include "auditor-database/start.h"
     40 #include "auditor-database/update_denomination_balance.h"
     41 #include "auditor-database/update_reserve_info.h"
     42 
     43 /**
     44  * Currency we use, must match CURRENCY in "test-auditor-db-postgres.conf".
     45  */
     46 #define CURRENCY "EUR"
     47 
     48 /**
     49  * Report line of error if @a cond is true, and jump to label "drop".
     50  */
     51 #define FAILIF(cond)                              \
     52         do {                                          \
     53           if (! (cond)) { break;}                     \
     54           GNUNET_break (0);                         \
     55           goto drop;                                \
     56         } while (0)
     57 
     58 /**
     59  * Initializes @a ptr with random data.
     60  */
     61 #define RND_BLK(ptr)                                                    \
     62         GNUNET_CRYPTO_random_block (ptr, sizeof (* \
     63                                                  ptr))
     64 
     65 /**
     66  * Initializes @a ptr with zeros.
     67  */
     68 #define ZR_BLK(ptr) \
     69         memset (ptr, 0, sizeof (*ptr))
     70 
     71 
     72 /**
     73  * Global result from the testcase.
     74  */
     75 static int result = -1;
     76 
     77 /**
     78  * Hash of denomination public key.
     79  */
     80 static struct TALER_DenominationHashP denom_pub_hash;
     81 
     82 /**
     83  * Another hash of a denomination public key.
     84  */
     85 static struct TALER_DenominationHashP rnd_hash;
     86 
     87 /**
     88  * Current time.
     89  */
     90 static struct GNUNET_TIME_Timestamp now;
     91 
     92 /**
     93  * Timestamp in the past.
     94  */
     95 static struct GNUNET_TIME_Timestamp past;
     96 
     97 /**
     98  * Timestamp in the future.
     99  */
    100 static struct GNUNET_TIME_Timestamp future;
    101 
    102 /**
    103  * Database under test.
    104  */
    105 static struct TALER_AUDITORDB_PostgresContext *pg;
    106 
    107 /**
    108  * Historic denomination revenue value.
    109  */
    110 static struct TALER_Amount rbalance;
    111 
    112 /**
    113  * Historic denomination loss value.
    114  */
    115 static struct TALER_Amount rloss;
    116 
    117 /**
    118  * Reserve profit value we are using.
    119  */
    120 static struct TALER_Amount reserve_profits;
    121 
    122 
    123 static enum GNUNET_GenericReturnValue
    124 select_historic_denom_revenue_result (
    125   void *cls,
    126   uint64_t rowid,
    127   const struct TALER_DenominationHashP *denom_pub_hash2,
    128   struct GNUNET_TIME_Timestamp revenue_timestamp2,
    129   const struct TALER_Amount *revenue_balance2,
    130   const struct TALER_Amount *loss2)
    131 {
    132   static int n = 0;
    133 
    134   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
    135               "select_historic_denom_revenue_result: row %u\n", n);
    136 
    137   if ( (2 <= n++)
    138        || (cls != NULL)
    139        || ((0 != GNUNET_memcmp (&revenue_timestamp2,
    140                                 &past))
    141            && (0 != GNUNET_memcmp (&revenue_timestamp2,
    142                                    &now)))
    143        || ((0 != GNUNET_memcmp (denom_pub_hash2,
    144                                 &denom_pub_hash))
    145            && (0 != GNUNET_memcmp (denom_pub_hash2,
    146                                    &rnd_hash)))
    147        || (0 != TALER_amount_cmp (revenue_balance2,
    148                                   &rbalance))
    149        || (0 != TALER_amount_cmp (loss2,
    150                                   &rloss)))
    151   {
    152     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
    153                 "select_historic_denom_revenue_result: result does not match\n")
    154     ;
    155     GNUNET_break (0);
    156     return GNUNET_SYSERR;
    157   }
    158   return GNUNET_OK;
    159 }
    160 
    161 
    162 static enum GNUNET_GenericReturnValue
    163 select_historic_reserve_revenue_result (
    164   void *cls,
    165   uint64_t rowid,
    166   struct GNUNET_TIME_Timestamp start_time2,
    167   struct GNUNET_TIME_Timestamp end_time2,
    168   const struct TALER_Amount *reserve_profits2)
    169 {
    170   static int n = 0;
    171 
    172   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
    173               "select_historic_reserve_revenue_result: row %u\n", n);
    174 
    175   if ((2 <= n++)
    176       || (cls != NULL)
    177       || ((0 != GNUNET_memcmp (&start_time2,
    178                                &past))
    179           && (0 != GNUNET_memcmp (&start_time2,
    180                                   &now)))
    181       || (0 != GNUNET_memcmp (&end_time2,
    182                               &future))
    183       || (0 != TALER_amount_cmp (reserve_profits2,
    184                                  &reserve_profits)))
    185   {
    186     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
    187                 "select_historic_reserve_revenue_result: result does not match\n");
    188     GNUNET_break (0);
    189     return GNUNET_SYSERR;
    190   }
    191   return GNUNET_OK;
    192 }
    193 
    194 
    195 /**
    196  * Main function that will be run by the scheduler.
    197  *
    198  * @param cls closure with config
    199  */
    200 static void
    201 run (void *cls)
    202 {
    203   struct GNUNET_CONFIGURATION_Handle *cfg = cls;
    204   uint64_t rowid;
    205   struct TALER_Amount value;
    206   struct TALER_Amount fee_withdraw;
    207   struct TALER_Amount fee_deposit;
    208   struct TALER_Amount fee_refresh;
    209   struct TALER_Amount fee_refund;
    210   struct TALER_ReservePublicKeyP reserve_pub;
    211   struct TALER_DenominationPrivateKey denom_priv;
    212   struct TALER_DenominationPublicKey denom_pub;
    213   struct GNUNET_TIME_Timestamp date;
    214 
    215   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
    216               "connecting to database\n");
    217 
    218   if (NULL ==
    219       (pg = TALER_AUDITORDB_connect (cfg)))
    220   {
    221     result = 77;
    222     return;
    223   }
    224   GNUNET_assert (GNUNET_OK ==
    225                  TALER_AUDITORDB_preflight (pg));
    226   (void) TALER_AUDITORDB_drop_tables (pg,
    227                                       GNUNET_YES);
    228   if (GNUNET_OK !=
    229       TALER_AUDITORDB_create_tables (pg,
    230                                      false,
    231                                      0))
    232   {
    233     result = 77;
    234     goto unload;
    235   }
    236   if (GNUNET_SYSERR ==
    237       TALER_AUDITORDB_preflight (pg))
    238   {
    239     result = 77;
    240     goto drop;
    241   }
    242 
    243   FAILIF (GNUNET_OK !=
    244           TALER_AUDITORDB_start (pg,
    245                                  "test-auditordb"));
    246 
    247   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
    248               "initializing\n");
    249 
    250   GNUNET_assert (GNUNET_OK ==
    251                  TALER_string_to_amount (CURRENCY ":1.000010",
    252                                          &value));
    253   GNUNET_assert (GNUNET_OK ==
    254                  TALER_string_to_amount (CURRENCY ":0.000011",
    255                                          &fee_withdraw));
    256   GNUNET_assert (GNUNET_OK ==
    257                  TALER_string_to_amount (CURRENCY ":0.000012",
    258                                          &fee_deposit));
    259   GNUNET_assert (GNUNET_OK ==
    260                  TALER_string_to_amount (CURRENCY ":0.000013",
    261                                          &fee_refresh));
    262   GNUNET_assert (GNUNET_OK ==
    263                  TALER_string_to_amount (CURRENCY ":0.000014",
    264                                          &fee_refund));
    265   RND_BLK (&reserve_pub);
    266   RND_BLK (&rnd_hash);
    267   GNUNET_assert (GNUNET_OK ==
    268                  TALER_denom_priv_create (&denom_priv,
    269                                           &denom_pub,
    270                                           GNUNET_CRYPTO_BSA_RSA,
    271                                           1024));
    272   TALER_denom_pub_hash (&denom_pub,
    273                         &denom_pub_hash);
    274   TALER_denom_priv_free (&denom_priv);
    275   TALER_denom_pub_free (&denom_pub);
    276 
    277   now = GNUNET_TIME_timestamp_get ();
    278   past = GNUNET_TIME_absolute_to_timestamp (
    279     GNUNET_TIME_absolute_subtract (now.abs_time,
    280                                    GNUNET_TIME_relative_multiply (
    281                                      GNUNET_TIME_UNIT_HOURS,
    282                                      4)));
    283   future = GNUNET_TIME_absolute_to_timestamp (
    284     GNUNET_TIME_absolute_add (now.abs_time,
    285                               GNUNET_TIME_relative_multiply (
    286                                 GNUNET_TIME_UNIT_HOURS,
    287                                 4)));
    288 
    289   {
    290     struct TALER_AUDITORDB_ReserveFeeBalance rfb;
    291     struct TALER_AUDITORDB_ReserveFeeBalance rfb2;
    292 
    293     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
    294                 "Test: insert_reserve_info\n");
    295     GNUNET_assert (GNUNET_OK ==
    296                    TALER_string_to_amount (CURRENCY ":12.345678",
    297                                            &rfb.reserve_balance));
    298     GNUNET_assert (GNUNET_OK ==
    299                    TALER_string_to_amount (CURRENCY ":11.245678",
    300                                            &rfb.reserve_loss));
    301     GNUNET_assert (GNUNET_OK ==
    302                    TALER_string_to_amount (CURRENCY ":23.456789",
    303                                            &rfb.withdraw_fee_balance));
    304     GNUNET_assert (GNUNET_OK ==
    305                    TALER_string_to_amount (CURRENCY ":23.456719",
    306                                            &rfb.close_fee_balance));
    307     GNUNET_assert (GNUNET_OK ==
    308                    TALER_string_to_amount (CURRENCY ":33.456789",
    309                                            &rfb.purse_fee_balance));
    310     GNUNET_assert (GNUNET_OK ==
    311                    TALER_string_to_amount (CURRENCY ":43.456789",
    312                                            &rfb.open_fee_balance));
    313     GNUNET_assert (GNUNET_OK ==
    314                    TALER_string_to_amount (CURRENCY ":53.456789",
    315                                            &rfb.history_fee_balance));
    316     {
    317       struct TALER_FullPayto pt = {
    318         .full_payto = (char *) "payto://bla/blub?receiver-name=blub"
    319       };
    320 
    321       FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
    322               TALER_AUDITORDB_insert_reserve_info (pg,
    323                                                    &reserve_pub,
    324                                                    &rfb,
    325                                                    past,
    326                                                    pt));
    327     }
    328     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
    329                 "Test: update_reserve_info\n");
    330     FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
    331             TALER_AUDITORDB_update_reserve_info (pg,
    332                                                  &reserve_pub,
    333                                                  &rfb,
    334                                                  future));
    335     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
    336                 "Test: get_reserve_info\n");
    337     {
    338       struct TALER_FullPayto payto;
    339 
    340       FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
    341               TALER_AUDITORDB_get_reserve_info (pg,
    342                                                 &reserve_pub,
    343                                                 &rowid,
    344                                                 &rfb2,
    345                                                 &date,
    346                                                 &payto));
    347       FAILIF (0 != strcmp (payto.full_payto,
    348                            "payto://bla/blub?receiver-name=blub"));
    349       GNUNET_free (payto.full_payto);
    350     }
    351     FAILIF ( (0 != GNUNET_memcmp (&date,
    352                                   &future))
    353              || (0 != TALER_amount_cmp (&rfb2.reserve_balance,
    354                                         &rfb.reserve_balance))
    355              || (0 != TALER_amount_cmp (&rfb2.withdraw_fee_balance,
    356                                         &rfb.withdraw_fee_balance))
    357              || (0 != TALER_amount_cmp (&rfb2.close_fee_balance,
    358                                         &rfb.close_fee_balance))
    359              || (0 != TALER_amount_cmp (&rfb2.purse_fee_balance,
    360                                         &rfb.purse_fee_balance))
    361              || (0 != TALER_amount_cmp (&rfb2.open_fee_balance,
    362                                         &rfb.open_fee_balance))
    363              || (0 != TALER_amount_cmp (&rfb2.history_fee_balance,
    364                                         &rfb.history_fee_balance))
    365              );
    366   }
    367 
    368   {
    369     struct TALER_AUDITORDB_ClosureLags cl = {
    370       .problem_row_id = 42
    371     };
    372 
    373     GNUNET_assert (GNUNET_OK ==
    374                    TALER_string_to_amount (CURRENCY ":12.345678",
    375                                            &cl.amount));
    376     cl.account.full_payto
    377       = (char *) "payto://unspec/foo?receiver-name=bar";
    378     memset (&cl.wtid,
    379             42,
    380             sizeof (cl.wtid));
    381     cl.deadline = GNUNET_TIME_absolute_get ();
    382     FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=
    383             TALER_AUDITORDB_delete_auditor_closure_lag (pg,
    384                                                         &cl.amount,
    385                                                         &cl.wtid,
    386                                                         cl.account));
    387     FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
    388             TALER_AUDITORDB_insert_auditor_closure_lags (pg,
    389                                                          &cl));
    390     FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
    391             TALER_AUDITORDB_delete_auditor_closure_lag (pg,
    392                                                         &cl.amount,
    393                                                         &cl.wtid,
    394                                                         cl.account));
    395   }
    396 
    397   {
    398     struct TALER_AUDITORDB_DenominationCirculationData dcd;
    399     struct TALER_AUDITORDB_DenominationCirculationData dcd2;
    400 
    401     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
    402                 "Test: insert_denomination_balance\n");
    403     GNUNET_assert (GNUNET_OK ==
    404                    TALER_string_to_amount (CURRENCY ":12.345678",
    405                                            &dcd.denom_balance));
    406     GNUNET_assert (GNUNET_OK ==
    407                    TALER_string_to_amount (CURRENCY ":0.1",
    408                                            &dcd.denom_loss));
    409     GNUNET_assert (GNUNET_OK ==
    410                    TALER_string_to_amount (CURRENCY ":13.57986",
    411                                            &dcd.denom_risk));
    412     GNUNET_assert (GNUNET_OK ==
    413                    TALER_string_to_amount (CURRENCY ":12.57986",
    414                                            &dcd.recoup_loss));
    415     dcd.num_issued = 62;
    416     FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
    417             TALER_AUDITORDB_insert_denomination_balance (pg,
    418                                                          &denom_pub_hash,
    419                                                          &dcd));
    420     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
    421                 "Test: update_denomination_balance\n");
    422     FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
    423             TALER_AUDITORDB_update_denomination_balance (pg,
    424                                                          &denom_pub_hash,
    425                                                          &dcd));
    426     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
    427                 "Test: get_denomination_balance\n");
    428 
    429     FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
    430             TALER_AUDITORDB_get_denomination_balance (pg,
    431                                                       &denom_pub_hash,
    432                                                       &dcd2));
    433     FAILIF (0 != TALER_amount_cmp (&dcd2.denom_balance,
    434                                    &dcd.denom_balance));
    435     FAILIF (0 != TALER_amount_cmp (&dcd2.denom_loss,
    436                                    &dcd.denom_loss));
    437     FAILIF (0 != TALER_amount_cmp (&dcd2.denom_risk,
    438                                    &dcd.denom_risk));
    439     FAILIF (0 != TALER_amount_cmp (&dcd2.recoup_loss,
    440                                    &dcd.recoup_loss));
    441     FAILIF (dcd2.num_issued != dcd.num_issued);
    442   }
    443 
    444   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
    445               "Test: insert_historic_denom_revenue\n");
    446   GNUNET_assert (GNUNET_OK ==
    447                  TALER_string_to_amount (CURRENCY ":12.345678",
    448                                          &rbalance));
    449   GNUNET_assert (GNUNET_OK ==
    450                  TALER_string_to_amount (CURRENCY ":23.456789",
    451                                          &rloss));
    452   FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
    453           TALER_AUDITORDB_insert_historic_denom_revenue (pg,
    454                                                          &denom_pub_hash,
    455                                                          past,
    456                                                          &rbalance,
    457                                                          &rloss));
    458   FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
    459           TALER_AUDITORDB_insert_historic_denom_revenue (pg,
    460                                                          &rnd_hash,
    461                                                          now,
    462                                                          &rbalance,
    463                                                          &rloss));
    464   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
    465               "Test: select_historic_denom_revenue\n");
    466   FAILIF (0 >=
    467           TALER_AUDITORDB_select_historic_denom_revenue (
    468             pg,
    469             1024, /* limit */
    470             0, /* offset */
    471             &select_historic_denom_revenue_result,
    472             NULL));
    473   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
    474               "Test: insert_historic_reserve_revenue\n");
    475   GNUNET_assert (GNUNET_OK ==
    476                  TALER_string_to_amount (CURRENCY ":56.789012",
    477                                          &reserve_profits));
    478   FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
    479           TALER_AUDITORDB_insert_historic_reserve_revenue (pg,
    480                                                            past,
    481                                                            future,
    482                                                            &reserve_profits));
    483   FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
    484           TALER_AUDITORDB_insert_historic_reserve_revenue (pg,
    485                                                            now,
    486                                                            future,
    487                                                            &reserve_profits));
    488   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
    489               "Test: select_historic_reserve_revenue\n");
    490   FAILIF (0 >=
    491           TALER_AUDITORDB_select_historic_reserve_revenue (
    492             pg,
    493             1024, /* limit */
    494             0,    /* offset */
    495             &select_historic_reserve_revenue_result,
    496             NULL));
    497 
    498   FAILIF (0 >
    499           TALER_AUDITORDB_commit (pg));
    500 
    501   FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
    502           TALER_AUDITORDB_del_reserve_info (pg,
    503                                             &reserve_pub));
    504 
    505 #if GC_IMPLEMENTED
    506   FAILIF (GNUNET_OK !=
    507           TALER_AUDITORDB_gc (pg));
    508 #endif
    509 
    510   result = 0;
    511 
    512 drop:
    513   TALER_AUDITORDB_rollback (pg);
    514   GNUNET_break (GNUNET_OK ==
    515                 TALER_AUDITORDB_drop_tables (pg,
    516                                              GNUNET_YES));
    517 unload:
    518   TALER_AUDITORDB_disconnect (pg);
    519   pg = NULL;
    520 }
    521 
    522 
    523 int
    524 main (int argc,
    525       char *const argv[])
    526 {
    527   struct GNUNET_CONFIGURATION_Handle *cfg;
    528 
    529   (void) argc;
    530   result = -1;
    531   GNUNET_log_setup (argv[0],
    532                     "WARNING",
    533                     NULL);
    534   cfg = GNUNET_CONFIGURATION_create (TALER_AUDITOR_project_data ());
    535   if (GNUNET_OK !=
    536       GNUNET_CONFIGURATION_parse (cfg,
    537                                   "test-auditor-db-postgres.conf"))
    538   {
    539     GNUNET_break (0);
    540     return 2;
    541   }
    542   GNUNET_SCHEDULER_run (&run,
    543                         cfg);
    544   GNUNET_CONFIGURATION_destroy (cfg);
    545   return result;
    546 }