exchange

Base system with REST service to issue digital coins, run by the payment service provider
Log | Files | Refs | Submodules | README | LICENSE

pg_get_refresh.c (6333B)


      1 /*
      2    This file is part of TALER
      3    Copyright (C) 2022 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_refresh.c
     18  * @brief Implementation of the get_refresh function for Postgres
     19  * @author get_refresh
     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_refresh.h"
     26 #include "pg_helper.h"
     27 
     28 
     29 enum GNUNET_DB_QueryStatus
     30 TEH_PG_get_refresh (void *cls,
     31                     const struct TALER_RefreshCommitmentP *rc,
     32                     struct TALER_EXCHANGEDB_Refresh_v27 *refresh)
     33 {
     34   struct PostgresClosure *pg = cls;
     35   struct GNUNET_PQ_QueryParam params[] = {
     36     GNUNET_PQ_query_param_auto_from_type (rc),
     37     GNUNET_PQ_query_param_end
     38   };
     39   bool no_cs_r_values;
     40   bool no_cs_r_choices;
     41   size_t num_denom_sigs;
     42   struct TALER_BlindedDenominationSignature *denom_sigs = NULL;
     43   struct GNUNET_CRYPTO_CSPublicRPairP *cs_r_values = NULL;
     44   uint64_t *denom_serials = NULL;
     45   struct GNUNET_PQ_ResultSpec rs[] = {
     46     TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee",
     47                                  &refresh->amount_with_fee),
     48     GNUNET_PQ_result_spec_auto_from_type ("old_coin_pub",
     49                                           &refresh->coin.coin_pub),
     50     GNUNET_PQ_result_spec_allow_null (
     51       GNUNET_PQ_result_spec_auto_from_type ("age_commitment_hash",
     52                                             &refresh->coin.h_age_commitment),
     53       &refresh->coin.no_age_commitment),
     54     GNUNET_PQ_result_spec_auto_from_type ("old_coin_sig",
     55                                           &refresh->coin_sig),
     56     GNUNET_PQ_result_spec_auto_from_type ("refresh_seed",
     57                                           &refresh->refresh_seed),
     58     GNUNET_PQ_result_spec_uint32 ("noreveal_index",
     59                                   &refresh->noreveal_index),
     60     GNUNET_PQ_result_spec_allow_null (
     61       GNUNET_PQ_result_spec_auto_from_type ("blinding_seed",
     62                                             &refresh->blinding_seed),
     63       &refresh->no_blinding_seed),
     64     GNUNET_PQ_result_spec_allow_null (
     65       TALER_PQ_result_spec_array_cs_r_pub (pg->conn,
     66                                            "cs_r_values",
     67                                            &refresh->num_cs_r_values,
     68                                            &cs_r_values),
     69       &no_cs_r_values),
     70     GNUNET_PQ_result_spec_allow_null (
     71       GNUNET_PQ_result_spec_uint64 ("cs_r_choices",
     72                                     &refresh->cs_r_choices),
     73       &no_cs_r_choices),
     74     GNUNET_PQ_result_spec_auto_from_type ("planchets_h",
     75                                           &refresh->planchets_h),
     76     GNUNET_PQ_result_spec_auto_from_type ("selected_h",
     77                                           &refresh->selected_h),
     78     GNUNET_PQ_result_spec_array_uint64 (pg->conn,
     79                                         "denom_serials",
     80                                         &refresh->num_coins,
     81                                         &denom_serials),
     82     TALER_PQ_result_spec_array_blinded_denom_sig (pg->conn,
     83                                                   "denom_sigs",
     84                                                   &num_denom_sigs,
     85                                                   &denom_sigs),
     86     GNUNET_PQ_result_spec_end
     87   };
     88   enum GNUNET_DB_QueryStatus qs;
     89 
     90   memset (&refresh->coin.denom_sig,
     91           0,
     92           sizeof (refresh->coin.denom_sig));
     93   PREPARE (pg,
     94            "get_refresh",
     95            "SELECT"
     96            " amount_with_fee"
     97            ",old_coin_pub"
     98            ",kc.age_commitment_hash AS age_commitment_hash"
     99            ",old_coin_sig"
    100            ",refresh_seed"
    101            ",noreveal_index"
    102            ",blinding_seed"
    103            ",cs_r_values"
    104            ",cs_r_choices"
    105            ",planchets_h"
    106            ",selected_h"
    107            ",denom_serials"
    108            ",denom_sigs"
    109            " FROM refresh"
    110            " JOIN known_coins kc"
    111            " ON (old_coin_pub = kc.coin_pub)"
    112            " WHERE rc = $1;"
    113            );
    114   qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
    115                                                  "get_refresh",
    116                                                  params,
    117                                                  rs);
    118   GNUNET_PQ_cleanup_query_params_closures (params);
    119   if (0 > qs)
    120   {
    121     GNUNET_break (0);
    122     GNUNET_PQ_cleanup_result (rs);
    123     return qs;
    124   }
    125   if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
    126   {
    127     GNUNET_PQ_cleanup_result (rs);
    128     return qs;
    129   }
    130   if (refresh->num_coins != num_denom_sigs)
    131   {
    132     GNUNET_break (0);
    133     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
    134                 "got inconsistent number of entries in refresh from DB: "
    135                 "num_coins=%ld, num_denom_sigs=%ld\n",
    136                 refresh->num_coins,
    137                 num_denom_sigs);
    138     GNUNET_PQ_cleanup_result (rs);
    139     return GNUNET_DB_STATUS_HARD_ERROR;
    140   }
    141   if (refresh->no_blinding_seed != no_cs_r_values)
    142   {
    143     GNUNET_break (0);
    144     GNUNET_PQ_cleanup_result (rs);
    145     return GNUNET_DB_STATUS_HARD_ERROR;
    146   }
    147   if (no_cs_r_choices != no_cs_r_values)
    148   {
    149     GNUNET_break (0);
    150     GNUNET_PQ_cleanup_result (rs);
    151     return GNUNET_DB_STATUS_HARD_ERROR;
    152   }
    153   if (no_cs_r_values)
    154   {
    155     refresh->cs_r_values = NULL;
    156     refresh->num_cs_r_values = 0;
    157   }
    158   if (refresh->coin.no_age_commitment)
    159     memset (&refresh->coin.h_age_commitment,
    160             0,
    161             sizeof(refresh->coin.h_age_commitment));
    162   refresh->rc = *rc;
    163   /* move the result arrays */
    164   refresh->denom_sigs = denom_sigs;
    165   refresh->denom_serials = denom_serials;
    166   refresh->cs_r_values = cs_r_values;
    167   denom_sigs = NULL;
    168   denom_serials = NULL;
    169   cs_r_values = NULL;
    170   GNUNET_PQ_cleanup_result (rs);
    171   return qs;
    172 }