diff options
Diffstat (limited to 'src/exchangedb/pg_get_link_data.c')
-rw-r--r-- | src/exchangedb/pg_get_link_data.c | 224 |
1 files changed, 167 insertions, 57 deletions
diff --git a/src/exchangedb/pg_get_link_data.c b/src/exchangedb/pg_get_link_data.c index f15bf35a2..1b0cb3e20 100644 --- a/src/exchangedb/pg_get_link_data.c +++ b/src/exchangedb/pg_get_link_data.c @@ -48,41 +48,53 @@ struct LinkDataContext struct TALER_TransferPublicKeyP transfer_pub; /** - * Link data for @e transfer_pub - */ - struct TALER_EXCHANGEDB_LinkList *last; - - /** * Status, set to #GNUNET_SYSERR on errors, */ - int status; + enum GNUNET_GenericReturnValue status; }; /** * Free memory of the link data list. * - * @param cls the @e cls of this struct with the plugin-specific state (unused) * @param ldl link data list to release */ static void -free_link_data_list (void *cls, - struct TALER_EXCHANGEDB_LinkList *ldl) +free_link_data_list (struct TALER_EXCHANGEDB_LinkList *ldl) { struct TALER_EXCHANGEDB_LinkList *next; - (void) cls; while (NULL != ldl) { next = ldl->next; TALER_denom_pub_free (&ldl->denom_pub); TALER_blinded_denom_sig_free (&ldl->ev_sig); + TALER_denom_ewv_free (&ldl->alg_values); GNUNET_free (ldl); ldl = next; } } +struct Results +{ + struct TALER_EXCHANGEDB_LinkList *pos; + struct TALER_TransferPublicKeyP transfer_pub; +}; + + +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 * that has returned @a num_results results. @@ -97,18 +109,20 @@ 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--) { struct TALER_EXCHANGEDB_LinkList *pos; - struct TALER_TransferPublicKeyP transfer_pub; pos = GNUNET_new (struct TALER_EXCHANGEDB_LinkList); { struct TALER_BlindedPlanchet bp; struct GNUNET_PQ_ResultSpec rs[] = { GNUNET_PQ_result_spec_auto_from_type ("transfer_pub", - &transfer_pub), + &temp[temp_off].transfer_pub), GNUNET_PQ_result_spec_auto_from_type ("link_sig", &pos->orig_coin_link_sig), TALER_PQ_result_spec_blinded_denom_sig ("ev_sig", @@ -134,33 +148,52 @@ add_ldl (void *cls, ldctx->status = GNUNET_SYSERR; return; } - if (TALER_DENOMINATION_CS == bp.cipher) + if (GNUNET_CRYPTO_BSA_CS == bp.blinded_message->cipher) { - pos->nonce = bp.details.cs_blinded_planchet.nonce; + pos->nonce.cs_nonce + = bp.blinded_message->details.cs_blinded_message.nonce; pos->have_nonce = true; } TALER_blinded_planchet_free (&bp); } - if ( (NULL != ldctx->last) && - (0 == GNUNET_memcmp (&transfer_pub, - &ldctx->transfer_pub)) ) - { - pos->next = ldctx->last; - } - else + temp[temp_off].pos = pos; + temp_off++; + } + qsort (temp, + temp_off, + sizeof (struct Results), + &transfer_pub_cmp); + if (temp_off > 0) + { + struct TALER_EXCHANGEDB_LinkList *head = NULL; + + head = temp[0].pos; + for (unsigned int i = 1; i < temp_off; i++) { - if (NULL != ldctx->last) + struct TALER_EXCHANGEDB_LinkList *pos = temp[i].pos; + const struct TALER_TransferPublicKeyP *tp = &temp[i].transfer_pub; + + if (0 == GNUNET_memcmp (tp, + &temp[i - 1].transfer_pub)) + { + pos->next = head; + head = pos; + } + else { ldctx->ldc (ldctx->ldc_cls, - &ldctx->transfer_pub, - ldctx->last); - free_link_data_list (cls, - ldctx->last); + &temp[i - 1].transfer_pub, + head); + free_link_data_list (head); + head = pos; } - ldctx->transfer_pub = transfer_pub; } - ldctx->last = pos; + ldctx->ldc (ldctx->ldc_cls, + &temp[temp_off - 1].transfer_pub, + head); + free_link_data_list (head); } + GNUNET_free (temp); } @@ -177,11 +210,33 @@ TEH_PG_get_link_data (void *cls, }; enum GNUNET_DB_QueryStatus qs; struct LinkDataContext ldctx; + static int percent_refund = -2; + const char *query; - if (NULL == getenv ("NEW_LOGIC")) + if (-2 == percent_refund) + { + const char *mode = getenv ("TALER_POSTGRES_GET_LINK_DATA_LOGIC"); + char dummy; + + if ( (NULL==mode) || + (1 != sscanf (mode, + "%d%c", + &percent_refund, + &dummy)) ) + { + if (NULL != mode) + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Bad mode `%s' specified\n", + mode); + percent_refund = 4; /* Fastest known */ + } + } + switch (percent_refund) { + case 0: + query = "get_link"; PREPARE (pg, - "get_link", + query, "SELECT " " tp.transfer_pub" ",denoms.denom_pub" @@ -199,16 +254,16 @@ TEH_PG_get_link_data (void *cls, " ON (rrc.denominations_serial = denoms.denominations_serial)" " WHERE old_coin_pub=$1" " ORDER BY tp.transfer_pub, rrc.freshcoin_index ASC"); - } - - else - { + break; + case 1: + query = "get_link_v1"; PREPARE (pg, - "get_link", + query, "WITH rc AS MATERIALIZED (" "SELECT" - "* FROM refresh_commitments" - "WHERE old_coin_pub=$1" + " melt_serial_id" + " FROM refresh_commitments" + " WHERE old_coin_pub=$1" ")" "SELECT " " tp.transfer_pub" @@ -217,41 +272,96 @@ TEH_PG_get_link_data (void *cls, ",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)" + " ORDER BY tp.transfer_pub, rrc.freshcoin_index ASC"); + break; + case 2: + query = "get_link_v2"; + PREPARE (pg, + query, + "SELECT" + " *" + " FROM" + " exchange_do_get_link_data" + " ($1) " + " AS " + " (transfer_pub BYTEA" + " ,denom_pub BYTEA" + " ,ev_sig BYTEA" + " ,ewv BYTEA" + " ,link_sig BYTEA" + " ,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_revealed_coins rrc" + " FROM refresh_commitments" + " JOIN refresh_revealed_coins rrc" " USING (melt_serial_id)" " JOIN refresh_transfer_keys tp" " USING (melt_serial_id)" " JOIN denominations denoms" - " USING (denominations_serial)" - " ORDER BY tp.transfer_pub, rrc.freshcoin_index ASC"); + " 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; } ldctx.ldc = ldc; ldctx.ldc_cls = ldc_cls; - ldctx.last = NULL; ldctx.status = GNUNET_OK; qs = GNUNET_PQ_eval_prepared_multi_select (pg->conn, - "get_link", + query, params, &add_ldl, &ldctx); - if (NULL != ldctx.last) - { - if (GNUNET_OK == ldctx.status) - { - /* call callback one more time! */ - ldc (ldc_cls, - &ldctx.transfer_pub, - ldctx.last); - } - free_link_data_list (cls, - ldctx.last); - ldctx.last = NULL; - } if (GNUNET_OK != ldctx.status) return GNUNET_DB_STATUS_HARD_ERROR; return qs; } - - |