summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2015-06-12 11:47:01 +0200
committerChristian Grothoff <christian@grothoff.org>2015-06-12 11:47:01 +0200
commit9891cafe12e48f2e79d47a0c62780ebeb4f6876a (patch)
tree4629379822111372481171531d2926f5d79cd14b
parent006c55b3de1262c390e2139798422ca0fb1e9c02 (diff)
downloadexchange-9891cafe12e48f2e79d47a0c62780ebeb4f6876a.tar.gz
exchange-9891cafe12e48f2e79d47a0c62780ebeb4f6876a.tar.bz2
exchange-9891cafe12e48f2e79d47a0c62780ebeb4f6876a.zip
implementing #3819: check for inconsistent deposit request
-rw-r--r--src/include/taler_mintdb_plugin.h5
-rw-r--r--src/mintdb/plugin_mintdb_postgres.c67
2 files changed, 55 insertions, 17 deletions
diff --git a/src/include/taler_mintdb_plugin.h b/src/include/taler_mintdb_plugin.h
index a249c6ad..72156ece 100644
--- a/src/include/taler_mintdb_plugin.h
+++ b/src/include/taler_mintdb_plugin.h
@@ -813,7 +813,10 @@ struct TALER_MINTDB_Plugin
* @param deposit deposit to search for
* @return #GNUNET_YES if we know this operation,
* #GNUNET_NO if this deposit is unknown to us,
- * #GNUNET_SYSERR on internal error
+ * #GNUNET_SYSERR on DB error or if same coin(pub), merchant(pub) and
+ * transaction ID are already in DB, but for different
+ * other transaction details (contract, wiring details,
+ * amount, etc.)
*/
int
(*have_deposit) (void *cls,
diff --git a/src/mintdb/plugin_mintdb_postgres.c b/src/mintdb/plugin_mintdb_postgres.c
index f381a943..311c2d10 100644
--- a/src/mintdb/plugin_mintdb_postgres.c
+++ b/src/mintdb/plugin_mintdb_postgres.c
@@ -797,18 +797,13 @@ postgres_prepare (PGconn *db_conn)
during /deposit processing. Used in #postgres_have_deposit(). */
PREPARE ("get_deposit",
"SELECT"
- " denom_pub" /* Note: not actually used (yet), #3819 */
- ",amount_with_fee_val" /* Note: not actually used (yet), #3819 */
+ " amount_with_fee_val" /* Note: not actually used (yet), #3819 */
",amount_with_fee_frac" /* Note: not actually used (yet), #3819 */
",amount_with_fee_curr" /* Note: not actually used (yet), #3819 */
- ",deposit_fee_val" /* Note: not actually used (yet), #3819 */
- ",deposit_fee_frac" /* Note: not actually used (yet), #3819 */
- ",deposit_fee_curr" /* Note: not actually used (yet), #3819 */
",timestamp" /* Note: not actually used (yet), #3819 */
",refund_deadline" /* Note: not actually used (yet), #3819 */
",h_contract" /* Note: not actually used (yet), #3819 */
",h_wire" /* Note: not actually used (yet), #3819 */
- ",coin_sig" /* Note: not actually used (yet), #3819 */
" FROM deposits"
" WHERE ("
" (coin_pub=$1) AND"
@@ -1759,6 +1754,10 @@ postgres_get_reserve_history (void *cls,
* @param deposit deposit to search for
* @return #GNUNET_YES if we know this operation,
* #GNUNET_NO if this deposit is unknown to us
+ * #GNUNET_SYSERR on DB error or if same coin(pub), merchant(pub) and
+ * transaction ID are already in DB, but for different
+ * other transaction details (contract, wiring details,
+ * amount, etc.)
*/
static int
postgres_have_deposit (void *cls,
@@ -1772,9 +1771,7 @@ postgres_have_deposit (void *cls,
TALER_PQ_query_param_end
};
PGresult *result;
- int ret;
- ret = GNUNET_SYSERR;
result = TALER_PQ_exec_prepared (session->conn,
"get_deposit",
params);
@@ -1782,16 +1779,54 @@ postgres_have_deposit (void *cls,
PQresultStatus (result))
{
BREAK_DB_ERR (result);
- goto cleanup;
+ PQclear (result);
+ return GNUNET_SYSERR;
+ }
+ if (0 == PQntuples (result))
+ {
+ PQclear (result);
+ return GNUNET_NO;
+ }
+
+ /* Now we check that the other information in @a deposit
+ also matches, and if not report inconsistencies. */
+ {
+ struct TALER_MINTDB_Deposit deposit2 = *deposit;
+ struct TALER_PQ_ResultSpec rs[] = {
+ TALER_PQ_result_spec_amount ("amount_with_fee",
+ &deposit2.amount_with_fee),
+ TALER_PQ_result_spec_absolute_time ("timestamp",
+ &deposit2.timestamp),
+ TALER_PQ_result_spec_absolute_time ("refund_deadline",
+ &deposit2.refund_deadline),
+ TALER_PQ_result_spec_auto_from_type ("h_contract",
+ &deposit2.h_contract),
+ TALER_PQ_result_spec_auto_from_type ("h_wire",
+ &deposit2.h_wire),
+ TALER_PQ_result_spec_end
+ };
+ if (GNUNET_OK !=
+ TALER_PQ_extract_result (result, rs, 0))
+ {
+ GNUNET_break (0);
+ PQclear (result);
+ return GNUNET_SYSERR;
+ }
+ if (0 != memcmp (&deposit2,
+ deposit,
+ sizeof (struct TALER_MINTDB_Deposit)))
+ {
+ /* Inconsistencies detected! Bug in merchant! (We might want to
+ expand the API with a 'get_deposit' function to return the
+ original transaction details to be used for an error message
+ in the future!) #3838 */
+ GNUNET_break_op (0);
+ PQclear (result);
+ return GNUNET_SYSERR;
+ }
}
- ret = (0 == PQntuples (result)) ? GNUNET_NO : GNUNET_YES;
- /* NOTE: maybe check that the other information in @a deposit
- also matches, and if not report inconsistencies? Right now,
- if the merchant re-uses a transaction ID, the mint silently
- ignores the second request (not ideal..., #3819) */
- cleanup:
PQclear (result);
- return ret;
+ return GNUNET_YES;
}