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

Generated by: LCOV version 2.0-1