implement #4937: allow extraction of fees
This commit is contained in:
parent
1c84b3d4af
commit
0e15a99504
@ -27,6 +27,7 @@
|
||||
#include <gnunet/gnunet_curl_lib.h>
|
||||
#include "taler_exchange_service.h"
|
||||
#include "taler_json_lib.h"
|
||||
#include "taler_signatures.h"
|
||||
#include "taler_wire_plugin.h"
|
||||
#include "exchange_api_handle.h"
|
||||
|
||||
@ -148,6 +149,8 @@ handle_wire_finished (void *cls,
|
||||
break;
|
||||
case MHD_HTTP_OK:
|
||||
{
|
||||
const struct TALER_EXCHANGE_Keys *keys;
|
||||
const struct TALER_MasterPublicKeyP *master_pub;
|
||||
const char *key;
|
||||
json_t *method;
|
||||
int ret;
|
||||
@ -175,19 +178,32 @@ handle_wire_finished (void *cls,
|
||||
method);
|
||||
}
|
||||
}
|
||||
/* check fees */
|
||||
keys = TALER_EXCHANGE_get_keys (wh->exchange);
|
||||
if (NULL == keys)
|
||||
master_pub = NULL;
|
||||
else
|
||||
master_pub = &keys->master_pub;
|
||||
if (GNUNET_OK !=
|
||||
TALER_EXCHANGE_wire_get_fees (master_pub,
|
||||
keep,
|
||||
NULL,
|
||||
NULL))
|
||||
{
|
||||
/* bogus reply */
|
||||
GNUNET_break_op (0);
|
||||
response_code = 0;
|
||||
}
|
||||
if (0 != response_code)
|
||||
{
|
||||
/* all supported methods were valid, use 'keep' for 'json' */
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* some supported methods were invalid, release 'keep', preserve
|
||||
full 'json' for application-level error handling. */
|
||||
json_decref (keep);
|
||||
keep = NULL;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MHD_HTTP_BAD_REQUEST:
|
||||
/* This should never happen, either us or the exchange is buggy
|
||||
@ -300,4 +316,143 @@ TALER_EXCHANGE_wire_cancel (struct TALER_EXCHANGE_WireHandle *wh)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parse wire @a fee and store the result in @a af.
|
||||
*
|
||||
* @param[out] af where to write the result
|
||||
* @param fee json AggregateTransferFee to parse
|
||||
* @return #GNUNET_OK on success, #GNUNET_SYSERR on error
|
||||
*/
|
||||
static int
|
||||
parse_json_fees (struct TALER_EXCHANGE_WireAggregateFees *af,
|
||||
json_t *fee)
|
||||
{
|
||||
struct GNUNET_JSON_Specification spec[] = {
|
||||
GNUNET_JSON_spec_fixed_auto ("sig",
|
||||
&af->master_sig),
|
||||
TALER_JSON_spec_amount ("wire_fee",
|
||||
&af->wire_fee),
|
||||
GNUNET_JSON_spec_absolute_time ("start_date",
|
||||
&af->start_date),
|
||||
GNUNET_JSON_spec_absolute_time ("end_date",
|
||||
&af->end_date),
|
||||
GNUNET_JSON_spec_end()
|
||||
};
|
||||
|
||||
if (GNUNET_OK !=
|
||||
GNUNET_JSON_parse (fee,
|
||||
spec,
|
||||
NULL,
|
||||
NULL))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
return GNUNET_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check the #TALER_SIGNATURE_MASTER_WIRE_FEES signature.
|
||||
*
|
||||
* @param af record to check
|
||||
* @param wire_method wire method to check against
|
||||
* @param master_pub expected signing key
|
||||
* @return #GNUNET_OK on success, #GNUNET_SYSERR on failure
|
||||
*/
|
||||
static int
|
||||
check_sig (const struct TALER_EXCHANGE_WireAggregateFees *af,
|
||||
const char *wire_method,
|
||||
const struct TALER_MasterPublicKeyP *master_pub)
|
||||
{
|
||||
struct TALER_MasterWireFeePS wp;
|
||||
|
||||
wp.purpose.purpose = htonl (TALER_SIGNATURE_MASTER_WIRE_FEES);
|
||||
wp.purpose.size = htonl (sizeof (wp));
|
||||
GNUNET_CRYPTO_hash (wire_method,
|
||||
strlen (wire_method) + 1,
|
||||
&wp.h_wire_method);
|
||||
wp.start_date = GNUNET_TIME_absolute_hton (af->start_date);
|
||||
wp.end_date = GNUNET_TIME_absolute_hton (af->end_date);
|
||||
TALER_amount_hton (&wp.wire_fee,
|
||||
&af->wire_fee);
|
||||
return GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MASTER_WIRE_FEES,
|
||||
&wp.purpose,
|
||||
&af->master_sig.eddsa_signature,
|
||||
&master_pub->eddsa_pub);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Obtain information about wire fees encoded in @a obj
|
||||
* by wire method.
|
||||
*
|
||||
* @param master_pub public key to use to verify signatures, NULL to not verify
|
||||
* @param obj wire information as encoded in the #TALER_EXCHANGE_WireResultCallback
|
||||
* @param cb callback to invoke for the fees
|
||||
* @param cb_cls closure for @a cb
|
||||
* @return #GNUNET_OK in success, #GNUNET_SYSERR if @a obj is ill-formed
|
||||
*/
|
||||
int
|
||||
TALER_EXCHANGE_wire_get_fees (const struct TALER_MasterPublicKeyP *master_pub,
|
||||
const json_t *obj,
|
||||
TALER_EXCHANGE_WireFeeCallback cb,
|
||||
void *cb_cls)
|
||||
{
|
||||
const char *wire_method;
|
||||
json_t *value;
|
||||
|
||||
json_object_foreach (((json_t *) obj), wire_method, value)
|
||||
{
|
||||
json_t *fees;
|
||||
size_t num_fees;
|
||||
|
||||
fees = json_object_get (value, "fees");
|
||||
if ( (NULL == fees) ||
|
||||
(! json_is_array (fees)) )
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
num_fees = json_array_size (fees);
|
||||
if (num_fees > 1024)
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
{
|
||||
struct TALER_EXCHANGE_WireAggregateFees af[num_fees + 1];
|
||||
|
||||
for (size_t i=0;i<num_fees;i++)
|
||||
{
|
||||
af[i].next = &af[i+1];
|
||||
if (GNUNET_OK !=
|
||||
parse_json_fees (&af[i],
|
||||
json_array_get (fees,
|
||||
i)))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
if ( (NULL != master_pub) &&
|
||||
(GNUNET_OK !=
|
||||
check_sig (&af[i],
|
||||
wire_method,
|
||||
master_pub)) )
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
}
|
||||
af[num_fees].next = NULL;
|
||||
if (NULL != cb)
|
||||
cb (cb_cls,
|
||||
wire_method,
|
||||
&af[0]);
|
||||
}
|
||||
}
|
||||
return GNUNET_OK;
|
||||
}
|
||||
|
||||
|
||||
/* end of exchange_api_wire.c */
|
||||
|
@ -340,6 +340,69 @@ TALER_EXCHANGE_get_denomination_key_by_hash (const struct TALER_EXCHANGE_Keys *k
|
||||
/* ********************* /wire *********************** */
|
||||
|
||||
|
||||
/**
|
||||
* Sorted list of fees to be paid for aggregate wire transfers.
|
||||
*/
|
||||
struct TALER_EXCHANGE_WireAggregateFees
|
||||
{
|
||||
/**
|
||||
* This is a linked list.
|
||||
*/
|
||||
struct TALER_EXCHANGE_WireAggregateFees *next;
|
||||
|
||||
/**
|
||||
* Fee to be paid.
|
||||
*/
|
||||
struct TALER_Amount wire_fee;
|
||||
|
||||
/**
|
||||
* Time when this fee goes into effect (inclusive)
|
||||
*/
|
||||
struct GNUNET_TIME_Absolute start_date;
|
||||
|
||||
/**
|
||||
* Time when this fee stops being in effect (exclusive).
|
||||
*/
|
||||
struct GNUNET_TIME_Absolute end_date;
|
||||
|
||||
/**
|
||||
* Signature affirming the above fee structure.
|
||||
*/
|
||||
struct TALER_MasterSignatureP master_sig;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Function called with information about the wire fees
|
||||
* for each wire method.
|
||||
*
|
||||
* @param cls closure
|
||||
* @param wire_method name of the wire method (i.e. "sepa")
|
||||
* @param fees fee structure for this method
|
||||
*/
|
||||
typedef void
|
||||
(*TALER_EXCHANGE_WireFeeCallback)(void *cls,
|
||||
const char *wire_method,
|
||||
const struct TALER_EXCHANGE_WireAggregateFees *fees);
|
||||
|
||||
|
||||
/**
|
||||
* Obtain information about wire fees encoded in @a obj
|
||||
* by wire method.
|
||||
*
|
||||
* @param master_pub public key to use to verify signatures, NULL to not verify
|
||||
* @param obj wire information as encoded in the #TALER_EXCHANGE_WireResultCallback
|
||||
* @param cb callback to invoke for the fees
|
||||
* @param cb_cls closure for @a cb
|
||||
* @return #GNUNET_OK in success, #GNUNET_SYSERR if @a obj is ill-formed
|
||||
*/
|
||||
int
|
||||
TALER_EXCHANGE_wire_get_fees (const struct TALER_MasterPublicKeyP *master_pub,
|
||||
const json_t *obj,
|
||||
TALER_EXCHANGE_WireFeeCallback cb,
|
||||
void *cb_cls);
|
||||
|
||||
|
||||
/**
|
||||
* @brief A Wire format inquiry handle
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user