fix more FTBFS issues

This commit is contained in:
Christian Grothoff 2021-10-30 19:28:11 +02:00
parent 55ea7fcb9a
commit 963a06c0aa
No known key found for this signature in database
GPG Key ID: 939E6BE1E29FC3CC
13 changed files with 341 additions and 327 deletions

View File

@ -440,27 +440,6 @@ check_transaction_history_for_deposit (
{ {
case TALER_EXCHANGEDB_TT_DEPOSIT: case TALER_EXCHANGEDB_TT_DEPOSIT:
/* check wire and h_wire are consistent */ /* 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*/ amount_with_fee = &tl->details.deposit->amount_with_fee; /* according to exchange*/
fee_claimed = &tl->details.deposit->deposit_fee; /* Fee according to exchange DB */ fee_claimed = &tl->details.deposit->deposit_fee; /* Fee according to exchange DB */
TALER_ARL_amount_add (&expenditures, TALER_ARL_amount_add (&expenditures,

View File

@ -1556,18 +1556,8 @@ refresh_session_cb (void *cls,
* @param cls closure * @param cls closure
* @param rowid unique serial ID for the deposit in our DB * @param rowid unique serial ID for the deposit in our DB
* @param exchange_timestamp when did the exchange get the deposit * @param exchange_timestamp when did the exchange get the deposit
* @param wallet_timestamp when did the contract signing happen * @param deposit deposit details
* @param merchant_pub public key of the merchant
* @param denom_pub denomination public key of @a coin_pub * @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) * @param done flag set if the deposit was already executed (or not)
* @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop
*/ */
@ -1575,17 +1565,9 @@ static enum GNUNET_GenericReturnValue
deposit_cb (void *cls, deposit_cb (void *cls,
uint64_t rowid, uint64_t rowid,
struct GNUNET_TIME_Absolute exchange_timestamp, struct GNUNET_TIME_Absolute exchange_timestamp,
struct GNUNET_TIME_Absolute wallet_timestamp, const struct TALER_EXCHANGEDB_Deposit *deposit,
const struct TALER_MerchantPublicKeyP *merchant_pub,
const struct TALER_DenominationPublicKey *denom_pub, const struct TALER_DenominationPublicKey *denom_pub,
const struct TALER_CoinSpendPublicKeyP *coin_pub, bool done)
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)
{ {
struct CoinContext *cc = cls; struct CoinContext *cc = cls;
const struct TALER_DenominationKeyValidityPS *issue; const struct TALER_DenominationKeyValidityPS *issue;
@ -1608,8 +1590,8 @@ deposit_cb (void *cls,
return GNUNET_SYSERR; return GNUNET_SYSERR;
return GNUNET_OK; return GNUNET_OK;
} }
if (refund_deadline.abs_value_us > if (deposit->refund_deadline.abs_value_us >
wire_deadline.abs_value_us) deposit->wire_deadline.abs_value_us)
{ {
report_row_inconsistency ("deposits", report_row_inconsistency ("deposits",
rowid, rowid,
@ -1625,9 +1607,9 @@ deposit_cb (void *cls,
qs = check_known_coin ("deposit", qs = check_known_coin ("deposit",
issue, issue,
rowid, rowid,
coin_pub, &deposit->coin.coin_pub,
denom_pub, denom_pub,
amount_with_fee); &deposit->amount_with_fee);
if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs) if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs)
{ {
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
@ -1640,47 +1622,29 @@ deposit_cb (void *cls,
struct TALER_DepositRequestPS dr = { struct TALER_DepositRequestPS dr = {
.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_DEPOSIT), .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_DEPOSIT),
.purpose.size = htonl (sizeof (dr)), .purpose.size = htonl (sizeof (dr)),
.h_contract_terms = *h_contract_terms, .h_contract_terms = deposit->h_contract_terms,
.wallet_timestamp = GNUNET_TIME_absolute_hton (wallet_timestamp), .wallet_timestamp = GNUNET_TIME_absolute_hton (deposit->timestamp),
.refund_deadline = GNUNET_TIME_absolute_hton (refund_deadline), .refund_deadline = GNUNET_TIME_absolute_hton (deposit->refund_deadline),
.deposit_fee = issue->fee_deposit, .deposit_fee = issue->fee_deposit,
.merchant = *merchant_pub, .merchant = deposit->merchant_pub,
.coin_pub = *coin_pub .coin_pub = deposit->coin.coin_pub
}; };
TALER_denom_pub_hash (denom_pub, TALER_denom_pub_hash (denom_pub,
&dr.h_denom_pub); &dr.h_denom_pub);
if (GNUNET_OK != TALER_merchant_wire_signature_hash (deposit->receiver_wire_account,
TALER_JSON_merchant_wire_signature_hash (receiver_wire_account, &deposit->wire_salt,
&dr.h_wire)) &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_amount_hton (&dr.amount_with_fee, TALER_amount_hton (&dr.amount_with_fee,
amount_with_fee); &deposit->amount_with_fee);
/* NOTE: This is one of the operations we might eventually /* NOTE: This is one of the operations we might eventually
want to do in parallel in the background to improve want to do in parallel in the background to improve
auditor performance! */ auditor performance! */
if (GNUNET_OK != if (GNUNET_OK !=
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_DEPOSIT, GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_DEPOSIT,
&dr, &dr,
&coin_sig->eddsa_signature, &deposit->csig.eddsa_signature,
&coin_pub->eddsa_pub)) &deposit->coin.coin_pub.eddsa_pub))
{ {
TALER_ARL_report (report_bad_sig_losses, TALER_ARL_report (report_bad_sig_losses,
GNUNET_JSON_PACK ( GNUNET_JSON_PACK (
@ -1689,12 +1653,12 @@ deposit_cb (void *cls,
GNUNET_JSON_pack_uint64 ("row", GNUNET_JSON_pack_uint64 ("row",
rowid), rowid),
TALER_JSON_pack_amount ("loss", TALER_JSON_pack_amount ("loss",
amount_with_fee), &deposit->amount_with_fee),
GNUNET_JSON_pack_data_auto ("coin_pub", GNUNET_JSON_pack_data_auto ("coin_pub",
coin_pub))); &deposit->coin.coin_pub)));
TALER_ARL_amount_add (&total_bad_sig_loss, TALER_ARL_amount_add (&total_bad_sig_loss,
&total_bad_sig_loss, &total_bad_sig_loss,
amount_with_fee); &deposit->amount_with_fee);
if (TALER_ARL_do_abort ()) if (TALER_ARL_do_abort ())
return GNUNET_SYSERR; return GNUNET_SYSERR;
return GNUNET_OK; return GNUNET_OK;
@ -1702,9 +1666,9 @@ deposit_cb (void *cls,
} }
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Deposited coin %s in denomination `%s' of value %s\n", "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), GNUNET_h2s (&issue->denom_hash.hash),
TALER_amount2s (amount_with_fee)); TALER_amount2s (&deposit->amount_with_fee));
/* update old coin's denomination balance */ /* update old coin's denomination balance */
ds = get_denomination_summary (cc, ds = get_denomination_summary (cc,
@ -1723,11 +1687,11 @@ deposit_cb (void *cls,
if (TALER_ARL_SR_INVALID_NEGATIVE == if (TALER_ARL_SR_INVALID_NEGATIVE ==
TALER_ARL_amount_subtract_neg (&tmp, TALER_ARL_amount_subtract_neg (&tmp,
&ds->denom_balance, &ds->denom_balance,
amount_with_fee)) &deposit->amount_with_fee))
{ {
TALER_ARL_amount_add (&ds->denom_loss, TALER_ARL_amount_add (&ds->denom_loss,
&ds->denom_loss, &ds->denom_loss,
amount_with_fee); &deposit->amount_with_fee);
ds->report_emergency = GNUNET_YES; ds->report_emergency = GNUNET_YES;
} }
else else
@ -1736,7 +1700,7 @@ deposit_cb (void *cls,
} }
if (-1 == TALER_amount_cmp (&total_escrow_balance, if (-1 == TALER_amount_cmp (&total_escrow_balance,
amount_with_fee)) &deposit->amount_with_fee))
{ {
/* This can theoretically happen if for example the exchange /* This can theoretically happen if for example the exchange
never issued any coins (i.e. escrow balance is zero), but 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", "subtracting deposit fee from escrow balance",
rowid, rowid,
&total_escrow_balance, &total_escrow_balance,
amount_with_fee, &deposit->amount_with_fee,
0); 0);
} }
else else
{ {
TALER_ARL_amount_subtract (&total_escrow_balance, TALER_ARL_amount_subtract (&total_escrow_balance,
&total_escrow_balance, &total_escrow_balance,
amount_with_fee); &deposit->amount_with_fee);
} }
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,

View File

@ -112,21 +112,17 @@ test_dc (void *cls,
dcc->last_seen_coin_serial = serial_id; dcc->last_seen_coin_serial = serial_id;
{ {
enum GNUNET_DB_QueryStatus qs; 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 GNUNET_TIME_Absolute exchange_timestamp;
struct TALER_Amount deposit_fee; struct TALER_Amount deposit_fee;
qs = TALER_ARL_edb->have_deposit (TALER_ARL_edb->cls, qs = TALER_ARL_edb->have_deposit2 (TALER_ARL_edb->cls,
&dep, &dc->h_contract_terms,
GNUNET_NO /* do not check refund deadline */, &dc->h_wire,
&deposit_fee, &dc->coin_pub,
&exchange_timestamp); &dc->merchant,
dc->refund_deadline,
&deposit_fee,
&exchange_timestamp);
if (qs > 0) if (qs > 0)
{ {
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,

View File

@ -58,11 +58,6 @@ static unsigned int refund_rate = 0;
*/ */
static char *currency; static char *currency;
/**
* Merchant JSON wire details.
*/
static json_t *json_wire;
/** /**
* Configuration. * Configuration.
*/ */
@ -213,11 +208,6 @@ do_shutdown (void *cls)
task = NULL; task = NULL;
} }
TALER_denom_sig_free (&denom_sig); 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; 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 struct Deposit
@ -320,9 +320,8 @@ add_deposit (const struct Merchant *m)
RANDOMIZE (&deposit.csig); RANDOMIZE (&deposit.csig);
deposit.merchant_pub = m->merchant_pub; deposit.merchant_pub = m->merchant_pub;
deposit.h_contract_terms = d.h_contract_terms; deposit.h_contract_terms = d.h_contract_terms;
deposit.h_wire = m->h_wire; deposit.wire_salt = m->wire_salt;
deposit.receiver_wire_account deposit.receiver_wire_account = m->payto_uri;
= json_wire;
deposit.timestamp = random_time (); deposit.timestamp = random_time ();
deposit.refund_deadline = random_time (); deposit.refund_deadline = random_time ();
deposit.wire_deadline = random_time (); deposit.wire_deadline = random_time ();
@ -355,7 +354,6 @@ static void
work (void *cls) work (void *cls)
{ {
struct Merchant m; struct Merchant m;
char *acc;
uint64_t rnd1; uint64_t rnd1;
uint64_t rnd2; uint64_t rnd2;
@ -365,33 +363,22 @@ work (void *cls)
UINT64_MAX); UINT64_MAX);
rnd2 = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_NONCE, rnd2 = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_NONCE,
UINT64_MAX); UINT64_MAX);
GNUNET_asprintf (&acc, GNUNET_asprintf (&m.payto_uri,
"payto://x-taler-bank/localhost:8082/account-%llX-%llX", "payto://x-taler-bank/localhost:8082/account-%llX-%llX",
(unsigned long long) rnd1, (unsigned long long) rnd1,
(unsigned long long) rnd2); (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); RANDOMIZE (&m.merchant_pub);
if (GNUNET_OK != RANDOMIZE (&m.wire_salt);
TALER_JSON_merchant_wire_signature_hash (json_wire, TALER_merchant_wire_signature_hash (m.payto_uri,
&m.h_wire)) &m.wire_salt,
{ &m.h_wire);
GNUNET_break (0);
global_ret = EXIT_FAILURE;
GNUNET_SCHEDULER_shutdown ();
return;
}
if (GNUNET_OK != if (GNUNET_OK !=
plugin->start (plugin->cls, plugin->start (plugin->cls,
"aggregator-benchmark-fill")) "aggregator-benchmark-fill"))
{ {
GNUNET_break (0); GNUNET_break (0);
global_ret = EXIT_FAILURE; global_ret = EXIT_FAILURE;
GNUNET_free (m.payto_uri);
GNUNET_SCHEDULER_shutdown (); GNUNET_SCHEDULER_shutdown ();
return; return;
} }
@ -401,6 +388,7 @@ work (void *cls)
{ {
global_ret = EXIT_FAILURE; global_ret = EXIT_FAILURE;
GNUNET_SCHEDULER_shutdown (); GNUNET_SCHEDULER_shutdown ();
GNUNET_free (m.payto_uri);
return; return;
} }
} }
@ -410,6 +398,7 @@ work (void *cls)
if (0 == --howmany_merchants) if (0 == --howmany_merchants)
{ {
GNUNET_SCHEDULER_shutdown (); GNUNET_SCHEDULER_shutdown ();
GNUNET_free (m.payto_uri);
return; return;
} }
} }
@ -418,8 +407,7 @@ work (void *cls)
GNUNET_log (GNUNET_ERROR_TYPE_WARNING, GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
"Failed to commit, will try again\n"); "Failed to commit, will try again\n");
} }
json_decref (json_wire); GNUNET_free (m.payto_uri);
json_wire = NULL;
task = GNUNET_SCHEDULER_add_now (&work, task = GNUNET_SCHEDULER_add_now (&work,
NULL); NULL);
} }

View File

@ -116,6 +116,11 @@ struct DepositContext
*/ */
struct GNUNET_TIME_Absolute exchange_timestamp; struct GNUNET_TIME_Absolute exchange_timestamp;
/**
* Calculated hash over the wire details.
*/
struct TALER_MerchantWireHash h_wire;
/** /**
* Value of the coin. * Value of the coin.
*/ */
@ -124,7 +129,7 @@ struct DepositContext
/** /**
* payto:// URI of the credited account. * 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, qs = TEH_plugin->have_deposit (TEH_plugin->cls,
deposit, deposit,
GNUNET_YES /* check refund deadline */,
&deposit_fee, &deposit_fee,
&dc->exchange_timestamp); &dc->exchange_timestamp);
if (qs < 0) if (qs < 0)
@ -179,7 +183,7 @@ deposit_precheck (void *cls,
&deposit_fee)); &deposit_fee));
*mhd_ret = reply_deposit_success (connection, *mhd_ret = reply_deposit_success (connection,
&deposit->coin.coin_pub, &deposit->coin.coin_pub,
&deposit->h_wire, &dc->h_wire,
&deposit->h_contract_terms, &deposit->h_contract_terms,
dc->exchange_timestamp, dc->exchange_timestamp,
deposit->refund_deadline, deposit->refund_deadline,
@ -318,13 +322,13 @@ TEH_handler_deposit (struct MHD_Connection *connection,
const struct TALER_CoinSpendPublicKeyP *coin_pub, const struct TALER_CoinSpendPublicKeyP *coin_pub,
const json_t *root) const json_t *root)
{ {
json_t *wire;
struct DepositContext dc; struct DepositContext dc;
struct TALER_EXCHANGEDB_Deposit deposit; struct TALER_EXCHANGEDB_Deposit deposit;
struct TALER_MerchantWireHash my_h_wire;
struct GNUNET_JSON_Specification spec[] = { struct GNUNET_JSON_Specification spec[] = {
GNUNET_JSON_spec_json ("wire", GNUNET_JSON_spec_string ("merchant_payto_uri",
&wire), &dc.payto_uri),
GNUNET_JSON_spec_fixed_auto ("wire_salt",
&deposit.wire_salt),
TALER_JSON_spec_amount ("contribution", TALER_JSON_spec_amount ("contribution",
TEH_currency, TEH_currency,
&deposit.amount_with_fee), &deposit.amount_with_fee),
@ -336,8 +340,6 @@ TEH_handler_deposit (struct MHD_Connection *connection,
&deposit.merchant_pub), &deposit.merchant_pub),
GNUNET_JSON_spec_fixed_auto ("h_contract_terms", GNUNET_JSON_spec_fixed_auto ("h_contract_terms",
&deposit.h_contract_terms), &deposit.h_contract_terms),
GNUNET_JSON_spec_fixed_auto ("h_wire",
&deposit.h_wire),
GNUNET_JSON_spec_fixed_auto ("coin_sig", GNUNET_JSON_spec_fixed_auto ("coin_sig",
&deposit.csig), &deposit.csig),
TALER_JSON_spec_absolute_time ("timestamp", TALER_JSON_spec_absolute_time ("timestamp",
@ -375,16 +377,6 @@ TEH_handler_deposit (struct MHD_Connection *connection,
{ {
char *emsg; 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); emsg = TALER_payto_validate (dc.payto_uri);
if (NULL != emsg) if (NULL != emsg)
{ {
@ -397,46 +389,22 @@ TEH_handler_deposit (struct MHD_Connection *connection,
TALER_EC_GENERIC_PARAMETER_MALFORMED, TALER_EC_GENERIC_PARAMETER_MALFORMED,
emsg); emsg);
GNUNET_free (emsg); GNUNET_free (emsg);
GNUNET_free (dc.payto_uri);
return ret; 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) if (deposit.refund_deadline.abs_value_us > deposit.wire_deadline.abs_value_us)
{ {
GNUNET_break_op (0); GNUNET_break_op (0);
GNUNET_JSON_parse_free (spec); GNUNET_JSON_parse_free (spec);
GNUNET_free (dc.payto_uri);
return TALER_MHD_reply_with_error (connection, return TALER_MHD_reply_with_error (connection,
MHD_HTTP_BAD_REQUEST, MHD_HTTP_BAD_REQUEST,
TALER_EC_EXCHANGE_DEPOSIT_REFUND_DEADLINE_AFTER_WIRE_DEADLINE, TALER_EC_EXCHANGE_DEPOSIT_REFUND_DEADLINE_AFTER_WIRE_DEADLINE,
NULL); NULL);
} }
if (GNUNET_OK != TALER_merchant_wire_signature_hash (dc.payto_uri,
TALER_JSON_merchant_wire_signature_hash (wire, &deposit.wire_salt,
&my_h_wire)) &dc.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);
}
/* Check for idempotency: did we get this request before? */ /* Check for idempotency: did we get this request before? */
dc.deposit = &deposit; dc.deposit = &deposit;
{ {
@ -450,7 +418,6 @@ TEH_handler_deposit (struct MHD_Connection *connection,
&dc)) &dc))
{ {
GNUNET_JSON_parse_free (spec); GNUNET_JSON_parse_free (spec);
GNUNET_free (dc.payto_uri);
return mhd_ret; return mhd_ret;
} }
} }
@ -469,7 +436,6 @@ TEH_handler_deposit (struct MHD_Connection *connection,
if (NULL == dk) if (NULL == dk)
{ {
GNUNET_JSON_parse_free (spec); GNUNET_JSON_parse_free (spec);
GNUNET_free (dc.payto_uri);
return mret; return mret;
} }
if (GNUNET_TIME_absolute_is_past (dk->meta.expire_deposit)) 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 (); now = GNUNET_TIME_absolute_get ();
(void) GNUNET_TIME_round_abs (&now); (void) GNUNET_TIME_round_abs (&now);
GNUNET_JSON_parse_free (spec); GNUNET_JSON_parse_free (spec);
GNUNET_free (dc.payto_uri);
return TEH_RESPONSE_reply_expired_denom_pub_hash ( return TEH_RESPONSE_reply_expired_denom_pub_hash (
connection, connection,
&deposit.coin.denom_pub_hash, &deposit.coin.denom_pub_hash,
@ -496,7 +461,6 @@ TEH_handler_deposit (struct MHD_Connection *connection,
now = GNUNET_TIME_absolute_get (); now = GNUNET_TIME_absolute_get ();
(void) GNUNET_TIME_round_abs (&now); (void) GNUNET_TIME_round_abs (&now);
GNUNET_JSON_parse_free (spec); GNUNET_JSON_parse_free (spec);
GNUNET_free (dc.payto_uri);
return TEH_RESPONSE_reply_expired_denom_pub_hash ( return TEH_RESPONSE_reply_expired_denom_pub_hash (
connection, connection,
&deposit.coin.denom_pub_hash, &deposit.coin.denom_pub_hash,
@ -512,7 +476,6 @@ TEH_handler_deposit (struct MHD_Connection *connection,
(void) GNUNET_TIME_round_abs (&now); (void) GNUNET_TIME_round_abs (&now);
/* This denomination has been revoked */ /* This denomination has been revoked */
GNUNET_JSON_parse_free (spec); GNUNET_JSON_parse_free (spec);
GNUNET_free (dc.payto_uri);
return TEH_RESPONSE_reply_expired_denom_pub_hash ( return TEH_RESPONSE_reply_expired_denom_pub_hash (
connection, connection,
&deposit.coin.denom_pub_hash, &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"); TALER_LOG_WARNING ("Invalid coin passed for /deposit\n");
GNUNET_JSON_parse_free (spec); GNUNET_JSON_parse_free (spec);
GNUNET_free (dc.payto_uri);
return TALER_MHD_reply_with_error (connection, return TALER_MHD_reply_with_error (connection,
MHD_HTTP_UNAUTHORIZED, MHD_HTTP_UNAUTHORIZED,
TALER_EC_EXCHANGE_DENOMINATION_SIGNATURE_INVALID, TALER_EC_EXCHANGE_DENOMINATION_SIGNATURE_INVALID,
@ -542,7 +504,6 @@ TEH_handler_deposit (struct MHD_Connection *connection,
{ {
GNUNET_break_op (0); GNUNET_break_op (0);
GNUNET_JSON_parse_free (spec); GNUNET_JSON_parse_free (spec);
GNUNET_free (dc.payto_uri);
return TALER_MHD_reply_with_error (connection, return TALER_MHD_reply_with_error (connection,
MHD_HTTP_BAD_REQUEST, MHD_HTTP_BAD_REQUEST,
TALER_EC_EXCHANGE_DEPOSIT_NEGATIVE_VALUE_AFTER_FEE, 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.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_DEPOSIT),
.purpose.size = htonl (sizeof (dr)), .purpose.size = htonl (sizeof (dr)),
.h_contract_terms = deposit.h_contract_terms, .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, .h_denom_pub = deposit.coin.denom_pub_hash,
.wallet_timestamp = GNUNET_TIME_absolute_hton (deposit.timestamp), .wallet_timestamp = GNUNET_TIME_absolute_hton (deposit.timestamp),
.refund_deadline = GNUNET_TIME_absolute_hton (deposit.refund_deadline), .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"); TALER_LOG_WARNING ("Invalid signature on /deposit request\n");
GNUNET_JSON_parse_free (spec); GNUNET_JSON_parse_free (spec);
GNUNET_free (dc.payto_uri);
return TALER_MHD_reply_with_error (connection, return TALER_MHD_reply_with_error (connection,
MHD_HTTP_UNAUTHORIZED, MHD_HTTP_UNAUTHORIZED,
TALER_EC_EXCHANGE_DEPOSIT_COIN_SIGNATURE_INVALID, TALER_EC_EXCHANGE_DEPOSIT_COIN_SIGNATURE_INVALID,
@ -595,11 +555,9 @@ TEH_handler_deposit (struct MHD_Connection *connection,
&dc)) &dc))
{ {
GNUNET_JSON_parse_free (spec); GNUNET_JSON_parse_free (spec);
GNUNET_free (dc.payto_uri);
return mhd_ret; return mhd_ret;
} }
} }
GNUNET_free (dc.payto_uri);
/* generate regular response */ /* generate regular response */
{ {
@ -612,7 +570,7 @@ TEH_handler_deposit (struct MHD_Connection *connection,
&deposit.deposit_fee)); &deposit.deposit_fee));
res = reply_deposit_success (connection, res = reply_deposit_success (connection,
&deposit.coin.coin_pub, &deposit.coin.coin_pub,
&deposit.h_wire, &dc.h_wire,
&deposit.h_contract_terms, &deposit.h_contract_terms,
dc.exchange_timestamp, dc.exchange_timestamp,
deposit.refund_deadline, deposit.refund_deadline,

View File

@ -65,7 +65,6 @@ TEH_RESPONSE_compile_transaction_history (
.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_DEPOSIT), .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_DEPOSIT),
.purpose.size = htonl (sizeof (dr)), .purpose.size = htonl (sizeof (dr)),
.h_contract_terms = deposit->h_contract_terms, .h_contract_terms = deposit->h_contract_terms,
.h_wire = deposit->h_wire,
.h_denom_pub = deposit->h_denom_pub, .h_denom_pub = deposit->h_denom_pub,
.wallet_timestamp = GNUNET_TIME_absolute_hton (deposit->timestamp), .wallet_timestamp = GNUNET_TIME_absolute_hton (deposit->timestamp),
.refund_deadline = GNUNET_TIME_absolute_hton ( .refund_deadline = GNUNET_TIME_absolute_hton (
@ -74,6 +73,10 @@ TEH_RESPONSE_compile_transaction_history (
.coin_pub = *coin_pub .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, TALER_amount_hton (&dr.amount_with_fee,
&deposit->amount_with_fee); &deposit->amount_with_fee);
TALER_amount_hton (&dr.deposit_fee, TALER_amount_hton (&dr.deposit_fee,
@ -111,7 +114,7 @@ TEH_RESPONSE_compile_transaction_history (
GNUNET_JSON_pack_data_auto ("h_contract_terms", GNUNET_JSON_pack_data_auto ("h_contract_terms",
&deposit->h_contract_terms), &deposit->h_contract_terms),
GNUNET_JSON_pack_data_auto ("h_wire", GNUNET_JSON_pack_data_auto ("h_wire",
&deposit->h_wire), &dr.h_wire),
GNUNET_JSON_pack_data_auto ("h_denom_pub", GNUNET_JSON_pack_data_auto ("h_denom_pub",
&deposit->h_denom_pub), &deposit->h_denom_pub),
GNUNET_JSON_pack_data_auto ("coin_sig", GNUNET_JSON_pack_data_auto ("coin_sig",

View File

@ -103,8 +103,7 @@ common_free_coin_transaction_list (void *cls,
struct TALER_EXCHANGEDB_DepositListEntry *deposit; struct TALER_EXCHANGEDB_DepositListEntry *deposit;
deposit = tl->details.deposit; deposit = tl->details.deposit;
if (NULL != deposit->receiver_wire_account) GNUNET_free (deposit->receiver_wire_account);
json_decref (deposit->receiver_wire_account);
GNUNET_free (deposit); GNUNET_free (deposit);
break; break;
} }

View File

@ -933,9 +933,9 @@ prepare_statements (struct PostgresClosure *pg)
",wire_deadline" ",wire_deadline"
",merchant_pub" ",merchant_pub"
",h_contract_terms" ",h_contract_terms"
",h_wire" ",wire_salt"
",wire_target_serial_id"
",coin_sig" ",coin_sig"
",wire"
",exchange_timestamp" ",exchange_timestamp"
",shard" ",shard"
") SELECT known_coin_id, $2, $3, $4, $5, $6, " ") SELECT known_coin_id, $2, $3, $4, $5, $6, "
@ -956,10 +956,12 @@ prepare_statements (struct PostgresClosure *pg)
",refund_deadline" ",refund_deadline"
",wire_deadline" ",wire_deadline"
",h_contract_terms" ",h_contract_terms"
",h_wire" ",wire_salt"
",payto_uri AS receiver_wire_account"
" FROM deposits" " FROM deposits"
" JOIN known_coins USING (known_coin_id)" " JOIN known_coins USING (known_coin_id)"
" JOIN denominations USING (denominations_serial)" " JOIN denominations USING (denominations_serial)"
" JOIN wire_targets USING (wire_target_serial_id)"
" WHERE ((coin_pub=$1)" " WHERE ((coin_pub=$1)"
" AND (merchant_pub=$3)" " AND (merchant_pub=$3)"
" AND (h_contract_terms=$2));", " AND (h_contract_terms=$2));",
@ -978,10 +980,12 @@ prepare_statements (struct PostgresClosure *pg)
",refund_deadline" ",refund_deadline"
",wire_deadline" ",wire_deadline"
",h_contract_terms" ",h_contract_terms"
",wire" ",wire_salt"
",payto_uri AS receiver_wire_account"
",done" ",done"
",deposit_serial_id" ",deposit_serial_id"
" FROM deposits" " FROM deposits"
" JOIN wire_targets USING (wire_target_serial_id)"
" JOIN known_coins kc USING (known_coin_id)" " JOIN known_coins kc USING (known_coin_id)"
" JOIN denominations denom USING (denominations_serial)" " JOIN denominations denom USING (denominations_serial)"
" WHERE (" " WHERE ("
@ -1095,12 +1099,14 @@ prepare_statements (struct PostgresClosure *pg)
",wire_deadline" ",wire_deadline"
",merchant_pub" ",merchant_pub"
",h_contract_terms" ",h_contract_terms"
",h_wire" ",wire_salt"
",wire" ",payto_uri"
",coin_sig" ",coin_sig"
",deposit_serial_id" ",deposit_serial_id"
",done" ",done"
" FROM deposits" " FROM deposits"
" JOIN wire_targets"
" USING (wire_target_serial_id)"
" JOIN known_coins kc" " JOIN known_coins kc"
" USING (known_coin_id)" " USING (known_coin_id)"
" JOIN denominations denoms" " JOIN denominations denoms"
@ -4790,7 +4796,6 @@ postgres_select_withdraw_amounts_by_account (
* *
* @param cls the `struct PostgresClosure` with the plugin-specific state * @param cls the `struct PostgresClosure` with the plugin-specific state
* @param deposit deposit to search for * @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] deposit_fee set to the deposit fee the exchange charged
* @param[out] exchange_timestamp set to the time when the exchange received the deposit * @param[out] exchange_timestamp set to the time when the exchange received the deposit
* @return 1 if we know this operation, * @return 1 if we know this operation,
@ -4800,7 +4805,6 @@ postgres_select_withdraw_amounts_by_account (
static enum GNUNET_DB_QueryStatus static enum GNUNET_DB_QueryStatus
postgres_have_deposit (void *cls, postgres_have_deposit (void *cls,
const struct TALER_EXCHANGEDB_Deposit *deposit, const struct TALER_EXCHANGEDB_Deposit *deposit,
int check_extras,
struct TALER_Amount *deposit_fee, struct TALER_Amount *deposit_fee,
struct GNUNET_TIME_Absolute *exchange_timestamp) struct GNUNET_TIME_Absolute *exchange_timestamp)
{ {
@ -4825,8 +4829,10 @@ postgres_have_deposit (void *cls,
&deposit2.wire_deadline), &deposit2.wire_deadline),
TALER_PQ_RESULT_SPEC_AMOUNT ("fee_deposit", TALER_PQ_RESULT_SPEC_AMOUNT ("fee_deposit",
deposit_fee), deposit_fee),
GNUNET_PQ_result_spec_auto_from_type ("h_wire", GNUNET_PQ_result_spec_auto_from_type ("wire_salt",
&deposit2.h_wire), &deposit2.wire_salt),
GNUNET_PQ_result_spec_string ("receiver_wire_account",
&deposit2.receiver_wire_account),
GNUNET_PQ_result_spec_end GNUNET_PQ_result_spec_end
}; };
enum GNUNET_DB_QueryStatus qs; enum GNUNET_DB_QueryStatus qs;
@ -4851,23 +4857,121 @@ postgres_have_deposit (void *cls,
return qs; return qs;
/* Now we check that the other information in @a deposit /* Now we check that the other information in @a deposit
also matches, and if not report inconsistencies. */ also matches, and if not report inconsistencies. */
if ( ( (check_extras) && if ( (0 != TALER_amount_cmp (&deposit->amount_with_fee,
( (0 != TALER_amount_cmp (&deposit->amount_with_fee, &deposit2.amount_with_fee)) ||
&deposit2.amount_with_fee)) || (deposit->timestamp.abs_value_us !=
(deposit->timestamp.abs_value_us != deposit2.timestamp.abs_value_us) ||
deposit2.timestamp.abs_value_us) ) ) ||
(deposit->refund_deadline.abs_value_us != (deposit->refund_deadline.abs_value_us !=
deposit2.refund_deadline.abs_value_us) || deposit2.refund_deadline.abs_value_us) ||
(0 != GNUNET_memcmp (&deposit->h_wire, (0 != strcmp (deposit->receiver_wire_account,
&deposit2.h_wire) ) ) 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 /* Inconsistencies detected! Does not match! (We might want to
expand the API with a 'get_deposit' function to return the expand the API with a 'get_deposit' function to return the
original transaction details to be used for an error message original transaction details to be used for an error message
in the future!) #3838 */ in the future!) FIXME #3838 */
return 0; /* Counts as if the transaction was not there */ 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_assert (GNUNET_YES ==
GNUNET_CRYPTO_kdf (&res, GNUNET_CRYPTO_kdf (&res,
sizeof (res), sizeof (res),
&deposit->h_wire, &deposit->wire_salt,
sizeof (deposit->h_wire), sizeof (deposit->wire_salt),
&deposit->merchant_pub, &deposit->merchant_pub,
sizeof (deposit->merchant_pub), sizeof (deposit->merchant_pub),
deposit->receiver_wire_account,
strlen (deposit->receiver_wire_account),
NULL, 0)); NULL, 0));
/* interpret hash result as NBO for platform independence, /* interpret hash result as NBO for platform independence,
convert to HBO and map to [0..2^31-1] range */ 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) const struct TALER_EXCHANGEDB_Deposit *deposit)
{ {
struct PostgresClosure *pg = cls; struct PostgresClosure *pg = cls;
uint32_t shard = compute_shard (deposit); struct TALER_EXCHANGEDB_KycStatus kyc;
struct GNUNET_PQ_QueryParam params[] = { enum GNUNET_DB_QueryStatus qs;
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
};
GNUNET_assert (shard <= INT32_MAX); qs = inselect_account_kyc_status (pg,
GNUNET_log (GNUNET_ERROR_TYPE_INFO, deposit->receiver_wire_account,
"Inserting deposit to be executed at %s (%llu/%llu)\n", &kyc);
GNUNET_STRINGS_absolute_time_to_string (deposit->wire_deadline), if (qs <= 0)
(unsigned long long) deposit->wire_deadline.abs_value_us, {
(unsigned long long) deposit->refund_deadline.abs_value_us); GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs);
return GNUNET_PQ_eval_prepared_non_select (pg->conn, GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
"insert_deposit", return qs;
params); }
{
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), &deposit->merchant_pub),
GNUNET_PQ_result_spec_auto_from_type ("h_contract_terms", GNUNET_PQ_result_spec_auto_from_type ("h_contract_terms",
&deposit->h_contract_terms), &deposit->h_contract_terms),
GNUNET_PQ_result_spec_auto_from_type ("h_wire", GNUNET_PQ_result_spec_auto_from_type ("wire_salt",
&deposit->h_wire), &deposit->wire_salt),
TALER_PQ_result_spec_json ("wire", GNUNET_PQ_result_spec_string ("payto_uri",
&deposit->receiver_wire_account), &deposit->receiver_wire_account),
GNUNET_PQ_result_spec_auto_from_type ("coin_sig", GNUNET_PQ_result_spec_auto_from_type ("coin_sig",
&deposit->csig), &deposit->csig),
GNUNET_PQ_result_spec_uint64 ("deposit_serial_id", GNUNET_PQ_result_spec_uint64 ("deposit_serial_id",
@ -7813,8 +7933,10 @@ deposit_serial_helper_cb (void *cls,
&deposit.wire_deadline), &deposit.wire_deadline),
GNUNET_PQ_result_spec_auto_from_type ("h_contract_terms", GNUNET_PQ_result_spec_auto_from_type ("h_contract_terms",
&deposit.h_contract_terms), &deposit.h_contract_terms),
TALER_PQ_result_spec_json ("wire", GNUNET_PQ_result_spec_auto_from_type ("wire_salt",
&deposit.receiver_wire_account), &deposit.wire_salt),
GNUNET_PQ_result_spec_string ("receiver_wire_account",
&deposit.receiver_wire_account),
GNUNET_PQ_result_spec_auto_from_type ("done", GNUNET_PQ_result_spec_auto_from_type ("done",
&done), &done),
GNUNET_PQ_result_spec_uint64 ("deposit_serial_id", GNUNET_PQ_result_spec_uint64 ("deposit_serial_id",
@ -7835,17 +7957,9 @@ deposit_serial_helper_cb (void *cls,
ret = dsc->cb (dsc->cb_cls, ret = dsc->cb (dsc->cb_cls,
rowid, rowid,
exchange_timestamp, exchange_timestamp,
deposit.timestamp, &deposit,
&deposit.merchant_pub,
&denom_pub, &denom_pub,
&deposit.coin.coin_pub, (0 != done) ? true : false);
&deposit.csig,
&deposit.amount_with_fee,
&deposit.h_contract_terms,
deposit.refund_deadline,
deposit.wire_deadline,
deposit.receiver_wire_account,
done);
GNUNET_PQ_cleanup_result (rs); GNUNET_PQ_cleanup_result (rs);
if (GNUNET_OK != ret) if (GNUNET_OK != ret)
break; break;
@ -11402,6 +11516,7 @@ libtaler_plugin_exchangedb_postgres_init (void *cls)
plugin->get_known_coin = &postgres_get_known_coin; plugin->get_known_coin = &postgres_get_known_coin;
plugin->get_coin_denomination = &postgres_get_coin_denomination; plugin->get_coin_denomination = &postgres_get_coin_denomination;
plugin->have_deposit = &postgres_have_deposit; plugin->have_deposit = &postgres_have_deposit;
plugin->have_deposit2 = &postgres_have_deposit2;
plugin->mark_deposit_tiny = &postgres_mark_deposit_tiny; plugin->mark_deposit_tiny = &postgres_mark_deposit_tiny;
plugin->test_deposit_done = &postgres_test_deposit_done; plugin->test_deposit_done = &postgres_test_deposit_done;
plugin->mark_deposit_done = &postgres_mark_deposit_done; plugin->mark_deposit_done = &postgres_mark_deposit_done;

View File

@ -889,7 +889,8 @@ typedef void
* @param amount the amount to be deposited * @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 * @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) * 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 merchants account details, in a format supported by the exchange * @param merchant_payto_uri the merchants 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 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 extension_details extension-specific details about the deposit relevant to the exchange
* @param coin_pub coins public key * @param coin_pub coins public key
@ -910,7 +911,8 @@ TALER_EXCHANGE_deposit (
struct TALER_EXCHANGE_Handle *exchange, struct TALER_EXCHANGE_Handle *exchange,
const struct TALER_Amount *amount, const struct TALER_Amount *amount,
struct GNUNET_TIME_Absolute wire_deadline, 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 struct TALER_PrivateContractHash *h_contract_terms,
const json_t *extension_details, const json_t *extension_details,
const struct TALER_CoinSpendPublicKeyP *coin_pub, const struct TALER_CoinSpendPublicKeyP *coin_pub,

View File

@ -981,18 +981,15 @@ struct TALER_EXCHANGEDB_Deposit
struct TALER_PrivateContractHash h_contract_terms; struct TALER_PrivateContractHash h_contract_terms;
/** /**
* Hash of the (canonical) representation of @e wire, used * Salt used by the merchant to compute "h_wire".
* 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; struct TALER_WireSalt wire_salt;
/** /**
* Detailed information about the receiver for executing the transaction. * Information about the receiver for executing the transaction. URI in
* Includes URL in payto://-format and salt. * payto://-format.
*/ */
json_t *receiver_wire_account; char *receiver_wire_account;
/** /**
* Additional details for extensions relevant for this * Additional details for extensions relevant for this
@ -1071,14 +1068,6 @@ struct TALER_EXCHANGEDB_DepositListEntry
*/ */
struct TALER_PrivateContractHash h_contract_terms; 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. * Hash of the public denomination key used to sign the coin.
*/ */
@ -1086,9 +1075,14 @@ struct TALER_EXCHANGEDB_DepositListEntry
/** /**
* Detailed information about the receiver for executing the transaction. * 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 * Time when this request was generated. Used, for example, to
@ -1545,17 +1539,9 @@ typedef enum GNUNET_GenericReturnValue
void *cls, void *cls,
uint64_t rowid, uint64_t rowid,
struct GNUNET_TIME_Absolute exchange_timestamp, struct GNUNET_TIME_Absolute exchange_timestamp,
struct GNUNET_TIME_Absolute wallet_timestamp, const struct TALER_EXCHANGEDB_Deposit *deposit,
const struct TALER_MerchantPublicKeyP *merchant_pub,
const struct TALER_DenominationPublicKey *denom_pub, const struct TALER_DenominationPublicKey *denom_pub,
const struct TALER_CoinSpendPublicKeyP *coin_pub, bool done);
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);
/** /**
@ -2627,7 +2613,6 @@ struct TALER_EXCHANGEDB_Plugin
* *
* @param cls the @e cls of this struct with the plugin-specific state * @param cls the @e cls of this struct with the plugin-specific state
* @param deposit deposit to search for * @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] deposit_fee set to the deposit fee the exchange charged
* @param[out] exchange_timestamp set to the time when the exchange received the deposit * @param[out] exchange_timestamp set to the time when the exchange received the deposit
* @return 1 if we know this operation, * @return 1 if we know this operation,
@ -2637,11 +2622,37 @@ struct TALER_EXCHANGEDB_Plugin
enum GNUNET_DB_QueryStatus enum GNUNET_DB_QueryStatus
(*have_deposit)(void *cls, (*have_deposit)(void *cls,
const struct TALER_EXCHANGEDB_Deposit *deposit, const struct TALER_EXCHANGEDB_Deposit *deposit,
int check_extras,
struct TALER_Amount *deposit_fee, struct TALER_Amount *deposit_fee,
struct GNUNET_TIME_Absolute *exchange_timestamp); 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. * Insert information about deposited coin into the database.
* *

View File

@ -543,7 +543,8 @@ TALER_EXCHANGE_deposit (
struct TALER_EXCHANGE_Handle *exchange, struct TALER_EXCHANGE_Handle *exchange,
const struct TALER_Amount *amount, const struct TALER_Amount *amount,
struct GNUNET_TIME_Absolute wire_deadline, 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 struct TALER_PrivateContractHash *h_contract_terms,
const json_t *extension_details, const json_t *extension_details,
const struct TALER_CoinSpendPublicKeyP *coin_pub, const struct TALER_CoinSpendPublicKeyP *coin_pub,
@ -594,14 +595,9 @@ TALER_EXCHANGE_deposit (
GNUNET_assert (GNUNET_YES == GNUNET_assert (GNUNET_YES ==
TEAH_handle_is_ready (exchange)); TEAH_handle_is_ready (exchange));
/* initialize h_wire */ /* initialize h_wire */
if (GNUNET_OK != TALER_merchant_wire_signature_hash (merchant_payto_uri,
TALER_JSON_merchant_wire_signature_hash (wire_details, wire_salt,
&h_wire)) &h_wire);
{
GNUNET_break (0);
*ec = TALER_EC_GENERIC_FAILED_COMPUTE_JSON_HASH;
return NULL;
}
key_state = TALER_EXCHANGE_get_keys (exchange); key_state = TALER_EXCHANGE_get_keys (exchange);
dki = TALER_EXCHANGE_get_denomination_key (key_state, dki = TALER_EXCHANGE_get_denomination_key (key_state,
denom_pub); denom_pub);
@ -644,10 +640,10 @@ TALER_EXCHANGE_deposit (
deposit_obj = GNUNET_JSON_PACK ( deposit_obj = GNUNET_JSON_PACK (
TALER_JSON_pack_amount ("contribution", TALER_JSON_pack_amount ("contribution",
amount), amount),
GNUNET_JSON_pack_object_incref ("wire", GNUNET_JSON_pack_string ("merchant_payto_uri",
(json_t *) wire_details), merchant_payto_uri),
GNUNET_JSON_pack_data_auto ("h_wire", GNUNET_JSON_pack_data_auto ("wire_salt",
&h_wire), wire_salt),
GNUNET_JSON_pack_data_auto ("h_contract_terms", GNUNET_JSON_pack_data_auto ("h_contract_terms",
h_contract_terms), h_contract_terms),
GNUNET_JSON_pack_data_auto ("denom_pub_hash", GNUNET_JSON_pack_data_auto ("denom_pub_hash",

View File

@ -289,7 +289,25 @@ deposit_run (void *cls,
struct TALER_MerchantPublicKeyP merchant_pub; struct TALER_MerchantPublicKeyP merchant_pub;
struct TALER_PrivateContractHash h_contract_terms; struct TALER_PrivateContractHash h_contract_terms;
enum TALER_ErrorCode ec; 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; (void) cmd;
ds->is = is; ds->is = is;
if (NULL != ds->deposit_reference) if (NULL != ds->deposit_reference)
@ -412,7 +430,8 @@ deposit_run (void *cls,
ds->dh = TALER_EXCHANGE_deposit (is->exchange, ds->dh = TALER_EXCHANGE_deposit (is->exchange,
&ds->amount, &ds->amount,
wire_deadline, wire_deadline,
ds->wire_details, payto_uri,
&wire_salt,
&h_contract_terms, &h_contract_terms,
NULL, /* FIXME: extension object */ NULL, /* FIXME: extension object */
&coin_pub, &coin_pub,

View File

@ -203,29 +203,12 @@ insert_deposit_run (void *cls,
deposit.coin.denom_sig.details.rsa_signature deposit.coin.denom_sig.details.rsa_signature
= GNUNET_CRYPTO_rsa_sign_fdh (denom_priv, = GNUNET_CRYPTO_rsa_sign_fdh (denom_priv,
&hc); &hc);
{ GNUNET_asprintf (&deposit.receiver_wire_account,
char *str; "payto://x-taler-bank/localhost/%s",
struct TALER_WireSalt salt; ids->merchant_account);
memset (&deposit.wire_salt,
GNUNET_asprintf (&str, 46,
"payto://x-taler-bank/localhost/%s", sizeof (deposit.wire_salt));
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));
deposit.timestamp = GNUNET_TIME_absolute_get (); deposit.timestamp = GNUNET_TIME_absolute_get ();
(void) GNUNET_TIME_round_abs (&deposit.timestamp); (void) GNUNET_TIME_round_abs (&deposit.timestamp);
deposit.wire_deadline = GNUNET_TIME_relative_to_absolute (ids->wire_deadline); deposit.wire_deadline = GNUNET_TIME_relative_to_absolute (ids->wire_deadline);
@ -247,14 +230,15 @@ insert_deposit_run (void *cls,
{ {
GNUNET_break (0); GNUNET_break (0);
ids->dbc->plugin->rollback (ids->dbc->plugin->cls); ids->dbc->plugin->rollback (ids->dbc->plugin->cls);
GNUNET_free (deposit.receiver_wire_account);
TALER_TESTING_interpreter_fail (is); TALER_TESTING_interpreter_fail (is);
return;
} }
TALER_denom_sig_free (&deposit.coin.denom_sig); TALER_denom_sig_free (&deposit.coin.denom_sig);
TALER_denom_pub_free (&dpk); TALER_denom_pub_free (&dpk);
GNUNET_CRYPTO_rsa_private_key_free (denom_priv); 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); TALER_TESTING_interpreter_next (is);
} }