LCOV - code coverage report
Current view: top level - exchangedb - test_batch_deposits.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 100.0 % 144 144
Test Date: 2026-09-11 18:55:36 Functions: 100.0 % 9 9

            Line data    Source code
       1              : /*
       2              :   This file is part of TALER
       3              :   Copyright (C) 2026 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 exchangedb/test_batch_deposits.c
      18              :  * @brief tests for the exchangedb functions whose primary table is
      19              :  *        `batch_deposits`
      20              :  * @author Christian Grothoff
      21              :  *
      22              :  * Covers #TALER_EXCHANGEDB_do_deposit(),
      23              :  * #TALER_EXCHANGEDB_do_check_deposit_idempotent(),
      24              :  * #TALER_EXCHANGEDB_get_exists_deposit(),
      25              :  * #TALER_EXCHANGEDB_get_ready_deposit(),
      26              :  * #TALER_EXCHANGEDB_iterate_batch_deposits_missing_wire() and
      27              :  * #TALER_EXCHANGEDB_get_wire_hash_for_contract().
      28              :  *
      29              :  * `batch_deposits` references `wire_targets` and, through `coin_deposits`,
      30              :  * `known_coins`.  A deposit is "ready" only once its wire deadline has
      31              :  * passed *and* its refund deadline is behind the aggregation shift
      32              :  * boundary, so the checks use deadlines in the past for that.
      33              :  */
      34              : #include "test_common.h"
      35              : #include "exchange-database/do_check_deposit_idempotent.h"
      36              : #include "exchange-database/do_deposit.h"
      37              : #include "exchange-database/get_exists_deposit.h"
      38              : #include "exchange-database/get_ready_deposit.h"
      39              : #include "exchange-database/get_wire_hash_for_contract.h"
      40              : #include "exchange-database/iterate_batch_deposits_missing_wire.h"
      41              : #include "exchange-database/rollback.h"
      42              : #include "exchange-database/start.h"
      43              : 
      44              : 
      45              : /**
      46              :  * Account the merchants of the checks are paid at.
      47              :  */
      48              : static struct TDB_Account account;
      49              : 
      50              : 
      51              : /**
      52              :  * Denomination the checks deposit.
      53              :  */
      54              : static struct TDB_Denom denom;
      55              : 
      56              : 
      57              : /**
      58              :  * Build a timestamp from a number of seconds since the epoch.
      59              :  *
      60              :  * @param secs seconds since the epoch
      61              :  * @return the timestamp
      62              :  */
      63              : static struct GNUNET_TIME_Timestamp
      64            7 : ts (uint64_t secs)
      65              : {
      66            7 :   struct GNUNET_TIME_Absolute abs = {
      67            7 :     .abs_value_us = secs * 1000LLU * 1000LLU
      68              :   };
      69              : 
      70            7 :   return GNUNET_TIME_absolute_to_timestamp (abs);
      71              : }
      72              : 
      73              : 
      74              : /**
      75              :  * Closure for #missing_cb().
      76              :  */
      77              : struct MissingContext
      78              : {
      79              :   /**
      80              :    * How many deposits did the callback see?
      81              :    */
      82              :   unsigned int total;
      83              : 
      84              :   /**
      85              :    * Row of the first deposit seen.
      86              :    */
      87              :   uint64_t first_row;
      88              : 
      89              :   /**
      90              :    * Sum of the whole-unit parts of the amounts seen.
      91              :    */
      92              :   uint64_t value_sum;
      93              : 
      94              :   /**
      95              :    * Account of the last deposit seen.
      96              :    */
      97              :   struct TALER_FullPaytoHashP h_payto;
      98              : };
      99              : 
     100              : 
     101              : /**
     102              :  * Callback for #TALER_EXCHANGEDB_iterate_batch_deposits_missing_wire().
     103              :  *
     104              :  * @param cls a `struct MissingContext *`
     105              :  * @param batch_deposit_serial_id row of the deposit
     106              :  * @param total_amount how much is owed
     107              :  * @param wire_target_h_payto where it is owed
     108              :  * @param deadline when it was due
     109              :  */
     110              : static void
     111            1 : missing_cb (void *cls,
     112              :             uint64_t batch_deposit_serial_id,
     113              :             const struct TALER_Amount *total_amount,
     114              :             const struct TALER_FullPaytoHashP *wire_target_h_payto,
     115              :             struct GNUNET_TIME_Timestamp deadline)
     116              : {
     117            1 :   struct MissingContext *ctx = cls;
     118              : 
     119              :   (void) deadline;
     120            1 :   if (0 == ctx->total++)
     121            1 :     ctx->first_row = batch_deposit_serial_id;
     122            1 :   ctx->value_sum += total_amount->value;
     123            1 :   ctx->h_payto = *wire_target_h_payto;
     124            1 : }
     125              : 
     126              : 
     127              : /**
     128              :  * Nothing is known while the table is empty.
     129              :  *
     130              :  * @param pg the database context
     131              :  * @return 0 on success
     132              :  */
     133              : static int
     134            1 : check_empty (struct TALER_EXCHANGEDB_PostgresContext *pg)
     135              : {
     136              :   struct TALER_MerchantPublicKeyP merchant_pub;
     137              :   struct TALER_PrivateContractHashP h_contract_terms;
     138              :   struct TALER_MerchantWireHashP h_wire;
     139              :   struct TALER_CoinSpendPublicKeyP coin_pub;
     140              :   struct TALER_Amount deposit_fee;
     141              :   struct GNUNET_TIME_Timestamp exchange_timestamp;
     142            1 :   struct TALER_FullPayto payto_uri = { NULL };
     143            1 :   struct MissingContext ctx = { 0 };
     144            1 :   char *metadata = NULL;
     145              : 
     146            1 :   TDB_FILL (merchant_pub,
     147              :             1);
     148            1 :   TDB_FILL (h_contract_terms,
     149              :             1);
     150            1 :   TDB_FILL (h_wire,
     151              :             1);
     152            1 :   TDB_FILL (coin_pub,
     153              :             1);
     154            1 :   FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=
     155              :           TALER_EXCHANGEDB_get_wire_hash_for_contract (pg,
     156              :                                                        &merchant_pub,
     157              :                                                        &h_contract_terms,
     158              :                                                        &h_wire));
     159            1 :   FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=
     160              :           TALER_EXCHANGEDB_get_exists_deposit (pg,
     161              :                                                &h_contract_terms,
     162              :                                                &h_wire,
     163              :                                                &coin_pub,
     164              :                                                &merchant_pub,
     165              :                                                ts (1600000000),
     166              :                                                &deposit_fee,
     167              :                                                &exchange_timestamp));
     168            1 :   FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=
     169              :           TALER_EXCHANGEDB_get_ready_deposit (pg,
     170              :                                               0,
     171              :                                               UINT32_MAX,
     172              :                                               &merchant_pub,
     173              :                                               &payto_uri,
     174              :                                               &metadata));
     175            1 :   FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=
     176              :           TALER_EXCHANGEDB_iterate_batch_deposits_missing_wire (pg,
     177              :                                                                 0,
     178              :                                                                 &missing_cb,
     179              :                                                                 &ctx));
     180            1 :   FAILIF (0 != ctx.total);
     181            1 :   return 0;
     182              : }
     183              : 
     184              : 
     185              : /**
     186              :  * A deposit of more than the coin holds is refused.
     187              :  *
     188              :  * @param pg the database context
     189              :  * @return 0 on success
     190              :  */
     191              : static int
     192            1 : check_insufficient_balance (struct TALER_EXCHANGEDB_PostgresContext *pg)
     193              : {
     194              :   struct TALER_CoinPublicInfo coin;
     195              :   struct TALER_EXCHANGEDB_CoinDepositInformation cdi;
     196              :   struct TALER_EXCHANGEDB_BatchDeposit bd;
     197              :   struct TALER_Amount fees[1];
     198              :   struct TALER_Amount total;
     199            1 :   struct GNUNET_TIME_Timestamp now = GNUNET_TIME_timestamp_get ();
     200            1 :   uint32_t bad_balance_index = 42;
     201            1 :   bool balance_ok = true;
     202            1 :   bool in_conflict = true;
     203              : 
     204            1 :   TDB_denom (pg,
     205              :              10,
     206              :              "5",
     207              :              "0.1",
     208              :              &denom);
     209            1 :   TDB_account (pg,
     210              :                10,
     211              :                &account);
     212            1 :   TDB_coin (pg,
     213              :             &denom,
     214              :             20,
     215              :             &coin,
     216              :             NULL);
     217            1 :   memset (&cdi,
     218              :           0,
     219              :           sizeof (cdi));
     220            1 :   cdi.coin = coin;
     221            1 :   TDB_FILL (cdi.csig,
     222              :             20);
     223            1 :   cdi.amount_with_fee = TDB_amount ("6");
     224            1 :   fees[0] = TDB_amount ("0.1");
     225            1 :   memset (&bd,
     226              :           0,
     227              :           sizeof (bd));
     228            1 :   TDB_FILL (bd.merchant_pub,
     229              :             20);
     230            1 :   TDB_FILL (bd.merchant_sig,
     231              :             20);
     232            1 :   TDB_FILL (bd.h_contract_terms,
     233              :             20);
     234            1 :   bd.no_wallet_data_hash = true;
     235            1 :   bd.wire_target_h_payto = account.h_full;
     236            1 :   TDB_FILL (bd.wire_salt,
     237              :             20);
     238            1 :   bd.wallet_timestamp = now;
     239            1 :   bd.refund_deadline = now;
     240            1 :   bd.wire_deadline = now;
     241            1 :   bd.receiver_wire_account = account.payto;
     242            1 :   bd.cdis = &cdi;
     243            1 :   bd.num_cdis = 1;
     244              :   /* The batch row goes in before the per-coin balance is checked, so this
     245              :      is how the /deposit handler uses the function: inside a transaction it
     246              :      can roll back. */
     247            1 :   FAILIF_C (GNUNET_OK !=
     248              :             TALER_EXCHANGEDB_start (pg,
     249              :                                     "test-deposit-insufficient"),
     250              :             TDB_coin_free (&coin));
     251            1 :   FAILIF_C (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
     252              :             TALER_EXCHANGEDB_do_deposit (pg,
     253              :                                          &bd,
     254              :                                          fees,
     255              :                                          &now,
     256              :                                          &total,
     257              :                                          &balance_ok,
     258              :                                          &bad_balance_index,
     259              :                                          &in_conflict),
     260              :             TALER_EXCHANGEDB_rollback (pg); TDB_coin_free (&coin));
     261            1 :   TALER_EXCHANGEDB_rollback (pg);
     262            1 :   TDB_coin_free (&coin);
     263            1 :   FAILIF (balance_ok);
     264            1 :   FAILIF (in_conflict);
     265            1 :   FAILIF (0 != bad_balance_index);
     266            1 :   FAILIF (0 != TDB_count (pg,
     267              :                           "FROM batch_deposits"));
     268            1 :   return 0;
     269              : }
     270              : 
     271              : 
     272              : /**
     273              :  * A deposit within the coin's balance is recorded and can be found again.
     274              :  *
     275              :  * @param pg the database context
     276              :  * @return 0 on success
     277              :  */
     278              : static int
     279            1 : check_deposit (struct TALER_EXCHANGEDB_PostgresContext *pg)
     280              : {
     281              :   struct TALER_CoinPublicInfo coin;
     282              :   struct TDB_Deposit dep;
     283              :   struct TALER_MerchantWireHashP h_wire;
     284              :   struct TALER_Amount deposit_fee;
     285            1 :   struct TALER_Amount expect_fee = TDB_amount ("0.1");
     286              :   struct GNUNET_TIME_Timestamp exchange_timestamp;
     287              : 
     288            1 :   TDB_coin (pg,
     289              :             &denom,
     290              :             21,
     291              :             &coin,
     292              :             NULL);
     293            1 :   TDB_deposit (pg,
     294              :                &account,
     295              :                &coin,
     296              :                21,
     297              :                "1",
     298              :                "0.1",
     299              :                ts (1600000000),
     300              :                ts (1600000000),
     301              :                &dep);
     302            1 :   FAILIF_C (1 != TDB_count (pg,
     303              :                             "FROM batch_deposits"),
     304              :             TDB_coin_free (&coin));
     305            1 :   FAILIF_C (1 != TDB_count (pg,
     306              :                             "FROM coin_deposits"),
     307              :             TDB_coin_free (&coin));
     308              : 
     309              :   /* the salted account hash comes back from the contract */
     310            1 :   FAILIF_C (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
     311              :             TALER_EXCHANGEDB_get_wire_hash_for_contract (pg,
     312              :                                                          &dep.merchant_pub,
     313              :                                                          &dep.h_contract_terms,
     314              :                                                          &h_wire),
     315              :             TDB_coin_free (&coin));
     316            1 :   FAILIF_C (0 != GNUNET_memcmp (&h_wire,
     317              :                                 &dep.h_wire),
     318              :             TDB_coin_free (&coin));
     319              : 
     320              :   /* ...and the deposit itself, with its fee */
     321            1 :   FAILIF_C (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
     322              :             TALER_EXCHANGEDB_get_exists_deposit (pg,
     323              :                                                  &dep.h_contract_terms,
     324              :                                                  &dep.h_wire,
     325              :                                                  &coin.coin_pub,
     326              :                                                  &dep.merchant_pub,
     327              :                                                  dep.refund_deadline,
     328              :                                                  &deposit_fee,
     329              :                                                  &exchange_timestamp),
     330              :             TDB_coin_free (&coin));
     331            1 :   FAILIF_C (0 != TALER_amount_cmp (&deposit_fee,
     332              :                                    &expect_fee),
     333              :             TDB_coin_free (&coin));
     334              : 
     335              :   /* a different refund deadline makes it a different deposit */
     336            1 :   FAILIF_C (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=
     337              :             TALER_EXCHANGEDB_get_exists_deposit (pg,
     338              :                                                  &dep.h_contract_terms,
     339              :                                                  &dep.h_wire,
     340              :                                                  &coin.coin_pub,
     341              :                                                  &dep.merchant_pub,
     342              :                                                  ts (1700000000),
     343              :                                                  &deposit_fee,
     344              :                                                  &exchange_timestamp),
     345              :             TDB_coin_free (&coin));
     346              :   /* ...and so does a different account hash */
     347              :   {
     348              :     struct TALER_MerchantWireHashP other;
     349              : 
     350            1 :     TDB_FILL (other,
     351              :               99);
     352            1 :     FAILIF_C (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=
     353              :               TALER_EXCHANGEDB_get_exists_deposit (pg,
     354              :                                                    &dep.h_contract_terms,
     355              :                                                    &other,
     356              :                                                    &coin.coin_pub,
     357              :                                                    &dep.merchant_pub,
     358              :                                                    dep.refund_deadline,
     359              :                                                    &deposit_fee,
     360              :                                                    &exchange_timestamp),
     361              :               TDB_coin_free (&coin));
     362              :   }
     363            1 :   TDB_coin_free (&coin);
     364            1 :   return 0;
     365              : }
     366              : 
     367              : 
     368              : /**
     369              :  * A replayed deposit is recognised as idempotent; a different one is not.
     370              :  *
     371              :  * @param pg the database context
     372              :  * @return 0 on success
     373              :  */
     374              : static int
     375            1 : check_idempotent (struct TALER_EXCHANGEDB_PostgresContext *pg)
     376              : {
     377              :   struct TALER_CoinPublicInfo coin;
     378              :   struct TALER_EXCHANGEDB_CoinDepositInformation cdi;
     379              :   struct TALER_EXCHANGEDB_BatchDeposit bd;
     380              :   struct GNUNET_TIME_Timestamp exchange_timestamp;
     381            1 :   bool is_idempotent = false;
     382              : 
     383            1 :   TDB_coin (pg,
     384              :             &denom,
     385              :             21,
     386              :             &coin,
     387              :             NULL);
     388            1 :   memset (&cdi,
     389              :           0,
     390              :           sizeof (cdi));
     391            1 :   cdi.coin = coin;
     392            1 :   TDB_FILL (cdi.csig,
     393              :             21);
     394            1 :   cdi.amount_with_fee = TDB_amount ("1");
     395            1 :   memset (&bd,
     396              :           0,
     397              :           sizeof (bd));
     398            1 :   TDB_FILL (bd.merchant_pub,
     399              :             21);
     400            1 :   TDB_FILL (bd.merchant_sig,
     401              :             21);
     402            1 :   TDB_FILL (bd.h_contract_terms,
     403              :             21);
     404            1 :   bd.no_wallet_data_hash = true;
     405            1 :   bd.wire_target_h_payto = account.h_full;
     406            1 :   TDB_FILL (bd.wire_salt,
     407              :             21);
     408            1 :   bd.wallet_timestamp = ts (1600000000);
     409            1 :   bd.refund_deadline = ts (1600000000);
     410            1 :   bd.wire_deadline = ts (1600000000);
     411            1 :   bd.receiver_wire_account = account.payto;
     412            1 :   bd.cdis = &cdi;
     413            1 :   bd.num_cdis = 1;
     414            1 :   exchange_timestamp = GNUNET_TIME_timestamp_get ();
     415            1 :   FAILIF_C (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
     416              :             TALER_EXCHANGEDB_do_check_deposit_idempotent (
     417              :               pg,
     418              :               &bd,
     419              :               &exchange_timestamp,
     420              :               &is_idempotent),
     421              :             TDB_coin_free (&coin));
     422            1 :   FAILIF_C (! is_idempotent,
     423              :             TDB_coin_free (&coin));
     424              : 
     425              :   /* a different amount for the same contract is not the same request */
     426            1 :   cdi.amount_with_fee = TDB_amount ("2");
     427            1 :   is_idempotent = true;
     428            1 :   FAILIF_C (0 >
     429              :             TALER_EXCHANGEDB_do_check_deposit_idempotent (
     430              :               pg,
     431              :               &bd,
     432              :               &exchange_timestamp,
     433              :               &is_idempotent),
     434              :             TDB_coin_free (&coin));
     435            1 :   FAILIF_C (is_idempotent,
     436              :             TDB_coin_free (&coin));
     437              : 
     438              :   /* neither is a contract we never saw */
     439            1 :   cdi.amount_with_fee = TDB_amount ("1");
     440            1 :   TDB_FILL (bd.h_contract_terms,
     441              :             98);
     442            1 :   is_idempotent = true;
     443            1 :   FAILIF_C (0 >
     444              :             TALER_EXCHANGEDB_do_check_deposit_idempotent (
     445              :               pg,
     446              :               &bd,
     447              :               &exchange_timestamp,
     448              :               &is_idempotent),
     449              :             TDB_coin_free (&coin));
     450            1 :   FAILIF_C (is_idempotent,
     451              :             TDB_coin_free (&coin));
     452            1 :   TDB_coin_free (&coin);
     453            1 :   return 0;
     454              : }
     455              : 
     456              : 
     457              : /**
     458              :  * A deposit whose deadlines have passed becomes ready for the aggregator,
     459              :  * and shows up as missing a wire transfer.
     460              :  *
     461              :  * @param pg the database context
     462              :  * @return 0 on success
     463              :  */
     464              : static int
     465            1 : check_ready (struct TALER_EXCHANGEDB_PostgresContext *pg)
     466              : {
     467              :   struct TALER_MerchantPublicKeyP merchant_pub;
     468            1 :   struct TALER_FullPayto payto_uri = { NULL };
     469              :   struct MissingContext ctx;
     470            1 :   char *metadata = NULL;
     471              : 
     472              :   /* the deposit from check_deposit() has deadlines in 2020 */
     473            1 :   FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
     474              :           TALER_EXCHANGEDB_get_ready_deposit (pg,
     475              :                                               0,
     476              :                                               UINT32_MAX,
     477              :                                               &merchant_pub,
     478              :                                               &payto_uri,
     479              :                                               &metadata));
     480            1 :   FAILIF_C (0 != strcmp (payto_uri.full_payto,
     481              :                          account.payto.full_payto),
     482              :             GNUNET_free (payto_uri.full_payto); GNUNET_free (metadata));
     483            1 :   GNUNET_free (payto_uri.full_payto);
     484            1 :   GNUNET_free (metadata);
     485              :   /* no extra metadata was set */
     486            1 :   FAILIF (NULL != metadata);
     487              : 
     488              :   /* a shard range the merchant is not in has nothing ready */
     489            1 :   FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=
     490              :           TALER_EXCHANGEDB_get_ready_deposit (pg,
     491              :                                               0,
     492              :                                               0,
     493              :                                               &merchant_pub,
     494              :                                               &payto_uri,
     495              :                                               &metadata));
     496              : 
     497            1 :   memset (&ctx,
     498              :           0,
     499              :           sizeof (ctx));
     500            1 :   FAILIF (0 >=
     501              :           TALER_EXCHANGEDB_iterate_batch_deposits_missing_wire (pg,
     502              :                                                                 0,
     503              :                                                                 &missing_cb,
     504              :                                                                 &ctx));
     505            1 :   FAILIF (1 != ctx.total);
     506            1 :   FAILIF (0 != GNUNET_memcmp (&ctx.h_payto,
     507              :                               &account.h_full));
     508              :   /* the amount reported is the gross deposit, fee included */
     509            1 :   FAILIF (1 != ctx.value_sum);
     510              : 
     511              :   /* the serial bound excludes it again */
     512            1 :   memset (&ctx,
     513              :           0,
     514              :           sizeof (ctx));
     515            1 :   FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=
     516              :           TALER_EXCHANGEDB_iterate_batch_deposits_missing_wire (pg,
     517              :                                                                 1000,
     518              :                                                                 &missing_cb,
     519              :                                                                 &ctx));
     520            1 :   FAILIF (0 != ctx.total);
     521            1 :   return 0;
     522              : }
     523              : 
     524              : 
     525              : /**
     526              :  * A deposit that is done or policy-blocked is not ready.
     527              :  *
     528              :  * @param pg the database context
     529              :  * @return 0 on success
     530              :  */
     531              : static int
     532            1 : check_not_ready (struct TALER_EXCHANGEDB_PostgresContext *pg)
     533              : {
     534              :   struct TALER_MerchantPublicKeyP merchant_pub;
     535            1 :   struct TALER_FullPayto payto_uri = { NULL };
     536            1 :   char *metadata = NULL;
     537              : 
     538            1 :   FAILIF (GNUNET_OK !=
     539              :           TDB_exec (pg,
     540              :                     "UPDATE batch_deposits SET done=TRUE;"));
     541            1 :   FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=
     542              :           TALER_EXCHANGEDB_get_ready_deposit (pg,
     543              :                                               0,
     544              :                                               UINT32_MAX,
     545              :                                               &merchant_pub,
     546              :                                               &payto_uri,
     547              :                                               &metadata));
     548            1 :   FAILIF (GNUNET_OK !=
     549              :           TDB_exec (pg,
     550              :                     "UPDATE batch_deposits"
     551              :                     " SET done=FALSE, policy_blocked=TRUE;"));
     552            1 :   FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS !=
     553              :           TALER_EXCHANGEDB_get_ready_deposit (pg,
     554              :                                               0,
     555              :                                               UINT32_MAX,
     556              :                                               &merchant_pub,
     557              :                                               &payto_uri,
     558              :                                               &metadata));
     559            1 :   FAILIF (GNUNET_OK !=
     560              :           TDB_exec (pg,
     561              :                     "UPDATE batch_deposits SET policy_blocked=FALSE;"));
     562            1 :   FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
     563              :           TALER_EXCHANGEDB_get_ready_deposit (pg,
     564              :                                               0,
     565              :                                               UINT32_MAX,
     566              :                                               &merchant_pub,
     567              :                                               &payto_uri,
     568              :                                               &metadata));
     569            1 :   GNUNET_free (payto_uri.full_payto);
     570            1 :   GNUNET_free (metadata);
     571            1 :   return 0;
     572              : }
     573              : 
     574              : 
     575              : /**
     576              :  * The checks to run, in order.
     577              :  */
     578              : static const struct TDB_Test tests[] = {
     579              :   { "batch-deposits-empty",
     580              :     &check_empty },
     581              :   { "batch-deposits-insufficient-balance",
     582              :     &check_insufficient_balance },
     583              :   { "batch-deposits-deposit",
     584              :     &check_deposit },
     585              :   { "batch-deposits-idempotent",
     586              :     &check_idempotent },
     587              :   { "batch-deposits-ready",
     588              :     &check_ready },
     589              :   { "batch-deposits-not-ready",
     590              :     &check_not_ready },
     591              :   { NULL, NULL }
     592              : };
     593              : 
     594              : 
     595              : int
     596            1 : main (int argc,
     597              :       char *const *argv)
     598              : {
     599              :   int ret;
     600              : 
     601            1 :   ret = TDB_main (argc,
     602              :                   argv,
     603              :                   "test-batch-deposits",
     604              :                   "Tests for the exchangedb `batch_deposits' table",
     605              :                   tests);
     606            1 :   TDB_account_free (&account);
     607            1 :   TDB_denom_free (&denom);
     608            1 :   return ret;
     609              : }
     610              : 
     611              : 
     612              : /* end of test_batch_deposits.c */
        

Generated by: LCOV version 2.0-1