WIP: policy_*_fulfiment added and API changes

- policy_fulfilment table defined, handlers added
- policy_details_fulfilment table defined, handlers added
- TALER_extensions_serial_from_policy_details implemened
This commit is contained in:
Özgür Kesim 2022-10-08 17:13:57 +02:00
parent d3c509fcd9
commit 4ba07b54e4
Signed by: oec
GPG Key ID: 3D76A56D79EDD9D7
12 changed files with 181 additions and 91 deletions

View File

@ -115,6 +115,7 @@ static struct Table tables[] = {
{ .rt = TALER_EXCHANGEDB_RT_EXTENSIONS}, { .rt = TALER_EXCHANGEDB_RT_EXTENSIONS},
{ .rt = TALER_EXCHANGEDB_RT_POLICY_DETAILS }, { .rt = TALER_EXCHANGEDB_RT_POLICY_DETAILS },
{ .rt = TALER_EXCHANGEDB_RT_POLICY_FULFILMENTS }, { .rt = TALER_EXCHANGEDB_RT_POLICY_FULFILMENTS },
{ .rt = TALER_EXCHANGEDB_RT_POLICY_DETAILS_FULFILMENTS },
{ .rt = TALER_EXCHANGEDB_RT_PURSE_REQUESTS}, { .rt = TALER_EXCHANGEDB_RT_PURSE_REQUESTS},
{ .rt = TALER_EXCHANGEDB_RT_PURSE_REFUNDS}, { .rt = TALER_EXCHANGEDB_RT_PURSE_REFUNDS},
{ .rt = TALER_EXCHANGEDB_RT_PURSE_MERGES}, { .rt = TALER_EXCHANGEDB_RT_PURSE_MERGES},

View File

@ -1620,14 +1620,14 @@ deposit_cb (void *cls,
want to do in parallel in the background to improve want to do in parallel in the background to improve
auditor performance! */ auditor performance! */
if (GNUNET_OK != if (GNUNET_OK !=
TALER_wallet_deposit_verify (&deposit->amount_with_fee, TALER_wallet_deposit_verify (
&deposit->amount_with_fee,
&issue->fees.deposit, &issue->fees.deposit,
&h_wire, &h_wire,
&deposit->h_contract_terms, &deposit->h_contract_terms,
&deposit->coin.h_age_commitment, &deposit->coin.h_age_commitment,
deposit->no_policy_details ? NULL : deposit->has_policy_details ?
&deposit->h_policy, &deposit->h_policy :NULL, &h_denom_pub,
&h_denom_pub,
deposit->timestamp, deposit->timestamp,
&deposit->merchant_pub, &deposit->merchant_pub,
deposit->refund_deadline, deposit->refund_deadline,

View File

@ -91,7 +91,7 @@ struct BatchDepositContext
* deposit operation, possibly NULL! * deposit operation, possibly NULL!
*/ */
json_t *policy_details; json_t *policy_details;
bool no_policy_details; bool has_policy_details;
/** /**
* Hash over @e policy_details, might be all zero; * Hash over @e policy_details, might be all zero;
@ -174,7 +174,7 @@ again:
&TEH_keys_exchange_sign_, &TEH_keys_exchange_sign_,
&bdc->h_contract_terms, &bdc->h_contract_terms,
&bdc->h_wire, &bdc->h_wire,
bdc->no_policy_details ? NULL : &bdc->h_policy, bdc->has_policy_details ? &bdc->h_policy : NULL,
bdc->exchange_timestamp, bdc->exchange_timestamp,
bdc->wire_deadline, bdc->wire_deadline,
bdc->refund_deadline, bdc->refund_deadline,
@ -474,7 +474,8 @@ parse_coin (struct MHD_Connection *connection,
&dc->h_wire, &dc->h_wire,
&dc->h_contract_terms, &dc->h_contract_terms,
&deposit->coin.h_age_commitment, &deposit->coin.h_age_commitment,
dc->no_policy_details ? NULL : &dc->h_policy, dc->has_policy_details ? &dc->h_policy :
NULL,
&deposit->coin.denom_pub_hash, &deposit->coin.denom_pub_hash,
dc->timestamp, dc->timestamp,
&dc->merchant_pub, &dc->merchant_pub,
@ -517,6 +518,7 @@ TEH_handler_batch_deposit (struct TEH_RequestContext *rc,
struct BatchDepositContext dc; struct BatchDepositContext dc;
json_t *coins; json_t *coins;
bool no_refund_deadline = true; bool no_refund_deadline = true;
bool no_policy_details = true;
struct GNUNET_JSON_Specification spec[] = { struct GNUNET_JSON_Specification spec[] = {
GNUNET_JSON_spec_string ("merchant_payto_uri", GNUNET_JSON_spec_string ("merchant_payto_uri",
&dc.payto_uri), &dc.payto_uri),
@ -531,7 +533,7 @@ TEH_handler_batch_deposit (struct TEH_RequestContext *rc,
GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_mark_optional (
GNUNET_JSON_spec_json ("policy", GNUNET_JSON_spec_json ("policy",
&dc.policy_details), &dc.policy_details),
&dc.no_policy_details), &no_policy_details),
GNUNET_JSON_spec_timestamp ("timestamp", GNUNET_JSON_spec_timestamp ("timestamp",
&dc.timestamp), &dc.timestamp),
GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_mark_optional (
@ -562,6 +564,8 @@ TEH_handler_batch_deposit (struct TEH_RequestContext *rc,
return MHD_YES; /* failure */ return MHD_YES; /* failure */
} }
dc.has_policy_details = ! no_policy_details;
/* validate merchant's wire details (as far as we can) */ /* validate merchant's wire details (as far as we can) */
{ {
char *emsg; char *emsg;
@ -606,7 +610,7 @@ TEH_handler_batch_deposit (struct TEH_RequestContext *rc,
TALER_merchant_wire_signature_hash (dc.payto_uri, TALER_merchant_wire_signature_hash (dc.payto_uri,
&dc.wire_salt, &dc.wire_salt,
&dc.h_wire); &dc.h_wire);
if (! dc.no_policy_details) if (dc.has_policy_details)
{ {
TALER_deposit_policy_hash (dc.policy_details, TALER_deposit_policy_hash (dc.policy_details,
&dc.h_policy); &dc.h_policy);

View File

@ -21,6 +21,7 @@
* @author Florian Dold * @author Florian Dold
* @author Benedikt Mueller * @author Benedikt Mueller
* @author Christian Grothoff * @author Christian Grothoff
* @author Özgür Kesim
*/ */
#include "platform.h" #include "platform.h"
#include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_util_lib.h>
@ -218,6 +219,7 @@ TEH_handler_deposit (struct MHD_Connection *connection,
struct TALER_EXCHANGEDB_Deposit deposit; struct TALER_EXCHANGEDB_Deposit deposit;
const char *payto_uri; const char *payto_uri;
struct TALER_ExtensionPolicyHashP *ph_policy = NULL; struct TALER_ExtensionPolicyHashP *ph_policy = NULL;
bool no_policy_details;
struct GNUNET_JSON_Specification spec[] = { struct GNUNET_JSON_Specification spec[] = {
GNUNET_JSON_spec_string ("merchant_payto_uri", GNUNET_JSON_spec_string ("merchant_payto_uri",
&payto_uri), &payto_uri),
@ -254,7 +256,7 @@ TEH_handler_deposit (struct MHD_Connection *connection,
GNUNET_JSON_spec_mark_optional ( GNUNET_JSON_spec_mark_optional (
GNUNET_JSON_spec_json ("policy", GNUNET_JSON_spec_json ("policy",
&deposit.policy_details), &deposit.policy_details),
&deposit.no_policy_details), &no_policy_details),
GNUNET_JSON_spec_end () GNUNET_JSON_spec_end ()
}; };
struct TALER_MerchantWireHashP h_wire; struct TALER_MerchantWireHashP h_wire;
@ -328,31 +330,15 @@ TEH_handler_deposit (struct MHD_Connection *connection,
dc.deposit = &deposit; dc.deposit = &deposit;
/* Check policy */ /* Check policy */
if (! deposit.no_policy_details) deposit.has_policy_details = ! no_policy_details;
if (! deposit.has_policy_details)
{ {
enum GNUNET_GenericReturnValue ret;
const struct TALER_Extension *ext;
const char *error_hint = NULL; const char *error_hint = NULL;
GNUNET_assert (ext->parse_policy_details); if (GNUNET_OK !=
TALER_extensions_serial_from_policy_details (deposit.policy_details,
do {
ret = TALER_extensions_from_policy_details (deposit.policy_details,
&ext,
&error_hint);
if (GNUNET_OK != ret)
break;
deposit.policy_deadline = GNUNET_TIME_UNIT_FOREVER_TS;
ret = ext->parse_policy_details (deposit.policy_details,
&deposit.policy_serial_id, &deposit.policy_serial_id,
&deposit.policy_deadline, &deposit.policy_deadline,
&error_hint); &error_hint))
} while(0);
if (GNUNET_OK != ret)
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,
@ -424,7 +410,7 @@ TEH_handler_deposit (struct MHD_Connection *connection,
NULL); NULL);
} }
if (! deposit.no_policy_details) if (deposit.has_policy_details)
{ {
TALER_deposit_policy_hash (deposit.policy_details, TALER_deposit_policy_hash (deposit.policy_details,
&deposit.h_policy); &deposit.h_policy);

View File

@ -539,10 +539,10 @@ SELECT add_constraints_to_refresh_transfer_keys_partition('default');
-- ------------------------------ policy_fulfilments ------------------------------------- -- ------------------------------ policy_fulfilments -------------------------------------
CREATE TABLE IF NOT EXISTS policy_fulfilments CREATE TABLE IF NOT EXISTS policy_fulfilments
(policy_fulfilments_serial_id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY (fulfilment_id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY
,fulfilment_timestamp INT8 NOT NULL ,fulfilment_timestamp INT8 NOT NULL
,fulfilment_proof VARCHAR) ,fulfilment_proof VARCHAR)
PARTITION BY HASH (policy_fulfilments_serial_id); PARTITION BY HASH (fulfilment_id);
COMMENT ON TABLE policy_fulfilments COMMENT ON TABLE policy_fulfilments
IS 'Proofs of fulfilment of policies that were set in deposits'; IS 'Proofs of fulfilment of policies that were set in deposits';
COMMENT ON COLUMN policy_fulfilments.fulfilment_timestamp COMMENT ON COLUMN policy_fulfilments.fulfilment_timestamp
@ -554,14 +554,14 @@ CREATE TABLE IF NOT EXISTS policy_fulfilments_default
PARTITION OF policy_fulfilments PARTITION OF policy_fulfilments
FOR VALUES WITH (MODULUS 1, REMAINDER 0); FOR VALUES WITH (MODULUS 1, REMAINDER 0);
-- ------------------------------ policy_details ---------------------------------------- -- ------------------------------ policy_details ----------------------------------------
CREATE TABLE IF NOT EXISTS policy_details CREATE TABLE IF NOT EXISTS policy_details
(policy_details_serial_id BIGINT GENERATED BY DEFAULT AS IDENTITY (policy_details_serial_id BIGINT GENERATED BY DEFAULT AS IDENTITY
,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
,fulfilment_serial_id BIGINT REFERENCES policy_fulfilments(policy_fulfilments_serial_id) ON DELETE CASCADE) ,deadline INT8 NOT NULL
,fulfilment_state INT4 NOT NULL CHECK(fulfilment_state between 0 and 3))
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.';
@ -569,13 +569,34 @@ COMMENT ON COLUMN policy_details.serial_id
IS 'ID (GNUNET_HashCode) that identifies a policy. Will be calculated by the policy extension based on the content'; IS 'ID (GNUNET_HashCode) that identifies a policy. Will be calculated by the policy extension based on the content';
COMMENT ON COLUMN policy_details.policy_options 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.fulfilment_serial_id COMMENT ON COLUMN policy_details.deadline
IS 'If not NULL, refers to the proof of fulfilment of this policy'; IS 'Deadline until the policy must be marked as fulfilled or unfulfilled (maybe "forever")';
COMMENT ON COLUMN policy_details.fulfilment_state
IS 'State of the fulfilment: 0 (PENDING), 1 (FULFILLED), 2 (NOT FULFILLED), 3 (TIMED OUT)';
CREATE TABLE IF NOT EXISTS policy_details_default CREATE TABLE IF NOT EXISTS policy_details_default
PARTITION OF policy_details PARTITION OF policy_details
FOR VALUES WITH (MODULUS 1, REMAINDER 0); FOR VALUES WITH (MODULUS 1, REMAINDER 0);
-- ------------------------------ policy_details_fulfilments -----------------------------
CREATE TABLE IF NOT EXISTS policy_details_fulfilments
(fulfilment_id BIGINT NOT NULL REFERENCES policy_fulfilments(fulfilment_id) ON DELETE CASCADE
,serial_id BYTEA NOT NULL UNIQUE REFERENCES policy_details(serial_id) ON DELETE CASCADE)
PARTITION BY HASH (serial_id); -- FIXME: choose other thing to hash here?
-- FIXME: define a primary key here?
COMMENT ON TABLE policy_details_fulfilments
IS 'Links policy_details.serial_id''s with policy_fulfilments.id''s. The same proof of fulfilment can be associated with multiple serial-id''s';
COMMENT ON COLUMN policy_details_fulfilments.fulfilment_id
IS 'ID of the proof of fulfilment';
COMMENT ON COLUMN policy_details_fulfilments.serial_id
IS 'Serial-ID of the corresponding policy_detail';
CREATE TABLE IF NOT EXISTS policy_details_fulfilments_default
PARTITION OF policy_details_fulfilments
FOR VALUES WITH (MODULUS 1, REMAINDER 0);
-- ------------------------------ deposits ---------------------------------------- -- ------------------------------ deposits ----------------------------------------
SELECT create_table_deposits(); SELECT create_table_deposits();

View File

@ -1442,7 +1442,6 @@ lrbt_cb_table_policy_details (void *cls,
for (unsigned int i = 0; i<num_results; i++) for (unsigned int i = 0; i<num_results; i++)
{ {
bool no_config = false; bool no_config = false;
bool no_fulfilment = false;
struct GNUNET_PQ_ResultSpec rs[] = { struct GNUNET_PQ_ResultSpec rs[] = {
GNUNET_PQ_result_spec_uint64 ("policy_details_serial_id", GNUNET_PQ_result_spec_uint64 ("policy_details_serial_id",
&td.serial), &td.serial),
@ -1454,11 +1453,12 @@ lrbt_cb_table_policy_details (void *cls,
&td.details.policy_details. &td.details.policy_details.
policy_options), policy_options),
&no_config), &no_config),
GNUNET_PQ_result_spec_allow_null ( GNUNET_PQ_result_spec_timestamp ("deadline",
GNUNET_PQ_result_spec_uint64 ("fulfilment_serial_id",
&td.details.policy_details. &td.details.policy_details.
fulfilment_serial_id), deadline),
&no_fulfilment), GNUNET_PQ_result_spec_uint64 ("fulfilment_state",
&td.details.policy_details.
fulfilment_state),
GNUNET_PQ_result_spec_end GNUNET_PQ_result_spec_end
}; };
@ -1500,7 +1500,7 @@ lrbt_cb_table_policy_fulfilments (void *cls,
bool no_config = false; bool no_config = false;
bool no_timestamp = false; bool no_timestamp = false;
struct GNUNET_PQ_ResultSpec rs[] = { struct GNUNET_PQ_ResultSpec rs[] = {
GNUNET_PQ_result_spec_uint64 ("policy_fulfilment_serial_id", GNUNET_PQ_result_spec_uint64 ("fulfilment_id",
&td.serial), &td.serial),
GNUNET_PQ_result_spec_allow_null ( GNUNET_PQ_result_spec_allow_null (
GNUNET_PQ_result_spec_string ("fulfilment_proof", GNUNET_PQ_result_spec_string ("fulfilment_proof",
@ -1531,6 +1531,52 @@ lrbt_cb_table_policy_fulfilments (void *cls,
} }
/**
* Function called with policy_details_fulfilments table entries.
*
* @param cls closure
* @param result the postgres result
* @param num_results the number of results in @a result
*/
static void
lrbt_cb_table_policy_details_fulfilments (void *cls,
PGresult *result,
unsigned int num_results)
{
struct LookupRecordsByTableContext *ctx = cls;
struct TALER_EXCHANGEDB_TableData td = {
.table = TALER_EXCHANGEDB_RT_POLICY_DETAILS_FULFILMENTS
};
for (unsigned int i = 0; i<num_results; i++)
{
struct GNUNET_PQ_ResultSpec rs[] = {
GNUNET_PQ_result_spec_uint64 ("fulfilment_id",
&td.details.policy_details_fulfilments.
fulfilment_id),
GNUNET_PQ_result_spec_auto_from_type ("serial_id",
&td.details.
policy_details_fulfilments.
serial_id),
GNUNET_PQ_result_spec_end
};
if (GNUNET_OK !=
GNUNET_PQ_extract_result (result,
rs,
i))
{
GNUNET_break (0);
ctx->error = true;
return;
}
ctx->cb (ctx->cb_cls,
&td);
GNUNET_PQ_cleanup_result (rs);
}
}
/** /**
* Function called with purse_requests table entries. * Function called with purse_requests table entries.
* *

View File

@ -3932,19 +3932,28 @@ prepare_statements (struct PostgresClosure *pg)
"(policy_details_serial_id" "(policy_details_serial_id"
",serial_id" ",serial_id"
",policy_options" ",policy_options"
",fulfilment_serial_id" ",deadline"
",fulfilment_state"
") VALUES " ") VALUES "
"($1, $2, $3, $4);", "($1, $2, $3, $4, $5);",
4), 5),
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"
"(policy_fulfilments_serial_id" "(fulfilment_id"
",fulfilment_timestamp" ",fulfilment_timestamp"
",fulfilment_proof" ",fulfilment_proof"
") VALUES " ") VALUES "
"($1, $2, $3);", "($1, $2, $3);",
3), 3),
GNUNET_PQ_make_prepare (
"insert_into_table_policy_details_fulfilments",
"INSERT INTO policy_details_fulfilments"
"(fulfilment_id"
",serial_id"
") VALUES "
"($1, $2);",
2),
GNUNET_PQ_make_prepare ( GNUNET_PQ_make_prepare (
"insert_into_table_purse_requests", "insert_into_table_purse_requests",
"INSERT INTO purse_requests" "INSERT INTO purse_requests"
@ -6273,16 +6282,16 @@ postgres_do_deposit (
GNUNET_PQ_query_param_auto_from_type (&deposit->coin.coin_pub), GNUNET_PQ_query_param_auto_from_type (&deposit->coin.coin_pub),
GNUNET_PQ_query_param_auto_from_type (&deposit->csig), GNUNET_PQ_query_param_auto_from_type (&deposit->csig),
GNUNET_PQ_query_param_uint64 (&deposit_shard), GNUNET_PQ_query_param_uint64 (&deposit_shard),
GNUNET_PQ_query_param_bool (! deposit->no_policy_details), GNUNET_PQ_query_param_bool (deposit->has_policy_details),
(deposit->no_policy_details) (deposit->has_policy_details)
? GNUNET_PQ_query_param_null () ? TALER_PQ_query_param_json (deposit->policy_details)
: TALER_PQ_query_param_json (deposit->policy_details), : GNUNET_PQ_query_param_null (),
(deposit->no_policy_details) (deposit->has_policy_details)
? GNUNET_PQ_query_param_null () ? GNUNET_PQ_query_param_auto_from_type (&deposit->policy_serial_id)
: GNUNET_PQ_query_param_auto_from_type (&deposit->policy_serial_id), : GNUNET_PQ_query_param_null (),
(deposit->no_policy_details) (deposit->has_policy_details)
? GNUNET_PQ_query_param_null () ? 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_end GNUNET_PQ_query_param_end
}; };
struct GNUNET_PQ_ResultSpec rs[] = { struct GNUNET_PQ_ResultSpec rs[] = {

View File

@ -512,6 +512,8 @@ CREATE OR REPLACE FUNCTION exchange_do_deposit(
IN in_shard INT8, IN in_shard INT8,
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_deadline INT8,
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)
@ -530,9 +532,15 @@ BEGIN
IF NOT NULL in_policy_details IF NOT NULL in_policy_details
THEN THEN
INSERT INTO exchange.policy_details INSERT INTO exchange.policy_details
(policy_options) (serial_id
,policy_options
,deadline
,fulfilment_state)
VALUES VALUES
(in_policy_details) (in_policy_serial_id
,in_policy_details
,in_policy_deadline
,'pending')
RETURNING policy_details_serial_id INTO xdi; RETURNING policy_details_serial_id INTO xdi;
ELSE ELSE
xdi=NULL; xdi=NULL;

View File

@ -1500,7 +1500,6 @@ run (void *cls)
&deposit, &deposit,
known_coin_id, known_coin_id,
&h_payto, &h_payto,
false,
&deposit_timestamp, &deposit_timestamp,
&balance_ok, &balance_ok,
&in_conflict)); &in_conflict));

View File

@ -354,15 +354,16 @@ TALER_extensions_load_manifests (
enum GNUNET_GenericReturnValue enum GNUNET_GenericReturnValue
TALER_extensions_from_policy_details ( TALER_extensions_serial_from_policy_details (
const json_t *policy_details, const json_t *policy_details,
const struct TALER_Extension **extension, struct GNUNET_HashCode *serial,
struct GNUNET_TIME_Timestamp *deadline,
const char **error_hint) const char **error_hint)
{ {
const struct TALER_Extension *extension;
const json_t *jtype; const json_t *jtype;
const char *type; const char *type;
*extension = NULL;
*error_hint = NULL; *error_hint = NULL;
if ((NULL == policy_details) || if ((NULL == policy_details) ||
@ -386,19 +387,23 @@ TALER_extensions_from_policy_details (
return GNUNET_SYSERR; return GNUNET_SYSERR;
} }
*extension = TALER_extensions_get_by_name (type); extension = TALER_extensions_get_by_name (type);
if ((NULL == *extension) || if ((NULL == extension) ||
(NULL == (*extension)->parse_policy_details)) (NULL == extension->parse_policy_details))
{ {
GNUNET_break (0); GNUNET_break (0);
GNUNET_log (GNUNET_ERROR_TYPE_WARNING, GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
"Unsupported extension policy '%s' requested\n", "Unsupported extension policy '%s' requested\n",
type); type);
*extension = NULL;
return GNUNET_NO; return GNUNET_NO;
} }
return GNUNET_OK; *deadline = GNUNET_TIME_UNIT_FOREVER_TS;
return extension->parse_policy_details (policy_details,
serial,
deadline,
error_hint);
} }

View File

@ -223,6 +223,7 @@ enum TALER_EXCHANGEDB_ReplicatedTable
TALER_EXCHANGEDB_RT_EXTENSIONS, TALER_EXCHANGEDB_RT_EXTENSIONS,
TALER_EXCHANGEDB_RT_POLICY_DETAILS, TALER_EXCHANGEDB_RT_POLICY_DETAILS,
TALER_EXCHANGEDB_RT_POLICY_FULFILMENTS, TALER_EXCHANGEDB_RT_POLICY_FULFILMENTS,
TALER_EXCHANGEDB_RT_POLICY_DETAILS_FULFILMENTS,
TALER_EXCHANGEDB_RT_PURSE_REQUESTS, TALER_EXCHANGEDB_RT_PURSE_REQUESTS,
TALER_EXCHANGEDB_RT_PURSE_REFUNDS, TALER_EXCHANGEDB_RT_PURSE_REFUNDS,
TALER_EXCHANGEDB_RT_PURSE_MERGES, TALER_EXCHANGEDB_RT_PURSE_MERGES,
@ -530,9 +531,15 @@ 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_serial_id; uint64_t fulfilment_state;
} policy_details; } policy_details;
struct
{
struct GNUNET_HashCode serial_id;
uint64_t fulfilment_id;
} policy_details_fulfilments;
struct struct
{ {
char *fulfilment_proof; char *fulfilment_proof;
@ -1442,23 +1449,25 @@ struct TALER_EXCHANGEDB_Deposit
* deposit operation, possibly NULL! * deposit operation, possibly NULL!
*/ */
json_t *policy_details; json_t *policy_details;
bool no_policy_details; bool has_policy_details;
/** /**
* If policy_details are present, the corresponding policy extension calculates * If policy_details are present, the corresponding policy extension
* a serial id under which the policy_details shall be stored in the policy_details table. * calculates a serial id under which the policy_details shall be stored in
* the policy_details table.
*/ */
struct GNUNET_HashCode policy_serial_id; struct GNUNET_HashCode policy_serial_id;
/** /**
* If policy_details are present, the corresponding policy extension can * If policy_details are present, the corresponding policy extension can set
* set a deadline for this policy. Can be "forever". * a deadline for this policy. Can be "forever".
*/ */
struct GNUNET_TIME_Timestamp policy_deadline; struct GNUNET_TIME_Timestamp policy_deadline;
/** /**
* Hash over the @e policy_details. Only filled if no_policy_details is false. * Hash over the @e policy_details. Only filled if has_policy_details is
* true.
*/ */
struct TALER_ExtensionPolicyHashP h_policy; struct TALER_ExtensionPolicyHashP h_policy;

View File

@ -390,16 +390,18 @@ TALER_extensions_get_age_restriction_mask ();
* @brief Finds the extension for a given policy * @brief Finds the extension for a given policy
* *
* @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] extension On GNUNET_OK, the exentions handling the given policy * @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] 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_from_policy_details ( TALER_extensions_serial_from_policy_details (
const json_t *policy_details, const json_t *policy_details,
const struct TALER_Extension **extension, struct GNUNET_HashCode *serial,
struct GNUNET_TIME_Timestamp *deadline,
const char **error_hint); const char **error_hint);
/* /*