2015-06-09 17:35:33 +02:00
|
|
|
/*
|
2015-06-10 14:59:14 +02:00
|
|
|
This file is part of TALER
|
2016-04-20 01:50:26 +02:00
|
|
|
Copyright (C) 2014, 2015, 2016 Inria & GNUnet e.V.
|
2015-06-09 17:35:33 +02:00
|
|
|
|
2015-06-10 14:59:14 +02:00
|
|
|
TALER is free software; you can redistribute it and/or modify it under the
|
|
|
|
terms of the GNU General Public License as published by the Free Software
|
|
|
|
Foundation; either version 3, or (at your option) any later version.
|
2015-06-09 17:35:33 +02:00
|
|
|
|
2015-06-10 14:59:14 +02:00
|
|
|
TALER is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
|
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
|
|
|
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
2015-06-09 17:35:33 +02:00
|
|
|
|
2015-06-10 14:59:14 +02:00
|
|
|
You should have received a copy of the GNU General Public License along with
|
|
|
|
TALER; see the file COPYING. If not, If not, see <http://www.gnu.org/licenses/>
|
|
|
|
*/
|
2015-06-09 17:35:33 +02:00
|
|
|
/**
|
2016-03-01 15:35:04 +01:00
|
|
|
* @file exchangedb/perf_taler_exchangedb_init.c
|
|
|
|
* @brief Interpreter library for exchange database performance analysis
|
2015-06-09 17:35:33 +02:00
|
|
|
* @author Nicolas Fournier
|
2016-04-20 01:50:26 +02:00
|
|
|
* @author Christian Grothoff
|
2015-06-09 17:35:33 +02:00
|
|
|
*/
|
2015-06-12 09:09:42 +02:00
|
|
|
#include "platform.h"
|
2016-03-01 15:35:04 +01:00
|
|
|
#include "perf_taler_exchangedb_init.h"
|
2015-06-09 13:03:37 +02:00
|
|
|
#include <gnunet/gnunet_signatures.h>
|
2015-06-12 09:09:42 +02:00
|
|
|
#include "taler_signatures.h"
|
|
|
|
#include "taler_amount_lib.h"
|
2015-06-09 13:03:37 +02:00
|
|
|
|
|
|
|
|
2015-06-09 17:35:33 +02:00
|
|
|
#define CURRENCY "EUR"
|
2016-03-01 15:35:04 +01:00
|
|
|
#define PERF_TALER_EXCHANGEDB_RSA_SIZE 512
|
2015-06-09 13:03:37 +02:00
|
|
|
|
2015-06-10 14:59:14 +02:00
|
|
|
|
2015-06-11 15:55:46 +02:00
|
|
|
/**
|
2015-06-30 09:23:04 +02:00
|
|
|
* Generate a dummy DenominationKeyInformation for testing purposes
|
|
|
|
* @return a dummy denomination key
|
2015-06-11 15:55:46 +02:00
|
|
|
*/
|
2016-03-01 15:35:04 +01:00
|
|
|
struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *
|
|
|
|
PERF_TALER_EXCHANGEDB_denomination_init ()
|
2015-06-09 13:55:05 +02:00
|
|
|
{
|
2015-06-30 09:23:04 +02:00
|
|
|
struct GNUNET_CRYPTO_EddsaPrivateKey *master_prvt;
|
2016-03-01 15:35:04 +01:00
|
|
|
struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki;
|
2015-07-15 15:49:39 +02:00
|
|
|
struct TALER_DenominationPrivateKey denom_priv;
|
|
|
|
struct TALER_DenominationPublicKey denom_pub;
|
2016-03-01 15:35:04 +01:00
|
|
|
struct TALER_EXCHANGEDB_DenominationKeyInformationP issue;
|
2015-07-15 15:49:39 +02:00
|
|
|
|
|
|
|
master_prvt = GNUNET_CRYPTO_eddsa_key_create();
|
2015-06-09 13:55:05 +02:00
|
|
|
|
2016-03-01 15:35:04 +01:00
|
|
|
dki = GNUNET_new (struct TALER_EXCHANGEDB_DenominationKeyIssueInformation);
|
2015-07-16 17:21:25 +02:00
|
|
|
GNUNET_assert (NULL != dki);
|
|
|
|
denom_priv.rsa_private_key
|
2016-03-01 15:35:04 +01:00
|
|
|
= GNUNET_CRYPTO_rsa_private_key_create (PERF_TALER_EXCHANGEDB_RSA_SIZE);
|
2015-07-16 17:21:25 +02:00
|
|
|
GNUNET_assert (NULL != denom_priv.rsa_private_key);
|
|
|
|
denom_pub.rsa_public_key =
|
|
|
|
GNUNET_CRYPTO_rsa_private_key_get_public (denom_priv.rsa_private_key);
|
|
|
|
GNUNET_assert (NULL != denom_pub.rsa_public_key);
|
2015-07-15 15:49:39 +02:00
|
|
|
{/* issue */
|
|
|
|
struct TALER_MasterSignatureP signature;
|
|
|
|
struct TALER_DenominationKeyValidityPS properties;
|
|
|
|
|
|
|
|
{/* properties */
|
|
|
|
struct TALER_Amount amount;
|
|
|
|
|
|
|
|
properties.purpose.purpose = htonl (TALER_SIGNATURE_MASTER_SIGNING_KEY_VALIDITY);
|
|
|
|
properties.purpose.size = htonl (sizeof (struct TALER_DenominationKeyValidityPS));
|
|
|
|
GNUNET_CRYPTO_eddsa_key_get_public (master_prvt,
|
|
|
|
&properties.master.eddsa_pub);
|
|
|
|
properties.start = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get());
|
|
|
|
properties.expire_withdraw = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get_forever_());
|
2016-05-02 05:10:40 +02:00
|
|
|
properties.expire_deposit = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get_forever_());
|
2015-07-15 15:49:39 +02:00
|
|
|
properties.expire_legal = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get_forever_());
|
2016-01-21 15:52:10 +01:00
|
|
|
GNUNET_assert (GNUNET_OK ==
|
|
|
|
TALER_string_to_amount (CURRENCY ":1.1", &amount));
|
2015-07-15 15:49:39 +02:00
|
|
|
TALER_amount_hton (&properties.value, &amount);
|
2016-01-21 15:52:10 +01:00
|
|
|
GNUNET_assert (GNUNET_OK ==
|
|
|
|
TALER_string_to_amount (CURRENCY ":0.1", &amount));
|
2015-07-15 15:49:39 +02:00
|
|
|
TALER_amount_hton (&properties.fee_withdraw, &amount);
|
|
|
|
TALER_amount_hton (&properties.fee_deposit, &amount);
|
|
|
|
TALER_amount_hton (&properties.fee_refresh, &amount);
|
2016-04-20 01:50:26 +02:00
|
|
|
TALER_amount_hton (&properties.fee_refund, &amount);
|
2015-07-15 15:49:39 +02:00
|
|
|
GNUNET_CRYPTO_rsa_public_key_hash (denom_pub.rsa_public_key,
|
|
|
|
&properties.denom_hash);
|
|
|
|
issue.properties = properties;
|
|
|
|
}
|
|
|
|
{/* signature */
|
|
|
|
GNUNET_CRYPTO_eddsa_sign (master_prvt,
|
|
|
|
&properties.purpose,
|
|
|
|
&signature.eddsa_signature);
|
|
|
|
issue.signature = signature;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
dki->denom_priv = denom_priv;
|
|
|
|
dki->denom_pub = denom_pub;
|
|
|
|
dki->issue = issue;
|
2015-06-30 09:23:04 +02:00
|
|
|
GNUNET_free (master_prvt);
|
|
|
|
return dki;
|
2015-06-09 13:03:37 +02:00
|
|
|
}
|
|
|
|
|
2015-06-26 15:32:20 +02:00
|
|
|
|
2015-06-30 09:23:04 +02:00
|
|
|
/**
|
|
|
|
* Copies the given denomination
|
|
|
|
* @param reserve the deposit copy
|
|
|
|
* @return a copy of @a deposit; NULL if error
|
|
|
|
*/
|
2016-03-01 15:35:04 +01:00
|
|
|
struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *
|
|
|
|
PERF_TALER_EXCHANGEDB_denomination_copy (const struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki)
|
2015-06-26 15:32:20 +02:00
|
|
|
{
|
2016-03-01 15:35:04 +01:00
|
|
|
struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *copy;
|
2015-06-26 15:32:20 +02:00
|
|
|
|
2015-06-30 09:23:04 +02:00
|
|
|
GNUNET_assert (NULL !=
|
2016-03-01 15:35:04 +01:00
|
|
|
(copy = GNUNET_new (struct TALER_EXCHANGEDB_DenominationKeyIssueInformation)));
|
2015-07-15 15:49:39 +02:00
|
|
|
{/* denom_priv */
|
|
|
|
copy->denom_priv.rsa_private_key =
|
|
|
|
GNUNET_CRYPTO_rsa_private_key_dup ( dki->denom_priv.rsa_private_key);
|
|
|
|
}
|
|
|
|
{/* denom_pub */
|
2015-08-06 12:46:15 +02:00
|
|
|
copy->denom_pub.rsa_public_key =
|
2015-07-15 15:49:39 +02:00
|
|
|
GNUNET_CRYPTO_rsa_public_key_dup (dki->denom_pub.rsa_public_key);
|
|
|
|
}
|
|
|
|
{/* issue */
|
|
|
|
copy->issue.properties = dki->issue.properties;
|
|
|
|
copy->issue.signature = dki->issue.signature;
|
|
|
|
}
|
2015-06-26 15:32:20 +02:00
|
|
|
return copy;
|
|
|
|
}
|
|
|
|
|
2015-06-30 09:23:04 +02:00
|
|
|
|
2015-06-09 17:35:33 +02:00
|
|
|
/**
|
2015-06-30 09:23:04 +02:00
|
|
|
* Free memory of a DenominationKeyIssueInformation
|
|
|
|
* @param dki pointer to the struct to free
|
2015-06-09 17:35:33 +02:00
|
|
|
*/
|
|
|
|
int
|
2016-03-01 15:35:04 +01:00
|
|
|
PERF_TALER_EXCHANGEDB_denomination_free (struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki)
|
2015-06-09 17:35:33 +02:00
|
|
|
{
|
2015-08-06 18:19:59 +02:00
|
|
|
if (NULL == dki)
|
2015-06-11 15:55:46 +02:00
|
|
|
return GNUNET_OK;
|
2015-06-30 09:23:04 +02:00
|
|
|
GNUNET_CRYPTO_rsa_private_key_free (dki->denom_priv.rsa_private_key);
|
|
|
|
GNUNET_CRYPTO_rsa_public_key_free (dki->denom_pub.rsa_public_key);
|
2015-06-12 11:14:32 +02:00
|
|
|
|
2015-08-06 14:56:24 +02:00
|
|
|
GNUNET_free (dki);
|
2015-06-09 17:35:33 +02:00
|
|
|
return GNUNET_OK;
|
|
|
|
}
|
|
|
|
|
2015-06-09 13:03:37 +02:00
|
|
|
|
2015-06-09 17:35:33 +02:00
|
|
|
/**
|
2015-06-30 09:23:04 +02:00
|
|
|
* Generate a dummy reserve for testing
|
|
|
|
* @return a reserve with 1000 EUR in it
|
2015-06-09 17:35:33 +02:00
|
|
|
*/
|
2016-03-01 15:35:04 +01:00
|
|
|
struct PERF_TALER_EXCHANGEDB_Reserve *
|
|
|
|
PERF_TALER_EXCHANGEDB_reserve_init ()
|
2015-06-09 17:35:33 +02:00
|
|
|
{
|
2016-03-01 15:35:04 +01:00
|
|
|
struct PERF_TALER_EXCHANGEDB_Reserve *reserve;
|
2015-06-11 15:55:46 +02:00
|
|
|
|
2015-06-12 09:09:42 +02:00
|
|
|
GNUNET_assert (NULL !=
|
2016-03-01 15:35:04 +01:00
|
|
|
(reserve = GNUNET_new (struct PERF_TALER_EXCHANGEDB_Reserve)));
|
2015-07-15 16:28:12 +02:00
|
|
|
{/* private */
|
|
|
|
struct GNUNET_CRYPTO_EddsaPrivateKey *private;
|
2015-08-06 14:56:24 +02:00
|
|
|
private = GNUNET_CRYPTO_eddsa_key_create ();
|
|
|
|
GNUNET_assert (NULL != private);
|
2015-07-15 16:28:12 +02:00
|
|
|
reserve->private = *private;
|
2015-08-06 14:56:24 +02:00
|
|
|
GNUNET_free (private);
|
2015-07-15 16:28:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
GNUNET_CRYPTO_eddsa_key_get_public (&reserve->private,
|
|
|
|
&reserve->reserve.pub.eddsa_pub);
|
2015-06-12 09:09:42 +02:00
|
|
|
GNUNET_assert (GNUNET_OK ==
|
2015-07-15 16:28:12 +02:00
|
|
|
TALER_string_to_amount (CURRENCY ":1000", &reserve->reserve.balance));
|
|
|
|
reserve->reserve.expiry = GNUNET_TIME_absolute_get_forever_ ();
|
2015-06-10 14:59:14 +02:00
|
|
|
return reserve;
|
|
|
|
}
|
2015-06-09 13:03:37 +02:00
|
|
|
|
2015-06-11 15:55:46 +02:00
|
|
|
|
2015-06-30 09:23:04 +02:00
|
|
|
/**
|
|
|
|
* Copies the given reserve
|
|
|
|
* @param reserve the reserve to copy
|
|
|
|
* @return a copy of @a reserve; NULL if error
|
|
|
|
*/
|
2016-03-01 15:35:04 +01:00
|
|
|
struct PERF_TALER_EXCHANGEDB_Reserve *
|
|
|
|
PERF_TALER_EXCHANGEDB_reserve_copy (const struct PERF_TALER_EXCHANGEDB_Reserve *reserve)
|
2015-06-26 15:32:20 +02:00
|
|
|
{
|
2016-03-01 15:35:04 +01:00
|
|
|
struct PERF_TALER_EXCHANGEDB_Reserve *copy;
|
2015-08-06 12:46:15 +02:00
|
|
|
GNUNET_assert (NULL !=
|
2016-03-01 15:35:04 +01:00
|
|
|
(copy = GNUNET_new (struct PERF_TALER_EXCHANGEDB_Reserve)));
|
2015-06-26 15:32:20 +02:00
|
|
|
*copy = *reserve;
|
|
|
|
return copy;
|
2015-08-06 12:46:15 +02:00
|
|
|
}
|
2015-06-26 15:32:20 +02:00
|
|
|
|
2015-07-09 10:46:33 +02:00
|
|
|
|
2015-06-11 15:55:46 +02:00
|
|
|
/**
|
|
|
|
* Free memory of a reserve
|
2015-06-30 09:23:04 +02:00
|
|
|
* @param reserve pointer to the structure to be freed
|
2015-06-11 15:55:46 +02:00
|
|
|
*/
|
2015-06-10 14:59:14 +02:00
|
|
|
int
|
2016-03-01 15:35:04 +01:00
|
|
|
PERF_TALER_EXCHANGEDB_reserve_free (struct PERF_TALER_EXCHANGEDB_Reserve *reserve)
|
2015-06-09 17:35:33 +02:00
|
|
|
{
|
2015-06-26 15:32:20 +02:00
|
|
|
if (NULL == reserve)
|
|
|
|
return GNUNET_OK;
|
2015-08-06 14:56:24 +02:00
|
|
|
GNUNET_free (reserve);
|
2015-06-10 14:59:14 +02:00
|
|
|
return GNUNET_OK;
|
2015-06-09 13:03:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-06-10 14:59:14 +02:00
|
|
|
/**
|
2015-06-30 09:23:04 +02:00
|
|
|
* Generate a dummy deposit for testing purposes
|
|
|
|
* @param dki the denomination key used to sign the key
|
2015-06-10 14:59:14 +02:00
|
|
|
*/
|
2016-03-01 15:35:04 +01:00
|
|
|
struct TALER_EXCHANGEDB_Deposit *
|
|
|
|
PERF_TALER_EXCHANGEDB_deposit_init (const struct PERF_TALER_EXCHANGEDB_Coin *coin)
|
2015-06-10 14:59:14 +02:00
|
|
|
{
|
2016-03-01 15:35:04 +01:00
|
|
|
struct TALER_EXCHANGEDB_Deposit *deposit;
|
2015-06-17 15:08:40 +02:00
|
|
|
struct TALER_CoinSpendSignatureP csig;
|
|
|
|
struct TALER_MerchantPublicKeyP merchant_pub;
|
|
|
|
struct GNUNET_HashCode h_contract;
|
|
|
|
struct GNUNET_HashCode h_wire;
|
|
|
|
const char wire[] = "{"
|
|
|
|
"\"type\":\"SEPA\","
|
|
|
|
"\"IBAN\":\"DE67830654080004822650\","
|
|
|
|
"\"NAME\":\"GNUNET E.\","
|
|
|
|
"\"BIC\":\"GENODEF1SRL\""
|
|
|
|
"}";
|
|
|
|
static uint64_t transaction_id = 0;
|
2015-08-06 12:46:15 +02:00
|
|
|
struct GNUNET_TIME_Absolute timestamp;
|
|
|
|
struct GNUNET_TIME_Absolute refund_deadline;
|
2015-06-17 15:08:40 +02:00
|
|
|
struct TALER_Amount amount_with_fee;
|
|
|
|
struct TALER_Amount deposit_fee;
|
2015-06-09 13:55:05 +02:00
|
|
|
|
2015-06-10 14:59:14 +02:00
|
|
|
GNUNET_assert (NULL !=
|
2016-03-01 15:35:04 +01:00
|
|
|
(deposit = GNUNET_malloc (sizeof (struct TALER_EXCHANGEDB_Deposit) + sizeof (wire))));
|
2015-07-16 17:21:25 +02:00
|
|
|
GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_WEAK,
|
|
|
|
&h_contract);
|
|
|
|
GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_WEAK,
|
|
|
|
&h_wire);
|
2015-06-17 15:08:40 +02:00
|
|
|
{ //csig
|
2015-06-10 14:59:14 +02:00
|
|
|
struct u32_presign
|
2015-06-09 13:03:37 +02:00
|
|
|
{
|
2015-06-10 14:59:14 +02:00
|
|
|
struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
|
2015-07-16 17:21:25 +02:00
|
|
|
struct GNUNET_HashCode h_wire;
|
|
|
|
struct GNUNET_HashCode h_contract;
|
2015-06-10 14:59:14 +02:00
|
|
|
} unsigned_data;
|
2015-06-11 15:55:46 +02:00
|
|
|
|
2015-07-16 17:21:25 +02:00
|
|
|
unsigned_data.h_contract = h_contract;
|
|
|
|
unsigned_data.h_wire = h_wire;
|
2015-06-12 09:09:42 +02:00
|
|
|
unsigned_data.purpose.size = htonl (sizeof (struct u32_presign));
|
|
|
|
unsigned_data.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_TEST);
|
2015-06-10 14:59:14 +02:00
|
|
|
GNUNET_assert (GNUNET_OK ==
|
2015-07-15 18:06:50 +02:00
|
|
|
GNUNET_CRYPTO_eddsa_sign (&coin->priv,
|
2015-06-12 11:14:32 +02:00
|
|
|
&unsigned_data.purpose,
|
2015-06-17 15:08:40 +02:00
|
|
|
&csig.eddsa_signature));
|
2015-06-10 14:59:14 +02:00
|
|
|
}
|
2015-06-17 15:08:40 +02:00
|
|
|
{ //merchant_pub
|
2015-06-12 09:09:42 +02:00
|
|
|
struct GNUNET_CRYPTO_EddsaPrivateKey *eddsa_prv;
|
2015-06-10 14:59:14 +02:00
|
|
|
|
2015-07-16 17:21:25 +02:00
|
|
|
eddsa_prv = GNUNET_CRYPTO_eddsa_key_create ();
|
|
|
|
GNUNET_assert(NULL != eddsa_prv);
|
2015-06-10 14:59:14 +02:00
|
|
|
GNUNET_CRYPTO_eddsa_key_get_public (
|
2015-06-30 09:23:04 +02:00
|
|
|
eddsa_prv,
|
|
|
|
&merchant_pub.eddsa_pub);
|
2015-06-12 11:14:32 +02:00
|
|
|
GNUNET_free (eddsa_prv);
|
2015-06-10 14:59:14 +02:00
|
|
|
}
|
2015-06-17 15:08:40 +02:00
|
|
|
timestamp = GNUNET_TIME_absolute_get ();
|
|
|
|
refund_deadline = GNUNET_TIME_absolute_get ();
|
|
|
|
GNUNET_assert (GNUNET_OK ==
|
2015-08-06 12:46:15 +02:00
|
|
|
TALER_string_to_amount (CURRENCY ":1.1",
|
2015-06-17 15:08:40 +02:00
|
|
|
&amount_with_fee));
|
|
|
|
GNUNET_assert (GNUNET_OK ==
|
2015-08-06 12:46:15 +02:00
|
|
|
TALER_string_to_amount (CURRENCY ":0.1",
|
2015-06-17 15:08:40 +02:00
|
|
|
&deposit_fee));
|
2015-07-16 17:21:25 +02:00
|
|
|
{
|
|
|
|
deposit->coin.coin_pub = coin->public_info.coin_pub;
|
|
|
|
deposit->coin.denom_pub.rsa_public_key = GNUNET_CRYPTO_rsa_public_key_dup (
|
|
|
|
coin->public_info.denom_pub.rsa_public_key);
|
|
|
|
GNUNET_assert (NULL != coin->public_info.denom_pub.rsa_public_key);
|
|
|
|
deposit->coin.denom_sig.rsa_signature = GNUNET_CRYPTO_rsa_signature_dup (
|
|
|
|
coin->public_info.denom_sig.rsa_signature);
|
|
|
|
GNUNET_assert (NULL != coin->public_info.denom_sig.rsa_signature);
|
|
|
|
}
|
2015-06-17 15:08:40 +02:00
|
|
|
deposit->csig = csig;
|
|
|
|
deposit->h_contract = h_contract;
|
|
|
|
deposit->h_wire = h_wire;
|
|
|
|
deposit->wire = json_loads (wire, 0, NULL);
|
|
|
|
deposit->transaction_id = transaction_id++;
|
|
|
|
deposit->timestamp = timestamp;
|
|
|
|
deposit->refund_deadline = refund_deadline;
|
|
|
|
deposit->amount_with_fee = amount_with_fee;
|
|
|
|
deposit->deposit_fee = deposit_fee;
|
2015-06-10 14:59:14 +02:00
|
|
|
return deposit;
|
2015-06-09 13:03:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-06-30 09:23:04 +02:00
|
|
|
/**
|
|
|
|
* Copies the given deposit
|
|
|
|
* @param reserve the deposit copy
|
|
|
|
* @return a copy of @a deposit; NULL if error
|
|
|
|
*/
|
2016-03-01 15:35:04 +01:00
|
|
|
struct TALER_EXCHANGEDB_Deposit *
|
|
|
|
PERF_TALER_EXCHANGEDB_deposit_copy (const struct TALER_EXCHANGEDB_Deposit *deposit)
|
2015-06-26 15:32:20 +02:00
|
|
|
{
|
2016-03-01 15:35:04 +01:00
|
|
|
struct TALER_EXCHANGEDB_Deposit *copy;
|
2015-06-26 15:32:20 +02:00
|
|
|
|
2016-03-01 15:35:04 +01:00
|
|
|
copy = GNUNET_new (struct TALER_EXCHANGEDB_Deposit);
|
2015-06-26 15:32:20 +02:00
|
|
|
*copy = *deposit;
|
|
|
|
json_incref (copy->wire);
|
2015-08-06 12:46:15 +02:00
|
|
|
copy->coin.denom_pub.rsa_public_key =
|
2015-07-16 17:21:25 +02:00
|
|
|
GNUNET_CRYPTO_rsa_public_key_dup (deposit->coin.denom_pub.rsa_public_key);
|
|
|
|
copy->coin.denom_sig.rsa_signature =
|
|
|
|
GNUNET_CRYPTO_rsa_signature_dup (deposit->coin.denom_sig.rsa_signature);
|
2015-06-26 15:32:20 +02:00
|
|
|
return copy;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-06-10 14:59:14 +02:00
|
|
|
/**
|
|
|
|
* Free memory of a deposit
|
2015-06-30 09:23:04 +02:00
|
|
|
* @param deposit pointer to the structure to free
|
2015-06-10 14:59:14 +02:00
|
|
|
*/
|
2015-06-09 17:35:33 +02:00
|
|
|
int
|
2016-03-01 15:35:04 +01:00
|
|
|
PERF_TALER_EXCHANGEDB_deposit_free (struct TALER_EXCHANGEDB_Deposit *deposit)
|
2015-06-09 17:35:33 +02:00
|
|
|
{
|
2015-08-06 12:46:15 +02:00
|
|
|
if (NULL == deposit)
|
2015-06-11 15:55:46 +02:00
|
|
|
return GNUNET_OK;
|
2015-06-10 14:59:14 +02:00
|
|
|
GNUNET_CRYPTO_rsa_public_key_free (deposit->coin.denom_pub.rsa_public_key);
|
|
|
|
GNUNET_CRYPTO_rsa_signature_free (deposit->coin.denom_sig.rsa_signature);
|
2015-06-17 17:24:08 +02:00
|
|
|
json_decref (deposit->wire);
|
2015-08-06 14:56:24 +02:00
|
|
|
GNUNET_free (deposit);
|
2015-06-09 17:35:33 +02:00
|
|
|
return GNUNET_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-06-10 14:59:14 +02:00
|
|
|
/**
|
2015-06-30 09:23:04 +02:00
|
|
|
* Generate a CollectableBlindcoin for testing purpuses
|
|
|
|
* @param dki denomination key used to sign the coin
|
|
|
|
* @param reserve reserve providing the money for the coin
|
|
|
|
* @return a randomly generated CollectableBlindcoin
|
2015-06-10 14:59:14 +02:00
|
|
|
*/
|
2016-03-01 15:35:04 +01:00
|
|
|
struct PERF_TALER_EXCHANGEDB_Coin *
|
|
|
|
PERF_TALER_EXCHANGEDB_coin_init (
|
|
|
|
const struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki,
|
|
|
|
const struct PERF_TALER_EXCHANGEDB_Reserve *reserve)
|
2015-06-09 17:35:33 +02:00
|
|
|
{
|
2016-03-01 15:35:04 +01:00
|
|
|
struct PERF_TALER_EXCHANGEDB_Coin *coin;
|
2015-07-16 17:21:25 +02:00
|
|
|
struct GNUNET_CRYPTO_EddsaPrivateKey *priv;
|
2016-04-01 20:18:18 +02:00
|
|
|
struct GNUNET_HashCode hc;
|
2015-07-16 17:21:25 +02:00
|
|
|
|
2016-03-01 15:35:04 +01:00
|
|
|
coin = GNUNET_new (struct PERF_TALER_EXCHANGEDB_Coin);
|
2015-07-16 17:21:25 +02:00
|
|
|
GNUNET_assert (NULL != coin);
|
|
|
|
/* priv */
|
2015-06-10 14:59:14 +02:00
|
|
|
|
2015-07-16 17:21:25 +02:00
|
|
|
priv = GNUNET_CRYPTO_eddsa_key_create();
|
|
|
|
GNUNET_assert (NULL != priv);
|
|
|
|
coin->priv = *priv;
|
|
|
|
GNUNET_free (priv);
|
|
|
|
|
|
|
|
/* public_info */
|
|
|
|
GNUNET_CRYPTO_eddsa_key_get_public (&coin->priv,
|
|
|
|
&coin->public_info.coin_pub.eddsa_pub);
|
2015-08-06 17:19:11 +02:00
|
|
|
coin->public_info.denom_pub.rsa_public_key =
|
2015-08-06 14:56:24 +02:00
|
|
|
GNUNET_CRYPTO_rsa_public_key_dup (dki->denom_pub.rsa_public_key);
|
2016-04-01 20:18:18 +02:00
|
|
|
GNUNET_CRYPTO_hash (&coin->public_info.coin_pub,
|
|
|
|
sizeof (struct TALER_CoinSpendPublicKeyP),
|
|
|
|
&hc);
|
2015-08-06 17:19:11 +02:00
|
|
|
coin->public_info.denom_sig.rsa_signature =
|
2016-03-20 21:30:10 +01:00
|
|
|
GNUNET_CRYPTO_rsa_sign_fdh (dki->denom_priv.rsa_private_key,
|
2016-04-01 20:18:18 +02:00
|
|
|
&hc);
|
2015-08-06 14:56:24 +02:00
|
|
|
GNUNET_assert (NULL != coin->public_info.denom_pub.rsa_public_key);
|
|
|
|
GNUNET_assert (NULL != coin->public_info.denom_sig.rsa_signature);
|
2015-07-16 17:21:25 +02:00
|
|
|
|
|
|
|
/* blind */
|
2015-08-06 17:19:11 +02:00
|
|
|
coin->blind.sig.rsa_signature =
|
2015-08-06 14:56:24 +02:00
|
|
|
GNUNET_CRYPTO_rsa_signature_dup (coin->public_info.denom_sig.rsa_signature);
|
2015-08-06 17:19:11 +02:00
|
|
|
coin->blind.denom_pub.rsa_public_key =
|
2015-08-06 14:56:24 +02:00
|
|
|
GNUNET_CRYPTO_rsa_public_key_dup (dki->denom_pub.rsa_public_key);
|
|
|
|
GNUNET_assert (NULL != coin->blind.sig.rsa_signature);
|
|
|
|
GNUNET_assert (NULL != coin->blind.denom_pub.rsa_public_key);
|
2015-07-16 17:21:25 +02:00
|
|
|
TALER_amount_ntoh (&coin->blind.amount_with_fee,
|
|
|
|
&dki->issue.properties.value);
|
|
|
|
TALER_amount_ntoh (&coin->blind.withdraw_fee,
|
|
|
|
&dki->issue.properties.fee_withdraw);
|
|
|
|
coin->blind.reserve_pub = reserve->reserve.pub;
|
|
|
|
GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_WEAK,
|
|
|
|
&coin->blind.h_coin_envelope);
|
2015-08-06 15:42:33 +02:00
|
|
|
|
2015-06-30 09:23:04 +02:00
|
|
|
return coin;
|
2015-06-09 13:03:37 +02:00
|
|
|
}
|
|
|
|
|
2015-06-11 15:55:46 +02:00
|
|
|
|
2015-06-30 09:23:04 +02:00
|
|
|
/**
|
|
|
|
* Copies the given coin
|
2015-08-06 17:19:11 +02:00
|
|
|
*
|
2015-06-30 09:23:04 +02:00
|
|
|
* @param coin the coin to copy
|
|
|
|
* @return a copy of coin; NULL if error
|
|
|
|
*/
|
2016-03-01 15:35:04 +01:00
|
|
|
struct PERF_TALER_EXCHANGEDB_Coin *
|
|
|
|
PERF_TALER_EXCHANGEDB_coin_copy (const struct PERF_TALER_EXCHANGEDB_Coin *coin)
|
2015-06-26 15:32:20 +02:00
|
|
|
{
|
2016-03-01 15:35:04 +01:00
|
|
|
struct PERF_TALER_EXCHANGEDB_Coin *copy;
|
2015-06-26 15:32:20 +02:00
|
|
|
|
2016-03-01 15:35:04 +01:00
|
|
|
copy = GNUNET_new (struct PERF_TALER_EXCHANGEDB_Coin);
|
2015-07-16 17:21:25 +02:00
|
|
|
/* priv */
|
2015-07-15 17:46:49 +02:00
|
|
|
copy->priv = coin->priv;
|
2015-07-16 17:21:25 +02:00
|
|
|
/* public_info */
|
|
|
|
copy->public_info.coin_pub = coin->public_info.coin_pub;
|
2015-08-06 12:46:15 +02:00
|
|
|
copy->public_info.denom_pub.rsa_public_key =
|
2015-08-06 17:19:11 +02:00
|
|
|
GNUNET_CRYPTO_rsa_public_key_dup (coin->public_info.denom_pub.rsa_public_key);
|
2015-08-06 12:46:15 +02:00
|
|
|
copy->public_info.denom_sig.rsa_signature =
|
2015-07-16 17:21:25 +02:00
|
|
|
GNUNET_CRYPTO_rsa_signature_dup (coin->public_info.denom_sig.rsa_signature);
|
|
|
|
|
|
|
|
/* blind */
|
2015-08-06 12:46:15 +02:00
|
|
|
copy->blind.sig.rsa_signature =
|
2015-08-06 17:19:11 +02:00
|
|
|
GNUNET_CRYPTO_rsa_signature_dup (coin->blind.sig.rsa_signature);
|
2015-07-16 17:21:25 +02:00
|
|
|
copy->blind.denom_pub.rsa_public_key =
|
2015-08-06 17:19:11 +02:00
|
|
|
GNUNET_CRYPTO_rsa_public_key_dup (coin->blind.denom_pub.rsa_public_key);
|
2015-07-16 17:21:25 +02:00
|
|
|
copy->blind.amount_with_fee = coin->blind.amount_with_fee;
|
|
|
|
copy->blind.withdraw_fee = coin->blind.withdraw_fee;
|
|
|
|
copy->blind.reserve_pub = coin->blind.reserve_pub;
|
|
|
|
copy->blind.h_coin_envelope = coin->blind.h_coin_envelope;
|
|
|
|
copy->blind.reserve_sig = coin->blind.reserve_sig;
|
|
|
|
|
2015-06-26 15:32:20 +02:00
|
|
|
return copy;
|
|
|
|
}
|
|
|
|
|
2015-07-09 10:46:33 +02:00
|
|
|
|
2015-06-10 14:59:14 +02:00
|
|
|
/**
|
2015-08-06 17:19:11 +02:00
|
|
|
* Free memory of @a coin
|
|
|
|
*
|
2015-06-30 09:23:04 +02:00
|
|
|
* @param coin pointer to the structure to free
|
2015-06-10 14:59:14 +02:00
|
|
|
*/
|
2015-06-09 13:03:37 +02:00
|
|
|
int
|
2016-03-01 15:35:04 +01:00
|
|
|
PERF_TALER_EXCHANGEDB_coin_free (struct PERF_TALER_EXCHANGEDB_Coin *coin)
|
2015-06-09 17:35:33 +02:00
|
|
|
{
|
2015-06-30 09:23:04 +02:00
|
|
|
if (NULL == coin)
|
2015-06-11 15:55:46 +02:00
|
|
|
return GNUNET_OK;
|
2015-07-15 17:46:49 +02:00
|
|
|
GNUNET_CRYPTO_rsa_public_key_free (coin->public_info.denom_pub.rsa_public_key);
|
|
|
|
GNUNET_CRYPTO_rsa_signature_free (coin->public_info.denom_sig.rsa_signature);
|
|
|
|
GNUNET_CRYPTO_rsa_signature_free (coin->blind.sig.rsa_signature);
|
|
|
|
GNUNET_CRYPTO_rsa_public_key_free (coin->blind.denom_pub.rsa_public_key);
|
2015-08-06 14:56:24 +02:00
|
|
|
GNUNET_free (coin);
|
2015-06-30 09:23:04 +02:00
|
|
|
return GNUNET_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return a randomly generated refresh session
|
|
|
|
*/
|
2016-03-01 15:35:04 +01:00
|
|
|
struct TALER_EXCHANGEDB_RefreshSession *
|
|
|
|
PERF_TALER_EXCHANGEDB_refresh_session_init ()
|
2015-06-30 09:23:04 +02:00
|
|
|
{
|
2016-03-01 15:35:04 +01:00
|
|
|
struct TALER_EXCHANGEDB_RefreshSession *refresh_session;
|
2015-06-30 09:23:04 +02:00
|
|
|
|
|
|
|
GNUNET_assert (NULL !=
|
2016-03-01 15:35:04 +01:00
|
|
|
(refresh_session = GNUNET_new (struct TALER_EXCHANGEDB_RefreshSession)));
|
2015-06-30 09:23:04 +02:00
|
|
|
refresh_session->noreveal_index = 1;
|
|
|
|
refresh_session->num_newcoins = 1;
|
|
|
|
|
|
|
|
return refresh_session;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-07-09 10:46:33 +02:00
|
|
|
/**
|
|
|
|
* @return #GNUNET_OK if the copy was successful, #GNUNET_SYSERR if it wasn't
|
|
|
|
*/
|
|
|
|
int
|
2016-03-01 15:35:04 +01:00
|
|
|
PERF_TALER_EXCHANGEDB_refresh_session_copy (struct TALER_EXCHANGEDB_RefreshSession *session,
|
2016-05-16 11:55:47 +02:00
|
|
|
struct TALER_EXCHANGEDB_RefreshSession *copy)
|
2015-07-09 10:46:33 +02:00
|
|
|
{
|
|
|
|
*copy = *session;
|
|
|
|
return GNUNET_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-06-30 09:23:04 +02:00
|
|
|
/**
|
|
|
|
* Free a refresh session
|
|
|
|
*/
|
|
|
|
int
|
2016-03-01 15:35:04 +01:00
|
|
|
PERF_TALER_EXCHANGEDB_refresh_session_free (struct TALER_EXCHANGEDB_RefreshSession *refresh_session)
|
2015-06-30 09:23:04 +02:00
|
|
|
{
|
2015-07-09 10:46:33 +02:00
|
|
|
if (NULL == refresh_session)
|
|
|
|
return GNUNET_OK;
|
2015-08-06 14:56:24 +02:00
|
|
|
GNUNET_free (refresh_session);
|
2016-01-21 16:16:23 +01:00
|
|
|
return GNUNET_OK;
|
2015-06-09 13:03:37 +02:00
|
|
|
}
|
2015-06-12 12:09:14 +02:00
|
|
|
|
|
|
|
|
2015-07-09 10:46:33 +02:00
|
|
|
/**
|
|
|
|
* Create a melt operation
|
|
|
|
*
|
2015-08-06 12:46:15 +02:00
|
|
|
* @param session the refresh session
|
2015-07-09 10:46:33 +02:00
|
|
|
* @param dki the denomination the melted coin uses
|
2016-03-01 15:35:04 +01:00
|
|
|
* @return a pointer to a #TALER_EXCHANGEDB_RefreshMelt
|
2015-07-09 10:46:33 +02:00
|
|
|
*/
|
2016-03-01 15:35:04 +01:00
|
|
|
struct TALER_EXCHANGEDB_RefreshMelt *
|
|
|
|
PERF_TALER_EXCHANGEDB_refresh_melt_init (struct GNUNET_HashCode *session,
|
2016-04-01 20:27:57 +02:00
|
|
|
struct PERF_TALER_EXCHANGEDB_Coin *coin)
|
2015-07-09 10:46:33 +02:00
|
|
|
{
|
2016-03-01 15:35:04 +01:00
|
|
|
struct TALER_EXCHANGEDB_RefreshMelt *melt;
|
2015-07-20 10:24:09 +02:00
|
|
|
struct TALER_CoinSpendSignatureP coin_sig;
|
2015-07-09 10:46:33 +02:00
|
|
|
struct TALER_Amount amount;
|
2015-08-06 12:46:15 +02:00
|
|
|
struct TALER_Amount amount_with_fee;
|
2015-07-09 10:46:33 +02:00
|
|
|
|
|
|
|
{
|
2015-08-06 12:46:15 +02:00
|
|
|
struct
|
2015-07-09 10:46:33 +02:00
|
|
|
{
|
|
|
|
struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
|
|
|
|
struct GNUNET_HashCode session;
|
|
|
|
} to_sign;
|
2015-08-06 12:46:15 +02:00
|
|
|
|
|
|
|
to_sign.purpose.purpose = GNUNET_SIGNATURE_PURPOSE_TEST;
|
2015-07-09 10:46:33 +02:00
|
|
|
to_sign.purpose.size = htonl (sizeof (to_sign));
|
2015-08-06 12:46:15 +02:00
|
|
|
to_sign.session = *session;
|
2015-07-20 10:24:09 +02:00
|
|
|
GNUNET_CRYPTO_eddsa_sign (&coin->priv,
|
2015-07-09 10:46:33 +02:00
|
|
|
&to_sign.purpose,
|
2015-07-20 10:24:09 +02:00
|
|
|
&coin_sig.eddsa_signature);
|
2015-07-09 10:46:33 +02:00
|
|
|
}
|
2016-01-21 15:52:10 +01:00
|
|
|
GNUNET_assert (GNUNET_OK ==
|
|
|
|
TALER_string_to_amount (CURRENCY ":1.1",
|
|
|
|
&amount));
|
|
|
|
GNUNET_assert (GNUNET_OK ==
|
|
|
|
TALER_string_to_amount (CURRENCY ":0.1",
|
|
|
|
&amount_with_fee));
|
2016-03-01 15:35:04 +01:00
|
|
|
melt = GNUNET_new (struct TALER_EXCHANGEDB_RefreshMelt);
|
2015-07-23 16:10:49 +02:00
|
|
|
melt->coin.coin_pub = coin->public_info.coin_pub;
|
2015-08-06 12:46:15 +02:00
|
|
|
melt->coin.denom_sig.rsa_signature =
|
2015-07-23 16:10:49 +02:00
|
|
|
GNUNET_CRYPTO_rsa_signature_dup (coin->public_info.denom_sig.rsa_signature);
|
|
|
|
melt->coin.denom_pub.rsa_public_key =
|
|
|
|
GNUNET_CRYPTO_rsa_public_key_dup (coin->public_info.denom_pub.rsa_public_key);
|
|
|
|
GNUNET_assert (NULL != melt->coin.denom_pub.rsa_public_key);
|
|
|
|
GNUNET_assert (NULL != melt->coin.denom_sig.rsa_signature);
|
2015-07-20 10:24:09 +02:00
|
|
|
melt->coin_sig = coin_sig;
|
2015-07-09 10:46:33 +02:00
|
|
|
melt->session_hash = *session;
|
|
|
|
melt->amount_with_fee = amount;
|
|
|
|
melt->melt_fee = amount_with_fee;
|
|
|
|
return melt;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2016-03-01 15:35:04 +01:00
|
|
|
* Copies the internals of a #TALER_EXCHANGEDB_RefreshMelt
|
2015-08-06 12:46:15 +02:00
|
|
|
*
|
2015-07-09 10:46:33 +02:00
|
|
|
* @param melt the refresh melt to copy
|
|
|
|
* @return an copy of @ melt
|
|
|
|
*/
|
2016-03-01 15:35:04 +01:00
|
|
|
struct TALER_EXCHANGEDB_RefreshMelt *
|
|
|
|
PERF_TALER_EXCHANGEDB_refresh_melt_copy (const struct TALER_EXCHANGEDB_RefreshMelt *melt)
|
2015-07-09 10:46:33 +02:00
|
|
|
{
|
2016-03-01 15:35:04 +01:00
|
|
|
struct TALER_EXCHANGEDB_RefreshMelt *copy;
|
2015-07-09 10:46:33 +02:00
|
|
|
|
2016-03-01 15:35:04 +01:00
|
|
|
copy = GNUNET_new (struct TALER_EXCHANGEDB_RefreshMelt);
|
2015-07-09 10:46:33 +02:00
|
|
|
*copy = *melt;
|
2015-08-06 17:19:11 +02:00
|
|
|
copy->coin.denom_sig.rsa_signature =
|
2015-08-06 14:56:24 +02:00
|
|
|
GNUNET_CRYPTO_rsa_signature_dup (melt->coin.denom_sig.rsa_signature);
|
|
|
|
GNUNET_assert (NULL != copy->coin.denom_sig.rsa_signature);
|
2015-07-09 10:46:33 +02:00
|
|
|
|
|
|
|
return copy;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2016-03-01 15:35:04 +01:00
|
|
|
* Free the internal memory of a #TALER_EXCHANGEDB_RefreshMelt
|
2015-07-09 10:46:33 +02:00
|
|
|
*
|
2016-03-01 15:35:04 +01:00
|
|
|
* @param melt the #TALER_EXCHANGEDB_RefreshMelt to free
|
2015-07-09 10:46:33 +02:00
|
|
|
* @return #GNUNET_OK if the operation was successful, #GNUNET_SYSERROR
|
|
|
|
*/
|
|
|
|
int
|
2016-03-01 15:35:04 +01:00
|
|
|
PERF_TALER_EXCHANGEDB_refresh_melt_free (struct TALER_EXCHANGEDB_RefreshMelt *melt)
|
2015-07-09 10:46:33 +02:00
|
|
|
{
|
|
|
|
GNUNET_CRYPTO_rsa_signature_free (melt->coin.denom_sig.rsa_signature);
|
2015-08-06 14:56:24 +02:00
|
|
|
GNUNET_free (melt);
|
2015-06-12 12:09:14 +02:00
|
|
|
return GNUNET_OK;
|
|
|
|
}
|
2015-07-27 15:56:01 +02:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
2016-03-01 15:35:04 +01:00
|
|
|
* Create a #TALER_EXCHANGEDB_RefreshCommitCoin
|
2015-07-27 15:56:01 +02:00
|
|
|
*/
|
2016-03-01 15:35:04 +01:00
|
|
|
struct TALER_EXCHANGEDB_RefreshCommitCoin *
|
|
|
|
PERF_TALER_EXCHANGEDB_refresh_commit_coin_init ()
|
2015-07-27 15:56:01 +02:00
|
|
|
{
|
2016-03-01 15:35:04 +01:00
|
|
|
struct TALER_EXCHANGEDB_RefreshCommitCoin *commit_coin;
|
2015-07-27 15:56:01 +02:00
|
|
|
|
2016-03-01 15:35:04 +01:00
|
|
|
commit_coin = GNUNET_new (struct TALER_EXCHANGEDB_RefreshCommitCoin);
|
2016-05-24 20:13:31 +02:00
|
|
|
GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
|
|
|
|
&commit_coin->refresh_link,
|
|
|
|
sizeof(struct TALER_RefreshLinkEncryptedP));
|
2015-08-06 14:56:24 +02:00
|
|
|
commit_coin->coin_ev = "coin_ev";
|
|
|
|
commit_coin->coin_ev_size = 8;
|
2015-07-27 15:56:01 +02:00
|
|
|
return commit_coin;
|
|
|
|
}
|
2015-08-17 10:56:56 +02:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
2016-03-01 15:35:04 +01:00
|
|
|
* Copies a #TALER_EXCHANGEDB_RefreshCommitCoin
|
2015-08-17 10:56:56 +02:00
|
|
|
*
|
|
|
|
* @param commit_coin the commit to copy
|
|
|
|
* @return a copy of @a commit_coin
|
|
|
|
*/
|
2016-03-01 15:35:04 +01:00
|
|
|
struct TALER_EXCHANGEDB_RefreshCommitCoin *
|
|
|
|
PERF_TALER_EXCHANGEDB_refresh_commit_coin_copy (struct TALER_EXCHANGEDB_RefreshCommitCoin *commit_coin)
|
2015-08-17 10:56:56 +02:00
|
|
|
{
|
2016-03-01 15:35:04 +01:00
|
|
|
struct TALER_EXCHANGEDB_RefreshCommitCoin *copy;
|
2015-10-28 21:01:02 +01:00
|
|
|
|
2016-03-01 15:35:04 +01:00
|
|
|
copy = GNUNET_new (struct TALER_EXCHANGEDB_RefreshCommitCoin);
|
2016-05-24 20:13:31 +02:00
|
|
|
*copy = *commit_coin;
|
2015-08-17 10:56:56 +02:00
|
|
|
return copy;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2016-03-01 15:35:04 +01:00
|
|
|
* Free a #TALER_EXCHANGEDB_RefreshCommitCoin
|
2015-08-17 10:56:56 +02:00
|
|
|
*
|
|
|
|
* @param commit_coin the coin to free
|
|
|
|
*/
|
|
|
|
void
|
2016-03-01 15:35:04 +01:00
|
|
|
PERF_TALER_EXCHANGEDB_refresh_commit_coin_free (struct TALER_EXCHANGEDB_RefreshCommitCoin *commit_coin)
|
2015-08-17 10:56:56 +02:00
|
|
|
{
|
|
|
|
GNUNET_free (commit_coin);
|
|
|
|
}
|