complete taler-exchange-httpd_reserves_open.c logic (first pass, still without DB logic or tests)
This commit is contained in:
parent
de657800a8
commit
4a36ed7fbf
@ -83,6 +83,11 @@ struct ReserveOpenContext
|
|||||||
*/
|
*/
|
||||||
struct TALER_Amount open_cost;
|
struct TALER_Amount open_cost;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Total amount that was deposited.
|
||||||
|
*/
|
||||||
|
struct TALER_Amount total;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Information about payments by coin.
|
* Information about payments by coin.
|
||||||
*/
|
*/
|
||||||
@ -111,9 +116,16 @@ static MHD_RESULT
|
|||||||
reply_reserve_open_success (struct MHD_Connection *connection,
|
reply_reserve_open_success (struct MHD_Connection *connection,
|
||||||
const struct ReserveOpenContext *rsc)
|
const struct ReserveOpenContext *rsc)
|
||||||
{
|
{
|
||||||
|
unsigned int status;
|
||||||
|
|
||||||
|
status = MHD_HTTP_OK;
|
||||||
|
if (GNUNET_TIME_timestamp_cmp (rsc->reserve_expiration,
|
||||||
|
<,
|
||||||
|
rsc->desired_expiration))
|
||||||
|
status = MHD_HTTP_PAYMENT_REQUIRED;
|
||||||
return TALER_MHD_REPLY_JSON_PACK (
|
return TALER_MHD_REPLY_JSON_PACK (
|
||||||
connection,
|
connection,
|
||||||
MHD_HTTP_OK,
|
status,
|
||||||
GNUNET_JSON_pack_timestamp ("reserve_expiration",
|
GNUNET_JSON_pack_timestamp ("reserve_expiration",
|
||||||
rsc->reserve_expiration),
|
rsc->reserve_expiration),
|
||||||
TALER_JSON_pack_amount ("open_cost",
|
TALER_JSON_pack_amount ("open_cost",
|
||||||
@ -150,7 +162,7 @@ cleanup_rsc (struct ReserveOpenContext *rsc)
|
|||||||
* @param cls a `struct ReserveOpenContext *`
|
* @param cls a `struct ReserveOpenContext *`
|
||||||
* @param connection MHD request which triggered the transaction
|
* @param connection MHD request which triggered the transaction
|
||||||
* @param[out] mhd_ret set to MHD response status for @a connection,
|
* @param[out] mhd_ret set to MHD response status for @a connection,
|
||||||
* if transaction failed (!); unused
|
* if transaction failed (!)
|
||||||
* @return transaction status
|
* @return transaction status
|
||||||
*/
|
*/
|
||||||
static enum GNUNET_DB_QueryStatus
|
static enum GNUNET_DB_QueryStatus
|
||||||
@ -161,15 +173,63 @@ reserve_open_transaction (void *cls,
|
|||||||
struct ReserveOpenContext *rsc = cls;
|
struct ReserveOpenContext *rsc = cls;
|
||||||
enum GNUNET_DB_QueryStatus qs;
|
enum GNUNET_DB_QueryStatus qs;
|
||||||
|
|
||||||
(void) rsc;
|
for (unsigned int i = 0; i<rsc->payments_len; i++)
|
||||||
#if 0
|
{
|
||||||
// FIXME: implement!
|
struct TEH_PurseDepositedCoin *coin = &rsc->payments[i];
|
||||||
|
bool insufficient_funds = true;
|
||||||
|
|
||||||
|
qs = TEH_make_coin_known (&coin->cpi,
|
||||||
|
connection,
|
||||||
|
&coin->known_coin_id,
|
||||||
|
mhd_ret);
|
||||||
|
if (qs < 0)
|
||||||
|
return qs;
|
||||||
|
qs = TEH_plugin->insert_reserve_open_deposit (
|
||||||
|
TEH_plugin->cls,
|
||||||
|
&coin->cpi,
|
||||||
|
&coin->coin_sig,
|
||||||
|
coin->known_coin_id,
|
||||||
|
&coin->amount,
|
||||||
|
&rsc->reserve_sig,
|
||||||
|
&insufficient_funds);
|
||||||
|
/* 0 == qs is fine, then the coin was already
|
||||||
|
spent for this very operation as identified
|
||||||
|
by reserve_sig! */
|
||||||
|
if (qs < 0)
|
||||||
|
{
|
||||||
|
if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
|
||||||
|
return qs;
|
||||||
|
GNUNET_break (0);
|
||||||
|
*mhd_ret = TALER_MHD_reply_with_error (connection,
|
||||||
|
MHD_HTTP_INTERNAL_SERVER_ERROR,
|
||||||
|
TALER_EC_GENERIC_DB_STORE_FAILED,
|
||||||
|
"insert_reserve_open_deposit");
|
||||||
|
return qs;
|
||||||
|
}
|
||||||
|
if (insufficient_funds)
|
||||||
|
{
|
||||||
|
*mhd_ret
|
||||||
|
= TEH_RESPONSE_reply_coin_insufficient_funds (
|
||||||
|
connection,
|
||||||
|
TALER_EC_EXCHANGE_GENERIC_INSUFFICIENT_FUNDS,
|
||||||
|
&coin->cpi.denom_pub_hash,
|
||||||
|
&coin->cpi.coin_pub);
|
||||||
|
return GNUNET_DB_STATUS_HARD_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
qs = TEH_plugin->do_reserve_open (TEH_plugin->cls,
|
qs = TEH_plugin->do_reserve_open (TEH_plugin->cls,
|
||||||
|
/* inputs */
|
||||||
rsc->reserve_pub,
|
rsc->reserve_pub,
|
||||||
...);
|
&rsc->total,
|
||||||
#else
|
rsc->purse_limit,
|
||||||
qs = GNUNET_DB_STATUS_HARD_ERROR;
|
&rsc->reserve_sig,
|
||||||
#endif
|
rsc->desired_expiration,
|
||||||
|
rsc->timestamp,
|
||||||
|
&rsc->gf->fees.account,
|
||||||
|
/* outputs */
|
||||||
|
&rsc->open_cost,
|
||||||
|
&rsc->reserve_expiration);
|
||||||
switch (qs)
|
switch (qs)
|
||||||
{
|
{
|
||||||
case GNUNET_DB_STATUS_HARD_ERROR:
|
case GNUNET_DB_STATUS_HARD_ERROR:
|
||||||
@ -178,7 +238,7 @@ reserve_open_transaction (void *cls,
|
|||||||
= TALER_MHD_reply_with_error (connection,
|
= TALER_MHD_reply_with_error (connection,
|
||||||
MHD_HTTP_INTERNAL_SERVER_ERROR,
|
MHD_HTTP_INTERNAL_SERVER_ERROR,
|
||||||
TALER_EC_GENERIC_DB_FETCH_FAILED,
|
TALER_EC_GENERIC_DB_FETCH_FAILED,
|
||||||
"get_reserve_open");
|
"do_reserve_open");
|
||||||
return GNUNET_DB_STATUS_HARD_ERROR;
|
return GNUNET_DB_STATUS_HARD_ERROR;
|
||||||
case GNUNET_DB_STATUS_SOFT_ERROR:
|
case GNUNET_DB_STATUS_SOFT_ERROR:
|
||||||
return qs;
|
return qs;
|
||||||
@ -258,6 +318,7 @@ TEH_handler_reserves_open (struct TEH_RequestContext *rc,
|
|||||||
rsc.payments_len = json_array_size (payments);
|
rsc.payments_len = json_array_size (payments);
|
||||||
rsc.payments = GNUNET_new_array (rsc.payments_len,
|
rsc.payments = GNUNET_new_array (rsc.payments_len,
|
||||||
struct TEH_PurseDepositedCoin);
|
struct TEH_PurseDepositedCoin);
|
||||||
|
rsc.total = rsc.reserve_payment;
|
||||||
for (unsigned int i = 0; i<rsc.payments_len; i++)
|
for (unsigned int i = 0; i<rsc.payments_len; i++)
|
||||||
{
|
{
|
||||||
struct TEH_PurseDepositedCoin *coin = &rsc.payments[i];
|
struct TEH_PurseDepositedCoin *coin = &rsc.payments[i];
|
||||||
@ -280,6 +341,21 @@ TEH_handler_reserves_open (struct TEH_RequestContext *rc,
|
|||||||
cleanup_rsc (&rsc);
|
cleanup_rsc (&rsc);
|
||||||
return MHD_YES; /* failure */
|
return MHD_YES; /* failure */
|
||||||
}
|
}
|
||||||
|
/* FIXME-DOLD: Alternatively, we could here add coin->amount_minus_fee and
|
||||||
|
thereby charge the deposit fee even when paying the reserve-open fee.
|
||||||
|
To be decided... */
|
||||||
|
if (0 >
|
||||||
|
TALER_amount_add (&rsc.total,
|
||||||
|
&rsc.total,
|
||||||
|
&coin->amount))
|
||||||
|
{
|
||||||
|
GNUNET_break (0);
|
||||||
|
cleanup_rsc (&rsc);
|
||||||
|
return TALER_MHD_reply_with_error (rc->connection,
|
||||||
|
MHD_HTTP_INTERNAL_SERVER_ERROR,
|
||||||
|
TALER_EC_GENERIC_FAILED_COMPUTE_AMOUNT,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -3107,16 +3107,14 @@ TALER_wallet_reserve_open_verify (
|
|||||||
* Sign to deposit coin to pay for keeping a reserve open.
|
* Sign to deposit coin to pay for keeping a reserve open.
|
||||||
*
|
*
|
||||||
* @param coin_contribution how much the coin should contribute
|
* @param coin_contribution how much the coin should contribute
|
||||||
* @param reserve_pub public key of the reserve
|
* @param reserve_sig signature over the reserve open operation
|
||||||
* @param request_timestamp time of the open request
|
|
||||||
* @param coin_priv private key of the coin
|
* @param coin_priv private key of the coin
|
||||||
* @param[out] coin_sig signature by the coin
|
* @param[out] coin_sig signature by the coin
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
TALER_wallet_reserve_open_deposit_sign (
|
TALER_wallet_reserve_open_deposit_sign (
|
||||||
const struct TALER_Amount *coin_contribution,
|
const struct TALER_Amount *coin_contribution,
|
||||||
const struct TALER_ReservePublicKeyP *reserve_pub,
|
const struct TALER_ReserveSignatureP *reserve_sig,
|
||||||
struct GNUNET_TIME_Timestamp request_timestamp,
|
|
||||||
const struct TALER_CoinSpendPrivateKeyP *coin_priv,
|
const struct TALER_CoinSpendPrivateKeyP *coin_priv,
|
||||||
struct TALER_CoinSpendSignatureP *coin_sig);
|
struct TALER_CoinSpendSignatureP *coin_sig);
|
||||||
|
|
||||||
@ -3125,8 +3123,7 @@ TALER_wallet_reserve_open_deposit_sign (
|
|||||||
* Verify signature that deposits coin to pay for keeping a reserve open.
|
* Verify signature that deposits coin to pay for keeping a reserve open.
|
||||||
*
|
*
|
||||||
* @param coin_contribution how much the coin should contribute
|
* @param coin_contribution how much the coin should contribute
|
||||||
* @param reserve_pub public key of the reserve
|
* @param reserve_sig signature over the reserve open operation
|
||||||
* @param request_timestamp time of the open request
|
|
||||||
* @param coin_pub public key of the coin
|
* @param coin_pub public key of the coin
|
||||||
* @param coin_sig signature by the coin
|
* @param coin_sig signature by the coin
|
||||||
* @return #GNUNET_OK if the signature is valid
|
* @return #GNUNET_OK if the signature is valid
|
||||||
@ -3134,8 +3131,7 @@ TALER_wallet_reserve_open_deposit_sign (
|
|||||||
enum GNUNET_GenericReturnValue
|
enum GNUNET_GenericReturnValue
|
||||||
TALER_wallet_reserve_open_deposit_verify (
|
TALER_wallet_reserve_open_deposit_verify (
|
||||||
const struct TALER_Amount *coin_contribution,
|
const struct TALER_Amount *coin_contribution,
|
||||||
const struct TALER_ReservePublicKeyP *reserve_pub,
|
const struct TALER_ReserveSignatureP *reserve_sig,
|
||||||
struct GNUNET_TIME_Timestamp request_timestamp,
|
|
||||||
const struct TALER_CoinSpendPublicKeyP *coin_pub,
|
const struct TALER_CoinSpendPublicKeyP *coin_pub,
|
||||||
const struct TALER_CoinSpendSignatureP *coin_sig);
|
const struct TALER_CoinSpendSignatureP *coin_sig);
|
||||||
|
|
||||||
|
@ -4043,6 +4043,55 @@ struct TALER_EXCHANGEDB_Plugin
|
|||||||
void *rec_cls);
|
void *rec_cls);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert reserve open coin deposit data into database.
|
||||||
|
* Subtracts the @a coin_total from the coin's balance.
|
||||||
|
*
|
||||||
|
* @param cls closure
|
||||||
|
* @param cpi public information about the coin
|
||||||
|
* @param coin_sig signature with @e coin_pub of type #TALER_SIGNATURE_WALLET_RESERVE_OPEN_DEPOSIT
|
||||||
|
* @param known_coin_id ID of the coin in the known_coins table
|
||||||
|
* @param coin_total amount to be spent of the coin (including deposit fee)
|
||||||
|
* @param reserve_sig signature by the reserve affirming the open operation
|
||||||
|
* @param[out] insufficient_funds set to true if the coin's balance is insufficient, otherwise to false
|
||||||
|
* @return transaction status code, 0 if operation is already in the DB
|
||||||
|
*/
|
||||||
|
enum GNUNET_DB_QueryStatus
|
||||||
|
(*insert_reserve_open_deposit)(
|
||||||
|
void *cls,
|
||||||
|
const struct TALER_CoinPublicInfo *cpi,
|
||||||
|
const struct TALER_CoinSpendSignatureP *coin_sig,
|
||||||
|
uint64_t known_coin_id,
|
||||||
|
const struct TALER_Amount *coin_total,
|
||||||
|
const struct TALER_ReserveSignatureP *reserve_sig,
|
||||||
|
bool *insufficient_funds);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert reserve close operation into database.
|
||||||
|
*
|
||||||
|
* @param cls closure
|
||||||
|
* @param reserve_pub which reserve is this about?
|
||||||
|
* @param execution_date when did we perform the transfer?
|
||||||
|
* @param receiver_account to which account do we transfer, in payto://-format
|
||||||
|
* @param wtid identifier for the wire transfer
|
||||||
|
* @param amount_with_fee amount we charged to the reserve
|
||||||
|
* @param closing_fee how high is the closing fee
|
||||||
|
* @return transaction status code
|
||||||
|
*/
|
||||||
|
enum GNUNET_DB_QueryStatus
|
||||||
|
(*do_reserve_open)(void *cls,
|
||||||
|
const struct TALER_ReservePublicKeyP *reserve_pub,
|
||||||
|
const struct TALER_Amount *total_paid,
|
||||||
|
uint32_t min_purse_limit,
|
||||||
|
const struct TALER_ReserveSignatureP *reserve_sig,
|
||||||
|
struct GNUNET_TIME_Timestamp desired_expiration,
|
||||||
|
struct GNUNET_TIME_Timestamp now,
|
||||||
|
const struct TALER_Amount *open_fee,
|
||||||
|
struct TALER_Amount *open_cost,
|
||||||
|
const struct GNUNET_TIME_Timestamp *final_expiration);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Insert reserve close operation into database.
|
* Insert reserve close operation into database.
|
||||||
*
|
*
|
||||||
|
@ -393,6 +393,12 @@ TALER_EXCHANGE_reserves_open (
|
|||||||
GNUNET_free (roh);
|
GNUNET_free (roh);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
TALER_wallet_reserve_open_sign (reserve_contribution,
|
||||||
|
roh->ts,
|
||||||
|
expiration_time,
|
||||||
|
min_purses,
|
||||||
|
reserve_priv,
|
||||||
|
&roh->reserve_sig);
|
||||||
cpa = json_array ();
|
cpa = json_array ();
|
||||||
GNUNET_assert (NULL != cpa);
|
GNUNET_assert (NULL != cpa);
|
||||||
for (unsigned int i = 0; i<coin_payments_length; i++)
|
for (unsigned int i = 0; i<coin_payments_length; i++)
|
||||||
@ -412,8 +418,7 @@ TALER_EXCHANGE_reserves_open (
|
|||||||
achp = &ahac;
|
achp = &ahac;
|
||||||
}
|
}
|
||||||
TALER_wallet_reserve_open_deposit_sign (&pd->amount,
|
TALER_wallet_reserve_open_deposit_sign (&pd->amount,
|
||||||
&roh->reserve_pub,
|
&roh->reserve_sig,
|
||||||
roh->ts,
|
|
||||||
&pd->coin_priv,
|
&pd->coin_priv,
|
||||||
&coin_sig);
|
&coin_sig);
|
||||||
GNUNET_CRYPTO_eddsa_key_get_public (&pd->coin_priv.eddsa_priv,
|
GNUNET_CRYPTO_eddsa_key_get_public (&pd->coin_priv.eddsa_priv,
|
||||||
@ -437,12 +442,6 @@ TALER_EXCHANGE_reserves_open (
|
|||||||
json_array_append_new (cpa,
|
json_array_append_new (cpa,
|
||||||
cp));
|
cp));
|
||||||
}
|
}
|
||||||
TALER_wallet_reserve_open_sign (reserve_contribution,
|
|
||||||
roh->ts,
|
|
||||||
expiration_time,
|
|
||||||
min_purses,
|
|
||||||
reserve_priv,
|
|
||||||
&roh->reserve_sig);
|
|
||||||
{
|
{
|
||||||
json_t *open_obj = GNUNET_JSON_PACK (
|
json_t *open_obj = GNUNET_JSON_PACK (
|
||||||
GNUNET_JSON_pack_timestamp ("request_timestamp",
|
GNUNET_JSON_pack_timestamp ("request_timestamp",
|
||||||
|
@ -1342,14 +1342,9 @@ struct TALER_ReserveOpenDepositPS
|
|||||||
struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
|
struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When was the request created.
|
* Which reserve's opening signature should be paid for?
|
||||||
*/
|
*/
|
||||||
struct GNUNET_TIME_TimestampNBO request_timestamp;
|
struct TALER_ReserveSignatureP reserve_sig;
|
||||||
|
|
||||||
/**
|
|
||||||
* Which reserve's opening should be paid for?
|
|
||||||
*/
|
|
||||||
struct TALER_ReservePublicKeyP reserve_pub;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specifies how much of the coin's value should be spent on opening this
|
* Specifies how much of the coin's value should be spent on opening this
|
||||||
@ -1364,16 +1359,14 @@ GNUNET_NETWORK_STRUCT_END
|
|||||||
void
|
void
|
||||||
TALER_wallet_reserve_open_deposit_sign (
|
TALER_wallet_reserve_open_deposit_sign (
|
||||||
const struct TALER_Amount *coin_contribution,
|
const struct TALER_Amount *coin_contribution,
|
||||||
const struct TALER_ReservePublicKeyP *reserve_pub,
|
const struct TALER_ReserveSignatureP *reserve_sig,
|
||||||
struct GNUNET_TIME_Timestamp request_timestamp,
|
|
||||||
const struct TALER_CoinSpendPrivateKeyP *coin_priv,
|
const struct TALER_CoinSpendPrivateKeyP *coin_priv,
|
||||||
struct TALER_CoinSpendSignatureP *coin_sig)
|
struct TALER_CoinSpendSignatureP *coin_sig)
|
||||||
{
|
{
|
||||||
struct TALER_ReserveOpenDepositPS rod = {
|
struct TALER_ReserveOpenDepositPS rod = {
|
||||||
.purpose.size = htonl (sizeof (rod)),
|
.purpose.size = htonl (sizeof (rod)),
|
||||||
.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_OPEN_DEPOSIT),
|
.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_OPEN_DEPOSIT),
|
||||||
.request_timestamp = GNUNET_TIME_timestamp_hton (request_timestamp),
|
.reserve_sig = *reserve_sig
|
||||||
.reserve_pub = *reserve_pub
|
|
||||||
};
|
};
|
||||||
|
|
||||||
TALER_amount_hton (&rod.coin_contribution,
|
TALER_amount_hton (&rod.coin_contribution,
|
||||||
@ -1388,16 +1381,14 @@ TALER_wallet_reserve_open_deposit_sign (
|
|||||||
enum GNUNET_GenericReturnValue
|
enum GNUNET_GenericReturnValue
|
||||||
TALER_wallet_reserve_open_deposit_verify (
|
TALER_wallet_reserve_open_deposit_verify (
|
||||||
const struct TALER_Amount *coin_contribution,
|
const struct TALER_Amount *coin_contribution,
|
||||||
const struct TALER_ReservePublicKeyP *reserve_pub,
|
const struct TALER_ReserveSignatureP *reserve_sig,
|
||||||
struct GNUNET_TIME_Timestamp request_timestamp,
|
|
||||||
const struct TALER_CoinSpendPublicKeyP *coin_pub,
|
const struct TALER_CoinSpendPublicKeyP *coin_pub,
|
||||||
const struct TALER_CoinSpendSignatureP *coin_sig)
|
const struct TALER_CoinSpendSignatureP *coin_sig)
|
||||||
{
|
{
|
||||||
struct TALER_ReserveOpenDepositPS rod = {
|
struct TALER_ReserveOpenDepositPS rod = {
|
||||||
.purpose.size = htonl (sizeof (rod)),
|
.purpose.size = htonl (sizeof (rod)),
|
||||||
.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_OPEN_DEPOSIT),
|
.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_OPEN_DEPOSIT),
|
||||||
.request_timestamp = GNUNET_TIME_timestamp_hton (request_timestamp),
|
.reserve_sig = *reserve_sig
|
||||||
.reserve_pub = *reserve_pub
|
|
||||||
};
|
};
|
||||||
|
|
||||||
TALER_amount_hton (&rod.coin_contribution,
|
TALER_amount_hton (&rod.coin_contribution,
|
||||||
|
Loading…
Reference in New Issue
Block a user