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/pg_do_withdraw.c
18 : * @brief Implementation of the do_withdraw function for Postgres
19 : * @author Özgür Kesim
20 : */
21 : #include "platform.h"
22 : #include "taler_error_codes.h"
23 : #include "taler_dbevents.h"
24 : #include "taler_exchangedb_plugin.h"
25 : #include "taler_pq_lib.h"
26 : #include "pg_do_withdraw.h"
27 : #include "pg_helper.h"
28 : #include <gnunet/gnunet_time_lib.h>
29 :
30 :
31 : enum GNUNET_DB_QueryStatus
32 75 : TEH_PG_do_withdraw (
33 : void *cls,
34 : const struct TALER_EXCHANGEDB_Withdraw *withdraw,
35 : const struct GNUNET_TIME_Timestamp *timestamp,
36 : bool *balance_ok,
37 : struct TALER_Amount *reserve_balance,
38 : bool *age_ok,
39 : uint16_t *required_age,
40 : uint32_t *reserve_birthday,
41 : bool *idempotent,
42 : uint16_t *noreveal_index,
43 : bool *nonce_reuse)
44 : {
45 75 : struct PostgresClosure *pg = cls;
46 : struct GNUNET_TIME_Timestamp gc;
47 75 : struct GNUNET_PQ_QueryParam params[] = {
48 75 : TALER_PQ_query_param_amount (pg->conn,
49 : &withdraw->amount_with_fee),
50 75 : GNUNET_PQ_query_param_auto_from_type (&withdraw->reserve_pub),
51 75 : GNUNET_PQ_query_param_auto_from_type (&withdraw->reserve_sig),
52 75 : GNUNET_PQ_query_param_timestamp (timestamp),
53 75 : GNUNET_PQ_query_param_timestamp (&gc),
54 75 : GNUNET_PQ_query_param_auto_from_type (&withdraw->planchets_h),
55 75 : (withdraw->age_proof_required)
56 5 : ? GNUNET_PQ_query_param_uint16 (&withdraw->max_age)
57 75 : : GNUNET_PQ_query_param_null (),
58 75 : (withdraw->age_proof_required)
59 5 : ? GNUNET_PQ_query_param_uint16 (&withdraw->noreveal_index)
60 75 : : GNUNET_PQ_query_param_null (),
61 75 : (withdraw->age_proof_required)
62 5 : ? GNUNET_PQ_query_param_auto_from_type (&withdraw->selected_h)
63 75 : : GNUNET_PQ_query_param_null (),
64 75 : GNUNET_PQ_query_param_array_uint64 (withdraw->num_coins,
65 75 : withdraw->denom_serials,
66 : pg->conn),
67 75 : TALER_PQ_query_param_array_blinded_denom_sig (withdraw->num_coins,
68 75 : withdraw->denom_sigs,
69 : pg->conn),
70 75 : (withdraw->no_blinding_seed)
71 41 : ? GNUNET_PQ_query_param_null ()
72 75 : : GNUNET_PQ_query_param_auto_from_type (&withdraw->blinding_seed),
73 75 : (withdraw->no_blinding_seed)
74 41 : ? GNUNET_PQ_query_param_null ()
75 75 : : TALER_PQ_query_param_array_cs_r_pub (withdraw->num_cs_r_values,
76 34 : withdraw->cs_r_values,
77 : pg->conn),
78 75 : (withdraw->no_blinding_seed)
79 41 : ? GNUNET_PQ_query_param_null ()
80 75 : : GNUNET_PQ_query_param_uint64 (&withdraw->cs_r_choices),
81 : GNUNET_PQ_query_param_end
82 : };
83 : bool reserve_found;
84 : bool no_noreveal_index;
85 75 : struct GNUNET_PQ_ResultSpec rs[] = {
86 75 : GNUNET_PQ_result_spec_bool ("out_reserve_found",
87 : &reserve_found),
88 75 : GNUNET_PQ_result_spec_bool ("out_balance_ok",
89 : balance_ok),
90 75 : TALER_PQ_RESULT_SPEC_AMOUNT ("out_reserve_balance",
91 : reserve_balance),
92 75 : GNUNET_PQ_result_spec_bool ("out_age_ok",
93 : age_ok),
94 75 : GNUNET_PQ_result_spec_uint16 ("out_required_age",
95 : required_age),
96 75 : GNUNET_PQ_result_spec_uint32 ("out_reserve_birthday",
97 : reserve_birthday),
98 75 : GNUNET_PQ_result_spec_bool ("out_idempotent",
99 : idempotent),
100 75 : GNUNET_PQ_result_spec_allow_null (
101 : GNUNET_PQ_result_spec_uint16 ("out_noreveal_index",
102 : noreveal_index),
103 : &no_noreveal_index),
104 75 : GNUNET_PQ_result_spec_bool ("out_nonce_reuse",
105 : nonce_reuse),
106 : GNUNET_PQ_result_spec_end
107 : };
108 : enum GNUNET_DB_QueryStatus qs;
109 :
110 75 : GNUNET_assert ((withdraw->no_blinding_seed) ==
111 : (0 == withdraw->num_cs_r_values));
112 :
113 75 : gc = GNUNET_TIME_absolute_to_timestamp (
114 : GNUNET_TIME_absolute_add (timestamp->abs_time,
115 : pg->legal_reserve_expiration_time));
116 75 : PREPARE (pg,
117 : "call_withdraw",
118 : "SELECT "
119 : " out_reserve_found"
120 : ",out_balance_ok"
121 : ",out_reserve_balance"
122 : ",out_age_ok"
123 : ",out_required_age"
124 : ",out_reserve_birthday"
125 : ",out_idempotent"
126 : ",out_noreveal_index"
127 : ",out_nonce_reuse"
128 : " FROM exchange_do_withdraw"
129 : " ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14);");
130 75 : qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
131 : "call_withdraw",
132 : params,
133 : rs);
134 75 : GNUNET_PQ_cleanup_query_params_closures (params);
135 :
136 75 : if (0 > qs)
137 0 : return qs;
138 75 : if (! reserve_found)
139 0 : return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS;
140 75 : if ((withdraw->age_proof_required) &&
141 5 : (idempotent && no_noreveal_index))
142 0 : GNUNET_break (0);
143 75 : return qs;
144 : }
|