gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] [taler-exchange] branch master updated (c94309ee -> 990e7ef


From: gnunet
Subject: [GNUnet-SVN] [taler-exchange] branch master updated (c94309ee -> 990e7ef3)
Date: Sun, 21 Jul 2019 20:15:19 +0200

This is an automated email from the git hooks/post-receive script.

grothoff pushed a change to branch master
in repository exchange.

    from c94309ee rename fresh coin to have TALER_TESTING_-prefix
     new ad343059 expose blinding key in refresh-reveal API in preparation for 
#5777
     new bafe0c77 expose blinding keys in trait of refresh reveal command 
(preparation for #5777)
     new 721c1ee7 extending postgres plugin with functions required to store 
payback data on refreshed coins for #5777
     new 990e7ef3 indentation fixes

The 4 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 src/exchange/taler-exchange-httpd_payback.c |  82 ++--
 src/exchangedb/plugin_exchangedb_common.c   |   6 +
 src/exchangedb/plugin_exchangedb_postgres.c | 725 ++++++++++++++++++++++------
 src/include/taler_crypto_lib.h              |  21 -
 src/include/taler_exchange_service.h        |   4 +-
 src/include/taler_exchangedb_plugin.h       | 177 ++++++-
 src/include/taler_testing_lib.h             |   8 +-
 src/lib/exchange_api_refresh.c              |  19 +-
 src/lib/testing_api_cmd_refresh.c           |  17 +-
 9 files changed, 815 insertions(+), 244 deletions(-)

diff --git a/src/exchange/taler-exchange-httpd_payback.c 
b/src/exchange/taler-exchange-httpd_payback.c
index 643b9fba..232c639e 100644
--- a/src/exchange/taler-exchange-httpd_payback.c
+++ b/src/exchange/taler-exchange-httpd_payback.c
@@ -50,7 +50,7 @@ reply_payback_unknown (struct MHD_Connection *connection,
                                        MHD_HTTP_NOT_FOUND,
                                        "{s:s, s:I}",
                                        "error", "blinded coin unknown",
-                                      "code", (json_int_t) ec);
+                                       "code", (json_int_t) ec);
 }
 
 
@@ -84,8 +84,8 @@ reply_payback_success (struct MHD_Connection *connection,
   pc.reserve_pub = *reserve_pub;
   if (GNUNET_OK !=
       TEH_KS_sign (&pc.purpose,
-                  &pub,
-                  &sig))
+                   &pub,
+                   &sig))
   {
     return TEH_RESPONSE_reply_internal_error (connection,
                                               
TALER_EC_EXCHANGE_BAD_CONFIGURATION,
@@ -172,9 +172,9 @@ struct PaybackContext
  */
 static enum GNUNET_DB_QueryStatus
 payback_transaction (void *cls,
-                    struct MHD_Connection *connection,
-                    struct TALER_EXCHANGEDB_Session *session,
-                    int *mhd_ret)
+                     struct MHD_Connection *connection,
+                     struct TALER_EXCHANGEDB_Session *session,
+                     int *mhd_ret)
 {
   struct PaybackContext *pc = cls;
   struct TALER_EXCHANGEDB_TransactionList *tl;
@@ -184,16 +184,16 @@ payback_transaction (void *cls,
   /* Check whether a payback is allowed, and if so, to which
      reserve / account the money should go */
   qs = TEH_plugin->get_reserve_by_h_blind (TEH_plugin->cls,
-                                          session,
-                                          &pc->h_blind,
-                                          &pc->reserve_pub);
+                                           session,
+                                           &pc->h_blind,
+                                           &pc->reserve_pub);
   if (0 > qs)
   {
     if (GNUNET_DB_STATUS_HARD_ERROR == qs)
     {
       GNUNET_break (0);
       *mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection,
-                                                      
TALER_EC_PAYBACK_DB_FETCH_FAILED);
+                                                       
TALER_EC_PAYBACK_DB_FETCH_FAILED);
     }
     return qs;
   }
@@ -201,7 +201,7 @@ payback_transaction (void *cls,
   {
     GNUNET_break_op (0);
     *mhd_ret = reply_payback_unknown (connection,
-                                     TALER_EC_PAYBACK_WITHDRAW_NOT_FOUND);
+                                      TALER_EC_PAYBACK_WITHDRAW_NOT_FOUND);
     return GNUNET_DB_STATUS_HARD_ERROR;
   }
 
@@ -210,14 +210,14 @@ payback_transaction (void *cls,
                                           session,
                                           &pc->coin->coin_pub,
                                           GNUNET_YES,
-                                         &tl);
+                                          &tl);
   if (0 > qs)
   {
     if (GNUNET_DB_STATUS_HARD_ERROR == qs)
     {
       GNUNET_break (0);
       *mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection,
-                                                      
TALER_EC_PAYBACK_DB_FETCH_FAILED);
+                                                       
TALER_EC_PAYBACK_DB_FETCH_FAILED);
     }
     return qs;
   }
@@ -226,14 +226,14 @@ payback_transaction (void *cls,
                                         &spent));
   if (GNUNET_OK !=
       TEH_DB_calculate_transaction_list_totals (tl,
-                                               &spent,
-                                               &spent))
+                                                &spent,
+                                                &spent))
   {
     GNUNET_break (0);
     TEH_plugin->free_coin_transaction_list (TEH_plugin->cls,
                                             tl);
     *mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection,
-                                                    
TALER_EC_PAYBACK_HISTORY_DB_ERROR);
+                                                     
TALER_EC_PAYBACK_HISTORY_DB_ERROR);
     return GNUNET_DB_STATUS_HARD_ERROR;
   }
   if (GNUNET_SYSERR ==
@@ -245,7 +245,7 @@ payback_transaction (void *cls,
     TEH_plugin->free_coin_transaction_list (TEH_plugin->cls,
                                             tl);
     *mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection,
-                                                    
TALER_EC_PAYBACK_COIN_BALANCE_NEGATIVE);
+                                                     
TALER_EC_PAYBACK_COIN_BALANCE_NEGATIVE);
     return GNUNET_DB_STATUS_HARD_ERROR;
   }
   if ( (0 == pc->amount.fraction) &&
@@ -254,8 +254,8 @@ payback_transaction (void *cls,
     TEH_plugin->rollback (TEH_plugin->cls,
                           session);
     *mhd_ret = TEH_RESPONSE_reply_coin_insufficient_funds (connection,
-                                                          
TALER_EC_PAYBACK_COIN_BALANCE_ZERO,
-                                                          tl);
+                                                           
TALER_EC_PAYBACK_COIN_BALANCE_ZERO,
+                                                           tl);
     TEH_plugin->free_coin_transaction_list (TEH_plugin->cls,
                                             tl);
     return GNUNET_DB_STATUS_HARD_ERROR;
@@ -267,21 +267,41 @@ payback_transaction (void *cls,
 
   /* add coin to list of wire transfers for payback */
   qs = TEH_plugin->insert_payback_request (TEH_plugin->cls,
-                                          session,
-                                          &pc->reserve_pub,
-                                          pc->coin,
-                                          pc->coin_sig,
-                                          pc->coin_bks,
-                                          &pc->amount,
-                                          &pc->h_blind,
-                                          pc->now);
+                                           session,
+                                           &pc->reserve_pub,
+                                           pc->coin,
+                                           pc->coin_sig,
+                                           pc->coin_bks,
+                                           &pc->amount,
+                                           &pc->h_blind,
+                                           pc->now);
   if (0 > qs)
   {
     if (GNUNET_DB_STATUS_HARD_ERROR == qs)
     {
       TALER_LOG_WARNING ("Failed to store /payback information in database\n");
       *mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection,
-                                                      
TALER_EC_PAYBACK_DB_PUT_FAILED);
+                                                       
TALER_EC_PAYBACK_DB_PUT_FAILED);
+    }
+    return qs;
+  }
+  /* increment reserve balance */
+  qs = TEH_plugin->increment_reserve_balance (TEH_plugin->cls,
+                                              session,
+                                              &pc->reserve_pub,
+                                              pc->coin,
+                                              pc->coin_sig,
+                                              pc->coin_bks,
+                                              &pc->amount,
+                                              &pc->h_blind,
+                                              pc->now);
+  if (0 > qs)
+  {
+    if (GNUNET_DB_STATUS_HARD_ERROR == qs)
+    {
+      TALER_LOG_WARNING ("Failed to store /payback information in database\n");
+      *mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection,
+                                                       
TALER_EC_PAYBACK_DB_PUT_FAILED);
     }
     return qs;
   }
