LCOV - code coverage report
Current view: top level - exchangedb - get_withdraw.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 76.1 % 71 54
Test Date: 2026-04-14 15:39:31 Functions: 100.0 % 1 1

            Line data    Source code
       1              : /*
       2              :    This file is part of TALER
       3              :    Copyright (C) 2023, 2025 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/get_withdraw.c
      18              :  * @brief Implementation of the get_withdraw function for Postgres
      19              :  * @author Özgür Kesim
      20              :  */
      21              : #include "taler/taler_pq_lib.h"
      22              : #include "exchange-database/get_withdraw.h"
      23              : #include "helper.h"
      24              : 
      25              : 
      26              : enum GNUNET_DB_QueryStatus
      27           10 : TALER_EXCHANGEDB_get_withdraw (
      28              :   struct TALER_EXCHANGEDB_PostgresContext *pg,
      29              :   const struct TALER_HashBlindedPlanchetsP *wch,
      30              :   struct TALER_EXCHANGEDB_Withdraw *wd)
      31              : {
      32              :   enum GNUNET_DB_QueryStatus ret;
      33           10 :   struct GNUNET_PQ_QueryParam params[] = {
      34           10 :     GNUNET_PQ_query_param_auto_from_type (wch),
      35              :     GNUNET_PQ_query_param_end
      36              :   };
      37           10 :   struct TALER_BlindedDenominationSignature *my_denom_sigs = NULL;
      38           10 :   uint64_t *my_denom_serials = NULL;
      39           10 :   struct GNUNET_CRYPTO_CSPublicRPairP *my_cs_r_values = NULL;
      40           10 :   size_t num_sigs = 0;
      41           10 :   size_t num_coins = 0;
      42           10 :   size_t num_cs_r_values = 0;
      43              :   bool no_noreveal_index;
      44              :   bool no_max_age;
      45              :   bool no_selected_h;
      46              :   bool no_blinding_seed;
      47              :   bool no_cs_r_values;
      48              :   bool no_cs_r_choices;
      49              : 
      50           10 :   struct GNUNET_PQ_ResultSpec rs[] = {
      51           10 :     GNUNET_PQ_result_spec_auto_from_type ("planchets_h",
      52              :                                           &wd->planchets_h),
      53           10 :     GNUNET_PQ_result_spec_auto_from_type ("reserve_sig",
      54              :                                           &wd->reserve_sig),
      55           10 :     GNUNET_PQ_result_spec_auto_from_type ("reserve_pub",
      56              :                                           &wd->reserve_pub),
      57           10 :     GNUNET_PQ_result_spec_allow_null (
      58              :       GNUNET_PQ_result_spec_uint16 ("max_age",
      59              :                                     &wd->max_age),
      60              :       &no_max_age),
      61           10 :     TALER_PQ_result_spec_amount ("amount_with_fee",
      62           10 :                                  pg->currency,
      63              :                                  &wd->amount_with_fee),
      64           10 :     GNUNET_PQ_result_spec_allow_null (
      65              :       GNUNET_PQ_result_spec_uint16 ("noreveal_index",
      66              :                                     &wd->noreveal_index),
      67              :       &no_noreveal_index),
      68           10 :     GNUNET_PQ_result_spec_allow_null (
      69           10 :       GNUNET_PQ_result_spec_auto_from_type ("selected_h",
      70              :                                             &wd->selected_h),
      71              :       &no_selected_h),
      72           10 :     GNUNET_PQ_result_spec_allow_null (
      73           10 :       GNUNET_PQ_result_spec_auto_from_type ("blinding_seed",
      74              :                                             &wd->blinding_seed),
      75              :       &no_blinding_seed),
      76           10 :     GNUNET_PQ_result_spec_allow_null (
      77              :       TALER_PQ_result_spec_array_cs_r_pub (
      78              :         pg->conn,
      79              :         "cs_r_values",
      80              :         &num_cs_r_values,
      81              :         &my_cs_r_values),
      82              :       &no_cs_r_values),
      83           10 :     GNUNET_PQ_result_spec_allow_null (
      84              :       GNUNET_PQ_result_spec_uint64 ("cs_r_choices",
      85              :                                     &wd->cs_r_choices),
      86              :       &no_cs_r_choices),
      87           10 :     TALER_PQ_result_spec_array_blinded_denom_sig (
      88              :       pg->conn,
      89              :       "denom_sigs",
      90              :       &num_sigs,
      91              :       &my_denom_sigs),
      92           10 :     GNUNET_PQ_result_spec_array_uint64 (
      93              :       pg->conn,
      94              :       "denom_serials",
      95              :       &num_coins,
      96              :       &my_denom_serials),
      97              :     GNUNET_PQ_result_spec_end
      98              :   };
      99              : 
     100           10 :   PREPARE (pg,
     101              :            "get_withdraw",
     102              :            "SELECT"
     103              :            " planchets_h"
     104              :            ",blinding_seed"
     105              :            ",reserve_sig"
     106              :            ",reserve_pub"
     107              :            ",max_age"
     108              :            ",amount_with_fee"
     109              :            ",noreveal_index"
     110              :            ",selected_h"
     111              :            ",blinding_seed"
     112              :            ",cs_r_values"
     113              :            ",cs_r_choices"
     114              :            ",denom_sigs"
     115              :            ",denom_serials"
     116              :            " FROM withdraw"
     117              :            " WHERE planchets_h=$1;");
     118           10 :   ret = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
     119              :                                                   "get_withdraw",
     120              :                                                   params,
     121              :                                                   rs);
     122           10 :   if (0 > ret)
     123              :   {
     124            0 :     GNUNET_break (0);
     125            0 :     GNUNET_PQ_cleanup_result (rs);
     126            0 :     return ret;
     127              :   }
     128           10 :   if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == ret)
     129              :   {
     130            7 :     GNUNET_PQ_cleanup_result (rs);
     131            7 :     return ret;
     132              :   }
     133              : 
     134            3 :   if ((no_max_age != no_noreveal_index) ||
     135            3 :       (no_max_age != no_selected_h))
     136              :   {
     137            0 :     GNUNET_break (0);
     138            0 :     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     139              :                 "got inconsistent state for max_age, noreveal_index and planchets_h in DB: "
     140              :                 "no_max_age=%s, no_noreveal_index=%s, no_selected_h=%s\n",
     141              :                 no_max_age ? "true" : "false",
     142              :                 no_noreveal_index ? "true" : "false",
     143              :                 no_selected_h ? "true" : "false");
     144            0 :     GNUNET_PQ_cleanup_result (rs);
     145            0 :     return GNUNET_DB_STATUS_HARD_ERROR;
     146              :   }
     147            3 :   if (no_blinding_seed != no_cs_r_values)
     148              :   {
     149            0 :     GNUNET_break (0);
     150            0 :     GNUNET_PQ_cleanup_result (rs);
     151            0 :     return GNUNET_DB_STATUS_HARD_ERROR;
     152              :   }
     153            3 :   if (no_cs_r_choices != no_cs_r_values)
     154              :   {
     155            0 :     GNUNET_break (0);
     156            0 :     GNUNET_PQ_cleanup_result (rs);
     157            0 :     return GNUNET_DB_STATUS_HARD_ERROR;
     158              :   }
     159            3 :   if (num_coins != num_sigs)
     160              :   {
     161            0 :     GNUNET_break (0);
     162            0 :     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     163              :                 "got inconsistent number of entries in withdraw from DB: "
     164              :                 "num_coins=%ld, num_sigs=%ld\n",
     165              :                 num_coins,
     166              :                 num_sigs);
     167            0 :     GNUNET_PQ_cleanup_result (rs);
     168            0 :     return GNUNET_DB_STATUS_HARD_ERROR;
     169              :   }
     170            3 :   wd->age_proof_required = ! no_max_age;
     171            3 :   if (no_cs_r_values)
     172              :   {
     173            2 :     wd->cs_r_values = NULL;
     174            2 :     wd->num_cs_r_values = 0;
     175            2 :     wd->cs_r_choices = 0;
     176              :   }
     177            3 :   wd->denom_sigs = my_denom_sigs;
     178            3 :   wd->num_coins = num_coins;
     179            3 :   wd->denom_serials = my_denom_serials;
     180            3 :   wd->cs_r_values = my_cs_r_values;
     181            3 :   wd->num_cs_r_values = num_cs_r_values;
     182              :   /* ensure cleanup_result does not trash data we care about */
     183            3 :   my_denom_sigs = NULL;
     184            3 :   my_denom_serials = NULL;
     185            3 :   my_cs_r_values = NULL;
     186            3 :   num_sigs = 0;
     187            3 :   num_coins = 0;
     188            3 :   num_cs_r_values = 0;
     189            3 :   GNUNET_PQ_cleanup_result (rs);
     190            3 :   return ret;
     191              : }
        

Generated by: LCOV version 2.0-1