WIP: policy handling advancements
- introduction of policy states. - introduction of default state on timeout. - introduction of TALER_PolicyFulfilmentOutcome - parsing for policy_details now also provides default state on timeout. - introduction of check_serial as preflight func before heavy operations in policy post handler - brandt auction now returns outcomes.
This commit is contained in:
parent
18d8dcd1f9
commit
956e3c3065
@ -1070,18 +1070,32 @@ handle_get_extensions (struct TEH_RequestContext *rc,
|
|||||||
"/extensions/$EXTENSION unknown");
|
"/extensions/$EXTENSION unknown");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NULL == ext->http_get_handler)
|
if (NULL == ext->policy_get_handler)
|
||||||
return TALER_MHD_reply_with_error (rc->connection,
|
return TALER_MHD_reply_with_error (rc->connection,
|
||||||
MHD_HTTP_NOT_IMPLEMENTED,
|
MHD_HTTP_NOT_IMPLEMENTED,
|
||||||
TALER_EC_EXCHANGE_GENERIC_OPERATION_UNKNOWN,
|
TALER_EC_EXCHANGE_GENERIC_OPERATION_UNKNOWN,
|
||||||
"GET /extensions/$EXTENSION not supported");
|
"GET /extensions/$EXTENSION not supported");
|
||||||
|
|
||||||
return ext->http_get_handler (
|
return ext->policy_get_handler (
|
||||||
rc->connection,
|
rc->connection,
|
||||||
&args[1]);
|
&args[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* @brief function pointer for TALER_extension.check */
|
||||||
|
static enum GNUNET_GenericReturnValue
|
||||||
|
check_serial_ids (
|
||||||
|
struct GNUNET_HashCode serial_ids[],
|
||||||
|
size_t size)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < size; i++)
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||||
|
"Got to check serial_id: %s\n",
|
||||||
|
GNUNET_h2s (&serial_ids[i]));
|
||||||
|
return GNUNET_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle POST "/extensions/..." requests.
|
* Handle POST "/extensions/..." requests.
|
||||||
*
|
*
|
||||||
@ -1096,6 +1110,7 @@ handle_post_extensions (struct TEH_RequestContext *rc,
|
|||||||
const char *const args[])
|
const char *const args[])
|
||||||
{
|
{
|
||||||
const struct TALER_Extension *ext = NULL;
|
const struct TALER_Extension *ext = NULL;
|
||||||
|
json_t *output;
|
||||||
|
|
||||||
if (NULL == args[0])
|
if (NULL == args[0])
|
||||||
{
|
{
|
||||||
@ -1112,16 +1127,49 @@ handle_post_extensions (struct TEH_RequestContext *rc,
|
|||||||
"/extensions/$EXTENSION unknown");
|
"/extensions/$EXTENSION unknown");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NULL == ext->http_post_handler)
|
if (NULL == ext->policy_post_handler)
|
||||||
return TALER_MHD_reply_with_error (rc->connection,
|
return TALER_MHD_reply_with_error (rc->connection,
|
||||||
MHD_HTTP_NOT_IMPLEMENTED,
|
MHD_HTTP_NOT_IMPLEMENTED,
|
||||||
TALER_EC_EXCHANGE_GENERIC_OPERATION_UNKNOWN,
|
TALER_EC_EXCHANGE_GENERIC_OPERATION_UNKNOWN,
|
||||||
"POST /extensions/$EXTENSION not supported");
|
"POST /extensions/$EXTENSION not supported");
|
||||||
|
|
||||||
return ext->http_post_handler (
|
{
|
||||||
rc->connection,
|
enum GNUNET_GenericReturnValue ret;
|
||||||
root,
|
struct TALER_PolicyFulfilmentOutcome *outcome;
|
||||||
&args[1]);
|
|
||||||
|
ret = ext->policy_post_handler (root,
|
||||||
|
&args[1],
|
||||||
|
&check_serial_ids,
|
||||||
|
&outcome,
|
||||||
|
&output);
|
||||||
|
|
||||||
|
if (GNUNET_OK != ret)
|
||||||
|
{
|
||||||
|
TALER_policy_fulfilment_outcome_free (outcome);
|
||||||
|
TALER_MHD_reply_json_steal (
|
||||||
|
rc->connection,
|
||||||
|
output,
|
||||||
|
MHD_HTTP_BAD_REQUEST);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: deal with outcome */
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < outcome->len; i++)
|
||||||
|
{
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||||
|
"Got outcome for serial_id: %s, state: %s, amount: %s\n",
|
||||||
|
GNUNET_h2s (&outcome->positions[i].serial_id),
|
||||||
|
TALER_policy_fulfilment_state_str (
|
||||||
|
outcome->positions[i].state),
|
||||||
|
TALER_amount_to_string (&outcome->positions[i].new_amount));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return TALER_MHD_reply_json_steal (rc->connection,
|
||||||
|
output,
|
||||||
|
MHD_HTTP_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -337,15 +337,22 @@ TEH_handler_deposit (struct MHD_Connection *connection,
|
|||||||
if (deposit.has_policy_details)
|
if (deposit.has_policy_details)
|
||||||
{
|
{
|
||||||
const char *error_hint = NULL;
|
const char *error_hint = NULL;
|
||||||
|
enum TALER_PolicyFulfilmentState state_on_timeout;
|
||||||
|
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
TALER_extensions_serial_from_policy_details (deposit.policy_details,
|
TALER_extensions_extract_meta_data_from_policy_details (
|
||||||
&deposit.policy_serial_id,
|
deposit.policy_details,
|
||||||
&deposit.policy_deadline,
|
&deposit.policy_serial_id,
|
||||||
&error_hint))
|
&deposit.policy_deadline,
|
||||||
|
&state_on_timeout,
|
||||||
|
&error_hint))
|
||||||
return TALER_MHD_reply_with_error (connection,
|
return TALER_MHD_reply_with_error (connection,
|
||||||
MHD_HTTP_BAD_REQUEST,
|
MHD_HTTP_BAD_REQUEST,
|
||||||
TALER_EC_EXCHANGE_DEPOSITS_POLICY_NOT_ACCEPTED,
|
TALER_EC_EXCHANGE_DEPOSITS_POLICY_NOT_ACCEPTED,
|
||||||
error_hint);
|
error_hint);
|
||||||
|
|
||||||
|
GNUNET_assert (TALER_PolicyFulfilmentStateMax >= state_on_timeout);
|
||||||
|
deposit.policy_state_on_timeout = state_on_timeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* new deposit */
|
/* new deposit */
|
||||||
|
@ -561,7 +561,8 @@ CREATE TABLE IF NOT EXISTS policy_details
|
|||||||
,serial_id BYTEA PRIMARY KEY CHECK(LENGTH(serial_id)=64)
|
,serial_id BYTEA PRIMARY KEY CHECK(LENGTH(serial_id)=64)
|
||||||
,policy_options VARCHAR
|
,policy_options VARCHAR
|
||||||
,deadline INT8 NOT NULL
|
,deadline INT8 NOT NULL
|
||||||
,fulfilment_state INT4 NOT NULL CHECK(fulfilment_state between 0 and 3))
|
,timeout_fulfilment_state smallint NOT NULL CHECK(timeout_fulfilment_state in (5, 6))
|
||||||
|
,fulfilment_state smallint NOT NULL CHECK(fulfilment_state between 0 and 6))
|
||||||
PARTITION BY HASH (serial_id);
|
PARTITION BY HASH (serial_id);
|
||||||
COMMENT ON TABLE policy_details
|
COMMENT ON TABLE policy_details
|
||||||
IS 'Policies that were provided with deposits via policy extensions.';
|
IS 'Policies that were provided with deposits via policy extensions.';
|
||||||
@ -571,8 +572,17 @@ COMMENT ON COLUMN policy_details.policy_options
|
|||||||
IS 'JSON object with options set that the exchange needs to consider when executing a deposit. Supported details depend on the policy extensions supported by the exchange.';
|
IS 'JSON object with options set that the exchange needs to consider when executing a deposit. Supported details depend on the policy extensions supported by the exchange.';
|
||||||
COMMENT ON COLUMN policy_details.deadline
|
COMMENT ON COLUMN policy_details.deadline
|
||||||
IS 'Deadline until the policy must be marked as fulfilled or unfulfilled (maybe "forever")';
|
IS 'Deadline until the policy must be marked as fulfilled or unfulfilled (maybe "forever")';
|
||||||
|
COMMENT ON COLUMN policy_details.timeout_fulfilment_state
|
||||||
|
IS 'State that a pending policy should be put into, once the deadline is reached. Allowed values are 5 (TIMEOUT, transfer coins) or 6 (TIMEOUT, coins refreshable)';
|
||||||
COMMENT ON COLUMN policy_details.fulfilment_state
|
COMMENT ON COLUMN policy_details.fulfilment_state
|
||||||
IS 'State of the fulfilment: 0 (PENDING), 1 (FULFILLED), 2 (NOT FULFILLED), 3 (TIMED OUT)';
|
IS 'State of the fulfilment:
|
||||||
|
- 0 (PENDING)
|
||||||
|
- 1 (SUCCESS, transfer coins)
|
||||||
|
- 2 (SUCCESS, coins refreshable)
|
||||||
|
- 3 (FAILURE, transfer coins)
|
||||||
|
- 4 (FAILURE, coins refreshable)
|
||||||
|
- 5 (TIMEOUT, tranfer coins)
|
||||||
|
- 6 (TIMEOUT, coins refrehsable)';
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS policy_details_default
|
CREATE TABLE IF NOT EXISTS policy_details_default
|
||||||
PARTITION OF policy_details
|
PARTITION OF policy_details
|
||||||
|
@ -929,11 +929,16 @@ irbt_cb_table_policy_details (struct PostgresClosure *pg,
|
|||||||
{
|
{
|
||||||
struct GNUNET_PQ_QueryParam params[] = {
|
struct GNUNET_PQ_QueryParam params[] = {
|
||||||
GNUNET_PQ_query_param_uint64 (&td->serial),
|
GNUNET_PQ_query_param_uint64 (&td->serial),
|
||||||
NULL ==
|
NULL == td->details.policy_details.policy_options ?
|
||||||
td->details.policy_details.policy_options ?
|
|
||||||
GNUNET_PQ_query_param_null () :
|
GNUNET_PQ_query_param_null () :
|
||||||
GNUNET_PQ_query_param_string (
|
GNUNET_PQ_query_param_string (
|
||||||
td->details.policy_details.policy_options),
|
td->details.policy_details.policy_options),
|
||||||
|
GNUNET_PQ_query_param_timestamp (
|
||||||
|
&td->details.policy_details.deadline),
|
||||||
|
GNUNET_PQ_query_param_uint16 (
|
||||||
|
&td->details.policy_details.timeout_fulfilment_state),
|
||||||
|
GNUNET_PQ_query_param_uint16 (
|
||||||
|
&td->details.policy_details.fulfilment_state),
|
||||||
GNUNET_PQ_query_param_end
|
GNUNET_PQ_query_param_end
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1456,7 +1456,10 @@ lrbt_cb_table_policy_details (void *cls,
|
|||||||
GNUNET_PQ_result_spec_timestamp ("deadline",
|
GNUNET_PQ_result_spec_timestamp ("deadline",
|
||||||
&td.details.policy_details.
|
&td.details.policy_details.
|
||||||
deadline),
|
deadline),
|
||||||
GNUNET_PQ_result_spec_uint64 ("fulfilment_state",
|
GNUNET_PQ_result_spec_uint16 ("timeout_fulfilment_state",
|
||||||
|
&td.details.policy_details.
|
||||||
|
timeout_fulfilment_state),
|
||||||
|
GNUNET_PQ_result_spec_uint16 ("fulfilment_state",
|
||||||
&td.details.policy_details.
|
&td.details.policy_details.
|
||||||
fulfilment_state),
|
fulfilment_state),
|
||||||
GNUNET_PQ_result_spec_end
|
GNUNET_PQ_result_spec_end
|
||||||
@ -1502,16 +1505,16 @@ lrbt_cb_table_policy_fulfilments (void *cls,
|
|||||||
struct GNUNET_PQ_ResultSpec rs[] = {
|
struct GNUNET_PQ_ResultSpec rs[] = {
|
||||||
GNUNET_PQ_result_spec_uint64 ("fulfilment_id",
|
GNUNET_PQ_result_spec_uint64 ("fulfilment_id",
|
||||||
&td.serial),
|
&td.serial),
|
||||||
GNUNET_PQ_result_spec_allow_null (
|
|
||||||
GNUNET_PQ_result_spec_string ("fulfilment_proof",
|
|
||||||
&td.details.policy_fulfilments.
|
|
||||||
fulfilment_proof),
|
|
||||||
&no_config),
|
|
||||||
GNUNET_PQ_result_spec_allow_null (
|
GNUNET_PQ_result_spec_allow_null (
|
||||||
GNUNET_PQ_result_spec_timestamp ("fulfilment_timestamp",
|
GNUNET_PQ_result_spec_timestamp ("fulfilment_timestamp",
|
||||||
&td.details.policy_fulfilments.
|
&td.details.policy_fulfilments.
|
||||||
fulfilment_timestamp),
|
fulfilment_timestamp),
|
||||||
&no_timestamp),
|
&no_timestamp),
|
||||||
|
GNUNET_PQ_result_spec_allow_null (
|
||||||
|
GNUNET_PQ_result_spec_string ("fulfilment_proof",
|
||||||
|
&td.details.policy_fulfilments.
|
||||||
|
fulfilment_proof),
|
||||||
|
&no_config),
|
||||||
GNUNET_PQ_result_spec_end
|
GNUNET_PQ_result_spec_end
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -822,8 +822,8 @@ prepare_statements (struct PostgresClosure *pg)
|
|||||||
",out_balance_ok AS balance_ok"
|
",out_balance_ok AS balance_ok"
|
||||||
",out_conflict AS conflicted"
|
",out_conflict AS conflicted"
|
||||||
" FROM exchange_do_deposit"
|
" FROM exchange_do_deposit"
|
||||||
" ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19);",
|
" ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20);",
|
||||||
19),
|
20),
|
||||||
/* used in postgres_do_purse_deposit() */
|
/* used in postgres_do_purse_deposit() */
|
||||||
GNUNET_PQ_make_prepare (
|
GNUNET_PQ_make_prepare (
|
||||||
"call_purse_deposit",
|
"call_purse_deposit",
|
||||||
@ -3933,10 +3933,11 @@ prepare_statements (struct PostgresClosure *pg)
|
|||||||
",serial_id"
|
",serial_id"
|
||||||
",policy_options"
|
",policy_options"
|
||||||
",deadline"
|
",deadline"
|
||||||
|
",timeout_fulfilment_state"
|
||||||
",fulfilment_state"
|
",fulfilment_state"
|
||||||
") VALUES "
|
") VALUES "
|
||||||
"($1, $2, $3, $4, $5);",
|
"($1, $2, $3, $4, $5, $6);",
|
||||||
5),
|
6),
|
||||||
GNUNET_PQ_make_prepare (
|
GNUNET_PQ_make_prepare (
|
||||||
"insert_into_table_policy_fulfilments",
|
"insert_into_table_policy_fulfilments",
|
||||||
"INSERT INTO policy_fulfilments"
|
"INSERT INTO policy_fulfilments"
|
||||||
@ -6292,6 +6293,9 @@ postgres_do_deposit (
|
|||||||
(deposit->has_policy_details)
|
(deposit->has_policy_details)
|
||||||
? GNUNET_PQ_query_param_timestamp (&deposit->policy_deadline)
|
? GNUNET_PQ_query_param_timestamp (&deposit->policy_deadline)
|
||||||
: GNUNET_PQ_query_param_null (),
|
: GNUNET_PQ_query_param_null (),
|
||||||
|
(deposit->has_policy_details)
|
||||||
|
? GNUNET_PQ_query_param_uint16 (&deposit->policy_state_on_timeout)
|
||||||
|
: GNUNET_PQ_query_param_null (),
|
||||||
GNUNET_PQ_query_param_end
|
GNUNET_PQ_query_param_end
|
||||||
};
|
};
|
||||||
struct GNUNET_PQ_ResultSpec rs[] = {
|
struct GNUNET_PQ_ResultSpec rs[] = {
|
||||||
@ -14651,6 +14655,7 @@ postgres_insert_records_by_table (void *cls,
|
|||||||
case TALER_EXCHANGEDB_RT_POLICY_DETAILS:
|
case TALER_EXCHANGEDB_RT_POLICY_DETAILS:
|
||||||
rh = &irbt_cb_table_policy_details;
|
rh = &irbt_cb_table_policy_details;
|
||||||
break;
|
break;
|
||||||
|
/* TODO: policy_details_fulfilments and policy_fulfilments */
|
||||||
case TALER_EXCHANGEDB_RT_PURSE_REQUESTS:
|
case TALER_EXCHANGEDB_RT_PURSE_REQUESTS:
|
||||||
rh = &irbt_cb_table_purse_requests;
|
rh = &irbt_cb_table_purse_requests;
|
||||||
break;
|
break;
|
||||||
|
@ -513,7 +513,8 @@ CREATE OR REPLACE FUNCTION exchange_do_deposit(
|
|||||||
IN in_policy_blocked BOOLEAN,
|
IN in_policy_blocked BOOLEAN,
|
||||||
IN in_policy_details VARCHAR,
|
IN in_policy_details VARCHAR,
|
||||||
IN in_policy_serial_id BYTEA,
|
IN in_policy_serial_id BYTEA,
|
||||||
IN in_policy_deadline INT8,
|
IN in_policy_deadline SMALLINT,
|
||||||
|
IN in_policy_timeout_fulfilment_state SMALLINT,
|
||||||
OUT out_exchange_timestamp INT8,
|
OUT out_exchange_timestamp INT8,
|
||||||
OUT out_balance_ok BOOLEAN,
|
OUT out_balance_ok BOOLEAN,
|
||||||
OUT out_conflict BOOLEAN)
|
OUT out_conflict BOOLEAN)
|
||||||
@ -535,11 +536,13 @@ THEN
|
|||||||
(serial_id
|
(serial_id
|
||||||
,policy_options
|
,policy_options
|
||||||
,deadline
|
,deadline
|
||||||
|
,timeout_fulfilment_state
|
||||||
,fulfilment_state)
|
,fulfilment_state)
|
||||||
VALUES
|
VALUES
|
||||||
(in_policy_serial_id
|
(in_policy_serial_id
|
||||||
,in_policy_details
|
,in_policy_details
|
||||||
,in_policy_deadline
|
,in_policy_deadline
|
||||||
|
,in_policy_timeout_fulfilment_state
|
||||||
,0) -- 0 == pending
|
,0) -- 0 == pending
|
||||||
RETURNING policy_details_serial_id INTO xdi;
|
RETURNING policy_details_serial_id INTO xdi;
|
||||||
ELSE
|
ELSE
|
||||||
|
@ -154,8 +154,8 @@ struct TALER_Extension TE_age_restriction = {
|
|||||||
|
|
||||||
/* This extension is not a policy extension */
|
/* This extension is not a policy extension */
|
||||||
.parse_policy_details = NULL,
|
.parse_policy_details = NULL,
|
||||||
.http_get_handler = NULL,
|
.policy_get_handler = NULL,
|
||||||
.http_post_handler = NULL,
|
.policy_post_handler = NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -353,13 +353,38 @@ TALER_extensions_load_manifests (
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Policy related
|
||||||
|
*/
|
||||||
|
|
||||||
|
static char *fulfilment2str[] = {
|
||||||
|
[TALER_PolicyFulfilmentPending] = "Pending",
|
||||||
|
[TALER_PolicyFulfilmentSuccessTransfer] = "SuccessTransfer",
|
||||||
|
[TALER_PolicyFulfilmentSuccessRefreshable] = "SuccessRefreshable",
|
||||||
|
[TALER_PolicyFulfilmentFailureTransfer] = "FailureTransfer",
|
||||||
|
[TALER_PolicyFulfilmentFailureRefreshable] = "FailureRefreshable",
|
||||||
|
[TALER_PolicyFulfilmentTimeoutTransfer] = "TimeoutTransfer",
|
||||||
|
[TALER_PolicyFulfilmentTimeoutRefreshable] = "TimeoutRefreshable",
|
||||||
|
};
|
||||||
|
|
||||||
|
const char *
|
||||||
|
TALER_policy_fulfilment_state_str (
|
||||||
|
enum TALER_PolicyFulfilmentState state)
|
||||||
|
{
|
||||||
|
GNUNET_assert (TALER_PolicyFulfilmentStateMax >= state);
|
||||||
|
return fulfilment2str[state];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
enum GNUNET_GenericReturnValue
|
enum GNUNET_GenericReturnValue
|
||||||
TALER_extensions_serial_from_policy_details (
|
TALER_extensions_extract_meta_data_from_policy_details (
|
||||||
const json_t *policy_details,
|
const json_t *policy_details,
|
||||||
struct GNUNET_HashCode *serial,
|
struct GNUNET_HashCode *serial,
|
||||||
struct GNUNET_TIME_Timestamp *deadline,
|
struct GNUNET_TIME_Timestamp *deadline,
|
||||||
|
enum TALER_PolicyFulfilmentState *state_on_deadline,
|
||||||
const char **error_hint)
|
const char **error_hint)
|
||||||
{
|
{
|
||||||
|
enum GNUNET_GenericReturnValue ret;
|
||||||
const struct TALER_Extension *extension;
|
const struct TALER_Extension *extension;
|
||||||
const json_t *jtype;
|
const json_t *jtype;
|
||||||
const char *type;
|
const char *type;
|
||||||
@ -399,12 +424,49 @@ TALER_extensions_serial_from_policy_details (
|
|||||||
}
|
}
|
||||||
|
|
||||||
*deadline = GNUNET_TIME_UNIT_FOREVER_TS;
|
*deadline = GNUNET_TIME_UNIT_FOREVER_TS;
|
||||||
return extension->parse_policy_details (policy_details,
|
ret = extension->parse_policy_details (policy_details,
|
||||||
serial,
|
serial,
|
||||||
deadline,
|
deadline,
|
||||||
error_hint);
|
state_on_deadline,
|
||||||
|
error_hint);
|
||||||
|
|
||||||
|
GNUNET_assert ((TALER_PolicyFulfilmentTimeoutRefreshable ==
|
||||||
|
*state_on_deadline) ||
|
||||||
|
(TALER_PolicyFulfilmentTimeoutTransfer ==
|
||||||
|
*state_on_deadline));
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct TALER_PolicyFulfilmentOutcome *
|
||||||
|
TALER_policy_fulfilment_outcome_new (size_t len)
|
||||||
|
{
|
||||||
|
struct TALER_PolicyFulfilmentOutcome *out;
|
||||||
|
|
||||||
|
out = GNUNET_new (struct TALER_PolicyFulfilmentOutcome);
|
||||||
|
out->len = len;
|
||||||
|
out->positions = GNUNET_new_array (len,
|
||||||
|
struct
|
||||||
|
TALER_PolicyFulfilmentOutcomePosition);
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TALER_policy_fulfilment_outcome_free (
|
||||||
|
struct TALER_PolicyFulfilmentOutcome *outcome)
|
||||||
|
{
|
||||||
|
if (NULL == outcome)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (NULL != outcome->positions)
|
||||||
|
GNUNET_free (outcome->positions);
|
||||||
|
|
||||||
|
GNUNET_free (outcome);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* end of extensions.c */
|
/* end of extensions.c */
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
|
TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
|
||||||
*/
|
*/
|
||||||
/**
|
/**
|
||||||
* @file policy_brandt_vickery_auction.c
|
* @file policy_brandt_vickrey_auction.c
|
||||||
* @brief Extension for replay of auctions of type Brandt
|
* @brief Extension for replay of auctions of type Brandt
|
||||||
* @author Özgür Kesim
|
* @author Özgür Kesim
|
||||||
*/
|
*/
|
||||||
@ -26,8 +26,8 @@
|
|||||||
#include "stdint.h"
|
#include "stdint.h"
|
||||||
#include <microhttpd.h>
|
#include <microhttpd.h>
|
||||||
|
|
||||||
#define POLICY_AUCTION "policy_brandt_vickery_auction"
|
#define POLICY_AUCTION "policy_brandt_vickrey_auction"
|
||||||
#define LOG_PREFIX "[policy_brandt_vickery_auction] "
|
#define LOG_PREFIX "[policy_brandt_vickrey_auction] "
|
||||||
#define MAX_RESULT_SIZE 10 * 1024
|
#define MAX_RESULT_SIZE 10 * 1024
|
||||||
|
|
||||||
/* (public) configuration of this extension */
|
/* (public) configuration of this extension */
|
||||||
@ -54,7 +54,7 @@ struct result
|
|||||||
{
|
{
|
||||||
uint16_t bidder;
|
uint16_t bidder;
|
||||||
uint16_t price_idx;
|
uint16_t price_idx;
|
||||||
const char *price;
|
const char *price;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -73,12 +73,19 @@ struct transcript
|
|||||||
/* Payto URL */
|
/* Payto URL */
|
||||||
const char *payto;
|
const char *payto;
|
||||||
|
|
||||||
/* Number of bidders + 1 (for seller) */
|
/* Number of bidders */
|
||||||
uint16_t n;
|
uint16_t n;
|
||||||
|
|
||||||
/* (n-1) public keys of bidders */
|
/* (n-1) public keys of bidders */
|
||||||
struct GNUNET_CRYPTO_EddsaPublicKey *bidder_pub;
|
struct GNUNET_CRYPTO_EddsaPublicKey *bidder_pub;
|
||||||
|
|
||||||
|
/* Hash of the auction */
|
||||||
|
struct GNUNET_HashCode h_auction;
|
||||||
|
|
||||||
|
/* (n-1) calculated serial_ids */
|
||||||
|
struct GNUNET_HashCode *serial_ids;
|
||||||
|
|
||||||
|
|
||||||
/* Type of auction, see libbrandt */
|
/* Type of auction, see libbrandt */
|
||||||
uint16_t m;
|
uint16_t m;
|
||||||
|
|
||||||
@ -137,6 +144,25 @@ json_error (json_t **output,
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* Create serial as H(bidder_pub, h_auction) */
|
||||||
|
static void
|
||||||
|
calculate_serial (
|
||||||
|
struct GNUNET_CRYPTO_EddsaPublicKey *pub,
|
||||||
|
struct GNUNET_HashCode *hc,
|
||||||
|
struct GNUNET_HashCode *serial)
|
||||||
|
{
|
||||||
|
struct GNUNET_HashContext *ctx = GNUNET_CRYPTO_hash_context_start ();
|
||||||
|
GNUNET_CRYPTO_hash_context_read (ctx,
|
||||||
|
pub,
|
||||||
|
sizeof(*pub));
|
||||||
|
GNUNET_CRYPTO_hash_context_read (ctx,
|
||||||
|
hc,
|
||||||
|
sizeof(*hc));
|
||||||
|
GNUNET_CRYPTO_hash_context_finish (ctx,
|
||||||
|
serial);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @brief Parses a given json as transcript.
|
* @brief Parses a given json as transcript.
|
||||||
*
|
*
|
||||||
@ -165,8 +191,8 @@ parse_transcript (const json_t *jtr,
|
|||||||
char *perr;
|
char *perr;
|
||||||
unsigned int eline;
|
unsigned int eline;
|
||||||
struct GNUNET_JSON_Specification au_spec[] = {
|
struct GNUNET_JSON_Specification au_spec[] = {
|
||||||
GNUNET_JSON_spec_bool ("public", &tr->public),
|
GNUNET_JSON_spec_bool ("outcome_public", &tr->public),
|
||||||
GNUNET_JSON_spec_uint16 ("type", &tr->m),
|
GNUNET_JSON_spec_uint16 ("auction_type", &tr->m),
|
||||||
GNUNET_JSON_spec_fixed_auto ("pubkey", &tr->seller_pub),
|
GNUNET_JSON_spec_fixed_auto ("pubkey", &tr->seller_pub),
|
||||||
GNUNET_JSON_spec_timestamp ("time_start", &tr->time_start),
|
GNUNET_JSON_spec_timestamp ("time_start", &tr->time_start),
|
||||||
GNUNET_JSON_spec_relative_time ("time_round", &tr->time_round),
|
GNUNET_JSON_spec_relative_time ("time_round", &tr->time_round),
|
||||||
@ -187,6 +213,13 @@ parse_transcript (const json_t *jtr,
|
|||||||
return json_error (jerror,
|
return json_error (jerror,
|
||||||
perr);
|
perr);
|
||||||
|
|
||||||
|
{
|
||||||
|
const char *auc_js = json_dumps (auc, JSON_COMPACT);
|
||||||
|
GNUNET_CRYPTO_hash (auc_js,
|
||||||
|
strlen (auc_js),
|
||||||
|
&tr->h_auction);
|
||||||
|
}
|
||||||
|
|
||||||
// Prices...
|
// Prices...
|
||||||
{
|
{
|
||||||
size_t idx;
|
size_t idx;
|
||||||
@ -235,15 +268,23 @@ parse_transcript (const json_t *jtr,
|
|||||||
|
|
||||||
tr->n = json_array_size (bidders);
|
tr->n = json_array_size (bidders);
|
||||||
|
|
||||||
tr->bidder_pub = GNUNET_new_array (tr->n, struct
|
tr->bidder_pub = GNUNET_new_array (
|
||||||
GNUNET_CRYPTO_EddsaPublicKey);
|
tr->n,
|
||||||
|
struct GNUNET_CRYPTO_EddsaPublicKey);
|
||||||
|
|
||||||
|
tr->serial_ids = GNUNET_new_array (
|
||||||
|
tr->n,
|
||||||
|
struct GNUNET_HashCode);
|
||||||
|
|
||||||
json_array_foreach (bidders, idx, val)
|
json_array_foreach (bidders, idx, val)
|
||||||
{
|
{
|
||||||
struct GNUNET_JSON_Specification spec[] = {
|
struct GNUNET_JSON_Specification spec[] = {
|
||||||
GNUNET_JSON_spec_fixed_auto (NULL,
|
GNUNET_JSON_spec_fixed_auto (NULL,
|
||||||
&(tr->bidder_pub[idx])),
|
&tr->bidder_pub[idx]),
|
||||||
GNUNET_JSON_spec_end (),
|
GNUNET_JSON_spec_end (),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* TODO: cleanup */
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
GNUNET_JSON_parse (val,
|
GNUNET_JSON_parse (val,
|
||||||
spec,
|
spec,
|
||||||
@ -252,12 +293,13 @@ parse_transcript (const json_t *jtr,
|
|||||||
return json_error (jerror,
|
return json_error (jerror,
|
||||||
"bidder no %ld public key couldn't be parsed",
|
"bidder no %ld public key couldn't be parsed",
|
||||||
idx + 1);
|
idx + 1);
|
||||||
|
|
||||||
|
calculate_serial (&tr->bidder_pub[idx],
|
||||||
|
&tr->h_auction,
|
||||||
|
&tr->serial_ids[idx]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: parse and verify signatures from bidders of the auction
|
|
||||||
|
|
||||||
|
|
||||||
// Messages
|
// Messages
|
||||||
{
|
{
|
||||||
size_t nm;
|
size_t nm;
|
||||||
@ -322,7 +364,6 @@ parse_transcript (const json_t *jtr,
|
|||||||
|
|
||||||
DONE:
|
DONE:
|
||||||
|
|
||||||
*jerror = NULL;
|
|
||||||
return GNUNET_OK;
|
return GNUNET_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -331,7 +372,8 @@ DONE:
|
|||||||
* @brief replay an auction using the external program
|
* @brief replay an auction using the external program
|
||||||
*
|
*
|
||||||
* @param[in] root The original JSON transcript
|
* @param[in] root The original JSON transcript
|
||||||
* @param[in] transcript The transcript object parsed so far
|
* @param[in,out] transcript The transcript object parsed so far
|
||||||
|
* @param[out] outcome Outcome object to fill
|
||||||
* @param[out] result The JSON result from the program
|
* @param[out] result The JSON result from the program
|
||||||
* @return GNUNET_OK on success
|
* @return GNUNET_OK on success
|
||||||
*
|
*
|
||||||
@ -340,8 +382,10 @@ DONE:
|
|||||||
static enum GNUNET_GenericReturnValue
|
static enum GNUNET_GenericReturnValue
|
||||||
replay_transcript (const json_t*root,
|
replay_transcript (const json_t*root,
|
||||||
struct transcript *tr,
|
struct transcript *tr,
|
||||||
|
struct TALER_PolicyFulfilmentOutcome **outcome,
|
||||||
json_t **result)
|
json_t **result)
|
||||||
{
|
{
|
||||||
|
enum GNUNET_GenericReturnValue ret = GNUNET_SYSERR;
|
||||||
struct GNUNET_DISK_PipeHandle *pi;
|
struct GNUNET_DISK_PipeHandle *pi;
|
||||||
struct GNUNET_DISK_PipeHandle *po;
|
struct GNUNET_DISK_PipeHandle *po;
|
||||||
const struct GNUNET_DISK_FileHandle *fd;
|
const struct GNUNET_DISK_FileHandle *fd;
|
||||||
@ -444,32 +488,106 @@ replay_transcript (const json_t*root,
|
|||||||
return json_error (result, "internal error");
|
return json_error (result, "internal error");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: check each winner with tr->expected, if applicable
|
||||||
|
|
||||||
|
|
||||||
|
// Create the outcome object
|
||||||
{
|
{
|
||||||
// TODO: check each winner with tr->expected, if applicable
|
json_t *w;
|
||||||
json_object_set (res, "exchange_sig", json_string (
|
size_t idx;
|
||||||
"sig(priv_E, winners)"));
|
struct TALER_PolicyFulfilmentOutcomePosition *pos;
|
||||||
|
|
||||||
|
*outcome =
|
||||||
|
TALER_policy_fulfilment_outcome_new (tr->n);
|
||||||
|
|
||||||
|
/* Set outcome for all bidders to a default value first */
|
||||||
|
for (uint16_t i = 0; i<tr->n; i++)
|
||||||
|
{
|
||||||
|
pos = &((*outcome)->positions[i]);
|
||||||
|
pos->serial_id = tr->serial_ids[i];
|
||||||
|
pos->has_new_amount = false;
|
||||||
|
pos->state = TALER_PolicyFulfilmentFailureRefreshable;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the outcome of the winners */
|
||||||
|
json_array_foreach (winners, idx, w)
|
||||||
|
{
|
||||||
|
enum GNUNET_GenericReturnValue ret;
|
||||||
|
const char *jerror;
|
||||||
|
uint16_t bidder;
|
||||||
|
uint16_t price_idx;
|
||||||
|
struct TALER_Amount price;
|
||||||
|
|
||||||
|
struct GNUNET_JSON_Specification spec[] = {
|
||||||
|
GNUNET_JSON_spec_uint16 ("bidder",
|
||||||
|
&bidder),
|
||||||
|
GNUNET_JSON_spec_uint16 ("price_idx",
|
||||||
|
&price_idx),
|
||||||
|
TALER_JSON_spec_amount ("price",
|
||||||
|
BV_config.auction_fee.currency,
|
||||||
|
&price),
|
||||||
|
GNUNET_JSON_spec_end ()
|
||||||
|
};
|
||||||
|
|
||||||
|
ret = GNUNET_JSON_parse (w,
|
||||||
|
spec,
|
||||||
|
&jerror,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
if (GNUNET_OK != ret)
|
||||||
|
{
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||||
|
LOG_PREFIX
|
||||||
|
"couldn't parse output of replay program: %s\n",
|
||||||
|
jerror);
|
||||||
|
ret = json_error (result, "internal error");
|
||||||
|
goto DONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bidder > tr->n - 1)
|
||||||
|
{
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||||
|
LOG_PREFIX
|
||||||
|
"replay program sent a bidder out of range\n");
|
||||||
|
ret = json_error (result, "internal error");
|
||||||
|
goto DONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fill the outcome position for this winning bidder.
|
||||||
|
pos = &((*outcome)->positions[idx]);
|
||||||
|
pos->has_new_amount = true;
|
||||||
|
pos->new_amount = price;
|
||||||
|
pos->state = TALER_PolicyFulfilmentSuccessTransfer;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: return own result object.
|
||||||
|
// TODO: sign the result by the exchange
|
||||||
|
*result = json_copy (res);
|
||||||
|
json_decref (res);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: return own result object.
|
|
||||||
*result = json_copy (res);
|
|
||||||
json_decref (res);
|
|
||||||
}
|
}
|
||||||
|
ret = GNUNET_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GNUNET_OK != GNUNET_OS_process_wait (proc))
|
ret = GNUNET_OS_process_wait (proc);
|
||||||
|
if (GNUNET_OK != ret)
|
||||||
{
|
{
|
||||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||||
LOG_PREFIX "error while launching auction replay program '%s'\n",
|
LOG_PREFIX
|
||||||
|
"error waiting for auction replay program '%s'\n",
|
||||||
replay_program);
|
replay_program);
|
||||||
|
|
||||||
json_object_clear (*result);
|
json_object_clear (*result);
|
||||||
return json_error (result, "internal error");
|
ret = json_error (result, "internal error");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DONE:
|
||||||
return GNUNET_OK;
|
if (GNUNET_OK != ret)
|
||||||
|
{
|
||||||
|
TALER_policy_fulfilment_outcome_free (*outcome);
|
||||||
|
*outcome = NULL;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -531,60 +649,58 @@ auction_load_config (
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief implements the TALER_Extension.http_get_handler
|
* @brief implements the TALER_Extension.policy_get_handler
|
||||||
*/
|
*/
|
||||||
static MHD_RESULT
|
static MHD_RESULT
|
||||||
auction_http_get_handler (
|
auction_policy_get_handler (
|
||||||
struct MHD_Connection *connection,
|
struct MHD_Connection *connection,
|
||||||
const char *const args[])
|
const char *const args[])
|
||||||
{
|
{
|
||||||
/* TODO: return some meta-data about supported version, limits, etc.*/
|
/* TODO: return some meta-data about supported version, limits, etc.*/
|
||||||
|
|
||||||
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
|
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
|
||||||
LOG_PREFIX "auction_http_get_handler not implemented yet\n");
|
LOG_PREFIX "auction_policy_get_handler not implemented yet\n");
|
||||||
|
|
||||||
return TALER_MHD_reply_with_error (connection,
|
return TALER_MHD_reply_with_error (connection,
|
||||||
MHD_HTTP_NOT_IMPLEMENTED,
|
MHD_HTTP_NOT_IMPLEMENTED,
|
||||||
TALER_EC_EXCHANGE_GENERIC_OPERATION_UNKNOWN,
|
TALER_EC_EXCHANGE_GENERIC_OPERATION_UNKNOWN,
|
||||||
"auction_http_get_handler not implemented yet\n");
|
"auction_policy_get_handler not implemented yet\n");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief implements the TALER_Extension.http_post_handler
|
* @brief implements the TALER_Extension.policy_post_handler
|
||||||
*
|
*
|
||||||
* TODO: make this non-blocking
|
* TODO: make this non-blocking
|
||||||
*/
|
*/
|
||||||
static MHD_RESULT
|
enum GNUNET_GenericReturnValue
|
||||||
auction_http_post_handler (
|
auction_policy_post_handler (
|
||||||
struct MHD_Connection *connection,
|
|
||||||
const json_t *root,
|
const json_t *root,
|
||||||
const char *const args[])
|
const char *const args[],
|
||||||
|
enum GNUNET_GenericReturnValue (*serial_id_check)(struct GNUNET_HashCode
|
||||||
|
serial_ids[], size_t size),
|
||||||
|
struct TALER_PolicyFulfilmentOutcome **outcome,
|
||||||
|
json_t **output)
|
||||||
{
|
{
|
||||||
struct transcript tr = {};
|
struct transcript tr = {};
|
||||||
enum GNUNET_GenericReturnValue ret;
|
enum GNUNET_GenericReturnValue ret;
|
||||||
json_t *result1;
|
|
||||||
json_t *result2;
|
|
||||||
|
|
||||||
|
*outcome = NULL;
|
||||||
ret = parse_transcript (root,
|
ret = parse_transcript (root,
|
||||||
&tr,
|
&tr,
|
||||||
&result1);
|
output);
|
||||||
|
|
||||||
|
/* TODO: cleanups! */
|
||||||
if (GNUNET_OK != ret)
|
if (GNUNET_OK != ret)
|
||||||
return TALER_MHD_reply_json_steal (connection,
|
return ret;
|
||||||
result1,
|
|
||||||
MHD_HTTP_BAD_REQUEST);
|
|
||||||
GNUNET_assert (NULL == result1);
|
|
||||||
|
|
||||||
ret = replay_transcript (root,
|
serial_id_check (tr.serial_ids, tr.n);
|
||||||
&tr,
|
|
||||||
&result2);
|
|
||||||
|
|
||||||
return TALER_MHD_reply_json_steal (connection,
|
return replay_transcript (root,
|
||||||
result2,
|
&tr,
|
||||||
GNUNET_OK == ret?
|
outcome,
|
||||||
MHD_HTTP_OK :
|
output);
|
||||||
MHD_HTTP_BAD_REQUEST);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -594,6 +710,7 @@ auction_http_post_handler (
|
|||||||
* @param[in] input The policy_details for this handler during deposit
|
* @param[in] input The policy_details for this handler during deposit
|
||||||
* @param[out] serial On success will contain the serial-ID under which the
|
* @param[out] serial On success will contain the serial-ID under which the
|
||||||
* @param[out] deadline On success will contain a deadline, might be "forever"
|
* @param[out] deadline On success will contain a deadline, might be "forever"
|
||||||
|
* @param[out] state_on_timeout On success, will be set to the default state that the policy shall be put in case of a timeout.
|
||||||
* @param[out] error_hint On error, will contain a hint
|
* @param[out] error_hint On error, will contain a hint
|
||||||
* exchange should store the policy_details in the policy_details table.
|
* exchange should store the policy_details in the policy_details table.
|
||||||
* @return GNUNET_OK if the request was OK
|
* @return GNUNET_OK if the request was OK
|
||||||
@ -603,6 +720,7 @@ auction_parse_policy_details (
|
|||||||
const json_t *input,
|
const json_t *input,
|
||||||
struct GNUNET_HashCode *serial,
|
struct GNUNET_HashCode *serial,
|
||||||
struct GNUNET_TIME_Timestamp *deadline,
|
struct GNUNET_TIME_Timestamp *deadline,
|
||||||
|
enum TALER_PolicyFulfilmentState *state_on_timeout,
|
||||||
const char **error_hint)
|
const char **error_hint)
|
||||||
{
|
{
|
||||||
enum GNUNET_GenericReturnValue ret = GNUNET_NO;
|
enum GNUNET_GenericReturnValue ret = GNUNET_NO;
|
||||||
@ -636,22 +754,14 @@ auction_parse_policy_details (
|
|||||||
LOG_PREFIX "check of deadline %ld not implemented!\n",
|
LOG_PREFIX "check of deadline %ld not implemented!\n",
|
||||||
deadline->abs_time.abs_value_us);
|
deadline->abs_time.abs_value_us);
|
||||||
|
|
||||||
/* Create serial as H(bidder_pub, h_auction) */
|
calculate_serial (&pub, &hc, serial);
|
||||||
{
|
|
||||||
struct GNUNET_HashContext *hc = GNUNET_CRYPTO_hash_context_start ();
|
|
||||||
GNUNET_CRYPTO_hash_context_read (hc,
|
|
||||||
&pub,
|
|
||||||
sizeof(pub));
|
|
||||||
GNUNET_CRYPTO_hash_context_read (hc,
|
|
||||||
&hc,
|
|
||||||
sizeof(hc));
|
|
||||||
GNUNET_CRYPTO_hash_context_finish (hc,
|
|
||||||
serial);
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = GNUNET_OK;
|
ret = GNUNET_OK;
|
||||||
} while(0);
|
} while(0);
|
||||||
|
|
||||||
|
/* In case of timeout, the coin shall be refreshable by the owner */
|
||||||
|
*state_on_timeout = TALER_PolicyFulfilmentTimeoutRefreshable;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -668,8 +778,8 @@ struct TALER_Extension TE_auction_brandt = {
|
|||||||
.load_config = &auction_load_config,
|
.load_config = &auction_load_config,
|
||||||
.manifest = &auction_manifest,
|
.manifest = &auction_manifest,
|
||||||
.parse_policy_details = &auction_parse_policy_details,
|
.parse_policy_details = &auction_parse_policy_details,
|
||||||
.http_get_handler = &auction_http_get_handler,
|
.policy_get_handler = &auction_policy_get_handler,
|
||||||
.http_post_handler = &auction_http_post_handler,
|
.policy_post_handler = &auction_policy_post_handler,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -687,7 +797,7 @@ struct TALER_Extension TE_auction_brandt = {
|
|||||||
* @return Pointer to TE_auction_brandt
|
* @return Pointer to TE_auction_brandt
|
||||||
*/
|
*/
|
||||||
struct TALER_Extension *
|
struct TALER_Extension *
|
||||||
libtaler_extension_policy_brandt_vickery_auction_init (void *arg)
|
libtaler_extension_policy_brandt_vickrey_auction_init (void *arg)
|
||||||
{
|
{
|
||||||
const struct GNUNET_CONFIGURATION_Handle *cfg = arg;
|
const struct GNUNET_CONFIGURATION_Handle *cfg = arg;
|
||||||
|
|
||||||
@ -751,7 +861,7 @@ libtaler_extension_policy_brandt_vickery_auction_init (void *arg)
|
|||||||
* @return null
|
* @return null
|
||||||
*/
|
*/
|
||||||
void *
|
void *
|
||||||
libtaler_extension_policy_brandt_vickery_auction_done (void *arg)
|
libtaler_extension_policy_brandt_vickrey_auction_done (void *arg)
|
||||||
{
|
{
|
||||||
auction_disable (&TE_auction_brandt);
|
auction_disable (&TE_auction_brandt);
|
||||||
GNUNET_free (replay_program);
|
GNUNET_free (replay_program);
|
||||||
@ -761,4 +871,4 @@ libtaler_extension_policy_brandt_vickery_auction_done (void *arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* end of policy_brandt_vickery_auction.c */
|
/* end of policy_brandt_vickrey_auction.c */
|
||||||
|
@ -531,7 +531,8 @@ struct TALER_EXCHANGEDB_TableData
|
|||||||
char *policy_options;
|
char *policy_options;
|
||||||
struct GNUNET_HashCode serial_id;
|
struct GNUNET_HashCode serial_id;
|
||||||
struct GNUNET_TIME_Timestamp deadline;
|
struct GNUNET_TIME_Timestamp deadline;
|
||||||
uint64_t fulfilment_state;
|
uint16_t timeout_fulfilment_state;
|
||||||
|
uint16_t fulfilment_state;
|
||||||
} policy_details;
|
} policy_details;
|
||||||
|
|
||||||
struct
|
struct
|
||||||
@ -1464,6 +1465,11 @@ struct TALER_EXCHANGEDB_Deposit
|
|||||||
*/
|
*/
|
||||||
struct GNUNET_TIME_Timestamp policy_deadline;
|
struct GNUNET_TIME_Timestamp policy_deadline;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The state that a _pending_ policy should be put into once the timeout triggers
|
||||||
|
*/
|
||||||
|
uint16_t policy_state_on_timeout;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hash over the @e policy_details. Only filled if has_policy_details is
|
* Hash over the @e policy_details. Only filled if has_policy_details is
|
||||||
|
@ -53,6 +53,10 @@ struct TALER_Extensions
|
|||||||
const struct TALER_Extension *extension;
|
const struct TALER_Extension *extension;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Forward declarations */
|
||||||
|
enum TALER_PolicyFulfilmentState;
|
||||||
|
struct TALER_PolicyFulfilmentOutcome;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @brief Represents the implementation of an extension.
|
* @brief Represents the implementation of an extension.
|
||||||
*
|
*
|
||||||
@ -159,6 +163,7 @@ struct TALER_Extension
|
|||||||
* Policy related handlers
|
* Policy related handlers
|
||||||
* =========================
|
* =========================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Handler to check a policy. Can be NULL;
|
* @brief Handler to check a policy. Can be NULL;
|
||||||
*
|
*
|
||||||
@ -166,44 +171,55 @@ struct TALER_Extension
|
|||||||
* (see https://docs.taler.net/core/api-exchange.html#deposit), this handler
|
* (see https://docs.taler.net/core/api-exchange.html#deposit), this handler
|
||||||
* will be called before the deposit transaction.
|
* will be called before the deposit transaction.
|
||||||
*
|
*
|
||||||
* @param[in] policy_details Details about the policy, provided by the client
|
* @param[in] policy_details Details about the policy, provided by the client
|
||||||
* during a deposit request.
|
* during a deposit request.
|
||||||
* @param[out] serial On success, will contain the serial-ID under which the
|
* @param[out] serial On success, will contain the serial-ID under which the
|
||||||
* exchange should save the policy_details in the deposit table.
|
* exchange should save the policy_details in the deposit table.
|
||||||
* @param[out] deadline On success, set to the deadline until the policy must
|
* @param[out] deadline On success, set to the deadline until the policy must
|
||||||
* be fulfilled. Might be "forever". This value is used by an external
|
* be fulfilled. Might be "forever". This value is used by an
|
||||||
|
* external mechanism to detect timeouts.
|
||||||
|
* @param[out] state_on_timeout On GNUNET_OK, which state shall the
|
||||||
|
* fulfilment of this policy be put in. MUST be either
|
||||||
|
* TALER_PolicyFulfilmentTimeoutTransfer or
|
||||||
|
* TALER_PolicyFulfilmentTimeoutRefreshable
|
||||||
* @param[out] error_hint On error, will contain a hint
|
* @param[out] error_hint On error, will contain a hint
|
||||||
* mechanism to detect timeouts.
|
* @return GNUNET_OK if the data was accepted by the extension.
|
||||||
* @return GNUNET_OK if the data was accepted by the extension.
|
|
||||||
*/
|
*/
|
||||||
enum GNUNET_GenericReturnValue (*parse_policy_details)(
|
enum GNUNET_GenericReturnValue (*parse_policy_details)(
|
||||||
const json_t *policy_details,
|
const json_t *policy_details,
|
||||||
struct GNUNET_HashCode *serial,
|
struct GNUNET_HashCode *serial,
|
||||||
struct GNUNET_TIME_Timestamp *deadline,
|
struct GNUNET_TIME_Timestamp *deadline,
|
||||||
|
enum TALER_PolicyFulfilmentState *state_on_timeout,
|
||||||
const char **error_hint);
|
const char **error_hint);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Handler for POST-requests to the /policy/$name endpoint. Can be NULL.
|
* @brief Handler for POST-requests to the /extensions/$name endpoint. Can be NULL.
|
||||||
*
|
*
|
||||||
* @param connection The current connection
|
* @param[in] root The JSON body from the request
|
||||||
* @param root The JSON body from the request
|
* @param[in] args Additional query parameters of the request.
|
||||||
* @param args Additional query parameters of the request.
|
* @param[in] serial_id_check Helper function to check the presence of serial_ids in policy_details. Can be used by the handler to ensure the presence of entries before starting calculations.
|
||||||
* @return MDH result
|
* @param[out] outcome Result of the operation. Must be freed via TALER_policy_fulfilment_outcome_free after use.
|
||||||
|
* @param[out] output JSON output to return to the client
|
||||||
|
* @return GNUNET_OK on success.
|
||||||
*/
|
*/
|
||||||
MHD_RESULT (*http_post_handler)(
|
enum GNUNET_GenericReturnValue (*policy_post_handler)(
|
||||||
struct MHD_Connection *connection,
|
|
||||||
const json_t *root,
|
const json_t *root,
|
||||||
const char *const args[]);
|
const char *const args[],
|
||||||
|
enum GNUNET_GenericReturnValue (*serial_id_check)(struct GNUNET_HashCode
|
||||||
|
serial_ids[], size_t
|
||||||
|
size),
|
||||||
|
struct TALER_PolicyFulfilmentOutcome **outcome,
|
||||||
|
json_t **output);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Handler for GET-requests to the /policy/$name endpoint. Can be NULL.
|
* @brief Handler for GET-requests to the /extensions/$name endpoint. Can be NULL.
|
||||||
*
|
*
|
||||||
* @param connection The current connection
|
* @param connection The current connection
|
||||||
* @param root The JSON body from the request
|
* @param root The JSON body from the request
|
||||||
* @param args Additional query parameters of the request.
|
* @param args Additional query parameters of the request.
|
||||||
* @return MDH result
|
* @return MDH result
|
||||||
*/
|
*/
|
||||||
MHD_RESULT (*http_get_handler)(
|
MHD_RESULT (*policy_get_handler)(
|
||||||
struct MHD_Connection *connection,
|
struct MHD_Connection *connection,
|
||||||
const char *const args[]);
|
const char *const args[]);
|
||||||
};
|
};
|
||||||
@ -382,28 +398,123 @@ TALER_extensions_get_age_restriction_mask ();
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* ===================================
|
* ===================================
|
||||||
* Policy extensions related functions
|
* Policy extensions related API
|
||||||
* ===================================
|
* ===================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @brief Finds the extension for a given policy
|
* @brief Describes the states of fulfilment of a policy bound to a deposit
|
||||||
|
*/
|
||||||
|
enum TALER_PolicyFulfilmentState
|
||||||
|
{
|
||||||
|
/* Initial state of the policy */
|
||||||
|
TALER_PolicyFulfilmentPending = 0,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Policy provably fulfilled. The semantics of the policy require that
|
||||||
|
* the exchange MUST transfer amount in the associated deposit to the
|
||||||
|
* payto-URI */
|
||||||
|
TALER_PolicyFulfilmentSuccessTransfer = 1,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Policy provably fulfilled. The semantics of the policy require that
|
||||||
|
* the coins' value in the associated deposit remains and the owner can
|
||||||
|
* refresh them. */
|
||||||
|
TALER_PolicyFulfilmentSuccessRefreshable = 2,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Policy provably UNfulfilled. The semantics of the policy require
|
||||||
|
* that the exchange MUST transfer amount in the associated deposit to
|
||||||
|
* the payto-URI. */
|
||||||
|
TALER_PolicyFulfilmentFailureTransfer = 3,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Policy provably UNfulfilled. The semantics of the policy require that
|
||||||
|
* the coins' value in the associated deposit remains and the owner can
|
||||||
|
* refresh them. */
|
||||||
|
TALER_PolicyFulfilmentFailureRefreshable = 4,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Policy timed out. The semantics of the policy require that the
|
||||||
|
* exchange MUST transfer amount in the associated deposit to the
|
||||||
|
* payto-URI. */
|
||||||
|
TALER_PolicyFulfilmentTimeoutTransfer = 5,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Policy timed out. The semantics of the policy require that the
|
||||||
|
* coins' value in the associated deposit remains and the owner can
|
||||||
|
* refresh them. */
|
||||||
|
TALER_PolicyFulfilmentTimeoutRefreshable = 6,
|
||||||
|
|
||||||
|
TALER_PolicyFulfilmentStateMax = TALER_PolicyFulfilmentTimeoutRefreshable
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const char *
|
||||||
|
TALER_policy_fulfilment_state_str (enum TALER_PolicyFulfilmentState state);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @brief Respresents the outcome of a policy fulfilment evaluation
|
||||||
|
* returned by a http_post_handler.
|
||||||
|
*/
|
||||||
|
struct TALER_PolicyFulfilmentOutcome
|
||||||
|
{
|
||||||
|
size_t len;
|
||||||
|
struct TALER_PolicyFulfilmentOutcomePosition
|
||||||
|
{
|
||||||
|
/* Identifies the particular policy in the policy_details */
|
||||||
|
struct GNUNET_HashCode serial_id;
|
||||||
|
|
||||||
|
/* The state that the policy should be be put into. */
|
||||||
|
enum TALER_PolicyFulfilmentState state;
|
||||||
|
|
||||||
|
/* If @e has_new_amount is true, the actual amount to be transfered
|
||||||
|
* according to the @e state is not taken from the associated deposit
|
||||||
|
* entry, but provided with @new_amount
|
||||||
|
*/
|
||||||
|
bool has_new_amount;
|
||||||
|
struct TALER_Amount new_amount;
|
||||||
|
|
||||||
|
} *positions;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @brief allocate a TALER_PolicyFulfilmentOutcome
|
||||||
|
*/
|
||||||
|
struct TALER_PolicyFulfilmentOutcome *
|
||||||
|
TALER_policy_fulfilment_outcome_new (size_t len);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @brief free the content of a TALER_PolicyFulfilmentOutcome
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
TALER_policy_fulfilment_outcome_free (
|
||||||
|
struct TALER_PolicyFulfilmentOutcome *outcome);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @brief Extracts meta information from policy_details
|
||||||
*
|
*
|
||||||
* @param[in] policy_details JSON of the policy detail from a deposit request
|
* @param[in] policy_details JSON of the policy detail from a deposit request
|
||||||
* @param[out] serial On GNUNET_OK, the hash code that should be used to save the policy_details in the policy_details table
|
* @param[out] serial On GNUNET_OK, the hash code that should be used to save the policy_details in the policy_details table
|
||||||
* @param[out] deadline On GNUNET_OK, the deadline that should be saved in the policy_details table
|
* @param[out] deadline On GNUNET_OK, the deadline that should be saved in the policy_details table
|
||||||
|
* @param[out] state_on_timeout On GNUNET_OK, which state shall the fulfilment of this policy be put in
|
||||||
* @param[out] error_hint On GNUNET_SYSERR, will contain a hint for the reason why it failed
|
* @param[out] error_hint On GNUNET_SYSERR, will contain a hint for the reason why it failed
|
||||||
* @return GNUNET_OK on success, with *extension set to the correct extension.
|
* @return GNUNET_OK on success, with *extension set to the correct extension.
|
||||||
* GNUNET_NO, when no extension was found. GNUNET_SYSERR when the JSON was
|
* GNUNET_NO, when no extension was found. GNUNET_SYSERR when the JSON was
|
||||||
* invalid, with *error_hint maybe non-NULL.
|
* invalid, with *error_hint maybe non-NULL.
|
||||||
*/
|
*/
|
||||||
enum GNUNET_GenericReturnValue
|
enum GNUNET_GenericReturnValue
|
||||||
TALER_extensions_serial_from_policy_details (
|
TALER_extensions_extract_meta_data_from_policy_details (
|
||||||
const json_t *policy_details,
|
const json_t *policy_details,
|
||||||
struct GNUNET_HashCode *serial,
|
struct GNUNET_HashCode *serial,
|
||||||
struct GNUNET_TIME_Timestamp *deadline,
|
struct GNUNET_TIME_Timestamp *deadline,
|
||||||
|
enum TALER_PolicyFulfilmentState *state_on_timeout,
|
||||||
const char **error_hint);
|
const char **error_hint);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ================================
|
* ================================
|
||||||
* Merchant refund policy
|
* Merchant refund policy
|
||||||
|
Loading…
Reference in New Issue
Block a user