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:
/* 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,

View File

@ -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,

View File

@ -112,19 +112,15 @@ 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 */,
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)

View File

@ -58,11 +58,6 @@ static unsigned int refund_rate = 0;
*/
static char *currency;
/**
* Merchant JSON wire details.
*/
static json_t *json_wire;
/**
* Configuration.
*/
@ -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);
}

View File

@ -116,6 +116,11 @@ struct DepositContext
*/
struct GNUNET_TIME_Absolute exchange_timestamp;
/**
* Calculated hash over the wire details.
*/
struct TALER_MerchantWireHash h_wire;
/**
* Value of the coin.
*/
@ -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,

View File

@ -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",

View File

@ -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;
}

View File

@ -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,
if ( (0 != TALER_amount_cmp (&deposit->amount_with_fee,
&deposit2.amount_with_fee)) ||
(deposit->timestamp.abs_value_us !=
deposit2.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,6 +5574,19 @@ postgres_insert_deposit (void *cls,
const struct TALER_EXCHANGEDB_Deposit *deposit)
{
struct PostgresClosure *pg = cls;
struct TALER_EXCHANGEDB_KycStatus kyc;
enum GNUNET_DB_QueryStatus qs;
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),
@ -5477,9 +5596,9 @@ postgres_insert_deposit (void *cls,
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->wire_salt),
GNUNET_PQ_query_param_uint64 (&kyc.payment_target_uuid),
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
@ -5495,6 +5614,7 @@ postgres_insert_deposit (void *cls,
"insert_deposit",
params);
}
}
/**
@ -6285,9 +6405,9 @@ 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",
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),
@ -7813,7 +7933,9 @@ 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",
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),
@ -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;

View File

@ -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 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 extension_details extension-specific details about the deposit relevant to the exchange
* @param coin_pub coins 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,

View File

@ -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
@ -1071,14 +1068,6 @@ 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.
*/
@ -1086,9 +1075,14 @@ struct TALER_EXCHANGEDB_DepositListEntry
/**
* 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,7 +2622,33 @@ 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);

View File

@ -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",

View File

@ -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,

View File

@ -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,
GNUNET_asprintf (&deposit.receiver_wire_account,
"payto://x-taler-bank/localhost/%s",
ids->merchant_account);
memset (&salt,
memset (&deposit.wire_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));
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);
}