misc bugfixes from tests

This commit is contained in:
Christian Grothoff 2015-07-05 16:55:01 +02:00
parent f623214c12
commit 922323b410
18 changed files with 300 additions and 116 deletions

View File

@ -651,7 +651,7 @@ struct TALER_MINT_AdminAddIncomingHandle *
TALER_MINT_admin_add_incoming (struct TALER_MINT_Handle *mint,
const struct TALER_ReservePublicKeyP *reserve_pub,
const struct TALER_Amount *amount,
const struct GNUNET_TIME_Absolute execution_date,
struct GNUNET_TIME_Absolute execution_date,
const json_t *wire,
TALER_MINT_AdminAddIncomingResultCallback res_cb,
void *res_cb_cls);

View File

@ -73,6 +73,30 @@ void
TALER_gcrypt_init (void);
/**
* Round a time value so that it is suitable for transmission
* via JSON encodings.
*
* @param at time to round
* @return #GNUNET_OK if time was already rounded, #GNUNET_NO if
* it was just now rounded
*/
int
TALER_round_abs_time (struct GNUNET_TIME_Absolute *at);
/**
* Round a time value so that it is suitable for transmission
* via JSON encodings.
*
* @param rt time to round
* @return #GNUNET_OK if time was already rounded, #GNUNET_NO if
* it was just now rounded
*/
int
TALER_round_rel_time (struct GNUNET_TIME_Relative *rt);
/**
* Load configuration by parsing all configuration
* files in the given directory.

View File

@ -246,7 +246,7 @@ struct TALER_MINT_AdminAddIncomingHandle *
TALER_MINT_admin_add_incoming (struct TALER_MINT_Handle *mint,
const struct TALER_ReservePublicKeyP *reserve_pub,
const struct TALER_Amount *amount,
const struct GNUNET_TIME_Absolute execution_date,
struct GNUNET_TIME_Absolute execution_date,
const json_t *wire,
TALER_MINT_AdminAddIncomingResultCallback res_cb,
void *res_cb_cls)
@ -256,6 +256,8 @@ TALER_MINT_admin_add_incoming (struct TALER_MINT_Handle *mint,
json_t *admin_obj;
CURL *eh;
GNUNET_assert (GNUNET_OK ==
TALER_round_abs_time (&execution_date));
if (GNUNET_YES !=
MAH_handle_is_ready (mint))
{

View File

@ -37,7 +37,7 @@
*/
#define JSON_WARN(error) \
GNUNET_log (GNUNET_ERROR_TYPE_WARNING, \
"JSON parsing failed at %s:%u: %s (%s)", \
"JSON parsing failed at %s:%u: %s (%s)\n", \
__FILE__, __LINE__, error.text, error.source)
@ -464,8 +464,8 @@ verify_signatures (const struct TALER_MINT_DenomPublicKey *dki,
TALER_LOG_WARNING ("Invalid coin passed for /deposit\n");
return GNUNET_SYSERR;
}
if (TALER_amount_cmp (&dki->fee_deposit,
amount) < 0)
if (0 < TALER_amount_cmp (&dki->fee_deposit,
amount))
{
TALER_LOG_WARNING ("Deposit amount smaller than fee\n");
return GNUNET_SYSERR;
@ -615,17 +615,17 @@ TALER_MINT_deposit (struct TALER_MINT_Handle *mint,
}
deposit_obj = json_pack ("{s:o, s:o," /* f/wire */
" s:s, s:s," /* H_wire, H_contract */
" s:s, s:s," /* coin_pub, denom_pub */
" s:s, s:s," /* ub_sig, timestamp */
" s:I, s:s," /* transaction id, merchant_pub */
" s:s, s:s}", /* refund_deadline, coin_sig */
" s:o, s:o," /* H_wire, H_contract */
" s:o, s:o," /* coin_pub, denom_pub */
" s:o, s:o," /* ub_sig, timestamp */
" s:I, s:o," /* transaction id, merchant_pub */
" s:o, s:o}", /* refund_deadline, coin_sig */
"f", TALER_json_from_amount (amount),
"wire", wire_details,
"H_wire", TALER_json_from_data (&h_wire,
sizeof (h_wire)),
"H_contract", TALER_json_from_data (&h_contract,
sizeof (h_contract)),
"H_contract", TALER_json_from_data (h_contract,
sizeof (struct GNUNET_HashCode)),
"coin_pub", TALER_json_from_data (coin_pub,
sizeof (*coin_pub)),
"denom_pub", TALER_json_from_rsa_public_key (denom_pub->rsa_public_key),

View File

@ -2,8 +2,9 @@
# Currency supported by the mint (can only be one)
CURRENCY = EUR
# Wire format supproted by the mint (currently only SEPA is implemented)
WIREFORMAT = SEPA
# Wire format supproted by the mint
# TEST is used for testing... (what a shock)
WIREFORMAT = TEST
# HTTP port the mint listens to
PORT = 8081

View File

@ -27,6 +27,7 @@
*/
#include "platform.h"
#include "taler_util.h"
#include "taler_signatures.h"
#include "taler_mint_service.h"
#include <microhttpd.h>
@ -506,6 +507,7 @@ interpreter_run (void *cls,
struct TALER_ReservePublicKeyP reserve_pub;
struct TALER_CoinSpendPublicKeyP coin_pub;
struct TALER_Amount amount;
struct GNUNET_TIME_Absolute execution_date;
json_t *wire;
is->task = NULL;
@ -566,14 +568,22 @@ interpreter_run (void *cls,
fail (is);
return;
}
execution_date = GNUNET_TIME_absolute_get ();
TALER_round_abs_time (&execution_date);
cmd->details.admin_add_incoming.aih
= TALER_MINT_admin_add_incoming (mint,
&reserve_pub,
&amount,
GNUNET_TIME_absolute_get (),
execution_date,
wire,
&add_incoming_cb,
is);
if (NULL == cmd->details.admin_add_incoming.aih)
{
GNUNET_break (0);
fail (is);
return;
}
trigger_context_task ();
return;
case OC_WITHDRAW_SIGN:
@ -629,6 +639,12 @@ interpreter_run (void *cls,
&cmd->details.withdraw_sign.blinding_key,
&withdraw_sign_cb,
is);
if (NULL == cmd->details.withdraw_sign.wsh)
{
GNUNET_break (0);
fail (is);
return;
}
trigger_context_task ();
return;
case OC_DEPOSIT:
@ -690,9 +706,30 @@ interpreter_run (void *cls,
refund_deadline = GNUNET_TIME_UNIT_ZERO_ABS;
}
timestamp = GNUNET_TIME_absolute_get ();
TALER_round_abs_time (&timestamp);
{
struct TALER_DepositRequestPS dr;
/* FIXME: init "coin_sig" here! */
dr.purpose.size = htonl (sizeof (struct TALER_DepositRequestPS));
dr.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_DEPOSIT);
dr.h_contract = h_contract;
TALER_hash_json (wire,
&dr.h_wire);
dr.timestamp = GNUNET_TIME_absolute_hton (timestamp);
dr.refund_deadline = GNUNET_TIME_absolute_hton (refund_deadline);
dr.transaction_id = GNUNET_htonll (cmd->details.deposit.transaction_id);
TALER_amount_hton (&dr.amount_with_fee,
&amount);
TALER_amount_hton (&dr.deposit_fee,
&ref->details.withdraw_sign.pk->fee_deposit);
dr.merchant = merchant_pub;
dr.coin_pub = coin_pub;
GNUNET_assert (GNUNET_OK ==
GNUNET_CRYPTO_eddsa_sign (&ref->details.withdraw_sign.coin_priv.eddsa_priv,
&dr.purpose,
&coin_sig.eddsa_signature));
}
cmd->details.deposit.dh
= TALER_MINT_deposit (mint,
&amount,
@ -715,6 +752,7 @@ interpreter_run (void *cls,
fail (is);
return;
}
trigger_context_task ();
return;
}
default:
@ -938,7 +976,7 @@ run (void *cls,
/* Fill reserve with EUR:5.01, as withdraw fee is 1 ct per config */
{ .oc = OC_ADMIN_ADD_INCOMING,
.label = "create-reserve-1",
.details.admin_add_incoming.wire = "{ \"bank\":\"source bank\", \"account\":42 }",
.details.admin_add_incoming.wire = "{ \"type\":\"TEST\", \"bank\":\"source bank\", \"account\":42 }",
.details.admin_add_incoming.amount = "EUR:5.01" },
{ .oc = OC_WITHDRAW_SIGN,
.label = "withdraw-coin-1",
@ -948,7 +986,7 @@ run (void *cls,
.label = "deposit-simple",
.details.deposit.amount = "EUR:5",
.details.deposit.coin_ref = "withdraw-coin-1",
.details.deposit.wire_details = "{ \"bank\":\"dest bank\", \"account\":42 }",
.details.deposit.wire_details = "{ \"type\":\"TEST\", \"bank\":\"dest bank\", \"account\":42 }",
.details.deposit.contract = "{ \"items\"={ \"name\":\"ice cream\", \"value\":1 } }",
.details.deposit.transaction_id = 1 },
{ .oc = OC_END }
@ -1007,7 +1045,7 @@ main (int argc,
"-d", "test-mint-home",
NULL);
/* give child time to start and bind against the socket */
sleep (1);
sleep (5);
result = GNUNET_SYSERR;
GNUNET_SCHEDULER_run (&run, NULL);
GNUNET_OS_process_kill (mintd,

View File

@ -34,14 +34,6 @@
*/
#define HASH_CUTOFF 20
/**
* Macro to round microseconds to seconds in GNUNET_TIME_* structs.
*
* @param name value to round
* @param us_field rel_value_us or abs_value_us
*/
#define ROUND_TO_SECS(name,us_field) name.us_field -= name.us_field % (1000 * 1000);
GNUNET_NETWORK_STRUCT_BEGIN
@ -515,8 +507,7 @@ mint_keys_update_signkeys ()
"must be longer than signkey_duration");
return GNUNET_SYSERR;
}
ROUND_TO_SECS (signkey_duration,
rel_value_us);
TALER_round_rel_time (&signkey_duration);
GNUNET_asprintf (&signkey_dir,
"%s" DIR_SEPARATOR_STR TALER_MINTDB_DIR_SIGNING_KEYS,
mint_directory);
@ -598,8 +589,7 @@ get_cointype_params (const char *ct,
"duration_withdraw");
return GNUNET_SYSERR;
}
ROUND_TO_SECS (params->duration_withdraw,
rel_value_us);
TALER_round_rel_time (&params->duration_withdraw);
if (GNUNET_OK !=
GNUNET_CONFIGURATION_get_value_time (kcfg,
ct,
@ -611,8 +601,7 @@ get_cointype_params (const char *ct,
"duration_spend");
return GNUNET_SYSERR;
}
ROUND_TO_SECS (params->duration_spend,
rel_value_us);
TALER_round_rel_time (&params->duration_spend);
if (GNUNET_OK !=
GNUNET_CONFIGURATION_get_value_time (kcfg,
ct,
@ -624,8 +613,7 @@ get_cointype_params (const char *ct,
"duration_legal");
return GNUNET_SYSERR;
}
ROUND_TO_SECS (params->duration_legal,
rel_value_us);
TALER_round_rel_time (&params->duration_legal);
if (GNUNET_OK !=
GNUNET_CONFIGURATION_get_value_time (kcfg,
ct,
@ -637,8 +625,7 @@ get_cointype_params (const char *ct,
"mint_denom_duration_overlap");
return GNUNET_SYSERR;
}
ROUND_TO_SECS (params->duration_overlap,
rel_value_us);
TALER_round_rel_time (&params->duration_overlap);
if (GNUNET_OK !=
GNUNET_CONFIGURATION_get_value_number (kcfg,
ct,
@ -914,7 +901,7 @@ main (int argc,
{
now = GNUNET_TIME_absolute_get ();
}
ROUND_TO_SECS (now, abs_value_us);
TALER_round_abs_time (&now);
kcfg = TALER_config_load (mint_directory);
if (NULL == kcfg)
@ -990,8 +977,7 @@ main (int argc,
_("must not be zero"));
return GNUNET_SYSERR;
}
ROUND_TO_SECS (lookahead_sign,
rel_value_us);
TALER_round_rel_time (&lookahead_sign);
lookahead_sign_stamp = GNUNET_TIME_absolute_add (now,
lookahead_sign);

View File

@ -126,6 +126,7 @@ TMH_DB_execute_deposit (struct MHD_Connection *connection,
&deposit->h_wire,
&deposit->h_contract,
deposit->transaction_id,
deposit->timestamp,
deposit->refund_deadline,
&deposit->merchant_pub,
&amount_without_fee);
@ -194,14 +195,19 @@ TMH_DB_execute_deposit (struct MHD_Connection *connection,
TALER_LOG_WARNING ("/deposit transaction commit failed\n");
return TMH_RESPONSE_reply_commit_error (connection);
}
GNUNET_assert (GNUNET_OK ==
TALER_amount_subtract (&amount_without_fee,
&deposit->amount_with_fee,
&deposit->deposit_fee));
return TMH_RESPONSE_reply_deposit_success (connection,
&deposit->coin.coin_pub,
&deposit->h_wire,
&deposit->h_contract,
deposit->transaction_id,
deposit->timestamp,
deposit->refund_deadline,
&deposit->merchant_pub,
&deposit->amount_with_fee);
&amount_without_fee);
}

View File

@ -101,14 +101,12 @@ verify_and_execute_deposit (struct MHD_Connection *connection,
}
TALER_amount_ntoh (&fee_deposit,
&dki->issue.fee_deposit);
if (TALER_amount_cmp (&fee_deposit,
&deposit->amount_with_fee) < 0)
if (0 < TALER_amount_cmp (&fee_deposit,
&deposit->amount_with_fee))
{
TMH_KS_release (key_state);
return (MHD_YES ==
TMH_RESPONSE_reply_external_error (connection,
"deposited amount smaller than depositing fee"))
? GNUNET_NO : GNUNET_SYSERR;
return TMH_RESPONSE_reply_external_error (connection,
"deposited amount smaller than depositing fee");
}
TMH_KS_release (key_state);
@ -146,7 +144,7 @@ parse_and_handle_deposit_request (struct MHD_Connection *connection,
TMH_PARSE_MEMBER_FIXED ("H_contract", &deposit.h_contract),
TMH_PARSE_MEMBER_FIXED ("H_wire", &deposit.h_wire),
TMH_PARSE_MEMBER_FIXED ("coin_sig", &deposit.csig),
TMH_PARSE_MEMBER_FIXED ("transaction_id", &deposit.transaction_id),
TMH_PARSE_member_uint64 ("transaction_id", &deposit.transaction_id),
TMH_PARSE_member_time_abs ("timestamp", &deposit.timestamp),
TMH_PARSE_member_time_abs ("refund_deadline", &deposit.refund_deadline),
TMH_PARSE_MEMBER_END
@ -160,6 +158,7 @@ parse_and_handle_deposit_request (struct MHD_Connection *connection,
return MHD_NO; /* hard failure */
if (GNUNET_NO == res)
return MHD_YES; /* failure */
if (GNUNET_YES !=
TALER_json_validate_wireformat (TMH_expected_wire_format,
wire))
@ -197,7 +196,7 @@ parse_and_handle_deposit_request (struct MHD_Connection *connection,
&deposit.deposit_fee))
{
/* Total amount smaller than fee, invalid */
TMH_PARSE_release_data (spec);
TMH_PARSE_release_data (spec);
return TMH_RESPONSE_reply_arg_invalid (connection,
"f");
}
@ -247,7 +246,7 @@ TMH_DEPOSIT_handler_deposit (struct TMH_RequestHandler *rh,
if ( (GNUNET_NO == res) || (NULL == json) )
return MHD_YES;
if (-1 == json_unpack (json,
"{s:s, s:o, f:o}",
"{s:o, s:o}",
"wire", &wire,
"f", &f))
{

View File

@ -494,6 +494,7 @@ TMH_KS_acquire (void)
key_state->denomkey_map = GNUNET_CONTAINER_multihashmap_create (32,
GNUNET_NO);
key_state->reload_time = GNUNET_TIME_absolute_get ();
TALER_round_abs_time (&key_state->reload_time);
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Loading keys from `%s'\n",
TMH_mint_directory);

View File

@ -549,6 +549,28 @@ TMH_PARSE_navigate_json (struct MHD_Connection *connection,
}
break;
case TMH_PARSE_JNC_RET_UINT64:
{
uint64_t *r_u64 = va_arg (argp, uint64_t *);
if (json_typeof (root) != JSON_INTEGER)
{
ret = (MHD_YES ==
TMH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_BAD_REQUEST,
"{s:s, s:s, s:i, s:o}",
"error", "wrong JSON field type",
"type_expected", "integer",
"type_actual", json_typeof (root),
"path", path))
? GNUNET_NO : GNUNET_SYSERR;
break;
}
*r_u64 = (uint64_t) json_integer_value (root);
ret = GNUNET_OK;
}
break;
case TMH_PARSE_JNC_RET_RSA_PUBLIC_KEY:
{
struct TALER_DenominationPublicKey *where;
@ -803,6 +825,16 @@ TMH_PARSE_json_data (struct MHD_Connection *connection,
TMH_PARSE_JNC_RET_TIME_ABSOLUTE,
spec[i].destination);
break;
case TMH_PARSE_JNC_RET_UINT64:
GNUNET_assert (sizeof (uint64_t) ==
spec[i].destination_size_in);
ret = TMH_PARSE_navigate_json (connection,
root,
TMH_PARSE_JNC_FIELD,
spec[i].field_name,
TMH_PARSE_JNC_RET_UINT64,
spec[i].destination);
break;
}
}
if (GNUNET_YES != ret)
@ -882,6 +914,8 @@ TMH_PARSE_release_data (struct TMH_PARSE_FieldSpecification *spec)
break;
case TMH_PARSE_JNC_RET_TIME_ABSOLUTE:
break;
case TMH_PARSE_JNC_RET_UINT64:
break;
}
}
}
@ -889,8 +923,9 @@ TMH_PARSE_release_data (struct TMH_PARSE_FieldSpecification *spec)
/**
* Parse absolute time specified in JSON format. The JSON format is
* "/TIMEVAL/" where TIMEVAL is in milliseconds. Additionally, we
* support "/forever/" to represent the end of time.
* "/Date(TIMEVAL)/" where TIMEVAL is in seconds after the Unix Epoch.
* Additionally, we support "/forever/" and "/never/" to represent the
* end of time.
*
* @param connection the MHD connection (to report errors)
* @param f json specification of the amount
@ -906,9 +941,7 @@ TMH_PARSE_time_abs_json (struct MHD_Connection *connection,
struct GNUNET_TIME_Absolute *time)
{
const char *val;
size_t slen;
unsigned long long int tval;
char *endp;
unsigned long long tval;
val = json_string_value (f);
if (NULL == val)
@ -921,30 +954,18 @@ TMH_PARSE_time_abs_json (struct MHD_Connection *connection,
return GNUNET_SYSERR;
return GNUNET_NO;
}
slen = strlen (val);
if ( (slen <= 2) ||
('/' != val[0]) ||
('/' != val[slen - 1]) )
{
if (MHD_YES !=
TMH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_BAD_REQUEST,
"{s:s, s:s}",
"error", "timestamp expected",
"value", val))
return GNUNET_SYSERR;
return GNUNET_NO;
}
if (0 == strcasecmp (val,
"/forever/"))
if ( (0 == strcasecmp (val,
"/forever/")) ||
(0 == strcasecmp (val,
"/never/")) )
{
*time = GNUNET_TIME_UNIT_FOREVER_ABS;
return GNUNET_OK;
}
tval = strtoull (&val[1],
&endp,
10);
if (&val[slen - 1] != endp)
if (1 != sscanf (val,
"/Date(%llu)/",
&tval))
{
if (MHD_YES !=
TMH_RESPONSE_reply_json_pack (connection,
@ -955,9 +976,9 @@ TMH_PARSE_time_abs_json (struct MHD_Connection *connection,
return GNUNET_SYSERR;
return GNUNET_NO;
}
/* Time is in 'ms' in JSON, but in microseconds in GNUNET_TIME_Absolute */
time->abs_value_us = tval * 1000LL;
if ( (time->abs_value_us) / 1000LL != tval)
/* Time is in seconds in JSON, but in microseconds in GNUNET_TIME_Absolute */
time->abs_value_us = tval * 1000LL * 1000LL;
if ( (time->abs_value_us) / 1000LL / 1000LL != tval)
{
/* Integer overflow */
if (MHD_YES !=
@ -1047,6 +1068,24 @@ TMH_PARSE_amount_json (struct MHD_Connection *connection,
}
/**
* Generate line in parser specification for 64-bit integer
* given as an integer in JSON.
*
* @param field name of the field
* @param[out] u64 integer to initialize
* @return corresponding field spec
*/
struct TMH_PARSE_FieldSpecification
TMH_PARSE_member_uint64 (const char *field,
uint64_t *u64)
{
struct TMH_PARSE_FieldSpecification ret =
{ field, (void *) u64, sizeof (uint64_t), 0, TMH_PARSE_JNC_RET_UINT64, 0 };
return ret;
}
/**
* Generate line in parser specification for JSON object value.
*

View File

@ -133,7 +133,14 @@ enum TMH_PARSE_JsonNavigationCommand
* encoded within its own json object.
* Param: struct GNUNET_TIME_Absolute *
*/
TMH_PARSE_JNC_RET_TIME_ABSOLUTE
TMH_PARSE_JNC_RET_TIME_ABSOLUTE,
/**
* Return a `uint64_t` which was
* encoded as a JSON integer.
* Param: uint64_t *
*/
TMH_PARSE_JNC_RET_UINT64
};
@ -253,11 +260,24 @@ TMH_PARSE_release_data (struct TMH_PARSE_FieldSpecification *spec);
#define TMH_PARSE_MEMBER_VARIABLE(field) { field, NULL, 0, 0, TMH_PARSE_JNC_RET_DATA_VAR, 0 }
/**
* Generate line in parser specification for 64-bit integer
* given as an integer in JSON.
*
* @param field name of the field
* @param[out] u64 integer to initialize
* @return corresponding field spec
*/
struct TMH_PARSE_FieldSpecification
TMH_PARSE_member_uint64 (const char *field,
uint64_t *u64);
/**
* Generate line in parser specification for JSON array value.
*
* @param field name of the field
* @param ptraddr address of JSON pointer to initialize
* @param[out] jsonp address of JSON pointer to initialize
* @return corresponding field spec
*/
struct TMH_PARSE_FieldSpecification
@ -269,7 +289,7 @@ TMH_PARSE_member_array (const char *field,
* Generate line in parser specification for JSON object value.
*
* @param field name of the field
* @param jsonp address of pointer to JSON to initialize
* @param[out] jsonp address of pointer to JSON to initialize
* @return corresponding field spec
*/
struct TMH_PARSE_FieldSpecification
@ -351,8 +371,8 @@ TMH_PARSE_amount_json (struct MHD_Connection *connection,
/**
* Parse absolute time specified in JSON format. The JSON format is
* "/TIMEVAL/" where TIMEVAL is in milliseconds. Additionally, we
* support "/forever/" to represent the end of time.
* "/TIMEVAL/" where TIMEVAL is in seconds. Additionally, we
* support "/forever/" and "/never/" to represent the end of time.
*
* @param connection the MHD connection (to report errors)
* @param f json specification of the amount

View File

@ -330,6 +330,7 @@ TMH_RESPONSE_reply_invalid_json (struct MHD_Connection *connection)
* @param h_wire hash of wire details
* @param h_contract hash of contract details
* @param transaction_id transaction ID
* @param timestamp client's timestamp
* @param refund_deadline until when this deposit be refunded
* @param merchant merchant public key
* @param amount_without_fee fraction of coin value to deposit, without the fee
@ -341,6 +342,7 @@ TMH_RESPONSE_reply_deposit_success (struct MHD_Connection *connection,
const struct GNUNET_HashCode *h_wire,
const struct GNUNET_HashCode *h_contract,
uint64_t transaction_id,
struct GNUNET_TIME_Absolute timestamp,
struct GNUNET_TIME_Absolute refund_deadline,
const struct TALER_MerchantPublicKeyP *merchant,
const struct TALER_Amount *amount_without_fee)
@ -348,14 +350,13 @@ TMH_RESPONSE_reply_deposit_success (struct MHD_Connection *connection,
struct TALER_DepositConfirmationPS dc;
struct TALER_MintSignatureP sig;
json_t *sig_json;
int ret;
dc.purpose.purpose = htonl (TALER_SIGNATURE_MINT_CONFIRM_DEPOSIT);
dc.purpose.size = htonl (sizeof (struct TALER_DepositConfirmationPS));
dc.h_contract = *h_contract;
dc.h_wire = *h_wire;
dc.transaction_id = GNUNET_htonll (transaction_id);
dc.timestamp = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get ());
dc.timestamp = GNUNET_TIME_absolute_hton (timestamp);
dc.refund_deadline = GNUNET_TIME_absolute_hton (refund_deadline);
TALER_amount_hton (&dc.amount_without_fee,
amount_without_fee);
@ -363,15 +364,13 @@ TMH_RESPONSE_reply_deposit_success (struct MHD_Connection *connection,
dc.merchant = *merchant;
TMH_KS_sign (&dc.purpose,
&sig);
sig_json = TALER_json_from_eddsa_sig (&dc.purpose,
&sig.eddsa_signature);
ret = TMH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_OK,
"{s:s, s:o}",
"status", "DEPOSIT_OK",
"signature", sig_json);
json_decref (sig_json);
return ret;
sig_json = TALER_json_from_data (&sig,
sizeof (sig));
return TMH_RESPONSE_reply_json_pack (connection,
MHD_HTTP_OK,
"{s:s, s:o}",
"status", "DEPOSIT_OK",
"sig", sig_json);
}

View File

@ -205,6 +205,7 @@ TMH_RESPONSE_reply_invalid_json (struct MHD_Connection *connection);
* @param h_wire hash of wire details
* @param h_contract hash of contract details
* @param transaction_id transaction ID
* @param timestamp client's timestamp
* @param refund_deadline until when this deposit be refunded
* @param merchant merchant public key
* @param amount_without_fee fraction of coin value to deposit (without fee)
@ -216,7 +217,9 @@ TMH_RESPONSE_reply_deposit_success (struct MHD_Connection *connection,
const struct GNUNET_HashCode *h_wire,
const struct GNUNET_HashCode *h_contract,
uint64_t transaction_id,
struct GNUNET_TIME_Absolute refund_deadline, const struct TALER_MerchantPublicKeyP *merchant,
struct GNUNET_TIME_Absolute timestamp,
struct GNUNET_TIME_Absolute refund_deadline,
const struct TALER_MerchantPublicKeyP *merchant,
const struct TALER_Amount *amount_without_fee);

View File

@ -89,11 +89,13 @@ TALER_json_from_abs (struct GNUNET_TIME_Absolute stamp)
char *mystr;
int ret;
GNUNET_assert (GNUNET_OK ==
TALER_round_abs_time (&stamp));
if (stamp.abs_value_us == GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us)
return json_string ("/never/");
ret = GNUNET_asprintf (&mystr,
"/%llu/",
(long long) (stamp.abs_value_us / (1000LL * 1000LL)));
"/Date(%llu)/",
(unsigned long long) (stamp.abs_value_us / (1000LL * 1000LL)));
GNUNET_assert (ret > 0);
j = json_string (mystr);
GNUNET_free (mystr);
@ -320,7 +322,7 @@ TALER_json_to_amount (json_t *json,
/**
* Parse given JSON object to Amount
* Parse given JSON object to absolute time.
*
* @param json the json object representing Amount
* @param[out] abs where the amount has to be written
@ -331,9 +333,7 @@ TALER_json_to_abs (json_t *json,
struct GNUNET_TIME_Absolute *abs)
{
const char *val;
size_t slen;
unsigned long long int tval;
char *endp;
val = json_string_value (json);
if (NULL == val)
@ -341,14 +341,6 @@ TALER_json_to_abs (json_t *json,
GNUNET_break_op (0);
return GNUNET_SYSERR;
}
slen = strlen (val);
if ( (slen <= 2) ||
('/' != val[0]) ||
('/' != val[slen - 1]) )
{
GNUNET_break_op (0);
return GNUNET_SYSERR;
}
if ( (0 == strcasecmp (val,
"/forever/")) ||
(0 == strcasecmp (val,
@ -357,10 +349,9 @@ TALER_json_to_abs (json_t *json,
*abs = GNUNET_TIME_UNIT_FOREVER_ABS;
return GNUNET_OK;
}
tval = strtoull (&val[1],
&endp,
10);
if (&val[slen - 1] != endp)
if (1 != sscanf (val,
"/Date(%llu)/",
&tval))
{
GNUNET_break_op (0);
return GNUNET_SYSERR;

View File

@ -65,7 +65,7 @@ test_time ()
struct GNUNET_TIME_Absolute a2;
a1 = GNUNET_TIME_absolute_get ();
a1.abs_value_us -= a1.abs_value_us % 1000000; /* round! */
TALER_round_abs_time (&a1);
j = TALER_json_from_abs (a1);
GNUNET_assert (NULL != j);
GNUNET_assert (GNUNET_OK ==

View File

@ -63,6 +63,46 @@ TALER_config_get_denom (struct GNUNET_CONFIGURATION_Handle *cfg,
}
/**
* Round a time value so that it is suitable for transmission
* via JSON encodings.
*
* @param at time to round
* @return #GNUNET_OK if time was already rounded, #GNUNET_NO if
* it was just now rounded
*/
int
TALER_round_abs_time (struct GNUNET_TIME_Absolute *at)
{
if (at->abs_value_us == GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us)
return GNUNET_OK;
if (0 == at->abs_value_us % 1000000)
return GNUNET_OK;
at->abs_value_us -= at->abs_value_us % 1000000;
return GNUNET_NO;
}
/**
* Round a time value so that it is suitable for transmission
* via JSON encodings.
*
* @param rt time to round
* @return #GNUNET_OK if time was already rounded, #GNUNET_NO if
* it was just now rounded
*/
int
TALER_round_rel_time (struct GNUNET_TIME_Relative *rt)
{
if (rt->rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us)
return GNUNET_OK;
if (0 == rt->rel_value_us % 1000000)
return GNUNET_OK;
rt->rel_value_us -= rt->rel_value_us % 1000000;
return GNUNET_NO;
}
/**
* Load configuration by parsing all configuration
* files in the given directory.

View File

@ -330,7 +330,7 @@ validate_sepa (const json_t *wire)
((json_t *) wire,
&error, JSON_STRICT,
"{"
"s:s " /* type: "SEPA" */
"s:s " /* TYPE: sepa */
"s:s " /* IBAN: iban */
"s:s " /* name: beneficiary name */
"s:s " /* BIC: beneficiary bank's BIC */
@ -345,7 +345,6 @@ validate_sepa (const json_t *wire)
"edate", &edate,
"r", &r,
"address", &address));
EXITIF (0 != strcmp (type, "SEPA"));
if (1 != validate_iban (iban))
{
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
@ -359,6 +358,20 @@ validate_sepa (const json_t *wire)
}
/**
* Validate TEST account details. The "test" format is used
* for testing, so this validator does nothing.
*
* @param wire JSON with the TEST details
* @return #GNUNET_YES if correctly formatted; #GNUNET_NO if not
*/
static int
validate_test (const json_t *wire)
{
return GNUNET_YES;
}
/**
* Handler for a wire format.
*/
@ -392,9 +405,29 @@ TALER_json_validate_wireformat (const char *type,
{
static const struct FormatHandler format_handlers[] = {
{ "SEPA", &validate_sepa },
{ "TEST", &validate_test },
{ NULL, NULL}
};
unsigned int i;
char *stype;
json_error_t error;
UNPACK_EXITIF (0 != json_unpack_ex
((json_t *) wire,
&error, 0,
"{"
"s:s " /* TYPE: type */
"}",
"type", &stype));
if (0 != strcasecmp (type,
stype))
{
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Wireformat `%s' does not match mint's expected `%s' format\n",
stype,
type);
return GNUNET_NO;
}
for (i=0;NULL != format_handlers[i].type;i++)
if (0 == strcasecmp (format_handlers[i].type,
@ -404,6 +437,8 @@ TALER_json_validate_wireformat (const char *type,
"Wireformat `%s' not supported\n",
type);
return GNUNET_NO;
EXITIF_exit:
return GNUNET_NO;
}
/* end of wireformats.c */