LCOV - code coverage report
Current view: top level - exchangedb - exchangedb_fees.c (source / functions) Hit Total Coverage
Test: rcoverage.info Lines: 69 82 84.1 %
Date: 2017-09-17 17:24:28 Functions: 5 5 100.0 %

          Line data    Source code
       1             : /*
       2             :   This file is part of TALER
       3             :   Copyright (C) 2017 GNUnet e.V.
       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/exchangedb_fees.c
      18             :  * @brief Logic to read/write/convert aggregation wire fees (not other fees!)
      19             :  * @author Christian Grothoff
      20             :  */
      21             : #include "platform.h"
      22             : #include "taler_exchangedb_lib.h"
      23             : 
      24             : 
      25             : GNUNET_NETWORK_STRUCT_BEGIN
      26             : 
      27             : /**
      28             :  * Structure for wire fees on disk.
      29             :  */
      30             : struct TALER_WireFeeDiskP
      31             : {
      32             : 
      33             :   /**
      34             :    * Wire fee details.
      35             :    */
      36             :   struct TALER_MasterWireFeePS wf;
      37             : 
      38             : 
      39             :   /**
      40             :    * Signature affirming the above fee structure.
      41             :    */
      42             :   struct TALER_MasterSignatureP master_sig;
      43             : 
      44             : };
      45             : 
      46             : GNUNET_NETWORK_STRUCT_END
      47             : 
      48             : 
      49             : /**
      50             :  * Convert @a wd disk format to host format.
      51             :  *
      52             :  * @param wd aggregate fees, disk format
      53             :  * @return fees in host format
      54             :  */
      55             : static struct TALER_EXCHANGEDB_AggregateFees *
      56          54 : wd2af (const struct TALER_WireFeeDiskP *wd)
      57             : {
      58             :   struct TALER_EXCHANGEDB_AggregateFees *af;
      59             : 
      60          54 :   af = GNUNET_new (struct TALER_EXCHANGEDB_AggregateFees);
      61          54 :   af->start_date = GNUNET_TIME_absolute_ntoh (wd->wf.start_date);
      62          54 :   af->end_date = GNUNET_TIME_absolute_ntoh (wd->wf.end_date);
      63          54 :   TALER_amount_ntoh (&af->wire_fee,
      64             :                      &wd->wf.wire_fee);
      65          54 :   TALER_amount_ntoh (&af->closing_fee,
      66             :                      &wd->wf.closing_fee);
      67          54 :   af->master_sig = wd->master_sig;
      68          54 :   return af;
      69             : }
      70             : 
      71             : 
      72             : /**
      73             :  * Read the current fee structure from disk.
      74             :  *
      75             :  * @param cfg configuration to use
      76             :  * @param wireplugin name of the wire plugin to read fees for
      77             :  * @return sorted list of aggregation fees, NULL on error
      78             :  */
      79             : struct TALER_EXCHANGEDB_AggregateFees *
      80          27 : TALER_EXCHANGEDB_fees_read (const struct GNUNET_CONFIGURATION_Handle *cfg,
      81             :                             const char *wireplugin)
      82             : {
      83             :   char *wirefee_base_dir;
      84             :   char *fn;
      85             :   struct GNUNET_DISK_FileHandle *fh;
      86             :   struct TALER_WireFeeDiskP wd;
      87             :   struct TALER_EXCHANGEDB_AggregateFees *af;
      88             :   struct TALER_EXCHANGEDB_AggregateFees *endp;
      89             : 
      90          27 :   if (GNUNET_OK !=
      91          27 :       GNUNET_CONFIGURATION_get_value_filename (cfg,
      92             :                                                "exchangedb",
      93             :                                                "WIREFEE_BASE_DIR",
      94             :                                                &wirefee_base_dir))
      95           0 :     return NULL;
      96          27 :   GNUNET_asprintf (&fn,
      97             :                    "%s/%s.fee",
      98             :                    wirefee_base_dir,
      99             :                    wireplugin);
     100          27 :   GNUNET_free (wirefee_base_dir);
     101          27 :   fh = GNUNET_DISK_file_open (fn,
     102             :                               GNUNET_DISK_OPEN_READ,
     103             :                               GNUNET_DISK_PERM_NONE);
     104          27 :   GNUNET_free (fn);
     105          27 :   if (NULL == fh)
     106           1 :     return NULL;
     107             : 
     108          26 :   af = NULL;
     109          26 :   endp = NULL;
     110         106 :   while (sizeof (wd) ==
     111          80 :          GNUNET_DISK_file_read (fh,
     112             :                                 &wd,
     113             :                                 sizeof (wd)))
     114             :   {
     115             :     struct TALER_EXCHANGEDB_AggregateFees *n;
     116             : 
     117          54 :     n = wd2af (&wd);
     118          82 :     if ( ( (NULL == af) ||
     119          82 :            (endp->end_date.abs_value_us == n->start_date.abs_value_us) ) &&
     120          54 :          (n->start_date.abs_value_us < n->end_date.abs_value_us) )
     121             :     {
     122             :       /* append to list */
     123          54 :       if (NULL != endp)
     124          28 :         endp->next = n;
     125             :       else
     126          26 :         af = n;
     127          54 :       endp = n;
     128             :     }
     129             :     else
     130             :     {
     131             :       /* We expect file to be in chronological order! */
     132           0 :       GNUNET_break (0);
     133           0 :       GNUNET_DISK_file_close (fh);
     134           0 :       GNUNET_free (n);
     135           0 :       TALER_EXCHANGEDB_fees_free (af);
     136           0 :       return NULL;
     137             :     }
     138             :   }
     139          26 :   GNUNET_DISK_file_close (fh);
     140          26 :   return af;
     141             : }
     142             : 
     143             : 
     144             : /**
     145             :  * Convert @a af to @a wf.
     146             :  *
     147             :  * @param wireplugin name of the wire plugin the fees are for
     148             :  * @param[in,out] af aggregate fees, host format (updated to round time)
     149             :  * @param[out] wf aggregate fees, disk / signature format
     150             :  */
     151             : void
     152          58 : TALER_EXCHANGEDB_fees_2_wf (const char *wireplugin,
     153             :                             struct TALER_EXCHANGEDB_AggregateFees *af,
     154             :                             struct TALER_MasterWireFeePS *wf)
     155             : {
     156          58 :   (void) GNUNET_TIME_round_abs (&af->start_date);
     157          58 :   (void) GNUNET_TIME_round_abs (&af->end_date);
     158          58 :   wf->purpose.size = htonl (sizeof (*wf));
     159          58 :   wf->purpose.purpose = htonl (TALER_SIGNATURE_MASTER_WIRE_FEES);
     160         116 :   GNUNET_CRYPTO_hash (wireplugin,
     161          58 :                       strlen (wireplugin) + 1,
     162             :                       &wf->h_wire_method);
     163          58 :   wf->start_date = GNUNET_TIME_absolute_hton (af->start_date);
     164          58 :   wf->end_date = GNUNET_TIME_absolute_hton (af->end_date);
     165          58 :   TALER_amount_hton (&wf->wire_fee,
     166          58 :                      &af->wire_fee);
     167          58 :   TALER_amount_hton (&wf->closing_fee,
     168          58 :                      &af->closing_fee);
     169          58 : }
     170             : 
     171             : 
     172             : /**
     173             :  * Write given fee structure to disk.
     174             :  *
     175             :  * @param filename where to write the fees
     176             :  * @param wireplugin which plugin the fees are about
     177             :  * @param af fee structure to write
     178             :  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
     179             :  */
     180             : int
     181          13 : TALER_EXCHANGEDB_fees_write (const char *filename,
     182             :                              const char *wireplugin,
     183             :                              struct TALER_EXCHANGEDB_AggregateFees *af)
     184             : {
     185             :   struct GNUNET_DISK_FileHandle *fh;
     186             :   struct TALER_WireFeeDiskP wd;
     187             :   struct TALER_EXCHANGEDB_AggregateFees *last;
     188             : 
     189          13 :   if (GNUNET_OK !=
     190          13 :       GNUNET_DISK_directory_create_for_file (filename))
     191           0 :     return GNUNET_SYSERR;
     192             : 
     193          13 :   fh = GNUNET_DISK_file_open (filename,
     194             :                               GNUNET_DISK_OPEN_WRITE |
     195             :                               GNUNET_DISK_OPEN_TRUNCATE |
     196             :                               GNUNET_DISK_OPEN_CREATE,
     197             :                               GNUNET_DISK_PERM_USER_READ |
     198             :                               GNUNET_DISK_PERM_USER_WRITE);
     199          13 :   if (NULL == fh)
     200           0 :     return GNUNET_SYSERR;
     201             : 
     202          13 :   last = NULL;
     203          54 :   while (NULL != af)
     204             :   {
     205          43 :     if ( ( (NULL != last) &&
     206          43 :            (last->end_date.abs_value_us != af->start_date.abs_value_us) ) ||
     207          28 :          (af->start_date.abs_value_us >= af->end_date.abs_value_us) )
     208             :     {
     209             :       /* @a af malformed, refusing to write file that will be rejected */
     210           0 :       GNUNET_break (0);
     211           0 :       GNUNET_assert (GNUNET_OK ==
     212             :                      GNUNET_DISK_file_close (fh));
     213           0 :       return GNUNET_SYSERR;
     214             :     }
     215          28 :     TALER_EXCHANGEDB_fees_2_wf (wireplugin,
     216             :                                 af,
     217             :                                 &wd.wf);
     218          28 :     wd.master_sig = af->master_sig;
     219          28 :     last = af;
     220          28 :     af = af->next;
     221          28 :     if (sizeof (wd) !=
     222          28 :         GNUNET_DISK_file_write (fh,
     223             :                                 &wd,
     224             :                                 sizeof (wd)))
     225             :     {
     226           0 :       GNUNET_assert (GNUNET_OK ==
     227             :                      GNUNET_DISK_file_close (fh));
     228           0 :       return GNUNET_SYSERR;
     229             :     }
     230             :   }
     231          13 :   GNUNET_assert (GNUNET_OK ==
     232             :                  GNUNET_DISK_file_close (fh));
     233          13 :   return GNUNET_OK;
     234             : }
     235             : 
     236             : 
     237             : /**
     238             :  * Free @a af data structure
     239             :  *
     240             :  * @param af list to free
     241             :  */
     242             : void
     243          40 : TALER_EXCHANGEDB_fees_free (struct TALER_EXCHANGEDB_AggregateFees *af)
     244             : {
     245             :   struct TALER_EXCHANGEDB_AggregateFees *next;
     246             : 
     247         162 :   while (NULL != af)
     248             :   {
     249          82 :     next = af->next;
     250          82 :     GNUNET_free (af);
     251          82 :     af = next;
     252             :   }
     253          40 : }
     254             : 
     255             : 
     256             : /* end of exchangedb_fees.c */

Generated by: LCOV version 1.13