@@ -333,7 +353,7 @@ verify_and_execute_payback (struct MHD_Connection 
*connection,
     TEH_KS_release (key_state);
     TALER_LOG_WARNING ("Denomination key in /payback request not in payback 
mode\n");
     return TEH_RESPONSE_reply_arg_unknown (connection,
-                                          
TALER_EC_PAYBACK_DENOMINATION_KEY_UNKNOWN,
+                                           
TALER_EC_PAYBACK_DENOMINATION_KEY_UNKNOWN,
                                            "denom_pub");
   }
   TALER_amount_ntoh (&pc.value,
@@ -347,7 +367,7 @@ verify_and_execute_payback (struct MHD_Connection 
*connection,
     TALER_LOG_WARNING ("Invalid coin passed for /payback\n");
     TEH_KS_release (key_state);
     return TEH_RESPONSE_reply_signature_invalid (connection,
-                                                
TALER_EC_PAYBACK_DENOMINATION_SIGNATURE_INVALID,
+                                                 
TALER_EC_PAYBACK_DENOMINATION_SIGNATURE_INVALID,
                                                  "denom_sig");
   }
 
@@ -367,7 +387,7 @@ verify_and_execute_payback (struct MHD_Connection 
*connection,
     TALER_LOG_WARNING ("Invalid signature on /payback request\n");
     TEH_KS_release (key_state);
     return TEH_RESPONSE_reply_signature_invalid (connection,
-                                                
TALER_EC_PAYBACK_SIGNATURE_INVALID,
+                                                 
TALER_EC_PAYBACK_SIGNATURE_INVALID,
                                                  "coin_sig");
   }
 
diff --git a/src/exchangedb/plugin_exchangedb_common.c 
b/src/exchangedb/plugin_exchangedb_common.c
index fd2620c7..4a72f546 100644
--- a/src/exchangedb/plugin_exchangedb_common.c
+++ b/src/exchangedb/plugin_exchangedb_common.c
@@ -99,6 +99,9 @@ common_free_coin_transaction_list (void *cls,
         GNUNET_CRYPTO_rsa_signature_free 
(list->details.melt->session.coin.denom_sig.rsa_signature);
       GNUNET_free (list->details.melt);
       break;
+    case TALER_EXCHANGEDB_TT_OLD_COIN_PAYBACK:
+      GNUNET_free (list->details.old_coin_payback);
+      break;
     case TALER_EXCHANGEDB_TT_REFUND:
       if (NULL != list->details.refund->coin.denom_sig.rsa_signature)
         GNUNET_CRYPTO_rsa_signature_free 
(list->details.refund->coin.denom_sig.rsa_signature);
@@ -109,6 +112,9 @@ common_free_coin_transaction_list (void *cls,
         GNUNET_CRYPTO_rsa_signature_free 
(list->details.payback->coin.denom_sig.rsa_signature);
       GNUNET_free (list->details.payback);
       break;
+    case TALER_EXCHANGEDB_TT_PAYBACK_REFRESH:
+      GNUNET_free (list->details.payback_refresh);
+      break;
     }
     GNUNET_free (list);
     list = next;
diff --git a/src/exchangedb/plugin_exchangedb_postgres.c 
b/src/exchangedb/plugin_exchangedb_postgres.c
index b4c2d49d..cbf4c093 100644
--- a/src/exchangedb/plugin_exchangedb_postgres.c
+++ b/src/exchangedb/plugin_exchangedb_postgres.c
@@ -115,6 +115,7 @@ postgres_drop_tables (void *cls)
     GNUNET_PQ_make_execute ("DROP TABLE IF EXISTS kyc_merchants CASCADE;"),
     GNUNET_PQ_make_execute ("DROP TABLE IF EXISTS prewire CASCADE;"),
     GNUNET_PQ_make_execute ("DROP TABLE IF EXISTS payback CASCADE;"),
+    GNUNET_PQ_make_execute ("DROP TABLE IF EXISTS payback_refresh CASCADE;"),
     GNUNET_PQ_make_execute ("DROP TABLE IF EXISTS aggregation_tracking 
CASCADE;"),
     GNUNET_PQ_make_execute ("DROP TABLE IF EXISTS wire_out CASCADE;"),
     GNUNET_PQ_make_execute ("DROP TABLE IF EXISTS wire_fee CASCADE;"),
@@ -317,7 +318,7 @@ postgres_create_tables (void *cls)
                            ",newcoin_index INT4 NOT NULL"
                            ",link_sig BYTEA NOT NULL 
CHECK(LENGTH(link_sig)=64)"
                            ",denom_pub_hash BYTEA NOT NULL REFERENCES 
denominations (denom_pub_hash) ON DELETE CASCADE"
-                           ",coin_ev BYTEA NOT NULL"
+                           ",coin_ev BYTEA UNIQUE NOT NULL"
                            ",ev_sig BYTEA NOT NULL"
                            ",PRIMARY KEY (rc, newcoin_index)"
                            ");"),
@@ -449,6 +450,27 @@ postgres_create_tables (void *cls)
     GNUNET_PQ_make_try_execute("CREATE INDEX payback_for_by_reserve "
                                "ON 
payback(coin_pub,denom_pub_hash,h_blind_ev);"),
 
+    /* Table for /payback-refresh information */
+    GNUNET_PQ_make_execute("CREATE TABLE IF NOT EXISTS payback_refresh "
+                           "(payback_refresh_uuid BIGSERIAL UNIQUE"
+                           ",coin_pub BYTEA NOT NULL REFERENCES known_coins 
(coin_pub)" /* do NOT CASCADE on delete, we may keep the coin alive! */
+                           ",coin_sig BYTEA NOT NULL 
CHECK(LENGTH(coin_sig)=64)"
+                           ",coin_blind BYTEA NOT NULL 
CHECK(LENGTH(coin_blind)=32)"
+                           ",amount_val INT8 NOT NULL"
+                           ",amount_frac INT4 NOT NULL"
+                           ",amount_curr VARCHAR("TALER_CURRENCY_LEN_STR") NOT 
NULL"
+                           ",timestamp INT8 NOT NULL"
+                           ",h_blind_ev BYTEA NOT NULL REFERENCES 
refresh_revealed_coins (coin_ev) ON DELETE CASCADE"
+                           ");"),
+    GNUNET_PQ_make_try_execute("CREATE INDEX payback_refresh_by_coin_index "
+                               "ON payback_refresh(coin_pub);"),
+    GNUNET_PQ_make_try_execute("CREATE INDEX payback_refresh_by_h_blind_ev "
+                               "ON payback_refresh(h_blind_ev);"),
+    GNUNET_PQ_make_try_execute("CREATE INDEX payback_refresh_by_reserve_index "
+                               "ON payback_refresh(reserve_pub);"),
+    GNUNET_PQ_make_try_execute("CREATE INDEX payback_refresh_for_by_reserve "
+                               "ON 
payback_refresh(coin_pub,denom_pub_hash,h_blind_ev);"),
+
     /* This table contains the pre-commit data for
        wire transfers the exchange is about to execute. */
     GNUNET_PQ_make_execute("CREATE TABLE IF NOT EXISTS prewire "
@@ -658,14 +680,14 @@ postgres_prepare (PGconn *db_conn)
                             ") VALUES "
                             "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10);",
                             10),
-    /* Used in #postgres_reserves_update() when the reserve is updated */
+    /* Used in #reserves_update() when the reserve is updated */
     GNUNET_PQ_make_prepare ("reserve_update",
                             "UPDATE reserves"
                             " SET"
                             " expiration_date=$1 "
                             ",current_balance_val=$2"
                             ",current_balance_frac=$3"
-                           ",current_balance_curr=$4"
+                            ",current_balance_curr=$4"
                             " WHERE"
                             " reserve_pub=$5;",
                             5),
@@ -1521,6 +1543,21 @@ postgres_prepare (PGconn *db_conn)
                             ") VALUES "
                             "($1, $2, $3, $4, $5, $6, $7, $8);",
                             8),
+    /* Used in #postgres_insert_payback_request() to store payback-refresh
+       information */
+    GNUNET_PQ_make_prepare ("payback_refresh_insert",
+                            "INSERT INTO payback_refresh "
+                            "(coin_pub"
+                            ",coin_sig"
+                            ",coin_blind"
+                            ",amount_val"
+                            ",amount_frac"
+                            ",amount_curr"
+                            ",timestamp"
+                            ",h_blind_ev"
+                            ") VALUES "
+                            "($1, $2, $3, $4, $5, $6, $7, $8);",
+                            8),
     /* Used in #postgres_select_payback_above_serial_id() to obtain payback 
transactions */
     GNUNET_PQ_make_prepare ("payback_get_incr",
                             "SELECT"
@@ -1547,6 +1584,35 @@ postgres_prepare (PGconn *db_conn)
                             " WHERE payback_uuid>=$1"
                             " ORDER BY payback_uuid ASC;",
                             1),
+    /* Used in #postgres_select_payback_refresh_above_serial_id() to obtain
+       payback-refresh transactions */
+    GNUNET_PQ_make_prepare ("payback_refresh_get_incr",
+                            "SELECT"
+                            " payback_refresh_uuid"
+                            ",timestamp"
+                            ",rc.old_coin_pub"
+                            ",coin_pub"
+                            ",coin_sig"
+                            ",coin_blind"
+                            ",h_blind_ev"
+                            ",coins.denom_pub_hash"
+                            ",denoms.denom_pub"
+                            ",coins.denom_sig"
+                            ",amount_val"
+                            ",amount_frac"
+                            ",amount_curr"
+                            " FROM payback_refresh"
+                            "    JOIN refresh_revealed_coins rrc"
+                            "      ON (rrc.coin_ev = h_blind_ev)"
+                            "    JOIN refresh_commitments rc"
+                            "      ON (rrc.rc = rc.rc)"
+                            "    JOIN known_coins coins"
+                            "      USING (coin_pub)"
+                            "    JOIN denominations denoms"
+                            "      ON (coins.denom_pub_hash = 
denoms.denom_pub_hash)"
+                            " WHERE payback_refresh_uuid>=$1"
+                            " ORDER BY payback_refresh_uuid ASC;",
+                            1),
     /* Used in #postgres_select_reserve_closed_above_serial_id() to
        obtain information about closed reserves */
     GNUNET_PQ_make_prepare ("reserves_close_get_incr",
@@ -1587,6 +1653,29 @@ postgres_prepare (PGconn *db_conn)
                             " WHERE ro.reserve_pub=$1"
                             " FOR UPDATE;",
                             1),
+    /* Used in #postgres_get_coin_transactions() to obtain payback transactions
+       affecting old coins of refreshed coins */
+    GNUNET_PQ_make_prepare ("payback_by_old_coin",
+                            "SELECT"
+                            " pr.coin_pub"
+                            ",pr.coin_sig"
+                            ",pr.coin_blind"
+                            ",pr.amount_val"
+                            ",pr.amount_frac"
+                            ",pr.amount_curr"
+                            ",pr.timestamp"
+                            ",coins.denom_pub_hash"
+                            ",coins.denom_sig"
+                            " FROM refresh_commitments"
+                            "    JOIN refresh_revealed_coins rrc"
+                            "      USING (rc)"
+                            "    JOIN payback_refresh pr"
+                            "      ON (rrc.coin_ev = pr.h_blind_ev)"
+                            "    JOIN known_coins coins"
+                            "      ON (coins.coin_pub = pr.coin_pub)"
+                            " WHERE old_coin_pub=$1"
+                            " FOR UPDATE;",
+                            1),
     /* Used in #postgres_get_reserve_history() */
     GNUNET_PQ_make_prepare ("close_by_reserve",
                             "SELECT"
@@ -1616,8 +1705,8 @@ postgres_prepare (PGconn *db_conn)
                             " WHERE expiration_date<=$1"
                             "   AND (current_balance_val != 0 "
                             "        OR current_balance_frac != 0)"
-                           " ORDER BY expiration_date ASC"
-                           " LIMIT 1;",
+                            " ORDER BY expiration_date ASC"
+                            " LIMIT 1;",
                             1),
     /* Used in #postgres_get_coin_transactions() to obtain payback transactions
        for a coin */
@@ -1637,7 +1726,31 @@ postgres_prepare (PGconn *db_conn)
                             "      USING (coin_pub)"
                             "    JOIN reserves_out ro"
                             "      USING (h_blind_ev)"
-                            " WHERE payback.coin_pub=$1;",
+                            " WHERE payback.coin_pub=$1"
+                            " FOR UPDATE;",
+                            1),
+    /* Used in #postgres_get_coin_transactions() to obtain payback transactions
+       for a refreshed coin */
+    GNUNET_PQ_make_prepare ("payback_by_refreshed_coin",
+                            "SELECT"
+                            " rc.old_coin_pub"
+                            ",coin_sig"
+                            ",coin_blind"
+                            ",amount_val"
+                            ",amount_frac"
+                            ",amount_curr"
+                            ",timestamp"
+                            ",coins.denom_pub_hash"
+                            ",coins.denom_sig"
+                            " FROM payback_refresh"
+                            "    JOIN refresh_revealed_coins rrc"
+                            "      ON (rrc.coin_ev = h_blind_ev)"
+                            "    JOIN refresh_commitments rc"
+                            "      ON (rrc.rc = rc.rc)"
+                            "    JOIN known_coins coins"
+                            "      USING (coin_pub)"
+                            " WHERE coin_pub=$1"
+                            " FOR UPDATE;",
                             1),
     /* Used in #postgres_get_reserve_by_h_blind() */
     GNUNET_PQ_make_prepare ("reserve_by_h_blind",
@@ -2181,8 +2294,8 @@ reserves_update (void *cls,
   };
 
   return GNUNET_PQ_eval_prepared_non_select (session->conn,
-                                            "reserve_update",
-                                            params);
+                                             "reserve_update",
+                                             params);
 }
 
 
@@ -2334,8 +2447,8 @@ postgres_reserves_in_insert (void *cls,
     updated_reserve.expiry = GNUNET_TIME_absolute_max (expiry,
                                                        reserve.expiry);
     return reserves_update (cls,
-                           session,
-                           &updated_reserve);
+                            session,
+                            &updated_reserve);
   }
   return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
 }
