diff options
| author | Christian Grothoff <christian@grothoff.org> | 2022-05-17 08:50:28 +0200 | 
|---|---|---|
| committer | Christian Grothoff <christian@grothoff.org> | 2022-05-17 08:50:42 +0200 | 
| commit | 802649c2703cb1b9991316073ca0b9e20cebe16f (patch) | |
| tree | 590eb7af77af7350c8e6101dd962260359dcd32a /src/exchangedb | |
| parent | f089bbe5366553c15758200febd6c77a941272f2 (diff) | |
-add DB logic for purse expiration
Diffstat (limited to 'src/exchangedb')
| -rw-r--r-- | src/exchangedb/exchange-0001-part.sql | 69 | ||||
| -rw-r--r-- | src/exchangedb/plugin_exchangedb_postgres.c | 36 | 
2 files changed, 100 insertions, 5 deletions
| diff --git a/src/exchangedb/exchange-0001-part.sql b/src/exchangedb/exchange-0001-part.sql index dc4f29c8..97c26cb0 100644 --- a/src/exchangedb/exchange-0001-part.sql +++ b/src/exchangedb/exchange-0001-part.sql @@ -1977,7 +1977,7 @@ BEGIN  END;  $$; -COMMENT ON FUNCTION exchange_do_recoup_by_reserve  +COMMENT ON FUNCTION exchange_do_recoup_by_reserve    IS 'Recoup by reserve as a function to make sure we hit only the needed partition and not all when joining as joins on distributed tables fetch ALL rows from the shards'; @@ -2505,7 +2505,8 @@ UPDATE known_coins           THEN 1           ELSE 0           END -  WHERE coin_pub=in_coin_pub; +  WHERE coin_pub=in_coin_pub +  LIMIT 1; -- just to be extra safe  out_conflict=FALSE; @@ -3360,6 +3361,70 @@ BEGIN  END $$; + +CREATE OR REPLACE FUNCTION exchange_do_expire_purse( +  IN in_partner_id INT8, +  IN in_start_time INT8, +  IN in_end_time INT8, +  OUT out_found BOOLEAN) +LANGUAGE plpgsql +AS $$ +DECLARE +  my_purse_pub BYTEA; +DECLARE +  my_deposit record; +BEGIN + +UPDATE purse_requests + SET refunded=TRUE, +     finished=TRUE + WHERE (purse_expiration >= in_start_time) AND +       (purse_expiration < in_end_time) AND +       (NOT finished) AND +       (NOT refunded) + RETURNING purse_pub +   ,in_reserve_quota +   ,flags + INTO my_purse_pub +   ,my_rq +   ,my_flags; +out_found = FOUND; +IF NOT FOUND +THEN +  RETURN; +END IF; + +-- restore balance to each coin deposited into the purse +FOR my_deposit IN +  SELECT coin_pub +        ,amount_with_fee_val +        ,amount_with_fee_frac +    FROM purse_deposits +  WHERE purse_pub = my_purse_pub +LOOP +  UPDATE +    remaining_frac=remaining_frac+my_deposit.amount_with_fee_frac +     - CASE +       WHEN remaining_frac+my_deposit.amount_with_fee_frac >= 100000000 +       THEN 100000000 +       ELSE 0 +       END, +    remaining_val=remaining_val+my_deposit.amount_with_fee_val +     + CASE +       WHEN remaining_frac+my_deposit.amount_with_fee_frac >= 100000000 +       THEN 1 +       ELSE 0 +       END +    FROM known_coins +    WHERE coin_pub = my_deposit.coin_pub +    LIMIT 1; -- just to be extra safe +  END LOOP; +END $$; + +COMMENT ON FUNCTION exchange_do_expire_purse(INT8,INT8) +  IS 'Finds an expired purse in the given time range and refunds the coins (if any).'; + +  CREATE OR REPLACE FUNCTION exchange_do_history_request(    IN in_reserve_pub BYTEA,    IN in_reserve_sig BYTEA, diff --git a/src/exchangedb/plugin_exchangedb_postgres.c b/src/exchangedb/plugin_exchangedb_postgres.c index ab282f4f..2c113cf1 100644 --- a/src/exchangedb/plugin_exchangedb_postgres.c +++ b/src/exchangedb/plugin_exchangedb_postgres.c @@ -904,6 +904,14 @@ prepare_statements (struct PostgresClosure *pg)        " FROM exchange_do_purse_deposit"        " ($1,$2,$3,$4,$5,$6,$7,$8);",        8), +    /* used in #postgres_expire_purse() */ +    GNUNET_PQ_make_prepare ( +      "call_expire_purse", +      "SELECT " +      " out_found AS found" +      " FROM exchange_do_expire_purse" +      " ($1,$2);", +      2),      /* Used in #postgres_do_melt() to melt a coin. */      GNUNET_PQ_make_prepare (        "call_melt", @@ -13337,7 +13345,7 @@ postgres_select_contract_by_purse (void *cls,   * @param[out] in_conflict set to true if @a econtract   *             conflicts with an existing contract;   *             in this case, the return value will be - *             #GNUNET_DB_STATUS_SUCCESS_ONE despite the failure + *             #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT despite the failure   * @return transaction status code   */  static enum GNUNET_DB_QueryStatus @@ -13568,8 +13576,30 @@ postgres_expire_purse (    struct GNUNET_TIME_Absolute start_time,    struct GNUNET_TIME_Absolute end_time)  { -  GNUNET_break (0); -  return GNUNET_DB_STATUS_HARD_ERROR; +  struct PostgresClosure *pg = cls; +  struct GNUNET_PQ_QueryParam params[] = { +    GNUNET_PQ_query_param_absolute_time (&start_time), +    GNUNET_PQ_query_param_absolute_time (&end_time), +    GNUNET_PQ_query_param_end +  }; +  bool found = false; +  struct GNUNET_PQ_ResultSpec rs[] = { +    GNUNET_PQ_result_spec_bool ("found", +                                &found), +    GNUNET_PQ_result_spec_end +  }; +  enum GNUNET_DB_QueryStatus qs; + +  qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn, +                                                 "call_expire_purse", +                                                 params, +                                                 rs); +  if (qs < 0) +    return qs; +  GNUNET_assert (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs); +  return found +    ? GNUNET_DB_STATUS_SUCCESS_ONE_RESULT +    : GNUNET_DB_STATUS_SUCCESS_NO_RESULTS;  } | 
