frosix

Multiparty signature service (experimental)
Log | Files | Refs | README | LICENSE

frosix_database_plugin.h (19860B)


      1 /*
      2   This file is part of Frosix
      3   Copyright (C) 2019-2022 Anastasis SARL
      4 
      5   Frosix is free software; you can redistribute it and/or modify it under the
      6   terms of the GNU Affero General Public License as published by the Free Software
      7   Foundation; either version 3, or (at your option) any later version.
      8 
      9   Frosix 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 Affero General Public License for more details.
     12 
     13   You should have received a copy of the GNU Affero General Public License along with
     14   Frosix; see the file COPYING.GPL.  If not, see <http://www.gnu.org/licenses/>
     15 */
     16 /**
     17  * @file include/frosix_database_plugin.h
     18  * @brief database access for Frosix
     19  * @author Christian Grothoff
     20  */
     21 #ifndef FROSIX_DATABASE_PLUGIN_H
     22 #define FROSIX_DATABASE_PLUGIN_H
     23 
     24 #include "frosix_service.h"
     25 #include "frost_high.h"
     26 #include "keygen.h"
     27 #include "frosix_util_lib.h"
     28 #include <gnunet/gnunet_db_lib.h>
     29 #include <taler/taler_util.h>
     30 
     31 /**
     32  * How long is an offer for a challenge payment valid for payment?
     33  */
     34 #define FROSIX_CHALLENGE_OFFER_LIFETIME GNUNET_TIME_UNIT_HOURS
     35 
     36 /**
     37  * FIXME
     38 */
     39 enum FROSIX_DB_CommitmentStatus
     40 {
     41   /**
     42   * FIXME
     43  */
     44   FROSIX_DB_COMMITMENT_STATUS_HARD_ERROR = -2,
     45 
     46   /**
     47    * FIXME
     48   */
     49   FROSIX_DB_COMMITMENT_STATUS_SOFT_ERROR = -1,
     50 
     51   /**
     52    * FIXME
     53   */
     54   FROSIX_DB_COMMITMENT_STATUS_NO_RESULTS = 0,
     55 
     56   /**
     57    * FIXME
     58   */
     59   FROSIX_DB_COMMITMENT_STATUS_ONE_RESULT = 1,
     60 };
     61 
     62 /**
     63  * FIXME
     64 */
     65 enum FROSIX_DB_KeyStatus
     66 {
     67   /**
     68   * FIXME
     69  */
     70   FROSIX_DB_KEY_STATUS_HARD_ERROR = -2,
     71 
     72   /**
     73    * FIXME
     74   */
     75   FROSIX_DB_KEY_STATUS_SOFT_ERROR = -1,
     76 
     77   /**
     78    * FIXME
     79   */
     80   FROSIX_DB_KEY_STATUS_NO_RESULTS = 0,
     81 
     82   /**
     83    * FIXME
     84   */
     85   FROSIX_DB_KEY_STATUS_ONE_RESULT = 1,
     86 };
     87 
     88 /**
     89  * Return values for checking code validity.
     90  */
     91 enum FROSIX_DB_CodeStatus
     92 {
     93   /**
     94    * Provided authentication code does not match database content.
     95    */
     96   FROSIX_DB_CODE_STATUS_CHALLENGE_CODE_MISMATCH = -3,
     97 
     98   /**
     99    * Encountered hard error talking to DB.
    100    */
    101   FROSIX_DB_CODE_STATUS_HARD_ERROR = -2,
    102 
    103   /**
    104    * Encountered serialization error talking to DB.
    105    */
    106   FROSIX_DB_CODE_STATUS_SOFT_ERROR = -1,
    107 
    108   /**
    109    * We have no challenge in the database.
    110    */
    111   FROSIX_DB_CODE_STATUS_NO_RESULTS = 0,
    112 
    113   /**
    114    * The provided challenge matches what we have in the database.
    115    */
    116   FROSIX_DB_CODE_STATUS_VALID_CODE_STORED = 1,
    117 };
    118 
    119 
    120 /**
    121  * Return values for checking account validity.
    122  */
    123 enum FROSIX_DB_AccountStatus
    124 {
    125   /**
    126    * Account is unknown, user should pay to establish it.
    127    */
    128   FROSIX_DB_ACCOUNT_STATUS_PAYMENT_REQUIRED = -3,
    129 
    130   /**
    131    * Encountered hard error talking to DB.
    132    */
    133   FROSIX_DB_ACCOUNT_STATUS_HARD_ERROR = -2,
    134 
    135   /**
    136    * Account is valid, but we have no policy stored yet.
    137    */
    138   FROSIX_DB_ACCOUNT_STATUS_NO_RESULTS = 0,
    139 
    140   /**
    141    * Account is valid, and we have a policy stored.
    142    */
    143   FROSIX_DB_ACCOUNT_STATUS_VALID_HASH_RETURNED = 1,
    144 };
    145 
    146 
    147 /**
    148  * Return values for storing data in database with payment.
    149  */
    150 enum FROSIX_DB_StoreStatus
    151 {
    152   /**
    153    * The client has stored too many policies, should pay to store more.
    154    */
    155   FROSIX_DB_STORE_STATUS_STORE_LIMIT_EXCEEDED = -4,
    156 
    157   /**
    158    * The client needs to pay to store policies.
    159    */
    160   FROSIX_DB_STORE_STATUS_PAYMENT_REQUIRED = -3,
    161 
    162   /**
    163    * Encountered hard error talking to DB.
    164    */
    165   FROSIX_DB_STORE_STATUS_HARD_ERROR = -2,
    166 
    167   /**
    168    * Despite retrying, we encountered serialization errors.
    169    */
    170   FROSIX_DB_STORE_STATUS_SOFT_ERROR = -1,
    171 
    172   /**
    173    * Database did not need an update (document exists).
    174    */
    175   FROSIX_DB_STORE_STATUS_NO_RESULTS = 0,
    176 
    177   /**
    178    * We successfully stored the document.
    179    */
    180   FROSIX_DB_STORE_STATUS_SUCCESS = 1,
    181 };
    182 
    183 
    184 /**
    185  * Function called on all pending payments for an account or challenge.
    186  *
    187  * @param cls closure
    188  * @param timestamp for how long have we been waiting
    189  * @param payment_secret payment secret / order id in the backend
    190  * @param amount how much is the order for
    191  */
    192 typedef void
    193 (*FROSIX_DB_PaymentPendingIterator)(
    194   void *cls,
    195   struct GNUNET_TIME_Timestamp timestamp,
    196   const struct FROSIX_PaymentSecretP *payment_secret,
    197   const struct TALER_Amount *amount);
    198 
    199 
    200 /**
    201  * Function called to test if a given wire transfer
    202  * satisfied the authentication requirement of the
    203  * IBAN plugin.
    204  *
    205  * @param cls closure
    206  * @param credit amount that was transferred
    207  * @param wire_subject subject provided in the wire transfer
    208  * @return true if this wire transfer satisfied the authentication check
    209  */
    210 typedef bool
    211 (*FROSIX_DB_AuthIbanTransfercheck)(
    212   void *cls,
    213   const struct TALER_Amount *credit,
    214   const char *wire_subject);
    215 
    216 
    217 /**
    218  * Function called on matching meta data.  Note that if the client did
    219  * not provide meta data for @a version, the function will be called
    220  * with @a recovery_meta_data being NULL.
    221  *
    222  * @param cls closure
    223  * @param version the version of the recovery document
    224  * @param ts timestamp when the document was uploaded
    225  * @param recovery_meta_data contains meta data about the encrypted recovery document
    226  * @param recovery_meta_data_size size of @a recovery_meta_data blob
    227  * @return #GNUNET_OK to continue to iterate, #GNUNET_NO to abort iteration
    228  */
    229 typedef enum GNUNET_GenericReturnValue
    230 (*FROSIX_DB_RecoveryMetaCallback)(void *cls,
    231                                   uint32_t version,
    232                                   struct GNUNET_TIME_Timestamp ts,
    233                                   const void *recovery_meta_data,
    234                                   size_t recovery_meta_data_size);
    235 
    236 
    237 /**
    238  * Handle to interact with the database.
    239  *
    240  * Functions ending with "_TR" run their OWN transaction scope
    241  * and MUST NOT be called from within a transaction setup by the
    242  * caller.  Functions ending with "_NT" require the caller to
    243  * setup a transaction scope.  Functions without a suffix are
    244  * simple, single SQL queries that MAY be used either way.
    245  */
    246 struct FROSIX_DatabasePlugin
    247 {
    248 
    249   /**
    250    * Closure for all callbacks.
    251    */
    252   void *cls;
    253 
    254   /**
    255    * Name of the library which generated this plugin.  Set by the
    256    * plugin loader.
    257    */
    258   char *library_name;
    259 
    260   /**
    261    * Drop anastasis tables. Used for testcases.
    262    *
    263    * @param cls closure
    264    * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure
    265    */
    266   enum GNUNET_GenericReturnValue
    267   (*drop_tables)(void *cls);
    268 
    269   /**
    270    * Connect to the database.
    271    *
    272    * @param cls closure
    273    * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure
    274    */
    275   enum GNUNET_GenericReturnValue
    276   (*connect)(void *cls);
    277 
    278   /**
    279    * Initialize merchant tables
    280    *
    281    * @param cls closure
    282    * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure
    283    */
    284   enum GNUNET_GenericReturnValue
    285   (*create_tables)(void *cls);
    286 
    287   /**
    288    * Function called to perform "garbage collection" on the
    289    * database, expiring records we no longer require.  Deletes
    290    * all user records that are not paid up (and by cascade deletes
    291    * the associated recovery documents). Also deletes expired
    292    * truth and financial records older than @a fin_expire.
    293    *
    294    * @param cls closure
    295    * @param expire_backups backups older than the given time stamp should be garbage collected
    296    * @param expire_pending_payments payments still pending from since before
    297    *            this value should be garbage collected
    298    * @return transaction status
    299    */
    300   enum GNUNET_DB_QueryStatus
    301   (*gc)(void *cls,
    302         struct GNUNET_TIME_Absolute expire,
    303         struct GNUNET_TIME_Absolute expire_pending_payments);
    304 
    305   /**
    306   * Do a pre-flight check that we are not in an uncommitted transaction.
    307   * If we are, try to commit the previous transaction and output a warning.
    308   * Does not return anything, as we will continue regardless of the outcome.
    309   *
    310   * @param cls the `struct PostgresClosure` with the plugin-specific state
    311   * @return #GNUNET_OK if everything is fine
    312   *         #GNUNET_NO if a transaction was rolled back
    313   *         #GNUNET_SYSERR on hard errors
    314   */
    315   enum GNUNET_GenericReturnValue
    316   (*preflight)(void *cls);
    317 
    318   /**
    319   * Check that the database connection is still up.
    320   *
    321   * @param pg connection to check
    322   */
    323   void
    324   (*check_connection) (void *cls);
    325 
    326   /**
    327   * Roll back the current transaction of a database connection.
    328   *
    329   * @param cls the `struct PostgresClosure` with the plugin-specific state
    330   * @return #GNUNET_OK on success
    331   */
    332   void
    333   (*rollback) (void *cls);
    334 
    335   /**
    336    * Start a transaction.
    337    *
    338    * @param cls the `struct PostgresClosure` with the plugin-specific state
    339    * @param name unique name identifying the transaction (for debugging),
    340    *             must point to a constant
    341    * @return #GNUNET_OK on success
    342    */
    343   int
    344   (*start) (void *cls,
    345             const char *name);
    346 
    347   /**
    348    * Commit the current transaction of a database connection.
    349    *
    350    * @param cls the `struct PostgresClosure` with the plugin-specific state
    351    * @return transaction status code
    352    */
    353   enum GNUNET_DB_QueryStatus
    354   (*commit)(void *cls);
    355 
    356 
    357   /**
    358    * Register callback to be invoked on events of type @a es.
    359    *
    360    * @param cls database context to use
    361    * @param es specification of the event to listen for
    362    * @param timeout how long to wait for the event
    363    * @param cb function to call when the event happens, possibly
    364    *         multiple times (until cancel is invoked)
    365    * @param cb_cls closure for @a cb
    366    * @return handle useful to cancel the listener
    367    */
    368   struct GNUNET_DB_EventHandler *
    369   (*event_listen)(void *cls,
    370                   const struct GNUNET_DB_EventHeaderP *es,
    371                   struct GNUNET_TIME_Relative timeout,
    372                   GNUNET_DB_EventCallback cb,
    373                   void *cb_cls);
    374 
    375   /**
    376    * Stop notifications.
    377    *
    378    * @param eh handle to unregister.
    379    */
    380   void
    381   (*event_listen_cancel)(struct GNUNET_DB_EventHandler *eh);
    382 
    383 
    384   /**
    385    * Notify all that listen on @a es of an event.
    386    *
    387    * @param cls database context to use
    388    * @param es specification of the event to generate
    389    * @param extra additional event data provided
    390    * @param extra_size number of bytes in @a extra
    391    */
    392   void
    393   (*event_notify)(void *cls,
    394                   const struct GNUNET_DB_EventHeaderP *es,
    395                   const void *extra,
    396                   size_t extra_size);
    397 
    398 
    399   /**
    400    * FIXME
    401   */
    402   enum FROSIX_DB_StoreStatus
    403   (*store_dkg_commitment)(
    404     void *cls,
    405     const struct FROSIX_DkgRequestIdP *dkg_id,
    406     const struct FROSIX_DkgCommitmentsRaw *dkg_commits);
    407 
    408   /**
    409    * FIXME
    410   */
    411   enum GNUNET_DB_QueryStatus
    412   (*get_dkg_commitment)(
    413     void *cls,
    414     const struct FROSIX_DkgRequestIdP *dkg_id,
    415     struct FROSIX_DkgCommitmentsRaw *dkg_commits);
    416 
    417 
    418   /**
    419    * FIXME
    420   */
    421   enum FROSIX_DB_CommitmentStatus
    422   (*lookup_dkg_commitment)(
    423     void *cls,
    424     const struct FROSIX_DkgRequestIdP *dkg_id);
    425 
    426 
    427   /**
    428    * FIXME
    429   */
    430   enum FROSIX_DB_StoreStatus
    431   (*store_key)(
    432     void *cls,
    433     const struct FROST_HashCode *id,
    434     const struct FROSIX_EncryptionNonceP *nonce,
    435     const struct FROSIX_KeyDataEncrypted *key_data,
    436     const struct FROSIX_ChallengeHashP *challenge_hash,
    437     uint32_t expiration,
    438     uint8_t identifier);
    439 
    440 /**
    441  * FIXME
    442 */
    443   enum FROSIX_DB_KeyStatus
    444   (*lookup_key)(
    445     void *cls,
    446     const struct FROST_HashCode *id);
    447 
    448 
    449   /**
    450    * FIXME
    451   */
    452   enum GNUNET_DB_QueryStatus
    453   (*get_auth_hash)(
    454     void *cls,
    455     const struct FROST_HashCode *db_id,
    456     struct FROSIX_ChallengeHashP *challenge_hash);
    457 
    458 
    459   /**
    460    * FIXME
    461   */
    462   enum GNUNET_DB_QueryStatus
    463   (*get_key_data)(
    464     void *cls,
    465     const struct FROST_HashCode *db_id,
    466     uint32_t *identifier,
    467     struct FROSIX_EncryptionNonceP *nonce,
    468     struct FROSIX_KeyDataEncrypted *enc_key_data);
    469 
    470 
    471   /**
    472    * FIXME
    473   */
    474   enum GNUNET_DB_QueryStatus
    475   (*delete_key_data)(
    476     void *cls,
    477     const struct FROST_HashCode *db_id);
    478 
    479 
    480   /**
    481    * FIXME
    482   */
    483   enum GNUNET_DB_QueryStatus
    484   (*store_commitment_seed)(
    485     void *cls,
    486     const struct GNUNET_HashCode *db_id,
    487     const struct FROST_CommitmentSeed *seed);
    488 
    489 
    490   /**
    491    * FIXME
    492   */
    493   enum GNUNET_DB_QueryStatus
    494   (*get_and_delete_commitment_seed)(
    495     void *cls,
    496     const struct GNUNET_HashCode *db_id,
    497     struct FROST_CommitmentSeed *seed);
    498 
    499 
    500   /**
    501    * Verify the provided code with the code on the server.
    502    * If the code matches the function will return with success, if the code
    503    * does not match, the retry counter will be decreased by one.
    504    *
    505    * @param cls closure
    506    * @param truth_uuid identification of the challenge which the code corresponds to
    507    * @param hashed_code code which the user provided and wants to verify
    508    * @param[out] code set to the original numeric code
    509    * @param[out] satisfied set to true if the challenge is set to satisfied
    510    * @return transaction status
    511    */
    512   enum FROSIX_DB_CodeStatus
    513   (*verify_challenge_code)(
    514     void *cls,
    515     const struct FROSIX_ChallengeIdP *truth_uuid,
    516     const struct GNUNET_HashCode *hashed_code,
    517     uint64_t *code,
    518     bool *satisfied);
    519 
    520 
    521   /**
    522    * Set the 'satisfied' bit for the given challenge and code to
    523    * 'true'.
    524    *
    525    * @param cls closure
    526    * @param truth_uuid identification of the challenge which the code corresponds to
    527    * @param code code which is now satisfied
    528    * @return transaction status
    529    */
    530   enum GNUNET_DB_QueryStatus
    531   (*mark_challenge_code_satisfied)(
    532     void *cls,
    533     const struct FROSIX_ChallengeIdP *truth_uuid,
    534     uint64_t code);
    535 
    536 
    537   /**
    538    * Check if the 'satisfied' bit for the given challenge and code is
    539    * 'true' and the challenge code is not yet expired.
    540    *
    541    * @param cls closure
    542    * @param truth_uuid identification of the challenge which the code corresponds to
    543    * @param code code which is now satisfied
    544    * @param after after what time must the challenge have been created
    545    * @return transaction status,
    546    *        #GNUNET_DB_STATUS_SUCCESS_NO_RESULTS if the challenge code is not satisfied or expired
    547    *        #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT if the challenge code has been marked as satisfied
    548    */
    549   enum GNUNET_DB_QueryStatus
    550   (*test_challenge_code_satisfied)(
    551     void *cls,
    552     const struct FROSIX_ChallengeIdP *truth_uuid,
    553     const uint64_t code,
    554     struct GNUNET_TIME_Timestamp after);
    555 
    556 
    557   /**
    558    * Insert a new challenge code for a given challenge identified by the challenge
    559    * public key. The function will first check if there is already a valid code
    560    * for this challenge present and won't insert a new one in this case.
    561    *
    562    * @param cls closure
    563    * @param truth_uuid the identifier for the challenge
    564    * @param rotation_period for how long is the code available
    565    * @param validity_period for how long is the code available
    566    * @param retry_counter amount of retries allowed
    567    * @param[out] retransmission_date when to next retransmit
    568    * @param[out] code set to the code which will be checked for later
    569    * @return transaction status,
    570    *        #GNUNET_DB_STATUS_SUCCESS_NO_RESULTS if we are out of valid tries,
    571    *        #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT if @a code is now in the DB
    572    */
    573   enum GNUNET_DB_QueryStatus
    574   (*create_challenge_code)(
    575     void *cls,
    576     const struct FROSIX_ChallengeIdP *truth_uuid,
    577     struct GNUNET_TIME_Relative rotation_period,
    578     struct GNUNET_TIME_Relative validity_period,
    579     uint32_t retry_counter,
    580     struct GNUNET_TIME_Timestamp *retransmission_date,
    581     uint64_t *code);
    582 
    583 
    584   /**
    585    * Remember in the database that we successfully sent a challenge.
    586    *
    587    * @param cls closure
    588    * @param truth_uuid the identifier for the challenge
    589    * @param code the challenge that was sent
    590    */
    591   enum GNUNET_DB_QueryStatus
    592   (*mark_challenge_sent)(
    593     void *cls,
    594     const struct FROSIX_ChallengeIdP *truth_uuid,
    595     uint64_t code);
    596 
    597 
    598   /**
    599    * Store payment for challenge.
    600    *
    601    * @param cls closure
    602    * @param truth_key identifier of the challenge to pay
    603    * @param payment_secret payment secret which the user must provide with every upload
    604    * @param amount how much we asked for
    605    * @return transaction status
    606    */
    607   enum GNUNET_DB_QueryStatus
    608   (*record_challenge_payment)(
    609     void *cls,
    610     const struct FROSIX_ChallengeIdP *truth_uuid,
    611     const struct FROSIX_PaymentSecretP *payment_secret,
    612     const struct TALER_Amount *amount);
    613 
    614 
    615   /**
    616    * Record refund for challenge.
    617    *
    618    * @param cls closure
    619    * @param truth_uuid identifier of the challenge to refund
    620    * @param payment_secret payment secret which the user must provide with every upload
    621    * @return transaction status
    622    */
    623   enum GNUNET_DB_QueryStatus
    624   (*record_challenge_refund)(
    625     void *cls,
    626     const struct FROSIX_ChallengeIdP *truth_uuid,
    627     const struct FROSIX_PaymentSecretP *payment_secret);
    628 
    629 
    630   /**
    631    * Lookup for a pending payment for a certain challenge
    632    *
    633    * @param cls closure
    634    * @param truth_uuid identification of the challenge
    635    * @param[out] payment_secret set to the challenge payment secret
    636    * @return transaction status
    637    */
    638   enum GNUNET_DB_QueryStatus
    639   (*lookup_challenge_payment)(
    640     void *cls,
    641     const struct FROSIX_ChallengeIdP *truth_uuid,
    642     struct FROSIX_PaymentSecretP *payment_secret);
    643 
    644 
    645   /**
    646    * Update payment status of challenge
    647    *
    648    * @param cls closure
    649    * @param truth_uuid which challenge received a payment
    650    * @param payment_identifier proof of payment, must be unique and match pending payment
    651    * @return transaction status
    652    */
    653   enum GNUNET_DB_QueryStatus
    654   (*update_challenge_payment)(
    655     void *cls,
    656     const struct FROSIX_ChallengeIdP *truth_uuid,
    657     const struct FROSIX_PaymentSecretP *payment_identifier);
    658 
    659 
    660   /**
    661    * Store inbound IBAN payment made for authentication.
    662    *
    663    * @param cls closure
    664    * @param wire_reference unique identifier inside LibEuFin/Nexus
    665    * @param wire_subject subject of the wire transfer
    666    * @param amount how much was transferred
    667    * @param debit_account account that was debited
    668    * @param credit_account Anastasis operator account credited
    669    * @param execution_date when was the transfer made
    670    * @return transaction status
    671    */
    672   enum GNUNET_DB_QueryStatus
    673   (*record_auth_iban_payment)(
    674     void *cls,
    675     uint8_t wire_reference,
    676     const char *wire_subject,
    677     const struct TALER_Amount *amount,
    678     const char *debit_account,
    679     const char *credit_account,
    680     struct GNUNET_TIME_Timestamp execution_date);
    681 
    682 
    683   /**
    684    * Function to check if we are aware of a wire transfer
    685    * that satisfies the IBAN plugin's authentication check.
    686    *
    687    * @param cls closure
    688    * @param debit_account which debit account to check
    689    * @param earliest_date earliest date to check
    690    * @param cb function to call on all entries found
    691    * @param cb_cls closure for @a cb
    692    * @return transaction status,
    693    *    #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT if @a cb
    694    *      returned 'true' once
    695    *    #GNUNET_DB_STATUS_SUCCESS_NO_RESULTS if no
    696    *      wire transfers existed for which @a cb returned true
    697    */
    698   enum GNUNET_DB_QueryStatus
    699   (*test_auth_iban_payment)(
    700     void *cls,
    701     const char *debit_account,
    702     struct GNUNET_TIME_Timestamp earliest_date,
    703     FROSIX_DB_AuthIbanTransfercheck cb,
    704     void *cb_cls);
    705 
    706 
    707   /**
    708    * Function to check the last known IBAN payment.
    709    *
    710    * @param cls closure
    711    * @param credit_account which credit account to check
    712    * @param[out] last_row set to the last known row
    713    * @return transaction status,
    714    *    #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT if @a cb
    715    *      returned 'true' once
    716    *    #GNUNET_DB_STATUS_SUCCESS_NO_RESULTS if no
    717    *      wire transfers existed for which @a cb returned true
    718    */
    719   enum GNUNET_DB_QueryStatus
    720   (*get_last_auth_iban_payment_row)(
    721     void *cls,
    722     const char *credit_account,
    723     uint8_t *last_row);
    724 
    725 
    726   /**
    727    * Function called to remove all expired codes from the database.
    728    *
    729    * @return transaction status
    730    */
    731   enum GNUNET_DB_QueryStatus
    732   (*challenge_gc)(void *cls);
    733 
    734 
    735 };
    736 #endif