address DB failure error handling in KYC check

This commit is contained in:
Christian Grothoff 2023-01-27 14:10:27 +01:00
parent 7e8e2f4317
commit c239ba6f18
No known key found for this signature in database
GPG Key ID: 939E6BE1E29FC3CC
9 changed files with 155 additions and 40 deletions

View File

@ -484,13 +484,19 @@ kyc_satisfied (struct AggregationUnit *au_active)
const char *requirement; const char *requirement;
enum GNUNET_DB_QueryStatus qs; enum GNUNET_DB_QueryStatus qs;
requirement = TALER_KYCLOGIC_kyc_test_required ( qs = TALER_KYCLOGIC_kyc_test_required (
TALER_KYCLOGIC_KYC_TRIGGER_DEPOSIT, TALER_KYCLOGIC_KYC_TRIGGER_DEPOSIT,
&au_active->h_payto, &au_active->h_payto,
db_plugin->select_satisfied_kyc_processes, db_plugin->select_satisfied_kyc_processes,
db_plugin->cls, db_plugin->cls,
&return_relevant_amounts, &return_relevant_amounts,
(void *) au_active); (void *) au_active,
&requirement);
if (qs < 0)
{
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
return false;
}
if (NULL == requirement) if (NULL == requirement)
return true; return true;
GNUNET_log (GNUNET_ERROR_TYPE_INFO, GNUNET_log (GNUNET_ERROR_TYPE_INFO,

View File

@ -184,7 +184,14 @@ batch_withdraw_transaction (void *cls,
wc->reserve_pub, wc->reserve_pub,
&wc->h_payto); &wc->h_payto);
if (qs < 0) if (qs < 0)
{
if (GNUNET_DB_STATUS_HARD_ERROR == qs)
*mhd_ret = TALER_MHD_reply_with_error (connection,
MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_GENERIC_DB_FETCH_FAILED,
"reserves_get_origin");
return qs; return qs;
}
if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs) if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
{ {
*mhd_ret = TALER_MHD_reply_with_error (connection, *mhd_ret = TALER_MHD_reply_with_error (connection,
@ -193,13 +200,24 @@ batch_withdraw_transaction (void *cls,
NULL); NULL);
return GNUNET_DB_STATUS_HARD_ERROR; return GNUNET_DB_STATUS_HARD_ERROR;
} }
kyc_required = TALER_KYCLOGIC_kyc_test_required ( qs = TALER_KYCLOGIC_kyc_test_required (
TALER_KYCLOGIC_KYC_TRIGGER_WITHDRAW, TALER_KYCLOGIC_KYC_TRIGGER_WITHDRAW,
&wc->h_payto, &wc->h_payto,
TEH_plugin->select_satisfied_kyc_processes, TEH_plugin->select_satisfied_kyc_processes,
TEH_plugin->cls, TEH_plugin->cls,
&batch_withdraw_amount_cb, &batch_withdraw_amount_cb,
wc); wc,
&kyc_required);
if (qs < 0)
{
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
if (GNUNET_DB_STATUS_HARD_ERROR == qs)
*mhd_ret = TALER_MHD_reply_with_error (connection,
MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_GENERIC_DB_FETCH_FAILED,
"kyc_test_required");
return qs;
}
if (NULL != kyc_required) if (NULL != kyc_required)
{ {
/* insert KYC requirement into DB! */ /* insert KYC requirement into DB! */
@ -221,10 +239,13 @@ batch_withdraw_transaction (void *cls,
if (0 > qs) if (0 > qs)
{ {
if (GNUNET_DB_STATUS_HARD_ERROR == qs) if (GNUNET_DB_STATUS_HARD_ERROR == qs)
{
GNUNET_break (0);
*mhd_ret = TALER_MHD_reply_with_error (connection, *mhd_ret = TALER_MHD_reply_with_error (connection,
MHD_HTTP_INTERNAL_SERVER_ERROR, MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_GENERIC_DB_FETCH_FAILED, TALER_EC_GENERIC_DB_FETCH_FAILED,
"update_reserve_batch_withdraw"); "update_reserve_batch_withdraw");
}
return qs; return qs;
} }
if (! found) if (! found)

View File

@ -109,22 +109,34 @@ wallet_kyc_check (void *cls,
struct KycRequestContext *krc = cls; struct KycRequestContext *krc = cls;
enum GNUNET_DB_QueryStatus qs; enum GNUNET_DB_QueryStatus qs;
krc->required = TALER_KYCLOGIC_kyc_test_required ( qs = TALER_KYCLOGIC_kyc_test_required (
TALER_KYCLOGIC_KYC_TRIGGER_WALLET_BALANCE, TALER_KYCLOGIC_KYC_TRIGGER_WALLET_BALANCE,
&krc->h_payto, &krc->h_payto,
TEH_plugin->select_satisfied_kyc_processes, TEH_plugin->select_satisfied_kyc_processes,
TEH_plugin->cls, TEH_plugin->cls,
&balance_iterator, &balance_iterator,
krc); krc,
GNUNET_log (GNUNET_ERROR_TYPE_INFO, &krc->required);
"KYC check required at %s is `%s'\n", if (qs < 0)
TALER_amount2s (&krc->balance), {
krc->required); if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
return qs;
GNUNET_break (0);
*mhd_ret = TALER_MHD_reply_with_error (connection,
MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_GENERIC_DB_FETCH_FAILED,
"kyc_test_required");
return qs;
}
if (NULL == krc->required) if (NULL == krc->required)
{ {
krc->kyc.ok = true; krc->kyc.ok = true;
return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS; return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS;
} }
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"KYC check required at %s is `%s'\n",
TALER_amount2s (&krc->balance),
krc->required);
krc->kyc.ok = false; krc->kyc.ok = false;
qs = TEH_plugin->insert_kyc_requirement_for_account (TEH_plugin->cls, qs = TEH_plugin->insert_kyc_requirement_for_account (TEH_plugin->cls,
krc->required, krc->required,

View File

@ -282,13 +282,26 @@ merge_transaction (void *cls,
bool no_partner = true; bool no_partner = true;
const char *required; const char *required;
required = TALER_KYCLOGIC_kyc_test_required ( qs = TALER_KYCLOGIC_kyc_test_required (
TALER_KYCLOGIC_KYC_TRIGGER_P2P_RECEIVE, TALER_KYCLOGIC_KYC_TRIGGER_P2P_RECEIVE,
&pcc->h_payto, &pcc->h_payto,
TEH_plugin->select_satisfied_kyc_processes, TEH_plugin->select_satisfied_kyc_processes,
TEH_plugin->cls, TEH_plugin->cls,
&amount_iterator, &amount_iterator,
pcc); pcc,
&required);
if (qs < 0)
{
if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
return qs;
GNUNET_break (0);
*mhd_ret =
TALER_MHD_reply_with_error (connection,
MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_GENERIC_DB_FETCH_FAILED,
"kyc_test_required");
return qs;
}
if (NULL != required) if (NULL != required)
{ {
pcc->kyc.ok = false; pcc->kyc.ok = false;
@ -314,8 +327,7 @@ merge_transaction (void *cls,
{ {
if (GNUNET_DB_STATUS_SOFT_ERROR == qs) if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
return qs; return qs;
TALER_LOG_WARNING ( GNUNET_break (0);
"Failed to store merge purse information in database\n");
*mhd_ret = *mhd_ret =
TALER_MHD_reply_with_error (connection, TALER_MHD_reply_with_error (connection,
MHD_HTTP_INTERNAL_SERVER_ERROR, MHD_HTTP_INTERNAL_SERVER_ERROR,

View File

@ -231,14 +231,26 @@ reserve_close_transaction (void *cls,
TALER_payto_hash (rcc->payto_uri, TALER_payto_hash (rcc->payto_uri,
&rcc->kyc_payto); &rcc->kyc_payto);
rcc->qs = GNUNET_DB_STATUS_SUCCESS_NO_RESULTS; rcc->qs = GNUNET_DB_STATUS_SUCCESS_NO_RESULTS;
kyc_needed qs = TALER_KYCLOGIC_kyc_test_required (
= TALER_KYCLOGIC_kyc_test_required (
TALER_KYCLOGIC_KYC_TRIGGER_RESERVE_CLOSE, TALER_KYCLOGIC_KYC_TRIGGER_RESERVE_CLOSE,
&rcc->kyc_payto, &rcc->kyc_payto,
TEH_plugin->select_satisfied_kyc_processes, TEH_plugin->select_satisfied_kyc_processes,
TEH_plugin->cls, TEH_plugin->cls,
&amount_it, &amount_it,
rcc); rcc,
&kyc_needed);
if (qs < 0)
{
if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
return qs;
GNUNET_break (0);
*mhd_ret
= TALER_MHD_reply_with_error (connection,
MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_GENERIC_DB_FETCH_FAILED,
"iterate_reserve_close_info");
return qs;
}
if (rcc->qs < 0) if (rcc->qs < 0)
{ {
if (GNUNET_DB_STATUS_SOFT_ERROR == rcc->qs) if (GNUNET_DB_STATUS_SOFT_ERROR == rcc->qs)

View File

@ -192,13 +192,26 @@ purse_transaction (void *cls,
const char *required; const char *required;
required = TALER_KYCLOGIC_kyc_test_required ( qs = TALER_KYCLOGIC_kyc_test_required (
TALER_KYCLOGIC_KYC_TRIGGER_P2P_RECEIVE, TALER_KYCLOGIC_KYC_TRIGGER_P2P_RECEIVE,
&rpc->h_payto, &rpc->h_payto,
TEH_plugin->select_satisfied_kyc_processes, TEH_plugin->select_satisfied_kyc_processes,
TEH_plugin->cls, TEH_plugin->cls,
&amount_iterator, &amount_iterator,
rpc); rpc,
&required);
if (qs < 0)
{
if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
return qs;
GNUNET_break (0);
*mhd_ret =
TALER_MHD_reply_with_error (connection,
MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_GENERIC_DB_FETCH_FAILED,
"kyc_test_required");
return GNUNET_DB_STATUS_HARD_ERROR;
}
if (NULL != required) if (NULL != required)
{ {
rpc->kyc.ok = false; rpc->kyc.ok = false;
@ -230,8 +243,7 @@ purse_transaction (void *cls,
{ {
if (GNUNET_DB_STATUS_SOFT_ERROR == qs) if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
return qs; return qs;
TALER_LOG_WARNING ( GNUNET_break (0);
"Failed to store purse purse information in database\n");
*mhd_ret = *mhd_ret =
TALER_MHD_reply_with_error (connection, TALER_MHD_reply_with_error (connection,
MHD_HTTP_INTERNAL_SERVER_ERROR, MHD_HTTP_INTERNAL_SERVER_ERROR,

View File

@ -164,13 +164,26 @@ withdraw_transaction (void *cls,
{ {
const char *kyc_required; const char *kyc_required;
kyc_required = TALER_KYCLOGIC_kyc_test_required ( qs = TALER_KYCLOGIC_kyc_test_required (
TALER_KYCLOGIC_KYC_TRIGGER_WITHDRAW, TALER_KYCLOGIC_KYC_TRIGGER_WITHDRAW,
&wc->h_payto, &wc->h_payto,
TEH_plugin->select_satisfied_kyc_processes, TEH_plugin->select_satisfied_kyc_processes,
TEH_plugin->cls, TEH_plugin->cls,
&withdraw_amount_cb, &withdraw_amount_cb,
wc); wc,
&kyc_required);
if (qs < 0)
{
if (GNUNET_DB_STATUS_HARD_ERROR == qs)
{
GNUNET_break (0);
*mhd_ret = TALER_MHD_reply_with_error (connection,
MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_GENERIC_DB_FETCH_FAILED,
"kyc_test_required");
}
return qs;
}
if (NULL != kyc_required) if (NULL != kyc_required)
{ {
/* insert KYC requirement into DB! */ /* insert KYC requirement into DB! */
@ -198,10 +211,13 @@ withdraw_transaction (void *cls,
if (0 > qs) if (0 > qs)
{ {
if (GNUNET_DB_STATUS_HARD_ERROR == qs) if (GNUNET_DB_STATUS_HARD_ERROR == qs)
{
GNUNET_break (0);
*mhd_ret = TALER_MHD_reply_with_error (connection, *mhd_ret = TALER_MHD_reply_with_error (connection,
MHD_HTTP_INTERNAL_SERVER_ERROR, MHD_HTTP_INTERNAL_SERVER_ERROR,
TALER_EC_GENERIC_DB_FETCH_FAILED, TALER_EC_GENERIC_DB_FETCH_FAILED,
"do_withdraw"); "do_withdraw");
}
return qs; return qs;
} }
if (! found) if (! found)

View File

@ -214,16 +214,18 @@ typedef enum GNUNET_DB_QueryStatus
* amounts involved in this type of operation * amounts involved in this type of operation
* at the given account * at the given account
* @param ai_cls closure for @a ai * @param ai_cls closure for @a ai
* @return NULL if no check is needed, * @param[out] set to NULL if no check is needed,
* otherwise space-separated list of required checks * otherwise space-separated list of required checks
* @return transaction status
*/ */
const char * enum GNUNET_DB_QueryStatus
TALER_KYCLOGIC_kyc_test_required (enum TALER_KYCLOGIC_KycTriggerEvent event, TALER_KYCLOGIC_kyc_test_required (enum TALER_KYCLOGIC_KycTriggerEvent event,
const struct TALER_PaytoHashP *h_payto, const struct TALER_PaytoHashP *h_payto,
TALER_KYCLOGIC_KycSatisfiedIterator ki, TALER_KYCLOGIC_KycSatisfiedIterator ki,
void *ki_cls, void *ki_cls,
TALER_KYCLOGIC_KycAmountIterator ai, TALER_KYCLOGIC_KycAmountIterator ai,
void *ai_cls); void *ai_cls,
const char **required);
/** /**

View File

@ -996,13 +996,14 @@ remove_satisfied (void *cls,
} }
const char * enum GNUNET_DB_QueryStatus
TALER_KYCLOGIC_kyc_test_required (enum TALER_KYCLOGIC_KycTriggerEvent event, TALER_KYCLOGIC_kyc_test_required (enum TALER_KYCLOGIC_KycTriggerEvent event,
const struct TALER_PaytoHashP *h_payto, const struct TALER_PaytoHashP *h_payto,
TALER_KYCLOGIC_KycSatisfiedIterator ki, TALER_KYCLOGIC_KycSatisfiedIterator ki,
void *ki_cls, void *ki_cls,
TALER_KYCLOGIC_KycAmountIterator ai, TALER_KYCLOGIC_KycAmountIterator ai,
void *ai_cls) void *ai_cls,
const char **required)
{ {
struct TALER_KYCLOGIC_KycCheck *needed[num_kyc_checks]; struct TALER_KYCLOGIC_KycCheck *needed[num_kyc_checks];
unsigned int needed_cnt = 0; unsigned int needed_cnt = 0;
@ -1035,7 +1036,10 @@ TALER_KYCLOGIC_kyc_test_required (enum TALER_KYCLOGIC_KycTriggerEvent event,
&ttc); &ttc);
} }
if (0 == needed_cnt) if (0 == needed_cnt)
return NULL; {
*required = NULL;
return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS;
}
timeframe = GNUNET_TIME_UNIT_ZERO; timeframe = GNUNET_TIME_UNIT_ZERO;
for (unsigned int i = 0; i<num_kyc_triggers; i++) for (unsigned int i = 0; i<num_kyc_triggers; i++)
{ {
@ -1062,7 +1066,10 @@ TALER_KYCLOGIC_kyc_test_required (enum TALER_KYCLOGIC_KycTriggerEvent event,
&ttc); &ttc);
} }
if (0 == needed_cnt) if (0 == needed_cnt)
return NULL; {
*required = NULL;
return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS;
}
{ {
struct RemoveContext rc = { struct RemoveContext rc = {
.needed = needed, .needed = needed,
@ -1076,10 +1083,17 @@ TALER_KYCLOGIC_kyc_test_required (enum TALER_KYCLOGIC_KycTriggerEvent event,
h_payto, h_payto,
&remove_satisfied, &remove_satisfied,
&rc); &rc);
GNUNET_break (qs >= 0); // FIXME: handle DB failure more nicely? if (qs < 0)
{
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
return qs;
}
} }
if (0 == needed_cnt) if (0 == needed_cnt)
return NULL; {
*required = NULL;
return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS;
}
{ {
struct RemoveContext rc = { struct RemoveContext rc = {
.needed = needed, .needed = needed,
@ -1093,10 +1107,17 @@ TALER_KYCLOGIC_kyc_test_required (enum TALER_KYCLOGIC_KycTriggerEvent event,
h_payto, h_payto,
&remove_satisfied, &remove_satisfied,
&rc); &rc);
GNUNET_break (qs >= 0); // FIXME: handle DB failure more nicely? if (qs < 0)
{
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
return qs;
}
} }
if (0 == needed_cnt) if (0 == needed_cnt)
return NULL; {
*required = NULL;
return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS;
}
ret = NULL; ret = NULL;
for (unsigned int k = 0; k<needed_cnt; k++) for (unsigned int k = 0; k<needed_cnt; k++)
{ {
@ -1117,7 +1138,8 @@ TALER_KYCLOGIC_kyc_test_required (enum TALER_KYCLOGIC_KycTriggerEvent event,
GNUNET_free (tmp); GNUNET_free (tmp);
} }
} }
return ret; *required = ret;
return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
} }