exchange_do_recoup_to_coin.sql (3121B)
1 -- 2 -- This file is part of TALER 3 -- Copyright (C) 2014--2022 Taler Systems SA 4 -- 5 -- TALER is free software; you can redistribute it and/or modify it under the 6 -- terms of the GNU General Public License as published by the Free Software 7 -- Foundation; either version 3, or (at your option) any later version. 8 -- 9 -- TALER is distributed in the hope that it will be useful, but WITHOUT ANY 10 -- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 11 -- A PARTICULAR PURPOSE. See the GNU General Public License for more details. 12 -- 13 -- You should have received a copy of the GNU General Public License along with 14 -- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> 15 -- 16 17 DROP FUNCTION IF EXISTS exchange_do_recoup_to_coin; 18 CREATE FUNCTION exchange_do_recoup_to_coin( 19 IN in_old_coin_pub BYTEA, 20 IN in_refresh_id INT8, 21 IN in_coin_blind BYTEA, 22 IN in_coin_pub BYTEA, 23 IN in_known_coin_id INT8, 24 IN in_coin_sig BYTEA, 25 IN in_recoup_timestamp INT8, 26 OUT out_recoup_ok BOOLEAN, 27 OUT out_internal_failure BOOLEAN, 28 OUT out_recoup_timestamp INT8) 29 LANGUAGE plpgsql 30 AS $$ 31 DECLARE 32 rval RECORD; 33 DECLARE 34 tmp taler_amount; -- amount recouped 35 BEGIN 36 37 -- Shards: UPDATE known_coins (by coin_pub) 38 -- SELECT recoup_refresh (by coin_pub) 39 -- UPDATE known_coins (by coin_pub) 40 -- INSERT recoup_refresh (by coin_pub) 41 42 out_internal_failure=FALSE; 43 44 -- Check remaining balance of the coin. 45 SELECT 46 remaining 47 INTO 48 rval 49 FROM exchange.known_coins 50 WHERE coin_pub=in_coin_pub; 51 52 IF NOT FOUND 53 THEN 54 out_internal_failure=TRUE; 55 out_recoup_ok=FALSE; 56 RETURN; 57 END IF; 58 59 tmp := rval.remaining; 60 61 IF tmp.val + tmp.frac = 0 62 THEN 63 -- Check for idempotency 64 SELECT 65 recoup_timestamp 66 INTO 67 out_recoup_timestamp 68 FROM recoup_refresh 69 WHERE coin_pub=in_coin_pub; 70 out_recoup_ok=FOUND; 71 RETURN; 72 END IF; 73 74 -- Update balance of the coin. 75 UPDATE known_coins 76 SET 77 remaining.val = 0 78 ,remaining.frac = 0 79 WHERE coin_pub=in_coin_pub; 80 81 -- Credit the old coin. 82 UPDATE known_coins kc 83 SET 84 remaining.frac=(kc.remaining).frac+tmp.frac 85 - CASE 86 WHEN (kc.remaining).frac+tmp.frac >= 100000000 87 THEN 100000000 88 ELSE 0 89 END, 90 remaining.val=(kc.remaining).val+tmp.val 91 + CASE 92 WHEN (kc.remaining).frac+tmp.frac >= 100000000 93 THEN 1 94 ELSE 0 95 END 96 WHERE coin_pub=in_old_coin_pub; 97 98 IF NOT FOUND 99 THEN 100 RAISE NOTICE 'failed to increase old coin balance from recoup'; 101 out_recoup_ok=TRUE; 102 out_internal_failure=TRUE; 103 RETURN; 104 END IF; 105 106 107 INSERT INTO recoup_refresh 108 (coin_pub 109 ,known_coin_id 110 ,coin_sig 111 ,coin_blind 112 ,amount 113 ,recoup_timestamp 114 ,refresh_id 115 ) 116 VALUES 117 (in_coin_pub 118 ,in_known_coin_id 119 ,in_coin_sig 120 ,in_coin_blind 121 ,tmp 122 ,in_recoup_timestamp 123 ,in_refresh_id); 124 125 -- Normal end, everything is fine. 126 out_recoup_ok=TRUE; 127 out_recoup_timestamp=in_recoup_timestamp; 128 129 END $$; 130 131 132 -- COMMENT ON FUNCTION exchange_do_recoup_to_coin(INT8, INT4, BYTEA, BOOLEAN, BOOLEAN) 133 -- IS 'Executes a recoup-refresh of a coin that was obtained from a refresh-reveal process';