extending interpreter to cover refund (but not used yet)
This commit is contained in:
parent
e39beff272
commit
93aaf1d172
@ -144,7 +144,12 @@ enum OpCode
|
|||||||
/**
|
/**
|
||||||
* Check that the fakebank has not received any other transactions.
|
* Check that the fakebank has not received any other transactions.
|
||||||
*/
|
*/
|
||||||
OC_CHECK_BANK_TRANSFERS_EMPTY
|
OC_CHECK_BANK_TRANSFERS_EMPTY,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Refund some deposit.
|
||||||
|
*/
|
||||||
|
OC_REFUND
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -601,6 +606,37 @@ struct Command
|
|||||||
|
|
||||||
} check_bank_transfer;
|
} check_bank_transfer;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Amount that should be refunded.
|
||||||
|
*/
|
||||||
|
const char *amount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expected refund fee.
|
||||||
|
*/
|
||||||
|
const char *fee;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reference to the corresponding deposit operation.
|
||||||
|
* Used to obtain contract details, merchant keys,
|
||||||
|
* fee structure, etc.
|
||||||
|
*/
|
||||||
|
const char *deposit_ref;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Refund transaction identifier.
|
||||||
|
*/
|
||||||
|
uint64_t rtransaction_id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle to the refund operation (while it is ongoing).
|
||||||
|
*/
|
||||||
|
struct TALER_EXCHANGE_RefundHandle *rh;
|
||||||
|
|
||||||
|
} refund;
|
||||||
|
|
||||||
} details;
|
} details;
|
||||||
|
|
||||||
};
|
};
|
||||||
@ -1533,6 +1569,82 @@ deposit_wtid_cb (void *cls,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check the result for the refund request.
|
||||||
|
*
|
||||||
|
* @param cls closure
|
||||||
|
* @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful deposit;
|
||||||
|
* 0 if the exchange's reply is bogus (fails to follow the protocol)
|
||||||
|
* @param obj the received JSON reply, should be kept as proof (and, in particular,
|
||||||
|
* be forwarded to the customer)
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
refund_cb (void *cls,
|
||||||
|
unsigned int http_status,
|
||||||
|
const json_t *obj)
|
||||||
|
{
|
||||||
|
struct InterpreterState *is = cls;
|
||||||
|
struct Command *cmd = &is->commands[is->ip];
|
||||||
|
|
||||||
|
cmd->details.refund.rh = NULL;
|
||||||
|
if (cmd->expected_response_code != http_status)
|
||||||
|
{
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||||
|
"Unexpected response code %u to command %s\n",
|
||||||
|
http_status,
|
||||||
|
cmd->label);
|
||||||
|
json_dumpf (obj, stderr, 0);
|
||||||
|
fail (is);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
switch (http_status)
|
||||||
|
{
|
||||||
|
case MHD_HTTP_OK:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
next_command (is);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given a command that is used to withdraw coins,
|
||||||
|
* extract the corresponding public key of the coin.
|
||||||
|
*
|
||||||
|
* @param coin command relating to coin withdrawal or refresh
|
||||||
|
* @param idx index to use if we got multiple coins from the @a coin command
|
||||||
|
* @param[out] coin_pub where to store the public key of the coin
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
get_public_key_from_coin_command (const struct Command *coin,
|
||||||
|
unsigned int idx,
|
||||||
|
struct TALER_CoinSpendPublicKeyP *coin_pub)
|
||||||
|
{
|
||||||
|
switch (coin->oc)
|
||||||
|
{
|
||||||
|
case OC_WITHDRAW_SIGN:
|
||||||
|
GNUNET_CRYPTO_eddsa_key_get_public (&coin->details.reserve_withdraw.coin_priv.eddsa_priv,
|
||||||
|
&coin_pub->eddsa_pub);
|
||||||
|
break;
|
||||||
|
case OC_REFRESH_REVEAL:
|
||||||
|
{
|
||||||
|
const struct FreshCoin *fc;
|
||||||
|
|
||||||
|
GNUNET_assert (idx < coin->details.refresh_reveal.num_fresh_coins);
|
||||||
|
fc = &coin->details.refresh_reveal.fresh_coins[idx];
|
||||||
|
|
||||||
|
GNUNET_CRYPTO_eddsa_key_get_public (&fc->coin_priv.eddsa_priv,
|
||||||
|
&coin_pub->eddsa_pub);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
GNUNET_assert (0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Run the main interpreter loop that performs exchange operations.
|
* Run the main interpreter loop that performs exchange operations.
|
||||||
*
|
*
|
||||||
@ -2038,29 +2150,9 @@ interpreter_run (void *cls)
|
|||||||
coin = find_command (is,
|
coin = find_command (is,
|
||||||
ref->details.deposit.coin_ref);
|
ref->details.deposit.coin_ref);
|
||||||
GNUNET_assert (NULL != coin);
|
GNUNET_assert (NULL != coin);
|
||||||
switch (coin->oc)
|
get_public_key_from_coin_command (coin,
|
||||||
{
|
ref->details.deposit.coin_idx,
|
||||||
case OC_WITHDRAW_SIGN:
|
&coin_pub);
|
||||||
GNUNET_CRYPTO_eddsa_key_get_public (&coin->details.reserve_withdraw.coin_priv.eddsa_priv,
|
|
||||||
&coin_pub.eddsa_pub);
|
|
||||||
break;
|
|
||||||
case OC_REFRESH_REVEAL:
|
|
||||||
{
|
|
||||||
const struct FreshCoin *fc;
|
|
||||||
unsigned int idx;
|
|
||||||
|
|
||||||
idx = ref->details.deposit.coin_idx;
|
|
||||||
GNUNET_assert (idx < coin->details.refresh_reveal.num_fresh_coins);
|
|
||||||
fc = &coin->details.refresh_reveal.fresh_coins[idx];
|
|
||||||
|
|
||||||
GNUNET_CRYPTO_eddsa_key_get_public (&fc->coin_priv.eddsa_priv,
|
|
||||||
&coin_pub.eddsa_pub);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
GNUNET_assert (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
wire = json_loads (ref->details.deposit.wire_details,
|
wire = json_loads (ref->details.deposit.wire_details,
|
||||||
JSON_REJECT_DUPLICATES,
|
JSON_REJECT_DUPLICATES,
|
||||||
NULL);
|
NULL);
|
||||||
@ -2150,6 +2242,72 @@ interpreter_run (void *cls)
|
|||||||
next_command (is);
|
next_command (is);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
case OC_REFUND:
|
||||||
|
{
|
||||||
|
const struct Command *coin;
|
||||||
|
struct GNUNET_HashCode h_contract;
|
||||||
|
json_t *contract;
|
||||||
|
struct TALER_CoinSpendPublicKeyP coin_pub;
|
||||||
|
struct TALER_Amount refund_fee;
|
||||||
|
|
||||||
|
if (GNUNET_OK !=
|
||||||
|
TALER_string_to_amount (cmd->details.refund.amount,
|
||||||
|
&amount))
|
||||||
|
{
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||||
|
"Failed to parse amount `%s' at %u\n",
|
||||||
|
cmd->details.refund.amount,
|
||||||
|
is->ip);
|
||||||
|
fail (is);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (GNUNET_OK !=
|
||||||
|
TALER_string_to_amount (cmd->details.refund.fee,
|
||||||
|
&refund_fee))
|
||||||
|
{
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||||
|
"Failed to parse amount `%s' at %u\n",
|
||||||
|
cmd->details.refund.fee,
|
||||||
|
is->ip);
|
||||||
|
fail (is);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ref = find_command (is,
|
||||||
|
cmd->details.refund.deposit_ref);
|
||||||
|
GNUNET_assert (NULL != ref);
|
||||||
|
contract = json_loads (cmd->details.deposit.contract,
|
||||||
|
JSON_REJECT_DUPLICATES,
|
||||||
|
NULL);
|
||||||
|
GNUNET_assert (NULL != contract);
|
||||||
|
TALER_JSON_hash (contract,
|
||||||
|
&h_contract);
|
||||||
|
json_decref (contract);
|
||||||
|
|
||||||
|
coin = find_command (is,
|
||||||
|
ref->details.deposit.coin_ref);
|
||||||
|
GNUNET_assert (NULL != coin);
|
||||||
|
get_public_key_from_coin_command (coin,
|
||||||
|
ref->details.deposit.coin_idx,
|
||||||
|
&coin_pub);
|
||||||
|
cmd->details.refund.rh
|
||||||
|
= TALER_EXCHANGE_refund (exchange,
|
||||||
|
&amount,
|
||||||
|
&refund_fee,
|
||||||
|
&h_contract,
|
||||||
|
ref->details.deposit.transaction_id,
|
||||||
|
&coin_pub,
|
||||||
|
cmd->details.refund.rtransaction_id,
|
||||||
|
&ref->details.deposit.merchant_priv,
|
||||||
|
&refund_cb,
|
||||||
|
is);
|
||||||
|
if (NULL == cmd->details.refund.rh)
|
||||||
|
{
|
||||||
|
GNUNET_break (0);
|
||||||
|
fail (is);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||||
"Unknown instruction %d at %u (%s)\n",
|
"Unknown instruction %d at %u (%s)\n",
|
||||||
@ -2364,6 +2522,17 @@ do_shutdown (void *cls)
|
|||||||
break;
|
break;
|
||||||
case OC_CHECK_BANK_TRANSFERS_EMPTY:
|
case OC_CHECK_BANK_TRANSFERS_EMPTY:
|
||||||
break;
|
break;
|
||||||
|
case OC_REFUND:
|
||||||
|
if (NULL != cmd->details.refund.rh)
|
||||||
|
{
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
|
||||||
|
"Command %u (%s) did not complete\n",
|
||||||
|
i,
|
||||||
|
cmd->label);
|
||||||
|
TALER_EXCHANGE_refund_cancel (cmd->details.refund.rh);
|
||||||
|
cmd->details.refund.rh = NULL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||||
"Unknown instruction %d at %u (%s)\n",
|
"Unknown instruction %d at %u (%s)\n",
|
||||||
|
@ -475,7 +475,7 @@ struct TALER_EXCHANGE_RefundHandle;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Callbacks of this type are used to serve the result of submitting a
|
* Callbacks of this type are used to serve the result of submitting a
|
||||||
* deposit permission request to a exchange.
|
* refund request to an exchange.
|
||||||
*
|
*
|
||||||
* @param cls closure
|
* @param cls closure
|
||||||
* @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful deposit;
|
* @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful deposit;
|
||||||
|
Loading…
Reference in New Issue
Block a user