Line data Source code
1 : /*
2 : This file is part of TALER
3 : Copyright (C) 2014--2022 Taler Systems SA
4 :
5 : TALER is free software; you can redistribute it and/or modify
6 : it under the terms of the GNU General Public License as
7 : published by the Free Software Foundation; either version 3, or
8 : (at your option) any later version.
9 :
10 : TALER is distributed in the hope that it will be useful, but
11 : WITHOUT ANY WARRANTY; without even the implied warranty of
12 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 : GNU General Public License for more details.
14 :
15 : You should have received a copy of the GNU General Public
16 : License along with TALER; see the file COPYING. If not, see
17 : <http://www.gnu.org/licenses/>
18 : */
19 : /**
20 : * @file testing/test_exchange_api.c
21 : * @brief testcase to test exchange's HTTP API interface
22 : * @author Sree Harsha Totakura <sreeharsha@totakura.in>
23 : * @author Christian Grothoff
24 : * @author Marcello Stanisci
25 : */
26 : #include "taler/taler_util.h"
27 : #include "taler/taler_signatures.h"
28 : #include "taler/taler_json_lib.h"
29 : #include <gnunet/gnunet_util_lib.h>
30 : #include <gnunet/gnunet_testing_lib.h>
31 : #include <microhttpd.h>
32 : #include "taler/taler_bank_service.h"
33 : #include "taler/taler_testing_lib.h"
34 : #include "taler/taler_extensions.h"
35 :
36 : /**
37 : * Configuration file we use. One (big) configuration is used
38 : * for the various components for this test.
39 : */
40 : static char *config_file;
41 :
42 : /**
43 : * Special configuration file to use when we want reserves
44 : * to expire 'immediately'.
45 : */
46 : static char *config_file_expire_reserve_now;
47 :
48 : /**
49 : * Our credentials.
50 : */
51 : static struct TALER_TESTING_Credentials cred;
52 :
53 : /**
54 : * Some tests behave differently when using CS as we cannot
55 : * reuse the coin private key for different denominations
56 : * due to the derivation of it with the /csr values. Hence
57 : * some tests behave differently in CS mode, hence this
58 : * flag.
59 : */
60 : static bool uses_cs;
61 :
62 : /**
63 : * Execute the taler-exchange-wirewatch command with
64 : * our configuration file.
65 : *
66 : * @param label label to use for the command.
67 : */
68 : #define CMD_EXEC_WIREWATCH(label) \
69 : TALER_TESTING_cmd_exec_wirewatch2 (label, config_file, \
70 : "exchange-account-2")
71 :
72 : /**
73 : * Execute the taler-exchange-aggregator, closer and transfer commands with
74 : * our configuration file.
75 : *
76 : * @param label label to use for the command.
77 : */
78 : #define CMD_EXEC_AGGREGATOR(label) \
79 : TALER_TESTING_cmd_sleep ("sleep-before-aggregator", 2), \
80 : TALER_TESTING_cmd_exec_aggregator (label "-aggregator", config_file), \
81 : TALER_TESTING_cmd_exec_transfer (label "-transfer", config_file)
82 :
83 :
84 : /**
85 : * Run wire transfer of funds from some user's account to the
86 : * exchange.
87 : *
88 : * @param label label to use for the command.
89 : * @param amount amount to transfer, i.e. "EUR:1"
90 : */
91 : #define CMD_TRANSFER_TO_EXCHANGE(label,amount) \
92 : TALER_TESTING_cmd_admin_add_incoming (label, amount, \
93 : &cred.ba, \
94 : cred.user42_payto)
95 :
96 : /**
97 : * Main function that will tell the interpreter what commands to
98 : * run.
99 : *
100 : * @param cls closure
101 : * @param is interpreter we use to run commands
102 : */
103 : static void
104 2 : run (void *cls,
105 : struct TALER_TESTING_Interpreter *is)
106 : {
107 : /**
108 : * Test withdrawal plus spending.
109 : */
110 : struct TALER_TESTING_Command withdraw[] = {
111 : /**
112 : * Move money to the exchange's bank account.
113 : */
114 2 : CMD_TRANSFER_TO_EXCHANGE ("create-reserve-1",
115 : "EUR:6.02"),
116 2 : TALER_TESTING_cmd_reserve_poll ("poll-reserve-1",
117 : "create-reserve-1",
118 : "EUR:6.02",
119 : GNUNET_TIME_UNIT_MINUTES,
120 : MHD_HTTP_OK),
121 2 : TALER_TESTING_cmd_check_bank_admin_transfer ("check-create-reserve-1",
122 : "EUR:6.02",
123 : cred.user42_payto,
124 : cred.exchange_payto,
125 : "create-reserve-1"),
126 : /**
127 : * Make a reserve exist, according to the previous
128 : * transfer.
129 : */
130 2 : CMD_EXEC_WIREWATCH ("wirewatch-1"),
131 2 : TALER_TESTING_cmd_reserve_poll_finish ("finish-poll-reserve-1",
132 : GNUNET_TIME_relative_multiply (
133 : GNUNET_TIME_UNIT_SECONDS,
134 : 2),
135 : "poll-reserve-1"),
136 : /**
137 : * Withdraw EUR:5.
138 : */
139 2 : TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-1",
140 : "create-reserve-1",
141 : "EUR:5",
142 : 0, /* age restriction off */
143 : MHD_HTTP_OK),
144 : /**
145 : * Idempotent withdrawal. Note that in the case of CS, this is _not_
146 : * idempotent because the blinding nonces still differ, so instead,
147 : * it is an overcharging of the reserve.
148 : */
149 2 : TALER_TESTING_cmd_withdraw_amount_reuse_key ("withdraw-coin-1-idem",
150 : "create-reserve-1",
151 : "EUR:5",
152 : 0, /* age restriction off */
153 : "withdraw-coin-1",
154 : (uses_cs)
155 2 : ? MHD_HTTP_CONFLICT
156 : : MHD_HTTP_OK),
157 : /**
158 : * Withdraw EUR:1 using the SAME private coin key as for the previous coin
159 : * (in violation of the specification, to be detected on spending!).
160 : * However, note that this does NOT work with 'CS', as for a different
161 : * denomination we get different R0/R1 values from the exchange, and
162 : * thus will generate a different coin private key as R0/R1 are hashed
163 : * into the coin priv. So here, we fail to 'reuse' the key due to the
164 : * cryptographic construction!
165 : */
166 2 : TALER_TESTING_cmd_withdraw_amount_reuse_key ("withdraw-coin-1x",
167 : "create-reserve-1",
168 : "EUR:1",
169 : 0, /* age restriction off */
170 : "withdraw-coin-1",
171 : MHD_HTTP_OK),
172 : /**
173 : * Check the reserve is depleted.
174 : */
175 2 : TALER_TESTING_cmd_status ("status-1",
176 : "create-reserve-1",
177 : "EUR:0",
178 : MHD_HTTP_OK),
179 : /*
180 : * Try to overdraw.
181 : */
182 2 : TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-2",
183 : "create-reserve-1",
184 : "EUR:5",
185 : 0, /* age restriction off */
186 : MHD_HTTP_CONFLICT),
187 2 : TALER_TESTING_cmd_end ()
188 : };
189 :
190 : struct TALER_TESTING_Command spend[] = {
191 : /**
192 : * Spend the coin.
193 : */
194 2 : TALER_TESTING_cmd_set_var (
195 : "account-priv",
196 : TALER_TESTING_cmd_deposit (
197 : "deposit-simple-fail-kyc",
198 : "withdraw-coin-1",
199 : 0,
200 : cred.user42_payto,
201 : "{\"items\":[{\"name\":\"ice cream\",\"value\":1}]}",
202 2 : GNUNET_TIME_UNIT_ZERO,
203 : "EUR:5",
204 : MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS)),
205 2 : TALER_TESTING_cmd_admin_add_kycauth (
206 : "kyc-auth-transfer",
207 : "EUR:0.01",
208 : &cred.ba,
209 : cred.user42_payto,
210 : "deposit-simple-fail-kyc"),
211 2 : CMD_EXEC_WIREWATCH (
212 : "import-kyc-account-withdraw"),
213 2 : TALER_TESTING_cmd_deposit_replay (
214 : "deposit-simple",
215 : "deposit-simple-fail-kyc",
216 : MHD_HTTP_OK),
217 2 : TALER_TESTING_cmd_deposit_replay (
218 : "deposit-simple-replay-1",
219 : "deposit-simple",
220 : MHD_HTTP_OK),
221 2 : TALER_TESTING_cmd_sleep (
222 : "sleep-before-deposit-replay",
223 : 1),
224 2 : TALER_TESTING_cmd_deposit_replay (
225 : "deposit-simple-replay-2",
226 : "deposit-simple",
227 : MHD_HTTP_OK),
228 : /* This creates a conflict, as we have the same coin public key (reuse!),
229 : but different denomination public keys (which is not allowed).
230 : However, note that this does NOT work with 'CS', as for a different
231 : denomination we get different R0/R1 values from the exchange, and
232 : thus will generate a different coin private key as R0/R1 are hashed
233 : into the coin priv. So here, we fail to 'reuse' the key due to the
234 : cryptographic construction! */
235 2 : TALER_TESTING_cmd_deposit (
236 : "deposit-reused-coin-key-failure",
237 : "withdraw-coin-1x",
238 : 0,
239 : cred.user42_payto,
240 : "{\"items\":[{\"name\":\"conflicting ice cream\",\"value\":1}]}",
241 2 : GNUNET_TIME_UNIT_ZERO,
242 : "EUR:1",
243 : uses_cs
244 2 : ? MHD_HTTP_OK
245 : : MHD_HTTP_CONFLICT),
246 : /**
247 : * Try to double spend using different wire details.
248 : */
249 2 : TALER_TESTING_cmd_admin_add_kycauth (
250 : "kyc-auth-transfer-2",
251 : "EUR:0.01",
252 : &cred.ba,
253 : cred.user43_payto,
254 : "deposit-simple-fail-kyc"),
255 2 : CMD_EXEC_WIREWATCH (
256 : "import-kyc-account-1"),
257 2 : TALER_TESTING_cmd_deposit (
258 : "deposit-double-1",
259 : "withdraw-coin-1",
260 : 0,
261 : cred.user43_payto,
262 : "{\"items\":[{\"name\":\"ice cream\",\"value\":1}]}",
263 2 : GNUNET_TIME_UNIT_ZERO,
264 : "EUR:5",
265 : MHD_HTTP_CONFLICT),
266 : /* Try to double spend using a different transaction id.
267 : * The test needs the contract terms to differ. This
268 : * is currently the case because of the "timestamp" field,
269 : * which is set automatically by #TALER_TESTING_cmd_deposit().
270 : * This could theoretically fail if at some point a deposit
271 : * command executes in less than 1 ms. */
272 2 : TALER_TESTING_cmd_deposit (
273 : "deposit-double-1",
274 : "withdraw-coin-1",
275 : 0,
276 : cred.user43_payto,
277 : "{\"items\":[{\"name\":\"ice cream\",\"value\":1}]}",
278 2 : GNUNET_TIME_UNIT_ZERO,
279 : "EUR:5",
280 : MHD_HTTP_CONFLICT),
281 : /**
282 : * Try to double spend with different proposal.
283 : */
284 2 : TALER_TESTING_cmd_deposit (
285 : "deposit-double-2",
286 : "withdraw-coin-1",
287 : 0,
288 : cred.user43_payto,
289 : "{\"items\":[{\"name\":\"ice cream\",\"value\":2}]}",
290 2 : GNUNET_TIME_UNIT_ZERO,
291 : "EUR:5",
292 : MHD_HTTP_CONFLICT),
293 2 : TALER_TESTING_cmd_end ()
294 : };
295 :
296 : struct TALER_TESTING_Command refresh[] = {
297 : /**
298 : * Try to melt the coin that shared the private key with another
299 : * coin (should fail). Note that in the CS-case, we fail also
300 : * with MHD_HTTP_CONFLICT, but for a different reason: here it
301 : * is not a denomination conflict, but a double-spending conflict.
302 : */
303 2 : TALER_TESTING_cmd_melt (
304 : "refresh-melt-reused-coin-key-failure",
305 : "withdraw-coin-1x",
306 : MHD_HTTP_CONFLICT,
307 : NULL),
308 :
309 : /* Fill reserve with EUR:5, 1ct is for fees. */
310 2 : CMD_TRANSFER_TO_EXCHANGE (
311 : "refresh-create-reserve-1",
312 : "EUR:5.01"),
313 2 : TALER_TESTING_cmd_check_bank_admin_transfer (
314 : "ck-refresh-create-reserve-1",
315 : "EUR:5.01",
316 : cred.user42_payto,
317 : cred.exchange_payto,
318 : "refresh-create-reserve-1"),
319 : /**
320 : * Make previous command effective.
321 : */
322 2 : CMD_EXEC_WIREWATCH ("wirewatch-2"),
323 : /**
324 : * Withdraw EUR:5.
325 : */
326 2 : TALER_TESTING_cmd_withdraw_amount (
327 : "refresh-withdraw-coin-1",
328 : "refresh-create-reserve-1",
329 : "EUR:5",
330 : 0, /* age restriction off */
331 : MHD_HTTP_OK),
332 : /* Try to partially spend (deposit) 1 EUR of the 5 EUR coin
333 : * (in full) (merchant would receive EUR:0.99 due to 1 ct
334 : * deposit fee)
335 : */
336 2 : TALER_TESTING_cmd_deposit (
337 : "refresh-deposit-partial",
338 : "refresh-withdraw-coin-1",
339 : 0,
340 : cred.user42_payto,
341 : "{\"items\":[{\"name\":\"ice cream\",\"value\":\"EUR:1\"}]}",
342 2 : GNUNET_TIME_UNIT_ZERO,
343 : "EUR:1",
344 : MHD_HTTP_OK),
345 : /**
346 : * Melt the rest of the coin's value
347 : * (EUR:4.00 = 3x EUR:1.03 + 7x EUR:0.13) */
348 2 : TALER_TESTING_cmd_melt_double (
349 : "refresh-melt-1",
350 : "refresh-withdraw-coin-1",
351 : MHD_HTTP_OK,
352 : NULL),
353 : /**
354 : * Complete (successful) melt operation, and
355 : * withdraw the coins
356 : */
357 2 : TALER_TESTING_cmd_melt_reveal (
358 : "refresh-reveal-1",
359 : "refresh-melt-1",
360 : MHD_HTTP_OK),
361 : /**
362 : * Do it again to check idempotency
363 : */
364 2 : TALER_TESTING_cmd_melt_reveal (
365 : "refresh-reveal-1-idempotency",
366 : "refresh-melt-1",
367 : MHD_HTTP_OK),
368 : /**
369 : * Try to spend a refreshed EUR:1 coin
370 : */
371 2 : TALER_TESTING_cmd_deposit (
372 : "refresh-deposit-refreshed-1a",
373 : "refresh-reveal-1-idempotency",
374 : 0,
375 : cred.user42_payto,
376 : "{\"items\":[{\"name\":\"ice cream\",\"value\":3}]}",
377 2 : GNUNET_TIME_UNIT_ZERO,
378 : "EUR:1",
379 : MHD_HTTP_OK),
380 : /**
381 : * Try to spend a refreshed EUR:0.1 coin
382 : */
383 2 : TALER_TESTING_cmd_deposit (
384 : "refresh-deposit-refreshed-1b",
385 : "refresh-reveal-1",
386 : 3,
387 : cred.user43_payto,
388 : "{\"items\":[{\"name\":\"cheap ice cream\",\"value\":3}]}",
389 2 : GNUNET_TIME_UNIT_ZERO,
390 : "EUR:0.1",
391 : MHD_HTTP_OK),
392 : /* Test running a failing melt operation (same operation
393 : * again must fail) */
394 2 : TALER_TESTING_cmd_melt (
395 : "refresh-melt-failing",
396 : "refresh-withdraw-coin-1",
397 : MHD_HTTP_CONFLICT,
398 : NULL),
399 : /* Test running a failing melt operation (on a coin that
400 : was itself revealed and subsequently deposited) */
401 2 : TALER_TESTING_cmd_melt (
402 : "refresh-melt-failing-2",
403 : "refresh-reveal-1",
404 : MHD_HTTP_CONFLICT,
405 : NULL),
406 :
407 2 : TALER_TESTING_cmd_end ()
408 : };
409 :
410 : /**
411 : * Test withdrawal with age restriction. Success is expected, so it MUST be
412 : * called _after_ TALER_TESTING_cmd_exec_offline_sign_extensions is called,
413 : * i. e. age restriction is activated in the exchange!
414 : *
415 : * FIXME[oec]: create a test that tries to withdraw coins with age restriction but
416 : * (expectedly) fails because the exchange doesn't support age restriction
417 : * yet.
418 : */
419 : struct TALER_TESTING_Command withdraw_age[] = {
420 : /**
421 : * Move money to the exchange's bank account.
422 : */
423 2 : CMD_TRANSFER_TO_EXCHANGE (
424 : "create-reserve-age",
425 : "EUR:6.01"),
426 2 : TALER_TESTING_cmd_check_bank_admin_transfer (
427 : "check-create-reserve-age",
428 : "EUR:6.01",
429 : cred.user42_payto,
430 : cred.exchange_payto,
431 : "create-reserve-age"),
432 : /**
433 : * Make a reserve exist, according to the previous
434 : * transfer.
435 : */
436 2 : CMD_EXEC_WIREWATCH ("wirewatch-age"),
437 : /**
438 : * Withdraw EUR:5.
439 : */
440 2 : TALER_TESTING_cmd_withdraw_amount (
441 : "withdraw-coin-age-1",
442 : "create-reserve-age",
443 : "EUR:5",
444 : 13,
445 : MHD_HTTP_OK),
446 :
447 2 : TALER_TESTING_cmd_end ()
448 : };
449 :
450 : struct TALER_TESTING_Command spend_age[] = {
451 : /**
452 : * Spend the coin.
453 : */
454 2 : TALER_TESTING_cmd_deposit (
455 : "deposit-simple-age",
456 : "withdraw-coin-age-1",
457 : 0,
458 : cred.user42_payto,
459 : "{\"items\":[{\"name\":\"unique ice cream\",\"value\":1}]}",
460 2 : GNUNET_TIME_UNIT_ZERO,
461 : "EUR:4.99",
462 : MHD_HTTP_OK),
463 2 : TALER_TESTING_cmd_deposit_replay (
464 : "deposit-simple-replay-age",
465 : "deposit-simple-age",
466 : MHD_HTTP_OK),
467 2 : TALER_TESTING_cmd_deposit_replay (
468 : "deposit-simple-replay-age-1",
469 : "deposit-simple-age",
470 : MHD_HTTP_OK),
471 2 : TALER_TESTING_cmd_sleep (
472 : "sleep-before-age-deposit-replay",
473 : 1),
474 2 : TALER_TESTING_cmd_deposit_replay (
475 : "deposit-simple-replay-age-2",
476 : "deposit-simple-age",
477 : MHD_HTTP_OK),
478 2 : TALER_TESTING_cmd_end ()
479 : };
480 :
481 : struct TALER_TESTING_Command track[] = {
482 : /* Try resolving a deposit's WTID, as we never triggered
483 : * execution of transactions, the answer should be that
484 : * the exchange knows about the deposit, but has no WTID yet.
485 : */
486 2 : TALER_TESTING_cmd_deposits_get (
487 : "deposit-wtid-found",
488 : "deposit-simple",
489 : 0,
490 : MHD_HTTP_ACCEPTED,
491 : NULL),
492 : /* Try resolving a deposit's WTID for a failed deposit.
493 : * As the deposit failed, the answer should be that the
494 : * exchange does NOT know about the deposit.
495 : */
496 2 : TALER_TESTING_cmd_deposits_get (
497 : "deposit-wtid-failing",
498 : "deposit-double-2",
499 : 0,
500 : MHD_HTTP_NOT_FOUND,
501 : NULL),
502 : /* Try resolving an undefined (all zeros) WTID; this
503 : * should fail as obviously the exchange didn't use that
504 : * WTID value for any transaction.
505 : */
506 2 : TALER_TESTING_cmd_track_transfer_empty (
507 : "wire-deposit-failing",
508 : NULL,
509 : MHD_HTTP_NOT_FOUND),
510 : /* Run transfers. */
511 2 : CMD_EXEC_AGGREGATOR ("run-aggregator"),
512 : /**
513 : * Check all the transfers took place.
514 : */
515 2 : TALER_TESTING_cmd_check_bank_transfer (
516 : "check_bank_transfer-42-aggregate",
517 2 : cred.exchange_url,
518 : /* In case of CS, one transaction above succeeded that
519 : failed for RSA, hence we get a larger amount here */
520 2 : uses_cs ? "EUR:14.91" : "EUR:13.92",
521 : cred.exchange_payto,
522 : cred.user42_payto),
523 2 : TALER_TESTING_cmd_check_bank_transfer (
524 : "check_bank_transfer-43-aggregate",
525 2 : cred.exchange_url,
526 : "EUR:0.17",
527 : cred.exchange_payto,
528 : cred.user43_payto),
529 2 : TALER_TESTING_cmd_check_bank_empty ("check_bank_empty"),
530 2 : TALER_TESTING_cmd_deposits_get (
531 : "deposit-wtid-ok",
532 : "deposit-simple",
533 : 0,
534 : MHD_HTTP_OK,
535 : "check_bank_transfer-42-aggregate"),
536 2 : TALER_TESTING_cmd_track_transfer (
537 : "wire-deposit-success-bank",
538 : "check_bank_transfer-42-aggregate",
539 : MHD_HTTP_OK,
540 2 : uses_cs ? "EUR:14.91" : "EUR:13.92",
541 : "EUR:0.01"),
542 2 : TALER_TESTING_cmd_track_transfer (
543 : "wire-deposits-success-wtid",
544 : "check_bank_transfer-43-aggregate",
545 : MHD_HTTP_OK,
546 : "EUR:0.17",
547 : "EUR:0.01"),
548 2 : TALER_TESTING_cmd_end ()
549 : };
550 :
551 : /**
552 : * This block checks whether a wire deadline
553 : * very far in the future does NOT get aggregated now.
554 : */
555 : struct TALER_TESTING_Command unaggregation[] = {
556 2 : TALER_TESTING_cmd_check_bank_empty ("far-future-aggregation-a"),
557 2 : CMD_TRANSFER_TO_EXCHANGE (
558 : "create-reserve-unaggregated",
559 : "EUR:5.01"),
560 : /* "consume" reserve creation transfer. */
561 2 : TALER_TESTING_cmd_check_bank_admin_transfer (
562 : "check-create-reserve-unaggregated",
563 : "EUR:5.01",
564 : cred.user42_payto,
565 : cred.exchange_payto,
566 : "create-reserve-unaggregated"),
567 2 : CMD_EXEC_WIREWATCH ("wirewatch-unaggregated"),
568 2 : TALER_TESTING_cmd_withdraw_amount (
569 : "withdraw-coin-unaggregated",
570 : "create-reserve-unaggregated",
571 : "EUR:5",
572 : 0, /* age restriction off */
573 : MHD_HTTP_OK),
574 2 : TALER_TESTING_cmd_deposit (
575 : "deposit-unaggregated",
576 : "withdraw-coin-unaggregated",
577 : 0,
578 : cred.user43_payto,
579 : "{\"items\":[{\"name\":\"different ice cream\",\"value\":1}]}",
580 : GNUNET_TIME_relative_multiply (
581 : GNUNET_TIME_UNIT_YEARS,
582 : 3000),
583 : "EUR:5",
584 : MHD_HTTP_OK),
585 2 : CMD_EXEC_AGGREGATOR ("aggregation-attempt"),
586 :
587 2 : TALER_TESTING_cmd_check_bank_empty (
588 : "far-future-aggregation-b"),
589 :
590 2 : TALER_TESTING_cmd_end ()
591 : };
592 :
593 : struct TALER_TESTING_Command refresh_age[] = {
594 : /* Fill reserve with EUR:5, 1ct is for fees. */
595 2 : CMD_TRANSFER_TO_EXCHANGE (
596 : "refresh-create-reserve-age-1",
597 : "EUR:6.01"),
598 2 : TALER_TESTING_cmd_check_bank_admin_transfer (
599 : "ck-refresh-create-reserve-age-1",
600 : "EUR:6.01",
601 : cred.user42_payto,
602 : cred.exchange_payto,
603 : "refresh-create-reserve-age-1"),
604 : /**
605 : * Make previous command effective.
606 : */
607 2 : CMD_EXEC_WIREWATCH ("wirewatch-age-2"),
608 : /**
609 : * Withdraw EUR:7 with age restriction for age 13.
610 : */
611 2 : TALER_TESTING_cmd_withdraw_amount (
612 : "refresh-withdraw-coin-age-1",
613 : "refresh-create-reserve-age-1",
614 : "EUR:5",
615 : 13,
616 : MHD_HTTP_OK),
617 : /* Try to partially spend (deposit) 1 EUR of the 5 EUR coin
618 : * (in full) (merchant would receive EUR:0.99 due to 1 ct
619 : * deposit fee)
620 : */
621 2 : TALER_TESTING_cmd_deposit (
622 : "refresh-deposit-partial-age",
623 : "refresh-withdraw-coin-age-1",
624 : 0,
625 : cred.user42_payto,
626 : "{\"items\":[{\"name\":\"special ice cream\",\"value\":\"EUR:1\"}]}",
627 2 : GNUNET_TIME_UNIT_ZERO,
628 : "EUR:1",
629 : MHD_HTTP_OK),
630 : /**
631 : * Melt the rest of the coin's value
632 : * (EUR:4.00 = 3x EUR:1.03 + 7x EUR:0.13) */
633 2 : TALER_TESTING_cmd_melt_double (
634 : "refresh-melt-age-1",
635 : "refresh-withdraw-coin-age-1",
636 : MHD_HTTP_OK,
637 : NULL),
638 : /**
639 : * Complete (successful) melt operation, and
640 : * withdraw the coins
641 : */
642 2 : TALER_TESTING_cmd_melt_reveal (
643 : "refresh-reveal-age-1",
644 : "refresh-melt-age-1",
645 : MHD_HTTP_OK),
646 : /**
647 : * Do it again to check idempotency
648 : */
649 2 : TALER_TESTING_cmd_melt_reveal (
650 : "refresh-reveal-age-1-idempotency",
651 : "refresh-melt-age-1",
652 : MHD_HTTP_OK),
653 : /**
654 : * Try to spend a refreshed EUR:1 coin
655 : */
656 2 : TALER_TESTING_cmd_deposit (
657 : "refresh-deposit-refreshed-age-1a",
658 : "refresh-reveal-age-1-idempotency",
659 : 0,
660 : cred.user42_payto,
661 : "{\"items\":[{\"name\":\"garlic ice cream\",\"value\":3}]}",
662 2 : GNUNET_TIME_UNIT_ZERO,
663 : "EUR:1",
664 : MHD_HTTP_OK),
665 : /**
666 : * Try to spend a refreshed EUR:0.1 coin
667 : */
668 2 : TALER_TESTING_cmd_deposit (
669 : "refresh-deposit-refreshed-age-1b",
670 : "refresh-reveal-age-1",
671 : 3,
672 : cred.user43_payto,
673 : "{\"items\":[{\"name\":\"spicy ice cream\",\"value\":3}]}",
674 2 : GNUNET_TIME_UNIT_ZERO,
675 : "EUR:0.1",
676 : MHD_HTTP_OK),
677 : /* Test running a failing melt operation (same operation
678 : * again must fail) */
679 2 : TALER_TESTING_cmd_melt (
680 : "refresh-melt-failing-age",
681 : "refresh-withdraw-coin-age-1",
682 : MHD_HTTP_CONFLICT,
683 : NULL),
684 : /* Test running a failing melt operation (on a coin that
685 : was itself revealed and subsequently deposited) */
686 2 : TALER_TESTING_cmd_melt (
687 : "refresh-melt-failing-age-2",
688 : "refresh-reveal-age-1",
689 : MHD_HTTP_CONFLICT,
690 : NULL),
691 2 : TALER_TESTING_cmd_end ()
692 : };
693 :
694 : /**
695 : * This block exercises the aggretation logic by making two payments
696 : * to the same merchant.
697 : */
698 : struct TALER_TESTING_Command aggregation[] = {
699 2 : CMD_TRANSFER_TO_EXCHANGE ("create-reserve-aggtest",
700 : "EUR:5.01"),
701 : /* "consume" reserve creation transfer. */
702 2 : TALER_TESTING_cmd_check_bank_admin_transfer (
703 : "check-create-reserve-aggtest",
704 : "EUR:5.01",
705 : cred.user42_payto,
706 : cred.exchange_payto,
707 : "create-reserve-aggtest"),
708 2 : CMD_EXEC_WIREWATCH ("wirewatch-aggtest"),
709 2 : TALER_TESTING_cmd_withdraw_amount (
710 : "withdraw-coin-aggtest",
711 : "create-reserve-aggtest",
712 : "EUR:5",
713 : 0, /* age restriction off */
714 : MHD_HTTP_OK),
715 2 : TALER_TESTING_cmd_deposit (
716 : "deposit-aggtest-1",
717 : "withdraw-coin-aggtest",
718 : 0,
719 : cred.user43_payto,
720 : "{\"items\":[{\"name\":\"cinamon ice cream\",\"value\":1}]}",
721 2 : GNUNET_TIME_UNIT_ZERO,
722 : "EUR:2",
723 : MHD_HTTP_OK),
724 2 : TALER_TESTING_cmd_deposit_with_ref (
725 : "deposit-aggtest-2",
726 : "withdraw-coin-aggtest",
727 : 0,
728 : cred.user43_payto,
729 : "{\"items\":[{\"name\":\"foo bar\",\"value\":1}]}",
730 2 : GNUNET_TIME_UNIT_ZERO,
731 : "EUR:2",
732 : MHD_HTTP_OK,
733 : "deposit-aggtest-1"),
734 2 : CMD_EXEC_AGGREGATOR ("aggregation-aggtest"),
735 2 : TALER_TESTING_cmd_check_bank_transfer (
736 : "check-bank-transfer-aggtest",
737 2 : cred.exchange_url,
738 : "EUR:3.97",
739 : cred.exchange_payto,
740 : cred.user43_payto),
741 2 : TALER_TESTING_cmd_check_bank_empty ("check-bank-empty-aggtest"),
742 2 : TALER_TESTING_cmd_end ()
743 : };
744 :
745 : struct TALER_TESTING_Command refund[] = {
746 : /**
747 : * Fill reserve with EUR:5.01, as withdraw fee is 1 ct per
748 : * config.
749 : */
750 2 : CMD_TRANSFER_TO_EXCHANGE (
751 : "create-reserve-r1",
752 : "EUR:5.01"),
753 2 : TALER_TESTING_cmd_check_bank_admin_transfer (
754 : "check-create-reserve-r1",
755 : "EUR:5.01",
756 : cred.user42_payto,
757 : cred.exchange_payto,
758 : "create-reserve-r1"),
759 : /**
760 : * Run wire-watch to trigger the reserve creation.
761 : */
762 2 : CMD_EXEC_WIREWATCH ("wirewatch-3"),
763 : /* Withdraw a 5 EUR coin, at fee of 1 ct */
764 2 : TALER_TESTING_cmd_withdraw_amount (
765 : "withdraw-coin-r1",
766 : "create-reserve-r1",
767 : "EUR:5",
768 : 0, /* age restriction off */
769 : MHD_HTTP_OK),
770 : /**
771 : * Spend 5 EUR of the 5 EUR coin (in full) (merchant would
772 : * receive EUR:4.99 due to 1 ct deposit fee)
773 : */
774 2 : TALER_TESTING_cmd_deposit (
775 : "deposit-refund-1",
776 : "withdraw-coin-r1",
777 : 0,
778 : cred.user42_payto,
779 : "{\"items\":[{\"name\":\"blue ice cream\",\"value\":\"EUR:5\"}]}",
780 : GNUNET_TIME_UNIT_MINUTES,
781 : "EUR:5",
782 : MHD_HTTP_OK),
783 : /**
784 : * Run transfers. Should do nothing as refund deadline blocks it
785 : */
786 2 : CMD_EXEC_AGGREGATOR ("run-aggregator-refund"),
787 : /* Check that aggregator didn't do anything, as expected.
788 : * Note, this operation takes two commands: one to "flush"
789 : * the preliminary transfer (used to withdraw) from the
790 : * fakebank and the second to actually check there are not
791 : * other transfers around. */
792 2 : TALER_TESTING_cmd_check_bank_empty ("check_bank_transfer-pre-refund"),
793 2 : TALER_TESTING_cmd_refund_with_id (
794 : "refund-ok",
795 : MHD_HTTP_OK,
796 : "EUR:3",
797 : "deposit-refund-1",
798 : 3),
799 2 : TALER_TESTING_cmd_refund_with_id (
800 : "refund-ok-double",
801 : MHD_HTTP_OK,
802 : "EUR:3",
803 : "deposit-refund-1",
804 : 3),
805 : /* Previous /refund(s) had id == 0. */
806 2 : TALER_TESTING_cmd_refund_with_id (
807 : "refund-conflicting",
808 : MHD_HTTP_CONFLICT,
809 : "EUR:5",
810 : "deposit-refund-1",
811 : 1),
812 2 : TALER_TESTING_cmd_deposit (
813 : "deposit-refund-insufficient-refund",
814 : "withdraw-coin-r1",
815 : 0,
816 : cred.user42_payto,
817 : "{\"items\":[{\"name\":\"fruit ice cream\",\"value\":\"EUR:4\"}]}",
818 : GNUNET_TIME_UNIT_MINUTES,
819 : "EUR:4",
820 : MHD_HTTP_CONFLICT),
821 2 : TALER_TESTING_cmd_refund_with_id (
822 : "refund-ok-increase",
823 : MHD_HTTP_OK,
824 : "EUR:2",
825 : "deposit-refund-1",
826 : 2),
827 : /**
828 : * Spend 4.99 EUR of the refunded 4.99 EUR coin (1ct gone
829 : * due to refund) (merchant would receive EUR:4.98 due to
830 : * 1 ct deposit fee) */
831 2 : TALER_TESTING_cmd_deposit (
832 : "deposit-refund-2",
833 : "withdraw-coin-r1",
834 : 0,
835 : cred.user42_payto,
836 : "{\"items\":[{\"name\":\"more ice cream\",\"value\":\"EUR:5\"}]}",
837 2 : GNUNET_TIME_UNIT_ZERO,
838 : "EUR:4.99",
839 : MHD_HTTP_OK),
840 : /**
841 : * Run transfers. This will do the transfer as refund deadline
842 : * was 0
843 : */
844 2 : CMD_EXEC_AGGREGATOR ("run-aggregator-3"),
845 : /**
846 : * Check that deposit did run.
847 : */
848 2 : TALER_TESTING_cmd_check_bank_transfer (
849 : "check_bank_transfer-pre-refund",
850 2 : cred.exchange_url,
851 : "EUR:4.97",
852 : cred.exchange_payto,
853 : cred.user42_payto),
854 : /**
855 : * Run failing refund, as past deadline & aggregation.
856 : */
857 2 : TALER_TESTING_cmd_refund (
858 : "refund-fail",
859 : MHD_HTTP_GONE,
860 : "EUR:4.99",
861 : "deposit-refund-2"),
862 2 : TALER_TESTING_cmd_check_bank_empty ("check-empty-after-refund"),
863 : /**
864 : * Test refunded coins are never executed, even past
865 : * refund deadline
866 : */
867 2 : CMD_TRANSFER_TO_EXCHANGE (
868 : "create-reserve-rb",
869 : "EUR:5.01"),
870 2 : TALER_TESTING_cmd_check_bank_admin_transfer (
871 : "check-create-reserve-rb",
872 : "EUR:5.01",
873 : cred.user42_payto,
874 : cred.exchange_payto,
875 : "create-reserve-rb"),
876 2 : CMD_EXEC_WIREWATCH ("wirewatch-rb"),
877 2 : TALER_TESTING_cmd_withdraw_amount (
878 : "withdraw-coin-rb",
879 : "create-reserve-rb",
880 : "EUR:5",
881 : 0, /* age restriction off */
882 : MHD_HTTP_OK),
883 2 : TALER_TESTING_cmd_deposit (
884 : "deposit-refund-1b",
885 : "withdraw-coin-rb",
886 : 0,
887 : cred.user42_payto,
888 : "{\"items\":[{\"name\":\"purple ice cream\",\"value\":\"EUR:5\"}]}",
889 2 : GNUNET_TIME_UNIT_ZERO,
890 : "EUR:5",
891 : MHD_HTTP_OK),
892 : /**
893 : * Trigger refund (before aggregator had a chance to execute
894 : * deposit, even though refund deadline was zero).
895 : */
896 2 : TALER_TESTING_cmd_refund (
897 : "refund-ok-fast",
898 : MHD_HTTP_OK,
899 : "EUR:5",
900 : "deposit-refund-1b"),
901 : /**
902 : * Run transfers. This will do the transfer as refund deadline
903 : * was 0, except of course because the refund succeeded, the
904 : * transfer should no longer be done.
905 : */
906 2 : CMD_EXEC_AGGREGATOR ("run-aggregator-3b"),
907 : /* check that aggregator didn't do anything, as expected */
908 2 : TALER_TESTING_cmd_check_bank_empty ("check-refund-fast-not-run"),
909 2 : TALER_TESTING_cmd_end ()
910 : };
911 :
912 : #if FIXME_9828
913 : struct TALER_TESTING_Command recoup[] = {
914 : /**
915 : * Fill reserve with EUR:5.01, as withdraw fee is 1 ct per
916 : * config.
917 : */
918 : CMD_TRANSFER_TO_EXCHANGE (
919 : "recoup-create-reserve-1",
920 : "EUR:15.02"),
921 : TALER_TESTING_cmd_check_bank_admin_transfer (
922 : "recoup-create-reserve-1-check",
923 : "EUR:15.02",
924 : cred.user42_payto,
925 : cred.exchange_payto,
926 : "recoup-create-reserve-1"),
927 : /**
928 : * Run wire-watch to trigger the reserve creation.
929 : */
930 : CMD_EXEC_WIREWATCH ("wirewatch-4"),
931 : /* Withdraw a 5 EUR coin, at fee of 1 ct */
932 : TALER_TESTING_cmd_withdraw_amount (
933 : "recoup-withdraw-coin-1",
934 : "recoup-create-reserve-1",
935 : "EUR:5",
936 : 0, /* age restriction off */
937 : MHD_HTTP_OK),
938 : /* Withdraw a 10 EUR coin, at fee of 1 ct */
939 : TALER_TESTING_cmd_withdraw_amount (
940 : "recoup-withdraw-coin-1b",
941 : "recoup-create-reserve-1",
942 : "EUR:10",
943 : 0, /* age restriction off */
944 : MHD_HTTP_OK),
945 : /* melt 10 EUR coin to get 5 EUR refreshed coin */
946 : TALER_TESTING_cmd_melt (
947 : "recoup-melt-coin-1b",
948 : "recoup-withdraw-coin-1b",
949 : MHD_HTTP_OK,
950 : "EUR:5",
951 : NULL),
952 : TALER_TESTING_cmd_melt_reveal (
953 : "recoup-reveal-coin-1b",
954 : "recoup-melt-coin-1b",
955 : MHD_HTTP_OK),
956 : /* Revoke both 5 EUR coins */
957 : TALER_TESTING_cmd_revoke (
958 : "revoke-0-EUR:5",
959 : MHD_HTTP_OK,
960 : "recoup-withdraw-coin-1",
961 : config_file),
962 : /* Recoup coin to reserve */
963 : TALER_TESTING_cmd_recoup (
964 : "recoup-1",
965 : MHD_HTTP_OK,
966 : "recoup-withdraw-coin-1",
967 : "EUR:5"),
968 : /* Check the money is back with the reserve */
969 : TALER_TESTING_cmd_status (
970 : "recoup-reserve-status-1",
971 : "recoup-create-reserve-1",
972 : "EUR:5.0",
973 : MHD_HTTP_OK),
974 : /* Recoup-refresh coin to 10 EUR coin */
975 : TALER_TESTING_cmd_recoup_refresh (
976 : "recoup-1b",
977 : MHD_HTTP_OK,
978 : "recoup-reveal-coin-1b",
979 : "recoup-melt-coin-1b",
980 : "EUR:5"),
981 : /* melt 10 EUR coin *again* to get 1 EUR refreshed coin */
982 : TALER_TESTING_cmd_melt (
983 : "recoup-remelt-coin-1a",
984 : "recoup-withdraw-coin-1b",
985 : MHD_HTTP_OK,
986 : "EUR:1",
987 : NULL),
988 : TALER_TESTING_cmd_melt_reveal (
989 : "recoup-reveal-coin-1a",
990 : "recoup-remelt-coin-1a",
991 : MHD_HTTP_OK),
992 : /* Try melting for more than the residual value to provoke an error */
993 : TALER_TESTING_cmd_melt (
994 : "recoup-remelt-coin-1b",
995 : "recoup-withdraw-coin-1b",
996 : MHD_HTTP_OK,
997 : "EUR:1",
998 : NULL),
999 : TALER_TESTING_cmd_melt (
1000 : "recoup-remelt-coin-1c",
1001 : "recoup-withdraw-coin-1b",
1002 : MHD_HTTP_OK,
1003 : "EUR:1",
1004 : NULL),
1005 : TALER_TESTING_cmd_melt (
1006 : "recoup-remelt-coin-1d",
1007 : "recoup-withdraw-coin-1b",
1008 : MHD_HTTP_OK,
1009 : "EUR:1",
1010 : NULL),
1011 : TALER_TESTING_cmd_melt (
1012 : "recoup-remelt-coin-1e",
1013 : "recoup-withdraw-coin-1b",
1014 : MHD_HTTP_OK,
1015 : "EUR:1",
1016 : NULL),
1017 : TALER_TESTING_cmd_melt (
1018 : "recoup-remelt-coin-1f",
1019 : "recoup-withdraw-coin-1b",
1020 : MHD_HTTP_OK,
1021 : "EUR:1",
1022 : NULL),
1023 : TALER_TESTING_cmd_melt (
1024 : "recoup-remelt-coin-1g",
1025 : "recoup-withdraw-coin-1b",
1026 : MHD_HTTP_OK,
1027 : "EUR:1",
1028 : NULL),
1029 : TALER_TESTING_cmd_melt (
1030 : "recoup-remelt-coin-1h",
1031 : "recoup-withdraw-coin-1b",
1032 : MHD_HTTP_OK,
1033 : "EUR:1",
1034 : NULL),
1035 : TALER_TESTING_cmd_melt (
1036 : "recoup-remelt-coin-1i",
1037 : "recoup-withdraw-coin-1b",
1038 : MHD_HTTP_OK,
1039 : "EUR:1",
1040 : NULL),
1041 : TALER_TESTING_cmd_melt (
1042 : "recoup-remelt-coin-1b-failing",
1043 : "recoup-withdraw-coin-1b",
1044 : MHD_HTTP_CONFLICT,
1045 : "EUR:1",
1046 : NULL),
1047 : /* Re-withdraw from this reserve */
1048 : TALER_TESTING_cmd_withdraw_amount (
1049 : "recoup-withdraw-coin-2",
1050 : "recoup-create-reserve-1",
1051 : "EUR:1",
1052 : 0, /* age restriction off */
1053 : MHD_HTTP_OK),
1054 : /**
1055 : * This withdrawal will test the logic to create a "recoup"
1056 : * element to insert into the reserve's history.
1057 : */
1058 : TALER_TESTING_cmd_withdraw_amount (
1059 : "recoup-withdraw-coin-2-over",
1060 : "recoup-create-reserve-1",
1061 : "EUR:10",
1062 : 0, /* age restriction off */
1063 : MHD_HTTP_CONFLICT),
1064 : TALER_TESTING_cmd_status (
1065 : "recoup-reserve-status-2",
1066 : "recoup-create-reserve-1",
1067 : "EUR:3.99",
1068 : MHD_HTTP_OK),
1069 : /* These commands should close the reserve because
1070 : * the aggregator is given a config file that overrides
1071 : * the reserve expiration time (making it now-ish) */
1072 : CMD_TRANSFER_TO_EXCHANGE ("short-lived-reserve",
1073 : "EUR:5.01"),
1074 : TALER_TESTING_cmd_check_bank_admin_transfer (
1075 : "check-short-lived-reserve",
1076 : "EUR:5.01",
1077 : cred.user42_payto,
1078 : cred.exchange_payto,
1079 : "short-lived-reserve"),
1080 : TALER_TESTING_cmd_exec_wirewatch2 (
1081 : "short-lived-aggregation",
1082 : config_file_expire_reserve_now,
1083 : "exchange-account-2"),
1084 : TALER_TESTING_cmd_exec_closer (
1085 : "close-reserves",
1086 : config_file_expire_reserve_now,
1087 : "EUR:5",
1088 : "EUR:0.01",
1089 : "short-lived-reserve"),
1090 : TALER_TESTING_cmd_exec_transfer (
1091 : "close-reserves-transfer",
1092 : config_file_expire_reserve_now),
1093 :
1094 : TALER_TESTING_cmd_status (
1095 : "short-lived-status",
1096 : "short-lived-reserve",
1097 : "EUR:0",
1098 : MHD_HTTP_OK),
1099 : TALER_TESTING_cmd_withdraw_amount (
1100 : "expired-withdraw",
1101 : "short-lived-reserve",
1102 : "EUR:1",
1103 : 0, /* age restriction off */
1104 : MHD_HTTP_CONFLICT),
1105 : TALER_TESTING_cmd_check_bank_transfer (
1106 : "check_bank_short-lived_reimburse",
1107 : cred.exchange_url,
1108 : "EUR:5",
1109 : cred.exchange_payto,
1110 : cred.user42_payto),
1111 : /* Fill reserve with EUR:2.02, as withdraw fee is 1 ct per
1112 : * config, then withdraw two coin, partially spend one, and
1113 : * then have the rest paid back. Check deposit of other coin
1114 : * fails. Do not use EUR:5 here as the EUR:5 coin was
1115 : * revoked and we did not bother to create a new one... */
1116 : CMD_TRANSFER_TO_EXCHANGE ("recoup-create-reserve-2",
1117 : "EUR:2.02"),
1118 : TALER_TESTING_cmd_check_bank_admin_transfer (
1119 : "ck-recoup-create-reserve-2",
1120 : "EUR:2.02",
1121 : cred.user42_payto,
1122 : cred.exchange_payto,
1123 : "recoup-create-reserve-2"),
1124 : /* Make previous command effective. */
1125 : CMD_EXEC_WIREWATCH ("wirewatch-5"),
1126 : /* Withdraw a 1 EUR coin, at fee of 1 ct */
1127 : TALER_TESTING_cmd_withdraw_amount (
1128 : "recoup-withdraw-coin-2a",
1129 : "recoup-create-reserve-2",
1130 : "EUR:1",
1131 : 0, /* age restriction off */
1132 : MHD_HTTP_OK),
1133 : /* Withdraw a 1 EUR coin, at fee of 1 ct */
1134 : TALER_TESTING_cmd_withdraw_amount (
1135 : "recoup-withdraw-coin-2b",
1136 : "recoup-create-reserve-2",
1137 : "EUR:1",
1138 : 0, /* age restriction off */
1139 : MHD_HTTP_OK),
1140 : TALER_TESTING_cmd_deposit (
1141 : "recoup-deposit-partial",
1142 : "recoup-withdraw-coin-2a",
1143 : 0,
1144 : cred.user42_payto,
1145 : "{\"items\":[{\"name\":\"more ice cream\",\"value\":1}]}",
1146 : GNUNET_TIME_UNIT_ZERO,
1147 : "EUR:0.5",
1148 : MHD_HTTP_OK),
1149 : TALER_TESTING_cmd_revoke (
1150 : "revoke-1-EUR:1",
1151 : MHD_HTTP_OK,
1152 : "recoup-withdraw-coin-2a",
1153 : config_file),
1154 : /* Check recoup is failing for the coin with the reused coin key
1155 : (fails either because of denomination conflict (RSA) or
1156 : double-spending (CS))*/
1157 : TALER_TESTING_cmd_recoup (
1158 : "recoup-2x",
1159 : MHD_HTTP_CONFLICT,
1160 : "withdraw-coin-1x",
1161 : "EUR:1"),
1162 : TALER_TESTING_cmd_recoup (
1163 : "recoup-2",
1164 : MHD_HTTP_OK,
1165 : "recoup-withdraw-coin-2a",
1166 : "EUR:0.5"),
1167 : /* Idempotency of recoup (withdrawal variant) */
1168 : TALER_TESTING_cmd_recoup (
1169 : "recoup-2b",
1170 : MHD_HTTP_OK,
1171 : "recoup-withdraw-coin-2a",
1172 : "EUR:0.5"),
1173 : TALER_TESTING_cmd_deposit (
1174 : "recoup-deposit-revoked",
1175 : "recoup-withdraw-coin-2b",
1176 : 0,
1177 : cred.user42_payto,
1178 : "{\"items\":[{\"name\":\"gnu ice cream\",\"value\":1}]}",
1179 : GNUNET_TIME_UNIT_ZERO,
1180 : "EUR:1",
1181 : MHD_HTTP_GONE),
1182 : /* Test deposit fails after recoup, with proof in recoup */
1183 :
1184 : /* Note that, the exchange will never return the coin's transaction
1185 : * history with recoup data, as we get a 410 on the DK! */
1186 : TALER_TESTING_cmd_deposit (
1187 : "recoup-deposit-partial-after-recoup",
1188 : "recoup-withdraw-coin-2a",
1189 : 0,
1190 : cred.user42_payto,
1191 : "{\"items\":[{\"name\":\"extra ice cream\",\"value\":1}]}",
1192 : GNUNET_TIME_UNIT_ZERO,
1193 : "EUR:0.5",
1194 : MHD_HTTP_GONE),
1195 : /* Test that revoked coins cannot be withdrawn */
1196 : CMD_TRANSFER_TO_EXCHANGE (
1197 : "recoup-create-reserve-3",
1198 : "EUR:1.01"),
1199 : TALER_TESTING_cmd_check_bank_admin_transfer (
1200 : "check-recoup-create-reserve-3",
1201 : "EUR:1.01",
1202 : cred.user42_payto,
1203 : cred.exchange_payto,
1204 : "recoup-create-reserve-3"),
1205 : CMD_EXEC_WIREWATCH ("wirewatch-6"),
1206 : TALER_TESTING_cmd_withdraw_amount (
1207 : "recoup-withdraw-coin-3-revoked",
1208 : "recoup-create-reserve-3",
1209 : "EUR:1",
1210 : 0, /* age restriction off */
1211 : MHD_HTTP_GONE),
1212 : /* check that we are empty before the rejection test */
1213 : TALER_TESTING_cmd_check_bank_empty ("check-empty-again"),
1214 :
1215 : TALER_TESTING_cmd_end ()
1216 : };
1217 : #endif
1218 :
1219 : /**
1220 : * Test batch withdrawal plus spending.
1221 : */
1222 : struct TALER_TESTING_Command batch_withdraw[] = {
1223 : /**
1224 : * Move money to the exchange's bank account.
1225 : */
1226 2 : CMD_TRANSFER_TO_EXCHANGE (
1227 : "create-batch-reserve-1",
1228 : "EUR:6.03"),
1229 2 : TALER_TESTING_cmd_reserve_poll (
1230 : "poll-batch-reserve-1",
1231 : "create-batch-reserve-1",
1232 : "EUR:6.03",
1233 : GNUNET_TIME_UNIT_MINUTES,
1234 : MHD_HTTP_OK),
1235 2 : TALER_TESTING_cmd_check_bank_admin_transfer (
1236 : "check-create-batch-reserve-1",
1237 : "EUR:6.03",
1238 : cred.user42_payto,
1239 : cred.exchange_payto,
1240 : "create-batch-reserve-1"),
1241 : /*
1242 : * Make a reserve exist, according to the previous
1243 : * transfer.
1244 : */
1245 2 : CMD_EXEC_WIREWATCH ("wirewatch-batch-1"),
1246 2 : TALER_TESTING_cmd_reserve_poll_finish (
1247 : "finish-poll-batch-reserve-1",
1248 : GNUNET_TIME_UNIT_SECONDS,
1249 : "poll-batch-reserve-1"),
1250 : /**
1251 : * Withdraw EUR:5 AND EUR:1.
1252 : */
1253 2 : TALER_TESTING_cmd_batch_withdraw (
1254 : "batch-withdraw-coin-1",
1255 : "create-batch-reserve-1",
1256 : MHD_HTTP_OK,
1257 : "EUR:5",
1258 : "EUR:1",
1259 : NULL),
1260 : /**
1261 : * Check the reserve is (almost) depleted.
1262 : */
1263 2 : TALER_TESTING_cmd_status (
1264 : "status-batch-1",
1265 : "create-batch-reserve-1",
1266 : "EUR:0.01",
1267 : MHD_HTTP_OK),
1268 2 : TALER_TESTING_cmd_reserve_history (
1269 : "history-batch-1",
1270 : "create-batch-reserve-1",
1271 : "EUR:0.01",
1272 : MHD_HTTP_OK),
1273 : /**
1274 : * Spend the coins.
1275 : */
1276 2 : TALER_TESTING_cmd_batch_deposit (
1277 : "batch-deposit-1",
1278 : cred.user42_payto,
1279 : "{\"items\":[{\"name\":\"final ice cream\",\"value\":5}]}",
1280 2 : GNUNET_TIME_UNIT_ZERO,
1281 : MHD_HTTP_OK,
1282 : "batch-withdraw-coin-1#0",
1283 : "EUR:5",
1284 : "batch-withdraw-coin-1#1",
1285 : "EUR:1",
1286 : NULL),
1287 2 : TALER_TESTING_cmd_coin_history (
1288 : "coin-history-batch-1",
1289 : "batch-withdraw-coin-1#0",
1290 : "EUR:0.0",
1291 : MHD_HTTP_OK),
1292 2 : TALER_TESTING_cmd_end ()
1293 : };
1294 :
1295 :
1296 : #define RESERVE_OPEN_CLOSE_CHUNK 4
1297 : #define RESERVE_OPEN_CLOSE_ITERATIONS 3
1298 :
1299 : struct TALER_TESTING_Command reserve_open_close[(RESERVE_OPEN_CLOSE_ITERATIONS
1300 : * RESERVE_OPEN_CLOSE_CHUNK)
1301 : + 1];
1302 :
1303 : (void) cls;
1304 2 : for (unsigned int i = 0;
1305 8 : i < RESERVE_OPEN_CLOSE_ITERATIONS;
1306 6 : i++)
1307 : {
1308 6 : reserve_open_close[(i * RESERVE_OPEN_CLOSE_CHUNK) + 0]
1309 6 : = CMD_TRANSFER_TO_EXCHANGE ("reserve-open-close-key",
1310 : "EUR:20");
1311 6 : reserve_open_close[(i * RESERVE_OPEN_CLOSE_CHUNK) + 1]
1312 6 : = TALER_TESTING_cmd_exec_wirewatch2 ("reserve-open-close-wirewatch",
1313 : config_file_expire_reserve_now,
1314 : "exchange-account-2");
1315 6 : reserve_open_close[(i * RESERVE_OPEN_CLOSE_CHUNK) + 2]
1316 6 : = TALER_TESTING_cmd_exec_closer ("reserve-open-close-aggregation",
1317 : config_file_expire_reserve_now,
1318 : "EUR:19.99",
1319 : "EUR:0.01",
1320 : "reserve-open-close-key");
1321 6 : reserve_open_close[(i * RESERVE_OPEN_CLOSE_CHUNK) + 3]
1322 6 : = TALER_TESTING_cmd_status ("reserve-open-close-status",
1323 : "reserve-open-close-key",
1324 : "EUR:0",
1325 : MHD_HTTP_OK);
1326 : }
1327 : reserve_open_close[RESERVE_OPEN_CLOSE_ITERATIONS * RESERVE_OPEN_CLOSE_CHUNK]
1328 2 : = TALER_TESTING_cmd_end ();
1329 :
1330 : {
1331 : struct TALER_TESTING_Command commands[] = {
1332 2 : TALER_TESTING_cmd_run_fakebank ("run-fakebank",
1333 2 : cred.cfg,
1334 : "exchange-account-2"),
1335 2 : TALER_TESTING_cmd_system_start ("start-taler",
1336 : config_file,
1337 : "-e",
1338 : NULL),
1339 2 : TALER_TESTING_cmd_get_exchange ("get-exchange",
1340 2 : cred.cfg,
1341 : NULL,
1342 : true,
1343 : true),
1344 2 : TALER_TESTING_cmd_batch ("withdraw",
1345 : withdraw),
1346 2 : TALER_TESTING_cmd_batch ("spend",
1347 : spend),
1348 2 : TALER_TESTING_cmd_batch ("refresh",
1349 : refresh),
1350 2 : TALER_TESTING_cmd_batch ("withdraw-age",
1351 : withdraw_age),
1352 2 : TALER_TESTING_cmd_batch ("spend-age",
1353 : spend_age),
1354 2 : TALER_TESTING_cmd_batch ("refresh-age",
1355 : refresh_age),
1356 2 : TALER_TESTING_cmd_batch ("track",
1357 : track),
1358 2 : TALER_TESTING_cmd_batch ("unaggregation",
1359 : unaggregation),
1360 2 : TALER_TESTING_cmd_batch ("aggregation",
1361 : aggregation),
1362 2 : TALER_TESTING_cmd_batch ("refund",
1363 : refund),
1364 2 : TALER_TESTING_cmd_batch ("batch-withdraw",
1365 : batch_withdraw),
1366 : #if FIXME_9828
1367 : TALER_TESTING_cmd_batch ("recoup",
1368 : recoup),
1369 : #endif
1370 2 : TALER_TESTING_cmd_batch ("reserve-open-close",
1371 : reserve_open_close),
1372 : /* End the suite. */
1373 2 : TALER_TESTING_cmd_end ()
1374 : };
1375 :
1376 2 : TALER_TESTING_run (is,
1377 : commands);
1378 : }
1379 2 : }
1380 :
1381 :
1382 : int
1383 2 : main (int argc,
1384 : char *const *argv)
1385 : {
1386 : (void) argc;
1387 : {
1388 : char *cipher;
1389 :
1390 2 : cipher = GNUNET_STRINGS_get_suffix_from_binary_name (argv[0]);
1391 2 : GNUNET_assert (NULL != cipher);
1392 2 : uses_cs = (0 == strcmp (cipher,
1393 2 : "cs"));
1394 2 : GNUNET_asprintf (&config_file,
1395 : "test_exchange_api-%s.conf",
1396 : cipher);
1397 2 : GNUNET_asprintf (&config_file_expire_reserve_now,
1398 : "test_exchange_api_expire_reserve_now-%s.conf",
1399 : cipher);
1400 2 : GNUNET_free (cipher);
1401 : }
1402 2 : return TALER_TESTING_main (argv,
1403 : "INFO",
1404 : config_file,
1405 : "exchange-account-2",
1406 : TALER_TESTING_BS_FAKEBANK,
1407 : &cred,
1408 : &run,
1409 : NULL);
1410 : }
1411 :
1412 :
1413 : /* end of test_exchange_api.c */
|