handle reserve open/close responses in reserve history in libtalerexchange

This commit is contained in:
Christian Grothoff 2022-10-15 22:03:55 +02:00
parent 7421142bc1
commit 518c7009e7
No known key found for this signature in database
GPG Key ID: 939E6BE1E29FC3CC
5 changed files with 216 additions and 13 deletions

View File

@ -1505,7 +1505,7 @@ enum TALER_EXCHANGE_ReserveTransactionType
/**
* Reserve closed operation.
*/
TALER_EXCHANGE_RTT_CLOSE,
TALER_EXCHANGE_RTT_CLOSING,
/**
* Reserve history request.
@ -1513,9 +1513,19 @@ enum TALER_EXCHANGE_ReserveTransactionType
TALER_EXCHANGE_RTT_HISTORY,
/**
* Reserve purese merge operation.
* Reserve purse merge operation.
*/
TALER_EXCHANGE_RTT_MERGE
TALER_EXCHANGE_RTT_MERGE,
/**
* Reserve open request operation.
*/
TALER_EXCHANGE_RTT_OPEN,
/**
* Reserve close request operation.
*/
TALER_EXCHANGE_RTT_CLOSE
};
@ -1730,6 +1740,71 @@ struct TALER_EXCHANGE_ReserveHistoryEntry
} merge_details;
/**
* Information about an open request operation on the reserve.
* @e type is #TALER_EXCHANGE_RTT_OPEN.
*/
struct
{
/**
* Signature by the reserve approving the open.
*/
struct TALER_ReserveSignatureP reserve_sig;
/**
* Amount to be paid from the reserve balance to open
* the reserve.
*/
struct TALER_Amount reserve_payment;
/**
* When was the request created.
*/
struct GNUNET_TIME_Timestamp request_timestamp;
/**
* For how long should the reserve be kept open.
* (Determines amount to be paid.)
*/
struct GNUNET_TIME_Timestamp reserve_expiration;
/**
* How many open purses should be included with the
* open reserve?
* (Determines amount to be paid.)
*/
uint32_t purse_limit;
} open_request;
/**
* Information about an close request operation on the reserve.
* @e type is #TALER_EXCHANGE_RTT_CLOSE.
*/
struct
{
/**
* Signature by the reserve approving the close.
*/
struct TALER_ReserveSignatureP reserve_sig;
/**
* When was the request created.
*/
struct GNUNET_TIME_Timestamp request_timestamp;
/**
* Hash of the payto://-URI of the target account
* for the closure, or all zeros for the reserve
* origin account.
*/
struct TALER_PaytoHashP target_account_h_payto;
} close_request;
} details;
};

View File

