1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
|
--
-- 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 OR REPLACE FUNCTION merchant_insert_deposit_to_transfer (
IN in_deposit_serial INT8,
IN in_amount_with_fee taler_amount_currency,
IN in_execution_time INT8,
IN in_exchange_sig BYTEA,
IN in_exchange_pub BYTEA,
IN in_wtid BYTEA,
OUT out_wire_pending_cleared BOOL,
OUT out_conflict BOOL,
OUT out_no_exchange_pub BOOL)
LANGUAGE plpgsql
AS $$
DECLARE
my_signkey_serial INT8;
DECLARE
my_confirmed BOOL;
DECLARE
my_decose INT8;
DECLARE
my_order_serial INT8;
BEGIN
-- Find exchange sign key
SELECT signkey_serial
INTO my_signkey_serial
FROM merchant_exchange_signing_keys
WHERE exchange_pub=in_exchange_pub
ORDER BY start_date DESC
LIMIT 1;
IF NOT FOUND
THEN
out_no_exchange_pub=TRUE;
out_conflict=FALSE;
out_wire_pending_cleared=FALSE;
RETURN;
END IF;
out_no_exchange_pub=FALSE;
-- Try to insert new wire transfer
INSERT INTO merchant_deposit_to_transfer
(deposit_serial
,coin_contribution_value
,wtid
,execution_time
,signkey_serial
,exchange_sig
)
VALUES
(in_deposit_serial
,in_amount_with_fee
,in_wtid
,in_execution_time
,my_signkey_serial
,in_exchange_sig
)
ON CONFLICT DO NOTHING;
IF NOT FOUND
THEN
-- Same or conflicting wire transfer existed in the table already
-- Note: we don't distinguish here between
-- conflict and duplicate. Do we need to?
out_conflict=TRUE;
out_wire_pending_cleared=FALSE;
return;
END IF;
out_conflict=FALSE;
-- Check if we already imported the (confirmed)
-- wire transfer *and* if it is mapped to this deposit.
PERFORM
FROM merchant_transfers mt
JOIN merchant_transfer_to_coin mtc
USING (credit_serial)
WHERE mt.wtid=in_wtid
AND mt.confirmed
AND mtc.deposit_serial=in_deposit_serial;
IF NOT FOUND
THEN
out_wire_pending_cleared=FALSE;
RETURN;
END IF;
RAISE NOTICE 'checking affected deposit confirmation for completion';
SELECT deposit_confirmation_serial
INTO my_decose
FROM merchant_deposits
WHERE deposit_serial=in_deposit_serial;
-- we made a change, check about clearing wire_pending
-- for the entire deposit confirmation
UPDATE merchant_deposit_confirmations
SET wire_pending=FALSE
WHERE (deposit_confirmation_serial=decose)
AND NOT EXISTS
(SELECT 1
FROM merchant_deposits md
LEFT JOIN merchant_deposit_to_transfer mdtt
USING (wtid)
WHERE md.deposit_confirmation_serial=my_decose
AND mdtt.credit_serial IS NULL);
-- credit_serial will be NULL due to LEFT JOIN
-- if we do not have an entry in mdtt for the deposit
-- and thus some entry in md was not yet wired.
IF NOT FOUND
THEN
out_wire_pending_cleared=FALSE;
RETURN;
END IF;
out_wire_pending_cleared=TRUE;
RAISE NOTICE 'checking affected contracts for completion';
-- Check if all deposit confirmations of the same
-- contract are now wired.
SELECT deposit_confirmation_serial
INTO my_order_serial
FROM merchant_deposit_confirmations
WHERE deposit_confirmation_serial=my_decose;
-- The above MUST succeed by invariants.
-- Check about setting 'wired' for the contract term.
-- Note: the same contract may be paid from
-- multiple exchanges, so we need to check if
-- payments were wired from all of them!
UPDATE merchant_contract_terms
SET wired=TRUE
WHERE (order_serial=my_order_serial)
AND NOT EXISTS
(SELECT 1
FROM merchant_deposit_confirmations mdc
WHERE mdc.wire_pending
AND mdc.order_serial=my_order_serial);
END $$;
|