@@ -2504,8 +2617,8 @@ postgres_insert_withdraw_info (void *cls,
   reserve.expiry = GNUNET_TIME_absolute_max (expiry,
                                              reserve.expiry);
   qs = reserves_update (cls,
-                       session,
-                       &reserve);
+                        session,
+                        &reserve);
   GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR != qs);
   if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
   {
@@ -4253,8 +4366,8 @@ struct CoinHistoryContext
  */
 static void
 add_coin_deposit (void *cls,
-                 PGresult *result,
-                 unsigned int num_results)
+                  PGresult *result,
+                  unsigned int num_results)
 {
   struct CoinHistoryContext *chc = cls;
 
@@ -4267,38 +4380,38 @@ add_coin_deposit (void *cls,
     deposit = GNUNET_new (struct TALER_EXCHANGEDB_Deposit);
     {
       struct GNUNET_PQ_ResultSpec rs[] = {
-       TALER_PQ_result_spec_amount ("amount_with_fee",
-                                    &deposit->amount_with_fee),
-       TALER_PQ_result_spec_amount ("fee_deposit",
-                                    &deposit->deposit_fee),
-       TALER_PQ_result_spec_absolute_time ("timestamp",
-                                            &deposit->timestamp),
-       TALER_PQ_result_spec_absolute_time ("refund_deadline",
-                                            &deposit->refund_deadline),
-       TALER_PQ_result_spec_absolute_time ("wire_deadline",
-                                            &deposit->wire_deadline),
-       GNUNET_PQ_result_spec_auto_from_type ("merchant_pub",
-                                             &deposit->merchant_pub),
-       GNUNET_PQ_result_spec_auto_from_type ("h_contract_terms",
-                                             &deposit->h_contract_terms),
-       GNUNET_PQ_result_spec_auto_from_type ("h_wire",
-                                             &deposit->h_wire),
-       TALER_PQ_result_spec_json ("wire",
+        TALER_PQ_result_spec_amount ("amount_with_fee",
+                                     &deposit->amount_with_fee),
+        TALER_PQ_result_spec_amount ("fee_deposit",
+                                     &deposit->deposit_fee),
+        TALER_PQ_result_spec_absolute_time ("timestamp",
+                                            &deposit->timestamp),
+        TALER_PQ_result_spec_absolute_time ("refund_deadline",
+                                            &deposit->refund_deadline),
+        TALER_PQ_result_spec_absolute_time ("wire_deadline",
+                                            &deposit->wire_deadline),
+        GNUNET_PQ_result_spec_auto_from_type ("merchant_pub",
+                                              &deposit->merchant_pub),
+        GNUNET_PQ_result_spec_auto_from_type ("h_contract_terms",
+                                              &deposit->h_contract_terms),
+        GNUNET_PQ_result_spec_auto_from_type ("h_wire",
+                                              &deposit->h_wire),
+        TALER_PQ_result_spec_json ("wire",
                                    &deposit->receiver_wire_account),
-       GNUNET_PQ_result_spec_auto_from_type ("coin_sig",
-                                             &deposit->csig),
-       GNUNET_PQ_result_spec_end
+        GNUNET_PQ_result_spec_auto_from_type ("coin_sig",
+                                              &deposit->csig),
+        GNUNET_PQ_result_spec_end
       };
 
       if (GNUNET_OK !=
-         GNUNET_PQ_extract_result (result,
-                                   rs,
-                                   i))
+          GNUNET_PQ_extract_result (result,
+                                    rs,
+                                    i))
       {
-       GNUNET_break (0);
-       GNUNET_free (deposit);
-       chc->status = GNUNET_DB_STATUS_HARD_ERROR;
-       return;
+        GNUNET_break (0);
+        GNUNET_free (deposit);
+        chc->status = GNUNET_DB_STATUS_HARD_ERROR;
+        return;
       }
       deposit->coin.coin_pub = *chc->coin_pub;
     }
@@ -4332,8 +4445,8 @@ add_coin_deposit (void *cls,
  */
 static void
 add_coin_melt (void *cls,
-              PGresult *result,
-              unsigned int num_results)
+               PGresult *result,
+               unsigned int num_results)
 {
   struct CoinHistoryContext *chc = cls;
 
@@ -4346,27 +4459,27 @@ add_coin_melt (void *cls,
     melt = GNUNET_new (struct TALER_EXCHANGEDB_RefreshMelt);
     {
       struct GNUNET_PQ_ResultSpec rs[] = {
-       GNUNET_PQ_result_spec_auto_from_type ("rc",
-                                             &melt->session.rc),
-       /* oldcoin_index not needed */
-       GNUNET_PQ_result_spec_auto_from_type ("old_coin_sig",
-                                             &melt->session.coin_sig),
-       TALER_PQ_result_spec_amount ("amount_with_fee",
-                                    &melt->session.amount_with_fee),
-       TALER_PQ_result_spec_amount ("fee_refresh",
-                                    &melt->melt_fee),
-       GNUNET_PQ_result_spec_end
+           GNUNET_PQ_result_spec_auto_from_type ("rc",
+                                              &melt->session.rc),
+        /* oldcoin_index not needed */
+        GNUNET_PQ_result_spec_auto_from_type ("old_coin_sig",
+                                              &melt->session.coin_sig),
+        TALER_PQ_result_spec_amount ("amount_with_fee",
+                                     &melt->session.amount_with_fee),
+        TALER_PQ_result_spec_amount ("fee_refresh",
+                                     &melt->melt_fee),
+        GNUNET_PQ_result_spec_end
       };
 
       if (GNUNET_OK !=
-         GNUNET_PQ_extract_result (result,
-                                   rs,
-                                   i))
+          GNUNET_PQ_extract_result (result,
+                                    rs,
+                                    i))
       {
-       GNUNET_break (0);
-       GNUNET_free (melt);
-       chc->status = GNUNET_DB_STATUS_HARD_ERROR;
-       return;
+        GNUNET_break (0);
+        GNUNET_free (melt);
+        chc->status = GNUNET_DB_STATUS_HARD_ERROR;
+        return;
       }
       melt->session.coin.coin_pub = *chc->coin_pub;
     }
@@ -4401,8 +4514,8 @@ add_coin_melt (void *cls,
  */
 static void
 add_coin_refund (void *cls,
-                PGresult *result,
-                unsigned int num_results)
+                 PGresult *result,
+                 unsigned int num_results)
 {
   struct CoinHistoryContext *chc = cls;
 
@@ -4415,30 +4528,30 @@ add_coin_refund (void *cls,
     refund = GNUNET_new (struct TALER_EXCHANGEDB_Refund);
     {
       struct GNUNET_PQ_ResultSpec rs[] = {
-       GNUNET_PQ_result_spec_auto_from_type ("merchant_pub",
-                                             &refund->merchant_pub),
-       GNUNET_PQ_result_spec_auto_from_type ("merchant_sig",
-                                             &refund->merchant_sig),
-       GNUNET_PQ_result_spec_auto_from_type ("h_contract_terms",
-                                             &refund->h_contract_terms),
-       GNUNET_PQ_result_spec_uint64 ("rtransaction_id",
-                                     &refund->rtransaction_id),
-       TALER_PQ_result_spec_amount ("amount_with_fee",
-                                    &refund->refund_amount),
-       TALER_PQ_result_spec_amount ("fee_refund",
-                                    &refund->refund_fee),
-       GNUNET_PQ_result_spec_end
+        GNUNET_PQ_result_spec_auto_from_type ("merchant_pub",
+                                              &refund->merchant_pub),
+        GNUNET_PQ_result_spec_auto_from_type ("merchant_sig",
+                                              &refund->merchant_sig),
+        GNUNET_PQ_result_spec_auto_from_type ("h_contract_terms",
+                                              &refund->h_contract_terms),
+        GNUNET_PQ_result_spec_uint64 ("rtransaction_id",
+                                      &refund->rtransaction_id),
+        TALER_PQ_result_spec_amount ("amount_with_fee",
+                                     &refund->refund_amount),
+        TALER_PQ_result_spec_amount ("fee_refund",
+                                     &refund->refund_fee),
+        GNUNET_PQ_result_spec_end
       };
 
       if (GNUNET_OK !=
-         GNUNET_PQ_extract_result (result,
-                                   rs,
-                                   i))
+          GNUNET_PQ_extract_result (result,
+                                    rs,
+                                    i))
       {
-       GNUNET_break (0);
-       GNUNET_free (refund);
-       chc->status = GNUNET_DB_STATUS_HARD_ERROR;
-       return;
+        GNUNET_break (0);
+        GNUNET_free (refund);
+        chc->status = GNUNET_DB_STATUS_HARD_ERROR;
+        return;
       }
       refund->coin.coin_pub = *chc->coin_pub;
     }
@@ -4471,9 +4584,70 @@ add_coin_refund (void *cls,
  * @param num_result the number of results in @a result
  */
 static void
+add_old_coin_payback (void *cls,
+                      PGresult *result,
+                      unsigned int num_results)
+{
+  struct CoinHistoryContext *chc = cls;
+
+  for (unsigned int i=0;i<num_results;i++)
+  {
+    struct TALER_EXCHANGEDB_PaybackRefresh *payback;
+    struct TALER_EXCHANGEDB_TransactionList *tl;
+
+    payback = GNUNET_new (struct TALER_EXCHANGEDB_PaybackRefresh);
+    {
+      struct GNUNET_PQ_ResultSpec rs[] = {
+        GNUNET_PQ_result_spec_auto_from_type ("coin_pub",
+                                              &payback->coin.coin_pub),
+        GNUNET_PQ_result_spec_auto_from_type ("coin_sig",
+                                              &payback->coin_sig),
+        GNUNET_PQ_result_spec_auto_from_type ("coin_blind",
+                                              &payback->coin_blind),
+        TALER_PQ_result_spec_amount ("amount",
+                                     &payback->value),
+        TALER_PQ_result_spec_absolute_time ("timestamp",
+                                            &payback->timestamp),
+        GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash",
+                                              &payback->coin.denom_pub_hash),
+        GNUNET_PQ_result_spec_rsa_signature ("denom_sig",
+                                             
&payback->coin.denom_sig.rsa_signature),
+        GNUNET_PQ_result_spec_end
+      };
+
+      if (GNUNET_OK !=
+          GNUNET_PQ_extract_result (result,
+                                    rs,
+                                    i))
+      {
+        GNUNET_break (0);
+        GNUNET_free (payback);
+        chc->status = GNUNET_DB_STATUS_HARD_ERROR;
+        return;
+      }
+      payback->old_coin_pub = *chc->coin_pub;
+    }
+    tl = GNUNET_new (struct TALER_EXCHANGEDB_TransactionList);
+    tl->next = chc->head;
+    tl->type = TALER_EXCHANGEDB_TT_OLD_COIN_PAYBACK;
+    tl->details.old_coin_payback = payback;
+    chc->head = tl;
+  }
+}
+
+
+/**
+ * Function to be called with the results of a SELECT statement
+ * that has returned @a num_results results.
+ *
+ * @param cls closure of type `struct CoinHistoryContext`
+ * @param result the postgres result
+ * @param num_result the number of results in @a result
+ */
+static void
 add_coin_payback (void *cls,
-                 PGresult *result,
-                 unsigned int num_results)
+                  PGresult *result,
+                  unsigned int num_results)
 {
   struct CoinHistoryContext *chc = cls;
 
@@ -4485,32 +4659,32 @@ add_coin_payback (void *cls,
     payback = GNUNET_new (struct TALER_EXCHANGEDB_Payback);
     {
       struct GNUNET_PQ_ResultSpec rs[] = {
-       TALER_PQ_result_spec_amount ("amount",
-                                    &payback->value),
-       GNUNET_PQ_result_spec_auto_from_type ("reserve_pub",
-                                             &payback->reserve_pub),
-       GNUNET_PQ_result_spec_auto_from_type ("coin_blind",
-                                             &payback->coin_blind),
-       GNUNET_PQ_result_spec_auto_from_type ("coin_sig",
-                                             &payback->coin_sig),
-       TALER_PQ_result_spec_absolute_time ("timestamp",
-                                            &payback->timestamp),
-       GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash",
-                                             &payback->coin.denom_pub_hash),
-       GNUNET_PQ_result_spec_rsa_signature ("denom_sig",
-                                            
&payback->coin.denom_sig.rsa_signature),
-       GNUNET_PQ_result_spec_end
+        TALER_PQ_result_spec_amount ("amount",
+                                     &payback->value),
+        GNUNET_PQ_result_spec_auto_from_type ("reserve_pub",
+                                              &payback->reserve_pub),
+        GNUNET_PQ_result_spec_auto_from_type ("coin_blind",
+                                              &payback->coin_blind),
+        GNUNET_PQ_result_spec_auto_from_type ("coin_sig",
+                                              &payback->coin_sig),
+        TALER_PQ_result_spec_absolute_time ("timestamp",
+                                            &payback->timestamp),
+        GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash",
+                                              &payback->coin.denom_pub_hash),
+        GNUNET_PQ_result_spec_rsa_signature ("denom_sig",
+                                             
&payback->coin.denom_sig.rsa_signature),
+        GNUNET_PQ_result_spec_end
       };
 
       if (GNUNET_OK !=
-         GNUNET_PQ_extract_result (result,
-                                   rs,
-                                   i))
+          GNUNET_PQ_extract_result (result,
+                                    rs,
+                                    i))
       {
-       GNUNET_break (0);
-       GNUNET_free (payback);
-       chc->status = GNUNET_DB_STATUS_HARD_ERROR;
-       return;
+        GNUNET_break (0);
+        GNUNET_free (payback);
+        chc->status = GNUNET_DB_STATUS_HARD_ERROR;
+        return;
       }
       payback->coin.coin_pub = *chc->coin_pub;
     }
@@ -4524,6 +4698,67 @@ add_coin_payback (void *cls,
 
 
 /**
+ * Function to be called with the results of a SELECT statement
+ * that has returned @a num_results results.
+ *
+ * @param cls closure of type `struct CoinHistoryContext`
+ * @param result the postgres result
+ * @param num_result the number of results in @a result
+ */
+static void
+add_coin_payback_refresh (void *cls,
+                          PGresult *result,
+                          unsigned int num_results)
+{
+  struct CoinHistoryContext *chc = cls;
+
+  for (unsigned int i=0;i<num_results;i++)
+  {
+    struct TALER_EXCHANGEDB_PaybackRefresh *payback;
+    struct TALER_EXCHANGEDB_TransactionList *tl;
+
+    payback = GNUNET_new (struct TALER_EXCHANGEDB_PaybackRefresh);
+    {
+      struct GNUNET_PQ_ResultSpec rs[] = {
+        GNUNET_PQ_result_spec_auto_from_type ("old_coin_pub",
+                                              &payback->old_coin_pub),
+        GNUNET_PQ_result_spec_auto_from_type ("coin_sig",
+                                              &payback->coin_sig),
+        GNUNET_PQ_result_spec_auto_from_type ("coin_blind",
+                                              &payback->coin_blind),
+        TALER_PQ_result_spec_amount ("amount",
+                                     &payback->value),
+        TALER_PQ_result_spec_absolute_time ("timestamp",
+                                            &payback->timestamp),
+        GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash",
+                                              &payback->coin.denom_pub_hash),
+        GNUNET_PQ_result_spec_rsa_signature ("denom_sig",
+                                             
&payback->coin.denom_sig.rsa_signature),
+        GNUNET_PQ_result_spec_end
+      };
+
+      if (GNUNET_OK !=
+          GNUNET_PQ_extract_result (result,
+                                    rs,
+                                    i))
+      {
+        GNUNET_break (0);
+        GNUNET_free (payback);
+        chc->status = GNUNET_DB_STATUS_HARD_ERROR;
+        return;
+      }
+      payback->coin.coin_pub = *chc->coin_pub;
+    }
+    tl = GNUNET_new (struct TALER_EXCHANGEDB_TransactionList);
+    tl->next = chc->head;
+    tl->type = TALER_EXCHANGEDB_TT_PAYBACK_REFRESH;
+    tl->details.payback_refresh = payback;
+    chc->head = tl;
+  }
+}
+
+
+/**
  * Work we need to do.
  */
 struct Work
@@ -4541,8 +4776,8 @@ struct Work
 
 
 /**
- * Compile a list of all (historic) transactions performed
- * with the given coin (/refresh/melt, /deposit and /refund operations).
+ * Compile a list of all (historic) transactions performed with the given coin
+ * (/refresh/melt, /deposit, /refund and /payback operations).
  *
  * @param cls the `struct PostgresClosure` with the plugin-specific state
  * @param session database connection
@@ -4555,7 +4790,7 @@ postgres_get_coin_transactions (void *cls,
                                 struct TALER_EXCHANGEDB_Session *session,
                                 const struct TALER_CoinSpendPublicKeyP 
*coin_pub,
                                 int include_payback,
-                               struct TALER_EXCHANGEDB_TransactionList **tlp)
+                                struct TALER_EXCHANGEDB_TransactionList **tlp)
 {
   static const struct Work work_op[] = {
     /** #TALER_EXCHANGEDB_TT_DEPOSIT */
@@ -4567,6 +4802,9 @@ postgres_get_coin_transactions (void *cls,
     /** #TALER_EXCHANGEDB_TT_REFUND */
     { "get_refunds_by_coin",
       &add_coin_refund },
+    /** #TALER_EXCHANGEDB_TT_OLD_COIN_PAYBACK */
+    { "payback_by_old_coin",
+      &add_old_coin_payback },
     { NULL, NULL }
   };
   static const struct Work work_wp[] = {
@@ -4579,9 +4817,15 @@ postgres_get_coin_transactions (void *cls,
     /** #TALER_EXCHANGEDB_TT_REFUND */
     { "get_refunds_by_coin",
       &add_coin_refund },
+    /** #TALER_EXCHANGEDB_TT_OLD_COIN_PAYBACK */
+    { "payback_by_old_coin",
+      &add_old_coin_payback },
     /** #TALER_EXCHANGEDB_TT_PAYBACK */
     { "payback_by_coin",
       &add_coin_payback },
+    /** #TALER_EXCHANGEDB_TT_PAYBACK_REFRESH */
+    { "payback_by_refreshed_coin",
+      &add_coin_payback_refresh },
     { NULL, NULL }
   };
   struct CoinHistoryContext chc;
@@ -4604,19 +4848,19 @@ postgres_get_coin_transactions (void *cls,
   for (unsigned int i=0;NULL != work[i].statement; i++)
   {
     qs = GNUNET_PQ_eval_prepared_multi_select (session->conn,
-                                              work[i].statement,
-                                              params,
-                                              work[i].cb,
-                                              &chc);
+                                               work[i].statement,
+                                               params,
+                                               work[i].cb,
+                                               &chc);
     if ( (0 > qs) ||
         (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != chc.status) )
     {
       if (NULL != chc.head)
-       common_free_coin_transaction_list (cls,
-                                          chc.head);
+        common_free_coin_transaction_list (cls,
+                                           chc.head);
       *tlp = NULL;
       if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != chc.status)
-       qs = chc.status;
+        qs = chc.status;
       return qs;
     }
   }
@@ -4660,8 +4904,8 @@ struct WireTransferResultContext
  */
 static void
 handle_wt_result (void *cls,
-                 PGresult *result,
-                 unsigned int num_results)
+                  PGresult *result,
+                  unsigned int num_results)
 {
   struct WireTransferResultContext *ctx = cls;
 
@@ -5207,8 +5451,8 @@ postgres_insert_reserve_closed (void *cls,
   }
   GNUNET_break (GNUNET_NO == ret);
   return reserves_update (cls,
-                         session,
-                         &reserve);
+                          session,
+                          &reserve);
 }
 
 
