report wire amount minus aggregation fee in wire_out table, start logic in auditor to check wire amounts including wire fees
This commit is contained in:
parent
1ce5651373
commit
4599b25895
@ -1108,6 +1108,15 @@ struct AggregationContext
|
|||||||
*/
|
*/
|
||||||
struct WirePlugin *wire_tail;
|
struct WirePlugin *wire_tail;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* How much did we make in aggregation fees.
|
||||||
|
*/
|
||||||
|
struct TALER_Amount total_aggregation_fees;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Final result status.
|
||||||
|
*/
|
||||||
|
int ret;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -1594,6 +1603,22 @@ wire_transfer_information_cb (void *cls,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lookup the wire fee that the exchange charges at @a timestamp.
|
||||||
|
*
|
||||||
|
* @param ac context for caching the result
|
||||||
|
* @param timestamp time for which we need the fee
|
||||||
|
* @return NULL on error (fee unknown)
|
||||||
|
*/
|
||||||
|
static const struct TALER_Amount *
|
||||||
|
get_wire_fee (struct AggregationContext *ac,
|
||||||
|
struct GNUNET_TIME_Absolute timestamp)
|
||||||
|
{
|
||||||
|
GNUNET_break (0); /* not implemented! */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check that a wire transfer made by the exchange is valid
|
* Check that a wire transfer made by the exchange is valid
|
||||||
* (has matching deposits).
|
* (has matching deposits).
|
||||||
@ -1617,6 +1642,9 @@ check_wire_out_cb (void *cls,
|
|||||||
struct WireCheckContext wcc;
|
struct WireCheckContext wcc;
|
||||||
json_t *method;
|
json_t *method;
|
||||||
struct TALER_WIRE_Plugin *plugin;
|
struct TALER_WIRE_Plugin *plugin;
|
||||||
|
const struct TALER_Amount *wire_fee;
|
||||||
|
struct TALER_Amount final_amount;
|
||||||
|
struct TALER_Amount exchange_gain;
|
||||||
|
|
||||||
/* should be monotonically increasing */
|
/* should be monotonically increasing */
|
||||||
GNUNET_assert (rowid >= pp.last_wire_out_serial_id);
|
GNUNET_assert (rowid >= pp.last_wire_out_serial_id);
|
||||||
@ -1655,7 +1683,30 @@ check_wire_out_cb (void *cls,
|
|||||||
report_row_inconsistency ("wire_out",
|
report_row_inconsistency ("wire_out",
|
||||||
rowid,
|
rowid,
|
||||||
"audit of associated transactions failed");
|
"audit of associated transactions failed");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Subtract aggregation fee from total */
|
||||||
|
wire_fee = get_wire_fee (ac,
|
||||||
|
date);
|
||||||
|
if (NULL == wire_fee)
|
||||||
|
{
|
||||||
|
GNUNET_break (0);
|
||||||
|
ac->ret = GNUNET_SYSERR;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (GNUNET_SYSERR ==
|
||||||
|
TALER_amount_subtract (&final_amount,
|
||||||
|
&wcc.total_deposits,
|
||||||
|
wire_fee))
|
||||||
|
{
|
||||||
|
report_row_inconsistency ("wire_out",
|
||||||
|
rowid,
|
||||||
|
"could not subtract wire fee from total amount");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Round down to amount supported by wire method */
|
||||||
plugin = get_wire_plugin (ac,
|
plugin = get_wire_plugin (ac,
|
||||||
wcc.method);
|
wcc.method);
|
||||||
if (NULL == plugin)
|
if (NULL == plugin)
|
||||||
@ -1665,20 +1716,45 @@ check_wire_out_cb (void *cls,
|
|||||||
"could not load required wire plugin to validate");
|
"could not load required wire plugin to validate");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GNUNET_SYSERR ==
|
if (GNUNET_SYSERR ==
|
||||||
plugin->amount_round (plugin->cls,
|
plugin->amount_round (plugin->cls,
|
||||||
&wcc.total_deposits))
|
&final_amount))
|
||||||
{
|
{
|
||||||
report_row_minor_inconsistency ("wire_out",
|
report_row_minor_inconsistency ("wire_out",
|
||||||
rowid,
|
rowid,
|
||||||
"wire plugin failed to round given amount");
|
"wire plugin failed to round given amount");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Calculate the exchange's gain as the fees plus rounding differences! */
|
||||||
|
if (GNUNET_OK !=
|
||||||
|
TALER_amount_subtract (&exchange_gain,
|
||||||
|
&wcc.total_deposits,
|
||||||
|
&final_amount))
|
||||||
|
{
|
||||||
|
GNUNET_break (0);
|
||||||
|
ac->ret = GNUNET_SYSERR;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sum up aggregation fees (we simply include the rounding gains) */
|
||||||
|
if (GNUNET_OK !=
|
||||||
|
TALER_amount_add (&ac->total_aggregation_fees,
|
||||||
|
&ac->total_aggregation_fees,
|
||||||
|
&exchange_gain))
|
||||||
|
{
|
||||||
|
GNUNET_break (0);
|
||||||
|
ac->ret = GNUNET_SYSERR;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check that calculated amount matches actual amount */
|
||||||
if (0 != TALER_amount_cmp (amount,
|
if (0 != TALER_amount_cmp (amount,
|
||||||
&wcc.total_deposits))
|
&wcc.total_deposits))
|
||||||
{
|
{
|
||||||
report_wire_out_inconsistency (wire,
|
report_wire_out_inconsistency (wire,
|
||||||
rowid,
|
rowid,
|
||||||
&wcc.total_deposits,
|
&final_amount,
|
||||||
amount,
|
amount,
|
||||||
"computed amount inconsistent with wire amount");
|
"computed amount inconsistent with wire amount");
|
||||||
return;
|
return;
|
||||||
@ -1700,13 +1776,16 @@ analyze_aggregations (void *cls)
|
|||||||
{
|
{
|
||||||
struct AggregationContext ac;
|
struct AggregationContext ac;
|
||||||
struct WirePlugin *wc;
|
struct WirePlugin *wc;
|
||||||
int ret;
|
|
||||||
|
|
||||||
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
|
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
|
||||||
"Analyzing aggregations\n");
|
"Analyzing aggregations\n");
|
||||||
ret = GNUNET_OK;
|
ac.ret = GNUNET_OK;
|
||||||
ac.wire_head = NULL;
|
ac.wire_head = NULL;
|
||||||
ac.wire_tail = NULL;
|
ac.wire_tail = NULL;
|
||||||
|
/* FIXME: load existing value from DB! */
|
||||||
|
GNUNET_assert (GNUNET_OK ==
|
||||||
|
TALER_amount_get_zero (currency,
|
||||||
|
&ac.total_aggregation_fees));
|
||||||
if (GNUNET_SYSERR ==
|
if (GNUNET_SYSERR ==
|
||||||
edb->select_wire_out_above_serial_id (edb->cls,
|
edb->select_wire_out_above_serial_id (edb->cls,
|
||||||
esession,
|
esession,
|
||||||
@ -1715,7 +1794,7 @@ analyze_aggregations (void *cls)
|
|||||||
&ac))
|
&ac))
|
||||||
{
|
{
|
||||||
GNUNET_break (0);
|
GNUNET_break (0);
|
||||||
ret = GNUNET_SYSERR;
|
ac.ret = GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
while (NULL != (wc = ac.wire_head))
|
while (NULL != (wc = ac.wire_head))
|
||||||
{
|
{
|
||||||
@ -1726,7 +1805,14 @@ analyze_aggregations (void *cls)
|
|||||||
GNUNET_free (wc->type);
|
GNUNET_free (wc->type);
|
||||||
GNUNET_free (wc);
|
GNUNET_free (wc);
|
||||||
}
|
}
|
||||||
return ret;
|
if (GNUNET_OK != ac.ret)
|
||||||
|
{
|
||||||
|
GNUNET_break (0);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
/* FIXME: store aggregation fee total to DB! */
|
||||||
|
/* FIXME: report aggregation fee total */
|
||||||
|
return ac.ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -104,10 +104,15 @@ struct AggregationUnit
|
|||||||
struct TALER_MerchantPublicKeyP merchant_pub;
|
struct TALER_MerchantPublicKeyP merchant_pub;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Total amount to be transferred.
|
* Total amount to be transferred, before subtraction of @e wire_fee and rounding down.
|
||||||
*/
|
*/
|
||||||
struct TALER_Amount total_amount;
|
struct TALER_Amount total_amount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Final amount to be transferred (after fee and rounding down).
|
||||||
|
*/
|
||||||
|
struct TALER_Amount final_amount;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wire fee we charge for @e wp at @e execution_time.
|
* Wire fee we charge for @e wp at @e execution_time.
|
||||||
*/
|
*/
|
||||||
@ -686,7 +691,6 @@ run_aggregation (void *cls)
|
|||||||
unsigned int i;
|
unsigned int i;
|
||||||
int ret;
|
int ret;
|
||||||
const struct GNUNET_SCHEDULER_TaskContext *tc;
|
const struct GNUNET_SCHEDULER_TaskContext *tc;
|
||||||
struct TALER_Amount final_amount;
|
|
||||||
|
|
||||||
task = NULL;
|
task = NULL;
|
||||||
tc = GNUNET_SCHEDULER_get_task_context ();
|
tc = GNUNET_SCHEDULER_get_task_context ();
|
||||||
@ -782,14 +786,14 @@ run_aggregation (void *cls)
|
|||||||
wire transfer method; Check if after rounding down, we still have
|
wire transfer method; Check if after rounding down, we still have
|
||||||
an amount to transfer, and if not mark as 'tiny'. */
|
an amount to transfer, and if not mark as 'tiny'. */
|
||||||
if ( (GNUNET_OK !=
|
if ( (GNUNET_OK !=
|
||||||
TALER_amount_subtract (&final_amount,
|
TALER_amount_subtract (&au->final_amount,
|
||||||
&au->total_amount,
|
&au->total_amount,
|
||||||
&au->wire_fee)) ||
|
&au->wire_fee)) ||
|
||||||
(GNUNET_SYSERR ==
|
(GNUNET_SYSERR ==
|
||||||
au->wp->wire_plugin->amount_round (au->wp->wire_plugin->cls,
|
au->wp->wire_plugin->amount_round (au->wp->wire_plugin->cls,
|
||||||
&final_amount)) ||
|
&au->final_amount)) ||
|
||||||
( (0 == final_amount.value) &&
|
( (0 == au->final_amount.value) &&
|
||||||
(0 == final_amount.fraction) ) )
|
(0 == au->final_amount.fraction) ) )
|
||||||
{
|
{
|
||||||
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||||
"Aggregate value too low for transfer\n");
|
"Aggregate value too low for transfer\n");
|
||||||
@ -849,7 +853,7 @@ run_aggregation (void *cls)
|
|||||||
{
|
{
|
||||||
char *amount_s;
|
char *amount_s;
|
||||||
|
|
||||||
amount_s = TALER_amount_to_string (&final_amount);
|
amount_s = TALER_amount_to_string (&au->final_amount);
|
||||||
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||||
"Preparing wire transfer of %s to %s\n",
|
"Preparing wire transfer of %s to %s\n",
|
||||||
amount_s,
|
amount_s,
|
||||||
@ -858,7 +862,7 @@ run_aggregation (void *cls)
|
|||||||
}
|
}
|
||||||
au->ph = au->wp->wire_plugin->prepare_wire_transfer (au->wp->wire_plugin->cls,
|
au->ph = au->wp->wire_plugin->prepare_wire_transfer (au->wp->wire_plugin->cls,
|
||||||
au->wire,
|
au->wire,
|
||||||
&final_amount,
|
&au->final_amount,
|
||||||
exchange_base_url,
|
exchange_base_url,
|
||||||
&au->wtid,
|
&au->wtid,
|
||||||
&prepare_cb,
|
&prepare_cb,
|
||||||
@ -957,7 +961,7 @@ prepare_cb (void *cls,
|
|||||||
au->execution_time,
|
au->execution_time,
|
||||||
&au->wtid,
|
&au->wtid,
|
||||||
au->wire,
|
au->wire,
|
||||||
&au->total_amount))
|
&au->final_amount))
|
||||||
{
|
{
|
||||||
GNUNET_break (0); /* why? how to best recover? */
|
GNUNET_break (0); /* why? how to best recover? */
|
||||||
db_plugin->rollback (db_plugin->cls,
|
db_plugin->rollback (db_plugin->cls,
|
||||||
|
Loading…
Reference in New Issue
Block a user