[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[taler-merchant] 95/277: db work for POST /transfers
From: |
gnunet |
Subject: |
[taler-merchant] 95/277: db work for POST /transfers |
Date: |
Sun, 05 Jul 2020 20:50:08 +0200 |
This is an automated email from the git hooks/post-receive script.
grothoff pushed a commit to branch master
in repository merchant.
commit 02faacad3cd56e3266be625980920e420f61250f
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Wed May 6 21:41:59 2020 +0200
db work for POST /transfers
---
.../taler-merchant-httpd_private-post-transfers.c | 18 ++
src/backenddb/merchant-0001.sql | 2 -
src/backenddb/plugin_merchantdb_postgres.c | 255 ++++++++++++++++++++-
src/include/taler_merchantdb_plugin.h | 22 +-
4 files changed, 284 insertions(+), 13 deletions(-)
diff --git a/src/backend/taler-merchant-httpd_private-post-transfers.c
b/src/backend/taler-merchant-httpd_private-post-transfers.c
index 2f22d05..5c3a0e3 100644
--- a/src/backend/taler-merchant-httpd_private-post-transfers.c
+++ b/src/backend/taler-merchant-httpd_private-post-transfers.c
@@ -1013,6 +1013,7 @@ TMH_private_post_transfers (const struct
TMH_RequestHandler *rh,
/* reply not in database, ensure the POST is in the database, and
start work to obtain the reply from the exchange */
qs = TMH_db->insert_transfer (TMH_db->cls,
+ rctx->hc->instance->settings.id,
rctx->exchange_url,
&rctx->wtid,
&rctx->amount,
@@ -1029,6 +1030,23 @@ TMH_private_post_transfers (const struct
TMH_RequestHandler *rh,
TALER_EC_POST_TRANSFER_DB_STORE_ERROR,
"Fail to update database with transfer
record");
}
+ if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
+ {
+ uint64_t account_serial;
+
+ /* Either the record already exists (we should ignore this), or
+ the INSERT failed because we did not find the account based on
+ the given payto-URI and the instance. */
+ qs = TMH_db->lookup_account (TMH_db->cls,
+ rctx->hc->instance->settings.id,
+ rctx->payto_uri,
+ &account_serial);
+ if (0 >= qs)
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_NOT_FOUND,
+
TALER_EC_POST_TRANSFER_ACCOUNT_NOT_FOUND,
+ "Instance does not have this bank
account");
+ }
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Suspending POST /private/transfers handling while working with
exchange\n");
diff --git a/src/backenddb/merchant-0001.sql b/src/backenddb/merchant-0001.sql
index 3feb347..55cef42 100644
--- a/src/backenddb/merchant-0001.sql
+++ b/src/backenddb/merchant-0001.sql
@@ -368,8 +368,6 @@ COMMENT ON COLUMN merchant_transfers.confirmed
CREATE TABLE IF NOT EXISTS merchant_transfer_signatures
(credit_serial BIGINT PRIMARY KEY
REFERENCES merchant_transfers (credit_serial) ON DELETE CASCADE
- ,account_serial BIGINT NOT NULL
- REFERENCES merchant_accounts (account_serial) ON DELETE CASCADE
,signkey_serial BIGINT NOT NULL
REFERENCES merchant_exchange_signing_keys (signkey_serial) ON DELETE
CASCADE
,execution_time INT8 NOT NULL
diff --git a/src/backenddb/plugin_merchantdb_postgres.c
b/src/backenddb/plugin_merchantdb_postgres.c
index e6bc530..acb32e9 100644
--- a/src/backenddb/plugin_merchantdb_postgres.c
+++ b/src/backenddb/plugin_merchantdb_postgres.c
@@ -2696,6 +2696,7 @@ postgres_lookup_order_by_fulfillment (void *cls,
* Insert information about a wire transfer the merchant has received.
*
* @param cls closure
+ * @param instance_id the instance that received the transfer
* @param exchange_url which exchange made the transfer
* @param wtid identifier of the wire transfer
* @param credit_amount how much did we receive
@@ -2707,12 +2708,64 @@ postgres_lookup_order_by_fulfillment (void *cls,
static enum GNUNET_DB_QueryStatus
postgres_insert_transfer (
void *cls,
+ const char *instance_id,
const char *exchange_url,
const struct TALER_WireTransferIdentifierRawP *wtid,
const struct TALER_Amount *credit_amount,
const char *payto_uri,
bool confirmed)
{
+ struct PostgresClosure *pg = cls;
+ uint8_t confirmed8 = confirmed;
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_string (exchange_url),
+ GNUNET_PQ_query_param_auto_from_type (wtid),
+ TALER_PQ_query_param_amount (credit_amount),
+ GNUNET_PQ_query_param_string (payto_uri),
+ GNUNET_PQ_query_param_auto_from_type (&confirmed8),
+ GNUNET_PQ_query_param_string (instance_id),
+ GNUNET_PQ_query_param_end
+ };
+
+ check_connection (pg);
+ return GNUNET_PQ_eval_prepared_non_select (pg->conn,
+ "insert_transfer",
+ params);
+}
+
+
+/**
+ * Lookup account serial by payto URI.
+ *
+ * @param cls closure
+ * @param instance_id instance to lookup the account from
+ * @param payto_uri what is the merchant's bank account to lookup
+ * @param[out] account_serial serial number of the account
+ * @return transaction status
+ */
+static enum GNUNET_DB_QueryStatus
+postgres_lookup_account (void *cls,
+ const char *instance_id,
+ const char *payto_uri,
+ uint64_t *account_serial)
+{
+ struct PostgresClosure *pg = cls;
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_string (instance_id),
+ GNUNET_PQ_query_param_string (payto_uri),
+ GNUNET_PQ_query_param_end
+ };
+ struct GNUNET_PQ_ResultSpec rs[] = {
+ GNUNET_PQ_result_spec_uint64 ("account_serial",
+ account_serial),
+ GNUNET_PQ_result_spec_end
+ };
+
+ check_connection (pg);
+ return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
+ "lookup_account",
+ params,
+ rs);
}
@@ -2720,6 +2773,7 @@ postgres_insert_transfer (
* Insert information about a wire transfer the merchant has received.
*
* @param cls closure
+ * @param instance_id instance to provide transfer details for
* @param exchange_url which exchange made the transfer
* @param payto_uri what is the merchant's bank account that received the
transfer
* @param wtid identifier of the wire transfer
@@ -2729,11 +2783,123 @@ postgres_insert_transfer (
static enum GNUNET_DB_QueryStatus
postgres_insert_transfer_details (
void *cls,
- const char *exchange_url, // FIXME: do we need the URL? We have
exchange_pub!
+ const char *instance_id,
+ const char *exchange_url,
const char *payto_uri,
const struct TALER_WireTransferIdentifierRawP *wtid,
const struct TALER_EXCHANGE_TransferData *td)
{
+ struct PostgresClosure *pg = cls;
+ enum GNUNET_DB_QueryStatus qs;
+ uint64_t credit_serial;
+ unsigned int retries;
+
+ retries = 0;
+ check_connection (pg);
+RETRY:
+ if (MAX_RETRIES < ++retries)
+ return GNUNET_DB_STATUS_SOFT_ERROR;
+ if (GNUNET_OK !=
+ postgres_start (pg,
+ "insert transfer details"))
+ {
+ GNUNET_break (0);
+ return GNUNET_DB_STATUS_HARD_ERROR;
+ }
+
+ /* lookup credit serial */
+ {
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_string (exchange_url),
+ GNUNET_PQ_query_param_string (payto_uri),
+ GNUNET_PQ_query_param_string (instance_id),
+ GNUNET_PQ_query_param_auto_from_type (wtid),
+ TALER_PQ_query_param_amount (&td->total_amount),
+ GNUNET_PQ_query_param_end
+ };
+ struct GNUNET_PQ_ResultSpec rs[] = {
+ GNUNET_PQ_result_spec_uint64 ("credit_serial",
+ &credit_serial),
+ GNUNET_PQ_result_spec_end
+ };
+
+ qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
+ "lookup_credit_serial",
+ params,
+ rs);
+ if (0 > qs)
+ {
+ GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
+ postgres_rollback (pg);
+ if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
+ goto RETRY;
+ return qs;
+ }
+ if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
+ {
+ /* account does not exists, fail! */
+ postgres_rollback (pg);
+ return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS;
+ }
+ }
+
+ /* update merchant_transfer_signatures table */
+ {
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_uint64 (&credit_serial),
+ GNUNET_PQ_query_param_absolute_time (&td->execution_time),
+ GNUNET_PQ_query_param_auto_from_type (&td->exchange_sig),
+ GNUNET_PQ_query_param_auto_from_type (&td->exchange_pub),
+ GNUNET_PQ_query_param_end
+ };
+
+ qs = GNUNET_PQ_eval_prepared_non_select (pg->conn,
+ "insert_transfer_signature",
+ params);
+ if (0 > qs)
+ {
+ GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
+ postgres_rollback (pg);
+ if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
+ goto RETRY;
+ return qs;
+ }
+ }
+
+ /* Update transfer-coin association table */
+ for (unsigned int i = 0; i<td->details_length; i++)
+ {
+ const struct TALER_TrackTransferDetails *d = &td->details[i];
+ uint32_t i32 = (uint32_t) i;
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_uint64 (&credit_serial),
+ GNUNET_PQ_query_param_uint32 (&i32),
+ TALER_PQ_query_param_amount (&d->coin_value),
+ TALER_PQ_query_param_amount (&d->coin_fee), /* deposit fee */
+ GNUNET_PQ_query_param_auto_from_type (&d->coin_pub),
+ GNUNET_PQ_query_param_auto_from_type (&d->h_contract_terms),
+ GNUNET_PQ_query_param_end
+ };
+
+ qs = GNUNET_PQ_eval_prepared_non_select (pg->conn,
+ "insert_transfer_to_coin_mapping",
+ params);
+ if (0 > qs)
+ {
+ GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
+ postgres_rollback (pg);
+ if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
+ goto RETRY;
+ return qs;
+ }
+ }
+ qs = postgres_commit (pg);
+ if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
+ return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
+ GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
+ if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
+ goto RETRY;
+ return qs;
}
@@ -5604,17 +5770,86 @@ libtaler_plugin_merchantdb_postgres_init (void *cls)
" FROM merchant_instances"
" WHERE merchant_id=$1)",
3),
-
+ /* for postgres_insert_transfer() */
+ GNUNET_PQ_make_prepare ("insert_transfer",
+ "INSERT INTO merchant_transfers"
+ "(exchange_url"
+ ",wtid"
+ ",credit_amount_val"
+ ",credit_amount_frac"
+ ",account_serial"
+ ",confirmed)"
+ "SELECT"
+ " $1, $2, $3, $4, account_serial, $6"
+ " FROM merchant_accounts"
+ " WHERE payto_uri=$5"
+ " AND merchant_serial="
+ " (SELECT merchant_serial"
+ " FROM merchant_instances"
+ " WHERE merchant_id=$7)",
+ 7),
+ /* for postgres_lookup_account() */
+ GNUNET_PQ_make_prepare ("lookup_account",
+ "SELECT"
+ " account_serial"
+ " FROM merchant_accounts"
+ " WHERE payto_uri=$2"
+ " AND merchant_serial="
+ " (SELECT merchant_serial"
+ " FROM merchant_instances"
+ " WHERE merchant_id=$1)",
+ 2),
+ /* for postgres_insert_transfer_details() */
+ GNUNET_PQ_make_prepare ("lookup_credit_serial",
+ "SELECT"
+ " credit_serial"
+ " FROM merchant_transfers"
+ " WHERE exchange_url=$1"
+ " AND wtid=$4"
+ " AND credit_account_val=$5"
+ " AND credit_account_frac=$6"
+ " AND account_serial="
+ " (SELECT account_serial"
+ " FROM merchant_accounts"
+ " WHERE payto_uri=$2"
+ " AND exchange_url=$1"
+ " AND merchant_serial="
+ " (SELECT merchant_serial"
+ " FROM merchant_instances"
+ " WHERE merchant_id=$3))",
+ 2),
+ /* for postgres_insert_transfer_details() */
+ GNUNET_PQ_make_prepare ("insert_transfer_signature",
+ "INSERT INTO merchant_transfer_signatures"
+ "(credit_serial"
+ ",signkey_serial"
+ ",execution_time"
+ ",exchange_sig) "
+ "SELECT $1, signkey_serial, $2, $3"
+ " FROM merchant_exchange_signing_keys"
+ " WHERE exchange_pub=$4"
+ " ORDER BY start_date DESC"
+ " LIMIT 1",
+ 4),
+ /* for postgres_insert_transfer_details() */
+ GNUNET_PQ_make_prepare ("insert_transfer_to_coin_mapping",
+ "INSERT INTO merchant_transfer_to_coin"
+ "(deposit_serial"
+ ",credit_serial"
+ ",offset_in_exchange_list"
+ ",exchange_deposit_value_val"
+ ",exchange_deposit_value_frac"
+ ",exchange_deposit_fee_val"
+ ",exchange_deposit_fee_frac) "
+ "SELECT deposit_serial, $1, $2, $3, $4, $5, $6"
+ " FROM merchant_deposits"
+ " JOIN merchant_contract_terms USING
(order_serial)"
+ " WHERE coin_pub=$7"
+ " AND h_contract_terms=$8",
+ 8),
/* OLD API: */
#if 0
- GNUNET_PQ_make_prepare ("insert_transfer",
- "INSERT INTO merchant_transfers"
- "(h_contract_terms"
- ",coin_pub"
- ",wtid) VALUES "
- "($1, $2, $3)",
- 3),
GNUNET_PQ_make_prepare ("insert_contract_terms",
"INSERT INTO merchant_contract_terms"
"(order_id"
@@ -5942,8 +6177,8 @@ libtaler_plugin_merchantdb_postgres_init (void *cls)
plugin->insert_refund_proof = &postgres_insert_refund_proof;
plugin->lookup_refund_proof = &postgres_lookup_refund_proof;
plugin->lookup_order_by_fulfillment = &postgres_lookup_order_by_fulfillment;
- /* WIP: */
plugin->insert_transfer = &postgres_insert_transfer;
+ plugin->lookup_account = &postgres_lookup_account;
plugin->insert_transfer_details = &postgres_insert_transfer_details;
plugin->lookup_wire_fee = &postgres_lookup_wire_fee;
diff --git a/src/include/taler_merchantdb_plugin.h
b/src/include/taler_merchantdb_plugin.h
index e0f7699..94fe618 100644
--- a/src/include/taler_merchantdb_plugin.h
+++ b/src/include/taler_merchantdb_plugin.h
@@ -1199,6 +1199,7 @@ struct TALER_MERCHANTDB_Plugin
* Insert information about a wire transfer the merchant has received.
*
* @param cls closure
+ * @param instance_id instance to lookup the order from
* @param exchange_url which exchange made the transfer
* @param wtid identifier of the wire transfer
* @param credit_amount how much did we receive
@@ -1210,6 +1211,7 @@ struct TALER_MERCHANTDB_Plugin
enum GNUNET_DB_QueryStatus
(*insert_transfer)(
void *cls,
+ const char *instance_id,
const char *exchange_url,
const struct TALER_WireTransferIdentifierRawP *wtid,
const struct TALER_Amount *credit_amount,
@@ -1217,10 +1219,27 @@ struct TALER_MERCHANTDB_Plugin
bool confirmed);
+ /**
+ * Lookup account serial by payto URI.
+ *
+ * @param cls closure
+ * @param instance_id instance to lookup the account from
+ * @param payto_uri what is the merchant's bank account to lookup
+ * @param[out] account_serial serial number of the account
+ * @return transaction status
+ */
+ enum GNUNET_DB_QueryStatus
+ (*lookup_account)(void *cls,
+ const char *instance_id,
+ const char *payto_uri,
+ uint64_t *account_serial);
+
+
/**
* Insert information about a wire transfer the merchant has received.
*
* @param cls closure
+ * @param instance_id instance to provide transfer details for
* @param exchange_url which exchange made the transfer
* @param payto_uri what is the merchant's bank account that received the
transfer
* @param wtid identifier of the wire transfer
@@ -1230,7 +1249,8 @@ struct TALER_MERCHANTDB_Plugin
enum GNUNET_DB_QueryStatus
(*insert_transfer_details)(
void *cls,
- const char *exchange_url, // FIXME: do we need the URL? We have
exchange_pub!
+ const char *instance_id,
+ const char *exchange_url,
const char *payto_uri,
const struct TALER_WireTransferIdentifierRawP *wtid,
const struct TALER_EXCHANGE_TransferData *td);
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.
- [taler-merchant] 76/277: adapt to exchangev8 protocol, (continued)
- [taler-merchant] 76/277: adapt to exchangev8 protocol, gnunet, 2020/07/05
- [taler-merchant] 73/277: DB API for /abort, gnunet, 2020/07/05
- [taler-merchant] 75/277: work on abort, gnunet, 2020/07/05
- [taler-merchant] 83/277: renaming, gnunet, 2020/07/05
- [taler-merchant] 78/277: work on refund, gnunet, 2020/07/05
- [taler-merchant] 84/277: dce, gnunet, 2020/07/05
- [taler-merchant] 82/277: implement abort client lib, gnunet, 2020/07/05
- [taler-merchant] 87/277: revise GET /private/orders API, gnunet, 2020/07/05
- [taler-merchant] 86/277: GET /orders/ID API design, gnunet, 2020/07/05
- [taler-merchant] 88/277: fix benchmark FTBFS, gnunet, 2020/07/05
- [taler-merchant] 95/277: db work for POST /transfers,
gnunet <=
- [taler-merchant] 96/277: fix FTBFS, gnunet, 2020/07/05
- [taler-merchant] 109/277: commentfix, gnunet, 2020/07/05
- [taler-merchant] 110/277: fix benchmark FTBFS, gnunet, 2020/07/05
- [taler-merchant] 116/277: fix test, gnunet, 2020/07/05
- [taler-merchant] 115/277: misc. fixes, gnunet, 2020/07/05
- [taler-merchant] 91/277: implement GET /orders/ID, gnunet, 2020/07/05
- [taler-merchant] 101/277: more SQL, gnunet, 2020/07/05
- [taler-merchant] 104/277: GET /transfers implementation, gnunet, 2020/07/05
- [taler-merchant] 102/277: towards idempotency in POST /private/transfers, gnunet, 2020/07/05
- [taler-merchant] 103/277: towards GET /transfers, gnunet, 2020/07/05