Merge branch 'master' into ar
This commit is contained in:
commit
6230de917f
@ -1983,38 +1983,29 @@ check_recoup (struct CoinContext *cc,
|
||||
cc->qs = qs;
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
if (GNUNET_OK !=
|
||||
TALER_wallet_recoup_verify (&coin->denom_pub_hash,
|
||||
coin_blind,
|
||||
amount,
|
||||
&coin->coin_pub,
|
||||
coin_sig))
|
||||
{
|
||||
struct TALER_RecoupRequestPS pr = {
|
||||
.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_RECOUP),
|
||||
.purpose.size = htonl (sizeof (pr)),
|
||||
.coin_pub = coin->coin_pub,
|
||||
.coin_blind = *coin_blind,
|
||||
.h_denom_pub = coin->denom_pub_hash
|
||||
};
|
||||
|
||||
if (GNUNET_OK !=
|
||||
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_RECOUP,
|
||||
&pr,
|
||||
&coin_sig->eddsa_signature,
|
||||
&coin->coin_pub.eddsa_pub))
|
||||
{
|
||||
TALER_ARL_report (report_bad_sig_losses,
|
||||
GNUNET_JSON_PACK (
|
||||
GNUNET_JSON_pack_string ("operation",
|
||||
operation),
|
||||
GNUNET_JSON_pack_uint64 ("row",
|
||||
rowid),
|
||||
TALER_JSON_pack_amount ("loss",
|
||||
amount),
|
||||
GNUNET_JSON_pack_data_auto ("coin_pub",
|
||||
&coin->coin_pub)));
|
||||
TALER_ARL_amount_add (&total_bad_sig_loss,
|
||||
&total_bad_sig_loss,
|
||||
amount);
|
||||
if (TALER_ARL_do_abort ())
|
||||
return GNUNET_SYSERR;
|
||||
return GNUNET_OK;
|
||||
}
|
||||
TALER_ARL_report (report_bad_sig_losses,
|
||||
GNUNET_JSON_PACK (
|
||||
GNUNET_JSON_pack_string ("operation",
|
||||
operation),
|
||||
GNUNET_JSON_pack_uint64 ("row",
|
||||
rowid),
|
||||
TALER_JSON_pack_amount ("loss",
|
||||
amount),
|
||||
GNUNET_JSON_pack_data_auto ("coin_pub",
|
||||
&coin->coin_pub)));
|
||||
TALER_ARL_amount_add (&total_bad_sig_loss,
|
||||
&total_bad_sig_loss,
|
||||
amount);
|
||||
if (TALER_ARL_do_abort ())
|
||||
return GNUNET_SYSERR;
|
||||
return GNUNET_OK;
|
||||
}
|
||||
ds = get_denomination_summary (cc,
|
||||
issue,
|
||||
|
@ -684,7 +684,7 @@ handle_reserve_out (void *cls,
|
||||
* @param coin_blind blinding factor used to blind the coin
|
||||
* @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop
|
||||
*/
|
||||
static int
|
||||
static enum GNUNET_GenericReturnValue
|
||||
handle_recoup_by_reserve (
|
||||
void *cls,
|
||||
uint64_t rowid,
|
||||
@ -711,35 +711,26 @@ handle_recoup_by_reserve (
|
||||
ppr.last_reserve_recoup_serial_id = rowid + 1;
|
||||
/* We know that denom_pub matches denom_pub_hash because this
|
||||
is how the SQL statement joined the tables. */
|
||||
if (GNUNET_OK !=
|
||||
TALER_wallet_recoup_verify (&coin->denom_pub_hash,
|
||||
coin_blind,
|
||||
amount,
|
||||
&coin->coin_pub,
|
||||
coin_sig))
|
||||
{
|
||||
struct TALER_RecoupRequestPS pr = {
|
||||
.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_RECOUP),
|
||||
.purpose.size = htonl (sizeof (pr)),
|
||||
.h_denom_pub = coin->denom_pub_hash,
|
||||
.coin_pub = coin->coin_pub,
|
||||
.coin_blind = *coin_blind
|
||||
};
|
||||
|
||||
if (GNUNET_OK !=
|
||||
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_RECOUP,
|
||||
&pr,
|
||||
&coin_sig->eddsa_signature,
|
||||
&coin->coin_pub.eddsa_pub))
|
||||
{
|
||||
TALER_ARL_report (report_bad_sig_losses,
|
||||
GNUNET_JSON_PACK (
|
||||
GNUNET_JSON_pack_string ("operation",
|
||||
"recoup"),
|
||||
GNUNET_JSON_pack_uint64 ("row",
|
||||
rowid),
|
||||
TALER_JSON_pack_amount ("loss",
|
||||
amount),
|
||||
GNUNET_JSON_pack_data_auto ("key_pub",
|
||||
&coin->coin_pub)));
|
||||
TALER_ARL_amount_add (&total_bad_sig_loss,
|
||||
&total_bad_sig_loss,
|
||||
amount);
|
||||
}
|
||||
TALER_ARL_report (report_bad_sig_losses,
|
||||
GNUNET_JSON_PACK (
|
||||
GNUNET_JSON_pack_string ("operation",
|
||||
"recoup"),
|
||||
GNUNET_JSON_pack_uint64 ("row",
|
||||
rowid),
|
||||
TALER_JSON_pack_amount ("loss",
|
||||
amount),
|
||||
GNUNET_JSON_pack_data_auto ("key_pub",
|
||||
&coin->coin_pub)));
|
||||
TALER_ARL_amount_add (&total_bad_sig_loss,
|
||||
&total_bad_sig_loss,
|
||||
amount);
|
||||
}
|
||||
|
||||
/* check that the coin was eligible for recoup!*/
|
||||
|
@ -87,6 +87,7 @@ struct RecoupContext
|
||||
* Set by #recoup_transaction() to the amount that will be paid back
|
||||
*/
|
||||
struct TALER_Amount amount;
|
||||
const struct TALER_Amount *requested_amount;
|
||||
|
||||
/**
|
||||
* Set by #recoup_transaction to the timestamp when the recoup
|
||||
@ -234,6 +235,15 @@ recoup_transaction (void *cls,
|
||||
TEH_plugin->free_coin_transaction_list (TEH_plugin->cls,
|
||||
tl);
|
||||
pc->now = GNUNET_TIME_timestamp_get ();
|
||||
if (0 != TALER_amount_cmp (&pc->amount,
|
||||
pc->requested_amount))
|
||||
{
|
||||
*mhd_ret = TALER_MHD_reply_with_error (connection,
|
||||
MHD_HTTP_CONFLICT,
|
||||
TALER_EC_EXCHANGE_GENERIC_INSUFFICIENT_FUNDS,
|
||||
TALER_amount2s (&pc->amount));
|
||||
return GNUNET_DB_STATUS_HARD_ERROR;
|
||||
}
|
||||
|
||||
/* add coin to list of wire transfers for recoup */
|
||||
if (pc->refreshed)
|
||||
@ -284,6 +294,7 @@ recoup_transaction (void *cls,
|
||||
* @param coin information about the coin
|
||||
* @param coin_bks blinding data of the coin (to be checked)
|
||||
* @param coin_sig signature of the coin
|
||||
* @param requested_amount requested amount to be recouped
|
||||
* @param refreshed true if the coin was refreshed
|
||||
* @return MHD result code
|
||||
*/
|
||||
@ -293,6 +304,7 @@ verify_and_execute_recoup (
|
||||
const struct TALER_CoinPublicInfo *coin,
|
||||
const union TALER_DenominationBlindingKeyP *coin_bks,
|
||||
const struct TALER_CoinSpendSignatureP *coin_sig,
|
||||
const struct TALER_Amount *requested_amount,
|
||||
bool refreshed)
|
||||
{
|
||||
struct RecoupContext pc;
|
||||
@ -352,27 +364,18 @@ verify_and_execute_recoup (
|
||||
}
|
||||
|
||||
/* check recoup request signature */
|
||||
if (GNUNET_OK !=
|
||||
TALER_wallet_recoup_verify (&coin->denom_pub_hash,
|
||||
coin_bks,
|
||||
requested_amount,
|
||||
&coin->coin_pub,
|
||||
coin_sig))
|
||||
{
|
||||
struct TALER_RecoupRequestPS pr = {
|
||||
.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_RECOUP),
|
||||
.purpose.size = htonl (sizeof (pr)),
|
||||
.coin_pub = coin->coin_pub,
|
||||
.h_denom_pub = coin->denom_pub_hash,
|
||||
.coin_blind = *coin_bks
|
||||
};
|
||||
|
||||
if (GNUNET_OK !=
|
||||
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_RECOUP,
|
||||
&pr,
|
||||
&coin_sig->eddsa_signature,
|
||||
&coin->coin_pub.eddsa_pub))
|
||||
{
|
||||
TALER_LOG_WARNING ("Invalid signature on recoup request\n");
|
||||
return TALER_MHD_reply_with_error (connection,
|
||||
MHD_HTTP_FORBIDDEN,
|
||||
TALER_EC_EXCHANGE_RECOUP_SIGNATURE_INVALID,
|
||||
NULL);
|
||||
}
|
||||
GNUNET_break_op (0);
|
||||
return TALER_MHD_reply_with_error (connection,
|
||||
MHD_HTTP_FORBIDDEN,
|
||||
TALER_EC_EXCHANGE_RECOUP_SIGNATURE_INVALID,
|
||||
NULL);
|
||||
}
|
||||
|
||||
{
|
||||
@ -404,6 +407,7 @@ verify_and_execute_recoup (
|
||||
pc.coin_bks = coin_bks;
|
||||
pc.coin = coin;
|
||||
pc.refreshed = refreshed;
|
||||
pc.requested_amount = requested_amount;
|
||||
|
||||
{
|
||||
MHD_RESULT mhd_ret = MHD_NO;
|
||||
@ -552,6 +556,7 @@ TEH_handler_recoup (struct MHD_Connection *connection,
|
||||
&coin,
|
||||
&coin_bks,
|
||||
&coin_sig,
|
||||
&amount,
|
||||
refreshed);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
return res;
|
||||
|
@ -140,7 +140,6 @@ withdraw_transaction (void *cls,
|
||||
enum GNUNET_DB_QueryStatus qs;
|
||||
bool found = false;
|
||||
bool balance_ok = false;
|
||||
uint64_t reserve_uuid;
|
||||
struct GNUNET_TIME_Timestamp now;
|
||||
|
||||
now = GNUNET_TIME_timestamp_get ();
|
||||
@ -151,8 +150,7 @@ withdraw_transaction (void *cls,
|
||||
now,
|
||||
&found,
|
||||
&balance_ok,
|
||||
&wc->kyc,
|
||||
&reserve_uuid);
|
||||
&wc->kyc);
|
||||
if (0 > qs)
|
||||
{
|
||||
if (GNUNET_DB_STATUS_HARD_ERROR == qs)
|
||||
@ -234,7 +232,7 @@ withdraw_transaction (void *cls,
|
||||
|
||||
qs2 = TEH_plugin->do_withdraw_limit_check (
|
||||
TEH_plugin->cls,
|
||||
reserve_uuid,
|
||||
&wc->collectable.reserve_pub,
|
||||
GNUNET_TIME_absolute_subtract (now.abs_time,
|
||||
TEH_kyc_config.withdraw_period),
|
||||
&TEH_kyc_config.withdraw_limit,
|
||||
|
@ -87,13 +87,15 @@ COMMENT ON COLUMN wire_targets.external_id
|
||||
|
||||
|
||||
CREATE TABLE IF NOT EXISTS reserves
|
||||
(reserve_uuid BIGSERIAL UNIQUE
|
||||
(reserve_uuid BIGSERIAL
|
||||
,reserve_pub BYTEA PRIMARY KEY CHECK(LENGTH(reserve_pub)=32)
|
||||
,current_balance_val INT8 NOT NULL
|
||||
,current_balance_frac INT4 NOT NULL
|
||||
,expiration_date INT8 NOT NULL
|
||||
,gc_date INT8 NOT NULL
|
||||
);
|
||||
)
|
||||
PARTITION BY HASH (reserve_pub);
|
||||
|
||||
COMMENT ON TABLE reserves
|
||||
IS 'Summarizes the balance of a reserve. Updated when new funds are added or withdrawn.';
|
||||
COMMENT ON COLUMN reserves.expiration_date
|
||||
@ -101,6 +103,17 @@ COMMENT ON COLUMN reserves.expiration_date
|
||||
COMMENT ON COLUMN reserves.gc_date
|
||||
IS 'Used to forget all information about a reserve during garbage collection';
|
||||
|
||||
CREATE TABLE reserves_0 PARTITION OF reserves FOR VALUES WITH (MODULUS 8, REMAINDER 0);
|
||||
CREATE TABLE reserves_1 PARTITION OF reserves FOR VALUES WITH (MODULUS 8, REMAINDER 1);
|
||||
CREATE TABLE reserves_2 PARTITION OF reserves FOR VALUES WITH (MODULUS 8, REMAINDER 2);
|
||||
CREATE TABLE reserves_3 PARTITION OF reserves FOR VALUES WITH (MODULUS 8, REMAINDER 3);
|
||||
CREATE TABLE reserves_4 PARTITION OF reserves FOR VALUES WITH (MODULUS 8, REMAINDER 4);
|
||||
CREATE TABLE reserves_5 PARTITION OF reserves FOR VALUES WITH (MODULUS 8, REMAINDER 5);
|
||||
CREATE TABLE reserves_6 PARTITION OF reserves FOR VALUES WITH (MODULUS 8, REMAINDER 6);
|
||||
CREATE TABLE reserves_7 PARTITION OF reserves FOR VALUES WITH (MODULUS 8, REMAINDER 7);
|
||||
|
||||
|
||||
|
||||
CREATE INDEX IF NOT EXISTS reserves_expiration_index
|
||||
ON reserves
|
||||
(expiration_date
|
||||
@ -119,14 +132,14 @@ COMMENT ON INDEX reserves_gc_index
|
||||
|
||||
CREATE TABLE IF NOT EXISTS reserves_in
|
||||
(reserve_in_serial_id BIGSERIAL UNIQUE
|
||||
,reserve_uuid INT8 NOT NULL REFERENCES reserves (reserve_uuid) ON DELETE CASCADE
|
||||
,reserve_pub BYTEA NOT NULL REFERENCES reserves (reserve_pub) ON DELETE CASCADE
|
||||
,wire_reference INT8 NOT NULL
|
||||
,credit_val INT8 NOT NULL
|
||||
,credit_frac INT4 NOT NULL
|
||||
,wire_source_serial_id INT8 NOT NULL REFERENCES wire_targets (wire_target_serial_id)
|
||||
,exchange_account_section TEXT NOT NULL
|
||||
,execution_date INT8 NOT NULL
|
||||
,PRIMARY KEY (reserve_uuid, wire_reference)
|
||||
,PRIMARY KEY (reserve_pub, wire_reference)
|
||||
);
|
||||
COMMENT ON TABLE reserves_in
|
||||
IS 'list of transfers of funds into the reserves, one per incoming wire transfer';
|
||||
@ -144,9 +157,10 @@ CREATE INDEX IF NOT EXISTS reserves_in_exchange_account_serial
|
||||
);
|
||||
|
||||
|
||||
|
||||
CREATE TABLE IF NOT EXISTS reserves_close
|
||||
(close_uuid BIGSERIAL PRIMARY KEY
|
||||
,reserve_uuid INT8 NOT NULL REFERENCES reserves (reserve_uuid) ON DELETE CASCADE
|
||||
,reserve_pub BYTEA NOT NULL REFERENCES reserves (reserve_pub) ON DELETE CASCADE
|
||||
,execution_date INT8 NOT NULL
|
||||
,wtid BYTEA NOT NULL CHECK (LENGTH(wtid)=32)
|
||||
,wire_target_serial_id INT8 NOT NULL REFERENCES wire_targets (wire_target_serial_id)
|
||||
@ -161,7 +175,7 @@ COMMENT ON COLUMN reserves_close.wire_target_serial_id
|
||||
|
||||
CREATE INDEX IF NOT EXISTS reserves_close_by_uuid
|
||||
ON reserves_close
|
||||
(reserve_uuid);
|
||||
(reserve_pub);
|
||||
|
||||
|
||||
CREATE TABLE IF NOT EXISTS reserves_out
|
||||
@ -169,7 +183,7 @@ CREATE TABLE IF NOT EXISTS reserves_out
|
||||
,h_blind_ev BYTEA PRIMARY KEY CHECK (LENGTH(h_blind_ev)=64)
|
||||
,denominations_serial INT8 NOT NULL REFERENCES denominations (denominations_serial)
|
||||
,denom_sig BYTEA NOT NULL
|
||||
,reserve_uuid INT8 NOT NULL REFERENCES reserves (reserve_uuid) ON DELETE CASCADE
|
||||
,reserve_pub BYTEA NOT NULL REFERENCES reserves (reserve_pub) ON DELETE CASCADE
|
||||
,reserve_sig BYTEA NOT NULL CHECK (LENGTH(reserve_sig)=64)
|
||||
,execution_date INT8 NOT NULL
|
||||
,amount_with_fee_val INT8 NOT NULL
|
||||
@ -182,10 +196,10 @@ COMMENT ON COLUMN reserves_out.h_blind_ev
|
||||
COMMENT ON COLUMN reserves_out.denominations_serial
|
||||
IS 'We do not CASCADE ON DELETE here, we may keep the denomination data alive';
|
||||
|
||||
CREATE INDEX IF NOT EXISTS reserves_out_reserve_uuid_index
|
||||
CREATE INDEX IF NOT EXISTS reserves_out_reserve_pub_index
|
||||
ON reserves_out
|
||||
(reserve_uuid);
|
||||
COMMENT ON INDEX reserves_out_reserve_uuid_index
|
||||
(reserve_pub);
|
||||
COMMENT ON INDEX reserves_out_reserve_pub_index
|
||||
IS 'for get_reserves_out';
|
||||
|
||||
CREATE INDEX IF NOT EXISTS reserves_out_execution_date
|
||||
@ -713,8 +727,6 @@ CREATE INDEX IF NOT EXISTS revolving_work_shards_index
|
||||
-- Stored procedures
|
||||
|
||||
|
||||
DROP FUNCTION IF EXISTS exchange_do_withdraw(bigint,integer,bytea,bytea,bytea,bytea,bytea,bigint,bigint) ;
|
||||
|
||||
CREATE OR REPLACE FUNCTION exchange_do_withdraw(
|
||||
IN amount_val INT8,
|
||||
IN amount_frac INT4,
|
||||
@ -728,7 +740,6 @@ CREATE OR REPLACE FUNCTION exchange_do_withdraw(
|
||||
OUT reserve_found BOOLEAN,
|
||||
OUT balance_ok BOOLEAN,
|
||||
OUT kycok BOOLEAN,
|
||||
OUT ruuid INT8,
|
||||
OUT account_uuid INT8)
|
||||
LANGUAGE plpgsql
|
||||
AS $$
|
||||
@ -752,21 +763,18 @@ THEN
|
||||
reserve_found=FALSE;
|
||||
balance_ok=FALSE;
|
||||
kycok=FALSE;
|
||||
ruuid=0;
|
||||
account_uuid=0;
|
||||
ASSERT false, 'denomination unknown';
|
||||
RETURN;
|
||||
END IF;
|
||||
|
||||
SELECT
|
||||
reserves.reserve_uuid
|
||||
,current_balance_val
|
||||
current_balance_val
|
||||
,current_balance_frac
|
||||
,expiration_date
|
||||
,gc_date
|
||||
INTO
|
||||
ruuid
|
||||
,reserve_val
|
||||
reserve_val
|
||||
,reserve_frac
|
||||
,reserve_gc
|
||||
FROM reserves
|
||||
@ -788,7 +796,7 @@ INSERT INTO reserves_out
|
||||
(h_blind_ev
|
||||
,denominations_serial
|
||||
,denom_sig
|
||||
,reserve_uuid
|
||||
,reserve_pub
|
||||
,reserve_sig
|
||||
,execution_date
|
||||
,amount_with_fee_val
|
||||
@ -797,7 +805,7 @@ VALUES
|
||||
(h_coin_envelope
|
||||
,denom_serial
|
||||
,denom_sig
|
||||
,ruuid
|
||||
,rpub
|
||||
,reserve_sig
|
||||
,now
|
||||
,amount_val
|
||||
@ -848,7 +856,7 @@ UPDATE reserves SET
|
||||
,current_balance_val=reserve_val
|
||||
,current_balance_frac=reserve_frac
|
||||
WHERE
|
||||
reserves.reserve_uuid=ruuid;
|
||||
reserves.reserve_pub=rpub;
|
||||
|
||||
reserve_found=TRUE;
|
||||
balance_ok=TRUE;
|
||||
@ -863,7 +871,7 @@ SELECT
|
||||
,account_uuid
|
||||
FROM reserves_in
|
||||
JOIN wire_targets ON (wire_source_serial_id = wire_target_serial_id)
|
||||
WHERE reserve_uuid=ruuid
|
||||
WHERE reserve_pub=rpub
|
||||
LIMIT 1; -- limit 1 should not be required (without p2p transfers)
|
||||
|
||||
END $$;
|
||||
@ -873,11 +881,8 @@ COMMENT ON FUNCTION exchange_do_withdraw(INT8, INT4, BYTEA, BYTEA, BYTEA, BYTEA,
|
||||
|
||||
|
||||
|
||||
DROP FUNCTION IF EXISTS exchange_do_withdraw_limit_check(bigint,bigint,bigint,int) ;
|
||||
|
||||
|
||||
CREATE OR REPLACE FUNCTION exchange_do_withdraw_limit_check(
|
||||
IN ruuid INT8,
|
||||
IN rpub BYTEA,
|
||||
IN start_time INT8,
|
||||
IN upper_limit_val INT8,
|
||||
IN upper_limit_frac INT4,
|
||||
@ -897,7 +902,7 @@ SELECT
|
||||
total_val
|
||||
,total_frac
|
||||
FROM reserves_out
|
||||
WHERE reserves_out.reserve_uuid=ruuid
|
||||
WHERE reserves_out.reserve_pub=rpub
|
||||
AND execution_date > start_time;
|
||||
|
||||
-- normalize result
|
||||
@ -910,7 +915,7 @@ below_limit = (total_val < upper_limit_val) OR
|
||||
(total_frac <= upper_limit_frac) );
|
||||
END $$;
|
||||
|
||||
COMMENT ON FUNCTION exchange_do_withdraw_limit_check(INT8, INT8, INT8, INT4)
|
||||
COMMENT ON FUNCTION exchange_do_withdraw_limit_check(BYTEA, INT8, INT8, INT4)
|
||||
IS 'Check whether the withdrawals from the given reserve since the given time are below the given threshold';
|
||||
|
||||
|
||||
|
@ -174,7 +174,7 @@ irbt_cb_table_reserves_in (struct PostgresClosure *pg,
|
||||
td->details.reserves_in.exchange_account_section),
|
||||
GNUNET_PQ_query_param_timestamp (
|
||||
&td->details.reserves_in.execution_date),
|
||||
GNUNET_PQ_query_param_uint64 (&td->details.reserves_in.reserve_uuid),
|
||||
GNUNET_PQ_query_param_auto_from_type (&td->details.reserves_in.reserve_pub),
|
||||
GNUNET_PQ_query_param_end
|
||||
};
|
||||
|
||||
@ -204,7 +204,8 @@ irbt_cb_table_reserves_close (struct PostgresClosure *pg,
|
||||
&td->details.reserves_close.wire_target_serial_id),
|
||||
TALER_PQ_query_param_amount (&td->details.reserves_close.amount),
|
||||
TALER_PQ_query_param_amount (&td->details.reserves_close.closing_fee),
|
||||
GNUNET_PQ_query_param_uint64 (&td->details.reserves_close.reserve_uuid),
|
||||
GNUNET_PQ_query_param_auto_from_type (
|
||||
&td->details.reserves_close.reserve_pub),
|
||||
GNUNET_PQ_query_param_end
|
||||
};
|
||||
|
||||
@ -232,8 +233,8 @@ irbt_cb_table_reserves_out (struct PostgresClosure *pg,
|
||||
&td->details.reserves_out.denominations_serial),
|
||||
TALER_PQ_query_param_blinded_denom_sig (
|
||||
&td->details.reserves_out.denom_sig),
|
||||
GNUNET_PQ_query_param_uint64 (
|
||||
&td->details.reserves_out.reserve_uuid),
|
||||
GNUNET_PQ_query_param_auto_from_type (
|
||||
&td->details.reserves_out.reserve_pub),
|
||||
GNUNET_PQ_query_param_auto_from_type (
|
||||
&td->details.reserves_out.reserve_sig),
|
||||
GNUNET_PQ_query_param_timestamp (
|
||||
|
@ -277,9 +277,9 @@ lrbt_cb_table_reserves_in (void *cls,
|
||||
GNUNET_PQ_result_spec_uint64 (
|
||||
"serial",
|
||||
&td.serial),
|
||||
GNUNET_PQ_result_spec_uint64 (
|
||||
"reserve_uuid",
|
||||
&td.details.reserves_in.reserve_uuid),
|
||||
GNUNET_PQ_result_spec_auto_from_type (
|
||||
"reserve_pub",
|
||||
&td.details.reserves_in.reserve_pub),
|
||||
GNUNET_PQ_result_spec_uint64 (
|
||||
"wire_reference",
|
||||
&td.details.reserves_in.wire_reference),
|
||||
@ -338,9 +338,9 @@ lrbt_cb_table_reserves_close (void *cls,
|
||||
GNUNET_PQ_result_spec_uint64 (
|
||||
"serial",
|
||||
&td.serial),
|
||||
GNUNET_PQ_result_spec_uint64 (
|
||||
"reserve_uuid",
|
||||
&td.details.reserves_close.reserve_uuid),
|
||||
GNUNET_PQ_result_spec_auto_from_type (
|
||||
"reserve_pub",
|
||||
&td.details.reserves_close.reserve_pub),
|
||||
GNUNET_PQ_result_spec_timestamp (
|
||||
"execution_date",
|
||||
&td.details.reserves_close.execution_date),
|
||||
@ -408,9 +408,9 @@ lrbt_cb_table_reserves_out (void *cls,
|
||||
TALER_PQ_result_spec_blinded_denom_sig (
|
||||
"denom_sig",
|
||||
&td.details.reserves_out.denom_sig),
|
||||
GNUNET_PQ_result_spec_uint64 (
|
||||
"reserve_uuid",
|
||||
&td.details.reserves_out.reserve_uuid),
|
||||
GNUNET_PQ_result_spec_auto_from_type (
|
||||
"reserve_pub",
|
||||
&td.details.reserves_out.reserve_pub),
|
||||
GNUNET_PQ_result_spec_auto_from_type (
|
||||
"reserve_sig",
|
||||
&td.details.reserves_out.reserve_sig),
|
||||
|
@ -378,7 +378,7 @@ prepare_statements (struct PostgresClosure *pg)
|
||||
",kyc_ok"
|
||||
",wire_target_serial_id AS payment_target_uuid"
|
||||
" FROM reserves"
|
||||
" JOIN reserves_in ri USING (reserve_uuid)"
|
||||
" JOIN reserves_in ri USING (reserve_pub)"
|
||||
" JOIN wire_targets wt "
|
||||
" ON (ri.wire_source_serial_id = wt.wire_target_serial_id)"
|
||||
" WHERE reserve_pub=$1"
|
||||
@ -467,7 +467,7 @@ prepare_statements (struct PostgresClosure *pg)
|
||||
GNUNET_PQ_make_prepare (
|
||||
"reserves_close_insert",
|
||||
"INSERT INTO reserves_close "
|
||||
"(reserve_uuid"
|
||||
"(reserve_pub"
|
||||
",execution_date"
|
||||
",wtid"
|
||||
",wire_target_serial_id"
|
||||
@ -475,9 +475,7 @@ prepare_statements (struct PostgresClosure *pg)
|
||||
",amount_frac"
|
||||
",closing_fee_val"
|
||||
",closing_fee_frac"
|
||||
") SELECT reserve_uuid, $2, $3, $4, $5, $6, $7, $8"
|
||||
" FROM reserves"
|
||||
" WHERE reserve_pub=$1;",
|
||||
") VALUES ($1, $2, $3, $4, $5, $6, $7, $8);",
|
||||
8),
|
||||
/* Used in #reserves_update() when the reserve is updated */
|
||||
GNUNET_PQ_make_prepare (
|
||||
@ -494,23 +492,21 @@ prepare_statements (struct PostgresClosure *pg)
|
||||
GNUNET_PQ_make_prepare (
|
||||
"reserves_in_add_transaction",
|
||||
"INSERT INTO reserves_in "
|
||||
"(reserve_uuid"
|
||||
"(reserve_pub"
|
||||
",wire_reference"
|
||||
",credit_val"
|
||||
",credit_frac"
|
||||
",exchange_account_section"
|
||||
",wire_source_serial_id"
|
||||
",execution_date"
|
||||
") SELECT reserve_uuid, $2, $3, $4, $5, $6, $7"
|
||||
" FROM reserves"
|
||||
" WHERE reserve_pub=$1"
|
||||
") VALUES ($1, $2, $3, $4, $5, $6, $7)"
|
||||
" ON CONFLICT DO NOTHING;",
|
||||
7),
|
||||
/* Used in #postgres_reserves_in_insert() to store transaction details */
|
||||
GNUNET_PQ_make_prepare (
|
||||
"reserves_in_add_by_uuid",
|
||||
"reserves_in_add_by_pub",
|
||||
"INSERT INTO reserves_in "
|
||||
"(reserve_uuid"
|
||||
"(reserve_pub"
|
||||
",wire_reference"
|
||||
",credit_val"
|
||||
",credit_frac"
|
||||
@ -545,7 +541,7 @@ prepare_statements (struct PostgresClosure *pg)
|
||||
",reserve_in_serial_id"
|
||||
" FROM reserves_in"
|
||||
" JOIN reserves"
|
||||
" USING (reserve_uuid)"
|
||||
" USING (reserve_pub)"
|
||||
" JOIN wire_targets"
|
||||
" ON (wire_source_serial_id = wire_target_serial_id)"
|
||||
" WHERE reserve_in_serial_id>=$1"
|
||||
@ -565,7 +561,7 @@ prepare_statements (struct PostgresClosure *pg)
|
||||
",reserve_in_serial_id"
|
||||
" FROM reserves_in"
|
||||
" JOIN reserves "
|
||||
" USING (reserve_uuid)"
|
||||
" USING (reserve_pub)"
|
||||
" JOIN wire_targets"
|
||||
" ON (wire_source_serial_id = wire_target_serial_id)"
|
||||
" WHERE reserve_in_serial_id>=$1 AND exchange_account_section=$2"
|
||||
@ -584,10 +580,7 @@ prepare_statements (struct PostgresClosure *pg)
|
||||
" FROM reserves_in"
|
||||
" JOIN wire_targets"
|
||||
" ON (wire_source_serial_id = wire_target_serial_id)"
|
||||
" WHERE reserve_uuid="
|
||||
" (SELECT reserve_uuid "
|
||||
" FROM reserves"
|
||||
" WHERE reserve_pub=$1);",
|
||||
" WHERE reserve_pub=$1;",
|
||||
1),
|
||||
/* Lock withdraw table; NOTE: we may want to eventually shard the
|
||||
deposit table to avoid this lock being the main point of
|
||||
@ -619,7 +612,6 @@ prepare_statements (struct PostgresClosure *pg)
|
||||
" reserve_found"
|
||||
",balance_ok"
|
||||
",kycok AS kyc_ok"
|
||||
",ruuid AS reserve_uuid"
|
||||
",account_uuid AS payment_target_uuid"
|
||||
" FROM exchange_do_withdraw"
|
||||
" ($1,$2,$3,$4,$5,$6,$7,$8,$9);",
|
||||
@ -643,23 +635,18 @@ prepare_statements (struct PostgresClosure *pg)
|
||||
authorizing the withdrawal. */
|
||||
GNUNET_PQ_make_prepare (
|
||||
"insert_withdraw_info",
|
||||
"WITH ds AS"
|
||||
" (SELECT denominations_serial"
|
||||
" FROM denominations"
|
||||
" WHERE denom_pub_hash=$2)"
|
||||
"INSERT INTO reserves_out "
|
||||
"(h_blind_ev"
|
||||
",denominations_serial"
|
||||
",denom_sig"
|
||||
",reserve_uuid"
|
||||
",reserve_pub"
|
||||
",reserve_sig"
|
||||
",execution_date"
|
||||
",amount_with_fee_val"
|
||||
",amount_with_fee_frac"
|
||||
") SELECT $1, ds.denominations_serial, $3, reserve_uuid, $5, $6, $7, $8"
|
||||
" FROM reserves"
|
||||
" CROSS JOIN ds"
|
||||
" WHERE reserve_pub=$4;",
|
||||
") SELECT $1, denominations_serial, $3, $4, $5, $6, $7, $8"
|
||||
" FROM denominations"
|
||||
" WHERE denom_pub_hash=$2;",
|
||||
8),
|
||||
/* Used in #postgres_get_withdraw_info() to
|
||||
locate the response for a /reserve/withdraw request
|
||||
@ -679,7 +666,7 @@ prepare_statements (struct PostgresClosure *pg)
|
||||
",denom.fee_withdraw_frac"
|
||||
" FROM reserves_out"
|
||||
" JOIN reserves"
|
||||
" USING (reserve_uuid)"
|
||||
" USING (reserve_pub)"
|
||||
" JOIN denominations denom"
|
||||
" USING (denominations_serial)"
|
||||
" WHERE h_blind_ev=$1;",
|
||||
@ -703,10 +690,7 @@ prepare_statements (struct PostgresClosure *pg)
|
||||
" FROM reserves_out"
|
||||
" JOIN denominations denom"
|
||||
" USING (denominations_serial)"
|
||||
" WHERE reserve_uuid="
|
||||
" (SELECT reserve_uuid"
|
||||
" FROM reserves"
|
||||
" WHERE reserve_pub=$1);",
|
||||
" WHERE reserve_pub=$1;",
|
||||
1),
|
||||
/* Used in #postgres_select_withdrawals_above_serial_id() */
|
||||
GNUNET_PQ_make_prepare (
|
||||
@ -722,7 +706,7 @@ prepare_statements (struct PostgresClosure *pg)
|
||||
",reserve_out_serial_id"
|
||||
" FROM reserves_out"
|
||||
" JOIN reserves"
|
||||
" USING (reserve_uuid)"
|
||||
" USING (reserve_pub)"
|
||||
" JOIN denominations denom"
|
||||
" USING (denominations_serial)"
|
||||
" WHERE reserve_out_serial_id>=$1"
|
||||
@ -1531,7 +1515,7 @@ prepare_statements (struct PostgresClosure *pg)
|
||||
" JOIN reserves_out ro"
|
||||
" USING (reserve_out_serial_id)"
|
||||
" JOIN reserves"
|
||||
" USING (reserve_uuid)"
|
||||
" USING (reserve_pub)"
|
||||
" JOIN denominations denoms"
|
||||
" ON (coins.denominations_serial = denoms.denominations_serial)"
|
||||
" WHERE recoup_uuid>=$1"
|
||||
@ -1589,7 +1573,7 @@ prepare_statements (struct PostgresClosure *pg)
|
||||
" JOIN wire_targets"
|
||||
" USING (wire_target_serial_id)"
|
||||
" JOIN reserves"
|
||||
" USING (reserve_uuid)"
|
||||
" USING (reserve_pub)"
|
||||
" WHERE close_uuid>=$1"
|
||||
" ORDER BY close_uuid ASC;",
|
||||
1),
|
||||
@ -1613,10 +1597,7 @@ prepare_statements (struct PostgresClosure *pg)
|
||||
" USING (denominations_serial)"
|
||||
" JOIN reserves_out ro"
|
||||
" USING (reserve_out_serial_id)"
|
||||
" WHERE ro.reserve_uuid="
|
||||
" (SELECT reserve_uuid"
|
||||
" FROM reserves"
|
||||
" WHERE reserve_pub=$1);",
|
||||
" WHERE ro.reserve_pub=$1;",
|
||||
1),
|
||||
/* Used in #postgres_get_coin_transactions() to obtain recoup transactions
|
||||
affecting old coins of refreshed coins */
|
||||
@ -1661,10 +1642,7 @@ prepare_statements (struct PostgresClosure *pg)
|
||||
" FROM reserves_close"
|
||||
" JOIN wire_targets"
|
||||
" USING (wire_target_serial_id)"
|
||||
" WHERE reserve_uuid="
|
||||
" (SELECT reserve_uuid"
|
||||
" FROM reserves"
|
||||
" WHERE reserve_pub=$1);",
|
||||
" WHERE reserve_pub=$1;",
|
||||
1),
|
||||
/* Used in #postgres_get_expired_reserves() */
|
||||
GNUNET_PQ_make_prepare (
|
||||
@ -1677,7 +1655,7 @@ prepare_statements (struct PostgresClosure *pg)
|
||||
",current_balance_frac"
|
||||
" FROM reserves"
|
||||
" JOIN reserves_in ri"
|
||||
" USING (reserve_uuid)"
|
||||
" USING (reserve_pub)"
|
||||
" JOIN wire_targets wt"
|
||||
" ON (ri.wire_source_serial_id = wt.wire_target_serial_id)"
|
||||
" WHERE expiration_date<=$1"
|
||||
@ -1703,7 +1681,7 @@ prepare_statements (struct PostgresClosure *pg)
|
||||
" JOIN reserves_out ro"
|
||||
" USING (reserve_out_serial_id)"
|
||||
" JOIN reserves"
|
||||
" USING (reserve_uuid)"
|
||||
" USING (reserve_pub)"
|
||||
" JOIN known_coins coins"
|
||||
" USING (known_coin_id)"
|
||||
" JOIN denominations denoms"
|
||||
@ -1744,7 +1722,7 @@ prepare_statements (struct PostgresClosure *pg)
|
||||
" reserves.reserve_pub"
|
||||
" FROM reserves_out"
|
||||
" JOIN reserves"
|
||||
" USING (reserve_uuid)"
|
||||
" USING (reserve_pub)"
|
||||
" WHERE h_blind_ev=$1"
|
||||
" LIMIT 1;",
|
||||
1),
|
||||
@ -1952,10 +1930,7 @@ prepare_statements (struct PostgresClosure *pg)
|
||||
" amount_with_fee_val"
|
||||
",amount_with_fee_frac"
|
||||
" FROM reserves_out"
|
||||
" WHERE reserve_uuid="
|
||||
" (SELECT reserve_uuid"
|
||||
" FROM reserves"
|
||||
" WHERE reserve_pub=$1)"
|
||||
" WHERE reserve_pub=$1"
|
||||
" AND execution_date > $2;",
|
||||
2),
|
||||
/* used in #postgres_lookup_wire_fee_by_time() */
|
||||
@ -2199,7 +2174,7 @@ prepare_statements (struct PostgresClosure *pg)
|
||||
"select_above_serial_by_table_reserves_in",
|
||||
"SELECT"
|
||||
" reserve_in_serial_id AS serial"
|
||||
",reserve_uuid"
|
||||
",reserve_pub"
|
||||
",wire_reference"
|
||||
",credit_val"
|
||||
",credit_frac"
|
||||
@ -2214,7 +2189,7 @@ prepare_statements (struct PostgresClosure *pg)
|
||||
"select_above_serial_by_table_reserves_close",
|
||||
"SELECT"
|
||||
" close_uuid AS serial"
|
||||
",reserve_uuid"
|
||||
",reserve_pub"
|
||||
",execution_date"
|
||||
",wtid"
|
||||
",wire_target_serial_id"
|
||||
@ -2233,7 +2208,7 @@ prepare_statements (struct PostgresClosure *pg)
|
||||
",h_blind_ev"
|
||||
",denominations_serial"
|
||||
",denom_sig"
|
||||
",reserve_uuid"
|
||||
",reserve_pub"
|
||||
",reserve_sig"
|
||||
",execution_date"
|
||||
",amount_with_fee_val"
|
||||
@ -2504,7 +2479,7 @@ prepare_statements (struct PostgresClosure *pg)
|
||||
",wire_source_serial_id"
|
||||
",exchange_account_section"
|
||||
",execution_date"
|
||||
",reserve_uuid"
|
||||
",reserve_pub"
|
||||
") VALUES "
|
||||
"($1, $2, $3, $4, $5, $6, $7, $8);",
|
||||
8),
|
||||
@ -2519,7 +2494,7 @@ prepare_statements (struct PostgresClosure *pg)
|
||||
",amount_frac"
|
||||
",closing_fee_val"
|
||||
",closing_fee_frac"
|
||||
",reserve_uuid"
|
||||
",reserve_pub"
|
||||
") VALUES "
|
||||
"($1, $2, $3, $4, $5, $6, $7, $8, $9);",
|
||||
9),
|
||||
@ -2530,7 +2505,7 @@ prepare_statements (struct PostgresClosure *pg)
|
||||
",h_blind_ev"
|
||||
",denominations_serial"
|
||||
",denom_sig"
|
||||
",reserve_uuid"
|
||||
",reserve_pub"
|
||||
",reserve_sig"
|
||||
",execution_date"
|
||||
",amount_with_fee_val"
|
||||
@ -3246,8 +3221,8 @@ postgres_get_denomination_info (
|
||||
rs);
|
||||
if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs)
|
||||
return qs;
|
||||
issue->properties.purpose.size = htonl (sizeof (struct
|
||||
TALER_DenominationKeyValidityPS));
|
||||
issue->properties.purpose.size
|
||||
= htonl (sizeof (struct TALER_DenominationKeyValidityPS));
|
||||
issue->properties.purpose.purpose = htonl (
|
||||
TALER_SIGNATURE_MASTER_DENOMINATION_KEY_VALIDITY);
|
||||
issue->properties.denom_hash = *denom_pub_hash;
|
||||
@ -4249,41 +4224,21 @@ postgres_reserves_in_insert (void *cls,
|
||||
return qs3;
|
||||
}
|
||||
GNUNET_assert (0 != kyc.payment_target_uuid);
|
||||
if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs1)
|
||||
{
|
||||
/* We do not have the UUID, so insert by public key */
|
||||
struct GNUNET_PQ_QueryParam params[] = {
|
||||
GNUNET_PQ_query_param_auto_from_type (&reserve.pub),
|
||||
GNUNET_PQ_query_param_uint64 (&wire_ref),
|
||||
TALER_PQ_query_param_amount (balance),
|
||||
GNUNET_PQ_query_param_string (exchange_account_section),
|
||||
GNUNET_PQ_query_param_uint64 (&kyc.payment_target_uuid),
|
||||
GNUNET_PQ_query_param_timestamp (&execution_time),
|
||||
GNUNET_PQ_query_param_end
|
||||
};
|
||||
/* We do not have the UUID, so insert by public key */
|
||||
struct GNUNET_PQ_QueryParam params[] = {
|
||||
GNUNET_PQ_query_param_auto_from_type (&reserve.pub),
|
||||
GNUNET_PQ_query_param_uint64 (&wire_ref),
|
||||
TALER_PQ_query_param_amount (balance),
|
||||
GNUNET_PQ_query_param_string (exchange_account_section),
|
||||
GNUNET_PQ_query_param_uint64 (&kyc.payment_target_uuid),
|
||||
GNUNET_PQ_query_param_timestamp (&execution_time),
|
||||
GNUNET_PQ_query_param_end
|
||||
};
|
||||
|
||||
qs2 = GNUNET_PQ_eval_prepared_non_select (pg->conn,
|
||||
"reserves_in_add_transaction",
|
||||
params);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We do have the UUID, use that for the insert */
|
||||
struct GNUNET_PQ_QueryParam params[] = {
|
||||
GNUNET_PQ_query_param_uint64 (&reserve_uuid),
|
||||
GNUNET_PQ_query_param_uint64 (&wire_ref),
|
||||
TALER_PQ_query_param_amount (balance),
|
||||
GNUNET_PQ_query_param_string (exchange_account_section),
|
||||
GNUNET_PQ_query_param_uint64 (&kyc.payment_target_uuid),
|
||||
GNUNET_PQ_query_param_timestamp (&execution_time),
|
||||
GNUNET_PQ_query_param_end
|
||||
};
|
||||
|
||||
qs2 = GNUNET_PQ_eval_prepared_non_select (pg->conn,
|
||||
"reserves_in_add_by_uuid",
|
||||
params);
|
||||
}
|
||||
/* qs2 could be 0 as both statements used 'ON CONFLICT DO NOTHING' */
|
||||
qs2 = GNUNET_PQ_eval_prepared_non_select (pg->conn,
|
||||
"reserves_in_add_transaction",
|
||||
params);
|
||||
/* qs2 could be 0 as statement used 'ON CONFLICT DO NOTHING' */
|
||||
if (0 >= qs2)
|
||||
{
|
||||
if ( (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs2) &&
|
||||
@ -4558,7 +4513,6 @@ postgres_do_check_coin_balance (
|
||||
* @param[out] found set to true if the reserve was found
|
||||
* @param[out] balance_ok set to true if the balance was sufficient
|
||||
* @param[out] kyc_ok set to true if the kyc status of the reserve is satisfied
|
||||
* @param[out] reserve_uuid set to the UUID of the reserve
|
||||
* @return query execution status
|
||||
*/
|
||||
static enum GNUNET_DB_QueryStatus
|
||||
@ -4568,8 +4522,7 @@ postgres_do_withdraw (
|
||||
struct GNUNET_TIME_Timestamp now,
|
||||
bool *found,
|
||||
bool *balance_ok,
|
||||
struct TALER_EXCHANGEDB_KycStatus *kyc,
|
||||
uint64_t *reserve_uuid)
|
||||
struct TALER_EXCHANGEDB_KycStatus *kyc)
|
||||
{
|
||||
struct PostgresClosure *pg = cls;
|
||||
struct GNUNET_TIME_Timestamp gc;
|
||||
@ -4591,8 +4544,6 @@ postgres_do_withdraw (
|
||||
balance_ok),
|
||||
GNUNET_PQ_result_spec_bool ("kyc_ok",
|
||||
&kyc->ok),
|
||||
GNUNET_PQ_result_spec_uint64 ("reserve_uuid",
|
||||
reserve_uuid),
|
||||
GNUNET_PQ_result_spec_uint64 ("payment_target_uuid",
|
||||
&kyc->payment_target_uuid),
|
||||
GNUNET_PQ_result_spec_end
|
||||
@ -4624,14 +4575,14 @@ postgres_do_withdraw (
|
||||
static enum GNUNET_DB_QueryStatus
|
||||
postgres_do_withdraw_limit_check (
|
||||
void *cls,
|
||||
uint64_t reserve_uuid,
|
||||
const struct TALER_ReservePublicKeyP *reserve_pub,
|
||||
struct GNUNET_TIME_Absolute withdraw_start,
|
||||
const struct TALER_Amount *upper_limit,
|
||||
bool *below_limit)
|
||||
{
|
||||
struct PostgresClosure *pg = cls;
|
||||
struct GNUNET_PQ_QueryParam params[] = {
|
||||
GNUNET_PQ_query_param_uint64 (&reserve_uuid),
|
||||
GNUNET_PQ_query_param_auto_from_type (reserve_pub),
|
||||
GNUNET_PQ_query_param_absolute_time (&withdraw_start),
|
||||
TALER_PQ_query_param_amount (upper_limit),
|
||||
GNUNET_PQ_query_param_end
|
||||
|
@ -238,23 +238,26 @@ create_denom_key_pair (unsigned int size,
|
||||
sizeof (struct TALER_EXCHANGEDB_DenominationKey));
|
||||
dki.denom_pub = dkp->pub;
|
||||
dki.issue.properties.start = GNUNET_TIME_timestamp_hton (now);
|
||||
dki.issue.properties.expire_withdraw = GNUNET_TIME_timestamp_hton
|
||||
(GNUNET_TIME_absolute_to_timestamp
|
||||
(GNUNET_TIME_absolute_add (
|
||||
now.abs_time,
|
||||
GNUNET_TIME_UNIT_HOURS)));
|
||||
dki.issue.properties.expire_deposit = GNUNET_TIME_timestamp_hton (
|
||||
GNUNET_TIME_absolute_to_timestamp
|
||||
(GNUNET_TIME_absolute_add
|
||||
(now.abs_time,
|
||||
GNUNET_TIME_relative_multiply (
|
||||
GNUNET_TIME_UNIT_HOURS, 2))));
|
||||
dki.issue.properties.expire_legal = GNUNET_TIME_timestamp_hton (
|
||||
GNUNET_TIME_absolute_to_timestamp
|
||||
(GNUNET_TIME_absolute_add
|
||||
(now.abs_time,
|
||||
GNUNET_TIME_relative_multiply (
|
||||
GNUNET_TIME_UNIT_HOURS, 3))));
|
||||
dki.issue.properties.expire_withdraw
|
||||
= GNUNET_TIME_timestamp_hton
|
||||
(GNUNET_TIME_absolute_to_timestamp
|
||||
(GNUNET_TIME_absolute_add (
|
||||
now.abs_time,
|
||||
GNUNET_TIME_UNIT_HOURS)));
|
||||
dki.issue.properties.expire_deposit
|
||||
= GNUNET_TIME_timestamp_hton (
|
||||
GNUNET_TIME_absolute_to_timestamp
|
||||
(GNUNET_TIME_absolute_add
|
||||
(now.abs_time,
|
||||
GNUNET_TIME_relative_multiply (
|
||||
GNUNET_TIME_UNIT_HOURS, 2))));
|
||||
dki.issue.properties.expire_legal
|
||||
= GNUNET_TIME_timestamp_hton (
|
||||
GNUNET_TIME_absolute_to_timestamp
|
||||
(GNUNET_TIME_absolute_add
|
||||
(now.abs_time,
|
||||
GNUNET_TIME_relative_multiply (
|
||||
GNUNET_TIME_UNIT_HOURS, 3))));
|
||||
TALER_amount_hton (&dki.issue.properties.value, value);
|
||||
TALER_amount_hton (&dki.issue.properties.fee_withdraw, fee_withdraw);
|
||||
TALER_amount_hton (&dki.issue.properties.fee_deposit, fee_deposit);
|
||||
@ -276,6 +279,8 @@ create_denom_key_pair (unsigned int size,
|
||||
destroy_denom_key_pair (dkp);
|
||||
return NULL;
|
||||
}
|
||||
memset (&issue2, 0, sizeof (issue2));
|
||||
plugin->commit (plugin->cls);
|
||||
if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
|
||||
plugin->get_denomination_info (plugin->cls,
|
||||
&dki.issue.properties.denom_hash,
|
||||
@ -1669,7 +1674,6 @@ run (void *cls)
|
||||
bool found;
|
||||
bool balance_ok;
|
||||
struct TALER_EXCHANGEDB_KycStatus kyc;
|
||||
uint64_t ruuid;
|
||||
|
||||
FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
|
||||
plugin->do_withdraw (plugin->cls,
|
||||
@ -1677,8 +1681,7 @@ run (void *cls)
|
||||
now,
|
||||
&found,
|
||||
&balance_ok,
|
||||
&kyc,
|
||||
&ruuid));
|
||||
&kyc));
|
||||
GNUNET_assert (found);
|
||||
GNUNET_assert (balance_ok);
|
||||
GNUNET_assert (! kyc.ok);
|
||||
|
@ -518,6 +518,30 @@ struct TALER_CoinPubHash
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief Value that uniquely identifies a tip.
|
||||
*/
|
||||
struct TALER_TipIdentifierP
|
||||
{
|
||||
/**
|
||||
* The tip identifier is a SHA-512 hash code.
|
||||
*/
|
||||
struct GNUNET_HashCode hash;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief Value that uniquely identifies a tip pick up operation.
|
||||
*/
|
||||
struct TALER_PickupIdentifierP
|
||||
{
|
||||
/**
|
||||
* The pickup identifier is a SHA-512 hash code.
|
||||
*/
|
||||
struct GNUNET_HashCode hash;
|
||||
};
|
||||
|
||||
|
||||
GNUNET_NETWORK_STRUCT_END
|
||||
|
||||
|
||||
@ -1738,6 +1762,63 @@ TALER_wallet_link_verify (
|
||||
const struct TALER_CoinSpendPublicKeyP *old_coin_pub,
|
||||
const struct TALER_CoinSpendSignatureP *coin_sig);
|
||||
|
||||
|
||||
/**
|
||||
* Sign link data.
|
||||
*
|
||||
* @param h_denom_pub hash of the denomiantion public key of the new coin
|
||||
* @param transfer_pub transfer public key
|
||||
* @param coin_ev coin envelope
|
||||
* @param coin_ev_size number of bytes in @a coin_ev
|
||||
* @param old_coin_priv private key to sign with
|
||||
* @param[out] coin_sig resulting signature
|
||||
*/
|
||||
void
|
||||
TALER_wallet_link_sign (const struct TALER_DenominationHash *h_denom_pub,
|
||||
const struct TALER_TransferPublicKeyP *transfer_pub,
|
||||
const void *coin_ev,
|
||||
size_t coin_ev_size,
|
||||
const struct TALER_CoinSpendPrivateKeyP *old_coin_priv,
|
||||
struct TALER_CoinSpendSignatureP *coin_sig);
|
||||
|
||||
|
||||
/**
|
||||
* Verify recoup signature.
|
||||
*
|
||||
* @param h_denom_pub hash of the denomiantion public key of the coin
|
||||
* @param coin_bks blinding factor used when withdrawing the coin
|
||||
* @param requested_amount amount that is left to be recouped
|
||||
* @param coin_pub coin key of the coin to be recouped
|
||||
* @param coin_sig resulting signature
|
||||
* @return #GNUNET_OK if the signature is valid
|
||||
*/
|
||||
enum GNUNET_GenericReturnValue
|
||||
TALER_wallet_recoup_verify (
|
||||
const struct TALER_DenominationHash *h_denom_pub,
|
||||
const union TALER_DenominationBlindingKeyP *coin_bks,
|
||||
const struct TALER_Amount *requested_amount,
|
||||
const struct TALER_CoinSpendPublicKeyP *coin_pub,
|
||||
const struct TALER_CoinSpendSignatureP *coin_sig);
|
||||
|
||||
|
||||
/**
|
||||
* Create recoup signature.
|
||||
*
|
||||
* @param h_denom_pub hash of the denomiantion public key of the coin
|
||||
* @param coin_bks blinding factor used when withdrawing the coin
|
||||
* @param requested_amount amount that is left to be recouped
|
||||
* @param coin_priv coin key of the coin to be recouped
|
||||
* @param coin_sig resulting signature
|
||||
*/
|
||||
void
|
||||
TALER_wallet_recoup_sign (
|
||||
const struct TALER_DenominationHash *h_denom_pub,
|
||||
const union TALER_DenominationBlindingKeyP *coin_bks,
|
||||
const struct TALER_Amount *requested_amount,
|
||||
const struct TALER_CoinSpendPrivateKeyP *coin_priv,
|
||||
struct TALER_CoinSpendSignatureP *coin_sig);
|
||||
|
||||
|
||||
/* ********************* offline signing ************************** */
|
||||
|
||||
|
||||
|
@ -239,12 +239,12 @@ struct TALER_EXCHANGEDB_TableData
|
||||
uint64_t sender_account;
|
||||
char *exchange_account_section;
|
||||
struct GNUNET_TIME_Timestamp execution_date;
|
||||
uint64_t reserve_uuid;
|
||||
struct TALER_ReservePublicKeyP reserve_pub;
|
||||
} reserves_in;
|
||||
|
||||
struct
|
||||
{
|
||||
uint64_t reserve_uuid;
|
||||
struct TALER_ReservePublicKeyP reserve_pub;
|
||||
struct GNUNET_TIME_Timestamp execution_date;
|
||||
struct TALER_WireTransferIdentifierRawP wtid;
|
||||
uint64_t wire_target_serial_id;
|
||||
@ -257,7 +257,7 @@ struct TALER_EXCHANGEDB_TableData
|
||||
struct TALER_BlindedCoinHash h_blind_ev;
|
||||
uint64_t denominations_serial;
|
||||
struct TALER_BlindedDenominationSignature denom_sig;
|
||||
uint64_t reserve_uuid;
|
||||
struct TALER_ReservePublicKeyP reserve_pub;
|
||||
struct TALER_ReserveSignatureP reserve_sig;
|
||||
struct GNUNET_TIME_Timestamp execution_date;
|
||||
struct TALER_Amount amount_with_fee;
|
||||
@ -2537,7 +2537,6 @@ struct TALER_EXCHANGEDB_Plugin
|
||||
* @param[out] found set to true if the reserve was found
|
||||
* @param[out] balance_ok set to true if the balance was sufficient
|
||||
* @param[out] kyc set to the KYC status of the reserve
|
||||
* @param[out] reserve_uuid set to the UUID of the reserve
|
||||
* @return query execution status
|
||||
*/
|
||||
enum GNUNET_DB_QueryStatus
|
||||
@ -2547,8 +2546,7 @@ struct TALER_EXCHANGEDB_Plugin
|
||||
struct GNUNET_TIME_Timestamp now,
|
||||
bool *found,
|
||||
bool *balance_ok,
|
||||
struct TALER_EXCHANGEDB_KycStatus *kyc_ok,
|
||||
uint64_t *reserve_uuid);
|
||||
struct TALER_EXCHANGEDB_KycStatus *kyc_ok);
|
||||
|
||||
|
||||
/**
|
||||
@ -2556,7 +2554,7 @@ struct TALER_EXCHANGEDB_Plugin
|
||||
* checks after withdraw operation.
|
||||
*
|
||||
* @param cls the `struct PostgresClosure` with the plugin-specific state
|
||||
* @param reserve_uuid reserve to check
|
||||
* @param reserve_pub reserve to check
|
||||
* @param withdraw_start starting point to accumulate from
|
||||
* @param upper_limit maximum amount allowed
|
||||
* @param[out] below_limit set to true if the limit was not exceeded
|
||||
@ -2565,7 +2563,7 @@ struct TALER_EXCHANGEDB_Plugin
|
||||
enum GNUNET_DB_QueryStatus
|
||||
(*do_withdraw_limit_check)(
|
||||
void *cls,
|
||||
uint64_t reserve_uuid,
|
||||
const struct TALER_ReservePublicKeyP *reserve_pub,
|
||||
struct GNUNET_TIME_Absolute withdraw_start,
|
||||
const struct TALER_Amount *upper_limit,
|
||||
bool *below_limit);
|
||||
|
@ -1496,11 +1496,6 @@ struct TALER_RecoupRequestPS
|
||||
*/
|
||||
struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
|
||||
|
||||
/**
|
||||
* Public key of the coin to be refunded.
|
||||
*/
|
||||
struct TALER_CoinSpendPublicKeyP coin_pub;
|
||||
|
||||
/**
|
||||
* Hash of the (revoked) denomination public key of the coin.
|
||||
*/
|
||||
@ -1510,6 +1505,12 @@ struct TALER_RecoupRequestPS
|
||||
* Blinding factor that was used to withdraw the coin.
|
||||
*/
|
||||
union TALER_DenominationBlindingKeyP coin_blind;
|
||||
|
||||
/**
|
||||
* How much of the coin's value will be recouped?
|
||||
*/
|
||||
struct TALER_AmountNBO recoup_amount;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -688,17 +688,16 @@ TALER_EXCHANGE_verify_coin_history (
|
||||
.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP),
|
||||
.coin_pub = *coin_pub
|
||||
};
|
||||
struct TALER_RecoupRequestPS rr = {
|
||||
.purpose.size = htonl (sizeof (pc)),
|
||||
.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_RECOUP),
|
||||
.coin_pub = *coin_pub
|
||||
};
|
||||
union TALER_DenominationBlindingKeyP coin_bks;
|
||||
struct TALER_Amount recoup_amount;
|
||||
struct TALER_ExchangePublicKeyP exchange_pub;
|
||||
struct TALER_ExchangeSignatureP exchange_sig;
|
||||
struct TALER_CoinSpendSignatureP coin_sig;
|
||||
struct GNUNET_JSON_Specification spec[] = {
|
||||
TALER_JSON_spec_amount_any_nbo ("amount",
|
||||
&pc.recoup_amount),
|
||||
TALER_JSON_spec_amount_any ("amount",
|
||||
&recoup_amount),
|
||||
GNUNET_JSON_spec_fixed_auto ("exchange_sig",
|
||||
&exchange_sig),
|
||||
GNUNET_JSON_spec_fixed_auto ("exchange_pub",
|
||||
@ -708,9 +707,9 @@ TALER_EXCHANGE_verify_coin_history (
|
||||
GNUNET_JSON_spec_fixed_auto ("coin_sig",
|
||||
&coin_sig),
|
||||
GNUNET_JSON_spec_fixed_auto ("coin_blind",
|
||||
&rr.coin_blind),
|
||||
&coin_bks),
|
||||
GNUNET_JSON_spec_fixed_auto ("h_denom_pub",
|
||||
&rr.h_denom_pub),
|
||||
h_denom_pub),
|
||||
GNUNET_JSON_spec_timestamp_nbo ("timestamp",
|
||||
&pc.timestamp),
|
||||
GNUNET_JSON_spec_end ()
|
||||
@ -736,15 +735,15 @@ TALER_EXCHANGE_verify_coin_history (
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
if (GNUNET_OK !=
|
||||
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_RECOUP,
|
||||
&rr,
|
||||
&coin_sig.eddsa_signature,
|
||||
&coin_pub->eddsa_pub))
|
||||
TALER_wallet_recoup_verify (h_denom_pub,
|
||||
&coin_bks,
|
||||
&recoup_amount,
|
||||
coin_pub,
|
||||
&coin_sig))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
*h_denom_pub = rr.h_denom_pub;
|
||||
add = GNUNET_YES;
|
||||
}
|
||||
else if (0 == strcasecmp (type,
|
||||
@ -758,17 +757,16 @@ TALER_EXCHANGE_verify_coin_history (
|
||||
TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_REFRESH),
|
||||
.coin_pub = *coin_pub
|
||||
};
|
||||
struct TALER_RecoupRequestPS rr = {
|
||||
.purpose.size = htonl (sizeof (pc)),
|
||||
.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_RECOUP),
|
||||
.coin_pub = *coin_pub
|
||||
};
|
||||
union TALER_DenominationBlindingKeyP coin_bks;
|
||||
struct TALER_Amount recoup_amount;
|
||||
struct TALER_ExchangePublicKeyP exchange_pub;
|
||||
struct TALER_ExchangeSignatureP exchange_sig;
|
||||
struct TALER_CoinSpendSignatureP coin_sig;
|
||||
struct GNUNET_JSON_Specification spec[] = {
|
||||
TALER_JSON_spec_amount_any_nbo ("amount",
|
||||
&pc.recoup_amount),
|
||||
TALER_JSON_spec_amount_any ("amount",
|
||||
&recoup_amount),
|
||||
GNUNET_JSON_spec_fixed_auto ("exchange_sig",
|
||||
&exchange_sig),
|
||||
GNUNET_JSON_spec_fixed_auto ("exchange_pub",
|
||||
@ -778,9 +776,9 @@ TALER_EXCHANGE_verify_coin_history (
|
||||
GNUNET_JSON_spec_fixed_auto ("old_coin_pub",
|
||||
&pc.old_coin_pub),
|
||||
GNUNET_JSON_spec_fixed_auto ("coin_blind",
|
||||
&rr.coin_blind),
|
||||
&coin_bks),
|
||||
GNUNET_JSON_spec_fixed_auto ("h_denom_pub",
|
||||
&rr.h_denom_pub),
|
||||
h_denom_pub),
|
||||
GNUNET_JSON_spec_timestamp_nbo ("timestamp",
|
||||
&pc.timestamp),
|
||||
GNUNET_JSON_spec_end ()
|
||||
@ -807,15 +805,15 @@ TALER_EXCHANGE_verify_coin_history (
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
if (GNUNET_OK !=
|
||||
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_RECOUP,
|
||||
&rr,
|
||||
&coin_sig.eddsa_signature,
|
||||
&coin_pub->eddsa_pub))
|
||||
TALER_wallet_recoup_verify (h_denom_pub,
|
||||
&coin_bks,
|
||||
&recoup_amount,
|
||||
coin_pub,
|
||||
&coin_sig))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
*h_denom_pub = rr.h_denom_pub;
|
||||
add = GNUNET_YES;
|
||||
}
|
||||
else if (0 == strcasecmp (type,
|
||||
|
@ -95,7 +95,7 @@ struct TALER_EXCHANGE_RecoupHandle
|
||||
* @return #GNUNET_OK if the signature is valid and we called the callback;
|
||||
* #GNUNET_SYSERR if not (callback must still be called)
|
||||
*/
|
||||
static int
|
||||
static enum GNUNET_GenericReturnValue
|
||||
process_recoup_response (const struct TALER_EXCHANGE_RecoupHandle *ph,
|
||||
const json_t *json)
|
||||
{
|
||||
@ -312,8 +312,8 @@ TALER_EXCHANGE_recoup (struct TALER_EXCHANGE_Handle *exchange,
|
||||
{
|
||||
struct TALER_EXCHANGE_RecoupHandle *ph;
|
||||
struct GNUNET_CURL_Context *ctx;
|
||||
struct TALER_RecoupRequestPS pr;
|
||||
struct TALER_CoinSpendSignatureP coin_sig;
|
||||
struct TALER_CoinSpendPublicKeyP coin_pub;
|
||||
struct TALER_DenominationHash h_denom_pub;
|
||||
json_t *recoup_obj;
|
||||
CURL *eh;
|
||||
@ -321,17 +321,15 @@ TALER_EXCHANGE_recoup (struct TALER_EXCHANGE_Handle *exchange,
|
||||
|
||||
GNUNET_assert (GNUNET_YES ==
|
||||
TEAH_handle_is_ready (exchange));
|
||||
pr.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_RECOUP);
|
||||
pr.purpose.size = htonl (sizeof (struct TALER_RecoupRequestPS));
|
||||
GNUNET_CRYPTO_eddsa_key_get_public (&ps->coin_priv.eddsa_priv,
|
||||
&pr.coin_pub.eddsa_pub);
|
||||
&coin_pub.eddsa_pub);
|
||||
TALER_denom_pub_hash (&pk->key,
|
||||
&h_denom_pub);
|
||||
pr.h_denom_pub = pk->h_key;
|
||||
pr.coin_blind = ps->blinding_key;
|
||||
GNUNET_CRYPTO_eddsa_sign (&ps->coin_priv.eddsa_priv,
|
||||
&pr,
|
||||
&coin_sig.eddsa_signature);
|
||||
TALER_wallet_recoup_sign (&h_denom_pub,
|
||||
&ps->blinding_key,
|
||||
amount,
|
||||
&ps->coin_priv,
|
||||
&coin_sig);
|
||||
recoup_obj = GNUNET_JSON_PACK (
|
||||
GNUNET_JSON_pack_data_auto ("denom_pub_hash",
|
||||
&h_denom_pub),
|
||||
@ -349,11 +347,11 @@ TALER_EXCHANGE_recoup (struct TALER_EXCHANGE_Handle *exchange,
|
||||
char pub_str[sizeof (struct TALER_CoinSpendPublicKeyP) * 2];
|
||||
char *end;
|
||||
|
||||
end = GNUNET_STRINGS_data_to_string (&pr.coin_pub,
|
||||
sizeof (struct
|
||||
TALER_CoinSpendPublicKeyP),
|
||||
pub_str,
|
||||
sizeof (pub_str));
|
||||
end = GNUNET_STRINGS_data_to_string (
|
||||
&coin_pub,
|
||||
sizeof (struct TALER_CoinSpendPublicKeyP),
|
||||
pub_str,
|
||||
sizeof (pub_str));
|
||||
*end = '\0';
|
||||
GNUNET_snprintf (arg_str,
|
||||
sizeof (arg_str),
|
||||
@ -362,7 +360,7 @@ TALER_EXCHANGE_recoup (struct TALER_EXCHANGE_Handle *exchange,
|
||||
}
|
||||
|
||||
ph = GNUNET_new (struct TALER_EXCHANGE_RecoupHandle);
|
||||
ph->coin_pub = pr.coin_pub;
|
||||
ph->coin_pub = coin_pub;
|
||||
ph->exchange = exchange;
|
||||
ph->pk = *pk;
|
||||
memset (&ph->pk.key,
|
||||
|
@ -855,7 +855,7 @@ run (void *cls,
|
||||
MHD_HTTP_OK,
|
||||
"recoup-withdraw-coin-2a",
|
||||
NULL,
|
||||
NULL),
|
||||
"EUR:0.5"),
|
||||
TALER_TESTING_cmd_deposit ("recoup-deposit-revoked",
|
||||
"recoup-withdraw-coin-2b",
|
||||
0,
|
||||
|
@ -139,7 +139,7 @@ run (void *cls,
|
||||
MHD_HTTP_GONE,
|
||||
"refresh-reveal-1#0",
|
||||
"refresh-melt-1",
|
||||
NULL),
|
||||
"EUR:0.1"),
|
||||
/* Make refreshed coin invalid */
|
||||
TALER_TESTING_cmd_revoke ("revoke-2-EUR:5",
|
||||
MHD_HTTP_OK,
|
||||
@ -155,44 +155,44 @@ run (void *cls,
|
||||
MHD_HTTP_CONFLICT,
|
||||
"withdraw-revocation-coin-2",
|
||||
NULL,
|
||||
NULL),
|
||||
"EUR:0.1"),
|
||||
/* Refund coin to original coin */
|
||||
TALER_TESTING_cmd_recoup ("recoup-1a",
|
||||
MHD_HTTP_OK,
|
||||
"refresh-reveal-1#0",
|
||||
"refresh-melt-1",
|
||||
NULL),
|
||||
"EUR:1"),
|
||||
TALER_TESTING_cmd_recoup ("recoup-1b",
|
||||
MHD_HTTP_OK,
|
||||
"refresh-reveal-1#1",
|
||||
"refresh-melt-1",
|
||||
NULL),
|
||||
"EUR:1"),
|
||||
TALER_TESTING_cmd_recoup ("recoup-1c",
|
||||
MHD_HTTP_OK,
|
||||
"refresh-reveal-1#2",
|
||||
"refresh-melt-1",
|
||||
NULL),
|
||||
"EUR:1"),
|
||||
/* Repeat recoup to test idempotency */
|
||||
TALER_TESTING_cmd_recoup ("recoup-1c",
|
||||
MHD_HTTP_OK,
|
||||
"refresh-reveal-1#2",
|
||||
"refresh-melt-1",
|
||||
NULL),
|
||||
"EUR:1"),
|
||||
TALER_TESTING_cmd_recoup ("recoup-1c",
|
||||
MHD_HTTP_OK,
|
||||
"refresh-reveal-1#2",
|
||||
"refresh-melt-1",
|
||||
NULL),
|
||||
"EUR:1"),
|
||||
TALER_TESTING_cmd_recoup ("recoup-1c",
|
||||
MHD_HTTP_OK,
|
||||
"refresh-reveal-1#2",
|
||||
"refresh-melt-1",
|
||||
NULL),
|
||||
"EUR:1"),
|
||||
TALER_TESTING_cmd_recoup ("recoup-1c",
|
||||
MHD_HTTP_OK,
|
||||
"refresh-reveal-1#2",
|
||||
"refresh-melt-1",
|
||||
NULL),
|
||||
"EUR:1"),
|
||||
/* Now we have EUR:3.83 EUR back after 3x EUR:1 in recoups */
|
||||
/* Melt original coin AGAIN, but only create one 0.1 EUR coin;
|
||||
This costs EUR:0.03 in refresh and EUR:01 in withdraw fees,
|
||||
@ -223,7 +223,7 @@ run (void *cls,
|
||||
MHD_HTTP_OK,
|
||||
"refresh-reveal-2",
|
||||
"refresh-melt-2",
|
||||
NULL),
|
||||
"EUR:0.1"),
|
||||
/* Due to recoup, original coin is now at EUR:3.79 */
|
||||
/* Refund original (now zombie) coin to reserve */
|
||||
TALER_TESTING_cmd_recoup ("recoup-3",
|
||||
|
@ -155,4 +155,51 @@ TALER_wallet_link_verify (
|
||||
}
|
||||
|
||||
|
||||
enum GNUNET_GenericReturnValue
|
||||
TALER_wallet_recoup_verify (
|
||||
const struct TALER_DenominationHash *h_denom_pub,
|
||||
const union TALER_DenominationBlindingKeyP *coin_bks,
|
||||
const struct TALER_Amount *requested_amount,
|
||||
const struct TALER_CoinSpendPublicKeyP *coin_pub,
|
||||
const struct TALER_CoinSpendSignatureP *coin_sig)
|
||||
{
|
||||
struct TALER_RecoupRequestPS pr = {
|
||||
.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_RECOUP),
|
||||
.purpose.size = htonl (sizeof (pr)),
|
||||
.h_denom_pub = *h_denom_pub,
|
||||
.coin_blind = *coin_bks
|
||||
};
|
||||
|
||||
TALER_amount_hton (&pr.recoup_amount,
|
||||
requested_amount);
|
||||
return GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_RECOUP,
|
||||
&pr,
|
||||
&coin_sig->eddsa_signature,
|
||||
&coin_pub->eddsa_pub);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TALER_wallet_recoup_sign (
|
||||
const struct TALER_DenominationHash *h_denom_pub,
|
||||
const union TALER_DenominationBlindingKeyP *coin_bks,
|
||||
const struct TALER_Amount *requested_amount,
|
||||
const struct TALER_CoinSpendPrivateKeyP *coin_priv,
|
||||
struct TALER_CoinSpendSignatureP *coin_sig)
|
||||
{
|
||||
struct TALER_RecoupRequestPS pr = {
|
||||
.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_RECOUP),
|
||||
.purpose.size = htonl (sizeof (struct TALER_RecoupRequestPS)),
|
||||
.h_denom_pub = *h_denom_pub,
|
||||
.coin_blind = *coin_bks
|
||||
};
|
||||
|
||||
TALER_amount_hton (&pr.recoup_amount,
|
||||
requested_amount);
|
||||
GNUNET_CRYPTO_eddsa_sign (&coin_priv->eddsa_priv,
|
||||
&pr,
|
||||
&coin_sig->eddsa_signature);
|
||||
}
|
||||
|
||||
|
||||
/* end of wallet_signatures.c */
|
||||
|
Loading…
Reference in New Issue
Block a user