diff options
Diffstat (limited to 'src/exchangedb/exchange_do_purse_merge.sql')
-rw-r--r-- | src/exchangedb/exchange_do_purse_merge.sql | 118 |
1 files changed, 63 insertions, 55 deletions
diff --git a/src/exchangedb/exchange_do_purse_merge.sql b/src/exchangedb/exchange_do_purse_merge.sql index f02dd5dcd..946fd7e97 100644 --- a/src/exchangedb/exchange_do_purse_merge.sql +++ b/src/exchangedb/exchange_do_purse_merge.sql @@ -19,7 +19,7 @@ CREATE OR REPLACE FUNCTION exchange_do_purse_merge( IN in_merge_sig BYTEA, IN in_merge_timestamp INT8, IN in_reserve_sig BYTEA, - IN in_partner_url VARCHAR, + IN in_partner_url TEXT, IN in_reserve_pub BYTEA, IN in_wallet_h_payto BYTEA, IN in_expiration_date INT8, @@ -29,19 +29,32 @@ CREATE OR REPLACE FUNCTION exchange_do_purse_merge( LANGUAGE plpgsql AS $$ DECLARE - my_amount_val INT8; + my_amount taler_amount; DECLARE - my_amount_frac INT4; -DECLARE - my_purse_fee_val INT8; -DECLARE - my_purse_fee_frac INT4; + my_purse_fee taler_amount; DECLARE my_partner_serial_id INT8; DECLARE my_in_reserve_quota BOOLEAN; +DECLARE + rval RECORD; +DECLARE + reserve RECORD; +DECLARE + balance taler_amount; BEGIN +-- Initialize reserve, if not yet exists. +INSERT INTO reserves + (reserve_pub + ,expiration_date + ,gc_date) + VALUES + (in_reserve_pub + ,in_expiration_date + ,in_expiration_date) + ON CONFLICT DO NOTHING; + IF in_partner_url IS NULL THEN @@ -65,33 +78,33 @@ END IF; out_no_partner=FALSE; - -- Check purse is 'full'. -SELECT amount_with_fee_val - ,amount_with_fee_frac - ,purse_fee_val - ,purse_fee_frac +SELECT amount_with_fee + ,purse_fee ,in_reserve_quota - INTO my_amount_val - ,my_amount_frac - ,my_purse_fee_val - ,my_purse_fee_frac - ,my_in_reserve_quota - FROM exchange.purse_requests + INTO rval + FROM purse_requests pr WHERE purse_pub=in_purse_pub - AND balance_val >= amount_with_fee_val - AND ( (balance_frac >= amount_with_fee_frac) OR - (balance_val > amount_with_fee_val) ); + AND (pr.balance).val >= (pr.amount_with_fee).val + AND ( (pr.balance).frac >= (pr.amount_with_fee).frac OR + (pr.balance).val > (pr.amount_with_fee).val ); IF NOT FOUND THEN out_no_balance=TRUE; out_conflict=FALSE; RETURN; END IF; + +-- We use rval as workaround as we cannot select +-- directly into the amount due to Postgres limitations. +my_amount := rval.amount_with_fee; +my_purse_fee := rval.purse_fee; +my_in_reserve_quota := rval.in_reserve_quota; + out_no_balance=FALSE; -- Store purse merge signature, checks for purse_pub uniqueness -INSERT INTO exchange.purse_merges +INSERT INTO purse_merges (partner_serial_id ,reserve_pub ,purse_pub @@ -111,7 +124,7 @@ THEN -- Note that by checking 'merge_sig', we implicitly check -- identity over everything that the signature covers. PERFORM - FROM exchange.purse_merges + FROM purse_merges WHERE purse_pub=in_purse_pub AND merge_sig=in_merge_sig; IF NOT FOUND @@ -149,17 +162,6 @@ END IF; out_conflict=FALSE; --- Initialize reserve, if not yet exists. -INSERT INTO reserves - (reserve_pub - ,expiration_date - ,gc_date) - VALUES - (in_reserve_pub - ,in_expiration_date - ,in_expiration_date) - ON CONFLICT DO NOTHING; - IF (my_in_reserve_quota) THEN @@ -167,13 +169,13 @@ THEN SET purses_active=purses_active-1 WHERE reserve_pub IN (SELECT reserve_pub - FROM exchange.purse_merges + FROM purse_merges WHERE purse_pub=my_purse_pub LIMIT 1); END IF; -- Store account merge signature. -INSERT INTO exchange.account_merges +INSERT INTO account_merges (reserve_pub ,reserve_sig ,purse_pub @@ -196,26 +198,33 @@ ELSE -- This is a local reserve, update reserve balance immediately. -- Refund the purse fee, by adding it to the purse value: - my_amount_val = my_amount_val + my_purse_fee_val; - my_amount_frac = my_amount_frac + my_purse_fee_frac; + my_amount.val = my_amount.val + my_purse_fee.val; + my_amount.frac = my_amount.frac + my_purse_fee.frac; -- normalize result - my_amount_val = my_amount_val + my_amount_frac / 100000000; - my_amount_frac = my_amount_frac % 100000000; + my_amount.val = my_amount.val + my_amount.frac / 100000000; + my_amount.frac = my_amount.frac % 100000000; + + SELECT * + INTO reserve + FROM exchange.reserves + WHERE reserve_pub=in_reserve_pub; + + balance = reserve.current_balance; + balance.frac=balance.frac+my_amount.frac + - CASE + WHEN balance.frac + my_amount.frac >= 100000000 + THEN 100000000 + ELSE 0 + END; + balance.val=balance.val+my_amount.val + + CASE + WHEN balance.frac + my_amount.frac >= 100000000 + THEN 1 + ELSE 0 + END; UPDATE exchange.reserves - SET - current_balance_frac=current_balance_frac+my_amount_frac - - CASE - WHEN current_balance_frac + my_amount_frac >= 100000000 - THEN 100000000 - ELSE 0 - END, - current_balance_val=current_balance_val+my_amount_val - + CASE - WHEN current_balance_frac + my_amount_frac >= 100000000 - THEN 1 - ELSE 0 - END + SET current_balance=balance WHERE reserve_pub=in_reserve_pub; END IF; @@ -224,6 +233,5 @@ RETURN; END $$; -COMMENT ON FUNCTION exchange_do_purse_merge(BYTEA, BYTEA, INT8, BYTEA, VARCHAR, BYTEA, BYTEA, INT8) +COMMENT ON FUNCTION exchange_do_purse_merge(BYTEA, BYTEA, INT8, BYTEA, TEXT, BYTEA, BYTEA, INT8) IS 'Checks that the partner exists, the purse has not been merged with a different reserve and that the purse is full. If so, persists the merge data and either merges the purse with the reserve or marks it as ready for the taler-exchange-router. Caller MUST abort the transaction on failures so as to not persist data by accident.'; - |