exchange_do_recoup_to_reserve.sql (3626B)
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 -- When parameter names have changed, we can not REPLACE 18 -- but need to drop first 19 DROP FUNCTION IF EXISTS exchange_do_recoup_to_reserve; 20 21 CREATE FUNCTION exchange_do_recoup_to_reserve( 22 IN in_reserve_pub BYTEA, 23 IN in_withdraw_id INT8, 24 IN in_coin_blind BYTEA, 25 IN in_coin_pub BYTEA, 26 IN in_known_coin_id INT8, 27 IN in_coin_sig BYTEA, 28 IN in_reserve_gc INT8, 29 IN in_reserve_expiration INT8, 30 IN in_recoup_timestamp INT8, 31 OUT out_recoup_ok BOOLEAN, 32 OUT out_internal_failure BOOLEAN, 33 OUT out_recoup_timestamp INT8) 34 LANGUAGE plpgsql 35 AS $$ 36 DECLARE 37 tmp taler_amount; -- amount recouped 38 balance taler_amount; -- current balance of the reserve 39 new_balance taler_amount; -- new balance of the reserve 40 reserve RECORD; 41 rval RECORD; 42 BEGIN 43 -- Shards: SELECT known_coins (by coin_pub) 44 -- SELECT recoup (by coin_pub) 45 -- UPDATE known_coins (by coin_pub) 46 -- UPDATE reserves (by reserve_pub) 47 -- INSERT recoup (by coin_pub) 48 49 out_internal_failure=FALSE; 50 51 52 -- Check remaining balance of the coin. 53 SELECT 54 remaining 55 INTO 56 rval 57 FROM exchange.known_coins 58 WHERE coin_pub=in_coin_pub; 59 60 IF NOT FOUND 61 THEN 62 out_internal_failure=TRUE; 63 out_recoup_ok=FALSE; 64 RETURN; 65 END IF; 66 67 tmp := rval.remaining; 68 69 IF tmp.val + tmp.frac = 0 70 THEN 71 -- Check for idempotency 72 SELECT 73 recoup_timestamp 74 INTO 75 out_recoup_timestamp 76 FROM exchange.recoup 77 WHERE coin_pub=in_coin_pub; 78 79 out_recoup_ok=FOUND; 80 RETURN; 81 END IF; 82 83 84 -- Update balance of the coin. 85 UPDATE known_coins 86 SET 87 remaining.val = 0 88 ,remaining.frac = 0 89 WHERE coin_pub=in_coin_pub; 90 91 -- Get current balance 92 SELECT current_balance 93 INTO reserve 94 FROM reserves 95 WHERE reserve_pub=in_reserve_pub; 96 97 balance = reserve.current_balance; 98 new_balance.frac=balance.frac+tmp.frac 99 - CASE 100 WHEN balance.frac+tmp.frac >= 100000000 101 THEN 100000000 102 ELSE 0 103 END; 104 105 new_balance.val=balance.val+tmp.val 106 + CASE 107 WHEN balance.frac+tmp.frac >= 100000000 108 THEN 1 109 ELSE 0 110 END; 111 112 -- Credit the reserve and update reserve timers. 113 UPDATE reserves 114 SET 115 current_balance = new_balance, 116 gc_date=GREATEST(gc_date, in_reserve_gc), 117 expiration_date=GREATEST(expiration_date, in_reserve_expiration) 118 WHERE reserve_pub=in_reserve_pub; 119 120 121 IF NOT FOUND 122 THEN 123 RAISE NOTICE 'failed to increase reserve balance from recoup'; 124 out_recoup_ok=TRUE; 125 out_internal_failure=TRUE; 126 RETURN; 127 END IF; 128 129 130 INSERT INTO exchange.recoup 131 (coin_pub 132 ,coin_sig 133 ,coin_blind 134 ,amount 135 ,recoup_timestamp 136 ,withdraw_id 137 ) 138 VALUES 139 (in_coin_pub 140 ,in_coin_sig 141 ,in_coin_blind 142 ,tmp 143 ,in_recoup_timestamp 144 ,in_withdraw_id); 145 146 -- Normal end, everything is fine. 147 out_recoup_ok=TRUE; 148 out_recoup_timestamp=in_recoup_timestamp; 149 150 END $$; 151 152 -- COMMENT ON FUNCTION exchange_do_recoup_to_reserve(INT8, INT4, BYTEA, BOOLEAN, BOOLEAN) 153 -- IS 'Executes a recoup of a coin that was withdrawn from a reserve';