exchange

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

exchange_do_reserve_purse.sql (4122B)


      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 CREATE OR REPLACE FUNCTION exchange_do_reserve_purse(
     18   IN in_purse_pub BYTEA,
     19   IN in_merge_sig BYTEA,
     20   IN in_merge_timestamp INT8,
     21   IN in_reserve_expiration INT8,
     22   IN in_reserve_gc INT8,
     23   IN in_reserve_sig BYTEA,
     24   IN in_reserve_quota BOOLEAN,
     25   IN in_purse_fee taler_amount,
     26   IN in_reserve_pub BYTEA,
     27   IN in_wallet_h_payto BYTEA,
     28   OUT out_no_funds BOOLEAN,
     29   OUT out_no_reserve BOOLEAN,
     30   OUT out_conflict BOOLEAN)
     31 LANGUAGE plpgsql
     32 AS $$
     33 BEGIN
     34 
     35 -- Store purse merge signature, checks for purse_pub uniqueness
     36 INSERT INTO purse_merges
     37     (partner_serial_id
     38     ,reserve_pub
     39     ,purse_pub
     40     ,merge_sig
     41     ,merge_timestamp)
     42   VALUES
     43     (NULL
     44     ,in_reserve_pub
     45     ,in_purse_pub
     46     ,in_merge_sig
     47     ,in_merge_timestamp)
     48   ON CONFLICT DO NOTHING;
     49 
     50 IF NOT FOUND
     51 THEN
     52   -- Idempotency check: see if an identical record exists.
     53   -- Note that by checking 'merge_sig', we implicitly check
     54   -- identity over everything that the signature covers.
     55   PERFORM
     56   FROM purse_merges
     57   WHERE purse_pub=in_purse_pub
     58      AND merge_sig=in_merge_sig;
     59   IF NOT FOUND
     60   THEN
     61      -- Purse was merged, but to some other reserve. Not allowed.
     62      out_conflict=TRUE;
     63      out_no_reserve=FALSE;
     64      out_no_funds=FALSE;
     65      RETURN;
     66   END IF;
     67 
     68   -- "success"
     69   out_conflict=FALSE;
     70   out_no_funds=FALSE;
     71   out_no_reserve=FALSE;
     72   RETURN;
     73 END IF;
     74 out_conflict=FALSE;
     75 
     76 PERFORM
     77   FROM exchange.reserves
     78  WHERE reserve_pub=in_reserve_pub;
     79 
     80 out_no_reserve = NOT FOUND;
     81 
     82 IF (in_reserve_quota)
     83 THEN
     84   -- Increment active purses per reserve (and check this is allowed)
     85   IF (out_no_reserve)
     86   THEN
     87     out_no_funds=TRUE;
     88     RETURN;
     89   END IF;
     90   UPDATE exchange.reserves
     91      SET purses_active=purses_active+1
     92    WHERE reserve_pub=in_reserve_pub
     93      AND purses_active < purses_allowed;
     94   IF NOT FOUND
     95   THEN
     96     out_no_funds=TRUE;
     97     RETURN;
     98   END IF;
     99 ELSE
    100   --  UPDATE reserves balance (and check if balance is enough to pay the fee)
    101   IF (out_no_reserve)
    102   THEN
    103     IF ( (0 != in_purse_fee.val) OR
    104          (0 != in_purse_fee.frac) )
    105     THEN
    106       out_no_funds=TRUE;
    107       RETURN;
    108     END IF;
    109     INSERT INTO exchange.reserves
    110       (reserve_pub
    111       ,expiration_date
    112       ,gc_date)
    113     VALUES
    114       (in_reserve_pub
    115       ,in_reserve_expiration
    116       ,in_reserve_gc);
    117   ELSE
    118     UPDATE exchange.reserves
    119       SET
    120         current_balance.frac=(current_balance).frac-in_purse_fee.frac
    121          + CASE
    122          WHEN (current_balance).frac < in_purse_fee.frac
    123          THEN 100000000
    124          ELSE 0
    125          END,
    126        current_balance.val=(current_balance).val-in_purse_fee.val
    127          - CASE
    128          WHEN (current_balance).frac < in_purse_fee.frac
    129          THEN 1
    130          ELSE 0
    131          END
    132       WHERE reserve_pub=in_reserve_pub
    133         AND ( ((current_balance).val > in_purse_fee.val) OR
    134               ( ((current_balance).frac >= in_purse_fee.frac) AND
    135                 ((current_balance).val >= in_purse_fee.val) ) );
    136     IF NOT FOUND
    137     THEN
    138       out_no_funds=TRUE;
    139       RETURN;
    140     END IF;
    141   END IF;
    142 END IF;
    143 
    144 out_no_funds=FALSE;
    145 
    146 
    147 -- Store account merge signature.
    148 INSERT INTO account_merges
    149   (reserve_pub
    150   ,reserve_sig
    151   ,purse_pub
    152   ,wallet_h_payto)
    153   VALUES
    154   (in_reserve_pub
    155   ,in_reserve_sig
    156   ,in_purse_pub
    157   ,in_wallet_h_payto);
    158 
    159 END $$;
    160 
    161 COMMENT ON FUNCTION exchange_do_reserve_purse(BYTEA, BYTEA, INT8, INT8, INT8, BYTEA, BOOLEAN, taler_amount, BYTEA, BYTEA)
    162   IS 'Create a purse for a reserve.';