resolving merge issue
This commit is contained in:
commit
1d740824fa
1
.gitignore
vendored
1
.gitignore
vendored
@ -30,6 +30,7 @@ GTAGS
|
|||||||
src/lib/test_exchange_api
|
src/lib/test_exchange_api
|
||||||
doc/doxygen/doxygen_sqlite3.db
|
doc/doxygen/doxygen_sqlite3.db
|
||||||
src/auditor/taler-auditor
|
src/auditor/taler-auditor
|
||||||
|
src/auditor/taler-auditor-sign
|
||||||
src/bank-lib/test_bank_api
|
src/bank-lib/test_bank_api
|
||||||
src/bank-lib/test_bank_api_with_fakebank
|
src/bank-lib/test_bank_api_with_fakebank
|
||||||
src/exchange-lib/test_exchange_api
|
src/exchange-lib/test_exchange_api
|
||||||
|
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -1,3 +1,6 @@
|
|||||||
[submodule "doc/api"]
|
[submodule "doc/api"]
|
||||||
path = doc/api
|
path = doc/api
|
||||||
url = git@git.taler.net:api
|
url = git@git.taler.net:api
|
||||||
|
[submodule "gnunet"]
|
||||||
|
path = gnunet
|
||||||
|
url = git://taler.net/gnunet.git
|
||||||
|
84
default.nix
Normal file
84
default.nix
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
# Nix package for GNUnet development
|
||||||
|
#
|
||||||
|
## INSTALL
|
||||||
|
#
|
||||||
|
# To build and install the package in the user environment, use:
|
||||||
|
#
|
||||||
|
# $ nix-env -f . -i
|
||||||
|
#
|
||||||
|
## BUILD ONLY
|
||||||
|
#
|
||||||
|
# To build the package and add it to the nix store, use:
|
||||||
|
#
|
||||||
|
# $ nix-build
|
||||||
|
#
|
||||||
|
## SHELL
|
||||||
|
#
|
||||||
|
# To launch a shell with all dependencies installed in the environment, use one of the following:
|
||||||
|
# $ nix-shell
|
||||||
|
#
|
||||||
|
# After entering nix-shell, build it:
|
||||||
|
#
|
||||||
|
# $ configurePhase
|
||||||
|
# $ buildPhase
|
||||||
|
#
|
||||||
|
## NIXPKGS
|
||||||
|
#
|
||||||
|
# For all of the above commands, nixpkgs to use can be set the following way:
|
||||||
|
#
|
||||||
|
# a) by default it uses nixpkgs pinned to a known working version
|
||||||
|
#
|
||||||
|
# b) use nixpkgs from the system:
|
||||||
|
# --arg pkgs 0
|
||||||
|
#
|
||||||
|
# c) use nixpkgs at a given path
|
||||||
|
# --arg pkgs /path/to/nixpkgs
|
||||||
|
#
|
||||||
|
## CCACHE
|
||||||
|
#
|
||||||
|
# To enable ccache, use the following:
|
||||||
|
#
|
||||||
|
# --argstr ccache_dir /var/cache/ccache
|
||||||
|
|
||||||
|
# or when using nix-shell:
|
||||||
|
# --argstr ccache_dir ~/.ccache
|
||||||
|
#
|
||||||
|
# and make sure the given directory is writable by the nixpkgs group when using nix-build or nix-env -i,
|
||||||
|
# or the current user when using nix-shell
|
||||||
|
#
|
||||||
|
|
||||||
|
{
|
||||||
|
pkgs ? null,
|
||||||
|
ccache_dir ? "",
|
||||||
|
}:
|
||||||
|
|
||||||
|
let
|
||||||
|
syspkgs = import <nixpkgs> { };
|
||||||
|
pinpkgs = syspkgs.fetchFromGitHub {
|
||||||
|
owner = "NixOS";
|
||||||
|
repo = "nixpkgs";
|
||||||
|
|
||||||
|
# binary cache exists for revisions in https://nixos.org/releases/nixos/<release>/<build>/git-revision
|
||||||
|
rev = "c4469edac1fc1fa5e5b5aa2ceadeda8f3f92d30a"; # https://nixos.org/releases/nixos/16.09/nixos-16.09beta430.c4469ed/git-revision
|
||||||
|
sha256 = "1x6hmf815d5anfxrxl6iivfkk60q5qxa6waa9xnwhwkbc14rhvn9";
|
||||||
|
};
|
||||||
|
usepkgs = if null == pkgs then
|
||||||
|
import pinpkgs {}
|
||||||
|
else
|
||||||
|
if 0 == pkgs then
|
||||||
|
import <nixpkgs> { }
|
||||||
|
else
|
||||||
|
import pkgs {};
|
||||||
|
stdenv = usepkgs.stdenvAdapters.keepDebugInfo usepkgs.stdenv;
|
||||||
|
|
||||||
|
in {
|
||||||
|
gnunet-dev = usepkgs.callPackage ./gnunet/gnunet-dev.nix {
|
||||||
|
inherit ccache_dir;
|
||||||
|
};
|
||||||
|
taler-exchange-dev = usepkgs.callPackage ./taler-exchange-dev.nix {
|
||||||
|
inherit ccache_dir;
|
||||||
|
gnunet-dev = usepkgs.callPackage ./gnunet/gnunet-dev.nix {
|
||||||
|
inherit ccache_dir;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
@ -19,6 +19,13 @@
|
|||||||
pages = {11-15},
|
pages = {11-15},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@misc{BOLT,
|
||||||
|
author = {Matthew Green and Ian Miers},
|
||||||
|
title = {Bolt: Anonymous Payment Channels for Decentralized Currencies},
|
||||||
|
howpublished = {Cryptology ePrint Archive, Report 2016/701},
|
||||||
|
year = {2016},
|
||||||
|
note = {\url{http://eprint.iacr.org/2016/701}},
|
||||||
|
}
|
||||||
|
|
||||||
@Misc{greece2015cash,
|
@Misc{greece2015cash,
|
||||||
author = {Reuters},
|
author = {Reuters},
|
||||||
@ -90,6 +97,13 @@
|
|||||||
organization={Springer}
|
organization={Springer}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@inproceedings{zerocash,
|
||||||
|
author = {Eli Ben-Sasson and Alessandro Chiesa and Christina Garman and Matthew Green and Ian Miers and Eran Tromer and Madars Virza},
|
||||||
|
title = {Zerocash: Decentralized Anonymous Payments from Bitcoin},
|
||||||
|
booktitle = {IEEE Symposium on Security \& Privacy},
|
||||||
|
year = {2014},
|
||||||
|
}
|
||||||
|
|
||||||
@inproceedings{miers2013zerocoin,
|
@inproceedings{miers2013zerocoin,
|
||||||
title={Zerocoin: Anonymous distributed e-cash from bitcoin},
|
title={Zerocoin: Anonymous distributed e-cash from bitcoin},
|
||||||
author={Miers, Ian and Garman, Christina and Green, Matthew and Rubin, Aviel D},
|
author={Miers, Ian and Garman, Christina and Green, Matthew and Rubin, Aviel D},
|
||||||
@ -197,9 +211,9 @@
|
|||||||
author="Bellare, Mihir and Namprempre, Chanathip and Pointcheval, David and Semanko, Michael",
|
author="Bellare, Mihir and Namprempre, Chanathip and Pointcheval, David and Semanko, Michael",
|
||||||
editor="Syverson, Paul",
|
editor="Syverson, Paul",
|
||||||
chapter="The Power of RSA Inversion Oracles and the Security of Chaum's RSA-Based Blind Signature Scheme",
|
chapter="The Power of RSA Inversion Oracles and the Security of Chaum's RSA-Based Blind Signature Scheme",
|
||||||
title="Financial Cryptography: 5th International Conference, FC 2001 Grand Cayman, British West Indies, February 19--22, 2001 Proceedings",
|
title="Financial Cryptography: 5th International Conference",
|
||||||
year="2002",
|
year="2002",
|
||||||
publisher="Springer Berlin Heidelberg",
|
publisher="Springer",
|
||||||
address="Berlin, Heidelberg",
|
address="Berlin, Heidelberg",
|
||||||
pages="319--338",
|
pages="319--338",
|
||||||
isbn="978-3-540-46088-6",
|
isbn="978-3-540-46088-6",
|
||||||
|
@ -63,7 +63,7 @@
|
|||||||
% - sharing = coin copying that should not be taxed
|
% - sharing = coin copying that should not be taxed
|
||||||
|
|
||||||
|
|
||||||
\title{Refreshing Coins for Giving Change and Refunds \\ in Chaum-style Anonymous Payments}
|
\title{Refreshing Coins for Giving Change and Refunds \\ in Chaum-style Anonymous Payment Systems}
|
||||||
|
|
||||||
\begin{document}
|
\begin{document}
|
||||||
\mainmatter
|
\mainmatter
|
||||||
@ -77,7 +77,7 @@
|
|||||||
\begin{abstract}
|
\begin{abstract}
|
||||||
This paper introduces {\em Taler}, a Chaum-style digital currency that
|
This paper introduces {\em Taler}, a Chaum-style digital currency that
|
||||||
enables anonymous payments while ensuring that entities that receive
|
enables anonymous payments while ensuring that entities that receive
|
||||||
payments are auditable and thus taxable. In Taler, customers can
|
payments are auditable. In Taler, customers can
|
||||||
never defraud anyone, merchants can only fail to deliver the
|
never defraud anyone, merchants can only fail to deliver the
|
||||||
merchandise to the customer, and payment service providers can be
|
merchandise to the customer, and payment service providers can be
|
||||||
fully audited. All parties receive cryptographic evidence for all
|
fully audited. All parties receive cryptographic evidence for all
|
||||||
@ -88,10 +88,10 @@ systems that do not provide for privacy.
|
|||||||
|
|
||||||
The key technical contribution underpinning Taler is a new {\em
|
The key technical contribution underpinning Taler is a new {\em
|
||||||
refresh protocol} which allows fractional payments and refunds while
|
refresh protocol} which allows fractional payments and refunds while
|
||||||
maintaining anonymity of the customer and unlinkability of
|
maintaining untraceability of the customer and unlinkability of
|
||||||
transactions. The refresh protocol combines an efficient
|
transactions. The refresh protocol combines an
|
||||||
cut-and-choose mechanism with a {\em link} step to ensure that
|
efficient cut-and-choose mechanism with a {\em link} step to ensure
|
||||||
refreshing is not abused for transactional payments.
|
that refreshing is not abused for transactional payments.
|
||||||
|
|
||||||
We argue that Taler provides a secure digital currency for modern
|
We argue that Taler provides a secure digital currency for modern
|
||||||
liberal societies as it is a flexible, libre and efficient protocol
|
liberal societies as it is a flexible, libre and efficient protocol
|
||||||
@ -106,11 +106,11 @@ developed nation states have adopted highly transparent payment systems,
|
|||||||
such as the MasterCard and VisaCard credit card schemes and computerized
|
such as the MasterCard and VisaCard credit card schemes and computerized
|
||||||
bank transactions such as SWIFT. These systems enable mass surveillance
|
bank transactions such as SWIFT. These systems enable mass surveillance
|
||||||
by both governments and private companies. Aspects of this surveillance
|
by both governments and private companies. Aspects of this surveillance
|
||||||
sometimes benifit society by providing information about tax evasion or
|
sometimes benefit society by providing information about tax evasion or
|
||||||
crimes like extortion. % TODO : anti-money laundering later?
|
crimes like extortion. % TODO : anti-money laundering later?
|
||||||
In particular, bribery and corruption are limited to elites who can
|
In particular, bribery and corruption are limited to elites who can
|
||||||
afford to escape the dragnet.
|
afford to escape the dragnet.
|
||||||
|
%
|
||||||
At the other extreme, weaker developing nation states have economic
|
At the other extreme, weaker developing nation states have economic
|
||||||
activity based largely on coins, paper money or even barter. Here,
|
activity based largely on coins, paper money or even barter. Here,
|
||||||
the state is often unable to effectively monitor or tax economic
|
the state is often unable to effectively monitor or tax economic
|
||||||
@ -118,24 +118,23 @@ activity, and this limits the ability of the state to shape the
|
|||||||
society. As bribery is virtually impossible to detect, corruption is
|
society. As bribery is virtually impossible to detect, corruption is
|
||||||
widespread and not limited to social elites.
|
widespread and not limited to social elites.
|
||||||
%
|
%
|
||||||
ZeroCoin~\cite{miers2013zerocoin} is an example for translating an
|
Zerocoin~\cite{miers2013zerocoin} is an example for translating an
|
||||||
anarchistic economy into the digital realm.
|
anarchistic economy into the digital realm.
|
||||||
|
|
||||||
This paper describes Taler, a simple and practical payment system for
|
This paper describes Taler, a simple and practical payment system for
|
||||||
a modern social-liberal society, which is not being served well by
|
a social-liberal society, which is underserved by
|
||||||
current payment systems which enable either an authoritarian state in
|
current payment systems.
|
||||||
total control of the population, or create weak states with almost
|
|
||||||
anarchistic economies.
|
|
||||||
|
|
||||||
The Taler protocol is influenced by ideas from
|
The Taler protocol is influenced by ideas from
|
||||||
Chaum~\cite{chaum1983blind} and also follows Chaum's basic architecture of
|
Chaum~\cite{chaum1983blind} and also follows Chaum's basic
|
||||||
customer, merchant and exchange (Figure~\ref{fig:cmm}).
|
architecture of customer, merchant and exchange
|
||||||
The two designs share the key first step where the {\em customer}
|
(Figure~\ref{fig:cmm}). The two designs share the key first step
|
||||||
withdraws digital {\em coins} from the {\em exchange} with unlinkability
|
where the {\em customer} withdraws digital {\em coins} from the {\em
|
||||||
provided via blind signatures. The coins can then be spent at a
|
exchange} with unlinkability provided via blind signatures. The
|
||||||
{\em merchant} who {\em deposits} them at the exchange.
|
coins can then be spent at a {\em merchant} who {\em deposits} them at
|
||||||
Taler uses online detection of double-spending, thus assuring the merchant
|
the exchange. Taler uses online detection of double-spending and
|
||||||
instantly that a transaction is valid.
|
provides excuplability via cryptographic proofs. Thus merchants are
|
||||||
|
instantly assured that a transaction is valid.
|
||||||
|
|
||||||
\begin{figure}[h]
|
\begin{figure}[h]
|
||||||
\centering
|
\centering
|
||||||
@ -159,16 +158,14 @@ instantly that a transaction is valid.
|
|||||||
\label{fig:cmm}
|
\label{fig:cmm}
|
||||||
\end{figure}
|
\end{figure}
|
||||||
|
|
||||||
|
|
||||||
A key issue for an efficient Chaumian digital payment system is the
|
A key issue for an efficient Chaumian digital payment system is the
|
||||||
need to provide change. For example, a customer may want to pay
|
need to provide change. For example, a customer may want to pay
|
||||||
\EUR{49,99}, but has withdrawn a \EUR{100,00} coin. Withdrawng 10,000
|
\EUR{49,99}, but has withdrawn a \EUR{100,00} coin. Withdrawing 10,000
|
||||||
pieces with a denomination of \EUR{0,01} and transferring 4,999 would
|
coins with a denomination of \EUR{0,01} and transferring 4,999 coins would
|
||||||
be too inefficient, even for modern systems. The customer should not
|
be too inefficient. The customer should not
|
||||||
withdraw exact change from her account, as doing so reduces anonymity
|
withdraw exact change from her account, as doing so reduces anonymity
|
||||||
due to the obvious corrolation. A practical payment system must thus
|
due to the obvious correlation. A practical payment system must thus
|
||||||
support giving change in the form of spendable coins, say a \EUR{0,01}
|
support giving change.
|
||||||
coin and a \EUR{50,00} coin.
|
|
||||||
|
|
||||||
Taler solves the problem of giving change by introducing a new
|
Taler solves the problem of giving change by introducing a new
|
||||||
{\em refresh protocol}. Using this protocol, a customer can obtain
|
{\em refresh protocol}. Using this protocol, a customer can obtain
|
||||||
@ -178,9 +175,11 @@ Additionally, the refresh protocol ensures that the change is owned by
|
|||||||
the same entity which owned the original coin.
|
the same entity which owned the original coin.
|
||||||
|
|
||||||
|
|
||||||
|
\vspace{-0.3cm}
|
||||||
\section{Related Work}
|
\section{Related Work}
|
||||||
|
\vspace{-0.3cm}
|
||||||
|
|
||||||
\subsection{Blockchain-based currencies}
|
%\subsection{Blockchain-based currencies}
|
||||||
|
|
||||||
In recent years, a class of decentralized electronic payment systems,
|
In recent years, a class of decentralized electronic payment systems,
|
||||||
based on collectively recorded and verified append-only public
|
based on collectively recorded and verified append-only public
|
||||||
@ -191,13 +190,14 @@ transactions are recorded for eternity, which can enable
|
|||||||
identification of users. In theory, this concern has been addressed
|
identification of users. In theory, this concern has been addressed
|
||||||
with the Zerocoin extension to the protocol~\cite{miers2013zerocoin}.
|
with the Zerocoin extension to the protocol~\cite{miers2013zerocoin}.
|
||||||
|
|
||||||
These protocols dispense with the need for a central, trusted
|
The key contribution of blockchain-based protocols is that
|
||||||
authority, while providing a useful measure of pseudonymity.
|
they dispense with the need for a central, trusted
|
||||||
|
authority.
|
||||||
Yet, there are several major irredeemable problems inherent in their designs:
|
Yet, there are several major irredeemable problems inherent in their designs:
|
||||||
|
|
||||||
\begin{itemize}
|
\begin{itemize}
|
||||||
\item The computational puzzles solved by Bitcoin nodes with the purpose
|
\item The computational puzzles solved by Bitcoin nodes with the purpose
|
||||||
of securing the block chain consume a considerable amount of energy.
|
of securing the blockchain consume a considerable amount of energy.
|
||||||
So Bitcoin is an environmentally irresponsible design.
|
So Bitcoin is an environmentally irresponsible design.
|
||||||
\item Bitcoin transactions have pseduononymous recipients, making taxation
|
\item Bitcoin transactions have pseduononymous recipients, making taxation
|
||||||
hard to systematically enforce.
|
hard to systematically enforce.
|
||||||
@ -216,6 +216,15 @@ Yet, there are several major irredeemable problems inherent in their designs:
|
|||||||
% currency exchange and exacerbates the problems with currency fluctuations.
|
% currency exchange and exacerbates the problems with currency fluctuations.
|
||||||
\end{itemize}
|
\end{itemize}
|
||||||
|
|
||||||
|
Anonymity extensions for BitCoin such as Zerocoin~\cite{miers2013zerocoin}
|
||||||
|
and BOLT~\cite{BOLT} are also limited to transactions with coins
|
||||||
|
of fixed discrete value, creating problems with giving change we
|
||||||
|
outlined in the introduction. Furthermore, these extensions have
|
||||||
|
problems with aborted transactions, which can reduce the anonymity
|
||||||
|
set. Taler's refresh protocol also addresses the problem of aborted
|
||||||
|
transactions, ensuring that aborts cannot be used to attack the
|
||||||
|
privacy assurances of the system.
|
||||||
|
|
||||||
%GreenCoinX\footnote{\url{https://www.greencoinx.com/}} is a more
|
%GreenCoinX\footnote{\url{https://www.greencoinx.com/}} is a more
|
||||||
%recent AltCoin where the company promises to identify the owner of
|
%recent AltCoin where the company promises to identify the owner of
|
||||||
%each coin via e-mail addresses and phone numbers. While it is unclear
|
%each coin via e-mail addresses and phone numbers. While it is unclear
|
||||||
@ -224,7 +233,7 @@ Yet, there are several major irredeemable problems inherent in their designs:
|
|||||||
%would also merely impose a financial panopticon on a BitCoin-style
|
%would also merely impose a financial panopticon on a BitCoin-style
|
||||||
%money supply and transaction model.
|
%money supply and transaction model.
|
||||||
|
|
||||||
\subsection{Chaum-style electronic cash}
|
%\subsection{Chaum-style electronic cash}
|
||||||
|
|
||||||
Chaum~\cite{chaum1983blind} proposed a digital payment system that
|
Chaum~\cite{chaum1983blind} proposed a digital payment system that
|
||||||
would provide some customer anonymity while disclosing the identity of
|
would provide some customer anonymity while disclosing the identity of
|
||||||
@ -312,53 +321,64 @@ description of the Opencoin protocol is available to date.
|
|||||||
%macropayment. It is therefore unclear how Peppercoin would actually
|
%macropayment. It is therefore unclear how Peppercoin would actually
|
||||||
%reduce the computational burden on the exchange.
|
%reduce the computational burden on the exchange.
|
||||||
|
|
||||||
|
%\vspace{-0.3cm}
|
||||||
\section{Design}
|
\section{Design}
|
||||||
|
%\vspace{-0.3cm}
|
||||||
|
|
||||||
The Taler system comprises three principal types of actors
|
The Taler system comprises three principal types of actors
|
||||||
(Figure~\ref{fig:cmm}): The \emph{customer} is interested in receiving
|
(Figure~\ref{fig:cmm}): The \emph{customer} is interested in receiving
|
||||||
goods or services from the \emph{merchant} in exchange for payment.
|
goods or services from the \emph{merchant} in exchange for payment.
|
||||||
When making a transaction, both the customer and the merchant use the
|
To pay, the customer {\em spends} digital coins at the merchant. When
|
||||||
same \emph{exchange}, which serves as a payment service provider for
|
making a transaction, both the customer and the merchant use the same
|
||||||
the financial transaction between the two. The exchange is
|
\emph{exchange}, which serves as a payment service provider for the
|
||||||
responsible for allowing the customer to convert financial reserves to
|
financial transaction between the two. The exchange is responsible
|
||||||
the anonymous digital coins, and for enabling the merchant to convert
|
for allowing the customer to withdraw anonymous digital coins from the
|
||||||
spent digital coins back to funds in a financial reserve. In
|
customer's financial reserves, and for enabling the merchant to
|
||||||
addition, we describe an \emph{auditor} who assures customers and
|
deposit digital coins in return for receiving credit at the merchant's
|
||||||
merchants that the exchange operates correctly.
|
financial reserve. In addition, Taler includes an \emph{auditor} who
|
||||||
|
assures customers and merchants that the exchange operates correctly.
|
||||||
|
|
||||||
|
%\vspace{-0.3cm}
|
||||||
\subsection{Security model}
|
\subsection{Security model}
|
||||||
|
%\vspace{-0.3cm}
|
||||||
|
|
||||||
Taler's security model assumes that cryptographic primitives are
|
Taler assumes that each participant has full control over their
|
||||||
secure and that each participant is under full control of his system.
|
system. We assume the contact information of the exchange is known to
|
||||||
The contact information of the exchange is known to both customer and
|
both customer and merchant from the start, including that the customer
|
||||||
merchant from the start. We further assume that the customer can
|
can authenticate the merchant, for example by using X.509
|
||||||
authenticate the merchant, e.g. using X.509
|
certificates~\cite{rfc6818}. A Taler merchant is trusted to deliver
|
||||||
certificates~\cite{rfc5280}. Finally, we assume that customer has an
|
the service or goods to the customer upon receiving payment. The
|
||||||
anonymous bi-directional channel, such as Tor, to communicate with
|
customer can seek legal relief to achieve this, as the customer
|
||||||
both the exchange and the merchant.
|
receives cryptographic evidence of the contract and the associated
|
||||||
|
payment. We assume each Taler customer has an anonymous
|
||||||
|
bi-directional channel, such as Tor, to communicate with both the
|
||||||
|
exchange and the merchant.
|
||||||
|
|
||||||
The exchange is trusted to hold funds of its customers and to forward
|
A Taler exchange is trusted to hold funds of its customers and to
|
||||||
them when receiving the respective deposit instructions from the
|
forward them when receiving the respective deposit instructions from
|
||||||
merchants. Customer and merchant can have assurances about the
|
the merchants. Customer and merchant can have assurances about the
|
||||||
exchange's liquidity and operation though published audits by
|
exchange's liquidity and operation though published audits by
|
||||||
financial regulators or other trusted third parties. If sufficently
|
financial regulators or other trusted third parties. An exchange's
|
||||||
regular, audits of the exchange's accounts should reveal any possible
|
signing keys expire regularly, allowing the exchange to eventually
|
||||||
fraud. Online signing keys expire regularly, allowing the exchange to
|
destroy the corresponding accumulated cryptographic proofs, and
|
||||||
destroy the corresponding accumulated cryptographic proofs.
|
limiting the exchange's financial liability.
|
||||||
|
|
||||||
The merchant is trusted to deliver the service or goods to the
|
On the cryptographic side, a Taler exchange demands that coins use a
|
||||||
customer upon receiving payment. The customer can seek legal relief
|
full domain hash (FDH) to make so-called ``one-more forgery'' attacks
|
||||||
to achieve this, as he receives cryptographic proofs of the contract
|
provably hard, assuming the RSA known-target inversion problem is
|
||||||
and has proof that he paid his obligations.
|
hard~\cite[Theorem 12]{RSA-HDF-KTIvCTI}. For a withdrawn coin,
|
||||||
|
violating the customers anonymity cryptographily requires recognizing
|
||||||
|
a random blinding factor from a random element of the group of
|
||||||
|
integers modulo the denomination key's RSA modulus, which appears
|
||||||
|
impossible even with a quantum computers. For a refreshed coin,
|
||||||
|
unlinkabiltiy requires the hardness of the discrete logarithm for
|
||||||
|
Curve25519.
|
||||||
|
|
||||||
|
The cut-and-choose protocol prevents merchants and customers from
|
||||||
|
conspiring to conceal a merchants income. We assume that the maximum
|
||||||
|
tax rate is below $1/\kappa$, and that expected transaction losses of
|
||||||
|
a factor of $\kappa$ for tax evasion are thus unacceptable.
|
||||||
|
|
||||||
Neither the merchant nor the customer have any ability to {\em effectively}
|
|
||||||
defraud the exchange or the state collecting taxes. Here, ``effectively''
|
|
||||||
means that the expected return for fraud is negative.
|
|
||||||
%
|
|
||||||
Note that customers do not need to be trusted in any way, and that in
|
|
||||||
particular it is never necessary for anyone to try to recover funds
|
|
||||||
from customers using legal coersion.
|
|
||||||
|
|
||||||
\subsection{Taxability and Entities}
|
\subsection{Taxability and Entities}
|
||||||
|
|
||||||
@ -396,15 +416,14 @@ could spend the associated funds. Assuming the payment system has
|
|||||||
effective double-spending detection, this means that either entity has
|
effective double-spending detection, this means that either entity has
|
||||||
to constantly fear that the funds might no longer be available to it.
|
to constantly fear that the funds might no longer be available to it.
|
||||||
It follows that sharing coins by copying a private key implies mutual
|
It follows that sharing coins by copying a private key implies mutual
|
||||||
trust between the two parties, in which case we treat them as the same
|
trust between the two parties.
|
||||||
entity for taxability.
|
|
||||||
|
|
||||||
In Taler, making funds available by copying a private key and thus
|
In Taler, making funds available by copying a private key and thus
|
||||||
sharing control is {\bf not} considered a {\em transaction} and thus
|
sharing control is {\bf not} considered a {\em transaction} and thus
|
||||||
{\bf not} recorded for taxation. Taler does, however, ensure
|
{\bf not} recorded for taxation. Taler does, however, ensure
|
||||||
taxability when a merchant entity acquires exclusive control over the
|
taxability when a merchant entity acquires exclusive control over the
|
||||||
value represented by a digital coins. For such transactions, the state
|
value represented by a digital coins. For such transactions, the state
|
||||||
can obtain information from the exchange, or a bank, that identifies
|
can obtain information from the exchange that identifies
|
||||||
the entity that received the digital coins as well as the exact value
|
the entity that received the digital coins as well as the exact value
|
||||||
of those coins. Taler also allows the exchange, and hence the state,
|
of those coins. Taler also allows the exchange, and hence the state,
|
||||||
to learn the value of digital coins withdrawn by a customer---but not
|
to learn the value of digital coins withdrawn by a customer---but not
|
||||||
@ -439,7 +458,7 @@ is unable to link the known identity of the customer that withdrew
|
|||||||
anonymous digital coins to the {\em purchase} performed later at the
|
anonymous digital coins to the {\em purchase} performed later at the
|
||||||
merchant.
|
merchant.
|
||||||
|
|
||||||
While the customer thus has anonymity for purchases, the exchange will
|
While the customer thus has untraceability for purchases, the exchange will
|
||||||
always learn the merchant's identity in order to credit the merchant's
|
always learn the merchant's identity in order to credit the merchant's
|
||||||
account. This is also necessary for taxation, as Taler deliberately
|
account. This is also necessary for taxation, as Taler deliberately
|
||||||
exposes these events as anchors for tax audits on income.
|
exposes these events as anchors for tax audits on income.
|
||||||
@ -467,31 +486,30 @@ exposes these events as anchors for tax audits on income.
|
|||||||
|
|
||||||
A \emph{coin} in Taler is a public-private key pair where the private
|
A \emph{coin} in Taler is a public-private key pair where the private
|
||||||
key is only known to the owner of the coin. A coin derives its
|
key is only known to the owner of the coin. A coin derives its
|
||||||
financial value from an RSA signature over a the full domain hash
|
financial value from an RSA signature over the FDH
|
||||||
(FDH) of the coin's public key. An FDH is used so that ``one-more
|
of the coin's public key. The exchange has multiple RSA {\em
|
||||||
forgery'' is provably hard assuming the RSA known-target inversion
|
denomination key} pairs available for blind-signing coins of
|
||||||
problem is hard~cite[Theorem 12]{RSA-HDF-KTIvCTI}. The exchange has
|
different value.
|
||||||
multiple RSA {\em denomination key} pairs available for blind-signing
|
|
||||||
coins of different value.
|
|
||||||
|
|
||||||
Denomination keys have an expiration date, before which any coins
|
Denomination keys have an expiration date, before which any coins
|
||||||
signed with it must be spent or refreshed. This allows the exchange
|
signed with it must be spent or refreshed. This allows the exchange
|
||||||
to eventually discard records of old transactions, thus limiting the
|
to eventually discard records of old transactions, thus limiting the
|
||||||
records that the exchange must retain and search to detect
|
records that the exchange must retain and search to detect
|
||||||
double-spending attempts. Furthermore, the exchange uses each
|
double-spending attempts. If a private denomination key were to be
|
||||||
denomination key only for a limited number of coins. In this way, if
|
compromised, the exchange can detect this once more coins are redeemed
|
||||||
a private denomination key were to be compromised, the exchange would
|
than the total that was signed into existence using that denomination
|
||||||
detect this once more coins were redeemed than the total that was
|
key. In this case, the exchange can allow authentic customers to
|
||||||
signed into existence using that denomination key. In this case, the
|
redeem their unspent coins that were signed with the compromised
|
||||||
exchange can allow authentic customers to exchange their unspent
|
private key, while refusing further deposits involving coins signed by
|
||||||
coins that were signed with the compromised private key, while
|
the compromised denomination key. As a result, the financial damage
|
||||||
refusing further anonymous transactions involving those coins. As a
|
of losing a private signing key is limited to at most the amount
|
||||||
result, the financial damage of losing a private signing key can be
|
originally signed with that key, and denomination key rotation can be
|
||||||
limited to at most twice the amount originally signed with that key.
|
used to bound that risk.
|
||||||
|
|
||||||
We also ensure that the exchange cannot deanonymize users by signing
|
We ensure that the exchange cannot deanonymize users by signing
|
||||||
each coin with a fresh denomination key. For this, exchanges are
|
each coin with a fresh denomination key. For this, exchanges are
|
||||||
required to publicly announce their denomination keys in advance.
|
required to publicly announce their denomination keys in advance
|
||||||
|
with validity periods that imply sufficiently strong anonymity sets.
|
||||||
These announcements are expected to be signed with an off-line
|
These announcements are expected to be signed with an off-line
|
||||||
long-term private {\em master signing key} of the exchange and the
|
long-term private {\em master signing key} of the exchange and the
|
||||||
auditor. Additionally, customers should obtain these announcements
|
auditor. Additionally, customers should obtain these announcements
|
||||||
@ -515,10 +533,12 @@ withdrawal message as proof that the reserve was debited correctly.
|
|||||||
|
|
||||||
After a coin is issued, the customer is the only entity that knows the
|
After a coin is issued, the customer is the only entity that knows the
|
||||||
private key of the coin, making him the \emph{owner} of the coin. Due
|
private key of the coin, making him the \emph{owner} of the coin. Due
|
||||||
to the use of blind signatures, the exchange does not even learn the
|
to the use of blind signatures, the exchange does not learn the
|
||||||
public key during the withdrawal process. If the private key is
|
public key during the withdrawal process. If the private key is
|
||||||
shared with others, they become co-owners of the coin. Knowledge of
|
shared with others, they become co-owners of the coin. Knowledge of
|
||||||
the private key of the coin enables the owner to spent the coin.
|
the private key of the coin and the signature over the coin's public
|
||||||
|
key by an exchange's denomination key enables spending the
|
||||||
|
coin.
|
||||||
|
|
||||||
|
|
||||||
% \subsection{Coin spending}
|
% \subsection{Coin spending}
|
||||||
@ -612,9 +632,9 @@ purposes. The exchange's bank transfers dealing in traditional currency
|
|||||||
are expected to be recorded for tax authorities to ensure taxability.
|
are expected to be recorded for tax authorities to ensure taxability.
|
||||||
% FIXME: Auditor?
|
% FIXME: Auditor?
|
||||||
|
|
||||||
We use RSA for denomination keys and EdDSA over some eliptic curve
|
$S_K$ denotes RSA signing with denomination key $K$ and EdDSA
|
||||||
$\mathbb{E}$ for all other keys. Let $G$ denote the generator of
|
over eliptic curve $\mathbb{E}$ for other types of keys.
|
||||||
our elliptic curve $\mathbb{E}$.
|
$G$ denotes the generator of elliptic curve $\mathbb{E}$.
|
||||||
|
|
||||||
\subsection{Withdrawal}
|
\subsection{Withdrawal}
|
||||||
|
|
||||||
@ -639,25 +659,25 @@ Now the customer carries out the following interaction with the exchange:
|
|||||||
\item coin key $C := (c_s,C_p)$ with private key $c_s$ and public key $C_p := c_s G$,
|
\item coin key $C := (c_s,C_p)$ with private key $c_s$ and public key $C_p := c_s G$,
|
||||||
\item blinding factor $b$, and commits $\langle W, C, b \rangle$ to disk.
|
\item blinding factor $b$, and commits $\langle W, C, b \rangle$ to disk.
|
||||||
\end{itemize}
|
\end{itemize}
|
||||||
\item[SEPA Send]
|
\item[Wire transfer send]
|
||||||
The customer transfers an amount of money corresponding to
|
The customer transfers an amount of money corresponding to
|
||||||
at least $K_v$ to the exchange, with $W_p$ in the subject line
|
at least $K_v$ to the exchange, with $W_p$ in the subject line
|
||||||
of the transaction.
|
of the transaction.
|
||||||
\item[SEPA Recieve]
|
\item[Wire transfer recieve]
|
||||||
The exchange receives the transaction and credits the reserve $W_p$
|
The exchange receives the transaction and credits the reserve $W_p$
|
||||||
with the respective amount in its database.
|
with the respective amount in its database.
|
||||||
\item[POST {\tt /withdraw/sign}]
|
\item[POST {\tt /withdraw/sign}]
|
||||||
The customer sends $S_W(B)$ where $B := B_b(\FDH_K(C_p))$ to
|
The customer sends $S_W(B)$ where $B := B_b(\FDH_K(C_p))$ to
|
||||||
the exchange to request withdrawal of $C$; here, $B_b$ denotes
|
the exchange to request withdrawal of $C$; here, $B_b$ denotes
|
||||||
Chaum-style blinding with blinding factor $b$.
|
Chaum-style blinding with blinding factor $b$.
|
||||||
\item[200 OK / 402 PAYMENT REQUIRED]
|
\item[200 OK / 403 FORBIDDEN]
|
||||||
The exchange checks if the same withdrawal request was issued before;
|
The exchange checks if the same withdrawal request was issued before;
|
||||||
in this case, it sends a Chaum-style blind signature $S_K(B)$ with
|
in this case, it sends a Chaum-style blind signature $S_K(B)$ with
|
||||||
private key $K_s$ to the customer. \\
|
private key $K_s$ to the customer. \\
|
||||||
If this is a fresh withdrawal request, the exchange performs the following transaction:
|
If this is a fresh withdrawal request, the exchange performs the following transaction:
|
||||||
\begin{enumerate}
|
\begin{enumerate}
|
||||||
\item checks if the reserve $W_p$ has sufficient funds
|
\item checks if the reserve $W_p$ has sufficient funds
|
||||||
for a coin of value corresponding to $K$
|
for a coin of value corresponding to $K$,
|
||||||
\item stores the withdrawal request and response
|
\item stores the withdrawal request and response
|
||||||
$\langle S_W(B), S_K(B) \rangle$ in its database
|
$\langle S_W(B), S_K(B) \rangle$ in its database
|
||||||
for future reference,
|
for future reference,
|
||||||
@ -668,9 +688,8 @@ Now the customer carries out the following interaction with the exchange:
|
|||||||
error back to the customer, with proof that it operated correctly.
|
error back to the customer, with proof that it operated correctly.
|
||||||
Assuming the signature was valid, this would involve showing the transaction
|
Assuming the signature was valid, this would involve showing the transaction
|
||||||
history for the reserve.
|
history for the reserve.
|
||||||
% FIXME: Is it really the whole history?
|
|
||||||
\item[Done] The customer computes and verifies the unblinded signature
|
\item[Done] The customer computes and verifies the unblinded signature
|
||||||
$S_K(\FDH_K{C_p}) = U_b(S_K(B))$.
|
$S_K(\FDH_K(C_p)) = U_b(S_K(B))$.
|
||||||
Finally the customer saves the coin $\langle S_K(\FDH_K(C_p)), c_s \rangle$
|
Finally the customer saves the coin $\langle S_K(\FDH_K(C_p)), c_s \rangle$
|
||||||
to their local wallet on disk.
|
to their local wallet on disk.
|
||||||
\end{description}
|
\end{description}
|
||||||
@ -681,9 +700,9 @@ Now the customer carries out the following interaction with the exchange:
|
|||||||
A customer can spend coins at a merchant, under the condition that the
|
A customer can spend coins at a merchant, under the condition that the
|
||||||
merchant trusts the exchange that issued the coin.
|
merchant trusts the exchange that issued the coin.
|
||||||
% FIXME: Auditor here?
|
% FIXME: Auditor here?
|
||||||
Merchants are identified by their public key $M_p = m_s G$ which the
|
Merchants are identified by their public key $M_p$ which the
|
||||||
customer's wallet learns through the merchant's webpage, which itself
|
customer's wallet learns through the merchant's webpage, which itself
|
||||||
must be authenticated with X.509c.
|
should be authenticated with X.509c.
|
||||||
% FIXME: Is this correct?
|
% FIXME: Is this correct?
|
||||||
|
|
||||||
We now describe the protocol between the customer, merchant, and exchange
|
We now describe the protocol between the customer, merchant, and exchange
|
||||||
@ -702,35 +721,37 @@ with signature $\widetilde{C} := S_K(\FDH_K(C_p))$
|
|||||||
\item[Proposal]
|
\item[Proposal]
|
||||||
The merchant creates a digitally signed contract
|
The merchant creates a digitally signed contract
|
||||||
$\mathcal{A} := S_M(m, f, a, H(p, r), \vec{X})$
|
$\mathcal{A} := S_M(m, f, a, H(p, r), \vec{X})$
|
||||||
where $m$ is an identifier for this transaction, $a$ is data relevant
|
where $m$ is an identifier for this transaction, $f$ is the price of the offer,
|
||||||
|
and $a$ is data relevant
|
||||||
to the contract indicating which services or goods the merchant will
|
to the contract indicating which services or goods the merchant will
|
||||||
deliver to the customer, $f$ is the price of the offer, and
|
deliver to the customer, including the {\tt /merchant-specific} URI for the payment.
|
||||||
$p$ is the merchant's payment information (e.g. his IBAN number), and
|
$p$ is the merchant's payment information (e.g. his IBAN number), and
|
||||||
$r$ is a random nonce. The merchant commits $\langle \mathcal{A} \rangle$
|
$r$ is a random nonce. The merchant commits $\langle \mathcal{A} \rangle$
|
||||||
to disk and sends $\mathcal{A}$ to the customer.
|
to disk and sends $\mathcal{A}$ to the customer.
|
||||||
\item[Customer Setup]
|
\item[Customer Setup]
|
||||||
The customer should already possess a coin issued by a exchange that is
|
The customer should already possess a coin $\widetilde{C}$ issued by a exchange that is
|
||||||
accepted by the merchant, meaning $K$ should be publicly signed by
|
accepted by the merchant, meaning $K$ of $\widetilde{C}$ should be publicly signed by
|
||||||
some $X_j$ from $\vec{X}$, and has a value $\geq f$.
|
some $X_j$ from $\vec{X}$, and has a value $\geq f$.
|
||||||
\item[POST {\tt /???}] \label{deposit}
|
\item[POST {\tt /merchant-specific}]
|
||||||
|
Let $X_j$ be the exchange which signed $\widetilde{C}$ with $K$.
|
||||||
The customer generates a \emph{deposit-permission}
|
The customer generates a \emph{deposit-permission}
|
||||||
$\mathcal{D} := S_c(\widetilde{C}, m, f, H(a), H(p,r), M_p)$
|
$\mathcal{D} := S_c(\widetilde{C}, m, f, H(a), H(p,r), M_p)$
|
||||||
and sends $\langle \mathcal{D}, X_j\rangle$ to the merchant,
|
and sends $\langle \mathcal{D}, X_j\rangle$ to the merchant.
|
||||||
where $X_j$ is the exchange which signed $K$.
|
|
||||||
\item[POST {\tt/deposit}]
|
\item[POST {\tt/deposit}]
|
||||||
The merchant gives $(\mathcal{D}, p, r)$ to the exchange, thereby
|
The merchant gives $(\mathcal{D}, p, r)$ to the exchange, thereby
|
||||||
revealing $p$ only to the exchange.
|
revealing $p$ only to the exchange.
|
||||||
\item[200 OK / 409 CONFLICT]
|
\item[200 OK / 403 FORBIDDEN]
|
||||||
The exchange validates $\mathcal{D}$ and checks for double spending.
|
The exchange validates $\mathcal{D}$ and checks for double spending.
|
||||||
If the coin has been involved in previous transactions and the new
|
If the coin has been involved in previous transactions and the new
|
||||||
one would exceed its remaining value, it sends an error
|
one would exceed its remaining value, it sends a ``403 FORBIDDEN'' error
|
||||||
with the records from the previous transactions back to the merchant. \\
|
with the records from the previous transactions back to the merchant. \\
|
||||||
%
|
%
|
||||||
If double spending is not found, the exchange commits $\langle \mathcal{D} \rangle$ to disk
|
If double spending is not found, the exchange commits $\langle \mathcal{D} \rangle$ to disk
|
||||||
and notifies the merchant that the deposit operation was successful.
|
and signs a ``200 OK'' message affirming the deposit operation was successful.
|
||||||
\item[200 OK / ???]
|
\item[200 OK / 424 FAILED DEPENDENCY]
|
||||||
The merchant commits and forwards the notification from the exchange to the
|
The merchant commits and forwards the notification from the exchange to the
|
||||||
customer, confirming the success or failure of the operation.
|
customer, confirming the success (``200 OK'') or failure (``424 FAILED DEPENDENCY'')
|
||||||
|
of the operation.
|
||||||
\end{description}
|
\end{description}
|
||||||
|
|
||||||
We have simplified the exposition by assuming that one coin suffices,
|
We have simplified the exposition by assuming that one coin suffices,
|
||||||
@ -738,12 +759,12 @@ but in practice a customer can use multiple coins from the same
|
|||||||
exchange where the total value adds up to $f$ by running the above
|
exchange where the total value adds up to $f$ by running the above
|
||||||
steps for each of the coins.
|
steps for each of the coins.
|
||||||
|
|
||||||
If a transaction is aborted after Step~\ref{deposit},
|
If a transaction is aborted after the first POST, subsequent
|
||||||
subsequent transactions with the same coin could be linked to the coin,
|
transactions with the same coin could be linked to this operation.
|
||||||
but not directly to the coin's owner. The same applies to partially
|
The same applies to partially spent coins where $f$ is smaller than
|
||||||
spent coins where $f$ is smaller than the actual value of the coin.
|
the actual value of the coin. To unlink subsequent transactions from
|
||||||
To unlink subsequent transactions from a coin, the customer has to
|
a coin, the customer has to execute the following coin refreshing
|
||||||
execute the coin refreshing protocol with the exchange.
|
protocol with the exchange.
|
||||||
|
|
||||||
%\begin{figure}[h]
|
%\begin{figure}[h]
|
||||||
%\centering
|
%\centering
|
||||||
@ -785,17 +806,17 @@ denomination $K$ is melted to obtain a fresh coin $\widetilde{C}$
|
|||||||
with the same denomination. In practice, Taler uses a natural
|
with the same denomination. In practice, Taler uses a natural
|
||||||
extension where multiple fresh coins are generated a the same time to
|
extension where multiple fresh coins are generated a the same time to
|
||||||
enable giving precise change matching any amount.
|
enable giving precise change matching any amount.
|
||||||
In the protocol, $\kappa \ge 3$ is a security parameter for the
|
|
||||||
cut-and-choose part of the protocol and $G$ is the
|
|
||||||
generator of the elliptic curve.
|
|
||||||
|
|
||||||
We note that $\kappa = 3$ is actually perfectly sufficient in most
|
In the protocol, $\kappa \ge 2$ is a security parameter for the
|
||||||
cases in practice, as the cut-and-choose protocol does not need to
|
cut-and-choose part of the protocol. $\kappa = 3$ is actually
|
||||||
provide cryptographic security: If the maximum applicable tax is less
|
perfectly sufficient in most cases in practice, as the cut-and-choose
|
||||||
than $\frac{2}{3}$, then detecting $\kappa = 3$ ensures that cheating
|
protocol does not need to provide cryptographic security: If the
|
||||||
results in a negative return on average as $\kappa - 1$ out of
|
maximum applicable tax is less than $\frac{2}{3}$, then $\kappa = 3$
|
||||||
$\kappa$ attempts to cheat are detected. This makes the use of
|
ensures that cheating results in a negative financial return on
|
||||||
cut-and-choose practical and efficient in this context.
|
average as $\kappa - 1$ out of $\kappa$ attempts to hide from taxation
|
||||||
|
are detected and penalized by a total loss. This makes our use of
|
||||||
|
cut-and-choose practical and efficient, and in particularly faster
|
||||||
|
than the comparable use of zk-SNARKs in ZeroCash~\cite{zerocash}.
|
||||||
|
|
||||||
% FIXME: I'm explicit about the rounds in postquantum.tex
|
% FIXME: I'm explicit about the rounds in postquantum.tex
|
||||||
|
|
||||||
@ -805,16 +826,16 @@ cut-and-choose practical and efficient in this context.
|
|||||||
a transfer private key $t^{(i)}_s$ and computes
|
a transfer private key $t^{(i)}_s$ and computes
|
||||||
\begin{itemize}
|
\begin{itemize}
|
||||||
\item the transfer public key $T^{(i)}_p := t^{(i)}_s G$ and
|
\item the transfer public key $T^{(i)}_p := t^{(i)}_s G$ and
|
||||||
\item the new coin secret seed $L_i := H(c'_s T_p^{(i)})$.
|
\item the new coin secret seed $L^{(i)} := H(c'_s T_p^{(i)})$.
|
||||||
\end{itemize}
|
\end{itemize}
|
||||||
We have computed $L_i$ as a Diffie-Hellman shared secret between
|
We have computed $L_i$ as a Diffie-Hellman shared secret between
|
||||||
the transfer key pair $T^{(i)} := \left(t^{(i)}_s,T^{(i)}_p\right)$
|
the transfer key pair $T^{(i)} := \left(t^{(i)}_s,T^{(i)}_p\right)$
|
||||||
and old coin key pair $C' := \left(c_s', C_p'\right)$;
|
and old coin key pair $C' := \left(c_s', C_p'\right)$;
|
||||||
as a result, $L_i = H(t^{(i)}_s C'_p)$ also holds.
|
as a result, $L^{(i)} = H(t^{(i)}_s C'_p)$ also holds.
|
||||||
Now the customer applies key derivation functions $\KDF_?$ to $L_i$ to generate
|
Now the customer applies key derivation functions $\KDF_{\textrm{blinding}}$ and $\KDF_{\textrm{Ed25519}}$ to $L^{(i)}$ to generate
|
||||||
\begin{itemize}
|
\begin{itemize}
|
||||||
\item a blinding factor $b^{(i)} = \FDH_K(\KDF_{\textrm{blinding}}(L_i))$.
|
\item a blinding factor $b^{(i)} = \FDH_K(\KDF_{\textrm{blinding}}(L^{(i)}))$.
|
||||||
\item $c_s^{(i)} = \KDF_{\textrm{Ed25519}}(L_i)$
|
\item $c_s^{(i)} = \KDF_{\textrm{Ed25519}}(L^{(i)})$
|
||||||
\end{itemize}
|
\end{itemize}
|
||||||
Now the customer can compute her new coin key pair
|
Now the customer can compute her new coin key pair
|
||||||
$C^{(i)} := \left(c_s^{(i)}, C_p^{(i)}\right)$
|
$C^{(i)} := \left(c_s^{(i)}, C_p^{(i)}\right)$
|
||||||
@ -837,7 +858,7 @@ cut-and-choose practical and efficient in this context.
|
|||||||
this time to prevent the exchange from assisting tax evasion. \\
|
this time to prevent the exchange from assisting tax evasion. \\
|
||||||
%
|
%
|
||||||
The exchange sends $S_{K'}(C'_p, \gamma)$ to the customer where
|
The exchange sends $S_{K'}(C'_p, \gamma)$ to the customer where
|
||||||
$K'$ is the exchange's message signing key.
|
$K'$ is the exchange's message signing key, thereby commmitting the exchange to $\gamma$.
|
||||||
\item[POST {\tt /refresh/reveal}]
|
\item[POST {\tt /refresh/reveal}]
|
||||||
The customer commits $\langle C', S_K(C'_p, \gamma) \rangle$ to disk.
|
The customer commits $\langle C', S_K(C'_p, \gamma) \rangle$ to disk.
|
||||||
Also, the customer assembles
|
Also, the customer assembles
|
||||||
@ -850,16 +871,16 @@ cut-and-choose practical and efficient in this context.
|
|||||||
\vspace{-2ex}
|
\vspace{-2ex}
|
||||||
\begin{minipage}{5cm}
|
\begin{minipage}{5cm}
|
||||||
\begin{align*}
|
\begin{align*}
|
||||||
\overline{L}_i :&= H(t_s^{(i)} C_p') \\
|
\overline{L^{(i)}} :&= H(t_s^{(i)} C_p') \\
|
||||||
\overline{c}_s^{(i)} :&= \KDF_{\textrm{Ed25519}}(\overline{L}_i) \\
|
\overline{c_s^{(i)}} :&= \KDF_{\textrm{Ed25519}}(\overline{L^{(i)}}) \\
|
||||||
\overline{C^{(i)}_p} :&= \overline{c}_s^{(i)} G
|
\overline{C^{(i)}_p} :&= \overline{c_s^{(i)}} G
|
||||||
\end{align*}
|
\end{align*}
|
||||||
\end{minipage}
|
\end{minipage}
|
||||||
\begin{minipage}{5cm}
|
\begin{minipage}{5cm}
|
||||||
\begin{align*}
|
\begin{align*}
|
||||||
\overline{T_p^{(i)}} :&= t_s^{(i)} G \\
|
\overline{T_p^{(i)}} :&= t_s^{(i)} G \\
|
||||||
\overline{b}^{(i)} :&= \FDH_K(\KDF_{\textrm{blinding}}(\overline{L}_i)) \\
|
\overline{b^{(i)}} :&= \FDH_K(\KDF_{\textrm{blinding}}(\overline{L^{(i)}})) \\
|
||||||
\overline{B^{(i)}} :&= B_{\overline{b_i}}(\overline{C_p^{(i)}})
|
\overline{B^{(i)}} :&= B_{\overline{b^{(i)}}}(\overline{C_p^{(i)}})
|
||||||
\end{align*}
|
\end{align*}
|
||||||
\end{minipage}
|
\end{minipage}
|
||||||
|
|
||||||
@ -909,7 +930,7 @@ taxation model as with such trust they are assumed to be the same
|
|||||||
entity.
|
entity.
|
||||||
|
|
||||||
The auditor can anonymously check if the exchange correctly implements the
|
The auditor can anonymously check if the exchange correctly implements the
|
||||||
link request, thus preventing the exchange operator from legally disabling
|
link request, thus preventing the exchange operator from secretly disabling
|
||||||
this protocol component. Without the link operation, Taler would
|
this protocol component. Without the link operation, Taler would
|
||||||
devolve into a payment system where both sides can be anonymous, and
|
devolve into a payment system where both sides can be anonymous, and
|
||||||
thus no longer provide taxability.
|
thus no longer provide taxability.
|
||||||
@ -942,13 +963,12 @@ faulty exchange.
|
|||||||
The third case are transient failures, such as network failures or
|
The third case are transient failures, such as network failures or
|
||||||
temporary hardware failures at the exchange service provider. Here, the
|
temporary hardware failures at the exchange service provider. Here, the
|
||||||
client may receive an explicit protocol indication, such as an HTTP
|
client may receive an explicit protocol indication, such as an HTTP
|
||||||
response code 500 ``internal server error'' or simply no response.
|
response code ``500 INTERNAL SERVER ERROR'' or simply no response.
|
||||||
The appropriate behavior for the client is to automatically retry
|
The appropriate behavior for the client is to automatically retry
|
||||||
after 1s, and twice more at randomized times within 1 minute.
|
after 1s, and twice more at randomized times within 1 minute.
|
||||||
If those three attempts fail, the user should be informed about the
|
If those three attempts fail, the user should be informed about the
|
||||||
delay. The client should then retry another three times within the
|
delay. The client should then retry another three times within the
|
||||||
next 24h, and after that time the auditor be informed about the outage.
|
next 24h, and after that time the auditor should be informed about the outage.
|
||||||
|
|
||||||
Using this process, short term failures should be effectively obscured
|
Using this process, short term failures should be effectively obscured
|
||||||
from the user, while malicious behavior is reported to the auditor who
|
from the user, while malicious behavior is reported to the auditor who
|
||||||
can then presumably rectify the situation, using methods such as
|
can then presumably rectify the situation, using methods such as
|
||||||
@ -1041,7 +1061,7 @@ At network latencies above 10 ms, the delay
|
|||||||
for executing a transaction is dominated by the network latency, as
|
for executing a transaction is dominated by the network latency, as
|
||||||
local processing virtually always takes less than 10 ms.
|
local processing virtually always takes less than 10 ms.
|
||||||
|
|
||||||
Database transactions are dominated by writes
|
Database transactions are dominated by writes%
|
||||||
%(Figure~\ref{fig:read} vs. Figure~\ref{fig:write})
|
%(Figure~\ref{fig:read} vs. Figure~\ref{fig:write})
|
||||||
, as Taler mostly needs to log
|
, as Taler mostly needs to log
|
||||||
transactions and occasionally needs to read to guard against
|
transactions and occasionally needs to read to guard against
|
||||||
@ -1092,7 +1112,7 @@ actually facilitates voluntary cooperation between the exchange and
|
|||||||
criminals~\cite{sander1999escrow} and where the state could
|
criminals~\cite{sander1999escrow} and where the state could
|
||||||
deanonymize citizens.
|
deanonymize citizens.
|
||||||
|
|
||||||
\subsection{Offline Payments}
|
%\subsection{Offline Payments}
|
||||||
|
|
||||||
Chaum's original proposals for anonymous digital cash avoided the need
|
Chaum's original proposals for anonymous digital cash avoided the need
|
||||||
for online interactions with the exchange to detect double spending by
|
for online interactions with the exchange to detect double spending by
|
||||||
@ -1115,7 +1135,7 @@ coin after restoring from backup.
|
|||||||
%subjected to financial penalties by the state in relation to the
|
%subjected to financial penalties by the state in relation to the
|
||||||
%amount transferred by the traditional currency transfer.
|
%amount transferred by the traditional currency transfer.
|
||||||
|
|
||||||
\subsection{Cryptographic proof vs. evidence}
|
% \subsection{Cryptographic proof vs. evidence}
|
||||||
|
|
||||||
In this paper we have use the term ``proof'' in many places as the
|
In this paper we have use the term ``proof'' in many places as the
|
||||||
protocol provides cryptographic proofs of which parties behave
|
protocol provides cryptographic proofs of which parties behave
|
||||||
@ -1167,11 +1187,11 @@ the participants have to disclose their core secrets.
|
|||||||
\bibliographystyle{alpha}
|
\bibliographystyle{alpha}
|
||||||
\bibliography{taler,rfc}
|
\bibliography{taler,rfc}
|
||||||
|
|
||||||
\vfill
|
%\vfill
|
||||||
\begin{center}
|
%\begin{center}
|
||||||
\Large Demonstration available at \url{https://demo.taler.net/}
|
% \Large Demonstration available at \url{https://demo.taler.net/}
|
||||||
\end{center}
|
%\end{center}
|
||||||
\vfill
|
%\vfill
|
||||||
|
|
||||||
\newpage
|
\newpage
|
||||||
\appendix
|
\appendix
|
||||||
@ -1241,13 +1261,13 @@ data being committed to disk are represented in between $\langle\rangle$.
|
|||||||
\item[$\vec{b}$]{Vector of $b^{(i)}$}
|
\item[$\vec{b}$]{Vector of $b^{(i)}$}
|
||||||
\item[$B^{(i)}$]{Blinding of $C_p^{(i)}$}
|
\item[$B^{(i)}$]{Blinding of $C_p^{(i)}$}
|
||||||
\item[$\vec{B}$]{Vector of $B^{(i)}$}
|
\item[$\vec{B}$]{Vector of $B^{(i)}$}
|
||||||
\item[$L_i$]{Link secret derived from ECDH operation via hashing}
|
\item[$L^{(i)}$]{Link secret derived from ECDH operation via hashing}
|
||||||
% \item[$E_{L_i}()$]{Symmetric encryption using key $L_i$}
|
% \item[$E_{L^{(i)}}()$]{Symmetric encryption using key $L^{(i)}$}
|
||||||
% \item[$E^{(i)}$]{$i$-th encryption of the private information $(c_s^{(i)}, b_i)$}
|
% \item[$E^{(i)}$]{$i$-th encryption of the private information $(c_s^{(i)}, b_i)$}
|
||||||
% \item[$\vec{E}$]{Vector of $E^{(i)}$}
|
% \item[$\vec{E}$]{Vector of $E^{(i)}$}
|
||||||
\item[$\cal{R}$]{Tuple of revealed vectors in cut-and-choose protocol,
|
\item[$\cal{R}$]{Tuple of revealed vectors in cut-and-choose protocol,
|
||||||
where the vectors exclude the selected index $\gamma$}
|
where the vectors exclude the selected index $\gamma$}
|
||||||
\item[$\overline{L_i}$]{Link secrets derived by the verifier from DH}
|
\item[$\overline{L^{(i)}}$]{Link secrets derived by the verifier from DH}
|
||||||
\item[$\overline{B^{(i)}}$]{Blinded values derived by the verifier}
|
\item[$\overline{B^{(i)}}$]{Blinded values derived by the verifier}
|
||||||
\item[$\overline{T_p^{(i)}}$]{Public transfer keys derived by the verifier from revealed private keys}
|
\item[$\overline{T_p^{(i)}}$]{Public transfer keys derived by the verifier from revealed private keys}
|
||||||
\item[$\overline{c_s^{(i)}}$]{Private keys obtained from decryption by the verifier}
|
\item[$\overline{c_s^{(i)}}$]{Private keys obtained from decryption by the verifier}
|
||||||
|
1
gnunet
Submodule
1
gnunet
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit 674d59da9956998c0e33ad1a3aa9facc3ba66d10
|
122
m4/libgcrypt.m4
Normal file
122
m4/libgcrypt.m4
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
dnl Autoconf macros for libgcrypt
|
||||||
|
dnl Copyright (C) 2002, 2004, 2011 Free Software Foundation, Inc.
|
||||||
|
dnl
|
||||||
|
dnl This file is free software; as a special exception the author gives
|
||||||
|
dnl unlimited permission to copy and/or distribute it, with or without
|
||||||
|
dnl modifications, as long as this notice is preserved.
|
||||||
|
dnl
|
||||||
|
dnl This file is distributed in the hope that it will be useful, but
|
||||||
|
dnl WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
|
||||||
|
dnl implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
|
||||||
|
dnl AM_PATH_LIBGCRYPT([MINIMUM-VERSION,
|
||||||
|
dnl [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]])
|
||||||
|
dnl Test for libgcrypt and define LIBGCRYPT_CFLAGS and LIBGCRYPT_LIBS.
|
||||||
|
dnl MINIMUN-VERSION is a string with the version number optionalliy prefixed
|
||||||
|
dnl with the API version to also check the API compatibility. Example:
|
||||||
|
dnl a MINIMUN-VERSION of 1:1.2.5 won't pass the test unless the installed
|
||||||
|
dnl version of libgcrypt is at least 1.2.5 *and* the API number is 1. Using
|
||||||
|
dnl this features allows to prevent build against newer versions of libgcrypt
|
||||||
|
dnl with a changed API.
|
||||||
|
dnl
|
||||||
|
AC_DEFUN([AM_PATH_LIBGCRYPT],
|
||||||
|
[ AC_REQUIRE([AC_CANONICAL_HOST])
|
||||||
|
AC_ARG_WITH(libgcrypt-prefix,
|
||||||
|
AC_HELP_STRING([--with-libgcrypt-prefix=PFX],
|
||||||
|
[prefix where LIBGCRYPT is installed (optional)]),
|
||||||
|
libgcrypt_config_prefix="$withval", libgcrypt_config_prefix="")
|
||||||
|
if test x$libgcrypt_config_prefix != x ; then
|
||||||
|
if test x${LIBGCRYPT_CONFIG+set} != xset ; then
|
||||||
|
LIBGCRYPT_CONFIG=$libgcrypt_config_prefix/bin/libgcrypt-config
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_PATH_TOOL(LIBGCRYPT_CONFIG, libgcrypt-config, no)
|
||||||
|
tmp=ifelse([$1], ,1:1.2.0,$1)
|
||||||
|
if echo "$tmp" | grep ':' >/dev/null 2>/dev/null ; then
|
||||||
|
req_libgcrypt_api=`echo "$tmp" | sed 's/\(.*\):\(.*\)/\1/'`
|
||||||
|
min_libgcrypt_version=`echo "$tmp" | sed 's/\(.*\):\(.*\)/\2/'`
|
||||||
|
else
|
||||||
|
req_libgcrypt_api=0
|
||||||
|
min_libgcrypt_version="$tmp"
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_MSG_CHECKING(for LIBGCRYPT - version >= $min_libgcrypt_version)
|
||||||
|
ok=no
|
||||||
|
if test "$LIBGCRYPT_CONFIG" != "no" ; then
|
||||||
|
req_major=`echo $min_libgcrypt_version | \
|
||||||
|
sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\1/'`
|
||||||
|
req_minor=`echo $min_libgcrypt_version | \
|
||||||
|
sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\2/'`
|
||||||
|
req_micro=`echo $min_libgcrypt_version | \
|
||||||
|
sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\3/'`
|
||||||
|
libgcrypt_config_version=`$LIBGCRYPT_CONFIG --version`
|
||||||
|
major=`echo $libgcrypt_config_version | \
|
||||||
|
sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\1/'`
|
||||||
|
minor=`echo $libgcrypt_config_version | \
|
||||||
|
sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\2/'`
|
||||||
|
micro=`echo $libgcrypt_config_version | \
|
||||||
|
sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\3/'`
|
||||||
|
if test "$major" -gt "$req_major"; then
|
||||||
|
ok=yes
|
||||||
|
else
|
||||||
|
if test "$major" -eq "$req_major"; then
|
||||||
|
if test "$minor" -gt "$req_minor"; then
|
||||||
|
ok=yes
|
||||||
|
else
|
||||||
|
if test "$minor" -eq "$req_minor"; then
|
||||||
|
if test "$micro" -ge "$req_micro"; then
|
||||||
|
ok=yes
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if test $ok = yes; then
|
||||||
|
AC_MSG_RESULT([yes ($libgcrypt_config_version)])
|
||||||
|
else
|
||||||
|
AC_MSG_RESULT(no)
|
||||||
|
fi
|
||||||
|
if test $ok = yes; then
|
||||||
|
# If we have a recent libgcrypt, we should also check that the
|
||||||
|
# API is compatible
|
||||||
|
if test "$req_libgcrypt_api" -gt 0 ; then
|
||||||
|
tmp=`$LIBGCRYPT_CONFIG --api-version 2>/dev/null || echo 0`
|
||||||
|
if test "$tmp" -gt 0 ; then
|
||||||
|
AC_MSG_CHECKING([LIBGCRYPT API version])
|
||||||
|
if test "$req_libgcrypt_api" -eq "$tmp" ; then
|
||||||
|
AC_MSG_RESULT([okay])
|
||||||
|
else
|
||||||
|
ok=no
|
||||||
|
AC_MSG_RESULT([does not match. want=$req_libgcrypt_api got=$tmp])
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if test $ok = yes; then
|
||||||
|
LIBGCRYPT_CFLAGS=`$LIBGCRYPT_CONFIG --cflags`
|
||||||
|
LIBGCRYPT_LIBS=`$LIBGCRYPT_CONFIG --libs`
|
||||||
|
ifelse([$2], , :, [$2])
|
||||||
|
libgcrypt_config_host=`$LIBGCRYPT_CONFIG --host 2>/dev/null || echo none`
|
||||||
|
if test x"$libgcrypt_config_host" != xnone ; then
|
||||||
|
if test x"$libgcrypt_config_host" != x"$host" ; then
|
||||||
|
AC_MSG_WARN([[
|
||||||
|
***
|
||||||
|
*** The config script $LIBGCRYPT_CONFIG was
|
||||||
|
*** built for $libgcrypt_config_host and thus may not match the
|
||||||
|
*** used host $host.
|
||||||
|
*** You may want to use the configure option --with-libgcrypt-prefix
|
||||||
|
*** to specify a matching config script.
|
||||||
|
***]])
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
LIBGCRYPT_CFLAGS=""
|
||||||
|
LIBGCRYPT_LIBS=""
|
||||||
|
ifelse([$3], , :, [$3])
|
||||||
|
fi
|
||||||
|
AC_SUBST(LIBGCRYPT_CFLAGS)
|
||||||
|
AC_SUBST(LIBGCRYPT_LIBS)
|
||||||
|
])
|
@ -12,7 +12,8 @@ pkgcfg_DATA = \
|
|||||||
auditordb-postgres.conf
|
auditordb-postgres.conf
|
||||||
|
|
||||||
EXTRA_DIST = \
|
EXTRA_DIST = \
|
||||||
auditordb-postgres.conf
|
auditordb-postgres.conf \
|
||||||
|
test-auditor-db-postgres.conf
|
||||||
|
|
||||||
plugindir = $(libdir)/taler
|
plugindir = $(libdir)/taler
|
||||||
|
|
||||||
@ -49,5 +50,21 @@ libtalerauditordb_la_LDFLAGS = \
|
|||||||
-no-undefined
|
-no-undefined
|
||||||
|
|
||||||
|
|
||||||
EXTRA_test_auditordb_postgres_DEPENDENCIES = \
|
#EXTRA_test_auditordb_postgres_DEPENDENCIES = \
|
||||||
libtaler_plugin_auditordb_postgres.la
|
# libtaler_plugin_auditordb_postgres.la
|
||||||
|
|
||||||
|
|
||||||
|
check_PROGRAMS = \
|
||||||
|
test-auditordb-postgres
|
||||||
|
|
||||||
|
AM_TESTS_ENVIRONMENT=export TALER_PREFIX=$${TALER_PREFIX:-@libdir@};export PATH=$${TALER_PREFIX:-@prefix@}/bin:$$PATH;
|
||||||
|
TESTS = \
|
||||||
|
test-auditordb-postgres
|
||||||
|
|
||||||
|
test_auditordb_postgres_SOURCES = \
|
||||||
|
test_auditordb.c
|
||||||
|
test_auditordb_postgres_LDADD = \
|
||||||
|
libtalerauditordb.la \
|
||||||
|
$(top_srcdir)/src/pq/libtalerpq.la \
|
||||||
|
$(top_srcdir)/src/util/libtalerutil.la \
|
||||||
|
-lgnunetutil
|
||||||
|
File diff suppressed because it is too large
Load Diff
7
src/auditordb/test-auditor-db-postgres.conf
Normal file
7
src/auditordb/test-auditor-db-postgres.conf
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
[auditor]
|
||||||
|
# Which database backend do we use for the auditor?
|
||||||
|
DB = postgres
|
||||||
|
|
||||||
|
[auditordb-postgres]
|
||||||
|
# Argument for Postgres for how to connect to the database.
|
||||||
|
DB_CONN_STR = "postgres:///talercheck"
|
798
src/auditordb/test_auditordb.c
Normal file
798
src/auditordb/test_auditordb.c
Normal file
@ -0,0 +1,798 @@
|
|||||||
|
/*
|
||||||
|
This file is part of TALER
|
||||||
|
Copyright (C) 2016 GNUnet e.V. and INRIA
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along with
|
||||||
|
TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @file auditordb/test_auditordb.c
|
||||||
|
* @brief test cases for DB interaction functions
|
||||||
|
* @author Gabor X Toth
|
||||||
|
*/
|
||||||
|
#include "platform.h"
|
||||||
|
#include "taler_auditordb_lib.h"
|
||||||
|
#include "taler_auditordb_plugin.h"
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Global result from the testcase.
|
||||||
|
*/
|
||||||
|
static int result = -1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Report line of error if @a cond is true, and jump to label "drop".
|
||||||
|
*/
|
||||||
|
#define FAILIF(cond) \
|
||||||
|
do { \
|
||||||
|
if (!(cond)){ break;} \
|
||||||
|
GNUNET_break (0); \
|
||||||
|
goto drop; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes @a ptr with random data.
|
||||||
|
*/
|
||||||
|
#define RND_BLK(ptr) \
|
||||||
|
GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, ptr, sizeof (*ptr))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes @a ptr with zeros.
|
||||||
|
*/
|
||||||
|
#define ZR_BLK(ptr) \
|
||||||
|
memset (ptr, 0, sizeof (*ptr))
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Currency we use.
|
||||||
|
*/
|
||||||
|
#define CURRENCY "EUR"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Database plugin under test.
|
||||||
|
*/
|
||||||
|
static struct TALER_AUDITORDB_Plugin *plugin;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main function that will be run by the scheduler.
|
||||||
|
*
|
||||||
|
* @param cls closure with config
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
run (void *cls)
|
||||||
|
{
|
||||||
|
struct GNUNET_CONFIGURATION_Handle *cfg = cls;
|
||||||
|
struct TALER_AUDITORDB_Session *session;
|
||||||
|
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||||
|
"loading database plugin\n");
|
||||||
|
|
||||||
|
if (NULL ==
|
||||||
|
(plugin = TALER_AUDITORDB_plugin_load (cfg)))
|
||||||
|
{
|
||||||
|
result = 77;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
(void) plugin->drop_tables (plugin->cls);
|
||||||
|
if (GNUNET_OK !=
|
||||||
|
plugin->create_tables (plugin->cls))
|
||||||
|
{
|
||||||
|
result = 77;
|
||||||
|
goto drop;
|
||||||
|
}
|
||||||
|
if (NULL ==
|
||||||
|
(session = plugin->get_session (plugin->cls)))
|
||||||
|
{
|
||||||
|
result = 77;
|
||||||
|
goto drop;
|
||||||
|
}
|
||||||
|
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||||
|
"initializing\n");
|
||||||
|
|
||||||
|
struct TALER_Amount value, fee_withdraw, fee_deposit, fee_refresh, fee_refund;
|
||||||
|
|
||||||
|
GNUNET_assert (GNUNET_OK ==
|
||||||
|
TALER_string_to_amount (CURRENCY ":1.000010",
|
||||||
|
&value));
|
||||||
|
GNUNET_assert (GNUNET_OK ==
|
||||||
|
TALER_string_to_amount (CURRENCY ":0.000011",
|
||||||
|
&fee_withdraw));
|
||||||
|
GNUNET_assert (GNUNET_OK ==
|
||||||
|
TALER_string_to_amount (CURRENCY ":0.000012",
|
||||||
|
&fee_deposit));
|
||||||
|
GNUNET_assert (GNUNET_OK ==
|
||||||
|
TALER_string_to_amount (CURRENCY ":0.000013",
|
||||||
|
&fee_refresh));
|
||||||
|
GNUNET_assert (GNUNET_OK ==
|
||||||
|
TALER_string_to_amount (CURRENCY ":0.000014",
|
||||||
|
&fee_refund));
|
||||||
|
|
||||||
|
struct TALER_MasterPublicKeyP master_pub;
|
||||||
|
struct TALER_ReservePublicKeyP reserve_pub;
|
||||||
|
struct GNUNET_HashCode rnd_hash;
|
||||||
|
RND_BLK (&master_pub);
|
||||||
|
RND_BLK (&reserve_pub);
|
||||||
|
RND_BLK (&rnd_hash);
|
||||||
|
|
||||||
|
struct TALER_DenominationPrivateKey denom_priv;
|
||||||
|
struct TALER_DenominationPublicKey denom_pub;
|
||||||
|
struct GNUNET_HashCode denom_pub_hash;
|
||||||
|
denom_priv.rsa_private_key = GNUNET_CRYPTO_rsa_private_key_create (1024);
|
||||||
|
denom_pub.rsa_public_key = GNUNET_CRYPTO_rsa_private_key_get_public (denom_priv.rsa_private_key);
|
||||||
|
GNUNET_CRYPTO_rsa_public_key_hash (denom_pub.rsa_public_key, &denom_pub_hash);
|
||||||
|
|
||||||
|
struct GNUNET_TIME_Absolute now, past, future, date;
|
||||||
|
now = GNUNET_TIME_absolute_get ();
|
||||||
|
past = GNUNET_TIME_absolute_subtract (now,
|
||||||
|
GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS,
|
||||||
|
4));
|
||||||
|
future = GNUNET_TIME_absolute_add (now,
|
||||||
|
GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS,
|
||||||
|
4));
|
||||||
|
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||||
|
"Test: insert_denomination_info\n");
|
||||||
|
|
||||||
|
struct TALER_DenominationKeyValidityPS issue = { 0 };
|
||||||
|
issue.master = master_pub;
|
||||||
|
issue.denom_hash = denom_pub_hash;
|
||||||
|
|
||||||
|
issue.start = GNUNET_TIME_absolute_hton (now);
|
||||||
|
issue.expire_withdraw = GNUNET_TIME_absolute_hton
|
||||||
|
(GNUNET_TIME_absolute_add (now,
|
||||||
|
GNUNET_TIME_UNIT_HOURS));
|
||||||
|
issue.expire_deposit = GNUNET_TIME_absolute_hton
|
||||||
|
(GNUNET_TIME_absolute_add
|
||||||
|
(now,
|
||||||
|
GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 2)));
|
||||||
|
issue.expire_legal = GNUNET_TIME_absolute_hton
|
||||||
|
(GNUNET_TIME_absolute_add
|
||||||
|
(now,
|
||||||
|
GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 3)));
|
||||||
|
TALER_amount_hton (&issue.value, &value);
|
||||||
|
TALER_amount_hton (&issue.fee_withdraw, &fee_withdraw);
|
||||||
|
TALER_amount_hton (&issue.fee_deposit, &fee_deposit);
|
||||||
|
TALER_amount_hton (&issue.fee_refresh, &fee_refresh);
|
||||||
|
TALER_amount_hton (&issue.fee_refund, &fee_refund);
|
||||||
|
|
||||||
|
FAILIF (GNUNET_OK !=
|
||||||
|
plugin->insert_denomination_info (plugin->cls,
|
||||||
|
session,
|
||||||
|
&issue));
|
||||||
|
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||||
|
"Test: select_denomination_info\n");
|
||||||
|
|
||||||
|
int
|
||||||
|
select_denomination_info_result (void *cls,
|
||||||
|
const struct TALER_DenominationKeyValidityPS *issue2)
|
||||||
|
{
|
||||||
|
const struct TALER_DenominationKeyValidityPS *issue1 = cls;
|
||||||
|
|
||||||
|
if (0 != memcmp (issue1, issue2, sizeof (*issue2)))
|
||||||
|
{
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||||
|
"select_denomination_info_result: issue does not match\n");
|
||||||
|
GNUNET_break (0);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
return GNUNET_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
FAILIF (GNUNET_OK !=
|
||||||
|
plugin->select_denomination_info (plugin->cls,
|
||||||
|
session,
|
||||||
|
&master_pub,
|
||||||
|
select_denomination_info_result,
|
||||||
|
&issue));
|
||||||
|
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||||
|
"Test: insert_auditor_progress\n");
|
||||||
|
|
||||||
|
uint64_t
|
||||||
|
last_reserve_in_serial_id = 1234,
|
||||||
|
last_reserve_out_serial_id = 5678,
|
||||||
|
last_deposit_serial_id = 123,
|
||||||
|
last_melt_serial_id = 456,
|
||||||
|
last_refund_serial_id = 789,
|
||||||
|
last_prewire_serial_id = 555,
|
||||||
|
|
||||||
|
last_reserve_in_serial_id2 = 0,
|
||||||
|
last_reserve_out_serial_id2 = 0,
|
||||||
|
last_deposit_serial_id2 = 0,
|
||||||
|
last_melt_serial_id2 = 0,
|
||||||
|
last_refund_serial_id2 = 0,
|
||||||
|
last_prewire_serial_id2 = 0;
|
||||||
|
|
||||||
|
FAILIF (GNUNET_OK !=
|
||||||
|
plugin->insert_auditor_progress (plugin->cls,
|
||||||
|
session,
|
||||||
|
&master_pub,
|
||||||
|
last_reserve_in_serial_id,
|
||||||
|
last_reserve_out_serial_id,
|
||||||
|
last_deposit_serial_id,
|
||||||
|
last_melt_serial_id,
|
||||||
|
last_refund_serial_id,
|
||||||
|
last_prewire_serial_id));
|
||||||
|
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||||
|
"Test: update_auditor_progress\n");
|
||||||
|
|
||||||
|
last_reserve_in_serial_id++;
|
||||||
|
last_reserve_out_serial_id++;
|
||||||
|
last_deposit_serial_id2++;
|
||||||
|
last_melt_serial_id2++;
|
||||||
|
last_refund_serial_id2++;
|
||||||
|
last_prewire_serial_id2++;
|
||||||
|
|
||||||
|
FAILIF (GNUNET_OK !=
|
||||||
|
plugin->update_auditor_progress (plugin->cls,
|
||||||
|
session,
|
||||||
|
&master_pub,
|
||||||
|
last_reserve_in_serial_id,
|
||||||
|
last_reserve_out_serial_id,
|
||||||
|
last_deposit_serial_id,
|
||||||
|
last_melt_serial_id,
|
||||||
|
last_refund_serial_id,
|
||||||
|
last_prewire_serial_id));
|
||||||
|
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||||
|
"Test: get_auditor_progress\n");
|
||||||
|
|
||||||
|
FAILIF (GNUNET_OK !=
|
||||||
|
plugin->get_auditor_progress (plugin->cls,
|
||||||
|
session,
|
||||||
|
&master_pub,
|
||||||
|
&last_reserve_in_serial_id2,
|
||||||
|
&last_reserve_out_serial_id2,
|
||||||
|
&last_deposit_serial_id2,
|
||||||
|
&last_melt_serial_id2,
|
||||||
|
&last_refund_serial_id2,
|
||||||
|
&last_prewire_serial_id2));
|
||||||
|
|
||||||
|
FAILIF (last_reserve_in_serial_id2 != last_reserve_in_serial_id
|
||||||
|
|| last_reserve_out_serial_id2 != last_reserve_out_serial_id
|
||||||
|
|| last_deposit_serial_id2 != last_deposit_serial_id
|
||||||
|
|| last_melt_serial_id2 != last_melt_serial_id
|
||||||
|
|| last_refund_serial_id2 != last_refund_serial_id
|
||||||
|
|| last_prewire_serial_id2 != last_prewire_serial_id);
|
||||||
|
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||||
|
"Test: insert_reserve_info\n");
|
||||||
|
|
||||||
|
struct TALER_Amount reserve_balance, withdraw_fee_balance;
|
||||||
|
struct TALER_Amount reserve_balance2 = {}, withdraw_fee_balance2 = {};
|
||||||
|
|
||||||
|
GNUNET_assert (GNUNET_OK ==
|
||||||
|
TALER_string_to_amount (CURRENCY ":12.345678",
|
||||||
|
&reserve_balance));
|
||||||
|
GNUNET_assert (GNUNET_OK ==
|
||||||
|
TALER_string_to_amount (CURRENCY ":23.456789",
|
||||||
|
&withdraw_fee_balance));
|
||||||
|
|
||||||
|
FAILIF (GNUNET_OK !=
|
||||||
|
plugin->insert_reserve_info (plugin->cls,
|
||||||
|
session,
|
||||||
|
&reserve_pub,
|
||||||
|
&master_pub,
|
||||||
|
&reserve_balance,
|
||||||
|
&withdraw_fee_balance,
|
||||||
|
past,
|
||||||
|
last_reserve_in_serial_id,
|
||||||
|
last_reserve_out_serial_id));
|
||||||
|
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||||
|
"Test: update_reserve_info\n");
|
||||||
|
|
||||||
|
last_reserve_in_serial_id++;
|
||||||
|
last_reserve_out_serial_id++;
|
||||||
|
|
||||||
|
FAILIF (GNUNET_OK !=
|
||||||
|
plugin->update_reserve_info (plugin->cls,
|
||||||
|
session,
|
||||||
|
&reserve_pub,
|
||||||
|
&master_pub,
|
||||||
|
&reserve_balance,
|
||||||
|
&withdraw_fee_balance,
|
||||||
|
future,
|
||||||
|
last_reserve_in_serial_id,
|
||||||
|
last_reserve_out_serial_id));
|
||||||
|
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||||
|
"Test: get_reserve_info\n");
|
||||||
|
|
||||||
|
FAILIF (GNUNET_OK !=
|
||||||
|
plugin->get_reserve_info (plugin->cls,
|
||||||
|
session,
|
||||||
|
&reserve_pub,
|
||||||
|
&master_pub,
|
||||||
|
&reserve_balance2,
|
||||||
|
&withdraw_fee_balance2,
|
||||||
|
&date,
|
||||||
|
&last_reserve_in_serial_id2,
|
||||||
|
&last_reserve_out_serial_id2));
|
||||||
|
|
||||||
|
FAILIF (0 != memcmp (&date, &future, sizeof (future))
|
||||||
|
|| 0 != memcmp (&reserve_balance2, &reserve_balance, sizeof (reserve_balance))
|
||||||
|
|| 0 != memcmp (&withdraw_fee_balance2, &withdraw_fee_balance, sizeof (withdraw_fee_balance))
|
||||||
|
|| last_reserve_in_serial_id2 != last_reserve_in_serial_id
|
||||||
|
|| last_reserve_out_serial_id2 != last_reserve_out_serial_id);
|
||||||
|
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||||
|
"Test: insert_reserve_summary\n");
|
||||||
|
|
||||||
|
FAILIF (GNUNET_OK !=
|
||||||
|
plugin->insert_reserve_summary (plugin->cls,
|
||||||
|
session,
|
||||||
|
&master_pub,
|
||||||
|
&withdraw_fee_balance,
|
||||||
|
&reserve_balance));
|
||||||
|
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||||
|
"Test: update_reserve_summary\n");
|
||||||
|
|
||||||
|
FAILIF (GNUNET_OK !=
|
||||||
|
plugin->update_reserve_summary (plugin->cls,
|
||||||
|
session,
|
||||||
|
&master_pub,
|
||||||
|
&reserve_balance,
|
||||||
|
&withdraw_fee_balance));
|
||||||
|
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||||
|
"Test: get_reserve_summary\n");
|
||||||
|
|
||||||
|
ZR_BLK (&reserve_balance2);
|
||||||
|
ZR_BLK (&withdraw_fee_balance2);
|
||||||
|
|
||||||
|
FAILIF (GNUNET_OK !=
|
||||||
|
plugin->get_reserve_summary (plugin->cls,
|
||||||
|
session,
|
||||||
|
&master_pub,
|
||||||
|
&reserve_balance2,
|
||||||
|
&withdraw_fee_balance2));
|
||||||
|
|
||||||
|
FAILIF (0 != memcmp (&reserve_balance2, &reserve_balance, sizeof (reserve_balance))
|
||||||
|
|| 0 != memcmp (&withdraw_fee_balance2, &withdraw_fee_balance, sizeof (withdraw_fee_balance)));
|
||||||
|
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||||
|
"Test: insert_denomination_balance\n");
|
||||||
|
|
||||||
|
struct TALER_Amount denom_balance, deposit_fee_balance, melt_fee_balance, refund_fee_balance;
|
||||||
|
struct TALER_Amount denom_balance2, deposit_fee_balance2, melt_fee_balance2, refund_fee_balance2;
|
||||||
|
|
||||||
|
GNUNET_assert (GNUNET_OK ==
|
||||||
|
TALER_string_to_amount (CURRENCY ":12.345678",
|
||||||
|
&denom_balance));
|
||||||
|
GNUNET_assert (GNUNET_OK ==
|
||||||
|
TALER_string_to_amount (CURRENCY ":23.456789",
|
||||||
|
&deposit_fee_balance));
|
||||||
|
GNUNET_assert (GNUNET_OK ==
|
||||||
|
TALER_string_to_amount (CURRENCY ":34.567890",
|
||||||
|
&melt_fee_balance));
|
||||||
|
GNUNET_assert (GNUNET_OK ==
|
||||||
|
TALER_string_to_amount (CURRENCY ":45.678901",
|
||||||
|
&refund_fee_balance));
|
||||||
|
|
||||||
|
FAILIF (GNUNET_OK !=
|
||||||
|
plugin->insert_denomination_balance (plugin->cls,
|
||||||
|
session,
|
||||||
|
&denom_pub_hash,
|
||||||
|
&refund_fee_balance,
|
||||||
|
&melt_fee_balance,
|
||||||
|
&deposit_fee_balance,
|
||||||
|
&denom_balance,
|
||||||
|
last_reserve_out_serial_id,
|
||||||
|
last_deposit_serial_id,
|
||||||
|
last_melt_serial_id,
|
||||||
|
last_refund_serial_id));
|
||||||
|
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||||
|
"Test: update_denomination_balance\n");
|
||||||
|
|
||||||
|
last_reserve_out_serial_id++;
|
||||||
|
last_deposit_serial_id++;
|
||||||
|
last_melt_serial_id++;
|
||||||
|
last_refund_serial_id++;
|
||||||
|
|
||||||
|
FAILIF (GNUNET_OK !=
|
||||||
|
plugin->update_denomination_balance (plugin->cls,
|
||||||
|
session,
|
||||||
|
&denom_pub_hash,
|
||||||
|
&denom_balance,
|
||||||
|
&deposit_fee_balance,
|
||||||
|
&melt_fee_balance,
|
||||||
|
&refund_fee_balance,
|
||||||
|
last_reserve_out_serial_id,
|
||||||
|
last_deposit_serial_id,
|
||||||
|
last_melt_serial_id,
|
||||||
|
last_refund_serial_id));
|
||||||
|
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||||
|
"Test: get_denomination_balance\n");
|
||||||
|
|
||||||
|
FAILIF (GNUNET_OK !=
|
||||||
|
plugin->get_denomination_balance (plugin->cls,
|
||||||
|
session,
|
||||||
|
&denom_pub_hash,
|
||||||
|
&denom_balance2,
|
||||||
|
&deposit_fee_balance2,
|
||||||
|
&melt_fee_balance2,
|
||||||
|
&refund_fee_balance2,
|
||||||
|
&last_reserve_out_serial_id2,
|
||||||
|
&last_deposit_serial_id2,
|
||||||
|
&last_melt_serial_id2,
|
||||||
|
&last_refund_serial_id2));
|
||||||
|
|
||||||
|
FAILIF (0 != memcmp (&denom_balance2, &denom_balance, sizeof (denom_balance))
|
||||||
|
|| 0 != memcmp (&deposit_fee_balance2, &deposit_fee_balance, sizeof (deposit_fee_balance))
|
||||||
|
|| 0 != memcmp (&melt_fee_balance2, &melt_fee_balance, sizeof (melt_fee_balance))
|
||||||
|
|| 0 != memcmp (&refund_fee_balance2, &refund_fee_balance, sizeof (refund_fee_balance))
|
||||||
|
|| last_reserve_out_serial_id2 != last_reserve_out_serial_id
|
||||||
|
|| last_deposit_serial_id2 != last_deposit_serial_id
|
||||||
|
|| last_melt_serial_id2 != last_melt_serial_id
|
||||||
|
|| last_refund_serial_id2 != last_refund_serial_id);
|
||||||
|
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||||
|
"Test: insert_denomination_summary\n");
|
||||||
|
|
||||||
|
FAILIF (GNUNET_OK !=
|
||||||
|
plugin->insert_denomination_summary (plugin->cls,
|
||||||
|
session,
|
||||||
|
&master_pub,
|
||||||
|
&refund_fee_balance,
|
||||||
|
&melt_fee_balance,
|
||||||
|
&deposit_fee_balance,
|
||||||
|
&denom_balance));
|
||||||
|
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||||
|
"Test: update_denomination_summary\n");
|
||||||
|
|
||||||
|
FAILIF (GNUNET_OK !=
|
||||||
|
plugin->update_denomination_summary (plugin->cls,
|
||||||
|
session,
|
||||||
|
&master_pub,
|
||||||
|
&denom_balance,
|
||||||
|
&deposit_fee_balance,
|
||||||
|
&melt_fee_balance,
|
||||||
|
&refund_fee_balance));
|
||||||
|
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||||
|
"Test: get_denomination_summary\n");
|
||||||
|
|
||||||
|
ZR_BLK (&denom_balance2);
|
||||||
|
ZR_BLK (&deposit_fee_balance2);
|
||||||
|
ZR_BLK (&melt_fee_balance2);
|
||||||
|
ZR_BLK (&refund_fee_balance2);
|
||||||
|
|
||||||
|
FAILIF (GNUNET_OK !=
|
||||||
|
plugin->get_denomination_summary (plugin->cls,
|
||||||
|
session,
|
||||||
|
&master_pub,
|
||||||
|
&denom_balance2,
|
||||||
|
&deposit_fee_balance2,
|
||||||
|
&melt_fee_balance2,
|
||||||
|
&refund_fee_balance2));
|
||||||
|
|
||||||
|
FAILIF (0 != memcmp (&denom_balance2, &denom_balance, sizeof (denom_balance))
|
||||||
|
|| 0 != memcmp (&deposit_fee_balance2, &deposit_fee_balance, sizeof (deposit_fee_balance))
|
||||||
|
|| 0 != memcmp (&melt_fee_balance2, &melt_fee_balance, sizeof (melt_fee_balance))
|
||||||
|
|| 0 != memcmp (&refund_fee_balance2, &refund_fee_balance, sizeof (refund_fee_balance)));
|
||||||
|
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||||
|
"Test: insert_risk_summary\n");
|
||||||
|
|
||||||
|
struct TALER_Amount balance, balance2;
|
||||||
|
|
||||||
|
GNUNET_assert (GNUNET_OK ==
|
||||||
|
TALER_string_to_amount (CURRENCY ":13.57986",
|
||||||
|
&balance));
|
||||||
|
|
||||||
|
FAILIF (GNUNET_OK !=
|
||||||
|
plugin->insert_risk_summary (plugin->cls,
|
||||||
|
session,
|
||||||
|
&master_pub,
|
||||||
|
&balance));
|
||||||
|
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||||
|
"Test: update_risk_summary\n");
|
||||||
|
|
||||||
|
GNUNET_assert (GNUNET_OK ==
|
||||||
|
TALER_string_to_amount (CURRENCY ":57.310986",
|
||||||
|
&balance));
|
||||||
|
|
||||||
|
FAILIF (GNUNET_OK !=
|
||||||
|
plugin->update_risk_summary (plugin->cls,
|
||||||
|
session,
|
||||||
|
&master_pub,
|
||||||
|
&balance));
|
||||||
|
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||||
|
"Test: get_risk_summary\n");
|
||||||
|
|
||||||
|
FAILIF (GNUNET_OK !=
|
||||||
|
plugin->get_risk_summary (plugin->cls,
|
||||||
|
session,
|
||||||
|
&master_pub,
|
||||||
|
&balance2));
|
||||||
|
|
||||||
|
FAILIF (0 != memcmp (&balance2, &balance, sizeof (balance)));
|
||||||
|
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||||
|
"Test: insert_historic_denom_revenue\n");
|
||||||
|
|
||||||
|
FAILIF (GNUNET_OK !=
|
||||||
|
plugin->insert_historic_denom_revenue (plugin->cls,
|
||||||
|
session,
|
||||||
|
&master_pub,
|
||||||
|
&denom_pub_hash,
|
||||||
|
past,
|
||||||
|
&balance,
|
||||||
|
&deposit_fee_balance,
|
||||||
|
&melt_fee_balance,
|
||||||
|
&refund_fee_balance));
|
||||||
|
|
||||||
|
FAILIF (GNUNET_OK !=
|
||||||
|
plugin->insert_historic_denom_revenue (plugin->cls,
|
||||||
|
session,
|
||||||
|
&master_pub,
|
||||||
|
&rnd_hash,
|
||||||
|
now,
|
||||||
|
&balance,
|
||||||
|
&deposit_fee_balance,
|
||||||
|
&melt_fee_balance,
|
||||||
|
&refund_fee_balance));
|
||||||
|
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||||
|
"Test: select_historic_denom_revenue\n");
|
||||||
|
|
||||||
|
int
|
||||||
|
select_historic_denom_revenue_result (void *cls,
|
||||||
|
const struct GNUNET_HashCode *denom_pub_hash2,
|
||||||
|
struct GNUNET_TIME_Absolute revenue_timestamp2,
|
||||||
|
const struct TALER_Amount *revenue_balance2,
|
||||||
|
const struct TALER_Amount *deposit_fee_balance2,
|
||||||
|
const struct TALER_Amount *melt_fee_balance2,
|
||||||
|
const struct TALER_Amount *refund_fee_balance2)
|
||||||
|
{
|
||||||
|
static int n = 0;
|
||||||
|
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
|
||||||
|
"select_historic_denom_revenue_result: row %u\n", n);
|
||||||
|
|
||||||
|
if (2 <= n++
|
||||||
|
|| cls != NULL
|
||||||
|
|| (0 != memcmp (&revenue_timestamp2, &past, sizeof (past))
|
||||||
|
&& 0 != memcmp (&revenue_timestamp2, &now, sizeof (now)))
|
||||||
|
|| (0 != memcmp (denom_pub_hash2, &denom_pub_hash, sizeof (denom_pub_hash))
|
||||||
|
&& 0 != memcmp (denom_pub_hash2, &rnd_hash, sizeof (rnd_hash)))
|
||||||
|
|| 0 != memcmp (revenue_balance2, &balance, sizeof (balance))
|
||||||
|
|| 0 != memcmp (deposit_fee_balance2, &deposit_fee_balance, sizeof (deposit_fee_balance))
|
||||||
|
|| 0 != memcmp (melt_fee_balance2, &melt_fee_balance, sizeof (melt_fee_balance))
|
||||||
|
|| 0 != memcmp (refund_fee_balance2, &refund_fee_balance, sizeof (refund_fee_balance)))
|
||||||
|
{
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||||
|
"select_historic_denom_revenue_result: result does not match\n");
|
||||||
|
GNUNET_break (0);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
return GNUNET_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
FAILIF (GNUNET_OK !=
|
||||||
|
plugin->select_historic_denom_revenue (plugin->cls,
|
||||||
|
session,
|
||||||
|
&master_pub,
|
||||||
|
select_historic_denom_revenue_result,
|
||||||
|
NULL));
|
||||||
|
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||||
|
"Test: insert_historic_losses\n");
|
||||||
|
|
||||||
|
FAILIF (GNUNET_OK !=
|
||||||
|
plugin->insert_historic_losses (plugin->cls,
|
||||||
|
session,
|
||||||
|
&master_pub,
|
||||||
|
&denom_pub_hash,
|
||||||
|
past,
|
||||||
|
&balance));
|
||||||
|
|
||||||
|
FAILIF (GNUNET_OK !=
|
||||||
|
plugin->insert_historic_losses (plugin->cls,
|
||||||
|
session,
|
||||||
|
&master_pub,
|
||||||
|
&rnd_hash,
|
||||||
|
past,
|
||||||
|
&balance));
|
||||||
|
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||||
|
"Test: select_historic_losses\n");
|
||||||
|
|
||||||
|
int
|
||||||
|
select_historic_losses_result (void *cls,
|
||||||
|
const struct GNUNET_HashCode *denom_pub_hash2,
|
||||||
|
struct GNUNET_TIME_Absolute loss_timestamp2,
|
||||||
|
const struct TALER_Amount *loss_balance2)
|
||||||
|
{
|
||||||
|
static int n = 0;
|
||||||
|
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
|
||||||
|
"select_historic_losses_result: row %u\n", n);
|
||||||
|
|
||||||
|
if (2 <= n++
|
||||||
|
|| cls != NULL
|
||||||
|
|| (0 != memcmp (&loss_timestamp2, &past, sizeof (past))
|
||||||
|
&& 0 != memcmp (&loss_timestamp2, &now, sizeof (now)))
|
||||||
|
|| (0 != memcmp (denom_pub_hash2, &denom_pub_hash, sizeof (denom_pub_hash))
|
||||||
|
&& 0 != memcmp (denom_pub_hash2, &rnd_hash, sizeof (rnd_hash)))
|
||||||
|
|| 0 != memcmp (loss_balance2, &balance, sizeof (balance)))
|
||||||
|
{
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||||
|
"select_historic_denom_revenue_result: result does not match\n");
|
||||||
|
GNUNET_break (0);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
return GNUNET_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
FAILIF (GNUNET_OK !=
|
||||||
|
plugin->select_historic_losses (plugin->cls,
|
||||||
|
session,
|
||||||
|
&master_pub,
|
||||||
|
select_historic_losses_result,
|
||||||
|
NULL));
|
||||||
|
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||||
|
"Test: insert_historic_reserve_revenue\n");
|
||||||
|
|
||||||
|
struct TALER_Amount reserve_profits;
|
||||||
|
GNUNET_assert (GNUNET_OK ==
|
||||||
|
TALER_string_to_amount (CURRENCY ":56.789012",
|
||||||
|
&reserve_profits));
|
||||||
|
|
||||||
|
FAILIF (GNUNET_OK !=
|
||||||
|
plugin->insert_historic_reserve_revenue (plugin->cls,
|
||||||
|
session,
|
||||||
|
&master_pub,
|
||||||
|
past,
|
||||||
|
future,
|
||||||
|
&reserve_profits));
|
||||||
|
|
||||||
|
FAILIF (GNUNET_OK !=
|
||||||
|
plugin->insert_historic_reserve_revenue (plugin->cls,
|
||||||
|
session,
|
||||||
|
&master_pub,
|
||||||
|
now,
|
||||||
|
future,
|
||||||
|
&reserve_profits));
|
||||||
|
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||||
|
"Test: select_historic_reserve_revenue\n");
|
||||||
|
|
||||||
|
int
|
||||||
|
select_historic_reserve_revenue_result (void *cls,
|
||||||
|
struct GNUNET_TIME_Absolute start_time2,
|
||||||
|
struct GNUNET_TIME_Absolute end_time2,
|
||||||
|
const struct TALER_Amount *reserve_profits2)
|
||||||
|
{
|
||||||
|
static int n = 0;
|
||||||
|
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
|
||||||
|
"select_historic_reserve_revenue_result: row %u\n", n);
|
||||||
|
|
||||||
|
if (2 <= n++
|
||||||
|
|| cls != NULL
|
||||||
|
|| (0 != memcmp (&start_time2, &past, sizeof (past))
|
||||||
|
&& 0 != memcmp (&start_time2, &now, sizeof (now)))
|
||||||
|
|| 0 != memcmp (&end_time2, &future, sizeof (future))
|
||||||
|
|| 0 != memcmp (reserve_profits2, &reserve_profits, sizeof (reserve_profits)))
|
||||||
|
{
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||||
|
"select_historic_reserve_revenue_result: result does not match\n");
|
||||||
|
GNUNET_break (0);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
return GNUNET_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
FAILIF (GNUNET_OK !=
|
||||||
|
plugin->select_historic_reserve_revenue (plugin->cls,
|
||||||
|
session,
|
||||||
|
&master_pub,
|
||||||
|
select_historic_reserve_revenue_result,
|
||||||
|
NULL));
|
||||||
|
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||||
|
"Test: insert_predicted_result\n");
|
||||||
|
|
||||||
|
FAILIF (GNUNET_OK !=
|
||||||
|
plugin->insert_predicted_result (plugin->cls,
|
||||||
|
session,
|
||||||
|
&master_pub,
|
||||||
|
&balance));
|
||||||
|
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||||
|
"Test: update_predicted_result\n");
|
||||||
|
|
||||||
|
GNUNET_assert (GNUNET_OK ==
|
||||||
|
TALER_string_to_amount (CURRENCY ":78.901234",
|
||||||
|
&balance));
|
||||||
|
|
||||||
|
FAILIF (GNUNET_OK !=
|
||||||
|
plugin->update_predicted_result (plugin->cls,
|
||||||
|
session,
|
||||||
|
&master_pub,
|
||||||
|
&balance));
|
||||||
|
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||||
|
"Test: get_predicted_balance\n");
|
||||||
|
|
||||||
|
FAILIF (GNUNET_OK !=
|
||||||
|
plugin->get_predicted_balance (plugin->cls,
|
||||||
|
session,
|
||||||
|
&master_pub,
|
||||||
|
&balance2));
|
||||||
|
|
||||||
|
FAILIF (0 != memcmp (&balance2, &balance, sizeof (balance)));
|
||||||
|
|
||||||
|
result = 0;
|
||||||
|
|
||||||
|
drop:
|
||||||
|
|
||||||
|
GNUNET_break (GNUNET_OK ==
|
||||||
|
plugin->drop_tables (plugin->cls));
|
||||||
|
TALER_AUDITORDB_plugin_unload (plugin);
|
||||||
|
plugin = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
main (int argc,
|
||||||
|
char *const argv[])
|
||||||
|
{
|
||||||
|
const char *plugin_name;
|
||||||
|
char *config_filename;
|
||||||
|
char *testname;
|
||||||
|
struct GNUNET_CONFIGURATION_Handle *cfg;
|
||||||
|
|
||||||
|
result = -1;
|
||||||
|
if (NULL == (plugin_name = strrchr (argv[0], (int) '-')))
|
||||||
|
{
|
||||||
|
GNUNET_break (0);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
GNUNET_log_setup (argv[0],
|
||||||
|
"WARNING",
|
||||||
|
NULL);
|
||||||
|
plugin_name++;
|
||||||
|
(void) GNUNET_asprintf (&testname,
|
||||||
|
"test-auditor-db-%s", plugin_name);
|
||||||
|
(void) GNUNET_asprintf (&config_filename,
|
||||||
|
"%s.conf", testname);
|
||||||
|
cfg = GNUNET_CONFIGURATION_create ();
|
||||||
|
if (GNUNET_OK !=
|
||||||
|
GNUNET_CONFIGURATION_parse (cfg,
|
||||||
|
config_filename))
|
||||||
|
{
|
||||||
|
GNUNET_break (0);
|
||||||
|
GNUNET_free (config_filename);
|
||||||
|
GNUNET_free (testname);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
GNUNET_SCHEDULER_run (&run, cfg);
|
||||||
|
GNUNET_CONFIGURATION_destroy (cfg);
|
||||||
|
GNUNET_free (config_filename);
|
||||||
|
GNUNET_free (testname);
|
||||||
|
return result;
|
||||||
|
}
|
@ -67,22 +67,35 @@ main (int argc,
|
|||||||
char * const *argv)
|
char * const *argv)
|
||||||
{
|
{
|
||||||
struct GNUNET_OS_Process *bankd;
|
struct GNUNET_OS_Process *bankd;
|
||||||
|
struct GNUNET_OS_Process *bankd_admin;
|
||||||
unsigned int cnt;
|
unsigned int cnt;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
GNUNET_log_setup ("test-bank-api",
|
GNUNET_log_setup ("test-bank-api",
|
||||||
"WARNING",
|
"WARNING",
|
||||||
NULL);
|
NULL);
|
||||||
|
bankd_admin = GNUNET_OS_start_process (GNUNET_NO,
|
||||||
|
GNUNET_OS_INHERIT_STD_ALL,
|
||||||
|
NULL, NULL, NULL,
|
||||||
|
"taler-bank-manage",
|
||||||
|
"taler-bank-manage",
|
||||||
|
"--admin",
|
||||||
|
"serve-http",
|
||||||
|
"--port", "8081",
|
||||||
|
NULL);
|
||||||
bankd = GNUNET_OS_start_process (GNUNET_NO,
|
bankd = GNUNET_OS_start_process (GNUNET_NO,
|
||||||
GNUNET_OS_INHERIT_STD_ALL,
|
GNUNET_OS_INHERIT_STD_ALL,
|
||||||
NULL, NULL, NULL,
|
NULL, NULL, NULL,
|
||||||
"taler-bank-manage",
|
"taler-bank-manage",
|
||||||
"taler-bank-manage",
|
"taler-bank-manage",
|
||||||
"serve-http",
|
"serve-http",
|
||||||
"--port", "8081",
|
"--port", "8080",
|
||||||
NULL);
|
NULL);
|
||||||
if (NULL == bankd)
|
|
||||||
|
|
||||||
|
if ((NULL == bankd_admin) || (NULL == bankd))
|
||||||
{
|
{
|
||||||
|
/*FIXME: More accurate error message?*/
|
||||||
fprintf (stderr,
|
fprintf (stderr,
|
||||||
"taler-bank-manage not found, skipping test\n");
|
"taler-bank-manage not found, skipping test\n");
|
||||||
return 77; /* report 'skip' */
|
return 77; /* report 'skip' */
|
||||||
@ -99,13 +112,26 @@ main (int argc,
|
|||||||
if (cnt > 30)
|
if (cnt > 30)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
while (0 != system ("wget -q -t 1 -T 1 http://127.0.0.1:8081/ -o /dev/null -O /dev/null"));
|
while (0 != system ("wget -q -t 1 -T 1 http://127.0.0.1:8080/ -o /dev/null -O /dev/null"));
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
fprintf (stderr, ".");
|
||||||
|
sleep (1);
|
||||||
|
cnt++;
|
||||||
|
if (cnt > 30)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
while (0 != system ("wget -q -t 1 -T 1 http://127.0.0.1:8081/admin/add/incoming -o /dev/null -O /dev/null"));
|
||||||
|
|
||||||
fprintf (stderr, "\n");
|
fprintf (stderr, "\n");
|
||||||
result = GNUNET_SYSERR;
|
result = GNUNET_SYSERR;
|
||||||
if (cnt <= 30)
|
if (cnt <= 30)
|
||||||
GNUNET_SCHEDULER_run (&run, &result);
|
GNUNET_SCHEDULER_run (&run, &result);
|
||||||
GNUNET_OS_process_kill (bankd,
|
GNUNET_OS_process_kill (bankd,
|
||||||
SIGTERM);
|
SIGTERM);
|
||||||
|
GNUNET_OS_process_kill (bankd_admin,
|
||||||
|
SIGTERM);
|
||||||
GNUNET_OS_process_wait (bankd);
|
GNUNET_OS_process_wait (bankd);
|
||||||
GNUNET_OS_process_destroy (bankd);
|
GNUNET_OS_process_destroy (bankd);
|
||||||
if (cnt > 30)
|
if (cnt > 30)
|
||||||
|
@ -541,6 +541,7 @@ find_pk (const struct TALER_EXCHANGE_Keys *keys,
|
|||||||
* @param cls closure with the `struct Coin *`
|
* @param cls closure with the `struct Coin *`
|
||||||
* @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful status request
|
* @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful status request
|
||||||
* 0 if the exchange's reply is bogus (fails to follow the protocol)
|
* 0 if the exchange's reply is bogus (fails to follow the protocol)
|
||||||
|
* @param ec taler-specific error code, #TALER_EC_NONE on success
|
||||||
* @param num_coins number of fresh coins created, length of the @a sigs and @a coin_privs arrays, 0 if the operation failed
|
* @param num_coins number of fresh coins created, length of the @a sigs and @a coin_privs arrays, 0 if the operation failed
|
||||||
* @param coin_privs array of @a num_coins private keys for the coins that were created, NULL on error
|
* @param coin_privs array of @a num_coins private keys for the coins that were created, NULL on error
|
||||||
* @param sigs array of signature over @a num_coins coins, NULL on error
|
* @param sigs array of signature over @a num_coins coins, NULL on error
|
||||||
@ -549,6 +550,7 @@ find_pk (const struct TALER_EXCHANGE_Keys *keys,
|
|||||||
static void
|
static void
|
||||||
reveal_cb (void *cls,
|
reveal_cb (void *cls,
|
||||||
unsigned int http_status,
|
unsigned int http_status,
|
||||||
|
enum TALER_ErrorCode ec,
|
||||||
unsigned int num_coins,
|
unsigned int num_coins,
|
||||||
const struct TALER_CoinSpendPrivateKeyP *coin_privs,
|
const struct TALER_CoinSpendPrivateKeyP *coin_privs,
|
||||||
const struct TALER_DenominationSignature *sigs,
|
const struct TALER_DenominationSignature *sigs,
|
||||||
@ -617,6 +619,7 @@ reveal_cb (void *cls,
|
|||||||
* @param cls closure with the `struct Coin *`
|
* @param cls closure with the `struct Coin *`
|
||||||
* @param http_status HTTP response code, never #MHD_HTTP_OK (200) as for successful intermediate response this callback is skipped.
|
* @param http_status HTTP response code, never #MHD_HTTP_OK (200) as for successful intermediate response this callback is skipped.
|
||||||
* 0 if the exchange's reply is bogus (fails to follow the protocol)
|
* 0 if the exchange's reply is bogus (fails to follow the protocol)
|
||||||
|
* @param ec taler-specific error code, #TALER_EC_NONE on success
|
||||||
* @param noreveal_index choice by the exchange in the cut-and-choose protocol,
|
* @param noreveal_index choice by the exchange in the cut-and-choose protocol,
|
||||||
* UINT16_MAX on error
|
* UINT16_MAX on error
|
||||||
* @param exchange_pub public key the exchange used for signing
|
* @param exchange_pub public key the exchange used for signing
|
||||||
@ -625,6 +628,7 @@ reveal_cb (void *cls,
|
|||||||
static void
|
static void
|
||||||
melt_cb (void *cls,
|
melt_cb (void *cls,
|
||||||
unsigned int http_status,
|
unsigned int http_status,
|
||||||
|
enum TALER_ErrorCode ec,
|
||||||
uint16_t noreveal_index,
|
uint16_t noreveal_index,
|
||||||
const struct TALER_ExchangePublicKeyP *exchange_pub,
|
const struct TALER_ExchangePublicKeyP *exchange_pub,
|
||||||
const json_t *full_response)
|
const json_t *full_response)
|
||||||
@ -776,6 +780,7 @@ refresh_coin (struct Coin *coin)
|
|||||||
* @param cls closure with the `struct Coin` that we are processing
|
* @param cls closure with the `struct Coin` that we are processing
|
||||||
* @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful deposit;
|
* @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful deposit;
|
||||||
* 0 if the exchange's reply is bogus (fails to follow the protocol)
|
* 0 if the exchange's reply is bogus (fails to follow the protocol)
|
||||||
|
* @param ec taler-specific error code, #TALER_EC_NONE on success
|
||||||
* @param exchange_pub public key used by the exchange for signing
|
* @param exchange_pub public key used by the exchange for signing
|
||||||
* @param obj the received JSON reply, should be kept as proof (and, in case of errors,
|
* @param obj the received JSON reply, should be kept as proof (and, in case of errors,
|
||||||
* be forwarded to the customer)
|
* be forwarded to the customer)
|
||||||
@ -783,6 +788,7 @@ refresh_coin (struct Coin *coin)
|
|||||||
static void
|
static void
|
||||||
deposit_cb (void *cls,
|
deposit_cb (void *cls,
|
||||||
unsigned int http_status,
|
unsigned int http_status,
|
||||||
|
enum TALER_ErrorCode ec,
|
||||||
const struct TALER_ExchangePublicKeyP *exchange_pub,
|
const struct TALER_ExchangePublicKeyP *exchange_pub,
|
||||||
const json_t *obj)
|
const json_t *obj)
|
||||||
{
|
{
|
||||||
@ -935,12 +941,14 @@ spend_coin (struct Coin *coin,
|
|||||||
* @param cls closure with our `struct Coin`
|
* @param cls closure with our `struct Coin`
|
||||||
* @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful status request
|
* @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful status request
|
||||||
* 0 if the exchange's reply is bogus (fails to follow the protocol)
|
* 0 if the exchange's reply is bogus (fails to follow the protocol)
|
||||||
|
* @param ec taler-specific error code, #TALER_EC_NONE on success
|
||||||
* @param sig signature over the coin, NULL on error
|
* @param sig signature over the coin, NULL on error
|
||||||
* @param full_response full response from the exchange (for logging, in case of errors)
|
* @param full_response full response from the exchange (for logging, in case of errors)
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
reserve_withdraw_cb (void *cls,
|
reserve_withdraw_cb (void *cls,
|
||||||
unsigned int http_status,
|
unsigned int http_status,
|
||||||
|
enum TALER_ErrorCode ec,
|
||||||
const struct TALER_DenominationSignature *sig,
|
const struct TALER_DenominationSignature *sig,
|
||||||
const json_t *full_response)
|
const json_t *full_response)
|
||||||
{
|
{
|
||||||
@ -1027,11 +1035,13 @@ withdraw_coin (struct Coin *coin)
|
|||||||
* @param cls closure with the `struct Reserve *`
|
* @param cls closure with the `struct Reserve *`
|
||||||
* @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful status request
|
* @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful status request
|
||||||
* 0 if the exchange's reply is bogus (fails to follow the protocol)
|
* 0 if the exchange's reply is bogus (fails to follow the protocol)
|
||||||
|
* @param ec taler-specific error code, #TALER_EC_NONE on success
|
||||||
* @param full_response full response from the exchange (for logging, in case of errors)
|
* @param full_response full response from the exchange (for logging, in case of errors)
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
add_incoming_cb (void *cls,
|
add_incoming_cb (void *cls,
|
||||||
unsigned int http_status,
|
unsigned int http_status,
|
||||||
|
enum TALER_ErrorCode ec,
|
||||||
const json_t *full_response)
|
const json_t *full_response)
|
||||||
{
|
{
|
||||||
struct Reserve *r = cls;
|
struct Reserve *r = cls;
|
||||||
|
@ -14,7 +14,7 @@ libtalerexchange_la_LDFLAGS = \
|
|||||||
-no-undefined
|
-no-undefined
|
||||||
|
|
||||||
libtalerexchange_la_SOURCES = \
|
libtalerexchange_la_SOURCES = \
|
||||||
exchange_api_common.c exchange_api_common.h \
|
exchange_api_common.c \
|
||||||
exchange_api_handle.c exchange_api_handle.h \
|
exchange_api_handle.c exchange_api_handle.h \
|
||||||
exchange_api_admin.c \
|
exchange_api_admin.c \
|
||||||
exchange_api_deposit.c \
|
exchange_api_deposit.c \
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
This file is part of TALER
|
This file is part of TALER
|
||||||
Copyright (C) 2014, 2015 GNUnet e.V.
|
Copyright (C) 2014, 2015, 2016 GNUnet e.V.
|
||||||
|
|
||||||
TALER is free software; you can redistribute it and/or modify it under the
|
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
|
terms of the GNU General Public License as published by the Free Software
|
||||||
@ -129,6 +129,7 @@ handle_admin_add_incoming_finished (void *cls,
|
|||||||
}
|
}
|
||||||
aai->cb (aai->cb_cls,
|
aai->cb (aai->cb_cls,
|
||||||
response_code,
|
response_code,
|
||||||
|
TALER_JSON_get_error_code (json),
|
||||||
json);
|
json);
|
||||||
TALER_EXCHANGE_admin_add_incoming_cancel (aai);
|
TALER_EXCHANGE_admin_add_incoming_cancel (aai);
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,6 @@
|
|||||||
* @author Christian Grothoff
|
* @author Christian Grothoff
|
||||||
*/
|
*/
|
||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
#include "exchange_api_common.h"
|
|
||||||
#include "taler_json_lib.h"
|
#include "taler_json_lib.h"
|
||||||
#include <gnunet/gnunet_curl_lib.h>
|
#include <gnunet/gnunet_curl_lib.h>
|
||||||
#include "exchange_api_handle.h"
|
#include "exchange_api_handle.h"
|
||||||
@ -38,8 +37,8 @@
|
|||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
TALER_EXCHANGE_verify_coin_history (const char *currency,
|
TALER_EXCHANGE_verify_coin_history (const char *currency,
|
||||||
const struct TALER_CoinSpendPublicKeyP *coin_pub,
|
const struct TALER_CoinSpendPublicKeyP *coin_pub,
|
||||||
json_t *history,
|
json_t *history,
|
||||||
struct TALER_Amount *total)
|
struct TALER_Amount *total)
|
||||||
{
|
{
|
||||||
size_t len;
|
size_t len;
|
||||||
|
@ -1,41 +0,0 @@
|
|||||||
/*
|
|
||||||
This file is part of TALER
|
|
||||||
Copyright (C) 2015 GNUnet e.V.
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License along with
|
|
||||||
TALER; see the file COPYING. If not, see
|
|
||||||
<http://www.gnu.org/licenses/>
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* @file exchange-lib/exchange_api_common.h
|
|
||||||
* @brief common functions for the exchange API
|
|
||||||
* @author Christian Grothoff
|
|
||||||
*/
|
|
||||||
#include <jansson.h>
|
|
||||||
#include <gnunet/gnunet_util_lib.h>
|
|
||||||
#include "taler_exchange_service.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Verify a coins transaction history as returned by the exchange.
|
|
||||||
*
|
|
||||||
* @param currency expected currency for the coin
|
|
||||||
* @param coin_pub public key of the coin
|
|
||||||
* @param history history of the coin in json encoding
|
|
||||||
* @param[out] total how much of the coin has been spent according to @a history
|
|
||||||
* @return #GNUNET_OK if @a history is valid, #GNUNET_SYSERR if not
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
TALER_EXCHANGE_verify_coin_history (const char *currency,
|
|
||||||
const struct TALER_CoinSpendPublicKeyP *coin_pub,
|
|
||||||
json_t *history,
|
|
||||||
struct TALER_Amount *total);
|
|
||||||
|
|
||||||
/* end of exchange_api_common.h */
|
|
@ -29,7 +29,6 @@
|
|||||||
#include <gnunet/gnunet_curl_lib.h>
|
#include <gnunet/gnunet_curl_lib.h>
|
||||||
#include "taler_json_lib.h"
|
#include "taler_json_lib.h"
|
||||||
#include "taler_exchange_service.h"
|
#include "taler_exchange_service.h"
|
||||||
#include "exchange_api_common.h"
|
|
||||||
#include "exchange_api_handle.h"
|
#include "exchange_api_handle.h"
|
||||||
#include "taler_signatures.h"
|
#include "taler_signatures.h"
|
||||||
|
|
||||||
@ -262,6 +261,7 @@ handle_deposit_finished (void *cls,
|
|||||||
}
|
}
|
||||||
dh->cb (dh->cb_cls,
|
dh->cb (dh->cb_cls,
|
||||||
response_code,
|
response_code,
|
||||||
|
TALER_JSON_get_error_code (json),
|
||||||
ep,
|
ep,
|
||||||
json);
|
json);
|
||||||
TALER_EXCHANGE_deposit_cancel (dh);
|
TALER_EXCHANGE_deposit_cancel (dh);
|
||||||
|
@ -28,7 +28,6 @@
|
|||||||
#include <gnunet/gnunet_curl_lib.h>
|
#include <gnunet/gnunet_curl_lib.h>
|
||||||
#include "taler_json_lib.h"
|
#include "taler_json_lib.h"
|
||||||
#include "taler_exchange_service.h"
|
#include "taler_exchange_service.h"
|
||||||
#include "exchange_api_common.h"
|
|
||||||
#include "exchange_api_handle.h"
|
#include "exchange_api_handle.h"
|
||||||
#include "taler_signatures.h"
|
#include "taler_signatures.h"
|
||||||
|
|
||||||
@ -1115,6 +1114,7 @@ handle_refresh_melt_finished (void *cls,
|
|||||||
{
|
{
|
||||||
rmh->melt_cb (rmh->melt_cb_cls,
|
rmh->melt_cb (rmh->melt_cb_cls,
|
||||||
response_code,
|
response_code,
|
||||||
|
TALER_JSON_get_error_code (json),
|
||||||
noreveal_index,
|
noreveal_index,
|
||||||
(0 == response_code) ? NULL : &exchange_pub,
|
(0 == response_code) ? NULL : &exchange_pub,
|
||||||
json);
|
json);
|
||||||
@ -1160,6 +1160,7 @@ handle_refresh_melt_finished (void *cls,
|
|||||||
if (NULL != rmh->melt_cb)
|
if (NULL != rmh->melt_cb)
|
||||||
rmh->melt_cb (rmh->melt_cb_cls,
|
rmh->melt_cb (rmh->melt_cb_cls,
|
||||||
response_code,
|
response_code,
|
||||||
|
TALER_JSON_get_error_code (json),
|
||||||
UINT16_MAX,
|
UINT16_MAX,
|
||||||
NULL,
|
NULL,
|
||||||
json);
|
json);
|
||||||
@ -1598,6 +1599,7 @@ handle_refresh_reveal_finished (void *cls,
|
|||||||
{
|
{
|
||||||
rrh->reveal_cb (rrh->reveal_cb_cls,
|
rrh->reveal_cb (rrh->reveal_cb_cls,
|
||||||
MHD_HTTP_OK,
|
MHD_HTTP_OK,
|
||||||
|
TALER_EC_NONE,
|
||||||
rrh->md->num_fresh_coins,
|
rrh->md->num_fresh_coins,
|
||||||
coin_privs,
|
coin_privs,
|
||||||
sigs,
|
sigs,
|
||||||
@ -1634,7 +1636,10 @@ handle_refresh_reveal_finished (void *cls,
|
|||||||
if (NULL != rrh->reveal_cb)
|
if (NULL != rrh->reveal_cb)
|
||||||
rrh->reveal_cb (rrh->reveal_cb_cls,
|
rrh->reveal_cb (rrh->reveal_cb_cls,
|
||||||
response_code,
|
response_code,
|
||||||
0, NULL, NULL,
|
TALER_JSON_get_error_code (json),
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
json);
|
json);
|
||||||
TALER_EXCHANGE_refresh_reveal_cancel (rrh);
|
TALER_EXCHANGE_refresh_reveal_cancel (rrh);
|
||||||
}
|
}
|
||||||
|
@ -265,6 +265,7 @@ parse_refresh_link_ok (struct TALER_EXCHANGE_RefreshLinkHandle *rlh,
|
|||||||
{
|
{
|
||||||
rlh->link_cb (rlh->link_cb_cls,
|
rlh->link_cb (rlh->link_cb_cls,
|
||||||
MHD_HTTP_OK,
|
MHD_HTTP_OK,
|
||||||
|
TALER_EC_NONE,
|
||||||
num_coins,
|
num_coins,
|
||||||
coin_privs,
|
coin_privs,
|
||||||
sigs,
|
sigs,
|
||||||
@ -345,7 +346,11 @@ handle_refresh_link_finished (void *cls,
|
|||||||
if (NULL != rlh->link_cb)
|
if (NULL != rlh->link_cb)
|
||||||
rlh->link_cb (rlh->link_cb_cls,
|
rlh->link_cb (rlh->link_cb_cls,
|
||||||
response_code,
|
response_code,
|
||||||
0, NULL, NULL, NULL,
|
TALER_JSON_get_error_code (json),
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
json);
|
json);
|
||||||
TALER_EXCHANGE_refresh_link_cancel (rlh);
|
TALER_EXCHANGE_refresh_link_cancel (rlh);
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,6 @@
|
|||||||
#include <gnunet/gnunet_curl_lib.h>
|
#include <gnunet/gnunet_curl_lib.h>
|
||||||
#include "taler_json_lib.h"
|
#include "taler_json_lib.h"
|
||||||
#include "taler_exchange_service.h"
|
#include "taler_exchange_service.h"
|
||||||
#include "exchange_api_common.h"
|
|
||||||
#include "exchange_api_handle.h"
|
#include "exchange_api_handle.h"
|
||||||
#include "taler_signatures.h"
|
#include "taler_signatures.h"
|
||||||
|
|
||||||
@ -196,6 +195,7 @@ handle_refund_finished (void *cls,
|
|||||||
}
|
}
|
||||||
rh->cb (rh->cb_cls,
|
rh->cb (rh->cb_cls,
|
||||||
response_code,
|
response_code,
|
||||||
|
TALER_JSON_get_error_code (json),
|
||||||
ep,
|
ep,
|
||||||
json);
|
json);
|
||||||
TALER_EXCHANGE_refund_cancel (rh);
|
TALER_EXCHANGE_refund_cancel (rh);
|
||||||
|
@ -314,7 +314,8 @@ handle_reserve_status_finished (void *cls,
|
|||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
GNUNET_JSON_parse (json,
|
GNUNET_JSON_parse (json,
|
||||||
spec,
|
spec,
|
||||||
NULL, NULL))
|
NULL,
|
||||||
|
NULL))
|
||||||
{
|
{
|
||||||
GNUNET_break_op (0);
|
GNUNET_break_op (0);
|
||||||
response_code = 0;
|
response_code = 0;
|
||||||
@ -355,6 +356,7 @@ handle_reserve_status_finished (void *cls,
|
|||||||
}
|
}
|
||||||
wsh->cb (wsh->cb_cls,
|
wsh->cb (wsh->cb_cls,
|
||||||
response_code,
|
response_code,
|
||||||
|
TALER_EC_NONE,
|
||||||
json,
|
json,
|
||||||
&balance,
|
&balance,
|
||||||
len,
|
len,
|
||||||
@ -387,6 +389,7 @@ handle_reserve_status_finished (void *cls,
|
|||||||
if (NULL != wsh->cb)
|
if (NULL != wsh->cb)
|
||||||
wsh->cb (wsh->cb_cls,
|
wsh->cb (wsh->cb_cls,
|
||||||
response_code,
|
response_code,
|
||||||
|
TALER_JSON_get_error_code (json),
|
||||||
json,
|
json,
|
||||||
NULL,
|
NULL,
|
||||||
0, NULL);
|
0, NULL);
|
||||||
@ -589,6 +592,7 @@ reserve_withdraw_ok (struct TALER_EXCHANGE_ReserveWithdrawHandle *wsh,
|
|||||||
dsig.rsa_signature = sig;
|
dsig.rsa_signature = sig;
|
||||||
wsh->cb (wsh->cb_cls,
|
wsh->cb (wsh->cb_cls,
|
||||||
MHD_HTTP_OK,
|
MHD_HTTP_OK,
|
||||||
|
TALER_EC_NONE,
|
||||||
&dsig,
|
&dsig,
|
||||||
json);
|
json);
|
||||||
/* make sure callback isn't called again after return */
|
/* make sure callback isn't called again after return */
|
||||||
@ -599,7 +603,7 @@ reserve_withdraw_ok (struct TALER_EXCHANGE_ReserveWithdrawHandle *wsh,
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* We got a 402 PAYMENT REQUIRED response for the /reserve/withdraw operation.
|
* We got a 403 FORBIDDEN response for the /reserve/withdraw operation.
|
||||||
* Check the signatures on the withdraw transactions in the provided
|
* Check the signatures on the withdraw transactions in the provided
|
||||||
* history and that the balances add up. We don't do anything directly
|
* history and that the balances add up. We don't do anything directly
|
||||||
* with the information, as the JSON will be returned to the application.
|
* with the information, as the JSON will be returned to the application.
|
||||||
@ -723,7 +727,7 @@ handle_reserve_withdraw_finished (void *cls,
|
|||||||
/* This should never happen, either us or the exchange is buggy
|
/* This should never happen, either us or the exchange is buggy
|
||||||
(or API version conflict); just pass JSON reply to the application */
|
(or API version conflict); just pass JSON reply to the application */
|
||||||
break;
|
break;
|
||||||
case MHD_HTTP_PAYMENT_REQUIRED:
|
case MHD_HTTP_FORBIDDEN:
|
||||||
/* The exchange says that the reserve has insufficient funds;
|
/* The exchange says that the reserve has insufficient funds;
|
||||||
check the signatures in the history... */
|
check the signatures in the history... */
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
@ -762,6 +766,7 @@ handle_reserve_withdraw_finished (void *cls,
|
|||||||
if (NULL != wsh->cb)
|
if (NULL != wsh->cb)
|
||||||
wsh->cb (wsh->cb_cls,
|
wsh->cb (wsh->cb_cls,
|
||||||
response_code,
|
response_code,
|
||||||
|
TALER_JSON_get_error_code (json),
|
||||||
NULL,
|
NULL,
|
||||||
json);
|
json);
|
||||||
TALER_EXCHANGE_reserve_withdraw_cancel (wsh);
|
TALER_EXCHANGE_reserve_withdraw_cancel (wsh);
|
||||||
|
@ -28,7 +28,6 @@
|
|||||||
#include <gnunet/gnunet_curl_lib.h>
|
#include <gnunet/gnunet_curl_lib.h>
|
||||||
#include "taler_json_lib.h"
|
#include "taler_json_lib.h"
|
||||||
#include "taler_exchange_service.h"
|
#include "taler_exchange_service.h"
|
||||||
#include "exchange_api_common.h"
|
|
||||||
#include "exchange_api_handle.h"
|
#include "exchange_api_handle.h"
|
||||||
#include "taler_signatures.h"
|
#include "taler_signatures.h"
|
||||||
|
|
||||||
@ -239,6 +238,7 @@ handle_deposit_wtid_finished (void *cls,
|
|||||||
}
|
}
|
||||||
dwh->cb (dwh->cb_cls,
|
dwh->cb (dwh->cb_cls,
|
||||||
response_code,
|
response_code,
|
||||||
|
TALER_JSON_get_error_code (json),
|
||||||
ep,
|
ep,
|
||||||
json,
|
json,
|
||||||
wtid,
|
wtid,
|
||||||
|
@ -26,7 +26,6 @@
|
|||||||
#include <gnunet/gnunet_util_lib.h>
|
#include <gnunet/gnunet_util_lib.h>
|
||||||
#include <gnunet/gnunet_curl_lib.h>
|
#include <gnunet/gnunet_curl_lib.h>
|
||||||
#include "taler_exchange_service.h"
|
#include "taler_exchange_service.h"
|
||||||
#include "exchange_api_common.h"
|
|
||||||
#include "taler_json_lib.h"
|
#include "taler_json_lib.h"
|
||||||
#include "exchange_api_handle.h"
|
#include "exchange_api_handle.h"
|
||||||
#include "taler_signatures.h"
|
#include "taler_signatures.h"
|
||||||
@ -183,6 +182,7 @@ check_track_transfer_response_ok (struct TALER_EXCHANGE_TrackTransferHandle *wdh
|
|||||||
}
|
}
|
||||||
wdh->cb (wdh->cb_cls,
|
wdh->cb (wdh->cb_cls,
|
||||||
MHD_HTTP_OK,
|
MHD_HTTP_OK,
|
||||||
|
TALER_EC_NONE,
|
||||||
&exchange_pub,
|
&exchange_pub,
|
||||||
json,
|
json,
|
||||||
&h_wire,
|
&h_wire,
|
||||||
@ -253,6 +253,7 @@ handle_track_transfer_finished (void *cls,
|
|||||||
}
|
}
|
||||||
wdh->cb (wdh->cb_cls,
|
wdh->cb (wdh->cb_cls,
|
||||||
response_code,
|
response_code,
|
||||||
|
TALER_JSON_get_error_code (json),
|
||||||
NULL,
|
NULL,
|
||||||
json,
|
json,
|
||||||
NULL,
|
NULL,
|
||||||
|
@ -28,7 +28,6 @@
|
|||||||
#include "taler_exchange_service.h"
|
#include "taler_exchange_service.h"
|
||||||
#include "taler_json_lib.h"
|
#include "taler_json_lib.h"
|
||||||
#include "taler_wire_plugin.h"
|
#include "taler_wire_plugin.h"
|
||||||
#include "exchange_api_common.h"
|
|
||||||
#include "exchange_api_handle.h"
|
#include "exchange_api_handle.h"
|
||||||
|
|
||||||
|
|
||||||
@ -210,6 +209,7 @@ handle_wire_finished (void *cls,
|
|||||||
}
|
}
|
||||||
wh->cb (wh->cb_cls,
|
wh->cb (wh->cb_cls,
|
||||||
response_code,
|
response_code,
|
||||||
|
TALER_JSON_get_error_code (json),
|
||||||
(NULL != keep) ? keep : json);
|
(NULL != keep) ? keep : json);
|
||||||
if (NULL != keep)
|
if (NULL != keep)
|
||||||
json_decref (keep);
|
json_decref (keep);
|
||||||
|
@ -761,11 +761,13 @@ next_command (struct InterpreterState *is)
|
|||||||
* @param cls closure with the interpreter state
|
* @param cls closure with the interpreter state
|
||||||
* @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful status request
|
* @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful status request
|
||||||
* 0 if the exchange's reply is bogus (fails to follow the protocol)
|
* 0 if the exchange's reply is bogus (fails to follow the protocol)
|
||||||
|
* @param ec taler-specific error code, #TALER_EC_NONE on success
|
||||||
* @param full_response full response from the exchange (for logging, in case of errors)
|
* @param full_response full response from the exchange (for logging, in case of errors)
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
add_incoming_cb (void *cls,
|
add_incoming_cb (void *cls,
|
||||||
unsigned int http_status,
|
unsigned int http_status,
|
||||||
|
enum TALER_ErrorCode ec,
|
||||||
const json_t *full_response)
|
const json_t *full_response)
|
||||||
{
|
{
|
||||||
struct InterpreterState *is = cls;
|
struct InterpreterState *is = cls;
|
||||||
@ -857,6 +859,7 @@ compare_reserve_withdraw_history (const struct TALER_EXCHANGE_ReserveHistory *h,
|
|||||||
* @param cls closure with the interpreter state
|
* @param cls closure with the interpreter state
|
||||||
* @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful status request
|
* @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful status request
|
||||||
* 0 if the exchange's reply is bogus (fails to follow the protocol)
|
* 0 if the exchange's reply is bogus (fails to follow the protocol)
|
||||||
|
* @param ec taler-specific error code, #TALER_EC_NONE on success
|
||||||
* @param[in] json original response in JSON format (useful only for diagnostics)
|
* @param[in] json original response in JSON format (useful only for diagnostics)
|
||||||
* @param balance current balance in the reserve, NULL on error
|
* @param balance current balance in the reserve, NULL on error
|
||||||
* @param history_length number of entries in the transaction history, 0 on error
|
* @param history_length number of entries in the transaction history, 0 on error
|
||||||
@ -865,6 +868,7 @@ compare_reserve_withdraw_history (const struct TALER_EXCHANGE_ReserveHistory *h,
|
|||||||
static void
|
static void
|
||||||
reserve_status_cb (void *cls,
|
reserve_status_cb (void *cls,
|
||||||
unsigned int http_status,
|
unsigned int http_status,
|
||||||
|
enum TALER_ErrorCode ec,
|
||||||
const json_t *json,
|
const json_t *json,
|
||||||
const struct TALER_Amount *balance,
|
const struct TALER_Amount *balance,
|
||||||
unsigned int history_length,
|
unsigned int history_length,
|
||||||
@ -924,7 +928,7 @@ reserve_status_cb (void *cls,
|
|||||||
{
|
{
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
compare_reserve_withdraw_history (&history[j],
|
compare_reserve_withdraw_history (&history[j],
|
||||||
rel))
|
rel))
|
||||||
{
|
{
|
||||||
GNUNET_break (0);
|
GNUNET_break (0);
|
||||||
fail (is);
|
fail (is);
|
||||||
@ -973,12 +977,14 @@ reserve_status_cb (void *cls,
|
|||||||
* @param cls closure with the interpreter state
|
* @param cls closure with the interpreter state
|
||||||
* @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful status request
|
* @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful status request
|
||||||
* 0 if the exchange's reply is bogus (fails to follow the protocol)
|
* 0 if the exchange's reply is bogus (fails to follow the protocol)
|
||||||
|
* @param ec taler-specific error code, #TALER_EC_NONE on success
|
||||||
* @param sig signature over the coin, NULL on error
|
* @param sig signature over the coin, NULL on error
|
||||||
* @param full_response full response from the exchange (for logging, in case of errors)
|
* @param full_response full response from the exchange (for logging, in case of errors)
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
reserve_withdraw_cb (void *cls,
|
reserve_withdraw_cb (void *cls,
|
||||||
unsigned int http_status,
|
unsigned int http_status,
|
||||||
|
enum TALER_ErrorCode ec,
|
||||||
const struct TALER_DenominationSignature *sig,
|
const struct TALER_DenominationSignature *sig,
|
||||||
const json_t *full_response)
|
const json_t *full_response)
|
||||||
{
|
{
|
||||||
@ -1009,7 +1015,7 @@ reserve_withdraw_cb (void *cls,
|
|||||||
cmd->details.reserve_withdraw.sig.rsa_signature
|
cmd->details.reserve_withdraw.sig.rsa_signature
|
||||||
= GNUNET_CRYPTO_rsa_signature_dup (sig->rsa_signature);
|
= GNUNET_CRYPTO_rsa_signature_dup (sig->rsa_signature);
|
||||||
break;
|
break;
|
||||||
case MHD_HTTP_PAYMENT_REQUIRED:
|
case MHD_HTTP_FORBIDDEN:
|
||||||
/* nothing to check */
|
/* nothing to check */
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -1027,6 +1033,7 @@ reserve_withdraw_cb (void *cls,
|
|||||||
* @param cls closure with the interpreter state
|
* @param cls closure with the interpreter state
|
||||||
* @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful deposit;
|
* @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful deposit;
|
||||||
* 0 if the exchange's reply is bogus (fails to follow the protocol)
|
* 0 if the exchange's reply is bogus (fails to follow the protocol)
|
||||||
|
* @param ec taler-specific error code, #TALER_EC_NONE on success
|
||||||
* @param exchange_pub public key the exchange used for signing
|
* @param exchange_pub public key the exchange used for signing
|
||||||
* @param obj the received JSON reply, should be kept as proof (and, in case of errors,
|
* @param obj the received JSON reply, should be kept as proof (and, in case of errors,
|
||||||
* be forwarded to the customer)
|
* be forwarded to the customer)
|
||||||
@ -1034,6 +1041,7 @@ reserve_withdraw_cb (void *cls,
|
|||||||
static void
|
static void
|
||||||
deposit_cb (void *cls,
|
deposit_cb (void *cls,
|
||||||
unsigned int http_status,
|
unsigned int http_status,
|
||||||
|
enum TALER_ErrorCode ec,
|
||||||
const struct TALER_ExchangePublicKeyP *exchange_pub,
|
const struct TALER_ExchangePublicKeyP *exchange_pub,
|
||||||
const json_t *obj)
|
const json_t *obj)
|
||||||
{
|
{
|
||||||
@ -1061,6 +1069,7 @@ deposit_cb (void *cls,
|
|||||||
* @param cls closure with the interpreter state
|
* @param cls closure with the interpreter state
|
||||||
* @param http_status HTTP response code, never #MHD_HTTP_OK (200) as for successful intermediate response this callback is skipped.
|
* @param http_status HTTP response code, never #MHD_HTTP_OK (200) as for successful intermediate response this callback is skipped.
|
||||||
* 0 if the exchange's reply is bogus (fails to follow the protocol)
|
* 0 if the exchange's reply is bogus (fails to follow the protocol)
|
||||||
|
* @param ec taler-specific error code, #TALER_EC_NONE on success
|
||||||
* @param noreveal_index choice by the exchange in the cut-and-choose protocol,
|
* @param noreveal_index choice by the exchange in the cut-and-choose protocol,
|
||||||
* UINT16_MAX on error
|
* UINT16_MAX on error
|
||||||
* @param exchange_pub public key the exchange used for signing
|
* @param exchange_pub public key the exchange used for signing
|
||||||
@ -1069,6 +1078,7 @@ deposit_cb (void *cls,
|
|||||||
static void
|
static void
|
||||||
melt_cb (void *cls,
|
melt_cb (void *cls,
|
||||||
unsigned int http_status,
|
unsigned int http_status,
|
||||||
|
enum TALER_ErrorCode ec,
|
||||||
uint16_t noreveal_index,
|
uint16_t noreveal_index,
|
||||||
const struct TALER_ExchangePublicKeyP *exchange_pub,
|
const struct TALER_ExchangePublicKeyP *exchange_pub,
|
||||||
const json_t *full_response)
|
const json_t *full_response)
|
||||||
@ -1098,6 +1108,7 @@ melt_cb (void *cls,
|
|||||||
* @param cls closure with the interpreter state
|
* @param cls closure with the interpreter state
|
||||||
* @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful status request
|
* @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful status request
|
||||||
* 0 if the exchange's reply is bogus (fails to follow the protocol)
|
* 0 if the exchange's reply is bogus (fails to follow the protocol)
|
||||||
|
* @param ec taler-specific error code, #TALER_EC_NONE on success
|
||||||
* @param num_coins number of fresh coins created, length of the @a sigs and @a coin_privs arrays, 0 if the operation failed
|
* @param num_coins number of fresh coins created, length of the @a sigs and @a coin_privs arrays, 0 if the operation failed
|
||||||
* @param coin_privs array of @a num_coins private keys for the coins that were created, NULL on error
|
* @param coin_privs array of @a num_coins private keys for the coins that were created, NULL on error
|
||||||
* @param sigs array of signature over @a num_coins coins, NULL on error
|
* @param sigs array of signature over @a num_coins coins, NULL on error
|
||||||
@ -1106,6 +1117,7 @@ melt_cb (void *cls,
|
|||||||
static void
|
static void
|
||||||
reveal_cb (void *cls,
|
reveal_cb (void *cls,
|
||||||
unsigned int http_status,
|
unsigned int http_status,
|
||||||
|
enum TALER_ErrorCode ec,
|
||||||
unsigned int num_coins,
|
unsigned int num_coins,
|
||||||
const struct TALER_CoinSpendPrivateKeyP *coin_privs,
|
const struct TALER_CoinSpendPrivateKeyP *coin_privs,
|
||||||
const struct TALER_DenominationSignature *sigs,
|
const struct TALER_DenominationSignature *sigs,
|
||||||
@ -1160,6 +1172,7 @@ reveal_cb (void *cls,
|
|||||||
* @param cls closure with the interpreter state
|
* @param cls closure with the interpreter state
|
||||||
* @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful status request
|
* @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful status request
|
||||||
* 0 if the exchange's reply is bogus (fails to follow the protocol)
|
* 0 if the exchange's reply is bogus (fails to follow the protocol)
|
||||||
|
* @param ec taler-specific error code, #TALER_EC_NONE on success
|
||||||
* @param num_coins number of fresh coins created, length of the @a sigs and @a coin_privs arrays, 0 if the operation failed
|
* @param num_coins number of fresh coins created, length of the @a sigs and @a coin_privs arrays, 0 if the operation failed
|
||||||
* @param coin_privs array of @a num_coins private keys for the coins that were created, NULL on error
|
* @param coin_privs array of @a num_coins private keys for the coins that were created, NULL on error
|
||||||
* @param sigs array of signature over @a num_coins coins, NULL on error
|
* @param sigs array of signature over @a num_coins coins, NULL on error
|
||||||
@ -1169,6 +1182,7 @@ reveal_cb (void *cls,
|
|||||||
static void
|
static void
|
||||||
link_cb (void *cls,
|
link_cb (void *cls,
|
||||||
unsigned int http_status,
|
unsigned int http_status,
|
||||||
|
enum TALER_ErrorCode ec,
|
||||||
unsigned int num_coins,
|
unsigned int num_coins,
|
||||||
const struct TALER_CoinSpendPrivateKeyP *coin_privs,
|
const struct TALER_CoinSpendPrivateKeyP *coin_privs,
|
||||||
const struct TALER_DenominationSignature *sigs,
|
const struct TALER_DenominationSignature *sigs,
|
||||||
@ -1336,12 +1350,14 @@ find_pk (const struct TALER_EXCHANGE_Keys *keys,
|
|||||||
* @param cls closure with the interpreter state
|
* @param cls closure with the interpreter state
|
||||||
* @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful request;
|
* @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful request;
|
||||||
* 0 if the exchange's reply is bogus (fails to follow the protocol)
|
* 0 if the exchange's reply is bogus (fails to follow the protocol)
|
||||||
|
* @param ec taler-specific error code, #TALER_EC_NONE on success
|
||||||
* @param obj the received JSON reply, if successful this should be the wire
|
* @param obj the received JSON reply, if successful this should be the wire
|
||||||
* format details as provided by /wire.
|
* format details as provided by /wire.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
wire_cb (void *cls,
|
wire_cb (void *cls,
|
||||||
unsigned int http_status,
|
unsigned int http_status,
|
||||||
|
enum TALER_ErrorCode ec,
|
||||||
const json_t *obj)
|
const json_t *obj)
|
||||||
{
|
{
|
||||||
struct InterpreterState *is = cls;
|
struct InterpreterState *is = cls;
|
||||||
@ -1391,6 +1407,7 @@ wire_cb (void *cls,
|
|||||||
*
|
*
|
||||||
* @param cls closure
|
* @param cls closure
|
||||||
* @param http_status HTTP status code we got, 0 on exchange protocol violation
|
* @param http_status HTTP status code we got, 0 on exchange protocol violation
|
||||||
|
* @param ec taler-specific error code, #TALER_EC_NONE on success
|
||||||
* @param exchange_pub public key the exchange used for signing
|
* @param exchange_pub public key the exchange used for signing
|
||||||
* @param json original json reply (may include signatures, those have then been
|
* @param json original json reply (may include signatures, those have then been
|
||||||
* validated already)
|
* validated already)
|
||||||
@ -1404,6 +1421,7 @@ wire_cb (void *cls,
|
|||||||
static void
|
static void
|
||||||
wire_deposits_cb (void *cls,
|
wire_deposits_cb (void *cls,
|
||||||
unsigned int http_status,
|
unsigned int http_status,
|
||||||
|
enum TALER_ErrorCode ec,
|
||||||
const struct TALER_ExchangePublicKeyP *exchange_pub,
|
const struct TALER_ExchangePublicKeyP *exchange_pub,
|
||||||
const json_t *json,
|
const json_t *json,
|
||||||
const struct GNUNET_HashCode *h_wire,
|
const struct GNUNET_HashCode *h_wire,
|
||||||
@ -1521,6 +1539,7 @@ wire_deposits_cb (void *cls,
|
|||||||
*
|
*
|
||||||
* @param cls closure
|
* @param cls closure
|
||||||
* @param http_status HTTP status code we got, 0 on exchange protocol violation
|
* @param http_status HTTP status code we got, 0 on exchange protocol violation
|
||||||
|
* @param ec taler-specific error code, #TALER_EC_NONE on success
|
||||||
* @param exchange_pub public key the exchange used for signing
|
* @param exchange_pub public key the exchange used for signing
|
||||||
* @param json original json reply (may include signatures, those have then been
|
* @param json original json reply (may include signatures, those have then been
|
||||||
* validated already)
|
* validated already)
|
||||||
@ -1534,6 +1553,7 @@ wire_deposits_cb (void *cls,
|
|||||||
static void
|
static void
|
||||||
deposit_wtid_cb (void *cls,
|
deposit_wtid_cb (void *cls,
|
||||||
unsigned int http_status,
|
unsigned int http_status,
|
||||||
|
enum TALER_ErrorCode ec,
|
||||||
const struct TALER_ExchangePublicKeyP *exchange_pub,
|
const struct TALER_ExchangePublicKeyP *exchange_pub,
|
||||||
const json_t *json,
|
const json_t *json,
|
||||||
const struct TALER_WireTransferIdentifierRawP *wtid,
|
const struct TALER_WireTransferIdentifierRawP *wtid,
|
||||||
@ -1588,6 +1608,7 @@ deposit_wtid_cb (void *cls,
|
|||||||
* @param cls closure
|
* @param cls closure
|
||||||
* @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful deposit;
|
* @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful deposit;
|
||||||
* 0 if the exchange's reply is bogus (fails to follow the protocol)
|
* 0 if the exchange's reply is bogus (fails to follow the protocol)
|
||||||
|
* @param ec taler-specific error code, #TALER_EC_NONE on success
|
||||||
* @param exchange_pub public key the exchange used for signing @a obj
|
* @param exchange_pub public key the exchange used for signing @a obj
|
||||||
* @param obj the received JSON reply, should be kept as proof (and, in particular,
|
* @param obj the received JSON reply, should be kept as proof (and, in particular,
|
||||||
* be forwarded to the customer)
|
* be forwarded to the customer)
|
||||||
@ -1595,6 +1616,7 @@ deposit_wtid_cb (void *cls,
|
|||||||
static void
|
static void
|
||||||
refund_cb (void *cls,
|
refund_cb (void *cls,
|
||||||
unsigned int http_status,
|
unsigned int http_status,
|
||||||
|
enum TALER_ErrorCode ec,
|
||||||
const struct TALER_ExchangePublicKeyP *exchange_pub,
|
const struct TALER_ExchangePublicKeyP *exchange_pub,
|
||||||
const json_t *obj)
|
const json_t *obj)
|
||||||
{
|
{
|
||||||
@ -1782,9 +1804,9 @@ interpreter_run (void *cls)
|
|||||||
&reserve_pub.eddsa_pub);
|
&reserve_pub.eddsa_pub);
|
||||||
cmd->details.reserve_status.wsh
|
cmd->details.reserve_status.wsh
|
||||||
= TALER_EXCHANGE_reserve_status (exchange,
|
= TALER_EXCHANGE_reserve_status (exchange,
|
||||||
&reserve_pub,
|
&reserve_pub,
|
||||||
&reserve_status_cb,
|
&reserve_status_cb,
|
||||||
is);
|
is);
|
||||||
return;
|
return;
|
||||||
case OC_WITHDRAW_SIGN:
|
case OC_WITHDRAW_SIGN:
|
||||||
GNUNET_assert (NULL !=
|
GNUNET_assert (NULL !=
|
||||||
@ -2737,7 +2759,7 @@ run (void *cls)
|
|||||||
/* Try to overdraw funds ... */
|
/* Try to overdraw funds ... */
|
||||||
{ .oc = OC_WITHDRAW_SIGN,
|
{ .oc = OC_WITHDRAW_SIGN,
|
||||||
.label = "withdraw-coin-2",
|
.label = "withdraw-coin-2",
|
||||||
.expected_response_code = MHD_HTTP_PAYMENT_REQUIRED,
|
.expected_response_code = MHD_HTTP_FORBIDDEN,
|
||||||
.details.reserve_withdraw.reserve_reference = "create-reserve-1",
|
.details.reserve_withdraw.reserve_reference = "create-reserve-1",
|
||||||
.details.reserve_withdraw.amount = "EUR:5" },
|
.details.reserve_withdraw.amount = "EUR:5" },
|
||||||
|
|
||||||
@ -3051,8 +3073,11 @@ main (int argc,
|
|||||||
unsigned long code;
|
unsigned long code;
|
||||||
|
|
||||||
GNUNET_log_setup ("test-exchange-api",
|
GNUNET_log_setup ("test-exchange-api",
|
||||||
"WARNING",
|
"DEBUG",
|
||||||
NULL);
|
"/tmp/logs");
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test log\n");
|
||||||
|
return 0;
|
||||||
|
|
||||||
/* These might get in the way... */
|
/* These might get in the way... */
|
||||||
unsetenv ("XDG_DATA_HOME");
|
unsetenv ("XDG_DATA_HOME");
|
||||||
unsetenv ("XDG_CONFIG_HOME");
|
unsetenv ("XDG_CONFIG_HOME");
|
||||||
|
@ -89,6 +89,7 @@ TEH_ADMIN_handler_admin_add_incoming (struct TEH_RequestHandler *rh,
|
|||||||
GNUNET_break_op (0);
|
GNUNET_break_op (0);
|
||||||
GNUNET_JSON_parse_free (spec);
|
GNUNET_JSON_parse_free (spec);
|
||||||
return TEH_RESPONSE_reply_arg_unknown (connection,
|
return TEH_RESPONSE_reply_arg_unknown (connection,
|
||||||
|
TALER_EC_ADMIN_ADD_INCOMING_WIREFORMAT_UNSUPPORTED,
|
||||||
"sender_account_details");
|
"sender_account_details");
|
||||||
}
|
}
|
||||||
if (0 != strcasecmp (amount.currency,
|
if (0 != strcasecmp (amount.currency,
|
||||||
@ -100,6 +101,7 @@ TEH_ADMIN_handler_admin_add_incoming (struct TEH_RequestHandler *rh,
|
|||||||
amount.currency);
|
amount.currency);
|
||||||
GNUNET_JSON_parse_free (spec);
|
GNUNET_JSON_parse_free (spec);
|
||||||
return TEH_RESPONSE_reply_arg_invalid (connection,
|
return TEH_RESPONSE_reply_arg_invalid (connection,
|
||||||
|
TALER_EC_ADMIN_ADD_INCOMING_CURRENCY_UNSUPPORTED,
|
||||||
"amount:currency");
|
"amount:currency");
|
||||||
}
|
}
|
||||||
res = TEH_DB_execute_admin_add_incoming (connection,
|
res = TEH_DB_execute_admin_add_incoming (connection,
|
||||||
|
@ -53,7 +53,8 @@ transaction_start_label: /* we will use goto for retries */ \
|
|||||||
session)) \
|
session)) \
|
||||||
{ \
|
{ \
|
||||||
GNUNET_break (0); \
|
GNUNET_break (0); \
|
||||||
return TEH_RESPONSE_reply_internal_db_error (connection); \
|
return TEH_RESPONSE_reply_internal_db_error (connection, \
|
||||||
|
TALER_EC_DB_START_FAILED); \
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -73,8 +74,9 @@ transaction_start_label: /* we will use goto for retries */ \
|
|||||||
if (GNUNET_SYSERR == transaction_commit_result) \
|
if (GNUNET_SYSERR == transaction_commit_result) \
|
||||||
{ \
|
{ \
|
||||||
TALER_LOG_WARNING ("Transaction commit failed in %s\n", __FUNCTION__); \
|
TALER_LOG_WARNING ("Transaction commit failed in %s\n", __FUNCTION__); \
|
||||||
return TEH_RESPONSE_reply_commit_error (connection); \
|
return TEH_RESPONSE_reply_commit_error (connection, \
|
||||||
} \
|
TALER_EC_DB_COMMIT_FAILED_HARD); \
|
||||||
|
} \
|
||||||
if (GNUNET_NO == transaction_commit_result) \
|
if (GNUNET_NO == transaction_commit_result) \
|
||||||
{ \
|
{ \
|
||||||
TALER_LOG_WARNING ("Transaction commit failed in %s\n", __FUNCTION__); \
|
TALER_LOG_WARNING ("Transaction commit failed in %s\n", __FUNCTION__); \
|
||||||
@ -83,7 +85,8 @@ transaction_start_label: /* we will use goto for retries */ \
|
|||||||
TALER_LOG_WARNING ("Transaction commit failed %u times in %s\n", \
|
TALER_LOG_WARNING ("Transaction commit failed %u times in %s\n", \
|
||||||
transaction_retries, \
|
transaction_retries, \
|
||||||
__FUNCTION__); \
|
__FUNCTION__); \
|
||||||
return TEH_RESPONSE_reply_commit_error (connection); \
|
return TEH_RESPONSE_reply_commit_error (connection, \
|
||||||
|
TALER_EC_DB_COMMIT_FAILED_ON_RETRY); \
|
||||||
} \
|
} \
|
||||||
} /* end of scope opened by BEGIN_TRANSACTION */
|
} /* end of scope opened by BEGIN_TRANSACTION */
|
||||||
|
|
||||||
@ -197,7 +200,8 @@ TEH_DB_execute_deposit (struct MHD_Connection *connection,
|
|||||||
if (NULL == (session = TEH_plugin->get_session (TEH_plugin->cls)))
|
if (NULL == (session = TEH_plugin->get_session (TEH_plugin->cls)))
|
||||||
{
|
{
|
||||||
GNUNET_break (0);
|
GNUNET_break (0);
|
||||||
return TEH_RESPONSE_reply_internal_db_error (connection);
|
return TEH_RESPONSE_reply_internal_db_error (connection,
|
||||||
|
TALER_EC_DB_SETUP_FAILED);
|
||||||
}
|
}
|
||||||
if (GNUNET_YES ==
|
if (GNUNET_YES ==
|
||||||
TEH_plugin->have_deposit (TEH_plugin->cls,
|
TEH_plugin->have_deposit (TEH_plugin->cls,
|
||||||
@ -225,8 +229,8 @@ TEH_DB_execute_deposit (struct MHD_Connection *connection,
|
|||||||
if (NULL == dki)
|
if (NULL == dki)
|
||||||
{
|
{
|
||||||
TEH_KS_release (mks);
|
TEH_KS_release (mks);
|
||||||
return TEH_RESPONSE_reply_arg_invalid (connection,
|
return TEH_RESPONSE_reply_internal_db_error (connection,
|
||||||
"denom_pub");
|
TALER_EC_DEPOSIT_DB_DENOMINATION_KEY_UNKNOWN);
|
||||||
}
|
}
|
||||||
TALER_amount_ntoh (&value,
|
TALER_amount_ntoh (&value,
|
||||||
&dki->issue.properties.value);
|
&dki->issue.properties.value);
|
||||||
@ -249,7 +253,8 @@ TEH_DB_execute_deposit (struct MHD_Connection *connection,
|
|||||||
session);
|
session);
|
||||||
TEH_plugin->free_coin_transaction_list (TEH_plugin->cls,
|
TEH_plugin->free_coin_transaction_list (TEH_plugin->cls,
|
||||||
tl);
|
tl);
|
||||||
return TEH_RESPONSE_reply_internal_db_error (connection);
|
return TEH_RESPONSE_reply_internal_db_error (connection,
|
||||||
|
TALER_EC_DEPOSIT_HISTORY_DB_ERROR);
|
||||||
}
|
}
|
||||||
/* Check that cost of all transactions is smaller than
|
/* Check that cost of all transactions is smaller than
|
||||||
the value of the coin. */
|
the value of the coin. */
|
||||||
@ -274,7 +279,8 @@ TEH_DB_execute_deposit (struct MHD_Connection *connection,
|
|||||||
TALER_LOG_WARNING ("Failed to store /deposit information in database\n");
|
TALER_LOG_WARNING ("Failed to store /deposit information in database\n");
|
||||||
TEH_plugin->rollback (TEH_plugin->cls,
|
TEH_plugin->rollback (TEH_plugin->cls,
|
||||||
session);
|
session);
|
||||||
return TEH_RESPONSE_reply_internal_db_error (connection);
|
return TEH_RESPONSE_reply_internal_db_error (connection,
|
||||||
|
TALER_EC_DEPOSIT_STORE_DB_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
COMMIT_TRANSACTION(session, connection);
|
COMMIT_TRANSACTION(session, connection);
|
||||||
@ -324,7 +330,8 @@ TEH_DB_execute_refund (struct MHD_Connection *connection,
|
|||||||
if (NULL == (session = TEH_plugin->get_session (TEH_plugin->cls)))
|
if (NULL == (session = TEH_plugin->get_session (TEH_plugin->cls)))
|
||||||
{
|
{
|
||||||
GNUNET_break (0);
|
GNUNET_break (0);
|
||||||
return TEH_RESPONSE_reply_internal_db_error (connection);
|
return TEH_RESPONSE_reply_internal_db_error (connection,
|
||||||
|
TALER_EC_DB_SETUP_FAILED);
|
||||||
}
|
}
|
||||||
dep = NULL;
|
dep = NULL;
|
||||||
ref = NULL;
|
ref = NULL;
|
||||||
@ -337,7 +344,8 @@ TEH_DB_execute_refund (struct MHD_Connection *connection,
|
|||||||
TEH_plugin->rollback (TEH_plugin->cls,
|
TEH_plugin->rollback (TEH_plugin->cls,
|
||||||
session);
|
session);
|
||||||
return TEH_RESPONSE_reply_refund_failure (connection,
|
return TEH_RESPONSE_reply_refund_failure (connection,
|
||||||
MHD_HTTP_NOT_FOUND);
|
MHD_HTTP_NOT_FOUND,
|
||||||
|
TALER_EC_REFUND_COIN_NOT_FOUND);
|
||||||
}
|
}
|
||||||
deposit_found = GNUNET_NO;
|
deposit_found = GNUNET_NO;
|
||||||
refund_found = GNUNET_NO;
|
refund_found = GNUNET_NO;
|
||||||
@ -411,7 +419,8 @@ TEH_DB_execute_refund (struct MHD_Connection *connection,
|
|||||||
session);
|
session);
|
||||||
TEH_plugin->free_coin_transaction_list (TEH_plugin->cls,
|
TEH_plugin->free_coin_transaction_list (TEH_plugin->cls,
|
||||||
tl);
|
tl);
|
||||||
return TEH_RESPONSE_reply_transaction_unknown (connection);
|
return TEH_RESPONSE_reply_transaction_unknown (connection,
|
||||||
|
TALER_EC_REFUND_DEPOSIT_NOT_FOUND);
|
||||||
}
|
}
|
||||||
/* handle if conflicting refund found */
|
/* handle if conflicting refund found */
|
||||||
if (GNUNET_SYSERR == refund_found)
|
if (GNUNET_SYSERR == refund_found)
|
||||||
@ -449,7 +458,8 @@ TEH_DB_execute_refund (struct MHD_Connection *connection,
|
|||||||
TEH_plugin->rollback (TEH_plugin->cls,
|
TEH_plugin->rollback (TEH_plugin->cls,
|
||||||
session);
|
session);
|
||||||
return TEH_RESPONSE_reply_refund_failure (connection,
|
return TEH_RESPONSE_reply_refund_failure (connection,
|
||||||
MHD_HTTP_PRECONDITION_FAILED);
|
MHD_HTTP_PRECONDITION_FAILED,
|
||||||
|
TALER_EC_REFUND_CURRENCY_MISSMATCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check if we already send the money for the /deposit */
|
/* check if we already send the money for the /deposit */
|
||||||
@ -466,6 +476,7 @@ TEH_DB_execute_refund (struct MHD_Connection *connection,
|
|||||||
TEH_plugin->rollback (TEH_plugin->cls,
|
TEH_plugin->rollback (TEH_plugin->cls,
|
||||||
session);
|
session);
|
||||||
return TEH_RESPONSE_reply_internal_error (connection,
|
return TEH_RESPONSE_reply_internal_error (connection,
|
||||||
|
TALER_EC_REFUND_DB_INCONSISTENT,
|
||||||
"database inconsistent");
|
"database inconsistent");
|
||||||
}
|
}
|
||||||
if (GNUNET_YES == done)
|
if (GNUNET_YES == done)
|
||||||
@ -476,7 +487,8 @@ TEH_DB_execute_refund (struct MHD_Connection *connection,
|
|||||||
TEH_plugin->free_coin_transaction_list (TEH_plugin->cls,
|
TEH_plugin->free_coin_transaction_list (TEH_plugin->cls,
|
||||||
tl);
|
tl);
|
||||||
return TEH_RESPONSE_reply_refund_failure (connection,
|
return TEH_RESPONSE_reply_refund_failure (connection,
|
||||||
MHD_HTTP_GONE);
|
MHD_HTTP_GONE,
|
||||||
|
TALER_EC_REFUND_MERCHANT_ALREADY_PAID);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check refund amount is sufficiently low */
|
/* check refund amount is sufficiently low */
|
||||||
@ -487,7 +499,8 @@ TEH_DB_execute_refund (struct MHD_Connection *connection,
|
|||||||
TEH_plugin->free_coin_transaction_list (TEH_plugin->cls,
|
TEH_plugin->free_coin_transaction_list (TEH_plugin->cls,
|
||||||
tl);
|
tl);
|
||||||
return TEH_RESPONSE_reply_refund_failure (connection,
|
return TEH_RESPONSE_reply_refund_failure (connection,
|
||||||
MHD_HTTP_PRECONDITION_FAILED);
|
MHD_HTTP_PRECONDITION_FAILED,
|
||||||
|
TALER_EC_REFUND_INSUFFICIENT_FUNDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check refund fee matches fee of denomination key! */
|
/* Check refund fee matches fee of denomination key! */
|
||||||
@ -504,6 +517,7 @@ TEH_DB_execute_refund (struct MHD_Connection *connection,
|
|||||||
TEH_plugin->free_coin_transaction_list (TEH_plugin->cls,
|
TEH_plugin->free_coin_transaction_list (TEH_plugin->cls,
|
||||||
tl);
|
tl);
|
||||||
return TEH_RESPONSE_reply_internal_error (connection,
|
return TEH_RESPONSE_reply_internal_error (connection,
|
||||||
|
TALER_EC_REFUND_DENOMINATION_KEY_NOT_FOUND,
|
||||||
"denomination key not found");
|
"denomination key not found");
|
||||||
}
|
}
|
||||||
TALER_amount_ntoh (&expect_fee,
|
TALER_amount_ntoh (&expect_fee,
|
||||||
@ -519,6 +533,7 @@ TEH_DB_execute_refund (struct MHD_Connection *connection,
|
|||||||
TEH_plugin->free_coin_transaction_list (TEH_plugin->cls,
|
TEH_plugin->free_coin_transaction_list (TEH_plugin->cls,
|
||||||
tl);
|
tl);
|
||||||
return TEH_RESPONSE_reply_arg_invalid (connection,
|
return TEH_RESPONSE_reply_arg_invalid (connection,
|
||||||
|
TALER_EC_REFUND_FEE_TOO_LOW,
|
||||||
"refund_fee");
|
"refund_fee");
|
||||||
}
|
}
|
||||||
if (1 == fee_cmp)
|
if (1 == fee_cmp)
|
||||||
@ -538,7 +553,8 @@ TEH_DB_execute_refund (struct MHD_Connection *connection,
|
|||||||
TALER_LOG_WARNING ("Failed to store /refund information in database\n");
|
TALER_LOG_WARNING ("Failed to store /refund information in database\n");
|
||||||
TEH_plugin->rollback (TEH_plugin->cls,
|
TEH_plugin->rollback (TEH_plugin->cls,
|
||||||
session);
|
session);
|
||||||
return TEH_RESPONSE_reply_internal_db_error (connection);
|
return TEH_RESPONSE_reply_internal_db_error (connection,
|
||||||
|
TALER_EC_REFUND_STORE_DB_ERROR);
|
||||||
}
|
}
|
||||||
COMMIT_TRANSACTION(session, connection);
|
COMMIT_TRANSACTION(session, connection);
|
||||||
|
|
||||||
@ -566,7 +582,8 @@ TEH_DB_execute_reserve_status (struct MHD_Connection *connection,
|
|||||||
if (NULL == (session = TEH_plugin->get_session (TEH_plugin->cls)))
|
if (NULL == (session = TEH_plugin->get_session (TEH_plugin->cls)))
|
||||||
{
|
{
|
||||||
GNUNET_break (0);
|
GNUNET_break (0);
|
||||||
return TEH_RESPONSE_reply_internal_db_error (connection);
|
return TEH_RESPONSE_reply_internal_db_error (connection,
|
||||||
|
TALER_EC_DB_SETUP_FAILED);
|
||||||
}
|
}
|
||||||
rh = TEH_plugin->get_reserve_history (TEH_plugin->cls,
|
rh = TEH_plugin->get_reserve_history (TEH_plugin->cls,
|
||||||
session,
|
session,
|
||||||
@ -637,6 +654,7 @@ execute_reserve_withdraw_transaction (struct MHD_Connection *connection,
|
|||||||
TEH_plugin->rollback (TEH_plugin->cls,
|
TEH_plugin->rollback (TEH_plugin->cls,
|
||||||
session);
|
session);
|
||||||
return TEH_RESPONSE_reply_arg_unknown (connection,
|
return TEH_RESPONSE_reply_arg_unknown (connection,
|
||||||
|
TALER_EC_WITHDRAW_RESERVE_UNKNOWN,
|
||||||
"reserve_pub");
|
"reserve_pub");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -653,7 +671,8 @@ execute_reserve_withdraw_transaction (struct MHD_Connection *connection,
|
|||||||
{
|
{
|
||||||
TEH_plugin->rollback (TEH_plugin->cls,
|
TEH_plugin->rollback (TEH_plugin->cls,
|
||||||
session);
|
session);
|
||||||
return TEH_RESPONSE_reply_internal_db_error (connection);
|
return TEH_RESPONSE_reply_internal_db_error (connection,
|
||||||
|
TALER_EC_WITHDRAW_AMOUNT_FEE_OVERFLOW);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* calculate balance of the reserve */
|
/* calculate balance of the reserve */
|
||||||
@ -673,7 +692,8 @@ execute_reserve_withdraw_transaction (struct MHD_Connection *connection,
|
|||||||
{
|
{
|
||||||
TEH_plugin->rollback (TEH_plugin->cls,
|
TEH_plugin->rollback (TEH_plugin->cls,
|
||||||
session);
|
session);
|
||||||
return TEH_RESPONSE_reply_internal_db_error (connection);
|
return TEH_RESPONSE_reply_internal_db_error (connection,
|
||||||
|
TALER_EC_WITHDRAW_AMOUNT_DEPOSITS_OVERFLOW);
|
||||||
}
|
}
|
||||||
res |= 1;
|
res |= 1;
|
||||||
break;
|
break;
|
||||||
@ -686,7 +706,8 @@ execute_reserve_withdraw_transaction (struct MHD_Connection *connection,
|
|||||||
GNUNET_break (0);
|
GNUNET_break (0);
|
||||||
TEH_plugin->rollback (TEH_plugin->cls,
|
TEH_plugin->rollback (TEH_plugin->cls,
|
||||||
session);
|
session);
|
||||||
return TEH_RESPONSE_reply_internal_db_error (connection);
|
return TEH_RESPONSE_reply_internal_db_error (connection,
|
||||||
|
TALER_EC_WITHDRAW_HISTORIC_DENOMINATION_KEY_NOT_FOUND);
|
||||||
}
|
}
|
||||||
TALER_amount_ntoh (&value,
|
TALER_amount_ntoh (&value,
|
||||||
&tdki->issue.properties.value);
|
&tdki->issue.properties.value);
|
||||||
@ -700,7 +721,8 @@ execute_reserve_withdraw_transaction (struct MHD_Connection *connection,
|
|||||||
{
|
{
|
||||||
TEH_plugin->rollback (TEH_plugin->cls,
|
TEH_plugin->rollback (TEH_plugin->cls,
|
||||||
session);
|
session);
|
||||||
return TEH_RESPONSE_reply_internal_db_error (connection);
|
return TEH_RESPONSE_reply_internal_db_error (connection,
|
||||||
|
TALER_EC_WITHDRAW_AMOUNT_WITHDRAWALS_OVERFLOW);
|
||||||
}
|
}
|
||||||
res |= 2;
|
res |= 2;
|
||||||
break;
|
break;
|
||||||
@ -708,9 +730,10 @@ execute_reserve_withdraw_transaction (struct MHD_Connection *connection,
|
|||||||
}
|
}
|
||||||
if (0 == (res & 1))
|
if (0 == (res & 1))
|
||||||
{
|
{
|
||||||
/* did not encounter any deposit operations, how can we have a reserve? */
|
/* did not encounter any wire transfer operations, how can we have a reserve? */
|
||||||
GNUNET_break (0);
|
GNUNET_break (0);
|
||||||
return TEH_RESPONSE_reply_internal_db_error (connection);
|
return TEH_RESPONSE_reply_internal_db_error (connection,
|
||||||
|
TALER_EC_WITHDRAW_RESERVE_WITHOUT_WIRE_TRANSFER);
|
||||||
}
|
}
|
||||||
if (0 == (res & 2))
|
if (0 == (res & 2))
|
||||||
{
|
{
|
||||||
@ -748,6 +771,7 @@ execute_reserve_withdraw_transaction (struct MHD_Connection *connection,
|
|||||||
TEH_plugin->rollback (TEH_plugin->cls,
|
TEH_plugin->rollback (TEH_plugin->cls,
|
||||||
session);
|
session);
|
||||||
return TEH_RESPONSE_reply_internal_error (connection,
|
return TEH_RESPONSE_reply_internal_error (connection,
|
||||||
|
TALER_EC_WITHDRAW_SIGNATURE_FAILED,
|
||||||
"Internal error");
|
"Internal error");
|
||||||
}
|
}
|
||||||
collectable.sig = *denom_sig;
|
collectable.sig = *denom_sig;
|
||||||
@ -765,7 +789,8 @@ execute_reserve_withdraw_transaction (struct MHD_Connection *connection,
|
|||||||
GNUNET_break (0);
|
GNUNET_break (0);
|
||||||
TEH_plugin->rollback (TEH_plugin->cls,
|
TEH_plugin->rollback (TEH_plugin->cls,
|
||||||
session);
|
session);
|
||||||
return TEH_RESPONSE_reply_internal_db_error (connection);
|
return TEH_RESPONSE_reply_internal_db_error (connection,
|
||||||
|
TALER_EC_WITHDRAW_DB_STORE_ERROR);
|
||||||
}
|
}
|
||||||
COMMIT_TRANSACTION (session, connection);
|
COMMIT_TRANSACTION (session, connection);
|
||||||
|
|
||||||
@ -811,7 +836,8 @@ TEH_DB_execute_reserve_withdraw (struct MHD_Connection *connection,
|
|||||||
if (NULL == (session = TEH_plugin->get_session (TEH_plugin->cls)))
|
if (NULL == (session = TEH_plugin->get_session (TEH_plugin->cls)))
|
||||||
{
|
{
|
||||||
GNUNET_break (0);
|
GNUNET_break (0);
|
||||||
return TEH_RESPONSE_reply_internal_db_error (connection);
|
return TEH_RESPONSE_reply_internal_db_error (connection,
|
||||||
|
TALER_EC_DB_SETUP_FAILED);
|
||||||
}
|
}
|
||||||
res = TEH_plugin->get_withdraw_info (TEH_plugin->cls,
|
res = TEH_plugin->get_withdraw_info (TEH_plugin->cls,
|
||||||
session,
|
session,
|
||||||
@ -820,7 +846,8 @@ TEH_DB_execute_reserve_withdraw (struct MHD_Connection *connection,
|
|||||||
if (GNUNET_SYSERR == res)
|
if (GNUNET_SYSERR == res)
|
||||||
{
|
{
|
||||||
GNUNET_break (0);
|
GNUNET_break (0);
|
||||||
return TEH_RESPONSE_reply_internal_db_error (connection);
|
return TEH_RESPONSE_reply_internal_db_error (connection,
|
||||||
|
TALER_EC_WITHDRAW_DB_FETCH_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Don't sign again if we have already signed the coin */
|
/* Don't sign again if we have already signed the coin */
|
||||||
@ -834,6 +861,7 @@ TEH_DB_execute_reserve_withdraw (struct MHD_Connection *connection,
|
|||||||
}
|
}
|
||||||
GNUNET_assert (GNUNET_NO == res);
|
GNUNET_assert (GNUNET_NO == res);
|
||||||
|
|
||||||
|
/* FIXME: do we have to do this a second time here? */
|
||||||
key_state = TEH_KS_acquire ();
|
key_state = TEH_KS_acquire ();
|
||||||
dki = TEH_KS_denomination_key_lookup (key_state,
|
dki = TEH_KS_denomination_key_lookup (key_state,
|
||||||
denomination_pub,
|
denomination_pub,
|
||||||
@ -843,9 +871,11 @@ TEH_DB_execute_reserve_withdraw (struct MHD_Connection *connection,
|
|||||||
TEH_KS_release (key_state);
|
TEH_KS_release (key_state);
|
||||||
return TEH_RESPONSE_reply_json_pack (connection,
|
return TEH_RESPONSE_reply_json_pack (connection,
|
||||||
MHD_HTTP_NOT_FOUND,
|
MHD_HTTP_NOT_FOUND,
|
||||||
"{s:s}",
|
"{s:s, s:I}",
|
||||||
"error",
|
"error",
|
||||||
"Denomination not found");
|
"Denomination not found",
|
||||||
|
"code",
|
||||||
|
(json_int_t) TALER_EC_WITHDRAW_DENOMINATION_KEY_NOT_FOUND);
|
||||||
}
|
}
|
||||||
denom_sig.rsa_signature = NULL;
|
denom_sig.rsa_signature = NULL;
|
||||||
res = execute_reserve_withdraw_transaction (connection,
|
res = execute_reserve_withdraw_transaction (connection,
|
||||||
@ -901,8 +931,9 @@ refresh_check_melt (struct MHD_Connection *connection,
|
|||||||
TEH_KS_DKU_DEPOSIT);
|
TEH_KS_DKU_DEPOSIT);
|
||||||
if (NULL == dk)
|
if (NULL == dk)
|
||||||
return (MHD_YES ==
|
return (MHD_YES ==
|
||||||
TEH_RESPONSE_reply_arg_unknown (connection,
|
TEH_RESPONSE_reply_internal_error (connection,
|
||||||
"denom_pub"))
|
TALER_EC_REFRESH_MELT_DB_DENOMINATION_KEY_NOT_FOUND,
|
||||||
|
"denomination key no longer available while executing transaction"))
|
||||||
? GNUNET_NO : GNUNET_SYSERR;
|
? GNUNET_NO : GNUNET_SYSERR;
|
||||||
dki = &dk->issue;
|
dki = &dk->issue;
|
||||||
TALER_amount_ntoh (&coin_value,
|
TALER_amount_ntoh (&coin_value,
|
||||||
@ -922,7 +953,8 @@ refresh_check_melt (struct MHD_Connection *connection,
|
|||||||
TEH_plugin->free_coin_transaction_list (TEH_plugin->cls,
|
TEH_plugin->free_coin_transaction_list (TEH_plugin->cls,
|
||||||
tl);
|
tl);
|
||||||
return (MHD_YES ==
|
return (MHD_YES ==
|
||||||
TEH_RESPONSE_reply_internal_db_error (connection))
|
TEH_RESPONSE_reply_internal_db_error (connection,
|
||||||
|
TALER_EC_REFRESH_MELT_COIN_HISTORY_COMPUTATION_FAILED))
|
||||||
? GNUNET_NO : GNUNET_SYSERR;
|
? GNUNET_NO : GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
/* Refuse to refresh when the coin's value is insufficient
|
/* Refuse to refresh when the coin's value is insufficient
|
||||||
@ -995,7 +1027,8 @@ TEH_DB_execute_refresh_melt (struct MHD_Connection *connection,
|
|||||||
if (NULL == (session = TEH_plugin->get_session (TEH_plugin->cls)))
|
if (NULL == (session = TEH_plugin->get_session (TEH_plugin->cls)))
|
||||||
{
|
{
|
||||||
GNUNET_break (0);
|
GNUNET_break (0);
|
||||||
return TEH_RESPONSE_reply_internal_db_error (connection);
|
return TEH_RESPONSE_reply_internal_db_error (connection,
|
||||||
|
TALER_EC_DB_SETUP_FAILED);
|
||||||
}
|
}
|
||||||
START_TRANSACTION (session, connection);
|
START_TRANSACTION (session, connection);
|
||||||
res = TEH_plugin->get_refresh_session (TEH_plugin->cls,
|
res = TEH_plugin->get_refresh_session (TEH_plugin->cls,
|
||||||
@ -1015,14 +1048,15 @@ TEH_DB_execute_refresh_melt (struct MHD_Connection *connection,
|
|||||||
{
|
{
|
||||||
TEH_plugin->rollback (TEH_plugin->cls,
|
TEH_plugin->rollback (TEH_plugin->cls,
|
||||||
session);
|
session);
|
||||||
return TEH_RESPONSE_reply_internal_db_error (connection);
|
return TEH_RESPONSE_reply_internal_db_error (connection,
|
||||||
|
TALER_EC_REFRESH_MELT_DB_FETCH_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* store 'global' session data */
|
/* store 'global' session data */
|
||||||
refresh_session.num_newcoins = num_new_denoms;
|
refresh_session.num_newcoins = num_new_denoms;
|
||||||
refresh_session.noreveal_index
|
refresh_session.noreveal_index
|
||||||
= GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_STRONG,
|
= GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_STRONG,
|
||||||
TALER_CNC_KAPPA);
|
TALER_CNC_KAPPA);
|
||||||
key_state = TEH_KS_acquire ();
|
key_state = TEH_KS_acquire ();
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
(res = refresh_check_melt (connection,
|
(res = refresh_check_melt (connection,
|
||||||
@ -1047,7 +1081,8 @@ TEH_DB_execute_refresh_melt (struct MHD_Connection *connection,
|
|||||||
{
|
{
|
||||||
TEH_plugin->rollback (TEH_plugin->cls,
|
TEH_plugin->rollback (TEH_plugin->cls,
|
||||||
session);
|
session);
|
||||||
return TEH_RESPONSE_reply_internal_db_error (connection);
|
return TEH_RESPONSE_reply_internal_db_error (connection,
|
||||||
|
TALER_EC_REFRESH_MELT_DB_STORE_SESSION_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* store requested new denominations */
|
/* store requested new denominations */
|
||||||
@ -1060,7 +1095,8 @@ TEH_DB_execute_refresh_melt (struct MHD_Connection *connection,
|
|||||||
{
|
{
|
||||||
TEH_plugin->rollback (TEH_plugin->cls,
|
TEH_plugin->rollback (TEH_plugin->cls,
|
||||||
session);
|
session);
|
||||||
return TEH_RESPONSE_reply_internal_db_error (connection);
|
return TEH_RESPONSE_reply_internal_db_error (connection,
|
||||||
|
TALER_EC_REFRESH_MELT_DB_STORE_ORDER_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
@ -1072,7 +1108,8 @@ TEH_DB_execute_refresh_melt (struct MHD_Connection *connection,
|
|||||||
{
|
{
|
||||||
TEH_plugin->rollback (TEH_plugin->cls,
|
TEH_plugin->rollback (TEH_plugin->cls,
|
||||||
session);
|
session);
|
||||||
return TEH_RESPONSE_reply_internal_db_error (connection);
|
return TEH_RESPONSE_reply_internal_db_error (connection,
|
||||||
|
TALER_EC_REFRESH_MELT_DB_STORE_ORDER_ERROR);
|
||||||
}
|
}
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
TEH_plugin->insert_refresh_transfer_public_key (TEH_plugin->cls,
|
TEH_plugin->insert_refresh_transfer_public_key (TEH_plugin->cls,
|
||||||
@ -1082,7 +1119,8 @@ TEH_DB_execute_refresh_melt (struct MHD_Connection *connection,
|
|||||||
{
|
{
|
||||||
TEH_plugin->rollback (TEH_plugin->cls,
|
TEH_plugin->rollback (TEH_plugin->cls,
|
||||||
session);
|
session);
|
||||||
return TEH_RESPONSE_reply_internal_db_error (connection);
|
return TEH_RESPONSE_reply_internal_db_error (connection,
|
||||||
|
TALER_EC_REFRESH_MELT_DB_STORE_TRANSFER_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
COMMIT_TRANSACTION (session, connection);
|
COMMIT_TRANSACTION (session, connection);
|
||||||
@ -1126,8 +1164,6 @@ check_commitment (struct MHD_Connection *connection,
|
|||||||
struct TALER_TransferSecretP transfer_secret;
|
struct TALER_TransferSecretP transfer_secret;
|
||||||
unsigned int j;
|
unsigned int j;
|
||||||
|
|
||||||
/* FIXME: instead of consulting DB, reconstruct everything
|
|
||||||
from transfer_priv here! */
|
|
||||||
TALER_link_reveal_transfer_secret (transfer_priv,
|
TALER_link_reveal_transfer_secret (transfer_priv,
|
||||||
&melt->coin.coin_pub,
|
&melt->coin.coin_pub,
|
||||||
&transfer_secret);
|
&transfer_secret);
|
||||||
@ -1158,8 +1194,10 @@ check_commitment (struct MHD_Connection *connection,
|
|||||||
{
|
{
|
||||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||||
"Blind failed (bad denomination key!?)\n");
|
"Blind failed (bad denomination key!?)\n");
|
||||||
return (MHD_YES == TEH_RESPONSE_reply_internal_error (connection,
|
return (MHD_YES ==
|
||||||
"Blinding error"))
|
TEH_RESPONSE_reply_internal_error (connection,
|
||||||
|
TALER_EC_REFRESH_REVEAL_BLINDING_ERROR,
|
||||||
|
"Blinding error"))
|
||||||
? GNUNET_NO : GNUNET_SYSERR;
|
? GNUNET_NO : GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
GNUNET_CRYPTO_hash_context_read (hash_context,
|
GNUNET_CRYPTO_hash_context_read (hash_context,
|
||||||
@ -1274,7 +1312,8 @@ execute_refresh_reveal_transaction (struct MHD_Connection *connection,
|
|||||||
j);
|
j);
|
||||||
if (NULL == ev_sigs[j].rsa_signature)
|
if (NULL == ev_sigs[j].rsa_signature)
|
||||||
{
|
{
|
||||||
ret = TEH_RESPONSE_reply_internal_db_error (connection);
|
ret = TEH_RESPONSE_reply_internal_db_error (connection,
|
||||||
|
TALER_EC_REFRESH_REVEAL_SIGNING_ERROR);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1323,7 +1362,8 @@ TEH_DB_execute_refresh_reveal (struct MHD_Connection *connection,
|
|||||||
if (NULL == (session = TEH_plugin->get_session (TEH_plugin->cls)))
|
if (NULL == (session = TEH_plugin->get_session (TEH_plugin->cls)))
|
||||||
{
|
{
|
||||||
GNUNET_break (0);
|
GNUNET_break (0);
|
||||||
return TEH_RESPONSE_reply_internal_db_error (connection);
|
return TEH_RESPONSE_reply_internal_db_error (connection,
|
||||||
|
TALER_EC_DB_SETUP_FAILED);
|
||||||
}
|
}
|
||||||
|
|
||||||
res = TEH_plugin->get_refresh_session (TEH_plugin->cls,
|
res = TEH_plugin->get_refresh_session (TEH_plugin->cls,
|
||||||
@ -1332,10 +1372,12 @@ TEH_DB_execute_refresh_reveal (struct MHD_Connection *connection,
|
|||||||
&refresh_session);
|
&refresh_session);
|
||||||
if (GNUNET_NO == res)
|
if (GNUNET_NO == res)
|
||||||
return TEH_RESPONSE_reply_arg_invalid (connection,
|
return TEH_RESPONSE_reply_arg_invalid (connection,
|
||||||
|
TALER_EC_REFRESH_REVEAL_SESSION_UNKNOWN,
|
||||||
"session_hash");
|
"session_hash");
|
||||||
if ( (GNUNET_SYSERR == res) ||
|
if ( (GNUNET_SYSERR == res) ||
|
||||||
(refresh_session.noreveal_index >= TALER_CNC_KAPPA) )
|
(refresh_session.noreveal_index >= TALER_CNC_KAPPA) )
|
||||||
return TEH_RESPONSE_reply_internal_db_error (connection);
|
return TEH_RESPONSE_reply_internal_db_error (connection,
|
||||||
|
TALER_EC_REFRESH_REVEAL_DB_FETCH_SESSION_ERROR);
|
||||||
denom_pubs = GNUNET_new_array (refresh_session.num_newcoins,
|
denom_pubs = GNUNET_new_array (refresh_session.num_newcoins,
|
||||||
struct TALER_DenominationPublicKey);
|
struct TALER_DenominationPublicKey);
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
@ -1349,7 +1391,8 @@ TEH_DB_execute_refresh_reveal (struct MHD_Connection *connection,
|
|||||||
GNUNET_free (denom_pubs);
|
GNUNET_free (denom_pubs);
|
||||||
GNUNET_CRYPTO_rsa_signature_free (refresh_session.melt.coin.denom_sig.rsa_signature);
|
GNUNET_CRYPTO_rsa_signature_free (refresh_session.melt.coin.denom_sig.rsa_signature);
|
||||||
GNUNET_CRYPTO_rsa_public_key_free (refresh_session.melt.coin.denom_pub.rsa_public_key);
|
GNUNET_CRYPTO_rsa_public_key_free (refresh_session.melt.coin.denom_pub.rsa_public_key);
|
||||||
return (MHD_YES == TEH_RESPONSE_reply_internal_db_error (connection))
|
return (MHD_YES == TEH_RESPONSE_reply_internal_db_error (connection,
|
||||||
|
TALER_EC_REFRESH_REVEAL_DB_FETCH_ORDER_ERROR))
|
||||||
? GNUNET_NO : GNUNET_SYSERR;
|
? GNUNET_NO : GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1373,7 +1416,8 @@ TEH_DB_execute_refresh_reveal (struct MHD_Connection *connection,
|
|||||||
GNUNET_CRYPTO_rsa_signature_free (refresh_session.melt.coin.denom_sig.rsa_signature);
|
GNUNET_CRYPTO_rsa_signature_free (refresh_session.melt.coin.denom_sig.rsa_signature);
|
||||||
GNUNET_CRYPTO_rsa_public_key_free (refresh_session.melt.coin.denom_pub.rsa_public_key);
|
GNUNET_CRYPTO_rsa_public_key_free (refresh_session.melt.coin.denom_pub.rsa_public_key);
|
||||||
GNUNET_CRYPTO_hash_context_abort (hash_context);
|
GNUNET_CRYPTO_hash_context_abort (hash_context);
|
||||||
return (MHD_YES == TEH_RESPONSE_reply_internal_db_error (connection))
|
return (MHD_YES == TEH_RESPONSE_reply_internal_db_error (connection,
|
||||||
|
TALER_EC_REFRESH_REVEAL_DB_FETCH_TRANSFER_ERROR))
|
||||||
? GNUNET_NO : GNUNET_SYSERR;
|
? GNUNET_NO : GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
GNUNET_CRYPTO_hash_context_read (hash_context,
|
GNUNET_CRYPTO_hash_context_read (hash_context,
|
||||||
@ -1410,7 +1454,8 @@ TEH_DB_execute_refresh_reveal (struct MHD_Connection *connection,
|
|||||||
GNUNET_CRYPTO_rsa_signature_free (refresh_session.melt.coin.denom_sig.rsa_signature);
|
GNUNET_CRYPTO_rsa_signature_free (refresh_session.melt.coin.denom_sig.rsa_signature);
|
||||||
GNUNET_CRYPTO_rsa_public_key_free (refresh_session.melt.coin.denom_pub.rsa_public_key);
|
GNUNET_CRYPTO_rsa_public_key_free (refresh_session.melt.coin.denom_pub.rsa_public_key);
|
||||||
GNUNET_CRYPTO_hash_context_abort (hash_context);
|
GNUNET_CRYPTO_hash_context_abort (hash_context);
|
||||||
return (MHD_YES == TEH_RESPONSE_reply_internal_db_error (connection))
|
return (MHD_YES == TEH_RESPONSE_reply_internal_db_error (connection,
|
||||||
|
TALER_EC_REFRESH_REVEAL_DB_FETCH_ORDER_ERROR))
|
||||||
? GNUNET_NO : GNUNET_SYSERR;
|
? GNUNET_NO : GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
for (i=0;i<refresh_session.num_newcoins;i++)
|
for (i=0;i<refresh_session.num_newcoins;i++)
|
||||||
@ -1463,7 +1508,8 @@ TEH_DB_execute_refresh_reveal (struct MHD_Connection *connection,
|
|||||||
GNUNET_CRYPTO_rsa_signature_free (refresh_session.melt.coin.denom_sig.rsa_signature);
|
GNUNET_CRYPTO_rsa_signature_free (refresh_session.melt.coin.denom_sig.rsa_signature);
|
||||||
GNUNET_CRYPTO_rsa_public_key_free (refresh_session.melt.coin.denom_pub.rsa_public_key);
|
GNUNET_CRYPTO_rsa_public_key_free (refresh_session.melt.coin.denom_pub.rsa_public_key);
|
||||||
GNUNET_CRYPTO_hash_context_abort (hash_context);
|
GNUNET_CRYPTO_hash_context_abort (hash_context);
|
||||||
return TEH_RESPONSE_reply_internal_db_error (connection);
|
return TEH_RESPONSE_reply_internal_db_error (connection,
|
||||||
|
TALER_EC_REFRESH_REVEAL_DB_FETCH_COMMIT_ERROR);
|
||||||
}
|
}
|
||||||
/* add envelopes to hash_context */
|
/* add envelopes to hash_context */
|
||||||
for (j=0;j<refresh_session.num_newcoins;j++)
|
for (j=0;j<refresh_session.num_newcoins;j++)
|
||||||
@ -1656,7 +1702,8 @@ TEH_DB_execute_refresh_link (struct MHD_Connection *connection,
|
|||||||
if (NULL == (ctx.session = TEH_plugin->get_session (TEH_plugin->cls)))
|
if (NULL == (ctx.session = TEH_plugin->get_session (TEH_plugin->cls)))
|
||||||
{
|
{
|
||||||
GNUNET_break (0);
|
GNUNET_break (0);
|
||||||
return TEH_RESPONSE_reply_internal_db_error (connection);
|
return TEH_RESPONSE_reply_internal_db_error (connection,
|
||||||
|
TALER_EC_DB_SETUP_FAILED);
|
||||||
}
|
}
|
||||||
ctx.connection = connection;
|
ctx.connection = connection;
|
||||||
ctx.num_sessions = 0;
|
ctx.num_sessions = 0;
|
||||||
@ -1680,6 +1727,7 @@ TEH_DB_execute_refresh_link (struct MHD_Connection *connection,
|
|||||||
GNUNET_assert (GNUNET_OK == ctx.status);
|
GNUNET_assert (GNUNET_OK == ctx.status);
|
||||||
if (0 == ctx.num_sessions)
|
if (0 == ctx.num_sessions)
|
||||||
return TEH_RESPONSE_reply_arg_unknown (connection,
|
return TEH_RESPONSE_reply_arg_unknown (connection,
|
||||||
|
TALER_EC_REFRESH_LINK_COIN_UNKNOWN,
|
||||||
"coin_pub");
|
"coin_pub");
|
||||||
res = TEH_RESPONSE_reply_refresh_link_success (connection,
|
res = TEH_RESPONSE_reply_refresh_link_success (connection,
|
||||||
ctx.num_sessions,
|
ctx.num_sessions,
|
||||||
@ -1720,7 +1768,8 @@ TEH_DB_execute_admin_add_incoming (struct MHD_Connection *connection,
|
|||||||
if (NULL == (session = TEH_plugin->get_session (TEH_plugin->cls)))
|
if (NULL == (session = TEH_plugin->get_session (TEH_plugin->cls)))
|
||||||
{
|
{
|
||||||
GNUNET_break (0);
|
GNUNET_break (0);
|
||||||
return TEH_RESPONSE_reply_internal_db_error (connection);
|
return TEH_RESPONSE_reply_internal_db_error (connection,
|
||||||
|
TALER_EC_DB_SETUP_FAILED);
|
||||||
}
|
}
|
||||||
ret = TEH_plugin->reserves_in_insert (TEH_plugin->cls,
|
ret = TEH_plugin->reserves_in_insert (TEH_plugin->cls,
|
||||||
session,
|
session,
|
||||||
@ -1732,7 +1781,8 @@ TEH_DB_execute_admin_add_incoming (struct MHD_Connection *connection,
|
|||||||
if (GNUNET_SYSERR == ret)
|
if (GNUNET_SYSERR == ret)
|
||||||
{
|
{
|
||||||
GNUNET_break (0);
|
GNUNET_break (0);
|
||||||
return TEH_RESPONSE_reply_internal_db_error (connection);
|
return TEH_RESPONSE_reply_internal_db_error (connection,
|
||||||
|
TALER_EC_ADMIN_ADD_INCOMING_DB_STORE);
|
||||||
}
|
}
|
||||||
return TEH_RESPONSE_reply_json_pack (connection,
|
return TEH_RESPONSE_reply_json_pack (connection,
|
||||||
MHD_HTTP_OK,
|
MHD_HTTP_OK,
|
||||||
@ -1913,7 +1963,8 @@ TEH_DB_execute_track_transfer (struct MHD_Connection *connection,
|
|||||||
if (NULL == (session = TEH_plugin->get_session (TEH_plugin->cls)))
|
if (NULL == (session = TEH_plugin->get_session (TEH_plugin->cls)))
|
||||||
{
|
{
|
||||||
GNUNET_break (0);
|
GNUNET_break (0);
|
||||||
return TEH_RESPONSE_reply_internal_db_error (connection);
|
return TEH_RESPONSE_reply_internal_db_error (connection,
|
||||||
|
TALER_EC_DB_SETUP_FAILED);
|
||||||
}
|
}
|
||||||
ctx.is_valid = GNUNET_NO;
|
ctx.is_valid = GNUNET_NO;
|
||||||
ctx.wdd_head = NULL;
|
ctx.wdd_head = NULL;
|
||||||
@ -1926,18 +1977,21 @@ TEH_DB_execute_track_transfer (struct MHD_Connection *connection,
|
|||||||
if (GNUNET_SYSERR == ret)
|
if (GNUNET_SYSERR == ret)
|
||||||
{
|
{
|
||||||
GNUNET_break (0);
|
GNUNET_break (0);
|
||||||
ret = TEH_RESPONSE_reply_internal_db_error (connection);
|
ret = TEH_RESPONSE_reply_internal_db_error (connection,
|
||||||
|
TALER_EC_TRACK_TRANSFER_DB_FETCH_FAILED);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
if (GNUNET_SYSERR == ctx.is_valid)
|
if (GNUNET_SYSERR == ctx.is_valid)
|
||||||
{
|
{
|
||||||
GNUNET_break (0);
|
GNUNET_break (0);
|
||||||
ret = TEH_RESPONSE_reply_internal_db_error (connection);
|
ret = TEH_RESPONSE_reply_internal_db_error (connection,
|
||||||
|
TALER_EC_TRACK_TRANSFER_DB_INCONSISTENT);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
if (GNUNET_NO == ctx.is_valid)
|
if (GNUNET_NO == ctx.is_valid)
|
||||||
{
|
{
|
||||||
ret = TEH_RESPONSE_reply_arg_unknown (connection,
|
ret = TEH_RESPONSE_reply_arg_unknown (connection,
|
||||||
|
TALER_EC_TRACK_TRANSFER_WTID_NOT_FOUND,
|
||||||
"wtid");
|
"wtid");
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
@ -2035,7 +2089,8 @@ handle_wtid_data (void *cls,
|
|||||||
coin_fee))
|
coin_fee))
|
||||||
{
|
{
|
||||||
GNUNET_break (0);
|
GNUNET_break (0);
|
||||||
ctx->res = TEH_RESPONSE_reply_internal_db_error (ctx->connection);
|
ctx->res = TEH_RESPONSE_reply_internal_db_error (ctx->connection,
|
||||||
|
TALER_EC_TRACK_TRANSACTION_DB_FEE_INCONSISTENT);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -2079,7 +2134,8 @@ TEH_DB_execute_track_transaction (struct MHD_Connection *connection,
|
|||||||
if (NULL == (session = TEH_plugin->get_session (TEH_plugin->cls)))
|
if (NULL == (session = TEH_plugin->get_session (TEH_plugin->cls)))
|
||||||
{
|
{
|
||||||
GNUNET_break (0);
|
GNUNET_break (0);
|
||||||
return TEH_RESPONSE_reply_internal_db_error (connection);
|
return TEH_RESPONSE_reply_internal_db_error (connection,
|
||||||
|
TALER_EC_DB_SETUP_FAILED);
|
||||||
}
|
}
|
||||||
ctx.connection = connection;
|
ctx.connection = connection;
|
||||||
ctx.h_contract = *h_contract;
|
ctx.h_contract = *h_contract;
|
||||||
@ -2100,17 +2156,20 @@ TEH_DB_execute_track_transaction (struct MHD_Connection *connection,
|
|||||||
{
|
{
|
||||||
GNUNET_break (0);
|
GNUNET_break (0);
|
||||||
GNUNET_break (GNUNET_SYSERR == ctx.res);
|
GNUNET_break (GNUNET_SYSERR == ctx.res);
|
||||||
return TEH_RESPONSE_reply_internal_db_error (connection);
|
return TEH_RESPONSE_reply_internal_db_error (connection,
|
||||||
|
TALER_EC_TRACK_TRANSACTION_DB_FETCH_FAILED);
|
||||||
}
|
}
|
||||||
if (GNUNET_NO == ret)
|
if (GNUNET_NO == ret)
|
||||||
{
|
{
|
||||||
GNUNET_break (GNUNET_SYSERR == ctx.res);
|
GNUNET_break (GNUNET_SYSERR == ctx.res);
|
||||||
return TEH_RESPONSE_reply_transaction_unknown (connection);
|
return TEH_RESPONSE_reply_transaction_unknown (connection,
|
||||||
|
TALER_EC_TRACK_TRANSACTION_NOT_FOUND);
|
||||||
}
|
}
|
||||||
if (GNUNET_SYSERR == ctx.res)
|
if (GNUNET_SYSERR == ctx.res)
|
||||||
{
|
{
|
||||||
GNUNET_break (0);
|
GNUNET_break (0);
|
||||||
return TEH_RESPONSE_reply_internal_error (connection,
|
return TEH_RESPONSE_reply_internal_error (connection,
|
||||||
|
TALER_EC_TRACK_TRANSACTION_WTID_RESOLUTION_ERROR,
|
||||||
"bug resolving deposit wtid");
|
"bug resolving deposit wtid");
|
||||||
}
|
}
|
||||||
return ctx.res;
|
return ctx.res;
|
||||||
|
@ -48,12 +48,9 @@
|
|||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
verify_and_execute_deposit (struct MHD_Connection *connection,
|
verify_and_execute_deposit (struct MHD_Connection *connection,
|
||||||
const struct TALER_EXCHANGEDB_Deposit *deposit)
|
const struct TALER_EXCHANGEDB_Deposit *deposit)
|
||||||
{
|
{
|
||||||
struct TEH_KS_StateHandle *key_state;
|
|
||||||
struct TALER_DepositRequestPS dr;
|
struct TALER_DepositRequestPS dr;
|
||||||
struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki;
|
|
||||||
struct TALER_Amount fee_deposit;
|
|
||||||
|
|
||||||
dr.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_DEPOSIT);
|
dr.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_DEPOSIT);
|
||||||
dr.purpose.size = htonl (sizeof (struct TALER_DepositRequestPS));
|
dr.purpose.size = htonl (sizeof (struct TALER_DepositRequestPS));
|
||||||
@ -76,39 +73,9 @@ verify_and_execute_deposit (struct MHD_Connection *connection,
|
|||||||
{
|
{
|
||||||
TALER_LOG_WARNING ("Invalid signature on /deposit request\n");
|
TALER_LOG_WARNING ("Invalid signature on /deposit request\n");
|
||||||
return TEH_RESPONSE_reply_signature_invalid (connection,
|
return TEH_RESPONSE_reply_signature_invalid (connection,
|
||||||
|
TALER_EC_DEPOSIT_COIN_SIGNATURE_INVALID,
|
||||||
"coin_sig");
|
"coin_sig");
|
||||||
}
|
}
|
||||||
/* check denomination exists and is valid */
|
|
||||||
key_state = TEH_KS_acquire ();
|
|
||||||
dki = TEH_KS_denomination_key_lookup (key_state,
|
|
||||||
&deposit->coin.denom_pub,
|
|
||||||
TEH_KS_DKU_DEPOSIT);
|
|
||||||
if (NULL == dki)
|
|
||||||
{
|
|
||||||
TEH_KS_release (key_state);
|
|
||||||
TALER_LOG_WARNING ("Unknown denomination key in /deposit request\n");
|
|
||||||
return TEH_RESPONSE_reply_arg_unknown (connection,
|
|
||||||
"denom_pub");
|
|
||||||
}
|
|
||||||
/* check coin signature */
|
|
||||||
if (GNUNET_YES !=
|
|
||||||
TALER_test_coin_valid (&deposit->coin))
|
|
||||||
{
|
|
||||||
TALER_LOG_WARNING ("Invalid coin passed for /deposit\n");
|
|
||||||
TEH_KS_release (key_state);
|
|
||||||
return TEH_RESPONSE_reply_signature_invalid (connection,
|
|
||||||
"ub_sig");
|
|
||||||
}
|
|
||||||
TALER_amount_ntoh (&fee_deposit,
|
|
||||||
&dki->issue.properties.fee_deposit);
|
|
||||||
if (0 < TALER_amount_cmp (&fee_deposit,
|
|
||||||
&deposit->amount_with_fee))
|
|
||||||
{
|
|
||||||
TEH_KS_release (key_state);
|
|
||||||
return TEH_RESPONSE_reply_external_error (connection,
|
|
||||||
"deposited amount smaller than depositing fee");
|
|
||||||
}
|
|
||||||
TEH_KS_release (key_state);
|
|
||||||
|
|
||||||
return TEH_DB_execute_deposit (connection,
|
return TEH_DB_execute_deposit (connection,
|
||||||
deposit);
|
deposit);
|
||||||
@ -141,12 +108,11 @@ TEH_DEPOSIT_handler_deposit (struct TEH_RequestHandler *rh,
|
|||||||
json_t *wire;
|
json_t *wire;
|
||||||
struct TALER_EXCHANGEDB_Deposit deposit;
|
struct TALER_EXCHANGEDB_Deposit deposit;
|
||||||
struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki;
|
struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki;
|
||||||
struct TEH_KS_StateHandle *ks;
|
struct TEH_KS_StateHandle *key_state;
|
||||||
struct GNUNET_HashCode my_h_wire;
|
struct GNUNET_HashCode my_h_wire;
|
||||||
struct TALER_Amount amount;
|
|
||||||
struct GNUNET_JSON_Specification spec[] = {
|
struct GNUNET_JSON_Specification spec[] = {
|
||||||
GNUNET_JSON_spec_json ("wire", &wire),
|
GNUNET_JSON_spec_json ("wire", &wire),
|
||||||
TALER_JSON_spec_amount ("f", &amount),
|
TALER_JSON_spec_amount ("f", &deposit.amount_with_fee),
|
||||||
TALER_JSON_spec_denomination_public_key ("denom_pub", &deposit.coin.denom_pub),
|
TALER_JSON_spec_denomination_public_key ("denom_pub", &deposit.coin.denom_pub),
|
||||||
TALER_JSON_spec_denomination_signature ("ub_sig", &deposit.coin.denom_sig),
|
TALER_JSON_spec_denomination_signature ("ub_sig", &deposit.coin.denom_sig),
|
||||||
GNUNET_JSON_spec_fixed_auto ("coin_pub", &deposit.coin.coin_pub),
|
GNUNET_JSON_spec_fixed_auto ("coin_pub", &deposit.coin.coin_pub),
|
||||||
@ -180,11 +146,13 @@ TEH_DEPOSIT_handler_deposit (struct TEH_RequestHandler *rh,
|
|||||||
if (GNUNET_NO == res)
|
if (GNUNET_NO == res)
|
||||||
return MHD_YES; /* failure */
|
return MHD_YES; /* failure */
|
||||||
|
|
||||||
|
deposit.receiver_wire_account = wire;
|
||||||
if (deposit.refund_deadline.abs_value_us > deposit.wire_deadline.abs_value_us)
|
if (deposit.refund_deadline.abs_value_us > deposit.wire_deadline.abs_value_us)
|
||||||
{
|
{
|
||||||
GNUNET_break_op (0);
|
GNUNET_break_op (0);
|
||||||
GNUNET_JSON_parse_free (spec);
|
GNUNET_JSON_parse_free (spec);
|
||||||
return TEH_RESPONSE_reply_arg_invalid (connection,
|
return TEH_RESPONSE_reply_arg_invalid (connection,
|
||||||
|
TALER_EC_DEPOSIT_REFUND_DEADLINE_AFTER_WIRE_DEADLINE,
|
||||||
"refund_deadline");
|
"refund_deadline");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,6 +162,7 @@ TEH_DEPOSIT_handler_deposit (struct TEH_RequestHandler *rh,
|
|||||||
{
|
{
|
||||||
GNUNET_JSON_parse_free (spec);
|
GNUNET_JSON_parse_free (spec);
|
||||||
return TEH_RESPONSE_reply_arg_unknown (connection,
|
return TEH_RESPONSE_reply_arg_unknown (connection,
|
||||||
|
TALER_EC_DEPOSIT_INVALID_WIRE_FORMAT,
|
||||||
"wire");
|
"wire");
|
||||||
}
|
}
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
@ -203,6 +172,7 @@ TEH_DEPOSIT_handler_deposit (struct TEH_RequestHandler *rh,
|
|||||||
TALER_LOG_WARNING ("Failed to parse JSON wire format specification for /deposit request\n");
|
TALER_LOG_WARNING ("Failed to parse JSON wire format specification for /deposit request\n");
|
||||||
GNUNET_JSON_parse_free (spec);
|
GNUNET_JSON_parse_free (spec);
|
||||||
return TEH_RESPONSE_reply_arg_invalid (connection,
|
return TEH_RESPONSE_reply_arg_invalid (connection,
|
||||||
|
TALER_EC_DEPOSIT_INVALID_WIRE_FORMAT_JSON,
|
||||||
"wire");
|
"wire");
|
||||||
}
|
}
|
||||||
if (0 != memcmp (&deposit.h_wire,
|
if (0 != memcmp (&deposit.h_wire,
|
||||||
@ -212,32 +182,48 @@ TEH_DEPOSIT_handler_deposit (struct TEH_RequestHandler *rh,
|
|||||||
/* Client hashed contract differently than we did, reject */
|
/* Client hashed contract differently than we did, reject */
|
||||||
GNUNET_JSON_parse_free (spec);
|
GNUNET_JSON_parse_free (spec);
|
||||||
return TEH_RESPONSE_reply_arg_invalid (connection,
|
return TEH_RESPONSE_reply_arg_invalid (connection,
|
||||||
|
TALER_EC_DEPOSIT_INVALID_WIRE_FORMAT_CONTRACT_HASH_CONFLICT,
|
||||||
"H_wire");
|
"H_wire");
|
||||||
}
|
}
|
||||||
ks = TEH_KS_acquire ();
|
|
||||||
dki = TEH_KS_denomination_key_lookup (ks,
|
/* check denomination exists and is valid */
|
||||||
|
key_state = TEH_KS_acquire ();
|
||||||
|
dki = TEH_KS_denomination_key_lookup (key_state,
|
||||||
&deposit.coin.denom_pub,
|
&deposit.coin.denom_pub,
|
||||||
TEH_KS_DKU_DEPOSIT);
|
TEH_KS_DKU_DEPOSIT);
|
||||||
if (NULL == dki)
|
if (NULL == dki)
|
||||||
{
|
{
|
||||||
TEH_KS_release (ks);
|
TEH_KS_release (key_state);
|
||||||
GNUNET_JSON_parse_free (spec);
|
TALER_LOG_WARNING ("Unknown denomination key in /deposit request\n");
|
||||||
return TEH_RESPONSE_reply_arg_unknown (connection,
|
return TEH_RESPONSE_reply_arg_unknown (connection,
|
||||||
|
TALER_EC_DEPOSIT_DENOMINATION_KEY_UNKNOWN,
|
||||||
"denom_pub");
|
"denom_pub");
|
||||||
}
|
}
|
||||||
TALER_amount_ntoh (&deposit.deposit_fee,
|
TALER_amount_ntoh (&deposit.deposit_fee,
|
||||||
&dki->issue.properties.fee_deposit);
|
&dki->issue.properties.fee_deposit);
|
||||||
TEH_KS_release (ks);
|
/* check coin signature */
|
||||||
deposit.receiver_wire_account = wire;
|
if (GNUNET_YES !=
|
||||||
deposit.amount_with_fee = amount;
|
TALER_test_coin_valid (&deposit.coin))
|
||||||
if (-1 == TALER_amount_cmp (&deposit.amount_with_fee,
|
|
||||||
&deposit.deposit_fee))
|
|
||||||
{
|
{
|
||||||
/* Total amount smaller than fee, invalid */
|
TALER_LOG_WARNING ("Invalid coin passed for /deposit\n");
|
||||||
GNUNET_JSON_parse_free (spec);
|
TEH_KS_release (key_state);
|
||||||
return TEH_RESPONSE_reply_arg_invalid (connection,
|
return TEH_RESPONSE_reply_signature_invalid (connection,
|
||||||
"f");
|
TALER_EC_DEPOSIT_DENOMINATION_SIGNATURE_INVALID,
|
||||||
|
"ub_sig");
|
||||||
}
|
}
|
||||||
|
TALER_amount_ntoh (&deposit.deposit_fee,
|
||||||
|
&dki->issue.properties.fee_deposit);
|
||||||
|
TEH_KS_release (key_state);
|
||||||
|
|
||||||
|
if (0 < TALER_amount_cmp (&deposit.deposit_fee,
|
||||||
|
&deposit.amount_with_fee))
|
||||||
|
{
|
||||||
|
GNUNET_break_op (0);
|
||||||
|
return TEH_RESPONSE_reply_external_error (connection,
|
||||||
|
TALER_EC_DEPOSIT_NEGATIVE_VALUE_AFTER_FEE,
|
||||||
|
"deposited amount smaller than depositing fee");
|
||||||
|
}
|
||||||
|
|
||||||
res = verify_and_execute_deposit (connection,
|
res = verify_and_execute_deposit (connection,
|
||||||
&deposit);
|
&deposit);
|
||||||
GNUNET_JSON_parse_free (spec);
|
GNUNET_JSON_parse_free (spec);
|
||||||
|
@ -79,6 +79,7 @@ TEH_PARSE_post_json (struct MHD_Connection *connection,
|
|||||||
case GNUNET_JSON_PR_OUT_OF_MEMORY:
|
case GNUNET_JSON_PR_OUT_OF_MEMORY:
|
||||||
return (MHD_NO ==
|
return (MHD_NO ==
|
||||||
TEH_RESPONSE_reply_internal_error (connection,
|
TEH_RESPONSE_reply_internal_error (connection,
|
||||||
|
TALER_EC_PARSER_OUT_OF_MEMORY,
|
||||||
"out of memory"))
|
"out of memory"))
|
||||||
? GNUNET_SYSERR : GNUNET_NO;
|
? GNUNET_SYSERR : GNUNET_NO;
|
||||||
case GNUNET_JSON_PR_CONTINUE:
|
case GNUNET_JSON_PR_CONTINUE:
|
||||||
@ -144,7 +145,9 @@ TEH_PARSE_mhd_request_arg_data (struct MHD_Connection *connection,
|
|||||||
if (NULL == str)
|
if (NULL == str)
|
||||||
{
|
{
|
||||||
return (MHD_NO ==
|
return (MHD_NO ==
|
||||||
TEH_RESPONSE_reply_arg_missing (connection, param_name))
|
TEH_RESPONSE_reply_arg_missing (connection,
|
||||||
|
TALER_EC_PARAMETER_MISSING,
|
||||||
|
param_name))
|
||||||
? GNUNET_SYSERR : GNUNET_NO;
|
? GNUNET_SYSERR : GNUNET_NO;
|
||||||
}
|
}
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
@ -153,7 +156,9 @@ TEH_PARSE_mhd_request_arg_data (struct MHD_Connection *connection,
|
|||||||
out_data,
|
out_data,
|
||||||
out_size))
|
out_size))
|
||||||
return (MHD_NO ==
|
return (MHD_NO ==
|
||||||
TEH_RESPONSE_reply_arg_invalid (connection, param_name))
|
TEH_RESPONSE_reply_arg_invalid (connection,
|
||||||
|
TALER_EC_PARAMETER_MALFORMED,
|
||||||
|
param_name))
|
||||||
? GNUNET_SYSERR : GNUNET_NO;
|
? GNUNET_SYSERR : GNUNET_NO;
|
||||||
return GNUNET_OK;
|
return GNUNET_OK;
|
||||||
}
|
}
|
||||||
@ -193,8 +198,9 @@ TEH_PARSE_json_data (struct MHD_Connection *connection,
|
|||||||
ret = (MHD_YES ==
|
ret = (MHD_YES ==
|
||||||
TEH_RESPONSE_reply_json_pack (connection,
|
TEH_RESPONSE_reply_json_pack (connection,
|
||||||
MHD_HTTP_BAD_REQUEST,
|
MHD_HTTP_BAD_REQUEST,
|
||||||
"{s:s, s:s, s:I}",
|
"{s:s, s:I, s:s, s:I}",
|
||||||
"error", "parse error",
|
"error", "parse error",
|
||||||
|
"code", (json_int_t) TALER_EC_JSON_INVALID_WITH_DETAILS,
|
||||||
"field", error_json_name,
|
"field", error_json_name,
|
||||||
"line", (json_int_t) error_line))
|
"line", (json_int_t) error_line))
|
||||||
? GNUNET_NO : GNUNET_SYSERR;
|
? GNUNET_NO : GNUNET_SYSERR;
|
||||||
|
@ -69,7 +69,7 @@ handle_refresh_melt_binary (struct MHD_Connection *connection,
|
|||||||
struct TALER_Amount total_melt;
|
struct TALER_Amount total_melt;
|
||||||
|
|
||||||
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
|
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
|
||||||
"melt request for session %s\n",
|
"/refresh/melt request for session %s\n",
|
||||||
GNUNET_h2s (session_hash));
|
GNUNET_h2s (session_hash));
|
||||||
|
|
||||||
GNUNET_assert (GNUNET_OK ==
|
GNUNET_assert (GNUNET_OK ==
|
||||||
@ -86,6 +86,7 @@ handle_refresh_melt_binary (struct MHD_Connection *connection,
|
|||||||
GNUNET_break_op (0);
|
GNUNET_break_op (0);
|
||||||
TEH_KS_release (key_state);
|
TEH_KS_release (key_state);
|
||||||
return TEH_RESPONSE_reply_arg_invalid (connection,
|
return TEH_RESPONSE_reply_arg_invalid (connection,
|
||||||
|
TALER_EC_REFRESH_MELT_FRESH_DENOMINATION_KEY_NOT_FOUND,
|
||||||
"new_denoms");
|
"new_denoms");
|
||||||
}
|
}
|
||||||
dki = &dk->issue;
|
dki = &dk->issue;
|
||||||
@ -105,6 +106,7 @@ handle_refresh_melt_binary (struct MHD_Connection *connection,
|
|||||||
GNUNET_break_op (0);
|
GNUNET_break_op (0);
|
||||||
TEH_KS_release (key_state);
|
TEH_KS_release (key_state);
|
||||||
return TEH_RESPONSE_reply_internal_error (connection,
|
return TEH_RESPONSE_reply_internal_error (connection,
|
||||||
|
TALER_EC_REFRESH_MELT_COST_CALCULATION_OVERFLOW,
|
||||||
"cost calculation failure");
|
"cost calculation failure");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -115,8 +117,9 @@ handle_refresh_melt_binary (struct MHD_Connection *connection,
|
|||||||
if (NULL == dk)
|
if (NULL == dk)
|
||||||
{
|
{
|
||||||
GNUNET_break (0);
|
GNUNET_break (0);
|
||||||
return TEH_RESPONSE_reply_arg_invalid (connection,
|
return TEH_RESPONSE_reply_arg_unknown (connection,
|
||||||
"denom_pub");
|
TALER_EC_REFRESH_MELT_DENOMINATION_KEY_NOT_FOUND,
|
||||||
|
"denom_pub");
|
||||||
}
|
}
|
||||||
dki = &dk->issue;
|
dki = &dk->issue;
|
||||||
TALER_amount_ntoh (&fee_melt,
|
TALER_amount_ntoh (&fee_melt,
|
||||||
@ -129,6 +132,7 @@ handle_refresh_melt_binary (struct MHD_Connection *connection,
|
|||||||
GNUNET_break_op (0);
|
GNUNET_break_op (0);
|
||||||
TEH_KS_release (key_state);
|
TEH_KS_release (key_state);
|
||||||
return TEH_RESPONSE_reply_external_error (connection,
|
return TEH_RESPONSE_reply_external_error (connection,
|
||||||
|
TALER_EC_REFRESH_MELT_FEES_EXCEED_CONTRIBUTION,
|
||||||
"Melt contribution below melting fee");
|
"Melt contribution below melting fee");
|
||||||
}
|
}
|
||||||
TEH_KS_release (key_state);
|
TEH_KS_release (key_state);
|
||||||
@ -141,8 +145,9 @@ handle_refresh_melt_binary (struct MHD_Connection *connection,
|
|||||||
total value of coins being generated to match! */
|
total value of coins being generated to match! */
|
||||||
return TEH_RESPONSE_reply_json_pack (connection,
|
return TEH_RESPONSE_reply_json_pack (connection,
|
||||||
MHD_HTTP_BAD_REQUEST,
|
MHD_HTTP_BAD_REQUEST,
|
||||||
"{s:s}",
|
"{s:s, s:I}",
|
||||||
"error", "value mismatch");
|
"error", "value mismatch",
|
||||||
|
"code", (json_int_t) TALER_EC_REFRESH_MELT_FEES_MISSMATCH);
|
||||||
}
|
}
|
||||||
return TEH_DB_execute_refresh_melt (connection,
|
return TEH_DB_execute_refresh_melt (connection,
|
||||||
session_hash,
|
session_hash,
|
||||||
@ -203,6 +208,7 @@ get_coin_public_info (struct MHD_Connection *connection,
|
|||||||
r_melt_detail->coin_info.denom_pub.rsa_public_key = NULL;
|
r_melt_detail->coin_info.denom_pub.rsa_public_key = NULL;
|
||||||
return (MHD_YES ==
|
return (MHD_YES ==
|
||||||
TEH_RESPONSE_reply_signature_invalid (connection,
|
TEH_RESPONSE_reply_signature_invalid (connection,
|
||||||
|
TALER_EC_REFRESH_MELT_DENOMINATION_SIGNATURE_INVALID,
|
||||||
"denom_sig"))
|
"denom_sig"))
|
||||||
? GNUNET_NO : GNUNET_SYSERR;
|
? GNUNET_NO : GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
@ -237,6 +243,8 @@ verify_coin_public_info (struct MHD_Connection *connection,
|
|||||||
struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki;
|
struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki;
|
||||||
struct TALER_Amount fee_refresh;
|
struct TALER_Amount fee_refresh;
|
||||||
|
|
||||||
|
/* FIXME: we lookup the dki twice during /refresh/melt.
|
||||||
|
This should be avoided. */
|
||||||
key_state = TEH_KS_acquire ();
|
key_state = TEH_KS_acquire ();
|
||||||
dki = TEH_KS_denomination_key_lookup (key_state,
|
dki = TEH_KS_denomination_key_lookup (key_state,
|
||||||
&melt_detail->coin_info.denom_pub,
|
&melt_detail->coin_info.denom_pub,
|
||||||
@ -246,6 +254,7 @@ verify_coin_public_info (struct MHD_Connection *connection,
|
|||||||
TEH_KS_release (key_state);
|
TEH_KS_release (key_state);
|
||||||
TALER_LOG_WARNING ("Unknown denomination key in /refresh/melt request\n");
|
TALER_LOG_WARNING ("Unknown denomination key in /refresh/melt request\n");
|
||||||
return TEH_RESPONSE_reply_arg_unknown (connection,
|
return TEH_RESPONSE_reply_arg_unknown (connection,
|
||||||
|
TALER_EC_REFRESH_MELT_DENOMINATION_KEY_NOT_FOUND,
|
||||||
"denom_pub");
|
"denom_pub");
|
||||||
}
|
}
|
||||||
TALER_amount_ntoh (&fee_refresh,
|
TALER_amount_ntoh (&fee_refresh,
|
||||||
@ -266,6 +275,7 @@ verify_coin_public_info (struct MHD_Connection *connection,
|
|||||||
TEH_KS_release (key_state);
|
TEH_KS_release (key_state);
|
||||||
return (MHD_YES ==
|
return (MHD_YES ==
|
||||||
TEH_RESPONSE_reply_external_error (connection,
|
TEH_RESPONSE_reply_external_error (connection,
|
||||||
|
TALER_EC_REFRESH_MELT_AMOUNT_INSUFFICIENT,
|
||||||
"melt amount smaller than melting fee"))
|
"melt amount smaller than melting fee"))
|
||||||
? GNUNET_NO : GNUNET_SYSERR;
|
? GNUNET_NO : GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
@ -280,6 +290,7 @@ verify_coin_public_info (struct MHD_Connection *connection,
|
|||||||
GNUNET_break_op (0);
|
GNUNET_break_op (0);
|
||||||
if (MHD_YES !=
|
if (MHD_YES !=
|
||||||
TEH_RESPONSE_reply_signature_invalid (connection,
|
TEH_RESPONSE_reply_signature_invalid (connection,
|
||||||
|
TALER_EC_REFRESH_MELT_COIN_SIGNATURE_INVALID,
|
||||||
"confirm_sig"))
|
"confirm_sig"))
|
||||||
return GNUNET_SYSERR;
|
return GNUNET_SYSERR;
|
||||||
return GNUNET_NO;
|
return GNUNET_NO;
|
||||||
@ -565,6 +576,7 @@ TEH_REFRESH_handler_refresh_melt (struct TEH_RequestHandler *rh,
|
|||||||
GNUNET_break_op (0);
|
GNUNET_break_op (0);
|
||||||
GNUNET_JSON_parse_free (spec);
|
GNUNET_JSON_parse_free (spec);
|
||||||
return TEH_RESPONSE_reply_arg_invalid (connection,
|
return TEH_RESPONSE_reply_arg_invalid (connection,
|
||||||
|
TALER_EC_REFRESH_MELT_CNC_COIN_ARRAY_SIZE_INVALID,
|
||||||
"coin_evs");
|
"coin_evs");
|
||||||
}
|
}
|
||||||
if (TALER_CNC_KAPPA != json_array_size (transfer_pubs))
|
if (TALER_CNC_KAPPA != json_array_size (transfer_pubs))
|
||||||
@ -572,6 +584,7 @@ TEH_REFRESH_handler_refresh_melt (struct TEH_RequestHandler *rh,
|
|||||||
GNUNET_break_op (0);
|
GNUNET_break_op (0);
|
||||||
GNUNET_JSON_parse_free (spec);
|
GNUNET_JSON_parse_free (spec);
|
||||||
return TEH_RESPONSE_reply_arg_invalid (connection,
|
return TEH_RESPONSE_reply_arg_invalid (connection,
|
||||||
|
TALER_EC_REFRESH_MELT_CNC_TRANSFER_ARRAY_SIZE_INVALID,
|
||||||
"transfer_pubs");
|
"transfer_pubs");
|
||||||
}
|
}
|
||||||
res = handle_refresh_melt_json (connection,
|
res = handle_refresh_melt_json (connection,
|
||||||
@ -694,6 +707,7 @@ TEH_REFRESH_handler_refresh_reveal (struct TEH_RequestHandler *rh,
|
|||||||
GNUNET_JSON_parse_free (spec);
|
GNUNET_JSON_parse_free (spec);
|
||||||
GNUNET_break_op (0);
|
GNUNET_break_op (0);
|
||||||
return TEH_RESPONSE_reply_arg_invalid (connection,
|
return TEH_RESPONSE_reply_arg_invalid (connection,
|
||||||
|
TALER_EC_REFRESH_REVEAL_CNC_TRANSFER_ARRAY_SIZE_INVALID,
|
||||||
"transfer_privs");
|
"transfer_privs");
|
||||||
}
|
}
|
||||||
res = handle_refresh_reveal_json (connection,
|
res = handle_refresh_reveal_json (connection,
|
||||||
|
@ -69,14 +69,16 @@ verify_and_execute_refund (struct MHD_Connection *connection,
|
|||||||
{
|
{
|
||||||
GNUNET_break_op (0);
|
GNUNET_break_op (0);
|
||||||
return TEH_RESPONSE_reply_arg_invalid (connection,
|
return TEH_RESPONSE_reply_arg_invalid (connection,
|
||||||
|
TALER_EC_REFUND_FEE_CURRENCY_MISSMATCH,
|
||||||
"refund_fee");
|
"refund_fee");
|
||||||
}
|
}
|
||||||
if (-1 == TALER_amount_cmp (&refund->refund_amount,
|
if (-1 == TALER_amount_cmp (&refund->refund_amount,
|
||||||
&refund->refund_fee) )
|
&refund->refund_fee) )
|
||||||
{
|
{
|
||||||
GNUNET_break_op (0);
|
GNUNET_break_op (0);
|
||||||
return TEH_RESPONSE_reply_signature_invalid (connection,
|
return TEH_RESPONSE_reply_arg_invalid (connection,
|
||||||
"refund_amount");
|
TALER_EC_REFUND_FEE_ABOVE_AMOUNT,
|
||||||
|
"refund_amount");
|
||||||
}
|
}
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MERCHANT_REFUND,
|
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MERCHANT_REFUND,
|
||||||
@ -86,6 +88,7 @@ verify_and_execute_refund (struct MHD_Connection *connection,
|
|||||||
{
|
{
|
||||||
TALER_LOG_WARNING ("Invalid signature on /refund request\n");
|
TALER_LOG_WARNING ("Invalid signature on /refund request\n");
|
||||||
return TEH_RESPONSE_reply_signature_invalid (connection,
|
return TEH_RESPONSE_reply_signature_invalid (connection,
|
||||||
|
TALER_EC_REFUND_MERCHANT_SIGNATURE_INVALID,
|
||||||
"merchant_sig");
|
"merchant_sig");
|
||||||
}
|
}
|
||||||
return TEH_DB_execute_refund (connection,
|
return TEH_DB_execute_refund (connection,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
This file is part of TALER
|
This file is part of TALER
|
||||||
Copyright (C) 2014,2015 GNUnet e.V.
|
Copyright (C) 2014, 2015, 2016 GNUnet e.V.
|
||||||
|
|
||||||
TALER is free software; you can redistribute it and/or modify it under the
|
TALER is free software; you can redistribute it and/or modify it under the
|
||||||
terms of the GNU Affero General Public License as published by the Free Software
|
terms of the GNU Affero General Public License as published by the Free Software
|
||||||
@ -138,6 +138,7 @@ TEH_RESERVE_handler_reserve_withdraw (struct TEH_RequestHandler *rh,
|
|||||||
GNUNET_JSON_parse_free (spec);
|
GNUNET_JSON_parse_free (spec);
|
||||||
TEH_KS_release (ks);
|
TEH_KS_release (ks);
|
||||||
return TEH_RESPONSE_reply_arg_unknown (connection,
|
return TEH_RESPONSE_reply_arg_unknown (connection,
|
||||||
|
TALER_EC_WITHDRAW_DENOMINATION_KEY_NOT_FOUND,
|
||||||
"denom_pub");
|
"denom_pub");
|
||||||
}
|
}
|
||||||
TALER_amount_ntoh (&amount,
|
TALER_amount_ntoh (&amount,
|
||||||
@ -171,6 +172,7 @@ TEH_RESERVE_handler_reserve_withdraw (struct TEH_RequestHandler *rh,
|
|||||||
TALER_LOG_WARNING ("Client supplied invalid signature for /reserve/withdraw request\n");
|
TALER_LOG_WARNING ("Client supplied invalid signature for /reserve/withdraw request\n");
|
||||||
GNUNET_JSON_parse_free (spec);
|
GNUNET_JSON_parse_free (spec);
|
||||||
return TEH_RESPONSE_reply_signature_invalid (connection,
|
return TEH_RESPONSE_reply_signature_invalid (connection,
|
||||||
|
TALER_EC_WITHDRAW_RESERVE_SIGNATURE_INVALID,
|
||||||
"reserve_sig");
|
"reserve_sig");
|
||||||
}
|
}
|
||||||
res = TEH_DB_execute_reserve_withdraw (connection,
|
res = TEH_DB_execute_reserve_withdraw (connection,
|
||||||
|
@ -132,17 +132,20 @@ TEH_RESPONSE_reply_json_pack (struct MHD_Connection *connection,
|
|||||||
* Send a response indicating an invalid argument.
|
* Send a response indicating an invalid argument.
|
||||||
*
|
*
|
||||||
* @param connection the MHD connection to use
|
* @param connection the MHD connection to use
|
||||||
|
* @param ec error code uniquely identifying the error
|
||||||
* @param param_name the parameter that is invalid
|
* @param param_name the parameter that is invalid
|
||||||
* @return a MHD result code
|
* @return a MHD result code
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
TEH_RESPONSE_reply_arg_invalid (struct MHD_Connection *connection,
|
TEH_RESPONSE_reply_arg_invalid (struct MHD_Connection *connection,
|
||||||
|
enum TALER_ErrorCode ec,
|
||||||
const char *param_name)
|
const char *param_name)
|
||||||
{
|
{
|
||||||
return TEH_RESPONSE_reply_json_pack (connection,
|
return TEH_RESPONSE_reply_json_pack (connection,
|
||||||
MHD_HTTP_BAD_REQUEST,
|
MHD_HTTP_BAD_REQUEST,
|
||||||
"{s:s, s:s}",
|
"{s:s, s:I, s:s}",
|
||||||
"error", "invalid parameter",
|
"error", "invalid parameter",
|
||||||
|
"code", (json_int_t) ec,
|
||||||
"parameter", param_name);
|
"parameter", param_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,17 +156,20 @@ TEH_RESPONSE_reply_arg_invalid (struct MHD_Connection *connection,
|
|||||||
* denomination key).
|
* denomination key).
|
||||||
*
|
*
|
||||||
* @param connection the MHD connection to use
|
* @param connection the MHD connection to use
|
||||||
|
* @param ec error code uniquely identifying the error
|
||||||
* @param param_name the parameter that is invalid
|
* @param param_name the parameter that is invalid
|
||||||
* @return a MHD result code
|
* @return a MHD result code
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
TEH_RESPONSE_reply_arg_unknown (struct MHD_Connection *connection,
|
TEH_RESPONSE_reply_arg_unknown (struct MHD_Connection *connection,
|
||||||
|
enum TALER_ErrorCode ec,
|
||||||
const char *param_name)
|
const char *param_name)
|
||||||
{
|
{
|
||||||
return TEH_RESPONSE_reply_json_pack (connection,
|
return TEH_RESPONSE_reply_json_pack (connection,
|
||||||
MHD_HTTP_NOT_FOUND,
|
MHD_HTTP_NOT_FOUND,
|
||||||
"{s:s, s:s}",
|
"{s:s, s:I, s:s}",
|
||||||
"error", "unknown entity referenced",
|
"error", "unknown entity referenced",
|
||||||
|
"code", (json_int_t) ec,
|
||||||
"parameter", param_name);
|
"parameter", param_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,17 +178,20 @@ TEH_RESPONSE_reply_arg_unknown (struct MHD_Connection *connection,
|
|||||||
* Send a response indicating an invalid signature.
|
* Send a response indicating an invalid signature.
|
||||||
*
|
*
|
||||||
* @param connection the MHD connection to use
|
* @param connection the MHD connection to use
|
||||||
|
* @param ec error code uniquely identifying the error
|
||||||
* @param param_name the parameter that is invalid
|
* @param param_name the parameter that is invalid
|
||||||
* @return a MHD result code
|
* @return a MHD result code
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
TEH_RESPONSE_reply_signature_invalid (struct MHD_Connection *connection,
|
TEH_RESPONSE_reply_signature_invalid (struct MHD_Connection *connection,
|
||||||
|
enum TALER_ErrorCode ec,
|
||||||
const char *param_name)
|
const char *param_name)
|
||||||
{
|
{
|
||||||
return TEH_RESPONSE_reply_json_pack (connection,
|
return TEH_RESPONSE_reply_json_pack (connection,
|
||||||
MHD_HTTP_UNAUTHORIZED,
|
MHD_HTTP_UNAUTHORIZED,
|
||||||
"{s:s, s:s}",
|
"{s:s, s:I, s:s}",
|
||||||
"error", "invalid signature",
|
"error", "invalid signature",
|
||||||
|
"code", (json_int_t) ec,
|
||||||
"parameter", param_name);
|
"parameter", param_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -191,17 +200,20 @@ TEH_RESPONSE_reply_signature_invalid (struct MHD_Connection *connection,
|
|||||||
* Send a response indicating a missing argument.
|
* Send a response indicating a missing argument.
|
||||||
*
|
*
|
||||||
* @param connection the MHD connection to use
|
* @param connection the MHD connection to use
|
||||||
|
* @param ec error code uniquely identifying the error
|
||||||
* @param param_name the parameter that is missing
|
* @param param_name the parameter that is missing
|
||||||
* @return a MHD result code
|
* @return a MHD result code
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
TEH_RESPONSE_reply_arg_missing (struct MHD_Connection *connection,
|
TEH_RESPONSE_reply_arg_missing (struct MHD_Connection *connection,
|
||||||
|
enum TALER_ErrorCode ec,
|
||||||
const char *param_name)
|
const char *param_name)
|
||||||
{
|
{
|
||||||
return TEH_RESPONSE_reply_json_pack (connection,
|
return TEH_RESPONSE_reply_json_pack (connection,
|
||||||
MHD_HTTP_BAD_REQUEST,
|
MHD_HTTP_BAD_REQUEST,
|
||||||
"{ s:s, s:s}",
|
"{ s:s, s:I, s:s}",
|
||||||
"error", "missing parameter",
|
"error", "missing parameter",
|
||||||
|
"code", (json_int_t) ec,
|
||||||
"parameter", param_name);
|
"parameter", param_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -210,17 +222,20 @@ TEH_RESPONSE_reply_arg_missing (struct MHD_Connection *connection,
|
|||||||
* Send a response indicating permission denied.
|
* Send a response indicating permission denied.
|
||||||
*
|
*
|
||||||
* @param connection the MHD connection to use
|
* @param connection the MHD connection to use
|
||||||
|
* @param ec error code uniquely identifying the error
|
||||||
* @param hint hint about why access was denied
|
* @param hint hint about why access was denied
|
||||||
* @return a MHD result code
|
* @return a MHD result code
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
TEH_RESPONSE_reply_permission_denied (struct MHD_Connection *connection,
|
TEH_RESPONSE_reply_permission_denied (struct MHD_Connection *connection,
|
||||||
|
enum TALER_ErrorCode ec,
|
||||||
const char *hint)
|
const char *hint)
|
||||||
{
|
{
|
||||||
return TEH_RESPONSE_reply_json_pack (connection,
|
return TEH_RESPONSE_reply_json_pack (connection,
|
||||||
MHD_HTTP_FORBIDDEN,
|
MHD_HTTP_FORBIDDEN,
|
||||||
"{s:s, s:s}",
|
"{s:s, s:I, s:s}",
|
||||||
"error", "permission denied",
|
"error", "permission denied",
|
||||||
|
"code", (json_int_t) ec,
|
||||||
"hint", hint);
|
"hint", hint);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -229,17 +244,20 @@ TEH_RESPONSE_reply_permission_denied (struct MHD_Connection *connection,
|
|||||||
* Send a response indicating an internal error.
|
* Send a response indicating an internal error.
|
||||||
*
|
*
|
||||||
* @param connection the MHD connection to use
|
* @param connection the MHD connection to use
|
||||||
|
* @param ec error code uniquely identifying the error
|
||||||
* @param hint hint about the internal error's nature
|
* @param hint hint about the internal error's nature
|
||||||
* @return a MHD result code
|
* @return a MHD result code
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
TEH_RESPONSE_reply_internal_error (struct MHD_Connection *connection,
|
TEH_RESPONSE_reply_internal_error (struct MHD_Connection *connection,
|
||||||
|
enum TALER_ErrorCode ec,
|
||||||
const char *hint)
|
const char *hint)
|
||||||
{
|
{
|
||||||
return TEH_RESPONSE_reply_json_pack (connection,
|
return TEH_RESPONSE_reply_json_pack (connection,
|
||||||
MHD_HTTP_INTERNAL_SERVER_ERROR,
|
MHD_HTTP_INTERNAL_SERVER_ERROR,
|
||||||
"{s:s, s:s}",
|
"{s:s, s:I, s:s}",
|
||||||
"error", "internal error",
|
"error", "internal error",
|
||||||
|
"code", (json_int_t) ec,
|
||||||
"hint", hint);
|
"hint", hint);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -248,17 +266,20 @@ TEH_RESPONSE_reply_internal_error (struct MHD_Connection *connection,
|
|||||||
* Send a response indicating an external error.
|
* Send a response indicating an external error.
|
||||||
*
|
*
|
||||||
* @param connection the MHD connection to use
|
* @param connection the MHD connection to use
|
||||||
|
* @param ec error code uniquely identifying the error
|
||||||
* @param hint hint about the error's nature
|
* @param hint hint about the error's nature
|
||||||
* @return a MHD result code
|
* @return a MHD result code
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
TEH_RESPONSE_reply_external_error (struct MHD_Connection *connection,
|
TEH_RESPONSE_reply_external_error (struct MHD_Connection *connection,
|
||||||
|
enum TALER_ErrorCode ec,
|
||||||
const char *hint)
|
const char *hint)
|
||||||
{
|
{
|
||||||
return TEH_RESPONSE_reply_json_pack (connection,
|
return TEH_RESPONSE_reply_json_pack (connection,
|
||||||
MHD_HTTP_BAD_REQUEST,
|
MHD_HTTP_BAD_REQUEST,
|
||||||
"{s:s, s:s}",
|
"{s:s, s:I, s:s}",
|
||||||
"error", "client error",
|
"error", "client error",
|
||||||
|
"code", (json_int_t) ec,
|
||||||
"hint", hint);
|
"hint", hint);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -268,15 +289,18 @@ TEH_RESPONSE_reply_external_error (struct MHD_Connection *connection,
|
|||||||
* transaction (concurrent interference).
|
* transaction (concurrent interference).
|
||||||
*
|
*
|
||||||
* @param connection the MHD connection to use
|
* @param connection the MHD connection to use
|
||||||
|
* @param ec error code uniquely identifying the error
|
||||||
* @return a MHD result code
|
* @return a MHD result code
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
TEH_RESPONSE_reply_commit_error (struct MHD_Connection *connection)
|
TEH_RESPONSE_reply_commit_error (struct MHD_Connection *connection,
|
||||||
|
enum TALER_ErrorCode ec)
|
||||||
{
|
{
|
||||||
return TEH_RESPONSE_reply_json_pack (connection,
|
return TEH_RESPONSE_reply_json_pack (connection,
|
||||||
MHD_HTTP_BAD_REQUEST,
|
MHD_HTTP_BAD_REQUEST,
|
||||||
"{s:s}",
|
"{s:s, s:I}",
|
||||||
"error", "commit failure");
|
"error", "commit failure",
|
||||||
|
"code", (json_int_t) ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -285,12 +309,15 @@ TEH_RESPONSE_reply_commit_error (struct MHD_Connection *connection)
|
|||||||
* database.
|
* database.
|
||||||
*
|
*
|
||||||
* @param connection the MHD connection to use
|
* @param connection the MHD connection to use
|
||||||
|
* @param ec error code uniquely identifying the error
|
||||||
* @return a MHD result code
|
* @return a MHD result code
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
TEH_RESPONSE_reply_internal_db_error (struct MHD_Connection *connection)
|
TEH_RESPONSE_reply_internal_db_error (struct MHD_Connection *connection,
|
||||||
|
enum TALER_ErrorCode ec)
|
||||||
{
|
{
|
||||||
return TEH_RESPONSE_reply_internal_error (connection,
|
return TEH_RESPONSE_reply_internal_error (connection,
|
||||||
|
ec,
|
||||||
"Failed to connect to database");
|
"Failed to connect to database");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -332,9 +359,9 @@ TEH_RESPONSE_reply_invalid_json (struct MHD_Connection *connection)
|
|||||||
{
|
{
|
||||||
return TEH_RESPONSE_reply_json_pack (connection,
|
return TEH_RESPONSE_reply_json_pack (connection,
|
||||||
MHD_HTTP_BAD_REQUEST,
|
MHD_HTTP_BAD_REQUEST,
|
||||||
"{s:s}",
|
"{s:s, s:I}",
|
||||||
"error",
|
"error", "invalid json",
|
||||||
"invalid json");
|
"code", (json_int_t) TALER_EC_JSON_INVALID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -556,11 +583,13 @@ TEH_RESPONSE_reply_deposit_insufficient_funds (struct MHD_Connection *connection
|
|||||||
|
|
||||||
history = compile_transaction_history (tl);
|
history = compile_transaction_history (tl);
|
||||||
if (NULL == history)
|
if (NULL == history)
|
||||||
return TEH_RESPONSE_reply_internal_db_error (connection);
|
return TEH_RESPONSE_reply_internal_db_error (connection,
|
||||||
|
TALER_EC_DEPOSIT_HISTORY_DB_ERROR_INSUFFICIENT_FUNDS);
|
||||||
return TEH_RESPONSE_reply_json_pack (connection,
|
return TEH_RESPONSE_reply_json_pack (connection,
|
||||||
MHD_HTTP_FORBIDDEN,
|
MHD_HTTP_FORBIDDEN,
|
||||||
"{s:s, s:o}",
|
"{s:s, s:I, s:o}",
|
||||||
"error", "insufficient funds",
|
"error", "insufficient funds",
|
||||||
|
"code", (json_int_t) TALER_EC_DEPOSIT_INSUFFICIENT_FUNDS,
|
||||||
"history", history);
|
"history", history);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -696,8 +725,9 @@ TEH_RESPONSE_reply_refund_conflict (struct MHD_Connection *connection,
|
|||||||
{
|
{
|
||||||
return TEH_RESPONSE_reply_json_pack (connection,
|
return TEH_RESPONSE_reply_json_pack (connection,
|
||||||
MHD_HTTP_CONFLICT,
|
MHD_HTTP_CONFLICT,
|
||||||
"{s:s, s:o}",
|
"{s:s, s:I, s:o}",
|
||||||
"status", "conflicting refund",
|
"status", "conflicting refund",
|
||||||
|
"code", (json_int_t) TALER_EC_REFUND_CONFLICT,
|
||||||
"history", compile_transaction_history (tl));
|
"history", compile_transaction_history (tl));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -708,17 +738,19 @@ TEH_RESPONSE_reply_refund_conflict (struct MHD_Connection *connection,
|
|||||||
*
|
*
|
||||||
* @param connection connection to the client
|
* @param connection connection to the client
|
||||||
* @param response_code response code to generate
|
* @param response_code response code to generate
|
||||||
|
* @param ec taler error code to include
|
||||||
* @return MHD result code
|
* @return MHD result code
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
TEH_RESPONSE_reply_refund_failure (struct MHD_Connection *connection,
|
TEH_RESPONSE_reply_refund_failure (struct MHD_Connection *connection,
|
||||||
unsigned int response_code)
|
unsigned int response_code,
|
||||||
|
enum TALER_ErrorCode ec)
|
||||||
{
|
{
|
||||||
return TEH_RESPONSE_reply_json_pack (connection,
|
return TEH_RESPONSE_reply_json_pack (connection,
|
||||||
response_code,
|
response_code,
|
||||||
"{s:s}",
|
"{s:s, s:I}",
|
||||||
"error",
|
"status", "refund failure",
|
||||||
"no details");
|
"code", (json_int_t) ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -779,6 +811,7 @@ TEH_RESPONSE_reply_reserve_status_success (struct MHD_Connection *connection,
|
|||||||
&balance);
|
&balance);
|
||||||
if (NULL == json_history)
|
if (NULL == json_history)
|
||||||
return TEH_RESPONSE_reply_internal_error (connection,
|
return TEH_RESPONSE_reply_internal_error (connection,
|
||||||
|
TALER_EC_RESERVE_STATUS_DB_ERROR,
|
||||||
"balance calculation failure");
|
"balance calculation failure");
|
||||||
json_balance = TALER_JSON_from_amount (&balance);
|
json_balance = TALER_JSON_from_amount (&balance);
|
||||||
return TEH_RESPONSE_reply_json_pack (connection,
|
return TEH_RESPONSE_reply_json_pack (connection,
|
||||||
@ -810,12 +843,14 @@ TEH_RESPONSE_reply_reserve_withdraw_insufficient_funds (struct MHD_Connection *c
|
|||||||
&balance);
|
&balance);
|
||||||
if (NULL == json_history)
|
if (NULL == json_history)
|
||||||
return TEH_RESPONSE_reply_internal_error (connection,
|
return TEH_RESPONSE_reply_internal_error (connection,
|
||||||
|
TALER_EC_WITHDRAW_HISTORY_DB_ERROR_INSUFFICIENT_FUNDS,
|
||||||
"balance calculation failure");
|
"balance calculation failure");
|
||||||
json_balance = TALER_JSON_from_amount (&balance);
|
json_balance = TALER_JSON_from_amount (&balance);
|
||||||
return TEH_RESPONSE_reply_json_pack (connection,
|
return TEH_RESPONSE_reply_json_pack (connection,
|
||||||
MHD_HTTP_PAYMENT_REQUIRED,
|
MHD_HTTP_FORBIDDEN,
|
||||||
"{s:s, s:o, s:o}",
|
"{s:s, s:I, s:o, s:o}",
|
||||||
"error", "Insufficient funds",
|
"error", "Insufficient funds",
|
||||||
|
"code", (json_int_t) TALER_EC_WITHDRAW_INSUFFICIENT_FUNDS,
|
||||||
"balance", json_balance,
|
"balance", json_balance,
|
||||||
"history", json_history);
|
"history", json_history);
|
||||||
}
|
}
|
||||||
@ -830,7 +865,7 @@ TEH_RESPONSE_reply_reserve_withdraw_insufficient_funds (struct MHD_Connection *c
|
|||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
TEH_RESPONSE_reply_reserve_withdraw_success (struct MHD_Connection *connection,
|
TEH_RESPONSE_reply_reserve_withdraw_success (struct MHD_Connection *connection,
|
||||||
const struct TALER_EXCHANGEDB_CollectableBlindcoin *collectable)
|
const struct TALER_EXCHANGEDB_CollectableBlindcoin *collectable)
|
||||||
{
|
{
|
||||||
json_t *sig_json;
|
json_t *sig_json;
|
||||||
|
|
||||||
@ -869,12 +904,15 @@ TEH_RESPONSE_reply_refresh_melt_insufficient_funds (struct MHD_Connection *conne
|
|||||||
|
|
||||||
history = compile_transaction_history (tl);
|
history = compile_transaction_history (tl);
|
||||||
if (NULL == history)
|
if (NULL == history)
|
||||||
return TEH_RESPONSE_reply_internal_db_error (connection);
|
return TEH_RESPONSE_reply_internal_db_error (connection,
|
||||||
|
TALER_EC_REFRESH_MELT_HISTORY_DB_ERROR_INSUFFICIENT_FUNDS);
|
||||||
return TEH_RESPONSE_reply_json_pack (connection,
|
return TEH_RESPONSE_reply_json_pack (connection,
|
||||||
MHD_HTTP_FORBIDDEN,
|
MHD_HTTP_FORBIDDEN,
|
||||||
"{s:s, s:o, s:o, s:o, s:o, s:o}",
|
"{s:s, s:I, s:o, s:o, s:o, s:o, s:o}",
|
||||||
"error",
|
"error",
|
||||||
"insufficient funds",
|
"insufficient funds",
|
||||||
|
"code",
|
||||||
|
(json_int_t) TALER_EC_REFRESH_MELT_INSUFFICIENT_FUNDS,
|
||||||
"coin_pub",
|
"coin_pub",
|
||||||
GNUNET_JSON_from_data_auto (coin_pub),
|
GNUNET_JSON_from_data_auto (coin_pub),
|
||||||
"original_value",
|
"original_value",
|
||||||
@ -1011,8 +1049,9 @@ TEH_RESPONSE_reply_refresh_reveal_missmatch (struct MHD_Connection *connection,
|
|||||||
}
|
}
|
||||||
return TEH_RESPONSE_reply_json_pack (connection,
|
return TEH_RESPONSE_reply_json_pack (connection,
|
||||||
MHD_HTTP_CONFLICT,
|
MHD_HTTP_CONFLICT,
|
||||||
"{s:s, s:o, s:o, s:o, s:o, s:o, s:o, s:o, s:i}",
|
"{s:s, s:I, s:o, s:o, s:o, s:o, s:o, s:o, s:o, s:i}",
|
||||||
"error", "commitment violation",
|
"error", "commitment violation",
|
||||||
|
"code", (json_int_t) TALER_EC_REFRESH_REVEAL_COMMITMENT_VIOLATION,
|
||||||
"coin_sig", GNUNET_JSON_from_data_auto (&session->melt.coin_sig),
|
"coin_sig", GNUNET_JSON_from_data_auto (&session->melt.coin_sig),
|
||||||
"coin_pub", GNUNET_JSON_from_data_auto (&session->melt.coin.coin_pub),
|
"coin_pub", GNUNET_JSON_from_data_auto (&session->melt.coin.coin_pub),
|
||||||
"melt_amount_with_fee", TALER_JSON_from_amount (&session->melt.amount_with_fee),
|
"melt_amount_with_fee", TALER_JSON_from_amount (&session->melt.amount_with_fee),
|
||||||
@ -1089,15 +1128,18 @@ TEH_RESPONSE_reply_refresh_link_success (struct MHD_Connection *connection,
|
|||||||
* 404 reply.
|
* 404 reply.
|
||||||
*
|
*
|
||||||
* @param connection connection to the client
|
* @param connection connection to the client
|
||||||
|
* @param ec Taler error code
|
||||||
* @return MHD result code
|
* @return MHD result code
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
TEH_RESPONSE_reply_transaction_unknown (struct MHD_Connection *connection)
|
TEH_RESPONSE_reply_transaction_unknown (struct MHD_Connection *connection,
|
||||||
|
enum TALER_ErrorCode ec)
|
||||||
{
|
{
|
||||||
return TEH_RESPONSE_reply_json_pack (connection,
|
return TEH_RESPONSE_reply_json_pack (connection,
|
||||||
MHD_HTTP_NOT_FOUND,
|
MHD_HTTP_NOT_FOUND,
|
||||||
"{s:s}",
|
"{s:s, s:I}",
|
||||||
"error", "Deposit unknown");
|
"error", "Deposit unknown",
|
||||||
|
"code", (json_int_t) ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
#include <jansson.h>
|
#include <jansson.h>
|
||||||
#include <microhttpd.h>
|
#include <microhttpd.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
#include "taler_error_codes.h"
|
||||||
#include "taler-exchange-httpd.h"
|
#include "taler-exchange-httpd.h"
|
||||||
#include "taler-exchange-httpd_db.h"
|
#include "taler-exchange-httpd_db.h"
|
||||||
|
|
||||||
@ -78,11 +79,13 @@ TEH_RESPONSE_reply_json_pack (struct MHD_Connection *connection,
|
|||||||
* Send a response indicating an invalid signature.
|
* Send a response indicating an invalid signature.
|
||||||
*
|
*
|
||||||
* @param connection the MHD connection to use
|
* @param connection the MHD connection to use
|
||||||
|
* @param ec error code uniquely identifying the error
|
||||||
* @param param_name the parameter that is invalid
|
* @param param_name the parameter that is invalid
|
||||||
* @return a MHD result code
|
* @return a MHD result code
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
TEH_RESPONSE_reply_signature_invalid (struct MHD_Connection *connection,
|
TEH_RESPONSE_reply_signature_invalid (struct MHD_Connection *connection,
|
||||||
|
enum TALER_ErrorCode ec,
|
||||||
const char *param_name);
|
const char *param_name);
|
||||||
|
|
||||||
|
|
||||||
@ -90,11 +93,13 @@ TEH_RESPONSE_reply_signature_invalid (struct MHD_Connection *connection,
|
|||||||
* Send a response indicating an invalid argument.
|
* Send a response indicating an invalid argument.
|
||||||
*
|
*
|
||||||
* @param connection the MHD connection to use
|
* @param connection the MHD connection to use
|
||||||
|
* @param ec error code uniquely identifying the error
|
||||||
* @param param_name the parameter that is invalid
|
* @param param_name the parameter that is invalid
|
||||||
* @return MHD result code
|
* @return MHD result code
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
TEH_RESPONSE_reply_arg_invalid (struct MHD_Connection *connection,
|
TEH_RESPONSE_reply_arg_invalid (struct MHD_Connection *connection,
|
||||||
|
enum TALER_ErrorCode ec,
|
||||||
const char *param_name);
|
const char *param_name);
|
||||||
|
|
||||||
|
|
||||||
@ -104,11 +109,13 @@ TEH_RESPONSE_reply_arg_invalid (struct MHD_Connection *connection,
|
|||||||
* denomination key).
|
* denomination key).
|
||||||
*
|
*
|
||||||
* @param connection the MHD connection to use
|
* @param connection the MHD connection to use
|
||||||
|
* @param ec error code uniquely identifying the error
|
||||||
* @param param_name the parameter that is invalid
|
* @param param_name the parameter that is invalid
|
||||||
* @return a MHD result code
|
* @return a MHD result code
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
TEH_RESPONSE_reply_arg_unknown (struct MHD_Connection *connection,
|
TEH_RESPONSE_reply_arg_unknown (struct MHD_Connection *connection,
|
||||||
|
enum TALER_ErrorCode ec,
|
||||||
const char *param_name);
|
const char *param_name);
|
||||||
|
|
||||||
|
|
||||||
@ -116,11 +123,13 @@ TEH_RESPONSE_reply_arg_unknown (struct MHD_Connection *connection,
|
|||||||
* Send a response indicating a missing argument.
|
* Send a response indicating a missing argument.
|
||||||
*
|
*
|
||||||
* @param connection the MHD connection to use
|
* @param connection the MHD connection to use
|
||||||
|
* @param ec error code uniquely identifying the error
|
||||||
* @param param_name the parameter that is missing
|
* @param param_name the parameter that is missing
|
||||||
* @return a MHD result code
|
* @return a MHD result code
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
TEH_RESPONSE_reply_arg_missing (struct MHD_Connection *connection,
|
TEH_RESPONSE_reply_arg_missing (struct MHD_Connection *connection,
|
||||||
|
enum TALER_ErrorCode ec,
|
||||||
const char *param_name);
|
const char *param_name);
|
||||||
|
|
||||||
|
|
||||||
@ -128,11 +137,13 @@ TEH_RESPONSE_reply_arg_missing (struct MHD_Connection *connection,
|
|||||||
* Send a response indicating permission denied.
|
* Send a response indicating permission denied.
|
||||||
*
|
*
|
||||||
* @param connection the MHD connection to use
|
* @param connection the MHD connection to use
|
||||||
|
* @param ec error code uniquely identifying the error
|
||||||
* @param hint hint about why access was denied
|
* @param hint hint about why access was denied
|
||||||
* @return a MHD result code
|
* @return a MHD result code
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
TEH_RESPONSE_reply_permission_denied (struct MHD_Connection *connection,
|
TEH_RESPONSE_reply_permission_denied (struct MHD_Connection *connection,
|
||||||
|
enum TALER_ErrorCode ec,
|
||||||
const char *hint);
|
const char *hint);
|
||||||
|
|
||||||
|
|
||||||
@ -140,11 +151,13 @@ TEH_RESPONSE_reply_permission_denied (struct MHD_Connection *connection,
|
|||||||
* Send a response indicating an internal error.
|
* Send a response indicating an internal error.
|
||||||
*
|
*
|
||||||
* @param connection the MHD connection to use
|
* @param connection the MHD connection to use
|
||||||
|
* @param ec error code uniquely identifying the error
|
||||||
* @param hint hint about the internal error's nature
|
* @param hint hint about the internal error's nature
|
||||||
* @return a MHD result code
|
* @return a MHD result code
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
TEH_RESPONSE_reply_internal_error (struct MHD_Connection *connection,
|
TEH_RESPONSE_reply_internal_error (struct MHD_Connection *connection,
|
||||||
|
enum TALER_ErrorCode ec,
|
||||||
const char *hint);
|
const char *hint);
|
||||||
|
|
||||||
|
|
||||||
@ -152,11 +165,13 @@ TEH_RESPONSE_reply_internal_error (struct MHD_Connection *connection,
|
|||||||
* Send a response indicating an external error.
|
* Send a response indicating an external error.
|
||||||
*
|
*
|
||||||
* @param connection the MHD connection to use
|
* @param connection the MHD connection to use
|
||||||
|
* @param ec error code uniquely identifying the error
|
||||||
* @param hint hint about the error's nature
|
* @param hint hint about the error's nature
|
||||||
* @return a MHD result code
|
* @return a MHD result code
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
TEH_RESPONSE_reply_external_error (struct MHD_Connection *connection,
|
TEH_RESPONSE_reply_external_error (struct MHD_Connection *connection,
|
||||||
|
enum TALER_ErrorCode ec,
|
||||||
const char *hint);
|
const char *hint);
|
||||||
|
|
||||||
|
|
||||||
@ -165,21 +180,24 @@ TEH_RESPONSE_reply_external_error (struct MHD_Connection *connection,
|
|||||||
* transaction (concurrent interference).
|
* transaction (concurrent interference).
|
||||||
*
|
*
|
||||||
* @param connection the MHD connection to use
|
* @param connection the MHD connection to use
|
||||||
|
* @param ec error code uniquely identifying the error
|
||||||
* @return a MHD result code
|
* @return a MHD result code
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
TEH_RESPONSE_reply_commit_error (struct MHD_Connection *connection);
|
TEH_RESPONSE_reply_commit_error (struct MHD_Connection *connection,
|
||||||
|
enum TALER_ErrorCode ec);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send a response indicating a failure to talk to the Exchange's
|
* Send a response indicating a failure to talk to the Exchange's
|
||||||
* database.
|
* database.
|
||||||
*
|
*
|
||||||
* @param connection the MHD connection to use
|
* @param connection the MHD connection to use
|
||||||
|
* @param ec error code uniquely identifying the error
|
||||||
* @return a MHD result code
|
* @return a MHD result code
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
TEH_RESPONSE_reply_internal_db_error (struct MHD_Connection *connection);
|
TEH_RESPONSE_reply_internal_db_error (struct MHD_Connection *connection,
|
||||||
|
enum TALER_ErrorCode ec);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -199,7 +217,7 @@ TEH_RESPONSE_reply_request_too_large (struct MHD_Connection *connection);
|
|||||||
* @return a MHD result code
|
* @return a MHD result code
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
TEH_RESPONSE_reply_invalid_json (struct MHD_Connection *connection);
|
TEH_RESPONSE_reply_invalid_json (struct MHD_Connection *connectionx);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -266,11 +284,13 @@ TEH_RESPONSE_reply_refund_conflict (struct MHD_Connection *connection,
|
|||||||
*
|
*
|
||||||
* @param connection connection to the client
|
* @param connection connection to the client
|
||||||
* @param response_code response code to generate
|
* @param response_code response code to generate
|
||||||
|
* @param ec error code uniquely identifying the error
|
||||||
* @return MHD result code
|
* @return MHD result code
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
TEH_RESPONSE_reply_refund_failure (struct MHD_Connection *connection,
|
TEH_RESPONSE_reply_refund_failure (struct MHD_Connection *connection,
|
||||||
unsigned int response_code);
|
unsigned int response_code,
|
||||||
|
enum TALER_ErrorCode ec);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -291,10 +311,12 @@ TEH_RESPONSE_reply_refund_success (struct MHD_Connection *connection,
|
|||||||
* 404 reply.
|
* 404 reply.
|
||||||
*
|
*
|
||||||
* @param connection connection to the client
|
* @param connection connection to the client
|
||||||
|
* @param ec Taler error code
|
||||||
* @return MHD result code
|
* @return MHD result code
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
TEH_RESPONSE_reply_transaction_unknown (struct MHD_Connection *connection);
|
TEH_RESPONSE_reply_transaction_unknown (struct MHD_Connection *connection,
|
||||||
|
enum TALER_ErrorCode ec);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -307,7 +329,7 @@ TEH_RESPONSE_reply_transaction_unknown (struct MHD_Connection *connection);
|
|||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
TEH_RESPONSE_reply_transfer_pending (struct MHD_Connection *connection,
|
TEH_RESPONSE_reply_transfer_pending (struct MHD_Connection *connection,
|
||||||
struct GNUNET_TIME_Absolute planned_exec_time);
|
struct GNUNET_TIME_Absolute planned_exec_time);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -295,6 +295,7 @@ TEH_TEST_handler_test_ecdhe (struct TEH_RequestHandler *rh,
|
|||||||
{
|
{
|
||||||
GNUNET_JSON_parse_free (spec);
|
GNUNET_JSON_parse_free (spec);
|
||||||
return TEH_RESPONSE_reply_internal_error (connection,
|
return TEH_RESPONSE_reply_internal_error (connection,
|
||||||
|
TALER_EC_TEST_ECDH_ERROR,
|
||||||
"Failed to perform ECDH");
|
"Failed to perform ECDH");
|
||||||
}
|
}
|
||||||
GNUNET_JSON_parse_free (spec);
|
GNUNET_JSON_parse_free (spec);
|
||||||
@ -365,6 +366,7 @@ TEH_TEST_handler_test_eddsa (struct TEH_RequestHandler *rh,
|
|||||||
{
|
{
|
||||||
GNUNET_JSON_parse_free (spec);
|
GNUNET_JSON_parse_free (spec);
|
||||||
return TEH_RESPONSE_reply_signature_invalid (connection,
|
return TEH_RESPONSE_reply_signature_invalid (connection,
|
||||||
|
TALER_EC_TEST_EDDSA_INVALID,
|
||||||
"eddsa_sig");
|
"eddsa_sig");
|
||||||
}
|
}
|
||||||
GNUNET_JSON_parse_free (spec);
|
GNUNET_JSON_parse_free (spec);
|
||||||
@ -377,6 +379,7 @@ TEH_TEST_handler_test_eddsa (struct TEH_RequestHandler *rh,
|
|||||||
{
|
{
|
||||||
GNUNET_free (pk);
|
GNUNET_free (pk);
|
||||||
return TEH_RESPONSE_reply_internal_error (connection,
|
return TEH_RESPONSE_reply_internal_error (connection,
|
||||||
|
TALER_EC_TEST_EDDSA_ERROR,
|
||||||
"Failed to EdDSA-sign");
|
"Failed to EdDSA-sign");
|
||||||
}
|
}
|
||||||
GNUNET_CRYPTO_eddsa_key_get_public (pk,
|
GNUNET_CRYPTO_eddsa_key_get_public (pk,
|
||||||
@ -419,6 +422,7 @@ TEH_TEST_handler_test_rsa_get (struct TEH_RequestHandler *rh,
|
|||||||
{
|
{
|
||||||
GNUNET_break (0);
|
GNUNET_break (0);
|
||||||
return TEH_RESPONSE_reply_internal_error (connection,
|
return TEH_RESPONSE_reply_internal_error (connection,
|
||||||
|
TALER_EC_TEST_RSA_GEN_ERROR,
|
||||||
"Failed to create RSA key");
|
"Failed to create RSA key");
|
||||||
}
|
}
|
||||||
pub = GNUNET_CRYPTO_rsa_private_key_get_public (rsa_pk);
|
pub = GNUNET_CRYPTO_rsa_private_key_get_public (rsa_pk);
|
||||||
@ -426,6 +430,7 @@ TEH_TEST_handler_test_rsa_get (struct TEH_RequestHandler *rh,
|
|||||||
{
|
{
|
||||||
GNUNET_break (0);
|
GNUNET_break (0);
|
||||||
return TEH_RESPONSE_reply_internal_error (connection,
|
return TEH_RESPONSE_reply_internal_error (connection,
|
||||||
|
TALER_EC_TEST_RSA_PUB_ERROR,
|
||||||
"Failed to get public RSA key");
|
"Failed to get public RSA key");
|
||||||
}
|
}
|
||||||
res = TEH_RESPONSE_reply_json_pack (connection,
|
res = TEH_RESPONSE_reply_json_pack (connection,
|
||||||
@ -489,6 +494,7 @@ TEH_TEST_handler_test_rsa_sign (struct TEH_RequestHandler *rh,
|
|||||||
GNUNET_break (0);
|
GNUNET_break (0);
|
||||||
GNUNET_JSON_parse_free (spec);
|
GNUNET_JSON_parse_free (spec);
|
||||||
return TEH_RESPONSE_reply_internal_error (connection,
|
return TEH_RESPONSE_reply_internal_error (connection,
|
||||||
|
TALER_EC_TEST_RSA_GEN_ERROR,
|
||||||
"Failed to create RSA key");
|
"Failed to create RSA key");
|
||||||
}
|
}
|
||||||
sig = GNUNET_CRYPTO_rsa_sign_blinded (rsa_pk,
|
sig = GNUNET_CRYPTO_rsa_sign_blinded (rsa_pk,
|
||||||
@ -499,6 +505,7 @@ TEH_TEST_handler_test_rsa_sign (struct TEH_RequestHandler *rh,
|
|||||||
GNUNET_break (0);
|
GNUNET_break (0);
|
||||||
GNUNET_JSON_parse_free (spec);
|
GNUNET_JSON_parse_free (spec);
|
||||||
return TEH_RESPONSE_reply_internal_error (connection,
|
return TEH_RESPONSE_reply_internal_error (connection,
|
||||||
|
TALER_EC_TEST_RSA_SIGN_ERROR,
|
||||||
"Failed to RSA-sign");
|
"Failed to RSA-sign");
|
||||||
}
|
}
|
||||||
GNUNET_JSON_parse_free (spec);
|
GNUNET_JSON_parse_free (spec);
|
||||||
|
@ -88,6 +88,7 @@ check_and_handle_track_transaction_request (struct MHD_Connection *connection,
|
|||||||
{
|
{
|
||||||
GNUNET_break_op (0);
|
GNUNET_break_op (0);
|
||||||
return TEH_RESPONSE_reply_signature_invalid (connection,
|
return TEH_RESPONSE_reply_signature_invalid (connection,
|
||||||
|
TALER_EC_TRACK_TRANSACTION_MERCHANT_SIGNATURE_INVALID,
|
||||||
"merchant_sig");
|
"merchant_sig");
|
||||||
}
|
}
|
||||||
return TEH_DB_execute_track_transaction (connection,
|
return TEH_DB_execute_track_transaction (connection,
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
* @author Florian Dold
|
* @author Florian Dold
|
||||||
* @author Christian Grothoff
|
* @author Christian Grothoff
|
||||||
* @author Sree Harsha Totakura
|
* @author Sree Harsha Totakura
|
||||||
|
* @author Marcello Stanisci
|
||||||
*/
|
*/
|
||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
#include "taler_pq_lib.h"
|
#include "taler_pq_lib.h"
|
||||||
@ -627,6 +628,23 @@ postgres_prepare (PGconn *db_conn)
|
|||||||
"($1, $2, $3, $4, $5, $6, $7);",
|
"($1, $2, $3, $4, $5, $6, $7);",
|
||||||
7, NULL);
|
7, NULL);
|
||||||
|
|
||||||
|
|
||||||
|
/* Used in postgres_select_reserves_in_above_serial_id() to obtain inbound
|
||||||
|
transactions for reserves with serial id '\geq' the given parameter */
|
||||||
|
PREPARE ("audit_reserves_in_get_transactions_incr",
|
||||||
|
"SELECT"
|
||||||
|
" reserve_pub"
|
||||||
|
",credit_val"
|
||||||
|
",credit_frac"
|
||||||
|
",credit_curr"
|
||||||
|
",execution_date"
|
||||||
|
",sender_account_details"
|
||||||
|
",transfer_details"
|
||||||
|
" FROM reserves_in"
|
||||||
|
" WHERE reserve_in_serial_id>=$1"
|
||||||
|
" ORDER BY reserve_in_serial_id",
|
||||||
|
1, NULL);
|
||||||
|
|
||||||
/* Used in #postgres_get_reserve_history() to obtain inbound transactions
|
/* Used in #postgres_get_reserve_history() to obtain inbound transactions
|
||||||
for a reserve */
|
for a reserve */
|
||||||
PREPARE ("reserves_in_get_transactions",
|
PREPARE ("reserves_in_get_transactions",
|
||||||
@ -707,6 +725,23 @@ postgres_prepare (PGconn *db_conn)
|
|||||||
" WHERE reserve_pub=$1;",
|
" WHERE reserve_pub=$1;",
|
||||||
1, NULL);
|
1, NULL);
|
||||||
|
|
||||||
|
/* Used in #postgres_select_reserves_out_above_serial_id() */
|
||||||
|
PREPARE ("audit_get_reserves_out_incr",
|
||||||
|
"SELECT"
|
||||||
|
" h_blind_ev"
|
||||||
|
",denom_pub"
|
||||||
|
",denom_sig"
|
||||||
|
",reserve_sig"
|
||||||
|
",reserve_pub"
|
||||||
|
",execution_date"
|
||||||
|
",amount_with_fee_val"
|
||||||
|
",amount_with_fee_frac"
|
||||||
|
",amount_with_fee_curr"
|
||||||
|
" FROM reserves_out"
|
||||||
|
" WHERE reserve_out_serial_id>=$1"
|
||||||
|
" ORDER BY reserve_out_serial_id ASC",
|
||||||
|
1, NULL);
|
||||||
|
|
||||||
/* Used in #postgres_get_refresh_session() to fetch
|
/* Used in #postgres_get_refresh_session() to fetch
|
||||||
high-level information about a refresh session */
|
high-level information about a refresh session */
|
||||||
PREPARE ("get_refresh_session",
|
PREPARE ("get_refresh_session",
|
||||||
@ -727,6 +762,22 @@ postgres_prepare (PGconn *db_conn)
|
|||||||
" WHERE session_hash=$1 ",
|
" WHERE session_hash=$1 ",
|
||||||
1, NULL);
|
1, NULL);
|
||||||
|
|
||||||
|
/* Used in #postgres_select_refreshs_above_serial_id() to fetch
|
||||||
|
refresh session with id '\geq' the given parameter */
|
||||||
|
PREPARE ("audit_get_refresh_sessions_incr",
|
||||||
|
"SELECT"
|
||||||
|
" old_coin_pub"
|
||||||
|
",old_coin_sig"
|
||||||
|
",amount_with_fee_val"
|
||||||
|
",amount_with_fee_frac"
|
||||||
|
",amount_with_fee_curr"
|
||||||
|
",num_newcoins"
|
||||||
|
",noreveal_index"
|
||||||
|
" FROM refresh_sessions"
|
||||||
|
" WHERE melt_serial_id>=$1"
|
||||||
|
" ORDER BY melt_serial_id ASC",
|
||||||
|
1, NULL);
|
||||||
|
|
||||||
/* Used in #postgres_create_refresh_session() to store
|
/* Used in #postgres_create_refresh_session() to store
|
||||||
high-level information about a refresh session */
|
high-level information about a refresh session */
|
||||||
PREPARE ("insert_refresh_session",
|
PREPARE ("insert_refresh_session",
|
||||||
@ -802,6 +853,23 @@ postgres_prepare (PGconn *db_conn)
|
|||||||
" WHERE old_coin_pub=$1",
|
" WHERE old_coin_pub=$1",
|
||||||
1, NULL);
|
1, NULL);
|
||||||
|
|
||||||
|
/* Fetch refunds with rowid '\geq' the given parameter */
|
||||||
|
PREPARE ("audit_get_refunds_incr",
|
||||||
|
"SELECT"
|
||||||
|
" merchant_pub"
|
||||||
|
",merchant_sig"
|
||||||
|
",h_contract"
|
||||||
|
",transaction_id"
|
||||||
|
",rtransaction_id"
|
||||||
|
",coin_pub"
|
||||||
|
",amount_with_fee_val"
|
||||||
|
",amount_with_fee_frac"
|
||||||
|
",amount_with_fee_curr"
|
||||||
|
" FROM refunds"
|
||||||
|
" WHERE refund_serial_id>=$1"
|
||||||
|
" ORDER BY refund_serial_id ASC",
|
||||||
|
1, NULL);
|
||||||
|
|
||||||
/* Query the 'refunds' by coin public key */
|
/* Query the 'refunds' by coin public key */
|
||||||
PREPARE ("get_refunds_by_coin",
|
PREPARE ("get_refunds_by_coin",
|
||||||
"SELECT"
|
"SELECT"
|
||||||
@ -823,6 +891,7 @@ postgres_prepare (PGconn *db_conn)
|
|||||||
1, NULL);
|
1, NULL);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Used in #postgres_insert_transfer_public_key() to
|
/* Used in #postgres_insert_transfer_public_key() to
|
||||||
store commitments */
|
store commitments */
|
||||||
PREPARE ("insert_transfer_public_key",
|
PREPARE ("insert_transfer_public_key",
|
||||||
@ -921,8 +990,7 @@ postgres_prepare (PGconn *db_conn)
|
|||||||
" )",
|
" )",
|
||||||
3, NULL);
|
3, NULL);
|
||||||
|
|
||||||
/* Fetch an existing deposit request, used to ensure idempotency
|
/* Fetch deposits with rowid '\geq' the given parameter */
|
||||||
during /deposit processing. Used in #postgres_have_deposit(). */
|
|
||||||
PREPARE ("audit_get_deposits_incr",
|
PREPARE ("audit_get_deposits_incr",
|
||||||
"SELECT"
|
"SELECT"
|
||||||
" amount_with_fee_val"
|
" amount_with_fee_val"
|
||||||
@ -937,11 +1005,12 @@ postgres_prepare (PGconn *db_conn)
|
|||||||
",wire_deadline"
|
",wire_deadline"
|
||||||
",h_contract"
|
",h_contract"
|
||||||
",wire"
|
",wire"
|
||||||
|
",done"
|
||||||
" FROM deposits"
|
" FROM deposits"
|
||||||
" WHERE ("
|
" WHERE ("
|
||||||
" (deposit_serial_id>=$1)"
|
" (deposit_serial_id>=$1)"
|
||||||
" )"
|
" )"
|
||||||
" ORDER BY deposit_serial_id",
|
" ORDER BY deposit_serial_id ASC",
|
||||||
1, NULL);
|
1, NULL);
|
||||||
|
|
||||||
/* Fetch an existing deposit request.
|
/* Fetch an existing deposit request.
|
||||||
@ -1207,6 +1276,18 @@ postgres_prepare (PGconn *db_conn)
|
|||||||
" FROM prewire"
|
" FROM prewire"
|
||||||
" WHERE finished=true",
|
" WHERE finished=true",
|
||||||
0, NULL);
|
0, NULL);
|
||||||
|
|
||||||
|
/* Used in #postgres_select_prepare_above_serial_id() */
|
||||||
|
PREPARE ("audit_get_wire_incr",
|
||||||
|
"SELECT"
|
||||||
|
" type"
|
||||||
|
",buf"
|
||||||
|
",finished"
|
||||||
|
" FROM prewire"
|
||||||
|
" WHERE prewire_uuid>=$1"
|
||||||
|
" ORDER BY prewire_uuid ASC",
|
||||||
|
1, NULL);
|
||||||
|
|
||||||
PREPARE ("gc_denominations",
|
PREPARE ("gc_denominations",
|
||||||
"DELETE"
|
"DELETE"
|
||||||
" FROM denominations"
|
" FROM denominations"
|
||||||
@ -4291,9 +4372,9 @@ postgres_select_deposits_above_serial_id (void *cls,
|
|||||||
};
|
};
|
||||||
PGresult *result;
|
PGresult *result;
|
||||||
result = GNUNET_PQ_exec_prepared (session->conn,
|
result = GNUNET_PQ_exec_prepared (session->conn,
|
||||||
"audit_get_deposits_incr",
|
"audit_get_deposits_incr",
|
||||||
params);
|
params);
|
||||||
if (PGRES_COMMAND_OK !=
|
if (PGRES_TUPLES_OK !=
|
||||||
PQresultStatus (result))
|
PQresultStatus (result))
|
||||||
{
|
{
|
||||||
BREAK_DB_ERR (result);
|
BREAK_DB_ERR (result);
|
||||||
@ -4307,20 +4388,62 @@ postgres_select_deposits_above_serial_id (void *cls,
|
|||||||
if (0 == nrows)
|
if (0 == nrows)
|
||||||
{
|
{
|
||||||
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
|
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
|
||||||
"audit_get_deposit_incr() returned 0 matching rows\n");
|
"select_deposits_above_serial_id() returned 0 matching rows\n");
|
||||||
PQclear (result);
|
PQclear (result);
|
||||||
return GNUNET_NO;
|
return GNUNET_NO;
|
||||||
}
|
}
|
||||||
for (i=0;i<nrows;i++)
|
for (i=0;i<nrows;i++)
|
||||||
{
|
{
|
||||||
|
struct TALER_EXCHANGEDB_Deposit deposit;
|
||||||
|
uint8_t done = 0;
|
||||||
|
|
||||||
|
struct GNUNET_PQ_ResultSpec rs[] = {
|
||||||
|
TALER_PQ_result_spec_amount ("amount_with_fee",
|
||||||
|
&deposit.amount_with_fee),
|
||||||
|
GNUNET_PQ_result_spec_absolute_time ("timestamp",
|
||||||
|
&deposit.timestamp),
|
||||||
|
GNUNET_PQ_result_spec_auto_from_type ("merchant_pub",
|
||||||
|
&deposit.merchant_pub),
|
||||||
|
GNUNET_PQ_result_spec_auto_from_type ("coin_pub",
|
||||||
|
&deposit.coin.coin_pub),
|
||||||
|
GNUNET_PQ_result_spec_auto_from_type ("coin_sig",
|
||||||
|
&deposit.csig),
|
||||||
|
GNUNET_PQ_result_spec_uint64 ("transaction_id",
|
||||||
|
&deposit.transaction_id),
|
||||||
|
GNUNET_PQ_result_spec_absolute_time ("refund_deadline",
|
||||||
|
&deposit.refund_deadline),
|
||||||
|
GNUNET_PQ_result_spec_absolute_time ("wire_deadline",
|
||||||
|
&deposit.wire_deadline),
|
||||||
|
GNUNET_PQ_result_spec_auto_from_type ("h_contract",
|
||||||
|
&deposit.h_contract),
|
||||||
|
TALER_PQ_result_spec_json ("wire",
|
||||||
|
&deposit.receiver_wire_account),
|
||||||
|
GNUNET_PQ_result_spec_auto_from_type ("done",
|
||||||
|
&done),
|
||||||
|
GNUNET_PQ_result_spec_end
|
||||||
|
};
|
||||||
|
if (GNUNET_OK !=
|
||||||
|
GNUNET_PQ_extract_result (result, rs, 0))
|
||||||
|
{
|
||||||
|
GNUNET_break (0);
|
||||||
|
PQclear (result);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
cb (cb_cls,
|
||||||
|
serial_id,
|
||||||
|
&deposit.merchant_pub,
|
||||||
|
&deposit.coin.coin_pub,
|
||||||
|
&deposit.csig,
|
||||||
|
&deposit.amount_with_fee,
|
||||||
|
deposit.transaction_id,
|
||||||
|
&deposit.h_contract,
|
||||||
|
deposit.refund_deadline,
|
||||||
|
deposit.wire_deadline,
|
||||||
|
deposit.receiver_wire_account,
|
||||||
|
done);
|
||||||
}
|
}
|
||||||
|
|
||||||
PQclear (result);
|
PQclear (result);
|
||||||
return GNUNET_OK;
|
return GNUNET_OK;
|
||||||
|
|
||||||
GNUNET_break (0); // FIXME: not implemented
|
|
||||||
return GNUNET_SYSERR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -4343,8 +4466,72 @@ postgres_select_refreshs_above_serial_id (void *cls,
|
|||||||
TALER_EXCHANGEDB_RefreshSessionCallback cb,
|
TALER_EXCHANGEDB_RefreshSessionCallback cb,
|
||||||
void *cb_cls)
|
void *cb_cls)
|
||||||
{
|
{
|
||||||
GNUNET_break (0); // FIXME: not implemented
|
struct GNUNET_PQ_QueryParam params[] = {
|
||||||
return GNUNET_SYSERR;
|
GNUNET_PQ_query_param_uint64 (&serial_id),
|
||||||
|
GNUNET_PQ_query_param_end
|
||||||
|
};
|
||||||
|
PGresult *result;
|
||||||
|
result = GNUNET_PQ_exec_prepared (session->conn,
|
||||||
|
"audit_get_refresh_sessions_incr",
|
||||||
|
params);
|
||||||
|
|
||||||
|
if (PGRES_TUPLES_OK !=
|
||||||
|
PQresultStatus (result))
|
||||||
|
{
|
||||||
|
BREAK_DB_ERR (result);
|
||||||
|
PQclear (result);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
int nrows;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
nrows = PQntuples (result);
|
||||||
|
if (0 == nrows)
|
||||||
|
{
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
|
||||||
|
"select_refreshs_above_serial_id() returned 0 matching rows\n");
|
||||||
|
PQclear (result);
|
||||||
|
return GNUNET_NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=0;i<nrows;i++)
|
||||||
|
{
|
||||||
|
struct TALER_CoinSpendPublicKeyP coin_pub;
|
||||||
|
struct TALER_CoinSpendSignatureP coin_sig;
|
||||||
|
struct TALER_Amount amount_with_fee;
|
||||||
|
uint16_t num_newcoins;
|
||||||
|
uint16_t noreveal_index;
|
||||||
|
|
||||||
|
struct GNUNET_PQ_ResultSpec rs[] = {
|
||||||
|
GNUNET_PQ_result_spec_auto_from_type ("old_coin_pub",
|
||||||
|
&coin_pub),
|
||||||
|
GNUNET_PQ_result_spec_auto_from_type ("old_coin_sig",
|
||||||
|
&coin_sig),
|
||||||
|
TALER_PQ_result_spec_amount ("amount_with_fee",
|
||||||
|
&amount_with_fee),
|
||||||
|
GNUNET_PQ_result_spec_uint16 ("num_newcoins",
|
||||||
|
&num_newcoins),
|
||||||
|
GNUNET_PQ_result_spec_uint16 ("noreveal_index",
|
||||||
|
&noreveal_index),
|
||||||
|
GNUNET_PQ_result_spec_end
|
||||||
|
};
|
||||||
|
if (GNUNET_OK !=
|
||||||
|
GNUNET_PQ_extract_result (result, rs, 0))
|
||||||
|
{
|
||||||
|
GNUNET_break (0);
|
||||||
|
PQclear (result);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
cb (cb_cls,
|
||||||
|
serial_id,
|
||||||
|
&coin_pub,
|
||||||
|
&coin_sig,
|
||||||
|
&amount_with_fee,
|
||||||
|
num_newcoins,
|
||||||
|
noreveal_index);
|
||||||
|
}
|
||||||
|
PQclear (result);
|
||||||
|
return GNUNET_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -4367,8 +4554,72 @@ postgres_select_refunds_above_serial_id (void *cls,
|
|||||||
TALER_EXCHANGEDB_RefundCallback cb,
|
TALER_EXCHANGEDB_RefundCallback cb,
|
||||||
void *cb_cls)
|
void *cb_cls)
|
||||||
{
|
{
|
||||||
GNUNET_break (0); // FIXME: not implemented
|
struct GNUNET_PQ_QueryParam params[] = {
|
||||||
return GNUNET_SYSERR;
|
GNUNET_PQ_query_param_uint64 (&serial_id),
|
||||||
|
GNUNET_PQ_query_param_end
|
||||||
|
};
|
||||||
|
PGresult *result;
|
||||||
|
result = GNUNET_PQ_exec_prepared (session->conn,
|
||||||
|
"audit_get_refunds_incr",
|
||||||
|
params);
|
||||||
|
if (PGRES_TUPLES_OK !=
|
||||||
|
PQresultStatus (result))
|
||||||
|
{
|
||||||
|
BREAK_DB_ERR (result);
|
||||||
|
PQclear (result);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
int nrows;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
nrows = PQntuples (result);
|
||||||
|
if (0 == nrows)
|
||||||
|
{
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
|
||||||
|
"select_refunds_above_serial_id() returned 0 matching rows\n");
|
||||||
|
PQclear (result);
|
||||||
|
return GNUNET_NO;
|
||||||
|
}
|
||||||
|
for (i=0;i<nrows;i++)
|
||||||
|
{
|
||||||
|
struct TALER_EXCHANGEDB_Refund refund;
|
||||||
|
|
||||||
|
struct GNUNET_PQ_ResultSpec rs[] = {
|
||||||
|
GNUNET_PQ_result_spec_auto_from_type ("merchant_pub",
|
||||||
|
&refund.merchant_pub),
|
||||||
|
GNUNET_PQ_result_spec_auto_from_type ("merchant_sig",
|
||||||
|
&refund.merchant_sig),
|
||||||
|
GNUNET_PQ_result_spec_auto_from_type ("h_contract",
|
||||||
|
&refund.h_contract),
|
||||||
|
GNUNET_PQ_result_spec_uint64 ("transaction_id",
|
||||||
|
&refund.transaction_id),
|
||||||
|
GNUNET_PQ_result_spec_uint64 ("rtransaction_id",
|
||||||
|
&refund.rtransaction_id),
|
||||||
|
GNUNET_PQ_result_spec_auto_from_type ("coin_pub",
|
||||||
|
&refund.coin.coin_pub),
|
||||||
|
TALER_PQ_result_spec_amount ("amount_with_fee",
|
||||||
|
&refund.refund_amount),
|
||||||
|
GNUNET_PQ_result_spec_end
|
||||||
|
};
|
||||||
|
if (GNUNET_OK !=
|
||||||
|
GNUNET_PQ_extract_result (result, rs, 0))
|
||||||
|
{
|
||||||
|
GNUNET_break (0);
|
||||||
|
PQclear (result);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
cb (cb_cls,
|
||||||
|
serial_id,
|
||||||
|
&refund.coin.coin_pub,
|
||||||
|
&refund.merchant_pub,
|
||||||
|
&refund.merchant_sig,
|
||||||
|
&refund.h_contract,
|
||||||
|
refund.transaction_id,
|
||||||
|
refund.rtransaction_id,
|
||||||
|
&refund.refund_amount);
|
||||||
|
}
|
||||||
|
PQclear (result);
|
||||||
|
return GNUNET_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -4391,8 +4642,73 @@ postgres_select_reserves_in_above_serial_id (void *cls,
|
|||||||
TALER_EXCHANGEDB_ReserveInCallback cb,
|
TALER_EXCHANGEDB_ReserveInCallback cb,
|
||||||
void *cb_cls)
|
void *cb_cls)
|
||||||
{
|
{
|
||||||
GNUNET_break (0); // FIXME: not implemented
|
struct GNUNET_PQ_QueryParam params[] = {
|
||||||
return GNUNET_SYSERR;
|
GNUNET_PQ_query_param_uint64 (&serial_id),
|
||||||
|
GNUNET_PQ_query_param_end
|
||||||
|
};
|
||||||
|
PGresult *result;
|
||||||
|
result = GNUNET_PQ_exec_prepared (session->conn,
|
||||||
|
"audit_reserves_in_get_transactions_incr",
|
||||||
|
params);
|
||||||
|
if (PGRES_TUPLES_OK !=
|
||||||
|
PQresultStatus (result))
|
||||||
|
{
|
||||||
|
BREAK_DB_ERR (result);
|
||||||
|
PQclear (result);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
int nrows;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
nrows = PQntuples (result);
|
||||||
|
if (0 == nrows)
|
||||||
|
{
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
|
||||||
|
"select_reserves_in_above_serial_id() returned 0 matching rows\n");
|
||||||
|
PQclear (result);
|
||||||
|
return GNUNET_NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=0;i<nrows;i++)
|
||||||
|
{
|
||||||
|
struct TALER_ReservePublicKeyP reserve_pub;
|
||||||
|
struct TALER_Amount credit;
|
||||||
|
json_t *sender_account_details;
|
||||||
|
json_t *transfer_details;
|
||||||
|
struct GNUNET_TIME_Absolute execution_date;
|
||||||
|
|
||||||
|
struct GNUNET_PQ_ResultSpec rs[] = {
|
||||||
|
GNUNET_PQ_result_spec_auto_from_type ("reserve_pub",
|
||||||
|
&reserve_pub),
|
||||||
|
TALER_PQ_result_spec_amount ("credit",
|
||||||
|
&credit),
|
||||||
|
GNUNET_PQ_result_spec_absolute_time("execution_date",
|
||||||
|
&execution_date),
|
||||||
|
TALER_PQ_result_spec_json ("sender_account_details",
|
||||||
|
&sender_account_details),
|
||||||
|
TALER_PQ_result_spec_json ("transfer_details",
|
||||||
|
&transfer_details),
|
||||||
|
GNUNET_PQ_result_spec_end
|
||||||
|
};
|
||||||
|
|
||||||
|
if (GNUNET_OK !=
|
||||||
|
GNUNET_PQ_extract_result (result, rs, 0))
|
||||||
|
{
|
||||||
|
GNUNET_break (0);
|
||||||
|
PQclear (result);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
cb (cb_cls,
|
||||||
|
serial_id,
|
||||||
|
&reserve_pub,
|
||||||
|
&credit,
|
||||||
|
sender_account_details,
|
||||||
|
transfer_details,
|
||||||
|
execution_date);
|
||||||
|
}
|
||||||
|
|
||||||
|
PQclear (result);
|
||||||
|
return GNUNET_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -4415,8 +4731,79 @@ postgres_select_reserves_out_above_serial_id (void *cls,
|
|||||||
TALER_EXCHANGEDB_WithdrawCallback cb,
|
TALER_EXCHANGEDB_WithdrawCallback cb,
|
||||||
void *cb_cls)
|
void *cb_cls)
|
||||||
{
|
{
|
||||||
GNUNET_break (0); // FIXME: not implemented
|
struct GNUNET_PQ_QueryParam params[] = {
|
||||||
return GNUNET_SYSERR;
|
GNUNET_PQ_query_param_uint64 (&serial_id),
|
||||||
|
GNUNET_PQ_query_param_end
|
||||||
|
};
|
||||||
|
PGresult *result;
|
||||||
|
result = GNUNET_PQ_exec_prepared (session->conn,
|
||||||
|
"audit_get_reserves_out_incr",
|
||||||
|
params);
|
||||||
|
if (PGRES_TUPLES_OK !=
|
||||||
|
PQresultStatus (result))
|
||||||
|
{
|
||||||
|
BREAK_DB_ERR (result);
|
||||||
|
PQclear (result);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
int nrows;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
nrows = PQntuples (result);
|
||||||
|
if (0 == nrows)
|
||||||
|
{
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
|
||||||
|
"select_reserves_out_above_serial_id() returned 0 matching rows\n");
|
||||||
|
PQclear (result);
|
||||||
|
return GNUNET_NO;
|
||||||
|
}
|
||||||
|
for (i=0;i<nrows;i++)
|
||||||
|
{
|
||||||
|
struct GNUNET_HashCode h_blind_ev;
|
||||||
|
struct TALER_DenominationPublicKey denom_pub;
|
||||||
|
struct TALER_DenominationSignature denom_sig;
|
||||||
|
struct TALER_ReservePublicKeyP reserve_pub;
|
||||||
|
struct TALER_ReserveSignatureP reserve_sig;
|
||||||
|
struct GNUNET_TIME_Absolute execution_date;
|
||||||
|
struct TALER_Amount amount_with_fee;
|
||||||
|
|
||||||
|
struct GNUNET_PQ_ResultSpec rs[] = {
|
||||||
|
GNUNET_PQ_result_spec_auto_from_type ("h_blind_ev",
|
||||||
|
&h_blind_ev),
|
||||||
|
GNUNET_PQ_result_spec_rsa_public_key ("denom_pub",
|
||||||
|
&denom_pub.rsa_public_key),
|
||||||
|
GNUNET_PQ_result_spec_rsa_signature ("denom_sig",
|
||||||
|
&denom_sig.rsa_signature),
|
||||||
|
GNUNET_PQ_result_spec_auto_from_type ("reserve_pub",
|
||||||
|
&reserve_pub),
|
||||||
|
GNUNET_PQ_result_spec_auto_from_type ("reserve_sig",
|
||||||
|
&reserve_sig),
|
||||||
|
GNUNET_PQ_result_spec_absolute_time ("execution_date",
|
||||||
|
&execution_date),
|
||||||
|
TALER_PQ_result_spec_amount ("amount_with_fee",
|
||||||
|
&amount_with_fee),
|
||||||
|
GNUNET_PQ_result_spec_end
|
||||||
|
};
|
||||||
|
if (GNUNET_OK !=
|
||||||
|
GNUNET_PQ_extract_result (result, rs, 0))
|
||||||
|
{
|
||||||
|
GNUNET_break (0);
|
||||||
|
PQclear (result);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
cb (cb_cls,
|
||||||
|
serial_id,
|
||||||
|
&h_blind_ev,
|
||||||
|
&denom_pub,
|
||||||
|
&denom_sig,
|
||||||
|
&reserve_pub,
|
||||||
|
&reserve_sig,
|
||||||
|
execution_date,
|
||||||
|
&amount_with_fee);
|
||||||
|
}
|
||||||
|
|
||||||
|
PQclear (result);
|
||||||
|
return GNUNET_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -4440,8 +4827,69 @@ postgres_select_prepare_above_serial_id (void *cls,
|
|||||||
TALER_EXCHANGEDB_WirePreparationCallback cb,
|
TALER_EXCHANGEDB_WirePreparationCallback cb,
|
||||||
void *cb_cls)
|
void *cb_cls)
|
||||||
{
|
{
|
||||||
GNUNET_break (0); // FIXME: not implemented
|
|
||||||
return GNUNET_SYSERR;
|
struct GNUNET_PQ_QueryParam params[] = {
|
||||||
|
GNUNET_PQ_query_param_uint64 (&serial_id),
|
||||||
|
GNUNET_PQ_query_param_end
|
||||||
|
};
|
||||||
|
PGresult *result;
|
||||||
|
result = GNUNET_PQ_exec_prepared (session->conn,
|
||||||
|
"audit_get_wire_incr",
|
||||||
|
params);
|
||||||
|
if (PGRES_TUPLES_OK !=
|
||||||
|
PQresultStatus (result))
|
||||||
|
{
|
||||||
|
BREAK_DB_ERR (result);
|
||||||
|
PQclear (result);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
int nrows;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
nrows = PQntuples (result);
|
||||||
|
if (0 == nrows)
|
||||||
|
{
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
|
||||||
|
"select_prepare_above_serial_id() returned 0 matching rows\n");
|
||||||
|
PQclear (result);
|
||||||
|
return GNUNET_NO;
|
||||||
|
}
|
||||||
|
for (i=0;i<nrows;i++)
|
||||||
|
{
|
||||||
|
char *wire_method;
|
||||||
|
void *buf;
|
||||||
|
size_t buf_size;
|
||||||
|
uint8_t finished;
|
||||||
|
|
||||||
|
struct GNUNET_PQ_ResultSpec rs[] = {
|
||||||
|
GNUNET_PQ_result_spec_string ("type",
|
||||||
|
&wire_method),
|
||||||
|
GNUNET_PQ_result_spec_variable_size ("buf",
|
||||||
|
&buf,
|
||||||
|
&buf_size),
|
||||||
|
GNUNET_PQ_result_spec_auto_from_type ("finished",
|
||||||
|
&finished),
|
||||||
|
GNUNET_PQ_result_spec_end
|
||||||
|
};
|
||||||
|
|
||||||
|
if (GNUNET_OK !=
|
||||||
|
GNUNET_PQ_extract_result (result, rs, 0))
|
||||||
|
{
|
||||||
|
GNUNET_break (0);
|
||||||
|
PQclear (result);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
cb (cb_cls,
|
||||||
|
serial_id,
|
||||||
|
wire_method,
|
||||||
|
buf,
|
||||||
|
buf_size,
|
||||||
|
finished);
|
||||||
|
}
|
||||||
|
|
||||||
|
PQclear (result);
|
||||||
|
return GNUNET_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
* @brief test cases for DB interaction functions
|
* @brief test cases for DB interaction functions
|
||||||
* @author Sree Harsha Totakura
|
* @author Sree Harsha Totakura
|
||||||
* @author Christian Grothoff
|
* @author Christian Grothoff
|
||||||
|
* @author Marcello Stanisci
|
||||||
*/
|
*/
|
||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
#include "taler_exchangedb_lib.h"
|
#include "taler_exchangedb_lib.h"
|
||||||
@ -77,6 +78,12 @@ dead_prepare_cb (void *cls,
|
|||||||
GNUNET_assert (0);
|
GNUNET_assert (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Counter used in auditor-related db functions. Used to count
|
||||||
|
* expected rows.
|
||||||
|
*/
|
||||||
|
unsigned int auditor_row_cnt;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback that is called with wire prepare data
|
* Callback that is called with wire prepare data
|
||||||
@ -103,6 +110,27 @@ mark_prepare_cb (void *cls,
|
|||||||
rowid));
|
rowid));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback with data about a prepared wire transfer.
|
||||||
|
*
|
||||||
|
* @param cls closure
|
||||||
|
* @param rowid row identifier used to mark prepared transaction as done
|
||||||
|
* @param wire_method which wire method is this preparation data for
|
||||||
|
* @param buf transaction data that was persisted, NULL on error
|
||||||
|
* @param buf_size number of bytes in @a buf, 0 on error
|
||||||
|
* @param finished did we complete the transfer yet?
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
audit_wire_cb (void *cls,
|
||||||
|
unsigned long long rowid,
|
||||||
|
const char *wire_method,
|
||||||
|
const char *buf,
|
||||||
|
size_t buf_size,
|
||||||
|
int finished)
|
||||||
|
{
|
||||||
|
auditor_row_cnt++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test API relating to persisting the wire plugins preparation data.
|
* Test API relating to persisting the wire plugins preparation data.
|
||||||
@ -134,6 +162,14 @@ test_wire_prepare (struct TALER_EXCHANGEDB_Session *session)
|
|||||||
session,
|
session,
|
||||||
&dead_prepare_cb,
|
&dead_prepare_cb,
|
||||||
NULL));
|
NULL));
|
||||||
|
auditor_row_cnt = 0;
|
||||||
|
FAILIF (GNUNET_OK !=
|
||||||
|
plugin->select_prepare_above_serial_id (plugin->cls,
|
||||||
|
session,
|
||||||
|
0,
|
||||||
|
&audit_wire_cb,
|
||||||
|
NULL));
|
||||||
|
FAILIF (1 != auditor_row_cnt);
|
||||||
return GNUNET_OK;
|
return GNUNET_OK;
|
||||||
drop:
|
drop:
|
||||||
return GNUNET_SYSERR;
|
return GNUNET_SYSERR;
|
||||||
@ -465,6 +501,38 @@ check_transfer_data (void *cls,
|
|||||||
*ok = GNUNET_SYSERR;
|
*ok = GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function called with details about coins that were melted,
|
||||||
|
* with the goal of auditing the refresh's execution.
|
||||||
|
*
|
||||||
|
* @param cls closure
|
||||||
|
* @param rowid unique serial ID for the refresh session in our DB
|
||||||
|
* @param merchant_pub public key of the merchant
|
||||||
|
* @param coin_pub public key of the coin
|
||||||
|
* @param coin_sig signature from the coin
|
||||||
|
* @param amount_with_fee amount that was deposited including fee
|
||||||
|
* @param transaction_id unique transaction ID chosen by the merchant
|
||||||
|
* @param h_contract hash of the contract between merchant and customer
|
||||||
|
* @param refund_deadline by which the merchant adviced that he might want
|
||||||
|
* to get a refund
|
||||||
|
* @param wire_deadline by which the merchant adviced that he would like the
|
||||||
|
* wire transfer to be executed
|
||||||
|
* @param receiver_wire_account wire details for the merchant, NULL from iterate_matching_deposits()
|
||||||
|
* @param done flag set if the deposit was already executed (or not)
|
||||||
|
* @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
audit_refresh_session_cb (void *cls,
|
||||||
|
unsigned long long rowid, /* FIXME: decide data type for serial_id! */
|
||||||
|
const struct TALER_CoinSpendPublicKeyP *coin_pub,
|
||||||
|
const struct TALER_CoinSpendSignatureP *coin_sig,
|
||||||
|
const struct TALER_Amount *amount_with_fee,
|
||||||
|
uint16_t num_newcoins,
|
||||||
|
uint16_t noreveal_index)
|
||||||
|
{
|
||||||
|
auditor_row_cnt++;
|
||||||
|
return GNUNET_OK;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function to test melting of coins as part of a refresh session
|
* Function to test melting of coins as part of a refresh session
|
||||||
@ -538,6 +606,14 @@ test_melting (struct TALER_EXCHANGEDB_Session *session)
|
|||||||
session,
|
session,
|
||||||
&session_hash,
|
&session_hash,
|
||||||
&ret_refresh_session));
|
&ret_refresh_session));
|
||||||
|
|
||||||
|
auditor_row_cnt = 0;
|
||||||
|
FAILIF (GNUNET_OK != plugin->select_refreshs_above_serial_id (plugin->cls,
|
||||||
|
session,
|
||||||
|
0,
|
||||||
|
&audit_refresh_session_cb,
|
||||||
|
NULL));
|
||||||
|
FAILIF (1 != auditor_row_cnt);
|
||||||
FAILIF (ret_refresh_session.num_newcoins != refresh_session.num_newcoins);
|
FAILIF (ret_refresh_session.num_newcoins != refresh_session.num_newcoins);
|
||||||
FAILIF (ret_refresh_session.noreveal_index != refresh_session.noreveal_index);
|
FAILIF (ret_refresh_session.noreveal_index != refresh_session.noreveal_index);
|
||||||
|
|
||||||
@ -874,6 +950,128 @@ deposit_cb (void *cls,
|
|||||||
return GNUNET_OK;
|
return GNUNET_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback for #select_deposits_above_serial_id ()
|
||||||
|
*
|
||||||
|
* @param cls closure
|
||||||
|
* @param rowid unique serial ID for the deposit in our DB
|
||||||
|
* @param merchant_pub public key of the merchant
|
||||||
|
* @param coin_pub public key of the coin
|
||||||
|
* @param coin_sig signature from the coin
|
||||||
|
* @param amount_with_fee amount that was deposited including fee
|
||||||
|
* @param transaction_id unique transaction ID chosen by the merchant
|
||||||
|
* @param h_contract hash of the contract between merchant and customer
|
||||||
|
* @param refund_deadline by which the merchant adviced that he might want
|
||||||
|
* to get a refund
|
||||||
|
* @param wire_deadline by which the merchant adviced that he would like the
|
||||||
|
* wire transfer to be executed
|
||||||
|
* @param receiver_wire_account wire details for the merchant, NULL from iterate_matching_deposits()
|
||||||
|
* @param done flag set if the deposit was already executed (or not)
|
||||||
|
* @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
audit_deposit_cb (void *cls,
|
||||||
|
unsigned long long rowid,
|
||||||
|
const struct TALER_MerchantPublicKeyP *merchant_pub,
|
||||||
|
const struct TALER_CoinSpendPublicKeyP *coin_pub,
|
||||||
|
const struct TALER_CoinSpendSignatureP *coin_sig,
|
||||||
|
const struct TALER_Amount *amount_with_fee,
|
||||||
|
uint64_t transaction_id,
|
||||||
|
const struct GNUNET_HashCode *h_contract,
|
||||||
|
struct GNUNET_TIME_Absolute refund_deadline,
|
||||||
|
struct GNUNET_TIME_Absolute wire_deadline,
|
||||||
|
const json_t *receiver_wire_account,
|
||||||
|
int done)
|
||||||
|
{
|
||||||
|
auditor_row_cnt++;
|
||||||
|
return GNUNET_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function called with details about coins that were refunding,
|
||||||
|
* with the goal of auditing the refund's execution.
|
||||||
|
*
|
||||||
|
* @param cls closure
|
||||||
|
* @param rowid unique serial ID for the refund in our DB
|
||||||
|
* @param coin_pub public key of the coin
|
||||||
|
* @param merchant_pub public key of the merchant
|
||||||
|
* @param merchant_sig signature of the merchant
|
||||||
|
* @param h_contract hash of the contract between merchant and customer
|
||||||
|
* @param transaction_id original transaction ID chosen by the merchant
|
||||||
|
* @param rtransaction_id refund transaction ID chosen by the merchant
|
||||||
|
* @param amount_with_fee amount that was deposited including fee
|
||||||
|
* @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
audit_refund_cb (void *cls,
|
||||||
|
unsigned long long rowid, /* FIXME: decide data type for serial_id! */
|
||||||
|
const struct TALER_CoinSpendPublicKeyP *coin_pub,
|
||||||
|
const struct TALER_MerchantPublicKeyP *merchant_pub,
|
||||||
|
const struct TALER_MerchantSignatureP *merchant_sig,
|
||||||
|
const struct GNUNET_HashCode *h_contract,
|
||||||
|
uint64_t transaction_id,
|
||||||
|
uint64_t rtransaction_id,
|
||||||
|
const struct TALER_Amount *amount_with_fee)
|
||||||
|
{
|
||||||
|
auditor_row_cnt++;
|
||||||
|
return GNUNET_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function called with details about incoming wire transfers.
|
||||||
|
*
|
||||||
|
* @param cls closure
|
||||||
|
* @param rowid unique serial ID for the refresh session in our DB
|
||||||
|
* @param reserve_pub public key of the reserve (also the WTID)
|
||||||
|
* @param credit amount that was received
|
||||||
|
* @param sender_account_details information about the sender's bank account
|
||||||
|
* @param transfer_details information that uniquely identifies the wire transfer
|
||||||
|
* @param execution_date when did we receive the funds
|
||||||
|
* @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
audit_reserve_in_cb (void *cls,
|
||||||
|
unsigned long long rowid, /* FIXME: decide data type for serial_id! */
|
||||||
|
const struct TALER_ReservePublicKeyP *reserve_pub,
|
||||||
|
const struct TALER_Amount *credit,
|
||||||
|
const json_t *sender_account_details,
|
||||||
|
const json_t *transfer_details,
|
||||||
|
struct GNUNET_TIME_Absolute execution_date)
|
||||||
|
{
|
||||||
|
auditor_row_cnt++;
|
||||||
|
return GNUNET_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function called with details about withdraw operations.
|
||||||
|
*
|
||||||
|
* @param cls closure
|
||||||
|
* @param rowid unique serial ID for the refresh session in our DB
|
||||||
|
* @param h_blind_ev blinded hash of the coin's public key
|
||||||
|
* @param denom_pub public denomination key of the deposited coin
|
||||||
|
* @param denom_sig signature over the deposited coin
|
||||||
|
* @param reserve_pub public key of the reserve
|
||||||
|
* @param reserve_sig signature over the withdraw operation
|
||||||
|
* @param execution_date when did the wallet withdraw the coin
|
||||||
|
* @param amount_with_fee amount that was withdrawn
|
||||||
|
* @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
audit_reserve_out_cb (void *cls,
|
||||||
|
unsigned long long rowid, /* FIXME: decide data type for serial_id! */
|
||||||
|
const struct GNUNET_HashCode *h_blind_ev,
|
||||||
|
const struct TALER_DenominationPublicKey *denom_pub,
|
||||||
|
const struct TALER_DenominationSignature *denom_sig,
|
||||||
|
const struct TALER_ReservePublicKeyP *reserve_pub,
|
||||||
|
const struct TALER_ReserveSignatureP *reserve_sig,
|
||||||
|
struct GNUNET_TIME_Absolute execution_date,
|
||||||
|
const struct TALER_Amount *amount_with_fee)
|
||||||
|
{
|
||||||
|
auditor_row_cnt++;
|
||||||
|
return GNUNET_OK;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test garbage collection.
|
* Test garbage collection.
|
||||||
@ -1121,6 +1319,21 @@ run (void *cls)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
FAILIF (3 != cnt);
|
FAILIF (3 != cnt);
|
||||||
|
|
||||||
|
auditor_row_cnt = 0;
|
||||||
|
FAILIF (GNUNET_OK !=
|
||||||
|
plugin->select_reserves_in_above_serial_id (plugin->cls,
|
||||||
|
session,
|
||||||
|
0,
|
||||||
|
&audit_reserve_in_cb,
|
||||||
|
NULL));
|
||||||
|
FAILIF (GNUNET_OK !=
|
||||||
|
plugin->select_reserves_out_above_serial_id (plugin->cls,
|
||||||
|
session,
|
||||||
|
0,
|
||||||
|
&audit_reserve_out_cb,
|
||||||
|
NULL));
|
||||||
|
FAILIF (3 != auditor_row_cnt);
|
||||||
/* Tests for deposits */
|
/* Tests for deposits */
|
||||||
memset (&deposit, 0, sizeof (deposit));
|
memset (&deposit, 0, sizeof (deposit));
|
||||||
RND_BLK (&deposit.coin.coin_pub);
|
RND_BLK (&deposit.coin.coin_pub);
|
||||||
@ -1145,6 +1358,14 @@ run (void *cls)
|
|||||||
plugin->have_deposit (plugin->cls,
|
plugin->have_deposit (plugin->cls,
|
||||||
session,
|
session,
|
||||||
&deposit));
|
&deposit));
|
||||||
|
auditor_row_cnt = 0;
|
||||||
|
FAILIF (GNUNET_OK !=
|
||||||
|
plugin->select_deposits_above_serial_id (plugin->cls,
|
||||||
|
session,
|
||||||
|
0,
|
||||||
|
&audit_deposit_cb,
|
||||||
|
NULL));
|
||||||
|
FAILIF (1 != auditor_row_cnt);
|
||||||
result = 9;
|
result = 9;
|
||||||
FAILIF (1 !=
|
FAILIF (1 !=
|
||||||
plugin->iterate_matching_deposits (plugin->cls,
|
plugin->iterate_matching_deposits (plugin->cls,
|
||||||
@ -1232,7 +1453,15 @@ run (void *cls)
|
|||||||
plugin->insert_refund (plugin->cls,
|
plugin->insert_refund (plugin->cls,
|
||||||
session,
|
session,
|
||||||
&refund));
|
&refund));
|
||||||
|
auditor_row_cnt = 0;
|
||||||
|
FAILIF (GNUNET_OK !=
|
||||||
|
plugin->select_refunds_above_serial_id (plugin->cls,
|
||||||
|
session,
|
||||||
|
0,
|
||||||
|
&audit_refund_cb,
|
||||||
|
NULL));
|
||||||
|
|
||||||
|
FAILIF (1 != auditor_row_cnt);
|
||||||
tl = plugin->get_coin_transactions (plugin->cls,
|
tl = plugin->get_coin_transactions (plugin->cls,
|
||||||
session,
|
session,
|
||||||
&refund.coin.coin_pub);
|
&refund.coin.coin_pub);
|
||||||
|
@ -28,6 +28,90 @@
|
|||||||
#include "taler_signatures.h"
|
#include "taler_signatures.h"
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function called with the results of select_denomination_info()
|
||||||
|
*
|
||||||
|
* @param cls closure
|
||||||
|
* @param issue issuing information with value, fees and other info about the denomination.
|
||||||
|
*
|
||||||
|
* @return sets the return value of select_denomination_info(),
|
||||||
|
* #GNUNET_OK to continue,
|
||||||
|
* #GNUNET_NO to stop processing further rows
|
||||||
|
* #GNUNET_SYSERR or other values on error.
|
||||||
|
*/
|
||||||
|
typedef int
|
||||||
|
(*TALER_AUDITORDB_DenominationInfoDataCallback)(void *cls,
|
||||||
|
const struct TALER_DenominationKeyValidityPS *issue);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function called with the results of select_historic_denom_revenue()
|
||||||
|
*
|
||||||
|
* @param cls closure
|
||||||
|
* @param denom_pub_hash hash of the denomination key
|
||||||
|
* @param revenue_timestamp when did this profit get realized
|
||||||
|
* @param revenue_balance what was the total profit made from
|
||||||
|
* deposit fees, melting fees, refresh fees
|
||||||
|
* and coins that were never returned?
|
||||||
|
* @param deposit_fee_balance total profits from deposit fees
|
||||||
|
* @param melt_fee_balance total profits from melting fees
|
||||||
|
* @param refund_fee_balance total profits from refund fees
|
||||||
|
*
|
||||||
|
* @return sets the return value of select_denomination_info(),
|
||||||
|
* #GNUNET_OK to continue,
|
||||||
|
* #GNUNET_NO to stop processing further rows
|
||||||
|
* #GNUNET_SYSERR or other values on error.
|
||||||
|
*/
|
||||||
|
typedef int
|
||||||
|
(*TALER_AUDITORDB_HistoricDenominationRevenueDataCallback)(void *cls,
|
||||||
|
const struct GNUNET_HashCode *denom_pub_hash,
|
||||||
|
struct GNUNET_TIME_Absolute revenue_timestamp,
|
||||||
|
const struct TALER_Amount *revenue_balance,
|
||||||
|
const struct TALER_Amount *deposit_fee_balance,
|
||||||
|
const struct TALER_Amount *melt_fee_balance,
|
||||||
|
const struct TALER_Amount *refund_fee_balance);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function called with the results of select_historic_losses()
|
||||||
|
*
|
||||||
|
* @param cls closure
|
||||||
|
* @param denom_pub_hash hash of the denomination key
|
||||||
|
* @param loss_timestamp when did this profit get realized
|
||||||
|
* @param loss_balance what was the total loss
|
||||||
|
*
|
||||||
|
* @return sets the return value of select_denomination_info(),
|
||||||
|
* #GNUNET_OK to continue,
|
||||||
|
* #GNUNET_NO to stop processing further rows
|
||||||
|
* #GNUNET_SYSERR or other values on error.
|
||||||
|
*/
|
||||||
|
typedef int
|
||||||
|
(*TALER_AUDITORDB_HistoricLossesDataCallback)(void *cls,
|
||||||
|
const struct GNUNET_HashCode *denom_pub_hash,
|
||||||
|
struct GNUNET_TIME_Absolute loss_timestamp,
|
||||||
|
const struct TALER_Amount *loss_balance);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function called with the results of select_historic_reserve_revenue()
|
||||||
|
*
|
||||||
|
* @param cls closure
|
||||||
|
* @param start_time beginning of aggregated time interval
|
||||||
|
* @param end_time end of aggregated time interval
|
||||||
|
* @param reserve_profits total profits made
|
||||||
|
*
|
||||||
|
* @return sets the return value of select_denomination_info(),
|
||||||
|
* #GNUNET_OK to continue,
|
||||||
|
* #GNUNET_NO to stop processing further rows
|
||||||
|
* #GNUNET_SYSERR or other values on error.
|
||||||
|
*/
|
||||||
|
typedef int
|
||||||
|
(*TALER_AUDITORDB_HistoricReserveRevenueDataCallback)(void *cls,
|
||||||
|
struct GNUNET_TIME_Absolute start_time,
|
||||||
|
struct GNUNET_TIME_Absolute end_time,
|
||||||
|
const struct TALER_Amount *reserve_profits);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle for one session with the database.
|
* Handle for one session with the database.
|
||||||
*/
|
*/
|
||||||
@ -164,10 +248,88 @@ struct TALER_AUDITORDB_Plugin
|
|||||||
(*select_denomination_info)(void *cls,
|
(*select_denomination_info)(void *cls,
|
||||||
struct TALER_AUDITORDB_Session *session,
|
struct TALER_AUDITORDB_Session *session,
|
||||||
const struct TALER_MasterPublicKeyP *master_pub,
|
const struct TALER_MasterPublicKeyP *master_pub,
|
||||||
void *cb, /* FIXME: type! */
|
TALER_AUDITORDB_DenominationInfoDataCallback cb,
|
||||||
void *cb_cls);
|
void *cb_cls);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert information about the auditor's progress with an exchange's
|
||||||
|
* data.
|
||||||
|
*
|
||||||
|
* @param cls the @e cls of this struct with the plugin-specific state
|
||||||
|
* @param session connection to use
|
||||||
|
* @param master_pub master key of the exchange
|
||||||
|
* @param last_reserve_in_serial_id serial ID of the last reserve_in transfer the auditor processed
|
||||||
|
* @param last_reserve_out_serial_id serial ID of the last withdraw the auditor processed
|
||||||
|
* @param last_deposit_serial_id serial ID of the last deposit the auditor processed
|
||||||
|
* @param last_melt_serial_id serial ID of the last refresh the auditor processed
|
||||||
|
* @param last_prewire_serial_id serial ID of the last prewire transfer the auditor processed
|
||||||
|
* @return #GNUNET_OK on success; #GNUNET_SYSERR on failure
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
(*insert_auditor_progress)(void *cls,
|
||||||
|
struct TALER_AUDITORDB_Session *session,
|
||||||
|
const struct TALER_MasterPublicKeyP *master_pub,
|
||||||
|
uint64_t last_reserve_in_serial_id,
|
||||||
|
uint64_t last_reserve_out_serial_id,
|
||||||
|
uint64_t last_deposit_serial_id,
|
||||||
|
uint64_t last_melt_serial_id,
|
||||||
|
uint64_t last_refund_serial_id,
|
||||||
|
uint64_t last_prewire_serial_id);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update information about the progress of the auditor. There
|
||||||
|
* must be an existing record for the exchange.
|
||||||
|
*
|
||||||
|
* @param cls the @e cls of this struct with the plugin-specific state
|
||||||
|
* @param session connection to use
|
||||||
|
* @param master_pub master key of the exchange
|
||||||
|
* @param last_reserve_in_serial_id serial ID of the last reserve_in transfer the auditor processed
|
||||||
|
* @param last_reserve_out_serial_id serial ID of the last withdraw the auditor processed
|
||||||
|
* @param last_deposit_serial_id serial ID of the last deposit the auditor processed
|
||||||
|
* @param last_melt_serial_id serial ID of the last refresh the auditor processed
|
||||||
|
* @param last_prewire_serial_id serial ID of the last prewire transfer the auditor processed
|
||||||
|
* @return #GNUNET_OK on success; #GNUNET_SYSERR on failure
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
(*update_auditor_progress)(void *cls,
|
||||||
|
struct TALER_AUDITORDB_Session *session,
|
||||||
|
const struct TALER_MasterPublicKeyP *master_pub,
|
||||||
|
uint64_t last_reserve_in_serial_id,
|
||||||
|
uint64_t last_reserve_out_serial_id,
|
||||||
|
uint64_t last_deposit_serial_id,
|
||||||
|
uint64_t last_melt_serial_id,
|
||||||
|
uint64_t last_refund_serial_id,
|
||||||
|
uint64_t last_prewire_serial_id);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get information about the progress of the auditor.
|
||||||
|
*
|
||||||
|
* @param cls the @e cls of this struct with the plugin-specific state
|
||||||
|
* @param session connection to use
|
||||||
|
* @param master_pub master key of the exchange
|
||||||
|
* @param[out] last_reserve_in_serial_id serial ID of the last reserve_in transfer the auditor processed
|
||||||
|
* @param[out] last_reserve_out_serial_id serial ID of the last withdraw the auditor processed
|
||||||
|
* @param[out] last_deposit_serial_id serial ID of the last deposit the auditor processed
|
||||||
|
* @param[out] last_melt_serial_id serial ID of the last refresh the auditor processed
|
||||||
|
* @param[out] last_prewire_serial_id serial ID of the last prewire transfer the auditor processed
|
||||||
|
* @return #GNUNET_OK on success; #GNUNET_SYSERR on failure;
|
||||||
|
* #GNUNET_NO if we have no records for the @a master_pub
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
(*get_auditor_progress)(void *cls,
|
||||||
|
struct TALER_AUDITORDB_Session *session,
|
||||||
|
const struct TALER_MasterPublicKeyP *master_pub,
|
||||||
|
uint64_t *last_reserve_in_serial_id,
|
||||||
|
uint64_t *last_reserve_out_serial_id,
|
||||||
|
uint64_t *last_deposit_serial_id,
|
||||||
|
uint64_t *last_melt_serial_id,
|
||||||
|
uint64_t *last_refund_serial_id,
|
||||||
|
uint64_t *last_prewire_serial_id);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Insert information about a reserve. There must not be an
|
* Insert information about a reserve. There must not be an
|
||||||
* existing record for the reserve.
|
* existing record for the reserve.
|
||||||
@ -586,7 +748,7 @@ struct TALER_AUDITORDB_Plugin
|
|||||||
(*select_historic_denom_revenue)(void *cls,
|
(*select_historic_denom_revenue)(void *cls,
|
||||||
struct TALER_AUDITORDB_Session *session,
|
struct TALER_AUDITORDB_Session *session,
|
||||||
const struct TALER_MasterPublicKeyP *master_pub,
|
const struct TALER_MasterPublicKeyP *master_pub,
|
||||||
void *cb, /* FIXME: fix type */
|
TALER_AUDITORDB_HistoricDenominationRevenueDataCallback cb,
|
||||||
void *cb_cls);
|
void *cb_cls);
|
||||||
|
|
||||||
|
|
||||||
@ -628,7 +790,7 @@ struct TALER_AUDITORDB_Plugin
|
|||||||
(*select_historic_losses)(void *cls,
|
(*select_historic_losses)(void *cls,
|
||||||
struct TALER_AUDITORDB_Session *session,
|
struct TALER_AUDITORDB_Session *session,
|
||||||
const struct TALER_MasterPublicKeyP *master_pub,
|
const struct TALER_MasterPublicKeyP *master_pub,
|
||||||
void *cb, /* FIXME: fix type */
|
TALER_AUDITORDB_HistoricLossesDataCallback cb,
|
||||||
void *cb_cls);
|
void *cb_cls);
|
||||||
|
|
||||||
|
|
||||||
@ -666,7 +828,7 @@ struct TALER_AUDITORDB_Plugin
|
|||||||
(*select_historic_reserve_revenue)(void *cls,
|
(*select_historic_reserve_revenue)(void *cls,
|
||||||
struct TALER_AUDITORDB_Session *session,
|
struct TALER_AUDITORDB_Session *session,
|
||||||
const struct TALER_MasterPublicKeyP *master_pub,
|
const struct TALER_MasterPublicKeyP *master_pub,
|
||||||
void *cb, /* FIXME: type */
|
TALER_AUDITORDB_HistoricReserveRevenueDataCallback cb,
|
||||||
void *cb_cls);
|
void *cb_cls);
|
||||||
|
|
||||||
|
|
||||||
@ -721,6 +883,7 @@ struct TALER_AUDITORDB_Plugin
|
|||||||
const struct TALER_MasterPublicKeyP *master_pub,
|
const struct TALER_MasterPublicKeyP *master_pub,
|
||||||
struct TALER_Amount *balance);
|
struct TALER_Amount *balance);
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
#include <jansson.h>
|
#include <jansson.h>
|
||||||
#include "taler_util.h"
|
#include "taler_util.h"
|
||||||
|
#include "taler_error_codes.h"
|
||||||
#include <gnunet/gnunet_curl_lib.h>
|
#include <gnunet/gnunet_curl_lib.h>
|
||||||
|
|
||||||
|
|
||||||
@ -355,6 +356,7 @@ struct TALER_EXCHANGE_WireHandle;
|
|||||||
* @param cls closure
|
* @param cls closure
|
||||||
* @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful request;
|
* @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful request;
|
||||||
* 0 if the exchange's reply is bogus (fails to follow the protocol)
|
* 0 if the exchange's reply is bogus (fails to follow the protocol)
|
||||||
|
* @param ec taler-specific error code, #TALER_EC_NONE on success
|
||||||
* @param obj the received JSON reply, if successful this should be the wire
|
* @param obj the received JSON reply, if successful this should be the wire
|
||||||
* format details as provided by /wire, or NULL if the
|
* format details as provided by /wire, or NULL if the
|
||||||
* reply was not in JSON format.
|
* reply was not in JSON format.
|
||||||
@ -362,6 +364,7 @@ struct TALER_EXCHANGE_WireHandle;
|
|||||||
typedef void
|
typedef void
|
||||||
(*TALER_EXCHANGE_WireResultCallback) (void *cls,
|
(*TALER_EXCHANGE_WireResultCallback) (void *cls,
|
||||||
unsigned int http_status,
|
unsigned int http_status,
|
||||||
|
enum TALER_ErrorCode ec,
|
||||||
const json_t *obj);
|
const json_t *obj);
|
||||||
|
|
||||||
|
|
||||||
@ -423,6 +426,7 @@ struct TALER_EXCHANGE_DepositHandle;
|
|||||||
typedef void
|
typedef void
|
||||||
(*TALER_EXCHANGE_DepositResultCallback) (void *cls,
|
(*TALER_EXCHANGE_DepositResultCallback) (void *cls,
|
||||||
unsigned int http_status,
|
unsigned int http_status,
|
||||||
|
enum TALER_ErrorCode ec,
|
||||||
const struct TALER_ExchangePublicKeyP *sign_key,
|
const struct TALER_ExchangePublicKeyP *sign_key,
|
||||||
const json_t *obj);
|
const json_t *obj);
|
||||||
|
|
||||||
@ -504,6 +508,7 @@ struct TALER_EXCHANGE_RefundHandle;
|
|||||||
* @param cls closure
|
* @param cls closure
|
||||||
* @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful deposit;
|
* @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful deposit;
|
||||||
* 0 if the exchange's reply is bogus (fails to follow the protocol)
|
* 0 if the exchange's reply is bogus (fails to follow the protocol)
|
||||||
|
* @param ec taler-specific error code, #TALER_EC_NONE on success
|
||||||
* @param sign_key exchange key used to sign @a obj, or NULL
|
* @param sign_key exchange key used to sign @a obj, or NULL
|
||||||
* @param obj the received JSON reply, should be kept as proof (and, in particular,
|
* @param obj the received JSON reply, should be kept as proof (and, in particular,
|
||||||
* be forwarded to the customer)
|
* be forwarded to the customer)
|
||||||
@ -511,6 +516,7 @@ struct TALER_EXCHANGE_RefundHandle;
|
|||||||
typedef void
|
typedef void
|
||||||
(*TALER_EXCHANGE_RefundResultCallback) (void *cls,
|
(*TALER_EXCHANGE_RefundResultCallback) (void *cls,
|
||||||
unsigned int http_status,
|
unsigned int http_status,
|
||||||
|
enum TALER_ErrorCode ec,
|
||||||
const struct TALER_ExchangePublicKeyP *sign_key,
|
const struct TALER_ExchangePublicKeyP *sign_key,
|
||||||
const json_t *obj);
|
const json_t *obj);
|
||||||
|
|
||||||
@ -650,6 +656,7 @@ struct TALER_EXCHANGE_ReserveHistory
|
|||||||
* @param cls closure
|
* @param cls closure
|
||||||
* @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful status request
|
* @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful status request
|
||||||
* 0 if the exchange's reply is bogus (fails to follow the protocol)
|
* 0 if the exchange's reply is bogus (fails to follow the protocol)
|
||||||
|
* @param ec taler-specific error code, #TALER_EC_NONE on success
|
||||||
* @param[in] json original response in JSON format (useful only for diagnostics)
|
* @param[in] json original response in JSON format (useful only for diagnostics)
|
||||||
* @param balance current balance in the reserve, NULL on error
|
* @param balance current balance in the reserve, NULL on error
|
||||||
* @param history_length number of entries in the transaction history, 0 on error
|
* @param history_length number of entries in the transaction history, 0 on error
|
||||||
@ -658,6 +665,7 @@ struct TALER_EXCHANGE_ReserveHistory
|
|||||||
typedef void
|
typedef void
|
||||||
(*TALER_EXCHANGE_ReserveStatusResultCallback) (void *cls,
|
(*TALER_EXCHANGE_ReserveStatusResultCallback) (void *cls,
|
||||||
unsigned int http_status,
|
unsigned int http_status,
|
||||||
|
enum TALER_ErrorCode ec,
|
||||||
const json_t *json,
|
const json_t *json,
|
||||||
const struct TALER_Amount *balance,
|
const struct TALER_Amount *balance,
|
||||||
unsigned int history_length,
|
unsigned int history_length,
|
||||||
@ -713,12 +721,14 @@ struct TALER_EXCHANGE_ReserveWithdrawHandle;
|
|||||||
* @param cls closure
|
* @param cls closure
|
||||||
* @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful status request
|
* @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful status request
|
||||||
* 0 if the exchange's reply is bogus (fails to follow the protocol)
|
* 0 if the exchange's reply is bogus (fails to follow the protocol)
|
||||||
|
* @param ec taler-specific error code, #TALER_EC_NONE on success
|
||||||
* @param sig signature over the coin, NULL on error
|
* @param sig signature over the coin, NULL on error
|
||||||
* @param full_response full response from the exchange (for logging, in case of errors)
|
* @param full_response full response from the exchange (for logging, in case of errors)
|
||||||
*/
|
*/
|
||||||
typedef void
|
typedef void
|
||||||
(*TALER_EXCHANGE_ReserveWithdrawResultCallback) (void *cls,
|
(*TALER_EXCHANGE_ReserveWithdrawResultCallback) (void *cls,
|
||||||
unsigned int http_status,
|
unsigned int http_status,
|
||||||
|
enum TALER_ErrorCode ec,
|
||||||
const struct TALER_DenominationSignature *sig,
|
const struct TALER_DenominationSignature *sig,
|
||||||
const json_t *full_response);
|
const json_t *full_response);
|
||||||
|
|
||||||
@ -835,6 +845,7 @@ struct TALER_EXCHANGE_RefreshMeltHandle;
|
|||||||
* @param cls closure
|
* @param cls closure
|
||||||
* @param http_status HTTP response code, never #MHD_HTTP_OK (200) as for successful intermediate response this callback is skipped.
|
* @param http_status HTTP response code, never #MHD_HTTP_OK (200) as for successful intermediate response this callback is skipped.
|
||||||
* 0 if the exchange's reply is bogus (fails to follow the protocol)
|
* 0 if the exchange's reply is bogus (fails to follow the protocol)
|
||||||
|
* @param ec taler-specific error code, #TALER_EC_NONE on success
|
||||||
* @param noreveal_index choice by the exchange in the cut-and-choose protocol,
|
* @param noreveal_index choice by the exchange in the cut-and-choose protocol,
|
||||||
* UINT16_MAX on error
|
* UINT16_MAX on error
|
||||||
* @param sign_key exchange key used to sign @a full_response, or NULL
|
* @param sign_key exchange key used to sign @a full_response, or NULL
|
||||||
@ -843,7 +854,8 @@ struct TALER_EXCHANGE_RefreshMeltHandle;
|
|||||||
typedef void
|
typedef void
|
||||||
(*TALER_EXCHANGE_RefreshMeltCallback) (void *cls,
|
(*TALER_EXCHANGE_RefreshMeltCallback) (void *cls,
|
||||||
unsigned int http_status,
|
unsigned int http_status,
|
||||||
uint16_t noreveal_index,
|
enum TALER_ErrorCode ec,
|
||||||
|
uint16_t noreveal_index,
|
||||||
const struct TALER_ExchangePublicKeyP *sign_key,
|
const struct TALER_ExchangePublicKeyP *sign_key,
|
||||||
const json_t *full_response);
|
const json_t *full_response);
|
||||||
|
|
||||||
@ -900,6 +912,7 @@ TALER_EXCHANGE_refresh_melt_cancel (struct TALER_EXCHANGE_RefreshMeltHandle *rmh
|
|||||||
* @param cls closure
|
* @param cls closure
|
||||||
* @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful status request
|
* @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful status request
|
||||||
* 0 if the exchange's reply is bogus (fails to follow the protocol)
|
* 0 if the exchange's reply is bogus (fails to follow the protocol)
|
||||||
|
* @param ec taler-specific error code, #TALER_EC_NONE on success
|
||||||
* @param num_coins number of fresh coins created, length of the @a sigs and @a coin_privs arrays, 0 if the operation failed
|
* @param num_coins number of fresh coins created, length of the @a sigs and @a coin_privs arrays, 0 if the operation failed
|
||||||
* @param coin_privs array of @a num_coins private keys for the coins that were created, NULL on error
|
* @param coin_privs array of @a num_coins private keys for the coins that were created, NULL on error
|
||||||
* @param sigs array of signature over @a num_coins coins, NULL on error
|
* @param sigs array of signature over @a num_coins coins, NULL on error
|
||||||
@ -908,6 +921,7 @@ TALER_EXCHANGE_refresh_melt_cancel (struct TALER_EXCHANGE_RefreshMeltHandle *rmh
|
|||||||
typedef void
|
typedef void
|
||||||
(*TALER_EXCHANGE_RefreshRevealCallback) (void *cls,
|
(*TALER_EXCHANGE_RefreshRevealCallback) (void *cls,
|
||||||
unsigned int http_status,
|
unsigned int http_status,
|
||||||
|
enum TALER_ErrorCode ec,
|
||||||
unsigned int num_coins,
|
unsigned int num_coins,
|
||||||
const struct TALER_CoinSpendPrivateKeyP *coin_privs,
|
const struct TALER_CoinSpendPrivateKeyP *coin_privs,
|
||||||
const struct TALER_DenominationSignature *sigs,
|
const struct TALER_DenominationSignature *sigs,
|
||||||
@ -979,6 +993,7 @@ struct TALER_EXCHANGE_RefreshLinkHandle;
|
|||||||
* @param cls closure
|
* @param cls closure
|
||||||
* @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful status request
|
* @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful status request
|
||||||
* 0 if the exchange's reply is bogus (fails to follow the protocol)
|
* 0 if the exchange's reply is bogus (fails to follow the protocol)
|
||||||
|
* @param ec taler-specific error code, #TALER_EC_NONE on success
|
||||||
* @param num_coins number of fresh coins created, length of the @a sigs and @a coin_privs arrays, 0 if the operation failed
|
* @param num_coins number of fresh coins created, length of the @a sigs and @a coin_privs arrays, 0 if the operation failed
|
||||||
* @param coin_privs array of @a num_coins private keys for the coins that were created, NULL on error
|
* @param coin_privs array of @a num_coins private keys for the coins that were created, NULL on error
|
||||||
* @param sigs array of signature over @a num_coins coins, NULL on error
|
* @param sigs array of signature over @a num_coins coins, NULL on error
|
||||||
@ -988,6 +1003,7 @@ struct TALER_EXCHANGE_RefreshLinkHandle;
|
|||||||
typedef void
|
typedef void
|
||||||
(*TALER_EXCHANGE_RefreshLinkCallback) (void *cls,
|
(*TALER_EXCHANGE_RefreshLinkCallback) (void *cls,
|
||||||
unsigned int http_status,
|
unsigned int http_status,
|
||||||
|
enum TALER_ErrorCode ec,
|
||||||
unsigned int num_coins,
|
unsigned int num_coins,
|
||||||
const struct TALER_CoinSpendPrivateKeyP *coin_privs,
|
const struct TALER_CoinSpendPrivateKeyP *coin_privs,
|
||||||
const struct TALER_DenominationSignature *sigs,
|
const struct TALER_DenominationSignature *sigs,
|
||||||
@ -1043,11 +1059,13 @@ struct TALER_EXCHANGE_AdminAddIncomingHandle;
|
|||||||
* @param cls closure
|
* @param cls closure
|
||||||
* @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful status request
|
* @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful status request
|
||||||
* 0 if the exchange's reply is bogus (fails to follow the protocol)
|
* 0 if the exchange's reply is bogus (fails to follow the protocol)
|
||||||
|
* @param ec taler-specific error code, #TALER_EC_NONE on success
|
||||||
* @param full_response full response from the exchange (for logging, in case of errors)
|
* @param full_response full response from the exchange (for logging, in case of errors)
|
||||||
*/
|
*/
|
||||||
typedef void
|
typedef void
|
||||||
(*TALER_EXCHANGE_AdminAddIncomingResultCallback) (void *cls,
|
(*TALER_EXCHANGE_AdminAddIncomingResultCallback) (void *cls,
|
||||||
unsigned int http_status,
|
unsigned int http_status,
|
||||||
|
enum TALER_ErrorCode ec,
|
||||||
const json_t *full_response);
|
const json_t *full_response);
|
||||||
|
|
||||||
|
|
||||||
@ -1108,6 +1126,7 @@ struct TALER_EXCHANGE_TrackTransferHandle;
|
|||||||
*
|
*
|
||||||
* @param cls closure
|
* @param cls closure
|
||||||
* @param http_status HTTP status code we got, 0 on exchange protocol violation
|
* @param http_status HTTP status code we got, 0 on exchange protocol violation
|
||||||
|
* @param ec taler-specific error code, #TALER_EC_NONE on success
|
||||||
* @param sign_key exchange key used to sign @a json, or NULL
|
* @param sign_key exchange key used to sign @a json, or NULL
|
||||||
* @param json original json reply (may include signatures, those have then been
|
* @param json original json reply (may include signatures, those have then been
|
||||||
* validated already)
|
* validated already)
|
||||||
@ -1121,6 +1140,7 @@ struct TALER_EXCHANGE_TrackTransferHandle;
|
|||||||
typedef void
|
typedef void
|
||||||
(*TALER_EXCHANGE_TrackTransferCallback)(void *cls,
|
(*TALER_EXCHANGE_TrackTransferCallback)(void *cls,
|
||||||
unsigned int http_status,
|
unsigned int http_status,
|
||||||
|
enum TALER_ErrorCode ec,
|
||||||
const struct TALER_ExchangePublicKeyP *sign_key,
|
const struct TALER_ExchangePublicKeyP *sign_key,
|
||||||
const json_t *json,
|
const json_t *json,
|
||||||
const struct GNUNET_HashCode *h_wire,
|
const struct GNUNET_HashCode *h_wire,
|
||||||
@ -1171,6 +1191,7 @@ struct TALER_EXCHANGE_TrackTransactionHandle;
|
|||||||
*
|
*
|
||||||
* @param cls closure
|
* @param cls closure
|
||||||
* @param http_status HTTP status code we got, 0 on exchange protocol violation
|
* @param http_status HTTP status code we got, 0 on exchange protocol violation
|
||||||
|
* @param ec taler-specific error code, #TALER_EC_NONE on success
|
||||||
* @param sign_key exchange key used to sign @a json, or NULL
|
* @param sign_key exchange key used to sign @a json, or NULL
|
||||||
* @param json original json reply (may include signatures, those have then been
|
* @param json original json reply (may include signatures, those have then been
|
||||||
* validated already)
|
* validated already)
|
||||||
@ -1182,6 +1203,7 @@ struct TALER_EXCHANGE_TrackTransactionHandle;
|
|||||||
typedef void
|
typedef void
|
||||||
(*TALER_EXCHANGE_TrackTransactionCallback)(void *cls,
|
(*TALER_EXCHANGE_TrackTransactionCallback)(void *cls,
|
||||||
unsigned int http_status,
|
unsigned int http_status,
|
||||||
|
enum TALER_ErrorCode ec,
|
||||||
const struct TALER_ExchangePublicKeyP *sign_key,
|
const struct TALER_ExchangePublicKeyP *sign_key,
|
||||||
const json_t *json,
|
const json_t *json,
|
||||||
const struct TALER_WireTransferIdentifierRawP *wtid,
|
const struct TALER_WireTransferIdentifierRawP *wtid,
|
||||||
@ -1240,4 +1262,5 @@ TALER_EXCHANGE_verify_coin_history (const char *currency,
|
|||||||
json_t *history,
|
json_t *history,
|
||||||
struct TALER_Amount *total);
|
struct TALER_Amount *total);
|
||||||
|
|
||||||
|
|
||||||
#endif /* _TALER_EXCHANGE_SERVICE_H */
|
#endif /* _TALER_EXCHANGE_SERVICE_H */
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include <jansson.h>
|
#include <jansson.h>
|
||||||
#include <gnunet/gnunet_json_lib.h>
|
#include <gnunet/gnunet_json_lib.h>
|
||||||
#include "taler_util.h"
|
#include "taler_util.h"
|
||||||
|
#include "taler_error_codes.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Print JSON parsing related error information
|
* Print JSON parsing related error information
|
||||||
@ -92,6 +93,17 @@ int
|
|||||||
TALER_JSON_hash (const json_t *json,
|
TALER_JSON_hash (const json_t *json,
|
||||||
struct GNUNET_HashCode *hc);
|
struct GNUNET_HashCode *hc);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract the Taler error code from the given @a json object.
|
||||||
|
* Note that #TALER_EC_NONE is returned if no "code" is present.
|
||||||
|
*
|
||||||
|
* @param json response to extract the error code from
|
||||||
|
* @return the "code" value from @a json
|
||||||
|
*/
|
||||||
|
enum TALER_ErrorCode
|
||||||
|
TALER_JSON_get_error_code (const json_t *json);
|
||||||
|
|
||||||
|
|
||||||
#endif /* TALER_JSON_LIB_H_ */
|
#endif /* TALER_JSON_LIB_H_ */
|
||||||
|
|
||||||
/* End of taler_json_lib.h */
|
/* End of taler_json_lib.h */
|
||||||
|
@ -117,4 +117,6 @@ const struct GNUNET_OS_ProjectData *
|
|||||||
TALER_project_data_default (void);
|
TALER_project_data_default (void);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -50,4 +50,33 @@ TALER_JSON_hash (const json_t *json,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract the Taler error code from the given @a json object.
|
||||||
|
* Note that #TALER_EC_NONE is returned if no "code" is present.
|
||||||
|
*
|
||||||
|
* @param json response to extract the error code from
|
||||||
|
* @return the "code" value from @a json
|
||||||
|
*/
|
||||||
|
enum TALER_ErrorCode
|
||||||
|
TALER_JSON_get_error_code (const json_t *json)
|
||||||
|
{
|
||||||
|
const json_t *jc;
|
||||||
|
|
||||||
|
if (NULL == json)
|
||||||
|
{
|
||||||
|
GNUNET_break_op (0);
|
||||||
|
return TALER_EC_INVALID_RESPONSE;
|
||||||
|
}
|
||||||
|
jc = json_object_get (json, "code");
|
||||||
|
if (NULL == jc)
|
||||||
|
return TALER_EC_NONE;
|
||||||
|
if (json_is_integer (jc))
|
||||||
|
return (enum TALER_ErrorCode) json_integer_value (jc);
|
||||||
|
GNUNET_break_op (0);
|
||||||
|
return TALER_EC_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* End of json/json.c */
|
/* End of json/json.c */
|
||||||
|
61
taler-exchange-dev.nix
Normal file
61
taler-exchange-dev.nix
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
{ stdenv, makeWrapper, pkgconfig, autoconf, automake, libtool, ccache, ccache_dir ? ""
|
||||||
|
, gnunet-dev, postgresql, jansson, libgcrypt, libgnurl, libmicrohttpd }:
|
||||||
|
|
||||||
|
stdenv.mkDerivation rec {
|
||||||
|
src = ./.;
|
||||||
|
name = "taler-exchange-dev";
|
||||||
|
|
||||||
|
buildInputs = [
|
||||||
|
makeWrapper pkgconfig autoconf automake libtool ccache
|
||||||
|
gnunet-dev postgresql jansson libgcrypt libgnurl libmicrohttpd
|
||||||
|
];
|
||||||
|
|
||||||
|
patchPhase = ''
|
||||||
|
if [ -e Makefile ]; then
|
||||||
|
make distclean
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
|
||||||
|
NIX_CFLAGS_COMPILE = "-ggdb -O0";
|
||||||
|
|
||||||
|
configureFlags = [
|
||||||
|
"--enable-gcc-hardening"
|
||||||
|
"--enable-linker-hardening"
|
||||||
|
|
||||||
|
"--enable-logging=verbose"
|
||||||
|
"--enable-poisoning"
|
||||||
|
];
|
||||||
|
|
||||||
|
preConfigure = ''
|
||||||
|
./bootstrap
|
||||||
|
|
||||||
|
if [ -n "${ccache_dir}" ]; then
|
||||||
|
export CC='ccache gcc'
|
||||||
|
export CCACHE_COMPRESS=1
|
||||||
|
export CCACHE_DIR="${ccache_dir}"
|
||||||
|
export CCACHE_UMASK=007
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
|
||||||
|
doCheck = false;
|
||||||
|
|
||||||
|
postInstall = ''
|
||||||
|
# Tests can be run this way
|
||||||
|
#export GNUNET_PREFIX="$out"
|
||||||
|
#export PATH="$out/bin:$PATH"
|
||||||
|
#make -k check
|
||||||
|
'';
|
||||||
|
|
||||||
|
meta = with stdenv.lib; {
|
||||||
|
description = "Exchange for GNU Taler";
|
||||||
|
|
||||||
|
longDescription = ''
|
||||||
|
'';
|
||||||
|
|
||||||
|
homepage = https://taler.net/;
|
||||||
|
|
||||||
|
license = licenses.gpl3Plus;
|
||||||
|
platforms = platforms.gnu;
|
||||||
|
maintainers = with maintainers; [ ];
|
||||||
|
};
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user