exchange

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

0002-batch_deposits.sql (5782B)


      1 --
      2 -- This file is part of TALER
      3 -- Copyright (C) 2014--2023 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 FUNCTION create_table_batch_deposits(
     18   IN partition_suffix TEXT DEFAULT NULL
     19 )
     20 RETURNS VOID
     21 LANGUAGE plpgsql
     22 AS $$
     23 DECLARE
     24   table_name TEXT DEFAULT 'batch_deposits';
     25 BEGIN
     26   PERFORM create_partitioned_table(
     27     'CREATE TABLE %I'
     28       '(batch_deposit_serial_id INT8 GENERATED BY DEFAULT AS IDENTITY'
     29       ',shard INT8 NOT NULL'
     30       ',merchant_pub BYTEA NOT NULL CHECK (LENGTH(merchant_pub)=32)'
     31       ',wallet_timestamp INT8 NOT NULL'
     32       ',exchange_timestamp INT8 NOT NULL'
     33       ',refund_deadline INT8 NOT NULL'
     34       ',wire_deadline INT8 NOT NULL'
     35       ',h_contract_terms BYTEA NOT NULL CHECK (LENGTH(h_contract_terms)=64)'
     36       ',wallet_data_hash BYTEA CHECK (LENGTH(wallet_data_hash)=64) DEFAULT NULL'
     37       ',wire_salt BYTEA NOT NULL CHECK (LENGTH(wire_salt)=16)'
     38       ',wire_target_h_payto BYTEA CHECK (LENGTH(wire_target_h_payto)=32)'
     39       ',policy_details_serial_id INT8'
     40       ',policy_blocked BOOLEAN NOT NULL DEFAULT FALSE'
     41       ',total_amount taler_amount NOT NULL'
     42       ',merchant_sig BYTEA CHECK(LENGTH(merchant_sig)=64) NOT NULL'
     43       ',done BOOLEAN NOT NULL DEFAULT FALSE'
     44     ') %s ;'
     45     ,table_name
     46     ,'PARTITION BY HASH (shard)'
     47     ,partition_suffix
     48   );
     49   PERFORM comment_partitioned_table(
     50     'Information about the contracts for which we have received (batch) deposits.'
     51     ,table_name
     52     ,partition_suffix
     53   );
     54   PERFORM comment_partitioned_column(
     55      'Used for load sharding in the materialized indices. Should be set based on merchant_pub. 64-bit value because we need an *unsigned* 32-bit value.'
     56     ,'shard'
     57     ,table_name
     58     ,partition_suffix
     59   );
     60   PERFORM comment_partitioned_column(
     61      'Unsalted hash of the target bank account; also used to lookup the KYC status'
     62     ,'wire_target_h_payto'
     63     ,table_name
     64     ,partition_suffix
     65   );
     66   PERFORM comment_partitioned_column(
     67      'hash over data provided by the wallet upon payment to select a more specific contract'
     68     ,'wallet_data_hash'
     69     ,table_name
     70     ,partition_suffix
     71   );
     72   PERFORM comment_partitioned_column(
     73      'Salt used when hashing the payto://-URI to get the h_wire that was used by the coin deposit signatures; not used to calculate wire_target_h_payto (as that one is unsalted)'
     74     ,'wire_salt'
     75     ,table_name
     76     ,partition_suffix
     77   );
     78   PERFORM comment_partitioned_column(
     79      'Set to TRUE once we have included this (batch) deposit (and all associated coins) in some aggregate wire transfer to the merchant'
     80     ,'done'
     81     ,table_name
     82     ,partition_suffix
     83   );
     84   PERFORM comment_partitioned_column(
     85      'True if the aggregation of the (batch) deposit is currently blocked by some policy extension mechanism. Used to filter out deposits that must not be processed by the canonical deposit logic.'
     86     ,'policy_blocked'
     87     ,table_name
     88     ,partition_suffix
     89   );
     90   PERFORM comment_partitioned_column(
     91      'References policy extensions table, NULL if extensions are not used'
     92     ,'policy_details_serial_id'
     93     ,table_name
     94     ,partition_suffix
     95   );
     96   PERFORM comment_partitioned_column(
     97      'total amount'
     98     ,'total_amount'
     99     ,'batch_deposits'
    100     ,partition_suffix
    101   );
    102   PERFORM comment_partitioned_column(
    103      'signature by the merchant over the contract terms, of purpose TALER_SIGNATURE_MERCHANT_CONTRACT'
    104     ,'merchant_sig'
    105     ,'batch_deposits'
    106     ,partition_suffix
    107   );
    108 END
    109 $$;
    110 
    111 
    112 CREATE FUNCTION constrain_table_batch_deposits(
    113   IN partition_suffix TEXT
    114 )
    115 RETURNS void
    116 LANGUAGE plpgsql
    117 AS $$
    118 DECLARE
    119   table_name TEXT DEFAULT 'batch_deposits';
    120 BEGIN
    121   table_name = concat_ws('_', table_name, partition_suffix);
    122   EXECUTE FORMAT (
    123     'ALTER TABLE ' || table_name ||
    124     ' ADD CONSTRAINT ' || table_name || '_batch_deposit_serial_id_pkey'
    125     ' PRIMARY KEY (batch_deposit_serial_id) '
    126     ',ADD CONSTRAINT ' || table_name || '_merchant_pub_h_contract_terms'
    127     ' UNIQUE (shard, merchant_pub, h_contract_terms)'
    128   );
    129   EXECUTE FORMAT (
    130     'CREATE INDEX ' || table_name || '_by_ready '
    131     'ON ' || table_name || ' '
    132     '(shard ASC'
    133     ',wire_deadline ASC'
    134     ') WHERE NOT (done OR policy_blocked);'
    135   );
    136   EXECUTE FORMAT (
    137     'CREATE INDEX ' || table_name || '_for_matching '
    138     'ON ' || table_name || ' '
    139     '(shard ASC'
    140     ',refund_deadline ASC'
    141     ',wire_target_h_payto'
    142     ') WHERE NOT (done OR policy_blocked);'
    143   );
    144 END
    145 $$;
    146 
    147 CREATE OR REPLACE FUNCTION foreign_table_batch_deposits()
    148 RETURNS VOID
    149 LANGUAGE plpgsql
    150 AS $$
    151 DECLARE
    152   table_name TEXT DEFAULT 'batch_deposits';
    153 BEGIN
    154   EXECUTE FORMAT (
    155     'ALTER TABLE ' || table_name ||
    156     ' ADD CONSTRAINT ' || table_name || '_foreign_policy_details'
    157     ' FOREIGN KEY (policy_details_serial_id) '
    158     ' REFERENCES policy_details (policy_details_serial_id) ON DELETE RESTRICT'
    159   );
    160 END
    161 $$;
    162 
    163 
    164 INSERT INTO exchange_tables
    165     (name
    166     ,version
    167     ,action
    168     ,partitioned
    169     ,by_range)
    170   VALUES
    171     ('batch_deposits'
    172     ,'exchange-0002'
    173     ,'create'
    174     ,TRUE
    175     ,FALSE),
    176     ('batch_deposits'
    177     ,'exchange-0002'
    178     ,'constrain'
    179     ,TRUE
    180     ,FALSE),
    181     ('batch_deposits'
    182     ,'exchange-0002'
    183     ,'foreign'
    184     ,TRUE
    185     ,FALSE)
    186     ;