misc bugfixes from tests
This commit is contained in:
parent
f623214c12
commit
922323b410
@ -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);
|
||||
|
@ -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.
|
||||
|
@ -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))
|
||||
{
|
||||
|
@ -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),
|
||||
|
@ -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
|
||||
|
@ -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 (×tamp);
|
||||
{
|
||||
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,
|
||||
|
@ -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 (¶ms->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 (¶ms->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 (¶ms->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 (¶ms->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);
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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))
|
||||
@ -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))
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
*
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
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",
|
||||
"signature", sig_json);
|
||||
json_decref (sig_json);
|
||||
return ret;
|
||||
"sig", sig_json);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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 ==
|
||||
|
@ -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.
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user