From c0451f0982bdb565f431417cea3ab0238342d125 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Thu, 26 May 2016 16:38:59 +0200 Subject: fix #4533 for exchange (breaks interaction with bank for /admin/add/incoming) --- src/exchange-lib/exchange_api_admin.c | 23 +++++---- src/exchange-lib/exchange_api_reserve.c | 30 ++++++++--- src/exchange-lib/test_exchange_api.c | 50 +++++++++++++----- src/exchange-tools/taler-exchange-reservemod.c | 60 +++++++++++++++++----- src/exchange/taler-exchange-httpd_admin.c | 13 +++-- src/exchange/taler-exchange-httpd_db.c | 13 +++-- src/exchange/taler-exchange-httpd_db.h | 6 ++- src/exchange/taler-exchange-httpd_deposit.c | 2 +- src/exchange/taler-exchange-httpd_responses.c | 5 +- src/exchange/test_taler_exchange_aggregator.c | 12 ++--- src/exchangedb/perf_taler_exchangedb_init.c | 6 +-- src/exchangedb/perf_taler_exchangedb_interpreter.c | 24 ++++++--- src/exchangedb/plugin_exchangedb_common.c | 8 +-- src/exchangedb/plugin_exchangedb_postgres.c | 45 +++++++++------- src/exchangedb/test_exchangedb.c | 15 +++--- src/include/taler_exchange_service.h | 25 ++++++--- src/include/taler_exchangedb_plugin.h | 25 +++++---- 17 files changed, 246 insertions(+), 116 deletions(-) (limited to 'src') diff --git a/src/exchange-lib/exchange_api_admin.c b/src/exchange-lib/exchange_api_admin.c index 3c87be5a3..0452a9546 100644 --- a/src/exchange-lib/exchange_api_admin.c +++ b/src/exchange-lib/exchange_api_admin.c @@ -144,7 +144,10 @@ handle_admin_add_incoming_finished (void *cls, * @param reserve_pub public key of the reserve * @param amount amount that was deposited * @param execution_date when did we receive the amount - * @param wire wire details + * @param sender_account_details account information of the sender of the money; + * the receiver is always the exchange. + * @param transfer_details details that uniquely identify the transfer; + * used to check for duplicate operations by the exchange * @param res_cb the callback to call when the final result for this request is available * @param res_cb_cls closure for the above callback * @return NULL @@ -153,12 +156,13 @@ handle_admin_add_incoming_finished (void *cls, */ struct TALER_EXCHANGE_AdminAddIncomingHandle * TALER_EXCHANGE_admin_add_incoming (struct TALER_EXCHANGE_Handle *exchange, - const struct TALER_ReservePublicKeyP *reserve_pub, - const struct TALER_Amount *amount, - struct GNUNET_TIME_Absolute execution_date, - const json_t *wire, - TALER_EXCHANGE_AdminAddIncomingResultCallback res_cb, - void *res_cb_cls) + const struct TALER_ReservePublicKeyP *reserve_pub, + const struct TALER_Amount *amount, + struct GNUNET_TIME_Absolute execution_date, + const json_t *sender_account_details, + const json_t *transfer_details, + TALER_EXCHANGE_AdminAddIncomingResultCallback res_cb, + void *res_cb_cls) { struct TALER_EXCHANGE_AdminAddIncomingHandle *aai; struct GNUNET_CURL_Context *ctx; @@ -174,11 +178,12 @@ TALER_EXCHANGE_admin_add_incoming (struct TALER_EXCHANGE_Handle *exchange, return NULL; } admin_obj = json_pack ("{s:o, s:o," /* reserve_pub/amount */ - " s:o, s:O}", /* execution_Date/wire */ + " s:o, s:O, s:O}", /* execution_Date/sender/transfer */ "reserve_pub", GNUNET_JSON_from_data_auto (reserve_pub), "amount", TALER_JSON_from_amount (amount), "execution_date", GNUNET_JSON_from_time_abs (execution_date), - "wire", wire); + "sender_account_details", sender_account_details, + "transfer_details", transfer_details); aai = GNUNET_new (struct TALER_EXCHANGE_AdminAddIncomingHandle); aai->exchange = exchange; aai->cb = res_cb; diff --git a/src/exchange-lib/exchange_api_reserve.c b/src/exchange-lib/exchange_api_reserve.c index 9c0314d0f..ab8733dbb 100644 --- a/src/exchange-lib/exchange_api_reserve.c +++ b/src/exchange-lib/exchange_api_reserve.c @@ -135,7 +135,8 @@ parse_reserve_history (const json_t *history, if (0 == strcasecmp (type, "DEPOSIT")) { - json_t *wire; + json_t *wire_account; + json_t *transfer; rhistory[off].type = TALER_EXCHANGE_RTT_DEPOSIT; if (GNUNET_OK != @@ -147,18 +148,33 @@ parse_reserve_history (const json_t *history, GNUNET_break_op (0); return GNUNET_SYSERR; } - wire = json_object_get (transaction, - "wire"); - /* check 'wire' is a JSON object (no need to check wireformat, + wire_account = json_object_get (transaction, + "sender_account_details"); + /* check 'wire_account' is a JSON object (no need to check wireformat, but we do at least expect "some" JSON object here) */ - if ( (NULL == wire) || - (! json_is_object (wire)) ) + if ( (NULL == wire_account) || + (! json_is_object (wire_account)) ) { /* not even a JSON 'wire' specification, not acceptable */ GNUNET_break_op (0); + if (NULL != wire_account) + json_decref (wire_account); return GNUNET_SYSERR; } - rhistory[off].details.wire_in_details = wire; + transfer = json_object_get (transaction, + "transfer_details"); + /* check 'transfer' is a JSON object */ + if ( (NULL == transfer) || + (! json_is_object (transfer)) ) + { + GNUNET_break_op (0); + json_decref (wire_account); + if (NULL != transfer) + json_decref (transfer); + return GNUNET_SYSERR; + } + rhistory[off].details.in_details.sender_account_details = wire_account; + rhistory[off].details.in_details.transfer_details = transfer; /* end type==DEPOSIT */ } else if (0 == strcasecmp (type, diff --git a/src/exchange-lib/test_exchange_api.c b/src/exchange-lib/test_exchange_api.c index c9140b3fb..75a9cfbd9 100644 --- a/src/exchange-lib/test_exchange_api.c +++ b/src/exchange-lib/test_exchange_api.c @@ -248,9 +248,14 @@ struct Command const char *amount; /** - * Wire details (JSON). + * Sender account details (JSON). */ - const char *wire; + const char *sender_details; + + /** + * Transfer information identifier (JSON). + */ + const char *transfer_details; /** * Set (by the interpreter) to the reserve's private key @@ -1660,7 +1665,8 @@ interpreter_run (void *cls) struct TALER_CoinSpendPublicKeyP coin_pub; struct TALER_Amount amount; struct GNUNET_TIME_Absolute execution_date; - json_t *wire; + json_t *sender_details; + json_t *transfer_details; const struct GNUNET_SCHEDULER_TaskContext *tc; is->task = NULL; @@ -1710,14 +1716,26 @@ interpreter_run (void *cls) fail (is); return; } - wire = json_loads (cmd->details.admin_add_incoming.wire, - JSON_REJECT_DUPLICATES, - NULL); - if (NULL == wire) + sender_details = json_loads (cmd->details.admin_add_incoming.sender_details, + JSON_REJECT_DUPLICATES, + NULL); + if (NULL == sender_details) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Failed to parse sender details `%s' at %u\n", + cmd->details.admin_add_incoming.sender_details, + is->ip); + fail (is); + return; + } + transfer_details = json_loads (cmd->details.admin_add_incoming.transfer_details, + JSON_REJECT_DUPLICATES, + NULL); + if (NULL == transfer_details) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Failed to parse wire details `%s' at %u\n", - cmd->details.admin_add_incoming.wire, + "Failed to parse transfer details `%s' at %u\n", + cmd->details.admin_add_incoming.transfer_details, is->ip); fail (is); return; @@ -1729,9 +1747,12 @@ interpreter_run (void *cls) &reserve_pub, &amount, execution_date, - wire, + sender_details, + transfer_details, &add_incoming_cb, is); + json_decref (sender_details); + json_decref (transfer_details); if (NULL == cmd->details.admin_add_incoming.aih) { GNUNET_break (0); @@ -2669,7 +2690,8 @@ run (void *cls) { .oc = OC_ADMIN_ADD_INCOMING, .label = "create-reserve-1", .expected_response_code = MHD_HTTP_OK, - .details.admin_add_incoming.wire = "{ \"type\":\"test\", \"bank_uri\":\"http://localhost:8082/\", \"account_number\":42, \"uuid\":1 }", + .details.admin_add_incoming.sender_details = "{ \"type\":\"test\", \"bank_uri\":\"http://localhost:8082/\", \"account_number\":42}", + .details.admin_add_incoming.transfer_details = "{ \"uuid\":1 }", .details.admin_add_incoming.amount = "EUR:5.01" }, /* Withdraw a 5 EUR coin, at fee of 1 ct */ { .oc = OC_WITHDRAW_SIGN, @@ -2737,7 +2759,8 @@ run (void *cls) { .oc = OC_ADMIN_ADD_INCOMING, .label = "refresh-create-reserve-1", .expected_response_code = MHD_HTTP_OK, - .details.admin_add_incoming.wire = "{ \"type\":\"test\", \"bank_uri\":\"http://localhost:8082/\", \"account_number\":424 }", + .details.admin_add_incoming.sender_details = "{ \"type\":\"test\", \"bank_uri\":\"http://localhost:8082/\", \"account_number\":424 }", + .details.admin_add_incoming.transfer_details = "{ \"uuid\":2 }", .details.admin_add_incoming.amount = "EUR:5.01" }, /* Withdraw a 5 EUR coin, at fee of 1 ct */ { .oc = OC_WITHDRAW_SIGN, @@ -2900,7 +2923,8 @@ run (void *cls) { .oc = OC_ADMIN_ADD_INCOMING, .label = "create-reserve-r1", .expected_response_code = MHD_HTTP_OK, - .details.admin_add_incoming.wire = "{ \"type\":\"test\", \"bank_uri\":\"http://localhost:8082/\", \"account_number\":42, \"uuid\":2 }", + .details.admin_add_incoming.sender_details = "{ \"type\":\"test\", \"bank_uri\":\"http://localhost:8082/\", \"account_number\":42 }", + .details.admin_add_incoming.transfer_details = "{ \"uuid\":3 }", .details.admin_add_incoming.amount = "EUR:5.01" }, /* Withdraw a 5 EUR coin, at fee of 1 ct */ { .oc = OC_WITHDRAW_SIGN, diff --git a/src/exchange-tools/taler-exchange-reservemod.c b/src/exchange-tools/taler-exchange-reservemod.c index 2aeb951ce..b87b15923 100644 --- a/src/exchange-tools/taler-exchange-reservemod.c +++ b/src/exchange-tools/taler-exchange-reservemod.c @@ -45,10 +45,15 @@ static char *reserve_pub_str; */ static char *add_str; +/** + * Details about the sender account in JSON format. + */ +static char *sender_details; + /** * Details about the wire transfer in JSON format. */ -static char *details; +static char *transfer_details; /** * Return value from main(). @@ -61,14 +66,16 @@ static int global_ret; * * @param reserve_pub public key of the reserve to use * @param add_value value to add - * @param jdetails JSON details + * @param jdetails JSON details about sender + * @param tdetails JSON details about transfer * @return #GNUNET_OK on success, #GNUNET_SYSERR on hard error, * #GNUNET_NO if record exists */ static int run_transaction (const struct TALER_ReservePublicKeyP *reserve_pub, const struct TALER_Amount *add_value, - json_t *jdetails) + json_t *jdetails, + json_t *tdetails) { int ret; struct TALER_EXCHANGEDB_Session *session; @@ -86,7 +93,8 @@ run_transaction (const struct TALER_ReservePublicKeyP *reserve_pub, reserve_pub, add_value, GNUNET_TIME_absolute_get (), - jdetails); + jdetails, + tdetails); if (GNUNET_SYSERR == ret) { fprintf (stderr, @@ -117,6 +125,7 @@ run (void *cls, { struct TALER_Amount add_value; json_t *jdetails; + json_t *tdetails; json_error_t error; struct TALER_ReservePublicKeyP reserve_pub; @@ -155,24 +164,46 @@ run (void *cls, global_ret = 1; return; } - if (NULL == details) + if (NULL == sender_details) { fprintf (stderr, - "No wiring details given (justification required)\n"); + "No sender details given (sender required)\n"); global_ret = 1; return; } - jdetails = json_loads (details, + jdetails = json_loads (sender_details, JSON_REJECT_DUPLICATES, &error); if (NULL == jdetails) { fprintf (stderr, "Failed to parse JSON transaction details `%s': %s (%s)\n", - details, + sender_details, + error.text, + error.source); + global_ret = 1; + return; + } + if (NULL == transfer_details) + { + fprintf (stderr, + "No transfer details given (justification required)\n"); + global_ret = 1; + json_decref (jdetails); + return; + } + tdetails = json_loads (transfer_details, + JSON_REJECT_DUPLICATES, + &error); + if (NULL == tdetails) + { + fprintf (stderr, + "Failed to parse JSON transaction details `%s': %s (%s)\n", + transfer_details, error.text, error.source); global_ret = 1; + json_decref (jdetails); return; } @@ -187,10 +218,12 @@ run (void *cls, if (GNUNET_SYSERR == run_transaction (&reserve_pub, &add_value, - jdetails)) + jdetails, + tdetails)) global_ret = 1; TALER_EXCHANGEDB_plugin_unload (plugin); json_decref (jdetails); + json_decref (tdetails); } @@ -208,9 +241,12 @@ main (int argc, char *const *argv) {'a', "add", "DENOM", "value to add", 1, &GNUNET_GETOPT_set_string, &add_str}, - {'d', "details", "JSON", - "details about the bank transaction which justify why we add this amount", 1, - &GNUNET_GETOPT_set_string, &details}, + {'s', "sender", "JSON", + "details about the sender's bank account", 1, + &GNUNET_GETOPT_set_string, &sender_details}, + {'t', "transfer", "JSON", + "details that uniquely identify the bank transfer", 1, + &GNUNET_GETOPT_set_string, &transfer_details}, GNUNET_GETOPT_OPTION_HELP ("Deposit funds into a Taler reserve"), {'R', "reserve", "KEY", "reserve (public key) to modify", 1, diff --git a/src/exchange/taler-exchange-httpd_admin.c b/src/exchange/taler-exchange-httpd_admin.c index 6b28e9cc1..618a76583 100644 --- a/src/exchange/taler-exchange-httpd_admin.c +++ b/src/exchange/taler-exchange-httpd_admin.c @@ -114,13 +114,15 @@ TMH_ADMIN_handler_admin_add_incoming (struct TMH_RequestHandler *rh, struct TALER_ReservePublicKeyP reserve_pub; struct TALER_Amount amount; struct GNUNET_TIME_Absolute at; - json_t *wire; + json_t *sender_account_details; + json_t *transfer_details; json_t *root; struct GNUNET_JSON_Specification spec[] = { GNUNET_JSON_spec_fixed_auto ("reserve_pub", &reserve_pub), TALER_JSON_spec_amount ("amount", &amount), GNUNET_JSON_spec_absolute_time ("execution_date", &at), - GNUNET_JSON_spec_json ("wire", &wire), + GNUNET_JSON_spec_json ("sender_account_details", &sender_account_details), + GNUNET_JSON_spec_json ("transfer_details", &transfer_details), GNUNET_JSON_spec_end () }; int res; @@ -148,19 +150,20 @@ TMH_ADMIN_handler_admin_add_incoming (struct TMH_RequestHandler *rh, return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES; } if (GNUNET_YES != - TMH_json_validate_wireformat (wire, + TMH_json_validate_wireformat (sender_account_details, GNUNET_NO)) { GNUNET_break_op (0); GNUNET_JSON_parse_free (spec); return TMH_RESPONSE_reply_arg_unknown (connection, - "wire"); + "sender_account_details"); } res = TMH_DB_execute_admin_add_incoming (connection, &reserve_pub, &amount, at, - wire); + sender_account_details, + transfer_details); GNUNET_JSON_parse_free (spec); return res; } diff --git a/src/exchange/taler-exchange-httpd_db.c b/src/exchange/taler-exchange-httpd_db.c index 7e3ce0a44..43de27e9c 100644 --- a/src/exchange/taler-exchange-httpd_db.c +++ b/src/exchange/taler-exchange-httpd_db.c @@ -1253,7 +1253,7 @@ check_commitment (struct MHD_Connection *connection, struct GNUNET_HashCode h_msg; char *buf; size_t buf_len; - + TALER_refresh_decrypt (&commit_coins[j].refresh_link, &shared_secret, &link_data); @@ -1275,7 +1275,7 @@ check_commitment (struct MHD_Connection *connection, "Blinding error")) ? GNUNET_NO : GNUNET_SYSERR; } - + if ( (buf_len != commit_coins[j].coin_ev_size) || (0 != memcmp (buf, commit_coins[j].coin_ev, @@ -1690,7 +1690,8 @@ TMH_DB_execute_refresh_link (struct MHD_Connection *connection, * @param reserve_pub public key of the reserve * @param amount amount to add to the reserve * @param execution_time when did we receive the wire transfer - * @param wire details about the wire transfer + * @param sender_account_details which account send the funds + * @param transfer_details information that uniquely identifies the transfer * @return MHD result code */ int @@ -1698,7 +1699,8 @@ TMH_DB_execute_admin_add_incoming (struct MHD_Connection *connection, const struct TALER_ReservePublicKeyP *reserve_pub, const struct TALER_Amount *amount, struct GNUNET_TIME_Absolute execution_time, - json_t *wire) + const json_t *sender_account_details, + const json_t *transfer_details) { struct TALER_EXCHANGEDB_Session *session; int ret; @@ -1713,7 +1715,8 @@ TMH_DB_execute_admin_add_incoming (struct MHD_Connection *connection, reserve_pub, amount, execution_time, - wire); + sender_account_details, + transfer_details); if (GNUNET_SYSERR == ret) { GNUNET_break (0); diff --git a/src/exchange/taler-exchange-httpd_db.h b/src/exchange/taler-exchange-httpd_db.h index c0fd110b6..e22d39d81 100644 --- a/src/exchange/taler-exchange-httpd_db.h +++ b/src/exchange/taler-exchange-httpd_db.h @@ -191,7 +191,8 @@ TMH_DB_execute_refresh_link (struct MHD_Connection *connection, * @param reserve_pub public key of the reserve * @param amount amount to add to the reserve * @param execution_time when did we receive the wire transfer - * @param wire details about the wire transfer + * @param sender_account_details which account send the funds + * @param transfer_details information that uniquely identifies the transfer * @return MHD result code */ int @@ -199,7 +200,8 @@ TMH_DB_execute_admin_add_incoming (struct MHD_Connection *connection, const struct TALER_ReservePublicKeyP *reserve_pub, const struct TALER_Amount *amount, struct GNUNET_TIME_Absolute execution_time, - json_t *wire); + const json_t *sender_account_details, + const json_t *transfer_details); /** diff --git a/src/exchange/taler-exchange-httpd_deposit.c b/src/exchange/taler-exchange-httpd_deposit.c index c59f9a6ae..3515a4549 100644 --- a/src/exchange/taler-exchange-httpd_deposit.c +++ b/src/exchange/taler-exchange-httpd_deposit.c @@ -228,7 +228,7 @@ TMH_DEPOSIT_handler_deposit (struct TMH_RequestHandler *rh, TALER_amount_ntoh (&deposit.deposit_fee, &dki->issue.properties.fee_deposit); TMH_KS_release (ks); - deposit.wire = wire; + deposit.receiver_wire_account = wire; deposit.amount_with_fee = amount; if (-1 == TALER_amount_cmp (&deposit.amount_with_fee, &deposit.deposit_fee)) diff --git a/src/exchange/taler-exchange-httpd_responses.c b/src/exchange/taler-exchange-httpd_responses.c index 91b54b0b2..aec2ac27b 100644 --- a/src/exchange/taler-exchange-httpd_responses.c +++ b/src/exchange/taler-exchange-httpd_responses.c @@ -602,9 +602,10 @@ compile_reserve_history (const struct TALER_EXCHANGEDB_ReserveHistory *rh, } ret = 1; json_array_append_new (json_history, - json_pack ("{s:s, s:O, s:o}", + json_pack ("{s:s, s:O, s:O, s:o}", "type", "DEPOSIT", - "wire", pos->details.bank->wire, + "sender_account_details", pos->details.bank->sender_account_details, + "transfer_details", pos->details.bank->transfer_details, "amount", TALER_JSON_from_amount (&pos->details.bank->amount))); break; case TALER_EXCHANGEDB_RO_WITHDRAW_COIN: diff --git a/src/exchange/test_taler_exchange_aggregator.c b/src/exchange/test_taler_exchange_aggregator.c index c9756dad4..7802c8230 100644 --- a/src/exchange/test_taler_exchange_aggregator.c +++ b/src/exchange/test_taler_exchange_aggregator.c @@ -432,12 +432,12 @@ do_deposit (struct Command *cmd) } fake_coin (&deposit.coin); /* Build JSON for wire details */ - deposit.wire = json_pack ("{s:s, s:s, s:I}", - "type", "test", - "bank_uri", "http://localhost:8082/", - "account_number", (json_int_t) cmd->details.deposit.merchant_account); + deposit.receiver_wire_account = json_pack ("{s:s, s:s, s:I}", + "type", "test", + "bank_uri", "http://localhost:8082/", + "account_number", (json_int_t) cmd->details.deposit.merchant_account); GNUNET_assert (GNUNET_OK == - TALER_JSON_hash (deposit.wire, + TALER_JSON_hash (deposit.receiver_wire_account, &deposit.h_wire)); deposit.transaction_id = cmd->details.deposit.transaction_id; deposit.timestamp = GNUNET_TIME_absolute_get (); @@ -458,7 +458,7 @@ do_deposit (struct Command *cmd) else ret = GNUNET_OK; GNUNET_CRYPTO_rsa_signature_free (deposit.coin.denom_sig.rsa_signature); - json_decref (deposit.wire); + json_decref (deposit.receiver_wire_account); return ret; } diff --git a/src/exchangedb/perf_taler_exchangedb_init.c b/src/exchangedb/perf_taler_exchangedb_init.c index 5e98c4f5a..5183074bb 100644 --- a/src/exchangedb/perf_taler_exchangedb_init.c +++ b/src/exchangedb/perf_taler_exchangedb_init.c @@ -276,7 +276,7 @@ PERF_TALER_EXCHANGEDB_deposit_init (const struct PERF_TALER_EXCHANGEDB_Coin *coi deposit->csig = csig; deposit->h_contract = h_contract; deposit->h_wire = h_wire; - deposit->wire = json_loads (wire, 0, NULL); + deposit->receiver_wire_account = json_loads (wire, 0, NULL); deposit->transaction_id = transaction_id++; deposit->timestamp = timestamp; deposit->refund_deadline = refund_deadline; @@ -298,7 +298,7 @@ PERF_TALER_EXCHANGEDB_deposit_copy (const struct TALER_EXCHANGEDB_Deposit *depos copy = GNUNET_new (struct TALER_EXCHANGEDB_Deposit); *copy = *deposit; - json_incref (copy->wire); + json_incref (copy->receiver_wire_account); copy->coin.denom_pub.rsa_public_key = GNUNET_CRYPTO_rsa_public_key_dup (deposit->coin.denom_pub.rsa_public_key); copy->coin.denom_sig.rsa_signature = @@ -318,7 +318,7 @@ PERF_TALER_EXCHANGEDB_deposit_free (struct TALER_EXCHANGEDB_Deposit *deposit) return GNUNET_OK; GNUNET_CRYPTO_rsa_public_key_free (deposit->coin.denom_pub.rsa_public_key); GNUNET_CRYPTO_rsa_signature_free (deposit->coin.denom_sig.rsa_signature); - json_decref (deposit->wire); + json_decref (deposit->receiver_wire_account); GNUNET_free (deposit); return GNUNET_OK; } diff --git a/src/exchangedb/perf_taler_exchangedb_interpreter.c b/src/exchangedb/perf_taler_exchangedb_interpreter.c index 5a2eed95f..e6268ebbc 100644 --- a/src/exchangedb/perf_taler_exchangedb_interpreter.c +++ b/src/exchangedb/perf_taler_exchangedb_interpreter.c @@ -1373,23 +1373,31 @@ interpret (struct PERF_TALER_EXCHANGEDB_interpreter_state *state) unsigned int reserve_index; int ret; struct PERF_TALER_EXCHANGEDB_Reserve *reserve; - json_t *details = NULL; + json_t *sndr; + json_t *just; reserve_index = state->cmd[state->i].details.insert_reserve.index_reserve; reserve = state->cmd[reserve_index].exposed.data.reserve; - details = json_pack ("{s:i}","justification", - GNUNET_CRYPTO_random_u32 ( - GNUNET_CRYPTO_QUALITY_WEAK, - UINT32_MAX)); - GNUNET_assert (NULL != details); + sndr = json_pack ("{s:i}", + "account", + (int) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, + UINT32_MAX)); + just = json_pack ("{s:i}", + "justification", + (int) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, + UINT32_MAX)); + GNUNET_assert (NULL != just); + GNUNET_assert (NULL != sndr); ret = state->plugin->reserves_in_insert (state->plugin->cls, state->session, &reserve->reserve.pub, &reserve->reserve.balance, GNUNET_TIME_absolute_get (), - details); + sndr, + just); GNUNET_assert (GNUNET_SYSERR != ret); - json_decref (details); + json_decref (sndr); + json_decref (just); } break; diff --git a/src/exchangedb/plugin_exchangedb_common.c b/src/exchangedb/plugin_exchangedb_common.c index 16396f0f3..3bf9bda32 100644 --- a/src/exchangedb/plugin_exchangedb_common.c +++ b/src/exchangedb/plugin_exchangedb_common.c @@ -40,8 +40,10 @@ common_free_reserve_history (void *cls, { case TALER_EXCHANGEDB_RO_BANK_TO_EXCHANGE: bt = rh->details.bank; - if (NULL != bt->wire) - json_decref (bt->wire); + if (NULL != bt->sender_account_details) + json_decref (bt->sender_account_details); + if (NULL != bt->transfer_details) + json_decref (bt->transfer_details); GNUNET_free (bt); break; case TALER_EXCHANGEDB_RO_WITHDRAW_COIN: @@ -98,7 +100,7 @@ common_free_coin_transaction_list (void *cls, switch (list->type) { case TALER_EXCHANGEDB_TT_DEPOSIT: - json_decref (list->details.deposit->wire); + json_decref (list->details.deposit->receiver_wire_account); if (NULL != list->details.deposit->coin.denom_pub.rsa_public_key) GNUNET_CRYPTO_rsa_public_key_free (list->details.deposit->coin.denom_pub.rsa_public_key); if (NULL != list->details.deposit->coin.denom_sig.rsa_signature) diff --git a/src/exchangedb/plugin_exchangedb_postgres.c b/src/exchangedb/plugin_exchangedb_postgres.c index 8465e4de0..34cffa0f5 100644 --- a/src/exchangedb/plugin_exchangedb_postgres.c +++ b/src/exchangedb/plugin_exchangedb_postgres.c @@ -305,9 +305,10 @@ postgres_create_tables (void *cls) ",balance_val INT8 NOT NULL" ",balance_frac INT4 NOT NULL" ",balance_curr VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL" - ",details TEXT NOT NULL " + ",sender_account_details TEXT NOT NULL " + ",transfer_details TEXT NOT NULL " ",execution_date INT8 NOT NULL" - ",PRIMARY KEY (reserve_pub,details)" + ",PRIMARY KEY (reserve_pub,transfer_details)" ");"); /* Create indices on reserves_in */ SQLEXEC_INDEX ("CREATE INDEX reserves_in_reserve_pub_index" @@ -627,11 +628,12 @@ postgres_prepare (PGconn *db_conn) ",balance_val" ",balance_frac" ",balance_curr" - ",details" + ",sender_account_details" + ",transfer_details" ",execution_date" ") VALUES " - "($1, $2, $3, $4, $5, $6);", - 6, NULL); + "($1, $2, $3, $4, $5, $6, $7);", + 7, NULL); /* Used in #postgres_get_reserve_history() to obtain inbound transactions for a reserve */ @@ -641,7 +643,8 @@ postgres_prepare (PGconn *db_conn) ",balance_frac" ",balance_curr" ",execution_date" - ",details" + ",sender_account_details" + ",transfer_details" " FROM reserves_in" " WHERE reserve_pub=$1", 1, NULL); @@ -1634,8 +1637,8 @@ reserves_update (void *cls, * @param reserve_pub public key of the reserve * @param balance the amount that has to be added to the reserve * @param execution_time when was the amount added - * @param details bank transaction details justifying the increment, - * must be unique for each incoming transaction + * @param sender_account_details account information for the sender + * @param transfer_details information that uniquely identifies the transfer * @return #GNUNET_OK upon success; #GNUNET_NO if the given * @a details are already known for this @a reserve_pub, * #GNUNET_SYSERR upon failures (DB error, incompatible currency) @@ -1646,7 +1649,8 @@ postgres_reserves_in_insert (void *cls, const struct TALER_ReservePublicKeyP *reserve_pub, const struct TALER_Amount *balance, struct GNUNET_TIME_Absolute execution_time, - const json_t *details) + const json_t *sender_account_details, + const json_t *transfer_details) { PGresult *result; int reserve_exists; @@ -1688,8 +1692,8 @@ postgres_reserves_in_insert (void *cls, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Reserve does not exist; creating a new one\n"); result = GNUNET_PQ_exec_prepared (session->conn, - "reserve_create", - params); + "reserve_create", + params); if (PGRES_COMMAND_OK != PQresultStatus(result)) { QUERY_ERR (result); @@ -1707,14 +1711,15 @@ postgres_reserves_in_insert (void *cls, struct GNUNET_PQ_QueryParam params[] = { GNUNET_PQ_query_param_auto_from_type (&reserve.pub), TALER_PQ_query_param_amount (balance), - TALER_PQ_query_param_json (details), + TALER_PQ_query_param_json (sender_account_details), + TALER_PQ_query_param_json (transfer_details), GNUNET_PQ_query_param_absolute_time (&execution_time), GNUNET_PQ_query_param_end }; result = GNUNET_PQ_exec_prepared (session->conn, - "reserves_in_add_transaction", - params); + "reserves_in_add_transaction", + params); } if (PGRES_COMMAND_OK != PQresultStatus(result)) { @@ -1989,8 +1994,10 @@ postgres_get_reserve_history (void *cls, &bt->amount), GNUNET_PQ_result_spec_absolute_time ("execution_date", &bt->execution_date), - TALER_PQ_result_spec_json ("details", - &bt->wire), + TALER_PQ_result_spec_json ("sender_account_details", + &bt->sender_account_details), + TALER_PQ_result_spec_json ("transfer_details", + &bt->transfer_details), GNUNET_PQ_result_spec_end }; if (GNUNET_OK != @@ -2647,7 +2654,7 @@ postgres_insert_deposit (void *cls, GNUNET_PQ_query_param_auto_from_type (&deposit->h_contract), GNUNET_PQ_query_param_auto_from_type (&deposit->h_wire), GNUNET_PQ_query_param_auto_from_type (&deposit->csig), - TALER_PQ_query_param_json (deposit->wire), + TALER_PQ_query_param_json (deposit->receiver_wire_account), GNUNET_PQ_query_param_end }; @@ -3484,7 +3491,7 @@ postgres_get_link_data_list (void *cls, &denom_pub), GNUNET_PQ_result_spec_end }; - + if (GNUNET_OK != GNUNET_PQ_extract_result (result, rs, i)) { @@ -3643,7 +3650,7 @@ postgres_get_coin_transactions (void *cls, GNUNET_PQ_result_spec_auto_from_type ("h_wire", &deposit->h_wire), TALER_PQ_result_spec_json ("wire", - &deposit->wire), + &deposit->receiver_wire_account), GNUNET_PQ_result_spec_auto_from_type ("coin_sig", &deposit->csig), GNUNET_PQ_result_spec_end diff --git a/src/exchangedb/test_exchangedb.c b/src/exchangedb/test_exchangedb.c index 355ef6a87..6d624f407 100644 --- a/src/exchangedb/test_exchangedb.c +++ b/src/exchangedb/test_exchangedb.c @@ -974,9 +974,6 @@ deposit_cb (void *cls, } - - - /** * Main function that will be run by the scheduler. * @@ -1003,6 +1000,7 @@ run (void *cls) struct TALER_WireTransferIdentifierRawP wtid; json_t *wire; json_t *just; + json_t *sndr; unsigned int matched; const char * const json_wire_str = "{ \"type\":\"SEPA\", \ @@ -1060,6 +1058,7 @@ run (void *cls) &amount_with_fee)); result = 4; + sndr = json_loads ("{ \"account\":\"1\" }", 0, NULL); just = json_loads ("{ \"justification\":\"1\" }", 0, NULL); FAILIF (GNUNET_OK != plugin->reserves_in_insert (plugin->cls, @@ -1067,6 +1066,7 @@ run (void *cls) &reserve_pub, &value, GNUNET_TIME_absolute_get (), + sndr, just)); json_decref (just); FAILIF (GNUNET_OK != @@ -1082,8 +1082,10 @@ run (void *cls) &reserve_pub, &value, GNUNET_TIME_absolute_get (), - just)); + sndr, + just)); json_decref (just); + json_decref (sndr); FAILIF (GNUNET_OK != check_reserve (session, &reserve_pub, @@ -1153,7 +1155,8 @@ run (void *cls) FAILIF (1 != bt->amount.value); FAILIF (10 != bt->amount.fraction); FAILIF (0 != strcmp (CURRENCY, bt->amount.currency)); - FAILIF (NULL == bt->wire); + FAILIF (NULL == bt->sender_account_details); + FAILIF (NULL == bt->transfer_details); break; case TALER_EXCHANGEDB_RO_WITHDRAW_COIN: withdraw = rh_head->details.withdraw; @@ -1178,7 +1181,7 @@ run (void *cls) wire = json_loads (json_wire_str, 0, NULL); TALER_JSON_hash (wire, &deposit.h_wire); - deposit.wire = wire; + deposit.receiver_wire_account = wire; deposit.transaction_id = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, UINT64_MAX); deposit.amount_with_fee = value; diff --git a/src/include/taler_exchange_service.h b/src/include/taler_exchange_service.h index bcc794107..62fc64b6f 100644 --- a/src/include/taler_exchange_service.h +++ b/src/include/taler_exchange_service.h @@ -604,10 +604,19 @@ struct TALER_EXCHANGE_ReserveHistory */ union { - /** - * Transaction details for the incoming transaction. - */ - json_t *wire_in_details; + struct { + /** + * Sender account information for the incoming transfer. + */ + json_t *sender_account_details; + + /** + * Wire transfer details for the incoming transfer. + */ + json_t *transfer_details; + + + } in_details; /** * Signature authorizing the withdrawal for outgoing transaction. @@ -1036,7 +1045,10 @@ typedef void * @param reserve_pub public key of the reserve * @param amount amount that was deposited * @param execution_date when did we receive the amount - * @param wire wire details + * @param sender_account_details account information of the sender of the money; + * the receiver is always the exchange. + * @param transfer_details details that uniquely identify the transfer; + * used to check for duplicate operations by the exchange * @param res_cb the callback to call when the final result for this request is available * @param res_cb_cls closure for the above callback * @return NULL @@ -1048,7 +1060,8 @@ TALER_EXCHANGE_admin_add_incoming (struct TALER_EXCHANGE_Handle *exchange, const struct TALER_ReservePublicKeyP *reserve_pub, const struct TALER_Amount *amount, struct GNUNET_TIME_Absolute execution_date, - const json_t *wire, + const json_t *sender_account_details, + const json_t *transfer_details, TALER_EXCHANGE_AdminAddIncomingResultCallback res_cb, void *res_cb_cls); diff --git a/src/include/taler_exchangedb_plugin.h b/src/include/taler_exchangedb_plugin.h index 59e33a9eb..e8d2c80e8 100644 --- a/src/include/taler_exchangedb_plugin.h +++ b/src/include/taler_exchangedb_plugin.h @@ -51,9 +51,15 @@ struct TALER_EXCHANGEDB_BankTransfer struct GNUNET_TIME_Absolute execution_date; /** - * Detailed wire information about the transaction. + * Detailed wire information about the sending account. */ - json_t *wire; + json_t *sender_account_details; + + /** + * Detailed wire transfer information that uniquely identifies the + * wire transfer. + */ + json_t *transfer_details; }; @@ -243,9 +249,9 @@ struct TALER_EXCHANGEDB_Deposit struct GNUNET_HashCode h_wire; /** - * Detailed wire information for executing the transaction. + * Detailed information about the receiver for executing the transaction. */ - json_t *wire; + json_t *receiver_wire_account; /** * Merchant-generated transaction ID to detect duplicate @@ -601,7 +607,7 @@ struct TALER_EXCHANGEDB_Session; * @param h_contract hash of the contract between merchant and customer * @param wire_deadline by which the merchant adviced that he would like the * wire transfer to be executed - * @param wire wire details for the merchant, NULL from iterate_matching_deposits() + * @param receiver_wire_account wire details for the merchant, NULL from iterate_matching_deposits() * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop */ typedef int @@ -614,7 +620,7 @@ typedef int uint64_t transaction_id, const struct GNUNET_HashCode *h_contract, struct GNUNET_TIME_Absolute wire_deadline, - const json_t *wire); + const json_t *receiver_wire_account); /** @@ -842,8 +848,8 @@ struct TALER_EXCHANGEDB_Plugin * @param reserve_pub public key of the reserve * @param balance the amount that has to be added to the reserve * @param execution_time when was the amount added - * @param details bank transaction details justifying the increment, - * must be unique for each incoming transaction + * @param sender_account_details information about the sender + * @param transfer_details information that uniquely identifies the wire transfer * @return #GNUNET_OK upon success; #GNUNET_NO if the given * @a details are already known for this @a reserve_pub, * #GNUNET_SYSERR upon failures (DB error, incompatible currency) @@ -854,7 +860,8 @@ struct TALER_EXCHANGEDB_Plugin const struct TALER_ReservePublicKeyP *reserve_pub, const struct TALER_Amount *balance, struct GNUNET_TIME_Absolute execution_time, - const json_t *details); + const json_t *sender_account_details, + const json_t *transfer_details); /** -- cgit v1.2.3