more towards actually allowing AML decisions to trigger KYC
This commit is contained in:
parent
86e0f2c70d
commit
aa5e7d2ad5
@ -103,6 +103,85 @@ make_aml_decision (void *cls,
|
|||||||
enum GNUNET_DB_QueryStatus qs;
|
enum GNUNET_DB_QueryStatus qs;
|
||||||
struct GNUNET_TIME_Timestamp last_date;
|
struct GNUNET_TIME_Timestamp last_date;
|
||||||
bool invalid_officer;
|
bool invalid_officer;
|
||||||
|
uint64_t requirement_row = 0;
|
||||||
|
|
||||||
|
if ( (NULL != dc->kyc_requirements) &&
|
||||||
|
(0 != json_array_size (dc->kyc_requirements)) )
|
||||||
|
{
|
||||||
|
char *res = NULL;
|
||||||
|
size_t idx;
|
||||||
|
json_t *req;
|
||||||
|
bool satisfied;
|
||||||
|
|
||||||
|
json_array_foreach (dc->kyc_requirements, idx, req)
|
||||||
|
{
|
||||||
|
const char *r = json_string_value (req);
|
||||||
|
|
||||||
|
if (NULL == res)
|
||||||
|
{
|
||||||
|
res = GNUNET_strdup (r);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char *tmp;
|
||||||
|
|
||||||
|
GNUNET_asprintf (&tmp,
|
||||||
|
"%s %s",
|
||||||
|
res,
|
||||||
|
r);
|
||||||
|
GNUNET_free (res);
|
||||||
|
res = tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
json_t *kyc_details = NULL;
|
||||||
|
|
||||||
|
qs = TALER_KYCLOGIC_check_satisfied (
|
||||||
|
&res,
|
||||||
|
&dc->h_payto,
|
||||||
|
&kyc_details,
|
||||||
|
TEH_plugin->select_satisfied_kyc_processes,
|
||||||
|
TEH_plugin->cls,
|
||||||
|
&satisfied);
|
||||||
|
json_decref (kyc_details);
|
||||||
|
}
|
||||||
|
if (qs < 0)
|
||||||
|
{
|
||||||
|
if (GNUNET_DB_STATUS_SOFT_ERROR != qs)
|
||||||
|
{
|
||||||
|
GNUNET_break (0);
|
||||||
|
*mhd_ret = TALER_MHD_reply_with_error (connection,
|
||||||
|
MHD_HTTP_INTERNAL_SERVER_ERROR,
|
||||||
|
TALER_EC_GENERIC_DB_FETCH_FAILED,
|
||||||
|
"select_satisfied_kyc_processes");
|
||||||
|
return GNUNET_DB_STATUS_HARD_ERROR;
|
||||||
|
}
|
||||||
|
return qs;
|
||||||
|
}
|
||||||
|
if (! satisfied)
|
||||||
|
{
|
||||||
|
qs = TEH_plugin->insert_kyc_requirement_for_account (
|
||||||
|
TEH_plugin->cls,
|
||||||
|
res,
|
||||||
|
&dc->h_payto,
|
||||||
|
&requirement_row);
|
||||||
|
if (qs < 0)
|
||||||
|
{
|
||||||
|
if (GNUNET_DB_STATUS_SOFT_ERROR != qs)
|
||||||
|
{
|
||||||
|
GNUNET_break (0);
|
||||||
|
*mhd_ret = TALER_MHD_reply_with_error (connection,
|
||||||
|
MHD_HTTP_INTERNAL_SERVER_ERROR,
|
||||||
|
TALER_EC_GENERIC_DB_STORE_FAILED,
|
||||||
|
"insert_kyc_requirement_for_account");
|
||||||
|
return GNUNET_DB_STATUS_HARD_ERROR;
|
||||||
|
}
|
||||||
|
return qs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
GNUNET_free (res);
|
||||||
|
}
|
||||||
|
|
||||||
qs = TEH_plugin->insert_aml_decision (TEH_plugin->cls,
|
qs = TEH_plugin->insert_aml_decision (TEH_plugin->cls,
|
||||||
&dc->h_payto,
|
&dc->h_payto,
|
||||||
@ -111,6 +190,7 @@ make_aml_decision (void *cls,
|
|||||||
dc->decision_time,
|
dc->decision_time,
|
||||||
dc->justification,
|
dc->justification,
|
||||||
dc->kyc_requirements,
|
dc->kyc_requirements,
|
||||||
|
requirement_row,
|
||||||
dc->officer_pub,
|
dc->officer_pub,
|
||||||
&dc->officer_sig,
|
&dc->officer_sig,
|
||||||
&invalid_officer,
|
&invalid_officer,
|
||||||
@ -151,11 +231,6 @@ make_aml_decision (void *cls,
|
|||||||
return GNUNET_DB_STATUS_HARD_ERROR;
|
return GNUNET_DB_STATUS_HARD_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NULL != dc->kyc_requirements)
|
|
||||||
{
|
|
||||||
// FIXME: act on these!
|
|
||||||
}
|
|
||||||
|
|
||||||
return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
|
return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -210,7 +210,7 @@ batch_withdraw_transaction (void *cls,
|
|||||||
enum GNUNET_DB_QueryStatus qs;
|
enum GNUNET_DB_QueryStatus qs;
|
||||||
bool balance_ok = false;
|
bool balance_ok = false;
|
||||||
bool found = false;
|
bool found = false;
|
||||||
const char *kyc_required;
|
char *kyc_required;
|
||||||
struct TALER_PaytoHashP reserve_h_payto;
|
struct TALER_PaytoHashP reserve_h_payto;
|
||||||
|
|
||||||
wc->now = GNUNET_TIME_timestamp_get ();
|
wc->now = GNUNET_TIME_timestamp_get ();
|
||||||
@ -349,11 +349,22 @@ batch_withdraw_transaction (void *cls,
|
|||||||
{
|
{
|
||||||
/* insert KYC requirement into DB! */
|
/* insert KYC requirement into DB! */
|
||||||
wc->kyc.ok = false;
|
wc->kyc.ok = false;
|
||||||
return TEH_plugin->insert_kyc_requirement_for_account (
|
qs = TEH_plugin->insert_kyc_requirement_for_account (
|
||||||
TEH_plugin->cls,
|
TEH_plugin->cls,
|
||||||
kyc_required,
|
kyc_required,
|
||||||
&wc->h_payto,
|
&wc->h_payto,
|
||||||
&wc->kyc.requirement_row);
|
&wc->kyc.requirement_row);
|
||||||
|
GNUNET_free (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_STORE_FAILED,
|
||||||
|
"insert_kyc_requirement_for_account");
|
||||||
|
}
|
||||||
|
return qs;
|
||||||
}
|
}
|
||||||
wc->kyc.ok = true;
|
wc->kyc.ok = true;
|
||||||
qs = TEH_plugin->do_batch_withdraw (TEH_plugin->cls,
|
qs = TEH_plugin->do_batch_withdraw (TEH_plugin->cls,
|
||||||
|
@ -332,7 +332,7 @@ kyc_check (void *cls,
|
|||||||
return GNUNET_DB_STATUS_HARD_ERROR;
|
return GNUNET_DB_STATUS_HARD_ERROR;
|
||||||
}
|
}
|
||||||
qs = TALER_KYCLOGIC_check_satisfied (
|
qs = TALER_KYCLOGIC_check_satisfied (
|
||||||
requirements,
|
&requirements,
|
||||||
&h_payto,
|
&h_payto,
|
||||||
&kyp->kyc_details,
|
&kyp->kyc_details,
|
||||||
TEH_plugin->select_satisfied_kyc_processes,
|
TEH_plugin->select_satisfied_kyc_processes,
|
||||||
@ -389,6 +389,17 @@ kyc_check (void *cls,
|
|||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
&kyp->process_row);
|
&kyp->process_row);
|
||||||
|
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_STORE_FAILED,
|
||||||
|
"insert_kyc_requirement_process");
|
||||||
|
return GNUNET_DB_STATUS_HARD_ERROR;
|
||||||
|
}
|
||||||
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||||
"Initiating KYC check with logic %s\n",
|
"Initiating KYC check with logic %s\n",
|
||||||
kyp->ih_logic->name);
|
kyp->ih_logic->name);
|
||||||
|
@ -237,7 +237,7 @@ TEH_handler_kyc_wallet (
|
|||||||
NULL,
|
NULL,
|
||||||
0);
|
0);
|
||||||
}
|
}
|
||||||
GNUNET_free (kyc.required);
|
GNUNET_free (krc.required);
|
||||||
return TEH_RESPONSE_reply_kyc_required (rc->connection,
|
return TEH_RESPONSE_reply_kyc_required (rc->connection,
|
||||||
&krc.h_payto,
|
&krc.h_payto,
|
||||||
&krc.kyc);
|
&krc.kyc);
|
||||||
|
@ -33,6 +33,7 @@ BEGIN
|
|||||||
',decision_time INT8 NOT NULL DEFAULT(0)'
|
',decision_time INT8 NOT NULL DEFAULT(0)'
|
||||||
',justification VARCHAR NOT NULL'
|
',justification VARCHAR NOT NULL'
|
||||||
',kyc_requirements VARCHAR'
|
',kyc_requirements VARCHAR'
|
||||||
|
',kyc_req_row INT8 NOT NULL DEFAULT(0)'
|
||||||
',decider_pub BYTEA CHECK (LENGTH(decider_pub)=32)'
|
',decider_pub BYTEA CHECK (LENGTH(decider_pub)=32)'
|
||||||
',decider_sig BYTEA CHECK (LENGTH(decider_sig)=64)'
|
',decider_sig BYTEA CHECK (LENGTH(decider_sig)=64)'
|
||||||
') %s ;'
|
') %s ;'
|
||||||
@ -87,6 +88,12 @@ BEGIN
|
|||||||
,table_name
|
,table_name
|
||||||
,partition_suffix
|
,partition_suffix
|
||||||
);
|
);
|
||||||
|
PERFORM comment_partitioned_column(
|
||||||
|
'Row in the KYC table for this KYC requirement, 0 for none.'
|
||||||
|
,'kyc_req_row'
|
||||||
|
,table_name
|
||||||
|
,partition_suffix
|
||||||
|
);
|
||||||
PERFORM comment_partitioned_column(
|
PERFORM comment_partitioned_column(
|
||||||
'Signature key of the staff member affirming the AML decision; of type AML_DECISION'
|
'Signature key of the staff member affirming the AML decision; of type AML_DECISION'
|
||||||
,'decider_sig'
|
,'decider_sig'
|
||||||
|
@ -25,6 +25,7 @@ CREATE OR REPLACE FUNCTION exchange_do_insert_aml_decision(
|
|||||||
IN in_decider_sig BYTEA,
|
IN in_decider_sig BYTEA,
|
||||||
IN in_notify_s VARCHAR,
|
IN in_notify_s VARCHAR,
|
||||||
IN in_kyc_requirements VARCHAR,
|
IN in_kyc_requirements VARCHAR,
|
||||||
|
IN in_requirement_row INT8,
|
||||||
OUT out_invalid_officer BOOLEAN,
|
OUT out_invalid_officer BOOLEAN,
|
||||||
OUT out_last_date INT8)
|
OUT out_last_date INT8)
|
||||||
LANGUAGE plpgsql
|
LANGUAGE plpgsql
|
||||||
@ -86,6 +87,7 @@ INSERT INTO exchange.aml_history
|
|||||||
,decision_time
|
,decision_time
|
||||||
,justification
|
,justification
|
||||||
,kyc_requirements
|
,kyc_requirements
|
||||||
|
,kyc_req_row
|
||||||
,decider_pub
|
,decider_pub
|
||||||
,decider_sig
|
,decider_sig
|
||||||
) VALUES
|
) VALUES
|
||||||
@ -96,6 +98,7 @@ INSERT INTO exchange.aml_history
|
|||||||
,in_decision_time
|
,in_decision_time
|
||||||
,in_justification
|
,in_justification
|
||||||
,in_kyc_requirements
|
,in_kyc_requirements
|
||||||
|
,in_requirement_row
|
||||||
,in_decider_pub
|
,in_decider_pub
|
||||||
,in_decider_sig);
|
,in_decider_sig);
|
||||||
|
|
||||||
@ -119,5 +122,5 @@ END IF;
|
|||||||
END $$;
|
END $$;
|
||||||
|
|
||||||
|
|
||||||
COMMENT ON FUNCTION exchange_do_insert_aml_decision(BYTEA, INT8, INT4, INT4, INT8, VARCHAR, BYTEA, BYTEA, VARCHAR, VARCHAR)
|
COMMENT ON FUNCTION exchange_do_insert_aml_decision(BYTEA, INT8, INT4, INT4, INT8, VARCHAR, BYTEA, BYTEA, VARCHAR, VARCHAR, INT8)
|
||||||
IS 'Checks whether the AML officer is eligible to make AML decisions and if so inserts the decision into the table';
|
IS 'Checks whether the AML officer is eligible to make AML decisions and if so inserts the decision into the table';
|
||||||
|
@ -36,6 +36,7 @@ TEH_PG_insert_aml_decision (
|
|||||||
struct GNUNET_TIME_Timestamp decision_time,
|
struct GNUNET_TIME_Timestamp decision_time,
|
||||||
const char *justification,
|
const char *justification,
|
||||||
const json_t *kyc_requirements,
|
const json_t *kyc_requirements,
|
||||||
|
uint64_t requirements_row,
|
||||||
const struct TALER_AmlOfficerPublicKeyP *decider_pub,
|
const struct TALER_AmlOfficerPublicKeyP *decider_pub,
|
||||||
const struct TALER_AmlOfficerSignatureP *decider_sig,
|
const struct TALER_AmlOfficerSignatureP *decider_sig,
|
||||||
bool *invalid_officer,
|
bool *invalid_officer,
|
||||||
@ -64,6 +65,7 @@ TEH_PG_insert_aml_decision (
|
|||||||
NULL != kyc_requirements
|
NULL != kyc_requirements
|
||||||
? GNUNET_PQ_query_param_string (kyc_s)
|
? GNUNET_PQ_query_param_string (kyc_s)
|
||||||
: GNUNET_PQ_query_param_null (),
|
: GNUNET_PQ_query_param_null (),
|
||||||
|
GNUNET_PQ_query_param_uint64 (&requirements_row),
|
||||||
GNUNET_PQ_query_param_end
|
GNUNET_PQ_query_param_end
|
||||||
};
|
};
|
||||||
struct GNUNET_PQ_ResultSpec rs[] = {
|
struct GNUNET_PQ_ResultSpec rs[] = {
|
||||||
@ -81,7 +83,7 @@ TEH_PG_insert_aml_decision (
|
|||||||
" out_invalid_officer"
|
" out_invalid_officer"
|
||||||
",out_last_date"
|
",out_last_date"
|
||||||
" FROM exchange_do_insert_aml_decision"
|
" FROM exchange_do_insert_aml_decision"
|
||||||
"($1, $2, $3, $4, $5, $6, $7, $8, $9, $10);");
|
"($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11);");
|
||||||
qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
|
qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
|
||||||
"do_insert_aml_decision",
|
"do_insert_aml_decision",
|
||||||
params,
|
params,
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
* @param decision_time when was the decision made
|
* @param decision_time when was the decision made
|
||||||
* @param justification human-readable text justifying the decision
|
* @param justification human-readable text justifying the decision
|
||||||
* @param kyc_requirements JSON array with KYC requirements
|
* @param kyc_requirements JSON array with KYC requirements
|
||||||
|
* @param requirements_row row in the KYC table for this process, 0 for none
|
||||||
* @param decider_pub public key of the staff member
|
* @param decider_pub public key of the staff member
|
||||||
* @param decider_sig signature of the staff member
|
* @param decider_sig signature of the staff member
|
||||||
* @param[out] invalid_officer set to TRUE if @a decider_pub is not allowed to make decisions right now
|
* @param[out] invalid_officer set to TRUE if @a decider_pub is not allowed to make decisions right now
|
||||||
@ -53,6 +54,7 @@ TEH_PG_insert_aml_decision (
|
|||||||
struct GNUNET_TIME_Timestamp decision_time,
|
struct GNUNET_TIME_Timestamp decision_time,
|
||||||
const char *justification,
|
const char *justification,
|
||||||
const json_t *kyc_requirements,
|
const json_t *kyc_requirements,
|
||||||
|
uint64_t requirements_row,
|
||||||
const struct TALER_AmlOfficerPublicKeyP *decider_pub,
|
const struct TALER_AmlOfficerPublicKeyP *decider_pub,
|
||||||
const struct TALER_AmlOfficerSignatureP *decider_sig,
|
const struct TALER_AmlOfficerSignatureP *decider_sig,
|
||||||
bool *invalid_officer,
|
bool *invalid_officer,
|
||||||
|
@ -6689,6 +6689,8 @@ struct TALER_EXCHANGEDB_Plugin
|
|||||||
* @param new_status AML decision status
|
* @param new_status AML decision status
|
||||||
* @param decision_time when was the decision made
|
* @param decision_time when was the decision made
|
||||||
* @param justification human-readable text justifying the decision
|
* @param justification human-readable text justifying the decision
|
||||||
|
* @param kyc_requirements specific KYC requiremnts being imposed
|
||||||
|
* @param requirements_row row in the KYC table for this process, 0 for none
|
||||||
* @param decider_pub public key of the staff member
|
* @param decider_pub public key of the staff member
|
||||||
* @param decider_sig signature of the staff member
|
* @param decider_sig signature of the staff member
|
||||||
* @param[out] invalid_officer set to TRUE if @a decider_pub is not allowed to make decisions right now
|
* @param[out] invalid_officer set to TRUE if @a decider_pub is not allowed to make decisions right now
|
||||||
@ -6705,6 +6707,7 @@ struct TALER_EXCHANGEDB_Plugin
|
|||||||
struct GNUNET_TIME_Timestamp decision_time,
|
struct GNUNET_TIME_Timestamp decision_time,
|
||||||
const char *justification,
|
const char *justification,
|
||||||
const json_t *kyc_requirements,
|
const json_t *kyc_requirements,
|
||||||
|
uint64_t requirements_row,
|
||||||
const struct TALER_AmlOfficerPublicKeyP *decider_pub,
|
const struct TALER_AmlOfficerPublicKeyP *decider_pub,
|
||||||
const struct TALER_AmlOfficerSignatureP *decider_sig,
|
const struct TALER_AmlOfficerSignatureP *decider_sig,
|
||||||
bool *invalid_officer,
|
bool *invalid_officer,
|
||||||
|
@ -232,7 +232,8 @@ TALER_KYCLOGIC_kyc_test_required (enum TALER_KYCLOGIC_KycTriggerEvent event,
|
|||||||
* Check if the @a requirements are now satsified for
|
* Check if the @a requirements are now satsified for
|
||||||
* @a h_payto account.
|
* @a h_payto account.
|
||||||
*
|
*
|
||||||
* @param requirements space-spearated list of requirements
|
* @param[in,out] requirements space-spearated list of requirements,
|
||||||
|
* already satisfied requirements are removed from the list
|
||||||
* @param h_payto hash over the account
|
* @param h_payto hash over the account
|
||||||
* @param[out] kyc_details if satisfied, set to what kind of
|
* @param[out] kyc_details if satisfied, set to what kind of
|
||||||
* KYC information was collected
|
* KYC information was collected
|
||||||
@ -242,7 +243,7 @@ TALER_KYCLOGIC_kyc_test_required (enum TALER_KYCLOGIC_KycTriggerEvent event,
|
|||||||
* @return transaction status (from @a ki)
|
* @return transaction status (from @a ki)
|
||||||
*/
|
*/
|
||||||
enum GNUNET_DB_QueryStatus
|
enum GNUNET_DB_QueryStatus
|
||||||
TALER_KYCLOGIC_check_satisfied (const char *requirements,
|
TALER_KYCLOGIC_check_satisfied (char **requirements,
|
||||||
const struct TALER_PaytoHashP *h_payto,
|
const struct TALER_PaytoHashP *h_payto,
|
||||||
json_t **kyc_details,
|
json_t **kyc_details,
|
||||||
TALER_KYCLOGIC_KycSatisfiedIterator ki,
|
TALER_KYCLOGIC_KycSatisfiedIterator ki,
|
||||||
|
@ -1228,7 +1228,7 @@ TALER_KYCLOGIC_kyc_get_details (
|
|||||||
|
|
||||||
|
|
||||||
enum GNUNET_DB_QueryStatus
|
enum GNUNET_DB_QueryStatus
|
||||||
TALER_KYCLOGIC_check_satisfied (const char *requirements,
|
TALER_KYCLOGIC_check_satisfied (char **requirements,
|
||||||
const struct TALER_PaytoHashP *h_payto,
|
const struct TALER_PaytoHashP *h_payto,
|
||||||
json_t **kyc_details,
|
json_t **kyc_details,
|
||||||
TALER_KYCLOGIC_KycSatisfiedIterator ki,
|
TALER_KYCLOGIC_KycSatisfiedIterator ki,
|
||||||
@ -1244,13 +1244,14 @@ TALER_KYCLOGIC_check_satisfied (const char *requirements,
|
|||||||
return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS;
|
return GNUNET_DB_STATUS_SUCCESS_NO_RESULTS;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
char *req = GNUNET_strdup (requirements);
|
char *req = *requirements;
|
||||||
|
|
||||||
for (const char *tok = strtok (req, " ");
|
for (const char *tok = strtok (req, " ");
|
||||||
NULL != tok;
|
NULL != tok;
|
||||||
tok = strtok (NULL, " "))
|
tok = strtok (NULL, " "))
|
||||||
needed[needed_cnt++] = add_check (tok);
|
needed[needed_cnt++] = add_check (tok);
|
||||||
GNUNET_free (req);
|
GNUNET_free (req);
|
||||||
|
*requirements = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -1286,6 +1287,32 @@ TALER_KYCLOGIC_check_satisfied (const char *requirements,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
*satisfied = (0 == needed_cnt);
|
*satisfied = (0 == needed_cnt);
|
||||||
|
|
||||||
|
{
|
||||||
|
char *res = NULL;
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i<needed_cnt; i++)
|
||||||
|
{
|
||||||
|
const struct TALER_KYCLOGIC_KycCheck *need = needed[i];
|
||||||
|
|
||||||
|
if (NULL == res)
|
||||||
|
{
|
||||||
|
res = GNUNET_strdup (need->name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char *tmp;
|
||||||
|
|
||||||
|
GNUNET_asprintf (&tmp,
|
||||||
|
"%s %s",
|
||||||
|
res,
|
||||||
|
need->name);
|
||||||
|
GNUNET_free (res);
|
||||||
|
res = tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*requirements = res;
|
||||||
|
}
|
||||||
return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
|
return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user