ensure consistent order between CREATE, INSERT and SELECT statements

This commit is contained in:
Christian Grothoff 2015-06-03 16:29:30 +02:00
parent f0e097c9a8
commit 89793f8180

View File

@ -304,10 +304,8 @@ postgres_create_tables (void *cls,
key (coin_pub), the melting session, the index of this coin in that key (coin_pub), the melting session, the index of this coin in that
session, the signature affirming the melting and the amount that session, the signature affirming the melting and the amount that
this coin contributed to the melting session. this coin contributed to the melting session.
TODO: is this amount with or without fees? Should probably TODO: Should we include
be total (with fee), but then we should make that explicit both amounts (also the fee explicitly) in the table
in the name. Also should we not include
both amounts (or also the fee explicitly) in the table
to ease auditing of operations? (#3812) to ease auditing of operations? (#3812)
*/ */
SQLEXEC("CREATE TABLE IF NOT EXISTS refresh_melts " SQLEXEC("CREATE TABLE IF NOT EXISTS refresh_melts "
@ -315,9 +313,9 @@ postgres_create_tables (void *cls,
",session BYTEA NOT NULL REFERENCES refresh_sessions (session_hash)" ",session BYTEA NOT NULL REFERENCES refresh_sessions (session_hash)"
",oldcoin_index INT2 NOT NULL" ",oldcoin_index INT2 NOT NULL"
",coin_sig BYTEA NOT NULL CHECK(LENGTH(coin_sig)=64)" ",coin_sig BYTEA NOT NULL CHECK(LENGTH(coin_sig)=64)"
",amount_val INT8 NOT NULL" ",amount_with_fee_val INT8 NOT NULL"
",amount_frac INT8 NOT NULL" ",amount_with_fee_frac INT8 NOT NULL"
",amount_curr VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL" ",amount_with_fee_curr VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL"
",PRIMARY KEY (session, oldcoin_index)" /* a coin can be used only ",PRIMARY KEY (session, oldcoin_index)" /* a coin can be used only
once in a refresh session */ once in a refresh session */
") "); ") ");
@ -359,9 +357,9 @@ postgres_create_tables (void *cls,
(#3815) */ (#3815) */
SQLEXEC("CREATE TABLE IF NOT EXISTS refresh_commit_coin " SQLEXEC("CREATE TABLE IF NOT EXISTS refresh_commit_coin "
"(session_hash BYTEA NOT NULL REFERENCES refresh_sessions (session_hash) " "(session_hash BYTEA NOT NULL REFERENCES refresh_sessions (session_hash) "
",link_vector_enc BYTEA NOT NULL"
",newcoin_index INT2 NOT NULL"
",cnc_index INT2 NOT NULL" ",cnc_index INT2 NOT NULL"
",newcoin_index INT2 NOT NULL"
",link_vector_enc BYTEA NOT NULL"
",coin_ev BYTEA NOT NULL" ",coin_ev BYTEA NOT NULL"
")"); ")");
/* Table with the signatures over coins generated during a refresh /* Table with the signatures over coins generated during a refresh
@ -599,22 +597,8 @@ postgres_prepare (PGconn *db_conn)
") VALUES " ") VALUES "
"($1,$2,$3);", "($1,$2,$3);",
3, NULL); 3, NULL);
/* Store information about the desired denominations for a
refresh operation, used in #postgres_insert_refresh_order() */
PREPARE ("get_refresh_commit_link",
"SELECT"
" transfer_pub"
",link_secret_enc"
" FROM refresh_commit_link"
" WHERE session_hash=$1 AND cnc_index=$2 AND oldcoin_index=$3",
3, NULL);
PREPARE ("get_refresh_commit_coin",
"SELECT"
" link_vector_enc"
",coin_ev"
" FROM refresh_commit_coin"
" WHERE session_hash=$1 AND cnc_index=$2 AND newcoin_index=$3",
3, NULL);
PREPARE ("insert_refresh_order", PREPARE ("insert_refresh_order",
"INSERT INTO refresh_order " "INSERT INTO refresh_order "
"(newcoin_index " "(newcoin_index "
@ -623,40 +607,51 @@ postgres_prepare (PGconn *db_conn)
") VALUES " ") VALUES "
"($1, $2, $3);", "($1, $2, $3);",
3, NULL); 3, NULL);
/* Obtain information about the desired denominations for a
refresh operation, used in #postgres_get_refresh_order() */
PREPARE ("get_refresh_order",
"SELECT denom_pub"
" FROM refresh_order"
" WHERE session_hash=$1 AND newcoin_index=$2",
2, NULL);
/* Used in #postgres_insert_refresh_melt to store information
about melted coins */
PREPARE ("insert_refresh_melt", PREPARE ("insert_refresh_melt",
"INSERT INTO refresh_melts " "INSERT INTO refresh_melts "
"(coin_pub " "(coin_pub "
",session" ",session"
",oldcoin_index " ",oldcoin_index "
",coin_sig " ",coin_sig "
",amount_val " ",amount_with_fee_val "
",amount_frac " ",amount_with_fee_frac "
",amount_curr " ",amount_with_fee_curr "
") VALUES " ") VALUES "
"($1, $2, $3, $4, $5, $6, $7);", "($1, $2, $3, $4, $5, $6, $7);",
7, NULL); 7, NULL);
/* Used in #postgres_get_refresh_melt to obtain information
about melted coins */
PREPARE ("get_refresh_melt", PREPARE ("get_refresh_melt",
"SELECT" "SELECT"
" coin_pub" " coin_pub"
",coin_sig" ",coin_sig"
",amount_val" ",amount_with_fee_val"
",amount_frac" ",amount_with_fee_frac"
",amount_curr" ",amount_with_fee_curr"
" FROM refresh_melts " " FROM refresh_melts "
"WHERE session=$1 AND oldcoin_index=$2", "WHERE session=$1 AND oldcoin_index=$2",
2, NULL); 2, NULL);
/* FIXME: should have a way to query the 'refresh_melts' by /* FIXME: should have a way to query the 'refresh_melts' by
coin public key (#3813) */ coin public key (#3813) */
PREPARE ("get_refresh_order", /* FIXME: 'get_refresh_collectable' is not used anywhere!
"SELECT denom_pub " Should be needed for /refresh/link at least. */
"FROM refresh_order "
"WHERE session_hash=$1 AND newcoin_index=$2",
2, NULL);
PREPARE ("get_refresh_collectable", PREPARE ("get_refresh_collectable",
"SELECT ev_sig " "SELECT ev_sig "
"FROM refresh_collectable " "FROM refresh_collectable "
"WHERE session_hash=$1 AND newcoin_index=$2", "WHERE session_hash=$1 AND newcoin_index=$2",
2, NULL); 2, NULL);
/* Used in #postgres_insert_refresh_commit_links() to
store commitments */
PREPARE ("insert_refresh_commit_link", PREPARE ("insert_refresh_commit_link",
"INSERT INTO refresh_commit_link " "INSERT INTO refresh_commit_link "
"(session_hash" "(session_hash"
@ -667,56 +662,38 @@ postgres_prepare (PGconn *db_conn)
") VALUES " ") VALUES "
"($1, $2, $3, $4, $5);", "($1, $2, $3, $4, $5);",
5, NULL); 5, NULL);
/* NOTE: order differs from 'CREATE TABLE' statement, might want to fix */ /* Used in #postgres_get_refresh_commit_links() to
retrieve original commitments during /refresh/reveal */
PREPARE ("get_refresh_commit_link",
"SELECT"
" transfer_pub"
",link_secret_enc"
" FROM refresh_commit_link"
" WHERE session_hash=$1 AND cnc_index=$2 AND oldcoin_index=$3",
3, NULL);
/* Used in #postgres_insert_refresh_commit_coins() to
store coin commitments. */
PREPARE ("insert_refresh_commit_coin", PREPARE ("insert_refresh_commit_coin",
"INSERT INTO refresh_commit_coin " "INSERT INTO refresh_commit_coin "
"(session_hash" "(session_hash"
",coin_ev"
",cnc_index" ",cnc_index"
",newcoin_index" ",newcoin_index"
",link_vector_enc" ",link_vector_enc"
",coin_ev"
") VALUES " ") VALUES "
"($1, $2, $3, $4, $5);", "($1, $2, $3, $4, $5);",
5, NULL); 5, NULL);
#if 0 /* FIXME: not complete yet */ /* Used in #postgres_get_refresh_commit_coins() to
PREPARE ("insert_refresh_collectable", retrieve the original coin envelopes, to either be
"INSERT INTO refresh_collectable " verified or signed. */
"(session_hash" PREPARE ("get_refresh_commit_coin",
",newcoin_index" "SELECT"
",ev_sig" " link_vector_enc"
") VALUES " ",coin_ev"
"($1, $2, $3)", " FROM refresh_commit_coin"
" WHERE session_hash=$1 AND cnc_index=$2 AND newcoin_index=$3",
3, NULL); 3, NULL);
PREPARE ("get_link",
"SELECT link_vector_enc, ro.denom_pub, ev_sig "
"FROM refresh_melt 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_collectable rc USING (session_hash) "
"WHERE rm.coin_pub=$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"
" ) ",
1, NULL);
PREPARE ("get_transfer",
"SELECT transfer_pub, link_secret_enc "
"FROM refresh_melt 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"
" ) ",
1, NULL);
#endif
PREPARE ("insert_deposit", PREPARE ("insert_deposit",
"INSERT INTO deposits " "INSERT INTO deposits "
"(coin_pub" "(coin_pub"
@ -770,6 +747,46 @@ postgres_prepare (PGconn *db_conn)
" WHERE coin_pub=$1", " WHERE coin_pub=$1",
1, NULL); 1, NULL);
#if 0 /* FIXME: not complete yet */
PREPARE ("insert_refresh_collectable",
"INSERT INTO refresh_collectable "
"(session_hash"
",newcoin_index"
",ev_sig"
") VALUES "
"($1, $2, $3)",
3, NULL);
PREPARE ("get_link",
"SELECT link_vector_enc, ro.denom_pub, ev_sig "
"FROM refresh_melt 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_collectable rc USING (session_hash) "
"WHERE rm.coin_pub=$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"
" ) ",
1, NULL);
PREPARE ("get_transfer",
"SELECT transfer_pub, link_secret_enc "
"FROM refresh_melt 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"
" ) ",
1, NULL);
#endif
return GNUNET_OK; return GNUNET_OK;
#undef PREPARE #undef PREPARE
} }
@ -1901,7 +1918,7 @@ postgres_get_refresh_melt (void *cls,
PGresult *result; PGresult *result;
struct TALER_CoinPublicInfo coin; struct TALER_CoinPublicInfo coin;
struct TALER_CoinSpendSignatureP coin_sig; struct TALER_CoinSpendSignatureP coin_sig;
struct TALER_Amount amount; struct TALER_Amount amount_with_fee;
uint16_t oldcoin_index_nbo = htons (oldcoin_index); uint16_t oldcoin_index_nbo = htons (oldcoin_index);
struct TALER_PQ_QueryParam params[] = { struct TALER_PQ_QueryParam params[] = {
TALER_PQ_query_param_auto_from_type (session_hash), TALER_PQ_query_param_auto_from_type (session_hash),
@ -1932,7 +1949,7 @@ postgres_get_refresh_melt (void *cls,
struct TALER_PQ_ResultSpec rs[] = { struct TALER_PQ_ResultSpec rs[] = {
TALER_PQ_result_spec_auto_from_type ("coin_pub", &coin.coin_pub), TALER_PQ_result_spec_auto_from_type ("coin_pub", &coin.coin_pub),
TALER_PQ_result_spec_auto_from_type ("coin_sig", &coin_sig), TALER_PQ_result_spec_auto_from_type ("coin_sig", &coin_sig),
TALER_PQ_result_spec_amount ("amount", &amount), TALER_PQ_result_spec_amount ("amount_with_fee", &amount_with_fee),
TALER_PQ_result_spec_end TALER_PQ_result_spec_end
}; };
if (GNUNET_OK != TALER_PQ_extract_result (result, rs, 0)) if (GNUNET_OK != TALER_PQ_extract_result (result, rs, 0))
@ -1953,8 +1970,8 @@ postgres_get_refresh_melt (void *cls,
melt->coin_sig = coin_sig; melt->coin_sig = coin_sig;
if (session_hash != &melt->session_hash) if (session_hash != &melt->session_hash)
melt->session_hash = *session_hash; melt->session_hash = *session_hash;
melt->amount_with_fee = amount; melt->amount_with_fee = amount_with_fee;
/* FIXME: melt->melt_fee = ?? */ /* FIXME: melt->melt_fee = ??, #3812 */
return GNUNET_OK; return GNUNET_OK;
} }
@ -2096,12 +2113,12 @@ postgres_insert_refresh_commit_coins (void *cls,
uint16_t newcoin_index_nbo = htons (num_newcoins); uint16_t newcoin_index_nbo = htons (num_newcoins);
struct TALER_PQ_QueryParam params[] = { struct TALER_PQ_QueryParam params[] = {
TALER_PQ_query_param_auto_from_type(session_hash), TALER_PQ_query_param_auto_from_type(session_hash),
TALER_PQ_query_param_fixed_size(commit_coins->coin_ev, commit_coins->coin_ev_size),
TALER_PQ_query_param_auto_from_type(&cnc_index_nbo), TALER_PQ_query_param_auto_from_type(&cnc_index_nbo),
TALER_PQ_query_param_auto_from_type(&newcoin_index_nbo), TALER_PQ_query_param_auto_from_type(&newcoin_index_nbo),
TALER_PQ_query_param_fixed_size (commit_coins->refresh_link->coin_priv_enc, TALER_PQ_query_param_fixed_size (commit_coins->refresh_link->coin_priv_enc,
commit_coins->refresh_link->blinding_key_enc_size + commit_coins->refresh_link->blinding_key_enc_size +
sizeof (struct TALER_CoinSpendPrivateKeyP)), sizeof (struct TALER_CoinSpendPrivateKeyP)),
TALER_PQ_query_param_fixed_size(commit_coins->coin_ev, commit_coins->coin_ev_size),
TALER_PQ_query_param_end TALER_PQ_query_param_end
}; };
@ -2137,6 +2154,7 @@ postgres_insert_refresh_commit_coins (void *cls,
* @param cnc_index set index (1st dimension) * @param cnc_index set index (1st dimension)
* @param newcoin_index coin index (2nd dimension), corresponds to refreshed (new) coins * @param newcoin_index coin index (2nd dimension), corresponds to refreshed (new) coins
* @param[out] cc coin commitment to return * @param[out] cc coin commitment to return
* FIXME: should we not take an array of 'cc's and return all at once?
* @return #GNUNET_OK on success * @return #GNUNET_OK on success
* #GNUNET_NO if not found * #GNUNET_NO if not found
* #GNUNET_SYSERR on error * #GNUNET_SYSERR on error
@ -2182,8 +2200,8 @@ postgres_get_refresh_commit_coins (void *cls,
} }
struct TALER_PQ_ResultSpec rs[] = { struct TALER_PQ_ResultSpec rs[] = {
TALER_PQ_result_spec_variable_size("coin_ev", &c_buf, &c_buf_size),
TALER_PQ_result_spec_variable_size("link_vector_enc", &rl_buf, &rl_buf_size), TALER_PQ_result_spec_variable_size("link_vector_enc", &rl_buf, &rl_buf_size),
TALER_PQ_result_spec_variable_size("coin_ev", &c_buf, &c_buf_size),
TALER_PQ_result_spec_end TALER_PQ_result_spec_end
}; };
if (GNUNET_YES != TALER_PQ_extract_result (result, rs, 0)) if (GNUNET_YES != TALER_PQ_extract_result (result, rs, 0))
@ -2215,6 +2233,7 @@ postgres_get_refresh_commit_coins (void *cls,
* @param cls the `struct PostgresClosure` with the plugin-specific state * @param cls the `struct PostgresClosure` with the plugin-specific state
* @param session database connection to use * @param session database connection to use
* @param session_hash hash to identify refresh session * @param session_hash hash to identify refresh session
* FIXME: i/j -- better names, please!
* @param i set index (1st dimension) * @param i set index (1st dimension)
* @param j coin index (2nd dimension), corresponds to melted (old) coins * @param j coin index (2nd dimension), corresponds to melted (old) coins
* @param commit_link link information to store * @param commit_link link information to store