-was integrated

This commit is contained in:
Christian Grothoff 2021-12-09 23:17:15 +01:00
parent 4c8b99f333
commit 386301d1cf
No known key found for this signature in database
GPG Key ID: 939E6BE1E29FC3CC

View File

@ -1,171 +0,0 @@
-- Everything in one big transaction
-- BEGIN;
-- Check patch versioning is in place.
-- SELECT _v.register_patch('exchange-000x', NULL, NULL);
CREATE OR REPLACE FUNCTION exchange_check_coin_balance(
IN denom_val INT8, -- value of the denomination of the coin
IN denom_frac INT4, -- value of the denomination of the coin
IN in_coin_pub BYTEA, -- coin public key
IN check_recoup BOOLEAN, -- do we need to check the recoup table?
IN zombie_required BOOLEAN, -- do we need a zombie coin?
OUT balance_ok BOOLEAN, -- balance satisfied?
OUT zombie_ok BOOLEAN) -- zombie satisfied?
LANGUAGE plpgsql
AS $$
DECLARE
coin_uuid INT8; -- known_coin_id of coin_pub
DECLARE
tmp_val INT8; -- temporary result
DECLARE
tmp_frac INT8; -- temporary result
DECLARE
spent_val INT8; -- how much of coin was spent?
DECLARE
spent_frac INT8; -- how much of coin was spent?
DECLARE
unspent_val INT8; -- how much of coin was refunded?
DECLARE
unspent_frac INT8; -- how much of coin was refunded?
BEGIN
-- Note: possible future optimization: get the coin_uuid from the previous
-- 'ensure_coin_known' and pass that here instead of the coin_pub. Might help
-- a tiny bit with performance.
SELECT known_coin_id INTO coin_uuid
FROM known_coins
WHERE coin_pub=in_coin_pub;
IF NOT FOUND
THEN
-- coin unknown, should be impossible!
balance_ok=FALSE;
zombie_ok=FALSE;
ASSERT false, 'coin unknown';
RETURN;
END IF;
spent_val = 0;
spent_frac = 0;
unspent_val = denom_val;
unspent_frac = denom_frac;
SELECT
SUM(amount_with_fee_val) -- overflow here is not plausible
,SUM(CAST(amount_with_fee_frac AS INT8)) -- compute using 64 bits
INTO
tmp_val
,tmp_frac
FROM deposits
WHERE known_coin_id=coin_uuid;
spent_val = spent_val + tmp_val;
spent_frac = spent_frac + tmp_frac;
SELECT
SUM(amount_with_fee_val) -- overflow here is not plausible
,SUM(CAST(amount_with_fee_frac AS INT8)) -- compute using 64 bits
INTO
tmp_val
,tmp_frac
FROM refresh_commitments
WHERE old_known_coin_id=coin_uuid;
spent_val = spent_val + tmp_val;
spent_frac = spent_frac + tmp_frac;
SELECT
SUM(amount_with_fee_val) -- overflow here is not plausible
,SUM(CAST(amount_with_fee_frac AS INT8)) -- compute using 64 bits
INTO
tmp_val
,tmp_frac
FROM refunds
WHERE known_coin_id=coin_uuid;
unspent_val = unspent_val + tmp_val;
unspent_frac = unspent_frac + tmp_frac;
-- Note: even if 'check_recoup' is true, the tables below
-- are in practice likely empty (as they only apply if
-- the exchange (ever) had to revoke keys).
IF check_recoup
THEN
SELECT
SUM(amount_val) -- overflow here is not plausible
,SUM(CAST(amount_frac AS INT8)) -- compute using 64 bits
INTO
tmp_val
,tmp_frac
FROM recoup_refresh
WHERE known_coin_id=coin_uuid;
unspent_val = unspent_val + tmp_val;
unspent_frac = unspent_frac + tmp_frac;
SELECT
SUM(amount_val) -- overflow here is not plausible
,SUM(CAST(amount_frac AS INT8)) -- compute using 64 bits
INTO
tmp_val
,tmp_frac
FROM recoup
WHERE known_coin_id=coin_uuid;
spent_val = spent_val + tmp_val;
spent_frac = spent_frac + tmp_frac;
SELECT
SUM(amount_val) -- overflow here is not plausible
,SUM(CAST(amount_frac AS INT8)) -- compute using 64 bits
INTO
tmp_val
,tmp_frac
FROM recoup_refresh
JOIN refresh_revealed_coins rrc
USING (rrc_serial)
JOIN refresh_commitments rfc
ON (rrc.melt_serial_id = rfc.melt_serial_id)
WHERE rfc.old_known_coin_id=coin_uuid;
spent_val = spent_val + tmp_val;
spent_frac = spent_frac + tmp_frac;
IF ( (0 < tmp_val) OR (0 < tmp_frac) )
THEN
-- There was a transaction that justifies the zombie
-- status, clear the flag
zombie_required=FALSE;
END IF;
END IF;
-- Actually check if the coin balance is sufficient. Verbosely. ;-)
IF (unspent_val > spent_val)
THEN
balance_ok=TRUE;
ELSE
IF (reserve_val == amount_val) AND (reserve_frac >= amount_frac)
THEN
balance_ok=TRUE;
ELSE
balance_ok=FALSE;
END IF;
END IF;
zombie_ok = NOT zombie_required;
END $$;
COMMENT ON FUNCTION exchange_check_coin_balance(INT8, INT4, BYTEA, BOOLEAN, BOOLEAN)
IS 'Checks whether the coin has sufficient balance for all the operations associated with it';
-- Complete transaction
-- COMMIT;