exchange

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

select_withdrawals_above_serial_id.c (6716B)


      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/select_withdrawals_above_serial_id.c
     18  * @brief Implementation of the select_withdrawals_above_serial_id function for Postgres
     19  * @author Christian Grothoff
     20  * @author Özgür Kesim
     21  */
     22 #include "taler/taler_pq_lib.h"
     23 #include "exchange-database/select_withdrawals_above_serial_id.h"
     24 #include "helper.h"
     25 
     26 /**
     27  * Closure for #withdraw_serial_helper_cb().
     28  */
     29 struct WithdrawSerialContext
     30 {
     31 
     32   /**
     33    * Callback to call.
     34    */
     35   TALER_EXCHANGEDB_WithdrawCallback cb;
     36 
     37   /**
     38    * Closure for @e cb.
     39    */
     40   void *cb_cls;
     41 
     42   /**
     43    * Plugin context.
     44    */
     45   struct TALER_EXCHANGEDB_PostgresContext *pg;
     46 
     47   /**
     48    * Status code, set to #GNUNET_SYSERR on hard errors.
     49    */
     50   enum GNUNET_GenericReturnValue status;
     51 };
     52 
     53 
     54 /**
     55  * Helper function to be called with the results of a SELECT statement
     56  * that has returned @a num_results results.
     57  *
     58  * @param cls closure of type `struct WithdrawSerialContext`
     59  * @param result the postgres result
     60  * @param num_results the number of results in @a result
     61  */
     62 static void
     63 withdraw_serial_helper_cb (void *cls,
     64                            PGresult *result,
     65                            unsigned int num_results)
     66 {
     67   struct WithdrawSerialContext *rosc = cls;
     68   struct TALER_EXCHANGEDB_PostgresContext *pg = rosc->pg;
     69 
     70   for (unsigned int i = 0; i<num_results; i++)
     71   {
     72     uint64_t rowid;
     73     struct TALER_HashBlindedPlanchetsP h_planchets;
     74     struct GNUNET_TIME_Timestamp execution_date;
     75     struct TALER_Amount amount_with_fee;
     76     struct TALER_ReservePublicKeyP reserve_pub;
     77     struct TALER_ReserveSignatureP reserve_sig;
     78     uint16_t max_age;
     79     bool no_max_age;
     80     uint16_t noreveal_index;
     81     bool no_noreveal_index;
     82     struct TALER_HashBlindedPlanchetsP selected_h;
     83     bool no_selected_h;
     84     struct TALER_BlindingMasterSeedP blinding_seed;
     85     bool no_blinding_seed;
     86     size_t num_denom_serials;
     87     uint64_t *denom_serials = NULL;
     88     struct GNUNET_PQ_ResultSpec rs[] = {
     89       GNUNET_PQ_result_spec_uint64 ("withdraw_id",
     90                                     &rowid),
     91       GNUNET_PQ_result_spec_auto_from_type ("planchets_h",
     92                                             &h_planchets),
     93       GNUNET_PQ_result_spec_timestamp ("execution_date",
     94                                        &execution_date),
     95       TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee",
     96                                    &amount_with_fee),
     97       GNUNET_PQ_result_spec_auto_from_type ("reserve_pub",
     98                                             &reserve_pub),
     99       GNUNET_PQ_result_spec_auto_from_type ("reserve_sig",
    100                                             &reserve_sig),
    101       GNUNET_PQ_result_spec_allow_null (
    102         GNUNET_PQ_result_spec_uint16 ("max_age",
    103                                       &max_age),
    104         &no_max_age),
    105       GNUNET_PQ_result_spec_allow_null (
    106         GNUNET_PQ_result_spec_uint16 ("noreveal_index",
    107                                       &noreveal_index),
    108         &no_noreveal_index),
    109       GNUNET_PQ_result_spec_allow_null (
    110         GNUNET_PQ_result_spec_auto_from_type (
    111           "selected_h",
    112           &selected_h),
    113         &no_selected_h),
    114       GNUNET_PQ_result_spec_allow_null (
    115         GNUNET_PQ_result_spec_auto_from_type (
    116           "blinding_seed",
    117           &blinding_seed),
    118         &no_blinding_seed),
    119       GNUNET_PQ_result_spec_array_uint64 (
    120         pg->conn,
    121         "denom_serials",
    122         &num_denom_serials,
    123         &denom_serials),
    124       GNUNET_PQ_result_spec_end
    125     };
    126     enum GNUNET_GenericReturnValue ret;
    127 
    128     if (GNUNET_OK !=
    129         GNUNET_PQ_extract_result (result,
    130                                   rs,
    131                                   i))
    132     {
    133       GNUNET_break (0);
    134       rosc->status = GNUNET_SYSERR;
    135       GNUNET_PQ_cleanup_result (rs);
    136       return;
    137     }
    138     if ((! no_max_age) &&
    139         ((255 <= noreveal_index) || (255 <= max_age)))
    140     {
    141       GNUNET_break (0);
    142       rosc->status = GNUNET_SYSERR;
    143       GNUNET_PQ_cleanup_result (rs);
    144       return;
    145     }
    146     ret = rosc->cb (rosc->cb_cls,
    147                     rowid,
    148                     num_denom_serials,
    149                     denom_serials,
    150                     no_selected_h ? NULL : &selected_h,
    151                     &h_planchets,
    152                     no_blinding_seed ? NULL : &blinding_seed,
    153                     ! no_max_age,
    154                     (uint8_t) max_age,
    155                     (uint8_t) noreveal_index,
    156                     &reserve_pub,
    157                     &reserve_sig,
    158                     execution_date,
    159                     &amount_with_fee);
    160     GNUNET_PQ_cleanup_result (rs);
    161     if (GNUNET_OK != ret)
    162       break;
    163   }
    164 }
    165 
    166 
    167 enum GNUNET_DB_QueryStatus
    168 TALER_EXCHANGEDB_select_withdrawals_above_serial_id (
    169   struct TALER_EXCHANGEDB_PostgresContext *pg,
    170   uint64_t serial_id,
    171   TALER_EXCHANGEDB_WithdrawCallback cb,
    172   void *cb_cls)
    173 {
    174   struct GNUNET_PQ_QueryParam params[] = {
    175     GNUNET_PQ_query_param_uint64 (&serial_id),
    176     GNUNET_PQ_query_param_end
    177   };
    178   struct WithdrawSerialContext rosc = {
    179     .cb = cb,
    180     .cb_cls = cb_cls,
    181     .pg = pg,
    182     .status = GNUNET_OK
    183   };
    184   enum GNUNET_DB_QueryStatus qs;
    185 
    186   /* Fetch deposits with rowid '\geq' the given parameter */
    187   PREPARE (pg,
    188            "audit_get_withdraw_incr",
    189            "SELECT"
    190            " withdraw_id"
    191            ",planchets_h"
    192            ",execution_date"
    193            ",amount_with_fee"
    194            ",reserve_pub"
    195            ",reserve_sig"
    196            ",max_age"
    197            ",noreveal_index"
    198            ",selected_h"
    199            ",blinding_seed"
    200            ",denom_serials"
    201            " FROM withdraw"
    202            " WHERE withdraw_id>=$1"
    203            " ORDER BY withdraw_id ASC;");
    204   qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
    205                                              "audit_get_withdraw_incr",
    206                                              params,
    207                                              &withdraw_serial_helper_cb,
    208                                              &rosc);
    209   if (GNUNET_OK != rosc.status)
    210     return GNUNET_DB_STATUS_HARD_ERROR;
    211   return qs;
    212 }