diff --git a/src/exchangedb/Makefile.am b/src/exchangedb/Makefile.am index 620e52352..71c058c13 100644 --- a/src/exchangedb/Makefile.am +++ b/src/exchangedb/Makefile.am @@ -301,6 +301,7 @@ noinst_PROGRAMS = \ AM_TESTS_ENVIRONMENT=export TALER_PREFIX=$${TALER_PREFIX:-@libdir@};export PATH=$${TALER_PREFIX:-@prefix@}/bin:$$PATH; TESTS = \ $(check_PROGRAMS) + test_exchangedb_postgres_SOURCES = \ test_exchangedb.c test_exchangedb_postgres_LDADD = \ @@ -375,5 +376,6 @@ perf_deposits_get_ready_postgres_LDADD = \ -lm \ $(XLIB) + EXTRA_test_exchangedb_postgres_DEPENDENCIES = \ libtaler_plugin_exchangedb_postgres.la diff --git a/src/exchangedb/exchange_do_get_link_data.sql b/src/exchangedb/exchange_do_get_link_data.sql index a76f4aaaf..08611a5ea 100644 --- a/src/exchangedb/exchange_do_get_link_data.sql +++ b/src/exchangedb/exchange_do_get_link_data.sql @@ -13,11 +13,7 @@ -- You should have received a copy of the GNU General Public License along with -- TALER; see the file COPYING. If not, see -- -/*DROP FUNCTION exchange_do_refund_by_coin( - IN in_coin_pub BYTEA, - IN in_merchant_pub BYTEA, - IN in_h_contract BYTEA -);*/ + CREATE OR REPLACE FUNCTION exchange_do_get_link_data( IN in_coin_pub BYTEA ) @@ -53,7 +49,11 @@ LOOP 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; + 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 $$; diff --git a/src/exchangedb/exchange_do_get_ready_deposit.sql b/src/exchangedb/exchange_do_get_ready_deposit.sql index b887571e4..001b69cb8 100644 --- a/src/exchangedb/exchange_do_get_ready_deposit.sql +++ b/src/exchangedb/exchange_do_get_ready_deposit.sql @@ -28,37 +28,42 @@ DECLARE var_coin_pub BYTEA; DECLARE var_deposit_serial_id INT8; -BEGIN - -SELECT +DECLARE + curs CURSOR + FOR + SELECT coin_pub ,deposit_serial_id + ,wire_deadline + ,shard + FROM deposits_by_ready + WHERE wire_deadline <= in_now + AND shard >=in_start_shard_now + AND shard <=in_end_shard_now + LIMIT 1; +DECLARE + i RECORD; +BEGIN +OPEN curs; +FETCH FROM curs INTO i; +IF NOT FOUND +THEN + RETURN; +END IF; +SELECT + payto_uri + ,merchant_pub INTO - var_coin_pub - ,var_deposit_serial_id - FROM deposits_by_ready - WHERE wire_deadline <= in_now - AND shard >= in_start_shard_now - AND shard <=in_end_shard_now + out_payto_uri + ,out_merchant_pub + FROM deposits dep + JOIN wire_targets wt + ON (wt.wire_target_h_payto=dep.wire_target_h_payto) + WHERE dep.coin_pub=i.coin_pub + AND dep.deposit_serial_id=i.deposit_serial_id ORDER BY - wire_deadline ASC - ,shard ASC; - -SELECT - merchant_pub - ,wire_target_h_payto - INTO - out_merchant_pub - ,var_wire_target_h_payto - FROM deposits - WHERE coin_pub=var_coin_pub - AND deposit_serial_id=var_deposit_serial_id; - -SELECT - payto_uri - INTO out_payto_uri - FROM wire_targets - WHERE wire_target_h_payto=var_wire_target_h_payto; + i.wire_deadline ASC + ,i.shard ASC; RETURN; END $$; diff --git a/src/exchangedb/pg_ensure_coin_known.c b/src/exchangedb/pg_ensure_coin_known.c index 6b2385adb..7ad37bf1d 100644 --- a/src/exchangedb/pg_ensure_coin_known.c +++ b/src/exchangedb/pg_ensure_coin_known.c @@ -60,12 +60,12 @@ TEH_PG_ensure_coin_known (void *cls, &is_age_hash_null), GNUNET_PQ_result_spec_end }; - /* Used in #postgres_insert_known_coin() to store the denomination public - key and signature for a coin known to the exchange. + /* Used in #postgres_insert_known_coin() to store the denomination public + key and signature for a coin known to the exchange. - See also: - https://stackoverflow.com/questions/34708509/how-to-use-returning-with-on-conflict-in-postgresql/37543015#37543015 - */ + See also: + https://stackoverflow.com/questions/34708509/how-to-use-returning-with-on-conflict-in-postgresql/37543015#37543015 + */ PREPARE (pg, "insert_known_coin", "WITH dd" diff --git a/src/exchangedb/pg_get_link_data.c b/src/exchangedb/pg_get_link_data.c index a07954335..f167b3b6e 100644 --- a/src/exchangedb/pg_get_link_data.c +++ b/src/exchangedb/pg_get_link_data.c @@ -58,7 +58,10 @@ struct LinkDataContext enum GNUNET_GenericReturnValue status; }; - +struct Results { + struct TALER_EXCHANGEDB_LinkList *pos; + struct TALER_TransferPublicKeyP transfer_pub; + }; /** * Free memory of the link data list. * @@ -82,6 +85,16 @@ free_link_data_list (void *cls, } } +static int +transfer_pub_cmp (const void *a, + const void *b) +{ + const struct Results *ra = a; + const struct Results *rb = b; + + return GNUNET_memcmp (&ra->transfer_pub, + &rb->transfer_pub); +} /** * Function to be called with the results of a SELECT statement @@ -97,6 +110,10 @@ add_ldl (void *cls, unsigned int num_results) { struct LinkDataContext *ldctx = cls; + struct Results *temp= GNUNET_new_array (num_results, + struct Results);; + unsigned int temp_off = 0; + for (int i = num_results - 1; i >= 0; i--) { @@ -141,9 +158,48 @@ add_ldl (void *cls, } TALER_blinded_planchet_free (&bp); } - if ( (NULL != ldctx->last) && - (0 == GNUNET_memcmp (&transfer_pub, - &ldctx->transfer_pub)) ) + temp[temp_off].pos = pos; + temp[temp_off].transfer_pub = transfer_pub; + temp_off++; + } + qsort (temp, + temp_off, + sizeof (struct Results), + transfer_pub_cmp); + for (unsigned int i = 0; i < temp_off; i++) + { + struct TALER_EXCHANGEDB_LinkList *pos; + struct Results *r = &temp[i]; + + pos = GNUNET_new (struct TALER_EXCHANGEDB_LinkList); + pos->orig_coin_link_sig = r->pos->orig_coin_link_sig; + pos->ev_sig = r->pos->ev_sig; + pos->coin_refresh_offset = r->pos->coin_refresh_offset; + pos->alg_values = r->pos->alg_values; + pos->denom_pub = r->pos->denom_pub; + pos->nonce = r->pos->nonce; + pos->have_nonce = r->pos->have_nonce; + + pos->next = ldctx->last; + ldctx->last = pos; + } + + if (NULL != ldctx->last) + { + ldctx->ldc (ldctx->ldc_cls, + &ldctx->transfer_pub, + ldctx->last); + free_link_data_list (ldctx, + ldctx->last); + } + + ldctx->last = NULL; + + GNUNET_free(temp); + /* + if ( (NULL != ldctx->last) && + (0 == GNUNET_memcmp (&transfer_pub, + &ldctx->transfer_pub)) ) { pos->next = ldctx->last; } @@ -161,6 +217,7 @@ add_ldl (void *cls, } ldctx->last = pos; } + GNUNET_free(temp);*/ } @@ -267,6 +324,54 @@ TEH_PG_get_link_data (void *cls, " ,freshcoin_index INT4" " ,coin_ev BYTEA);"); break; + case 3: + query="get_link_v3"; + PREPARE (pg, + query, + "SELECT " + " tp.transfer_pub" + ",denoms.denom_pub" + ",rrc.ev_sig" + ",rrc.ewv" + ",rrc.link_sig" + ",rrc.freshcoin_index" + ",rrc.coin_ev" + " FROM refresh_commitments" + " JOIN refresh_revealed_coins rrc" + " USING (melt_serial_id)" + " JOIN refresh_transfer_keys tp" + " USING (melt_serial_id)" + " JOIN denominations denoms" + " ON (rrc.denominations_serial = denoms.denominations_serial)" + " WHERE old_coin_pub=$1"); + break; + case 4: + query="get_link_v4"; + PREPARE (pg, + query, + "WITH rc AS MATERIALIZED (" + "SELECT" + " melt_serial_id" + " FROM refresh_commitments" + " WHERE old_coin_pub=$1" + ")" + "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" + " USING (melt_serial_id)" + " JOIN denominations denoms" + " USING (denominations_serial)" + " WHERE rrc.melt_serial_id = (SELECT melt_serial_id FROM rc)" + ); + break; default: GNUNET_break (0); return GNUNET_DB_STATUS_HARD_ERROR;