WiP: age-withdraw, finished reveal-request, 10/n

- /age-withdraw/$ACH/reveal handler now fully implemented
- for consistency with api: rename of tables from withdraw_age_... to
  age_withdraw
This commit is contained in:
Özgür Kesim 2023-05-01 14:05:58 +02:00
parent af3c92f9d5
commit 1a63275d98
Signed by: oec
GPG Key ID: 3D76A56D79EDD9D7
12 changed files with 304 additions and 163 deletions

View File

@ -22,6 +22,8 @@
#include <gnunet/gnunet_util_lib.h> #include <gnunet/gnunet_util_lib.h>
#include <jansson.h> #include <jansson.h>
#include <microhttpd.h> #include <microhttpd.h>
#include "taler-exchange-httpd_metrics.h"
#include "taler_exchangedb_plugin.h"
#include "taler_mhd_lib.h" #include "taler_mhd_lib.h"
#include "taler-exchange-httpd_mhd.h" #include "taler-exchange-httpd_mhd.h"
#include "taler-exchange-httpd_age-withdraw_reveal.h" #include "taler-exchange-httpd_age-withdraw_reveal.h"
@ -387,12 +389,10 @@ denomination_is_valid (
struct TEH_DenominationKey *dks, struct TEH_DenominationKey *dks,
MHD_RESULT *result) MHD_RESULT *result)
{ {
dks = TEH_keys_denomination_by_hash2 ( dks = TEH_keys_denomination_by_hash2 (ksh,
ksh,
denom_h, denom_h,
connection, connection,
result); result);
if (NULL == dks) if (NULL == dks)
{ {
/* The denomination doesn't exist */ /* The denomination doesn't exist */
@ -784,6 +784,43 @@ verify_commitment_and_max_age (
} }
/**
* @brief Send a response for "/age-withdraw/$RCH/reveal"
*
* @param connection The http connection to the client to send the reponse to
* @param num_coins Number of new coins with age restriction for which we reveal data
* @param awrcs array of @a num_coins signatures revealed
* @return a MHD result code
*/
static MHD_RESULT
reply_age_withdraw_reveal_success (
struct MHD_Connection *connection,
unsigned int num_coins,
const struct TALER_EXCHANGEDB_AgeWithdrawRevealedCoin *awrcs)
{
json_t *list = json_array ();
GNUNET_assert (NULL != list);
for (unsigned int index = 0;
index < num_coins;
index++)
{
json_t *obj = GNUNET_JSON_PACK (
TALER_JSON_pack_blinded_denom_sig ("ev_sig",
&awrcs[index].coin_sig));
GNUNET_assert (0 ==
json_array_append_new (list,
obj));
}
return TALER_MHD_REPLY_JSON_PACK (
connection,
MHD_HTTP_OK,
GNUNET_JSON_pack_array_steal ("ev_sigs",
list));
}
/** /**
* @brief Signs and persists the undisclosed coins * @brief Signs and persists the undisclosed coins
* *
@ -796,7 +833,7 @@ verify_commitment_and_max_age (
* @return GNUNET_OK on success, GNUNET_SYSERR otherwise * @return GNUNET_OK on success, GNUNET_SYSERR otherwise
*/ */
static enum GNUNET_GenericReturnValue static enum GNUNET_GenericReturnValue
finalize_age_withdraw_and_sign ( sign_and_finalize_age_withdraw (
struct MHD_Connection *connection, struct MHD_Connection *connection,
const struct TALER_AgeWithdrawCommitmentHashP *h_commitment, const struct TALER_AgeWithdrawCommitmentHashP *h_commitment,
const uint32_t num_coins, const uint32_t num_coins,
@ -806,7 +843,9 @@ finalize_age_withdraw_and_sign (
{ {
enum GNUNET_GenericReturnValue ret = GNUNET_SYSERR; enum GNUNET_GenericReturnValue ret = GNUNET_SYSERR;
struct TEH_CoinSignData csds[num_coins]; struct TEH_CoinSignData csds[num_coins];
struct TALER_BlindedDenominationSignature bss[num_coins]; struct TALER_BlindedDenominationSignature bds[num_coins];
struct TALER_EXCHANGEDB_AgeWithdrawRevealedCoin awrcs[num_coins];
enum GNUNET_DB_QueryStatus qs;
for (uint32_t i = 0; i<num_coins; i++) for (uint32_t i = 0; i<num_coins; i++)
{ {
@ -814,13 +853,13 @@ finalize_age_withdraw_and_sign (
csds[i].bp = &coin_evs[i]; csds[i].bp = &coin_evs[i];
} }
/* First, sign the the blinded coins */ /* Sign the the blinded coins first */
{ {
enum TALER_ErrorCode ec; enum TALER_ErrorCode ec;
ec = TEH_keys_denomination_batch_sign (csds, ec = TEH_keys_denomination_batch_sign (csds,
num_coins, num_coins,
false, false,
bss); bds);
if (TALER_EC_NONE != ec) if (TALER_EC_NONE != ec)
{ {
GNUNET_break (0); GNUNET_break (0);
@ -831,12 +870,104 @@ finalize_age_withdraw_and_sign (
} }
} }
/* TODO[oec]: GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
* - in a transaction: save the coins. "Signatures ready, starting DB interaction\n");
* - add signature response
*/
#pragma message "FIXME[oec]: implement finalize_age_withdraw_and_sign" /* Prepare the data for insertion */
for (uint32_t i = 0; i<num_coins; i++)
{
TALER_coin_ev_hash (&coin_evs[i],
csds[i].h_denom_pub,
&awrcs[i].h_coin_ev);
awrcs[i].h_denom_pub = *csds[i].h_denom_pub;
awrcs[i].coin_sig = bds[i];
}
/* Persist operation result in DB, transactionally */
for (unsigned int r = 0; r < MAX_TRANSACTION_COMMIT_RETRIES; r++)
{
bool changed = false;
/* Transaction start */
if (GNUNET_OK !=
TEH_plugin->start (TEH_plugin->cls,
"insert_age_withdraw_reveal batch"))
{
GNUNET_break (0);
ret = TALER_MHD_reply_with_error (connection,
MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_GENERIC_DB_START_FAILED,
NULL);
goto cleanup;
}
qs = TEH_plugin->insert_age_withdraw_reveal (TEH_plugin->cls,
h_commitment,
num_coins,
awrcs);
if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
{
TEH_plugin->rollback (TEH_plugin->cls);
continue;
}
else if (GNUNET_DB_STATUS_HARD_ERROR == qs)
{
GNUNET_break (0);
TEH_plugin->rollback (TEH_plugin->cls);
ret = TALER_MHD_reply_with_error (connection,
MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_GENERIC_DB_STORE_FAILED,
"insert_age_withdraw_reveal");
goto cleanup;
}
changed = (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs);
/* Commit the transaction */
qs = TEH_plugin->commit (TEH_plugin->cls);
if (qs >= 0)
{
if (changed)
TEH_METRICS_num_success[TEH_MT_SUCCESS_AGE_WITHDRAW_REVEAL]++;
break; /* success */
}
else if (GNUNET_DB_STATUS_HARD_ERROR == qs)
{
GNUNET_break (0);
TEH_plugin->rollback (TEH_plugin->cls);
ret = TALER_MHD_reply_with_error (connection,
MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_GENERIC_DB_COMMIT_FAILED,
NULL);
goto cleanup;
}
else
{
TEH_plugin->rollback (TEH_plugin->cls);
}
} /* end of retry */
if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
{
GNUNET_break (0);
TEH_plugin->rollback (TEH_plugin->cls);
ret = TALER_MHD_reply_with_error (connection,
MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_GENERIC_DB_SOFT_FAILURE,
NULL);
goto cleanup;
}
/* Generate final (positive) response */
ret = reply_age_withdraw_reveal_success (connection,
num_coins,
awrcs);
cleanup:
// TODO[oec]: handle error cases
// TODO[oec]: cleanup!
return ret; return ret;
} }
@ -922,7 +1053,7 @@ TEH_handler_age_withdraw_reveal (
break; break;
/* Finally, sign and persist the coins */ /* Finally, sign and persist the coins */
if (GNUNET_OK != finalize_age_withdraw_and_sign ( if (GNUNET_OK != sign_and_finalize_age_withdraw (
rc->connection, rc->connection,
&actx.commitment.h_commitment, &actx.commitment.h_commitment,
actx.num_coins, actx.num_coins,

View File

@ -61,7 +61,8 @@ enum TEH_MetricTypeSuccess
TEH_MT_SUCCESS_BATCH_WITHDRAW = 3, TEH_MT_SUCCESS_BATCH_WITHDRAW = 3,
TEH_MT_SUCCESS_MELT = 4, TEH_MT_SUCCESS_MELT = 4,
TEH_MT_SUCCESS_REFRESH_REVEAL = 5, TEH_MT_SUCCESS_REFRESH_REVEAL = 5,
TEH_MT_SUCCESS_COUNT = 6 /* MUST BE LAST! */ TEH_MT_SUCCESS_AGE_WITHDRAW_REVEAL = 6,
TEH_MT_SUCCESS_COUNT = 7 /* MUST BE LAST! */
}; };
/** /**

View File

@ -773,12 +773,17 @@ clean_age:
NULL); NULL);
goto cleanup; goto cleanup;
} }
for (unsigned int i = 0; i<rctx->num_fresh_coins; i++) for (unsigned int i = 0; i<rctx->num_fresh_coins; i++)
{
rrcs[i].coin_sig = bss[i]; rrcs[i].coin_sig = bss[i];
rrcs[i].blinded_planchet = rcds[i].blinded_planchet;
}
} }
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Signatures ready, starting DB interaction\n"); "Signatures ready, starting DB interaction\n");
for (unsigned int r = 0; r<MAX_TRANSACTION_COMMIT_RETRIES; r++) for (unsigned int r = 0; r<MAX_TRANSACTION_COMMIT_RETRIES; r++)
{ {
bool changed; bool changed;
@ -795,12 +800,7 @@ clean_age:
NULL); NULL);
goto cleanup; goto cleanup;
} }
for (unsigned int i = 0; i<rctx->num_fresh_coins; i++)
{
struct TALER_EXCHANGEDB_RefreshRevealedCoin *rrc = &rrcs[i];
rrc->blinded_planchet = rcds[i].blinded_planchet;
}
qs = TEH_plugin->insert_refresh_reveal ( qs = TEH_plugin->insert_refresh_reveal (
TEH_plugin->cls, TEH_plugin->cls,
melt_serial_id, melt_serial_id,

View File

@ -14,24 +14,24 @@
-- 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/>
-- --
CREATE FUNCTION create_table_withdraw_age_commitments( CREATE FUNCTION create_table_age_withdraw_commitments(
IN partition_suffix VARCHAR DEFAULT NULL IN partition_suffix VARCHAR DEFAULT NULL
) )
RETURNS VOID RETURNS VOID
LANGUAGE plpgsql LANGUAGE plpgsql
AS $$ AS $$
DECLARE DECLARE
table_name VARCHAR DEFAULT 'withdraw_age_commitments'; table_name VARCHAR DEFAULT 'age_withdraw_commitments';
BEGIN BEGIN
PERFORM create_partitioned_table( PERFORM create_partitioned_table(
'CREATE TABLE %I' 'CREATE TABLE %I'
'(withdraw_age_commitment_id BIGINT GENERATED BY DEFAULT AS IDENTITY' '(age_withdraw_commitment_id BIGINT GENERATED BY DEFAULT AS IDENTITY'
',h_commitment BYTEA PRIMARY KEY CHECK (LENGTH(h_commitment)=64)' ',h_commitment BYTEA CHECK (LENGTH(h_commitment)=64)'
',amount_with_fee_val INT8 NOT NULL' ',amount_with_fee_val INT8 NOT NULL'
',amount_with_fee_frac INT4 NOT NULL' ',amount_with_fee_frac INT4 NOT NULL'
',max_age INT2 NOT NULL' ',max_age INT2 NOT NULL'
',reserve_pub BYTEA NOT NULL CHECK (LENGTH(reserve_pub)=32)' ',reserve_pub BYTEA CHECK (LENGTH(reserve_pub)=32)'
',reserve_sig BYTEA CHECK (LENGTH(reserve_sig)=64)' ',reserve_sig BYTEA NOT NULL CHECK (LENGTH(reserve_sig)=64)'
',noreveal_index INT4 NOT NULL' ',noreveal_index INT4 NOT NULL'
') %s ;' ') %s ;'
,table_name ,table_name
@ -77,36 +77,40 @@ END
$$; $$;
CREATE FUNCTION constrain_table_withdraw_age_commitments( CREATE FUNCTION constrain_table_age_withdraw_commitments(
IN partition_suffix VARCHAR IN partition_suffix VARCHAR
) )
RETURNS void RETURNS void
LANGUAGE plpgsql LANGUAGE plpgsql
AS $$ AS $$
DECLARE DECLARE
table_name VARCHAR DEFAULT 'withdraw_age_commitments'; table_name VARCHAR DEFAULT 'age_withdraw_commitments';
BEGIN BEGIN
table_name = concat_ws('_', table_name, partition_suffix); table_name = concat_ws('_', table_name, partition_suffix);
EXECUTE FORMAT ( EXECUTE FORMAT (
'ALTER TABLE ' || table_name || 'ALTER TABLE ' || table_name ||
' ADD PRIMARY KEY (h_commitment, reserve_pub);' ' ADD PRIMARY KEY (h_commitment);'
); );
EXECUTE FORMAT ( EXECUTE FORMAT (
'ALTER TABLE ' || table_name || 'ALTER TABLE ' || table_name ||
' ADD CONSTRAINT ' || table_name || '_withdraw_age_commitment_id_key' ' ADD CONSTRAINT ' || table_name || '_h_commitment_reserve_pub_key'
' UNIQUE (withdraw_age_commitment_id);' ' UNIQUE (h_commitment, reserve_pub);'
);
EXECUTE FORMAT (
'ALTER TABLE ' || table_name ||
' ADD CONSTRAINT ' || table_name || '_age_withdraw_commitment_id_key'
' UNIQUE (age_withdraw_commitment_id);'
); );
END END
$$; $$;
CREATE FUNCTION foreign_table_withdraw_age_commitments() CREATE FUNCTION foreign_table_age_withdraw_commitments()
RETURNS void RETURNS void
LANGUAGE plpgsql LANGUAGE plpgsql
AS $$ AS $$
DECLARE DECLARE
table_name VARCHAR DEFAULT 'withdraw_age_commitments'; table_name VARCHAR DEFAULT 'age_withdraw_commitments';
BEGIN BEGIN
EXECUTE FORMAT ( EXECUTE FORMAT (
'ALTER TABLE ' || table_name || 'ALTER TABLE ' || table_name ||
@ -125,18 +129,6 @@ INSERT INTO exchange_tables
,partitioned ,partitioned
,by_range) ,by_range)
VALUES VALUES
('withdraw_age_commitments' ('age_withdraw_commitments', 'exchange-0003', 'create', TRUE ,FALSE),
,'exchange-0003' ('age_withdraw_commitments', 'exchange-0003', 'constrain',TRUE ,FALSE),
,'create' ('age_withdraw_commitments', 'exchange-0003', 'foreign', TRUE ,FALSE);
,TRUE
,FALSE),
('withdraw_age_commitments'
,'exchange-0003'
,'constrain'
,TRUE
,FALSE),
('withdraw_age_commitments'
,'exchange-0003'
,'foreign'
,TRUE
,FALSE);

View File

@ -14,25 +14,24 @@
-- 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/>
-- --
CREATE FUNCTION create_table_withdraw_age_revealed_coins( CREATE FUNCTION create_table_age_withdraw_revealed_coins(
IN partition_suffix VARCHAR DEFAULT NULL IN partition_suffix VARCHAR DEFAULT NULL
) )
RETURNS VOID RETURNS VOID
LANGUAGE plpgsql LANGUAGE plpgsql
AS $$ AS $$
DECLARE DECLARE
table_name VARCHAR DEFAULT 'withdraw_age_revealed_coins'; table_name VARCHAR DEFAULT 'age_withdraw_revealed_coins';
BEGIN BEGIN
PERFORM create_partitioned_table( PERFORM create_partitioned_table(
'CREATE TABLE %I' 'CREATE TABLE %I'
'(withdraw_age_revealed_coins_id BIGINT GENERATED BY DEFAULT AS IDENTITY' -- UNIQUE '(age_withdraw_revealed_coins_id BIGINT GENERATED BY DEFAULT AS IDENTITY' -- UNIQUE
',h_commitment BYTEA NOT NULL CHECK (LENGTH(h_commitment)=64)' ',h_commitment BYTEA NOT NULL CHECK (LENGTH(h_commitment)=64)'
',freshcoin_index INT4 NOT NULL' ',freshcoin_index INT4 NOT NULL'
',denominations_serial INT8 NOT NULL' ',denominations_serial INT8 NOT NULL'
',coin_ev BYTEA NOT NULL' ',coin_ev BYTEA NOT NULL'
',h_coin_ev BYTEA CHECK (LENGTH(h_coin_ev)=64)' ',h_coin_ev BYTEA CHECK (LENGTH(h_coin_ev)=64)'
',ev_sig BYTEA NOT NULL' ',ev_sig BYTEA NOT NULL'
',ewv BYTEA NOT NULL'
') %s ;' ') %s ;'
,table_name ,table_name
,'PARTITION BY HASH (h_commitment)' ,'PARTITION BY HASH (h_commitment)'
@ -79,30 +78,24 @@ BEGIN
,table_name ,table_name
,partition_suffix ,partition_suffix
); );
PERFORM comment_partitioned_column(
'Exchange contributed values in the creation of the fresh coin (see /csr)'
,'ewv'
,table_name
,partition_suffix
);
END END
$$; $$;
CREATE FUNCTION constrain_table_withdraw_age_revealed_coins( CREATE FUNCTION constrain_table_age_withdraw_revealed_coins(
IN partition_suffix VARCHAR IN partition_suffix VARCHAR
) )
RETURNS void RETURNS void
LANGUAGE plpgsql LANGUAGE plpgsql
AS $$ AS $$
DECLARE DECLARE
table_name VARCHAR DEFAULT 'withdraw_age_revealed_coins'; table_name VARCHAR DEFAULT 'age_withdraw_revealed_coins';
BEGIN BEGIN
table_name = concat_ws('_', table_name, partition_suffix); table_name = concat_ws('_', table_name, partition_suffix);
EXECUTE FORMAT ( EXECUTE FORMAT (
'ALTER TABLE ' || table_name || 'ALTER TABLE ' || table_name ||
' ADD CONSTRAINT ' || table_name || '_withdraw_age_revealed_coins_id_key' ' ADD CONSTRAINT ' || table_name || '_age_withdraw_revealed_coins_id_key'
' UNIQUE (withdraw_age_revealed_coins_id);' ' UNIQUE (age_withdraw_revealed_coins_id);'
); );
EXECUTE FORMAT ( EXECUTE FORMAT (
'ALTER TABLE ' || table_name || 'ALTER TABLE ' || table_name ||
@ -112,18 +105,18 @@ BEGIN
END END
$$; $$;
CREATE FUNCTION foreign_table_withdraw_age_revealed_coins() CREATE FUNCTION foreign_table_age_withdraw_revealed_coins()
RETURNS void RETURNS void
LANGUAGE plpgsql LANGUAGE plpgsql
AS $$ AS $$
DECLARE DECLARE
table_name VARCHAR DEFAULT 'withdraw_age_revealed_coins'; table_name VARCHAR DEFAULT 'age_withdraw_revealed_coins';
BEGIN BEGIN
EXECUTE FORMAT ( EXECUTE FORMAT (
'ALTER TABLE ' || table_name || 'ALTER TABLE ' || table_name ||
' ADD CONSTRAINT ' || table_name || '_foreign_h_commitment' ' ADD CONSTRAINT ' || table_name || '_foreign_h_commitment'
' FOREIGN KEY (h_commitment)' ' FOREIGN KEY (h_commitment)'
' REFERENCES withdraw_age_commitments (h_commitment) ON DELETE CASCADE;' ' REFERENCES age_withdraw_commitments (h_commitment) ON DELETE CASCADE;'
); );
EXECUTE FORMAT ( EXECUTE FORMAT (
'ALTER TABLE ' || table_name || 'ALTER TABLE ' || table_name ||
@ -142,17 +135,17 @@ INSERT INTO exchange_tables
,partitioned ,partitioned
,by_range) ,by_range)
VALUES VALUES
('withdraw_age_revealed_coins' ('age_withdraw_revealed_coins'
,'exchange-0003' ,'exchange-0003'
,'create' ,'create'
,TRUE ,TRUE
,FALSE), ,FALSE),
('withdraw_age_revealed_coins' ('age_withdraw_revealed_coins'
,'exchange-0003' ,'exchange-0003'
,'constrain' ,'constrain'
,TRUE ,TRUE
,FALSE), ,FALSE),
('withdraw_age_revealed_coins' ('age_withdraw_revealed_coins'
,'exchange-0003' ,'exchange-0003'
,'foreign' ,'foreign'
,TRUE ,TRUE

View File

@ -25,6 +25,8 @@ SET search_path TO exchange;
#include "0003-aml_status.sql" #include "0003-aml_status.sql"
#include "0003-aml_staff.sql" #include "0003-aml_staff.sql"
#include "0003-aml_history.sql" #include "0003-aml_history.sql"
#include "0003-age_withdraw_commitments.sql"
#include "0003-age_withdraw_reveals.sql"
COMMIT; COMMIT;

View File

@ -69,7 +69,7 @@ TEH_PG_get_age_withdraw_info (
",amount_with_fee_val" ",amount_with_fee_val"
",amount_with_fee_frac" ",amount_with_fee_frac"
",noreveal_index" ",noreveal_index"
" FROM withdraw_age_commitments" " FROM age_withdraw_commitments"
" WHERE reserve_pub=$1 and h_commitment=$2;"); " WHERE reserve_pub=$1 and h_commitment=$2;");
return GNUNET_PQ_eval_prepared_singleton_select (pg->conn, return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
"get_age_withdraw_info", "get_age_withdraw_info",

View File

@ -42,8 +42,8 @@ TEH_PG_insert_age_withdraw_reveal (
/* TODO */ /* TODO */
#if 0 #if 0
PREPARE (pg, PREPARE (pg,
"insert_withdraw_age_revealed_coin", "insert_age_withdraw_revealed_coin",
"INSERT INTO withdraw_age_reveals " "INSERT INTO age_withdraw_reveals "
"(h_commitment " "(h_commitment "
",freshcoin_index " ",freshcoin_index "
",denominations_serial " ",denominations_serial "

View File

@ -2062,39 +2062,39 @@ irbt_cb_table_purse_deletion (struct PostgresClosure *pg,
/** /**
* Function called with withdraw_age_commitments records to insert into table. * Function called with age_withdraw_commitments records to insert into table.
* *
* @param pg plugin context * @param pg plugin context
* @param td record to insert * @param td record to insert
*/ */
static enum GNUNET_DB_QueryStatus static enum GNUNET_DB_QueryStatus
irbt_cb_table_withdraw_age_commitments (struct PostgresClosure *pg, irbt_cb_table_age_withdraw_commitments (struct PostgresClosure *pg,
const struct const struct
TALER_EXCHANGEDB_TableData *td) TALER_EXCHANGEDB_TableData *td)
{ {
struct GNUNET_PQ_QueryParam params[] = { struct GNUNET_PQ_QueryParam params[] = {
GNUNET_PQ_query_param_uint64 (&td->serial), GNUNET_PQ_query_param_uint64 (&td->serial),
GNUNET_PQ_query_param_auto_from_type ( GNUNET_PQ_query_param_auto_from_type (
&td->details.withdraw_age_commitments.h_commitment), &td->details.age_withdraw_commitments.h_commitment),
TALER_PQ_query_param_amount ( TALER_PQ_query_param_amount (
&td->details.withdraw_age_commitments.amount_with_fee), &td->details.age_withdraw_commitments.amount_with_fee),
GNUNET_PQ_query_param_uint16 ( GNUNET_PQ_query_param_uint16 (
&td->details.withdraw_age_commitments.max_age), &td->details.age_withdraw_commitments.max_age),
GNUNET_PQ_query_param_auto_from_type ( GNUNET_PQ_query_param_auto_from_type (
&td->details.withdraw_age_commitments.reserve_pub), &td->details.age_withdraw_commitments.reserve_pub),
GNUNET_PQ_query_param_auto_from_type ( GNUNET_PQ_query_param_auto_from_type (
&td->details.withdraw_age_commitments.reserve_sig), &td->details.age_withdraw_commitments.reserve_sig),
GNUNET_PQ_query_param_uint32 ( GNUNET_PQ_query_param_uint32 (
&td->details.withdraw_age_commitments.noreveal_index), &td->details.age_withdraw_commitments.noreveal_index),
GNUNET_PQ_query_param_absolute_time ( GNUNET_PQ_query_param_absolute_time (
&td->details.withdraw_age_commitments.timestamp), &td->details.age_withdraw_commitments.timestamp),
GNUNET_PQ_query_param_end GNUNET_PQ_query_param_end
}; };
PREPARE (pg, PREPARE (pg,
"insert_into_table_withdraw_age_commitments", "insert_into_table_age_withdraw_commitments",
"INSERT INTO withdraw_age_commitments" "INSERT INTO age_withdraw_commitments"
"(withdraw_age_commitment_id" "(age_withdraw_commitment_id"
",h_commitment" ",h_commitment"
",amount_with_fee_val" ",amount_with_fee_val"
",amount_with_fee_frac" ",amount_with_fee_frac"
@ -2106,19 +2106,19 @@ irbt_cb_table_withdraw_age_commitments (struct PostgresClosure *pg,
") VALUES " ") VALUES "
"($1, $2, $3, $4, $5, $6, $7, $8, $9);"); "($1, $2, $3, $4, $5, $6, $7, $8, $9);");
return GNUNET_PQ_eval_prepared_non_select (pg->conn, return GNUNET_PQ_eval_prepared_non_select (pg->conn,
"insert_into_table_withdraw_age_commitments", "insert_into_table_age_withdraw_commitments",
params); params);
} }
/** /**
* Function called with withdraw_age_revealed_coins records to insert into table. * Function called with age_withdraw_revealed_coins records to insert into table.
* *
* @param pg plugin context * @param pg plugin context
* @param td record to insert * @param td record to insert
*/ */
static enum GNUNET_DB_QueryStatus static enum GNUNET_DB_QueryStatus
irbt_cb_table_withdraw_age_revealed_coins (struct PostgresClosure *pg, irbt_cb_table_age_withdraw_revealed_coins (struct PostgresClosure *pg,
const struct const struct
TALER_EXCHANGEDB_TableData *td) TALER_EXCHANGEDB_TableData *td)
{ {
@ -2126,26 +2126,26 @@ irbt_cb_table_withdraw_age_revealed_coins (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),
GNUNET_PQ_query_param_auto_from_type ( GNUNET_PQ_query_param_auto_from_type (
&td->details.withdraw_age_revealed_coins.h_commitment), &td->details.age_withdraw_revealed_coins.h_commitment),
GNUNET_PQ_query_param_uint32 ( GNUNET_PQ_query_param_uint32 (
&td->details.withdraw_age_revealed_coins.freshcoin_index), &td->details.age_withdraw_revealed_coins.freshcoin_index),
GNUNET_PQ_query_param_uint64 ( GNUNET_PQ_query_param_uint64 (
&td->details.withdraw_age_revealed_coins.denominations_serial), &td->details.age_withdraw_revealed_coins.denominations_serial),
GNUNET_PQ_query_param_fixed_size ( GNUNET_PQ_query_param_fixed_size (
td->details.withdraw_age_revealed_coins.coin_ev, td->details.age_withdraw_revealed_coins.coin_ev,
td->details.withdraw_age_revealed_coins.coin_ev_size), td->details.age_withdraw_revealed_coins.coin_ev_size),
GNUNET_PQ_query_param_auto_from_type (&h_coin_ev), GNUNET_PQ_query_param_auto_from_type (&h_coin_ev),
TALER_PQ_query_param_blinded_denom_sig ( TALER_PQ_query_param_blinded_denom_sig (
&td->details.withdraw_age_revealed_coins.ev_sig), &td->details.age_withdraw_revealed_coins.ev_sig),
TALER_PQ_query_param_exchange_withdraw_values ( TALER_PQ_query_param_exchange_withdraw_values (
&td->details.withdraw_age_revealed_coins.ewv), &td->details.age_withdraw_revealed_coins.ewv),
GNUNET_PQ_query_param_end GNUNET_PQ_query_param_end
}; };
PREPARE (pg, PREPARE (pg,
"insert_into_table_withdraw_age_revealed_coins", "insert_into_table_age_withdraw_revealed_coins",
"INSERT INTO withdraw_age_revealed_coins" "INSERT INTO age_withdraw_revealed_coins"
"(withdraw_age_revealed_coins_id" "(age_withdraw_revealed_coins_id"
",h_commitment" ",h_commitment"
",freshcoin_index" ",freshcoin_index"
",denominations_serial" ",denominations_serial"
@ -2156,12 +2156,12 @@ irbt_cb_table_withdraw_age_revealed_coins (struct PostgresClosure *pg,
") VALUES " ") VALUES "
"($1, $2, $3, $4, $5, $6, $7, $8);"); "($1, $2, $3, $4, $5, $6, $7, $8);");
GNUNET_CRYPTO_hash (td->details.withdraw_age_revealed_coins.coin_ev, GNUNET_CRYPTO_hash (td->details.age_withdraw_revealed_coins.coin_ev,
td->details.withdraw_age_revealed_coins.coin_ev_size, td->details.age_withdraw_revealed_coins.coin_ev_size,
&h_coin_ev); &h_coin_ev);
return GNUNET_PQ_eval_prepared_non_select (pg->conn, return GNUNET_PQ_eval_prepared_non_select (pg->conn,
"insert_into_table_withdraw_age_revealed_coins", "insert_into_table_age_withdraw_revealed_coins",
params); params);
} }
@ -2314,10 +2314,10 @@ TEH_PG_insert_records_by_table (void *cls,
rh = &irbt_cb_table_purse_deletion; rh = &irbt_cb_table_purse_deletion;
break; break;
case TALER_EXCHANGEDB_RT_WITHDRAW_AGE_COMMITMENTS: case TALER_EXCHANGEDB_RT_WITHDRAW_AGE_COMMITMENTS:
rh = &irbt_cb_table_withdraw_age_commitments; rh = &irbt_cb_table_age_withdraw_commitments;
break; break;
case TALER_EXCHANGEDB_RT_WITHDRAW_AGE_REVEALED_COINS: case TALER_EXCHANGEDB_RT_WITHDRAW_AGE_REVEALED_COINS:
rh = &irbt_cb_table_withdraw_age_revealed_coins; rh = &irbt_cb_table_age_withdraw_revealed_coins;
break; break;
} }
if (NULL == rh) if (NULL == rh)

View File

@ -2767,14 +2767,14 @@ lrbt_cb_table_purse_deletion (void *cls,
/** /**
* Function called with withdraw_age_commitments table entries. * Function called with age_withdraw_commitments table entries.
* *
* @param cls closure * @param cls closure
* @param result the postgres result * @param result the postgres result
* @param num_results the number of results in @a result * @param num_results the number of results in @a result
*/ */
static void static void
lrbt_cb_table_withdraw_age_commitments (void *cls, lrbt_cb_table_age_withdraw_commitments (void *cls,
PGresult *result, PGresult *result,
unsigned int num_results) unsigned int num_results)
{ {
@ -2788,26 +2788,26 @@ lrbt_cb_table_withdraw_age_commitments (void *cls,
{ {
struct GNUNET_PQ_ResultSpec rs[] = { struct GNUNET_PQ_ResultSpec rs[] = {
GNUNET_PQ_result_spec_uint64 ( GNUNET_PQ_result_spec_uint64 (
"withdraw_age_commitment_id", "age_withdraw_commitment_id",
&td.serial), &td.serial),
GNUNET_PQ_result_spec_auto_from_type ( GNUNET_PQ_result_spec_auto_from_type (
"h_commitment", "h_commitment",
&td.details.withdraw_age_commitments.h_commitment), &td.details.age_withdraw_commitments.h_commitment),
GNUNET_PQ_result_spec_uint16 ( GNUNET_PQ_result_spec_uint16 (
"max_age", "max_age",
&td.details.withdraw_age_commitments.max_age), &td.details.age_withdraw_commitments.max_age),
TALER_PQ_RESULT_SPEC_AMOUNT ( TALER_PQ_RESULT_SPEC_AMOUNT (
"amount_with_fee", "amount_with_fee",
&td.details.withdraw_age_commitments.amount_with_fee), &td.details.age_withdraw_commitments.amount_with_fee),
GNUNET_PQ_result_spec_auto_from_type ( GNUNET_PQ_result_spec_auto_from_type (
"reserve_pub", "reserve_pub",
&td.details.withdraw_age_commitments.reserve_pub), &td.details.age_withdraw_commitments.reserve_pub),
GNUNET_PQ_result_spec_auto_from_type ( GNUNET_PQ_result_spec_auto_from_type (
"reserve_sig", "reserve_sig",
&td.details.withdraw_age_commitments.reserve_sig), &td.details.age_withdraw_commitments.reserve_sig),
GNUNET_PQ_result_spec_uint32 ( GNUNET_PQ_result_spec_uint32 (
"noreveal_index", "noreveal_index",
&td.details.withdraw_age_commitments.noreveal_index), &td.details.age_withdraw_commitments.noreveal_index),
GNUNET_PQ_result_spec_end GNUNET_PQ_result_spec_end
}; };
@ -2828,14 +2828,14 @@ lrbt_cb_table_withdraw_age_commitments (void *cls,
/** /**
* Function called with withdraw_age_revealed_coins table entries. * Function called with age_withdraw_revealed_coins table entries.
* *
* @param cls closure * @param cls closure
* @param result the postgres result * @param result the postgres result
* @param num_results the number of results in @a result * @param num_results the number of results in @a result
*/ */
static void static void
lrbt_cb_table_withdraw_age_revealed_coins (void *cls, lrbt_cb_table_age_withdraw_revealed_coins (void *cls,
PGresult *result, PGresult *result,
unsigned int num_results) unsigned int num_results)
{ {
@ -2848,22 +2848,22 @@ lrbt_cb_table_withdraw_age_revealed_coins (void *cls,
{ {
struct GNUNET_PQ_ResultSpec rs[] = { struct GNUNET_PQ_ResultSpec rs[] = {
GNUNET_PQ_result_spec_uint64 ( GNUNET_PQ_result_spec_uint64 (
"withdraw_age_revealed_coins_id", "age_withdraw_revealed_coins_id",
&td.serial), &td.serial),
GNUNET_PQ_result_spec_auto_from_type ( GNUNET_PQ_result_spec_auto_from_type (
"h_commitment", "h_commitment",
&td.details.withdraw_age_revealed_coins.h_commitment), &td.details.age_withdraw_revealed_coins.h_commitment),
GNUNET_PQ_result_spec_uint32 ( GNUNET_PQ_result_spec_uint32 (
"freshcoin_index", "freshcoin_index",
&td.details.withdraw_age_revealed_coins.freshcoin_index), &td.details.age_withdraw_revealed_coins.freshcoin_index),
GNUNET_PQ_result_spec_uint64 ( GNUNET_PQ_result_spec_uint64 (
"denominations_serial", "denominations_serial",
&td.details.withdraw_age_revealed_coins.denominations_serial), &td.details.age_withdraw_revealed_coins.denominations_serial),
/* Note: h_coin_ev is recalculated */ /* Note: h_coin_ev is recalculated */
GNUNET_PQ_result_spec_variable_size ( GNUNET_PQ_result_spec_variable_size (
"coin_ev", "coin_ev",
(void **) &td.details.withdraw_age_revealed_coins.coin_ev, (void **) &td.details.age_withdraw_revealed_coins.coin_ev,
&td.details.withdraw_age_revealed_coins.coin_ev_size), &td.details.age_withdraw_revealed_coins.coin_ev_size),
TALER_PQ_result_spec_blinded_denom_sig ( TALER_PQ_result_spec_blinded_denom_sig (
"ev_sig", "ev_sig",
&td.details.refresh_revealed_coins.ev_sig), &td.details.refresh_revealed_coins.ev_sig),
@ -3598,9 +3598,9 @@ TEH_PG_lookup_records_by_table (void *cls,
rh = &lrbt_cb_table_purse_deletion; rh = &lrbt_cb_table_purse_deletion;
break; break;
case TALER_EXCHANGEDB_RT_WITHDRAW_AGE_COMMITMENTS: case TALER_EXCHANGEDB_RT_WITHDRAW_AGE_COMMITMENTS:
XPREPARE ("select_above_serial_by_table_withdraw_age_commitments", XPREPARE ("select_above_serial_by_table_age_withdraw_commitments",
"SELECT" "SELECT"
" withdraw_age_commitment_id" " age_withdraw_commitment_id"
",h_commitment" ",h_commitment"
",amount_with_fee_val" ",amount_with_fee_val"
",amount_with_fee_frac" ",amount_with_fee_frac"
@ -3608,15 +3608,15 @@ TEH_PG_lookup_records_by_table (void *cls,
",reserve_pub" ",reserve_pub"
",reserve_sig" ",reserve_sig"
",noreveal_index" ",noreveal_index"
" FROM withdraw_age_commitments" " FROM age_withdraw_commitments"
" WHERE withdraw_age_commitment_id > $1" " WHERE age_withdraw_commitment_id > $1"
" ORDER BY withdraw_age_commitment_id ASC;"); " ORDER BY age_withdraw_commitment_id ASC;");
rh = &lrbt_cb_table_withdraw_age_commitments; rh = &lrbt_cb_table_age_withdraw_commitments;
break; break;
case TALER_EXCHANGEDB_RT_WITHDRAW_AGE_REVEALED_COINS: case TALER_EXCHANGEDB_RT_WITHDRAW_AGE_REVEALED_COINS:
XPREPARE ("select_above_serial_by_table_withdraw_age_revealed_coins", XPREPARE ("select_above_serial_by_table_age_withdraw_revealed_coins",
"SELECT" "SELECT"
" withdraw_age_revealed_coins_serial_id" " age_withdraw_revealed_coins_serial_id"
",h_commitment" ",h_commitment"
",freshcoin_index" ",freshcoin_index"
",denominations_serial" ",denominations_serial"
@ -3624,10 +3624,10 @@ TEH_PG_lookup_records_by_table (void *cls,
",h_coin_ev" ",h_coin_ev"
",ev_sig" ",ev_sig"
",ewv" ",ewv"
" FROM withdraw_age_revealed_coins" " FROM age_withdraw_revealed_coins"
" WHERE withdraw_age_revealed_coins_serial_id > $1" " WHERE age_withdraw_revealed_coins_serial_id > $1"
" ORDER BY withdraw_age_revealed_coins_serial_id ASC;"); " ORDER BY age_withdraw_revealed_coins_serial_id ASC;");
rh = &lrbt_cb_table_withdraw_age_revealed_coins; rh = &lrbt_cb_table_age_withdraw_revealed_coins;
break; break;
} }
if (NULL == rh) if (NULL == rh)

View File

@ -427,22 +427,22 @@ TEH_PG_lookup_serial_by_table (void *cls,
statement = "select_serial_by_table_purse_deletion"; statement = "select_serial_by_table_purse_deletion";
break; break;
case TALER_EXCHANGEDB_RT_WITHDRAW_AGE_COMMITMENTS: case TALER_EXCHANGEDB_RT_WITHDRAW_AGE_COMMITMENTS:
XPREPARE ("select_serial_by_table_withdraw_age_commitments", XPREPARE ("select_serial_by_table_age_withdraw_commitments",
"SELECT" "SELECT"
" withdraw_age_commitment_id AS serial" " age_withdraw_commitment_id AS serial"
" FROM withdraw_age_commitments" " FROM age_withdraw_commitments"
" ORDER BY withdraw_age_commitment_id DESC" " ORDER BY age_withdraw_commitment_id DESC"
" LIMIT 1;"); " LIMIT 1;");
statement = "select_serial_by_table_withdraw_age_commitments"; statement = "select_serial_by_table_age_withdraw_commitments";
break; break;
case TALER_EXCHANGEDB_RT_WITHDRAW_AGE_REVEALED_COINS: case TALER_EXCHANGEDB_RT_WITHDRAW_AGE_REVEALED_COINS:
XPREPARE ("select_serial_by_table_withdraw_age_revealed_coins", XPREPARE ("select_serial_by_table_age_withdraw_revealed_coins",
"SELECT" "SELECT"
" withdraw_age_revealed_coins_id AS serial" " age_withdraw_revealed_coins_id AS serial"
" FROM withdraw_age_revealed_coins" " FROM age_withdraw_revealed_coins"
" ORDER BY withdraw_age_revealed_coins_id DESC" " ORDER BY age_withdraw_revealed_coins_id DESC"
" LIMIT 1;"); " LIMIT 1;");
statement = "select_serial_by_table_withdraw_age_revealed_coins"; statement = "select_serial_by_table_age_withdraw_revealed_coins";
break; break;
} }
if (NULL == statement) if (NULL == statement)

View File

@ -760,7 +760,7 @@ struct TALER_EXCHANGEDB_TableData
struct TALER_ReserveSignatureP reserve_sig; struct TALER_ReserveSignatureP reserve_sig;
uint32_t noreveal_index; uint32_t noreveal_index;
struct GNUNET_TIME_Absolute timestamp; struct GNUNET_TIME_Absolute timestamp;
} withdraw_age_commitments; } age_withdraw_commitments;
struct struct
{ {
@ -772,7 +772,7 @@ struct TALER_EXCHANGEDB_TableData
struct TALER_ExchangeWithdrawValues ewv; struct TALER_ExchangeWithdrawValues ewv;
// h_coin_ev omitted, to be recomputed! // h_coin_ev omitted, to be recomputed!
struct TALER_BlindedDenominationSignature ev_sig; struct TALER_BlindedDenominationSignature ev_sig;
} withdraw_age_revealed_coins; } age_withdraw_revealed_coins;
} details; } details;
@ -1200,8 +1200,9 @@ struct TALER_EXCHANGEDB_AgeWithdrawCommitment
struct TALER_ReservePublicKeyP reserve_pub; struct TALER_ReservePublicKeyP reserve_pub;
/** /**
* Signature confirming the age withdrawal, matching @e reserve_pub, @e * Signature confirming the age withdrawal commitment, matching @e
* maximum_age_group and @e h_commitment and @e total_amount_with_fee. * reserve_pub, @e maximum_age_group and @e h_commitment and @e
* total_amount_with_fee.
*/ */
struct TALER_ReserveSignatureP reserve_sig; struct TALER_ReserveSignatureP reserve_sig;
@ -2737,6 +2738,28 @@ struct TALER_EXCHANGEDB_CsRevealFreshCoinData
uint32_t coin_off; uint32_t coin_off;
}; };
/**
* Information about a coin that was revealed to the exchange
* during reveal.
*/
struct TALER_EXCHANGEDB_AgeWithdrawRevealedCoin
{
/**
* Hash of the public denomination key of the coin.
*/
struct TALER_DenominationHashP h_denom_pub;
/**
* Signature generated by the exchange over the coin (in blinded format).
*/
struct TALER_BlindedDenominationSignature coin_sig;
/**
* Blinded hash of the new coin
*/
struct TALER_BlindedCoinHashP h_coin_ev;
};
/** /**
* Generic KYC status for some operation. * Generic KYC status for some operation.
@ -3810,19 +3833,18 @@ struct TALER_EXCHANGEDB_Plugin
* age restriction enabled in a given age-withdraw operation and the relevant * age restriction enabled in a given age-withdraw operation and the relevant
* information we learned or created in the reveal steop * information we learned or created in the reveal steop
* *
* @param cls the `struct PostgresClosure` with the plugin-specific state * @param cls The `struct PostgresClosure` with the plugin-specific state
* @param h_commitment The hash of the original age-withdraw commitment, which is a key into the withdraw_age_commitments table * @param h_commitment The hash of the original age-withdraw commitment, which is a key into the age_withdraw_commitments table
* @param num_coins number of coins to generate, size of the @a coin_evs array * @param num_awrcs Number of coins to generate, size of the @a coin_evs array
* TODO: oec * @param awrcs Array of @a num_awrcs information about coins to be created
* @return query execution status * @return query execution status
*/ */
enum GNUNET_DB_QueryStatus enum GNUNET_DB_QueryStatus
(*insert_age_withdraw_reveal)( (*insert_age_withdraw_reveal)(
void *cls, void *cls,
uint64_t h_commitment, const struct TALER_AgeWithdrawCommitmentHashP *h_commitment,
uint32_t num_coins uint32_t num_awrcs,
/* TODO: oec */ const struct TALER_EXCHANGEDB_AgeWithdrawRevealedCoin *awrcs);
);
/** /**
* Lookup in the database for the fresh coins with age-restriction that * Lookup in the database for the fresh coins with age-restriction that