exchange

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

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';