Compare commits
27 Commits
47620fa81b
...
e0f78bc3c9
Author | SHA1 | Date | |
---|---|---|---|
e0f78bc3c9 | |||
4ebdcc0247 | |||
8a7bfefa38 | |||
88ecba945e | |||
|
43d5e5707c | ||
|
1e572ebcab | ||
|
c6676f1aa5 | ||
|
6c44755458 | ||
|
6a483b51ec | ||
|
66f9a5b5e5 | ||
|
f4abc1c369 | ||
|
c57c3463d1 | ||
8d6b0944da | |||
6107e99559 | |||
3024dc9fa5 | |||
9d706a01a2 | |||
|
c05f832048 | ||
|
1026a32c71 | ||
7e9f5324b7 | |||
|
c02d88c8e3 | ||
|
11ea6fcfce | ||
|
f2c3443860 | ||
|
95c05a8827 | ||
|
40dfb94e0f | ||
|
1db17d43bd | ||
|
999db0fb80 | ||
|
ff8349e6e7 |
@ -1 +1 @@
|
||||
Subproject commit 31b74264e62c4a7f4a671033e214c43fa2f304c0
|
||||
Subproject commit 86b36917a59cc46961a9c9042b1af75a88545558
|
@ -85,7 +85,7 @@ CREATE_SUBDIRS = YES
|
||||
# level increment doubles the number of directories, resulting in 4096
|
||||
# directories at level 8 which is the default and also the maximum value. The
|
||||
# sub-directories are organized in 2 levels, the first level always has a fixed
|
||||
# numer of 16 directories.
|
||||
# number of 16 directories.
|
||||
# Minimum value: 0, maximum value: 8, default value: 8.
|
||||
# This tag requires that the tag CREATE_SUBDIRS is set to YES.
|
||||
|
||||
|
@ -40,7 +40,7 @@ The main interactions of the system are:
|
||||
\item[shutdown] the Taler payment system operator informs the customers that the system is being shut down for good
|
||||
\end{description}
|
||||
|
||||
In the analysis of the legal requirements, it is important to differenciate
|
||||
In the analysis of the legal requirements, it is important to differentiate
|
||||
between transactions between wallets (customer-to-customer) and transactions
|
||||
where money flows from a wallet into a bank account (customer-to-merchant) as
|
||||
these have different limits: When digital coins are used to pay at a business in
|
||||
|
@ -43,8 +43,8 @@
|
||||
\end{figure}
|
||||
|
||||
At the beginning of the KYB process, the user needs to specify whether they
|
||||
are an {\bf individual} (not incorporated) or a {\bf business}.\footnote{ In
|
||||
pratice, we expect most owners of bank accounts crossing the KYB threshold to
|
||||
are an {\bf individual} (not incorporated) or a {\bf business}.\footnote{In
|
||||
practice, we expect most owners of bank accounts crossing the KYB threshold to
|
||||
be businesses, but in principle such a bank account could be owned by an
|
||||
individual operating a business without a separate legal entity.} This then
|
||||
determines which types of attributes are collected in the KYB process
|
||||
|
@ -43,7 +43,7 @@
|
||||
\end{figure}
|
||||
|
||||
At the beginning of the KYC process, the user needs to specify whether they
|
||||
are an {\bf individual} or a {\bf business}.\footnote{ In pratice, we expect
|
||||
are an {\bf individual} or a {\bf business}.\footnote{ In practice, we expect
|
||||
most wallet-users to be individuals, but in principle a wallet could be owned
|
||||
by a business.} This then determines which types of attributes are collected
|
||||
in the KYC process (Table~\ref{table:proc:kyc:individual} vs.
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 66e99d09d4351bb6e6c5fd442f14ec7cf1363a81
|
||||
Subproject commit fa4729db5637c82d5fc6f5bb7021f6c350c8c5a6
|
@ -218,6 +218,7 @@ EXTRA_DIST = \
|
||||
taler-auditor.in \
|
||||
taler-helper-auditor-render.py \
|
||||
auditor.conf \
|
||||
setup.sh \
|
||||
test-sync-in.conf \
|
||||
test-sync-out.conf \
|
||||
generate-auditor-basedb.sh \
|
||||
|
@ -1,14 +1,27 @@
|
||||
[exchange-offline]
|
||||
MASTER_PRIV_FILE = auditor-basedb.mpriv
|
||||
[PATHS]
|
||||
TALER_CACHE_HOME = $TALER_HOME/.cache/taler/
|
||||
TALER_CONFIG_HOME = $TALER_HOME/.config/taler/
|
||||
TALER_DATA_HOME = $TALER_HOME/.local/share/taler/
|
||||
TALER_HOME = ${PWD}/generate_auditordb_home/
|
||||
|
||||
[instance-default]
|
||||
KEYFILE = ${TALER_DATA_HOME}/merchant/default.priv
|
||||
NAME = Merchant Inc.
|
||||
[taler]
|
||||
CURRENCY = TESTKUDOS
|
||||
CURRENCY_ROUND_UNIT = TESTKUDOS:0.01
|
||||
|
||||
[exchange]
|
||||
MASTER_PUBLIC_KEY = M4FGP18EQFXFGGFQ1AWXHACN2JX0SMVK9CNF6459Z1WG18JSN0BG
|
||||
SIGNKEY_DURATION = 4 weeks
|
||||
LOOKAHEAD_SIGN = 32 weeks 1 day
|
||||
SIGNKEY_LEGAL_DURATION = 4 weeks
|
||||
AML_THRESHOLD = TESTKUDOS:1000000
|
||||
|
||||
[exchangedb-postgres]
|
||||
CONFIG = postgres:///auditor-basedb
|
||||
|
||||
[exchange-account-1]
|
||||
PAYTO_URI = payto://iban/SANDBOXX/DE989651?receiver-name=Exchange+Company
|
||||
enable_debit = yes
|
||||
enable_credit = yes
|
||||
ENABLE_DEBIT = YES
|
||||
ENABLE_CREDIT = YES
|
||||
|
||||
[exchange-accountcredentials-1]
|
||||
WIRE_GATEWAY_URL = http://localhost:8082/facades/test-facade/taler-wire-gateway/
|
||||
@ -16,24 +29,38 @@ WIRE_GATEWAY_AUTH_METHOD = basic
|
||||
USERNAME = exchange
|
||||
PASSWORD = x
|
||||
|
||||
[merchant-account-merchant]
|
||||
PAYTO_URI = payto://x-taler-bank/localhost/42
|
||||
HONOR_default = YES
|
||||
ACTIVE_default = YES
|
||||
[merchant]
|
||||
WIREFORMAT = default
|
||||
DEFAULT_MAX_DEPOSIT_FEE = TESTKUDOS:0.1
|
||||
KEYFILE = ${TALER_DATA_HOME}/merchant/merchant.priv
|
||||
DEFAULT_MAX_WIRE_FEE = TESTKUDOS:0.10
|
||||
WIRE_TRANSFER_DELAY = 1 minute
|
||||
FORCE_AUDIT = YES
|
||||
|
||||
[merchantdb-postgres]
|
||||
CONFIG = postgres:///auditor-basedb
|
||||
|
||||
[merchant-exchange-default]
|
||||
MASTER_KEY = RKNMPRGXCX35H11WEYXDXYHPR7NX2QK9BG15MT0QEF75PC5KR470
|
||||
MASTER_KEY = M4FGP18EQFXFGGFQ1AWXHACN2JX0SMVK9CNF6459Z1WG18JSN0BG
|
||||
EXCHANGE_BASE_URL = http://localhost:8081/
|
||||
CURRENCY = TESTKUDOS
|
||||
|
||||
[payments-generator]
|
||||
currency = TESTKUDOS
|
||||
instance = default
|
||||
bank = http://localhost:8082/
|
||||
merchant = http://localhost:9966/
|
||||
exchange_admin = http://localhost:18080/
|
||||
exchange-admin = http://localhost:18080/
|
||||
exchange = http://localhost:8081/
|
||||
[bank]
|
||||
HTTP_PORT = 8082
|
||||
|
||||
[libeufin-nexus]
|
||||
DB_CONNECTION="jdbc:postgresql://localhost/auditor-basedb?socketFactory=org.newsclub.net.unix.AFUNIXSocketFactory$FactoryArg&socketFactoryArg=/var/run/postgresql/.s.PGSQL.5432"
|
||||
|
||||
[libeufin-sandbox]
|
||||
DB_CONNECTION="jdbc:postgresql://localhost/auditor-basedb?socketFactory=org.newsclub.net.unix.AFUNIXSocketFactory$FactoryArg&socketFactoryArg=/var/run/postgresql/.s.PGSQL.5432"
|
||||
|
||||
[auditor]
|
||||
BASE_URL = http://localhost:8083/
|
||||
TINY_AMOUNT = TESTKUDOS:0.01
|
||||
PUBLIC_KEY = 0EHPW5WEKHXPPN4MPJNGA7Z6D29JP21GKVNV8ARFB1YW7WWJX20G
|
||||
|
||||
[auditordb-postgres]
|
||||
CONFIG = postgres:///auditor-basedb
|
||||
|
||||
[coin_kudos_ct_1]
|
||||
value = TESTKUDOS:0.01
|
||||
@ -130,61 +157,3 @@ fee_refresh = TESTKUDOS:0.03
|
||||
fee_refund = TESTKUDOS:0.01
|
||||
CIPHER = RSA
|
||||
rsa_keysize = 1024
|
||||
|
||||
[benchmark]
|
||||
BANK_DETAILS = bank_details.json
|
||||
MERCHANT_DETAILS = merchant_details.json
|
||||
|
||||
[arm]
|
||||
CONFIG = /research/taler/exchange/src/auditor/auditor-basedb.conf
|
||||
|
||||
[taler]
|
||||
CURRENCY_ROUND_UNIT = TESTKUDOS:0.01
|
||||
CURRENCY = TESTKUDOS
|
||||
AML_THRESHOLD = TESTKUDOS:1000000
|
||||
|
||||
[merchantdb-postgres]
|
||||
CONFIG = postgres:///auditor-basedb
|
||||
|
||||
[merchant]
|
||||
WIREFORMAT = default
|
||||
DEFAULT_MAX_DEPOSIT_FEE = TESTKUDOS:0.1
|
||||
KEYFILE = ${TALER_DATA_HOME}/merchant/merchant.priv
|
||||
DEFAULT_MAX_WIRE_FEE = TESTKUDOS:0.10
|
||||
WIRE_TRANSFER_DELAY = 1 minute
|
||||
FORCE_AUDIT = YES
|
||||
UNIXPATH = ${TALER_RUNTIME_DIR}/merchant.http
|
||||
|
||||
[exchangedb-postgres]
|
||||
CONFIG = postgres:///auditor-basedb
|
||||
|
||||
[exchange]
|
||||
MASTER_PUBLIC_KEY = RKNMPRGXCX35H11WEYXDXYHPR7NX2QK9BG15MT0QEF75PC5KR470
|
||||
SIGNKEY_DURATION = 4 weeks
|
||||
LOOKAHEAD_SIGN = 32 weeks 1 day
|
||||
SIGNKEY_LEGAL_DURATION = 4 weeks
|
||||
UNIXPATH = ${TALER_RUNTIME_DIR}/exchange.http
|
||||
|
||||
[bank]
|
||||
HTTP_PORT = 8082
|
||||
SUGGESTED_EXCHANGE = http://localhost:8081/
|
||||
SUGGESTED_EXCHANGE_PAYTO = payto://x-taler-bank/localhost/2
|
||||
ALLOW_REGISTRATIONS = YES
|
||||
SERVE = http
|
||||
MAX_DEBT_BANK = TESTKUDOS:100000.0
|
||||
MAX_DEBT = TESTKUDOS:50.0
|
||||
DATABASE = postgres:///auditor-basedb
|
||||
|
||||
[auditordb-postgres]
|
||||
CONFIG = postgres:///auditor-basedb
|
||||
|
||||
[auditor]
|
||||
BASE_URL = http://localhost:8083/
|
||||
TINY_AMOUNT = TESTKUDOS:0.01
|
||||
PUBLIC_KEY = 0EHPW5WEKHXPPN4MPJNGA7Z6D29JP21GKVNV8ARFB1YW7WWJX20G
|
||||
|
||||
[PATHS]
|
||||
TALER_CACHE_HOME = $TALER_HOME/.cache/taler/
|
||||
TALER_CONFIG_HOME = $TALER_HOME/.config/taler/
|
||||
TALER_DATA_HOME = $TALER_HOME/.local/share/taler/
|
||||
TALER_HOME = ${PWD}/generate_auditordb_home/
|
||||
|
@ -1,412 +1,61 @@
|
||||
#!/bin/bash
|
||||
# Script to generate the basic database for auditor
|
||||
# testing from a 'correct' interaction between exchange,
|
||||
# wallet and merchant.
|
||||
# This file is in the public domain.
|
||||
#
|
||||
# Creates $BASEDB.sql, $BASEDB.fees,
|
||||
# $BASEDB.{mpub,mpriv}.
|
||||
# Default $BASEDB is "auditor-basedb", override via $1.
|
||||
# Script to generate the basic database for auditor testing from a 'correct'
|
||||
# interaction between exchange, wallet and merchant.
|
||||
#
|
||||
# Currently must be run online as it interacts with
|
||||
# bank.test.taler.net; also requires the wallet CLI
|
||||
# to be installed and in the path. Furthermore, the
|
||||
# user running this script must be Postgres superuser
|
||||
# and be allowed to create/drop databases.
|
||||
# Creates "$1.sql".
|
||||
#
|
||||
# Requires the wallet CLI to be installed and in the path. Furthermore, the
|
||||
# user running this script must be Postgres superuser and be allowed to
|
||||
# create/drop databases.
|
||||
#
|
||||
set -eu
|
||||
#set -x
|
||||
|
||||
# Cleanup to run whenever we exit
|
||||
function exit_cleanup()
|
||||
{
|
||||
echo "Running generate-auditor-basedb exit cleanup logic..."
|
||||
if test -f ${MY_TMP_DIR:-/}/libeufin-sandbox.pid
|
||||
then
|
||||
PID=`cat ${MY_TMP_DIR}/libeufin-sandbox.pid 2> /dev/null`
|
||||
kill $PID 2> /dev/null || true
|
||||
rm ${MY_TMP_DIR}/libeufin-sandbox.pid
|
||||
echo "Killed libeufin sandbox $PID"
|
||||
wait $PID || true
|
||||
fi
|
||||
if test -f ${MY_TMP_DIR:-/}/libeufin-nexus.pid
|
||||
then
|
||||
PID=`cat ${MY_TMP_DIR}/libeufin-nexus.pid 2> /dev/null`
|
||||
kill $PID 2> /dev/null || true
|
||||
rm ${MY_TMP_DIR}/libeufin-nexus.pid
|
||||
echo "Killed libeufin nexus $PID"
|
||||
wait $PID || true
|
||||
fi
|
||||
echo "killing libeufin DONE"
|
||||
for n in `jobs -p`
|
||||
do
|
||||
kill $n 2> /dev/null || true
|
||||
done
|
||||
wait || true
|
||||
}
|
||||
|
||||
# Install cleanup handler (except for kill -9)
|
||||
trap exit_cleanup EXIT
|
||||
|
||||
|
||||
# Exit, with status code "skip" (no 'real' failure)
|
||||
function exit_skip() {
|
||||
echo "SKIPPING: $1"
|
||||
exit 77
|
||||
}
|
||||
# Where do we write the result?
|
||||
BASEDB=${1:-"auditor-basedb"}
|
||||
# Name of the Postgres database we will use for the script.
|
||||
# Will be dropped, do NOT use anything that might be used
|
||||
# elsewhere
|
||||
export TARGET_DB=`basename ${BASEDB}`
|
||||
BASEDB="$1"
|
||||
|
||||
export WALLET_DB=${BASEDB:-"wallet"}.wdb
|
||||
. setup.sh
|
||||
|
||||
# delete existing wallet database
|
||||
rm -f $WALLET_DB
|
||||
|
||||
# Configuration file will be edited, so we create one
|
||||
# from the template.
|
||||
export CONF=$1.conf
|
||||
cp generate-auditor-basedb.conf $CONF
|
||||
echo "Created configuration at ${CONF}"
|
||||
DATA_DIR=$1/exchange-data-dir/
|
||||
mkdir -p $DATA_DIR
|
||||
taler-config -c $CONF -s PATHS -o TALER_HOME -V $DATA_DIR
|
||||
|
||||
echo -n "Testing for libeufin"
|
||||
libeufin-cli --help >/dev/null </dev/null || exit_skip " MISSING"
|
||||
echo " FOUND"
|
||||
echo -n "Testing for taler-wallet-cli"
|
||||
taler-wallet-cli -v >/dev/null </dev/null || exit_skip " MISSING"
|
||||
echo " FOUND"
|
||||
echo -n "Testing for curl"
|
||||
echo -n "Testing for curl ..."
|
||||
curl --help >/dev/null </dev/null || exit_skip " MISSING"
|
||||
echo " FOUND"
|
||||
|
||||
CONF="generate-auditor-basedb.conf"
|
||||
|
||||
# reset database
|
||||
dropdb $TARGET_DB >/dev/null 2>/dev/null || true
|
||||
createdb $TARGET_DB || exit_skip "Could not create database $TARGET_DB"
|
||||
ORIGIN=`pwd`
|
||||
MY_TMP_DIR=`dirname $1`
|
||||
echo -n "Reset 'auditor-basedb' database ..."
|
||||
dropdb "auditor-basedb" >/dev/null 2>/dev/null || true
|
||||
createdb "auditor-basedb" || exit_skip "Could not create database '$BASEDB'"
|
||||
echo " DONE"
|
||||
|
||||
# Launch exchange, merchant and bank.
|
||||
setup -c "$CONF" \
|
||||
-aenmsw \
|
||||
-d "iban"
|
||||
|
||||
# obtain key configuration data
|
||||
MASTER_PRIV_FILE=$1.mpriv
|
||||
MASTER_PRIV_DIR=`dirname $MASTER_PRIV_FILE`
|
||||
taler-config -f -c ${CONF} -s exchange-offline -o MASTER_PRIV_FILE -V ${MASTER_PRIV_FILE}
|
||||
rm -f "${MASTER_PRIV_FILE}"
|
||||
mkdir -p $MASTER_PRIV_DIR
|
||||
gnunet-ecc -l/dev/null -g1 $MASTER_PRIV_FILE > /dev/null
|
||||
export MASTER_PUB=`gnunet-ecc -p $MASTER_PRIV_FILE`
|
||||
export EXCHANGE_URL=`taler-config -c $CONF -s EXCHANGE -o BASE_URL`
|
||||
MERCHANT_PORT=`taler-config -c $CONF -s MERCHANT -o PORT`
|
||||
export MERCHANT_URL=http://localhost:${MERCHANT_PORT}/
|
||||
BANK_PORT=`taler-config -c $CONF -s BANK -o HTTP_PORT`
|
||||
EXCHANGE_URL=$(taler-config -c "$CONF" -s EXCHANGE -o BASE_URL)
|
||||
MERCHANT_PORT=$(taler-config -c "$CONF" -s MERCHANT -o PORT)
|
||||
MERCHANT_URL="http://localhost:${MERCHANT_PORT}/"
|
||||
BANK_PORT=$(taler-config -c "$CONF" -s BANK -o HTTP_PORT)
|
||||
BANK_URL="http://localhost:1${BANK_PORT}"
|
||||
export AUDITOR_URL=http://localhost:8083/
|
||||
AUDITOR_PRIV_FILE=$1.apriv
|
||||
AUDITOR_PRIV_DIR=`dirname $AUDITOR_PRIV_FILE`
|
||||
taler-config -f -c ${CONF} -s auditor -o AUDITOR_PRIV_FILE -V ${AUDITOR_PRIV_FILE}
|
||||
mkdir -p $AUDITOR_PRIV_DIR
|
||||
gnunet-ecc -l/dev/null -g1 $AUDITOR_PRIV_FILE > /dev/null
|
||||
AUDITOR_PUB=`gnunet-ecc -p $AUDITOR_PRIV_FILE`
|
||||
|
||||
echo "MASTER PUB is ${MASTER_PUB} using file ${MASTER_PRIV_FILE}"
|
||||
echo "AUDITOR PUB is ${AUDITOR_PUB} using file ${AUDITOR_PRIV_FILE}"
|
||||
|
||||
# patch configuration
|
||||
taler-config -c $CONF -s exchange -o MASTER_PUBLIC_KEY -V $MASTER_PUB
|
||||
taler-config -c $CONF -s auditor -o PUBLIC_KEY -V $AUDITOR_PUB
|
||||
taler-config -c $CONF -s merchant-exchange-default -o MASTER_KEY -V $MASTER_PUB
|
||||
|
||||
taler-config -c $CONF -s exchangedb-postgres -o CONFIG -V postgres:///$TARGET_DB
|
||||
taler-config -c $CONF -s auditordb-postgres -o CONFIG -V postgres:///$TARGET_DB
|
||||
taler-config -c $CONF -s merchantdb-postgres -o CONFIG -V postgres:///$TARGET_DB
|
||||
taler-config -c $CONF -s bank -o database -V postgres:///$TARGET_DB
|
||||
|
||||
# setup exchange
|
||||
echo "Setting up exchange"
|
||||
taler-exchange-dbinit -c $CONF
|
||||
|
||||
echo "Setting up merchant"
|
||||
taler-merchant-dbinit -c $CONF
|
||||
|
||||
# setup auditor
|
||||
echo "Setting up auditor"
|
||||
taler-auditor-dbinit -c $CONF || exit_skip "Failed to initialize auditor DB"
|
||||
taler-auditor-exchange -c $CONF -m $MASTER_PUB -u $EXCHANGE_URL || exit_skip "Failed to add exchange to auditor"
|
||||
|
||||
# Launch services
|
||||
echo "Launching services (pre audit DB: $TARGET_DB)"
|
||||
|
||||
rm -rf ${TARGET_DB}-sandbox.sqlite3
|
||||
export LIBEUFIN_SANDBOX_DB_CONNECTION="jdbc:sqlite:${TARGET_DB}-sandbox.sqlite3"
|
||||
# Create the default demobank.
|
||||
cd $MY_TMP_DIR
|
||||
export LIBEUFIN_SANDBOX_ADMIN_PASSWORD=secret
|
||||
libeufin-sandbox config --currency "TESTKUDOS" default
|
||||
libeufin-sandbox serve --port "1${BANK_PORT}" \
|
||||
> ${MY_TMP_DIR}/libeufin-sandbox-stdout.log \
|
||||
2> ${MY_TMP_DIR}/libeufin-sandbox-stderr.log &
|
||||
echo $! > ${MY_TMP_DIR}/libeufin-sandbox.pid
|
||||
cd $ORIGIN
|
||||
export LIBEUFIN_SANDBOX_URL="http://localhost:1${BANK_PORT}"
|
||||
set +e
|
||||
echo -n "Waiting for Sandbox..."
|
||||
OK=0
|
||||
for n in `seq 1 100`; do
|
||||
echo -n "."
|
||||
sleep 1
|
||||
if wget --timeout=1 \
|
||||
--user admin --password secret --auth-no-challenge \
|
||||
--tries=3 --waitretry=0 \
|
||||
-o /dev/null -O /dev/null \
|
||||
${LIBEUFIN_SANDBOX_URL};
|
||||
then
|
||||
OK=1
|
||||
break
|
||||
fi
|
||||
done
|
||||
if test $OK != 1
|
||||
then
|
||||
exit_skip " Failed to launch sandbox"
|
||||
fi
|
||||
echo "OK"
|
||||
|
||||
register_sandbox_account() {
|
||||
export LIBEUFIN_SANDBOX_USERNAME=$1
|
||||
export LIBEUFIN_SANDBOX_PASSWORD=$2
|
||||
cd $MY_TMP_DIR
|
||||
libeufin-cli sandbox \
|
||||
demobank \
|
||||
register --name "$3"
|
||||
cd $ORIGIN
|
||||
unset LIBEUFIN_SANDBOX_USERNAME
|
||||
unset LIBEUFIN_SANDBOX_PASSWORD
|
||||
}
|
||||
set -e
|
||||
echo -n "Register the 'fortytwo' Sandbox user.."
|
||||
register_sandbox_account fortytwo x "Forty Two"
|
||||
echo OK
|
||||
echo -n "Register the 'fortythree' Sandbox user.."
|
||||
register_sandbox_account fortythree x "Forty Three"
|
||||
echo OK
|
||||
echo -n "Register 'exchange' Sandbox user.."
|
||||
register_sandbox_account exchange x "Exchange Company"
|
||||
echo OK
|
||||
echo -n "Specify exchange's PAYTO_URI in the config ..."
|
||||
export LIBEUFIN_SANDBOX_USERNAME=exchange
|
||||
export LIBEUFIN_SANDBOX_PASSWORD=x
|
||||
cd $MY_TMP_DIR
|
||||
PAYTO=`libeufin-cli sandbox demobank info --bank-account exchange | jq --raw-output '.paytoUri'`
|
||||
taler-config -c $CONF -s exchange-account-1 -o PAYTO_URI -V $PAYTO
|
||||
echo " OK"
|
||||
echo -n "Setting this exchange as the bank's default ..."
|
||||
EXCHANGE_PAYTO=`libeufin-cli sandbox demobank info --bank-account exchange | jq --raw-output '.paytoUri'`
|
||||
libeufin-sandbox default-exchange "$EXCHANGE_URL" "$EXCHANGE_PAYTO"
|
||||
echo " OK"
|
||||
# Prepare EBICS: create Ebics host and Exchange subscriber.
|
||||
# Shortly becoming admin to setup Ebics.
|
||||
export LIBEUFIN_SANDBOX_USERNAME=admin
|
||||
export LIBEUFIN_SANDBOX_PASSWORD=secret
|
||||
echo -n "Create EBICS host at Sandbox.."
|
||||
libeufin-cli sandbox \
|
||||
--sandbox-url "http://localhost:1${BANK_PORT}" \
|
||||
ebicshost create --host-id "talerebics"
|
||||
echo "OK"
|
||||
echo -n "Create exchange EBICS subscriber at Sandbox.."
|
||||
libeufin-cli sandbox \
|
||||
demobank new-ebicssubscriber --host-id talerebics \
|
||||
--user-id exchangeebics --partner-id talerpartner \
|
||||
--bank-account exchange # that's a username _and_ a bank account name
|
||||
echo "OK"
|
||||
unset LIBEUFIN_SANDBOX_USERNAME
|
||||
unset LIBEUFIN_SANDBOX_PASSWORD
|
||||
# Prepare Nexus, which is the side actually talking
|
||||
# to the exchange.
|
||||
rm -rf ${TARGET_DB}-nexus.sqlite3
|
||||
export LIBEUFIN_NEXUS_DB_CONNECTION="jdbc:sqlite:${TARGET_DB}-nexus.sqlite3"
|
||||
# For convenience, username and password are
|
||||
# identical to those used at the Sandbox.
|
||||
echo -n "Create exchange Nexus user..."
|
||||
libeufin-nexus superuser exchange --password x
|
||||
echo " OK"
|
||||
libeufin-nexus serve --port ${BANK_PORT} \
|
||||
2> ${MY_TMP_DIR}/libeufin-nexus-stderr.log \
|
||||
> ${MY_TMP_DIR}/libeufin-nexus-stdout.log &
|
||||
echo $! > ${MY_TMP_DIR}/libeufin-nexus.pid
|
||||
export LIBEUFIN_NEXUS_URL="http://localhost:${BANK_PORT}"
|
||||
echo -n "Waiting for Nexus..."
|
||||
set +e
|
||||
OK=0
|
||||
for n in `seq 1 50`; do
|
||||
echo -n "."
|
||||
sleep 1
|
||||
if wget --timeout=1 \
|
||||
--tries=3 --waitretry=0 \
|
||||
-o /dev/null -O /dev/null \
|
||||
$LIBEUFIN_NEXUS_URL;
|
||||
then
|
||||
OK=1
|
||||
break
|
||||
fi
|
||||
done
|
||||
if test $OK != 1
|
||||
then
|
||||
exit_skip " Failed to launch Nexus at $LIBEUFIN_NEXUS_URL"
|
||||
fi
|
||||
set -e
|
||||
echo "OK"
|
||||
export LIBEUFIN_NEXUS_USERNAME=exchange
|
||||
export LIBEUFIN_NEXUS_PASSWORD=x
|
||||
echo -n "Creating an EBICS connection at Nexus..."
|
||||
libeufin-cli connections new-ebics-connection \
|
||||
--ebics-url "http://localhost:1${BANK_PORT}/ebicsweb" \
|
||||
--host-id "talerebics" \
|
||||
--partner-id "talerpartner" \
|
||||
--ebics-user-id "exchangeebics" \
|
||||
talerconn
|
||||
echo "OK"
|
||||
echo -n "Setup EBICS keying..."
|
||||
libeufin-cli connections connect "talerconn" > /dev/null
|
||||
echo "OK"
|
||||
echo -n "Download bank account name from Sandbox..."
|
||||
libeufin-cli connections download-bank-accounts "talerconn"
|
||||
echo "OK"
|
||||
echo -n "Importing bank account info into Nexus..."
|
||||
libeufin-cli connections import-bank-account \
|
||||
--offered-account-id "exchange" \
|
||||
--nexus-bank-account-id "exchange-nexus" \
|
||||
"talerconn"
|
||||
echo "OK"
|
||||
echo -n "Setup payments submission task..."
|
||||
# Tries every second.
|
||||
libeufin-cli accounts task-schedule \
|
||||
--task-type submit \
|
||||
--task-name "exchange-payments" \
|
||||
--task-cronspec "* * *" \
|
||||
"exchange-nexus"
|
||||
echo "OK"
|
||||
# Tries every second. Ask C52
|
||||
echo -n "Setup history fetch task..."
|
||||
libeufin-cli accounts task-schedule \
|
||||
--task-type fetch \
|
||||
--task-name "exchange-history" \
|
||||
--task-cronspec "* * *" \
|
||||
--task-param-level report \
|
||||
--task-param-range-type latest \
|
||||
"exchange-nexus"
|
||||
echo "OK"
|
||||
# create Taler facade.
|
||||
echo -n "Create the Taler facade at Nexus..."
|
||||
libeufin-cli facades \
|
||||
new-taler-wire-gateway-facade \
|
||||
--currency "TESTKUDOS" --facade-name "test-facade" \
|
||||
"talerconn" "exchange-nexus"
|
||||
echo "OK"
|
||||
cd $ORIGIN
|
||||
# Facade schema: http://localhost:$BANK_PORT/facades/test-facade/taler-wire-gateway/
|
||||
|
||||
|
||||
TFN=`which taler-exchange-httpd`
|
||||
TBINPFX=`dirname $TFN`
|
||||
TLIBEXEC=${TBINPFX}/../lib/taler/libexec/
|
||||
taler-exchange-secmod-eddsa -c $CONF 2> ${MY_TMP_DIR}/taler-exchange-secmod-eddsa.log &
|
||||
taler-exchange-secmod-rsa -c $CONF 2> ${MY_TMP_DIR}/taler-exchange-secmod-rsa.log &
|
||||
taler-exchange-secmod-cs -c $CONF 2> ${MY_TMP_DIR}/taler-exchange-secmod-cs.log &
|
||||
taler-exchange-httpd -c $CONF 2> ${MY_TMP_DIR}/taler-exchange-httpd.log &
|
||||
taler-merchant-httpd -c $CONF -L INFO 2> ${MY_TMP_DIR}/taler-merchant-httpd.log &
|
||||
taler-exchange-wirewatch -c $CONF 2> ${MY_TMP_DIR}/taler-exchange-wirewatch.log &
|
||||
taler-auditor-httpd -L INFO -c $CONF 2> ${MY_TMP_DIR}/taler-auditor-httpd.log &
|
||||
export BANK_PORT
|
||||
export EXCHANGE_URL
|
||||
export MERCHANT_URL
|
||||
export AUDITOR_URL
|
||||
|
||||
echo -n "Waiting for services to be available "
|
||||
# Wait for all bank to be available (usually the slowest)
|
||||
for n in `seq 1 50`
|
||||
do
|
||||
echo -n "."
|
||||
sleep 0.2
|
||||
OK=0
|
||||
# bank
|
||||
wget http://localhost:${BANK_PORT}/ -o /dev/null -O /dev/null >/dev/null || continue
|
||||
OK=1
|
||||
break
|
||||
done
|
||||
|
||||
if [ 1 != $OK ]
|
||||
then
|
||||
exit_skip "Failed to launch services (bank)"
|
||||
fi
|
||||
|
||||
# Wait for all services to be available
|
||||
for n in `seq 1 50`
|
||||
do
|
||||
echo -n "."
|
||||
sleep 0.1
|
||||
OK=0
|
||||
# exchange
|
||||
wget ${EXCHANGE_URL}seed -o /dev/null -O /dev/null >/dev/null || continue
|
||||
# merchant
|
||||
wget ${MERCHANT_URL} -o /dev/null -O /dev/null >/dev/null || continue
|
||||
# Auditor
|
||||
wget ${AUDITOR_URL} -o /dev/null -O /dev/null >/dev/null || continue
|
||||
OK=1
|
||||
break
|
||||
done
|
||||
|
||||
if [ 1 != $OK ]
|
||||
then
|
||||
bash
|
||||
exit_skip "Failed to launch services (Taler)"
|
||||
fi
|
||||
echo -n "Setting up keys"
|
||||
taler-exchange-offline -c $CONF \
|
||||
download sign \
|
||||
enable-account `taler-config -c $CONF -s exchange-account-1 -o PAYTO_URI` \
|
||||
enable-auditor $AUDITOR_PUB $AUDITOR_URL "TESTKUDOS Auditor" \
|
||||
wire-fee now iban TESTKUDOS:0.07 TESTKUDOS:0.01 \
|
||||
global-fee now TESTKUDOS:0.01 TESTKUDOS:0.01 TESTKUDOS:0.01 1h 1year 5 \
|
||||
upload &> ${MY_TMP_DIR}/taler-exchange-offline.log
|
||||
|
||||
echo -n "."
|
||||
|
||||
for n in `seq 1 2`
|
||||
do
|
||||
echo -n "."
|
||||
OK=0
|
||||
wget --timeout=1 http://localhost:8081/keys -o /dev/null -O /dev/null >/dev/null || continue
|
||||
OK=1
|
||||
break
|
||||
done
|
||||
|
||||
if [ 1 != $OK ]
|
||||
then
|
||||
exit_skip "Failed to setup keys"
|
||||
fi
|
||||
|
||||
echo " DONE"
|
||||
echo -n "Adding auditor signatures ..."
|
||||
|
||||
taler-auditor-offline -c $CONF \
|
||||
download sign upload &> ${MY_TMP_DIR}/taler-auditor-offline.log
|
||||
|
||||
echo " DONE"
|
||||
# Setup merchant
|
||||
|
||||
echo -n "Setting up merchant"
|
||||
|
||||
curl -H "Content-Type: application/json" -X POST -d '{"auth":{"method":"external"},"accounts":[{"payto_uri":"payto://iban/SANDBOXX/DE474361?receiver-name=Merchant43"}],"id":"default","name":"default","address":{},"jurisdiction":{},"default_max_wire_fee":"TESTKUDOS:1", "default_max_deposit_fee":"TESTKUDOS:1","default_wire_fee_amortization":1,"default_wire_transfer_delay":{"d_us" : 3600000000},"default_pay_delay":{"d_us": 3600000000}}' http://localhost:9966/management/instances
|
||||
|
||||
|
||||
echo -n "Setting up merchant ..."
|
||||
curl -H "Content-Type: application/json" -X POST -d '{"auth":{"method":"external"},"accounts":[{"payto_uri":"payto://iban/SANDBOXX/DE474361?receiver-name=Merchant43"}],"id":"default","name":"default","address":{},"jurisdiction":{},"default_max_wire_fee":"TESTKUDOS:1", "default_max_deposit_fee":"TESTKUDOS:1","default_wire_fee_amortization":1,"default_wire_transfer_delay":{"d_us" : 3600000000},"default_pay_delay":{"d_us": 3600000000}}' "${MERCHANT_URL}management/instances"
|
||||
echo " DONE"
|
||||
|
||||
# run wallet CLI
|
||||
echo "Running wallet"
|
||||
# delete existing wallet database
|
||||
export WALLET_DB="wallet.wdb"
|
||||
rm -f "$WALLET_DB"
|
||||
|
||||
taler-wallet-cli --no-throttle --wallet-db=$WALLET_DB api --expect-success 'runIntegrationTest' \
|
||||
echo -n "Running wallet ..."
|
||||
taler-wallet-cli \
|
||||
--no-throttle \
|
||||
--wallet-db="$WALLET_DB" \
|
||||
api \
|
||||
--expect-success \
|
||||
'runIntegrationTest' \
|
||||
"$(jq -n '
|
||||
{
|
||||
amountToSpend: "TESTKUDOS:4",
|
||||
@ -418,28 +67,25 @@ taler-wallet-cli --no-throttle --wallet-db=$WALLET_DB api --expect-success 'runI
|
||||
--arg MERCHANT_URL "$MERCHANT_URL" \
|
||||
--arg EXCHANGE_URL "$EXCHANGE_URL" \
|
||||
--arg BANK_URL "$BANK_URL/demobanks/default/access-api/"
|
||||
)" &> ${MY_TMP_DIR}/taler-wallet-cli.log
|
||||
|
||||
echo "Shutting down services"
|
||||
exit_cleanup
|
||||
)" &> taler-wallet-cli.log
|
||||
echo " DONE"
|
||||
|
||||
# Dump database
|
||||
echo "Dumping database ${BASEDB}(-libeufin).sql"
|
||||
pg_dump -O $TARGET_DB | sed -e '/AS integer/d' > ${BASEDB}.sql
|
||||
cd $MY_TMP_DIR
|
||||
sqlite3 ${TARGET_DB}-nexus.sqlite3 ".dump" > ${BASEDB}-libeufin-nexus.sql
|
||||
sqlite3 ${TARGET_DB}-sandbox.sqlite3 ".dump" > ${BASEDB}-libeufin-sandbox.sql
|
||||
rm ${TARGET_DB}-sandbox.sqlite3 ${TARGET_DB}-nexus.sqlite3 # libeufin DB
|
||||
cd $ORIGIN
|
||||
mkdir -p "$(dirname "$BASEDB")"
|
||||
|
||||
echo $MASTER_PUB > ${BASEDB}.mpub
|
||||
echo "Dumping database ${BASEDB}.sql"
|
||||
pg_dump -O "auditor-basedb" | sed -e '/AS integer/d' > "${BASEDB}.sql"
|
||||
|
||||
# clean up
|
||||
echo "Final clean up"
|
||||
dropdb $TARGET_DB
|
||||
echo -n "Final clean up ..."
|
||||
kill -TERM "$SETUP_PID"
|
||||
wait
|
||||
unset SETUP_PID
|
||||
dropdb "auditor-basedb"
|
||||
echo " DONE"
|
||||
|
||||
echo "====================================="
|
||||
echo " Finished generation of $BASEDB"
|
||||
echo "Finished generation of ${BASEDB}.sql"
|
||||
echo "====================================="
|
||||
|
||||
exit 0
|
||||
|
@ -8,405 +8,50 @@
|
||||
set -eu
|
||||
# set -x
|
||||
|
||||
# Cleanup to run whenever we exit
|
||||
function exit_cleanup()
|
||||
{
|
||||
echo "Running generate-revoke-basedb exit cleanup logic..."
|
||||
if test -f ${MY_TMP_DIR:-/}/libeufin-sandbox.pid
|
||||
then
|
||||
PID=`cat ${MY_TMP_DIR}/libeufin-sandbox.pid 2> /dev/null`
|
||||
kill $PID 2> /dev/null || true
|
||||
rm ${MY_TMP_DIR}/libeufin-sandbox.pid
|
||||
echo "Killed libeufin sandbox $PID"
|
||||
wait $PID || true
|
||||
fi
|
||||
if test -f ${MY_TMP_DIR}/libeufin-nexus.pid
|
||||
then
|
||||
PID=`cat ${MY_TMP_DIR}/libeufin-nexus.pid 2> /dev/null`
|
||||
kill $PID 2> /dev/null || true
|
||||
rm ${MY_TMP_DIR}/libeufin-nexus.pid
|
||||
echo "Killed libeufin nexus $PID"
|
||||
wait $PID || true
|
||||
fi
|
||||
echo "killing libeufin DONE"
|
||||
for n in `jobs -p`
|
||||
do
|
||||
kill $n 2> /dev/null || true
|
||||
done
|
||||
wait
|
||||
}
|
||||
. setup.sh
|
||||
|
||||
function get_payto_uri() {
|
||||
export LIBEUFIN_SANDBOX_USERNAME=$1
|
||||
export LIBEUFIN_SANDBOX_PASSWORD=$2
|
||||
export LIBEUFIN_SANDBOX_URL=$BANK_URL
|
||||
cd $MY_TMP_DIR
|
||||
libeufin-cli sandbox demobank info --bank-account $1 | jq --raw-output '.paytoUri'
|
||||
cd $ORIGIN
|
||||
}
|
||||
|
||||
# Install cleanup handler (except for kill -9)
|
||||
trap exit_cleanup EXIT
|
||||
|
||||
# Exit, with status code "skip" (no 'real' failure)
|
||||
function exit_skip() {
|
||||
echo $1
|
||||
exit 77
|
||||
}
|
||||
|
||||
# Where do we write the result?
|
||||
export BASEDB=${1:-"revoke-basedb"}
|
||||
|
||||
# Name of the Postgres database we will use for the script.
|
||||
# Will be dropped, do NOT use anything that might be used
|
||||
# elsewhere
|
||||
export TARGET_DB=`basename ${BASEDB}`
|
||||
TMP_DIR=`mktemp -d revocation-tmp-XXXXXX`
|
||||
export WALLET_DB=wallet-revocation.json
|
||||
rm -f $WALLET_DB
|
||||
|
||||
# Configuration file will be edited, so we create one
|
||||
# from the template.
|
||||
export CONF=${BASEDB}.conf
|
||||
cp generate-auditor-basedb.conf $CONF
|
||||
echo "Created configuration at ${CONF}"
|
||||
DATA_DIR=$1/exchange-data-dir/
|
||||
mkdir -p $DATA_DIR
|
||||
taler-config -c $CONF -s PATHS -o TALER_HOME -V $DATA_DIR
|
||||
|
||||
echo -n "Testing for libeufin(-cli)"
|
||||
libeufin-cli --help >/dev/null </dev/null || exit_skip " MISSING"
|
||||
echo " FOUND"
|
||||
echo -n "Testing for taler-wallet-cli"
|
||||
taler-wallet-cli -v >/dev/null </dev/null || exit_skip " MISSING"
|
||||
echo " FOUND"
|
||||
echo -n "Testing for curl"
|
||||
echo -n "Testing for curl ..."
|
||||
curl --help >/dev/null </dev/null || exit_skip " MISSING"
|
||||
echo " FOUND"
|
||||
|
||||
# reset database
|
||||
dropdb $TARGET_DB >/dev/null 2>/dev/null || true
|
||||
createdb $TARGET_DB || exit_skip "Could not create database $TARGET_DB"
|
||||
ORIGIN=`pwd`
|
||||
MY_TMP_DIR=`dirname $1`
|
||||
CONF="generate-auditor-basedb.conf"
|
||||
|
||||
# reset database
|
||||
echo -n "Reset 'auditor-basedb' database ..."
|
||||
dropdb "auditor-basedb" >/dev/null 2>/dev/null || true
|
||||
createdb "auditor-basedb" || exit_skip "Could not create database '$BASEDB'"
|
||||
echo " DONE"
|
||||
|
||||
# Launch exchange, merchant and bank.
|
||||
setup -c "$CONF" \
|
||||
-aenmsw \
|
||||
-d "iban"
|
||||
|
||||
# obtain key configuration data
|
||||
MASTER_PRIV_FILE=$1.mpriv
|
||||
MASTER_PRIV_DIR=`dirname $MASTER_PRIV_FILE`
|
||||
taler-config -f -c $CONF -s exchange-offline -o MASTER_PRIV_FILE -V ${MASTER_PRIV_FILE}
|
||||
mkdir -p $MASTER_PRIV_DIR
|
||||
rm -f "${MASTER_PRIV_FILE}"
|
||||
gnunet-ecc -g1 $MASTER_PRIV_FILE > /dev/null
|
||||
export MASTER_PUB=`gnunet-ecc -p $MASTER_PRIV_FILE`
|
||||
export EXCHANGE_URL=`taler-config -c $CONF -s EXCHANGE -o BASE_URL`
|
||||
MERCHANT_PORT=`taler-config -c $CONF -s MERCHANT -o PORT`
|
||||
export MERCHANT_URL=http://localhost:${MERCHANT_PORT}/
|
||||
BANK_PORT=`taler-config -c $CONF -s BANK -o HTTP_PORT`
|
||||
export BANK_URL=http://localhost:1${BANK_PORT}
|
||||
export AUDITOR_URL=http://localhost:8083/
|
||||
AUDITOR_PRIV_FILE=$1.apriv
|
||||
AUDITOR_PRIV_DIR=`dirname $AUDITOR_PRIV_FILE`
|
||||
taler-config -f -c ${CONF} -s auditor -o AUDITOR_PRIV_FILE -V ${AUDITOR_PRIV_FILE}
|
||||
mkdir -p $AUDITOR_PRIV_DIR
|
||||
gnunet-ecc -l /dev/null -g1 $AUDITOR_PRIV_FILE > /dev/null
|
||||
AUDITOR_PUB=`gnunet-ecc -p $AUDITOR_PRIV_FILE`
|
||||
EXCHANGE_URL=$(taler-config -c "$CONF" -s EXCHANGE -o BASE_URL)
|
||||
MERCHANT_PORT=$(taler-config -c "$CONF" -s MERCHANT -o PORT)
|
||||
MERCHANT_URL="http://localhost:${MERCHANT_PORT}/"
|
||||
BANK_PORT=$(taler-config -c "$CONF" -s BANK -o HTTP_PORT)
|
||||
BANK_URL="http://localhost:1${BANK_PORT}"
|
||||
|
||||
echo "MASTER PUB is ${MASTER_PUB} using file ${MASTER_PRIV_FILE}"
|
||||
echo "AUDITOR PUB is ${AUDITOR_PUB} using file ${AUDITOR_PRIV_FILE}"
|
||||
|
||||
|
||||
# patch configuration
|
||||
taler-config -c $CONF -s exchange -o MASTER_PUBLIC_KEY -V $MASTER_PUB
|
||||
taler-config -c $CONF -s auditor -o PUBLIC_KEY -V $AUDITOR_PUB
|
||||
taler-config -c $CONF -s merchant-exchange-default -o MASTER_KEY -V $MASTER_PUB
|
||||
taler-config -c $CONF -s exchangedb-postgres -o CONFIG -V postgres:///$TARGET_DB
|
||||
taler-config -c $CONF -s auditordb-postgres -o CONFIG -V postgres:///$TARGET_DB
|
||||
taler-config -c $CONF -s merchantdb-postgres -o CONFIG -V postgres:///$TARGET_DB
|
||||
taler-config -c $CONF -s bank -o database -V postgres:///$TARGET_DB
|
||||
taler-config -c $CONF -s exchange -o KEYDIR -V "${TMP_DIR}/keydir/"
|
||||
taler-config -c $CONF -s exchange -o REVOCATION_DIR -V "${TMP_DIR}/revdir/"
|
||||
|
||||
# setup exchange
|
||||
echo "Setting up exchange"
|
||||
taler-exchange-dbinit -c $CONF
|
||||
|
||||
echo "Setting up merchant"
|
||||
taler-merchant-dbinit -c $CONF
|
||||
|
||||
# setup auditor
|
||||
echo "Setting up auditor"
|
||||
taler-auditor-dbinit -c $CONF
|
||||
taler-auditor-exchange -c $CONF -m $MASTER_PUB -u $EXCHANGE_URL
|
||||
|
||||
# Launch services
|
||||
echo "Launching services"
|
||||
|
||||
export LIBEUFIN_SANDBOX_DB_CONNECTION="jdbc:sqlite:${TARGET_DB}-sandbox.sqlite3"
|
||||
# Create the default demobank.
|
||||
cd $MY_TMP_DIR
|
||||
export LIBEUFIN_SANDBOX_ADMIN_PASSWORD=secret
|
||||
libeufin-sandbox config --currency "TESTKUDOS" default
|
||||
libeufin-sandbox serve --port "1${BANK_PORT}" \
|
||||
> ${MY_TMP_DIR}/libeufin-sandbox-stdout.log \
|
||||
2> ${MY_TMP_DIR}/libeufin-sandbox-stderr.log &
|
||||
echo $! > ${MY_TMP_DIR}/libeufin-sandbox.pid
|
||||
cd $ORIGIN
|
||||
export LIBEUFIN_SANDBOX_URL="http://localhost:1${BANK_PORT}"
|
||||
set +e
|
||||
echo -n "Waiting for Sandbox..."
|
||||
OK=0
|
||||
for n in `seq 1 50`; do
|
||||
echo -n "."
|
||||
sleep 1
|
||||
if wget --timeout=1 \
|
||||
--user admin --password secret --auth-no-challenge \
|
||||
--tries=3 --waitretry=0 \
|
||||
-o /dev/null -O /dev/null \
|
||||
${LIBEUFIN_SANDBOX_URL};
|
||||
then
|
||||
OK=1
|
||||
break
|
||||
fi
|
||||
done
|
||||
if test $OK != 1
|
||||
then
|
||||
exit_skip " Failed to launch sandbox"
|
||||
fi
|
||||
echo "OK"
|
||||
|
||||
register_sandbox_account() {
|
||||
export LIBEUFIN_SANDBOX_USERNAME=$1
|
||||
export LIBEUFIN_SANDBOX_PASSWORD=$2
|
||||
cd $MY_TMP_DIR
|
||||
libeufin-cli sandbox \
|
||||
demobank \
|
||||
register --name "$3"
|
||||
cd $ORIGIN
|
||||
unset LIBEUFIN_SANDBOX_USERNAME
|
||||
unset LIBEUFIN_SANDBOX_PASSWORD
|
||||
}
|
||||
set -e
|
||||
echo -n "Register the 'fortytwo' Sandbox user.."
|
||||
register_sandbox_account fortytwo x "Forty Two"
|
||||
echo OK
|
||||
echo -n "Register the 'fortythree' Sandbox user.."
|
||||
register_sandbox_account fortythree x "Forty Three"
|
||||
echo OK
|
||||
echo -n "Register 'exchange' Sandbox user.."
|
||||
register_sandbox_account exchange x "Exchange Company"
|
||||
echo OK
|
||||
echo -n "Specify exchange's PAYTO_URI in the config ..."
|
||||
export LIBEUFIN_SANDBOX_USERNAME=exchange
|
||||
export LIBEUFIN_SANDBOX_PASSWORD=x
|
||||
cd $MY_TMP_DIR
|
||||
PAYTO=`libeufin-cli sandbox demobank info --bank-account exchange | jq --raw-output '.paytoUri'`
|
||||
taler-config -c $CONF -s exchange-account-1 -o PAYTO_URI -V $PAYTO
|
||||
echo " OK"
|
||||
echo -n "Setting this exchange as the bank's default ..."
|
||||
EXCHANGE_PAYTO=`libeufin-cli sandbox demobank info --bank-account exchange | jq --raw-output '.paytoUri'`
|
||||
libeufin-sandbox default-exchange "$EXCHANGE_URL" "$EXCHANGE_PAYTO"
|
||||
echo " OK"
|
||||
# Prepare EBICS: create Ebics host and Exchange subscriber.
|
||||
# Shortly becoming admin to setup Ebics.
|
||||
export LIBEUFIN_SANDBOX_USERNAME=admin
|
||||
export LIBEUFIN_SANDBOX_PASSWORD=secret
|
||||
echo -n "Create EBICS host at Sandbox.."
|
||||
libeufin-cli sandbox \
|
||||
--sandbox-url "http://localhost:1${BANK_PORT}" \
|
||||
ebicshost create --host-id "talerebics"
|
||||
echo "OK"
|
||||
echo -n "Create exchange EBICS subscriber at Sandbox.."
|
||||
libeufin-cli sandbox \
|
||||
demobank new-ebicssubscriber --host-id talerebics \
|
||||
--user-id exchangeebics --partner-id talerpartner \
|
||||
--bank-account exchange # that's a username _and_ a bank account name
|
||||
echo "OK"
|
||||
unset LIBEUFIN_SANDBOX_USERNAME
|
||||
unset LIBEUFIN_SANDBOX_PASSWORD
|
||||
# Prepare Nexus, which is the side actually talking
|
||||
# to the exchange.
|
||||
export LIBEUFIN_NEXUS_DB_CONNECTION="jdbc:sqlite:${TARGET_DB}-nexus.sqlite3"
|
||||
# For convenience, username and password are
|
||||
# identical to those used at the Sandbox.
|
||||
echo -n "Create exchange Nexus user..."
|
||||
libeufin-nexus superuser exchange --password x
|
||||
echo " OK"
|
||||
libeufin-nexus serve --port ${BANK_PORT} \
|
||||
2> ${MY_TMP_DIR}/libeufin-nexus-stderr.log \
|
||||
> ${MY_TMP_DIR}/libeufin-nexus-stdout.log &
|
||||
echo $! > ${MY_TMP_DIR}/libeufin-nexus.pid
|
||||
export LIBEUFIN_NEXUS_URL="http://localhost:${BANK_PORT}"
|
||||
echo -n "Waiting for Nexus..."
|
||||
set +e
|
||||
OK=0
|
||||
for n in `seq 1 50`; do
|
||||
echo -n "."
|
||||
sleep 1
|
||||
if wget --timeout=1 \
|
||||
--tries=3 --waitretry=0 \
|
||||
-o /dev/null -O /dev/null \
|
||||
$LIBEUFIN_NEXUS_URL;
|
||||
then
|
||||
OK=1
|
||||
break
|
||||
fi
|
||||
done
|
||||
if test $OK != 1
|
||||
then
|
||||
exit_skip " Failed to launch Nexus at $LIBEUFIN_NEXUS_URL"
|
||||
fi
|
||||
set -e
|
||||
echo "OK"
|
||||
export LIBEUFIN_NEXUS_USERNAME=exchange
|
||||
export LIBEUFIN_NEXUS_PASSWORD=x
|
||||
echo -n "Creating an EBICS connection at Nexus..."
|
||||
libeufin-cli connections new-ebics-connection \
|
||||
--ebics-url "http://localhost:1${BANK_PORT}/ebicsweb" \
|
||||
--host-id "talerebics" \
|
||||
--partner-id "talerpartner" \
|
||||
--ebics-user-id "exchangeebics" \
|
||||
talerconn
|
||||
echo "OK"
|
||||
echo -n "Setup EBICS keying..."
|
||||
libeufin-cli connections connect "talerconn" > /dev/null
|
||||
echo "OK"
|
||||
echo -n "Download bank account name from Sandbox..."
|
||||
libeufin-cli connections download-bank-accounts "talerconn"
|
||||
echo "OK"
|
||||
echo -n "Importing bank account info into Nexus..."
|
||||
libeufin-cli connections import-bank-account \
|
||||
--offered-account-id "exchange" \
|
||||
--nexus-bank-account-id "exchange-nexus" \
|
||||
"talerconn"
|
||||
echo "OK"
|
||||
echo -n "Setup payments submission task..."
|
||||
# Tries every second.
|
||||
libeufin-cli accounts task-schedule \
|
||||
--task-type submit \
|
||||
--task-name "exchange-payments" \
|
||||
--task-cronspec "* * *" \
|
||||
"exchange-nexus"
|
||||
echo "OK"
|
||||
# Tries every second. Ask C52
|
||||
echo -n "Setup history fetch task..."
|
||||
libeufin-cli accounts task-schedule \
|
||||
--task-type fetch \
|
||||
--task-name "exchange-history" \
|
||||
--task-cronspec "* * *" \
|
||||
--task-param-level report \
|
||||
--task-param-range-type latest \
|
||||
"exchange-nexus"
|
||||
echo "OK"
|
||||
# create Taler facade.
|
||||
echo -n "Create the Taler facade at Nexus..."
|
||||
libeufin-cli facades \
|
||||
new-taler-wire-gateway-facade \
|
||||
--currency "TESTKUDOS" --facade-name "test-facade" \
|
||||
"talerconn" "exchange-nexus"
|
||||
echo "OK"
|
||||
cd $ORIGIN
|
||||
# Facade schema: http://localhost:$BANK_PORT/facades/test-facade/taler-wire-gateway/
|
||||
|
||||
TFN=`which taler-exchange-httpd`
|
||||
TBINPFX=`dirname $TFN`
|
||||
TLIBEXEC=${TBINPFX}/../lib/taler/libexec/
|
||||
taler-exchange-secmod-eddsa -c $CONF 2> ${MY_TMP_DIR}/taler-exchange-secmod-eddsa.log &
|
||||
SIGNKEY_HELPER_PID=$!
|
||||
taler-exchange-secmod-rsa -c $CONF 2> ${MY_TMP_DIR}/taler-exchange-secmod-rsa.log &
|
||||
RSA_DENOM_HELPER_PID=$!
|
||||
taler-exchange-secmod-cs -c $CONF 2> ${MY_TMP_DIR}/taler-exchange-secmod-cs.log &
|
||||
CS_DENOM_HELPER_PID=$!
|
||||
taler-exchange-httpd -c $CONF 2> ${MY_TMP_DIR}/taler-exchange-httpd.log &
|
||||
EXCHANGE_PID=$!
|
||||
taler-merchant-httpd -c $CONF -L INFO 2> ${MY_TMP_DIR}/taler-merchant-httpd.log &
|
||||
MERCHANT_PID=$!
|
||||
taler-exchange-wirewatch -c $CONF 2> ${MY_TMP_DIR}/taler-exchange-wirewatch.log &
|
||||
taler-auditor-httpd -c $CONF 2> ${MY_TMP_DIR}/taler-auditor-httpd.log &
|
||||
|
||||
# Wait for all bank to be available (usually the slowest)
|
||||
for n in `seq 1 50`
|
||||
do
|
||||
echo -n "."
|
||||
sleep 0.2
|
||||
OK=0
|
||||
# bank
|
||||
wget http://localhost:8082/ -o /dev/null -O /dev/null >/dev/null || continue
|
||||
OK=1
|
||||
break
|
||||
done
|
||||
|
||||
if [ 1 != $OK ]
|
||||
then
|
||||
exit_skip "Failed to launch Bank services"
|
||||
fi
|
||||
|
||||
# Wait for all other services to be available
|
||||
for n in `seq 1 50`
|
||||
do
|
||||
echo -n "."
|
||||
sleep 0.1
|
||||
OK=0
|
||||
# exchange
|
||||
wget http://localhost:8081/seed -o /dev/null -O /dev/null >/dev/null || continue
|
||||
# merchant
|
||||
wget http://localhost:9966/ -o /dev/null -O /dev/null >/dev/null || continue
|
||||
# Auditor
|
||||
wget http://localhost:8083/ -o /dev/null -O /dev/null >/dev/null || continue
|
||||
OK=1
|
||||
break
|
||||
done
|
||||
|
||||
if [ 1 != $OK ]
|
||||
then
|
||||
exit_cleanup
|
||||
exit_skip "Failed to launch Taler services"
|
||||
fi
|
||||
echo " DONE"
|
||||
|
||||
echo -n "Setting up keys"
|
||||
|
||||
taler-exchange-offline -c $CONF \
|
||||
download sign \
|
||||
enable-account `taler-config -c $CONF -s exchange-account-1 -o PAYTO_URI` \
|
||||
enable-auditor $AUDITOR_PUB $AUDITOR_URL "TESTKUDOS Auditor" \
|
||||
wire-fee now iban TESTKUDOS:0.01 TESTKUDOS:0.01 \
|
||||
global-fee now TESTKUDOS:0.01 TESTKUDOS:0.01 TESTKUDOS:0.01 1h 1year 5 \
|
||||
upload &> ${MY_TMP_DIR}/taler-exchange-offline.log
|
||||
|
||||
echo -n "."
|
||||
|
||||
for n in `seq 1 2`
|
||||
do
|
||||
echo -n "."
|
||||
OK=0
|
||||
# bank
|
||||
wget --timeout=1 http://localhost:8081/keys -o /dev/null -O /dev/null >/dev/null || continue
|
||||
OK=1
|
||||
break
|
||||
done
|
||||
|
||||
if [ 1 != $OK ]
|
||||
then
|
||||
exit_skip "Failed to setup keys"
|
||||
fi
|
||||
|
||||
|
||||
taler-auditor-offline -c $CONF \
|
||||
download sign upload &> ${MY_TMP_DIR}/taler-auditor-offline.log
|
||||
|
||||
echo " DONE"
|
||||
|
||||
# Setup merchant
|
||||
echo -n "Setting up merchant"
|
||||
|
||||
curl -H "Content-Type: application/json" -X POST -d '{"auth": {"method": "external"}, "accounts":[{"payto_uri":"payto://iban/SANDBOXX/DE474361?receiver-name=Merchant43"}],"id":"default","name":"default","address":{},"jurisdiction":{},"default_max_wire_fee":"TESTKUDOS:1", "default_max_deposit_fee":"TESTKUDOS:1","default_wire_fee_amortization":1,"default_wire_transfer_delay":{"d_us" : 3600000000},"default_pay_delay":{"d_us": 3600000000}}' http://localhost:9966/management/instances
|
||||
echo -n "Setting up merchant ..."
|
||||
curl -H "Content-Type: application/json" -X POST -d '{"auth": {"method": "external"}, "accounts":[{"payto_uri":"payto://iban/SANDBOXX/DE474361?receiver-name=Merchant43"}],"id":"default","name":"default","address":{},"jurisdiction":{},"default_max_wire_fee":"TESTKUDOS:1", "default_max_deposit_fee":"TESTKUDOS:1","default_wire_fee_amortization":1,"default_wire_transfer_delay":{"d_us" : 3600000000},"default_pay_delay":{"d_us": 3600000000}}' "${MERCHANT_URL}management/instances"
|
||||
echo " DONE"
|
||||
|
||||
|
||||
# run wallet CLI
|
||||
echo "Running wallet"
|
||||
|
||||
taler-wallet-cli --no-throttle --wallet-db=$WALLET_DB api --expect-success 'withdrawTestBalance' \
|
||||
export WALLET_DB="wallet.wdb"
|
||||
rm -f "$WALLET_DB"
|
||||
|
||||
taler-wallet-cli \
|
||||
--no-throttle \
|
||||
--wallet-db="$WALLET_DB" \
|
||||
api \
|
||||
--expect-success 'withdrawTestBalance' \
|
||||
"$(jq -n '
|
||||
{
|
||||
amount: "TESTKUDOS:8",
|
||||
@ -414,57 +59,85 @@ taler-wallet-cli --no-throttle --wallet-db=$WALLET_DB api --expect-success 'with
|
||||
exchangeBaseUrl: $EXCHANGE_URL,
|
||||
}' \
|
||||
--arg BANK_URL "$BANK_URL/demobanks/default/access-api/" \
|
||||
--arg EXCHANGE_URL $EXCHANGE_URL
|
||||
)"
|
||||
--arg EXCHANGE_URL "$EXCHANGE_URL"
|
||||
)" &> taler-wallet-cli-withdraw.log
|
||||
|
||||
taler-wallet-cli --no-throttle --wallet-db=$WALLET_DB run-until-done
|
||||
taler-wallet-cli \
|
||||
--no-throttle \
|
||||
--wallet-db="$WALLET_DB" \
|
||||
run-until-done \
|
||||
&> taler-wallet-cli-withdraw-finish.log
|
||||
|
||||
export coins=$(taler-wallet-cli --wallet-db=$WALLET_DB advanced dump-coins)
|
||||
export COINS=$(taler-wallet-cli --wallet-db="$WALLET_DB" advanced dump-coins)
|
||||
|
||||
echo -n "COINS are:"
|
||||
echo $coins
|
||||
echo "$COINS"
|
||||
|
||||
# Find coin we want to revoke
|
||||
export rc=$(echo "$coins" | jq -r '[.coins[] | select((.denom_value == "TESTKUDOS:2"))][0] | .coin_pub')
|
||||
export rc=$(echo "$COINS" | jq -r '[.coins[] | select((.denom_value == "TESTKUDOS:2"))][0] | .coin_pub')
|
||||
# Find the denom
|
||||
export rd=$(echo "$coins" | jq -r '[.coins[] | select((.denom_value == "TESTKUDOS:2"))][0] | .denom_pub_hash')
|
||||
echo "Revoking denomination ${rd} (to affect coin ${rc})"
|
||||
export rd=$(echo "$COINS" | jq -r '[.coins[] | select((.denom_value == "TESTKUDOS:2"))][0] | .denom_pub_hash')
|
||||
echo -n "Revoking denomination ${rd} (to affect coin ${rc}) ..."
|
||||
# Find all other coins, which will be suspended
|
||||
export susp=$(echo "$coins" | jq --arg rc "$rc" '[.coins[] | select(.coin_pub != $rc) | .coin_pub]')
|
||||
export susp=$(echo "$COINS" | jq --arg rc "$rc" '[.coins[] | select(.coin_pub != $rc) | .coin_pub]')
|
||||
|
||||
# Do the revocation
|
||||
taler-exchange-offline -c $CONF \
|
||||
revoke-denomination "${rd}" upload &> ${MY_TMP_DIR}/taler-exchange-offline-revoke.log
|
||||
taler-exchange-offline \
|
||||
-c $CONF \
|
||||
revoke-denomination "${rd}" \
|
||||
upload \
|
||||
&> taler-exchange-offline-revoke.log
|
||||
echo "DONE"
|
||||
|
||||
echo -n "Signing replacement keys ..."
|
||||
sleep 1 # Give exchange time to create replacmenent key
|
||||
|
||||
# Re-sign replacement keys
|
||||
taler-auditor-offline -c $CONF \
|
||||
download sign upload &> ${MY_TMP_DIR}/taler-auditor-offline.log
|
||||
taler-auditor-offline \
|
||||
-c $CONF \
|
||||
download \
|
||||
sign \
|
||||
upload \
|
||||
&> taler-auditor-offline-reinit.log
|
||||
echo " DONE"
|
||||
|
||||
# Now we suspend the other coins, so later we will pay with the recouped coin
|
||||
taler-wallet-cli --wallet-db=$WALLET_DB advanced suspend-coins "$susp"
|
||||
taler-wallet-cli \
|
||||
--wallet-db="$WALLET_DB" \
|
||||
advanced \
|
||||
suspend-coins "$susp"
|
||||
|
||||
# Update exchange /keys so recoup gets scheduled
|
||||
taler-wallet-cli --wallet-db=$WALLET_DB exchanges update \
|
||||
-f $EXCHANGE_URL
|
||||
taler-wallet-cli \
|
||||
--wallet-db="$WALLET_DB" \
|
||||
exchanges \
|
||||
update \
|
||||
-f "$EXCHANGE_URL"
|
||||
|
||||
# Block until scheduled operations are done
|
||||
taler-wallet-cli --wallet-db=$WALLET_DB run-until-done
|
||||
taler-wallet-cli \
|
||||
--wallet-db="$WALLET_DB"\
|
||||
run-until-done
|
||||
|
||||
# Now we buy something, only the coins resulting from recouped will be
|
||||
# Now we buy something, only the coins resulting from recoup will be
|
||||
# used, as other ones are suspended
|
||||
taler-wallet-cli --no-throttle --wallet-db=$WALLET_DB api 'testPay' \
|
||||
taler-wallet-cli \
|
||||
--no-throttle \
|
||||
--wallet-db="$WALLET_DB" \
|
||||
api \
|
||||
'testPay' \
|
||||
"$(jq -n '
|
||||
{
|
||||
amount: "TESTKUDOS:1",
|
||||
merchantBaseUrl: $MERCHANT_URL,
|
||||
summary: "foo",
|
||||
}' \
|
||||
--arg MERCHANT_URL $MERCHANT_URL
|
||||
--arg MERCHANT_URL "$MERCHANT_URL"
|
||||
)"
|
||||
|
||||
taler-wallet-cli --wallet-db=$WALLET_DB run-until-done
|
||||
taler-wallet-cli \
|
||||
--wallet-db="$WALLET_DB" \
|
||||
run-until-done
|
||||
|
||||
echo "Purchase with recoup'ed coin (via reserve) done"
|
||||
|
||||
@ -477,9 +150,6 @@ echo "Will refresh coin ${rrc} of denomination ${zombie_denom}"
|
||||
# Find all other coins, which will be suspended
|
||||
export susp=$(echo "$coins" | jq --arg rrc "$rrc" '[.coins[] | select(.coin_pub != $rrc) | .coin_pub]')
|
||||
|
||||
export rrc
|
||||
export zombie_denom
|
||||
|
||||
# Travel into the future! (must match DURATION_WITHDRAW option)
|
||||
export TIMETRAVEL="--timetravel=604800000000"
|
||||
|
||||
@ -510,8 +180,15 @@ do
|
||||
done
|
||||
|
||||
echo "Refreshing coin $rrc"
|
||||
taler-wallet-cli $TIMETRAVEL --wallet-db=$WALLET_DB advanced force-refresh "$rrc"
|
||||
taler-wallet-cli $TIMETRAVEL --wallet-db=$WALLET_DB run-until-done
|
||||
taler-wallet-cli \
|
||||
"$TIMETRAVEL" \
|
||||
--wallet-db="$WALLET_DB" \
|
||||
advanced force-refresh \
|
||||
"$rrc"
|
||||
taler-wallet-cli \
|
||||
"$TIMETRAVEL" \
|
||||
--wallet-db="$WALLET_DB" \
|
||||
run-until-done
|
||||
|
||||
# Update our list of the coins
|
||||
export coins=$(taler-wallet-cli $TIMETRAVEL --wallet-db=$WALLET_DB advanced dump-coins)
|
||||
@ -534,29 +211,49 @@ export susp=$(echo "$coins" | jq --arg freshc "$freshc" '[.coins[] | select(.coi
|
||||
|
||||
# Do the revocation of freshc
|
||||
echo "Revoking ${fresh_denom} (to affect coin ${freshc})"
|
||||
taler-exchange-offline -c $CONF \
|
||||
revoke-denomination "${fresh_denom}" upload &> ${MY_TMP_DIR}/taler-exchange-offline-revoke-2.log
|
||||
taler-exchange-offline \
|
||||
-c "$CONF" \
|
||||
revoke-denomination \
|
||||
"${fresh_denom}" \
|
||||
upload &> taler-exchange-offline-revoke-2.log
|
||||
|
||||
sleep 1 # Give exchange time to create replacmenent key
|
||||
|
||||
# Re-sign replacement keys
|
||||
taler-auditor-offline -c $CONF \
|
||||
download sign upload &> ${MY_TMP_DIR}/taler-auditor-offline.log
|
||||
taler-auditor-offline \
|
||||
-c "$CONF" \
|
||||
download \
|
||||
sign \
|
||||
upload &> taler-auditor-offline.log
|
||||
|
||||
# Now we suspend the other coins, so later we will pay with the recouped coin
|
||||
taler-wallet-cli $TIMETRAVEL --wallet-db=$WALLET_DB advanced suspend-coins "$susp"
|
||||
taler-wallet-cli \
|
||||
"$TIMETRAVEL" \
|
||||
--wallet-db="$WALLET_DB" \
|
||||
advanced \
|
||||
suspend-coins "$susp"
|
||||
|
||||
# Update exchange /keys so recoup gets scheduled
|
||||
taler-wallet-cli $TIMETRAVEL --wallet-db=$WALLET_DB exchanges update \
|
||||
-f $EXCHANGE_URL
|
||||
taler-wallet-cli \
|
||||
"$TIMETRAVEL"\
|
||||
--wallet-db="$WALLET_DB" \
|
||||
exchanges update \
|
||||
-f "$EXCHANGE_URL"
|
||||
|
||||
# Block until scheduled operations are done
|
||||
taler-wallet-cli $TIMETRAVEL --wallet-db=$WALLET_DB run-until-done
|
||||
taler-wallet-cli \
|
||||
"$TIMETRAVEL" \
|
||||
--wallet-db="$WALLET_DB" \
|
||||
run-until-done
|
||||
|
||||
echo "Restarting merchant (so new keys are known)"
|
||||
kill -TERM $MERCHANT_PID
|
||||
taler-merchant-httpd -c $CONF -L INFO 2> ${MY_TMP_DIR}/taler-merchant-httpd.log &
|
||||
taler-merchant-httpd \
|
||||
-c "$CONF" \
|
||||
-L INFO \
|
||||
2> ${MY_TMP_DIR}/taler-merchant-httpd.log &
|
||||
MERCHANT_PID=$!
|
||||
|
||||
# Wait for merchant to be again available
|
||||
for n in `seq 1 50`
|
||||
do
|
||||
@ -580,7 +277,10 @@ taler-wallet-cli $TIMETRAVEL --no-throttle --wallet-db=$WALLET_DB api 'testPay'
|
||||
}' \
|
||||
--arg MERCHANT_URL $MERCHANT_URL
|
||||
)"
|
||||
taler-wallet-cli $TIMETRAVEL --wallet-db=$WALLET_DB run-until-done
|
||||
taler-wallet-cli \
|
||||
"$TIMETRAVEL" \
|
||||
--wallet-db="$WALLET_DB" \
|
||||
run-until-done
|
||||
|
||||
echo "Bought something with refresh-recouped coin"
|
||||
|
||||
@ -588,26 +288,24 @@ echo "Shutting down services"
|
||||
exit_cleanup
|
||||
|
||||
|
||||
# Where do we write the result?
|
||||
export BASEDB=${1:-"revoke-basedb"}
|
||||
|
||||
|
||||
# Dump database
|
||||
echo "Dumping database"
|
||||
echo "Dumping PostgreSQL database: ${BASEDB}.sql"
|
||||
pg_dump -O $TARGET_DB | sed -e '/AS integer/d' > ${BASEDB}.sql
|
||||
echo "Dumping libeufin database: ${TARGET_DB}-libeufin-*.sql"
|
||||
cd $MY_TMP_DIR
|
||||
sqlite3 ${TARGET_DB}-nexus.sqlite3 ".dump" > ${BASEDB}-libeufin-nexus.sql
|
||||
sqlite3 ${TARGET_DB}-sandbox.sqlite3 ".dump" > ${BASEDB}-libeufin-sandbox.sql
|
||||
echo "Dumping database ${BASEDB}.sql"
|
||||
pg_dump -O "auditor-basedb" | sed -e '/AS integer/d' > "${BASEDB}.sql"
|
||||
|
||||
rm ${TARGET_DB}-sandbox.sqlite3 ${TARGET_DB}-nexus.sqlite3 # libeufin DB
|
||||
|
||||
cd $ORIGIN
|
||||
|
||||
echo $MASTER_PUB > ${BASEDB}.mpub
|
||||
|
||||
echo "Final clean up"
|
||||
dropdb $TARGET_DB
|
||||
# clean up
|
||||
echo -n "Final clean up ..."
|
||||
kill -TERM "$SETUP_PID"
|
||||
wait
|
||||
unset SETUP_PID
|
||||
dropdb "auditor-basedb"
|
||||
echo " DONE"
|
||||
|
||||
echo "====================================="
|
||||
echo " Finished generation of $BASEDB "
|
||||
echo "Finished generation of ${BASEDB}.sql"
|
||||
echo "====================================="
|
||||
|
||||
exit 0
|
||||
|
@ -0,0 +1 @@
|
||||
%I7qYÿ®ÜX˜2@–šò%'1†”ÂOàÔæJ³Ô¦‘
|
72
src/auditor/setup.sh
Executable file
72
src/auditor/setup.sh
Executable file
@ -0,0 +1,72 @@
|
||||
#!/bin/sh
|
||||
# This file is in the public domain
|
||||
|
||||
# Script to be inlined into the main test scripts. Defines function 'setup()'
|
||||
# which wraps around 'taler-unified-setup.sh' to launch GNU Taler services.
|
||||
# Call setup() with the arguments to pass to 'taler-unified-setup'. setup()
|
||||
# will then launch GNU Taler, wait for the process to be complete before
|
||||
# returning. The script will also install an exit handler to ensure the GNU
|
||||
# Taler processes are stopped when the shell exits.
|
||||
|
||||
set -eu
|
||||
|
||||
# Cleanup to run whenever we exit
|
||||
function exit_cleanup()
|
||||
{
|
||||
if [ ! -z ${SETUP_PID+x} ]
|
||||
then
|
||||
echo "Killing taler-unified-setup ($SETUP_PID)" >&2
|
||||
kill -TERM "$SETUP_PID"
|
||||
wait
|
||||
fi
|
||||
}
|
||||
|
||||
# Install cleanup handler (except for kill -9)
|
||||
trap exit_cleanup EXIT
|
||||
|
||||
function setup()
|
||||
{
|
||||
echo "Starting test system ..." >&2
|
||||
# Create a named pipe in a temp directory we own.
|
||||
FIFO_DIR=$(mktemp -d fifo-XXXXXX)
|
||||
FIFO_OUT=$(echo "$FIFO_DIR/out")
|
||||
mkfifo "$FIFO_OUT"
|
||||
# Open pipe as FD 3 (RW) and FD 4 (RO)
|
||||
exec 3<> "$FIFO_OUT" 4< "$FIFO_OUT"
|
||||
rm -rf "$FIFO_DIR"
|
||||
# We require '-W' for our termination logic to work.
|
||||
taler-unified-setup.sh -W "$@" >&3 &
|
||||
SETUP_PID=$!
|
||||
# Close FD3
|
||||
exec 3>&-
|
||||
sed -u '/<<READY>>/ q' <&4
|
||||
# Close FD4
|
||||
exec 4>&-
|
||||
echo "Test system ready" >&2
|
||||
}
|
||||
|
||||
# Exit, with status code "skip" (no 'real' failure)
|
||||
function exit_fail() {
|
||||
echo "$@" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Exit, with status code "skip" (no 'real' failure)
|
||||
function exit_skip() {
|
||||
echo "SKIPPING: $1"
|
||||
exit 77
|
||||
}
|
||||
|
||||
function get_payto_uri() {
|
||||
export LIBEUFIN_SANDBOX_USERNAME="$1"
|
||||
export LIBEUFIN_SANDBOX_PASSWORD="$2"
|
||||
export LIBEUFIN_SANDBOX_URL="http://localhost:18082"
|
||||
libeufin-cli sandbox demobank info --bank-account "$1" | jq --raw-output '.paytoUri'
|
||||
}
|
||||
|
||||
function get_bankaccount_transactions() {
|
||||
export LIBEUFIN_SANDBOX_USERNAME=$1
|
||||
export LIBEUFIN_SANDBOX_PASSWORD=$2
|
||||
export LIBEUFIN_SANDBOX_URL="http://localhost:18082"
|
||||
libeufin-cli sandbox demobank list-transactions --bank-account $1
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# This file is part of TALER
|
||||
# Copyright (C) 2014-2022 Taler Systems SA
|
||||
# Copyright (C) 2014-2023 Taler Systems SA
|
||||
#
|
||||
# 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
|
||||
@ -49,17 +49,7 @@ VALGRIND=""
|
||||
# history request.
|
||||
LIBEUFIN_SETTLE_TIME=1
|
||||
|
||||
# Exit, with status code "skip" (no 'real' failure)
|
||||
function exit_skip() {
|
||||
echo "SKIPPING test: $1"
|
||||
exit 77
|
||||
}
|
||||
|
||||
# Exit, with error message (hard failure)
|
||||
function exit_fail() {
|
||||
echo "FAILING test: $1"
|
||||
exit 1
|
||||
}
|
||||
. setup.sh
|
||||
|
||||
# Stop libeufin sandbox and nexus (if running)
|
||||
function stop_libeufin()
|
||||
@ -2002,12 +1992,12 @@ function check_with_database()
|
||||
{
|
||||
BASEDB=$1
|
||||
CONF=$1.conf
|
||||
ORIGIN=`pwd`
|
||||
MY_TMP_DIR=`dirname $1`
|
||||
ORIGIN=$(pwd)
|
||||
MY_TMP_DIR=$(dirname $1)
|
||||
echo "Running test suite with database $BASEDB using configuration $CONF"
|
||||
MASTER_PRIV_FILE=${BASEDB}.mpriv
|
||||
taler-config -f -c ${CONF} -s exchange-offline -o MASTER_PRIV_FILE -V ${MASTER_PRIV_FILE}
|
||||
MASTER_PUB=`gnunet-ecc -p $MASTER_PRIV_FILE`
|
||||
MASTER_PUB=$(gnunet-ecc -p $MASTER_PRIV_FILE)
|
||||
|
||||
echo "MASTER PUB is ${MASTER_PUB} using file ${MASTER_PRIV_FILE}"
|
||||
|
||||
@ -2037,7 +2027,7 @@ function check_with_database()
|
||||
|
||||
# ####### Setup globals ######
|
||||
# Postgres database to use
|
||||
export DB=auditor-basedb
|
||||
export DB="auditor-basedb"
|
||||
|
||||
# test required commands exist
|
||||
echo "Testing for jq"
|
||||
@ -2059,12 +2049,12 @@ INITDB_BIN=$(command -v initdb) || true
|
||||
if [[ ! -z "$INITDB_BIN" ]]; then
|
||||
echo " FOUND (in path) at" $INITDB_BIN
|
||||
else
|
||||
HAVE_INITDB=`find /usr -name "initdb" | head -1 2> /dev/null | grep postgres` || exit_skip " MISSING"
|
||||
echo " FOUND at" `dirname $HAVE_INITDB`
|
||||
INITDB_BIN=`echo $HAVE_INITDB | grep bin/initdb | grep postgres | sort -n | tail -n1`
|
||||
HAVE_INITDB=$(find /usr -name "initdb" | head -1 2> /dev/null | grep postgres) || exit_skip " MISSING"
|
||||
echo " FOUND at" $(dirname $HAVE_INITDB)
|
||||
INITDB_BIN=$(echo $HAVE_INITDB | grep bin/initdb | grep postgres | sort -n | tail -n1)
|
||||
fi
|
||||
POSTGRES_PATH=`dirname $INITDB_BIN`
|
||||
MYDIR=`mktemp -d /tmp/taler-auditor-basedbXXXXXX`
|
||||
POSTGRES_PATH=$(dirname $INITDB_BIN)
|
||||
MYDIR=$(mktemp -d /tmp/taler-auditor-basedbXXXXXX)
|
||||
echo "Using $MYDIR for logging and temporary data"
|
||||
TMPDIR="$MYDIR/postgres/"
|
||||
mkdir -p $TMPDIR
|
||||
@ -2089,9 +2079,9 @@ PGHOST="$TMPDIR/sockets"
|
||||
export PGHOST
|
||||
|
||||
echo "Generating fresh database at $MYDIR"
|
||||
if faketime -f '-1 d' ./generate-auditor-basedb.sh $MYDIR/$DB
|
||||
if faketime -f '-1 d' ./generate-auditor-basedb.sh "$MYDIR/$DB"
|
||||
then
|
||||
check_with_database $MYDIR/$DB
|
||||
check_with_database "$MYDIR/$DB"
|
||||
if test x$fail != x0
|
||||
then
|
||||
exit $fail
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
This file is part of TALER
|
||||
Copyright (C) 2020-2021 Taler Systems SA
|
||||
Copyright (C) 2020-2023 Taler Systems SA
|
||||
|
||||
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
|
||||
@ -174,7 +174,7 @@ static struct DenominationAddRequest *dar_tail;
|
||||
/**
|
||||
* Handle to the exchange, used to request /keys.
|
||||
*/
|
||||
static struct TALER_EXCHANGE_Handle *exchange;
|
||||
static struct TALER_EXCHANGE_GetKeysHandle *exchange;
|
||||
|
||||
|
||||
/**
|
||||
@ -219,7 +219,7 @@ do_shutdown (void *cls)
|
||||
}
|
||||
if (NULL != exchange)
|
||||
{
|
||||
TALER_EXCHANGE_disconnect (exchange);
|
||||
TALER_EXCHANGE_get_keys_cancel (exchange);
|
||||
exchange = NULL;
|
||||
}
|
||||
if (NULL != nxt)
|
||||
@ -646,22 +646,23 @@ do_upload (char *const *args)
|
||||
*
|
||||
* @param cls closure with the `char **` remaining args
|
||||
* @param kr response data
|
||||
* @param keys key data from the exchange
|
||||
*/
|
||||
static void
|
||||
keys_cb (
|
||||
void *cls,
|
||||
const struct TALER_EXCHANGE_KeysResponse *kr)
|
||||
const struct TALER_EXCHANGE_KeysResponse *kr,
|
||||
struct TALER_EXCHANGE_Keys *keys)
|
||||
{
|
||||
char *const *args = cls;
|
||||
|
||||
exchange = NULL;
|
||||
switch (kr->hr.http_status)
|
||||
{
|
||||
case MHD_HTTP_OK:
|
||||
if (! json_is_object (kr->hr.reply))
|
||||
if (NULL == kr->hr.reply)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
TALER_EXCHANGE_disconnect (exchange);
|
||||
exchange = NULL;
|
||||
test_shutdown ();
|
||||
global_ret = EXIT_FAILURE;
|
||||
return;
|
||||
@ -673,8 +674,6 @@ keys_cb (
|
||||
kr->hr.hint,
|
||||
kr->hr.http_status,
|
||||
(unsigned int) kr->hr.ec);
|
||||
TALER_EXCHANGE_disconnect (exchange);
|
||||
exchange = NULL;
|
||||
test_shutdown ();
|
||||
global_ret = EXIT_FAILURE;
|
||||
return;
|
||||
@ -692,9 +691,8 @@ keys_cb (
|
||||
json_decref (in);
|
||||
in = NULL;
|
||||
}
|
||||
TALER_EXCHANGE_disconnect (exchange);
|
||||
exchange = NULL;
|
||||
next (args);
|
||||
TALER_EXCHANGE_keys_decref (keys);
|
||||
}
|
||||
|
||||
|
||||
@ -721,11 +719,11 @@ do_download (char *const *args)
|
||||
global_ret = EXIT_NOTCONFIGURED;
|
||||
return;
|
||||
}
|
||||
exchange = TALER_EXCHANGE_connect (ctx,
|
||||
exchange_url,
|
||||
&keys_cb,
|
||||
(void *) args,
|
||||
TALER_EXCHANGE_OPTION_END);
|
||||
exchange = TALER_EXCHANGE_get_keys (ctx,
|
||||
exchange_url,
|
||||
NULL,
|
||||
&keys_cb,
|
||||
(void *) args);
|
||||
GNUNET_free (exchange_url);
|
||||
}
|
||||
|
||||
|
@ -20,8 +20,8 @@ KYC_AML_TRIGGER = true
|
||||
# in the database. Should be a high-entropy nonce.
|
||||
ATTRIBUTE_ENCRYPTION_KEY = SET_ME_PLEASE
|
||||
|
||||
# Set to NO to disable tipping.
|
||||
ENABLE_TIPPING = YES
|
||||
# Set to NO to disable rewards.
|
||||
ENABLE_REWARDS = YES
|
||||
|
||||
# How long do we allow /keys to be cached at most? The actual
|
||||
# limit is the minimum of this value and the first expected
|
||||
|
@ -161,9 +161,9 @@ char *TEH_currency;
|
||||
char *TEH_kyc_aml_trigger;
|
||||
|
||||
/**
|
||||
* Option set to #GNUNET_YES if tipping is enabled.
|
||||
* Option set to #GNUNET_YES if rewards are enabled.
|
||||
*/
|
||||
int TEH_enable_tipping;
|
||||
int TEH_enable_rewards;
|
||||
|
||||
/**
|
||||
* What is the largest amount we allow a peer to
|
||||
@ -1943,15 +1943,15 @@ exchange_serve_process_config (void)
|
||||
"Amount in section `exchange' under `AML_THRESHOLD' uses the wrong currency!\n");
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
TEH_enable_tipping
|
||||
TEH_enable_rewards
|
||||
= GNUNET_CONFIGURATION_get_value_yesno (
|
||||
TEH_cfg,
|
||||
"exchange",
|
||||
"ENABLE_TIPPING");
|
||||
if (GNUNET_SYSERR == TEH_enable_tipping)
|
||||
"ENABLE_REWARDS");
|
||||
if (GNUNET_SYSERR == TEH_enable_rewards)
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Need YES or NO in section `exchange' under `ENABLE_TIPPING'\n");
|
||||
"Need YES or NO in section `exchange' under `ENABLE_REWARDS'\n");
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
if (GNUNET_OK !=
|
||||
|
@ -65,9 +65,9 @@ extern int TEH_check_invariants_flag;
|
||||
extern int TEH_allow_keys_timetravel;
|
||||
|
||||
/**
|
||||
* Option set to #GNUNET_YES if tipping is enabled.
|
||||
* Option set to #GNUNET_YES if rewards are allowed.
|
||||
*/
|
||||
extern int TEH_enable_tipping;
|
||||
extern int TEH_enable_rewards;
|
||||
|
||||
/**
|
||||
* Main directory with revocation data.
|
||||
|
@ -106,7 +106,7 @@ free_age_withdraw_context_resources (struct AgeWithdrawContext *awc)
|
||||
* @param connection The MHD connection to handle
|
||||
* @param j_denoms_h Array of n hashes of the denominations for the withdrawal, in JSON format
|
||||
* @param j_blinded_coin_evs Array of n arrays of kappa blinded envelopes of in JSON format for the coins.
|
||||
* @param[out] aws The context of the operation, only partially built at call time
|
||||
* @param[out] awc The context of the operation, only partially built at call time
|
||||
* @param[out] mhd_ret The result if a reply is queued for MHD
|
||||
* @return true on success, false on failure, with a reply already queued for MHD
|
||||
*/
|
||||
@ -315,7 +315,7 @@ EXIT:
|
||||
* @param connection HTTP-connection to the client
|
||||
* @param ksh The handle to the current state of (denomination) keys in the exchange
|
||||
* @param denom_h Hash of the denomination key to check
|
||||
* @param[out] dk On success, will contain the denomination key details
|
||||
* @param[out] pdk On success, will contain the denomination key details
|
||||
* @param[out] result On failure, an MHD-response will be qeued and result will be set to accordingly
|
||||
* @return true on success (denomination valid), false otherwise
|
||||
*/
|
||||
@ -402,10 +402,10 @@ denomination_is_valid (
|
||||
*
|
||||
* @param connection The HTTP connection to the client
|
||||
* @param len The lengths of the array @a denoms_h
|
||||
* @param denoms_h array of hashes of denomination public keys
|
||||
* @param denom_hs array of hashes of denomination public keys
|
||||
* @param coin_evs array of blinded coin planchets
|
||||
* @param[out] denom_serials On success, will be filled with the serial-id's of the denomination keys. Caller must deallocate.
|
||||
* @param[out] amount_with_fee On succes, will contain the committed amount including fees
|
||||
* @param[out] amount_with_fee On success, will contain the committed amount including fees
|
||||
* @param[out] result In the error cases, a response will be queued with MHD and this will be the result.
|
||||
* @return GNUNET_OK if the denominations are valid and support age-restriction
|
||||
* GNUNET_SYSERR otherwise
|
||||
@ -511,8 +511,7 @@ static enum GNUNET_GenericReturnValue
|
||||
verify_reserve_signature (
|
||||
struct MHD_Connection *connection,
|
||||
const struct TALER_EXCHANGEDB_AgeWithdraw *commitment,
|
||||
enum MHD_Result *mhd_ret
|
||||
)
|
||||
enum MHD_Result *mhd_ret)
|
||||
{
|
||||
|
||||
TEH_METRICS_num_verifications[TEH_MT_SIGNATURE_EDDSA]++;
|
||||
@ -824,10 +823,7 @@ age_withdraw_transaction (void *cls,
|
||||
* 2.) age withdraw was successful.
|
||||
*
|
||||
* @param connection HTTP-connection to the client
|
||||
* @param h_commitment Original commitment
|
||||
* @param num_coins Number of coins
|
||||
* @param coin_evs The Hashes of the undisclosed, blinded coins, @a num_coins many
|
||||
* @param denom_keys The array of denomination keys, @a num_coins. Needed to detect Clause-Schnorr-based denominations
|
||||
* @param awc The context for the current age withdraw request
|
||||
* @param[out] result On error, a HTTP-response will be queued and result set accordingly
|
||||
* @return GNUNET_OK on success, GNUNET_SYSERR otherwise
|
||||
*/
|
||||
|
@ -81,8 +81,6 @@ struct AgeRevealContext
|
||||
* memory for those.
|
||||
*
|
||||
* @param connection The MHD connection to handle
|
||||
* @param j_denoms_h Array of hashes of the denominations for the withdrawal, in JSON format
|
||||
* @param j_coin_evs The blinded envelopes in JSON format for the coins that are not revealed and will be signed on success
|
||||
* @param j_disclosed_coin_secrets The n*(kappa-1) disclosed coins' private keys in JSON format, from which all other attributes (age restriction, blinding, nonce) will be derived from
|
||||
* @param[out] actx The context of the operation, only partially built at call time
|
||||
* @param[out] mhd_ret The result if a reply is queued for MHD
|
||||
@ -223,7 +221,7 @@ find_original_commitment (
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
}
|
||||
/* after unsuccessfull retries*/
|
||||
/* after unsuccessful retries*/
|
||||
*result = TALER_MHD_reply_with_ec (connection,
|
||||
TALER_EC_GENERIC_DB_FETCH_FAILED,
|
||||
"get_age_withdraw_info");
|
||||
@ -235,11 +233,11 @@ find_original_commitment (
|
||||
* @brief Derives a age-restricted planchet from a given secret and calculates the hash
|
||||
*
|
||||
* @param connection Connection to the client
|
||||
* @param ksh The denomination keys in memory
|
||||
* @param keys The denomination keys in memory
|
||||
* @param secret The secret to a planchet
|
||||
* @param denom_pub_h The hash of the denomination for the planchet
|
||||
* @param max_age The maximum age allowed
|
||||
* @param[out] hc Hashcode to write
|
||||
* @param[out] bch Hashcode to write
|
||||
* @param[out] result On error, a HTTP-response will be queued and result set accordingly
|
||||
* @return GNUNET_OK on success, GNUNET_SYSERR otherwise, with an error message
|
||||
* written to the client and @e result set.
|
||||
|
@ -182,8 +182,7 @@ kyc_aml_finished (void *cls,
|
||||
kat->http_status = MHD_HTTP_INTERNAL_SERVER_ERROR;
|
||||
kat->response = TALER_MHD_make_error (TALER_EC_GENERIC_DB_STORE_FAILED,
|
||||
"do_insert_kyc_attributes");
|
||||
|
||||
/* FIXME-Christian: shouldn't we return in the error case? */
|
||||
/* Continued below to return the response */
|
||||
}
|
||||
/* Finally, return result to main handler */
|
||||
kat->cb (kat->cb_cls,
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
This file is part of TALER
|
||||
Copyright (C) 2020-2022 Taler Systems SA
|
||||
Copyright (C) 2020-2023 Taler Systems SA
|
||||
|
||||
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
|
||||
@ -801,7 +801,7 @@ destroy_key_helpers (struct HelperState *hs)
|
||||
* denomination.
|
||||
*/
|
||||
static struct TALER_AgeMask
|
||||
load_age_mask (const char*section_name)
|
||||
load_age_mask (const char *section_name)
|
||||
{
|
||||
static const struct TALER_AgeMask null_mask = {0};
|
||||
enum GNUNET_GenericReturnValue ret;
|
||||
@ -1701,8 +1701,10 @@ setup_general_response_headers (struct TEH_KeyStateHandle *ksh,
|
||||
TALER_MHD_get_date_string (m.abs_time,
|
||||
dat);
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||
"Setting /keys 'Expires' header to '%s'\n",
|
||||
dat);
|
||||
"Setting /keys 'Expires' header to '%s' (rekey frequency is %s)\n",
|
||||
dat,
|
||||
GNUNET_TIME_relative2s (ksh->rekey_frequency,
|
||||
false));
|
||||
GNUNET_break (MHD_YES ==
|
||||
MHD_add_response_header (response,
|
||||
MHD_HTTP_HEADER_EXPIRES,
|
||||
@ -1857,8 +1859,11 @@ create_krd (struct TEH_KeyStateHandle *ksh,
|
||||
TEH_currency),
|
||||
GNUNET_JSON_pack_string ("asset_type",
|
||||
asset_type),
|
||||
// FIXME: legacy, remove soon!
|
||||
GNUNET_JSON_pack_bool ("tipping_allowed",
|
||||
GNUNET_YES == TEH_enable_tipping),
|
||||
GNUNET_YES == TEH_enable_rewards),
|
||||
GNUNET_JSON_pack_bool ("rewards_allowed",
|
||||
GNUNET_YES == TEH_enable_rewards),
|
||||
GNUNET_JSON_pack_data_auto ("master_public_key",
|
||||
&TEH_master_public_key),
|
||||
GNUNET_JSON_pack_time_rel ("reserve_closing_delay",
|
||||
@ -2105,8 +2110,8 @@ finish_keys_response (struct TEH_KeyStateHandle *ksh)
|
||||
{
|
||||
struct TEH_DenominationKey *dk;
|
||||
struct GNUNET_CONTAINER_MultiHashMap *denominations_by_group;
|
||||
/* groupData is the value we store for each group meta-data */
|
||||
struct groupData
|
||||
/* GroupData is the value we store for each group meta-data */
|
||||
struct GroupData
|
||||
{
|
||||
/**
|
||||
* The json blob with the group meta-data and list of denominations
|
||||
@ -2210,7 +2215,7 @@ finish_keys_response (struct TEH_KeyStateHandle *ksh)
|
||||
*/
|
||||
{
|
||||
static const char *denoms_key = "denoms";
|
||||
struct groupData *group;
|
||||
struct GroupData *group;
|
||||
json_t *list;
|
||||
json_t *entry;
|
||||
struct GNUNET_HashCode key;
|
||||
@ -2221,25 +2226,19 @@ finish_keys_response (struct TEH_KeyStateHandle *ksh)
|
||||
.age_mask = dk->meta.age_mask,
|
||||
};
|
||||
|
||||
memset (&meta.hash, 0, sizeof(meta.hash));
|
||||
|
||||
/* Search the group/JSON-blob for the key */
|
||||
GNUNET_CRYPTO_hash (&meta, sizeof(meta), &key);
|
||||
|
||||
group =
|
||||
(struct groupData *) GNUNET_CONTAINER_multihashmap_get (
|
||||
denominations_by_group,
|
||||
&key);
|
||||
|
||||
TALER_denomination_group_get_key (&meta,
|
||||
&key);
|
||||
group = GNUNET_CONTAINER_multihashmap_get (
|
||||
denominations_by_group,
|
||||
&key);
|
||||
if (NULL == group)
|
||||
{
|
||||
/* There is no group for this meta-data yet, so we create a new group */
|
||||
bool age_restricted = meta.age_mask.bits != 0;
|
||||
char *cipher;
|
||||
|
||||
group = GNUNET_new (struct groupData);
|
||||
memset (group, 0, sizeof(*group));
|
||||
const char *cipher;
|
||||
|
||||
group = GNUNET_new (struct GroupData);
|
||||
switch (meta.cipher)
|
||||
{
|
||||
case TALER_DENOMINATION_RSA:
|
||||
@ -2253,9 +2252,12 @@ finish_keys_response (struct TEH_KeyStateHandle *ksh)
|
||||
}
|
||||
|
||||
group->json = GNUNET_JSON_PACK (
|
||||
GNUNET_JSON_pack_string ("cipher", cipher),
|
||||
TALER_JSON_PACK_DENOM_FEES ("fee", &meta.fees),
|
||||
TALER_JSON_pack_amount ("value", &meta.value));
|
||||
GNUNET_JSON_pack_string ("cipher",
|
||||
cipher),
|
||||
TALER_JSON_PACK_DENOM_FEES ("fee",
|
||||
&meta.fees),
|
||||
TALER_JSON_pack_amount ("value",
|
||||
&meta.value));
|
||||
GNUNET_assert (NULL != group->json);
|
||||
|
||||
if (age_restricted)
|
||||
@ -2294,17 +2296,16 @@ finish_keys_response (struct TEH_KeyStateHandle *ksh)
|
||||
{
|
||||
case TALER_DENOMINATION_RSA:
|
||||
key_spec =
|
||||
GNUNET_JSON_pack_rsa_public_key ("rsa_pub",
|
||||
dk->denom_pub.details.
|
||||
rsa_public_key);
|
||||
GNUNET_JSON_pack_rsa_public_key (
|
||||
"rsa_pub",
|
||||
dk->denom_pub.details.rsa_public_key);
|
||||
break;
|
||||
case TALER_DENOMINATION_CS:
|
||||
key_spec =
|
||||
GNUNET_JSON_pack_data_varsize ("cs_pub",
|
||||
&dk->denom_pub.details.
|
||||
cs_public_key,
|
||||
sizeof (dk->denom_pub.details.
|
||||
cs_public_key));
|
||||
GNUNET_JSON_pack_data_varsize (
|
||||
"cs_pub",
|
||||
&dk->denom_pub.details.cs_public_key,
|
||||
sizeof (dk->denom_pub.details.cs_public_key));
|
||||
break;
|
||||
default:
|
||||
GNUNET_assert (false);
|
||||
@ -2347,7 +2348,7 @@ finish_keys_response (struct TEH_KeyStateHandle *ksh)
|
||||
GNUNET_CONTAINER_multihashmap_size (denominations_by_group))
|
||||
{
|
||||
struct GNUNET_CONTAINER_MultiHashMapIterator *iter;
|
||||
struct groupData *group = NULL;
|
||||
struct GroupData *group = NULL;
|
||||
|
||||
iter =
|
||||
GNUNET_CONTAINER_multihashmap_iterator_create (denominations_by_group);
|
||||
@ -2372,15 +2373,12 @@ finish_keys_response (struct TEH_KeyStateHandle *ksh)
|
||||
json_array_append_new (
|
||||
grouped_denominations,
|
||||
group->json));
|
||||
|
||||
/* Build the running XOR over all hash(_xor) */
|
||||
GNUNET_CRYPTO_hash_xor (&group->hash_xor,
|
||||
&grouped_hash_xor,
|
||||
&grouped_hash_xor);
|
||||
|
||||
GNUNET_free (group);
|
||||
}
|
||||
|
||||
GNUNET_CONTAINER_multihashmap_iterator_destroy (iter);
|
||||
|
||||
}
|
||||
@ -2544,9 +2542,9 @@ build_key_state (struct HelperState *hs,
|
||||
ksh->helpers = hs;
|
||||
}
|
||||
ksh->denomkey_map = GNUNET_CONTAINER_multihashmap_create (1024,
|
||||
GNUNET_YES);
|
||||
true);
|
||||
ksh->signkey_map = GNUNET_CONTAINER_multipeermap_create (32,
|
||||
GNUNET_NO /* MUST be NO! */);
|
||||
false /* MUST be false! */);
|
||||
ksh->auditors = json_array ();
|
||||
GNUNET_assert (NULL != ksh->auditors);
|
||||
/* NOTE: fetches master-signed signkeys, but ALSO those that were revoked! */
|
||||
|
@ -94,7 +94,7 @@ age_restriction_load_config (
|
||||
ext->config = &AR_config;
|
||||
ext->enabled = true;
|
||||
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||
"loaded new age restriction config with age groups: %s\n",
|
||||
TALER_age_mask_to_string (&mask));
|
||||
|
||||
@ -112,7 +112,6 @@ static json_t *
|
||||
age_restriction_manifest (
|
||||
const struct TALER_Extension *ext)
|
||||
{
|
||||
char *mask_str;
|
||||
json_t *conf;
|
||||
|
||||
GNUNET_assert (NULL != ext);
|
||||
@ -124,12 +123,11 @@ age_restriction_manifest (
|
||||
return json_null ();
|
||||
}
|
||||
|
||||
mask_str = TALER_age_mask_to_string (&AR_config.mask);
|
||||
conf = GNUNET_JSON_PACK (
|
||||
GNUNET_JSON_pack_string ("age_groups", mask_str)
|
||||
GNUNET_JSON_pack_string ("age_groups",
|
||||
TALER_age_mask_to_string (&AR_config.mask))
|
||||
);
|
||||
|
||||
free (mask_str);
|
||||
|
||||
return GNUNET_JSON_PACK (
|
||||
GNUNET_JSON_pack_bool ("critical", ext->critical),
|
||||
|
@ -184,7 +184,7 @@ configure_extension (
|
||||
{
|
||||
struct LoadConfClosure *col = cls;
|
||||
const char *name;
|
||||
char *lib_name;
|
||||
char lib_name[1024] = {0};
|
||||
struct TALER_Extension *extension;
|
||||
|
||||
if (GNUNET_OK != col->error)
|
||||
@ -199,17 +199,16 @@ configure_extension (
|
||||
|
||||
|
||||
/* Load the extension library */
|
||||
GNUNET_asprintf (&lib_name,
|
||||
GNUNET_snprintf (lib_name,
|
||||
sizeof(lib_name),
|
||||
"libtaler_extension_%s",
|
||||
name);
|
||||
/* Lower-case extension name, config is case-insensitive */
|
||||
for (unsigned int i = 0; i < strlen (lib_name); i++)
|
||||
{
|
||||
lib_name[i] = tolower (lib_name[i]);
|
||||
}
|
||||
extension = GNUNET_PLUGIN_load (
|
||||
lib_name,
|
||||
(void *) col->cfg);
|
||||
|
||||
extension = GNUNET_PLUGIN_load (lib_name,
|
||||
(void *) col->cfg);
|
||||
if (NULL == extension)
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
|
@ -829,9 +829,9 @@ struct TALER_CoinPubHashP
|
||||
|
||||
|
||||
/**
|
||||
* @brief Value that uniquely identifies a tip.
|
||||
* @brief Value that uniquely identifies a reward.
|
||||
*/
|
||||
struct TALER_TipIdentifierP
|
||||
struct TALER_RewardIdentifierP
|
||||
{
|
||||
/**
|
||||
* The tip identifier is a SHA-512 hash code.
|
||||
@ -5947,33 +5947,54 @@ TALER_age_commitment_verify (
|
||||
/**
|
||||
* @brief helper function to free memory of a struct TALER_AgeCommitment
|
||||
*
|
||||
* @param p the commitment from which all memory should be freed.
|
||||
* @param ac the commitment from which all memory should be freed.
|
||||
*/
|
||||
void
|
||||
TALER_age_commitment_free (
|
||||
struct TALER_AgeCommitment *p);
|
||||
struct TALER_AgeCommitment *ac);
|
||||
|
||||
|
||||
/**
|
||||
* @brief helper function to free memory of a struct TALER_AgeProof
|
||||
*
|
||||
* @param p the proof of commitment from which all memory should be freed.
|
||||
* @param ap the proof of commitment from which all memory should be freed.
|
||||
*/
|
||||
void
|
||||
TALER_age_proof_free (
|
||||
struct TALER_AgeProof *p);
|
||||
struct TALER_AgeProof *ap);
|
||||
|
||||
|
||||
/**
|
||||
* @brief helper function to free memory of a struct TALER_AgeCommitmentProof
|
||||
*
|
||||
* @param p the commitment and its proof from which all memory should be freed.
|
||||
* @param acp the commitment and its proof from which all memory should be freed.
|
||||
*/
|
||||
void
|
||||
TALER_age_commitment_proof_free (
|
||||
struct TALER_AgeCommitmentProof *p);
|
||||
struct TALER_AgeCommitmentProof *acp);
|
||||
|
||||
|
||||
/**
|
||||
* @brief helper function to allocate and copy a struct TALER_AgeCommitmentProof
|
||||
*
|
||||
* @param[in] acp The original age commitment proof
|
||||
* @return The deep copy of @e acp, allocated
|
||||
*/
|
||||
struct TALER_AgeCommitmentProof *
|
||||
TALER_age_commitment_proof_duplicate (
|
||||
const struct TALER_AgeCommitmentProof *acp);
|
||||
|
||||
/**
|
||||
* @brief helper function to copy a struct TALER_AgeCommitmentProof
|
||||
*
|
||||
* @param[in] acp The original age commitment proof
|
||||
* @param[out] nacp The struct to copy the data into, with freshly allocated and copied keys.
|
||||
*/
|
||||
void
|
||||
TALER_age_commitment_proof_deep_copy (
|
||||
const struct TALER_AgeCommitmentProof *acp,
|
||||
struct TALER_AgeCommitmentProof *nacp);
|
||||
|
||||
/**
|
||||
* @brief For age-withdraw, clients have to prove that the public keys for all
|
||||
* age groups larger than the allowed maximum age group are derived by scalar
|
||||
@ -6011,4 +6032,56 @@ TALER_age_restriction_from_secret (
|
||||
struct TALER_AgeCommitmentProof *comm_proof);
|
||||
|
||||
|
||||
/**
|
||||
* Group of Denominations. These are the common fields of an array of
|
||||
* denominations.
|
||||
*
|
||||
* The corresponding JSON-blob will also contain an array of particular
|
||||
* denominations with only the timestamps, cipher-specific public key and the
|
||||
* master signature.
|
||||
*/
|
||||
struct TALER_DenominationGroup
|
||||
{
|
||||
|
||||
/**
|
||||
* XOR of all SHA-512 hashes of the public keys in this
|
||||
* group.
|
||||
*/
|
||||
struct GNUNET_HashCode hash;
|
||||
|
||||
/**
|
||||
* Value of coins in this denomination group.
|
||||
*/
|
||||
struct TALER_Amount value;
|
||||
|
||||
/**
|
||||
* Fee structure for all coins in the group.
|
||||
*/
|
||||
struct TALER_DenomFeeSet fees;
|
||||
|
||||
/**
|
||||
* Cipher used for the denomination.
|
||||
*/
|
||||
enum TALER_DenominationCipher cipher;
|
||||
|
||||
/**
|
||||
* Age mask for the denomiation.
|
||||
*/
|
||||
struct TALER_AgeMask age_mask;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Compute a unique key for the meta data of a denomination group.
|
||||
*
|
||||
* @param dg denomination group to evaluate
|
||||
* @param[out] key key to set
|
||||
*/
|
||||
void
|
||||
TALER_denomination_group_get_key (
|
||||
const struct TALER_DenominationGroup *dg,
|
||||
struct GNUNET_HashCode *key);
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -32,27 +32,6 @@
|
||||
|
||||
/* ********************* /keys *********************** */
|
||||
|
||||
/**
|
||||
* List of possible options to be passed to
|
||||
* #TALER_EXCHANGE_connect().
|
||||
*/
|
||||
enum TALER_EXCHANGE_Option
|
||||
{
|
||||
/**
|
||||
* Terminator (end of option list).
|
||||
*/
|
||||
TALER_EXCHANGE_OPTION_END = 0,
|
||||
|
||||
/**
|
||||
* Followed by a "const json_t *" that was previously returned for
|
||||
* this exchange URL by #TALER_EXCHANGE_serialize_data(). Used to
|
||||
* resume a connection to an exchange without having to re-download
|
||||
* /keys data (or at least only download the deltas).
|
||||
*/
|
||||
TALER_EXCHANGE_OPTION_DATA
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief Exchange's signature key
|
||||
@ -146,6 +125,7 @@ struct TALER_EXCHANGE_DenomPublicKey
|
||||
* revoked by the exchange.
|
||||
*/
|
||||
bool revoked;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -260,6 +240,11 @@ struct TALER_EXCHANGE_Keys
|
||||
*/
|
||||
struct TALER_MasterPublicKeyP master_pub;
|
||||
|
||||
/**
|
||||
* Signature over extension configuration data, if any.
|
||||
*/
|
||||
struct TALER_MasterSignatureP extensions_sig;
|
||||
|
||||
/**
|
||||
* Array of the exchange's online signing keys.
|
||||
*/
|
||||
@ -280,6 +265,11 @@ struct TALER_EXCHANGE_Keys
|
||||
*/
|
||||
struct TALER_EXCHANGE_GlobalFee *global_fees;
|
||||
|
||||
/**
|
||||
* Configuration data for extensions.
|
||||
*/
|
||||
json_t *extensions;
|
||||
|
||||
/**
|
||||
* Supported Taler protocol version by the exchange.
|
||||
* String in the format current:revision:age using the
|
||||
@ -294,11 +284,18 @@ struct TALER_EXCHANGE_Keys
|
||||
char *currency;
|
||||
|
||||
/**
|
||||
* How long after a reserve went idle will the exchange close it?
|
||||
* This is an approximate number, not cryptographically signed by
|
||||
* the exchange (advisory-only, may change anytime).
|
||||
* What is the base URL of the exchange that returned
|
||||
* these keys?
|
||||
*/
|
||||
struct GNUNET_TIME_Relative reserve_closing_delay;
|
||||
char *exchange_url;
|
||||
|
||||
/**
|
||||
* Asset type used by the exchange. Typical values
|
||||
* are "fiat" or "crypto" or "regional" or "stock".
|
||||
* Wallets should adjust their UI/UX based on this
|
||||
* value.
|
||||
*/
|
||||
char *asset_type;
|
||||
|
||||
/**
|
||||
* Array of amounts a wallet is allowed to hold from
|
||||
@ -307,16 +304,22 @@ struct TALER_EXCHANGE_Keys
|
||||
struct TALER_Amount *wallet_balance_limit_without_kyc;
|
||||
|
||||
/**
|
||||
* Length of the @e wallet_balance_limit_without_kyc
|
||||
* array.
|
||||
* How long after a reserve went idle will the exchange close it?
|
||||
* This is an approximate number, not cryptographically signed by
|
||||
* the exchange (advisory-only, may change anytime).
|
||||
*/
|
||||
unsigned int wblwk_length;
|
||||
struct GNUNET_TIME_Relative reserve_closing_delay;
|
||||
|
||||
/**
|
||||
* Timestamp indicating the /keys generation.
|
||||
*/
|
||||
struct GNUNET_TIME_Timestamp list_issue_date;
|
||||
|
||||
/**
|
||||
* When does this keys data expire?
|
||||
*/
|
||||
struct GNUNET_TIME_Timestamp key_data_expiration;
|
||||
|
||||
/**
|
||||
* Timestamp indicating the creation time of the last
|
||||
* denomination key in /keys.
|
||||
@ -329,6 +332,12 @@ struct TALER_EXCHANGE_Keys
|
||||
*/
|
||||
struct TALER_AgeMask age_mask;
|
||||
|
||||
/**
|
||||
* Length of the @e wallet_balance_limit_without_kyc
|
||||
* array.
|
||||
*/
|
||||
unsigned int wblwk_length;
|
||||
|
||||
/**
|
||||
* Length of the @e global_fees array.
|
||||
*/
|
||||
@ -360,17 +369,15 @@ struct TALER_EXCHANGE_Keys
|
||||
unsigned int denom_keys_size;
|
||||
|
||||
/**
|
||||
* Asset type used by the exchange. Typical values
|
||||
* are "fiat" or "crypto" or "regional" or "stock".
|
||||
* Wallets should adjust their UI/UX based on this
|
||||
* value.
|
||||
* Reference counter for this structure.
|
||||
* Freed when it reaches 0.
|
||||
*/
|
||||
char *asset_type;
|
||||
unsigned int rc;
|
||||
|
||||
/**
|
||||
* Set to true if tipping is allowed at this exchange.
|
||||
* Set to true if rewards are allowed at this exchange.
|
||||
*/
|
||||
bool tipping_allowed;
|
||||
bool rewards_allowed;
|
||||
};
|
||||
|
||||
|
||||
@ -505,77 +512,82 @@ struct TALER_EXCHANGE_KeysResponse
|
||||
/**
|
||||
* Function called with information about who is auditing
|
||||
* a particular exchange and what keys the exchange is using.
|
||||
* The ownership over the @a keys object is passed to
|
||||
* the callee, thus it is given explicitly and not
|
||||
* (only) via @a kr.
|
||||
*
|
||||
* @param cls closure
|
||||
* @param kr response from /keys
|
||||
* @param[in] keys keys object passed to callback with
|
||||
* reference counter of 1. Must be freed by callee
|
||||
* using #TALER_EXCHANGE_keys_decref(). NULL on failure.
|
||||
*/
|
||||
typedef void
|
||||
(*TALER_EXCHANGE_CertificationCallback) (
|
||||
(*TALER_EXCHANGE_GetKeysCallback) (
|
||||
void *cls,
|
||||
const struct TALER_EXCHANGE_KeysResponse *kr);
|
||||
const struct TALER_EXCHANGE_KeysResponse *kr,
|
||||
struct TALER_EXCHANGE_Keys *keys);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Handle to the exchange. This is where we interact with
|
||||
* a particular exchange and keep the per-exchange information.
|
||||
* @brief Handle for a GET /keys request.
|
||||
*/
|
||||
struct TALER_EXCHANGE_Handle;
|
||||
struct TALER_EXCHANGE_GetKeysHandle;
|
||||
|
||||
|
||||
/**
|
||||
* Initialise a connection to the exchange. Will connect to the
|
||||
* exchange and obtain information about the exchange's master public
|
||||
* key and the exchange's auditor. The respective information will
|
||||
* be passed to the @a cert_cb once available, and all future
|
||||
* interactions with the exchange will be checked to be signed
|
||||
* (where appropriate) by the respective master key.
|
||||
* Fetch the main /keys resources from an exchange. Does an incremental
|
||||
* fetch if @a last_keys is given. The obtained information will be passed to
|
||||
* the @a cert_cb (possibly after first merging it with @a last_keys to
|
||||
* produce a full picture; expired keys (for deposit) will be removed from @a
|
||||
* last_keys if there are any).
|
||||
*
|
||||
* @param ctx the context
|
||||
* @param url HTTP base URL for the exchange
|
||||
* @param[in,out] last_keys previous keys object, NULL for none
|
||||
* @param cert_cb function to call with the exchange's certification information,
|
||||
* possibly called repeatedly if the information changes
|
||||
* @param cert_cb_cls closure for @a cert_cb
|
||||
* @param ... list of additional arguments, terminated by #TALER_EXCHANGE_OPTION_END.
|
||||
* @return the exchange handle; NULL upon error
|
||||
*/
|
||||
struct TALER_EXCHANGE_Handle *
|
||||
TALER_EXCHANGE_connect (struct GNUNET_CURL_Context *ctx,
|
||||
const char *url,
|
||||
TALER_EXCHANGE_CertificationCallback cert_cb,
|
||||
void *cert_cb_cls,
|
||||
...);
|
||||
struct TALER_EXCHANGE_GetKeysHandle *
|
||||
TALER_EXCHANGE_get_keys (
|
||||
struct GNUNET_CURL_Context *ctx,
|
||||
const char *url,
|
||||
struct TALER_EXCHANGE_Keys *last_keys,
|
||||
TALER_EXCHANGE_GetKeysCallback cert_cb,
|
||||
void *cert_cb_cls);
|
||||
|
||||
|
||||
/**
|
||||
* Serialize the latest key data from @a exchange to be persisted
|
||||
* on disk (to be used with #TALER_EXCHANGE_OPTION_DATA to more
|
||||
* efficiently recover the state).
|
||||
* Serialize the latest data from @a keys to be persisted
|
||||
* (for example, to be used as @a last_keys later).
|
||||
*
|
||||
* @param exchange which exchange's key and wire data should be serialized
|
||||
* @return NULL on error (i.e. no current data available); otherwise
|
||||
* json object owned by the caller
|
||||
* @param kd the key data to serialize
|
||||
* @return NULL on error; otherwise JSON object owned by the caller
|
||||
*/
|
||||
json_t *
|
||||
TALER_EXCHANGE_serialize_data (struct TALER_EXCHANGE_Handle *exchange);
|
||||
TALER_EXCHANGE_keys_to_json (const struct TALER_EXCHANGE_Keys *kd);
|
||||
|
||||
|
||||
/**
|
||||
* Disconnect from the exchange.
|
||||
* Deserialize keys data stored in @a j.
|
||||
*
|
||||
* @param exchange the exchange handle
|
||||
*/
|
||||
void
|
||||
TALER_EXCHANGE_disconnect (struct TALER_EXCHANGE_Handle *exchange);
|
||||
|
||||
|
||||
/**
|
||||
* Obtain the keys from the exchange.
|
||||
*
|
||||
* @param exchange the exchange handle
|
||||
* @return the exchange's key set
|
||||
* @param j JSON keys data previously returned from #TALER_EXCHANGE_keys_to_json()
|
||||
* @return NULL on error (i.e. invalid JSON); otherwise
|
||||
* keys object with reference counter 1 owned by the caller
|
||||
*/
|
||||
struct TALER_EXCHANGE_Keys *
|
||||
TALER_EXCHANGE_get_keys (struct TALER_EXCHANGE_Handle *exchange);
|
||||
TALER_EXCHANGE_keys_from_json (const json_t *j);
|
||||
|
||||
|
||||
/**
|
||||
* Cancel GET /keys operation.
|
||||
*
|
||||
* @param[in] gkh the GET /keys handle
|
||||
*/
|
||||
void
|
||||
TALER_EXCHANGE_get_keys_cancel (struct TALER_EXCHANGE_GetKeysHandle *gkh);
|
||||
|
||||
|
||||
/**
|
||||
@ -598,90 +610,6 @@ void
|
||||
TALER_EXCHANGE_keys_decref (struct TALER_EXCHANGE_Keys *keys);
|
||||
|
||||
|
||||
/**
|
||||
* Let the user set the last valid denomination time manually.
|
||||
*
|
||||
* @param exchange the exchange handle.
|
||||
* @param last_denom_new new last denomination time.
|
||||
*/
|
||||
void
|
||||
TALER_EXCHANGE_set_last_denom (
|
||||
struct TALER_EXCHANGE_Handle *exchange,
|
||||
struct GNUNET_TIME_Timestamp last_denom_new);
|
||||
|
||||
|
||||
/**
|
||||
* Flags for #TALER_EXCHANGE_check_keys_current().
|
||||
*/
|
||||
enum TALER_EXCHANGE_CheckKeysFlags
|
||||
{
|
||||
/**
|
||||
* No special options.
|
||||
*/
|
||||
TALER_EXCHANGE_CKF_NONE,
|
||||
|
||||
/**
|
||||
* Force downloading /keys now, even if /keys is still valid
|
||||
* (that is, the period advertised by the exchange for re-downloads
|
||||
* has not yet expired).
|
||||
*/
|
||||
TALER_EXCHANGE_CKF_FORCE_DOWNLOAD = 1,
|
||||
|
||||
/**
|
||||
* Pull all keys again, resetting the client state to the original state.
|
||||
* Using this flag disables the incremental download, and also prevents using
|
||||
* the context until the re-download has completed.
|
||||
*/
|
||||
TALER_EXCHANGE_CKF_PULL_ALL_KEYS = 2,
|
||||
|
||||
/**
|
||||
* Force downloading all keys now.
|
||||
*/
|
||||
TALER_EXCHANGE_CKF_FORCE_ALL_NOW = TALER_EXCHANGE_CKF_FORCE_DOWNLOAD
|
||||
| TALER_EXCHANGE_CKF_PULL_ALL_KEYS
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Check if our current response for /keys is valid, and if
|
||||
* not, trigger /keys download. If @a cb is given, changes
|
||||
* the @a exchange callback for the /keys response.
|
||||
*
|
||||
* @param exchange exchange to check keys for
|
||||
* @param flags options controlling when to download what
|
||||
* @param cb function to call with the /keys response, can be NULL
|
||||
* @param cb_cls closure for @a cb
|
||||
* @return until when the existing response is current, 0 if we are re-downloading now
|
||||
*/
|
||||
struct GNUNET_TIME_Timestamp
|
||||
TALER_EXCHANGE_check_keys_current (
|
||||
struct TALER_EXCHANGE_Handle *exchange,
|
||||
enum TALER_EXCHANGE_CheckKeysFlags flags,
|
||||
TALER_EXCHANGE_CertificationCallback cb,
|
||||
void *cb_cls);
|
||||
|
||||
|
||||
/**
|
||||
* Obtain the keys from the exchange in the raw JSON format.
|
||||
*
|
||||
* @param exchange the exchange handle
|
||||
* @return the exchange's keys in raw JSON
|
||||
*/
|
||||
json_t *
|
||||
TALER_EXCHANGE_get_keys_raw (struct TALER_EXCHANGE_Handle *exchange);
|
||||
|
||||
|
||||
/**
|
||||
* Obtain the keys from the exchange in the raw JSON format.
|
||||
*
|
||||
* @param keys the keys structure
|
||||
* @return the keys in raw JSON
|
||||
*/
|
||||
json_t *
|
||||
TALER_EXCHANGE_keys_to_json (struct TALER_EXCHANGE_Keys *keys);
|
||||
|
||||
|
||||
/**
|
||||
* Test if the given @a pub is a the current signing key from the exchange
|
||||
* according to @a keys.
|
||||
@ -691,18 +619,9 @@ TALER_EXCHANGE_keys_to_json (struct TALER_EXCHANGE_Keys *keys);
|
||||
* @return #GNUNET_OK if @a pub is (according to /keys) a current signing key
|
||||
*/
|
||||
enum GNUNET_GenericReturnValue
|
||||
TALER_EXCHANGE_test_signing_key (const struct TALER_EXCHANGE_Keys *keys,
|
||||
const struct TALER_ExchangePublicKeyP *pub);
|
||||
|
||||
|
||||
/**
|
||||
* Get exchange's base URL.
|
||||
*
|
||||
* @param exchange exchange handle.
|
||||
* @return the base URL from the handle.
|
||||
*/
|
||||
const char *
|
||||
TALER_EXCHANGE_get_base_url (const struct TALER_EXCHANGE_Handle *exchange);
|
||||
TALER_EXCHANGE_test_signing_key (
|
||||
const struct TALER_EXCHANGE_Keys *keys,
|
||||
const struct TALER_ExchangePublicKeyP *pub);
|
||||
|
||||
|
||||
/**
|
||||
@ -736,7 +655,8 @@ TALER_EXCHANGE_get_global_fee (
|
||||
* Create a copy of a denomination public key.
|
||||
*
|
||||
* @param key key to copy
|
||||
* @returns a copy, must be freed with #TALER_EXCHANGE_destroy_denomination_key
|
||||
* @returns a copy, must be freed with #TALER_EXCHANGE_destroy_denomination_key()
|
||||
* @deprecated
|
||||
*/
|
||||
struct TALER_EXCHANGE_DenomPublicKey *
|
||||
TALER_EXCHANGE_copy_denomination_key (
|
||||
@ -745,9 +665,10 @@ TALER_EXCHANGE_copy_denomination_key (
|
||||
|
||||
/**
|
||||
* Destroy a denomination public key.
|
||||
* Should only be called with keys created by #TALER_EXCHANGE_copy_denomination_key.
|
||||
* Should only be called with keys created by #TALER_EXCHANGE_copy_denomination_key().
|
||||
*
|
||||
* @param key key to destroy.
|
||||
* @deprecated
|
||||
*/
|
||||
void
|
||||
TALER_EXCHANGE_destroy_denomination_key (
|
||||
@ -2828,13 +2749,16 @@ TALER_EXCHANGE_batch_withdraw2_cancel (
|
||||
*/
|
||||
struct TALER_EXCHANGE_AgeWithdrawCoinInput
|
||||
{
|
||||
/* The master secret from which we derive all other relevant values for
|
||||
/**
|
||||
* The master secret from which we derive all other relevant values for
|
||||
* the coin: private key, nonces (if applicable) and age restriction
|
||||
*/
|
||||
const struct TALER_PlanchetMasterSecretP secret[TALER_CNC_KAPPA];
|
||||
|
||||
/* The denomination of the coin. Must support age restriction, i.e
|
||||
* its .keys.age_mask MUST not be 0 */
|
||||
/**
|
||||
* The denomination of the coin. Must support age restriction, i.e
|
||||
* its .keys.age_mask MUST not be 0
|
||||
*/
|
||||
const struct TALER_EXCHANGE_DenomPublicKey *denom_pub;
|
||||
};
|
||||
|
||||
@ -2901,7 +2825,7 @@ typedef void
|
||||
*
|
||||
* @param curl_ctx The curl context
|
||||
* @param exchange_url The base url of the exchange
|
||||
* @parm keys The denomination keys from the exchange
|
||||
* @param keys The denomination keys from the exchange
|
||||
* @param reserve_priv The pivate key to the reserve
|
||||
* @param num_coins The number of elements in @e coin_inputs
|
||||
* @param coin_inputs The input for the coins to withdraw
|
||||
@ -2918,8 +2842,8 @@ TALER_EXCHANGE_age_withdraw (
|
||||
struct TALER_EXCHANGE_Keys *keys,
|
||||
const struct TALER_ReservePrivateKeyP *reserve_priv,
|
||||
size_t num_coins,
|
||||
const struct TALER_EXCHANGE_AgeWithdrawCoinInput coin_inputs[
|
||||
const static num_coins],
|
||||
const struct TALER_EXCHANGE_AgeWithdrawCoinInput coin_inputs[const static
|
||||
num_coins],
|
||||
uint8_t max_age,
|
||||
TALER_EXCHANGE_AgeWithdrawCallback res_cb,
|
||||
void *res_cb_cls);
|
||||
@ -3133,7 +3057,7 @@ struct TALER_EXCHANGE_RevealedCoinInfo
|
||||
* Age commitment and its hash of the coin, might be NULL.
|
||||
*/
|
||||
struct TALER_AgeCommitmentProof *age_commitment_proof;
|
||||
struct TALER_AgeCommitmentHash *h_age_commitment;
|
||||
struct TALER_AgeCommitmentHash h_age_commitment;
|
||||
|
||||
/**
|
||||
* Blinding keys used to blind the fresh coin.
|
||||
@ -3220,7 +3144,6 @@ struct TALER_EXCHANGE_RefreshesRevealHandle;
|
||||
*
|
||||
* @param ctx curl context
|
||||
* @param url exchange base URL
|
||||
* @param keys exchange keys
|
||||
* @param rms the fresh secret that defines the refresh operation
|
||||
* @param rd the refresh data that characterizes the refresh operation
|
||||
* @param num_coins number of fresh coins to be created, length of the @a exchange_vals array, must match value in @a rd
|
||||
@ -3277,10 +3200,11 @@ struct TALER_EXCHANGE_LinkedCoinInfo
|
||||
struct TALER_CoinSpendPrivateKeyP coin_priv;
|
||||
|
||||
/**
|
||||
* Age commitment and its hash, if applicable. Might be NULL.
|
||||
* Age commitment and its hash, if applicable.
|
||||
*/
|
||||
struct TALER_AgeCommitmentProof *age_commitment_proof;
|
||||
struct TALER_AgeCommitmentHash *h_age_commitment;
|
||||
bool has_age_commitment;
|
||||
struct TALER_AgeCommitmentProof age_commitment_proof;
|
||||
struct TALER_AgeCommitmentHash h_age_commitment;
|
||||
|
||||
/**
|
||||
* Master secret of this coin.
|
||||
|
@ -380,26 +380,6 @@ TALER_JSON_spec_amount_any_nbo (const char *name,
|
||||
TALER_JSON_pack_amount ("account_fee", &(gfs)->account), \
|
||||
TALER_JSON_pack_amount ("purse_fee", &(gfs)->purse)
|
||||
|
||||
/**
|
||||
* Group of Denominations. These are the common fields of an array of
|
||||
* denominations.
|
||||
*
|
||||
* The corresponding JSON-blob will also contain an array of particular
|
||||
* denominations with only the timestamps, cipher-specific public key and the
|
||||
* master signature.
|
||||
*
|
||||
**/
|
||||
struct TALER_DenominationGroup
|
||||
{
|
||||
enum TALER_DenominationCipher cipher;
|
||||
struct TALER_Amount value;
|
||||
struct TALER_DenomFeeSet fees;
|
||||
struct TALER_AgeMask age_mask;
|
||||
|
||||
// hash is/should be the XOR of all SHA-512 hashes of the public keys in this
|
||||
// group
|
||||
struct GNUNET_HashCode hash;
|
||||
};
|
||||
|
||||
/**
|
||||
* Generate a parser for a group of denominations.
|
||||
|
@ -57,18 +57,44 @@
|
||||
*
|
||||
* @param is interpreter to fail
|
||||
* @param status unexpected HTTP status code received
|
||||
* @param expected expected HTTP status code
|
||||
*/
|
||||
#define TALER_TESTING_unexpected_status(is,status) \
|
||||
#define TALER_TESTING_unexpected_status(is,status,expected) \
|
||||
do { \
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR, \
|
||||
"Unexpected response code %u to command %s in %s:%u\n", \
|
||||
"Unexpected response code %u (expected: %u) to command %s in %s:%u\n", \
|
||||
status, \
|
||||
expected, \
|
||||
TALER_TESTING_interpreter_get_current_label (is), \
|
||||
__FILE__, \
|
||||
__LINE__); \
|
||||
TALER_TESTING_interpreter_fail (is); \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* Log an error message about us receiving an unexpected HTTP
|
||||
* status code at the current command and fail the test and print the response
|
||||
* body (expected as json).
|
||||
*
|
||||
* @param is interpreter to fail
|
||||
* @param status unexpected HTTP status code received
|
||||
* @param expected expected HTTP status code
|
||||
* @param body received JSON-reply
|
||||
*/
|
||||
#define TALER_TESTING_unexpected_status_with_body(is,status,expected,body) \
|
||||
do { \
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR, \
|
||||
"Unexpected response code %u (expected: %u) to " \
|
||||
"command %s in %s:%u\nwith body:\n>>%s<<\n", \
|
||||
status, \
|
||||
expected, \
|
||||
TALER_TESTING_interpreter_get_current_label (is), \
|
||||
__FILE__, \
|
||||
__LINE__, \
|
||||
json_dumps (body, JSON_INDENT (2))); \
|
||||
TALER_TESTING_interpreter_fail (is); \
|
||||
} while (0)
|
||||
|
||||
|
||||
/**
|
||||
* Log an error message about a command not having
|
||||
@ -85,7 +111,7 @@
|
||||
__FILE__, \
|
||||
__LINE__, \
|
||||
TALER_TESTING_interpreter_get_current_label (is)); \
|
||||
}while (0)
|
||||
} while (0)
|
||||
|
||||
|
||||
/**
|
||||
@ -623,6 +649,7 @@ TALER_TESTING_cmd_system_start (
|
||||
*
|
||||
* @param label command label
|
||||
* @param cfg configuration to use
|
||||
* @param last_keys_ref reference to command with prior /keys response, NULL for none
|
||||
* @param wait_for_keys block until we got /keys
|
||||
* @param load_private_key obtain private key from file indicated in @a cfg
|
||||
* @return the command.
|
||||
@ -631,6 +658,7 @@ struct TALER_TESTING_Command
|
||||
TALER_TESTING_cmd_get_exchange (
|
||||
const char *label,
|
||||
const struct GNUNET_CONFIGURATION_Handle *cfg,
|
||||
const char *last_keys_ref,
|
||||
bool wait_for_keys,
|
||||
bool load_private_key);
|
||||
|
||||
@ -1786,45 +1814,6 @@ struct TALER_TESTING_Command
|
||||
TALER_TESTING_cmd_wait_service (const char *label,
|
||||
const char *url);
|
||||
|
||||
|
||||
/**
|
||||
* Make a "check keys" command.
|
||||
*
|
||||
* @param label command label
|
||||
* @return the command.
|
||||
*/
|
||||
struct TALER_TESTING_Command
|
||||
TALER_TESTING_cmd_check_keys (const char *label);
|
||||
|
||||
|
||||
/**
|
||||
* Make a "check keys" command that forcedly does NOT cherry pick;
|
||||
* just redownload the whole /keys.
|
||||
*
|
||||
* @param label command label
|
||||
* @return the command.
|
||||
*/
|
||||
struct TALER_TESTING_Command
|
||||
TALER_TESTING_cmd_check_keys_pull_all_keys (const char *label);
|
||||
|
||||
|
||||
/**
|
||||
* Make a "check keys" command. It lets the user set a last denom issue date to be
|
||||
* used in the request for /keys.
|
||||
*
|
||||
* @param label command label
|
||||
* @param last_denom_date_ref previous /keys command to use to
|
||||
* obtain the "last_denom_date" value from; "zero" can be used
|
||||
* as a special value to force an absolute time of zero to be
|
||||
* given to as an argument
|
||||
* @return the command.
|
||||
*/
|
||||
struct TALER_TESTING_Command
|
||||
TALER_TESTING_cmd_check_keys_with_last_denom (
|
||||
const char *label,
|
||||
const char *last_denom_date_ref);
|
||||
|
||||
|
||||
/**
|
||||
* Create a "batch" command. Such command takes a
|
||||
* end_CMD-terminated array of CMDs and executed them.
|
||||
@ -1883,31 +1872,6 @@ TALER_TESTING_cmd_batch_set_current (const struct TALER_TESTING_Command *cmd,
|
||||
unsigned int new_ip);
|
||||
|
||||
|
||||
/**
|
||||
* Make a serialize-keys CMD.
|
||||
*
|
||||
* @param label CMD label
|
||||
* @return the CMD.
|
||||
*/
|
||||
struct TALER_TESTING_Command
|
||||
TALER_TESTING_cmd_serialize_keys (const char *label);
|
||||
|
||||
|
||||
/**
|
||||
* Make a connect-with-state CMD. This command
|
||||
* will use a serialized key state to reconnect
|
||||
* to the exchange.
|
||||
*
|
||||
* @param label command label
|
||||
* @param state_reference label of a CMD offering
|
||||
* a serialized key state.
|
||||
* @return the CMD.
|
||||
*/
|
||||
struct TALER_TESTING_Command
|
||||
TALER_TESTING_cmd_connect_with_state (const char *label,
|
||||
const char *state_reference);
|
||||
|
||||
|
||||
/**
|
||||
* Make the "insert-deposit" CMD.
|
||||
*
|
||||
@ -2246,6 +2210,7 @@ TALER_TESTING_cmd_proof_kyc_oauth2 (
|
||||
* KYC processes which also provides a @a birthdate in a response
|
||||
*
|
||||
* @param label command label
|
||||
* @param birthdate fixed birthdate, such as "2022-03-04", "2022-03-00", "2022-00-00"
|
||||
* @param port the TCP port to listen on
|
||||
*/
|
||||
struct TALER_TESTING_Command
|
||||
@ -2499,6 +2464,30 @@ TALER_TESTING_cmd_check_aml_decisions (
|
||||
unsigned int expected_http_status);
|
||||
|
||||
|
||||
/* ****************** convenience functions ************** */
|
||||
|
||||
/**
|
||||
* Get exchange URL from interpreter. Convenience function.
|
||||
*
|
||||
* @param is interpreter state.
|
||||
* @return the exchange URL, or NULL on error
|
||||
*/
|
||||
const char *
|
||||
TALER_TESTING_get_exchange_url (
|
||||
struct TALER_TESTING_Interpreter *is);
|
||||
|
||||
|
||||
/**
|
||||
* Get exchange keys from interpreter. Convenience function.
|
||||
*
|
||||
* @param is interpreter state.
|
||||
* @return the exchange keys, or NULL on error
|
||||
*/
|
||||
struct TALER_EXCHANGE_Keys *
|
||||
TALER_TESTING_get_keys (
|
||||
struct TALER_TESTING_Interpreter *is);
|
||||
|
||||
|
||||
/* *** Generic trait logic for implementing traits ********* */
|
||||
|
||||
|
||||
@ -2657,13 +2646,13 @@ TALER_TESTING_get_trait (const struct TALER_TESTING_Trait *traits,
|
||||
op (bank_row, const uint64_t) \
|
||||
op (officer_pub, const struct TALER_AmlOfficerPublicKeyP) \
|
||||
op (officer_priv, const struct TALER_AmlOfficerPrivateKeyP) \
|
||||
op (officer_name, const char) \
|
||||
op (officer_name, const char) \
|
||||
op (aml_decision, enum TALER_AmlDecisionState) \
|
||||
op (aml_justification, const char) \
|
||||
op (auditor_priv, const struct TALER_AuditorPrivateKeyP) \
|
||||
op (auditor_pub, const struct TALER_AuditorPublicKeyP) \
|
||||
op (master_priv, const struct TALER_MasterPrivateKeyP) \
|
||||
op (master_pub, const struct TALER_MasterPublicKeyP) \
|
||||
op (aml_justification, const char) \
|
||||
op (auditor_priv, const struct TALER_AuditorPrivateKeyP) \
|
||||
op (auditor_pub, const struct TALER_AuditorPublicKeyP) \
|
||||
op (master_priv, const struct TALER_MasterPrivateKeyP) \
|
||||
op (master_pub, const struct TALER_MasterPublicKeyP) \
|
||||
op (purse_priv, const struct TALER_PurseContractPrivateKeyP) \
|
||||
op (purse_pub, const struct TALER_PurseContractPublicKeyP) \
|
||||
op (merge_priv, const struct TALER_PurseMergePrivateKeyP) \
|
||||
@ -2682,7 +2671,6 @@ TALER_TESTING_get_trait (const struct TALER_TESTING_Trait *traits,
|
||||
op (bank_auth_data, const struct TALER_BANK_AuthenticationData) \
|
||||
op (contract_terms, const json_t) \
|
||||
op (wire_details, const json_t) \
|
||||
op (exchange_keys, const json_t) \
|
||||
op (exchange_url, const char) \
|
||||
op (auditor_url, const char) \
|
||||
op (exchange_bank_account_url, const char) \
|
||||
@ -2703,7 +2691,6 @@ TALER_TESTING_get_trait (const struct TALER_TESTING_Trait *traits,
|
||||
op (fresh_coins, const struct TALER_TESTING_FreshCoinData *) \
|
||||
op (claim_token, const struct TALER_ClaimTokenP) \
|
||||
op (relative_time, const struct GNUNET_TIME_Relative) \
|
||||
op (exchange, struct TALER_EXCHANGE_Handle) \
|
||||
op (fakebank, struct TALER_FAKEBANK_Handle) \
|
||||
op (keys, struct TALER_EXCHANGE_Keys) \
|
||||
op (process, struct GNUNET_OS_Process *)
|
||||
@ -2740,38 +2727,4 @@ TALER_TESTING_SIMPLE_TRAITS (TALER_TESTING_MAKE_DECL_SIMPLE_TRAIT)
|
||||
TALER_TESTING_INDEXED_TRAITS (TALER_TESTING_MAKE_DECL_INDEXED_TRAIT)
|
||||
|
||||
|
||||
/* ****************** convenience functions ************** */
|
||||
|
||||
/**
|
||||
* Get exchange handle from interpreter. Convenience function.
|
||||
*
|
||||
* @param is interpreter state.
|
||||
* @return the exchange handle, or NULL on error
|
||||
*/
|
||||
struct TALER_EXCHANGE_Handle *
|
||||
TALER_TESTING_get_exchange (struct TALER_TESTING_Interpreter *is);
|
||||
|
||||
|
||||
/**
|
||||
* Get exchange URL from interpreter. Convenience function.
|
||||
*
|
||||
* @param is interpreter state.
|
||||
* @return the exchange URL, or NULL on error
|
||||
*/
|
||||
const char *
|
||||
TALER_TESTING_get_exchange_url (
|
||||
struct TALER_TESTING_Interpreter *is);
|
||||
|
||||
|
||||
/**
|
||||
* Get exchange keys from interpreter. Convenience function.
|
||||
*
|
||||
* @param is interpreter state.
|
||||
* @return the exchange keys, or NULL on error
|
||||
*/
|
||||
struct TALER_EXCHANGE_Keys *
|
||||
TALER_TESTING_get_keys (
|
||||
struct TALER_TESTING_Interpreter *is);
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -578,11 +578,14 @@ TALER_parse_age_group_string (
|
||||
/**
|
||||
* @brief Encodes the age mask into a string, like "8:10:12:14:16:18:21"
|
||||
*
|
||||
* NOTE: This function uses a static buffer. It is not safe to call this
|
||||
* function concurrently.
|
||||
*
|
||||
* @param mask Age mask
|
||||
* @return String representation of the age mask, allocated by GNUNET_malloc.
|
||||
* @return String representation of the age mask.
|
||||
* Can be used as value in the TALER config.
|
||||
*/
|
||||
char *
|
||||
const char *
|
||||
TALER_age_mask_to_string (
|
||||
const struct TALER_AgeMask *mask);
|
||||
|
||||
|
@ -279,6 +279,11 @@ parse_denomination_group (void *cls,
|
||||
&emsg,
|
||||
&eline))
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
|
||||
"Failed to parse %s at %u: %s\n",
|
||||
spec[eline].field,
|
||||
eline,
|
||||
emsg);
|
||||
GNUNET_break_op (0);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
|
@ -95,7 +95,7 @@ struct TALER_AUDITOR_GetConfigHandle
|
||||
* in the @a key_data.
|
||||
*
|
||||
* @param[in] resp_obj JSON object to parse
|
||||
* @param[in,out] auditor where to store the results we decoded
|
||||
* @param[in,out] vi where to store the results we decoded
|
||||
* @param[out] vc where to store config compatibility data
|
||||
* @return #TALER_EC_NONE on success
|
||||
*/
|
||||
|
@ -382,7 +382,8 @@ reserve_age_withdraw_payment_required (
|
||||
* HTTP /reserves/$RESERVE_PUB/age-withdraw request.
|
||||
*
|
||||
* @param cls the `struct TALER_EXCHANGE_AgeWithdrawHandle`
|
||||
* @param aw2r response data
|
||||
* @param response_code The HTTP response code
|
||||
* @param response response data
|
||||
*/
|
||||
static void
|
||||
handle_reserve_age_withdraw_finished (
|
||||
@ -651,6 +652,7 @@ ERROR:
|
||||
* Prepares the request URL for the age-withdraw request
|
||||
*
|
||||
* @param awh The handler
|
||||
* @param exchange_url The base-URL to the exchange
|
||||
*/
|
||||
static
|
||||
enum GNUNET_GenericReturnValue
|
||||
@ -770,7 +772,7 @@ csr_withdraw_done (
|
||||
*
|
||||
* @param awh The handler to the age-withdraw
|
||||
* @param num_coins The number of coins in @e coin_inputs
|
||||
* @param coin_inputs The input for the individial coin(-candidates)
|
||||
* @param coin_inputs The input for the individual coin(-candidates)
|
||||
* @return GNUNET_OK on success, GNUNET_SYSERR on failure
|
||||
*/
|
||||
static
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
||||
/*
|
||||
This file is part of TALER
|
||||
Copyright (C) 2014, 2015 Taler Systems SA
|
||||
Copyright (C) 2014, 2015, 2023 Taler Systems SA
|
||||
|
||||
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
|
||||
@ -28,124 +28,6 @@
|
||||
#include "taler_util.h"
|
||||
#include "taler_curl_lib.h"
|
||||
|
||||
/**
|
||||
* Entry in DLL of auditors used by an exchange.
|
||||
*/
|
||||
struct TEAH_AuditorListEntry;
|
||||
|
||||
|
||||
/**
|
||||
* Stages of initialization for the `struct TALER_EXCHANGE_Handle`
|
||||
*/
|
||||
enum ExchangeHandleState
|
||||
{
|
||||
/**
|
||||
* Just allocated.
|
||||
*/
|
||||
MHS_INIT = 0,
|
||||
|
||||
/**
|
||||
* Obtained the exchange's certification data and keys.
|
||||
*/
|
||||
MHS_CERT = 1,
|
||||
|
||||
/**
|
||||
* Failed to initialize (fatal).
|
||||
*/
|
||||
MHS_FAILED = 2
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Handle to the exchange
|
||||
*/
|
||||
struct TALER_EXCHANGE_Handle
|
||||
{
|
||||
/**
|
||||
* The context of this handle
|
||||
*/
|
||||
struct GNUNET_CURL_Context *ctx;
|
||||
|
||||
/**
|
||||
* The URL of the exchange (i.e. "http://exchange.taler.net/")
|
||||
*/
|
||||
char *url;
|
||||
|
||||
/**
|
||||
* Function to call with the exchange's certification data,
|
||||
* NULL if this has already been done.
|
||||
*/
|
||||
TALER_EXCHANGE_CertificationCallback cert_cb;
|
||||
|
||||
/**
|
||||
* Closure to pass to @e cert_cb.
|
||||
*/
|
||||
void *cert_cb_cls;
|
||||
|
||||
/**
|
||||
* Data for the request to get the /keys of a exchange,
|
||||
* NULL once we are past stage #MHS_INIT.
|
||||
*/
|
||||
struct KeysRequest *kr;
|
||||
|
||||
/**
|
||||
* Task for retrying /keys request.
|
||||
*/
|
||||
struct GNUNET_SCHEDULER_Task *retry_task;
|
||||
|
||||
/**
|
||||
* Raw key data of the exchange, only valid if
|
||||
* @e handshake_complete is past stage #MHS_CERT.
|
||||
*/
|
||||
json_t *key_data_raw;
|
||||
|
||||
/**
|
||||
* Head of DLL of auditors of this exchange.
|
||||
*/
|
||||
struct TEAH_AuditorListEntry *auditors_head;
|
||||
|
||||
/**
|
||||
* Tail of DLL of auditors of this exchange.
|
||||
*/
|
||||
struct TEAH_AuditorListEntry *auditors_tail;
|
||||
|
||||
/**
|
||||
* Key data of the exchange, only valid if
|
||||
* @e handshake_complete is past stage #MHS_CERT.
|
||||
*/
|
||||
struct TALER_EXCHANGE_Keys key_data;
|
||||
|
||||
/**
|
||||
* Retry /keys frequency.
|
||||
*/
|
||||
struct GNUNET_TIME_Relative retry_delay;
|
||||
|
||||
/**
|
||||
* When does @e key_data expire?
|
||||
*/
|
||||
struct GNUNET_TIME_Timestamp key_data_expiration;
|
||||
|
||||
/**
|
||||
* Number of subsequent failed requests to /keys.
|
||||
*
|
||||
* Used to compute the CURL timeout for the request.
|
||||
*/
|
||||
unsigned int keys_error_count;
|
||||
|
||||
/**
|
||||
* Number of subsequent failed requests to /wire.
|
||||
*
|
||||
* Used to compute the CURL timeout for the request.
|
||||
*/
|
||||
unsigned int wire_error_count;
|
||||
|
||||
/**
|
||||
* Stage of the exchange's initialization routines.
|
||||
*/
|
||||
enum ExchangeHandleState state;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Function called for each auditor to give us a chance to possibly
|
||||
@ -156,9 +38,10 @@ struct TALER_EXCHANGE_Handle
|
||||
* @param auditor_pub public key of the auditor
|
||||
*/
|
||||
typedef void
|
||||
(*TEAH_AuditorCallback)(void *cls,
|
||||
const char *auditor_url,
|
||||
const struct TALER_AuditorPublicKeyP *auditor_pub);
|
||||
(*TEAH_AuditorCallback)(
|
||||
void *cls,
|
||||
const char *auditor_url,
|
||||
const struct TALER_AuditorPublicKeyP *auditor_pub);
|
||||
|
||||
|
||||
/**
|
||||
@ -171,50 +54,11 @@ typedef void
|
||||
* @param ac_cls closure for @a ac
|
||||
*/
|
||||
void
|
||||
TEAH_get_auditors_for_dc (struct TALER_EXCHANGE_Keys *keys,
|
||||
TEAH_AuditorCallback ac,
|
||||
void *ac_cls);
|
||||
TEAH_get_auditors_for_dc (
|
||||
struct TALER_EXCHANGE_Keys *keys,
|
||||
TEAH_AuditorCallback ac,
|
||||
void *ac_cls);
|
||||
|
||||
|
||||
/**
|
||||
* Get the context of a exchange.
|
||||
*
|
||||
* @param h the exchange handle to query
|
||||
* @return ctx context to execute jobs in
|
||||
*/
|
||||
struct GNUNET_CURL_Context *
|
||||
TEAH_handle_to_context (struct TALER_EXCHANGE_Handle *h);
|
||||
|
||||
|
||||
/**
|
||||
* Check if the handle is ready to process requests.
|
||||
*
|
||||
* @param h the exchange handle to query
|
||||
* @return #GNUNET_YES if we are ready, #GNUNET_NO if not
|
||||
*/
|
||||
enum GNUNET_GenericReturnValue
|
||||
TEAH_handle_is_ready (struct TALER_EXCHANGE_Handle *h);
|
||||
|
||||
/**
|
||||
* Check if the handle is ready to process requests.
|
||||
*
|
||||
* @param h the exchange handle to query
|
||||
* @return #GNUNET_YES if we are ready, #GNUNET_NO if not
|
||||
*/
|
||||
enum GNUNET_GenericReturnValue
|
||||
TEAH_handle_is_ready (struct TALER_EXCHANGE_Handle *h);
|
||||
|
||||
|
||||
/**
|
||||
* Obtain the URL to use for an API request.
|
||||
*
|
||||
* @param h the exchange handle to query
|
||||
* @param path Taler API path (i.e. "/reserve/withdraw")
|
||||
* @return the full URL to use with cURL
|
||||
*/
|
||||
char *
|
||||
TEAH_path_to_url (struct TALER_EXCHANGE_Handle *h,
|
||||
const char *path);
|
||||
|
||||
/* end of exchange_api_handle.h */
|
||||
#endif
|
||||
|
@ -114,6 +114,7 @@ parse_link_coin (const struct TALER_EXCHANGE_LinkHandle *lh,
|
||||
struct TALER_TransferSecretP secret;
|
||||
struct TALER_PlanchetDetail pd;
|
||||
struct TALER_CoinPubHashP c_hash;
|
||||
struct TALER_AgeCommitmentHash *pah = NULL;
|
||||
|
||||
/* parse reply */
|
||||
if (GNUNET_OK !=
|
||||
@ -137,34 +138,35 @@ parse_link_coin (const struct TALER_EXCHANGE_LinkHandle *lh,
|
||||
&alg_values,
|
||||
&bks);
|
||||
|
||||
lci->age_commitment_proof = NULL;
|
||||
lci->h_age_commitment = NULL;
|
||||
lci->has_age_commitment = false;
|
||||
|
||||
/* Derive the age commitment and calculate the hash */
|
||||
if (NULL != lh->age_commitment_proof)
|
||||
{
|
||||
lci->age_commitment_proof = GNUNET_new (struct TALER_AgeCommitmentProof);
|
||||
lci->h_age_commitment = GNUNET_new (struct TALER_AgeCommitmentHash);
|
||||
|
||||
GNUNET_assert (GNUNET_OK ==
|
||||
TALER_age_commitment_derive (
|
||||
lh->age_commitment_proof,
|
||||
&secret.key,
|
||||
lci->age_commitment_proof));
|
||||
&lci->age_commitment_proof));
|
||||
|
||||
TALER_age_commitment_hash (
|
||||
&(lci->age_commitment_proof->commitment),
|
||||
lci->h_age_commitment);
|
||||
&lci->age_commitment_proof.commitment,
|
||||
&lci->h_age_commitment);
|
||||
|
||||
lci->has_age_commitment = true;
|
||||
pah = &lci->h_age_commitment;
|
||||
}
|
||||
|
||||
if (GNUNET_OK !=
|
||||
TALER_planchet_prepare (&rpub,
|
||||
&alg_values,
|
||||
&bks,
|
||||
&lci->coin_priv,
|
||||
lci->h_age_commitment,
|
||||
&c_hash,
|
||||
&pd))
|
||||
TALER_planchet_prepare (
|
||||
&rpub,
|
||||
&alg_values,
|
||||
&bks,
|
||||
&lci->coin_priv,
|
||||
pah,
|
||||
&c_hash,
|
||||
&pd))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
@ -364,6 +366,8 @@ parse_link_ok (struct TALER_EXCHANGE_LinkHandle *lh,
|
||||
{
|
||||
TALER_denom_sig_free (&lcis[i].sig);
|
||||
TALER_denom_pub_free (&lcis[i].pub);
|
||||
if (lcis[i].has_age_commitment)
|
||||
TALER_age_commitment_proof_free (&lcis[i].age_commitment_proof);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
@ -513,6 +517,7 @@ TALER_EXCHANGE_link_cancel (struct TALER_EXCHANGE_LinkHandle *lh)
|
||||
GNUNET_CURL_job_cancel (lh->job);
|
||||
lh->job = NULL;
|
||||
}
|
||||
|
||||
GNUNET_free (lh->url);
|
||||
GNUNET_free (lh);
|
||||
}
|
||||
|
@ -336,13 +336,14 @@ start_melt (struct TALER_EXCHANGE_MeltHandle *mh)
|
||||
}
|
||||
TALER_denom_pub_hash (&mh->md.melted_coin.pub_key,
|
||||
&h_denom_pub);
|
||||
TALER_wallet_melt_sign (&mh->md.melted_coin.melt_amount_with_fee,
|
||||
&mh->md.melted_coin.fee_melt,
|
||||
&mh->md.rc,
|
||||
&h_denom_pub,
|
||||
mh->md.melted_coin.h_age_commitment,
|
||||
&mh->md.melted_coin.coin_priv,
|
||||
&mh->coin_sig);
|
||||
TALER_wallet_melt_sign (
|
||||
&mh->md.melted_coin.melt_amount_with_fee,
|
||||
&mh->md.melted_coin.fee_melt,
|
||||
&mh->md.rc,
|
||||
&h_denom_pub,
|
||||
mh->md.melted_coin.h_age_commitment,
|
||||
&mh->md.melted_coin.coin_priv,
|
||||
&mh->coin_sig);
|
||||
GNUNET_CRYPTO_eddsa_key_get_public (&mh->md.melted_coin.coin_priv.eddsa_priv,
|
||||
&mh->coin_pub.eddsa_pub);
|
||||
melt_obj = GNUNET_JSON_PACK (
|
||||
@ -357,7 +358,7 @@ start_melt (struct TALER_EXCHANGE_MeltHandle *mh)
|
||||
GNUNET_JSON_pack_data_auto ("rc",
|
||||
&mh->md.rc),
|
||||
GNUNET_JSON_pack_allow_null (
|
||||
mh->md.melted_coin.h_age_commitment
|
||||
(NULL != mh->md.melted_coin.h_age_commitment)
|
||||
? GNUNET_JSON_pack_data_auto ("age_commitment_hash",
|
||||
mh->md.melted_coin.h_age_commitment)
|
||||
: GNUNET_JSON_pack_string ("age_commitment_hash",
|
||||
@ -504,7 +505,6 @@ csr_cb (void *cls,
|
||||
}
|
||||
|
||||
|
||||
/* FIXME: refactor this to use struct TALER_EXCHANGE_Handle */
|
||||
struct TALER_EXCHANGE_MeltHandle *
|
||||
TALER_EXCHANGE_melt (
|
||||
struct GNUNET_CURL_Context *ctx,
|
||||
|
@ -45,6 +45,11 @@ TALER_EXCHANGE_free_melt_data_ (struct MeltData *md)
|
||||
struct FreshCoinData *fcd = &md->fcds[j];
|
||||
|
||||
TALER_denom_pub_free (&fcd->fresh_pk);
|
||||
for (size_t i = 0; i < TALER_CNC_KAPPA; i++)
|
||||
{
|
||||
TALER_age_commitment_proof_free (fcd->age_commitment_proofs[i]);
|
||||
GNUNET_free (fcd->age_commitment_proofs[i]);
|
||||
}
|
||||
}
|
||||
GNUNET_free (md->fcds);
|
||||
}
|
||||
@ -168,7 +173,8 @@ TALER_EXCHANGE_get_melt_data_ (
|
||||
union TALER_DenominationBlindingKeyP *bks = &fcd->bks[i];
|
||||
struct TALER_PlanchetDetail pd;
|
||||
struct TALER_CoinPubHashP c_hash;
|
||||
struct TALER_AgeCommitmentHash *ach = NULL;
|
||||
struct TALER_AgeCommitmentHash ach;
|
||||
struct TALER_AgeCommitmentHash *pah = NULL;
|
||||
|
||||
TALER_transfer_secret_to_planchet_secret (&trans_sec,
|
||||
j,
|
||||
@ -182,22 +188,21 @@ TALER_EXCHANGE_get_melt_data_ (
|
||||
&alg_values[j],
|
||||
bks);
|
||||
|
||||
/* Handle age commitment, if present */
|
||||
if (NULL != md->melted_coin.age_commitment_proof)
|
||||
if (NULL != rd->melt_age_commitment_proof)
|
||||
{
|
||||
fcd->age_commitment_proof[i] = GNUNET_new (struct
|
||||
TALER_AgeCommitmentProof);
|
||||
ach = GNUNET_new (struct TALER_AgeCommitmentHash);
|
||||
fcd->age_commitment_proofs[i] = GNUNET_new (struct
|
||||
TALER_AgeCommitmentProof);
|
||||
|
||||
GNUNET_assert (GNUNET_OK ==
|
||||
TALER_age_commitment_derive (
|
||||
md->melted_coin.age_commitment_proof,
|
||||
&trans_sec.key,
|
||||
fcd->age_commitment_proof[i]));
|
||||
fcd->age_commitment_proofs[i]));
|
||||
|
||||
TALER_age_commitment_hash (
|
||||
&fcd->age_commitment_proof[i]->commitment,
|
||||
ach);
|
||||
&fcd->age_commitment_proofs[i]->commitment,
|
||||
&ach);
|
||||
pah = &ach;
|
||||
}
|
||||
|
||||
if (TALER_DENOMINATION_CS == alg_values[j].cipher)
|
||||
@ -208,7 +213,7 @@ TALER_EXCHANGE_get_melt_data_ (
|
||||
&alg_values[j],
|
||||
bks,
|
||||
coin_priv,
|
||||
ach,
|
||||
pah,
|
||||
&c_hash,
|
||||
&pd))
|
||||
{
|
||||
|
@ -101,10 +101,9 @@ struct FreshCoinData
|
||||
|
||||
/**
|
||||
* Arrays of age commitments and proofs to be created, one for each
|
||||
* cut-and-choose dimension. The entries in each list might be NULL and
|
||||
* indicate no age commitment/restriction on the particular coin.
|
||||
* cut-and-choose dimension. NULL if age restriction is not applicable.
|
||||
*/
|
||||
struct TALER_AgeCommitmentProof *age_commitment_proof[TALER_CNC_KAPPA];
|
||||
struct TALER_AgeCommitmentProof *age_commitment_proofs[TALER_CNC_KAPPA];
|
||||
|
||||
/**
|
||||
* Blinding key secrets for the coins, depending on the
|
||||
|
@ -125,8 +125,7 @@ refresh_reveal_ok (struct TALER_EXCHANGE_RefreshesRevealHandle *rrh,
|
||||
}
|
||||
for (unsigned int i = 0; i<rrh->md.num_fresh_coins; i++)
|
||||
{
|
||||
struct TALER_EXCHANGE_RevealedCoinInfo *rci =
|
||||
&rcis[i];
|
||||
struct TALER_EXCHANGE_RevealedCoinInfo *rci = &rcis[i];
|
||||
const struct FreshCoinData *fcd = &rrh->md.fcds[i];
|
||||
const struct TALER_DenominationPublicKey *pk;
|
||||
json_t *jsonai;
|
||||
@ -140,25 +139,25 @@ refresh_reveal_ok (struct TALER_EXCHANGE_RefreshesRevealHandle *rrh,
|
||||
};
|
||||
struct TALER_FreshCoin coin;
|
||||
union TALER_DenominationBlindingKeyP bks;
|
||||
const struct TALER_AgeCommitmentHash *pah = NULL;
|
||||
|
||||
rci->ps = fcd->ps[rrh->noreveal_index];
|
||||
rci->bks = fcd->bks[rrh->noreveal_index];
|
||||
rci->age_commitment_proof = fcd->age_commitment_proof[rrh->noreveal_index];
|
||||
rci->h_age_commitment = NULL;
|
||||
rci->age_commitment_proof = NULL;
|
||||
|
||||
pk = &fcd->fresh_pk;
|
||||
jsonai = json_array_get (jsona, i);
|
||||
|
||||
GNUNET_assert (NULL != jsonai);
|
||||
GNUNET_assert (
|
||||
(NULL != rrh->md.melted_coin.age_commitment_proof) ==
|
||||
(NULL != rci->age_commitment_proof));
|
||||
|
||||
if (NULL != rci->age_commitment_proof)
|
||||
if (NULL != rrh->md.melted_coin.age_commitment_proof)
|
||||
{
|
||||
rci->h_age_commitment = GNUNET_new (struct TALER_AgeCommitmentHash);
|
||||
TALER_age_commitment_hash (
|
||||
&rci->age_commitment_proof->commitment,
|
||||
rci->h_age_commitment);
|
||||
rci->age_commitment_proof =
|
||||
fcd->age_commitment_proofs[rrh->noreveal_index];
|
||||
|
||||
TALER_age_commitment_hash (&rci->age_commitment_proof->commitment,
|
||||
&rci->h_age_commitment);
|
||||
pah = &rci->h_age_commitment;
|
||||
}
|
||||
|
||||
if (GNUNET_OK !=
|
||||
@ -180,18 +179,20 @@ refresh_reveal_ok (struct TALER_EXCHANGE_RefreshesRevealHandle *rrh,
|
||||
hence recomputing it here... */
|
||||
GNUNET_CRYPTO_eddsa_key_get_public (&rci->coin_priv.eddsa_priv,
|
||||
&coin_pub.eddsa_pub);
|
||||
TALER_coin_pub_hash (&coin_pub,
|
||||
rci->h_age_commitment,
|
||||
&coin_hash);
|
||||
TALER_coin_pub_hash (
|
||||
&coin_pub,
|
||||
pah,
|
||||
&coin_hash);
|
||||
if (GNUNET_OK !=
|
||||
TALER_planchet_to_coin (pk,
|
||||
&blind_sig,
|
||||
&bks,
|
||||
&rci->coin_priv,
|
||||
rci->h_age_commitment,
|
||||
&coin_hash,
|
||||
&rrh->alg_values[i],
|
||||
&coin))
|
||||
TALER_planchet_to_coin (
|
||||
pk,
|
||||
&blind_sig,
|
||||
&bks,
|
||||
&rci->coin_priv,
|
||||
pah,
|
||||
&coin_hash,
|
||||
&rrh->alg_values[i],
|
||||
&coin))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
@ -257,7 +258,10 @@ handle_refresh_reveal_finished (void *cls,
|
||||
rrh->reveal_cb = NULL;
|
||||
}
|
||||
for (unsigned int i = 0; i<rrh->md.num_fresh_coins; i++)
|
||||
{
|
||||
TALER_denom_sig_free (&rcis[i].sig);
|
||||
TALER_age_commitment_proof_free (rcis[i].age_commitment_proof);
|
||||
}
|
||||
TALER_EXCHANGE_refreshes_reveal_cancel (rrh);
|
||||
return;
|
||||
}
|
||||
@ -303,7 +307,6 @@ handle_refresh_reveal_finished (void *cls,
|
||||
}
|
||||
|
||||
|
||||
/* FIXME: refactor this to use struct TALER_EXCHANGE_Handle */
|
||||
struct TALER_EXCHANGE_RefreshesRevealHandle *
|
||||
TALER_EXCHANGE_refreshes_reveal (
|
||||
struct GNUNET_CURL_Context *ctx,
|
||||
@ -408,20 +411,19 @@ TALER_EXCHANGE_refreshes_reveal (
|
||||
}
|
||||
|
||||
/* build array of old age commitment, if applicable */
|
||||
GNUNET_assert ((NULL == rd->melt_age_commitment_proof) ==
|
||||
(NULL == rd->melt_h_age_commitment));
|
||||
if (NULL != rd->melt_age_commitment_proof)
|
||||
{
|
||||
GNUNET_assert (NULL != rd->melt_h_age_commitment);
|
||||
GNUNET_assert (NULL != (old_age_commitment = json_array ()));
|
||||
|
||||
for (size_t i = 0; i < rd->melt_age_commitment_proof->commitment.num; i++)
|
||||
{
|
||||
GNUNET_assert (0 ==
|
||||
json_array_append_new (
|
||||
old_age_commitment,
|
||||
GNUNET_JSON_from_data_auto (
|
||||
&rd->melt_age_commitment_proof->
|
||||
commitment.keys[i])));
|
||||
enum GNUNET_GenericReturnValue ret;
|
||||
ret = json_array_append_new (
|
||||
old_age_commitment,
|
||||
GNUNET_JSON_from_data_auto (
|
||||
&rd->melt_age_commitment_proof->commitment.keys[i]));
|
||||
GNUNET_assert (0 == ret);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -126,10 +126,17 @@ mime_matches (const char *accept_pattern,
|
||||
{
|
||||
const char *da = strchr (accept_pattern, '/');
|
||||
const char *dm = strchr (mime, '/');
|
||||
const char *end;
|
||||
|
||||
if ( (NULL == da) ||
|
||||
(NULL == dm) )
|
||||
return (0 == strcmp ("*", accept_pattern));
|
||||
/* FIXME: eventually, we might want to parse the "q=$FLOAT"
|
||||
part after the ';' and figure out which one is the
|
||||
best/preferred match instead of returning a boolean... */
|
||||
end = strchr (da, ';');
|
||||
if (NULL == end)
|
||||
end = &da[strlen (da)];
|
||||
return
|
||||
( ( (1 == da - accept_pattern) &&
|
||||
('*' == *accept_pattern) ) ||
|
||||
@ -138,8 +145,9 @@ mime_matches (const char *accept_pattern,
|
||||
mime,
|
||||
da - accept_pattern)) ) ) &&
|
||||
( (0 == strcmp (da, "/*")) ||
|
||||
(0 == strcasecmp (da,
|
||||
dm)) );
|
||||
(0 == strncasecmp (da,
|
||||
dm,
|
||||
end - da)) );
|
||||
}
|
||||
|
||||
|
||||
@ -150,9 +158,9 @@ TALER_MHD_xmime_matches (const char *accept_pattern,
|
||||
char *ap = GNUNET_strdup (accept_pattern);
|
||||
char *sptr;
|
||||
|
||||
for (const char *tok = strtok_r (ap, ";", &sptr);
|
||||
for (const char *tok = strtok_r (ap, ",", &sptr);
|
||||
NULL != tok;
|
||||
tok = strtok_r (NULL, ";", &sptr))
|
||||
tok = strtok_r (NULL, ",", &sptr))
|
||||
{
|
||||
if (mime_matches (tok,
|
||||
mime))
|
||||
|
@ -59,9 +59,7 @@ libtalertesting_la_SOURCES = \
|
||||
testing_api_cmd_batch_withdraw.c \
|
||||
testing_api_cmd_check_aml_decision.c \
|
||||
testing_api_cmd_check_aml_decisions.c \
|
||||
testing_api_cmd_check_keys.c \
|
||||
testing_api_cmd_common.c \
|
||||
testing_api_cmd_connect_with_state.c \
|
||||
testing_api_cmd_contract_get.c \
|
||||
testing_api_cmd_deposit.c \
|
||||
testing_api_cmd_deposits_get.c \
|
||||
@ -106,7 +104,6 @@ libtalertesting_la_SOURCES = \
|
||||
testing_api_cmd_revoke_denom_key.c \
|
||||
testing_api_cmd_revoke_sign_key.c \
|
||||
testing_api_cmd_run_fakebank.c \
|
||||
testing_api_cmd_serialize_keys.c \
|
||||
testing_api_cmd_set_officer.c \
|
||||
testing_api_cmd_set_wire_fee.c \
|
||||
testing_api_cmd_signal.c \
|
||||
|
@ -251,7 +251,7 @@ then
|
||||
echo -n "Configuring sandbox "
|
||||
libeufin-sandbox config --currency "$CURRENCY" default &> libeufin-sandbox-config.log
|
||||
echo "DONE"
|
||||
echo -n "Launching sandbox "
|
||||
echo -n "Launching sandbox ... "
|
||||
export LIBEUFIN_SANDBOX_ADMIN_PASSWORD="secret"
|
||||
libeufin-sandbox serve \
|
||||
--port "$SANDBOX_PORT" \
|
||||
@ -660,6 +660,8 @@ then
|
||||
enable-account "$EXCHANGE_PAYTO_URI" \
|
||||
upload &> "taler-exchange-offline-account.log"
|
||||
echo " OK"
|
||||
else
|
||||
echo "WARNING: Account ${USE_ACCOUNT} not enabled (set to: '$ENABLED')"
|
||||
fi
|
||||
if [ "1" = "$START_AUDITOR" ]
|
||||
then
|
||||
|
@ -653,12 +653,12 @@ run (void *cls,
|
||||
NULL),
|
||||
TALER_TESTING_cmd_get_exchange ("get-exchange",
|
||||
cred.cfg,
|
||||
NULL,
|
||||
true,
|
||||
true),
|
||||
TALER_TESTING_cmd_get_auditor ("get-auditor",
|
||||
cred.cfg,
|
||||
true),
|
||||
TALER_TESTING_cmd_check_keys_pull_all_keys ("refetch /keys"),
|
||||
TALER_TESTING_cmd_exec_auditor_offline ("auditor-offline",
|
||||
config_file),
|
||||
CMD_RUN_AUDITOR ("virgin-auditor"),
|
||||
|
@ -78,6 +78,9 @@ run (void *cls,
|
||||
case TALER_TESTING_BS_IBAN:
|
||||
ssoptions = "-ns";
|
||||
break;
|
||||
default:
|
||||
ssoptions = NULL;
|
||||
break;
|
||||
}
|
||||
memset (&wtid,
|
||||
42,
|
||||
|
@ -660,7 +660,6 @@ run (void *cls,
|
||||
"refresh-reveal-age-1",
|
||||
MHD_HTTP_CONFLICT,
|
||||
NULL),
|
||||
|
||||
TALER_TESTING_cmd_end ()
|
||||
};
|
||||
|
||||
@ -1236,9 +1235,9 @@ run (void *cls,
|
||||
NULL),
|
||||
TALER_TESTING_cmd_get_exchange ("get-exchange",
|
||||
cred.cfg,
|
||||
NULL,
|
||||
true,
|
||||
true),
|
||||
TALER_TESTING_cmd_check_keys_pull_all_keys ("refetch /keys"),
|
||||
TALER_TESTING_cmd_batch ("wire",
|
||||
wire),
|
||||
TALER_TESTING_cmd_batch ("withdraw",
|
||||
|
@ -21,7 +21,7 @@ CONFIG = "postgres:///talercheck"
|
||||
HTTP_PORT = 8082
|
||||
|
||||
[exchange]
|
||||
TERMS_ETAG = 0
|
||||
TERMS_ETAG = tos
|
||||
PRIVACY_ETAG = 0
|
||||
AML_THRESHOLD = EUR:1000000
|
||||
PORT = 8081
|
||||
@ -34,6 +34,9 @@ EXPIRE_IDLE_SLEEP_INTERVAL = 1 s
|
||||
[exchangedb-postgres]
|
||||
CONFIG = "postgres:///talercheck"
|
||||
|
||||
[taler-exchange-secmod-cs]
|
||||
LOOKAHEAD_SIGN = 24 days
|
||||
|
||||
[taler-exchange-secmod-rsa]
|
||||
LOOKAHEAD_SIGN = 24 days
|
||||
|
||||
|
@ -65,22 +65,21 @@ run (void *cls,
|
||||
NULL),
|
||||
TALER_TESTING_cmd_get_exchange ("get-exchange",
|
||||
cred.cfg,
|
||||
NULL,
|
||||
true,
|
||||
true),
|
||||
TALER_TESTING_cmd_check_keys_pull_all_keys ("initial-/keys"),
|
||||
TALER_TESTING_cmd_sleep ("sleep",
|
||||
6 /* seconds */),
|
||||
TALER_TESTING_cmd_check_keys ("check-keys-1"),
|
||||
TALER_TESTING_cmd_check_keys_with_last_denom ("check-keys-2",
|
||||
"check-keys-1"),
|
||||
TALER_TESTING_cmd_serialize_keys ("serialize-keys"),
|
||||
TALER_TESTING_cmd_connect_with_state ("reconnect-with-state",
|
||||
"serialize-keys"),
|
||||
/**
|
||||
* Make sure we have the same keys situation as
|
||||
* it was before the serialization.
|
||||
*/
|
||||
TALER_TESTING_cmd_check_keys ("check-keys-after-deserialization"),
|
||||
TALER_TESTING_cmd_get_exchange ("get-exchange-1",
|
||||
cred.cfg,
|
||||
"get-exchange",
|
||||
true,
|
||||
true),
|
||||
TALER_TESTING_cmd_get_exchange ("get-exchange-2",
|
||||
cred.cfg,
|
||||
"get-exchange-1",
|
||||
true,
|
||||
true),
|
||||
/**
|
||||
* Use one of the deserialized keys.
|
||||
*/
|
||||
|
@ -69,13 +69,19 @@ run (void *cls,
|
||||
NULL),
|
||||
TALER_TESTING_cmd_get_exchange ("get-exchange",
|
||||
cred.cfg,
|
||||
NULL,
|
||||
true,
|
||||
true),
|
||||
TALER_TESTING_cmd_get_exchange ("get-exchange-1",
|
||||
cred.cfg,
|
||||
"get-exchange",
|
||||
true,
|
||||
true),
|
||||
TALER_TESTING_cmd_get_exchange ("get-exchange-2",
|
||||
cred.cfg,
|
||||
NULL,
|
||||
true,
|
||||
true),
|
||||
TALER_TESTING_cmd_check_keys_pull_all_keys ("refetch /keys"),
|
||||
TALER_TESTING_cmd_check_keys ("first-download"),
|
||||
/* Causes GET /keys?last_denom_issue=0 */
|
||||
TALER_TESTING_cmd_check_keys_with_last_denom ("second-download",
|
||||
"zero"),
|
||||
TALER_TESTING_cmd_end ()
|
||||
};
|
||||
|
||||
|
@ -67,20 +67,9 @@ run (void *cls,
|
||||
NULL),
|
||||
TALER_TESTING_cmd_get_exchange ("get-exchange",
|
||||
cred.cfg,
|
||||
NULL,
|
||||
true,
|
||||
true),
|
||||
#if 0
|
||||
TALER_TESTING_cmd_auditor_add ("add-auditor-OK",
|
||||
MHD_HTTP_NO_CONTENT,
|
||||
false),
|
||||
TALER_TESTING_cmd_wire_add ("add-wire-account",
|
||||
"payto://x-taler-bank/localhost/2?receiver-name=2",
|
||||
MHD_HTTP_NO_CONTENT,
|
||||
false),
|
||||
TALER_TESTING_cmd_exec_offline_sign_keys ("offline-sign-future-keys",
|
||||
config_file),
|
||||
#endif
|
||||
TALER_TESTING_cmd_check_keys_pull_all_keys ("refetch /keys"),
|
||||
/**
|
||||
* Fill reserve with EUR:10.02, as withdraw fee is 1 ct per
|
||||
* config.
|
||||
|
@ -255,6 +255,7 @@ run (void *cls,
|
||||
NULL),
|
||||
TALER_TESTING_cmd_get_exchange ("get-exchange",
|
||||
cred.cfg,
|
||||
NULL,
|
||||
true,
|
||||
true),
|
||||
TALER_TESTING_cmd_batch (
|
||||
|
@ -59,6 +59,7 @@ run (void *cls,
|
||||
NULL),
|
||||
TALER_TESTING_cmd_get_exchange ("get-exchange",
|
||||
cred.cfg,
|
||||
NULL,
|
||||
true,
|
||||
true),
|
||||
TALER_TESTING_cmd_get_auditor ("get-auditor",
|
||||
@ -145,7 +146,16 @@ run (void *cls,
|
||||
false),
|
||||
TALER_TESTING_cmd_exec_offline_sign_keys ("download-future-keys",
|
||||
config_file),
|
||||
TALER_TESTING_cmd_check_keys_pull_all_keys ("refetch /keys"),
|
||||
TALER_TESTING_cmd_get_exchange ("get-exchange-1",
|
||||
cred.cfg,
|
||||
"get-exchange",
|
||||
true,
|
||||
true),
|
||||
TALER_TESTING_cmd_get_exchange ("get-exchange-2",
|
||||
cred.cfg,
|
||||
NULL,
|
||||
true,
|
||||
true),
|
||||
TALER_TESTING_cmd_end ()
|
||||
};
|
||||
|
||||
|
@ -504,9 +504,9 @@ run (void *cls,
|
||||
NULL),
|
||||
TALER_TESTING_cmd_get_exchange ("get-exchange",
|
||||
cred.cfg,
|
||||
NULL,
|
||||
true,
|
||||
true),
|
||||
TALER_TESTING_cmd_check_keys_pull_all_keys ("refetch /keys"),
|
||||
TALER_TESTING_cmd_batch ("withdraw",
|
||||
withdraw),
|
||||
TALER_TESTING_cmd_batch ("push",
|
||||
|
@ -523,9 +523,9 @@ run (void *cls,
|
||||
NULL),
|
||||
TALER_TESTING_cmd_get_exchange ("get-exchange",
|
||||
cred.cfg,
|
||||
NULL,
|
||||
true,
|
||||
true),
|
||||
TALER_TESTING_cmd_check_keys_pull_all_keys ("refetch /keys"),
|
||||
TALER_TESTING_cmd_batch ("withdraw",
|
||||
withdraw),
|
||||
TALER_TESTING_cmd_batch ("spend",
|
||||
|
@ -87,9 +87,9 @@ run (void *cls,
|
||||
NULL),
|
||||
TALER_TESTING_cmd_get_exchange ("get-exchange",
|
||||
cred.cfg,
|
||||
NULL,
|
||||
true,
|
||||
true),
|
||||
TALER_TESTING_cmd_check_keys_pull_all_keys ("refetch /keys"),
|
||||
TALER_TESTING_cmd_check_bank_empty ("expect-empty-transactions-on-start"),
|
||||
CMD_EXEC_AGGREGATOR ("run-aggregator-on-empty"),
|
||||
TALER_TESTING_cmd_exec_wirewatch ("run-wirewatch-on-empty",
|
||||
|
@ -76,7 +76,8 @@ auditor_add_cb (
|
||||
if (ds->expected_response_code != hr->http_status)
|
||||
{
|
||||
TALER_TESTING_unexpected_status (ds->is,
|
||||
hr->http_status);
|
||||
hr->http_status,
|
||||
ds->expected_response_code);
|
||||
return;
|
||||
}
|
||||
TALER_TESTING_interpreter_next (ds->is);
|
||||
|
@ -81,7 +81,8 @@ denom_sig_add_cb (
|
||||
if (ds->expected_response_code != hr->http_status)
|
||||
{
|
||||
TALER_TESTING_unexpected_status (ds->is,
|
||||
hr->http_status);
|
||||
hr->http_status,
|
||||
ds->expected_response_code);
|
||||
return;
|
||||
}
|
||||
TALER_TESTING_interpreter_next (ds->is);
|
||||
|
@ -77,7 +77,8 @@ auditor_del_cb (
|
||||
if (ds->expected_response_code != hr->http_status)
|
||||
{
|
||||
TALER_TESTING_unexpected_status (ds->is,
|
||||
hr->http_status);
|
||||
hr->http_status,
|
||||
ds->expected_response_code);
|
||||
return;
|
||||
}
|
||||
TALER_TESTING_interpreter_next (ds->is);
|
||||
|
@ -170,7 +170,8 @@ deposit_confirmation_cb (
|
||||
}
|
||||
}
|
||||
TALER_TESTING_unexpected_status (dcs->is,
|
||||
hr->http_status);
|
||||
hr->http_status,
|
||||
dcs->expected_response_code);
|
||||
return;
|
||||
}
|
||||
TALER_TESTING_interpreter_next (dcs->is);
|
||||
@ -211,12 +212,8 @@ deposit_confirmation_run (void *cls,
|
||||
const struct TALER_EXCHANGE_Keys *keys;
|
||||
const struct TALER_EXCHANGE_SigningPublicKey *spk;
|
||||
const char *auditor_url;
|
||||
struct TALER_EXCHANGE_Handle *exchange
|
||||
= TALER_TESTING_get_exchange (is);
|
||||
|
||||
(void) cmd;
|
||||
if (NULL == exchange)
|
||||
return;
|
||||
dcs->is = is;
|
||||
GNUNET_assert (NULL != dcs->deposit_reference);
|
||||
{
|
||||
@ -267,7 +264,7 @@ deposit_confirmation_run (void *cls,
|
||||
dcs->coin_index,
|
||||
&wire_deadline));
|
||||
GNUNET_assert (NULL != exchange_timestamp);
|
||||
keys = TALER_EXCHANGE_get_keys (exchange);
|
||||
keys = TALER_TESTING_get_keys (is);
|
||||
GNUNET_assert (NULL != keys);
|
||||
spk = TALER_EXCHANGE_get_signing_key_info (keys,
|
||||
exchange_pub);
|
||||
|
@ -120,10 +120,8 @@ do_retry (void *cls)
|
||||
/**
|
||||
* Callback to analyze the /exchanges response.
|
||||
*
|
||||
* @param cls closure.
|
||||
* @param hr HTTP response details
|
||||
* @param num_exchanges length of the @a ei array
|
||||
* @param ei array with information about the exchanges
|
||||
* @param cls closure of type struct ExchangesState*
|
||||
* @param ler Response to the GET /exchanges request
|
||||
*/
|
||||
static void
|
||||
exchanges_cb (void *cls,
|
||||
@ -160,7 +158,8 @@ exchanges_cb (void *cls,
|
||||
}
|
||||
}
|
||||
TALER_TESTING_unexpected_status (es->is,
|
||||
hr->http_status);
|
||||
hr->http_status,
|
||||
es->expected_response_code);
|
||||
return;
|
||||
}
|
||||
if (MHD_HTTP_OK != hr->http_status)
|
||||
|
@ -199,7 +199,8 @@ confirmation_cb (void *cls,
|
||||
}
|
||||
}
|
||||
TALER_TESTING_unexpected_status (is,
|
||||
tr->http_status);
|
||||
tr->http_status,
|
||||
MHD_HTTP_OK);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -199,7 +199,8 @@ batch_deposit_cb (void *cls,
|
||||
if (ds->expected_response_code != dr->hr.http_status)
|
||||
{
|
||||
TALER_TESTING_unexpected_status (ds->is,
|
||||
dr->hr.http_status);
|
||||
dr->hr.http_status,
|
||||
ds->expected_response_code);
|
||||
return;
|
||||
}
|
||||
if (MHD_HTTP_OK == dr->hr.http_status)
|
||||
|
@ -79,10 +79,10 @@ struct CoinState
|
||||
|
||||
/**
|
||||
* If age > 0, put here the corresponding age commitment with its proof and
|
||||
* its hash, respectivelly, NULL otherwise.
|
||||
* its hash, respectivelly.
|
||||
*/
|
||||
struct TALER_AgeCommitmentProof *age_commitment_proof;
|
||||
struct TALER_AgeCommitmentHash *h_age_commitment;
|
||||
struct TALER_AgeCommitmentProof age_commitment_proof;
|
||||
struct TALER_AgeCommitmentHash h_age_commitment;
|
||||
|
||||
/**
|
||||
* Reserve history entry that corresponds to this coin.
|
||||
@ -190,7 +190,8 @@ reserve_batch_withdraw_cb (void *cls,
|
||||
if (ws->expected_response_code != wr->hr.http_status)
|
||||
{
|
||||
TALER_TESTING_unexpected_status (is,
|
||||
wr->hr.http_status);
|
||||
wr->hr.http_status,
|
||||
ws->expected_response_code);
|
||||
return;
|
||||
}
|
||||
switch (wr->hr.http_status)
|
||||
@ -253,12 +254,8 @@ batch_withdraw_run (void *cls,
|
||||
const struct TALER_TESTING_Command *create_reserve;
|
||||
const struct TALER_EXCHANGE_DenomPublicKey *dpk;
|
||||
struct TALER_EXCHANGE_WithdrawCoinInput wcis[ws->num_coins];
|
||||
struct TALER_EXCHANGE_Handle *exchange
|
||||
= TALER_TESTING_get_exchange (is);
|
||||
|
||||
(void) cmd;
|
||||
if (NULL == exchange)
|
||||
return;
|
||||
ws->is = is;
|
||||
create_reserve
|
||||
= TALER_TESTING_interpreter_lookup_command (
|
||||
@ -281,7 +278,7 @@ batch_withdraw_run (void *cls,
|
||||
}
|
||||
if (NULL == ws->exchange_url)
|
||||
ws->exchange_url
|
||||
= GNUNET_strdup (TALER_EXCHANGE_get_base_url (exchange));
|
||||
= GNUNET_strdup (TALER_TESTING_get_exchange_url (is));
|
||||
ws->reserve_priv = *rp;
|
||||
GNUNET_CRYPTO_eddsa_key_get_public (&ws->reserve_priv.eddsa_priv,
|
||||
&ws->reserve_pub.eddsa_pub);
|
||||
@ -295,7 +292,7 @@ batch_withdraw_run (void *cls,
|
||||
struct TALER_EXCHANGE_WithdrawCoinInput *wci = &wcis[i];
|
||||
|
||||
TALER_planchet_master_setup_random (&cs->ps);
|
||||
dpk = TALER_TESTING_find_pk (TALER_EXCHANGE_get_keys (exchange),
|
||||
dpk = TALER_TESTING_find_pk (TALER_TESTING_get_keys (is),
|
||||
&cs->amount,
|
||||
ws->age > 0);
|
||||
if (NULL == dpk)
|
||||
@ -319,7 +316,7 @@ batch_withdraw_run (void *cls,
|
||||
|
||||
wci->pk = cs->pk;
|
||||
wci->ps = &cs->ps;
|
||||
wci->ach = cs->h_age_commitment;
|
||||
wci->ach = &cs->h_age_commitment;
|
||||
}
|
||||
ws->wsh = TALER_EXCHANGE_batch_withdraw (
|
||||
TALER_TESTING_interpreter_get_context (is),
|
||||
@ -369,13 +366,8 @@ batch_withdraw_cleanup (void *cls,
|
||||
TALER_EXCHANGE_destroy_denomination_key (cs->pk);
|
||||
cs->pk = NULL;
|
||||
}
|
||||
if (NULL != cs->age_commitment_proof)
|
||||
{
|
||||
TALER_age_commitment_proof_free (cs->age_commitment_proof);
|
||||
cs->age_commitment_proof = NULL;
|
||||
}
|
||||
if (NULL != cs->h_age_commitment)
|
||||
GNUNET_free (cs->h_age_commitment);
|
||||
if (0 < ws->age)
|
||||
TALER_age_commitment_proof_free (&cs->age_commitment_proof);
|
||||
}
|
||||
GNUNET_free (ws->coins);
|
||||
GNUNET_free (ws->exchange_url);
|
||||
@ -427,9 +419,13 @@ batch_withdraw_traits (void *cls,
|
||||
TALER_TESTING_make_trait_payto_uri (ws->reserve_payto_uri),
|
||||
TALER_TESTING_make_trait_exchange_url (ws->exchange_url),
|
||||
TALER_TESTING_make_trait_age_commitment_proof (index,
|
||||
cs->age_commitment_proof),
|
||||
ws->age > 0 ?
|
||||
&cs->age_commitment_proof:
|
||||
NULL),
|
||||
TALER_TESTING_make_trait_h_age_commitment (index,
|
||||
cs->h_age_commitment),
|
||||
ws->age > 0 ?
|
||||
&cs->h_age_commitment :
|
||||
NULL),
|
||||
TALER_TESTING_trait_end ()
|
||||
};
|
||||
|
||||
@ -476,13 +472,9 @@ TALER_TESTING_cmd_batch_withdraw (const char *label,
|
||||
|
||||
if (0 < age)
|
||||
{
|
||||
struct TALER_AgeCommitmentProof *acp;
|
||||
struct TALER_AgeCommitmentHash *hac;
|
||||
struct GNUNET_HashCode seed;
|
||||
struct TALER_AgeMask mask;
|
||||
|
||||
acp = GNUNET_new (struct TALER_AgeCommitmentProof);
|
||||
hac = GNUNET_new (struct TALER_AgeCommitmentHash);
|
||||
mask = TALER_extensions_get_age_restriction_mask ();
|
||||
GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
|
||||
&seed,
|
||||
@ -493,7 +485,7 @@ TALER_TESTING_cmd_batch_withdraw (const char *label,
|
||||
&mask,
|
||||
age,
|
||||
&seed,
|
||||
acp))
|
||||
&cs->age_commitment_proof))
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Failed to generate age commitment for age %d at %s\n",
|
||||
@ -502,10 +494,8 @@ TALER_TESTING_cmd_batch_withdraw (const char *label,
|
||||
GNUNET_assert (0);
|
||||
}
|
||||
|
||||
TALER_age_commitment_hash (&acp->commitment,
|
||||
hac);
|
||||
cs->age_commitment_proof = acp;
|
||||
cs->h_age_commitment = hac;
|
||||
TALER_age_commitment_hash (&cs->age_commitment_proof.commitment,
|
||||
&cs->h_age_commitment);
|
||||
}
|
||||
|
||||
if (GNUNET_OK !=
|
||||
|
@ -80,7 +80,8 @@ check_aml_decision_cb (void *cls,
|
||||
if (ds->expected_http_status != adr->hr.http_status)
|
||||
{
|
||||
TALER_TESTING_unexpected_status (ds->is,
|
||||
adr->hr.http_status);
|
||||
adr->hr.http_status,
|
||||
ds->expected_http_status);
|
||||
return;
|
||||
}
|
||||
if (MHD_HTTP_OK == adr->hr.http_status)
|
||||
|
@ -80,7 +80,8 @@ check_aml_decisions_cb (void *cls,
|
||||
if (ds->expected_http_status != adr->hr.http_status)
|
||||
{
|
||||
TALER_TESTING_unexpected_status (ds->is,
|
||||
adr->hr.http_status);
|
||||
adr->hr.http_status,
|
||||
ds->expected_http_status);
|
||||
return;
|
||||
}
|
||||
TALER_TESTING_interpreter_next (ds->is);
|
||||
|
@ -1,251 +0,0 @@
|
||||
/*
|
||||
This file is part of TALER
|
||||
(C) 2018, 2020, 2021 Taler Systems SA
|
||||
|
||||
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 testing/testing_api_cmd_check_keys.c
|
||||
* @brief Implementation of "check keys" test command.
|
||||
* @author Marcello Stanisci
|
||||
* @author Christian Grothoff
|
||||
*/
|
||||
#include "platform.h"
|
||||
#include "taler_json_lib.h"
|
||||
#include <gnunet/gnunet_curl_lib.h>
|
||||
#include "taler_testing_lib.h"
|
||||
|
||||
|
||||
/**
|
||||
* State for a "check keys" CMD.
|
||||
*/
|
||||
struct CheckKeysState
|
||||
{
|
||||
|
||||
/**
|
||||
* If this value is true, then the "cherry picking" facility is turned off;
|
||||
* whole /keys is downloaded.
|
||||
*/
|
||||
bool pull_all_keys;
|
||||
|
||||
/**
|
||||
* Label of a command to use to derive the "last_denom_issue" date to use.
|
||||
*/
|
||||
const char *last_denom_date_ref;
|
||||
|
||||
/**
|
||||
* Our interpreter state.
|
||||
*/
|
||||
struct TALER_TESTING_Interpreter *is;
|
||||
|
||||
/**
|
||||
* Last denomination date we received when doing this request.
|
||||
*/
|
||||
struct GNUNET_TIME_Timestamp my_denom_date;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Function called with information about who is auditing
|
||||
* a particular exchange and what keys the exchange is using.
|
||||
*
|
||||
* @param cls closure
|
||||
* @param kr response from /keys
|
||||
*/
|
||||
static void
|
||||
keys_cb (void *cls,
|
||||
const struct TALER_EXCHANGE_KeysResponse *kr)
|
||||
{
|
||||
struct CheckKeysState *cks = cls;
|
||||
|
||||
if (MHD_HTTP_OK != kr->hr.http_status)
|
||||
{
|
||||
TALER_TESTING_unexpected_status (cks->is,
|
||||
kr->hr.http_status);
|
||||
return;
|
||||
}
|
||||
cks->my_denom_date = kr->details.ok.keys->last_denom_issue_date;
|
||||
TALER_TESTING_interpreter_next (cks->is);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Run the "check keys" command.
|
||||
*
|
||||
* @param cls closure.
|
||||
* @param cmd the command currently being executed.
|
||||
* @param is the interpreter state.
|
||||
*/
|
||||
static void
|
||||
check_keys_run (void *cls,
|
||||
const struct TALER_TESTING_Command *cmd,
|
||||
struct TALER_TESTING_Interpreter *is)
|
||||
{
|
||||
struct CheckKeysState *cks = cls;
|
||||
struct TALER_EXCHANGE_Handle *exchange
|
||||
= TALER_TESTING_get_exchange (is);
|
||||
struct GNUNET_TIME_Timestamp rdate;
|
||||
|
||||
(void) cmd;
|
||||
cks->is = is;
|
||||
if (NULL == exchange)
|
||||
return;
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||
"Triggering GET /keys, cmd `%s'\n",
|
||||
cmd->label);
|
||||
if (NULL != cks->last_denom_date_ref)
|
||||
{
|
||||
if (0 == strcmp ("zero",
|
||||
cks->last_denom_date_ref))
|
||||
{
|
||||
TALER_LOG_DEBUG ("Forcing last_denom_date URL argument set to zero\n");
|
||||
TALER_EXCHANGE_set_last_denom (exchange,
|
||||
GNUNET_TIME_UNIT_ZERO_TS);
|
||||
}
|
||||
else
|
||||
{
|
||||
const struct GNUNET_TIME_Timestamp *last_denom_date;
|
||||
const struct TALER_TESTING_Command *ref;
|
||||
|
||||
ref = TALER_TESTING_interpreter_lookup_command (is,
|
||||
cks->last_denom_date_ref);
|
||||
if (NULL == ref)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
TALER_TESTING_interpreter_fail (is);
|
||||
return;
|
||||
}
|
||||
if (GNUNET_OK !=
|
||||
TALER_TESTING_get_trait_timestamp (ref,
|
||||
0,
|
||||
&last_denom_date))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
TALER_TESTING_interpreter_fail (is);
|
||||
return;
|
||||
}
|
||||
|
||||
TALER_LOG_DEBUG ("Forcing last_denom_date URL argument\n");
|
||||
TALER_EXCHANGE_set_last_denom (exchange,
|
||||
*last_denom_date);
|
||||
}
|
||||
}
|
||||
|
||||
rdate = TALER_EXCHANGE_check_keys_current (
|
||||
exchange,
|
||||
cks->pull_all_keys
|
||||
? TALER_EXCHANGE_CKF_FORCE_ALL_NOW
|
||||
: TALER_EXCHANGE_CKF_FORCE_DOWNLOAD,
|
||||
&keys_cb,
|
||||
cks);
|
||||
/* Redownload /keys. */
|
||||
GNUNET_break (GNUNET_TIME_absolute_is_zero (rdate.abs_time));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Cleanup the state.
|
||||
*
|
||||
* @param cls closure.
|
||||
* @param cmd the command which is being cleaned up.
|
||||
*/
|
||||
static void
|
||||
check_keys_cleanup (void *cls,
|
||||
const struct TALER_TESTING_Command *cmd)
|
||||
{
|
||||
struct CheckKeysState *cks = cls;
|
||||
|
||||
(void) cmd;
|
||||
GNUNET_free (cks);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Offer internal data to a "check_keys" CMD state to other
|
||||
* commands.
|
||||
*
|
||||
* @param cls closure
|
||||
* @param[out] ret result (could be anything)
|
||||
* @param trait name of the trait
|
||||
* @param index index number of the object to offer.
|
||||
* @return #GNUNET_OK on success
|
||||
*/
|
||||
static enum GNUNET_GenericReturnValue
|
||||
check_keys_traits (void *cls,
|
||||
const void **ret,
|
||||
const char *trait,
|
||||
unsigned int index)
|
||||
{
|
||||
struct CheckKeysState *cks = cls;
|
||||
struct TALER_TESTING_Trait traits[] = {
|
||||
TALER_TESTING_make_trait_timestamp (0,
|
||||
&cks->my_denom_date),
|
||||
TALER_TESTING_trait_end ()
|
||||
};
|
||||
|
||||
return TALER_TESTING_get_trait (traits,
|
||||
ret,
|
||||
trait,
|
||||
index);
|
||||
}
|
||||
|
||||
|
||||
struct TALER_TESTING_Command
|
||||
TALER_TESTING_cmd_check_keys (const char *label)
|
||||
{
|
||||
struct CheckKeysState *cks;
|
||||
|
||||
cks = GNUNET_new (struct CheckKeysState);
|
||||
{
|
||||
struct TALER_TESTING_Command cmd = {
|
||||
.cls = cks,
|
||||
.label = label,
|
||||
.run = &check_keys_run,
|
||||
.cleanup = &check_keys_cleanup,
|
||||
.traits = &check_keys_traits
|
||||
};
|
||||
|
||||
return cmd;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct TALER_TESTING_Command
|
||||
TALER_TESTING_cmd_check_keys_pull_all_keys (const char *label)
|
||||
{
|
||||
struct TALER_TESTING_Command cmd
|
||||
= TALER_TESTING_cmd_check_keys (label);
|
||||
struct CheckKeysState *cks = cmd.cls;
|
||||
|
||||
cks->pull_all_keys = true;
|
||||
return cmd;
|
||||
}
|
||||
|
||||
|
||||
struct TALER_TESTING_Command
|
||||
TALER_TESTING_cmd_check_keys_with_last_denom (
|
||||
const char *label,
|
||||
const char *last_denom_date_ref)
|
||||
{
|
||||
struct TALER_TESTING_Command cmd
|
||||
= TALER_TESTING_cmd_check_keys (label);
|
||||
struct CheckKeysState *cks = cmd.cls;
|
||||
|
||||
cks->last_denom_date_ref = last_denom_date_ref;
|
||||
return cmd;
|
||||
}
|
||||
|
||||
|
||||
/* end of testing_api_cmd_check_keys.c */
|
@ -1,191 +0,0 @@
|
||||
/*
|
||||
This file is part of TALER
|
||||
(C) 2018-2023 Taler Systems SA
|
||||
|
||||
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 testing/testing_api_cmd_connect_with_state.c
|
||||
* @brief Lets tests use the keys deserialization API.
|
||||
* @author Marcello Stanisci
|
||||
*/
|
||||
#include "platform.h"
|
||||
#include <jansson.h>
|
||||
#include "taler_testing_lib.h"
|
||||
|
||||
|
||||
/**
|
||||
* Internal state for a connect-with-state CMD.
|
||||
*/
|
||||
struct ConnectWithStateState
|
||||
{
|
||||
|
||||
/**
|
||||
* Reference to a CMD that offers a serialized key-state
|
||||
* that will be used in the reconnection.
|
||||
*/
|
||||
const char *state_reference;
|
||||
|
||||
/**
|
||||
* Interpreter state.
|
||||
*/
|
||||
struct TALER_TESTING_Interpreter *is;
|
||||
|
||||
/**
|
||||
* New exchange handle.
|
||||
*/
|
||||
struct TALER_EXCHANGE_Handle *exchange;
|
||||
};
|
||||
|
||||
|
||||
static void
|
||||
cert_cb (void *cls,
|
||||
const struct TALER_EXCHANGE_KeysResponse *kr)
|
||||
{
|
||||
struct ConnectWithStateState *cwss = cls;
|
||||
struct TALER_TESTING_Interpreter *is = cwss->is;
|
||||
const struct TALER_EXCHANGE_HttpResponse *hr = &kr->hr;
|
||||
|
||||
switch (hr->http_status)
|
||||
{
|
||||
case MHD_HTTP_OK:
|
||||
/* dealt with below */
|
||||
break;
|
||||
default:
|
||||
GNUNET_break (0);
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
|
||||
"Got failure response %u/%d for /keys!\n",
|
||||
hr->http_status,
|
||||
(int) hr->ec);
|
||||
TALER_TESTING_interpreter_fail (is);
|
||||
return;
|
||||
}
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
|
||||
"Got %d DK from /keys\n",
|
||||
kr->details.ok.keys->num_denom_keys);
|
||||
TALER_TESTING_interpreter_next (is);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Run the command.
|
||||
*
|
||||
* @param cls closure.
|
||||
* @param cmd the command to execute.
|
||||
* @param is the interpreter state.
|
||||
*/
|
||||
static void
|
||||
connect_with_state_run (void *cls,
|
||||
const struct TALER_TESTING_Command *cmd,
|
||||
struct TALER_TESTING_Interpreter *is)
|
||||
{
|
||||
struct ConnectWithStateState *cwss = cls;
|
||||
const struct TALER_TESTING_Command *state_cmd;
|
||||
const json_t *serialized_keys;
|
||||
const char *exchange_url;
|
||||
|
||||
cwss->is = is;
|
||||
state_cmd = TALER_TESTING_interpreter_lookup_command (is,
|
||||
cwss->state_reference);
|
||||
if (NULL == state_cmd)
|
||||
{
|
||||
/* Command providing serialized keys not found. */
|
||||
GNUNET_break (0);
|
||||
TALER_TESTING_interpreter_fail (is);
|
||||
return;
|
||||
}
|
||||
GNUNET_assert (GNUNET_OK ==
|
||||
TALER_TESTING_get_trait_exchange_keys (state_cmd,
|
||||
&serialized_keys));
|
||||
GNUNET_assert (GNUNET_OK ==
|
||||
TALER_TESTING_get_trait_exchange_url (state_cmd,
|
||||
&exchange_url));
|
||||
cwss->exchange
|
||||
= TALER_EXCHANGE_connect (
|
||||
TALER_TESTING_interpreter_get_context (is),
|
||||
exchange_url,
|
||||
&cert_cb,
|
||||
cwss,
|
||||
TALER_EXCHANGE_OPTION_DATA,
|
||||
serialized_keys,
|
||||
TALER_EXCHANGE_OPTION_END);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Offer exchange connection as trait.
|
||||
*
|
||||
* @param cls closure.
|
||||
* @param[out] ret result.
|
||||
* @param trait name of the trait.
|
||||
* @param index index number of the object to offer.
|
||||
* @return #GNUNET_OK on success.
|
||||
*/
|
||||
static enum GNUNET_GenericReturnValue
|
||||
connect_with_state_traits (void *cls,
|
||||
const void **ret,
|
||||
const char *trait,
|
||||
unsigned int index)
|
||||
{
|
||||
struct ConnectWithStateState *cwss = cls;
|
||||
struct TALER_TESTING_Trait traits[] = {
|
||||
TALER_TESTING_make_trait_exchange (cwss->exchange),
|
||||
TALER_TESTING_trait_end ()
|
||||
};
|
||||
|
||||
return TALER_TESTING_get_trait (traits,
|
||||
ret,
|
||||
trait,
|
||||
index);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Cleanup the state of a "connect with state" CMD. Just
|
||||
* a placeholder to avoid jumping on an invalid address.
|
||||
*
|
||||
* @param cls closure.
|
||||
* @param cmd the command which is being cleaned up.
|
||||
*/
|
||||
static void
|
||||
connect_with_state_cleanup (void *cls,
|
||||
const struct TALER_TESTING_Command *cmd)
|
||||
{
|
||||
struct ConnectWithStateState *cwss = cls;
|
||||
|
||||
GNUNET_free (cwss);
|
||||
}
|
||||
|
||||
|
||||
struct TALER_TESTING_Command
|
||||
TALER_TESTING_cmd_connect_with_state (const char *label,
|
||||
const char *state_reference)
|
||||
{
|
||||
struct ConnectWithStateState *cwss;
|
||||
|
||||
cwss = GNUNET_new (struct ConnectWithStateState);
|
||||
cwss->state_reference = state_reference;
|
||||
{
|
||||
struct TALER_TESTING_Command cmd = {
|
||||
.cls = cwss,
|
||||
.label = label,
|
||||
.run = connect_with_state_run,
|
||||
.cleanup = connect_with_state_cleanup,
|
||||
.traits = connect_with_state_traits
|
||||
};
|
||||
|
||||
return cmd;
|
||||
}
|
||||
}
|
@ -102,7 +102,8 @@ get_cb (void *cls,
|
||||
if (ds->expected_response_code != dr->hr.http_status)
|
||||
{
|
||||
TALER_TESTING_unexpected_status (ds->is,
|
||||
dr->hr.http_status);
|
||||
dr->hr.http_status,
|
||||
ds->expected_response_code);
|
||||
return;
|
||||
}
|
||||
ref = TALER_TESTING_interpreter_lookup_command (ds->is,
|
||||
|
@ -248,8 +248,12 @@ deposit_cb (void *cls,
|
||||
return;
|
||||
}
|
||||
}
|
||||
TALER_TESTING_unexpected_status (ds->is,
|
||||
dr->hr.http_status);
|
||||
TALER_TESTING_unexpected_status_with_body (
|
||||
ds->is,
|
||||
dr->hr.http_status,
|
||||
ds->expected_response_code,
|
||||
dr->hr.reply);
|
||||
|
||||
return;
|
||||
}
|
||||
if (MHD_HTTP_OK == dr->hr.http_status)
|
||||
@ -280,8 +284,7 @@ deposit_run (void *cls,
|
||||
const struct TALER_TESTING_Command *coin_cmd;
|
||||
const struct TALER_CoinSpendPrivateKeyP *coin_priv;
|
||||
struct TALER_CoinSpendPublicKeyP coin_pub;
|
||||
const struct TALER_AgeCommitmentProof *age_commitment_proof = NULL;
|
||||
struct TALER_AgeCommitmentHash h_age_commitment = {0};
|
||||
const struct TALER_AgeCommitmentHash *phac;
|
||||
const struct TALER_EXCHANGE_DenomPublicKey *denom_pub;
|
||||
const struct TALER_DenominationSignature *denom_pub_sig;
|
||||
struct TALER_CoinSpendSignatureP coin_sig;
|
||||
@ -385,9 +388,9 @@ deposit_run (void *cls,
|
||||
ds->coin_index,
|
||||
&coin_priv)) ||
|
||||
(GNUNET_OK !=
|
||||
TALER_TESTING_get_trait_age_commitment_proof (coin_cmd,
|
||||
ds->coin_index,
|
||||
&age_commitment_proof)) ||
|
||||
TALER_TESTING_get_trait_h_age_commitment (coin_cmd,
|
||||
ds->coin_index,
|
||||
&phac)) ||
|
||||
(GNUNET_OK !=
|
||||
TALER_TESTING_get_trait_denom_pub (coin_cmd,
|
||||
ds->coin_index,
|
||||
@ -405,11 +408,6 @@ deposit_run (void *cls,
|
||||
return;
|
||||
}
|
||||
|
||||
if (NULL != age_commitment_proof)
|
||||
{
|
||||
TALER_age_commitment_hash (&age_commitment_proof->commitment,
|
||||
&h_age_commitment);
|
||||
}
|
||||
ds->deposit_fee = denom_pub->fees.deposit;
|
||||
GNUNET_CRYPTO_eddsa_key_get_public (&coin_priv->eddsa_priv,
|
||||
&coin_pub.eddsa_pub);
|
||||
@ -443,7 +441,7 @@ deposit_run (void *cls,
|
||||
&denom_pub->fees.deposit,
|
||||
&h_wire,
|
||||
&h_contract_terms,
|
||||
&h_age_commitment,
|
||||
phac,
|
||||
NULL, /* FIXME #7270: add hash of extensions */
|
||||
&denom_pub->h_key,
|
||||
ds->wallet_timestamp,
|
||||
@ -456,11 +454,11 @@ deposit_run (void *cls,
|
||||
{
|
||||
struct TALER_EXCHANGE_CoinDepositDetail cdd = {
|
||||
.amount = ds->amount,
|
||||
.h_age_commitment = h_age_commitment,
|
||||
.coin_pub = coin_pub,
|
||||
.coin_sig = coin_sig,
|
||||
.denom_sig = *denom_pub_sig,
|
||||
.h_denom_pub = denom_pub->h_key
|
||||
.h_denom_pub = denom_pub->h_key,
|
||||
.h_age_commitment = {{{0}}},
|
||||
};
|
||||
struct TALER_EXCHANGE_DepositContractDetail dcd = {
|
||||
.wire_deadline = ds->wire_deadline,
|
||||
@ -473,6 +471,9 @@ deposit_run (void *cls,
|
||||
.refund_deadline = ds->refund_deadline
|
||||
};
|
||||
|
||||
if (NULL != phac)
|
||||
cdd.h_age_commitment = *phac;
|
||||
|
||||
ds->dh = TALER_EXCHANGE_batch_deposit (
|
||||
TALER_TESTING_interpreter_get_context (is),
|
||||
exchange_url,
|
||||
@ -547,6 +548,7 @@ deposit_traits (void *cls,
|
||||
/* Will point to coin cmd internals. */
|
||||
const struct TALER_CoinSpendPrivateKeyP *coin_spent_priv;
|
||||
const struct TALER_AgeCommitmentProof *age_commitment_proof;
|
||||
const struct TALER_AgeCommitmentHash *h_age_commitment;
|
||||
|
||||
if (GNUNET_YES != ds->command_initialized)
|
||||
{
|
||||
@ -571,12 +573,17 @@ deposit_traits (void *cls,
|
||||
(GNUNET_OK !=
|
||||
TALER_TESTING_get_trait_age_commitment_proof (coin_cmd,
|
||||
ds->coin_index,
|
||||
&age_commitment_proof)) )
|
||||
&age_commitment_proof)) ||
|
||||
(GNUNET_OK !=
|
||||
TALER_TESTING_get_trait_h_age_commitment (coin_cmd,
|
||||
ds->coin_index,
|
||||
&h_age_commitment)) )
|
||||
{
|
||||
GNUNET_break (0);
|
||||
TALER_TESTING_interpreter_fail (ds->is);
|
||||
return GNUNET_NO;
|
||||
}
|
||||
|
||||
{
|
||||
struct TALER_TESTING_Trait traits[] = {
|
||||
/* First two traits are only available if
|
||||
@ -590,6 +597,8 @@ deposit_traits (void *cls,
|
||||
coin_spent_priv),
|
||||
TALER_TESTING_make_trait_age_commitment_proof (0,
|
||||
age_commitment_proof),
|
||||
TALER_TESTING_make_trait_h_age_commitment (0,
|
||||
h_age_commitment),
|
||||
TALER_TESTING_make_trait_wire_details (ds->wire_details),
|
||||
TALER_TESTING_make_trait_contract_terms (ds->contract_terms),
|
||||
TALER_TESTING_make_trait_merchant_priv (&ds->merchant_priv),
|
||||
|
@ -117,7 +117,8 @@ deposit_wtid_cb (void *cls,
|
||||
if (tts->expected_response_code != dr->hr.http_status)
|
||||
{
|
||||
TALER_TESTING_unexpected_status (is,
|
||||
dr->hr.http_status);
|
||||
dr->hr.http_status,
|
||||
tts->expected_response_code);
|
||||
return;
|
||||
}
|
||||
switch (dr->hr.http_status)
|
||||
|
@ -83,7 +83,8 @@ version_cb (
|
||||
if (MHD_HTTP_OK != vr->hr.http_status)
|
||||
{
|
||||
TALER_TESTING_unexpected_status (gas->is,
|
||||
vr->hr.http_status);
|
||||
vr->hr.http_status,
|
||||
MHD_HTTP_OK);
|
||||
return;
|
||||
}
|
||||
if ( (NULL != gas->priv_file) &&
|
||||
|
@ -46,7 +46,12 @@ struct GetExchangeState
|
||||
/**
|
||||
* Exchange handle we produced.
|
||||
*/
|
||||
struct TALER_EXCHANGE_Handle *exchange;
|
||||
struct TALER_EXCHANGE_GetKeysHandle *exchange;
|
||||
|
||||
/**
|
||||
* Keys of the exchange.
|
||||
*/
|
||||
struct TALER_EXCHANGE_Keys *keys;
|
||||
|
||||
/**
|
||||
* URL of the exchange.
|
||||
@ -58,6 +63,17 @@ struct GetExchangeState
|
||||
*/
|
||||
char *master_priv_file;
|
||||
|
||||
/**
|
||||
* Label of a command to use to obtain existing
|
||||
* keys.
|
||||
*/
|
||||
const char *last_keys_ref;
|
||||
|
||||
/**
|
||||
* Last denomination date we received when doing this request.
|
||||
*/
|
||||
struct GNUNET_TIME_Timestamp my_denom_date;
|
||||
|
||||
/**
|
||||
* Are we waiting for /keys before continuing?
|
||||
*/
|
||||
@ -65,14 +81,25 @@ struct GetExchangeState
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Function called with information about who is auditing
|
||||
* a particular exchange and what keys the exchange is using.
|
||||
*
|
||||
* @param cls closure
|
||||
* @param kr response from /keys
|
||||
* @param[in] keys the keys of the exchange
|
||||
*/
|
||||
static void
|
||||
cert_cb (void *cls,
|
||||
const struct TALER_EXCHANGE_KeysResponse *kr)
|
||||
const struct TALER_EXCHANGE_KeysResponse *kr,
|
||||
struct TALER_EXCHANGE_Keys *keys)
|
||||
{
|
||||
struct GetExchangeState *ges = cls;
|
||||
const struct TALER_EXCHANGE_HttpResponse *hr = &kr->hr;
|
||||
struct TALER_TESTING_Interpreter *is = ges->is;
|
||||
|
||||
ges->exchange = NULL;
|
||||
ges->keys = keys;
|
||||
switch (hr->http_status)
|
||||
{
|
||||
case MHD_HTTP_OK:
|
||||
@ -82,11 +109,13 @@ cert_cb (void *cls,
|
||||
TALER_TESTING_interpreter_next (is);
|
||||
return;
|
||||
}
|
||||
ges->my_denom_date = kr->details.ok.keys->last_denom_issue_date;
|
||||
return;
|
||||
default:
|
||||
GNUNET_break (0);
|
||||
TALER_EXCHANGE_disconnect (ges->exchange);
|
||||
ges->exchange = NULL;
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
|
||||
"/keys responded with HTTP status %u\n",
|
||||
hr->http_status);
|
||||
if (ges->wait_for_keys)
|
||||
{
|
||||
ges->wait_for_keys = false;
|
||||
@ -111,6 +140,7 @@ get_exchange_run (void *cls,
|
||||
struct TALER_TESTING_Interpreter *is)
|
||||
{
|
||||
struct GetExchangeState *ges = cls;
|
||||
struct TALER_EXCHANGE_Keys *xkeys = NULL;
|
||||
|
||||
(void) cmd;
|
||||
if (NULL == ges->exchange_url)
|
||||
@ -119,6 +149,72 @@ get_exchange_run (void *cls,
|
||||
TALER_TESTING_interpreter_fail (is);
|
||||
return;
|
||||
}
|
||||
if (NULL != ges->last_keys_ref)
|
||||
{
|
||||
const struct TALER_TESTING_Command *state_cmd;
|
||||
struct TALER_EXCHANGE_Keys *old_keys;
|
||||
const char *exchange_url;
|
||||
json_t *s_keys;
|
||||
|
||||
state_cmd
|
||||
= TALER_TESTING_interpreter_lookup_command (is,
|
||||
ges->last_keys_ref);
|
||||
if (NULL == state_cmd)
|
||||
{
|
||||
/* Command providing serialized keys not found. */
|
||||
GNUNET_break (0);
|
||||
TALER_TESTING_interpreter_fail (is);
|
||||
return;
|
||||
}
|
||||
if (GNUNET_OK !=
|
||||
TALER_TESTING_get_trait_keys (state_cmd,
|
||||
&old_keys))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
TALER_TESTING_interpreter_fail (is);
|
||||
return;
|
||||
}
|
||||
if (NULL == old_keys)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
TALER_TESTING_interpreter_fail (is);
|
||||
return;
|
||||
}
|
||||
if (GNUNET_OK !=
|
||||
TALER_TESTING_get_trait_exchange_url (state_cmd,
|
||||
&exchange_url))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
TALER_TESTING_interpreter_fail (is);
|
||||
return;
|
||||
}
|
||||
if (0 != strcmp (exchange_url,
|
||||
ges->exchange_url))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
TALER_TESTING_interpreter_fail (is);
|
||||
return;
|
||||
}
|
||||
s_keys = TALER_EXCHANGE_keys_to_json (old_keys);
|
||||
if (NULL == s_keys)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
TALER_TESTING_interpreter_fail (is);
|
||||
return;
|
||||
}
|
||||
xkeys = TALER_EXCHANGE_keys_from_json (s_keys);
|
||||
if (NULL == xkeys)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
json_dumpf (s_keys,
|
||||
stderr,
|
||||
JSON_INDENT (2));
|
||||
json_decref (s_keys);
|
||||
TALER_TESTING_interpreter_fail (is);
|
||||
return;
|
||||
}
|
||||
json_decref (s_keys);
|
||||
}
|
||||
if (NULL != ges->master_priv_file)
|
||||
{
|
||||
if (GNUNET_SYSERR ==
|
||||
@ -127,17 +223,19 @@ get_exchange_run (void *cls,
|
||||
&ges->master_priv.eddsa_priv))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
TALER_EXCHANGE_keys_decref (xkeys);
|
||||
TALER_TESTING_interpreter_fail (is);
|
||||
return;
|
||||
}
|
||||
}
|
||||
ges->is = is;
|
||||
ges->exchange
|
||||
= TALER_EXCHANGE_connect (TALER_TESTING_interpreter_get_context (is),
|
||||
ges->exchange_url,
|
||||
&cert_cb,
|
||||
ges,
|
||||
TALER_EXCHANGE_OPTION_END);
|
||||
= TALER_EXCHANGE_get_keys (TALER_TESTING_interpreter_get_context (is),
|
||||
ges->exchange_url,
|
||||
xkeys,
|
||||
&cert_cb,
|
||||
ges);
|
||||
TALER_EXCHANGE_keys_decref (xkeys);
|
||||
if (NULL == ges->exchange)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
@ -163,9 +261,11 @@ get_exchange_cleanup (void *cls,
|
||||
|
||||
if (NULL != ges->exchange)
|
||||
{
|
||||
TALER_EXCHANGE_disconnect (ges->exchange);
|
||||
TALER_EXCHANGE_get_keys_cancel (ges->exchange);
|
||||
ges->exchange = NULL;
|
||||
}
|
||||
TALER_EXCHANGE_keys_decref (ges->keys);
|
||||
ges->keys = NULL;
|
||||
GNUNET_free (ges->master_priv_file);
|
||||
GNUNET_free (ges->exchange_url);
|
||||
GNUNET_free (ges);
|
||||
@ -189,17 +289,16 @@ get_exchange_traits (void *cls,
|
||||
{
|
||||
struct GetExchangeState *ges = cls;
|
||||
unsigned int off = (NULL == ges->master_priv_file) ? 1 : 0;
|
||||
struct TALER_EXCHANGE_Keys *keys
|
||||
= TALER_EXCHANGE_get_keys (ges->exchange);
|
||||
|
||||
if (NULL != keys)
|
||||
if (NULL != ges->keys)
|
||||
{
|
||||
struct TALER_TESTING_Trait traits[] = {
|
||||
TALER_TESTING_make_trait_master_priv (&ges->master_priv),
|
||||
TALER_TESTING_make_trait_master_pub (&keys->master_pub),
|
||||
TALER_TESTING_make_trait_exchange (ges->exchange),
|
||||
TALER_TESTING_make_trait_keys (keys),
|
||||
TALER_TESTING_make_trait_master_pub (&ges->keys->master_pub),
|
||||
TALER_TESTING_make_trait_keys (ges->keys),
|
||||
TALER_TESTING_make_trait_exchange_url (ges->exchange_url),
|
||||
TALER_TESTING_make_trait_timestamp (0,
|
||||
&ges->my_denom_date),
|
||||
TALER_TESTING_trait_end ()
|
||||
};
|
||||
|
||||
@ -212,8 +311,9 @@ get_exchange_traits (void *cls,
|
||||
{
|
||||
struct TALER_TESTING_Trait traits[] = {
|
||||
TALER_TESTING_make_trait_master_priv (&ges->master_priv),
|
||||
TALER_TESTING_make_trait_exchange (ges->exchange),
|
||||
TALER_TESTING_make_trait_exchange_url (ges->exchange_url),
|
||||
TALER_TESTING_make_trait_timestamp (0,
|
||||
&ges->my_denom_date),
|
||||
TALER_TESTING_trait_end ()
|
||||
};
|
||||
|
||||
@ -284,6 +384,7 @@ struct TALER_TESTING_Command
|
||||
TALER_TESTING_cmd_get_exchange (
|
||||
const char *label,
|
||||
const struct GNUNET_CONFIGURATION_Handle *cfg,
|
||||
const char *last_keys_ref,
|
||||
bool wait_for_keys,
|
||||
bool load_private_key)
|
||||
{
|
||||
@ -291,6 +392,7 @@ TALER_TESTING_cmd_get_exchange (
|
||||
|
||||
ges = GNUNET_new (struct GetExchangeState);
|
||||
ges->exchange_url = get_exchange_base_url (cfg);
|
||||
ges->last_keys_ref = last_keys_ref;
|
||||
if (load_private_key)
|
||||
ges->master_priv_file = get_exchange_master_priv_file (cfg);
|
||||
ges->wait_for_keys = wait_for_keys;
|
||||
|
@ -78,7 +78,8 @@ check_kyc_cb (void *cls,
|
||||
if (kcg->expected_response_code != ks->http_status)
|
||||
{
|
||||
TALER_TESTING_unexpected_status (is,
|
||||
ks->http_status);
|
||||
ks->http_status,
|
||||
kcg->expected_response_code);
|
||||
return;
|
||||
}
|
||||
switch (ks->http_status)
|
||||
|
@ -88,7 +88,8 @@ proof_kyc_cb (void *cls,
|
||||
if (kcg->expected_response_code != kpr->http_status)
|
||||
{
|
||||
TALER_TESTING_unexpected_status (is,
|
||||
kpr->http_status);
|
||||
kpr->http_status,
|
||||
kcg->expected_response_code);
|
||||
return;
|
||||
}
|
||||
switch (kpr->http_status)
|
||||
|
@ -109,7 +109,8 @@ wallet_kyc_cb (void *cls,
|
||||
if (kwg->expected_response_code != wkr->http_status)
|
||||
{
|
||||
TALER_TESTING_unexpected_status (is,
|
||||
wkr->http_status);
|
||||
wkr->http_status,
|
||||
kwg->expected_response_code);
|
||||
return;
|
||||
}
|
||||
switch (wkr->http_status)
|
||||
|
@ -163,7 +163,8 @@ deposit_cb (void *cls,
|
||||
if (ds->expected_response_code != dr->hr.http_status)
|
||||
{
|
||||
TALER_TESTING_unexpected_status (ds->is,
|
||||
dr->hr.http_status);
|
||||
dr->hr.http_status,
|
||||
ds->expected_response_code);
|
||||
return;
|
||||
}
|
||||
if (MHD_HTTP_OK == dr->hr.http_status)
|
||||
|
@ -75,7 +75,8 @@ purse_delete_cb (void *cls,
|
||||
if (pds->expected_response_code != pdr->hr.http_status)
|
||||
{
|
||||
TALER_TESTING_unexpected_status (pds->is,
|
||||
pdr->hr.http_status);
|
||||
pdr->hr.http_status,
|
||||
pds->expected_response_code);
|
||||
return;
|
||||
}
|
||||
TALER_TESTING_interpreter_next (pds->is);
|
||||
|
@ -133,15 +133,13 @@ deposit_cb (void *cls,
|
||||
const struct TALER_EXCHANGE_PurseDepositResponse *dr)
|
||||
{
|
||||
struct PurseDepositState *ds = cls;
|
||||
struct TALER_EXCHANGE_Handle *exchange
|
||||
= TALER_TESTING_get_exchange (ds->is);
|
||||
|
||||
ds->dh = NULL;
|
||||
GNUNET_assert (NULL != exchange);
|
||||
if (ds->expected_response_code != dr->hr.http_status)
|
||||
{
|
||||
TALER_TESTING_unexpected_status (ds->is,
|
||||
dr->hr.http_status);
|
||||
dr->hr.http_status,
|
||||
ds->expected_response_code);
|
||||
return;
|
||||
}
|
||||
if (MHD_HTTP_OK == dr->hr.http_status)
|
||||
@ -197,10 +195,10 @@ deposit_cb (void *cls,
|
||||
/* Deposits complete, create trait! */
|
||||
ds->reserve_history.type = TALER_EXCHANGE_RTT_MERGE;
|
||||
{
|
||||
const struct TALER_EXCHANGE_Keys *keys;
|
||||
struct TALER_EXCHANGE_Keys *keys;
|
||||
const struct TALER_EXCHANGE_GlobalFee *gf;
|
||||
|
||||
keys = TALER_EXCHANGE_get_keys (exchange);
|
||||
keys = TALER_TESTING_get_keys (ds->is);
|
||||
GNUNET_assert (NULL != keys);
|
||||
gf = TALER_EXCHANGE_get_global_fee (keys,
|
||||
*merge_timestamp);
|
||||
|
@ -178,7 +178,8 @@ merge_cb (void *cls,
|
||||
if (ds->expected_response_code != dr->hr.http_status)
|
||||
{
|
||||
TALER_TESTING_unexpected_status (ds->is,
|
||||
dr->hr.http_status);
|
||||
dr->hr.http_status,
|
||||
ds->expected_response_code);
|
||||
return;
|
||||
}
|
||||
TALER_TESTING_interpreter_next (ds->is);
|
||||
|
@ -90,7 +90,8 @@ recoup_cb (void *cls,
|
||||
if (ps->expected_response_code != hr->http_status)
|
||||
{
|
||||
TALER_TESTING_unexpected_status (is,
|
||||
hr->http_status);
|
||||
hr->http_status,
|
||||
ps->expected_response_code);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -89,7 +89,8 @@ recoup_refresh_cb (void *cls,
|
||||
if (rrs->expected_response_code != hr->http_status)
|
||||
{
|
||||
TALER_TESTING_unexpected_status (is,
|
||||
hr->http_status);
|
||||
hr->http_status,
|
||||
rrs->expected_response_code);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -75,7 +75,7 @@ struct TALER_TESTING_FreshCoinData
|
||||
* applicable.
|
||||
*/
|
||||
struct TALER_AgeCommitmentProof *age_commitment_proof;
|
||||
struct TALER_AgeCommitmentHash *h_age_commitment;
|
||||
struct TALER_AgeCommitmentHash h_age_commitment;
|
||||
|
||||
/**
|
||||
* The blinding key (needed for recoup operations).
|
||||
@ -371,12 +371,8 @@ reveal_cb (void *cls,
|
||||
struct RefreshRevealState *rrs = cls;
|
||||
const struct TALER_EXCHANGE_HttpResponse *hr = &rr->hr;
|
||||
const struct TALER_TESTING_Command *melt_cmd;
|
||||
struct TALER_EXCHANGE_Handle *exchange
|
||||
= TALER_TESTING_get_exchange (rrs->is);
|
||||
|
||||
rrs->rrh = NULL;
|
||||
if (NULL == exchange)
|
||||
return;
|
||||
if (rrs->expected_response_code != hr->http_status)
|
||||
{
|
||||
if (0 != rrs->do_retry)
|
||||
@ -406,7 +402,8 @@ reveal_cb (void *cls,
|
||||
}
|
||||
}
|
||||
TALER_TESTING_unexpected_status (rrs->is,
|
||||
hr->http_status);
|
||||
hr->http_status,
|
||||
rrs->expected_response_code);
|
||||
return;
|
||||
}
|
||||
melt_cmd = TALER_TESTING_interpreter_lookup_command (rrs->is,
|
||||
@ -443,8 +440,13 @@ reveal_cb (void *cls,
|
||||
return;
|
||||
}
|
||||
fc->coin_priv = coin->coin_priv;
|
||||
fc->age_commitment_proof = coin->age_commitment_proof;
|
||||
fc->h_age_commitment = coin->h_age_commitment;
|
||||
|
||||
if (NULL != coin->age_commitment_proof)
|
||||
{
|
||||
fc->age_commitment_proof =
|
||||
TALER_age_commitment_proof_duplicate (coin->age_commitment_proof);
|
||||
fc->h_age_commitment = coin->h_age_commitment;
|
||||
}
|
||||
|
||||
TALER_denom_sig_deep_copy (&fc->sig,
|
||||
&coin->sig);
|
||||
@ -562,7 +564,11 @@ refresh_reveal_cleanup (void *cls,
|
||||
}
|
||||
|
||||
for (unsigned int j = 0; j < rrs->num_fresh_coins; j++)
|
||||
{
|
||||
TALER_denom_sig_free (&rrs->fresh_coins[j].sig);
|
||||
TALER_age_commitment_proof_free (rrs->fresh_coins[j].age_commitment_proof);
|
||||
GNUNET_free (rrs->fresh_coins[j].age_commitment_proof);
|
||||
}
|
||||
|
||||
GNUNET_free (rrs->fresh_coins);
|
||||
GNUNET_free (rrs->psa);
|
||||
@ -650,7 +656,8 @@ link_cb (void *cls,
|
||||
}
|
||||
}
|
||||
TALER_TESTING_unexpected_status (rls->is,
|
||||
hr->http_status);
|
||||
hr->http_status,
|
||||
rls->expected_response_code);
|
||||
return;
|
||||
}
|
||||
reveal_cmd = TALER_TESTING_interpreter_lookup_command (rls->is,
|
||||
@ -941,8 +948,10 @@ melt_cb (void *cls,
|
||||
return;
|
||||
}
|
||||
}
|
||||
TALER_TESTING_unexpected_status (rms->is,
|
||||
hr->http_status);
|
||||
TALER_TESTING_unexpected_status_with_body (rms->is,
|
||||
hr->http_status,
|
||||
rms->expected_response_code,
|
||||
hr->reply);
|
||||
return;
|
||||
}
|
||||
if (MHD_HTTP_OK == hr->http_status)
|
||||
@ -1006,12 +1015,8 @@ melt_run (void *cls,
|
||||
NULL
|
||||
};
|
||||
const char **melt_fresh_amounts;
|
||||
struct TALER_EXCHANGE_Handle *exchange
|
||||
= TALER_TESTING_get_exchange (is);
|
||||
|
||||
rms->cmd = cmd;
|
||||
if (NULL == exchange)
|
||||
return;
|
||||
if (NULL == (melt_fresh_amounts = rms->melt_fresh_amounts))
|
||||
melt_fresh_amounts = default_melt_fresh_amounts;
|
||||
rms->is = is;
|
||||
@ -1028,12 +1033,12 @@ melt_run (void *cls,
|
||||
{
|
||||
struct TALER_Amount melt_amount;
|
||||
struct TALER_Amount fresh_amount;
|
||||
const struct TALER_AgeCommitmentProof *age_commitment_proof;
|
||||
const struct TALER_AgeCommitmentHash *h_age_commitment;
|
||||
const struct TALER_AgeCommitmentProof *age_commitment_proof = NULL;
|
||||
const struct TALER_AgeCommitmentHash *h_age_commitment = NULL;
|
||||
const struct TALER_DenominationSignature *melt_sig;
|
||||
const struct TALER_EXCHANGE_DenomPublicKey *melt_denom_pub;
|
||||
const struct TALER_TESTING_Command *coin_command;
|
||||
bool age_restricted;
|
||||
bool age_restricted_denom;
|
||||
|
||||
if (NULL == (coin_command
|
||||
= TALER_TESTING_interpreter_lookup_command (
|
||||
@ -1098,7 +1103,10 @@ melt_run (void *cls,
|
||||
/* Melt amount starts with the melt fee of the old coin; we'll add the
|
||||
values and withdraw fees of the fresh coins next */
|
||||
melt_amount = melt_denom_pub->fees.refresh;
|
||||
age_restricted = melt_denom_pub->key.age_mask.bits != 0;
|
||||
age_restricted_denom = melt_denom_pub->key.age_mask.bits != 0;
|
||||
GNUNET_assert (age_restricted_denom == (NULL != age_commitment_proof));
|
||||
GNUNET_assert ((NULL == age_commitment_proof) ||
|
||||
(0 < age_commitment_proof->commitment.num));
|
||||
for (unsigned int i = 0; i<num_fresh_coins; i++)
|
||||
{
|
||||
const struct TALER_EXCHANGE_DenomPublicKey *fresh_pk;
|
||||
@ -1115,9 +1123,9 @@ melt_run (void *cls,
|
||||
TALER_TESTING_interpreter_fail (rms->is);
|
||||
return;
|
||||
}
|
||||
fresh_pk = TALER_TESTING_find_pk (TALER_EXCHANGE_get_keys (exchange),
|
||||
fresh_pk = TALER_TESTING_find_pk (TALER_TESTING_get_keys (rms->is),
|
||||
&fresh_amount,
|
||||
age_restricted);
|
||||
age_restricted_denom);
|
||||
if (NULL == fresh_pk)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
@ -1143,13 +1151,20 @@ melt_run (void *cls,
|
||||
rms->refresh_data.melt_amount = melt_amount;
|
||||
rms->refresh_data.melt_sig = *melt_sig;
|
||||
rms->refresh_data.melt_pk = *melt_denom_pub;
|
||||
rms->refresh_data.melt_age_commitment_proof = age_commitment_proof;
|
||||
rms->refresh_data.melt_h_age_commitment = h_age_commitment;
|
||||
|
||||
if (NULL != age_commitment_proof)
|
||||
{
|
||||
GNUNET_assert (NULL != h_age_commitment);
|
||||
rms->refresh_data.melt_age_commitment_proof = age_commitment_proof;
|
||||
rms->refresh_data.melt_h_age_commitment = h_age_commitment;
|
||||
}
|
||||
rms->refresh_data.fresh_pks = rms->fresh_pks;
|
||||
rms->refresh_data.fresh_pks_len = num_fresh_coins;
|
||||
|
||||
GNUNET_assert (age_restricted ==
|
||||
GNUNET_assert (age_restricted_denom ==
|
||||
(NULL != age_commitment_proof));
|
||||
GNUNET_assert ((NULL == age_commitment_proof) ||
|
||||
(0 < age_commitment_proof->commitment.num));
|
||||
|
||||
rms->rmh = TALER_EXCHANGE_melt (
|
||||
TALER_TESTING_interpreter_get_context (is),
|
||||
@ -1202,6 +1217,7 @@ melt_cleanup (void *cls,
|
||||
TALER_denom_pub_free (&rms->fresh_pks[i].key);
|
||||
GNUNET_free (rms->fresh_pks);
|
||||
}
|
||||
|
||||
GNUNET_free (rms->mbds);
|
||||
GNUNET_free (rms->melt_fresh_amounts);
|
||||
GNUNET_free (rms);
|
||||
@ -1413,7 +1429,7 @@ refresh_reveal_traits (void *cls,
|
||||
rrs->fresh_coins[index].age_commitment_proof),
|
||||
TALER_TESTING_make_trait_h_age_commitment (
|
||||
index,
|
||||
rrs->fresh_coins[index].h_age_commitment),
|
||||
&rrs->fresh_coins[index].h_age_commitment),
|
||||
TALER_TESTING_make_trait_denom_pub (
|
||||
index,
|
||||
rrs->fresh_coins[index].pk),
|
||||
@ -1431,6 +1447,7 @@ refresh_reveal_traits (void *cls,
|
||||
&rrs->psa[index]),
|
||||
TALER_TESTING_trait_end ()
|
||||
};
|
||||
|
||||
return TALER_TESTING_get_trait (traits,
|
||||
ret,
|
||||
trait,
|
||||
|
@ -83,7 +83,8 @@ refund_cb (void *cls,
|
||||
if (rs->expected_response_code != hr->http_status)
|
||||
{
|
||||
TALER_TESTING_unexpected_status (rs->is,
|
||||
hr->http_status);
|
||||
hr->http_status,
|
||||
rs->expected_response_code);
|
||||
return;
|
||||
}
|
||||
TALER_TESTING_interpreter_next (rs->is);
|
||||
|
@ -230,19 +230,15 @@ reserve_history_cb (void *cls,
|
||||
struct HistoryState *ss = cls;
|
||||
struct TALER_TESTING_Interpreter *is = ss->is;
|
||||
struct TALER_Amount eb;
|
||||
struct TALER_EXCHANGE_Handle *exchange
|
||||
= TALER_TESTING_get_exchange (is);
|
||||
|
||||
ss->rsh = NULL;
|
||||
if (NULL == exchange)
|
||||
return;
|
||||
if (MHD_HTTP_OK == rs->hr.http_status)
|
||||
{
|
||||
const struct TALER_EXCHANGE_Keys *keys;
|
||||
struct TALER_EXCHANGE_Keys *keys;
|
||||
const struct TALER_EXCHANGE_GlobalFee *gf;
|
||||
|
||||
ss->reserve_history.type = TALER_EXCHANGE_RTT_HISTORY;
|
||||
keys = TALER_EXCHANGE_get_keys (exchange);
|
||||
keys = TALER_TESTING_get_keys (is);
|
||||
GNUNET_assert (NULL != keys);
|
||||
gf = TALER_EXCHANGE_get_global_fee (keys,
|
||||
rs->ts);
|
||||
@ -343,11 +339,7 @@ history_run (void *cls,
|
||||
{
|
||||
struct HistoryState *ss = cls;
|
||||
const struct TALER_TESTING_Command *create_reserve;
|
||||
struct TALER_EXCHANGE_Handle *exchange
|
||||
= TALER_TESTING_get_exchange (is);
|
||||
|
||||
if (NULL == exchange)
|
||||
return;
|
||||
ss->is = is;
|
||||
create_reserve
|
||||
= TALER_TESTING_interpreter_lookup_command (is,
|
||||
|
@ -165,11 +165,7 @@ open_run (void *cls,
|
||||
struct OpenState *ss = cls;
|
||||
const struct TALER_TESTING_Command *create_reserve;
|
||||
struct TALER_EXCHANGE_PurseDeposit cp[GNUNET_NZL (ss->cpl)];
|
||||
struct TALER_EXCHANGE_Handle *exchange
|
||||
= TALER_TESTING_get_exchange (is);
|
||||
|
||||
if (NULL == exchange)
|
||||
return;
|
||||
ss->is = is;
|
||||
create_reserve
|
||||
= TALER_TESTING_interpreter_lookup_command (is,
|
||||
|
@ -154,7 +154,8 @@ purse_cb (void *cls,
|
||||
if (ds->expected_response_code != dr->hr.http_status)
|
||||
{
|
||||
TALER_TESTING_unexpected_status (ds->is,
|
||||
dr->hr.http_status);
|
||||
dr->hr.http_status,
|
||||
ds->expected_response_code);
|
||||
return;
|
||||
}
|
||||
switch (dr->hr.http_status)
|
||||
@ -184,12 +185,8 @@ purse_run (void *cls,
|
||||
struct ReservePurseState *ds = cls;
|
||||
const struct TALER_ReservePrivateKeyP *reserve_priv;
|
||||
const struct TALER_TESTING_Command *ref;
|
||||
struct TALER_EXCHANGE_Handle *exchange
|
||||
= TALER_TESTING_get_exchange (is);
|
||||
|
||||
(void) cmd;
|
||||
if (NULL == exchange)
|
||||
return;
|
||||
ds->is = is;
|
||||
ref = TALER_TESTING_interpreter_lookup_command (ds->is,
|
||||
ds->reserve_ref);
|
||||
|
@ -314,11 +314,7 @@ status_run (void *cls,
|
||||
{
|
||||
struct StatusState *ss = cls;
|
||||
const struct TALER_TESTING_Command *create_reserve;
|
||||
struct TALER_EXCHANGE_Handle *exchange
|
||||
= TALER_TESTING_get_exchange (is);
|
||||
|
||||
if (NULL == exchange)
|
||||
return;
|
||||
ss->is = is;
|
||||
create_reserve
|
||||
= TALER_TESTING_interpreter_lookup_command (is,
|
||||
|
@ -79,7 +79,8 @@ success_cb (
|
||||
if (rs->expected_response_code != hr->http_status)
|
||||
{
|
||||
TALER_TESTING_unexpected_status (rs->is,
|
||||
hr->http_status);
|
||||
hr->http_status,
|
||||
rs->expected_response_code);
|
||||
return;
|
||||
}
|
||||
TALER_TESTING_interpreter_next (rs->is);
|
||||
|
@ -79,7 +79,8 @@ success_cb (
|
||||
if (rs->expected_response_code != hr->http_status)
|
||||
{
|
||||
TALER_TESTING_unexpected_status (rs->is,
|
||||
hr->http_status);
|
||||
hr->http_status,
|
||||
rs->expected_response_code);
|
||||
return;
|
||||
}
|
||||
TALER_TESTING_interpreter_next (rs->is);
|
||||
|
@ -110,6 +110,7 @@ run_fakebank_cleanup (void *cls,
|
||||
}
|
||||
GNUNET_free (rfs->ba.wire_gateway_url);
|
||||
GNUNET_free (rfs->bank_url);
|
||||
GNUNET_free (rfs->currency);
|
||||
GNUNET_free (rfs);
|
||||
}
|
||||
|
||||
@ -194,7 +195,9 @@ TALER_TESTING_cmd_run_fakebank (
|
||||
(unsigned int) fakebank_port,
|
||||
exchange_xtalerbank_account);
|
||||
GNUNET_free (exchange_xtalerbank_account);
|
||||
GNUNET_free (exchange_payto_uri);
|
||||
}
|
||||
GNUNET_free (exchange_payto_uri);
|
||||
rfs->ba.method = TALER_BANK_AUTH_NONE;
|
||||
{
|
||||
struct TALER_TESTING_Command cmd = {
|
||||
|
@ -1,144 +0,0 @@
|
||||
/*
|
||||
This file is part of TALER
|
||||
(C) 2018-2023 Taler Systems SA
|
||||
|
||||
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 testing/testing_api_cmd_serialize_keys.c
|
||||
* @brief Lets tests use the keys serialization API.
|
||||
* @author Marcello Stanisci
|
||||
*/
|
||||
#include "platform.h"
|
||||
#include <jansson.h>
|
||||
#include "taler_testing_lib.h"
|
||||
|
||||
|
||||
/**
|
||||
* Internal state for a serialize-keys CMD.
|
||||
*/
|
||||
struct SerializeKeysState
|
||||
{
|
||||
/**
|
||||
* Serialized keys.
|
||||
*/
|
||||
json_t *keys;
|
||||
|
||||
/**
|
||||
* Exchange URL. Needed because the exchange gets disconnected
|
||||
* from, after keys serialization. This value is then needed by
|
||||
* subsequent commands that have to reconnect to the exchange.
|
||||
*/
|
||||
char *exchange_url;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Run the command.
|
||||
*
|
||||
* @param cls closure.
|
||||
* @param cmd the command to execute.
|
||||
* @param is the interpreter state.
|
||||
*/
|
||||
static void
|
||||
serialize_keys_run (void *cls,
|
||||
const struct TALER_TESTING_Command *cmd,
|
||||
struct TALER_TESTING_Interpreter *is)
|
||||
{
|
||||
struct SerializeKeysState *sks = cls;
|
||||
struct TALER_EXCHANGE_Handle *exchange
|
||||
= TALER_TESTING_get_exchange (is);
|
||||
|
||||
if (NULL == exchange)
|
||||
return;
|
||||
sks->keys = TALER_EXCHANGE_serialize_data (exchange);
|
||||
if (NULL == sks->keys)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
TALER_TESTING_interpreter_fail (is);
|
||||
}
|
||||
sks->exchange_url
|
||||
= GNUNET_strdup (
|
||||
TALER_EXCHANGE_get_base_url (exchange));
|
||||
TALER_TESTING_interpreter_next (is);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Cleanup the state of a "serialize keys" CMD.
|
||||
*
|
||||
* @param cls closure.
|
||||
* @param cmd the command which is being cleaned up.
|
||||
*/
|
||||
static void
|
||||
serialize_keys_cleanup (void *cls,
|
||||
const struct TALER_TESTING_Command *cmd)
|
||||
{
|
||||
struct SerializeKeysState *sks = cls;
|
||||
|
||||
if (NULL != sks->keys)
|
||||
json_decref (sks->keys);
|
||||
GNUNET_free (sks->exchange_url);
|
||||
GNUNET_free (sks);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Offer serialized keys as trait.
|
||||
*
|
||||
* @param cls closure.
|
||||
* @param[out] ret result.
|
||||
* @param trait name of the trait.
|
||||
* @param index index number of the object to offer.
|
||||
* @return #GNUNET_OK on success.
|
||||
*/
|
||||
static enum GNUNET_GenericReturnValue
|
||||
serialize_keys_traits (void *cls,
|
||||
const void **ret,
|
||||
const char *trait,
|
||||
unsigned int index)
|
||||
{
|
||||
struct SerializeKeysState *sks = cls;
|
||||
struct TALER_TESTING_Trait traits[] = {
|
||||
TALER_TESTING_make_trait_exchange_keys (sks->keys),
|
||||
TALER_TESTING_make_trait_exchange_url (sks->exchange_url),
|
||||
TALER_TESTING_trait_end ()
|
||||
};
|
||||
|
||||
return TALER_TESTING_get_trait (traits,
|
||||
ret,
|
||||
trait,
|
||||
index);
|
||||
}
|
||||
|
||||
|
||||
struct TALER_TESTING_Command
|
||||
TALER_TESTING_cmd_serialize_keys (const char *label)
|
||||
{
|
||||
struct SerializeKeysState *sks;
|
||||
|
||||
sks = GNUNET_new (struct SerializeKeysState);
|
||||
{
|
||||
struct TALER_TESTING_Command cmd = {
|
||||
.cls = sks,
|
||||
.label = label,
|
||||
.run = serialize_keys_run,
|
||||
.cleanup = serialize_keys_cleanup,
|
||||
.traits = serialize_keys_traits
|
||||
};
|
||||
|
||||
return cmd;
|
||||
}
|
||||
}
|
@ -98,7 +98,8 @@ set_officer_cb (void *cls,
|
||||
if (MHD_HTTP_NO_CONTENT != hr->http_status)
|
||||
{
|
||||
TALER_TESTING_unexpected_status (ds->is,
|
||||
hr->http_status);
|
||||
hr->http_status,
|
||||
MHD_HTTP_NO_CONTENT);
|
||||
return;
|
||||
}
|
||||
TALER_TESTING_interpreter_next (ds->is);
|
||||
|
@ -90,7 +90,8 @@ wire_add_cb (void *cls,
|
||||
if (ds->expected_response_code != hr->http_status)
|
||||
{
|
||||
TALER_TESTING_unexpected_status (ds->is,
|
||||
hr->http_status);
|
||||
hr->http_status,
|
||||
ds->expected_response_code);
|
||||
return;
|
||||
}
|
||||
TALER_TESTING_interpreter_next (ds->is);
|
||||
|
@ -108,7 +108,8 @@ take_aml_decision_cb (
|
||||
if (ds->expected_response != hr->http_status)
|
||||
{
|
||||
TALER_TESTING_unexpected_status (ds->is,
|
||||
hr->http_status);
|
||||
hr->http_status,
|
||||
ds->expected_response);
|
||||
return;
|
||||
}
|
||||
TALER_TESTING_interpreter_next (ds->is);
|
||||
|
@ -133,7 +133,8 @@ track_transfer_cb (void *cls,
|
||||
if (tts->expected_response_code != hr->http_status)
|
||||
{
|
||||
TALER_TESTING_unexpected_status (is,
|
||||
hr->http_status);
|
||||
hr->http_status,
|
||||
tts->expected_response_code);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -309,12 +310,8 @@ track_transfer_run (void *cls,
|
||||
struct TrackTransferState *tts = cls;
|
||||
struct TALER_WireTransferIdentifierRawP wtid;
|
||||
const struct TALER_WireTransferIdentifierRawP *wtid_ptr;
|
||||
struct TALER_EXCHANGE_Handle *exchange
|
||||
= TALER_TESTING_get_exchange (is);
|
||||
|
||||
tts->cmd = cmd;
|
||||
if (NULL == exchange)
|
||||
return;
|
||||
/* If no reference is given, we'll use a all-zeros
|
||||
* WTID */
|
||||
memset (&wtid,
|
||||
|
@ -80,7 +80,8 @@ wire_add_cb (void *cls,
|
||||
if (ds->expected_response_code != hr->http_status)
|
||||
{
|
||||
TALER_TESTING_unexpected_status (ds->is,
|
||||
hr->http_status);
|
||||
hr->http_status,
|
||||
ds->expected_response_code);
|
||||
return;
|
||||
}
|
||||
TALER_TESTING_interpreter_next (ds->is);
|
||||
|
@ -80,7 +80,9 @@ wire_del_cb (void *cls,
|
||||
if (ds->expected_response_code != hr->http_status)
|
||||
{
|
||||
TALER_TESTING_unexpected_status (ds->is,
|
||||
hr->http_status);
|
||||
hr->http_status,
|
||||
ds->expected_response_code);
|
||||
|
||||
return;
|
||||
}
|
||||
TALER_TESTING_interpreter_next (ds->is);
|
||||
|
@ -144,10 +144,10 @@ struct WithdrawState
|
||||
|
||||
/**
|
||||
* If age > 0, put here the corresponding age commitment with its proof and
|
||||
* its hash, respectivelly, NULL otherwise.
|
||||
* its hash, respectivelly.
|
||||
*/
|
||||
struct TALER_AgeCommitmentProof *age_commitment_proof;
|
||||
struct TALER_AgeCommitmentHash *h_age_commitment;
|
||||
struct TALER_AgeCommitmentProof age_commitment_proof;
|
||||
struct TALER_AgeCommitmentHash h_age_commitment;
|
||||
|
||||
/**
|
||||
* Reserve history entry that corresponds to this operation.
|
||||
@ -284,7 +284,8 @@ reserve_withdraw_cb (void *cls,
|
||||
}
|
||||
}
|
||||
TALER_TESTING_unexpected_status (is,
|
||||
wr->hr.http_status);
|
||||
wr->hr.http_status,
|
||||
ws->expected_response_code);
|
||||
return;
|
||||
}
|
||||
switch (wr->hr.http_status)
|
||||
@ -347,7 +348,6 @@ withdraw_run (void *cls,
|
||||
const struct TALER_ReservePrivateKeyP *rp;
|
||||
const struct TALER_TESTING_Command *create_reserve;
|
||||
const struct TALER_EXCHANGE_DenomPublicKey *dpk;
|
||||
struct TALER_EXCHANGE_Handle *exchange;
|
||||
|
||||
ws->cmd = cmd;
|
||||
ws->is = is;
|
||||
@ -369,12 +369,9 @@ withdraw_run (void *cls,
|
||||
TALER_TESTING_interpreter_fail (is);
|
||||
return;
|
||||
}
|
||||
exchange = TALER_TESTING_get_exchange (is);
|
||||
if (NULL == exchange)
|
||||
return;
|
||||
if (NULL == ws->exchange_url)
|
||||
ws->exchange_url
|
||||
= GNUNET_strdup (TALER_EXCHANGE_get_base_url (exchange));
|
||||
= GNUNET_strdup (TALER_TESTING_get_exchange_url (is));
|
||||
ws->reserve_priv = *rp;
|
||||
GNUNET_CRYPTO_eddsa_key_get_public (&ws->reserve_priv.eddsa_priv,
|
||||
&ws->reserve_pub.eddsa_pub);
|
||||
@ -441,7 +438,7 @@ withdraw_run (void *cls,
|
||||
struct TALER_EXCHANGE_WithdrawCoinInput wci = {
|
||||
.pk = ws->pk,
|
||||
.ps = &ws->ps,
|
||||
.ach = ws->h_age_commitment
|
||||
.ach = 0 < ws->age ? &ws->h_age_commitment : NULL
|
||||
};
|
||||
ws->wsh = TALER_EXCHANGE_withdraw (
|
||||
TALER_TESTING_interpreter_get_context (is),
|
||||
@ -492,16 +489,8 @@ withdraw_cleanup (void *cls,
|
||||
TALER_EXCHANGE_destroy_denomination_key (ws->pk);
|
||||
ws->pk = NULL;
|
||||
}
|
||||
if (NULL != ws->age_commitment_proof)
|
||||
{
|
||||
TALER_age_commitment_proof_free (ws->age_commitment_proof);
|
||||
ws->age_commitment_proof = NULL;
|
||||
}
|
||||
if (NULL != ws->h_age_commitment)
|
||||
{
|
||||
GNUNET_free (ws->h_age_commitment);
|
||||
ws->h_age_commitment = NULL;
|
||||
}
|
||||
if (ws->age > 0)
|
||||
TALER_age_commitment_proof_free (&ws->age_commitment_proof);
|
||||
GNUNET_free (ws->exchange_url);
|
||||
GNUNET_free (ws->reserve_payto_uri);
|
||||
GNUNET_free (ws);
|
||||
@ -548,9 +537,13 @@ withdraw_traits (void *cls,
|
||||
TALER_TESTING_make_trait_payto_uri (ws->reserve_payto_uri),
|
||||
TALER_TESTING_make_trait_exchange_url (ws->exchange_url),
|
||||
TALER_TESTING_make_trait_age_commitment_proof (0,
|
||||
ws->age_commitment_proof),
|
||||
0 < ws->age
|
||||
? &ws->age_commitment_proof
|
||||
: NULL),
|
||||
TALER_TESTING_make_trait_h_age_commitment (0,
|
||||
ws->h_age_commitment),
|
||||
0 < ws->age
|
||||
? &ws->h_age_commitment
|
||||
: NULL),
|
||||
TALER_TESTING_trait_end ()
|
||||
};
|
||||
|
||||
@ -576,13 +569,9 @@ TALER_TESTING_cmd_withdraw_amount (const char *label,
|
||||
ws->age = age;
|
||||
if (0 < age)
|
||||
{
|
||||
struct TALER_AgeCommitmentProof *acp;
|
||||
struct TALER_AgeCommitmentHash *hac;
|
||||
struct GNUNET_HashCode seed;
|
||||
struct TALER_AgeMask mask;
|
||||
|
||||
acp = GNUNET_new (struct TALER_AgeCommitmentProof);
|
||||
hac = GNUNET_new (struct TALER_AgeCommitmentHash);
|
||||
mask = TALER_extensions_get_age_restriction_mask ();
|
||||
GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
|
||||
&seed,
|
||||
@ -593,7 +582,7 @@ TALER_TESTING_cmd_withdraw_amount (const char *label,
|
||||
&mask,
|
||||
age,
|
||||
&seed,
|
||||
acp))
|
||||
&ws->age_commitment_proof))
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Failed to generate age commitment for age %d at %s\n",
|
||||
@ -601,10 +590,8 @@ TALER_TESTING_cmd_withdraw_amount (const char *label,
|
||||
label);
|
||||
GNUNET_assert (0);
|
||||
}
|
||||
TALER_age_commitment_hash (&acp->commitment,
|
||||
hac);
|
||||
ws->age_commitment_proof = acp;
|
||||
ws->h_age_commitment = hac;
|
||||
TALER_age_commitment_hash (&ws->age_commitment_proof.commitment,
|
||||
&ws->h_age_commitment);
|
||||
}
|
||||
|
||||
ws->reserve_reference = reserve_reference;
|
||||
|
@ -75,33 +75,6 @@ TALER_TESTING_get_trait (const struct TALER_TESTING_Trait *traits,
|
||||
}
|
||||
|
||||
|
||||
struct TALER_EXCHANGE_Handle *
|
||||
TALER_TESTING_get_exchange (struct TALER_TESTING_Interpreter *is)
|
||||
{
|
||||
struct TALER_EXCHANGE_Handle *exchange;
|
||||
const struct TALER_TESTING_Command *exchange_cmd;
|
||||
|
||||
exchange_cmd
|
||||
= TALER_TESTING_interpreter_get_command (is,
|
||||
"exchange");
|
||||
if (NULL == exchange_cmd)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
TALER_TESTING_interpreter_fail (is);
|
||||
return NULL;
|
||||
}
|
||||
if (GNUNET_OK !=
|
||||
TALER_TESTING_get_trait_exchange (exchange_cmd,
|
||||
&exchange))
|
||||
{
|
||||
GNUNET_break (0);
|
||||
TALER_TESTING_interpreter_fail (is);
|
||||
return NULL;
|
||||
}
|
||||
return exchange;
|
||||
}
|
||||
|
||||
|
||||
const char *
|
||||
TALER_TESTING_get_exchange_url (struct TALER_TESTING_Interpreter *is)
|
||||
{
|
||||
|
@ -464,6 +464,9 @@ void
|
||||
TALER_age_proof_free (
|
||||
struct TALER_AgeProof *proof)
|
||||
{
|
||||
if (NULL == proof)
|
||||
return;
|
||||
|
||||
if (NULL != proof->keys)
|
||||
{
|
||||
GNUNET_CRYPTO_zero_keys (
|
||||
@ -479,26 +482,71 @@ TALER_age_proof_free (
|
||||
|
||||
void
|
||||
TALER_age_commitment_proof_free (
|
||||
struct TALER_AgeCommitmentProof *cp)
|
||||
struct TALER_AgeCommitmentProof *acp)
|
||||
{
|
||||
if (NULL != cp->proof.keys)
|
||||
if (NULL == acp)
|
||||
return;
|
||||
|
||||
if (NULL != acp->proof.keys)
|
||||
{
|
||||
GNUNET_CRYPTO_zero_keys (
|
||||
cp->proof.keys,
|
||||
sizeof(*cp->proof.keys) * cp->proof.num);
|
||||
acp->proof.keys,
|
||||
sizeof(*acp->proof.keys) * acp->proof.num);
|
||||
|
||||
GNUNET_free (cp->proof.keys);
|
||||
cp->proof.keys = NULL;
|
||||
GNUNET_free (acp->proof.keys);
|
||||
acp->proof.keys = NULL;
|
||||
}
|
||||
|
||||
if (NULL != cp->commitment.keys)
|
||||
if (NULL != acp->commitment.keys)
|
||||
{
|
||||
GNUNET_free (cp->commitment.keys);
|
||||
cp->commitment.keys = NULL;
|
||||
GNUNET_free (acp->commitment.keys);
|
||||
acp->commitment.keys = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct TALER_AgeCommitmentProof *
|
||||
TALER_age_commitment_proof_duplicate (
|
||||
const struct TALER_AgeCommitmentProof *acp)
|
||||
{
|
||||
struct TALER_AgeCommitmentProof *nacp;
|
||||
|
||||
GNUNET_assert (NULL != acp);
|
||||
GNUNET_assert (__builtin_popcount (acp->commitment.mask.bits) - 1 ==
|
||||
(int) acp->commitment.num);
|
||||
|
||||
nacp = GNUNET_new (struct TALER_AgeCommitmentProof);
|
||||
|
||||
TALER_age_commitment_proof_deep_copy (acp,nacp);
|
||||
return nacp;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TALER_age_commitment_proof_deep_copy (
|
||||
const struct TALER_AgeCommitmentProof *acp,
|
||||
struct TALER_AgeCommitmentProof *nacp)
|
||||
{
|
||||
GNUNET_assert (NULL != acp);
|
||||
GNUNET_assert (__builtin_popcount (acp->commitment.mask.bits) - 1 ==
|
||||
(int) acp->commitment.num);
|
||||
|
||||
*nacp = *acp;
|
||||
nacp->commitment.keys =
|
||||
GNUNET_new_array (acp->commitment.num,
|
||||
struct TALER_AgeCommitmentPublicKeyP);
|
||||
nacp->proof.keys =
|
||||
GNUNET_new_array (acp->proof.num,
|
||||
struct TALER_AgeCommitmentPrivateKeyP);
|
||||
|
||||
for (size_t i = 0; i < acp->commitment.num; i++)
|
||||
nacp->commitment.keys[i] = acp->commitment.keys[i];
|
||||
|
||||
for (size_t i = 0; i < acp->proof.num; i++)
|
||||
nacp->proof.keys[i] = acp->proof.keys[i];
|
||||
}
|
||||
|
||||
|
||||
enum GNUNET_GenericReturnValue
|
||||
TALER_JSON_parse_age_groups (const json_t *root,
|
||||
struct TALER_AgeMask *mask)
|
||||
@ -571,19 +619,16 @@ TALER_parse_age_group_string (
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
const char *
|
||||
TALER_age_mask_to_string (
|
||||
const struct TALER_AgeMask *mask)
|
||||
{
|
||||
static char buf[256] = {0};
|
||||
uint32_t bits = mask->bits;
|
||||
unsigned int n = 0;
|
||||
char *buf = GNUNET_malloc (32 * 3); // max characters possible
|
||||
char *pos = buf;
|
||||
|
||||
if (NULL == buf)
|
||||
{
|
||||
return buf;
|
||||
}
|
||||
memset (buf, 0, sizeof(buf));
|
||||
|
||||
while (bits != 0)
|
||||
{
|
||||
|
@ -461,4 +461,54 @@ TALER_coin_ev_hash (const struct TALER_BlindedPlanchet *blinded_planchet,
|
||||
}
|
||||
|
||||
|
||||
GNUNET_NETWORK_STRUCT_BEGIN
|
||||
/**
|
||||
* Structure we hash to compute the group key for
|
||||
* a denomination group.
|
||||
*/
|
||||
struct DenominationGroupP
|
||||
{
|
||||
/**
|
||||
* Value of coins in this denomination group.
|
||||
*/
|
||||
struct TALER_AmountNBO value;
|
||||
|
||||
/**
|
||||
* Fee structure for all coins in the group.
|
||||
*/
|
||||
struct TALER_DenomFeeSetNBOP fees;
|
||||
|
||||
/**
|
||||
* Age mask for the denomiation, in NBO.
|
||||
*/
|
||||
uint32_t age_mask GNUNET_PACKED;
|
||||
|
||||
/**
|
||||
* Cipher used for the denomination, in NBO.
|
||||
*/
|
||||
uint32_t cipher GNUNET_PACKED;
|
||||
};
|
||||
GNUNET_NETWORK_STRUCT_END
|
||||
|
||||
|
||||
void
|
||||
TALER_denomination_group_get_key (
|
||||
const struct TALER_DenominationGroup *dg,
|
||||
struct GNUNET_HashCode *key)
|
||||
{
|
||||
struct DenominationGroupP dgp = {
|
||||
.age_mask = htonl (dg->age_mask.bits),
|
||||
.cipher = htonl (dg->cipher)
|
||||
};
|
||||
|
||||
TALER_amount_hton (&dgp.value,
|
||||
&dg->value);
|
||||
TALER_denom_fee_set_hton (&dgp.fees,
|
||||
&dg->fees);
|
||||
GNUNET_CRYPTO_hash (&dgp,
|
||||
sizeof (dgp),
|
||||
key);
|
||||
}
|
||||
|
||||
|
||||
/* end of crypto.c */
|
||||
|
Loading…
Reference in New Issue
Block a user