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