[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[taler-anastasis] branch master updated: try to fix truth upload logic:
From: |
gnunet |
Subject: |
[taler-anastasis] branch master updated: try to fix truth upload logic: store success status, and on resuming possibly retry upload |
Date: |
Wed, 17 Mar 2021 18:45:07 +0100 |
This is an automated email from the git hooks/post-receive script.
grothoff pushed a commit to branch master
in repository anastasis.
The following commit(s) were added to refs/heads/master by this push:
new 91a7eff try to fix truth upload logic: store success status, and on
resuming possibly retry upload
91a7eff is described below
commit 91a7eff05106573893d32ebfc588c404e8820a39
Author: Christian Grothoff <grothoff@gnunet.org>
AuthorDate: Wed Mar 17 18:44:50 2021 +0100
try to fix truth upload logic: store success status, and on resuming
possibly retry upload
---
src/backend/anastasis-httpd_truth_upload.c | 12 ++
src/include/anastasis.h | 29 ++++
src/lib/anastasis_backup.c | 98 ++++++++---
src/reducer/anastasis_api_backup_redux.c | 266 +++++++++++++++++++++--------
4 files changed, 309 insertions(+), 96 deletions(-)
diff --git a/src/backend/anastasis-httpd_truth_upload.c
b/src/backend/anastasis-httpd_truth_upload.c
index 64e7088..1082fe8 100644
--- a/src/backend/anastasis-httpd_truth_upload.c
+++ b/src/backend/anastasis-httpd_truth_upload.c
@@ -197,6 +197,9 @@ make_payment_request (struct TruthUploadContext *tuc)
MHD_add_response_header (resp,
ANASTASIS_HTTP_HEADER_TALER,
hdr));
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "TRUTH payment request made: %s\n",
+ hdr);
GNUNET_free (hdr);
}
tuc->resp = resp;
@@ -546,7 +549,16 @@ AH_handler_truth_post (
if ( (0 == qs) ||
(0 ==
GNUNET_TIME_absolute_get_remaining (paid_until).rel_value_us) )
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "TRUTH payment require!\n");
return begin_payment (tuc);
+ }
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "TRUTH paid until %llu (%d)!\n",
+ (unsigned long long) GNUNET_TIME_absolute_get_remaining (
+ paid_until).rel_value_us,
+ qs);
}
}
diff --git a/src/include/anastasis.h b/src/include/anastasis.h
index d6cac02..ca277d8 100644
--- a/src/include/anastasis.h
+++ b/src/include/anastasis.h
@@ -649,6 +649,35 @@ ANASTASIS_truth_upload2 (struct GNUNET_CURL_Context *ctx,
void *tc_cls);
+/**
+ * Retries upload of truth data to an escrow provider using an
+ * existing truth object. If payment is required, it is requested via
+ * the @a tc callback.
+ *
+ * @param ctx the CURL context used to connect to the backend
+ * @param user_id user identifier derived from user data and backend salt
+ * @param[in] t truth details, reference is consumed
+ * @param truth_data contains the truth for this challenge i.e. phone number,
email address
+ * @param truth_data_size size of the data
+ * @param payment_requested true if the client wants to pay more for the
account now
+ * @param paid_order_id payment identifier of last payment
+ * @param pay_timeout how long to wait for payment
+ * @param tc opens the truth callback which contains the status of the upload
+ * @param tc_cls closure for the callback
+ */
+struct ANASTASIS_TruthUpload *
+ANASTASIS_truth_upload3 (struct GNUNET_CURL_Context *ctx,
+ const struct ANASTASIS_CRYPTO_UserIdentifierP
*user_id,
+ struct ANASTASIS_Truth *t,
+ const void *truth_data,
+ size_t truth_data_size,
+ bool payment_requested,
+ const struct ANASTASIS_PaymentSecretP *paid_order_id,
+ struct GNUNET_TIME_Relative pay_timeout,
+ ANASTASIS_TruthCallback tc,
+ void *tc_cls);
+
+
/**
* Cancels a truth upload process.
*
diff --git a/src/lib/anastasis_backup.c b/src/lib/anastasis_backup.c
index 429a36e..10ccd2e 100644
--- a/src/lib/anastasis_backup.c
+++ b/src/lib/anastasis_backup.c
@@ -225,28 +225,35 @@ truth_store_callback (void *cls,
}
+/**
+ * Retries upload of truth data to an escrow provider using an
+ * existing truth object. If payment is required, it is requested via
+ * the @a tc callback.
+ *
+ * @param ctx the CURL context used to connect to the backend
+ * @param user_id user identifier derived from user data and backend salt
+ * @param[in] t truth details, reference is consumed
+ * @param truth_data contains the truth for this challenge i.e. phone number,
email address
+ * @param truth_data_size size of the data
+ * @param payment_requested true if the client wants to pay more for the
account now
+ * @param paid_order_id payment identifier of last payment
+ * @param pay_timeout how long to wait for payment
+ * @param tc opens the truth callback which contains the status of the upload
+ * @param tc_cls closure for the callback
+ */
struct ANASTASIS_TruthUpload *
-ANASTASIS_truth_upload2 (struct GNUNET_CURL_Context *ctx,
+ANASTASIS_truth_upload3 (struct GNUNET_CURL_Context *ctx,
const struct ANASTASIS_CRYPTO_UserIdentifierP
*user_id,
- const char *provider_url,
- const char *type,
- const char *instructions,
- const char *mime_type,
- const struct ANASTASIS_CRYPTO_PowSalt *provider_salt,
+ struct ANASTASIS_Truth *t,
const void *truth_data,
size_t truth_data_size,
bool payment_requested,
const struct ANASTASIS_PaymentSecretP *paid_order_id,
struct GNUNET_TIME_Relative pay_timeout,
- const struct ANASTASIS_CRYPTO_TruthUUIDP *uuid,
- const struct ANASTASIS_CRYPTO_PowSalt *salt,
- const struct ANASTASIS_CRYPTO_TruthKeyP *truth_key,
- const struct ANASTASIS_CRYPTO_KeyShareP *key_share,
ANASTASIS_TruthCallback tc,
void *tc_cls)
{
struct ANASTASIS_TruthUpload *tu;
- struct ANASTASIS_Truth *t;
struct ANASTASIS_CRYPTO_EncryptedKeyShareP encrypted_key_share;
struct GNUNET_HashCode nt;
void *encrypted_truth;
@@ -259,26 +266,12 @@ ANASTASIS_truth_upload2 (struct GNUNET_CURL_Context *ctx,
tu->id = *user_id;
tu->tc = tc;
tu->tc_cls = tc_cls;
- t = GNUNET_new (struct ANASTASIS_Truth);
- t->url = GNUNET_strdup (provider_url);
- t->type = GNUNET_strdup (type);
- t->instructions = (NULL != instructions)
- ? GNUNET_strdup (instructions)
- : NULL;
- t->mime_type = (NULL != mime_type)
- ? GNUNET_strdup (mime_type)
- : NULL;
- t->provider_salt = *provider_salt;
tu->t = t;
- t->salt = *salt;
- t->uuid = *uuid;
- t->truth_key = *truth_key;
- t->key_share = *key_share;
ANASTASIS_CRYPTO_keyshare_encrypt (&t->key_share,
&tu->id,
&encrypted_key_share);
if (0 == strcmp ("question",
- type))
+ t->type))
{
char *answer;
@@ -310,9 +303,9 @@ ANASTASIS_truth_upload2 (struct GNUNET_CURL_Context *ctx,
tu->tso = ANASTASIS_truth_store (tu->ctx,
t->url,
&t->uuid,
- type,
+ t->type,
&encrypted_key_share,
- mime_type,
+ t->mime_type,
encrypted_truth_size,
encrypted_truth,
payment_requested,
@@ -332,6 +325,55 @@ ANASTASIS_truth_upload2 (struct GNUNET_CURL_Context *ctx,
}
+struct ANASTASIS_TruthUpload *
+ANASTASIS_truth_upload2 (struct GNUNET_CURL_Context *ctx,
+ const struct ANASTASIS_CRYPTO_UserIdentifierP
*user_id,
+ const char *provider_url,
+ const char *type,
+ const char *instructions,
+ const char *mime_type,
+ const struct ANASTASIS_CRYPTO_PowSalt *provider_salt,
+ const void *truth_data,
+ size_t truth_data_size,
+ bool payment_requested,
+ const struct ANASTASIS_PaymentSecretP *paid_order_id,
+ struct GNUNET_TIME_Relative pay_timeout,
+ const struct ANASTASIS_CRYPTO_TruthUUIDP *uuid,
+ const struct ANASTASIS_CRYPTO_PowSalt *salt,
+ const struct ANASTASIS_CRYPTO_TruthKeyP *truth_key,
+ const struct ANASTASIS_CRYPTO_KeyShareP *key_share,
+ ANASTASIS_TruthCallback tc,
+ void *tc_cls)
+{
+ struct ANASTASIS_Truth *t;
+
+ t = GNUNET_new (struct ANASTASIS_Truth);
+ t->url = GNUNET_strdup (provider_url);
+ t->type = GNUNET_strdup (type);
+ t->instructions = (NULL != instructions)
+ ? GNUNET_strdup (instructions)
+ : NULL;
+ t->mime_type = (NULL != mime_type)
+ ? GNUNET_strdup (mime_type)
+ : NULL;
+ t->provider_salt = *provider_salt;
+ t->salt = *salt;
+ t->uuid = *uuid;
+ t->truth_key = *truth_key;
+ t->key_share = *key_share;
+ return ANASTASIS_truth_upload3 (ctx,
+ user_id,
+ t,
+ truth_data,
+ truth_data_size,
+ payment_requested,
+ paid_order_id,
+ pay_timeout,
+ tc,
+ tc_cls);
+}
+
+
struct ANASTASIS_TruthUpload *
ANASTASIS_truth_upload (struct GNUNET_CURL_Context *ctx,
const struct ANASTASIS_CRYPTO_UserIdentifierP *user_id,
diff --git a/src/reducer/anastasis_api_backup_redux.c
b/src/reducer/anastasis_api_backup_redux.c
index ea43203..dd31284 100644
--- a/src/reducer/anastasis_api_backup_redux.c
+++ b/src/reducer/anastasis_api_backup_redux.c
@@ -1285,6 +1285,11 @@ struct UploadContext
*/
struct TruthUpload *tues_tail;
+ /**
+ * Timeout to use for the operation, from the arguments.
+ */
+ struct GNUNET_TIME_Relative timeout;
+
};
@@ -1885,6 +1890,7 @@ truth_upload_cb (void *cls,
const struct ANASTASIS_UploadDetails *ud)
{
struct TruthUpload *tue = cls;
+ json_t *policies;
tue->tu = NULL;
tue->t = t;
@@ -1895,6 +1901,27 @@ truth_upload_cb (void *cls,
ud->details.payment.payment_request);
tue->ps = ud->details.payment.ps;
}
+ /* persist upload status for later */
+ policies = json_object_get (tue->uc->state,
+ "policies");
+ for (unsigned int i = 0; i<tue->policies_length; i++)
+ {
+ const struct PolicyMethodReference *pmr = &tue->policies[i];
+ json_t *policy = json_array_get (policies,
+ pmr->policy_index);
+ json_t *methods = json_object_get (policy,
+ "methods");
+ json_t *method = json_array_get (methods,
+ pmr->method_index);
+
+ GNUNET_assert (NULL != policy);
+ GNUNET_assert (NULL != methods);
+ GNUNET_assert (NULL != method);
+ GNUNET_assert (0 ==
+ json_object_set_new (method,
+ "upload_status",
+ json_integer (ud->us)));
+ }
check_upload_finished (tue->uc);
}
@@ -1911,69 +1938,157 @@ truth_upload_cb (void *cls,
* the truth to, used to check for existing entries
* @param am_idx index of the authentication method, used to check for
existing entries
* @param[in] truth object representing already uploaded truth, reference
captured!
+ * @param must_upload true if the upload was not yet completed and should be
attempted
+ * @param[in,out] async_truth pointer to counter with the number of ongoing
uploads,
+ * updated
+ * @param auth_method object with the challenge details, to generate the truth
* @return #GNUNET_SYSERR error requiring abort,
- * #GNUNET_NO if truth uploads remain unchanged (@a pmr was only
appended)
- * #GNUNET_OK if an existing truth upload was cancelled (!)
+ * #GNUNET_OK on success
*/
static int
add_truth_object (struct UploadContext *uc,
const struct PolicyMethodReference *pmr,
const char *provider_url,
uint32_t am_idx,
- json_t *truth)
+ json_t *truth,
+ bool must_upload,
+ unsigned int *async_truth,
+ json_t *auth_method)
{
/* check if we are already uploading this truth */
+ struct TruthUpload *tue;
+
+ for (tue = uc->tues_head;
+ NULL != tue;
+ tue = tue->next)
{
- for (struct TruthUpload *tue = uc->tues_head;
- NULL != tue;
- tue = tue->next)
+ if ( (0 == strcmp (tue->provider_url,
+ provider_url)) &&
+ (am_idx == tue->am_idx) )
{
- if ( (0 == strcmp (tue->provider_url,
- provider_url)) &&
- (am_idx == tue->am_idx) )
- {
- GNUNET_array_append (tue->policies,
- tue->policies_length,
- *pmr);
- if (NULL == tue->t)
- {
- if (NULL != tue->tu)
- {
- ANASTASIS_truth_upload_cancel (tue->tu);
- tue->tu = NULL;
- return GNUNET_OK;
- }
- }
- else
- {
- json_decref (truth);
- }
- return GNUNET_NO;
- }
+ GNUNET_array_append (tue->policies,
+ tue->policies_length,
+ *pmr);
+ break;
}
}
- /* Create new entry */
+ if (NULL == tue)
{
- struct TruthUpload *tue = GNUNET_new (struct TruthUpload);
+ /* Create new entry */
+ tue = GNUNET_new (struct TruthUpload);
GNUNET_CONTAINER_DLL_insert (uc->tues_head,
uc->tues_tail,
tue);
- tue->t = ANASTASIS_truth_from_json (truth);
- if (NULL == tue->t)
- {
- GNUNET_break (0);
- return GNUNET_SYSERR;
- }
tue->uc = uc;
tue->policies = GNUNET_new (struct PolicyMethodReference);
*tue->policies = *pmr;
tue->provider_url = GNUNET_strdup (provider_url);
tue->am_idx = am_idx;
tue->policies_length = 1;
- return GNUNET_NO;
}
+
+ if (NULL == tue->t)
+ {
+ tue->t = ANASTASIS_truth_from_json (truth);
+ if (NULL == tue->t)
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ }
+
+ if ( (NULL != tue->tu) &&
+ (! must_upload) )
+ {
+ ANASTASIS_truth_upload_cancel (tue->tu);
+ (*async_truth)--;
+ tue->tu = NULL;
+ return GNUNET_OK;
+ }
+
+ if ( (NULL == tue->tu) &&
+ (must_upload) )
+ {
+ struct ANASTASIS_CRYPTO_PowSalt salt;
+ struct ANASTASIS_CRYPTO_UserIdentifierP id;
+ bool force_payment = false;
+ void *truth_data;
+ size_t truth_data_size;
+ const char *payment_request = NULL;
+ struct GNUNET_JSON_Specification spec[] = {
+ GNUNET_JSON_spec_mark_optional (
+ GNUNET_JSON_spec_bool ("force_pay",
+ &force_payment)),
+ GNUNET_JSON_spec_mark_optional (
+ GNUNET_JSON_spec_string ("payment_request",
+ &payment_request)),
+ GNUNET_JSON_spec_mark_optional (
+ GNUNET_JSON_spec_fixed_auto ("payment_secret",
+ &tue->ps)),
+ GNUNET_JSON_spec_varsize ("challenge",
+ &truth_data,
+ &truth_data_size),
+ GNUNET_JSON_spec_end ()
+ };
+
+ if (GNUNET_OK !=
+ lookup_salt (uc->state,
+ provider_url,
+ &salt))
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ if (GNUNET_OK !=
+ GNUNET_JSON_parse (auth_method,
+ spec,
+ NULL, NULL))
+ {
+ json_dumpf (auth_method,
+ stderr,
+ JSON_INDENT (2));
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ {
+ json_t *user_id;
+
+ user_id = json_object_get (uc->state,
+ "identity_attributes");
+ if (! json_is_object (user_id))
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ ANASTASIS_CRYPTO_user_identifier_derive (user_id,
+ &salt,
+ &id);
+ }
+ tue->tu = ANASTASIS_truth_upload3 (ANASTASIS_REDUX_ctx_,
+ &id,
+ tue->t,
+ truth_data,
+ truth_data_size,
+ force_payment,
+ &tue->ps,
+ uc->timeout,
+ &truth_upload_cb,
+ tue);
+ GNUNET_JSON_parse_free (spec);
+ tue->t = NULL;
+ (*async_truth)++;
+ }
+
+ if ( (NULL != tue->tu) &&
+ (NULL != tue->t) )
+ {
+ /* no point in having both */
+ ANASTASIS_truth_free (tue->t);
+ tue->t = NULL;
+ }
+ return GNUNET_OK;
}
@@ -2001,7 +2116,6 @@ check_truth_upload (struct UploadContext *uc,
json_t *auth_method)
{
json_t *user_id;
- struct GNUNET_TIME_Relative timeout = GNUNET_TIME_UNIT_ZERO;
json_t *jtruth;
user_id = json_object_get (uc->state,
@@ -2028,31 +2142,6 @@ check_truth_upload (struct UploadContext *uc,
}
}
- {
- json_t *args;
- struct GNUNET_JSON_Specification pspec[] = {
- GNUNET_JSON_spec_mark_optional (
- GNUNET_JSON_spec_relative_time ("timeout",
- &timeout)),
- GNUNET_JSON_spec_end ()
- };
-
- args = json_object_get (uc->state,
- "pay-arguments");
- if ( (NULL != args) &&
- (GNUNET_OK !=
- GNUNET_JSON_parse (args,
- pspec,
- NULL, NULL)) )
- {
- json_dumpf (args,
- stderr,
- JSON_INDENT (2));
- GNUNET_break (0);
- return GNUNET_SYSERR;
- }
- }
-
{
json_t *policies = json_object_get (uc->state,
"policies");
@@ -2172,7 +2261,7 @@ check_truth_upload (struct UploadContext *uc,
(NULL != payment_request)
? &tue->ps
: NULL,
- timeout,
+ uc->timeout,
&truth_upload_cb,
tue);
}
@@ -2191,7 +2280,7 @@ check_truth_upload (struct UploadContext *uc,
(NULL != payment_request)
? &tue->ps
: NULL,
- timeout,
+ uc->timeout,
&uuid,
&salt,
&truth_key,
@@ -2261,6 +2350,37 @@ upload (json_t *state,
uc->cb = cb;
uc->cb_cls = cb_cls;
uc->state = json_incref (state);
+
+ {
+ json_t *args;
+ struct GNUNET_JSON_Specification pspec[] = {
+ GNUNET_JSON_spec_mark_optional (
+ GNUNET_JSON_spec_relative_time ("timeout",
+ &uc->timeout)),
+ GNUNET_JSON_spec_end ()
+ };
+
+ args = json_object_get (uc->state,
+ "pay-arguments");
+ if ( (NULL != args) &&
+ (GNUNET_OK !=
+ GNUNET_JSON_parse (args,
+ pspec,
+ NULL, NULL)) )
+ {
+ json_dumpf (args,
+ stderr,
+ JSON_INDENT (2));
+ GNUNET_break (0);
+ ANASTASIS_redux_fail_ (cb,
+ cb_cls,
+ TALER_EC_ANASTASIS_REDUCER_INPUT_INVALID,
+ "'timeout' must be valid delay");
+
+ return NULL;
+ }
+ }
+
{
json_t *policy;
size_t pindex;
@@ -2288,11 +2408,15 @@ upload (json_t *state,
uint32_t am_idx;
const char *provider_url;
json_t *truth = NULL;
+ uint32_t status = UINT32_MAX;
struct GNUNET_JSON_Specification spec[] = {
GNUNET_JSON_spec_string ("provider",
&provider_url),
GNUNET_JSON_spec_uint32 ("authentication_method",
&am_idx),
+ GNUNET_JSON_spec_mark_optional (
+ GNUNET_JSON_spec_uint32 ("upload_status",
+ &status)),
GNUNET_JSON_spec_mark_optional (
GNUNET_JSON_spec_json ("truth",
&truth)),
@@ -2327,6 +2451,7 @@ upload (json_t *state,
TALER_EC_ANASTASIS_REDUCER_STATE_INVALID,
"'authentication_method' refers to invalid
authorization index malformed");
upload_cancel_cb (uc);
+ GNUNET_JSON_parse_free (spec);
return NULL;
}
if (NULL == truth)
@@ -2340,6 +2465,7 @@ upload (json_t *state,
amj);
if (GNUNET_SYSERR == ret)
{
+ GNUNET_JSON_parse_free (spec);
ANASTASIS_redux_fail_ (cb,
cb_cls,
TALER_EC_ANASTASIS_REDUCER_STATE_INVALID,
@@ -2352,24 +2478,28 @@ upload (json_t *state,
else
{
int ret;
+ bool must_upload = (ANASTASIS_US_SUCCESS != status);
ret = add_truth_object (uc,
&pmr,
provider_url,
am_idx,
- truth);
+ truth,
+ must_upload,
+ &async_truth,
+ amj);
if (GNUNET_SYSERR == ret)
{
+ GNUNET_JSON_parse_free (spec);
ANASTASIS_redux_fail_ (cb,
cb_cls,
TALER_EC_ANASTASIS_REDUCER_STATE_INVALID,
NULL);
return NULL;
}
- if (GNUNET_OK == ret)
- async_truth--;
}
}
+ GNUNET_JSON_parse_free (spec);
} /* end for all methods of policy */
} /* end for all policies */
if (async_truth > 0)
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [taler-anastasis] branch master updated: try to fix truth upload logic: store success status, and on resuming possibly retry upload,
gnunet <=