handle wirefee issues better

This commit is contained in:
Christian Grothoff 2019-09-05 05:49:45 +02:00
parent cc5297a7f1
commit d4905d7e2c
No known key found for this signature in database
GPG Key ID: 939E6BE1E29FC3CC

View File

@ -2553,13 +2553,13 @@ wire_transfer_information_cb (void *cls,
* Lookup the wire fee that the exchange charges at @a timestamp. * Lookup the wire fee that the exchange charges at @a timestamp.
* *
* @param ac context for caching the result * @param ac context for caching the result
* @param type type of the wire plugin * @param method method of the wire plugin
* @param timestamp time for which we need the fee * @param timestamp time for which we need the fee
* @return NULL on error (fee unknown) * @return NULL on error (fee unknown)
*/ */
static const struct TALER_Amount * static const struct TALER_Amount *
get_wire_fee (struct AggregationContext *ac, get_wire_fee (struct AggregationContext *ac,
const char *type, const char *method,
struct GNUNET_TIME_Absolute timestamp) struct GNUNET_TIME_Absolute timestamp)
{ {
struct WireFeeInfo *wfi; struct WireFeeInfo *wfi;
@ -2581,7 +2581,7 @@ get_wire_fee (struct AggregationContext *ac,
if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
edb->get_wire_fee (edb->cls, edb->get_wire_fee (edb->cls,
esession, esession,
type, method,
timestamp, timestamp,
&wfi->start_date, &wfi->start_date,
&wfi->end_date, &wfi->end_date,
@ -2594,33 +2594,32 @@ get_wire_fee (struct AggregationContext *ac,
return NULL; return NULL;
} }
/* Check signature (not terribly meaningful as the exchange can /* Check signature. (This is not terribly meaningful as the exchange can
easily make this one up, but it means that we have proof that easily make this one up, but it means that we have proof that the master
the master key was used for inconsistent wire fees if a key was used for inconsistent wire fees if a merchant complains.) */
merchant complains. */
{ {
struct TALER_MasterWireFeePS wp; struct TALER_MasterWireFeePS wf;
wp.purpose.purpose = htonl (TALER_SIGNATURE_MASTER_WIRE_FEES); wf.purpose.purpose = htonl (TALER_SIGNATURE_MASTER_WIRE_FEES);
wp.purpose.size = htonl (sizeof (wp)); wf.purpose.size = htonl (sizeof (wf));
GNUNET_CRYPTO_hash (type, GNUNET_CRYPTO_hash (method,
strlen (type) + 1, strlen (method) + 1,
&wp.h_wire_method); &wf.h_wire_method);
wp.start_date = GNUNET_TIME_absolute_hton (wfi->start_date); wf.start_date = GNUNET_TIME_absolute_hton (wfi->start_date);
wp.end_date = GNUNET_TIME_absolute_hton (wfi->end_date); wf.end_date = GNUNET_TIME_absolute_hton (wfi->end_date);
TALER_amount_hton (&wp.wire_fee, TALER_amount_hton (&wf.wire_fee,
&wfi->wire_fee); &wfi->wire_fee);
TALER_amount_hton (&wp.closing_fee, TALER_amount_hton (&wf.closing_fee,
&wfi->closing_fee); &wfi->closing_fee);
if (GNUNET_OK != if (GNUNET_OK !=
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MASTER_WIRE_FEES, GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MASTER_WIRE_FEES,
&wp.purpose, &wf.purpose,
&master_sig.eddsa_signature, &master_sig.eddsa_signature,
&master_pub.eddsa_pub)) &master_pub.eddsa_pub))
{ {
GNUNET_break (0); report_row_inconsistency ("wire-fee",
GNUNET_free (wfi); timestamp.abs_value_us,
return NULL; "wire fee signature invalid at given time");
} }
} }
@ -2645,7 +2644,7 @@ get_wire_fee (struct AggregationContext *ac,
{ {
report (report_fee_time_inconsistencies, report (report_fee_time_inconsistencies,
json_pack ("{s:s, s:s, s:o}", json_pack ("{s:s, s:s, s:o}",
"type", type, "type", method,
"diagnostic", "start date before previous end date", "diagnostic", "start date before previous end date",
"time", json_from_time_abs (wfi->start_date))); "time", json_from_time_abs (wfi->start_date)));
} }
@ -2654,7 +2653,7 @@ get_wire_fee (struct AggregationContext *ac,
{ {
report (report_fee_time_inconsistencies, report (report_fee_time_inconsistencies,
json_pack ("{s:s, s:s, s:o}", json_pack ("{s:s, s:s, s:o}",
"type", type, "type", method,
"diagnostic", "end date date after next start date", "diagnostic", "end date date after next start date",
"time", json_from_time_abs (wfi->end_date))); "time", json_from_time_abs (wfi->end_date)));
} }
@ -2686,7 +2685,6 @@ check_wire_out_cb
struct AggregationContext *ac = cls; struct AggregationContext *ac = cls;
struct WireCheckContext wcc; struct WireCheckContext wcc;
struct TALER_WIRE_Plugin *plugin; struct TALER_WIRE_Plugin *plugin;
const struct TALER_Amount *wire_fee;
struct TALER_Amount final_amount; struct TALER_Amount final_amount;
struct TALER_Amount exchange_gain; struct TALER_Amount exchange_gain;
enum GNUNET_DB_QueryStatus qs; enum GNUNET_DB_QueryStatus qs;
@ -2745,32 +2743,35 @@ check_wire_out_cb
return GNUNET_OK; return GNUNET_OK;
} }
/* Subtract aggregation fee from total */ /* Subtract aggregation fee from total (if possible) */
wire_fee = get_wire_fee (ac,
method,
date);
if (NULL == wire_fee)
{
GNUNET_break (0);
ac->qs = GNUNET_DB_STATUS_HARD_ERROR;
GNUNET_free (method);
return GNUNET_SYSERR;
}
if (GNUNET_SYSERR ==
TALER_amount_subtract (&final_amount,
&wcc.total_deposits,
wire_fee))
{ {
const struct TALER_Amount *wire_fee;
report_amount_arithmetic_inconsistency wire_fee = get_wire_fee (ac,
("wire out (fee structure)", method,
rowid, date);
&wcc.total_deposits, if (NULL == wire_fee)
wire_fee, {
-1); report_row_inconsistency ("wire-fee",
date.abs_value_us,
GNUNET_free (method); "wire fee unavailable for given time");
return GNUNET_OK; /* If fee is unknown, we just assume the fee is zero */
final_amount = wcc.total_deposits;
}
else if (GNUNET_SYSERR ==
TALER_amount_subtract (&final_amount,
&wcc.total_deposits,
wire_fee))
{
report_amount_arithmetic_inconsistency
("wire out (fee structure)",
rowid,
&wcc.total_deposits,
wire_fee,
-1);
/* If fee arithmetic fails, we just assume the fee is zero */
final_amount = wcc.total_deposits;
}
} }
/* Round down to amount supported by wire method */ /* Round down to amount supported by wire method */