summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2016-06-05 14:10:21 +0200
committerChristian Grothoff <christian@grothoff.org>2016-06-05 14:10:21 +0200
commit148de70dd07591d40a5fa123dcbf4c3b1701cab2 (patch)
treebacdb10e8a731fd4b75e030905a40b8e671837b9
parent94d8d6b48e7fdaf7c7caf47a39faa8a33a72915f (diff)
downloadmerchant-148de70dd07591d40a5fa123dcbf4c3b1701cab2.tar.gz
merchant-148de70dd07591d40a5fa123dcbf4c3b1701cab2.tar.bz2
merchant-148de70dd07591d40a5fa123dcbf4c3b1701cab2.zip
more work on tracking, do store exchange_uri with transaction data
-rw-r--r--src/backend/taler-merchant-httpd.c11
-rw-r--r--src/backend/taler-merchant-httpd.h4
-rw-r--r--src/backend/taler-merchant-httpd_contract.c2
-rw-r--r--src/backend/taler-merchant-httpd_pay.c3
-rw-r--r--src/backend/taler-merchant-httpd_track-transaction.c186
-rw-r--r--src/backenddb/plugin_merchantdb_postgres.c16
-rw-r--r--src/include/taler_merchantdb_plugin.h4
7 files changed, 168 insertions, 58 deletions
diff --git a/src/backend/taler-merchant-httpd.c b/src/backend/taler-merchant-httpd.c
index 5f0a887c..afff8285 100644
--- a/src/backend/taler-merchant-httpd.c
+++ b/src/backend/taler-merchant-httpd.c
@@ -60,7 +60,7 @@ struct GNUNET_HashCode h_wire;
/**
* Merchant's private key
*/
-struct GNUNET_CRYPTO_EddsaPrivateKey *privkey;
+struct TALER_MerchantPrivateKeyP privkey;
/**
* Merchant's public key
@@ -276,8 +276,6 @@ do_shutdown (void *cls)
}
TMH_EXCHANGES_done ();
TMH_AUDITORS_done ();
- if (NULL != keyfile)
- GNUNET_free (privkey);
if (NULL != j_wire)
{
json_decref (j_wire);
@@ -491,6 +489,7 @@ run (void *cls,
{
char *wireformat;
int fh;
+ struct GNUNET_CRYPTO_EddsaPrivateKey *pk;
wireformat = NULL;
result = GNUNET_SYSERR;
@@ -575,15 +574,17 @@ run (void *cls,
"Merchant private key `%s' does not exist yet, creating it!\n",
keyfile);
if (NULL ==
- (privkey =
+ (pk =
GNUNET_CRYPTO_eddsa_key_create_from_file (keyfile)))
{
GNUNET_break (0);
GNUNET_SCHEDULER_shutdown ();
return;
}
- GNUNET_CRYPTO_eddsa_key_get_public (privkey,
+ privkey.eddsa_priv = *pk;
+ GNUNET_CRYPTO_eddsa_key_get_public (pk,
&pubkey.eddsa_pub);
+ GNUNET_free (pk);
if (NULL ==
(db = TALER_MERCHANTDB_plugin_load (config)))
{
diff --git a/src/backend/taler-merchant-httpd.h b/src/backend/taler-merchant-httpd.h
index 4446a7df..7fcfba02 100644
--- a/src/backend/taler-merchant-httpd.h
+++ b/src/backend/taler-merchant-httpd.h
@@ -162,9 +162,9 @@ extern json_t *j_wire;
extern struct GNUNET_HashCode h_wire;
/**
- * Our private key (for the merchant to sign contracts).
+ * Our private key, corresponds to #pubkey.
*/
-extern struct GNUNET_CRYPTO_EddsaPrivateKey *privkey;
+extern struct TALER_MerchantPrivateKeyP privkey;
/**
* Our public key, corresponds to #privkey.
diff --git a/src/backend/taler-merchant-httpd_contract.c b/src/backend/taler-merchant-httpd_contract.c
index 0278a7f7..969c0c9e 100644
--- a/src/backend/taler-merchant-httpd_contract.c
+++ b/src/backend/taler-merchant-httpd_contract.c
@@ -213,7 +213,7 @@ MH_handler_contract (struct TMH_RequestHandler *rh,
GNUNET_assert (GNUNET_OK ==
TALER_JSON_hash (jcontract,
&contract.h_contract));
- GNUNET_CRYPTO_eddsa_sign (privkey,
+ GNUNET_CRYPTO_eddsa_sign (&privkey.eddsa_priv,
&contract.purpose,
&contract_sig);
diff --git a/src/backend/taler-merchant-httpd_pay.c b/src/backend/taler-merchant-httpd_pay.c
index 50cbe79f..f32d3dbb 100644
--- a/src/backend/taler-merchant-httpd_pay.c
+++ b/src/backend/taler-merchant-httpd_pay.c
@@ -748,6 +748,7 @@ check_coin_paid (void *cls,
*
* @param cls closure with the `struct PayContext`
* @param transaction_id of the contract
+ * @param exchange_uri URI of the exchange
* @param h_contract hash of the contract
* @param h_xwire hash of our wire details
* @param timestamp time of the confirmation
@@ -757,6 +758,7 @@ check_coin_paid (void *cls,
static void
check_transaction_exists (void *cls,
uint64_t transaction_id,
+ const char *exchange_uri,
const struct GNUNET_HashCode *h_contract,
const struct GNUNET_HashCode *h_xwire,
struct GNUNET_TIME_Absolute timestamp,
@@ -1053,6 +1055,7 @@ MH_handler_pay (struct TMH_RequestHandler *rh,
if (GNUNET_OK !=
db->store_transaction (db->cls,
pc->transaction_id,
+ pc->chosen_exchange,
&pc->h_contract,
&h_wire,
pc->timestamp,
diff --git a/src/backend/taler-merchant-httpd_track-transaction.c b/src/backend/taler-merchant-httpd_track-transaction.c
index b64e8204..96c677dd 100644
--- a/src/backend/taler-merchant-httpd_track-transaction.c
+++ b/src/backend/taler-merchant-httpd_track-transaction.c
@@ -40,6 +40,11 @@
extern char *TMH_merchant_currency_string;
+/**
+ * Context for a /track/transaction operation.
+ */
+struct TrackTransactionContext;
+
/**
* Information we keep for each coin in a /track/transaction operation.
@@ -57,6 +62,11 @@ struct TrackCoinContext
struct TrackCoinContext *prev;
/**
+ * Our Context for a /track/transaction operation.
+ */
+ struct TrackTransactionContext *tctx;
+
+ /**
* Public key of the coin.
*/
struct TALER_CoinSpendPublicKeyP coin_pub;
@@ -66,6 +76,16 @@ struct TrackCoinContext
*/
struct TALER_EXCHANGE_DepositWtidHandle *dwh;
+ /**
+ * Wire transfer identifier for this coin.
+ */
+ struct TALER_WireTransferIdentifierRawP wtid;
+
+ /**
+ * Have we obtained the WTID for this coin yet?
+ */
+ int have_wtid;
+
};
@@ -97,6 +117,16 @@ struct TrackTransactionContext
struct TrackCoinContext *tcc_tail;
/**
+ * Exchange that was used for the transaction.
+ */
+ char *exchange_uri;
+
+ /**
+ * Wire transfer identifier we are currently looking up in @e wdh
+ */
+ struct TALER_WireTransferIdentifierRawP current_wtid;
+
+ /**
* Transaction this request is about.
*/
uint64_t transaction_id;
@@ -184,6 +214,11 @@ free_tctx (struct TrackTransactionContext *tctx)
}
GNUNET_free (tcc);
}
+ if (NULL != tctx->wdh)
+ {
+ TALER_EXCHANGE_wire_deposits_cancel (tctx->wdh);
+ tctx->wdh = NULL;
+ }
if (NULL != tctx->fo)
{
TMH_EXCHANGES_find_exchange_cancel (tctx->fo);
@@ -194,6 +229,11 @@ free_tctx (struct TrackTransactionContext *tctx)
GNUNET_SCHEDULER_cancel (tctx->timeout_task);
tctx->timeout_task = NULL;
}
+ if (NULL != tctx->exchange_uri)
+ {
+ GNUNET_free (tctx->exchange_uri);
+ tctx->exchange_uri = NULL;
+ }
GNUNET_free (tctx);
}
@@ -222,21 +262,21 @@ track_transaction_cleanup (struct TM_HandlerContext *hc)
* @param response response data to send back
*/
static void
-resume_track_transaction_with_response (struct TrackTransactionContext *ttc,
+resume_track_transaction_with_response (struct TrackTransactionContext *tctx,
unsigned int response_code,
struct MHD_Response *response)
{
- ttc->response_code = response_code;
- ttc->response = response;
+ tctx->response_code = response_code;
+ tctx->response = response;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Resuming /track/transaction handling as exchange interaction is done (%u)\n",
response_code);
- if (NULL != ttc->timeout_task)
+ if (NULL != tctx->timeout_task)
{
- GNUNET_SCHEDULER_cancel (ttc->timeout_task);
- ttc->timeout_task = NULL;
+ GNUNET_SCHEDULER_cancel (tctx->timeout_task);
+ tctx->timeout_task = NULL;
}
- MHD_resume_connection (ttc->connection);
+ MHD_resume_connection (tctx->connection);
TMH_trigger_daemon (); /* we resumed, kick MHD */
}
@@ -280,15 +320,58 @@ wire_deposits_cb (void *cls,
const struct TALER_WireDepositDetails *details)
{
struct TrackTransactionContext *tctx = cls;
+ struct TrackCoinContext *tcc;
+ unsigned int i;
- /* FIXME: store data in database */
- /* FIXME: check which coins of 'tctx' are now covered */
- GNUNET_break (0);
+ tctx->wdh = NULL;
+ if (MHD_HTTP_OK != http_status)
+ {
+ resume_track_transaction_with_response
+ (tctx,
+ MHD_HTTP_FAILED_DEPENDENCY,
+ TMH_RESPONSE_make_json_pack ("{s:I, s:o}",
+ "exchange_status", (json_int_t) http_status,
+ "details", json));
+ return;
+ }
+ if (GNUNET_OK !=
+ db->store_transfer_to_proof (db->cls,
+ &tctx->current_wtid,
+ json))
+ {
+ /* Not good, but not fatal either, log error and continue */
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Failed to store transfer-to-proof mapping in DB\n");
+ }
+ for (tcc=tctx->tcc_head;NULL != tcc;tcc=tcc->next)
+ {
+ if (GNUNET_YES == tcc->have_wtid)
+ continue;
+ for (i=0;i<details_length;i++)
+ {
+ if (0 != memcmp (&details[i].coin_pub,
+ &tcc->coin_pub,
+ sizeof (struct TALER_CoinSpendPublicKeyP)))
+ continue;
+ tcc->wtid = tctx->current_wtid;
+ tcc->have_wtid = GNUNET_YES;
+ if (GNUNET_OK !=
+ db->store_coin_to_transfer (db->cls,
+ tctx->transaction_id,
+ &tcc->coin_pub,
+ &tctx->current_wtid))
+ {
+ /* Not good, but not fatal either, log error and continue */
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Failed to store coin-to-transfer mapping in DB\n");
+ }
+ }
+ }
+ /* Continue traceing (will also handle case that we are done) */
trace_coins (tctx);
}
-
/**
* Function called with detailed wire transfer data.
* We were trying to find out in which wire transfer one of the
@@ -296,7 +379,7 @@ wire_deposits_cb (void *cls,
* obtain the inverse: all other coins of that wire transfer,
* which is what we prefer to store.
*
- * @param cls closure
+ * @param cls closure with a `struct TrackCoinContext`
* @param http_status HTTP status code we got, 0 on exchange protocol violation
* @param json original json reply (may include signatures, those have then been
* validated already)
@@ -313,8 +396,11 @@ wtid_cb (void *cls,
struct GNUNET_TIME_Absolute execution_time,
const struct TALER_Amount *coin_contribution)
{
- struct TrackTransactionContext *tctx = cls;
+ struct TrackCoinContext *tcc = cls;
+ struct TrackTransactionContext *tctx = tcc->tctx;
+ tcc->dwh = NULL;
+ tctx->current_wtid = *wtid;
tctx->wdh = TALER_EXCHANGE_wire_deposits (tctx->eh,
wtid,
&wire_deposits_cb,
@@ -332,29 +418,30 @@ wtid_cb (void *cls,
static void
trace_coins (struct TrackTransactionContext *tctx)
{
- GNUNET_assert (NULL != tctx->eh);
+ struct TrackCoinContext *tcc;
- GNUNET_break (0);
-#if ALL_COINS_DONE
- if (0)
+ GNUNET_assert (NULL != tctx->eh);
+ for (tcc = tctx->tcc_head; NULL != tcc; tcc = tcc->next)
+ if (GNUNET_YES != tcc->have_wtid)
+ break;
+ if (NULL == tcc)
{
+#if ALL_COINS_DONE_FIXME
generate_response ();
resume_track_transaction_with_response (tctx,
MHD_HTTP_OK,
response);
+#endif
return;
}
-#endif
-#if FOR_NEXT_COIN_IN_ORDER_ONE_AT_A_TIME_UNTIL_ALL_ARE_DONE
- tctx->dwh = TALER_EXCHANGE_deposit_wtid (eh,
- merchant_priv,
- &tctx->h_wire,
- &tctx->h_contract,
- &coin_pub,
- tctx->transaction_id,
- &wtid_cb,
- tctx);
-#endif
+ tcc->dwh = TALER_EXCHANGE_deposit_wtid (tctx->eh,
+ &privkey,
+ &tctx->h_wire,
+ &tctx->h_contract,
+ &tcc->coin_pub,
+ tctx->transaction_id,
+ &wtid_cb,
+ tcc);
}
@@ -386,18 +473,18 @@ process_track_transaction_with_exchange (void *cls,
static void
handle_track_transaction_timeout (void *cls)
{
- struct TrackTransactionContext *ttc = cls;
+ struct TrackTransactionContext *tctx = cls;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Resuming /track/transaction with error after timeout\n");
- ttc->timeout_task = NULL;
+ tctx->timeout_task = NULL;
- if (NULL != ttc->fo)
+ if (NULL != tctx->fo)
{
- TMH_EXCHANGES_find_exchange_cancel (ttc->fo);
- ttc->fo = NULL;
+ TMH_EXCHANGES_find_exchange_cancel (tctx->fo);
+ tctx->fo = NULL;
}
- resume_track_transaction_with_response (ttc,
+ resume_track_transaction_with_response (tctx,
MHD_HTTP_SERVICE_UNAVAILABLE,
TMH_RESPONSE_make_internal_error ("exchange not reachable"));
}
@@ -408,6 +495,7 @@ handle_track_transaction_timeout (void *cls)
*
* @param cls closure
* @param transaction_id of the contract
+ * @param exchange_uri URI of the exchange
* @param h_contract hash of the contract
* @param h_wire hash of our wire details
* @param timestamp time of the confirmation
@@ -417,20 +505,22 @@ handle_track_transaction_timeout (void *cls)
static void
transaction_cb (void *cls,
uint64_t transaction_id,
+ const char *exchange_uri,
const struct GNUNET_HashCode *h_contract,
const struct GNUNET_HashCode *h_wire,
struct GNUNET_TIME_Absolute timestamp,
struct GNUNET_TIME_Absolute refund,
const struct TALER_Amount *total_amount)
{
- struct TrackTransactionContext *ttc = cls;
-
- ttc->transaction_id = transaction_id;
- ttc->h_contract = *h_contract;
- ttc->h_wire = *h_wire;
- ttc->timestamp = timestamp;
- ttc->refund_deadline = refund;
- ttc->total_amount = *total_amount;
+ struct TrackTransactionContext *tctx = cls;
+
+ tctx->transaction_id = transaction_id;
+ tctx->exchange_uri = GNUNET_strdup (exchange_uri);
+ tctx->h_contract = *h_contract;
+ tctx->h_wire = *h_wire;
+ tctx->timestamp = timestamp;
+ tctx->refund_deadline = refund;
+ tctx->total_amount = *total_amount;
}
@@ -452,13 +542,14 @@ coin_cb (void *cls,
const struct TALER_Amount *deposit_fee,
const json_t *exchange_proof)
{
- struct TrackTransactionContext *ttc = cls;
+ struct TrackTransactionContext *tctx = cls;
struct TrackCoinContext *tcc;
tcc = GNUNET_new (struct TrackCoinContext);
+ tcc->tctx = tctx;
tcc->coin_pub = *coin_pub;
- GNUNET_CONTAINER_DLL_insert (ttc->tcc_head,
- ttc->tcc_tail,
+ GNUNET_CONTAINER_DLL_insert (tctx->tcc_head,
+ tctx->tcc_tail,
tcc);
}
@@ -545,7 +636,8 @@ MH_handler_track_transaction (struct TMH_RequestHandler *rh,
"Unknown transaction ID");
}
if ( (GNUNET_SYSERR == ret) ||
- (tctx->transaction_id != (uint64_t) transaction_id) )
+ (tctx->transaction_id != (uint64_t) transaction_id) ||
+ (NULL == tctx->exchange_uri) )
{
GNUNET_break (0);
free_tctx (tctx);
@@ -575,7 +667,7 @@ MH_handler_track_transaction (struct TMH_RequestHandler *rh,
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Suspending /track/transaction handling while working with the exchange\n");
MHD_suspend_connection (connection);
- tctx->fo = TMH_EXCHANGES_find_exchange (NULL, /* FIXME: tctx->chosen_exchange */
+ tctx->fo = TMH_EXCHANGES_find_exchange (tctx->exchange_uri,
&process_track_transaction_with_exchange,
tctx);
diff --git a/src/backenddb/plugin_merchantdb_postgres.c b/src/backenddb/plugin_merchantdb_postgres.c
index 46435790..bfd0c55f 100644
--- a/src/backenddb/plugin_merchantdb_postgres.c
+++ b/src/backenddb/plugin_merchantdb_postgres.c
@@ -156,6 +156,7 @@ postgres_initialize (void *cls)
PG_EXEC (pg,
"CREATE TABLE IF NOT EXISTS merchant_transactions ("
" transaction_id INT8 PRIMARY KEY"
+ ",exchange_uri VARCHAR NOT NULL"
",h_contract BYTEA NOT NULL CHECK (LENGTH(h_contract)=64)"
",h_wire BYTEA NOT NULL CHECK (LENGTH(h_wire)=64)"
",timestamp INT8 NOT NULL"
@@ -203,6 +204,7 @@ postgres_initialize (void *cls)
"insert_transaction",
"INSERT INTO merchant_transactions"
"(transaction_id"
+ ",exchange_uri"
",h_contract"
",h_wire"
",timestamp"
@@ -211,8 +213,8 @@ postgres_initialize (void *cls)
",total_amount_frac"
",total_amount_curr"
") VALUES "
- "($1, $2, $3, $4, $5, $6, $7, $8)",
- 8);
+ "($1, $2, $3, $4, $5, $6, $7, $8, $9)",
+ 9);
PG_PREPARE (pg,
"insert_deposit",
"INSERT INTO merchant_deposits"
@@ -247,7 +249,8 @@ postgres_initialize (void *cls)
PG_PREPARE (pg,
"find_transaction",
"SELECT"
- " h_contract"
+ " exchange_uri"
+ ",h_contract"
",h_wire"
",timestamp"
",refund_deadline"
@@ -309,6 +312,7 @@ postgres_initialize (void *cls)
*
* @param cls closure
* @param transaction_id of the contract
+ * @param exchange_uri URI of the exchange
* @param h_contract hash of the contract
* @param h_wire hash of our wire details
* @param timestamp time of the confirmation
@@ -319,6 +323,7 @@ postgres_initialize (void *cls)
static int
postgres_store_transaction (void *cls,
uint64_t transaction_id,
+ const char *exchange_uri,
const struct GNUNET_HashCode *h_contract,
const struct GNUNET_HashCode *h_wire,
struct GNUNET_TIME_Absolute timestamp,
@@ -331,6 +336,7 @@ postgres_store_transaction (void *cls,
struct GNUNET_PQ_QueryParam params[] = {
GNUNET_PQ_query_param_uint64 (&transaction_id),
+ GNUNET_PQ_query_param_string (exchange_uri),
GNUNET_PQ_query_param_auto_from_type (h_contract),
GNUNET_PQ_query_param_auto_from_type (h_wire),
GNUNET_PQ_query_param_absolute_time (&timestamp),
@@ -535,12 +541,15 @@ postgres_find_transaction_by_id (void *cls,
}
{
+ char *exchange_uri;
struct GNUNET_HashCode h_contract;
struct GNUNET_HashCode h_wire;
struct GNUNET_TIME_Absolute timestamp;
struct GNUNET_TIME_Absolute refund_deadline;
struct TALER_Amount total_amount;
struct GNUNET_PQ_ResultSpec rs[] = {
+ GNUNET_PQ_result_spec_string ("exchange_uri",
+ &exchange_uri),
GNUNET_PQ_result_spec_auto_from_type ("h_contract",
&h_contract),
GNUNET_PQ_result_spec_auto_from_type ("h_wire",
@@ -565,6 +574,7 @@ postgres_find_transaction_by_id (void *cls,
}
cb (cb_cls,
transaction_id,
+ exchange_uri,
&h_contract,
&h_wire,
timestamp,
diff --git a/src/include/taler_merchantdb_plugin.h b/src/include/taler_merchantdb_plugin.h
index 16064448..1b3013dd 100644
--- a/src/include/taler_merchantdb_plugin.h
+++ b/src/include/taler_merchantdb_plugin.h
@@ -36,6 +36,7 @@ struct TALER_MERCHANTDB_Plugin;
*
* @param cls closure
* @param transaction_id of the contract
+ * @param exchange_uri URI of the exchange
* @param h_contract hash of the contract
* @param h_wire hash of our wire details
* @param timestamp time of the confirmation
@@ -45,6 +46,7 @@ struct TALER_MERCHANTDB_Plugin;
typedef void
(*TALER_MERCHANTDB_TransactionCallback)(void *cls,
uint64_t transaction_id,
+ const char *exchange_uri,
const struct GNUNET_HashCode *h_contract,
const struct GNUNET_HashCode *h_wire,
struct GNUNET_TIME_Absolute timestamp,
@@ -136,6 +138,7 @@ struct TALER_MERCHANTDB_Plugin
*
* @param cls closure
* @param transaction_id of the contract
+ * @param exchange_uri URI of the exchange
* @param h_contract hash of the contract
* @param h_wire hash of our wire details
* @param timestamp time of the confirmation
@@ -146,6 +149,7 @@ struct TALER_MERCHANTDB_Plugin
int
(*store_transaction) (void *cls,
uint64_t transaction_id,
+ const char *exchange_uri,
const struct GNUNET_HashCode *h_contract,
const struct GNUNET_HashCode *h_wire,
struct GNUNET_TIME_Absolute timestamp,