@@ -6369,8 +6613,8 @@ struct PaybackSerialContext
  */
 static void
 payback_serial_helper_cb (void *cls,
-                         PGresult *result,
-                         unsigned int num_results)
+                          PGresult *result,
+                          unsigned int num_results)
 {
   struct PaybackSerialContext *psc = cls;
 
@@ -6422,14 +6666,14 @@ payback_serial_helper_cb (void *cls,
       return;
     }
     ret = psc->cb (psc->cb_cls,
-                  rowid,
-                  timestamp,
-                  &amount,
-                  &reserve_pub,
-                  &coin,
+                   rowid,
+                   timestamp,
+                   &amount,
+                   &reserve_pub,
+                   &coin,
                    &denom_pub,
-                  &coin_sig,
-                  &coin_blind);
+                   &coin_sig,
+                   &coin_blind);
     GNUNET_PQ_cleanup_result (rs);
     if (GNUNET_OK != ret)
       break;
@@ -6478,6 +6722,147 @@ postgres_select_payback_above_serial_id (void *cls,
 
 
 /**
+ * Closure for #payback_refresh_serial_helper_cb().
+ */
+struct PaybackRefreshSerialContext
+{
+
+  /**
+   * Callback to call.
+   */
+  TALER_EXCHANGEDB_PaybackRefreshCallback cb;
+
+  /**
+   * Closure for @e cb.
+   */
+  void *cb_cls;
+
+  /**
+   * Status code, set to #GNUNET_SYSERR on hard errors.
+   */
+  int status;
+};
+
+
+/**
+ * Helper function to be called with the results of a SELECT statement
+ * that has returned @a num_results results.
+ *
+ * @param cls closure of type `struct PaybackRefreshSerialContext`
+ * @param result the postgres result
+ * @param num_result the number of results in @a result
+ */
+static void
+payback_refresh_serial_helper_cb (void *cls,
+                                  PGresult *result,
+                                  unsigned int num_results)
+{
+  struct PaybackRefreshSerialContext *psc = cls;
+
+  for (unsigned int i=0;i<num_results;i++)
+  {
+    uint64_t rowid;
+    struct TALER_CoinSpendPublicKeyP old_coin_pub;
+    struct TALER_CoinPublicInfo coin;
+    struct TALER_CoinSpendSignatureP coin_sig;
+    struct TALER_DenominationBlindingKeyP coin_blind;
+    struct TALER_DenominationPublicKey denom_pub;
+    struct TALER_Amount amount;
+    struct GNUNET_HashCode h_blind_ev;
+    struct GNUNET_TIME_Absolute timestamp;
+    struct GNUNET_PQ_ResultSpec rs[] = {
+      GNUNET_PQ_result_spec_uint64 ("payback_uuid",
+                                    &rowid),
+      TALER_PQ_result_spec_absolute_time ("timestamp",
+                                           &timestamp),
+      GNUNET_PQ_result_spec_auto_from_type ("old_coin_pub",
+                                            &old_coin_pub),
+      GNUNET_PQ_result_spec_auto_from_type ("coin_pub",
+                                            &coin.coin_pub),
+      GNUNET_PQ_result_spec_auto_from_type ("coin_sig",
+                                            &coin_sig),
+      GNUNET_PQ_result_spec_auto_from_type ("coin_blind",
+                                            &coin_blind),
+      GNUNET_PQ_result_spec_auto_from_type ("h_blind_ev",
+                                            &h_blind_ev),
+      GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash",
+                                            &coin.denom_pub_hash),
+      GNUNET_PQ_result_spec_rsa_public_key ("denom_pub",
+                                           &denom_pub.rsa_public_key),
+      GNUNET_PQ_result_spec_rsa_signature ("denom_sig",
+                                           &coin.denom_sig.rsa_signature),
+      TALER_PQ_result_spec_amount ("amount",
+                                   &amount),
+      GNUNET_PQ_result_spec_end
+    };
+    int ret;
+
+    if (GNUNET_OK !=
+        GNUNET_PQ_extract_result (result,
+                                  rs,
+                                  i))
+    {
+      GNUNET_break (0);
+      psc->status = GNUNET_SYSERR;
+      return;
+    }
+    ret = psc->cb (psc->cb_cls,
+                   rowid,
+                   timestamp,
+                   &amount,
+                   &old_coin_pub,
+                   &coin,
+                   &denom_pub,
+                   &coin_sig,
+                   &coin_blind);
+    GNUNET_PQ_cleanup_result (rs);
+    if (GNUNET_OK != ret)
+      break;
+  }
+}
+
+
+/**
+ * Function called to select payback requests the exchange received for
+ * refreshed coins, ordered by serial ID (monotonically increasing).
+ *
+ * @param cls closure
+ * @param session database connection
+ * @param serial_id lowest serial ID to include (select larger or equal)
+ * @param cb function to call for ONE unfinished item
+ * @param cb_cls closure for @a cb
+ * @return transaction status code
+ */
+static enum GNUNET_DB_QueryStatus
+postgres_select_payback_refresh_above_serial_id (void *cls,
+                                                 struct 
TALER_EXCHANGEDB_Session *session,
+                                                 uint64_t serial_id,
+                                                 
TALER_EXCHANGEDB_PaybackRefreshCallback cb,
+                                                 void *cb_cls)
+{
+  struct GNUNET_PQ_QueryParam params[] = {
+    GNUNET_PQ_query_param_uint64 (&serial_id),
+    GNUNET_PQ_query_param_end
+  };
+  struct PaybackRefreshSerialContext psc = {
+    .cb = cb,
+    .cb_cls = cb_cls,
+    .status = GNUNET_OK
+  };
+  enum GNUNET_DB_QueryStatus qs;
+
+  qs = GNUNET_PQ_eval_prepared_multi_select (session->conn,
+                                             "payback_refresh_get_incr",
+                                             params,
+                                             &payback_refresh_serial_helper_cb,
+                                             &psc);
+  if (GNUNET_OK != psc.status)
+    return GNUNET_DB_STATUS_HARD_ERROR;
+  return qs;
+}
+
+
+/**
  * Closure for #reserve_closed_serial_helper_cb().
  */
 struct ReserveClosedSerialContext
