fix #3818 and handle coins being melted into multiple sessions
This commit is contained in:
parent
699f283ca7
commit
2ca543cd07
@ -576,6 +576,22 @@ struct TALER_MINTDB_MeltCommitment
|
||||
struct TALER_MINTDB_Session;
|
||||
|
||||
|
||||
/**
|
||||
* Function called with the session hashes and transfer secret
|
||||
* information for a given coin.
|
||||
*
|
||||
* @param cls closure
|
||||
* @param session_hash a session the coin was melted in
|
||||
* @param transfer_pub public transfer key for the session
|
||||
* @param shared_secret_enc set to shared secret for the session
|
||||
*/
|
||||
typedef void
|
||||
(*TALER_MINTDB_TransferDataCallback)(void *cls,
|
||||
const struct GNUNET_HashCode *session_hash,
|
||||
const struct TALER_TransferPublicKeyP *transfer_pub,
|
||||
const struct TALER_EncryptedLinkSecretP *shared_secret_enc);
|
||||
|
||||
|
||||
/**
|
||||
* @brief The plugin API, returned from the plugin's "init" function.
|
||||
* The argument given to "init" is simply a configuration handle.
|
||||
@ -1092,13 +1108,13 @@ struct TALER_MINTDB_Plugin
|
||||
*
|
||||
* @param cls the @e cls of this struct with the plugin-specific state
|
||||
* @param sesssion database connection
|
||||
* @param coin_pub public key to use to retrieve linkage data
|
||||
* @return all known link data for the coin
|
||||
* @param session_hash session to get linkage data for
|
||||
* @return all known link data for the session
|
||||
*/
|
||||
struct TALER_MINTDB_LinkDataList *
|
||||
(*get_link_data_list) (void *cls,
|
||||
struct TALER_MINTDB_Session *sesssion,
|
||||
const struct TALER_CoinSpendPublicKeyP *coin_pub);
|
||||
const struct GNUNET_HashCode *session_hash);
|
||||
|
||||
|
||||
/**
|
||||
@ -1122,8 +1138,8 @@ struct TALER_MINTDB_Plugin
|
||||
* @param cls the @e cls of this struct with the plugin-specific state
|
||||
* @param sesssion database connection
|
||||
* @param coin_pub public key of the coin
|
||||
* @param[out] transfer_pub public transfer key
|
||||
* @param[out] shared_secret_enc set to shared secret
|
||||
* @param tdc function to call for each session the coin was melted into
|
||||
* @param tdc_cls closure for @a tdc
|
||||
* @return #GNUNET_OK on success,
|
||||
* #GNUNET_NO on failure (not found)
|
||||
* #GNUNET_SYSERR on internal failure (database issue)
|
||||
@ -1132,8 +1148,9 @@ struct TALER_MINTDB_Plugin
|
||||
(*get_transfer) (void *cls,
|
||||
struct TALER_MINTDB_Session *sesssion,
|
||||
const struct TALER_CoinSpendPublicKeyP *coin_pub,
|
||||
struct TALER_TransferPublicKeyP *transfer_pub,
|
||||
struct TALER_EncryptedLinkSecretP *shared_secret_enc);
|
||||
TALER_MINTDB_TransferDataCallback tdc,
|
||||
void *tdc_cls);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
|
@ -1231,6 +1231,92 @@ TMH_DB_execute_refresh_reveal (struct MHD_Connection *connection,
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Closure for #handle_transfer_data().
|
||||
*/
|
||||
struct HTD_Context
|
||||
{
|
||||
|
||||
/**
|
||||
* Session link data we collect.
|
||||
*/
|
||||
struct TMH_RESPONSE_LinkSessionInfo *sessions;
|
||||
|
||||
/**
|
||||
* Database session. Nothing to do with @a sessions.
|
||||
*/
|
||||
struct TALER_MINTDB_Session *session;
|
||||
|
||||
/**
|
||||
* MHD connection, for queueing replies.
|
||||
*/
|
||||
struct MHD_Connection *connection;
|
||||
|
||||
/**
|
||||
* Number of sessions the coin was melted into.
|
||||
*/
|
||||
unsigned int num_sessions;
|
||||
|
||||
/**
|
||||
* How are we expected to proceed. #GNUNET_SYSERR if we
|
||||
* failed to return an error (should return #MHD_NO).
|
||||
* #GNUNET_NO if we succeeded in queueing an MHD error
|
||||
* (should return #MHD_YES from #TMH_execute_refresh_link),
|
||||
* #GNUNET_OK if we should call #TMH_RESPONSE_reply_refresh_link_success().
|
||||
*/
|
||||
int status;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Function called with the session hashes and transfer secret
|
||||
* information for a given coin. Gets the linkage data and
|
||||
* builds the reply for the client.
|
||||
*
|
||||
*
|
||||
* @param cls closure, a `struct HTD_Context`
|
||||
* @param session_hash a session the coin was melted in
|
||||
* @param transfer_pub public transfer key for the session
|
||||
* @param shared_secret_enc set to shared secret for the session
|
||||
*/
|
||||
static void
|
||||
handle_transfer_data (void *cls,
|
||||
const struct GNUNET_HashCode *session_hash,
|
||||
const struct TALER_TransferPublicKeyP *transfer_pub,
|
||||
const struct TALER_EncryptedLinkSecretP *shared_secret_enc)
|
||||
{
|
||||
struct HTD_Context *ctx = cls;
|
||||
struct TALER_MINTDB_LinkDataList *ldl;
|
||||
struct TMH_RESPONSE_LinkSessionInfo *lsi;
|
||||
|
||||
if (GNUNET_OK != ctx->status)
|
||||
return;
|
||||
ldl = TMH_plugin->get_link_data_list (TMH_plugin->cls,
|
||||
ctx->session,
|
||||
session_hash);
|
||||
if (NULL == ldl)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
ctx->status = GNUNET_NO;
|
||||
if (MHD_NO ==
|
||||
TMH_RESPONSE_reply_json_pack (ctx->connection,
|
||||
MHD_HTTP_NOT_FOUND,
|
||||
"{s:s}",
|
||||
"error",
|
||||
"link data not found (link)"))
|
||||
ctx->status = GNUNET_SYSERR;
|
||||
return;
|
||||
}
|
||||
GNUNET_array_grow (ctx->sessions,
|
||||
ctx->num_sessions,
|
||||
ctx->num_sessions + 1);
|
||||
lsi = &ctx->sessions[ctx->num_sessions - 1];
|
||||
lsi->transfer_pub = *transfer_pub;
|
||||
lsi->shared_secret_enc = *shared_secret_enc;
|
||||
lsi->ldl = ldl;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Execute a "/refresh/link". Returns the linkage information that
|
||||
* will allow the owner of a coin to follow the refresh trail to
|
||||
@ -1244,52 +1330,47 @@ int
|
||||
TMH_DB_execute_refresh_link (struct MHD_Connection *connection,
|
||||
const struct TALER_CoinSpendPublicKeyP *coin_pub)
|
||||
{
|
||||
struct HTD_Context ctx;
|
||||
int res;
|
||||
struct TALER_MINTDB_Session *session;
|
||||
struct TALER_TransferPublicKeyP transfer_pub;
|
||||
struct TALER_EncryptedLinkSecretP shared_secret_enc;
|
||||
struct TALER_MINTDB_LinkDataList *ldl;
|
||||
unsigned int i;
|
||||
|
||||
if (NULL == (session = TMH_plugin->get_session (TMH_plugin->cls,
|
||||
if (NULL == (ctx.session = TMH_plugin->get_session (TMH_plugin->cls,
|
||||
GNUNET_NO)))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
return TMH_RESPONSE_reply_internal_db_error (connection);
|
||||
}
|
||||
ctx.connection = connection;
|
||||
ctx.num_sessions = 0;
|
||||
ctx.sessions = NULL;
|
||||
ctx.status = GNUNET_OK;
|
||||
res = TMH_plugin->get_transfer (TMH_plugin->cls,
|
||||
session,
|
||||
ctx.session,
|
||||
coin_pub,
|
||||
&transfer_pub,
|
||||
&shared_secret_enc);
|
||||
if (GNUNET_SYSERR == res)
|
||||
&handle_transfer_data,
|
||||
&ctx);
|
||||
if (GNUNET_SYSERR == ctx.status)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
return TMH_RESPONSE_reply_internal_db_error (connection);
|
||||
res = MHD_NO;
|
||||
goto cleanup;
|
||||
}
|
||||
if (GNUNET_NO == res)
|
||||
if (GNUNET_NO == ctx.status)
|
||||
{
|
||||
res = MHD_YES;
|
||||
goto cleanup;
|
||||
}
|
||||
GNUNET_assert (GNUNET_OK == ctx.status);
|
||||
if (0 == ctx.num_sessions)
|
||||
return TMH_RESPONSE_reply_arg_unknown (connection,
|
||||
"coin_pub");
|
||||
}
|
||||
GNUNET_assert (GNUNET_OK == res);
|
||||
|
||||
ldl = TMH_plugin->get_link_data_list (TMH_plugin->cls,
|
||||
session,
|
||||
coin_pub);
|
||||
if (NULL == ldl)
|
||||
{
|
||||
return TMH_RESPONSE_reply_json_pack (connection,
|
||||
MHD_HTTP_NOT_FOUND,
|
||||
"{s:s}",
|
||||
"error",
|
||||
"link data not found (link)");
|
||||
}
|
||||
res = TMH_RESPONSE_reply_refresh_link_success (connection,
|
||||
&transfer_pub,
|
||||
&shared_secret_enc,
|
||||
ldl);
|
||||
ctx.num_sessions,
|
||||
ctx.sessions);
|
||||
cleanup:
|
||||
for (i=0;i<ctx.num_sessions;i++)
|
||||
TMH_plugin->free_link_data_list (TMH_plugin->cls,
|
||||
ldl);
|
||||
ctx.sessions[i].ldl);
|
||||
GNUNET_free (ctx.sessions);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -908,58 +908,65 @@ TMH_RESPONSE_reply_refresh_reveal_missmatch (struct MHD_Connection *connection,
|
||||
* Send a response for "/refresh/link".
|
||||
*
|
||||
* @param connection the connection to send the response to
|
||||
* @param transfer_pub transfer public key
|
||||
* @param shared_secret_enc encrypted shared secret
|
||||
* @param ldl linked list with link data
|
||||
* @param num_sessions number of sessions the coin was used in
|
||||
* @param sessions array of @a num_session entries with
|
||||
* information for each session
|
||||
* @return a MHD result code
|
||||
*/
|
||||
int
|
||||
TMH_RESPONSE_reply_refresh_link_success (struct MHD_Connection *connection,
|
||||
const struct TALER_TransferPublicKeyP *transfer_pub,
|
||||
const struct TALER_EncryptedLinkSecretP *shared_secret_enc,
|
||||
const struct TALER_MINTDB_LinkDataList *ldl)
|
||||
unsigned int num_sessions,
|
||||
const struct TMH_RESPONSE_LinkSessionInfo *sessions)
|
||||
{
|
||||
const struct TALER_MINTDB_LinkDataList *pos;
|
||||
json_t *root;
|
||||
json_t *list;
|
||||
json_t *mlist;
|
||||
int res;
|
||||
unsigned int i;
|
||||
|
||||
list = json_array ();
|
||||
for (pos = ldl; NULL != pos; pos = pos->next)
|
||||
mlist = json_array ();
|
||||
for (i=0;i<num_sessions;i++)
|
||||
{
|
||||
const struct TALER_MINTDB_LinkDataList *pos;
|
||||
json_t *list = json_array ();
|
||||
|
||||
for (pos = sessions[i].ldl; NULL != pos; pos = pos->next)
|
||||
{
|
||||
json_t *obj;
|
||||
|
||||
obj = json_object ();
|
||||
json_object_set_new (obj,
|
||||
"link_enc",
|
||||
TALER_json_from_data (ldl->link_data_enc->coin_priv_enc,
|
||||
TALER_json_from_data (pos->link_data_enc->coin_priv_enc,
|
||||
sizeof (struct TALER_CoinSpendPrivateKeyP) +
|
||||
ldl->link_data_enc->blinding_key_enc_size));
|
||||
pos->link_data_enc->blinding_key_enc_size));
|
||||
json_object_set_new (obj,
|
||||
"denom_pub",
|
||||
TALER_json_from_rsa_public_key (ldl->denom_pub.rsa_public_key));
|
||||
TALER_json_from_rsa_public_key (pos->denom_pub.rsa_public_key));
|
||||
json_object_set_new (obj,
|
||||
"ev_sig",
|
||||
TALER_json_from_rsa_signature (ldl->ev_sig.rsa_signature));
|
||||
json_array_append_new (list, obj);
|
||||
TALER_json_from_rsa_signature (pos->ev_sig.rsa_signature));
|
||||
json_array_append_new (list,
|
||||
obj);
|
||||
}
|
||||
|
||||
root = json_object ();
|
||||
json_object_set_new (root,
|
||||
"new_coins",
|
||||
list);
|
||||
json_object_set_new (root,
|
||||
"transfer_pub",
|
||||
TALER_json_from_data (transfer_pub,
|
||||
TALER_json_from_data (&sessions[i].transfer_pub,
|
||||
sizeof (struct TALER_TransferPublicKeyP)));
|
||||
json_object_set_new (root,
|
||||
"secret_enc",
|
||||
TALER_json_from_data (shared_secret_enc,
|
||||
TALER_json_from_data (&sessions[i].shared_secret_enc,
|
||||
sizeof (struct TALER_EncryptedLinkSecretP)));
|
||||
json_array_append_new (mlist,
|
||||
root);
|
||||
}
|
||||
res = TMH_RESPONSE_reply_json (connection,
|
||||
root,
|
||||
mlist,
|
||||
MHD_HTTP_OK);
|
||||
json_decref (root);
|
||||
json_decref (mlist);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -334,20 +334,42 @@ TMH_RESPONSE_reply_refresh_reveal_missmatch (struct MHD_Connection *connection,
|
||||
const char *missmatch_object);
|
||||
|
||||
|
||||
/**
|
||||
* Information for each session a coin was melted into.
|
||||
*/
|
||||
struct TMH_RESPONSE_LinkSessionInfo
|
||||
{
|
||||
/**
|
||||
* Transfer public key of the coin.
|
||||
*/
|
||||
struct TALER_TransferPublicKeyP transfer_pub;
|
||||
|
||||
/**
|
||||
* Encrypted shared secret for decrypting the transfer secrets.
|
||||
*/
|
||||
struct TALER_EncryptedLinkSecretP shared_secret_enc;
|
||||
|
||||
/**
|
||||
* Linked data of coins being created in the session.
|
||||
*/
|
||||
struct TALER_MINTDB_LinkDataList *ldl;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Send a response for "/refresh/link".
|
||||
*
|
||||
* @param connection the connection to send the response to
|
||||
* @param transfer_pub transfer public key
|
||||
* @param shared_secret_enc encrypted shared secret
|
||||
* @param ldl linked list with link data
|
||||
* @param num_sessions number of sessions the coin was used in
|
||||
* @param sessions array of @a num_session entries with
|
||||
* information for each session
|
||||
* @return a MHD result code
|
||||
*/
|
||||
int
|
||||
TMH_RESPONSE_reply_refresh_link_success (struct MHD_Connection *connection,
|
||||
const struct TALER_TransferPublicKeyP *transfer_pub,
|
||||
const struct TALER_EncryptedLinkSecretP *shared_secret_enc,
|
||||
const struct TALER_MINTDB_LinkDataList *ldl);
|
||||
unsigned int num_sessions,
|
||||
const struct TMH_RESPONSE_LinkSessionInfo *sessions);
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -312,7 +312,7 @@ postgres_create_tables (void *cls,
|
||||
*/
|
||||
SQLEXEC("CREATE TABLE IF NOT EXISTS refresh_melts "
|
||||
"(coin_pub BYTEA NOT NULL REFERENCES known_coins (coin_pub)"
|
||||
",session BYTEA NOT NULL REFERENCES refresh_sessions (session_hash)"
|
||||
",session_hash BYTEA NOT NULL REFERENCES refresh_sessions (session_hash)"
|
||||
",oldcoin_index INT2 NOT NULL"
|
||||
",coin_sig BYTEA NOT NULL CHECK(LENGTH(coin_sig)=64)"
|
||||
",amount_with_fee_val INT8 NOT NULL"
|
||||
@ -321,7 +321,7 @@ postgres_create_tables (void *cls,
|
||||
",melt_fee_val INT8 NOT NULL"
|
||||
",melt_fee_frac INT8 NOT NULL"
|
||||
",melt_fee_curr VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL"
|
||||
",PRIMARY KEY (session, oldcoin_index)" /* a coin can be used only
|
||||
",PRIMARY KEY (session_hash, oldcoin_index)" /* a coin can be used only
|
||||
once in a refresh session */
|
||||
") ");
|
||||
/* Table with information about the desired denominations to be created
|
||||
@ -675,7 +675,7 @@ postgres_prepare (PGconn *db_conn)
|
||||
PREPARE ("insert_refresh_melt",
|
||||
"INSERT INTO refresh_melts "
|
||||
"(coin_pub "
|
||||
",session"
|
||||
",session_hash"
|
||||
",oldcoin_index "
|
||||
",coin_sig "
|
||||
",amount_with_fee_val "
|
||||
@ -700,12 +700,12 @@ postgres_prepare (PGconn *db_conn)
|
||||
",melt_fee_frac "
|
||||
",melt_fee_curr "
|
||||
" FROM refresh_melts"
|
||||
" WHERE session=$1 AND oldcoin_index=$2",
|
||||
" WHERE session_hash=$1 AND oldcoin_index=$2",
|
||||
2, NULL);
|
||||
/* Query the 'refresh_melts' by coin public key */
|
||||
PREPARE ("get_refresh_melt_by_coin",
|
||||
"SELECT"
|
||||
" session"
|
||||
" session_hash"
|
||||
/* ",oldcoin_index" // not needed */
|
||||
",coin_sig"
|
||||
",amount_with_fee_val"
|
||||
@ -845,43 +845,49 @@ postgres_prepare (PGconn *db_conn)
|
||||
") VALUES "
|
||||
"($1, $2, $3)",
|
||||
3, NULL);
|
||||
#if 0
|
||||
/* FIXME: not complete yet -- #3818... */
|
||||
/* Used in #postgres_get_link_data_list().
|
||||
FIXME: document how this is supposed to work... */
|
||||
/* Used in #postgres_get_link_data_list(). We use the session_hash
|
||||
to obtain the "noreveal_index" for that session, and then select
|
||||
the encrypted link vectors (link_vector_enc) and the
|
||||
corresponding signatures (ev_sig) and the denomination keys from
|
||||
the respective tables (namely refresh_melts and refresh_order)
|
||||
using the session_hash as the primary filter (on join) and the
|
||||
'noreveal_index' to constrain the selection on the commitment.
|
||||
We also want to get the triplet for each of the newcoins, so we
|
||||
have another constraint to ensure we get each triplet with
|
||||
matching "newcoin_index" values. NOTE: This may return many
|
||||
results, both for different sessions and for the different coins
|
||||
being minted in the refresh ops. NOTE: There may be more
|
||||
efficient ways to express the same query. */
|
||||
PREPARE ("get_link",
|
||||
"SELECT link_vector_enc,ro.denom_pub,ev_sig"
|
||||
" FROM refresh_melt rm "
|
||||
"SELECT link_vector_enc,ev_sig,ro.denom_pub"
|
||||
" FROM refresh_melts rm "
|
||||
" JOIN refresh_order ro USING (session_hash)"
|
||||
" JOIN refresh_commit_coin rcc USING (session_hash)"
|
||||
" JOIN refresh_sessions rs USING (session_hash)"
|
||||
" JOIN refresh_out rc USING (session_hash)"
|
||||
" WHERE rm.coin_pub=$1"
|
||||
" WHERE ro.session_hash=$1"
|
||||
" AND ro.newcoin_index=rcc.newcoin_index"
|
||||
" AND ro.newcoin_index=rc.newcoin_index"
|
||||
" AND rcc.cnc_index=rs.noreveal_index % ("
|
||||
" SELECT count(*) FROM refresh_commit_coin rcc2"
|
||||
" WHERE rcc2.newcoin_index=0"
|
||||
" AND rcc2.session_hash=rs.session_hash"
|
||||
" ) ",
|
||||
" AND rcc.cnc_index=rs.noreveal_index",
|
||||
1, NULL);
|
||||
/* Used in #postgres_get_transfer().
|
||||
FIXME: document how this is supposed to work... -- #3818 */
|
||||
/* Used in #postgres_get_transfer(). Given the public key of a
|
||||
melted coin, we obtain the corresponding encrypted link secret
|
||||
and the transfer public key. This is done by first finding
|
||||
the session_hash(es) of all sessions the coin was melted into,
|
||||
and then constraining the result to the selected "noreveal_index"
|
||||
and the transfer public key to the corresponding index of the
|
||||
old coin.
|
||||
NOTE: This may (in theory) return multiple results, one per session
|
||||
that the old coin was melted into. */
|
||||
PREPARE ("get_transfer",
|
||||
"SELECT transfer_pub,link_secret_enc"
|
||||
" FROM refresh_melt rm"
|
||||
"SELECT transfer_pub,link_secret_enc,session_hash"
|
||||
" FROM refresh_melts rm"
|
||||
" JOIN refresh_commit_link rcl USING (session_hash)"
|
||||
" JOIN refresh_sessions rs USING (session_hash)"
|
||||
" WHERE rm.coin_pub=$1"
|
||||
" AND rm.oldcoin_index = rcl.oldcoin_index"
|
||||
" AND rcl.cnc_index=rs.noreveal_index % ("
|
||||
" SELECT count(*) FROM refresh_commit_coin rcc2"
|
||||
" WHERE newcoin_index=0"
|
||||
" AND rcc2.session_hash=rm.session_hash"
|
||||
" )",
|
||||
" AND rcl.cnc_index=rs.noreveal_index",
|
||||
1, NULL);
|
||||
#endif
|
||||
|
||||
return GNUNET_OK;
|
||||
#undef PREPARE
|
||||
}
|
||||
@ -2848,20 +2854,20 @@ postgres_insert_refresh_out (void *cls,
|
||||
*
|
||||
* @param cls the `struct PostgresClosure` with the plugin-specific state
|
||||
* @param session database connection
|
||||
* @param coin_pub public key to use to retrieve linkage data
|
||||
* @return all known link data for the coin
|
||||
* @param session_hash refresh session to get linkage data for
|
||||
* @return all known link data for the session
|
||||
*/
|
||||
static struct TALER_MINTDB_LinkDataList *
|
||||
postgres_get_link_data_list (void *cls,
|
||||
struct TALER_MINTDB_Session *session,
|
||||
const struct TALER_CoinSpendPublicKeyP *coin_pub)
|
||||
const struct GNUNET_HashCode *session_hash)
|
||||
{
|
||||
struct TALER_MINTDB_LinkDataList *ldl;
|
||||
struct TALER_MINTDB_LinkDataList *pos;
|
||||
int i;
|
||||
int nrows;
|
||||
struct TALER_PQ_QueryParam params[] = {
|
||||
TALER_PQ_query_param_auto_from_type (coin_pub),
|
||||
TALER_PQ_query_param_auto_from_type (session_hash),
|
||||
TALER_PQ_query_param_end
|
||||
};
|
||||
PGresult *result;
|
||||
@ -2895,10 +2901,10 @@ postgres_get_link_data_list (void *cls,
|
||||
TALER_PQ_result_spec_variable_size ("link_vector_enc",
|
||||
&ld_buf,
|
||||
&ld_buf_size),
|
||||
TALER_PQ_result_spec_rsa_public_key ("denom_pub",
|
||||
&denom_pub),
|
||||
TALER_PQ_result_spec_rsa_signature ("ev_sig",
|
||||
&sig),
|
||||
TALER_PQ_result_spec_rsa_public_key ("denom_pub",
|
||||
&denom_pub),
|
||||
TALER_PQ_result_spec_end
|
||||
};
|
||||
|
||||
@ -2942,8 +2948,8 @@ postgres_get_link_data_list (void *cls,
|
||||
* @param cls the `struct PostgresClosure` with the plugin-specific state
|
||||
* @param session database connection
|
||||
* @param coin_pub public key of the coin
|
||||
* @param[out] transfer_pub public transfer key
|
||||
* @param[out] shared_secret_enc set to shared secret
|
||||
* @param tdc function to call for each session the coin was melted into
|
||||
* @param tdc_cls closure for @a tdc
|
||||
* @return #GNUNET_OK on success,
|
||||
* #GNUNET_NO on failure (not found)
|
||||
* #GNUNET_SYSERR on internal failure (database issue)
|
||||
@ -2952,14 +2958,16 @@ static int
|
||||
postgres_get_transfer (void *cls,
|
||||
struct TALER_MINTDB_Session *session,
|
||||
const struct TALER_CoinSpendPublicKeyP *coin_pub,
|
||||
struct TALER_TransferPublicKeyP *transfer_pub,
|
||||
struct TALER_EncryptedLinkSecretP *shared_secret_enc)
|
||||
TALER_MINTDB_TransferDataCallback tdc,
|
||||
void *tdc_cls)
|
||||
{
|
||||
struct TALER_PQ_QueryParam params[] = {
|
||||
TALER_PQ_query_param_auto_from_type (coin_pub),
|
||||
TALER_PQ_query_param_end
|
||||
};
|
||||
PGresult *result;
|
||||
int nrows;
|
||||
int i;
|
||||
|
||||
result = TALER_PQ_exec_prepared (session->conn,
|
||||
"get_transfer",
|
||||
@ -2971,23 +2979,21 @@ postgres_get_transfer (void *cls,
|
||||
PQclear (result);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
if (0 == PQntuples (result))
|
||||
nrows = PQntuples (result);
|
||||
if (0 == nrows)
|
||||
{
|
||||
PQclear (result);
|
||||
return GNUNET_NO;
|
||||
}
|
||||
if (1 != PQntuples (result))
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"got %d tuples from get_transfer\n",
|
||||
PQntuples (result));
|
||||
GNUNET_break (0);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
for (i=0;i<nrows;i++)
|
||||
{
|
||||
struct GNUNET_HashCode session_hash;
|
||||
struct TALER_TransferPublicKeyP transfer_pub;
|
||||
struct TALER_EncryptedLinkSecretP shared_secret_enc;
|
||||
struct TALER_PQ_ResultSpec rs[] = {
|
||||
TALER_PQ_result_spec_auto_from_type ("transfer_pub", transfer_pub),
|
||||
TALER_PQ_result_spec_auto_from_type ("link_secret_enc", shared_secret_enc),
|
||||
TALER_PQ_result_spec_auto_from_type ("transfer_pub", &transfer_pub),
|
||||
TALER_PQ_result_spec_auto_from_type ("link_secret_enc", &shared_secret_enc),
|
||||
TALER_PQ_result_spec_auto_from_type ("session_hash", &session_hash),
|
||||
TALER_PQ_result_spec_end
|
||||
};
|
||||
|
||||
@ -2998,6 +3004,10 @@ postgres_get_transfer (void *cls,
|
||||
GNUNET_break (0);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
tdc (tdc_cls,
|
||||
&session_hash,
|
||||
&transfer_pub,
|
||||
&shared_secret_enc);
|
||||
}
|
||||
PQclear (result);
|
||||
return GNUNET_OK;
|
||||
@ -3121,7 +3131,7 @@ postgres_get_coin_transactions (void *cls,
|
||||
melt = GNUNET_new (struct TALER_MINTDB_RefreshMelt);
|
||||
{
|
||||
struct TALER_PQ_ResultSpec rs[] = {
|
||||
TALER_PQ_result_spec_auto_from_type ("session",
|
||||
TALER_PQ_result_spec_auto_from_type ("session_hash",
|
||||
&melt->session_hash),
|
||||
/* oldcoin_index not needed */
|
||||
TALER_PQ_result_spec_auto_from_type ("coin_sig",
|
||||
|
Loading…
Reference in New Issue
Block a user