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

Generated by: LCOV version 2.0-1