From 0d0494ee9117c89faeda64baf7413dee1cee46ca Mon Sep 17 00:00:00 2001 From: Özgür Kesim Date: Fri, 28 Jul 2023 14:28:20 +0200 Subject: finalize v3/v4 -> v2 exchange schema merger --- src/exchangedb/0002-age_withdraw.sql | 156 +++++++++++++++++++++++++ src/exchangedb/0002-age_withdrawl.sql | 156 ------------------------- src/exchangedb/exchange-0003.sql.in | 24 ---- src/exchangedb/exchange_do_amount_specific.sql | 78 +++++++++++++ 4 files changed, 234 insertions(+), 180 deletions(-) create mode 100644 src/exchangedb/0002-age_withdraw.sql delete mode 100644 src/exchangedb/0002-age_withdrawl.sql delete mode 100644 src/exchangedb/exchange-0003.sql.in create mode 100644 src/exchangedb/exchange_do_amount_specific.sql diff --git a/src/exchangedb/0002-age_withdraw.sql b/src/exchangedb/0002-age_withdraw.sql new file mode 100644 index 00000000..05c0df27 --- /dev/null +++ b/src/exchangedb/0002-age_withdraw.sql @@ -0,0 +1,156 @@ +-- +-- This file is part of TALER +-- Copyright (C) 2023 Taler Systems SA +-- +-- TALER is free software; you can redistribute it and/or modify it under the +-- terms of the GNU General Public License as published by the Free Software +-- Foundation; either version 3, or (at your option) any later version. +-- +-- TALER is distributed in the hope that it will be useful, but WITHOUT ANY +-- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +-- A PARTICULAR PURPOSE. See the GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License along with +-- TALER; see the file COPYING. If not, see +-- +-- @author Özgür Kesim + +CREATE FUNCTION create_table_age_withdraw( + IN partition_suffix VARCHAR DEFAULT NULL +) +RETURNS VOID +LANGUAGE plpgsql +AS $$ +DECLARE + table_name VARCHAR DEFAULT 'age_withdraw'; +BEGIN + PERFORM create_partitioned_table( + 'CREATE TABLE %I' + '(age_withdraw_id BIGINT GENERATED BY DEFAULT AS IDENTITY' + ',h_commitment BYTEA NOT NULL CONSTRAINT h_commitment_length CHECK(LENGTH(h_commitment)=64)' + ',max_age SMALLINT NOT NULL CONSTRAINT max_age_positive CHECK(max_age>=0)' + ',amount_with_fee taler_amount NOT NULL' + ',reserve_pub BYTEA NOT NULL CONSTRAINT reserve_pub_length CHECK(LENGTH(reserve_pub)=32)' + ',reserve_sig BYTEA NOT NULL CONSTRAINT reserve_sig_length CHECK(LENGTH(reserve_sig)=64)' + ',noreveal_index SMALLINT NOT NULL CONSTRAINT noreveal_index_positive CHECK(noreveal_index>=0)' + ',h_blind_evs BYTEA[] NOT NULL CONSTRAINT h_blind_evs_length CHECK(cardinality(h_blind_evs)=cardinality(denom_serials))' + ',denom_serials INT8[] NOT NULL CONSTRAINT denom_serials_array_length CHECK(cardinality(denom_serials)=cardinality(denom_sigs))' + ',denom_sigs BYTEA[] NOT NULL CONSTRAINT denom_sigs_array_length CHECK(cardinality(denom_sigs)=cardinality(denom_serials))' + ') %s ;' + ,table_name + ,'PARTITION BY HASH (reserve_pub)' + ,partition_suffix + ); + PERFORM comment_partitioned_table( + 'Commitments made when withdrawing coins with age restriction and the gamma value chosen by the exchange. ' + 'It also contains the blindly signed coins, their signatures and denominations.' + ,table_name + ,partition_suffix + ); + PERFORM comment_partitioned_column( + 'The gamma value chosen by the exchange in the cut-and-choose protocol' + ,'noreveal_index' + ,table_name + ,partition_suffix + ); + PERFORM comment_partitioned_column( + 'The maximum age (in years) that the client commits to with this request' + ,'max_age' + ,table_name + ,partition_suffix + ); + PERFORM comment_partitioned_column( + 'Commitment made by the client, hash over the various client inputs in the cut-and-choose protocol' + ,'h_commitment' + ,table_name + ,partition_suffix + ); + PERFORM comment_partitioned_column( + 'Reference to the public key of the reserve from which the coins are going to be withdrawn' + ,'reserve_pub' + ,table_name + ,partition_suffix + ); + PERFORM comment_partitioned_column( + 'Signature of the reserve''s private key over the age-withdraw request' + ,'reserve_sig' + ,table_name + ,partition_suffix + ); + PERFORM comment_partitioned_column( + 'Array of references to the denominations' + ,'denom_serials' + ,table_name + ,partition_suffix + ); + PERFORM comment_partitioned_column( + 'Array of the blinded envelopes of the chosen fresh coins, with value as given by the denomination in the corresponding slot in denom_serials' + ,'h_blind_evs' + ,table_name + ,partition_suffix + ); + PERFORM comment_partitioned_column( + 'Array of signatures over each blinded envelope' + ,'denom_sigs' + ,table_name + ,partition_suffix + ); +END +$$; + + +CREATE FUNCTION constrain_table_age_withdraw( + IN partition_suffix VARCHAR +) +RETURNS void +LANGUAGE plpgsql +AS $$ +DECLARE + table_name VARCHAR DEFAULT 'age_withdraw'; +BEGIN + table_name = concat_ws('_', table_name, partition_suffix); + EXECUTE FORMAT ( + 'ALTER TABLE ' || table_name || + ' ADD PRIMARY KEY (h_commitment);' + ); + EXECUTE FORMAT ( + 'ALTER TABLE ' || table_name || + ' ADD CONSTRAINT ' || table_name || '_h_commitment_reserve_pub_key' + ' UNIQUE (h_commitment, reserve_pub);' + ); + EXECUTE FORMAT ( + 'ALTER TABLE ' || table_name || + ' ADD CONSTRAINT ' || table_name || '_age_withdraw_id_key' + ' UNIQUE (age_withdraw_id);' + ); +END +$$; + + +CREATE FUNCTION foreign_table_age_withdraw() +RETURNS void +LANGUAGE plpgsql +AS $$ +DECLARE + table_name VARCHAR DEFAULT 'age_withdraw'; +BEGIN + EXECUTE FORMAT ( + 'ALTER TABLE ' || table_name || + ' ADD CONSTRAINT ' || table_name || '_foreign_reserve_pub' + ' FOREIGN KEY (reserve_pub)' + ' REFERENCES reserves(reserve_pub);' -- ON DELETE CASCADE;' + ); +END +$$; + + +INSERT INTO exchange_tables + (name + ,version + ,action + ,partitioned + ,by_range) +VALUES + ('age_withdraw', 'exchange-0003', 'create', TRUE ,FALSE), + ('age_withdraw', 'exchange-0003', 'constrain',TRUE ,FALSE), + ('age_withdraw', 'exchange-0003', 'foreign', TRUE ,FALSE); diff --git a/src/exchangedb/0002-age_withdrawl.sql b/src/exchangedb/0002-age_withdrawl.sql deleted file mode 100644 index 05c0df27..00000000 --- a/src/exchangedb/0002-age_withdrawl.sql +++ /dev/null @@ -1,156 +0,0 @@ --- --- This file is part of TALER --- Copyright (C) 2023 Taler Systems SA --- --- TALER is free software; you can redistribute it and/or modify it under the --- terms of the GNU General Public License as published by the Free Software --- Foundation; either version 3, or (at your option) any later version. --- --- TALER is distributed in the hope that it will be useful, but WITHOUT ANY --- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR --- A PARTICULAR PURPOSE. See the GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License along with --- TALER; see the file COPYING. If not, see --- --- @author Özgür Kesim - -CREATE FUNCTION create_table_age_withdraw( - IN partition_suffix VARCHAR DEFAULT NULL -) -RETURNS VOID -LANGUAGE plpgsql -AS $$ -DECLARE - table_name VARCHAR DEFAULT 'age_withdraw'; -BEGIN - PERFORM create_partitioned_table( - 'CREATE TABLE %I' - '(age_withdraw_id BIGINT GENERATED BY DEFAULT AS IDENTITY' - ',h_commitment BYTEA NOT NULL CONSTRAINT h_commitment_length CHECK(LENGTH(h_commitment)=64)' - ',max_age SMALLINT NOT NULL CONSTRAINT max_age_positive CHECK(max_age>=0)' - ',amount_with_fee taler_amount NOT NULL' - ',reserve_pub BYTEA NOT NULL CONSTRAINT reserve_pub_length CHECK(LENGTH(reserve_pub)=32)' - ',reserve_sig BYTEA NOT NULL CONSTRAINT reserve_sig_length CHECK(LENGTH(reserve_sig)=64)' - ',noreveal_index SMALLINT NOT NULL CONSTRAINT noreveal_index_positive CHECK(noreveal_index>=0)' - ',h_blind_evs BYTEA[] NOT NULL CONSTRAINT h_blind_evs_length CHECK(cardinality(h_blind_evs)=cardinality(denom_serials))' - ',denom_serials INT8[] NOT NULL CONSTRAINT denom_serials_array_length CHECK(cardinality(denom_serials)=cardinality(denom_sigs))' - ',denom_sigs BYTEA[] NOT NULL CONSTRAINT denom_sigs_array_length CHECK(cardinality(denom_sigs)=cardinality(denom_serials))' - ') %s ;' - ,table_name - ,'PARTITION BY HASH (reserve_pub)' - ,partition_suffix - ); - PERFORM comment_partitioned_table( - 'Commitments made when withdrawing coins with age restriction and the gamma value chosen by the exchange. ' - 'It also contains the blindly signed coins, their signatures and denominations.' - ,table_name - ,partition_suffix - ); - PERFORM comment_partitioned_column( - 'The gamma value chosen by the exchange in the cut-and-choose protocol' - ,'noreveal_index' - ,table_name - ,partition_suffix - ); - PERFORM comment_partitioned_column( - 'The maximum age (in years) that the client commits to with this request' - ,'max_age' - ,table_name - ,partition_suffix - ); - PERFORM comment_partitioned_column( - 'Commitment made by the client, hash over the various client inputs in the cut-and-choose protocol' - ,'h_commitment' - ,table_name - ,partition_suffix - ); - PERFORM comment_partitioned_column( - 'Reference to the public key of the reserve from which the coins are going to be withdrawn' - ,'reserve_pub' - ,table_name - ,partition_suffix - ); - PERFORM comment_partitioned_column( - 'Signature of the reserve''s private key over the age-withdraw request' - ,'reserve_sig' - ,table_name - ,partition_suffix - ); - PERFORM comment_partitioned_column( - 'Array of references to the denominations' - ,'denom_serials' - ,table_name - ,partition_suffix - ); - PERFORM comment_partitioned_column( - 'Array of the blinded envelopes of the chosen fresh coins, with value as given by the denomination in the corresponding slot in denom_serials' - ,'h_blind_evs' - ,table_name - ,partition_suffix - ); - PERFORM comment_partitioned_column( - 'Array of signatures over each blinded envelope' - ,'denom_sigs' - ,table_name - ,partition_suffix - ); -END -$$; - - -CREATE FUNCTION constrain_table_age_withdraw( - IN partition_suffix VARCHAR -) -RETURNS void -LANGUAGE plpgsql -AS $$ -DECLARE - table_name VARCHAR DEFAULT 'age_withdraw'; -BEGIN - table_name = concat_ws('_', table_name, partition_suffix); - EXECUTE FORMAT ( - 'ALTER TABLE ' || table_name || - ' ADD PRIMARY KEY (h_commitment);' - ); - EXECUTE FORMAT ( - 'ALTER TABLE ' || table_name || - ' ADD CONSTRAINT ' || table_name || '_h_commitment_reserve_pub_key' - ' UNIQUE (h_commitment, reserve_pub);' - ); - EXECUTE FORMAT ( - 'ALTER TABLE ' || table_name || - ' ADD CONSTRAINT ' || table_name || '_age_withdraw_id_key' - ' UNIQUE (age_withdraw_id);' - ); -END -$$; - - -CREATE FUNCTION foreign_table_age_withdraw() -RETURNS void -LANGUAGE plpgsql -AS $$ -DECLARE - table_name VARCHAR DEFAULT 'age_withdraw'; -BEGIN - EXECUTE FORMAT ( - 'ALTER TABLE ' || table_name || - ' ADD CONSTRAINT ' || table_name || '_foreign_reserve_pub' - ' FOREIGN KEY (reserve_pub)' - ' REFERENCES reserves(reserve_pub);' -- ON DELETE CASCADE;' - ); -END -$$; - - -INSERT INTO exchange_tables - (name - ,version - ,action - ,partitioned - ,by_range) -VALUES - ('age_withdraw', 'exchange-0003', 'create', TRUE ,FALSE), - ('age_withdraw', 'exchange-0003', 'constrain',TRUE ,FALSE), - ('age_withdraw', 'exchange-0003', 'foreign', TRUE ,FALSE); diff --git a/src/exchangedb/exchange-0003.sql.in b/src/exchangedb/exchange-0003.sql.in deleted file mode 100644 index 768aa778..00000000 --- a/src/exchangedb/exchange-0003.sql.in +++ /dev/null @@ -1,24 +0,0 @@ --- --- This file is part of TALER --- Copyright (C) 2014--2022 Taler Systems SA --- --- TALER is free software; you can redistribute it and/or modify it under the --- terms of the GNU General Public License as published by the Free Software --- Foundation; either version 3, or (at your option) any later version. --- --- TALER is distributed in the hope that it will be useful, but WITHOUT ANY --- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR --- A PARTICULAR PURPOSE. See the GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License along with --- TALER; see the file COPYING. If not, see --- - -BEGIN; - -SELECT _v.register_patch('exchange-0003', NULL, NULL); -SET search_path TO exchange; - - - -COMMIT; diff --git a/src/exchangedb/exchange_do_amount_specific.sql b/src/exchangedb/exchange_do_amount_specific.sql new file mode 100644 index 00000000..c88cc851 --- /dev/null +++ b/src/exchangedb/exchange_do_amount_specific.sql @@ -0,0 +1,78 @@ +-------------------------------------------------------------- +-- Taler amounts and helper functiosn +------------------------------------------------------------- + +CREATE OR REPLACE PROCEDURE amount_normalize( + IN amount taler_amount + ,OUT normalized taler_amount +) +LANGUAGE plpgsql +AS $$ +BEGIN + normalized.val = amount.val + amount.frac / 100000000; + normalized.frac = amount.frac % 100000000; +END $$; + +COMMENT ON PROCEDURE amount_normalize + IS 'Returns the normalized amount by adding to the .val the value of (.frac / 100000000) and removing the modulus 100000000 from .frac.'; + +CREATE OR REPLACE PROCEDURE amount_add( + IN a taler_amount + ,IN b taler_amount + ,OUT sum taler_amount +) +LANGUAGE plpgsql +AS $$ +BEGIN + sum = (a.val + b.val, a.frac + b.frac); + CALL amount_normalize(sum ,sum); + + IF (sum.val > (1<<52)) + THEN + RAISE EXCEPTION 'addition overflow'; + END IF; +END $$; + +COMMENT ON PROCEDURE amount_add + IS 'Returns the normalized sum of two amounts. It raises an exception when the resulting .val is larger than 2^52'; + +CREATE OR REPLACE FUNCTION amount_left_minus_right( + IN l taler_amount + ,IN r taler_amount + ,OUT diff taler_amount + ,OUT ok BOOLEAN +) +LANGUAGE plpgsql +AS $$ +BEGIN + +IF (l.val > r.val) +THEN + ok = TRUE; + IF (l.frac >= r.frac) + THEN + diff.val = l.val - r.val; + diff.frac = l.frac - r.frac; + ELSE + diff.val = l.val - r.val - 1; + diff.frac = l.frac + 100000000 - r.frac; + END IF; +ELSE + IF (l.val = r.val) AND (l.frac >= r.frac) + THEN + diff.val = 0; + diff.frac = l.frac - r.frac; + ok = TRUE; + ELSE + diff = (-1, -1); + ok = FALSE; + END IF; +END IF; + +RETURN; +END $$; + +COMMENT ON FUNCTION amount_left_minus_right + IS 'Subtracts the right amount from the left and returns the difference and TRUE, if the left amount is larger than the right, or an invalid amount and FALSE otherwise.'; + + -- cgit v1.2.3