LCOV - code coverage report
Current view: top level - exchangedb - pg_get_refresh_reveal.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 63 0.0 %
Date: 2025-06-05 21:03:14 Functions: 0 2 0.0 %

          Line data    Source code
       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 exchangedb/pg_get_refresh_reveal.c
      18             :  * @brief Implementation of the get_refresh_reveal function for Postgres
      19             :  * @author Christian Grothoff
      20             :  */
      21             : #include "platform.h"
      22             : #include "taler_error_codes.h"
      23             : #include "taler_dbevents.h"
      24             : #include "taler_pq_lib.h"
      25             : #include "pg_get_refresh_reveal.h"
      26             : #include "pg_helper.h"
      27             : 
      28             : 
      29             : /**
      30             :  * Context where we aggregate data from the database.
      31             :  * Closure for #add_revealed_coins().
      32             :  */
      33             : struct GetRevealContext
      34             : {
      35             :   /**
      36             :    * Array of revealed coins we obtained from the DB.
      37             :    */
      38             :   struct TALER_EXCHANGEDB_RefreshRevealedCoin *rrcs;
      39             : 
      40             :   /**
      41             :    * Length of the @a rrcs array.
      42             :    */
      43             :   unsigned int rrcs_len;
      44             : 
      45             :   /**
      46             :    * Set to an error code if we ran into trouble.
      47             :    */
      48             :   enum GNUNET_DB_QueryStatus qs;
      49             : };
      50             : 
      51             : 
      52             : /**
      53             :  * Function to be called with the results of a SELECT statement
      54             :  * that has returned @a num_results results.
      55             :  *
      56             :  * @param cls closure of type `struct GetRevealContext`
      57             :  * @param result the postgres result
      58             :  * @param num_results the number of results in @a result
      59             :  */
      60             : static void
      61           0 : add_revealed_coins (void *cls,
      62             :                     PGresult *result,
      63             :                     unsigned int num_results)
      64             : {
      65           0 :   struct GetRevealContext *grctx = cls;
      66             : 
      67           0 :   if (0 == num_results)
      68           0 :     return;
      69           0 :   grctx->rrcs = GNUNET_new_array (num_results,
      70             :                                   struct TALER_EXCHANGEDB_RefreshRevealedCoin);
      71           0 :   grctx->rrcs_len = num_results;
      72           0 :   for (unsigned int i = 0; i < num_results; i++)
      73             :   {
      74             :     uint32_t off;
      75           0 :     struct GNUNET_PQ_ResultSpec rso[] = {
      76           0 :       GNUNET_PQ_result_spec_uint32 ("freshcoin_index",
      77             :                                     &off),
      78             :       GNUNET_PQ_result_spec_end
      79             :     };
      80             : 
      81           0 :     if (GNUNET_OK !=
      82           0 :         GNUNET_PQ_extract_result (result,
      83             :                                   rso,
      84             :                                   i))
      85             :     {
      86           0 :       GNUNET_break (0);
      87           0 :       grctx->qs = GNUNET_DB_STATUS_HARD_ERROR;
      88           0 :       return;
      89             :     }
      90           0 :     if (off >= num_results)
      91             :     {
      92           0 :       GNUNET_break (0);
      93           0 :       grctx->qs = GNUNET_DB_STATUS_HARD_ERROR;
      94           0 :       return;
      95             :     }
      96             :     {
      97           0 :       struct TALER_EXCHANGEDB_RefreshRevealedCoin *rrc = &grctx->rrcs[off];
      98           0 :       struct GNUNET_PQ_ResultSpec rsi[] = {
      99             :         /* NOTE: freshcoin_index selected and discarded here... */
     100           0 :         GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash",
     101             :                                               &rrc->h_denom_pub),
     102           0 :         GNUNET_PQ_result_spec_auto_from_type ("link_sig",
     103             :                                               &rrc->orig_coin_link_sig),
     104           0 :         GNUNET_PQ_result_spec_auto_from_type ("h_coin_ev",
     105             :                                               &rrc->coin_envelope_hash),
     106           0 :         TALER_PQ_result_spec_blinded_planchet ("coin_ev",
     107             :                                                &rrc->blinded_planchet),
     108           0 :         TALER_PQ_result_spec_exchange_withdraw_values ("ewv",
     109             :                                                        &rrc->exchange_vals),
     110           0 :         TALER_PQ_result_spec_blinded_denom_sig ("ev_sig",
     111             :                                                 &rrc->coin_sig),
     112             :         GNUNET_PQ_result_spec_end
     113             :       };
     114             : 
     115           0 :       if (NULL !=
     116           0 :           rrc->blinded_planchet.blinded_message)
     117             :       {
     118             :         /* duplicate offset, not allowed */
     119           0 :         GNUNET_break (0);
     120           0 :         grctx->qs = GNUNET_DB_STATUS_HARD_ERROR;
     121           0 :         return;
     122             :       }
     123           0 :       if (GNUNET_OK !=
     124           0 :           GNUNET_PQ_extract_result (result,
     125             :                                     rsi,
     126             :                                     i))
     127             :       {
     128           0 :         GNUNET_break (0);
     129           0 :         grctx->qs = GNUNET_DB_STATUS_HARD_ERROR;
     130           0 :         return;
     131             :       }
     132             :     }
     133             :   }
     134             : }
     135             : 
     136             : 
     137             : enum GNUNET_DB_QueryStatus
     138           0 : TEH_PG_get_refresh_reveal (void *cls,
     139             :                            const struct TALER_RefreshCommitmentP *rc,
     140             :                            TALER_EXCHANGEDB_RefreshCallback cb,
     141             :                            void *cb_cls)
     142             : {
     143           0 :   struct PostgresClosure *pg = cls;
     144             :   struct GetRevealContext grctx;
     145             :   enum GNUNET_DB_QueryStatus qs;
     146           0 :   struct GNUNET_PQ_QueryParam params[] = {
     147           0 :     GNUNET_PQ_query_param_auto_from_type (rc),
     148             :     GNUNET_PQ_query_param_end
     149             :   };
     150             : 
     151           0 :   memset (&grctx,
     152             :           0,
     153             :           sizeof (grctx));
     154             : 
     155             :   /* Obtain information about the coins created in a refresh
     156             :      operation, used in #postgres_get_refresh_reveal() */
     157           0 :   PREPARE (pg,
     158             :            "get_refresh_revealed_coins",
     159             :            "SELECT "
     160             :            " rrc.freshcoin_index"
     161             :            ",denom.denom_pub_hash"
     162             :            ",rrc.h_coin_ev"
     163             :            ",rrc.link_sig"
     164             :            ",rrc.coin_ev"
     165             :            ",rrc.ewv"
     166             :            ",rrc.ev_sig"
     167             :            " FROM refresh_commitments"
     168             :            "    JOIN refresh_revealed_coins rrc"
     169             :            "      USING (melt_serial_id)"
     170             :            "    JOIN denominations denom "
     171             :            "      USING (denominations_serial)"
     172             :            " WHERE rc=$1;");
     173           0 :   qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn,
     174             :                                              "get_refresh_revealed_coins",
     175             :                                              params,
     176             :                                              &add_revealed_coins,
     177             :                                              &grctx);
     178           0 :   switch (qs)
     179             :   {
     180           0 :   case GNUNET_DB_STATUS_HARD_ERROR:
     181             :   case GNUNET_DB_STATUS_SOFT_ERROR:
     182             :   case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
     183           0 :     goto cleanup;
     184           0 :   case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
     185             :   default: /* can have more than one result */
     186           0 :     break;
     187             :   }
     188           0 :   switch (grctx.qs)
     189             :   {
     190           0 :   case GNUNET_DB_STATUS_HARD_ERROR:
     191             :   case GNUNET_DB_STATUS_SOFT_ERROR:
     192           0 :     goto cleanup;
     193           0 :   case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
     194             :   case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: /* should be impossible */
     195           0 :     break;
     196             :   }
     197             : 
     198             :   /* Pass result back to application */
     199           0 :   cb (cb_cls,
     200             :       grctx.rrcs_len,
     201           0 :       grctx.rrcs);
     202           0 : cleanup:
     203           0 :   for (unsigned int i = 0; i < grctx.rrcs_len; i++)
     204             :   {
     205           0 :     struct TALER_EXCHANGEDB_RefreshRevealedCoin *rrc = &grctx.rrcs[i];
     206             : 
     207           0 :     TALER_blinded_denom_sig_free (&rrc->coin_sig);
     208           0 :     TALER_blinded_planchet_free (&rrc->blinded_planchet);
     209           0 :     TALER_denom_ewv_free (&rrc->exchange_vals);
     210             :   }
     211           0 :   GNUNET_free (grctx.rrcs);
     212           0 :   return qs;
     213             : }

Generated by: LCOV version 1.16