taler-developer-manual.rst (69362B)
1 .. 2 This file is part of GNU TALER. 3 4 Copyright (C) 2014-2025 Taler Systems SA 5 6 TALER is free software; you can redistribute it and/or modify it under the 7 terms of the GNU Affero General Public License as published by the Free Software 8 Foundation; either version 3.0, or (at your option) any later version. 9 10 TALER is distributed in the hope that it will be useful, but WITHOUT ANY 11 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 12 A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 13 14 You should have received a copy of the GNU Affero General Public License along with 15 TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> 16 17 @author Christian Grothoff 18 19 General Developer Manual 20 ######################## 21 22 .. note:: 23 24 This manual contains information for developers working on GNU Taler 25 and related components. It is not intended for a general audience. 26 27 28 Project Overview 29 ================ 30 31 GNU Taler consists of a large (and growing) number of components 32 in various Git repositories. The following list gives a first 33 overview: 34 35 * exchange: core payment processing logic with a REST API, plus various 36 helper processes for interaction with banks and cryptographic 37 computations. Also includes the logic for the auditor and an 38 in-memory "bank" API implementation for testing. 39 40 * libeufin: implementation of the "bank" API using the EBICS protocol 41 used by banks in the EU. Allows an exchange to interact with 42 European banks. 43 44 * taler-magnet-bank: implementation of the "bank" API using the Magnet Bank 45 API. Allows an exchange to interact with Magnet Bank. 46 47 * taler-cyclos: implementation of the "bank" API using the Cyclos API. Allows an exchange to interact with a Cyclos network. 48 49 * taler-wise: implementation of the "bank" API using the Wise API. Allows an exchange to interact with Wise. 50 51 * depolymerization: implementation of the "bank" API on top of 52 blockchains, specifically Bitcoin and Ethereum. Allows an exchange 53 to interact with crypto-currencies. 54 55 * merchant: payment processing backend to be run by merchants, 56 offering a REST API. 57 58 * wallet-core: platform-independent implementation of a wallet to be run by 59 normal users. Includes also the WebExtension for various browsers. 60 Furthermore, includes various single-page apps used by other 61 components (especially as libeufin and merchant). Also includes 62 command-line wallet and tools for testing. 63 64 * taler-android: Android Apps including the Android wallet, the 65 Android point-of-sale App and the Android casher app. 66 67 * taler-ios: iOS wallet App. 68 69 * sync: backup service, provides a simple REST API to allow users to 70 make encrypted backups of their wallet state. 71 72 * anastasis: key escrow service, provides a simple REST API to allow 73 users to distribute encryption keys across multiple providers and 74 define authorization policies for key recovery. 75 76 * taler-mdb: integration of Taler with the multi-drop-bus (MDB) API 77 used by vending machines. Allows Taler payments to be integrated 78 with vending machines. 79 80 * gnu-taler-payment-for-woocommerce: payment plugin for the 81 woocommerce (wordpress) E-commerce solution. 82 83 * twister: man-in-the-middle proxy for tests that require fuzzing a 84 REST/JSON protocol. Used for some of our testing. 85 86 * challenger: implementation of an OAuth 2.0 provider that can be used 87 to verify that a user can receive SMS or E-mail at particular addresses. 88 Used as part of KYC processes of the exchange. 89 90 * taler-mailbox: messaging service used to store and forward payment 91 messages to Taler wallets. 92 93 * taldir: directory service used to lookup Taler wallet addresses for 94 sending invoices or payments to other wallets. 95 96 * taler-merchant-demos: various demonstration services operated at 97 'demo.taler.net', including a simple shop and a donation page. 98 99 There are other important repositories without code, including: 100 101 * gana: Hosted on git.gnunet.org, this repository defines various 102 constants used in the GNU Taler project. 103 104 * docs: documentation, including this very document. 105 106 * marketing: various presentations, papers and other resources for 107 outreach. 108 109 * large-media: very large data objects, such as videos. 110 111 * www: the taler.net website. 112 113 Fundamentals 114 ============ 115 116 Versioning 117 ---------- 118 119 A central rule is to never break anything for any dependency. To accomplish 120 this, we use versioning, of the APIs, database schema and the protocol. The 121 database versioning approach is described in the :ref:`Database schema 122 versioning <DatabaseVersioning>` section. Here, we will focus on API and 123 protocol versioning. 124 125 The key issue we need to solve with protocols and APIs (and that does not 126 apply to database versioning) is being able to introduce and remove features 127 without requiring a flag day where all components must update at the same 128 time. For this, we use GNU libtool style versioning with MAJOR:REVISION:AGE 129 and *not* semantic versioning (SEMVER). With GNU libtool style versioning, 130 first the REVISION should be increased on every change to the respective code. 131 Then, each time a feature is introduced or deprecated, the MAJOR and AGE 132 numbers are increased. Whenever an API is actually removed the AGE number is 133 reduced to match the distance since the removed API was deprecated. Thus, if 134 some client implements version X of the protocol (including not using any APIs 135 that have been deprecated), it is compatible for any implementation where 136 MAJOR is larger or equal to X, and MAJOR minus AGE is smaller or equal to X. 137 REVISION is not used for expected compatibility issues and merely serves to 138 uniquely identify each version (in combination with MAJOR). 139 140 To evolve any implementation, it is thus critical to first of all never 141 just break an existing API or endpoint. The only acceptable modifications 142 are to return additional information (being aware of binary compatibility!) 143 or to accept additional optional arguments (again, in a way that does not 144 break existing users). Thus, the most common way to introduce changes will 145 be the addition of new endpoints. Breaking existing endpoints is only ever 146 at best acceptable while in the process of introducing it and if you are 147 absolutely sure that there are zero users in other components. 148 149 When removing endpoints (or fields being returned), you must first deprecate 150 the existing API (incrementing MAJOR and AGE) and then wait for all clients, 151 including all clients in operation (e.g. Android and iOS Apps, e-commerce 152 integrations, etc.) to upgrade to a protocol implementation above the 153 deprecated MAJOR revision. Only then you should remove the endpoint and reduce 154 AGE. 155 156 To document these changes, please try to use ``@since`` annotations in the API 157 specifications to explain the MAJOR revision when a feature became available, 158 but most importantly use ``@deprecated X`` annotations to indicate that an API 159 was deprecated and will be removed once MAJOR minus AGE is above X. When using 160 an API, use the ``/config`` endpoints to check for compatibility and show a 161 warning if the version(s) you support and the version(s) offered by the server 162 are incompatible. 163 164 165 Tagging and Package Versioning 166 ------------------------------ 167 168 Release tags are of the form ``v${major}.${minor}.${patch}``. Release tags *should* be 169 annotated git tags. 170 171 We usually consider Debian packaging files (in ``debian/``) to be part of a release. 172 When only the Debian packaging files need to be changed, there are two options: 173 174 * Make a new patch release (``v${major}.${minor}.${patch+1}``) 175 * Make a Debian release: 176 177 * Debian version now includes a revision: ``${major}.${minor}.${patch}-${debrevision}`` 178 * The tag is Debian-specific: ``debian-${major}.${minor}.${patch}-${debrevision}`` 179 180 All source repos *should* include a ``contrib/bump`` script that automates bumping the\ 181 version in all relevant source and packaging files. 182 In the future, we might add an option to the script to only release a packaging bump. 183 Right now, that process is manual. 184 185 We support tagged and published pre-release versions via tags of the form ``v${major}.${minor}.${patch}-dev.${n}``. 186 The corresponding Debian version must be ``${major}.${minor}.${patch}~dev${n}``. 187 188 Nightly Debian packages should follow the `Debian conventions <https://wiki.debian.org/Versioning>`__ of ``{upcoming_version}~git{date}.{hash}-{revision}``. 189 190 Testing Tools 191 ------------- 192 193 For full ``make check`` support, install these programs: 194 195 - `jq <https://github.com/stedolan/jq>`__ 196 - `curl <http://curl.haxx.se>`__ 197 - `faketime <https://github.com/wolfcw/libfaketime>`__ 198 199 The ``make check`` should be able to function without them, but 200 their presence permits some tests to run that would otherwise be skipped. 201 202 Manual Testing Database Reset 203 ----------------------------- 204 205 Sometimes ``make check`` will fail with some kind of database (SQL) 206 error, perhaps with a message like ``OBJECT does not exist`` in the 207 ``test-suite.log`` file, where ``OBJECT`` is the name of a table or function. 208 In that case, it may be necessary to reset the ``talercheck`` database 209 with the commands: 210 211 .. code-block:: console 212 213 $ dropdb talercheck 214 $ createdb talercheck 215 216 This is because, at the moment, there is no support for 217 doing these steps automatically in the ``make check`` flow. 218 219 (If ``make check`` still fails after the reset, file a bug report as usual.) 220 221 Bug Tracking 222 ------------ 223 224 Bug tracking is done with Mantis (https://www.mantisbt.org/). The bug tracker 225 is available at `<https://bugs.taler.net>`_. A registration on the Web site is 226 needed in order to use the bug tracker, only read access is granted without a 227 login. 228 229 We use the following conventions for the bug states: 230 231 * NEW: Incoming bugs are in 'new' so that management (or developers) 232 can easily identify those that need to be checked (report correct? 233 something we want to fix?), prioritized and targeted for releases. 234 "NEW" bugs are never assigned to a developer. 235 236 * FEEDBACK: When blocked on feedback from reporter or other developer. 237 Assigned to other developer (but cannot be assigned to reporter, 238 in this case MAY remain associated with the developer who expects 239 the feedback). If a bug is on feedback, it automatically should be 240 considered to be high-priority to give the feedback (as it is 241 blocking someone else!). 242 243 * ACKNOWLEDGED: The bug has been reviewed, but no decision about 244 what action to take has been made yet. Should not be worked on 245 until management (or a developer) comes up with a plan. 246 "ACKNOWLEDGED" bugs should NOT be assigned to a developer. 247 248 * CONFIRMED: This is a real issue that should be worked on, but 249 is not yet actively worked on. If working on this bug requires 250 other bugs to be fixed first, they should be added as 251 child-bugs (via relationships). Developers are always welcome 252 to self-assign bugs that are "CONFIRMED" if they start to work 253 on a bug. "CONFIRMED" bugs should NOT be assigned to a developer. 254 255 * ASSIGNED: The specific developer the bug is assigned to is 256 **actively** working on the issue. Developers should strive to 257 not have more than 5-10 bugs assigned to them at any time. 258 Only having one assigned to you is totally OK! 259 Developers should aggressively un-assign bugs that they are 260 blocked on, cannot make progress on, or are no longer actively 261 working on (but of course, better *resolve* them before 262 moving on if possible). If the bug remains open, it probably 263 should go back to "CONFIRMED" or "ACKNOWLEDGED". 264 265 * RESOLVED: The bug has been fixed in Git. 266 267 * CLOSED: An official release was made with the fix in it. 268 269 When developers want to keep an eye on certain bugs, they should 270 **monitor** them. Multiple developers can be monitoring a bug, but 271 it can only be assigned to one. Developers should also keep an 272 eye on the roadmap (by release), bug categories they care about, 273 and of course priorities / severities. 274 275 We use **tags** to categorize bugs. Common tags that also imply 276 some urgency include (in alphabetical order): 277 278 * accounting: issues required for accounting (such as taxes by merchants) 279 * compliance: issues related to regulatory compliance 280 * $CUSTOMER: issues requested by a particular customer 281 * performance: performance problems or ideas for improvement 282 * security: security issues (including planned improvements to security) 283 * UX: user experience issues 284 285 These tags **should** be attached to "NEW" bugs if they apply. 286 287 288 Code Repositories 289 ----------------- 290 291 Taler code is versioned with Git. For those users without write access, all the 292 codebases are found at the following URL: 293 294 .. code-block:: none 295 296 git://git.taler.net/<repository> 297 298 A complete list of all the existing repositories is currently found at 299 `<https://git.taler.net/>`_. 300 301 302 Committing code 303 --------------- 304 305 Before you can obtain Git write access, you must sign the copyright 306 agreement. As we collaborate closely with GNUnet, we use their 307 copyright agreement -- with the understanding that your contributions 308 to GNU Taler are included in the assignment. You can find the 309 agreement on the `GNUnet site <https://gnunet.org/en/copyright.html>`_. 310 Please sign and mail it to Christian Grothoff as he currently collects 311 all the documents for GNUnet e.V. 312 313 To obtain Git access, you need to send us your SSH public key. Most core 314 team members have administrative Git access, so simply contact whoever 315 is your primary point of contact so far. You can 316 find instructions on how to generate an SSH key 317 in the `Git book <https://git-scm.com/book/en/v2/Git-on-the-Server-Generating-Your-SSH-Public-Key>`_. 318 If you have been granted write access, you first of all must change the URL of 319 the respective repository to: 320 321 .. code-block:: none 322 323 ssh://git@git.taler.net/<repository> 324 325 For an existing checkout, this can be done by editing the ``.git/config`` file. 326 327 The server is configured to reject all commits that have not been signed with 328 GnuPG. If you do not yet have a GnuPG key, you must create one, as explained 329 in the `GNU Privacy Handbook <https://www.gnupg.org/gph/en/manual/c14.html>`_. 330 You do not need to share the respective public key with us to make commits. 331 However, we recommend that you upload it to key servers, put it on your 332 business card and personally meet with other GNU hackers to have it signed 333 such that others can verify your commits later. 334 335 To sign all commits, you should run 336 337 .. code-block:: console 338 339 $ git config --global commit.gpgsign true 340 341 You can also sign individual commits only by adding the ``-S`` option to the 342 ``git commit`` command. If you accidentally already made commits but forgot 343 to sign them, you can retroactively add signatures using: 344 345 .. code-block:: console 346 347 $ git rebase -S 348 349 350 Whether you commit to a personal branch (recommended: ``dev/$USER/...``), 351 a feature branch or to ``master`` should 352 depend on your level of comfort and the nature of the change. As a general 353 rule, the code in ``master`` must always build and tests should always pass, at 354 least on your own system. However, we all make mistakes and you should expect 355 to receive friendly reminders if your change did not live up to this simple 356 standard. We plan to move to a system where the CI guarantees this invariant 357 in the future. 358 359 In order to keep a linear and clean commits history, we advise to avoid 360 merge commits and instead always rebase your changes before pushing to 361 the ``master`` branch. If you commit and later find out that new commits were 362 pushed, the following command will pull the new commits and rebase yours 363 on top of them. 364 365 .. code-block:: console 366 367 # -S instructs Git to (re)sign your commits 368 $ git pull --rebase -S 369 370 371 372 Observing changes 373 ----------------- 374 375 Every commit to the ``master`` branch of any of our public repositories 376 (and almost all are public) is automatically sent to the 377 gnunet-svn@gnu.org mailinglist. That list is for Git commits only, 378 and must not be used for discussions. It also carries commits from 379 our main dependencies, namely GNUnet and GNU libmicrohttpd. While 380 it can be high volume, the lists is a good way to follow overall 381 development. 382 383 384 Code generator usage policy 385 --------------------------- 386 387 We do neither encourage nor discourage the use of tools for code generation. 388 It is up to the individual developer to decide if a tool is acceptable for 389 a particular task. But of course, we do encourage you to use FLOSS tools 390 and we MUST NOT become dependent on non-free software! That said, if you 391 use tools, you must document their use and in particular satisfy the 392 `NLnet policy on the use of "AI" <https://nlnet.nl/news/2025/20250829-policy-on-use-of-AI.html>`__. 393 394 Specifically, we ask developers to always put generated code into a *separate* 395 Git commit and to include the full prompt in the commit message. Naturally, 396 you may clean up the code generator's output, but then you should do so in 397 separate Git commits (and of course only merge into master/stable after the 398 clean up is complete). But do preserve (not squash!) the commit with the 399 generated code so that it remains documented what the prompts were and which 400 code is generated. This will go a long way to keep code auditors sane! 401 402 403 Communication 404 ------------- 405 406 For public discussions we use the taler@gnu.org mailinglist. All developers 407 should subscribe to the low-volume Taler mailinglist. There are separate 408 low-volume mailinglists for gnunet-developers (@gnu.org) and for libmicrohttpd 409 (@gnu.org). For internal discussions we use https://mattermost.taler.net/ 410 (invitation only, but also archived). 411 412 413 What to put in bootstrap 414 ------------------------ 415 416 Each repository has a ``bootstrap`` script, which contains commands for the 417 developer to run after a repository checkout (i.e., after ``git clone`` or 418 ``git pull``). 419 Typically, this updates and initializes submodules, prepares the tool chain, 420 and runs ``autoreconf``. 421 The last step generates the ``configure`` script, whether for immediate use or 422 for inclusion in the distribution tarball. 423 424 One common submodule is ``contrib/gana``, which pulls from the 425 `GNUnet GANA repository <https://git.gnunet.org/gana.git/>`__. 426 For example, in the 427 `Taler exchange repository <https://git.taler.net/exchange.git>`__, 428 the bootstrap script eventually runs the ``git submodule update --init`` command 429 early on, and later runs script ``./contrib/gana-generate.sh``, which 430 generates files such as ``src/include/taler_signatures.h``. 431 432 Thus, to update that file, you need to: 433 434 - (in GANA repo) Find a suitable (unused) name and number for the Signature 435 Purposes database. 436 437 - Add it to GANA, in ``gnunet-signatures/registry.rec``. 438 (You can check for uniqueness with the ``recfix`` utility.) 439 440 - Commit the change, and push it to the GANA Git repo. 441 442 - (in Taler Repo) Run the ``contrib/gana-latest.sh`` script. 443 444 - Bootstrap, configure, do ``make install``, ``make check``, etc. 445 (Basically, make sure the change does not break anything.) 446 447 - Commit the submodule change, and push it to the Taler exchange Git repo. 448 449 A similar procedure is required for other databases in GANA. 450 See file ``README`` in the various directories for specific instructions. 451 452 453 Debian and Ubuntu Repositories 454 ============================== 455 456 We package our software for Debian and Ubuntu. 457 458 Nightly Repositories 459 -------------------- 460 461 To try the latest, unstable and untested versions of packages, 462 you can add the nightly package sources. 463 464 .. code-block:: shell-session 465 466 # For Debian (trixie) 467 $ curl -sS https://deb.taler.net/apt-nightly/taler-trixie-ci.sources \ 468 | tee /etc/apt/sources.list.d/taler-trixie-nightly.sources 469 470 471 Taler Deployment on gv.taler.net 472 ================================ 473 474 This section describes the GNU Taler deployment on ``gv.taler.net``. ``gv`` 475 is our server at BFH. It hosts the Git repositories, Web sites, CI and other 476 services. Developers can receive an SSH account and e-mail alias for the 477 system, you should contact Javier, Christian or Florian. As with Git, ask 478 your primary team contact for shell access if you think you need it. 479 480 481 DNS 482 --- 483 484 DNS records for taler.net are controlled by the GNU Taler maintainers, 485 specifically Christian and Florian, and our system administrator, Javier. If 486 you need a sub-domain to be added, please contact one of them. 487 488 489 User Acccounts 490 -------------- 491 492 On ``gv.taler.net``, there are three system users that are set up to 493 serve Taler on the Internet: 494 495 - ``head``: serves ``*.head.taler.net`` and gets automatically 496 built by Buildbot every 2 hours from the ``sandcastle-ng.git``. 497 Master key may be reset occasionally 498 499 - ``taler-test``: serves ``*.test.taler.net`` and does *NOT* get 500 automatically built, and runs more recent tags and/or unreleased 501 versions of Taler components. Master key may be reset 502 occasionally. 503 504 - ``demo``: serves ``*.demo.taler.net``. Never automatically built. 505 Master key is retained. 506 507 Demo Upgrade Procedure 508 ====================== 509 510 #. Login as the ``demo`` user on ``gv.taler.net``. 511 #. Pull the latest ``sandcastle-ng.git`` code in checkout at ``$HOME/sandcastle-ng``. 512 #. Run ``systemctl --user restart container-taler-sandcastle-demo.service`` 513 #. Refer to the sandcastle-ng README (https://git.taler.net/sandcastle-ng.git/about/) 514 for more info. 515 516 517 Upgrading the ``demo`` environment should be done with care, and ideally be 518 coordinated on the mailing list before. It is our goal for ``demo`` to always 519 run a "working version" that is compatible with various published wallets. 520 Please use the :doc:`demo upgrade checklist <../checklists/checklist-demo-upgrade>` to make 521 sure everything is working. 522 Nginx is already configured to reach the services as exported by the user unit. 523 524 525 Tagging components 526 ------------------ 527 528 All Taler components must be tagged with git before they are deployed on the 529 ``demo`` environment, using a tag of the following form: 530 531 .. code-block:: none 532 533 demo-YYYY-MM-DD-SS 534 YYYY = year 535 MM = month 536 DD = day 537 SS = serial 538 539 Environments and Builders on taler.net 540 ====================================== 541 542 Buildbot implementation 543 ----------------------- 544 545 GNU Taler uses a buildbot implementation (front end at https://buildbot.taler.net) to manage continuous integration. Buildbot documentation is at https://docs.buildbot.net/. 546 547 Here are some highlights: 548 549 - The WORKER is the config that that lives on a shell account on a localhost (taler.net), where this host has buildbot-worker installed. The WORKER executes the commands that perform all end-functions of buildbot. 550 551 - The WORKER running buildbot-worker receives these commands by authenticating and communicating with the buildbot server using parameters that were specified when the worker was created in that shell account with the ``buildbot-worker`` command. 552 553 - The buildbot server's master.cfg file contains FACTORY declarations which specify the commands that the WORKER will run on localhost. 554 555 - The FACTORY is tied to the WORKER in master.cfg by a BUILDER. 556 557 - The master.cfg also allows for SCHEDULER that defines how and when the BUILDER is executed. 558 559 - Our master.cfg file is checked into git, and then periodically updated on a particular account on taler.net (ask Christian for access if needed). Do not edit this file directly/locally on taler.net, but check changes into Git. 560 561 562 Best Practices: 563 564 - When creating a new WORKER in the ``master.cfg`` file, leave a comment specifying the server and user account that this WORKER is called from. (At this time, taler.net is the only server used by this implementation, but it's still good practice.) 565 566 - Create a worker from a shell account with this command: ``buildbot-worker create-worker <workername> localhost <username> <password>`` 567 568 Then make sure there is a WORKER defined in master.cfg like: ``worker.Worker("<username>", "<password>")`` 569 570 Test builder 571 ------------ 572 573 This builder (``test-builder``) compiles and starts every Taler component. 574 The associated worker is run by the ``taler-test`` Gv user, via the SystemD 575 unit ``buildbot-worker-taler``. The following commands start/stop/restart 576 the worker: 577 578 .. code-block:: 579 580 systemctl --user start buildbot-worker-taler 581 systemctl --user stop buildbot-worker-taler 582 systemctl --user restart buildbot-worker-taler 583 584 .. note:: 585 the mentioned unit file can be found at ``deployment.git/systemd-services/`` 586 587 Wallet builder 588 -------------- 589 590 This builder (``wallet-builder``) compiles every Taler component 591 and runs the wallet integration tests. The associated worker is 592 run by the ``walletbuilder`` Gv user, via the SystemD unit ``buildbot-worker-wallet``. 593 The following commands start/stop/restart the worker: 594 595 .. code-block:: 596 597 systemctl --user start buildbot-worker-wallet 598 systemctl --user stop buildbot-worker-wallet 599 systemctl --user restart buildbot-worker-wallet 600 601 .. note:: 602 the mentioned unit file can be found at ``deployment.git/systemd-services/`` 603 604 Documentation Builder 605 --------------------- 606 607 All the Taler documentation is built by the user ``docbuilder`` that 608 runs a Buildbot worker. The following commands set the ``docbuilder`` up, 609 starting with an empty home directory. 610 611 .. code-block:: console 612 613 # Log-in as the 'docbuilder' user. 614 615 $ cd $HOME 616 $ git clone git://git.taler.net/deployment 617 $ ./deployment/bootstrap-docbuilder 618 619 # If the previous step worked, the setup is 620 # complete and the Buildbot worker can be started. 621 622 $ buildbot-worker start worker/ 623 624 625 Website Builder 626 --------------- 627 628 629 Taler Websites, ``www.taler.net`` and ``stage.taler.net``, are built by the 630 user ``taler-websites`` by the means of a Buildbot worker. The following 631 commands set the ``taler-websites`` up, starting with an empty home directory. 632 633 .. code-block:: console 634 635 # Log-in as the 'taler-websites' user. 636 637 $ cd $HOME 638 $ git clone git://git.taler.net/deployment 639 $ ./deployment/bootstrap-sitesbuilder 640 641 # If the previous step worked, the setup is 642 # complete and the Buildbot worker can be started. 643 644 $ buildbot-worker start worker/ 645 646 647 Code coverage 648 ------------- 649 650 Code coverage tests are run by the ``lcovworker`` user, and are also driven 651 by Buildbot. 652 653 .. code-block:: console 654 655 # Log-in as the 'lcovworker' user. 656 657 $ cd $HOME 658 $ git clone git://git.taler.net/deployment 659 $ ./deployment/bootstrap-taler lcov 660 661 # If the previous step worked, the setup is 662 # complete and the Buildbot worker can be started. 663 664 $ buildbot-worker start worker/ 665 666 The results are then published at ``https://lcov.taler.net/``. 667 668 Producing auditor reports 669 ------------------------- 670 671 Both 'test' and 'demo' setups get their auditor reports compiled 672 by a Buildbot worker. The following steps get the reports compiler 673 prepared. 674 675 .. code-block:: console 676 677 # Log-in as <env>-auditor, with <env> being either 'test' or 'demo' 678 679 $ git clone git://git.taler.net/deployment 680 $ ./deployment/buildbot/bootstrap-scripts/prepare-auditorreporter <env> 681 682 # If the previous steps worked, then it should suffice to start 683 # the worker, with: 684 685 $ buildbot-worker start worker/ 686 687 688 .. _DatabaseVersioning: 689 690 Database schema versioning 691 -------------------------- 692 693 The PostgreSQL databases of the exchange, auditor, and merchant are versioned. 694 See the ``versioning.sql`` file in the respective directory for documentation. 695 696 Every set of changes to the database schema must be stored in a new 697 versioned SQL script. The scripts must have contiguous numbers. After 698 any release (or version being deployed to a production or staging 699 environment), existing scripts MUST be immutable. 700 701 Developers and operators MUST NOT make changes to database schema 702 outside of this versioning. All tables of a GNU Taler component should live in their own schema. 703 704 Runtime stored procedures are loaded from the component's generated 705 ``procedures.sql`` after schema patches. Updating a runtime procedure does 706 not itself advance the schema-patch version; table, index, constraint, and 707 data migrations still require a new numbered script. Component database 708 initialization tools are the supported way to apply both the pending patches 709 and the current procedure definitions. 710 711 712 QA Plans 713 ======== 714 715 .. include:: ../checklists/qa-1.0.rst 716 717 718 Releases 719 ======== 720 721 .. include:: ../checklists/checklist-release.rst 722 723 Release Process 724 --------------- 725 726 This document describes the process for releasing a new version of the 727 various Taler components to the official GNU mirrors. 728 729 The following components are published on the GNU mirrors 730 731 - taler-exchange (exchange.git) 732 - taler-merchant (merchant.git) 733 - sync (sync.git) 734 - taler-mdb (taler-mdb.git) 735 - libeufin (libeufin.git) 736 - challenger (challenger.git) 737 - wallet-core (wallet-core.git) 738 739 Tagging 740 ------- 741 742 Tag releases with an **annotated** commit, like 743 744 .. code-block:: console 745 746 $ git tag -a v0.1.0 -m "Official release v0.1.0" 747 $ git push origin v0.1.0 748 749 Prebuilt artifact policy 750 ------------------------ 751 752 Prebuilt artifacts are stored separately from source, normally on an orphan 753 ``prebuilt`` branch, and are consumed through a Git submodule pinned to an 754 exact commit. Projects producing such artifacts MUST provide repeatable 755 Makefile targets that build the artifact, prepare the prebuilt worktree, and 756 install the result in that worktree. A consumer's ``bootstrap`` script MUST 757 initialize the submodule and SHOULD fail gracefully when an obsolete prebuilt 758 commit is no longer available. 759 760 Artifacts use the layout ``COMPONENT/VERSION/``. ``VERSION`` MUST match both 761 the component version and a source tag. Every revision intended for consumers 762 MUST have a ``prebuilt-SERIAL`` tag; a ``COMPONENT/VERSION`` tag MAY additionally 763 identify the component-specific payload. Consumers MUST pin a tagged commit 764 and SHOULD use sparse checkout. Source, build instructions, and dependency 765 versions must remain sufficient to reproduce the artifact offline. 766 767 768 Database for tests 769 ------------------ 770 771 For tests in the exchange and merchant to run, make sure that a database 772 *talercheck* is accessible by *$USER*. Otherwise tests involving the 773 database logic are skipped. 774 775 .. include:: ../frags/db-stores-sensitive-data.rst 776 777 Exchange, merchant 778 ------------------ 779 780 Set the version in ``configure.ac``. The commit being tagged should be 781 the change of the version. 782 783 Tag the current GANA version that works with the exchange and merchant and 784 checkout that tag of gana.git (instead of master). Otherwise, if there are 785 incompatible changes in GANA (like removed symbols), old builds could break. 786 787 Update the Texinfo documentation using the files from docs.git: 788 789 .. code-block:: console 790 791 # Get the latest documentation repository 792 $ cd $GIT/docs 793 $ git pull 794 $ make texinfo 795 # The *.texi files are now in _build/texinfo 796 # 797 # This checks out the prebuilt branch in the prebuilt directory 798 $ git worktree add prebuilt prebuilt 799 $ cd prebuilt 800 # Copy the pre-built documentation into the prebuilt directory 801 $ cp -r ../_build/texinfo . 802 # Push and commit to branch 803 $ git commit -a -S -m "updating texinfo" 804 $ git status 805 # Verify that all files that should be tracked are tracked, 806 # new files will have to be added to the Makefile.am in 807 # exchange.git as well! 808 $ git push 809 # Remember $REVISION of commit 810 # 811 # Go to exchange 812 $ cd $GIT/exchange/doc/prebuilt 813 # Update submodule to point to latest commit 814 $ git checkout $REVISION 815 816 Finally, the Automake ``Makefile.am`` files may have to be adjusted to 817 include new ``*.texi`` files or images. 818 819 For bootstrap, you will need to install 820 `GNU Recutils <https://www.gnu.org/software/recutils/>`_. 821 822 For the exchange test cases to pass, ``make install`` must be run first. 823 Without it, test cases will fail because plugins can't be located. 824 825 .. code-block:: console 826 827 $ ./bootstrap 828 $ ./configure # add required options for your system 829 $ make dist 830 $ tar -xf taler-$COMPONENT-$VERSION.tar.gz 831 $ cd taler-$COMPONENT-$VERSION 832 $ make install check 833 834 Wallet WebExtension 835 ------------------- 836 837 The version of the wallet is in *manifest.json*. The ``version_name`` 838 should be adjusted, and *version* should be increased independently on 839 every upload to the WebStore. 840 841 .. code-block:: console 842 843 $ ./configure 844 $ make dist 845 846 Upload to GNU mirrors 847 --------------------- 848 849 See https://www.gnu.org/prep/maintain/maintain.html#Automated-FTP-Uploads 850 851 Directive file: 852 853 .. code-block:: none 854 855 version: 1.2 856 directory: taler 857 filename: taler-exchange-0.1.0.tar.gz 858 symlink: taler-exchange-0.1.0.tar.gz taler-exchange-latest.tar.gz 859 860 Upload the files in **binary mode** to the ftp servers. 861 862 863 Creating Debian packages 864 ------------------------ 865 866 Our general setup is based on 867 https://wiki.debian.org/DebianRepository/SetupWithReprepro 868 869 First, update at least the version of the Debian package in 870 debian/changelog, and then run: 871 872 .. code-block:: bash 873 874 $ dpkg-buildpackage -rfakeroot -b -uc -us 875 876 in the respective source directory (GNUnet, exchange, merchant) to create the 877 ``.deb`` files. Note that they will be created in the parent directory. This 878 can be done on gv.taler.net, or on another (secure) machine. 879 Actual release builds should be done via the Docker images 880 that can be found in ``deployment.git`` under packaging. 881 882 On ``gv``, we use the ``aptbuilder`` user to manage the reprepro repository. 883 884 Next, the ``*.deb`` files should be copied to gv.taler.net, say to 885 ``/home/aptbuilder/incoming``. Then, run 886 887 .. code-block:: bash 888 889 # cd /home/aptbuilder/apt 890 # reprepro includedeb bullseye ~/incoming/*.deb 891 892 to import all Debian files from ``~/incoming/`` into the ``bullseye`` 893 distribution. If Debian packages were build against other distributions, 894 reprepro may need to be first configured for those and the import command 895 updated accordingly. 896 897 Finally, make sure to clean up ``~/incoming/`` (by deleting the 898 now imported ``*.deb`` files). 899 900 901 902 Continuous integration 903 ====================== 904 905 CI is done with Buildbot (https://buildbot.net/), and builds are 906 triggered by the means of Git hooks. The results are published at 907 https://buildbot.taler.net/ . 908 909 In order to avoid downtimes, CI uses a "blue/green" deployment 910 technique. In detail, there are two users building code on the system, 911 the "green" and the "blue" user; and at any given time, one is running 912 Taler services and the other one is either building the code or waiting 913 for that. 914 915 There is also the possibility to trigger builds manually, but this is 916 only reserved to "admin" users. 917 918 Each repository owns its CI definition under ``contrib/ci``. Jobs are 919 directories named ``contrib/ci/jobs/N-NAME`` and MUST contain ``job.sh``; 920 their numeric prefix determines execution order. Optional job configuration 921 is stored as ``config.ini``. Unless every job selects its own container, the 922 repository MUST provide ``contrib/ci/Containerfile``. Projects SHOULD provide 923 at least separate build and test jobs. 924 925 The repository's ``contrib/ci/ci.sh NAME`` entry point runs an individual job 926 locally in the same containerized environment used by Buildbot. CI behavior 927 belongs in the component repository rather than in a central Buildbot-only 928 configuration. Cross-repository pipelines are separate builders because they 929 require several source trees and have different triggering requirements. 930 931 932 Dynamic form metadata 933 ===================== 934 935 Taler Web UIs that consume backend-provided form descriptions use a versioned 936 ``FormMetadata`` envelope. It contains a stable form ``id``, human-readable 937 ``label`` and optional ``description``, numeric ``version``, and a ``config`` 938 object. JSON configurations use one of two layouts: 939 940 * ``single-column`` with an ordered ``fields`` list; or 941 * ``double-column`` with an ordered ``sections`` list, where each section has a 942 title, optional description, and fields. 943 944 Fields are discriminated by their ``type``. Currently supported field classes 945 include amount, boolean, date, duration, one- and multi-select, text, 946 multi-line text, and toggle controls. Consumers MUST reject unknown or 947 malformed structures through the shared codec instead of interpreting them as 948 arbitrary HTML. The version belongs to the form definition and must change 949 when an incompatible metadata interpretation is introduced. 950 951 952 Internationalisation 953 ==================== 954 955 Internationalisation (a.k.a "translation") is handled using text-based 956 localization files named PO (Portable Object) holding pairs of original and 957 translated strings. 958 959 .. include:: dictionary.rst 960 :start-line: 4 961 962 iOS localization uses the checked-in ``Localizable.xcstrings`` catalogs as the 963 application source and checked-in ``XLIFF/*.xliff`` files as the Weblate 964 interchange representation. The XLIFF ``original`` attributes identify the 965 source ``.xcstrings`` catalogs. Translation updates must round-trip through 966 Xcode's XLIFF import/export support, preserve message identifiers and 967 placeholders, and be followed by a full application build. The older proposed 968 ``pogen`` conversion through PO files is not the deployed iOS workflow. 969 970 971 iOS Apps 972 ======== 973 974 .. _Build-iOS-from-source: 975 976 Building Taler Wallet for iOS from source 977 ----------------------------------------- 978 979 The GNU Taler Wallet iOS app is in 980 `the official Git repository <https://git.taler.net/taler-ios.git>`__. 981 982 Compatibility 983 ^^^^^^^^^^^^^ 984 985 The minimum version of iOS supported is 15.0. 986 This app runs on all iPhone models at least as new as the iPhone 6S. 987 988 989 Building 990 ^^^^^^^^ 991 992 Before building the iOS wallet, you must first checkout the 993 `quickjs-tart repo <https://git.taler.net/quickjs-tart.git>`__ 994 and the 995 `wallet-core repo <https://git.taler.net/wallet-core.git>`__. 996 997 Have all 3 local repos (wallet-core, quickjs-tart, and this one) adjacent at 998 the same level (e.g. in a "GNU_Taler" folder) 999 Taler.xcworkspace expects the QuickJS framework sub-project to be at 1000 ``../quickjs-tart/QuickJS-rt.xcodeproj``. 1001 1002 Build wallet-core first: 1003 1004 .. code-block:: shell-session 1005 1006 $ cd wallet-core 1007 $ make embedded 1008 $ open packages/taler-wallet-embedded/dist 1009 1010 then drag or move its product "taler-wallet-core-qjs.mjs" 1011 into your quickjs-tart folder right at the top level. 1012 1013 Open Taler.xcworkspace, and set scheme / target to Taler_Wallet. Build&run... 1014 1015 Don't open QuickJS-rt.xcodeproj or TalerWallet.xcodeproj and build anything 1016 there - all needed libraries and frameworks will be built automatically from 1017 Taler.xcworkspace. 1018 1019 1020 Android Apps 1021 ============ 1022 1023 Android App Nightly Builds 1024 -------------------------- 1025 1026 There are currently three Android apps in 1027 `the official Git repository <https://git.taler.net/taler-android.git>`__: 1028 1029 * Wallet 1030 [`CI <https://git.taler.net/taler-android.git/tree/wallet/.gitlab-ci.yml>`__] 1031 * Merchant PoS Terminal 1032 [`CI <https://git.taler.net/taler-android.git/tree/merchant-terminal/.gitlab-ci.yml>`__] 1033 * Cashier 1034 [`CI <https://git.taler.net/taler-android.git/tree/cashier/.gitlab-ci.yml>`__] 1035 1036 Their git repositories are `mirrored at Gitlab <https://gitlab.com/gnu-taler/taler-android>`__ 1037 to utilize their CI 1038 and `F-Droid <https://f-droid.org>`_'s Gitlab integration 1039 to `publish automatic nightly builds <https://f-droid.org/docs/Publishing_Nightly_Builds/>`_ 1040 for each change on the ``master`` branch. 1041 1042 All three apps publish their builds to the same F-Droid nightly repository 1043 (which is stored as a git repository): 1044 https://gitlab.com/gnu-taler/fdroid-repo-nightly 1045 1046 You can download the APK files directly from that repository 1047 or add it to the F-Droid app for automatic updates 1048 by clicking the following link (on the phone that has F-Droid installed). 1049 1050 `GNU Taler Nightly F-Droid Repository <fdroidrepos://gnu-taler.gitlab.io/fdroid-repo-nightly/fdroid/repo?fingerprint=55F8A24F97FAB7B0960016AF393B7E57E7A0B13C2D2D36BAC50E1205923A7843>`_ 1051 1052 .. note:: 1053 Nightly apps can be installed alongside official releases 1054 and thus are meant **only for testing purposes**. 1055 Use at your own risk! 1056 1057 .. _Build-apps-from-source: 1058 1059 Building apps from source 1060 ------------------------- 1061 1062 Note that this guide is different from other guides for building Android apps, 1063 because it does not require you to run non-free software. 1064 It uses the Merchant PoS Terminal as an example, but works as well for the other apps 1065 if you replace ``merchant-terminal`` with ``wallet`` or ``cashier``. 1066 1067 First, ensure that you have the required dependencies installed: 1068 1069 * Java Development Kit 8 or higher (default-jdk-headless) 1070 * git 1071 * unzip 1072 1073 Then you can get the app's source code using git: 1074 1075 .. code-block:: console 1076 1077 # Start by cloning the Android git repository 1078 $ git clone https://git.taler.net/taler-android.git 1079 1080 # Change into the directory of the cloned repository 1081 $ cd taler-android 1082 1083 # Find out which Android SDK version you will need 1084 $ grep -i compileSdkVersion merchant-terminal/build.gradle 1085 1086 The last command will return something like ``compileSdkVersion 29``. 1087 So visit the `Android Rebuilds <http://android-rebuilds.beuc.net/>`_ project 1088 and look for that version of the Android SDK there. 1089 If the SDK version is not yet available as a free rebuild, 1090 you can try to lower the ``compileSdkVersion`` in the app's ``merchant-terminal/build.gradle`` file. 1091 Note that this might break things 1092 or require you to also lower other versions such as ``targetSdkVersion``. 1093 1094 In our example, the version is ``29`` which is available, 1095 so download the "SDK Platform" package of "Android 10.0.0 (API 29)" 1096 and unpack it: 1097 1098 .. code-block:: console 1099 1100 # Change into the directory that contains your downloaded SDK 1101 $ cd $HOME 1102 1103 # Unpack/extract the Android SDK 1104 $ unzip android-sdk_eng.10.0.0_r14_linux-x86.zip 1105 1106 # Tell the build system where to find the SDK 1107 $ export ANDROID_SDK_ROOT="$HOME/android-sdk_eng.10.0.0_r14_linux-x86" 1108 1109 # Change into the directory of the cloned repository 1110 $ cd taler-android 1111 1112 # Build the merchant-terminal app 1113 $ ./gradlew :merchant-terminal:assembleRelease 1114 1115 If you get an error message complaining about build-tools 1116 1117 > Failed to install the following Android SDK packages as some licences have not been accepted. 1118 build-tools;29.0.3 Android SDK Build-Tools 29.0.3 1119 1120 you can try changing the ``buildToolsVersion`` in the app's ``merchant-terminal/build.gradle`` file 1121 to the latest "Android SDK build tools" version supported by the Android Rebuilds project. 1122 1123 After the build finished successfully, 1124 you will find your APK in ``merchant-terminal/build/outputs/apk/release/``. 1125 1126 Update translations 1127 ------------------- 1128 1129 Translations are managed with Taler's weblate instance: 1130 https://weblate.taler.net/projects/gnu-taler/ 1131 1132 To update translations, enter the taler-android git repository 1133 and ensure that the weblate remote exists: 1134 1135 .. code-block:: console 1136 1137 $ git config -l | grep weblate 1138 1139 If it does not yet exist (empty output), you can add it like this: 1140 1141 .. code-block:: console 1142 1143 $ git remote add weblate https://weblate.taler.net/git/gnu-taler/wallet-android/ 1144 1145 Then you can merge in translations commit from the weblate remote: 1146 1147 .. code-block:: console 1148 1149 # ensure you have latest version 1150 $ git fetch weblate 1151 1152 # merge in translation commits 1153 $ git merge weblate/master 1154 1155 Afterwards, build the entire project from source and test the UI 1156 to ensure that no erroneous translations (missing placeholders) are breaking things. 1157 1158 Release process 1159 --------------- 1160 1161 After extensive testing, the code making up a new release should get a signed git tag. 1162 The current tag format is: 1163 1164 * cashier-$VERSION 1165 * pos-$VERSION 1166 * wallet-$VERSION (where $VERSION has a v prefix) 1167 1168 .. code-block:: console 1169 1170 $ git tag -s $APP-$VERSION 1171 1172 F-Droid 1173 ^^^^^^^ 1174 Nightly builds get published automatically (see above) after pushing code to the official repo. 1175 Actual releases get picked up by F-Droid's official repository via git tags. 1176 So ensure that all releases get tagged properly. 1177 1178 Some information for F-Droid official repository debugging: 1179 1180 * Wallet: [`metadata <https://gitlab.com/fdroid/fdroiddata/-/blob/master/metadata/net.taler.wallet.fdroid.yml>`__] [`build log <https://f-droid.org/wiki/page/net.taler.wallet.fdroid/lastbuild>`__] 1181 * Cashier: [`metadata <https://gitlab.com/fdroid/fdroiddata/-/blob/master/metadata/net.taler.cashier.yml>`__] [`build log <https://f-droid.org/wiki/page/net.taler.cashier/lastbuild>`__] 1182 * PoS: [`metadata <https://gitlab.com/fdroid/fdroiddata/-/blob/master/metadata/net.taler.merchantpos.yml>`__] [`build log <https://f-droid.org/wiki/page/net.taler.merchantpos/lastbuild>`__] 1183 1184 Google Play 1185 ^^^^^^^^^^^ 1186 Google Play uploads are managed via `Fastlane <https://docs.fastlane.tools/getting-started/android/setup/>`__. 1187 Before proceeding, ensure that this is properly set up 1188 and that you have access to the Google Play API. 1189 1190 It is important to have access to the signing keys and Google Play access keys 1191 (JSON) and to ensure that the following environment variables are set 1192 correctly and made available to Fastlane: 1193 1194 .. code-block:: bash 1195 1196 TALER_KEYSTORE_PATH= 1197 TALER_KEYSTORE_PASS= 1198 TALER_KEYSTORE_WALLET_ALIAS= 1199 TALER_KEYSTORE_WALLET_PASS= 1200 TALER_KEYSTORE_POS_ALIAS= 1201 TALER_KEYSTORE_POS_PASS= 1202 TALER_KEYSTORE_CASHIER_ALIAS= 1203 TALER_KEYSTORE_CASHIER_PASS= 1204 TALER_JSON_KEY_FILE= 1205 1206 To release an app, enter into its respective folder and run fastlane: 1207 1208 .. code-block:: console 1209 1210 $ bundle exec fastlane 1211 1212 Then select the deploy option. 1213 1214 All uploads are going to the beta track by default. These can be promoted to 1215 production later or immediately after upload if you feel daring. It is also 1216 important to bump the version and build code with every release. 1217 1218 .. _Code-coverage: 1219 1220 Code Coverage 1221 ============= 1222 1223 Code coverage is done with the Gcov / Lcov 1224 (http://ltp.sourceforge.net/coverage/lcov.php) combo, and it is run 1225 nightly (once a day) by a Buildbot worker. The coverage results are 1226 then published at https://lcov.taler.net/ . 1227 1228 1229 Coding Conventions 1230 ================== 1231 1232 GNU Taler is developed primarily in C, Kotlin, Python, Swift and TypeScript. 1233 1234 Components written in C 1235 ----------------------- 1236 1237 These are the general coding style rules for Taler. 1238 1239 * Baseline rules are to follow GNU guidelines, modified or extended 1240 by the GNUnet style: https://docs.gnunet.org/handbook/gnunet.html#Coding-style 1241 1242 Naming conventions 1243 ^^^^^^^^^^^^^^^^^^ 1244 1245 * include files (very similar to GNUnet): 1246 1247 * if installed, must start with "``taler_``" (exception: platform.h), 1248 and MUST live in src/include/ 1249 * if NOT installed, must NOT start with "``taler_``" and 1250 MUST NOT live in src/include/ and 1251 SHOULD NOT be included from outside of their own directory 1252 * end in "_lib" for "simple" libraries 1253 * end in "_plugin" for plugins 1254 * end in "_service" for libraries accessing a service, i.e. the exchange 1255 1256 * binaries: 1257 1258 * taler-exchange-xxx: exchange programs 1259 * taler-merchant-xxx: merchant programs (demos) 1260 * taler-wallet-xxx: wallet programs 1261 * plugins should be libtaler_plugin_xxx_yyy.so: plugin yyy for API xxx 1262 * libtalerxxx: library for API xxx 1263 1264 * logging 1265 1266 * tools use their full name in GNUNET_log_setup 1267 (i.e. 'taler-exchange-offline') and log using plain 'GNUNET_log'. 1268 * pure libraries (without associated service) use 'GNUNET_log_from' 1269 with the component set to their library name (without lib or '.so'), 1270 which should also be their directory name (i.e. 'util') 1271 * plugin libraries (without associated service) use 'GNUNET_log_from' 1272 with the component set to their type and plugin name (without lib or '.so'), 1273 which should also be their directory name (i.e. 'exchangedb-postgres') 1274 * libraries with associated service) use 'GNUNET_log_from' 1275 with the name of the service, which should also be their 1276 directory name (i.e. 'exchange') 1277 * for tools with ``-l LOGFILE``, its absence means write logs to stderr 1278 1279 * configuration 1280 1281 * same rules as for GNUnet 1282 1283 * exported symbols 1284 1285 * must start with TALER_[SUBSYSTEMNAME]_ where SUBSYSTEMNAME 1286 MUST match the subdirectory of src/ in which the symbol is defined 1287 * from libtalerutil start just with ``TALER_``, without subsystemname 1288 * if scope is ONE binary and symbols are not in a shared library, 1289 use binary-specific prefix (such as TMH = taler-exchange-httpd) for 1290 globals, possibly followed by the subsystem (TMH_DB_xxx). 1291 1292 * structs: 1293 1294 * structs that are 'packed' and do not contain pointers and are 1295 thus suitable for hashing or similar operations are distinguished 1296 by adding a "P" at the end of the name. (NEW) Note that this 1297 convention does not hold for the GNUnet-structs (yet). 1298 * structs that are used with a purpose for signatures, additionally 1299 get an "S" at the end of the name. 1300 1301 * private (library-internal) symbols (including structs and macros) 1302 1303 * must not start with ``TALER_`` or any other prefix 1304 1305 * testcases 1306 1307 * must be called "test_module-under-test_case-description.c" 1308 1309 * performance tests 1310 1311 * must be called "perf_module-under-test_case-description.c" 1312 1313 Shell Scripts 1314 ------------- 1315 1316 Shell scripts should be avoided if at all possible. The only permissible uses of shell scripts 1317 in GNU Taler are: 1318 1319 * Trivial invocation of other commands. 1320 * Scripts for compatibility (e.g. ``./configure``) that must run on 1321 as many systems as possible. 1322 1323 When shell scripts are used, they ``MUST`` begin with the following ``set`` command: 1324 1325 .. code-block:: console 1326 1327 # Make the shell fail on undefined variables and 1328 # commands with non-zero exit status. 1329 $ set -eu 1330 1331 Kotlin 1332 ------ 1333 1334 We so far have no specific guidelines, please follow best practices 1335 for the language. 1336 1337 1338 Python 1339 ------ 1340 1341 Supported Python Versions 1342 ^^^^^^^^^^^^^^^^^^^^^^^^^ 1343 1344 Python code should be written and built against version 3.7 of Python. 1345 1346 Style 1347 ^^^^^ 1348 1349 We use `yapf <https://github.com/google/yapf>`_ to reformat the 1350 code to conform to our style instructions. 1351 A reusable yapf style file can be found in ``build-common``, 1352 which is intended to be used as a git submodule. 1353 1354 Python for Scripting 1355 ^^^^^^^^^^^^^^^^^^^^ 1356 1357 When using Python for writing small utilities, the following libraries 1358 are useful: 1359 1360 * ``click`` for argument parsing (should be preferred over argparse) 1361 * ``pathlib`` for path manipulation (part of the standard library) 1362 * ``subprocess`` for "shelling out" to other programs. Prefer ``subprocess.run`` 1363 over the older APIs. 1364 1365 1366 Swift 1367 ----- 1368 1369 Please follow best practices for the language. 1370 1371 1372 TypeScript 1373 ---------- 1374 1375 Please follow best practices for the language. 1376 1377 1378 Testing library 1379 =============== 1380 1381 This chapter is a VERY ABSTRACT description of how testing is 1382 implemented in Taler, and in NO WAY wants to substitute the reading of 1383 the actual source code by the user. 1384 1385 In Taler, a test case is an array of ``struct TALER_TESTING_Command``, 1386 informally referred to as ``CMD``, that is iteratively executed by the 1387 testing interpreter. This latter is transparently initiated by the 1388 testing library. 1389 1390 However, the developer does not have to define CMDs manually, but 1391 rather call the proper constructor provided by the library. For example, 1392 if a CMD is supposed to test feature ``x``, then the library would 1393 provide the ``TALER_TESTING_cmd_x ()`` constructor for it. Obviously, 1394 each constructor has its own particular arguments that make sense to 1395 test ``x``, and all constructors are thoroughly commented within the 1396 source code. 1397 1398 Internally, each CMD has two methods: ``run ()`` and ``cleanup ()``. The 1399 former contains the main logic to test feature ``x``, whereas the latter 1400 cleans the memory up after execution. 1401 1402 In a test life, each CMD needs some internal state, made by values it 1403 keeps in memory. Often, the test has to *share* those values with other 1404 CMDs: for example, CMD1 may create some key material and CMD2 needs this 1405 key material to encrypt data. 1406 1407 The offering of internal values from CMD1 to CMD2 is made by *traits*. A 1408 trait is a ``struct TALER_TESTING_Trait``, and each CMD contains an array 1409 of traits, that it offers via the public trait interface to other 1410 commands. The definition and filling of such array happens transparently 1411 to the test developer. 1412 1413 For example, the following example shows how CMD2 takes an amount object 1414 offered by CMD1 via the trait interface. 1415 1416 Note: the main interpreter and the most part of CMDs and traits are 1417 hosted inside the exchange codebase, but nothing prevents the developer 1418 from implementing new CMDs and traits within other codebases. 1419 1420 .. code-block:: c 1421 1422 /* Without loss of generality, let's consider the 1423 * following logic to exist inside the run() method of CMD1 */ 1424 ... 1425 1426 struct TALER_Amount *a; 1427 /** 1428 * the second argument (0) points to the first amount object offered, 1429 * in case multiple are available. 1430 */ 1431 if (GNUNET_OK != TALER_TESTING_get_trait_amount_obj (cmd2, 0, &a)) 1432 return GNUNET_SYSERR; 1433 ... 1434 1435 use(a); /* 'a' points straight into the internal state of CMD2 */ 1436 1437 In the Taler realm, there is also the possibility to alter the behaviour 1438 of supposedly well-behaved components. This is needed when, for example, 1439 we want the exchange to return some corrupted signature in order to 1440 check if the merchant backend detects it. 1441 1442 This alteration is accomplished by another service called *twister*. The 1443 twister acts as a proxy between service A and B, and can be programmed 1444 to tamper with the data exchanged by A and B. 1445 1446 Please refer to the Twister codebase (under the ``test`` directory) in 1447 order to see how to configure it. 1448 1449 1450 User-Facing Terminology 1451 ======================= 1452 1453 This section contains terminology that should be used and that should not be 1454 used in the user interface and help materials. 1455 1456 Terms to Avoid 1457 -------------- 1458 1459 Refreshing 1460 Refreshing is the internal technical terminology for the protocol to 1461 give change for partially spent coins 1462 1463 **Use instead**: "Obtaining change" 1464 1465 Charge 1466 Charge has two opposite meanings (charge to a credit card vs. charge a battery). 1467 This can confuse users. 1468 1469 **Use instead**: "Obtain", "Credit", "Debit", "Withdraw", "Top up" 1470 1471 Coin 1472 Coins are an internal construct, the user should never be aware that their balance 1473 is represented by coins of different denominations. 1474 1475 **Use instead**: "(Digital) Cash" or "(Wallet) Balance" 1476 1477 Consumer 1478 Has bad connotation of consumption. 1479 1480 **Use instead**: Customer or user. 1481 1482 Proposal 1483 The term used to describe the process of the merchant facilitating the download 1484 of the signed contract terms for an order. 1485 1486 **Avoid**. Generally events that relate to proposal downloads 1487 should not be shown to normal users, only developers. Instead, use 1488 "communication with merchant failed" if a proposed order can't be downloaded. 1489 1490 Anonymous E-Cash 1491 Should be generally avoided, since Taler is only anonymous for 1492 the customer. Also some people are scared of anonymity (which as 1493 a term is also way too absolute, as anonymity is hardly ever perfect). 1494 1495 **Use instead**: "Privacy-preserving", "Privacy-friendly" 1496 1497 Payment Replay 1498 The process of proving to the merchant that the customer is entitled 1499 to view a digital product again, as they already paid for it. 1500 1501 **Use instead**: In the event history, "re-activated digital content purchase" 1502 could be used. (FIXME: this is still not nice.) 1503 1504 Session ID 1505 See Payment Replay. 1506 1507 Order 1508 Too ambiguous in the wallet. 1509 1510 **Use instead**: Purchase 1511 1512 Fulfillment URL 1513 URL that serves the digital content that the user purchased 1514 with their payment. Can also be something like a donation receipt. 1515 1516 Donau 1517 Developer-internal name for the tax authority component. 1518 1519 **Use instead**: Tax authority 1520 1521 Terms to Use 1522 ------------ 1523 1524 Auditor 1525 Regulatory entity that certifies exchanges and oversees their operation. 1526 1527 Exchange Operator 1528 The entity/service that gives out digital cash in exchange for some 1529 other means of payment. 1530 1531 In some contexts, using "Issuer" could also be appropriate. 1532 When showing a balance breakdown, 1533 we can say "100 Eur (issued by exchange.euro.taler.net)". 1534 Sometimes we may also use the more generic term "Payment Service Provider" 1535 when the concept of an "Exchange" is still unclear to the reader. 1536 1537 Refund 1538 A refund is given by a merchant to the customer (rather the customer's wallet) 1539 and "undoes" a previous payment operation. 1540 1541 Payment 1542 The act of sending digital cash to a merchant to pay for an order. 1543 1544 Purchase 1545 Used to refer to the "result" of a payment, as in "view purchase". 1546 Use sparingly, as the word doesn't fit for all payments, such as donations. 1547 1548 Contract Terms 1549 Partially machine-readable representation of the merchant's obligation after the 1550 customer makes a payment. 1551 1552 Merchant 1553 Party that receives a payment. 1554 1555 Wallet 1556 Also "Taler Wallet". Software component that manages the user's digital cash 1557 and payments. 1558 1559 1560 Developer Glossary 1561 ================== 1562 1563 This glossary is meant for developers. It contains some terms that we usually do not 1564 use when talking to end users or even system administrators. 1565 1566 .. glossary:: 1567 :sorted: 1568 1569 absolute time 1570 method of keeping time in :term:`GNUnet` where the time is represented 1571 as the number of microseconds since 1.1.1970 (UNIX epoch). Called 1572 absolute time in contrast to :term:`relative time`. 1573 1574 aggregate 1575 the :term:`exchange` combines multiple payments received by the 1576 same :term:`merchant` into one larger :term:`wire transfer` to 1577 the respective merchant's :term:`bank` account 1578 1579 auditor 1580 trusted third party that verifies that the :term:`exchange` is operating correctly 1581 1582 bank 1583 traditional financial service provider who offers 1584 :term:`wire transfers <wire transfer>` between accounts 1585 1586 buyer 1587 individual in control of a Taler :term:`wallet`, usually using it to 1588 :term:`spend` the :term:`coins <coin>` on :term:`contracts <contract>` (see also :term:`customer`). 1589 1590 close 1591 operation an :term:`exchange` performs on a :term:`reserve` that has not been 1592 :term:`emptied <empty>` by :term:`withdraw` operations. When closing a reserve, the 1593 exchange wires the remaining funds back to the customer, minus a :term:`fee` 1594 for closing 1595 1596 customer 1597 individual that directs the buyer (perhaps the same individual) to make a purchase 1598 1599 coin 1600 coins are individual tokens representing a certain amount of value, also known as the :term:`denomination` of the coin 1601 1602 refresh commitment 1603 data that the wallet commits to during the :term:`melt` stage of the 1604 :term:`refresh` protocol where it 1605 has to prove to the :term:`exchange` that it is deriving the :term:`fresh` 1606 coins as specified by the Taler protocol. The commitment is verified 1607 probabilistically (see: :term:`kappa`) during the :term:`reveal` stage. 1608 1609 contract 1610 formal agreement between :term:`merchant` and :term:`customer` specifying the 1611 :term:`contract terms` and signed by the merchant and the :term:`coins <coin>` of the 1612 customer 1613 1614 contract terms 1615 the individual clauses specifying what the buyer is purchasing from the 1616 :term:`merchant` 1617 1618 denomination 1619 unit of currency, specifies both the currency and the face value of a :term:`coin`, 1620 as well as associated fees and validity periods 1621 1622 denomination key 1623 (RSA) key used by the exchange to certify that a given :term:`coin` is valid and of a 1624 particular :term:`denomination` 1625 1626 deposit 1627 operation by which a merchant passes coins to an exchange, expecting the 1628 exchange to credit his bank account in the future using an 1629 :term:`aggregate` :term:`wire transfer` 1630 1631 drain 1632 process by which an exchange operator takes the profits 1633 (from :term:`fees <fee>`) out of the escrow account and moves them into 1634 their regular business account 1635 1636 dirty 1637 a :term:`coin` is dirty if its public key may be known to an entity other than 1638 the customer, thereby creating the danger of some entity being able to 1639 link multiple transactions of coin's owner if the coin is not refreshed 1640 1641 empty 1642 a :term:`reserve` is being emptied when a :term:`wallet` is using the 1643 reserve's private key to :term:`withdraw` coins from it. This reduces 1644 the balance of the reserve. Once the balance reaches zero, we say that 1645 the reserve has been (fully) emptied. Reserves that are not emptied 1646 (which is the normal process) are :term:`closed <close>` by the exchange. 1647 1648 exchange 1649 Taler's payment service operator. Issues electronic coins during 1650 withdrawal and redeems them when they are deposited by merchants 1651 1652 expired 1653 Various operations come with time limits. In particular, denomination keys 1654 come with strict time limits for the various operations involving the 1655 coin issued under the denomination. The most important limit is the 1656 deposit expiration, which specifies until when wallets are allowed to 1657 use the coin in deposit or refreshing operations. There is also a "legal" 1658 expiration, which specifies how long the exchange keeps records beyond the 1659 deposit expiration time. This latter expiration matters for legal disputes 1660 in courts and also creates an upper limit for refreshing operations on 1661 special zombie coin 1662 1663 GNUnet 1664 Codebase of various libraries for a better Internet, some of which 1665 GNU Taler depends upon. 1666 1667 fakebank 1668 implementation of the :term:`bank` API in memory to be used only for test 1669 cases. 1670 1671 fee 1672 an :term:`exchange` charges various fees for its service. The different 1673 fees are specified in the protocol. There are fees per coin for 1674 :term:`withdrawing <withdraw>`, :term:`depositing <deposit>`, :term:`melting <melt>`, and 1675 :term:`refunding <refund>`. Furthermore, there are fees per wire transfer 1676 when a :term:`reserve` is :term:`closed <close>` 1677 and for :term:`aggregate` :term:`wire transfers <wire transfer>` 1678 to the :term:`merchant`. 1679 1680 fresh 1681 a :term:`coin` is fresh if its public key is only known to the customer 1682 1683 JSON 1684 JavaScript Object Notation (JSON) is a 1685 serialization format derived from the JavaScript language which is 1686 commonly used in the Taler protocol as the payload of HTTP requests 1687 and responses. 1688 1689 kappa 1690 security parameter used in the :term:`refresh` protocol. Defined to be 3. 1691 The probability of successfully evading the income transparency with the 1692 refresh protocol is 1:kappa. 1693 1694 libeufin 1695 Kotlin component that implements a regional currency bank and an 1696 adapter to communicate via EBICS with European core banking systems. 1697 1698 link 1699 specific step in the :term:`refresh` protocol that an exchange must offer 1700 to prevent abuse of the :term:`refresh` mechanism. The link step is 1701 not needed in normal operation, it just must be offered. 1702 1703 master key 1704 offline key used by the exchange to certify denomination keys and 1705 message signing keys 1706 1707 melt 1708 step of the :term:`refresh` protocol where a :term:`dirty` :term:`coin` 1709 is invalidated to be reborn :term:`fresh` in a subsequent 1710 :term:`reveal` step. 1711 1712 merchant 1713 party receiving payments (usually in return for goods or services) 1714 1715 message signing key 1716 key used by the exchange to sign online messages, other than coins 1717 1718 order 1719 offer made by the merchant to a wallet; pre-cursor to 1720 a contract where the wallet is not yet fixed. Turns 1721 into a :term:`contract` when a wallet claims the order. 1722 1723 owner 1724 a coin is owned by the entity that knows the private key of the coin 1725 1726 relative time 1727 method of keeping time in :term:`GNUnet` where the time is represented 1728 as a relative number of microseconds. Thus, a relative time specifies 1729 an offset or a duration, but not a date. Called relative time in 1730 contrast to :term:`absolute time`. 1731 1732 recoup 1733 Operation by which an exchange returns the value of coins affected 1734 by a :term:`revocation <revoke>` to their :term:`owner`, either by allowing the owner to 1735 withdraw new coins or wiring funds back to the bank account of the :term:`owner`. 1736 1737 planchet 1738 precursor data for a :term:`coin`. A planchet includes the coin's internal 1739 secrets (coin private key, blinding factor), but lacks the RSA signature 1740 of the :term:`exchange`. When :term:`withdrawing <withdraw>`, a :term:`wallet` 1741 creates and persists a planchet before asking the exchange to sign it to 1742 get the coin. 1743 1744 purchase 1745 Refers to the overall process of negotiating a :term:`contract` and then 1746 making a payment with :term:`coins <coin>` to a :term:`merchant`. 1747 1748 privacy policy 1749 Statement of an operator how they will protect the privacy of users. 1750 1751 proof 1752 Message that cryptographically demonstrates that a particular claim is correct. 1753 1754 proposal 1755 a list of :term:`contract terms` that has been completed and signed by the 1756 merchant backend. 1757 1758 refresh 1759 operation by which a :term:`dirty` :term:`coin` is converted into one or more 1760 :term:`fresh` coins. Involves :term:`melting <melt>` the :term:`dirty` coins and 1761 then :term:`revealing <reveal>` so-called :term:`transfer keys <transfer key>`. 1762 1763 refund 1764 operation by which a merchant steps back from the right to funds that he 1765 obtained from a :term:`deposit` operation, giving the right to the funds back 1766 to the customer 1767 1768 refund transaction id 1769 unique number by which a merchant identifies a :term:`refund`. Needed 1770 as refunds can be partial and thus there could be multiple refunds for 1771 the same :term:`purchase`. 1772 1773 reserve 1774 accounting mechanism used by the exchange to track customer funds 1775 from incoming :term:`wire transfers <wire transfer>`. A reserve is created whenever 1776 a customer wires money to the exchange using a well-formed public key 1777 in the subject. The exchange then allows the customer's :term:`wallet` 1778 to :term:`withdraw` up to the amount received in :term:`fresh` 1779 :term:`coins <coin>` from the reserve, thereby emptying the reserve. If a 1780 reserve is not emptied, the exchange will eventually :term:`close` it. 1781 1782 Other definition: Funds set aside for future use; either the balance of a customer at the 1783 exchange ready for withdrawal, or the funds kept in the exchange;s bank 1784 account to cover obligations from coins in circulation. 1785 1786 reveal 1787 step in the :term:`refresh` protocol where some of the transfer private 1788 keys are revealed to prove honest behavior on the part of the wallet. 1789 In the reveal step, the exchange returns the signed :term:`fresh` coins. 1790 1791 revoke 1792 exceptional operation by which an exchange withdraws a denomination from 1793 circulation, either because the signing key was compromised or because 1794 the exchange is going out of operation; unspent coins of a revoked 1795 denomination are subjected to recoup. 1796 1797 sharing 1798 users can share ownership of a :term:`coin` by sharing access to the coin's 1799 private key, thereby allowing all co-owners to spend the coin at any 1800 time. 1801 1802 spend 1803 operation by which a customer gives a merchant the right to deposit 1804 coins in return for merchandise 1805 1806 transfer key 1807 special cryptographic key used in the :term:`refresh` protocol, some of which 1808 are revealed during the :term:`reveal` step. Note that transfer keys have, 1809 despite the name, no relationship to :term:`wire transfers <wire transfer>`. They merely 1810 help to transfer the value from a :term:`dirty` coin to a :term:`fresh` coin 1811 1812 terms 1813 the general terms of service of an operator, possibly including 1814 the :term:`privacy policy`. Not to be confused with the 1815 :term:`contract terms` which are about the specific purchase. 1816 1817 transaction 1818 method by which ownership is exclusively transferred from one entity 1819 1820 user 1821 any individual using the Taler payment system 1822 (see :term:`customer`, :term:`buyer`, :term:`merchant`). 1823 1824 version 1825 Taler uses various forms of versioning. There is a database 1826 schema version (stored itself in the database, see \*-0000.sql) describing 1827 the state of the table structure in the database of an :term:`exchange`, 1828 :term:`auditor` or :term:`merchant`. There is a protocol 1829 version (CURRENT:REVISION:AGE, see GNU libtool) which specifies 1830 the network protocol spoken by an :term:`exchange` or :term:`merchant` 1831 including backwards-compatibility. And finally there is the software 1832 release version (MAJOR.MINOR.PATCH, see https://semver.org/) of 1833 the respective code base. 1834 1835 wallet 1836 software running on a customer's computer; withdraws, stores and 1837 spends coins 1838 1839 WebExtension 1840 Cross-browser API used to implement the GNU Taler wallet browser extension. 1841 1842 wire gateway 1843 API used by the exchange to talk with some real-time gross settlement system 1844 (core banking system, blockchain) to notice inbound credits wire transfers 1845 (during withdraw) and to trigger outbound debit wire transfers (primarily 1846 for deposits). 1847 1848 wire transfer 1849 a wire transfer is a method of sending funds between :term:`bank` accounts 1850 1851 wire transfer identifier 1852 Subject of a wire transfer from the exchange to a merchant; 1853 set by the aggregator to a random nonce which uniquely 1854 identifies the transfer. 1855 1856 withdraw 1857 operation by which a :term:`wallet` can convert funds from a :term:`reserve` to 1858 fresh coins 1859 1860 zombie 1861 :term:`coin` where the respective :term:`denomination key` is past its 1862 :term:`deposit` :term:`expiration <expired>` time, but which is still (again) valid 1863 for an operation because it was :term:`melted <melt>` while it was still 1864 valid, and then later again credited during a :term:`recoup` process 1865 1866 1867 1868 Developer Tools 1869 =============== 1870 1871 This section describes various internal programs to make life easier for the 1872 developer. 1873 1874 1875 taler-harness 1876 ------------- 1877 1878 **taler-harness deployment gen-coin-config** is a tool to simplify Taler configuration generation. 1879 1880 1881 **taler-harness deployment gen-coin-config** 1882 [**-min-amount**=**\ \ *VALUE*] 1883 [**-max-amount**=**\ \ *VALUE*]