Line data Source code
1 : /*
2 : This file is part of TALER
3 : Copyright (C) 2023, 2025 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_withdraw.c
18 : * @brief Implementation of the get_withdraw function for Postgres
19 : * @author Özgür Kesim
20 : */
21 : #include "taler/taler_pq_lib.h"
22 : #include "exchange-database/get_withdraw.h"
23 : #include "helper.h"
24 :
25 :
26 : enum GNUNET_DB_QueryStatus
27 10 : TALER_EXCHANGEDB_get_withdraw (
28 : struct TALER_EXCHANGEDB_PostgresContext *pg,
29 : const struct TALER_HashBlindedPlanchetsP *wch,
30 : struct TALER_EXCHANGEDB_Withdraw *wd)
31 : {
32 : enum GNUNET_DB_QueryStatus ret;
33 10 : struct GNUNET_PQ_QueryParam params[] = {
34 10 : GNUNET_PQ_query_param_auto_from_type (wch),
35 : GNUNET_PQ_query_param_end
36 : };
37 10 : struct TALER_BlindedDenominationSignature *my_denom_sigs = NULL;
38 10 : uint64_t *my_denom_serials = NULL;
39 10 : struct GNUNET_CRYPTO_CSPublicRPairP *my_cs_r_values = NULL;
40 10 : size_t num_sigs = 0;
41 10 : size_t num_coins = 0;
42 10 : size_t num_cs_r_values = 0;
43 : bool no_noreveal_index;
44 : bool no_max_age;
45 : bool no_selected_h;
46 : bool no_blinding_seed;
47 : bool no_cs_r_values;
48 : bool no_cs_r_choices;
49 :
50 10 : struct GNUNET_PQ_ResultSpec rs[] = {
51 10 : GNUNET_PQ_result_spec_auto_from_type ("planchets_h",
52 : &wd->planchets_h),
53 10 : GNUNET_PQ_result_spec_auto_from_type ("reserve_sig",
54 : &wd->reserve_sig),
55 10 : GNUNET_PQ_result_spec_auto_from_type ("reserve_pub",
56 : &wd->reserve_pub),
57 10 : GNUNET_PQ_result_spec_allow_null (
58 : GNUNET_PQ_result_spec_uint16 ("max_age",
59 : &wd->max_age),
60 : &no_max_age),
61 10 : TALER_PQ_result_spec_amount ("amount_with_fee",
62 10 : pg->currency,
63 : &wd->amount_with_fee),
64 10 : GNUNET_PQ_result_spec_allow_null (
65 : GNUNET_PQ_result_spec_uint16 ("noreveal_index",
66 : &wd->noreveal_index),
67 : &no_noreveal_index),
68 10 : GNUNET_PQ_result_spec_allow_null (
69 10 : GNUNET_PQ_result_spec_auto_from_type ("selected_h",
70 : &wd->selected_h),
71 : &no_selected_h),
72 10 : GNUNET_PQ_result_spec_allow_null (
73 10 : GNUNET_PQ_result_spec_auto_from_type ("blinding_seed",
74 : &wd->blinding_seed),
75 : &no_blinding_seed),
76 10 : GNUNET_PQ_result_spec_allow_null (
77 : TALER_PQ_result_spec_array_cs_r_pub (
78 : pg->conn,
79 : "cs_r_values",
80 : &num_cs_r_values,
81 : &my_cs_r_values),
82 : &no_cs_r_values),
83 10 : GNUNET_PQ_result_spec_allow_null (
84 : GNUNET_PQ_result_spec_uint64 ("cs_r_choices",
85 : &wd->cs_r_choices),
86 : &no_cs_r_choices),
87 10 : TALER_PQ_result_spec_array_blinded_denom_sig (
88 : pg->conn,
89 : "denom_sigs",
90 : &num_sigs,
91 : &my_denom_sigs),
92 10 : GNUNET_PQ_result_spec_array_uint64 (
93 : pg->conn,
94 : "denom_serials",
95 : &num_coins,
96 : &my_denom_serials),
97 : GNUNET_PQ_result_spec_end
98 : };
99 :
100 10 : PREPARE (pg,
101 : "get_withdraw",
102 : "SELECT"
103 : " planchets_h"
104 : ",blinding_seed"
105 : ",reserve_sig"
106 : ",reserve_pub"
107 : ",max_age"
108 : ",amount_with_fee"
109 : ",noreveal_index"
110 : ",selected_h"
111 : ",blinding_seed"
112 : ",cs_r_values"
113 : ",cs_r_choices"
114 : ",denom_sigs"
115 : ",denom_serials"
116 : " FROM withdraw"
117 : " WHERE planchets_h=$1;");
118 10 : ret = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
119 : "get_withdraw",
120 : params,
121 : rs);
122 10 : if (0 > ret)
123 : {
124 0 : GNUNET_break (0);
125 0 : GNUNET_PQ_cleanup_result (rs);
126 0 : return ret;
127 : }
128 10 : if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == ret)
129 : {
130 7 : GNUNET_PQ_cleanup_result (rs);
131 7 : return ret;
132 : }
133 :
134 3 : if ((no_max_age != no_noreveal_index) ||
135 3 : (no_max_age != no_selected_h))
136 : {
137 0 : GNUNET_break (0);
138 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
139 : "got inconsistent state for max_age, noreveal_index and planchets_h in DB: "
140 : "no_max_age=%s, no_noreveal_index=%s, no_selected_h=%s\n",
141 : no_max_age ? "true" : "false",
142 : no_noreveal_index ? "true" : "false",
143 : no_selected_h ? "true" : "false");
144 0 : GNUNET_PQ_cleanup_result (rs);
145 0 : return GNUNET_DB_STATUS_HARD_ERROR;
146 : }
147 3 : if (no_blinding_seed != no_cs_r_values)
148 : {
149 0 : GNUNET_break (0);
150 0 : GNUNET_PQ_cleanup_result (rs);
151 0 : return GNUNET_DB_STATUS_HARD_ERROR;
152 : }
153 3 : if (no_cs_r_choices != no_cs_r_values)
154 : {
155 0 : GNUNET_break (0);
156 0 : GNUNET_PQ_cleanup_result (rs);
157 0 : return GNUNET_DB_STATUS_HARD_ERROR;
158 : }
159 3 : if (num_coins != num_sigs)
160 : {
161 0 : GNUNET_break (0);
162 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
163 : "got inconsistent number of entries in withdraw from DB: "
164 : "num_coins=%ld, num_sigs=%ld\n",
165 : num_coins,
166 : num_sigs);
167 0 : GNUNET_PQ_cleanup_result (rs);
168 0 : return GNUNET_DB_STATUS_HARD_ERROR;
169 : }
170 3 : wd->age_proof_required = ! no_max_age;
171 3 : if (no_cs_r_values)
172 : {
173 2 : wd->cs_r_values = NULL;
174 2 : wd->num_cs_r_values = 0;
175 2 : wd->cs_r_choices = 0;
176 : }
177 3 : wd->denom_sigs = my_denom_sigs;
178 3 : wd->num_coins = num_coins;
179 3 : wd->denom_serials = my_denom_serials;
180 3 : wd->cs_r_values = my_cs_r_values;
181 3 : wd->num_cs_r_values = num_cs_r_values;
182 : /* ensure cleanup_result does not trash data we care about */
183 3 : my_denom_sigs = NULL;
184 3 : my_denom_serials = NULL;
185 3 : my_cs_r_values = NULL;
186 3 : num_sigs = 0;
187 3 : num_coins = 0;
188 3 : num_cs_r_values = 0;
189 3 : GNUNET_PQ_cleanup_result (rs);
190 3 : return ret;
191 : }
|