Compare commits

...

3 Commits

2 changed files with 28 additions and 149 deletions

View File

@ -1469,27 +1469,36 @@ run (void *cls)
{
struct TALER_PlanchetDetail pd;
struct TALER_CoinSpendPublicKeyP coin_pub;
struct TALER_AgeHash age_hash;
struct TALER_AgeHash *p_ah[2] = {NULL, &age_hash};
RND_BLK (&coin_pub);
TALER_blinding_secret_create (&bks);
GNUNET_assert (GNUNET_OK ==
TALER_denom_blind (&dkp->pub,
&bks,
NULL, /* FIXME-Oec */
&coin_pub,
&c_hash,
&pd.coin_ev,
&pd.coin_ev_size));
TALER_coin_ev_hash (pd.coin_ev,
pd.coin_ev_size,
&cbc.h_coin_envelope);
GNUNET_assert (GNUNET_OK ==
TALER_denom_sign_blinded (&cbc.sig,
&dkp->priv,
pd.coin_ev,
pd.coin_ev_size));
GNUNET_free (pd.coin_ev);
/* Call TALER_denom_blind()/TALER_denom_sign_blinded() twice, once without
* age_hash, once with age_hash */
RND_BLK (&age_hash);
for (size_t i = 0; i < sizeof(p_ah) / sizeof(p_ah[0]); i++)
{
RND_BLK (&coin_pub);
TALER_blinding_secret_create (&bks);
GNUNET_assert (GNUNET_OK ==
TALER_denom_blind (&dkp->pub,
&bks,
p_ah[i],
&coin_pub,
&c_hash,
&pd.coin_ev,
&pd.coin_ev_size));
TALER_coin_ev_hash (pd.coin_ev,
pd.coin_ev_size,
&cbc.h_coin_envelope);
GNUNET_assert (GNUNET_OK ==
TALER_denom_sign_blinded (&cbc.sig,
&dkp->priv,
pd.coin_ev,
pd.coin_ev_size));
GNUNET_free (pd.coin_ev);
}
}
cbc.reserve_pub = reserve_pub;
cbc.amount_with_fee = value;
GNUNET_assert (GNUNET_OK ==

View File

@ -1,130 +0,0 @@
CREATE OR REPLACE FUNCTION exchange_do_withdraw(
IN amount_val INT8,
IN amount_frac INT4,
IN h_denom_pub BYTEA,
IN rpub BYTEA,
IN reserve_sig BYTEA,
IN h_coin_envelope BYTEA,
IN denom_sig BYTEA,
IN now INT8,
IN min_reserve_gc INT8,
OUT reserve_found BOOLEAN,
OUT balance_ok BOOLEAN,
OUT kycok BOOLEAN,
OUT ruuid INT8,
OUT account_uuid INT8)
LANGUAGE plpgsql
AS $$
DECLARE
reserve_gc INT8;
DECLARE
denom_serial INT8;
DECLARE
reserve_val INT8;
DECLARE
reserve_frac INT4;
BEGIN
SELECT denominations_serial INTO denom_serial
FROM denominations
WHERE denom_pub_hash=h_denom_pub;
IF NOT FOUND
THEN
-- denomination unknown, should be impossible!
reserve_found=FALSE;
balance_ok=FALSE;
kycok=FALSE;
ruuid=0;
account_uuid=0;
ASSERT false, 'denomination unknown';
RETURN;
END IF;
UPDATE reserves SET
gc_date=GREATEST(gc_date, min_reserve_gc)
,current_balance_val=current_balance_val - amount_val
- CASE WHEN (current_balance_frac < amount_frac)
THEN 1
ELSE 0
END
,current_balance_frac=current_balance_frac - amount_frac
+ CASE WHEN (current_balance_frac < amount_frac)
THEN 100000000
ELSE 0
END
WHERE reserves.reserve_pub=rpub
AND ( (current_balance_val > amount_val) OR
( (current_balance_val = amount_val) AND
(current_balance_frac >= amount_frac) ) );
balance_ok=FOUND;
-- Obtain KYC status based on the last wire transfer into
-- this reserve. FIXME: likely not adequate for reserves that got P2P transfers!
SELECT
kyc_ok
,wire_source_serial_id
,reserve_uuid
INTO
kycok
,account_uuid
,ruuid
FROM reserves
JOIN reserves_in USING (reserve_uuid)
JOIN wire_targets ON (wire_source_serial_id = wire_target_serial_id)
WHERE reserves.reserve_pub=rpub
LIMIT 1; -- limit 1 should not be required (without p2p transfers)
IF NOT FOUND
THEN
-- reserve unknown
reserve_found=FALSE;
balance_ok=FALSE;
kycok=FALSE;
account_uuid=0;
RETURN;
END IF;
reserve_found=TRUE;
-- We optimistically insert, and then on conflict declare
-- the query successful due to idempotency.
INSERT INTO reserves_out
(h_blind_ev
,denominations_serial
,denom_sig
,reserve_uuid
,reserve_sig
,execution_date
,amount_with_fee_val
,amount_with_fee_frac)
VALUES
(h_coin_envelope
,denom_serial
,denom_sig
,ruuid
,reserve_sig
,now
,amount_val
,amount_frac)
ON CONFLICT DO NOTHING;
IF NOT FOUND
THEN
-- idempotent query, all constraints must be satisfied
balance_ok=TRUE;
-- rollback any potential balance update we may have made
ROLLBACK;
START TRANSACTION ISOLATION LEVEL SERIALIZABLE;
RETURN;
END IF;
END $$;
COMMENT ON FUNCTION exchange_do_withdraw(INT8, INT4, BYTEA, BYTEA, BYTEA, BYTEA, BYTEA, INT8, INT8)
IS 'Checks whether the reserve has sufficient balance for a withdraw operation (or the request is repeated and was previously approved) and if so updates the database with the result';