LCOV - code coverage report
Current view: top level - exchangedb - pg_get_withdraw.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 55 72 76.4 %
Date: 2025-06-05 21:03:14 Functions: 1 1 100.0 %

          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 "platform.h"
      22             : #include "taler_error_codes.h"
      23             : #include "taler_dbevents.h"
      24             : #include "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 1.16