work on purse creation logic
This commit is contained in:
parent
747ae5ef09
commit
caf66486e7
@ -1 +1 @@
|
||||
Subproject commit 25eb78f2d0e20a137020dd0ab1c6474123843dbe
|
||||
Subproject commit b799c63db9beda99e9151e7611a1ac4e810786ab
|
@ -178,7 +178,6 @@ deposit_transaction (void *cls,
|
||||
}
|
||||
if (in_conflict)
|
||||
{
|
||||
TEH_plugin->rollback (TEH_plugin->cls);
|
||||
*mhd_ret
|
||||
= TEH_RESPONSE_reply_coin_insufficient_funds (
|
||||
connection,
|
||||
@ -188,7 +187,6 @@ deposit_transaction (void *cls,
|
||||
}
|
||||
if (! balance_ok)
|
||||
{
|
||||
TEH_plugin->rollback (TEH_plugin->cls);
|
||||
*mhd_ret
|
||||
= TEH_RESPONSE_reply_coin_insufficient_funds (
|
||||
connection,
|
||||
@ -323,6 +321,16 @@ TEH_handler_deposit (struct MHD_Connection *connection,
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
return mret;
|
||||
}
|
||||
if (0 > TALER_amount_cmp (&dk->meta.value,
|
||||
&deposit.amount_with_fee))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
return TALER_MHD_reply_with_error (connection,
|
||||
MHD_HTTP_BAD_REQUEST,
|
||||
TALER_EC_EXCHANGE_GENERIC_AMOUNT_EXCEEDS_DENOMINATION_VALUE,
|
||||
NULL);
|
||||
}
|
||||
if (GNUNET_TIME_absolute_is_past (dk->meta.expire_deposit.abs_time))
|
||||
{
|
||||
/* This denomination is past the expiration time for deposits */
|
||||
|
@ -183,7 +183,6 @@ melt_transaction (void *cls,
|
||||
if (rmc->zombie_required)
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
TEH_plugin->rollback (TEH_plugin->cls);
|
||||
*mhd_ret = TALER_MHD_reply_with_error (connection,
|
||||
MHD_HTTP_BAD_REQUEST,
|
||||
TALER_EC_EXCHANGE_MELT_COIN_EXPIRED_NO_ZOMBIE,
|
||||
@ -193,7 +192,6 @@ melt_transaction (void *cls,
|
||||
if (! balance_ok)
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
TEH_plugin->rollback (TEH_plugin->cls);
|
||||
*mhd_ret
|
||||
= TEH_RESPONSE_reply_coin_insufficient_funds (
|
||||
connection,
|
||||
|
@ -58,6 +58,11 @@ struct Coin
|
||||
* Deposit fee applicable for this coin.
|
||||
*/
|
||||
struct TALER_Amount deposit_fee;
|
||||
|
||||
/**
|
||||
* Amount to be put into the purse from this coin.
|
||||
*/
|
||||
struct TALER_Amount amount_minus_fee;
|
||||
};
|
||||
|
||||
|
||||
@ -147,22 +152,22 @@ reply_create_success (struct MHD_Connection *connection,
|
||||
{
|
||||
struct TALER_ExchangePublicKeyP pub;
|
||||
struct TALER_ExchangeSignatureP sig;
|
||||
// FIXME: define what exactly we sign over!
|
||||
struct TALER_DepositConfirmationPS dc = {
|
||||
.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_CREATION),
|
||||
.purpose.size = htonl (sizeof (dc)),
|
||||
.h_contract_terms = pcc->h_contract_terms,
|
||||
.purse_pub = *pcc->purse_pub
|
||||
};
|
||||
enum TALER_ErrorCode ec;
|
||||
|
||||
TALER_amount_hton (&dc.amount_without_fee,
|
||||
&pcc->amount);
|
||||
if (TALER_EC_NONE !=
|
||||
(ec = TEH_keys_exchange_sign (&dc,
|
||||
&pub,
|
||||
&sig)))
|
||||
(ec = TALER_exchange_online_purse_created_sign (
|
||||
&TEH_keys_exchange_sign_,
|
||||
pcc->exchange_timestamp,
|
||||
pcc->purse_expiration,
|
||||
&pcc->amount,
|
||||
&pcc->total_deposited,
|
||||
pcc->purse_pub,
|
||||
&pcc->merge_pub,
|
||||
&pcc->h_contract_terms,
|
||||
&pub,
|
||||
&sig)))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
return TALER_MHD_reply_with_ec (connection,
|
||||
ec,
|
||||
NULL);
|
||||
@ -170,8 +175,10 @@ reply_create_success (struct MHD_Connection *connection,
|
||||
return TALER_MHD_REPLY_JSON_PACK (
|
||||
connection,
|
||||
MHD_HTTP_OK,
|
||||
// GNUNET_JSON_pack_timestamp ("exchange_timestamp",
|
||||
// pcc->exchange_timestamp),
|
||||
GNUNET_JSON_pack_amount ("total_deposited",
|
||||
&pcc->deposit_total),
|
||||
GNUNET_JSON_pack_timestamp ("exchange_timestamp",
|
||||
pcc->exchange_timestamp),
|
||||
GNUNET_JSON_pack_data_auto ("exchange_sig",
|
||||
&sig),
|
||||
GNUNET_JSON_pack_data_auto ("exchange_pub",
|
||||
@ -199,14 +206,120 @@ create_transaction (void *cls,
|
||||
{
|
||||
struct PurseCreateContext *pcc = cls;
|
||||
enum GNUNET_DB_QueryStatus qs;
|
||||
bool balance_ok;
|
||||
bool in_conflict;
|
||||
bool in_conflict = true;
|
||||
|
||||
// 1) create purse
|
||||
// 2) deposit all coins
|
||||
// 3) if present, persist contract
|
||||
// Also: nicely report errors...
|
||||
qs = TEH_plugin->XXX (TEH_plugin->cls, ...);
|
||||
/* 1) create purse */
|
||||
qs = TEH_plugin->insert_purse_request (TEH_plugin->cls,
|
||||
&pcc->purse_pub,
|
||||
&pcc->merge_pub,
|
||||
pcc->purse_expiration,
|
||||
&pcc->h_contract_terms,
|
||||
pcc->min_age,
|
||||
&pcc->amount,
|
||||
&pcc->purse_sig,
|
||||
&in_conflict);
|
||||
if (qs < 0)
|
||||
{
|
||||
if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
|
||||
return qs;
|
||||
TALER_LOG_WARNING (
|
||||
"Failed to store create purse information in database\n");
|
||||
*mhd_ret =
|
||||
TALER_MHD_reply_with_error (connection,
|
||||
MHD_HTTP_INTERNAL_SERVER_ERROR,
|
||||
TALER_EC_GENERIC_DB_STORE_FAILED,
|
||||
"purse create");
|
||||
return qs;
|
||||
}
|
||||
if (in_conflict)
|
||||
{
|
||||
struct TALER_PurseMergePublicKeyP merge_pub;
|
||||
struct GNUNET_TIME_Timestamp purse_expiration;
|
||||
struct TALER_PrivateContractHashP h_contract_terms;
|
||||
struct TALER_Amount target_amount;
|
||||
struct TALER_Amount balance;
|
||||
struct TALER_PurseContractSignatureP purse_sig;
|
||||
|
||||
TEH_plugin->rollback (TEH_plugin->cls);
|
||||
qs = TEH_plugin->select_purse_request (TEH_plugin->cls,
|
||||
pcc->purse_pub,
|
||||
&merge_pub,
|
||||
&purse_expiration,
|
||||
&h_contract_terms,
|
||||
&target_amount,
|
||||
&balance,
|
||||
&purse_sig);
|
||||
if (qs < 0)
|
||||
{
|
||||
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR != qs);
|
||||
TALER_LOG_WARNING ("Failed to fetch purse information from database\n");
|
||||
*mhd_ret = TALER_MHD_reply_with_error (connection,
|
||||
MHD_HTTP_INTERNAL_SERVER_ERROR,
|
||||
TALER_EC_GENERIC_DB_FETCH_FAILED,
|
||||
"select purse request");
|
||||
return GNUNET_DB_STATUS_HARD_ERROR;
|
||||
}
|
||||
*mhd_ret
|
||||
= return TALER_MHD_REPLY_JSON_PACK (
|
||||
connection,
|
||||
MHD_HTTP_CONFLICT,
|
||||
TALER_JSON_pack_ec (
|
||||
TALER_EC_EXCHANGE_PURSE_CREATE_CONFLICTING_META_DATA),
|
||||
GNUNET_JSON_pack_amount ("amount",
|
||||
&amount),
|
||||
GNUNET_JSON_pack_timestamp ("purse_expiration",
|
||||
purse_expiration),
|
||||
GNUNET_JSON_pack_data_auto ("purse_sig",
|
||||
&purse_sig),
|
||||
GNUNET_JSON_pack_data_auto ("h_contract_terms",
|
||||
&h_contract_terms),
|
||||
GNUNET_JSON_pack_data_auto ("merge_pub",
|
||||
&merge_pub));
|
||||
return GNUNET_DB_STATUS_HARD_ERROR;
|
||||
}
|
||||
/* 2) deposit all coins */
|
||||
for (unsigned int i = 0; i<pcc->num_coins; i++)
|
||||
{
|
||||
struct Coin *coin = &pcc->coins[i];
|
||||
bool balance_ok = false;
|
||||
|
||||
qs = TEH_plugin->do_purse_deposit (TEH_plugin->cls,
|
||||
&pcc->purse_pub,
|
||||
&coin->cpi.coin_pub,
|
||||
&coin->amount,
|
||||
&coin->coin_sig,
|
||||
&coin->amount_minus_fee,
|
||||
&balance_ok);
|
||||
if (qs < 0)
|
||||
{
|
||||
if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
|
||||
return qs;
|
||||
TALER_LOG_WARNING (
|
||||
"Failed to store purse deposit information in database\n");
|
||||
*mhd_ret = TALER_MHD_reply_with_error (connection,
|
||||
MHD_HTTP_INTERNAL_SERVER_ERROR,
|
||||
TALER_EC_GENERIC_DB_STORE_FAILED,
|
||||
"purse create deposit");
|
||||
return qs;
|
||||
}
|
||||
if (! balance_ok)
|
||||
{
|
||||
*mhd_ret
|
||||
= TEH_RESPONSE_reply_coin_insufficient_funds (
|
||||
connection,
|
||||
TALER_EC_EXCHANGE_GENERIC_INSUFFICIENT_FUNDS,
|
||||
&coin->pci.coin_pub);
|
||||
return GNUNET_DB_STATUS_HARD_ERROR;
|
||||
}
|
||||
}
|
||||
/* 3) if present, persist contract */
|
||||
in_conflict = true;
|
||||
qs = TEH_plugin->insert_contract (TEH_plugin->cls,
|
||||
&pcc->purse_pub,
|
||||
&pcc->contract_pub,
|
||||
pcc->econtract_size,
|
||||
pcc->econtract,
|
||||
&in_conflict);
|
||||
if (qs < 0)
|
||||
{
|
||||
if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
|
||||
@ -215,27 +328,21 @@ create_transaction (void *cls,
|
||||
*mhd_ret = TALER_MHD_reply_with_error (connection,
|
||||
MHD_HTTP_INTERNAL_SERVER_ERROR,
|
||||
TALER_EC_GENERIC_DB_STORE_FAILED,
|
||||
"purse create");
|
||||
"purse create contract");
|
||||
return qs;
|
||||
}
|
||||
if (in_conflict)
|
||||
{
|
||||
TEH_plugin->rollback (TEH_plugin->cls);
|
||||
/* FIXME-DESIGN: we have no proof that the
|
||||
client is at fault here!
|
||||
=> need 2nd client signature over the encrypted
|
||||
contract (and ECDHE public key)!!! */
|
||||
*mhd_ret
|
||||
= TEH_RESPONSE_reply_coin_insufficient_funds (
|
||||
= TEH_RESPONSE_reply_with_error (
|
||||
connection,
|
||||
TALER_EC_EXCHANGE_PURSE_CREATE_CONFLICTING_CONTRACT,
|
||||
&coin->pci.coin_pub);
|
||||
return GNUNET_DB_STATUS_HARD_ERROR;
|
||||
}
|
||||
if (! balance_ok)
|
||||
{
|
||||
TEH_plugin->rollback (TEH_plugin->cls);
|
||||
*mhd_ret
|
||||
= TEH_RESPONSE_reply_coin_insufficient_funds (
|
||||
connection,
|
||||
TALER_EC_EXCHANGE_GENERIC_INSUFFICIENT_FUNDS,
|
||||
&coin->pci.coin_pub);
|
||||
MHD_HTTP_INTERNAL_SERVER_ERROR,
|
||||
TALER_EC_EXCHANGE_PURSE_CREATE_CONFLICTING_CONTRACT_STORED,
|
||||
NULL);
|
||||
return GNUNET_DB_STATUS_HARD_ERROR;
|
||||
}
|
||||
return qs;
|
||||
@ -289,7 +396,7 @@ parse_coin (struct MHD_Connection *connection,
|
||||
}
|
||||
|
||||
if (GNUNET_OK !=
|
||||
TALER_wallet_purse_deposit_verify ("http://FIXME-URL",
|
||||
TALER_wallet_purse_deposit_verify (TEH_base_url,
|
||||
&pcc->purse_pub,
|
||||
&pcc->amount,
|
||||
&coin->coin_pub,
|
||||
@ -301,7 +408,7 @@ parse_coin (struct MHD_Connection *connection,
|
||||
TALER_MHD_reply_with_error (connection,
|
||||
MHD_HTTP_UNAUTHORIZED,
|
||||
TALER_EC_EXCHANGE_PURSE_CREATE_COIN_SIGNATURE_INVALID,
|
||||
NULL))
|
||||
TEH_base_url))
|
||||
? GNUNET_NO : GNUNET_SYSERR;
|
||||
}
|
||||
/* check denomination exists and is valid */
|
||||
@ -317,6 +424,18 @@ parse_coin (struct MHD_Connection *connection,
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
return (MHD_YES == mret) ? GNUNET_NO : GNUNET_SYSERR:
|
||||
}
|
||||
if (0 > TALER_amount_cmp (&dk->meta.value,
|
||||
&coin->amount))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
return (MHD_YES ==
|
||||
TALER_MHD_reply_with_error (connection,
|
||||
MHD_HTTP_BAD_REQUEST,
|
||||
TALER_EC_EXCHANGE_GENERIC_AMOUNT_EXCEEDS_DENOMINATION_VALUE,
|
||||
NULL))
|
||||
? GNUNET_NO : GNUNET_SYSERR;
|
||||
}
|
||||
if (GNUNET_TIME_absolute_is_past (dk->meta.expire_deposit.abs_time))
|
||||
{
|
||||
/* This denomination is past the expiration time for deposits */
|
||||
@ -366,6 +485,20 @@ parse_coin (struct MHD_Connection *connection,
|
||||
}
|
||||
|
||||
coin->deposit_fee = dk->meta.fees.deposit;
|
||||
if (0 < TALER_amount_cmp (&coin->deposit_fee,
|
||||
&coin->amount))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
return TALER_MHD_reply_with_error (connection,
|
||||
MHD_HTTP_BAD_REQUEST,
|
||||
TALER_EC_EXCHANGE_DEPOSIT_NEGATIVE_VALUE_AFTER_FEE,
|
||||
NULL);
|
||||
}
|
||||
GNUNET_assert (0 <=
|
||||
TALER_amount_subtact (&coin->amount_minus_fee,
|
||||
&coin->amount,
|
||||
&coin->deposit_fee));
|
||||
/* check coin signature */
|
||||
switch (dk->denom_pub.cipher)
|
||||
{
|
||||
@ -391,6 +524,17 @@ parse_coin (struct MHD_Connection *connection,
|
||||
NULL))
|
||||
? GNUNET_NO : GNUNET_SYSERR;
|
||||
}
|
||||
if (0 >
|
||||
TALER_amount_add (&pcc->deposit_total,
|
||||
&pcc->deposit_total,
|
||||
&coin->amount_minus_fee))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
return TALER_MHD_reply_with_error (connection,
|
||||
MHD_HTTP_INTERNAL_SERVER_ERROR,
|
||||
TALER_EC_GENERIC_FAILED_COMPUTE_AMOUNT,
|
||||
"total deposit contribution");
|
||||
}
|
||||
}
|
||||
{
|
||||
MHD_RESULT mhd_ret = MHD_NO;
|
||||
@ -425,10 +569,10 @@ parse_coin (struct MHD_Connection *connection,
|
||||
|
||||
|
||||
MHD_RESULT
|
||||
TEH_handler_purses_create (struct MHD_Connection *connection,
|
||||
const struct
|
||||
TALER_PurseContractPublicKeyP *purse_pub,
|
||||
const json_t *root)
|
||||
TEH_handler_purses_create (
|
||||
struct MHD_Connection *connection,
|
||||
const struct TALER_PurseContractPublicKeyP *purse_pub,
|
||||
const json_t *root)
|
||||
{
|
||||
struct PurseCreateContext pcc = {
|
||||
.purse_pub = purse_pub,
|
||||
@ -461,6 +605,7 @@ TEH_handler_purses_create (struct MHD_Connection *connection,
|
||||
&pcc.purse_expiration),
|
||||
GNUNET_JSON_spec_end ()
|
||||
};
|
||||
const struct TEH_GlobalFee *gf;
|
||||
|
||||
{
|
||||
enum GNUNET_GenericReturnValue res;
|
||||
@ -479,7 +624,9 @@ TEH_handler_purses_create (struct MHD_Connection *connection,
|
||||
return MHD_YES; /* failure */
|
||||
}
|
||||
}
|
||||
|
||||
GNUNET_assert (GNUNET_OK ==
|
||||
TALER_amount_set_zero (TEH_currency,
|
||||
&pcc.deposit_total));
|
||||
if (GNUNET_TIME_timestamp_cmp (pcc.purse_expiration,
|
||||
<,
|
||||
pcc.exchange_timestamp))
|
||||
@ -511,6 +658,17 @@ TEH_handler_purses_create (struct MHD_Connection *connection,
|
||||
TALER_EC_EXCHANGE_GENERIC_PARAMETER_MALFORMED,
|
||||
"deposits");
|
||||
}
|
||||
gf = TEH_keys_global_fee_by_time (TEH_keys_get_state (),
|
||||
pcc.exchange_timestamp);
|
||||
if (NULL == gf)
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
|
||||
"Cannot create purse: global fees not configured!\n");
|
||||
return TALER_MHD_reply_with_error (connection,
|
||||
MHD_HTTP_INTERNAL_SERVER_ERROR,
|
||||
TALER_EC_EXCHANGE_GENERIC_GLOBAL_FEES_MISSING,
|
||||
NULL);
|
||||
}
|
||||
/* parse deposits */
|
||||
pcc.coins = GNUNET_new_array (struct Coin,
|
||||
pcc.num_coins);
|
||||
@ -531,8 +689,7 @@ TEH_handler_purses_create (struct MHD_Connection *connection,
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: get purse_fee!
|
||||
if (0 < TALER_amount_cmp (&purse_fee,
|
||||
if (0 < TALER_amount_cmp (&gf->fees.purse,
|
||||
&pcc.deposit_total))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
@ -543,7 +700,6 @@ TEH_handler_purses_create (struct MHD_Connection *connection,
|
||||
TALER_EC_EXCHANGE_CREATE_PURSE_NEGATIVE_VALUE_AFTER_FEE,
|
||||
NULL);
|
||||
}
|
||||
|
||||
TEH_METRICS_num_verifications[TEH_MT_SIGNATURE_EDDSA]++;
|
||||
|
||||
if (GNUNET_OK !=
|
||||
@ -560,7 +716,7 @@ TEH_handler_purses_create (struct MHD_Connection *connection,
|
||||
GNUNET_free (pcc.coins);
|
||||
return TALER_MHD_reply_with_error (connection,
|
||||
MHD_HTTP_UNAUTHORIZED,
|
||||
TALER_EC_EXCHANGE_PURSE_CREATE_COIN_SIGNATURE_INVALID,
|
||||
TALER_EC_EXCHANGE_PURSE_CREATE_SIGNATURE_INVALID,
|
||||
NULL);
|
||||
}
|
||||
|
||||
@ -568,6 +724,7 @@ TEH_handler_purses_create (struct MHD_Connection *connection,
|
||||
TEH_plugin->preflight (TEH_plugin->cls))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
GNUNET_free (pcc.coins);
|
||||
return TALER_MHD_reply_with_error (connection,
|
||||
MHD_HTTP_INTERNAL_SERVER_ERROR,
|
||||
|
@ -256,7 +256,6 @@ withdraw_transaction (void *cls,
|
||||
}
|
||||
if (! below_limit)
|
||||
{
|
||||
TEH_plugin->rollback (TEH_plugin->cls);
|
||||
*mhd_ret = TALER_MHD_REPLY_JSON_PACK (
|
||||
connection,
|
||||
MHD_HTTP_ACCEPTED,
|
||||
|
@ -12668,6 +12668,10 @@ postgres_insert_partner (void *cls,
|
||||
* @param pub_ckey ephemeral key for DH used to encrypt the contract
|
||||
* @param econtract_size number of bytes in @a econtract
|
||||
* @param econtract the encrypted contract
|
||||
* @param[out] in_conflict set to true if @a econtract
|
||||
* conflicts with an existing contract;
|
||||
* in this case, the return value will be
|
||||
* #GNUNET_DB_STATUS_SUCCESS_ONE despite the failure
|
||||
* @return transaction status code
|
||||
*/
|
||||
static enum GNUNET_DB_QueryStatus
|
||||
@ -12675,7 +12679,8 @@ postgres_insert_contract (void *cls,
|
||||
const struct TALER_PurseContractPublicKeyP *purse_pub,
|
||||
const struct TALER_ContractDiffiePublicP *pub_ckey,
|
||||
size_t econtract_size,
|
||||
const void *econtract)
|
||||
const void *econtract,
|
||||
bool *in_conflict)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
return GNUNET_DB_STATUS_HARD_ERROR;
|
||||
@ -12715,6 +12720,10 @@ postgres_select_contract (void *cls,
|
||||
* @param age_limit age limit to enforce for payments into the purse
|
||||
* @param amount target amount (with fees) to be put into the purse
|
||||
* @param purse_sig signature with @a purse_pub's private key affirming the above
|
||||
* @param[out] in_conflict set to true if the meta data
|
||||
* conflicts with an existing purse;
|
||||
* in this case, the return value will be
|
||||
* #GNUNET_DB_STATUS_SUCCESS_ONE despite the failure
|
||||
* @return transaction status code
|
||||
*/
|
||||
static enum GNUNET_DB_QueryStatus
|
||||
@ -12726,7 +12735,8 @@ postgres_insert_purse_request (
|
||||
const struct TALER_PrivateContractHashP *h_contract_terms,
|
||||
uint32_t age_limit,
|
||||
const struct TALER_Amount *amount,
|
||||
const struct TALER_PurseContractSignatureP *purse_sig)
|
||||
const struct TALER_PurseContractSignatureP *purse_sig,
|
||||
bool *in_conflict)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
return GNUNET_DB_STATUS_HARD_ERROR;
|
||||
@ -12806,6 +12816,11 @@ postgres_select_purse_by_merge_pub (
|
||||
* @param coin_pub coin to deposit (debit)
|
||||
* @param amount fraction of the coin's value to deposit
|
||||
* @param coin_sig signature affirming the operation
|
||||
* @param amount_minus_fee amount to add to the purse
|
||||
* @param[out] balance_ok set to false if the coin's
|
||||
* remaining balance is below @a amount;
|
||||
* in this case, the return value will be
|
||||
* #GNUNET_DB_STATUS_SUCCESS_ONE despite the failure
|
||||
* @return transaction status code
|
||||
*/
|
||||
static enum GNUNET_DB_QueryStatus
|
||||
@ -12814,7 +12829,9 @@ postgres_do_purse_deposit (
|
||||
const struct TALER_PurseContractPublicKeyP *purse_pub,
|
||||
const struct TALER_CoinSpendPublicKeyP *coin_pub,
|
||||
const struct TALER_Amount *amount,
|
||||
const struct TALER_CoinSpendSignatureP *coin_sig)
|
||||
const struct TALER_CoinSpendSignatureP *coin_sig,
|
||||
const struct TALER_Amount *amount_minus_fee,
|
||||
bool *balance_ok)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
return GNUNET_DB_STATUS_HARD_ERROR;
|
||||
|
@ -3811,6 +3811,33 @@ TALER_exchange_online_reserve_closed_verify (
|
||||
const struct TALER_ExchangeSignatureP *sig);
|
||||
|
||||
|
||||
enum TALER_ErrorCode
|
||||
TALER_exchange_online_purse_created_sign (
|
||||
TALER_ExchangeSignCallback scb,
|
||||
struct GNUNET_TIME_Timestamp exchange_time,
|
||||
struct GNUNET_TIME_Timestamp purse_expiration,
|
||||
const struct TALER_Amount *amount_without_fee,
|
||||
const struct TALER_Amount *total_deposited,
|
||||
const struct TALER_PurseContractPublicKeyP *purse_pub,
|
||||
const struct TALER_PurseMergePublicKeyP *merge_pub,
|
||||
const struct TALER_PrivateContractHashP *h_contract_terms,
|
||||
struct TALER_ExchangePublicKeyP *pub,
|
||||
struct TALER_ExchangeSignatureP *sig);
|
||||
|
||||
|
||||
enum GNUNET_GenericReturnValue
|
||||
TALER_exchange_online_purse_created_verify (
|
||||
struct GNUNET_TIME_Timestamp exchange_time,
|
||||
struct GNUNET_TIME_Timestamp purse_expiration,
|
||||
const struct TALER_Amount *amount_without_fee,
|
||||
const struct TALER_Amount *total_deposited,
|
||||
const struct TALER_PurseContractPublicKeyP *purse_pub,
|
||||
const struct TALER_PurseMergePublicKeyP *merge_pub,
|
||||
const struct TALER_PrivateContractHashP *h_contract_terms,
|
||||
const struct TALER_ExchangePublicKeyP *pub,
|
||||
const struct TALER_ExchangeSignatureP *sig);
|
||||
|
||||
|
||||
/* ********************* offline signing ************************** */
|
||||
|
||||
|
||||
|
@ -4389,6 +4389,10 @@ struct TALER_EXCHANGEDB_Plugin
|
||||
* @param pub_ckey ephemeral key for DH used to encrypt the contract
|
||||
* @param econtract_size number of bytes in @a econtract
|
||||
* @param econtract the encrypted contract
|
||||
* @param[out] in_conflict set to true if @a econtract
|
||||
* conflicts with an existing contract;
|
||||
* in this case, the return value will be
|
||||
* #GNUNET_DB_STATUS_SUCCESS_ONE despite the failure
|
||||
* @return transaction status code
|
||||
*/
|
||||
enum GNUNET_DB_QueryStatus
|
||||
@ -4396,7 +4400,8 @@ struct TALER_EXCHANGEDB_Plugin
|
||||
const struct TALER_PurseContractPublicKeyP *purse_pub,
|
||||
const struct TALER_ContractDiffiePublicP *pub_ckey,
|
||||
size_t econtract_size,
|
||||
const void *econtract);
|
||||
const void *econtract,
|
||||
bool *in_conflict);
|
||||
|
||||
|
||||
/**
|
||||
@ -4428,6 +4433,10 @@ struct TALER_EXCHANGEDB_Plugin
|
||||
* @param age_limit age limit to enforce for payments into the purse
|
||||
* @param amount target amount (with fees) to be put into the purse
|
||||
* @param purse_sig signature with @a purse_pub's private key affirming the above
|
||||
* @param[out] in_conflict set to true if the meta data
|
||||
* conflicts with an existing purse;
|
||||
* in this case, the return value will be
|
||||
* #GNUNET_DB_STATUS_SUCCESS_ONE despite the failure
|
||||
* @return transaction status code
|
||||
*/
|
||||
enum GNUNET_DB_QueryStatus
|
||||
@ -4439,7 +4448,8 @@ struct TALER_EXCHANGEDB_Plugin
|
||||
const struct TALER_PrivateContractHashP *h_contract_terms,
|
||||
uint32_t age_limit,
|
||||
const struct TALER_Amount *amount,
|
||||
const struct TALER_PurseContractSignatureP *purse_sig);
|
||||
const struct TALER_PurseContractSignatureP *purse_sig,
|
||||
bool *in_conflict);
|
||||
|
||||
|
||||
/**
|
||||
@ -4507,6 +4517,11 @@ struct TALER_EXCHANGEDB_Plugin
|
||||
* @param coin_pub coin to deposit (debit)
|
||||
* @param amount fraction of the coin's value to deposit
|
||||
* @param coin_sig signature affirming the operation
|
||||
* @param amount_minus_fee amount to add to the purse
|
||||
* @param[out] balance_ok set to false if the coin's
|
||||
* remaining balance is below @a amount;
|
||||
* in this case, the return value will be
|
||||
* #GNUNET_DB_STATUS_SUCCESS_ONE despite the failure
|
||||
* @return transaction status code
|
||||
*/
|
||||
enum GNUNET_DB_QueryStatus
|
||||
@ -4515,7 +4530,9 @@ struct TALER_EXCHANGEDB_Plugin
|
||||
const struct TALER_PurseContractPublicKeyP *purse_pub,
|
||||
const struct TALER_CoinSpendPublicKeyP *coin_pub,
|
||||
const struct TALER_Amount *amount,
|
||||
const struct TALER_CoinSpendSignatureP *coin_sig);
|
||||
const struct TALER_CoinSpendSignatureP *coin_sig,
|
||||
const struct TALER_Amount *amount_minus_fee,
|
||||
bool *balance_ok);
|
||||
|
||||
|
||||
/**
|
||||
|
@ -176,6 +176,11 @@
|
||||
*/
|
||||
#define TALER_SIGNATURE_EXCHANGE_ACCOUNT_SETUP_SUCCESS 1044
|
||||
|
||||
/**
|
||||
* Signature by which the exchange affirms that a purse
|
||||
* was created with a certain amount deposited into it.
|
||||
*/
|
||||
#define TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_CREATION 1045
|
||||
|
||||
/**********************/
|
||||
/* Auditor signatures */
|
||||
|
@ -1261,4 +1261,117 @@ TALER_exchange_online_reserve_closed_verify (
|
||||
}
|
||||
|
||||
|
||||
GNUNET_NETWORK_STRUCT_BEGIN
|
||||
|
||||
/**
|
||||
* Response by which the exchange affirms that it has
|
||||
* received funds deposited into a purse.
|
||||
*/
|
||||
struct TALER_PurseCreateDepositConfirmationPS
|
||||
{
|
||||
|
||||
/**
|
||||
* Purpose is #TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_CREATION
|
||||
*/
|
||||
struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
|
||||
|
||||
/**
|
||||
* When did the exchange receive the deposits.
|
||||
*/
|
||||
struct GNUNET_TIME_TimestampNBO exchange_time;
|
||||
|
||||
/**
|
||||
* When will the purse expire?
|
||||
*/
|
||||
struct GNUNET_TIME_TimestampNBO purse_expiration;
|
||||
|
||||
/**
|
||||
* How much should the purse ultimately contain.
|
||||
*/
|
||||
struct TALER_AmountNBO amount_without_fee;
|
||||
|
||||
/**
|
||||
* How much was deposited so far.
|
||||
*/
|
||||
struct TALER_AmountNBO total_deposited;
|
||||
|
||||
/**
|
||||
* Public key of the purse.
|
||||
*/
|
||||
struct TALER_PurseContractPublicKeyP purse_pub;
|
||||
|
||||
/**
|
||||
* Public key of the merge capability.
|
||||
*/
|
||||
struct TALER_PurseMergePublicKeyP merge_pub;
|
||||
|
||||
/**
|
||||
* Hash of the contract of the purse.
|
||||
*/
|
||||
struct TALER_PrivateContractHashP h_contract_terms;
|
||||
|
||||
};
|
||||
|
||||
GNUNET_NETWORK_STRUCT_END
|
||||
|
||||
|
||||
enum TALER_ErrorCode
|
||||
TALER_exchange_online_purse_created_sign (
|
||||
TALER_ExchangeSignCallback scb,
|
||||
struct GNUNET_TIME_Timestamp exchange_time,
|
||||
struct GNUNET_TIME_Timestamp purse_expiration,
|
||||
const struct TALER_Amount *amount_without_fee,
|
||||
const struct TALER_Amount *total_deposited,
|
||||
const struct TALER_PurseContractPublicKeyP *purse_pub,
|
||||
const struct TALER_PurseMergePublicKeyP *merge_pub,
|
||||
const struct TALER_PrivateContractHashP *h_contract_terms,
|
||||
struct TALER_ExchangePublicKeyP *pub,
|
||||
struct TALER_ExchangeSignatureP *sig)
|
||||
{
|
||||
struct TALER_PurseCreateDepositConfirmationPS dc = {
|
||||
.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_CREATION),
|
||||
.purpose.size = htonl (sizeof (dc)),
|
||||
.h_contract_terms = *h_contract_terms,
|
||||
.purse_pub = *purse_pub,
|
||||
.merge_pub = *merge_pub,
|
||||
.purse_expiration = GNUNET_TIME_timestamp_hton (purse_expiration),
|
||||
.exchange_time = GNUNET_TIME_timestamp_hton (exchange_time)
|
||||
};
|
||||
|
||||
return scb (&dc.purpose,
|
||||
pub,
|
||||
sig);
|
||||
}
|
||||
|
||||
|
||||
enum GNUNET_GenericReturnValue
|
||||
TALER_exchange_online_purse_created_verify (
|
||||
struct GNUNET_TIME_Timestamp exchange_time,
|
||||
struct GNUNET_TIME_Timestamp purse_expiration,
|
||||
const struct TALER_Amount *amount_without_fee,
|
||||
const struct TALER_Amount *total_deposited,
|
||||
const struct TALER_PurseContractPublicKeyP *purse_pub,
|
||||
const struct TALER_PurseMergePublicKeyP *merge_pub,
|
||||
const struct TALER_PrivateContractHashP *h_contract_terms,
|
||||
const struct TALER_ExchangePublicKeyP *pub,
|
||||
const struct TALER_ExchangeSignatureP *sig)
|
||||
{
|
||||
struct TALER_PurseCreateDepositConfirmationPS dc = {
|
||||
.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_CREATION),
|
||||
.purpose.size = htonl (sizeof (dc)),
|
||||
.h_contract_terms = *h_contract_terms,
|
||||
.purse_pub = *purse_pub,
|
||||
.merge_pub = *merge_pub,
|
||||
.purse_expiration = GNUNET_TIME_timestamp_hton (purse_expiration),
|
||||
.exchange_time = GNUNET_TIME_timestamp_hton (exchange_time)
|
||||
};
|
||||
|
||||
return
|
||||
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_CREATION,
|
||||
&dc,
|
||||
&sig->eddsa_signature,
|
||||
&pub->eddsa_pub);
|
||||
}
|
||||
|
||||
|
||||
/* end of exchange_signatures.c */
|
||||
|
Loading…
Reference in New Issue
Block a user