skeleton logic for analyze_coins()
This commit is contained in:
parent
54b3a9e930
commit
36195e85ea
@ -25,6 +25,7 @@
|
|||||||
* given in the aggregation_tracking table. This needs to be checked separately!
|
* given in the aggregation_tracking table. This needs to be checked separately!
|
||||||
*
|
*
|
||||||
* TODO:
|
* TODO:
|
||||||
|
* - initialize 'currency' (URGENT!)
|
||||||
* - modify auditordb to allow multiple last serial IDs per table in progress tracking
|
* - modify auditordb to allow multiple last serial IDs per table in progress tracking
|
||||||
* - implement coin/denomination audit
|
* - implement coin/denomination audit
|
||||||
* - implement merchant deposit audit
|
* - implement merchant deposit audit
|
||||||
@ -54,6 +55,11 @@ static int global_ret;
|
|||||||
*/
|
*/
|
||||||
static struct TALER_EXCHANGEDB_Plugin *edb;
|
static struct TALER_EXCHANGEDB_Plugin *edb;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Which currency are we doing the audit for?
|
||||||
|
*/
|
||||||
|
static char *currency;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Our session with the #edb.
|
* Our session with the #edb.
|
||||||
*/
|
*/
|
||||||
@ -891,6 +897,7 @@ analyze_reserves (void *cls)
|
|||||||
&rc.total_balance,
|
&rc.total_balance,
|
||||||
&rc.total_fee_balance);
|
&rc.total_fee_balance);
|
||||||
}
|
}
|
||||||
|
// FIXME: handle error in 'ret'!
|
||||||
report_reserve_balance (&rc.total_balance,
|
report_reserve_balance (&rc.total_balance,
|
||||||
&rc.total_fee_balance);
|
&rc.total_fee_balance);
|
||||||
return GNUNET_OK;
|
return GNUNET_OK;
|
||||||
@ -902,7 +909,6 @@ analyze_reserves (void *cls)
|
|||||||
coin, checking deposits, refunds, refresh* and known_coins
|
coin, checking deposits, refunds, refresh* and known_coins
|
||||||
tables */
|
tables */
|
||||||
|
|
||||||
/* TODO! */
|
|
||||||
/**
|
/**
|
||||||
* Summary data we keep per coin.
|
* Summary data we keep per coin.
|
||||||
*/
|
*/
|
||||||
@ -971,6 +977,13 @@ struct DenominationSummary
|
|||||||
* Up to which point have we processed refunds?
|
* Up to which point have we processed refunds?
|
||||||
*/
|
*/
|
||||||
uint64_t last_refund_serial_id;
|
uint64_t last_refund_serial_id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* #GNUNET_YES if this record already existed in the DB.
|
||||||
|
* Used to decide between insert/update in
|
||||||
|
* #sync_denomination().
|
||||||
|
*/
|
||||||
|
int in_db;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -990,9 +1003,228 @@ struct CoinContext
|
|||||||
*/
|
*/
|
||||||
struct GNUNET_CONTAINER_MultiHashMap *denominations;
|
struct GNUNET_CONTAINER_MultiHashMap *denominations;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Total outstanding balances across all denomination keys.
|
||||||
|
*/
|
||||||
|
struct TALER_Amount denom_balance;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Total deposit fees earned so far.
|
||||||
|
*/
|
||||||
|
struct TALER_Amount deposit_fee_balance;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Total melt fees earned so far.
|
||||||
|
*/
|
||||||
|
struct TALER_Amount melt_fee_balance;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Total refund fees earned so far.
|
||||||
|
*/
|
||||||
|
struct TALER_Amount refund_fee_balance;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Current financial risk of the exchange operator with respect
|
||||||
|
* to key compromise.
|
||||||
|
*/
|
||||||
|
struct TALER_Amount risk;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize information about denomination from the database.
|
||||||
|
*
|
||||||
|
* @param denom_hash hash of the public key of the denomination
|
||||||
|
* @param[out] ds summary to initialize
|
||||||
|
* @return #GNUNET_OK on success, #GNUNET_SYSERR on error
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
init_denomination (const struct GNUNET_HashCode *denom_hash,
|
||||||
|
struct DenominationSummary *ds)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = adb->get_denomination_balance (adb->cls,
|
||||||
|
asession,
|
||||||
|
denom_hash,
|
||||||
|
&ds->denom_balance,
|
||||||
|
&ds->deposit_fee_balance,
|
||||||
|
&ds->melt_fee_balance,
|
||||||
|
&ds->refund_fee_balance,
|
||||||
|
&ds->last_reserve_out_serial_id,
|
||||||
|
&ds->last_deposit_serial_id,
|
||||||
|
&ds->last_melt_serial_id,
|
||||||
|
&ds->last_refund_serial_id);
|
||||||
|
if (GNUNET_OK == ret)
|
||||||
|
{
|
||||||
|
ds->in_db = GNUNET_YES;
|
||||||
|
return GNUNET_OK;
|
||||||
|
}
|
||||||
|
if (GNUNET_SYSERR == ret)
|
||||||
|
{
|
||||||
|
GNUNET_break (0);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
GNUNET_assert (GNUNET_OK ==
|
||||||
|
TALER_amount_get_zero (currency,
|
||||||
|
&ds->denom_balance));
|
||||||
|
GNUNET_assert (GNUNET_OK ==
|
||||||
|
TALER_amount_get_zero (currency,
|
||||||
|
&ds->deposit_fee_balance));
|
||||||
|
GNUNET_assert (GNUNET_OK ==
|
||||||
|
TALER_amount_get_zero (currency,
|
||||||
|
&ds->melt_fee_balance));
|
||||||
|
GNUNET_assert (GNUNET_OK ==
|
||||||
|
TALER_amount_get_zero (currency,
|
||||||
|
&ds->refund_fee_balance));
|
||||||
|
return GNUNET_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtain the denomination summary for the given @a dh
|
||||||
|
*
|
||||||
|
* @param cc our execution context
|
||||||
|
* @param dh the denomination hash to use for the lookup
|
||||||
|
* @return NULL on error
|
||||||
|
*/
|
||||||
|
static struct DenominationSummary *
|
||||||
|
get_denomination_summary (struct CoinContext *cc,
|
||||||
|
const struct GNUNET_HashCode *dh)
|
||||||
|
{
|
||||||
|
struct DenominationSummary *ds;
|
||||||
|
|
||||||
|
ds = GNUNET_CONTAINER_multihashmap_get (cc->denominations,
|
||||||
|
dh);
|
||||||
|
if (NULL != ds)
|
||||||
|
return ds;
|
||||||
|
ds = GNUNET_new (struct DenominationSummary);
|
||||||
|
if (GNUNET_OK !=
|
||||||
|
init_denomination (dh,
|
||||||
|
ds))
|
||||||
|
{
|
||||||
|
GNUNET_break (0);
|
||||||
|
GNUNET_free (ds);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
GNUNET_assert (GNUNET_OK ==
|
||||||
|
GNUNET_CONTAINER_multihashmap_put (cc->denominations,
|
||||||
|
dh,
|
||||||
|
ds,
|
||||||
|
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
|
||||||
|
return ds;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write information about the current knowledge about a denomination key
|
||||||
|
* back to the database and update our global reporting data about the
|
||||||
|
* denomination. Also remove and free the memory of @a value.
|
||||||
|
*
|
||||||
|
* @param cls the `struct CoinContext`
|
||||||
|
* @param key the hash of the denomination key
|
||||||
|
* @param value a `struct DenominationSummary`
|
||||||
|
* @return #GNUNET_OK (continue to iterate)
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
sync_denomination (void *cls,
|
||||||
|
const struct GNUNET_HashCode *denom_hash,
|
||||||
|
void *value)
|
||||||
|
{
|
||||||
|
struct CoinContext *cc = cls;
|
||||||
|
struct DenominationSummary *ds = value;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
// FIXME: if expired, insert into historic denomination revenue
|
||||||
|
// and DELETE denomination balance.
|
||||||
|
|
||||||
|
// FIXME: update "global" info about denominations (here?)
|
||||||
|
|
||||||
|
if (ds->in_db)
|
||||||
|
ret = adb->update_denomination_balance (adb->cls,
|
||||||
|
asession,
|
||||||
|
denom_hash,
|
||||||
|
&ds->denom_balance,
|
||||||
|
&ds->deposit_fee_balance,
|
||||||
|
&ds->melt_fee_balance,
|
||||||
|
&ds->refund_fee_balance,
|
||||||
|
ds->last_reserve_out_serial_id,
|
||||||
|
ds->last_deposit_serial_id,
|
||||||
|
ds->last_melt_serial_id,
|
||||||
|
ds->last_refund_serial_id);
|
||||||
|
else
|
||||||
|
ret = adb->insert_denomination_balance (adb->cls,
|
||||||
|
asession,
|
||||||
|
denom_hash,
|
||||||
|
&ds->denom_balance,
|
||||||
|
&ds->deposit_fee_balance,
|
||||||
|
&ds->melt_fee_balance,
|
||||||
|
&ds->refund_fee_balance,
|
||||||
|
ds->last_reserve_out_serial_id,
|
||||||
|
ds->last_deposit_serial_id,
|
||||||
|
ds->last_melt_serial_id,
|
||||||
|
ds->last_refund_serial_id);
|
||||||
|
|
||||||
|
// FIXME handle errors in 'ret'
|
||||||
|
|
||||||
|
GNUNET_assert (GNUNET_YES ==
|
||||||
|
GNUNET_CONTAINER_multihashmap_remove (cc->denominations,
|
||||||
|
denom_hash,
|
||||||
|
ds));
|
||||||
|
GNUNET_free (ds);
|
||||||
|
return GNUNET_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function called with details about all withdraw operations.
|
||||||
|
*
|
||||||
|
* @param cls our `struct CoinContext`
|
||||||
|
* @param rowid unique serial ID for the refresh session in our DB
|
||||||
|
* @param h_blind_ev blinded hash of the coin's public key
|
||||||
|
* @param denom_pub public denomination key of the deposited coin
|
||||||
|
* @param denom_sig signature over the deposited coin
|
||||||
|
* @param reserve_pub public key of the reserve
|
||||||
|
* @param reserve_sig signature over the withdraw operation
|
||||||
|
* @param execution_date when did the wallet withdraw the coin
|
||||||
|
* @param amount_with_fee amount that was withdrawn
|
||||||
|
* @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
withdraw_cb (void *cls,
|
||||||
|
uint64_t rowid,
|
||||||
|
const struct GNUNET_HashCode *h_blind_ev,
|
||||||
|
const struct TALER_DenominationPublicKey *denom_pub,
|
||||||
|
const struct TALER_DenominationSignature *denom_sig,
|
||||||
|
const struct TALER_ReservePublicKeyP *reserve_pub,
|
||||||
|
const struct TALER_ReserveSignatureP *reserve_sig,
|
||||||
|
struct GNUNET_TIME_Absolute execution_date,
|
||||||
|
const struct TALER_Amount *amount_with_fee)
|
||||||
|
{
|
||||||
|
struct CoinContext *cc = cls;
|
||||||
|
struct DenominationSummary *ds;
|
||||||
|
struct GNUNET_HashCode dh;
|
||||||
|
const struct TALER_EXCHANGEDB_DenominationKeyInformationP *dki;
|
||||||
|
|
||||||
|
if (GNUNET_OK !=
|
||||||
|
get_denomination_info (denom_pub,
|
||||||
|
&dki,
|
||||||
|
&dh))
|
||||||
|
{
|
||||||
|
GNUNET_break (0);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
ds = get_denomination_summary (cc,
|
||||||
|
&dh);
|
||||||
|
// FIXME: use ds, dki, etc.
|
||||||
|
return GNUNET_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Analyze the exchange's processing of coins.
|
* Analyze the exchange's processing of coins.
|
||||||
*
|
*
|
||||||
@ -1003,16 +1235,139 @@ static int
|
|||||||
analyze_coins (void *cls)
|
analyze_coins (void *cls)
|
||||||
{
|
{
|
||||||
struct CoinContext cc;
|
struct CoinContext cc;
|
||||||
|
int dret;
|
||||||
|
int rret;
|
||||||
|
|
||||||
|
/* setup 'cc' */
|
||||||
|
dret = adb->get_denomination_summary (adb->cls,
|
||||||
|
asession,
|
||||||
|
&master_pub,
|
||||||
|
&cc.denom_balance,
|
||||||
|
&cc.deposit_fee_balance,
|
||||||
|
&cc.melt_fee_balance,
|
||||||
|
&cc.refund_fee_balance);
|
||||||
|
if (GNUNET_SYSERR == dret)
|
||||||
|
{
|
||||||
|
GNUNET_break (0);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
if (GNUNET_NO == dret)
|
||||||
|
{
|
||||||
|
GNUNET_assert (GNUNET_OK ==
|
||||||
|
TALER_amount_get_zero (currency,
|
||||||
|
&cc.denom_balance));
|
||||||
|
GNUNET_assert (GNUNET_OK ==
|
||||||
|
TALER_amount_get_zero (currency,
|
||||||
|
&cc.deposit_fee_balance));
|
||||||
|
GNUNET_assert (GNUNET_OK ==
|
||||||
|
TALER_amount_get_zero (currency,
|
||||||
|
&cc.melt_fee_balance));
|
||||||
|
GNUNET_assert (GNUNET_OK ==
|
||||||
|
TALER_amount_get_zero (currency,
|
||||||
|
&cc.refund_fee_balance));
|
||||||
|
}
|
||||||
|
rret = adb->get_risk_summary (adb->cls,
|
||||||
|
asession,
|
||||||
|
&master_pub,
|
||||||
|
&cc.risk);
|
||||||
|
if (GNUNET_SYSERR == dret)
|
||||||
|
{
|
||||||
|
GNUNET_break (0);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
if (GNUNET_NO == dret)
|
||||||
|
{
|
||||||
|
/* FIXME: initialize cc->risk by other means... */
|
||||||
|
}
|
||||||
|
|
||||||
cc.coins = GNUNET_CONTAINER_multihashmap_create (1024,
|
cc.coins = GNUNET_CONTAINER_multihashmap_create (1024,
|
||||||
GNUNET_YES);
|
GNUNET_NO);
|
||||||
cc.denominations = GNUNET_CONTAINER_multihashmap_create (256,
|
cc.denominations = GNUNET_CONTAINER_multihashmap_create (256,
|
||||||
GNUNET_YES);
|
GNUNET_NO);
|
||||||
|
|
||||||
|
/* process withdrawals */
|
||||||
|
if (GNUNET_OK !=
|
||||||
|
edb->select_reserves_out_above_serial_id (edb->cls,
|
||||||
|
esession,
|
||||||
|
42LL, // FIXME
|
||||||
|
&withdraw_cb,
|
||||||
|
&cc))
|
||||||
|
{
|
||||||
|
// FIXME...
|
||||||
|
}
|
||||||
|
|
||||||
|
/* process refreshs */
|
||||||
|
if (GNUNET_OK !=
|
||||||
|
edb->select_refreshs_above_serial_id (edb->cls,
|
||||||
|
esession,
|
||||||
|
42LL, // FIXME
|
||||||
|
NULL, // FIXME
|
||||||
|
&cc))
|
||||||
|
{
|
||||||
|
// FIXME...
|
||||||
|
}
|
||||||
|
|
||||||
|
/* process deposits */
|
||||||
|
if (GNUNET_OK !=
|
||||||
|
edb->select_deposits_above_serial_id (edb->cls,
|
||||||
|
esession,
|
||||||
|
42LL, // FIXME
|
||||||
|
NULL, // FIXME
|
||||||
|
&cc))
|
||||||
|
{
|
||||||
|
// FIXME...
|
||||||
|
}
|
||||||
|
|
||||||
|
/* process refunds */
|
||||||
|
if (GNUNET_OK !=
|
||||||
|
edb->select_refunds_above_serial_id (edb->cls,
|
||||||
|
esession,
|
||||||
|
42LL, // FIXME
|
||||||
|
NULL, // FIXME
|
||||||
|
&cc))
|
||||||
|
{
|
||||||
|
// FIXME...
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME...
|
||||||
|
|
||||||
|
/* FIXME: check invariants */
|
||||||
|
|
||||||
|
/* sync 'cc' back to disk */
|
||||||
|
GNUNET_CONTAINER_multihashmap_iterate (cc.denominations,
|
||||||
|
&sync_denomination,
|
||||||
|
&cc);
|
||||||
GNUNET_CONTAINER_multihashmap_destroy (cc.denominations);
|
GNUNET_CONTAINER_multihashmap_destroy (cc.denominations);
|
||||||
GNUNET_CONTAINER_multihashmap_destroy (cc.coins);
|
GNUNET_CONTAINER_multihashmap_destroy (cc.coins);
|
||||||
|
|
||||||
|
if (GNUNET_YES == rret)
|
||||||
|
rret = adb->update_risk_summary (adb->cls,
|
||||||
|
asession,
|
||||||
|
&master_pub,
|
||||||
|
&cc.risk);
|
||||||
|
else
|
||||||
|
rret = adb->insert_risk_summary (adb->cls,
|
||||||
|
asession,
|
||||||
|
&master_pub,
|
||||||
|
&cc.risk);
|
||||||
|
// FIXME: handle error in 'rret'!
|
||||||
|
if (GNUNET_YES == dret)
|
||||||
|
dret = adb->update_denomination_summary (adb->cls,
|
||||||
|
asession,
|
||||||
|
&master_pub,
|
||||||
|
&cc.denom_balance,
|
||||||
|
&cc.deposit_fee_balance,
|
||||||
|
&cc.melt_fee_balance,
|
||||||
|
&cc.refund_fee_balance);
|
||||||
|
else
|
||||||
|
dret = adb->insert_denomination_summary (adb->cls,
|
||||||
|
asession,
|
||||||
|
&master_pub,
|
||||||
|
&cc.denom_balance,
|
||||||
|
&cc.deposit_fee_balance,
|
||||||
|
&cc.melt_fee_balance,
|
||||||
|
&cc.refund_fee_balance);
|
||||||
|
// FIXME: handle error in 'dret'!
|
||||||
return GNUNET_OK;
|
return GNUNET_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2049,7 +2049,7 @@ postgres_update_denomination_balance (void *cls,
|
|||||||
* melts for the above information
|
* melts for the above information
|
||||||
* @param[out] last_refund_serial_id up to which point did we consider
|
* @param[out] last_refund_serial_id up to which point did we consider
|
||||||
* refunds for the above information
|
* refunds for the above information
|
||||||
* @return #GNUNET_OK on success; #GNUNET_SYSERR on failure
|
* @return #GNUNET_OK on success; #GNUNET_NO if no record found, #GNUNET_SYSERR on failure
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
postgres_get_denomination_balance (void *cls,
|
postgres_get_denomination_balance (void *cls,
|
||||||
|
@ -603,7 +603,7 @@ struct TALER_AUDITORDB_Plugin
|
|||||||
* melts for the above information
|
* melts for the above information
|
||||||
* @param[out] last_refund_serial_id up to which point did we consider
|
* @param[out] last_refund_serial_id up to which point did we consider
|
||||||
* refunds for the above information
|
* refunds for the above information
|
||||||
* @return #GNUNET_OK on success; #GNUNET_SYSERR on failure
|
* @return #GNUNET_OK on success; #GNUNET_NO if no record found, #GNUNET_SYSERR on failure
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
(*get_denomination_balance)(void *cls,
|
(*get_denomination_balance)(void *cls,
|
||||||
|
Loading…
Reference in New Issue
Block a user