summaryrefslogtreecommitdiff
path: root/src/exchangedb/pg_get_link_data.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/exchangedb/pg_get_link_data.c')
-rw-r--r--src/exchangedb/pg_get_link_data.c224
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;
}
-
-