Line data Source code
1 : /*
2 : This file is part of TALER
3 : Copyright (C) 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/do_refresh.c
18 : * @brief Implementation of the do_refresh function for Postgres
19 : * @author Özgür Kesim
20 : */
21 : #include "taler/taler_exchangedb_lib.h"
22 : #include "taler/taler_pq_lib.h"
23 : #include "exchange-database/do_refresh.h"
24 : #include "helper.h"
25 :
26 :
27 : enum GNUNET_DB_QueryStatus
28 29 : TALER_EXCHANGEDB_do_refresh (
29 : struct TALER_EXCHANGEDB_PostgresContext *pg,
30 : struct TALER_EXCHANGEDB_Refresh_vDOLDPLUS *refresh,
31 : const struct GNUNET_TIME_Timestamp *timestamp,
32 : bool *found,
33 : uint32_t *noreveal_index,
34 : bool *zombie_required,
35 : bool *nonce_reuse,
36 : bool *balance_ok,
37 : struct TALER_Amount *coin_balance)
38 : {
39 29 : struct GNUNET_PQ_QueryParam params[] = {
40 29 : GNUNET_PQ_query_param_auto_from_type (&refresh->rc),
41 29 : GNUNET_PQ_query_param_timestamp (timestamp),
42 29 : GNUNET_PQ_query_param_auto_from_type (&refresh->refresh_seed), /* 3 */
43 29 : (refresh->is_v27_refresh)
44 0 : ? GNUNET_PQ_query_param_null ()
45 29 : : GNUNET_PQ_query_param_array_auto_from_type (refresh->num_coins,
46 : refresh->transfer_pubs,
47 : pg->conn),
48 29 : GNUNET_PQ_query_param_auto_from_type (&refresh->planchets_h),
49 29 : TALER_PQ_query_param_amount (pg->conn, /* 6 */
50 29 : &refresh->amount_with_fee),
51 29 : (refresh->no_blinding_seed)
52 14 : ? GNUNET_PQ_query_param_null ()
53 29 : : GNUNET_PQ_query_param_auto_from_type (&refresh->blinding_seed),
54 29 : (0 < refresh->num_cs_r_values)
55 15 : ? TALER_PQ_query_param_array_cs_r_pub (refresh->num_cs_r_values,
56 15 : refresh->cs_r_values,
57 : pg->conn)
58 29 : : GNUNET_PQ_query_param_null (),
59 29 : (0 < refresh->num_cs_r_values)
60 15 : ? GNUNET_PQ_query_param_uint64 (&refresh->cs_r_choices) /* 9 */
61 29 : : GNUNET_PQ_query_param_null (),
62 29 : GNUNET_PQ_query_param_auto_from_type (&refresh->selected_h),
63 29 : TALER_PQ_query_param_array_blinded_denom_sig (refresh->num_coins,
64 29 : refresh->denom_sigs,
65 : pg->conn),
66 29 : GNUNET_PQ_query_param_array_uint64 (refresh->num_coins, /* 12 */
67 29 : refresh->denom_serials,
68 : pg->conn),
69 29 : GNUNET_PQ_query_param_auto_from_type (&refresh->coin.coin_pub),
70 29 : GNUNET_PQ_query_param_auto_from_type (&refresh->coin_sig),
71 29 : GNUNET_PQ_query_param_uint32 (&refresh->noreveal_index), /* 15 */
72 29 : GNUNET_PQ_query_param_bool (*zombie_required),
73 : GNUNET_PQ_query_param_end
74 : };
75 : bool coin_found;
76 : bool no_noreveal_index;
77 : bool no_coin_balance;
78 29 : struct GNUNET_PQ_ResultSpec rs[] = {
79 29 : GNUNET_PQ_result_spec_bool ("coin_found",
80 : &coin_found),
81 29 : GNUNET_PQ_result_spec_bool ("balance_ok",
82 : balance_ok),
83 29 : GNUNET_PQ_result_spec_bool ("zombie_required",
84 : zombie_required),
85 29 : GNUNET_PQ_result_spec_bool ("nonce_reuse",
86 : nonce_reuse),
87 29 : GNUNET_PQ_result_spec_bool ("found",
88 : found),
89 29 : GNUNET_PQ_result_spec_allow_null (
90 : GNUNET_PQ_result_spec_uint32 ("noreveal_index",
91 : noreveal_index),
92 : &no_noreveal_index),
93 29 : GNUNET_PQ_result_spec_allow_null (
94 29 : TALER_PQ_RESULT_SPEC_AMOUNT ("coin_balance",
95 : coin_balance),
96 : &no_coin_balance),
97 : GNUNET_PQ_result_spec_end
98 : };
99 : enum GNUNET_DB_QueryStatus qs;
100 :
101 29 : PREPARE (pg,
102 : "call_refresh",
103 : "SELECT "
104 : " out_coin_found AS coin_found"
105 : ",out_balance_ok AS balance_ok"
106 : ",out_zombie_bad AS zombie_required"
107 : ",out_nonce_reuse AS nonce_reuse"
108 : ",out_idempotent AS found"
109 : ",out_noreveal_index AS noreveal_index"
110 : ",out_coin_balance AS coin_balance"
111 : " FROM exchange_do_refresh"
112 : " ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16);");
113 29 : qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
114 : "call_refresh",
115 : params,
116 : rs);
117 29 : GNUNET_PQ_cleanup_query_params_closures (params);
118 29 : if (0 > qs)
119 : {
120 0 : GNUNET_break (0);
121 0 : return qs;
122 : }
123 29 : if (! coin_found)
124 : {
125 0 : return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS;
126 : }
127 29 : if (*found && no_noreveal_index)
128 : {
129 0 : GNUNET_break (0);
130 0 : return GNUNET_DB_STATUS_HARD_ERROR;
131 : }
132 29 : if (! balance_ok && no_coin_balance)
133 : {
134 0 : GNUNET_break (0);
135 0 : return GNUNET_DB_STATUS_HARD_ERROR;
136 : }
137 29 : return qs;
138 : }
|