Compare commits
3 Commits
5825f8b4ef
...
dbd18a36d5
Author | SHA1 | Date | |
---|---|---|---|
dbd18a36d5 | |||
93415b6a35 | |||
|
766a291151 |
@ -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 ==
|
||||
|
@ -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';
|
||||
|
Loading…
Reference in New Issue
Block a user