LCOV - code coverage report
Current view: top level - exchangedb - get_withdraw.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 76.4 % 72 55
Test Date: 2026-10-10 21:00:14 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           39 : 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           39 :   struct GNUNET_PQ_QueryParam params[] = {
      34           39 :     GNUNET_PQ_query_param_auto_from_type (wch),
      35              :     GNUNET_PQ_query_param_end
      36              :   };
      37           39 :   struct TALER_BlindedDenominationSignature *my_denom_sigs = NULL;
      38           39 :   uint64_t *my_denom_serials = NULL;
      39           39 :   struct GNUNET_CRYPTO_CSPublicRPairP *my_cs_r_values = NULL;
      40           39 :   size_t num_sigs = 0;
      41           39 :   size_t num_coins = 0;
      42           39 :   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           39 :   struct GNUNET_PQ_ResultSpec rs[] = {
      51           39 :     GNUNET_PQ_result_spec_uint64 ("withdraw_id",
      52              :                                   &wd->withdraw_id),
      53           39 :     GNUNET_PQ_result_spec_auto_from_type ("planchets_h",
      54              :                                           &wd->planchets_h),
      55           39 :     GNUNET_PQ_result_spec_auto_from_type ("reserve_sig",
      56              :                                           &wd->reserve_sig),
      57           39 :     GNUNET_PQ_result_spec_auto_from_type ("reserve_pub",
      58              :                                           &wd->reserve_pub),
      59           39 :     GNUNET_PQ_result_spec_allow_null (
      60              :       GNUNET_PQ_result_spec_uint16 ("max_age",
      61              :                                     &wd->max_age),
      62              :       &no_max_age),
      63           39 :     TALER_PQ_result_spec_amount ("amount_with_fee",
      64           39 :                                  pg->currency,
      65              :                                  &wd->amount_with_fee),
      66           39 :     GNUNET_PQ_result_spec_allow_null (
      67              :       GNUNET_PQ_result_spec_uint16 ("noreveal_index",
      68              :                                     &wd->noreveal_index),
      69              :       &no_noreveal_index),
      70           39 :     GNUNET_PQ_result_spec_allow_null (
      71           39 :       GNUNET_PQ_result_spec_auto_from_type ("selected_h",
      72              :                                             &wd->selected_h),
      73              :       &no_selected_h),
      74           39 :     GNUNET_PQ_result_spec_allow_null (
      75           39 :       GNUNET_PQ_result_spec_auto_from_type ("blinding_seed",
      76              :                                             &wd->blinding_seed),
      77              :       &no_blinding_seed),
      78           39 :     GNUNET_PQ_result_spec_allow_null (
      79              :       TALER_PQ_result_spec_array_cs_r_pub (
      80              :         pg->conn,
      81              :         "cs_r_values",
      82              :         &num_cs_r_values,
      83              :         &my_cs_r_values),
      84              :       &no_cs_r_values),
      85           39 :     GNUNET_PQ_result_spec_allow_null (
      86              :       GNUNET_PQ_result_spec_uint64 ("cs_r_choices",
      87              :                                     &wd->cs_r_choices),
      88              :       &no_cs_r_choices),
      89           39 :     TALER_PQ_result_spec_array_blinded_denom_sig (
      90              :       pg->conn,
      91              :       "denom_sigs",
      92              :       &num_sigs,
      93              :       &my_denom_sigs),
      94           39 :     GNUNET_PQ_result_spec_array_uint64 (
      95              :       pg->conn,
      96              :       "denom_serials",
      97              :       &num_coins,
      98              :       &my_denom_serials),
      99              :     GNUNET_PQ_result_spec_end
     100              :   };
     101              : 
     102           39 :   PREPARE (pg,
     103              :            "get_withdraw",
     104              :            "SELECT"
     105              :            " withdraw_id"
     106              :            ",planchets_h"
     107              :            ",blinding_seed"
     108              :            ",reserve_sig"
     109              :            ",reserve_pub"
     110              :            ",max_age"
     111              :            ",amount_with_fee"
     112              :            ",noreveal_index"
     113              :            ",selected_h"
     114              :            ",blinding_seed"
     115              :            ",cs_r_values"
     116              :            ",cs_r_choices"
     117              :            ",denom_sigs"
     118              :            ",denom_serials"
     119              :            " FROM withdraw"
     120              :            " WHERE planchets_h=$1;");
     121           39 :   ret = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
     122              :                                                   "get_withdraw",
     123              :                                                   params,
     124              :                                                   rs);
     125           39 :   if (0 > ret)
     126              :   {
     127            0 :     GNUNET_break (0);
     128            0 :     GNUNET_PQ_cleanup_result (rs);
     129            0 :     return ret;
     130              :   }
     131           39 :   if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == ret)
     132              :   {
     133           13 :     GNUNET_PQ_cleanup_result (rs);
     134           13 :     return ret;
     135              :   }
     136              : 
     137           26 :   if ((no_max_age != no_noreveal_index) ||
     138           26 :       (no_max_age != no_selected_h))
     139              :   {
     140            0 :     GNUNET_break (0);
     141            0 :     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     142              :                 "got inconsistent state for max_age, noreveal_index and planchets_h in DB: "
     143              :                 "no_max_age=%s, no_noreveal_index=%s, no_selected_h=%s\n",
     144              :                 no_max_age ? "true" : "false",
     145              :                 no_noreveal_index ? "true" : "false",
     146              :                 no_selected_h ? "true" : "false");
     147            0 :     GNUNET_PQ_cleanup_result (rs);
     148            0 :     return GNUNET_DB_STATUS_HARD_ERROR;
     149              :   }
     150           26 :   if (no_blinding_seed != no_cs_r_values)
     151              :   {
     152            0 :     GNUNET_break (0);
     153            0 :     GNUNET_PQ_cleanup_result (rs);
     154            0 :     return GNUNET_DB_STATUS_HARD_ERROR;
     155              :   }
     156           26 :   if (no_cs_r_choices != no_cs_r_values)
     157              :   {
     158            0 :     GNUNET_break (0);
     159            0 :     GNUNET_PQ_cleanup_result (rs);
     160            0 :     return GNUNET_DB_STATUS_HARD_ERROR;
     161              :   }
     162           26 :   if (num_coins != num_sigs)
     163              :   {
     164            0 :     GNUNET_break (0);
     165            0 :     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     166              :                 "got inconsistent number of entries in withdraw from DB: "
     167              :                 "num_coins=%ld, num_sigs=%ld\n",
     168              :                 num_coins,
     169              :                 num_sigs);
     170            0 :     GNUNET_PQ_cleanup_result (rs);
     171            0 :     return GNUNET_DB_STATUS_HARD_ERROR;
     172              :   }
     173           26 :   wd->age_proof_required = ! no_max_age;
     174           26 :   if (no_cs_r_values)
     175              :   {
     176           13 :     wd->cs_r_values = NULL;
     177           13 :     wd->num_cs_r_values = 0;
     178           13 :     wd->cs_r_choices = 0;
     179              :   }
     180           26 :   wd->denom_sigs = my_denom_sigs;
     181           26 :   wd->num_coins = num_coins;
     182           26 :   wd->denom_serials = my_denom_serials;
     183           26 :   wd->cs_r_values = my_cs_r_values;
     184           26 :   wd->num_cs_r_values = num_cs_r_values;
     185              :   /* ensure cleanup_result does not trash data we care about */
     186           26 :   my_denom_sigs = NULL;
     187           26 :   my_denom_serials = NULL;
     188           26 :   my_cs_r_values = NULL;
     189           26 :   num_sigs = 0;
     190           26 :   num_coins = 0;
     191           26 :   num_cs_r_values = 0;
     192           26 :   GNUNET_PQ_cleanup_result (rs);
     193           26 :   return ret;
     194              : }
        

Generated by: LCOV version 2.0-1