@@ -6580,10 +6965,10 @@ reserve_closed_serial_helper_cb (void *cls,
  */
 static enum GNUNET_DB_QueryStatus
 postgres_select_reserve_closed_above_serial_id (void *cls,
-                                               struct TALER_EXCHANGEDB_Session 
*session,
-                                               uint64_t serial_id,
-                                               
TALER_EXCHANGEDB_ReserveClosedCallback cb,
-                                               void *cb_cls)
+                                                struct 
TALER_EXCHANGEDB_Session *session,
+                                                uint64_t serial_id,
+                                                
TALER_EXCHANGEDB_ReserveClosedCallback cb,
+                                                void *cb_cls)
 {
   struct GNUNET_PQ_QueryParam params[] = {
     GNUNET_PQ_query_param_uint64 (&serial_id),
@@ -6649,17 +7034,10 @@ postgres_insert_payback_request (void *cls,
   };
   enum GNUNET_DB_QueryStatus qs;
 
-#if 0
-  /* check if the coin is already known */
-  if (0 > (qs = postgres_ensure_coin_known (cls,
-                                            session,
-                                            coin)))
-    return qs;
-#endif
   /* now store actual payback information */
   qs = GNUNET_PQ_eval_prepared_non_select (session->conn,
-                                          "payback_insert",
-                                          params);
+                                           "payback_insert",
+                                           params);
   if (0 > qs)
   {
     GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
@@ -6669,8 +7047,8 @@ postgres_insert_payback_request (void *cls,
   /* Update reserve balance */
   reserve.pub = *reserve_pub;
   qs = postgres_reserve_get (cls,
-                            session,
-                            &reserve);
+                             session,
+                             &reserve);
   if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs)
   {
     GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
@@ -6689,8 +7067,8 @@ postgres_insert_payback_request (void *cls,
   reserve.expiry = GNUNET_TIME_absolute_max (expiry,
                                              reserve.expiry);
   qs = reserves_update (cls,
-                         session,
-                         &reserve);
+                        session,
+                        &reserve);
   if (0 >= qs)
   {
     GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
@@ -6701,6 +7079,57 @@ postgres_insert_payback_request (void *cls,
 
 
 /**
+ * Function called to add a request for an emergency payback for a
+ * refreshed coin.  The funds are to be added back to the original coin
+ * (which is implied via @a h_blind_ev, see the prepared statement
+ * "payback_by_old_coin" used in #postgres_get_coin_transactions()).
+ *
+ * @param cls closure
+ * @param session database connection
+ * @param coin public information about the refreshed coin
+ * @param coin_sig signature of the coin of type 
#TALER_SIGNATURE_WALLET_COIN_PAYBACK
+ * @param coin_blind blinding key of the coin
+ * @param h_blind_ev blinded envelope, as calculated by the exchange
+ * @param amount total amount to be paid back
+ * @param h_blind_ev hash of the blinded coin's envelope (must match 
reserves_out entry)
+ * @param timestamp a timestamp to store
+ * @return transaction result status
+ */
+static enum GNUNET_DB_QueryStatus
+postgres_insert_payback_refresh_request (void *cls,
+                                         struct TALER_EXCHANGEDB_Session 
*session,
+                                         const struct TALER_CoinPublicInfo 
*coin,
+                                         const struct 
TALER_CoinSpendSignatureP *coin_sig,
+                                         const struct 
TALER_DenominationBlindingKeyP *coin_blind,
+                                         const struct TALER_Amount *amount,
+                                         const struct GNUNET_HashCode 
*h_blind_ev,
+                                         struct GNUNET_TIME_Absolute timestamp)
+{
+  struct GNUNET_PQ_QueryParam params[] = {
+    GNUNET_PQ_query_param_auto_from_type (&coin->coin_pub),
+    GNUNET_PQ_query_param_auto_from_type (coin_sig),
+    GNUNET_PQ_query_param_auto_from_type (coin_blind),
+    TALER_PQ_query_param_amount (amount),
+    TALER_PQ_query_param_absolute_time (&timestamp),
+    GNUNET_PQ_query_param_auto_from_type (h_blind_ev),
+    GNUNET_PQ_query_param_end
+  };
+  enum GNUNET_DB_QueryStatus qs;
+
+  /* now store actual payback information */
+  qs = GNUNET_PQ_eval_prepared_non_select (session->conn,
+                                           "payback_refresh_insert",
+                                           params);
+  if (0 > qs)
+  {
+    GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
+    return qs;
+  }
+  return qs;
+}
+
+
+/**
  * Obtain information about which reserve a coin was generated
  * from given the hash of the blinded coin.
  *
@@ -7325,10 +7754,14 @@ libtaler_plugin_exchangedb_postgres_init (void *cls)
     = &postgres_select_wire_out_above_serial_id_by_account;
   plugin->select_payback_above_serial_id
     = &postgres_select_payback_above_serial_id;
+  plugin->select_payback_refresh_above_serial_id
+    = &postgres_select_payback_refresh_above_serial_id;
   plugin->select_reserve_closed_above_serial_id
     = &postgres_select_reserve_closed_above_serial_id;
   plugin->insert_payback_request
     = &postgres_insert_payback_request;
+  plugin->insert_payback_refresh_request
+    = &postgres_insert_payback_refresh_request;
   plugin->get_reserve_by_h_blind
     = &postgres_get_reserve_by_h_blind;
   plugin->insert_denomination_revocation
diff --git a/src/include/taler_crypto_lib.h b/src/include/taler_crypto_lib.h
index 4024123b..7b9d932d 100644
--- a/src/include/taler_crypto_lib.h
+++ b/src/include/taler_crypto_lib.h
@@ -435,27 +435,6 @@ struct TALER_PlanchetSecretsP
 };
 
 
-/**
- * Header for serializations of coin-specific information about the fresh
- * coins we generate from refresh.  These are the secrets that arise during
- * planchet generation, which is the first stage of creating a new coin from
- * refresh.
- */
-struct TALER_RefreshPlanchetSecretsP
-{
-
-  /**
-   * Private key of the coin.
-   */
-  struct TALER_CoinSpendPrivateKeyP coin_priv;
-
-  /**
-   * XXX. See #5777~0014690 - need a solution for this first!
-   */
-  struct TALER_TransferPrivateKeyP transfer_priv;
-
-};
-
 GNUNET_NETWORK_STRUCT_END
 
 
diff --git a/src/include/taler_exchange_service.h 
b/src/include/taler_exchange_service.h
index eebbf6c5..7fc7a569 100644
--- a/src/include/taler_exchange_service.h
+++ b/src/include/taler_exchange_service.h
@@ -1356,9 +1356,7 @@ typedef void
                                          unsigned int http_status,
                                          enum TALER_ErrorCode ec,
                                          unsigned int num_coins,
-                                         /* TODO (#5777): possibly replace
-                                            by a `struct 
TALER_RefreshPlanchetSecretsP` */
-                                         const struct 
TALER_CoinSpendPrivateKeyP *coin_privs,
+                                         const struct TALER_PlanchetSecretsP 
*coin_privs,
                                          const struct 
TALER_DenominationSignature *sigs,
                                          const json_t *full_response);
 
diff --git a/src/include/taler_exchangedb_plugin.h 
b/src/include/taler_exchangedb_plugin.h
index 49aac827..8450fb04 100644
--- a/src/include/taler_exchangedb_plugin.h
+++ b/src/include/taler_exchangedb_plugin.h
@@ -234,6 +234,47 @@ struct TALER_EXCHANGEDB_Payback
 
 
 /**
+ * Information the exchange records about a /payback-refresh request.
+ */
+struct TALER_EXCHANGEDB_PaybackRefresh
+{
+
+  /**
+   * Information about the coin that was paid back.
+   */
+  struct TALER_CoinPublicInfo coin;
+
+  /**
+   * Blinding factor supplied to prove to the exchange that
+   * the coin came from this reserve.
+   */
+  struct TALER_DenominationBlindingKeyP coin_blind;
+
+  /**
+   * Signature of the coin of type
+   * #TALER_SIGNATURE_WALLET_COIN_PAYBACK.
+   */
+  struct TALER_CoinSpendSignatureP coin_sig;
+
+  /**
+   * Public key of the old coin that the refresh'ed coin was paid back to.
+   */
+  struct TALER_CoinSpendPublicKeyP old_coin_pub;
+
+  /**
+   * How much was the coin still worth at this time?
+   */
+  struct TALER_Amount value;
+
+  /**
+   * When did the /payback operation happen?
+   */
+  struct GNUNET_TIME_Absolute timestamp;
+
+};
+
+
+/**
  * @brief Types of operations on a reserve.
  */
 enum TALER_EXCHANGEDB_ReserveOperation
@@ -572,9 +613,19 @@ enum TALER_EXCHANGEDB_TransactionType {
   TALER_EXCHANGEDB_TT_REFUND = 2,
 
   /**
+   * /payback-refresh operation (on the old coin, adding to the old coin's 
value)
+   */
+  TALER_EXCHANGEDB_TT_OLD_COIN_PAYBACK = 3,
+
+  /**
    * /payback operation.
    */
-  TALER_EXCHANGEDB_TT_PAYBACK = 3
+  TALER_EXCHANGEDB_TT_PAYBACK = 4,
+
+  /**
+   * /payback-refresh operation (on the new coin, eliminating its value)
+   */
+  TALER_EXCHANGEDB_TT_PAYBACK_REFRESH = 5
 
 };
 
@@ -603,24 +654,42 @@ struct TALER_EXCHANGEDB_TransactionList
 
     /**
      * Details if transaction was a /deposit operation.
+     * (#TALER_EXCHANGEDB_TT_DEPOSIT)
      */
     struct TALER_EXCHANGEDB_Deposit *deposit;
 
     /**
      * Details if transaction was a /refresh/melt operation.
+     * (#TALER_EXCHANGEDB_TT_REFRESH_MELT)
      */
     struct TALER_EXCHANGEDB_RefreshMelt *melt;
 
     /**
      * Details if transaction was a /refund operation.
+     * (#TALER_EXCHANGEDB_TT_REFUND)
      */
     struct TALER_EXCHANGEDB_Refund *refund;
 
     /**
+     * Details if transaction was a /payback-refund operation where
+     * this coin was the OLD coin.
+     * (#TALER_EXCHANGEDB_TT_OLD_COIN_PAYBACK).
+     */
+    struct TALER_EXCHANGEDB_PaybackRefresh *old_coin_payback;
+
+    /**
      * Details if transaction was a /payback operation.
+     * (#TALER_EXCHANGEDB_TT_PAYBACK)
      */
     struct TALER_EXCHANGEDB_Payback *payback;
 
+    /**
+     * Details if transaction was a /payback-refund operation where
+     * this coin was the REFRESHED coin.
+     * (#TALER_EXCHANGEDB_TT_PAYBACK_REFRESH)
+     */
+    struct TALER_EXCHANGEDB_PaybackRefresh *payback_refresh;
+
   } details;
 
 };
@@ -804,7 +873,7 @@ struct TALER_EXCHANGEDB_RefreshRevealedCoin
    * link data, of type #TALER_SIGNATURE_WALLET_COIN_LINK
    */
   struct TALER_CoinSpendSignatureP orig_coin_link_sig;
-  
+
   /**
    * Blinded message to be signed (in envelope), with @e coin_env_size bytes.
    */
@@ -1062,6 +1131,35 @@ typedef int
                                     const struct 
TALER_DenominationBlindingKeyP *coin_blind);
 
 
+
+/**
+ * Function called about paybacks on refreshed coins the exchange has to
+ * perform.
+ *
+ * @param cls closure
+ * @param rowid row identifier used to uniquely identify the payback operation
+ * @param timestamp when did we receive the payback request
+ * @param amount how much should be added back to the reserve
+ * @param old_coin_pub original coin that was refreshed to create @a coin
+ * @param coin public information about the coin
+ * @param coin_sig signature with @e coin_pub of type 
#TALER_SIGNATURE_WALLET_COIN_PAYBACK
+ * @param coin_blind blinding factor used to blind the coin
+ * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop
+ */
+typedef int
+(*TALER_EXCHANGEDB_PaybackRefreshCallback)(void *cls,
+                                           uint64_t rowid,
+                                           struct GNUNET_TIME_Absolute 
timestamp,
+                                           const struct TALER_Amount *amount,
+                                           const struct 
TALER_CoinSpendPublicKeyP *old_coin_pub,
+                                           const struct TALER_CoinPublicInfo 
*coin,
+                                           const struct 
TALER_DenominationPublicKey *denom_pub,
+                                           const struct 
TALER_CoinSpendSignatureP *coin_sig,
+                                           const struct 
TALER_DenominationBlindingKeyP *coin_blind);
+
+
+
+
 /**
  * Function called about reserve closing operations
  * the aggregator triggered.
@@ -1463,7 +1561,7 @@ struct TALER_EXCHANGEDB_Plugin
                         struct TALER_EXCHANGEDB_Session *session,
                         const struct TALER_CoinPublicInfo *coin);
 
-  
+
   /**
    * Retrieve information about the given @a coin from the database.
    *
@@ -2223,6 +2321,25 @@ struct TALER_EXCHANGEDB_Plugin
 
 
   /**
+   * Function called to select payback requests the exchange received for
+   * refreshed coins, ordered by serial ID (monotonically increasing).
+   *
+   * @param cls closure
+   * @param session database connection
+   * @param serial_id lowest serial ID to include (select larger or equal)
+   * @param cb function to call for ONE unfinished item
+   * @param cb_cls closure for @a cb
+   * @return transaction status code
+   */
+  enum GNUNET_DB_QueryStatus
+  (*select_payback_refresh_above_serial_id)(void *cls,
+                                            struct TALER_EXCHANGEDB_Session 
*session,
+                                            uint64_t serial_id,
+                                            
TALER_EXCHANGEDB_PaybackRefreshCallback cb,
+                                            void *cb_cls);
+
+
+  /**
    * Function called to select reserve close operations the aggregator
    * triggered, ordered by serial ID (monotonically increasing).
    *
@@ -2235,18 +2352,15 @@ struct TALER_EXCHANGEDB_Plugin
    */
   enum GNUNET_DB_QueryStatus
   (*select_reserve_closed_above_serial_id)(void *cls,
-                                          struct TALER_EXCHANGEDB_Session 
*session,
-                                          uint64_t serial_id,
-                                          
TALER_EXCHANGEDB_ReserveClosedCallback cb,
-                                          void *cb_cls);
+                                           struct TALER_EXCHANGEDB_Session 
*session,
+                                           uint64_t serial_id,
+                                           
TALER_EXCHANGEDB_ReserveClosedCallback cb,
+                                           void *cb_cls);
 
 
   /**
    * Function called to add a request for an emergency payback for a
-   * coin.  The funds are to be added back to the reserve.  The
-   * function should return the @a deadline by which the exchange will
-   * trigger a wire transfer back to the customer's account for the
-   * reserve.
+   * coin.  The funds are to be added back to the reserve.
    *
    * @param cls closure
    * @param session database connection
@@ -2256,9 +2370,8 @@ struct TALER_EXCHANGEDB_Plugin
    * @param coin_blind blinding key of the coin
    * @param h_blind_ev blinded envelope, as calculated by the exchange
    * @param amount total amount to be paid back
-   * @param receiver_account_details who should receive the funds
    * @param h_blind_ev hash of the blinded coin's envelope (must match 
reserves_out entry)
-   * @param now timestamp to store
+   * @param timestamp the timestamp to store
    * @return transaction result status
    */
   enum GNUNET_DB_QueryStatus
