-implementing do_reserves_open logic
This commit is contained in:
parent
ea11a9a0fd
commit
c1c02b8a3c
@ -30,3 +30,7 @@ LEGAL_RESERVE_EXPIRATION_TIME = 7 years
|
||||
# What is the desired delay between a transaction being ready and the
|
||||
# aggregator triggering on it?
|
||||
AGGREGATOR_SHIFT = 1 s
|
||||
|
||||
# How many concurrent purses may be opened by a reserve
|
||||
# if the reserve is paid for a year?
|
||||
DEFAULT_PURSE_LIMIT = 1
|
@ -47,8 +47,10 @@ TEH_PG_do_reserve_open (
|
||||
TALER_PQ_query_param_amount (total_paid),
|
||||
TALER_PQ_query_param_amount (reserve_payment),
|
||||
GNUNET_PQ_query_param_uint32 (&min_purse_limit),
|
||||
GNUNET_PQ_query_param_uint32 (&pg->def_purse_limit),
|
||||
GNUNET_PQ_query_param_auto_from_type (reserve_sig),
|
||||
GNUNET_PQ_query_param_timestamp (&desired_expiration),
|
||||
GNUNET_PQ_query_param_relative_time (&pg->legal_reserve_expiration_time),
|
||||
GNUNET_PQ_query_param_timestamp (&now),
|
||||
TALER_PQ_query_param_amount (open_fee),
|
||||
GNUNET_PQ_query_param_end
|
||||
|
@ -82,6 +82,12 @@ struct PostgresClosure
|
||||
*/
|
||||
unsigned long long prep_gen;
|
||||
|
||||
/**
|
||||
* Number of purses we allow to be opened concurrently
|
||||
* for one year per annual fee payment.
|
||||
*/
|
||||
uint32_t def_purse_limit;
|
||||
|
||||
/**
|
||||
* Did we initialize the prepared statements
|
||||
* for this session? (To be replaced with @e prep_gen.)
|
||||
|
@ -15567,6 +15567,7 @@ libtaler_plugin_exchangedb_postgres_init (void *cls)
|
||||
const struct GNUNET_CONFIGURATION_Handle *cfg = cls;
|
||||
struct PostgresClosure *pg;
|
||||
struct TALER_EXCHANGEDB_Plugin *plugin;
|
||||
unsigned long long dpl;
|
||||
|
||||
pg = GNUNET_new (struct PostgresClosure);
|
||||
pg->cfg = cfg;
|
||||
@ -15625,6 +15626,21 @@ libtaler_plugin_exchangedb_postgres_init (void *cls)
|
||||
"exchangedb",
|
||||
"AGGREGATOR_SHIFT");
|
||||
}
|
||||
if (GNUNET_OK !=
|
||||
GNUNET_CONFIGURATION_get_value_number (cfg,
|
||||
"exchangedb",
|
||||
"DEFAULT_PURSE_LIMIT",
|
||||
&dpl))
|
||||
{
|
||||
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_WARNING,
|
||||
"exchangedb",
|
||||
"DEFAULT_PURSE_LIMIT");
|
||||
pg->def_purse_limit = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
pg->def_purse_limit = (uint32_t) dpl;
|
||||
}
|
||||
|
||||
if (GNUNET_OK !=
|
||||
TALER_config_get_currency (cfg,
|
||||
|
@ -2183,8 +2183,10 @@ CREATE OR REPLACE FUNCTION exchange_do_reserve_open(
|
||||
IN in_reserve_payment_val INT8,
|
||||
IN in_reserve_payment_frac INT4,
|
||||
IN in_min_purse_limit INT4,
|
||||
IN in_default_purse_limit INT4,
|
||||
IN in_reserve_sig BYTEA,
|
||||
IN in_desired_expiration INT8,
|
||||
IN in_reserve_gc_delay INT8,
|
||||
IN in_now INT8,
|
||||
IN in_open_fee_val INT8,
|
||||
IN in_open_fee_frac INT4,
|
||||
@ -2194,9 +2196,161 @@ CREATE OR REPLACE FUNCTION exchange_do_reserve_open(
|
||||
OUT out_no_funds BOOLEAN)
|
||||
LANGUAGE plpgsql
|
||||
AS $$
|
||||
DECLARE
|
||||
my_balance_val INT8;
|
||||
DECLARE
|
||||
my_balance_frac INT4;
|
||||
DECLARE
|
||||
my_cost_val INT8;
|
||||
DECLARE
|
||||
my_cost_tmp INT8;
|
||||
DECLARE
|
||||
my_cost_frac INT4;
|
||||
DECLARE
|
||||
my_years_tmp INT4;
|
||||
DECLARE
|
||||
my_years INT4;
|
||||
DECLARE
|
||||
my_needs_update BOOL;
|
||||
DECLARE
|
||||
my_purses_allowed INT8;
|
||||
DECLARE
|
||||
my_expiration_date INT8;
|
||||
DECLARE
|
||||
my_reserve_expiration INT8;
|
||||
BEGIN
|
||||
|
||||
-- FIXME: implement!
|
||||
-- FIXME: use SELECT FOR UPDATE?
|
||||
SELECT
|
||||
purses_allowed
|
||||
,expiration_date
|
||||
,current_balance_val
|
||||
,current_balance_frac
|
||||
INTO
|
||||
my_purses_allowed
|
||||
,my_reserve_expiration
|
||||
,my_balance_val
|
||||
,my_balance_frac
|
||||
FROM reserves
|
||||
WHERE
|
||||
reserve_pub=in_reserve_pub;
|
||||
|
||||
IF NOT FOUND
|
||||
THEN
|
||||
-- FIXME: do we need to set a 'not found'?
|
||||
RETURN;
|
||||
END IF;
|
||||
|
||||
-- Do not allow expiration time to start in the past already
|
||||
IF (my_reserve_expiration < in_now)
|
||||
THEN
|
||||
my_expiration_date = in_now;
|
||||
ELSE
|
||||
my_expiration_date = my_reserve_expiration;
|
||||
END IF;
|
||||
|
||||
my_cost_val = 0;
|
||||
my_cost_frac = 0;
|
||||
my_needs_update = FALSE;
|
||||
my_years = 0;
|
||||
|
||||
-- Compute years based on desired expiration time
|
||||
IF (my_expiration_date < in_desired_expiration)
|
||||
THEN
|
||||
my_years = (31535999999999 + in_desired_expiration - my_expiration_date) / 31536000000000;
|
||||
my_purses_allowed = in_default_purse_limit;
|
||||
my_expiration_date = my_expiration_date + 31536000000000 * my_years;
|
||||
END IF;
|
||||
|
||||
-- Increase years based on purses requested
|
||||
IF (my_purses_allowed < in_min_purse_limit)
|
||||
THEN
|
||||
my_years = (31535999999999 + in_desired_expiration - in_now) / 31536000000000;
|
||||
my_expiration_date = in_now + 31536000000000 * my_years;
|
||||
my_years_tmp = (in_min_purse_limit + in_default_purse_limit - my_purses_allowed - 1) / in_default_purse_limit;
|
||||
my_years = my_years + my_years_tmp;
|
||||
my_purses_allowed = my_purses_allowed + (in_default_purse_limit * my_years_tmp);
|
||||
END IF;
|
||||
|
||||
-- Compute cost based on annual fees
|
||||
IF (my_years > 0)
|
||||
THEN
|
||||
my_cost_val = my_years * in_open_fee_val;
|
||||
my_cost_tmp = my_years * in_open_fee_frac / 100000000;
|
||||
IF (CAST (my_cost_val + my_cost_tmp AS INT8) < my_cost_val)
|
||||
THEN
|
||||
out_open_cost_val=9223372036854775807;
|
||||
out_open_cost_frac=2147483647;
|
||||
out_final_expiration=my_expiration_date;
|
||||
out_no_funds=true;
|
||||
RETURN;
|
||||
END IF;
|
||||
my_cost_val = CAST (my_cost_val + my_cost_tmp AS INT8);
|
||||
my_cost_frac = my_years * in_open_fee_frac % 100000000;
|
||||
my_needs_update = TRUE;
|
||||
END IF;
|
||||
|
||||
-- check if we actually have something to do
|
||||
IF NOT my_needs_update
|
||||
THEN
|
||||
out_final_expiration = my_reserve_expiration;
|
||||
out_open_cost_val = 0;
|
||||
out_open_cost_frac = 0;
|
||||
out_no_funds=FALSE;
|
||||
RETURN;
|
||||
END IF;
|
||||
|
||||
-- Check payment (coins and reserve) would be sufficient.
|
||||
IF ( (in_total_paid_val < my_cost_val) OR
|
||||
( (in_total_paid_val = my_cost_val) AND
|
||||
(in_total_paid_frac < my_cost_frac) ) )
|
||||
THEN
|
||||
out_final_expiration=my_reserve_expiration;
|
||||
out_open_cost_val = my_cost_val;
|
||||
out_open_cost_frac = my_cost_frac;
|
||||
out_no_funds=TRUE;
|
||||
RETURN;
|
||||
END IF;
|
||||
|
||||
-- Check reserve balance is sufficient.
|
||||
IF (my_balance_val > in_reserve_payment_val)
|
||||
THEN
|
||||
IF (my_balance_frac >= in_reserve_payment_frac)
|
||||
THEN
|
||||
my_balance_val=my_balance_val - in_reserve_payment_val;
|
||||
my_balance_frac=my_balance_frac - in_reserve_payment_frac;
|
||||
ELSE
|
||||
my_balance_val=my_balance_val - in_reserve_payment_val - 1;
|
||||
my_balance_frac=my_balance_frac + 100000000 - in_reserve_payment_frac;
|
||||
END IF;
|
||||
ELSE
|
||||
IF (my_balance_val = in_reserve_payment_val) AND (my_balance_frac >= in_reserve_payment_frac)
|
||||
THEN
|
||||
my_balance_val=0;
|
||||
my_balance_frac=my_balance_frac - in_reserve_payment_frac;
|
||||
ELSE
|
||||
out_final_expiration=my_reserve_expiration;
|
||||
out_open_cost_val = my_cost_val;
|
||||
out_open_cost_frac = my_cost_frac;
|
||||
out_no_funds=TRUE;
|
||||
RETURN;
|
||||
END IF;
|
||||
END IF;
|
||||
|
||||
UPDATE reserves SET
|
||||
current_balance_val=my_balance_val
|
||||
,current_balance_frac=my_balance_frac
|
||||
,gc_date=my_reserve_expiration + in_reserve_gc_delay
|
||||
,expiration_date=my_reserve_expiration
|
||||
,purses_allowed=my_purses_allowed
|
||||
WHERE
|
||||
reserve_pub=in_reserve_pub;
|
||||
|
||||
out_final_expiration=my_reserve_expiration;
|
||||
out_open_cost_val = my_cost_val;
|
||||
out_open_cost_frac = my_cost_frac;
|
||||
out_no_funds=FALSE;
|
||||
RETURN;
|
||||
|
||||
END $$;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user