exchange

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

get_refresh.c (7653B)


      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/get_refresh.c
     18  * @brief Implementation of the get_refresh function for Postgres
     19  * @author get_refresh
     20  */
     21 #include "taler/taler_pq_lib.h"
     22 #include "exchange-database/get_refresh.h"
     23 #include "helper.h"
     24 
     25 
     26 enum GNUNET_DB_QueryStatus
     27 TALER_EXCHANGEDB_get_refresh (
     28   struct TALER_EXCHANGEDB_PostgresContext *pg,
     29   const struct TALER_RefreshCommitmentP *rc,
     30   struct TALER_EXCHANGEDB_Refresh_vDOLDPLUS *refresh)
     31 {
     32   struct GNUNET_PQ_QueryParam params[] = {
     33     GNUNET_PQ_query_param_auto_from_type (rc),
     34     GNUNET_PQ_query_param_end
     35   };
     36   bool no_cs_r_values;
     37   bool no_cs_r_choices;
     38   bool no_transfer_pubs;
     39   size_t num_denom_sigs;
     40   size_t num_transfer_pubs;
     41   struct TALER_BlindedDenominationSignature *denom_sigs = NULL;
     42   struct GNUNET_CRYPTO_CSPublicRPairP *cs_r_values = NULL;
     43   struct TALER_TransferPublicKeyP *transfer_pubs = NULL;
     44   uint64_t *denom_serials = NULL;
     45   struct GNUNET_PQ_ResultSpec rs[] = {
     46     GNUNET_PQ_result_spec_uint64 ("refresh_id",
     47                                   &refresh->refresh_id),
     48     TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee",
     49                                  &refresh->amount_with_fee),
     50     GNUNET_PQ_result_spec_auto_from_type ("old_coin_pub",
     51                                           &refresh->coin.coin_pub),
     52     GNUNET_PQ_result_spec_allow_null (
     53       GNUNET_PQ_result_spec_auto_from_type ("age_commitment_hash",
     54                                             &refresh->coin.h_age_commitment),
     55       &refresh->coin.no_age_commitment),
     56     GNUNET_PQ_result_spec_auto_from_type ("old_coin_sig",
     57                                           &refresh->coin_sig),
     58     GNUNET_PQ_result_spec_auto_from_type ("refresh_seed",
     59                                           &refresh->refresh_seed),
     60     GNUNET_PQ_result_spec_uint32 ("noreveal_index",
     61                                   &refresh->noreveal_index),
     62     GNUNET_PQ_result_spec_allow_null (
     63       GNUNET_PQ_result_spec_auto_from_type ("blinding_seed",
     64                                             &refresh->blinding_seed),
     65       &refresh->no_blinding_seed),
     66     GNUNET_PQ_result_spec_allow_null (
     67       TALER_PQ_result_spec_array_cs_r_pub (pg->conn,
     68                                            "cs_r_values",
     69                                            &refresh->num_cs_r_values,
     70                                            &cs_r_values),
     71       &no_cs_r_values),
     72     GNUNET_PQ_result_spec_allow_null (
     73       GNUNET_PQ_result_spec_uint64 ("cs_r_choices",
     74                                     &refresh->cs_r_choices),
     75       &no_cs_r_choices),
     76     GNUNET_PQ_result_spec_auto_from_type ("planchets_h",
     77                                           &refresh->planchets_h),
     78     GNUNET_PQ_result_spec_auto_from_type ("selected_h",
     79                                           &refresh->selected_h),
     80     GNUNET_PQ_result_spec_allow_null (
     81       GNUNET_PQ_result_spec_array_fixed_size (pg->conn,
     82                                               "transfer_pubs",
     83                                               sizeof(*transfer_pubs),
     84                                               &num_transfer_pubs,
     85                                               (void **) &transfer_pubs),
     86       &no_transfer_pubs),
     87     GNUNET_PQ_result_spec_array_uint64 (pg->conn,
     88                                         "denom_serials",
     89                                         &refresh->num_coins,
     90                                         &denom_serials),
     91     TALER_PQ_result_spec_array_blinded_denom_sig (pg->conn,
     92                                                   "denom_sigs",
     93                                                   &num_denom_sigs,
     94                                                   &denom_sigs),
     95     GNUNET_PQ_result_spec_bool ("revealed",
     96                                 &refresh->revealed),
     97     GNUNET_PQ_result_spec_end
     98   };
     99   enum GNUNET_DB_QueryStatus qs;
    100 
    101   memset (&refresh->coin.denom_sig,
    102           0,
    103           sizeof (refresh->coin.denom_sig));
    104   PREPARE (pg,
    105            "get_refresh",
    106            "SELECT"
    107            " refresh_id"
    108            ",amount_with_fee"
    109            ",old_coin_pub"
    110            ",kc.age_commitment_hash AS age_commitment_hash"
    111            ",old_coin_sig"
    112            ",refresh_seed"
    113            ",noreveal_index"
    114            ",blinding_seed"
    115            ",cs_r_values"
    116            ",cs_r_choices"
    117            ",planchets_h"
    118            ",transfer_pubs"
    119            ",selected_h"
    120            ",denom_serials"
    121            ",denom_sigs"
    122            ",revealed"
    123            " FROM refresh"
    124            " JOIN known_coins kc"
    125            " ON (old_coin_pub = kc.coin_pub)"
    126            " WHERE rc = $1;"
    127            );
    128   qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
    129                                                  "get_refresh",
    130                                                  params,
    131                                                  rs);
    132   GNUNET_PQ_cleanup_query_params_closures (params);
    133   if (0 > qs)
    134   {
    135     GNUNET_break (0);
    136     GNUNET_PQ_cleanup_result (rs);
    137     return qs;
    138   }
    139   if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
    140   {
    141     GNUNET_PQ_cleanup_result (rs);
    142     return qs;
    143   }
    144   if (refresh->num_coins != num_denom_sigs)
    145   {
    146     GNUNET_break (0);
    147     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
    148                 "got inconsistent number of entries in refresh from DB: "
    149                 "num_coins=%ld, num_denom_sigs=%ld\n",
    150                 refresh->num_coins,
    151                 num_denom_sigs);
    152     GNUNET_PQ_cleanup_result (rs);
    153     return GNUNET_DB_STATUS_HARD_ERROR;
    154   }
    155   if (no_transfer_pubs)
    156   {
    157     refresh->is_v27_refresh = true;
    158     refresh->transfer_pubs = NULL;
    159   }
    160   else
    161   {
    162     if (num_transfer_pubs != refresh->num_coins)
    163     {
    164       GNUNET_break (0);
    165       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
    166                   "got inconsistent number of transfer_pubs in refresh from DB: "
    167                   "num_coins=%ld, num_transfer_pubs=%ld\n",
    168                   refresh->num_coins,
    169                   num_transfer_pubs);
    170       GNUNET_PQ_cleanup_result (rs);
    171       return GNUNET_DB_STATUS_HARD_ERROR;
    172     }
    173     refresh->is_v27_refresh = false;
    174     refresh->transfer_pubs = transfer_pubs;
    175   }
    176   if (refresh->no_blinding_seed != no_cs_r_values)
    177   {
    178     GNUNET_break (0);
    179     GNUNET_PQ_cleanup_result (rs);
    180     return GNUNET_DB_STATUS_HARD_ERROR;
    181   }
    182   if (no_cs_r_choices != no_cs_r_values)
    183   {
    184     GNUNET_break (0);
    185     GNUNET_PQ_cleanup_result (rs);
    186     return GNUNET_DB_STATUS_HARD_ERROR;
    187   }
    188   if (no_cs_r_values)
    189   {
    190     refresh->cs_r_values = NULL;
    191     refresh->num_cs_r_values = 0;
    192   }
    193   if (refresh->coin.no_age_commitment)
    194     memset (&refresh->coin.h_age_commitment,
    195             0,
    196             sizeof(refresh->coin.h_age_commitment));
    197   refresh->rc = *rc;
    198   /* move the result arrays */
    199   refresh->denom_sigs = denom_sigs;
    200   refresh->denom_serials = denom_serials;
    201   refresh->cs_r_values = cs_r_values;
    202   transfer_pubs = NULL;
    203   denom_sigs = NULL;
    204   denom_serials = NULL;
    205   cs_r_values = NULL;
    206   GNUNET_PQ_cleanup_result (rs);
    207   return qs;
    208 }