Line data Source code
1 : /*
2 : This file is part of TALER
3 : Copyright (C) 2014-2022 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 plugin_auditordb_postgres.c
18 : * @brief Low-level (statement-level) Postgres database access for the auditor
19 : * @author Christian Grothoff
20 : * @author Gabor X Toth
21 : */
22 : #include "platform.h"
23 : #include "taler_pq_lib.h"
24 : #include "taler_auditordb_plugin.h"
25 : #include <pthread.h>
26 : #include <libpq-fe.h>
27 :
28 :
29 : #define LOG(kind,...) GNUNET_log_from (kind, "taler-auditordb-postgres", \
30 : __VA_ARGS__)
31 :
32 :
33 : /**
34 : * Wrapper macro to add the currency from the plugin's state
35 : * when fetching amounts from the database.
36 : *
37 : * @param field name of the database field to fetch amount from
38 : * @param[out] amountp pointer to amount to set
39 : */
40 : #define TALER_PQ_RESULT_SPEC_AMOUNT(field,amountp) \
41 : TALER_PQ_result_spec_amount ( \
42 : field,pg->currency,amountp)
43 :
44 : /**
45 : * Wrapper macro to add the currency from the plugin's state
46 : * when fetching amounts from the database. NBO variant.
47 : *
48 : * @param field name of the database field to fetch amount from
49 : * @param[out] amountp pointer to amount to set
50 : */
51 : #define TALER_PQ_RESULT_SPEC_AMOUNT_NBO(field, \
52 : amountp) TALER_PQ_result_spec_amount_nbo ( \
53 : field,pg->currency,amountp)
54 :
55 :
56 : /**
57 : * Type of the "cls" argument given to each of the functions in
58 : * our API.
59 : */
60 : struct PostgresClosure
61 : {
62 :
63 : /**
64 : * Postgres connection handle.
65 : */
66 : struct GNUNET_PQ_Context *conn;
67 :
68 : /**
69 : * Name of the ongoing transaction, used to debug cases where
70 : * a transaction is not properly terminated via COMMIT or
71 : * ROLLBACK.
72 : */
73 : const char *transaction_name;
74 :
75 : /**
76 : * Our configuration.
77 : */
78 : const struct GNUNET_CONFIGURATION_Handle *cfg;
79 :
80 : /**
81 : * Which currency should we assume all amounts to be in?
82 : */
83 : char *currency;
84 : };
85 :
86 :
87 : /**
88 : * Drop all auditor tables OR deletes recoverable auditor state.
89 : * This should only be used by testcases or when restarting the
90 : * auditor from scratch.
91 : *
92 : * @param cls the `struct PostgresClosure` with the plugin-specific state
93 : * @param drop_exchangelist drop all tables, including schema versioning
94 : * and the exchange and deposit_confirmations table; NOT to be
95 : * used when restarting the auditor
96 : * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure
97 : */
98 : static enum GNUNET_GenericReturnValue
99 1 : postgres_drop_tables (void *cls,
100 : bool drop_exchangelist)
101 : {
102 1 : struct PostgresClosure *pc = cls;
103 : struct GNUNET_PQ_Context *conn;
104 : enum GNUNET_GenericReturnValue ret;
105 :
106 1 : conn = GNUNET_PQ_connect_with_cfg (pc->cfg,
107 : "auditordb-postgres",
108 : NULL,
109 : NULL,
110 : NULL);
111 1 : if (NULL == conn)
112 1 : return GNUNET_SYSERR;
113 0 : ret = GNUNET_PQ_exec_sql (conn,
114 : (drop_exchangelist) ? "drop" : "restart");
115 0 : GNUNET_PQ_disconnect (conn);
116 0 : return ret;
117 : }
118 :
119 :
120 : /**
121 : * Create the necessary tables if they are not present
122 : *
123 : * @param cls the `struct PostgresClosure` with the plugin-specific state
124 : * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure
125 : */
126 : static enum GNUNET_GenericReturnValue
127 1 : postgres_create_tables (void *cls)
128 : {
129 1 : struct PostgresClosure *pc = cls;
130 : struct GNUNET_PQ_Context *conn;
131 1 : struct GNUNET_PQ_ExecuteStatement es[] = {
132 1 : GNUNET_PQ_make_try_execute ("SET search_path TO auditor;"),
133 : GNUNET_PQ_EXECUTE_STATEMENT_END
134 : };
135 :
136 1 : conn = GNUNET_PQ_connect_with_cfg (pc->cfg,
137 : "auditordb-postgres",
138 : "auditor-",
139 : es,
140 : NULL);
141 1 : if (NULL == conn)
142 1 : return GNUNET_SYSERR;
143 0 : GNUNET_PQ_disconnect (conn);
144 0 : return GNUNET_OK;
145 : }
146 :
147 :
148 : /**
149 : * Connect to the db if the connection does not exist yet.
150 : *
151 : * @param[in,out] pg the plugin-specific state
152 : * @return #GNUNET_OK on success
153 : */
154 : static enum GNUNET_GenericReturnValue
155 0 : setup_connection (struct PostgresClosure *pg)
156 : {
157 0 : struct GNUNET_PQ_PreparedStatement ps[] = {
158 : /* used in #postgres_commit */
159 0 : GNUNET_PQ_make_prepare ("do_commit",
160 : "COMMIT",
161 : 0),
162 : /* used in #postgres_insert_exchange */
163 0 : GNUNET_PQ_make_prepare ("auditor_insert_exchange",
164 : "INSERT INTO auditor_exchanges "
165 : "(master_pub"
166 : ",exchange_url"
167 : ") VALUES ($1,$2);",
168 : 2),
169 : /* used in #postgres_delete_exchange */
170 0 : GNUNET_PQ_make_prepare ("auditor_delete_exchange",
171 : "DELETE"
172 : " FROM auditor_exchanges"
173 : " WHERE master_pub=$1;",
174 : 1),
175 : /* used in #postgres_list_exchanges */
176 0 : GNUNET_PQ_make_prepare ("auditor_list_exchanges",
177 : "SELECT"
178 : " master_pub"
179 : ",exchange_url"
180 : " FROM auditor_exchanges",
181 : 0),
182 : /* used in #postgres_insert_exchange_signkey */
183 0 : GNUNET_PQ_make_prepare ("auditor_insert_exchange_signkey",
184 : "INSERT INTO auditor_exchange_signkeys "
185 : "(master_pub"
186 : ",ep_start"
187 : ",ep_expire"
188 : ",ep_end"
189 : ",exchange_pub"
190 : ",master_sig"
191 : ") VALUES ($1,$2,$3,$4,$5,$6);",
192 : 6),
193 : /* Used in #postgres_insert_deposit_confirmation() */
194 0 : GNUNET_PQ_make_prepare ("auditor_deposit_confirmation_insert",
195 : "INSERT INTO deposit_confirmations "
196 : "(master_pub"
197 : ",h_contract_terms"
198 : ",h_extensions"
199 : ",h_wire"
200 : ",exchange_timestamp"
201 : ",wire_deadline"
202 : ",refund_deadline"
203 : ",amount_without_fee_val"
204 : ",amount_without_fee_frac"
205 : ",coin_pub"
206 : ",merchant_pub"
207 : ",exchange_sig"
208 : ",exchange_pub"
209 : ",master_sig" /* master_sig could be normalized... */
210 : ") VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14);",
211 : 14),
212 : /* Used in #postgres_get_deposit_confirmations() */
213 0 : GNUNET_PQ_make_prepare ("auditor_deposit_confirmation_select",
214 : "SELECT"
215 : " serial_id"
216 : ",h_contract_terms"
217 : ",h_extensions"
218 : ",h_wire"
219 : ",exchange_timestamp"
220 : ",wire_deadline"
221 : ",refund_deadline"
222 : ",amount_without_fee_val"
223 : ",amount_without_fee_frac"
224 : ",coin_pub"
225 : ",merchant_pub"
226 : ",exchange_sig"
227 : ",exchange_pub"
228 : ",master_sig" /* master_sig could be normalized... */
229 : " FROM deposit_confirmations"
230 : " WHERE master_pub=$1"
231 : " AND serial_id>$2",
232 : 2),
233 : /* Used in #postgres_update_auditor_progress_reserve() */
234 0 : GNUNET_PQ_make_prepare ("auditor_progress_update_reserve",
235 : "UPDATE auditor_progress_reserve SET "
236 : " last_reserve_in_serial_id=$1"
237 : ",last_reserve_out_serial_id=$2"
238 : ",last_reserve_recoup_serial_id=$3"
239 : ",last_reserve_close_serial_id=$4"
240 : ",last_purse_merges_serial_id=$5"
241 : ",last_purse_deposits_serial_id=$6"
242 : ",last_account_merges_serial_id=$7"
243 : ",last_history_requests_serial_id=$8"
244 : ",last_close_requests_serial_id=$9"
245 : " WHERE master_pub=$10",
246 : 10),
247 : /* Used in #postgres_get_auditor_progress_reserve() */
248 0 : GNUNET_PQ_make_prepare ("auditor_progress_select_reserve",
249 : "SELECT"
250 : " last_reserve_in_serial_id"
251 : ",last_reserve_out_serial_id"
252 : ",last_reserve_recoup_serial_id"
253 : ",last_reserve_close_serial_id"
254 : ",last_purse_merges_serial_id"
255 : ",last_purse_deposits_serial_id"
256 : ",last_account_merges_serial_id"
257 : ",last_history_requests_serial_id"
258 : ",last_close_requests_serial_id"
259 : " FROM auditor_progress_reserve"
260 : " WHERE master_pub=$1;",
261 : 1),
262 : /* Used in #postgres_insert_auditor_progress_reserve() */
263 0 : GNUNET_PQ_make_prepare ("auditor_progress_insert_reserve",
264 : "INSERT INTO auditor_progress_reserve "
265 : "(master_pub"
266 : ",last_reserve_in_serial_id"
267 : ",last_reserve_out_serial_id"
268 : ",last_reserve_recoup_serial_id"
269 : ",last_reserve_close_serial_id"
270 : ",last_purse_merges_serial_id"
271 : ",last_purse_deposits_serial_id"
272 : ",last_account_merges_serial_id"
273 : ",last_history_requests_serial_id"
274 : ",last_close_requests_serial_id"
275 : ") VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10);",
276 : 10),
277 : /* Used in #postgres_update_auditor_progress_aggregation() */
278 0 : GNUNET_PQ_make_prepare ("auditor_progress_update_aggregation",
279 : "UPDATE auditor_progress_aggregation SET "
280 : " last_wire_out_serial_id=$1"
281 : " WHERE master_pub=$2",
282 : 2),
283 : /* Used in #postgres_get_auditor_progress_aggregation() */
284 0 : GNUNET_PQ_make_prepare ("auditor_progress_select_aggregation",
285 : "SELECT"
286 : " last_wire_out_serial_id"
287 : " FROM auditor_progress_aggregation"
288 : " WHERE master_pub=$1;",
289 : 1),
290 : /* Used in #postgres_insert_auditor_progress_aggregation() */
291 0 : GNUNET_PQ_make_prepare ("auditor_progress_insert_aggregation",
292 : "INSERT INTO auditor_progress_aggregation "
293 : "(master_pub"
294 : ",last_wire_out_serial_id"
295 : ") VALUES ($1,$2);",
296 : 2),
297 : /* Used in #postgres_update_auditor_progress_deposit_confirmation() */
298 0 : GNUNET_PQ_make_prepare ("auditor_progress_update_deposit_confirmation",
299 : "UPDATE auditor_progress_deposit_confirmation SET "
300 : " last_deposit_confirmation_serial_id=$1"
301 : " WHERE master_pub=$2",
302 : 2),
303 : /* Used in #postgres_get_auditor_progress_deposit_confirmation() */
304 0 : GNUNET_PQ_make_prepare ("auditor_progress_select_deposit_confirmation",
305 : "SELECT"
306 : " last_deposit_confirmation_serial_id"
307 : " FROM auditor_progress_deposit_confirmation"
308 : " WHERE master_pub=$1;",
309 : 1),
310 : /* Used in #postgres_insert_auditor_progress_deposit_confirmation() */
311 0 : GNUNET_PQ_make_prepare ("auditor_progress_insert_deposit_confirmation",
312 : "INSERT INTO auditor_progress_deposit_confirmation "
313 : "(master_pub"
314 : ",last_deposit_confirmation_serial_id"
315 : ") VALUES ($1,$2);",
316 : 2),
317 : /* Used in #postgres_update_auditor_progress_coin() */
318 0 : GNUNET_PQ_make_prepare ("auditor_progress_update_coin",
319 : "UPDATE auditor_progress_coin SET "
320 : " last_withdraw_serial_id=$1"
321 : ",last_deposit_serial_id=$2"
322 : ",last_melt_serial_id=$3"
323 : ",last_refund_serial_id=$4"
324 : ",last_recoup_serial_id=$5"
325 : ",last_recoup_refresh_serial_id=$6"
326 : ",last_purse_deposits_serial_id=$7"
327 : ",last_purse_refunds_serial_id=$8"
328 : " WHERE master_pub=$9",
329 : 9),
330 : /* Used in #postgres_get_auditor_progress_coin() */
331 0 : GNUNET_PQ_make_prepare ("auditor_progress_select_coin",
332 : "SELECT"
333 : " last_withdraw_serial_id"
334 : ",last_deposit_serial_id"
335 : ",last_melt_serial_id"
336 : ",last_refund_serial_id"
337 : ",last_recoup_serial_id"
338 : ",last_recoup_refresh_serial_id"
339 : ",last_purse_deposits_serial_id"
340 : ",last_purse_refunds_serial_id"
341 : " FROM auditor_progress_coin"
342 : " WHERE master_pub=$1;",
343 : 1),
344 : /* Used in #postgres_insert_auditor_progress() */
345 0 : GNUNET_PQ_make_prepare ("auditor_progress_insert_coin",
346 : "INSERT INTO auditor_progress_coin "
347 : "(master_pub"
348 : ",last_withdraw_serial_id"
349 : ",last_deposit_serial_id"
350 : ",last_melt_serial_id"
351 : ",last_refund_serial_id"
352 : ",last_recoup_serial_id"
353 : ",last_recoup_refresh_serial_id"
354 : ",last_purse_deposits_serial_id"
355 : ",last_purse_refunds_serial_id"
356 : ") VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9);",
357 : 9),
358 : /* Used in #postgres_insert_wire_auditor_account_progress() */
359 0 : GNUNET_PQ_make_prepare ("wire_auditor_account_progress_insert",
360 : "INSERT INTO wire_auditor_account_progress "
361 : "(master_pub"
362 : ",account_name"
363 : ",last_wire_reserve_in_serial_id"
364 : ",last_wire_wire_out_serial_id"
365 : ",wire_in_off"
366 : ",wire_out_off"
367 : ") VALUES ($1,$2,$3,$4,$5,$6);",
368 : 6),
369 : /* Used in #postgres_update_wire_auditor_account_progress() */
370 0 : GNUNET_PQ_make_prepare ("wire_auditor_account_progress_update",
371 : "UPDATE wire_auditor_account_progress SET "
372 : " last_wire_reserve_in_serial_id=$1"
373 : ",last_wire_wire_out_serial_id=$2"
374 : ",wire_in_off=$3"
375 : ",wire_out_off=$4"
376 : " WHERE master_pub=$5 AND account_name=$6",
377 : 6),
378 : /* Used in #postgres_get_wire_auditor_account_progress() */
379 0 : GNUNET_PQ_make_prepare ("wire_auditor_account_progress_select",
380 : "SELECT"
381 : " last_wire_reserve_in_serial_id"
382 : ",last_wire_wire_out_serial_id"
383 : ",wire_in_off"
384 : ",wire_out_off"
385 : " FROM wire_auditor_account_progress"
386 : " WHERE master_pub=$1 AND account_name=$2;",
387 : 2),
388 : /* Used in #postgres_insert_wire_auditor_progress() */
389 0 : GNUNET_PQ_make_prepare ("wire_auditor_progress_insert",
390 : "INSERT INTO wire_auditor_progress "
391 : "(master_pub"
392 : ",last_timestamp"
393 : ",last_reserve_close_uuid"
394 : ") VALUES ($1,$2,$3);",
395 : 3),
396 : /* Used in #postgres_update_wire_auditor_progress() */
397 0 : GNUNET_PQ_make_prepare ("wire_auditor_progress_update",
398 : "UPDATE wire_auditor_progress SET "
399 : " last_timestamp=$1"
400 : ",last_reserve_close_uuid=$2"
401 : " WHERE master_pub=$3",
402 : 3),
403 : /* Used in #postgres_get_wire_auditor_progress() */
404 0 : GNUNET_PQ_make_prepare ("wire_auditor_progress_select",
405 : "SELECT"
406 : " last_timestamp"
407 : ",last_reserve_close_uuid"
408 : " FROM wire_auditor_progress"
409 : " WHERE master_pub=$1;",
410 : 1),
411 : /* Used in #postgres_insert_reserve_info() */
412 0 : GNUNET_PQ_make_prepare ("auditor_reserves_insert",
413 : "INSERT INTO auditor_reserves "
414 : "(reserve_pub"
415 : ",master_pub"
416 : ",reserve_balance_val"
417 : ",reserve_balance_frac"
418 : ",withdraw_fee_balance_val"
419 : ",withdraw_fee_balance_frac"
420 : ",expiration_date"
421 : ",origin_account"
422 : ") VALUES ($1,$2,$3,$4,$5,$6,$7,$8);",
423 : 8),
424 : /* Used in #postgres_update_reserve_info() */
425 0 : GNUNET_PQ_make_prepare ("auditor_reserves_update",
426 : "UPDATE auditor_reserves SET"
427 : " reserve_balance_val=$1"
428 : ",reserve_balance_frac=$2"
429 : ",withdraw_fee_balance_val=$3"
430 : ",withdraw_fee_balance_frac=$4"
431 : ",expiration_date=$5"
432 : " WHERE reserve_pub=$6 AND master_pub=$7;",
433 : 7),
434 : /* Used in #postgres_get_reserve_info() */
435 0 : GNUNET_PQ_make_prepare ("auditor_reserves_select",
436 : "SELECT"
437 : " reserve_balance_val"
438 : ",reserve_balance_frac"
439 : ",withdraw_fee_balance_val"
440 : ",withdraw_fee_balance_frac"
441 : ",expiration_date"
442 : ",auditor_reserves_rowid"
443 : ",origin_account"
444 : " FROM auditor_reserves"
445 : " WHERE reserve_pub=$1 AND master_pub=$2;",
446 : 2),
447 : /* Used in #postgres_del_reserve_info() */
448 0 : GNUNET_PQ_make_prepare ("auditor_reserves_delete",
449 : "DELETE"
450 : " FROM auditor_reserves"
451 : " WHERE reserve_pub=$1 AND master_pub=$2;",
452 : 2),
453 : /* Used in #postgres_insert_reserve_summary() */
454 0 : GNUNET_PQ_make_prepare ("auditor_reserve_balance_insert",
455 : "INSERT INTO auditor_reserve_balance"
456 : "(master_pub"
457 : ",reserve_balance_val"
458 : ",reserve_balance_frac"
459 : ",withdraw_fee_balance_val"
460 : ",withdraw_fee_balance_frac"
461 : ",purse_fee_balance_val"
462 : ",purse_fee_balance_frac"
463 : ",history_fee_balance_val"
464 : ",history_fee_balance_frac"
465 : ") VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9)",
466 : 9),
467 : /* Used in #postgres_update_reserve_summary() */
468 0 : GNUNET_PQ_make_prepare ("auditor_reserve_balance_update",
469 : "UPDATE auditor_reserve_balance SET"
470 : " reserve_balance_val=$1"
471 : ",reserve_balance_frac=$2"
472 : ",withdraw_fee_balance_val=$3"
473 : ",withdraw_fee_balance_frac=$4"
474 : ",purse_fee_balance_val=$5"
475 : ",purse_fee_balance_frac=$6"
476 : ",history_fee_balance_val=$7"
477 : ",history_fee_balance_frac=$8"
478 : " WHERE master_pub=$9;",
479 : 9),
480 : /* Used in #postgres_get_reserve_summary() */
481 0 : GNUNET_PQ_make_prepare ("auditor_reserve_balance_select",
482 : "SELECT"
483 : " reserve_balance_val"
484 : ",reserve_balance_frac"
485 : ",withdraw_fee_balance_val"
486 : ",withdraw_fee_balance_frac"
487 : ",purse_fee_balance_val"
488 : ",purse_fee_balance_frac"
489 : ",history_fee_balance_val"
490 : ",history_fee_balance_frac"
491 : " FROM auditor_reserve_balance"
492 : " WHERE master_pub=$1;",
493 : 1),
494 : /* Used in #postgres_insert_wire_fee_summary() */
495 0 : GNUNET_PQ_make_prepare ("auditor_wire_fee_balance_insert",
496 : "INSERT INTO auditor_wire_fee_balance"
497 : "(master_pub"
498 : ",wire_fee_balance_val"
499 : ",wire_fee_balance_frac"
500 : ") VALUES ($1,$2,$3)",
501 : 3),
502 : /* Used in #postgres_update_wire_fee_summary() */
503 0 : GNUNET_PQ_make_prepare ("auditor_wire_fee_balance_update",
504 : "UPDATE auditor_wire_fee_balance SET"
505 : " wire_fee_balance_val=$1"
506 : ",wire_fee_balance_frac=$2"
507 : " WHERE master_pub=$3;",
508 : 3),
509 : /* Used in #postgres_get_wire_fee_summary() */
510 0 : GNUNET_PQ_make_prepare ("auditor_wire_fee_balance_select",
511 : "SELECT"
512 : " wire_fee_balance_val"
513 : ",wire_fee_balance_frac"
514 : " FROM auditor_wire_fee_balance"
515 : " WHERE master_pub=$1;",
516 : 1),
517 : /* Used in #postgres_insert_denomination_balance() */
518 0 : GNUNET_PQ_make_prepare ("auditor_denomination_pending_insert",
519 : "INSERT INTO auditor_denomination_pending "
520 : "(denom_pub_hash"
521 : ",denom_balance_val"
522 : ",denom_balance_frac"
523 : ",denom_loss_val"
524 : ",denom_loss_frac"
525 : ",num_issued"
526 : ",denom_risk_val"
527 : ",denom_risk_frac"
528 : ",recoup_loss_val"
529 : ",recoup_loss_frac"
530 : ") VALUES ("
531 : "$1,$2,$3,$4,$5,$6,$7,$8,$9,$10"
532 : ");",
533 : 10),
534 : /* Used in #postgres_update_denomination_balance() */
535 0 : GNUNET_PQ_make_prepare ("auditor_denomination_pending_update",
536 : "UPDATE auditor_denomination_pending SET"
537 : " denom_balance_val=$1"
538 : ",denom_balance_frac=$2"
539 : ",denom_loss_val=$3"
540 : ",denom_loss_frac=$4"
541 : ",num_issued=$5"
542 : ",denom_risk_val=$6"
543 : ",denom_risk_frac=$7"
544 : ",recoup_loss_val=$8"
545 : ",recoup_loss_frac=$9"
546 : " WHERE denom_pub_hash=$10",
547 : 10),
548 : /* Used in #postgres_get_denomination_balance() */
549 0 : GNUNET_PQ_make_prepare ("auditor_denomination_pending_select",
550 : "SELECT"
551 : " denom_balance_val"
552 : ",denom_balance_frac"
553 : ",denom_loss_val"
554 : ",denom_loss_frac"
555 : ",num_issued"
556 : ",denom_risk_val"
557 : ",denom_risk_frac"
558 : ",recoup_loss_val"
559 : ",recoup_loss_frac"
560 : " FROM auditor_denomination_pending"
561 : " WHERE denom_pub_hash=$1",
562 : 1),
563 : /* Used in #postgres_insert_balance_summary() */
564 0 : GNUNET_PQ_make_prepare ("auditor_balance_summary_insert",
565 : "INSERT INTO auditor_balance_summary "
566 : "(master_pub"
567 : ",denom_balance_val"
568 : ",denom_balance_frac"
569 : ",deposit_fee_balance_val"
570 : ",deposit_fee_balance_frac"
571 : ",melt_fee_balance_val"
572 : ",melt_fee_balance_frac"
573 : ",refund_fee_balance_val"
574 : ",refund_fee_balance_frac"
575 : ",risk_val"
576 : ",risk_frac"
577 : ",loss_val"
578 : ",loss_frac"
579 : ",irregular_recoup_val"
580 : ",irregular_recoup_frac"
581 : ") VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,"
582 : " $11,$12,$13,$14,$15);",
583 : 15),
584 : /* Used in #postgres_update_balance_summary() */
585 0 : GNUNET_PQ_make_prepare ("auditor_balance_summary_update",
586 : "UPDATE auditor_balance_summary SET"
587 : " denom_balance_val=$1"
588 : ",denom_balance_frac=$2"
589 : ",deposit_fee_balance_val=$3"
590 : ",deposit_fee_balance_frac=$4"
591 : ",melt_fee_balance_val=$5"
592 : ",melt_fee_balance_frac=$6"
593 : ",refund_fee_balance_val=$7"
594 : ",refund_fee_balance_frac=$8"
595 : ",risk_val=$9"
596 : ",risk_frac=$10"
597 : ",loss_val=$11"
598 : ",loss_frac=$12"
599 : ",irregular_recoup_val=$13"
600 : ",irregular_recoup_frac=$14"
601 : " WHERE master_pub=$15;",
602 : 15),
603 : /* Used in #postgres_get_balance_summary() */
604 0 : GNUNET_PQ_make_prepare ("auditor_balance_summary_select",
605 : "SELECT"
606 : " denom_balance_val"
607 : ",denom_balance_frac"
608 : ",deposit_fee_balance_val"
609 : ",deposit_fee_balance_frac"
610 : ",melt_fee_balance_val"
611 : ",melt_fee_balance_frac"
612 : ",refund_fee_balance_val"
613 : ",refund_fee_balance_frac"
614 : ",risk_val"
615 : ",risk_frac"
616 : ",loss_val"
617 : ",loss_frac"
618 : ",irregular_recoup_val"
619 : ",irregular_recoup_frac"
620 : " FROM auditor_balance_summary"
621 : " WHERE master_pub=$1;",
622 : 1),
623 : /* Used in #postgres_insert_historic_denom_revenue() */
624 0 : GNUNET_PQ_make_prepare ("auditor_historic_denomination_revenue_insert",
625 : "INSERT INTO auditor_historic_denomination_revenue"
626 : "(master_pub"
627 : ",denom_pub_hash"
628 : ",revenue_timestamp"
629 : ",revenue_balance_val"
630 : ",revenue_balance_frac"
631 : ",loss_balance_val"
632 : ",loss_balance_frac"
633 : ") VALUES ($1,$2,$3,$4,$5,$6,$7);",
634 : 7),
635 : /* Used in #postgres_select_historic_denom_revenue() */
636 0 : GNUNET_PQ_make_prepare ("auditor_historic_denomination_revenue_select",
637 : "SELECT"
638 : " denom_pub_hash"
639 : ",revenue_timestamp"
640 : ",revenue_balance_val"
641 : ",revenue_balance_frac"
642 : ",loss_balance_val"
643 : ",loss_balance_frac"
644 : " FROM auditor_historic_denomination_revenue"
645 : " WHERE master_pub=$1;",
646 : 1),
647 : /* Used in #postgres_insert_historic_reserve_revenue() */
648 0 : GNUNET_PQ_make_prepare ("auditor_historic_reserve_summary_insert",
649 : "INSERT INTO auditor_historic_reserve_summary"
650 : "(master_pub"
651 : ",start_date"
652 : ",end_date"
653 : ",reserve_profits_val"
654 : ",reserve_profits_frac"
655 : ") VALUES ($1,$2,$3,$4,$5);",
656 : 5),
657 : /* Used in #postgres_select_historic_reserve_revenue() */
658 0 : GNUNET_PQ_make_prepare ("auditor_historic_reserve_summary_select",
659 : "SELECT"
660 : " start_date"
661 : ",end_date"
662 : ",reserve_profits_val"
663 : ",reserve_profits_frac"
664 : " FROM auditor_historic_reserve_summary"
665 : " WHERE master_pub=$1;",
666 : 1),
667 : /* Used in #postgres_insert_predicted_result() */
668 0 : GNUNET_PQ_make_prepare ("auditor_predicted_result_insert",
669 : "INSERT INTO auditor_predicted_result"
670 : "(master_pub"
671 : ",balance_val"
672 : ",balance_frac"
673 : ",drained_val"
674 : ",drained_frac"
675 : ") VALUES ($1,$2,$3,$4,$5);",
676 : 5),
677 : /* Used in #postgres_update_predicted_result() */
678 0 : GNUNET_PQ_make_prepare ("auditor_predicted_result_update",
679 : "UPDATE auditor_predicted_result SET"
680 : " balance_val=$1"
681 : ",balance_frac=$2"
682 : ",drained_val=$3"
683 : ",drained_frac=$4"
684 : " WHERE master_pub=$5;",
685 : 5),
686 : /* Used in #postgres_get_predicted_balance() */
687 0 : GNUNET_PQ_make_prepare ("auditor_predicted_result_select",
688 : "SELECT"
689 : " balance_val"
690 : ",balance_frac"
691 : ",drained_val"
692 : ",drained_frac"
693 : " FROM auditor_predicted_result"
694 : " WHERE master_pub=$1;",
695 : 1),
696 : GNUNET_PQ_PREPARED_STATEMENT_END
697 : };
698 0 : struct GNUNET_PQ_ExecuteStatement es[] = {
699 0 : GNUNET_PQ_make_try_execute ("SET search_path TO auditor;"),
700 : GNUNET_PQ_EXECUTE_STATEMENT_END
701 : };
702 : struct GNUNET_PQ_Context *db_conn;
703 :
704 0 : if (NULL != pg->conn)
705 : {
706 0 : GNUNET_PQ_reconnect_if_down (pg->conn);
707 0 : return GNUNET_OK;
708 : }
709 0 : db_conn = GNUNET_PQ_connect_with_cfg (pg->cfg,
710 : "auditordb-postgres",
711 : NULL,
712 : es,
713 : ps);
714 0 : if (NULL == db_conn)
715 0 : return GNUNET_SYSERR;
716 0 : pg->conn = db_conn;
717 0 : return GNUNET_OK;
718 : }
719 :
720 :
721 : /**
722 : * Do a pre-flight check that we are not in an uncommitted transaction.
723 : * If we are, rollback the previous transaction and output a warning.
724 : *
725 : * @param cls the `struct PostgresClosure` with the plugin-specific state
726 : * @return #GNUNET_OK on success,
727 : * #GNUNET_NO if we rolled back an earlier transaction
728 : * #GNUNET_SYSERR if we have no DB connection
729 : */
730 : static enum GNUNET_GenericReturnValue
731 0 : postgres_preflight (void *cls)
732 : {
733 0 : struct PostgresClosure *pg = cls;
734 0 : struct GNUNET_PQ_ExecuteStatement es[] = {
735 0 : GNUNET_PQ_make_execute ("ROLLBACK"),
736 : GNUNET_PQ_EXECUTE_STATEMENT_END
737 : };
738 :
739 0 : if (NULL == pg->conn)
740 : {
741 0 : if (GNUNET_OK !=
742 0 : setup_connection (pg))
743 : {
744 0 : GNUNET_break (0);
745 0 : return GNUNET_SYSERR;
746 : }
747 : }
748 0 : if (NULL == pg->transaction_name)
749 0 : return GNUNET_OK; /* all good */
750 0 : if (GNUNET_OK ==
751 0 : GNUNET_PQ_exec_statements (pg->conn,
752 : es))
753 : {
754 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
755 : "BUG: Preflight check rolled back transaction `%s'!\n",
756 : pg->transaction_name);
757 : }
758 : else
759 : {
760 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
761 : "BUG: Preflight check failed to rollback transaction `%s'!\n",
762 : pg->transaction_name);
763 : }
764 0 : pg->transaction_name = NULL;
765 0 : return GNUNET_NO;
766 : }
767 :
768 :
769 : /**
770 : * Start a transaction.
771 : *
772 : * @param cls the `struct PostgresClosure` with the plugin-specific state
773 : * @return #GNUNET_OK on success
774 : */
775 : static enum GNUNET_GenericReturnValue
776 0 : postgres_start (void *cls)
777 : {
778 0 : struct PostgresClosure *pg = cls;
779 0 : struct GNUNET_PQ_ExecuteStatement es[] = {
780 0 : GNUNET_PQ_make_execute ("START TRANSACTION ISOLATION LEVEL SERIALIZABLE"),
781 : GNUNET_PQ_EXECUTE_STATEMENT_END
782 : };
783 :
784 0 : postgres_preflight (cls);
785 0 : if (GNUNET_OK !=
786 0 : GNUNET_PQ_exec_statements (pg->conn,
787 : es))
788 : {
789 0 : TALER_LOG_ERROR ("Failed to start transaction\n");
790 0 : GNUNET_break (0);
791 0 : return GNUNET_SYSERR;
792 : }
793 0 : return GNUNET_OK;
794 : }
795 :
796 :
797 : /**
798 : * Roll back the current transaction of a database connection.
799 : *
800 : * @param cls the `struct PostgresClosure` with the plugin-specific state
801 : */
802 : static void
803 0 : postgres_rollback (void *cls)
804 : {
805 0 : struct PostgresClosure *pg = cls;
806 0 : struct GNUNET_PQ_ExecuteStatement es[] = {
807 0 : GNUNET_PQ_make_execute ("ROLLBACK"),
808 : GNUNET_PQ_EXECUTE_STATEMENT_END
809 : };
810 :
811 0 : GNUNET_break (GNUNET_OK ==
812 : GNUNET_PQ_exec_statements (pg->conn,
813 : es));
814 0 : }
815 :
816 :
817 : /**
818 : * Commit the current transaction of a database connection.
819 : *
820 : * @param cls the `struct PostgresClosure` with the plugin-specific state
821 : * @return transaction status code
822 : */
823 : enum GNUNET_DB_QueryStatus
824 0 : postgres_commit (void *cls)
825 : {
826 0 : struct PostgresClosure *pg = cls;
827 0 : struct GNUNET_PQ_QueryParam params[] = {
828 : GNUNET_PQ_query_param_end
829 : };
830 :
831 0 : return GNUNET_PQ_eval_prepared_non_select (pg->conn,
832 : "do_commit",
833 : params);
834 : }
835 :
836 :
837 : /**
838 : * Function called to perform "garbage collection" on the
839 : * database, expiring records we no longer require.
840 : *
841 : * @param cls closure
842 : * @return #GNUNET_OK on success,
843 : * #GNUNET_SYSERR on DB errors
844 : */
845 : static enum GNUNET_GenericReturnValue
846 0 : postgres_gc (void *cls)
847 : {
848 0 : struct PostgresClosure *pg = cls;
849 0 : struct GNUNET_TIME_Absolute now = {0};
850 0 : struct GNUNET_PQ_QueryParam params_time[] = {
851 0 : GNUNET_PQ_query_param_absolute_time (&now),
852 : GNUNET_PQ_query_param_end
853 : };
854 : struct GNUNET_PQ_Context *conn;
855 : enum GNUNET_DB_QueryStatus qs;
856 0 : struct GNUNET_PQ_PreparedStatement ps[] = {
857 : #if 0
858 : GNUNET_PQ_make_prepare ("gc_auditor",
859 : "TODO: #4960",
860 : 0),
861 : #endif
862 : GNUNET_PQ_PREPARED_STATEMENT_END
863 : };
864 0 : struct GNUNET_PQ_ExecuteStatement es[] = {
865 0 : GNUNET_PQ_make_try_execute ("SET search_path TO auditor;"),
866 : GNUNET_PQ_EXECUTE_STATEMENT_END
867 : };
868 :
869 0 : now = GNUNET_TIME_absolute_get ();
870 0 : conn = GNUNET_PQ_connect_with_cfg (pg->cfg,
871 : "auditordb-postgres",
872 : NULL,
873 : es,
874 : ps);
875 0 : if (NULL == conn)
876 0 : return GNUNET_SYSERR;
877 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
878 : "TODO: Auditor GC not implemented (#4960)\n");
879 0 : qs = GNUNET_PQ_eval_prepared_non_select (conn,
880 : "gc_auditor",
881 : params_time);
882 0 : GNUNET_PQ_disconnect (conn);
883 0 : if (0 > qs)
884 : {
885 0 : GNUNET_break (0);
886 0 : return GNUNET_SYSERR;
887 : }
888 0 : return GNUNET_OK;
889 : }
890 :
891 :
892 : /**
893 : * Insert information about an exchange this auditor will be auditing.
894 : *
895 : * @param cls the @e cls of this struct with the plugin-specific state
896 : * @param master_pub master public key of the exchange
897 : * @param exchange_url public (base) URL of the API of the exchange
898 : * @return query result status
899 : */
900 : static enum GNUNET_DB_QueryStatus
901 0 : postgres_insert_exchange (void *cls,
902 : const struct TALER_MasterPublicKeyP *master_pub,
903 : const char *exchange_url)
904 : {
905 0 : struct PostgresClosure *pg = cls;
906 0 : struct GNUNET_PQ_QueryParam params[] = {
907 0 : GNUNET_PQ_query_param_auto_from_type (master_pub),
908 0 : GNUNET_PQ_query_param_string (exchange_url),
909 : GNUNET_PQ_query_param_end
910 : };
911 :
912 0 : return GNUNET_PQ_eval_prepared_non_select (pg->conn,
913 : "auditor_insert_exchange",
914 : params);
915 : }
916 :
917 :
918 : /**
919 : * Delete an exchange from the list of exchanges this auditor is auditing.
920 : * Warning: this will cascade and delete all knowledge of this auditor related
921 : * to this exchange!
922 : *
923 : * @param cls the @e cls of this struct with the plugin-specific state
924 : * @param master_pub master public key of the exchange
925 : * @return query result status
926 : */
927 : static enum GNUNET_DB_QueryStatus
928 0 : postgres_delete_exchange (void *cls,
929 : const struct TALER_MasterPublicKeyP *master_pub)
930 : {
931 0 : struct PostgresClosure *pg = cls;
932 0 : struct GNUNET_PQ_QueryParam params[] = {
933 0 : GNUNET_PQ_query_param_auto_from_type (master_pub),
934 : GNUNET_PQ_query_param_end
935 : };
936 :
937 0 : return GNUNET_PQ_eval_prepared_non_select (pg->conn,
938 : "auditor_delete_exchange",
939 : params);
940 : }
941 :
942 :
943 : /**
944 : * Closure for #exchange_info_cb().
945 : */
946 : struct ExchangeInfoContext
947 : {
948 :
949 : /**
950 : * Function to call for each exchange.
951 : */
952 : TALER_AUDITORDB_ExchangeCallback cb;
953 :
954 : /**
955 : * Closure for @e cb
956 : */
957 : void *cb_cls;
958 :
959 : /**
960 : * Query status to return.
961 : */
962 : enum GNUNET_DB_QueryStatus qs;
963 : };
964 :
965 :
966 : /**
967 : * Helper function for #postgres_list_exchanges().
968 : * To be called with the results of a SELECT statement
969 : * that has returned @a num_results results.
970 : *
971 : * @param cls closure of type `struct ExchangeInfoContext *`
972 : * @param result the postgres result
973 : * @param num_results the number of results in @a result
974 : */
975 : static void
976 0 : exchange_info_cb (void *cls,
977 : PGresult *result,
978 : unsigned int num_results)
979 : {
980 0 : struct ExchangeInfoContext *eic = cls;
981 :
982 0 : for (unsigned int i = 0; i < num_results; i++)
983 : {
984 : struct TALER_MasterPublicKeyP master_pub;
985 : char *exchange_url;
986 0 : struct GNUNET_PQ_ResultSpec rs[] = {
987 0 : GNUNET_PQ_result_spec_auto_from_type ("master_pub", &master_pub),
988 0 : GNUNET_PQ_result_spec_string ("exchange_url", &exchange_url),
989 : GNUNET_PQ_result_spec_end
990 : };
991 :
992 0 : if (GNUNET_OK !=
993 0 : GNUNET_PQ_extract_result (result,
994 : rs,
995 : i))
996 : {
997 0 : GNUNET_break (0);
998 0 : eic->qs = GNUNET_DB_STATUS_HARD_ERROR;
999 0 : return;
1000 : }
1001 0 : eic->qs = i + 1;
1002 0 : eic->cb (eic->cb_cls,
1003 : &master_pub,
1004 : exchange_url);
1005 0 : GNUNET_free (exchange_url);
1006 : }
1007 : }
1008 :
1009 :
1010 : /**
1011 : * Obtain information about exchanges this auditor is auditing.
1012 : *
1013 : * @param cls the @e cls of this struct with the plugin-specific state
1014 : * @param cb function to call with the results
1015 : * @param cb_cls closure for @a cb
1016 : * @return query result status
1017 : */
1018 : static enum GNUNET_DB_QueryStatus
1019 0 : postgres_list_exchanges (void *cls,
1020 : TALER_AUDITORDB_ExchangeCallback cb,
1021 : void *cb_cls)
1022 : {
1023 0 : struct PostgresClosure *pg = cls;
1024 0 : struct GNUNET_PQ_QueryParam params[] = {
1025 : GNUNET_PQ_query_param_end
1026 : };
1027 0 : struct ExchangeInfoContext eic = {
1028 : .cb = cb,
1029 : .cb_cls = cb_cls
1030 : };
1031 : enum GNUNET_DB_QueryStatus qs;
1032 :
1033 0 : qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
1034 : "auditor_list_exchanges",
1035 : params,
1036 : &exchange_info_cb,
1037 : &eic);
1038 0 : if (qs > 0)
1039 0 : return eic.qs;
1040 0 : GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR != qs);
1041 0 : return qs;
1042 : }
1043 :
1044 :
1045 : /**
1046 : * Insert information about a signing key of the exchange.
1047 : *
1048 : * @param cls the @e cls of this struct with the plugin-specific state
1049 : * @param sk signing key information to store
1050 : * @return query result status
1051 : */
1052 : static enum GNUNET_DB_QueryStatus
1053 0 : postgres_insert_exchange_signkey (
1054 : void *cls,
1055 : const struct TALER_AUDITORDB_ExchangeSigningKey *sk)
1056 : {
1057 0 : struct PostgresClosure *pg = cls;
1058 0 : struct GNUNET_PQ_QueryParam params[] = {
1059 0 : GNUNET_PQ_query_param_auto_from_type (&sk->master_public_key),
1060 0 : GNUNET_PQ_query_param_timestamp (&sk->ep_start),
1061 0 : GNUNET_PQ_query_param_timestamp (&sk->ep_expire),
1062 0 : GNUNET_PQ_query_param_timestamp (&sk->ep_end),
1063 0 : GNUNET_PQ_query_param_auto_from_type (&sk->exchange_pub),
1064 0 : GNUNET_PQ_query_param_auto_from_type (&sk->master_sig),
1065 : GNUNET_PQ_query_param_end
1066 : };
1067 :
1068 0 : return GNUNET_PQ_eval_prepared_non_select (pg->conn,
1069 : "auditor_insert_exchange_signkey",
1070 : params);
1071 : }
1072 :
1073 :
1074 : /**
1075 : * Insert information about a deposit confirmation into the database.
1076 : *
1077 : * @param cls the @e cls of this struct with the plugin-specific state
1078 : * @param dc deposit confirmation information to store
1079 : * @return query result status
1080 : */
1081 : static enum GNUNET_DB_QueryStatus
1082 0 : postgres_insert_deposit_confirmation (
1083 : void *cls,
1084 : const struct TALER_AUDITORDB_DepositConfirmation *dc)
1085 : {
1086 0 : struct PostgresClosure *pg = cls;
1087 0 : struct GNUNET_PQ_QueryParam params[] = {
1088 0 : GNUNET_PQ_query_param_auto_from_type (&dc->master_public_key),
1089 0 : GNUNET_PQ_query_param_auto_from_type (&dc->h_contract_terms),
1090 0 : GNUNET_PQ_query_param_auto_from_type (&dc->h_extensions),
1091 0 : GNUNET_PQ_query_param_auto_from_type (&dc->h_wire),
1092 0 : GNUNET_PQ_query_param_timestamp (&dc->exchange_timestamp),
1093 0 : GNUNET_PQ_query_param_timestamp (&dc->wire_deadline),
1094 0 : GNUNET_PQ_query_param_timestamp (&dc->refund_deadline),
1095 0 : TALER_PQ_query_param_amount (&dc->amount_without_fee),
1096 0 : GNUNET_PQ_query_param_auto_from_type (&dc->coin_pub),
1097 0 : GNUNET_PQ_query_param_auto_from_type (&dc->merchant),
1098 0 : GNUNET_PQ_query_param_auto_from_type (&dc->exchange_sig),
1099 0 : GNUNET_PQ_query_param_auto_from_type (&dc->exchange_pub),
1100 0 : GNUNET_PQ_query_param_auto_from_type (&dc->master_sig),
1101 : GNUNET_PQ_query_param_end
1102 : };
1103 :
1104 0 : return GNUNET_PQ_eval_prepared_non_select (pg->conn,
1105 : "auditor_deposit_confirmation_insert",
1106 : params);
1107 : }
1108 :
1109 :
1110 : /**
1111 : * Closure for #deposit_confirmation_cb().
1112 : */
1113 : struct DepositConfirmationContext
1114 : {
1115 :
1116 : /**
1117 : * Master public key that is being used.
1118 : */
1119 : const struct TALER_MasterPublicKeyP *master_pub;
1120 :
1121 : /**
1122 : * Function to call for each deposit confirmation.
1123 : */
1124 : TALER_AUDITORDB_DepositConfirmationCallback cb;
1125 :
1126 : /**
1127 : * Closure for @e cb
1128 : */
1129 : void *cb_cls;
1130 :
1131 : /**
1132 : * Plugin context.
1133 : */
1134 : struct PostgresClosure *pg;
1135 :
1136 : /**
1137 : * Query status to return.
1138 : */
1139 : enum GNUNET_DB_QueryStatus qs;
1140 : };
1141 :
1142 :
1143 : /**
1144 : * Helper function for #postgres_get_deposit_confirmations().
1145 : * To be called with the results of a SELECT statement
1146 : * that has returned @a num_results results.
1147 : *
1148 : * @param cls closure of type `struct DepositConfirmationContext *`
1149 : * @param result the postgres result
1150 : * @param num_results the number of results in @a result
1151 : */
1152 : static void
1153 0 : deposit_confirmation_cb (void *cls,
1154 : PGresult *result,
1155 : unsigned int num_results)
1156 : {
1157 0 : struct DepositConfirmationContext *dcc = cls;
1158 0 : struct PostgresClosure *pg = dcc->pg;
1159 :
1160 0 : for (unsigned int i = 0; i < num_results; i++)
1161 : {
1162 : uint64_t serial_id;
1163 0 : struct TALER_AUDITORDB_DepositConfirmation dc = {
1164 0 : .master_public_key = *dcc->master_pub
1165 : };
1166 0 : struct GNUNET_PQ_ResultSpec rs[] = {
1167 0 : GNUNET_PQ_result_spec_uint64 ("serial_id",
1168 : &serial_id),
1169 0 : GNUNET_PQ_result_spec_auto_from_type ("h_contract_terms",
1170 : &dc.h_contract_terms),
1171 0 : GNUNET_PQ_result_spec_auto_from_type ("h_extensions",
1172 : &dc.h_extensions),
1173 0 : GNUNET_PQ_result_spec_auto_from_type ("h_wire",
1174 : &dc.h_wire),
1175 0 : GNUNET_PQ_result_spec_timestamp ("exchange_timestamp",
1176 : &dc.exchange_timestamp),
1177 0 : GNUNET_PQ_result_spec_timestamp ("refund_deadline",
1178 : &dc.refund_deadline),
1179 0 : GNUNET_PQ_result_spec_timestamp ("wire_deadline",
1180 : &dc.wire_deadline),
1181 0 : TALER_PQ_RESULT_SPEC_AMOUNT ("amount_without_fee",
1182 : &dc.amount_without_fee),
1183 0 : GNUNET_PQ_result_spec_auto_from_type ("coin_pub",
1184 : &dc.coin_pub),
1185 0 : GNUNET_PQ_result_spec_auto_from_type ("merchant_pub",
1186 : &dc.merchant),
1187 0 : GNUNET_PQ_result_spec_auto_from_type ("exchange_sig",
1188 : &dc.exchange_sig),
1189 0 : GNUNET_PQ_result_spec_auto_from_type ("exchange_pub",
1190 : &dc.exchange_pub),
1191 0 : GNUNET_PQ_result_spec_auto_from_type ("master_sig",
1192 : &dc.master_sig),
1193 : GNUNET_PQ_result_spec_end
1194 : };
1195 :
1196 0 : if (GNUNET_OK !=
1197 0 : GNUNET_PQ_extract_result (result,
1198 : rs,
1199 : i))
1200 : {
1201 0 : GNUNET_break (0);
1202 0 : dcc->qs = GNUNET_DB_STATUS_HARD_ERROR;
1203 0 : return;
1204 : }
1205 0 : dcc->qs = i + 1;
1206 0 : if (GNUNET_OK !=
1207 0 : dcc->cb (dcc->cb_cls,
1208 : serial_id,
1209 : &dc))
1210 0 : break;
1211 : }
1212 : }
1213 :
1214 :
1215 : /**
1216 : * Get information about deposit confirmations from the database.
1217 : *
1218 : * @param cls the @e cls of this struct with the plugin-specific state
1219 : * @param master_public_key for which exchange do we want to get deposit confirmations
1220 : * @param start_id row/serial ID where to start the iteration (0 from
1221 : * the start, exclusive, i.e. serial_ids must start from 1)
1222 : * @param cb function to call with results
1223 : * @param cb_cls closure for @a cb
1224 : * @return query result status
1225 : */
1226 : static enum GNUNET_DB_QueryStatus
1227 0 : postgres_get_deposit_confirmations (
1228 : void *cls,
1229 : const struct TALER_MasterPublicKeyP *master_public_key,
1230 : uint64_t start_id,
1231 : TALER_AUDITORDB_DepositConfirmationCallback cb,
1232 : void *cb_cls)
1233 : {
1234 0 : struct PostgresClosure *pg = cls;
1235 0 : struct GNUNET_PQ_QueryParam params[] = {
1236 0 : GNUNET_PQ_query_param_auto_from_type (master_public_key),
1237 0 : GNUNET_PQ_query_param_uint64 (&start_id),
1238 : GNUNET_PQ_query_param_end
1239 : };
1240 0 : struct DepositConfirmationContext dcc = {
1241 : .master_pub = master_public_key,
1242 : .cb = cb,
1243 : .cb_cls = cb_cls,
1244 : .pg = pg
1245 : };
1246 : enum GNUNET_DB_QueryStatus qs;
1247 :
1248 0 : qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
1249 : "auditor_deposit_confirmation_select",
1250 : params,
1251 : &deposit_confirmation_cb,
1252 : &dcc);
1253 0 : if (qs > 0)
1254 0 : return dcc.qs;
1255 0 : GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR != qs);
1256 0 : return qs;
1257 : }
1258 :
1259 :
1260 : /**
1261 : * Insert information about the auditor's progress with an exchange's
1262 : * data.
1263 : *
1264 : * @param cls the @e cls of this struct with the plugin-specific state
1265 : * @param master_pub master key of the exchange
1266 : * @param ppr where is the auditor in processing
1267 : * @return transaction status code
1268 : */
1269 : static enum GNUNET_DB_QueryStatus
1270 0 : postgres_insert_auditor_progress_reserve (
1271 : void *cls,
1272 : const struct TALER_MasterPublicKeyP *master_pub,
1273 : const struct TALER_AUDITORDB_ProgressPointReserve *ppr)
1274 : {
1275 0 : struct PostgresClosure *pg = cls;
1276 0 : struct GNUNET_PQ_QueryParam params[] = {
1277 0 : GNUNET_PQ_query_param_auto_from_type (master_pub),
1278 0 : GNUNET_PQ_query_param_uint64 (&ppr->last_reserve_in_serial_id),
1279 0 : GNUNET_PQ_query_param_uint64 (&ppr->last_reserve_out_serial_id),
1280 0 : GNUNET_PQ_query_param_uint64 (&ppr->last_reserve_recoup_serial_id),
1281 0 : GNUNET_PQ_query_param_uint64 (&ppr->last_reserve_close_serial_id),
1282 0 : GNUNET_PQ_query_param_uint64 (&ppr->last_purse_merges_serial_id),
1283 0 : GNUNET_PQ_query_param_uint64 (&ppr->last_purse_deposits_serial_id),
1284 0 : GNUNET_PQ_query_param_uint64 (&ppr->last_account_merges_serial_id),
1285 0 : GNUNET_PQ_query_param_uint64 (&ppr->last_history_requests_serial_id),
1286 0 : GNUNET_PQ_query_param_uint64 (&ppr->last_close_requests_serial_id),
1287 : GNUNET_PQ_query_param_end
1288 : };
1289 :
1290 0 : return GNUNET_PQ_eval_prepared_non_select (pg->conn,
1291 : "auditor_progress_insert_reserve",
1292 : params);
1293 : }
1294 :
1295 :
1296 : /**
1297 : * Update information about the progress of the auditor. There
1298 : * must be an existing record for the exchange.
1299 : *
1300 : * @param cls the @e cls of this struct with the plugin-specific state
1301 : * @param master_pub master key of the exchange
1302 : * @param ppr where is the auditor in processing
1303 : * @return transaction status code
1304 : */
1305 : static enum GNUNET_DB_QueryStatus
1306 0 : postgres_update_auditor_progress_reserve (
1307 : void *cls,
1308 : const struct TALER_MasterPublicKeyP *master_pub,
1309 : const struct TALER_AUDITORDB_ProgressPointReserve *ppr)
1310 : {
1311 0 : struct PostgresClosure *pg = cls;
1312 0 : struct GNUNET_PQ_QueryParam params[] = {
1313 0 : GNUNET_PQ_query_param_uint64 (&ppr->last_reserve_in_serial_id),
1314 0 : GNUNET_PQ_query_param_uint64 (&ppr->last_reserve_out_serial_id),
1315 0 : GNUNET_PQ_query_param_uint64 (&ppr->last_reserve_recoup_serial_id),
1316 0 : GNUNET_PQ_query_param_uint64 (&ppr->last_reserve_close_serial_id),
1317 0 : GNUNET_PQ_query_param_uint64 (&ppr->last_purse_merges_serial_id),
1318 0 : GNUNET_PQ_query_param_uint64 (&ppr->last_purse_deposits_serial_id),
1319 0 : GNUNET_PQ_query_param_uint64 (&ppr->last_account_merges_serial_id),
1320 0 : GNUNET_PQ_query_param_uint64 (&ppr->last_history_requests_serial_id),
1321 0 : GNUNET_PQ_query_param_uint64 (&ppr->last_close_requests_serial_id),
1322 0 : GNUNET_PQ_query_param_auto_from_type (master_pub),
1323 : GNUNET_PQ_query_param_end
1324 : };
1325 :
1326 0 : return GNUNET_PQ_eval_prepared_non_select (pg->conn,
1327 : "auditor_progress_update_reserve",
1328 : params);
1329 : }
1330 :
1331 :
1332 : /**
1333 : * Get information about the progress of the auditor.
1334 : *
1335 : * @param cls the @e cls of this struct with the plugin-specific state
1336 : * @param master_pub master key of the exchange
1337 : * @param[out] ppr set to where the auditor is in processing
1338 : * @return transaction status code
1339 : */
1340 : static enum GNUNET_DB_QueryStatus
1341 0 : postgres_get_auditor_progress_reserve (
1342 : void *cls,
1343 : const struct TALER_MasterPublicKeyP *master_pub,
1344 : struct TALER_AUDITORDB_ProgressPointReserve *ppr)
1345 : {
1346 0 : struct PostgresClosure *pg = cls;
1347 0 : struct GNUNET_PQ_QueryParam params[] = {
1348 0 : GNUNET_PQ_query_param_auto_from_type (master_pub),
1349 : GNUNET_PQ_query_param_end
1350 : };
1351 0 : struct GNUNET_PQ_ResultSpec rs[] = {
1352 0 : GNUNET_PQ_result_spec_uint64 ("last_reserve_in_serial_id",
1353 : &ppr->last_reserve_in_serial_id),
1354 0 : GNUNET_PQ_result_spec_uint64 ("last_reserve_out_serial_id",
1355 : &ppr->last_reserve_out_serial_id),
1356 0 : GNUNET_PQ_result_spec_uint64 ("last_reserve_recoup_serial_id",
1357 : &ppr->last_reserve_recoup_serial_id),
1358 0 : GNUNET_PQ_result_spec_uint64 ("last_reserve_close_serial_id",
1359 : &ppr->last_reserve_close_serial_id),
1360 0 : GNUNET_PQ_result_spec_uint64 ("last_purse_merges_serial_id",
1361 : &ppr->last_purse_merges_serial_id),
1362 0 : GNUNET_PQ_result_spec_uint64 ("last_purse_deposits_serial_id",
1363 : &ppr->last_purse_deposits_serial_id),
1364 0 : GNUNET_PQ_result_spec_uint64 ("last_account_merges_serial_id",
1365 : &ppr->last_account_merges_serial_id),
1366 0 : GNUNET_PQ_result_spec_uint64 ("last_history_requests_serial_id",
1367 : &ppr->last_history_requests_serial_id),
1368 0 : GNUNET_PQ_result_spec_uint64 ("last_close_requests_serial_id",
1369 : &ppr->last_close_requests_serial_id),
1370 : GNUNET_PQ_result_spec_end
1371 : };
1372 :
1373 0 : return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
1374 : "auditor_progress_select_reserve",
1375 : params,
1376 : rs);
1377 : }
1378 :
1379 :
1380 : /**
1381 : * Insert information about the auditor's progress with an exchange's
1382 : * data.
1383 : *
1384 : * @param cls the @e cls of this struct with the plugin-specific state
1385 : * @param master_pub master key of the exchange
1386 : * @param ppa where is the auditor in processing
1387 : * @return transaction status code
1388 : */
1389 : static enum GNUNET_DB_QueryStatus
1390 0 : postgres_insert_auditor_progress_aggregation (
1391 : void *cls,
1392 : const struct TALER_MasterPublicKeyP *master_pub,
1393 : const struct TALER_AUDITORDB_ProgressPointAggregation *ppa)
1394 : {
1395 0 : struct PostgresClosure *pg = cls;
1396 0 : struct GNUNET_PQ_QueryParam params[] = {
1397 0 : GNUNET_PQ_query_param_auto_from_type (master_pub),
1398 0 : GNUNET_PQ_query_param_uint64 (&ppa->last_wire_out_serial_id),
1399 : GNUNET_PQ_query_param_end
1400 : };
1401 :
1402 0 : return GNUNET_PQ_eval_prepared_non_select (pg->conn,
1403 : "auditor_progress_insert_aggregation",
1404 : params);
1405 : }
1406 :
1407 :
1408 : /**
1409 : * Update information about the progress of the auditor. There
1410 : * must be an existing record for the exchange.
1411 : *
1412 : * @param cls the @e cls of this struct with the plugin-specific state
1413 : * @param master_pub master key of the exchange
1414 : * @param ppa where is the auditor in processing
1415 : * @return transaction status code
1416 : */
1417 : static enum GNUNET_DB_QueryStatus
1418 0 : postgres_update_auditor_progress_aggregation (
1419 : void *cls,
1420 : const struct TALER_MasterPublicKeyP *master_pub,
1421 : const struct TALER_AUDITORDB_ProgressPointAggregation *ppa)
1422 : {
1423 0 : struct PostgresClosure *pg = cls;
1424 0 : struct GNUNET_PQ_QueryParam params[] = {
1425 0 : GNUNET_PQ_query_param_uint64 (&ppa->last_wire_out_serial_id),
1426 0 : GNUNET_PQ_query_param_auto_from_type (master_pub),
1427 : GNUNET_PQ_query_param_end
1428 : };
1429 :
1430 0 : return GNUNET_PQ_eval_prepared_non_select (pg->conn,
1431 : "auditor_progress_update_aggregation",
1432 : params);
1433 : }
1434 :
1435 :
1436 : /**
1437 : * Get information about the progress of the auditor.
1438 : *
1439 : * @param cls the @e cls of this struct with the plugin-specific state
1440 : * @param master_pub master key of the exchange
1441 : * @param[out] ppa set to where the auditor is in processing
1442 : * @return transaction status code
1443 : */
1444 : static enum GNUNET_DB_QueryStatus
1445 0 : postgres_get_auditor_progress_aggregation (
1446 : void *cls,
1447 : const struct TALER_MasterPublicKeyP *master_pub,
1448 : struct TALER_AUDITORDB_ProgressPointAggregation *ppa)
1449 : {
1450 0 : struct PostgresClosure *pg = cls;
1451 0 : struct GNUNET_PQ_QueryParam params[] = {
1452 0 : GNUNET_PQ_query_param_auto_from_type (master_pub),
1453 : GNUNET_PQ_query_param_end
1454 : };
1455 0 : struct GNUNET_PQ_ResultSpec rs[] = {
1456 0 : GNUNET_PQ_result_spec_uint64 ("last_wire_out_serial_id",
1457 : &ppa->last_wire_out_serial_id),
1458 : GNUNET_PQ_result_spec_end
1459 : };
1460 :
1461 0 : return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
1462 : "auditor_progress_select_aggregation",
1463 : params,
1464 : rs);
1465 : }
1466 :
1467 :
1468 : /**
1469 : * Insert information about the auditor's progress with an exchange's
1470 : * data.
1471 : *
1472 : * @param cls the @e cls of this struct with the plugin-specific state
1473 : * @param master_pub master key of the exchange
1474 : * @param ppdc where is the auditor in processing
1475 : * @return transaction status code
1476 : */
1477 : static enum GNUNET_DB_QueryStatus
1478 0 : postgres_insert_auditor_progress_deposit_confirmation (
1479 : void *cls,
1480 : const struct TALER_MasterPublicKeyP *master_pub,
1481 : const struct TALER_AUDITORDB_ProgressPointDepositConfirmation *ppdc)
1482 : {
1483 0 : struct PostgresClosure *pg = cls;
1484 0 : struct GNUNET_PQ_QueryParam params[] = {
1485 0 : GNUNET_PQ_query_param_auto_from_type (master_pub),
1486 0 : GNUNET_PQ_query_param_uint64 (&ppdc->last_deposit_confirmation_serial_id),
1487 : GNUNET_PQ_query_param_end
1488 : };
1489 :
1490 0 : return GNUNET_PQ_eval_prepared_non_select (pg->conn,
1491 : "auditor_progress_insert_deposit_confirmation",
1492 : params);
1493 : }
1494 :
1495 :
1496 : /**
1497 : * Update information about the progress of the auditor. There
1498 : * must be an existing record for the exchange.
1499 : *
1500 : * @param cls the @e cls of this struct with the plugin-specific state
1501 : * @param master_pub master key of the exchange
1502 : * @param ppdc where is the auditor in processing
1503 : * @return transaction status code
1504 : */
1505 : static enum GNUNET_DB_QueryStatus
1506 0 : postgres_update_auditor_progress_deposit_confirmation (
1507 : void *cls,
1508 : const struct TALER_MasterPublicKeyP *master_pub,
1509 : const struct TALER_AUDITORDB_ProgressPointDepositConfirmation *ppdc)
1510 : {
1511 0 : struct PostgresClosure *pg = cls;
1512 0 : struct GNUNET_PQ_QueryParam params[] = {
1513 0 : GNUNET_PQ_query_param_uint64 (&ppdc->last_deposit_confirmation_serial_id),
1514 0 : GNUNET_PQ_query_param_auto_from_type (master_pub),
1515 : GNUNET_PQ_query_param_end
1516 : };
1517 :
1518 0 : return GNUNET_PQ_eval_prepared_non_select (pg->conn,
1519 : "auditor_progress_update_deposit_confirmation",
1520 : params);
1521 : }
1522 :
1523 :
1524 : /**
1525 : * Get information about the progress of the auditor.
1526 : *
1527 : * @param cls the @e cls of this struct with the plugin-specific state
1528 : * @param master_pub master key of the exchange
1529 : * @param[out] ppdc set to where the auditor is in processing
1530 : * @return transaction status code
1531 : */
1532 : static enum GNUNET_DB_QueryStatus
1533 0 : postgres_get_auditor_progress_deposit_confirmation (
1534 : void *cls,
1535 : const struct TALER_MasterPublicKeyP *master_pub,
1536 : struct TALER_AUDITORDB_ProgressPointDepositConfirmation *ppdc)
1537 : {
1538 0 : struct PostgresClosure *pg = cls;
1539 0 : struct GNUNET_PQ_QueryParam params[] = {
1540 0 : GNUNET_PQ_query_param_auto_from_type (master_pub),
1541 : GNUNET_PQ_query_param_end
1542 : };
1543 0 : struct GNUNET_PQ_ResultSpec rs[] = {
1544 0 : GNUNET_PQ_result_spec_uint64 ("last_deposit_confirmation_serial_id",
1545 : &ppdc->last_deposit_confirmation_serial_id),
1546 : GNUNET_PQ_result_spec_end
1547 : };
1548 :
1549 0 : return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
1550 : "auditor_progress_select_deposit_confirmation",
1551 : params,
1552 : rs);
1553 : }
1554 :
1555 :
1556 : /**
1557 : * Insert information about the auditor's progress with an exchange's
1558 : * data.
1559 : *
1560 : * @param cls the @e cls of this struct with the plugin-specific state
1561 : * @param master_pub master key of the exchange
1562 : * @param ppc where is the auditor in processing
1563 : * @return transaction status code
1564 : */
1565 : static enum GNUNET_DB_QueryStatus
1566 0 : postgres_insert_auditor_progress_coin (
1567 : void *cls,
1568 : const struct TALER_MasterPublicKeyP *master_pub,
1569 : const struct TALER_AUDITORDB_ProgressPointCoin *ppc)
1570 : {
1571 0 : struct PostgresClosure *pg = cls;
1572 0 : struct GNUNET_PQ_QueryParam params[] = {
1573 0 : GNUNET_PQ_query_param_auto_from_type (master_pub),
1574 0 : GNUNET_PQ_query_param_uint64 (&ppc->last_withdraw_serial_id),
1575 0 : GNUNET_PQ_query_param_uint64 (&ppc->last_deposit_serial_id),
1576 0 : GNUNET_PQ_query_param_uint64 (&ppc->last_melt_serial_id),
1577 0 : GNUNET_PQ_query_param_uint64 (&ppc->last_refund_serial_id),
1578 0 : GNUNET_PQ_query_param_uint64 (&ppc->last_recoup_serial_id),
1579 0 : GNUNET_PQ_query_param_uint64 (&ppc->last_recoup_refresh_serial_id),
1580 0 : GNUNET_PQ_query_param_uint64 (&ppc->last_purse_deposits_serial_id),
1581 0 : GNUNET_PQ_query_param_uint64 (&ppc->last_purse_refunds_serial_id),
1582 : GNUNET_PQ_query_param_end
1583 : };
1584 :
1585 0 : return GNUNET_PQ_eval_prepared_non_select (pg->conn,
1586 : "auditor_progress_insert_coin",
1587 : params);
1588 : }
1589 :
1590 :
1591 : /**
1592 : * Update information about the progress of the auditor. There
1593 : * must be an existing record for the exchange.
1594 : *
1595 : * @param cls the @e cls of this struct with the plugin-specific state
1596 : * @param master_pub master key of the exchange
1597 : * @param ppc where is the auditor in processing
1598 : * @return transaction status code
1599 : */
1600 : static enum GNUNET_DB_QueryStatus
1601 0 : postgres_update_auditor_progress_coin (
1602 : void *cls,
1603 : const struct TALER_MasterPublicKeyP *master_pub,
1604 : const struct TALER_AUDITORDB_ProgressPointCoin *ppc)
1605 : {
1606 0 : struct PostgresClosure *pg = cls;
1607 0 : struct GNUNET_PQ_QueryParam params[] = {
1608 0 : GNUNET_PQ_query_param_uint64 (&ppc->last_withdraw_serial_id),
1609 0 : GNUNET_PQ_query_param_uint64 (&ppc->last_deposit_serial_id),
1610 0 : GNUNET_PQ_query_param_uint64 (&ppc->last_melt_serial_id),
1611 0 : GNUNET_PQ_query_param_uint64 (&ppc->last_refund_serial_id),
1612 0 : GNUNET_PQ_query_param_uint64 (&ppc->last_recoup_serial_id),
1613 0 : GNUNET_PQ_query_param_uint64 (&ppc->last_recoup_refresh_serial_id),
1614 0 : GNUNET_PQ_query_param_uint64 (&ppc->last_purse_deposits_serial_id),
1615 0 : GNUNET_PQ_query_param_uint64 (&ppc->last_purse_refunds_serial_id),
1616 0 : GNUNET_PQ_query_param_auto_from_type (master_pub),
1617 : GNUNET_PQ_query_param_end
1618 : };
1619 :
1620 0 : return GNUNET_PQ_eval_prepared_non_select (pg->conn,
1621 : "auditor_progress_update_coin",
1622 : params);
1623 : }
1624 :
1625 :
1626 : /**
1627 : * Get information about the progress of the auditor.
1628 : *
1629 : * @param cls the @e cls of this struct with the plugin-specific state
1630 : * @param master_pub master key of the exchange
1631 : * @param[out] ppc set to where the auditor is in processing
1632 : * @return transaction status code
1633 : */
1634 : static enum GNUNET_DB_QueryStatus
1635 0 : postgres_get_auditor_progress_coin (
1636 : void *cls,
1637 : const struct TALER_MasterPublicKeyP *master_pub,
1638 : struct TALER_AUDITORDB_ProgressPointCoin *ppc)
1639 : {
1640 0 : struct PostgresClosure *pg = cls;
1641 0 : struct GNUNET_PQ_QueryParam params[] = {
1642 0 : GNUNET_PQ_query_param_auto_from_type (master_pub),
1643 : GNUNET_PQ_query_param_end
1644 : };
1645 0 : struct GNUNET_PQ_ResultSpec rs[] = {
1646 0 : GNUNET_PQ_result_spec_uint64 ("last_withdraw_serial_id",
1647 : &ppc->last_withdraw_serial_id),
1648 0 : GNUNET_PQ_result_spec_uint64 ("last_deposit_serial_id",
1649 : &ppc->last_deposit_serial_id),
1650 0 : GNUNET_PQ_result_spec_uint64 ("last_melt_serial_id",
1651 : &ppc->last_melt_serial_id),
1652 0 : GNUNET_PQ_result_spec_uint64 ("last_refund_serial_id",
1653 : &ppc->last_refund_serial_id),
1654 0 : GNUNET_PQ_result_spec_uint64 ("last_recoup_serial_id",
1655 : &ppc->last_recoup_serial_id),
1656 0 : GNUNET_PQ_result_spec_uint64 ("last_recoup_refresh_serial_id",
1657 : &ppc->last_recoup_refresh_serial_id),
1658 0 : GNUNET_PQ_result_spec_uint64 ("last_purse_deposits_serial_id",
1659 : &ppc->last_purse_deposits_serial_id),
1660 0 : GNUNET_PQ_result_spec_uint64 ("last_purse_refunds_serial_id",
1661 : &ppc->last_purse_refunds_serial_id),
1662 : GNUNET_PQ_result_spec_end
1663 : };
1664 :
1665 0 : return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
1666 : "auditor_progress_select_coin",
1667 : params,
1668 : rs);
1669 : }
1670 :
1671 :
1672 : /**
1673 : * Insert information about the auditor's progress with an exchange's
1674 : * data.
1675 : *
1676 : * @param cls the @e cls of this struct with the plugin-specific state
1677 : * @param master_pub master key of the exchange
1678 : * @param account_name name of the wire account we are auditing
1679 : * @param pp how far are we in the auditor's tables
1680 : * @param in_wire_off how far are we in the incoming wire transfers
1681 : * @param out_wire_off how far are we in the outgoing wire transfers
1682 : * @return transaction status code
1683 : */
1684 : static enum GNUNET_DB_QueryStatus
1685 0 : postgres_insert_wire_auditor_account_progress (
1686 : void *cls,
1687 : const struct TALER_MasterPublicKeyP *master_pub,
1688 : const char *account_name,
1689 : const struct TALER_AUDITORDB_WireAccountProgressPoint *pp,
1690 : uint64_t in_wire_off,
1691 : uint64_t out_wire_off)
1692 : {
1693 0 : struct PostgresClosure *pg = cls;
1694 0 : struct GNUNET_PQ_QueryParam params[] = {
1695 0 : GNUNET_PQ_query_param_auto_from_type (master_pub),
1696 0 : GNUNET_PQ_query_param_string (account_name),
1697 0 : GNUNET_PQ_query_param_uint64 (&pp->last_reserve_in_serial_id),
1698 0 : GNUNET_PQ_query_param_uint64 (&pp->last_wire_out_serial_id),
1699 0 : GNUNET_PQ_query_param_uint64 (&in_wire_off),
1700 0 : GNUNET_PQ_query_param_uint64 (&out_wire_off),
1701 : GNUNET_PQ_query_param_end
1702 : };
1703 :
1704 0 : return GNUNET_PQ_eval_prepared_non_select (pg->conn,
1705 : "wire_auditor_account_progress_insert",
1706 : params);
1707 : }
1708 :
1709 :
1710 : /**
1711 : * Update information about the progress of the auditor. There
1712 : * must be an existing record for the exchange.
1713 : *
1714 : * @param cls the @e cls of this struct with the plugin-specific state
1715 : * @param master_pub master key of the exchange
1716 : * @param account_name name of the wire account we are auditing
1717 : * @param pp where is the auditor in processing
1718 : * @param in_wire_off how far are we in the incoming wire transaction history
1719 : * @param out_wire_off how far are we in the outgoing wire transaction history
1720 : * @return transaction status code
1721 : */
1722 : static enum GNUNET_DB_QueryStatus
1723 0 : postgres_update_wire_auditor_account_progress (
1724 : void *cls,
1725 : const struct TALER_MasterPublicKeyP *master_pub,
1726 : const char *account_name,
1727 : const struct TALER_AUDITORDB_WireAccountProgressPoint *pp,
1728 : uint64_t in_wire_off,
1729 : uint64_t out_wire_off)
1730 : {
1731 0 : struct PostgresClosure *pg = cls;
1732 0 : struct GNUNET_PQ_QueryParam params[] = {
1733 0 : GNUNET_PQ_query_param_uint64 (&pp->last_reserve_in_serial_id),
1734 0 : GNUNET_PQ_query_param_uint64 (&pp->last_wire_out_serial_id),
1735 0 : GNUNET_PQ_query_param_uint64 (&in_wire_off),
1736 0 : GNUNET_PQ_query_param_uint64 (&out_wire_off),
1737 0 : GNUNET_PQ_query_param_auto_from_type (master_pub),
1738 0 : GNUNET_PQ_query_param_string (account_name),
1739 : GNUNET_PQ_query_param_end
1740 : };
1741 :
1742 0 : return GNUNET_PQ_eval_prepared_non_select (pg->conn,
1743 : "wire_auditor_account_progress_update",
1744 : params);
1745 : }
1746 :
1747 :
1748 : /**
1749 : * Get information about the progress of the auditor.
1750 : *
1751 : * @param cls the @e cls of this struct with the plugin-specific state
1752 : * @param master_pub master key of the exchange
1753 : * @param account_name name of the wire account we are auditing
1754 : * @param[out] pp where is the auditor in processing
1755 : * @param[out] in_wire_off how far are we in the incoming wire transaction history
1756 : * @param[out] out_wire_off how far are we in the outgoing wire transaction history
1757 : * @return transaction status code
1758 : */
1759 : static enum GNUNET_DB_QueryStatus
1760 0 : postgres_get_wire_auditor_account_progress (
1761 : void *cls,
1762 : const struct TALER_MasterPublicKeyP *master_pub,
1763 : const char *account_name,
1764 : struct TALER_AUDITORDB_WireAccountProgressPoint *pp,
1765 : uint64_t *in_wire_off,
1766 : uint64_t *out_wire_off)
1767 : {
1768 0 : struct PostgresClosure *pg = cls;
1769 0 : struct GNUNET_PQ_QueryParam params[] = {
1770 0 : GNUNET_PQ_query_param_auto_from_type (master_pub),
1771 0 : GNUNET_PQ_query_param_string (account_name),
1772 : GNUNET_PQ_query_param_end
1773 : };
1774 0 : struct GNUNET_PQ_ResultSpec rs[] = {
1775 0 : GNUNET_PQ_result_spec_uint64 ("last_wire_reserve_in_serial_id",
1776 : &pp->last_reserve_in_serial_id),
1777 0 : GNUNET_PQ_result_spec_uint64 ("last_wire_wire_out_serial_id",
1778 : &pp->last_wire_out_serial_id),
1779 0 : GNUNET_PQ_result_spec_uint64 ("wire_in_off",
1780 : in_wire_off),
1781 0 : GNUNET_PQ_result_spec_uint64 ("wire_out_off",
1782 : out_wire_off),
1783 : GNUNET_PQ_result_spec_end
1784 : };
1785 :
1786 0 : return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
1787 : "wire_auditor_account_progress_select",
1788 : params,
1789 : rs);
1790 : }
1791 :
1792 :
1793 : /**
1794 : * Insert information about the auditor's progress with an exchange's
1795 : * data.
1796 : *
1797 : * @param cls the @e cls of this struct with the plugin-specific state
1798 : * @param master_pub master key of the exchange
1799 : * @param pp where is the auditor in processing
1800 : * @return transaction status code
1801 : */
1802 : static enum GNUNET_DB_QueryStatus
1803 0 : postgres_insert_wire_auditor_progress (
1804 : void *cls,
1805 : const struct TALER_MasterPublicKeyP *master_pub,
1806 : const struct TALER_AUDITORDB_WireProgressPoint *pp)
1807 : {
1808 0 : struct PostgresClosure *pg = cls;
1809 0 : struct GNUNET_PQ_QueryParam params[] = {
1810 0 : GNUNET_PQ_query_param_auto_from_type (master_pub),
1811 0 : GNUNET_PQ_query_param_timestamp (&pp->last_timestamp),
1812 0 : GNUNET_PQ_query_param_uint64 (&pp->last_reserve_close_uuid),
1813 : GNUNET_PQ_query_param_end
1814 : };
1815 :
1816 0 : return GNUNET_PQ_eval_prepared_non_select (pg->conn,
1817 : "wire_auditor_progress_insert",
1818 : params);
1819 : }
1820 :
1821 :
1822 : /**
1823 : * Update information about the progress of the auditor. There
1824 : * must be an existing record for the exchange.
1825 : *
1826 : * @param cls the @e cls of this struct with the plugin-specific state
1827 : * @param master_pub master key of the exchange
1828 : * @param pp where is the auditor in processing
1829 : * @return transaction status code
1830 : */
1831 : static enum GNUNET_DB_QueryStatus
1832 0 : postgres_update_wire_auditor_progress (
1833 : void *cls,
1834 : const struct TALER_MasterPublicKeyP *master_pub,
1835 : const struct TALER_AUDITORDB_WireProgressPoint *pp)
1836 : {
1837 0 : struct PostgresClosure *pg = cls;
1838 0 : struct GNUNET_PQ_QueryParam params[] = {
1839 0 : GNUNET_PQ_query_param_timestamp (&pp->last_timestamp),
1840 0 : GNUNET_PQ_query_param_uint64 (&pp->last_reserve_close_uuid),
1841 0 : GNUNET_PQ_query_param_auto_from_type (master_pub),
1842 : GNUNET_PQ_query_param_end
1843 : };
1844 :
1845 0 : return GNUNET_PQ_eval_prepared_non_select (pg->conn,
1846 : "wire_auditor_progress_update",
1847 : params);
1848 : }
1849 :
1850 :
1851 : /**
1852 : * Get information about the progress of the auditor.
1853 : *
1854 : * @param cls the @e cls of this struct with the plugin-specific state
1855 : * @param master_pub master key of the exchange
1856 : * @param[out] pp set to where the auditor is in processing
1857 : * @return transaction status code
1858 : */
1859 : static enum GNUNET_DB_QueryStatus
1860 0 : postgres_get_wire_auditor_progress (
1861 : void *cls,
1862 : const struct TALER_MasterPublicKeyP *master_pub,
1863 : struct TALER_AUDITORDB_WireProgressPoint *pp)
1864 : {
1865 0 : struct PostgresClosure *pg = cls;
1866 0 : struct GNUNET_PQ_QueryParam params[] = {
1867 0 : GNUNET_PQ_query_param_auto_from_type (master_pub),
1868 : GNUNET_PQ_query_param_end
1869 : };
1870 0 : struct GNUNET_PQ_ResultSpec rs[] = {
1871 0 : GNUNET_PQ_result_spec_timestamp ("last_timestamp",
1872 : &pp->last_timestamp),
1873 0 : GNUNET_PQ_result_spec_uint64 ("last_reserve_close_uuid",
1874 : &pp->last_reserve_close_uuid),
1875 : GNUNET_PQ_result_spec_end
1876 : };
1877 :
1878 0 : return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
1879 : "wire_auditor_progress_select",
1880 : params,
1881 : rs);
1882 : }
1883 :
1884 :
1885 : /**
1886 : * Insert information about a reserve. There must not be an
1887 : * existing record for the reserve.
1888 : *
1889 : * @param cls the @e cls of this struct with the plugin-specific state
1890 : * @param reserve_pub public key of the reserve
1891 : * @param master_pub master public key of the exchange
1892 : * @param reserve_balance amount stored in the reserve
1893 : * @param withdraw_fee_balance amount the exchange gained in withdraw fees
1894 : * due to withdrawals from this reserve
1895 : * @param expiration_date expiration date of the reserve
1896 : * @param origin_account where did the money in the reserve originally come from
1897 : * @return transaction status code
1898 : */
1899 : static enum GNUNET_DB_QueryStatus
1900 0 : postgres_insert_reserve_info (void *cls,
1901 : const struct TALER_ReservePublicKeyP *reserve_pub,
1902 : const struct TALER_MasterPublicKeyP *master_pub,
1903 : const struct TALER_Amount *reserve_balance,
1904 : const struct TALER_Amount *withdraw_fee_balance,
1905 : struct GNUNET_TIME_Timestamp expiration_date,
1906 : const char *origin_account)
1907 : {
1908 0 : struct PostgresClosure *pg = cls;
1909 0 : struct GNUNET_PQ_QueryParam params[] = {
1910 0 : GNUNET_PQ_query_param_auto_from_type (reserve_pub),
1911 0 : GNUNET_PQ_query_param_auto_from_type (master_pub),
1912 0 : TALER_PQ_query_param_amount (reserve_balance),
1913 0 : TALER_PQ_query_param_amount (withdraw_fee_balance),
1914 0 : GNUNET_PQ_query_param_timestamp (&expiration_date),
1915 0 : GNUNET_PQ_query_param_string (origin_account),
1916 : GNUNET_PQ_query_param_end
1917 : };
1918 :
1919 0 : GNUNET_assert (GNUNET_YES ==
1920 : TALER_amount_cmp_currency (reserve_balance,
1921 : withdraw_fee_balance));
1922 :
1923 0 : return GNUNET_PQ_eval_prepared_non_select (pg->conn,
1924 : "auditor_reserves_insert",
1925 : params);
1926 : }
1927 :
1928 :
1929 : /**
1930 : * Update information about a reserve. Destructively updates an
1931 : * existing record, which must already exist.
1932 : *
1933 : * @param cls the @e cls of this struct with the plugin-specific state
1934 : * @param reserve_pub public key of the reserve
1935 : * @param master_pub master public key of the exchange
1936 : * @param reserve_balance amount stored in the reserve
1937 : * @param withdraw_fee_balance amount the exchange gained in withdraw fees
1938 : * due to withdrawals from this reserve
1939 : * @param expiration_date expiration date of the reserve
1940 : * @return transaction status code
1941 : */
1942 : static enum GNUNET_DB_QueryStatus
1943 0 : postgres_update_reserve_info (void *cls,
1944 : const struct TALER_ReservePublicKeyP *reserve_pub,
1945 : const struct TALER_MasterPublicKeyP *master_pub,
1946 : const struct TALER_Amount *reserve_balance,
1947 : const struct TALER_Amount *withdraw_fee_balance,
1948 : struct GNUNET_TIME_Timestamp expiration_date)
1949 : {
1950 0 : struct PostgresClosure *pg = cls;
1951 0 : struct GNUNET_PQ_QueryParam params[] = {
1952 0 : TALER_PQ_query_param_amount (reserve_balance),
1953 0 : TALER_PQ_query_param_amount (withdraw_fee_balance),
1954 0 : GNUNET_PQ_query_param_timestamp (&expiration_date),
1955 0 : GNUNET_PQ_query_param_auto_from_type (reserve_pub),
1956 0 : GNUNET_PQ_query_param_auto_from_type (master_pub),
1957 : GNUNET_PQ_query_param_end
1958 : };
1959 :
1960 0 : GNUNET_assert (GNUNET_YES ==
1961 : TALER_amount_cmp_currency (reserve_balance,
1962 : withdraw_fee_balance));
1963 :
1964 0 : return GNUNET_PQ_eval_prepared_non_select (pg->conn,
1965 : "auditor_reserves_update",
1966 : params);
1967 : }
1968 :
1969 :
1970 : /**
1971 : * Delete information about a reserve.
1972 : *
1973 : * @param cls the @e cls of this struct with the plugin-specific state
1974 : * @param reserve_pub public key of the reserve
1975 : * @param master_pub master public key of the exchange
1976 : * @return transaction status code
1977 : */
1978 : static enum GNUNET_DB_QueryStatus
1979 0 : postgres_del_reserve_info (void *cls,
1980 : const struct TALER_ReservePublicKeyP *reserve_pub,
1981 : const struct TALER_MasterPublicKeyP *master_pub)
1982 : {
1983 0 : struct PostgresClosure *pg = cls;
1984 0 : struct GNUNET_PQ_QueryParam params[] = {
1985 0 : GNUNET_PQ_query_param_auto_from_type (reserve_pub),
1986 0 : GNUNET_PQ_query_param_auto_from_type (master_pub),
1987 : GNUNET_PQ_query_param_end
1988 : };
1989 :
1990 0 : return GNUNET_PQ_eval_prepared_non_select (pg->conn,
1991 : "auditor_reserves_delete",
1992 : params);
1993 : }
1994 :
1995 :
1996 : /**
1997 : * Get information about a reserve.
1998 : *
1999 : * @param cls the @e cls of this struct with the plugin-specific state
2000 : * @param reserve_pub public key of the reserve
2001 : * @param master_pub master public key of the exchange
2002 : * @param[out] rowid which row did we get the information from
2003 : * @param[out] reserve_balance amount stored in the reserve
2004 : * @param[out] withdraw_fee_balance amount the exchange gained in withdraw fees
2005 : * due to withdrawals from this reserve
2006 : * @param[out] expiration_date expiration date of the reserve
2007 : * @param[out] sender_account from where did the money in the reserve originally come from
2008 : * @return transaction status code
2009 : */
2010 : static enum GNUNET_DB_QueryStatus
2011 0 : postgres_get_reserve_info (void *cls,
2012 : const struct TALER_ReservePublicKeyP *reserve_pub,
2013 : const struct TALER_MasterPublicKeyP *master_pub,
2014 : uint64_t *rowid,
2015 : struct TALER_Amount *reserve_balance,
2016 : struct TALER_Amount *withdraw_fee_balance,
2017 : struct GNUNET_TIME_Timestamp *expiration_date,
2018 : char **sender_account)
2019 : {
2020 0 : struct PostgresClosure *pg = cls;
2021 0 : struct GNUNET_PQ_QueryParam params[] = {
2022 0 : GNUNET_PQ_query_param_auto_from_type (reserve_pub),
2023 0 : GNUNET_PQ_query_param_auto_from_type (master_pub),
2024 : GNUNET_PQ_query_param_end
2025 : };
2026 0 : struct GNUNET_PQ_ResultSpec rs[] = {
2027 0 : TALER_PQ_RESULT_SPEC_AMOUNT ("reserve_balance", reserve_balance),
2028 0 : TALER_PQ_RESULT_SPEC_AMOUNT ("withdraw_fee_balance", withdraw_fee_balance),
2029 0 : GNUNET_PQ_result_spec_timestamp ("expiration_date", expiration_date),
2030 0 : GNUNET_PQ_result_spec_uint64 ("auditor_reserves_rowid", rowid),
2031 0 : GNUNET_PQ_result_spec_string ("origin_account", sender_account),
2032 : GNUNET_PQ_result_spec_end
2033 : };
2034 :
2035 0 : return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
2036 : "auditor_reserves_select",
2037 : params,
2038 : rs);
2039 : }
2040 :
2041 :
2042 : /**
2043 : * Insert information about all reserves. There must not be an
2044 : * existing record for the @a master_pub.
2045 : *
2046 : * @param cls the @e cls of this struct with the plugin-specific state
2047 : * @param master_pub master public key of the exchange
2048 : * @param reserve_balance amount stored in the reserve
2049 : * @param withdraw_fee_balance amount the exchange gained in withdraw fees
2050 : * @param purse_fee_balance amount the exchange gained in purse fees
2051 : * @param history_fee_balance amount the exchange gained in history fees
2052 : * @return transaction status code
2053 : */
2054 : static enum GNUNET_DB_QueryStatus
2055 0 : postgres_insert_reserve_summary (
2056 : void *cls,
2057 : const struct TALER_MasterPublicKeyP *master_pub,
2058 : const struct TALER_Amount *reserve_balance,
2059 : const struct TALER_Amount *withdraw_fee_balance,
2060 : const struct TALER_Amount *purse_fee_balance,
2061 : const struct TALER_Amount *history_fee_balance)
2062 : {
2063 0 : struct PostgresClosure *pg = cls;
2064 0 : struct GNUNET_PQ_QueryParam params[] = {
2065 0 : GNUNET_PQ_query_param_auto_from_type (master_pub),
2066 0 : TALER_PQ_query_param_amount (reserve_balance),
2067 0 : TALER_PQ_query_param_amount (withdraw_fee_balance),
2068 0 : TALER_PQ_query_param_amount (purse_fee_balance),
2069 0 : TALER_PQ_query_param_amount (history_fee_balance),
2070 : GNUNET_PQ_query_param_end
2071 : };
2072 :
2073 0 : GNUNET_assert (GNUNET_YES ==
2074 : TALER_amount_cmp_currency (reserve_balance,
2075 : withdraw_fee_balance));
2076 :
2077 0 : return GNUNET_PQ_eval_prepared_non_select (pg->conn,
2078 : "auditor_reserve_balance_insert",
2079 : params);
2080 : }
2081 :
2082 :
2083 : /**
2084 : * Update information about all reserves. Destructively updates an
2085 : * existing record, which must already exist.
2086 : *
2087 : * @param cls the @e cls of this struct with the plugin-specific state
2088 : * @param master_pub master public key of the exchange
2089 : * @param reserve_balance amount stored in the reserve
2090 : * @param withdraw_fee_balance amount the exchange gained in withdraw fees
2091 : * due to withdrawals from this reserve
2092 : * @param purse_fee_balance amount the exchange gained in purse fees
2093 : * @param history_fee_balance amount the exchange gained in history fees
2094 : * @return transaction status code
2095 : */
2096 : static enum GNUNET_DB_QueryStatus
2097 0 : postgres_update_reserve_summary (
2098 : void *cls,
2099 : const struct TALER_MasterPublicKeyP *master_pub,
2100 : const struct TALER_Amount *reserve_balance,
2101 : const struct TALER_Amount *withdraw_fee_balance,
2102 : const struct TALER_Amount *purse_fee_balance,
2103 : const struct TALER_Amount *history_fee_balance)
2104 : {
2105 0 : struct PostgresClosure *pg = cls;
2106 0 : struct GNUNET_PQ_QueryParam params[] = {
2107 0 : TALER_PQ_query_param_amount (reserve_balance),
2108 0 : TALER_PQ_query_param_amount (withdraw_fee_balance),
2109 0 : TALER_PQ_query_param_amount (purse_fee_balance),
2110 0 : TALER_PQ_query_param_amount (history_fee_balance),
2111 0 : GNUNET_PQ_query_param_auto_from_type (master_pub),
2112 : GNUNET_PQ_query_param_end
2113 : };
2114 :
2115 0 : return GNUNET_PQ_eval_prepared_non_select (pg->conn,
2116 : "auditor_reserve_balance_update",
2117 : params);
2118 : }
2119 :
2120 :
2121 : /**
2122 : * Get summary information about all reserves.
2123 : *
2124 : * @param cls the @e cls of this struct with the plugin-specific state
2125 : * @param master_pub master public key of the exchange
2126 : * @param[out] reserve_balance amount stored in reserves
2127 : * @param[out] withdraw_fee_balance amount the exchange gained in withdraw fees
2128 : * @param[out] purse_fee_balance amount the exchange gained in purse fees
2129 : * @param[out] history_fee_balance amount the exchange gained in history fees
2130 : * @return transaction status code
2131 : */
2132 : static enum GNUNET_DB_QueryStatus
2133 0 : postgres_get_reserve_summary (void *cls,
2134 : const struct TALER_MasterPublicKeyP *master_pub,
2135 : struct TALER_Amount *reserve_balance,
2136 : struct TALER_Amount *withdraw_fee_balance,
2137 : struct TALER_Amount *purse_fee_balance,
2138 : struct TALER_Amount *history_fee_balance)
2139 : {
2140 0 : struct PostgresClosure *pg = cls;
2141 0 : struct GNUNET_PQ_QueryParam params[] = {
2142 0 : GNUNET_PQ_query_param_auto_from_type (master_pub),
2143 : GNUNET_PQ_query_param_end
2144 : };
2145 0 : struct GNUNET_PQ_ResultSpec rs[] = {
2146 0 : TALER_PQ_RESULT_SPEC_AMOUNT ("reserve_balance", reserve_balance),
2147 0 : TALER_PQ_RESULT_SPEC_AMOUNT ("withdraw_fee_balance", withdraw_fee_balance),
2148 0 : TALER_PQ_RESULT_SPEC_AMOUNT ("purse_fee_balance", purse_fee_balance),
2149 0 : TALER_PQ_RESULT_SPEC_AMOUNT ("history_fee_balance", history_fee_balance),
2150 : GNUNET_PQ_result_spec_end
2151 : };
2152 :
2153 0 : return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
2154 : "auditor_reserve_balance_select",
2155 : params,
2156 : rs);
2157 : }
2158 :
2159 :
2160 : /**
2161 : * Insert information about exchange's wire fee balance. There must not be an
2162 : * existing record for the same @a master_pub.
2163 : *
2164 : * @param cls the @e cls of this struct with the plugin-specific state
2165 : * @param master_pub master public key of the exchange
2166 : * @param wire_fee_balance amount the exchange gained in wire fees
2167 : * @return transaction status code
2168 : */
2169 : static enum GNUNET_DB_QueryStatus
2170 0 : postgres_insert_wire_fee_summary (
2171 : void *cls,
2172 : const struct TALER_MasterPublicKeyP *master_pub,
2173 : const struct TALER_Amount *wire_fee_balance)
2174 : {
2175 0 : struct PostgresClosure *pg = cls;
2176 0 : struct GNUNET_PQ_QueryParam params[] = {
2177 0 : GNUNET_PQ_query_param_auto_from_type (master_pub),
2178 0 : TALER_PQ_query_param_amount (wire_fee_balance),
2179 : GNUNET_PQ_query_param_end
2180 : };
2181 :
2182 0 : return GNUNET_PQ_eval_prepared_non_select (pg->conn,
2183 : "auditor_wire_fee_balance_insert",
2184 : params);
2185 : }
2186 :
2187 :
2188 : /**
2189 : * Insert information about exchange's wire fee balance. Destructively updates an
2190 : * existing record, which must already exist.
2191 : *
2192 : * @param cls the @e cls of this struct with the plugin-specific state
2193 : * @param master_pub master public key of the exchange
2194 : * @param wire_fee_balance amount the exchange gained in wire fees
2195 : * @return transaction status code
2196 : */
2197 : static enum GNUNET_DB_QueryStatus
2198 0 : postgres_update_wire_fee_summary (
2199 : void *cls,
2200 : const struct TALER_MasterPublicKeyP *master_pub,
2201 : const struct TALER_Amount *wire_fee_balance)
2202 : {
2203 0 : struct PostgresClosure *pg = cls;
2204 0 : struct GNUNET_PQ_QueryParam params[] = {
2205 0 : TALER_PQ_query_param_amount (wire_fee_balance),
2206 0 : GNUNET_PQ_query_param_auto_from_type (master_pub),
2207 : GNUNET_PQ_query_param_end
2208 : };
2209 :
2210 0 : return GNUNET_PQ_eval_prepared_non_select (pg->conn,
2211 : "auditor_wire_fee_balance_update",
2212 : params);
2213 : }
2214 :
2215 :
2216 : /**
2217 : * Get summary information about an exchanges wire fee balance.
2218 : *
2219 : * @param cls the @e cls of this struct with the plugin-specific state
2220 : * @param master_pub master public key of the exchange
2221 : * @param[out] wire_fee_balance set amount the exchange gained in wire fees
2222 : * @return transaction status code
2223 : */
2224 : static enum GNUNET_DB_QueryStatus
2225 0 : postgres_get_wire_fee_summary (void *cls,
2226 : const struct TALER_MasterPublicKeyP *master_pub,
2227 : struct TALER_Amount *wire_fee_balance)
2228 : {
2229 0 : struct PostgresClosure *pg = cls;
2230 0 : struct GNUNET_PQ_QueryParam params[] = {
2231 0 : GNUNET_PQ_query_param_auto_from_type (master_pub),
2232 : GNUNET_PQ_query_param_end
2233 : };
2234 0 : struct GNUNET_PQ_ResultSpec rs[] = {
2235 0 : TALER_PQ_RESULT_SPEC_AMOUNT ("wire_fee_balance",
2236 : wire_fee_balance),
2237 : GNUNET_PQ_result_spec_end
2238 : };
2239 :
2240 0 : return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
2241 : "auditor_wire_fee_balance_select",
2242 : params,
2243 : rs);
2244 : }
2245 :
2246 :
2247 : /**
2248 : * Insert information about a denomination key's balances. There
2249 : * must not be an existing record for the denomination key.
2250 : *
2251 : * @param cls the @e cls of this struct with the plugin-specific state
2252 : * @param denom_pub_hash hash of the denomination public key
2253 : * @param denom_balance value of coins outstanding with this denomination key
2254 : * @param denom_loss value of coins redeemed that were not outstanding (effectively, negative @a denom_balance)
2255 : * @param denom_risk value of coins issued with this denomination key
2256 : * @param recoup_loss losses from recoup (if this denomination was revoked)
2257 : * @param num_issued how many coins of this denomination did the exchange blind-sign
2258 : * @return transaction status code
2259 : */
2260 : static enum GNUNET_DB_QueryStatus
2261 0 : postgres_insert_denomination_balance (
2262 : void *cls,
2263 : const struct TALER_DenominationHashP *denom_pub_hash,
2264 : const struct TALER_Amount *denom_balance,
2265 : const struct TALER_Amount *denom_loss,
2266 : const struct TALER_Amount *denom_risk,
2267 : const struct TALER_Amount *recoup_loss,
2268 : uint64_t num_issued)
2269 : {
2270 0 : struct PostgresClosure *pg = cls;
2271 0 : struct GNUNET_PQ_QueryParam params[] = {
2272 0 : GNUNET_PQ_query_param_auto_from_type (denom_pub_hash),
2273 0 : TALER_PQ_query_param_amount (denom_balance),
2274 0 : TALER_PQ_query_param_amount (denom_loss),
2275 0 : GNUNET_PQ_query_param_uint64 (&num_issued),
2276 0 : TALER_PQ_query_param_amount (denom_risk),
2277 0 : TALER_PQ_query_param_amount (recoup_loss),
2278 : GNUNET_PQ_query_param_end
2279 : };
2280 :
2281 0 : return GNUNET_PQ_eval_prepared_non_select (pg->conn,
2282 : "auditor_denomination_pending_insert",
2283 : params);
2284 : }
2285 :
2286 :
2287 : /**
2288 : * Update information about a denomination key's balances. There
2289 : * must be an existing record for the denomination key.
2290 : *
2291 : * @param cls the @e cls of this struct with the plugin-specific state
2292 : * @param denom_pub_hash hash of the denomination public key
2293 : * @param denom_balance value of coins outstanding with this denomination key
2294 : * @param denom_loss value of coins redeemed that were not outstanding (effectively, negative @a denom_balance)
2295 : * @param denom_risk value of coins issued with this denomination key
2296 : * @param recoup_loss losses from recoup (if this denomination was revoked)
2297 : * @param num_issued how many coins of this denomination did the exchange blind-sign
2298 : * @return transaction status code
2299 : */
2300 : static enum GNUNET_DB_QueryStatus
2301 0 : postgres_update_denomination_balance (
2302 : void *cls,
2303 : const struct TALER_DenominationHashP *denom_pub_hash,
2304 : const struct TALER_Amount *denom_balance,
2305 : const struct TALER_Amount *denom_loss,
2306 : const struct TALER_Amount *denom_risk,
2307 : const struct TALER_Amount *recoup_loss,
2308 : uint64_t num_issued)
2309 : {
2310 0 : struct PostgresClosure *pg = cls;
2311 0 : struct GNUNET_PQ_QueryParam params[] = {
2312 0 : TALER_PQ_query_param_amount (denom_balance),
2313 0 : TALER_PQ_query_param_amount (denom_loss),
2314 0 : GNUNET_PQ_query_param_uint64 (&num_issued),
2315 0 : TALER_PQ_query_param_amount (denom_risk),
2316 0 : TALER_PQ_query_param_amount (recoup_loss),
2317 0 : GNUNET_PQ_query_param_auto_from_type (denom_pub_hash),
2318 : GNUNET_PQ_query_param_end
2319 : };
2320 :
2321 0 : return GNUNET_PQ_eval_prepared_non_select (pg->conn,
2322 : "auditor_denomination_pending_update",
2323 : params);
2324 : }
2325 :
2326 :
2327 : /**
2328 : * Get information about a denomination key's balances.
2329 : *
2330 : * @param cls the @e cls of this struct with the plugin-specific state
2331 : * @param denom_pub_hash hash of the denomination public key
2332 : * @param[out] denom_balance value of coins outstanding with this denomination key
2333 : * @param[out] denom_risk value of coins issued with this denomination key
2334 : * @param[out] denom_loss value of coins redeemed that were not outstanding (effectively, negative @a denom_balance)
2335 : * @param[out] recoup_loss losses from recoup (if this denomination was revoked)
2336 : * @param[out] num_issued how many coins of this denomination did the exchange blind-sign
2337 : * @return transaction status code
2338 : */
2339 : static enum GNUNET_DB_QueryStatus
2340 0 : postgres_get_denomination_balance (
2341 : void *cls,
2342 : const struct TALER_DenominationHashP *denom_pub_hash,
2343 : struct TALER_Amount *denom_balance,
2344 : struct TALER_Amount *denom_loss,
2345 : struct TALER_Amount *denom_risk,
2346 : struct TALER_Amount *recoup_loss,
2347 : uint64_t *num_issued)
2348 : {
2349 0 : struct PostgresClosure *pg = cls;
2350 0 : struct GNUNET_PQ_QueryParam params[] = {
2351 0 : GNUNET_PQ_query_param_auto_from_type (denom_pub_hash),
2352 : GNUNET_PQ_query_param_end
2353 : };
2354 0 : struct GNUNET_PQ_ResultSpec rs[] = {
2355 0 : TALER_PQ_RESULT_SPEC_AMOUNT ("denom_balance", denom_balance),
2356 0 : TALER_PQ_RESULT_SPEC_AMOUNT ("denom_loss", denom_loss),
2357 0 : TALER_PQ_RESULT_SPEC_AMOUNT ("denom_risk", denom_risk),
2358 0 : TALER_PQ_RESULT_SPEC_AMOUNT ("recoup_loss", recoup_loss),
2359 0 : GNUNET_PQ_result_spec_uint64 ("num_issued", num_issued),
2360 : GNUNET_PQ_result_spec_end
2361 : };
2362 :
2363 0 : return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
2364 : "auditor_denomination_pending_select",
2365 : params,
2366 : rs);
2367 : }
2368 :
2369 :
2370 : /**
2371 : * Insert information about an exchange's denomination balances. There
2372 : * must not be an existing record for the exchange.
2373 : *
2374 : * @param cls the @e cls of this struct with the plugin-specific state
2375 : * @param master_pub master key of the exchange
2376 : * @param denom_balance value of coins outstanding with this denomination key
2377 : * @param deposit_fee_balance total deposit fees collected for this DK
2378 : * @param melt_fee_balance total melt fees collected for this DK
2379 : * @param refund_fee_balance total refund fees collected for this DK
2380 : * @param risk maximum risk exposure of the exchange
2381 : * @param loss materialized @a risk from recoup
2382 : * @param irregular_recoup recoups on non-revoked coins
2383 : * @return transaction status code
2384 : */
2385 : static enum GNUNET_DB_QueryStatus
2386 0 : postgres_insert_balance_summary (
2387 : void *cls,
2388 : const struct TALER_MasterPublicKeyP *master_pub,
2389 : const struct TALER_Amount *denom_balance,
2390 : const struct TALER_Amount *deposit_fee_balance,
2391 : const struct TALER_Amount *melt_fee_balance,
2392 : const struct TALER_Amount *refund_fee_balance,
2393 : const struct TALER_Amount *risk,
2394 : const struct TALER_Amount *loss,
2395 : const struct TALER_Amount *irregular_recoup)
2396 : {
2397 0 : struct PostgresClosure *pg = cls;
2398 0 : struct GNUNET_PQ_QueryParam params[] = {
2399 0 : GNUNET_PQ_query_param_auto_from_type (master_pub),
2400 0 : TALER_PQ_query_param_amount (denom_balance),
2401 0 : TALER_PQ_query_param_amount (deposit_fee_balance),
2402 0 : TALER_PQ_query_param_amount (melt_fee_balance),
2403 0 : TALER_PQ_query_param_amount (refund_fee_balance),
2404 0 : TALER_PQ_query_param_amount (risk),
2405 0 : TALER_PQ_query_param_amount (loss),
2406 0 : TALER_PQ_query_param_amount (irregular_recoup),
2407 : GNUNET_PQ_query_param_end
2408 : };
2409 :
2410 0 : GNUNET_assert (GNUNET_YES ==
2411 : TALER_amount_cmp_currency (denom_balance,
2412 : deposit_fee_balance));
2413 0 : GNUNET_assert (GNUNET_YES ==
2414 : TALER_amount_cmp_currency (denom_balance,
2415 : melt_fee_balance));
2416 :
2417 0 : GNUNET_assert (GNUNET_YES ==
2418 : TALER_amount_cmp_currency (denom_balance,
2419 : refund_fee_balance));
2420 :
2421 0 : return GNUNET_PQ_eval_prepared_non_select (pg->conn,
2422 : "auditor_balance_summary_insert",
2423 : params);
2424 : }
2425 :
2426 :
2427 : /**
2428 : * Update information about an exchange's denomination balances. There
2429 : * must be an existing record for the exchange.
2430 : *
2431 : * @param cls the @e cls of this struct with the plugin-specific state
2432 : * @param master_pub master key of the exchange
2433 : * @param denom_balance value of coins outstanding with this denomination key
2434 : * @param deposit_fee_balance total deposit fees collected for this DK
2435 : * @param melt_fee_balance total melt fees collected for this DK
2436 : * @param refund_fee_balance total refund fees collected for this DK
2437 : * @param risk maximum risk exposure of the exchange
2438 : * @param loss materialized @a risk from recoup
2439 : * @param irregular_recoup recoups made on non-revoked coins
2440 : * @return transaction status code
2441 : */
2442 : static enum GNUNET_DB_QueryStatus
2443 0 : postgres_update_balance_summary (
2444 : void *cls,
2445 : const struct TALER_MasterPublicKeyP *master_pub,
2446 : const struct TALER_Amount *denom_balance,
2447 : const struct TALER_Amount *deposit_fee_balance,
2448 : const struct TALER_Amount *melt_fee_balance,
2449 : const struct TALER_Amount *refund_fee_balance,
2450 : const struct TALER_Amount *risk,
2451 : const struct TALER_Amount *loss,
2452 : const struct TALER_Amount *irregular_recoup)
2453 : {
2454 0 : struct PostgresClosure *pg = cls;
2455 0 : struct GNUNET_PQ_QueryParam params[] = {
2456 0 : TALER_PQ_query_param_amount (denom_balance),
2457 0 : TALER_PQ_query_param_amount (deposit_fee_balance),
2458 0 : TALER_PQ_query_param_amount (melt_fee_balance),
2459 0 : TALER_PQ_query_param_amount (refund_fee_balance),
2460 0 : TALER_PQ_query_param_amount (risk),
2461 0 : TALER_PQ_query_param_amount (loss),
2462 0 : TALER_PQ_query_param_amount (irregular_recoup),
2463 0 : GNUNET_PQ_query_param_auto_from_type (master_pub),
2464 : GNUNET_PQ_query_param_end
2465 : };
2466 :
2467 0 : return GNUNET_PQ_eval_prepared_non_select (pg->conn,
2468 : "auditor_balance_summary_update",
2469 : params);
2470 : }
2471 :
2472 :
2473 : /**
2474 : * Get information about an exchange's denomination balances.
2475 : *
2476 : * @param cls the @e cls of this struct with the plugin-specific state
2477 : * @param master_pub master key of the exchange
2478 : * @param[out] denom_balance value of coins outstanding with this denomination key
2479 : * @param[out] deposit_fee_balance total deposit fees collected for this DK
2480 : * @param[out] melt_fee_balance total melt fees collected for this DK
2481 : * @param[out] refund_fee_balance total refund fees collected for this DK
2482 : * @param[out] risk maximum risk exposure of the exchange
2483 : * @param[out] loss losses from recoup (on revoked denominations)
2484 : * @param[out] irregular_recoup recoups on NOT revoked denominations
2485 : * @return transaction status code
2486 : */
2487 : static enum GNUNET_DB_QueryStatus
2488 0 : postgres_get_balance_summary (void *cls,
2489 : const struct TALER_MasterPublicKeyP *master_pub,
2490 : struct TALER_Amount *denom_balance,
2491 : struct TALER_Amount *deposit_fee_balance,
2492 : struct TALER_Amount *melt_fee_balance,
2493 : struct TALER_Amount *refund_fee_balance,
2494 : struct TALER_Amount *risk,
2495 : struct TALER_Amount *loss,
2496 : struct TALER_Amount *irregular_recoup)
2497 : {
2498 0 : struct PostgresClosure *pg = cls;
2499 0 : struct GNUNET_PQ_QueryParam params[] = {
2500 0 : GNUNET_PQ_query_param_auto_from_type (master_pub),
2501 : GNUNET_PQ_query_param_end
2502 : };
2503 0 : struct GNUNET_PQ_ResultSpec rs[] = {
2504 0 : TALER_PQ_RESULT_SPEC_AMOUNT ("denom_balance", denom_balance),
2505 0 : TALER_PQ_RESULT_SPEC_AMOUNT ("deposit_fee_balance", deposit_fee_balance),
2506 0 : TALER_PQ_RESULT_SPEC_AMOUNT ("melt_fee_balance", melt_fee_balance),
2507 0 : TALER_PQ_RESULT_SPEC_AMOUNT ("refund_fee_balance", refund_fee_balance),
2508 0 : TALER_PQ_RESULT_SPEC_AMOUNT ("risk", risk),
2509 0 : TALER_PQ_RESULT_SPEC_AMOUNT ("loss", loss),
2510 0 : TALER_PQ_RESULT_SPEC_AMOUNT ("irregular_recoup", irregular_recoup),
2511 : GNUNET_PQ_result_spec_end
2512 : };
2513 :
2514 0 : return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
2515 : "auditor_balance_summary_select",
2516 : params,
2517 : rs);
2518 : }
2519 :
2520 :
2521 : /**
2522 : * Insert information about an exchange's historic
2523 : * revenue about a denomination key.
2524 : *
2525 : * @param cls the @e cls of this struct with the plugin-specific state
2526 : * @param master_pub master key of the exchange
2527 : * @param denom_pub_hash hash of the denomination key
2528 : * @param revenue_timestamp when did this profit get realized
2529 : * @param revenue_balance what was the total profit made from
2530 : * deposit fees, melting fees, refresh fees
2531 : * and coins that were never returned?
2532 : * @param loss_balance total losses suffered by the exchange at the time
2533 : * @return transaction status code
2534 : */
2535 : static enum GNUNET_DB_QueryStatus
2536 0 : postgres_insert_historic_denom_revenue (
2537 : void *cls,
2538 : const struct TALER_MasterPublicKeyP *master_pub,
2539 : const struct TALER_DenominationHashP *denom_pub_hash,
2540 : struct GNUNET_TIME_Timestamp revenue_timestamp,
2541 : const struct TALER_Amount *revenue_balance,
2542 : const struct TALER_Amount *loss_balance)
2543 : {
2544 0 : struct PostgresClosure *pg = cls;
2545 0 : struct GNUNET_PQ_QueryParam params[] = {
2546 0 : GNUNET_PQ_query_param_auto_from_type (master_pub),
2547 0 : GNUNET_PQ_query_param_auto_from_type (denom_pub_hash),
2548 0 : GNUNET_PQ_query_param_timestamp (&revenue_timestamp),
2549 0 : TALER_PQ_query_param_amount (revenue_balance),
2550 0 : TALER_PQ_query_param_amount (loss_balance),
2551 : GNUNET_PQ_query_param_end
2552 : };
2553 :
2554 0 : return GNUNET_PQ_eval_prepared_non_select (pg->conn,
2555 : "auditor_historic_denomination_revenue_insert",
2556 : params);
2557 : }
2558 :
2559 :
2560 : /**
2561 : * Closure for #historic_denom_revenue_cb().
2562 : */
2563 : struct HistoricDenomRevenueContext
2564 : {
2565 : /**
2566 : * Function to call for each result.
2567 : */
2568 : TALER_AUDITORDB_HistoricDenominationRevenueDataCallback cb;
2569 :
2570 : /**
2571 : * Closure for @e cb.
2572 : */
2573 : void *cb_cls;
2574 :
2575 : /**
2576 : * Plugin context.
2577 : */
2578 : struct PostgresClosure *pg;
2579 :
2580 : /**
2581 : * Number of results processed.
2582 : */
2583 : enum GNUNET_DB_QueryStatus qs;
2584 : };
2585 :
2586 :
2587 : /**
2588 : * Helper function for #postgres_select_historic_denom_revenue().
2589 : * To be called with the results of a SELECT statement
2590 : * that has returned @a num_results results.
2591 : *
2592 : * @param cls closure of type `struct HistoricRevenueContext *`
2593 : * @param result the postgres result
2594 : * @param num_results the number of results in @a result
2595 : */
2596 : static void
2597 0 : historic_denom_revenue_cb (void *cls,
2598 : PGresult *result,
2599 : unsigned int num_results)
2600 : {
2601 0 : struct HistoricDenomRevenueContext *hrc = cls;
2602 0 : struct PostgresClosure *pg = hrc->pg;
2603 :
2604 0 : for (unsigned int i = 0; i < num_results; i++)
2605 : {
2606 : struct TALER_DenominationHashP denom_pub_hash;
2607 : struct GNUNET_TIME_Timestamp revenue_timestamp;
2608 : struct TALER_Amount revenue_balance;
2609 : struct TALER_Amount loss;
2610 0 : struct GNUNET_PQ_ResultSpec rs[] = {
2611 0 : GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash",
2612 : &denom_pub_hash),
2613 0 : GNUNET_PQ_result_spec_timestamp ("revenue_timestamp",
2614 : &revenue_timestamp),
2615 0 : TALER_PQ_RESULT_SPEC_AMOUNT ("revenue_balance",
2616 : &revenue_balance),
2617 0 : TALER_PQ_RESULT_SPEC_AMOUNT ("loss_balance",
2618 : &loss),
2619 : GNUNET_PQ_result_spec_end
2620 : };
2621 :
2622 0 : if (GNUNET_OK !=
2623 0 : GNUNET_PQ_extract_result (result,
2624 : rs,
2625 : i))
2626 : {
2627 0 : GNUNET_break (0);
2628 0 : hrc->qs = GNUNET_DB_STATUS_HARD_ERROR;
2629 0 : return;
2630 : }
2631 :
2632 0 : hrc->qs = i + 1;
2633 0 : if (GNUNET_OK !=
2634 0 : hrc->cb (hrc->cb_cls,
2635 : &denom_pub_hash,
2636 : revenue_timestamp,
2637 : &revenue_balance,
2638 : &loss))
2639 0 : break;
2640 : }
2641 : }
2642 :
2643 :
2644 : /**
2645 : * Obtain all of the historic denomination key revenue
2646 : * of the given @a master_pub.
2647 : *
2648 : * @param cls the @e cls of this struct with the plugin-specific state
2649 : * @param master_pub master key of the exchange
2650 : * @param cb function to call with the results
2651 : * @param cb_cls closure for @a cb
2652 : * @return transaction status code
2653 : */
2654 : static enum GNUNET_DB_QueryStatus
2655 0 : postgres_select_historic_denom_revenue (
2656 : void *cls,
2657 : const struct TALER_MasterPublicKeyP *master_pub,
2658 : TALER_AUDITORDB_HistoricDenominationRevenueDataCallback cb,
2659 : void *cb_cls)
2660 : {
2661 0 : struct PostgresClosure *pg = cls;
2662 0 : struct GNUNET_PQ_QueryParam params[] = {
2663 0 : GNUNET_PQ_query_param_auto_from_type (master_pub),
2664 : GNUNET_PQ_query_param_end
2665 : };
2666 0 : struct HistoricDenomRevenueContext hrc = {
2667 : .cb = cb,
2668 : .cb_cls = cb_cls,
2669 : .pg = pg
2670 : };
2671 : enum GNUNET_DB_QueryStatus qs;
2672 :
2673 0 : qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
2674 : "auditor_historic_denomination_revenue_select",
2675 : params,
2676 : &historic_denom_revenue_cb,
2677 : &hrc);
2678 0 : if (qs <= 0)
2679 0 : return qs;
2680 0 : return hrc.qs;
2681 : }
2682 :
2683 :
2684 : /**
2685 : * Insert information about an exchange's historic revenue from reserves.
2686 : *
2687 : * @param cls the @e cls of this struct with the plugin-specific state
2688 : * @param master_pub master key of the exchange
2689 : * @param start_time beginning of aggregated time interval
2690 : * @param end_time end of aggregated time interval
2691 : * @param reserve_profits total profits made
2692 : * @return transaction status code
2693 : */
2694 : static enum GNUNET_DB_QueryStatus
2695 0 : postgres_insert_historic_reserve_revenue (
2696 : void *cls,
2697 : const struct TALER_MasterPublicKeyP *master_pub,
2698 : struct GNUNET_TIME_Timestamp start_time,
2699 : struct GNUNET_TIME_Timestamp end_time,
2700 : const struct TALER_Amount *reserve_profits)
2701 : {
2702 0 : struct PostgresClosure *pg = cls;
2703 0 : struct GNUNET_PQ_QueryParam params[] = {
2704 0 : GNUNET_PQ_query_param_auto_from_type (master_pub),
2705 0 : GNUNET_PQ_query_param_timestamp (&start_time),
2706 0 : GNUNET_PQ_query_param_timestamp (&end_time),
2707 0 : TALER_PQ_query_param_amount (reserve_profits),
2708 : GNUNET_PQ_query_param_end
2709 : };
2710 :
2711 0 : return GNUNET_PQ_eval_prepared_non_select (pg->conn,
2712 : "auditor_historic_reserve_summary_insert",
2713 : params);
2714 : }
2715 :
2716 :
2717 : /**
2718 : * Closure for #historic_reserve_revenue_cb().
2719 : */
2720 : struct HistoricReserveRevenueContext
2721 : {
2722 : /**
2723 : * Function to call for each result.
2724 : */
2725 : TALER_AUDITORDB_HistoricReserveRevenueDataCallback cb;
2726 :
2727 : /**
2728 : * Closure for @e cb.
2729 : */
2730 : void *cb_cls;
2731 :
2732 : /**
2733 : * Plugin context.
2734 : */
2735 : struct PostgresClosure *pg;
2736 :
2737 : /**
2738 : * Number of results processed.
2739 : */
2740 : enum GNUNET_DB_QueryStatus qs;
2741 : };
2742 :
2743 :
2744 : /**
2745 : * Helper function for #postgres_select_historic_reserve_revenue().
2746 : * To be called with the results of a SELECT statement
2747 : * that has returned @a num_results results.
2748 : *
2749 : * @param cls closure of type `struct HistoricRevenueContext *`
2750 : * @param result the postgres result
2751 : * @param num_results the number of results in @a result
2752 : */
2753 : static void
2754 0 : historic_reserve_revenue_cb (void *cls,
2755 : PGresult *result,
2756 : unsigned int num_results)
2757 : {
2758 0 : struct HistoricReserveRevenueContext *hrc = cls;
2759 0 : struct PostgresClosure *pg = hrc->pg;
2760 :
2761 0 : for (unsigned int i = 0; i < num_results; i++)
2762 : {
2763 : struct GNUNET_TIME_Timestamp start_date;
2764 : struct GNUNET_TIME_Timestamp end_date;
2765 : struct TALER_Amount reserve_profits;
2766 0 : struct GNUNET_PQ_ResultSpec rs[] = {
2767 0 : GNUNET_PQ_result_spec_timestamp ("start_date",
2768 : &start_date),
2769 0 : GNUNET_PQ_result_spec_timestamp ("end_date",
2770 : &end_date),
2771 0 : TALER_PQ_RESULT_SPEC_AMOUNT ("reserve_profits",
2772 : &reserve_profits),
2773 : GNUNET_PQ_result_spec_end
2774 : };
2775 :
2776 0 : if (GNUNET_OK !=
2777 0 : GNUNET_PQ_extract_result (result,
2778 : rs,
2779 : i))
2780 : {
2781 0 : GNUNET_break (0);
2782 0 : hrc->qs = GNUNET_DB_STATUS_HARD_ERROR;
2783 0 : return;
2784 : }
2785 0 : hrc->qs = i + 1;
2786 0 : if (GNUNET_OK !=
2787 0 : hrc->cb (hrc->cb_cls,
2788 : start_date,
2789 : end_date,
2790 : &reserve_profits))
2791 0 : break;
2792 : }
2793 : }
2794 :
2795 :
2796 : /**
2797 : * Return information about an exchange's historic revenue from reserves.
2798 : *
2799 : * @param cls the @e cls of this struct with the plugin-specific state
2800 : * @param master_pub master key of the exchange
2801 : * @param cb function to call with results
2802 : * @param cb_cls closure for @a cb
2803 : * @return transaction status code
2804 : */
2805 : static enum GNUNET_DB_QueryStatus
2806 0 : postgres_select_historic_reserve_revenue (
2807 : void *cls,
2808 : const struct TALER_MasterPublicKeyP *master_pub,
2809 : TALER_AUDITORDB_HistoricReserveRevenueDataCallback cb,
2810 : void *cb_cls)
2811 : {
2812 0 : struct PostgresClosure *pg = cls;
2813 0 : struct GNUNET_PQ_QueryParam params[] = {
2814 0 : GNUNET_PQ_query_param_auto_from_type (master_pub),
2815 : GNUNET_PQ_query_param_end
2816 : };
2817 : enum GNUNET_DB_QueryStatus qs;
2818 0 : struct HistoricReserveRevenueContext hrc = {
2819 : .cb = cb,
2820 : .cb_cls = cb_cls,
2821 : .pg = pg
2822 : };
2823 :
2824 0 : qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
2825 : "auditor_historic_reserve_summary_select",
2826 : params,
2827 : &historic_reserve_revenue_cb,
2828 : &hrc);
2829 0 : if (0 >= qs)
2830 0 : return qs;
2831 0 : return hrc.qs;
2832 : }
2833 :
2834 :
2835 : /**
2836 : * Insert information about the predicted exchange's bank
2837 : * account balance.
2838 : *
2839 : * @param cls the @e cls of this struct with the plugin-specific state
2840 : * @param master_pub master key of the exchange
2841 : * @param balance what the bank account balance of the exchange should show
2842 : * @param drained amount that was drained in profits
2843 : * @return transaction status code
2844 : */
2845 : static enum GNUNET_DB_QueryStatus
2846 0 : postgres_insert_predicted_result (
2847 : void *cls,
2848 : const struct TALER_MasterPublicKeyP *master_pub,
2849 : const struct TALER_Amount *balance,
2850 : const struct TALER_Amount *drained)
2851 : {
2852 0 : struct PostgresClosure *pg = cls;
2853 0 : struct GNUNET_PQ_QueryParam params[] = {
2854 0 : GNUNET_PQ_query_param_auto_from_type (master_pub),
2855 0 : TALER_PQ_query_param_amount (balance),
2856 0 : TALER_PQ_query_param_amount (drained),
2857 : GNUNET_PQ_query_param_end
2858 : };
2859 :
2860 0 : return GNUNET_PQ_eval_prepared_non_select (pg->conn,
2861 : "auditor_predicted_result_insert",
2862 : params);
2863 : }
2864 :
2865 :
2866 : /**
2867 : * Update information about an exchange's predicted balance. There
2868 : * must be an existing record for the exchange.
2869 : *
2870 : * @param cls the @e cls of this struct with the plugin-specific state
2871 : * @param master_pub master key of the exchange
2872 : * @param balance what the bank account balance of the exchange should show
2873 : * @param drained amount that was drained in profits
2874 : * @return transaction status code
2875 : */
2876 : static enum GNUNET_DB_QueryStatus
2877 0 : postgres_update_predicted_result (
2878 : void *cls,
2879 : const struct TALER_MasterPublicKeyP *master_pub,
2880 : const struct TALER_Amount *balance,
2881 : const struct TALER_Amount *drained)
2882 : {
2883 0 : struct PostgresClosure *pg = cls;
2884 0 : struct GNUNET_PQ_QueryParam params[] = {
2885 0 : TALER_PQ_query_param_amount (balance),
2886 0 : TALER_PQ_query_param_amount (drained),
2887 0 : GNUNET_PQ_query_param_auto_from_type (master_pub),
2888 : GNUNET_PQ_query_param_end
2889 : };
2890 :
2891 0 : return GNUNET_PQ_eval_prepared_non_select (pg->conn,
2892 : "auditor_predicted_result_update",
2893 : params);
2894 : }
2895 :
2896 :
2897 : /**
2898 : * Get an exchange's predicted balance.
2899 : *
2900 : * @param cls the @e cls of this struct with the plugin-specific state
2901 : * @param master_pub master key of the exchange
2902 : * @param[out] balance expected bank account balance of the exchange
2903 : * @param[out] drained amount drained so far
2904 : * @return transaction status code
2905 : */
2906 : static enum GNUNET_DB_QueryStatus
2907 0 : postgres_get_predicted_balance (void *cls,
2908 : const struct TALER_MasterPublicKeyP *master_pub,
2909 : struct TALER_Amount *balance,
2910 : struct TALER_Amount *drained)
2911 : {
2912 0 : struct PostgresClosure *pg = cls;
2913 0 : struct GNUNET_PQ_QueryParam params[] = {
2914 0 : GNUNET_PQ_query_param_auto_from_type (master_pub),
2915 : GNUNET_PQ_query_param_end
2916 : };
2917 0 : struct GNUNET_PQ_ResultSpec rs[] = {
2918 0 : TALER_PQ_RESULT_SPEC_AMOUNT ("balance",
2919 : balance),
2920 0 : TALER_PQ_RESULT_SPEC_AMOUNT ("drained",
2921 : drained),
2922 : GNUNET_PQ_result_spec_end
2923 : };
2924 :
2925 0 : return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
2926 : "auditor_predicted_result_select",
2927 : params,
2928 : rs);
2929 : }
2930 :
2931 :
2932 : /**
2933 : * Initialize Postgres database subsystem.
2934 : *
2935 : * @param cls a configuration instance
2936 : * @return NULL on error, otherwise a `struct TALER_AUDITORDB_Plugin`
2937 : */
2938 : void *
2939 1 : libtaler_plugin_auditordb_postgres_init (void *cls)
2940 : {
2941 1 : const struct GNUNET_CONFIGURATION_Handle *cfg = cls;
2942 : struct PostgresClosure *pg;
2943 : struct TALER_AUDITORDB_Plugin *plugin;
2944 :
2945 1 : pg = GNUNET_new (struct PostgresClosure);
2946 1 : pg->cfg = cfg;
2947 1 : if (GNUNET_OK !=
2948 1 : TALER_config_get_currency (cfg,
2949 : &pg->currency))
2950 : {
2951 0 : GNUNET_free (pg);
2952 0 : return NULL;
2953 : }
2954 1 : plugin = GNUNET_new (struct TALER_AUDITORDB_Plugin);
2955 1 : plugin->cls = pg;
2956 1 : plugin->preflight = &postgres_preflight;
2957 1 : plugin->drop_tables = &postgres_drop_tables;
2958 1 : plugin->create_tables = &postgres_create_tables;
2959 1 : plugin->start = &postgres_start;
2960 1 : plugin->commit = &postgres_commit;
2961 1 : plugin->rollback = &postgres_rollback;
2962 1 : plugin->gc = &postgres_gc;
2963 :
2964 1 : plugin->insert_exchange = &postgres_insert_exchange;
2965 1 : plugin->delete_exchange = &postgres_delete_exchange;
2966 1 : plugin->list_exchanges = &postgres_list_exchanges;
2967 1 : plugin->insert_exchange_signkey = &postgres_insert_exchange_signkey;
2968 1 : plugin->insert_deposit_confirmation = &postgres_insert_deposit_confirmation;
2969 1 : plugin->get_deposit_confirmations = &postgres_get_deposit_confirmations;
2970 :
2971 1 : plugin->get_auditor_progress_reserve = &postgres_get_auditor_progress_reserve;
2972 1 : plugin->update_auditor_progress_reserve =
2973 : &postgres_update_auditor_progress_reserve;
2974 1 : plugin->insert_auditor_progress_reserve =
2975 : &postgres_insert_auditor_progress_reserve;
2976 1 : plugin->get_auditor_progress_aggregation =
2977 : &postgres_get_auditor_progress_aggregation;
2978 1 : plugin->update_auditor_progress_aggregation =
2979 : &postgres_update_auditor_progress_aggregation;
2980 1 : plugin->insert_auditor_progress_aggregation =
2981 : &postgres_insert_auditor_progress_aggregation;
2982 1 : plugin->get_auditor_progress_deposit_confirmation =
2983 : &postgres_get_auditor_progress_deposit_confirmation;
2984 1 : plugin->update_auditor_progress_deposit_confirmation =
2985 : &postgres_update_auditor_progress_deposit_confirmation;
2986 1 : plugin->insert_auditor_progress_deposit_confirmation =
2987 : &postgres_insert_auditor_progress_deposit_confirmation;
2988 1 : plugin->get_auditor_progress_coin = &postgres_get_auditor_progress_coin;
2989 1 : plugin->update_auditor_progress_coin = &postgres_update_auditor_progress_coin;
2990 1 : plugin->insert_auditor_progress_coin = &postgres_insert_auditor_progress_coin;
2991 :
2992 1 : plugin->get_wire_auditor_account_progress =
2993 : &postgres_get_wire_auditor_account_progress;
2994 1 : plugin->update_wire_auditor_account_progress =
2995 : &postgres_update_wire_auditor_account_progress;
2996 1 : plugin->insert_wire_auditor_account_progress =
2997 : &postgres_insert_wire_auditor_account_progress;
2998 1 : plugin->get_wire_auditor_progress = &postgres_get_wire_auditor_progress;
2999 1 : plugin->update_wire_auditor_progress = &postgres_update_wire_auditor_progress;
3000 1 : plugin->insert_wire_auditor_progress = &postgres_insert_wire_auditor_progress;
3001 :
3002 1 : plugin->del_reserve_info = &postgres_del_reserve_info;
3003 1 : plugin->get_reserve_info = &postgres_get_reserve_info;
3004 1 : plugin->update_reserve_info = &postgres_update_reserve_info;
3005 1 : plugin->insert_reserve_info = &postgres_insert_reserve_info;
3006 :
3007 1 : plugin->get_reserve_summary = &postgres_get_reserve_summary;
3008 1 : plugin->update_reserve_summary = &postgres_update_reserve_summary;
3009 1 : plugin->insert_reserve_summary = &postgres_insert_reserve_summary;
3010 :
3011 1 : plugin->get_wire_fee_summary = &postgres_get_wire_fee_summary;
3012 1 : plugin->update_wire_fee_summary = &postgres_update_wire_fee_summary;
3013 1 : plugin->insert_wire_fee_summary = &postgres_insert_wire_fee_summary;
3014 :
3015 1 : plugin->get_denomination_balance = &postgres_get_denomination_balance;
3016 1 : plugin->update_denomination_balance = &postgres_update_denomination_balance;
3017 1 : plugin->insert_denomination_balance = &postgres_insert_denomination_balance;
3018 :
3019 1 : plugin->get_balance_summary = &postgres_get_balance_summary;
3020 1 : plugin->update_balance_summary = &postgres_update_balance_summary;
3021 1 : plugin->insert_balance_summary = &postgres_insert_balance_summary;
3022 :
3023 1 : plugin->select_historic_denom_revenue =
3024 : &postgres_select_historic_denom_revenue;
3025 1 : plugin->insert_historic_denom_revenue =
3026 : &postgres_insert_historic_denom_revenue;
3027 :
3028 1 : plugin->select_historic_reserve_revenue =
3029 : &postgres_select_historic_reserve_revenue;
3030 1 : plugin->insert_historic_reserve_revenue =
3031 : &postgres_insert_historic_reserve_revenue;
3032 :
3033 1 : plugin->get_predicted_balance = &postgres_get_predicted_balance;
3034 1 : plugin->update_predicted_result = &postgres_update_predicted_result;
3035 1 : plugin->insert_predicted_result = &postgres_insert_predicted_result;
3036 :
3037 1 : return plugin;
3038 : }
3039 :
3040 :
3041 : /**
3042 : * Shutdown Postgres database subsystem.
3043 : *
3044 : * @param cls a `struct TALER_AUDITORDB_Plugin`
3045 : * @return NULL (always)
3046 : */
3047 : void *
3048 1 : libtaler_plugin_auditordb_postgres_done (void *cls)
3049 : {
3050 1 : struct TALER_AUDITORDB_Plugin *plugin = cls;
3051 1 : struct PostgresClosure *pg = plugin->cls;
3052 :
3053 1 : if (NULL != pg->conn)
3054 0 : GNUNET_PQ_disconnect (pg->conn);
3055 1 : GNUNET_free (pg->currency);
3056 1 : GNUNET_free (pg);
3057 1 : GNUNET_free (plugin);
3058 1 : return NULL;
3059 : }
3060 :
3061 :
3062 : /* end of plugin_auditordb_postgres.c */
|