diff options
author | Christian Grothoff <christian@grothoff.org> | 2017-04-04 15:38:58 +0200 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2017-04-04 15:38:58 +0200 |
commit | 4b82a591c54bec9720181358c8230caa3759363f (patch) | |
tree | c4f5ab8a5f93c6640ee1c8ce311b3bb6e13d3f86 /src/exchangedb | |
parent | cc3aa31732b2c214e6733206e713387d5ef8d39a (diff) |
handle /payback in auditor when checking reserves
Diffstat (limited to 'src/exchangedb')
-rw-r--r-- | src/exchangedb/plugin_exchangedb_postgres.c | 282 | ||||
-rw-r--r-- | src/exchangedb/test_exchangedb.c | 4 |
2 files changed, 219 insertions, 67 deletions
diff --git a/src/exchangedb/plugin_exchangedb_postgres.c b/src/exchangedb/plugin_exchangedb_postgres.c index e869bcd95..498b84864 100644 --- a/src/exchangedb/plugin_exchangedb_postgres.c +++ b/src/exchangedb/plugin_exchangedb_postgres.c @@ -515,7 +515,8 @@ postgres_create_tables (void *cls) /* Table for /payback information */ SQLEXEC("CREATE TABLE IF NOT EXISTS payback " - "(reserve_pub BYTEA NOT NULL REFERENCES reserves (reserve_pub) ON DELETE CASCADE" + "(payback_uuid BIGSERIAL" + ",reserve_pub BYTEA NOT NULL REFERENCES reserves (reserve_pub) ON DELETE CASCADE" ",coin_pub BYTEA NOT NULL CHECK (LENGTH(coin_pub)=32)" ",coin_sig BYTEA NOT NULL CHECK(LENGTH(coin_sig)=64)" ",coin_blind BYTEA NOT NULL CHECK(LENGTH(coin_blind)=32)" @@ -1418,6 +1419,26 @@ postgres_prepare (PGconn *db_conn) "($1, $2, $3, $4, $5, $6, $7, $8, $9)", 9, NULL); + /* Used in #postgres_select_payback_above_serial_id() to obtain payback transactions */ + PREPARE ("payback_get_incr", + "SELECT" + " payback_uuid" + ",timestamp" + ",reserve_pub" + ",coin_pub" + ",coin_sig" + ",coin_blind" + ",h_blind_ev" + ",denom.denom_pub" + ",amount_val" + ",amount_frac" + ",amount_curr" + " FROM payback" + " JOIN reserves_out denom USING (reserve_pub,h_blind_ev)" + " WHERE payback_uuid>=$1" + " ORDER BY payback_uuid ASC", + 1, NULL); + /* Used in #postgres_get_reserve_history() to obtain payback transactions for a reserve */ PREPARE ("payback_by_reserve", @@ -5057,7 +5078,7 @@ postgres_select_deposits_above_serial_id (void *cls, return GNUNET_SYSERR; } int nrows; - int i; + int ret; nrows = PQntuples (result); if (0 == nrows) @@ -5067,7 +5088,7 @@ postgres_select_deposits_above_serial_id (void *cls, PQclear (result); return GNUNET_NO; } - for (i=0;i<nrows;i++) + for (int i=0;i<nrows;i++) { struct TALER_EXCHANGEDB_Deposit deposit; struct TALER_DenominationPublicKey denom_pub; @@ -5109,20 +5130,22 @@ postgres_select_deposits_above_serial_id (void *cls, PQclear (result); return GNUNET_SYSERR; } - cb (cb_cls, - rowid, - deposit.timestamp, - &deposit.merchant_pub, - &denom_pub, - &deposit.coin.coin_pub, - &deposit.csig, - &deposit.amount_with_fee, - &deposit.h_proposal_data, - deposit.refund_deadline, - deposit.wire_deadline, - deposit.receiver_wire_account, - done); + ret = cb (cb_cls, + rowid, + deposit.timestamp, + &deposit.merchant_pub, + &denom_pub, + &deposit.coin.coin_pub, + &deposit.csig, + &deposit.amount_with_fee, + &deposit.h_proposal_data, + deposit.refund_deadline, + deposit.wire_deadline, + deposit.receiver_wire_account, + done); GNUNET_PQ_cleanup_result (rs); + if (GNUNET_OK != ret) + break; } PQclear (result); return GNUNET_OK; @@ -5153,6 +5176,10 @@ postgres_select_refreshs_above_serial_id (void *cls, GNUNET_PQ_query_param_end }; PGresult *result; + int nrows; + int i; + int ret; + result = GNUNET_PQ_exec_prepared (session->conn, "audit_get_refresh_sessions_incr", params); @@ -5164,8 +5191,6 @@ postgres_select_refreshs_above_serial_id (void *cls, PQclear (result); return GNUNET_SYSERR; } - int nrows; - int i; nrows = PQntuples (result); if (0 == nrows) @@ -5215,16 +5240,18 @@ postgres_select_refreshs_above_serial_id (void *cls, PQclear (result); return GNUNET_SYSERR; } - cb (cb_cls, - rowid, - &denom_pub, - &coin_pub, - &coin_sig, - &amount_with_fee, - num_newcoins, - noreveal_index, - &session_hash); + ret = cb (cb_cls, + rowid, + &denom_pub, + &coin_pub, + &coin_sig, + &amount_with_fee, + num_newcoins, + noreveal_index, + &session_hash); GNUNET_PQ_cleanup_result (rs); + if (GNUNET_OK != ret) + break; } PQclear (result); return GNUNET_OK; @@ -5255,6 +5282,9 @@ postgres_select_refunds_above_serial_id (void *cls, GNUNET_PQ_query_param_end }; PGresult *result; + int nrows; + int ret; + result = GNUNET_PQ_exec_prepared (session->conn, "audit_get_refunds_incr", params); @@ -5265,8 +5295,6 @@ postgres_select_refunds_above_serial_id (void *cls, PQclear (result); return GNUNET_SYSERR; } - int nrows; - int i; nrows = PQntuples (result); if (0 == nrows) @@ -5276,7 +5304,7 @@ postgres_select_refunds_above_serial_id (void *cls, PQclear (result); return GNUNET_NO; } - for (i=0;i<nrows;i++) + for (int i=0;i<nrows;i++) { struct TALER_EXCHANGEDB_Refund refund; struct TALER_DenominationPublicKey denom_pub; @@ -5310,16 +5338,18 @@ postgres_select_refunds_above_serial_id (void *cls, PQclear (result); return GNUNET_SYSERR; } - cb (cb_cls, - rowid, - &denom_pub, - &refund.coin.coin_pub, - &refund.merchant_pub, - &refund.merchant_sig, - &refund.h_proposal_data, - refund.rtransaction_id, - &refund.refund_amount); + ret = cb (cb_cls, + rowid, + &denom_pub, + &refund.coin.coin_pub, + &refund.merchant_pub, + &refund.merchant_sig, + &refund.h_proposal_data, + refund.rtransaction_id, + &refund.refund_amount); GNUNET_PQ_cleanup_result (rs); + if (GNUNET_OK != ret) + break; } PQclear (result); return GNUNET_OK; @@ -5361,7 +5391,7 @@ postgres_select_reserves_in_above_serial_id (void *cls, return GNUNET_SYSERR; } int nrows; - int i; + int ret; nrows = PQntuples (result); if (0 == nrows) @@ -5372,7 +5402,7 @@ postgres_select_reserves_in_above_serial_id (void *cls, return GNUNET_NO; } - for (i=0;i<nrows;i++) + for (int i=0;i<nrows;i++) { struct TALER_ReservePublicKeyP reserve_pub; struct TALER_Amount credit; @@ -5406,14 +5436,16 @@ postgres_select_reserves_in_above_serial_id (void *cls, PQclear (result); return GNUNET_SYSERR; } - cb (cb_cls, - rowid, - &reserve_pub, - &credit, - sender_account_details, - transfer_details, - execution_date); + ret = cb (cb_cls, + rowid, + &reserve_pub, + &credit, + sender_account_details, + transfer_details, + execution_date); GNUNET_PQ_cleanup_result (rs); + if (GNUNET_OK != ret) + break; } PQclear (result); @@ -5457,7 +5489,7 @@ postgres_select_reserves_out_above_serial_id (void *cls, return GNUNET_SYSERR; } int nrows; - int i; + int ret; nrows = PQntuples (result); if (0 == nrows) @@ -5467,7 +5499,7 @@ postgres_select_reserves_out_above_serial_id (void *cls, PQclear (result); return GNUNET_NO; } - for (i=0;i<nrows;i++) + for (int i=0;i<nrows;i++) { struct GNUNET_HashCode h_blind_ev; struct TALER_DenominationPublicKey denom_pub; @@ -5506,16 +5538,18 @@ postgres_select_reserves_out_above_serial_id (void *cls, PQclear (result); return GNUNET_SYSERR; } - cb (cb_cls, - rowid, - &h_blind_ev, - &denom_pub, - &denom_sig, - &reserve_pub, - &reserve_sig, - execution_date, - &amount_with_fee); + ret = cb (cb_cls, + rowid, + &h_blind_ev, + &denom_pub, + &denom_sig, + &reserve_pub, + &reserve_sig, + execution_date, + &amount_with_fee); GNUNET_PQ_cleanup_result (rs); + if (GNUNET_OK != ret) + break; } PQclear (result); @@ -5548,6 +5582,9 @@ postgres_select_wire_out_above_serial_id (void *cls, GNUNET_PQ_query_param_end }; PGresult *result; + int nrows; + int ret; + result = GNUNET_PQ_exec_prepared (session->conn, "audit_get_wire_incr", params); @@ -5558,7 +5595,6 @@ postgres_select_wire_out_above_serial_id (void *cls, PQclear (result); return GNUNET_SYSERR; } - int nrows; nrows = PQntuples (result); if (0 == nrows) @@ -5600,13 +5636,126 @@ postgres_select_wire_out_above_serial_id (void *cls, return GNUNET_SYSERR; } - cb (cb_cls, - rowid, - date, - &wtid, - wire, - &amount); + ret = cb (cb_cls, + rowid, + date, + &wtid, + wire, + &amount); + GNUNET_PQ_cleanup_result (rs); + if (GNUNET_OK != ret) + break; + } + + PQclear (result); + return GNUNET_OK; +} + + +/** + * Function called to select payback requests the exchange + * received, ordered by serial ID (monotonically increasing). + * + * @param cls closure + * @param session database connection + * @param serial_id lowest serial ID to include (select larger or equal) + * @param cb function to call for ONE unfinished item + * @param cb_cls closure for @a cb + * @return #GNUNET_OK on success, + * #GNUNET_NO if there are no entries, + * #GNUNET_SYSERR on DB errors + */ +static int +postgres_select_payback_above_serial_id (void *cls, + struct TALER_EXCHANGEDB_Session *session, + uint64_t serial_id, + TALER_EXCHANGEDB_PaybackCallback cb, + void *cb_cls) +{ + 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, + "payback_get_incr", + params); + if (PGRES_TUPLES_OK != + PQresultStatus (result)) + { + BREAK_DB_ERR (result, session->conn); + PQclear (result); + return GNUNET_SYSERR; + } + int nrows; + int ret; + + 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 (int i=0;i<nrows;i++) + { + uint64_t rowid; + struct TALER_ReservePublicKeyP reserve_pub; + struct TALER_CoinSpendPublicKeyP coin_pub; + struct TALER_CoinSpendSignatureP coin_sig; + struct TALER_DenominationBlindingKeyP coin_blind; + struct TALER_Amount amount; + struct GNUNET_HashCode h_blind_ev; + struct GNUNET_TIME_Absolute timestamp; + struct TALER_DenominationPublicKey denom_pub; + struct GNUNET_HashCode h_denom_pub; + + struct GNUNET_PQ_ResultSpec rs[] = { + GNUNET_PQ_result_spec_uint64 ("payback_uuid", + &rowid), + GNUNET_PQ_result_spec_absolute_time ("timestamp", + ×tamp), + GNUNET_PQ_result_spec_auto_from_type ("reserve_pub", + &reserve_pub), + GNUNET_PQ_result_spec_auto_from_type ("coin_pub", + &coin_pub), + GNUNET_PQ_result_spec_auto_from_type ("coin_sig", + &coin_sig), + GNUNET_PQ_result_spec_auto_from_type ("coin_blind", + &coin_blind), + 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), + TALER_PQ_result_spec_amount ("amount", + &amount), + GNUNET_PQ_result_spec_end + }; + + if (GNUNET_OK != + GNUNET_PQ_extract_result (result, + rs, + i)) + { + GNUNET_break (0); + PQclear (result); + return GNUNET_SYSERR; + } + GNUNET_CRYPTO_rsa_public_key_hash (denom_pub.rsa_public_key, + &h_denom_pub); + ret = cb (cb_cls, + rowid, + timestamp, + &amount, + &reserve_pub, + &coin_pub, + &coin_sig, + &h_denom_pub, + &coin_blind); GNUNET_PQ_cleanup_result (rs); + if (GNUNET_OK != ret) + break; } PQclear (result); @@ -5868,6 +6017,7 @@ libtaler_plugin_exchangedb_postgres_init (void *cls) plugin->select_reserves_in_above_serial_id = &postgres_select_reserves_in_above_serial_id; plugin->select_reserves_out_above_serial_id = &postgres_select_reserves_out_above_serial_id; plugin->select_wire_out_above_serial_id = &postgres_select_wire_out_above_serial_id; + plugin->select_payback_above_serial_id = &postgres_select_payback_above_serial_id; plugin->insert_payback_request = &postgres_insert_payback_request; plugin->get_reserve_by_h_blind = &postgres_get_reserve_by_h_blind; return plugin; diff --git a/src/exchangedb/test_exchangedb.c b/src/exchangedb/test_exchangedb.c index e8fd21194..49cc64316 100644 --- a/src/exchangedb/test_exchangedb.c +++ b/src/exchangedb/test_exchangedb.c @@ -1205,8 +1205,9 @@ static struct TALER_Amount wire_out_amount; * @param wtid wire transfer subject * @param wire wire transfer details of the receiver * @param amount amount that was wired + * @return #GNUNET_OK to continue, #GNUNET_SYSERR to stop iteration */ -static void +static int audit_wire_cb (void *cls, uint64_t rowid, struct GNUNET_TIME_Absolute date, @@ -1223,6 +1224,7 @@ audit_wire_cb (void *cls, &wire_out_wtid, sizeof (*wtid))); GNUNET_assert (date.abs_value_us == wire_out_date.abs_value_us); + return GNUNET_OK; } |