diff options
author | Christian Grothoff <christian@grothoff.org> | 2021-10-17 13:22:15 +0200 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2021-10-17 13:22:15 +0200 |
commit | 932d2aaf88d9c871bc64abcd8d7ab9c5a4f543fd (patch) | |
tree | 56e30b12989583a01d24dd496d8dec67ab3a90f5 /src | |
parent | 0739405f679782ed925cb3041dda14d062798ff2 (diff) | |
download | exchange-932d2aaf88d9c871bc64abcd8d7ab9c5a4f543fd.tar.xz |
implement returning KYC status from GET /deposits/ endpoint
Diffstat (limited to 'src')
-rw-r--r-- | src/exchange/taler-exchange-httpd_deposits_get.c | 88 | ||||
-rw-r--r-- | src/exchangedb/plugin_exchangedb_postgres.c | 99 | ||||
-rw-r--r-- | src/exchangedb/test_exchangedb.c | 87 | ||||
-rw-r--r-- | src/include/taler_exchange_service.h | 6 | ||||
-rw-r--r-- | src/include/taler_exchangedb_plugin.h | 41 | ||||
-rw-r--r-- | src/lib/exchange_api_deposits_get.c | 5 |
6 files changed, 149 insertions, 177 deletions
diff --git a/src/exchange/taler-exchange-httpd_deposits_get.c b/src/exchange/taler-exchange-httpd_deposits_get.c index c0c6fdfe2..2423cc967 100644 --- a/src/exchange/taler-exchange-httpd_deposits_get.c +++ b/src/exchange/taler-exchange-httpd_deposits_get.c @@ -137,6 +137,11 @@ struct DepositWtidContext struct TALER_Amount coin_delta; /** + * KYC status information for the receiving account. + */ + struct TALER_EXCHANGEDB_KycStatus kyc; + + /** * Set to #GNUNET_YES by #handle_wtid if the wire transfer is still pending * (and the above were not set). * Set to #GNUNET_SYSERR if there was a serious error. @@ -146,52 +151,6 @@ struct DepositWtidContext /** - * Function called with the results of the lookup of the - * wire transfer identifier information. - * - * @param cls our context for transmission, a `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 including fee) - * @param coin_fee how much did the exchange charge for the deposit fee - * @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 exchange - */ -static void -handle_wtid_data (void *cls, - const struct TALER_WireTransferIdentifierRawP *wtid, - const struct TALER_Amount *coin_contribution, - const struct TALER_Amount *coin_fee, - struct GNUNET_TIME_Absolute execution_time) -{ - struct DepositWtidContext *ctx = cls; - - if (NULL == wtid) - { - ctx->pending = GNUNET_YES; - ctx->execution_time = execution_time; - return; - } - if (0 > - TALER_amount_subtract (&ctx->coin_delta, - coin_contribution, - coin_fee)) - { - GNUNET_break (0); - ctx->pending = GNUNET_SYSERR; - return; - } - ctx->wtid = *wtid; - ctx->execution_time = execution_time; - ctx->coin_contribution = *coin_contribution; - ctx->coin_fee = *coin_fee; -} - - -/** * Execute a "deposits" GET. Returns the transfer information * associated with the given deposit. * @@ -214,14 +173,21 @@ deposits_get_transaction (void *cls, { struct DepositWtidContext *ctx = cls; enum GNUNET_DB_QueryStatus qs; + bool pending; + struct TALER_Amount fee; qs = TEH_plugin->lookup_transfer_by_deposit (TEH_plugin->cls, &ctx->tps->h_contract_terms, &ctx->tps->h_wire, &ctx->tps->coin_pub, ctx->merchant_pub, - &handle_wtid_data, - ctx); + + &pending, + &ctx->wtid, + &ctx->execution_time, + &ctx->coin_contribution, + &fee, + &ctx->kyc); if (0 > qs) { if (GNUNET_DB_STATUS_HARD_ERROR == qs) @@ -242,6 +208,17 @@ deposits_get_transaction (void *cls, NULL); return GNUNET_DB_STATUS_HARD_ERROR; } + + if (0 > + TALER_amount_subtract (&ctx->coin_delta, + &ctx->coin_contribution, + &fee)) + { + GNUNET_break (0); + ctx->pending = GNUNET_SYSERR; + return qs; + } + ctx->pending = (pending) ? GNUNET_YES : GNUNET_NO; return qs; } @@ -262,7 +239,6 @@ handle_track_transaction_request ( { MHD_RESULT mhd_ret; struct DepositWtidContext ctx = { - .pending = GNUNET_NO, .tps = tps, .merchant_pub = merchant_pub }; @@ -274,17 +250,21 @@ handle_track_transaction_request ( &deposits_get_transaction, &ctx)) return mhd_ret; + if (GNUNET_SYSERR == ctx.pending) + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_GENERIC_DB_INVARIANT_FAILURE, + "wire fees exceed aggregate in database"); if (GNUNET_YES == ctx.pending) return TALER_MHD_REPLY_JSON_PACK ( connection, MHD_HTTP_ACCEPTED, + GNUNET_JSON_pack_uint64 ("payment_target_uuid", + ctx.kyc.payment_target_uuid), + GNUNET_JSON_pack_bool ("kyc_ok", + ctx.kyc.ok), GNUNET_JSON_pack_time_abs ("execution_time", ctx.execution_time)); - if (GNUNET_SYSERR == ctx.pending) - return TALER_MHD_reply_with_error (connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_DB_INVARIANT_FAILURE, - "wire fees exceed aggregate in database"); return reply_deposit_details (connection, &tps->h_contract_terms, &tps->h_wire, diff --git a/src/exchangedb/plugin_exchangedb_postgres.c b/src/exchangedb/plugin_exchangedb_postgres.c index dfd7432e3..54a03dce9 100644 --- a/src/exchangedb/plugin_exchangedb_postgres.c +++ b/src/exchangedb/plugin_exchangedb_postgres.c @@ -948,7 +948,9 @@ prepare_statements (struct PostgresClosure *pg) Used in #postgres_lookup_transfer_by_deposit(). */ GNUNET_PQ_make_prepare ("get_deposit_for_wtid", "SELECT" - " amount_with_fee_val" + " FALSE AS kyc_ok" // FIXME + ",CAST (0 AS INT8) AS payment_target_uuid" // FIXME + ",amount_with_fee_val" ",amount_with_fee_frac" ",denom.fee_deposit_val" ",denom.fee_deposit_frac" @@ -957,9 +959,9 @@ prepare_statements (struct PostgresClosure *pg) " JOIN known_coins USING (known_coin_id)" " JOIN denominations denom USING (denominations_serial)" " WHERE ((coin_pub=$1)" - " AND (merchant_pub=$2)" - " AND (h_contract_terms=$3)" - " AND (h_wire=$4)" + " AND (merchant_pub=$4)" + " AND (h_contract_terms=$2)" + " AND (h_wire=$3)" " );", 4), /* Used in #postgres_get_ready_deposit() */ @@ -6686,10 +6688,16 @@ postgres_lookup_wire_transfer ( * @param h_wire hash of merchant wire details * @param coin_pub public key of deposited coin * @param merchant_pub merchant public key - * @param cb function to call with the result - * @param cb_cls closure to pass to @a cb + * @param[out] pending set to true if the transaction is still pending + * @param[out] wtid wire transfer identifier, only set if @a pending is false + * @param[out] coin_contribution how much did the coin we asked about + * contribute to the total transfer value? (deposit value including fee) + * @param[out] coin_fee how much did the exchange charge for the deposit fee + * @param[out] execution_time when was the transaction done, or + * when we expect it to be done (if @a pending is false) + * @param[out] kyc set to the kyc status of the receiver (if @a pending) * @return transaction status code - - */ + */ static enum GNUNET_DB_QueryStatus postgres_lookup_transfer_by_deposit ( void *cls, @@ -6697,8 +6705,12 @@ postgres_lookup_transfer_by_deposit ( const struct GNUNET_HashCode *h_wire, const struct TALER_CoinSpendPublicKeyP *coin_pub, const struct TALER_MerchantPublicKeyP *merchant_pub, - TALER_EXCHANGEDB_WireTransferByCoinCallback cb, - void *cb_cls) + bool *pending, + struct TALER_WireTransferIdentifierRawP *wtid, + struct GNUNET_TIME_Absolute *exec_time, + struct TALER_Amount *amount_with_fee, + struct TALER_Amount *deposit_fee, + struct TALER_EXCHANGEDB_KycStatus *kyc) { struct PostgresClosure *pg = cls; enum GNUNET_DB_QueryStatus qs; @@ -6709,39 +6721,39 @@ postgres_lookup_transfer_by_deposit ( GNUNET_PQ_query_param_auto_from_type (merchant_pub), GNUNET_PQ_query_param_end }; - struct TALER_WireTransferIdentifierRawP wtid; - struct GNUNET_TIME_Absolute exec_time; - struct TALER_Amount amount_with_fee; - struct TALER_Amount deposit_fee; struct GNUNET_PQ_ResultSpec rs[] = { GNUNET_PQ_result_spec_auto_from_type ("wtid_raw", - &wtid), + wtid), TALER_PQ_result_spec_absolute_time ("execution_date", - &exec_time), + exec_time), TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee", - &amount_with_fee), + amount_with_fee), TALER_PQ_RESULT_SPEC_AMOUNT ("fee_deposit", - &deposit_fee), + deposit_fee), GNUNET_PQ_result_spec_end }; - /* check if the melt record exists and get it */ + /* check if the aggregation record exists and get it */ qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn, "lookup_deposit_wtid", params, rs); if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs) { - cb (cb_cls, - &wtid, - &amount_with_fee, - &deposit_fee, - exec_time); + *pending = false; + memset (kyc, + 0, + sizeof (*kyc)); + kyc->type = TALER_EXCHANGEDB_KYC_DEPOSIT; + kyc->ok = true; return qs; } if (0 > qs) return qs; - + *pending = true; + memset (wtid, + 0, + sizeof (*wtid)); GNUNET_assert (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "lookup_deposit_wtid returned 0 matching rows\n"); @@ -6749,38 +6761,27 @@ postgres_lookup_transfer_by_deposit ( /* 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 GNUNET_PQ_QueryParam params2[] = { - GNUNET_PQ_query_param_auto_from_type (coin_pub), - GNUNET_PQ_query_param_auto_from_type (merchant_pub), - GNUNET_PQ_query_param_auto_from_type (h_contract_terms), - GNUNET_PQ_query_param_auto_from_type (h_wire), - GNUNET_PQ_query_param_end - }; - struct GNUNET_TIME_Absolute exec_time; - struct TALER_Amount amount_with_fee; - struct TALER_Amount deposit_fee; + uint8_t ok8 = 0; struct GNUNET_PQ_ResultSpec rs2[] = { - TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee", &amount_with_fee), - TALER_PQ_RESULT_SPEC_AMOUNT ("fee_deposit", &deposit_fee), - TALER_PQ_result_spec_absolute_time ("wire_deadline", &exec_time), + GNUNET_PQ_result_spec_uint64 ("payment_target_uuid", + &kyc->payment_target_uuid), + GNUNET_PQ_result_spec_auto_from_type ("kyc_ok", + &ok8), + TALER_PQ_RESULT_SPEC_AMOUNT ("amount_with_fee", + amount_with_fee), + TALER_PQ_RESULT_SPEC_AMOUNT ("fee_deposit", + deposit_fee), + TALER_PQ_result_spec_absolute_time ("wire_deadline", + exec_time), GNUNET_PQ_result_spec_end }; qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn, "get_deposit_for_wtid", - params2, + params, rs2); - if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs) - { - /* Ok, we're aware of the transaction, but it has not yet been - executed */ - cb (cb_cls, - NULL, - &amount_with_fee, - &deposit_fee, - exec_time); - return qs; - } + kyc->type = TALER_EXCHANGEDB_KYC_DEPOSIT; + kyc->ok = (0 != ok8); return qs; } } diff --git a/src/exchangedb/test_exchangedb.c b/src/exchangedb/test_exchangedb.c index bfe131639..c68cba816 100644 --- a/src/exchangedb/test_exchangedb.c +++ b/src/exchangedb/test_exchangedb.c @@ -716,20 +716,6 @@ cb_wt_never (void *cls, } -/** - * Callback that should never be called. - */ -static void -cb_wtid_never (void *cls, - const struct TALER_WireTransferIdentifierRawP *wtid, - const struct TALER_Amount *coin_contribution, - const struct TALER_Amount *coin_fee, - struct GNUNET_TIME_Absolute execution_time) -{ - GNUNET_assert (0); -} - - static struct TALER_MerchantPublicKeyP merchant_pub_wt; static struct GNUNET_HashCode h_wire_wt; static struct GNUNET_HashCode h_contract_terms_wt; @@ -778,28 +764,6 @@ cb_wt_check (void *cls, /** - * Callback that should be called with the WT data. - */ -static void -cb_wtid_check (void *cls, - const struct TALER_WireTransferIdentifierRawP *wtid, - const struct TALER_Amount *coin_contribution, - const struct TALER_Amount *coin_fee, - struct GNUNET_TIME_Absolute execution_time) -{ - GNUNET_assert (cls == &cb_wtid_never); - GNUNET_assert (0 == GNUNET_memcmp (wtid, - &wire_out_wtid)); - GNUNET_assert (execution_time.abs_value_us == - wire_out_date.abs_value_us); - GNUNET_assert (0 == TALER_amount_cmp (coin_contribution, - &coin_value_wt)); - GNUNET_assert (0 == TALER_amount_cmp (coin_fee, - &coin_fee_wt)); -} - - -/** * Here #deposit_cb() will store the row ID of the deposit. */ static uint64_t deposit_rowid; @@ -1285,6 +1249,12 @@ test_wire_out (const struct TALER_EXCHANGEDB_Deposit *deposit) { struct GNUNET_HashCode h_contract_terms_wt2 = h_contract_terms_wt; + bool pending; + struct TALER_WireTransferIdentifierRawP wtid2; + struct TALER_Amount coin_contribution2; + struct TALER_Amount coin_fee2; + struct GNUNET_TIME_Absolute execution_time2; + struct TALER_EXCHANGEDB_KycStatus kyc; h_contract_terms_wt2.bits[0]++; FAILIF (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != @@ -1293,8 +1263,12 @@ test_wire_out (const struct TALER_EXCHANGEDB_Deposit *deposit) &h_wire_wt, &coin_pub_wt, &merchant_pub_wt, - &cb_wtid_never, - NULL)); + &pending, + &wtid2, + &execution_time2, + &coin_contribution2, + &coin_fee2, + &kyc)); } /* insert WT data */ FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != @@ -1338,14 +1312,35 @@ test_wire_out (const struct TALER_EXCHANGEDB_Deposit *deposit) &wire_out_wtid, &cb_wt_check, &cb_wt_never)); - FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != - plugin->lookup_transfer_by_deposit (plugin->cls, - &h_contract_terms_wt, - &h_wire_wt, - &coin_pub_wt, - &merchant_pub_wt, - &cb_wtid_check, - &cb_wtid_never)); + { + bool pending; + struct TALER_WireTransferIdentifierRawP wtid2; + struct TALER_Amount coin_contribution2; + struct TALER_Amount coin_fee2; + struct GNUNET_TIME_Absolute execution_time2; + struct TALER_EXCHANGEDB_KycStatus kyc; + + FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != + plugin->lookup_transfer_by_deposit (plugin->cls, + &h_contract_terms_wt, + &h_wire_wt, + &coin_pub_wt, + &merchant_pub_wt, + &pending, + &wtid2, + &execution_time2, + &coin_contribution2, + &coin_fee2, + &kyc)); + GNUNET_assert (0 == GNUNET_memcmp (&wtid2, + &wire_out_wtid)); + GNUNET_assert (execution_time2.abs_value_us == + wire_out_date.abs_value_us); + GNUNET_assert (0 == TALER_amount_cmp (&coin_contribution2, + &coin_value_wt)); + GNUNET_assert (0 == TALER_amount_cmp (&coin_fee2, + &coin_fee_wt)); + } FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != plugin->select_wire_out_above_serial_id (plugin->cls, 0, diff --git a/src/include/taler_exchange_service.h b/src/include/taler_exchange_service.h index 2bfb08547..9d89c96b6 100644 --- a/src/include/taler_exchange_service.h +++ b/src/include/taler_exchange_service.h @@ -1874,6 +1874,12 @@ struct TALER_EXCHANGE_GetDepositResponse * to check for its KYC status. */ uint64_t payment_target_uuid; + + /** + * Set to 'true' if the KYC check is already finished and + * the exchange is merely waiting for the @e execution_time. + */ + bool kyc_ok; } accepted; } details; diff --git a/src/include/taler_exchangedb_plugin.h b/src/include/taler_exchangedb_plugin.h index 17d78217d..286162fbc 100644 --- a/src/include/taler_exchangedb_plugin.h +++ b/src/include/taler_exchangedb_plugin.h @@ -1833,29 +1833,6 @@ typedef void /** - * Function called with the results of the lookup of the 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 including fee) - * @param coin_fee how much did the exchange charge for the deposit fee - * @param execution_time when was the transaction done, or - * when we expect it to be done (if @a wtid was NULL) - */ -typedef void -(*TALER_EXCHANGEDB_WireTransferByCoinCallback)( - void *cls, - const struct TALER_WireTransferIdentifierRawP *wtid, - const struct TALER_Amount *coin_contribution, - const struct TALER_Amount *coin_fee, - struct GNUNET_TIME_Absolute execution_time); - - -/** * Function called with the results of the lookup of the * transaction data associated with a wire transfer identifier. * @@ -2916,8 +2893,14 @@ struct TALER_EXCHANGEDB_Plugin * @param h_wire hash of merchant wire details * @param coin_pub public key of deposited coin * @param merchant_pub merchant public key - * @param cb function to call with the result - * @param cb_cls closure to pass to @a cb + * @param[out] pending set to true if the transaction is still pending + * @param[out] wtid wire transfer identifier, only set if @a pending is false + * @param[out] coin_contribution how much did the coin we asked about + * contribute to the total transfer value? (deposit value including fee) + * @param[out] coin_fee how much did the exchange charge for the deposit fee + * @param[out] execution_time when was the transaction done, or + * when we expect it to be done (if @a pending is false) + * @param[out] kyc set to the kyc status of the receiver (if @a pending) * @return transaction status code */ enum GNUNET_DB_QueryStatus @@ -2927,8 +2910,12 @@ struct TALER_EXCHANGEDB_Plugin const struct GNUNET_HashCode *h_wire, const struct TALER_CoinSpendPublicKeyP *coin_pub, const struct TALER_MerchantPublicKeyP *merchant_pub, - TALER_EXCHANGEDB_WireTransferByCoinCallback cb, - void *cb_cls); + bool *pending, + struct TALER_WireTransferIdentifierRawP *wtid, + struct GNUNET_TIME_Absolute *exec_time, + struct TALER_Amount *amount_with_fee, + struct TALER_Amount *deposit_fee, + struct TALER_EXCHANGEDB_KycStatus *kyc); /** diff --git a/src/lib/exchange_api_deposits_get.c b/src/lib/exchange_api_deposits_get.c index 6c2aa1cb1..f57388c89 100644 --- a/src/lib/exchange_api_deposits_get.c +++ b/src/lib/exchange_api_deposits_get.c @@ -197,6 +197,10 @@ handle_deposit_wtid_finished (void *cls, struct GNUNET_JSON_Specification spec[] = { TALER_JSON_spec_absolute_time ("execution_time", &dr.details.accepted.execution_time), + GNUNET_JSON_spec_uint64 ("execution_time", + &dr.details.accepted.payment_target_uuid), + GNUNET_JSON_spec_bool ("kyc_ok", + &dr.details.accepted.kyc_ok), GNUNET_JSON_spec_end () }; @@ -210,7 +214,6 @@ handle_deposit_wtid_finished (void *cls, dr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED; break; } - dr.details.accepted.payment_target_uuid; // FIXME dwh->cb (dwh->cb_cls, &dr); TALER_EXCHANGE_deposits_get_cancel (dwh); |