@@ -2274,6 +2387,32 @@ struct TALER_EXCHANGEDB_Plugin
 
 
   /**
+   * Function called to add a request for an emergency payback for a
+   * refreshed coin.  The funds are to be added back to the original coin.
+   *
+   * @param cls closure
+   * @param session database connection
+   * @param coin public information about the refreshed coin
+   * @param coin_sig signature of the coin of type 
#TALER_SIGNATURE_WALLET_COIN_PAYBACK
+   * @param coin_blind blinding key of the coin
+   * @param h_blind_ev blinded envelope, as calculated by the exchange
+   * @param amount total amount to be paid back
+   * @param h_blind_ev hash of the blinded coin's envelope (must match 
reserves_out entry)
+   * @param timestamp a timestamp to store
+   * @return transaction result status
+   */
+  enum GNUNET_DB_QueryStatus
+  (*insert_payback_refresh_request)(void *cls,
+                                    struct TALER_EXCHANGEDB_Session *session,
+                                    const struct TALER_CoinPublicInfo *coin,
+                                    const struct TALER_CoinSpendSignatureP 
*coin_sig,
+                                    const struct 
TALER_DenominationBlindingKeyP *coin_blind,
+                                    const struct TALER_Amount *amount,
+                                    const struct GNUNET_HashCode *h_blind_ev,
+                                    struct GNUNET_TIME_Absolute timestamp);
+
+
+  /**
    * Obtain information about which reserve a coin was generated
    * from given the hash of the blinded coin.
    *
@@ -2323,7 +2462,7 @@ struct TALER_EXCHANGEDB_Plugin
                                  struct TALER_EXCHANGEDB_Session *session,
                                  const struct GNUNET_HashCode *denom_pub_hash,
                                  struct TALER_MasterSignatureP *master_sig,
-                                uint64_t *rowid);
+                                 uint64_t *rowid);
 
 
   /**
@@ -2341,11 +2480,11 @@ struct TALER_EXCHANGEDB_Plugin
    */
   enum GNUNET_DB_QueryStatus
   (*select_deposits_missing_wire)(void *cls,
-                                 struct TALER_EXCHANGEDB_Session *session,
-                                 struct GNUNET_TIME_Absolute start_date,
-                                 struct GNUNET_TIME_Absolute end_date,
-                                 TALER_EXCHANGEDB_WireMissingCallback cb,
-                                 void *cb_cls);
+                                  struct TALER_EXCHANGEDB_Session *session,
+                                  struct GNUNET_TIME_Absolute start_date,
+                                  struct GNUNET_TIME_Absolute end_date,
+                                  TALER_EXCHANGEDB_WireMissingCallback cb,
+                                  void *cb_cls);
 
   /**
    * Insert a merchant into the KYC monitor table, namely it
diff --git a/src/include/taler_testing_lib.h b/src/include/taler_testing_lib.h
index a421cf43..beb28f7a 100644
--- a/src/include/taler_testing_lib.h
+++ b/src/include/taler_testing_lib.h
@@ -1950,8 +1950,6 @@ TALER_TESTING_get_trait_uint
 /**
  * Information about a fresh coin generated by the refresh
  * operation. FIXME: should go away from here!
- *
- * FIXME: should be renamed, easily confused with `struct TALER_FreshCoin`!
  */
 struct TALER_TESTING_FreshCoinData
 {
@@ -1973,6 +1971,12 @@ struct TALER_TESTING_FreshCoinData
    * Set (by the interpreter) to the coin's private key.
    */
   struct TALER_CoinSpendPrivateKeyP coin_priv;
+
+  /**
+   * The blinding key (needed for payback operations).
+   */
+  struct TALER_DenominationBlindingKeyP blinding_key;
+
 };
 
 
