summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSree Harsha Totakura <sreeharsha@totakura.in>2015-03-09 17:05:35 +0100
committerSree Harsha Totakura <sreeharsha@totakura.in>2015-03-09 19:54:44 +0100
commit07f18f16601cc4757c0c2658ad501497b07cebee (patch)
treeff8b1b5e40bff7315aa3eb111d83105854780ade
parent3d4c72e20793c1eddb9394b67089d2e63cf63192 (diff)
downloadexchange-07f18f16601cc4757c0c2658ad501497b07cebee.tar.gz
exchange-07f18f16601cc4757c0c2658ad501497b07cebee.tar.bz2
exchange-07f18f16601cc4757c0c2658ad501497b07cebee.zip
db: Implement get_reserve_history()
-rw-r--r--src/mint/mint_db.c227
-rw-r--r--src/mint/test_mint_db.c41
2 files changed, 214 insertions, 54 deletions
diff --git a/src/mint/mint_db.c b/src/mint/mint_db.c
index f66eb66a1..53d35b33d 100644
--- a/src/mint/mint_db.c
+++ b/src/mint/mint_db.c
@@ -331,6 +331,14 @@ TALER_MINT_DB_prepare (PGconn *db_conn)
" expiration_date) VALUES ("
" $1, $2, $3, $4, $5);",
5, NULL);
+ PREPARE ("get_reserves_in_transactions",
+ "SELECT"
+ " balance_value"
+ ",balance_fraction"
+ ",balance_currency"
+ ",expiration_date"
+ " FROM reserves_in WHERE reserve_pub=$1",
+ 1, NULL);
PREPARE ("insert_collectable_blindcoin",
"INSERT INTO collectable_blindcoins ( "
" blind_ev"
@@ -345,6 +353,14 @@ TALER_MINT_DB_prepare (PGconn *db_conn)
"FROM collectable_blindcoins "
"WHERE blind_ev = $1",
1, NULL);
+ PREPARE ("get_reserves_blindcoins",
+ "select"
+ " blind_ev"
+ ",denom_pub, denom_sig"
+ ",reserve_sig"
+ " FROM collectable_blindcoins"
+ " WHERE reserve_pub=$1;",
+ 1, NULL);
/* FIXME: does it make sense to store these computed values in the DB? */
#if 0
@@ -874,6 +890,8 @@ TALER_MINT_DB_reserves_in_insert (PGconn *db,
TALER_DB_QUERY_PARAM_PTR (reserve->pub),
TALER_DB_QUERY_PARAM_PTR (&balance_nbo.value),
TALER_DB_QUERY_PARAM_PTR (&balance_nbo.fraction),
+ TALER_DB_QUERY_PARAM_PTR_SIZED (&balance_nbo.currency,
+ TALER_DB_CURRENCY_LEN),
TALER_DB_QUERY_PARAM_PTR (&expiry_nbo),
TALER_DB_QUERY_PARAM_END
};
@@ -1070,66 +1088,150 @@ struct ReserveHistory *
TALER_MINT_DB_get_reserve_history (PGconn *db_conn,
const struct GNUNET_CRYPTO_EddsaPublicKey *reserve_pub)
{
- // FIXME: implement logic!
PGresult *result;
- struct TALER_DB_QueryParam params[] = {
- TALER_DB_QUERY_PARAM_PTR (reserve_pub),
- TALER_DB_QUERY_PARAM_END
- };
-
- result = TALER_DB_exec_prepared (db_conn, "get_reserve", params);
+ struct ReserveHistory *rh;
+ struct ReserveHistory *rh_head;
+ int rows;
+ int ret;
- if (PGRES_TUPLES_OK != PQresultStatus (result))
+ result = NULL;
+ rh = NULL;
+ rh_head = NULL;
+ ret = GNUNET_SYSERR;
{
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Query failed: %s\n",
- PQresultErrorMessage (result));
- PQclear (result);
- return NULL;
- }
+ struct BankTransfer *bt;
+ struct TALER_DB_QueryParam params[] = {
+ TALER_DB_QUERY_PARAM_PTR (reserve_pub),
+ TALER_DB_QUERY_PARAM_END
+ };
- if (0 == PQntuples (result))
- {
- PQclear (result);
- return NULL;
+ result = TALER_DB_exec_prepared (db_conn,
+ "get_reserves_in_transactions",
+ params);
+ if (PGRES_TUPLES_OK != PQresultStatus (result))
+ {
+ QUERY_ERR (result);
+ goto cleanup;
+ }
+ if (0 == (rows = PQntuples (result)))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Asked to fetch history for an unknown reserve.\n");
+ goto cleanup;
+ }
+ while (0 < rows)
+ {
+ bt = GNUNET_new (struct BankTransfer);
+ if (GNUNET_OK != TALER_DB_extract_amount (result,
+ --rows,
+ "balance_value",
+ "balance_fraction",
+ "balance_currency",
+ &bt->amount))
+ {
+ GNUNET_free (bt);
+ GNUNET_break (0);
+ goto cleanup;
+ }
+ (void) memcpy (&bt->reserve_pub, reserve_pub, sizeof (bt->reserve_pub));
+ if (NULL != rh_head)
+ {
+ rh_head->next = GNUNET_new (struct ReserveHistory);
+ rh_head = rh_head->next;
+ }
+ else
+ {
+ rh_head = GNUNET_new (struct ReserveHistory);
+ rh = rh_head;
+ }
+ rh_head->type = TALER_MINT_DB_RO_BANK_TO_MINT;
+ rh_head->details.bank = bt;
+ }
}
-#if 0
- reserve->reserve_pub = *reserve_pub;
-
- struct TALER_DB_ResultSpec rs[] = {
- TALER_DB_RESULT_SPEC("status_sig", &reserve->status_sig),
- TALER_DB_RESULT_SPEC("status_sign_pub", &reserve->status_sign_pub),
- TALER_DB_RESULT_SPEC_END
- };
-
- res = TALER_DB_extract_result (result, rs, 0);
- if (GNUNET_SYSERR == res)
+ PQclear (result);
+ result = NULL;
{
- GNUNET_break (0);
- PQclear (result);
- return GNUNET_SYSERR;
- }
+ struct GNUNET_HashCode blind_ev;
+ struct GNUNET_CRYPTO_EddsaSignature reserve_sig;
+ struct CollectableBlindcoin *cbc;
+ char *denom_pub_enc;
+ char *denom_sig_enc;
+ size_t denom_pub_enc_size;
+ size_t denom_sig_enc_size;
- {
- if (GNUNET_OK !=
- TALER_DB_extract_amount_nbo (result, 0,
- "balance_value",
- "balance_fraction",
- "balance_currency",
- &reserve->balance))
+ struct TALER_DB_QueryParam params[] = {
+ TALER_DB_QUERY_PARAM_PTR (reserve_pub),
+ TALER_DB_QUERY_PARAM_END
+ };
+ result = TALER_DB_exec_prepared (db_conn,
+ "get_reserves_blindcoins",
+ params);
+ if (PGRES_TUPLES_OK != PQresultStatus (result))
{
- GNUNET_break (0);
- PQclear (result);
- return GNUNET_SYSERR;
+ QUERY_ERR (result);
+ goto cleanup;
+ }
+ if (0 == (rows = PQntuples (result)))
+ {
+ ret = GNUNET_OK; /* Its OK if there are no withdrawls yet */
+ goto cleanup;
+ }
+ struct TALER_DB_ResultSpec rs[] = {
+ TALER_DB_RESULT_SPEC ("blind_ev", &blind_ev),
+ TALER_DB_RESULT_SPEC_VAR ("denom_pub", &denom_pub_enc, &denom_pub_enc_size),
+ TALER_DB_RESULT_SPEC_VAR ("denom_sig", &denom_sig_enc, &denom_sig_enc_size),
+ TALER_DB_RESULT_SPEC ("reserve_sig", &reserve_sig),
+ TALER_DB_RESULT_SPEC_END
+ };
+ GNUNET_assert (NULL != rh);
+ GNUNET_assert (NULL != rh_head);
+ GNUNET_assert (NULL == rh_head->next);
+ while (0 < rows)
+ {
+ if (GNUNET_YES != TALER_DB_extract_result (result, rs, --rows))
+ {
+ GNUNET_break (0);
+ goto cleanup;
+ }
+ cbc = GNUNET_new (struct CollectableBlindcoin);
+ cbc->sig = GNUNET_CRYPTO_rsa_signature_decode (denom_sig_enc,
+ denom_sig_enc_size);
+ GNUNET_free (denom_sig_enc);
+ denom_sig_enc = NULL;
+ cbc->denom_pub = GNUNET_CRYPTO_rsa_public_key_decode (denom_pub_enc,
+ denom_pub_enc_size);
+ GNUNET_free (denom_pub_enc);
+ denom_pub_enc = NULL;
+ if ((NULL == cbc->sig) || (NULL == cbc->denom_pub))
+ {
+ if (NULL != cbc->sig)
+ GNUNET_CRYPTO_rsa_signature_free (cbc->sig);
+ if (NULL != cbc->denom_pub)
+ GNUNET_CRYPTO_rsa_public_key_free (cbc->denom_pub);
+ GNUNET_free (cbc);
+ GNUNET_break (0);
+ goto cleanup;
+ }
+ (void) memcpy (&cbc->h_coin_envelope, &blind_ev, sizeof (blind_ev));
+ (void) memcpy (&cbc->reserve_pub, reserve_pub, sizeof (cbc->reserve_pub));
+ (void) memcpy (&cbc->reserve_sig, &reserve_sig, sizeof (cbc->reserve_sig));
+ rh_head->next = GNUNET_new (struct ReserveHistory);
+ rh_head = rh_head->next;
+ rh_head->type = TALER_MINT_DB_RO_WITHDRAW_COIN;
+ rh_head->details.withdraw = cbc;
}
}
+ ret = GNUNET_OK;
- /* FIXME: Add expiration?? */
-
- PQclear (result);
- return GNUNET_OK;
-#endif
- return NULL;
+ cleanup:
+ if (NULL != result)
+ PQclear (result);
+ if (GNUNET_SYSERR == ret)
+ {
+ TALER_MINT_DB_free_reserve_history (rh);
+ rh = NULL;
+ }
+ return rh;
}
@@ -1141,8 +1243,31 @@ TALER_MINT_DB_get_reserve_history (PGconn *db_conn,
void
TALER_MINT_DB_free_reserve_history (struct ReserveHistory *rh)
{
- // FIXME: implement
- GNUNET_assert (0);
+ struct BankTransfer *bt;
+ struct CollectableBlindcoin *cbc;
+ struct ReserveHistory *backref;
+
+ while (NULL != rh)
+ {
+ switch(rh->type)
+ {
+ case TALER_MINT_DB_RO_BANK_TO_MINT:
+ bt = rh->details.bank;
+ if (NULL != bt->wire)
+ json_decref ((json_t *) bt->wire); /* FIXME: avoid cast? */
+ GNUNET_free (bt);
+ break;
+ case TALER_MINT_DB_RO_WITHDRAW_COIN:
+ cbc = rh->details.withdraw;
+ GNUNET_CRYPTO_rsa_signature_free (cbc->sig);
+ GNUNET_CRYPTO_rsa_public_key_free (cbc->denom_pub);
+ GNUNET_free (cbc);
+ break;
+ }
+ backref = rh;
+ rh = rh->next;
+ GNUNET_free (backref);
+ }
}
diff --git a/src/mint/test_mint_db.c b/src/mint/test_mint_db.c
index b154e0bfe..c18ad2e8e 100644
--- a/src/mint/test_mint_db.c
+++ b/src/mint/test_mint_db.c
@@ -40,6 +40,8 @@ static int result;
memset (ptr, 0, sizeof (*ptr))
+#define CURRENCY "EUR"
+
/**
* Checks if the given reserve has the given amount of balance and expiry
*
@@ -120,10 +122,15 @@ run (void *cls, char *const *args, const char *cfgfile,
struct GNUNET_HashCode h_blind;
struct CollectableBlindcoin cbc;
struct CollectableBlindcoin cbc2;
-
+ struct ReserveHistory *rh;
+ struct ReserveHistory *rh_head;
+ struct BankTransfer *bt;
+ struct CollectableBlindcoin *withdraw;
+ unsigned int cnt;
db = NULL;
dkp = NULL;
+ rh = NULL;
ZR_BLK (&cbc);
ZR_BLK (&cbc2);
if (GNUNET_OK != TALER_MINT_DB_init ("postgres:///taler"))
@@ -145,7 +152,7 @@ run (void *cls, char *const *args, const char *cfgfile,
reserve.pub = &reserve_pub;
amount.value = 1;
amount.fraction = 1;
- strcpy (amount.currency, "EUR");
+ strcpy (amount.currency, CURRENCY);
expiry = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (),
GNUNET_TIME_UNIT_HOURS);
result = 4;
@@ -174,7 +181,7 @@ run (void *cls, char *const *args, const char *cfgfile,
RND_BLK(&cbc.reserve_sig);
cbc.denom_pub = dkp->pub;
cbc.sig = GNUNET_CRYPTO_rsa_sign (dkp->priv, &h_blind, sizeof (h_blind));
- memcpy (&cbc.reserve_pub, &reserve_pub, sizeof (reserve_pub));
+ (void) memcpy (&cbc.reserve_pub, &reserve_pub, sizeof (reserve_pub));
FAILIF (GNUNET_OK != TALER_MINT_DB_insert_collectable_blindcoin (db,
&h_blind,
&cbc));
@@ -185,9 +192,37 @@ run (void *cls, char *const *args, const char *cfgfile,
FAILIF (0 != memcmp (&cbc2.reserve_sig, &cbc.reserve_sig, sizeof (cbc2.reserve_sig)));
FAILIF (0 != memcmp (&cbc2.reserve_pub, &cbc.reserve_pub, sizeof (cbc2.reserve_pub)));
FAILIF (GNUNET_OK != GNUNET_CRYPTO_rsa_verify (&h_blind, cbc2.sig, dkp->pub));
+ rh_head = rh = TALER_MINT_DB_get_reserve_history (db, &reserve_pub);
+ FAILIF (NULL == rh);
+ for (cnt=0; NULL != rh_head; rh_head=rh_head->next, cnt++)
+ {
+ switch (rh_head->type)
+ {
+ case TALER_MINT_DB_RO_BANK_TO_MINT:
+ bt = rh_head->details.bank;
+ FAILIF (0 != memcmp (&bt->reserve_pub, &reserve_pub, sizeof (reserve_pub)));
+ FAILIF (1 != bt->amount.value);
+ FAILIF (1 != bt->amount.fraction);
+ FAILIF (0 != strcmp (CURRENCY, bt->amount.currency));
+ FAILIF (NULL != bt->wire); /* FIXME: write wire details to db */
+ break;
+ case TALER_MINT_DB_RO_WITHDRAW_COIN:
+ withdraw = rh_head->details.withdraw;
+ FAILIF (0 != memcmp (&withdraw->reserve_pub,
+ &reserve_pub,
+ sizeof (reserve_pub)));
+ FAILIF (0 != memcmp (&withdraw->h_coin_envelope,
+ &h_blind, sizeof (h_blind)));
+ break;
+ }
+ }
+ FAILIF (3 != cnt);
result = 0;
drop:
+ if (NULL != rh)
+ TALER_MINT_DB_free_reserve_history (rh);
+ rh = NULL;
if (NULL != db)
GNUNET_break (GNUNET_OK == TALER_MINT_DB_drop_temporary (db));
if (NULL != dkp)