more work on auditor, listing open TODOs

This commit is contained in:
Christian Grothoff 2017-03-14 18:00:17 +01:00
parent 6d798cecba
commit 296f919ce4
No known key found for this signature in database
GPG Key ID: 939E6BE1E29FC3CC
3 changed files with 578 additions and 40 deletions

View File

@ -22,7 +22,22 @@
* - This auditor does not verify that 'reserves_in' actually matches
* the wire transfers from the bank. This needs to be checked separately!
* - Similarly, we do not check that the outgoing wire transfers match those
* given in the XXX table. This needs to be checked separately!
* given in the aggregation_tracking table. This needs to be checked separately!
*
* TODO:
* - initialize master_pub via command-line argument (URGENT!)
* - modify auditordb to allow multiple last serial IDs per table in progress tracking
* - modify auditordb to return row ID where we need it for diagnostics
* - implement coin/denomination audit
* - implement merchant deposit audit
* - see if we need more tables there
* - write reporting logic to output nice report beyond GNUNET_log()
*
* EXTERNAL:
* - add tool to pay-back expired reserves (#4956), and support here
* - add tool to verify 'reserves_in' from wire transfer inspection
* - add tool to trigger computation of historic revenues
* (move balances from 'current' revenue/profits to 'historic' tables)
*/
#include "platform.h"
#include <gnunet/gnunet_util_lib.h>
@ -115,6 +130,28 @@ report_row_inconsistency (const char *table,
}
/**
* Report a minor inconsistency in the exchange's database (i.e. something
* relating to timestamps that should have no financial implications).
*
* @param table affected table
* @param rowid affected row, UINT64_MAX if row is missing
* @param diagnostic message explaining the problem
*/
static void
report_row_minor_inconsistency (const char *table,
uint64_t rowid,
const char *diagnostic)
{
// TODO: implement proper reporting logic writing to file.
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Minor inconsistency detected in table %s at row %llu: %s\n",
table,
(unsigned long long) rowid,
diagnostic);
}
/**
* Report a global inconsistency with respect to a reserve.
*
@ -137,6 +174,43 @@ report_reserve_inconsistency (const struct TALER_ReservePublicKeyP *reserve_pub,
}
/**
* Report the final result on the reserve balances of the exchange.
* The reserve must have @a total_balance in its escrow account just
* to cover outstanding reserve funds (outstanding coins are on top).
* The reserve has made @a total_fee_balance in profit from withdrawal
* operations alone.
*
* Note that this is for the "ongoing" reporting period. Historic
* revenue (as stored via the "insert_historic_reserve_revenue")
* is not included in the @a total_fee_balance.
*
* @param total_balance how much money (in total) is left in all of the
* reserves (that has not been withdrawn)
* @param total_fee_balance how much money (in total) did the reserve
* make from withdrawal fees
*/
static void
report_reserve_balance (const struct TALER_Amount *total_balance,
const struct TALER_Amount *total_fee_balance)
{
char *balance;
char *fees;
balance = TALER_amount_to_string (total_balance);
fees = TALER_amount_to_string (total_fee_balance);
// TODO: implement proper reporting logic writing to file.
GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
"Total escrow balance to be held for reserves: %s\n",
balance);
GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
"Total profits made from reserves: %s\n",
fees);
GNUNET_free (fees);
GNUNET_free (balance);
}
/* ************************* Transaction-global state ************************ */
/**
@ -236,6 +310,7 @@ clear_transaction_state_cache ()
/* ***************************** Analyze reserves ************************ */
/* This logic checks the reserves_in, reserves_out and reserves-tables */
/**
* Summary data we keep per reserve.
@ -244,46 +319,62 @@ struct ReserveSummary
{
/**
* Public key of the reserve.
* Always set when the struct is first initialized.
*/
struct TALER_ReservePublicKeyP reserve_pub;
/**
* Sum of all incoming transfers.
* Sum of all incoming transfers during this transaction.
* Updated only in #handle_reserve_in().
*/
struct TALER_Amount total_in;
/**
* Sum of all outgoing transfers.
* Sum of all outgoing transfers during this transaction (includes fees).
* Updated only in #handle_reserve_out().
*/
struct TALER_Amount total_out;
/**
* Sum of withdraw fees encountered during this transaction.
*/
struct TALER_Amount total_fee;
/**
* Previous balance of the reserve as remembered by the auditor.
* (updated based on @e total_in and @e total_out at the end).
*/
struct TALER_Amount a_balance;
/**
* Previous withdraw fee balance of the reserve, as remembered by the auditor.
* (updated based on @e total_fee at the end).
*/
struct TALER_Amount a_withdraw_fee_balance;
/**
* Previous reserve expiration data, as remembered by the auditor.
* (updated on-the-fly in #handle_reserve_in()).
*/
struct GNUNET_TIME_Absolute a_expiration_date;
/**
* Previous last processed reserve_in serial ID, as remembered by the auditor.
* (updated on-the-fly in #handle_reserve_in()).
*/
uint64_t a_last_reserve_in_serial_id;
/**
* Previous last processed reserve_out serial ID, as remembered by the auditor.
* (updated on-the-fly in #handle_reserve_out()).
*/
uint64_t a_last_reserve_out_serial_id;
/**
* Did we have a previous reserve info?
* Did we have a previous reserve info? Used to decide between
* UPDATE and INSERT later. Initialized in
* #load_auditor_reserve_summary() together with the a-* values
* (if available).
*/
int had_ri;
@ -292,6 +383,8 @@ struct ReserveSummary
/**
* Load the auditor's remembered state about the reserve into @a rs.
* The "total_in" and "total_out" amounts of @a rs must already be
* initialized (so we can determine the currency).
*
* @param[in|out] rs reserve summary to (fully) initialize
* @return #GNUNET_OK on success, #GNUNET_SYSERR on DB errors
@ -318,19 +411,60 @@ load_auditor_reserve_summary (struct ReserveSummary *rs)
if (GNUNET_NO == ret)
{
rs->had_ri = GNUNET_NO;
// FIXME: set rs->a-values to sane defaults!
GNUNET_assert (GNUNET_OK ==
TALER_amount_get_zero (rs->total_in.currency,
&rs->a_balance));
GNUNET_assert (GNUNET_OK ==
TALER_amount_get_zero (rs->total_in.currency,
&rs->a_withdraw_fee_balance));
return GNUNET_OK;
}
rs->had_ri = GNUNET_YES;
/* TODO: check values we got are sane? */
if ( (GNUNET_YES !=
TALER_amount_cmp_currency (&rs->a_balance,
&rs->a_withdraw_fee_balance)) ||
(GNUNET_YES !=
TALER_amount_cmp_currency (&rs->total_in,
&rs->a_balance)) )
{
report_row_inconsistency ("auditor-reserve-info",
UINT64_MAX, /* FIXME: modify API to get rowid! */
"currencies for reserve differ");
/* TODO: find a sane way to continue... */
GNUNET_break (0);
return GNUNET_SYSERR;
}
return GNUNET_OK;
}
/**
* Closure to the various callbacks we make while checking a reserve.
*/
struct ReserveContext
{
/**
* Map from hash of reserve's public key to a `struct ReserveSummary`.
*/
struct GNUNET_CONTAINER_MultiHashMap *reserves;
/**
* Total balance in all reserves (updated).
*/
struct TALER_Amount total_balance;
/**
* Total withdraw fees gotten in all reserves (updated).
*/
struct TALER_Amount total_fee_balance;
};
/**
* Function called with details about incoming wire transfers.
*
* @param cls our `struct GNUNET_CONTAINER_MultiHashMap` with the reserves
* @param cls our `struct ReserveContext`
* @param rowid unique serial ID for the refresh session in our DB
* @param reserve_pub public key of the reserve (also the WTID)
* @param credit amount that was received
@ -348,16 +482,17 @@ handle_reserve_in (void *cls,
const json_t *transfer_details,
struct GNUNET_TIME_Absolute execution_date)
{
struct GNUNET_CONTAINER_MultiHashMap *reserves = cls;
struct ReserveContext *rc = cls;
struct GNUNET_HashCode key;
struct ReserveSummary *rs;
struct GNUNET_TIME_Absolute expiry;
GNUNET_assert (rowid >= reserve_in_serial_id); /* should be monotonically increasing */
reserve_in_serial_id = rowid + 1;
GNUNET_CRYPTO_hash (reserve_pub,
sizeof (*reserve_pub),
&key);
rs = GNUNET_CONTAINER_multihashmap_get (reserves,
rs = GNUNET_CONTAINER_multihashmap_get (rc->reserves,
&key);
if (NULL == rs)
{
@ -367,6 +502,9 @@ handle_reserve_in (void *cls,
GNUNET_assert (GNUNET_OK ==
TALER_amount_get_zero (credit->currency,
&rs->total_out));
GNUNET_assert (GNUNET_OK ==
TALER_amount_get_zero (credit->currency,
&rs->total_fee));
if (GNUNET_OK !=
load_auditor_reserve_summary (rs))
{
@ -375,7 +513,7 @@ handle_reserve_in (void *cls,
return GNUNET_SYSERR;
}
GNUNET_assert (GNUNET_OK ==
GNUNET_CONTAINER_multihashmap_put (reserves,
GNUNET_CONTAINER_multihashmap_put (rc->reserves,
&key,
rs,
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
@ -387,6 +525,12 @@ handle_reserve_in (void *cls,
&rs->total_in,
credit));
}
GNUNET_assert (rowid >= rs->a_last_reserve_in_serial_id);
rs->a_last_reserve_in_serial_id = rowid + 1;
expiry = GNUNET_TIME_absolute_add (execution_date,
TALER_IDLE_RESERVE_EXPIRATION_TIME);
rs->a_expiration_date = GNUNET_TIME_absolute_max (rs->a_expiration_date,
expiry);
return GNUNET_OK;
}
@ -394,7 +538,7 @@ handle_reserve_in (void *cls,
/**
* Function called with details about withdraw operations.
*
* @param cls our `struct GNUNET_CONTAINER_MultiHashMap` with the reserves
* @param cls our `struct ReserveContext`
* @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
@ -416,11 +560,14 @@ handle_reserve_out (void *cls,
struct GNUNET_TIME_Absolute execution_date,
const struct TALER_Amount *amount_with_fee)
{
struct GNUNET_CONTAINER_MultiHashMap *reserves = cls;
struct ReserveContext *rc = cls;
struct TALER_WithdrawRequestPS wsrd;
struct GNUNET_HashCode key;
struct ReserveSummary *rs;
const struct TALER_EXCHANGEDB_DenominationKeyInformationP *dki;
struct TALER_Amount withdraw_fee;
struct GNUNET_TIME_Absolute valid_start;
struct GNUNET_TIME_Absolute expire_withdraw;
int ret;
/* should be monotonically increasing */
@ -444,7 +591,16 @@ handle_reserve_out (void *cls,
return GNUNET_OK;
}
/* check that execution date is within withdraw range for denom_pub (?) */
/* check that execution date is within withdraw range for denom_pub */
valid_start = GNUNET_TIME_absolute_ntoh (dki->properties.start);
expire_withdraw = GNUNET_TIME_absolute_ntoh (dki->properties.expire_withdraw);
if ( (valid_start.abs_value_us > execution_date.abs_value_us) ||
(expire_withdraw.abs_value_us < execution_date.abs_value_us) )
{
report_row_minor_inconsistency ("reserve_out",
rowid,
"denomination key not valid at time of withdrawal");
}
/* check reserve_sig */
wsrd.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW);
@ -468,7 +624,7 @@ handle_reserve_out (void *cls,
GNUNET_CRYPTO_hash (reserve_pub,
sizeof (*reserve_pub),
&key);
rs = GNUNET_CONTAINER_multihashmap_get (reserves,
rs = GNUNET_CONTAINER_multihashmap_get (rc->reserves,
&key);
if (NULL == rs)
{
@ -478,6 +634,9 @@ handle_reserve_out (void *cls,
GNUNET_assert (GNUNET_OK ==
TALER_amount_get_zero (amount_with_fee->currency,
&rs->total_in));
GNUNET_assert (GNUNET_OK ==
TALER_amount_get_zero (amount_with_fee->currency,
&rs->total_fee));
if (GNUNET_OK !=
load_auditor_reserve_summary (rs))
{
@ -486,7 +645,7 @@ handle_reserve_out (void *cls,
return GNUNET_SYSERR;
}
GNUNET_assert (GNUNET_OK ==
GNUNET_CONTAINER_multihashmap_put (reserves,
GNUNET_CONTAINER_multihashmap_put (rc->reserves,
&key,
rs,
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
@ -498,6 +657,16 @@ handle_reserve_out (void *cls,
&rs->total_out,
amount_with_fee));
}
GNUNET_assert (rowid >= rs->a_last_reserve_out_serial_id);
rs->a_last_reserve_out_serial_id = rowid + 1;
TALER_amount_ntoh (&withdraw_fee,
&dki->properties.fee_withdraw);
GNUNET_assert (GNUNET_OK ==
TALER_amount_add (&rs->total_fee,
&rs->total_fee,
&withdraw_fee));
return GNUNET_OK;
}
@ -508,7 +677,7 @@ handle_reserve_out (void *cls,
*
* Remove all reserves that we are happy with from the DB.
*
* @param cls our `struct GNUNET_CONTAINER_MultiHashMap` with the reserves
* @param cls our `struct ReserveContext`
* @param key hash of the reserve public key
* @param value a `struct ReserveSummary`
* @return #GNUNET_OK to process more entries
@ -518,7 +687,7 @@ verify_reserve_balance (void *cls,
const struct GNUNET_HashCode *key,
void *value)
{
struct GNUNET_CONTAINER_MultiHashMap *reserves = cls;
struct ReserveContext *rc = cls;
struct ReserveSummary *rs = value;
struct TALER_EXCHANGEDB_Reserve reserve;
struct TALER_Amount balance;
@ -542,13 +711,22 @@ verify_reserve_balance (void *cls,
GNUNET_free (diag);
return GNUNET_OK;
}
/* TODO: check reserve.expiry */
/* FIXME: simplified computation as we have no previous reserve state yet */
/* FIXME: actually update withdraw fee balance, expiration data and serial IDs! */
if (GNUNET_OK !=
TALER_amount_add (&balance,
&rs->total_in,
&rs->a_balance))
{
report_reserve_inconsistency (&rs->reserve_pub,
&rs->total_in,
&rs->a_balance,
"could not add old balance to new balance");
goto cleanup;
}
if (GNUNET_SYSERR ==
TALER_amount_subtract (&balance,
&rs->total_in,
&balance,
&rs->total_out))
{
report_reserve_inconsistency (&rs->reserve_pub,
@ -567,12 +745,55 @@ verify_reserve_balance (void *cls,
goto cleanup;
}
/* FIXME: if balance is zero, create reserve summary and drop reserve details! */
if (0 == GNUNET_TIME_absolute_get_remaining (rs->a_expiration_date).rel_value_us)
{
/* TODO: handle case where reserve is expired! (#4956) */
/* NOTE: we may or may not have seen the wire-back transfer at this time,
as the expiration may have just now happened.
(That is, after we add the table structures and the logic to track
such transfers...) */
}
if ( (0ULL == balance.value) &&
(0U == balance.fraction) )
{
/* TODO: balance is zero, drop reserve details (and then do not update/insert) */
if (rs->had_ri)
{
ret = adb->del_reserve_info (adb->cls,
asession,
&rs->reserve_pub,
&master_pub);
if (GNUNET_SYSERR == ret)
{
GNUNET_break (0);
goto cleanup;
}
if (GNUNET_NO == ret)
{
GNUNET_break (0);
ret = GNUNET_SYSERR;
goto cleanup;
}
}
ret = GNUNET_OK;
goto cleanup;
}
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Reserve balance `%s' OK\n",
TALER_B2S (&rs->reserve_pub));
/* Add withdraw fees we encountered to totals */
if (GNUNET_YES !=
TALER_amount_add (&rs->a_withdraw_fee_balance,
&rs->a_withdraw_fee_balance,
&rs->total_fee))
{
GNUNET_break (0);
ret = GNUNET_SYSERR;
goto cleanup;
}
if (rs->had_ri)
ret = adb->update_reserve_info (adb->cls,
asession,
@ -594,10 +815,28 @@ verify_reserve_balance (void *cls,
rs->a_last_reserve_in_serial_id,
rs->a_last_reserve_out_serial_id);
if ( (GNUNET_YES !=
TALER_amount_add (&rc->total_balance,
&rc->total_balance,
&rs->total_in)) ||
(GNUNET_SYSERR ==
TALER_amount_subtract (&rc->total_balance,
&rc->total_balance,
&rs->total_out)) ||
(GNUNET_YES !=
TALER_amount_add (&rc->total_fee_balance,
&rc->total_fee_balance,
&rs->total_fee)) )
{
GNUNET_break (0);
ret = GNUNET_SYSERR;
goto cleanup;
}
cleanup:
GNUNET_assert (GNUNET_YES ==
GNUNET_CONTAINER_multihashmap_remove (reserves,
GNUNET_CONTAINER_multihashmap_remove (rc->reserves,
key,
rs));
GNUNET_free (rs);
@ -614,18 +853,29 @@ verify_reserve_balance (void *cls,
static int
analyze_reserves (void *cls)
{
/* Map from hash of reserve's public key to a `struct ReserveSummary`. */
struct GNUNET_CONTAINER_MultiHashMap *reserves;
struct ReserveContext rc;
int ret;
reserves = GNUNET_CONTAINER_multihashmap_create (512,
GNUNET_NO);
ret = adb->get_reserve_summary (adb->cls,
asession,
&master_pub,
&rc.total_balance,
&rc.total_fee_balance);
if (GNUNET_SYSERR == ret)
{
GNUNET_break (0);
return GNUNET_SYSERR;
}
rc.reserves = GNUNET_CONTAINER_multihashmap_create (512,
GNUNET_NO);
if (GNUNET_OK !=
edb->select_reserves_in_above_serial_id (edb->cls,
esession,
reserve_in_serial_id,
&handle_reserve_in,
reserves))
&rc))
{
GNUNET_break (0);
return GNUNET_SYSERR;
@ -635,18 +885,234 @@ analyze_reserves (void *cls)
esession,
reserve_out_serial_id,
&handle_reserve_out,
reserves))
&rc))
{
GNUNET_break (0);
return GNUNET_SYSERR;
}
GNUNET_CONTAINER_multihashmap_iterate (reserves,
&verify_reserve_balance,
reserves);
GNUNET_break (0 ==
GNUNET_CONTAINER_multihashmap_size (reserves));
GNUNET_CONTAINER_multihashmap_destroy (reserves);
/* TODO: iterate over table for reserve expiration refunds! (#4956) */
GNUNET_CONTAINER_multihashmap_iterate (rc.reserves,
&verify_reserve_balance,
&rc);
GNUNET_break (0 ==
GNUNET_CONTAINER_multihashmap_size (rc.reserves));
GNUNET_CONTAINER_multihashmap_destroy (rc.reserves);
if (GNUNET_NO == ret)
{
ret = adb->insert_reserve_summary (adb->cls,
asession,
&master_pub,
&rc.total_balance,
&rc.total_fee_balance);
}
else
{
ret = adb->update_reserve_summary (adb->cls,
asession,
&master_pub,
&rc.total_balance,
&rc.total_fee_balance);
}
report_reserve_balance (&rc.total_balance,
&rc.total_fee_balance);
return GNUNET_OK;
}
/* ************************* Analyze coins ******************** */
/* This logic checks that the exchange did the right thing for each
coin, checking deposits, refunds, refresh* and known_coins
tables */
/* TODO! */
/**
* Summary data we keep per coin.
*/
struct CoinSummary
{
/**
* Denomination of the coin with fee structure.
*/
struct TALER_EXCHANGEDB_DenominationKeyInformationP *dki;
/**
* Public key of the coin.
*/
struct TALER_CoinSpendPublicKeyP coin_pub;
/**
* Total value lost of the coin (deposits, refreshs and fees minus refunds).
* Must be smaller than the coin's total (origional) value.
*/
struct TALER_Amount spent;
};
/**
* Summary data we keep per denomination.
*/
struct DenominationSummary
{
/**
* Total value of coins issued with this denomination key.
*/
struct TALER_Amount denom_balance;
/**
* Total amount of deposit fees made.
*/
struct TALER_Amount deposit_fee_balance;
/**
* Total amount of melt fees made.
*/
struct TALER_Amount melt_fee_balance;
/**
* Total amount of refund fees made.
*/
struct TALER_Amount refund_fee_balance;
/**
* Up to which point have we processed reserves_out?
*/
uint64_t last_reserve_out_serial_id;
/**
* Up to which point have we processed deposits?
*/
uint64_t last_deposit_serial_id;
/**
* Up to which point have we processed melts?
*/
uint64_t last_melt_serial_id;
/**
* Up to which point have we processed refunds?
*/
uint64_t last_refund_serial_id;
};
/**
* Closure for callbacks during #analyze_coins().
*/
struct CoinContext
{
/**
* Map for tracking information about coins.
*/
struct GNUNET_CONTAINER_MultiHashMap *coins;
/**
* Map for tracking information about denominations.
*/
struct GNUNET_CONTAINER_MultiHashMap *denominations;
};
/**
* Analyze the exchange's processing of coins.
*
* @param cls closure
* @param int #GNUNET_OK on success, #GNUNET_SYSERR on hard errors
*/
static int
analyze_coins (void *cls)
{
struct CoinContext cc;
cc.coins = GNUNET_CONTAINER_multihashmap_create (1024,
GNUNET_YES);
cc.denominations = GNUNET_CONTAINER_multihashmap_create (256,
GNUNET_YES);
GNUNET_CONTAINER_multihashmap_destroy (cc.denominations);
GNUNET_CONTAINER_multihashmap_destroy (cc.coins);
return GNUNET_OK;
}
/* ************************* Analyze merchants ******************** */
/* This logic checks that the aggregator did the right thing
paying each merchant what they were due (and on time). */
/**
* Summary data we keep per merchant.
*/
struct MerchantSummary
{
/**
* Which account were we supposed to pay?
*/
struct GNUNET_HashCode h_wire;
/**
* Total due to be paid to @e h_wire.
*/
struct TALER_Amount total_due;
/**
* Total paid to @e h_wire.
*/
struct TALER_Amount total_paid;
/**
* Total wire fees charged.
*/
struct TALER_Amount total_fees;
/**
* Last (expired) refund deadline of all the transactions totaled
* up in @e due.
*/
struct GNUNET_TIME_Absolute last_refund_deadline;
};
/**
* Closure for callbacks during #analyze_merchants().
*/
struct MerchantContext
{
/**
* Map for tracking information about merchants.
*/
struct GNUNET_CONTAINER_MultiHashMap *merchants;
};
/**
* Analyze the exchange aggregator's payment processing.
*
* @param cls closure
* @param int #GNUNET_OK on success, #GNUNET_SYSERR on hard errors
*/
static int
analyze_merchants (void *cls)
{
struct MerchantContext mc;
mc.merchants = GNUNET_CONTAINER_multihashmap_create (1024,
GNUNET_YES);
// TODO
GNUNET_CONTAINER_multihashmap_destroy (mc.merchants);
return GNUNET_OK;
}
@ -835,7 +1301,10 @@ setup_sessions_and_run ()
transact (&analyze_reserves,
NULL);
// NOTE: add other 'transact (&analyze_*)'-calls here as they are implemented.
transact (&analyze_coins,
NULL);
transact (&analyze_merchants,
NULL);
}

View File

@ -649,6 +649,13 @@ postgres_prepare (PGconn *db_conn)
" WHERE reserve_pub=$1 AND master_pub=$2;",
2, NULL);
/* Used in #postgres_del_reserve_info() */
PREPARE ("auditor_reserves_delete",
"DELETE"
" FROM auditor_reserves"
" WHERE reserve_pub=$1 AND master_pub=$2;",
2, NULL);
/* Used in #postgres_insert_reserve_summary() */
PREPARE ("auditor_reserve_balance_insert",
"INSERT INTO auditor_reserve_balance"
@ -1650,6 +1657,47 @@ postgres_update_reserve_info (void *cls,
}
/**
* Delete information about a reserve.
*
* @param cls the @e cls of this struct with the plugin-specific state
* @param session connection to use
* @param reserve_pub public key of the reserve
* @param master_pub master public key of the exchange
* @return #GNUNET_OK on success; #GNUNET_NO if there is no known
* record about this reserve; #GNUNET_SYSERR on failure
*/
static int
postgres_del_reserve_info (void *cls,
struct TALER_AUDITORDB_Session *session,
const struct TALER_ReservePublicKeyP *reserve_pub,
const struct TALER_MasterPublicKeyP *master_pub)
{
struct GNUNET_PQ_QueryParam params[] = {
GNUNET_PQ_query_param_auto_from_type (reserve_pub),
GNUNET_PQ_query_param_auto_from_type (master_pub),
GNUNET_PQ_query_param_end
};
PGresult *result;
int ret;
result = GNUNET_PQ_exec_prepared (session->conn,
"auditor_reserves_delete",
params);
ret = PQresultStatus (result);
if (PGRES_COMMAND_OK != ret)
{
BREAK_DB_ERR (result);
PQclear (result);
return GNUNET_SYSERR;
}
if (0 == strcmp ("0",
PQcmdTuples (result)))
return GNUNET_NO;
return GNUNET_OK;
}
/**
* Get information about a reserve.
*
@ -3110,6 +3158,7 @@ libtaler_plugin_auditordb_postgres_init (void *cls)
plugin->update_auditor_progress = &postgres_update_auditor_progress;
plugin->insert_auditor_progress = &postgres_insert_auditor_progress;
plugin->del_reserve_info = &postgres_del_reserve_info;
plugin->get_reserve_info = &postgres_get_reserve_info;
plugin->update_reserve_info = &postgres_update_reserve_info;
plugin->insert_reserve_info = &postgres_insert_reserve_info;

View File

@ -1,6 +1,6 @@
/*
This file is part of TALER
Copyright (C) 2014-2016 GNUnet e.V.
Copyright (C) 2014-2017 Inria and GNUnet e.V.
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
@ -252,6 +252,10 @@ struct TALER_AUDITORDB_Plugin
void *cb_cls);
// FIXME: this does not quite work, as independent transactions
// touch certain tables (i.e. reserves_out), so we need some of
// these counters more than once!
// ALSO: put all of these counters into a struct, this is very ugly...
/**
* Insert information about the auditor's progress with an exchange's
* data.
@ -420,6 +424,22 @@ struct TALER_AUDITORDB_Plugin
uint64_t *last_reserve_out_serial_id);
/**
* Delete information about a reserve.
*
* @param cls the @e cls of this struct with the plugin-specific state
* @param session connection to use
* @param reserve_pub public key of the reserve
* @param master_pub master public key of the exchange
* @return #GNUNET_OK on success; #GNUNET_NO if there is no known
* record about this reserve; #GNUNET_SYSERR on failure
*/
int
(*del_reserve_info)(void *cls,
struct TALER_AUDITORDB_Session *session,
const struct TALER_ReservePublicKeyP *reserve_pub,
const struct TALER_MasterPublicKeyP *master_pub);
/**
* Insert information about all reserves. There must not be an
@ -488,7 +508,7 @@ struct TALER_AUDITORDB_Plugin
* @param cls the @e cls of this struct with the plugin-specific state
* @param session connection to use
* @param denom_pub_hash hash of the denomination public key
* @param denom_balance value of coins outstanding with this denomination key
* @param denom_balance value of coins outstanding (or issued?) with this denomination key
* @param deposit_fee_balance total deposit fees collected for this DK
* @param melt_fee_balance total melt fees collected for this DK
* @param refund_fee_balance total refund fees collected for this DK
@ -523,7 +543,7 @@ struct TALER_AUDITORDB_Plugin
* @param cls the @e cls of this struct with the plugin-specific state
* @param session connection to use
* @param denom_pub_hash hash of the denomination public key
* @param denom_balance value of coins outstanding with this denomination key
* @param denom_balance value of coins outstanding (or issued?) with this denomination key
* @param deposit_fee_balance total deposit fees collected for this DK
* @param melt_fee_balance total melt fees collected for this DK
* @param refund_fee_balance total refund fees collected for this DK
@ -557,7 +577,7 @@ struct TALER_AUDITORDB_Plugin
* @param cls the @e cls of this struct with the plugin-specific state
* @param session connection to use
* @param denom_pub_hash hash of the denomination public key
* @param[out] denom_balance value of coins outstanding with this denomination key
* @param[out] denom_balance value of coins outstanding (or issued?) with this denomination key
* @param[out] deposit_fee_balance total deposit fees collected for this DK
* @param[out] melt_fee_balance total melt fees collected for this DK
* @param[out] refund_fee_balance total refund fees collected for this DK