@ -340,7 +340,7 @@ parse_closing (struct TALER_EXCHANGE_ReserveHistoryEntry *rh,
GNUNET_JSON_spec_end ()
};
rh->type = TALER_EXCHANGE_RTT_CLOSE;
rh->type = TALER_EXCHANGE_RTT_CLOSING;
if (GNUNET_OK !=
GNUNET_JSON_parse (transaction,
closing_spec,
@ -531,6 +531,120 @@ parse_history (struct TALER_EXCHANGE_ReserveHistoryEntry *rh,
}
/**
* Parse "open" reserve open entry.
*
* @param[in,out] rh entry to parse
* @param uc our context
* @param transaction the transaction to parse
* @return #GNUNET_OK on success
*/
static enum GNUNET_GenericReturnValue
parse_open (struct TALER_EXCHANGE_ReserveHistoryEntry *rh,
struct HistoryParseContext *uc,
const json_t *transaction)
{
struct GNUNET_JSON_Specification open_spec[] = {
GNUNET_JSON_spec_fixed_auto ("reserve_sig",
&rh->details.open_request.reserve_sig),
TALER_JSON_spec_amount_any ("open_payment",
&rh->details.open_request.reserve_payment),
GNUNET_JSON_spec_uint32 ("requested_min_purses",
&rh->details.open_request.purse_limit),
GNUNET_JSON_spec_timestamp ("request_timestamp",
&rh->details.open_request.request_timestamp),
GNUNET_JSON_spec_timestamp ("requested_expiration",
&rh->details.open_request.reserve_expiration),
GNUNET_JSON_spec_end ()
};
rh->type = TALER_EXCHANGE_RTT_OPEN;
if (GNUNET_OK !=
GNUNET_JSON_parse (transaction,
open_spec,
NULL, NULL))
{
GNUNET_break_op (0);
return GNUNET_SYSERR;
}
if (GNUNET_OK !=
TALER_wallet_reserve_open_verify (
&rh->amount,
rh->details.open_request.request_timestamp,
rh->details.open_request.reserve_expiration,
rh->details.open_request.purse_limit,
uc->reserve_pub,
&rh->details.open_request.reserve_sig))
{
GNUNET_break_op (0);
return GNUNET_SYSERR;
}
if (0 >
TALER_amount_add (uc->total_out,
uc->total_out,
&rh->amount))
{
/* overflow in history already!? inconceivable! Bad exchange! */
GNUNET_break_op (0);
return GNUNET_SYSERR;
}
return GNUNET_OK;
}
/**
* Parse "close" reserve close entry.
*
* @param[in,out] rh entry to parse
* @param uc our context
* @param transaction the transaction to parse
* @return #GNUNET_OK on success
*/
static enum GNUNET_GenericReturnValue
parse_close (struct TALER_EXCHANGE_ReserveHistoryEntry *rh,
struct HistoryParseContext *uc,
const json_t *transaction)
{
struct GNUNET_JSON_Specification close_spec[] = {
GNUNET_JSON_spec_fixed_auto ("reserve_sig",
&rh->details.close_request.reserve_sig),
GNUNET_JSON_spec_mark_optional (
GNUNET_JSON_spec_fixed_auto ("h_payto",
&rh->details.close_request.
target_account_h_payto),
NULL),
GNUNET_JSON_spec_timestamp ("request_timestamp",
&rh->details.close_request.request_timestamp),
GNUNET_JSON_spec_end ()
};
rh->type = TALER_EXCHANGE_RTT_CLOSE;
if (GNUNET_OK !=
GNUNET_JSON_parse (transaction,
close_spec,
NULL, NULL))
{
GNUNET_break_op (0);
return GNUNET_SYSERR;
}
/* force amount to invalid */
memset (&rh->amount,
0,
sizeof (rh->amount));
if (GNUNET_OK !=
TALER_wallet_reserve_close_verify (
rh->details.close_request.request_timestamp,
&rh->details.close_request.target_account_h_payto,
uc->reserve_pub,
&rh->details.close_request.reserve_sig))
{
GNUNET_break_op (0);
return GNUNET_SYSERR;
}
return GNUNET_OK;
}
enum GNUNET_GenericReturnValue
TALER_EXCHANGE_parse_reserve_history (
struct TALER_EXCHANGE_Handle *exchange,
@ -553,6 +667,8 @@ TALER_EXCHANGE_parse_reserve_history (
{ "MERGE", &parse_merge },
{ "CLOSING", &parse_closing },
{ "HISTORY", &parse_history },
{ "OPEN", &parse_open },
{ "CLOSE", &parse_close },
{ NULL, NULL }
};
struct GNUNET_HashCode uuid[history_length];
@ -651,12 +767,16 @@ TALER_EXCHANGE_free_reserve_history (
break;
case TALER_EXCHANGE_RTT_RECOUP:
break;
case TALER_EXCHANGE_RTT_CLOSE:
case TALER_EXCHANGE_RTT_CLOSING:
break;
case TALER_EXCHANGE_RTT_HISTORY:
break;
case TALER_EXCHANGE_RTT_MERGE:
break;
case TALER_EXCHANGE_RTT_OPEN:
break;
case TALER_EXCHANGE_RTT_CLOSE:
break;
}
}
GNUNET_free (rhistory);
@ -1253,6 +1373,8 @@ TALER_EXCHANGE_verify_coin_history (
{ "RECOUP-REFRESH", &help_recoup_refresh },
{ "OLD-COIN-RECOUP", &help_old_coin_recoup },
{ "PURSE-DEPOSIT", &help_purse_deposit },
// FIXME: PURSE-REFUND missing here!
// FIXME: RESERVE-DEPOSIT missing here!
{ NULL, NULL }
};
struct CoinHistoryParseContext pc = {

View File

@ -70,7 +70,7 @@ TALER_TESTING_history_entry_cmp (
&h2->details.recoup_details.coin_pub)) )
return 0;
return 1;
case TALER_EXCHANGE_RTT_CLOSE:
case TALER_EXCHANGE_RTT_CLOSING:
/* testing_api_cmd_exec_closer doesn't set the
receiver_account_details, exchange_sig, exchange_pub or wtid or timestamp
so we cannot test for it here. but if the amount matches,
@ -130,6 +130,12 @@ TALER_TESTING_history_entry_cmp (
h2->details.merge_details.flags) )
return 0;
return 1;
case TALER_EXCHANGE_RTT_OPEN:
// FIXME: verify response...
return 1;
case TALER_EXCHANGE_RTT_CLOSE:
// FIXME: verify response...
return 1;
}
GNUNET_assert (0);
return 1;

View File

@ -221,11 +221,11 @@ TALER_TESTING_cmd_exec_closer (const char *label,
/* expected amount includes fee, while our argument
gives the amount _without_ the fee. So add the fee. */
GNUNET_assert (0 <=
TALER_amount_add (&as->reserve_history.amount,
TALER_amount_add (
&as->reserve_history.amount,
&as->reserve_history.details.close_details.
fee));
as->reserve_history.type = TALER_EXCHANGE_RTT_CLOSE;
&as->reserve_history.amount,
&as->reserve_history.details.close_details.fee));
as->reserve_history.type = TALER_EXCHANGE_RTT_CLOSING;
}
{
struct TALER_TESTING_Command cmd = {

View File

@ -1237,7 +1237,7 @@ TALER_wallet_account_merge_verify (
GNUNET_NETWORK_STRUCT_BEGIN
/**
* Message signed by
* Message signed by reserve key.
*/
struct TALER_ReserveOpenPS
{
@ -1404,7 +1404,7 @@ TALER_wallet_reserve_open_deposit_verify (
GNUNET_NETWORK_STRUCT_BEGIN
/**
* Message signed by
* Message signed by reserve key.
*/
struct TALER_ReserveClosePS
{