fix sync issues, add rudimentary test

This commit is contained in:
Christian Grothoff 2021-01-13 19:47:45 +01:00
parent 52513dcc26
commit e3a0bc0d1f
No known key found for this signature in database
GPG Key ID: 939E6BE1E29FC3CC
9 changed files with 263 additions and 163 deletions

View File

@ -190,7 +190,8 @@ taler_auditor_dbinit_CPPFLAGS = \
check_SCRIPTS = \
test-auditor.sh \
test-revocation.sh
test-revocation.sh \
test-sync.sh
.NOTPARALLEL:
TESTS = $(check_SCRIPTS)
@ -200,6 +201,8 @@ EXTRA_DIST = \
taler-helper-auditor-render.py \
auditor.conf \
test-auditor.conf \
test-sync-in.conf \
test-sync-out.conf \
generate-auditor-basedb.sh \
generate-revoke-basedb.sh \
generate-auditor-basedb.conf \

View File

@ -50,15 +50,45 @@ static unsigned int transaction_size = 512;
/**
* Number of records copied in this transaction.
*/
static unsigned int actual_size;
static unsigned long long actual_size;
static struct Table
/**
* Terminate once synchronization is achieved.
*/
static int exit_if_synced;
/**
* Information we track per replicated table.
*/
struct Table
{
/**
* Which table is this record about?
*/
enum TALER_EXCHANGEDB_ReplicatedTable rt;
/**
* Up to which record is the destination table synchronized.
*/
uint64_t start_serial;
/**
* Highest serial in the source table.
*/
uint64_t end_serial;
/**
* Marker for the end of the list of #tables.
*/
bool end;
} tables[] = {
};
/**
* Information about replicated tables.
*/
static struct Table tables[] = {
{ .rt = TALER_EXCHANGEDB_RT_DENOMINATIONS},
{ .rt = TALER_EXCHANGEDB_RT_DENOMINATION_REVOCATIONS},
{ .rt = TALER_EXCHANGEDB_RT_RESERVES},
@ -94,6 +124,11 @@ struct InsertContext
*/
struct TALER_EXCHANGEDB_Session *ds;
/**
* Table we are replicating.
*/
struct Table *table;
/**
* Set to error if insertion created an error.
*/
@ -123,10 +158,32 @@ do_insert (void *cls,
td);
if (0 >= qs)
{
switch (qs)
{
case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
GNUNET_assert (0);
break;
case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
"Failed to insert record into table %d: no change\n",
td->table);
break;
case GNUNET_DB_STATUS_SOFT_ERROR:
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
"Serialization error inserting record into table %d (will retry)\n",
td->table);
break;
case GNUNET_DB_STATUS_HARD_ERROR:
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Failed to insert record into table %d: hard error\n",
td->table);
break;
}
ctx->qs = qs;
return GNUNET_SYSERR;
}
actual_size++;
ctx->table->start_serial = td->serial;
return GNUNET_OK;
}
@ -175,9 +232,17 @@ transact (struct TALER_EXCHANGEDB_Session *ss,
return GNUNET_SYSERR;
for (unsigned int i = 0; ! tables[i].end; i++)
{
printf ("%d ", i);
fflush (stdout);
while (tables[i].start_serial < tables[i].end_serial)
struct Table *table = &tables[i];
if (table->start_serial == table->end_serial)
continue;
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Replicating table %d from %llu to %llu\n",
i,
(unsigned long long) table->start_serial,
(unsigned long long) table->end_serial);
ctx.table = table;
while (table->start_serial < table->end_serial)
{
enum GNUNET_DB_QueryStatus qs;
@ -193,21 +258,32 @@ transact (struct TALER_EXCHANGEDB_Session *ss,
return GNUNET_SYSERR;
qs = src->lookup_records_by_table (src->cls,
ss,
tables[i].rt,
tables[i].start_serial,
table->rt,
table->start_serial,
&do_insert,
&ctx);
if (ctx.qs < 0)
qs = ctx.qs;
if (GNUNET_DB_STATUS_HARD_ERROR == qs)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Failed to lookup records from table %d: hard error\n",
i);
global_ret = 3;
return GNUNET_SYSERR;
}
if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
{
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
"Serialization error looking up records from table %d (will retry)\n",
i);
return GNUNET_SYSERR; /* will retry */
}
if (0 == qs)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Failed to lookup records from table %d: no results\n",
i);
GNUNET_break (0); /* should be impossible */
global_ret = 4;
return GNUNET_SYSERR;
@ -219,16 +295,26 @@ transact (struct TALER_EXCHANGEDB_Session *ss,
qs = dst->commit (dst->cls,
ds);
if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
{
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
"Serialization error committing transaction on table %d (will retry)\n",
i);
continue;
}
if (GNUNET_DB_STATUS_HARD_ERROR == qs)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Hard error committing transaction on table %d\n",
i);
global_ret = 5;
return GNUNET_SYSERR;
}
}
}
/* we do not care about conflicting UPDATEs to src table, so safe to just rollback */
printf ("\n");
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Sync pass completed successfully with %llu updates\n",
actual_size);
return GNUNET_OK;
}
@ -248,18 +334,43 @@ do_sync (void *cls)
sync_task = NULL;
actual_size = 0;
ss = src->get_session (src->cls);
if (NULL == ss)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Failed to begin transaction with data source. Exiting\n");
return;
}
ds = dst->get_session (dst->cls);
if (NULL == ds)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Failed to begin transaction with data destination. Exiting\n");
return;
}
if (GNUNET_OK !=
transact (ss,
ds))
{
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Transaction failed, rolling back\n");
src->rollback (src->cls,
ss);
dst->rollback (dst->cls,
ds);
}
if (0 != global_ret)
{
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Transaction failed permanently, exiting\n");
return;
}
if ( (0 == actual_size) &&
(exit_if_synced) )
{
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Databases are synchronized. Exiting\n");
return;
}
if (actual_size < transaction_size / 2)
{
delay = GNUNET_TIME_STD_BACKOFF (delay);
@ -268,6 +379,10 @@ do_sync (void *cls)
{
delay = GNUNET_TIME_UNIT_ZERO;
}
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Next sync pass in %s\n",
GNUNET_STRINGS_relative_time_to_string (delay,
GNUNET_YES));
sync_task = GNUNET_SCHEDULER_add_delayed (delay,
&do_sync,
NULL);
@ -450,6 +565,7 @@ main (int argc,
{
char *src_cfgfile = NULL;
char *dst_cfgfile = NULL;
char *level = GNUNET_strdup ("WARNING");
struct GNUNET_CONFIGURATION_Handle *src_cfg;
struct GNUNET_CONFIGURATION_Handle *dst_cfg;
const struct GNUNET_GETOPT_CommandLineOption options[] = {
@ -466,15 +582,18 @@ main (int argc,
gettext_noop (
"target SIZE for a the number of records to copy in one transaction"),
&transaction_size),
GNUNET_GETOPT_option_flag (
't',
"terminate-when-synchronized",
gettext_noop (
"terminate as soon as the databases are synchronized"),
&exit_if_synced),
GNUNET_GETOPT_option_version (VERSION "-" VCS_VERSION),
GNUNET_GETOPT_option_loglevel (&level),
GNUNET_GETOPT_OPTION_END
};
TALER_gcrypt_init (); /* must trigger initialization manually at this point! */
GNUNET_assert (GNUNET_OK ==
GNUNET_log_setup ("taler-auditor-sync",
"WARNING",
NULL));
{
int ret;
@ -486,6 +605,11 @@ main (int argc,
if (GNUNET_SYSERR == ret)
return 1;
}
GNUNET_assert (GNUNET_OK ==
GNUNET_log_setup ("taler-auditor-sync",
level,
NULL));
GNUNET_free (level);
if (0 == strcmp (src_cfgfile,
dst_cfgfile))
{

View File

@ -0,0 +1,29 @@
[exchange]
#The DB plugin to use
DB = postgres
[exchangedb-postgres]
#The connection string the plugin has to use for connecting to the database
CONFIG = postgres:///talercheck-in
# Where are the SQL files to setup our tables?
SQL_DIR = $DATADIR/sql/exchange/
[taler]
CURRENCY = EUR
[exchangedb]
# After how long do we close idle reserves? The exchange
# and the auditor must agree on this value. We currently
# expect it to be globally defined for the whole system,
# as there is no way for wallets to query this value. Thus,
# it is only configurable for testing, and should be treated
# as constant in production.
IDLE_RESERVE_EXPIRATION_TIME = 4 weeks
# After how long do we forget about reserves? Should be above
# the legal expiration timeframe of withdrawn coins.
LEGAL_RESERVE_EXPIRATION_TIME = 7 years

View File

@ -0,0 +1,29 @@
[exchange]
#The DB plugin to use
DB = postgres
[exchangedb-postgres]
#The connection string the plugin has to use for connecting to the database
CONFIG = postgres:///talercheck-out
# Where are the SQL files to setup our tables?
SQL_DIR = $DATADIR/sql/exchange/
[taler]
CURRENCY = EUR
[exchangedb]
# After how long do we close idle reserves? The exchange
# and the auditor must agree on this value. We currently
# expect it to be globally defined for the whole system,
# as there is no way for wallets to query this value. Thus,
# it is only configurable for testing, and should be treated
# as constant in production.
IDLE_RESERVE_EXPIRATION_TIME = 4 weeks
# After how long do we forget about reserves? Should be above
# the legal expiration timeframe of withdrawn coins.
LEGAL_RESERVE_EXPIRATION_TIME = 7 years

42
src/auditor/test-sync.sh Executable file
View File

@ -0,0 +1,42 @@
#!/bin/sh
set -eu
echo -n "Testing synchronization logic ..."
dropdb talercheck-in 2> /dev/null || true
dropdb talercheck-out 2> /dev/null || true
createdb talercheck-in || exit 77
createdb talercheck-out || exit 77
echo -n "."
taler-exchange-dbinit -c test-sync-out.conf
echo -n "."
psql talercheck-in < auditor-basedb.sql >/dev/null 2> /dev/null
echo -n "."
taler-auditor-sync -s test-sync-in.conf -d test-sync-out.conf -t
for table in denominations denomination_revocations reserves reserves_in reserves_close reserves_out auditors auditor_denom_sigs exchange_sign_keys signkey_revocations known_coins refresh_commitments refresh_revealed_coins refresh_transfer_keys deposits refunds wire_out aggregation_tracking wire_fee recoup recoup_refresh
do
echo -n "."
CIN=`echo "SELECT COUNT(*) FROM $table" | psql talercheck-in -Aqt`
COUT=`echo "SELECT COUNT(*) FROM $table" | psql talercheck-out -Aqt`
if test ${CIN} != ${COUT}
then
dropdb talercheck-in
dropdb talercheck-out
echo "FAIL"
echo "Record count missmatch: $CIN / $COUT in table $table"
exit 1
fi
done
echo -n ". "
dropdb talercheck-in
dropdb talercheck-out
echo "PASS"
exit 0

View File

@ -437,11 +437,11 @@ irbt_cb_table_refresh_revealed_coins (struct PostgresClosure *pg,
&td->details.refresh_revealed_coins.freshcoin_index),
GNUNET_PQ_query_param_auto_from_type (
&td->details.refresh_revealed_coins.link_sig),
GNUNET_PQ_query_param_auto_from_type (&h_coin_ev),
GNUNET_PQ_query_param_fixed_size (
td->details.refresh_revealed_coins.coin_ev,
td->details.refresh_revealed_coins.
coin_ev_size),
GNUNET_PQ_query_param_auto_from_type (&h_coin_ev),
GNUNET_PQ_query_param_rsa_signature (
td->details.refresh_revealed_coins.ev_sig.rsa_signature),
GNUNET_PQ_query_param_uint64 (

View File

@ -436,14 +436,18 @@ lrbt_cb_table_auditor_denom_sigs (void *cls,
for (unsigned int i = 0; i<num_results; i++)
{
struct GNUNET_PQ_ResultSpec rs[] = {
GNUNET_PQ_result_spec_uint64 ("serial",
GNUNET_PQ_result_spec_uint64 (
"serial",
&td.serial),
GNUNET_PQ_result_spec_uint64 ("denominations_serial",
&td.details.auditor_denom_sigs.
denominations_serial),
GNUNET_PQ_result_spec_auto_from_type ("auditor_sig",
&td.details.auditor_denom_sigs.
auditor_sig),
GNUNET_PQ_result_spec_uint64 (
"auditor_uuid",
&td.details.auditor_denom_sigs.auditor_uuid),
GNUNET_PQ_result_spec_uint64 (
"denominations_serial",
&td.details.auditor_denom_sigs.denominations_serial),
GNUNET_PQ_result_spec_auto_from_type (
"auditor_sig",
&td.details.auditor_denom_sigs.auditor_sig),
GNUNET_PQ_result_spec_end
};
@ -1052,6 +1056,8 @@ lrbt_cb_table_wire_fee (void *cls,
struct GNUNET_PQ_ResultSpec rs[] = {
GNUNET_PQ_result_spec_uint64 ("serial",
&td.serial),
GNUNET_PQ_result_spec_string ("wire_method",
&td.details.wire_fee.wire_method),
TALER_PQ_result_spec_absolute_time ("start_date",
&td.details.wire_fee.start_date),
TALER_PQ_result_spec_absolute_time ("end_date",

View File

@ -1753,22 +1753,6 @@ postgres_get_session (void *cls)
GNUNET_PQ_make_prepare ("select_serial_by_table_denominations",
"SELECT"
" denominations_serial AS serial"
",denom_pub"
",master_sig"
",valid_from"
",expire_withdraw"
",expire_deposit"
",expire_legal"
",coin_val"
",coin_frac"
",fee_withdraw_val"
",fee_withdraw_frac"
",fee_deposit_val"
",fee_deposit_frac"
",fee_refresh_val"
",fee_refresh_frac"
",fee_refund_val"
",fee_refund_frac"
" FROM denominations"
" ORDER BY denominations_serial DESC"
" LIMIT 1;",
@ -1776,8 +1760,6 @@ postgres_get_session (void *cls)
GNUNET_PQ_make_prepare ("select_serial_by_table_denomination_revocations",
"SELECT"
" denom_revocations_serial_id AS serial"
",master_sig"
",denominations_serial"
" FROM denomination_revocations"
" ORDER BY denom_revocations_serial_id DESC"
" LIMIT 1;",
@ -1785,12 +1767,6 @@ postgres_get_session (void *cls)
GNUNET_PQ_make_prepare ("select_serial_by_table_reserves",
"SELECT"
" reserve_uuid AS serial"
",reserve_pub"
",account_details"
",current_balance_val"
",current_balance_frac"
",expiration_date"
",gc_date"
" FROM reserves"
" ORDER BY reserve_uuid DESC"
" LIMIT 1;",
@ -1798,13 +1774,6 @@ postgres_get_session (void *cls)
GNUNET_PQ_make_prepare ("select_serial_by_table_reserves_in",
"SELECT"
" reserve_in_serial_id AS serial"
",wire_reference"
",credit_val"
",credit_frac"
",sender_account_details"
",exchange_account_section"
",execution_date"
",reserve_uuid"
" FROM reserves_in"
" ORDER BY reserve_in_serial_id DESC"
" LIMIT 1;",
@ -1812,14 +1781,6 @@ postgres_get_session (void *cls)
GNUNET_PQ_make_prepare ("select_serial_by_table_reserves_close",
"SELECT"
" close_uuid AS serial"
",execution_date"
",wtid"
",receiver_account"
",amount_val"
",amount_frac"
",closing_fee_val"
",closing_fee_frac"
",reserve_uuid"
" FROM reserves_close"
" ORDER BY close_uuid DESC"
" LIMIT 1;",
@ -1827,14 +1788,6 @@ postgres_get_session (void *cls)
GNUNET_PQ_make_prepare ("select_serial_by_table_reserves_out",
"SELECT"
" reserve_out_serial_id AS serial"
",h_blind_ev"
",denom_sig"
",reserve_sig"
",execution_date"
",amount_with_fee_val"
",amount_with_fee_frac"
",reserve_uuid"
",denominations_serial"
" FROM reserves_out"
" ORDER BY reserve_out_serial_id DESC"
" LIMIT 1;",
@ -1842,11 +1795,6 @@ postgres_get_session (void *cls)
GNUNET_PQ_make_prepare ("select_serial_by_table_auditors",
"SELECT"
" auditor_uuid AS serial"
",auditor_pub"
",auditor_name"
",auditor_url"
",is_active"
",last_change"
" FROM auditors"
" ORDER BY auditor_uuid DESC"
" LIMIT 1;",
@ -1854,9 +1802,6 @@ postgres_get_session (void *cls)
GNUNET_PQ_make_prepare ("select_serial_by_table_auditor_denom_sigs",
"SELECT"
" auditor_denom_serial AS serial"
",auditor_uuid"
",denominations_serial"
",auditor_sig"
" FROM auditor_denom_sigs"
" ORDER BY auditor_denom_serial DESC"
" LIMIT 1;",
@ -1864,11 +1809,6 @@ postgres_get_session (void *cls)
GNUNET_PQ_make_prepare ("select_serial_by_table_exchange_sign_keys",
"SELECT"
" esk_serial AS serial"
",exchange_pub"
",master_sig"
",valid_from"
",expire_sign"
",expire_legal"
" FROM exchange_sign_keys"
" ORDER BY esk_serial DESC"
" LIMIT 1;",
@ -1876,8 +1816,6 @@ postgres_get_session (void *cls)
GNUNET_PQ_make_prepare ("select_serial_by_table_signkey_revocations",
"SELECT"
" signkey_revocations_serial_id AS serial"
",esk_serial"
",master_sig"
" FROM signkey_revocations"
" ORDER BY signkey_revocations_serial_id DESC"
" LIMIT 1;",
@ -1885,9 +1823,6 @@ postgres_get_session (void *cls)
GNUNET_PQ_make_prepare ("select_serial_by_table_known_coins",
"SELECT"
" known_coin_id AS serial"
",coin_pub"
",denom_sig"
",denominations_serial"
" FROM known_coins"
" ORDER BY known_coin_id DESC"
" LIMIT 1;",
@ -1895,12 +1830,6 @@ postgres_get_session (void *cls)
GNUNET_PQ_make_prepare ("select_serial_by_table_refresh_commitments",
"SELECT"
" melt_serial_id AS serial"
",rc"
",old_coin_sig"
",amount_with_fee_val"
",amount_with_fee_frac"
",noreveal_index"
",old_known_coin_id"
" FROM refresh_commitments"
" ORDER BY melt_serial_id DESC"
" LIMIT 1;",
@ -1908,12 +1837,6 @@ postgres_get_session (void *cls)
GNUNET_PQ_make_prepare ("select_serial_by_table_refresh_revealed_coins",
"SELECT"
" rrc_serial AS serial"
",freshcoin_index"
",link_sig"
",coin_ev"
",ev_sig"
",denominations_serial"
",melt_serial_id"
" FROM refresh_revealed_coins"
" ORDER BY rrc_serial DESC"
" LIMIT 1;",
@ -1921,9 +1844,6 @@ postgres_get_session (void *cls)
GNUNET_PQ_make_prepare ("select_serial_by_table_refresh_transfer_keys",
"SELECT"
" rtc_serial AS serial"
",transfer_pub"
",transfer_privs"
",melt_serial_id"
" FROM refresh_transfer_keys"
" ORDER BY rtc_serial DESC"
" LIMIT 1;",
@ -1931,19 +1851,6 @@ postgres_get_session (void *cls)
GNUNET_PQ_make_prepare ("select_serial_by_table_deposits",
"SELECT"
" deposit_serial_id AS serial"
",amount_with_fee_val"
",amount_with_fee_frac"
",wallet_timestamp"
",exchange_timestamp"
",refund_deadline"
",wire_deadline"
",merchant_pub"
",h_contract_terms"
",coin_sig"
",wire"
",tiny"
",done"
",known_coin_id"
" FROM deposits"
" ORDER BY deposit_serial_id DESC"
" LIMIT 1;",
@ -1951,11 +1858,6 @@ postgres_get_session (void *cls)
GNUNET_PQ_make_prepare ("select_serial_by_table_refunds",
"SELECT"
" refund_serial_id AS serial"
",merchant_sig"
",rtransaction_id"
",amount_with_fee_val"
",amount_with_fee_frac"
",deposit_serial_id"
" FROM refunds"
" ORDER BY refund_serial_id DESC"
" LIMIT 1;",
@ -1963,12 +1865,6 @@ postgres_get_session (void *cls)
GNUNET_PQ_make_prepare ("select_serial_by_table_wire_out",
"SELECT"
" wireout_uuid AS serial"
",execution_date"
",wtid_raw"
",wire_target"
",exchange_account_section"
",amount_val"
",amount_frac"
" FROM wire_out"
" ORDER BY wireout_uuid DESC"
" LIMIT 1;",
@ -1976,8 +1872,6 @@ postgres_get_session (void *cls)
GNUNET_PQ_make_prepare ("select_serial_by_table_aggregation_tracking",
"SELECT"
" aggregation_serial_id AS serial"
",deposit_serial_id"
",wtid_raw"
" FROM aggregation_tracking"
" ORDER BY aggregation_serial_id DESC"
" LIMIT 1;",
@ -1985,14 +1879,6 @@ postgres_get_session (void *cls)
GNUNET_PQ_make_prepare ("select_serial_by_table_wire_fee",
"SELECT"
" wire_fee_serial AS serial"
",wire_method"
",start_date"
",end_date"
",wire_fee_val"
",wire_fee_frac"
",closing_fee_val"
",closing_fee_frac"
",master_sig"
" FROM wire_fee"
" ORDER BY wire_fee_serial DESC"
" LIMIT 1;",
@ -2000,13 +1886,6 @@ postgres_get_session (void *cls)
GNUNET_PQ_make_prepare ("select_serial_by_table_recoup",
"SELECT"
" recoup_uuid AS serial"
",coin_sig"
",coin_blind"
",amount_val"
",amount_frac"
",timestamp"
",known_coin_id"
",reserve_out_serial_id"
" FROM recoup"
" ORDER BY recoup_uuid DESC"
" LIMIT 1;",
@ -2014,13 +1893,6 @@ postgres_get_session (void *cls)
GNUNET_PQ_make_prepare ("select_serial_by_table_recoup_refresh",
"SELECT"
" recoup_refresh_uuid AS serial"
",coin_sig"
",coin_blind"
",amount_val"
",amount_frac"
",timestamp"
",known_coin_id"
",rrc_serial"
" FROM recoup_refresh"
" ORDER BY recoup_refresh_uuid DESC"
" LIMIT 1;",
@ -2133,6 +2005,7 @@ postgres_get_session (void *cls)
" auditor_denom_serial AS serial"
",auditor_uuid"
",denominations_serial"
",auditor_sig"
" FROM auditor_denom_sigs"
" WHERE auditor_denom_serial > $1"
" ORDER BY auditor_denom_serial ASC;",
@ -2187,16 +2060,14 @@ postgres_get_session (void *cls)
"select_above_serial_by_table_refresh_revealed_coins",
"SELECT"
" rrc_serial AS serial"
",rc"
",freshcoin_index"
",link_sig"
",coin_ev"
",h_coin_ev"
",ev_sig"
",rrc_serial"
",melt_serial_id"
",denominations_serial"
" FROM refresh_revealed_coins"
" JOIN refresh_commitments USING (melt_serial_id)"
" WHERE rrc_serial > $1"
" ORDER BY rrc_serial ASC;",
1),
@ -2204,11 +2075,10 @@ postgres_get_session (void *cls)
"select_above_serial_by_table_refresh_transfer_keys",
"SELECT"
" rtc_serial AS serial"
",rc"
",transfer_pub"
",transfer_privs"
",melt_serial_id"
" FROM refresh_transfer_keys"
" JOIN refresh_commitments USING (melt_serial_id)"
" WHERE rtc_serial > $1"
" ORDER BY rtc_serial ASC;",
1),
@ -2236,15 +2106,12 @@ postgres_get_session (void *cls)
GNUNET_PQ_make_prepare ("select_above_serial_by_table_refunds",
"SELECT"
" refund_serial_id AS serial"
",merchant_pub"
",merchant_sig"
",h_contract_terms"
",rtransaction_id"
",refunds.amount_with_fee_val"
",refunds.amount_with_fee_frac"
",known_coin_id"
",amount_with_fee_val"
",amount_with_fee_frac"
",deposit_serial_id"
" FROM refunds"
" JOIN deposits USING (deposit_serial_id)"
" WHERE refund_serial_id > $1"
" ORDER BY refund_serial_id ASC;",
1),

View File

@ -3811,7 +3811,7 @@ struct TALER_EXCHANGEDB_Plugin
* @param cls closure
* @param session a session
* @param tb table data to insert
* @return transaction status code, GNUNET_DB_STATUS_HARD_ERROR if
* @return transaction status code, #GNUNET_DB_STATUS_HARD_ERROR if
* @a table does not have a serial number
*/
enum GNUNET_DB_QueryStatus