exchange

Base system with REST service to issue digital coins, run by the payment service provider
Log | Files | Refs | Submodules | README | LICENSE

do_recoup_refresh.sql (3744B)


      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_index INT4,
     22   IN in_coin_blind BYTEA,
     23   IN in_coin_pub BYTEA,
     24   IN in_known_coin_id INT8,
     25   IN in_coin_sig BYTEA,
     26   IN in_recoup_timestamp INT8,
     27   OUT out_recoup_ok BOOLEAN,
     28   OUT out_internal_failure BOOLEAN,
     29   OUT out_recoup_timestamp INT8,
     30   OUT out_recoup_amount taler_amount)
     31 LANGUAGE plpgsql
     32 AS $$
     33 DECLARE
     34   rval RECORD;
     35 DECLARE
     36   tmp taler_amount; -- amount recouped
     37 BEGIN
     38 
     39 -- Shards: UPDATE known_coins (by coin_pub)
     40 --         SELECT recoup_refresh (by coin_pub)
     41 --         UPDATE known_coins (by coin_pub)
     42 --         INSERT recoup_refresh (by coin_pub)
     43 
     44 out_internal_failure=FALSE;
     45 
     46 -- Check remaining balance of the coin.
     47 SELECT
     48    remaining
     49  INTO
     50    rval
     51 FROM exchange.known_coins
     52   WHERE coin_pub=in_coin_pub;
     53 
     54 IF NOT FOUND
     55 THEN
     56   out_internal_failure=TRUE;
     57   out_recoup_ok=FALSE;
     58   RETURN;
     59 END IF;
     60 
     61 tmp := rval.remaining;
     62 
     63 IF tmp.val + tmp.frac = 0
     64 THEN
     65   -- Check for idempotency: only a recoup for this very
     66   -- refresh operation and position counts, a recoup of the same
     67   -- coin for another operation means the coin has nothing left.
     68   -- The coin may have been credited again (by a refund) and
     69   -- recouped again since, so report the latest recoup.
     70   SELECT
     71        recoup_timestamp
     72       ,amount
     73     INTO
     74       rval
     75     FROM recoup_refresh
     76     WHERE coin_pub=in_coin_pub
     77       AND refresh_id=in_refresh_id
     78       AND coin_index=in_coin_index
     79     ORDER BY recoup_refresh_uuid DESC
     80     LIMIT 1;
     81   out_recoup_ok=FOUND;
     82   IF FOUND
     83   THEN
     84     out_recoup_timestamp=rval.recoup_timestamp;
     85     out_recoup_amount=rval.amount;
     86   END IF;
     87   RETURN;
     88 END IF;
     89 
     90 -- Update balance of the coin.
     91 UPDATE known_coins
     92   SET
     93      remaining.val = 0
     94     ,remaining.frac = 0
     95   WHERE coin_pub=in_coin_pub;
     96 
     97 -- Credit the old coin.
     98 UPDATE known_coins kc
     99   SET
    100     remaining.frac=(kc.remaining).frac+tmp.frac
    101        - CASE
    102          WHEN (kc.remaining).frac+tmp.frac >= 100000000
    103          THEN 100000000
    104          ELSE 0
    105          END,
    106     remaining.val=(kc.remaining).val+tmp.val
    107        + CASE
    108          WHEN (kc.remaining).frac+tmp.frac >= 100000000
    109          THEN 1
    110          ELSE 0
    111          END
    112   WHERE coin_pub=in_old_coin_pub;
    113 
    114 IF NOT FOUND
    115 THEN
    116   RAISE NOTICE 'failed to increase old coin balance from recoup';
    117   out_recoup_ok=TRUE;
    118   out_internal_failure=TRUE;
    119   RETURN;
    120 END IF;
    121 
    122 
    123 INSERT INTO recoup_refresh
    124   (coin_pub
    125   ,known_coin_id
    126   ,coin_sig
    127   ,coin_blind
    128   ,amount
    129   ,recoup_timestamp
    130   ,refresh_id
    131   ,coin_index
    132   )
    133 VALUES
    134   (in_coin_pub
    135   ,in_known_coin_id
    136   ,in_coin_sig
    137   ,in_coin_blind
    138   ,tmp
    139   ,in_recoup_timestamp
    140   ,in_refresh_id
    141   ,in_coin_index);
    142 
    143 -- Normal end, everything is fine.
    144 out_recoup_ok=TRUE;
    145 out_recoup_timestamp=in_recoup_timestamp;
    146 out_recoup_amount=tmp;
    147 
    148 END $$;
    149 
    150 
    151 -- COMMENT ON FUNCTION exchange_do_recoup_to_coin(INT8, INT4, BYTEA, BOOLEAN, BOOLEAN)
    152 --  IS 'Executes a recoup-refresh of a coin that was obtained from a refresh-reveal process';