diff options
author | Christian Grothoff <christian@grothoff.org> | 2023-02-09 17:54:14 +0100 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2023-02-09 17:54:14 +0100 |
commit | 19132b67165d04bede03ba83e98359849e357536 (patch) | |
tree | 754cd0806eeb267f18b3807e3003caeac663f6c9 /src/exchange | |
parent | d0b43b0e6aeb10b54318265c5fcf64375c3fb764 (diff) |
-start on AML work (incomplete)
Diffstat (limited to 'src/exchange')
-rw-r--r-- | src/exchange/taler-exchange-aggregator.c | 99 | ||||
-rw-r--r-- | src/exchange/taler-exchange-httpd_batch-deposit.c | 24 |
2 files changed, 106 insertions, 17 deletions
diff --git a/src/exchange/taler-exchange-aggregator.c b/src/exchange/taler-exchange-aggregator.c index 823326d0..af3e111d 100644 --- a/src/exchange/taler-exchange-aggregator.c +++ b/src/exchange/taler-exchange-aggregator.c @@ -149,6 +149,12 @@ struct Shard static struct TALER_Amount currency_round_unit; /** + * What is the largest amount we transfer before triggering + * an AML check? + */ +static struct TALER_Amount aml_threshold; + +/** * What is the base URL of this exchange? Used in the * wire transfer subjects so that merchants and governments * can ask for the list of aggregated deposits. @@ -294,11 +300,20 @@ parse_aggregator_config (void) "taler", "CURRENCY_ROUND_UNIT", ¤cy_round_unit)) || - ( (0 != currency_round_unit.fraction) && - (0 != currency_round_unit.value) ) ) + (TALER_amount_is_zero (¤cy_round_unit)) ) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Need non-zero value in section `TALER' under `CURRENCY_ROUND_UNIT'\n"); + "Need non-zero amount in section `TALER' under `CURRENCY_ROUND_UNIT'\n"); + return GNUNET_SYSERR; + } + if (GNUNET_OK != + TALER_config_get_amount (cfg, + "taler", + "AML_THRESHOLD", + &aml_threshold)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Need amount in section `TALER' under `AML_THRESHOLD'\n"); return GNUNET_SYSERR; } @@ -525,6 +540,81 @@ kyc_satisfied (struct AggregationUnit *au_active) /** + * Function called on each @a amount that was found to + * be relevant for an AML check. + * + * @param cls closure with the `struct TALER_Amount *` where we store the sum + * @param amount encountered transaction amount + * @param date when was the amount encountered + * @return #GNUNET_OK to continue to iterate, + * #GNUNET_NO to abort iteration + * #GNUNET_SYSERR on internal error (also abort itaration) + */ +static enum GNUNET_GenericReturnValue +sum_for_aml ( + void *cls, + const struct TALER_Amount *amount, + struct GNUNET_TIME_Absolute date) +{ + struct TALER_Amount *sum = cls; + + (void) date; + if (0 > + TALER_amount_add (sum, + sum, + amount)) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + return GNUNET_OK; +} + + +/** + * Test if AML is required for a transfer to @a h_payto. + * + * @param[in,out] au_active aggregation unit to check for + * @return true if AML checks are satisfied + */ +static bool +aml_satisfied (struct AggregationUnit *au_active) +{ + enum GNUNET_DB_QueryStatus qs; + struct TALER_Amount total; + + total = au_active->final_amount; + qs = db_plugin->select_aggregation_amounts_for_kyc_check ( + db_plugin->cls, + &au_active->h_payto, + GNUNET_TIME_absolute_subtract (GNUNET_TIME_absolute_get (), + GNUNET_TIME_UNIT_MONTHS), + &sum_for_aml, + &total); + if (qs < 0) + { + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + return false; + } + if (0 >= TALER_amount_cmp (&total, + &aml_threshold)) + { + /* total <= aml_threshold, do nothing */ + return true; + } + qs = db_plugin->trigger_aml_process (db_plugin->cls, + &au_active->h_payto, + &total); + if (qs < 0) + { + GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs); + return false; + } + return false; +} + + +/** * Perform the main aggregation work for @a au. Expects to be in * a working transaction, which the caller must also ultimately commit * (or rollback) depending on our return value. @@ -649,7 +739,8 @@ do_aggregate (struct AggregationUnit *au) TALER_amount_round_down (&au->final_amount, ¤cy_round_unit)) || (TALER_amount_is_zero (&au->final_amount)) || - (! kyc_satisfied (au)) ) + (! kyc_satisfied (au)) || + (! aml_satisfied (au)) ) { GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Not ready for wire transfer (%d/%s)\n", diff --git a/src/exchange/taler-exchange-httpd_batch-deposit.c b/src/exchange/taler-exchange-httpd_batch-deposit.c index 0545c393..d000c454 100644 --- a/src/exchange/taler-exchange-httpd_batch-deposit.c +++ b/src/exchange/taler-exchange-httpd_batch-deposit.c @@ -233,9 +233,8 @@ again: MHD_HTTP_OK, GNUNET_JSON_pack_timestamp ("exchange_timestamp", bdc->exchange_timestamp), - GNUNET_JSON_pack_data_auto ( - "exchange_pub", - &pub), + GNUNET_JSON_pack_data_auto ("exchange_pub", + &pub), GNUNET_JSON_pack_array_steal ("exchange_sigs", arr)); } @@ -268,13 +267,12 @@ batch_deposit_transaction (void *cls, * insert or update the record. */ if (dc->has_policy) { - qs = TEH_plugin->persist_policy_details (TEH_plugin->cls, - &dc->policy_details, - &dc->policy_details_serial_id, - &dc->policy_details. - accumulated_total, - &dc->policy_details. - fulfillment_state); + qs = TEH_plugin->persist_policy_details ( + TEH_plugin->cls, + &dc->policy_details, + &dc->policy_details_serial_id, + &dc->policy_details.accumulated_total, + &dc->policy_details.fulfillment_state); if (qs < 0) return qs; } @@ -295,9 +293,9 @@ batch_deposit_transaction (void *cls, deposit, known_coin_id, &dc->h_payto, - (dc->has_policy) - ? &dc->policy_details_serial_id - : NULL, + dc->has_policy + ? &dc->policy_details_serial_id + : NULL, &dc->exchange_timestamp, &balance_ok, &in_conflict); |