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 }