exchange

Base system with REST service to issue digital coins, run by the payment service provider
Log | Files | Refs | Submodules | README | LICENSE

free_coin_transaction_list.h (15249B)


      1 /*
      2    This file is part of TALER
      3    Copyright (C) 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 free_coin_transaction_list.h
     18  * @brief implementation of the free_coin_transaction_list function for Postgres
     19  * @author Christian Grothoff
     20  */
     21 #ifndef EXCHANGE_DATABASE_FREE_COIN_TRANSACTION_LIST_H
     22 #define EXCHANGE_DATABASE_FREE_COIN_TRANSACTION_LIST_H
     23 
     24 #include "exchangedb_lib.h"
     25 
     26 
     27 /**
     28  * @brief Enumeration to classify the different types of transactions
     29  * that can be done with a coin.
     30  */
     31 enum TALER_EXCHANGEDB_TransactionType
     32 {
     33 
     34   /**
     35    * Deposit operation.
     36    */
     37   TALER_EXCHANGEDB_TT_DEPOSIT = 0,
     38 
     39   /**
     40    * Melt operation.
     41    */
     42   TALER_EXCHANGEDB_TT_MELT = 1,
     43 
     44   /**
     45    * Refund operation.
     46    */
     47   TALER_EXCHANGEDB_TT_REFUND = 2,
     48 
     49   /**
     50    * Recoup-refresh operation (on the old coin, adding to the old coin's value)
     51    */
     52   TALER_EXCHANGEDB_TT_RECOUP_REFRESH_RECEIVER = 3,
     53 
     54   /**
     55    * Recoup operation.
     56    */
     57   TALER_EXCHANGEDB_TT_RECOUP_WITHDRAW = 4,
     58 
     59   /**
     60    * Recoup-refresh operation (on the new coin, eliminating its value)
     61    */
     62   TALER_EXCHANGEDB_TT_RECOUP_REFRESH = 5,
     63 
     64   /**
     65    * Purse deposit operation.
     66    */
     67   TALER_EXCHANGEDB_TT_PURSE_DEPOSIT = 6,
     68 
     69   /**
     70    * Purse deposit operation.
     71    */
     72   TALER_EXCHANGEDB_TT_PURSE_REFUND = 7,
     73 
     74   /**
     75    * Reserve open deposit operation.
     76    */
     77   TALER_EXCHANGEDB_TT_RESERVE_OPEN = 8
     78 
     79 };
     80 
     81 
     82 /**
     83  * @brief Specification for a deposit operation in the
     84  * `struct TALER_EXCHANGEDB_TransactionList`.
     85  */
     86 struct TALER_EXCHANGEDB_DepositListEntry
     87 {
     88 
     89   /**
     90    * ECDSA signature affirming that the customer intends
     91    * this coin to be deposited at the merchant identified
     92    * by @e h_wire in relation to the proposal data identified
     93    * by @e h_contract_terms.
     94    */
     95   struct TALER_CoinSpendSignatureP csig;
     96 
     97   /**
     98    * Public key of the merchant.  Enables later identification
     99    * of the merchant in case of a need to rollback transactions.
    100    */
    101   struct TALER_MerchantPublicKeyP merchant_pub;
    102 
    103   /**
    104    * Hash over the proposa data between merchant and customer
    105    * (remains unknown to the Exchange).
    106    */
    107   struct TALER_PrivateContractHashP h_contract_terms;
    108 
    109   /**
    110    * Hash over inputs from the wallet to customize the contract.
    111    */
    112   struct GNUNET_HashCode wallet_data_hash;
    113 
    114   /**
    115    * Hash of the public denomination key used to sign the coin.
    116    */
    117   struct TALER_DenominationHashP h_denom_pub;
    118 
    119   /**
    120    * Age commitment hash, if applicable to the denomination.  Should be all
    121    * zeroes if age commitment is not applicable to the denonimation.
    122    */
    123   struct TALER_AgeCommitmentHashP h_age_commitment;
    124 
    125   /**
    126    * Salt used to compute h_wire from the @e receiver_wire_account.
    127    */
    128   struct TALER_WireSaltP wire_salt;
    129 
    130   /**
    131    * Hash over the policy data for this deposit (remains unknown to the
    132    * Exchange).  Needed for the verification of the deposit's signature
    133    */
    134   struct TALER_ExtensionPolicyHashP h_policy;
    135 
    136   /**
    137    * Fraction of the coin's remaining value to be deposited, including
    138    * depositing fee (if any).  The coin is identified by @e coin_pub.
    139    */
    140   struct TALER_Amount amount_with_fee;
    141 
    142   /**
    143    * Depositing fee.
    144    */
    145   struct TALER_Amount deposit_fee;
    146 
    147   /**
    148    * Time when this request was generated.  Used, for example, to
    149    * assess when (roughly) the income was achieved for tax purposes.
    150    * Note that the Exchange will only check that the timestamp is not "too
    151    * far" into the future (i.e. several days).  The fact that the
    152    * timestamp falls within the validity period of the coin's
    153    * denomination key is irrelevant for the validity of the deposit
    154    * request, as obviously the customer and merchant could conspire to
    155    * set any timestamp.  Also, the Exchange must accept very old deposit
    156    * requests, as the merchant might have been unable to transmit the
    157    * deposit request in a timely fashion (so back-dating is not
    158    * prevented).
    159    */
    160   struct GNUNET_TIME_Timestamp timestamp;
    161 
    162   /**
    163    * How much time does the merchant have to issue a refund request?
    164    * Zero if refunds are not allowed.  After this time, the coin
    165    * cannot be refunded.
    166    */
    167   struct GNUNET_TIME_Timestamp refund_deadline;
    168 
    169   /**
    170    * How much time does the merchant have to execute the wire transfer?
    171    * This time is advisory for aggregating transactions, not a hard
    172    * constraint (as the merchant can theoretically pick any time,
    173    * including one in the past).
    174    */
    175   struct GNUNET_TIME_Timestamp wire_deadline;
    176 
    177   /**
    178    * Detailed information about the receiver for executing the transaction.
    179    * URL in payto://-format.
    180    */
    181   struct TALER_FullPayto receiver_wire_account;
    182 
    183   /**
    184    * true, if age commitment is not applicable
    185    */
    186   bool no_age_commitment;
    187 
    188   /**
    189    * true, if wallet data hash is not present
    190    */
    191   bool no_wallet_data_hash;
    192 
    193   /**
    194    * True if a policy was provided with the deposit request
    195    */
    196   bool has_policy;
    197 
    198   /**
    199    * Has the deposit been wired?
    200    */
    201   bool done;
    202 
    203 };
    204 
    205 
    206 /**
    207  * @brief Specification for a refund operation in a coin's transaction list.
    208  */
    209 struct TALER_EXCHANGEDB_RefundListEntry
    210 {
    211 
    212   /**
    213    * Public key of the merchant.
    214    */
    215   struct TALER_MerchantPublicKeyP merchant_pub;
    216 
    217   /**
    218    * Signature from the merchant affirming the refund.
    219    */
    220   struct TALER_MerchantSignatureP merchant_sig;
    221 
    222   /**
    223    * Hash over the proposal data between merchant and customer
    224    * (remains unknown to the Exchange).
    225    */
    226   struct TALER_PrivateContractHashP h_contract_terms;
    227 
    228   /**
    229    * Merchant-generated REFUND transaction ID to detect duplicate
    230    * refunds.
    231    */
    232   uint64_t rtransaction_id;
    233 
    234   /**
    235    * Fraction of the original deposit's value to be refunded, including
    236    * refund fee (if any).  The coin is identified by @e coin_pub.
    237    */
    238   struct TALER_Amount refund_amount;
    239 
    240   /**
    241    * Refund fee to be covered by the customer.
    242    */
    243   struct TALER_Amount refund_fee;
    244 
    245 };
    246 
    247 
    248 /**
    249  * Information about a /coins/$COIN_PUB/melt operation in a coin transaction history.
    250  */
    251 struct TALER_EXCHANGEDB_MeltListEntry
    252 {
    253 
    254   /**
    255    * Signature over the melting operation.
    256    */
    257   struct TALER_CoinSpendSignatureP coin_sig;
    258 
    259   /**
    260    * Refresh commitment this coin is melted into.
    261    */
    262   struct TALER_RefreshCommitmentP rc;
    263 
    264   /**
    265    * Hash of the public denomination key used to sign the coin.
    266    */
    267   struct TALER_DenominationHashP h_denom_pub;
    268 
    269   /**
    270    * Hash of the age commitment used to sign the coin, if age restriction was
    271    * applicable to the denomination.  May be all zeroes if no age restriction
    272    * applies.
    273    */
    274   struct TALER_AgeCommitmentHashP h_age_commitment;
    275 
    276   /**
    277    * true, if no @e h_age_commitment is applicable
    278    */
    279   bool no_age_commitment;
    280 
    281   /**
    282    * How much value is being melted?  This amount includes the fees,
    283    * so the final amount contributed to the melt is this value minus
    284    * the fee for melting the coin.  We include the fee in what is
    285    * being signed so that we can verify a reserve's remaining total
    286    * balance without needing to access the respective denomination key
    287    * information each time.
    288    */
    289   struct TALER_Amount amount_with_fee;
    290 
    291   /**
    292    * Melt fee the exchange charged.
    293    */
    294   struct TALER_Amount melt_fee;
    295 
    296   /**
    297    * Index (smaller #TALER_CNC_KAPPA) which the exchange has chosen to not
    298    * have revealed during cut and choose.
    299    */
    300   uint32_t noreveal_index;
    301 
    302   /**
    303    * The refresh seed that was used for the melt operation
    304    */
    305   struct TALER_PublicRefreshMasterSeedP refresh_seed;
    306 
    307   /**
    308    * If false, @e blinding_seed is present
    309    */
    310   bool no_blinding_seed;
    311 
    312   /**
    313    * If @e no_blinding_seed it false, the blinding seed that was used
    314    * for the melt operation, in case of CS denominations.
    315    */
    316   struct TALER_BlindingMasterSeedP blinding_seed;
    317 
    318 };
    319 
    320 
    321 /**
    322  * Information the exchange records about a recoup request
    323  * in a coin history.
    324  */
    325 struct TALER_EXCHANGEDB_RecoupListEntry
    326 {
    327 
    328   /**
    329    * Blinding factor supplied to prove to the exchange that
    330    * the coin came from this reserve.
    331    */
    332   union GNUNET_CRYPTO_BlindingSecretP coin_blind;
    333 
    334   /**
    335    * Signature of the coin of type
    336    * #TALER_SIGNATURE_WALLET_COIN_RECOUP.
    337    */
    338   struct TALER_CoinSpendSignatureP coin_sig;
    339 
    340   /**
    341    * Hash of the public denomination key used to sign the coin.
    342    */
    343   struct TALER_DenominationHashP h_denom_pub;
    344 
    345   /**
    346    * Public key of the reserve the coin was paid back into.
    347    */
    348   struct TALER_ReservePublicKeyP reserve_pub;
    349 
    350   /**
    351    * How much was the coin still worth at this time?
    352    */
    353   struct TALER_Amount value;
    354 
    355   /**
    356    * When did the /recoup operation happen?
    357    */
    358   struct GNUNET_TIME_Timestamp timestamp;
    359 
    360 };
    361 
    362 
    363 /**
    364  * Information the exchange records about a recoup-refresh request in
    365  * a coin transaction history.
    366  */
    367 struct TALER_EXCHANGEDB_RecoupRefreshListEntry
    368 {
    369 
    370   /**
    371    * Information about the coin that was paid back
    372    * (NOT the coin we are considering the history of!)
    373    */
    374   struct TALER_CoinPublicInfo coin;
    375 
    376   /**
    377    * Blinding factor supplied to prove to the exchange that
    378    * the coin came from this @e old_coin_pub.
    379    */
    380   union GNUNET_CRYPTO_BlindingSecretP coin_blind;
    381 
    382   /**
    383    * Signature of the coin of type
    384    * #TALER_SIGNATURE_WALLET_COIN_RECOUP.
    385    */
    386   struct TALER_CoinSpendSignatureP coin_sig;
    387 
    388   /**
    389    * Public key of the old coin that the refreshed coin was paid back to.
    390    */
    391   struct TALER_CoinSpendPublicKeyP old_coin_pub;
    392 
    393   /**
    394    * How much was the coin still worth at this time?
    395    */
    396   struct TALER_Amount value;
    397 
    398   /**
    399    * When did the recoup operation happen?
    400    */
    401   struct GNUNET_TIME_Timestamp timestamp;
    402 
    403 };
    404 
    405 
    406 /**
    407  * Information about a /purses/$PID/deposit operation in a coin transaction history.
    408  */
    409 struct TALER_EXCHANGEDB_PurseDepositListEntry
    410 {
    411 
    412   /**
    413    * Exchange hosting the purse, NULL for this exchange.
    414    */
    415   char *exchange_base_url;
    416 
    417   /**
    418    * Public key of the purse.
    419    */
    420   struct TALER_PurseContractPublicKeyP purse_pub;
    421 
    422   /**
    423    * Contribution of the coin to the purse, including
    424    * deposit fee.
    425    */
    426   struct TALER_Amount amount;
    427 
    428   /**
    429    * Depositing fee.
    430    */
    431   struct TALER_Amount deposit_fee;
    432 
    433   /**
    434    * Signature by the coin affirming the deposit.
    435    */
    436   struct TALER_CoinSpendSignatureP coin_sig;
    437 
    438   /**
    439    * Hash of the age commitment used to sign the coin, if age restriction was
    440    * applicable to the denomination.
    441    */
    442   struct TALER_AgeCommitmentHashP h_age_commitment;
    443 
    444   /**
    445    * Hash of the public denomination key used to sign the coin.
    446    */
    447   struct TALER_DenominationHashP h_denom_pub;
    448 
    449   /**
    450    * Set to true if the coin was refunded.
    451    */
    452   bool refunded;
    453 
    454   /**
    455    * Set to true if there was no age commitment.
    456    */
    457   bool no_age_commitment;
    458 
    459 };
    460 
    461 
    462 /**
    463  * @brief Specification for a purse refund operation in a coin's transaction list.
    464  */
    465 struct TALER_EXCHANGEDB_PurseRefundListEntry
    466 {
    467 
    468   /**
    469    * Public key of the purse.
    470    */
    471   struct TALER_PurseContractPublicKeyP purse_pub;
    472 
    473   /**
    474    * Fraction of the original deposit's value to be refunded, including
    475    * refund fee (if any).  The coin is identified by @e coin_pub.
    476    */
    477   struct TALER_Amount refund_amount;
    478 
    479   /**
    480    * Refund fee to be covered by the customer.
    481    */
    482   struct TALER_Amount refund_fee;
    483 
    484 };
    485 
    486 
    487 /**
    488  * Information about a /reserves/$RID/open operation in a coin transaction history.
    489  */
    490 struct TALER_EXCHANGEDB_ReserveOpenListEntry
    491 {
    492 
    493   /**
    494    * Signature of the reserve.
    495    */
    496   struct TALER_ReserveSignatureP reserve_sig;
    497 
    498   /**
    499    * Contribution of the coin to the open fee, including
    500    * deposit fee.
    501    */
    502   struct TALER_Amount coin_contribution;
    503 
    504   /**
    505    * Signature by the coin affirming the open deposit.
    506    */
    507   struct TALER_CoinSpendSignatureP coin_sig;
    508 
    509 };
    510 
    511 
    512 /**
    513  * @brief List of transactions we performed for a particular coin.
    514  */
    515 struct TALER_EXCHANGEDB_TransactionList
    516 {
    517 
    518   /**
    519    * Next pointer in the NULL-terminated linked list.
    520    */
    521   struct TALER_EXCHANGEDB_TransactionList *next;
    522 
    523   /**
    524    * Type of the transaction, determines what is stored in @e details.
    525    */
    526   enum TALER_EXCHANGEDB_TransactionType type;
    527 
    528   /**
    529    * Serial ID of this entry in the @e type-specific table.
    530    */
    531   uint64_t serial_id;
    532 
    533   /**
    534    * Serial ID of this entry in the coin history table.
    535    */
    536   uint64_t coin_history_id;
    537 
    538   /**
    539    * Details about the transaction, depending on @e type.
    540    */
    541   union
    542   {
    543 
    544     /**
    545      * Details if transaction was a deposit operation.
    546      * (#TALER_EXCHANGEDB_TT_DEPOSIT)
    547      */
    548     struct TALER_EXCHANGEDB_DepositListEntry *deposit;
    549 
    550     /**
    551      * Details if transaction was a melt operation.
    552      * (#TALER_EXCHANGEDB_TT_MELT)
    553      */
    554     struct TALER_EXCHANGEDB_MeltListEntry *melt;
    555 
    556     /**
    557      * Details if transaction was a refund operation.
    558      * (#TALER_EXCHANGEDB_TT_REFUND)
    559      */
    560     struct TALER_EXCHANGEDB_RefundListEntry *refund;
    561 
    562     /**
    563      * Details if transaction was a recoup-refund operation where
    564      * this coin was the OLD coin.
    565      * (#TALER_EXCHANGEDB_TT_RECOUP_REFRESH_RECEIVER).
    566      */
    567     struct TALER_EXCHANGEDB_RecoupRefreshListEntry *old_coin_recoup;
    568 
    569     /**
    570      * Details if transaction was a recoup operation.
    571      * (#TALER_EXCHANGEDB_TT_RECOUP_WITHDRAW)
    572      */
    573     struct TALER_EXCHANGEDB_RecoupListEntry *recoup;
    574 
    575     /**
    576      * Details if transaction was a recoup-refund operation where
    577      * this coin was the REFRESHED coin.
    578      * (#TALER_EXCHANGEDB_TT_RECOUP_REFRESH)
    579      */
    580     struct TALER_EXCHANGEDB_RecoupRefreshListEntry *recoup_refresh;
    581 
    582     /**
    583      * Coin was deposited into a purse.
    584      * (#TALER_EXCHANGEDB_TT_PURSE_DEPOSIT)
    585      */
    586     struct TALER_EXCHANGEDB_PurseDepositListEntry *purse_deposit;
    587 
    588     /**
    589      * Coin was refunded upon purse expiration
    590      * (#TALER_EXCHANGEDB_TT_PURSE_REFUND)
    591      */
    592     struct TALER_EXCHANGEDB_PurseRefundListEntry *purse_refund;
    593 
    594     /**
    595      * Coin was used to pay to open a reserve.
    596      * (#TALER_EXCHANGEDB_TT_RESERVE_OPEN)
    597      */
    598     struct TALER_EXCHANGEDB_ReserveOpenListEntry *reserve_open;
    599 
    600   } details;
    601 
    602 };
    603 
    604 /**
    605  * Calculate the total value of all transactions performed.
    606  * Stores @a off plus the cost of all transactions in @a tl
    607  * in @a ret.
    608  *
    609  * @param tl transaction list to process
    610  * @param off offset to use as the starting value
    611  * @param[out] ret where the resulting total is to be stored
    612  * @return #GNUNET_OK on success, #GNUNET_SYSERR on errors
    613  */
    614 enum GNUNET_GenericReturnValue
    615 TALER_EXCHANGEDB_calculate_transaction_list_totals (
    616   struct TALER_EXCHANGEDB_TransactionList *tl,
    617   const struct TALER_Amount *off,
    618   struct TALER_Amount *ret);
    619 
    620 
    621 /**
    622  * Free linked list of transactions.
    623  *
    624  * @param[in] tl list to free
    625  */
    626 void
    627 TALER_EXCHANGEDB_free_coin_transaction_list (
    628   struct TALER_EXCHANGEDB_TransactionList *tl);
    629 
    630 
    631 #endif