add sql Makefile
This commit is contained in:
parent
11ee418801
commit
d7a252e42c
136 changed files with 75 additions and 16894 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -1 +1,3 @@
|
||||||
_build
|
_build
|
||||||
|
include/sql/*.sql
|
||||||
|
include/sql/*.sql.in
|
||||||
|
|
|
||||||
|
|
@ -1,145 +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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
CREATE FUNCTION create_table_account_merges(
|
|
||||||
IN partition_suffix TEXT DEFAULT NULL
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'account_merges';
|
|
||||||
BEGIN
|
|
||||||
PERFORM create_partitioned_table(
|
|
||||||
'CREATE TABLE IF NOT EXISTS %I '
|
|
||||||
'(account_merge_request_serial_id BIGINT GENERATED BY DEFAULT AS IDENTITY'
|
|
||||||
',reserve_pub BYTEA NOT NULL CHECK (LENGTH(reserve_pub)=32)'
|
|
||||||
',reserve_sig BYTEA NOT NULL CHECK (LENGTH(reserve_sig)=64)'
|
|
||||||
',purse_pub BYTEA NOT NULL CHECK (LENGTH(purse_pub)=32)'
|
|
||||||
',wallet_h_payto BYTEA NOT NULL CHECK (LENGTH(wallet_h_payto)=32)'
|
|
||||||
',PRIMARY KEY (purse_pub)'
|
|
||||||
') %s ;'
|
|
||||||
,table_name
|
|
||||||
,'PARTITION BY HASH (purse_pub)'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_table(
|
|
||||||
'Merge requests where a purse- and account-owner requested merging the purse into the account'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'public key of the target reserve'
|
|
||||||
,'reserve_pub'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'public key of the purse'
|
|
||||||
,'purse_pub'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'hash over the normalized (!) payto:// URI that identifies the receiving wallet'
|
|
||||||
,'wallet_h_payto'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'signature by the reserve private key affirming the merge, of type TALER_SIGNATURE_WALLET_ACCOUNT_MERGE'
|
|
||||||
,'reserve_sig'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION constrain_table_account_merges(
|
|
||||||
IN partition_suffix TEXT
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'account_merges';
|
|
||||||
BEGIN
|
|
||||||
table_name = concat_ws('_', table_name, partition_suffix);
|
|
||||||
|
|
||||||
-- Note: this index *may* be useful in
|
|
||||||
-- pg_get_reserve_history depending on how
|
|
||||||
-- smart the DB is when computing the JOIN.
|
|
||||||
-- Removing it MAY boost performance slightly, at
|
|
||||||
-- the expense of trouble if the "merge_by_reserve"
|
|
||||||
-- query planner goes off the rails. Needs benchmarking
|
|
||||||
-- to be sure.
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'CREATE INDEX ' || table_name || '_by_reserve_pub '
|
|
||||||
'ON ' || table_name || ' '
|
|
||||||
'(reserve_pub);'
|
|
||||||
);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD CONSTRAINT ' || table_name || '_account_merge_request_serial_id_key'
|
|
||||||
' UNIQUE (account_merge_request_serial_id) '
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION foreign_table_account_merges()
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'account_merges';
|
|
||||||
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'
|
|
||||||
',ADD CONSTRAINT ' || table_name || '_foreign_purse_pub'
|
|
||||||
' FOREIGN KEY (purse_pub) '
|
|
||||||
' REFERENCES purse_requests (purse_pub)'
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
INSERT INTO exchange_tables
|
|
||||||
(name
|
|
||||||
,version
|
|
||||||
,action
|
|
||||||
,partitioned
|
|
||||||
,by_range)
|
|
||||||
VALUES
|
|
||||||
('account_merges'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'create'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('account_merges'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'constrain'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('account_merges'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'foreign'
|
|
||||||
,TRUE
|
|
||||||
,FALSE);
|
|
||||||
|
|
@ -1,118 +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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
CREATE FUNCTION create_table_aggregation_tracking(
|
|
||||||
IN partition_suffix TEXT DEFAULT NULL
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'aggregation_tracking';
|
|
||||||
BEGIN
|
|
||||||
PERFORM create_partitioned_table(
|
|
||||||
'CREATE TABLE %I'
|
|
||||||
'(aggregation_serial_id BIGINT GENERATED BY DEFAULT AS IDENTITY'
|
|
||||||
',batch_deposit_serial_id INT8 PRIMARY KEY'
|
|
||||||
',wtid_raw BYTEA NOT NULL'
|
|
||||||
') %s ;'
|
|
||||||
,table_name
|
|
||||||
,'PARTITION BY HASH (batch_deposit_serial_id)'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_table(
|
|
||||||
'mapping from wire transfer identifiers (WTID) to deposits (and back)'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'identifier of the wire transfer'
|
|
||||||
,'wtid_raw'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION constrain_table_aggregation_tracking(
|
|
||||||
IN partition_suffix TEXT
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'aggregation_tracking';
|
|
||||||
BEGIN
|
|
||||||
table_name = concat_ws('_', table_name, partition_suffix);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'CREATE INDEX ' || table_name || '_by_wtid_raw_index '
|
|
||||||
'ON ' || table_name || ' '
|
|
||||||
'(wtid_raw);'
|
|
||||||
);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'COMMENT ON INDEX ' || table_name || '_by_wtid_raw_index '
|
|
||||||
'IS ' || quote_literal('for lookup_transactions') || ';'
|
|
||||||
);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD CONSTRAINT ' || table_name || '_aggregation_serial_id_key'
|
|
||||||
' UNIQUE (aggregation_serial_id) '
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION foreign_table_aggregation_tracking()
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'aggregation_tracking';
|
|
||||||
BEGIN
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD CONSTRAINT ' || table_name || '_foreign_deposit'
|
|
||||||
' FOREIGN KEY (batch_deposit_serial_id)'
|
|
||||||
' REFERENCES batch_deposits (batch_deposit_serial_id)'
|
|
||||||
' ON DELETE CASCADE'
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
INSERT INTO exchange_tables
|
|
||||||
(name
|
|
||||||
,version
|
|
||||||
,action
|
|
||||||
,partitioned
|
|
||||||
,by_range)
|
|
||||||
VALUES
|
|
||||||
('aggregation_tracking'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'create'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('aggregation_tracking'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'constrain'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('aggregation_tracking'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'foreign'
|
|
||||||
,TRUE
|
|
||||||
,FALSE);
|
|
||||||
|
|
@ -1,126 +0,0 @@
|
||||||
--
|
|
||||||
-- This file is part of TALER
|
|
||||||
-- Copyright (C) 2014--2025 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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
CREATE FUNCTION create_table_aggregation_transient(
|
|
||||||
IN shard_suffix TEXT DEFAULT NULL
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'aggregation_transient';
|
|
||||||
BEGIN
|
|
||||||
PERFORM create_partitioned_table(
|
|
||||||
'CREATE TABLE %I '
|
|
||||||
'(amount taler_amount NOT NULL'
|
|
||||||
',wire_target_h_payto BYTEA CHECK (LENGTH(wire_target_h_payto)=32)'
|
|
||||||
',merchant_pub BYTEA CHECK (LENGTH(merchant_pub)=32)'
|
|
||||||
',exchange_account_section TEXT NOT NULL'
|
|
||||||
',legitimization_requirement_serial_id INT8 NOT NULL DEFAULT(0)'
|
|
||||||
',wtid_raw BYTEA NOT NULL CHECK (LENGTH(wtid_raw)=32)'
|
|
||||||
') %s ;'
|
|
||||||
,table_name
|
|
||||||
,'PARTITION BY HASH (wire_target_h_payto)'
|
|
||||||
,shard_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_table(
|
|
||||||
'aggregations currently happening (lacking wire_out, usually because the amount is too low); this table is not replicated'
|
|
||||||
,table_name
|
|
||||||
,shard_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Sum of all of the aggregated deposits (without deposit fees)'
|
|
||||||
,'amount'
|
|
||||||
,table_name
|
|
||||||
,shard_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'public key of the merchant that authorized the deposits'
|
|
||||||
,'merchant_pub'
|
|
||||||
,table_name
|
|
||||||
,shard_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'unsalted hash of the (full) payto URI of the merchant account that should receive the funds'
|
|
||||||
,'wire_target_h_payto'
|
|
||||||
,table_name
|
|
||||||
,shard_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'identifier of the wire transfer'
|
|
||||||
,'wtid_raw'
|
|
||||||
,table_name
|
|
||||||
,shard_suffix
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
CREATE FUNCTION foreign_table_aggregation_transient()
|
|
||||||
RETURNS void
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'aggregation_transient';
|
|
||||||
BEGIN
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD CONSTRAINT ' || table_name || '_foreign_wire_target_h_payto'
|
|
||||||
' FOREIGN KEY (wire_target_h_payto) '
|
|
||||||
' REFERENCES wire_targets (wire_target_h_payto) ON DELETE RESTRICT'
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
CREATE FUNCTION constrain_table_aggregation_transient(
|
|
||||||
IN partition_suffix TEXT
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'aggregation_transient';
|
|
||||||
BEGIN
|
|
||||||
table_name = concat_ws('_', table_name, partition_suffix);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD CONSTRAINT ' || table_name || '_wire_target_h_payto_and_wtid_unique'
|
|
||||||
' UNIQUE (wire_target_h_payto,wtid_raw)'
|
|
||||||
);
|
|
||||||
END $$;
|
|
||||||
|
|
||||||
|
|
||||||
INSERT INTO exchange_tables
|
|
||||||
(name
|
|
||||||
,version
|
|
||||||
,action
|
|
||||||
,partitioned
|
|
||||||
,by_range)
|
|
||||||
VALUES
|
|
||||||
('aggregation_transient'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'create'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('aggregation_transient'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'foreign'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('aggregation_transient'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'constrain'
|
|
||||||
,TRUE
|
|
||||||
,FALSE);
|
|
||||||
|
|
@ -1,160 +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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION create_table_aml_history(
|
|
||||||
IN partition_suffix TEXT DEFAULT NULL
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'aml_history';
|
|
||||||
BEGIN
|
|
||||||
PERFORM create_partitioned_table(
|
|
||||||
'CREATE TABLE IF NOT EXISTS %I'
|
|
||||||
'(aml_history_serial_id BIGINT GENERATED BY DEFAULT AS IDENTITY'
|
|
||||||
',h_payto BYTEA CHECK (LENGTH(h_payto)=32)'
|
|
||||||
',justification TEXT NOT NULL'
|
|
||||||
',decider_pub BYTEA CHECK (LENGTH(decider_pub)=32)'
|
|
||||||
',decider_sig BYTEA CHECK (LENGTH(decider_sig)=64)'
|
|
||||||
',outcome_serial_id INT8 NOT NULL'
|
|
||||||
',kyc_attributes_hash BYTEA CHECK(LENGTH(kyc_attributes_hash)=64) DEFAULT NULL'
|
|
||||||
',kyc_attributes_serial_id INT8 DEFAULT NULL'
|
|
||||||
') %s ;'
|
|
||||||
,table_name
|
|
||||||
,'PARTITION BY HASH (h_payto)'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_table(
|
|
||||||
'AML decision history for a particular payment destination'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'hash of the payto://-URI this AML history is about'
|
|
||||||
,'h_payto'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'human-readable justification for the status change'
|
|
||||||
,'justification'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Public key of the staff member who made the AML decision'
|
|
||||||
,'decider_pub'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Signature key of the staff member affirming the AML decision; of type AML_DECISION'
|
|
||||||
,'decider_sig'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Actual outcome for the account (included in what decider_sig signs over)'
|
|
||||||
,'outcome_serial_id'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Hash of the new attributes inserted by the AML officer.'
|
|
||||||
,'kyc_attributes_hash'
|
|
||||||
,'aml_history'
|
|
||||||
,NULL
|
|
||||||
);
|
|
||||||
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Attributes inserted by the AML officer.'
|
|
||||||
,'kyc_attributes_serial_id'
|
|
||||||
,'aml_history'
|
|
||||||
,NULL
|
|
||||||
);
|
|
||||||
END $$;
|
|
||||||
|
|
||||||
COMMENT ON FUNCTION create_table_aml_history
|
|
||||||
IS 'Creates the aml_history table';
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION constrain_table_aml_history(
|
|
||||||
IN partition_suffix TEXT
|
|
||||||
)
|
|
||||||
RETURNS void
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'aml_history';
|
|
||||||
BEGIN
|
|
||||||
table_name = concat_ws('_', table_name, partition_suffix);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD CONSTRAINT ' || table_name || '_serial_key '
|
|
||||||
'UNIQUE (aml_history_serial_id)'
|
|
||||||
);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'CREATE INDEX ' || table_name || '_main_index '
|
|
||||||
'ON ' || table_name || ' '
|
|
||||||
'(h_payto);'
|
|
||||||
);
|
|
||||||
END $$;
|
|
||||||
|
|
||||||
CREATE FUNCTION foreign_table_aml_history()
|
|
||||||
RETURNS void
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'aml_history';
|
|
||||||
BEGIN
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD CONSTRAINT ' || table_name || '_legitimization_outcome'
|
|
||||||
' FOREIGN KEY (outcome_serial_id)'
|
|
||||||
' REFERENCES legitimization_outcomes (outcome_serial_id)'
|
|
||||||
);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD CONSTRAINT ' || table_name || '_foreign_key_kyc_attributes'
|
|
||||||
' FOREIGN KEY (kyc_attributes_serial_id)'
|
|
||||||
' REFERENCES kyc_attributes (kyc_attributes_serial_id)');
|
|
||||||
END $$;
|
|
||||||
|
|
||||||
|
|
||||||
INSERT INTO exchange_tables
|
|
||||||
(name
|
|
||||||
,version
|
|
||||||
,action
|
|
||||||
,partitioned
|
|
||||||
,by_range)
|
|
||||||
VALUES
|
|
||||||
('aml_history'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'create'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('aml_history'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'constrain'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('aml_history'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'foreign'
|
|
||||||
,TRUE
|
|
||||||
,FALSE);
|
|
||||||
|
|
||||||
|
|
@ -1,40 +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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
|
|
||||||
CREATE TABLE aml_staff
|
|
||||||
(aml_staff_uuid BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE
|
|
||||||
,decider_pub BYTEA PRIMARY KEY CHECK (LENGTH(decider_pub)=32)
|
|
||||||
,master_sig BYTEA CHECK (LENGTH(master_sig)=64)
|
|
||||||
,decider_name TEXT NOT NULL
|
|
||||||
,is_active BOOLEAN NOT NULL
|
|
||||||
,read_only BOOLEAN NOT NULL
|
|
||||||
,last_change INT8 NOT NULL
|
|
||||||
);
|
|
||||||
COMMENT ON TABLE aml_staff
|
|
||||||
IS 'Table with AML staff members the exchange uses or has used in the past. Entries never expire as we need to remember the last_change column indefinitely.';
|
|
||||||
COMMENT ON COLUMN aml_staff.decider_pub
|
|
||||||
IS 'Public key of the AML staff member.';
|
|
||||||
COMMENT ON COLUMN aml_staff.master_sig
|
|
||||||
IS 'The master public key signature on the AML staff member status, of type TALER_SIGNATURE_MASTER_AML_KEY.';
|
|
||||||
COMMENT ON COLUMN aml_staff.decider_name
|
|
||||||
IS 'Name of the staff member.';
|
|
||||||
COMMENT ON COLUMN aml_staff.is_active
|
|
||||||
IS 'true if we are currently supporting the use of this AML staff member.';
|
|
||||||
COMMENT ON COLUMN aml_staff.is_active
|
|
||||||
IS 'true if the member has read-only access.';
|
|
||||||
COMMENT ON COLUMN aml_staff.last_change
|
|
||||||
IS 'Latest time when active status changed. Used to detect replays of old messages.';
|
|
||||||
|
|
@ -1,32 +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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
|
|
||||||
CREATE TABLE auditor_denom_sigs
|
|
||||||
(auditor_denom_serial BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE
|
|
||||||
,auditor_uuid INT8 NOT NULL REFERENCES auditors (auditor_uuid) ON DELETE CASCADE
|
|
||||||
,denominations_serial INT8 NOT NULL REFERENCES denominations (denominations_serial) ON DELETE CASCADE
|
|
||||||
,auditor_sig BYTEA CHECK (LENGTH(auditor_sig)=64)
|
|
||||||
,PRIMARY KEY (denominations_serial, auditor_uuid)
|
|
||||||
);
|
|
||||||
COMMENT ON TABLE auditor_denom_sigs
|
|
||||||
IS 'Table with auditor signatures on exchange denomination keys.';
|
|
||||||
COMMENT ON COLUMN auditor_denom_sigs.auditor_uuid
|
|
||||||
IS 'Identifies the auditor.';
|
|
||||||
COMMENT ON COLUMN auditor_denom_sigs.denominations_serial
|
|
||||||
IS 'Denomination the signature is for.';
|
|
||||||
COMMENT ON COLUMN auditor_denom_sigs.auditor_sig
|
|
||||||
IS 'Signature of the auditor, of purpose TALER_SIGNATURE_AUDITOR_EXCHANGE_KEYS.';
|
|
||||||
|
|
@ -1,35 +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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
|
|
||||||
CREATE TABLE auditors
|
|
||||||
(auditor_uuid BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE
|
|
||||||
,auditor_pub BYTEA PRIMARY KEY CHECK (LENGTH(auditor_pub)=32)
|
|
||||||
,auditor_name TEXT NOT NULL
|
|
||||||
,auditor_url TEXT NOT NULL
|
|
||||||
,is_active BOOLEAN NOT NULL
|
|
||||||
,last_change INT8 NOT NULL
|
|
||||||
);
|
|
||||||
COMMENT ON TABLE auditors
|
|
||||||
IS 'Table with auditors the exchange uses or has used in the past. Entries never expire as we need to remember the last_change column indefinitely.';
|
|
||||||
COMMENT ON COLUMN auditors.auditor_pub
|
|
||||||
IS 'Public key of the auditor.';
|
|
||||||
COMMENT ON COLUMN auditors.auditor_url
|
|
||||||
IS 'The base URL of the auditor.';
|
|
||||||
COMMENT ON COLUMN auditors.is_active
|
|
||||||
IS 'true if we are currently supporting the use of this auditor.';
|
|
||||||
COMMENT ON COLUMN auditors.last_change
|
|
||||||
IS 'Latest time when active status changed. Used to detect replays of old messages.';
|
|
||||||
|
|
@ -1,186 +0,0 @@
|
||||||
--
|
|
||||||
-- This file is part of TALER
|
|
||||||
-- Copyright (C) 2014--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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
CREATE FUNCTION create_table_batch_deposits(
|
|
||||||
IN partition_suffix TEXT DEFAULT NULL
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'batch_deposits';
|
|
||||||
BEGIN
|
|
||||||
PERFORM create_partitioned_table(
|
|
||||||
'CREATE TABLE %I'
|
|
||||||
'(batch_deposit_serial_id INT8 GENERATED BY DEFAULT AS IDENTITY'
|
|
||||||
',shard INT8 NOT NULL'
|
|
||||||
',merchant_pub BYTEA NOT NULL CHECK (LENGTH(merchant_pub)=32)'
|
|
||||||
',wallet_timestamp INT8 NOT NULL'
|
|
||||||
',exchange_timestamp INT8 NOT NULL'
|
|
||||||
',refund_deadline INT8 NOT NULL'
|
|
||||||
',wire_deadline INT8 NOT NULL'
|
|
||||||
',h_contract_terms BYTEA NOT NULL CHECK (LENGTH(h_contract_terms)=64)'
|
|
||||||
',wallet_data_hash BYTEA CHECK (LENGTH(wallet_data_hash)=64) DEFAULT NULL'
|
|
||||||
',wire_salt BYTEA NOT NULL CHECK (LENGTH(wire_salt)=16)'
|
|
||||||
',wire_target_h_payto BYTEA CHECK (LENGTH(wire_target_h_payto)=32)'
|
|
||||||
',policy_details_serial_id INT8'
|
|
||||||
',policy_blocked BOOLEAN NOT NULL DEFAULT FALSE'
|
|
||||||
',total_amount taler_amount NOT NULL'
|
|
||||||
',merchant_sig BYTEA CHECK(LENGTH(merchant_sig)=64) NOT NULL'
|
|
||||||
',done BOOLEAN NOT NULL DEFAULT FALSE'
|
|
||||||
') %s ;'
|
|
||||||
,table_name
|
|
||||||
,'PARTITION BY HASH (shard)'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_table(
|
|
||||||
'Information about the contracts for which we have received (batch) deposits.'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'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.'
|
|
||||||
,'shard'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Unsalted hash of the target bank account; also used to lookup the KYC status'
|
|
||||||
,'wire_target_h_payto'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'hash over data provided by the wallet upon payment to select a more specific contract'
|
|
||||||
,'wallet_data_hash'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'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)'
|
|
||||||
,'wire_salt'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Set to TRUE once we have included this (batch) deposit (and all associated coins) in some aggregate wire transfer to the merchant'
|
|
||||||
,'done'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'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.'
|
|
||||||
,'policy_blocked'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'References policy extensions table, NULL if extensions are not used'
|
|
||||||
,'policy_details_serial_id'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'total amount'
|
|
||||||
,'total_amount'
|
|
||||||
,'batch_deposits'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'signature by the merchant over the contract terms, of purpose TALER_SIGNATURE_MERCHANT_CONTRACT'
|
|
||||||
,'merchant_sig'
|
|
||||||
,'batch_deposits'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION constrain_table_batch_deposits(
|
|
||||||
IN partition_suffix TEXT
|
|
||||||
)
|
|
||||||
RETURNS void
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'batch_deposits';
|
|
||||||
BEGIN
|
|
||||||
table_name = concat_ws('_', table_name, partition_suffix);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD CONSTRAINT ' || table_name || '_batch_deposit_serial_id_pkey'
|
|
||||||
' PRIMARY KEY (batch_deposit_serial_id) '
|
|
||||||
',ADD CONSTRAINT ' || table_name || '_merchant_pub_h_contract_terms'
|
|
||||||
' UNIQUE (shard, merchant_pub, h_contract_terms)'
|
|
||||||
);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'CREATE INDEX ' || table_name || '_by_ready '
|
|
||||||
'ON ' || table_name || ' '
|
|
||||||
'(shard ASC'
|
|
||||||
',wire_deadline ASC'
|
|
||||||
') WHERE NOT (done OR policy_blocked);'
|
|
||||||
);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'CREATE INDEX ' || table_name || '_for_matching '
|
|
||||||
'ON ' || table_name || ' '
|
|
||||||
'(shard ASC'
|
|
||||||
',refund_deadline ASC'
|
|
||||||
',wire_target_h_payto'
|
|
||||||
') WHERE NOT (done OR policy_blocked);'
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION foreign_table_batch_deposits()
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'batch_deposits';
|
|
||||||
BEGIN
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD CONSTRAINT ' || table_name || '_foreign_policy_details'
|
|
||||||
' FOREIGN KEY (policy_details_serial_id) '
|
|
||||||
' REFERENCES policy_details (policy_details_serial_id) ON DELETE RESTRICT'
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
INSERT INTO exchange_tables
|
|
||||||
(name
|
|
||||||
,version
|
|
||||||
,action
|
|
||||||
,partitioned
|
|
||||||
,by_range)
|
|
||||||
VALUES
|
|
||||||
('batch_deposits'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'create'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('batch_deposits'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'constrain'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('batch_deposits'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'foreign'
|
|
||||||
,TRUE
|
|
||||||
,FALSE)
|
|
||||||
;
|
|
||||||
|
|
@ -1,178 +0,0 @@
|
||||||
--
|
|
||||||
-- This file is part of TALER
|
|
||||||
-- Copyright (C) 2014--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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
CREATE FUNCTION create_table_close_requests(
|
|
||||||
IN partition_suffix TEXT DEFAULT NULL
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'close_requests';
|
|
||||||
BEGIN
|
|
||||||
PERFORM create_partitioned_table(
|
|
||||||
'CREATE TABLE %I '
|
|
||||||
'(close_request_serial_id BIGINT GENERATED BY DEFAULT AS IDENTITY'
|
|
||||||
',reserve_pub BYTEA NOT NULL CHECK (LENGTH(reserve_pub)=32)'
|
|
||||||
',close_timestamp INT8 NOT NULL'
|
|
||||||
',reserve_sig BYTEA NOT NULL CHECK (LENGTH(reserve_sig)=64)'
|
|
||||||
',close taler_amount NOT NULL'
|
|
||||||
',close_fee taler_amount NOT NULL'
|
|
||||||
',payto_uri TEXT NOT NULL'
|
|
||||||
',done BOOL NOT NULL DEFAULT(FALSE)'
|
|
||||||
',PRIMARY KEY (reserve_pub,close_timestamp)'
|
|
||||||
') %s ;'
|
|
||||||
,table_name
|
|
||||||
,'PARTITION BY HASH (reserve_pub)'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_table(
|
|
||||||
'Explicit requests by a reserve owner to close a reserve immediately'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'When the request was created by the client'
|
|
||||||
,'close_timestamp'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Signature affirming that the reserve is to be closed'
|
|
||||||
,'reserve_sig'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Balance of the reserve at the time of closing, to be wired to the associated bank account (minus the closing fee)'
|
|
||||||
,'close'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Identifies the credited bank account. Optional.'
|
|
||||||
,'payto_uri'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
END $$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION constrain_table_close_requests(
|
|
||||||
IN partition_suffix TEXT
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'close_requests';
|
|
||||||
BEGIN
|
|
||||||
table_name = concat_ws('_', table_name, partition_suffix);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'CREATE INDEX ' || table_name || '_by_close_request_uuid_index '
|
|
||||||
'ON ' || table_name || ' '
|
|
||||||
'(close_request_serial_id);'
|
|
||||||
);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'CREATE INDEX ' || table_name || '_by_close_request_done_index '
|
|
||||||
'ON ' || table_name || ' '
|
|
||||||
'(done);'
|
|
||||||
);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD CONSTRAINT ' || table_name || '_close_request_uuid_pkey'
|
|
||||||
' UNIQUE (close_request_serial_id)'
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION foreign_table_close_requests()
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'close_requests';
|
|
||||||
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
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION close_requests_insert_trigger()
|
|
||||||
RETURNS trigger
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
BEGIN
|
|
||||||
INSERT INTO reserve_history
|
|
||||||
(reserve_pub
|
|
||||||
,table_name
|
|
||||||
,serial_id)
|
|
||||||
VALUES
|
|
||||||
(NEW.reserve_pub
|
|
||||||
,'close_requests'
|
|
||||||
,NEW.close_request_serial_id);
|
|
||||||
RETURN NEW;
|
|
||||||
END $$;
|
|
||||||
COMMENT ON FUNCTION close_requests_insert_trigger()
|
|
||||||
IS 'Automatically generate reserve history entry.';
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION master_table_close_requests()
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
BEGIN
|
|
||||||
CREATE TRIGGER close_requests_on_insert
|
|
||||||
AFTER INSERT
|
|
||||||
ON close_requests
|
|
||||||
FOR EACH ROW EXECUTE FUNCTION close_requests_insert_trigger();
|
|
||||||
END $$;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
INSERT INTO exchange_tables
|
|
||||||
(name
|
|
||||||
,version
|
|
||||||
,action
|
|
||||||
,partitioned
|
|
||||||
,by_range)
|
|
||||||
VALUES
|
|
||||||
('close_requests'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'create'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('close_requests'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'constrain'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('close_requests'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'foreign'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('close_requests'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'master'
|
|
||||||
,TRUE
|
|
||||||
,FALSE);
|
|
||||||
|
|
@ -1,157 +0,0 @@
|
||||||
--
|
|
||||||
-- This file is part of TALER
|
|
||||||
-- Copyright (C) 2014--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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
CREATE FUNCTION create_table_coin_deposits(
|
|
||||||
IN partition_suffix TEXT DEFAULT NULL
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'coin_deposits';
|
|
||||||
BEGIN
|
|
||||||
PERFORM create_partitioned_table(
|
|
||||||
'CREATE TABLE %I'
|
|
||||||
'(coin_deposit_serial_id INT8 GENERATED BY DEFAULT AS IDENTITY'
|
|
||||||
',batch_deposit_serial_id INT8 NOT NULL'
|
|
||||||
',coin_pub BYTEA NOT NULL CHECK (LENGTH(coin_pub)=32)'
|
|
||||||
',coin_sig BYTEA NOT NULL CHECK (LENGTH(coin_sig)=64)'
|
|
||||||
',amount_with_fee taler_amount NOT NULL'
|
|
||||||
') %s ;'
|
|
||||||
,table_name
|
|
||||||
,'PARTITION BY HASH (coin_pub)'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_table(
|
|
||||||
'Coins which have been deposited with the respective per-coin signatures.'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Link to information about the batch deposit this coin was used for'
|
|
||||||
,'batch_deposit_serial_id'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION constrain_table_coin_deposits(
|
|
||||||
IN partition_suffix TEXT
|
|
||||||
)
|
|
||||||
RETURNS void
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'coin_deposits';
|
|
||||||
BEGIN
|
|
||||||
table_name = concat_ws('_', table_name, partition_suffix);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD CONSTRAINT ' || table_name || '_coin_deposit_serial_id_pkey'
|
|
||||||
' PRIMARY KEY (coin_deposit_serial_id) '
|
|
||||||
',ADD CONSTRAINT ' || table_name || '_unique_coin_sig'
|
|
||||||
' UNIQUE (coin_pub, coin_sig)'
|
|
||||||
);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'CREATE INDEX ' || table_name || '_by_batch '
|
|
||||||
'ON ' || table_name || ' '
|
|
||||||
'(batch_deposit_serial_id);'
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION foreign_table_coin_deposits()
|
|
||||||
RETURNS void
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'coin_deposits';
|
|
||||||
BEGIN
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD CONSTRAINT ' || table_name || '_foreign_coin_pub'
|
|
||||||
' FOREIGN KEY (coin_pub) '
|
|
||||||
' REFERENCES known_coins (coin_pub) ON DELETE CASCADE'
|
|
||||||
',ADD CONSTRAINT ' || table_name || '_foreign_batch_deposits_id'
|
|
||||||
' FOREIGN KEY (batch_deposit_serial_id) '
|
|
||||||
' REFERENCES batch_deposits (batch_deposit_serial_id) ON DELETE CASCADE'
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION coin_deposits_insert_trigger()
|
|
||||||
RETURNS trigger
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
BEGIN
|
|
||||||
INSERT INTO exchange.coin_history
|
|
||||||
(coin_pub
|
|
||||||
,table_name
|
|
||||||
,serial_id)
|
|
||||||
VALUES
|
|
||||||
(NEW.coin_pub
|
|
||||||
,'coin_deposits'
|
|
||||||
,NEW.coin_deposit_serial_id);
|
|
||||||
RETURN NEW;
|
|
||||||
END $$;
|
|
||||||
COMMENT ON FUNCTION coin_deposits_insert_trigger()
|
|
||||||
IS 'Automatically generate coin history entry.';
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION master_table_coin_deposits()
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
BEGIN
|
|
||||||
CREATE TRIGGER coin_deposits_on_insert
|
|
||||||
AFTER INSERT
|
|
||||||
ON coin_deposits
|
|
||||||
FOR EACH ROW EXECUTE FUNCTION coin_deposits_insert_trigger();
|
|
||||||
END $$;
|
|
||||||
|
|
||||||
|
|
||||||
INSERT INTO exchange_tables
|
|
||||||
(name
|
|
||||||
,version
|
|
||||||
,action
|
|
||||||
,partitioned
|
|
||||||
,by_range)
|
|
||||||
VALUES
|
|
||||||
('coin_deposits'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'create'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('coin_deposits'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'constrain'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('coin_deposits'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'foreign'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('coin_deposits'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'master'
|
|
||||||
,TRUE
|
|
||||||
,FALSE)
|
|
||||||
;
|
|
||||||
|
|
@ -1,138 +0,0 @@
|
||||||
--
|
|
||||||
-- This file is part of TALER
|
|
||||||
-- Copyright (C) 2014--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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
CREATE FUNCTION create_table_coin_history (
|
|
||||||
IN partition_suffix TEXT DEFAULT NULL
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'coin_history';
|
|
||||||
BEGIN
|
|
||||||
PERFORM create_partitioned_table(
|
|
||||||
'CREATE TABLE %I'
|
|
||||||
'(coin_history_serial_id INT8 GENERATED BY DEFAULT AS IDENTITY'
|
|
||||||
',coin_pub BYTEA NOT NULL CHECK (LENGTH(coin_pub)=32)'
|
|
||||||
',table_name TEXT NOT NULL'
|
|
||||||
',serial_id INT8 NOT NULL'
|
|
||||||
') %s ;'
|
|
||||||
,table_name
|
|
||||||
,'PARTITION BY HASH (coin_pub)'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_table(
|
|
||||||
'Links to tables with entries that affected the transaction history of a coin.'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'For which coin is this a history entry'
|
|
||||||
,'coin_pub'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'In which table is the history entry'
|
|
||||||
,'table_name'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Which is the generated serial ID of the entry in the table'
|
|
||||||
,'serial_id'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Monotonic counter, used to generate Etags for caching'
|
|
||||||
,'coin_history_serial_id'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION constrain_table_coin_history(
|
|
||||||
IN partition_suffix TEXT
|
|
||||||
)
|
|
||||||
RETURNS void
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'coin_history';
|
|
||||||
BEGIN
|
|
||||||
table_name = concat_ws('_', table_name, partition_suffix);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD CONSTRAINT ' || table_name || '_coin_history_serial_id_pkey'
|
|
||||||
' PRIMARY KEY (coin_history_serial_id) '
|
|
||||||
',ADD CONSTRAINT ' || table_name || '_coin_entry_key'
|
|
||||||
' UNIQUE (coin_pub, table_name, serial_id)'
|
|
||||||
);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'CREATE INDEX ' || table_name || '_coin_by_time'
|
|
||||||
' ON ' || table_name || ' '
|
|
||||||
'(coin_pub'
|
|
||||||
',coin_history_serial_id DESC'
|
|
||||||
');'
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION foreign_table_coin_history()
|
|
||||||
RETURNS void
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'coin_history';
|
|
||||||
BEGIN
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD CONSTRAINT ' || table_name || '_foreign_coin_pub'
|
|
||||||
' FOREIGN KEY (coin_pub) '
|
|
||||||
' REFERENCES known_coins (coin_pub) ON DELETE CASCADE'
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
INSERT INTO exchange_tables
|
|
||||||
(name
|
|
||||||
,version
|
|
||||||
,action
|
|
||||||
,partitioned
|
|
||||||
,by_range)
|
|
||||||
VALUES
|
|
||||||
('coin_history'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'create'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('coin_history'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'constrain'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('coin_history'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'foreign'
|
|
||||||
,TRUE
|
|
||||||
,FALSE)
|
|
||||||
;
|
|
||||||
|
|
@ -1,109 +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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION create_table_contracts(
|
|
||||||
IN partition_suffix TEXT DEFAULT NULL
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'contracts';
|
|
||||||
BEGIN
|
|
||||||
PERFORM create_partitioned_table(
|
|
||||||
'CREATE TABLE %I '
|
|
||||||
'(contract_serial_id BIGINT GENERATED BY DEFAULT AS IDENTITY'
|
|
||||||
',purse_pub BYTEA NOT NULL CHECK (LENGTH(purse_pub)=32)'
|
|
||||||
',pub_ckey BYTEA NOT NULL CHECK (LENGTH(pub_ckey)=32)'
|
|
||||||
',contract_sig BYTEA NOT NULL CHECK (LENGTH(contract_sig)=64)'
|
|
||||||
',e_contract BYTEA NOT NULL'
|
|
||||||
',purse_expiration INT8 NOT NULL'
|
|
||||||
',PRIMARY KEY (purse_pub)'
|
|
||||||
') %s ;'
|
|
||||||
,table_name
|
|
||||||
,'PARTITION BY HASH (purse_pub)'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_table(
|
|
||||||
'encrypted contracts associated with purses'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'public key of the purse that the contract is associated with'
|
|
||||||
,'purse_pub'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'signature over the encrypted contract by the purse contract key'
|
|
||||||
,'contract_sig'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Public ECDH key used to encrypt the contract, to be used with the purse private key for decryption'
|
|
||||||
,'pub_ckey'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'AES-GCM encrypted contract terms (contains gzip compressed JSON after decryption)'
|
|
||||||
,'e_contract'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION constrain_table_contracts(
|
|
||||||
IN partition_suffix TEXT
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'contracts';
|
|
||||||
BEGIN
|
|
||||||
table_name = concat_ws('_', table_name, partition_suffix);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD CONSTRAINT ' || table_name || '_contract_serial_id_key'
|
|
||||||
' UNIQUE (contract_serial_id) '
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
INSERT INTO exchange_tables
|
|
||||||
(name
|
|
||||||
,version
|
|
||||||
,action
|
|
||||||
,partitioned
|
|
||||||
,by_range)
|
|
||||||
VALUES
|
|
||||||
('contracts'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'create'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('contracts'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'constrain'
|
|
||||||
,TRUE
|
|
||||||
,FALSE);
|
|
||||||
|
|
@ -1,97 +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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
CREATE FUNCTION create_table_cs_nonce_locks(
|
|
||||||
partition_suffix TEXT DEFAULT NULL
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
BEGIN
|
|
||||||
PERFORM create_partitioned_table(
|
|
||||||
'CREATE TABLE %I'
|
|
||||||
'(cs_nonce_lock_serial_id BIGINT GENERATED BY DEFAULT AS IDENTITY'
|
|
||||||
',nonce BYTEA PRIMARY KEY CHECK (LENGTH(nonce)=32)'
|
|
||||||
',op_hash BYTEA NOT NULL CHECK (LENGTH(op_hash)=64)'
|
|
||||||
',max_denomination_serial INT8 NOT NULL'
|
|
||||||
') %s ;'
|
|
||||||
,'cs_nonce_locks'
|
|
||||||
,'PARTITION BY HASH (nonce)'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_table(
|
|
||||||
'ensures a Clause Schnorr client nonce is locked for use with an operation identified by a hash'
|
|
||||||
,'cs_nonce_locks'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'actual nonce submitted by the client'
|
|
||||||
,'nonce'
|
|
||||||
,'cs_nonce_locks'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'hash (RC for refresh, blind coin hash for withdraw) the nonce may be used with'
|
|
||||||
,'op_hash'
|
|
||||||
,'cs_nonce_locks'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Maximum number of a CS denomination serial the nonce could be used with, for GC'
|
|
||||||
,'max_denomination_serial'
|
|
||||||
,'cs_nonce_locks'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION constrain_table_cs_nonce_locks(
|
|
||||||
IN partition_suffix TEXT
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'cs_nonce_locks';
|
|
||||||
BEGIN
|
|
||||||
table_name = concat_ws('_', table_name, partition_suffix);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD CONSTRAINT ' || table_name || '_cs_nonce_lock_serial_id_key'
|
|
||||||
' UNIQUE (cs_nonce_lock_serial_id)'
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
INSERT INTO exchange_tables
|
|
||||||
(name
|
|
||||||
,version
|
|
||||||
,action
|
|
||||||
,partitioned
|
|
||||||
,by_range)
|
|
||||||
VALUES
|
|
||||||
('cs_nonce_locks'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'create'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('cs_nonce_locks'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'constrain'
|
|
||||||
,TRUE
|
|
||||||
,FALSE);
|
|
||||||
|
|
@ -1,23 +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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS denomination_revocations
|
|
||||||
(denom_revocations_serial_id BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE
|
|
||||||
,denominations_serial INT8 PRIMARY KEY REFERENCES denominations (denominations_serial) ON DELETE CASCADE
|
|
||||||
,master_sig BYTEA NOT NULL CHECK (LENGTH(master_sig)=64)
|
|
||||||
);
|
|
||||||
COMMENT ON TABLE denomination_revocations
|
|
||||||
IS 'remembering which denomination keys have been revoked';
|
|
||||||
|
|
@ -1,45 +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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
CREATE TABLE denominations
|
|
||||||
(denominations_serial BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE
|
|
||||||
,denom_pub_hash BYTEA PRIMARY KEY CHECK (LENGTH(denom_pub_hash)=64)
|
|
||||||
,denom_type INT4 NOT NULL DEFAULT (1) -- 1 == RSA (for now, remove default later!)
|
|
||||||
,age_mask INT4 NOT NULL DEFAULT (0)
|
|
||||||
,denom_pub BYTEA NOT NULL
|
|
||||||
,master_sig BYTEA NOT NULL CHECK (LENGTH(master_sig)=64)
|
|
||||||
,valid_from INT8 NOT NULL
|
|
||||||
,expire_withdraw INT8 NOT NULL
|
|
||||||
,expire_deposit INT8 NOT NULL
|
|
||||||
,expire_legal INT8 NOT NULL
|
|
||||||
,coin taler_amount NOT NULL
|
|
||||||
,fee_withdraw taler_amount NOT NULL
|
|
||||||
,fee_deposit taler_amount NOT NULL
|
|
||||||
,fee_refresh taler_amount NOT NULL
|
|
||||||
,fee_refund taler_amount NOT NULL
|
|
||||||
);
|
|
||||||
COMMENT ON TABLE denominations
|
|
||||||
IS 'Main denominations table. All the valid denominations the exchange knows about.';
|
|
||||||
COMMENT ON COLUMN denominations.denom_type
|
|
||||||
IS 'determines cipher type for blind signatures used with this denomination; 0 is for RSA';
|
|
||||||
COMMENT ON COLUMN denominations.age_mask
|
|
||||||
IS 'bitmask with the age restrictions that are being used for this denomination; 0 if denomination does not support the use of age restrictions';
|
|
||||||
COMMENT ON COLUMN denominations.denominations_serial
|
|
||||||
IS 'needed for exchange-auditor replication logic';
|
|
||||||
|
|
||||||
CREATE INDEX denominations_by_expire_legal_index
|
|
||||||
ON denominations
|
|
||||||
(expire_legal);
|
|
||||||
|
|
@ -1,36 +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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
CREATE TABLE exchange_sign_keys
|
|
||||||
(esk_serial BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE
|
|
||||||
,exchange_pub BYTEA PRIMARY KEY CHECK (LENGTH(exchange_pub)=32)
|
|
||||||
,master_sig BYTEA NOT NULL CHECK (LENGTH(master_sig)=64)
|
|
||||||
,valid_from INT8 NOT NULL
|
|
||||||
,expire_sign INT8 NOT NULL
|
|
||||||
,expire_legal INT8 NOT NULL
|
|
||||||
);
|
|
||||||
COMMENT ON TABLE exchange_sign_keys
|
|
||||||
IS 'Table with master public key signatures on exchange online signing keys.';
|
|
||||||
COMMENT ON COLUMN exchange_sign_keys.exchange_pub
|
|
||||||
IS 'Public online signing key of the exchange.';
|
|
||||||
COMMENT ON COLUMN exchange_sign_keys.master_sig
|
|
||||||
IS 'Signature affirming the validity of the signing key of purpose TALER_SIGNATURE_MASTER_SIGNING_KEY_VALIDITY.';
|
|
||||||
COMMENT ON COLUMN exchange_sign_keys.valid_from
|
|
||||||
IS 'Time when this online signing key will first be used to sign messages.';
|
|
||||||
COMMENT ON COLUMN exchange_sign_keys.expire_sign
|
|
||||||
IS 'Time when this online signing key will no longer be used to sign.';
|
|
||||||
COMMENT ON COLUMN exchange_sign_keys.expire_legal
|
|
||||||
IS 'Time when this online signing key legally expires.';
|
|
||||||
|
|
@ -1,27 +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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
CREATE TABLE extensions
|
|
||||||
(extension_id BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE
|
|
||||||
,name TEXT NOT NULL UNIQUE
|
|
||||||
,manifest BYTEA
|
|
||||||
);
|
|
||||||
COMMENT ON TABLE extensions
|
|
||||||
IS 'Configurations of the activated extensions';
|
|
||||||
COMMENT ON COLUMN extensions.name
|
|
||||||
IS 'Name of the extension';
|
|
||||||
COMMENT ON COLUMN extensions.manifest
|
|
||||||
IS 'Manifest of the extension as JSON-blob, maybe NULL. It contains common meta-information and extension-specific configuration.';
|
|
||||||
|
|
@ -1,37 +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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
CREATE TABLE global_fee
|
|
||||||
(global_fee_serial BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE
|
|
||||||
,start_date INT8 NOT NULL
|
|
||||||
,end_date INT8 NOT NULL
|
|
||||||
,history_fee taler_amount NOT NULL
|
|
||||||
,account_fee taler_amount NOT NULL
|
|
||||||
,purse_fee taler_amount NOT NULL
|
|
||||||
,purse_timeout INT8 NOT NULL
|
|
||||||
,history_expiration INT8 NOT NULL
|
|
||||||
,purse_account_limit INT4 NOT NULL
|
|
||||||
,master_sig BYTEA NOT NULL CHECK (LENGTH(master_sig)=64)
|
|
||||||
,PRIMARY KEY (start_date)
|
|
||||||
);
|
|
||||||
COMMENT ON TABLE global_fee
|
|
||||||
IS 'list of the global fees of this exchange, by date';
|
|
||||||
COMMENT ON COLUMN global_fee.global_fee_serial
|
|
||||||
IS 'needed for exchange-auditor replication logic';
|
|
||||||
|
|
||||||
CREATE INDEX global_fee_by_end_date_index
|
|
||||||
ON global_fee
|
|
||||||
(end_date);
|
|
||||||
|
|
@ -1,159 +0,0 @@
|
||||||
--
|
|
||||||
-- This file is part of TALER
|
|
||||||
-- Copyright (C) 2014--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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION create_table_history_requests(
|
|
||||||
IN shard_suffix TEXT DEFAULT NULL
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'history_requests';
|
|
||||||
BEGIN
|
|
||||||
PERFORM create_partitioned_table(
|
|
||||||
'CREATE TABLE %I '
|
|
||||||
'(history_request_serial_id BIGINT GENERATED BY DEFAULT AS IDENTITY'
|
|
||||||
',reserve_pub BYTEA NOT NULL CHECK (LENGTH(reserve_pub)=32)'
|
|
||||||
',request_timestamp INT8 NOT NULL'
|
|
||||||
',reserve_sig BYTEA NOT NULL CHECK (LENGTH(reserve_sig)=64)'
|
|
||||||
',history_fee taler_amount NOT NULL'
|
|
||||||
',PRIMARY KEY (reserve_pub,request_timestamp)'
|
|
||||||
') %s ;'
|
|
||||||
,table_name
|
|
||||||
,'PARTITION BY HASH (reserve_pub)'
|
|
||||||
,shard_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_table(
|
|
||||||
'Paid history requests issued by a client against a reserve'
|
|
||||||
,table_name
|
|
||||||
,shard_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'When was the history request made'
|
|
||||||
,'request_timestamp'
|
|
||||||
,table_name
|
|
||||||
,shard_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Signature approving payment for the history request'
|
|
||||||
,'reserve_sig'
|
|
||||||
,table_name
|
|
||||||
,shard_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'History fee approved by the signature'
|
|
||||||
,'history_fee'
|
|
||||||
,table_name
|
|
||||||
,shard_suffix
|
|
||||||
);
|
|
||||||
END $$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION constrain_table_history_requests(
|
|
||||||
IN partition_suffix TEXT
|
|
||||||
)
|
|
||||||
RETURNS void
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
partition_name TEXT;
|
|
||||||
BEGIN
|
|
||||||
partition_name = concat_ws('_', 'history_requests', partition_suffix);
|
|
||||||
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || partition_name ||
|
|
||||||
' ADD CONSTRAINT ' || partition_name || '_serial_id'
|
|
||||||
' UNIQUE (history_request_serial_id)'
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION foreign_table_history_requests()
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'history_requests';
|
|
||||||
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 $$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION history_requests_insert_trigger()
|
|
||||||
RETURNS trigger
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
BEGIN
|
|
||||||
INSERT INTO reserve_history
|
|
||||||
(reserve_pub
|
|
||||||
,table_name
|
|
||||||
,serial_id)
|
|
||||||
VALUES
|
|
||||||
(NEW.reserve_pub
|
|
||||||
,'history_requests'
|
|
||||||
,NEW.history_request_serial_id);
|
|
||||||
RETURN NEW;
|
|
||||||
END $$;
|
|
||||||
COMMENT ON FUNCTION history_requests_insert_trigger()
|
|
||||||
IS 'Automatically generate reserve history entry.';
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION master_table_history_requests()
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
BEGIN
|
|
||||||
CREATE TRIGGER history_requests_on_insert
|
|
||||||
AFTER INSERT
|
|
||||||
ON history_requests
|
|
||||||
FOR EACH ROW EXECUTE FUNCTION history_requests_insert_trigger();
|
|
||||||
END $$;
|
|
||||||
|
|
||||||
|
|
||||||
INSERT INTO exchange_tables
|
|
||||||
(name
|
|
||||||
,version
|
|
||||||
,action
|
|
||||||
,partitioned
|
|
||||||
,by_range)
|
|
||||||
VALUES
|
|
||||||
('history_requests'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'create'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('history_requests'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'constrain'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('history_requests'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'foreign'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('history_requests'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'master'
|
|
||||||
,TRUE
|
|
||||||
,FALSE);
|
|
||||||
|
|
@ -1,136 +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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION create_table_known_coins(
|
|
||||||
IN partition_suffix TEXT DEFAULT NULL
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT default 'known_coins';
|
|
||||||
BEGIN
|
|
||||||
PERFORM create_partitioned_table(
|
|
||||||
'CREATE TABLE %I'
|
|
||||||
'(known_coin_id BIGINT GENERATED BY DEFAULT AS IDENTITY'
|
|
||||||
',denominations_serial INT8 NOT NULL'
|
|
||||||
',coin_pub BYTEA NOT NULL PRIMARY KEY CHECK (LENGTH(coin_pub)=32)'
|
|
||||||
',age_commitment_hash BYTEA CHECK (LENGTH(age_commitment_hash)=32)'
|
|
||||||
',denom_sig BYTEA NOT NULL'
|
|
||||||
',remaining taler_amount NOT NULL DEFAULT(0,0)'
|
|
||||||
') %s ;'
|
|
||||||
,table_name
|
|
||||||
,'PARTITION BY HASH (coin_pub)'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_table(
|
|
||||||
'information about coins and their signatures, so we do not have to store the signatures more than once if a coin is involved in multiple operations'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Denomination of the coin, determines the value of the original coin and applicable fees for coin-specific operations.'
|
|
||||||
,'denominations_serial'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'EdDSA public key of the coin'
|
|
||||||
,'coin_pub'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Value of the coin that remains to be spent'
|
|
||||||
,'remaining'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Optional hash of the age commitment for age restrictions as per DD 24 (active if denom_type has the respective bit set)'
|
|
||||||
,'age_commitment_hash'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'This is the signature of the exchange that affirms that the coin is a valid coin. The specific signature type depends on denom_type of the denomination.'
|
|
||||||
,'denom_sig'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION constrain_table_known_coins(
|
|
||||||
IN partition_suffix TEXT
|
|
||||||
)
|
|
||||||
RETURNS void
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT default 'known_coins';
|
|
||||||
BEGIN
|
|
||||||
table_name = concat_ws('_', table_name, partition_suffix);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD CONSTRAINT ' || table_name || '_known_coin_id_key'
|
|
||||||
' UNIQUE (known_coin_id)'
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION foreign_table_known_coins()
|
|
||||||
RETURNS void
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT default 'known_coins';
|
|
||||||
BEGIN
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD CONSTRAINT ' || table_name || '_foreign_denominations'
|
|
||||||
' FOREIGN KEY (denominations_serial) '
|
|
||||||
' REFERENCES denominations (denominations_serial) ON DELETE CASCADE'
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
INSERT INTO exchange_tables
|
|
||||||
(name
|
|
||||||
,version
|
|
||||||
,action
|
|
||||||
,partitioned
|
|
||||||
,by_range)
|
|
||||||
VALUES
|
|
||||||
('known_coins'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'create'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('known_coins'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'constrain'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('known_coins'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'foreign'
|
|
||||||
,TRUE
|
|
||||||
,FALSE);
|
|
||||||
|
|
@ -1,27 +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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
CREATE TABLE kyc_alerts
|
|
||||||
(h_payto BYTEA PRIMARY KEY CHECK (LENGTH(h_payto)=32)
|
|
||||||
,trigger_type INT4 NOT NULL
|
|
||||||
,UNIQUE(trigger_type,h_payto)
|
|
||||||
);
|
|
||||||
COMMENT ON TABLE kyc_alerts
|
|
||||||
IS 'alerts about completed KYC events reliably notifying other components (even if they are not running)';
|
|
||||||
COMMENT ON COLUMN kyc_alerts.h_payto
|
|
||||||
IS 'hash of the normalized payto://-URI for which the KYC status changed';
|
|
||||||
COMMENT ON COLUMN kyc_alerts.trigger_type
|
|
||||||
IS 'identifies the receiver of the alert, as the same h_payto may require multiple components to be notified';
|
|
||||||
|
|
@ -1,161 +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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION create_table_kyc_attributes(
|
|
||||||
IN partition_suffix TEXT DEFAULT NULL
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'kyc_attributes';
|
|
||||||
BEGIN
|
|
||||||
PERFORM create_partitioned_table(
|
|
||||||
'CREATE TABLE IF NOT EXISTS %I'
|
|
||||||
'(kyc_attributes_serial_id BIGINT GENERATED BY DEFAULT AS IDENTITY'
|
|
||||||
',h_payto BYTEA CHECK (LENGTH(h_payto)=32)'
|
|
||||||
',collection_time INT8 NOT NULL'
|
|
||||||
',expiration_time INT8 NOT NULL'
|
|
||||||
',encrypted_attributes BYTEA NOT NULL'
|
|
||||||
',legitimization_serial INT8 NOT NULL'
|
|
||||||
',form_name TEXT DEFAULT(NULL)'
|
|
||||||
',by_aml_officer BOOL NOT NULL DEFAULT(FALSE)'
|
|
||||||
') %s ;'
|
|
||||||
,table_name
|
|
||||||
,'PARTITION BY HASH (h_payto)'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_table(
|
|
||||||
'KYC data about particular payment addresses'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'hash of payto://-URI the attributes are about'
|
|
||||||
,'h_payto'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'time when the attributes were collected by the provider'
|
|
||||||
,'collection_time'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'time when the attributes should no longer be considered validated'
|
|
||||||
,'expiration_time'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'(encrypted) JSON object (as string) with the attributes'
|
|
||||||
,'encrypted_attributes'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Reference the legitimization process for which these attributes are gathered for.'
|
|
||||||
,'legitimization_serial'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Name of the form (FORM_ID) that is captured in the attributes.'
|
|
||||||
,'form_name'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'TRUE if the attributes were submitted by an AML officer.'
|
|
||||||
,'by_aml_officer'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
END $$;
|
|
||||||
|
|
||||||
COMMENT ON FUNCTION create_table_kyc_attributes
|
|
||||||
IS 'Creates the kyc_attributes table';
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION constrain_table_kyc_attributes(
|
|
||||||
IN partition_suffix TEXT
|
|
||||||
)
|
|
||||||
RETURNS void
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'kyc_attributes';
|
|
||||||
BEGIN
|
|
||||||
table_name = concat_ws('_', table_name, partition_suffix);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD CONSTRAINT ' || table_name || '_serial_key '
|
|
||||||
'UNIQUE (kyc_attributes_serial_id)'
|
|
||||||
);
|
|
||||||
-- To search accounts
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'CREATE INDEX ' || table_name || '_h_payto_index '
|
|
||||||
'ON ' || table_name || ' '
|
|
||||||
'(h_payto);'
|
|
||||||
);
|
|
||||||
-- For garbage collection
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'CREATE INDEX ' || table_name || '_expiration_time '
|
|
||||||
'ON ' || table_name || ' '
|
|
||||||
'(expiration_time ASC);'
|
|
||||||
);
|
|
||||||
END $$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION foreign_table_kyc_attributes()
|
|
||||||
RETURNS void
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'kyc_attributes';
|
|
||||||
BEGIN
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD CONSTRAINT ' || table_name || '_foreign_legitimization_processes'
|
|
||||||
' FOREIGN KEY (legitimization_serial) '
|
|
||||||
' REFERENCES legitimization_processes (legitimization_process_serial_id)' -- ON DELETE SET NULL?
|
|
||||||
);
|
|
||||||
END $$;
|
|
||||||
|
|
||||||
|
|
||||||
INSERT INTO exchange_tables
|
|
||||||
(name
|
|
||||||
,version
|
|
||||||
,action
|
|
||||||
,partitioned
|
|
||||||
,by_range)
|
|
||||||
VALUES
|
|
||||||
('kyc_attributes'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'create'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('kyc_attributes'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'constrain'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('kyc_attributes'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'foreign'
|
|
||||||
,TRUE
|
|
||||||
,FALSE);
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
--
|
|
||||||
-- This file is part of TALER
|
|
||||||
-- Copyright (C) 2024 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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
CREATE TABLE kyc_events (
|
|
||||||
kyc_event_serial_id BIGINT GENERATED BY DEFAULT AS IDENTITY
|
|
||||||
,event_timestamp INT8 NOT NULL
|
|
||||||
,event_type TEXT NOT NULL
|
|
||||||
);
|
|
||||||
|
|
||||||
COMMENT ON TABLE kyc_events
|
|
||||||
IS 'Records of key events for statistics. Populated via triggers.';
|
|
||||||
COMMENT ON COLUMN kyc_events.event_type
|
|
||||||
IS 'Name of the event, such as account-open or sar-filed';
|
|
||||||
COMMENT ON COLUMN kyc_events.event_timestamp
|
|
||||||
IS 'When did the event occur; timestamp in rounded absolute time';
|
|
||||||
|
|
||||||
CREATE INDEX kyc_event_index
|
|
||||||
ON kyc_events(event_type,event_timestamp);
|
|
||||||
|
|
@ -1,104 +0,0 @@
|
||||||
--
|
|
||||||
-- This file is part of TALER
|
|
||||||
-- Copyright (C) 2024 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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
CREATE FUNCTION create_table_kycauths_in(
|
|
||||||
IN partition_suffix TEXT DEFAULT NULL
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT default 'kycauths_in';
|
|
||||||
BEGIN
|
|
||||||
PERFORM create_partitioned_table(
|
|
||||||
'CREATE TABLE %I'
|
|
||||||
'(kycauth_in_serial_id BIGINT GENERATED BY DEFAULT AS IDENTITY'
|
|
||||||
',account_pub BYTEA CHECK (LENGTH(account_pub)=32)'
|
|
||||||
',wire_reference INT8 NOT NULL'
|
|
||||||
',credit taler_amount NOT NULL'
|
|
||||||
',wire_source_h_payto BYTEA CHECK (LENGTH(wire_source_h_payto)=32)'
|
|
||||||
',exchange_account_section TEXT NOT NULL'
|
|
||||||
',execution_date INT8 NOT NULL'
|
|
||||||
',PRIMARY KEY(wire_source_h_payto, wire_reference)'
|
|
||||||
') %s ;'
|
|
||||||
,table_name
|
|
||||||
,'PARTITION BY HASH (wire_source_h_payto)'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_table(
|
|
||||||
'list of transfers to register a key for KYC authentication, one per incoming wire transfer'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
-- FIXME: check that the *full* payto URI is indeed the best choice here,
|
|
||||||
-- given that this is mostly used for KYC, we may prefer the normalized
|
|
||||||
-- payto URI instead! Not sure, to be checked!
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Identifies the debited bank account and KYC status by the hash over the full payto URI'
|
|
||||||
,'wire_source_h_payto'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Public key to be associated with the account.'
|
|
||||||
,'account_pub'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Amount that was transferred into the account'
|
|
||||||
,'credit'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
END $$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION constrain_table_kycauths_in(
|
|
||||||
IN partition_suffix TEXT
|
|
||||||
)
|
|
||||||
RETURNS void
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT default 'kycauths_in';
|
|
||||||
BEGIN
|
|
||||||
table_name = concat_ws('_', table_name, partition_suffix);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD CONSTRAINT ' || table_name || '_kycauth_in_serial_id_key'
|
|
||||||
' UNIQUE (kycauth_in_serial_id)'
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
INSERT INTO exchange_tables
|
|
||||||
(name
|
|
||||||
,version
|
|
||||||
,action
|
|
||||||
,partitioned
|
|
||||||
,by_range)
|
|
||||||
VALUES
|
|
||||||
('kycauths_in'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'create'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('kycauths_in'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'constrain'
|
|
||||||
,TRUE
|
|
||||||
,FALSE);
|
|
||||||
|
|
@ -1,147 +0,0 @@
|
||||||
--
|
|
||||||
-- This file is part of TALER
|
|
||||||
-- Copyright (C) 2024 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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
CREATE FUNCTION create_table_legitimization_measures(
|
|
||||||
IN partition_suffix TEXT DEFAULT NULL
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
BEGIN
|
|
||||||
PERFORM create_partitioned_table(
|
|
||||||
'CREATE TABLE %I'
|
|
||||||
'(legitimization_measure_serial_id INT8 GENERATED BY DEFAULT AS IDENTITY'
|
|
||||||
',access_token BYTEA NOT NULL CHECK (LENGTH(access_token)=32)'
|
|
||||||
',start_time INT8 NOT NULL'
|
|
||||||
',jmeasures TEXT NOT NULL'
|
|
||||||
',display_priority INT4 NOT NULL' -- DEAD?
|
|
||||||
',is_finished BOOL NOT NULL DEFAULT(FALSE)'
|
|
||||||
') %s ;'
|
|
||||||
,'legitimization_measures'
|
|
||||||
,'PARTITION BY HASH (access_token)'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_table(
|
|
||||||
'List of required legitimizations by account'
|
|
||||||
,'legitimization_measures'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'unique ID for this legitimization process at the exchange'
|
|
||||||
,'legitimization_measure_serial_id'
|
|
||||||
,'legitimization_measures'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'foreign key linking the entry to the kyc_targets table, NOT a primary key (multiple legitimizations are possible per account)'
|
|
||||||
,'access_token'
|
|
||||||
,'legitimization_measures'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Time when the measure was triggered (by decision or rule)'
|
|
||||||
,'start_time'
|
|
||||||
,'legitimization_measures'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'JSON object of type LegitimizationMeasures with KYC/AML measures for the account encoded'
|
|
||||||
,'jmeasures'
|
|
||||||
,'legitimization_measures'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Display priority of the rule that triggered this measure; if in the meantime another rule also triggers, the measure is only replaced if the new rule has a higher display priority; probably not really useful, as right now there is only ever one set of legitimization_measures active at any time, might be removed in the future'
|
|
||||||
,'display_priority'
|
|
||||||
,'legitimization_measures'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Set to TRUE if this set of measures was processed; used to avoid indexing measures that are done'
|
|
||||||
,'is_finished'
|
|
||||||
,'legitimization_measures'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION constrain_table_legitimization_measures(
|
|
||||||
IN partition_suffix TEXT
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'legitimization_measures';
|
|
||||||
BEGIN
|
|
||||||
table_name = concat_ws('_', table_name, partition_suffix);
|
|
||||||
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD CONSTRAINT ' || table_name || '_serial_id_key'
|
|
||||||
' UNIQUE (legitimization_measure_serial_id)');
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'CREATE INDEX ' || table_name || '_by_access_token'
|
|
||||||
' ON ' || table_name ||
|
|
||||||
' (access_token)'
|
|
||||||
' WHERE NOT is_finished' ||
|
|
||||||
';'
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION foreign_table_legitimization_measures()
|
|
||||||
RETURNS void
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'legitimization_measures';
|
|
||||||
BEGIN
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD CONSTRAINT ' || table_name || '_foreign_key_access_token'
|
|
||||||
' FOREIGN KEY (access_token)'
|
|
||||||
' REFERENCES wire_targets (access_token)'
|
|
||||||
' ON DELETE CASCADE');
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
INSERT INTO exchange_tables
|
|
||||||
(name
|
|
||||||
,version
|
|
||||||
,action
|
|
||||||
,partitioned
|
|
||||||
,by_range)
|
|
||||||
VALUES
|
|
||||||
('legitimization_measures'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'create'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('legitimization_measures'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'constrain'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('legitimization_measures'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'foreign'
|
|
||||||
,TRUE
|
|
||||||
,FALSE);
|
|
||||||
|
|
@ -1,162 +0,0 @@
|
||||||
--
|
|
||||||
-- This file is part of TALER
|
|
||||||
-- Copyright (C) 2024 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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
CREATE FUNCTION create_table_legitimization_outcomes(
|
|
||||||
IN partition_suffix TEXT DEFAULT NULL
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
BEGIN
|
|
||||||
PERFORM create_partitioned_table(
|
|
||||||
'CREATE TABLE %I'
|
|
||||||
'(outcome_serial_id BIGINT GENERATED BY DEFAULT AS IDENTITY'
|
|
||||||
',h_payto BYTEA NOT NULL CHECK (LENGTH(h_payto)=32)'
|
|
||||||
',decision_time INT8 NOT NULL'
|
|
||||||
',expiration_time INT8 NOT NULL'
|
|
||||||
',jproperties TEXT'
|
|
||||||
',new_measure_name TEXT'
|
|
||||||
',to_investigate BOOL NOT NULL'
|
|
||||||
',is_active BOOL NOT NULL DEFAULT(TRUE)'
|
|
||||||
',jnew_rules TEXT'
|
|
||||||
') %s ;'
|
|
||||||
,'legitimization_outcomes'
|
|
||||||
,'PARTITION BY HASH (h_payto)'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_table(
|
|
||||||
'Outcomes of legitimization processes by account'
|
|
||||||
,'legitimization_outcomes'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'unique ID for this legitimization outcome at the exchange'
|
|
||||||
,'outcome_serial_id'
|
|
||||||
,'legitimization_outcomes'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'hash of the normalized payto://-URI this outcome is about; foreign key linking the entry to the kyc_targets table, NOT a primary key (multiple outcomes are possible per account over time)'
|
|
||||||
,'h_payto'
|
|
||||||
,'legitimization_outcomes'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'when was this outcome decided, rounded timestamp'
|
|
||||||
,'decision_time'
|
|
||||||
,'legitimization_outcomes'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'space-separated list of names of measures to trigger immediately, NULL for none, prefixed with a "+" to indicate AND combination for the measures'
|
|
||||||
,'new_measure_name'
|
|
||||||
,'legitimization_outcomes'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'time when the decision expires and the expiration jnew_rules should be applied'
|
|
||||||
,'expiration_time'
|
|
||||||
,'legitimization_outcomes'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'JSON object of type AccountProperties, such as PEP status, business domain, risk assessment, etc.'
|
|
||||||
,'jproperties'
|
|
||||||
,'legitimization_outcomes'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'AML staff should investigate the activity of this account'
|
|
||||||
,'to_investigate'
|
|
||||||
,'legitimization_outcomes'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'TRUE if this is the current authoritative legitimization outcome'
|
|
||||||
,'is_active'
|
|
||||||
,'legitimization_outcomes'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'JSON object of type LegitimizationRuleSet with rules to apply to the various operation types for this account; all KYC checks should first check if active new rules for a given account exist in this table (and apply specified measures); if not, it should check the default rules to decide if a measure is required; NULL if the default rules apply'
|
|
||||||
,'jnew_rules'
|
|
||||||
,'legitimization_outcomes'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION constrain_table_legitimization_outcomes(
|
|
||||||
IN partition_suffix TEXT
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'legitimization_outcomes';
|
|
||||||
BEGIN
|
|
||||||
table_name = concat_ws('_', table_name, partition_suffix);
|
|
||||||
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'CREATE INDEX ' || table_name || '_by_target_token'
|
|
||||||
' ON ' || table_name ||
|
|
||||||
' (h_payto)'
|
|
||||||
' WHERE is_active' ||
|
|
||||||
';'
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION foreign_table_legitimization_outcomes()
|
|
||||||
RETURNS void
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'legitimization_outcomes';
|
|
||||||
BEGIN
|
|
||||||
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD CONSTRAINT ' || table_name || '_serial_id_key'
|
|
||||||
' UNIQUE (outcome_serial_id)');
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
INSERT INTO exchange_tables
|
|
||||||
(name
|
|
||||||
,version
|
|
||||||
,action
|
|
||||||
,partitioned
|
|
||||||
,by_range)
|
|
||||||
VALUES
|
|
||||||
('legitimization_outcomes'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'create'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('legitimization_outcomes'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'constrain'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('legitimization_outcomes'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'foreign'
|
|
||||||
,TRUE
|
|
||||||
,FALSE);
|
|
||||||
|
|
@ -1,206 +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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
CREATE FUNCTION create_table_legitimization_processes(
|
|
||||||
IN shard_suffix TEXT DEFAULT NULL
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
BEGIN
|
|
||||||
PERFORM create_partitioned_table(
|
|
||||||
'CREATE TABLE %I'
|
|
||||||
'(legitimization_process_serial_id BIGINT GENERATED BY DEFAULT AS IDENTITY'
|
|
||||||
',h_payto BYTEA NOT NULL CHECK (LENGTH(h_payto)=32)'
|
|
||||||
',start_time INT8 NOT NULL'
|
|
||||||
',expiration_time INT8 NOT NULL DEFAULT (0)'
|
|
||||||
',provider_name TEXT NOT NULL'
|
|
||||||
',provider_user_id TEXT DEFAULT NULL'
|
|
||||||
',provider_legitimization_id TEXT DEFAULT NULL'
|
|
||||||
',redirect_url TEXT DEFAULT NULL'
|
|
||||||
',finished BOOLEAN DEFAULT (FALSE)'
|
|
||||||
',legitimization_measure_serial_id BIGINT'
|
|
||||||
',measure_index INT4 DEFAULT(0)'
|
|
||||||
',error_code INT4 DEFAULT (0)'
|
|
||||||
',error_message TEXT DEFAULT NULL'
|
|
||||||
') %s ;'
|
|
||||||
,'legitimization_processes'
|
|
||||||
,'PARTITION BY HASH (h_payto)'
|
|
||||||
,shard_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_table(
|
|
||||||
'List of legitimization processes (ongoing and completed) by account and provider'
|
|
||||||
,'legitimization_processes'
|
|
||||||
,shard_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'unique ID for this legitimization process at the exchange'
|
|
||||||
,'legitimization_process_serial_id'
|
|
||||||
,'legitimization_processes'
|
|
||||||
,shard_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'hash over the normalized payto URI; foreign key linking the entry to the kyc_targets table, NOT a primary key (multiple legitimizations are possible per wire target)'
|
|
||||||
,'h_payto'
|
|
||||||
,'legitimization_processes'
|
|
||||||
,shard_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'time when the KYC check was initiated, useful for garbage collection (absolute time, not rounded)'
|
|
||||||
,'start_time'
|
|
||||||
,'legitimization_processes'
|
|
||||||
,shard_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'URL where the user should go to begin the KYC process'
|
|
||||||
,'redirect_url'
|
|
||||||
,'legitimization_processes'
|
|
||||||
,shard_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'in the future if the respective KYC check was passed successfully; an absolute time (not rounded)'
|
|
||||||
,'expiration_time'
|
|
||||||
,'legitimization_processes'
|
|
||||||
,shard_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Configuration file section with details about this provider'
|
|
||||||
,'provider_name'
|
|
||||||
,'legitimization_processes'
|
|
||||||
,shard_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Identifier for the user at the provider that was used for the legitimization. NULL if provider is unaware.'
|
|
||||||
,'provider_user_id'
|
|
||||||
,'legitimization_processes'
|
|
||||||
,shard_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Identifier for the specific legitimization process at the provider. NULL if legitimization was not started.'
|
|
||||||
,'provider_legitimization_id'
|
|
||||||
,'legitimization_processes'
|
|
||||||
,shard_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Set to TRUE when the specific legitimization process is finished.'
|
|
||||||
,'finished'
|
|
||||||
,'legitimization_processes'
|
|
||||||
,shard_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'measure that enabled this setup, NULL if client voluntarily initiated the process'
|
|
||||||
,'legitimization_measure_serial_id'
|
|
||||||
,'legitimization_processes'
|
|
||||||
,shard_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'index of the measure in legitimization_measures that was selected for this KYC setup; NULL if legitimization_measure_serial_id is NULL; enables determination of the context data provided to the external process'
|
|
||||||
,'measure_index'
|
|
||||||
,'legitimization_processes'
|
|
||||||
,shard_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'TALER_ErrorCode set if the process failed, otherwise NULL'
|
|
||||||
,'error_code'
|
|
||||||
,'legitimization_processes'
|
|
||||||
,shard_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'human-readable error details set if the process failed, otherwise NULL'
|
|
||||||
,'error_message'
|
|
||||||
,'legitimization_processes'
|
|
||||||
,shard_suffix
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
-- We need a separate function for this, as we call create_table only once but need to add
|
|
||||||
-- those constraints to each partition which gets created
|
|
||||||
CREATE FUNCTION constrain_table_legitimization_processes(
|
|
||||||
IN partition_suffix TEXT
|
|
||||||
)
|
|
||||||
RETURNS void
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
partition_name TEXT;
|
|
||||||
BEGIN
|
|
||||||
partition_name = concat_ws('_', 'legitimization_processes', partition_suffix);
|
|
||||||
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || partition_name
|
|
||||||
|| ' '
|
|
||||||
'ADD CONSTRAINT ' || partition_name || '_serial_key '
|
|
||||||
'UNIQUE (legitimization_process_serial_id)');
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'CREATE INDEX IF NOT EXISTS ' || partition_name || '_by_provider_and_legi_index '
|
|
||||||
'ON '|| partition_name || ' '
|
|
||||||
'(provider_name,provider_legitimization_id)'
|
|
||||||
);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'COMMENT ON INDEX ' || partition_name || '_by_provider_and_legi_index '
|
|
||||||
'IS ' || quote_literal('used (rarely) in kyc_provider_account_lookup') || ';'
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
-- We need a separate function for this, as we call create_table only once but need to add
|
|
||||||
-- those constraints to each partition which gets created
|
|
||||||
CREATE FUNCTION foreign_table_legitimization_processes()
|
|
||||||
RETURNS void
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'legitimization_processes';
|
|
||||||
BEGIN
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD CONSTRAINT ' || table_name || '_foreign_key_legitimization_measure'
|
|
||||||
' FOREIGN KEY (legitimization_measure_serial_id)'
|
|
||||||
' REFERENCES legitimization_measures (legitimization_measure_serial_id)');
|
|
||||||
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD CONSTRAINT ' || table_name || '_unique_measure_and_index'
|
|
||||||
' UNIQUE (legitimization_measure_serial_id,measure_index)');
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
INSERT INTO exchange_tables
|
|
||||||
(name
|
|
||||||
,version
|
|
||||||
,action
|
|
||||||
,partitioned
|
|
||||||
,by_range)
|
|
||||||
VALUES
|
|
||||||
('legitimization_processes'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'create'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('legitimization_processes'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'constrain'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('legitimization_processes'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'foreign'
|
|
||||||
,TRUE
|
|
||||||
,FALSE);
|
|
||||||
|
|
@ -1,33 +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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
|
|
||||||
CREATE TABLE partner_accounts
|
|
||||||
(payto_uri TEXT PRIMARY KEY
|
|
||||||
,partner_serial_id INT8 REFERENCES partners(partner_serial_id) ON DELETE CASCADE
|
|
||||||
,partner_master_sig BYTEA CHECK (LENGTH(partner_master_sig)=64)
|
|
||||||
,last_seen INT8 NOT NULL
|
|
||||||
);
|
|
||||||
CREATE INDEX IF NOT EXISTS partner_accounts_index_by_partner_and_time
|
|
||||||
ON partner_accounts (partner_serial_id,last_seen);
|
|
||||||
COMMENT ON TABLE partner_accounts
|
|
||||||
IS 'Table with bank accounts of the partner exchange. Entries never expire as we need to remember the signature for the auditor.';
|
|
||||||
COMMENT ON COLUMN partner_accounts.payto_uri
|
|
||||||
IS 'payto URI (RFC 8905) with the bank account of the partner exchange.';
|
|
||||||
COMMENT ON COLUMN partner_accounts.partner_master_sig
|
|
||||||
IS 'Signature of purpose TALER_SIGNATURE_MASTER_WIRE_DETAILS by the partner master public key';
|
|
||||||
COMMENT ON COLUMN partner_accounts.last_seen
|
|
||||||
IS 'Last time we saw this account as being active at the partner exchange. Used to select the most recent entry, and to detect when we should check again.';
|
|
||||||
|
|
@ -1,49 +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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
CREATE TABLE partners
|
|
||||||
(partner_serial_id BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE
|
|
||||||
,partner_master_pub BYTEA NOT NULL CHECK(LENGTH(partner_master_pub)=32)
|
|
||||||
,start_date INT8 NOT NULL
|
|
||||||
,end_date INT8 NOT NULL
|
|
||||||
,next_wad INT8 NOT NULL DEFAULT (0)
|
|
||||||
,wad_frequency INT8 NOT NULL
|
|
||||||
,wad_fee taler_amount NOT NULL
|
|
||||||
,master_sig BYTEA NOT NULL CHECK (LENGTH(master_sig)=64)
|
|
||||||
,partner_base_url TEXT NOT NULL
|
|
||||||
,PRIMARY KEY (partner_master_pub, start_date)
|
|
||||||
);
|
|
||||||
COMMENT ON TABLE partners
|
|
||||||
IS 'exchanges we do wad transfers to';
|
|
||||||
COMMENT ON COLUMN partners.partner_master_pub
|
|
||||||
IS 'offline master public key of the partner';
|
|
||||||
COMMENT ON COLUMN partners.start_date
|
|
||||||
IS 'starting date of the partnership';
|
|
||||||
COMMENT ON COLUMN partners.end_date
|
|
||||||
IS 'end date of the partnership';
|
|
||||||
COMMENT ON COLUMN partners.next_wad
|
|
||||||
IS 'at what time should we do the next wad transfer to this partner (frequently updated); set to forever after the end_date';
|
|
||||||
COMMENT ON COLUMN partners.wad_frequency
|
|
||||||
IS 'how often do we promise to do wad transfers';
|
|
||||||
COMMENT ON COLUMN partners.wad_fee
|
|
||||||
IS 'how high is the fee for a wallet to be added to a wad to this partner';
|
|
||||||
COMMENT ON COLUMN partners.partner_base_url
|
|
||||||
IS 'base URL of the REST API for this partner';
|
|
||||||
COMMENT ON COLUMN partners.master_sig
|
|
||||||
IS 'signature of our master public key affirming the partnership, of purpose TALER_SIGNATURE_MASTER_PARTNER_DETAILS';
|
|
||||||
|
|
||||||
CREATE INDEX IF NOT EXISTS partner_by_wad_time
|
|
||||||
ON partners (next_wad ASC);
|
|
||||||
|
|
@ -1,175 +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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
-- @author: Özgür Kesim
|
|
||||||
|
|
||||||
CREATE FUNCTION create_table_policy_details(
|
|
||||||
IN partition_suffix TEXT DEFAULT NULL
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'policy_details';
|
|
||||||
BEGIN
|
|
||||||
PERFORM create_partitioned_table(
|
|
||||||
'CREATE TABLE %I '
|
|
||||||
'(policy_details_serial_id BIGINT GENERATED BY DEFAULT AS IDENTITY'
|
|
||||||
',policy_hash_code gnunet_hashcode NOT NULL'
|
|
||||||
',policy_json TEXT NOT NULL'
|
|
||||||
',deadline INT8 NOT NULL'
|
|
||||||
',commitment taler_amount NOT NULL'
|
|
||||||
',accumulated_total taler_amount NOT NULL'
|
|
||||||
',fee taler_amount NOT NULL'
|
|
||||||
',transferable taler_amount NOT NULL'
|
|
||||||
',fulfillment_state SMALLINT NOT NULL CHECK(fulfillment_state between 0 and 5)'
|
|
||||||
',h_fulfillment_proof gnunet_hashcode'
|
|
||||||
') %s;'
|
|
||||||
,table_name
|
|
||||||
,'PARTITION BY HASH (h_fulfillment_proof)'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_table(
|
|
||||||
'Policies that were provided with deposits via policy extensions.'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'ID (GNUNET_HashCode) that identifies a policy. Will be calculated by the policy extension based on the content'
|
|
||||||
,'policy_hash_code'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'JSON object with options set that the exchange needs to consider when executing a deposit. Supported details depend on the policy extensions supported by the exchange.'
|
|
||||||
,'policy_json'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Deadline until the policy must be marked as fulfilled (maybe "forever")'
|
|
||||||
,'deadline'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'The amount that this policy commits to. Invariant: commitment >= fee'
|
|
||||||
,'commitment'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'The sum of all contributions of all deposit that reference this policy. Invariant: The fulfilment_state must be Insufficient as long as accumulated_total < commitment'
|
|
||||||
,'accumulated_total'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'The fee for this policy, due when the policy is fulfilled or timed out'
|
|
||||||
,'fee'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'The amount that on fulfillment or timeout will be transferred to the payto-URI''s of the corresponding deposit''s. The policy fees must have been already deducted from it. Invariant: fee+transferable <= accumulated_total. The remaining amount (accumulated_total - fee - transferable) can be refreshed by the owner of the coins when the state is Timeout or Success.'
|
|
||||||
,'transferable'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'State of the fulfillment:
|
|
||||||
- 0 (Failure)
|
|
||||||
- 1 (Insufficient)
|
|
||||||
- 2 (Ready)
|
|
||||||
- 4 (Success)
|
|
||||||
- 5 (Timeout)'
|
|
||||||
,'fulfillment_state'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Reference to the proof of the fulfillment of this policy, if it exists. Invariant: If not NULL, this entry''s .hash_code MUST be part of the corresponding policy_fulfillments.policy_hash_codes array.'
|
|
||||||
,'h_fulfillment_proof'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
COMMENT ON FUNCTION create_table_policy_details
|
|
||||||
IS 'Creates the policy_details table';
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION constrain_table_policy_details(
|
|
||||||
IN partition_suffix TEXT
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
partition_name TEXT;
|
|
||||||
BEGIN
|
|
||||||
partition_name = concat_ws('_', 'policy_details', partition_suffix);
|
|
||||||
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || partition_name ||
|
|
||||||
' ADD CONSTRAINT ' || partition_name || '_unique_serial_id '
|
|
||||||
' UNIQUE (policy_details_serial_id)'
|
|
||||||
);
|
|
||||||
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || partition_name ||
|
|
||||||
' ADD CONSTRAINT ' || partition_name || '_unique_hash_fulfillment_proof '
|
|
||||||
' UNIQUE (policy_hash_code, h_fulfillment_proof)'
|
|
||||||
);
|
|
||||||
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'CREATE INDEX ' || partition_name || '_policy_hash_code'
|
|
||||||
' ON ' || partition_name ||
|
|
||||||
' (policy_hash_code);'
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION foreign_table_policy_details()
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'policy_details';
|
|
||||||
BEGIN
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD CONSTRAINT ' || table_name || '_foreign_policy_fulfillments'
|
|
||||||
' FOREIGN KEY (h_fulfillment_proof) '
|
|
||||||
' REFERENCES policy_fulfillments (h_fulfillment_proof) ON DELETE RESTRICT'
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
INSERT INTO exchange_tables
|
|
||||||
(name
|
|
||||||
,version
|
|
||||||
,action
|
|
||||||
,partitioned
|
|
||||||
,by_range)
|
|
||||||
VALUES
|
|
||||||
('policy_details', 'exchange-0002', 'create', TRUE ,FALSE),
|
|
||||||
('policy_details', 'exchange-0002', 'constrain', TRUE ,FALSE),
|
|
||||||
('policy_details', 'exchange-0002', 'foreign', TRUE ,FALSE);
|
|
||||||
|
|
@ -1,101 +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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
-- @author: Özgür Kesim
|
|
||||||
|
|
||||||
CREATE FUNCTION create_table_policy_fulfillments(
|
|
||||||
IN partition_suffix TEXT DEFAULT NULL
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'policy_fulfillments';
|
|
||||||
BEGIN
|
|
||||||
PERFORM create_partitioned_table(
|
|
||||||
'CREATE TABLE %I '
|
|
||||||
'(h_fulfillment_proof gnunet_hashcode PRIMARY KEY'
|
|
||||||
',fulfillment_id BIGINT GENERATED BY DEFAULT AS IDENTITY'
|
|
||||||
',fulfillment_timestamp INT8 NOT NULL'
|
|
||||||
',fulfillment_proof TEXT'
|
|
||||||
',policy_hash_codes gnunet_hashcode[] NOT NULL'
|
|
||||||
') %s ;'
|
|
||||||
,table_name
|
|
||||||
,'PARTITION BY HASH (h_fulfillment_proof)'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_table(
|
|
||||||
'Proofs of fulfillment of policies that were set in deposits'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Timestamp of the arrival of a proof of fulfillment'
|
|
||||||
,'fulfillment_timestamp'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'JSON object with a proof of the fulfillment of a policy. Supported details depend on the policy extensions supported by the exchange.'
|
|
||||||
,'fulfillment_proof'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Hash of the fulfillment_proof'
|
|
||||||
,'h_fulfillment_proof'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Array of the policy_hash_code''s of all policy_details that are fulfilled by this proof'
|
|
||||||
,'policy_hash_codes'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
COMMENT ON FUNCTION create_table_policy_fulfillments
|
|
||||||
IS 'Creates the policy_fulfillments table';
|
|
||||||
|
|
||||||
CREATE FUNCTION constrain_table_policy_fulfillments(
|
|
||||||
IN partition_suffix TEXT
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
partition_name TEXT;
|
|
||||||
BEGIN
|
|
||||||
partition_name = concat_ws('_', 'policy_fulfillments', partition_suffix);
|
|
||||||
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || partition_name ||
|
|
||||||
' ADD CONSTRAINT ' || partition_name || '_serial_id '
|
|
||||||
' UNIQUE (h_fulfillment_proof, fulfillment_id)'
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
INSERT INTO exchange_tables
|
|
||||||
(name
|
|
||||||
,version
|
|
||||||
,action
|
|
||||||
,partitioned
|
|
||||||
,by_range)
|
|
||||||
VALUES
|
|
||||||
('policy_fulfillments', 'exchange-0002', 'create', TRUE ,FALSE),
|
|
||||||
('policy_fulfillments', 'exchange-0002', 'constrain', TRUE ,FALSE);
|
|
||||||
|
|
@ -1,116 +0,0 @@
|
||||||
--
|
|
||||||
-- This file is part of TALER
|
|
||||||
-- Copyright (C) 2014--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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
CREATE FUNCTION create_table_prewire(
|
|
||||||
IN partition_suffix TEXT DEFAULT NULL
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'prewire';
|
|
||||||
BEGIN
|
|
||||||
PERFORM create_partitioned_table(
|
|
||||||
'CREATE TABLE %I'
|
|
||||||
'(prewire_uuid BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY'
|
|
||||||
',wire_method TEXT NOT NULL'
|
|
||||||
',finished BOOLEAN NOT NULL DEFAULT FALSE'
|
|
||||||
',failed BOOLEAN NOT NULL DEFAULT FALSE'
|
|
||||||
',buf BYTEA NOT NULL'
|
|
||||||
') %s ;'
|
|
||||||
,table_name
|
|
||||||
,'PARTITION BY HASH (prewire_uuid)'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_table(
|
|
||||||
'pre-commit data for wire transfers we are about to execute'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'set to TRUE if the bank responded with a non-transient failure to our transfer request'
|
|
||||||
,'failed'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'set to TRUE once bank confirmed receiving the wire transfer request'
|
|
||||||
,'finished'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'serialized data to send to the bank to execute the wire transfer'
|
|
||||||
,'buf'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION constrain_table_prewire(
|
|
||||||
IN partition_suffix TEXT DEFAULT NULL
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'prewire';
|
|
||||||
BEGIN
|
|
||||||
table_name = concat_ws('_', table_name, partition_suffix);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'CREATE INDEX ' || table_name || '_by_finished_index '
|
|
||||||
'ON ' || table_name || ' '
|
|
||||||
'(finished)'
|
|
||||||
' WHERE finished;'
|
|
||||||
);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'COMMENT ON INDEX ' || table_name || '_by_finished_index '
|
|
||||||
'IS ' || quote_literal('for do_gc') || ';'
|
|
||||||
);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'CREATE INDEX ' || table_name || '_by_failed_finished_index '
|
|
||||||
'ON ' || table_name || ' '
|
|
||||||
'(prewire_uuid)'
|
|
||||||
' WHERE finished=FALSE'
|
|
||||||
' AND failed=FALSE;'
|
|
||||||
);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'COMMENT ON INDEX ' || table_name || '_by_failed_finished_index '
|
|
||||||
'IS ' || quote_literal('for wire_prepare_data_get') || ';'
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
INSERT INTO exchange_tables
|
|
||||||
(name
|
|
||||||
,version
|
|
||||||
,action
|
|
||||||
,partitioned
|
|
||||||
,by_range)
|
|
||||||
VALUES
|
|
||||||
('prewire'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'create'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('prewire'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'constrain'
|
|
||||||
,TRUE
|
|
||||||
,FALSE);
|
|
||||||
|
|
@ -1,42 +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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
CREATE TABLE profit_drains
|
|
||||||
(profit_drain_serial_id BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE
|
|
||||||
,wtid BYTEA PRIMARY KEY CHECK (LENGTH(wtid)=32)
|
|
||||||
,account_section TEXT NOT NULL
|
|
||||||
,payto_uri TEXT NOT NULL
|
|
||||||
,trigger_date INT8 NOT NULL
|
|
||||||
,amount taler_amount NOT NULL
|
|
||||||
,master_sig BYTEA NOT NULL CHECK (LENGTH(master_sig)=64)
|
|
||||||
,executed BOOLEAN NOT NULL DEFAULT FALSE
|
|
||||||
);
|
|
||||||
COMMENT ON TABLE profit_drains
|
|
||||||
IS 'transactions to be performed to move profits from the escrow account of the exchange to a regular account';
|
|
||||||
COMMENT ON COLUMN profit_drains.wtid
|
|
||||||
IS 'randomly chosen nonce, unique to prevent double-submission';
|
|
||||||
COMMENT ON COLUMN profit_drains.account_section
|
|
||||||
IS 'specifies the configuration section in the taler-exchange-drain configuration with the wire account to drain';
|
|
||||||
COMMENT ON COLUMN profit_drains.payto_uri
|
|
||||||
IS 'specifies the account to be credited';
|
|
||||||
COMMENT ON COLUMN profit_drains.trigger_date
|
|
||||||
IS 'set by taler-exchange-offline at the time of making the signature; not necessarily the exact date of execution of the wire transfer, just for orientation';
|
|
||||||
COMMENT ON COLUMN profit_drains.amount
|
|
||||||
IS 'amount to be transferred';
|
|
||||||
COMMENT ON COLUMN profit_drains.master_sig
|
|
||||||
IS 'EdDSA signature of type TALER_SIGNATURE_MASTER_DRAIN_PROFIT';
|
|
||||||
COMMENT ON COLUMN profit_drains.executed
|
|
||||||
IS 'set to TRUE by taler-exchange-drain on execution of the transaction, not replicated to auditor';
|
|
||||||
|
|
@ -1,102 +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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION create_table_purse_actions(
|
|
||||||
IN partition_suffix TEXT DEFAULT NULL
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'purse_actions';
|
|
||||||
BEGIN
|
|
||||||
PERFORM create_partitioned_table(
|
|
||||||
'CREATE TABLE IF NOT EXISTS %I'
|
|
||||||
'(purse_pub BYTEA NOT NULL PRIMARY KEY CHECK(LENGTH(purse_pub)=32)'
|
|
||||||
',action_date INT8 NOT NULL'
|
|
||||||
',partner_serial_id INT8'
|
|
||||||
') %s ;'
|
|
||||||
,table_name
|
|
||||||
,'PARTITION BY HASH (purse_pub)'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_table(
|
|
||||||
'purses awaiting some action by the router'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'public (contract) key of the purse'
|
|
||||||
,'purse_pub'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'when is the purse ready for action'
|
|
||||||
,'action_date'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'wad target of an outgoing wire transfer, 0 for local, NULL if the purse is unmerged and thus the target is still unknown'
|
|
||||||
,'partner_serial_id'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
END $$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION master_table_purse_actions()
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'purse_actions';
|
|
||||||
BEGIN
|
|
||||||
-- Create global index
|
|
||||||
CREATE INDEX IF NOT EXISTS purse_action_by_target
|
|
||||||
ON purse_actions
|
|
||||||
(partner_serial_id,action_date);
|
|
||||||
|
|
||||||
-- Setup trigger
|
|
||||||
CREATE TRIGGER purse_requests_on_insert
|
|
||||||
AFTER INSERT
|
|
||||||
ON purse_requests
|
|
||||||
FOR EACH ROW EXECUTE FUNCTION purse_requests_insert_trigger();
|
|
||||||
COMMENT ON TRIGGER purse_requests_on_insert
|
|
||||||
ON purse_requests
|
|
||||||
IS 'Here we install an entry for the purse expiration.';
|
|
||||||
END $$;
|
|
||||||
|
|
||||||
|
|
||||||
INSERT INTO exchange_tables
|
|
||||||
(name
|
|
||||||
,version
|
|
||||||
,action
|
|
||||||
,partitioned
|
|
||||||
,by_range)
|
|
||||||
VALUES
|
|
||||||
('purse_actions'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'create'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('purse_actions'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'master'
|
|
||||||
,TRUE
|
|
||||||
,FALSE);
|
|
||||||
|
|
@ -1,110 +0,0 @@
|
||||||
--
|
|
||||||
-- This file is part of TALER
|
|
||||||
-- Copyright (C) 2014--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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION create_table_purse_decision(
|
|
||||||
IN partition_suffix TEXT DEFAULT NULL
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'purse_decision';
|
|
||||||
BEGIN
|
|
||||||
PERFORM create_partitioned_table(
|
|
||||||
'CREATE TABLE %I '
|
|
||||||
'(purse_decision_serial_id BIGINT GENERATED BY DEFAULT AS IDENTITY'
|
|
||||||
',purse_pub BYTEA NOT NULL CHECK (LENGTH(purse_pub)=32)'
|
|
||||||
',action_timestamp INT8 NOT NULL'
|
|
||||||
',refunded BOOL NOT NULL'
|
|
||||||
',PRIMARY KEY (purse_pub)'
|
|
||||||
') %s ;'
|
|
||||||
,table_name
|
|
||||||
,'PARTITION BY HASH (purse_pub)'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_table(
|
|
||||||
'Purses that were decided upon (refund or merge)'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Public key of the purse'
|
|
||||||
,'purse_pub'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
CREATE FUNCTION constrain_table_purse_decision(
|
|
||||||
IN partition_suffix TEXT
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'purse_decision';
|
|
||||||
BEGIN
|
|
||||||
table_name = concat_ws('_', table_name, partition_suffix);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD CONSTRAINT ' || table_name || '_purse_action_serial_id_key'
|
|
||||||
' UNIQUE (purse_decision_serial_id) '
|
|
||||||
);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD CONSTRAINT ' || table_name || '_purse_decision_purse_pub'
|
|
||||||
' UNIQUE (purse_pub) '
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION master_table_purse_decision()
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
BEGIN
|
|
||||||
CREATE TRIGGER purse_decision_on_insert
|
|
||||||
AFTER INSERT
|
|
||||||
ON purse_decision
|
|
||||||
FOR EACH ROW EXECUTE FUNCTION purse_decision_insert_trigger();
|
|
||||||
END $$;
|
|
||||||
|
|
||||||
|
|
||||||
INSERT INTO exchange_tables
|
|
||||||
(name
|
|
||||||
,version
|
|
||||||
,action
|
|
||||||
,partitioned
|
|
||||||
,by_range)
|
|
||||||
VALUES
|
|
||||||
('purse_decision'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'create'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('purse_decision'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'constrain'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('purse_decision'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'master'
|
|
||||||
,TRUE
|
|
||||||
,FALSE);
|
|
||||||
|
|
@ -1,110 +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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION create_table_purse_deletion(
|
|
||||||
IN partition_suffix TEXT DEFAULT NULL
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'purse_deletion';
|
|
||||||
BEGIN
|
|
||||||
PERFORM create_partitioned_table(
|
|
||||||
'CREATE TABLE IF NOT EXISTS %I'
|
|
||||||
'(purse_deletion_serial_id BIGINT GENERATED BY DEFAULT AS IDENTITY'
|
|
||||||
',purse_sig BYTEA CHECK (LENGTH(purse_sig)=64)'
|
|
||||||
',purse_pub BYTEA NOT NULL CHECK (LENGTH(purse_pub)=32)'
|
|
||||||
') %s ;'
|
|
||||||
,table_name
|
|
||||||
,'PARTITION BY HASH (purse_pub)'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_table(
|
|
||||||
'signatures affirming explicit purse deletions'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'signature of type WALLET_PURSE_DELETE'
|
|
||||||
,'purse_sig'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
END $$;
|
|
||||||
|
|
||||||
COMMENT ON FUNCTION create_table_purse_deletion
|
|
||||||
IS 'Creates the purse_deletion table';
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION constrain_table_purse_deletion(
|
|
||||||
IN partition_suffix TEXT DEFAULT NULL
|
|
||||||
)
|
|
||||||
RETURNS void
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'purse_deletion';
|
|
||||||
BEGIN
|
|
||||||
table_name = concat_ws('_', table_name, partition_suffix);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD CONSTRAINT ' || table_name || '_delete_serial_key '
|
|
||||||
'UNIQUE (purse_deletion_serial_id)'
|
|
||||||
);
|
|
||||||
END $$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION master_table_purse_requests_was_deleted (
|
|
||||||
)
|
|
||||||
RETURNS void
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'purse_requests';
|
|
||||||
BEGIN
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE exchange.' || table_name ||
|
|
||||||
' ADD COLUMN'
|
|
||||||
' was_deleted BOOLEAN NOT NULL DEFAULT(FALSE)'
|
|
||||||
);
|
|
||||||
COMMENT ON COLUMN purse_requests.was_deleted
|
|
||||||
IS 'TRUE if the purse was explicitly deleted (purse must have an entry in the purse_deletion table)';
|
|
||||||
END $$;
|
|
||||||
|
|
||||||
|
|
||||||
INSERT INTO exchange_tables
|
|
||||||
(name
|
|
||||||
,version
|
|
||||||
,action
|
|
||||||
,partitioned
|
|
||||||
,by_range)
|
|
||||||
VALUES
|
|
||||||
('purse_deletion'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'create'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('purse_deletion'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'constrain'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('purse_requests_was_deleted'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'master'
|
|
||||||
,TRUE
|
|
||||||
,FALSE);
|
|
||||||
|
|
@ -1,176 +0,0 @@
|
||||||
--
|
|
||||||
-- This file is part of TALER
|
|
||||||
-- Copyright (C) 2014--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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
CREATE FUNCTION create_table_purse_deposits(
|
|
||||||
IN partition_suffix TEXT DEFAULT NULL
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'purse_deposits';
|
|
||||||
BEGIN
|
|
||||||
PERFORM create_partitioned_table(
|
|
||||||
'CREATE TABLE %I '
|
|
||||||
'(purse_deposit_serial_id BIGINT GENERATED BY DEFAULT AS IDENTITY'
|
|
||||||
',partner_serial_id INT8'
|
|
||||||
',purse_pub BYTEA NOT NULL CHECK (LENGTH(purse_pub)=32)'
|
|
||||||
',coin_pub BYTEA NOT NULL'
|
|
||||||
',amount_with_fee taler_amount NOT NULL'
|
|
||||||
',coin_sig BYTEA NOT NULL CHECK(LENGTH(coin_sig)=64)'
|
|
||||||
',PRIMARY KEY (purse_pub,coin_pub)'
|
|
||||||
') %s ;'
|
|
||||||
,table_name
|
|
||||||
,'PARTITION BY HASH (purse_pub)'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_table(
|
|
||||||
'Requests depositing coins into a purse'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'identifies the partner exchange, NULL in case the target purse lives at this exchange'
|
|
||||||
,'partner_serial_id'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Public key of the purse'
|
|
||||||
,'purse_pub'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Public key of the coin being deposited'
|
|
||||||
,'coin_pub'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Total amount being deposited'
|
|
||||||
,'amount_with_fee'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Signature of the coin affirming the deposit into the purse, of type TALER_SIGNATURE_PURSE_DEPOSIT'
|
|
||||||
,'coin_sig'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION constrain_table_purse_deposits(
|
|
||||||
IN partition_suffix TEXT
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'purse_deposits';
|
|
||||||
BEGIN
|
|
||||||
table_name = concat_ws('_', table_name, partition_suffix);
|
|
||||||
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD CONSTRAINT ' || table_name || '_purse_deposit_serial_id_key'
|
|
||||||
' UNIQUE (purse_deposit_serial_id) '
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION foreign_table_purse_deposits()
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'purse_deposits';
|
|
||||||
BEGIN
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD CONSTRAINT ' || table_name || '_foreign_partner'
|
|
||||||
' FOREIGN KEY (partner_serial_id) '
|
|
||||||
' REFERENCES partners(partner_serial_id) ON DELETE CASCADE'
|
|
||||||
',ADD CONSTRAINT ' || table_name || '_foreign_coin_pub'
|
|
||||||
' FOREIGN KEY (coin_pub) '
|
|
||||||
' REFERENCES known_coins (coin_pub) ON DELETE CASCADE'
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION purse_deposits_insert_trigger()
|
|
||||||
RETURNS trigger
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
BEGIN
|
|
||||||
INSERT INTO exchange.coin_history
|
|
||||||
(coin_pub
|
|
||||||
,table_name
|
|
||||||
,serial_id)
|
|
||||||
VALUES
|
|
||||||
(NEW.coin_pub
|
|
||||||
,'purse_deposits'
|
|
||||||
,NEW.purse_deposit_serial_id);
|
|
||||||
RETURN NEW;
|
|
||||||
END $$;
|
|
||||||
COMMENT ON FUNCTION purse_deposits_insert_trigger()
|
|
||||||
IS 'Automatically generate coin history entry.';
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION master_table_purse_deposits()
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
BEGIN
|
|
||||||
CREATE TRIGGER purse_deposits_on_insert
|
|
||||||
AFTER INSERT
|
|
||||||
ON purse_deposits
|
|
||||||
FOR EACH ROW EXECUTE FUNCTION purse_deposits_insert_trigger();
|
|
||||||
END $$;
|
|
||||||
|
|
||||||
|
|
||||||
INSERT INTO exchange_tables
|
|
||||||
(name
|
|
||||||
,version
|
|
||||||
,action
|
|
||||||
,partitioned
|
|
||||||
,by_range)
|
|
||||||
VALUES
|
|
||||||
('purse_deposits'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'create'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('purse_deposits'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'constrain'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('purse_deposits'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'foreign'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('purse_deposits'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'master'
|
|
||||||
,TRUE
|
|
||||||
,FALSE);
|
|
||||||
|
|
@ -1,140 +0,0 @@
|
||||||
--
|
|
||||||
-- This file is part of TALER
|
|
||||||
-- Copyright (C) 2014--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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
CREATE FUNCTION create_table_purse_merges(
|
|
||||||
IN partition_suffix TEXT DEFAULT NULL
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'purse_merges';
|
|
||||||
BEGIN
|
|
||||||
PERFORM create_partitioned_table(
|
|
||||||
'CREATE TABLE %I '
|
|
||||||
'(purse_merge_request_serial_id BIGINT GENERATED BY DEFAULT AS IDENTITY'
|
|
||||||
',partner_serial_id INT8'
|
|
||||||
',reserve_pub BYTEA NOT NULL CHECK(length(reserve_pub)=32)'
|
|
||||||
',purse_pub BYTEA NOT NULL CHECK (LENGTH(purse_pub)=32)'
|
|
||||||
',merge_sig BYTEA NOT NULL CHECK (LENGTH(merge_sig)=64)'
|
|
||||||
',merge_timestamp INT8 NOT NULL'
|
|
||||||
',PRIMARY KEY (purse_pub)'
|
|
||||||
') %s ;'
|
|
||||||
,table_name
|
|
||||||
,'PARTITION BY HASH (purse_pub)'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_table(
|
|
||||||
'Merge requests where a purse-owner requested merging the purse into the account'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'identifies the partner exchange, NULL in case the target reserve lives at this exchange'
|
|
||||||
,'partner_serial_id'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'public key of the target reserve'
|
|
||||||
,'reserve_pub'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'public key of the purse'
|
|
||||||
,'purse_pub'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'signature by the purse private key affirming the merge, of type TALER_SIGNATURE_WALLET_PURSE_MERGE'
|
|
||||||
,'merge_sig'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'when was the merge message signed'
|
|
||||||
,'merge_timestamp'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION constrain_table_purse_merges(
|
|
||||||
IN partition_suffix TEXT
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'purse_merges';
|
|
||||||
BEGIN
|
|
||||||
table_name = concat_ws('_', table_name, partition_suffix);
|
|
||||||
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD CONSTRAINT ' || table_name || '_purse_merge_request_serial_id_key'
|
|
||||||
' UNIQUE (purse_merge_request_serial_id) '
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION foreign_table_purse_merges()
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'purse_merges';
|
|
||||||
BEGIN
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD CONSTRAINT ' || table_name || '_foreign_partner_serial_id'
|
|
||||||
' FOREIGN KEY (partner_serial_id) '
|
|
||||||
' REFERENCES partners(partner_serial_id) ON DELETE CASCADE'
|
|
||||||
',ADD CONSTRAINT ' || table_name || '_foreign_purse_pub'
|
|
||||||
' FOREIGN KEY (purse_pub) '
|
|
||||||
' REFERENCES purse_requests (purse_pub) ON DELETE CASCADE'
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
INSERT INTO exchange_tables
|
|
||||||
(name
|
|
||||||
,version
|
|
||||||
,action
|
|
||||||
,partitioned
|
|
||||||
,by_range)
|
|
||||||
VALUES
|
|
||||||
('purse_merges'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'create'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('purse_merges'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'constrain'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('purse_merges'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'foreign'
|
|
||||||
,TRUE
|
|
||||||
,FALSE);
|
|
||||||
|
|
@ -1,163 +0,0 @@
|
||||||
--
|
|
||||||
-- This file is part of TALER
|
|
||||||
-- Copyright (C) 2014--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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
CREATE FUNCTION create_table_purse_requests(
|
|
||||||
IN partition_suffix TEXT DEFAULT NULL
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'purse_requests';
|
|
||||||
BEGIN
|
|
||||||
PERFORM create_partitioned_table(
|
|
||||||
'CREATE TABLE %I '
|
|
||||||
'(purse_requests_serial_id BIGINT GENERATED BY DEFAULT AS IDENTITY'
|
|
||||||
',purse_pub BYTEA NOT NULL CHECK (LENGTH(purse_pub)=32)'
|
|
||||||
',merge_pub BYTEA NOT NULL CHECK (LENGTH(merge_pub)=32)'
|
|
||||||
',purse_creation INT8 NOT NULL'
|
|
||||||
',purse_expiration INT8 NOT NULL'
|
|
||||||
',h_contract_terms BYTEA NOT NULL CHECK (LENGTH(h_contract_terms)=64)'
|
|
||||||
',age_limit INT4 NOT NULL'
|
|
||||||
',flags INT4 NOT NULL'
|
|
||||||
',in_reserve_quota BOOLEAN NOT NULL DEFAULT(FALSE)'
|
|
||||||
',was_decided BOOLEAN NOT NULL DEFAULT(FALSE)'
|
|
||||||
',amount_with_fee taler_amount NOT NULL'
|
|
||||||
',purse_fee taler_amount NOT NULL'
|
|
||||||
',balance taler_amount NOT NULL DEFAULT (0,0)'
|
|
||||||
',purse_sig BYTEA NOT NULL CHECK(LENGTH(purse_sig)=64)'
|
|
||||||
',PRIMARY KEY (purse_pub)'
|
|
||||||
') %s ;'
|
|
||||||
,table_name
|
|
||||||
,'PARTITION BY HASH (purse_pub)'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_table(
|
|
||||||
'Requests establishing purses, associating them with a contract but without a target reserve'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Public key of the purse'
|
|
||||||
,'purse_pub'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Local time when the purse was created. Determines applicable purse fees.'
|
|
||||||
,'purse_creation'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'When the purse is set to expire'
|
|
||||||
,'purse_expiration'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Hash of the contract the parties are to agree to'
|
|
||||||
,'h_contract_terms'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'see the enum TALER_WalletAccountMergeFlags'
|
|
||||||
,'flags'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'set to TRUE if this purse currently counts against the number of free purses in the respective reserve'
|
|
||||||
,'in_reserve_quota'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Total amount expected to be in the purse'
|
|
||||||
,'amount_with_fee'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Purse fee the client agreed to pay from the reserve (accepted by the exchange at the time the purse was created). Zero if in_reserve_quota is TRUE.'
|
|
||||||
,'purse_fee'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Total amount actually in the purse (updated)'
|
|
||||||
,'balance'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Signature of the purse affirming the purse parameters, of type TALER_SIGNATURE_PURSE_REQUEST'
|
|
||||||
,'purse_sig'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
CREATE FUNCTION constrain_table_purse_requests(
|
|
||||||
IN partition_suffix TEXT
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'purse_requests';
|
|
||||||
BEGIN
|
|
||||||
table_name = concat_ws('_', table_name, partition_suffix);
|
|
||||||
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'CREATE INDEX ' || table_name || '_merge_pub '
|
|
||||||
'ON ' || table_name || ' '
|
|
||||||
'(merge_pub);'
|
|
||||||
);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'CREATE INDEX ' || table_name || '_purse_expiration '
|
|
||||||
'ON ' || table_name || ' '
|
|
||||||
'(purse_expiration) ' ||
|
|
||||||
'WHERE NOT was_decided;'
|
|
||||||
);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD CONSTRAINT ' || table_name || '_purse_requests_serial_id_key'
|
|
||||||
' UNIQUE (purse_requests_serial_id) '
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
INSERT INTO exchange_tables
|
|
||||||
(name
|
|
||||||
,version
|
|
||||||
,action
|
|
||||||
,partitioned
|
|
||||||
,by_range)
|
|
||||||
VALUES
|
|
||||||
('purse_requests'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'create'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('purse_requests'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'constrain'
|
|
||||||
,TRUE
|
|
||||||
,FALSE);
|
|
||||||
|
|
@ -1,268 +0,0 @@
|
||||||
--
|
|
||||||
-- This file is part of TALER
|
|
||||||
-- Copyright (C) 2025 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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
CREATE FUNCTION create_table_recoup(
|
|
||||||
IN partition_suffix TEXT DEFAULT NULL
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'recoup';
|
|
||||||
BEGIN
|
|
||||||
|
|
||||||
PERFORM create_partitioned_table(
|
|
||||||
'CREATE TABLE %I'
|
|
||||||
'(recoup_uuid BIGINT GENERATED BY DEFAULT AS IDENTITY'
|
|
||||||
',coin_pub BYTEA NOT NULL CHECK (LENGTH(coin_pub)=32)'
|
|
||||||
',coin_sig BYTEA NOT NULL CHECK(LENGTH(coin_sig)=64)'
|
|
||||||
',coin_blind BYTEA NOT NULL CHECK(LENGTH(coin_blind)=32)'
|
|
||||||
',amount taler_amount NOT NULL'
|
|
||||||
',recoup_timestamp INT8 NOT NULL'
|
|
||||||
',withdraw_id INT8 NOT NULL'
|
|
||||||
') %s ;'
|
|
||||||
,table_name
|
|
||||||
,'PARTITION BY HASH (coin_pub);'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_table(
|
|
||||||
'Information about recoups that were executed between a coin and a reserve. In this type of recoup, the amount is credited back to the reserve from which the coin originated.'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Coin that is being debited in the recoup. Do not CASCADE ON DROP on the coin_pub, as we may keep the coin alive!'
|
|
||||||
,'coin_pub'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Identifies the h_commitment of the recouped coin and provides the link to the credited reserve.'
|
|
||||||
,'withdraw_id'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Signature by the coin affirming the recoup, of type TALER_SIGNATURE_WALLET_COIN_RECOUP'
|
|
||||||
,'coin_sig'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Denomination blinding key used when creating the blinded coin from the planchet. Secret revealed during the recoup to provide the linkage between the coin and the withdraw operation.'
|
|
||||||
,'coin_blind'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION constrain_table_recoup(
|
|
||||||
IN partition_suffix TEXT
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'recoup';
|
|
||||||
BEGIN
|
|
||||||
table_name = concat_ws('_', table_name, partition_suffix);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'CREATE INDEX ' || table_name || '_by_coin_pub_index '
|
|
||||||
'ON ' || table_name || ' '
|
|
||||||
'(coin_pub);'
|
|
||||||
);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD CONSTRAINT ' || table_name || '_recoup_uuid_key'
|
|
||||||
' UNIQUE (recoup_uuid) '
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION foreign_table_recoup()
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'recoup';
|
|
||||||
BEGIN
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD CONSTRAINT ' || table_name || '_foreign_withdraw'
|
|
||||||
' FOREIGN KEY (withdraw_id) '
|
|
||||||
' REFERENCES withdraw (withdraw_id) ON DELETE CASCADE'
|
|
||||||
',ADD CONSTRAINT ' || table_name || '_foreign_coin_pub'
|
|
||||||
' FOREIGN KEY (coin_pub) '
|
|
||||||
' REFERENCES known_coins (coin_pub)'
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION create_table_recoup_by_reserve(
|
|
||||||
IN partition_suffix TEXT DEFAULT NULL
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'recoup_by_reserve';
|
|
||||||
BEGIN
|
|
||||||
PERFORM create_partitioned_table(
|
|
||||||
'CREATE TABLE %I'
|
|
||||||
'(withdraw_id INT8 NOT NULL' -- REFERENCES withdraw (withdraw_id) ON DELETE CASCADE
|
|
||||||
',coin_pub BYTEA CHECK (LENGTH(coin_pub)=32)' -- REFERENCES known_coins (coin_pub)
|
|
||||||
') %s ;'
|
|
||||||
,table_name
|
|
||||||
,'PARTITION BY HASH (withdraw_id)'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_table(
|
|
||||||
'Information in this table is strictly redundant with that of recoup, but saved by a different primary key for fast lookups by withdraw_id.'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION constrain_table_recoup_by_reserve(
|
|
||||||
IN partition_suffix TEXT DEFAULT NULL
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'recoup_by_reserve';
|
|
||||||
BEGIN
|
|
||||||
table_name = concat_ws('_', table_name, partition_suffix);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'CREATE INDEX ' || table_name || '_main_index '
|
|
||||||
'ON ' || table_name || ' '
|
|
||||||
'(withdraw_id);'
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION recoup_insert_trigger()
|
|
||||||
RETURNS trigger
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
BEGIN
|
|
||||||
INSERT INTO recoup_by_reserve
|
|
||||||
(withdraw_id
|
|
||||||
,coin_pub)
|
|
||||||
VALUES
|
|
||||||
(NEW.withdraw_id
|
|
||||||
,NEW.coin_pub);
|
|
||||||
INSERT INTO coin_history
|
|
||||||
(coin_pub
|
|
||||||
,table_name
|
|
||||||
,serial_id)
|
|
||||||
VALUES
|
|
||||||
(NEW.coin_pub
|
|
||||||
,'recoup'
|
|
||||||
,NEW.recoup_uuid);
|
|
||||||
INSERT INTO reserve_history
|
|
||||||
(reserve_pub
|
|
||||||
,table_name
|
|
||||||
,serial_id)
|
|
||||||
SELECT
|
|
||||||
res.reserve_pub
|
|
||||||
,'recoup'
|
|
||||||
,NEW.recoup_uuid
|
|
||||||
FROM withdraw wd
|
|
||||||
JOIN reserves res
|
|
||||||
USING (reserve_pub)
|
|
||||||
WHERE wd.withdraw_id = NEW.withdraw_id;
|
|
||||||
RETURN NEW;
|
|
||||||
END $$;
|
|
||||||
COMMENT ON FUNCTION recoup_insert_trigger()
|
|
||||||
IS 'Replicates recoup inserts into recoup_by_reserve table and updates the coin_history table.';
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION recoup_delete_trigger()
|
|
||||||
RETURNS trigger
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
BEGIN
|
|
||||||
DELETE FROM recoup_by_reserve
|
|
||||||
WHERE withdraw_id = OLD.withdraw_id
|
|
||||||
AND coin_pub = OLD.coin_pub;
|
|
||||||
RETURN OLD;
|
|
||||||
END $$;
|
|
||||||
COMMENT ON FUNCTION recoup_delete_trigger()
|
|
||||||
IS 'Replicate recoup deletions into recoup_by_reserve table.';
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION master_table_recoup()
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
BEGIN
|
|
||||||
CREATE TRIGGER recoup_on_insert
|
|
||||||
AFTER INSERT
|
|
||||||
ON recoup
|
|
||||||
FOR EACH ROW EXECUTE FUNCTION recoup_insert_trigger();
|
|
||||||
CREATE TRIGGER recoup_on_delete
|
|
||||||
AFTER DELETE
|
|
||||||
ON recoup
|
|
||||||
FOR EACH ROW EXECUTE FUNCTION recoup_delete_trigger();
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
INSERT INTO exchange_tables
|
|
||||||
(name
|
|
||||||
,version
|
|
||||||
,action
|
|
||||||
,partitioned
|
|
||||||
,by_range)
|
|
||||||
VALUES
|
|
||||||
('recoup'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'create'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('recoup'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'constrain'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('recoup'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'foreign'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('recoup_by_reserve'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'create'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('recoup_by_reserve'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'constrain'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('recoup'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'master'
|
|
||||||
,TRUE
|
|
||||||
,FALSE);
|
|
||||||
|
|
@ -1,201 +0,0 @@
|
||||||
--
|
|
||||||
-- This file is part of TALER
|
|
||||||
-- Copyright (C) 2025 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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION create_table_recoup_refresh(
|
|
||||||
IN partition_suffix TEXT DEFAULT NULL
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'recoup_refresh';
|
|
||||||
BEGIN
|
|
||||||
PERFORM create_partitioned_table(
|
|
||||||
'CREATE TABLE %I'
|
|
||||||
'(recoup_refresh_uuid BIGINT GENERATED BY DEFAULT AS IDENTITY'
|
|
||||||
',coin_pub BYTEA NOT NULL CHECK (LENGTH(coin_pub)=32)'
|
|
||||||
',known_coin_id BIGINT NOT NULL'
|
|
||||||
',coin_sig BYTEA NOT NULL CHECK(LENGTH(coin_sig)=64)'
|
|
||||||
',coin_blind BYTEA NOT NULL CHECK(LENGTH(coin_blind)=32)'
|
|
||||||
',amount taler_amount NOT NULL'
|
|
||||||
',recoup_timestamp INT8 NOT NULL'
|
|
||||||
',refresh_id INT8 NOT NULL'
|
|
||||||
') %s ;'
|
|
||||||
,table_name
|
|
||||||
,'PARTITION BY HASH (coin_pub)'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_table(
|
|
||||||
'Table of coins that originated from a refresh operation and that were recouped. Links the (fresh) coin to the melted operation (and thus the old coin). A recoup on a refreshed coin credits the old coin and debits the fresh coin.'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Refreshed coin of a revoked denomination where the residual value is credited to the old coin. Do not CASCADE ON DROP on the coin_pub, as we may keep the coin alive!'
|
|
||||||
,'coin_pub'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Used for garbage collection (in the absence of foreign constraints, in the future)'
|
|
||||||
,'known_coin_id'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Link to the refresh operation. Also identifies the h_blind_ev of the recouped coin (as h_coin_ev).'
|
|
||||||
,'refresh_id'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Denomination blinding key used when creating the blinded coin from the planchet. Secret revealed during the recoup to provide the linkage between the coin and the refresh operation.'
|
|
||||||
,'coin_blind'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION constrain_table_recoup_refresh(
|
|
||||||
IN partition_suffix TEXT
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'recoup_refresh';
|
|
||||||
BEGIN
|
|
||||||
table_name = concat_ws('_', table_name, partition_suffix);
|
|
||||||
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'CREATE INDEX ' || table_name || '_by_refresh_id_index'
|
|
||||||
' ON ' || table_name || ' '
|
|
||||||
'(refresh_id);'
|
|
||||||
);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'COMMENT ON INDEX ' || table_name || '_by_refresh_id_index '
|
|
||||||
'IS ' || quote_literal('used in exchange_do_melt for zombie coins (rare)') || ';'
|
|
||||||
);
|
|
||||||
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'CREATE INDEX ' || table_name || '_by_coin_pub_index'
|
|
||||||
' ON ' || table_name || ' '
|
|
||||||
'(coin_pub);'
|
|
||||||
);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD CONSTRAINT ' || table_name || '_recoup_refresh_uuid_key'
|
|
||||||
' UNIQUE (recoup_refresh_uuid) '
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION foreign_table_recoup_refresh()
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'recoup_refresh';
|
|
||||||
BEGIN
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD CONSTRAINT ' || table_name || '_foreign_coin_pub'
|
|
||||||
' FOREIGN KEY (coin_pub) '
|
|
||||||
' REFERENCES known_coins (coin_pub)'
|
|
||||||
',ADD CONSTRAINT ' || table_name || '_foreign_known_coin_id'
|
|
||||||
' FOREIGN KEY (known_coin_id) '
|
|
||||||
' REFERENCES known_coins (known_coin_id) ON DELETE CASCADE'
|
|
||||||
',ADD CONSTRAINT ' || table_name || '_foreign_refresh_id'
|
|
||||||
' FOREIGN KEY (refresh_id) '
|
|
||||||
' REFERENCES refresh (refresh_id) ON DELETE CASCADE'
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION recoup_refresh_insert_trigger()
|
|
||||||
RETURNS trigger
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
BEGIN
|
|
||||||
INSERT INTO exchange.coin_history
|
|
||||||
(coin_pub
|
|
||||||
,table_name
|
|
||||||
,serial_id)
|
|
||||||
VALUES
|
|
||||||
(NEW.coin_pub
|
|
||||||
,'recoup_refresh::NEW'
|
|
||||||
,NEW.recoup_refresh_uuid);
|
|
||||||
INSERT INTO exchange.coin_history
|
|
||||||
(coin_pub
|
|
||||||
,table_name
|
|
||||||
,serial_id)
|
|
||||||
SELECT
|
|
||||||
refresh.old_coin_pub
|
|
||||||
,'recoup_refresh::OLD'
|
|
||||||
,NEW.recoup_refresh_uuid
|
|
||||||
FROM refresh
|
|
||||||
WHERE refresh.refresh_id = NEW.refresh_id;
|
|
||||||
RETURN NEW;
|
|
||||||
END $$;
|
|
||||||
COMMENT ON FUNCTION coin_deposits_insert_trigger()
|
|
||||||
IS 'Automatically generate coin history entry.';
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION master_table_recoup_refresh()
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
BEGIN
|
|
||||||
CREATE TRIGGER recoup_refresh_on_insert
|
|
||||||
AFTER INSERT
|
|
||||||
ON recoup_refresh
|
|
||||||
FOR EACH ROW EXECUTE FUNCTION recoup_refresh_insert_trigger();
|
|
||||||
END $$;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
INSERT INTO exchange_tables
|
|
||||||
(name
|
|
||||||
,version
|
|
||||||
,action
|
|
||||||
,partitioned
|
|
||||||
,by_range)
|
|
||||||
VALUES
|
|
||||||
('recoup_refresh'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'create'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('recoup_refresh'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'constrain'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('recoup_refresh'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'foreign'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('recoup_refresh'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'master'
|
|
||||||
,TRUE
|
|
||||||
,FALSE);
|
|
||||||
|
|
@ -1,246 +0,0 @@
|
||||||
--
|
|
||||||
-- This file is part of TALER
|
|
||||||
-- Copyright (C) 2025 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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
-- @author Özgür Kesim
|
|
||||||
|
|
||||||
CREATE FUNCTION create_table_refresh(
|
|
||||||
IN partition_suffix TEXT DEFAULT NULL
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'refresh';
|
|
||||||
BEGIN
|
|
||||||
PERFORM create_partitioned_table(
|
|
||||||
'CREATE TABLE %I'
|
|
||||||
'(refresh_id BIGINT GENERATED BY DEFAULT AS IDENTITY'
|
|
||||||
',rc BYTEA PRIMARY KEY CONSTRAINT rc_length CHECK(LENGTH(rc)=64)'
|
|
||||||
',execution_date INT8 NOT NULL'
|
|
||||||
',amount_with_fee taler_amount NOT NULL'
|
|
||||||
',old_coin_pub BYTEA NOT NULL'
|
|
||||||
',old_coin_sig BYTEA NOT NULL CHECK(LENGTH(old_coin_sig)=64)'
|
|
||||||
',refresh_seed BYTEA NOT NULL'
|
|
||||||
',noreveal_index INT4 NOT NULL CONSTRAINT noreveal_index_positive CHECK(noreveal_index>=0)'
|
|
||||||
',planchets_h BYTEA CONSTRAINT planchets_h_length CHECK(LENGTH(planchets_h)=64)'
|
|
||||||
',selected_h BYTEA CONSTRAINT selected_h_length CHECK(LENGTH(selected_h)=64)'
|
|
||||||
',blinding_seed BYTEA CONSTRAINT blinding_seed_length CHECK(LENGTH(blinding_seed)>=32)'
|
|
||||||
',cs_r_values BYTEA[]'
|
|
||||||
',cs_r_choices INT8'
|
|
||||||
',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 (rc)'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_table(
|
|
||||||
'The data provided by the client for the melting operation of an old coin and he choices made by the exchange '
|
|
||||||
' with respect to the cut-and-choose protocol: nonreveal_index and the corresponding chosen'
|
|
||||||
' blinded coin envelope along with the denomination signatures at the moment of the melting.'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'The hash over the refresh request, which serves as the primary key'
|
|
||||||
' for the lookup during the reveal phase.'
|
|
||||||
,'rc'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'The publice nonce from which all other nonces for all n*kappa coin candidates are derived for which'
|
|
||||||
' the old coin proves ownership via signatures'
|
|
||||||
,'refresh_seed'
|
|
||||||
,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 date of execution of the melting operation, according to the exchange'
|
|
||||||
,'execution_date'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Reference to the public key of the old coin which is melted'
|
|
||||||
,'old_coin_pub'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Signature of the old coin''s private key over the melt request'
|
|
||||||
,'old_coin_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(
|
|
||||||
'The master seed for the blinding nonces, needed for blind CS signatures; maybe NULL'
|
|
||||||
,'blinding_seed'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'The public pairs of R-values provided by the exchange for the CS denominations; might be NULL'
|
|
||||||
,'cs_r_values'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'The bitvector of choices made by the exchange for each of the pairs in cs_r_values; maybe NULL.'
|
|
||||||
'The vector is stored in network byte order and the lowest bit corresponds to the 0-th entry in cs_r_values (pair)'
|
|
||||||
,'cs_r_choices'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'The hash over all kappa*n blinded planchets that were provided by the client'
|
|
||||||
,'planchets_h'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'The hash over the n blinded planchets that were selected by the exchange.'
|
|
||||||
,'selected_h'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Array of signatures, one for each blinded envelope'
|
|
||||||
,'denom_sigs'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION constrain_table_refresh(
|
|
||||||
IN partition_suffix TEXT
|
|
||||||
)
|
|
||||||
RETURNS void
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'refresh';
|
|
||||||
BEGIN
|
|
||||||
table_name = concat_ws('_', table_name, partition_suffix);
|
|
||||||
-- Note: index spans partitions, may need to be materialized.
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'CREATE INDEX ' || table_name || '_by_old_coin_pub_index '
|
|
||||||
'ON ' || table_name || ' '
|
|
||||||
'(old_coin_pub);'
|
|
||||||
);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD CONSTRAINT ' || table_name || '_refresh_id_key'
|
|
||||||
' UNIQUE (refresh_id);'
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION foreign_table_refresh()
|
|
||||||
RETURNS void
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'refresh';
|
|
||||||
BEGIN
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD CONSTRAINT ' || table_name || '_foreign_coin_pub'
|
|
||||||
' FOREIGN KEY (old_coin_pub) '
|
|
||||||
' REFERENCES known_coins (coin_pub) ON DELETE CASCADE'
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
-- Trigger to update the reserve_history table
|
|
||||||
CREATE FUNCTION refresh_insert_trigger()
|
|
||||||
RETURNS trigger
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
BEGIN
|
|
||||||
INSERT INTO coin_history
|
|
||||||
(coin_pub
|
|
||||||
,table_name
|
|
||||||
,serial_id)
|
|
||||||
VALUES
|
|
||||||
(NEW.old_coin_pub
|
|
||||||
,'refresh'
|
|
||||||
,NEW.refresh_id);
|
|
||||||
RETURN NEW;
|
|
||||||
END $$;
|
|
||||||
COMMENT ON FUNCTION refresh_insert_trigger()
|
|
||||||
IS 'Keep track of a particular refresh in the coin_history table.';
|
|
||||||
|
|
||||||
-- Trigger to update the unique_refresh_blinding_seed table
|
|
||||||
CREATE FUNCTION refresh_delete_trigger()
|
|
||||||
RETURNS trigger
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
BEGIN
|
|
||||||
DELETE FROM unique_refresh_blinding_seed
|
|
||||||
WHERE blinding_seed = OLD.blinding_seed;
|
|
||||||
RETURN OLD;
|
|
||||||
END $$;
|
|
||||||
COMMENT ON FUNCTION refresh_delete_trigger()
|
|
||||||
IS 'Delete blinding_seed from unique_refresh_blinding_seed table.';
|
|
||||||
|
|
||||||
-- Put the triggers into the master table
|
|
||||||
CREATE FUNCTION master_table_refresh()
|
|
||||||
RETURNS void
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
BEGIN
|
|
||||||
CREATE TRIGGER refresh_on_insert
|
|
||||||
AFTER INSERT
|
|
||||||
ON refresh
|
|
||||||
FOR EACH ROW EXECUTE FUNCTION refresh_insert_trigger();
|
|
||||||
|
|
||||||
CREATE TRIGGER refresh_on_delete
|
|
||||||
AFTER DELETE
|
|
||||||
ON refresh
|
|
||||||
FOR EACH ROW EXECUTE FUNCTION refresh_delete_trigger();
|
|
||||||
END $$;
|
|
||||||
COMMENT ON FUNCTION master_table_refresh()
|
|
||||||
IS 'Setup triggers to replicate refresh into coin_history and delete blinding_seed from unique_refresh_blinding_seed.';
|
|
||||||
|
|
||||||
|
|
||||||
INSERT INTO exchange_tables
|
|
||||||
(name
|
|
||||||
,version
|
|
||||||
,action
|
|
||||||
,partitioned
|
|
||||||
,by_range)
|
|
||||||
VALUES
|
|
||||||
('refresh', 'exchange-0002', 'create', TRUE ,FALSE),
|
|
||||||
('refresh', 'exchange-0002', 'constrain',TRUE ,FALSE),
|
|
||||||
('refresh', 'exchange-0002', 'foreign', TRUE ,FALSE),
|
|
||||||
('refresh', 'exchange-0002', 'master', TRUE ,FALSE);
|
|
||||||
|
|
||||||
|
|
@ -1,162 +0,0 @@
|
||||||
--
|
|
||||||
-- This file is part of TALER
|
|
||||||
-- Copyright (C) 2014--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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
CREATE FUNCTION create_table_refunds(
|
|
||||||
IN partition_suffix TEXT DEFAULT NULL
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'refunds';
|
|
||||||
BEGIN
|
|
||||||
PERFORM create_partitioned_table(
|
|
||||||
'CREATE TABLE %I'
|
|
||||||
'(refund_serial_id BIGINT GENERATED BY DEFAULT AS IDENTITY'
|
|
||||||
',coin_pub BYTEA NOT NULL CHECK (LENGTH(coin_pub)=32)'
|
|
||||||
',batch_deposit_serial_id INT8 NOT NULL'
|
|
||||||
',merchant_sig BYTEA NOT NULL CHECK(LENGTH(merchant_sig)=64)'
|
|
||||||
',rtransaction_id INT8 NOT NULL'
|
|
||||||
',amount_with_fee taler_amount NOT NULL'
|
|
||||||
') %s ;'
|
|
||||||
,table_name
|
|
||||||
,'PARTITION BY HASH (coin_pub)'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_table(
|
|
||||||
'Data on coins that were refunded. Technically, refunds always apply against specific deposit operations involving a coin. The combination of coin_pub, merchant_pub, h_contract_terms and rtransaction_id MUST be unique, and we usually select by coin_pub so that one goes first.'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Identifies ONLY the merchant_pub, h_contract_terms and coin_pub. Multiple deposits may match a refund, this only identifies one of them.'
|
|
||||||
,'batch_deposit_serial_id'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'used by the merchant to make refunds unique in case the same coin for the same deposit gets a subsequent (higher) refund'
|
|
||||||
,'rtransaction_id'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION constrain_table_refunds (
|
|
||||||
IN partition_suffix TEXT DEFAULT NULL
|
|
||||||
)
|
|
||||||
RETURNS void
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'refunds';
|
|
||||||
BEGIN
|
|
||||||
table_name = concat_ws('_', table_name, partition_suffix);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'CREATE INDEX ' || table_name || '_by_coin_pub_index '
|
|
||||||
'ON ' || table_name || ' '
|
|
||||||
'(coin_pub);'
|
|
||||||
);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD CONSTRAINT ' || table_name || '_refund_serial_id_key'
|
|
||||||
' UNIQUE (refund_serial_id) '
|
|
||||||
',ADD PRIMARY KEY (batch_deposit_serial_id, coin_pub, rtransaction_id) '
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION foreign_table_refunds ()
|
|
||||||
RETURNS void
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'refunds';
|
|
||||||
BEGIN
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD CONSTRAINT ' || table_name || '_foreign_coin_pub'
|
|
||||||
' FOREIGN KEY (coin_pub) '
|
|
||||||
' REFERENCES known_coins (coin_pub) ON DELETE CASCADE'
|
|
||||||
',ADD CONSTRAINT ' || table_name || '_foreign_deposit'
|
|
||||||
' FOREIGN KEY (batch_deposit_serial_id) '
|
|
||||||
' REFERENCES batch_deposits (batch_deposit_serial_id) ON DELETE CASCADE'
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION refunds_insert_trigger()
|
|
||||||
RETURNS trigger
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
BEGIN
|
|
||||||
INSERT INTO exchange.coin_history
|
|
||||||
(coin_pub
|
|
||||||
,table_name
|
|
||||||
,serial_id)
|
|
||||||
VALUES
|
|
||||||
(NEW.coin_pub
|
|
||||||
,'refunds'
|
|
||||||
,NEW.refund_serial_id);
|
|
||||||
RETURN NEW;
|
|
||||||
END $$;
|
|
||||||
COMMENT ON FUNCTION refunds_insert_trigger()
|
|
||||||
IS 'Automatically generate coin history entry.';
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION master_table_refunds()
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
BEGIN
|
|
||||||
CREATE TRIGGER refunds_on_insert
|
|
||||||
AFTER INSERT
|
|
||||||
ON refunds
|
|
||||||
FOR EACH ROW EXECUTE FUNCTION refunds_insert_trigger();
|
|
||||||
END $$;
|
|
||||||
|
|
||||||
|
|
||||||
INSERT INTO exchange_tables
|
|
||||||
(name
|
|
||||||
,version
|
|
||||||
,action
|
|
||||||
,partitioned
|
|
||||||
,by_range)
|
|
||||||
VALUES
|
|
||||||
('refunds'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'create'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('refunds'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'constrain'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('refunds'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'foreign'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('refunds'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'master'
|
|
||||||
,TRUE
|
|
||||||
,FALSE);
|
|
||||||
|
|
@ -1,138 +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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
CREATE FUNCTION create_table_reserve_history (
|
|
||||||
IN partition_suffix TEXT DEFAULT NULL
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'reserve_history';
|
|
||||||
BEGIN
|
|
||||||
PERFORM create_partitioned_table(
|
|
||||||
'CREATE TABLE %I'
|
|
||||||
'(reserve_history_serial_id INT8 GENERATED BY DEFAULT AS IDENTITY'
|
|
||||||
',reserve_pub BYTEA NOT NULL CHECK (LENGTH(reserve_pub)=32)'
|
|
||||||
',table_name TEXT NOT NULL'
|
|
||||||
',serial_id INT8 NOT NULL'
|
|
||||||
') %s ;'
|
|
||||||
,table_name
|
|
||||||
,'PARTITION BY HASH (reserve_pub)'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_table(
|
|
||||||
'Links to tables with entries that affected the transaction history of a reserve.'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'For which reserve is this a history entry'
|
|
||||||
,'reserve_pub'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'In which table is the history entry'
|
|
||||||
,'table_name'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Which is the generated serial ID of the entry in the table'
|
|
||||||
,'serial_id'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Monotonic counter, used to generate Etags for caching'
|
|
||||||
,'reserve_history_serial_id'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION constrain_table_reserve_history(
|
|
||||||
IN partition_suffix TEXT
|
|
||||||
)
|
|
||||||
RETURNS void
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'reserve_history';
|
|
||||||
BEGIN
|
|
||||||
table_name = concat_ws('_', table_name, partition_suffix);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD CONSTRAINT ' || table_name || '_reserve_history_serial_id_pkey'
|
|
||||||
' PRIMARY KEY (reserve_history_serial_id) '
|
|
||||||
',ADD CONSTRAINT ' || table_name || '_reserve_entry_key'
|
|
||||||
' UNIQUE (reserve_pub, table_name, serial_id)'
|
|
||||||
);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'CREATE INDEX ' || table_name || '_reserve_by_time'
|
|
||||||
' ON ' || table_name || ' '
|
|
||||||
'(reserve_pub'
|
|
||||||
',reserve_history_serial_id DESC'
|
|
||||||
');'
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION foreign_table_reserve_history()
|
|
||||||
RETURNS void
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'reserve_history';
|
|
||||||
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
|
|
||||||
('reserve_history'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'create'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('reserve_history'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'constrain'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('reserve_history'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'foreign'
|
|
||||||
,TRUE
|
|
||||||
,FALSE)
|
|
||||||
;
|
|
||||||
|
|
@ -1,152 +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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
CREATE FUNCTION create_table_reserves(
|
|
||||||
IN partition_suffix TEXT DEFAULT NULL
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'reserves';
|
|
||||||
BEGIN
|
|
||||||
PERFORM create_partitioned_table(
|
|
||||||
'CREATE TABLE %I'
|
|
||||||
'(reserve_uuid BIGINT GENERATED BY DEFAULT AS IDENTITY'
|
|
||||||
',reserve_pub BYTEA PRIMARY KEY CHECK(LENGTH(reserve_pub)=32)'
|
|
||||||
',current_balance taler_amount NOT NULL DEFAULT (0, 0)'
|
|
||||||
',purses_active INT8 NOT NULL DEFAULT(0)'
|
|
||||||
',purses_allowed INT8 NOT NULL DEFAULT(0)'
|
|
||||||
',birthday INT4 NOT NULL DEFAULT(0)'
|
|
||||||
',expiration_date INT8 NOT NULL'
|
|
||||||
',gc_date INT8 NOT NULL'
|
|
||||||
') %s ;'
|
|
||||||
,table_name
|
|
||||||
,'PARTITION BY HASH (reserve_pub)'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_table(
|
|
||||||
'Summarizes the balance of a reserve. Updated when new funds are added or withdrawn.'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'EdDSA public key of the reserve. Knowledge of the private key implies ownership over the balance.'
|
|
||||||
,'reserve_pub'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Current balance remaining with the reserve.'
|
|
||||||
,'current_balance'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Number of purses that were created by this reserve that are not expired and not fully paid.'
|
|
||||||
,'purses_active'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Number of purses that this reserve is allowed to have active at most.'
|
|
||||||
,'purses_allowed'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Used to trigger closing of reserves that have not been drained after some time'
|
|
||||||
,'expiration_date'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Used to forget all information about a reserve during garbage collection'
|
|
||||||
,'gc_date'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Birthday of the user in days after 1970, or 0 if user is an adult and is not subject to age restrictions'
|
|
||||||
,'birthday'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION constrain_table_reserves(
|
|
||||||
IN partition_suffix TEXT
|
|
||||||
)
|
|
||||||
RETURNS void
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'reserves';
|
|
||||||
BEGIN
|
|
||||||
table_name = concat_ws('_', table_name, partition_suffix);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD CONSTRAINT ' || table_name || '_unique_uuid'
|
|
||||||
' UNIQUE (reserve_uuid)'
|
|
||||||
);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'CREATE INDEX ' || table_name || '_by_expiration_index '
|
|
||||||
'ON ' || table_name || ' '
|
|
||||||
'(expiration_date'
|
|
||||||
',current_balance'
|
|
||||||
');'
|
|
||||||
);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'COMMENT ON INDEX ' || table_name || '_by_expiration_index '
|
|
||||||
'IS ' || quote_literal('used in get_expired_reserves') || ';'
|
|
||||||
);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'CREATE INDEX ' || table_name || '_by_reserve_uuid_index '
|
|
||||||
'ON ' || table_name || ' '
|
|
||||||
'(reserve_uuid);'
|
|
||||||
);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'CREATE INDEX ' || table_name || '_by_gc_date_index '
|
|
||||||
'ON ' || table_name || ' '
|
|
||||||
'(gc_date);'
|
|
||||||
);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'COMMENT ON INDEX ' || table_name || '_by_gc_date_index '
|
|
||||||
'IS ' || quote_literal('for reserve garbage collection') || ';'
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
INSERT INTO exchange_tables
|
|
||||||
(name
|
|
||||||
,version
|
|
||||||
,action
|
|
||||||
,partitioned
|
|
||||||
,by_range)
|
|
||||||
VALUES
|
|
||||||
('reserves'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'create'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('reserves'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'constrain'
|
|
||||||
,TRUE
|
|
||||||
,FALSE);
|
|
||||||
|
|
@ -1,151 +0,0 @@
|
||||||
--
|
|
||||||
-- This file is part of TALER
|
|
||||||
-- Copyright (C) 2014--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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
CREATE FUNCTION create_table_reserves_close(
|
|
||||||
IN partition_suffix TEXT DEFAULT NULL
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT default 'reserves_close';
|
|
||||||
BEGIN
|
|
||||||
PERFORM create_partitioned_table(
|
|
||||||
'CREATE TABLE %I'
|
|
||||||
'(close_uuid BIGINT GENERATED BY DEFAULT AS IDENTITY'
|
|
||||||
',reserve_pub BYTEA NOT NULL'
|
|
||||||
',execution_date INT8 NOT NULL'
|
|
||||||
',wtid BYTEA NOT NULL CHECK (LENGTH(wtid)=32)'
|
|
||||||
',wire_target_h_payto BYTEA CHECK (LENGTH(wire_target_h_payto)=32)'
|
|
||||||
',amount taler_amount NOT NULL'
|
|
||||||
',closing_fee taler_amount NOT NULL'
|
|
||||||
',close_request_row INT8 NOT NULL DEFAULT(0)'
|
|
||||||
') %s ;'
|
|
||||||
,table_name
|
|
||||||
,'PARTITION BY HASH (reserve_pub)'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_table(
|
|
||||||
'wire transfers executed by the reserve to close reserves'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Identifies the credited bank account (and KYC status). Note that closing does not depend on KYC.'
|
|
||||||
,'wire_target_h_payto'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION constrain_table_reserves_close(
|
|
||||||
IN partition_suffix TEXT
|
|
||||||
)
|
|
||||||
RETURNS void
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT default 'reserves_close';
|
|
||||||
BEGIN
|
|
||||||
table_name = concat_ws('_', table_name, partition_suffix);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD CONSTRAINT ' || table_name || '_close_uuid_pkey'
|
|
||||||
' PRIMARY KEY (close_uuid)'
|
|
||||||
);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'CREATE INDEX ' || table_name || '_by_reserve_pub_index '
|
|
||||||
'ON ' || table_name || ' (reserve_pub);'
|
|
||||||
);
|
|
||||||
END $$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION foreign_table_reserves_close()
|
|
||||||
RETURNS void
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT default 'reserves_close';
|
|
||||||
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 $$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION reserves_close_insert_trigger()
|
|
||||||
RETURNS trigger
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
BEGIN
|
|
||||||
INSERT INTO reserve_history
|
|
||||||
(reserve_pub
|
|
||||||
,table_name
|
|
||||||
,serial_id)
|
|
||||||
VALUES
|
|
||||||
(NEW.reserve_pub
|
|
||||||
,'reserves_close'
|
|
||||||
,NEW.close_uuid);
|
|
||||||
RETURN NEW;
|
|
||||||
END $$;
|
|
||||||
COMMENT ON FUNCTION reserves_close_insert_trigger()
|
|
||||||
IS 'Automatically generate reserve history entry.';
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION master_table_reserves_close()
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
BEGIN
|
|
||||||
CREATE TRIGGER reserves_close_on_insert
|
|
||||||
AFTER INSERT
|
|
||||||
ON reserves_close
|
|
||||||
FOR EACH ROW EXECUTE FUNCTION reserves_close_insert_trigger();
|
|
||||||
END $$;
|
|
||||||
|
|
||||||
|
|
||||||
INSERT INTO exchange_tables
|
|
||||||
(name
|
|
||||||
,version
|
|
||||||
,action
|
|
||||||
,partitioned
|
|
||||||
,by_range)
|
|
||||||
VALUES
|
|
||||||
('reserves_close'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'create'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('reserves_close'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'constrain'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('reserves_close'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'foreign'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('reserves_close'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'master'
|
|
||||||
,TRUE
|
|
||||||
,FALSE);
|
|
||||||
|
|
@ -1,162 +0,0 @@
|
||||||
--
|
|
||||||
-- This file is part of TALER
|
|
||||||
-- Copyright (C) 2014--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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
CREATE FUNCTION create_table_reserves_in(
|
|
||||||
IN partition_suffix TEXT DEFAULT NULL
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT default 'reserves_in';
|
|
||||||
BEGIN
|
|
||||||
PERFORM create_partitioned_table(
|
|
||||||
'CREATE TABLE %I'
|
|
||||||
'(reserve_in_serial_id BIGINT GENERATED BY DEFAULT AS IDENTITY'
|
|
||||||
',reserve_pub BYTEA PRIMARY KEY'
|
|
||||||
',wire_reference INT8 NOT NULL'
|
|
||||||
',credit taler_amount NOT NULL'
|
|
||||||
',wire_source_h_payto BYTEA CHECK (LENGTH(wire_source_h_payto)=32)'
|
|
||||||
',exchange_account_section TEXT NOT NULL'
|
|
||||||
',execution_date INT8 NOT NULL'
|
|
||||||
') %s ;'
|
|
||||||
,table_name
|
|
||||||
,'PARTITION BY HASH (reserve_pub)'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_table(
|
|
||||||
'list of transfers of funds into the reserves, one per incoming wire transfer'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Identifies the debited bank account and KYC status'
|
|
||||||
,'wire_source_h_payto'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Public key of the reserve. Private key signifies ownership of the remaining balance.'
|
|
||||||
,'reserve_pub'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Amount that was transferred into the reserve'
|
|
||||||
,'credit'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
END $$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION constrain_table_reserves_in(
|
|
||||||
IN partition_suffix TEXT
|
|
||||||
)
|
|
||||||
RETURNS void
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT default 'reserves_in';
|
|
||||||
BEGIN
|
|
||||||
table_name = concat_ws('_', table_name, partition_suffix);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD CONSTRAINT ' || table_name || '_reserve_in_serial_id_key'
|
|
||||||
' UNIQUE (reserve_in_serial_id)'
|
|
||||||
);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'CREATE INDEX ' || table_name || '_by_reserve_in_serial_id_index '
|
|
||||||
'ON ' || table_name || ' '
|
|
||||||
'(reserve_in_serial_id);'
|
|
||||||
);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'CREATE INDEX ' || table_name || '_by_exch_accnt_reserve_in_serial_id_idx '
|
|
||||||
'ON ' || table_name || ' '
|
|
||||||
'(exchange_account_section'
|
|
||||||
',reserve_in_serial_id ASC'
|
|
||||||
');'
|
|
||||||
);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'COMMENT ON INDEX ' || table_name || '_by_exch_accnt_reserve_in_serial_id_idx '
|
|
||||||
'IS ' || quote_literal ('for pg_select_reserves_in_above_serial_id_by_account') || ';'
|
|
||||||
);
|
|
||||||
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
CREATE FUNCTION foreign_table_reserves_in()
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'reserves_in';
|
|
||||||
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'
|
|
||||||
);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD CONSTRAINT ' || table_name || '_wire_target_h_payto_foreign'
|
|
||||||
' FOREIGN KEY (wire_source_h_payto)'
|
|
||||||
' REFERENCES wire_targets (wire_target_h_payto)'
|
|
||||||
' ON DELETE RESTRICT'
|
|
||||||
);
|
|
||||||
END $$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION master_table_reserves_in()
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
BEGIN
|
|
||||||
CREATE TRIGGER reserves_in_on_insert
|
|
||||||
AFTER INSERT
|
|
||||||
ON reserves_in
|
|
||||||
FOR EACH ROW EXECUTE FUNCTION reserves_in_insert_trigger();
|
|
||||||
END $$;
|
|
||||||
|
|
||||||
|
|
||||||
INSERT INTO exchange_tables
|
|
||||||
(name
|
|
||||||
,version
|
|
||||||
,action
|
|
||||||
,partitioned
|
|
||||||
,by_range)
|
|
||||||
VALUES
|
|
||||||
('reserves_in'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'create'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('reserves_in'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'constrain'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('reserves_in'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'foreign'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('reserves_in'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'master'
|
|
||||||
,TRUE
|
|
||||||
,FALSE);
|
|
||||||
|
|
@ -1,135 +0,0 @@
|
||||||
--
|
|
||||||
-- This file is part of TALER
|
|
||||||
-- Copyright (C) 2014--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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
CREATE FUNCTION create_table_reserves_open_deposits(
|
|
||||||
IN partition_suffix TEXT DEFAULT NULL
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT default 'reserves_open_deposits';
|
|
||||||
BEGIN
|
|
||||||
PERFORM create_partitioned_table(
|
|
||||||
'CREATE TABLE %I'
|
|
||||||
'(reserve_open_deposit_uuid BIGINT GENERATED BY DEFAULT AS IDENTITY'
|
|
||||||
',reserve_sig BYTEA NOT NULL CHECK (LENGTH(reserve_sig)=64)'
|
|
||||||
',reserve_pub BYTEA NOT NULL CHECK (LENGTH(reserve_pub)=32)'
|
|
||||||
',coin_pub BYTEA NOT NULL CHECK (LENGTH(coin_pub)=32)'
|
|
||||||
',coin_sig BYTEA NOT NULL CHECK (LENGTH(coin_sig)=64)'
|
|
||||||
',contribution taler_amount NOT NULL'
|
|
||||||
') %s ;'
|
|
||||||
,table_name
|
|
||||||
,'PARTITION BY HASH (coin_pub)'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_table(
|
|
||||||
'coin contributions paying for a reserve to remain open'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Identifies the specific reserve being paid for (possibly together with reserve_sig).'
|
|
||||||
,'reserve_pub'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION constrain_table_reserves_open_deposits(
|
|
||||||
IN partition_suffix TEXT
|
|
||||||
)
|
|
||||||
RETURNS void
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT default 'reserves_open_deposits';
|
|
||||||
BEGIN
|
|
||||||
table_name = concat_ws('_', table_name, partition_suffix);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name || ' '
|
|
||||||
'ADD CONSTRAINT ' || table_name || '_coin_unique '
|
|
||||||
'PRIMARY KEY (coin_pub,coin_sig)'
|
|
||||||
);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'CREATE INDEX ' || table_name || '_by_uuid '
|
|
||||||
'ON ' || table_name || ' '
|
|
||||||
'(reserve_open_deposit_uuid);'
|
|
||||||
);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'CREATE INDEX ' || table_name || '_by_reserve '
|
|
||||||
'ON ' || table_name || ' '
|
|
||||||
'(reserve_pub);'
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION reserves_open_deposits_insert_trigger()
|
|
||||||
RETURNS trigger
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
BEGIN
|
|
||||||
INSERT INTO exchange.coin_history
|
|
||||||
(coin_pub
|
|
||||||
,table_name
|
|
||||||
,serial_id)
|
|
||||||
VALUES
|
|
||||||
(NEW.coin_pub
|
|
||||||
,'reserves_open_deposits'
|
|
||||||
,NEW.reserve_open_deposit_uuid);
|
|
||||||
RETURN NEW;
|
|
||||||
END $$;
|
|
||||||
COMMENT ON FUNCTION reserves_open_deposits_insert_trigger()
|
|
||||||
IS 'Automatically generate coin history entry.';
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION master_table_reserves_open_deposits()
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
BEGIN
|
|
||||||
CREATE TRIGGER reserves_open_deposits_on_insert
|
|
||||||
AFTER INSERT
|
|
||||||
ON reserves_open_deposits
|
|
||||||
FOR EACH ROW EXECUTE FUNCTION reserves_open_deposits_insert_trigger();
|
|
||||||
END $$;
|
|
||||||
|
|
||||||
|
|
||||||
INSERT INTO exchange_tables
|
|
||||||
(name
|
|
||||||
,version
|
|
||||||
,action
|
|
||||||
,partitioned
|
|
||||||
,by_range)
|
|
||||||
VALUES
|
|
||||||
('reserves_open_deposits'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'create'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('reserves_open_deposits'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'constrain'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('reserves_open_deposits'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'master'
|
|
||||||
,TRUE
|
|
||||||
,FALSE);
|
|
||||||
|
|
@ -1,150 +0,0 @@
|
||||||
--
|
|
||||||
-- This file is part of TALER
|
|
||||||
-- Copyright (C) 2014--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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
CREATE FUNCTION create_table_reserves_open_requests(
|
|
||||||
IN partition_suffix TEXT DEFAULT NULL
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT default 'reserves_open_requests';
|
|
||||||
BEGIN
|
|
||||||
PERFORM create_partitioned_table(
|
|
||||||
'CREATE TABLE %I'
|
|
||||||
'(open_request_uuid BIGINT GENERATED BY DEFAULT AS IDENTITY'
|
|
||||||
',reserve_pub BYTEA NOT NULL'
|
|
||||||
',request_timestamp INT8 NOT NULL'
|
|
||||||
',expiration_date INT8 NOT NULL'
|
|
||||||
',reserve_sig BYTEA NOT NULL CHECK (LENGTH(reserve_sig)=64)'
|
|
||||||
',reserve_payment taler_amount NOT NULL'
|
|
||||||
',requested_purse_limit INT4 NOT NULL'
|
|
||||||
') %s ;'
|
|
||||||
,table_name
|
|
||||||
,'PARTITION BY HASH (reserve_pub)'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_table (
|
|
||||||
'requests to keep a reserve open'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column (
|
|
||||||
'Fee to pay for the request from the reserve balance itself.'
|
|
||||||
,'reserve_payment'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION constrain_table_reserves_open_requests(
|
|
||||||
IN partition_suffix TEXT
|
|
||||||
)
|
|
||||||
RETURNS void
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT default 'reserves_open_requests';
|
|
||||||
BEGIN
|
|
||||||
table_name = concat_ws('_', table_name, partition_suffix);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD CONSTRAINT ' || table_name || '_by_uuid'
|
|
||||||
' PRIMARY KEY (open_request_uuid)'
|
|
||||||
',ADD CONSTRAINT ' || table_name || '_by_time'
|
|
||||||
' UNIQUE (reserve_pub,request_timestamp)'
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION foreign_table_reserves_open_requests()
|
|
||||||
RETURNS void
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT default 'reserves_open_requests';
|
|
||||||
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
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION reserves_open_requests_insert_trigger()
|
|
||||||
RETURNS trigger
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
BEGIN
|
|
||||||
INSERT INTO reserve_history
|
|
||||||
(reserve_pub
|
|
||||||
,table_name
|
|
||||||
,serial_id)
|
|
||||||
VALUES
|
|
||||||
(NEW.reserve_pub
|
|
||||||
,'reserves_open_requests'
|
|
||||||
,NEW.open_request_uuid);
|
|
||||||
RETURN NEW;
|
|
||||||
END $$;
|
|
||||||
COMMENT ON FUNCTION reserves_open_requests_insert_trigger()
|
|
||||||
IS 'Automatically generate reserve history entry.';
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION master_table_reserves_open_requests()
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
BEGIN
|
|
||||||
CREATE TRIGGER reserves_open_requests_on_insert
|
|
||||||
AFTER INSERT
|
|
||||||
ON reserves_open_requests
|
|
||||||
FOR EACH ROW EXECUTE FUNCTION reserves_open_requests_insert_trigger();
|
|
||||||
END $$;
|
|
||||||
|
|
||||||
|
|
||||||
INSERT INTO exchange_tables
|
|
||||||
(name
|
|
||||||
,version
|
|
||||||
,action
|
|
||||||
,partitioned
|
|
||||||
,by_range)
|
|
||||||
VALUES
|
|
||||||
('reserves_open_requests'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'create'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('reserves_open_requests'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'constrain'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('reserves_open_requests'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'foreign'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('reserves_open_requests'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'master'
|
|
||||||
,TRUE
|
|
||||||
,FALSE);
|
|
||||||
|
|
@ -1,46 +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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
CREATE UNLOGGED TABLE revolving_work_shards
|
|
||||||
(shard_serial_id BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE
|
|
||||||
,last_attempt INT8 NOT NULL
|
|
||||||
,start_row INT4 NOT NULL
|
|
||||||
,end_row INT4 NOT NULL
|
|
||||||
,active BOOLEAN NOT NULL DEFAULT FALSE
|
|
||||||
,job_name TEXT NOT NULL
|
|
||||||
,PRIMARY KEY (job_name, start_row)
|
|
||||||
);
|
|
||||||
COMMENT ON TABLE revolving_work_shards
|
|
||||||
IS 'coordinates work between multiple processes working on the same job with partitions that need to be repeatedly processed; unlogged because on system crashes the locks represented by this table will have to be cleared anyway, typically using "taler-exchange-dbinit -s"';
|
|
||||||
COMMENT ON COLUMN revolving_work_shards.shard_serial_id
|
|
||||||
IS 'unique serial number identifying the shard';
|
|
||||||
COMMENT ON COLUMN revolving_work_shards.last_attempt
|
|
||||||
IS 'last time a worker attempted to work on the shard';
|
|
||||||
COMMENT ON COLUMN revolving_work_shards.active
|
|
||||||
IS 'set to TRUE when a worker is active on the shard';
|
|
||||||
COMMENT ON COLUMN revolving_work_shards.start_row
|
|
||||||
IS 'row at which the shard scope starts, inclusive';
|
|
||||||
COMMENT ON COLUMN revolving_work_shards.end_row
|
|
||||||
IS 'row at which the shard scope ends, exclusive';
|
|
||||||
COMMENT ON COLUMN revolving_work_shards.job_name
|
|
||||||
IS 'unique name of the job the workers on this shard are performing';
|
|
||||||
|
|
||||||
CREATE INDEX revolving_work_shards_by_job_name_active_last_attempt_index
|
|
||||||
ON revolving_work_shards
|
|
||||||
(job_name
|
|
||||||
,active
|
|
||||||
,last_attempt
|
|
||||||
);
|
|
||||||
|
|
@ -1,23 +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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
CREATE TABLE signkey_revocations
|
|
||||||
(signkey_revocations_serial_id BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE
|
|
||||||
,esk_serial INT8 PRIMARY KEY REFERENCES exchange_sign_keys (esk_serial) ON DELETE CASCADE
|
|
||||||
,master_sig BYTEA NOT NULL CHECK (LENGTH(master_sig)=64)
|
|
||||||
);
|
|
||||||
COMMENT ON TABLE signkey_revocations
|
|
||||||
IS 'Table storing which online signing keys have been revoked';
|
|
||||||
|
|
@ -1,590 +0,0 @@
|
||||||
--
|
|
||||||
-- This file is part of TALER
|
|
||||||
-- Copyright (C) 2025 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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
-- Ranges given here must be supported by the date_trunc function of Postgresql!
|
|
||||||
CREATE TYPE statistic_range AS
|
|
||||||
ENUM('century', 'decade', 'year', 'quarter', 'month', 'week', 'day', 'hour', 'minute', 'second');
|
|
||||||
|
|
||||||
CREATE TYPE statistic_type AS
|
|
||||||
ENUM('amount', 'number');
|
|
||||||
|
|
||||||
-- -------------- Bucket statistics ---------------------
|
|
||||||
|
|
||||||
CREATE TABLE exchange_statistic_bucket_meta
|
|
||||||
(bmeta_serial_id INT8 GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY
|
|
||||||
,origin TEXT NOT NULL
|
|
||||||
,slug TEXT NOT NULL
|
|
||||||
,description TEXT NOT NULL
|
|
||||||
,stype statistic_type NOT NULL
|
|
||||||
,ranges statistic_range[] NOT NULL
|
|
||||||
,ages INT4[] NOT NULL
|
|
||||||
,UNIQUE(slug,stype)
|
|
||||||
,CONSTRAINT equal_array_length
|
|
||||||
CHECK (array_length(ranges,1) =
|
|
||||||
array_length(ages,1))
|
|
||||||
);
|
|
||||||
COMMENT ON TABLE exchange_statistic_bucket_meta
|
|
||||||
IS 'meta data about a statistic with events falling into buckets we are tracking';
|
|
||||||
COMMENT ON COLUMN exchange_statistic_bucket_meta.bmeta_serial_id
|
|
||||||
IS 'unique identifier for this type of bucket statistic we are tracking';
|
|
||||||
COMMENT ON COLUMN exchange_statistic_bucket_meta.origin
|
|
||||||
IS 'which customization schema does this statistic originate from (used for easy deletion)';
|
|
||||||
COMMENT ON COLUMN exchange_statistic_bucket_meta.slug
|
|
||||||
IS 'keyword (or name) of the statistic; identifies what the statistic is about; should be a slug suitable for a URI path';
|
|
||||||
COMMENT ON COLUMN exchange_statistic_bucket_meta.description
|
|
||||||
IS 'description of the statistic being tracked';
|
|
||||||
COMMENT ON COLUMN exchange_statistic_bucket_meta.stype
|
|
||||||
IS 'statistic type, what kind of data is being tracked, amount or number';
|
|
||||||
COMMENT ON COLUMN exchange_statistic_bucket_meta.ranges
|
|
||||||
IS 'size of the buckets that are being kept for this statistic';
|
|
||||||
COMMENT ON COLUMN exchange_statistic_bucket_meta.ages
|
|
||||||
IS 'determines how long into the past we keep buckets for the range at the given index around (in generations)';
|
|
||||||
CREATE INDEX exchange_statistic_bucket_meta_by_origin
|
|
||||||
ON exchange_statistic_bucket_meta
|
|
||||||
(origin);
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION create_table_exchange_statistic_bucket_counter (
|
|
||||||
IN partition_suffix TEXT DEFAULT NULL
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
BEGIN
|
|
||||||
PERFORM create_partitioned_table (
|
|
||||||
'CREATE TABLE %I'
|
|
||||||
'(bmeta_serial_id INT8 NOT NULL'
|
|
||||||
' REFERENCES exchange_statistic_bucket_meta (bmeta_serial_id) ON DELETE CASCADE'
|
|
||||||
',h_payto BYTEA CHECK (LENGTH(h_payto)=32)'
|
|
||||||
',bucket_start INT8 NOT NULL'
|
|
||||||
',bucket_range statistic_range NOT NULL'
|
|
||||||
',cumulative_number INT8 NOT NULL'
|
|
||||||
',UNIQUE (h_payto,bmeta_serial_id,bucket_start,bucket_range)'
|
|
||||||
') %s;'
|
|
||||||
,'exchange_statistic_bucket_counter'
|
|
||||||
,'PARTITION BY HASH (h_payto)'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_table(
|
|
||||||
'various numeric statistics (cumulative counters) being tracked by bucket into which they fall'
|
|
||||||
,'exchange_statistic_bucket_counter'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'identifies what the statistic is about'
|
|
||||||
,'bmeta_serial_id'
|
|
||||||
,'exchange_statistic_bucket_counter'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'identifies an account (hash of normalized payto) for which the statistic is kept, NULL for global statistics'
|
|
||||||
,'h_payto'
|
|
||||||
,'exchange_statistic_bucket_counter'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'start date for the bucket in seconds since the epoch'
|
|
||||||
,'bucket_start'
|
|
||||||
,'exchange_statistic_bucket_counter'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'range of the bucket'
|
|
||||||
,'bucket_range'
|
|
||||||
,'exchange_statistic_bucket_counter'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'aggregate (sum) of tracked by the statistic; what exactly is tracked is determined by the keyword'
|
|
||||||
,'cumulative_number'
|
|
||||||
,'exchange_statistic_bucket_counter'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
END $$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION create_table_exchange_statistic_bucket_amount (
|
|
||||||
IN partition_suffix TEXT DEFAULT NULL
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
BEGIN
|
|
||||||
PERFORM create_partitioned_table (
|
|
||||||
'CREATE TABLE %I'
|
|
||||||
'(bmeta_serial_id INT8 NOT NULL'
|
|
||||||
' REFERENCES exchange_statistic_bucket_meta (bmeta_serial_id) ON DELETE CASCADE'
|
|
||||||
',h_payto BYTEA CHECK (LENGTH(h_payto)=32)'
|
|
||||||
',bucket_start INT8 NOT NULL'
|
|
||||||
',bucket_range statistic_range NOT NULL'
|
|
||||||
',cumulative_value taler_amount NOT NULL'
|
|
||||||
',CHECK ((cumulative_value).val IS NOT NULL AND (cumulative_value).frac IS NOT NULL)'
|
|
||||||
',UNIQUE (h_payto,bmeta_serial_id,bucket_start,bucket_range)'
|
|
||||||
') %s;'
|
|
||||||
,'exchange_statistic_bucket_amount'
|
|
||||||
,'PARTITION BY HASH(h_payto)'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_table (
|
|
||||||
'various amount statistics being tracked'
|
|
||||||
,'exchange_statistic_bucket_amount'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'identifies what the statistic is about'
|
|
||||||
,'bmeta_serial_id'
|
|
||||||
,'exchange_statistic_bucket_amount'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column (
|
|
||||||
'identifies an account (hash of normalized payto) for which the statistic is kept, NULL for global statistics'
|
|
||||||
,'h_payto'
|
|
||||||
,'exchange_statistic_bucket_amount'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'start date for the bucket in seconds since the epoch'
|
|
||||||
,'bucket_start'
|
|
||||||
,'exchange_statistic_bucket_amount'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'range of the bucket'
|
|
||||||
,'bucket_range'
|
|
||||||
,'exchange_statistic_bucket_amount'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'amount being tracked'
|
|
||||||
,'cumulative_value'
|
|
||||||
,'exchange_statistic_bucket_amount'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
END $$;
|
|
||||||
|
|
||||||
|
|
||||||
-- -------------- Interval statistics ---------------------
|
|
||||||
|
|
||||||
|
|
||||||
CREATE TABLE exchange_statistic_interval_meta
|
|
||||||
(imeta_serial_id INT8 GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY
|
|
||||||
,origin TEXT NOT NULL
|
|
||||||
,slug TEXT NOT NULL
|
|
||||||
,description TEXT NOT NULL
|
|
||||||
,stype statistic_type NOT NULL
|
|
||||||
,ranges INT8[] NOT NULL CHECK (array_length(ranges,1) > 0)
|
|
||||||
,precisions INT8[] NOT NULL CHECK (array_length(precisions,1) > 0)
|
|
||||||
,UNIQUE(slug,stype)
|
|
||||||
,CONSTRAINT equal_array_length
|
|
||||||
CHECK (array_length(ranges,1) =
|
|
||||||
array_length(precisions,1))
|
|
||||||
);
|
|
||||||
COMMENT ON TABLE exchange_statistic_interval_meta
|
|
||||||
IS 'meta data about an interval statistic we are tracking';
|
|
||||||
COMMENT ON COLUMN exchange_statistic_interval_meta.imeta_serial_id
|
|
||||||
IS 'unique identifier for this type of interval statistic we are tracking';
|
|
||||||
COMMENT ON COLUMN exchange_statistic_interval_meta.origin
|
|
||||||
IS 'which customization schema does this statistic originate from (used for easy deletion)';
|
|
||||||
COMMENT ON COLUMN exchange_statistic_interval_meta.slug
|
|
||||||
IS 'keyword (or name) of the statistic; identifies what the statistic is about; should be a slug suitable for a URI path';
|
|
||||||
COMMENT ON COLUMN exchange_statistic_interval_meta.description
|
|
||||||
IS 'description of the statistic being tracked';
|
|
||||||
COMMENT ON COLUMN exchange_statistic_interval_meta.stype
|
|
||||||
IS 'statistic type, what kind of data is being tracked, amount or number';
|
|
||||||
COMMENT ON COLUMN exchange_statistic_interval_meta.ranges
|
|
||||||
IS 'range of values that is being kept for this statistic, in seconds, must be monotonically increasing';
|
|
||||||
COMMENT ON COLUMN exchange_statistic_interval_meta.precisions
|
|
||||||
IS 'determines how precisely we track which events fall into the range at the same index (allowing us to coalesce events with timestamps in proximity close to the given precision), in seconds, 0 is not allowed';
|
|
||||||
CREATE INDEX exchange_statistic_interval_meta_by_origin
|
|
||||||
ON exchange_statistic_interval_meta
|
|
||||||
(origin);
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION create_table_exchange_statistic_counter_event (
|
|
||||||
IN partition_suffix TEXT DEFAULT NULL
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
BEGIN
|
|
||||||
PERFORM create_partitioned_table(
|
|
||||||
'CREATE TABLE %I'
|
|
||||||
'(nevent_serial_id INT8 GENERATED BY DEFAULT AS IDENTITY'
|
|
||||||
',imeta_serial_id INT8'
|
|
||||||
' REFERENCES exchange_statistic_interval_meta (imeta_serial_id) ON DELETE CASCADE'
|
|
||||||
',h_payto BYTEA CHECK (LENGTH(h_payto)=32)'
|
|
||||||
',slot INT8 NOT NULL'
|
|
||||||
',delta INT8 NOT NULL'
|
|
||||||
',UNIQUE (h_payto,imeta_serial_id,slot)'
|
|
||||||
') %s ;'
|
|
||||||
,'exchange_statistic_counter_event'
|
|
||||||
,'PARTITION BY HASH(h_payto)'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_table(
|
|
||||||
'number to decrement an interval statistic by when a certain time value is reached'
|
|
||||||
,'exchange_statistic_counter_event'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'unique identifier for this number event'
|
|
||||||
,'nevent_serial_id'
|
|
||||||
,'exchange_statistic_counter_event'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'identifies what the statistic is about; must be of stype number'
|
|
||||||
,'imeta_serial_id'
|
|
||||||
,'exchange_statistic_counter_event'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'identifies an account (hash of normalized payto) for which the statistic is kept, NULL for global statistics'
|
|
||||||
,'h_payto'
|
|
||||||
,'exchange_statistic_counter_event'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'identifies the time slot at which the given event(s) happened, rounded down by the respective precisions value'
|
|
||||||
,'slot'
|
|
||||||
,'exchange_statistic_counter_event'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'total cumulative number that was added at the time identified by slot'
|
|
||||||
,'delta'
|
|
||||||
,'exchange_statistic_counter_event'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
END $$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION constrain_table_exchange_statistic_counter_event(
|
|
||||||
IN partition_suffix TEXT
|
|
||||||
)
|
|
||||||
RETURNS void
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT default 'exchange_statistic_counter_event';
|
|
||||||
BEGIN
|
|
||||||
table_name = concat_ws('_', table_name, partition_suffix);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD CONSTRAINT ' || table_name || '_nevent_serial_id_key'
|
|
||||||
' UNIQUE (nevent_serial_id)'
|
|
||||||
);
|
|
||||||
END $$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION create_table_exchange_statistic_interval_counter (
|
|
||||||
IN partition_suffix TEXT DEFAULT NULL
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
BEGIN
|
|
||||||
PERFORM create_partitioned_table(
|
|
||||||
'CREATE TABLE %I'
|
|
||||||
'(imeta_serial_id INT8 NOT NULL'
|
|
||||||
' REFERENCES exchange_statistic_interval_meta (imeta_serial_id) ON DELETE CASCADE'
|
|
||||||
',h_payto BYTEA CHECK (LENGTH(h_payto)=32)'
|
|
||||||
',range INT8 NOT NULL'
|
|
||||||
',event_delimiter INT8 NOT NULL'
|
|
||||||
',cumulative_number INT8 NOT NULL'
|
|
||||||
',UNIQUE (h_payto,imeta_serial_id,range)'
|
|
||||||
') %s ;'
|
|
||||||
,'exchange_statistic_interval_counter'
|
|
||||||
,'PARTITION BY HASH(h_payto)'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_table(
|
|
||||||
'various numeric statistics (cumulative counters) being tracked'
|
|
||||||
,'exchange_statistic_interval_counter'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'identifies what the statistic is about'
|
|
||||||
,'imeta_serial_id'
|
|
||||||
,'exchange_statistic_interval_counter'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'identifies an account (hash of normalized payto) for which the statistic is kept, NULL for global statistics'
|
|
||||||
,'h_payto'
|
|
||||||
,'exchange_statistic_interval_counter'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'for which range is this the counter; note that the cumulative_number excludes the values already stored in smaller ranges'
|
|
||||||
,'range'
|
|
||||||
,'exchange_statistic_interval_counter'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'determines the last event currently included in the interval'
|
|
||||||
,'event_delimiter'
|
|
||||||
,'exchange_statistic_interval_counter'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'aggregate (sum) of tracked by the statistic; what exactly is tracked is determined by the keyword'
|
|
||||||
,'cumulative_number'
|
|
||||||
,'exchange_statistic_interval_counter'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
END $$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION foreign_table_exchange_statistic_interval_counter()
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'exchange_statistic_interval_counter';
|
|
||||||
BEGIN
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD CONSTRAINT ' || table_name || '_event_delimiter_foreign_key'
|
|
||||||
' FOREIGN KEY (event_delimiter) '
|
|
||||||
' REFERENCES exchange_statistic_counter_event (nevent_serial_id) ON DELETE RESTRICT'
|
|
||||||
);
|
|
||||||
END $$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION create_table_exchange_statistic_amount_event (
|
|
||||||
IN partition_suffix TEXT DEFAULT NULL
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
BEGIN
|
|
||||||
PERFORM create_partitioned_table(
|
|
||||||
'CREATE TABLE %I'
|
|
||||||
'(aevent_serial_id INT8 GENERATED BY DEFAULT AS IDENTITY'
|
|
||||||
',imeta_serial_id INT8'
|
|
||||||
' REFERENCES exchange_statistic_interval_meta (imeta_serial_id) ON DELETE CASCADE'
|
|
||||||
',h_payto BYTEA CHECK (LENGTH(h_payto)=32)'
|
|
||||||
',slot INT8 NOT NULL'
|
|
||||||
',delta taler_amount NOT NULL'
|
|
||||||
',CHECK ((delta).val IS NOT NULL AND (delta).frac IS NOT NULL)'
|
|
||||||
',CONSTRAINT event_key UNIQUE (h_payto,imeta_serial_id,slot)'
|
|
||||||
') %s ;'
|
|
||||||
,'exchange_statistic_amount_event'
|
|
||||||
,'PARTITION BY HASH(h_payto)'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_table(
|
|
||||||
'amount to decrement an interval statistic by when a certain time value is reached'
|
|
||||||
,'exchange_statistic_amount_event'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'unique identifier for this amount event'
|
|
||||||
,'aevent_serial_id'
|
|
||||||
,'exchange_statistic_amount_event'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'identifies what the statistic is about; must be of clazz interval and of stype amount'
|
|
||||||
,'imeta_serial_id'
|
|
||||||
,'exchange_statistic_amount_event'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'identifies an account (hash of normalized payto) for which the statistic is kept, NULL for global statistics'
|
|
||||||
,'h_payto'
|
|
||||||
,'exchange_statistic_amount_event'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'identifies the time slot at which the given event(s) happened'
|
|
||||||
,'slot'
|
|
||||||
,'exchange_statistic_amount_event'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'total cumulative amount that was added at the time identified by slot'
|
|
||||||
,'delta'
|
|
||||||
,'exchange_statistic_amount_event'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
END $$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION constrain_table_exchange_statistic_amount_event(
|
|
||||||
IN partition_suffix TEXT
|
|
||||||
)
|
|
||||||
RETURNS void
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT default 'exchange_statistic_amount_event';
|
|
||||||
BEGIN
|
|
||||||
table_name = concat_ws('_', table_name, partition_suffix);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD CONSTRAINT ' || table_name || '_aevent_serial_id_key'
|
|
||||||
' UNIQUE (aevent_serial_id)'
|
|
||||||
);
|
|
||||||
END $$;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION create_table_exchange_statistic_interval_amount (
|
|
||||||
IN partition_suffix TEXT DEFAULT NULL
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
BEGIN
|
|
||||||
PERFORM create_partitioned_table(
|
|
||||||
'CREATE TABLE %I'
|
|
||||||
'(imeta_serial_id INT8 NOT NULL'
|
|
||||||
' REFERENCES exchange_statistic_interval_meta (imeta_serial_id) ON DELETE CASCADE'
|
|
||||||
',h_payto BYTEA CHECK (LENGTH(h_payto)=32)'
|
|
||||||
',event_delimiter INT8 NOT NULL'
|
|
||||||
',range INT8 NOT NULL'
|
|
||||||
',cumulative_value taler_amount NOT NULL'
|
|
||||||
',CHECK ((cumulative_value).val IS NOT NULL AND (cumulative_value).frac IS NOT NULL)'
|
|
||||||
',UNIQUE (h_payto,imeta_serial_id,range)'
|
|
||||||
') %s ;'
|
|
||||||
,'exchange_statistic_interval_amount'
|
|
||||||
,'PARTITION BY HASH(h_payto)'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_table(
|
|
||||||
'various amount statistics being tracked'
|
|
||||||
,'exchange_statistic_interval_amount'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'identifies what the statistic is about'
|
|
||||||
,'imeta_serial_id'
|
|
||||||
,'exchange_statistic_interval_amount'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'identifies an account (hash of normalized payto) for which the statistic is kept, NULL for global statistics'
|
|
||||||
,'h_payto'
|
|
||||||
,'exchange_statistic_interval_amount'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'for which range is this the counter; note that the cumulative_number excludes the values already stored in smaller ranges'
|
|
||||||
,'range'
|
|
||||||
,'exchange_statistic_interval_amount'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'amount affected by the event'
|
|
||||||
,'cumulative_value'
|
|
||||||
,'exchange_statistic_interval_amount'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
END $$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION foreign_table_exchange_statistic_interval_amount()
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'exchange_statistic_interval_amount';
|
|
||||||
BEGIN
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD CONSTRAINT ' || table_name || '_event_delimiter_foreign_key'
|
|
||||||
' FOREIGN KEY (event_delimiter) '
|
|
||||||
' REFERENCES exchange_statistic_amount_event (aevent_serial_id) ON DELETE RESTRICT'
|
|
||||||
);
|
|
||||||
END $$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE TYPE exchange_statistic_interval_number_get_return_value
|
|
||||||
AS
|
|
||||||
(range INT8
|
|
||||||
,rvalue INT8
|
|
||||||
);
|
|
||||||
COMMENT ON TYPE exchange_statistic_interval_number_get_return_value
|
|
||||||
IS 'Return type for exchange_statistic_interval_number_get stored procedure';
|
|
||||||
|
|
||||||
CREATE TYPE exchange_statistic_interval_amount_get_return_value
|
|
||||||
AS
|
|
||||||
(range INT8
|
|
||||||
,rvalue taler_amount
|
|
||||||
);
|
|
||||||
COMMENT ON TYPE exchange_statistic_interval_amount_get_return_value
|
|
||||||
IS 'Return type for exchange_statistic_interval_amount_get stored procedure';
|
|
||||||
|
|
||||||
|
|
||||||
INSERT INTO exchange_tables
|
|
||||||
(name
|
|
||||||
,version
|
|
||||||
,action
|
|
||||||
,partitioned
|
|
||||||
,by_range)
|
|
||||||
VALUES
|
|
||||||
('exchange_statistic_bucket_counter'
|
|
||||||
,'exchange-0009'
|
|
||||||
,'create'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('exchange_statistic_bucket_amount'
|
|
||||||
,'exchange-0009'
|
|
||||||
,'create'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('exchange_statistic_counter_event'
|
|
||||||
,'exchange-0009'
|
|
||||||
,'create'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('exchange_statistic_counter_event'
|
|
||||||
,'exchange-0009'
|
|
||||||
,'constrain'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('exchange_statistic_interval_counter'
|
|
||||||
,'exchange-0009'
|
|
||||||
,'create'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('exchange_statistic_interval_counter'
|
|
||||||
,'exchange-0009'
|
|
||||||
,'foreign'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('exchange_statistic_amount_event'
|
|
||||||
,'exchange-0009'
|
|
||||||
,'create'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('exchange_statistic_amount_event'
|
|
||||||
,'exchange-0009'
|
|
||||||
,'constrain'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('exchange_statistic_interval_amount'
|
|
||||||
,'exchange-0009'
|
|
||||||
,'create'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('exchange_statistic_interval_amount'
|
|
||||||
,'exchange-0009'
|
|
||||||
,'foreign'
|
|
||||||
,TRUE
|
|
||||||
,FALSE);
|
|
||||||
|
|
@ -1,72 +0,0 @@
|
||||||
--
|
|
||||||
-- This file is part of TALER
|
|
||||||
-- Copyright (C) 2025 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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
-- @author Özgür Kesim
|
|
||||||
|
|
||||||
CREATE FUNCTION create_table_unique_refresh_blinding_seed(
|
|
||||||
IN partition_suffix TEXT DEFAULT NULL
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'unique_refresh_blinding_seed';
|
|
||||||
BEGIN
|
|
||||||
PERFORM create_partitioned_table(
|
|
||||||
'CREATE TABLE %I'
|
|
||||||
'(unique_refresh_blinding_seed_id BIGINT GENERATED BY DEFAULT AS IDENTITY'
|
|
||||||
',blinding_seed BYTEA PRIMARY KEY'
|
|
||||||
') %s ;'
|
|
||||||
,table_name
|
|
||||||
,'PARTITION BY HASH (blinding_seed)'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_table(
|
|
||||||
'Table to ensure uniqueness of the blinding_seed for CS signatures across all refresh operations. '
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION constrain_table_unique_refresh_blinding_seed(
|
|
||||||
IN partition_suffix TEXT
|
|
||||||
)
|
|
||||||
RETURNS void
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'unique_refresh_blinding_seed';
|
|
||||||
BEGIN
|
|
||||||
table_name = concat_ws('_', table_name, partition_suffix);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD CONSTRAINT ' || table_name || '_refresh_id_key'
|
|
||||||
' UNIQUE (unique_refresh_blinding_seed_id);'
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
INSERT INTO exchange_tables
|
|
||||||
(name
|
|
||||||
,version
|
|
||||||
,action
|
|
||||||
,partitioned
|
|
||||||
,by_range)
|
|
||||||
VALUES
|
|
||||||
('unique_refresh_blinding_seed', 'exchange-0002', 'create', TRUE ,FALSE),
|
|
||||||
('unique_refresh_blinding_seed', 'exchange-0002', 'constrain',TRUE ,FALSE);
|
|
||||||
|
|
||||||
|
|
@ -1,72 +0,0 @@
|
||||||
--
|
|
||||||
-- This file is part of TALER
|
|
||||||
-- Copyright (C) 2025 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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
-- @author Özgür Kesim
|
|
||||||
|
|
||||||
CREATE FUNCTION create_table_unique_withdraw_blinding_seed(
|
|
||||||
IN partition_suffix TEXT DEFAULT NULL
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'unique_withdraw_blinding_seed';
|
|
||||||
BEGIN
|
|
||||||
PERFORM create_partitioned_table(
|
|
||||||
'CREATE TABLE %I'
|
|
||||||
'(unique_withdraw_blinding_seed_id BIGINT GENERATED BY DEFAULT AS IDENTITY'
|
|
||||||
',blinding_seed BYTEA PRIMARY KEY'
|
|
||||||
') %s ;'
|
|
||||||
,table_name
|
|
||||||
,'PARTITION BY HASH (blinding_seed)'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_table(
|
|
||||||
'Table to ensure uniqueness of the blinding_seed for CS signatures across all withdraw operations. '
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION constrain_table_unique_withdraw_blinding_seed(
|
|
||||||
IN partition_suffix TEXT
|
|
||||||
)
|
|
||||||
RETURNS void
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'unique_withdraw_blinding_seed';
|
|
||||||
BEGIN
|
|
||||||
table_name = concat_ws('_', table_name, partition_suffix);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD CONSTRAINT ' || table_name || '_withdraw_id_key'
|
|
||||||
' UNIQUE (unique_withdraw_blinding_seed_id);'
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
INSERT INTO exchange_tables
|
|
||||||
(name
|
|
||||||
,version
|
|
||||||
,action
|
|
||||||
,partitioned
|
|
||||||
,by_range)
|
|
||||||
VALUES
|
|
||||||
('unique_withdraw_blinding_seed', 'exchange-0002', 'create', TRUE ,FALSE),
|
|
||||||
('unique_withdraw_blinding_seed', 'exchange-0002', 'constrain',TRUE ,FALSE);
|
|
||||||
|
|
||||||
|
|
@ -1,175 +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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
CREATE FUNCTION create_table_wad_in_entries(
|
|
||||||
IN partition_suffix TEXT DEFAULT NULL
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'wad_in_entries';
|
|
||||||
BEGIN
|
|
||||||
PERFORM create_partitioned_table(
|
|
||||||
'CREATE TABLE %I '
|
|
||||||
'(wad_in_entry_serial_id BIGINT GENERATED BY DEFAULT AS IDENTITY'
|
|
||||||
',wad_in_serial_id INT8'
|
|
||||||
',reserve_pub BYTEA NOT NULL CHECK(LENGTH(reserve_pub)=32)'
|
|
||||||
',purse_pub BYTEA PRIMARY KEY CHECK(LENGTH(purse_pub)=32)'
|
|
||||||
',h_contract BYTEA NOT NULL CHECK(LENGTH(h_contract)=64)'
|
|
||||||
',purse_expiration INT8 NOT NULL'
|
|
||||||
',merge_timestamp INT8 NOT NULL'
|
|
||||||
',amount_with_fee taler_amount NOT NULL'
|
|
||||||
',wad_fee taler_amount NOT NULL'
|
|
||||||
',deposit_fees taler_amount NOT NULL'
|
|
||||||
',reserve_sig BYTEA NOT NULL CHECK (LENGTH(reserve_sig)=64)'
|
|
||||||
',purse_sig BYTEA NOT NULL CHECK (LENGTH(purse_sig)=64)'
|
|
||||||
') %s ;'
|
|
||||||
,table_name
|
|
||||||
,'PARTITION BY HASH (purse_pub)'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_table(
|
|
||||||
'list of purses aggregated in a wad according to the sending exchange'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'wad for which the given purse was included in the aggregation'
|
|
||||||
,'wad_in_serial_id'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'target account of the purse (must be at the local exchange)'
|
|
||||||
,'reserve_pub'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'public key of the purse that was merged'
|
|
||||||
,'purse_pub'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'hash of the contract terms of the purse'
|
|
||||||
,'h_contract'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Time when the purse was set to expire'
|
|
||||||
,'purse_expiration'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Time when the merge was approved'
|
|
||||||
,'merge_timestamp'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Total amount in the purse'
|
|
||||||
,'amount_with_fee'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Total wad fees paid by the purse'
|
|
||||||
,'wad_fee'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Total deposit fees paid when depositing coins into the purse'
|
|
||||||
,'deposit_fees'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Signature by the receiving reserve, of purpose TALER_SIGNATURE_ACCOUNT_MERGE'
|
|
||||||
,'reserve_sig'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Signature by the purse of purpose TALER_SIGNATURE_PURSE_MERGE'
|
|
||||||
,'purse_sig'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
END $$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION constrain_table_wad_in_entries(
|
|
||||||
IN partition_suffix TEXT
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'wad_in_entries';
|
|
||||||
BEGIN
|
|
||||||
table_name = concat_ws('_', table_name, partition_suffix);
|
|
||||||
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD CONSTRAINT ' || table_name || '_wad_in_entry_serial_id_key'
|
|
||||||
' UNIQUE (wad_in_entry_serial_id) '
|
|
||||||
);
|
|
||||||
END $$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION foreign_table_wad_in_entries()
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'wad_in_entries';
|
|
||||||
BEGIN
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD CONSTRAINT ' || table_name || '_foreign_wad_in'
|
|
||||||
' FOREIGN KEY(wad_in_serial_id)'
|
|
||||||
' REFERENCES wads_in (wad_in_serial_id) ON DELETE CASCADE'
|
|
||||||
);
|
|
||||||
END $$;
|
|
||||||
|
|
||||||
|
|
||||||
INSERT INTO exchange_tables
|
|
||||||
(name
|
|
||||||
,version
|
|
||||||
,action
|
|
||||||
,partitioned
|
|
||||||
,by_range)
|
|
||||||
VALUES
|
|
||||||
('wad_in_entries'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'create'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('wad_in_entries'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'constrain'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('wad_in_entries'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'foreign'
|
|
||||||
,TRUE
|
|
||||||
,FALSE);
|
|
||||||
|
|
@ -1,179 +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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION create_table_wad_out_entries(
|
|
||||||
IN partition_suffix TEXT DEFAULT NULL
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'wad_out_entries';
|
|
||||||
BEGIN
|
|
||||||
PERFORM create_partitioned_table(
|
|
||||||
'CREATE TABLE %I '
|
|
||||||
'(wad_out_entry_serial_id BIGINT GENERATED BY DEFAULT AS IDENTITY'
|
|
||||||
',wad_out_serial_id INT8'
|
|
||||||
',reserve_pub BYTEA NOT NULL CHECK(LENGTH(reserve_pub)=32)'
|
|
||||||
',purse_pub BYTEA PRIMARY KEY CHECK(LENGTH(purse_pub)=32)'
|
|
||||||
',h_contract BYTEA NOT NULL CHECK(LENGTH(h_contract)=64)'
|
|
||||||
',purse_expiration INT8 NOT NULL'
|
|
||||||
',merge_timestamp INT8 NOT NULL'
|
|
||||||
',amount_with_fee taler_amount NOT NULL'
|
|
||||||
',wad_fee taler_amount NOT NULL'
|
|
||||||
',deposit_fees taler_amount NOT NULL'
|
|
||||||
',reserve_sig BYTEA NOT NULL CHECK (LENGTH(reserve_sig)=64)'
|
|
||||||
',purse_sig BYTEA NOT NULL CHECK (LENGTH(purse_sig)=64)'
|
|
||||||
') %s ;'
|
|
||||||
,table_name
|
|
||||||
,'PARTITION BY HASH (purse_pub)'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_table(
|
|
||||||
'Purses combined into a wad'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Wad the purse was part of'
|
|
||||||
,'wad_out_serial_id'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Target reserve for the purse'
|
|
||||||
,'reserve_pub'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Public key of the purse'
|
|
||||||
,'purse_pub'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Hash of the contract associated with the purse'
|
|
||||||
,'h_contract'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Time when the purse expires'
|
|
||||||
,'purse_expiration'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Time when the merge was approved'
|
|
||||||
,'merge_timestamp'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Total amount in the purse'
|
|
||||||
,'amount_with_fee'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Wad fee charged to the purse'
|
|
||||||
,'wad_fee'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Total deposit fees charged to the purse'
|
|
||||||
,'deposit_fees'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Signature by the receiving reserve, of purpose TALER_SIGNATURE_ACCOUNT_MERGE'
|
|
||||||
,'reserve_sig'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Signature by the purse of purpose TALER_SIGNATURE_PURSE_MERGE'
|
|
||||||
,'purse_sig'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION constrain_table_wad_out_entries(
|
|
||||||
IN partition_suffix TEXT
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'wad_out_entries';
|
|
||||||
BEGIN
|
|
||||||
table_name = concat_ws('_', table_name, partition_suffix);
|
|
||||||
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD CONSTRAINT ' || table_name || '_wad_out_entry_serial_id_key'
|
|
||||||
' UNIQUE (wad_out_entry_serial_id) '
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION foreign_table_wad_out_entries()
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'wad_out_entries';
|
|
||||||
BEGIN
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD CONSTRAINT ' || table_name || '_foreign_wad_out'
|
|
||||||
' FOREIGN KEY(wad_out_serial_id)'
|
|
||||||
' REFERENCES wads_out (wad_out_serial_id) ON DELETE CASCADE'
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
INSERT INTO exchange_tables
|
|
||||||
(name
|
|
||||||
,version
|
|
||||||
,action
|
|
||||||
,partitioned
|
|
||||||
,by_range)
|
|
||||||
VALUES
|
|
||||||
('wad_out_entries'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'create'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('wad_out_entries'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'constrain'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('wad_out_entries'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'foreign'
|
|
||||||
,TRUE
|
|
||||||
,FALSE);
|
|
||||||
|
|
@ -1,107 +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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
CREATE FUNCTION create_table_wads_in(
|
|
||||||
IN partition_suffix TEXT DEFAULT NULL
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'wads_in';
|
|
||||||
BEGIN
|
|
||||||
PERFORM create_partitioned_table(
|
|
||||||
'CREATE TABLE %I '
|
|
||||||
'(wad_in_serial_id BIGINT GENERATED BY DEFAULT AS IDENTITY'
|
|
||||||
',wad_id BYTEA PRIMARY KEY CHECK (LENGTH(wad_id)=24)'
|
|
||||||
',origin_exchange_url TEXT NOT NULL'
|
|
||||||
',amount taler_amount NOT NULL'
|
|
||||||
',arrival_time INT8 NOT NULL'
|
|
||||||
',UNIQUE (wad_id, origin_exchange_url)'
|
|
||||||
') %s ;'
|
|
||||||
,table_name
|
|
||||||
,'PARTITION BY HASH (wad_id)'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_table(
|
|
||||||
'Incoming exchange-to-exchange wad wire transfers'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Unique identifier of the wad, part of the wire transfer subject'
|
|
||||||
,'wad_id'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Base URL of the originating URL, also part of the wire transfer subject'
|
|
||||||
,'origin_exchange_url'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Actual amount that was received by our exchange'
|
|
||||||
,'amount'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Time when the wad was received'
|
|
||||||
,'arrival_time'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
END $$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION constrain_table_wads_in(
|
|
||||||
IN partition_suffix TEXT
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'wads_in';
|
|
||||||
BEGIN
|
|
||||||
table_name = concat_ws('_', table_name, partition_suffix);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD CONSTRAINT ' || table_name || '_wad_in_serial_id_key'
|
|
||||||
' UNIQUE (wad_in_serial_id) '
|
|
||||||
',ADD CONSTRAINT ' || table_name || '_wad_is_origin_exchange_url_key'
|
|
||||||
' UNIQUE (wad_id, origin_exchange_url) '
|
|
||||||
);
|
|
||||||
END $$;
|
|
||||||
|
|
||||||
|
|
||||||
INSERT INTO exchange_tables
|
|
||||||
(name
|
|
||||||
,version
|
|
||||||
,action
|
|
||||||
,partitioned
|
|
||||||
,by_range)
|
|
||||||
VALUES
|
|
||||||
('wads_in'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'create'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('wads_in'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'constrain'
|
|
||||||
,TRUE
|
|
||||||
,FALSE);
|
|
||||||
|
|
@ -1,128 +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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
CREATE FUNCTION create_table_wads_out(
|
|
||||||
IN shard_suffix TEXT DEFAULT NULL
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'wads_out';
|
|
||||||
BEGIN
|
|
||||||
PERFORM create_partitioned_table(
|
|
||||||
'CREATE TABLE %I '
|
|
||||||
'(wad_out_serial_id BIGINT GENERATED BY DEFAULT AS IDENTITY'
|
|
||||||
',wad_id BYTEA PRIMARY KEY CHECK (LENGTH(wad_id)=24)'
|
|
||||||
',partner_serial_id INT8 NOT NULL'
|
|
||||||
',amount taler_amount NOT NULL'
|
|
||||||
',execution_time INT8 NOT NULL'
|
|
||||||
') %s ;'
|
|
||||||
,table_name
|
|
||||||
,'PARTITION BY HASH (wad_id)'
|
|
||||||
,shard_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_table(
|
|
||||||
'Wire transfers made to another exchange to transfer purse funds'
|
|
||||||
,table_name
|
|
||||||
,shard_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Unique identifier of the wad, part of the wire transfer subject'
|
|
||||||
,'wad_id'
|
|
||||||
,table_name
|
|
||||||
,shard_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'target exchange of the wad'
|
|
||||||
,'partner_serial_id'
|
|
||||||
,table_name
|
|
||||||
,shard_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Amount that was wired'
|
|
||||||
,'amount'
|
|
||||||
,table_name
|
|
||||||
,shard_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Time when the wire transfer was scheduled'
|
|
||||||
,'execution_time'
|
|
||||||
,table_name
|
|
||||||
,shard_suffix
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION constrain_table_wads_out(
|
|
||||||
IN partition_suffix TEXT
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'wads_out';
|
|
||||||
BEGIN
|
|
||||||
table_name = concat_ws('_', table_name, partition_suffix);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD CONSTRAINT ' || table_name || '_wad_out_serial_id_key'
|
|
||||||
' UNIQUE (wad_out_serial_id) '
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION foreign_table_wads_out()
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'wads_out';
|
|
||||||
BEGIN
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD CONSTRAINT ' || table_name || '_foreign_partner'
|
|
||||||
' FOREIGN KEY(partner_serial_id)'
|
|
||||||
' REFERENCES partners(partner_serial_id) ON DELETE CASCADE'
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
INSERT INTO exchange_tables
|
|
||||||
(name
|
|
||||||
,version
|
|
||||||
,action
|
|
||||||
,partitioned
|
|
||||||
,by_range)
|
|
||||||
VALUES
|
|
||||||
('wads_out'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'create'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('wads_out'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'constrain'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('wads_out'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'foreign'
|
|
||||||
,TRUE
|
|
||||||
,FALSE);
|
|
||||||
|
|
@ -1,51 +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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
CREATE TABLE wire_accounts
|
|
||||||
(payto_uri TEXT PRIMARY KEY
|
|
||||||
,master_sig BYTEA CHECK (LENGTH(master_sig)=64)
|
|
||||||
,is_active BOOLEAN NOT NULL
|
|
||||||
,last_change INT8 NOT NULL
|
|
||||||
,conversion_url TEXT DEFAULT (NULL)
|
|
||||||
,debit_restrictions TEXT DEFAULT (NULL)
|
|
||||||
,credit_restrictions TEXT DEFAULT (NULL)
|
|
||||||
,priority INT8 NOT NULL DEFAULT (0)
|
|
||||||
,bank_label TEXT DEFAULT (NULL)
|
|
||||||
);
|
|
||||||
COMMENT ON TABLE wire_accounts
|
|
||||||
IS 'Table with current and historic bank accounts of the exchange. Entries never expire as we need to remember the last_change column indefinitely.';
|
|
||||||
COMMENT ON COLUMN wire_accounts.payto_uri
|
|
||||||
IS 'payto URI (RFC 8905) with the bank account of the exchange.';
|
|
||||||
COMMENT ON COLUMN wire_accounts.master_sig
|
|
||||||
IS 'Signature of purpose TALER_SIGNATURE_MASTER_WIRE_DETAILS';
|
|
||||||
COMMENT ON COLUMN wire_accounts.is_active
|
|
||||||
IS 'true if we are currently supporting the use of this account.';
|
|
||||||
COMMENT ON COLUMN wire_accounts.last_change
|
|
||||||
IS 'Latest time when active status changed. Used to detect replays of old messages.';
|
|
||||||
COMMENT ON COLUMN wire_accounts.conversion_url
|
|
||||||
IS 'URL of a currency conversion service if conversion is needed when this account is used; NULL if there is no conversion.';
|
|
||||||
COMMENT ON COLUMN wire_accounts.debit_restrictions
|
|
||||||
IS 'JSON array describing restrictions imposed when debiting this account. Empty for no restrictions, NULL if account was migrated from previous database revision or account is disabled.';
|
|
||||||
COMMENT ON COLUMN wire_accounts.credit_restrictions
|
|
||||||
IS 'JSON array describing restrictions imposed when crediting this account. Empty for no restrictions, NULL if account was migrated from previous database revision or account is disabled.';
|
|
||||||
COMMENT ON COLUMN wire_accounts.priority
|
|
||||||
IS 'priority determines the order in which wallets should display wire accounts';
|
|
||||||
COMMENT ON COLUMN wire_accounts.bank_label
|
|
||||||
IS 'label to show in the selector for this bank account in the wallet UI';
|
|
||||||
|
|
||||||
|
|
||||||
-- "wire_accounts" has no sequence because it is a 'mutable' table
|
|
||||||
-- and is of no concern to the auditor
|
|
||||||
|
|
@ -1,34 +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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
CREATE TABLE wire_fee
|
|
||||||
(wire_fee_serial BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE
|
|
||||||
,wire_method TEXT NOT NULL
|
|
||||||
,start_date INT8 NOT NULL
|
|
||||||
,end_date INT8 NOT NULL
|
|
||||||
,wire_fee taler_amount NOT NULL
|
|
||||||
,closing_fee taler_amount NOT NULL
|
|
||||||
,master_sig BYTEA NOT NULL CHECK (LENGTH(master_sig)=64)
|
|
||||||
,PRIMARY KEY (wire_method, start_date)
|
|
||||||
);
|
|
||||||
COMMENT ON TABLE wire_fee
|
|
||||||
IS 'list of the wire fees of this exchange, by date';
|
|
||||||
COMMENT ON COLUMN wire_fee.wire_fee_serial
|
|
||||||
IS 'needed for exchange-auditor replication logic';
|
|
||||||
|
|
||||||
CREATE INDEX wire_fee_by_end_date_index
|
|
||||||
ON wire_fee
|
|
||||||
(end_date);
|
|
||||||
|
|
@ -1,130 +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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
CREATE FUNCTION create_table_wire_out(
|
|
||||||
IN partition_suffix TEXT DEFAULT NULL
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'wire_out';
|
|
||||||
BEGIN
|
|
||||||
PERFORM create_partitioned_table(
|
|
||||||
'CREATE TABLE IF NOT EXISTS %I'
|
|
||||||
'(wireout_uuid BIGINT GENERATED BY DEFAULT AS IDENTITY'
|
|
||||||
',execution_date INT8 NOT NULL'
|
|
||||||
',wtid_raw BYTEA UNIQUE NOT NULL CHECK (LENGTH(wtid_raw)=32)'
|
|
||||||
',wire_target_h_payto BYTEA CHECK (LENGTH(wire_target_h_payto)=32)'
|
|
||||||
',exchange_account_section TEXT NOT NULL'
|
|
||||||
',amount taler_amount NOT NULL'
|
|
||||||
') %s ;'
|
|
||||||
,table_name
|
|
||||||
,'PARTITION BY HASH (wtid_raw)'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_table(
|
|
||||||
'wire transfers the exchange has executed'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'identifies the configuration section with the debit account of this payment'
|
|
||||||
,'exchange_account_section'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Identifies the credited bank account and KYC status'
|
|
||||||
,'wire_target_h_payto'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION constrain_table_wire_out(
|
|
||||||
IN partition_suffix TEXT
|
|
||||||
)
|
|
||||||
RETURNS void
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'wire_out';
|
|
||||||
BEGIN
|
|
||||||
table_name = concat_ws('_', table_name, partition_suffix);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'CREATE INDEX ' || table_name || '_by_wire_target_h_payto_index '
|
|
||||||
'ON ' || table_name || ' '
|
|
||||||
'(wire_target_h_payto);'
|
|
||||||
);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD CONSTRAINT ' || table_name || '_wireout_uuid_pkey'
|
|
||||||
' PRIMARY KEY (wireout_uuid)'
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION wire_out_delete_trigger()
|
|
||||||
RETURNS trigger
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
BEGIN
|
|
||||||
DELETE FROM exchange.aggregation_tracking
|
|
||||||
WHERE wtid_raw = OLD.wtid_raw;
|
|
||||||
RETURN OLD;
|
|
||||||
END $$;
|
|
||||||
COMMENT ON FUNCTION wire_out_delete_trigger()
|
|
||||||
IS 'Replicate reserve_out deletions into aggregation_tracking. This replaces an earlier use of an ON DELETE CASCADE that required a DEFERRABLE constraint and conflicted with nice partitioning.';
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION master_table_wire_out()
|
|
||||||
RETURNS void
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
BEGIN
|
|
||||||
CREATE TRIGGER wire_out_on_delete
|
|
||||||
AFTER DELETE
|
|
||||||
ON wire_out
|
|
||||||
FOR EACH ROW EXECUTE FUNCTION wire_out_delete_trigger();
|
|
||||||
END $$;
|
|
||||||
|
|
||||||
|
|
||||||
INSERT INTO exchange_tables
|
|
||||||
(name
|
|
||||||
,version
|
|
||||||
,action
|
|
||||||
,partitioned
|
|
||||||
,by_range)
|
|
||||||
VALUES
|
|
||||||
('wire_out'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'create'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('wire_out'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'constrain'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('wire_out'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'master'
|
|
||||||
,TRUE
|
|
||||||
,FALSE);
|
|
||||||
|
|
@ -1,141 +0,0 @@
|
||||||
--
|
|
||||||
-- This file is part of TALER
|
|
||||||
-- Copyright (C) 2014--2025 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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION random_bytea(
|
|
||||||
bytea_length INT
|
|
||||||
)
|
|
||||||
RETURNS BYTEA
|
|
||||||
AS $body$
|
|
||||||
SELECT decode(string_agg(lpad(to_hex(width_bucket(random(), 0, 1, 256)-1),2,'0') ,''), 'hex')
|
|
||||||
FROM generate_series(1, $1);
|
|
||||||
$body$
|
|
||||||
LANGUAGE 'sql'
|
|
||||||
VOLATILE;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION create_table_wire_targets(
|
|
||||||
IN partition_suffix TEXT DEFAULT NULL
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
BEGIN
|
|
||||||
PERFORM create_partitioned_table(
|
|
||||||
'CREATE TABLE %I'
|
|
||||||
'(wire_target_serial_id BIGINT GENERATED BY DEFAULT AS IDENTITY'
|
|
||||||
',wire_target_h_payto BYTEA PRIMARY KEY CHECK (LENGTH(wire_target_h_payto)=32)'
|
|
||||||
',payto_uri TEXT NOT NULL'
|
|
||||||
',access_token BYTEA CHECK(LENGTH(access_token)=32)'
|
|
||||||
' DEFAULT random_bytea(32)'
|
|
||||||
',target_pub BYTEA CHECK(LENGTH(target_pub)=32) DEFAULT NULL'
|
|
||||||
',h_normalized_payto BYTEA CHECK(LENGTH(h_normalized_payto)=32) DEFAULT NULL'
|
|
||||||
',aml_program_lock_timeout INT8 DEFAULT NULL'
|
|
||||||
') %s ;'
|
|
||||||
,'wire_targets'
|
|
||||||
,'PARTITION BY HASH (wire_target_h_payto)'
|
|
||||||
,partition_suffix
|
|
||||||
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_table(
|
|
||||||
'All senders and recipients of money via the exchange'
|
|
||||||
,'wire_targets'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Full payto URI. Can identify a regular bank account, or also be a URI identifying a reserve-account (for P2P payments)'
|
|
||||||
,'payto_uri'
|
|
||||||
,'wire_targets'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Unsalted hash of (full) payto_uri'
|
|
||||||
,'wire_target_h_payto'
|
|
||||||
,'wire_targets'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'high-entropy random value that is used as a bearer token used to authenticate access to the KYC SPA and its state (without requiring a signature)'
|
|
||||||
,'access_token'
|
|
||||||
,'wire_targets'
|
|
||||||
,NULL
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Public key of a merchant instance or reserve to authenticate access; NULL if KYC is not allowed for the account (if there was no incoming KYC wire transfer yet); updated, thus NOT available to the auditor'
|
|
||||||
,'target_pub'
|
|
||||||
,'wire_targets'
|
|
||||||
,NULL
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'hash over the normalized payto URI for this account; used for KYC operations; NULL if not available (due to DB migration not initializing this value)'
|
|
||||||
,'h_normalized_payto'
|
|
||||||
,'wire_targets'
|
|
||||||
,NULL
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'If non-NULL, an AML program should be running and it holds a lock on this account, thus other AML programs should not be started concurrently. Given the possibility of crashes, the lock automatically expires at the time value given in this column. At that time, the lock can be considered stale.'
|
|
||||||
,'aml_program_lock_timeout'
|
|
||||||
,'wire_targets'
|
|
||||||
,NULL
|
|
||||||
);
|
|
||||||
END $$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION constrain_table_wire_targets(
|
|
||||||
IN partition_suffix TEXT
|
|
||||||
)
|
|
||||||
RETURNS void
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'wire_targets';
|
|
||||||
BEGIN
|
|
||||||
table_name = concat_ws('_', table_name, partition_suffix);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD CONSTRAINT ' || table_name || '_wire_target_serial_id_key'
|
|
||||||
' UNIQUE (wire_target_serial_id)'
|
|
||||||
);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD CONSTRAINT ' || table_name || '_wire_target_access_token_unique'
|
|
||||||
' UNIQUE (access_token)'
|
|
||||||
);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'CREATE INDEX ' || table_name || '_normalized_h_payto_index '
|
|
||||||
'ON ' || table_name || ' '
|
|
||||||
'(h_normalized_payto);'
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
INSERT INTO exchange_tables
|
|
||||||
(name
|
|
||||||
,version
|
|
||||||
,action
|
|
||||||
,partitioned
|
|
||||||
,by_range)
|
|
||||||
VALUES
|
|
||||||
('wire_targets'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'create'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('wire_targets'
|
|
||||||
,'exchange-0002'
|
|
||||||
,'constrain'
|
|
||||||
,TRUE
|
|
||||||
,FALSE);
|
|
||||||
|
|
@ -1,208 +0,0 @@
|
||||||
--
|
|
||||||
-- This file is part of TALER
|
|
||||||
-- Copyright (C) 2025 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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
-- @author Özgür Kesim
|
|
||||||
|
|
||||||
CREATE FUNCTION create_table_withdraw(
|
|
||||||
IN partition_suffix TEXT DEFAULT NULL
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'withdraw';
|
|
||||||
BEGIN
|
|
||||||
PERFORM create_partitioned_table(
|
|
||||||
'CREATE TABLE %I'
|
|
||||||
'(withdraw_id BIGINT GENERATED BY DEFAULT AS IDENTITY'
|
|
||||||
',planchets_h BYTEA CONSTRAINT planchets_h_length CHECK(LENGTH(planchets_h)=64)'
|
|
||||||
',execution_date INT8 NOT NULL'
|
|
||||||
',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)'
|
|
||||||
',max_age SMALLINT CONSTRAINT max_age_positive CHECK(max_age>=0)'
|
|
||||||
',noreveal_index SMALLINT CONSTRAINT noreveal_index_positive CHECK(noreveal_index>=0)'
|
|
||||||
',selected_h BYTEA CONSTRAINT selected_h_length CHECK(LENGTH(selected_h)=64)'
|
|
||||||
',blinding_seed BYTEA CONSTRAINT blinding_seed_length CHECK(LENGTH(blinding_seed)>=32)'
|
|
||||||
',cs_r_values BYTEA[]'
|
|
||||||
',cs_r_choices INT8'
|
|
||||||
',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 and, in case of required proof of age restriction, 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(
|
|
||||||
'If the client explicitly commits to age-restricted coins, the gamma value chosen by the exchange in the cut-and-choose protocol; NULL if we did not use age-withdraw.'
|
|
||||||
,'noreveal_index'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'The running hash over all committed blinded planchets. Needed for recoup and (when a proof of age-restriction was required); NULL if we did not use age-withdraw.'
|
|
||||||
' in the subsequent cut-and-choose protocol.'
|
|
||||||
,'planchets_h'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'The date of execution of this withdrawal, according to the exchange'
|
|
||||||
,'execution_date'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'If the clients commits to age-restricted coins, the maximum age (in years) that the client explicitly commits to with this request; NULL if we did not use age-withdraw.'
|
|
||||||
,'max_age'
|
|
||||||
,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 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(
|
|
||||||
'In case of age restriction, the hash of the chosen (noreveal_index) blinded envelopes; NULL if we did not use age-withdraw.'
|
|
||||||
,'selected_h'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Array of signatures over each blinded envelope. If age-proof was not required, the signed envelopes are the ones'
|
|
||||||
' hashed into planchet_h. Otherwise (when age-proof is required) the selected planchets (noreveal_index) were signed,'
|
|
||||||
' hashed into selected_h.'
|
|
||||||
,'denom_sigs'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'The master seed for the blinding nonces, needed for blind CS signatures; NULL if we did not use age-withdraw or CS'
|
|
||||||
,'blinding_seed'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'The pairs of R-values (calculated by the exchange) for the coins of cipher type Clause-Schnorr, based on the blinding_seed; maybe NULL if we did not use CS.'
|
|
||||||
,'cs_r_values'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'The bitvector of choices made by the exchange for each of the pairs in cs_r_values; NULL if we did not use CS.'
|
|
||||||
'The vector is stored in network byte order and the lowest bit corresponds to the 0-th entry in cs_r_values (pair)'
|
|
||||||
,'cs_r_choices'
|
|
||||||
,table_name
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION constrain_table_withdraw(
|
|
||||||
IN partition_suffix TEXT
|
|
||||||
)
|
|
||||||
RETURNS void
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'withdraw';
|
|
||||||
BEGIN
|
|
||||||
table_name = concat_ws('_', table_name, partition_suffix);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'CREATE INDEX ' || table_name || '_by_reserve_pub_index '
|
|
||||||
'ON ' || table_name || ' '
|
|
||||||
'(reserve_pub);'
|
|
||||||
);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD PRIMARY KEY (reserve_pub, planchets_h);'
|
|
||||||
);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD CONSTRAINT ' || table_name || '_withdraw_id_key'
|
|
||||||
' UNIQUE (withdraw_id);'
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION foreign_table_withdraw()
|
|
||||||
RETURNS void
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT '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
|
|
||||||
$$;
|
|
||||||
|
|
||||||
-- Put the triggers into the master table
|
|
||||||
CREATE FUNCTION master_table_withdraw()
|
|
||||||
RETURNS void
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
BEGIN
|
|
||||||
CREATE TRIGGER withdraw_on_insert
|
|
||||||
AFTER INSERT
|
|
||||||
ON withdraw
|
|
||||||
FOR EACH ROW EXECUTE FUNCTION withdraw_insert_trigger();
|
|
||||||
|
|
||||||
CREATE TRIGGER withdraw_on_delete
|
|
||||||
AFTER DELETE
|
|
||||||
ON withdraw
|
|
||||||
FOR EACH ROW EXECUTE FUNCTION withdraw_delete_trigger();
|
|
||||||
END $$;
|
|
||||||
COMMENT ON FUNCTION master_table_withdraw()
|
|
||||||
IS 'Setup triggers to replicate withdraw into reserve_history and delete blinding_seed from unique_withdraw_blinding_seed.';
|
|
||||||
|
|
||||||
|
|
||||||
INSERT INTO exchange_tables
|
|
||||||
(name
|
|
||||||
,version
|
|
||||||
,action
|
|
||||||
,partitioned
|
|
||||||
,by_range)
|
|
||||||
VALUES
|
|
||||||
('withdraw', 'exchange-0002', 'create', TRUE ,FALSE),
|
|
||||||
('withdraw', 'exchange-0002', 'constrain',TRUE ,FALSE),
|
|
||||||
('withdraw', 'exchange-0002', 'foreign', TRUE ,FALSE),
|
|
||||||
('withdraw', 'exchange-0002', 'master', TRUE ,FALSE);
|
|
||||||
|
|
@ -1,56 +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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
CREATE TABLE work_shards
|
|
||||||
(shard_serial_id BIGINT GENERATED BY DEFAULT AS IDENTITY UNIQUE
|
|
||||||
,last_attempt INT8 NOT NULL
|
|
||||||
,start_row INT8 NOT NULL
|
|
||||||
,end_row INT8 NOT NULL
|
|
||||||
,completed BOOLEAN NOT NULL DEFAULT FALSE
|
|
||||||
,job_name TEXT NOT NULL
|
|
||||||
,PRIMARY KEY (job_name, start_row)
|
|
||||||
);
|
|
||||||
COMMENT ON TABLE work_shards
|
|
||||||
IS 'coordinates work between multiple processes working on the same job';
|
|
||||||
COMMENT ON COLUMN work_shards.shard_serial_id
|
|
||||||
IS 'unique serial number identifying the shard';
|
|
||||||
COMMENT ON COLUMN work_shards.last_attempt
|
|
||||||
IS 'last time a worker attempted to work on the shard';
|
|
||||||
COMMENT ON COLUMN work_shards.completed
|
|
||||||
IS 'set to TRUE once the shard is finished by a worker';
|
|
||||||
COMMENT ON COLUMN work_shards.start_row
|
|
||||||
IS 'row at which the shard scope starts, inclusive';
|
|
||||||
COMMENT ON COLUMN work_shards.end_row
|
|
||||||
IS 'row at which the shard scope ends, exclusive';
|
|
||||||
COMMENT ON COLUMN work_shards.job_name
|
|
||||||
IS 'unique name of the job the workers on this shard are performing';
|
|
||||||
|
|
||||||
CREATE INDEX work_shards_by_job_name_completed_last_attempt_index
|
|
||||||
ON work_shards
|
|
||||||
(job_name
|
|
||||||
,completed
|
|
||||||
,last_attempt ASC
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE INDEX work_shards_by_end_row_index
|
|
||||||
ON work_shards
|
|
||||||
(end_row DESC);
|
|
||||||
|
|
||||||
CREATE INDEX work_shards_by_rows
|
|
||||||
ON work_shards
|
|
||||||
(job_name
|
|
||||||
,start_row
|
|
||||||
,end_row);
|
|
||||||
|
|
@ -1,157 +0,0 @@
|
||||||
--
|
|
||||||
-- This file is part of TALER
|
|
||||||
-- Copyright (C) 2014--2025 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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
CREATE FUNCTION create_table_kyc_targets(
|
|
||||||
IN partition_suffix TEXT DEFAULT NULL
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
my_rec RECORD;
|
|
||||||
my_payto TEXT;
|
|
||||||
my_is_wallet BOOL;
|
|
||||||
wtc CURSOR FOR
|
|
||||||
SELECT
|
|
||||||
access_token
|
|
||||||
,target_pub
|
|
||||||
,h_normalized_payto
|
|
||||||
,aml_program_lock_timeout
|
|
||||||
,payto_uri
|
|
||||||
FROM exchange.wire_targets;
|
|
||||||
BEGIN
|
|
||||||
PERFORM create_partitioned_table(
|
|
||||||
'CREATE TABLE %I'
|
|
||||||
'(kyc_target_serial_id BIGINT GENERATED BY DEFAULT AS IDENTITY'
|
|
||||||
',h_normalized_payto BYTEA PRIMARY KEY CHECK(LENGTH(h_normalized_payto)=32)'
|
|
||||||
',access_token BYTEA CHECK(LENGTH(access_token)=32)'
|
|
||||||
' DEFAULT random_bytea(32)'
|
|
||||||
',target_pub BYTEA CHECK(LENGTH(target_pub)=32) DEFAULT NULL'
|
|
||||||
',aml_program_lock_timeout INT8 DEFAULT NULL'
|
|
||||||
',is_wallet BOOL'
|
|
||||||
') %s ;'
|
|
||||||
,'kyc_targets'
|
|
||||||
,'PARTITION BY HASH (h_normalized_payto)'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_table(
|
|
||||||
'All identities for KYC purposes based on normalized payto URIs'
|
|
||||||
,'kyc_targets'
|
|
||||||
,partition_suffix
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'high-entropy random value that is used as a bearer token used to authenticate access to the KYC SPA and its state (without requiring a signature)'
|
|
||||||
,'access_token'
|
|
||||||
,'kyc_targets'
|
|
||||||
,NULL
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'Public key of a merchant instance or reserve to authenticate access; NULL if KYC is not allowed for the account (if there was no incoming KYC wire transfer yet); updated, thus NOT available to the auditor'
|
|
||||||
,'target_pub'
|
|
||||||
,'kyc_targets'
|
|
||||||
,NULL
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'hash over the normalized payto URI for this account; used for KYC operations'
|
|
||||||
,'h_normalized_payto'
|
|
||||||
,'kyc_targets'
|
|
||||||
,NULL
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'If non-NULL, an AML program should be running and it holds a lock on this account, thus other AML programs should not be started concurrently. Given the possibility of crashes, the lock automatically expires at the time value given in this column. At that time, the lock can be considered stale.'
|
|
||||||
,'aml_program_lock_timeout'
|
|
||||||
,'kyc_targets'
|
|
||||||
,NULL
|
|
||||||
);
|
|
||||||
PERFORM comment_partitioned_column(
|
|
||||||
'True if this KYC account is for a wallet, false if it is for a bank account'
|
|
||||||
,'is_wallet'
|
|
||||||
,'kyc_targets'
|
|
||||||
,NULL
|
|
||||||
);
|
|
||||||
|
|
||||||
-- Migrate existing entries. We may have multiple for
|
|
||||||
-- the same account, which is a historic bug (#10003)
|
|
||||||
-- we are implicitly fixing here via "ON CONFLICT
|
|
||||||
-- DO NOTHING" which ensures that moving forward we
|
|
||||||
-- have a unique access token per KYC account.
|
|
||||||
FOR my_rec IN wtc
|
|
||||||
LOOP
|
|
||||||
my_payto = my_rec.payto_uri;
|
|
||||||
my_is_wallet
|
|
||||||
= (LOWER (SUBSTRING (my_payto, 22)) =
|
|
||||||
'payto://taler-reserve/') OR
|
|
||||||
(LOWER (SUBSTRING (my_payto, 27)) =
|
|
||||||
'payto://taler-reserve-http/');
|
|
||||||
INSERT INTO kyc_targets
|
|
||||||
(h_normalized_payto
|
|
||||||
,access_token
|
|
||||||
,target_pub
|
|
||||||
,aml_program_lock_timeout
|
|
||||||
,is_wallet
|
|
||||||
) VALUES (
|
|
||||||
my_rec.h_normalized_payto
|
|
||||||
,my_rec.access_token
|
|
||||||
,my_rec.target_pub
|
|
||||||
,my_rec.aml_program_lock_timeout
|
|
||||||
,my_is_wallet
|
|
||||||
)
|
|
||||||
ON CONFLICT DO NOTHING;
|
|
||||||
END LOOP;
|
|
||||||
END $$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION constrain_table_kyc_targets(
|
|
||||||
IN partition_suffix TEXT
|
|
||||||
)
|
|
||||||
RETURNS void
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'kyc_targets';
|
|
||||||
BEGIN
|
|
||||||
table_name = concat_ws('_', table_name, partition_suffix);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD CONSTRAINT ' || table_name || '_kyc_target_serial_id_key'
|
|
||||||
' UNIQUE (kyc_target_serial_id)'
|
|
||||||
);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD CONSTRAINT ' || table_name || '_kyc_target_access_token_unique'
|
|
||||||
' UNIQUE (access_token)'
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
INSERT INTO exchange_tables
|
|
||||||
(name
|
|
||||||
,version
|
|
||||||
,action
|
|
||||||
,partitioned
|
|
||||||
,by_range)
|
|
||||||
VALUES
|
|
||||||
('kyc_targets'
|
|
||||||
,'exchange-0003'
|
|
||||||
,'create'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('kyc_targets'
|
|
||||||
,'exchange-0003'
|
|
||||||
,'constrain'
|
|
||||||
,TRUE
|
|
||||||
,FALSE);
|
|
||||||
|
|
@ -1,49 +0,0 @@
|
||||||
--
|
|
||||||
-- This file is part of TALER
|
|
||||||
-- Copyright (C) 2024 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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
CREATE FUNCTION foreign_table_legitimization_measures3()
|
|
||||||
RETURNS void
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'legitimization_measures';
|
|
||||||
BEGIN
|
|
||||||
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' DROP CONSTRAINT ' || table_name || '_foreign_key_access_token');
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD CONSTRAINT ' || table_name || '_foreign_key_access_token'
|
|
||||||
' FOREIGN KEY (access_token)'
|
|
||||||
' REFERENCES kyc_targets (access_token)'
|
|
||||||
' ON DELETE CASCADE');
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
INSERT INTO exchange_tables
|
|
||||||
(name
|
|
||||||
,version
|
|
||||||
,action
|
|
||||||
,partitioned
|
|
||||||
,by_range)
|
|
||||||
VALUES
|
|
||||||
('legitimization_measures3'
|
|
||||||
,'exchange-0003'
|
|
||||||
,'foreign'
|
|
||||||
,TRUE
|
|
||||||
,FALSE);
|
|
||||||
|
|
@ -1,45 +0,0 @@
|
||||||
--
|
|
||||||
-- This file is part of TALER
|
|
||||||
-- Copyright (C) 2025 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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
CREATE FUNCTION foreign_table_legitimization_outcomes3()
|
|
||||||
RETURNS void
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'legitimization_outcomes';
|
|
||||||
BEGIN
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD CONSTRAINT ' || table_name || '_foreign_key_h_payto'
|
|
||||||
' FOREIGN KEY (h_payto)'
|
|
||||||
' REFERENCES kyc_targets (h_normalized_payto)'
|
|
||||||
' ON DELETE CASCADE');
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
INSERT INTO exchange_tables
|
|
||||||
(name
|
|
||||||
,version
|
|
||||||
,action
|
|
||||||
,partitioned
|
|
||||||
,by_range)
|
|
||||||
VALUES
|
|
||||||
('legitimization_outcomes3'
|
|
||||||
,'exchange-0003'
|
|
||||||
,'foreign'
|
|
||||||
,TRUE
|
|
||||||
,FALSE);
|
|
||||||
|
|
@ -1,45 +0,0 @@
|
||||||
--
|
|
||||||
-- This file is part of TALER
|
|
||||||
-- Copyright (C) 2025 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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
CREATE FUNCTION foreign_table_legitimization_processes3()
|
|
||||||
RETURNS void
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'legitimization_processes';
|
|
||||||
BEGIN
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD CONSTRAINT ' || table_name || '_foreign_key_h_payto'
|
|
||||||
' FOREIGN KEY (h_payto)'
|
|
||||||
' REFERENCES kyc_targets (h_normalized_payto)'
|
|
||||||
' ON DELETE CASCADE');
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
INSERT INTO exchange_tables
|
|
||||||
(name
|
|
||||||
,version
|
|
||||||
,action
|
|
||||||
,partitioned
|
|
||||||
,by_range)
|
|
||||||
VALUES
|
|
||||||
('legitimization_processes3'
|
|
||||||
,'exchange-0003'
|
|
||||||
,'foreign'
|
|
||||||
,TRUE
|
|
||||||
,FALSE);
|
|
||||||
|
|
@ -1,40 +0,0 @@
|
||||||
--
|
|
||||||
-- This file is part of TALER
|
|
||||||
-- Copyright (C) 2025 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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION master_table_reserves_out3()
|
|
||||||
RETURNS void
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
BEGIN
|
|
||||||
DROP TABLE IF EXISTS reserves_out;
|
|
||||||
END $$;
|
|
||||||
COMMENT ON FUNCTION master_table_reserves_out3()
|
|
||||||
IS 'Deletes the obsolete reserves_out table.';
|
|
||||||
|
|
||||||
|
|
||||||
INSERT INTO exchange_tables
|
|
||||||
(name
|
|
||||||
,version
|
|
||||||
,action
|
|
||||||
,partitioned
|
|
||||||
,by_range)
|
|
||||||
VALUES
|
|
||||||
('reserves_out3'
|
|
||||||
,'exchange-0003'
|
|
||||||
,'master'
|
|
||||||
,TRUE
|
|
||||||
,FALSE);
|
|
||||||
|
|
@ -1,61 +0,0 @@
|
||||||
--
|
|
||||||
-- This file is part of TALER
|
|
||||||
-- Copyright (C) 2014--2025 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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
CREATE FUNCTION alter_table_wire_targets3()
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
BEGIN
|
|
||||||
ALTER TABLE wire_targets
|
|
||||||
DROP COLUMN access_token,
|
|
||||||
DROP COLUMN aml_program_lock_timeout,
|
|
||||||
DROP COLUMN target_pub;
|
|
||||||
END $$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION foreign_table_wire_targets3()
|
|
||||||
RETURNS void
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'wire_targets';
|
|
||||||
BEGIN
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD CONSTRAINT ' || table_name || '_fk_kyc_targets'
|
|
||||||
' FOREIGN KEY (h_normalized_payto) REFERENCES kyc_targets (h_normalized_payto)'
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
INSERT INTO exchange_tables
|
|
||||||
(name
|
|
||||||
,version
|
|
||||||
,action
|
|
||||||
,partitioned
|
|
||||||
,by_range)
|
|
||||||
VALUES
|
|
||||||
('wire_targets3'
|
|
||||||
,'exchange-0003'
|
|
||||||
,'alter'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('wire_targets3'
|
|
||||||
,'exchange-0003'
|
|
||||||
,'foreign'
|
|
||||||
,TRUE
|
|
||||||
,FALSE);
|
|
||||||
|
|
@ -1,46 +0,0 @@
|
||||||
--
|
|
||||||
-- This file is part of TALER
|
|
||||||
-- Copyright (C) 2025 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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION constrain_table_kyc_attributes4(
|
|
||||||
IN partition_suffix TEXT
|
|
||||||
)
|
|
||||||
RETURNS void
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'kyc_attributes';
|
|
||||||
BEGIN
|
|
||||||
table_name = concat_ws('_', table_name, partition_suffix);
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD CONSTRAINT ' || table_name || '_legitimization_serial '
|
|
||||||
'UNIQUE (h_payto,legitimization_serial)'
|
|
||||||
);
|
|
||||||
END $$;
|
|
||||||
|
|
||||||
|
|
||||||
INSERT INTO exchange_tables
|
|
||||||
(name
|
|
||||||
,version
|
|
||||||
,action
|
|
||||||
,partitioned
|
|
||||||
,by_range)
|
|
||||||
VALUES
|
|
||||||
('kyc_attributes4'
|
|
||||||
,'exchange-0004'
|
|
||||||
,'constrain'
|
|
||||||
,TRUE
|
|
||||||
,FALSE);
|
|
||||||
|
|
@ -1,3 +1,42 @@
|
||||||
|
# TODO
|
||||||
|
# - make test
|
||||||
|
# - PostgreSQL configuration (host, port, username, password, ..)
|
||||||
|
# - gitsubmodules?
|
||||||
|
|
||||||
|
# usage:
|
||||||
|
# `make create_database`
|
||||||
|
# create a `taler-exchange` database
|
||||||
|
# `make fetch_source`
|
||||||
|
# fetch all *.sql and *.sql.in files from GNU Taler exchange repository (latest commit)
|
||||||
|
# file `exchangedb.version` contains hash of latest commit that changed
|
||||||
|
# something in exchange/src/exchangedb
|
||||||
|
# `make init`
|
||||||
|
# initialize taler-exchange database (create tables, ...)
|
||||||
|
# `taler-exchange` database must already be created
|
||||||
|
fetch_source:
|
||||||
|
git clone https://git.taler.net/exchange.git/ ./exchange
|
||||||
|
cp ./exchange/src/exchangedb/*.sql ./
|
||||||
|
cp ./exchange/src/exchangedb/*.sql.in ./
|
||||||
|
git -C ./exchange log -n 1 --pretty=format:%H ./src/exchangedb > exchangedb.version
|
||||||
|
rm -rf ./exchange
|
||||||
|
|
||||||
|
clean_source:
|
||||||
|
rm -f ./*.sql
|
||||||
|
rm -f ./*.sql.in
|
||||||
|
|
||||||
|
dbname := taler-exchange
|
||||||
|
sql_INIT := init.sql
|
||||||
|
sql_DROP := drop.sql
|
||||||
|
|
||||||
|
sql_DATA := \
|
||||||
|
versioning.sql \
|
||||||
|
exchange-0001.sql \
|
||||||
|
exchange-0002.sql \
|
||||||
|
exchange-0003.sql \
|
||||||
|
exchange-0004.sql \
|
||||||
|
exchange-0005.sql \
|
||||||
|
procedures.sql
|
||||||
|
|
||||||
procedures.sql: procedures.sql.in exchange_do_*.sql exchange_statistics_*.sql exchange_trigger_*.sql
|
procedures.sql: procedures.sql.in exchange_do_*.sql exchange_statistics_*.sql exchange_trigger_*.sql
|
||||||
chmod +w $@ 2> /dev/null || true
|
chmod +w $@ 2> /dev/null || true
|
||||||
gcc -E -P -undef - < procedures.sql.in 2>/dev/null | sed -e "s/--.*//" | awk 'NF' - >$@
|
gcc -E -P -undef - < procedures.sql.in 2>/dev/null | sed -e "s/--.*//" | awk 'NF' - >$@
|
||||||
|
|
@ -17,3 +56,32 @@ exchange-0004.sql: exchange-0004.sql.in 0004-*.sql
|
||||||
chmod +w $@ 2> /dev/null || true
|
chmod +w $@ 2> /dev/null || true
|
||||||
gcc -E -P -undef - < exchange-0004.sql.in 2>/dev/null | sed -e "s/--.*//" | awk 'NF' - >$@
|
gcc -E -P -undef - < exchange-0004.sql.in 2>/dev/null | sed -e "s/--.*//" | awk 'NF' - >$@
|
||||||
chmod ugo-w $@
|
chmod ugo-w $@
|
||||||
|
|
||||||
|
gen_sql: procedures.sql exchange-0002.sql exchange-0003.sql exchange-0004.sql
|
||||||
|
|
||||||
|
.DEFAULT_GOAL := gen_init
|
||||||
|
gen_init: gen_sql $(sql_DATA)
|
||||||
|
@printf "" > $(sql_INIT)
|
||||||
|
@cat $(sql_DATA) >> $(sql_INIT)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f procedures.sql
|
||||||
|
rm -f exchange-0002.sql
|
||||||
|
rm -f exchange-0003.sql
|
||||||
|
rm -f exchange-0004.sql
|
||||||
|
rm $(sql_INIT)
|
||||||
|
|
||||||
|
# "NOTICE: function xxx() does not exist, skipping" are normal and expected
|
||||||
|
init: gen_init
|
||||||
|
psql --host=localhost --port=5432 --username=mte --password --dbname=$(dbname) --file=$(sql_INIT)
|
||||||
|
|
||||||
|
drop:
|
||||||
|
psql --host=localhost --port=5432 --username=mte --password --dbname=$(dbname) --file=$(sql_DROP)
|
||||||
|
|
||||||
|
create_database:
|
||||||
|
createdb --host=localhost --port=5432 --username=mte --password $(dbname)
|
||||||
|
|
||||||
|
drop_database:
|
||||||
|
dropdb --host=localhost --port=5432 --username=mte --password $(dbname)
|
||||||
|
|
||||||
|
reset_database: drop_database create_database
|
||||||
|
|
|
||||||
|
|
@ -1,471 +0,0 @@
|
||||||
--
|
|
||||||
-- This file is part of TALER
|
|
||||||
-- Copyright (C) 2024 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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
-- Everything in one big transaction
|
|
||||||
BEGIN;
|
|
||||||
|
|
||||||
SELECT _v.register_patch('auditor-triggers-0001');
|
|
||||||
|
|
||||||
/*
|
|
||||||
CREATE OR REPLACE FUNCTION auditor_new_deposits_trigger()
|
|
||||||
RETURNS trigger
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
BEGIN
|
|
||||||
NOTIFY XFIXME;
|
|
||||||
RETURN NEW;
|
|
||||||
END $$;
|
|
||||||
COMMENT ON FUNCTION auditor_new_deposits_trigger()
|
|
||||||
IS 'Call XXX on new entry';
|
|
||||||
|
|
||||||
CREATE TRIGGER auditor_notify_helper_insert_deposits
|
|
||||||
AFTER INSERT
|
|
||||||
ON exchange.batch_deposits
|
|
||||||
EXECUTE PROCEDURE auditor_new_deposits_trigger();
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
-- make 6 of these functions, one for each helper
|
|
||||||
|
|
||||||
-- the coins helper listens to this trigger
|
|
||||||
CREATE OR REPLACE FUNCTION auditor_wake_coins_helper_trigger()
|
|
||||||
RETURNS trigger
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
BEGIN
|
|
||||||
NOTIFY X5V5R0DDFMXS0R3W058R3W4RPDVMK35YZCS0S5VZS583J0NR0PE2G;
|
|
||||||
RETURN NEW;
|
|
||||||
END $$;
|
|
||||||
COMMENT ON FUNCTION auditor_wake_coins_helper_trigger()
|
|
||||||
IS 'Call auditor_call_db_notify on new entry';
|
|
||||||
|
|
||||||
|
|
||||||
-- the purses helper listens to this trigger
|
|
||||||
CREATE OR REPLACE FUNCTION auditor_wake_purses_helper_trigger()
|
|
||||||
RETURNS trigger
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
BEGIN
|
|
||||||
NOTIFY X908G8PNPMJYA59YGGTJND1TKTBFNG8C7TREHG3X5SJ9EQAJY4Z00;
|
|
||||||
RETURN NEW;
|
|
||||||
END $$;
|
|
||||||
COMMENT ON FUNCTION auditor_wake_purses_helper_trigger()
|
|
||||||
IS 'Call auditor_call_db_notify on new entry';
|
|
||||||
|
|
||||||
|
|
||||||
-- the deposits helper listens to this trigger
|
|
||||||
CREATE OR REPLACE FUNCTION auditor_wake_deposits_helper_trigger()
|
|
||||||
RETURNS trigger
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
BEGIN
|
|
||||||
NOTIFY XZD0FASMJD3XCY3Z0CGXNJQ8CMWSCW80JN6796098N71CXPH70TQ0;
|
|
||||||
RETURN NEW;
|
|
||||||
END $$;
|
|
||||||
COMMENT ON FUNCTION auditor_wake_deposits_helper_trigger()
|
|
||||||
IS 'Call auditor_call_db_notify on new entry';
|
|
||||||
|
|
||||||
-- the reserves helper listens to this trigger
|
|
||||||
CREATE OR REPLACE FUNCTION auditor_wake_reserves_helper_trigger()
|
|
||||||
RETURNS trigger
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
BEGIN
|
|
||||||
NOTIFY XMF69RJQB7EN06KGSQ02VFD3723CE86VXA5GRE8H7XNNS6BDYF0G0;
|
|
||||||
RETURN NEW;
|
|
||||||
END $$;
|
|
||||||
COMMENT ON FUNCTION auditor_wake_reserves_helper_trigger()
|
|
||||||
IS 'Call auditor_call_db_notify on new entry';
|
|
||||||
|
|
||||||
-- the wire helper listens to this trigger
|
|
||||||
CREATE OR REPLACE FUNCTION auditor_wake_wire_helper_trigger()
|
|
||||||
RETURNS trigger
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
BEGIN
|
|
||||||
NOTIFY X1RYYSTS139MBHVEXJ6CZZTY76MAMEEF87SRRWC8WM00HCCW6D12G;
|
|
||||||
RETURN NEW;
|
|
||||||
END $$;
|
|
||||||
COMMENT ON FUNCTION auditor_wake_wire_helper_trigger()
|
|
||||||
IS 'Call auditor_call_db_notify on new entry';
|
|
||||||
|
|
||||||
-- the wire aggregation listens to this trigger
|
|
||||||
CREATE OR REPLACE FUNCTION auditor_wake_aggregation_helper_trigger()
|
|
||||||
RETURNS trigger
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
BEGIN
|
|
||||||
NOTIFY XWRPZ889FPA6TMGJ15JVTCMKEFVJEWCEKF1TEZHTDQHBYSV49M31G;
|
|
||||||
RETURN NEW;
|
|
||||||
END $$;
|
|
||||||
COMMENT ON FUNCTION auditor_wake_aggregation_helper_trigger()
|
|
||||||
IS 'Call auditor_call_db_notify on new entry';
|
|
||||||
|
|
||||||
|
|
||||||
-- call the functions in each table to call all relevant helpers
|
|
||||||
CREATE OR REPLACE TRIGGER auditor_exchange_notify_helper_aggregation0
|
|
||||||
AFTER INSERT ON exchange.batch_deposits
|
|
||||||
EXECUTE FUNCTION auditor_wake_aggregation_helper_trigger();
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE TRIGGER auditor_exchange_notify_helper_aggregation1
|
|
||||||
AFTER INSERT ON exchange.partners
|
|
||||||
EXECUTE FUNCTION auditor_wake_aggregation_helper_trigger();
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE TRIGGER auditor_exchange_notify_helper_aggregation2
|
|
||||||
AFTER INSERT ON exchange.wire_targets
|
|
||||||
EXECUTE FUNCTION auditor_wake_aggregation_helper_trigger();
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE TRIGGER auditor_exchange_notify_helper_aggregation3
|
|
||||||
AFTER INSERT ON exchange.reserves_open_deposits
|
|
||||||
EXECUTE FUNCTION auditor_wake_aggregation_helper_trigger();
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE TRIGGER auditor_exchange_notify_helper_aggregation4
|
|
||||||
AFTER INSERT ON exchange.aggregation_tracking
|
|
||||||
EXECUTE FUNCTION auditor_wake_aggregation_helper_trigger();
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE TRIGGER auditor_exchange_notify_helper_aggregation5
|
|
||||||
AFTER INSERT ON exchange.purse_requests
|
|
||||||
EXECUTE FUNCTION auditor_wake_aggregation_helper_trigger();
|
|
||||||
|
|
||||||
|
|
||||||
-- FIXME: #9900
|
|
||||||
--CREATE OR REPLACE TRIGGER auditor_exchange_notify_helper_aggregation6
|
|
||||||
-- AFTER INSERT ON exchange.refresh_revealed_coins
|
|
||||||
--EXECUTE FUNCTION auditor_wake_aggregation_helper_trigger();
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE TRIGGER auditor_exchange_notify_helper_aggregation7
|
|
||||||
AFTER INSERT ON exchange.reserves
|
|
||||||
EXECUTE FUNCTION auditor_wake_aggregation_helper_trigger();
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE TRIGGER auditor_exchange_notify_helper_aggregation8
|
|
||||||
AFTER INSERT ON exchange.purse_deposits
|
|
||||||
EXECUTE FUNCTION auditor_wake_aggregation_helper_trigger();
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE TRIGGER auditor_exchange_notify_helper_aggregation9
|
|
||||||
AFTER INSERT ON exchange.withdraw
|
|
||||||
EXECUTE FUNCTION auditor_wake_aggregation_helper_trigger();
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE TRIGGER auditor_exchange_notify_helper_aggregation10
|
|
||||||
AFTER INSERT ON exchange.recoup
|
|
||||||
EXECUTE FUNCTION auditor_wake_aggregation_helper_trigger();
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE TRIGGER auditor_exchange_notify_helper_aggregation11
|
|
||||||
AFTER INSERT ON exchange.coin_history
|
|
||||||
EXECUTE FUNCTION auditor_wake_aggregation_helper_trigger();
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE TRIGGER auditor_exchange_notify_helper_aggregation12
|
|
||||||
AFTER INSERT ON exchange.coin_deposits
|
|
||||||
EXECUTE FUNCTION auditor_wake_aggregation_helper_trigger();
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE TRIGGER auditor_exchange_notify_helper_aggregation13
|
|
||||||
AFTER INSERT ON exchange.wire_out
|
|
||||||
EXECUTE FUNCTION auditor_wake_aggregation_helper_trigger();
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE TRIGGER auditor_exchange_notify_helper_aggregation14
|
|
||||||
AFTER INSERT ON exchange.refunds
|
|
||||||
EXECUTE FUNCTION auditor_wake_aggregation_helper_trigger();
|
|
||||||
|
|
||||||
-- FIXME: #9900
|
|
||||||
--CREATE OR REPLACE TRIGGER auditor_exchange_notify_helper_aggregation15
|
|
||||||
-- AFTER INSERT ON exchange.refresh_commitments
|
|
||||||
--EXECUTE FUNCTION auditor_wake_aggregation_helper_trigger();
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE TRIGGER auditor_exchange_notify_helper_aggregation16
|
|
||||||
AFTER INSERT ON exchange.purse_decision
|
|
||||||
EXECUTE FUNCTION auditor_wake_aggregation_helper_trigger();
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE TRIGGER auditor_exchange_notify_helper_aggregation17
|
|
||||||
AFTER INSERT ON exchange.known_coins
|
|
||||||
EXECUTE FUNCTION auditor_wake_aggregation_helper_trigger();
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE TRIGGER auditor_exchange_notify_helper_aggregation18
|
|
||||||
AFTER INSERT ON exchange.recoup_refresh
|
|
||||||
EXECUTE FUNCTION auditor_wake_aggregation_helper_trigger();
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE TRIGGER auditor_exchange_notify_helper_coins0
|
|
||||||
AFTER INSERT ON exchange.purse_merges
|
|
||||||
EXECUTE FUNCTION auditor_wake_coins_helper_trigger();
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE TRIGGER auditor_exchange_notify_helper_coins1
|
|
||||||
AFTER INSERT ON exchange.batch_deposits
|
|
||||||
EXECUTE FUNCTION auditor_wake_coins_helper_trigger();
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE TRIGGER auditor_exchange_notify_helper_coins2
|
|
||||||
AFTER INSERT ON exchange.partners
|
|
||||||
EXECUTE FUNCTION auditor_wake_coins_helper_trigger();
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE TRIGGER auditor_exchange_notify_helper_coins3
|
|
||||||
AFTER INSERT ON exchange.denomination_revocations
|
|
||||||
EXECUTE FUNCTION auditor_wake_coins_helper_trigger();
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE TRIGGER auditor_exchange_notify_helper_coins4
|
|
||||||
AFTER INSERT ON exchange.wire_targets
|
|
||||||
EXECUTE FUNCTION auditor_wake_coins_helper_trigger();
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE TRIGGER auditor_exchange_notify_helper_coins5
|
|
||||||
AFTER INSERT ON exchange.auditors
|
|
||||||
EXECUTE FUNCTION auditor_wake_coins_helper_trigger();
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE TRIGGER auditor_exchange_notify_helper_coins6
|
|
||||||
AFTER INSERT ON exchange.purse_requests
|
|
||||||
EXECUTE FUNCTION auditor_wake_coins_helper_trigger();
|
|
||||||
|
|
||||||
|
|
||||||
-- FIXME: #9900
|
|
||||||
--CREATE OR REPLACE TRIGGER auditor_exchange_notify_helper_coins7
|
|
||||||
-- AFTER INSERT ON exchange.refresh_revealed_coins
|
|
||||||
--EXECUTE FUNCTION auditor_wake_coins_helper_trigger();
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE TRIGGER auditor_exchange_notify_helper_coins8
|
|
||||||
AFTER INSERT ON exchange.reserves
|
|
||||||
EXECUTE FUNCTION auditor_wake_coins_helper_trigger();
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE TRIGGER auditor_exchange_notify_helper_coins9
|
|
||||||
AFTER INSERT ON exchange.purse_deposits
|
|
||||||
EXECUTE FUNCTION auditor_wake_coins_helper_trigger();
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE TRIGGER auditor_exchange_notify_helper_coins10
|
|
||||||
AFTER INSERT ON exchange.withdraw
|
|
||||||
EXECUTE FUNCTION auditor_wake_coins_helper_trigger();
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE TRIGGER auditor_exchange_notify_helper_coins11
|
|
||||||
AFTER INSERT ON exchange.recoup
|
|
||||||
EXECUTE FUNCTION auditor_wake_coins_helper_trigger();
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE TRIGGER auditor_exchange_notify_helper_coins12
|
|
||||||
AFTER INSERT ON exchange.auditor_denom_sigs
|
|
||||||
EXECUTE FUNCTION auditor_wake_coins_helper_trigger();
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE TRIGGER auditor_exchange_notify_helper_coins13
|
|
||||||
AFTER INSERT ON exchange.coin_deposits
|
|
||||||
EXECUTE FUNCTION auditor_wake_coins_helper_trigger();
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE TRIGGER auditor_exchange_notify_helper_coins14
|
|
||||||
AFTER INSERT ON exchange.refunds
|
|
||||||
EXECUTE FUNCTION auditor_wake_coins_helper_trigger();
|
|
||||||
|
|
||||||
|
|
||||||
-- FIXME: #9900
|
|
||||||
--CREATE OR REPLACE TRIGGER auditor_exchange_notify_helper_coins15
|
|
||||||
-- AFTER INSERT ON exchange.refresh_commitments
|
|
||||||
--EXECUTE FUNCTION auditor_wake_coins_helper_trigger();
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE TRIGGER auditor_exchange_notify_helper_coins16
|
|
||||||
AFTER INSERT ON exchange.purse_decision
|
|
||||||
EXECUTE FUNCTION auditor_wake_coins_helper_trigger();
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE TRIGGER auditor_exchange_notify_helper_coins17
|
|
||||||
AFTER INSERT ON exchange.known_coins
|
|
||||||
EXECUTE FUNCTION auditor_wake_coins_helper_trigger();
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE TRIGGER auditor_exchange_notify_helper_coins18
|
|
||||||
AFTER INSERT ON exchange.recoup_refresh
|
|
||||||
EXECUTE FUNCTION auditor_wake_coins_helper_trigger();
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE TRIGGER auditor_exchange_notify_helper_purses0
|
|
||||||
AFTER INSERT ON exchange.purse_merges
|
|
||||||
EXECUTE FUNCTION auditor_wake_purses_helper_trigger();
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE TRIGGER auditor_exchange_notify_helper_purses1
|
|
||||||
AFTER INSERT ON exchange.account_merges
|
|
||||||
EXECUTE FUNCTION auditor_wake_purses_helper_trigger();
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE TRIGGER auditor_exchange_notify_helper_purses2
|
|
||||||
AFTER INSERT ON exchange.purse_deposits
|
|
||||||
EXECUTE FUNCTION auditor_wake_purses_helper_trigger();
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE TRIGGER auditor_exchange_notify_helper_purses3
|
|
||||||
AFTER INSERT ON exchange.global_fee
|
|
||||||
EXECUTE FUNCTION auditor_wake_purses_helper_trigger();
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE TRIGGER auditor_exchange_notify_helper_purses4
|
|
||||||
AFTER INSERT ON exchange.purse_requests
|
|
||||||
EXECUTE FUNCTION auditor_wake_purses_helper_trigger();
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE TRIGGER auditor_exchange_notify_helper_purses5
|
|
||||||
AFTER INSERT ON exchange.partners
|
|
||||||
EXECUTE FUNCTION auditor_wake_purses_helper_trigger();
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE TRIGGER auditor_exchange_notify_helper_purses6
|
|
||||||
AFTER INSERT ON exchange.purse_decision
|
|
||||||
EXECUTE FUNCTION auditor_wake_purses_helper_trigger();
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE TRIGGER auditor_exchange_notify_helper_purses7
|
|
||||||
AFTER INSERT ON exchange.known_coins
|
|
||||||
EXECUTE FUNCTION auditor_wake_purses_helper_trigger();
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE TRIGGER auditor_exchange_notify_helper_deposits0
|
|
||||||
AFTER INSERT ON exchange.wire_targets
|
|
||||||
EXECUTE FUNCTION auditor_wake_deposits_helper_trigger();
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE TRIGGER auditor_exchange_notify_helper_deposits1
|
|
||||||
AFTER INSERT ON exchange.batch_deposits
|
|
||||||
EXECUTE FUNCTION auditor_wake_deposits_helper_trigger();
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE TRIGGER auditor_exchange_notify_helper_deposits2
|
|
||||||
AFTER INSERT ON exchange.known_coins
|
|
||||||
EXECUTE FUNCTION auditor_wake_deposits_helper_trigger();
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE TRIGGER auditor_exchange_notify_helper_deposits3
|
|
||||||
AFTER INSERT ON exchange.coin_deposits
|
|
||||||
EXECUTE FUNCTION auditor_wake_deposits_helper_trigger();
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE TRIGGER auditor_exchange_notify_helper_reserves0
|
|
||||||
AFTER INSERT ON exchange.wire_fee
|
|
||||||
EXECUTE FUNCTION auditor_wake_reserves_helper_trigger();
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE TRIGGER auditor_exchange_notify_helper_reserves1
|
|
||||||
AFTER INSERT ON exchange.reserves
|
|
||||||
EXECUTE FUNCTION auditor_wake_reserves_helper_trigger();
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE TRIGGER auditor_exchange_notify_helper_reserves2
|
|
||||||
AFTER INSERT ON exchange.reserves_close
|
|
||||||
EXECUTE FUNCTION auditor_wake_reserves_helper_trigger();
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE TRIGGER auditor_exchange_notify_helper_reserves3
|
|
||||||
AFTER INSERT ON exchange.purse_merges
|
|
||||||
EXECUTE FUNCTION auditor_wake_reserves_helper_trigger();
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE TRIGGER auditor_exchange_notify_helper_reserves4
|
|
||||||
AFTER INSERT ON exchange.wire_targets
|
|
||||||
EXECUTE FUNCTION auditor_wake_reserves_helper_trigger();
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE TRIGGER auditor_exchange_notify_helper_reserves5
|
|
||||||
AFTER INSERT ON exchange.withdraw
|
|
||||||
EXECUTE FUNCTION auditor_wake_reserves_helper_trigger();
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE TRIGGER auditor_exchange_notify_helper_reserves6
|
|
||||||
AFTER INSERT ON exchange.recoup
|
|
||||||
EXECUTE FUNCTION auditor_wake_reserves_helper_trigger();
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE TRIGGER auditor_exchange_notify_helper_reserves7
|
|
||||||
AFTER INSERT ON exchange.purse_requests
|
|
||||||
EXECUTE FUNCTION auditor_wake_reserves_helper_trigger();
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE TRIGGER auditor_exchange_notify_helper_reserves8
|
|
||||||
AFTER INSERT ON exchange.reserves_open_requests
|
|
||||||
EXECUTE FUNCTION auditor_wake_reserves_helper_trigger();
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE TRIGGER auditor_exchange_notify_helper_reserves9
|
|
||||||
AFTER INSERT ON exchange.denomination_revocations
|
|
||||||
EXECUTE FUNCTION auditor_wake_reserves_helper_trigger();
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE TRIGGER auditor_exchange_notify_helper_reserves10
|
|
||||||
AFTER INSERT ON exchange.purse_decision
|
|
||||||
EXECUTE FUNCTION auditor_wake_reserves_helper_trigger();
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE TRIGGER auditor_exchange_notify_helper_reserves11
|
|
||||||
AFTER INSERT ON exchange.known_coins
|
|
||||||
EXECUTE FUNCTION auditor_wake_reserves_helper_trigger();
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE TRIGGER auditor_exchange_notify_helper_reserves12
|
|
||||||
AFTER INSERT ON exchange.reserves_in
|
|
||||||
EXECUTE FUNCTION auditor_wake_reserves_helper_trigger();
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE TRIGGER auditor_exchange_notify_helper_wire0
|
|
||||||
AFTER INSERT ON exchange.reserves
|
|
||||||
EXECUTE FUNCTION auditor_wake_wire_helper_trigger();
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE TRIGGER auditor_exchange_notify_helper_wire1
|
|
||||||
AFTER INSERT ON exchange.wire_targets
|
|
||||||
EXECUTE FUNCTION auditor_wake_wire_helper_trigger();
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE TRIGGER auditor_exchange_notify_helper_wire2
|
|
||||||
AFTER INSERT ON exchange.aggregation_tracking
|
|
||||||
EXECUTE FUNCTION auditor_wake_wire_helper_trigger();
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE TRIGGER auditor_exchange_notify_helper_wire3
|
|
||||||
AFTER INSERT ON exchange.wire_out
|
|
||||||
EXECUTE FUNCTION auditor_wake_wire_helper_trigger();
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE TRIGGER auditor_exchange_notify_helper_wire4
|
|
||||||
AFTER INSERT ON exchange.reserves_close
|
|
||||||
EXECUTE FUNCTION auditor_wake_wire_helper_trigger();
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE TRIGGER auditor_exchange_notify_helper_wire5
|
|
||||||
AFTER INSERT ON exchange.profit_drains
|
|
||||||
EXECUTE FUNCTION auditor_wake_wire_helper_trigger();
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE TRIGGER auditor_exchange_notify_helper_wire6
|
|
||||||
AFTER INSERT ON exchange.reserves_in
|
|
||||||
EXECUTE FUNCTION auditor_wake_wire_helper_trigger();
|
|
||||||
|
|
||||||
COMMIT;
|
|
||||||
|
|
@ -1,55 +0,0 @@
|
||||||
--
|
|
||||||
-- This file is part of TALER
|
|
||||||
-- Copyright (C) 2014--2021 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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
-- Everything in one big transaction
|
|
||||||
BEGIN;
|
|
||||||
|
|
||||||
-- Check patch versioning is in place.
|
|
||||||
SELECT _v.register_patch('benchmark-0001', NULL, NULL);
|
|
||||||
|
|
||||||
-- Naive, btree version
|
|
||||||
CREATE TABLE IF NOT EXISTS benchmap
|
|
||||||
(uuid BIGSERIAL PRIMARY KEY
|
|
||||||
,hc BYTEA UNIQUE CHECK(LENGTH(hc)=64)
|
|
||||||
,expiration_date INT8 NOT NULL
|
|
||||||
);
|
|
||||||
|
|
||||||
-- Replace btree with hash-based index
|
|
||||||
CREATE TABLE IF NOT EXISTS benchhmap
|
|
||||||
(uuid BIGSERIAL PRIMARY KEY
|
|
||||||
,hc BYTEA NOT NULL CHECK(LENGTH(hc)=64)
|
|
||||||
,expiration_date INT8 NOT NULL
|
|
||||||
);
|
|
||||||
CREATE INDEX IF NOT EXISTS benchhmap_index
|
|
||||||
ON benchhmap
|
|
||||||
USING HASH (hc);
|
|
||||||
ALTER TABLE benchhmap
|
|
||||||
ADD CONSTRAINT pk
|
|
||||||
EXCLUDE USING HASH (hc with =);
|
|
||||||
|
|
||||||
-- Keep btree, also add 32-bit hash-based index on top
|
|
||||||
CREATE TABLE IF NOT EXISTS benchemap
|
|
||||||
(uuid BIGSERIAL PRIMARY KEY
|
|
||||||
,ihc INT4 NOT NULL
|
|
||||||
,hc BYTEA UNIQUE CHECK(LENGTH(hc)=64)
|
|
||||||
,expiration_date INT8 NOT NULL
|
|
||||||
);
|
|
||||||
CREATE INDEX IF NOT EXISTS benchemap_index
|
|
||||||
ON benchemap
|
|
||||||
USING HASH (ihc);
|
|
||||||
|
|
||||||
-- Complete transaction
|
|
||||||
COMMIT;
|
|
||||||
|
|
@ -1,38 +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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
-- Everything in one big transaction
|
|
||||||
BEGIN;
|
|
||||||
|
|
||||||
WITH xpatches AS (
|
|
||||||
SELECT patch_name
|
|
||||||
FROM _v.patches
|
|
||||||
WHERE starts_with(patch_name,'exchange-')
|
|
||||||
)
|
|
||||||
SELECT _v.unregister_patch(xpatches.patch_name)
|
|
||||||
FROM xpatches;
|
|
||||||
|
|
||||||
WITH xpatches AS (
|
|
||||||
SELECT patch_name
|
|
||||||
FROM _v.patches
|
|
||||||
WHERE starts_with(patch_name,'auditor-triggers-')
|
|
||||||
)
|
|
||||||
SELECT _v.unregister_patch(xpatches.patch_name)
|
|
||||||
FROM xpatches;
|
|
||||||
|
|
||||||
DROP SCHEMA exchange CASCADE;
|
|
||||||
|
|
||||||
COMMIT;
|
|
||||||
|
|
@ -1,61 +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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
BEGIN;
|
|
||||||
|
|
||||||
SELECT _v.register_patch('exchange-0001', NULL, NULL);
|
|
||||||
|
|
||||||
CREATE SCHEMA exchange;
|
|
||||||
COMMENT ON SCHEMA exchange IS 'taler-exchange data';
|
|
||||||
|
|
||||||
SET search_path TO exchange;
|
|
||||||
|
|
||||||
---------------------------------------------------------------------------
|
|
||||||
-- General procedures for DB setup
|
|
||||||
---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
CREATE TABLE exchange_tables
|
|
||||||
(table_serial_id INT8 GENERATED BY DEFAULT AS IDENTITY
|
|
||||||
,name TEXT NOT NULL
|
|
||||||
,version TEXT NOT NULL
|
|
||||||
,action TEXT NOT NULL
|
|
||||||
,partitioned BOOL NOT NULL
|
|
||||||
,by_range BOOL NOT NULL
|
|
||||||
,finished BOOL NOT NULL DEFAULT(FALSE));
|
|
||||||
COMMENT ON TABLE exchange_tables
|
|
||||||
IS 'Tables of the exchange and their status';
|
|
||||||
COMMENT ON COLUMN exchange_tables.name
|
|
||||||
IS 'Base name of the table (without partition/shard)';
|
|
||||||
COMMENT ON COLUMN exchange_tables.version
|
|
||||||
IS 'Version of the DB in which the given action happened';
|
|
||||||
COMMENT ON COLUMN exchange_tables.action
|
|
||||||
IS 'Action to take on the table (e.g. create, alter, constrain, or foreign). Create is done for the master table and each partition; constrain is only for partitions or for master if there are no partitions; master only on master (takes no argument); foreign only on master if there are no partitions.';
|
|
||||||
COMMENT ON COLUMN exchange_tables.partitioned
|
|
||||||
IS 'TRUE if the table is partitioned';
|
|
||||||
COMMENT ON COLUMN exchange_tables.by_range
|
|
||||||
IS 'TRUE if the table is partitioned by range';
|
|
||||||
COMMENT ON COLUMN exchange_tables.finished
|
|
||||||
IS 'TRUE if the respective migration has been run';
|
|
||||||
|
|
||||||
CREATE INDEX exchange_tables_by_pending
|
|
||||||
ON exchange_tables (table_serial_id)
|
|
||||||
WHERE NOT finished;
|
|
||||||
COMMENT ON INDEX exchange_tables_by_pending
|
|
||||||
IS 'Used by exchange_do_create_tables';
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
COMMIT;
|
|
||||||
|
|
@ -1,134 +0,0 @@
|
||||||
--
|
|
||||||
-- This file is part of TALER
|
|
||||||
-- Copyright (C) 2014--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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
BEGIN;
|
|
||||||
|
|
||||||
SELECT _v.register_patch('exchange-0002', NULL, NULL);
|
|
||||||
SET search_path TO exchange;
|
|
||||||
|
|
||||||
CREATE DOMAIN gnunet_hashcode
|
|
||||||
AS BYTEA
|
|
||||||
CHECK(LENGTH(VALUE) = 32);
|
|
||||||
|
|
||||||
CREATE TYPE taler_amount
|
|
||||||
AS
|
|
||||||
(val INT8
|
|
||||||
,frac INT4
|
|
||||||
);
|
|
||||||
COMMENT ON TYPE taler_amount
|
|
||||||
IS 'Stores an amount, fraction is in units of 1/100000000 of the base value';
|
|
||||||
|
|
||||||
CREATE TYPE exchange_do_array_reserve_insert_return_type
|
|
||||||
AS
|
|
||||||
(transaction_duplicate BOOLEAN
|
|
||||||
,ruuid INT8
|
|
||||||
);
|
|
||||||
COMMENT ON TYPE exchange_do_array_reserve_insert_return_type
|
|
||||||
IS 'Return type for exchange_do_array_reserves_insert() stored procedure';
|
|
||||||
|
|
||||||
CREATE TYPE exchange_do_select_deposits_missing_wire_return_type
|
|
||||||
AS
|
|
||||||
(
|
|
||||||
batch_deposit_serial_id INT8,
|
|
||||||
total_amount taler_amount,
|
|
||||||
wire_target_h_payto BYTEA,
|
|
||||||
deadline INT8
|
|
||||||
);
|
|
||||||
COMMENT ON TYPE exchange_do_select_deposits_missing_wire_return_type
|
|
||||||
IS 'Return type for exchange_do_select_deposits_missing_wire';
|
|
||||||
|
|
||||||
CREATE TYPE exchange_do_select_aggregations_above_serial_return_type
|
|
||||||
AS
|
|
||||||
(
|
|
||||||
batch_deposit_serial_id INT8,
|
|
||||||
aggregation_serial_id INT8,
|
|
||||||
total_amount taler_amount
|
|
||||||
);
|
|
||||||
COMMENT ON TYPE exchange_do_select_aggregations_above_serial_return_type
|
|
||||||
IS 'Return type for exchange_do_select_aggregations_above_serial';
|
|
||||||
|
|
||||||
|
|
||||||
#include "0002-denominations.sql"
|
|
||||||
#include "0002-denomination_revocations.sql"
|
|
||||||
#include "0002-wire_targets.sql"
|
|
||||||
#include "0002-kyc_alerts.sql"
|
|
||||||
#include "0002-wire_fee.sql"
|
|
||||||
#include "0002-global_fee.sql"
|
|
||||||
#include "0002-wire_accounts.sql"
|
|
||||||
#include "0002-auditors.sql"
|
|
||||||
#include "0002-auditor_denom_sigs.sql"
|
|
||||||
#include "0002-exchange_sign_keys.sql"
|
|
||||||
#include "0002-signkey_revocations.sql"
|
|
||||||
#include "0002-extensions.sql"
|
|
||||||
#include "0002-policy_fulfillments.sql"
|
|
||||||
#include "0002-policy_details.sql"
|
|
||||||
#include "0002-profit_drains.sql"
|
|
||||||
#include "0002-legitimization_measures.sql"
|
|
||||||
#include "0002-legitimization_outcomes.sql"
|
|
||||||
#include "0002-legitimization_processes.sql"
|
|
||||||
|
|
||||||
|
|
||||||
#include "0002-reserves.sql"
|
|
||||||
#include "0002-reserve_history.sql"
|
|
||||||
#include "0002-reserves_in.sql"
|
|
||||||
#include "0002-reserves_close.sql"
|
|
||||||
#include "0002-close_requests.sql"
|
|
||||||
#include "0002-reserves_open_deposits.sql"
|
|
||||||
#include "0002-reserves_open_requests.sql"
|
|
||||||
#include "0002-known_coins.sql"
|
|
||||||
#include "0002-coin_history.sql"
|
|
||||||
#include "0002-batch_deposits.sql"
|
|
||||||
#include "0002-coin_deposits.sql"
|
|
||||||
#include "0002-refunds.sql"
|
|
||||||
#include "0002-wire_out.sql"
|
|
||||||
#include "0002-aggregation_transient.sql"
|
|
||||||
#include "0002-aggregation_tracking.sql"
|
|
||||||
#include "0002-unique_refresh_blinding_seed.sql"
|
|
||||||
#include "0002-refresh.sql"
|
|
||||||
#include "0002-unique_withdraw_blinding_seed.sql"
|
|
||||||
#include "0002-withdraw.sql"
|
|
||||||
#include "0002-recoup.sql"
|
|
||||||
#include "0002-recoup_refresh.sql"
|
|
||||||
#include "0002-prewire.sql"
|
|
||||||
#include "0002-cs_nonce_locks.sql"
|
|
||||||
#include "0002-purse_requests.sql"
|
|
||||||
#include "0002-purse_merges.sql"
|
|
||||||
#include "0002-account_merges.sql"
|
|
||||||
#include "0002-purse_decision.sql"
|
|
||||||
#include "0002-contracts.sql"
|
|
||||||
#include "0002-history_requests.sql"
|
|
||||||
#include "0002-purse_deposits.sql"
|
|
||||||
#include "0002-wads_in.sql"
|
|
||||||
#include "0002-wad_in_entries.sql"
|
|
||||||
#include "0002-wads_out.sql"
|
|
||||||
#include "0002-wad_out_entries.sql"
|
|
||||||
#include "0002-work_shards.sql"
|
|
||||||
#include "0002-revolving_work_shards.sql"
|
|
||||||
#include "0002-partners.sql"
|
|
||||||
#include "0002-partner_accounts.sql"
|
|
||||||
#include "0002-purse_actions.sql"
|
|
||||||
#include "0002-purse_deletion.sql"
|
|
||||||
|
|
||||||
#include "0002-kyc_attributes.sql"
|
|
||||||
|
|
||||||
#include "0002-kycauths_in.sql"
|
|
||||||
#include "0002-kyc_events.sql"
|
|
||||||
#include "0002-aml_staff.sql"
|
|
||||||
#include "0002-aml_history.sql"
|
|
||||||
|
|
||||||
#include "0002-statistics.sql"
|
|
||||||
|
|
||||||
COMMIT;
|
|
||||||
|
|
@ -1,34 +0,0 @@
|
||||||
--
|
|
||||||
-- This file is part of TALER
|
|
||||||
-- Copyright (C) 2025 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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
BEGIN;
|
|
||||||
|
|
||||||
SELECT _v.register_patch('exchange-0003', NULL, NULL);
|
|
||||||
SET search_path TO exchange;
|
|
||||||
|
|
||||||
#include "0003-kyc_targets.sql"
|
|
||||||
#include "0003-legitimization_measures.sql"
|
|
||||||
#include "0003-legitimization_outcomes.sql"
|
|
||||||
#include "0003-legitimization_processes.sql"
|
|
||||||
-- Note that wire_targets MUST be after kyc_targets and
|
|
||||||
-- legitimization measures here,
|
|
||||||
-- as we first need to create kyc_targets and migrate the
|
|
||||||
-- data before dropping it in wire_targets!
|
|
||||||
#include "0003-wire_targets.sql"
|
|
||||||
-- This table was already dead in v1.0, drop it for real
|
|
||||||
#include "0003-reserves_out.sql"
|
|
||||||
|
|
||||||
COMMIT;
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
--
|
|
||||||
-- This file is part of TALER
|
|
||||||
-- Copyright (C) 2025 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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
BEGIN;
|
|
||||||
|
|
||||||
SELECT _v.register_patch('exchange-0004', NULL, NULL);
|
|
||||||
SET search_path TO exchange;
|
|
||||||
|
|
||||||
#include "0004-kyc_attributes.sql"
|
|
||||||
|
|
||||||
COMMIT;
|
|
||||||
|
|
@ -1,133 +0,0 @@
|
||||||
--
|
|
||||||
-- This file is part of TALER
|
|
||||||
-- Copyright (C) 2025 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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
BEGIN;
|
|
||||||
|
|
||||||
SELECT _v.register_patch('exchange-0005', NULL, NULL);
|
|
||||||
|
|
||||||
SET search_path TO exchange;
|
|
||||||
|
|
||||||
-- convert all JSON-valued fields from TEXT to JSONB
|
|
||||||
|
|
||||||
CREATE FUNCTION alter_table_wire_accounts5()
|
|
||||||
RETURNS void
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
BEGIN
|
|
||||||
ALTER TABLE wire_accounts
|
|
||||||
ALTER COLUMN debit_restrictions
|
|
||||||
TYPE JSONB
|
|
||||||
USING debit_restrictions::JSONB,
|
|
||||||
ALTER COLUMN credit_restrictions
|
|
||||||
TYPE JSONB
|
|
||||||
USING credit_restrictions::JSONB;
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION alter_table_legitimization_outcomes5()
|
|
||||||
RETURNS void
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
BEGIN
|
|
||||||
ALTER TABLE legitimization_outcomes
|
|
||||||
ALTER COLUMN jproperties
|
|
||||||
TYPE JSONB
|
|
||||||
USING jproperties::JSONB,
|
|
||||||
ALTER COLUMN jnew_rules
|
|
||||||
TYPE JSONB
|
|
||||||
USING jnew_rules::JSONB;
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION alter_table_legitimization_measures5()
|
|
||||||
RETURNS void
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
BEGIN
|
|
||||||
ALTER TABLE legitimization_measures
|
|
||||||
ALTER COLUMN jmeasures
|
|
||||||
TYPE JSONB
|
|
||||||
USING jmeasures::JSONB;
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION alter_table_policy_fulfillments5()
|
|
||||||
RETURNS void
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
BEGIN
|
|
||||||
ALTER TABLE policy_fulfillments
|
|
||||||
ALTER COLUMN fulfillment_proof
|
|
||||||
TYPE JSONB
|
|
||||||
USING fulfillment_proof::JSONB;
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE FUNCTION alter_table_kyc_targets5()
|
|
||||||
RETURNS void
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
table_name TEXT DEFAULT 'kyc_targets';
|
|
||||||
BEGIN
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'ALTER TABLE ' || table_name ||
|
|
||||||
' ADD COLUMN open_time INT8 DEFAULT(NULL)'
|
|
||||||
',ADD COLUMN close_time INT8 DEFAULT(NULL);'
|
|
||||||
);
|
|
||||||
END
|
|
||||||
$$;
|
|
||||||
|
|
||||||
|
|
||||||
INSERT INTO exchange_tables
|
|
||||||
(name
|
|
||||||
,version
|
|
||||||
,action
|
|
||||||
,partitioned
|
|
||||||
,by_range)
|
|
||||||
VALUES
|
|
||||||
('wire_accounts5'
|
|
||||||
,'exchange-0005'
|
|
||||||
,'alter'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('legitimization_outcomes5'
|
|
||||||
,'exchange-0005'
|
|
||||||
,'alter'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('legitimization_measures5'
|
|
||||||
,'exchange-0005'
|
|
||||||
,'alter'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('policy_fulfillments5'
|
|
||||||
,'exchange-0005'
|
|
||||||
,'alter'
|
|
||||||
,TRUE
|
|
||||||
,FALSE),
|
|
||||||
('kyc_targets5'
|
|
||||||
,'exchange-0005'
|
|
||||||
,'alter'
|
|
||||||
,TRUE
|
|
||||||
,FALSE);
|
|
||||||
|
|
||||||
|
|
||||||
COMMIT;
|
|
||||||
|
|
@ -1,15 +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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
@ -1,92 +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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
--------------------------------------------------------------
|
|
||||||
-- Taler amounts and helper functions
|
|
||||||
-------------------------------------------------------------
|
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION 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 FUNCTION 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 FUNCTION 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 FUNCTION 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.';
|
|
||||||
|
|
@ -1,469 +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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION exchange_do_batch4_known_coin(
|
|
||||||
IN in_coin_pub1 BYTEA,
|
|
||||||
IN in_denom_pub_hash1 BYTEA,
|
|
||||||
IN in_h_age_commitment1 BYTEA,
|
|
||||||
IN in_denom_sig1 BYTEA,
|
|
||||||
IN in_coin_pub2 BYTEA,
|
|
||||||
IN in_denom_pub_hash2 BYTEA,
|
|
||||||
IN in_h_age_commitment2 BYTEA,
|
|
||||||
IN in_denom_sig2 BYTEA,
|
|
||||||
IN in_coin_pub3 BYTEA,
|
|
||||||
IN in_denom_pub_hash3 BYTEA,
|
|
||||||
IN in_h_age_commitment3 BYTEA,
|
|
||||||
IN in_denom_sig3 BYTEA,
|
|
||||||
IN in_coin_pub4 BYTEA,
|
|
||||||
IN in_denom_pub_hash4 BYTEA,
|
|
||||||
IN in_h_age_commitment4 BYTEA,
|
|
||||||
IN in_denom_sig4 BYTEA,
|
|
||||||
OUT existed1 BOOLEAN,
|
|
||||||
OUT existed2 BOOLEAN,
|
|
||||||
OUT existed3 BOOLEAN,
|
|
||||||
OUT existed4 BOOLEAN,
|
|
||||||
OUT known_coin_id1 INT8,
|
|
||||||
OUT known_coin_id2 INT8,
|
|
||||||
OUT known_coin_id3 INT8,
|
|
||||||
OUT known_coin_id4 INT8,
|
|
||||||
OUT denom_pub_hash1 BYTEA,
|
|
||||||
OUT denom_pub_hash2 BYTEA,
|
|
||||||
OUT denom_pub_hash3 BYTEA,
|
|
||||||
OUT denom_pub_hash4 BYTEA,
|
|
||||||
OUT age_commitment_hash1 BYTEA,
|
|
||||||
OUT age_commitment_hash2 BYTEA,
|
|
||||||
OUT age_commitment_hash3 BYTEA,
|
|
||||||
OUT age_commitment_hash4 BYTEA)
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
BEGIN
|
|
||||||
WITH dd AS (
|
|
||||||
SELECT
|
|
||||||
denominations_serial,
|
|
||||||
coin
|
|
||||||
FROM denominations
|
|
||||||
WHERE denom_pub_hash
|
|
||||||
IN
|
|
||||||
(in_denom_pub_hash1,
|
|
||||||
in_denom_pub_hash2,
|
|
||||||
in_denom_pub_hash3,
|
|
||||||
in_denom_pub_hash4)
|
|
||||||
),--dd
|
|
||||||
input_rows AS (
|
|
||||||
VALUES
|
|
||||||
(in_coin_pub1,
|
|
||||||
in_denom_pub_hash1,
|
|
||||||
in_h_age_commitment1,
|
|
||||||
in_denom_sig1),
|
|
||||||
(in_coin_pub2,
|
|
||||||
in_denom_pub_hash2,
|
|
||||||
in_h_age_commitment2,
|
|
||||||
in_denom_sig2),
|
|
||||||
(in_coin_pub3,
|
|
||||||
in_denom_pub_hash3,
|
|
||||||
in_h_age_commitment3,
|
|
||||||
in_denom_sig3),
|
|
||||||
(in_coin_pub4,
|
|
||||||
in_denom_pub_hash4,
|
|
||||||
in_h_age_commitment4,
|
|
||||||
in_denom_sig4)
|
|
||||||
),--ir
|
|
||||||
ins AS (
|
|
||||||
INSERT INTO known_coins (
|
|
||||||
coin_pub,
|
|
||||||
denominations_serial,
|
|
||||||
age_commitment_hash,
|
|
||||||
denom_sig,
|
|
||||||
remaining
|
|
||||||
)
|
|
||||||
SELECT
|
|
||||||
ir.coin_pub,
|
|
||||||
dd.denominations_serial,
|
|
||||||
ir.age_commitment_hash,
|
|
||||||
ir.denom_sig,
|
|
||||||
dd.coin
|
|
||||||
FROM input_rows ir
|
|
||||||
JOIN dd
|
|
||||||
ON dd.denom_pub_hash = ir.denom_pub_hash
|
|
||||||
ON CONFLICT DO NOTHING
|
|
||||||
RETURNING known_coin_id
|
|
||||||
),--kc
|
|
||||||
exists AS (
|
|
||||||
SELECT
|
|
||||||
CASE
|
|
||||||
WHEN
|
|
||||||
ins.known_coin_id IS NOT NULL
|
|
||||||
THEN
|
|
||||||
FALSE
|
|
||||||
ELSE
|
|
||||||
TRUE
|
|
||||||
END AS existed,
|
|
||||||
ins.known_coin_id,
|
|
||||||
dd.denom_pub_hash,
|
|
||||||
kc.age_commitment_hash
|
|
||||||
FROM input_rows ir
|
|
||||||
LEFT JOIN ins
|
|
||||||
ON ins.coin_pub = ir.coin_pub
|
|
||||||
LEFT JOIN known_coins kc
|
|
||||||
ON kc.coin_pub = ir.coin_pub
|
|
||||||
LEFT JOIN dd
|
|
||||||
ON dd.denom_pub_hash = ir.denom_pub_hash
|
|
||||||
)--exists
|
|
||||||
SELECT
|
|
||||||
exists.existed AS existed1,
|
|
||||||
exists.known_coin_id AS known_coin_id1,
|
|
||||||
exists.denom_pub_hash AS denom_pub_hash1,
|
|
||||||
exists.age_commitment_hash AS age_commitment_hash1,
|
|
||||||
(
|
|
||||||
SELECT exists.existed
|
|
||||||
FROM exists
|
|
||||||
WHERE exists.denom_pub_hash = in_denom_pub_hash2
|
|
||||||
) AS existed2,
|
|
||||||
(
|
|
||||||
SELECT exists.known_coin_id
|
|
||||||
FROM exists
|
|
||||||
WHERE exists.denom_pub_hash = in_denom_pub_hash2
|
|
||||||
) AS known_coin_id2,
|
|
||||||
(
|
|
||||||
SELECT exists.denom_pub_hash
|
|
||||||
FROM exists
|
|
||||||
WHERE exists.denom_pub_hash = in_denom_pub_hash2
|
|
||||||
) AS denom_pub_hash2,
|
|
||||||
(
|
|
||||||
SELECT exists.age_commitment_hash
|
|
||||||
FROM exists
|
|
||||||
WHERE exists.denom_pub_hash = in_denom_pub_hash2
|
|
||||||
)AS age_commitment_hash2,
|
|
||||||
(
|
|
||||||
SELECT exists.existed
|
|
||||||
FROM exists
|
|
||||||
WHERE exists.denom_pub_hash = in_denom_pub_hash3
|
|
||||||
) AS existed3,
|
|
||||||
(
|
|
||||||
SELECT exists.known_coin_id
|
|
||||||
FROM exists
|
|
||||||
WHERE exists.denom_pub_hash = in_denom_pub_hash3
|
|
||||||
) AS known_coin_id3,
|
|
||||||
(
|
|
||||||
SELECT exists.denom_pub_hash
|
|
||||||
FROM exists
|
|
||||||
WHERE exists.denom_pub_hash = in_denom_pub_hash3
|
|
||||||
) AS denom_pub_hash3,
|
|
||||||
(
|
|
||||||
SELECT exists.age_commitment_hash
|
|
||||||
FROM exists
|
|
||||||
WHERE exists.denom_pub_hash = in_denom_pub_hash3
|
|
||||||
)AS age_commitment_hash3,
|
|
||||||
(
|
|
||||||
SELECT exists.existed
|
|
||||||
FROM exists
|
|
||||||
WHERE exists.denom_pub_hash = in_denom_pub_hash4
|
|
||||||
) AS existed4,
|
|
||||||
(
|
|
||||||
SELECT exists.known_coin_id
|
|
||||||
FROM exists
|
|
||||||
WHERE exists.denom_pub_hash = in_denom_pub_hash4
|
|
||||||
) AS known_coin_id4,
|
|
||||||
(
|
|
||||||
SELECT exists.denom_pub_hash
|
|
||||||
FROM exists
|
|
||||||
WHERE exists.denom_pub_hash = in_denom_pub_hash4
|
|
||||||
) AS denom_pub_hash4,
|
|
||||||
(
|
|
||||||
SELECT exists.age_commitment_hash
|
|
||||||
FROM exists
|
|
||||||
WHERE exists.denom_pub_hash = in_denom_pub_hash4
|
|
||||||
)AS age_commitment_hash4
|
|
||||||
FROM exists;
|
|
||||||
|
|
||||||
RETURN;
|
|
||||||
END $$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION exchange_do_batch2_known_coin(
|
|
||||||
IN in_coin_pub1 BYTEA,
|
|
||||||
IN in_denom_pub_hash1 BYTEA,
|
|
||||||
IN in_h_age_commitment1 BYTEA,
|
|
||||||
IN in_denom_sig1 BYTEA,
|
|
||||||
IN in_coin_pub2 BYTEA,
|
|
||||||
IN in_denom_pub_hash2 BYTEA,
|
|
||||||
IN in_h_age_commitment2 BYTEA,
|
|
||||||
IN in_denom_sig2 BYTEA,
|
|
||||||
OUT existed1 BOOLEAN,
|
|
||||||
OUT existed2 BOOLEAN,
|
|
||||||
OUT known_coin_id1 INT8,
|
|
||||||
OUT known_coin_id2 INT8,
|
|
||||||
OUT denom_pub_hash1 BYTEA,
|
|
||||||
OUT denom_pub_hash2 BYTEA,
|
|
||||||
OUT age_commitment_hash1 BYTEA,
|
|
||||||
OUT age_commitment_hash2 BYTEA)
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
BEGIN
|
|
||||||
WITH dd AS (
|
|
||||||
SELECT
|
|
||||||
denominations_serial,
|
|
||||||
coin
|
|
||||||
FROM denominations
|
|
||||||
WHERE denom_pub_hash
|
|
||||||
IN
|
|
||||||
(in_denom_pub_hash1,
|
|
||||||
in_denom_pub_hash2)
|
|
||||||
),--dd
|
|
||||||
input_rows AS (
|
|
||||||
VALUES
|
|
||||||
(in_coin_pub1,
|
|
||||||
in_denom_pub_hash1,
|
|
||||||
in_h_age_commitment1,
|
|
||||||
in_denom_sig1),
|
|
||||||
(in_coin_pub2,
|
|
||||||
in_denom_pub_hash2,
|
|
||||||
in_h_age_commitment2,
|
|
||||||
in_denom_sig2)
|
|
||||||
),--ir
|
|
||||||
ins AS (
|
|
||||||
INSERT INTO known_coins (
|
|
||||||
coin_pub,
|
|
||||||
denominations_serial,
|
|
||||||
age_commitment_hash,
|
|
||||||
denom_sig,
|
|
||||||
remaining
|
|
||||||
)
|
|
||||||
SELECT
|
|
||||||
ir.coin_pub,
|
|
||||||
dd.denominations_serial,
|
|
||||||
ir.age_commitment_hash,
|
|
||||||
ir.denom_sig,
|
|
||||||
dd.coin
|
|
||||||
FROM input_rows ir
|
|
||||||
JOIN dd
|
|
||||||
ON dd.denom_pub_hash = ir.denom_pub_hash
|
|
||||||
ON CONFLICT DO NOTHING
|
|
||||||
RETURNING known_coin_id
|
|
||||||
),--kc
|
|
||||||
exists AS (
|
|
||||||
SELECT
|
|
||||||
CASE
|
|
||||||
WHEN ins.known_coin_id IS NOT NULL
|
|
||||||
THEN
|
|
||||||
FALSE
|
|
||||||
ELSE
|
|
||||||
TRUE
|
|
||||||
END AS existed,
|
|
||||||
ins.known_coin_id,
|
|
||||||
dd.denom_pub_hash,
|
|
||||||
kc.age_commitment_hash
|
|
||||||
FROM input_rows ir
|
|
||||||
LEFT JOIN ins
|
|
||||||
ON ins.coin_pub = ir.coin_pub
|
|
||||||
LEFT JOIN known_coins kc
|
|
||||||
ON kc.coin_pub = ir.coin_pub
|
|
||||||
LEFT JOIN dd
|
|
||||||
ON dd.denom_pub_hash = ir.denom_pub_hash
|
|
||||||
)--exists
|
|
||||||
SELECT
|
|
||||||
exists.existed AS existed1,
|
|
||||||
exists.known_coin_id AS known_coin_id1,
|
|
||||||
exists.denom_pub_hash AS denom_pub_hash1,
|
|
||||||
exists.age_commitment_hash AS age_commitment_hash1,
|
|
||||||
(
|
|
||||||
SELECT exists.existed
|
|
||||||
FROM exists
|
|
||||||
WHERE exists.denom_pub_hash = in_denom_pub_hash2
|
|
||||||
) AS existed2,
|
|
||||||
(
|
|
||||||
SELECT exists.known_coin_id
|
|
||||||
FROM exists
|
|
||||||
WHERE exists.denom_pub_hash = in_denom_pub_hash2
|
|
||||||
) AS known_coin_id2,
|
|
||||||
(
|
|
||||||
SELECT exists.denom_pub_hash
|
|
||||||
FROM exists
|
|
||||||
WHERE exists.denom_pub_hash = in_denom_pub_hash2
|
|
||||||
) AS denom_pub_hash2,
|
|
||||||
(
|
|
||||||
SELECT exists.age_commitment_hash
|
|
||||||
FROM exists
|
|
||||||
WHERE exists.denom_pub_hash = in_denom_pub_hash2
|
|
||||||
)AS age_commitment_hash2
|
|
||||||
FROM exists;
|
|
||||||
|
|
||||||
RETURN;
|
|
||||||
END $$;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION exchange_do_batch1_known_coin(
|
|
||||||
IN in_coin_pub1 BYTEA,
|
|
||||||
IN in_denom_pub_hash1 BYTEA,
|
|
||||||
IN in_h_age_commitment1 BYTEA,
|
|
||||||
IN in_denom_sig1 BYTEA,
|
|
||||||
OUT existed1 BOOLEAN,
|
|
||||||
OUT known_coin_id1 INT8,
|
|
||||||
OUT denom_pub_hash1 BYTEA,
|
|
||||||
OUT age_commitment_hash1 BYTEA)
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
BEGIN
|
|
||||||
WITH dd AS (
|
|
||||||
SELECT
|
|
||||||
denominations_serial,
|
|
||||||
coin
|
|
||||||
FROM denominations
|
|
||||||
WHERE denom_pub_hash
|
|
||||||
IN
|
|
||||||
(in_denom_pub_hash1,
|
|
||||||
in_denom_pub_hash2)
|
|
||||||
),--dd
|
|
||||||
input_rows AS (
|
|
||||||
VALUES
|
|
||||||
(in_coin_pub1,
|
|
||||||
in_denom_pub_hash1,
|
|
||||||
in_h_age_commitment1,
|
|
||||||
in_denom_sig1)
|
|
||||||
),--ir
|
|
||||||
ins AS (
|
|
||||||
INSERT INTO known_coins (
|
|
||||||
coin_pub,
|
|
||||||
denominations_serial,
|
|
||||||
age_commitment_hash,
|
|
||||||
denom_sig,
|
|
||||||
remaining
|
|
||||||
)
|
|
||||||
SELECT
|
|
||||||
ir.coin_pub,
|
|
||||||
dd.denominations_serial,
|
|
||||||
ir.age_commitment_hash,
|
|
||||||
ir.denom_sig,
|
|
||||||
dd.coin
|
|
||||||
FROM input_rows ir
|
|
||||||
JOIN dd
|
|
||||||
ON dd.denom_pub_hash = ir.denom_pub_hash
|
|
||||||
ON CONFLICT DO NOTHING
|
|
||||||
RETURNING known_coin_id
|
|
||||||
),--kc
|
|
||||||
exists AS (
|
|
||||||
SELECT
|
|
||||||
CASE
|
|
||||||
WHEN ins.known_coin_id IS NOT NULL
|
|
||||||
THEN
|
|
||||||
FALSE
|
|
||||||
ELSE
|
|
||||||
TRUE
|
|
||||||
END AS existed,
|
|
||||||
ins.known_coin_id,
|
|
||||||
dd.denom_pub_hash,
|
|
||||||
kc.age_commitment_hash
|
|
||||||
FROM input_rows ir
|
|
||||||
LEFT JOIN ins
|
|
||||||
ON ins.coin_pub = ir.coin_pub
|
|
||||||
LEFT JOIN known_coins kc
|
|
||||||
ON kc.coin_pub = ir.coin_pub
|
|
||||||
LEFT JOIN dd
|
|
||||||
ON dd.denom_pub_hash = ir.denom_pub_hash
|
|
||||||
)--exists
|
|
||||||
SELECT
|
|
||||||
exists.existed AS existed1,
|
|
||||||
exists.known_coin_id AS known_coin_id1,
|
|
||||||
exists.denom_pub_hash AS denom_pub_hash1,
|
|
||||||
exists.age_commitment_hash AS age_commitment_hash1
|
|
||||||
FROM exists;
|
|
||||||
|
|
||||||
RETURN;
|
|
||||||
END $$;
|
|
||||||
|
|
||||||
/*** Experiment using a loop ***/
|
|
||||||
/*
|
|
||||||
CREATE OR REPLACE FUNCTION exchange_do_batch2_known_coin(
|
|
||||||
IN in_coin_pub1 BYTEA,
|
|
||||||
IN in_denom_pub_hash1 TEXT,
|
|
||||||
IN in_h_age_commitment1 TEXT,
|
|
||||||
IN in_denom_sig1 TEXT,
|
|
||||||
IN in_coin_pub2 BYTEA,
|
|
||||||
IN in_denom_pub_hash2 TEXT,
|
|
||||||
IN in_h_age_commitment2 TEXT,
|
|
||||||
IN in_denom_sig2 TEXT,
|
|
||||||
OUT existed1 BOOLEAN,
|
|
||||||
OUT existed2 BOOLEAN,
|
|
||||||
OUT known_coin_id1 INT8,
|
|
||||||
OUT known_coin_id2 INT8,
|
|
||||||
OUT denom_pub_hash1 TEXT,
|
|
||||||
OUT denom_pub_hash2 TEXT,
|
|
||||||
OUT age_commitment_hash1 TEXT,
|
|
||||||
OUT age_commitment_hash2 TEXT)
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
ins_values RECORD;
|
|
||||||
BEGIN
|
|
||||||
FOR i IN 1..2 LOOP
|
|
||||||
ins_values := (
|
|
||||||
SELECT
|
|
||||||
in_coin_pub1 AS coin_pub,
|
|
||||||
in_denom_pub_hash1 AS denom_pub_hash,
|
|
||||||
in_h_age_commitment1 AS age_commitment_hash,
|
|
||||||
in_denom_sig1 AS denom_sig
|
|
||||||
WHERE i = 1
|
|
||||||
UNION
|
|
||||||
SELECT
|
|
||||||
in_coin_pub2 AS coin_pub,
|
|
||||||
in_denom_pub_hash2 AS denom_pub_hash,
|
|
||||||
in_h_age_commitment2 AS age_commitment_hash,
|
|
||||||
in_denom_sig2 AS denom_sig
|
|
||||||
WHERE i = 2
|
|
||||||
);
|
|
||||||
WITH dd (denominations_serial, coin) AS (
|
|
||||||
SELECT denominations_serial, coin
|
|
||||||
FROM denominations
|
|
||||||
WHERE denom_pub_hash = ins_values.denom_pub_hash
|
|
||||||
),
|
|
||||||
input_rows(coin_pub) AS (
|
|
||||||
VALUES (ins_values.coin_pub)
|
|
||||||
),
|
|
||||||
ins AS (
|
|
||||||
INSERT INTO known_coins (
|
|
||||||
coin_pub,
|
|
||||||
denominations_serial,
|
|
||||||
age_commitment_hash,
|
|
||||||
denom_sig,
|
|
||||||
remaining
|
|
||||||
) SELECT
|
|
||||||
input_rows.coin_pub,
|
|
||||||
dd.denominations_serial,
|
|
||||||
ins_values.age_commitment_hash,
|
|
||||||
ins_values.denom_sig,
|
|
||||||
coin
|
|
||||||
FROM dd
|
|
||||||
CROSS JOIN input_rows
|
|
||||||
ON CONFLICT DO NOTHING
|
|
||||||
RETURNING known_coin_id, denom_pub_hash
|
|
||||||
)
|
|
||||||
SELECT
|
|
||||||
CASE i
|
|
||||||
WHEN 1 THEN
|
|
||||||
COALESCE(ins.known_coin_id, 0) <> 0 AS existed1,
|
|
||||||
ins.known_coin_id AS known_coin_id1,
|
|
||||||
ins.denom_pub_hash AS denom_pub_hash1,
|
|
||||||
ins.age_commitment_hash AS age_commitment_hash1
|
|
||||||
WHEN 2 THEN
|
|
||||||
COALESCE(ins.known_coin_id, 0) <> 0 AS existed2,
|
|
||||||
ins.known_coin_id AS known_coin_id2,
|
|
||||||
ins.denom_pub_hash AS denom_pub_hash2,
|
|
||||||
ins.age_commitment_hash AS age_commitment_hash2
|
|
||||||
END
|
|
||||||
FROM ins;
|
|
||||||
END LOOP;
|
|
||||||
END;
|
|
||||||
$$;*/
|
|
||||||
|
|
@ -1,72 +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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION exchange_do_batch_reserves_update(
|
|
||||||
IN in_reserve_pub BYTEA,
|
|
||||||
IN in_expiration_date INT8,
|
|
||||||
IN in_wire_ref INT8,
|
|
||||||
IN in_credit taler_amount,
|
|
||||||
IN in_exchange_account_name TEXT,
|
|
||||||
IN in_wire_source_h_payto BYTEA,
|
|
||||||
IN in_notify text,
|
|
||||||
OUT out_duplicate BOOLEAN)
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
BEGIN
|
|
||||||
INSERT INTO reserves_in
|
|
||||||
(reserve_pub
|
|
||||||
,wire_reference
|
|
||||||
,credit
|
|
||||||
,exchange_account_section
|
|
||||||
,wire_source_h_payto
|
|
||||||
,execution_date)
|
|
||||||
VALUES
|
|
||||||
(in_reserve_pub
|
|
||||||
,in_wire_ref
|
|
||||||
,in_credit
|
|
||||||
,in_exchange_account_name
|
|
||||||
,in_wire_source_h_payto
|
|
||||||
,in_expiration_date)
|
|
||||||
ON CONFLICT DO NOTHING;
|
|
||||||
IF FOUND
|
|
||||||
THEN
|
|
||||||
--IF THE INSERTION WAS A SUCCESS IT MEANS NO DUPLICATED TRANSACTION
|
|
||||||
out_duplicate = FALSE;
|
|
||||||
UPDATE reserves rs
|
|
||||||
SET
|
|
||||||
current_balance.frac = (rs.current_balance).frac+in_credit.frac
|
|
||||||
- CASE
|
|
||||||
WHEN (rs.current_balance).frac + in_credit.frac >= 100000000
|
|
||||||
THEN 100000000
|
|
||||||
ELSE 1
|
|
||||||
END
|
|
||||||
,current_balance.val = (rs.current_balance).val+in_credit.val
|
|
||||||
+ CASE
|
|
||||||
WHEN (rs.current_balance).frac + in_credit.frac >= 100000000
|
|
||||||
THEN 1
|
|
||||||
ELSE 0
|
|
||||||
END
|
|
||||||
,expiration_date=GREATEST(expiration_date,in_expiration_date)
|
|
||||||
,gc_date=GREATEST(gc_date,in_expiration_date)
|
|
||||||
WHERE reserve_pub=in_reserve_pub;
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'NOTIFY %s'
|
|
||||||
,in_notify);
|
|
||||||
ELSE
|
|
||||||
out_duplicate = TRUE;
|
|
||||||
END IF;
|
|
||||||
RETURN;
|
|
||||||
END $$;
|
|
||||||
|
|
@ -1,122 +0,0 @@
|
||||||
--
|
|
||||||
-- This file is part of TALER
|
|
||||||
-- Copyright (C) 2024 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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
DROP FUNCTION IF EXISTS exchange_do_check_deposit_idempotent;
|
|
||||||
CREATE FUNCTION exchange_do_check_deposit_idempotent(
|
|
||||||
-- For batch_deposits
|
|
||||||
IN in_shard INT8,
|
|
||||||
IN in_merchant_pub BYTEA,
|
|
||||||
IN in_wallet_timestamp INT8,
|
|
||||||
IN in_exchange_timestamp INT8,
|
|
||||||
IN in_refund_deadline INT8,
|
|
||||||
IN in_wire_deadline INT8,
|
|
||||||
IN in_h_contract_terms BYTEA,
|
|
||||||
IN in_wallet_data_hash BYTEA, -- can be NULL
|
|
||||||
IN in_wire_salt BYTEA,
|
|
||||||
IN in_wire_target_h_payto BYTEA,
|
|
||||||
IN in_policy_details_serial_id INT8, -- can be NULL
|
|
||||||
IN in_policy_blocked BOOLEAN,
|
|
||||||
-- For coin_deposits
|
|
||||||
IN ina_coin_pub BYTEA[],
|
|
||||||
IN ina_coin_sig BYTEA[],
|
|
||||||
IN ina_amount_with_fee taler_amount[],
|
|
||||||
OUT out_exchange_timestamp INT8,
|
|
||||||
OUT out_is_idempotent BOOL
|
|
||||||
)
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
wtsi INT8; -- wire target serial id
|
|
||||||
bdsi INT8; -- batch_deposits serial id
|
|
||||||
i INT4;
|
|
||||||
ini_amount_with_fee taler_amount;
|
|
||||||
ini_coin_pub BYTEA;
|
|
||||||
ini_coin_sig BYTEA;
|
|
||||||
BEGIN
|
|
||||||
-- Shards:
|
|
||||||
-- SELECT wire_targets (by h_payto);
|
|
||||||
-- INSERT batch_deposits (by shard, merchant_pub), ON CONFLICT idempotency check;
|
|
||||||
-- PERFORM[] coin_deposits (by coin_pub), ON CONFLICT idempotency check;
|
|
||||||
|
|
||||||
out_exchange_timestamp = in_exchange_timestamp;
|
|
||||||
|
|
||||||
-- First, get the 'wtsi'
|
|
||||||
SELECT wire_target_serial_id
|
|
||||||
INTO wtsi
|
|
||||||
FROM wire_targets
|
|
||||||
WHERE wire_target_h_payto=in_wire_target_h_payto;
|
|
||||||
|
|
||||||
IF NOT FOUND
|
|
||||||
THEN
|
|
||||||
out_is_idempotent = FALSE;
|
|
||||||
RETURN;
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
|
|
||||||
-- Idempotency check: see if an identical record exists.
|
|
||||||
-- We do select over merchant_pub, h_contract_terms and wire_target_h_payto
|
|
||||||
-- first to maximally increase the chance of using the existing index.
|
|
||||||
SELECT
|
|
||||||
exchange_timestamp
|
|
||||||
,batch_deposit_serial_id
|
|
||||||
INTO
|
|
||||||
out_exchange_timestamp
|
|
||||||
,bdsi
|
|
||||||
FROM batch_deposits
|
|
||||||
WHERE shard=in_shard
|
|
||||||
AND merchant_pub=in_merchant_pub
|
|
||||||
AND h_contract_terms=in_h_contract_terms
|
|
||||||
AND wire_target_h_payto=in_wire_target_h_payto
|
|
||||||
-- now check the rest, too
|
|
||||||
AND ( (wallet_data_hash=in_wallet_data_hash) OR
|
|
||||||
(wallet_data_hash IS NULL AND in_wallet_data_hash IS NULL) )
|
|
||||||
AND wire_salt=in_wire_salt
|
|
||||||
AND wallet_timestamp=in_wallet_timestamp
|
|
||||||
AND refund_deadline=in_refund_deadline
|
|
||||||
AND wire_deadline=in_wire_deadline
|
|
||||||
AND ( (policy_details_serial_id=in_policy_details_serial_id) OR
|
|
||||||
(policy_details_serial_id IS NULL AND in_policy_details_serial_id IS NULL) );
|
|
||||||
|
|
||||||
IF NOT FOUND
|
|
||||||
THEN
|
|
||||||
out_is_idempotent=FALSE;
|
|
||||||
RETURN;
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
|
|
||||||
-- Check each coin
|
|
||||||
|
|
||||||
FOR i IN 1..array_length(ina_coin_pub,1)
|
|
||||||
LOOP
|
|
||||||
ini_coin_pub = ina_coin_pub[i];
|
|
||||||
ini_coin_sig = ina_coin_sig[i];
|
|
||||||
ini_amount_with_fee = ina_amount_with_fee[i];
|
|
||||||
|
|
||||||
PERFORM FROM coin_deposits
|
|
||||||
WHERE batch_deposit_serial_id=bdsi
|
|
||||||
AND coin_pub=ini_coin_pub
|
|
||||||
AND coin_sig=ini_coin_sig
|
|
||||||
AND amount_with_fee=ini_amount_with_fee;
|
|
||||||
IF NOT FOUND
|
|
||||||
THEN
|
|
||||||
out_is_idempotent=FALSE;
|
|
||||||
RETURN;
|
|
||||||
END IF;
|
|
||||||
END LOOP; -- end FOR all coins
|
|
||||||
|
|
||||||
out_is_idempotent=TRUE;
|
|
||||||
|
|
||||||
END $$;
|
|
||||||
|
|
@ -1,42 +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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION comment_partitioned_column(
|
|
||||||
IN table_comment TEXT
|
|
||||||
,IN column_name TEXT
|
|
||||||
,IN table_name TEXT
|
|
||||||
,IN partition_suffix TEXT DEFAULT NULL
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
BEGIN
|
|
||||||
IF ( (partition_suffix IS NOT NULL) AND
|
|
||||||
(partition_suffix::int > 0) )
|
|
||||||
THEN
|
|
||||||
-- sharding, add shard name
|
|
||||||
table_name=table_name || '_' || partition_suffix;
|
|
||||||
END IF;
|
|
||||||
EXECUTE FORMAT(
|
|
||||||
'COMMENT ON COLUMN %s.%s IS %s'
|
|
||||||
,table_name
|
|
||||||
,column_name
|
|
||||||
,quote_literal(table_comment)
|
|
||||||
);
|
|
||||||
END $$;
|
|
||||||
|
|
||||||
COMMENT ON FUNCTION comment_partitioned_column
|
|
||||||
IS 'Generic function to create a comment on column of a table that is partitioned.';
|
|
||||||
|
|
@ -1,40 +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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION comment_partitioned_table(
|
|
||||||
IN table_comment TEXT
|
|
||||||
,IN table_name TEXT
|
|
||||||
,IN partition_suffix TEXT DEFAULT NULL
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
BEGIN
|
|
||||||
IF ( (partition_suffix IS NOT NULL) AND
|
|
||||||
(partition_suffix::int > 0) )
|
|
||||||
THEN
|
|
||||||
-- sharding, add shard name
|
|
||||||
table_name=table_name || '_' || partition_suffix;
|
|
||||||
END IF;
|
|
||||||
EXECUTE FORMAT(
|
|
||||||
'COMMENT ON TABLE %s IS %s'
|
|
||||||
,table_name
|
|
||||||
,quote_literal(table_comment)
|
|
||||||
);
|
|
||||||
END $$;
|
|
||||||
|
|
||||||
COMMENT ON FUNCTION comment_partitioned_table
|
|
||||||
IS 'Generic function to create a comment on table that is partitioned.';
|
|
||||||
|
|
@ -1,47 +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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION create_partitioned_table(
|
|
||||||
IN table_definition TEXT -- SQL template for table creation
|
|
||||||
,IN table_name TEXT -- base name of the table
|
|
||||||
,IN main_table_partition_str TEXT -- declaration for how to partition the table
|
|
||||||
,IN partition_suffix TEXT DEFAULT NULL -- NULL: no partitioning, 0: yes partitioning, no sharding, >0: sharding
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
BEGIN
|
|
||||||
IF (partition_suffix IS NULL)
|
|
||||||
THEN
|
|
||||||
-- no partitioning, disable option
|
|
||||||
main_table_partition_str = '';
|
|
||||||
ELSE
|
|
||||||
IF (partition_suffix::int > 0)
|
|
||||||
THEN
|
|
||||||
-- sharding, add shard name
|
|
||||||
table_name=table_name || '_' || partition_suffix;
|
|
||||||
END IF;
|
|
||||||
END IF;
|
|
||||||
EXECUTE FORMAT(
|
|
||||||
table_definition,
|
|
||||||
table_name,
|
|
||||||
main_table_partition_str
|
|
||||||
);
|
|
||||||
END $$;
|
|
||||||
|
|
||||||
COMMENT ON FUNCTION create_partitioned_table
|
|
||||||
IS 'Generic function to create a table that is partitioned or sharded.';
|
|
||||||
|
|
@ -1,193 +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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
---------------------------------------------------------------------------
|
|
||||||
-- Main DB setup loop
|
|
||||||
---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION exchange_do_create_tables(
|
|
||||||
num_partitions INTEGER
|
|
||||||
-- NULL: no partitions, add foreign constraints
|
|
||||||
-- 0: no partitions, no foreign constraints
|
|
||||||
-- 1: only 1 default partition
|
|
||||||
-- > 1: normal partitions
|
|
||||||
)
|
|
||||||
RETURNS VOID
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
tc CURSOR FOR
|
|
||||||
SELECT table_serial_id
|
|
||||||
,name
|
|
||||||
,action
|
|
||||||
,partitioned
|
|
||||||
,by_range
|
|
||||||
FROM exchange.exchange_tables
|
|
||||||
WHERE NOT finished
|
|
||||||
ORDER BY table_serial_id ASC;
|
|
||||||
BEGIN
|
|
||||||
FOR rec IN tc
|
|
||||||
LOOP
|
|
||||||
CASE rec.action
|
|
||||||
-- "create" actions apply to master and partitions, providing the partition ID to the creation function (if any)
|
|
||||||
WHEN 'create'
|
|
||||||
THEN
|
|
||||||
IF (rec.partitioned AND
|
|
||||||
(num_partitions IS NOT NULL))
|
|
||||||
THEN
|
|
||||||
-- Create master table with partitioning.
|
|
||||||
EXECUTE FORMAT(
|
|
||||||
'SELECT exchange.create_table_%s (%s)'::text
|
|
||||||
,rec.name
|
|
||||||
,quote_literal('0')
|
|
||||||
);
|
|
||||||
IF (rec.by_range OR
|
|
||||||
(num_partitions = 0))
|
|
||||||
THEN
|
|
||||||
-- Create default partition.
|
|
||||||
IF (rec.by_range)
|
|
||||||
THEN
|
|
||||||
-- Range partition
|
|
||||||
EXECUTE FORMAT(
|
|
||||||
'CREATE TABLE exchange.%s_default'
|
|
||||||
' PARTITION OF %s'
|
|
||||||
' DEFAULT'
|
|
||||||
,rec.name
|
|
||||||
,rec.name
|
|
||||||
);
|
|
||||||
ELSE
|
|
||||||
-- Hash partition
|
|
||||||
EXECUTE FORMAT(
|
|
||||||
'CREATE TABLE exchange.%s_default'
|
|
||||||
' PARTITION OF %s'
|
|
||||||
' FOR VALUES WITH (MODULUS 1, REMAINDER 0)'
|
|
||||||
,rec.name
|
|
||||||
,rec.name
|
|
||||||
);
|
|
||||||
END IF;
|
|
||||||
ELSE
|
|
||||||
FOR i IN 1..num_partitions LOOP
|
|
||||||
-- Create num_partitions
|
|
||||||
EXECUTE FORMAT(
|
|
||||||
'CREATE TABLE exchange.%I'
|
|
||||||
' PARTITION OF %I'
|
|
||||||
' FOR VALUES WITH (MODULUS %s, REMAINDER %s)'
|
|
||||||
,rec.name || '_' || i
|
|
||||||
,rec.name
|
|
||||||
,num_partitions
|
|
||||||
,i-1
|
|
||||||
);
|
|
||||||
END LOOP;
|
|
||||||
END IF;
|
|
||||||
ELSE
|
|
||||||
-- Only create master table. No partitions.
|
|
||||||
EXECUTE FORMAT(
|
|
||||||
'SELECT exchange.create_table_%s ()'::text
|
|
||||||
,rec.name
|
|
||||||
);
|
|
||||||
END IF;
|
|
||||||
EXECUTE FORMAT(
|
|
||||||
'DROP FUNCTION exchange.create_table_%s'::text
|
|
||||||
,rec.name
|
|
||||||
);
|
|
||||||
-- "alter" actions apply to master and partitions (but are called without partition ID, as altering master applies to partitions for these); use when changing table layouts (adding or removing columns).
|
|
||||||
WHEN 'alter'
|
|
||||||
THEN
|
|
||||||
-- Alter master table.
|
|
||||||
EXECUTE FORMAT(
|
|
||||||
'SELECT exchange.alter_table_%s ()'::text
|
|
||||||
,rec.name
|
|
||||||
);
|
|
||||||
EXECUTE FORMAT(
|
|
||||||
'DROP FUNCTION exchange.alter_table_%s'::text
|
|
||||||
,rec.name
|
|
||||||
);
|
|
||||||
-- Constrain action apply to master OR each partition (but not on master if we have partitions); use to create (or remove) indices or constraints that apply to a partition and may not be aligned with the partition key
|
|
||||||
WHEN 'constrain'
|
|
||||||
THEN
|
|
||||||
ASSERT rec.partitioned, 'constrain action only applies to partitioned tables';
|
|
||||||
IF (num_partitions IS NULL)
|
|
||||||
THEN
|
|
||||||
-- Constrain master table
|
|
||||||
EXECUTE FORMAT(
|
|
||||||
'SELECT exchange.constrain_table_%s (NULL)'::text
|
|
||||||
,rec.name
|
|
||||||
);
|
|
||||||
ELSE
|
|
||||||
IF ( (num_partitions = 0) OR
|
|
||||||
(rec.by_range) )
|
|
||||||
THEN
|
|
||||||
-- Constrain default table
|
|
||||||
EXECUTE FORMAT(
|
|
||||||
'SELECT exchange.constrain_table_%s (%s)'::text
|
|
||||||
,rec.name
|
|
||||||
,quote_literal('default')
|
|
||||||
);
|
|
||||||
ELSE
|
|
||||||
-- Constrain each partition
|
|
||||||
FOR i IN 1..num_partitions LOOP
|
|
||||||
EXECUTE FORMAT(
|
|
||||||
'SELECT exchange.constrain_table_%s (%s)'::text
|
|
||||||
,rec.name
|
|
||||||
,quote_literal(i)
|
|
||||||
);
|
|
||||||
END LOOP;
|
|
||||||
END IF;
|
|
||||||
END IF;
|
|
||||||
EXECUTE FORMAT(
|
|
||||||
'DROP FUNCTION exchange.constrain_table_%s'::text
|
|
||||||
,rec.name
|
|
||||||
);
|
|
||||||
-- Foreign actions only apply if partitioning is off; use for foreign-key constraints that may span partitions
|
|
||||||
WHEN 'foreign'
|
|
||||||
THEN
|
|
||||||
IF (num_partitions IS NULL)
|
|
||||||
THEN
|
|
||||||
-- Add foreign constraints
|
|
||||||
EXECUTE FORMAT(
|
|
||||||
'SELECT exchange.foreign_table_%s (%s)'::text
|
|
||||||
,rec.name
|
|
||||||
,NULL
|
|
||||||
);
|
|
||||||
END IF;
|
|
||||||
EXECUTE FORMAT(
|
|
||||||
'DROP FUNCTION exchange.foreign_table_%s'::text
|
|
||||||
,rec.name
|
|
||||||
);
|
|
||||||
-- "master" actions only apply to the master table
|
|
||||||
WHEN 'master'
|
|
||||||
THEN
|
|
||||||
EXECUTE FORMAT(
|
|
||||||
'SELECT exchange.master_table_%s ()'::text
|
|
||||||
,rec.name
|
|
||||||
);
|
|
||||||
EXECUTE FORMAT(
|
|
||||||
'DROP FUNCTION exchange.master_table_%s'::text
|
|
||||||
,rec.name
|
|
||||||
);
|
|
||||||
ELSE
|
|
||||||
ASSERT FALSE, 'unsupported action type: ' || rec.action;
|
|
||||||
END CASE; -- END CASE (rec.action)
|
|
||||||
-- Mark as finished
|
|
||||||
UPDATE exchange.exchange_tables
|
|
||||||
SET finished=TRUE
|
|
||||||
WHERE table_serial_id=rec.table_serial_id;
|
|
||||||
END LOOP; -- create/alter/drop actions
|
|
||||||
END $$;
|
|
||||||
|
|
||||||
COMMENT ON FUNCTION exchange_do_create_tables
|
|
||||||
IS 'Creates all tables for the given number of partitions that need creating. Does NOT support sharding.';
|
|
||||||
|
|
@ -1,222 +0,0 @@
|
||||||
--
|
|
||||||
-- This file is part of TALER
|
|
||||||
-- Copyright (C) 2014--2025 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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
DROP FUNCTION IF EXISTS exchange_do_deposit;
|
|
||||||
CREATE FUNCTION exchange_do_deposit(
|
|
||||||
-- For batch_deposits
|
|
||||||
IN in_shard INT8,
|
|
||||||
IN in_merchant_pub BYTEA,
|
|
||||||
IN in_merchant_sig BYTEA,
|
|
||||||
IN in_wallet_timestamp INT8,
|
|
||||||
IN in_exchange_timestamp INT8,
|
|
||||||
IN in_refund_deadline INT8,
|
|
||||||
IN in_wire_deadline INT8,
|
|
||||||
IN in_h_contract_terms BYTEA,
|
|
||||||
IN in_wallet_data_hash BYTEA, -- can be NULL
|
|
||||||
IN in_wire_salt BYTEA,
|
|
||||||
IN in_wire_target_h_payto BYTEA,
|
|
||||||
IN in_h_normalized_payto BYTEA,
|
|
||||||
IN in_policy_details_serial_id INT8, -- can be NULL
|
|
||||||
IN in_policy_blocked BOOLEAN,
|
|
||||||
-- For wire_targets
|
|
||||||
IN in_receiver_wire_account TEXT,
|
|
||||||
-- For coin_deposits
|
|
||||||
IN ina_coin_pub BYTEA[],
|
|
||||||
IN ina_coin_sig BYTEA[],
|
|
||||||
IN ina_amount_with_fee taler_amount[],
|
|
||||||
IN in_total_amount taler_amount,
|
|
||||||
IN in_is_wallet BOOL,
|
|
||||||
OUT out_exchange_timestamp INT8,
|
|
||||||
OUT out_insufficient_balance_coin_index INT4, -- index of coin with bad balance, NULL if none
|
|
||||||
OUT out_conflict BOOL
|
|
||||||
)
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
wtsi INT8; -- wire target serial id
|
|
||||||
bdsi INT8; -- batch_deposits serial id
|
|
||||||
i INT4;
|
|
||||||
ini_amount_with_fee taler_amount;
|
|
||||||
ini_coin_pub BYTEA;
|
|
||||||
ini_coin_sig BYTEA;
|
|
||||||
BEGIN
|
|
||||||
-- Shards:
|
|
||||||
-- INSERT wire_targets (by h_payto), ON CONFLICT DO NOTHING;
|
|
||||||
-- INSERT batch_deposits (by shard, merchant_pub), ON CONFLICT idempotency check;
|
|
||||||
-- INSERT[] coin_deposits (by coin_pub), ON CONFLICT idempotency check;
|
|
||||||
-- UPDATE[] known_coins (by coin_pub)
|
|
||||||
|
|
||||||
|
|
||||||
-- Make sure the kyc_target entry exists
|
|
||||||
INSERT INTO kyc_targets
|
|
||||||
(h_normalized_payto
|
|
||||||
,is_wallet
|
|
||||||
) VALUES (
|
|
||||||
in_h_normalized_payto
|
|
||||||
,in_is_wallet
|
|
||||||
)
|
|
||||||
ON CONFLICT DO NOTHING;
|
|
||||||
|
|
||||||
-- First, get or create the 'wtsi'
|
|
||||||
INSERT INTO wire_targets
|
|
||||||
(wire_target_h_payto
|
|
||||||
,h_normalized_payto
|
|
||||||
,payto_uri
|
|
||||||
) VALUES (
|
|
||||||
in_wire_target_h_payto
|
|
||||||
,in_h_normalized_payto
|
|
||||||
,in_receiver_wire_account
|
|
||||||
)
|
|
||||||
ON CONFLICT DO NOTHING -- for CONFLICT ON (wire_target_h_payto)
|
|
||||||
RETURNING wire_target_serial_id
|
|
||||||
INTO wtsi;
|
|
||||||
|
|
||||||
IF NOT FOUND
|
|
||||||
THEN
|
|
||||||
SELECT wire_target_serial_id
|
|
||||||
INTO wtsi
|
|
||||||
FROM wire_targets
|
|
||||||
WHERE wire_target_h_payto=in_wire_target_h_payto;
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
|
|
||||||
-- Second, create the batch_deposits entry
|
|
||||||
INSERT INTO batch_deposits
|
|
||||||
(shard
|
|
||||||
,merchant_pub
|
|
||||||
,merchant_sig
|
|
||||||
,wallet_timestamp
|
|
||||||
,exchange_timestamp
|
|
||||||
,refund_deadline
|
|
||||||
,wire_deadline
|
|
||||||
,h_contract_terms
|
|
||||||
,wallet_data_hash
|
|
||||||
,wire_salt
|
|
||||||
,wire_target_h_payto
|
|
||||||
,policy_details_serial_id
|
|
||||||
,policy_blocked
|
|
||||||
,total_amount
|
|
||||||
) VALUES (
|
|
||||||
in_shard
|
|
||||||
,in_merchant_pub
|
|
||||||
,in_merchant_sig
|
|
||||||
,in_wallet_timestamp
|
|
||||||
,in_exchange_timestamp
|
|
||||||
,in_refund_deadline
|
|
||||||
,in_wire_deadline
|
|
||||||
,in_h_contract_terms
|
|
||||||
,in_wallet_data_hash
|
|
||||||
,in_wire_salt
|
|
||||||
,in_wire_target_h_payto
|
|
||||||
,in_policy_details_serial_id
|
|
||||||
,in_policy_blocked
|
|
||||||
,in_total_amount)
|
|
||||||
ON CONFLICT DO NOTHING -- for CONFLICT ON (merchant_pub, h_contract_terms)
|
|
||||||
RETURNING
|
|
||||||
batch_deposit_serial_id
|
|
||||||
INTO
|
|
||||||
bdsi;
|
|
||||||
|
|
||||||
IF NOT FOUND
|
|
||||||
THEN
|
|
||||||
-- Idempotency check: see if an identical record exists.
|
|
||||||
-- We do select over merchant_pub, h_contract_terms and wire_target_h_payto
|
|
||||||
-- first to maximally increase the chance of using the existing index.
|
|
||||||
SELECT
|
|
||||||
exchange_timestamp
|
|
||||||
,batch_deposit_serial_id
|
|
||||||
INTO
|
|
||||||
out_exchange_timestamp
|
|
||||||
,bdsi
|
|
||||||
FROM batch_deposits
|
|
||||||
WHERE shard=in_shard
|
|
||||||
AND merchant_pub=in_merchant_pub
|
|
||||||
AND h_contract_terms=in_h_contract_terms
|
|
||||||
AND wire_target_h_payto=in_wire_target_h_payto
|
|
||||||
-- now check the rest, too
|
|
||||||
AND ( (wallet_data_hash=in_wallet_data_hash) OR
|
|
||||||
(wallet_data_hash IS NULL AND in_wallet_data_hash IS NULL) )
|
|
||||||
AND wire_salt=in_wire_salt
|
|
||||||
AND wallet_timestamp=in_wallet_timestamp
|
|
||||||
AND refund_deadline=in_refund_deadline
|
|
||||||
AND wire_deadline=in_wire_deadline
|
|
||||||
AND ( (policy_details_serial_id=in_policy_details_serial_id) OR
|
|
||||||
(policy_details_serial_id IS NULL AND in_policy_details_serial_id IS NULL) );
|
|
||||||
IF NOT FOUND
|
|
||||||
THEN
|
|
||||||
-- Deposit exists, but with *strange* differences. Not allowed.
|
|
||||||
out_conflict=TRUE;
|
|
||||||
RETURN;
|
|
||||||
END IF;
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
out_conflict=FALSE;
|
|
||||||
|
|
||||||
-- Deposit each coin
|
|
||||||
|
|
||||||
FOR i IN 1..array_length(ina_coin_pub,1)
|
|
||||||
LOOP
|
|
||||||
ini_coin_pub = ina_coin_pub[i];
|
|
||||||
ini_coin_sig = ina_coin_sig[i];
|
|
||||||
ini_amount_with_fee = ina_amount_with_fee[i];
|
|
||||||
|
|
||||||
INSERT INTO coin_deposits
|
|
||||||
(batch_deposit_serial_id
|
|
||||||
,coin_pub
|
|
||||||
,coin_sig
|
|
||||||
,amount_with_fee
|
|
||||||
) VALUES (
|
|
||||||
bdsi
|
|
||||||
,ini_coin_pub
|
|
||||||
,ini_coin_sig
|
|
||||||
,ini_amount_with_fee
|
|
||||||
)
|
|
||||||
ON CONFLICT DO NOTHING;
|
|
||||||
|
|
||||||
IF FOUND
|
|
||||||
THEN
|
|
||||||
-- Insert did happen, update balance in known_coins!
|
|
||||||
|
|
||||||
UPDATE known_coins kc
|
|
||||||
SET
|
|
||||||
remaining.frac=(kc.remaining).frac-ini_amount_with_fee.frac
|
|
||||||
+ CASE
|
|
||||||
WHEN (kc.remaining).frac < ini_amount_with_fee.frac
|
|
||||||
THEN 100000000
|
|
||||||
ELSE 0
|
|
||||||
END,
|
|
||||||
remaining.val=(kc.remaining).val-ini_amount_with_fee.val
|
|
||||||
- CASE
|
|
||||||
WHEN (kc.remaining).frac < ini_amount_with_fee.frac
|
|
||||||
THEN 1
|
|
||||||
ELSE 0
|
|
||||||
END
|
|
||||||
WHERE coin_pub=ini_coin_pub
|
|
||||||
AND ( ((kc.remaining).val > ini_amount_with_fee.val) OR
|
|
||||||
( ((kc.remaining).frac >= ini_amount_with_fee.frac) AND
|
|
||||||
((kc.remaining).val >= ini_amount_with_fee.val) ) );
|
|
||||||
|
|
||||||
IF NOT FOUND
|
|
||||||
THEN
|
|
||||||
-- Insufficient balance.
|
|
||||||
-- Note: C arrays are 0 indexed, but i started at 1
|
|
||||||
out_insufficient_balance_coin_index=i-1;
|
|
||||||
RETURN;
|
|
||||||
END IF;
|
|
||||||
END IF;
|
|
||||||
END LOOP; -- end FOR all coins
|
|
||||||
|
|
||||||
END $$;
|
|
||||||
|
|
@ -1,98 +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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION exchange_do_expire_purse(
|
|
||||||
IN in_start_time INT8,
|
|
||||||
IN in_end_time INT8,
|
|
||||||
IN in_now INT8,
|
|
||||||
OUT out_found BOOLEAN)
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
my_purse_pub BYTEA;
|
|
||||||
DECLARE
|
|
||||||
my_deposit record;
|
|
||||||
DECLARE
|
|
||||||
my_in_reserve_quota BOOLEAN;
|
|
||||||
BEGIN
|
|
||||||
|
|
||||||
-- FIXME: we should probably do this in a loop
|
|
||||||
-- and expire all at once, instead of one per query
|
|
||||||
SELECT purse_pub
|
|
||||||
,in_reserve_quota
|
|
||||||
INTO my_purse_pub
|
|
||||||
,my_in_reserve_quota
|
|
||||||
FROM purse_requests
|
|
||||||
WHERE (purse_expiration >= in_start_time) AND
|
|
||||||
(purse_expiration < in_end_time) AND
|
|
||||||
NOT was_decided
|
|
||||||
ORDER BY purse_expiration ASC
|
|
||||||
LIMIT 1;
|
|
||||||
out_found = FOUND;
|
|
||||||
IF NOT FOUND
|
|
||||||
THEN
|
|
||||||
RETURN;
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
INSERT INTO purse_decision
|
|
||||||
(purse_pub
|
|
||||||
,action_timestamp
|
|
||||||
,refunded)
|
|
||||||
VALUES
|
|
||||||
(my_purse_pub
|
|
||||||
,in_now
|
|
||||||
,TRUE);
|
|
||||||
|
|
||||||
-- Code for 'TALER_DBEVENT_EXCHANGE_PURSE_REFUNDED'
|
|
||||||
NOTIFY X8DJSPNYJMNZDAP7GN6YQ4EZVSQXMF3HRP4VAR347WP9SZYP1C200;
|
|
||||||
|
|
||||||
IF (my_in_reserve_quota)
|
|
||||||
THEN
|
|
||||||
UPDATE reserves
|
|
||||||
SET purses_active=purses_active-1
|
|
||||||
WHERE reserve_pub IN
|
|
||||||
(SELECT reserve_pub
|
|
||||||
FROM exchange.purse_merges
|
|
||||||
WHERE purse_pub=my_purse_pub
|
|
||||||
LIMIT 1);
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
-- restore balance to each coin deposited into the purse
|
|
||||||
FOR my_deposit IN
|
|
||||||
SELECT coin_pub
|
|
||||||
,amount_with_fee
|
|
||||||
FROM purse_deposits
|
|
||||||
WHERE purse_pub = my_purse_pub
|
|
||||||
LOOP
|
|
||||||
UPDATE known_coins kc SET
|
|
||||||
remaining.frac=(kc.remaining).frac+(my_deposit.amount_with_fee).frac
|
|
||||||
- CASE
|
|
||||||
WHEN (kc.remaining).frac+(my_deposit.amount_with_fee).frac >= 100000000
|
|
||||||
THEN 100000000
|
|
||||||
ELSE 0
|
|
||||||
END,
|
|
||||||
remaining.val=(kc.remaining).val+(my_deposit.amount_with_fee).val
|
|
||||||
+ CASE
|
|
||||||
WHEN (kc.remaining).frac+(my_deposit.amount_with_fee).frac >= 100000000
|
|
||||||
THEN 1
|
|
||||||
ELSE 0
|
|
||||||
END
|
|
||||||
WHERE coin_pub = my_deposit.coin_pub;
|
|
||||||
END LOOP;
|
|
||||||
END $$;
|
|
||||||
|
|
||||||
COMMENT ON FUNCTION exchange_do_expire_purse(INT8,INT8,INT8)
|
|
||||||
IS 'Finds an expired purse in the given time range and refunds the coins (if any).';
|
|
||||||
|
|
@ -1,76 +0,0 @@
|
||||||
--
|
|
||||||
-- This file is part of TALER
|
|
||||||
-- Copyright (C) 2023-2025 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 <http://www.gnu.org/licenses/>
|
|
||||||
|
|
||||||
DROP FUNCTION IF EXISTS exchange_do_get_kyc_rules;
|
|
||||||
|
|
||||||
CREATE FUNCTION exchange_do_get_kyc_rules(
|
|
||||||
IN in_h_payto BYTEA,
|
|
||||||
IN in_now INT8,
|
|
||||||
IN in_merchant_pub BYTEA, -- possibly NULL
|
|
||||||
OUT out_target_pub BYTEA, -- possibly NULL
|
|
||||||
OUT out_reserve_pub BYTEA, -- possibly NULL
|
|
||||||
OUT out_jnew_rules JSONB -- possibly NULL
|
|
||||||
)
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
my_found BOOL;
|
|
||||||
BEGIN
|
|
||||||
IF in_merchant_pub IS NOT NULL
|
|
||||||
THEN
|
|
||||||
PERFORM FROM reserves_in
|
|
||||||
WHERE reserve_pub=in_merchant_pub
|
|
||||||
AND wire_source_h_payto IN
|
|
||||||
(SELECT wire_target_h_payto
|
|
||||||
FROM wire_targets
|
|
||||||
WHERE h_normalized_payto = in_h_payto);
|
|
||||||
my_found = FOUND;
|
|
||||||
ELSE
|
|
||||||
my_found = FALSE;
|
|
||||||
END IF;
|
|
||||||
IF FOUND
|
|
||||||
THEN
|
|
||||||
-- The merchant_pub used by the client matches, use that
|
|
||||||
out_reserve_pub = in_merchant_pub;
|
|
||||||
ELSE
|
|
||||||
-- If multiple reserves_in match, we pick the latest one
|
|
||||||
SELECT reserve_pub
|
|
||||||
INTO out_reserve_pub
|
|
||||||
FROM reserves_in
|
|
||||||
WHERE wire_source_h_payto IN
|
|
||||||
(SELECT wire_target_h_payto
|
|
||||||
FROM wire_targets
|
|
||||||
WHERE h_normalized_payto = in_h_payto)
|
|
||||||
ORDER BY execution_date DESC
|
|
||||||
LIMIT 1;
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
SELECT target_pub
|
|
||||||
INTO out_target_pub
|
|
||||||
FROM kyc_targets
|
|
||||||
WHERE h_normalized_payto = in_h_payto;
|
|
||||||
|
|
||||||
SELECT jnew_rules
|
|
||||||
INTO out_jnew_rules
|
|
||||||
FROM legitimization_outcomes
|
|
||||||
WHERE h_payto = in_h_payto
|
|
||||||
AND COALESCE(expiration_time >= $2, TRUE)
|
|
||||||
AND COALESCE(is_active, TRUE)
|
|
||||||
-- technically only one should ever be active, but we can be conservative
|
|
||||||
ORDER BY expiration_time DESC
|
|
||||||
LIMIT 1;
|
|
||||||
|
|
||||||
|
|
||||||
END $$;
|
|
||||||
|
|
@ -1,59 +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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION exchange_do_get_link_data(
|
|
||||||
IN in_coin_pub BYTEA
|
|
||||||
)
|
|
||||||
RETURNS SETOF record
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
curs CURSOR
|
|
||||||
FOR
|
|
||||||
SELECT
|
|
||||||
melt_serial_id
|
|
||||||
FROM refresh_commitments
|
|
||||||
WHERE old_coin_pub=in_coin_pub;
|
|
||||||
|
|
||||||
DECLARE
|
|
||||||
i RECORD;
|
|
||||||
BEGIN
|
|
||||||
OPEN curs;
|
|
||||||
LOOP
|
|
||||||
FETCH NEXT FROM curs INTO i;
|
|
||||||
EXIT WHEN NOT FOUND;
|
|
||||||
RETURN QUERY
|
|
||||||
SELECT
|
|
||||||
tp.transfer_pub
|
|
||||||
,denoms.denom_pub
|
|
||||||
,rrc.ev_sig
|
|
||||||
,rrc.ewv
|
|
||||||
,rrc.link_sig
|
|
||||||
,rrc.freshcoin_index
|
|
||||||
,rrc.coin_ev
|
|
||||||
FROM refresh_revealed_coins rrc
|
|
||||||
JOIN refresh_transfer_keys tp
|
|
||||||
ON (tp.melt_serial_id=rrc.melt_serial_id)
|
|
||||||
JOIN denominations denoms
|
|
||||||
ON (rrc.denominations_serial=denoms.denominations_serial)
|
|
||||||
WHERE rrc.melt_serial_id =i.melt_serial_id
|
|
||||||
/* GROUP BY tp.transfer_pub, denoms.denom_pub, rrc.ev_sig,rrc.ewv,rrc.link_sig,rrc.freshcoin_index, rrc.coin_ev*/
|
|
||||||
ORDER BY tp.transfer_pub,
|
|
||||||
rrc.freshcoin_index ASC
|
|
||||||
;
|
|
||||||
END LOOP;
|
|
||||||
CLOSE curs;
|
|
||||||
END $$;
|
|
||||||
|
|
@ -1,51 +0,0 @@
|
||||||
--
|
|
||||||
-- This file is part of TALER
|
|
||||||
-- Copyright (C) 2023, 2024 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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
DROP FUNCTION IF EXISTS exchange_do_insert_active_legitimization_measure;
|
|
||||||
CREATE FUNCTION exchange_do_insert_active_legitimization_measure(
|
|
||||||
IN in_access_token BYTEA,
|
|
||||||
IN in_start_time INT8,
|
|
||||||
IN in_jmeasures JSONB,
|
|
||||||
OUT out_legitimization_measure_serial_id INT8)
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
BEGIN
|
|
||||||
|
|
||||||
UPDATE legitimization_measures
|
|
||||||
SET is_finished=TRUE
|
|
||||||
WHERE access_token=in_access_token
|
|
||||||
AND NOT is_finished;
|
|
||||||
|
|
||||||
INSERT INTO legitimization_measures
|
|
||||||
(access_token
|
|
||||||
,start_time
|
|
||||||
,jmeasures
|
|
||||||
,display_priority)
|
|
||||||
VALUES
|
|
||||||
(in_access_token
|
|
||||||
,in_start_time
|
|
||||||
,in_jmeasures
|
|
||||||
,1)
|
|
||||||
RETURNING
|
|
||||||
legitimization_measure_serial_id
|
|
||||||
INTO
|
|
||||||
out_legitimization_measure_serial_id;
|
|
||||||
|
|
||||||
END $$;
|
|
||||||
|
|
||||||
|
|
||||||
COMMENT ON FUNCTION exchange_do_insert_active_legitimization_measure(BYTEA, INT8, JSONB)
|
|
||||||
IS 'Inserts legitimization measure for an account and marks all existing such measures as inactive';
|
|
||||||
|
|
@ -1,337 +0,0 @@
|
||||||
--
|
|
||||||
-- This file is part of TALER
|
|
||||||
-- Copyright (C) 2023, 2024 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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
DROP FUNCTION IF EXISTS exchange_do_insert_aml_decision;
|
|
||||||
CREATE FUNCTION exchange_do_insert_aml_decision(
|
|
||||||
IN in_payto_uri TEXT, -- can be NULL!
|
|
||||||
IN in_h_normalized_payto BYTEA,
|
|
||||||
IN in_h_full_payto BYTEA, -- can be NULL!
|
|
||||||
IN in_decision_time INT8,
|
|
||||||
IN in_expiration_time INT8,
|
|
||||||
IN in_properties JSONB, -- can be NULL
|
|
||||||
IN in_kyc_attributes_enc BYTEA, -- can be NULL
|
|
||||||
IN in_kyc_attributes_hash BYTEA, -- can be NULL
|
|
||||||
IN in_kyc_attributes_expiration INT8, -- can be NULL
|
|
||||||
IN in_new_rules JSONB,
|
|
||||||
IN in_to_investigate BOOLEAN,
|
|
||||||
IN in_new_measure_name TEXT, -- can be NULL
|
|
||||||
IN in_jmeasures JSONB, -- can be NULL
|
|
||||||
IN in_justification TEXT, -- can be NULL
|
|
||||||
IN in_decider_pub BYTEA, -- can be NULL
|
|
||||||
IN in_decider_sig BYTEA, -- can be NULL
|
|
||||||
IN in_notify_s TEXT,
|
|
||||||
IN ina_events TEXT[],
|
|
||||||
IN in_form_name TEXT, -- can be NULL
|
|
||||||
OUT out_invalid_officer BOOLEAN,
|
|
||||||
OUT out_account_unknown BOOLEAN,
|
|
||||||
OUT out_last_date INT8,
|
|
||||||
OUT out_legitimization_measure_serial_id INT8,
|
|
||||||
OUT out_is_wallet BOOL) -- can be (left at) NULL
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
my_outcome_serial_id INT8;
|
|
||||||
my_legitimization_process_serial_id INT8;
|
|
||||||
my_kyc_attributes_serial_id INT8;
|
|
||||||
my_rec RECORD;
|
|
||||||
my_access_token BYTEA;
|
|
||||||
my_i INT4;
|
|
||||||
ini_event TEXT;
|
|
||||||
BEGIN
|
|
||||||
|
|
||||||
out_account_unknown=FALSE;
|
|
||||||
out_legitimization_measure_serial_id=0;
|
|
||||||
|
|
||||||
IF in_decider_pub IS NOT NULL
|
|
||||||
THEN
|
|
||||||
IF in_justification IS NULL OR in_decider_sig IS NULL
|
|
||||||
THEN
|
|
||||||
RAISE EXCEPTION 'Got in_decider_sig without justification or signature.';
|
|
||||||
END IF;
|
|
||||||
-- Check officer is eligible to make decisions.
|
|
||||||
PERFORM
|
|
||||||
FROM aml_staff
|
|
||||||
WHERE decider_pub=in_decider_pub
|
|
||||||
AND is_active
|
|
||||||
AND NOT read_only;
|
|
||||||
IF NOT FOUND
|
|
||||||
THEN
|
|
||||||
out_invalid_officer=TRUE;
|
|
||||||
out_last_date=0;
|
|
||||||
RETURN;
|
|
||||||
END IF;
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
out_invalid_officer=FALSE;
|
|
||||||
|
|
||||||
-- Check no more recent decision exists.
|
|
||||||
SELECT decision_time
|
|
||||||
INTO out_last_date
|
|
||||||
FROM legitimization_outcomes
|
|
||||||
WHERE h_payto=in_h_normalized_payto
|
|
||||||
AND is_active
|
|
||||||
ORDER BY decision_time DESC, outcome_serial_id DESC;
|
|
||||||
|
|
||||||
IF FOUND
|
|
||||||
THEN
|
|
||||||
IF in_decider_pub IS NOT NULL AND out_last_date > in_decision_time
|
|
||||||
THEN
|
|
||||||
-- Refuse to insert older decision for officer decisions.
|
|
||||||
RETURN;
|
|
||||||
END IF;
|
|
||||||
UPDATE legitimization_outcomes
|
|
||||||
SET is_active=FALSE
|
|
||||||
WHERE h_payto=in_h_normalized_payto
|
|
||||||
AND is_active;
|
|
||||||
ELSE
|
|
||||||
out_last_date = 0;
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
SELECT access_token
|
|
||||||
,is_wallet
|
|
||||||
INTO my_rec
|
|
||||||
FROM kyc_targets
|
|
||||||
WHERE h_normalized_payto=in_h_normalized_payto;
|
|
||||||
|
|
||||||
IF NOT FOUND
|
|
||||||
THEN
|
|
||||||
-- AML decision for previously unknown account; better includes
|
|
||||||
-- all required details about the account ...
|
|
||||||
IF in_payto_uri IS NULL
|
|
||||||
THEN
|
|
||||||
-- AML decision on an unknown account without payto_uri => fail.
|
|
||||||
out_account_unknown=TRUE;
|
|
||||||
RETURN;
|
|
||||||
END IF;
|
|
||||||
-- Well, fine, setup the account
|
|
||||||
out_is_wallet
|
|
||||||
= (LOWER (SUBSTRING (in_payto_uri, 22)) =
|
|
||||||
'payto://taler-reserve/') OR
|
|
||||||
(LOWER (SUBSTRING (in_payto_uri, 27)) =
|
|
||||||
'payto://taler-reserve-http/');
|
|
||||||
INSERT INTO kyc_targets
|
|
||||||
(h_normalized_payto
|
|
||||||
,is_wallet
|
|
||||||
) VALUES (
|
|
||||||
in_h_normalized_payto
|
|
||||||
,out_is_wallet
|
|
||||||
)
|
|
||||||
RETURNING access_token
|
|
||||||
INTO my_access_token;
|
|
||||||
INSERT INTO wire_targets
|
|
||||||
(wire_target_h_payto
|
|
||||||
,h_normalized_payto
|
|
||||||
,payto_uri
|
|
||||||
) VALUES (
|
|
||||||
in_h_full_payto
|
|
||||||
,in_h_normalized_payto
|
|
||||||
,in_payto_uri
|
|
||||||
)
|
|
||||||
ON CONFLICT DO NOTHING;
|
|
||||||
ELSE
|
|
||||||
my_access_token = my_rec.access_token;
|
|
||||||
out_is_wallet = my_rec.is_wallet;
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
-- Did KYC measures get prescribed?
|
|
||||||
IF in_jmeasures IS NOT NULL
|
|
||||||
THEN
|
|
||||||
-- First check if a perfectly equivalent legi measure
|
|
||||||
-- already exists, to avoid creating tons of duplicates.
|
|
||||||
SELECT legitimization_measure_serial_id
|
|
||||||
INTO out_legitimization_measure_serial_id
|
|
||||||
FROM legitimization_measures
|
|
||||||
WHERE access_token=my_access_token
|
|
||||||
AND jmeasures=in_jmeasures
|
|
||||||
AND NOT is_finished;
|
|
||||||
|
|
||||||
IF NOT FOUND
|
|
||||||
THEN
|
|
||||||
-- Enable new legitimization measure
|
|
||||||
INSERT INTO legitimization_measures
|
|
||||||
(access_token
|
|
||||||
,start_time
|
|
||||||
,jmeasures
|
|
||||||
,display_priority
|
|
||||||
) VALUES (
|
|
||||||
my_access_token
|
|
||||||
,in_decision_time
|
|
||||||
,in_jmeasures
|
|
||||||
,1)
|
|
||||||
RETURNING
|
|
||||||
legitimization_measure_serial_id
|
|
||||||
INTO
|
|
||||||
out_legitimization_measure_serial_id;
|
|
||||||
END IF;
|
|
||||||
-- end if for where we had in_jmeasures
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
RAISE NOTICE 'marking legi measures of % as finished except for %', my_access_token, out_legitimization_measure_serial_id;
|
|
||||||
|
|
||||||
-- AML decision: mark all other active measures finished!
|
|
||||||
UPDATE legitimization_measures
|
|
||||||
SET is_finished=TRUE
|
|
||||||
WHERE access_token=my_access_token
|
|
||||||
AND NOT is_finished
|
|
||||||
AND legitimization_measure_serial_id != out_legitimization_measure_serial_id;
|
|
||||||
|
|
||||||
UPDATE legitimization_outcomes
|
|
||||||
SET is_active=FALSE
|
|
||||||
WHERE h_payto=in_h_normalized_payto
|
|
||||||
-- this clause is a minor optimization to avoid
|
|
||||||
-- updating outcomes that have long expired.
|
|
||||||
AND expiration_time >= in_decision_time;
|
|
||||||
|
|
||||||
INSERT INTO legitimization_outcomes
|
|
||||||
(h_payto
|
|
||||||
,decision_time
|
|
||||||
,expiration_time
|
|
||||||
,jproperties
|
|
||||||
,new_measure_name
|
|
||||||
,to_investigate
|
|
||||||
,jnew_rules
|
|
||||||
) VALUES (
|
|
||||||
in_h_normalized_payto
|
|
||||||
,in_decision_time
|
|
||||||
,in_expiration_time
|
|
||||||
,in_properties
|
|
||||||
,in_new_measure_name
|
|
||||||
,in_to_investigate
|
|
||||||
,in_new_rules
|
|
||||||
)
|
|
||||||
RETURNING outcome_serial_id
|
|
||||||
INTO my_outcome_serial_id;
|
|
||||||
|
|
||||||
IF in_kyc_attributes_enc IS NOT NULL
|
|
||||||
THEN
|
|
||||||
IF in_kyc_attributes_hash IS NULL OR in_kyc_attributes_expiration IS NULL
|
|
||||||
THEN
|
|
||||||
RAISE EXCEPTION 'Got in_kyc_attributes_hash without hash or expiration.';
|
|
||||||
END IF;
|
|
||||||
IF in_decider_pub IS NULL
|
|
||||||
THEN
|
|
||||||
RAISE EXCEPTION 'Got in_kyc_attributes_hash without in_decider_pub.';
|
|
||||||
END IF;
|
|
||||||
-- Simulate a legi process for attribute insertion by AML Officer
|
|
||||||
INSERT INTO legitimization_processes
|
|
||||||
(h_payto
|
|
||||||
,start_time
|
|
||||||
,expiration_time
|
|
||||||
,provider_name
|
|
||||||
,provider_user_id
|
|
||||||
,finished
|
|
||||||
) VALUES (
|
|
||||||
in_h_normalized_payto
|
|
||||||
,in_decision_time
|
|
||||||
-- Process starts and finishes instantly
|
|
||||||
,in_decision_time
|
|
||||||
,'aml-officer'
|
|
||||||
,in_decider_pub
|
|
||||||
,TRUE
|
|
||||||
)
|
|
||||||
RETURNING legitimization_process_serial_id
|
|
||||||
INTO my_legitimization_process_serial_id;
|
|
||||||
-- Now we can insert the attribute!
|
|
||||||
INSERT INTO kyc_attributes
|
|
||||||
(h_payto
|
|
||||||
,collection_time
|
|
||||||
,expiration_time
|
|
||||||
,form_name
|
|
||||||
,by_aml_officer
|
|
||||||
,encrypted_attributes
|
|
||||||
,legitimization_serial
|
|
||||||
) VALUES (
|
|
||||||
in_h_normalized_payto
|
|
||||||
,in_decision_time
|
|
||||||
,in_kyc_attributes_expiration
|
|
||||||
,in_form_name
|
|
||||||
,TRUE
|
|
||||||
,in_kyc_attributes_enc
|
|
||||||
,my_legitimization_process_serial_id
|
|
||||||
)
|
|
||||||
RETURNING kyc_attributes_serial_id
|
|
||||||
INTO my_kyc_attributes_serial_id;
|
|
||||||
-- Wake up taler-exchange-sanctionscheck to check new attributes
|
|
||||||
-- This is value for TALER_DBEVENT_EXCHANGE_NEW_KYC_ATTRIBUTES.
|
|
||||||
NOTIFY XSX9Z5XGWWYFKXTAYCES63B62527JKNX9XD0131Z08THVV8YW5BZG;
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
IF in_decider_pub IS NOT NULL
|
|
||||||
THEN
|
|
||||||
INSERT INTO aml_history
|
|
||||||
(h_payto
|
|
||||||
,outcome_serial_id
|
|
||||||
,justification
|
|
||||||
,decider_pub
|
|
||||||
,decider_sig
|
|
||||||
,kyc_attributes_hash
|
|
||||||
,kyc_attributes_serial_id
|
|
||||||
) VALUES (
|
|
||||||
in_h_normalized_payto
|
|
||||||
,my_outcome_serial_id
|
|
||||||
,in_justification
|
|
||||||
,in_decider_pub
|
|
||||||
,in_decider_sig
|
|
||||||
,in_kyc_attributes_hash
|
|
||||||
,my_kyc_attributes_serial_id
|
|
||||||
);
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
-- Trigger events
|
|
||||||
FOR i IN 1..COALESCE(array_length(ina_events,1),0)
|
|
||||||
LOOP
|
|
||||||
ini_event = ina_events[i];
|
|
||||||
INSERT INTO kyc_events
|
|
||||||
(event_timestamp
|
|
||||||
,event_type
|
|
||||||
) VALUES (
|
|
||||||
in_decision_time
|
|
||||||
,ini_event);
|
|
||||||
IF (ini-event = 'ACCOUNT_OPEN')
|
|
||||||
THEN
|
|
||||||
UPDATE kyc_targets
|
|
||||||
SET open_time=in_decision_time
|
|
||||||
,close_time=NULL
|
|
||||||
WHERE h_normalized_payto=in_h_normalized_payto;
|
|
||||||
END IF;
|
|
||||||
IF (ini-event = 'ACCOUNT_IDLE')
|
|
||||||
THEN
|
|
||||||
UPDATE kyc_targets
|
|
||||||
SET close_time=in_decision_time
|
|
||||||
WHERE h_normalized_payto=in_h_normalized_payto;
|
|
||||||
END IF;
|
|
||||||
END LOOP;
|
|
||||||
|
|
||||||
-- wake up taler-exchange-aggregator
|
|
||||||
INSERT INTO kyc_alerts
|
|
||||||
(h_payto
|
|
||||||
,trigger_type
|
|
||||||
) VALUES (
|
|
||||||
in_h_normalized_payto
|
|
||||||
,1
|
|
||||||
)
|
|
||||||
ON CONFLICT DO NOTHING;
|
|
||||||
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'NOTIFY %s'
|
|
||||||
,in_notify_s);
|
|
||||||
|
|
||||||
|
|
||||||
END $$;
|
|
||||||
|
|
||||||
|
|
||||||
COMMENT ON FUNCTION exchange_do_insert_aml_decision(TEXT, BYTEA, BYTEA, INT8, INT8, JSONB, BYTEA, BYTEA, INT8, JSONB, BOOLEAN, TEXT, JSONB, TEXT, BYTEA, BYTEA, TEXT, TEXT[], TEXT)
|
|
||||||
IS 'Checks whether the AML officer is eligible to make AML decisions and if so inserts the decision into the table';
|
|
||||||
|
|
@ -1,74 +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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION exchange_do_insert_aml_officer(
|
|
||||||
IN in_decider_pub BYTEA,
|
|
||||||
IN in_master_sig BYTEA,
|
|
||||||
IN in_decider_name TEXT,
|
|
||||||
IN in_is_active BOOLEAN,
|
|
||||||
IN in_read_only BOOLEAN,
|
|
||||||
IN in_last_change INT8,
|
|
||||||
OUT out_last_change INT8)
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
BEGIN
|
|
||||||
INSERT INTO exchange.aml_staff
|
|
||||||
(decider_pub
|
|
||||||
,master_sig
|
|
||||||
,decider_name
|
|
||||||
,is_active
|
|
||||||
,read_only
|
|
||||||
,last_change
|
|
||||||
) VALUES
|
|
||||||
(in_decider_pub
|
|
||||||
,in_master_sig
|
|
||||||
,in_decider_name
|
|
||||||
,in_is_active
|
|
||||||
,in_read_only
|
|
||||||
,in_last_change)
|
|
||||||
ON CONFLICT DO NOTHING;
|
|
||||||
IF FOUND
|
|
||||||
THEN
|
|
||||||
out_last_change=0;
|
|
||||||
RETURN;
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
-- Check update is most recent...
|
|
||||||
SELECT last_change
|
|
||||||
INTO out_last_change
|
|
||||||
FROM exchange.aml_staff
|
|
||||||
WHERE decider_pub=in_decider_pub;
|
|
||||||
ASSERT FOUND, 'cannot have INSERT conflict but no AML staff record';
|
|
||||||
|
|
||||||
IF out_last_change >= in_last_change
|
|
||||||
THEN
|
|
||||||
-- Refuse to insert older status
|
|
||||||
RETURN;
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
-- We are more recent, update existing record.
|
|
||||||
UPDATE exchange.aml_staff
|
|
||||||
SET master_sig=in_master_sig
|
|
||||||
,decider_name=in_decider_name
|
|
||||||
,is_active=in_is_active
|
|
||||||
,read_only=in_read_only
|
|
||||||
,last_change=in_last_change
|
|
||||||
WHERE decider_pub=in_decider_pub;
|
|
||||||
END $$;
|
|
||||||
|
|
||||||
|
|
||||||
COMMENT ON FUNCTION exchange_do_insert_aml_officer(BYTEA, BYTEA, TEXT, BOOL, BOOL, INT8)
|
|
||||||
IS 'Inserts or updates AML staff record, making sure the update is more recent than the previous change';
|
|
||||||
|
|
@ -1,75 +0,0 @@
|
||||||
--
|
|
||||||
-- This file is part of TALER
|
|
||||||
-- Copyright (C) 2023, 2024 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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
DROP FUNCTION IF EXISTS exchange_do_insert_aml_program_failure;
|
|
||||||
CREATE FUNCTION exchange_do_insert_aml_program_failure (
|
|
||||||
IN in_legitimization_process_serial_id INT8,
|
|
||||||
IN in_h_payto BYTEA,
|
|
||||||
IN in_now INT8,
|
|
||||||
IN in_error_code INT4,
|
|
||||||
IN in_error_message TEXT,
|
|
||||||
IN in_kyc_completed_notify_s TEXT,
|
|
||||||
OUT out_update BOOLEAN) -- set to true if we had a legi process matching in_process_row and in_provider_name for this account
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
BEGIN
|
|
||||||
|
|
||||||
|
|
||||||
UPDATE legitimization_processes
|
|
||||||
SET finished=TRUE
|
|
||||||
,error_code=in_error_code
|
|
||||||
,error_message=in_error_message
|
|
||||||
WHERE h_payto=in_h_payto
|
|
||||||
AND legitimization_process_serial_id=in_legitimization_process_serial_id;
|
|
||||||
out_update = FOUND;
|
|
||||||
IF NOT FOUND
|
|
||||||
THEN
|
|
||||||
-- Note: in_legitimization_process_serial_id should always be 0 here.
|
|
||||||
-- But we do not check and simply always create a new entry to at least
|
|
||||||
-- not loose information about the event!
|
|
||||||
INSERT INTO legitimization_processes
|
|
||||||
(finished
|
|
||||||
,error_code
|
|
||||||
,error_message
|
|
||||||
,h_payto
|
|
||||||
,start_time
|
|
||||||
,provider_section
|
|
||||||
) VALUES (
|
|
||||||
TRUE
|
|
||||||
,in_error_code
|
|
||||||
,in_error_message
|
|
||||||
,in_h_payto
|
|
||||||
,in_now
|
|
||||||
,'skip'
|
|
||||||
);
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'NOTIFY %s'
|
|
||||||
,in_kyc_completed_notify_s);
|
|
||||||
|
|
||||||
INSERT INTO kyc_alerts
|
|
||||||
(h_payto
|
|
||||||
,trigger_type)
|
|
||||||
VALUES
|
|
||||||
(in_h_payto,1)
|
|
||||||
ON CONFLICT DO NOTHING;
|
|
||||||
|
|
||||||
END $$;
|
|
||||||
|
|
||||||
|
|
||||||
COMMENT ON FUNCTION exchange_do_insert_aml_program_failure(INT8, BYTEA, INT8, INT4, TEXT, TEXT)
|
|
||||||
IS 'Stores information about an AML program run that failed into the legitimization_processes table. Either updates a row of an existing legitimization process, or creates a new entry.';
|
|
||||||
|
|
@ -1,114 +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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION exchange_do_insert_or_update_policy_details(
|
|
||||||
IN in_policy_hash_code BYTEA,
|
|
||||||
IN in_policy_json TEXT,
|
|
||||||
IN in_deadline INT8,
|
|
||||||
IN in_commitment taler_amount,
|
|
||||||
IN in_accumulated_total taler_amount,
|
|
||||||
IN in_fee taler_amount,
|
|
||||||
IN in_transferable taler_amount,
|
|
||||||
IN in_fulfillment_state SMALLINT,
|
|
||||||
OUT out_policy_details_serial_id INT8,
|
|
||||||
OUT out_accumulated_total taler_amount,
|
|
||||||
OUT out_fulfillment_state SMALLINT)
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
cur_commitment taler_amount;
|
|
||||||
DECLARE
|
|
||||||
cur_accumulated_total taler_amount;
|
|
||||||
DECLARE
|
|
||||||
rval RECORD;
|
|
||||||
BEGIN
|
|
||||||
-- First, try to create a new entry.
|
|
||||||
INSERT INTO policy_details
|
|
||||||
(policy_hash_code,
|
|
||||||
policy_json,
|
|
||||||
deadline,
|
|
||||||
commitment,
|
|
||||||
accumulated_total,
|
|
||||||
fee,
|
|
||||||
transferable,
|
|
||||||
fulfillment_state)
|
|
||||||
VALUES (in_policy_hash_code,
|
|
||||||
in_policy_json,
|
|
||||||
in_deadline,
|
|
||||||
in_commitment,
|
|
||||||
in_accumulated_total,
|
|
||||||
in_fee,
|
|
||||||
in_transferable,
|
|
||||||
in_fulfillment_state)
|
|
||||||
ON CONFLICT (policy_hash_code) DO NOTHING
|
|
||||||
RETURNING policy_details_serial_id INTO out_policy_details_serial_id;
|
|
||||||
|
|
||||||
-- If the insert was successful, return
|
|
||||||
-- We assume that the fullfilment_state was correct in first place.
|
|
||||||
IF FOUND THEN
|
|
||||||
out_accumulated_total = in_accumulated_total;
|
|
||||||
out_fulfillment_state = in_fulfillment_state;
|
|
||||||
RETURN;
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
-- We had a conflict, grab the parts we need to update.
|
|
||||||
SELECT policy_details_serial_id
|
|
||||||
,commitment
|
|
||||||
,accumulated_total
|
|
||||||
INTO rval
|
|
||||||
FROM policy_details
|
|
||||||
WHERE policy_hash_code = in_policy_hash_code;
|
|
||||||
|
|
||||||
-- We use rval as workaround as we cannot select
|
|
||||||
-- directly into the amount due to Postgres limitations.
|
|
||||||
out_policy_details_serial_id := rval.policy_details_serial_id;
|
|
||||||
cur_commitment := rval.commitment;
|
|
||||||
cur_accumulated_total := rval.accumulated_total;
|
|
||||||
|
|
||||||
-- calculate the new values (overflows throws exception)
|
|
||||||
out_accumulated_total.val = cur_accumulated_total.val + in_accumulated_total.val;
|
|
||||||
out_accumulated_total.frac = cur_accumulated_total.frac + in_accumulated_total.frac;
|
|
||||||
-- normalize
|
|
||||||
out_accumulated_total.val = out_accumulated_total.val + out_accumulated_total.frac / 100000000;
|
|
||||||
out_accumulated_total.frac = out_accumulated_total.frac % 100000000;
|
|
||||||
|
|
||||||
IF (out_accumulated_total.val > (1 << 52))
|
|
||||||
THEN
|
|
||||||
RAISE EXCEPTION 'accumulation overflow';
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
|
|
||||||
-- Set the fulfillment_state according to the values.
|
|
||||||
-- For now, we only update the state when it was INSUFFICIENT.
|
|
||||||
-- FIXME[oec] #7999: What to do in case of Failure or other state?
|
|
||||||
IF (out_fullfillment_state = 2) -- INSUFFICIENT
|
|
||||||
THEN
|
|
||||||
IF (out_accumulated_total.val >= cur_commitment.val OR
|
|
||||||
(out_accumulated_total.val = cur_commitment.val AND
|
|
||||||
out_accumulated_total.frac >= cur_commitment.frac))
|
|
||||||
THEN
|
|
||||||
out_fulfillment_state = 3; -- READY
|
|
||||||
END IF;
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
-- Now, update the record
|
|
||||||
UPDATE exchange.policy_details
|
|
||||||
SET
|
|
||||||
accumulated = out_accumulated_total,
|
|
||||||
fulfillment_state = out_fulfillment_state
|
|
||||||
WHERE
|
|
||||||
policy_details_serial_id = out_policy_details_serial_id;
|
|
||||||
END $$;
|
|
||||||
|
|
@ -1,82 +0,0 @@
|
||||||
--
|
|
||||||
-- This file is part of TALER
|
|
||||||
-- Copyright (C) 2025 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 <http://www.gnu.org/licenses/>
|
|
||||||
--
|
|
||||||
|
|
||||||
DROP FUNCTION IF EXISTS exchange_do_insert_sanction_list_hit;
|
|
||||||
CREATE FUNCTION exchange_do_insert_sanction_list_hit(
|
|
||||||
IN in_h_normalized_payto BYTEA,
|
|
||||||
IN in_decision_time INT8,
|
|
||||||
IN in_expiration_time INT8,
|
|
||||||
IN in_properties JSONB, -- can be NULL
|
|
||||||
IN in_new_rules JSONB, -- can be NULL
|
|
||||||
IN in_to_investigate BOOLEAN,
|
|
||||||
IN in_notify_s TEXT,
|
|
||||||
IN ina_events TEXT[],
|
|
||||||
OUT out_outcome_serial_id INT8)
|
|
||||||
LANGUAGE plpgsql
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
my_i INT4;
|
|
||||||
ini_event TEXT;
|
|
||||||
BEGIN
|
|
||||||
|
|
||||||
-- Disable all previous legitimization outcomes.
|
|
||||||
UPDATE legitimization_outcomes
|
|
||||||
SET is_active=FALSE
|
|
||||||
WHERE h_payto=in_h_normalized_payto;
|
|
||||||
|
|
||||||
INSERT INTO legitimization_outcomes
|
|
||||||
(h_payto
|
|
||||||
,decision_time
|
|
||||||
,expiration_time
|
|
||||||
,jproperties
|
|
||||||
,to_investigate
|
|
||||||
,jnew_rules
|
|
||||||
)
|
|
||||||
VALUES
|
|
||||||
(in_h_normalized_payto
|
|
||||||
,in_decision_time
|
|
||||||
,in_expiration_time
|
|
||||||
,in_properties
|
|
||||||
,in_to_investigate
|
|
||||||
,in_new_rules
|
|
||||||
)
|
|
||||||
RETURNING
|
|
||||||
outcome_serial_id
|
|
||||||
INTO
|
|
||||||
out_outcome_serial_id;
|
|
||||||
|
|
||||||
-- Trigger events
|
|
||||||
FOR i IN 1..COALESCE(array_length(ina_events,1),0)
|
|
||||||
LOOP
|
|
||||||
ini_event = ina_events[i];
|
|
||||||
INSERT INTO kyc_events
|
|
||||||
(event_timestamp
|
|
||||||
,event_type)
|
|
||||||
VALUES
|
|
||||||
(in_decision_time
|
|
||||||
,ini_event);
|
|
||||||
END LOOP;
|
|
||||||
|
|
||||||
EXECUTE FORMAT (
|
|
||||||
'NOTIFY %s'
|
|
||||||
,in_notify_s);
|
|
||||||
|
|
||||||
|
|
||||||
END $$;
|
|
||||||
|
|
||||||
|
|
||||||
COMMENT ON FUNCTION exchange_do_insert_sanction_list_hit(BYTEA, INT8, INT8, JSONB, JSONB, BOOLEAN, TEXT, TEXT[])
|
|
||||||
IS 'Insert result from sanction list check into the table';
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue