aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/auditor/taler-helper-auditor-aggregation.c21
-rw-r--r--src/auditor/taler-helper-auditor-coins.c92
-rw-r--r--src/auditor/taler-helper-auditor-deposits.c20
-rw-r--r--src/benchmark/taler-aggregator-benchmark.c54
-rw-r--r--src/exchange/taler-exchange-httpd_deposit.c76
-rw-r--r--src/exchange/taler-exchange-httpd_responses.c7
-rw-r--r--src/exchangedb/plugin_exchangedb_common.c3
-rw-r--r--src/exchangedb/plugin_exchangedb_postgres.c241
-rw-r--r--src/include/taler_exchange_service.h6
-rw-r--r--src/include/taler_exchangedb_plugin.h71
-rw-r--r--src/lib/exchange_api_deposit.c22
-rw-r--r--src/testing/testing_api_cmd_deposit.c21
-rw-r--r--src/testing/testing_api_cmd_insert_deposit.c34
13 files changed, 341 insertions, 327 deletions
diff --git a/src/auditor/taler-helper-auditor-aggregation.c b/src/auditor/taler-helper-auditor-aggregation.c
index e77eeab7a..99fe16e01 100644
--- a/src/auditor/taler-helper-auditor-aggregation.c
+++ b/src/auditor/taler-helper-auditor-aggregation.c
@@ -440,27 +440,6 @@ check_transaction_history_for_deposit (
{
case TALER_EXCHANGEDB_TT_DEPOSIT:
/* check wire and h_wire are consistent */
- {
- struct TALER_MerchantWireHash hw;
-
- if (GNUNET_OK !=
- TALER_JSON_merchant_wire_signature_hash (
- tl->details.deposit->receiver_wire_account,
- &hw))
- {
- report_row_inconsistency ("deposits",
- tl->serial_id,
- "wire account given is malformed");
- }
- else if (0 !=
- GNUNET_memcmp (&hw,
- &tl->details.deposit->h_wire))
- {
- report_row_inconsistency ("deposits",
- tl->serial_id,
- "h(wire) does not match wire");
- }
- }
amount_with_fee = &tl->details.deposit->amount_with_fee; /* according to exchange*/
fee_claimed = &tl->details.deposit->deposit_fee; /* Fee according to exchange DB */
TALER_ARL_amount_add (&expenditures,
diff --git a/src/auditor/taler-helper-auditor-coins.c b/src/auditor/taler-helper-auditor-coins.c
index b01197ff5..525738bd5 100644
--- a/src/auditor/taler-helper-auditor-coins.c
+++ b/src/auditor/taler-helper-auditor-coins.c
@@ -1556,18 +1556,8 @@ refresh_session_cb (void *cls,
* @param cls closure
* @param rowid unique serial ID for the deposit in our DB
* @param exchange_timestamp when did the exchange get the deposit
- * @param wallet_timestamp when did the contract signing happen
- * @param merchant_pub public key of the merchant
+ * @param deposit deposit details
* @param denom_pub denomination public key of @a coin_pub
- * @param coin_pub public key of the coin
- * @param coin_sig signature from the coin
- * @param amount_with_fee amount that was deposited including fee
- * @param h_contract_terms hash of the proposal data known to merchant and customer
- * @param refund_deadline by which the merchant advised that he might want
- * to get a refund
- * @param wire_deadline by which the merchant advised that he would like the
- * wire transfer to be executed
- * @param receiver_wire_account wire details for the merchant, NULL from iterate_matching_deposits()
* @param done flag set if the deposit was already executed (or not)
* @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop
*/
@@ -1575,17 +1565,9 @@ static enum GNUNET_GenericReturnValue
deposit_cb (void *cls,
uint64_t rowid,
struct GNUNET_TIME_Absolute exchange_timestamp,
- struct GNUNET_TIME_Absolute wallet_timestamp,
- const struct TALER_MerchantPublicKeyP *merchant_pub,
+ const struct TALER_EXCHANGEDB_Deposit *deposit,
const struct TALER_DenominationPublicKey *denom_pub,
- const struct TALER_CoinSpendPublicKeyP *coin_pub,
- const struct TALER_CoinSpendSignatureP *coin_sig,
- const struct TALER_Amount *amount_with_fee,
- const struct TALER_PrivateContractHash *h_contract_terms,
- struct GNUNET_TIME_Absolute refund_deadline,
- struct GNUNET_TIME_Absolute wire_deadline,
- const json_t *receiver_wire_account,
- int done)
+ bool done)
{
struct CoinContext *cc = cls;
const struct TALER_DenominationKeyValidityPS *issue;
@@ -1608,8 +1590,8 @@ deposit_cb (void *cls,
return GNUNET_SYSERR;
return GNUNET_OK;
}
- if (refund_deadline.abs_value_us >
- wire_deadline.abs_value_us)
+ if (deposit->refund_deadline.abs_value_us >
+ deposit->wire_deadline.abs_value_us)
{
report_row_inconsistency ("deposits",
rowid,
@@ -1625,9 +1607,9 @@ deposit_cb (void *cls,
qs = check_known_coin ("deposit",
issue,
rowid,
- coin_pub,
+ &deposit->coin.coin_pub,
denom_pub,
- amount_with_fee);
+ &deposit->amount_with_fee);
if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs)
{
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
@@ -1640,47 +1622,29 @@ deposit_cb (void *cls,
struct TALER_DepositRequestPS dr = {
.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_DEPOSIT),
.purpose.size = htonl (sizeof (dr)),
- .h_contract_terms = *h_contract_terms,
- .wallet_timestamp = GNUNET_TIME_absolute_hton (wallet_timestamp),
- .refund_deadline = GNUNET_TIME_absolute_hton (refund_deadline),
+ .h_contract_terms = deposit->h_contract_terms,
+ .wallet_timestamp = GNUNET_TIME_absolute_hton (deposit->timestamp),
+ .refund_deadline = GNUNET_TIME_absolute_hton (deposit->refund_deadline),
.deposit_fee = issue->fee_deposit,
- .merchant = *merchant_pub,
- .coin_pub = *coin_pub
+ .merchant = deposit->merchant_pub,
+ .coin_pub = deposit->coin.coin_pub
};
TALER_denom_pub_hash (denom_pub,
&dr.h_denom_pub);
- if (GNUNET_OK !=
- TALER_JSON_merchant_wire_signature_hash (receiver_wire_account,
- &dr.h_wire))
- {
- TALER_ARL_report (report_bad_sig_losses,
- GNUNET_JSON_PACK (
- GNUNET_JSON_pack_string ("operation",
- "deposit"),
- GNUNET_JSON_pack_uint64 ("row",
- rowid),
- TALER_JSON_pack_amount ("loss",
- amount_with_fee),
- GNUNET_JSON_pack_data_auto ("coin_pub",
- coin_pub)));
- TALER_ARL_amount_add (&total_bad_sig_loss,
- &total_bad_sig_loss,
- amount_with_fee);
- if (TALER_ARL_do_abort ())
- return GNUNET_SYSERR;
- return GNUNET_OK;
- }
+ TALER_merchant_wire_signature_hash (deposit->receiver_wire_account,
+ &deposit->wire_salt,
+ &dr.h_wire);
TALER_amount_hton (&dr.amount_with_fee,
- amount_with_fee);
+ &deposit->amount_with_fee);
/* NOTE: This is one of the operations we might eventually
want to do in parallel in the background to improve
auditor performance! */
if (GNUNET_OK !=
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_DEPOSIT,
&dr,
- &coin_sig->eddsa_signature,
- &coin_pub->eddsa_pub))
+ &deposit->csig.eddsa_signature,
+ &deposit->coin.coin_pub.eddsa_pub))
{
TALER_ARL_report (report_bad_sig_losses,
GNUNET_JSON_PACK (
@@ -1689,12 +1653,12 @@ deposit_cb (void *cls,
GNUNET_JSON_pack_uint64 ("row",
rowid),
TALER_JSON_pack_amount ("loss",
- amount_with_fee),
+ &deposit->amount_with_fee),
GNUNET_JSON_pack_data_auto ("coin_pub",
- coin_pub)));
+ &deposit->coin.coin_pub)));
TALER_ARL_amount_add (&total_bad_sig_loss,
&total_bad_sig_loss,
- amount_with_fee);
+ &deposit->amount_with_fee);
if (TALER_ARL_do_abort ())
return GNUNET_SYSERR;
return GNUNET_OK;
@@ -1702,9 +1666,9 @@ deposit_cb (void *cls,
}
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Deposited coin %s in denomination `%s' of value %s\n",
- TALER_B2S (coin_pub),
+ TALER_B2S (&deposit->coin.coin_pub),
GNUNET_h2s (&issue->denom_hash.hash),
- TALER_amount2s (amount_with_fee));
+ TALER_amount2s (&deposit->amount_with_fee));
/* update old coin's denomination balance */
ds = get_denomination_summary (cc,
@@ -1723,11 +1687,11 @@ deposit_cb (void *cls,
if (TALER_ARL_SR_INVALID_NEGATIVE ==
TALER_ARL_amount_subtract_neg (&tmp,
&ds->denom_balance,
- amount_with_fee))
+ &deposit->amount_with_fee))
{
TALER_ARL_amount_add (&ds->denom_loss,
&ds->denom_loss,
- amount_with_fee);
+ &deposit->amount_with_fee);
ds->report_emergency = GNUNET_YES;
}
else
@@ -1736,7 +1700,7 @@ deposit_cb (void *cls,
}
if (-1 == TALER_amount_cmp (&total_escrow_balance,
- amount_with_fee))
+ &deposit->amount_with_fee))
{
/* This can theoretically happen if for example the exchange
never issued any coins (i.e. escrow balance is zero), but
@@ -1748,14 +1712,14 @@ deposit_cb (void *cls,
"subtracting deposit fee from escrow balance",
rowid,
&total_escrow_balance,
- amount_with_fee,
+ &deposit->amount_with_fee,
0);
}
else
{
TALER_ARL_amount_subtract (&total_escrow_balance,
&total_escrow_balance,
- amount_with_fee);
+ &deposit->amount_with_fee);
}
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
diff --git a/src/auditor/taler-helper-auditor-deposits.c b/src/auditor/taler-helper-auditor-deposits.c
index d6351099e..f7e1cb0dc 100644
--- a/src/auditor/taler-helper-auditor-deposits.c
+++ b/src/auditor/taler-helper-auditor-deposits.c
@@ -112,21 +112,17 @@ test_dc (void *cls,
dcc->last_seen_coin_serial = serial_id;
{
enum GNUNET_DB_QueryStatus qs;
- struct TALER_EXCHANGEDB_Deposit dep = {
- .coin.coin_pub = dc->coin_pub,
- .h_contract_terms = dc->h_contract_terms,
- .merchant_pub = dc->merchant,
- .h_wire = dc->h_wire,
- .refund_deadline = dc->refund_deadline
- };
struct GNUNET_TIME_Absolute exchange_timestamp;
struct TALER_Amount deposit_fee;
- qs = TALER_ARL_edb->have_deposit (TALER_ARL_edb->cls,
- &dep,
- GNUNET_NO /* do not check refund deadline */,
- &deposit_fee,
- &exchange_timestamp);
+ qs = TALER_ARL_edb->have_deposit2 (TALER_ARL_edb->cls,
+ &dc->h_contract_terms,
+ &dc->h_wire,
+ &dc->coin_pub,
+ &dc->merchant,
+ dc->refund_deadline,
+ &deposit_fee,
+ &exchange_timestamp);
if (qs > 0)
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
diff --git a/src/benchmark/taler-aggregator-benchmark.c b/src/benchmark/taler-aggregator-benchmark.c
index 348d153cb..f5c809175 100644
--- a/src/benchmark/taler-aggregator-benchmark.c
+++ b/src/benchmark/taler-aggregator-benchmark.c
@@ -59,11 +59,6 @@ static unsigned int refund_rate = 0;
static char *currency;
/**
- * Merchant JSON wire details.
- */
-static json_t *json_wire;
-
-/**
* Configuration.
*/
static const struct GNUNET_CONFIGURATION_Handle *cfg;
@@ -213,11 +208,6 @@ do_shutdown (void *cls)
task = NULL;
}
TALER_denom_sig_free (&denom_sig);
- if (NULL != json_wire)
- {
- json_decref (json_wire);
- json_wire = NULL;
- }
}
@@ -238,6 +228,16 @@ struct Merchant
*/
struct TALER_MerchantWireHash h_wire;
+ /**
+ * Salt used when computing @e h_wire.
+ */
+ struct TALER_WireSalt wire_salt;
+
+ /**
+ * Account information for the merchant.
+ */
+ char *payto_uri;
+
};
struct Deposit
@@ -320,9 +320,8 @@ add_deposit (const struct Merchant *m)
RANDOMIZE (&deposit.csig);
deposit.merchant_pub = m->merchant_pub;
deposit.h_contract_terms = d.h_contract_terms;
- deposit.h_wire = m->h_wire;
- deposit.receiver_wire_account
- = json_wire;
+ deposit.wire_salt = m->wire_salt;
+ deposit.receiver_wire_account = m->payto_uri;
deposit.timestamp = random_time ();
deposit.refund_deadline = random_time ();
deposit.wire_deadline = random_time ();
@@ -355,7 +354,6 @@ static void
work (void *cls)
{
struct Merchant m;
- char *acc;
uint64_t rnd1;
uint64_t rnd2;
@@ -365,33 +363,22 @@ work (void *cls)
UINT64_MAX);
rnd2 = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_NONCE,
UINT64_MAX);
- GNUNET_asprintf (&acc,
+ GNUNET_asprintf (&m.payto_uri,
"payto://x-taler-bank/localhost:8082/account-%llX-%llX",
(unsigned long long) rnd1,
(unsigned long long) rnd2);
- json_wire = GNUNET_JSON_PACK (
- GNUNET_JSON_pack_string ("payto_uri",
- acc),
- GNUNET_JSON_pack_string ("salt",
- "thesalty"));
- GNUNET_free (acc);
RANDOMIZE (&m.merchant_pub);
- if (GNUNET_OK !=
- TALER_JSON_merchant_wire_signature_hash (json_wire,
- &m.h_wire))
- {
- GNUNET_break (0);
- global_ret = EXIT_FAILURE;
- GNUNET_SCHEDULER_shutdown ();
- return;
- }
-
+ RANDOMIZE (&m.wire_salt);
+ TALER_merchant_wire_signature_hash (m.payto_uri,
+ &m.wire_salt,
+ &m.h_wire);
if (GNUNET_OK !=
plugin->start (plugin->cls,
"aggregator-benchmark-fill"))
{
GNUNET_break (0);
global_ret = EXIT_FAILURE;
+ GNUNET_free (m.payto_uri);
GNUNET_SCHEDULER_shutdown ();
return;
}
@@ -401,6 +388,7 @@ work (void *cls)
{
global_ret = EXIT_FAILURE;
GNUNET_SCHEDULER_shutdown ();
+ GNUNET_free (m.payto_uri);
return;
}
}
@@ -410,6 +398,7 @@ work (void *cls)
if (0 == --howmany_merchants)
{
GNUNET_SCHEDULER_shutdown ();
+ GNUNET_free (m.payto_uri);
return;
}
}
@@ -418,8 +407,7 @@ work (void *cls)
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
"Failed to commit, will try again\n");
}
- json_decref (json_wire);
- json_wire = NULL;
+ GNUNET_free (m.payto_uri);
task = GNUNET_SCHEDULER_add_now (&work,
NULL);
}
diff --git a/src/exchange/taler-exchange-httpd_deposit.c b/src/exchange/taler-exchange-httpd_deposit.c
index 4f7e10e60..8f0ac8218 100644
--- a/src/exchange/taler-exchange-httpd_deposit.c
+++ b/src/exchange/taler-exchange-httpd_deposit.c
@@ -117,6 +117,11 @@ struct DepositContext
struct GNUNET_TIME_Absolute exchange_timestamp;
/**
+ * Calculated hash over the wire details.
+ */
+ struct TALER_MerchantWireHash h_wire;
+
+ /**
* Value of the coin.
*/
struct TALER_Amount value;
@@ -124,7 +129,7 @@ struct DepositContext
/**
* payto:// URI of the credited account.
*/
- char *payto_uri;
+ const char *payto_uri;
};
@@ -152,7 +157,6 @@ deposit_precheck (void *cls,
qs = TEH_plugin->have_deposit (TEH_plugin->cls,
deposit,
- GNUNET_YES /* check refund deadline */,
&deposit_fee,
&dc->exchange_timestamp);
if (qs < 0)
@@ -179,7 +183,7 @@ deposit_precheck (void *cls,
&deposit_fee));
*mhd_ret = reply_deposit_success (connection,
&deposit->coin.coin_pub,
- &deposit->h_wire,
+ &dc->h_wire,
&deposit->h_contract_terms,
dc->exchange_timestamp,
deposit->refund_deadline,
@@ -318,13 +322,13 @@ TEH_handler_deposit (struct MHD_Connection *connection,
const struct TALER_CoinSpendPublicKeyP *coin_pub,
const json_t *root)
{
- json_t *wire;
struct DepositContext dc;
struct TALER_EXCHANGEDB_Deposit deposit;
- struct TALER_MerchantWireHash my_h_wire;
struct GNUNET_JSON_Specification spec[] = {
- GNUNET_JSON_spec_json ("wire",
- &wire),
+ GNUNET_JSON_spec_string ("merchant_payto_uri",
+ &dc.payto_uri),
+ GNUNET_JSON_spec_fixed_auto ("wire_salt",
+ &deposit.wire_salt),
TALER_JSON_spec_amount ("contribution",
TEH_currency,
&deposit.amount_with_fee),
@@ -336,8 +340,6 @@ TEH_handler_deposit (struct MHD_Connection *connection,
&deposit.merchant_pub),
GNUNET_JSON_spec_fixed_auto ("h_contract_terms",
&deposit.h_contract_terms),
- GNUNET_JSON_spec_fixed_auto ("h_wire",
- &deposit.h_wire),
GNUNET_JSON_spec_fixed_auto ("coin_sig",
&deposit.csig),
TALER_JSON_spec_absolute_time ("timestamp",
@@ -375,16 +377,6 @@ TEH_handler_deposit (struct MHD_Connection *connection,
{
char *emsg;
- dc.payto_uri = TALER_JSON_wire_to_payto (wire);
- if (NULL == dc.payto_uri)
- {
- GNUNET_break_op (0);
- GNUNET_JSON_parse_free (spec);
- return TALER_MHD_reply_with_error (connection,
- MHD_HTTP_BAD_REQUEST,
- TALER_EC_GENERIC_PARAMETER_MALFORMED,
- "wire");
- }
emsg = TALER_payto_validate (dc.payto_uri);
if (NULL != emsg)
{
@@ -397,46 +389,22 @@ TEH_handler_deposit (struct MHD_Connection *connection,
TALER_EC_GENERIC_PARAMETER_MALFORMED,
emsg);
GNUNET_free (emsg);
- GNUNET_free (dc.payto_uri);
return ret;
}
}
- deposit.receiver_wire_account = wire;
+ deposit.receiver_wire_account = (char *) dc.payto_uri;
if (deposit.refund_deadline.abs_value_us > deposit.wire_deadline.abs_value_us)
{
GNUNET_break_op (0);
GNUNET_JSON_parse_free (spec);
- GNUNET_free (dc.payto_uri);
return TALER_MHD_reply_with_error (connection,
MHD_HTTP_BAD_REQUEST,
TALER_EC_EXCHANGE_DEPOSIT_REFUND_DEADLINE_AFTER_WIRE_DEADLINE,
NULL);
}
- if (GNUNET_OK !=
- TALER_JSON_merchant_wire_signature_hash (wire,
- &my_h_wire))
- {
- TALER_LOG_WARNING (
- "Failed to parse JSON wire format specification for /deposit request\n");
- GNUNET_JSON_parse_free (spec);
- GNUNET_free (dc.payto_uri);
- return TALER_MHD_reply_with_error (connection,
- MHD_HTTP_BAD_REQUEST,
- TALER_EC_EXCHANGE_DEPOSIT_INVALID_WIRE_FORMAT_JSON,
- NULL);
- }
- if (0 != GNUNET_memcmp (&deposit.h_wire,
- &my_h_wire))
- {
- /* Client hashed wire details differently than we did, reject */
- GNUNET_JSON_parse_free (spec);
- GNUNET_free (dc.payto_uri);
- return TALER_MHD_reply_with_error (connection,
- MHD_HTTP_BAD_REQUEST,
- TALER_EC_EXCHANGE_DEPOSIT_INVALID_WIRE_FORMAT_CONTRACT_HASH_CONFLICT,
- NULL);
- }
-
+ TALER_merchant_wire_signature_hash (dc.payto_uri,
+ &deposit.wire_salt,
+ &dc.h_wire);
/* Check for idempotency: did we get this request before? */
dc.deposit = &deposit;
{
@@ -450,7 +418,6 @@ TEH_handler_deposit (struct MHD_Connection *connection,
&dc))
{
GNUNET_JSON_parse_free (spec);
- GNUNET_free (dc.payto_uri);
return mhd_ret;
}
}
@@ -469,7 +436,6 @@ TEH_handler_deposit (struct MHD_Connection *connection,
if (NULL == dk)
{
GNUNET_JSON_parse_free (spec);
- GNUNET_free (dc.payto_uri);
return mret;
}
if (GNUNET_TIME_absolute_is_past (dk->meta.expire_deposit))
@@ -480,7 +446,6 @@ TEH_handler_deposit (struct MHD_Connection *connection,
now = GNUNET_TIME_absolute_get ();
(void) GNUNET_TIME_round_abs (&now);
GNUNET_JSON_parse_free (spec);
- GNUNET_free (dc.payto_uri);
return TEH_RESPONSE_reply_expired_denom_pub_hash (
connection,
&deposit.coin.denom_pub_hash,
@@ -496,7 +461,6 @@ TEH_handler_deposit (struct MHD_Connection *connection,
now = GNUNET_TIME_absolute_get ();
(void) GNUNET_TIME_round_abs (&now);
GNUNET_JSON_parse_free (spec);
- GNUNET_free (dc.payto_uri);
return TEH_RESPONSE_reply_expired_denom_pub_hash (
connection,
&deposit.coin.denom_pub_hash,
@@ -512,7 +476,6 @@ TEH_handler_deposit (struct MHD_Connection *connection,
(void) GNUNET_TIME_round_abs (&now);
/* This denomination has been revoked */
GNUNET_JSON_parse_free (spec);
- GNUNET_free (dc.payto_uri);
return TEH_RESPONSE_reply_expired_denom_pub_hash (
connection,
&deposit.coin.denom_pub_hash,
@@ -529,7 +492,6 @@ TEH_handler_deposit (struct MHD_Connection *connection,
{
TALER_LOG_WARNING ("Invalid coin passed for /deposit\n");
GNUNET_JSON_parse_free (spec);
- GNUNET_free (dc.payto_uri);
return TALER_MHD_reply_with_error (connection,
MHD_HTTP_UNAUTHORIZED,
TALER_EC_EXCHANGE_DENOMINATION_SIGNATURE_INVALID,
@@ -542,7 +504,6 @@ TEH_handler_deposit (struct MHD_Connection *connection,
{
GNUNET_break_op (0);
GNUNET_JSON_parse_free (spec);
- GNUNET_free (dc.payto_uri);
return TALER_MHD_reply_with_error (connection,
MHD_HTTP_BAD_REQUEST,
TALER_EC_EXCHANGE_DEPOSIT_NEGATIVE_VALUE_AFTER_FEE,
@@ -555,7 +516,7 @@ TEH_handler_deposit (struct MHD_Connection *connection,
.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_DEPOSIT),
.purpose.size = htonl (sizeof (dr)),
.h_contract_terms = deposit.h_contract_terms,
- .h_wire = deposit.h_wire,
+ .h_wire = dc.h_wire,
.h_denom_pub = deposit.coin.denom_pub_hash,
.wallet_timestamp = GNUNET_TIME_absolute_hton (deposit.timestamp),
.refund_deadline = GNUNET_TIME_absolute_hton (deposit.refund_deadline),
@@ -575,7 +536,6 @@ TEH_handler_deposit (struct MHD_Connection *connection,
{
TALER_LOG_WARNING ("Invalid signature on /deposit request\n");
GNUNET_JSON_parse_free (spec);
- GNUNET_free (dc.payto_uri);
return TALER_MHD_reply_with_error (connection,
MHD_HTTP_UNAUTHORIZED,
TALER_EC_EXCHANGE_DEPOSIT_COIN_SIGNATURE_INVALID,
@@ -595,11 +555,9 @@ TEH_handler_deposit (struct MHD_Connection *connection,
&dc))
{
GNUNET_JSON_parse_free (spec);
- GNUNET_free (dc.payto_uri);
return mhd_ret;
}
}
- GNUNET_free (dc.payto_uri);
/* generate regular response */
{
@@ -612,7 +570,7 @@ TEH_handler_deposit (struct MHD_Connection *connection,
&deposit.deposit_fee));
res = reply_deposit_success (connection,
&deposit.coin.coin_pub,
- &deposit.h_wire,
+ &dc.h_wire,
&deposit.h_contract_terms,
dc.exchange_timestamp,
deposit.refund_deadline,
diff --git a/src/exchange/taler-exchange-httpd_responses.c b/src/exchange/taler-exchange-httpd_responses.c
index 6747e3bf3..6dd204c6d 100644
--- a/src/exchange/taler-exchange-httpd_responses.c
+++ b/src/exchange/taler-exchange-httpd_responses.c
@@ -65,7 +65,6 @@ TEH_RESPONSE_compile_transaction_history (
.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_DEPOSIT),
.purpose.size = htonl (sizeof (dr)),
.h_contract_terms = deposit->h_contract_terms,
- .h_wire = deposit->h_wire,
.h_denom_pub = deposit->h_denom_pub,
.wallet_timestamp = GNUNET_TIME_absolute_hton (deposit->timestamp),
.refund_deadline = GNUNET_TIME_absolute_hton (
@@ -74,6 +73,10 @@ TEH_RESPONSE_compile_transaction_history (
.coin_pub = *coin_pub
};
+ TALER_merchant_wire_signature_hash (deposit->receiver_wire_account,
+ &deposit->wire_salt,
+ &dr.h_wire);
+
TALER_amount_hton (&dr.amount_with_fee,
&deposit->amount_with_fee);
TALER_amount_hton (&dr.deposit_fee,
@@ -111,7 +114,7 @@ TEH_RESPONSE_compile_transaction_history (
GNUNET_JSON_pack_data_auto ("h_contract_terms",
&deposit->h_contract_terms),
GNUNET_JSON_pack_data_auto ("h_wire",
- &deposit->h_wire),
+ &dr.h_wire),
GNUNET_JSON_pack_data_auto ("h_denom_pub",
&deposit->h_denom_pub),
GNUNET_JSON_pack_data_auto ("coin_sig",
diff --git a/src/exchangedb/plugin_exchangedb_common.c b/src/exchangedb/plugin_exchangedb_common.c
index 8f85e3ea7..2d482698d 100644
--- a/src/exchangedb/plugin_exchangedb_common.c
+++ b/src/exchangedb/plugin_exchangedb_common.c
@@ -103,8 +103,7 @@ common_free_coin_transaction_list (void *cls,
struct TALER_EXCHANGEDB_DepositListEntry *deposit;
deposit = tl->details.deposit;
- if (NULL != deposit->receiver_wire_account)
- json_decref (deposit->receiver_wire_account);
+ GNUNET_free (deposit->receiver_wire_account);
GNUNET_free (deposit);
break;
}
diff --git a/src/exchangedb/plugin_exchangedb_postgres.c b/src/exchangedb/plugin_exchangedb_postgres.c
index 0f389e86e..f15f92339 100644
--- a/src/exchangedb/plugin_exchangedb_postgres.c
+++ b/src/exchangedb/plugin_exchangedb_postgres.c
@@ -933,9 +933,9 @@ prepare_statements (struct PostgresClosure *pg)
",wire_deadline"
",merchant_pub"
",h_contract_terms"
- ",h_wire"
+ ",wire_salt"
+ ",wire_target_serial_id"
",coin_sig"
- ",wire"
",exchange_timestamp"
",shard"
") SELECT known_coin_id, $2, $3, $4, $5, $6, "
@@ -956,10 +956,12 @@ prepare_statements (struct PostgresClosure *pg)
",refund_deadline"
",wire_deadline"
",h_contract_terms"
- ",h_wire"
+ ",wire_salt"
+ ",payto_uri AS receiver_wire_account"
" FROM deposits"
" JOIN known_coins USING (known_coin_id)"
" JOIN denominations USING (denominations_serial)"
+ " JOIN wire_targets USING (wire_target_serial_id)"
" WHERE ((coin_pub=$1)"
" AND (merchant_pub=$3)"
" AND (h_contract_terms=$2));",
@@ -978,10 +980,12 @@ prepare_statements (struct PostgresClosure *pg)
",refund_deadline"
",wire_deadline"
",h_contract_terms"
- ",wire"
+ ",wire_salt"
+ ",payto_uri AS receiver_wire_account"
",done"
",deposit_serial_id"
" FROM deposits"
+ " JOIN wire_targets USING (wire_target_serial_id)"
" JOIN known_coins kc USING (known_coin_id)"
" JOIN denominations denom USING (denominations_serial)"
" WHERE ("
@@ -1095,12 +1099,14 @@ prepare_statements (struct PostgresClosure *pg)
",wire_deadline"
",merchant_pub"
",h_contract_terms"
- ",h_wire"
- ",wire"
+ ",wire_salt"
+ ",payto_uri"
",coin_sig"
",deposit_serial_id"
",done"
" FROM deposits"
+ " JOIN wire_targets"
+ " USING (wire_target_serial_id)"
" JOIN known_coins kc"
" USING (known_coin_id)"
" JOIN denominations denoms"
@@ -4790,7 +4796,6 @@ postgres_select_withdraw_amounts_by_account (
*
* @param cls the `struct PostgresClosure` with the plugin-specific state
* @param deposit deposit to search for
- * @param check_extras whether to check extra fields match or not
* @param[out] deposit_fee set to the deposit fee the exchange charged
* @param[out] exchange_timestamp set to the time when the exchange received the deposit
* @return 1 if we know this operation,
@@ -4800,7 +4805,6 @@ postgres_select_withdraw_amounts_by_account (
static enum GNUNET_DB_QueryStatus
postgres_have_deposit (void *cls,
const struct TALER_EXCHANGEDB_Deposit *deposit,
- int check_extras,
struct TALER_Amount *deposit_fee,
struct GNUNET_TIME_Absolute *exchange_timestamp)
{
@@ -4825,8 +4829,10 @@ postgres_have_deposit (void *cls,
&deposit2.wire_deadline),
TALER_PQ_RESULT_SPEC_AMOUNT ("fee_deposit",
deposit_fee),
- GNUNET_PQ_result_spec_auto_from_type ("h_wire",
- &deposit2.h_wire),
+ GNUNET_PQ_result_spec_auto_from_type ("wire_salt",
+ &deposit2.wire_salt),
+ GNUNET_PQ_result_spec_string ("receiver_wire_account",
+ &deposit2.receiver_wire_account),
GNUNET_PQ_result_spec_end
};
enum GNUNET_DB_QueryStatus qs;
@@ -4851,23 +4857,121 @@ postgres_have_deposit (void *cls,
return qs;
/* Now we check that the other information in @a deposit
also matches, and if not report inconsistencies. */
- if ( ( (check_extras) &&
- ( (0 != TALER_amount_cmp (&deposit->amount_with_fee,
- &deposit2.amount_with_fee)) ||
- (deposit->timestamp.abs_value_us !=
- deposit2.timestamp.abs_value_us) ) ) ||
+ if ( (0 != TALER_amount_cmp (&deposit->amount_with_fee,
+ &deposit2.amount_with_fee)) ||
+ (deposit->timestamp.abs_value_us !=
+ deposit2.timestamp.abs_value_us) ||
(deposit->refund_deadline.abs_value_us !=
deposit2.refund_deadline.abs_value_us) ||
- (0 != GNUNET_memcmp (&deposit->h_wire,
- &deposit2.h_wire) ) )
+ (0 != strcmp (deposit->receiver_wire_account,
+ deposit2.receiver_wire_account)) ||
+ (0 != GNUNET_memcmp (&deposit->wire_salt,
+ &deposit2.wire_salt) ) )
+ {
+ GNUNET_free (deposit2.receiver_wire_account);
+ /* Inconsistencies detected! Does not match! (We might want to
+ expand the API with a 'get_deposit' function to return the
+ original transaction details to be used for an error message
+ in the future!) FIXME #3838 */
+ return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS;
+ }
+ GNUNET_free (deposit2.receiver_wire_account);
+ return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
+}
+
+
+/**
+ * Check if we have the specified deposit already in the database.
+ *
+ * @param cls the `struct PostgresClosure` with the plugin-specific state
+ * @param h_contract_terms contract to check for
+ * @param h_wire wire hash to check for
+ * @param coin_pub public key of the coin to check for
+ * @param merchant merchant public key to check for
+ * @param refund_deadline expected refund deadline
+ * @param[out] deposit_fee set to the deposit fee the exchange charged
+ * @param[out] exchange_timestamp set to the time when the exchange received the deposit
+ * @return 1 if we know this operation,
+ * 0 if this exact deposit is unknown to us,
+ * otherwise transaction error status
+ */
+static enum GNUNET_DB_QueryStatus
+postgres_have_deposit2 (
+ void *cls,
+ const struct TALER_PrivateContractHash *h_contract_terms,
+ const struct TALER_MerchantWireHash *h_wire,
+ const struct TALER_CoinSpendPublicKeyP *coin_pub,
+ const struct TALER_MerchantPublicKeyP *merchant,
+ struct GNUNET_TIME_Absolute refund_deadline,
+ struct TALER_Amount *deposit_fee,
+ struct GNUNET_TIME_Absolute *exchange_timestamp)
+{
+ struct PostgresClosure *pg = cls;
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_auto_from_type (coin_pub),
+ GNUNET_PQ_query_param_auto_from_type (h_contract_terms),
+ GNUNET_PQ_query_param_auto_from_type (merchant),
+ GNUNET_PQ_query_param_end
+ };
+ struct TALER_EXCHANGEDB_Deposit deposit2;
+ struct GNUNET_PQ_ResultSpec rs[] = {
+ TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee",
+ &deposit2.amount_with_fee),
+ TALER_PQ_result_spec_absolute_time ("wallet_timestamp",
+ &deposit2.timestamp),
+ TALER_PQ_result_spec_absolute_time ("exchange_timestamp",
+ exchange_timestamp),
+ TALER_PQ_result_spec_absolute_time ("refund_deadline",
+ &deposit2.refund_deadline),
+ TALER_PQ_result_spec_absolute_time ("wire_deadline",
+ &deposit2.wire_deadline),
+ TALER_PQ_RESULT_SPEC_AMOUNT ("fee_deposit",
+ deposit_fee),
+ GNUNET_PQ_result_spec_auto_from_type ("wire_salt",
+ &deposit2.wire_salt),
+ GNUNET_PQ_result_spec_string ("receiver_wire_account",
+ &deposit2.receiver_wire_account),
+ GNUNET_PQ_result_spec_end
+ };
+ enum GNUNET_DB_QueryStatus qs;
+ struct TALER_MerchantWireHash h_wire2;
+#if EXPLICIT_LOCKS
+ struct GNUNET_PQ_QueryParam no_params[] = {
+ GNUNET_PQ_query_param_end
+ };
+
+ if (0 > (qs = GNUNET_PQ_eval_prepared_non_select (pg->conn,
+ "lock_deposit",
+ no_params)))
+ return qs;
+#endif
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Getting deposits for coin %s\n",
+ TALER_B2S (coin_pub));
+ qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
+ "get_deposit",
+ params,
+ rs);
+ if (0 >= qs)
+ return qs;
+ TALER_merchant_wire_signature_hash (deposit2.receiver_wire_account,
+ &deposit2.wire_salt,
+ &h_wire2);
+ GNUNET_free (deposit2.receiver_wire_account);
+ /* Now we check that the other information in @a deposit
+ also matches, and if not report inconsistencies. */
+ if ( (refund_deadline.abs_value_us !=
+ deposit2.refund_deadline.abs_value_us) ||
+ (0 != GNUNET_memcmp (h_wire,
+ &h_wire2) ) )
{
/* Inconsistencies detected! Does not match! (We might want to
expand the API with a 'get_deposit' function to return the
original transaction details to be used for an error message
- in the future!) #3838 */
- return 0; /* Counts as if the transaction was not there */
+ in the future!) FIXME #3838 */
+ return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS;
}
- return 1;
+ return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
}
@@ -5439,10 +5543,12 @@ compute_shard (const struct TALER_EXCHANGEDB_Deposit *deposit)
GNUNET_assert (GNUNET_YES ==
GNUNET_CRYPTO_kdf (&res,
sizeof (res),
- &deposit->h_wire,
- sizeof (deposit->h_wire),
+ &deposit->wire_salt,
+ sizeof (deposit->wire_salt),
&deposit->merchant_pub,
sizeof (deposit->merchant_pub),
+ deposit->receiver_wire_account,
+ strlen (deposit->receiver_wire_account),
NULL, 0));
/* interpret hash result as NBO for platform independence,
convert to HBO and map to [0..2^31-1] range */
@@ -5468,32 +5574,46 @@ postgres_insert_deposit (void *cls,
const struct TALER_EXCHANGEDB_Deposit *deposit)
{
struct PostgresClosure *pg = cls;
- uint32_t shard = compute_shard (deposit);
- struct GNUNET_PQ_QueryParam params[] = {
- GNUNET_PQ_query_param_auto_from_type (&deposit->coin.coin_pub),
- TALER_PQ_query_param_amount (&deposit->amount_with_fee),
- TALER_PQ_query_param_absolute_time (&deposit->timestamp),
- TALER_PQ_query_param_absolute_time (&deposit->refund_deadline),
- TALER_PQ_query_param_absolute_time (&deposit->wire_deadline),
- GNUNET_PQ_query_param_auto_from_type (&deposit->merchant_pub),
- GNUNET_PQ_query_param_auto_from_type (&deposit->h_contract_terms),
- GNUNET_PQ_query_param_auto_from_type (&deposit->h_wire),
- GNUNET_PQ_query_param_auto_from_type (&deposit->csig),
- TALER_PQ_query_param_json (deposit->receiver_wire_account),
- TALER_PQ_query_param_absolute_time (&exchange_timestamp),
- GNUNET_PQ_query_param_uint32 (&shard),
- GNUNET_PQ_query_param_end
- };
+ struct TALER_EXCHANGEDB_KycStatus kyc;
+ enum GNUNET_DB_QueryStatus qs;
- GNUNET_assert (shard <= INT32_MAX);
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Inserting deposit to be executed at %s (%llu/%llu)\n",
- GNUNET_STRINGS_absolute_time_to_string (deposit->wire_deadline),
- (unsigned long long) deposit->wire_deadline.abs_value_us,
- (unsigned long long) deposit->refund_deadline.abs_value_us);
- return GNUNET_PQ_eval_prepared_non_select (pg->conn,
- "insert_deposit",
- params);
+ qs = inselect_account_kyc_status (pg,
+ deposit->receiver_wire_account,
+ &kyc);
+ if (qs <= 0)
+ {
+ GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs);
+ GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
+ return qs;
+ }
+ {
+ uint32_t shard = compute_shard (deposit);
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_auto_from_type (&deposit->coin.coin_pub),
+ TALER_PQ_query_param_amount (&deposit->amount_with_fee),
+ TALER_PQ_query_param_absolute_time (&deposit->timestamp),
+ TALER_PQ_query_param_absolute_time (&deposit->refund_deadline),
+ TALER_PQ_query_param_absolute_time (&deposit->wire_deadline),
+ GNUNET_PQ_query_param_auto_from_type (&deposit->merchant_pub),
+ GNUNET_PQ_query_param_auto_from_type (&deposit->h_contract_terms),
+ GNUNET_PQ_query_param_auto_from_type (&deposit->wire_salt),
+ GNUNET_PQ_query_param_uint64 (&kyc.payment_target_uuid),
+ GNUNET_PQ_query_param_auto_from_type (&deposit->csig),
+ TALER_PQ_query_param_absolute_time (&exchange_timestamp),
+ GNUNET_PQ_query_param_uint32 (&shard),
+ GNUNET_PQ_query_param_end
+ };
+
+ GNUNET_assert (shard <= INT32_MAX);
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Inserting deposit to be executed at %s (%llu/%llu)\n",
+ GNUNET_STRINGS_absolute_time_to_string (deposit->wire_deadline),
+ (unsigned long long) deposit->wire_deadline.abs_value_us,
+ (unsigned long long) deposit->refund_deadline.abs_value_us);
+ return GNUNET_PQ_eval_prepared_non_select (pg->conn,
+ "insert_deposit",
+ params);
+ }
}
@@ -6285,10 +6405,10 @@ add_coin_deposit (void *cls,
&deposit->merchant_pub),
GNUNET_PQ_result_spec_auto_from_type ("h_contract_terms",
&deposit->h_contract_terms),
- GNUNET_PQ_result_spec_auto_from_type ("h_wire",
- &deposit->h_wire),
- TALER_PQ_result_spec_json ("wire",
- &deposit->receiver_wire_account),
+ GNUNET_PQ_result_spec_auto_from_type ("wire_salt",
+ &deposit->wire_salt),
+ GNUNET_PQ_result_spec_string ("payto_uri",
+ &deposit->receiver_wire_account),
GNUNET_PQ_result_spec_auto_from_type ("coin_sig",
&deposit->csig),
GNUNET_PQ_result_spec_uint64 ("deposit_serial_id",
@@ -7813,8 +7933,10 @@ deposit_serial_helper_cb (void *cls,
&deposit.wire_deadline),
GNUNET_PQ_result_spec_auto_from_type ("h_contract_terms",
&deposit.h_contract_terms),
- TALER_PQ_result_spec_json ("wire",
- &deposit.receiver_wire_account),
+ GNUNET_PQ_result_spec_auto_from_type ("wire_salt",
+ &deposit.wire_salt),
+ GNUNET_PQ_result_spec_string ("receiver_wire_account",
+ &deposit.receiver_wire_account),
GNUNET_PQ_result_spec_auto_from_type ("done",
&done),
GNUNET_PQ_result_spec_uint64 ("deposit_serial_id",
@@ -7835,17 +7957,9 @@ deposit_serial_helper_cb (void *cls,
ret = dsc->cb (dsc->cb_cls,
rowid,
exchange_timestamp,
- deposit.timestamp,
- &deposit.merchant_pub,
+ &deposit,
&denom_pub,
- &deposit.coin.coin_pub,
- &deposit.csig,
- &deposit.amount_with_fee,
- &deposit.h_contract_terms,
- deposit.refund_deadline,
- deposit.wire_deadline,
- deposit.receiver_wire_account,
- done);
+ (0 != done) ? true : false);
GNUNET_PQ_cleanup_result (rs);
if (GNUNET_OK != ret)
break;
@@ -11402,6 +11516,7 @@ libtaler_plugin_exchangedb_postgres_init (void *cls)
plugin->get_known_coin = &postgres_get_known_coin;
plugin->get_coin_denomination = &postgres_get_coin_denomination;
plugin->have_deposit = &postgres_have_deposit;
+ plugin->have_deposit2 = &postgres_have_deposit2;
plugin->mark_deposit_tiny = &postgres_mark_deposit_tiny;
plugin->test_deposit_done = &postgres_test_deposit_done;
plugin->mark_deposit_done = &postgres_mark_deposit_done;
diff --git a/src/include/taler_exchange_service.h b/src/include/taler_exchange_service.h
index 72c233258..7f3436cce 100644
--- a/src/include/taler_exchange_service.h
+++ b/src/include/taler_exchange_service.h
@@ -889,7 +889,8 @@ typedef void
* @param amount the amount to be deposited
* @param wire_deadline execution date, until which the merchant would like the exchange to settle the balance (advisory, the exchange cannot be
* forced to settle in the past or upon very short notice, but of course a well-behaved exchange will limit aggregation based on the advice received)
- * @param wire_details the merchant’s account details, in a format supported by the exchange
+ * @param merchant_payto_uri the merchant’s account details, in the payto://-format supported by the exchange
+ * @param wire_salt salt used to hash the @a merchant_payto_uri
* @param h_contract_terms hash of the contact of the merchant with the customer (further details are never disclosed to the exchange)
* @param extension_details extension-specific details about the deposit relevant to the exchange
* @param coin_pub coin’s public key
@@ -910,7 +911,8 @@ TALER_EXCHANGE_deposit (
struct TALER_EXCHANGE_Handle *exchange,
const struct TALER_Amount *amount,
struct GNUNET_TIME_Absolute wire_deadline,
- const json_t *wire_details,
+ const char *merchant_payto_uri,
+ const struct TALER_WireSalt *wire_salt,
const struct TALER_PrivateContractHash *h_contract_terms,
const json_t *extension_details,
const struct TALER_CoinSpendPublicKeyP *coin_pub,
diff --git a/src/include/taler_exchangedb_plugin.h b/src/include/taler_exchangedb_plugin.h
index 8b01ee650..73a18ca6a 100644
--- a/src/include/taler_exchangedb_plugin.h
+++ b/src/include/taler_exchangedb_plugin.h
@@ -981,18 +981,15 @@ struct TALER_EXCHANGEDB_Deposit
struct TALER_PrivateContractHash h_contract_terms;
/**
- * Hash of the (canonical) representation of @e wire, used
- * to check the signature on the request. Generated by
- * the exchange from the detailed wire data provided by the
- * merchant.
+ * Salt used by the merchant to compute "h_wire".
*/
- struct TALER_MerchantWireHash h_wire;
+ struct TALER_WireSalt wire_salt;
/**
- * Detailed information about the receiver for executing the transaction.
- * Includes URL in payto://-format and salt.
+ * Information about the receiver for executing the transaction. URI in
+ * payto://-format.
*/
- json_t *receiver_wire_account;
+ char *receiver_wire_account;
/**
* Additional details for extensions relevant for this
@@ -1072,23 +1069,20 @@ struct TALER_EXCHANGEDB_DepositListEntry
struct TALER_PrivateContractHash h_contract_terms;
/**
- * Hash of the (canonical) representation of @e wire, used
- * to check the signature on the request. Generated by
- * the exchange from the detailed wire data provided by the
- * merchant.
- */
- struct TALER_MerchantWireHash h_wire;
-
- /**
* Hash of the public denomination key used to sign the coin.
*/
struct TALER_DenominationHash h_denom_pub;
/**
* Detailed information about the receiver for executing the transaction.
- * Includes URL in payto://-format and salt.
+ * URL in payto://-format.
*/
- json_t *receiver_wire_account;
+ char *receiver_wire_account;
+
+ /**
+ * Salt used to compute h_wire from the @e receiver_wire_account.
+ */
+ struct TALER_WireSalt wire_salt;
/**
* Time when this request was generated. Used, for example, to
@@ -1545,17 +1539,9 @@ typedef enum GNUNET_GenericReturnValue
void *cls,
uint64_t rowid,
struct GNUNET_TIME_Absolute exchange_timestamp,
- struct GNUNET_TIME_Absolute wallet_timestamp,
- const struct TALER_MerchantPublicKeyP *merchant_pub,
+ const struct TALER_EXCHANGEDB_Deposit *deposit,
const struct TALER_DenominationPublicKey *denom_pub,
- const struct TALER_CoinSpendPublicKeyP *coin_pub,
- const struct TALER_CoinSpendSignatureP *coin_sig,
- const struct TALER_Amount *amount_with_fee,
- const struct TALER_PrivateContractHash *h_contract_terms,
- struct GNUNET_TIME_Absolute refund_deadline,
- struct GNUNET_TIME_Absolute wire_deadline,
- const json_t *receiver_wire_account,
- int done);
+ bool done);
/**
@@ -2627,7 +2613,6 @@ struct TALER_EXCHANGEDB_Plugin
*
* @param cls the @e cls of this struct with the plugin-specific state
* @param deposit deposit to search for
- * @param check_extras whether to check extra fields or not
* @param[out] deposit_fee set to the deposit fee the exchange charged
* @param[out] exchange_timestamp set to the time when the exchange received the deposit
* @return 1 if we know this operation,
@@ -2637,12 +2622,38 @@ struct TALER_EXCHANGEDB_Plugin
enum GNUNET_DB_QueryStatus
(*have_deposit)(void *cls,
const struct TALER_EXCHANGEDB_Deposit *deposit,
- int check_extras,
struct TALER_Amount *deposit_fee,
struct GNUNET_TIME_Absolute *exchange_timestamp);
/**
+ * Check if we have the specified deposit already in the database.
+ *
+ * @param cls the `struct PostgresClosure` with the plugin-specific state
+ * @param h_contract_terms contract to check for
+ * @param h_wire wire hash to check for
+ * @param coin_pub public key of the coin to check for
+ * @param merchant merchant public key to check for
+ * @param refund_deadline expected refund deadline
+ * @param[out] deposit_fee set to the deposit fee the exchange charged
+ * @param[out] exchange_timestamp set to the time when the exchange received the deposit
+ * @return 1 if we know this operation,
+ * 0 if this exact deposit is unknown to us,
+ * otherwise transaction error status
+ */
+ enum GNUNET_DB_QueryStatus
+ (*have_deposit2)(
+ void *cls,
+ const struct TALER_PrivateContractHash *h_contract_terms,
+ const struct TALER_MerchantWireHash *h_wire,
+ const struct TALER_CoinSpendPublicKeyP *coin_pub,
+ const struct TALER_MerchantPublicKeyP *merchant,
+ struct GNUNET_TIME_Absolute refund_deadline,
+ struct TALER_Amount *deposit_fee,
+ struct GNUNET_TIME_Absolute *exchange_timestamp);
+
+
+ /**
* Insert information about deposited coin into the database.
*
* @param cls the @e cls of this struct with the plugin-specific state
diff --git a/src/lib/exchange_api_deposit.c b/src/lib/exchange_api_deposit.c
index 62932d990..8abb73518 100644
--- a/src/lib/exchange_api_deposit.c
+++ b/src/lib/exchange_api_deposit.c
@@ -543,7 +543,8 @@ TALER_EXCHANGE_deposit (
struct TALER_EXCHANGE_Handle *exchange,
const struct TALER_Amount *amount,
struct GNUNET_TIME_Absolute wire_deadline,
- const json_t *wire_details,
+ const char *merchant_payto_uri,
+ const struct TALER_WireSalt *wire_salt,
const struct TALER_PrivateContractHash *h_contract_terms,
const json_t *extension_details,
const struct TALER_CoinSpendPublicKeyP *coin_pub,
@@ -594,14 +595,9 @@ TALER_EXCHANGE_deposit (
GNUNET_assert (GNUNET_YES ==
TEAH_handle_is_ready (exchange));
/* initialize h_wire */
- if (GNUNET_OK !=
- TALER_JSON_merchant_wire_signature_hash (wire_details,
- &h_wire))
- {
- GNUNET_break (0);
- *ec = TALER_EC_GENERIC_FAILED_COMPUTE_JSON_HASH;
- return NULL;
- }
+ TALER_merchant_wire_signature_hash (merchant_payto_uri,
+ wire_salt,
+ &h_wire);
key_state = TALER_EXCHANGE_get_keys (exchange);
dki = TALER_EXCHANGE_get_denomination_key (key_state,
denom_pub);
@@ -644,10 +640,10 @@ TALER_EXCHANGE_deposit (
deposit_obj = GNUNET_JSON_PACK (
TALER_JSON_pack_amount ("contribution",
amount),
- GNUNET_JSON_pack_object_incref ("wire",
- (json_t *) wire_details),
- GNUNET_JSON_pack_data_auto ("h_wire",
- &h_wire),
+ GNUNET_JSON_pack_string ("merchant_payto_uri",
+ merchant_payto_uri),
+ GNUNET_JSON_pack_data_auto ("wire_salt",
+ wire_salt),
GNUNET_JSON_pack_data_auto ("h_contract_terms",
h_contract_terms),
GNUNET_JSON_pack_data_auto ("denom_pub_hash",
diff --git a/src/testing/testing_api_cmd_deposit.c b/src/testing/testing_api_cmd_deposit.c
index 7e944b6ee..81e9814de 100644
--- a/src/testing/testing_api_cmd_deposit.c
+++ b/src/testing/testing_api_cmd_deposit.c
@@ -289,7 +289,25 @@ deposit_run (void *cls,
struct TALER_MerchantPublicKeyP merchant_pub;
struct TALER_PrivateContractHash h_contract_terms;
enum TALER_ErrorCode ec;
+ struct TALER_WireSalt wire_salt;
+ const char *payto_uri;
+ struct GNUNET_JSON_Specification spec[] = {
+ GNUNET_JSON_spec_string ("payto_uri",
+ &payto_uri),
+ GNUNET_JSON_spec_fixed_auto ("salt",
+ &wire_salt),
+ GNUNET_JSON_spec_end ()
+ };
+ if (GNUNET_OK !=
+ GNUNET_JSON_parse (ds->wire_details,
+ spec,
+ NULL, NULL))
+ {
+ GNUNET_break (0);
+ TALER_TESTING_interpreter_fail (is);
+ return;
+ }
(void) cmd;
ds->is = is;
if (NULL != ds->deposit_reference)
@@ -412,7 +430,8 @@ deposit_run (void *cls,
ds->dh = TALER_EXCHANGE_deposit (is->exchange,
&ds->amount,
wire_deadline,
- ds->wire_details,
+ payto_uri,
+ &wire_salt,
&h_contract_terms,
NULL, /* FIXME: extension object */
&coin_pub,
diff --git a/src/testing/testing_api_cmd_insert_deposit.c b/src/testing/testing_api_cmd_insert_deposit.c
index 222ef758a..cc427ff5e 100644
--- a/src/testing/testing_api_cmd_insert_deposit.c
+++ b/src/testing/testing_api_cmd_insert_deposit.c
@@ -203,29 +203,12 @@ insert_deposit_run (void *cls,
deposit.coin.denom_sig.details.rsa_signature
= GNUNET_CRYPTO_rsa_sign_fdh (denom_priv,
&hc);
- {
- char *str;
- struct TALER_WireSalt salt;
-
- GNUNET_asprintf (&str,
- "payto://x-taler-bank/localhost/%s",
- ids->merchant_account);
- memset (&salt,
- 46,
- sizeof (salt));
- deposit.receiver_wire_account
- = GNUNET_JSON_PACK (
- GNUNET_JSON_pack_data_auto ("salt",
- &salt),
- GNUNET_JSON_pack_string ("payto_uri",
- str));
- GNUNET_free (str);
- }
-
- GNUNET_assert (GNUNET_OK ==
- TALER_JSON_merchant_wire_signature_hash (
- deposit.receiver_wire_account,
- &deposit.h_wire));
+ GNUNET_asprintf (&deposit.receiver_wire_account,
+ "payto://x-taler-bank/localhost/%s",
+ ids->merchant_account);
+ memset (&deposit.wire_salt,
+ 46,
+ sizeof (deposit.wire_salt));
deposit.timestamp = GNUNET_TIME_absolute_get ();
(void) GNUNET_TIME_round_abs (&deposit.timestamp);
deposit.wire_deadline = GNUNET_TIME_relative_to_absolute (ids->wire_deadline);
@@ -247,14 +230,15 @@ insert_deposit_run (void *cls,
{
GNUNET_break (0);
ids->dbc->plugin->rollback (ids->dbc->plugin->cls);
+ GNUNET_free (deposit.receiver_wire_account);
TALER_TESTING_interpreter_fail (is);
+ return;
}
TALER_denom_sig_free (&deposit.coin.denom_sig);
TALER_denom_pub_free (&dpk);
GNUNET_CRYPTO_rsa_private_key_free (denom_priv);
- json_decref (deposit.receiver_wire_account);
-
+ GNUNET_free (deposit.receiver_wire_account);
TALER_TESTING_interpreter_next (is);
}