fakebank.h (12129B)
1 /* 2 This file is part of TALER 3 (C) 2016-2023 Taler Systems SA 4 5 TALER is free software; you can redistribute it and/or 6 modify it under the terms of the GNU General Public License 7 as published by the Free Software Foundation; either version 3, 8 or (at your option) any later version. 9 10 TALER is distributed in the hope that it will be useful, 11 but 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, 17 see <http://www.gnu.org/licenses/> 18 */ 19 /** 20 * @file bank-lib/fakebank.h 21 * @brief general state of the fakebank 22 * @author Christian Grothoff <christian@grothoff.org> 23 */ 24 #ifndef FAKEBANK_H 25 #define FAKEBANK_H 26 27 #include "taler/taler_fakebank_lib.h" 28 #include "taler/taler_bank_service.h" 29 #include "taler/taler_mhd_lib.h" 30 #include <gnunet/gnunet_mhd_compat.h> 31 32 33 /** 34 * How long are exchange base URLs allowed to be at most? 35 * Set to a relatively low number as this does contribute 36 * significantly to our RAM consumption. 37 */ 38 #define MAX_URL_LEN 64 39 40 41 /** 42 * Maximum POST request size. 43 */ 44 #define REQUEST_BUFFER_MAX (4 * 1024) 45 46 47 /** 48 * Per account information. 49 */ 50 struct Account; 51 52 53 /** 54 * Types of long polling activities. 55 */ 56 enum LongPollType 57 { 58 /** 59 * Transfer TO the exchange. 60 */ 61 LP_CREDIT, 62 63 /** 64 * Transfer FROM the exchange. 65 */ 66 LP_DEBIT, 67 68 /** 69 * Withdraw operation completion/abort. 70 */ 71 LP_WITHDRAW 72 73 }; 74 75 /** 76 * Client waiting for activity on this account. 77 */ 78 struct LongPoller 79 { 80 81 /** 82 * Kept in a DLL. 83 */ 84 struct LongPoller *next; 85 86 /** 87 * Kept in a DLL. 88 */ 89 struct LongPoller *prev; 90 91 /** 92 * Fakebank this long poller belongs with. 93 */ 94 struct TALER_FAKEBANK_Handle *h; 95 96 /** 97 * Account this long poller is waiting on. 98 */ 99 struct Account *account; 100 101 /** 102 * Withdraw operation we are waiting on, 103 * only if @e type is #LP_WITHDRAW, otherwise NULL. 104 */ 105 const struct WithdrawalOperation *wo; 106 107 /** 108 * Entry in the heap for this long poller. 109 */ 110 struct GNUNET_CONTAINER_HeapNode *hn; 111 112 /** 113 * Client that is waiting for transactions. 114 */ 115 struct MHD_Connection *conn; 116 117 /** 118 * When will this long poller time out? 119 */ 120 struct GNUNET_TIME_Absolute timeout; 121 122 /** 123 * What does the @e connection wait for? 124 */ 125 enum LongPollType type; 126 127 }; 128 129 130 /** 131 * Details about a transaction we (as the simulated bank) received. 132 */ 133 struct Transaction; 134 135 136 /** 137 * Information we keep per withdraw operation. 138 */ 139 struct WithdrawalOperation 140 { 141 /** 142 * Unique (random) operation ID. 143 */ 144 struct GNUNET_ShortHashCode wopid; 145 146 /** 147 * Debited account. 148 */ 149 struct Account *debit_account; 150 151 /** 152 * Target exchange account, or NULL if unknown. 153 */ 154 const struct Account *exchange_account; 155 156 /** 157 * RowID of the resulting transaction, if any. Otherwise 0. 158 */ 159 uint64_t row_id; 160 161 /** 162 * Amount transferred, NULL if still unknown. 163 */ 164 struct TALER_Amount *amount; 165 166 /** 167 * Public key of the reserve, wire transfer subject. 168 */ 169 struct TALER_ReservePublicKeyP reserve_pub; 170 171 /** 172 * When was the transaction made? 0 if not yet. 173 */ 174 struct GNUNET_TIME_Timestamp timestamp; 175 176 /** 177 * Was the withdrawal aborted? 178 */ 179 bool aborted; 180 181 /** 182 * Did the bank confirm the withdrawal? 183 */ 184 bool confirmation_done; 185 186 /** 187 * Is @e reserve_pub initialized? 188 */ 189 bool selection_done; 190 191 }; 192 193 194 /** 195 * Per account information. 196 */ 197 struct Account 198 { 199 200 /** 201 * Inbound transactions for this account in a MDLL. 202 */ 203 struct Transaction *in_head; 204 205 /** 206 * Inbound transactions for this account in a MDLL. 207 */ 208 struct Transaction *in_tail; 209 210 /** 211 * Outbound transactions for this account in a MDLL. 212 */ 213 struct Transaction *out_head; 214 215 /** 216 * Outbound transactions for this account in a MDLL. 217 */ 218 struct Transaction *out_tail; 219 220 /** 221 * Kept in a DLL. 222 */ 223 struct LongPoller *lp_head; 224 225 /** 226 * Kept in a DLL. 227 */ 228 struct LongPoller *lp_tail; 229 230 /** 231 * Account name (string, not payto!) 232 */ 233 char *account_name; 234 235 /** 236 * Receiver name for payto:// URIs. 237 */ 238 char *receiver_name; 239 240 /** 241 * Payto URI for this account. 242 */ 243 char *payto_uri; 244 245 /** 246 * Password set for the account (if any). 247 */ 248 char *password; 249 250 /** 251 * Current account balance. 252 */ 253 struct TALER_Amount balance; 254 255 /** 256 * true if the balance is negative. 257 */ 258 bool is_negative; 259 260 }; 261 262 263 /** 264 * Details about a transaction we (as the simulated bank) received. 265 */ 266 struct Transaction 267 { 268 /** 269 * We store inbound transactions in a MDLL. 270 */ 271 struct Transaction *next_in; 272 273 /** 274 * We store inbound transactions in a MDLL. 275 */ 276 struct Transaction *prev_in; 277 278 /** 279 * We store outbound transactions in a MDLL. 280 */ 281 struct Transaction *next_out; 282 283 /** 284 * We store outbound transactions in a MDLL. 285 */ 286 struct Transaction *prev_out; 287 288 /** 289 * Amount to be transferred. 290 */ 291 struct TALER_Amount amount; 292 293 /** 294 * Account to debit. 295 */ 296 struct Account *debit_account; 297 298 /** 299 * Account to credit. 300 */ 301 struct Account *credit_account; 302 303 /** 304 * Random unique identifier for the request. 305 * Used to detect idempotent requests. 306 */ 307 struct GNUNET_HashCode request_uid; 308 309 /** 310 * When did the transaction happen? 311 */ 312 struct GNUNET_TIME_Timestamp date; 313 314 /** 315 * Number of this transaction. 316 */ 317 uint64_t row_id; 318 319 /** 320 * What does the @e subject contain? 321 */ 322 enum 323 { 324 /** 325 * Transfer TO the exchange. 326 */ 327 T_CREDIT, 328 329 /** 330 * Transfer FROM the exchange. 331 */ 332 T_DEBIT, 333 334 /** 335 * Transfer TO the exchange for KYCAUTH. 336 */ 337 T_AUTH, 338 339 /** 340 * Exchange-to-exchange WAD transfer. 341 */ 342 T_WAD, 343 } type; 344 345 /** 346 * Wire transfer subject. 347 */ 348 union 349 { 350 351 /** 352 * Used if @e type is T_DEBIT. 353 */ 354 struct 355 { 356 357 /** 358 * Subject of the transfer. 359 */ 360 struct TALER_WireTransferIdentifierRawP wtid; 361 362 /** 363 * Base URL of the exchange. 364 */ 365 char exchange_base_url[MAX_URL_LEN]; 366 367 } debit; 368 369 /** 370 * Used if @e type is T_CREDIT. 371 */ 372 struct 373 { 374 375 /** 376 * Reserve public key of the credit operation. 377 */ 378 struct TALER_ReservePublicKeyP reserve_pub; 379 380 } credit; 381 382 /** 383 * Used if @e type is T_AUTH. 384 */ 385 struct 386 { 387 388 /** 389 * Account public key of the credit operation. 390 */ 391 union TALER_AccountPublicKeyP account_pub; 392 393 } auth; 394 395 /** 396 * Used if @e type is T_WAD. 397 */ 398 struct 399 { 400 401 /** 402 * Subject of the transfer. 403 */ 404 struct TALER_WadIdentifierP wad_id; 405 406 /** 407 * Base URL of the originating exchange. 408 */ 409 char origin_base_url[MAX_URL_LEN]; 410 411 } wad; 412 413 } subject; 414 415 /** 416 * Has this transaction not yet been subjected to 417 * #TALER_FAKEBANK_check_credit() or #TALER_FAKEBANK_check_debit() and 418 * should thus be counted in #TALER_FAKEBANK_check_empty()? 419 */ 420 bool unchecked; 421 }; 422 423 424 /** 425 * Function called to clean up context of a connection. 426 * 427 * @param ctx context to clean up 428 */ 429 typedef void 430 (*ConnectionCleaner)(void *ctx); 431 432 /** 433 * Universal context we keep per connection. 434 */ 435 struct ConnectionContext 436 { 437 /** 438 * Function we call upon completion to clean up. 439 */ 440 ConnectionCleaner ctx_cleaner; 441 442 /** 443 * Request-handler specific context. 444 */ 445 void *ctx; 446 }; 447 448 449 /** 450 * This is the "base" structure for both the /history and the 451 * /history-range API calls. 452 */ 453 struct HistoryArgs 454 { 455 456 /** 457 * Bank account number of the requesting client. 458 */ 459 uint64_t account_number; 460 461 /** 462 * Index of the starting transaction, exclusive (!). 463 */ 464 uint64_t start_idx; 465 466 /** 467 * Requested number of results and order 468 * (positive: ascending, negative: descending) 469 */ 470 int64_t delta; 471 472 /** 473 * Timeout for long polling. 474 */ 475 struct GNUNET_TIME_Relative lp_timeout; 476 477 /** 478 * true if starting point was given. 479 */ 480 bool have_start; 481 482 }; 483 484 485 /** 486 * Context we keep per history request. 487 */ 488 struct HistoryContext 489 { 490 /** 491 * When does this request time out. 492 */ 493 struct GNUNET_TIME_Absolute timeout; 494 495 /** 496 * Client arguments for this request. 497 */ 498 struct HistoryArgs ha; 499 500 /** 501 * Account the request is about. 502 */ 503 struct Account *acc; 504 505 /** 506 * JSON object we are building to return. 507 */ 508 json_t *history; 509 510 }; 511 512 513 /** 514 * Context we keep per get withdrawal operation request. 515 */ 516 struct WithdrawContext 517 { 518 /** 519 * When does this request time out. 520 */ 521 struct GNUNET_TIME_Absolute timeout; 522 523 /** 524 * The withdrawal operation this is about. 525 */ 526 struct WithdrawalOperation *wo; 527 528 }; 529 530 531 /** 532 * Handle for the fake bank. 533 */ 534 struct TALER_FAKEBANK_Handle 535 { 536 /** 537 * We store transactions in a revolving array. 538 */ 539 struct Transaction **transactions; 540 541 /** 542 * HTTP server we run to pretend to be the "test" bank. 543 */ 544 struct MHD_Daemon *mhd_bank; 545 546 /** 547 * Task running HTTP server for the "test" bank, 548 * unless we are using a thread pool (then NULL). 549 */ 550 struct GNUNET_SCHEDULER_Task *mhd_task; 551 552 /** 553 * Task for expiring long-polling connections, 554 * unless we are using a thread pool (then NULL). 555 */ 556 struct GNUNET_SCHEDULER_Task *lp_task; 557 558 /** 559 * Task for expiring long-polling connections, unless we are using the 560 * GNUnet scheduler (then NULL). 561 */ 562 pthread_t lp_thread; 563 564 /** 565 * MIN-heap of long pollers, sorted by timeout. 566 */ 567 struct GNUNET_CONTAINER_Heap *lp_heap; 568 569 /** 570 * Hashmap of reserve public keys to 571 * `struct Transaction` with that reserve public 572 * key. Used to prevent public-key reuse. 573 */ 574 struct GNUNET_CONTAINER_MultiPeerMap *rpubs; 575 576 /** 577 * Hashmap of short hashes (wopids) to 578 * `struct WithdrawalOperation`. 579 * Used to lookup withdrawal operations. 580 */ 581 struct GNUNET_CONTAINER_MultiShortmap *wops; 582 583 /** 584 * (Base) URL to suggest for the exchange. Can 585 * be NULL if there is no suggestion to be made. 586 */ 587 char *exchange_url; 588 589 /** 590 * Lock for accessing @a rpubs map. 591 */ 592 pthread_mutex_t rpubs_lock; 593 594 /** 595 * Hashmap of hashes of account names to `struct Account`. 596 */ 597 struct GNUNET_CONTAINER_MultiHashMap *accounts; 598 599 /** 600 * Lock for accessing @a accounts hash map. 601 */ 602 pthread_mutex_t accounts_lock; 603 604 /** 605 * Hashmap of hashes of transaction request_uids to `struct Transaction`. 606 */ 607 struct GNUNET_CONTAINER_MultiHashMap *uuid_map; 608 609 /** 610 * Lock for accessing @a uuid_map. 611 */ 612 pthread_mutex_t uuid_map_lock; 613 614 /** 615 * Lock for accessing the internals of 616 * accounts and transaction array entries. 617 */ 618 pthread_mutex_t big_lock; 619 620 /** 621 * How much money should be put into new accounts 622 * on /register. 623 */ 624 struct TALER_Amount signup_bonus; 625 626 /** 627 * Current transaction counter. 628 */ 629 uint64_t serial_counter; 630 631 /** 632 * Number of transactions we keep in memory (at most). 633 */ 634 uint64_t ram_limit; 635 636 /** 637 * Currency used by the fakebank. 638 */ 639 char *currency; 640 641 /** 642 * Hostname of the fakebank. 643 */ 644 char *hostname; 645 646 /** 647 * BaseURL of the fakebank. 648 */ 649 char *my_baseurl; 650 651 /** 652 * Our port number. 653 */ 654 uint16_t port; 655 656 #ifdef __linux__ 657 /** 658 * Event FD to signal @a lp_thread a change in 659 * @a lp_heap. 660 */ 661 int lp_event; 662 #else 663 /** 664 * Pipe input to signal @a lp_thread a change in 665 * @a lp_heap. 666 */ 667 int lp_event_in; 668 669 /** 670 * Pipe output to signal @a lp_thread a change in 671 * @a lp_heap. 672 */ 673 int lp_event_out; 674 #endif 675 676 /** 677 * Set to true once we are shutting down. 678 */ 679 bool in_shutdown; 680 681 /** 682 * Should we run MHD immediately again? 683 */ 684 bool mhd_again; 685 686 #if EPOLL_SUPPORT 687 /** 688 * Boxed @e mhd_fd. 689 */ 690 struct GNUNET_NETWORK_Handle *mhd_rfd; 691 692 /** 693 * File descriptor to use to wait for MHD. 694 */ 695 int mhd_fd; 696 #endif 697 }; 698 699 700 /** 701 * Task run whenever HTTP server operations are pending. 702 * 703 * @param cls the `struct TALER_FAKEBANK_Handle` 704 */ 705 void 706 TALER_FAKEBANK_run_mhd_ (void *cls); 707 708 709 #endif