diff --git a/src/lib/exchange_api_refresh.c b/src/lib/exchange_api_refresh.c
index 853c702e..c12fd32d 100644
--- a/src/lib/exchange_api_refresh.c
+++ b/src/lib/exchange_api_refresh.c
@@ -1318,14 +1318,12 @@ struct TALER_EXCHANGE_RefreshRevealHandle
  *
  * @param rrh operation handle
  * @param json reply from the exchange
- * @param[out] coin_privs array of length `num_fresh_coins`, initialized to 
contain private keys
  * @param[out] sigs array of length `num_fresh_coins`, initialized to cointain 
RSA signatures
  * @return #GNUNET_OK on success, #GNUNET_SYSERR on errors
  */
 static int
 refresh_reveal_ok (struct TALER_EXCHANGE_RefreshRevealHandle *rrh,
                    const json_t *json,
-                   struct TALER_CoinSpendPrivateKeyP *coin_privs,
                    struct TALER_DenominationSignature *sigs)
 {
   json_t *jsona;
@@ -1405,7 +1403,6 @@ refresh_reveal_ok (struct 
TALER_EXCHANGE_RefreshRevealHandle *rrh,
       return GNUNET_SYSERR;
     }
     GNUNET_CRYPTO_rsa_signature_free (blind_sig);
-    coin_privs[i] = coin.coin_priv;
     sigs[i] = coin.sig;
   }
   GNUNET_JSON_parse_free (outer_spec);
