do_insert_known_coins.h (5245B)
1 /* 2 This file is part of TALER 3 Copyright (C) 2022-2026 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/include/exchange-database/do_insert_known_coins.h 18 * @brief make a batch of coins known to the database 19 * @author Christian Grothoff 20 * @author Özgür Kesim 21 */ 22 #ifndef EXCHANGE_DATABASE_DO_INSERT_KNOWN_COINS_H 23 #define EXCHANGE_DATABASE_DO_INSERT_KNOWN_COINS_H 24 25 #include "exchangedb_lib.h" 26 27 /** 28 * Possible outcomes for one coin of a batch that is made known. 29 */ 30 enum TALER_EXCHANGEDB_CoinKnownStatus 31 { 32 /** 33 * The coin was successfully added. 34 */ 35 TALER_EXCHANGEDB_CKS_ADDED = 1, 36 37 /** 38 * The coin was already present, with the same denomination 39 * and age commitment. 40 */ 41 TALER_EXCHANGEDB_CKS_PRESENT = 0, 42 43 /** 44 * Conflicting coin (different denomination key) already in database. 45 */ 46 TALER_EXCHANGEDB_CKS_DENOM_CONFLICT = -3, 47 48 /** 49 * Conflicting coin already in database: the caller passed an age 50 * commitment hash, but the stored coin has none. 51 * 52 * Whether a coin has an age commitment hash is determined by its 53 * denomination (age-restricted or not), and the denomination 54 * signature covers it. For a caller that verified that signature, 55 * this and the following two conflicts can therefore only arise 56 * together with a #TALER_EXCHANGEDB_CKS_DENOM_CONFLICT, which is 57 * reported instead. They are kept for callers that do not verify 58 * the signature. 59 */ 60 TALER_EXCHANGEDB_CKS_AGE_CONFLICT_EXPECTED_NULL = -4, 61 62 /** 63 * Conflicting coin already in database: the caller passed no age 64 * commitment hash, but the stored coin has one. 65 */ 66 TALER_EXCHANGEDB_CKS_AGE_CONFLICT_EXPECTED_NON_NULL = -5, 67 68 /** 69 * Conflicting coin already in database: the stored age commitment 70 * hash differs from the one passed by the caller. 71 */ 72 TALER_EXCHANGEDB_CKS_AGE_CONFLICT_VALUE_DIFFERS = -6, 73 74 }; 75 76 77 /** 78 * Result of making one coin known. 79 */ 80 struct TALER_EXCHANGEDB_CoinKnownResult 81 { 82 /** 83 * What happened to the coin. 84 */ 85 enum TALER_EXCHANGEDB_CoinKnownStatus status; 86 87 /** 88 * Row of the coin in the `known_coins` table. Valid unless 89 * @e status is #TALER_EXCHANGEDB_CKS_DENOM_CONFLICT or one of 90 * the age conflicts. 91 */ 92 uint64_t known_coin_id; 93 94 /** 95 * Denomination hash of the coin as stored in the database. For a 96 * conflict, this is what the client must be told. 97 */ 98 struct TALER_DenominationHashP h_denom_pub; 99 100 /** 101 * Age commitment hash of the coin as stored in the database. Only 102 * valid if @e no_age_commitment is false. For a conflict, this is 103 * what the client must be told. 104 */ 105 struct TALER_AgeCommitmentHashP h_age_commitment; 106 107 /** 108 * True if the stored coin has no age commitment hash, which is the 109 * case exactly if its denomination is not age-restricted. Mirrors 110 * `struct TALER_CoinPublicInfo`. 111 */ 112 bool no_age_commitment; 113 }; 114 115 116 /** 117 * Make sure the given @a coins are known to the database, in one 118 * round trip. Coins that are not yet known are inserted; for coins 119 * that are already known, their stored denomination and age commitment 120 * are compared with what the caller passed and a conflict is reported 121 * per coin in @a results. The function does not abort on a conflict: 122 * the caller is expected to run it inside of a transaction and to roll 123 * that back if any entry of @a results reports a conflict, so that 124 * either all or none of the coins end up in the database. 125 * 126 * The coin public keys in @a coins must be distinct. A batch 127 * containing the same coin twice is rejected with 128 * #GNUNET_DB_STATUS_HARD_ERROR (a single INSERT cannot process the 129 * same key twice, and the caller should never build such a batch). 130 * The denomination of every coin must exist in the `denominations` 131 * table, otherwise #GNUNET_DB_STATUS_HARD_ERROR is returned as well. 132 * 133 * Primary test table: `known_coins` (see test_known_coins.c). 134 * 135 * @param pg the database context 136 * @param num_coins number of entries in @a coins and @a results 137 * @param coins the coins that must be made known 138 * @param[out] results set to the outcome for each coin, in the order 139 * of @a coins; only valid on success 140 * @return database transaction status; #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT 141 * if every coin was processed (check @a results for conflicts), 142 * negative on error 143 */ 144 enum GNUNET_DB_QueryStatus 145 TALER_EXCHANGEDB_do_insert_known_coins ( 146 struct TALER_EXCHANGEDB_PostgresContext *pg, 147 unsigned int num_coins, 148 const struct TALER_CoinPublicInfo *const coins[static num_coins], 149 struct TALER_EXCHANGEDB_CoinKnownResult results[static num_coins]); 150 151 #endif