exchange

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

pg_select_withdrawals_above_serial_id.c (6764B)


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