summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/taler-merchant-httpd_post-orders-ID-abort.c5
-rw-r--r--src/backend/taler-merchant-httpd_post-orders-ID-pay.c235
-rw-r--r--src/backend/taler-merchant-httpd_private-get-orders-ID.c15
-rw-r--r--src/backenddb/Makefile.am1
-rw-r--r--src/backenddb/merchant-0001.sql50
-rw-r--r--src/backenddb/pg_increase_refund.c15
-rw-r--r--src/backenddb/pg_insert_deposit.c69
-rw-r--r--src/backenddb/pg_insert_deposit.h33
-rw-r--r--src/backenddb/pg_insert_transfer_details.c60
-rw-r--r--src/backenddb/pg_lookup_deposits.c23
-rw-r--r--src/backenddb/pg_refund_coin.c14
-rw-r--r--src/backenddb/plugin_merchantdb_postgres.c167
-rw-r--r--src/backenddb/test_merchantdb.c124
-rw-r--r--src/include/taler_merchantdb_plugin.h132
-rwxr-xr-xsrc/testing/test_merchant_transfer_tracking.sh7
15 files changed, 502 insertions, 448 deletions
diff --git a/src/backend/taler-merchant-httpd_post-orders-ID-abort.c b/src/backend/taler-merchant-httpd_post-orders-ID-abort.c
index 09ac8acb..7b6bc7b5 100644
--- a/src/backend/taler-merchant-httpd_post-orders-ID-abort.c
+++ b/src/backend/taler-merchant-httpd_post-orders-ID-abort.c
@@ -619,7 +619,6 @@ find_next_exchange (struct AbortContext *ac)
* @param amount_with_fee amount the exchange will deposit for this coin
* @param deposit_fee fee the exchange will charge for this coin
* @param refund_fee fee the exchange will charge for refunding this coin
- * @param wire_fee wire fee the exchange of this coin charges
*/
static void
refund_coins (void *cls,
@@ -627,8 +626,7 @@ refund_coins (void *cls,
const struct TALER_CoinSpendPublicKeyP *coin_pub,
const struct TALER_Amount *amount_with_fee,
const struct TALER_Amount *deposit_fee,
- const struct TALER_Amount *refund_fee,
- const struct TALER_Amount *wire_fee)
+ const struct TALER_Amount *refund_fee)
{
struct AbortContext *ac = cls;
struct GNUNET_TIME_Timestamp now;
@@ -636,7 +634,6 @@ refund_coins (void *cls,
(void) amount_with_fee;
(void) deposit_fee;
(void) refund_fee;
- (void) wire_fee;
now = GNUNET_TIME_timestamp_get ();
for (unsigned int i = 0; i<ac->coins_cnt; i++)
{
diff --git a/src/backend/taler-merchant-httpd_post-orders-ID-pay.c b/src/backend/taler-merchant-httpd_post-orders-ID-pay.c
index fd17f029..c99a6c64 100644
--- a/src/backend/taler-merchant-httpd_post-orders-ID-pay.c
+++ b/src/backend/taler-merchant-httpd_post-orders-ID-pay.c
@@ -90,11 +90,6 @@ struct DepositConfirmation
struct TALER_Amount refund_fee;
/**
- * Wire fee charged by the exchange of this coin.
- */
- struct TALER_Amount wire_fee;
-
- /**
* If a minimum age was required (i. e. pc->minimum_age is large enough),
* this is the signature of the minimum age (as a single uint8_t), using the
* private key to the corresponding age group. Might be all zeroes for no
@@ -902,6 +897,107 @@ check_kyc (struct PayContext *pc,
/**
+ * Do database transaction for a completed batch deposit.
+ *
+ * @param eg group that completed
+ * @param dr response from the server
+ * @return transaction status
+ */
+static enum GNUNET_DB_QueryStatus
+batch_deposit_transaction (const struct ExchangeGroup *eg,
+ const struct TALER_EXCHANGE_BatchDepositResult *dr)
+{
+ const struct PayContext *pc = eg->pc;
+ enum GNUNET_DB_QueryStatus qs;
+ struct TALER_Amount total_without_fees = { 0 };
+ uint64_t b_dep_serial;
+ uint32_t off = 0;
+ bool found = false;
+
+ for (unsigned int i = 0; i<pc->coins_cnt; i++)
+ {
+ struct DepositConfirmation *dc = &pc->dc[i];
+ struct TALER_Amount amount_without_fees;
+
+ /* might want to group deposits by batch more explicitly ... */
+ if (0 != strcmp (eg->exchange_url,
+ dc->exchange_url))
+ continue;
+ if (dc->found_in_db)
+ continue;
+ GNUNET_assert (0 <=
+ TALER_amount_subtract (&amount_without_fees,
+ &dc->cdd.amount,
+ &dc->deposit_fee));
+ if (! found)
+ {
+ found = true;
+ total_without_fees = amount_without_fees;
+ }
+ else
+ {
+ GNUNET_assert (
+ 0 <=
+ TALER_amount_add (&total_without_fees,
+ &total_without_fees,
+ &amount_without_fees));
+ }
+ }
+ qs = TMH_db->insert_deposit_confirmation (
+ TMH_db->cls,
+ pc->hc->instance->settings.id,
+ dr->details.ok.deposit_timestamp,
+ &pc->h_contract_terms,
+ eg->exchange_url,
+ &total_without_fees,
+ &eg->wire_fee,
+ &pc->wm->h_wire,
+ dr->details.ok.exchange_sig,
+ dr->details.ok.exchange_pub,
+ &b_dep_serial);
+ if (qs <= 0)
+ return qs; /* Entire batch already known or failure, we're done */
+
+ if (! found)
+ {
+ /* All coins already done, but the batch was not? Invariant violation! */
+ GNUNET_break (0);
+ return GNUNET_DB_STATUS_HARD_ERROR;
+ }
+
+ for (unsigned int i = 0; i<pc->coins_cnt; i++)
+ {
+ struct DepositConfirmation *dc = &pc->dc[i];
+
+ /* might want to group deposits by batch more explicitly ... */
+ if (0 != strcmp (eg->exchange_url,
+ dc->exchange_url))
+ continue;
+ if (dc->found_in_db)
+ continue;
+ /* NOTE: We might want to check if the order was fully paid concurrently
+ by some other wallet here, and if so, issue an auto-refund. Right now,
+ it is possible to over-pay if two wallets literally make a concurrent
+ payment, as the earlier check for 'paid' is not in the same transaction
+ scope as this 'insert' operation. */
+ qs = TMH_db->insert_deposit (
+ TMH_db->cls,
+ off++, /* might want to group deposits by batch more explicitly ... */
+ b_dep_serial,
+ &dc->cdd.coin_pub,
+ &dc->cdd.coin_sig,
+ &dc->cdd.amount,
+ &dc->deposit_fee,
+ &dc->refund_fee);
+ if (qs < 0)
+ return qs;
+ GNUNET_break (qs > 0);
+ }
+ return qs;
+}
+
+
+/**
* Handle case where the batch deposit completed
* with a status of #MHD_HTTP_OK.
*
@@ -924,8 +1020,6 @@ handle_batch_deposit_ok (struct ExchangeGroup *eg,
pc->hc->instance->settings.id);
for (unsigned int r = 0; r<MAX_RETRIES; r++)
{
- unsigned int j = 0;
-
TMH_db->preflight (TMH_db->cls);
if (GNUNET_OK !=
TMH_db->start (TMH_db->cls,
@@ -940,50 +1034,19 @@ handle_batch_deposit_ok (struct ExchangeGroup *eg,
TMH_pack_exchange_reply (&dr->hr)));
return;
}
- for (unsigned int i = 0; i<pc->coins_cnt; i++)
+ qs = batch_deposit_transaction (eg,
+ dr);
+ if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
{
- struct DepositConfirmation *dc = &pc->dc[i];
-
- if (0 != strcmp (eg->exchange_url,
- pc->dc[i].exchange_url))
- continue;
- if (dc->found_in_db)
- continue;
- /* NOTE: We might want to check if the order was fully paid concurrently
- by some other wallet here, and if so, issue an auto-refund. Right now,
- it is possible to over-pay if two wallets literally make a concurrent
- payment, as the earlier check for 'paid' is not in the same transaction
- scope as this 'insert' operation. */
- GNUNET_assert (j < dr->details.ok.num_signatures);
- qs = TMH_db->insert_deposit (
- TMH_db->cls,
- pc->hc->instance->settings.id,
- dr->details.ok.deposit_timestamp,
- &pc->h_contract_terms,
- &dc->cdd.coin_pub,
- dc->exchange_url,
- &dc->cdd.amount,
- &dc->deposit_fee,
- &dc->refund_fee,
- &dc->wire_fee,
- &pc->wm->h_wire,
- &dr->details.ok.exchange_sigs[j++],
- dr->details.ok.exchange_pub);
- if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
- {
- TMH_db->rollback (TMH_db->cls);
- break;
- }
- if (0 > qs)
- {
- /* Always report on hard error as well to enable diagnostics */
- GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs);
- /* Forward error including 'proof' for the body */
- resume_pay_with_error (pc,
- TALER_EC_GENERIC_DB_STORE_FAILED,
- "insert_deposit");
- return;
- }
+ TMH_db->rollback (TMH_db->cls);
+ continue;
+ }
+ if (GNUNET_DB_STATUS_HARD_ERROR == qs)
+ {
+ GNUNET_break (0);
+ resume_pay_with_error (pc,
+ TALER_EC_GENERIC_DB_COMMIT_FAILED,
+ "batch_deposit_transaction");
}
qs = TMH_db->commit (TMH_db->cls);
if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
@@ -999,7 +1062,7 @@ handle_batch_deposit_ok (struct ExchangeGroup *eg,
"insert_deposit");
}
break; /* DB transaction succeeded */
- } /* FOR DB retries */
+ }
if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
{
resume_pay_with_error (pc,
@@ -1387,7 +1450,6 @@ AGE_FAIL:
eg->exchange_url))
continue;
cdds[i] = dc->cdd;
- dc->wire_fee = eg->wire_fee;
}
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Initiating batch deposit with %u coins\n",
@@ -1509,7 +1571,6 @@ start_batch_deposits (struct PayContext *pc)
* @param amount_with_fee amount the exchange will deposit for this coin
* @param deposit_fee fee the exchange will charge for this coin
* @param refund_fee fee the exchange will charge for refunding this coin
- * @param wire_fee wire fee the exchange of this coin charges
*/
static void
check_coin_paid (void *cls,
@@ -1517,8 +1578,7 @@ check_coin_paid (void *cls,
const struct TALER_CoinSpendPublicKeyP *coin_pub,
const struct TALER_Amount *amount_with_fee,
const struct TALER_Amount *deposit_fee,
- const struct TALER_Amount *refund_fee,
- const struct TALER_Amount *wire_fee)
+ const struct TALER_Amount *refund_fee)
{
struct PayContext *pc = cls;
@@ -1551,7 +1611,6 @@ check_coin_paid (void *cls,
deposit_fee));
dc->deposit_fee = *deposit_fee;
dc->refund_fee = *refund_fee;
- dc->wire_fee = *wire_fee;
dc->cdd.amount = *amount_with_fee;
dc->found_in_db = true;
pc->pending--;
@@ -1623,8 +1682,33 @@ check_payment_sufficient (struct PayContext *pc)
(0 == pc->amount.fraction));
}
+ total_wire_fee = pc->egs[0]->wire_fee;
+ for (unsigned int i = 1; i < pc->num_exchanges; i++)
+ {
+ if (GNUNET_OK !=
+ TALER_amount_cmp_currency (&total_wire_fee,
+ &pc->egs[i]->wire_fee))
+ {
+ GNUNET_break_op (0);
+ resume_pay_with_error (pc,
+ TALER_EC_GENERIC_CURRENCY_MISMATCH,
+ total_wire_fee.currency);
+ return false;
+ }
+ if (0 >
+ TALER_amount_add (&total_wire_fee,
+ &total_wire_fee,
+ &pc->egs[i]->wire_fee))
+ {
+ GNUNET_break (0);
+ resume_pay_with_error (pc,
+ TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_EXCHANGE_WIRE_FEE_ADDITION_FAILED,
+ "could not add exchange wire fee to total");
+ return false;
+ }
+ }
+
acc_fee = pc->dc[0].deposit_fee;
- total_wire_fee = pc->dc[0].wire_fee;
acc_amount = pc->dc[0].cdd.amount;
/**
@@ -1663,43 +1747,6 @@ check_payment_sufficient (struct PayContext *pc)
return false;
}
- /* If exchange differs, add wire fee */
- {
- bool new_exchange = true;
-
- for (unsigned int j = 0; j<i; j++)
- if (0 == strcasecmp (dc->exchange_url,
- pc->dc[j].exchange_url))
- {
- new_exchange = false;
- break;
- }
-
- if (! new_exchange)
- continue;
-
- if (GNUNET_OK !=
- TALER_amount_cmp_currency (&total_wire_fee,
- &dc->wire_fee))
- {
- GNUNET_break_op (0);
- resume_pay_with_error (pc,
- TALER_EC_GENERIC_CURRENCY_MISMATCH,
- total_wire_fee.currency);
- return false;
- }
- if (0 >
- TALER_amount_add (&total_wire_fee,
- &total_wire_fee,
- &dc->wire_fee))
- {
- GNUNET_break (0);
- resume_pay_with_error (pc,
- TALER_EC_MERCHANT_POST_ORDERS_ID_PAY_EXCHANGE_WIRE_FEE_ADDITION_FAILED,
- "could not add exchange wire fee to total");
- return false;
- }
- }
} /* deposit loop */
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
diff --git a/src/backend/taler-merchant-httpd_private-get-orders-ID.c b/src/backend/taler-merchant-httpd_private-get-orders-ID.c
index f732dc84..20ed5fa7 100644
--- a/src/backend/taler-merchant-httpd_private-get-orders-ID.c
+++ b/src/backend/taler-merchant-httpd_private-get-orders-ID.c
@@ -804,13 +804,14 @@ process_refunds_cb (void *cls,
* @a wtid over the total amount happened?
*/
static void
-process_transfer_details (void *cls,
- const struct TALER_WireTransferIdentifierRawP *wtid,
- const char *exchange_url,
- struct GNUNET_TIME_Timestamp execution_time,
- const struct TALER_Amount *deposit_value,
- const struct TALER_Amount *deposit_fee,
- bool transfer_confirmed)
+process_transfer_details (
+ void *cls,
+ const struct TALER_WireTransferIdentifierRawP *wtid,
+ const char *exchange_url,
+ struct GNUNET_TIME_Timestamp execution_time,
+ const struct TALER_Amount *deposit_value,
+ const struct TALER_Amount *deposit_fee,
+ bool transfer_confirmed)
{
struct GetOrderRequestContext *gorc = cls;
json_t *wire_details = gorc->wire_details;
diff --git a/src/backenddb/Makefile.am b/src/backenddb/Makefile.am
index 64b9883e..22041a1d 100644
--- a/src/backenddb/Makefile.am
+++ b/src/backenddb/Makefile.am
@@ -125,6 +125,7 @@ libtaler_plugin_merchantdb_postgres_la_SOURCES = \
pg_lookup_deposits.h pg_lookup_deposits.c \
pg_insert_exchange_signkey.h pg_insert_exchange_signkey.c \
pg_insert_deposit.h pg_insert_deposit.c \
+ pg_insert_deposit_confirmation.h pg_insert_deposit_confirmation.c \
pg_lookup_refunds.h pg_lookup_refunds.c \
pg_mark_contract_paid.h pg_mark_contract_paid.c \
pg_refund_coin.h pg_refund_coin.c \
diff --git a/src/backenddb/merchant-0001.sql b/src/backenddb/merchant-0001.sql
index 4e2b0639..d6b25d8d 100644
--- a/src/backenddb/merchant-0001.sql
+++ b/src/backenddb/merchant-0001.sql
@@ -383,35 +383,61 @@ CREATE INDEX IF NOT EXISTS merchant_contract_terms_by_merchant_session_and_fulfi
---------------- Payment and refunds ---------------------------
-CREATE TABLE IF NOT EXISTS merchant_deposits
- (deposit_serial BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY
+CREATE TABLE IF NOT EXISTS merchant_deposit_confirmations
+ (deposit_confirmation_serial BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY
,order_serial BIGINT
REFERENCES merchant_contract_terms (order_serial) ON DELETE CASCADE
,deposit_timestamp INT8 NOT NULL
- ,coin_pub BYTEA NOT NULL CHECK (LENGTH(coin_pub)=32)
,exchange_url TEXT NOT NULL
- ,amount_with_fee taler_amount_currency NOT NULL
- ,deposit_fee taler_amount_currency NOT NULL
- ,refund_fee taler_amount_currency NOT NULL
+ ,total_without_fee taler_amount_currency NOT NULL
,wire_fee taler_amount_currency NOT NULL
,signkey_serial BIGINT NOT NULL
REFERENCES merchant_exchange_signing_keys (signkey_serial) ON DELETE CASCADE
,exchange_sig BYTEA NOT NULL CHECK (LENGTH(exchange_sig)=64)
,account_serial BIGINT NOT NULL
REFERENCES merchant_accounts (account_serial) ON DELETE CASCADE
- ,UNIQUE (order_serial, coin_pub)
+ ,UNIQUE (order_serial, exchange_sig)
);
-COMMENT ON TABLE merchant_deposits
+COMMENT ON TABLE merchant_deposit_confirmations
IS 'Table with the deposit confirmations for each coin we deposited at the exchange';
-COMMENT ON COLUMN merchant_deposits.signkey_serial
+COMMENT ON COLUMN merchant_deposit_confirmations.signkey_serial
IS 'Online signing key of the exchange on the deposit confirmation';
-COMMENT ON COLUMN merchant_deposits.deposit_timestamp
+COMMENT ON COLUMN merchant_deposit_confirmations.deposit_timestamp
IS 'Time when the exchange generated the deposit confirmation';
-COMMENT ON COLUMN merchant_deposits.exchange_sig
+COMMENT ON COLUMN merchant_deposit_confirmations.exchange_sig
IS 'Signature of the exchange over the deposit confirmation';
-COMMENT ON COLUMN merchant_deposits.wire_fee
+COMMENT ON COLUMN merchant_deposit_confirmations.wire_fee
IS 'We MAY want to see if we should try to get this via merchant_exchange_wire_fees (not sure, may be too complicated with the date range, etc.)';
+
+CREATE TABLE IF NOT EXISTS merchant_deposits
+ (deposit_serial BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY
+ ,coin_offset INT4 NOT NULL
+ ,deposit_confirmation_serial BIGINT NOT NULL
+ REFERENCES merchant_deposit_confirmations (deposit_confirmation_serial) ON DELETE CASCADE
+ ,coin_pub BYTEA NOT NULL CHECK (LENGTH(coin_pub)=32)
+ ,coin_sig BYTEA NOT NULL CHECK (LENGTH(coin_sig)=64)
+ ,amount_with_fee taler_amount_currency NOT NULL
+ ,deposit_fee taler_amount_currency NOT NULL
+ ,refund_fee taler_amount_currency NOT NULL
+ ,UNIQUE (deposit_confirmation_serial, coin_pub)
+ );
+COMMENT ON TABLE merchant_deposits
+ IS 'Table with the deposit details for each coin we deposited at the exchange';
+COMMENT ON COLUMN merchant_deposits.coin_offset
+ IS 'Offset of this coin in the batch';
+COMMENT ON COLUMN merchant_deposits.deposit_confirmation_serial
+ IS 'Reference to the deposit confirmation of the exchange';
+COMMENT ON COLUMN merchant_deposits.coin_pub
+ IS 'Public key of the coin that was deposited';
+COMMENT ON COLUMN merchant_deposits.amount_with_fee
+ IS 'Total amount (incl. fee) of the coin that was deposited';
+COMMENT ON COLUMN merchant_deposits.deposit_fee
+ IS 'Deposit fee (for this coin) that was paid';
+COMMENT ON COLUMN merchant_deposits.refund_fee
+ IS 'How high would the refund fee be (for this coin)';
+
+
CREATE TABLE IF NOT EXISTS merchant_refunds
(refund_serial BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY
,order_serial BIGINT NOT NULL
diff --git a/src/backenddb/pg_increase_refund.c b/src/backenddb/pg_increase_refund.c
index 5fd548d7..d274b1e9 100644
--- a/src/backenddb/pg_increase_refund.c
+++ b/src/backenddb/pg_increase_refund.c
@@ -364,7 +364,7 @@ process_deposits_for_refund_cb (
GNUNET_PQ_query_param_auto_from_type (&rcd[i].coin_pub),
GNUNET_PQ_query_param_string (ctx->reason),
TALER_PQ_query_param_amount_with_currency (pg->conn,
- increment),
+ increment),
GNUNET_PQ_query_param_end
};
@@ -451,20 +451,21 @@ TMH_PG_increase_refund (void *cls,
PREPARE (pg,
"find_deposits_for_refund",
"SELECT"
- " coin_pub"
- ",order_serial"
- ",amount_with_fee"
- " FROM merchant_deposits"
+ " dep.coin_pub"
+ ",dco.order_serial"
+ ",dep.amount_with_fee"
+ " FROM merchant_deposits dep"
+ " JOIN merchant_deposit_confirmations dco"
+ " USING (deposit_confirmation_serial)"
" WHERE order_serial="
" (SELECT order_serial"
" FROM merchant_contract_terms"
" WHERE order_id=$2"
- " AND paid=TRUE"
+ " AND paid"
" AND merchant_serial="
" (SELECT merchant_serial"
" FROM merchant_instances"
" WHERE merchant_id=$1))");
-
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Asked to refund %s on order %s\n",
TALER_amount2s (refund),
diff --git a/src/backenddb/pg_insert_deposit.c b/src/backenddb/pg_insert_deposit.c
index f99c6f44..8e77e24a 100644
--- a/src/backenddb/pg_insert_deposit.c
+++ b/src/backenddb/pg_insert_deposit.c
@@ -30,85 +30,46 @@
enum GNUNET_DB_QueryStatus
TMH_PG_insert_deposit (
void *cls,
- const char *instance_id,
- struct GNUNET_TIME_Timestamp deposit_timestamp,
- const struct TALER_PrivateContractHashP *h_contract_terms,
+ uint32_t offset,
+ uint64_t deposit_confirmation_serial,
const struct TALER_CoinSpendPublicKeyP *coin_pub,
- const char *exchange_url,
+ const struct TALER_CoinSpendSignatureP *coin_sig,
const struct TALER_Amount *amount_with_fee,
const struct TALER_Amount *deposit_fee,
- const struct TALER_Amount *refund_fee,
- const struct TALER_Amount *wire_fee,
- const struct TALER_MerchantWireHashP *h_wire,
- const struct TALER_ExchangeSignatureP *exchange_sig,
- const struct TALER_ExchangePublicKeyP *exchange_pub)
+ const struct TALER_Amount *refund_fee)
{
struct PostgresClosure *pg = cls;
struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_string (instance_id),
- GNUNET_PQ_query_param_auto_from_type (h_contract_terms),
- GNUNET_PQ_query_param_timestamp (&deposit_timestamp), /* $3 */
+ GNUNET_PQ_query_param_uint64 (&deposit_confirmation_serial),
+ GNUNET_PQ_query_param_uint32 (&offset),
GNUNET_PQ_query_param_auto_from_type (coin_pub),
- GNUNET_PQ_query_param_string (exchange_url),
+ GNUNET_PQ_query_param_auto_from_type (coin_sig),
TALER_PQ_query_param_amount_with_currency (pg->conn,
- amount_with_fee), /* $6 */
+ amount_with_fee),
TALER_PQ_query_param_amount_with_currency (pg->conn,
- deposit_fee), /* $7 */
+ deposit_fee),
TALER_PQ_query_param_amount_with_currency (pg->conn,
- refund_fee), /* $8 */
- TALER_PQ_query_param_amount_with_currency (pg->conn,
- wire_fee), /* $9 */
- GNUNET_PQ_query_param_auto_from_type (h_wire), /* $10 */
- GNUNET_PQ_query_param_auto_from_type (exchange_sig), /* $11 */
- GNUNET_PQ_query_param_auto_from_type (exchange_pub), /* $12 */
+ refund_fee),
GNUNET_PQ_query_param_end
};
/* no preflight check here, run in transaction by caller! */
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Storing deposit for instance `%s' h_contract_terms `%s', coin_pub: `%s', amount_with_fee: %s\n",
- instance_id,
- GNUNET_h2s (&h_contract_terms->hash),
+ "Storing deposit for coin_pub: `%s', amount_with_fee: %s\n",
TALER_B2S (coin_pub),
TALER_amount2s (amount_with_fee));
check_connection (pg);
PREPARE (pg,
"insert_deposit",
- "WITH md AS"
- " (SELECT account_serial, merchant_serial"
- " FROM merchant_accounts"
- " WHERE h_wire=$10"
- " AND merchant_serial="
- " (SELECT merchant_serial"
- " FROM merchant_instances"
- " WHERE merchant_id=$1))"
- ", ed AS"
- " (SELECT signkey_serial"
- " FROM merchant_exchange_signing_keys"
- " WHERE exchange_pub=$12"
- " ORDER BY start_date DESC"
- " LIMIT 1)"
"INSERT INTO merchant_deposits"
- "(order_serial"
- ",deposit_timestamp"
+ "(deposit_confirmation_serial"
+ ",coin_offset"
",coin_pub"
- ",exchange_url"
+ ",coin_sig"
",amount_with_fee"
",deposit_fee"
",refund_fee"
- ",wire_fee"
- ",exchange_sig"
- ",signkey_serial"
- ",account_serial)"
- " SELECT "
- " order_serial"
- " ,$3, $4, $5, $6, $7, $8, $9, $11"
- " ,ed.signkey_serial"
- " ,md.account_serial"
- " FROM merchant_contract_terms"
- " JOIN md USING (merchant_serial)"
- " FULL OUTER JOIN ed ON TRUE"
- " WHERE h_contract_terms=$2");
+ ") VALUES ($1, $2, $3, $4, $5, $6, $7)");
return GNUNET_PQ_eval_prepared_non_select (pg->conn,
"insert_deposit",
params);
diff --git a/src/backenddb/pg_insert_deposit.h b/src/backenddb/pg_insert_deposit.h
index 999d9367..94af2bf4 100644
--- a/src/backenddb/pg_insert_deposit.h
+++ b/src/backenddb/pg_insert_deposit.h
@@ -29,34 +29,25 @@
* Insert payment confirmation from the exchange into the database.
*
* @param cls closure
- * @param instance_id instance to lookup deposits for
- * @param deposit_timestamp time when the exchange generated the deposit confirmation
- * @param h_contract_terms proposal data's hashcode
+ * @param offset offset of the coin in the batch
+ * @param deposit_confirmation_serial which deposit confirmation is this coin part of
* @param coin_pub public key of the coin
- * @param exchange_url URL of the exchange that issued @a coin_pub
+ * @param coin_sig signature of the coin
* @param amount_with_fee amount the exchange will deposit for this coin
* @param deposit_fee fee the exchange will charge for this coin
* @param wire_fee wire fee the exchange charges
* @param refund_fee fee the exchange charges to refund this coin
- * @param h_wire hash of the wire details of the target account of the merchant
- * @param exchange_sig signature from exchange that coin was accepted
- * @param exchange_pub signgin key that was used for @a exchange_sig
* @return transaction status
*/
enum GNUNET_DB_QueryStatus
-TMH_PG_insert_deposit (void *cls,
- const char *instance_id,
- struct GNUNET_TIME_Timestamp deposit_timestamp,
- const struct
- TALER_PrivateContractHashP *h_contract_terms,
- const struct TALER_CoinSpendPublicKeyP *coin_pub,
- const char *exchange_url,
- const struct TALER_Amount *amount_with_fee,
- const struct TALER_Amount *deposit_fee,
- const struct TALER_Amount *refund_fee,
- const struct TALER_Amount *wire_fee,
- const struct TALER_MerchantWireHashP *h_wire,
- const struct TALER_ExchangeSignatureP *exchange_sig,
- const struct TALER_ExchangePublicKeyP *exchange_pub);
+TMH_PG_insert_deposit (
+ void *cls,
+ uint32_t offset,
+ uint64_t deposit_confirmation_serial,
+ const struct TALER_CoinSpendPublicKeyP *coin_pub,
+ const struct TALER_CoinSpendSignatureP *coin_sig,
+ const struct TALER_Amount *amount_with_fee,
+ const struct TALER_Amount *deposit_fee,
+ const struct TALER_Amount *refund_fee);
#endif
diff --git a/src/backenddb/pg_insert_transfer_details.c b/src/backenddb/pg_insert_transfer_details.c
index a4f69989..66859649 100644
--- a/src/backenddb/pg_insert_transfer_details.c
+++ b/src/backenddb/pg_insert_transfer_details.c
@@ -87,35 +87,47 @@ TMH_PG_insert_transfer_details (
",offset_in_exchange_list"
",exchange_deposit_value"
",exchange_deposit_fee) "
- "SELECT deposit_serial, $1, $2, $3, $4"
- " FROM merchant_deposits"
- " JOIN merchant_contract_terms USING (order_serial)"
- " WHERE coin_pub=$5"
- " AND h_contract_terms=$6"
- " AND merchant_serial="
+ "SELECT dep.deposit_serial, $1, $2, $3, $4"
+ " FROM merchant_deposits dep"
+ " JOIN merchant_deposit_confirmations dcon"
+ " USING (deposit_confirmation_serial)"
+ " JOIN merchant_contract_terms cterm"
+ " USING (order_serial)"
+ " WHERE dep.coin_pub=$5"
+ " AND cterm.h_contract_terms=$6"
+ " AND cterm.merchant_serial="
" (SELECT merchant_serial"
" FROM merchant_instances"
" WHERE merchant_id=$7)");
PREPARE (pg,
"update_wired_by_coin_pub",
- "WITH os AS" /* select orders affected by the coin */
- "(SELECT order_serial"
- " FROM merchant_deposits"
- " WHERE coin_pub=$1)"
+ "WITH affected_orders AS" /* select orders affected by the coin */
+ "(SELECT mcon.order_serial"
+ " FROM merchant_deposits dep"
+ /* Next 2 joins ensure transfers exist in the first place */
+ " JOIN merchant_deposit_to_transfer"
+ " USING (deposit_serial)"
+ " JOIN merchant_transfers mtrans"
+ " USING (credit_serial)"
+ " JOIN merchant_deposit_confirmations mcon"
+ " USING (deposit_confirmation_serial)"
+ " WHERE dep.coin_pub=$1)"
"UPDATE merchant_contract_terms "
" SET wired=TRUE "
" WHERE order_serial IN "
- " (SELECT order_serial FROM merchant_deposits" /* only orders for which NO un-wired coin exists*/
+ " (SELECT order_serial"
+ " FROM merchant_deposit_confirmations dcon"
+ " JOIN affected_orders"
+ " USING (order_serial)"
" WHERE NOT EXISTS "
- " (SELECT order_serial FROM merchant_deposits" /* orders for which ANY un-wired coin exists */
- " JOIN os USING (order_serial)" /* filter early */
- " WHERE deposit_serial NOT IN"
- " (SELECT deposit_serial " /* all coins associated with order that WERE wired */
- " FROM merchant_deposits "
- " JOIN os USING (order_serial)" /* filter early */
- " JOIN merchant_deposit_to_transfer USING (deposit_serial)"
- " JOIN merchant_transfers USING (credit_serial)"
- " WHERE confirmed=TRUE)))");
+ " (SELECT 1"
+ " FROM merchant_deposits dep"
+ " JOIN merchant_deposit_to_transfer"
+ " USING (deposit_serial)"
+ " JOIN merchant_transfers mtrans"
+ " USING (credit_serial)"
+ " WHERE dep.deposit_confirmation_serial = dcon.deposit_confirmation_serial"
+ " AND NOT mtrans.confirmed))");
RETRY:
if (MAX_RETRIES < ++retries)
@@ -175,9 +187,9 @@ RETRY:
struct GNUNET_PQ_QueryParam params[] = {
GNUNET_PQ_query_param_uint64 (&credit_serial),
TALER_PQ_query_param_amount_with_currency (pg->conn,
- &td->total_amount),
+ &td->total_amount),
TALER_PQ_query_param_amount_with_currency (pg->conn,
- &td->wire_fee),
+ &td->wire_fee),
GNUNET_PQ_query_param_timestamp (&td->execution_time),
GNUNET_PQ_query_param_auto_from_type (&td->exchange_sig),
GNUNET_PQ_query_param_auto_from_type (&td->exchange_pub),
@@ -219,9 +231,9 @@ RETRY:
GNUNET_PQ_query_param_uint64 (&credit_serial),
GNUNET_PQ_query_param_uint64 (&i64),
TALER_PQ_query_param_amount_with_currency (pg->conn,
- &d->coin_value),
+ &d->coin_value),
TALER_PQ_query_param_amount_with_currency (pg->conn,
- &d->coin_fee), /* deposit fee */
+ &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_string (instance_id),
diff --git a/src/backenddb/pg_lookup_deposits.c b/src/backenddb/pg_lookup_deposits.c
index 242d7bbb..2440f62c 100644
--- a/src/backenddb/pg_lookup_deposits.c
+++ b/src/backenddb/pg_lookup_deposits.c
@@ -73,7 +73,6 @@ lookup_deposits_cb (void *cls,
struct TALER_Amount amount_with_fee;
struct TALER_Amount deposit_fee;
struct TALER_Amount refund_fee;
- struct TALER_Amount wire_fee;
char *exchange_url;
struct GNUNET_PQ_ResultSpec rs[] = {
GNUNET_PQ_result_spec_string ("exchange_url",
@@ -86,8 +85,6 @@ lookup_deposits_cb (void *cls,
&deposit_fee),
TALER_PQ_result_spec_amount_with_currency ("refund_fee",
&refund_fee),
- TALER_PQ_result_spec_amount_with_currency ("wire_fee",
- &wire_fee),
GNUNET_PQ_result_spec_end
};
@@ -105,8 +102,7 @@ lookup_deposits_cb (void *cls,
&coin_pub,
&amount_with_fee,
&deposit_fee,
- &refund_fee,
- &wire_fee);
+ &refund_fee);
GNUNET_PQ_cleanup_result (rs);
}
ldc->qs = num_results;
@@ -142,14 +138,15 @@ TMH_PG_lookup_deposits (
PREPARE (pg,
"lookup_deposits",
"SELECT"
- " exchange_url"
- ",coin_pub"
- ",amount_with_fee"
- ",deposit_fee"
- ",refund_fee"
- ",wire_fee"
- " FROM merchant_deposits"
- " WHERE order_serial="
+ " dcom.exchange_url"
+ ",dep.coin_pub"
+ ",dep.amount_with_fee"
+ ",dep.deposit_fee"
+ ",dep.refund_fee"
+ " FROM merchant_deposits dep"
+ " JOIN merchant_deposit_confirmations dcom"
+ " USING (deposit_confirmation_serial)"
+ " WHERE dcom.order_serial="
" (SELECT order_serial"
" FROM merchant_contract_terms"
" WHERE h_contract_terms=$2"
diff --git a/src/backenddb/pg_refund_coin.c b/src/backenddb/pg_refund_coin.c
index afbcebcc..1bde2974 100644
--- a/src/backenddb/pg_refund_coin.c
+++ b/src/backenddb/pg_refund_coin.c
@@ -53,15 +53,17 @@ TMH_PG_refund_coin (void *cls,
",refund_amount"
") "
"SELECT "
- " order_serial"
+ " dcon.order_serial"
",0" /* rtransaction_id always 0 for /abort */
",$3"
- ",coin_pub"
+ ",dep.coin_pub"
",$5"
- ",amount_with_fee"
- " FROM merchant_deposits"
- " WHERE coin_pub=$4"
- " AND order_serial="
+ ",dep.amount_with_fee"
+ " FROM merchant_deposits dep"
+ " JOIN merchant_deposit_confirmations dcon"
+ " USING (deposit_confirmation_serial)"
+ " WHERE dep.coin_pub=$4"
+ " AND dcon.order_serial="
" (SELECT order_serial"
" FROM merchant_contract_terms"
" WHERE h_contract_terms=$2"
diff --git a/src/backenddb/plugin_merchantdb_postgres.c b/src/backenddb/plugin_merchantdb_postgres.c
index 3682e5c1..30def849 100644
--- a/src/backenddb/plugin_merchantdb_postgres.c
+++ b/src/backenddb/plugin_merchantdb_postgres.c
@@ -89,6 +89,7 @@
#include "pg_lookup_deposits.h"
#include "pg_insert_exchange_signkey.h"
#include "pg_insert_deposit.h"
+#include "pg_insert_deposit_confirmation.h"
#include "pg_lookup_refunds.h"
#include "pg_mark_contract_paid.h"
#include "pg_select_account_by_uri.h"
@@ -3060,52 +3061,65 @@ postgres_connect (void *cls)
/* for postgres_lookup_deposits_by_order() */
GNUNET_PQ_make_prepare ("lookup_deposits_by_order",
"SELECT"
- " deposit_serial"
- ",exchange_url"
- ",h_wire"
- ",amount_with_fee"
- ",deposit_fee"
- ",coin_pub"
- " FROM merchant_deposits"
- " JOIN merchant_accounts USING (account_serial)"
- " WHERE order_serial=$1"),
+ " dep.deposit_serial"
+ ",mcon.exchange_url"
+ ",acc.h_wire"
+ ",dep.amount_with_fee"
+ ",dep.deposit_fee"
+ ",dep.coin_pub"
+ " FROM merchant_deposits dep"
+ " JOIN merchant_deposit_confirmations mcon"
+ " USING(deposit_confirmation_serial)"
+ " JOIN merchant_accounts acc"
+ " USING (account_serial)"
+ " WHERE mcon.order_serial=$1"),
/* for postgres_lookup_transfer_details_by_order() */
GNUNET_PQ_make_prepare ("lookup_transfer_details_by_order",
"SELECT"
" md.deposit_serial"
- ",md.exchange_url"
+ ",mcon.exchange_url"
",mt.wtid"
- ",exchange_deposit_value"
- ",exchange_deposit_fee"
- ",deposit_timestamp"
+ ",mtc.exchange_deposit_value"
+ ",mtc.exchange_deposit_fee"
+ ",mcon.deposit_timestamp"
",mt.confirmed AS transfer_confirmed"
- " FROM merchant_transfer_to_coin"
- " JOIN merchant_deposits AS md USING (deposit_serial)"
- " JOIN merchant_transfers AS mt USING (credit_serial)"
- " WHERE deposit_serial IN"
- " (SELECT deposit_serial"
- " FROM merchant_deposits"
- " WHERE order_serial=$1)"),
+ " FROM merchant_transfer_to_coin mtc"
+ " JOIN merchant_deposits md"
+ " USING (deposit_serial)"
+ " JOIN merchant_deposit_confirmations mcon"
+ " USING (deposit_confirmation_serial)"
+ " JOIN merchant_transfers mt"
+ " USING (credit_serial)"
+ " JOIN merchant_accounts acc"
+ " ON (acc.account_serial = mt.account_serial)"
+ /* Check that all this is for the same instance */
+ " JOIN merchant_contract_terms contracts"
+ " USING (merchant_serial, order_serial)"
+ " WHERE mcon.order_serial=$1"),
/* for postgres_mark_order_wired() */
GNUNET_PQ_make_prepare ("mark_order_wired",
"UPDATE merchant_contract_terms SET"
- " wired=true"
+ " wired=TRUE"
" WHERE order_serial=$1"),
/* for postgres_lookup_refunds_detailed() */
GNUNET_PQ_make_prepare ("lookup_refunds_detailed",
"SELECT"
- " refund_serial"
- ",refund_timestamp"
- ",coin_pub"
- ",merchant_deposits.exchange_url"
- ",rtransaction_id"
- ",reason"
- ",refund_amount"
+ " ref.refund_serial"
+ ",ref.refund_timestamp"
+ ",dep.coin_pub"
+ ",mcon.exchange_url"
+ ",ref.rtransaction_id"
+ ",ref.reason"
+ ",ref.refund_amount"
",merchant_refund_proofs.exchange_sig IS NULL AS pending"
- " FROM merchant_refunds"
- " JOIN merchant_deposits USING (order_serial, coin_pub)"
- " LEFT JOIN merchant_refund_proofs USING (refund_serial)"
- " WHERE order_serial="
+ " FROM merchant_deposit_confirmations mcon"
+ " JOIN merchant_deposits dep"
+ " USING (deposit_confirmation_serial)"
+ " JOIN merchant_refunds ref"
+ " USING (order_serial, coin_pub)"
+ " LEFT JOIN merchant_refund_proofs"
+ " USING (refund_serial)"
+ " WHERE mcon.order_serial="
" (SELECT order_serial"
" FROM merchant_contract_terms"
" WHERE h_contract_terms=$2"
@@ -3197,23 +3211,28 @@ postgres_connect (void *cls)
/* for postgres_lookup_deposits_by_contract_and_coin() */
GNUNET_PQ_make_prepare ("lookup_deposits_by_contract_and_coin",
"SELECT"
- " exchange_url"
- ",amount_with_fee"
- ",deposit_fee"
- ",refund_fee"
- ",wire_fee"
- ",h_wire"
- ",deposit_timestamp"
- ",refund_deadline"
- ",exchange_sig"
- ",exchange_pub"
- " FROM merchant_contract_terms"
- " JOIN merchant_deposits USING (order_serial)"
- " JOIN merchant_exchange_signing_keys USING (signkey_serial)"
- " JOIN merchant_accounts USING (account_serial)"
+ " mcon.exchange_url"
+ ",dep.amount_with_fee"
+ ",dep.deposit_fee"
+ ",dep.refund_fee"
+ ",mcon.wire_fee"
+ ",acc.h_wire"
+ ",mcon.deposit_timestamp"
+ ",mct.refund_deadline"
+ ",mcon.exchange_sig"
+ ",msig.exchange_pub"
+ " FROM merchant_contract_terms mct"
+ " JOIN merchant_deposit_confirmations mcon"
+ " USING (order_serial)"
+ " JOIN merchant_deposits dep"
+ " USING (deposit_confirmation_serial)"
+ " JOIN merchant_exchange_signing_keys msig"
+ " USING (signkey_serial)"
+ " JOIN merchant_accounts acc"
+ " USING (account_serial)"
" WHERE h_contract_terms=$2"
- " AND coin_pub=$3"
- " AND merchant_contract_terms.merchant_serial="
+ " AND dep.coin_pub=$3"
+ " AND mct.merchant_serial="
" (SELECT merchant_serial"
" FROM merchant_instances"
" WHERE merchant_id=$1)"),
@@ -3235,29 +3254,39 @@ postgres_connect (void *cls)
/* for postgres_lookup_transfer_summary() */
GNUNET_PQ_make_prepare ("lookup_transfer_summary",
"SELECT"
- " order_id"
- ",exchange_deposit_value"
- ",exchange_deposit_fee"
- " FROM merchant_transfers"
- " JOIN merchant_transfer_to_coin USING (credit_serial)"
- " JOIN merchant_deposits USING (deposit_serial)"
- " JOIN merchant_contract_terms USING (order_serial)"
- " WHERE wtid=$2"
- " AND merchant_transfers.exchange_url=$1"),
+ " mct.order_id"
+ ",mtc.exchange_deposit_value"
+ ",mtc.exchange_deposit_fee"
+ " FROM merchant_transfers mtr"
+ " JOIN merchant_transfer_to_coin mtc"
+ " USING (credit_serial)"
+ " JOIN merchant_deposits dep"
+ " USING (deposit_serial)"
+ " JOIN merchant_deposit_confirmations mcon"
+ " USING (deposit_confirmation_serial)"
+ " JOIN merchant_contract_terms mct"
+ " USING (order_serial)"
+ " WHERE mtr.wtid=$2"
+ " AND mtr.exchange_url=$1"),
/* for postgres_lookup_transfer_details() */
GNUNET_PQ_make_prepare ("lookup_transfer_details",
"SELECT"
- " merchant_contract_terms.h_contract_terms"
- ",merchant_transfer_to_coin.offset_in_exchange_list"
- ",merchant_deposits.coin_pub"
- ",exchange_deposit_value"
- ",exchange_deposit_fee"
- " FROM merchant_transfer_to_coin"
- " JOIN merchant_deposits USING (deposit_serial)"
- " JOIN merchant_contract_terms USING (order_serial)"
- " JOIN merchant_transfers USING (credit_serial)"
- " WHERE merchant_transfers.wtid=$2"
- " AND merchant_transfers.exchange_url=$1"),
+ " mterm.h_contract_terms"
+ ",mtcoin.offset_in_exchange_list"
+ ",dep.coin_pub"
+ ",mtcoin.exchange_deposit_value"
+ ",mtcoin.exchange_deposit_fee"
+ " FROM merchant_transfer_to_coin mtcoin"
+ " JOIN merchant_deposits dep"
+ " USING (deposit_serial)"
+ " JOIN merchant_deposit_confirmations mcon"
+ " USING (deposit_confirmation_serial)"
+ " JOIN merchant_contract_terms mterm"
+ " USING (order_serial)"
+ " JOIN merchant_transfers mtr"
+ " USING (credit_serial)"
+ " WHERE mtr.wtid=$2"
+ " AND mtr.exchange_url=$1"),
/* For postgres_insert_reserve() */
GNUNET_PQ_make_prepare ("insert_reserve_key",
"INSERT INTO merchant_reward_reserve_keys"
@@ -3786,6 +3815,8 @@ libtaler_plugin_merchantdb_postgres_init (void *cls)
= &TMH_PG_lookup_deposits;
plugin->insert_exchange_signkey
= &TMH_PG_insert_exchange_signkey;
+ plugin->insert_deposit_confirmation
+ = &TMH_PG_insert_deposit_confirmation;
plugin->insert_deposit
= &TMH_PG_insert_deposit;
plugin->lookup_refunds
diff --git a/src/backenddb/test_merchantdb.c b/src/backenddb/test_merchantdb.c
index 4c2ef5c9..94f47f70 100644
--- a/src/backenddb/test_merchantdb.c
+++ b/src/backenddb/test_merchantdb.c
@@ -304,9 +304,6 @@ lookup_instances_cb (void *cls,
}
-
-
-
/**
* Tests @e insert_instance.
*
@@ -2359,6 +2356,11 @@ struct DepositData
struct TALER_CoinSpendPublicKeyP coin_pub;
/**
+ * Signature of the coin that has been deposited.
+ */
+ struct TALER_CoinSpendSignatureP coin_sig;
+
+ /**
* URL of the exchange.
*/
const char *exchange_url;
@@ -2397,39 +2399,6 @@ struct DepositData
/**
- * Private key for my_sign_cb().
- */
-static const struct TALER_ExchangePrivateKeyP *msc_exchange_priv;
-
-/**
- * Function that signs the message in @a purpose with the
- * exchange's signing key from #msc_exchange_priv.
- *
- * The @a purpose data is the beginning of the data of which the signature is
- * to be created. The `size` field in @a purpose must correctly indicate the
- * number of bytes of the data structure, including its header. *
- * @param purpose the message to sign
- * @param[out] pub set to the current public signing key of the exchange
- * @param[out] sig signature over purpose using current signing key
- * @return #TALER_EC_NONE on success
- */
-static enum TALER_ErrorCode
-my_sign_cb (
- const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose,
- struct TALER_ExchangePublicKeyP *pub,
- struct TALER_ExchangeSignatureP *sig)
-{
- GNUNET_assert (GNUNET_OK ==
- GNUNET_CRYPTO_eddsa_sign_ (&msc_exchange_priv->eddsa_priv,
- purpose,
- &sig->eddsa_signature));
- GNUNET_CRYPTO_eddsa_key_get_public (&msc_exchange_priv->eddsa_priv,
- &pub->eddsa_pub);
- return TALER_EC_NONE;
-}
-
-
-/**
* Generates deposit data for an order.
*
* @param instance the instance to make the deposit to.
@@ -2448,7 +2417,6 @@ make_deposit (const struct InstanceData *instance,
struct TALER_CoinSpendPrivateKeyP coin_priv;
struct GNUNET_TIME_Timestamp now;
struct TALER_Amount amount_without_fee;
- struct TALER_ExchangePublicKeyP exchange_pub;
now = GNUNET_TIME_timestamp_get ();
deposit->timestamp = now;
@@ -2476,22 +2444,12 @@ make_deposit (const struct InstanceData *instance,
&deposit->amount_with_fee,
&deposit->deposit_fee));
deposit->h_wire = account->h_wire;
- msc_exchange_priv = &signkey->exchange_priv;
- GNUNET_assert (TALER_EC_NONE ==
- TALER_exchange_online_deposit_confirmation_sign (
- &my_sign_cb,
- &deposit->h_contract_terms,
- &deposit->h_wire,
- NULL,
- now,
- now,
- now,
- &amount_without_fee,
- &deposit->coin_pub,
- &instance->merchant_pub,
- &exchange_pub,
- &deposit->exchange_sig));
- msc_exchange_priv = NULL;
+ GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
+ &deposit->exchange_sig,
+ sizeof (deposit->exchange_sig));
+ GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
+ &deposit->coin_sig,
+ sizeof (deposit->coin_sig));
}
@@ -2534,21 +2492,38 @@ test_insert_deposit (const struct InstanceData *instance,
const struct DepositData *deposit,
enum GNUNET_DB_QueryStatus expected_result)
{
- TEST_COND_RET_ON_FAIL (expected_result ==
- plugin->insert_deposit (plugin->cls,
- instance->instance.id,
- deposit->timestamp,
- &deposit->h_contract_terms,
- &deposit->coin_pub,
- deposit->exchange_url,
- &deposit->amount_with_fee,
- &deposit->deposit_fee,
- &deposit->refund_fee,
- &deposit->wire_fee,
- &deposit->h_wire,
- &deposit->exchange_sig,
- &signkey->exchange_pub),
- "Insert deposit failed\n");
+ uint64_t row;
+ struct TALER_Amount awf;
+
+ GNUNET_assert (0 <=
+ TALER_amount_subtract (&awf,
+ &deposit->amount_with_fee,
+ &deposit->deposit_fee));
+ TEST_COND_RET_ON_FAIL (
+ expected_result ==
+ plugin->insert_deposit_confirmation (plugin->cls,
+ instance->instance.id,
+ deposit->timestamp,
+ &deposit->h_contract_terms,
+ deposit->exchange_url,
+ &awf,
+ &deposit->wire_fee,
+ &deposit->h_wire,
+ &deposit->exchange_sig,
+ &signkey->exchange_pub,
+ &row),
+ "Insert deposit confirmation failed\n");
+ TEST_COND_RET_ON_FAIL (
+ expected_result ==
+ plugin->insert_deposit (plugin->cls,
+ 0,
+ row,
+ &deposit->coin_pub,
+ &deposit->coin_sig,
+ &deposit->amount_with_fee,
+ &deposit->deposit_fee,
+ &deposit->refund_fee),
+ "Insert deposit failed\n");
return 0;
}
@@ -2588,7 +2563,6 @@ struct TestLookupDeposits_Closure
* @param amount_with_fee amount of the deposit with fees.
* @param deposit_fee fee charged for the deposit.
* @param refund_fee fee charged in case of a refund.
- * @param wire_fee fee charged when the money is wired.
*/
static void
lookup_deposits_cb (void *cls,
@@ -2596,8 +2570,7 @@ lookup_deposits_cb (void *cls,
const struct TALER_CoinSpendPublicKeyP *coin_pub,
const struct TALER_Amount *amount_with_fee,
const struct TALER_Amount *deposit_fee,
- const struct TALER_Amount *refund_fee,
- const struct TALER_Amount *wire_fee)
+ const struct TALER_Amount *refund_fee)
{
struct TestLookupDeposits_Closure *cmp = cls;
if (NULL == cmp)
@@ -2625,14 +2598,7 @@ lookup_deposits_cb (void *cls,
refund_fee)) &&
(0 ==
TALER_amount_cmp (&cmp->deposits_to_cmp[i].refund_fee,
- refund_fee)) &&
- (GNUNET_OK ==
- TALER_amount_cmp_currency (
- &cmp->deposits_to_cmp[i].wire_fee,
- wire_fee)) &&
- (0 ==
- TALER_amount_cmp (&cmp->deposits_to_cmp[i].wire_fee,
- wire_fee)))
+ refund_fee)))
{
cmp->results_matching[i] += 1;
}
diff --git a/src/include/taler_merchantdb_plugin.h b/src/include/taler_merchantdb_plugin.h
index fb05bf1c..fd29edba 100644
--- a/src/include/taler_merchantdb_plugin.h
+++ b/src/include/taler_merchantdb_plugin.h
@@ -370,7 +370,7 @@ struct TALER_MERCHANTDB_TemplateDetails
* In this template contract, we can have additional information.
*/
json_t *template_contract;
-
+
/**
* ID of the OTP device linked to the template, or NULL.
*/
@@ -606,7 +606,6 @@ typedef void
* @param amount_with_fee amount the exchange will deposit for this coin
* @param deposit_fee fee the exchange will charge for this coin
* @param refund_fee fee the exchange will charge for refunding this coin
- * @param wire_fee wire fee the exchange charges
*/
typedef void
(*TALER_MERCHANTDB_DepositsCallback)(
@@ -615,8 +614,7 @@ typedef void
const struct TALER_CoinSpendPublicKeyP *coin_pub,
const struct TALER_Amount *amount_with_fee,
const struct TALER_Amount *deposit_fee,
- const struct TALER_Amount *refund_fee,
- const struct TALER_Amount *wire_fee);
+ const struct TALER_Amount *refund_fee);
/**
@@ -1348,7 +1346,7 @@ struct TALER_MERCHANTDB_Plugin
const struct TALER_MerchantWireHashP *h_wire,
const char *credit_facade_url,
const json_t *credit_facade_credentials);
-
+
/**
* Obtain information about an instance's accounts.
@@ -1384,15 +1382,15 @@ struct TALER_MERCHANTDB_Plugin
struct TALER_MERCHANTDB_AccountDetails *ad);
- /**
- * Obtain detailed information about an instance's account.
- *
- * @param cls closure
- * @param id identifier of the instance
- * @param payto_uri URI of the account
- * @param[out] ad account details returned
- * @return database result code
- */
+ /**
+ * Obtain detailed information about an instance's account.
+ *
+ * @param cls closure
+ * @param id identifier of the instance
+ * @param payto_uri URI of the account
+ * @param[out] ad account details returned
+ * @return database result code
+ */
enum GNUNET_DB_QueryStatus
(*select_account_by_uri)(
void *cls,
@@ -1944,36 +1942,60 @@ struct TALER_MERCHANTDB_Plugin
/**
- * Insert payment confirmation from the exchange into the database.
+ * Insert deposit confirmation from the exchange into the database.
*
* @param cls closure
* @param instance_id instance to lookup deposits for
* @param deposit_timestamp time when the exchange generated the deposit confirmation
* @param h_contract_terms proposal data's hashcode
- * @param coin_pub public key of the coin
* @param exchange_url URL of the exchange that issued @a coin_pub
- * @param amount_with_fee amount the exchange will deposit for this coin
- * @param deposit_fee fee the exchange will charge for this coin
+ * @param total_without_fees deposited total in the batch without fees
* @param wire_fee wire fee the exchange charges
* @param h_wire hash of the wire details of the target account of the merchant
* @param exchange_sig signature from exchange that coin was accepted
* @param exchange_pub signing key that was used for @a exchange_sig
+ * @param[out] batch_deposit_serial_id set to the table row
* @return transaction status
*/
enum GNUNET_DB_QueryStatus
- (*insert_deposit)(void *cls,
- const char *instance_id,
- struct GNUNET_TIME_Timestamp deposit_timestamp,
- const struct TALER_PrivateContractHashP *h_contract_terms,
- const struct TALER_CoinSpendPublicKeyP *coin_pub,
- const char *exchange_url,
- const struct TALER_Amount *amount_with_fee,
- const struct TALER_Amount *deposit_fee,
- const struct TALER_Amount *refund_fee,
- const struct TALER_Amount *wire_fee,
- const struct TALER_MerchantWireHashP *h_wire,
- const struct TALER_ExchangeSignatureP *exchange_sig,
- const struct TALER_ExchangePublicKeyP *exchange_pub);
+ (*insert_deposit_confirmation)(
+ void *cls,
+ const char *instance_id,
+ struct GNUNET_TIME_Timestamp deposit_timestamp,
+ const struct TALER_PrivateContractHashP *h_contract_terms,
+ const char *exchange_url,
+ const struct TALER_Amount *total_without_fees,
+ const struct TALER_Amount *wire_fee,
+ const struct TALER_MerchantWireHashP *h_wire,
+ const struct TALER_ExchangeSignatureP *exchange_sig,
+ const struct TALER_ExchangePublicKeyP *exchange_pub,
+ uint64_t *batch_deposit_serial_id);
+
+
+ /**
+ * Insert information about coin deposited as part of
+ * a batch into the database.
+ *
+ * @param cls closure
+ * @param offset offset of the coin in the batch
+ * @param deposit_confirmation_serial_id deposit confirmation for the batch the coin is part of
+ * @param coin_pub public key of the coin
+ * @param coin_sig deposit signature of the coin
+ * @param amount_with_fee amount the exchange will deposit for this coin
+ * @param deposit_fee fee the exchange will charge for this coin
+ * @param refund_fee fee the exchange will charge for refunds of coin
+ * @return transaction status
+ */
+ enum GNUNET_DB_QueryStatus
+ (*insert_deposit)(
+ void *cls,
+ uint32_t offset,
+ uint64_t deposit_confirmation_serial_id,
+ const struct TALER_CoinSpendPublicKeyP *coin_pub,
+ const struct TALER_CoinSpendSignatureP *coin_sig,
+ const struct TALER_Amount *amount_with_fee,
+ const struct TALER_Amount *deposit_fee,
+ const struct TALER_Amount *refund_fee);
/**
@@ -3057,9 +3079,9 @@ struct TALER_MERCHANTDB_Plugin
* if template unknown.
*/
enum GNUNET_DB_QueryStatus
- (*delete_otp) (void *cls,
- const char *instance_id,
- const char *otp_id);
+ (*delete_otp)(void *cls,
+ const char *instance_id,
+ const char *otp_id);
/**
* Insert details about a particular OTP device.
@@ -3071,10 +3093,10 @@ struct TALER_MERCHANTDB_Plugin
* @return database result code
*/
enum GNUNET_DB_QueryStatus
- (*insert_otp) (void *cls,
- const char *instance_id,
- const char *otp_id,
- const struct TALER_MERCHANTDB_OtpDeviceDetails *td);
+ (*insert_otp)(void *cls,
+ const char *instance_id,
+ const char *otp_id,
+ const struct TALER_MERCHANTDB_OtpDeviceDetails *td);
/**
@@ -3089,10 +3111,10 @@ struct TALER_MERCHANTDB_Plugin
* does not yet exist.
*/
enum GNUNET_DB_QueryStatus
- (*update_otp) (void *cls,
- const char *instance_id,
- const char *otp_id,
- const struct TALER_MERCHANTDB_OtpDeviceDetails *td);
+ (*update_otp)(void *cls,
+ const char *instance_id,
+ const char *otp_id,
+ const struct TALER_MERCHANTDB_OtpDeviceDetails *td);
/**
* Lookup all of the OTP devices the given instance has configured.
@@ -3104,10 +3126,10 @@ struct TALER_MERCHANTDB_Plugin
* @return database result code
*/
enum GNUNET_DB_QueryStatus
- (*lookup_otp_devices) (void *cls,
- const char *instance_id,
- TALER_MERCHANTDB_OtpDeviceCallback cb,
- void *cb_cls);
+ (*lookup_otp_devices)(void *cls,
+ const char *instance_id,
+ TALER_MERCHANTDB_OtpDeviceCallback cb,
+ void *cb_cls);
/**
@@ -3121,10 +3143,10 @@ struct TALER_MERCHANTDB_Plugin
* @return database result code
*/
enum GNUNET_DB_QueryStatus
- (*select_otp) (void *cls,
- const char *instance_id,
- const char *otp_id,
- struct TALER_MERCHANTDB_OtpDeviceDetails *td);
+ (*select_otp)(void *cls,
+ const char *instance_id,
+ const char *otp_id,
+ struct TALER_MERCHANTDB_OtpDeviceDetails *td);
/**
@@ -3136,12 +3158,12 @@ struct TALER_MERCHANTDB_Plugin
* @param[out] serial set to the OTP device serial number * @return database result code
*/
enum GNUNET_DB_QueryStatus
- (*select_otp_serial) (void *cls,
- const char *instance_id,
- const char *otp_id,
- uint64_t *serial);
+ (*select_otp_serial)(void *cls,
+ const char *instance_id,
+ const char *otp_id,
+ uint64_t *serial);
+
-
/**
* Update details about a particular template.
*
diff --git a/src/testing/test_merchant_transfer_tracking.sh b/src/testing/test_merchant_transfer_tracking.sh
index dfd5f5d2..0e999f25 100755
--- a/src/testing/test_merchant_transfer_tracking.sh
+++ b/src/testing/test_merchant_transfer_tracking.sh
@@ -245,10 +245,6 @@ taler-exchange-aggregator -y -c $CONF -T ${TO_SLEEP}000000 -t -L INFO &> aggrega
taler-exchange-transfer -c $CONF -t -L INFO &> transfer.log
echo " DONE"
-echo -n "waiting for Nexus and Sandbox to settle the payment .."
-sleep 3
-echo " DONE"
-
echo -n "Obtaining wire transfer details from bank..."
if [ 1 = "$USE_FAKEBANK" ]
@@ -260,6 +256,9 @@ then
TARGET_PAYTO=$(echo "$BANKDATA" | jq -r .outgoing_transactions[0].credit_account)
TARGET=$(echo "$TARGET_PAYTO" | awk -F = '{print $2}')
else
+ echo -n "waiting for Nexus and Sandbox to settle the payment .."
+ sleep 3
+ echo " DONE"
# Emulating the previous pybank-based logic of getting
# the wire transfer information _via the exchange_ bank
# account. NOTE: grabbing tx == 0, since the latest