Line data Source code
1 : /*
2 : This file is part of TALER
3 : Copyright (C) 2024 Taler Systems SA
4 :
5 : TALER is free software; you can redistribute it and/or modify it under the
6 : terms of the GNU General Public License as published by the Free Software
7 : Foundation; either version 3, or (at your option) any later version.
8 :
9 : TALER is distributed in the hope that it will be useful, but WITHOUT ANY
10 : WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 : A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12 :
13 : You should have received a copy of the GNU General Public License along with
14 : TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
15 : */
16 : /**
17 : * @file src/backenddb/insert_used_token.c
18 : * @brief Implementation of the insert_used_token function for Postgres
19 : * @author Christian Blättler
20 : */
21 : #include "platform.h"
22 : #include <taler/taler_pq_lib.h>
23 : #include "merchant-database/insert_used_token.h"
24 : #include "helper.h"
25 :
26 :
27 : enum GNUNET_DB_QueryStatus
28 8 : TALER_MERCHANTDB_insert_used_token (
29 : struct TALER_MERCHANTDB_PostgresContext *pg,
30 : const struct TALER_PrivateContractHashP *h_contract_terms,
31 : const struct TALER_TokenIssuePublicKeyHashP *h_issue_pub,
32 : const struct TALER_TokenUsePublicKeyP *use_pub,
33 : const struct TALER_TokenUseSignatureP *use_sig,
34 : const struct TALER_TokenIssueSignature *issue_sig,
35 : bool *no_family)
36 : {
37 8 : struct GNUNET_PQ_QueryParam params[] = {
38 8 : GNUNET_PQ_query_param_auto_from_type (h_contract_terms),
39 8 : GNUNET_PQ_query_param_auto_from_type (h_issue_pub),
40 8 : GNUNET_PQ_query_param_auto_from_type (use_pub),
41 8 : GNUNET_PQ_query_param_auto_from_type (use_sig),
42 8 : GNUNET_PQ_query_param_unblinded_sig (issue_sig->signature),
43 : GNUNET_PQ_query_param_end
44 : };
45 8 : bool no_fam = false;
46 8 : bool conflict = false; /* used to signal double-spending */
47 8 : struct GNUNET_PQ_ResultSpec rs[] = {
48 8 : GNUNET_PQ_result_spec_bool ("out_no_family",
49 : &no_fam),
50 8 : GNUNET_PQ_result_spec_bool ("out_conflict",
51 : &conflict),
52 : GNUNET_PQ_result_spec_end
53 : };
54 : enum GNUNET_DB_QueryStatus qs;
55 :
56 8 : GNUNET_assert (NULL != pg->current_merchant_id);
57 8 : GNUNET_log (GNUNET_ERROR_TYPE_INFO,
58 : "Storing token spent with key %s\n",
59 : GNUNET_h2s (&h_issue_pub->hash));
60 8 : TMH_PQ_prepare_anon (pg,
61 : "SELECT"
62 : " out_no_family"
63 : " ,out_conflict"
64 : " FROM merchant_do_insert_spent_token"
65 : "($1, $2, $3, $4, $5);");
66 8 : qs = GNUNET_PQ_eval_prepared_singleton_select (
67 : pg->conn,
68 : "",
69 : params,
70 : rs);
71 8 : *no_family = false;
72 8 : if (qs <= 0)
73 0 : return qs;
74 8 : if (no_fam)
75 : {
76 : /* The token family (key) was deleted after the order was created;
77 : this is a client-visible conflict, not an internal failure. */
78 1 : *no_family = true;
79 1 : return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS;
80 : }
81 7 : if (conflict)
82 : {
83 3 : GNUNET_log (GNUNET_ERROR_TYPE_INFO,
84 : "Client attempted to double-spend token\n");
85 3 : return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS;
86 : }
87 4 : return qs;
88 : }
|