implement #3887-handling in exchange-lib
This commit is contained in:
parent
dbb2368403
commit
cc3aa31732
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
This file is part of TALER
|
This file is part of TALER
|
||||||
Copyright (C) 2015, 2016 Inria & GNUnet e.V.
|
Copyright (C) 2015-2017 Inria & GNUnet e.V.
|
||||||
|
|
||||||
TALER is free software; you can redistribute it and/or modify it under the
|
TALER is free software; you can redistribute it and/or modify it under the
|
||||||
terms of the GNU General Public License as published by the Free Software
|
terms of the GNU General Public License as published by the Free Software
|
||||||
@ -65,20 +65,12 @@ TALER_EXCHANGE_verify_coin_history (const char *currency,
|
|||||||
{
|
{
|
||||||
json_t *transaction;
|
json_t *transaction;
|
||||||
struct TALER_Amount amount;
|
struct TALER_Amount amount;
|
||||||
struct TALER_CoinSpendSignatureP sig;
|
|
||||||
void *details;
|
|
||||||
size_t details_size;
|
|
||||||
const char *type;
|
const char *type;
|
||||||
struct GNUNET_JSON_Specification spec[] = {
|
struct GNUNET_JSON_Specification spec_glob[] = {
|
||||||
TALER_JSON_spec_amount ("amount",
|
TALER_JSON_spec_amount ("amount",
|
||||||
&amount),
|
&amount),
|
||||||
GNUNET_JSON_spec_string ("type",
|
GNUNET_JSON_spec_string ("type",
|
||||||
&type),
|
&type),
|
||||||
GNUNET_JSON_spec_fixed_auto ("signature",
|
|
||||||
&sig),
|
|
||||||
GNUNET_JSON_spec_varsize ("details",
|
|
||||||
&details,
|
|
||||||
&details_size),
|
|
||||||
GNUNET_JSON_spec_end()
|
GNUNET_JSON_spec_end()
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -86,7 +78,7 @@ TALER_EXCHANGE_verify_coin_history (const char *currency,
|
|||||||
off);
|
off);
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
GNUNET_JSON_parse (transaction,
|
GNUNET_JSON_parse (transaction,
|
||||||
spec,
|
spec_glob,
|
||||||
NULL, NULL))
|
NULL, NULL))
|
||||||
{
|
{
|
||||||
GNUNET_break_op (0);
|
GNUNET_break_op (0);
|
||||||
@ -96,40 +88,47 @@ TALER_EXCHANGE_verify_coin_history (const char *currency,
|
|||||||
if (0 == strcasecmp (type,
|
if (0 == strcasecmp (type,
|
||||||
"DEPOSIT"))
|
"DEPOSIT"))
|
||||||
{
|
{
|
||||||
const struct TALER_DepositRequestPS *dr;
|
struct TALER_DepositRequestPS dr;
|
||||||
struct TALER_Amount dr_amount;
|
struct TALER_Amount dr_amount;
|
||||||
|
struct TALER_CoinSpendSignatureP sig;
|
||||||
|
struct GNUNET_JSON_Specification spec[] = {
|
||||||
|
GNUNET_JSON_spec_fixed_auto ("signature",
|
||||||
|
&sig),
|
||||||
|
GNUNET_JSON_spec_fixed_auto ("details",
|
||||||
|
&dr),
|
||||||
|
GNUNET_JSON_spec_end()
|
||||||
|
};
|
||||||
|
|
||||||
if (details_size != sizeof (struct TALER_DepositRequestPS))
|
if (GNUNET_OK !=
|
||||||
|
GNUNET_JSON_parse (transaction,
|
||||||
|
spec,
|
||||||
|
NULL, NULL))
|
||||||
{
|
{
|
||||||
GNUNET_break_op (0);
|
GNUNET_break_op (0);
|
||||||
GNUNET_JSON_parse_free (spec);
|
|
||||||
return GNUNET_SYSERR;
|
return GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
dr = (const struct TALER_DepositRequestPS *) details;
|
/* TODO #4980 */
|
||||||
if (details_size != ntohl (dr->purpose.size))
|
if (sizeof (dr) != ntohl (dr.purpose.size))
|
||||||
{
|
{
|
||||||
GNUNET_break_op (0);
|
GNUNET_break_op (0);
|
||||||
GNUNET_JSON_parse_free (spec);
|
|
||||||
return GNUNET_SYSERR;
|
return GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
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->purpose,
|
&dr.purpose,
|
||||||
&sig.eddsa_signature,
|
&sig.eddsa_signature,
|
||||||
&coin_pub->eddsa_pub))
|
&coin_pub->eddsa_pub))
|
||||||
{
|
{
|
||||||
GNUNET_break_op (0);
|
GNUNET_break_op (0);
|
||||||
GNUNET_JSON_parse_free (spec);
|
|
||||||
return GNUNET_SYSERR;
|
return GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
TALER_amount_ntoh (&dr_amount,
|
TALER_amount_ntoh (&dr_amount,
|
||||||
&dr->amount_with_fee);
|
&dr.amount_with_fee);
|
||||||
|
/* TODO #4980 */
|
||||||
if (0 != TALER_amount_cmp (&dr_amount,
|
if (0 != TALER_amount_cmp (&dr_amount,
|
||||||
&amount))
|
&amount))
|
||||||
{
|
{
|
||||||
GNUNET_break (0);
|
GNUNET_break (0);
|
||||||
GNUNET_JSON_parse_free (spec);
|
|
||||||
return GNUNET_SYSERR;
|
return GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
add = GNUNET_YES;
|
add = GNUNET_YES;
|
||||||
@ -137,39 +136,47 @@ TALER_EXCHANGE_verify_coin_history (const char *currency,
|
|||||||
else if (0 == strcasecmp (type,
|
else if (0 == strcasecmp (type,
|
||||||
"MELT"))
|
"MELT"))
|
||||||
{
|
{
|
||||||
const struct TALER_RefreshMeltCoinAffirmationPS *rm;
|
struct TALER_RefreshMeltCoinAffirmationPS rm;
|
||||||
struct TALER_Amount rm_amount;
|
struct TALER_Amount rm_amount;
|
||||||
|
struct TALER_CoinSpendSignatureP sig;
|
||||||
|
struct GNUNET_JSON_Specification spec[] = {
|
||||||
|
GNUNET_JSON_spec_fixed_auto ("signature",
|
||||||
|
&sig),
|
||||||
|
GNUNET_JSON_spec_fixed_auto ("details",
|
||||||
|
&rm),
|
||||||
|
GNUNET_JSON_spec_end()
|
||||||
|
};
|
||||||
|
|
||||||
if (details_size != sizeof (struct TALER_RefreshMeltCoinAffirmationPS))
|
if (GNUNET_OK !=
|
||||||
|
GNUNET_JSON_parse (transaction,
|
||||||
|
spec,
|
||||||
|
NULL, NULL))
|
||||||
{
|
{
|
||||||
GNUNET_break_op (0);
|
GNUNET_break_op (0);
|
||||||
GNUNET_JSON_parse_free (spec);
|
|
||||||
return GNUNET_SYSERR;
|
return GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
rm = (const struct TALER_RefreshMeltCoinAffirmationPS *) details;
|
/* TODO #4980 */
|
||||||
if (details_size != ntohl (rm->purpose.size))
|
if (sizeof (rm) != ntohl (rm.purpose.size))
|
||||||
{
|
{
|
||||||
GNUNET_break_op (0);
|
GNUNET_break_op (0);
|
||||||
GNUNET_JSON_parse_free (spec);
|
|
||||||
return GNUNET_SYSERR;
|
return GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_MELT,
|
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_MELT,
|
||||||
&rm->purpose,
|
&rm.purpose,
|
||||||
&sig.eddsa_signature,
|
&sig.eddsa_signature,
|
||||||
&coin_pub->eddsa_pub))
|
&coin_pub->eddsa_pub))
|
||||||
{
|
{
|
||||||
GNUNET_break_op (0);
|
GNUNET_break_op (0);
|
||||||
GNUNET_JSON_parse_free (spec);
|
|
||||||
return GNUNET_SYSERR;
|
return GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
TALER_amount_ntoh (&rm_amount,
|
TALER_amount_ntoh (&rm_amount,
|
||||||
&rm->amount_with_fee);
|
&rm.amount_with_fee);
|
||||||
|
/* TODO #4980 */
|
||||||
if (0 != TALER_amount_cmp (&rm_amount,
|
if (0 != TALER_amount_cmp (&rm_amount,
|
||||||
&amount))
|
&amount))
|
||||||
{
|
{
|
||||||
GNUNET_break_op (0);
|
GNUNET_break_op (0);
|
||||||
GNUNET_JSON_parse_free (spec);
|
|
||||||
return GNUNET_SYSERR;
|
return GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
add = GNUNET_YES;
|
add = GNUNET_YES;
|
||||||
@ -177,55 +184,60 @@ TALER_EXCHANGE_verify_coin_history (const char *currency,
|
|||||||
else if (0 == strcasecmp (type,
|
else if (0 == strcasecmp (type,
|
||||||
"REFUND"))
|
"REFUND"))
|
||||||
{
|
{
|
||||||
const struct TALER_RefundRequestPS *rr;
|
struct TALER_RefundRequestPS rr;
|
||||||
struct TALER_Amount rr_amount;
|
struct TALER_Amount rr_amount;
|
||||||
struct TALER_Amount rr_fee;
|
struct TALER_Amount rr_fee;
|
||||||
struct TALER_Amount rr_delta;
|
struct TALER_Amount rr_delta;
|
||||||
|
struct TALER_CoinSpendSignatureP sig;
|
||||||
|
struct GNUNET_JSON_Specification spec[] = {
|
||||||
|
GNUNET_JSON_spec_fixed_auto ("signature",
|
||||||
|
&sig),
|
||||||
|
GNUNET_JSON_spec_fixed_auto ("details",
|
||||||
|
&rr),
|
||||||
|
GNUNET_JSON_spec_end()
|
||||||
|
};
|
||||||
|
|
||||||
if (details_size != sizeof (struct TALER_RefundRequestPS))
|
if (GNUNET_OK !=
|
||||||
|
GNUNET_JSON_parse (transaction,
|
||||||
|
spec,
|
||||||
|
NULL, NULL))
|
||||||
{
|
{
|
||||||
GNUNET_break_op (0);
|
GNUNET_break_op (0);
|
||||||
GNUNET_JSON_parse_free (spec);
|
|
||||||
return GNUNET_SYSERR;
|
return GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
rr = (const struct TALER_RefundRequestPS *) details;
|
/* TODO #4980 */
|
||||||
if (details_size != ntohl (rr->purpose.size))
|
if (sizeof (rr) != ntohl (rr.purpose.size))
|
||||||
{
|
{
|
||||||
GNUNET_break_op (0);
|
GNUNET_break_op (0);
|
||||||
GNUNET_JSON_parse_free (spec);
|
|
||||||
return GNUNET_SYSERR;
|
return GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MERCHANT_REFUND,
|
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MERCHANT_REFUND,
|
||||||
&rr->purpose,
|
&rr.purpose,
|
||||||
&sig.eddsa_signature,
|
&sig.eddsa_signature,
|
||||||
&rr->merchant.eddsa_pub))
|
&rr.merchant.eddsa_pub))
|
||||||
{
|
{
|
||||||
GNUNET_break_op (0);
|
GNUNET_break_op (0);
|
||||||
GNUNET_JSON_parse_free (spec);
|
|
||||||
return GNUNET_SYSERR;
|
return GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
TALER_amount_ntoh (&rr_amount,
|
TALER_amount_ntoh (&rr_amount,
|
||||||
&rr->refund_amount);
|
&rr.refund_amount);
|
||||||
TALER_amount_ntoh (&rr_fee,
|
|
||||||
&rr->refund_fee);
|
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
TALER_amount_subtract (&rr_delta,
|
TALER_amount_subtract (&rr_delta,
|
||||||
&rr_amount,
|
&rr_amount,
|
||||||
&rr_fee))
|
&rr_fee))
|
||||||
{
|
{
|
||||||
GNUNET_break_op (0);
|
GNUNET_break_op (0);
|
||||||
GNUNET_JSON_parse_free (spec);
|
|
||||||
return GNUNET_SYSERR;
|
return GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
|
/* TODO #4980 */
|
||||||
if (0 != TALER_amount_cmp (&rr_delta,
|
if (0 != TALER_amount_cmp (&rr_delta,
|
||||||
&amount))
|
&amount))
|
||||||
{
|
{
|
||||||
GNUNET_break_op (0);
|
GNUNET_break_op (0);
|
||||||
GNUNET_JSON_parse_free (spec);
|
|
||||||
return GNUNET_SYSERR;
|
return GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
/* NOTE/FIXME: theoretically, we could also check that the given
|
/* NOTE: theoretically, we could also check that the given
|
||||||
merchant_pub and h_proposal_data appear in the
|
merchant_pub and h_proposal_data appear in the
|
||||||
history under deposits. However, there is really no benefit
|
history under deposits. However, there is really no benefit
|
||||||
for the exchange to lie here, so not checking is probably OK
|
for the exchange to lie here, so not checking is probably OK
|
||||||
@ -237,14 +249,59 @@ TALER_EXCHANGE_verify_coin_history (const char *currency,
|
|||||||
else if (0 == strcasecmp (type,
|
else if (0 == strcasecmp (type,
|
||||||
"PAYBACK"))
|
"PAYBACK"))
|
||||||
{
|
{
|
||||||
GNUNET_break (0); /* #3887 */
|
struct TALER_PaybackConfirmationPS pc;
|
||||||
|
struct TALER_Amount pc_amount;
|
||||||
|
struct TALER_ExchangePublicKeyP exchange_pub;
|
||||||
|
struct TALER_ExchangeSignatureP exchange_sig;
|
||||||
|
struct GNUNET_JSON_Specification spec[] = {
|
||||||
|
GNUNET_JSON_spec_fixed_auto ("exchange_sig",
|
||||||
|
&exchange_sig),
|
||||||
|
GNUNET_JSON_spec_fixed_auto ("exchange_pub",
|
||||||
|
&exchange_pub),
|
||||||
|
GNUNET_JSON_spec_fixed_auto ("details",
|
||||||
|
&pc),
|
||||||
|
GNUNET_JSON_spec_end()
|
||||||
|
};
|
||||||
|
|
||||||
|
if (GNUNET_OK !=
|
||||||
|
GNUNET_JSON_parse (transaction,
|
||||||
|
spec,
|
||||||
|
NULL, NULL))
|
||||||
|
{
|
||||||
|
GNUNET_break_op (0);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO #4980 */
|
||||||
|
if (sizeof (pc) != ntohl (pc.purpose.size))
|
||||||
|
{
|
||||||
|
GNUNET_break_op (0);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
if (GNUNET_OK !=
|
||||||
|
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_CONFIRM_PAYBACK,
|
||||||
|
&pc.purpose,
|
||||||
|
&exchange_sig.eddsa_signature,
|
||||||
|
&exchange_pub.eddsa_pub))
|
||||||
|
{
|
||||||
|
GNUNET_break_op (0);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
TALER_amount_ntoh (&pc_amount,
|
||||||
|
&pc.payback_amount);
|
||||||
|
/* TODO #4980 */
|
||||||
|
if (0 != TALER_amount_cmp (&pc_amount,
|
||||||
|
&amount))
|
||||||
|
{
|
||||||
|
GNUNET_break_op (0);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
add = GNUNET_YES;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* signature not supported, new version on server? */
|
/* signature not supported, new version on server? */
|
||||||
GNUNET_break_op (0);
|
GNUNET_break_op (0);
|
||||||
GNUNET_JSON_parse_free (spec);
|
|
||||||
return GNUNET_SYSERR;
|
return GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
if (GNUNET_YES == add)
|
if (GNUNET_YES == add)
|
||||||
@ -257,7 +314,6 @@ TALER_EXCHANGE_verify_coin_history (const char *currency,
|
|||||||
{
|
{
|
||||||
/* overflow in history already!? inconceivable! Bad exchange! */
|
/* overflow in history already!? inconceivable! Bad exchange! */
|
||||||
GNUNET_break_op (0);
|
GNUNET_break_op (0);
|
||||||
GNUNET_JSON_parse_free (spec);
|
|
||||||
return GNUNET_SYSERR;
|
return GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -277,11 +333,9 @@ TALER_EXCHANGE_verify_coin_history (const char *currency,
|
|||||||
{
|
{
|
||||||
/* overflow in refund history? inconceivable! Bad exchange! */
|
/* overflow in refund history? inconceivable! Bad exchange! */
|
||||||
GNUNET_break_op (0);
|
GNUNET_break_op (0);
|
||||||
GNUNET_JSON_parse_free (spec);
|
|
||||||
return GNUNET_SYSERR;
|
return GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
GNUNET_JSON_parse_free (spec);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Finally, subtract 'rtotal' from total to handle the subtractions */
|
/* Finally, subtract 'rtotal' from total to handle the subtractions */
|
||||||
|
@ -77,7 +77,8 @@ struct TALER_EXCHANGE_ReserveStatusHandle
|
|||||||
* Parse history given in JSON format and return it in binary
|
* Parse history given in JSON format and return it in binary
|
||||||
* format.
|
* format.
|
||||||
*
|
*
|
||||||
* @param[in] history JSON array with the history
|
* @param exchange connection to the exchange we can use
|
||||||
|
* @param history JSON array with the history
|
||||||
* @param reserve_pub public key of the reserve to inspect
|
* @param reserve_pub public key of the reserve to inspect
|
||||||
* @param currency currency we expect the balance to be in
|
* @param currency currency we expect the balance to be in
|
||||||
* @param[out] balance final balance
|
* @param[out] balance final balance
|
||||||
@ -89,7 +90,8 @@ struct TALER_EXCHANGE_ReserveStatusHandle
|
|||||||
* #GNUNET_SYSERR if there was a protocol violation in @a history
|
* #GNUNET_SYSERR if there was a protocol violation in @a history
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
parse_reserve_history (const json_t *history,
|
parse_reserve_history (struct TALER_EXCHANGE_Handle *exchange,
|
||||||
|
const json_t *history,
|
||||||
const struct TALER_ReservePublicKeyP *reserve_pub,
|
const struct TALER_ReservePublicKeyP *reserve_pub,
|
||||||
const char *currency,
|
const char *currency,
|
||||||
struct TALER_Amount *balance,
|
struct TALER_Amount *balance,
|
||||||
@ -214,6 +216,7 @@ parse_reserve_history (const json_t *history,
|
|||||||
}
|
}
|
||||||
TALER_amount_ntoh (&amount_from_purpose,
|
TALER_amount_ntoh (&amount_from_purpose,
|
||||||
&withdraw_purpose.amount_with_fee);
|
&withdraw_purpose.amount_with_fee);
|
||||||
|
/* TODO #4980 */
|
||||||
if (0 != TALER_amount_cmp (&amount,
|
if (0 != TALER_amount_cmp (&amount,
|
||||||
&amount_from_purpose))
|
&amount_from_purpose))
|
||||||
{
|
{
|
||||||
@ -259,13 +262,75 @@ parse_reserve_history (const json_t *history,
|
|||||||
else if (0 == strcasecmp (type,
|
else if (0 == strcasecmp (type,
|
||||||
"PAYBACK"))
|
"PAYBACK"))
|
||||||
{
|
{
|
||||||
GNUNET_break (0); /* #3887 */
|
struct TALER_PaybackConfirmationPS pc;
|
||||||
|
struct TALER_Amount amount_from_purpose;
|
||||||
|
struct GNUNET_TIME_Absolute timestamp_from_purpose;
|
||||||
|
struct GNUNET_TIME_Absolute timestamp;
|
||||||
|
const struct TALER_EXCHANGE_Keys *key_state;
|
||||||
|
struct GNUNET_JSON_Specification payback_spec[] = {
|
||||||
|
GNUNET_JSON_spec_fixed_auto ("details",
|
||||||
|
&pc),
|
||||||
|
GNUNET_JSON_spec_fixed_auto ("exchange_sig",
|
||||||
|
&rhistory[off].details.payback_details.exchange_sig),
|
||||||
|
GNUNET_JSON_spec_fixed_auto ("exchange_pub",
|
||||||
|
&rhistory[off].details.payback_details.exchange_pub),
|
||||||
|
GNUNET_JSON_spec_absolute_time ("timetamp",
|
||||||
|
×tamp),
|
||||||
|
TALER_JSON_spec_amount ("amount",
|
||||||
|
&rhistory[off].amount),
|
||||||
|
GNUNET_JSON_spec_end()
|
||||||
|
};
|
||||||
|
|
||||||
|
rhistory[off].type = TALER_EXCHANGE_RTT_PAYBACK;
|
||||||
|
if (GNUNET_OK !=
|
||||||
|
GNUNET_JSON_parse (transaction,
|
||||||
|
payback_spec,
|
||||||
|
NULL, NULL))
|
||||||
|
{
|
||||||
|
GNUNET_break_op (0);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
rhistory[off].details.payback_details.coin_pub = pc.coin_pub;
|
||||||
|
TALER_amount_ntoh (&amount_from_purpose,
|
||||||
|
&pc.payback_amount);
|
||||||
|
rhistory[off].details.payback_details.timestamp = timestamp;
|
||||||
|
timestamp_from_purpose = GNUNET_TIME_absolute_ntoh (pc.timestamp);
|
||||||
|
/* TODO #4980 */
|
||||||
|
if ( (0 != memcmp (&pc.reserve_pub,
|
||||||
|
reserve_pub,
|
||||||
|
sizeof (*reserve_pub))) ||
|
||||||
|
(timestamp_from_purpose.abs_value_us !=
|
||||||
|
timestamp.abs_value_us) ||
|
||||||
|
(0 != TALER_amount_cmp (&amount_from_purpose,
|
||||||
|
&rhistory[off].amount)) )
|
||||||
|
{
|
||||||
|
GNUNET_break_op (0);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
key_state = TALER_EXCHANGE_get_keys (exchange);
|
||||||
|
if (GNUNET_OK !=
|
||||||
|
TALER_EXCHANGE_test_signing_key (key_state,
|
||||||
|
&rhistory[off].details.payback_details.exchange_pub))
|
||||||
|
{
|
||||||
|
GNUNET_break_op (0);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
if (GNUNET_OK !=
|
||||||
|
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_CONFIRM_PAYBACK,
|
||||||
|
&pc.purpose,
|
||||||
|
&rhistory[off].details.payback_details.exchange_sig.eddsa_signature,
|
||||||
|
&rhistory[off].details.payback_details.exchange_pub.eddsa_pub))
|
||||||
|
{
|
||||||
|
GNUNET_break_op (0);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
/* end type==PAYBACK */
|
/* end type==PAYBACK */
|
||||||
}
|
}
|
||||||
else if (0 == strcasecmp (type,
|
else if (0 == strcasecmp (type,
|
||||||
"CLOSING"))
|
"CLOSING"))
|
||||||
{
|
{
|
||||||
GNUNET_break (0); /* #3887 / #4956 */
|
GNUNET_break (0); /* FIXME: implement with #4956 */
|
||||||
/* end type==CLOSING */
|
/* end type==CLOSING */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -304,9 +369,9 @@ handle_reserve_status_finished (void *cls,
|
|||||||
long response_code,
|
long response_code,
|
||||||
const json_t *json)
|
const json_t *json)
|
||||||
{
|
{
|
||||||
struct TALER_EXCHANGE_ReserveStatusHandle *wsh = cls;
|
struct TALER_EXCHANGE_ReserveStatusHandle *rsh = cls;
|
||||||
|
|
||||||
wsh->job = NULL;
|
rsh->job = NULL;
|
||||||
switch (response_code)
|
switch (response_code)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
@ -346,8 +411,9 @@ handle_reserve_status_finished (void *cls,
|
|||||||
struct TALER_EXCHANGE_ReserveHistory rhistory[len];
|
struct TALER_EXCHANGE_ReserveHistory rhistory[len];
|
||||||
|
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
parse_reserve_history (history,
|
parse_reserve_history (rsh->exchange,
|
||||||
&wsh->reserve_pub,
|
history,
|
||||||
|
&rsh->reserve_pub,
|
||||||
balance.currency,
|
balance.currency,
|
||||||
&balance_from_history,
|
&balance_from_history,
|
||||||
len,
|
len,
|
||||||
@ -366,14 +432,14 @@ handle_reserve_status_finished (void *cls,
|
|||||||
response_code = 0;
|
response_code = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
wsh->cb (wsh->cb_cls,
|
rsh->cb (rsh->cb_cls,
|
||||||
response_code,
|
response_code,
|
||||||
TALER_EC_NONE,
|
TALER_EC_NONE,
|
||||||
json,
|
json,
|
||||||
&balance,
|
&balance,
|
||||||
len,
|
len,
|
||||||
rhistory);
|
rhistory);
|
||||||
wsh->cb = NULL;
|
rsh->cb = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -398,14 +464,14 @@ handle_reserve_status_finished (void *cls,
|
|||||||
response_code = 0;
|
response_code = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (NULL != wsh->cb)
|
if (NULL != rsh->cb)
|
||||||
wsh->cb (wsh->cb_cls,
|
rsh->cb (rsh->cb_cls,
|
||||||
response_code,
|
response_code,
|
||||||
TALER_JSON_get_error_code (json),
|
TALER_JSON_get_error_code (json),
|
||||||
json,
|
json,
|
||||||
NULL,
|
NULL,
|
||||||
0, NULL);
|
0, NULL);
|
||||||
TALER_EXCHANGE_reserve_status_cancel (wsh);
|
TALER_EXCHANGE_reserve_status_cancel (rsh);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -431,7 +497,7 @@ TALER_EXCHANGE_reserve_status (struct TALER_EXCHANGE_Handle *exchange,
|
|||||||
TALER_EXCHANGE_ReserveStatusResultCallback cb,
|
TALER_EXCHANGE_ReserveStatusResultCallback cb,
|
||||||
void *cb_cls)
|
void *cb_cls)
|
||||||
{
|
{
|
||||||
struct TALER_EXCHANGE_ReserveStatusHandle *wsh;
|
struct TALER_EXCHANGE_ReserveStatusHandle *rsh;
|
||||||
struct GNUNET_CURL_Context *ctx;
|
struct GNUNET_CURL_Context *ctx;
|
||||||
CURL *eh;
|
CURL *eh;
|
||||||
char *pub_str;
|
char *pub_str;
|
||||||
@ -449,12 +515,12 @@ TALER_EXCHANGE_reserve_status (struct TALER_EXCHANGE_Handle *exchange,
|
|||||||
"/reserve/status?reserve_pub=%s",
|
"/reserve/status?reserve_pub=%s",
|
||||||
pub_str);
|
pub_str);
|
||||||
GNUNET_free (pub_str);
|
GNUNET_free (pub_str);
|
||||||
wsh = GNUNET_new (struct TALER_EXCHANGE_ReserveStatusHandle);
|
rsh = GNUNET_new (struct TALER_EXCHANGE_ReserveStatusHandle);
|
||||||
wsh->exchange = exchange;
|
rsh->exchange = exchange;
|
||||||
wsh->cb = cb;
|
rsh->cb = cb;
|
||||||
wsh->cb_cls = cb_cls;
|
rsh->cb_cls = cb_cls;
|
||||||
wsh->reserve_pub = *reserve_pub;
|
rsh->reserve_pub = *reserve_pub;
|
||||||
wsh->url = MAH_path_to_url (exchange,
|
rsh->url = MAH_path_to_url (exchange,
|
||||||
arg_str);
|
arg_str);
|
||||||
GNUNET_free (arg_str);
|
GNUNET_free (arg_str);
|
||||||
|
|
||||||
@ -462,14 +528,14 @@ TALER_EXCHANGE_reserve_status (struct TALER_EXCHANGE_Handle *exchange,
|
|||||||
GNUNET_assert (CURLE_OK ==
|
GNUNET_assert (CURLE_OK ==
|
||||||
curl_easy_setopt (eh,
|
curl_easy_setopt (eh,
|
||||||
CURLOPT_URL,
|
CURLOPT_URL,
|
||||||
wsh->url));
|
rsh->url));
|
||||||
ctx = MAH_handle_to_context (exchange);
|
ctx = MAH_handle_to_context (exchange);
|
||||||
wsh->job = GNUNET_CURL_job_add (ctx,
|
rsh->job = GNUNET_CURL_job_add (ctx,
|
||||||
eh,
|
eh,
|
||||||
GNUNET_NO,
|
GNUNET_NO,
|
||||||
&handle_reserve_status_finished,
|
&handle_reserve_status_finished,
|
||||||
wsh);
|
rsh);
|
||||||
return wsh;
|
return rsh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -477,18 +543,18 @@ TALER_EXCHANGE_reserve_status (struct TALER_EXCHANGE_Handle *exchange,
|
|||||||
* Cancel a withdraw status request. This function cannot be used
|
* Cancel a withdraw status request. This function cannot be used
|
||||||
* on a request handle if a response is already served for it.
|
* on a request handle if a response is already served for it.
|
||||||
*
|
*
|
||||||
* @param wsh the withdraw status request handle
|
* @param rsh the withdraw status request handle
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
TALER_EXCHANGE_reserve_status_cancel (struct TALER_EXCHANGE_ReserveStatusHandle *wsh)
|
TALER_EXCHANGE_reserve_status_cancel (struct TALER_EXCHANGE_ReserveStatusHandle *rsh)
|
||||||
{
|
{
|
||||||
if (NULL != wsh->job)
|
if (NULL != rsh->job)
|
||||||
{
|
{
|
||||||
GNUNET_CURL_job_cancel (wsh->job);
|
GNUNET_CURL_job_cancel (rsh->job);
|
||||||
wsh->job = NULL;
|
rsh->job = NULL;
|
||||||
}
|
}
|
||||||
GNUNET_free (wsh->url);
|
GNUNET_free (rsh->url);
|
||||||
GNUNET_free (wsh);
|
GNUNET_free (rsh);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -663,7 +729,8 @@ reserve_withdraw_payment_required (struct TALER_EXCHANGE_ReserveWithdrawHandle *
|
|||||||
struct TALER_EXCHANGE_ReserveHistory rhistory[len];
|
struct TALER_EXCHANGE_ReserveHistory rhistory[len];
|
||||||
|
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
parse_reserve_history (history,
|
parse_reserve_history (wsh->exchange,
|
||||||
|
history,
|
||||||
&wsh->reserve_pub,
|
&wsh->reserve_pub,
|
||||||
balance.currency,
|
balance.currency,
|
||||||
&balance_from_history,
|
&balance_from_history,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
This file is part of TALER
|
This file is part of TALER
|
||||||
Copyright (C) 2014, 2015, 2016 GNUnet e.V.
|
Copyright (C) 2014-2017 GNUnet e.V.
|
||||||
|
|
||||||
TALER is free software; you can redistribute it and/or modify it under the
|
TALER is free software; you can redistribute it and/or modify it under the
|
||||||
terms of the GNU Affero General Public License as published by the Free Software
|
terms of the GNU Affero General Public License as published by the Free Software
|
||||||
@ -658,7 +658,17 @@ enum TALER_EXCHANGE_ReserveTransactionType {
|
|||||||
/**
|
/**
|
||||||
* Withdrawal from the reserve.
|
* Withdrawal from the reserve.
|
||||||
*/
|
*/
|
||||||
TALER_EXCHANGE_RTT_WITHDRAWAL
|
TALER_EXCHANGE_RTT_WITHDRAWAL,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* /payback operation.
|
||||||
|
*/
|
||||||
|
TALER_EXCHANGE_RTT_PAYBACK,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reserve closed operation.
|
||||||
|
*/
|
||||||
|
TALER_EXCHANGE_RTT_CLOSE
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -684,6 +694,10 @@ struct TALER_EXCHANGE_ReserveHistory
|
|||||||
*/
|
*/
|
||||||
union {
|
union {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Information about a deposit that filled this reserve.
|
||||||
|
* @e type is #TALER_EXCHANGE_RTT_DEPOSIT.
|
||||||
|
*/
|
||||||
struct {
|
struct {
|
||||||
/**
|
/**
|
||||||
* Sender account information for the incoming transfer.
|
* Sender account information for the incoming transfer.
|
||||||
@ -695,14 +709,60 @@ struct TALER_EXCHANGE_ReserveHistory
|
|||||||
*/
|
*/
|
||||||
json_t *transfer_details;
|
json_t *transfer_details;
|
||||||
|
|
||||||
|
|
||||||
} in_details;
|
} in_details;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Signature authorizing the withdrawal for outgoing transaction.
|
* Signature authorizing the withdrawal for outgoing transaction.
|
||||||
|
* @e type is #TALER_EXCHANGE_RTT_WITHDRAWAL.
|
||||||
*/
|
*/
|
||||||
json_t *out_authorization_sig;
|
json_t *out_authorization_sig;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Information provided if the reserve was filled via /payback.
|
||||||
|
* @e type is #TALER_EXCHANGE_RTT_PAYBACK.
|
||||||
|
*/
|
||||||
|
struct {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Public key of the coin that was paid back.
|
||||||
|
*/
|
||||||
|
struct TALER_CoinSpendPublicKeyP coin_pub;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Signature of the coin of type
|
||||||
|
* #TALER_SIGNATURE_EXCHANGE_CONFIRM_PAYBACK.
|
||||||
|
*/
|
||||||
|
struct TALER_ExchangeSignatureP exchange_sig;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Public key of the exchange that was used for @e exchange_sig.
|
||||||
|
*/
|
||||||
|
struct TALER_ExchangePublicKeyP exchange_pub;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When did the /payback operation happen?
|
||||||
|
*/
|
||||||
|
struct GNUNET_TIME_Absolute timestamp;
|
||||||
|
|
||||||
|
} payback_details;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Information about a close operation of the reserve.
|
||||||
|
* @e type is #TALER_EXCHANGE_RTT_CLOSE.
|
||||||
|
*/
|
||||||
|
struct {
|
||||||
|
/**
|
||||||
|
* Receiver account information for the outgoing wire transfer.
|
||||||
|
*/
|
||||||
|
json_t *receiver_account_details;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wire transfer details for the outgoing wire transfer.
|
||||||
|
*/
|
||||||
|
json_t *transfer_details;
|
||||||
|
|
||||||
|
} close_details;
|
||||||
|
|
||||||
} details;
|
} details;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -537,8 +537,8 @@ struct TALER_EXCHANGEDB_LinkDataList
|
|||||||
* @brief Enumeration to classify the different types of transactions
|
* @brief Enumeration to classify the different types of transactions
|
||||||
* that can be done with a coin.
|
* that can be done with a coin.
|
||||||
*/
|
*/
|
||||||
enum TALER_EXCHANGEDB_TransactionType
|
enum TALER_EXCHANGEDB_TransactionType {
|
||||||
{
|
|
||||||
/**
|
/**
|
||||||
* /deposit operation.
|
* /deposit operation.
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user