implement deserialization logic for #5136

This commit is contained in:
Christian Grothoff 2018-10-13 08:15:02 +02:00
parent eb1b6fbc97
commit c09c900922
No known key found for this signature in database
GPG Key ID: 939E6BE1E29FC3CC
2 changed files with 129 additions and 6 deletions

View File

@ -1102,6 +1102,89 @@ header_cb (char *buffer,
/* ********************* public API ******************* */ /* ********************* public API ******************* */
/**
* Deserialize the key data and use it to bootstrap @a exchange to
* more efficiently recover the state. Errors in @a data must be
* tolerated (i.e. by re-downloading instead).
*
* @param exchange which exchange's key and wire data should be deserialized
* @return data the data to deserialize
*/
static void
deserialize_data (struct TALER_EXCHANGE_Handle *exchange,
const json_t *data)
{
enum TALER_EXCHANGE_VersionCompatibility vc;
json_t *keys;
const char *url;
struct GNUNET_TIME_Absolute expire;
struct GNUNET_JSON_Specification spec[] = {
GNUNET_JSON_spec_json ("keys",
&keys),
GNUNET_JSON_spec_string ("url",
&url),
GNUNET_JSON_spec_absolute_time ("expire",
&expire),
GNUNET_JSON_spec_end()
};
struct TALER_EXCHANGE_Keys key_data;
if (NULL == data)
return;
if (GNUNET_OK !=
GNUNET_JSON_parse (data,
spec,
NULL, NULL))
{
GNUNET_break_op (0);
return;
}
if (0 != strcmp (url,
exchange->url))
{
GNUNET_break (0);
return;
}
memset (&key_data,
0,
sizeof (struct TALER_EXCHANGE_Keys));
if (GNUNET_OK !=
decode_keys_json (keys,
&key_data,
&vc))
{
GNUNET_break (0);
return;
}
/* decode successful, initialize with the result */
GNUNET_assert (NULL == exchange->key_data_raw);
exchange->key_data_raw = json_deep_copy (keys);
exchange->key_data = key_data;
exchange->key_data_expiration = expire;
exchange->state = MHS_CERT;
/* notify application about the key information */
exchange->cert_cb (exchange->cert_cb_cls,
&exchange->key_data,
vc);
}
/**
* Serialize the latest key data from @a exchange to be persisted on
* disk (to be used with #TALER_EXCHANGE_OPTION_DATA to more
* efficiently recover the state).
*
* @param exchange which exchange's key and wire data should be serialized
* @return NULL on error (i.e. no current data available); otherwise
* json object owned by the caller
*/
json_t *
TALER_EXCHANGE_serialize_data (struct TALER_EXCHANGE_Handle *exchange)
{
return NULL;
}
/** /**
* Initialise a connection to the exchange. Will connect to the * Initialise a connection to the exchange. Will connect to the
* exchange and obtain information about the exchange's master public * exchange and obtain information about the exchange's master public
@ -1126,11 +1209,8 @@ TALER_EXCHANGE_connect (struct GNUNET_CURL_Context *ctx,
{ {
struct TALER_EXCHANGE_Handle *exchange; struct TALER_EXCHANGE_Handle *exchange;
va_list ap; va_list ap;
enum TALER_EXCHANGE_Option opt;
va_start (ap, cert_cb_cls);
GNUNET_assert (TALER_EXCHANGE_OPTION_END ==
va_arg (ap, int));
va_end (ap);
exchange = GNUNET_new (struct TALER_EXCHANGE_Handle); exchange = GNUNET_new (struct TALER_EXCHANGE_Handle);
exchange->ctx = ctx; exchange->ctx = ctx;
exchange->url = GNUNET_strdup (url); exchange->url = GNUNET_strdup (url);
@ -1138,6 +1218,28 @@ TALER_EXCHANGE_connect (struct GNUNET_CURL_Context *ctx,
exchange->cert_cb_cls = cert_cb_cls; exchange->cert_cb_cls = cert_cb_cls;
exchange->retry_task = GNUNET_SCHEDULER_add_now (&request_keys, exchange->retry_task = GNUNET_SCHEDULER_add_now (&request_keys,
exchange); exchange);
va_start (ap, cert_cb_cls);
while (TALER_EXCHANGE_OPTION_END !=
(opt = va_arg (ap, int)))
{
switch (opt) {
case TALER_EXCHANGE_OPTION_END:
GNUNET_assert (0);
break;
case TALER_EXCHANGE_OPTION_DATA:
{
const json_t *data = va_arg (ap, const json_t *);
deserialize_data (exchange,
data);
break;
}
default:
GNUNET_assert (0);
break;
}
}
va_end (ap);
return exchange; return exchange;
} }

View File

@ -1,6 +1,6 @@
/* /*
This file is part of TALER This file is part of TALER
Copyright (C) 2014-2017 Taler Systems SA Copyright (C) 2014-2018 Taler Systems SA
TALER is free software; you can redistribute it and/or modify it under the TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU Affero General Public License as published by the Free Software terms of the GNU Affero General Public License as published by the Free Software
@ -39,8 +39,16 @@ enum TALER_EXCHANGE_Option
/** /**
* Terminator (end of option list). * Terminator (end of option list).
*/ */
TALER_EXCHANGE_OPTION_END = 0 TALER_EXCHANGE_OPTION_END = 0,
/**
* Followed by a "const json_t *" that was previously returned for
* this exchange URL by #TALER_EXCHANGE_serialize_data(). Used to
* resume a connection to an exchange without having to re-download
* /keys data (or at least only download the deltas).
*/
TALER_EXCHANGE_OPTION_DATA
}; };
@ -348,6 +356,19 @@ TALER_EXCHANGE_connect (struct GNUNET_CURL_Context *ctx,
...); ...);
/**
* Serialize the latest key data from @a exchange to be persisted
* on disk (to be used with #TALER_EXCHANGE_OPTION_DATA to more
* efficiently recover the state).
*
* @param exchange which exchange's key and wire data should be serialized
* @return NULL on error (i.e. no current data available); otherwise
* json object owned by the caller
*/
json_t *
TALER_EXCHANGE_serialize_data (struct TALER_EXCHANGE_Handle *exchange);
/** /**
* Disconnect from the exchange. * Disconnect from the exchange.
* *