summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2017-11-02 15:39:00 +0100
committerChristian Grothoff <christian@grothoff.org>2017-11-02 15:39:09 +0100
commit44bb2aa309236b4aa8fe2765a7eb030d7dfb4042 (patch)
tree5447916dd1c8b27903c7a360b16f672dfadf417a
parent4e61ed47b8464b65b1d64c68af4e4c927a552823 (diff)
downloadmerchant-44bb2aa309236b4aa8fe2765a7eb030d7dfb4042.tar.gz
merchant-44bb2aa309236b4aa8fe2765a7eb030d7dfb4042.tar.bz2
merchant-44bb2aa309236b4aa8fe2765a7eb030d7dfb4042.zip
misc bugfixes to get first /tip-pickup test to pass
-rw-r--r--src/backend/taler-merchant-httpd_tip-pickup.c67
-rw-r--r--src/lib/merchant_api_tip_pickup.c15
-rw-r--r--src/lib/test_merchant_api.c118
3 files changed, 138 insertions, 62 deletions
diff --git a/src/backend/taler-merchant-httpd_tip-pickup.c b/src/backend/taler-merchant-httpd_tip-pickup.c
index ce62e769..3cb73b43 100644
--- a/src/backend/taler-merchant-httpd_tip-pickup.c
+++ b/src/backend/taler-merchant-httpd_tip-pickup.c
@@ -94,6 +94,11 @@ struct PickupContext
struct PlanchetDetail *planchets;
/**
+ * The connection we are processing.
+ */
+ struct MHD_Connection *connection;
+
+ /**
* Tip ID that was supplied by the client.
*/
struct GNUNET_HashCode tip_id;
@@ -230,7 +235,9 @@ run_pickup (struct MHD_Connection *connection,
&pd->wr.purpose,
&reserve_sig.eddsa_signature));
json_array_append_new (sigs,
- GNUNET_JSON_from_data_auto (&reserve_sig));
+ json_pack ("{s:o}",
+ "reserve_sig",
+ GNUNET_JSON_from_data_auto (&reserve_sig)));
}
return TMH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_OK,
@@ -261,11 +268,14 @@ exchange_found_cb (void *cls,
struct TALER_Amount total;
int ae;
+ pc->fo = NULL;
+ MHD_resume_connection (pc->connection);
if (NULL == eh)
{
pc->ec = TALER_EC_TIP_PICKUP_EXCHANGE_DOWN;
pc->error_hint = "failed to contact exchange, check URL";
pc->response_code = MHD_HTTP_FAILED_DEPENDENCY;
+ TMH_trigger_daemon ();
return;
}
keys = TALER_EXCHANGE_get_keys (eh);
@@ -274,13 +284,17 @@ exchange_found_cb (void *cls,
pc->ec = TALER_EC_TIP_PICKUP_EXCHANGE_LACKED_KEYS;
pc->error_hint = "could not obtain denomination keys from exchange, check URL";
pc->response_code = MHD_HTTP_FAILED_DEPENDENCY;
+ TMH_trigger_daemon ();
return;
}
-
+ GNUNET_assert (0 != pc->planchets_len);
ae = GNUNET_NO;
memset (&total,
0,
sizeof (total));
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Calculating tip amount over %u planchets!\n",
+ pc->planchets_len);
hc = GNUNET_CRYPTO_hash_context_start ();
for (unsigned int i=0;i<pc->planchets_len;i++)
{
@@ -309,7 +323,9 @@ exchange_found_cb (void *cls,
TALER_amount_add (&amount_with_fee,
&dk->value,
&dk->fee_withdraw))
+ {
ae = GNUNET_YES;
+ }
if (0 == i)
{
total = amount_with_fee;
@@ -320,7 +336,9 @@ exchange_found_cb (void *cls,
TALER_amount_add (&total,
&total,
&amount_with_fee))
+ {
ae = GNUNET_YES;
+ }
}
TALER_amount_hton (&pd->wr.withdraw_fee,
&dk->fee_withdraw);
@@ -346,35 +364,44 @@ exchange_found_cb (void *cls,
* Prepare (and eventually execute) a pickup. Finds the exchange
* handle we need for #run_pickup().
*
- * @param connection MHD connection for sending the response
- * @param tip_id which tip are we picking up
* @param pc pickup context
* @return #MHD_YES upon success, #MHD_NO if
* the connection ought to be dropped
*/
static int
-prepare_pickup (struct MHD_Connection *connection,
- struct PickupContext *pc)
+prepare_pickup (struct PickupContext *pc)
{
- enum TALER_ErrorCode ec;
+ enum GNUNET_DB_QueryStatus qs;
- ec = db->lookup_exchange_by_tip (db->cls,
+ qs = db->lookup_exchange_by_tip (db->cls,
&pc->tip_id,
&pc->exchange_uri);
- if (TALER_EC_NONE != ec)
+ if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs)
{
unsigned int response_code;
+ enum TALER_ErrorCode ec;
- switch (ec)
+ switch (qs)
{
- case TALER_EC_TIP_PICKUP_TIP_ID_UNKNOWN:
+ case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
+ ec = TALER_EC_TIP_PICKUP_TIP_ID_UNKNOWN;
response_code = MHD_HTTP_NOT_FOUND;
break;
+ case GNUNET_DB_STATUS_SOFT_ERROR:
+ ec = TALER_EC_TIP_PICKUP_DB_ERROR_SOFT;
+ response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
+ break;
+ case GNUNET_DB_STATUS_HARD_ERROR:
+ ec = TALER_EC_TIP_PICKUP_DB_ERROR_HARD;
+ response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
+ break;
default:
+ GNUNET_break (0);
+ ec = TALER_EC_INTERNAL_LOGIC_ERROR;
response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
break;
}
- return TMH_RESPONSE_reply_rc (connection,
+ return TMH_RESPONSE_reply_rc (pc->connection,
response_code,
ec,
"Could not determine exchange URI for the given tip id");
@@ -386,11 +413,12 @@ prepare_pickup (struct MHD_Connection *connection,
pc);
if (NULL == pc->fo)
{
- return TMH_RESPONSE_reply_rc (connection,
+ return TMH_RESPONSE_reply_rc (pc->connection,
MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_INTERNAL_INVARIANT_FAILURE,
"consult server logs");
}
+ MHD_suspend_connection (pc->connection);
return MHD_YES;
}
@@ -466,6 +494,7 @@ MH_handler_tip_pickup (struct TMH_RequestHandler *rh,
{
pc = GNUNET_new (struct PickupContext);
pc->hc.cc = &pickup_cleanup;
+ pc->connection = connection;
*connection_cls = pc;
}
else
@@ -511,6 +540,15 @@ MH_handler_tip_pickup (struct TMH_RequestHandler *rh,
TALER_EC_TIP_PICKUP_EXCHANGE_TOO_MANY_PLANCHETS,
"limit of 1024 planchets exceeded by request");
}
+ if (0 == pc->planchets_len)
+ {
+ GNUNET_JSON_parse_free (spec);
+ json_decref (root);
+ return TMH_RESPONSE_reply_rc (connection,
+ MHD_HTTP_BAD_REQUEST,
+ TALER_EC_PARAMETER_MALFORMED,
+ "no planchets specified");
+ }
pc->planchets = GNUNET_new_array (pc->planchets_len,
struct PlanchetDetail);
for (unsigned int i=0;i<pc->planchets_len;i++)
@@ -527,8 +565,7 @@ MH_handler_tip_pickup (struct TMH_RequestHandler *rh,
}
}
pc->tip_id = tip_id;
- res = prepare_pickup (connection,
- pc);
+ res = prepare_pickup (pc);
GNUNET_JSON_parse_free (spec);
json_decref (root);
return res;
diff --git a/src/lib/merchant_api_tip_pickup.c b/src/lib/merchant_api_tip_pickup.c
index ec46c0f9..74bcbe18 100644
--- a/src/lib/merchant_api_tip_pickup.c
+++ b/src/lib/merchant_api_tip_pickup.c
@@ -224,6 +224,11 @@ TALER_MERCHANT_tip_pickup (struct GNUNET_CURL_Context *ctx,
json_t *pa;
json_t *tp_obj;
+ if (0 == num_planchets)
+ {
+ GNUNET_break (0);
+ return NULL;
+ }
pa = json_array ();
for (unsigned int i=0;i<num_planchets;i++)
{
@@ -243,8 +248,14 @@ TALER_MERCHANT_tip_pickup (struct GNUNET_CURL_Context *ctx,
json_decref (pa);
return NULL;
}
- json_array_append_new (pa,
- p);
+ if (0 !=
+ json_array_append_new (pa,
+ p))
+ {
+ GNUNET_break (0);
+ json_decref (pa);
+ return NULL;
+ }
}
tp_obj = json_pack ("{"
" s:o," /* tip_id */
diff --git a/src/lib/test_merchant_api.c b/src/lib/test_merchant_api.c
index 5ccc5658..caf66a5c 100644
--- a/src/lib/test_merchant_api.c
+++ b/src/lib/test_merchant_api.c
@@ -1866,7 +1866,11 @@ pickup_withdraw_cb (void *cls,
if ( (MHD_HTTP_OK != http_status) ||
(TALER_EC_NONE != ec) )
{
- GNUNET_break (0);
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Unexpected response code %u/%u to command %s\n",
+ http_status,
+ ec,
+ cmd->label);
fail (is);
return;
}
@@ -1911,7 +1915,11 @@ pickup_cb (void *cls,
cmd->details.tip_pickup.tpo = NULL;
if (http_status != cmd->expected_response_code)
{
- GNUNET_break (0);
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Unexpected response code %u/%u to command %s\n",
+ http_status,
+ ec,
+ cmd->label);
fail (is);
return;
}
@@ -2590,6 +2598,7 @@ interpreter_run (void *cls)
icoin->denom_pub = coin_ref->details.tip_pickup.dks[ci]->key;
icoin->denom_sig = coin_ref->details.tip_pickup.sigs[ci];
icoin->denom_value = coin_ref->details.tip_pickup.dks[ci]->value;
+ break;
default:
GNUNET_assert (0);
}
@@ -2904,55 +2913,62 @@ interpreter_run (void *cls)
}
case OC_TIP_PICKUP:
{
- unsigned int num_planchets = cmd->details.tip_pickup.num_coins;
- struct TALER_PlanchetDetail planchets[num_planchets];
-
- ref = find_command (is,
- cmd->details.tip_pickup.authorize_ref);
- GNUNET_assert (NULL != ref);
- GNUNET_assert (OC_TIP_AUTHORIZE == ref->oc);
- cmd->details.tip_pickup.psa = GNUNET_new_array (num_planchets,
- struct TALER_PlanchetSecretsP);
- cmd->details.tip_pickup.dks = GNUNET_new_array (num_planchets,
- const struct TALER_EXCHANGE_DenomPublicKey *);
- for (unsigned int i=0;i<num_planchets;i++)
+ unsigned int num_planchets;
+
+ for (num_planchets=0;
+ NULL != cmd->details.tip_pickup.amounts[num_planchets];
+ num_planchets++);
+ cmd->details.tip_pickup.num_coins = num_planchets;
{
- GNUNET_assert (GNUNET_OK ==
- TALER_string_to_amount (cmd->details.tip_pickup.amounts[i],
- &amount));
+ struct TALER_PlanchetDetail planchets[num_planchets];
- cmd->details.tip_pickup.dks[i]
- = find_pk (is->keys,
- &amount);
- if (NULL == cmd->details.tip_pickup.dks[i])
+ ref = find_command (is,
+ cmd->details.tip_pickup.authorize_ref);
+ GNUNET_assert (NULL != ref);
+ GNUNET_assert (OC_TIP_AUTHORIZE == ref->oc);
+ cmd->details.tip_pickup.psa = GNUNET_new_array (num_planchets,
+ struct TALER_PlanchetSecretsP);
+ cmd->details.tip_pickup.dks = GNUNET_new_array (num_planchets,
+ const struct TALER_EXCHANGE_DenomPublicKey *);
+ for (unsigned int i=0;i<num_planchets;i++)
{
- GNUNET_break (0);
- fail (is);
- return;
+ GNUNET_assert (GNUNET_OK ==
+ TALER_string_to_amount (cmd->details.tip_pickup.amounts[i],
+ &amount));
+
+ cmd->details.tip_pickup.dks[i]
+ = find_pk (is->keys,
+ &amount);
+ if (NULL == cmd->details.tip_pickup.dks[i])
+ {
+ GNUNET_break (0);
+ fail (is);
+ return;
+ }
+ if (GNUNET_OK !=
+ TALER_planchet_prepare (&cmd->details.tip_pickup.dks[i]->key,
+ &cmd->details.tip_pickup.psa[i],
+ &planchets[i]))
+ {
+ GNUNET_break (0);
+ fail (is);
+ return;
+ }
}
- if (GNUNET_OK !=
- TALER_planchet_prepare (&cmd->details.tip_pickup.dks[i]->key,
- &cmd->details.tip_pickup.psa[i],
- &planchets[i]))
+ if (NULL == (cmd->details.tip_pickup.tpo
+ = TALER_MERCHANT_tip_pickup
+ (ctx,
+ MERCHANT_URI,
+ &ref->details.tip_authorize.tip_id,
+ num_planchets,
+ planchets,
+ &pickup_cb,
+ is)))
{
GNUNET_break (0);
fail (is);
- return;
}
}
- if (NULL == (cmd->details.tip_pickup.tpo
- = TALER_MERCHANT_tip_pickup
- (ctx,
- MERCHANT_URI,
- &ref->details.tip_authorize.tip_id,
- num_planchets,
- planchets,
- &pickup_cb,
- is)))
- {
- GNUNET_break (0);
- fail (is);
- }
break;
}
default:
@@ -3097,6 +3113,10 @@ static void
run (void *cls)
{
struct InterpreterState *is;
+ static const char *pickup_amounts_1[] = {
+ "EUR:5",
+ NULL
+ };
static struct Command commands[] =
{
/* Test tipping */
@@ -3115,11 +3135,13 @@ run (void *cls)
.expected_response_code = MHD_HTTP_OK,
.details.tip_enable.admin_add_incoming_ref = "create-reserve-tip-1",
.details.tip_enable.amount = "EUR:5.01" },
+ /* Test incrementing active reserve balance */
{ .oc = OC_TIP_ENABLE,
.label = "enable-tip-2",
.expected_response_code = MHD_HTTP_OK,
.details.tip_enable.admin_add_incoming_ref = "create-reserve-tip-1",
.details.tip_enable.amount = "EUR:5.01" },
+ /* Authorize two tips */
{ .oc = OC_TIP_AUTHORIZE,
.label = "authorize-tip-1",
.expected_response_code = MHD_HTTP_OK,
@@ -3132,6 +3154,7 @@ run (void *cls)
.details.tip_authorize.instance = "tip",
.details.tip_authorize.justification = "tip 2",
.details.tip_authorize.amount = "EUR:5.01" },
+ /* Test authorization failure modes */
{ .oc = OC_TIP_AUTHORIZE,
.label = "authorize-tip-3-insufficient-funds",
.expected_response_code = MHD_HTTP_PRECONDITION_FAILED,
@@ -3160,9 +3183,14 @@ run (void *cls)
.details.tip_authorize.justification = "tip 6",
.details.tip_authorize.amount = "EUR:5.01",
.details.tip_authorize.expected_ec = TALER_EC_TIP_AUTHORIZE_RESERVE_NOT_ENABLED },
-
-
-
+ /* Withdraw tip */
+ { .oc = OC_TIP_PICKUP,
+ .label = "pickup-tip-1",
+ .expected_response_code = MHD_HTTP_OK,
+ .details.tip_pickup.authorize_ref = "authorize-tip-1",
+ .details.tip_pickup.amounts = pickup_amounts_1 },
+
+
/* Fill reserve with EUR:5.01, as withdraw fee is 1 ct per
config */
{ .oc = OC_ADMIN_ADD_INCOMING,