finish taler-exchange-drain implementation
This commit is contained in:
parent
544fbd4fe9
commit
150917694a
@ -234,12 +234,12 @@ shutdown_task (void *cls)
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse the configuration for wirewatch.
|
* Parse the configuration for aggregator.
|
||||||
*
|
*
|
||||||
* @return #GNUNET_OK on success
|
* @return #GNUNET_OK on success
|
||||||
*/
|
*/
|
||||||
static enum GNUNET_GenericReturnValue
|
static enum GNUNET_GenericReturnValue
|
||||||
parse_wirewatch_config (void)
|
parse_aggregator_config (void)
|
||||||
{
|
{
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
GNUNET_CONFIGURATION_get_value_string (cfg,
|
GNUNET_CONFIGURATION_get_value_string (cfg,
|
||||||
@ -811,7 +811,7 @@ run (void *cls,
|
|||||||
(void) cfgfile;
|
(void) cfgfile;
|
||||||
|
|
||||||
cfg = c;
|
cfg = c;
|
||||||
if (GNUNET_OK != parse_wirewatch_config ())
|
if (GNUNET_OK != parse_aggregator_config ())
|
||||||
{
|
{
|
||||||
cfg = NULL;
|
cfg = NULL;
|
||||||
global_ret = EXIT_NOTCONFIGURED;
|
global_ret = EXIT_NOTCONFIGURED;
|
||||||
|
@ -39,11 +39,21 @@ static const struct GNUNET_CONFIGURATION_Handle *cfg;
|
|||||||
*/
|
*/
|
||||||
static struct TALER_EXCHANGEDB_Plugin *db_plugin;
|
static struct TALER_EXCHANGEDB_Plugin *db_plugin;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Our master public key.
|
||||||
|
*/
|
||||||
|
static struct TALER_MasterPublicKeyP master_pub;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Next task to run, if any.
|
* Next task to run, if any.
|
||||||
*/
|
*/
|
||||||
static struct GNUNET_SCHEDULER_Task *task;
|
static struct GNUNET_SCHEDULER_Task *task;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base URL of this exchange.
|
||||||
|
*/
|
||||||
|
static char *exchange_base_url;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Value to return from main(). 0 on success, non-zero on errors.
|
* Value to return from main(). 0 on success, non-zero on errors.
|
||||||
*/
|
*/
|
||||||
@ -82,6 +92,47 @@ shutdown_task (void *cls)
|
|||||||
static enum GNUNET_GenericReturnValue
|
static enum GNUNET_GenericReturnValue
|
||||||
parse_drain_config (void)
|
parse_drain_config (void)
|
||||||
{
|
{
|
||||||
|
if (GNUNET_OK !=
|
||||||
|
GNUNET_CONFIGURATION_get_value_string (cfg,
|
||||||
|
"exchange",
|
||||||
|
"BASE_URL",
|
||||||
|
&exchange_base_url))
|
||||||
|
{
|
||||||
|
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
|
||||||
|
"exchange",
|
||||||
|
"BASE_URL");
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
char *master_public_key_str;
|
||||||
|
|
||||||
|
if (GNUNET_OK !=
|
||||||
|
GNUNET_CONFIGURATION_get_value_string (cfg,
|
||||||
|
"exchange",
|
||||||
|
"MASTER_PUBLIC_KEY",
|
||||||
|
&master_public_key_str))
|
||||||
|
{
|
||||||
|
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
|
||||||
|
"exchange",
|
||||||
|
"MASTER_PUBLIC_KEY");
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
if (GNUNET_OK !=
|
||||||
|
GNUNET_CRYPTO_eddsa_public_key_from_string (master_public_key_str,
|
||||||
|
strlen (
|
||||||
|
master_public_key_str),
|
||||||
|
&master_pub.eddsa_pub))
|
||||||
|
{
|
||||||
|
GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
|
||||||
|
"exchange",
|
||||||
|
"MASTER_PUBLIC_KEY",
|
||||||
|
"invalid base32 encoding for a master public key");
|
||||||
|
GNUNET_free (master_public_key_str);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
GNUNET_free (master_public_key_str);
|
||||||
|
}
|
||||||
if (NULL ==
|
if (NULL ==
|
||||||
(db_plugin = TALER_EXCHANGEDB_plugin_load (cfg)))
|
(db_plugin = TALER_EXCHANGEDB_plugin_load (cfg)))
|
||||||
{
|
{
|
||||||
@ -134,6 +185,13 @@ static void
|
|||||||
run_drain (void *cls)
|
run_drain (void *cls)
|
||||||
{
|
{
|
||||||
enum GNUNET_DB_QueryStatus qs;
|
enum GNUNET_DB_QueryStatus qs;
|
||||||
|
uint64_t serial;
|
||||||
|
struct TALER_WireTransferIdentifierRawP wtid;
|
||||||
|
char *account_section;
|
||||||
|
char *payto_uri;
|
||||||
|
struct GNUNET_TIME_Timestamp request_timestamp;
|
||||||
|
struct TALER_Amount amount;
|
||||||
|
struct TALER_MasterSignatureP master_sig;
|
||||||
|
|
||||||
(void) cls;
|
(void) cls;
|
||||||
task = NULL;
|
task = NULL;
|
||||||
@ -147,11 +205,14 @@ run_drain (void *cls)
|
|||||||
GNUNET_SCHEDULER_shutdown ();
|
GNUNET_SCHEDULER_shutdown ();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#if 0
|
qs = db_plugin->profit_drains_get_pending (db_plugin->cls,
|
||||||
qs = db_plugin->profit_drains_get_pending (db_plugin->cls);
|
&serial,
|
||||||
#else
|
&wtid,
|
||||||
qs = -1;
|
&account_section,
|
||||||
#endif
|
&payto_uri,
|
||||||
|
&request_timestamp,
|
||||||
|
&amount,
|
||||||
|
&master_sig);
|
||||||
switch (qs)
|
switch (qs)
|
||||||
{
|
{
|
||||||
case GNUNET_DB_STATUS_HARD_ERROR:
|
case GNUNET_DB_STATUS_HARD_ERROR:
|
||||||
@ -161,7 +222,6 @@ run_drain (void *cls)
|
|||||||
GNUNET_SCHEDULER_shutdown ();
|
GNUNET_SCHEDULER_shutdown ();
|
||||||
return;
|
return;
|
||||||
case GNUNET_DB_STATUS_SOFT_ERROR:
|
case GNUNET_DB_STATUS_SOFT_ERROR:
|
||||||
/* try again */
|
|
||||||
db_plugin->rollback (db_plugin->cls);
|
db_plugin->rollback (db_plugin->cls);
|
||||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||||
"Serialization failure on simple SELECT!?\n");
|
"Serialization failure on simple SELECT!?\n");
|
||||||
@ -169,7 +229,7 @@ run_drain (void *cls)
|
|||||||
GNUNET_SCHEDULER_shutdown ();
|
GNUNET_SCHEDULER_shutdown ();
|
||||||
return;
|
return;
|
||||||
case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
|
case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
|
||||||
/* no more profit drains, go sleep a bit! */
|
/* no profit drains, finished */
|
||||||
db_plugin->rollback (db_plugin->cls);
|
db_plugin->rollback (db_plugin->cls);
|
||||||
GNUNET_assert (NULL == task);
|
GNUNET_assert (NULL == task);
|
||||||
GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
|
GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
|
||||||
@ -180,11 +240,107 @@ run_drain (void *cls)
|
|||||||
/* continued below */
|
/* continued below */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// FIXME: check signature (again!)
|
/* Check signature (again, this is a critical operation!) */
|
||||||
// FIMXE: display for human check
|
if (GNUNET_OK !=
|
||||||
// FIXME: insert into pre-wire
|
TALER_exchange_offline_profit_drain_verify (
|
||||||
// FIXME: mark as done
|
&wtid,
|
||||||
// FIXME: commit transaction + report success + exit
|
request_timestamp,
|
||||||
|
&amount,
|
||||||
|
account_section,
|
||||||
|
payto_uri,
|
||||||
|
&master_pub,
|
||||||
|
&master_sig))
|
||||||
|
{
|
||||||
|
GNUNET_break (0);
|
||||||
|
global_ret = EXIT_FAILURE;
|
||||||
|
db_plugin->rollback (db_plugin->cls);
|
||||||
|
GNUNET_assert (NULL == task);
|
||||||
|
GNUNET_SCHEDULER_shutdown ();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Display data for manual human check */
|
||||||
|
fprintf (stdout,
|
||||||
|
"Critical operation. MANUAL CHECK REQUIRED.\n");
|
||||||
|
fprintf (stdout,
|
||||||
|
"We will wire %s to `%s'\n based on instructions from %s.\n",
|
||||||
|
TALER_amount2s (&amount),
|
||||||
|
payto_uri,
|
||||||
|
GNUNET_TIME_timestamp2s (request_timestamp));
|
||||||
|
fprintf (stdout,
|
||||||
|
"Press ENTER to confirm, CTRL-D to abort.\n");
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
int key;
|
||||||
|
|
||||||
|
key = getchar ();
|
||||||
|
if (EOF == key)
|
||||||
|
{
|
||||||
|
fprintf (stdout,
|
||||||
|
"Transfer aborted.\n"
|
||||||
|
"Re-run 'taler-exchange-drain' to try it again.\n"
|
||||||
|
"Contact Taler Systems SA to cancel it for good.\n"
|
||||||
|
"Exiting.\n");
|
||||||
|
db_plugin->rollback (db_plugin->cls);
|
||||||
|
GNUNET_assert (NULL == task);
|
||||||
|
GNUNET_SCHEDULER_shutdown ();
|
||||||
|
global_ret = EXIT_FAILURE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ('\n' == key)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Note: account_section ignored for now, we
|
||||||
|
might want to use it here in the future... */
|
||||||
|
(void) account_section;
|
||||||
|
{
|
||||||
|
char *method;
|
||||||
|
void *buf;
|
||||||
|
size_t buf_size;
|
||||||
|
|
||||||
|
TALER_BANK_prepare_transfer (payto_uri,
|
||||||
|
&amount,
|
||||||
|
exchange_base_url,
|
||||||
|
&wtid,
|
||||||
|
&buf,
|
||||||
|
&buf_size);
|
||||||
|
method = TALER_payto_get_method (payto_uri);
|
||||||
|
qs = db_plugin->wire_prepare_data_insert (db_plugin->cls,
|
||||||
|
method,
|
||||||
|
buf,
|
||||||
|
buf_size);
|
||||||
|
GNUNET_free (method);
|
||||||
|
GNUNET_free (buf);
|
||||||
|
}
|
||||||
|
qs = db_plugin->profit_drains_set_finished (db_plugin->cls,
|
||||||
|
serial);
|
||||||
|
switch (qs)
|
||||||
|
{
|
||||||
|
case GNUNET_DB_STATUS_HARD_ERROR:
|
||||||
|
db_plugin->rollback (db_plugin->cls);
|
||||||
|
GNUNET_break (0);
|
||||||
|
global_ret = EXIT_FAILURE;
|
||||||
|
GNUNET_SCHEDULER_shutdown ();
|
||||||
|
return;
|
||||||
|
case GNUNET_DB_STATUS_SOFT_ERROR:
|
||||||
|
db_plugin->rollback (db_plugin->cls);
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||||
|
"Failed: database serialization issue\n");
|
||||||
|
global_ret = EXIT_FAILURE;
|
||||||
|
GNUNET_SCHEDULER_shutdown ();
|
||||||
|
return;
|
||||||
|
case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
|
||||||
|
db_plugin->rollback (db_plugin->cls);
|
||||||
|
GNUNET_assert (NULL == task);
|
||||||
|
GNUNET_break (0);
|
||||||
|
GNUNET_SCHEDULER_shutdown ();
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
/* continued below */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* commit transaction + report success + exit */
|
||||||
if (0 >= commit_or_warn ())
|
if (0 >= commit_or_warn ())
|
||||||
GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
|
GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
|
||||||
"Profit drain triggered. Exiting.\n");
|
"Profit drain triggered. Exiting.\n");
|
||||||
|
@ -1836,8 +1836,10 @@ exchange_serve_process_config (void)
|
|||||||
&TEH_master_public_key.
|
&TEH_master_public_key.
|
||||||
eddsa_pub))
|
eddsa_pub))
|
||||||
{
|
{
|
||||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
|
||||||
"Invalid master public key given in exchange configuration.");
|
"exchange",
|
||||||
|
"MASTER_PUBLIC_KEY",
|
||||||
|
"invalid base32 encoding for a master public key");
|
||||||
GNUNET_free (master_public_key_str);
|
GNUNET_free (master_public_key_str);
|
||||||
return GNUNET_SYSERR;
|
return GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
|
@ -5545,6 +5545,44 @@ struct TALER_EXCHANGEDB_Plugin
|
|||||||
const struct TALER_MasterSignatureP *master_sig);
|
const struct TALER_MasterSignatureP *master_sig);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get profit drain operation ready to execute.
|
||||||
|
*
|
||||||
|
* @param cls the @e cls of this struct with the plugin-specific state
|
||||||
|
* @param[out] serial set to serial ID of the entry
|
||||||
|
* @param[out] wtid set set to wire transfer ID to use
|
||||||
|
* @param[out] account_section set to account to drain
|
||||||
|
* @param[out] payto_uri set to account to wire funds to
|
||||||
|
* @param[out] request_timestamp set to time of the signature
|
||||||
|
* @param[out] amount set to amount to wire
|
||||||
|
* @param[out] master_sig set to signature affirming the operation
|
||||||
|
* @return transaction status code
|
||||||
|
*/
|
||||||
|
enum GNUNET_DB_QueryStatus
|
||||||
|
(*profit_drains_get_pending)(
|
||||||
|
void *cls,
|
||||||
|
uint64_t *serial,
|
||||||
|
struct TALER_WireTransferIdentifierRawP *wtid,
|
||||||
|
char **account_section,
|
||||||
|
char **payto_uri,
|
||||||
|
struct GNUNET_TIME_Timestamp *request_timestamp,
|
||||||
|
struct TALER_Amount *amount,
|
||||||
|
struct TALER_MasterSignatureP *master_sig);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set profit drain operation to finished.
|
||||||
|
*
|
||||||
|
* @param cls the @e cls of this struct with the plugin-specific state
|
||||||
|
* @param serial serial ID of the entry to mark finished
|
||||||
|
* @return transaction status code
|
||||||
|
*/
|
||||||
|
enum GNUNET_DB_QueryStatus
|
||||||
|
(*profit_drains_set_finished)(
|
||||||
|
void *cls,
|
||||||
|
uint64_t serial);
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* _TALER_EXCHANGE_DB_H */
|
#endif /* _TALER_EXCHANGE_DB_H */
|
||||||
|
Loading…
Reference in New Issue
Block a user