From c1f28638c9929424f9ad395c7016e6ea2022d751 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sun, 17 Jan 2016 18:19:09 +0100 Subject: working on #3888 --- src/mint/taler-mint-httpd_db.c | 198 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 191 insertions(+), 7 deletions(-) (limited to 'src/mint/taler-mint-httpd_db.c') diff --git a/src/mint/taler-mint-httpd_db.c b/src/mint/taler-mint-httpd_db.c index 2b4ade595..1b0af585d 100644 --- a/src/mint/taler-mint-httpd_db.c +++ b/src/mint/taler-mint-httpd_db.c @@ -1551,10 +1551,190 @@ TMH_DB_execute_admin_add_incoming (struct MHD_Connection *connection, } +/** + * Closure for #handle_transaction_data. + */ +struct WtidTransactionContext +{ + + /** + * Total amount of the wire transfer, as calculated by + * summing up the individual amounts. To be rounded down + * to calculate the real transfer amount at the end. + * Only valid if @e is_valid is #GNUNET_YES. + */ + struct TALER_Amount total; + + /** + * Public key of the merchant, only valid if @e is_valid + * is #GNUNET_YES. + */ + struct TALER_MerchantPublicKeyP merchant_pub; + + /** + * Hash of the wire details of the merchant (identical for all + * deposits), only valid if @e is_valid is #GNUNET_YES. + */ + struct GNUNET_HashCode h_wire; + + /** + * JSON array with details about the individual deposits. + */ + json_t *deposits; + + /** + * Initially #GNUNET_NO, if we found no deposits so far. Set to + * #GNUNET_YES if we got transaction data, and the database replies + * remained consistent with respect to @e merchant_pub and @e h_wire + * (as they should). Set to #GNUNET_SYSERR if we encountered an + * internal error. + */ + int is_valid; + +}; + + +/** + * Function called with the results of the lookup of the + * transaction data for the given wire transfer identifier. + * + * @param cls our context for transmission + * @param merchant_pub public key of the merchant (should be same for all callbacks with the same @e cls) + * @param h_wire hash of wire transfer details of the merchant (should be same for all callbacks with the same @e cls) + * @param h_contract which contract was this payment about + * @param transaction_id merchant's transaction ID for the payment + * @param coin_pub which public key was this payment about + * @param deposit_value amount contributed by this coin in total + * @param deposit_fee deposit fee charged by mint for this coin + */ +static void +handle_transaction_data (void *cls, + const struct TALER_MerchantPublicKeyP *merchant_pub, + const struct GNUNET_HashCode *h_wire, + const struct GNUNET_HashCode *h_contract, + uint64_t transaction_id, + const struct TALER_CoinSpendPublicKeyP *coin_pub, + const struct TALER_Amount *deposit_value, + const struct TALER_Amount *deposit_fee) +{ + struct WtidTransactionContext *ctx = cls; + struct TALER_Amount delta; + + if (GNUNET_SYSERR == ctx->is_valid) + return; + if (GNUNET_NO == ctx->is_valid) + { + ctx->merchant_pub = *merchant_pub; + ctx->h_wire = *h_wire; + ctx->is_valid = GNUNET_YES; + if (GNUNET_OK != + TALER_amount_subtract (&ctx->total, + deposit_value, + deposit_fee)) + { + GNUNET_break (0); + ctx->is_valid = GNUNET_SYSERR; + return; + } + } + else + { + if ( (0 != memcmp (&ctx->merchant_pub, + merchant_pub, + sizeof (struct TALER_MerchantPublicKeyP))) || + (0 != memcmp (&ctx->h_wire, + h_wire, + sizeof (struct GNUNET_HashCode))) ) + { + GNUNET_break (0); + ctx->is_valid = GNUNET_SYSERR; + return; + } + if (GNUNET_OK != + TALER_amount_subtract (&delta, + deposit_value, + deposit_fee)) + { + GNUNET_break (0); + ctx->is_valid = GNUNET_SYSERR; + return; + } + if (GNUNET_OK != + TALER_amount_add (&ctx->total, + &ctx->total, + &delta)) + { + GNUNET_break (0); + ctx->is_valid = GNUNET_SYSERR; + return; + } + } + /* NOTE: We usually keep JSON stuff out of the _DB file, and this + is also ugly if we ever add signatures over this data. (#4135) */ + json_array_append (ctx->deposits, + json_pack ("{s:o, s:o, s:o, s:I, s:o}", + "deposit_value", TALER_json_from_amount (deposit_value), + "deposit_fee", TALER_json_from_amount (deposit_fee), + "H_contract", TALER_json_from_data (h_contract, + sizeof (struct GNUNET_HashCode)), + "transaction_id", (json_int_t) transaction_id, + "coin_pub", TALER_json_from_data (coin_pub, + sizeof (struct TALER_CoinSpendPublicKeyP)))); +} + + +/** + * Execute a "/wire/deposits". Returns the transaction information + * associated with the given wire transfer identifier. + * + * @param connection the MHD connection to handle + * @param wtid wire transfer identifier to resolve + * @return MHD result code + */ +int +TMH_DB_execute_wire_deposits (struct MHD_Connection *connection, + const struct TALER_WireTransferIdentifierP *wtid) +{ + int ret; + struct WtidTransactionContext ctx; + + ctx.is_valid = GNUNET_NO; + ctx.deposits = json_array (); + ret = TMH_plugin->lookup_wire_transactions (TMH_plugin->cls, + &wtid->raw, + sizeof (wtid->raw), + &handle_transaction_data, + &ctx); + if (GNUNET_SYSERR == ret) + { + GNUNET_break (0); + json_decref (ctx.deposits); + return TMH_RESPONSE_reply_internal_db_error (connection); + } + if (GNUNET_SYSERR == ctx.is_valid) + { + GNUNET_break (0); + json_decref (ctx.deposits); + return TMH_RESPONSE_reply_internal_db_error (connection); + } + if (GNUNET_NO == ctx.is_valid) + { + json_decref (ctx.deposits); + return TMH_RESPONSE_reply_arg_unknown (connection, + "wtid"); + } + return TMH_RESPONSE_reply_wire_deposit_details (connection, + &ctx.total, + &ctx.merchant_pub, + &ctx.h_wire, + ctx.deposits); +} + + /** * Closure for #handle_wtid_data. */ -struct DepositWtidContext +struct DepositWtidContext { /** @@ -1572,7 +1752,7 @@ struct DepositWtidContext /** * Function called with the results of the lookup of the * wire transfer identifier information. - * + * * @param cls our context for transmission * @param wtid base32-encoded wire transfer identifier, NULL * if the transaction was not yet done @@ -1590,16 +1770,19 @@ handle_wtid_data (void *cls, if (NULL == wtid) { - if (GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us == + if (GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us == execution_time.abs_value_us) ctx->res = TMH_RESPONSE_reply_deposit_unknown (ctx->connection); else - ctx->res = TMH_RESPONSE_reply_deposit_pending (ctx->connection); + ctx->res = TMH_RESPONSE_reply_deposit_pending (ctx->connection, + execution_time); } else { - ctx->res = TMH_RESPONSE_reply_deposit_wtid (ctx->connection); - } + ctx->res = TMH_RESPONSE_reply_deposit_wtid (ctx->connection, + wtid, + execution_time); + } } @@ -1627,6 +1810,7 @@ TMH_DB_execute_deposit_wtid (struct MHD_Connection *connection, struct DepositWtidContext ctx; ctx.connection = connection; + ctx.res = MHD_NO; /* this value should never be read... */ ret = TMH_plugin->wire_lookup_deposit_wtid (TMH_plugin->cls, h_contract, h_wire, @@ -1634,7 +1818,7 @@ TMH_DB_execute_deposit_wtid (struct MHD_Connection *connection, merchant_pub, transaction_id, &handle_wtid_data, - connection); + &ctx); if (GNUNET_SYSERR == ret) { GNUNET_break (0); -- cgit v1.2.3 From 80f6c4240ee26884ac2dfdc02ff6b8aac0951777 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Tue, 19 Jan 2016 14:39:00 +0100 Subject: -fix (C) notices --- src/include/taler_amount_lib.h | 2 +- src/include/taler_crypto_lib.h | 2 +- src/include/taler_json_lib.h | 2 +- src/include/taler_mint_service.h | 2 +- src/include/taler_mintdb_lib.h | 2 +- src/include/taler_mintdb_plugin.h | 2 +- src/include/taler_pq_lib.h | 2 +- src/include/taler_signatures.h | 2 +- src/include/taler_util.h | 2 +- src/include/taler_util_wallet.h | 2 +- src/mint-lib/mint_api_admin.c | 2 +- src/mint-lib/mint_api_common.c | 2 +- src/mint-lib/mint_api_common.h | 2 +- src/mint-lib/mint_api_context.c | 2 +- src/mint-lib/mint_api_context.h | 2 +- src/mint-lib/mint_api_deposit.c | 2 +- src/mint-lib/mint_api_handle.c | 2 +- src/mint-lib/mint_api_handle.h | 2 +- src/mint-lib/mint_api_refresh.c | 2 +- src/mint-lib/mint_api_refresh_link.c | 2 +- src/mint-lib/mint_api_reserve.c | 2 +- src/mint-lib/mint_api_wire.c | 2 +- src/mint-lib/test_mint_api.c | 2 +- src/mint-tools/taler-auditor-sign.c | 2 +- src/mint-tools/taler-mint-dbinit.c | 2 +- src/mint-tools/taler-mint-keycheck.c | 2 +- src/mint-tools/taler-mint-keyup.c | 2 +- src/mint-tools/taler-mint-reservemod.c | 2 +- src/mint-tools/taler-mint-sepa.c | 2 +- src/mint/taler-mint-httpd_db.c | 2 +- src/mint/taler-mint-httpd_db.h | 2 +- src/mintdb/mintdb_keyio.c | 2 +- src/mintdb/mintdb_plugin.c | 2 +- src/mintdb/perf_taler_mintdb.c | 2 +- src/mintdb/perf_taler_mintdb_init.c | 2 +- src/mintdb/perf_taler_mintdb_init.h | 2 +- src/mintdb/perf_taler_mintdb_interpreter.c | 2 +- src/mintdb/perf_taler_mintdb_interpreter.h | 2 +- src/mintdb/perf_taler_mintdb_values.h | 2 +- src/mintdb/plugin_mintdb_common.c | 2 +- src/mintdb/plugin_mintdb_postgres.c | 2 +- src/mintdb/test_mintdb.c | 2 +- src/mintdb/test_mintdb_deposits.c | 2 +- src/mintdb/test_perf_taler_mintdb.c | 2 +- src/pq/db_pq.c | 2 +- src/pq/pq_helper.c | 2 +- src/pq/test_pq.c | 2 +- src/util/amount.c | 2 +- src/util/crypto.c | 2 +- src/util/json.c | 2 +- src/util/os_installation.c | 2 +- src/util/test_amount.c | 2 +- src/util/test_crypto.c | 2 +- src/util/test_json.c | 2 +- src/util/test_wireformats.c | 2 +- src/util/util.c | 2 +- src/util/wireformats.c | 2 +- 57 files changed, 57 insertions(+), 57 deletions(-) (limited to 'src/mint/taler-mint-httpd_db.c') diff --git a/src/include/taler_amount_lib.h b/src/include/taler_amount_lib.h index 8661ed913..094b96f7f 100644 --- a/src/include/taler_amount_lib.h +++ b/src/include/taler_amount_lib.h @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014, 2015 Christian Grothoff (and other contributing authors) + Copyright (C) 2014, 2015 GNUnet e.V. TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software diff --git a/src/include/taler_crypto_lib.h b/src/include/taler_crypto_lib.h index 87020fbbe..20cb434f1 100644 --- a/src/include/taler_crypto_lib.h +++ b/src/include/taler_crypto_lib.h @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014, 2015 Christian Grothoff (and other contributing authors) + Copyright (C) 2014, 2015 GNUnet e.V. TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software diff --git a/src/include/taler_json_lib.h b/src/include/taler_json_lib.h index 8bdcf2709..d9fa05188 100644 --- a/src/include/taler_json_lib.h +++ b/src/include/taler_json_lib.h @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014, 2015 Christian Grothoff (and other contributing authors) + Copyright (C) 2014, 2015 GNUnet e.V. TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software diff --git a/src/include/taler_mint_service.h b/src/include/taler_mint_service.h index 78650edfe..a7b6afd11 100644 --- a/src/include/taler_mint_service.h +++ b/src/include/taler_mint_service.h @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014, 2015 Christian Grothoff (and other contributing authors) + Copyright (C) 2014, 2015 GNUnet e.V. TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software diff --git a/src/include/taler_mintdb_lib.h b/src/include/taler_mintdb_lib.h index 7dfef8dc5..70e314d9a 100644 --- a/src/include/taler_mintdb_lib.h +++ b/src/include/taler_mintdb_lib.h @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014, 2015 Christian Grothoff (and other contributing authors) + Copyright (C) 2014, 2015 GNUnet e.V. TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software diff --git a/src/include/taler_mintdb_plugin.h b/src/include/taler_mintdb_plugin.h index a4a94faa9..90319b964 100644 --- a/src/include/taler_mintdb_plugin.h +++ b/src/include/taler_mintdb_plugin.h @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014, 2015 Christian Grothoff (and other contributing authors) + Copyright (C) 2014, 2015 GNUnet e.V. TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software diff --git a/src/include/taler_pq_lib.h b/src/include/taler_pq_lib.h index 2fe66c52f..e0ca429e1 100644 --- a/src/include/taler_pq_lib.h +++ b/src/include/taler_pq_lib.h @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014, 2015 Christian Grothoff (and other contributing authors) + Copyright (C) 2014, 2015 GNUnet e.V. TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software diff --git a/src/include/taler_signatures.h b/src/include/taler_signatures.h index ef9486e49..ac0119831 100644 --- a/src/include/taler_signatures.h +++ b/src/include/taler_signatures.h @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014, 2015 Christian Grothoff (and other contributing authors) + Copyright (C) 2014, 2015, 2016 GNUnet e.V. TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software diff --git a/src/include/taler_util.h b/src/include/taler_util.h index b6dd9596a..380901812 100644 --- a/src/include/taler_util.h +++ b/src/include/taler_util.h @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014, 2015 Christian Grothoff (and other contributing authors) + Copyright (C) 2014, 2015 GNUnet e.V. TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software diff --git a/src/include/taler_util_wallet.h b/src/include/taler_util_wallet.h index 4699a469d..87efcddaa 100644 --- a/src/include/taler_util_wallet.h +++ b/src/include/taler_util_wallet.h @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014, 2015 Christian Grothoff (and other contributing authors) + Copyright (C) 2014, 2015 GNUnet e.V. TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software diff --git a/src/mint-lib/mint_api_admin.c b/src/mint-lib/mint_api_admin.c index 472b02e7d..641e0690f 100644 --- a/src/mint-lib/mint_api_admin.c +++ b/src/mint-lib/mint_api_admin.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014, 2015 Christian Grothoff (and other contributing authors) + Copyright (C) 2014, 2015 GNUnet e.V. TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software diff --git a/src/mint-lib/mint_api_common.c b/src/mint-lib/mint_api_common.c index fd85fbdc4..faba38c74 100644 --- a/src/mint-lib/mint_api_common.c +++ b/src/mint-lib/mint_api_common.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2015 Christian Grothoff (and other contributing authors) + Copyright (C) 2015 GNUnet e.V. TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software diff --git a/src/mint-lib/mint_api_common.h b/src/mint-lib/mint_api_common.h index d256fa428..10a202146 100644 --- a/src/mint-lib/mint_api_common.h +++ b/src/mint-lib/mint_api_common.h @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2015 Christian Grothoff (and other contributing authors) + Copyright (C) 2015 GNUnet e.V. TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software diff --git a/src/mint-lib/mint_api_context.c b/src/mint-lib/mint_api_context.c index e60e01b07..3a86efb64 100644 --- a/src/mint-lib/mint_api_context.c +++ b/src/mint-lib/mint_api_context.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014, 2015 Christian Grothoff (and other contributing authors) + Copyright (C) 2014, 2015 GNUnet e.V. TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software diff --git a/src/mint-lib/mint_api_context.h b/src/mint-lib/mint_api_context.h index 79613cc8b..181a4808f 100644 --- a/src/mint-lib/mint_api_context.h +++ b/src/mint-lib/mint_api_context.h @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014, 2015 Christian Grothoff (and other contributing authors) + Copyright (C) 2014, 2015 GNUnet e.V. TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software diff --git a/src/mint-lib/mint_api_deposit.c b/src/mint-lib/mint_api_deposit.c index 58436adfa..400372925 100644 --- a/src/mint-lib/mint_api_deposit.c +++ b/src/mint-lib/mint_api_deposit.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014, 2015 Christian Grothoff (and other contributing authors) + Copyright (C) 2014, 2015 GNUnet e.V. TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software diff --git a/src/mint-lib/mint_api_handle.c b/src/mint-lib/mint_api_handle.c index 49960cb10..077e42c24 100644 --- a/src/mint-lib/mint_api_handle.c +++ b/src/mint-lib/mint_api_handle.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014, 2015 Christian Grothoff (and other contributing authors) + Copyright (C) 2014, 2015 GNUnet e.V. TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software diff --git a/src/mint-lib/mint_api_handle.h b/src/mint-lib/mint_api_handle.h index fae30a309..0dae58db6 100644 --- a/src/mint-lib/mint_api_handle.h +++ b/src/mint-lib/mint_api_handle.h @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014, 2015 Christian Grothoff (and other contributing authors) + Copyright (C) 2014, 2015 GNUnet e.V. TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software diff --git a/src/mint-lib/mint_api_refresh.c b/src/mint-lib/mint_api_refresh.c index 9effa3d40..cea16b153 100644 --- a/src/mint-lib/mint_api_refresh.c +++ b/src/mint-lib/mint_api_refresh.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2015 Christian Grothoff (and other contributing authors) + Copyright (C) 2015 GNUnet e.V. TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software diff --git a/src/mint-lib/mint_api_refresh_link.c b/src/mint-lib/mint_api_refresh_link.c index d4060bd1c..17c96039e 100644 --- a/src/mint-lib/mint_api_refresh_link.c +++ b/src/mint-lib/mint_api_refresh_link.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2015 Christian Grothoff (and other contributing authors) + Copyright (C) 2015 GNUnet e.V. TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software diff --git a/src/mint-lib/mint_api_reserve.c b/src/mint-lib/mint_api_reserve.c index a726eca46..1f8140cff 100644 --- a/src/mint-lib/mint_api_reserve.c +++ b/src/mint-lib/mint_api_reserve.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014, 2015 Christian Grothoff (and other contributing authors) + Copyright (C) 2014, 2015 GNUnet e.V. TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software diff --git a/src/mint-lib/mint_api_wire.c b/src/mint-lib/mint_api_wire.c index 5fc82f72d..0947354ad 100644 --- a/src/mint-lib/mint_api_wire.c +++ b/src/mint-lib/mint_api_wire.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014, 2015 Christian Grothoff (and other contributing authors) + Copyright (C) 2014, 2015 GNUnet e.V. TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software diff --git a/src/mint-lib/test_mint_api.c b/src/mint-lib/test_mint_api.c index 024e080fc..0e3b2bed8 100644 --- a/src/mint-lib/test_mint_api.c +++ b/src/mint-lib/test_mint_api.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014, 2015 Christian Grothoff (and other contributing authors) + Copyright (C) 2014, 2015 GNUnet e.V. TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software diff --git a/src/mint-tools/taler-auditor-sign.c b/src/mint-tools/taler-auditor-sign.c index bd37e68de..7e6d3b12a 100644 --- a/src/mint-tools/taler-auditor-sign.c +++ b/src/mint-tools/taler-auditor-sign.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014, 2015 Christian Grothoff (and other contributing authors) + Copyright (C) 2014, 2015 GNUnet e.V. TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software diff --git a/src/mint-tools/taler-mint-dbinit.c b/src/mint-tools/taler-mint-dbinit.c index 3293a69ab..2d9f77764 100644 --- a/src/mint-tools/taler-mint-dbinit.c +++ b/src/mint-tools/taler-mint-dbinit.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014, 2015 Christian Grothoff (and other contributing authors) + Copyright (C) 2014, 2015 GNUnet e.V. TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software diff --git a/src/mint-tools/taler-mint-keycheck.c b/src/mint-tools/taler-mint-keycheck.c index c5ac86cb6..4fa2707f8 100644 --- a/src/mint-tools/taler-mint-keycheck.c +++ b/src/mint-tools/taler-mint-keycheck.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014, 2015 Christian Grothoff (and other contributing authors) + Copyright (C) 2014, 2015 GNUnet e.V. TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software diff --git a/src/mint-tools/taler-mint-keyup.c b/src/mint-tools/taler-mint-keyup.c index e2c8d7986..b82554b94 100644 --- a/src/mint-tools/taler-mint-keyup.c +++ b/src/mint-tools/taler-mint-keyup.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014, 2015 Christian Grothoff (and other contributing authors) + Copyright (C) 2014, 2015 GNUnet e.V. TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software diff --git a/src/mint-tools/taler-mint-reservemod.c b/src/mint-tools/taler-mint-reservemod.c index 11d67ed5d..38d27054a 100644 --- a/src/mint-tools/taler-mint-reservemod.c +++ b/src/mint-tools/taler-mint-reservemod.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014, 2015 Christian Grothoff (and other contributing authors) + Copyright (C) 2014, 2015 GNUnet e.V. TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software diff --git a/src/mint-tools/taler-mint-sepa.c b/src/mint-tools/taler-mint-sepa.c index 21f4af9c4..e66db541e 100644 --- a/src/mint-tools/taler-mint-sepa.c +++ b/src/mint-tools/taler-mint-sepa.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2015 Christian Grothoff (and other contributing authors) + Copyright (C) 2015 GNUnet e.V. TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software diff --git a/src/mint/taler-mint-httpd_db.c b/src/mint/taler-mint-httpd_db.c index 1b0af585d..14e03dfd2 100644 --- a/src/mint/taler-mint-httpd_db.c +++ b/src/mint/taler-mint-httpd_db.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014, 2015 Christian Grothoff (and other contributing authors) + Copyright (C) 2014, 2015 GNUnet e.V. TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software diff --git a/src/mint/taler-mint-httpd_db.h b/src/mint/taler-mint-httpd_db.h index 0ee3d0509..e366112dd 100644 --- a/src/mint/taler-mint-httpd_db.h +++ b/src/mint/taler-mint-httpd_db.h @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014, 2015 Christian Grothoff (and other contributing authors) + Copyright (C) 2014, 2015 GNUnet e.V. TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software diff --git a/src/mintdb/mintdb_keyio.c b/src/mintdb/mintdb_keyio.c index 5bfe5bb12..89ac9055a 100644 --- a/src/mintdb/mintdb_keyio.c +++ b/src/mintdb/mintdb_keyio.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014, 2015 Christian Grothoff (and other contributing authors) + Copyright (C) 2014, 2015 GNUnet e.V. TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software diff --git a/src/mintdb/mintdb_plugin.c b/src/mintdb/mintdb_plugin.c index 2e8d206fd..f1b2ad044 100644 --- a/src/mintdb/mintdb_plugin.c +++ b/src/mintdb/mintdb_plugin.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2015 Christian Grothoff (and other contributing authors) + Copyright (C) 2015 GNUnet e.V. TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software diff --git a/src/mintdb/perf_taler_mintdb.c b/src/mintdb/perf_taler_mintdb.c index 73708a6c7..fbaa2ce34 100644 --- a/src/mintdb/perf_taler_mintdb.c +++ b/src/mintdb/perf_taler_mintdb.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014, 2015 Christian Grothoff (and other contributing authors) + Copyright (C) 2014, 2015 GNUnet e.V. TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software diff --git a/src/mintdb/perf_taler_mintdb_init.c b/src/mintdb/perf_taler_mintdb_init.c index 141ac1ab8..97a1b4c99 100644 --- a/src/mintdb/perf_taler_mintdb_init.c +++ b/src/mintdb/perf_taler_mintdb_init.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014, 2015 Christian Grothoff (and other contributing authors) + Copyright (C) 2014, 2015 GNUnet e.V. TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software diff --git a/src/mintdb/perf_taler_mintdb_init.h b/src/mintdb/perf_taler_mintdb_init.h index 063259f51..f94beef10 100644 --- a/src/mintdb/perf_taler_mintdb_init.h +++ b/src/mintdb/perf_taler_mintdb_init.h @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014, 2015 Christian Grothoff (and other contributing authors) + Copyright (C) 2014, 2015 GNUnet e.V. TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software diff --git a/src/mintdb/perf_taler_mintdb_interpreter.c b/src/mintdb/perf_taler_mintdb_interpreter.c index 9084513fb..293d5f35f 100644 --- a/src/mintdb/perf_taler_mintdb_interpreter.c +++ b/src/mintdb/perf_taler_mintdb_interpreter.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014, 2015 Christian Grothoff (and other contributing authors) + Copyright (C) 2014, 2015 GNUnet e.V. TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software diff --git a/src/mintdb/perf_taler_mintdb_interpreter.h b/src/mintdb/perf_taler_mintdb_interpreter.h index 722d1a07d..3510e3dd4 100644 --- a/src/mintdb/perf_taler_mintdb_interpreter.h +++ b/src/mintdb/perf_taler_mintdb_interpreter.h @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014, 2015 Christian Grothoff (and other contributing authors) + Copyright (C) 2014, 2015 GNUnet e.V. TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software diff --git a/src/mintdb/perf_taler_mintdb_values.h b/src/mintdb/perf_taler_mintdb_values.h index 25202edd1..35f87f5b0 100644 --- a/src/mintdb/perf_taler_mintdb_values.h +++ b/src/mintdb/perf_taler_mintdb_values.h @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014, 2015 Christian Grothoff (and other contributing authors) + Copyright (C) 2014, 2015 GNUnet e.V. TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software diff --git a/src/mintdb/plugin_mintdb_common.c b/src/mintdb/plugin_mintdb_common.c index bbe104f6c..1f2fdc58b 100644 --- a/src/mintdb/plugin_mintdb_common.c +++ b/src/mintdb/plugin_mintdb_common.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2015 Christian Grothoff (and other contributing authors) + Copyright (C) 2015 GNUnet e.V. TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software diff --git a/src/mintdb/plugin_mintdb_postgres.c b/src/mintdb/plugin_mintdb_postgres.c index 2ebc8f0ff..057ea9fe8 100644 --- a/src/mintdb/plugin_mintdb_postgres.c +++ b/src/mintdb/plugin_mintdb_postgres.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014, 2015 Christian Grothoff (and other contributing authors) + Copyright (C) 2014, 2015 GNUnet e.V. TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software diff --git a/src/mintdb/test_mintdb.c b/src/mintdb/test_mintdb.c index 5b9d1c2ec..0cd660a4d 100644 --- a/src/mintdb/test_mintdb.c +++ b/src/mintdb/test_mintdb.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014, 2015 Christian Grothoff (and other contributing authors) + Copyright (C) 2014, 2015 GNUnet e.V. TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software diff --git a/src/mintdb/test_mintdb_deposits.c b/src/mintdb/test_mintdb_deposits.c index 171fa2c69..3ce0a35a5 100644 --- a/src/mintdb/test_mintdb_deposits.c +++ b/src/mintdb/test_mintdb_deposits.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014 Christian Grothoff (and other contributing authors) + Copyright (C) 2014 GNUnet e.V. TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software diff --git a/src/mintdb/test_perf_taler_mintdb.c b/src/mintdb/test_perf_taler_mintdb.c index 2830ef812..789a0dd4f 100644 --- a/src/mintdb/test_perf_taler_mintdb.c +++ b/src/mintdb/test_perf_taler_mintdb.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014, 2015 Christian Grothoff (and other contributing authors) + Copyright (C) 2014, 2015 GNUnet e.V. TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software diff --git a/src/pq/db_pq.c b/src/pq/db_pq.c index e1a082e44..59a1db022 100644 --- a/src/pq/db_pq.c +++ b/src/pq/db_pq.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014, 2015 Christian Grothoff (and other contributing authors) + Copyright (C) 2014, 2015 GNUnet e.V. TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software diff --git a/src/pq/pq_helper.c b/src/pq/pq_helper.c index bd54447e7..d245ffdb8 100644 --- a/src/pq/pq_helper.c +++ b/src/pq/pq_helper.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014, 2015 Christian Grothoff (and other contributing authors) + Copyright (C) 2014, 2015 GNUnet e.V. TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software diff --git a/src/pq/test_pq.c b/src/pq/test_pq.c index bda227587..f0413d1ff 100644 --- a/src/pq/test_pq.c +++ b/src/pq/test_pq.c @@ -1,6 +1,6 @@ /* This file is part of TALER - (C) 2015 Christian Grothoff (and other contributing authors) + (C) 2015 GNUnet e.V. TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software diff --git a/src/util/amount.c b/src/util/amount.c index 7260b150f..dc2d2e400 100644 --- a/src/util/amount.c +++ b/src/util/amount.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014 Christian Grothoff (and other contributing authors) + Copyright (C) 2014 GNUnet e.V. TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software diff --git a/src/util/crypto.c b/src/util/crypto.c index ebf6413db..9e6890569 100644 --- a/src/util/crypto.c +++ b/src/util/crypto.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014, 2015 Christian Grothoff (and other contributing authors) + Copyright (C) 2014, 2015 GNUnet e.V. TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software diff --git a/src/util/json.c b/src/util/json.c index cea0118e1..6aca7548c 100644 --- a/src/util/json.c +++ b/src/util/json.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014, 2015 Christian Grothoff (and other contributing authors) + Copyright (C) 2014, 2015 GNUnet e.V. TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software diff --git a/src/util/os_installation.c b/src/util/os_installation.c index ec1868a84..0eab118fe 100644 --- a/src/util/os_installation.c +++ b/src/util/os_installation.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - Copyright (C) 2006-2014 Christian Grothoff (and other contributing authors) + Copyright (C) 2006-2014 GNUnet e.V. GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published diff --git a/src/util/test_amount.c b/src/util/test_amount.c index 4741bcf36..3f33334bc 100644 --- a/src/util/test_amount.c +++ b/src/util/test_amount.c @@ -1,6 +1,6 @@ /* This file is part of TALER - (C) 2015 Christian Grothoff (and other contributing authors) + (C) 2015 GNUnet e.V. TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software diff --git a/src/util/test_crypto.c b/src/util/test_crypto.c index a5313195a..59acd7814 100644 --- a/src/util/test_crypto.c +++ b/src/util/test_crypto.c @@ -1,6 +1,6 @@ /* This file is part of TALER - (C) 2015 Christian Grothoff (and other contributing authors) + (C) 2015 GNUnet e.V. TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software diff --git a/src/util/test_json.c b/src/util/test_json.c index c48fe68bd..5e2f50fe8 100644 --- a/src/util/test_json.c +++ b/src/util/test_json.c @@ -1,6 +1,6 @@ /* This file is part of TALER - (C) 2015 Christian Grothoff (and other contributing authors) + (C) 2015 GNUnet e.V. TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software diff --git a/src/util/test_wireformats.c b/src/util/test_wireformats.c index 7e0e5bbc4..b41abb802 100644 --- a/src/util/test_wireformats.c +++ b/src/util/test_wireformats.c @@ -1,6 +1,6 @@ /* This file is part of TALER - (C) 2014 Christian Grothoff (and other contributing authors) + (C) 2014 GNUnet e.V. TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software diff --git a/src/util/util.c b/src/util/util.c index 08438cfab..addafacf7 100644 --- a/src/util/util.c +++ b/src/util/util.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014 Christian Grothoff (and other contributing authors) + Copyright (C) 2014 GNUnet e.V. TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software diff --git a/src/util/wireformats.c b/src/util/wireformats.c index dab7fb926..cd5a9c3d4 100644 --- a/src/util/wireformats.c +++ b/src/util/wireformats.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014, 2015 Christian Grothoff (and other contributing authors) + Copyright (C) 2014, 2015 GNUnet e.V. TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software -- cgit v1.2.3 From 43e04f2ad105ff4712697b3480bbb75330f69ad3 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Wed, 20 Jan 2016 18:50:19 +0100 Subject: work on #3888 --- src/include/taler_mintdb_plugin.h | 15 +++++---- src/include/taler_signatures.h | 16 +++++----- src/mint/taler-mint-httpd_db.c | 40 ++++++++++++++++++++++-- src/mint/taler-mint-httpd_responses.c | 59 ++++++++++++++++++++++++++++++----- src/mint/taler-mint-httpd_responses.h | 14 +++++++-- src/mintdb/plugin_mintdb_postgres.c | 8 ++--- 6 files changed, 120 insertions(+), 32 deletions(-) (limited to 'src/mint/taler-mint-httpd_db.c') diff --git a/src/include/taler_mintdb_plugin.h b/src/include/taler_mintdb_plugin.h index 90319b964..9e4f891c5 100644 --- a/src/include/taler_mintdb_plugin.h +++ b/src/include/taler_mintdb_plugin.h @@ -573,8 +573,11 @@ typedef void * wire transfer identifier information. * * @param cls closure - * @param wtid base32-encoded wire transfer identifier, NULL + * @param wtid wire transfer identifier, NULL * if the transaction was not yet done + * @param coin_contribution how much did the coin we asked about + * contribute to the total transfer value? (deposit value minus fee) + * @param total_amount how much was the total wire transfer? * @param execution_time when was the transaction done, or * when we expect it to be done (if @a wtid was NULL); * #GNUNET_TIME_UNIT_FOREVER_ABS if the /deposit is unknown @@ -582,7 +585,9 @@ typedef void */ typedef void (*TALER_MINTDB_DepositWtidCallback)(void *cls, - const char *wtid, + const struct TALER_WireTransferIdentifierRawP *wtid, + const struct TALER_Amount *coin_contribution, + const struct TALER_Amount *total_amount, struct GNUNET_TIME_Absolute execution_time); @@ -1224,16 +1229,14 @@ struct TALER_MINTDB_Plugin * into a wire transfer by the respective @a raw_wtid. * * @param cls the @e cls of this struct with the plugin-specific state - * @param raw_wtid the raw wire transfer identifier we used - * @param raw_len number of bytes in @a raw_wtid (right now always 32) + * @param wtid the raw wire transfer identifier we used * @param cb function to call on each transaction found * @param cb_cls closure for @a cb * @return #GNUNET_OK on success, #GNUNET_SYSERR on database errors */ int (*lookup_wire_transactions) (void *cls, - const void *raw_wtid, - size_t raw_len, + const struct TALER_WireTransferIdentifierRawP *wtid, TALER_MINTDB_TransactionDataCallback cb, void *cb_cls); diff --git a/src/include/taler_signatures.h b/src/include/taler_signatures.h index 62e602a01..29008fc9a 100644 --- a/src/include/taler_signatures.h +++ b/src/include/taler_signatures.h @@ -893,7 +893,7 @@ struct TALER_ConfirmWirePS /** * Raw value (binary encoding) of the wire transfer subject. */ - struct TALER_WireTransferIdentifierRawP raw; + struct TALER_WireTransferIdentifierRawP wtid; /** * The coin's public key. This is the value that must have been @@ -903,13 +903,13 @@ struct TALER_ConfirmWirePS /** * Merchant-generated transaction ID to detect duplicate - * transactions. The merchant must communicate a merchant-unique ID - * to the customer for each transaction. Note that different coins - * that are part of the same transaction can use the same - * transaction ID. The transaction ID is useful for later disputes, - * and the merchant's contract offer (@e h_contract) with the - * customer should include the offer's term and transaction ID - * signed with a key from the merchant. + * transactions, in big endian. The merchant must communicate a + * merchant-unique ID to the customer for each transaction. Note + * that different coins that are part of the same transaction can + * use the same transaction ID. The transaction ID is useful for + * later disputes, and the merchant's contract offer (@e h_contract) + * with the customer should include the offer's term and transaction + * ID signed with a key from the merchant. */ uint64_t transaction_id GNUNET_PACKED; diff --git a/src/mint/taler-mint-httpd_db.c b/src/mint/taler-mint-httpd_db.c index 14e03dfd2..d31dcd2ba 100644 --- a/src/mint/taler-mint-httpd_db.c +++ b/src/mint/taler-mint-httpd_db.c @@ -1702,7 +1702,6 @@ TMH_DB_execute_wire_deposits (struct MHD_Connection *connection, ctx.deposits = json_array (); ret = TMH_plugin->lookup_wire_transactions (TMH_plugin->cls, &wtid->raw, - sizeof (wtid->raw), &handle_transaction_data, &ctx); if (GNUNET_SYSERR == ret) @@ -1742,6 +1741,26 @@ struct DepositWtidContext */ struct MHD_Connection *connection; + /** + * Hash of the contract we are looking up. + */ + struct GNUNET_HashCode h_contract; + + /** + * Hash of the wire transfer details we are looking up. + */ + struct GNUNET_HashCode h_wire; + + /** + * Public key we are looking up. + */ + struct TALER_CoinSpendPublicKeyP coin_pub; + + /** + * Transaction ID we are looking up. + */ + uint64_t transaction_id; + /** * MHD result code to return. */ @@ -1754,8 +1773,11 @@ struct DepositWtidContext * wire transfer identifier information. * * @param cls our context for transmission - * @param wtid base32-encoded wire transfer identifier, NULL + * @param wtid raw wire transfer identifier, NULL * if the transaction was not yet done + * @param coin_contribution how much did the coin we asked about + * contribute to the total transfer value? (deposit value minus fee) + * @param total_amount how much was the total wire transfer? * @param execution_time when was the transaction done, or * when we expect it to be done (if @a wtid was NULL); * #GNUNET_TIME_UNIT_FOREVER_ABS if the /deposit is unknown @@ -1763,7 +1785,9 @@ struct DepositWtidContext */ static void handle_wtid_data (void *cls, - const char *wtid, + const struct TALER_WireTransferIdentifierRawP *wtid, + const struct TALER_Amount *coin_contribution, + const struct TALER_Amount *total_amount, struct GNUNET_TIME_Absolute execution_time) { struct DepositWtidContext *ctx = cls; @@ -1780,6 +1804,12 @@ handle_wtid_data (void *cls, else { ctx->res = TMH_RESPONSE_reply_deposit_wtid (ctx->connection, + &ctx->h_contract, + &ctx->h_wire, + &ctx->coin_pub, + coin_contribution, + total_amount, + ctx->transaction_id, wtid, execution_time); } @@ -1810,6 +1840,10 @@ TMH_DB_execute_deposit_wtid (struct MHD_Connection *connection, struct DepositWtidContext ctx; ctx.connection = connection; + ctx.h_contract = *h_contract; + ctx.h_wire = *h_wire; + ctx.coin_pub = *coin_pub; + ctx.transaction_id = transaction_id; ctx.res = MHD_NO; /* this value should never be read... */ ret = TMH_plugin->wire_lookup_deposit_wtid (TMH_plugin->cls, h_contract, diff --git a/src/mint/taler-mint-httpd_responses.c b/src/mint/taler-mint-httpd_responses.c index 9a55d5aab..d89b74c8f 100644 --- a/src/mint/taler-mint-httpd_responses.c +++ b/src/mint/taler-mint-httpd_responses.c @@ -1092,34 +1092,69 @@ TMH_RESPONSE_reply_deposit_pending (struct MHD_Connection *connection, * them. Generates the 200 reply. * * @param connection connection to the client - * @param wtid wire transfer identifier (as 0-terminated string) + * @param h_contract hash of the contract + * @param h_wire hash of wire account details + * @param coin_pub public key of the coin + * @param coin_contribution how much did the coin we asked about + * contribute to the total transfer value? (deposit value minus fee) + * @param total_amount how much was the total wire transfer? + * @param transaction_id merchant transaction identifier + * @param wtid raw wire transfer identifier * @param exec_time execution time of the wire transfer * @return MHD result code */ int TMH_RESPONSE_reply_deposit_wtid (struct MHD_Connection *connection, - const char *wtid, + const struct GNUNET_HashCode *h_contract, + const struct GNUNET_HashCode *h_wire, + const struct TALER_CoinSpendPublicKeyP *coin_pub, + const struct TALER_Amount *coin_contribution, + const struct TALER_Amount *total_amount, + uint64_t transaction_id, + const struct TALER_WireTransferIdentifierRawP *wtid, struct GNUNET_TIME_Absolute exec_time) { struct TALER_ConfirmWirePS cw; struct TALER_MintPublicKeyP pub; struct TALER_MintSignatureP sig; + struct TALER_WireTransferIdentifierP wtid_crc; + char *wtid_s; + int ret; + /* Create signature for the reply */ cw.purpose.purpose = htonl (TALER_SIGNATURE_MINT_CONFIRM_WIRE); cw.purpose.size = htonl (sizeof (struct TALER_ConfirmWirePS)); - // FIXME: fill in rest of 'cw'! + cw.h_wire = *h_wire; + cw.h_contract = *h_contract; + cw.wtid = *wtid; + cw.coin_pub = *coin_pub; + cw.transaction_id = GNUNET_htonll (transaction_id); + cw.execution_time = GNUNET_TIME_absolute_hton (exec_time); + TALER_amount_hton (&cw.coin_contribution, + coin_contribution); + TALER_amount_hton (&cw.total_amount, + total_amount); TMH_KS_sign (&cw.purpose, &pub, &sig); - return TMH_RESPONSE_reply_json_pack (connection, - MHD_HTTP_FOUND, + /* Compute checksum and crockford encoding if wire transfer subject */ + wtid_crc.raw = *wtid; + wtid_crc.crc8 = GNUNET_CRYPTO_crc8_n (wtid, + sizeof (struct TALER_WireTransferIdentifierRawP)); + + wtid_s = GNUNET_STRINGS_data_to_string_alloc (&wtid_crc, + sizeof (wtid_crc)); + ret = TMH_RESPONSE_reply_json_pack (connection, + MHD_HTTP_OK, "{s:s, s:o, s:o, s:o}", - "wtid", wtid, + "wtid", wtid_s, "execution_time", TALER_json_from_abs (exec_time), "mint_sig", TALER_json_from_data (&sig, sizeof (sig)), "mint_pub", TALER_json_from_data (&pub, sizeof (pub))); + GNUNET_free (wtid_s); + return ret; } @@ -1141,8 +1176,16 @@ TMH_RESPONSE_reply_wire_deposit_details (struct MHD_Connection *connection, const struct GNUNET_HashCode *h_wire, json_t *deposits) { - GNUNET_break (0); // FIXME: not implemented - return MHD_NO; + /* FIXME: #4135: signing not implemented here */ + return TMH_RESPONSE_reply_json_pack (connection, + MHD_HTTP_OK, + "{s:o, s:o, s:o, s:o}", + "total", TALER_json_from_amount (total), + "merchant_pub", TALER_json_from_data (merchant_pub, + sizeof (struct TALER_MerchantPublicKeyP)), + "h_wire", TALER_json_from_data (h_wire, + sizeof (struct GNUNET_HashCode)), + "deposits", deposits); } diff --git a/src/mint/taler-mint-httpd_responses.h b/src/mint/taler-mint-httpd_responses.h index 6debbc935..caad29047 100644 --- a/src/mint/taler-mint-httpd_responses.h +++ b/src/mint/taler-mint-httpd_responses.h @@ -277,13 +277,23 @@ TMH_RESPONSE_reply_deposit_pending (struct MHD_Connection *connection, * them. Generates the 200 reply. * * @param connection connection to the client - * @param wtid wire transfer identifier (as 0-terminated string) + * @param h_contract hash of the contract + * @param h_wire hash of wire account details + * @param coin_pub public key of the coin + * @param transaction_id merchant transaction identifier + * @param wtid raw wire transfer identifier * @param exec_time execution time of the wire transfer * @return MHD result code */ int TMH_RESPONSE_reply_deposit_wtid (struct MHD_Connection *connection, - const char *wtid, + const struct GNUNET_HashCode *h_contract, + const struct GNUNET_HashCode *h_wire, + const struct TALER_CoinSpendPublicKeyP *coin_pub, + const struct TALER_Amount *coin_contribution, + const struct TALER_Amount *total_amount, + uint64_t transaction_id, + const struct TALER_WireTransferIdentifierRawP *wtid, struct GNUNET_TIME_Absolute exec_time); diff --git a/src/mintdb/plugin_mintdb_postgres.c b/src/mintdb/plugin_mintdb_postgres.c index 057ea9fe8..ad0c91150 100644 --- a/src/mintdb/plugin_mintdb_postgres.c +++ b/src/mintdb/plugin_mintdb_postgres.c @@ -3366,19 +3366,17 @@ postgres_get_coin_transactions (void *cls, /** * Lookup the list of Taler transactions that was aggregated - * into a wire transfer by the respective @a raw_wtid. + * into a wire transfer by the respective @a wtid. * * @param cls closure - * @param raw_wtid the raw wire transfer identifier we used - * @param raw_len number of bytes in @a raw_wtid (right now always 32) + * @param wtid the raw wire transfer identifier we used * @param cb function to call on each transaction found * @param cb_cls closure for @a cb * @return #GNUNET_OK on success, #GNUNET_SYSERR on database errors */ static int postgres_lookup_wire_transactions (void *cls, - const void *raw_wtid, - size_t raw_len, + const struct TALER_WireTransferIdentifierRawP *wtid, TALER_MINTDB_TransactionDataCallback cb, void *cb_cls) { -- cgit v1.2.3 From 9ccba0e77f1c388bbfb7e6bea1b650797d57d023 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Thu, 21 Jan 2016 11:24:18 +0100 Subject: implementing insert function into aggregation table --- src/include/taler_mintdb_plugin.h | 16 ++++++++++---- src/mint-lib/mint_api_context.c | 2 +- src/mint/taler-mint-httpd_db.c | 16 ++++++++++++++ src/mintdb/plugin_mintdb_postgres.c | 43 +++++++++++++++++++++++++++++++++++-- 4 files changed, 70 insertions(+), 7 deletions(-) (limited to 'src/mint/taler-mint-httpd_db.c') diff --git a/src/include/taler_mintdb_plugin.h b/src/include/taler_mintdb_plugin.h index baf587886..2ffde2285 100644 --- a/src/include/taler_mintdb_plugin.h +++ b/src/include/taler_mintdb_plugin.h @@ -1229,6 +1229,7 @@ struct TALER_MINTDB_Plugin * into a wire transfer by the respective @a raw_wtid. * * @param cls the @e cls of this struct with the plugin-specific state + * @param session database connection * @param wtid the raw wire transfer identifier we used * @param cb function to call on each transaction found * @param cb_cls closure for @a cb @@ -1236,6 +1237,7 @@ struct TALER_MINTDB_Plugin */ int (*lookup_wire_transactions) (void *cls, + struct TALER_MINTDB_Session *session, const struct TALER_WireTransferIdentifierRawP *wtid, TALER_MINTDB_TransactionDataCallback cb, void *cb_cls); @@ -1247,6 +1249,7 @@ struct TALER_MINTDB_Plugin * to be executed. * * @param cls closure + * @param session database connection * @param h_contract hash of the contract * @param h_wire hash of merchant wire details * @param coin_pub public key of deposited coin @@ -1258,6 +1261,7 @@ struct TALER_MINTDB_Plugin */ int (*wire_lookup_deposit_wtid)(void *cls, + struct TALER_MINTDB_Session *session, const struct GNUNET_HashCode *h_contract, const struct GNUNET_HashCode *h_wire, const struct TALER_CoinSpendPublicKeyP *coin_pub, @@ -1271,26 +1275,30 @@ struct TALER_MINTDB_Plugin * Function called to insert aggregation information into the DB. * * @param cls closure + * @param session database connection * @param wtid the raw wire transfer identifier we used * @param merchant_pub public key of the merchant (should be same for all callbacks with the same @e cls) * @param h_wire hash of wire transfer details of the merchant (should be same for all callbacks with the same @e cls) * @param h_contract which contract was this payment about * @param transaction_id merchant's transaction ID for the payment + * @param execution_time when did we execute the transaction * @param coin_pub which public key was this payment about - * @param deposit_value amount contributed by this coin in total - * @param deposit_fee deposit fee charged by mint for this coin + * @param coin_value amount contributed by this coin to the total + * @param transaction_value total amount of the wire transaction * @return #GNUNET_OK on success, #GNUNET_SYSERR on DB errors */ int (*insert_aggregation_tracking)(void *cls, + struct TALER_MINTDB_Session *session, const struct TALER_WireTransferIdentifierRawP *wtid, const struct TALER_MerchantPublicKeyP *merchant_pub, const struct GNUNET_HashCode *h_wire, const struct GNUNET_HashCode *h_contract, uint64_t transaction_id, + struct GNUNET_TIME_Absolute execution_time, const struct TALER_CoinSpendPublicKeyP *coin_pub, - const struct TALER_Amount *deposit_value, - const struct TALER_Amount *deposit_fee); + const struct TALER_Amount *coin_value, + const struct TALER_Amount *transaction_value); }; diff --git a/src/mint-lib/mint_api_context.c b/src/mint-lib/mint_api_context.c index 3a86efb64..2767906b5 100644 --- a/src/mint-lib/mint_api_context.c +++ b/src/mint-lib/mint_api_context.c @@ -288,7 +288,7 @@ TALER_MINT_perform (struct TALER_MINT_Context *ctx) GNUNET_assert (CURLE_OK == curl_easy_getinfo (cmsg->easy_handle, CURLINFO_PRIVATE, - (char *) &job)); + (char **) &job)); GNUNET_assert (job->ctx == ctx); job->jcc (job->jcc_cls, cmsg->easy_handle); diff --git a/src/mint/taler-mint-httpd_db.c b/src/mint/taler-mint-httpd_db.c index d31dcd2ba..cc1642202 100644 --- a/src/mint/taler-mint-httpd_db.c +++ b/src/mint/taler-mint-httpd_db.c @@ -1697,10 +1697,18 @@ TMH_DB_execute_wire_deposits (struct MHD_Connection *connection, { int ret; struct WtidTransactionContext ctx; + struct TALER_MINTDB_Session *session; + if (NULL == (session = TMH_plugin->get_session (TMH_plugin->cls, + TMH_test_mode))) + { + GNUNET_break (0); + return TMH_RESPONSE_reply_internal_db_error (connection); + } ctx.is_valid = GNUNET_NO; ctx.deposits = json_array (); ret = TMH_plugin->lookup_wire_transactions (TMH_plugin->cls, + session, &wtid->raw, &handle_transaction_data, &ctx); @@ -1838,7 +1846,14 @@ TMH_DB_execute_deposit_wtid (struct MHD_Connection *connection, { int ret; struct DepositWtidContext ctx; + struct TALER_MINTDB_Session *session; + if (NULL == (session = TMH_plugin->get_session (TMH_plugin->cls, + TMH_test_mode))) + { + GNUNET_break (0); + return TMH_RESPONSE_reply_internal_db_error (connection); + } ctx.connection = connection; ctx.h_contract = *h_contract; ctx.h_wire = *h_wire; @@ -1846,6 +1861,7 @@ TMH_DB_execute_deposit_wtid (struct MHD_Connection *connection, ctx.transaction_id = transaction_id; ctx.res = MHD_NO; /* this value should never be read... */ ret = TMH_plugin->wire_lookup_deposit_wtid (TMH_plugin->cls, + session, h_contract, h_wire, coin_pub, diff --git a/src/mintdb/plugin_mintdb_postgres.c b/src/mintdb/plugin_mintdb_postgres.c index ca8edcffd..f3760216f 100644 --- a/src/mintdb/plugin_mintdb_postgres.c +++ b/src/mintdb/plugin_mintdb_postgres.c @@ -3451,6 +3451,7 @@ postgres_get_coin_transactions (void *cls, * into a wire transfer by the respective @a wtid. * * @param cls closure + * @param session database connection * @param wtid the raw wire transfer identifier we used * @param cb function to call on each transaction found * @param cb_cls closure for @a cb @@ -3458,6 +3459,7 @@ postgres_get_coin_transactions (void *cls, */ static int postgres_lookup_wire_transactions (void *cls, + struct TALER_MINTDB_Session *session, const struct TALER_WireTransferIdentifierRawP *wtid, TALER_MINTDB_TransactionDataCallback cb, void *cb_cls) @@ -3473,6 +3475,7 @@ postgres_lookup_wire_transactions (void *cls, * to be executed. * * @param cls closure + * @param session database connection * @param h_contract hash of the contract * @param h_wire hash of merchant wire details * @param coin_pub public key of deposited coin @@ -3484,6 +3487,7 @@ postgres_lookup_wire_transactions (void *cls, */ static int postgres_wire_lookup_deposit_wtid (void *cls, + struct TALER_MINTDB_Session *session, const struct GNUNET_HashCode *h_contract, const struct GNUNET_HashCode *h_wire, const struct TALER_CoinSpendPublicKeyP *coin_pub, @@ -3501,6 +3505,7 @@ postgres_wire_lookup_deposit_wtid (void *cls, * Function called to insert aggregation information into the DB. * * @param cls closure + * @param session database connection * @param wtid the raw wire transfer identifier we used * @param merchant_pub public key of the merchant (should be same for all callbacks with the same @e cls) * @param h_wire hash of wire transfer details of the merchant (should be same for all callbacks with the same @e cls) @@ -3513,15 +3518,49 @@ postgres_wire_lookup_deposit_wtid (void *cls, */ static int postgres_insert_aggregation_tracking (void *cls, + struct TALER_MINTDB_Session *session, const struct TALER_WireTransferIdentifierRawP *wtid, const struct TALER_MerchantPublicKeyP *merchant_pub, const struct GNUNET_HashCode *h_wire, const struct GNUNET_HashCode *h_contract, uint64_t transaction_id, + struct GNUNET_TIME_Absolute execution_time, const struct TALER_CoinSpendPublicKeyP *coin_pub, - const struct TALER_Amount *deposit_value, - const struct TALER_Amount *deposit_fee) + const struct TALER_Amount *coin_value, + const struct TALER_Amount *transaction_value) { + struct TALER_PQ_QueryParam params[] = { + TALER_PQ_query_param_auto_from_type (h_contract), + TALER_PQ_query_param_auto_from_type (h_wire), + TALER_PQ_query_param_auto_from_type (coin_pub), + TALER_PQ_query_param_auto_from_type (merchant_pub), + TALER_PQ_query_param_uint64 (&transaction_id), + TALER_PQ_query_param_auto_from_type (wtid), + TALER_PQ_query_param_absolute_time (&execution_time), + TALER_PQ_query_param_amount (coin_value), + TALER_PQ_query_param_amount (transaction_value), + TALER_PQ_query_param_end + }; + PGresult *result; + + result = TALER_PQ_exec_prepared (session->conn, + "insert_aggregation_tracking", + params); + if (PGRES_COMMAND_OK != PQresultStatus (result)) + { + BREAK_DB_ERR (result); + PQclear (result); + return GNUNET_SYSERR; + } + if (0 != strcmp ("1", PQcmdTuples (result))) + { + GNUNET_break (0); + PQclear (result); + return GNUNET_SYSERR; + } + PQclear (result); + return GNUNET_OK; + GNUNET_break (0); // not implemented return GNUNET_SYSERR; } -- cgit v1.2.3 From c12a899f32e1ce432181fa428ebe77bd72ce4394 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Thu, 21 Jan 2016 12:09:17 +0100 Subject: finish implementation of DB tracing functions --- src/include/taler_mintdb_plugin.h | 57 ++++---- src/mint/taler-mint-httpd_db.c | 78 ++++++---- src/mintdb/plugin_mintdb_postgres.c | 277 ++++++++++++++++++++++++++++++++---- 3 files changed, 332 insertions(+), 80 deletions(-) (limited to 'src/mint/taler-mint-httpd_db.c') diff --git a/src/include/taler_mintdb_plugin.h b/src/include/taler_mintdb_plugin.h index 2ffde2285..e5cf6d6f1 100644 --- a/src/include/taler_mintdb_plugin.h +++ b/src/include/taler_mintdb_plugin.h @@ -570,23 +570,24 @@ typedef void /** * Function called with the results of the lookup of the - * wire transfer identifier information. + * wire transfer identifier information. Only called if + * we are at least aware of the transaction existing. * * @param cls closure * @param wtid wire transfer identifier, NULL * if the transaction was not yet done * @param coin_contribution how much did the coin we asked about - * contribute to the total transfer value? (deposit value minus fee) + * contribute to the total transfer value? (deposit value including fee) + * @param coin_fee how much did the mint charge for the deposit fee * @param total_amount how much was the total wire transfer? * @param execution_time when was the transaction done, or - * when we expect it to be done (if @a wtid was NULL); - * #GNUNET_TIME_UNIT_FOREVER_ABS if the /deposit is unknown - * to the mint + * when we expect it to be done (if @a wtid was NULL) */ typedef void (*TALER_MINTDB_DepositWtidCallback)(void *cls, const struct TALER_WireTransferIdentifierRawP *wtid, const struct TALER_Amount *coin_contribution, + const struct TALER_Amount *coin_fee, const struct TALER_Amount *total_amount, struct GNUNET_TIME_Absolute execution_time); @@ -601,18 +602,20 @@ typedef void * @param h_contract which contract was this payment about * @param transaction_id merchant's transaction ID for the payment * @param coin_pub which public key was this payment about - * @param deposit_value amount contributed by this coin in total - * @param deposit_fee deposit fee charged by mint for this coin + * @param coin_value amount contributed by this coin in total (with fee) + * @param coin_fee applicable fee for this coin + * @param transfer_value total amount of the wire transfer */ typedef void -(*TALER_MINTDB_TransactionDataCallback)(void *cls, - const struct TALER_MerchantPublicKeyP *merchant_pub, - const struct GNUNET_HashCode *h_wire, - const struct GNUNET_HashCode *h_contract, - uint64_t transaction_id, - const struct TALER_CoinSpendPublicKeyP *coin_pub, - const struct TALER_Amount *deposit_value, - const struct TALER_Amount *deposit_fee); +(*TALER_MINTDB_WireTransferDataCallback)(void *cls, + const struct TALER_MerchantPublicKeyP *merchant_pub, + const struct GNUNET_HashCode *h_wire, + const struct GNUNET_HashCode *h_contract, + uint64_t transaction_id, + const struct TALER_CoinSpendPublicKeyP *coin_pub, + const struct TALER_Amount *coin_value, + const struct TALER_Amount *coin_fee, + const struct TALER_Amount *transfer_value); /** @@ -1233,14 +1236,15 @@ struct TALER_MINTDB_Plugin * @param wtid the raw wire transfer identifier we used * @param cb function to call on each transaction found * @param cb_cls closure for @a cb - * @return #GNUNET_OK on success, #GNUNET_SYSERR on database errors + * @return #GNUNET_OK on success, #GNUNET_SYSERR on database errors, + * #GNUNET_NO if we found no results */ int - (*lookup_wire_transactions) (void *cls, - struct TALER_MINTDB_Session *session, - const struct TALER_WireTransferIdentifierRawP *wtid, - TALER_MINTDB_TransactionDataCallback cb, - void *cb_cls); + (*lookup_wire_transfer) (void *cls, + struct TALER_MINTDB_Session *session, + const struct TALER_WireTransferIdentifierRawP *wtid, + TALER_MINTDB_WireTransferDataCallback cb, + void *cb_cls); /** @@ -1257,7 +1261,8 @@ struct TALER_MINTDB_Plugin * @param transaction_id transaction identifier * @param cb function to call with the result * @param cb_cls closure to pass to @a cb - * @return #GNUNET_OK on success, #GNUNET_SYSERR on DB errors + * @return #GNUNET_OK on success, #GNUNET_SYSERR on DB errors, + * #GNUNET_NO if nothing was found */ int (*wire_lookup_deposit_wtid)(void *cls, @@ -1283,8 +1288,9 @@ struct TALER_MINTDB_Plugin * @param transaction_id merchant's transaction ID for the payment * @param execution_time when did we execute the transaction * @param coin_pub which public key was this payment about - * @param coin_value amount contributed by this coin to the total - * @param transaction_value total amount of the wire transaction + * @param coin_value amount contributed by this coin in total + * @param coin_fee deposit fee charged by mint for this coin + * @param transfer_value total amount of the wire transfer * @return #GNUNET_OK on success, #GNUNET_SYSERR on DB errors */ int @@ -1298,7 +1304,8 @@ struct TALER_MINTDB_Plugin struct GNUNET_TIME_Absolute execution_time, const struct TALER_CoinSpendPublicKeyP *coin_pub, const struct TALER_Amount *coin_value, - const struct TALER_Amount *transaction_value); + const struct TALER_Amount *coin_fee, + const struct TALER_Amount *transfer_value); }; diff --git a/src/mint/taler-mint-httpd_db.c b/src/mint/taler-mint-httpd_db.c index cc1642202..fb4ee1b7a 100644 --- a/src/mint/taler-mint-httpd_db.c +++ b/src/mint/taler-mint-httpd_db.c @@ -1565,6 +1565,12 @@ struct WtidTransactionContext */ struct TALER_Amount total; + /** + * Value we find in the DB for the @e total; only valid if @e is_valid + * is #GNUNET_YES. + */ + struct TALER_Amount db_transaction_value; + /** * Public key of the merchant, only valid if @e is_valid * is #GNUNET_YES. @@ -1606,6 +1612,7 @@ struct WtidTransactionContext * @param coin_pub which public key was this payment about * @param deposit_value amount contributed by this coin in total * @param deposit_fee deposit fee charged by mint for this coin + * @param transaction_value total value of the wire transaction */ static void handle_transaction_data (void *cls, @@ -1615,7 +1622,8 @@ handle_transaction_data (void *cls, uint64_t transaction_id, const struct TALER_CoinSpendPublicKeyP *coin_pub, const struct TALER_Amount *deposit_value, - const struct TALER_Amount *deposit_fee) + const struct TALER_Amount *deposit_fee, + const struct TALER_Amount *transaction_value) { struct WtidTransactionContext *ctx = cls; struct TALER_Amount delta; @@ -1626,6 +1634,7 @@ handle_transaction_data (void *cls, { ctx->merchant_pub = *merchant_pub; ctx->h_wire = *h_wire; + ctx->db_transaction_value = *transaction_value; ctx->is_valid = GNUNET_YES; if (GNUNET_OK != TALER_amount_subtract (&ctx->total, @@ -1644,7 +1653,9 @@ handle_transaction_data (void *cls, sizeof (struct TALER_MerchantPublicKeyP))) || (0 != memcmp (&ctx->h_wire, h_wire, - sizeof (struct GNUNET_HashCode))) ) + sizeof (struct GNUNET_HashCode))) || + (0 != TALER_amount_cmp (transaction_value, + &ctx->db_transaction_value)) ) { GNUNET_break (0); ctx->is_valid = GNUNET_SYSERR; @@ -1707,11 +1718,11 @@ TMH_DB_execute_wire_deposits (struct MHD_Connection *connection, } ctx.is_valid = GNUNET_NO; ctx.deposits = json_array (); - ret = TMH_plugin->lookup_wire_transactions (TMH_plugin->cls, - session, - &wtid->raw, - &handle_transaction_data, - &ctx); + ret = TMH_plugin->lookup_wire_transfer (TMH_plugin->cls, + session, + &wtid->raw, + &handle_transaction_data, + &ctx); if (GNUNET_SYSERR == ret) { GNUNET_break (0); @@ -1730,8 +1741,15 @@ TMH_DB_execute_wire_deposits (struct MHD_Connection *connection, return TMH_RESPONSE_reply_arg_unknown (connection, "wtid"); } + if (0 != TALER_amount_cmp (&ctx.total, + &ctx.db_transaction_value)) + { + /* FIXME: this CAN actually differ, due to rounding + down. But we should still check that the values + do match after rounding 'total' down! */ + } return TMH_RESPONSE_reply_wire_deposit_details (connection, - &ctx.total, + &ctx.db_transaction_value, &ctx.merchant_pub, &ctx.h_wire, ctx.deposits); @@ -1784,7 +1802,8 @@ struct DepositWtidContext * @param wtid raw wire transfer identifier, NULL * if the transaction was not yet done * @param coin_contribution how much did the coin we asked about - * contribute to the total transfer value? (deposit value minus fee) + * contribute to the total transfer value? (deposit value including fee) + * @param coin_fee how much did the mint charge for the deposit fee * @param total_amount how much was the total wire transfer? * @param execution_time when was the transaction done, or * when we expect it to be done (if @a wtid was NULL); @@ -1795,31 +1814,40 @@ static void handle_wtid_data (void *cls, const struct TALER_WireTransferIdentifierRawP *wtid, const struct TALER_Amount *coin_contribution, + const struct TALER_Amount *coin_fee, const struct TALER_Amount *total_amount, struct GNUNET_TIME_Absolute execution_time) { struct DepositWtidContext *ctx = cls; + struct TALER_Amount coin_delta; if (NULL == wtid) { - if (GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us == - execution_time.abs_value_us) - ctx->res = TMH_RESPONSE_reply_deposit_unknown (ctx->connection); - else - ctx->res = TMH_RESPONSE_reply_deposit_pending (ctx->connection, - execution_time); + ctx->res = TMH_RESPONSE_reply_deposit_pending (ctx->connection, + execution_time); } else { - ctx->res = TMH_RESPONSE_reply_deposit_wtid (ctx->connection, - &ctx->h_contract, - &ctx->h_wire, - &ctx->coin_pub, - coin_contribution, - total_amount, - ctx->transaction_id, - wtid, - execution_time); + if (GNUNET_SYSERR == + TALER_amount_subtract (&coin_delta, + coin_contribution, + coin_fee)) + { + GNUNET_break (0); + ctx->res = TMH_RESPONSE_reply_internal_db_error (ctx->connection); + } + else + { + ctx->res = TMH_RESPONSE_reply_deposit_wtid (ctx->connection, + &ctx->h_contract, + &ctx->h_wire, + &ctx->coin_pub, + &coin_delta, + total_amount, + ctx->transaction_id, + wtid, + execution_time); + } } } @@ -1874,6 +1902,8 @@ TMH_DB_execute_deposit_wtid (struct MHD_Connection *connection, GNUNET_break (0); return TMH_RESPONSE_reply_internal_db_error (connection); } + if (GNUNET_NO == ret) + return TMH_RESPONSE_reply_deposit_unknown (connection); return ctx.res; } diff --git a/src/mintdb/plugin_mintdb_postgres.c b/src/mintdb/plugin_mintdb_postgres.c index f3760216f..38ce45eb9 100644 --- a/src/mintdb/plugin_mintdb_postgres.c +++ b/src/mintdb/plugin_mintdb_postgres.c @@ -875,6 +875,26 @@ postgres_prepare (PGconn *db_conn) " (merchant_pub=$3)" " )", 3, NULL); + /* Fetch an existing deposit request. + Used in #postgres_wire_lookup_deposit_wtid(). */ + PREPARE ("get_deposit_for_wtid", + "SELECT" + " amount_with_fee_val" + ",amount_with_fee_frac" + ",amount_with_fee_curr" + ",deposit_fee_val" + ",deposit_fee_frac" + ",deposit_fee_curr" + ",wire_deadline" + " FROM deposits" + " WHERE (" + " (coin_pub=$1) AND" + " (transaction_id=$2) AND" + " (merchant_pub=$3) AND" + " (h_contract=$4) AND" + " (h_wire=$5)" + " )", + 5, NULL); /* Used in #postgres_iterate_deposits() */ PREPARE ("deposits_iterate", @@ -972,7 +992,7 @@ postgres_prepare (PGconn *db_conn) " AND rm.oldcoin_index = rcl.oldcoin_index" " AND rcl.cnc_index=rs.noreveal_index", 1, NULL); - /* Used in #postgres_lookup_wire_transactions */ + /* Used in #postgres_lookup_wire_transfer */ PREPARE ("lookup_transactions", "SELECT" " h_contract" @@ -984,9 +1004,12 @@ postgres_prepare (PGconn *db_conn) ",coin_amount_val" ",coin_amount_frac" ",coin_amount_curr" - ",transaction_total_val" - ",transaction_total_frac" - ",transaction_total_curr" + ",coin_fee_val" + ",coin_fee_frac" + ",coin_fee_curr" + ",transfer_total_val" + ",transfer_total_frac" + ",transfer_total_curr" " FROM aggregation_tracking" " WHERE wtid_raw=$1", 1, NULL); @@ -998,9 +1021,12 @@ postgres_prepare (PGconn *db_conn) ",coin_amount_val" ",coin_amount_frac" ",coin_amount_curr" - ",transaction_total_val" - ",transaction_total_frac" - ",transaction_total_curr" + ",coin_fee_val" + ",coin_fee_frac" + ",coin_fee_curr" + ",transfer_total_val" + ",transfer_total_frac" + ",transfer_total_curr" " FROM aggregation_tracking" " WHERE" " coin_pub=$1 AND" @@ -1022,12 +1048,15 @@ postgres_prepare (PGconn *db_conn) ",coin_amount_val" ",coin_amount_frac" ",coin_amount_curr" - ",transaction_total_val" - ",transaction_total_frac" - ",transaction_total_curr" + ",coin_fee_val" + ",coin_fee_frac" + ",coin_fee_curr" + ",transfer_total_val" + ",transfer_total_frac" + ",transfer_total_curr" ") VALUES " - "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)", - 13, NULL); + "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16)", + 16, NULL); return GNUNET_OK; #undef PREPARE @@ -3455,17 +3484,83 @@ postgres_get_coin_transactions (void *cls, * @param wtid the raw wire transfer identifier we used * @param cb function to call on each transaction found * @param cb_cls closure for @a cb - * @return #GNUNET_OK on success, #GNUNET_SYSERR on database errors + * @return #GNUNET_OK on success, #GNUNET_SYSERR on database errors, + * #GNUNET_NO if we found no results */ static int -postgres_lookup_wire_transactions (void *cls, - struct TALER_MINTDB_Session *session, - const struct TALER_WireTransferIdentifierRawP *wtid, - TALER_MINTDB_TransactionDataCallback cb, - void *cb_cls) +postgres_lookup_wire_transfer (void *cls, + struct TALER_MINTDB_Session *session, + const struct TALER_WireTransferIdentifierRawP *wtid, + TALER_MINTDB_WireTransferDataCallback cb, + void *cb_cls) { - GNUNET_break (0); // not implemented! - return GNUNET_SYSERR; + PGresult *result; + struct TALER_PQ_QueryParam params[] = { + TALER_PQ_query_param_auto_from_type (wtid), + TALER_PQ_query_param_end + }; + int nrows; + int i; + + /* check if the melt record exists and get it */ + result = TALER_PQ_exec_prepared (session->conn, + "lookup_transactions", + params); + if (PGRES_TUPLES_OK != PQresultStatus (result)) + { + BREAK_DB_ERR (result); + PQclear (result); + return GNUNET_SYSERR; + } + nrows = PQntuples (result); + if (0 == nrows) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "lookup_wire_transfer() returned 0 matching rows\n"); + PQclear (result); + return GNUNET_NO; + } + for (i=0;iconn, + "lookup_deposit_wtid", + params); + if (PGRES_TUPLES_OK != PQresultStatus (result)) + { + BREAK_DB_ERR (result); + PQclear (result); + return GNUNET_SYSERR; + } + nrows = PQntuples (result); + if (0 == nrows) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "lookup_wire_transfer() returned 0 matching rows\n"); + PQclear (result); + + /* Check if transaction exists in deposits, so that we just + do not have a WTID yet, if so, do call the CB with a NULL wtid + and return GNUNET_YES! */ + { + struct TALER_PQ_QueryParam params2[] = { + TALER_PQ_query_param_auto_from_type (coin_pub), + TALER_PQ_query_param_uint64 (&transaction_id), + TALER_PQ_query_param_auto_from_type (merchant_pub), + TALER_PQ_query_param_auto_from_type (h_contract), + TALER_PQ_query_param_auto_from_type (h_wire), + TALER_PQ_query_param_end + }; + + result = TALER_PQ_exec_prepared (session->conn, + "get_deposit_for_wtid", + params2); + if (PGRES_TUPLES_OK != PQresultStatus (result)) + { + BREAK_DB_ERR (result); + PQclear (result); + return GNUNET_SYSERR; + } + } + nrows = PQntuples (result); + if (0 == nrows) + { + PQclear (result); + return GNUNET_NO; + } + + /* Ok, we're aware of the transaction, but it has not yet been + executed */ + { + struct GNUNET_TIME_Absolute exec_time; + struct TALER_Amount coin_amount; + struct TALER_Amount coin_fee; + struct TALER_PQ_ResultSpec rs[] = { + TALER_PQ_result_spec_amount ("coin_amount", &coin_amount), + TALER_PQ_result_spec_amount ("deposit_fee", &coin_fee), + TALER_PQ_result_spec_absolute_time ("wire_deadline", &exec_time), + TALER_PQ_result_spec_end + }; + if (GNUNET_OK != TALER_PQ_extract_result (result, rs, 0)) + { + GNUNET_break (0); + PQclear (result); + return GNUNET_SYSERR; + } + cb (cb_cls, + NULL, + &coin_amount, + &coin_fee, + NULL, + exec_time); + PQclear (result); + return GNUNET_YES; + } + } + if (1 != nrows) + { + GNUNET_break (0); + PQclear (result); + return GNUNET_SYSERR; + } + { + struct TALER_WireTransferIdentifierRawP wtid; + struct GNUNET_TIME_Absolute exec_time; + struct TALER_Amount coin_amount; + struct TALER_Amount coin_fee; + struct TALER_Amount transaction_amount; + struct TALER_PQ_ResultSpec rs[] = { + TALER_PQ_result_spec_auto_from_type ("wtid_raw", &wtid), + TALER_PQ_result_spec_absolute_time ("execution_time", &exec_time), + TALER_PQ_result_spec_amount ("coin_amount", &coin_amount), + TALER_PQ_result_spec_amount ("coin_fee", &coin_fee), + TALER_PQ_result_spec_amount ("transfer_total", &transaction_amount), + TALER_PQ_result_spec_end + }; + if (GNUNET_OK != TALER_PQ_extract_result (result, rs, 0)) + { + GNUNET_break (0); + PQclear (result); + return GNUNET_SYSERR; + } + cb (cb_cls, + &wtid, + &coin_amount, + &coin_fee, + &transaction_amount, + exec_time); + } + PQclear (result); + return GNUNET_OK; } @@ -3512,8 +3727,9 @@ postgres_wire_lookup_deposit_wtid (void *cls, * @param h_contract which contract was this payment about * @param transaction_id merchant's transaction ID for the payment * @param coin_pub which public key was this payment about - * @param deposit_value amount contributed by this coin in total - * @param deposit_fee deposit fee charged by mint for this coin + * @param coin_value amount contributed by this coin in total + * @param coin_fee deposit fee charged by mint for this coin + * @param transfer_value total amount of the wire transfer * @return #GNUNET_OK on success, #GNUNET_SYSERR on DB errors */ static int @@ -3527,7 +3743,8 @@ postgres_insert_aggregation_tracking (void *cls, struct GNUNET_TIME_Absolute execution_time, const struct TALER_CoinSpendPublicKeyP *coin_pub, const struct TALER_Amount *coin_value, - const struct TALER_Amount *transaction_value) + const struct TALER_Amount *coin_fee, + const struct TALER_Amount *transfer_value) { struct TALER_PQ_QueryParam params[] = { TALER_PQ_query_param_auto_from_type (h_contract), @@ -3538,7 +3755,8 @@ postgres_insert_aggregation_tracking (void *cls, TALER_PQ_query_param_auto_from_type (wtid), TALER_PQ_query_param_absolute_time (&execution_time), TALER_PQ_query_param_amount (coin_value), - TALER_PQ_query_param_amount (transaction_value), + TALER_PQ_query_param_amount (coin_fee), + TALER_PQ_query_param_amount (transfer_value), TALER_PQ_query_param_end }; PGresult *result; @@ -3560,9 +3778,6 @@ postgres_insert_aggregation_tracking (void *cls, } PQclear (result); return GNUNET_OK; - - GNUNET_break (0); // not implemented - return GNUNET_SYSERR; } @@ -3635,7 +3850,7 @@ libtaler_plugin_mintdb_postgres_init (void *cls) plugin->get_transfer = &postgres_get_transfer; plugin->get_coin_transactions = &postgres_get_coin_transactions; plugin->free_coin_transaction_list = &common_free_coin_transaction_list; - plugin->lookup_wire_transactions = &postgres_lookup_wire_transactions; + plugin->lookup_wire_transfer = &postgres_lookup_wire_transfer; plugin->wire_lookup_deposit_wtid = &postgres_wire_lookup_deposit_wtid; plugin->insert_aggregation_tracking = &postgres_insert_aggregation_tracking; return plugin; -- cgit v1.2.3 From d63447baf65bd1578f51595cc8e673f3312f8044 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Thu, 21 Jan 2016 15:18:55 +0100 Subject: adding mint-lib logic to execute /wire/deposits requests --- src/include/taler_mint_service.h | 2 +- src/mint-lib/Makefile.am | 3 +- src/mint-lib/mint_api_json.c | 34 ++++ src/mint-lib/mint_api_json.h | 21 +++ src/mint-lib/mint_api_wire_deposits.c | 296 ++++++++++++++++++++++++++++++++++ src/mint/taler-mint-httpd_db.c | 4 +- src/mint/taler-mint-httpd_db.h | 2 +- src/mint/taler-mint-httpd_tracking.c | 9 +- 8 files changed, 359 insertions(+), 12 deletions(-) create mode 100644 src/mint-lib/mint_api_wire_deposits.c (limited to 'src/mint/taler-mint-httpd_db.c') diff --git a/src/include/taler_mint_service.h b/src/include/taler_mint_service.h index 070f77f03..b151cb009 100644 --- a/src/include/taler_mint_service.h +++ b/src/include/taler_mint_service.h @@ -1086,7 +1086,7 @@ struct TALER_WireDepositDetails /** * Value of the deposit (including fee). */ - struct TALER_Amount coin_contribution; + struct TALER_Amount coin_value; /** * Fee charged by the mint for the deposit. diff --git a/src/mint-lib/Makefile.am b/src/mint-lib/Makefile.am index 3ee1f5a10..171a42464 100644 --- a/src/mint-lib/Makefile.am +++ b/src/mint-lib/Makefile.am @@ -24,7 +24,8 @@ libtalermint_la_SOURCES = \ mint_api_refresh.c \ mint_api_refresh_link.c \ mint_api_reserve.c \ - mint_api_wire.c + mint_api_wire.c \ + mint_api_wire_deposits.c libtalermint_la_LIBADD = \ -lgnunetutil \ diff --git a/src/mint-lib/mint_api_json.c b/src/mint-lib/mint_api_json.c index a728a5495..7de33e5eb 100644 --- a/src/mint-lib/mint_api_json.c +++ b/src/mint-lib/mint_api_json.c @@ -232,6 +232,20 @@ parse_json (json_t *root, } break; + case MAJ_CMD_UINT64: + { + json_int_t val; + + if (! json_is_integer (pos)) + { + GNUNET_break_op (0); + return i; + } + val = json_integer_value (pos); + *spec[i].details.u64 = (uint64_t) val; + } + break; + case MAJ_CMD_JSON_OBJECT: { if (! (json_is_object (pos) || json_is_array (pos)) ) @@ -428,6 +442,26 @@ MAJ_spec_uint16 (const char *name, } +/** + * 64-bit integer. + * + * @param name name of the JSON field + * @param[out] u64 where to store the integer found under @a name + */ +struct MAJ_Specification +MAJ_spec_uint64 (const char *name, + uint64_t *u64) +{ + struct MAJ_Specification ret = + { + .cmd = MAJ_CMD_UINT64, + .field = name, + .details.u64 = u64 + }; + return ret; +} + + /** * JSON object. * diff --git a/src/mint-lib/mint_api_json.h b/src/mint-lib/mint_api_json.h index 68809059e..6bc3a5572 100644 --- a/src/mint-lib/mint_api_json.h +++ b/src/mint-lib/mint_api_json.h @@ -78,6 +78,11 @@ enum MAJ_Command */ MAJ_CMD_UINT16, + /** + * Parse `uint64_t` integer at the current position. + */ + MAJ_CMD_UINT64, + /** * Parse JSON object at the current position. */ @@ -191,6 +196,11 @@ struct MAJ_Specification */ uint16_t *u16; + /** + * Where to store 64-bit integer. + */ + uint64_t *u64; + /** * Where to store a JSON object. */ @@ -282,6 +292,17 @@ MAJ_spec_uint16 (const char *name, uint16_t *u16); +/** + * 64-bit integer. + * + * @param name name of the JSON field + * @param[out] u64 where to store the integer found under @a name + */ +struct MAJ_Specification +MAJ_spec_uint64 (const char *name, + uint64_t *u64); + + /** * JSON object. * diff --git a/src/mint-lib/mint_api_wire_deposits.c b/src/mint-lib/mint_api_wire_deposits.c new file mode 100644 index 000000000..6fd4d75d7 --- /dev/null +++ b/src/mint-lib/mint_api_wire_deposits.c @@ -0,0 +1,296 @@ +/* + This file is part of TALER + Copyright (C) 2014, 2015, 2016 GNUnet e.V. + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, If not, see + +*/ +/** + * @file mint-lib/mint_api_wire_deposits.c + * @brief Implementation of the /wire/deposits request of the mint's HTTP API + * @author Christian Grothoff + */ +#include "platform.h" +#include +#include +#include /* just for HTTP status codes */ +#include +#include "taler_mint_service.h" +#include "mint_api_common.h" +#include "mint_api_json.h" +#include "mint_api_context.h" +#include "mint_api_handle.h" +#include "taler_signatures.h" + + +/** + * @brief A /wire/deposits Handle + */ +struct TALER_MINT_WireDepositsHandle +{ + + /** + * The connection to mint this request handle will use + */ + struct TALER_MINT_Handle *mint; + + /** + * The url for this request. + */ + char *url; + + /** + * JSON encoding of the request to POST. + */ + char *json_enc; + + /** + * Handle for the request. + */ + struct MAC_Job *job; + + /** + * Function to call with the result. + */ + TALER_MINT_WireDepositsCallback cb; + + /** + * Closure for @a cb. + */ + void *cb_cls; + + /** + * Download buffer + */ + struct MAC_DownloadBuffer db; + +}; + + +/** + * Function called when we're done processing the + * HTTP /wire/deposits request. + * + * @param cls the `struct TALER_MINT_WireDepositsHandle` + * @param eh the curl request handle + */ +static void +handle_wire_deposits_finished (void *cls, + CURL *eh) +{ + struct TALER_MINT_WireDepositsHandle *wdh = cls; + long response_code; + json_t *json; + + wdh->job = NULL; + json = MAC_download_get_result (&wdh->db, + eh, + &response_code); + switch (response_code) + { + case 0: + break; + case MHD_HTTP_OK: + { + json_t *details_j; + struct GNUNET_HashCode h_wire; + struct TALER_Amount total_amount; + struct TALER_MerchantPublicKeyP merchant_pub; + unsigned int num_details; + struct MAJ_Specification spec[] = { + MAJ_spec_fixed_auto ("H_wire", &h_wire), + MAJ_spec_fixed_auto ("merchant_pub", &merchant_pub), + MAJ_spec_amount ("total_amount", &total_amount), + MAJ_spec_json ("details", &details_j), + MAJ_spec_end + }; + + if (GNUNET_OK != + MAJ_parse_json (json, + spec)) + { + GNUNET_break_op (0); + response_code = 0; + break; + } + num_details = json_array_size (details_j); + { + struct TALER_WireDepositDetails details[num_details]; + unsigned int i; + + for (i=0;ih_contract), + MAJ_spec_amount ("deposit_value", &detail->coin_value), + MAJ_spec_amount ("deposit_fee", &detail->coin_fee), + MAJ_spec_uint64 ("transaction_id", &detail->transaction_id), + MAJ_spec_fixed_auto ("coin_pub", &detail->coin_pub), + MAJ_spec_end + }; + + if (GNUNET_OK != + MAJ_parse_json (detail_j, + spec_detail)) + { + GNUNET_break_op (0); + response_code = 0; + break; + } + } + if (0 == response_code) + break; + wdh->cb (wdh->cb_cls, + response_code, + json, + &h_wire, + &total_amount, + num_details, + details); + json_decref (json); + TALER_MINT_wire_deposits_cancel (wdh); + return; + } + } + break; + case MHD_HTTP_BAD_REQUEST: + /* This should never happen, either us or the mint is buggy + (or API version conflict); just pass JSON reply to the application */ + break; + case MHD_HTTP_UNAUTHORIZED: + /* Nothing really to verify, mint says one of the signatures is + invalid; as we checked them, this should never happen, we + should pass the JSON reply to the application */ + break; + case MHD_HTTP_NOT_FOUND: + /* Mint does not know about transaction; + we should pass the reply to the application */ + break; + case MHD_HTTP_INTERNAL_SERVER_ERROR: + /* Server had an internal issue; we should retry, but this API + leaves this to the application */ + break; + default: + /* unexpected response code */ + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Unexpected response code %u\n", + response_code); + GNUNET_break (0); + response_code = 0; + break; + } + wdh->cb (wdh->cb_cls, + response_code, + json, + NULL, NULL, 0, NULL); + json_decref (json); + TALER_MINT_wire_deposits_cancel (wdh); +} + + +/** + * Query the mint about which transactions were combined + * to create a wire transfer. + * + * @param mint mint to query + * @param wtid raw wire transfer identifier to get information about + * @param cb callback to call + * @param cb_cls closure for @a cb + * @return handle to cancel operation + */ +struct TALER_MINT_WireDepositsHandle * +TALER_MINT_wire_deposits (struct TALER_MINT_Handle *mint, + const struct TALER_WireTransferIdentifierRawP *wtid, + TALER_MINT_WireDepositsCallback cb, + void *cb_cls) +{ + struct TALER_MINT_WireDepositsHandle *wdh; + struct TALER_MINT_Context *ctx; + json_t *wdh_obj; + CURL *eh; + + if (GNUNET_YES != + MAH_handle_is_ready (mint)) + { + GNUNET_break (0); + return NULL; + } + + wdh_obj = json_pack ("{s:o}", + "wtid", TALER_json_from_data (wtid, + sizeof (struct TALER_WireTransferIdentifierRawP))); + + wdh = GNUNET_new (struct TALER_MINT_WireDepositsHandle); + wdh->mint = mint; + wdh->cb = cb; + wdh->cb_cls = cb_cls; + wdh->url = MAH_path_to_url (mint, "/wire/deposits"); + + eh = curl_easy_init (); + GNUNET_assert (NULL != (wdh->json_enc = + json_dumps (wdh_obj, + JSON_COMPACT))); + json_decref (wdh_obj); + GNUNET_assert (CURLE_OK == + curl_easy_setopt (eh, + CURLOPT_URL, + wdh->url)); + GNUNET_assert (CURLE_OK == + curl_easy_setopt (eh, + CURLOPT_POSTFIELDS, + wdh->json_enc)); + GNUNET_assert (CURLE_OK == + curl_easy_setopt (eh, + CURLOPT_POSTFIELDSIZE, + strlen (wdh->json_enc))); + GNUNET_assert (CURLE_OK == + curl_easy_setopt (eh, + CURLOPT_WRITEFUNCTION, + &MAC_download_cb)); + GNUNET_assert (CURLE_OK == + curl_easy_setopt (eh, + CURLOPT_WRITEDATA, + &wdh->db)); + ctx = MAH_handle_to_context (mint); + wdh->job = MAC_job_add (ctx, + eh, + GNUNET_YES, + &handle_wire_deposits_finished, + wdh); + return wdh; +} + + +/** + * Cancel wire deposits request. This function cannot be used on a request + * handle if a response is already served for it. + * + * @param wdh the wire deposits request handle + */ +void +TALER_MINT_wire_deposits_cancel (struct TALER_MINT_WireDepositsHandle *wdh) +{ + if (NULL != wdh->job) + { + MAC_job_cancel (wdh->job); + wdh->job = NULL; + } + GNUNET_free_non_null (wdh->db.buf); + GNUNET_free (wdh->url); + GNUNET_free (wdh->json_enc); + GNUNET_free (wdh); +} + + +/* end of mint_api_wire_deposits.c */ diff --git a/src/mint/taler-mint-httpd_db.c b/src/mint/taler-mint-httpd_db.c index fb4ee1b7a..19c213988 100644 --- a/src/mint/taler-mint-httpd_db.c +++ b/src/mint/taler-mint-httpd_db.c @@ -1704,7 +1704,7 @@ handle_transaction_data (void *cls, */ int TMH_DB_execute_wire_deposits (struct MHD_Connection *connection, - const struct TALER_WireTransferIdentifierP *wtid) + const struct TALER_WireTransferIdentifierRawP *wtid) { int ret; struct WtidTransactionContext ctx; @@ -1720,7 +1720,7 @@ TMH_DB_execute_wire_deposits (struct MHD_Connection *connection, ctx.deposits = json_array (); ret = TMH_plugin->lookup_wire_transfer (TMH_plugin->cls, session, - &wtid->raw, + wtid, &handle_transaction_data, &ctx); if (GNUNET_SYSERR == ret) diff --git a/src/mint/taler-mint-httpd_db.h b/src/mint/taler-mint-httpd_db.h index e366112dd..0327bef2a 100644 --- a/src/mint/taler-mint-httpd_db.h +++ b/src/mint/taler-mint-httpd_db.h @@ -202,7 +202,7 @@ TMH_DB_execute_admin_add_incoming (struct MHD_Connection *connection, */ int TMH_DB_execute_wire_deposits (struct MHD_Connection *connection, - const struct TALER_WireTransferIdentifierP *wtid); + const struct TALER_WireTransferIdentifierRawP *wtid); /** diff --git a/src/mint/taler-mint-httpd_tracking.c b/src/mint/taler-mint-httpd_tracking.c index e61b4bae1..76293803d 100644 --- a/src/mint/taler-mint-httpd_tracking.c +++ b/src/mint/taler-mint-httpd_tracking.c @@ -46,22 +46,17 @@ TMH_TRACKING_handler_wire_deposits (struct TMH_RequestHandler *rh, const char *upload_data, size_t *upload_data_size) { - struct TALER_WireTransferIdentifierP wtid; + struct TALER_WireTransferIdentifierRawP wtid; int res; res = TMH_PARSE_mhd_request_arg_data (connection, "wtid", &wtid, - sizeof (struct TALER_WireTransferIdentifierP)); + sizeof (struct TALER_WireTransferIdentifierRawP)); if (GNUNET_SYSERR == res) return MHD_NO; /* internal error */ if (GNUNET_NO == res) return MHD_YES; /* parse error */ - if (wtid.crc8 != - GNUNET_CRYPTO_crc8_n (&wtid.raw, - sizeof (wtid.raw))) - return TMH_RESPONSE_reply_arg_invalid (connection, - "wtid"); return TMH_DB_execute_wire_deposits (connection, &wtid); } -- cgit v1.2.3 From 2fc6afe94693e826795f5cda768c6b3a9b11f2dd Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Fri, 22 Jan 2016 17:21:36 +0100 Subject: more robust error handling --- src/mint/taler-mint-httpd_db.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'src/mint/taler-mint-httpd_db.c') diff --git a/src/mint/taler-mint-httpd_db.c b/src/mint/taler-mint-httpd_db.c index 19c213988..c39cbbcf7 100644 --- a/src/mint/taler-mint-httpd_db.c +++ b/src/mint/taler-mint-httpd_db.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014, 2015 GNUnet e.V. + Copyright (C) 2014, 2015, 2016 GNUnet e.V. TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -1887,7 +1887,7 @@ TMH_DB_execute_deposit_wtid (struct MHD_Connection *connection, ctx.h_wire = *h_wire; ctx.coin_pub = *coin_pub; ctx.transaction_id = transaction_id; - ctx.res = MHD_NO; /* this value should never be read... */ + ctx.res = GNUNET_SYSERR; ret = TMH_plugin->wire_lookup_deposit_wtid (TMH_plugin->cls, session, h_contract, @@ -1900,10 +1900,20 @@ TMH_DB_execute_deposit_wtid (struct MHD_Connection *connection, if (GNUNET_SYSERR == ret) { GNUNET_break (0); + GNUNET_break (GNUNET_SYSERR == ctx.res); return TMH_RESPONSE_reply_internal_db_error (connection); } if (GNUNET_NO == ret) + { + GNUNET_break (GNUNET_SYSERR == ctx.res); return TMH_RESPONSE_reply_deposit_unknown (connection); + } + if (GNUNET_SYSERR == ctx.res) + { + GNUNET_break (0); + return TMH_RESPONSE_reply_internal_error (connection, + "bug resolving deposit wtid"); + } return ctx.res; } -- cgit v1.2.3 From 46d9cc367bdc9bf8cda7ae12e78ea0a2e0853d36 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Thu, 28 Jan 2016 03:58:21 +0100 Subject: finishing core logic for #4141, but untested --- src/include/taler_mint_service.h | 5 +- src/include/taler_mintdb_plugin.h | 6 +- src/include/taler_signatures.h | 14 - src/mint-lib/mint_api_deposit_wtid.c | 9 +- src/mint/taler-mint-aggregator.c | 661 ++++++++++++++++++++++++++++++++-- src/mint/taler-mint-httpd_db.c | 3 - src/mint/taler-mint-httpd_responses.c | 5 - src/mint/taler-mint-httpd_responses.h | 2 +- src/mintdb/plugin_mintdb_postgres.c | 25 +- 9 files changed, 640 insertions(+), 90 deletions(-) (limited to 'src/mint/taler-mint-httpd_db.c') diff --git a/src/include/taler_mint_service.h b/src/include/taler_mint_service.h index b151cb009..1502edfbc 100644 --- a/src/include/taler_mint_service.h +++ b/src/include/taler_mint_service.h @@ -1173,8 +1173,6 @@ struct TALER_MINT_DepositWtidHandle; * yet execute the transaction * @param execution_time actual or planned execution time for the wire transfer * @param coin_contribution contribution to the @a total_amount of the deposited coin (may be NULL) - * @param total_amount total amount of the wire transfer, or NULL if the mint could - * not provide any @a wtid (set only if @a http_status is #MHD_HTTP_OK) */ typedef void (*TALER_MINT_DepositWtidCallback)(void *cls, @@ -1182,8 +1180,7 @@ typedef void json_t *json, const struct TALER_WireTransferIdentifierRawP *wtid, struct GNUNET_TIME_Absolute execution_time, - const struct TALER_Amount *coin_contribution, - const struct TALER_Amount *total_amount); + const struct TALER_Amount *coin_contribution); /** diff --git a/src/include/taler_mintdb_plugin.h b/src/include/taler_mintdb_plugin.h index 7c48114b8..d2cc3d76e 100644 --- a/src/include/taler_mintdb_plugin.h +++ b/src/include/taler_mintdb_plugin.h @@ -583,7 +583,6 @@ typedef void * @param coin_contribution how much did the coin we asked about * contribute to the total transfer value? (deposit value including fee) * @param coin_fee how much did the mint charge for the deposit fee - * @param total_amount how much was the total wire transfer? * @param execution_time when was the transaction done, or * when we expect it to be done (if @a wtid was NULL) */ @@ -592,7 +591,6 @@ typedef void const struct TALER_WireTransferIdentifierRawP *wtid, const struct TALER_Amount *coin_contribution, const struct TALER_Amount *coin_fee, - const struct TALER_Amount *total_amount, struct GNUNET_TIME_Absolute execution_time); @@ -1360,7 +1358,6 @@ struct TALER_MINTDB_Plugin * @param coin_pub which public key was this payment about * @param coin_value amount contributed by this coin in total * @param coin_fee deposit fee charged by mint for this coin - * @param transfer_value total amount of the wire transfer * @return #GNUNET_OK on success, #GNUNET_SYSERR on DB errors */ int @@ -1374,8 +1371,7 @@ struct TALER_MINTDB_Plugin struct GNUNET_TIME_Absolute execution_time, const struct TALER_CoinSpendPublicKeyP *coin_pub, const struct TALER_Amount *coin_value, - const struct TALER_Amount *coin_fee, - const struct TALER_Amount *transfer_value); + const struct TALER_Amount *coin_fee); /** diff --git a/src/include/taler_signatures.h b/src/include/taler_signatures.h index 85c681dac..2526597ee 100644 --- a/src/include/taler_signatures.h +++ b/src/include/taler_signatures.h @@ -953,20 +953,6 @@ struct TALER_ConfirmWirePS */ struct TALER_AmountNBO coin_contribution; - /** - * The total amount the mint transferred in the transaction. - * Note that we may be aggregating multiple coin's @e coin_contribution - * values into a single wire transfer, so this value may be larger - * than that of @e coin_contribution. It may also be smaller, as - * @e coin_contribution may be say "1.123456" but the wire unit may - * be rounded down, i.e. to "1.12" (depending on the transfer method). - * - * Note that the mint books the deltas from rounding down as profit, - * so aggregating transfers is a good thing for the merchant (as it - * reduces rounding down expenses). - */ - struct TALER_AmountNBO total_amount; - }; GNUNET_NETWORK_STRUCT_END diff --git a/src/mint-lib/mint_api_deposit_wtid.c b/src/mint-lib/mint_api_deposit_wtid.c index 50f9c55d8..d29f406e3 100644 --- a/src/mint-lib/mint_api_deposit_wtid.c +++ b/src/mint-lib/mint_api_deposit_wtid.c @@ -148,9 +148,7 @@ handle_deposit_wtid_finished (void *cls, const struct TALER_WireTransferIdentifierRawP *wtid = NULL; struct GNUNET_TIME_Absolute execution_time = GNUNET_TIME_UNIT_FOREVER_ABS; const struct TALER_Amount *coin_contribution = NULL; - const struct TALER_Amount *total_amount = NULL; struct TALER_Amount coin_contribution_s; - struct TALER_Amount total_amount_s; dwh->job = NULL; json = MAC_download_get_result (&dwh->db, @@ -166,7 +164,6 @@ handle_deposit_wtid_finished (void *cls, MAJ_spec_fixed_auto ("wtid", &dwh->depconf.wtid), MAJ_spec_absolute_time ("execution_time", &execution_time), MAJ_spec_amount ("coin_contribution", &coin_contribution_s), - MAJ_spec_amount ("total_amount", &total_amount_s), MAJ_spec_end }; @@ -183,9 +180,6 @@ handle_deposit_wtid_finished (void *cls, TALER_amount_hton (&dwh->depconf.coin_contribution, &coin_contribution_s); coin_contribution = &coin_contribution_s; - TALER_amount_hton (&dwh->depconf.total_amount, - &total_amount_s); - total_amount = &total_amount_s; if (GNUNET_OK != verify_deposit_wtid_signature_ok (dwh, json)) @@ -244,8 +238,7 @@ handle_deposit_wtid_finished (void *cls, json, wtid, execution_time, - coin_contribution, - total_amount); + coin_contribution); json_decref (json); TALER_MINT_deposit_wtid_cancel (dwh); } diff --git a/src/mint/taler-mint-aggregator.c b/src/mint/taler-mint-aggregator.c index ee0f6ab22..5e05c8673 100644 --- a/src/mint/taler-mint-aggregator.c +++ b/src/mint/taler-mint-aggregator.c @@ -18,6 +18,10 @@ * @file taler-mint-aggregator.c * @brief Process that aggregates outgoing transactions and executes them * @author Christian Grothoff + * + * TODO: + * - simplify global_ret: make it a global! + * - handle shutdown more nicely (call 'cancel' method on wire transfers) */ #include "platform.h" #include @@ -62,6 +66,16 @@ static struct TALER_WIRE_Plugin *wire_plugin; */ static struct GNUNET_SCHEDULER_Task *task; +/** + * Limit on the number of transactions we aggregate at once. Note + * that the limit must be big enough to ensure that when transactions + * of the smallest possible unit are aggregated, they do surpass the + * "tiny" threshold beyond which we never trigger a wire transaction! + * + * TODO: make configurable (via config file or command line option) + */ +static unsigned int aggregation_limit = 10000; + /** * Load configuration parameters for the mint @@ -143,11 +157,86 @@ mint_serve_process_config (const char *mint_directory) } +/** + * Information about one aggregation process to + * be executed. + */ +struct AggregationUnit +{ + /** + * Public key of the merchant. + */ + struct TALER_MerchantPublicKeyP merchant_pub; + + /** + * Total amount to be transferred. + */ + struct TALER_Amount total_amount; + + /** + * Hash of @e wire. + */ + struct GNUNET_HashCode h_wire; + + /** + * Wire transfer identifier we use. + */ + struct TALER_WireTransferIdentifierRawP wtid; + + /** + * Row ID of the transaction that started it all. + */ + unsigned long long row_id; + + /** + * The current time. + */ + struct GNUNET_TIME_Absolute execution_time; + + /** + * Wire details of the merchant. + */ + json_t *wire; + + /** + * Database session for all of our transactions. + */ + struct TALER_MINTDB_Session *session; + + /** + * Wire preparation handle. + */ + struct TALER_WIRE_PrepareHandle *ph; + + /** + * Array of #aggregation_limit row_ids from the + * aggregation. + */ + unsigned long long *additional_rows; + + /** + * Pointer to global return value. Closure for #run(). + */ + int *global_ret; + + /** + * Offset specifying how many #additional_rows are in use. + */ + unsigned int rows_offset; + + /** + * Set to #GNUNET_YES if we have to abort due to failure. + */ + int failed; + +}; + + /** * Function called with details about deposits that have been made, * with the goal of executing the corresponding wire transaction. * - * @param cls closure + * @param cls closure with the `struct AggregationUnit` * @param row_id identifies database entry * @param merchant_pub public key of the merchant * @param coin_pub public key of the coin @@ -172,20 +261,187 @@ deposit_cb (void *cls, struct GNUNET_TIME_Absolute wire_deadline, const json_t *wire) { - /* FIXME: compute aggregates, etc. */ + struct AggregationUnit *au = cls; + + au->merchant_pub = *merchant_pub; + if (GNUNET_OK != + TALER_amount_subtract (&au->total_amount, + amount_with_fee, + deposit_fee)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Fatally malformed record at %llu\n", + row_id); + return GNUNET_SYSERR; + } + au->row_id = row_id; + au->wire = (json_t *) wire; + au->execution_time = GNUNET_TIME_absolute_get (); + TALER_hash_json (au->wire, + &au->h_wire); + json_incref (au->wire); + GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE, + &au->wtid, + sizeof (au->wtid)); + if (GNUNET_OK != + db_plugin->insert_aggregation_tracking (db_plugin->cls, + au->session, + &au->wtid, + merchant_pub, + &au->h_wire, + h_contract, + transaction_id, + au->execution_time, + coin_pub, + amount_with_fee, + deposit_fee)) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + if (GNUNET_OK != + db_plugin->mark_deposit_done (db_plugin->cls, + au->session, + row_id)) + { + GNUNET_break (0); + au->failed = GNUNET_YES; + return GNUNET_SYSERR; + } + return GNUNET_OK; +} + + + +/** + * Function called with details about another deposit we + * can aggregate into an existing aggregation unit. + * + * @param cls closure with the `struct AggregationUnit` + * @param row_id identifies database entry + * @param merchant_pub public key of the merchant + * @param coin_pub public key of the coin + * @param amount_with_fee amount that was deposited including fee + * @param deposit_fee amount the mint gets to keep as transaction fees + * @param transaction_id unique transaction ID chosen by the merchant + * @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 + * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop + */ +static int +aggregate_cb (void *cls, + unsigned long long row_id, + const struct TALER_MerchantPublicKeyP *merchant_pub, + const struct TALER_CoinSpendPublicKeyP *coin_pub, + const struct TALER_Amount *amount_with_fee, + const struct TALER_Amount *deposit_fee, + uint64_t transaction_id, + const struct GNUNET_HashCode *h_contract, + struct GNUNET_TIME_Absolute wire_deadline, + const json_t *wire) +{ + struct AggregationUnit *au = cls; + struct TALER_Amount delta; + + GNUNET_break (0 == + memcmp (&au->merchant_pub, + merchant_pub, + sizeof (struct TALER_MerchantPublicKeyP))); + /* compute contribution of this coin after fees */ + if (GNUNET_OK != + TALER_amount_subtract (&delta, + amount_with_fee, + deposit_fee)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Fatally malformed record at %llu\n", + row_id); + return GNUNET_SYSERR; + } + /* add to total */ + if (GNUNET_OK != + TALER_amount_add (&au->total_amount, + &au->total_amount, + &delta)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Overflow or currency incompatibility during aggregation at %llu\n", + row_id); + /* Skip this one, but keep going! */ + return GNUNET_OK; + } + if (au->rows_offset >= aggregation_limit) + { + /* Bug: we asked for at most #aggregation_limit results! */ + GNUNET_break (0); + /* Skip this one, but keep going. */ + return GNUNET_OK; + } + if (NULL == au->additional_rows) + au->additional_rows = GNUNET_new_array (aggregation_limit, + unsigned long long); + /* "append" to our list of rows */ + au->additional_rows[au->rows_offset++] = row_id; + /* insert into aggregation tracking table */ + if (GNUNET_OK != + db_plugin->insert_aggregation_tracking (db_plugin->cls, + au->session, + &au->wtid, + merchant_pub, + &au->h_wire, + h_contract, + transaction_id, + au->execution_time, + coin_pub, + amount_with_fee, + deposit_fee)) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + if (GNUNET_OK != + db_plugin->mark_deposit_done (db_plugin->cls, + au->session, + row_id)) + { + GNUNET_break (0); + au->failed = GNUNET_YES; + return GNUNET_SYSERR; + } return GNUNET_OK; } /** - * Main work function that queries the DB and executes transactions. + * Function to be called with the prepared transfer data. + * + * @param cls closure with the `struct AggregationUnit` + * @param buf transaction data to persist, NULL on error + * @param buf_size number of bytes in @a buf, 0 on error + */ +static void +prepare_cb (void *cls, + const char *buf, + size_t buf_size); + + +/** + * Main work function that queries the DB and aggregates transactions + * into larger wire transfers. + * + * @param cls pointer to an `int` which we will return from main() + * @param tc scheduler context */ static void -run (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc) +run_aggregation (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) { int *global_ret = cls; struct TALER_MINTDB_Session *session; + struct AggregationUnit *au; + unsigned int i; int ret; if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) @@ -207,50 +463,399 @@ run (void *cls, *global_ret = GNUNET_SYSERR; return; } + au = GNUNET_new (struct AggregationUnit); + au->session = session; ret = db_plugin->get_ready_deposit (db_plugin->cls, session, &deposit_cb, - NULL); - // FIXME: handle 0 == ret... - + au); if (GNUNET_OK != ret) + { + GNUNET_free (au); + db_plugin->rollback (db_plugin->cls, + session); + if (0 != ret) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Failed to execute deposit iteration!\n"); + *global_ret = GNUNET_SYSERR; + return; + } + /* nothing to do, sleep for a minute and try again */ + task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES, + &run_aggregation, + global_ret); + return; + } + /* Now try to find other deposits to aggregate */ + ret = db_plugin->iterate_matching_deposits (db_plugin->cls, + session, + &au->h_wire, + &au->merchant_pub, + &aggregate_cb, + au, + aggregation_limit); + if ( (GNUNET_SYSERR == ret) || + (GNUNET_YES == au->failed) ) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to execute deposit iteration!\n"); + GNUNET_free_non_null (au->additional_rows); + GNUNET_free (au); + db_plugin->rollback (db_plugin->cls, + session); *global_ret = GNUNET_SYSERR; + return; + } + /* Round to the unit supported by the wire transfer method */ + GNUNET_assert (GNUNET_SYSERR != + wire_plugin->amount_round (wire_plugin->cls, + &au->total_amount)); + /* Check if after rounding down, we still have an amount to transfer */ + if ( (0 == au->total_amount.value) && + (0 == au->total_amount.fraction) ) + { + /* Rollback ongoing transaction, as we will not use the respective + WTID and thus need to remove the tracking data */ + db_plugin->rollback (db_plugin->cls, + session); + /* Start another transaction to mark all* of the selected deposits + *as minor! */ + if (GNUNET_OK != + db_plugin->start (db_plugin->cls, + session)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Failed to start database transaction!\n"); + *global_ret = GNUNET_SYSERR; + GNUNET_free_non_null (au->additional_rows); + GNUNET_free (au); + return; + } + /* Mark transactions by row_id as minor */ + ret = GNUNET_OK; + if (GNUNET_OK != + db_plugin->mark_deposit_tiny (db_plugin->cls, + session, + au->row_id)) + ret = GNUNET_SYSERR; + else + for (i=0;irows_offset;i++) + if (GNUNET_OK != + db_plugin->mark_deposit_tiny (db_plugin->cls, + session, + au->additional_rows[i])) + ret = GNUNET_SYSERR; + /* commit */ + if (GNUNET_OK != + db_plugin->commit (db_plugin->cls, + session)) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Failed to commit database transaction!\n"); + } + GNUNET_free_non_null (au->additional_rows); + GNUNET_free (au); + /* start again */ + task = GNUNET_SCHEDULER_add_now (&run_aggregation, + global_ret); + return; + } + au->global_ret = global_ret; + au->ph = wire_plugin->prepare_wire_transfer (wire_plugin->cls, + au->wire, + &au->total_amount, + &au->wtid, + &prepare_cb, + au); + /* FIXME: currently we have no clean-up plan on + shutdown to call prepare_wire_transfer_cancel! + Maybe make 'au' global? */ + if (NULL == au->ph) + { + GNUNET_break (0); /* why? how to best recover? */ db_plugin->rollback (db_plugin->cls, session); + GNUNET_free_non_null (au->additional_rows); + GNUNET_free (au); + /* start again */ + task = GNUNET_SCHEDULER_add_now (&run_aggregation, + global_ret); return; } - /* FIXME: finish aggregate computation */ - /* wire_plugin->prepare_wire_transfer () -- ASYNC! */ - /* db_plugin->wire_prepare_data_insert () -- transactional! */ - /* db_plugin->XXX () -- mark transactions selected for aggregate as finished */ + /* otherwise we continue with #prepare_cb(), see below */ +} + - /* then finally: commit! */ +/** + * Execute the wire transfers that we have committed to + * do. + * + * @param cls pointer to an `int` which we will return from main() + * @param tc scheduler context + */ +static void +run_transfers (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc); + + +/** + * Function to be called with the prepared transfer data. + * + * @param cls closure with the `struct AggregationUnit` + * @param buf transaction data to persist, NULL on error + * @param buf_size number of bytes in @a buf, 0 on error + */ +static void +prepare_cb (void *cls, + const char *buf, + size_t buf_size) +{ + struct AggregationUnit *au = cls; + int *global_ret = au->global_ret; + struct TALER_MINTDB_Session *session = au->session; + + GNUNET_free_non_null (au->additional_rows); + GNUNET_free (au); + if (NULL == buf) + { + GNUNET_break (0); /* why? how to best recover? */ + db_plugin->rollback (db_plugin->cls, + session); + /* start again */ + task = GNUNET_SCHEDULER_add_now (&run_aggregation, + global_ret); + return; + } + + /* Commit our intention to execute the wire transfer! */ + if (GNUNET_OK != + db_plugin->wire_prepare_data_insert (db_plugin->cls, + session, + mint_wireformat, + buf, + buf_size)) + { + GNUNET_break (0); /* why? how to best recover? */ + db_plugin->rollback (db_plugin->cls, + session); + /* start again */ + task = GNUNET_SCHEDULER_add_now (&run_aggregation, + global_ret); + return; + } + + /* Now we can finally commit the overall transaction, as we are + again consistent if all of this passes. */ if (GNUNET_OK != db_plugin->commit (db_plugin->cls, session)) { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Failed to commit database transaction!\n"); + /* try again */ + task = GNUNET_SCHEDULER_add_now (&run_aggregation, + global_ret); + return; } - /* While possible, run 2nd type of transaction: - db_plugin->start() - - select pre-commit data from DB: - db_plugin->wire_prepare_data_iterate () - - execute wire transfer (successfully!) - wire_plugin->execute_wire_transfer() # ASYNC! - db_plugin->wire_prepare_data_mark_finished () - db_plugin->insert_aggregation_tracking () - db_plugin->commit() - */ + /* run alternative task: actually do wire transfer! */ + task = GNUNET_SCHEDULER_add_now (&run_transfers, + &global_ret); +} + + +/** + * Data we keep to #run_transfers(). + */ +struct WirePrepareData +{ + + /** + * Database session for all of our transactions. + */ + struct TALER_MINTDB_Session *session; + + /** + * Wire execution handle. + */ + struct TALER_WIRE_ExecuteHandle *eh; + + /** + * Pointer to global return value. Closure for #run(). + */ + int *global_ret; + + + /** + * Row ID of the transfer. + */ + unsigned long long row_id; +}; - task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS /* FIXME: adjust! */, - &run, - global_ret); + +/** + * Function called with the result from the execute step. + * + * @param cls closure with the `struct WirePrepareData` + * @param success #GNUNET_OK on success, #GNUNET_SYSERR on failure + * @param emsg NULL on success, otherwise an error message + */ +static void +wire_confirm_cb (void *cls, + int success, + const char *emsg) +{ + struct WirePrepareData *wpd = cls; + int *global_ret = wpd->global_ret; + struct TALER_MINTDB_Session *session = wpd->session; + + wpd->eh = NULL; + if (GNUNET_SYSERR == success) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Wire transaction failed: %s\n", + emsg); + db_plugin->rollback (db_plugin->cls, + session); + *global_ret = GNUNET_SYSERR; + GNUNET_free (wpd); + return; + } + if (GNUNET_OK != + db_plugin->wire_prepare_data_mark_finished (db_plugin->cls, + session, + wpd->row_id)) + { + GNUNET_break (0); /* why!? */ + db_plugin->rollback (db_plugin->cls, + session); + *global_ret = GNUNET_SYSERR; + GNUNET_free (wpd); + return; + } + GNUNET_free (wpd); + if (GNUNET_OK != + db_plugin->commit (db_plugin->cls, + session)) + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Failed to commit database transaction!\n"); + /* try again */ + task = GNUNET_SCHEDULER_add_now (&run_aggregation, + global_ret); + return; + } + /* continue with #run_transfers(), just to guard + against the unlikely case that there are more. */ + task = GNUNET_SCHEDULER_add_now (&run_transfers, + &global_ret); + +} + + +/** + * Callback with data about a prepared transaction. + * + * @param cls closure with the `struct WirePrepareData` + * @param rowid row identifier used to mark prepared transaction as done + * @param buf transaction data that was persisted, NULL on error + * @param buf_size number of bytes in @a buf, 0 on error + */ +static void +wire_prepare_cb (void *cls, + unsigned long long rowid, + const char *buf, + size_t buf_size) +{ + struct WirePrepareData *wpd = cls; + int *global_ret = wpd->global_ret; + + wpd->row_id = rowid; + wpd->eh = wire_plugin->execute_wire_transfer (wire_plugin->cls, + buf, + buf_size, + &wire_confirm_cb, + wpd); + /* FIXME: currently we have no clean-up plan on + shutdown to call execute_wire_transfer_cancel! + Maybe make 'wpd' global? */ + if (NULL == wpd->eh) + { + GNUNET_break (0); /* why? how to best recover? */ + db_plugin->rollback (db_plugin->cls, + wpd->session); + *global_ret = GNUNET_SYSERR; + GNUNET_free (wpd); + return; + } +} + + +/** + * Execute the wire transfers that we have committed to + * do. + * + * @param cls pointer to an `int` which we will return from main() + * @param tc scheduler context + */ +static void +run_transfers (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + int *global_ret = cls; + int ret; + struct WirePrepareData *wpd; + struct TALER_MINTDB_Session *session; + + if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) + return; + if (NULL == (session = db_plugin->get_session (db_plugin->cls, + GNUNET_NO))) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Failed to obtain database session!\n"); + *global_ret = GNUNET_SYSERR; + return; + } + if (GNUNET_OK != + db_plugin->start (db_plugin->cls, + session)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Failed to start database transaction!\n"); + *global_ret = GNUNET_SYSERR; + return; + } + wpd = GNUNET_new (struct WirePrepareData); + wpd->session = session; + wpd->global_ret = global_ret; + ret = db_plugin->wire_prepare_data_get (db_plugin->cls, + session, + mint_wireformat, + &wire_prepare_cb, + wpd); + if (GNUNET_SYSERR == ret) + { + GNUNET_break (0); /* why? how to best recover? */ + db_plugin->rollback (db_plugin->cls, + session); + *global_ret = GNUNET_SYSERR; + GNUNET_free (wpd); + return; + } + if (GNUNET_NO == ret) + { + /* no more prepared wire transfers, go back to aggregation! */ + db_plugin->rollback (db_plugin->cls, + session); + task = GNUNET_SCHEDULER_add_now (&run_aggregation, + global_ret); + GNUNET_free (wpd); + return; + } + /* otherwise, continues in #wire_prepare_cb() */ } @@ -299,7 +904,7 @@ main (int argc, return 1; } - GNUNET_SCHEDULER_run (&run, &ret); + GNUNET_SCHEDULER_run (&run_transfers, &ret); TALER_MINTDB_plugin_unload (db_plugin); TALER_WIRE_plugin_unload (wire_plugin); diff --git a/src/mint/taler-mint-httpd_db.c b/src/mint/taler-mint-httpd_db.c index c39cbbcf7..b93ead3af 100644 --- a/src/mint/taler-mint-httpd_db.c +++ b/src/mint/taler-mint-httpd_db.c @@ -1804,7 +1804,6 @@ struct DepositWtidContext * @param coin_contribution how much did the coin we asked about * contribute to the total transfer value? (deposit value including fee) * @param coin_fee how much did the mint charge for the deposit fee - * @param total_amount how much was the total wire transfer? * @param execution_time when was the transaction done, or * when we expect it to be done (if @a wtid was NULL); * #GNUNET_TIME_UNIT_FOREVER_ABS if the /deposit is unknown @@ -1815,7 +1814,6 @@ handle_wtid_data (void *cls, const struct TALER_WireTransferIdentifierRawP *wtid, const struct TALER_Amount *coin_contribution, const struct TALER_Amount *coin_fee, - const struct TALER_Amount *total_amount, struct GNUNET_TIME_Absolute execution_time) { struct DepositWtidContext *ctx = cls; @@ -1843,7 +1841,6 @@ handle_wtid_data (void *cls, &ctx->h_wire, &ctx->coin_pub, &coin_delta, - total_amount, ctx->transaction_id, wtid, execution_time); diff --git a/src/mint/taler-mint-httpd_responses.c b/src/mint/taler-mint-httpd_responses.c index 041f694bf..2ebd0d331 100644 --- a/src/mint/taler-mint-httpd_responses.c +++ b/src/mint/taler-mint-httpd_responses.c @@ -1097,7 +1097,6 @@ TMH_RESPONSE_reply_deposit_pending (struct MHD_Connection *connection, * @param coin_pub public key of the coin * @param coin_contribution how much did the coin we asked about * contribute to the total transfer value? (deposit value minus fee) - * @param total_amount how much was the total wire transfer? * @param transaction_id merchant transaction identifier * @param wtid raw wire transfer identifier * @param exec_time execution time of the wire transfer @@ -1109,7 +1108,6 @@ TMH_RESPONSE_reply_deposit_wtid (struct MHD_Connection *connection, const struct GNUNET_HashCode *h_wire, const struct TALER_CoinSpendPublicKeyP *coin_pub, const struct TALER_Amount *coin_contribution, - const struct TALER_Amount *total_amount, uint64_t transaction_id, const struct TALER_WireTransferIdentifierRawP *wtid, struct GNUNET_TIME_Absolute exec_time) @@ -1128,8 +1126,6 @@ TMH_RESPONSE_reply_deposit_wtid (struct MHD_Connection *connection, cw.execution_time = GNUNET_TIME_absolute_hton (exec_time); TALER_amount_hton (&cw.coin_contribution, coin_contribution); - TALER_amount_hton (&cw.total_amount, - total_amount); TMH_KS_sign (&cw.purpose, &pub, &sig); @@ -1140,7 +1136,6 @@ TMH_RESPONSE_reply_deposit_wtid (struct MHD_Connection *connection, sizeof (*wtid)), "execution_time", TALER_json_from_abs (exec_time), "coin_contribution", TALER_json_from_amount (coin_contribution), - "total_amount", TALER_json_from_amount (total_amount), "mint_sig", TALER_json_from_data (&sig, sizeof (sig)), "mint_pub", TALER_json_from_data (&pub, diff --git a/src/mint/taler-mint-httpd_responses.h b/src/mint/taler-mint-httpd_responses.h index caad29047..a0396c8a1 100644 --- a/src/mint/taler-mint-httpd_responses.h +++ b/src/mint/taler-mint-httpd_responses.h @@ -280,6 +280,7 @@ TMH_RESPONSE_reply_deposit_pending (struct MHD_Connection *connection, * @param h_contract hash of the contract * @param h_wire hash of wire account details * @param coin_pub public key of the coin + * @param coin_contribution contribution of this coin to the total amount transferred * @param transaction_id merchant transaction identifier * @param wtid raw wire transfer identifier * @param exec_time execution time of the wire transfer @@ -291,7 +292,6 @@ TMH_RESPONSE_reply_deposit_wtid (struct MHD_Connection *connection, const struct GNUNET_HashCode *h_wire, const struct TALER_CoinSpendPublicKeyP *coin_pub, const struct TALER_Amount *coin_contribution, - const struct TALER_Amount *total_amount, uint64_t transaction_id, const struct TALER_WireTransferIdentifierRawP *wtid, struct GNUNET_TIME_Absolute exec_time); diff --git a/src/mintdb/plugin_mintdb_postgres.c b/src/mintdb/plugin_mintdb_postgres.c index fc204f5e2..2ab3e81ac 100644 --- a/src/mintdb/plugin_mintdb_postgres.c +++ b/src/mintdb/plugin_mintdb_postgres.c @@ -466,9 +466,6 @@ postgres_create_tables (void *cls, ",coin_fee_val INT8 NOT NULL" ",coin_fee_frac INT4 NOT NULL" ",coin_fee_curr VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL" - ",transfer_total_val INT8 NOT NULL" - ",transfer_total_frac INT4 NOT NULL" - ",transfer_total_curr VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL" ")"); /* Index for lookup_transactions statement on wtid */ SQLEXEC_INDEX("CREATE INDEX aggregation_tracking_wtid_index " @@ -1090,9 +1087,6 @@ postgres_prepare (PGconn *db_conn) ",coin_fee_val" ",coin_fee_frac" ",coin_fee_curr" - ",transfer_total_val" - ",transfer_total_frac" - ",transfer_total_curr" " FROM aggregation_tracking" " WHERE wtid_raw=$1", 1, NULL); @@ -1108,9 +1102,6 @@ postgres_prepare (PGconn *db_conn) ",coin_fee_val" ",coin_fee_frac" ",coin_fee_curr" - ",transfer_total_val" - ",transfer_total_frac" - ",transfer_total_curr" " FROM aggregation_tracking" " WHERE" " coin_pub=$1 AND" @@ -1136,12 +1127,9 @@ postgres_prepare (PGconn *db_conn) ",coin_fee_val" ",coin_fee_frac" ",coin_fee_curr" - ",transfer_total_val" - ",transfer_total_frac" - ",transfer_total_curr" ") VALUES " - "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16)", - 16, NULL); + "($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)", + 13, NULL); /* Used in #postgres_wire_prepare_data_insert() to store @@ -3950,7 +3938,6 @@ postgres_wire_lookup_deposit_wtid (void *cls, NULL, &coin_amount, &coin_fee, - NULL, exec_time); PQclear (result); return GNUNET_YES; @@ -3967,13 +3954,11 @@ postgres_wire_lookup_deposit_wtid (void *cls, struct GNUNET_TIME_Absolute exec_time; struct TALER_Amount coin_amount; struct TALER_Amount coin_fee; - struct TALER_Amount transaction_amount; struct TALER_PQ_ResultSpec rs[] = { TALER_PQ_result_spec_auto_from_type ("wtid_raw", &wtid), TALER_PQ_result_spec_absolute_time ("execution_time", &exec_time), TALER_PQ_result_spec_amount ("coin_amount", &coin_amount), TALER_PQ_result_spec_amount ("coin_fee", &coin_fee), - TALER_PQ_result_spec_amount ("transfer_total", &transaction_amount), TALER_PQ_result_spec_end }; if (GNUNET_OK != TALER_PQ_extract_result (result, rs, 0)) @@ -3986,7 +3971,6 @@ postgres_wire_lookup_deposit_wtid (void *cls, &wtid, &coin_amount, &coin_fee, - &transaction_amount, exec_time); } PQclear (result); @@ -4007,7 +3991,6 @@ postgres_wire_lookup_deposit_wtid (void *cls, * @param coin_pub which public key was this payment about * @param coin_value amount contributed by this coin in total * @param coin_fee deposit fee charged by mint for this coin - * @param transfer_value total amount of the wire transfer * @return #GNUNET_OK on success, #GNUNET_SYSERR on DB errors */ static int @@ -4021,8 +4004,7 @@ postgres_insert_aggregation_tracking (void *cls, struct GNUNET_TIME_Absolute execution_time, const struct TALER_CoinSpendPublicKeyP *coin_pub, const struct TALER_Amount *coin_value, - const struct TALER_Amount *coin_fee, - const struct TALER_Amount *transfer_value) + const struct TALER_Amount *coin_fee) { struct TALER_PQ_QueryParam params[] = { TALER_PQ_query_param_auto_from_type (h_contract), @@ -4034,7 +4016,6 @@ postgres_insert_aggregation_tracking (void *cls, TALER_PQ_query_param_absolute_time (&execution_time), TALER_PQ_query_param_amount (coin_value), TALER_PQ_query_param_amount (coin_fee), - TALER_PQ_query_param_amount (transfer_value), TALER_PQ_query_param_end }; PGresult *result; -- cgit v1.2.3