@@ -1436,14 +1433,12 @@ handle_refresh_reveal_finished (void *cls,
     break;
   case MHD_HTTP_OK:
     {
-      struct TALER_CoinSpendPrivateKeyP coin_privs[rrh->md->num_fresh_coins];
       struct TALER_DenominationSignature sigs[rrh->md->num_fresh_coins];
       int ret;
 
       memset (sigs, 0, sizeof (sigs));
       ret = refresh_reveal_ok (rrh,
                                j,
-                               coin_privs,
                                sigs);
       if (GNUNET_OK != ret)
       {
@@ -1453,9 +1448,9 @@ handle_refresh_reveal_finished (void *cls,
       {
         rrh->reveal_cb (rrh->reveal_cb_cls,
                         MHD_HTTP_OK,
-                       TALER_EC_NONE,
+                        TALER_EC_NONE,
                         rrh->md->num_fresh_coins,
-                        coin_privs,
+                        rrh->md->fresh_coins[rrh->noreveal_index],
                         sigs,
                         j);
         rrh->reveal_cb = NULL;
@@ -1490,10 +1485,10 @@ handle_refresh_reveal_finished (void *cls,
   if (NULL != rrh->reveal_cb)
     rrh->reveal_cb (rrh->reveal_cb_cls,
                     response_code,
-                   TALER_JSON_get_error_code (j),
-                   0,
-                   NULL,
-                   NULL,
+                    TALER_JSON_get_error_code (j),
+                    0,
+                    NULL,
+                    NULL,
                     j);
   TALER_EXCHANGE_refresh_reveal_cancel (rrh);
 }
@@ -1616,7 +1611,7 @@ TALER_EXCHANGE_refresh_reveal (struct 
TALER_EXCHANGE_Handle *exchange,
                      json_array_append_new (link_sigs,
                                             GNUNET_JSON_from_data_auto 
(&link_sig)));
     }
-    
+
     GNUNET_free (pd.coin_ev);
   }
 
diff --git a/src/lib/testing_api_cmd_refresh.c 
b/src/lib/testing_api_cmd_refresh.c
index 155d30ce..2bbf189b 100644
--- a/src/lib/testing_api_cmd_refresh.c
+++ b/src/lib/testing_api_cmd_refresh.c
@@ -289,7 +289,7 @@ reveal_cb (void *cls,
            unsigned int http_status,
            enum TALER_ErrorCode ec,
            unsigned int num_coins,
-           const struct TALER_CoinSpendPrivateKeyP *coin_privs,
+           const struct TALER_PlanchetSecretsP *coin_privs,
            const struct TALER_DenominationSignature *sigs,
            const json_t *full_response)
 {
@@ -358,7 +358,8 @@ reveal_cb (void *cls,
         TALER_TESTING_interpreter_fail (rrs->is);
         return;
       }
-      fc->coin_priv = coin_privs[i];
+      fc->coin_priv = coin_privs[i].coin_priv;
+      fc->blinding_key = coin_privs[i].blinding_key;
       fc->sig.rsa_signature = GNUNET_CRYPTO_rsa_signature_dup
         (sigs[i].rsa_signature);
     }
@@ -1182,7 +1183,7 @@ refresh_reveal_traits (void *cls,
 {
   struct RefreshRevealState *rrs = cls;
   unsigned int num_coins = rrs->num_fresh_coins;
-#define NUM_TRAITS ((num_coins * 3) + 3)
+#define NUM_TRAITS ((num_coins * 4) + 3)
   struct TALER_TESTING_Trait traits[NUM_TRAITS];
 
   /* Making coin privs traits */
@@ -1201,26 +1202,22 @@ refresh_reveal_traits (void *cls,
     traits[(num_coins * 2) + i]
       = TALER_TESTING_make_trait_denom_sig
         (i, &rrs->fresh_coins[i].sig);
-#if 0
-  /* FIXME: need *some* trait for #5777 here, but we don't have
-     the blinding keys at hand. So we need to GET them! */
   /* blinding key traits */
   for (unsigned int i=0; i<num_coins; i++)
     traits[(num_coins * 3) + i]
       = TALER_TESTING_make_trait_blinding_key (i,
                                                
&rrs->fresh_coins[i].blinding_key),
-#endif
 
   /* number of fresh coins */
-  traits[(num_coins * 3)] = TALER_TESTING_make_trait_uint
+  traits[(num_coins * 4)] = TALER_TESTING_make_trait_uint
     (0, &rrs->num_fresh_coins);
 
   /* whole array of fresh coins */
-  traits[(num_coins * 3) + 1]
+  traits[(num_coins * 4) + 1]
     = TALER_TESTING_make_trait_fresh_coins (0, rrs->fresh_coins),
 
   /* end of traits */
-  traits[(num_coins * 3) + 2] = TALER_TESTING_trait_end ();
+  traits[(num_coins * 4) + 2] = TALER_TESTING_trait_end ();
 
   return TALER_TESTING_get_trait (traits,
                                   ret,

-- 
To stop receiving notification emails like this one, please contact
address@hidden.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]