diff options
Diffstat (limited to 'src/exchange/taler-exchange-httpd_purses_create.c')
-rw-r--r-- | src/exchange/taler-exchange-httpd_purses_create.c | 160 |
1 files changed, 53 insertions, 107 deletions
diff --git a/src/exchange/taler-exchange-httpd_purses_create.c b/src/exchange/taler-exchange-httpd_purses_create.c index 9cabdb1a1..2de9468fe 100644 --- a/src/exchange/taler-exchange-httpd_purses_create.c +++ b/src/exchange/taler-exchange-httpd_purses_create.c @@ -39,15 +39,6 @@ */ struct PurseCreateContext { - /** - * Public key of the purse we are creating. - */ - const struct TALER_PurseContractPublicKeyP *purse_pub; - - /** - * Total amount to be put into the purse. - */ - struct TALER_Amount amount; /** * Total actually deposited by all the coins. @@ -55,11 +46,6 @@ struct PurseCreateContext struct TALER_Amount deposit_total; /** - * When should the purse expire. - */ - struct GNUNET_TIME_Timestamp purse_expiration; - - /** * Our current time. */ struct GNUNET_TIME_Timestamp exchange_timestamp; @@ -80,9 +66,9 @@ struct PurseCreateContext struct TALER_PurseContractSignatureP purse_sig; /** - * Hash of the contract terms of the purse. + * Fundamental details about the purse. */ - struct TALER_PrivateContractHashP h_contract_terms; + struct TEH_PurseDetails pd; /** * Array of coins being deposited. @@ -108,52 +94,6 @@ struct PurseCreateContext /** - * Send confirmation of purse creation success to client. - * - * @param connection connection to the client - * @param pcc details about the request that succeeded - * @return MHD result code - */ -static MHD_RESULT -reply_create_success (struct MHD_Connection *connection, - const struct PurseCreateContext *pcc) -{ - struct TALER_ExchangePublicKeyP pub; - struct TALER_ExchangeSignatureP sig; - enum TALER_ErrorCode ec; - - if (TALER_EC_NONE != - (ec = TALER_exchange_online_purse_created_sign ( - &TEH_keys_exchange_sign_, - pcc->exchange_timestamp, - pcc->purse_expiration, - &pcc->amount, - &pcc->deposit_total, - pcc->purse_pub, - &pcc->h_contract_terms, - &pub, - &sig))) - { - GNUNET_break (0); - return TALER_MHD_reply_with_ec (connection, - ec, - NULL); - } - return TALER_MHD_REPLY_JSON_PACK ( - connection, - MHD_HTTP_OK, - TALER_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", - &pub)); -} - - -/** * Execute database transaction for /purses/$PID/create. Runs the transaction * logic; IF it returns a non-error code, the transaction logic MUST NOT queue * a MHD response. IF it returns an hard error, the transaction logic MUST @@ -177,19 +117,19 @@ create_transaction (void *cls, bool in_conflict = true; GNUNET_assert (GNUNET_OK == - TALER_amount_set_zero (pcc->amount.currency, + TALER_amount_set_zero (TEH_currency, &purse_fee)); /* 1) create purse */ qs = TEH_plugin->insert_purse_request ( TEH_plugin->cls, - pcc->purse_pub, + &pcc->pd.purse_pub, &pcc->merge_pub, - pcc->purse_expiration, - &pcc->h_contract_terms, + pcc->pd.purse_expiration, + &pcc->pd.h_contract_terms, pcc->min_age, TALER_WAMF_MODE_MERGE_FULLY_PAID_PURSE, &purse_fee, - &pcc->amount, + &pcc->pd.target_amount, &pcc->purse_sig, &in_conflict); if (qs < 0) @@ -216,15 +156,15 @@ create_transaction (void *cls, uint32_t min_age; 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, - &min_age, - &target_amount, - &balance, - &purse_sig); + qs = TEH_plugin->get_purse_request (TEH_plugin->cls, + &pcc->pd.purse_pub, + &merge_pub, + &purse_expiration, + &h_contract_terms, + &min_age, + &target_amount, + &balance, + &purse_sig); if (qs < 0) { GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR != qs); @@ -261,6 +201,7 @@ create_transaction (void *cls, struct TEH_PurseDepositedCoin *coin = &pcc->coins[i]; bool balance_ok = false; bool conflict = true; + bool too_late = true; qs = TEH_make_coin_known (&coin->cpi, connection, @@ -269,12 +210,13 @@ create_transaction (void *cls, if (qs < 0) return qs; qs = TEH_plugin->do_purse_deposit (TEH_plugin->cls, - pcc->purse_pub, + &pcc->pd.purse_pub, &coin->cpi.coin_pub, &coin->amount, &coin->coin_sig, &coin->amount_minus_fee, &balance_ok, + &too_late, &conflict); if (qs <= 0) { @@ -291,6 +233,10 @@ create_transaction (void *cls, } if (! balance_ok) { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Coin %s has insufficient balance for purse deposit of amount %s\n", + TALER_B2S (&coin->cpi.coin_pub), + TALER_amount2s (&coin->amount)); *mhd_ret = TEH_RESPONSE_reply_coin_insufficient_funds ( connection, @@ -299,6 +245,15 @@ create_transaction (void *cls, &coin->cpi.coin_pub); return GNUNET_DB_STATUS_HARD_ERROR; } + if (too_late) + { + *mhd_ret + = TALER_MHD_reply_with_ec ( + connection, + TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE, + "too late to deposit on purse creation"); + return GNUNET_DB_STATUS_HARD_ERROR; + } if (conflict) { struct TALER_Amount amount; @@ -310,7 +265,7 @@ create_transaction (void *cls, TEH_plugin->rollback (TEH_plugin->cls); qs = TEH_plugin->get_purse_deposit (TEH_plugin->cls, - pcc->purse_pub, + &pcc->pd.purse_pub, &coin->cpi.coin_pub, &amount, &h_denom_pub, @@ -357,7 +312,7 @@ create_transaction (void *cls, { in_conflict = true; qs = TEH_plugin->insert_contract (TEH_plugin->cls, - pcc->purse_pub, + &pcc->pd.purse_pub, &pcc->econtract, &in_conflict); if (qs < 0) @@ -378,7 +333,7 @@ create_transaction (void *cls, qs = TEH_plugin->select_contract_by_purse ( TEH_plugin->cls, - pcc->purse_pub, + &pcc->pd.purse_pub, &econtract); if (qs <= 0) { @@ -444,7 +399,7 @@ parse_coin (struct MHD_Connection *connection, (iret = TEH_common_deposit_check_purse_deposit ( connection, coin, - pcc->purse_pub, + &pcc->pd.purse_pub, pcc->min_age))) return iret; if (0 > @@ -472,16 +427,16 @@ TEH_handler_purses_create ( const json_t *root) { struct PurseCreateContext pcc = { - .purse_pub = purse_pub, + .pd.purse_pub = *purse_pub, .exchange_timestamp = GNUNET_TIME_timestamp_get () }; - json_t *deposits; + const json_t *deposits; json_t *deposit; unsigned int idx; struct GNUNET_JSON_Specification spec[] = { TALER_JSON_spec_amount ("amount", TEH_currency, - &pcc.amount), + &pcc.pd.target_amount), GNUNET_JSON_spec_uint32 ("min_age", &pcc.min_age), GNUNET_JSON_spec_mark_optional ( @@ -493,11 +448,11 @@ TEH_handler_purses_create ( GNUNET_JSON_spec_fixed_auto ("purse_sig", &pcc.purse_sig), GNUNET_JSON_spec_fixed_auto ("h_contract_terms", - &pcc.h_contract_terms), - GNUNET_JSON_spec_json ("deposits", - &deposits), + &pcc.pd.h_contract_terms), + GNUNET_JSON_spec_array_const ("deposits", + &deposits), GNUNET_JSON_spec_timestamp ("purse_expiration", - &pcc.purse_expiration), + &pcc.pd.purse_expiration), GNUNET_JSON_spec_end () }; const struct TEH_GlobalFee *gf; @@ -522,21 +477,19 @@ TEH_handler_purses_create ( GNUNET_assert (GNUNET_OK == TALER_amount_set_zero (TEH_currency, &pcc.deposit_total)); - if (GNUNET_TIME_timestamp_cmp (pcc.purse_expiration, + if (GNUNET_TIME_timestamp_cmp (pcc.pd.purse_expiration, <, pcc.exchange_timestamp)) { GNUNET_break_op (0); - GNUNET_JSON_parse_free (spec); return TALER_MHD_reply_with_error (connection, MHD_HTTP_BAD_REQUEST, TALER_EC_EXCHANGE_PURSE_CREATE_EXPIRATION_BEFORE_NOW, NULL); } - if (GNUNET_TIME_absolute_is_never (pcc.purse_expiration.abs_time)) + if (GNUNET_TIME_absolute_is_never (pcc.pd.purse_expiration.abs_time)) { GNUNET_break_op (0); - GNUNET_JSON_parse_free (spec); return TALER_MHD_reply_with_error (connection, MHD_HTTP_BAD_REQUEST, TALER_EC_EXCHANGE_PURSE_CREATE_EXPIRATION_IS_NEVER, @@ -547,7 +500,6 @@ TEH_handler_purses_create ( (pcc.num_coins > TALER_MAX_FRESH_COINS) ) { 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, @@ -560,7 +512,6 @@ TEH_handler_purses_create ( if (NULL == keys) { GNUNET_break (0); - GNUNET_JSON_parse_free (spec); return TALER_MHD_reply_with_error (connection, MHD_HTTP_INTERNAL_SERVER_ERROR, TALER_EC_EXCHANGE_GENERIC_KEYS_MISSING, @@ -592,7 +543,6 @@ TEH_handler_purses_create ( deposit); if (GNUNET_OK != res) { - GNUNET_JSON_parse_free (spec); for (unsigned int i = 0; i<idx; i++) TEH_common_purse_deposit_free_coin (&pcc.coins[i]); GNUNET_free (pcc.coins); @@ -604,7 +554,6 @@ TEH_handler_purses_create ( &pcc.deposit_total)) { GNUNET_break_op (0); - GNUNET_JSON_parse_free (spec); GNUNET_free (pcc.coins); return TALER_MHD_reply_with_error (connection, MHD_HTTP_BAD_REQUEST, @@ -615,16 +564,15 @@ TEH_handler_purses_create ( if (GNUNET_OK != TALER_wallet_purse_create_verify ( - pcc.purse_expiration, - &pcc.h_contract_terms, + pcc.pd.purse_expiration, + &pcc.pd.h_contract_terms, &pcc.merge_pub, pcc.min_age, - &pcc.amount, - pcc.purse_pub, + &pcc.pd.target_amount, + &pcc.pd.purse_pub, &pcc.purse_sig)) { TALER_LOG_WARNING ("Invalid signature on /purses/$PID/create request\n"); - GNUNET_JSON_parse_free (spec); for (unsigned int i = 0; i<pcc.num_coins; i++) TEH_common_purse_deposit_free_coin (&pcc.coins[i]); GNUNET_free (pcc.coins); @@ -642,7 +590,6 @@ TEH_handler_purses_create ( &pcc.econtract.econtract_sig)) ) { TALER_LOG_WARNING ("Invalid signature on /purses/$PID/create request\n"); - GNUNET_JSON_parse_free (spec); for (unsigned int i = 0; i<pcc.num_coins; i++) TEH_common_purse_deposit_free_coin (&pcc.coins[i]); GNUNET_free (pcc.coins); @@ -657,7 +604,6 @@ TEH_handler_purses_create ( TEH_plugin->preflight (TEH_plugin->cls)) { GNUNET_break (0); - GNUNET_JSON_parse_free (spec); for (unsigned int i = 0; i<pcc.num_coins; i++) TEH_common_purse_deposit_free_coin (&pcc.coins[i]); GNUNET_free (pcc.coins); @@ -679,7 +625,6 @@ TEH_handler_purses_create ( &create_transaction, &pcc)) { - GNUNET_JSON_parse_free (spec); for (unsigned int i = 0; i<pcc.num_coins; i++) TEH_common_purse_deposit_free_coin (&pcc.coins[i]); GNUNET_free (pcc.coins); @@ -691,12 +636,13 @@ TEH_handler_purses_create ( { MHD_RESULT res; - res = reply_create_success (connection, - &pcc); + res = TEH_RESPONSE_reply_purse_created (connection, + pcc.exchange_timestamp, + &pcc.deposit_total, + &pcc.pd); for (unsigned int i = 0; i<pcc.num_coins; i++) TEH_common_purse_deposit_free_coin (&pcc.coins[i]); GNUNET_free (pcc.coins); - GNUNET_JSON_parse_free (spec); return res; } } |