Line data Source code
1 : /*
2 : This file is part of TALER
3 : Copyright (C) 2022-2024 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_deposit.c
18 : * @brief Implementation of the do_deposit function for Postgres
19 : * @author Christian Grothoff
20 : */
21 : #include "platform.h"
22 : #include "taler_error_codes.h"
23 : #include "taler_dbevents.h"
24 : #include "taler_pq_lib.h"
25 : #include "pg_do_deposit.h"
26 : #include "pg_helper.h"
27 : #include "pg_compute_shard.h"
28 :
29 :
30 : enum GNUNET_DB_QueryStatus
31 122 : TEH_PG_do_deposit (
32 : void *cls,
33 : const struct TALER_EXCHANGEDB_BatchDeposit *bd,
34 : struct GNUNET_TIME_Timestamp *exchange_timestamp,
35 : bool *balance_ok,
36 : uint32_t *bad_balance_index,
37 : bool *ctr_conflict)
38 122 : {
39 122 : struct PostgresClosure *pg = cls;
40 122 : uint64_t deposit_shard = TEH_PG_compute_shard (&bd->merchant_pub);
41 122 : const struct TALER_CoinSpendPublicKeyP *coin_pubs[GNUNET_NZL (bd->num_cdis)];
42 122 : const struct TALER_CoinSpendSignatureP *coin_sigs[GNUNET_NZL (bd->num_cdis)];
43 122 : struct TALER_Amount amounts_with_fee[GNUNET_NZL (bd->num_cdis)];
44 : struct TALER_Amount total_amount;
45 : struct TALER_NormalizedPaytoHashP h_normalized_payto;
46 122 : struct GNUNET_PQ_QueryParam params[] = {
47 : /* data for batch_deposits */
48 122 : GNUNET_PQ_query_param_uint64 (&deposit_shard),
49 122 : GNUNET_PQ_query_param_auto_from_type (&bd->merchant_pub),
50 122 : GNUNET_PQ_query_param_auto_from_type (&bd->merchant_sig),
51 122 : GNUNET_PQ_query_param_timestamp (&bd->wallet_timestamp),
52 122 : GNUNET_PQ_query_param_timestamp (exchange_timestamp),
53 122 : GNUNET_PQ_query_param_timestamp (&bd->refund_deadline),
54 122 : GNUNET_PQ_query_param_timestamp (&bd->wire_deadline),
55 122 : GNUNET_PQ_query_param_auto_from_type (&bd->h_contract_terms),
56 122 : (bd->no_wallet_data_hash)
57 98 : ? GNUNET_PQ_query_param_null ()
58 122 : : GNUNET_PQ_query_param_auto_from_type (&bd->wallet_data_hash),
59 122 : GNUNET_PQ_query_param_auto_from_type (&bd->wire_salt),
60 122 : GNUNET_PQ_query_param_auto_from_type (&bd->wire_target_h_payto),
61 122 : GNUNET_PQ_query_param_auto_from_type (&h_normalized_payto),
62 122 : (0 == bd->policy_details_serial_id)
63 122 : ? GNUNET_PQ_query_param_null ()
64 122 : : GNUNET_PQ_query_param_uint64 (&bd->policy_details_serial_id),
65 122 : GNUNET_PQ_query_param_bool (bd->policy_blocked),
66 : /* to create entry in wire_targets */
67 122 : GNUNET_PQ_query_param_string (bd->receiver_wire_account.full_payto),
68 : /* arrays for coin_deposits */
69 122 : GNUNET_PQ_query_param_array_ptrs_auto_from_type (bd->num_cdis,
70 : coin_pubs,
71 : pg->conn),
72 122 : GNUNET_PQ_query_param_array_ptrs_auto_from_type (bd->num_cdis,
73 : coin_sigs,
74 : pg->conn),
75 122 : TALER_PQ_query_param_array_amount (bd->num_cdis,
76 : amounts_with_fee,
77 : pg->conn),
78 122 : TALER_PQ_query_param_amount (pg->conn,
79 : &total_amount),
80 122 : GNUNET_PQ_query_param_bool (TALER_payto_is_wallet (
81 122 : bd->receiver_wire_account.full_payto)),
82 : GNUNET_PQ_query_param_end
83 : };
84 : bool no_time;
85 122 : struct GNUNET_PQ_ResultSpec rs[] = {
86 122 : GNUNET_PQ_result_spec_allow_null (
87 : GNUNET_PQ_result_spec_timestamp ("exchange_timestamp",
88 : exchange_timestamp),
89 : &no_time),
90 122 : GNUNET_PQ_result_spec_allow_null (
91 : GNUNET_PQ_result_spec_uint32 ("insufficient_balance_coin_index",
92 : bad_balance_index),
93 : balance_ok),
94 122 : GNUNET_PQ_result_spec_bool ("conflicted",
95 : ctr_conflict),
96 : GNUNET_PQ_result_spec_end
97 : };
98 : enum GNUNET_DB_QueryStatus qs;
99 :
100 122 : GNUNET_assert (0 < bd->num_cdis);
101 122 : TALER_full_payto_normalize_and_hash (bd->receiver_wire_account,
102 : &h_normalized_payto);
103 246 : for (unsigned int i = 0; i < bd->num_cdis; i++)
104 : {
105 124 : const struct TALER_EXCHANGEDB_CoinDepositInformation *cdi
106 124 : = &bd->cdis[i];
107 :
108 124 : if (0 == i)
109 : {
110 122 : total_amount = cdi->amount_with_fee;
111 : }
112 : else
113 : {
114 2 : GNUNET_assert (0 <=
115 : TALER_amount_add (&total_amount,
116 : &total_amount,
117 : &cdi->amount_with_fee));
118 : }
119 124 : amounts_with_fee[i] = cdi->amount_with_fee;
120 124 : coin_pubs[i] = &cdi->coin.coin_pub;
121 124 : coin_sigs[i] = &cdi->csig;
122 124 : GNUNET_log (GNUNET_ERROR_TYPE_INFO,
123 : "Do deposit %u = %s\n",
124 : i,
125 : TALER_B2S (&cdi->coin.coin_pub));
126 : }
127 122 : PREPARE (pg,
128 : "call_deposit",
129 : "SELECT "
130 : " out_exchange_timestamp AS exchange_timestamp"
131 : ",out_insufficient_balance_coin_index AS insufficient_balance_coin_index"
132 : ",out_conflict AS conflicted"
133 : " FROM exchange_do_deposit"
134 : " ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20);");
135 122 : qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
136 : "call_deposit",
137 : params,
138 : rs);
139 122 : GNUNET_PQ_cleanup_query_params_closures (params);
140 122 : return qs;
141 : }
|