2017-03-03 19:23:34 +01:00
|
|
|
/*
|
|
|
|
This file is part of TALER
|
2020-01-16 22:40:12 +01:00
|
|
|
Copyright (C) 2017 Taler Systems SA
|
2017-03-03 19:23:34 +01:00
|
|
|
|
|
|
|
TALER is free software; you can redistribute it and/or modify it under the
|
|
|
|
terms of the GNU General Public License as published by the Free Software
|
|
|
|
Foundation; either version 3, or (at your option) any later version.
|
|
|
|
|
|
|
|
TALER is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
|
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
|
|
|
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License along with
|
|
|
|
TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
|
|
|
|
*/
|
|
|
|
/**
|
|
|
|
* @file exchangedb/exchangedb_fees.c
|
|
|
|
* @brief Logic to read/write/convert aggregation wire fees (not other fees!)
|
|
|
|
* @author Christian Grothoff
|
|
|
|
*/
|
|
|
|
#include "platform.h"
|
|
|
|
#include "taler_exchangedb_lib.h"
|
|
|
|
|
|
|
|
|
|
|
|
GNUNET_NETWORK_STRUCT_BEGIN
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Structure for wire fees on disk.
|
|
|
|
*/
|
|
|
|
struct TALER_WireFeeDiskP
|
|
|
|
{
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Wire fee details.
|
|
|
|
*/
|
|
|
|
struct TALER_MasterWireFeePS wf;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Signature affirming the above fee structure.
|
|
|
|
*/
|
|
|
|
struct TALER_MasterSignatureP master_sig;
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
GNUNET_NETWORK_STRUCT_END
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Convert @a wd disk format to host format.
|
|
|
|
*
|
|
|
|
* @param wd aggregate fees, disk format
|
|
|
|
* @return fees in host format
|
|
|
|
*/
|
|
|
|
static struct TALER_EXCHANGEDB_AggregateFees *
|
|
|
|
wd2af (const struct TALER_WireFeeDiskP *wd)
|
|
|
|
{
|
|
|
|
struct TALER_EXCHANGEDB_AggregateFees *af;
|
|
|
|
|
|
|
|
af = GNUNET_new (struct TALER_EXCHANGEDB_AggregateFees);
|
|
|
|
af->start_date = GNUNET_TIME_absolute_ntoh (wd->wf.start_date);
|
|
|
|
af->end_date = GNUNET_TIME_absolute_ntoh (wd->wf.end_date);
|
|
|
|
TALER_amount_ntoh (&af->wire_fee,
|
|
|
|
&wd->wf.wire_fee);
|
2017-04-17 14:01:55 +02:00
|
|
|
TALER_amount_ntoh (&af->closing_fee,
|
|
|
|
&wd->wf.closing_fee);
|
2017-03-03 19:23:34 +01:00
|
|
|
af->master_sig = wd->master_sig;
|
|
|
|
return af;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Read the current fee structure from disk.
|
|
|
|
*
|
|
|
|
* @param cfg configuration to use
|
|
|
|
* @param wireplugin name of the wire plugin to read fees for
|
|
|
|
* @return sorted list of aggregation fees, NULL on error
|
|
|
|
*/
|
|
|
|
struct TALER_EXCHANGEDB_AggregateFees *
|
|
|
|
TALER_EXCHANGEDB_fees_read (const struct GNUNET_CONFIGURATION_Handle *cfg,
|
|
|
|
const char *wireplugin)
|
|
|
|
{
|
|
|
|
char *wirefee_base_dir;
|
|
|
|
char *fn;
|
|
|
|
struct GNUNET_DISK_FileHandle *fh;
|
|
|
|
struct TALER_WireFeeDiskP wd;
|
|
|
|
struct TALER_EXCHANGEDB_AggregateFees *af;
|
|
|
|
struct TALER_EXCHANGEDB_AggregateFees *endp;
|
|
|
|
|
|
|
|
if (GNUNET_OK !=
|
|
|
|
GNUNET_CONFIGURATION_get_value_filename (cfg,
|
|
|
|
"exchangedb",
|
|
|
|
"WIREFEE_BASE_DIR",
|
|
|
|
&wirefee_base_dir))
|
|
|
|
return NULL;
|
|
|
|
GNUNET_asprintf (&fn,
|
2017-03-03 20:31:29 +01:00
|
|
|
"%s/%s.fee",
|
2017-03-03 19:23:34 +01:00
|
|
|
wirefee_base_dir,
|
|
|
|
wireplugin);
|
|
|
|
GNUNET_free (wirefee_base_dir);
|
|
|
|
fh = GNUNET_DISK_file_open (fn,
|
|
|
|
GNUNET_DISK_OPEN_READ,
|
|
|
|
GNUNET_DISK_PERM_NONE);
|
|
|
|
GNUNET_free (fn);
|
|
|
|
if (NULL == fh)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
af = NULL;
|
|
|
|
endp = NULL;
|
|
|
|
while (sizeof (wd) ==
|
|
|
|
GNUNET_DISK_file_read (fh,
|
|
|
|
&wd,
|
|
|
|
sizeof (wd)))
|
|
|
|
{
|
|
|
|
struct TALER_EXCHANGEDB_AggregateFees *n;
|
|
|
|
|
|
|
|
n = wd2af (&wd);
|
2020-01-18 16:28:42 +01:00
|
|
|
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
|
|
|
"Loaded wire fees starting at %s from file\n",
|
|
|
|
GNUNET_STRINGS_absolute_time_to_string (n->start_date));
|
2017-03-03 19:23:34 +01:00
|
|
|
if ( ( (NULL == af) ||
|
|
|
|
(endp->end_date.abs_value_us == n->start_date.abs_value_us) ) &&
|
|
|
|
(n->start_date.abs_value_us < n->end_date.abs_value_us) )
|
|
|
|
{
|
|
|
|
/* append to list */
|
|
|
|
if (NULL != endp)
|
|
|
|
endp->next = n;
|
|
|
|
else
|
|
|
|
af = n;
|
|
|
|
endp = n;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* We expect file to be in chronological order! */
|
|
|
|
GNUNET_break (0);
|
|
|
|
GNUNET_DISK_file_close (fh);
|
|
|
|
GNUNET_free (n);
|
|
|
|
TALER_EXCHANGEDB_fees_free (af);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
GNUNET_DISK_file_close (fh);
|
|
|
|
return af;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Convert @a af to @a wf.
|
|
|
|
*
|
2020-01-18 14:36:49 +01:00
|
|
|
* @param wiremethod name of the wire method the fees are for
|
2017-03-03 19:23:34 +01:00
|
|
|
* @param[in,out] af aggregate fees, host format (updated to round time)
|
|
|
|
* @param[out] wf aggregate fees, disk / signature format
|
|
|
|
*/
|
|
|
|
void
|
2020-01-18 14:36:49 +01:00
|
|
|
TALER_EXCHANGEDB_fees_2_wf (const char *wiremethod,
|
2017-03-04 18:09:39 +01:00
|
|
|
struct TALER_EXCHANGEDB_AggregateFees *af,
|
2017-03-03 19:23:34 +01:00
|
|
|
struct TALER_MasterWireFeePS *wf)
|
|
|
|
{
|
|
|
|
(void) GNUNET_TIME_round_abs (&af->start_date);
|
|
|
|
(void) GNUNET_TIME_round_abs (&af->end_date);
|
|
|
|
wf->purpose.size = htonl (sizeof (*wf));
|
|
|
|
wf->purpose.purpose = htonl (TALER_SIGNATURE_MASTER_WIRE_FEES);
|
2020-01-18 14:36:49 +01:00
|
|
|
GNUNET_CRYPTO_hash (wiremethod,
|
|
|
|
strlen (wiremethod) + 1,
|
2017-03-04 18:09:39 +01:00
|
|
|
&wf->h_wire_method);
|
2017-03-03 19:23:34 +01:00
|
|
|
wf->start_date = GNUNET_TIME_absolute_hton (af->start_date);
|
|
|
|
wf->end_date = GNUNET_TIME_absolute_hton (af->end_date);
|
|
|
|
TALER_amount_hton (&wf->wire_fee,
|
|
|
|
&af->wire_fee);
|
2017-04-17 14:01:55 +02:00
|
|
|
TALER_amount_hton (&wf->closing_fee,
|
|
|
|
&af->closing_fee);
|
2017-03-03 19:23:34 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Write given fee structure to disk.
|
|
|
|
*
|
|
|
|
* @param filename where to write the fees
|
2017-03-04 18:09:39 +01:00
|
|
|
* @param wireplugin which plugin the fees are about
|
2017-03-03 19:23:34 +01:00
|
|
|
* @param af fee structure to write
|
|
|
|
* @return #GNUNET_OK on success, #GNUNET_SYSERR on error
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
TALER_EXCHANGEDB_fees_write (const char *filename,
|
2017-03-04 18:09:39 +01:00
|
|
|
const char *wireplugin,
|
2017-03-03 19:23:34 +01:00
|
|
|
struct TALER_EXCHANGEDB_AggregateFees *af)
|
|
|
|
{
|
|
|
|
struct GNUNET_DISK_FileHandle *fh;
|
|
|
|
struct TALER_WireFeeDiskP wd;
|
|
|
|
struct TALER_EXCHANGEDB_AggregateFees *last;
|
|
|
|
|
|
|
|
if (GNUNET_OK !=
|
|
|
|
GNUNET_DISK_directory_create_for_file (filename))
|
|
|
|
return GNUNET_SYSERR;
|
|
|
|
|
|
|
|
fh = GNUNET_DISK_file_open (filename,
|
2019-08-25 16:18:24 +02:00
|
|
|
GNUNET_DISK_OPEN_WRITE
|
|
|
|
| GNUNET_DISK_OPEN_TRUNCATE
|
|
|
|
| GNUNET_DISK_OPEN_CREATE,
|
|
|
|
GNUNET_DISK_PERM_USER_READ
|
|
|
|
| GNUNET_DISK_PERM_USER_WRITE);
|
2017-03-03 19:23:34 +01:00
|
|
|
if (NULL == fh)
|
|
|
|
return GNUNET_SYSERR;
|
|
|
|
|
|
|
|
last = NULL;
|
|
|
|
while (NULL != af)
|
|
|
|
{
|
|
|
|
if ( ( (NULL != last) &&
|
|
|
|
(last->end_date.abs_value_us != af->start_date.abs_value_us) ) ||
|
|
|
|
(af->start_date.abs_value_us >= af->end_date.abs_value_us) )
|
|
|
|
{
|
|
|
|
/* @a af malformed, refusing to write file that will be rejected */
|
|
|
|
GNUNET_break (0);
|
|
|
|
GNUNET_assert (GNUNET_OK ==
|
|
|
|
GNUNET_DISK_file_close (fh));
|
|
|
|
return GNUNET_SYSERR;
|
|
|
|
}
|
2017-03-04 18:09:39 +01:00
|
|
|
TALER_EXCHANGEDB_fees_2_wf (wireplugin,
|
|
|
|
af,
|
2017-03-03 19:23:34 +01:00
|
|
|
&wd.wf);
|
|
|
|
wd.master_sig = af->master_sig;
|
2017-03-19 11:09:32 +01:00
|
|
|
last = af;
|
2017-03-03 19:23:34 +01:00
|
|
|
af = af->next;
|
|
|
|
if (sizeof (wd) !=
|
|
|
|
GNUNET_DISK_file_write (fh,
|
|
|
|
&wd,
|
|
|
|
sizeof (wd)))
|
|
|
|
{
|
|
|
|
GNUNET_assert (GNUNET_OK ==
|
|
|
|
GNUNET_DISK_file_close (fh));
|
|
|
|
return GNUNET_SYSERR;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
GNUNET_assert (GNUNET_OK ==
|
|
|
|
GNUNET_DISK_file_close (fh));
|
|
|
|
return GNUNET_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Free @a af data structure
|
|
|
|
*
|
|
|
|
* @param af list to free
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
TALER_EXCHANGEDB_fees_free (struct TALER_EXCHANGEDB_AggregateFees *af)
|
|
|
|
{
|
|
|
|
struct TALER_EXCHANGEDB_AggregateFees *next;
|
|
|
|
|
|
|
|
while (NULL != af)
|
|
|
|
{
|
|
|
|
next = af->next;
|
|
|
|
GNUNET_free (af);
|
|
|
|
af = next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* end of exchangedb_fees.c */
|