aboutsummaryrefslogtreecommitdiff
path: root/src/exchangedb
diff options
context:
space:
mode:
Diffstat (limited to 'src/exchangedb')
-rw-r--r--src/exchangedb/plugin_exchangedb_postgres.c490
-rw-r--r--src/exchangedb/test_exchangedb.c229
2 files changed, 698 insertions, 21 deletions
diff --git a/src/exchangedb/plugin_exchangedb_postgres.c b/src/exchangedb/plugin_exchangedb_postgres.c
index 972d70808..461184c7e 100644
--- a/src/exchangedb/plugin_exchangedb_postgres.c
+++ b/src/exchangedb/plugin_exchangedb_postgres.c
@@ -20,6 +20,7 @@
* @author Florian Dold
* @author Christian Grothoff
* @author Sree Harsha Totakura
+ * @author Marcello Stanisci
*/
#include "platform.h"
#include "taler_pq_lib.h"
@@ -627,6 +628,23 @@ postgres_prepare (PGconn *db_conn)
"($1, $2, $3, $4, $5, $6, $7);",
7, NULL);
+
+ /* Used in postgres_select_reserves_in_above_serial_id() to obtain inbound
+ transactions for reserves with serial id '\geq' the given parameter */
+ PREPARE ("audit_reserves_in_get_transactions_incr",
+ "SELECT"
+ " reserve_pub"
+ ",credit_val"
+ ",credit_frac"
+ ",credit_curr"
+ ",execution_date"
+ ",sender_account_details"
+ ",transfer_details"
+ " FROM reserves_in"
+ " WHERE reserve_in_serial_id>=$1"
+ " ORDER BY reserve_in_serial_id",
+ 1, NULL);
+
/* Used in #postgres_get_reserve_history() to obtain inbound transactions
for a reserve */
PREPARE ("reserves_in_get_transactions",
@@ -707,6 +725,23 @@ postgres_prepare (PGconn *db_conn)
" WHERE reserve_pub=$1;",
1, NULL);
+ /* Used in #postgres_select_reserves_out_above_serial_id() */
+ PREPARE ("audit_get_reserves_out_incr",
+ "SELECT"
+ " h_blind_ev"
+ ",denom_pub"
+ ",denom_sig"
+ ",reserve_sig"
+ ",reserve_pub"
+ ",execution_date"
+ ",amount_with_fee_val"
+ ",amount_with_fee_frac"
+ ",amount_with_fee_curr"
+ " FROM reserves_out"
+ " WHERE reserve_out_serial_id>=$1"
+ " ORDER BY reserve_out_serial_id ASC",
+ 1, NULL);
+
/* Used in #postgres_get_refresh_session() to fetch
high-level information about a refresh session */
PREPARE ("get_refresh_session",
@@ -727,6 +762,22 @@ postgres_prepare (PGconn *db_conn)
" WHERE session_hash=$1 ",
1, NULL);
+ /* Used in #postgres_select_refreshs_above_serial_id() to fetch
+ refresh session with id '\geq' the given parameter */
+ PREPARE ("audit_get_refresh_sessions_incr",
+ "SELECT"
+ " old_coin_pub"
+ ",old_coin_sig"
+ ",amount_with_fee_val"
+ ",amount_with_fee_frac"
+ ",amount_with_fee_curr"
+ ",num_newcoins"
+ ",noreveal_index"
+ " FROM refresh_sessions"
+ " WHERE melt_serial_id>=$1"
+ " ORDER BY melt_serial_id ASC",
+ 1, NULL);
+
/* Used in #postgres_create_refresh_session() to store
high-level information about a refresh session */
PREPARE ("insert_refresh_session",
@@ -802,6 +853,23 @@ postgres_prepare (PGconn *db_conn)
" WHERE old_coin_pub=$1",
1, NULL);
+ /* Fetch refunds with rowid '\geq' the given parameter */
+ PREPARE ("audit_get_refunds_incr",
+ "SELECT"
+ " merchant_pub"
+ ",merchant_sig"
+ ",h_contract"
+ ",transaction_id"
+ ",rtransaction_id"
+ ",coin_pub"
+ ",amount_with_fee_val"
+ ",amount_with_fee_frac"
+ ",amount_with_fee_curr"
+ " FROM refunds"
+ " WHERE refund_serial_id>=$1"
+ " ORDER BY refund_serial_id ASC",
+ 1, NULL);
+
/* Query the 'refunds' by coin public key */
PREPARE ("get_refunds_by_coin",
"SELECT"
@@ -823,6 +891,7 @@ postgres_prepare (PGconn *db_conn)
1, NULL);
+
/* Used in #postgres_insert_transfer_public_key() to
store commitments */
PREPARE ("insert_transfer_public_key",
@@ -921,8 +990,7 @@ postgres_prepare (PGconn *db_conn)
" )",
3, NULL);
- /* Fetch an existing deposit request, used to ensure idempotency
- during /deposit processing. Used in #postgres_have_deposit(). */
+ /* Fetch deposits with rowid '\geq' the given parameter */
PREPARE ("audit_get_deposits_incr",
"SELECT"
" amount_with_fee_val"
@@ -937,11 +1005,12 @@ postgres_prepare (PGconn *db_conn)
",wire_deadline"
",h_contract"
",wire"
+ ",done"
" FROM deposits"
" WHERE ("
" (deposit_serial_id>=$1)"
" )"
- " ORDER BY deposit_serial_id",
+ " ORDER BY deposit_serial_id ASC",
1, NULL);
/* Fetch an existing deposit request.
@@ -1207,6 +1276,18 @@ postgres_prepare (PGconn *db_conn)
" FROM prewire"
" WHERE finished=true",
0, NULL);
+
+ /* Used in #postgres_select_prepare_above_serial_id() */
+ PREPARE ("audit_get_wire_incr",
+ "SELECT"
+ " type"
+ ",buf"
+ ",finished"
+ " FROM prewire"
+ " WHERE prewire_uuid>=$1"
+ " ORDER BY prewire_uuid ASC",
+ 1, NULL);
+
PREPARE ("gc_denominations",
"DELETE"
" FROM denominations"
@@ -4291,9 +4372,9 @@ postgres_select_deposits_above_serial_id (void *cls,
};
PGresult *result;
result = GNUNET_PQ_exec_prepared (session->conn,
- "audit_get_deposits_incr",
- params);
- if (PGRES_COMMAND_OK !=
+ "audit_get_deposits_incr",
+ params);
+ if (PGRES_TUPLES_OK !=
PQresultStatus (result))
{
BREAK_DB_ERR (result);
@@ -4307,20 +4388,62 @@ postgres_select_deposits_above_serial_id (void *cls,
if (0 == nrows)
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "audit_get_deposit_incr() returned 0 matching rows\n");
+ "select_deposits_above_serial_id() returned 0 matching rows\n");
PQclear (result);
return GNUNET_NO;
}
for (i=0;i<nrows;i++)
{
+ struct TALER_EXCHANGEDB_Deposit deposit;
+ uint8_t done = 0;
+ struct GNUNET_PQ_ResultSpec rs[] = {
+ TALER_PQ_result_spec_amount ("amount_with_fee",
+ &deposit.amount_with_fee),
+ GNUNET_PQ_result_spec_absolute_time ("timestamp",
+ &deposit.timestamp),
+ GNUNET_PQ_result_spec_auto_from_type ("merchant_pub",
+ &deposit.merchant_pub),
+ GNUNET_PQ_result_spec_auto_from_type ("coin_pub",
+ &deposit.coin.coin_pub),
+ GNUNET_PQ_result_spec_auto_from_type ("coin_sig",
+ &deposit.csig),
+ GNUNET_PQ_result_spec_uint64 ("transaction_id",
+ &deposit.transaction_id),
+ GNUNET_PQ_result_spec_absolute_time ("refund_deadline",
+ &deposit.refund_deadline),
+ GNUNET_PQ_result_spec_absolute_time ("wire_deadline",
+ &deposit.wire_deadline),
+ GNUNET_PQ_result_spec_auto_from_type ("h_contract",
+ &deposit.h_contract),
+ TALER_PQ_result_spec_json ("wire",
+ &deposit.receiver_wire_account),
+ GNUNET_PQ_result_spec_auto_from_type ("done",
+ &done),
+ GNUNET_PQ_result_spec_end
+ };
+ if (GNUNET_OK !=
+ GNUNET_PQ_extract_result (result, rs, 0))
+ {
+ GNUNET_break (0);
+ PQclear (result);
+ return GNUNET_SYSERR;
+ }
+ cb (cb_cls,
+ serial_id,
+ &deposit.merchant_pub,
+ &deposit.coin.coin_pub,
+ &deposit.csig,
+ &deposit.amount_with_fee,
+ deposit.transaction_id,
+ &deposit.h_contract,
+ deposit.refund_deadline,
+ deposit.wire_deadline,
+ deposit.receiver_wire_account,
+ done);
}
-
PQclear (result);
return GNUNET_OK;
-
- GNUNET_break (0); // FIXME: not implemented
- return GNUNET_SYSERR;
}
@@ -4343,8 +4466,72 @@ postgres_select_refreshs_above_serial_id (void *cls,
TALER_EXCHANGEDB_RefreshSessionCallback cb,
void *cb_cls)
{
- GNUNET_break (0); // FIXME: not implemented
- return GNUNET_SYSERR;
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_uint64 (&serial_id),
+ GNUNET_PQ_query_param_end
+ };
+ PGresult *result;
+ result = GNUNET_PQ_exec_prepared (session->conn,
+ "audit_get_refresh_sessions_incr",
+ params);
+
+ if (PGRES_TUPLES_OK !=
+ PQresultStatus (result))
+ {
+ BREAK_DB_ERR (result);
+ PQclear (result);
+ return GNUNET_SYSERR;
+ }
+ int nrows;
+ int i;
+
+ nrows = PQntuples (result);
+ if (0 == nrows)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "select_refreshs_above_serial_id() returned 0 matching rows\n");
+ PQclear (result);
+ return GNUNET_NO;
+ }
+
+ for (i=0;i<nrows;i++)
+ {
+ struct TALER_CoinSpendPublicKeyP coin_pub;
+ struct TALER_CoinSpendSignatureP coin_sig;
+ struct TALER_Amount amount_with_fee;
+ uint16_t num_newcoins;
+ uint16_t noreveal_index;
+
+ struct GNUNET_PQ_ResultSpec rs[] = {
+ GNUNET_PQ_result_spec_auto_from_type ("old_coin_pub",
+ &coin_pub),
+ GNUNET_PQ_result_spec_auto_from_type ("old_coin_sig",
+ &coin_sig),
+ TALER_PQ_result_spec_amount ("amount_with_fee",
+ &amount_with_fee),
+ GNUNET_PQ_result_spec_uint16 ("num_newcoins",
+ &num_newcoins),
+ GNUNET_PQ_result_spec_uint16 ("noreveal_index",
+ &noreveal_index),
+ GNUNET_PQ_result_spec_end
+ };
+ if (GNUNET_OK !=
+ GNUNET_PQ_extract_result (result, rs, 0))
+ {
+ GNUNET_break (0);
+ PQclear (result);
+ return GNUNET_SYSERR;
+ }
+ cb (cb_cls,
+ serial_id,
+ &coin_pub,
+ &coin_sig,
+ &amount_with_fee,
+ num_newcoins,
+ noreveal_index);
+ }
+ PQclear (result);
+ return GNUNET_OK;
}
@@ -4367,8 +4554,72 @@ postgres_select_refunds_above_serial_id (void *cls,
TALER_EXCHANGEDB_RefundCallback cb,
void *cb_cls)
{
- GNUNET_break (0); // FIXME: not implemented
- return GNUNET_SYSERR;
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_uint64 (&serial_id),
+ GNUNET_PQ_query_param_end
+ };
+ PGresult *result;
+ result = GNUNET_PQ_exec_prepared (session->conn,
+ "audit_get_refunds_incr",
+ params);
+ if (PGRES_TUPLES_OK !=
+ PQresultStatus (result))
+ {
+ BREAK_DB_ERR (result);
+ PQclear (result);
+ return GNUNET_SYSERR;
+ }
+ int nrows;
+ int i;
+
+ nrows = PQntuples (result);
+ if (0 == nrows)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "select_refunds_above_serial_id() returned 0 matching rows\n");
+ PQclear (result);
+ return GNUNET_NO;
+ }
+ for (i=0;i<nrows;i++)
+ {
+ struct TALER_EXCHANGEDB_Refund refund;
+
+ struct GNUNET_PQ_ResultSpec rs[] = {
+ GNUNET_PQ_result_spec_auto_from_type ("merchant_pub",
+ &refund.merchant_pub),
+ GNUNET_PQ_result_spec_auto_from_type ("merchant_sig",
+ &refund.merchant_sig),
+ GNUNET_PQ_result_spec_auto_from_type ("h_contract",
+ &refund.h_contract),
+ GNUNET_PQ_result_spec_uint64 ("transaction_id",
+ &refund.transaction_id),
+ GNUNET_PQ_result_spec_uint64 ("rtransaction_id",
+ &refund.rtransaction_id),
+ GNUNET_PQ_result_spec_auto_from_type ("coin_pub",
+ &refund.coin.coin_pub),
+ TALER_PQ_result_spec_amount ("amount_with_fee",
+ &refund.refund_amount),
+ GNUNET_PQ_result_spec_end
+ };
+ if (GNUNET_OK !=
+ GNUNET_PQ_extract_result (result, rs, 0))
+ {
+ GNUNET_break (0);
+ PQclear (result);
+ return GNUNET_SYSERR;
+ }
+ cb (cb_cls,
+ serial_id,
+ &refund.coin.coin_pub,
+ &refund.merchant_pub,
+ &refund.merchant_sig,
+ &refund.h_contract,
+ refund.transaction_id,
+ refund.rtransaction_id,
+ &refund.refund_amount);
+ }
+ PQclear (result);
+ return GNUNET_OK;
}
@@ -4391,8 +4642,73 @@ postgres_select_reserves_in_above_serial_id (void *cls,
TALER_EXCHANGEDB_ReserveInCallback cb,
void *cb_cls)
{
- GNUNET_break (0); // FIXME: not implemented
- return GNUNET_SYSERR;
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_uint64 (&serial_id),
+ GNUNET_PQ_query_param_end
+ };
+ PGresult *result;
+ result = GNUNET_PQ_exec_prepared (session->conn,
+ "audit_reserves_in_get_transactions_incr",
+ params);
+ if (PGRES_TUPLES_OK !=
+ PQresultStatus (result))
+ {
+ BREAK_DB_ERR (result);
+ PQclear (result);
+ return GNUNET_SYSERR;
+ }
+ int nrows;
+ int i;
+
+ nrows = PQntuples (result);
+ if (0 == nrows)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "select_reserves_in_above_serial_id() returned 0 matching rows\n");
+ PQclear (result);
+ return GNUNET_NO;
+ }
+
+ for (i=0;i<nrows;i++)
+ {
+ struct TALER_ReservePublicKeyP reserve_pub;
+ struct TALER_Amount credit;
+ json_t *sender_account_details;
+ json_t *transfer_details;
+ struct GNUNET_TIME_Absolute execution_date;
+
+ struct GNUNET_PQ_ResultSpec rs[] = {
+ GNUNET_PQ_result_spec_auto_from_type ("reserve_pub",
+ &reserve_pub),
+ TALER_PQ_result_spec_amount ("credit",
+ &credit),
+ GNUNET_PQ_result_spec_absolute_time("execution_date",
+ &execution_date),
+ TALER_PQ_result_spec_json ("sender_account_details",
+ &sender_account_details),
+ TALER_PQ_result_spec_json ("transfer_details",
+ &transfer_details),
+ GNUNET_PQ_result_spec_end
+ };
+
+ if (GNUNET_OK !=
+ GNUNET_PQ_extract_result (result, rs, 0))
+ {
+ GNUNET_break (0);
+ PQclear (result);
+ return GNUNET_SYSERR;
+ }
+ cb (cb_cls,
+ serial_id,
+ &reserve_pub,
+ &credit,
+ sender_account_details,
+ transfer_details,
+ execution_date);
+ }
+
+ PQclear (result);
+ return GNUNET_OK;
}
@@ -4415,8 +4731,79 @@ postgres_select_reserves_out_above_serial_id (void *cls,
TALER_EXCHANGEDB_WithdrawCallback cb,
void *cb_cls)
{
- GNUNET_break (0); // FIXME: not implemented
- return GNUNET_SYSERR;
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_uint64 (&serial_id),
+ GNUNET_PQ_query_param_end
+ };
+ PGresult *result;
+ result = GNUNET_PQ_exec_prepared (session->conn,
+ "audit_get_reserves_out_incr",
+ params);
+ if (PGRES_TUPLES_OK !=
+ PQresultStatus (result))
+ {
+ BREAK_DB_ERR (result);
+ PQclear (result);
+ return GNUNET_SYSERR;
+ }
+ int nrows;
+ int i;
+
+ nrows = PQntuples (result);
+ if (0 == nrows)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "select_reserves_out_above_serial_id() returned 0 matching rows\n");
+ PQclear (result);
+ return GNUNET_NO;
+ }
+ for (i=0;i<nrows;i++)
+ {
+ struct GNUNET_HashCode h_blind_ev;
+ struct TALER_DenominationPublicKey denom_pub;
+ struct TALER_DenominationSignature denom_sig;
+ struct TALER_ReservePublicKeyP reserve_pub;
+ struct TALER_ReserveSignatureP reserve_sig;
+ struct GNUNET_TIME_Absolute execution_date;
+ struct TALER_Amount amount_with_fee;
+
+ struct GNUNET_PQ_ResultSpec rs[] = {
+ GNUNET_PQ_result_spec_auto_from_type ("h_blind_ev",
+ &h_blind_ev),
+ GNUNET_PQ_result_spec_rsa_public_key ("denom_pub",
+ &denom_pub.rsa_public_key),
+ GNUNET_PQ_result_spec_rsa_signature ("denom_sig",
+ &denom_sig.rsa_signature),
+ GNUNET_PQ_result_spec_auto_from_type ("reserve_pub",
+ &reserve_pub),
+ GNUNET_PQ_result_spec_auto_from_type ("reserve_sig",
+ &reserve_sig),
+ GNUNET_PQ_result_spec_absolute_time ("execution_date",
+ &execution_date),
+ TALER_PQ_result_spec_amount ("amount_with_fee",
+ &amount_with_fee),
+ GNUNET_PQ_result_spec_end
+ };
+ if (GNUNET_OK !=
+ GNUNET_PQ_extract_result (result, rs, 0))
+ {
+ GNUNET_break (0);
+ PQclear (result);
+ return GNUNET_SYSERR;
+ }
+ cb (cb_cls,
+ serial_id,
+ &h_blind_ev,
+ &denom_pub,
+ &denom_sig,
+ &reserve_pub,
+ &reserve_sig,
+ execution_date,
+ &amount_with_fee);
+ }
+
+ PQclear (result);
+ return GNUNET_OK;
}
@@ -4440,8 +4827,69 @@ postgres_select_prepare_above_serial_id (void *cls,
TALER_EXCHANGEDB_WirePreparationCallback cb,
void *cb_cls)
{
- GNUNET_break (0); // FIXME: not implemented
- return GNUNET_SYSERR;
+
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_uint64 (&serial_id),
+ GNUNET_PQ_query_param_end
+ };
+ PGresult *result;
+ result = GNUNET_PQ_exec_prepared (session->conn,
+ "audit_get_wire_incr",
+ params);
+ if (PGRES_TUPLES_OK !=
+ PQresultStatus (result))
+ {
+ BREAK_DB_ERR (result);
+ PQclear (result);
+ return GNUNET_SYSERR;
+ }
+ int nrows;
+ int i;
+
+ nrows = PQntuples (result);
+ if (0 == nrows)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "select_prepare_above_serial_id() returned 0 matching rows\n");
+ PQclear (result);
+ return GNUNET_NO;
+ }
+ for (i=0;i<nrows;i++)
+ {
+ char *wire_method;
+ void *buf;
+ size_t buf_size;
+ uint8_t finished;
+
+ struct GNUNET_PQ_ResultSpec rs[] = {
+ GNUNET_PQ_result_spec_string ("type",
+ &wire_method),
+ GNUNET_PQ_result_spec_variable_size ("buf",
+ &buf,
+ &buf_size),
+ GNUNET_PQ_result_spec_auto_from_type ("finished",
+ &finished),
+ GNUNET_PQ_result_spec_end
+ };
+
+ if (GNUNET_OK !=
+ GNUNET_PQ_extract_result (result, rs, 0))
+ {
+ GNUNET_break (0);
+ PQclear (result);
+ return GNUNET_SYSERR;
+ }
+
+ cb (cb_cls,
+ serial_id,
+ wire_method,
+ buf,
+ buf_size,
+ finished);
+ }
+
+ PQclear (result);
+ return GNUNET_OK;
}
diff --git a/src/exchangedb/test_exchangedb.c b/src/exchangedb/test_exchangedb.c
index 00c7a9ef6..d0ec63f46 100644
--- a/src/exchangedb/test_exchangedb.c
+++ b/src/exchangedb/test_exchangedb.c
@@ -18,6 +18,7 @@
* @brief test cases for DB interaction functions
* @author Sree Harsha Totakura
* @author Christian Grothoff
+ * @author Marcello Stanisci
*/
#include "platform.h"
#include "taler_exchangedb_lib.h"
@@ -77,6 +78,12 @@ dead_prepare_cb (void *cls,
GNUNET_assert (0);
}
+/**
+ * Counter used in auditor-related db functions. Used to count
+ * expected rows.
+ */
+unsigned int auditor_row_cnt;
+
/**
* Callback that is called with wire prepare data
@@ -103,6 +110,27 @@ mark_prepare_cb (void *cls,
rowid));
}
+/**
+ * Callback with data about a prepared wire transfer.
+ *
+ * @param cls closure
+ * @param rowid row identifier used to mark prepared transaction as done
+ * @param wire_method which wire method is this preparation data for
+ * @param buf transaction data that was persisted, NULL on error
+ * @param buf_size number of bytes in @a buf, 0 on error
+ * @param finished did we complete the transfer yet?
+ */
+void
+audit_wire_cb (void *cls,
+ unsigned long long rowid,
+ const char *wire_method,
+ const char *buf,
+ size_t buf_size,
+ int finished)
+{
+ auditor_row_cnt++;
+ return;
+}
/**
* Test API relating to persisting the wire plugins preparation data.
@@ -134,6 +162,14 @@ test_wire_prepare (struct TALER_EXCHANGEDB_Session *session)
session,
&dead_prepare_cb,
NULL));
+ auditor_row_cnt = 0;
+ FAILIF (GNUNET_OK !=
+ plugin->select_prepare_above_serial_id (plugin->cls,
+ session,
+ 0,
+ &audit_wire_cb,
+ NULL));
+ FAILIF (1 != auditor_row_cnt);
return GNUNET_OK;
drop:
return GNUNET_SYSERR;
@@ -465,6 +501,38 @@ check_transfer_data (void *cls,
*ok = GNUNET_SYSERR;
}
+/**
+ * Function called with details about coins that were melted,
+ * with the goal of auditing the refresh's execution.
+ *
+ * @param cls closure
+ * @param rowid unique serial ID for the refresh session in our DB
+ * @param merchant_pub public key of the merchant
+ * @param coin_pub public key of the coin
+ * @param coin_sig signature from the coin
+ * @param amount_with_fee amount that was deposited including fee
+ * @param transaction_id unique transaction ID chosen by the merchant
+ * @param h_contract hash of the contract between merchant and customer
+ * @param refund_deadline by which the merchant adviced that he might want
+ * to get a refund
+ * @param wire_deadline by which the merchant adviced that he would like the
+ * wire transfer to be executed
+ * @param receiver_wire_account wire details for the merchant, NULL from iterate_matching_deposits()
+ * @param done flag set if the deposit was already executed (or not)
+ * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop
+ */
+int
+audit_refresh_session_cb (void *cls,
+ unsigned long long rowid, /* FIXME: decide data type for serial_id! */
+ const struct TALER_CoinSpendPublicKeyP *coin_pub,
+ const struct TALER_CoinSpendSignatureP *coin_sig,
+ const struct TALER_Amount *amount_with_fee,
+ uint16_t num_newcoins,
+ uint16_t noreveal_index)
+{
+ auditor_row_cnt++;
+ return GNUNET_OK;
+}
/**
* Function to test melting of coins as part of a refresh session
@@ -538,6 +606,14 @@ test_melting (struct TALER_EXCHANGEDB_Session *session)
session,
&session_hash,
&ret_refresh_session));
+
+ auditor_row_cnt = 0;
+ FAILIF (GNUNET_OK != plugin->select_refreshs_above_serial_id (plugin->cls,
+ session,
+ 0,
+ &audit_refresh_session_cb,
+ NULL));
+ FAILIF (1 != auditor_row_cnt);
FAILIF (ret_refresh_session.num_newcoins != refresh_session.num_newcoins);
FAILIF (ret_refresh_session.noreveal_index != refresh_session.noreveal_index);
@@ -874,6 +950,128 @@ deposit_cb (void *cls,
return GNUNET_OK;
}
+/**
+ * Callback for #select_deposits_above_serial_id ()
+ *
+ * @param cls closure
+ * @param rowid unique serial ID for the deposit in our DB
+ * @param merchant_pub public key of the merchant
+ * @param coin_pub public key of the coin
+ * @param coin_sig signature from the coin
+ * @param amount_with_fee amount that was deposited including fee
+ * @param transaction_id unique transaction ID chosen by the merchant
+ * @param h_contract hash of the contract between merchant and customer
+ * @param refund_deadline by which the merchant adviced that he might want
+ * to get a refund
+ * @param wire_deadline by which the merchant adviced that he would like the
+ * wire transfer to be executed
+ * @param receiver_wire_account wire details for the merchant, NULL from iterate_matching_deposits()
+ * @param done flag set if the deposit was already executed (or not)
+ * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop
+ */
+int
+audit_deposit_cb (void *cls,
+ unsigned long long rowid,
+ const struct TALER_MerchantPublicKeyP *merchant_pub,
+ const struct TALER_CoinSpendPublicKeyP *coin_pub,
+ const struct TALER_CoinSpendSignatureP *coin_sig,
+ const struct TALER_Amount *amount_with_fee,
+ uint64_t transaction_id,
+ const struct GNUNET_HashCode *h_contract,
+ struct GNUNET_TIME_Absolute refund_deadline,
+ struct GNUNET_TIME_Absolute wire_deadline,
+ const json_t *receiver_wire_account,
+ int done)
+{
+ auditor_row_cnt++;
+ return GNUNET_OK;
+}
+
+
+/**
+ * Function called with details about coins that were refunding,
+ * with the goal of auditing the refund's execution.
+ *
+ * @param cls closure
+ * @param rowid unique serial ID for the refund in our DB
+ * @param coin_pub public key of the coin
+ * @param merchant_pub public key of the merchant
+ * @param merchant_sig signature of the merchant
+ * @param h_contract hash of the contract between merchant and customer
+ * @param transaction_id original transaction ID chosen by the merchant
+ * @param rtransaction_id refund transaction ID chosen by the merchant
+ * @param amount_with_fee amount that was deposited including fee
+ * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop
+ */
+int
+audit_refund_cb (void *cls,
+ unsigned long long rowid, /* FIXME: decide data type for serial_id! */
+ const struct TALER_CoinSpendPublicKeyP *coin_pub,
+ const struct TALER_MerchantPublicKeyP *merchant_pub,
+ const struct TALER_MerchantSignatureP *merchant_sig,
+ const struct GNUNET_HashCode *h_contract,
+ uint64_t transaction_id,
+ uint64_t rtransaction_id,
+ const struct TALER_Amount *amount_with_fee)
+{
+ auditor_row_cnt++;
+ return GNUNET_OK;
+}
+
+
+/**
+ * Function called with details about incoming wire transfers.
+ *
+ * @param cls closure
+ * @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
+ * @param sender_account_details information about the sender's bank account
+ * @param transfer_details information that uniquely identifies the wire transfer
+ * @param execution_date when did we receive the funds
+ * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop
+ */
+int
+audit_reserve_in_cb (void *cls,
+ unsigned long long rowid, /* FIXME: decide data type for serial_id! */
+ const struct TALER_ReservePublicKeyP *reserve_pub,
+ const struct TALER_Amount *credit,
+ const json_t *sender_account_details,
+ const json_t *transfer_details,
+ struct GNUNET_TIME_Absolute execution_date)
+{
+ auditor_row_cnt++;
+ return GNUNET_OK;
+}
+
+/**
+ * Function called with details about withdraw operations.
+ *
+ * @param cls closure
+ * @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
+ */
+int
+audit_reserve_out_cb (void *cls,
+ unsigned long long rowid, /* FIXME: decide data type for serial_id! */
+ 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)
+{
+ auditor_row_cnt++;
+ return GNUNET_OK;
+}
/**
* Test garbage collection.
@@ -1121,6 +1319,21 @@ run (void *cls)
}
}
FAILIF (3 != cnt);
+
+ auditor_row_cnt = 0;
+ FAILIF (GNUNET_OK !=
+ plugin->select_reserves_in_above_serial_id (plugin->cls,
+ session,
+ 0,
+ &audit_reserve_in_cb,
+ NULL));
+ FAILIF (GNUNET_OK !=
+ plugin->select_reserves_out_above_serial_id (plugin->cls,
+ session,
+ 0,
+ &audit_reserve_out_cb,
+ NULL));
+ FAILIF (3 != auditor_row_cnt);
/* Tests for deposits */
memset (&deposit, 0, sizeof (deposit));
RND_BLK (&deposit.coin.coin_pub);
@@ -1145,6 +1358,14 @@ run (void *cls)
plugin->have_deposit (plugin->cls,
session,
&deposit));
+ auditor_row_cnt = 0;
+ FAILIF (GNUNET_OK !=
+ plugin->select_deposits_above_serial_id (plugin->cls,
+ session,
+ 0,
+ &audit_deposit_cb,
+ NULL));
+ FAILIF (1 != auditor_row_cnt);
result = 9;
FAILIF (1 !=
plugin->iterate_matching_deposits (plugin->cls,
@@ -1232,7 +1453,15 @@ run (void *cls)
plugin->insert_refund (plugin->cls,
session,
&refund));
+ auditor_row_cnt = 0;
+ FAILIF (GNUNET_OK !=
+ plugin->select_refunds_above_serial_id (plugin->cls,
+ session,
+ 0,
+ &audit_refund_cb,
+ NULL));
+ FAILIF (1 != auditor_row_cnt);
tl = plugin->get_coin_transactions (plugin->cls,
session,
&refund.coin.coin_pub);