more work on crypto RSA helper

This commit is contained in:
Christian Grothoff 2020-11-14 22:27:50 +01:00
parent 81d6f8e0df
commit 4f0e38ab12
No known key found for this signature in database
GPG Key ID: 939E6BE1E29FC3CC
9 changed files with 1055 additions and 228 deletions

View File

@ -1,3 +1,10 @@
Sat 14 Nov 2020 05:47:30 PM CET
Modify taler-exchange-transfer to continue even after a
wire transfer failed due to the bank refusing it because
the target account does not exist. Changed the database
to track such failures in the respective table.
Opens new issue #6647. -CG
Tue 10 Nov 2020 01:03:22 PM CET Tue 10 Nov 2020 01:03:22 PM CET
Updates to error codes and HTTP status codes for improved Updates to error codes and HTTP status codes for improved
consistency. Fixed spelling issues. Ensure main() returns consistency. Fixed spelling issues. Ensure main() returns

View File

@ -264,8 +264,26 @@ wire_confirm_cb (void *cls,
(void) row_id; (void) row_id;
(void) wire_timestamp; (void) wire_timestamp;
wpd->eh = NULL; wpd->eh = NULL;
if (MHD_HTTP_OK != http_status_code) switch (http_status_code)
{ {
case MHD_HTTP_OK:
qs = db_plugin->wire_prepare_data_mark_finished (db_plugin->cls,
session,
wpd->row_id);
/* continued below */
break;
case MHD_HTTP_NOT_FOUND:
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Wire transaction %llu failed: %u/%d\n",
(unsigned long long) wpd->row_id,
http_status_code,
ec);
qs = db_plugin->wire_prepare_data_mark_failed (db_plugin->cls,
session,
wpd->row_id);
/* continued below */
break;
default:
GNUNET_log (GNUNET_ERROR_TYPE_ERROR, GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Wire transaction failed: %u/%d\n", "Wire transaction failed: %u/%d\n",
http_status_code, http_status_code,
@ -278,9 +296,6 @@ wire_confirm_cb (void *cls,
wpd = NULL; wpd = NULL;
return; return;
} }
qs = db_plugin->wire_prepare_data_mark_finished (db_plugin->cls,
session,
wpd->row_id);
if (0 >= qs) if (0 >= qs)
{ {
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);

View File

@ -17,7 +17,9 @@ sqldir = $(prefix)/share/taler/sql/exchange/
sql_DATA = \ sql_DATA = \
exchange-0000.sql \ exchange-0000.sql \
exchange-0001.sql \ exchange-0001.sql \
drop0001.sql exchange-0002.sql \
drop0001.sql \
drop0002.sql
EXTRA_DIST = \ EXTRA_DIST = \
exchangedb.conf \ exchangedb.conf \

View File

@ -0,0 +1,26 @@
--
-- This file is part of TALER
-- Copyright (C) 2020 Taler Systems SA
--
-- 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, see <http://www.gnu.org/licenses/>
--
-- Everything in one big transaction
BEGIN;
-- exchange-0002 did not create new tables, so nothing to do here.
-- Unregister patch (0002.sql)
SELECT _v.unregister_patch('exchange-0002');
-- And we're out of here...
COMMIT;

View File

@ -0,0 +1,48 @@
--
-- This file is part of TALER
-- Copyright (C) 2020 Taler Systems SA
--
-- 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, see <http://www.gnu.org/licenses/>
--
-- Everything in one big transaction
BEGIN;
-- Check patch versioning is in place.
SELECT _v.register_patch('exchange-0002', NULL, NULL);
ALTER TABLE prewire
ADD failed BOOLEAN NOT NULL DEFAULT false;
COMMENT ON COLUMN prewire.failed
IS 'set to TRUE if the bank responded with a non-transient failure to our transfer request';
COMMENT ON COLUMN prewire.finished
IS 'set to TRUE once bank confirmed receiving the wire transfer request';
COMMENT ON COLUMN prewire.buf
IS 'serialized data to send to the bank to execute the wire transfer';
-- change comment, existing index is still useful, but only for gc_prewire.
COMMENT ON INDEX prepare_iteration_index
IS 'for gc_prewire';
-- need a new index for updated wire_prepare_data_get statement:
CREATE INDEX IF NOT EXISTS prepare_get_index
ON prewire
(failed,finished);
COMMENT ON INDEX prepare_get_index
IS 'for wire_prepare_data_get';
-- Complete transaction
COMMIT;

View File

@ -1098,7 +1098,13 @@ postgres_get_session (void *cls)
/* Used in #postgres_wire_prepare_data_mark_finished() */ /* Used in #postgres_wire_prepare_data_mark_finished() */
GNUNET_PQ_make_prepare ("wire_prepare_data_mark_done", GNUNET_PQ_make_prepare ("wire_prepare_data_mark_done",
"UPDATE prewire" "UPDATE prewire"
" SET finished=true" " SET finished=TRUE"
" WHERE prewire_uuid=$1;",
1),
/* Used in #postgres_wire_prepare_data_mark_failed() */
GNUNET_PQ_make_prepare ("wire_prepare_data_mark_failed",
"UPDATE prewire"
" SET failed=TRUE"
" WHERE prewire_uuid=$1;", " WHERE prewire_uuid=$1;",
1), 1),
/* Used in #postgres_wire_prepare_data_get() */ /* Used in #postgres_wire_prepare_data_get() */
@ -1108,11 +1114,11 @@ postgres_get_session (void *cls)
",type" ",type"
",buf" ",buf"
" FROM prewire" " FROM prewire"
" WHERE finished=false" " WHERE finished=FALSE"
" AND failed=FALSE"
" ORDER BY prewire_uuid ASC" " ORDER BY prewire_uuid ASC"
" LIMIT 1;", " LIMIT 1;",
0), 0),
/* Used in #postgres_select_deposits_missing_wire */ /* Used in #postgres_select_deposits_missing_wire */
GNUNET_PQ_make_prepare ("deposits_get_overdue", GNUNET_PQ_make_prepare ("deposits_get_overdue",
"SELECT" "SELECT"
@ -5224,9 +5230,9 @@ postgres_wire_prepare_data_insert (void *cls,
* @return transaction status code * @return transaction status code
*/ */
static enum GNUNET_DB_QueryStatus static enum GNUNET_DB_QueryStatus
postgres_wire_prepare_data_mark_finished (void *cls, postgres_wire_prepare_data_mark_finished (
struct TALER_EXCHANGEDB_Session * void *cls,
session, struct TALER_EXCHANGEDB_Session *session,
uint64_t rowid) uint64_t rowid)
{ {
struct GNUNET_PQ_QueryParam params[] = { struct GNUNET_PQ_QueryParam params[] = {
@ -5241,6 +5247,32 @@ postgres_wire_prepare_data_mark_finished (void *cls,
} }
/**
* Function called to mark wire transfer commit data as failed.
*
* @param cls closure
* @param session database connection
* @param rowid which entry to mark as failed
* @return transaction status code
*/
static enum GNUNET_DB_QueryStatus
postgres_wire_prepare_data_mark_failed (
void *cls,
struct TALER_EXCHANGEDB_Session *session,
uint64_t rowid)
{
struct GNUNET_PQ_QueryParam params[] = {
GNUNET_PQ_query_param_uint64 (&rowid),
GNUNET_PQ_query_param_end
};
(void) cls;
return GNUNET_PQ_eval_prepared_non_select (session->conn,
"wire_prepare_data_mark_failed",
params);
}
/** /**
* Function called to get an unfinished wire transfer * Function called to get an unfinished wire transfer
* preparation data. Fetches at most one item. * preparation data. Fetches at most one item.
@ -7379,6 +7411,8 @@ libtaler_plugin_exchangedb_postgres_init (void *cls)
plugin->wire_prepare_data_insert = &postgres_wire_prepare_data_insert; plugin->wire_prepare_data_insert = &postgres_wire_prepare_data_insert;
plugin->wire_prepare_data_mark_finished = plugin->wire_prepare_data_mark_finished =
&postgres_wire_prepare_data_mark_finished; &postgres_wire_prepare_data_mark_finished;
plugin->wire_prepare_data_mark_failed =
&postgres_wire_prepare_data_mark_failed;
plugin->wire_prepare_data_get = &postgres_wire_prepare_data_get; plugin->wire_prepare_data_get = &postgres_wire_prepare_data_get;
plugin->start_deferred_wire_out = &postgres_start_deferred_wire_out; plugin->start_deferred_wire_out = &postgres_start_deferred_wire_out;
plugin->store_wire_transfer_out = &postgres_store_wire_transfer_out; plugin->store_wire_transfer_out = &postgres_store_wire_transfer_out;

View File

@ -2429,6 +2429,20 @@ struct TALER_EXCHANGEDB_Plugin
uint64_t rowid); uint64_t rowid);
/**
* Function called to mark wire transfer as failed.
*
* @param cls closure
* @param session database connection
* @param rowid which entry to mark as failed
* @return transaction status code
*/
enum GNUNET_DB_QueryStatus
(*wire_prepare_data_mark_failed)(void *cls,
struct TALER_EXCHANGEDB_Session *session,
uint64_t rowid);
/** /**
* Function called to get an unfinished wire transfer * Function called to get an unfinished wire transfer
* preparation data. Fetches at most one item. * preparation data. Fetches at most one item.

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,90 @@
/*
This file is part of TALER
Copyright (C) 2020 Taler Systems SA
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, see <http://www.gnu.org/licenses/>
*/
/**
* @file util/taler-helper-crypto-rsa.h
* @brief IPC messages for the RSA crypto helper.
* @author Christian Grothoff
*/
#ifndef TALER_HELPER_CRYPTO_RSA_H
#define TALER_HELPER_CRYPTO_RSA_H
GNUNET_NETWORK_STRUCT_BEGIN
/**
* Message sent if a key is available.
*/
struct TALER_CRYPTO_RsaKeyAvailableNotification
{
/**
* Type is PURGE.
*/
struct GNUNET_MessageHeader header;
/**
* Number of bytes of the public key.
*/
uint16_t pub_size;
/**
* Number of bytes of the section name.
*/
uint16_t section_name;
/**
* When does the key become available?
*/
struct GNUNET_TIME_AbsoluteNBO anchor_time;
/**
* How long is the key available after @e anchor_time?
*/
struct GNUNET_TIME_RelativeNBO duration_withdraw;
/* followed by @e pub_size bytes of the public key */
/* followed by @e section_name bytes of the configuration section name
of the denomination of this key */
};
/**
* Message sent if a key was purged.
*/
struct TALER_CRYPTO_RsaKeyPurgeNotification
{
/**
* Type is PURGE.
*/
struct GNUNET_MessageHeader header;
/**
* For now, always zero.
*/
uint32_t reserved;
/**
* Hash of the public key of the purged RSA key.
*/
struct GNUNET_HashCode h_denom_pub;
};
GNUNET_NETWORK_STRUCT_END
#endif