gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] [taler-exchange] branch stable updated (e140b41 -> ae68bd7)


From: gnunet
Subject: [GNUnet-SVN] [taler-exchange] branch stable updated (e140b41 -> ae68bd7)
Date: Wed, 18 Oct 2017 09:51:21 +0200

This is an automated email from the git hooks/post-receive script.

marcello pushed a change to branch stable
in repository exchange.

    from e140b41  log amount involved
     add 2c6956f  clean up PQ tables (renamings, remove redunant column), and 
primarily fix #4751
     add e1aa257  select on denom_pub_hash instead of denom_pub as the hash is 
a primary key
     add 0ea012e  make reserves_update more canonical, avoiding odd WHERE 
constraint that is unnecessary
     add 3a0e643  add UNIQUE constraint on BIGSERIAL columns as that is not 
automatic in Postgres
     add a301aad  add missing indices where needed
     add 6c63b3c  update picture of exhange DB
     add 1e8d0eb  implement #5114
     add 3e111f4  introducting error code for merchant detecting wire fee 
inconsistency
     add 2b56769  improve diagnostics
     add 26486e6  error code for merchant /pay db transaction
     add d30f7e9  Add ref for Practical Compact E-Cash with Arbitrary Wallet 
Size
     add 7d21331  Add two papers
     add 7aa23a3  add support for #4840 (/keys cherry picking) to 
libtalerexchange
     add 632fd85  fix odd missing initialization, very strange that this did 
not show up before as a problem
     add bf3d34e  do not version INSTALL, is generated
     add 6d7645a  theoretically finished implementation of #4840 (/keys cherry 
picking), but by far not done testing
     add e33d726  skeleton for /keys cherry picking testcase
     add b46735f  add argument to TALER_EXCHANGE_check_keys_current() to allow 
forcing the download
     add 7123015  create tables in taler-auditor-sign instead of failing 
obscurely
     add e243a89  style fix
     add 80a7fe9  add logic to signal exchange to reload keys
     add 36a7ac7  do keep signing over DKs even for cherry-picked /keys replies
     add f440904  note on messy / duplicated code
     add f346e89  (imperfect) test for #4840
     add 1c3e787  be more precise about encoding HTTP bodies
     add e328b44  clean up /keys cherry picking logic, including changing the 
last_issue_date value to be in seconds
     add e5a9b3f  bump version of taler protocol we implement
     add e78e0f6  starting point for #4948
     add a3b71ac  fix bad sizeof()
     add 7cb48a7  check json_array_append_new() return values, proper logging 
on errors
     add a8de810  simplify time conversion using strptime instead of manual 
hack, also check for timezone issues if we get unusual time values
     add 4728534  fix calculation of 'Expires:' header, also handle HTTP HEAD 
requests
     add d36a200  fix uninit auditor_url field
     add a0d410e  fix mapping of auditor sigs to DKs, avoid one hash operation 
by caching hash value
     add 34db060  update .gitignore
     add 96e04d3  update auditordb API to support logic for taler-wire-auditor
     add 6a4f6b1  also store wire position in auditordb
     add 85a2d3d  modify wire auditor to deal with asynchrony of WIRE plugin API
     add e5aed9e  fix signed calls to isalpha/isdigit/isspace etc.
     add 1da03b9  fix indentation
     add 2f715c2  check return value from TALER_JSON_hash
     add dbab0c6  check return value from TALER_amount_get_zero
     add 06f5621  better logging if IBAN validation fails, also avoid 
potentially unbounded stack allocation
     add 800c54b  do not potentially pass -1 to fcntl()
     add 7f37c2a  more return value checks on TALER_amount_get_zero
     add 8f08e46  do not potentially pass -1 to fcntl()
     add dc883f8  add assertion to be more defensive against buffer overflow 
(cannot happen, but this better protects against future changes)
     add d550506  BLOB is BYTEA in Postgres
     add a7746c8  add assertion to be more defensive against buffer overflow 
(cannot happen, but this better protects against future changes)
     add a90936f  reduce scope of local vars
     add ad97b8d  use proper type for do_shutdown() callback
     add 9b585fd  handle plugin load failure without crashing
     add 98b7444  handle hypothetical failure of plugin not found
     add 332a372  handle (most) TEH_KS_acquire errors
     add d86a661  really carefully check strtoll() return value before casting 
to uint64_t
     add 1c725c0  use proper enum value for error code on signature parsing in 
wire plugin
     add 1261971  yet another TALER_amount_get_zero with missing rval check
     add 15e27ab  doh, do not try to clean up after allocation failure
     add 837fcd5  use proper return value, some c99 changes
     add c92d88d  check rval from TALER_amount_to_string
     add 7935349  check return value from create_denom_key_pair in test
     add cc5d09c  properly handle signing errors if httpd lacks signing keys by 
returning internal errors (and handling new return value from TEH_KS_sign)
     add 600d168  completing reserves_in logic of taler-wire-auditor, but not 
tested
     add cb13afa  complete first pass of taler-wre-auditor's wire-out audit 
logic
     add 7a232a0  add references to Mantis bugs to TODO/FIXME comments in code
     add fca44ed  fix syntax issue in texi
     add b5f5956  fix geq, needs{}
     add 6dbbd36  add CSS to dist
     add d970d6a  suppress compiler warning
     add 88cdaf7  adding missing table in the drop method
     add 2cddf52  work on #4963 for taler-auditor
     add 4a84520  resolve #4963
     add 272f113  add exchangedb function for #4961
     add eda7e1c  missing figure for dist
     add 298d7dd  assertion only holds if we did get results
     add 3e19066  add JSON auditor output samples
     add fbc685a  make --wire argument mandatory
     add e4fe0dc  exit more nicely if command line arguments were wrong
     add 0346e37  actually properly implement API wrt return value handling, 
even if not used today
     add 1fae7a4  report if DK lacks auditor signature
     add 0f67a9f  fix matching of auditor keys/denomination issues so that we 
return _all_ applicable auditor signatures, instead of a tiny subset
     add 58528f3  update docs
     add ae68bd7  fix --with-libcurl and --with-libgnurl options; they used to 
ignore the given path.

No new revisions were added by this update.

Summary of changes:
 .gitignore                                         |     3 +
 ChangeLog                                          |    24 +
 INSTALL                                            |   370 -
 README                                             |    14 +-
 configure.ac                                       |     4 +
 contrib/samples/README                             |     3 +
 contrib/samples/auditor.json                       | 11737 +++++++++++++++++++
 contrib/samples/wire-auditor.json                  |  4175 +++++++
 doc/Makefile.am                                    |     6 +-
 doc/exchange-db.png                                |   Bin 198095 -> 564934 
bytes
 doc/paper/taler.bib                                |    41 +-
 doc/taler-exchange.texi                            |    22 +-
 src/auditor/Makefile.am                            |    15 +
 src/auditor/taler-auditor-sign.c                   |    89 +-
 src/auditor/taler-auditor.c                        |   302 +-
 src/auditor/taler-wire-auditor.c                   |  1128 ++
 src/auditordb/plugin_auditordb_postgres.c          |   351 +-
 src/benchmark/taler-exchange-benchmark.c           |    33 +-
 src/exchange-lib/Makefile.am                       |    18 +-
 src/exchange-lib/exchange_api_common.c             |    13 +-
 src/exchange-lib/exchange_api_deposit.c            |    10 +-
 src/exchange-lib/exchange_api_handle.c             |   314 +-
 src/exchange-lib/exchange_api_refresh_link.c       |     2 +
 src/exchange-lib/exchange_api_reserve.c            |    32 +-
 src/exchange-lib/test_exchange_api.c               |    38 +-
 src/exchange-lib/test_exchange_api.conf            |     3 +
 .../test_exchange_api_keys_cherry_picking.c        |   797 ++
 ... => test_exchange_api_keys_cherry_picking.conf} |    65 +-
 ..._exchange_api_keys_cherry_picking_extended.conf |     5 +
 src/exchange-tools/taler-exchange-keyup.c          |    16 +-
 src/exchange/taler-exchange-aggregator.c           |    49 +-
 src/exchange/taler-exchange-httpd.c                |    44 +-
 src/exchange/taler-exchange-httpd_db.c             |    21 +-
 src/exchange/taler-exchange-httpd_deposit.c        |    78 +-
 src/exchange/taler-exchange-httpd_keystate.c       |  1678 ++-
 src/exchange/taler-exchange-httpd_keystate.h       |     5 +-
 src/exchange/taler-exchange-httpd_mhd.c            |     8 +-
 src/exchange/taler-exchange-httpd_payback.c        |    30 +-
 src/exchange/taler-exchange-httpd_refresh_melt.c   |    33 +-
 src/exchange/taler-exchange-httpd_refresh_reveal.c |    12 +-
 src/exchange/taler-exchange-httpd_refund.c         |    28 +-
 .../taler-exchange-httpd_reserve_withdraw.c        |    23 +-
 src/exchange/taler-exchange-httpd_responses.c      |    67 +-
 .../taler-exchange-httpd_track_transaction.c       |    12 +-
 src/exchange/taler-exchange-httpd_track_transfer.c |    14 +-
 src/exchange/test_taler_exchange_aggregator.c      |     6 +
 src/exchangedb/exchangedb_auditorkeys.c            |    38 +-
 src/exchangedb/plugin_exchangedb_postgres.c        |   458 +-
 src/exchangedb/test_exchangedb.c                   |    13 +-
 src/include/taler_auditordb_plugin.h               |    87 +
 src/include/taler_error_codes.h                    |    31 +-
 src/include/taler_exchange_service.h               |    37 +-
 src/include/taler_exchangedb_plugin.h              |    46 +
 src/include/taler_signatures.h                     |     2 +-
 src/include/taler_wire_plugin.h                    |     6 +-
 src/json/json.c                                    |     3 +
 src/json/json_helper.c                             |     4 +-
 src/pq/test_pq.c                                   |    26 +-
 src/util/amount.c                                  |     2 +-
 src/wire/plugin_wire_sepa.c                        |    12 +-
 src/wire/plugin_wire_test.c                        |     2 +-
 61 files changed, 20937 insertions(+), 1568 deletions(-)
 delete mode 100644 INSTALL
 create mode 100644 contrib/samples/README
 create mode 100644 contrib/samples/auditor.json
 create mode 100644 contrib/samples/wire-auditor.json
 create mode 100644 src/auditor/taler-wire-auditor.c
 create mode 100644 src/exchange-lib/test_exchange_api_keys_cherry_picking.c
 copy src/exchange-lib/{test_exchange_api.conf => 
test_exchange_api_keys_cherry_picking.conf} (73%)
 create mode 100644 
src/exchange-lib/test_exchange_api_keys_cherry_picking_extended.conf

diff --git a/.gitignore b/.gitignore
index 4b4c412..16c6234 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,6 +10,7 @@ aclocal.m4
 autom4te.cache
 autoscan.log
 compile
+INSTALL
 configure
 depcomp
 missing
@@ -85,3 +86,5 @@ doc/manual/manual.tp
 doc/manual/manual.vr
 contrib/taler-exchange.tag
 doxygen-doc/
+src/exchange-lib/test_exchange_api_keys_cherry_picking
+src/auditor/taler-wire-auditor
diff --git a/ChangeLog b/ChangeLog
index c161add..9a5caa7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,27 @@
+Tue Oct 17 14:32:46 CEST 2017
+       Fix building of /keys response to include full auditor
+       signature set instead of partial map. -CG
+
+Mon Oct 16 12:10:35 CEST 2017
+       Realize JSON-based report formats from auditor (#4963). -CG
+
+Sun Sep 17 16:46:13 CEST 2017
+       Implement /keys cherry picking (#4840). -CG
+
+Wed Sep 13 14:06:44 CEST 2017
+       Add argument to TALER_EXCHANGE_check_keys_current()
+       to force download even if /keys are still considered
+       current. -CG
+
+Fri Jul 14 17:38:54 CEST 2017
+       Fix #4751 by not allowing denomination deletion (GC)
+       to cascade into reserve_out table (and tolerating such
+       deletion failures). This way, denominations will be kept
+       around until the last reserve that references them (or
+       known_coins derived from them) is closed. Naturally, in
+       most case we expect reserves to be closed much faster
+       than DKs, so in practice this should rarely apply. -CG
+
 Sun Jun 11 17:03:56 CEST 2017
        Finish implementation and testing of automated refunding
        of expired reserves (#4956). -CG
diff --git a/INSTALL b/INSTALL
deleted file mode 100644
index 2099840..0000000
--- a/INSTALL
+++ /dev/null
@@ -1,370 +0,0 @@
-Installation Instructions
-*************************
-
-Copyright (C) 1994-1996, 1999-2002, 2004-2013 Free Software Foundation,
-Inc.
-
-   Copying and distribution of this file, with or without modification,
-are permitted in any medium without royalty provided the copyright
-notice and this notice are preserved.  This file is offered as-is,
-without warranty of any kind.
-
-Basic Installation
-==================
-
-   Briefly, the shell command `./configure && make && make install'
-should configure, build, and install this package.  The following
-more-detailed instructions are generic; see the `README' file for
-instructions specific to this package.  Some packages provide this
-`INSTALL' file but do not implement all of the features documented
-below.  The lack of an optional feature in a given package is not
-necessarily a bug.  More recommendations for GNU packages can be found
-in *note Makefile Conventions: (standards)Makefile Conventions.
-
-   The `configure' shell script attempts to guess correct values for
-various system-dependent variables used during compilation.  It uses
-those values to create a `Makefile' in each directory of the package.
-It may also create one or more `.h' files containing system-dependent
-definitions.  Finally, it creates a shell script `config.status' that
-you can run in the future to recreate the current configuration, and a
-file `config.log' containing compiler output (useful mainly for
-debugging `configure').
-
-   It can also use an optional file (typically called `config.cache'
-and enabled with `--cache-file=config.cache' or simply `-C') that saves
-the results of its tests to speed up reconfiguring.  Caching is
-disabled by default to prevent problems with accidental use of stale
-cache files.
-
-   If you need to do unusual things to compile the package, please try
-to figure out how `configure' could check whether to do them, and mail
-diffs or instructions to the address given in the `README' so they can
-be considered for the next release.  If you are using the cache, and at
-some point `config.cache' contains results you don't want to keep, you
-may remove or edit it.
-
-   The file `configure.ac' (or `configure.in') is used to create
-`configure' by a program called `autoconf'.  You need `configure.ac' if
-you want to change it or regenerate `configure' using a newer version
-of `autoconf'.
-
-   The simplest way to compile this package is:
-
-  1. `cd' to the directory containing the package's source code and type
-     `./configure' to configure the package for your system.
-
-     Running `configure' might take a while.  While running, it prints
-     some messages telling which features it is checking for.
-
-  2. Type `make' to compile the package.
-
-  3. Optionally, type `make check' to run any self-tests that come with
-     the package, generally using the just-built uninstalled binaries.
-
-  4. Type `make install' to install the programs and any data files and
-     documentation.  When installing into a prefix owned by root, it is
-     recommended that the package be configured and built as a regular
-     user, and only the `make install' phase executed with root
-     privileges.
-
-  5. Optionally, type `make installcheck' to repeat any self-tests, but
-     this time using the binaries in their final installed location.
-     This target does not install anything.  Running this target as a
-     regular user, particularly if the prior `make install' required
-     root privileges, verifies that the installation completed
-     correctly.
-
-  6. You can remove the program binaries and object files from the
-     source code directory by typing `make clean'.  To also remove the
-     files that `configure' created (so you can compile the package for
-     a different kind of computer), type `make distclean'.  There is
-     also a `make maintainer-clean' target, but that is intended mainly
-     for the package's developers.  If you use it, you may have to get
-     all sorts of other programs in order to regenerate files that came
-     with the distribution.
-
-  7. Often, you can also type `make uninstall' to remove the installed
-     files again.  In practice, not all packages have tested that
-     uninstallation works correctly, even though it is required by the
-     GNU Coding Standards.
-
-  8. Some packages, particularly those that use Automake, provide `make
-     distcheck', which can by used by developers to test that all other
-     targets like `make install' and `make uninstall' work correctly.
-     This target is generally not run by end users.
-
-Compilers and Options
-=====================
-
-   Some systems require unusual options for compilation or linking that
-the `configure' script does not know about.  Run `./configure --help'
-for details on some of the pertinent environment variables.
-
-   You can give `configure' initial values for configuration parameters
-by setting variables in the command line or in the environment.  Here
-is an example:
-
-     ./configure CC=c99 CFLAGS=-g LIBS=-lposix
-
-   *Note Defining Variables::, for more details.
-
-Compiling For Multiple Architectures
-====================================
-
-   You can compile the package for more than one kind of computer at the
-same time, by placing the object files for each architecture in their
-own directory.  To do this, you can use GNU `make'.  `cd' to the
-directory where you want the object files and executables to go and run
-the `configure' script.  `configure' automatically checks for the
-source code in the directory that `configure' is in and in `..'.  This
-is known as a "VPATH" build.
-
-   With a non-GNU `make', it is safer to compile the package for one
-architecture at a time in the source code directory.  After you have
-installed the package for one architecture, use `make distclean' before
-reconfiguring for another architecture.
-
-   On MacOS X 10.5 and later systems, you can create libraries and
-executables that work on multiple system types--known as "fat" or
-"universal" binaries--by specifying multiple `-arch' options to the
-compiler but only a single `-arch' option to the preprocessor.  Like
-this:
-
-     ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
-                 CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
-                 CPP="gcc -E" CXXCPP="g++ -E"
-
-   This is not guaranteed to produce working output in all cases, you
-may have to build one architecture at a time and combine the results
-using the `lipo' tool if you have problems.
-
-Installation Names
-==================
-
-   By default, `make install' installs the package's commands under
-`/usr/local/bin', include files under `/usr/local/include', etc.  You
-can specify an installation prefix other than `/usr/local' by giving
-`configure' the option `--prefix=PREFIX', where PREFIX must be an
-absolute file name.
-
-   You can specify separate installation prefixes for
-architecture-specific files and architecture-independent files.  If you
-pass the option `--exec-prefix=PREFIX' to `configure', the package uses
-PREFIX as the prefix for installing programs and libraries.
-Documentation and other data files still use the regular prefix.
-
-   In addition, if you use an unusual directory layout you can give
-options like `--bindir=DIR' to specify different values for particular
-kinds of files.  Run `configure --help' for a list of the directories
-you can set and what kinds of files go in them.  In general, the
-default for these options is expressed in terms of `${prefix}', so that
-specifying just `--prefix' will affect all of the other directory
-specifications that were not explicitly provided.
-
-   The most portable way to affect installation locations is to pass the
-correct locations to `configure'; however, many packages provide one or
-both of the following shortcuts of passing variable assignments to the
-`make install' command line to change installation locations without
-having to reconfigure or recompile.
-
-   The first method involves providing an override variable for each
-affected directory.  For example, `make install
-prefix=/alternate/directory' will choose an alternate location for all
-directory configuration variables that were expressed in terms of
-`${prefix}'.  Any directories that were specified during `configure',
-but not in terms of `${prefix}', must each be overridden at install
-time for the entire installation to be relocated.  The approach of
-makefile variable overrides for each directory variable is required by
-the GNU Coding Standards, and ideally causes no recompilation.
-However, some platforms have known limitations with the semantics of
-shared libraries that end up requiring recompilation when using this
-method, particularly noticeable in packages that use GNU Libtool.
-
-   The second method involves providing the `DESTDIR' variable.  For
-example, `make install DESTDIR=/alternate/directory' will prepend
-`/alternate/directory' before all installation names.  The approach of
-`DESTDIR' overrides is not required by the GNU Coding Standards, and
-does not work on platforms that have drive letters.  On the other hand,
-it does better at avoiding recompilation issues, and works well even
-when some directory options were not specified in terms of `${prefix}'
-at `configure' time.
-
-Optional Features
-=================
-
-   If the package supports it, you can cause programs to be installed
-with an extra prefix or suffix on their names by giving `configure' the
-option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
-
-   Some packages pay attention to `--enable-FEATURE' options to
-`configure', where FEATURE indicates an optional part of the package.
-They may also pay attention to `--with-PACKAGE' options, where PACKAGE
-is something like `gnu-as' or `x' (for the X Window System).  The
-`README' should mention any `--enable-' and `--with-' options that the
-package recognizes.
-
-   For packages that use the X Window System, `configure' can usually
-find the X include and library files automatically, but if it doesn't,
-you can use the `configure' options `--x-includes=DIR' and
-`--x-libraries=DIR' to specify their locations.
-
-   Some packages offer the ability to configure how verbose the
-execution of `make' will be.  For these packages, running `./configure
---enable-silent-rules' sets the default to minimal output, which can be
-overridden with `make V=1'; while running `./configure
---disable-silent-rules' sets the default to verbose, which can be
-overridden with `make V=0'.
-
-Particular systems
-==================
-
-   On HP-UX, the default C compiler is not ANSI C compatible.  If GNU
-CC is not installed, it is recommended to use the following options in
-order to use an ANSI C compiler:
-
-     ./configure CC="cc -Ae -D_XOPEN_SOURCE=500"
-
-and if that doesn't work, install pre-built binaries of GCC for HP-UX.
-
-   HP-UX `make' updates targets which have the same time stamps as
-their prerequisites, which makes it generally unusable when shipped
-generated files such as `configure' are involved.  Use GNU `make'
-instead.
-
-   On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot
-parse its `<wchar.h>' header file.  The option `-nodtk' can be used as
-a workaround.  If GNU CC is not installed, it is therefore recommended
-to try
-
-     ./configure CC="cc"
-
-and if that doesn't work, try
-
-     ./configure CC="cc -nodtk"
-
-   On Solaris, don't put `/usr/ucb' early in your `PATH'.  This
-directory contains several dysfunctional programs; working variants of
-these programs are available in `/usr/bin'.  So, if you need `/usr/ucb'
-in your `PATH', put it _after_ `/usr/bin'.
-
-   On Haiku, software installed for all users goes in `/boot/common',
-not `/usr/local'.  It is recommended to use the following options:
-
-     ./configure --prefix=/boot/common
-
-Specifying the System Type
-==========================
-
-   There may be some features `configure' cannot figure out
-automatically, but needs to determine by the type of machine the package
-will run on.  Usually, assuming the package is built to be run on the
-_same_ architectures, `configure' can figure that out, but if it prints
-a message saying it cannot guess the machine type, give it the
-`--build=TYPE' option.  TYPE can either be a short name for the system
-type, such as `sun4', or a canonical name which has the form:
-
-     CPU-COMPANY-SYSTEM
-
-where SYSTEM can have one of these forms:
-
-     OS
-     KERNEL-OS
-
-   See the file `config.sub' for the possible values of each field.  If
-`config.sub' isn't included in this package, then this package doesn't
-need to know the machine type.
-
-   If you are _building_ compiler tools for cross-compiling, you should
-use the option `--target=TYPE' to select the type of system they will
-produce code for.
-
-   If you want to _use_ a cross compiler, that generates code for a
-platform different from the build platform, you should specify the
-"host" platform (i.e., that on which the generated programs will
-eventually be run) with `--host=TYPE'.
-
-Sharing Defaults
-================
-
-   If you want to set default values for `configure' scripts to share,
-you can create a site shell script called `config.site' that gives
-default values for variables like `CC', `cache_file', and `prefix'.
-`configure' looks for `PREFIX/share/config.site' if it exists, then
-`PREFIX/etc/config.site' if it exists.  Or, you can set the
-`CONFIG_SITE' environment variable to the location of the site script.
-A warning: not all `configure' scripts look for a site script.
-
-Defining Variables
-==================
-
-   Variables not defined in a site shell script can be set in the
-environment passed to `configure'.  However, some packages may run
-configure again during the build, and the customized values of these
-variables may be lost.  In order to avoid this problem, you should set
-them in the `configure' command line, using `VAR=value'.  For example:
-
-     ./configure CC=/usr/local2/bin/gcc
-
-causes the specified `gcc' to be used as the C compiler (unless it is
-overridden in the site shell script).
-
-Unfortunately, this technique does not work for `CONFIG_SHELL' due to
-an Autoconf limitation.  Until the limitation is lifted, you can use
-this workaround:
-
-     CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash
-
-`configure' Invocation
-======================
-
-   `configure' recognizes the following options to control how it
-operates.
-
-`--help'
-`-h'
-     Print a summary of all of the options to `configure', and exit.
-
-`--help=short'
-`--help=recursive'
-     Print a summary of the options unique to this package's
-     `configure', and exit.  The `short' variant lists options used
-     only in the top level, while the `recursive' variant lists options
-     also present in any nested packages.
-
-`--version'
-`-V'
-     Print the version of Autoconf used to generate the `configure'
-     script, and exit.
-
-`--cache-file=FILE'
-     Enable the cache: use and save the results of the tests in FILE,
-     traditionally `config.cache'.  FILE defaults to `/dev/null' to
-     disable caching.
-
-`--config-cache'
-`-C'
-     Alias for `--cache-file=config.cache'.
-
-`--quiet'
-`--silent'
-`-q'
-     Do not print messages saying which checks are being made.  To
-     suppress all normal output, redirect it to `/dev/null' (any error
-     messages will still be shown).
-
-`--srcdir=DIR'
-     Look for the package's source code in directory DIR.  Usually
-     `configure' can determine that directory automatically.
-
-`--prefix=DIR'
-     Use DIR as the installation prefix.  *note Installation Names::
-     for more details, including other options available for fine-tuning
-     the installation locations.
-
-`--no-create'
-`-n'
-     Run the configure checks, but stop before creating any output
-     files.
-
-`configure' also accepts some other, not widely useful, options.  Run
-`configure --help' for more details.
diff --git a/README b/README
index d5d76eb..751489f 100644
--- a/README
+++ b/README
@@ -15,7 +15,7 @@ payment system.
 
 Taler is currently developed by a worldwide group of independent free
 software developers and the DECENTRALISE team at Inria Rennes.  Taler
-is free software and a GNU package (http://www.gnu.org/).
+is free software and a GNU package (https://www.gnu.org/).
 
 This is an alpha release with a few known bugs, lacking a few
 important features, documentation, testing, performance tuning and an
@@ -23,7 +23,7 @@ external security audit.  However, you can run the code and 
it largely
 works fine.  that does not work yet.  This package also only includes
 the Taler exchange, not the other components of the system.
 
-Documentation about Taler can be found at http://taler.net/.
+Documentation about Taler can be found at https://taler.net/.
 Our bug tracker is at https://gnunet.org/bugs/.
 
 
@@ -63,9 +63,17 @@ src/exchange-tools/
 src/exchange-lib/
   -- libtalerexchange: C API to issue HTTP requests to exchange
 
+src/auditor/
+  -- tools to generate reports about financial performance and
+     to validate that the exchange has been operating correctly
+
+src/benchmark/
+  -- tool to run performance measurements
+
+
 
 Getting Started
-==============
+===============
 
 The following steps illustrate how to set up a exchange HTTP server.
 They take as a stub for configuring the exchange the content of 
'contrib/exchange-template/config/'.
diff --git a/configure.ac b/configure.ac
index 65efe78..f9eb7fa 100644
--- a/configure.ac
+++ b/configure.ac
@@ -317,6 +317,8 @@ AM_CONDITIONAL(HAVE_POSTGRESQL, test x$postgres = xtrue)
 LIBGNURL_CHECK_CONFIG(,7.34.0,gnurl=1,gnurl=0)
 if test "$gnurl" = 1
 then
+        LDFLAGS="-L$with_libgnurl/lib $LDFLAGS"
+        CPPFLAGS="-I$with_libgnurl/include $CPPFLAGS"
        AM_CONDITIONAL(HAVE_LIBGNURL, [true])
        AC_DEFINE([HAVE_LIBGNURL],[1],[Have libgnurl])
 else
@@ -327,6 +329,8 @@ fi
 LIBCURL_CHECK_CONFIG(,7.34.0,[curl=true],[curl=false])
 if test "x$curl" = xtrue
 then
+ LDFLAGS="-L$with_libcurl/lib $LDFLAGS"
+ CPPFLAGS="-I$with_libcurl/include $CPPFLAGS"
  AC_CHECK_HEADERS([curl/curl.h],
    AC_CHECK_DECLS(CURLINFO_TLS_SESSION,[curl=true],[curl=false],[[#include 
<curl/curl.h>]]),
    [curl=false])
diff --git a/contrib/samples/README b/contrib/samples/README
new file mode 100644
index 0000000..71d8090
--- /dev/null
+++ b/contrib/samples/README
@@ -0,0 +1,3 @@
+This directory contains some sample JSON reports
+from an auditor that are a useful starting point
+for the template-based report generation.
diff --git a/contrib/samples/auditor.json b/contrib/samples/auditor.json
new file mode 100644
index 0000000..1848492
--- /dev/null
+++ b/contrib/samples/auditor.json
@@ -0,0 +1,11737 @@
+{
+  "emergencies": [],
+  "row-inconsistencies": [],
+  "row-minor-inconsistencies": [],
+  "reserve-inconsistencies": [
+    {
+      "reserve_pub": "8ZV52AB6MHX8YVV0W0FHVDEZB54197JB85703J0E0AY6ZC4BFR7G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "ZJXM9B5551GKXWVAYPXNK30M79ZGQ56C90GJXQ1QQBGPHJH55QEG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "TJMX59TVK8CBGJVSSPM0VF2CVAWW66G2FRJ618V06G96QT1T161G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "GCR9P392CHBBZC5Q6WB638MVFNFFDHAHENXXJR0S9T2C1YQRBXM0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "KRF7HSVKT07XE1T6PQM2V787JG0KJP1NHDJ30QGG762AQSX7KN50",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "1A1CKR6CBZA9CX4SSQDQ4N3BX2H2X60YPZY415Y3D9411AGHJG70",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "HPKBGK7E2NB6M7W2P9W2CCSFDRXR2W35T9AXR2WXF9TDMN3V3JMG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "HJNDF2PAFPW42HDN9T902NDXNP859FC1FV2ATCJ5VSMNM1R61FQ0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "7R9ZDNJV3P1ZZTK8M3CQGE3MEA5KW6178JG9G74JV91VJ7PPFW00",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "98THXRYYWB3FEVR4A6Q34MERN9E4WW2EYY9JCMPX792KX67HXPNG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "H0TTEZ4VGNTQJ652W65CKSC8GDSBCEK1P6Q60ZGD80J7BS5DCQB0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "RWDA7MKZ98DS6P7N6Q7DDQM186AK872DFA7V5TKG19MMSTRWRC20",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "YZPTMT5D96MWP853E56K3GY7DX6NEZMMEXV0V91RZ7ZG34K8NZ30",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "NC02RDV3BKP0T5E5RAMNB2WWTE14DTZ0JD1SYH60VYN9WWGB9GZ0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "F8838830DJ2M6KXZ1R92G6NNF8D7S0QY734XP3K35XTFXSWCWQH0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "2XMJAX4NJFDY3442YQEDJV9C2WSH72ARKGT7W9C5SE5B59NQ97V0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "QDCMQSJZ5K106CT4Q51CQWSAPQ92PG16VEWHVQZRF3ATAB2TV8K0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "G55D8ZM6M534A21HEHX0NGTX98X3QR7MPYKZ0SC06VEZK9R7GPD0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "8GGW3YVFF04FTPNN1D0PA4YXDHZA1MFP5YVMGXKSYG5ZQ9J39F8G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "QE7A14VTQZACKP85E4K93PGKKBECY0YKP8RXBKKMRSCD8HP2HNA0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "W0CFNP998T148RFEEAB4VM7ZH9APD5FPYCACG0M72FB1W86QEQ80",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "E37MNVKKENQR3ZQTW4VT3XM6EPE1R3M91B4PVSHBSQARX43E9GW0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "68DPD5K998Y8XREE91Q51V2ADB1WHFNPWTFMC3WT940D28YWVE50",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "7Q8SZD065QDB64VHVE8BN325Q0PGZ117YA7DWGTX31GXTEHGJ4X0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "CPXA5R18G77HNF1BC24GRH84XQWWNZ0RNT552T7153GW2V5P4BVG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "TZG11N6H199HG95PFYQBZNH138NS0SC4QSPTKDGZJNAEWMAA3J0G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "DX1H1HMEKR63NX6QG72BWH2PF6QG2T625W2A938P1CGNHF4ANPV0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "2DDX75V8ZW1A51YR4PJ133HX7E1S3V9DJ3ZSPJ9CFYM32903V36G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "MY6TD61VDRF2TAC8SXXT5ZHV8V6DQPM2ZDJSYQP8ZVS4HB5YXTG0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "K1YVGX7BRKCAC6V7YB5YNSHJ73RYKJ2TBBJEXQ7475TYSKVS5VJG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "XK8VMEB5HVTFWKFYPH5XJNFATTRMYKNJYZQMMACCX90SY326S07G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "7GDJ7QS5GKKD8YPBFQ8TVHGPS84SSS9GR5R0681XJA0G4J2R6NB0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "33C2901ARBVCZAYFCQ8BDAN69CF1FJRYD3577GDQ1D16A8H0T12G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "R6EWQMP7T2B6XCAJH46PJCWVVR6VFDZEMWZ0SP7RP1NMPWCN4JX0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "E9XQMN2A54VW3C1GZDVZ29AX057X1TGTQ2M4XFCYP0HA4BXJ8KF0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "JGDKVJ5HJ90VCC1BHCQV09BYN8T57PTCT7GN3W3KNMAFT2JCCT80",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "DA6AMKDRB8X10SC9XVHJNA9VA9FGTBNDQQ2F75Z751G8DTKGJ37G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "YM8P57X99T3J3GG5MD4HVJ21N8EGYGZ2QJVHF24Y93SWKS19ES8G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "D7BJD4B6SGW7W1H040MM4M4R782BGT63SQ52R20Q14KZVEYE1TEG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "FWGTYEWQF36N56MJ38D6SJPC0CPBBVAVR94V2D61VBF2703DYSJ0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "DS80HSE492JXEEB0VBZKRG0CZ18FKB56T9CXGFTA8ZGXMMVYRDG0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "91WSTNPS2RKJTRQBMRA2QZ419WTR9GKK810A9KVBP7ZB3F8JQH20",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "8RB8AS3GQ6PKHT00XGV4T4RZ691J6WF30X33DK2W40NG156ZTXVG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "SFKR5GKK9DCMTDX09HR2ANDP47NVH686VSXPSVM45K6RH7XSKQPG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "6B2JMS5BAMKT6Z93D9GGP17R9WFJTY5JJTDGMPCGXXGM1TSJNXK0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "X70QF80H5EPK5YR9NM98QKNDQFGJB9KYY3Q1WFXTEXQNJ10XJAKG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "PRAXN67GY19041PP80NTBT5Q0T85NCW5HAQH3GV03Y8XJMSEVET0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "4TKAXYV245XAQKCJYRWPZEF5E42QKJXPDT017T0AJNT81YQMM3R0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "R6DH9CVA5K3TFW0YVTN5764Z6CXJK3HQCEX361X21NEKQ9T2CZD0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "NKCKQYEYAFP68EQM0XGR6MP00QKAY8V15N95Z7VTJ4A1YKCRZM9G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "WV9HE24FV4KTJDWP6WN4WCP562KZQAY0TYH4YP34WEXTE1DPXS10",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "965D34Q420Q9PK6RMTNPYDN4JTHY4ET9R86AJ7XY7RXTSD7AFGMG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "NZ1V3W4D9DGTYN6Z92D793G1832AA5A1MEF6JTCM83KTKFW0JBD0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "DTCK11V0N1PESM3GDBK5GA1PAZARZYMC8EPN6B155WRCN54JVA7G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "JFJR59W4G92JQEDQJG9P47MQATWNFMEMWPHD7BT5KMWVRRV8D29G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "9XSZBKFF7MQXHNBM6EV1FH75HZ31TFDC32NXH2A0M3M61AG3QN0G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "CS2207FWY8XVCE39PKSBZTPV8YCFFYJDNGFSBKTNY602GS0E0W1G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "Q6ERBVVHN5Q0MXCADQH5GA386V0EK0RCXS9R2Y0T4A8JVBDDY0X0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "N41QF6FNFY9VK8Q933PQ8PJT6Y6HQ8RXM68XTXD9A0YVB2XS5SV0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "9WFKGNW4CBZVK4AYZW3PZJAR4D8FCT8478ACV5PV0CS5WRRSHW2G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "VHJ8H9X567R6PFRJP85A6JJ5R2VPF2H5JQDC8QNZYQXJXWJQEK10",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "5NYX3M8DKSXH0Z6525E6804K4XMG1NBS349EA2VG369476HWEN00",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "H8N49R7D4KEJJ9BZG8QNM24Y5Y27EXSCHY3N1XCDH1VZR36PJ59G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "SDC78S5A5Z3MJ6NMMYQRER463Q1ADM6Q9WW1MSG2KA6H7QW7A5P0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "2QVN7XK5VS29TPKRRRB8RGSV67AQRA3G1W504047YZBE0NYGJDQ0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "NKYJ5AQE6AWPG8XS42TB9K9HE0R560HXKAK4V4182XQP2AKNTCN0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "N8YQASSA4474ZWS4TQP16MRG9H1WHXKXNJZENDW5XJESX6T9Z6KG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "RQA4N1DP3RP0SXHY2FPJJVWMD3MGCFYCYTY2VKH3H0QE9Z34A7E0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "Y2DRYT62SQ91S83V23DR6G0EW3A2PXFPKPP86JMM7AYXD8W7067G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "PB4ZKF9HF0J8B52148X104JTE35VAC89VFPXAV54RJ274DV8HBT0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "KCZ2WNRKPZJC2ZSR507RAE3896GH41ASTR12NGV23DD9FX6T1FMG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "5DZ465K5P6EHFXYDB3SHEZHG7QGKVVGZ33HAYCYHM44TGJ2JVM1G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "NCG9H41JCV8R2KQ71Q44S8JHPZKEZZPJTG4B0GCF9MEAT1ZH4C8G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "DXC077MXZ5QYJ6Y958FNSF88YZ46V2H3BRG3NNY4HJHB3539RJDG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "NZWFZW7G251WMD80C4B3EXVBJCD3NB2XSX8T7XD12XQEK51H8H00",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "DY8XECF7BJ19ANNJ9QNH3VB49ZX4N0DV51R6ADZW7E10EM9GA9DG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "GQQTFYYRA4141VXFBGT138663AD751GYQ4V7W6MBN51F8V5ATEK0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "ZM23WYMH8FZ7M20N9YQGZ3NAKY9MDKF6R26M0TZ9QDF4WV1841R0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "T6A09HW5RCRSNM0B9SCGSTES1NRR7W6QQYHW916Y1TJW5QN2HR3G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "37NV59SDCXEBF2M5ACTD463C86X1CC2KBHA1C41A4B8V38MR8MZ0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "ABAB2J1EANGW6HJ984K4HVE9057C7H5SX2NEV3H656K9E5H4A9GG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "JWEFHA9ST9K17XWBYNT32DXW7GW61TYYCJMJNNEF0S39F168WY20",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "KSF9E8VR88N2KAPMGYPS1P6QAXF15F1VX4S33DE4MHRFW4XDGZX0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "0H74YACCVQ0X9WF2JAXNNPD8MG1FAP60345H9EEPABE369BREZPG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "GWA4NB4KVNKFXVMGH2FA3G4C8RGWTTPMKQYYF1ZDE6DM7E3DGBQ0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "46MKA5QRJKBGN1P1EZP8T2TGRTV97EZTBP0210SRSX2111S07W70",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "XJJ7337CE50SHC5V7MY6V27B73XGGCHM8XSAES0RBAZ3XTZVDE0G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "F0XN5Z03WPHBC3RW0HRGXYYCEYB7YB4X81QKSXJSM92T2PPHW0MG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "SZHDF9GNQG9NHAERYBQ2TEA9XFF2Z44EHBDZR9GNKY2KDK6MPHZG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "VAWX6EFPNRYZ9SBMCMGVJ4ANRJGS9B3V95T9ZK0G9M02J2XRHEDG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "SAKJQ4ERKX7N0TGWHC4MRWS3HDBJSQZHH3ZWVCRPHCPKJKC4JSB0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "JZE07XYM613DY07WAF4NV678RW8JM7JHVPDE3PW9B7NA9RCD9ZYG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "SF34JEBVH5WPD7GNMSM8GM5BREA4NDGRBFMZ7WZD25SKFNKQFPHG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "2RFV5PCMHKANMHTZ5T5P1Y5YFRR4DYR0RTZXVB2X27WAXCNJA63G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "P9J6AWSF5QQJED6QE2PF1B5KWB7TJ5K5PBV9XBK8430NA8D4WYGG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "XSJFKFJCT7AJJ82VFPPH10YHYCCS0KCAKPYWANPDXW8QST116ZRG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "KBE6KPAE52JPTWBAWDDTTT3679QN4EDTC8MKZW958ER45TTAGXZG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "5SZ2FA8EWAZSY9GDWRNXYGKAS529FJZ97W16G4R0C4N3EKY7F040",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "YZEVFG8CJPKY20SPDK0X1ZK0JQ3C1JCDT9AE6S8AZ7Y2P5PHSMS0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "WMFBAVG2XVY5QJWH5RXCDCN9G3RHJQ75TP6T3MYRC852P0T05FV0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "KR3WTF6MF7CVJ41FJ4W1CXMPXAW986VFTB1S2340S5R355BJ2JYG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "7TRSKCWPJTSGR05PC35JKY72DCM2H38PJZXGPJ2FQ30WC3S5JPCG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "Z08Z8S01KHDF3WZ4F666YD40368XE2XZEY6GERDJ58YY3EKSWNWG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "WZ3V1FVAWP6SS7KRARRJ9D4YTSXREZJQKP794JEJEBHQ9MKR410G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "6EX3KH446ZBMP9M4ZFDA8K3B7FWR52SCMHQ7N8A1S9KBPGMXR0MG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "MP9ND4HRBQSSGDVZC9F936F3A474DSHNWWNQGC853APHEVGSW6JG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "GT1M8AYSM9G48794F03PW75NDTY8ACDHSERVW4ED2A84WXWQDKH0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "CYCBER3ND4JQEDYQ2BQBB19K69GJEK85P1ZE75H9H24H8KD6TWF0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "4J2V1661Q1SJ21GPH814XX7VNSPDR5WGNNWF8Y4TT9B407NNE7H0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "6JM4WXC4QM0D4JK4K01CBRB4BDRVEJ2GF2NEBVTQXCQDAE4EV450",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "4GW89Z5KNYST60MDWEQVA2PNSWWFCE5Z9TRWD2EN4RAV1KF2VFD0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "23H8FTH0J1FXJS9N7V0XHP75KGGVD45VQ0EGRGHSN16PQ1Y8PJKG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "P4SXQ305WTV2W0AKMQ7E3VR1WFVK0RXJ3J73AHX6ZY6C6EQ4N170",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "GXQ1RS4YJRHS6MDCP9QGN4XBKRJB2NZ0DYWK705MGYQ587K2ZN80",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "SF93HCBSKNXPYC5RPC6KBVD4TYD333GBH6DRPC81SY24WEBY0260",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "XH6X1XCE0VRB87W2ZYYJKNYGM65DWC1CSD0JZ4XJ9S69P6BAR4YG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "GT3AJ4DMKBN2ZA397MSBGGVAFGWBZ5QSXPVEHBX6FNNK80B984YG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "TSH0GD1YGEQY8MR5JC8TPTTPGJSGB3EV4ZGCBZTP46P6QRDAYFHG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "Z706KF6HKT8ZG6K1YA796QZ6C6RYDZ9NQMXTBYBQKX1PHZRZ5X8G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "VPHJFH0N5F3KHZ9X5F68VNKVVHXTZZDXZYYP744XQDBVYTN14900",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "0G5JKFVXSDHW6B03H8QAMHSZ3FRVBDNYS0MTASX11G68KFT60QW0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "HCPZD80RQH1P5SEKEJFTCDQ1SMJGJF4DCYTFCS564FHW9RXH0FN0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "DH6ANP2YN928BTT8G7WH2RN9PX0KQG6Y0HWT6HREDC7MFZCA58TG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "3GZNVBN60H3D9NJ9ZRFTPGX02QVRJMR67NDHVEZCP9AWWJPHHJTG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "8FN8C8VXJZV9VVGCH0AQX4G815P8QB1044B8VPBR5RZSEW6VV9X0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "HNF2K3YQMGFCNKBVMMC6AJDHM46PVM8X2B1BYZSY77QGX731VP80",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "K5EDQ58J67KGYMCDN6VDYMM2V9CJ4NA8H247B2526MYF9JRB5YMG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "RMHKXT2EQ2B20KAWJR7N4HWW8FGCR3JZFGAPCR42K6XETVTQ8EZG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "EV38SES4KZXGBCJVZANW4885E7A5YMHP8C3EWBMGF1XJ73W954YG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "7SZM3K3GPCJ5FZZMRDFE5H7WNPZ0RRJM2PFSBRGNFZX3Z0CS31J0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "AY7GM4G52VMV2VN5AFF82G9SMGFPEBNW69J909JBFCMDBHPAWSA0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "VBZVCSKTDK3VDDJ4AT904PDCCKSCA4Y8CWNH3KBMVZNMCC60NJEG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "FBX6317CV0EBMSB6FNQAA72AYFD3K5FXCCEQETNQ98NQSG99SV8G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "PSV3X7F6S2B31ZY6GH9RJ5PMYSQH0X3TRXNGCRZT5G31RYAVKQSG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "GYC867JNM5D7X64VRCNB0CQM2CPJ2YPDP8N1H8VMY5FGW65CSD60",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "XHMDKBH49J5T0FSGWVP8S8J700PKS4K3D48TXAT17J977ZBWEKR0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "QS0EX9YK2ZTMS09MD6STWQ51JVGKC5WDQ9F81BSMJ1JYAYGB4QBG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "5TDXNCYN0P89PXGF3800R81FWRVBEKP6RB1D5RHZ4VKYFXTYK5KG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "1J2TZDYEDSM2MCJHC64VNCN6GSV3HN1ZZZZAW1TBJZV32VKTXC80",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "H3P2JXFDVY057PZ4A3XGTW0M78NHSNJGGFXDN3995N76FM4M9CW0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "VC6KRMYN0FDVJBSFQWQ7D1EH9GTN7REC6FY398JPQ85Z74QH37X0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "53E091E3YEWER57M12P9R7BF08BRH4WR7K5RXMCYAQTF812HQNZ0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "2JFQK8CEWCPW9NR79Q80TJA8S4C7TJVQY2WYNNKNBAXB3JY3SCTG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "GASHZ1ZJPD8XY4CTTYXJRY0TYPZS9DDX0FR3DEPFGFPDYHER5EW0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "G80TWQ602VTGDE54ZH2A873B3D7W9JH0N113953S7YHNZCDA9MRG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "6FT82396X250SEE3TAB35PFRB8KTF2FKCC5X5RSM3QBT12VQMAW0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "VJSDEJ16B67N1VR2AA8RPFZY8VY0V90Z9D4FVKG5P2WAH6KQB55G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "RXS70DGBS4NWJNCRSEEVP37Z386MV5Z71VHHTTQDCN45MMDPYDP0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "5T1W7ACKKE38KFM56PRPVR4Y7KZ9R585CCXZWXFWSDKQ2H340E40",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "SWZYF5VXXD8Q3Z27FFB9J1W4RFTVQ7RJE7S0068J53NV7WZ4KKAG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "7E23H6FAQR882GQCWD8Z05Q8Z4K9D6THYR742N83ACXSSZXPGPZ0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "ACC5S73VCQ1BF0SN509D1CHQR2NWB0KHR3DWC3N0PB9Q3E7JNKK0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "X2JK6S3VVS8KX3SGJVDE49PXW2HQMEPRW8K3R6YPSH06GY5FT6C0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "K603M3BNYAVC0VZ51VH42XX6VTY8SS3S3VA07KH44V5XX8SPB0PG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "ZRNZGNR5AT1PBBYG5XM5SH33A2F7ZSZGJ62RXRETCVNW1VCGAWV0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "32VDNHA7A7Z8MVZVHXF5B9E16QRBXK7DM1MEQMHBQ8JTA6CW1X50",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "YVPMJSSMKFT02PAQD1TKF4Q4QXH9H07XTH9GQX5TSHV5N5WTJ0FG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "JM31ZPDEJ7FP8R8J5G1JX39G98PJGTSK7F0HEFD5Z7N0MMEGFKA0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "4TK2VZWZPCD5DFNX4124DTCE52XBQNRDCMAZH7VD65QY199EDC60",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "H6FC1MWRCFTFEXVBSDZ6NVTDDTKWP53VVTEFT527QRD4JRBDKPAG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "ENN2AY3MBPVM6PZWVYW2E0Y8GA3DXKY2CTEZ4NPW3HQ5BEHMM0AG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "8QSRS83KD7XYX430N290HWV38J12JMKNSJCWPJD6Q2EG549P9B60",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "MF7SEEBW0JQNGZSWK7YHS5W6RSRN1V1S4Y7C8WRQWA6HE8BASFY0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "MFFH7SGZ9XVNHEGFTR5MWJH7YT8KCTYDE71XHVW9W1A4GSRK4GVG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "54QK3NPWRJ5JFBVVRJRRGK940V7H27DTZDRPC5QWKESP8F9GMY8G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "EYNWH3QG84A1PNACQ96BKT6NG0TDK2MXEPD0QAGZDTDPMSSZBSRG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "10KBXRGYYP9V4DBS4NSFSMTJX2W0G724J7JCH0FDQHS985ZWV82G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "P8TQ0BA3KM96TWBENSRJRZRW8FPE12X650R46HHVXKSRFNBJ5C9G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "APN2QE5M4EY3B1V8T8JH1DK4Z3K3D8X18NWFVAYSE67TK5XVBGJ0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "6X8RQ8XFA6XHAACQ2MVYE21GMWQ0M4TV2DYNR1CT0NFWEZW9HQJG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "DA3YKQQY13BC0ZTDVXGFVCSEECPCQ38434GZXYW9VRESZ0BN9M1G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "SFZA39BD0VZYW63Q6FNKMVYVQ68S01NZYD8R7XD94J7MBH9YW710",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "Q60B2Y3YJ71KJHEKBD0E77H2GTD6Q2PJHS3VY7P0TABV02B7AWV0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "1QEX5G6QMRK1RRBZZ17FQ7X9VNEQK9T4T2PTQ7P1WNR457XZ3930",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "YQPP24Y3WMVDCB3Z9SSZDYRWVBEEFQ2MKVZZN277S3R34T42HFBG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "M7037WZAB3523QW5M8GZF77X8CB21FA0XJ2JEBXX431PRPHAJ4J0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "RJCVEPADX6MFQZNX87N2H2T5J15K8N7K4XSHRT95ZX34GD3P7SD0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "X8Y4N75P4V8ANMS47NFM3H06T0E9NJT8V6GMP2HXRD0XHAFP4XH0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "WS4RJ5HS0A55H7ZQRA421T22DR0BZKK3PVAMPGB7V2A4FM08FJHG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "Q0DF4K3P69HY75129H45N20F7FFJ5HVTCTDMD4BNGZ9M8CX8A8BG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "YSF6F2BD8PDGJBR7WDMQXGGT58DJ789BTRQHAY85QD80Q6GPZ8GG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "D6YE6SFEKQCP5R1PNJFAJ8XSTJH2P85061M6P3EH9CE6APWYT7N0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "2F38C68K5DWQ1T3A40Z5DZK164821XX8TD4ZMV0CSKV0S6HS5AB0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "D3AQA0VRD4Y91M1TTNGQBQ26A34FY5TSP1BEZ2WJ5H2QJAQHTTNG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "K4K0B7357NRWTZ2A5NFG1N46JGQQ3HXPRS9W07JZ40X5090K3EQ0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "8Y6XDXXXS416J8BE2WAKR79RGYFFXVV5J0S4XZSBD3RG39MSM2P0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "69DMS3TMHQ1R0PEG7EN1JHFWRRQBXZYH4JE3DW6PK7T8W67Y00VG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "3V63YJGDMTKM8ZJ05VMKA9TH408053SXYS950EA8GP0QDSB1N3DG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "354ZFTRWX0R2JY5AF7HQGNJSPMGSHPX2K44P34B6RGGSPKH6478G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "NE8VG1999FM31R79SJT0V4QP7CBBC1NQS2Q25CR5RHKMBMFWBENG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "R6R2J0QJ3E82FQ0WMGT2AMJ1ZGR05FWXEZNKET0M33G7K4PS47HG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "E0YP64K6TJNREM3EPF03ZKB8TWYMZ19Q50G5K1Q99D4QRNE23PGG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "M34490SCNZR0MF1CJNTC9EN4Y96WZ985KGJA3FCAMA2GK5J27YP0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "XHT12RV3D1VZFHDY1PD490GE0XD81E598PVYBFTDCVY2YYH5KT80",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "5W041WC3PKC1V9JW423HHRTYBSDSPK3WATJS35NK2SGG9S63MJ50",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "BDQRDQ6NG7PBPF76DTX5PYTY73REGRPSEXAAZP053WG0QTJFJM30",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "TA61C4DK8VSD2F0C8CAYH7QRK8B7HTR71MVG1PFX54MQAMXPDV6G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "7RRNY435S8TMRCCH440422Z8V9CY1NBEVPKQYC7TXQ0N3F7XFBBG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "CJC6T2VKA9W6HHSZXFCR8K8QFGWAVQ85P14NK8011WGAHECX372G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "RSZ7JFHGRSKKTWSVVKE39N9XYV49EGJHGGP7JQZY36AGCP6VQXY0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "8ES5VVMJ8R22Y360H0PJ3Q0F5CPTZY4ZM850TVN7JQHAZBTCPVEG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "EF0YGPBPS8S5007QGXFQN6F21KM3CK60QHBMDK8S17YPAEFVZBR0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "RWDGR2KAH36A6MHAAWVXBJJ5SP27MAZDRPYXJKCRHTATTPVXPD7G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "0RJHDS4F3JDFDHXBBTZT4ATTKQ88R43J843WQY3X4QHMM35NAV80",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "MGNAZE7CN1ZHC719SFCYBDE57GFSCRXV5XY145GQ3FBQKEASQ0CG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "SRJZQV63WN0JRBKDZYTBN0R1H0BFP272M4VZWRZVJGMHJ0QNKDB0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "DF18FHCB0XGGRVD4KBC8NFMSVCTN0JYF6M8PWC4Y4V39FF8Y3430",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "NHXF6V8FXCH6TBA02H7A3AE9B4K7V0TV2C2A0V1GGRKHDRW6MDHG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "B6RP7KFYAEQBWGFWD5DTQVJFCEAEQH3X7SCEDPF9REXP1615ZXT0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "42TATKYEBV5Y5TE3HEVSBBZFF8EVPHKT9WEYNWDJXNFY67290HJG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "AMH9SMPYSYQXFWJ3CRFN1ZSPVXPD04DDMQJYV9D3N67WB8C5R820",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "PYQNERJ0KV9N2KSJDNW8J0Q8S3017T5JEV5ZP7GGVJYX8CZ58PM0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "89GVQ3EJ610PGZR96T33GN410VDXCM02A2MJPFGQMSSY7MA1BK2G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "9REGXXQYZPWHRSCGBHKXSTCRFRYZG9RHGME9WHPBWEVV95ME46S0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "5RYA42N7Q3N40NED31T46XNPP74P089XZK0ZHHSGFQ4HF13KE8V0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "1YH4FB6S3E30JDAF419BA8G39NB97Z61RT7YKSQ4VBD16GQDW9RG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "3ME5JJGW33QSGVEMCHV4ZAQYB5XCYAVF3GE2F0YQFMG15RR1Q1Z0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "2FRFYDRVPYS4TABG7DDN251SB3M0TGJJJ7GBP87E2VW9DKY1PG5G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "J4D7DW8F7DPH6YJJZ96XB09GBVH95SXZHX4GTEETGPVZDWR7G4DG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "14MTRH9N4HP8R8NMQ3Q48K68AV8998MTB6MVE7V6D4KCMD7XBN5G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "W26W6KVWJ9G887K7HGSBERH74YGR0AZ2NTSSZ8NXSS3JMJBKTCBG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "QG3RZ288S22Q8REVHCVEF7KNEF6QNYQ4M2T7CX20EB7HHH773BAG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "BJ5SF3VF8G6ZCZ5CH25EN9N2AR5GFVAF4N3AMPPC40SBCSQ92JP0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "THVEGH9C995HJXEZMV0AP69Z26RXHY6AS7KGJF0H0A7ZFRVP2B90",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "T6RVXZ3YMV53KFFHT98NFPTPFC4H6Y48QGPAFW3JBVPWTTJKVKX0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "KZNJNAA6XKQ99JVM9ZRCJ8MZ42MPWQX2TD6NPR0B8KGXYWH7RWXG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "EBZVS4JEREDSHC8KJG21VD1JBHMN4A0DPH8T0H2C693YB9N7WHZ0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "BTQSRQC7ERPXRFP66NE1KFN98Q7N0CESPQ55E21J3VQ0HRRTDYW0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "7AGZAXMGQVS3NWJ7TFWQAC6593AD64P7BBJWDKRDZ4QZ8QZ90F00",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "6SF5S00RK68RAVJY4739SX8VWN5FXGEWHAPXE85C1DXCZM4BW8CG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "FST0J75W7H8H08AFDHP2Q88GJ8Z5SAN7EH19YQJ6C31W01F0ATPG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "YC246FX5E4XZEQD5XNT9V2D5SPPP9J3ZVM60DD9HJA4BFBZFJP30",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "C4DFKHJWYZK2ZTJ1Z3YN91FVZ5KPVGBZHZTAEGEYNVCM98FQCD20",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "R6KQDA3W40B4H94HJAH07PWZ0JABXJZS90TCHYAM031TV52N5BP0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "RAQ2YBNMDWCFFKQJWTR5Z8BAGP7YKJ6T96HNBZSSRR42NDCFJ35G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "9KSQ49Z9X0YXH64D2TAW2S6EJPB242NZ5E7ZP6CR500ZXMZTET30",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "PPKMAVKC8RT4CDBVJ352P63EE5WJRQHP1XWG3XR3HT7XM9SK56KG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "1YFSMEDVFB5PGW04T0HPB0DNFVBRSW5Y6F7Z41S4JT2X2YT170S0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "HX7R0EWRDZPY6HJH4HR4V957Q1373SB9ZAF5TRWAZTDRQ3TP4SNG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "P9W4FZQ7D6BB6M0H9TSXSDB4EJ7VW3VHCPN4GYKVCPHT40BHZWQ0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "AQ1MRDM6Q95TFKCJZK2QKPPSFWD1M4M8S4B6RPZ1KB3JN9J181JG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "BN8H3PCNG5BZBSYNK2Z43Z25Q5CS65ZT9HJMZV2ZTKHKHB5CDWZ0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "HARKJNGR5NFV87PKF6M1FRH70XREERW0SX31XNNFYN8KVFR8Q630",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "CKJA9E7332B4ASFMJZGN9E2AD33W3BEX05S89V1C3F6Q8RTFBKJG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "GVH6B061YAH2N91SYJTDK5D7QM41ZWN3XA1RYX7D086XSJZASZKG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "VXMPN88WC1HA056RP2GX9Z465VKW68WM0NDXN1BRZ73REM3KQQNG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "D7A037JZP99RN3TZXFJNQJHKTZZQ95F1PK0DGYT2XT0VNN7PJ460",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "J2PEDWSR0KDFK8PN4VC31SA1KQ1W7KQ4H88EH5JY45XV34YR5T40",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "RNSKC282QT24MC33GQV3MEJMCJYHQYSWR6MGC29JJYVCVQTB593G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "S9PRSTN1JQ3ZJTZ3Z1YJ2TBM8GRNHTYMJHC2SGGC6YK87HPPXJ3G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "CVY0JMX9FCZXVNMB4S4SV9WHDW200BK213QPS789BRKY7MD4YC7G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "5CQJXWH3ZSADG272HPF9JA5V31E7K479M2FMDGDE2XCSM4A09BZ0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "FRWJ01A7W0EQEPAY0BT0ND6B7YBRK98YGC3P7ADHH4XWKC5E50M0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "Z2TAQ9X5EA92MJ2Z5K0E7VXEQYGGBCY58RCPERVM2P2WWE49VDPG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "XFM9168FAHJX0QGBT4HCRMY85CKB0NT04X6178DTDGT2T2R03VF0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "N5ZGERJ7ETNMV3QNYYX66YXEK0WAAC5W90DTSWNFMM5YSDT7FD1G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "GZMVXXXGAJPGPZ2284R7F19AGCHR0ZF3590KBVMA5PZ7VR5NCFB0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "M18B9BWETER0BNMTASA9VP0N3PMM46S1RZE0EQQ48A4EW7DVXQP0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "9T33Y3D6VPWWRVDM8YK6GR3945VM4MFQ5N457MVCQNMRCH378930",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "X8PCM80BRQV39GJ365HE8BG05P921TBF17T1X01YJMWBHJXYPNY0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "6HP4RDZ8CBREDVAHQFXXSZ526BWJ37D72GND862844MN2MF9DBD0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "54912W2G34F68A3MTR5XDRRWCC82HJSD9WAT3Q14NM8MWCYEZG40",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "WHN4NVV0ZB3X6G0XP7THCWGG3SZD7Z0CMN0NSWMKWEAHB6HDJVJ0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "ENEK3RF44GK8RYGQFYX23G4B7PXYXYX70DN5JCGFD9X9R4Y2JFGG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "PDDCHA45Q5VKXVHVF8EA0N39GAD8DPF53P1RB6VW14331E9CQXY0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "A5PEZT7HNS6S2N67A92DRG9YCBC5J7HSTYQZVADSTXDGYMVCFR6G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "DCKJSCPVNYE4B61RK9ZAEMNY7F54KBX7V5E8DKT9RC323B7RCDQ0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "W1R1CCSQPRHCDRMCS8HT910VWMSHAYPBZG3A2HM5Q0FYT2BP6860",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "GF1542R7JMCB107ETXDK25M4N3DNHK0PZVN28WY9KXYPYJVDRYK0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "ADAF96R91E5RTJ013NGE34TQJSHMV4K5AXWWT6J8Y5T1963TAZ7G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "VNZJED1MNW3EQ7BCT79J8E6C10QHXBDEE9X709M8H0433Y6AX42G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "0CTAS9XKVC7J2FDBR5HHJTS7B0MYG0R1B6JDJY7R521807ZTXET0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "31NK4XJQG4VTG6ZEVKFHRPRRMZ572X8JJYE9AQX9ZYQ6VCYC0HNG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "APEWZD36K7SMHFPY9DGRTZVH7GX7YA7QMJ1G6W4Z1JJ2E97SP670",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "6Z5QJWHCG4NVBRW4S9SFBMVGRH823R66FV06TYX8BE601CSZCC00",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "EV5SCRQ47546WQ3KRCA7B8CSE2TSGF5BJJ4FYQK52HM0F57CVP8G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "9PNN63EKAJFB6KWKHZRD7T5712DZVKRJX4JKD2FYY6QB8YQHSNJG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "7292HFBJNFH8G9B3TE8F2W8VMZAPHD0Y5XSDAD9MDKREP2PEDP6G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "MEXMC8Z9HZ4PBHM4QQQNE1WP59KKG2A6PV2AFJ9K0D8JFHS1ABF0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "EHKJG3404NCSYMQDBK6JEP7RASM6WPRRHB48ZYD1JWY0M3ZJ8VC0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "63ZTWF0ZTYG352GKDFZ1RKY0W1D56AX63S8J51BPET3RA2YXWY40",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "36FXVZPKM5NF2G2Q4NT38WTEF57KDS8T0C2M6TT58BFPQ7C7NRWG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "7TFZWEX698DJ9GZATZK5SMVHSWMHYB92P92CQG8TZ6N32ZH35SW0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "R8KSJCT2NFTBATZKN6M7BQN8S2MAMH4TC9N2X2JYKEQMV9XKXJB0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "SZ8Z0KS2RS7NXRTVJEE226DBP57BY467NCJ99548GYDFGERNJFT0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "H1D9A50T0PWRAMDDEZDRYHY4QYCF3FJ5ZDTDF62Q457483CN5MCG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "EFQQFHAWPS35HN12V022X50AP4YPGPKX55ZTMM0944GN67YVAJ5G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "0CFJ3QSSG2JWE2ZT4M21KKQ3GYP19JVHVRARM71ZJ62JE42GMD10",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "0T2ESYT4Z4JX3AZ3JDP3GYDZ9W864RAY77STV334T4CSMQJ2BM00",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "10YT3WXY0QNJW2MCFTF9RCVGEX6CKWQNADWK884X5DJH279HJRY0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "PBFYC80S5T8FME0RJJR6JJ2BVJBWG9HDTYJG7TW2MN3JEPYZBAE0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "79FZG4V73KMRNG4GKGJC2Q57HSKZ25JSTPK64SRDDF11JKZ53A70",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "T9SQF1QSNGTTW9RAD8VGG0Z22GDFMADBXAFFF6KQBZWMST6D7F00",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "NM1GA6N9AAR2PNM9XC246C4KX95ZC21MHPP5FZ3Z7F64A80TXAX0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "2WWM7EC9XVBAEBCN7TRPZYDQDHR3RK5X0SS8D967RE8KBBQ14RP0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "T75XY9D4K71FG0435ZF6GC73ZD6KMRFJ405PWZGZ220K4TS1X620",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "3R0ET8N5B7ECRAJZSCP33DWCRE042S1XKMK611C7V0VJWXFPY1D0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "Z3KGX3T977TXSHZQ1M822F5QSZ2XSXMYY1H692H580725F3A5YK0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "TB86YBGP7WHPE2TEDQMSYGWJ9MDQQAZGSTYGR1TFGFJTVNQ96VAG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "A2R3NPMWTXKF6V9E9V65TMWXJ0H1XT4YD0D8KCQZET6HEWX67VVG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "5X9M21043RAY20QBTVWJ9QWA1WEE5R31FCPKM9HC8T7H9J0JQ6P0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "XRTN1Q02RBR0M9EPJZNTBB5T9HC94QFGVSY4VB7JYWAZA0Q0T4ZG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "863R69FPFK1R7GJE0QJWBTTMYJJX5MXYDTSWK94MMM589TNWYNW0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "Q8DYHC6AKHC7CS85PAF8BT0R8A3B5H00F0PZ8VJY1QP98WA7E4X0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "QX562EK2581ZBMYV7APZ5P50K0Z511BNXX70AX7AK5SPZRHW0NYG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "S3NK7HMFJ6QPZTT3YKDN2WXVBKKG1A162AGYXCPG8M4FM97Y3E50",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "K6S4BF4ZQTVMXD2RVAWNQC13C15Z249WMGY23Y0JKEQ3BFE2KDQ0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "8METC0RJ7VE0861YHZT8YVZQ8F3RJXTCDCMDP9P1GH7FA3GFTZD0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "92QC11ZGF0AFN9K2WGBR0SNCNAB48ZEWNVJRZ2ESH8AP96HBPPHG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "XVMX2S1EJ6HJ6YEWDBND3A0R9G87BQRW367GE6NRZRWGKGF2VPEG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "0QZ2HEK7FYWFYK9GA7EPRB90ENDMBRHM9DVQM0EAWHEDMZ3R9ZGG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "S3BYDERHK76XA7QNYDFARW1W2R6TG5N0363NR8PW6F0QTV1NR58G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "YCYXTAG3JB6CS18S53THCHK1DCE5ZKZ4SE0BXJNQAX4JKX3TQSR0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "QB6MPEPCJP5N2K4YT8A1EWMHTE42ZRJS647B90GMSSKR1F7EXTY0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "A2GJCKWPE8NP5F11THDMBGNKJJC12GWHKBWM80RBR4FTMGR4X1W0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "3SYFG08BMT9VRW6W7JS98FSB934TA4TPP8A82041TBPBD0DYM4DG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "BN47H1QPM4XJG0MZ5XKNMYY6R6AN1RS4P83XZ1ZAMSRR41H87P3G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "CX3KR35YHQD7AZMQ1ANZM8M1447GPA13GNPQDPKY23QFH7ACCAFG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "EMDG8MEXCVG9FGWH9WKDV9AFMX8AZS5PGN01P0N37D92XS3RJX00",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "46HTK122WRSXDS82D877SHK7X9BHGPK8KHRTY333JA2D02VEYMTG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "EYHSF8ZRDVBXRTAFNA72HV9T3AVWR4GMMX170RZN6BNRYKQQ5SWG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "TE5H9EP7E4H9X2V777JA683Z229SXBEFNA3TQ9A8WBVP7Z0MWVNG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "CGPR1TQSJ0KGHT743Y1G02VHYJ3GPATS54QRAV3E5XYQGXW711KG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "B2V81QPB7T3DHBCAYJ6AEV1C5EQ41GGP3X611RRTDKNSSKXH70K0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "4MABC7CYPG5FWWN6ZPF3P9MKRWSBSS3PSEB8EEEHSFD408MDJ4D0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "AVY3HHXRDD3QR8MC19FDP6V7WXNQ82ZH84PRM4TNMVBFJEWSJCRG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "HWXB4NX8HGEQDY8C4F1P1DDVHAAAK9E8YD1MZR0W08XA9YTR9SRG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "YSQQKNC1X1GX8DWKTJXYQC10PCE1V5W36BSNA7Q5D4E8YX92V4C0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "S2GE5FADBPXRT04091H9QTY4HNHW81T3C3AQ89MEDSA5NDHHDHXG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "YJ375Z9NTB6DJC1XYVCFHF4AQHJBM16N6B8N3WQN8E23AVX5JZA0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "WGX6NQ3R933JK3J4P5CVV2C2KTN9BRW9H0SJMM9ASXAQTBGF61EG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "ZW0GWP37TBQ0CCFXEG12R0TSM51JAQCBNWA2FHKGZZGV95QCK3F0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "BPYDG93N8AWW2A00TJRAXE0X7YJHJVVDV9R56CKW7RRQNCXRX2R0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "0ASCG912FBYWYGXNPWQ7WHZCANTF4KZPY1JNCBTFFQ984B4KFED0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "F54NPHAAY2EZKY9ZHDJ5EVZT73QVJS754DSG2E9KXPN0A1N7560G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "SCGE6RPN942WEXGT87ACW2T5A99YDFFXAQQVNSRGG58PBE1CMA20",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "RY9BGRQTV36DP6CDAEP90YDZY7JNKVE40ZBAD2XKVXHQ1QCB2QZ0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "FETMWBDAR53P19N3H8NJMJRS0D2BTPYKXCQTBHCX6EJBWTAV0D3G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "4F4AVFEWPMQHCAN5Y7B4N3VH6S2MJ577H8NCB37V5CYBQA539TA0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "09EWDW3S46MG1B6XSHBJMS1FNG1J85H1HCGV8S8YN77ZFGC61QK0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "XQ5HFHKDAQNBKWHVQVCRWKT4XDND60B3VT0ZEV08E3BZD70BA2CG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "5GX0M78E60YVQ82VZ36M4GFPQ33ZDXFSKMKNTA2VYY7T76ND8SCG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "6CHH40JP8GMYJJ19G9QHEZZCAFF1JRAB6MZR51FNK3ZQEJ5R2Y10",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "A76V2FDBP3EZKBT5P6YCJXQH73X7K2ABE3DJ9C8CZ44GMFYTJRA0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "W0RWJ2Z5Z21SK6TYMRXW2N5GDPBXBQRW36X2BXPDEQYT1AWGMEYG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "AW0GXCZGRVZ4ZG1RWVS3JVT7FGP9CKH2SV1NKN9QRXQEVGGSGXR0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "MR288XSZ65313BN0BD8KD5QZ5R89NQ277AF5WNX0MJYJWJER3Q80",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "952NF7PZMHRCYSKBDYE4Y3M438TZNDJM9T85F80X7WKWE0AXD6KG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "ZXPYB7GNH578RJVK861EK8X81T2TQ1TCD7Y50ER1QSH4CXAMQHA0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "HESSVCNM6WYC58GYKG4ME6MZWN8C8YRBSTHGYSG8X4MBNWAV5M0G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "QZZ1FZVFNPE4VN0B4XEF5BHT5MKM9CZFBH4JMS9FHAQG8R74WDCG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "8FD8NCCNYM2461682WW43KY1VZE6FTB67DXT7BEAR3CXGZVTZRZG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "X3MEH9JZM5RBZCJYH8GHFM7JGC8FMWC981525DSADYTYCNTS3SAG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "VYZS03TB7SVGMGYQZBJRBDJEAYYKAANARRPE9QWC6Q4TYSPNPG6G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "S2YV13BD8X6BQTZW0FPFXN6064K97J4D0YS62RF0PP7XW16RVTJ0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "2TQM5J443EADA2YRFDEHFQ1TQGK7CHZXRWGBB8NW3W1F0CSFWCV0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "T1Y35C2XMH4VPTH76BW0M18PCHJ5T543QWQQYR8468BJV5NNBVC0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "XYTKMH78YSQNCSM8D94A4174JP73JABZ03AH4VS34DT3JYV9XPPG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "801Y8ZM6WV78P20HH4R6SZ5EZRDJFWEST5RSFVWQMHJRK9M8AAJ0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "X49NQ85YMXHQJGRDHQ7P8KZ5X2C50MMCZBKKXBJYMX9WPTJHY9D0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "HKP3E7XTFBZXP95PH4Z9YE1RPKNF1ZJ6Y497ZJ9GYHP9JMVX0N30",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "SEKT2EBMWC379288ACHCNJSXNWQ1F333S5B04TRQM17NP6XSEHWG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "97MH379M67TZNJSS2F0QNKBQ7DX9WX8K21Y3A9TP6RPXW5HEKRVG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "36D46BTJ71V704WM1AS3FRVH6F33GGVQRCS1XNEKR9F0XC5PAMNG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "EXX3G37FFHP3QAXAGHJ7DCBQADG44R1T5TFBBE4P86GWXWY8C3BG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "WAF611F18ZJFV0TPVN4JDFBJ5VQ7DGV7YGF881GKN3TSRDQXEK40",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "J9M3JDJDMV29SBMPEMDE5HTZRYYS4MRWZBF4RMZHYK0Y4JTK44Q0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "M50RGZ0PH2QRFJHF3PFE1JBKM437CMB0401HARWYQ8NV5QBYSPKG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "7BVPB0XWJ200Z8HKZMPHGXDAP9B95GD2VYX0VYX5CBVB4RKDTG3G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "VNDX56Q6W5RBESEH8NRBM1XQQX3TX3C258TH27BNV6PSZZY279AG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "6Y3136FPT91E2724T4FTTY4SS7DGB9KK8GB40BSZ8TZ8FCT6FS30",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "CJRRZ0S47W89M92YZ8HREAS7P61NWA6ACJD5F4Y2NH3P8YWFD4B0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "TMMX5BA6WJ0M6CJJDM6DAV2D4M5QFHN5YE5KQ3CAKY824E4RKPB0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "TJGB8AF8NMDVPVT58ZYDM74VRA6BBRFG4Z2761FXYRGWJVNJPYZ0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "YF29DCF4S38TGYFBCJR1D55T8DVZQ01XYN3G5W1CT1438T8DCX70",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "YWJ3GYPG00ZYRKXTJP2047JCW36H6Y3NMFZEV5RAE581EKSNP1NG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "Z68Q27CBYEZBT8ZD43VKY5SWS05K0DY0WNEGVPK0QAHE8ND3127G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "S95N1VWDXN8KDVK09TFHCCM05VEBSR5JCQBYKQXD4DJS3EBJC81G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "T3EY154881GJY3YRRR0RNV8RGB1NV8S96SWGW936TMTMFE6AB1ZG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "F5FZ2VGPZXS5F4CY2ZCGY49J11RYRNWNWGCTF0CMJPN496A7K960",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "52MME29FC243FB4HZC4HRART8EX3Z00PKS7BTVBTRSCRENWSC020",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "4Y16BA2NDGV68R0WN3R4ZCZW9C68Q79534XGHTNTQ4SKWA0D5BCG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "KTPRM4J837HHYJM3VBW59Z4MAT514GMG6EPN3T8EK4RRT2SZ5240",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "7VTHF3229S2CGP7CVPWDGHAY652XSKVGMFGA8JCYETHKER9FH6T0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "BVQT07KTD2K8WWRK9C1SBW5V8SDXE2AWAWW801DHMDBGBF0HYWX0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "BXFP998HBRG30RHXWVHDXE434NGRF39R3R7R5SSJMNCHMKWCKSN0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "D9QG6Y250H76G7913P9M610AHQXH1AN0QGZT1NW2MCJ6460WXXP0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "H7KVTQMGQCXG4FKEFMN2NEESFDGQZS1185D4H41HWPD8AQ14PA60",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "DA5DZMN77B79K3Y7H07SN7XTX1H91ZJ62PMXFFP0KA6JXJAJ7XJ0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "7SQ0DFJF126Y72YEJ7TH6THDMYXKSNEBJ5RPV0CT5SAR6VE6DEB0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "KNNYCY6258D9JQ0T3DW6X201EYEMYCETNEC2QCJRD7XHEJ9V0C6G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "G8T9ATAJQSCEAN6TWMW0BVNBCKEXK83108TN20QRTJR3RN1PR1VG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "SB1716AEXB0K44MWGCAB0E2QYWV443BYFG0JNBDG25ECWGSAGFJ0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "1BQGW59MZJCQMSRNA0AJGA6M0DWPKKZYQVZCW3ZM1Y5GBN9FJMD0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "8AEBK5G2HPWEDS9AY1B569HCPVEV6QEPS5M9BB28WSTR2NDZPBZ0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "P08XKV98Q3HXM0RPQXZ2VTFT2CBZY2W0VJGXW8PSHS7JNKZBNBE0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "D8RHFG1BYH2EQQQSNBSWYNQ2CNRHQNK682MRY70W68KQ24B51EXG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "W7F0JA4AAFCX2Y7FKB78KZ94W88C6JCA3V9P7FXG6FK01J07CMW0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "RV5SNA1Z670TKNZ1MR2Y51XHGJBS75TR49R7FX74KJ0DH17DY9JG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "70DZ4D0228DAAVQZKH9JRKS9XF6C74R18JPQWKWANFYHGRZ4VBJ0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "TYQCE0DH59H1PS0YCYJQXY6DXZM7T0XHM6Z6G0C44Y8KQ1MC3YA0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "NRX8SEB5PA3KW124JB28Y5DJM8G69D0TA00DJ3MG2NGTA7D05T30",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "4PCX5KM2H5WN6A7P2E8NVYJJCZMVEKM07N57W3Y0Z24VZA20WWQG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "MZEBEZQ7QWE1SVF8Z6FBESC8T73H6WQT4PM46VXMBT0FVB4SNW80",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "E2PHPNC8JMAPPX54ZT36MFV3DCYZG5K504AN77G6FQYKKE3MGEYG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "3HCD5AGY29004MEK89Y13B3BCEHN45AAX0RN1V15SSQGGQPRQ3DG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "DKBNGTJC4RZDZ5SKMB16BN27973MQR1NAB3ZXEDGPZD8DARGXJ3G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "ETQZWR748KFKF37JVTKK0G8MD72K49MS18FA5GA5RZ129T45PT20",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "CYQX1M38R4Q551Z1RFE2298WSTP7CDWF1DBS5TTAAYD5856A1340",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "EY3KAE5B64S2MXSF0CM2BW53043KX19FRJH3DAQK9J26KSKE0JAG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "68HTVMJGEPE25G6ZVFMJJAES9SKJPK0S40PEHQD9S89VF9PET78G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "SKH6YXXWSQ1ACQTJGMXVPF9JV2F5JEYRXHC2G37E31TFJ3K00WBG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "7F0N7P5NX4JMQ3BHJKH83NPHKZ6NXDV39M3CEAN6WXYPVJ947J4G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "ZK0S8APWSQAH4SSXK62B2MMDJBCGNYRVX8ZWWVAD6W13W2TPCK6G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "Z116P9CCR2BM6ANH32RP5NCCJQCBXR51BF92WXAQ5QCFR28G9WEG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "MWT808JVRRC0CKDBPJ0ZH5TSS0Y7GJP22RTY6AKN0XHWRE9EE2DG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "YK7RGXR8K1X60JM4P56CT6FFST7Q93C0JZBWPWBXPKHJ795XXCAG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "3VQZ59VK97KW2FC1V6PME87SE08PV2JQXF0A58N75HGQ9N7Z09X0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "12TQTR7S0SPKZGM5J38ABWJFQPJGP7FQPXSR4EVMESGXVR9MVW40",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "4RK83SFKBMQHSCE78X41GEA4C41BCM31V4QG3BX6NKDJFCPZ2JJ0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "DJ23WS41K0WAGJHNN2AN2PWPWKT2MDBEZQZYV1Y8EG5SK7QVT9E0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "EV12RZ4VFESA955ECKECN9T0FSA9VJ9ATP1C5A50Y49WQF81JGTG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "VHHQ2PTQY19VRFXTP9FQRRCYR6TXXG19TXNY5ZG7EMBA6FC27650",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "882P8FBMXWHQNFE8NE7C0EYQRY0EA3NYTWF6X1NHTNBXWEVGVEG0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "C1AFJC4TY1WK0RKR3GNCSNWVZS252GCR6XFS1EKGJX6GTH9M8KA0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "WQKEAX2GVWBK5WV0D4024P4BTXPQ3S45V8ZVFMDV0BR6JPFWGVKG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "SPQYTY434Y90W1C66ZJ02MM12GDY25W6H888T52HSYCQX2XVSHNG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "JKARGYTZ9ADYV5NKWC1ZYZ1XSRDJ8YFFSW39HNAZ254VERS4HHT0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "HT4W86SEQRTA7CWRAFCEZDBVXV6QTC9ZJSER4JMJR8KY8YE5T310",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "H03AJ2YZSCQEZNRAM4AF3MXPKG75ASXDCXDAS707YFQ9YEB6WBHG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "9HB4Z6JYTD02X86T5CEX8NCVM9Q1T53NMQ22KHKRHCXK5PZCMCDG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "X9RA7KC7028CESCGGBSTHEMPR3Z3DMPWVWCQEG0DFQF4H6H5MKH0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "JH715AFRB15ER97XW1A4V5TQ8W40PEM13J5EDPPF50XWPTQ8D49G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "N5K826HKNQECFPVGQTHJ2WXVBFHV02FFGJTDQ5CBP2YJPB0GKEMG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "NK3BH5MPKKTD3F4B87ZJ4H2B9VJVF3E47GRWYV5EYK6YQRZZABT0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "90E3Q0246ZRJ7AM5N6TRF5CDWZP366VZ6294K0AGYGWVPM3DV2QG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "QRG0BFBKJA3MAW5TSR0YR7GMJG2E1YE435W7YXXFRBAN5T5VDSC0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "VBC96W50RJ8R2M4RK7VEJAJFPNE6YWMRNB9DG0RG0A55HA6HBZY0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "930WXATKP54PMHD6RPV0WHC05AZPHZ6NYTR8WJDKP1ZV3SA84B60",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "2AHZ7HV4QPKS8W9FPW91REFGP47SH6BNRCBGBWM3HJCVC1NMZ9F0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "EXCJQSJ6FEG8HHC6FZH6VPXCT8QAT3YY2DH5B010M6N5CJF0DDDG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "RY57YM23S14JGYRW4WVPXKPW9NNZF2TYAQGDSTCX8GRA333HTV8G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "CNK1J6PXSY64H8ZVNMGWSC06NRADW4R3PWA7QE6ZH0FJZX2S6Y4G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "MWFR8CW0CPHHAANRZMQ5WA33FTKBEMEETNE9JE7H1S356X3TYHDG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "STMPYZHMY0P54SKN176EMZTSPX0JZ0T8H0C65C832KWZQSQQZR9G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "2S86BKA14CRMGA8J21524T1FGZ5MTM3GM9RQ9JQXAB3J17SXFC7G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "1YFQ1YEET7R4M46RV7AW3308XJJ3SH5GPD9Z80SFXNQ811EZF7N0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "KGTKJZ0H3EN217QGF143XA4QJZE2R13TTYPRRYR58PQBHPHF6B10",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "D96QM835QM1QQJZJPMT205V8JC8GY3WGG13BA1145NZAV60PK3V0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "JT4VS59T9ZYMD84VWDG00NN3TQ7KJFYKDARJ1SZS6XGD4JF02040",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "SN9M2Y9HGNED55KCV029GJ96SQF517MYPK92ZKVPS3BPV308YH60",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "4H2AXFTHB9AMKKBJ4V6A8XMSVNFQ1GPAFPRHKD1SJ9N5SPG9YY5G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "WVQNP69JG5XFY5G04W67MZ6QVTP33H1YE2RFQYEK6Q817FXS97W0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "2MVVVXTG09DK7QTGGSV3ER1S5SK4DV75XJ236THKGJCR1Z00TPJ0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "83T1X84DZ7XZTCRJ4SVB1R9EYM6NFAYFZ18SVYMBQH263RBKRY20",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "N7S1Q8QS53Z8ZQESCC41PRCX0326M4H2DS5HBEZBV0JMBD6QVCP0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "WZQT5S00Z3RY0VB7XVKVYGFBWWRKZ9XZ49EGAQ1A4SX2A3KQNZQ0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "C5YEBFX8C9ZAXZBA64XKY1T558C7YJXNFZ0KVJB29FPP2ZR83AJG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "453WE9ZHTHBR31PFC7N3Q3DKJB374X093KXT2DGEY63TZPRWFRFG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "XEJ9HJ5W226TXAQA6CFP4VSHWTR1QB2EQ702JK3ZQ08DXQCBJ6JG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "BGVCYF1TZ2GWHMXFES9A2X49S90S61GVM8AEDNBR92QCS28HMA9G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "47DRDE056NDB576GV3HK4KMHDEE940V45JNWG94CH5WNAVD008BG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "K7VFDPD2JHBG9ZJV9TFB0NWCW5XR4A13EJ9R8FZ3T9ME7V04Y1F0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "YNSYRM28047DA8PXS35YYYHEV6GJB4EP8ZG3GB0GQ5CBYSDBQVM0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "Q49G173PXAHD117SCEZTJ6N7YY9WDXVWTVN75KPHG4KQNCJYR4FG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "0G5TQN0R27QSBVHG84SYPFE4SHWJ3KHG6CH7VN32BB2ANQTT662G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "4540R77BQ4CYFHCSNFSYBMYXF2Y614KSCDKEMX6KZXN6VF4AKFTG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "TTS79B6JF13ZR1WZRF66MPPBVVX1D6QX4BQ7JAGHSWMP7RS9Q6G0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "EXC4Z403H0W55WQN3M6MQSWQKSB6A6TMMF2MSJ1N1TDBQYD9F66G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "TSRZ41RAKDE2APW2ND4K5GKFGWWS4Q3F9N4ANAFPJKBCV83NH730",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "ZXFWNP3P02WDDEY077XK0BH3G2T2JQDS7CBS033HSJ47AM0WJQP0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "5Q2NYW74JK520H4VD6GV7R1E25P0FM8ZNS6MW7TFEAEVTFVMC380",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "E8R8PYVYW565FN0QQ45A7D8BS88DXERN1XJ89T59RVA7B5FN4B80",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "80GGFB7BRZHFCHB4C8YP7MQ5MFTTK1N30TDNG814S2FAWPMKDCCG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "G6FX91APZCTGJHPEV2KY1F9SRV1E6N88XV5TMS2JQ6BBF1RGGB00",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "6KH7X4QRB18F64JFHVYXMCRXYT17FXXRFKBSNTGXW8HQBFD9M5F0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "864PYEASTWZ4G65S01HC3ZV4PV9R6VRDBX88266H3V3S2GG1ZCHG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "20FAPCMN6VXG5KMJ9C1V1E5HAYJG9FKSG53Y3G3PFBKJ7PQW176G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "C6METX2B4H1TW1MRKA2P4RGZE2GPQRRCA05S5VD6ZFQCAA84X7RG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "17TETBHGA1ZS2D1DR35KYM9DEJH0TPP3B7DG53DFDXCQVJAJMEY0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "6B66QME25XESKDJ9WBNR7K3GQ378A0MRZSF8ZA8NQ2JD9PSHVF10",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "Z603HRD2C622SZ5HN8BDX0N6R7DWBFA3RPCE2K66F2PSA9NKNXD0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "TZZYF6Y5GVV9T5BXT75WTZW11B4ECM7K1RXNMWG4TJ63GNVFNGTG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "H61XDR8G3D56BPG2GRB4WHWET8DQ68EQVD94B9WJASYM95BEYYZG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "0GX4P35R2VRXJ2ARJ5F336791BSHGHXZKDD4BRPTW5RYJ7KDTE2G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "TVQATKNGF8FZCJ963TEZHYVRCBKZPMVKFH8NGY327AT1HJ7CB81G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "XQXXC823PHNR2PKJ4H3SYQ4V9HVKCT2VWWZBHH8PK4W5H1W9VFE0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "NVEATA9RP21VP5KVCF25R942C9EZ197TGTKY0H8QETXQARE7YH0G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "CV968YC9T0KF165M1JTFA4X7KQRP3SD87GE7B9D8S6NH0AWARA50",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "5TW7ZNKVC0NT6GA9R2CAWGTFEZ4365SSW5RKG0A6J0D9JS79BZ6G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "VEDG85Y30ZK8PZD7SCQBBA0Q7NPN3BEYH3XSE424KXGX0BAW1HAG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "HHT87XXGJRHDFV5FMHQAPBAM6YGSF8ABBC2HR2R4SM3838V1TQA0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "1G9TYX7GZVR7J9EAN3D0KB7WJD4HXJHB0M2T4W4PMQZEA58EQWPG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "11CD6K4VY8M5256PHCS10S0C6347QHVRGW3H8MNQ611AR018Q720",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "C5B72X9TBHX3K0PSGDJ0JV4GAH53C4S6QC4P1H0SZ55GTXK640TG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "D2AC53HMXM7YN5QHYY1JFH4QEBTBBFSSCH98E513S4XKMM7RCV70",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "GDNM3VDEKB35ZSXTASQBE20RS4SWEJMVWQH8RR78PWFTHX6E3HKG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "CRBJQ9D5SJ9DMBN9M3SA7AMH6YC9DN5FEY6PBFF4MF1YGWWYDRC0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "SZHPX2M9MW8AY8D726A9TSABHYDXAK30MDZK44S7YH65AM5NGPH0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "DBSK1HFSJQ2RTVPBFR5NZZKM7AAMSG79Y1A5ZTCECND6CEZP5W10",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "30P8HMEYVM9WGKK0B5GPJWG1C6P1CH0BC97636AJ8Y1CNWKVF57G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "FF4HE6EYWRD2KBQSCBRPM6T8YZVPPPS05Z0NYXKAA1SEJRCT596G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "AGR1HYC0BDCH6VNN3W6VGAK7TDFYQMBSKQZ8JVT1ZDRWMC9WG2ZG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "B6JZ0GFRABW28SBB8N05KG10EPZ23J2ACFNS7TEQY699ZA5FJN5G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "GKFAWDC2DBJ4H28V1RQFJEQJW8K2XEG56RRCYGRRV55TEF4YY4W0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "GDFHS0302C1A5ZR003W3DHQY5BPPNYXJAAH6SS0ZM31FKKT9MN7G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "49K6RSABMMHCCF2RSJJ9Z64XEC9C1GJC7RTM6KTT21W486N3N6P0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "G50M5G7P6BEWD0JXNMXTK1DFNXJMQY6GK3ZM0NAA82SM2R7QYVN0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "49W1VWC3XDXHRYPVQZ6BV0DK3FHDCNKFH50ZDAYA9TXGGSNMJ0KG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 984,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "CZHSG3WFWG6HR8AKXESH96SXNEVKTNRV5NGWRFZSDVFHSW0DSJ8G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "D30M1WJNA80YP3STAZR5E4Z2F7211KNKCY46AWJ9DWM5438ST650",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "8K6A7E0WNDPZ5N3KY84GG84BDNPEC6JTYZSREK9AP51EQZPZS480",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "2MY2ZZE6FKA0H14WFQ7P0WHHHD6XDQFMZY0YZ5SZ9V2K898KGKV0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "520V1JVTBXEB0BYBHSXZPHZAFN8NPJFFPNS58RDE2XP8ZYJ6NC2G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "242Q4C9ZAYWHP81W3A8V97F9GDC38CGQ7C297D1AV46Y1Y094EX0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "RQE062BQ5QD9GYXBXBBCRQY4J2ZX1Y4WWDTFVTMAKNN2R4CAD820",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "P41SMRP44TFB6ZCHGKKTHNFEKF0DQFD5Z6NF2AW0TKSW68WGEJN0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "DQTZNBQ36TR9QJEF6BE76FXK6Y1RV2V59JEY099X6AZ562PYSR0G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "ZV65EAWJRKZ3DB1VK3XY589MR6BN139M6DAC0MPFQQF32KG4TJNG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "V3S690CQVC0QNQJEFQJCQ1XM4QDCNV9FCCTJX3NVV459ZXNG8H0G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "S4XVBMN6RP2DSCJEQCK1DYAANEHH51VZZJGR795SBXQR7Q9VD20G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "2ZYBQ1YP7K801B0X11VZDS0R0SCV7976QY4RYC9GSYAB7GFW6AQG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "YX8WAAS8ZE3SF1GA6RW20WPQCADKVJKQ0ZDNSEAPFZ8WAXVNYGQG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "CKQKP7B1TC7965VDX6PKVGR4QR1VM2XX7NXD4FR7SNEN66AQ12A0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "Z0S0T1STGE6JBDWGXX7HQW5N6JCTS06Q3B3ZWTYEF0KDSG428QGG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "R9V6F63DXF3H4VHAF53MH7X3HWPKJDCRKZ8K23NH3568DWE9ARWG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "17ZZXXPK862CH53GM499AAMC8X366WEV8MM1R5YB40ZGEMZMP9GG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "H6Z94C8RCPY4NK89R0P8D8JHME4J3G5W22GPBZ3YST1Z7ET99NQ0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "P5YSBPTVBB7YFHT3FSCEE3KHVNR34QMAS636A5G12K7D83T6Z61G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "7HZ2N88TPZXKB92HJZF6M6VWB7MHCN4WXCQYA9ZPP8H7KBM8F1YG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "7TM1P2B6A755ZSGPTAN47VF0Z99ARMWHFW6RQY9WSYV0QBGZ4HJG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "KMZRYGJ57BR37EE9PD4NR282MMG3NAKK3QXHD658RA9RZXJE14FG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "G8ET6HCD1XKT55NTQ4F0VMD8RSFCCVZ18DVK0KNPFFV0BBG9YXJG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "BQJV2J7S8H2NAKS61C1FXE1YQ66XMMXBCQE9QMKSVYJA6VHW2KWG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "5Z4PRB8NSZ8GAKJA44DT8RZRAN7JA2QWTFAWZP1TB3DJM4RSTTAG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "D2KBAWH5RGXBT520QD6AZ4WX6QX2V93Z4YCRE6D7Y4QW4525FCZG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "3QFN10MVAM9552MXSFFRANK1FYKCVZSXJS99FJ1Q2F4BF26XFGT0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "3Q201CHJ6JGJW8716P01YCADPX3FT3X8N1H3GZQ7GG16REXXBDZ0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "Z1B0BRYTDXS0FBYQKV935YV3R9JB1RR7EA4F9F5PDK1YWMSJXS9G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "B3ZXHTDD8VH89J3408QJKFHFTS2MTKFQHT21ZX639QX80TAF8D9G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "ACC4VMXKQB9DRN0SE6JFP41EH4WVQPHWC9KZXD02H90GRJ3T2XD0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "2WZRD7Z77Z41Q8ECZ79574XKCDV6C0Q6G16D6Z77MWHNFXB49G80",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "GDK812SS0MTZFP79EAFB0H4MY04PJG6CA87HREV9TBN4JZTBR59G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "53P6SHJF48578DQ51847VWTJE4ESPQKBVXZKF5VXYPGZG4SDETZG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "ZX4DKYQ5EQ6FR7CDVCVEGY25YXNT2V3CB4MS6AE2Z5NZJDGQCNZG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "WW01K0E63446YNMQT7SKA4ZZ5MFX1Z2HSETR499Z44JPJZWD1ENG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "77ZNRRYC9CHE6Y6WSY40GE3ADY6SFEM6TX69BG9M98FFJMGNM5R0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "SXVKZRQP28MKAA09W18Y6JXJMC9X0C6THFJ4BM32AZ9JWFQPQQQ0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "EKXNHJRTFYH1KXTAE22NR6NDV41RBW0Z15GKBSDZDH6F2DDMGFQ0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "JG1BX8YBKWNZ9FJSXPMTAG8BACF50DPX09NSMVT9Y7G1X32ZXA50",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "7HJ4BA719SDK39TWRTARB261Q0D1SAMTSE4HT6ZXGM9WBSX7BCH0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "WMCWQM7TZKZQVDWZP8NNGMAY41AEYQQRGKWSQVMKGQSMX67F6440",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "NDN3HG4F9KGCZ918Y4E6FXQD2YRM1FR44FH3R8QZ5DZVWPGK4RMG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "KVKN3DBA2HAK5WKB9CPT36G38FR7XJ0M1A8924XER7TKHH0NDGV0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "D3303VVYP801KFYRA0X7EMY7JQHPJY16V1Z31BKQPFZBKC1BE4XG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "VMV1MYKK83YQ6YT1H5N4J478YPXSA82MM8KSRKW8MEVD6B122BA0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "3YVAG4M41SP85PQ2GN8HS4PTP1118M04HYJJ601HTA6MH4S9AY7G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "XGJK5BEJ3SZAC72GZK3ST6GR4MK43EKAQ6KWTTJEB82A2W7K1JC0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "BF6GRW62K7JQP73CWH0R7T1REAZSGKRSBVTZGNEJK1RTZMR6KAP0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "CM4SVCNFKH9G5NZT92V3W2S1RZMR21J7HF2GSQ9BC879WH8DB800",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "7WQ33PRC9KQPFX3XVZ3WRG85S3ZQV8YMW1TWQ44VE6QMSH6QHR6G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "TG74MNQXYFXB48Q7QJCM0TCXVGZB86NG2FKGPRTFAVANCYX2NVA0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "BJ0JRZHVJB9WR0WV7GE9K0VJC6D5XP40MKHYVHBM2CG7WVYT461G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "A77RE0TTARGBKT74GFDSNP8YX0ZB40JND33ZB3GDA01NR1VK68JG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "4KEGY9RZCHSS2PTFXQSHEZQY3JME6SKQGC5HVAJ6XEGNQGWXMSNG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "XZ6JM3Y6SJ2ZVVTJHNPMVB4Z69K779D35S98P2REYAZ1WK50S8F0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "FR8S9G61M4P519N8Y401N8BYCFQ28BD35VFPGZQEHRQA0GNP2DA0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "Z51D421JTKMT1R30GHSE73DXTDEBVAH5ZC1PWRNG24KSHXQ33R20",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "3364WN57PDSJHW7B72Z4JVYY9W72FN6KTSH050SKAD133RS2ZXAG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "PSN7AXWR7FNYB84YV0MMRP904XXWA4Z6QFJVGVCSNQ6X8E86AMNG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "EMR074MFT3B03G3AKYEVPMWSGKN0DYNDN8YX841NZK7M9FP1EJT0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "1TXTYW8V4C4B1NC6YW4603N9XGBBK6ZMJMQFWWDN6GGQ3Y6XQ5Q0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "P3XFMQD4P8C5QZ3TJGD3CBP9152ASBHH4YTR0SSPN7K70VVZEJQG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "TM509VPF71HJS7AVEJXKG1BNA7C7VGWFCKQVX891NM9H46MC4QM0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "C7G769HA56JDGM6SXB3N2AM7154BE7J2P8C4EAW1S46SG4J50Z20",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "V4995XHNSX7R7RT705A11J3ESSCNTYNDFQV4HFEBYGD8W3X6RCS0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "6ADF9XYB39ZBN5SMWGR5RFW5WNT38PM18WYXBVE7NX9VT2XAY6EG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "3RKRHK9D09KTAM1429FNXVAC1Z5GCTCAGSYVWYR6NXDMWXNM4HM0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "Q6VFT4JQDZWDV1BFXYTF3ECQT224EZV77XJM313Q2TTB6HV4K8B0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "5ERT0JZEEJ1RM7S58ZGAH0WBSQFZRSG0P8PGPT0BXX18XHZQE4YG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "T6VHV2R1RW9S5XG4QSWC238NJKRD2KT0BYCP04KQHB1AB31MV2P0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "1D7W7VWWYGVCY6T77FMBV1VDDDZAZZ1VM7WTMG9QRYY9K1Y4KY9G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "21HA5RGXQHT1YGBQYG00X175NPS21MH12KVVRVQQ00HB56HGSHVG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "3FC1PSS26WYHHNCZJR3X8EX5QQNTKNRMZD5RKZ1WKEMZ5XHNDWS0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "96XMY25V3VV6J577QM8E0E35EJ59F3SHMJ2VS2HTNFQ0D7J421HG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "GYW6MF9TP4YAA9QR88CFFYCGWW83P9PCASAWZRBYKZQ4QZ83536G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "HGT6T2Q63M0XJR9AYXERRVX0KD9V3SYAB6CR940EF823HG6G914G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "A1KW7W4TX12RRVT4YMWGGJ5E9W7CR8ZEFEDMCJG6H3NVTWE5BG3G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "WY2Q4JKW3HTEXQD3Z57SXCPH2XVYF529X54AATET0Q52BV947Y70",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "3BW5SYW143JWFM4NACQKD4GDC2S7X890NMPV9NQHNV6QZM995AN0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "2QEEEN8X3QSAEFDH21TM55Y7BDG25PDP06R3P8JW5F9VWJQVME90",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "3NEFDYK4H9GRJFWSF9VDY78N1MA8W62B27VJJ3APT6WEAB54VQ2G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "N66MN29ZAS6NJQT73GDFPGJM1082XTWZESH7PENW1XJCD5FY366G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "DX2FF0J8B223JTNX9F0Q6FBC44W7QQPTAC4PKQTFKH0B2J58Q51G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "JHRK8NG5QCZFR55MNWR3G97PZCSNGKTV8FCH6BNTJCZWP9WTAXA0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "RRC95ME78NQ06WQS5J14MCWTW13B00QC4AMKVR0ERH4DVJTC9HJ0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "MAK1QMASK2TZF20R7JT1Y3PKAK1TDE068R42BHBH1B4Z4TNHNFRG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "7GNZPGXFTGR0TEWVRH8M9DD8WBNK7RNP4BQXXQ873972MEABXZA0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "3WPW8AJ37YV80GB25JF820V7X7YT1XGMZ9ZP4QNZ03M0XE7Y27YG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "T5ARQ4VVWSSC995835AZGJ5QJF8JQEAQYJE7MZ5XQ0MNGYM3VAB0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "XSRAP2YHD0AKJY911622KR7PHNMB1NXQGVM969K16N0PWV8RV56G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "QD7RWZ3PW6TD17NDBZK7QBS6BJXDM7T6845C6EYRYPX0GRT5Q2RG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "1QKNEEY3CGDTGKD0SPBKYWXRAGKYC473K3KNR2NWJ3YD48YJXCBG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "1G1VZXKXS1KN2CVP6Z7AP0TX8DZ3HSTG661YA873PHF25029V5A0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "WGTPG5DY1E7506B6BMSEJJV2907C6CZK1P6YJZKH8N7059GBH560",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "G9BKHQKWZ96XAQJZWNXPRE1FFS6QV2ECVM84673PH62XWFKAK470",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "3FKYX99V10HVCAVWDHR0NJXBPQ0H51PYJEKNWP4NP1VXRJYJN0S0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "3Z5G33TZYEMN5W486ZNNVDMWSZFXND7A94D9CFGSP0YZDC579QKG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "7S7W2AFTMMCD5TCTM0YNAGFEGFEQ4TDEBFJAY6RAANB4NPDDENHG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "RSD86JKXCQQSQSE3QV4TF4D5154C4H8ZDQ13HDX38P1DAGCTA110",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "60QGXAGGJ8TC434XSD0WKVT421JFR8SKM5M3N0V02H3DYEA88TZG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "5D52C57EGVQV9XN2PA2E7KK85JTGDXTP86J5ZN4T7C827ZYPXCVG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "CX8MK9V8VB2BQR77DPGQJC8Q0Q87QDS9GBGXYBHHRAX2CPJ0DQRG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "3JT1PDAXVWJSGRDN51F48D8B4VJJACVJHJ9N1PV0Y0NCYMT1A9PG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "Z62X4KH6Z04DVTAZ4WFJZ93KR6TMXZK7727WAN855RQ4EJ5MRK90",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "6RTCNWSC0SFJW4MP3HB1SS3CKYVYF1PEQ840TT2140ETG37BYBWG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "MXMNTAN306HTCFEXHZA1E9HP9YRY50PX0H6ZX2K7Q2ZZ3WT9FYPG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "ABFQG5NR9QHSTN97A20A114GVTY35VSGHWW1G815Y5WFF5VB7VKG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "P4Z849141H998H966NXBKNP42Y534ARPGYT2XK8208T1XSR2FTS0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "CGP54WC3TVTFFF9YHTJ606JY1QYX3F81N5FYS5TSVK8NRYRCXV20",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "71AX1W2FMCMHXR3ZZTCKEQW3DTKZFQK7Q0B1MMKGKQT8AWMBXD50",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "2NVKG5BX0NVEGX3JB2GPWARNMR765STZZSJXCDVW3E1TK6RS89NG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "S2BBQP40V98F1D416C5BV2GM813WR0YAQHSN62ZZ9NWHMYYES3WG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "YBGA9NGWHCN27738RENEZQAKCACY58RJDQ7QK88N2Y68KXP8MS4G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "X8FK1CKRPJMHTR2MS5BVVY9VSXDWT52XDVVABT7Y0G6JZTQC03W0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "VE0KT9DAZ8QKSWZQ68HWEBNAG87NQ47YS79QBHW6BPNP2JMMZZAG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "P2QJHNSQ2YHB6C2W7NQYTFWKV2DK7PJ8XR3A60HZ9PS18BSVAAS0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "NX4WNTDS690JFCGJA1AQNFCK2E0YVFCAGGSXC3YNM7EJ6XFTRKBG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "XVTDMPSKCCVJ7E82J2DS13HG9R4VXWP4WJPGBVK6X66C7HHWMCA0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "TK325T42JXQ0AC6TJC1BW8YHNWWMRF7RFNJRK0TN1R5QBTKNK31G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "EMP65KJ8CGJ78HCNSZQEC38Q3469QG90Q0TZPM9CW7ANP5HFQ3CG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "29HYCTZH165NDFJM3RXHPP4W3021QCMVZSR9RY5MBHGB7JKXFTM0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "N34HX54PC0G10AT0E12WWY602ETDB8SES63BJ7AV2NMVQJJFV1A0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "4YP00Y5M6PBMC32X0MDXW0863Z7EF6H9MFRCRTYNFQ7FMG80F2G0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "64H9NC8V5A5AE9ZJYSSBVMPG0H54BSCFSBAF7J1YVECFFZJWN6QG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "YGZ80JEENCB11YJ0ZW9V9MZPXPB1ZWPCYNW47749RA4BNJR0H9D0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "78MGYYPG8YF4A6SBWD2879VKXRZP2VR0S6J52YF38C1W26VSS9RG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "BWW93KMEY7CY1PTVGJ7J64E4BN2NPPYMME7NGNZMP06ABQDF8T80",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "WVYY9E3KQNP3QMAFDYS04A6Q8YD0D5G6XGQVAVA5FVB99BVQ9WT0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "NYGW6FKPTHDVMN8YB6X6YQ8P3AF8K6SYRY95FMY2BF9G0TZG5BE0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "3ZG5YTZ38SZNMGE7X1ABN692PR6ENXTC8WZZEVXTZ9H14QC9DDQG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "R1C6S7X8MF8098VX6XCDYSE8NFD3MHCFXTKK4EHJTG8BYQDAF3VG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "KK32AKC8ASD7YB3SDQ4AN5Y0P8BDD9TY4JWPBHVG307CZJ4GPJVG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "ECEK0CG2D4HTZTAP9TH9YJ1GRVWYEVYR3GTQ8SCN93TBN4EAD7V0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "46KVGCK3FAWHGA417P95B88NB1KMXNRGCA02BWYY6T0E3FZVZCE0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "E1PZH83SJVRN3M0ZDWWECKNEXNC6EWABYSPJ33JT1F9MXEBDR9NG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "12ANM629642YMC0KBC4CME6G1QHD0RDTMP62GANW2MP7SA57NFB0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "4TZ2M9R0YZDPZG6M7Q34Q6WHRF5NT7P6VTHSSDQEKTKR8M0M6KJG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "3JDVTVGSCGTSZV7VE4CJGQVTB2CEX7NRE87R3REMY2EG87Y0K00G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "3TF3ACRQBCJM2WC5977BH6TN2DQGGH2PTDDGT9JEMYQABTCMECKG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "J1NGE0R611Q7EVR2N4V0EHD53RNE7YJ6C8NQWK1RBHV6GSB5Q3R0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "3SR9XWM0CZHWBPMXH7FPZ8DNHNTMSPQGAZCFWXA16W1XHNNK9PF0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "8RZPYN7SN3CWZHAV4P2TXC7V7J2ANJ1BN6QZ5PHEGW92NRBM4SP0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "70HN6TCDE1HFQQS8D5KVRBVGT977RRSHQBAEBGGA54BFM8VRRQA0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "NHAX9C1NPDTG0J6RT8NY2T674J11EGZARRNKSDDBWR35RS2A0TEG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "4DSW8HHFD2WF50FQJWHTK6P9J2YF4NWZJT4NDNSSDZ7E58X799X0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "3DJJDJCJB8NHKM98Z9CM9YC00BTABTRESV3T878ZE61FA25CYMB0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "P7DMYM2ZHAYNQFQ8DK943DGTKMV9ZEV46VBCSW2BB7DMEDP7KMXG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "240M4VSBN90JWZXZVYVYQ4G11PVR95X5BPYSDP0GHGVET95JN1K0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "0W514ED2PWEPRNNDVNDNMTC3QXEJYJVFTBAG53HWTFBBQKMPXYDG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "T9WTPWA022C5M333MYAN4BVJ1EH14B0CXP428V8XZ603HA2JE5MG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "20NP8JJ7105BBZN4YA5W36QCBZPZ84WH60FTT82YMRMMQ35RWR1G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "KCF7CDCN6TBY058GH6RF7Z49XA7YE9MV0MN6FJ9X9R043AV49KVG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "E0PTYD9SQNTBVDN211S20C8SRGYJQAHXW2B4CYN3FKSP0GKV4S8G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "Y2GRGEAX2BMG813G14CTMVPH1NZFC816DHGA5RAZGHV3G7S0XQAG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "NY1MW7XK5F0N97QY1NR6N75NFMK8QKDQ4J1AY1JT3QJTM6FNCJ90",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "8Y8Q89NK348MAVWM16NDG8NBQ560EZJQZ14CXK9A6CN0098HFWS0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "H9093N1ZJ1AB9X09FQ3AG9VN6VCQ86JDQW362WHSSX3EV2AE3N6G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "YM8N2R6HG8E9MMW38HEW50K5TG4F40MAFPWY3E475QE8CEM6EF30",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "F1Y5ZR8JQ59M4EQKTBB6GJ2C3063325XWPKJ3284PYJMVXBQ6490",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "6NZ96G3CZAMR4JTE3XFP1369S7PCTNXWAHNGE00X8K1B4QQ6TJV0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "WS2PYS56WSW37GY3ZP8KGM3AZEGBMWFK2E48T0K5B1VFZTQKZEP0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "703XKDKFGAWE1K4J3F3W7BM6W49D8M2SDKZ5MCBRTBQ5VW8QKS3G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "FBK9J3R58YK2D8T1ERQR4A8E559S7DWYP5TPYWZDZPM1WZMQY0R0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "PKHX116QWYHA711N1AY7W3MP2WFH55XZWH0QW03PGNPBKJY9SYD0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "1245P0M5FY7V6GM1Y6PA4ZTATS3MG7DZ80XR5EAWZ4W5WVK26FQ0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "SVJ7HH6QB7BZKX0M8A24C6R6RZQ9WXXH0CEEV88TXRZA0X79ET9G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "S7WK9TK4HWM2G4RC4N837JATB40TT1SNF2CVD3SWG7503Z6EGPS0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "Y0TMD5NFMSE6F5655PZNWD094QTNXSRZ7AX13ZE89FSDZJ2XVB0G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "PN4DHQN9SGF3GJYJS98MV24CQPQ1NQ0NZRFXZ4JJXPM8WV9RNGXG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "HND4WFNQ4W0GS8F56N4VMGRTFCJ1ZXKKYE35AVWVMRYE27V500DG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "05FYC5D9HG6Q1DK3EDVVN2K6G4BER38TD06T2147GAAJWTHG6PX0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "QV2413JZ55KWA0W76ZYBPB9VK0899KTWHFX105M7QT46B31B85WG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "R3HM264PNTSQB3BZKNC1VEGD7NC08CDS8KB6TBHR67Z92GPSSQBG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "CJM4ZAF16JJSTETYSFGEN4B82G0W50VCCQZWK9XKPSAQZ8EZ0JJG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "0W5ZJBN8JM1FQVCVH8YNGXGVEN1SYGN40NVKS6WG2DMJYMBP3BJ0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "ES8JE82K8BMS39PVS0VYGVG7E1Z8Z01YPPX4AVE1BYYBR6XFG150",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "JV1D51RCQ8Z3RQJVX56RRKCVERQJM4X62GZTHZQNSQAQ6SNVW8FG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "2VKN6VWY0JDQWMWD72RX0P1DFFTYV8006MCDXCZPER7EAHTQJ2PG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "PJFS3HQ7MN9QMB279E8YH7FVY7P89MNZDFTPH4ZXM0TBCRNYTGVG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "WKQPJ3MQCQKK55DNZZT2P91WF1H13Y8HH98TAEJ6YH1RW4SX0ZN0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "76AWG0BRVR1MGGQ8JNHWSMAHDTP1PKPW4EDAAZ0N54VM4WNWVJ2G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "VY5DB9RY44BWGX8B40YNCGEC7NZ0E5GDER1GQ32X6MMZQAQDS750",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "RAP5N25JG1MPW608CTRB4840S30NNSJJNFDFP9NJCKB3FEK05CA0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "0PNY3860HHWTY1C16KTMHRQ0NP6K8P05H1FCHFR3H4BQK04A8NH0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "N5DK5GS4QWEM9XXJYBA9YBB8J3YTKSYCKX7JGQ5NAFMDNGMM2VG0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "1KMGA6FD3AEDS3AMYMNQ11M02YGR2SSC1BS7TD233E2GR8S17K90",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "E9Y3K5T6A54VVFP20YBP6JH5FR6PFAA4S3849SA156RBNKQV6030",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "RXJ1CTJPABDWR2WA1NGKAACKC6CCQDQS9N3Q3DCZQ9GGGRGGSR6G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "FC7CSVFKFM31Z83B5KQGH1HPSQDEW0ENXJVEAF7P1T3EJVK5BPW0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "3Z26ERDPCA4DS4WKA88M2003PRN1RK93X2W3YY549JW024VM87J0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "B2PMFA3W41F2YMPDXKY4VW4SS3RY0N94VS3XVDJSPJWKJPQHRGP0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "0JZCPKYXDF3EF2Q82PCXB20PTDQF1WJE1TNE2XD8419H9ZZ0NABG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "XCKNX0CKWQWCSD345WRSWRAK6YFH5K4MPQ9GMYT734M82PXGWKKG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "VD9SAP0HRR2Y85Y7JC3HS0BXNPZJT1Y5W7HSQMF1T7BRFDTK8H0G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "5MHRG1D3Q5RYZT5MT69Z71994HMD0VN5QAZDPBC0W8Z2HT59VDYG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "YFKB0GVTDGVZBHR0K0CEJ8F4YY86KH4PCN36ME49YFBXW4Q1Z34G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "1AESTJPMEA0G82K8JCSQANJ1NE65X0MDKCAWTPRPRW7YSYHGTK70",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "97Z0GS5BNAZ98FZ15JM35D1TCYSMFNRPVD4W9DDRX24Q9QDBB7AG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "AJZY1B9EGGDDW36N417QA52KZ2M58BABJYAFYW6TYJ20HEXFCGHG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "KW5ZYTWSXDY1MCQ852FN624K3FJSFD2XQY08JVG83QXR7Z1XX55G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "T4CH1TXWRKVXZVJHGNEPM0K34AR2X65QEKPQF8V89JC7KF8GBX1G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "KQNW8R52K40RZRZVE6ZABZGXYRDW0Z1VYVKW7MSVD66ZW41YN1VG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "MPBF7VP0BK9954B4YQR03YDVDT3QGPRD6M602GS1NT089BFR8VR0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "VA86EG0VWBKB9S9Z0Y7FS9VPTHRE4BAXNR2MPC56ZZFSC98PZ9H0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "9R01CD9RAKVMR703K5KAG7SWMKZ9C5NWWZQ76BXNNWZWE5AFCGN0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "F0QV8BX5Z8GPF1GJJ8JCNRZHEPR282XAYVA48HYJMME1VQY5WBAG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "GD4QHQ32CKNG9DGVBRVA51GWHBNR1CWB8PKMH2ZHKHG7TDFF3J00",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "ZDK87K0FF5HP0GXFNVRCR357V843D2HMSRGC4TVQ47M1ADW8YEXG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "4VNV55Y147JWPCBGJRSV5489NNZF2QG00SEMFVNPNEX695KTM0B0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "V5S65H3RT9BCT4ACBZG46AQNCH8M4D6Z1GRS1HZSD7T4TJ5WYPC0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "6WJ10Z8XA996MHR063MQ0TQCB9B2RX1P00YBM4Q7CE1B0DQ9X3CG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "HN1B4Y4N2HTPWN9XE278X3XCSC1K6YZXE1Z4NNZPMEW27BYB1A9G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "YRHSX1CS3102AWGA9M34FBCTTPJQ7KNFXDRGK373FWVAK0K4V400",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "JW5KA38H36PD28JGC8DQ5EWH46E6TCSYJX4QJG18TQBCVYYZV4BG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "0DQCS3557VXHD8A7KC6EE63YSRZ301CMNBJQCCVKX0DHSCGV2QC0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "018RPWC95NWG2N1HH30NEMSEFEW53R1R995PRZ67PQ1VG0RQZAY0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "KMDZGBABACQ4CGB6FXKC5HK9PAQ0D4BY6BHXMNZ839XE7R341D7G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "5Z539SANHVG2YSJF501YTDNRWXS4XN049DYE9JFHN408NH4MAW50",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "50BRN6B6C6D5K00AKME93K60EW5ZM0HCCNQDZPPYSY7TRG0T1NZ0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "0NSHYHGRZ7CPAJ8KV58RSB21A9PTEAT8QH2M7FGK3THHRKY8ZEF0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "SM789GCHZDJ6PWS8F1NRX4821A14W713EYF462R48CMMZ91FZM6G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "2YB6WBDWJ0JE756P3W03SHTFJKJ18W1ZF6YD7HZKP1E9E958VM00",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "YGWJ3SA96TBFSBH96AS8RYH3H0Y784WS77RJD4RYB55JMDZK6550",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "75F99T7QZJ6V5WCA9PNQYHJ6WEPX7B8TFN6DEB7YJ6JERQ3XF8SG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "FDMMAKTN26ZAW76ZMQN6909Q8Q5TD0JSY1827WGX0T46WTCAWRQG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "MZWBDCZ7C14X7JJDJZ6SHVF1SEFBQ5F9HQANDJFMC6EB8DBJE55G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "V870QC3VH1Y37C97VYYZ7FCJM3KZQFYPAHAH5684D984DWDHY1B0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "YNTVB7518A2031615N1H1ZM3JRJ0G3A29C8VBCCMGJRYYSAGBFWG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "EH06D66YDPSBZYBC8P92FAMECTGAB0SGNWK8TG42JBBH2A2QQQR0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "KBV9W1H2D2G62XA392C24JBWNY2RCKEHX75MPTZHVMD6HDBN89X0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "VA7X5JXZ2XPHX34S0RMT48PAZM1MEGMVW082X78FVKT181J3RY9G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "C8R5JN6DEC8TY8TR45NKBATHRXZCM9Y41ZVMJR6HJYWJFM6DEFD0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "14CWK768S2PCDT7WBEN2MA0FRQ19WYYAQGKPS2PD1QW3HJD129G0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "0TCA87BDGM7SHVCMSB9R9EA21QKB0HC5W2YZKT6JGG3H1226ECMG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "XF3QYVTAB07RXJX0K0R3DHQNRDPQNJAW09QNABKQ9Q21GE88EQV0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "XD91Z84AVANJ74DJWHPW032HS3XXJB5R1NMPV29A8M0ZMFKB7B60",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "Y30581BW1GMWV0WXGJBWVCEYDBGE97DEYVNM1A4HXKFFYPW5Y0GG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "QSG2NKAYMM3PTTTAMCFVQN84BG5TXK3Z9QVETRQK70P743MANQX0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "YWB3BKYYT45WTHYTC49ZW37MGHBAH97Z8FE8P2EMEZ6DMNN7C2QG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "A8RG21XFNKW34HVTDD85AHBF1VXC4N78F8Z0J899M0KF4NYMTFJG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "ZN1PXHANJRYQFXCPPX195Q61X1ZSCYBVXEHHQS832YHNEGNC2EJG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "PKPTN9CVBQRJDRTCP7WGJTDDYNAHC42SJVTK1Q9DKNXXN6NP05W0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "03Y6Y9XHNTHVSJZY5WE11N2SRTBHXFP3D9H9V354V2FYFMVFXB70",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "ETSVYVBDAC68NHTPYAC9TD8J7MN2KNZASA7PFADRSD1B9TP2SXPG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "Y4DXGPFX8QBGB0NPVFCXTFB64R7GT3W8538PHTXFXNKMRD8VMH60",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "5VGH8FD9P6G8H3M5J7FYM3VYBFGC089MQAY7B69QY74TS5FNE89G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "TKM29QAFQ48YXNXXS0NZB1ET7RNAC2PWEB2QWXP0CXFB1S393ZY0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "YFZY73DFX71SB9Z35W04KABJ3KZR8KCM4Q8F405VHWXSFP0QDXT0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "WXEB6GNY2QW601E996QEMC1ZR19JD7BY80C0ZP4RJZF96CJGE17G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "0TSQJH2AN46Y8G7SX3NVD4CHBZBWE9513E3TX4ZGE7BPHH9DBM10",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "2GEE0EWTPCPD87RJSGVS0TSW0MDMTNH1C7A4B8E1S0N8PNT7XRQ0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "WB8YMB681DJ8HHWPAYKVQB8F0AP5TA1MPDE7BVPHCXG9PZBJ1X90",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "0394H8JYQM2C2T1M19C0YME4KCTH7E29TJR97CX8QS1W03MK8F4G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "MJSP3YBVXB8EBFE70YKZWG9ZHD4NQ7CER68TRAG71H2R1RJQRZ50",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "818R3Q5SVS3CESW0FPV9JRSWJZCCH5TP3EXHHF2QVAJQKAATKC1G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "17M30VGJBBT62KKQTTWE2JWX8NVHCF5TPM534J52MQJ6DMVQ10AG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "6NXHE0HGTBJGW8CT32GAQAXT88VWBRGV6WYN13EX0NGEKS9VXHHG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "QTCPYTC6TXHX8GCEN4MDFMHN0JF6ERQX7YJQ61618RTYER1HHVM0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "W3TSHS86VYJA9WR7M6RBEY02SHBHA60S8S466N66ES3K6RX912B0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "FR4CTMX8NX3MAYR45MY3NEK7WB2FGRG942ZPDMPRMFZHNXG61BRG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "VDRQQMGRDTD6N8CASR5E38EZD2Q9BH1T80Y4T931Y1QQRGQHWN20",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "4BZSAFH9TDKK76VWBXV0BBS4PWFJGE4BE2BM81F0756786Y92AN0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "QG2F6JYPBNRXHYEPAV1230JY2RJJT9YQ5RHT7BY3GKQ86H7BWNJ0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "HTXSF7VDF0FAY0SYAR7AKTD06YQ4KVEDFYRM6DPT55ZGRTFBH7X0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "Q6W6QKCMCBHGKVNFZR8G4EYK9E8CR63V0ZN3KHDDE7Q34E9RJ5V0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "4HRM7X1QNJ5R597G7W18ANJ570CH3SFSKZ1R7G8AQBATYS4PT0MG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "T3TX15WSFC6B5K84WN5T31AF25REMFZVGEKD812RT5HH70ZXJHHG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "80E5MYTR5XWJJECX6659DK4DTRP9ZQ34SZR404P3HFXNEQ0AKFHG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "MAVY2Y2N883V443TGWPGK9GTVQD63W7T3J5519X83CC1VDQ60D1G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "QPGNDB3XP3DZG8VF0JEPFC1MAG7VZPV3XWAMDQMGDW083G5C11R0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "BH5FPZTDJ9797W1BG1WREWXBCQ2VDW9ZY89AHVMBK5NAC2YG2270",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "QDMYJFKZ0MQZTZHGN8MSSKMJBMTSQ4H7HB33REX1KKFXZD5WZ0F0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "JPQ35NTEK00M9PHPJX6XW7YCGJ1P9CHHVHBBMKXV1BY3C7D25M7G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "SR9AJG9K0SPSH6643E27XZEHEPPDPME1D7E4HF0K8RVHYPA575FG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "HRQGDEQXSZK6MNP6EHD7K6DAHYTW8943Z98PKEWZYD278FW98EPG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "V2C8JNPMF1H3474M0RWZZD89J3C9SB2ZDBDQV822P57MF14PP8FG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "G74PT57V50VB1F7K7HG1FENXMH7B4FVGG0V6GMRAVVAWZW6R7170",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "RT3KGZ76C3GM31RN2GS25407KT3BXMDBR529P2X844D7FSE5WWW0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "RKNQ9D76DMASP74R4CMT65WBMNGNWSHNATPJW12G7HF0K19246FG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "9A01JGYM3DJ7QPWSZJ4Z0MVMJQZG6CPAKEW2E59YA0PP4QABCMK0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "NBQ3TDKKF9ATB8SA31JBZJV9C5BAECB6HDHY6A3GQ9WH335PFVEG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "YZDW3RHY1WZ1EFKZVBE25FR4477G4FZ1W36PEG8VHE5P8CVDRX1G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "4E24TZXT5B10R927MYZGXYYN93EQN5030Z0G81DDWS1GC2E0TCM0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "JYYSTHBVBE5XKHWRPFHTSTS01STNF2VAFW789MKZG635H1FDN8SG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "PS0GPE2WX1ZHCVPYDSFQ66ABYY6D0YKF5PA13BG1WN704CXSAX40",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "385JQHFA6PW2SR43AR84A40T8ECCKCS0TZC11VKDSRMXJHJPKCNG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "VFS2DM86S18X2NWEQD02B57WYW2E2ZZKJGNQ9QMM7K52R9RQV63G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "KJCGHQR3DYDYWWJ560XCJJGKA6FY8V87G3NPJWQY24JC2Q3FM47G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "36YKZYFQT4ACM91B1EKY5F8HF3JKSHBTJ6N6BHP8KGGQD5WT4G00",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "T6T4G56HJ0E4ZK0A7T3X3Y8XRTT3DBT1F9GRVZW7S58CN0BYMB9G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "8GKJ6SGW3NV57AA2X7H6D3B51S74H74V53VJNE0A8CKM7E8YR9A0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "KYC8YWPP8BEJSQCDE6WGFN8237FZXGMWSSQEYRDAT5RCN7RZW2F0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "NJY3J8WQZS2PM33N8TCN161WVB8P15SCR410E416NJ03KN1F1AMG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "D37FBJC2Z1WNZVZGP7AFF7SDXRWVMMAJW7SM17KZWQB11NQFQR7G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "TJ7HK4A3FQWYGWZK8YQZRVQAPXAR3W2CWES1V2TXZHC3HZPD5YD0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "004VYVFZMR4KFJVDAT1JAG7W8HVJDHCAS4WD6DVEZ06B88VBVTNG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "4W0Z0DZKM1VRJPKT01EHHGX4XJNGJTKPBEHVD0E6BD2Q4HNPWVKG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "MX1ADAGS43V6815TTTN70YQH02ZJM429F18D6PPKVT3HM4977CMG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "83XSDQ8DHN3MXB6HG0KD273B90NEFFJ9SC3830TJ5BCF5SBA6Q3G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "79ZHFA6ZY5KXSEWX94N0MAYA14PCBC8Q718HCSXHGA42KZ5G1EB0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "RM9242RDYRR7FE4F9CN69KH1YKM90Q9E2JTVHMSK18P6XVCX74QG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "E4BBRRG1Z2KSPJP5P9YWGK0W2FBW3VT8TKMTARR4S75XD73N2QR0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "FE5TXTFTAV0VBFD1CXQ0T38717DG1P7C51RJ0MYDZAFMMPS2NTP0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "G42X7JN9HN35G2SJCYB7PE6GH0VDPG8QQB965S3V00RKTMDKJKZ0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "33BJ1AZ37W9G16HHX8XQQEV83V364HCXTNG1FSJWFTMV7YKC1AQG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "Z3AQJA64JVYYF0V3PH73GKCW5QSNHRHTAZTC3BKRCE380CFFV020",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "NN4G5WGDRQW2RC0PK45V1YZ98EW0H3DHQSWZP9JKGEM6XGKWD0W0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "3YSC3ZFNHZ6G1APC88WCPMDGXA9SXNG3XNC0K6VZGA33FSKPDBVG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "FBXWPAJZBNMW08GG8WKM2NXWH53DARGG780WMBVG9804E7WJF0XG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "VFQ2Q9ZABKFW8TB45QGQHYX3KAMN1MKXA3VN63N8CQH8EDY8V07G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "D0Q3NZ37638KMSR7P74EFK2XM4EYBTR6GKXDZDKBYSA57F2CCXM0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "CSD8AE34FJG1RSP7YSB92H2MEECGCB7121RRY5X487ZEP1RCHWQ0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "APSFE8RP0H4HYCJT58HVJJBPTSFEGH3P1NQ86ERRZBYH0T04ED3G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "MP9TQ8GEG5BDP4M896A2YMPZQCXPDNMM8AT6FTNMQSXJJ00DFJM0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 1000,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "68QBV99WKFRFY34PKHS2SRKQCEMQ6CEGHVW1P6BEK65FR120TT7G",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "K9DMHQJZMMHWBTHB0N327SJV3AAVPSF6S16GB9MSR91WF6N30JY0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "6R78RF722Q1REGBZCWJQBBPCJDAD0YJ1DKGJ1WMXK925A33HAK00",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "BD7HVKVRA7RR05K5MGFNKVJ6QN91REJZG6TJRQPCNB3W23QFWK60",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "AQQ6Q6YH72BDSBPNEAPJ7A0YQ457VHAFGK4A5ABP2PEZ4Y3ZM890",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "5W6ZM3MDQ4QWP5SW71JH8MWTN43QK17Q8EHGEDB58FDWK8HDW890",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "5AKSDR22Q7MXS4MKEV3DD70K0APGVMJJ7NQCSKYE79MR4WN1WEB0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "CPME271SE6RQ0BDAN3RKR8GQ2042230KMDTHH82FPRT589GJTYBG",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    },
+    {
+      "reserve_pub": "7CVBX01XHV2JWB5FY9HA7PKWV0XM2NFJKSFNAKX53WATFMDDAJB0",
+      "expected": {
+        "currency": "KUDOS",
+        "value": 904,
+        "fraction": 0
+      },
+      "observed": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "diagnostic": "expired reserve needs to be closed"
+    }
+  ],
+  "wire-out-inconsistencies": [],
+  "coin_inconsistencies": [],
+  "reserve_balance": [
+    {
+      "total_escrow_balance": {
+        "currency": "KUDOS",
+        "value": 768512,
+        "fraction": 0
+      },
+      "total_withdraw_fee_income": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      }
+    }
+  ],
+  "aggregation_fee_balance": [
+    {
+      "total_aggregation_fee_income": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      }
+    }
+  ],
+  "report_denomination_balance": [
+    {
+      "total_escrow_balance": {
+        "currency": "KUDOS",
+        "value": 65488,
+        "fraction": 0
+      },
+      "total_active_risk": {
+        "currency": "KUDOS",
+        "value": 65488,
+        "fraction": 0
+      },
+      "total_deposit_fee_income": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "total_melt_fee_income": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      },
+      "total_refund_fee_income": {
+        "currency": "KUDOS",
+        "value": 0,
+        "fraction": 0
+      }
+    }
+  ]
+}
\ No newline at end of file
diff --git a/contrib/samples/wire-auditor.json 
b/contrib/samples/wire-auditor.json
new file mode 100644
index 0000000..b81d486
--- /dev/null
+++ b/contrib/samples/wire-auditor.json
@@ -0,0 +1,4175 @@
+{
+  "row-inconsistencies": [
+    {
+      "table": "reserves_in",
+      "row": 192,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 233,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 75,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 282,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 361,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 275,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 458,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 234,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 716,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 586,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 176,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 330,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 696,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 815,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 500,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 252,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 135,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 397,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 786,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 621,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 532,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 337,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 721,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 633,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 146,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 161,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 300,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 666,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 415,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 573,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 460,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 339,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 3,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 61,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 373,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 648,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 443,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 285,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 165,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 755,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 376,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 540,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 214,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 784,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 736,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 766,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 215,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 662,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 462,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 255,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 94,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 780,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 515,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 529,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 419,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 39,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 123,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 560,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 2,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 811,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 683,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 660,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 358,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 187,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 538,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 632,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 559,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 86,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 49,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 332,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 594,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 566,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 659,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 228,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 626,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 162,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 527,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 320,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 713,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 743,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 248,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 459,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 182,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 291,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 191,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 81,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 717,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 693,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 159,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 571,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 829,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 557,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 266,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 294,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 601,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 674,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 12,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 70,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 669,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 753,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 226,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 67,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 724,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 280,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 307,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 143,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 142,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 169,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 37,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 516,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 615,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 308,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 388,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 719,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 577,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 466,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 40,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 801,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 765,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 304,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 237,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 687,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 225,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 310,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 639,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 288,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 493,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 561,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 194,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 530,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 473,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 85,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 734,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 16,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 32,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 630,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 732,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 193,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 58,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 756,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 768,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 273,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 111,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 287,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 329,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 798,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 587,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 24,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 380,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 240,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 550,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 539,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 14,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 93,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 402,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 352,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 481,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 504,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 597,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 556,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 708,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 414,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 612,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 694,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 469,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 712,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 108,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 63,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 797,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 271,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 463,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 242,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 788,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 438,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 232,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 427,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 749,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 783,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 74,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 514,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 269,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 372,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 336,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 545,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 431,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 444,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 474,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 150,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 624,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 396,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 52,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 406,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 823,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 803,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 217,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 4,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 385,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 62,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 92,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 185,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 441,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 382,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 640,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 644,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 112,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 564,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 546,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 518,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 118,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 486,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 430,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 691,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 476,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 521,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 690,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 574,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 31,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 195,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 149,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 775,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 211,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 277,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 383,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 425,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 638,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 728,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 374,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 34,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 445,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 246,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 116,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 138,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 186,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 347,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 387,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 657,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 257,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 593,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 315,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 678,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 89,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 497,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 88,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 370,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 153,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 457,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 661,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 824,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 137,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 110,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 122,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 168,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 747,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 750,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 55,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 344,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 84,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 447,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 124,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 461,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 549,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 606,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 468,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 283,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 665,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 284,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 386,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 525,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 831,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 377,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 609,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 570,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 109,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 148,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 318,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 622,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 113,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 297,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 245,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 433,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 517,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 528,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 33,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 507,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 56,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 80,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 647,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 429,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 720,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 25,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 483,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 27,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 477,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 730,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 177,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 592,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 311,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 326,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 354,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 9,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 567,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 48,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 679,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 196,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 652,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 764,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 96,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 821,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 548,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 792,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 171,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 77,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 272,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 718,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 689,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 698,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 82,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 141,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 655,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 375,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 351,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 298,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 204,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 772,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 295,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 366,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 658,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 763,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 488,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 725,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 305,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 512,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 793,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 809,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 543,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 741,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 407,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 107,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 46,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 356,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 472,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 270,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 535,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 256,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 499,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 230,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 317,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 787,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 224,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 145,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 22,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 66,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 551,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 758,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 428,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 11,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 263,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 279,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 132,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 501,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 184,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 353,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 244,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 432,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 794,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 365,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 201,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 247,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 363,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 172,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 378,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 379,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 205,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 18,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 53,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 79,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 759,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 547,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 5,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 774,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 642,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 697,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 555,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 342,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 631,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 748,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 579,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 744,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 519,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 554,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 218,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 767,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 26,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 267,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 492,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 681,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 575,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 506,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 754,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 781,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 757,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 101,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 175,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 817,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 738,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 126,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 833,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 264,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 152,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 729,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 90,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 411,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 209,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 314,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 654,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 76,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 254,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 580,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 348,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 178,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 45,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 220,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 513,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 139,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 389,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 727,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 663,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 684,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 785,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 322,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 369,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 197,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 437,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 119,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 381,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 250,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 544,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 578,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 649,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 808,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 673,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 746,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 537,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 711,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 319,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 440,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 151,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 588,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 453,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 582,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 834,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 331,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 563,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 413,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 505,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 274,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 705,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 790,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 174,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 216,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 219,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 435,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 490,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 395,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 827,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 221,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 391,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 147,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 482,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 820,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 87,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 324,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 416,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 686,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 13,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 723,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 213,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 627,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 65,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 333,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 6,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 44,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 259,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 349,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 448,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 590,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 819,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 789,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 503,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 296,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 286,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 17,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 183,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 832,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 249,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 421,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 158,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 335,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 133,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 394,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 471,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 806,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 299,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 702,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 465,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 313,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 552,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 95,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 620,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 384,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 610,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 253,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 393,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 104,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 208,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 778,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 584,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 618,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 188,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 761,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 522,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 403,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 818,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 599,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 289,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 569,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 276,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 495,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 589,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 360,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 115,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 452,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 140,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 212,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 591,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 616,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 68,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 733,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 164,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 302,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 456,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 170,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 368,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 189,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 390,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 714,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 485,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 278,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 704,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 364,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 646,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 822,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 401,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 268,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 676,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 737,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 69,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 762,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 509,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 399,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 524,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 779,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 494,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 701,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 602,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 553,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 125,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 442,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 156,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 523,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 645,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 613,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 656,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 357,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 520,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 120,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 321,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 498,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 636,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 199,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 312,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 328,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 752,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 688,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 451,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 479,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 251,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 751,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 436,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 707,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 362,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 731,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 97,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 796,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 629,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 664,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 38,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 542,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 651,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 628,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 814,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 478,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 10,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 410,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 136,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 583,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 715,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 671,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 709,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 699,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 408,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 470,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 334,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 166,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 484,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 129,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 338,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 558,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 8,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 131,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 42,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 309,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 565,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 99,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 562,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 677,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 355,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 637,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 800,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 598,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 650,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 350,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 359,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 572,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 20,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 78,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 340,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 179,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 541,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 341,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 585,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 1,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 409,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 685,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 345,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 98,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 239,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 316,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 568,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 480,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 617,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 327,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 190,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 202,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 64,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 227,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 29,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 160,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 28,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 464,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 802,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 144,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 668,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 236,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 91,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 449,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 813,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 812,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 290,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 607,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 508,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 412,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 782,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 15,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 670,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 773,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 830,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 243,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 534,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 455,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 423,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 799,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 206,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 600,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 635,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 771,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 35,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 51,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 760,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 367,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 398,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 603,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 222,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 595,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 536,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 47,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 198,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 292,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 740,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 281,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 675,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 641,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 643,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 770,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 581,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 60,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 634,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 7,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 323,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 117,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 400,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 526,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 739,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 262,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 805,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 420,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 36,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 114,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 604,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 810,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 826,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 102,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 614,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 229,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 181,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 241,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 163,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 238,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 103,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 346,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 722,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 203,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 450,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 265,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 510,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 306,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 57,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 816,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 703,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 424,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 533,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 576,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 392,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 173,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 50,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 128,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 619,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 769,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 130,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 59,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 710,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 653,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 726,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 371,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 106,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 454,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 605,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 426,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 667,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 293,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 235,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 467,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 825,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 200,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 325,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 531,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 745,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 475,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 121,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 496,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 611,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 502,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 71,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 210,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 422,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 487,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 804,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 672,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 260,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 30,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 41,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 795,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 343,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 231,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 72,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 776,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 105,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 43,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 54,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 489,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 100,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 434,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 155,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 73,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 154,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 23,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 742,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 680,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 258,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 404,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 625,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 596,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 301,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 692,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 439,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 608,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 417,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 807,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 791,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 223,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 167,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 623,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 828,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 303,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 695,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 405,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 446,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 735,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 134,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 21,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 491,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 706,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 19,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 83,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 700,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 127,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 682,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 180,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 511,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 777,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 207,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 418,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 261,
+      "diagnostic": "matching wire transfer not found"
+    },
+    {
+      "table": "reserves_in",
+      "row": 157,
+      "diagnostic": "matching wire transfer not found"
+    }
+  ],
+  "row-minor-inconsistencies": []
+}
\ No newline at end of file
diff --git a/doc/Makefile.am b/doc/Makefile.am
index f8c8741..fe997cc 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -31,4 +31,8 @@ extra_TEXINFOS = \
 EXTRA_DIST = \
   coding-style.txt \
   $(man_MANS) \
-  $(extra_TEXINFOS)
+  $(extra_TEXINFOS) \
+  docstyle.css \
+  brown-paper.css \
+  exchange-db.png
+
diff --git a/doc/exchange-db.png b/doc/exchange-db.png
index ddc2559..421e594 100644
Binary files a/doc/exchange-db.png and b/doc/exchange-db.png differ
diff --git a/doc/paper/taler.bib b/doc/paper/taler.bib
index db98865..0b67fa5 100644
--- a/doc/paper/taler.bib
+++ b/doc/paper/taler.bib
@@ -216,6 +216,7 @@
 }
 
 
+
 @inproceedings{zerocash,
   author =      {Eli Ben-Sasson and Alessandro Chiesa and Christina Garman and 
Matthew Green and Ian Miers and Eran Tromer and Madars Virza},
   title =       {Zerocash: Decentralized Anonymous Payments from Bitcoin},
@@ -335,6 +336,40 @@
   year={2015}
 }
 
address@hidden,
+  title = {Practical Compact E-Cash with Arbitrary Wallet Size},
+  author = {Patrick M{\"a}rtens},
+  howpublished = {IACR Cryptology ePrint Archive 2015/086},
+  year = {2015},
+  note = {\url{http://eprint.iacr.org/2015/086}},
+}
+
address@hidden,
+  author = {Sébastien Canard, David Pointcheval, Olivier Sanders and Jacques 
Traoré},
+  title = {Divisible E-Cash Made Practical},
+  howpublished = {Cryptology ePrint Archive, Report 2014/785},
+  year = {2014},
+  note = {\url{http://eprint.iacr.org/2014/785}},
+}
+
address@hidden,
+  author="Pointcheval, David and Sanders, Olivier and Traor{\'e}, Jacques",
+  editor="Fehr, Serge",
+  title="Cut Down the Tree to Achieve Constant Complexity in Divisible E-cash",
+  bookTitle="Public-Key Cryptography -- PKC 2017: 20th IACR International 
Conference on Practice and Theory in Public-Key Cryptography, Amsterdam, The 
Netherlands, March 28-31, 2017, Proceedings, Part I",
+year="2017",
+  publisher="Springer Berlin Heidelberg",
+  address="Berlin, Heidelberg",
+  pages="61--90",
+  isbn="978-3-662-54365-8",
+  doi="10.1007/978-3-662-54365-8_4",
+  doi_url="https://doi.org/10.1007/978-3-662-54365-8_4";
+  note = {Cryptology ePrint Archive, Report 2015/972  
\url{http://eprint.iacr.org/2015/972}},
+  url = {http://eprint.iacr.org/2015/972},
+}
+
+
+
 @book{molander1998cyberpayments,
   title={Cyberpayments and money laundering: Problems and promise},
   author={Molander, Roger C and Mussington, David A and Mussington, David and 
Wilson, Peter A},
@@ -353,7 +388,7 @@
 }
 
 
address@hidden,
address@hidden,
   author="Bellare and Namprempre and Pointcheval and Semanko",
   title="The One-More-RSA-Inversion Problems and the Security of Chaum's Blind 
Signature Scheme ",
   journal="Journal of Cryptology",
@@ -368,7 +403,7 @@
 }
 
 
address@hidden,
address@hidden,
   author="Bellare, Mihir and Namprempre, Chanathip and Pointcheval, David and 
Semanko, Michael",
   editor="Syverson, Paul",
   chapter="The Power of RSA Inversion Oracles and the Security of Chaum's 
RSA-Based Blind Signature Scheme",
@@ -383,7 +418,7 @@
 }
 
 
address@hidden,
address@hidden,
   author="Coron, Jean-S{\'e}bastien",
   editor="Bellare, Mihir",
   chapter="On the Exact Security of Full Domain Hash",
diff --git a/doc/taler-exchange.texi b/doc/taler-exchange.texi
index 97a0d61..558a57e 100644
--- a/doc/taler-exchange.texi
+++ b/doc/taler-exchange.texi
@@ -239,37 +239,37 @@ Please install the following packages before proceeding 
with the exchange compil
 @itemize
 
 @item
-GNU autoconf >= 2.69
+GNU autoconf @geq{} 2.69
 
 @item
-GNU automake >= 1.14
+GNU automake @geq{} 1.14
 
 @item
-GNU libtool >= 2.4
+GNU libtool @geq{} 2.4
 
 @item
-GNU autopoint >= 0.19
+GNU autopoint @geq{} 0.19
 
 @item
-GNU libltdl >= 2.4
+GNU libltdl @geq{} 2.4
 
 @item
-GNU libunistring >= 0.9.3
+GNU libunistring @geq{} 0.9.3
 
 @item
-libcurl >= 7.26 (or libgnurl >= 7.26)
+libcurl @geq{} 7.26 (or libgnurl @geq{} 7.26)
 
 @item
-GNU libmicrohttpd >= 0.9.52
+GNU libmicrohttpd @geq{} 0.9.52
 
 @item
-GNU libgcrypt >= 1.6
+GNU libgcrypt @geq{} 1.6
 
 @item
-libjansson >= 2.7
+libjansson @geq{} 2.7
 
 @item
-Postgres >= 9.6, including libpq
+Postgres @geq{} 9.6, including libpq
 
 @item
 libgnunetutil (from Git)
diff --git a/src/auditor/Makefile.am b/src/auditor/Makefile.am
index c2e77f1..439db7f 100644
--- a/src/auditor/Makefile.am
+++ b/src/auditor/Makefile.am
@@ -13,6 +13,7 @@ pkgcfg_DATA = \
 
 bin_PROGRAMS = \
   taler-auditor \
+  taler-wire-auditor \
   taler-auditor-sign
 
 taler_auditor_SOURCES = \
@@ -25,6 +26,19 @@ taler_auditor_LDADD = \
   $(top_builddir)/src/exchangedb/libtalerexchangedb.la \
   $(top_builddir)/src/auditordb/libtalerauditordb.la \
   -ljansson \
+  -lgnunetjson \
+  -lgnunetutil
+
+taler_wire_auditor_SOURCES = \
+  taler-wire-auditor.c
+taler_wire_auditor_LDADD = \
+  $(LIBGCRYPT_LIBS) \
+  $(top_builddir)/src/util/libtalerutil.la \
+  $(top_builddir)/src/json/libtalerjson.la \
+  $(top_builddir)/src/wire/libtalerwire.la \
+  $(top_builddir)/src/exchangedb/libtalerexchangedb.la \
+  $(top_builddir)/src/auditordb/libtalerauditordb.la \
+  -ljansson \
   -lgnunetutil
 
 taler_auditor_sign_SOURCES = \
@@ -32,6 +46,7 @@ taler_auditor_sign_SOURCES = \
 taler_auditor_sign_LDADD = \
   $(LIBGCRYPT_LIBS) \
   $(top_builddir)/src/util/libtalerutil.la \
+  $(top_builddir)/src/auditordb/libtalerauditordb.la \
   $(top_builddir)/src/exchangedb/libtalerexchangedb.la \
   -lgnunetutil $(XLIB)
 
diff --git a/src/auditor/taler-auditor-sign.c b/src/auditor/taler-auditor-sign.c
index d1a205b..70c4098 100644
--- a/src/auditor/taler-auditor-sign.c
+++ b/src/auditor/taler-auditor-sign.c
@@ -21,6 +21,7 @@
  */
 #include <platform.h>
 #include "taler_exchangedb_lib.h"
+#include "taler_auditordb_lib.h"
 
 
 /**
@@ -59,6 +60,11 @@ static struct TALER_MasterPublicKeyP master_public_key;
  */
 static struct GNUNET_CONFIGURATION_Handle *cfg;
 
+/**
+ * Handle to access the auditor's database.
+ */
+static struct TALER_AUDITORDB_Plugin *adb;
+
 
 /**
  * Print denomination key details for diagnostics.
@@ -180,7 +186,6 @@ main (int argc,
   unsigned int dks_len;
   struct TALER_ExchangeKeyValidityPS kv;
   off_t in_size;
-  unsigned int i;
 
   GNUNET_assert (GNUNET_OK ==
                  GNUNET_log_setup ("taler-auditor-sign",
@@ -191,8 +196,9 @@ main (int argc,
                          argc, argv) < 0)
     return 1;
   cfg = GNUNET_CONFIGURATION_create ();
-  if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg,
-                                                  cfgfile))
+  if (GNUNET_SYSERR ==
+      GNUNET_CONFIGURATION_load (cfg,
+                                 cfgfile))
   {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                 _("Malformed configuration file `%s', exit ...\n"),
@@ -223,7 +229,8 @@ main (int argc,
              "Auditor URL not given in neither configuration nor 
command-line\n");
     return 1;
   }
-  if (GNUNET_YES != GNUNET_DISK_file_test (auditor_key_file))
+  if (GNUNET_YES !=
+      GNUNET_DISK_file_test (auditor_key_file))
     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
                 "Auditor private key `%s' does not exist yet, creating it!\n",
                 auditor_key_file);
@@ -278,8 +285,17 @@ main (int argc,
     GNUNET_DISK_file_close (fh);
     GNUNET_free (eddsa_priv);
     return 2;
-  
   }
+  if (NULL ==
+      (adb = TALER_AUDITORDB_plugin_load (cfg)))
+  {
+    fprintf (stderr,
+             "Failed to initialize auditor database plugin.\n");
+    GNUNET_DISK_file_close (fh);
+    GNUNET_free (eddsa_priv);
+    return 3;
+  }
+
   kv.purpose.purpose = htonl (TALER_SIGNATURE_AUDITOR_EXCHANGE_KEYS);
   kv.purpose.size = htonl (sizeof (struct TALER_ExchangeKeyValidityPS));
   GNUNET_CRYPTO_hash (auditor_url,
@@ -299,6 +315,7 @@ main (int argc,
              "Failed to read input file `%s': %s\n",
              exchange_request_file,
              STRERROR (errno));
+    TALER_AUDITORDB_plugin_unload (adb);
     GNUNET_DISK_file_close (fh);
     GNUNET_free (sigs);
     GNUNET_free (dks);
@@ -306,7 +323,7 @@ main (int argc,
     return 1;
   }
   GNUNET_DISK_file_close (fh);
-  for (i=0;i<dks_len;i++)
+  for (unsigned int i=0;i<dks_len;i++)
   {
     struct TALER_DenominationKeyValidityPS *dk = &dks[i];
 
@@ -324,21 +341,74 @@ main (int argc,
     kv.denom_hash = dk->denom_hash;
 
     /* Finally sign ... */
-    GNUNET_CRYPTO_eddsa_sign (eddsa_priv,
-                              &kv.purpose,
-                              &sigs[i].eddsa_sig);
+    GNUNET_assert (GNUNET_OK ==
+                   GNUNET_CRYPTO_eddsa_sign (eddsa_priv,
+                                             &kv.purpose,
+                                             &sigs[i].eddsa_sig));
   }
 
   if (NULL == output_file)
   {
     fprintf (stderr,
              "Output file not given\n");
+    TALER_AUDITORDB_plugin_unload (adb);
     GNUNET_free (dks);
     GNUNET_free (sigs);
     GNUNET_free (eddsa_priv);
     return 1;
   }
 
+  /* Create required tables */
+  if (GNUNET_OK !=
+      adb->create_tables (adb->cls))
+  {
+    fprintf (stderr,
+             "Failed to create tables in auditor's database\n");
+    TALER_AUDITORDB_plugin_unload (adb);
+    GNUNET_free (dks);
+    GNUNET_free (sigs);
+    GNUNET_free (eddsa_priv);
+    return 3;
+  }
+
+
+  /* Update DB */
+  {
+    enum GNUNET_DB_QueryStatus qs;
+    struct TALER_AUDITORDB_Session *session;
+
+    session = adb->get_session (adb->cls);
+    if (NULL == session)
+    {
+      fprintf (stderr,
+              "Failed to initialize database session\n");
+      TALER_AUDITORDB_plugin_unload (adb);
+      GNUNET_free (dks);
+      GNUNET_free (sigs);
+      GNUNET_free (eddsa_priv);
+      return 3;
+    }
+    for (unsigned int i=0;i<dks_len;i++)
+    {
+      const struct TALER_DenominationKeyValidityPS *dk = &dks[i];
+
+      qs = adb->insert_denomination_info (adb->cls,
+                                         session,
+                                         dk);
+      if (0 > qs)
+      {
+       fprintf (stderr,
+                "Failed to store key in auditor DB\n");
+       TALER_AUDITORDB_plugin_unload (adb);
+       GNUNET_free (dks);
+       GNUNET_free (sigs);
+       GNUNET_free (eddsa_priv);
+       return 3;
+      }
+    }
+  }
+  TALER_AUDITORDB_plugin_unload (adb);
+
   /* write result to disk */
   if (GNUNET_OK !=
       TALER_EXCHANGEDB_auditor_write (output_file,
@@ -357,7 +427,6 @@ main (int argc,
     GNUNET_free (dks);
     return 1;
   }
-
   GNUNET_free (sigs);
   GNUNET_free (dks);
   GNUNET_free (eddsa_priv);
diff --git a/src/auditor/taler-auditor.c b/src/auditor/taler-auditor.c
index f7ea947..3e4eca1 100644
--- a/src/auditor/taler-auditor.c
+++ b/src/auditor/taler-auditor.c
@@ -25,7 +25,6 @@
  *   given in the 'wire_out' table. This needs to be checked separately!
  *
  * KNOWN BUGS:
- * - calculate, store and report aggregation fee balance!
  * - error handling if denomination keys are used that are not known to the
  *   auditor is, eh, awful / non-existent. We just throw the DB's constraint
  *   violation back at the user. Great UX.
@@ -114,11 +113,74 @@ static struct TALER_MasterPublicKeyP master_pub;
  */
 static struct TALER_AUDITORDB_ProgressPoint pp;
 
+/**
+ * Array of reports about denomination keys with an
+ * emergency (more deposited than withdrawn)
+ */
+static json_t *report_emergencies;
+
+/**
+ * Array of reports about row inconsitencies.
+ */
+static json_t *report_row_inconsistencies;
+
+/**
+ * Array of reports about minor row inconcistencies.
+ */
+static json_t *report_row_minor_inconsistencies;
+
+/**
+ * Array of reports about reserve inconsitencies.
+ */
+static json_t *report_reserve_inconsistencies;
+
+/**
+ * Array of reports about irregular wire out entries.
+ */
+static json_t *report_wire_out_inconsistencies;
+
+/**
+ * Array of reports about inconsistencies about coins.
+ */
+static json_t *report_coin_inconsistencies;
+
+/**
+ * Report about expected reserve balances.
+ */
+static json_t *report_reserve_balances;
+
+/**
+ * Report about aggregate wire transfer fee profits.
+ */
+static json_t *report_aggregation_fee_balances;
+
+/**
+ * Report about denomination fee balances.
+ */
+static json_t *report_denomination_balances;
+
 
 /* ***************************** Report logic **************************** */
 
 
 /**
+ * Add @a object to the report @a array.  Fail hard if this fails.
+ *
+ * @param array report array to append @a object to
+ * @param object object to append, should be check that it is not NULL
+ */ 
+static void
+report (json_t *array,
+       json_t *object)
+{
+  GNUNET_assert (NULL != object);
+  GNUNET_assert (0 ==
+                json_array_append_new (array,
+                                       object));
+}
+
+
+/**
  * Called in case we detect an emergency situation where the exchange
  * is paying out a larger amount on a denomination than we issued in
  * that denomination.  This means that the exchange's private keys
@@ -131,14 +193,10 @@ static struct TALER_AUDITORDB_ProgressPoint pp;
 static void
 report_emergency (const struct TALER_EXCHANGEDB_DenominationKeyInformationP 
*dki)
 {
-  char *dhks;
-
-  dhks = GNUNET_STRINGS_data_to_string_alloc (&dki->properties.denom_hash,
-                                              sizeof (struct GNUNET_HashCode));
-  GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-              "Emergency detected. Exchange must revoke key using 
`taler-auditor -r %s`\n",
-              dhks);
-  GNUNET_free (dhks);
+  report (report_emergencies,
+         json_pack ("{s:o}",
+                    "denompub_hash",
+                    GNUNET_JSON_from_data_auto (&dki->properties.denom_hash)));
 }
 
 
@@ -154,12 +212,11 @@ report_row_inconsistency (const char *table,
                           uint64_t rowid,
                           const char *diagnostic)
 {
-  // TODO: implement proper reporting logic writing to file.
-  GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-              "Database inconsistency detected in table %s at row %llu: %s\n",
-              table,
-              (unsigned long long) rowid,
-              diagnostic);
+  report (report_row_inconsistencies,
+         json_pack ("{s:s, s:I, s:s}",
+                    "table", table,
+                    "row", (json_int_t) rowid,
+                    "diagnostic", diagnostic));
 }
 
 
@@ -176,12 +233,11 @@ report_row_minor_inconsistency (const char *table,
                                 uint64_t rowid,
                                 const char *diagnostic)
 {
-  // TODO: implement proper reporting logic writing to file.
-  GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-              "Minor inconsistency detected in table %s at row %llu: %s\n",
-              table,
-              (unsigned long long) rowid,
-              diagnostic);
+  report (report_row_minor_inconsistencies,
+         json_pack ("{s:s, s:I, s:s}",
+                    "table", table,
+                    "row", (json_int_t) rowid,
+                    "diagnostic", diagnostic));
 }
 
 
@@ -199,11 +255,16 @@ report_reserve_inconsistency (const struct 
TALER_ReservePublicKeyP *reserve_pub,
                               const struct TALER_Amount *observed,
                               const char *diagnostic)
 {
-  // TODO: implement proper reporting logic writing to file, include amounts.
-  GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-              "Reserve inconsistency detected affecting reserve %s: %s\n",
-              TALER_B2S (reserve_pub),
-              diagnostic);
+  report (report_reserve_inconsistencies,
+         json_pack ("{s:o, s:o, s:o, s:s}",
+                    "reserve_pub",
+                    GNUNET_JSON_from_data_auto (reserve_pub),
+                    "expected",
+                    TALER_JSON_from_amount (expected),
+                    "observed",
+                    TALER_JSON_from_amount (observed),
+                    "diagnostic",
+                    diagnostic));
 }
 
 
@@ -223,10 +284,18 @@ report_wire_out_inconsistency (const json_t *destination,
                                const struct TALER_Amount *observed,
                                const char *diagnostic)
 {
-  // TODO: implement proper reporting logic writing to file, include amounts.
-  GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-              "Wire out inconsistency detected: %s\n",
-              diagnostic);
+  report (report_wire_out_inconsistencies,
+         json_pack ("{s:O, s:I, s:o, s:o, s:s}",
+                    "destination_account",
+                    destination,
+                    "rowid",
+                    (json_int_t) rowid,
+                    "expected",
+                    TALER_JSON_from_amount (expected),
+                    "observed",
+                    TALER_JSON_from_amount (observed),
+                    "diagnostic",
+                    diagnostic));
 }
 
 
@@ -244,10 +313,16 @@ report_coin_inconsistency (const struct 
TALER_CoinSpendPublicKeyP *coin_pub,
                            const struct TALER_Amount *observed,
                            const char *diagnostic)
 {
-  // TODO: implement proper reporting logic writing to file, include amounts.
-  GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-              "Coin inconsistency detected: %s\n",
-              diagnostic);
+  report (report_coin_inconsistencies,
+         json_pack ("{s:o, s:o, s:o, s:s}",
+                    "coin_pub",
+                    GNUNET_JSON_from_data_auto (coin_pub),
+                    "expected",
+                    TALER_JSON_from_amount (expected),
+                    "observed",
+                    TALER_JSON_from_amount (observed),
+                    "diagnostic",
+                    diagnostic));
 }
 
 
@@ -271,13 +346,12 @@ static void
 report_reserve_balance (const struct TALER_Amount *total_balance,
                         const struct TALER_Amount *total_fee_balance)
 {
-  // TODO: implement proper reporting logic writing to file.
-  GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
-              "Escrow balance to be held for reserves is %s\n",
-              TALER_amount2s (total_balance));
-  GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
-              "Withdraw fees income is %s\n",
-              TALER_amount2s (total_fee_balance));
+  report (report_reserve_balances,
+         json_pack ("{s:o, s:o}",
+                    "total_escrow_balance",
+                    TALER_JSON_from_amount (total_balance),
+                    "total_withdraw_fee_income",
+                    TALER_JSON_from_amount (total_fee_balance)));
 }
 
 
@@ -294,10 +368,10 @@ report_reserve_balance (const struct TALER_Amount 
*total_balance,
 static void
 report_aggregation_fee_balance (const struct TALER_Amount *total_fee_balance)
 {
-  // TODO: implement proper reporting logic writing to file.
-  GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
-              "Aggregation fees income is %s\n",
-              TALER_amount2s (total_fee_balance));
+  report (report_aggregation_fee_balances,
+         json_pack ("{s:o}",
+                    "total_aggregation_fee_income",
+                    TALER_JSON_from_amount (total_fee_balance)));
 }
 
 
@@ -317,22 +391,18 @@ report_denomination_balance (const struct TALER_Amount 
*total_balance,
                              const struct TALER_Amount *melt_fees,
                              const struct TALER_Amount *refund_fees)
 {
-  // TODO: implement proper reporting logic writing to file.
-  GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
-              "Escrow balance for issued coins is %s\n",
-              TALER_amount2s (total_balance));
-  GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
-              "Risk from active operations is %s\n",
-              TALER_amount2s (total_risk));
-  GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
-              "Deposit fee income is %s\n",
-              TALER_amount2s (deposit_fees));
-  GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
-              "Melt fee income is %s\n",
-              TALER_amount2s (melt_fees));
-  GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
-              "Refund fee income is %s\n",
-              TALER_amount2s (refund_fees));
+  report (report_denomination_balances,
+         json_pack ("{s:o, s:o, s:o, s:o, s:o}",
+                    "total_escrow_balance",
+                    TALER_JSON_from_amount (total_balance),
+                    "total_active_risk",
+                    TALER_JSON_from_amount (total_risk),
+                    "total_deposit_fee_income",
+                    TALER_JSON_from_amount (deposit_fees),
+                    "total_melt_fee_income",
+                    TALER_JSON_from_amount (melt_fees),
+                    "total_refund_fee_income",
+                    TALER_JSON_from_amount (refund_fees)));
 }
 
 
@@ -606,7 +676,7 @@ struct ReserveContext
    * Transaction status code, set to error codes if applicable.
    */
   enum GNUNET_DB_QueryStatus qs;
-  
+
 };
 
 
@@ -1616,16 +1686,21 @@ check_transaction_history (const struct 
TALER_CoinSpendPublicKeyP *coin_pub,
               TALER_B2S (coin_pub));
 
   GNUNET_assert (NULL != tl_head);
-  TALER_amount_get_zero (currency,
-                         &expenditures);
-  TALER_amount_get_zero (currency,
-                         &refunds);
-  TALER_amount_get_zero (currency,
-                         merchant_gain);
-  TALER_amount_get_zero (currency,
-                         merchant_fees);
-  TALER_amount_get_zero (currency,
-                         &merchant_loss);
+  GNUNET_assert (GNUNET_OK ==
+                 TALER_amount_get_zero (currency,
+                                        &expenditures));
+  GNUNET_assert (GNUNET_OK ==
+                 TALER_amount_get_zero (currency,
+                                        &refunds));
+  GNUNET_assert (GNUNET_OK ==
+                 TALER_amount_get_zero (currency,
+                                        merchant_gain));
+  GNUNET_assert (GNUNET_OK ==
+                 TALER_amount_get_zero (currency,
+                                        merchant_fees));
+  GNUNET_assert (GNUNET_OK ==
+                 TALER_amount_get_zero (currency,
+                                        &merchant_loss));
   /* Go over transaction history to compute totals; note that we do not
      know the order, so instead of subtracting we compute positive
      (deposit, melt) and negative (refund) values separately here,
@@ -1936,6 +2011,7 @@ wire_transfer_information_cb (void *cls,
     return;
   }
 
+  GNUNET_assert (NULL != dki); /* mostly to help static analysis */
   /* Check transaction history to see if it supports aggregate
      valuation */
   check_transaction_history (coin_pub,
@@ -2119,7 +2195,7 @@ get_wire_fee (struct AggregationContext *ac,
                                        pos->prev,
                                        wfi);
   /* Check non-overlaping fee invariant */
-  /* TODO: maybe report problems more nicely? */
+  /* TODO (#4963): maybe report problems more nicely? */
   if (NULL != wfi->prev)
     GNUNET_break (wfi->prev->end_date.abs_value_us <= 
wfi->start_date.abs_value_us);
   if (NULL != wfi->next)
@@ -2180,10 +2256,18 @@ check_wire_out_cb (void *cls,
   wcc.method = json_string_value (method);
   wcc.qs = GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
   wcc.date = date;
-  TALER_amount_get_zero (amount->currency,
-                         &wcc.total_deposits);
-  TALER_JSON_hash (wire,
-                   &wcc.h_wire);
+  GNUNET_assert (GNUNET_OK ==
+                 TALER_amount_get_zero (amount->currency,
+                                        &wcc.total_deposits));
+  if (GNUNET_OK !=
+      TALER_JSON_hash (wire,
+                       &wcc.h_wire))
+  {
+    report_row_inconsistency ("wire_out",
+                              rowid,
+                              "could not hash wire address");
+    return GNUNET_OK;
+  }
   qs = edb->lookup_wire_transfer (edb->cls,
                                  esession,
                                  wtid,
@@ -3170,7 +3254,7 @@ deposit_cb (void *cls,
     /* This should not be possible, unless the AUDITOR
        has a bug in tracking total balance. */
     GNUNET_break (0);
-    cc->qs = GNUNET_DB_STATUS_HARD_ERROR; 
+    cc->qs = GNUNET_DB_STATUS_HARD_ERROR;
     return GNUNET_SYSERR;
   }
 
@@ -3191,7 +3275,7 @@ deposit_cb (void *cls,
                           &dfee))
     {
       GNUNET_break (0);
-      cc->qs = GNUNET_DB_STATUS_HARD_ERROR; 
+      cc->qs = GNUNET_DB_STATUS_HARD_ERROR;
       return GNUNET_SYSERR;
     }
   }
@@ -3304,7 +3388,7 @@ refund_cb (void *cls,
                         &amount_without_fee))
   {
     GNUNET_break (0);
-    cc->qs = GNUNET_DB_STATUS_HARD_ERROR; 
+    cc->qs = GNUNET_DB_STATUS_HARD_ERROR;
     return GNUNET_SYSERR;
   }
   if (GNUNET_OK !=
@@ -3313,7 +3397,7 @@ refund_cb (void *cls,
                         &amount_without_fee))
   {
     GNUNET_break (0);
-    cc->qs = GNUNET_DB_STATUS_HARD_ERROR; 
+    cc->qs = GNUNET_DB_STATUS_HARD_ERROR;
     return GNUNET_SYSERR;
   }
   if (GNUNET_OK !=
@@ -3322,7 +3406,7 @@ refund_cb (void *cls,
                         &amount_without_fee))
   {
     GNUNET_break (0);
-    cc->qs = GNUNET_DB_STATUS_HARD_ERROR; 
+    cc->qs = GNUNET_DB_STATUS_HARD_ERROR;
     return GNUNET_SYSERR;
   }
   if (GNUNET_OK !=
@@ -3331,7 +3415,7 @@ refund_cb (void *cls,
                         &amount_without_fee))
   {
     GNUNET_break (0);
-    cc->qs = GNUNET_DB_STATUS_HARD_ERROR; 
+    cc->qs = GNUNET_DB_STATUS_HARD_ERROR;
     return GNUNET_SYSERR;
   }
 
@@ -3347,7 +3431,7 @@ refund_cb (void *cls,
                         &refund_fee))
   {
     GNUNET_break (0);
-    cc->qs = GNUNET_DB_STATUS_HARD_ERROR; 
+    cc->qs = GNUNET_DB_STATUS_HARD_ERROR;
     return GNUNET_SYSERR;
   }
 
@@ -3431,7 +3515,7 @@ analyze_coins (void *cls)
   }
 
   /* process refreshs */
-  if (0 > 
+  if (0 >
       (qs = edb->select_refreshs_above_serial_id (edb->cls,
                                                  esession,
                                                  pp.last_melt_serial_id,
@@ -3709,6 +3793,8 @@ run (void *cls,
      const char *cfgfile,
      const struct GNUNET_CONFIGURATION_Handle *c)
 {
+  json_t *report;
+  
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Launching auditor\n");
   cfg = c;
@@ -3775,11 +3861,43 @@ run (void *cls,
 
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Starting audit\n");
+  GNUNET_assert (NULL !=
+                (report_emergencies = json_array ()));
+  GNUNET_assert (NULL !=
+                (report_row_inconsistencies = json_array ()));
+  GNUNET_assert (NULL !=
+                (report_row_minor_inconsistencies = json_array ()));
+  GNUNET_assert (NULL !=
+                (report_reserve_inconsistencies = json_array ()));
+  GNUNET_assert (NULL !=
+                (report_wire_out_inconsistencies = json_array ()));
+  GNUNET_assert (NULL !=
+                (report_coin_inconsistencies = json_array ()));
+  GNUNET_assert (NULL !=
+                (report_reserve_balances = json_array ()));
+  GNUNET_assert (NULL !=
+                (report_aggregation_fee_balances = json_array ()));
+  GNUNET_assert (NULL !=
+                (report_denomination_balances = json_array ()));
   setup_sessions_and_run ();
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Audit complete\n");
   TALER_AUDITORDB_plugin_unload (adb);
   TALER_EXCHANGEDB_plugin_unload (edb);
+  report = json_pack ("{s:o, s:o, s:o, s:o, s:o, s:o, s:o, s:o, s:o}",
+                     "emergencies", report_emergencies,
+                     "row-inconsistencies", report_row_inconsistencies,
+                     "row-minor-inconsistencies", 
report_row_minor_inconsistencies,
+                     "reserve-inconsistencies", report_reserve_inconsistencies,
+                     "wire-out-inconsistencies", 
report_wire_out_inconsistencies,
+                     "coin_inconsistencies", report_coin_inconsistencies,
+                     "reserve_balance", report_reserve_balances,
+                     "aggregation_fee_balance", 
report_aggregation_fee_balances,
+                     "report_denomination_balance", 
report_denomination_balances);
+  json_dumpf (report,
+             stdout,
+             JSON_INDENT (2));
+  json_decref (report);
 }
 
 
@@ -3798,14 +3916,14 @@ main (int argc,
   const struct GNUNET_GETOPT_CommandLineOption options[] = {
     GNUNET_GETOPT_option_mandatory
     (GNUNET_GETOPT_option_base32_auto ('m',
-                                           "exchange-key",
-                                           "KEY",
-                                           "public key of the exchange 
(Crockford base32 encoded)",
-                                           &master_pub)),
+                                      "exchange-key",
+                                      "KEY",
+                                      "public key of the exchange (Crockford 
base32 encoded)",
+                                      &master_pub)),
     GNUNET_GETOPT_option_flag ('r',
-                                  "restart",
-                                  "restart audit from the beginning (required 
on first run)",
-                                  &restart),
+                              "restart",
+                              "restart audit from the beginning (required on 
first run)",
+                              &restart),
     GNUNET_GETOPT_OPTION_END
   };
 
diff --git a/src/auditor/taler-wire-auditor.c b/src/auditor/taler-wire-auditor.c
new file mode 100644
index 0000000..7cc741b
--- /dev/null
+++ b/src/auditor/taler-wire-auditor.c
@@ -0,0 +1,1128 @@
+/*
+  This file is part of TALER
+  Copyright (C) 2017 Taler Systems SA
+
+  TALER is free software; you can redistribute it and/or modify it under the
+  terms of the GNU General Public License as published by the Free Software
+  Foundation; either version 3, or (at your option) any later version.
+
+  TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+  A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License along with
+  TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+*/
+/**
+ * @file auditor/taler-wire-auditor.c
+ * @brief audits that wire transfers match those from an exchange database.
+ * @author Christian Grothoff
+ *
+ * - First, this auditor verifies that 'reserves_in' actually matches
+ *   the incoming wire transfers from the bank.
+ * - Second, we check that the outgoing wire transfers match those
+ *   given in the 'wire_out' table
+ */
+#include "platform.h"
+#include <gnunet/gnunet_util_lib.h>
+#include "taler_auditordb_plugin.h"
+#include "taler_exchangedb_plugin.h"
+#include "taler_json_lib.h"
+#include "taler_wire_lib.h"
+#include "taler_signatures.h"
+
+
+/**
+ * Return value from main().
+ */
+static int global_ret;
+
+/**
+ * Command-line option "-r": restart audit from scratch
+ */
+static int restart;
+
+/**
+ * Name of the wire plugin to load to access the exchange's bank account.
+ */
+static char *wire_plugin;
+
+/**
+ * Handle to access the exchange's database.
+ */
+static struct TALER_EXCHANGEDB_Plugin *edb;
+
+/**
+ * Which currency are we doing the audit for?
+ */
+static char *currency;
+
+/**
+ * Our configuration.
+ */
+static const struct GNUNET_CONFIGURATION_Handle *cfg;
+
+/**
+ * Map with information about incoming wire transfers.
+ * Maps hashes of the wire offsets to `struct ReserveInInfo`s.
+ */
+static struct GNUNET_CONTAINER_MultiHashMap *in_map;
+
+/**
+ * Map with information about outgoing wire transfers.
+ * Maps hashes of the wire offsets to `struct ReserveOutInfo`s.
+ */
+static struct GNUNET_CONTAINER_MultiHashMap *out_map;
+
+/**
+ * Our session with the #edb.
+ */
+static struct TALER_EXCHANGEDB_Session *esession;
+
+/**
+ * Handle to access the auditor's database.
+ */
+static struct TALER_AUDITORDB_Plugin *adb;
+
+/**
+ * Our session with the #adb.
+ */
+static struct TALER_AUDITORDB_Session *asession;
+
+/**
+ * Master public key of the exchange to audit.
+ */
+static struct TALER_MasterPublicKeyP master_pub;
+
+/**
+ * Handle to the wire plugin for wire operations.
+ */
+static struct TALER_WIRE_Plugin *wp;
+
+/**
+ * Active wire request for the transaction history.
+ */
+static struct TALER_WIRE_HistoryHandle *hh;
+
+/**
+ * Query status for the incremental processing status in the auditordb.
+ */
+static enum GNUNET_DB_QueryStatus qsx;
+
+/**
+ * Last reserve_in / wire_out serial IDs seen.
+ */
+static struct TALER_AUDITORDB_WireProgressPoint pp;
+
+/**
+ * Where we are in the inbound (CREDIT) transaction history.
+ */
+static void *in_wire_off;
+
+/**
+ * Where we are in the inbound (DEBIT) transaction history.
+ */
+static void *out_wire_off;
+
+/**
+ * Number of bytes in #in_wire_off and #out_wire_off.
+ */
+static size_t wire_off_size;
+
+/**
+ * Array of reports about row inconsitencies.
+ */
+static json_t *report_row_inconsistencies;
+
+/**
+ * Array of reports about minor row inconcistencies.
+ */
+static json_t *report_row_minor_inconsistencies;
+
+
+/* *****************************   Shutdown   **************************** */
+
+/** 
+ * Entry in map with wire information we expect to obtain from the
+ * bank later.
+ */
+struct ReserveInInfo
+{
+
+  /** 
+   * Hash of expected row offset.
+   */
+  struct GNUNET_HashCode row_off_hash;
+
+  /**
+   * Number of bytes in @e row_off.
+   */
+  size_t row_off_size;
+
+  /**
+   * Expected details about the wire transfer.
+   */
+  struct TALER_WIRE_TransferDetails details;
+
+  /**
+   * RowID in reserves_in table.
+   */
+  uint64_t rowid;
+  
+};
+
+
+/** 
+ * Entry in map with wire information we expect to obtain from the
+ * #edb later.
+ */
+struct ReserveOutInfo
+{
+
+  /** 
+   * Hash of the wire transfer subject.
+   */
+  struct GNUNET_HashCode subject_hash;
+
+  /**
+   * Expected details about the wire transfer.
+   */
+  struct TALER_WIRE_TransferDetails details;
+  
+};
+
+
+/**
+ * Free entry in #in_map.
+ *
+ * @param cls NULL
+ * @param key unused key
+ * @param value the `struct ReserveInInfo` to free
+ * @return #GNUNET_OK
+ */
+static int
+free_rii (void *cls,
+         const struct GNUNET_HashCode *key,
+         void *value)
+{
+  struct ReserveInInfo *rii = value;
+
+  GNUNET_assert (GNUNET_YES ==
+                GNUNET_CONTAINER_multihashmap_remove (in_map,
+                                                      key,
+                                                      rii));
+  json_decref (rii->details.account_details);
+  GNUNET_free (rii);
+  return GNUNET_OK;
+}
+
+
+/**
+ * Free entry in #out_map.
+ *
+ * @param cls NULL
+ * @param key unused key
+ * @param value the `struct ReserveOutInfo` to free
+ * @return #GNUNET_OK
+ */
+static int
+free_roi (void *cls,
+         const struct GNUNET_HashCode *key,
+         void *value)
+{
+  struct ReserveOutInfo *roi = value;
+
+  GNUNET_assert (GNUNET_YES ==
+                GNUNET_CONTAINER_multihashmap_remove (out_map,
+                                                      key,
+                                                      roi));
+  json_decref (roi->details.account_details);
+  GNUNET_free (roi);
+  return GNUNET_OK;
+}
+
+
+/**
+ * Task run on shutdown.
+ *
+ * @param cls NULL
+ */
+static void
+do_shutdown (void *cls)
+{
+  if (NULL != report_row_inconsistencies)
+  {
+    json_t *report;
+    
+    GNUNET_assert (NULL != report_row_minor_inconsistencies);
+    report = json_pack ("{s:o, s:o}",
+                       "row-inconsistencies", report_row_inconsistencies,
+                       "row-minor-inconsistencies", 
report_row_minor_inconsistencies);
+    json_dumpf (report,
+               stdout,
+               JSON_INDENT (2));
+    json_decref (report);
+    report_row_inconsistencies = NULL;
+    report_row_minor_inconsistencies = NULL;
+  }
+  if (NULL != hh)
+  {
+    wp->get_history_cancel (wp->cls,
+                            hh);
+    hh = NULL;
+  }
+  if (NULL != in_map)
+  {
+    GNUNET_CONTAINER_multihashmap_iterate (in_map,
+                                          &free_rii,
+                                          NULL);
+    GNUNET_CONTAINER_multihashmap_destroy (in_map);
+    in_map = NULL;
+  }
+  if (NULL != out_map)
+  {
+    GNUNET_CONTAINER_multihashmap_iterate (out_map,
+                                          &free_roi,
+                                          NULL);
+    GNUNET_CONTAINER_multihashmap_destroy (out_map);
+    out_map = NULL;
+  }
+  if (NULL != wp)
+  {
+    TALER_WIRE_plugin_unload (wp);
+    wp = NULL;
+  }
+  if (NULL != adb)
+  {
+    TALER_AUDITORDB_plugin_unload (adb);
+    adb = NULL;
+  }
+  if (NULL != edb)
+  {
+    TALER_EXCHANGEDB_plugin_unload (edb);
+    edb = NULL;
+  }
+}
+
+
+/* ***************************** Report logic **************************** */
+
+
+/**
+ * Add @a object to the report @a array.  Fail hard if this fails.
+ *
+ * @param array report array to append @a object to
+ * @param object object to append, should be check that it is not NULL
+ */ 
+static void
+report (json_t *array,
+       json_t *object)
+{
+  GNUNET_assert (NULL != object);
+  GNUNET_assert (0 ==
+                json_array_append_new (array,
+                                       object));
+}
+
+
+/**
+ * Report a (serious) inconsistency in the exchange's database.
+ *
+ * @param table affected table
+ * @param rowid affected row, UINT64_MAX if row is missing
+ * @param diagnostic message explaining the problem
+ */
+static void
+report_row_inconsistency (const char *table,
+                          uint64_t rowid,
+                          const char *diagnostic)
+{
+  report (report_row_inconsistencies,
+         json_pack ("{s:s, s:I, s:s}",
+                    "table", table,
+                    "row", (json_int_t) rowid,
+                    "diagnostic", diagnostic));
+}
+
+
+/**
+ * Report a minor inconsistency in the exchange's database (i.e. something
+ * relating to timestamps that should have no financial implications).
+ *
+ * @param table affected table
+ * @param rowid affected row, UINT64_MAX if row is missing
+ * @param diagnostic message explaining the problem
+ */
+static void
+report_row_minor_inconsistency (const char *table,
+                                uint64_t rowid,
+                                const char *diagnostic)
+{
+  report (report_row_minor_inconsistencies,
+         json_pack ("{s:s, s:I, s:s}",
+                    "table", table,
+                    "row", (json_int_t) rowid,
+                    "diagnostic", diagnostic));
+}
+
+
+/* *************************** General transaction logic ****************** */
+
+/**
+ * Commit the transaction, checkpointing our progress in the auditor
+ * DB.
+ *
+ * @param qs transaction status so far
+ * @return transaction status code
+ */
+static enum GNUNET_DB_QueryStatus
+commit (enum GNUNET_DB_QueryStatus qs)
+{
+  if (0 > qs)
+  {
+    if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
+      GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                 "Serialization issue, not recording progress\n");
+    else
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                 "Hard error, not recording progress\n");
+    adb->rollback (adb->cls,
+                   asession);
+    edb->rollback (edb->cls,
+                   esession);
+    return qs;
+  }
+  if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qsx)
+    qs = adb->update_wire_auditor_progress (adb->cls,
+                                            asession,
+                                            &master_pub,
+                                            &pp,
+                                            in_wire_off,
+                                            out_wire_off,
+                                            wire_off_size);
+  else
+    qs = adb->insert_wire_auditor_progress (adb->cls,
+                                            asession,
+                                            &master_pub,
+                                            &pp,
+                                            in_wire_off,
+                                            out_wire_off,
+                                            wire_off_size);
+
+  if (0 >= qs)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+               "Failed to update auditor DB, not recording progress\n");
+    GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
+    return qs;
+  }
+  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+              _("Concluded audit step at %llu/%llu\n"),
+              (unsigned long long) pp.last_reserve_in_serial_id,
+              (unsigned long long) pp.last_wire_out_serial_id);
+
+  if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs)
+  {
+    qs = edb->commit (edb->cls,
+                       esession);
+    if (0 > qs)
+    {
+      GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                  "Exchange DB commit failed, rolling back transaction\n");
+      adb->rollback (adb->cls,
+                     asession);
+    }
+    else
+    {
+      qs = adb->commit (adb->cls,
+                       asession);
+      if (0 > qs)
+      {
+       GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
+        GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                    "Auditor DB commit failed!\n");
+      }
+    }
+  }
+  else
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "Processing failed, rolling back transaction\n");
+    adb->rollback (adb->cls,
+                   asession);
+    edb->rollback (edb->cls,
+                   esession);
+  }
+  return qs;
+}
+
+
+/* ***************************** Analyze reserves_out ************************ 
*/
+
+
+/**
+ * Function called with details about outgoing wire transfers
+ * as claimed by the exchange DB.
+ *
+ * @param cls NULL
+ * @param rowid unique serial ID for the refresh session in our DB
+ * @param date timestamp of the wire transfer (roughly)
+ * @param wtid wire transfer subject
+ * @param wire wire transfer details of the receiver
+ * @param amount amount that was wired
+ * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop
+ */
+static int
+wire_out_cb (void *cls,
+               uint64_t rowid,
+               struct GNUNET_TIME_Absolute date,
+               const struct TALER_WireTransferIdentifierRawP *wtid,
+               const json_t *wire,
+               const struct TALER_Amount *amount)
+{
+  struct GNUNET_HashCode key;
+  struct ReserveOutInfo *roi;
+  
+  GNUNET_CRYPTO_hash (wtid,
+                     sizeof (struct TALER_WireTransferIdentifierRawP),
+                     &key);
+  roi = GNUNET_CONTAINER_multihashmap_get (in_map,
+                                          &key);
+  if (NULL == roi)
+  {
+    /* FIXME (#4963): do proper logging! */
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+               "Failed to find wire transfer `%s' over %s at `%s' in exchange 
database!\n",
+               TALER_B2S (wtid),
+               TALER_amount2s (amount),
+               GNUNET_STRINGS_absolute_time_to_string (date));
+    return GNUNET_OK;
+  }
+  if (0 != TALER_amount_cmp (&roi->details.amount,
+                            amount))
+  {
+    report_row_inconsistency ("reserves_out",
+                             rowid,
+                             "wire amount missmatch");
+    return GNUNET_OK;
+  }
+  if (roi->details.execution_date.abs_value_us !=
+      date.abs_value_us)
+  {
+    report_row_minor_inconsistency ("reserves_out",
+                                   rowid,
+                                   "execution date missmatch");
+  }
+  if (! json_equal ((json_t *) wire,
+                   roi->details.account_details))
+  {
+    report_row_inconsistency ("reserves_out",
+                             rowid,
+                             "receiver account missmatch");
+    return GNUNET_OK;
+  }
+  GNUNET_assert (GNUNET_OK ==
+                GNUNET_CONTAINER_multihashmap_remove (out_map,
+                                                      &key,
+                                                      roi));
+  GNUNET_assert (GNUNET_OK ==
+                free_roi (NULL,
+                          &key,
+                          roi));
+  return GNUNET_OK;
+}
+
+
+/**
+ * Complain that we failed to match an entry from #out_map.
+ *
+ * @param cls NULL
+ * @param key unused key
+ * @param value the `struct ReserveOutInfo` to free
+ * @return #GNUNET_OK
+ */
+static int
+complain_out_not_found (void *cls,
+                       const struct GNUNET_HashCode *key,
+                       void *value)
+{
+  struct ReserveOutInfo *roi = value;
+
+  (void) roi;
+  /* FIXME (#4963): log more precisely which wire transfer (and amount)
+     is bogus. */
+  report_row_inconsistency ("reserves_out",
+                           UINT64_MAX,
+                           "matching wire transfer not found");
+  return GNUNET_OK;
+}
+
+
+/**
+ * Go over the "wire_out" table of the exchange and
+ * verify that all wire outs are in that table.
+ */
+static void
+check_exchange_wire_out ()
+{
+  enum GNUNET_DB_QueryStatus qs;
+    
+  qs = edb->select_wire_out_above_serial_id (edb->cls,
+                                            esession,
+                                            pp.last_wire_out_serial_id,
+                                            &wire_out_cb,
+                                            NULL);
+  if (0 > qs)
+  {
+    GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
+    global_ret = 1;
+    GNUNET_SCHEDULER_shutdown ();
+    return;
+  }
+  GNUNET_CONTAINER_multihashmap_iterate (out_map,
+                                        &complain_out_not_found,
+                                        NULL); 
+  /* clean up (technically redundant, but nicer) */
+  GNUNET_CONTAINER_multihashmap_iterate (out_map,
+                                        &free_roi,
+                                        NULL);
+  GNUNET_CONTAINER_multihashmap_destroy (out_map);
+  out_map = NULL;
+ 
+  /* conclude with: */
+  commit (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT);
+  GNUNET_SCHEDULER_shutdown ();
+}
+
+
+/**
+ * This function is called for all transactions that
+ * are credited to the exchange's account (incoming
+ * transactions).
+ *
+ * @param cls closure
+ * @param dir direction of the transfer
+ * @param row_off identification of the position at which we are querying
+ * @param row_off_size number of bytes in @a row_off
+ * @param details details about the wire transfer
+ * @return #GNUNET_OK to continue, #GNUNET_SYSERR to abort iteration
+ */
+static int
+history_debit_cb (void *cls,
+                 enum TALER_BANK_Direction dir,
+                 const void *row_off,
+                 size_t row_off_size,
+                 const struct TALER_WIRE_TransferDetails *details)
+{
+  struct ReserveOutInfo *roi;
+  
+  if (TALER_BANK_DIRECTION_NONE == dir)
+  {
+    /* end of iteration, now check wire_out to see
+       if it matches #out_map */
+    hh = NULL;
+    check_exchange_wire_out ();
+    return GNUNET_OK;
+  }
+  roi = GNUNET_new (struct ReserveOutInfo);
+  GNUNET_CRYPTO_hash (&details->reserve_pub, /* FIXME (#5077): missnomer */
+                     sizeof (details->reserve_pub),
+                     &roi->subject_hash);
+  roi->details.amount = details->amount;
+  roi->details.execution_date = details->execution_date;
+  roi->details.reserve_pub = details->reserve_pub; /* FIXME (#5077): missnomer 
& redundant */
+  roi->details.account_details = json_incref ((json_t *) 
details->account_details);
+  if (GNUNET_OK !=
+      GNUNET_CONTAINER_multihashmap_put (out_map,
+                                        &roi->subject_hash,
+                                        roi,
+                                        
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
+  {
+    GNUNET_break_op (0); /* duplicate wire offset is not allowed! */
+    report_row_inconsistency ("bank wire log",
+                             UINT64_MAX,
+                             "duplicate wire offset");
+    return GNUNET_SYSERR;
+  }
+  return GNUNET_OK;
+}
+
+
+/**
+ * Main functin for processing 'reserves_out' data.
+ * We start by going over the DEBIT transactions this
+ * time, and then verify that all of them are justified
+ * by 'reserves_out'.
+ */
+static void
+process_debits ()
+{
+  GNUNET_assert (NULL == hh);
+  out_map = GNUNET_CONTAINER_multihashmap_create (1024,
+                                                 GNUNET_YES);
+  hh = wp->get_history (wp->cls,
+                        TALER_BANK_DIRECTION_DEBIT,
+                        out_wire_off,
+                        wire_off_size,
+                        INT64_MAX,
+                        &history_debit_cb,
+                        NULL);
+  if (NULL == hh)
+  {
+    fprintf (stderr,
+             "Failed to obtain bank transaction history\n");
+    commit (GNUNET_DB_STATUS_HARD_ERROR);
+    global_ret = 1;
+    GNUNET_SCHEDULER_shutdown ();
+    return;
+  }
+}
+
+
+/* ***************************** Analyze reserves_in ************************ 
*/
+
+
+/**
+ * Function called with details about incoming wire transfers
+ * as claimed by the exchange DB.
+ *
+ * @param cls NULL
+ * @param rowid unique serial ID for the refresh session in our DB
+ * @param reserve_pub public key of the reserve (also the WTID)
+ * @param credit amount that was received
+ * @param sender_account_details information about the sender's bank account
+ * @param wire_reference unique identifier for the wire transfer 
(plugin-specific format)
+ * @param wire_reference_size number of bytes in @a wire_reference
+ * @param execution_date when did we receive the funds
+ * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop
+ */
+static int
+reserve_in_cb (void *cls,
+              uint64_t rowid,
+              const struct TALER_ReservePublicKeyP *reserve_pub,
+              const struct TALER_Amount *credit,
+              const json_t *sender_account_details,
+              const void *wire_reference,
+              size_t wire_reference_size,
+              struct GNUNET_TIME_Absolute execution_date)
+
+{
+  struct ReserveInInfo *rii;
+
+  rii = GNUNET_new (struct ReserveInInfo);
+  GNUNET_CRYPTO_hash (wire_reference,
+                     wire_reference_size,
+                     &rii->row_off_hash);
+  rii->row_off_size = wire_reference_size;
+  rii->details.amount = *credit;
+  rii->details.execution_date = execution_date;
+  rii->details.reserve_pub = *reserve_pub;
+  rii->details.account_details = json_incref ((json_t *) 
sender_account_details);
+  rii->rowid = rowid;
+  if (GNUNET_OK !=
+      GNUNET_CONTAINER_multihashmap_put (in_map,
+                                        &rii->row_off_hash,
+                                        rii,
+                                        
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
+  {
+    GNUNET_break_op (0); /* duplicate wire offset is not allowed! */
+    report_row_inconsistency ("reserves_in",
+                             rowid,
+                             "duplicate wire offset");
+    return GNUNET_SYSERR;
+  }
+  pp.last_reserve_in_serial_id = rowid + 1;
+  return GNUNET_OK;
+}
+
+
+/**
+ * Complain that we failed to match an entry from #in_map.
+ *
+ * @param cls NULL
+ * @param key unused key
+ * @param value the `struct ReserveInInfo` to free
+ * @return #GNUNET_OK
+ */
+static int
+complain_in_not_found (void *cls,
+                      const struct GNUNET_HashCode *key,
+                      void *value)
+{
+  struct ReserveInInfo *rii = value;
+
+  report_row_inconsistency ("reserves_in",
+                           rii->rowid,
+                           "matching wire transfer not found");
+  return GNUNET_OK;
+}
+
+
+/**
+ * This function is called for all transactions that
+ * are credited to the exchange's account (incoming
+ * transactions).
+ *
+ * @param cls closure
+ * @param dir direction of the transfer
+ * @param row_off identification of the position at which we are querying
+ * @param row_off_size number of bytes in @a row_off
+ * @param details details about the wire transfer
+ * @return #GNUNET_OK to continue, #GNUNET_SYSERR to abort iteration
+ */
+static int
+history_credit_cb (void *cls,
+                   enum TALER_BANK_Direction dir,
+                   const void *row_off,
+                   size_t row_off_size,
+                   const struct TALER_WIRE_TransferDetails *details)
+{
+  struct ReserveInInfo *rii;
+  struct GNUNET_HashCode key;
+  
+  if (TALER_BANK_DIRECTION_NONE == dir)
+  {
+    /* end of operation */
+    hh = NULL;
+    GNUNET_CONTAINER_multihashmap_iterate (in_map,
+                                          &complain_in_not_found,
+                                          NULL);
+    /* clean up before 2nd phase */
+    GNUNET_CONTAINER_multihashmap_iterate (in_map,
+                                          &free_rii,
+                                          NULL);
+    GNUNET_CONTAINER_multihashmap_destroy (in_map);
+    in_map = NULL;
+    process_debits ();
+    return GNUNET_SYSERR;
+  }
+  GNUNET_CRYPTO_hash (row_off,
+                     row_off_size,
+                     &key);
+  rii = GNUNET_CONTAINER_multihashmap_get (in_map,
+                                          &key);
+  if (NULL == rii)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+               "Failed to find wire transfer at `%s' in exchange database. 
Audit ends at this point in time.\n",
+               GNUNET_STRINGS_absolute_time_to_string 
(details->execution_date));
+    return GNUNET_SYSERR;
+  }
+
+  /* Update offset */
+  if (NULL == in_wire_off)
+  {
+    wire_off_size = row_off_size;
+    in_wire_off = GNUNET_malloc (row_off_size);
+  }
+  if (wire_off_size != row_off_size)
+  {
+    GNUNET_break (0);
+    commit (GNUNET_DB_STATUS_HARD_ERROR);
+    GNUNET_SCHEDULER_shutdown ();
+    return GNUNET_SYSERR;
+  }
+  memcpy (in_wire_off,
+         row_off,
+         row_off_size);
+
+  /* compare records with expected data */
+  if (row_off_size != rii->row_off_size)
+  {
+    GNUNET_break (0);
+    report_row_inconsistency ("reserves_in",
+                             rii->rowid,
+                             "wire reference size missmatch");
+    return GNUNET_OK;
+  }
+  if (0 != TALER_amount_cmp (&rii->details.amount,
+                            &details->amount))
+  {
+    report_row_inconsistency ("reserves_in",
+                             rii->rowid,
+                             "wire amount missmatch");
+    return GNUNET_OK;
+  }
+  if (details->execution_date.abs_value_us !=
+      rii->details.execution_date.abs_value_us)
+  {
+    report_row_minor_inconsistency ("reserves_in",
+                                   rii->rowid,
+                                   "execution date missmatch");
+  }
+  if (0 != memcmp (&details->reserve_pub,
+                  &rii->details.reserve_pub,
+                  sizeof (struct TALER_ReservePublicKeyP)))
+  {
+    report_row_inconsistency ("reserves_in",
+                             rii->rowid,
+                             "reserve public key / wire subject missmatch");
+    return GNUNET_OK;
+  }
+  if (! json_equal (details->account_details,
+                   rii->details.account_details))
+  {
+    report_row_minor_inconsistency ("reserves_in",
+                                   rii->rowid,
+                                   "sender account missmatch");
+  }
+  GNUNET_assert (GNUNET_OK ==
+                GNUNET_CONTAINER_multihashmap_remove (in_map,
+                                                      &key,
+                                                      rii));
+  GNUNET_assert (GNUNET_OK ==
+                free_rii (NULL,
+                          &key,
+                          rii));
+  return GNUNET_OK;
+}
+
+
+/* ***************************** Setup logic    ************************ */
+
+
+/**
+ * Main function that will be run.
+ *
+ * @param cls closure
+ * @param args remaining command-line arguments
+ * @param cfgfile name of the configuration file used (for saving, can be 
NULL!)
+ * @param c configuration
+ */
+static void
+run (void *cls,
+     char *const *args,
+     const char *cfgfile,
+     const struct GNUNET_CONFIGURATION_Handle *c)
+{
+  enum GNUNET_DB_QueryStatus qs;
+  int ret;
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Launching auditor\n");
+  cfg = c;
+  if (GNUNET_OK !=
+      GNUNET_CONFIGURATION_get_value_string (cfg,
+                                             "taler",
+                                             "CURRENCY",
+                                             &currency))
+  {
+    GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
+                               "taler",
+                               "CURRENCY");
+    global_ret = 1;
+    return;
+  }
+  if (NULL ==
+      (edb = TALER_EXCHANGEDB_plugin_load (cfg)))
+  {
+    fprintf (stderr,
+             "Failed to initialize exchange database plugin.\n");
+    global_ret = 1;
+    return;
+  }
+  if (NULL ==
+      (adb = TALER_AUDITORDB_plugin_load (cfg)))
+  {
+    fprintf (stderr,
+             "Failed to initialize auditor database plugin.\n");
+    global_ret = 1;
+    TALER_EXCHANGEDB_plugin_unload (edb);
+    return;
+  }
+  if (restart)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                "Full audit restart requested, dropping old audit data.\n");
+    GNUNET_break (GNUNET_OK ==
+                  adb->drop_tables (adb->cls));
+    TALER_AUDITORDB_plugin_unload (adb);
+    if (NULL ==
+        (adb = TALER_AUDITORDB_plugin_load (cfg)))
+    {
+      fprintf (stderr,
+               "Failed to initialize auditor database plugin after drop.\n");
+      global_ret = 1;
+      TALER_EXCHANGEDB_plugin_unload (edb);
+      return;
+    }
+    GNUNET_break (GNUNET_OK ==
+                  adb->create_tables (adb->cls));
+  }
+  GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
+                                 NULL);
+  esession = edb->get_session (edb->cls);
+  if (NULL == esession)
+  {
+    fprintf (stderr,
+             "Failed to initialize exchange session.\n");
+    global_ret = 1;
+    GNUNET_SCHEDULER_shutdown ();
+    return;
+  }
+  asession = adb->get_session (adb->cls);
+  if (NULL == asession)
+  {
+    fprintf (stderr,
+             "Failed to initialize auditor session.\n");
+    global_ret = 1;
+    GNUNET_SCHEDULER_shutdown ();
+    return;
+  }
+  wp = TALER_WIRE_plugin_load (cfg,
+                               wire_plugin);
+  if (NULL == wp)
+  {
+    fprintf (stderr,
+             "Failed to load wire plugin `%s'\n",
+             wire_plugin);
+    global_ret = 1;
+    GNUNET_SCHEDULER_shutdown ();
+    return;
+  }
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Starting audit\n");
+  ret = adb->start (adb->cls,
+                    asession);
+  if (GNUNET_OK != ret)
+  {
+    GNUNET_break (0);
+    global_ret = 1;
+    GNUNET_SCHEDULER_shutdown ();
+    return;
+  }
+  ret = edb->start (edb->cls,
+                    esession);
+  if (GNUNET_OK != ret)
+  {
+    GNUNET_break (0);
+    global_ret = 1;
+    GNUNET_SCHEDULER_shutdown ();
+    return;
+  }
+  GNUNET_assert (NULL !=
+                (report_row_inconsistencies = json_array ()));
+  GNUNET_assert (NULL !=
+                (report_row_minor_inconsistencies = json_array ()));
+  qsx = adb->get_wire_auditor_progress (adb->cls,
+                                        asession,
+                                        &master_pub,
+                                        &pp,
+                                        &in_wire_off,
+                                        &out_wire_off,
+                                        &wire_off_size);
+  if (0 > qsx)
+  {
+    GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qsx);
+    global_ret = 1;
+    GNUNET_SCHEDULER_shutdown ();
+    return;
+  }
+  if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qsx)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
+                _("First analysis using this auditor, starting audit from 
scratch\n"));
+  }
+  else
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                _("Resuming audit at %llu/%llu\n"),
+                (unsigned long long) pp.last_reserve_in_serial_id,
+                (unsigned long long) pp.last_wire_out_serial_id);
+  }
+
+  in_map = GNUNET_CONTAINER_multihashmap_create (1024,
+                                                GNUNET_YES);
+  qs = edb->select_reserves_in_above_serial_id (edb->cls,
+                                               esession,
+                                               pp.last_reserve_in_serial_id,
+                                               &reserve_in_cb,
+                                               NULL);
+  if (0 > qs)
+  {
+    GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
+    global_ret = 1;
+    GNUNET_SCHEDULER_shutdown ();
+    return;
+  }
+  if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
+                "No new incoming transactions available, skipping CREDIT 
phase\n");
+    process_debits ();
+    return;
+  }
+  hh = wp->get_history (wp->cls,
+                        TALER_BANK_DIRECTION_CREDIT,
+                        in_wire_off,
+                        wire_off_size,
+                        INT64_MAX,
+                        &history_credit_cb,
+                        NULL);
+  if (NULL == hh)
+  {
+    fprintf (stderr,
+             "Failed to obtain bank transaction history\n");
+    commit (GNUNET_DB_STATUS_HARD_ERROR);
+    global_ret = 1;
+    GNUNET_SCHEDULER_shutdown ();
+    return;
+  }
+}
+
+
+/**
+ * The main function of the database initialization tool.
+ * Used to initialize the Taler Exchange's database.
+ *
+ * @param argc number of arguments from the command line
+ * @param argv command line arguments
+ * @return 0 ok, 1 on error
+ */
+int
+main (int argc,
+      char *const *argv)
+{
+  const struct GNUNET_GETOPT_CommandLineOption options[] = {
+    GNUNET_GETOPT_option_mandatory
+    (GNUNET_GETOPT_option_base32_auto ('m',
+                                       "exchange-key",
+                                       "KEY",
+                                       "public key of the exchange (Crockford 
base32 encoded)",
+                                       &master_pub)),
+    GNUNET_GETOPT_option_flag ('r',
+                               "restart",
+                               "restart audit from the beginning (required on 
first run)",
+                               &restart),
+    GNUNET_GETOPT_option_mandatory
+    (GNUNET_GETOPT_option_string ('w',
+                                 "wire",
+                                 "PLUGINNAME",
+                                 "name of the wire plugin to use",
+                                 &wire_plugin)),
+    GNUNET_GETOPT_OPTION_END
+  };
+
+  /* force linker to link against libtalerutil; if we do
+     not do this, the linker may "optimize" libtalerutil
+     away and skip #TALER_OS_init(), which we do need */
+  (void) TALER_project_data_default ();
+  GNUNET_assert (GNUNET_OK ==
+                 GNUNET_log_setup ("taler-wire-auditor",
+                                   "MESSAGE",
+                                   NULL));
+  if (GNUNET_OK !=
+      GNUNET_PROGRAM_run (argc,
+                         argv,
+                          "taler-wire-auditor",
+                         "Audit exchange database for consistency with the 
bank's wire transfers",
+                         options,
+                         &run,
+                         NULL))
+    return 1;
+  return global_ret;
+}
+
+
+/* end of taler-wire-auditor.c */
diff --git a/src/auditordb/plugin_auditordb_postgres.c 
b/src/auditordb/plugin_auditordb_postgres.c
index 4862cf2..1001ba9 100644
--- a/src/auditordb/plugin_auditordb_postgres.c
+++ b/src/auditordb/plugin_auditordb_postgres.c
@@ -138,16 +138,17 @@ postgres_drop_tables (void *cls)
 {
   struct PostgresClosure *pc = cls;
   struct GNUNET_PQ_ExecuteStatement es[] = {
-    GNUNET_PQ_make_execute ("DROP TABLE IF EXISTS predicted_result;"),
-    GNUNET_PQ_make_execute ("DROP TABLE IF EXISTS historic_ledger;"),
-    GNUNET_PQ_make_execute ("DROP TABLE IF EXISTS historic_losses;"),
-    GNUNET_PQ_make_execute ("DROP TABLE IF EXISTS 
historic_denomination_revenue;"),
-    GNUNET_PQ_make_execute ("DROP TABLE IF EXISTS balance_summary;"),
-    GNUNET_PQ_make_execute ("DROP TABLE IF EXISTS denomination_pending;"),
+    GNUNET_PQ_make_execute ("DROP TABLE IF EXISTS auditor_predicted_result;"),
+    GNUNET_PQ_make_execute ("DROP TABLE IF EXISTS auditor_historic_ledger;"),
+    GNUNET_PQ_make_execute ("DROP TABLE IF EXISTS auditor_historic_losses;"),
+    GNUNET_PQ_make_execute ("DROP TABLE IF EXISTS 
auditor_historic_denomination_revenue;"),
+    GNUNET_PQ_make_execute ("DROP TABLE IF EXISTS auditor_balance_summary;"),
+    GNUNET_PQ_make_execute ("DROP TABLE IF EXISTS 
auditor_denomination_pending;"),
     GNUNET_PQ_make_execute ("DROP TABLE IF EXISTS auditor_reserve_balance;"),
     GNUNET_PQ_make_execute ("DROP TABLE IF EXISTS auditor_wire_fee_balance;"),
     GNUNET_PQ_make_execute ("DROP TABLE IF EXISTS auditor_reserves;"),
     GNUNET_PQ_make_execute ("DROP TABLE IF EXISTS auditor_progress;"),
+    GNUNET_PQ_make_execute ("DROP TABLE IF EXISTS wire_auditor_progress;"),
     GNUNET_PQ_EXECUTE_STATEMENT_END
   };
   PGconn *conn;
@@ -218,15 +219,22 @@ postgres_create_tables (void *cls)
        larger (and process in monotonically increasing order). */
     GNUNET_PQ_make_execute ("CREATE TABLE IF NOT EXISTS auditor_progress"
                            "(master_pub BYTEA PRIMARY KEY CHECK 
(LENGTH(master_pub)=32)"
-                           ",last_reserve_in_serial_id INT8 NOT NULL"
-                           ",last_reserve_out_serial_id INT8 NOT NULL"
-                           ",last_reserve_payback_serial_id INT8 NOT NULL"
-                           ",last_reserve_close_serial_id INT8 NOT NULL"
-                           ",last_withdraw_serial_id INT8 NOT NULL"
-                           ",last_deposit_serial_id INT8 NOT NULL"
-                           ",last_melt_serial_id INT8 NOT NULL"
-                           ",last_refund_serial_id INT8 NOT NULL"
-                           ",last_wire_out_serial_id INT8 NOT NULL"
+                           ",last_reserve_in_serial_id INT8 NOT NULL DEFAULT 0"
+                           ",last_reserve_out_serial_id INT8 NOT NULL DEFAULT 
0"
+                           ",last_reserve_payback_serial_id INT8 NOT NULL 
DEFAULT 0"
+                           ",last_reserve_close_serial_id INT8 NOT NULL 
DEFAULT 0"
+                           ",last_withdraw_serial_id INT8 NOT NULL DEFAULT 0"
+                           ",last_deposit_serial_id INT8 NOT NULL DEFAULT 0"
+                           ",last_melt_serial_id INT8 NOT NULL DEFAULT 0"
+                           ",last_refund_serial_id INT8 NOT NULL DEFAULT 0"
+                           ",last_wire_out_serial_id INT8 NOT NULL DEFAULT 0"
+                           ")"),
+    GNUNET_PQ_make_execute ("CREATE TABLE IF NOT EXISTS wire_auditor_progress"
+                           "(master_pub BYTEA PRIMARY KEY CHECK 
(LENGTH(master_pub)=32)"
+                           ",last_wire_reserve_in_serial_id INT8 NOT NULL 
DEFAULT 0"
+                           ",last_wire_wire_out_serial_id INT8 NOT NULL 
DEFAULT 0"
+                            ",wire_in_off BYTEA"
+                            ",wire_out_off BYTEA"
                            ")"),
     /* Table with all of the customer reserves and their respective
        balances that the auditor is aware of.
@@ -244,7 +252,7 @@ postgres_create_tables (void *cls)
                            ",withdraw_fee_balance_frac INT4 NOT NULL"
                            ",withdraw_fee_balance_curr 
VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL"
                            ",expiration_date INT8 NOT NULL"
-                           ",auditor_reserves_rowid BIGSERIAL"
+                           ",auditor_reserves_rowid BIGSERIAL UNIQUE"
                            ")"),
     GNUNET_PQ_make_try_execute ("CREATE INDEX auditor_reserves_by_reserve_pub "
                                "ON auditor_reserves(reserve_pub)"),
@@ -258,7 +266,7 @@ postgres_create_tables (void *cls)
                            ",withdraw_fee_balance_val INT8 NOT NULL"
                            ",withdraw_fee_balance_frac INT4 NOT NULL"
                            ",withdraw_fee_balance_curr 
VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL"
-                           ")"),    
+                           ")"),
     /* Table with the sum of the balances of all wire fees
        (by exchange's master public key) */
     GNUNET_PQ_make_execute ("CREATE TABLE IF NOT EXISTS 
auditor_wire_fee_balance"
@@ -274,9 +282,9 @@ postgres_create_tables (void *cls)
        last melt from "refresh_sessions" that the auditor is aware
        of; "refund_serial_id" tells us the last entry in "refunds"
        for this denom_pub that the auditor is aware of. */
-    GNUNET_PQ_make_execute ("CREATE TABLE IF NOT EXISTS denomination_pending"
+    GNUNET_PQ_make_execute ("CREATE TABLE IF NOT EXISTS 
auditor_denomination_pending"
                            "(denom_pub_hash BYTEA PRIMARY KEY"
-                           /* " REFERENCES auditor_denominations 
(denom_pub_hash) ON DELETE CASCADE" // Do we want this? */
+                           " REFERENCES auditor_denominations (denom_pub_hash) 
ON DELETE CASCADE"
                            ",denom_balance_val INT8 NOT NULL"
                            ",denom_balance_frac INT4 NOT NULL"
                            ",denom_balance_curr 
VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL"
@@ -285,12 +293,12 @@ postgres_create_tables (void *cls)
                            ",denom_risk_curr VARCHAR("TALER_CURRENCY_LEN_STR") 
NOT NULL"
                            ")"),
     /* Table with the sum of the outstanding coins from
-       "denomination_pending" (denom_pubs must belong to the
+       "auditor_denomination_pending" (denom_pubs must belong to the
        respective's exchange's master public key); it represents the
-       balance_summary of the exchange at this point (modulo
+       auditor_balance_summary of the exchange at this point (modulo
        unexpected historic_loss-style events where denomination keys are
        compromised) */
-    GNUNET_PQ_make_execute ("CREATE TABLE IF NOT EXISTS balance_summary"
+    GNUNET_PQ_make_execute ("CREATE TABLE IF NOT EXISTS 
auditor_balance_summary"
                            "(master_pub BYTEA PRIMARY KEY CHECK 
(LENGTH(master_pub)=32)"
                            ",denom_balance_val INT8 NOT NULL"
                            ",denom_balance_frac INT4 NOT NULL"
@@ -317,7 +325,7 @@ postgres_create_tables (void *cls)
        historic_reserve_revenue); the deposit, melt and refund fees are given
        individually; the delta to the revenue_balance is from coins that
        were withdrawn but never deposited prior to expiration. */
-    GNUNET_PQ_make_execute ("CREATE TABLE IF NOT EXISTS 
historic_denomination_revenue"
+    GNUNET_PQ_make_execute ("CREATE TABLE IF NOT EXISTS 
auditor_historic_denomination_revenue"
                            "(master_pub BYTEA NOT NULL CHECK 
(LENGTH(master_pub)=32)"
                            ",denom_pub_hash BYTEA PRIMARY KEY CHECK 
(LENGTH(denom_pub_hash)=64)"
                            ",revenue_timestamp INT8 NOT NULL"
@@ -330,7 +338,7 @@ postgres_create_tables (void *cls)
        compromised, we incur a loss. These losses are totaled
        up here. (NOTE: the 'bankrupcy' protocol is not yet
        implemented, so right now this table is not used.)  */
-    GNUNET_PQ_make_execute ("CREATE TABLE IF NOT EXISTS historic_losses"
+    GNUNET_PQ_make_execute ("CREATE TABLE IF NOT EXISTS 
auditor_historic_losses"
                            "(master_pub BYTEA NOT NULL CHECK 
(LENGTH(master_pub)=32)"
                            ",denom_pub_hash BYTEA PRIMARY KEY CHECK 
(LENGTH(denom_pub_hash)=64)"
                            ",loss_timestamp INT8 NOT NULL"
@@ -339,9 +347,9 @@ postgres_create_tables (void *cls)
                            ",loss_balance_curr 
VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL"
                            ")"),
     /* Table with historic profits from reserves; we eventually
-       GC "historic_reserve_revenue", and then store the totals
+       GC "auditor_historic_reserve_revenue", and then store the totals
        in here (by time intervals). */
-    GNUNET_PQ_make_execute ("CREATE TABLE IF NOT EXISTS 
historic_reserve_summary"
+    GNUNET_PQ_make_execute ("CREATE TABLE IF NOT EXISTS 
auditor_historic_reserve_summary"
                            "(master_pub BYTEA NOT NULL CHECK 
(LENGTH(master_pub)=32)"
                            ",start_date INT8 NOT NULL"
                            ",end_date INT8 NOT NULL"
@@ -349,8 +357,8 @@ postgres_create_tables (void *cls)
                            ",reserve_profits_frac INT4 NOT NULL"
                            ",reserve_profits_curr 
VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL"
                            ")"),
-    GNUNET_PQ_make_try_execute ("CREATE INDEX 
historic_reserve_summary_by_master_pub_start_date "
-                               "ON 
historic_reserve_summary(master_pub,start_date)"),
+    GNUNET_PQ_make_try_execute ("CREATE INDEX 
auditor_historic_reserve_summary_by_master_pub_start_date "
+                               "ON 
auditor_historic_reserve_summary(master_pub,start_date)"),
     /* Table with historic business ledger; basically, when the exchange
        operator decides to use operating costs for anything but wire
        transfers to merchants, it goes in here.  This happens when the
@@ -358,12 +366,12 @@ postgres_create_tables (void *cls)
        is free-form but should be a human-readable wire transfer
        identifier.   This is NOT yet used and outside of the scope of
        the core auditing logic. However, once we do take fees to use
-       operating costs, and if we still want "predicted_result" to match
+       operating costs, and if we still want "auditor_predicted_result" to 
match
        the tables overall, we'll need a command-line tool to insert rows
-       into this table and update "predicted_result" accordingly.
+       into this table and update "auditor_predicted_result" accordingly.
        (So this table for now just exists as a reminder of what we'll
        need in the long term.) */
-    GNUNET_PQ_make_execute ("CREATE TABLE IF NOT EXISTS historic_ledger"
+    GNUNET_PQ_make_execute ("CREATE TABLE IF NOT EXISTS 
auditor_historic_ledger"
                            "(master_pub BYTEA NOT NULL CHECK 
(LENGTH(master_pub)=32)"
                            ",purpose VARCHAR NOT NULL"
                            ",timestamp INT8 NOT NULL"
@@ -372,12 +380,12 @@ postgres_create_tables (void *cls)
                            ",balance_curr VARCHAR("TALER_CURRENCY_LEN_STR") 
NOT NULL"
                            ")"),
     GNUNET_PQ_make_try_execute ("CREATE INDEX 
history_ledger_by_master_pub_and_time "
-                               "ON historic_ledger(master_pub,timestamp)"),
-    /* Table with the sum of the ledger, historic_revenue,
-       historic_losses and the auditor_reserve_balance.  This is the
+                               "ON 
auditor_historic_ledger(master_pub,timestamp)"),
+    /* Table with the sum of the ledger, auditor_historic_revenue,
+       auditor_historic_losses and the auditor_reserve_balance.  This is the
        final amount that the exchange should have in its bank account
        right now. */
-    GNUNET_PQ_make_execute ("CREATE TABLE IF NOT EXISTS predicted_result"
+    GNUNET_PQ_make_execute ("CREATE TABLE IF NOT EXISTS 
auditor_predicted_result"
                            "(master_pub BYTEA PRIMARY KEY CHECK 
(LENGTH(master_pub)=32)"
                            ",balance_val INT8 NOT NULL"
                            ",balance_frac INT4 NOT NULL"
@@ -508,6 +516,35 @@ postgres_prepare (PGconn *db_conn)
                            " FROM auditor_progress"
                            " WHERE master_pub=$1;",
                            1),
+    /* Used in #postgres_insert_wire_auditor_progress() */
+    GNUNET_PQ_make_prepare ("wire_auditor_progress_insert",
+                           "INSERT INTO wire_auditor_progress "
+                           "(master_pub"
+                           ",last_wire_reserve_in_serial_id"
+                           ",last_wire_wire_out_serial_id"
+                            ",wire_in_off"
+                            ",wire_out_off"
+                           ") VALUES ($1,$2,$3,$4,$5);",
+                           5),
+    /* Used in #postgres_update_wire_auditor_progress() */
+    GNUNET_PQ_make_prepare ("wire_auditor_progress_update",
+                           "UPDATE wire_auditor_progress SET "
+                           " last_wire_reserve_in_serial_id=$1"
+                           ",last_wire_wire_out_serial_id=$2"
+                            ",wire_in_off=$3"
+                            ",wire_out_off=$4"
+                           " WHERE master_pub=$5",
+                           5),
+    /* Used in #postgres_get_wire_auditor_progress() */
+    GNUNET_PQ_make_prepare ("wire_auditor_progress_select",
+                           "SELECT"
+                           " last_wire_reserve_in_serial_id"
+                           ",last_wire_wire_out_serial_id"
+                            ",wire_in_off"
+                            ",wire_out_off"
+                           " FROM wire_auditor_progress"
+                           " WHERE master_pub=$1;",
+                           1),
     /* Used in #postgres_insert_reserve_info() */
     GNUNET_PQ_make_prepare ("auditor_reserves_insert",
                            "INSERT INTO auditor_reserves "
@@ -616,8 +653,8 @@ postgres_prepare (PGconn *db_conn)
                            " WHERE master_pub=$1;",
                            1),
     /* Used in #postgres_insert_denomination_balance() */
-    GNUNET_PQ_make_prepare ("denomination_pending_insert",
-                           "INSERT INTO denomination_pending "
+    GNUNET_PQ_make_prepare ("auditor_denomination_pending_insert",
+                           "INSERT INTO auditor_denomination_pending "
                            "(denom_pub_hash"
                            ",denom_balance_val"
                            ",denom_balance_frac"
@@ -626,10 +663,10 @@ postgres_prepare (PGconn *db_conn)
                            ",denom_risk_frac"
                            ",denom_risk_curr"
                            ") VALUES ($1,$2,$3,$4,$5,$6,$7);",
-                           7),    
+                           7),
     /* Used in #postgres_update_denomination_balance() */
-    GNUNET_PQ_make_prepare ("denomination_pending_update",
-                           "UPDATE denomination_pending SET"
+    GNUNET_PQ_make_prepare ("auditor_denomination_pending_update",
+                           "UPDATE auditor_denomination_pending SET"
                            " denom_balance_val=$1"
                            ",denom_balance_frac=$2"
                            ",denom_balance_curr=$3"
@@ -637,9 +674,9 @@ postgres_prepare (PGconn *db_conn)
                            ",denom_risk_frac=$5"
                            ",denom_risk_curr=$6"
                            " WHERE denom_pub_hash=$7",
-                           7),    
+                           7),
     /* Used in #postgres_get_denomination_balance() */
-    GNUNET_PQ_make_prepare ("denomination_pending_select",
+    GNUNET_PQ_make_prepare ("auditor_denomination_pending_select",
                            "SELECT"
                            " denom_balance_val"
                            ",denom_balance_frac"
@@ -647,12 +684,12 @@ postgres_prepare (PGconn *db_conn)
                            ",denom_risk_val"
                            ",denom_risk_frac"
                            ",denom_risk_curr"
-                           " FROM denomination_pending"
+                           " FROM auditor_denomination_pending"
                            " WHERE denom_pub_hash=$1",
                            1),
     /* Used in #postgres_insert_balance_summary() */
-    GNUNET_PQ_make_prepare ("balance_summary_insert",
-                           "INSERT INTO balance_summary "
+    GNUNET_PQ_make_prepare ("auditor_balance_summary_insert",
+                           "INSERT INTO auditor_balance_summary "
                            "(master_pub"
                            ",denom_balance_val"
                            ",denom_balance_frac"
@@ -672,8 +709,8 @@ postgres_prepare (PGconn *db_conn)
                            ") VALUES 
($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16);",
                            16),
     /* Used in #postgres_update_balance_summary() */
-    GNUNET_PQ_make_prepare ("balance_summary_update",
-                           "UPDATE balance_summary SET"
+    GNUNET_PQ_make_prepare ("auditor_balance_summary_update",
+                           "UPDATE auditor_balance_summary SET"
                            " denom_balance_val=$1"
                            ",denom_balance_frac=$2"
                            ",denom_balance_curr=$3"
@@ -692,7 +729,7 @@ postgres_prepare (PGconn *db_conn)
                            " WHERE master_pub=$16;",
                            16),
     /* Used in #postgres_get_balance_summary() */
-    GNUNET_PQ_make_prepare ("balance_summary_select",
+    GNUNET_PQ_make_prepare ("auditor_balance_summary_select",
                            "SELECT"
                            " denom_balance_val"
                            ",denom_balance_frac"
@@ -709,12 +746,12 @@ postgres_prepare (PGconn *db_conn)
                            ",risk_val"
                            ",risk_frac"
                            ",risk_curr"
-                           " FROM balance_summary"
+                           " FROM auditor_balance_summary"
                            " WHERE master_pub=$1;",
                            1),
     /* Used in #postgres_insert_historic_denom_revenue() */
-    GNUNET_PQ_make_prepare ("historic_denomination_revenue_insert",
-                           "INSERT INTO historic_denomination_revenue"
+    GNUNET_PQ_make_prepare ("auditor_historic_denomination_revenue_insert",
+                           "INSERT INTO auditor_historic_denomination_revenue"
                            "(master_pub"
                            ",denom_pub_hash"
                            ",revenue_timestamp"
@@ -724,19 +761,19 @@ postgres_prepare (PGconn *db_conn)
                            ") VALUES ($1,$2,$3,$4,$5,$6);",
                            6),
     /* Used in #postgres_select_historic_denom_revenue() */
-    GNUNET_PQ_make_prepare ("historic_denomination_revenue_select",
+    GNUNET_PQ_make_prepare ("auditor_historic_denomination_revenue_select",
                            "SELECT"
                            " denom_pub_hash"
                            ",revenue_timestamp"
                            ",revenue_balance_val"
                            ",revenue_balance_frac"
                            ",revenue_balance_curr"
-                           " FROM historic_denomination_revenue"
+                           " FROM auditor_historic_denomination_revenue"
                            " WHERE master_pub=$1;",
                            1),
     /* Used in #postgres_insert_historic_losses() */
-    GNUNET_PQ_make_prepare ("historic_losses_insert",
-                           "INSERT INTO historic_losses"
+    GNUNET_PQ_make_prepare ("auditor_historic_losses_insert",
+                           "INSERT INTO auditor_historic_losses"
                            "(master_pub"
                            ",denom_pub_hash"
                            ",loss_timestamp"
@@ -746,19 +783,19 @@ postgres_prepare (PGconn *db_conn)
                            ") VALUES ($1,$2,$3,$4,$5,$6);",
                            6),
     /* Used in #postgres_select_historic_losses() */
-    GNUNET_PQ_make_prepare ("historic_losses_select",
+    GNUNET_PQ_make_prepare ("auditor_historic_losses_select",
                            "SELECT"
                            " denom_pub_hash"
                            ",loss_timestamp"
                            ",loss_balance_val"
                            ",loss_balance_frac"
                            ",loss_balance_curr"
-                           " FROM historic_losses"
+                           " FROM auditor_historic_losses"
                            " WHERE master_pub=$1;",
                            1),
     /* Used in #postgres_insert_historic_reserve_revenue() */
-    GNUNET_PQ_make_prepare ("historic_reserve_summary_insert",
-                           "INSERT INTO historic_reserve_summary"
+    GNUNET_PQ_make_prepare ("auditor_historic_reserve_summary_insert",
+                           "INSERT INTO auditor_historic_reserve_summary"
                            "(master_pub"
                            ",start_date"
                            ",end_date"
@@ -766,21 +803,21 @@ postgres_prepare (PGconn *db_conn)
                            ",reserve_profits_frac"
                            ",reserve_profits_curr"
                            ") VALUES ($1,$2,$3,$4,$5,$6);",
-                           6),    
+                           6),
     /* Used in #postgres_select_historic_reserve_revenue() */
-    GNUNET_PQ_make_prepare ("historic_reserve_summary_select",
+    GNUNET_PQ_make_prepare ("auditor_historic_reserve_summary_select",
                            "SELECT"
                            " start_date"
                            ",end_date"
                            ",reserve_profits_val"
                            ",reserve_profits_frac"
                            ",reserve_profits_curr"
-                           " FROM historic_reserve_summary"
+                           " FROM auditor_historic_reserve_summary"
                            " WHERE master_pub=$1;",
                            1),
     /* Used in #postgres_insert_predicted_result() */
-    GNUNET_PQ_make_prepare ("predicted_result_insert",
-                           "INSERT INTO predicted_result"
+    GNUNET_PQ_make_prepare ("auditor_predicted_result_insert",
+                           "INSERT INTO auditor_predicted_result"
                            "(master_pub"
                            ",balance_val"
                            ",balance_frac"
@@ -788,20 +825,20 @@ postgres_prepare (PGconn *db_conn)
                            ") VALUES ($1,$2,$3,$4);",
                            4),
     /* Used in #postgres_update_predicted_result() */
-    GNUNET_PQ_make_prepare ("predicted_result_update",
-                           "UPDATE predicted_result SET"
+    GNUNET_PQ_make_prepare ("auditor_predicted_result_update",
+                           "UPDATE auditor_predicted_result SET"
                            " balance_val=$1"
                            ",balance_frac=$2"
                            ",balance_curr=$3"
                            " WHERE master_pub=$4;",
                            4),
     /* Used in #postgres_get_predicted_balance() */
-    GNUNET_PQ_make_prepare ("predicted_result_select",
+    GNUNET_PQ_make_prepare ("auditor_predicted_result_select",
                            "SELECT"
                            " balance_val"
                            ",balance_frac"
                            ",balance_curr"
-                           " FROM predicted_result"
+                           " FROM auditor_predicted_result"
                            " WHERE master_pub=$1;",
                            1),
     GNUNET_PQ_PREPARED_STATEMENT_END
@@ -1063,7 +1100,7 @@ struct DenominationInfoContext
    * Master public key that is being used.
    */
   const struct TALER_MasterPublicKeyP *master_pub;
-  
+
   /**
    * Function to call for each denomination.
    */
@@ -1073,7 +1110,7 @@ struct DenominationInfoContext
    * Closure for @e cb
    */
   void *cb_cls;
-  
+
   /**
    * Query status to return.
    */
@@ -1161,7 +1198,7 @@ postgres_select_denomination_info (void *cls,
     .cb_cls = cb_cls
   };
   enum GNUNET_DB_QueryStatus qs;
-  
+
   qs = GNUNET_PQ_eval_prepared_multi_select (session->conn,
                                             "auditor_denominations_select",
                                             params,
@@ -1295,6 +1332,130 @@ postgres_get_auditor_progress (void *cls,
 
 
 /**
+ * Insert information about the auditor's progress with an exchange's
+ * data.
+ *
+ * @param cls the @e cls of this struct with the plugin-specific state
+ * @param session connection to use
+ * @param master_pub master key of the exchange
+ * @param pp where is the auditor in processing
+ * @return transaction status code
+ */
+static enum GNUNET_DB_QueryStatus
+postgres_insert_wire_auditor_progress (void *cls,
+                                       struct TALER_AUDITORDB_Session *session,
+                                       const struct TALER_MasterPublicKeyP 
*master_pub,
+                                       const struct 
TALER_AUDITORDB_WireProgressPoint *pp,
+                                       const void *in_wire_off,
+                                       const void *out_wire_off,
+                                       size_t wire_off_size)
+{
+  struct GNUNET_PQ_QueryParam params[] = {
+    GNUNET_PQ_query_param_auto_from_type (master_pub),
+    GNUNET_PQ_query_param_uint64 (&pp->last_reserve_in_serial_id),
+    GNUNET_PQ_query_param_uint64 (&pp->last_wire_out_serial_id),
+    GNUNET_PQ_query_param_fixed_size (in_wire_off,
+                                      wire_off_size),
+    GNUNET_PQ_query_param_fixed_size (out_wire_off,
+                                      wire_off_size),
+    GNUNET_PQ_query_param_end
+  };
+
+  return GNUNET_PQ_eval_prepared_non_select (session->conn,
+                                            "wire_auditor_progress_insert",
+                                            params);
+}
+
+
+/**
+ * Update information about the progress of the auditor.  There
+ * must be an existing record for the exchange.
+ *
+ * @param cls the @e cls of this struct with the plugin-specific state
+ * @param session connection to use
+ * @param master_pub master key of the exchange
+ * @param pp where is the auditor in processing
+ * @return transaction status code
+ */
+static enum GNUNET_DB_QueryStatus
+postgres_update_wire_auditor_progress (void *cls,
+                                       struct TALER_AUDITORDB_Session *session,
+                                       const struct TALER_MasterPublicKeyP 
*master_pub,
+                                       const struct 
TALER_AUDITORDB_WireProgressPoint *pp,
+                                       const void *in_wire_off,
+                                       const void *out_wire_off,
+                                       size_t wire_off_size)
+{
+  struct GNUNET_PQ_QueryParam params[] = {
+    GNUNET_PQ_query_param_uint64 (&pp->last_reserve_in_serial_id),
+    GNUNET_PQ_query_param_uint64 (&pp->last_wire_out_serial_id),
+    GNUNET_PQ_query_param_auto_from_type (master_pub),
+    GNUNET_PQ_query_param_fixed_size (in_wire_off,
+                                      wire_off_size),
+    GNUNET_PQ_query_param_fixed_size (out_wire_off,
+                                      wire_off_size),
+    GNUNET_PQ_query_param_end
+  };
+
+  return GNUNET_PQ_eval_prepared_non_select (session->conn,
+                                            "wire_auditor_progress_update",
+                                            params);
+}
+
+
+/**
+ * Get information about the progress of the auditor.
+ *
+ * @param cls the @e cls of this struct with the plugin-specific state
+ * @param session connection to use
+ * @param master_pub master key of the exchange
+ * @param[out] pp set to where the auditor is in processing
+ * @return transaction status code
+ */
+static enum GNUNET_DB_QueryStatus
+postgres_get_wire_auditor_progress (void *cls,
+                                    struct TALER_AUDITORDB_Session *session,
+                                    const struct TALER_MasterPublicKeyP 
*master_pub,
+                                    struct TALER_AUDITORDB_WireProgressPoint 
*pp,
+                                    void **in_wire_off,
+                                    void **out_wire_off,
+                                    size_t *wire_off_size)
+{
+  size_t xsize;
+  enum GNUNET_DB_QueryStatus qs;
+  struct GNUNET_PQ_QueryParam params[] = {
+    GNUNET_PQ_query_param_auto_from_type (master_pub),
+    GNUNET_PQ_query_param_end
+  };
+  struct GNUNET_PQ_ResultSpec rs[] = {
+    GNUNET_PQ_result_spec_uint64 ("last_reserve_in_serial_id",
+                                  &pp->last_reserve_in_serial_id),
+    GNUNET_PQ_result_spec_uint64 ("last_wire_out_serial_id",
+                                  &pp->last_wire_out_serial_id),
+    GNUNET_PQ_result_spec_variable_size ("wire_in_off",
+                                         in_wire_off,
+                                         wire_off_size),
+    GNUNET_PQ_result_spec_variable_size ("wire_out_off",
+                                         out_wire_off,
+                                         &xsize),
+    GNUNET_PQ_result_spec_end
+  };
+
+  qs = GNUNET_PQ_eval_prepared_singleton_select (session->conn,
+                                                 
"wire_auditor_progress_select",
+                                                 params,
+                                                 rs);
+  if (qs <= 0)
+  {
+    *wire_off_size = 0;
+    xsize = 0;
+  }
+  GNUNET_assert (xsize == *wire_off_size);
+  return qs;
+}
+
+
+/**
  * Insert information about a reserve.  There must not be an
  * existing record for the reserve.
  *
@@ -1668,7 +1829,7 @@ postgres_insert_denomination_balance (void *cls,
   };
 
   return GNUNET_PQ_eval_prepared_non_select (session->conn,
-                                            "denomination_pending_insert",
+                                            
"auditor_denomination_pending_insert",
                                             params);
 }
 
@@ -1699,7 +1860,7 @@ postgres_update_denomination_balance (void *cls,
   };
 
   return GNUNET_PQ_eval_prepared_non_select (session->conn,
-                                            "denomination_pending_update",
+                                            
"auditor_denomination_pending_update",
                                             params);
 }
 
@@ -1730,9 +1891,9 @@ postgres_get_denomination_balance (void *cls,
     TALER_PQ_result_spec_amount ("denom_risk", denom_risk),
     GNUNET_PQ_result_spec_end
   };
-  
+
   return GNUNET_PQ_eval_prepared_singleton_select (session->conn,
-                                                  
"denomination_pending_select",
+                                                  
"auditor_denomination_pending_select",
                                                   params,
                                                   rs);
 }
@@ -1785,7 +1946,7 @@ postgres_insert_balance_summary (void *cls,
                                             refund_fee_balance));
 
   return GNUNET_PQ_eval_prepared_non_select (session->conn,
-                                            "balance_summary_insert",
+                                            "auditor_balance_summary_insert",
                                             params);
 }
 
@@ -1825,7 +1986,7 @@ postgres_update_balance_summary (void *cls,
   };
 
   return GNUNET_PQ_eval_prepared_non_select (session->conn,
-                                            "balance_summary_update",
+                                            "auditor_balance_summary_update",
                                             params);
 }
 
@@ -1867,7 +2028,7 @@ postgres_get_balance_summary (void *cls,
   };
 
   return GNUNET_PQ_eval_prepared_singleton_select (session->conn,
-                                                  "balance_summary_select",
+                                                  
"auditor_balance_summary_select",
                                                   params,
                                                   rs);
 }
@@ -1904,7 +2065,7 @@ postgres_insert_historic_denom_revenue (void *cls,
   };
 
   return GNUNET_PQ_eval_prepared_non_select (session->conn,
-                                            
"historic_denomination_revenue_insert",
+                                            
"auditor_historic_denomination_revenue_insert",
                                             params);
 }
 
@@ -2007,9 +2168,9 @@ postgres_select_historic_denom_revenue (void *cls,
     .cb_cls = cb_cls
   };
   enum GNUNET_DB_QueryStatus qs;
-  
+
   qs = GNUNET_PQ_eval_prepared_multi_select (session->conn,
-                                            
"historic_denomination_revenue_select",
+                                            
"auditor_historic_denomination_revenue_select",
                                             params,
                                             &historic_denom_revenue_cb,
                                             &hrc);
@@ -2051,7 +2212,7 @@ postgres_insert_historic_losses (void *cls,
   };
 
   return GNUNET_PQ_eval_prepared_non_select (session->conn,
-                                            "historic_losses_insert",
+                                            "auditor_historic_losses_insert",
                                             params);
 }
 
@@ -2066,7 +2227,7 @@ struct LossContext
    */
   TALER_AUDITORDB_HistoricLossesDataCallback cb;
 
-  /** 
+  /**
    * Closure for @e cb.
    */
   void *cb_cls;
@@ -2093,7 +2254,7 @@ losses_cb (void *cls,
           unsigned int num_results)
 {
   struct LossContext *lctx = cls;
-  
+
   for (unsigned int i = 0; i < num_results; i++)
   {
     struct GNUNET_HashCode denom_pub_hash;
@@ -2105,7 +2266,7 @@ losses_cb (void *cls,
       TALER_PQ_result_spec_amount ("loss_balance", &loss_balance),
       GNUNET_PQ_result_spec_end
     };
-    
+
     if (GNUNET_OK !=
         GNUNET_PQ_extract_result (result,
                                  rs,
@@ -2155,7 +2316,7 @@ postgres_select_historic_losses (void *cls,
   enum GNUNET_DB_QueryStatus qs;
 
   qs = GNUNET_PQ_eval_prepared_multi_select (session->conn,
-                                            "historic_losses_select",
+                                            "auditor_historic_losses_select",
                                             params,
                                             &losses_cb,
                                             &lctx);
@@ -2193,7 +2354,7 @@ postgres_insert_historic_reserve_revenue (void *cls,
   };
 
   return GNUNET_PQ_eval_prepared_non_select (session->conn,
-                                            "historic_reserve_summary_insert",
+                                            
"auditor_historic_reserve_summary_insert",
                                             params);
 }
 
@@ -2247,7 +2408,7 @@ historic_reserve_revenue_cb (void *cls,
       TALER_PQ_result_spec_amount ("reserve_profits", &reserve_profits),
       GNUNET_PQ_result_spec_end
     };
-    
+
     if (GNUNET_OK !=
         GNUNET_PQ_extract_result (result,
                                  rs,
@@ -2294,9 +2455,9 @@ postgres_select_historic_reserve_revenue (void *cls,
     .cb = cb,
     .cb_cls = cb_cls
   };
-  
+
   qs = GNUNET_PQ_eval_prepared_multi_select (session->conn,
-                                            "historic_reserve_summary_select",
+                                            
"auditor_historic_reserve_summary_select",
                                             params,
                                             &historic_reserve_revenue_cb,
                                             &hrc);
@@ -2329,7 +2490,7 @@ postgres_insert_predicted_result (void *cls,
   };
 
   return GNUNET_PQ_eval_prepared_non_select (session->conn,
-                                            "predicted_result_insert",
+                                            "auditor_predicted_result_insert",
                                             params);
 }
 
@@ -2357,7 +2518,7 @@ postgres_update_predicted_result (void *cls,
   };
 
   return GNUNET_PQ_eval_prepared_non_select (session->conn,
-                                            "predicted_result_update",
+                                            "auditor_predicted_result_update",
                                             params);
 }
 
@@ -2388,7 +2549,7 @@ postgres_get_predicted_balance (void *cls,
   };
 
   return GNUNET_PQ_eval_prepared_singleton_select (session->conn,
-                                                  "predicted_result_select",
+                                                  
"auditor_predicted_result_select",
                                                   params,
                                                   rs);
 }
@@ -2453,6 +2614,10 @@ libtaler_plugin_auditordb_postgres_init (void *cls)
   plugin->update_auditor_progress = &postgres_update_auditor_progress;
   plugin->insert_auditor_progress = &postgres_insert_auditor_progress;
 
+  plugin->get_wire_auditor_progress = &postgres_get_wire_auditor_progress;
+  plugin->update_wire_auditor_progress = 
&postgres_update_wire_auditor_progress;
+  plugin->insert_wire_auditor_progress = 
&postgres_insert_wire_auditor_progress;
+
   plugin->del_reserve_info = &postgres_del_reserve_info;
   plugin->get_reserve_info = &postgres_get_reserve_info;
   plugin->update_reserve_info = &postgres_update_reserve_info;
diff --git a/src/benchmark/taler-exchange-benchmark.c 
b/src/benchmark/taler-exchange-benchmark.c
index 10a5eed..93afb68 100644
--- a/src/benchmark/taler-exchange-benchmark.c
+++ b/src/benchmark/taler-exchange-benchmark.c
@@ -487,13 +487,12 @@ static const struct TALER_EXCHANGE_DenomPublicKey *
 find_pk (const struct TALER_EXCHANGE_Keys *keys,
          const struct TALER_Amount *amount)
 {
-  unsigned int i;
   struct GNUNET_TIME_Absolute now;
   struct TALER_EXCHANGE_DenomPublicKey *pk;
   char *str;
 
   now = GNUNET_TIME_absolute_get ();
-  for (i=0;i<keys->num_denom_keys;i++)
+  for (unsigned int i=0;i<keys->num_denom_keys;i++)
   {
     pk = &keys->denom_keys[i];
     if ( (0 == TALER_amount_cmp (amount,
@@ -504,7 +503,7 @@ find_pk (const struct TALER_EXCHANGE_Keys *keys,
   }
   /* do 2nd pass to check if expiration times are to blame for failure */
   str = TALER_amount_to_string (amount);
-  for (i=0;i<keys->num_denom_keys;i++)
+  for (unsigned int i=0;i<keys->num_denom_keys;i++)
   {
     pk = &keys->denom_keys[i];
     if ( (0 == TALER_amount_cmp (amount,
@@ -883,8 +882,9 @@ spend_coin (struct Coin *coin,
   dr.purpose.size = htonl (sizeof (struct TALER_DepositRequestPS));
   dr.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_DEPOSIT);
   dr.h_contract_terms = h_contract_terms;
-  TALER_JSON_hash (merchant_details,
-                  &dr.h_wire);
+  GNUNET_assert (GNUNET_OK ==
+                 TALER_JSON_hash (merchant_details,
+                                  &dr.h_wire));
 
   dr.timestamp = GNUNET_TIME_absolute_hton (timestamp);
   dr.refund_deadline = GNUNET_TIME_absolute_hton (refund_deadline);
@@ -1188,12 +1188,11 @@ benchmark_run (void *cls)
  * @return #GNUNET_OK if the array is correctly built, #GNUNET_SYSERR
  * otherwise
  */
-static unsigned int
+static int
 build_refresh ()
 {
   char *amount_str;
   struct TALER_Amount amount;
-  unsigned int i;
   const struct TALER_EXCHANGE_DenomPublicKey *picked_denom;
   const struct TALER_EXCHANGE_Keys *keys;
 
@@ -1201,7 +1200,7 @@ build_refresh ()
                     refresh_pk_len,
                     0);
   keys = TALER_EXCHANGE_get_keys (exchange);
-  for (i=0; NULL != refresh_denoms[i]; i++)
+  for (unsigned int i=0; NULL != refresh_denoms[i]; i++)
   {
     GNUNET_asprintf (&amount_str,
                     "%s:%s",
@@ -1292,7 +1291,6 @@ cert_cb (void *cls,
 static void
 do_shutdown (void *cls)
 {
-  unsigned int i;
   struct GNUNET_TIME_Relative duration;
 
   if (warm >= WARM_THRESHOLD)
@@ -1304,7 +1302,7 @@ do_shutdown (void *cls)
     GNUNET_SCHEDULER_cancel (benchmark_task);
     benchmark_task = NULL;
   }
-  for (i=0; i<nreserves; i++)
+  for (unsigned int i=0; i<nreserves; i++)
   {
     if (NULL != reserves[i].aih)
     {
@@ -1315,7 +1313,7 @@ do_shutdown (void *cls)
       reserves[i].aih = NULL;
     }
   }
-  for (i=0; i<COINS_PER_RESERVE * nreserves; i++)
+  for (unsigned int i=0; i<COINS_PER_RESERVE * nreserves; i++)
   {
     struct Coin *coin = &coins[i];
 
@@ -1438,8 +1436,6 @@ run (void *cls)
   char *bank_details_filename;
   char *merchant_details_filename;
   struct GNUNET_CRYPTO_EddsaPrivateKey *priv;
-  unsigned int i;
-  unsigned int j;
 
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "gotten pool_size of %d\n",
@@ -1519,7 +1515,7 @@ run (void *cls)
   ncoins = COINS_PER_RESERVE * nreserves;
   coins = GNUNET_new_array (ncoins,
                             struct Coin);
-  for (i=0;i < nreserves;i++)
+  for (unsigned int i=0;i < nreserves;i++)
   {
     struct Reserve *r = &reserves[i];
 
@@ -1527,7 +1523,7 @@ run (void *cls)
     GNUNET_CONTAINER_DLL_insert (empty_reserve_head,
                                 empty_reserve_tail,
                                 r);
-    for (j=0; j < COINS_PER_RESERVE; j++)
+    for (unsigned int j=0; j < COINS_PER_RESERVE; j++)
     {
       struct Coin *coin;
       unsigned int coin_index;
@@ -1603,7 +1599,12 @@ main (int argc,
   GNUNET_assert (COIN_VALUE <= (1LL << REFRESH_SLOTS_NEEDED));
   ret = GNUNET_GETOPT_run ("taler-exchange-benchmark",
                           options, argc, argv);
-  GNUNET_assert (GNUNET_SYSERR != ret);
+  if (GNUNET_SYSERR == ret)
+  {
+    fprintf (stderr,
+            "Invalid command line arguments\n");
+    return 1;
+  }
   if (GNUNET_NO == ret)
     return 0;
   if ( (0 != num_iterations) &&
diff --git a/src/exchange-lib/Makefile.am b/src/exchange-lib/Makefile.am
index d891d1d..ce1653c 100644
--- a/src/exchange-lib/Makefile.am
+++ b/src/exchange-lib/Makefile.am
@@ -45,7 +45,8 @@ endif
 endif
 
 check_PROGRAMS = \
-  test_exchange_api
+  test_exchange_api \
+  test_exchange_api_keys_cherry_picking
 
 AM_TESTS_ENVIRONMENT=export 
TALER_PREFIX=$${TALER_PREFIX:address@hidden@};export 
PATH=$${TALER_PREFIX:address@hidden@}/bin:$$PATH;
 
@@ -64,8 +65,21 @@ test_exchange_api_LDADD = \
   -lgnunetutil \
   -ljansson
 
+test_exchange_api_keys_cherry_picking_SOURCES = \
+  test_exchange_api_keys_cherry_picking.c
+test_exchange_api_keys_cherry_picking_LDADD = \
+  libtalerexchange.la \
+  $(LIBGCRYPT_LIBS) \
+  $(top_builddir)/src/json/libtalerjson.la \
+  $(top_builddir)/src/util/libtalerutil.la \
+  -lgnunetcurl \
+  -lgnunetutil \
+  -ljansson
+
 EXTRA_DIST = \
   test_exchange_api_home/.local/share/taler/exchange/offline-keys/master.priv \
   test_exchange_api_home/.config/taler/test.json \
   test_exchange_api_home/.config/taler/sepa.json \
-  test_exchange_api.conf
+  test_exchange_api.conf \
+  test_exchange_api_keys_cherry_picking.conf \
+  test_exchange_api_keys_cherry_picking_extended.conf
diff --git a/src/exchange-lib/exchange_api_common.c 
b/src/exchange-lib/exchange_api_common.c
index 99086a7..9d2a827 100644
--- a/src/exchange-lib/exchange_api_common.c
+++ b/src/exchange-lib/exchange_api_common.c
@@ -42,7 +42,6 @@ TALER_EXCHANGE_verify_coin_history (const char *currency,
                                     struct TALER_Amount *total)
 {
   size_t len;
-  size_t off;
   int add;
   struct TALER_Amount rtotal;
 
@@ -57,11 +56,13 @@ TALER_EXCHANGE_verify_coin_history (const char *currency,
     GNUNET_break_op (0);
     return GNUNET_SYSERR;
   }
-  TALER_amount_get_zero (currency,
-                         total);
-  TALER_amount_get_zero (currency,
-                         &rtotal);
-  for (off=0;off<len;off++)
+  GNUNET_assert (GNUNET_OK ==
+                 TALER_amount_get_zero (currency,
+                                        total));
+  GNUNET_assert (GNUNET_OK ==
+                 TALER_amount_get_zero (currency,
+                                        &rtotal));
+  for (size_t off=0;off<len;off++)
   {
     json_t *transaction;
     struct TALER_Amount amount;
diff --git a/src/exchange-lib/exchange_api_deposit.c 
b/src/exchange-lib/exchange_api_deposit.c
index 4937b14..d90b1aa 100644
--- a/src/exchange-lib/exchange_api_deposit.c
+++ b/src/exchange-lib/exchange_api_deposit.c
@@ -415,9 +415,13 @@ TALER_EXCHANGE_deposit (struct TALER_EXCHANGE_Handle 
*exchange,
   GNUNET_assert (GNUNET_YES ==
                 MAH_handle_is_ready (exchange));
   /* initialize h_wire */
-  GNUNET_assert (GNUNET_OK ==
-                TALER_JSON_hash (wire_details,
-                                 &h_wire));
+  if (GNUNET_OK !=
+      TALER_JSON_hash (wire_details,
+                       &h_wire))
+  {
+    GNUNET_break (0);
+    return NULL;
+  }
   key_state = TALER_EXCHANGE_get_keys (exchange);
   dki = TALER_EXCHANGE_get_denomination_key (key_state,
                                              denom_pub);
diff --git a/src/exchange-lib/exchange_api_handle.c 
b/src/exchange-lib/exchange_api_handle.c
index a03f7d4..e89448d 100644
--- a/src/exchange-lib/exchange_api_handle.c
+++ b/src/exchange-lib/exchange_api_handle.c
@@ -1,6 +1,6 @@
 /*
   This file is part of TALER
-  Copyright (C) 2014, 2015 GNUnet e.V.
+  Copyright (C) 2014-2017 GNUnet e.V.
 
   TALER is free software; you can redistribute it and/or modify it under the
   terms of the GNU General Public License as published by the Free Software
@@ -33,12 +33,12 @@
  * Which revision of the Taler protocol is implemented
  * by this library?  Used to determine compatibility.
  */
-#define TALER_PROTOCOL_CURRENT 0
+#define TALER_PROTOCOL_CURRENT 1
 
 /**
  * How many revisions back are we compatible to?
  */
-#define TALER_PROTOCOL_AGE 0
+#define TALER_PROTOCOL_AGE 1
 
 
 /**
@@ -285,7 +285,6 @@ parse_json_denomkey (struct TALER_EXCHANGE_DenomPublicKey 
*denom_key,
   struct TALER_DenominationKeyValidityPS denom_key_issue;
   struct GNUNET_CRYPTO_RsaPublicKey *pk;
   struct GNUNET_CRYPTO_EddsaSignature sig;
-
   struct GNUNET_JSON_Specification spec[] = {
     GNUNET_JSON_spec_fixed_auto ("master_sig",
                                 &sig),
@@ -320,7 +319,9 @@ parse_json_denomkey (struct TALER_EXCHANGE_DenomPublicKey 
*denom_key,
     return GNUNET_SYSERR;
   }
 
-  memset (&denom_key_issue, 0, sizeof (denom_key_issue));
+  memset (&denom_key_issue,
+          0,
+          sizeof (denom_key_issue));
   GNUNET_CRYPTO_rsa_public_key_hash (pk,
                                      &denom_key_issue.denom_hash);
   denom_key_issue.purpose.purpose
@@ -436,7 +437,7 @@ parse_json_auditor (struct 
TALER_EXCHANGE_AuditorInformation *auditor,
         GNUNET_JSON_parse (key,
                            kspec,
                            NULL, NULL))
-      {
+    {
       GNUNET_break_op (0);
       continue;
     }
@@ -471,6 +472,7 @@ parse_json_auditor (struct 
TALER_EXCHANGE_AuditorInformation *auditor,
     TALER_amount_hton (&kv.fee_refund,
                        &dk->fee_refund);
     kv.denom_hash = dk->h_key;
+
     if (GNUNET_OK !=
         GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_AUDITOR_EXCHANGE_KEYS,
                                     &kv.purpose,
@@ -505,43 +507,37 @@ decode_keys_json (const json_t *resp_obj,
                  enum TALER_EXCHANGE_VersionCompatibility *vc)
 {
   struct GNUNET_TIME_Absolute list_issue_date;
+  struct GNUNET_TIME_Absolute last_denom_issue_date;
   struct TALER_ExchangeSignatureP sig;
   struct TALER_ExchangeKeySetPS ks;
   struct GNUNET_HashContext *hash_context;
   struct TALER_ExchangePublicKeyP pub;
+  unsigned int age;
+  unsigned int revision;
+  unsigned int current;
 
-  /* FIXME: #4840: handle incremental / cherry-picked /keys! */
-  memset (key_data,
-         0,
-         sizeof (struct TALER_EXCHANGE_Keys));
   if (JSON_OBJECT != json_typeof (resp_obj))
+  {
+    GNUNET_break_op (0);
     return GNUNET_SYSERR;
-
-  hash_context = GNUNET_CRYPTO_hash_context_start ();
-  /* parse the master public key and issue date of the response */
+  }
+  /* check the version */
   {
     const char *ver;
-    unsigned int age;
-    unsigned int revision;
-    unsigned int current;
     struct GNUNET_JSON_Specification spec[] = {
       GNUNET_JSON_spec_string ("version",
                                &ver),
-      GNUNET_JSON_spec_fixed_auto ("master_public_key",
-                                   &key_data->master_pub),
-      GNUNET_JSON_spec_fixed_auto ("eddsa_sig",
-                                   &sig),
-      GNUNET_JSON_spec_fixed_auto ("eddsa_pub",
-                                   &pub),
-      GNUNET_JSON_spec_absolute_time ("list_issue_date",
-                                      &list_issue_date),
       GNUNET_JSON_spec_end()
     };
 
-    EXITIF (GNUNET_OK !=
-            GNUNET_JSON_parse (resp_obj,
-                               spec,
-                               NULL, NULL));
+    if (GNUNET_OK !=
+        GNUNET_JSON_parse (resp_obj,
+                           spec,
+                           NULL, NULL))
+    {
+      GNUNET_break_op (0);
+      return GNUNET_SYSERR;
+    }
     if (3 != sscanf (ver,
                     "%u:%u:%u",
                     &current,
@@ -549,7 +545,6 @@ decode_keys_json (const json_t *resp_obj,
                     &age))
     {
       GNUNET_break_op (0);
-      GNUNET_CRYPTO_hash_context_abort (hash_context);
       return GNUNET_SYSERR;
     }
     *vc = TALER_EXCHANGE_VC_MATCH;
@@ -568,6 +563,27 @@ decode_keys_json (const json_t *resp_obj,
     key_data->version = GNUNET_strdup (ver);
   }
 
+  /* parse the master public key and issue date of the response */
+  hash_context = GNUNET_CRYPTO_hash_context_start ();
+  {
+    struct GNUNET_JSON_Specification spec[] = {
+      GNUNET_JSON_spec_fixed_auto ("master_public_key",
+                                   &key_data->master_pub),
+      GNUNET_JSON_spec_fixed_auto ("eddsa_sig",
+                                   &sig),
+      GNUNET_JSON_spec_fixed_auto ("eddsa_pub",
+                                   &pub),
+      GNUNET_JSON_spec_absolute_time ("list_issue_date",
+                                      &list_issue_date),
+      GNUNET_JSON_spec_end()
+    };
+
+    EXITIF (GNUNET_OK !=
+            GNUNET_JSON_parse (resp_obj,
+                               spec,
+                               NULL, NULL));
+  }
+
   /* parse the signing keys */
   {
     json_t *sign_keys_array;
@@ -592,7 +608,9 @@ decode_keys_json (const json_t *resp_obj,
     }
   }
 
-  /* parse the denomination keys */
+  /* parse the denomination keys, merging with the
+     possibly EXISTING array as required (/keys cherry picking) */
+  last_denom_issue_date.abs_value_us = 0LLU;
   {
     json_t *denom_keys_array;
     json_t *denom_key_obj;
@@ -601,51 +619,96 @@ decode_keys_json (const json_t *resp_obj,
     EXITIF (NULL == (denom_keys_array =
                      json_object_get (resp_obj, "denoms")));
     EXITIF (JSON_ARRAY != json_typeof (denom_keys_array));
-    if (0 == (key_data->num_denom_keys = json_array_size (denom_keys_array)))
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  "Found no denomination keys at this exchange\n");
-      goto EXITIF_exit;
-    }
-    key_data->denom_keys = GNUNET_new_array (key_data->num_denom_keys,
-                                             struct 
TALER_EXCHANGE_DenomPublicKey);
+
     index = 0;
     json_array_foreach (denom_keys_array, index, denom_key_obj) {
+      struct TALER_EXCHANGE_DenomPublicKey dk;
+      bool found = false;
+
       EXITIF (GNUNET_SYSERR ==
-              parse_json_denomkey (&key_data->denom_keys[index],
+              parse_json_denomkey (&dk,
                                    denom_key_obj,
                                    &key_data->master_pub,
                                    hash_context));
-    }
+      for (unsigned int j=0;j<key_data->num_denom_keys;j++)
+      {
+       if (0 == memcmp (&dk,
+                        &key_data->denom_keys[j],
+                        sizeof (dk)))
+       {
+         found = true;
+         break;
+       }
+      }
+      if (found)
+      {
+       /* 0:0:0 did not support /keys cherry picking */
+       GNUNET_break_op (0 == current);
+       continue;
+      }
+      if (key_data->denom_keys_size == key_data->num_denom_keys)
+       GNUNET_array_grow (key_data->denom_keys,
+                          key_data->denom_keys_size,
+                          key_data->denom_keys_size * 2 + 2);
+      key_data->denom_keys[key_data->num_denom_keys++] = dk;
+
+      /* Update "last_denom_issue_date" */
+      last_denom_issue_date
+        = GNUNET_TIME_absolute_max (last_denom_issue_date,
+                                    dk.valid_from);
+    };
   }
+  key_data->last_denom_issue_date = last_denom_issue_date;
 
   /* parse the auditor information */
   {
     json_t *auditors_array;
     json_t *auditor_info;
-    unsigned int len;
     unsigned int index;
 
     EXITIF (NULL == (auditors_array =
                      json_object_get (resp_obj, "auditors")));
     EXITIF (JSON_ARRAY != json_typeof (auditors_array));
-    len = json_array_size (auditors_array);
-    if (0 != len)
-    {
-      key_data->auditors = GNUNET_new_array (len,
-                                             struct 
TALER_EXCHANGE_AuditorInformation);
-      index = 0;
-      json_array_foreach (auditors_array, index, auditor_info) {
-        EXITIF (GNUNET_SYSERR ==
-                parse_json_auditor (&key_data->auditors[index],
-                                    auditor_info,
-                                    key_data));
+
+    /* Merge with the existing auditor information we have (/keys cherry 
picking) */
+    index = 0;
+    json_array_foreach (auditors_array, index, auditor_info) {
+      struct TALER_EXCHANGE_AuditorInformation ai;
+      bool found = false;
+
+      EXITIF (GNUNET_SYSERR ==
+              parse_json_auditor (&ai,
+                                  auditor_info,
+                                  key_data));
+      for (unsigned int j=0;j<key_data->num_auditors;j++)
+      {
+        struct TALER_EXCHANGE_AuditorInformation *aix = &key_data->auditors[j];
+       if (0 == memcmp (&ai.auditor_pub,
+                        &aix->auditor_pub,
+                        sizeof (struct TALER_AuditorPublicKeyP)))
+       {
+         found = true;
+          /* Merge denomination key signatures of downloaded /keys into 
existing
+             auditor information 'aix'. */
+          GNUNET_array_grow (aix->denom_keys,
+                             aix->num_denom_keys,
+                             aix->num_denom_keys + ai.num_denom_keys);
+          memcpy (&aix->denom_keys[aix->num_denom_keys - ai.num_denom_keys],
+                  ai.denom_keys,
+                  ai.num_denom_keys * sizeof (struct 
TALER_EXCHANGE_DenomPublicKey *));
+         break;
+       }
       }
-      key_data->num_auditors = len;
-    }
+      if (found)
+        continue; /* we are done */
+      if (key_data->auditors_size == key_data->num_auditors)
+       GNUNET_array_grow (key_data->auditors,
+                          key_data->auditors_size,
+                          key_data->auditors_size * 2 + 2);
+      key_data->auditors[key_data->num_auditors++] = ai;
+    };
   }
-  key_data->last_issue_date = list_issue_date;
-  
+
   /* Validate signature... */
   ks.purpose.size = htonl (sizeof (ks));
   ks.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_KEY_SET);
@@ -655,7 +718,7 @@ decode_keys_json (const json_t *resp_obj,
   hash_context = NULL;
   EXITIF (GNUNET_OK !=
           TALER_EXCHANGE_test_signing_key (key_data,
-                                       &pub));
+                                          &pub));
   EXITIF (GNUNET_OK !=
           GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_KEY_SET,
                                       &ks.purpose,
@@ -684,7 +747,7 @@ free_key_data (struct TALER_EXCHANGE_Keys *key_data)
   for (unsigned int i=0;i<key_data->num_denom_keys;i++)
     GNUNET_CRYPTO_rsa_public_key_free 
(key_data->denom_keys[i].key.rsa_public_key);
   GNUNET_array_grow (key_data->denom_keys,
-                     key_data->num_denom_keys,
+                     key_data->denom_keys_size,
                      0);
   for (unsigned int i=0;i<key_data->num_auditors;i++)
   {
@@ -694,7 +757,7 @@ free_key_data (struct TALER_EXCHANGE_Keys *key_data)
     GNUNET_free (key_data->auditors[i].auditor_url);
   }
   GNUNET_array_grow (key_data->auditors,
-                     key_data->num_auditors,
+                     key_data->auditors_size,
                      0);
   GNUNET_free_non_null (key_data->version);
   key_data->version = NULL;
@@ -715,14 +778,17 @@ request_keys (struct TALER_EXCHANGE_Handle *exchange);
  * not trigger download.
  *
  * @param exchange exchange to check keys for
+ * @param force_download #GNUNET_YES to force download even if /keys is still 
valid
  * @return until when the response is current, 0 if we are re-downloading
  */
 struct GNUNET_TIME_Absolute
-TALER_EXCHANGE_check_keys_current (struct TALER_EXCHANGE_Handle *exchange)
+TALER_EXCHANGE_check_keys_current (struct TALER_EXCHANGE_Handle *exchange,
+                                   int force_download)
 {
   if (NULL != exchange->kr)
     return GNUNET_TIME_UNIT_ZERO_ABS;
-  if (0 < GNUNET_TIME_absolute_get_remaining 
(exchange->key_data_expiration).rel_value_us)
+  if ( (GNUNET_NO == force_download) &&
+       (0 < GNUNET_TIME_absolute_get_remaining 
(exchange->key_data_expiration).rel_value_us) )
     return exchange->key_data_expiration;
   request_keys (exchange);
   return GNUNET_TIME_UNIT_ZERO_ABS;
@@ -753,6 +819,9 @@ keys_completed_cb (void *cls,
               kr->url,
               response_code);
   kd_old = exchange->key_data;
+  memset (&kd,
+          0,
+          sizeof (struct TALER_EXCHANGE_Keys));
   vc = TALER_EXCHANGE_VC_PROTOCOL_ERROR;
   switch (response_code)
   {
@@ -764,6 +833,44 @@ keys_completed_cb (void *cls,
       response_code = 0;
       break;
     }
+    /* We keep the denomination keys and auditor signatures from the
+       previous iteration (/keys cherry picking) */
+    kd.num_denom_keys = kd_old.num_denom_keys;
+    GNUNET_array_grow (kd.denom_keys,
+                       kd.denom_keys_size,
+                       kd.num_denom_keys);
+    /* First make a shallow copy, we then need another pass for the RSA key... 
*/
+    memcpy (kd.denom_keys,
+            kd_old.denom_keys,
+            kd_old.num_denom_keys * sizeof (struct 
TALER_EXCHANGE_DenomPublicKey));
+    for (unsigned int i=0;i<kd_old.num_denom_keys;i++)
+      kd.denom_keys[i].key.rsa_public_key
+        = GNUNET_CRYPTO_rsa_public_key_dup 
(kd_old.denom_keys[i].key.rsa_public_key);
+
+    kd.num_auditors = kd_old.num_auditors;
+    kd.auditors = GNUNET_new_array (kd.num_auditors,
+                                    struct TALER_EXCHANGE_AuditorInformation);
+    /* Now the necessary deep copy... */
+    for (unsigned int i=0;i<kd_old.num_auditors;i++)
+    {
+      const struct TALER_EXCHANGE_AuditorInformation *aold = 
&kd_old.auditors[i];
+      struct TALER_EXCHANGE_AuditorInformation *anew = &kd.auditors[i];
+
+      anew->auditor_pub = aold->auditor_pub;
+      anew->auditor_url = GNUNET_strdup (aold->auditor_url);
+      GNUNET_array_grow (anew->denom_keys,
+                         anew->num_denom_keys,
+                         aold->num_denom_keys);
+      for (unsigned int j=0;j<aold->num_denom_keys;j++)
+      {
+        /* offsets will map 1:1 */
+        unsigned int off = aold->denom_keys[j] - kd_old.denom_keys;
+
+        GNUNET_assert (off < kd_old.num_denom_keys);
+        anew->denom_keys[j] = &kd.denom_keys[off];
+      }
+    }
+
     if (GNUNET_OK !=
         decode_keys_json (resp_obj,
                           &kd,
@@ -772,7 +879,6 @@ keys_completed_cb (void *cls,
       response_code = 0;
       break;
     }
-    exchange->key_data = kd;
     json_decref (exchange->key_data_raw);
     exchange->key_data_raw = json_deep_copy (resp_obj);
     break;
@@ -782,6 +888,7 @@ keys_completed_cb (void *cls,
                 (unsigned int) response_code);
     break;
   }
+  exchange->key_data = kd;
 
   if (MHD_HTTP_OK != response_code)
   {
@@ -894,50 +1001,32 @@ static int
 parse_date_string (const char *date,
                    struct GNUNET_TIME_Absolute *at)
 {
-  static const char *const days[] =
-    { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
-  static const char *const mons[] =
-    { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
-      "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"  };
   struct tm now;
   time_t t;
-  char day[4];
-  char mon[4];
-  unsigned int i;
-  unsigned int mday;
-  unsigned int year;
-  unsigned int h;
-  unsigned int m;
-  unsigned int s;
-
-  if (7 != sscanf (date,
-                   "%3s, %02u %3s %04u %02u:%02u:%02u GMT",
-                   day,
-                   &mday,
-                   mon,
-                   &year,
-                   &h,
-                   &m,
-                   &s))
-    return GNUNET_SYSERR;
-  memset (&now, 0, sizeof (now));
-  now.tm_year = year - 1900;
-  now.tm_mday = mday;
-  now.tm_hour = h;
-  now.tm_min = m;
-  now.tm_sec = s;
-  now.tm_wday = 7;
-  for (i=0;i<7;i++)
-    if (0 == strcasecmp (days[i], day))
-      now.tm_wday = i;
-  now.tm_mon = 12;
-  for (i=0;i<12;i++)
-    if (0 == strcasecmp (mons[i], mon))
-      now.tm_mon = i;
-  if ( (7 == now.tm_wday) ||
-       (12 == now.tm_mon) )
+  const char *end;
+
+  memset (&now,
+          0,
+          sizeof (now));
+  end = strptime (date,
+                  "%a, %d %b %Y %H:%M:%S %Z", /* RFC-1123 standard spec */
+                  &now);
+  if ( (NULL == end) ||
+       ( (*end != '\n') &&
+         (*end != '\r') ) )
+  {
+    GNUNET_break_op (0);
     return GNUNET_SYSERR;
+  }
   t = mktime (&now);
+  if (((time_t) -1) == t)
+  {
+    GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
+                         "mktime");
+    return GNUNET_SYSERR;
+  }
+  if (t < 0)
+    t = 0; /* can happen due to timezone issues if date was 1.1.1970 */
   at->abs_value_us = 1000LL * 1000LL * t;
   return GNUNET_OK;
 }
@@ -980,6 +1069,7 @@ header_cb (char *buffer,
                 "Failed to parse %s-header `%s'\n",
                 MHD_HTTP_HEADER_EXPIRES,
                 val);
+    kr->expire = GNUNET_TIME_UNIT_ZERO_ABS;
   }
   GNUNET_free (val);
   return total;
@@ -1041,7 +1131,7 @@ request_keys (struct TALER_EXCHANGE_Handle *exchange)
 
     GNUNET_asprintf (&arg,
                     "/keys?last_issue_date=%llu",
-                    (unsigned long long) 
exchange->key_data.last_issue_date.abs_value_us);
+                    (unsigned long long) 
exchange->key_data.last_denom_issue_date.abs_value_us / 1000000LLU);
     kr->url = MAH_path_to_url (exchange,
                               arg);
     GNUNET_free (arg);
@@ -1122,11 +1212,10 @@ TALER_EXCHANGE_test_signing_key (const struct 
TALER_EXCHANGE_Keys *keys,
                                  const struct TALER_ExchangePublicKeyP *pub)
 {
   struct GNUNET_TIME_Absolute now;
-  unsigned int i;
 
   /* we will check using a tolerance of 1h for the time */
   now = GNUNET_TIME_absolute_get ();
-  for (i=0;i<keys->num_sign_keys;i++)
+  for (unsigned int i=0;i<keys->num_sign_keys;i++)
     if ( (keys->sign_keys[i].valid_from.abs_value_us <= now.abs_value_us + 60 
* 60 * 1000LL * 1000LL) &&
          (keys->sign_keys[i].valid_until.abs_value_us > now.abs_value_us - 60 
* 60 * 1000LL * 1000LL) &&
          (0 == memcmp (pub,
@@ -1149,9 +1238,7 @@ const struct TALER_EXCHANGE_DenomPublicKey *
 TALER_EXCHANGE_get_denomination_key (const struct TALER_EXCHANGE_Keys *keys,
                                      const struct TALER_DenominationPublicKey 
*pk)
 {
-  unsigned int i;
-
-  for (i=0;i<keys->num_denom_keys;i++)
+  for (unsigned int i=0;i<keys->num_denom_keys;i++)
     if (0 == GNUNET_CRYPTO_rsa_public_key_cmp (pk->rsa_public_key,
                                                
keys->denom_keys[i].key.rsa_public_key))
       return &keys->denom_keys[i];
@@ -1170,9 +1257,7 @@ const struct TALER_EXCHANGE_DenomPublicKey *
 TALER_EXCHANGE_get_denomination_key_by_hash (const struct TALER_EXCHANGE_Keys 
*keys,
                                              const struct GNUNET_HashCode *hc)
 {
-  unsigned int i;
-
-  for (i=0;i<keys->num_denom_keys;i++)
+  for (unsigned int i=0;i<keys->num_denom_keys;i++)
     if (0 == memcmp (hc,
                      &keys->denom_keys[i].h_key,
                      sizeof (struct GNUNET_HashCode)))
@@ -1190,7 +1275,8 @@ TALER_EXCHANGE_get_denomination_key_by_hash (const struct 
TALER_EXCHANGE_Keys *k
 const struct TALER_EXCHANGE_Keys *
 TALER_EXCHANGE_get_keys (struct TALER_EXCHANGE_Handle *exchange)
 {
-  (void) TALER_EXCHANGE_check_keys_current (exchange);
+  (void) TALER_EXCHANGE_check_keys_current (exchange,
+                                            GNUNET_NO);
   return &exchange->key_data;
 }
 
@@ -1205,10 +1291,10 @@ TALER_EXCHANGE_get_keys (struct TALER_EXCHANGE_Handle 
*exchange)
 json_t *
 TALER_EXCHANGE_get_keys_raw (struct TALER_EXCHANGE_Handle *exchange)
 {
-  (void) TALER_EXCHANGE_check_keys_current (exchange);
+  (void) TALER_EXCHANGE_check_keys_current (exchange,
+                                            GNUNET_NO);
   return json_deep_copy (exchange->key_data_raw);
 }
 
 
-
 /* end of exchange_api_handle.c */
diff --git a/src/exchange-lib/exchange_api_refresh_link.c 
b/src/exchange-lib/exchange_api_refresh_link.c
index 5b2286e..5b7f686 100644
--- a/src/exchange-lib/exchange_api_refresh_link.c
+++ b/src/exchange-lib/exchange_api_refresh_link.c
@@ -235,6 +235,7 @@ parse_refresh_link_ok (struct 
TALER_EXCHANGE_RefreshLinkHandle *rlh,
       /* decode all coins */
       for (i=0;i<json_array_size (jsona);i++)
       {
+        GNUNET_assert (i + off_coin < num_coins);
        if (GNUNET_OK !=
            parse_refresh_link_coin (rlh,
                                     json_array_get (jsona,
@@ -281,6 +282,7 @@ parse_refresh_link_ok (struct 
TALER_EXCHANGE_RefreshLinkHandle *rlh,
     }
 
     /* clean up */
+    GNUNET_assert (off_coin <= num_coins);
     for (i=0;i<off_coin;i++)
     {
       if (NULL != sigs[i].rsa_signature)
diff --git a/src/exchange-lib/exchange_api_reserve.c 
b/src/exchange-lib/exchange_api_reserve.c
index 4b5152c..22e0e3d 100644
--- a/src/exchange-lib/exchange_api_reserve.c
+++ b/src/exchange-lib/exchange_api_reserve.c
@@ -104,10 +104,12 @@ parse_reserve_history (struct TALER_EXCHANGE_Handle 
*exchange,
   struct TALER_Amount total_out;
   size_t off;
 
-  TALER_amount_get_zero (currency,
-                         &total_in);
-  TALER_amount_get_zero (currency,
-                         &total_out);
+  GNUNET_assert (GNUNET_OK ==
+                 TALER_amount_get_zero (currency,
+                                        &total_in));
+  GNUNET_assert (GNUNET_OK ==
+                 TALER_amount_get_zero (currency,
+                                        &total_out));
   uuid_off = 0;
   for (off=0;off<history_length;off++)
   {
@@ -354,8 +356,13 @@ parse_reserve_history (struct TALER_EXCHANGE_Handle 
*exchange,
       }
       TALER_amount_hton (&rcc.closing_amount,
                         &amount);
-      TALER_JSON_hash 
(rhistory[off].details.close_details.receiver_account_details,
-                      &rcc.h_wire);
+      if (GNUNET_OK !=
+          TALER_JSON_hash 
(rhistory[off].details.close_details.receiver_account_details,
+                           &rcc.h_wire))
+      {
+        GNUNET_break (0);
+        return GNUNET_SYSERR;
+      }
       rcc.wtid = rhistory[off].details.close_details.wtid;
       rcc.purpose.size = htonl (sizeof (rcc));
       rcc.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_RESERVE_CLOSED);
@@ -820,7 +827,18 @@ reserve_withdraw_payment_required (struct 
TALER_EXCHANGE_ReserveWithdrawHandle *
      total incoming and outgoing amounts */
   len = json_array_size (history);
   {
-    struct TALER_EXCHANGE_ReserveHistory rhistory[len];
+    struct TALER_EXCHANGE_ReserveHistory *rhistory;
+
+    /* Use heap allocation as "len" may be very big and thus this may
+       not fit on the stack. Use "GNUNET_malloc_large" as a malicious
+       exchange may theoretically try to crash us by giving a history
+       that does not fit into our memory. */
+    rhistory = GNUNET_malloc_large (sizeof (struct 
TALER_EXCHANGE_ReserveHistory) * len);
+    if (NULL == rhistory)
+    {
+      GNUNET_break (0);
+      return GNUNET_SYSERR;
+    }
 
     if (GNUNET_OK !=
         parse_reserve_history (wsh->exchange,
diff --git a/src/exchange-lib/test_exchange_api.c 
b/src/exchange-lib/test_exchange_api.c
index b5b6804..70fb3ff 100644
--- a/src/exchange-lib/test_exchange_api.c
+++ b/src/exchange-lib/test_exchange_api.c
@@ -1709,8 +1709,9 @@ wire_deposits_cb (void *cls,
         wire = json_loads (dep->details.deposit.wire_details,
                            JSON_REJECT_DUPLICATES,
                            NULL);
-        TALER_JSON_hash (wire,
-                         &hw);
+        GNUNET_assert (GNUNET_OK ==
+                       TALER_JSON_hash (wire,
+                                        &hw));
         json_decref (wire);
         if (0 != memcmp (&hw,
                          h_wire,
@@ -2261,8 +2262,9 @@ interpreter_run (void *cls)
         fail (is);
         return;
       }
-      TALER_JSON_hash (contract_terms,
-                       &h_contract_terms);
+      GNUNET_assert (GNUNET_OK ==
+                     TALER_JSON_hash (contract_terms,
+                                      &h_contract_terms));
       json_decref (contract_terms);
       wire = json_loads (cmd->details.deposit.wire_details,
                          JSON_REJECT_DUPLICATES,
@@ -2307,8 +2309,9 @@ interpreter_run (void *cls)
         dr.purpose.size = htonl (sizeof (struct TALER_DepositRequestPS));
         dr.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_DEPOSIT);
         dr.h_contract_terms = h_contract_terms;
-        TALER_JSON_hash (wire,
-                         &dr.h_wire);
+        GNUNET_assert (GNUNET_OK ==
+                       TALER_JSON_hash (wire,
+                                        &dr.h_wire));
         dr.timestamp = GNUNET_TIME_absolute_hton (timestamp);
         dr.refund_deadline = GNUNET_TIME_absolute_hton (refund_deadline);
         TALER_amount_hton (&dr.amount_with_fee,
@@ -2542,15 +2545,17 @@ interpreter_run (void *cls)
                          JSON_REJECT_DUPLICATES,
                          NULL);
       GNUNET_assert (NULL != wire);
-      TALER_JSON_hash (wire,
-                       &h_wire);
+      GNUNET_assert (GNUNET_OK ==
+                     TALER_JSON_hash (wire,
+                                      &h_wire));
       json_decref (wire);
       contract_terms = json_loads (ref->details.deposit.contract_terms,
                              JSON_REJECT_DUPLICATES,
                              NULL);
       GNUNET_assert (NULL != contract_terms);
-      TALER_JSON_hash (contract_terms,
-                       &h_contract_terms);
+      GNUNET_assert (GNUNET_OK ==
+                     TALER_JSON_hash (contract_terms,
+                                      &h_contract_terms));
       json_decref (contract_terms);
       cmd->details.deposit_wtid.dwh
           = TALER_EXCHANGE_track_transaction (exchange,
@@ -2665,8 +2670,9 @@ interpreter_run (void *cls)
                              JSON_REJECT_DUPLICATES,
                              NULL);
       GNUNET_assert (NULL != contract_terms);
-      TALER_JSON_hash (contract_terms,
-                       &h_contract_terms);
+      GNUNET_assert (GNUNET_OK ==
+                     TALER_JSON_hash (contract_terms,
+                                      &h_contract_terms));
       json_decref (contract_terms);
 
       coin = find_command (is,
@@ -3773,9 +3779,11 @@ main (int argc,
   GNUNET_SIGNAL_handler_uninstall (shc_chld);
   shc_chld = NULL;
   GNUNET_DISK_pipe_close (sigpipe);
-  GNUNET_OS_process_kill (exchanged,
-                          SIGTERM);
-  GNUNET_OS_process_wait (exchanged);
+  GNUNET_break (0 ==
+                GNUNET_OS_process_kill (exchanged,
+                                        SIGTERM));
+  GNUNET_break (GNUNET_OK ==
+                GNUNET_OS_process_wait (exchanged));
   GNUNET_OS_process_destroy (exchanged);
   return (GNUNET_OK == result) ? 0 : 1;
 }
diff --git a/src/exchange-lib/test_exchange_api.conf 
b/src/exchange-lib/test_exchange_api.conf
index a8543bc..6539928 100644
--- a/src/exchange-lib/test_exchange_api.conf
+++ b/src/exchange-lib/test_exchange_api.conf
@@ -26,6 +26,9 @@ BASE_URL = "https://exchange.com/";
 [exchangedb-postgres]
 DB_CONN_STR = "postgres:///talercheck"
 
+[auditordb-postgres]
+DB_CONN_STR = "postgres:///talercheck"
+
 [exchange-wire-sepa]
 # Enable 'sepa' to test SEPA-specific routines.
 ENABLE = YES
diff --git a/src/exchange-lib/test_exchange_api_keys_cherry_picking.c 
b/src/exchange-lib/test_exchange_api_keys_cherry_picking.c
new file mode 100644
index 0000000..0fbf172
--- /dev/null
+++ b/src/exchange-lib/test_exchange_api_keys_cherry_picking.c
@@ -0,0 +1,797 @@
+/*
+  This file is part of TALER
+  Copyright (C) 2014-2017 GNUnet e.V. and Inria
+
+  TALER is free software; you can redistribute it and/or modify it under the
+  terms of the GNU General Public License as published by the Free Software
+  Foundation; either version 3, or (at your option) any later version.
+
+  TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+  A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License along with
+  TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+*/
+/**
+ * @file exchange/test_exchange_api_keys_cherry_picking.c
+ * @brief testcase to test exchange's /keys cherry picking ability
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include "taler_util.h"
+#include "taler_signatures.h"
+#include "taler_exchange_service.h"
+#include "taler_json_lib.h"
+#include <gnunet/gnunet_util_lib.h>
+#include <microhttpd.h>
+
+
+/**
+ * Main execution context for the main loop.
+ */
+static struct GNUNET_CURL_Context *ctx;
+
+/**
+ * Handle to access the exchange.
+ */
+static struct TALER_EXCHANGE_Handle *exchange;
+
+/**
+ * Context for running the CURL event loop.
+ */
+static struct GNUNET_CURL_RescheduleContext *rc;
+
+/**
+ * Handle to the exchange process.
+ */
+static struct GNUNET_OS_Process *exchanged;
+
+/**
+ * Task run on timeout.
+ */
+static struct GNUNET_SCHEDULER_Task *timeout_task;
+
+/**
+ * Result of the testcases, #GNUNET_OK on success
+ */
+static int result;
+
+
+/**
+ * Opcodes for the interpreter.
+ */
+enum OpCode
+{
+  /**
+   * Termination code, stops the interpreter loop (with success).
+   */
+  OC_END = 0,
+
+  /**
+   * Run a process.
+   */
+  OC_RUN_PROCESS,
+
+  /**
+   * Signal the exchange to reload the keys.
+   */
+  OC_SIGNAL_EXCHANGE,
+
+  /**
+   * Check the /keys.
+   */
+  OC_CHECK_KEYS
+
+};
+
+
+/**
+ * Details for a exchange operation to execute.
+ */
+struct Command
+{
+  /**
+   * Opcode of the command.
+   */
+  enum OpCode oc;
+
+  /**
+   * Label for the command, can be NULL.
+   */
+  const char *label;
+
+  /**
+   * Details about the command.
+   */
+  union
+  {
+
+    struct {
+
+      /**
+       * Binary to execute.
+       */
+      const char *binary;
+
+      /**
+       * Command-line arguments for the process to be run.
+       */
+      char *const *argv;
+
+      /**
+       * Process handle.
+       */
+      struct GNUNET_OS_Process *proc;
+
+      /**
+       * ID of task called whenever we get a SIGCHILD.
+       */
+      struct GNUNET_SCHEDULER_Task *child_death_task;
+
+    } run_process;
+
+    struct {
+
+      /**
+       * Expected number of denomination keys.
+       */
+      unsigned int num_denom_keys;
+
+      /**
+       * Which generation of /keys are we verifying here?
+       * Used to make sure we got the right number of
+       * interactions.
+       */
+      unsigned int generation;
+
+    } check_keys;
+
+  } details;
+
+};
+
+
+/**
+ * State of the interpreter loop.
+ */
+struct InterpreterState
+{
+  /**
+   * Keys from the exchange.
+   */
+  const struct TALER_EXCHANGE_Keys *keys;
+
+  /**
+   * Commands the interpreter will run.
+   */
+  struct Command *commands;
+
+  /**
+   * Interpreter task (if one is scheduled).
+   */
+  struct GNUNET_SCHEDULER_Task *task;
+
+  /**
+   * Instruction pointer.  Tells #interpreter_run() which
+   * instruction to run next.
+   */
+  unsigned int ip;
+
+  /**
+   * Is the interpreter running (#GNUNET_YES) or waiting
+   * for /keys (#GNUNET_NO)?
+   */
+  int working;
+
+  /**
+   * How often have we gotten a /keys response so far?
+   */
+  unsigned int key_generation;
+
+};
+
+
+/**
+ * Pipe used to communicate child death via signal.
+ */
+static struct GNUNET_DISK_PipeHandle *sigpipe;
+
+
+/**
+ * The testcase failed, return with an error code.
+ *
+ * @param is interpreter state to clean up
+ */
+static void
+fail (struct InterpreterState *is)
+{
+  result = GNUNET_SYSERR;
+  GNUNET_SCHEDULER_shutdown ();
+}
+
+
+/**
+ * Run the main interpreter loop that performs exchange operations.
+ *
+ * @param cls contains the `struct InterpreterState`
+ */
+static void
+interpreter_run (void *cls);
+
+
+/**
+ * Run the next command with the interpreter.
+ *
+ * @param is current interpeter state.
+ */
+static void
+next_command (struct InterpreterState *is)
+{
+  if (GNUNET_SYSERR == result)
+    return; /* ignore, we already failed! */
+  is->ip++;
+  is->task = GNUNET_SCHEDULER_add_now (&interpreter_run,
+                                       is);
+}
+
+
+/**
+ * Task triggered whenever we receive a SIGCHLD (child
+ * process died).
+ *
+ * @param cls closure, NULL if we need to self-restart
+ */
+static void
+maint_child_death (void *cls)
+{
+  struct InterpreterState *is = cls;
+  struct Command *cmd = &is->commands[is->ip];
+  const struct GNUNET_DISK_FileHandle *pr;
+  char c[16];
+
+  switch (cmd->oc) {
+  case OC_RUN_PROCESS:
+    cmd->details.run_process.child_death_task = NULL;
+    pr = GNUNET_DISK_pipe_handle (sigpipe, GNUNET_DISK_PIPE_END_READ);
+    GNUNET_break (0 < GNUNET_DISK_file_read (pr, &c, sizeof (c)));
+    GNUNET_OS_process_wait (cmd->details.run_process.proc);
+    GNUNET_OS_process_destroy (cmd->details.run_process.proc);
+    cmd->details.run_process.proc = NULL;
+    break;
+  default:
+    GNUNET_break (0);
+    fail (is);
+    return;
+  }
+  next_command (is);
+}
+
+
+/**
+ * Run the main interpreter loop that performs exchange operations.
+ *
+ * @param cls contains the `struct InterpreterState`
+ */
+static void
+interpreter_run (void *cls)
+{
+  struct InterpreterState *is = cls;
+  struct Command *cmd = &is->commands[is->ip];
+  const struct GNUNET_SCHEDULER_TaskContext *tc;
+
+  is->task = NULL;
+  tc = GNUNET_SCHEDULER_get_task_context ();
+  if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
+  {
+    fprintf (stderr,
+             "Test aborted by shutdown request\n");
+    fail (is);
+    return;
+  }
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Running command `%s'\n",
+              cmd->label);
+  switch (cmd->oc)
+  {
+  case OC_END:
+    result = GNUNET_OK;
+    GNUNET_SCHEDULER_shutdown ();
+    return;
+  case OC_RUN_PROCESS:
+    {
+      const struct GNUNET_DISK_FileHandle *pr;
+
+      cmd->details.run_process.proc
+        = GNUNET_OS_start_process_vap (GNUNET_NO,
+                                       GNUNET_OS_INHERIT_STD_ALL,
+                                       NULL, NULL, NULL,
+                                       cmd->details.run_process.binary,
+                                       cmd->details.run_process.argv);
+      if (NULL == cmd->details.run_process.proc)
+      {
+        GNUNET_break (0);
+        fail (is);
+        return;
+      }
+      pr = GNUNET_DISK_pipe_handle (sigpipe,
+                                    GNUNET_DISK_PIPE_END_READ);
+      cmd->details.run_process.child_death_task
+        = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
+                                          pr,
+                                          &maint_child_death,
+                                          is);
+      return;
+    }
+  case OC_SIGNAL_EXCHANGE:
+    {
+      GNUNET_break (0 ==
+                    GNUNET_OS_process_kill (exchanged,
+                                            SIGUSR1));
+      /* give exchange time to process the signal */
+      sleep (1);
+      next_command (is);
+      return;
+    }
+  case OC_CHECK_KEYS:
+    {
+      if (is->key_generation < cmd->details.check_keys.generation)
+      {
+        /* Go back to waiting for /keys signal! */
+        is->working = GNUNET_NO;
+        GNUNET_break (0 ==
+                      TALER_EXCHANGE_check_keys_current (exchange,
+                                                         
GNUNET_YES).abs_value_us);
+        return;
+      }
+      if (is->key_generation > cmd->details.check_keys.generation)
+      {
+        /* We got /keys too often, strange. Fatal. May theoretically happen if
+           somehow we were really unlucky and /keys expired "naturally", but
+           obviously with a sane configuration this should also not be. */
+        GNUNET_break (0);
+        fail (is);
+        return;
+      }
+      /* /keys was updated, let's check they were OK! */
+      if (cmd->details.check_keys.num_denom_keys !=
+          is->keys->num_denom_keys)
+      {
+        /* Did not get the expected number of denomination keys! */
+        GNUNET_break (0);
+        fprintf (stderr,
+                 "Got %u keys in step %s\n",
+                 is->keys->num_denom_keys,
+                 cmd->label);
+        fail (is);
+        return;
+      }
+      next_command (is);
+      return;
+    }
+  default:
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Unknown instruction %d at %u (%s)\n",
+                cmd->oc,
+                is->ip,
+                cmd->label);
+    fail (is);
+    return;
+  }
+}
+
+
+/**
+ * Signal handler called for SIGCHLD.  Triggers the
+ * respective handler by writing to the trigger pipe.
+ */
+static void
+sighandler_child_death ()
+{
+  static char c;
+  int old_errno = errno;       /* back-up errno */
+
+  GNUNET_break (1 ==
+               GNUNET_DISK_file_write (GNUNET_DISK_pipe_handle
+                                       (sigpipe, GNUNET_DISK_PIPE_END_WRITE),
+                                       &c, sizeof (c)));
+  errno = old_errno;           /* restore errno */
+}
+
+
+/**
+ * Function run when the test terminates (good or bad) with timeout.
+ *
+ * @param cls NULL
+ */
+static void
+do_timeout (void *cls)
+{
+  timeout_task = NULL;
+  GNUNET_SCHEDULER_shutdown ();
+}
+
+
+/**
+ * Function run when the test terminates (good or bad).
+ * Cleans up our state.
+ *
+ * @param cls the interpreter state.
+ */
+static void
+do_shutdown (void *cls)
+{
+  struct InterpreterState *is = cls;
+  struct Command *cmd;
+
+  for (unsigned int i=0;OC_END != (cmd = &is->commands[i])->oc;i++)
+  {
+    switch (cmd->oc)
+    {
+    case OC_END:
+      GNUNET_assert (0);
+      break;
+    case OC_RUN_PROCESS:
+      if (NULL != cmd->details.run_process.proc)
+      {
+        GNUNET_break (0 ==
+                      GNUNET_OS_process_kill (cmd->details.run_process.proc,
+                                              SIGKILL));
+        GNUNET_OS_process_wait (cmd->details.run_process.proc);
+        GNUNET_OS_process_destroy (cmd->details.run_process.proc);
+        cmd->details.run_process.proc = NULL;
+      }
+      if (NULL != cmd->details.run_process.child_death_task)
+      {
+        GNUNET_SCHEDULER_cancel (cmd->details.run_process.child_death_task);
+        cmd->details.run_process.child_death_task = NULL;
+      }
+      break;
+    case OC_SIGNAL_EXCHANGE:
+      /* nothing to do */
+      break;
+    case OC_CHECK_KEYS:
+      /* nothing to do */
+      break;
+    default:
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                  "Unknown instruction %d at %u (%s)\n",
+                  cmd->oc,
+                  i,
+                  cmd->label);
+      break;
+    }
+  }
+  if (NULL != is->task)
+  {
+    GNUNET_SCHEDULER_cancel (is->task);
+    is->task = NULL;
+  }
+  GNUNET_free (is);
+  if (NULL != exchange)
+  {
+    TALER_EXCHANGE_disconnect (exchange);
+    exchange = NULL;
+  }
+  if (NULL != ctx)
+  {
+    GNUNET_CURL_fini (ctx);
+    ctx = NULL;
+  }
+  if (NULL != rc)
+  {
+    GNUNET_CURL_gnunet_rc_destroy (rc);
+    rc = NULL;
+  }
+  if (NULL != timeout_task)
+  {
+    GNUNET_SCHEDULER_cancel (timeout_task);
+    timeout_task = NULL;
+  }
+}
+
+
+/**
+ * Functions of this type are called to provide the retrieved signing and
+ * denomination keys of the exchange.  No TALER_EXCHANGE_*() functions should 
be called
+ * in this callback.
+ *
+ * @param cls closure
+ * @param keys information about keys of the exchange
+ * @param vc version compatibility
+ */
+static void
+cert_cb (void *cls,
+         const struct TALER_EXCHANGE_Keys *keys,
+        enum TALER_EXCHANGE_VersionCompatibility vc)
+{
+  struct InterpreterState *is = cls;
+
+  /* check that keys is OK */
+#define ERR(cond) do { if(!(cond)) break; GNUNET_break (0); 
GNUNET_SCHEDULER_shutdown(); return; } while (0)
+  ERR (NULL == keys);
+  ERR (0 == keys->num_sign_keys);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Read %u signing keys\n",
+              keys->num_sign_keys);
+  ERR (0 == keys->num_denom_keys);
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Read %u denomination keys\n",
+              keys->num_denom_keys);
+#undef ERR
+
+  /* run actual tests via interpreter-loop */
+  is->keys = keys;
+  if (GNUNET_YES == is->working)
+    return;
+  is->working = GNUNET_YES;
+  is->key_generation++;
+  is->task = GNUNET_SCHEDULER_add_now (&interpreter_run,
+                                       is);
+}
+
+
+/**
+ * Main function that will be run by the scheduler.
+ *
+ * @param cls closure
+ */
+static void
+run (void *cls)
+{
+  struct InterpreterState *is;
+  static char *keyup[] = {
+    "taler-exchange-keyup",
+    "-c", "test_exchange_api_keys_cherry_picking_extended.conf",
+    "-o", "auditor.in",
+    NULL
+  };
+  static char *auditorsign[] = {
+    "taler-auditor-sign",
+    "-c", "test_exchange_api_keys_cherry_picking.conf",
+    "-u", "http://auditor/";,
+    "-m", "98NJW3CQHZQGQXTY3K85K531XKPAPAVV4Q5V8PYYRR00NJGZWNVG",
+    "-r", "auditor.in",
+    "-o", "test_exchange_api_home/.local/share/taler/auditors/auditor.out",
+    NULL
+  };
+  static struct Command commands[] =
+  {
+    /* Test signal handling by itself */
+    { .oc = OC_SIGNAL_EXCHANGE },
+    /* Check we got /keys properly */
+    { .oc = OC_CHECK_KEYS,
+      .details.check_keys.generation = 1,
+      .details.check_keys.num_denom_keys = 4
+    },
+    /* Generate more keys */
+    { .oc = OC_RUN_PROCESS,
+      .details.run_process.binary = "taler-exchange-keyup",
+      .details.run_process.argv = keyup
+    },
+    /* Auditor-sign them */
+    { .oc = OC_RUN_PROCESS,
+      .details.run_process.binary = "taler-auditor-sign",
+      .details.run_process.argv = auditorsign
+    },
+    /* Load new keys into exchange via signal */
+    { .oc = OC_SIGNAL_EXCHANGE },
+    /* Re-download and check /keys */
+    { .oc = OC_CHECK_KEYS,
+      .details.check_keys.generation = 2,
+      .details.check_keys.num_denom_keys = 8
+    },
+    { .oc = OC_END }
+  };
+
+  is = GNUNET_new (struct InterpreterState);
+  is->commands = commands;
+
+  ctx = GNUNET_CURL_init (&GNUNET_CURL_gnunet_scheduler_reschedule,
+                          &rc);
+  GNUNET_assert (NULL != ctx);
+  rc = GNUNET_CURL_gnunet_rc_create (ctx);
+  exchange = TALER_EXCHANGE_connect (ctx,
+                                     "http://localhost:8081";,
+                                     &cert_cb, is,
+                                     TALER_EXCHANGE_OPTION_END);
+  GNUNET_assert (NULL != exchange);
+  timeout_task
+    = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
+                                    (GNUNET_TIME_UNIT_SECONDS, 300),
+                                    &do_timeout, NULL);
+  GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
+                                 is);
+}
+
+
+/**
+ * Remove files from previous runs
+ */
+static void
+cleanup_files ()
+{
+  struct GNUNET_CONFIGURATION_Handle *cfg;
+  char *dir;
+
+  cfg = GNUNET_CONFIGURATION_create ();
+  if (GNUNET_OK !=
+      GNUNET_CONFIGURATION_load (cfg,
+                                 "test_exchange_api.conf"))
+  {
+    GNUNET_break (0);
+    GNUNET_CONFIGURATION_destroy (cfg);
+    exit (77);
+  }
+  GNUNET_assert (GNUNET_OK ==
+                 GNUNET_CONFIGURATION_get_value_filename (cfg,
+                                                          "exchange",
+                                                          "keydir",
+                                                          &dir));
+  if (GNUNET_YES ==
+      GNUNET_DISK_directory_test (dir,
+                                  GNUNET_NO))
+    GNUNET_break (GNUNET_OK ==
+                  GNUNET_DISK_directory_remove (dir));
+  GNUNET_free (dir);
+  GNUNET_CONFIGURATION_destroy (cfg);
+}
+
+
+/**
+ * Main function for the testcase for the exchange API.
+ *
+ * @param argc expected to be 1
+ * @param argv expected to only contain the program name
+ */
+int
+main (int argc,
+      char * const *argv)
+{
+  struct GNUNET_OS_Process *proc;
+  struct GNUNET_SIGNAL_Context *shc_chld;
+  enum GNUNET_OS_ProcessStatusType type;
+  unsigned long code;
+  unsigned int iter;
+
+  /* These might get in the way... */
+  unsetenv ("XDG_DATA_HOME");
+  unsetenv ("XDG_CONFIG_HOME");
+  GNUNET_log_setup ("test-exchange-api-keys-cherry-picking",
+                    "INFO",
+                    NULL);
+  if (GNUNET_OK !=
+      GNUNET_NETWORK_test_port_free (IPPROTO_TCP,
+                                    8081))
+  {
+    fprintf (stderr,
+             "Required port %u not available, skipping.\n",
+            8081);
+    return 77;
+  }
+  cleanup_files ();
+
+  proc = GNUNET_OS_start_process (GNUNET_NO,
+                                  GNUNET_OS_INHERIT_STD_ALL,
+                                  NULL, NULL, NULL,
+                                  "taler-exchange-keyup",
+                                  "taler-exchange-keyup",
+                                  "-c", 
"test_exchange_api_keys_cherry_picking.conf",
+                                  "-o", "auditor.in",
+                                  NULL);
+  if (NULL == proc)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+               "Failed to run `taler-exchange-keyup`, is your PATH 
correct?\n");
+    return 77;
+  }
+  GNUNET_OS_process_wait (proc);
+  GNUNET_OS_process_destroy (proc);
+
+  proc = GNUNET_OS_start_process (GNUNET_NO,
+                                  GNUNET_OS_INHERIT_STD_ALL,
+                                  NULL, NULL, NULL,
+                                  "taler-auditor-sign",
+                                  "taler-auditor-sign",
+                                  "-c", 
"test_exchange_api_keys_cherry_picking.conf",
+                                  "-u", "http://auditor/";,
+                                  "-m", 
"98NJW3CQHZQGQXTY3K85K531XKPAPAVV4Q5V8PYYRR00NJGZWNVG",
+                                  "-r", "auditor.in",
+                                  "-o", 
"test_exchange_api_home/.local/share/taler/auditors/auditor.out",
+                                  NULL);
+  if (NULL == proc)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+               "Failed to run `taler-exchange-keyup`, is your PATH 
correct?\n");
+    return 77;
+  }
+  GNUNET_OS_process_wait (proc);
+  GNUNET_OS_process_destroy (proc);
+
+  proc = GNUNET_OS_start_process (GNUNET_NO,
+                                  GNUNET_OS_INHERIT_STD_ALL,
+                                  NULL, NULL, NULL,
+                                  "taler-exchange-dbinit",
+                                  "taler-exchange-dbinit",
+                                  "-c", 
"test_exchange_api_keys_cherry_picking.conf",
+                                  "-r",
+                                  NULL);
+  if (NULL == proc)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+               "Failed to run `taler-exchange-dbinit`, is your PATH 
correct?\n");
+    return 77;
+  }
+  if (GNUNET_SYSERR ==
+      GNUNET_OS_process_wait_status (proc,
+                                     &type,
+                                     &code))
+  {
+    GNUNET_break (0);
+    GNUNET_OS_process_destroy (proc);
+    return 1;
+  }
+  GNUNET_OS_process_destroy (proc);
+  if ( (type == GNUNET_OS_PROCESS_EXITED) &&
+       (0 != code) )
+  {
+    fprintf (stderr,
+             "Failed to setup database\n");
+    return 77;
+  }
+  if ( (type != GNUNET_OS_PROCESS_EXITED) ||
+       (0 != code) )
+  {
+    fprintf (stderr,
+             "Unexpected error running `taler-exchange-dbinit'!\n");
+    return 1;
+  }
+  exchanged = GNUNET_OS_start_process (GNUNET_NO,
+                                       GNUNET_OS_INHERIT_STD_ALL,
+                                       NULL, NULL, NULL,
+                                       "taler-exchange-httpd",
+                                       "taler-exchange-httpd",
+                                       "-c", 
"test_exchange_api_keys_cherry_picking.conf",
+                                       "-i",
+                                       NULL);
+  /* give child time to start and bind against the socket */
+  fprintf (stderr,
+           "Waiting for `taler-exchange-httpd' to be ready");
+  iter = 0;
+  do
+    {
+      if (10 == iter)
+      {
+       fprintf (stderr,
+                "Failed to launch `taler-exchange-httpd' (or `wget')\n");
+       GNUNET_OS_process_kill (exchanged,
+                               SIGTERM);
+       GNUNET_OS_process_wait (exchanged);
+       GNUNET_OS_process_destroy (exchanged);
+       return 77;
+      }
+      fprintf (stderr, ".");
+      sleep (1);
+      iter++;
+    }
+  while (0 != system ("wget -q -t 1 -T 1 http://127.0.0.1:8081/keys -o 
/dev/null -O /dev/null"));
+  fprintf (stderr, "\n");
+  result = GNUNET_NO;
+  sigpipe = GNUNET_DISK_pipe (GNUNET_NO, GNUNET_NO, GNUNET_NO, GNUNET_NO);
+  GNUNET_assert (NULL != sigpipe);
+  shc_chld = GNUNET_SIGNAL_handler_install (GNUNET_SIGCHLD,
+                                            &sighandler_child_death);
+  GNUNET_SCHEDULER_run (&run, NULL);
+  GNUNET_SIGNAL_handler_uninstall (shc_chld);
+  shc_chld = NULL;
+  GNUNET_DISK_pipe_close (sigpipe);
+  GNUNET_break (0 ==
+                GNUNET_OS_process_kill (exchanged,
+                                        SIGTERM));
+  GNUNET_break (GNUNET_OK ==
+                GNUNET_OS_process_wait (exchanged));
+  GNUNET_OS_process_destroy (exchanged);
+  return (GNUNET_OK == result) ? 0 : 1;
+}
+
+/* end of test_exchange_api_keys_cherry_picking.c */
diff --git a/src/exchange-lib/test_exchange_api.conf 
b/src/exchange-lib/test_exchange_api_keys_cherry_picking.conf
similarity index 73%
copy from src/exchange-lib/test_exchange_api.conf
copy to src/exchange-lib/test_exchange_api_keys_cherry_picking.conf
index a8543bc..c6b8ef9 100644
--- a/src/exchange-lib/test_exchange_api.conf
+++ b/src/exchange-lib/test_exchange_api_keys_cherry_picking.conf
@@ -26,6 +26,9 @@ BASE_URL = "https://exchange.com/";
 [exchangedb-postgres]
 DB_CONN_STR = "postgres:///talercheck"
 
+[auditordb-postgres]
+DB_CONN_STR = "postgres:///talercheck"
+
 [exchange-wire-sepa]
 # Enable 'sepa' to test SEPA-specific routines.
 ENABLE = YES
@@ -59,8 +62,8 @@ CLOSING-FEE-2025 = EUR:0.01
 CLOSING-FEE-2026 = EUR:0.01
 
 [exchange_keys]
-# Keep it short so the test runs fast.
-LOOKAHEAD_SIGN = 12 h
+# Keep it short so we can prolong later!
+LOOKAHEAD_SIGN = 60 s
 
 [exchange-wire-test]
 # Enable 'test' for testing of the actual coin operations.
@@ -102,60 +105,24 @@ BANK_ACCOUNT_NUMBER = 2
 
 [coin_eur_ct_1]
 value = EUR:0.01
-duration_overlap = 5 minutes
-duration_withdraw = 7 days
-duration_spend = 2 years
-duration_legal = 3 years
+duration_overlap = 5 s
+duration_withdraw = 35 s
+duration_spend = 40 s
+duration_legal = 60 s
 fee_withdraw = EUR:0.00
 fee_deposit = EUR:0.00
 fee_refresh = EUR:0.01
 fee_refund = EUR:0.01
 rsa_keysize = 1024
 
-[coin_eur_ct_10]
-value = EUR:0.10
-duration_overlap = 5 minutes
-duration_withdraw = 7 days
-duration_spend = 2 years
-duration_legal = 3 years
-fee_withdraw = EUR:0.01
-fee_deposit = EUR:0.01
-fee_refresh = EUR:0.03
-fee_refund = EUR:0.01
-rsa_keysize = 1024
-
-[coin_eur_1]
-value = EUR:1
-duration_overlap = 5 minutes
-duration_withdraw = 7 days
-duration_spend = 2 years
-duration_legal = 3 years
-fee_withdraw = EUR:0.01
-fee_deposit = EUR:0.01
-fee_refresh = EUR:0.03
-fee_refund = EUR:0.01
-rsa_keysize = 1024
-
-[coin_eur_5]
-value = EUR:5
-duration_overlap = 5 minutes
-duration_withdraw = 7 days
-duration_spend = 2 years
-duration_legal = 3 years
+[coin_eur_ct_2]
+value = EUR:0.02
+duration_overlap = 5 s
+duration_withdraw = 35 s
+duration_spend = 40 s
+duration_legal = 60 s
 fee_withdraw = EUR:0.01
 fee_deposit = EUR:0.01
-fee_refresh = EUR:0.03
-fee_refund = EUR:0.01
-rsa_keysize = 1024
-
-[coin_eur_10]
-value = EUR:10
-duration_overlap = 5 minutes
-duration_withdraw = 7 days
-duration_spend = 2 years
-duration_legal = 3 years
-fee_withdraw = EUR:0.01
-fee_deposit = EUR:0.01
-fee_refresh = EUR:0.03
+fee_refresh = EUR:0.01
 fee_refund = EUR:0.01
 rsa_keysize = 1024
diff --git 
a/src/exchange-lib/test_exchange_api_keys_cherry_picking_extended.conf 
b/src/exchange-lib/test_exchange_api_keys_cherry_picking_extended.conf
new file mode 100644
index 0000000..3becf3d
--- /dev/null
+++ b/src/exchange-lib/test_exchange_api_keys_cherry_picking_extended.conf
@@ -0,0 +1,5 @@
address@hidden@ test_exchange_api_keys_cherry_picking.conf
+
+[exchange_keys]
+# Lengthen over original value (60 s)
+LOOKAHEAD_SIGN = 100 s
diff --git a/src/exchange-tools/taler-exchange-keyup.c 
b/src/exchange-tools/taler-exchange-keyup.c
index facb832..b37a7a4 100644
--- a/src/exchange-tools/taler-exchange-keyup.c
+++ b/src/exchange-tools/taler-exchange-keyup.c
@@ -288,7 +288,6 @@ get_cointype_dir (const struct CoinTypeParams *p)
   struct GNUNET_HashCode hash;
   char *hash_str;
   char *val_str;
-  size_t i;
 
   hash_coin_type (p, &hash);
   hash_str = GNUNET_STRINGS_data_to_string_alloc (&hash,
@@ -298,7 +297,8 @@ get_cointype_dir (const struct CoinTypeParams *p)
   hash_str[HASH_CUTOFF] = 0;
 
   val_str = TALER_amount_to_string (&p->value);
-  for (i = 0; i < strlen (val_str); i++)
+  GNUNET_assert (NULL != val_str);
+  for (size_t i = 0; i < strlen (val_str); i++)
     if ( (':' == val_str[i]) ||
          ('.' == val_str[i]) )
       val_str[i] = '_';
@@ -363,18 +363,22 @@ get_anchor_iter (void *cls,
   struct GNUNET_TIME_Absolute stamp;
   const char *base;
   char *end = NULL;
+  long long int bval;
 
   base = GNUNET_STRINGS_get_short_name (filename);
-  stamp.abs_value_us = strtoll (base,
-                                &end,
-                                10);
-  if ((NULL == end) || (0 != *end))
+  bval = strtoll (base,
+                  &end,
+                  10);
+  if ( (NULL == end) ||
+       (0 != *end) ||
+       (0 > bval) )
   {
     fprintf(stderr,
             "Ignoring unexpected file `%s'.\n",
             filename);
     return GNUNET_OK;
   }
+  stamp.abs_value_us = (uint64_t) bval;
   *anchor = GNUNET_TIME_absolute_max (stamp,
                                       *anchor);
   return GNUNET_OK;
diff --git a/src/exchange/taler-exchange-aggregator.c 
b/src/exchange/taler-exchange-aggregator.c
index fdb32a2..5e0c52c 100644
--- a/src/exchange/taler-exchange-aggregator.c
+++ b/src/exchange/taler-exchange-aggregator.c
@@ -354,7 +354,7 @@ update_fees (struct WirePlugin *wp,
              struct TALER_EXCHANGEDB_Session *session)
 {
   enum GNUNET_DB_QueryStatus qs;
-  
+
   advance_fees (wp,
                 now);
   if (NULL != wp->af)
@@ -595,7 +595,7 @@ deposit_cb (void *cls,
             const json_t *wire)
 {
   enum GNUNET_DB_QueryStatus qs;
-  
+
   au->merchant_pub = *merchant_pub;
   if (GNUNET_SYSERR ==
       TALER_amount_subtract (&au->total_amount,
@@ -611,8 +611,15 @@ deposit_cb (void *cls,
   au->row_id = row_id;
   GNUNET_assert (NULL == au->wire);
   au->wire = json_incref ((json_t *) wire);
-  TALER_JSON_hash (au->wire,
-                   &au->h_wire);
+  if (GNUNET_OK !=
+      TALER_JSON_hash (au->wire,
+                       &au->h_wire))
+  {
+    GNUNET_break (0);
+    json_decref (au->wire);
+    au->wire = NULL;
+    return GNUNET_DB_STATUS_HARD_ERROR;
+  }
   GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,
                               &au->wtid,
                               sizeof (au->wtid));
@@ -839,7 +846,7 @@ prepare_close_cb (void *cls,
                  size_t buf_size)
 {
   enum GNUNET_DB_QueryStatus qs;
-    
+
   GNUNET_assert (cls == ctc);
 
   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
@@ -867,7 +874,7 @@ prepare_close_cb (void *cls,
                                            buf_size);
   if (GNUNET_DB_STATUS_HARD_ERROR == qs)
   {
-    GNUNET_break (0); 
+    GNUNET_break (0);
     db_plugin->rollback (db_plugin->cls,
                          ctc->session);
     global_ret = GNUNET_SYSERR;
@@ -999,8 +1006,9 @@ expired_reserve_cb (void *cls,
     /* Closing fee higher than remaining balance, close
        without wire transfer. */
     closing_fee = left;
-    TALER_amount_get_zero (left->currency,
-                          &amount_without_fee);
+    GNUNET_assert (GNUNET_OK ==
+                   TALER_amount_get_zero (left->currency,
+                                          &amount_without_fee));
   }
 
   /* NOTE: sizeof (*reserve_pub) == sizeof (wtid) right now, but to
@@ -1093,7 +1101,7 @@ run_reserve_closures (void *cls)
   enum GNUNET_DB_QueryStatus qs;
   const struct GNUNET_SCHEDULER_TaskContext *tc;
   struct ExpiredReserveContext erc;
-  
+
   task = NULL;
   reserves_idle = GNUNET_NO;
   tc = GNUNET_SCHEDULER_get_task_context ();
@@ -1126,9 +1134,9 @@ run_reserve_closures (void *cls)
                                        GNUNET_TIME_absolute_get (),
                                        &expired_reserve_cb,
                                        &erc);
-  switch (qs) 
+  switch (qs)
   {
-  case GNUNET_DB_STATUS_HARD_ERROR:    
+  case GNUNET_DB_STATUS_HARD_ERROR:
     GNUNET_break (0);
     db_plugin->rollback (db_plugin->cls,
                          session);
@@ -1290,7 +1298,7 @@ run_aggregation (void *cls)
                                     NULL);
     return;
   }
-  
+
   /* Subtract wire transfer fee and round to the unit supported by the
      wire transfer method; Check if after rounding down, we still have
      an amount to transfer, and if not mark as 'tiny'. */
@@ -1322,7 +1330,7 @@ run_aggregation (void *cls)
       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                   "Failed to start database transaction!\n");
       global_ret = GNUNET_SYSERR;
-      cleanup_au ();      
+      cleanup_au ();
       GNUNET_SCHEDULER_shutdown ();
       return;
     }
@@ -1612,6 +1620,19 @@ wire_prepare_cb (void *cls,
               "Starting wire transfer %llu\n",
               (unsigned long long) rowid);
   wpd->wp = find_plugin (wire_method);
+  if (NULL == wpd->wp)
+  {
+    /* Should really never happen here, as when we get
+       here the plugin should be in the cache. */
+    GNUNET_break (0);
+    db_plugin->rollback (db_plugin->cls,
+                         wpd->session);
+    global_ret = GNUNET_SYSERR;
+    GNUNET_SCHEDULER_shutdown ();
+    GNUNET_free (wpd);
+    wpd = NULL;
+    return;
+  }
   wpd->eh = wpd->wp->wire_plugin->execute_wire_transfer 
(wpd->wp->wire_plugin->cls,
                                                          buf,
                                                          buf_size,
@@ -1690,7 +1711,7 @@ run_transfers (void *cls)
   case GNUNET_DB_STATUS_SOFT_ERROR:
     /* try again */
     task = GNUNET_SCHEDULER_add_now (&run_transfers,
-                                    NULL);      
+                                    NULL);
     return;
   case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
     /* no more prepared wire transfers, go back to aggregation! */
diff --git a/src/exchange/taler-exchange-httpd.c 
b/src/exchange/taler-exchange-httpd.c
index 1a4d286..0dd3f96 100644
--- a/src/exchange/taler-exchange-httpd.c
+++ b/src/exchange/taler-exchange-httpd.c
@@ -316,12 +316,14 @@ handle_mhd_request (void *cls,
       &TEH_MHD_handler_static_response, MHD_HTTP_NOT_FOUND
     };
   struct TEH_RequestHandler *rh;
-  unsigned int i;
 
   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
               "Handling request for URL '%s'\n",
               url);
-  for (i=0;NULL != handlers[i].url;i++)
+  if (0 == strcasecmp (method,
+                       MHD_HTTP_METHOD_HEAD))
+    method = MHD_HTTP_METHOD_GET; /* treat HEAD as GET here, MHD will do the 
rest */
+  for (unsigned int i=0;NULL != handlers[i].url;i++)
   {
     rh = &handlers[i];
     if ( (0 == strcasecmp (url,
@@ -1013,37 +1015,55 @@ main (int argc,
   listen_fds = getenv ("LISTEN_FDS");
   if ( (NULL != listen_pid) &&
        (NULL != listen_fds) &&
-       (getpid() == strtol (listen_pid, NULL, 10)) &&
-       ( (1 == strtoul (listen_fds, NULL, 10)) ||
-         (2 == strtoul (listen_fds, NULL, 10)) ) )
+       (getpid() == strtol (listen_pid,
+                            NULL,
+                            10)) &&
+       ( (1 == strtoul (listen_fds,
+                        NULL,
+                        10)) ||
+         (2 == strtoul (listen_fds,
+                        NULL,
+                        10)) ) )
   {
     int flags;
 
     fh = 3;
-    flags = fcntl (fh, F_GETFD);
-    if ( (-1 == flags) && (EBADF == errno) )
+    flags = fcntl (fh,
+                   F_GETFD);
+    if ( (-1 == flags) &&
+         (EBADF == errno) )
     {
       fprintf (stderr,
                "Bad listen socket passed, ignored\n");
       fh = -1;
     }
     flags |= FD_CLOEXEC;
-    if (0 != fcntl (fh, F_SETFD, flags))
+    if ( (-1 != fh) &&
+         (0 != fcntl (fh,
+                      F_SETFD,
+                      flags)) )
       GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
                            "fcntl");
 
-    if (2 == strtoul (listen_fds, NULL, 10))
+    if (2 == strtoul (listen_fds,
+                      NULL,
+                      10))
     {
       fh_admin = 4;
-      flags = fcntl (fh_admin, F_GETFD);
-      if ( (-1 == flags) && (EBADF == errno) )
+      flags = fcntl (fh_admin,
+                     F_GETFD);
+      if ( (-1 == flags) &&
+           (EBADF == errno) )
       {
         fprintf (stderr,
                  "Bad listen socket passed, ignored\n");
         fh_admin = -1;
       }
       flags |= FD_CLOEXEC;
-      if (0 != fcntl (fh_admin, F_SETFD, flags))
+      if ( (-1 != fh_admin) &&
+           (0 != fcntl (fh_admin,
+                        F_SETFD,
+                        flags)) )
         GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
                              "fcntl");
     }
diff --git a/src/exchange/taler-exchange-httpd_db.c 
b/src/exchange/taler-exchange-httpd_db.c
index f2e1f7b..30bc33e 100644
--- a/src/exchange/taler-exchange-httpd_db.c
+++ b/src/exchange/taler-exchange-httpd_db.c
@@ -39,7 +39,7 @@
  * attempts to commit the transaction.  Upon soft failures,
  * retries @a cb a few times.  Upon hard or persistent soft
  * errors, generates an error message for @a connection.
- * 
+ *
  * @param connection MHD connection to run @a cb for
  * @param[out] set to MHD response code, if transaction failed
  * @param cb callback implementing transaction logic
@@ -68,13 +68,13 @@ TEH_DB_run_transaction (struct MHD_Connection *connection,
   {
     enum GNUNET_DB_QueryStatus qs;
 
-    if (GNUNET_OK !=                                            
-       TEH_plugin->start (TEH_plugin->cls,                     
-                          session))                            
-    {                                      
+    if (GNUNET_OK !=
+       TEH_plugin->start (TEH_plugin->cls,
+                          session))
+    {
       GNUNET_break (0);
       if (NULL != mhd_ret)
-       *mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection, 
+       *mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection,
                                                         
TALER_EC_DB_START_FAILED);
       return GNUNET_SYSERR;
     }
@@ -84,12 +84,12 @@ TEH_DB_run_transaction (struct MHD_Connection *connection,
             mhd_ret);
     if (0 > qs)
       TEH_plugin->rollback (TEH_plugin->cls,
-                           session);      
+                           session);
     if (GNUNET_DB_STATUS_HARD_ERROR == qs)
       return GNUNET_SYSERR;
     if (0 <= qs)
       qs = TEH_plugin->commit (TEH_plugin->cls,
-                              session);                              
+                              session);
     if (GNUNET_DB_STATUS_HARD_ERROR == qs)
     {
       if (NULL != mhd_ret)
@@ -132,8 +132,9 @@ TEH_DB_calculate_transaction_list_totals (struct 
TALER_EXCHANGEDB_TransactionLis
   struct TALER_EXCHANGEDB_TransactionList *pos;
   struct TALER_Amount refunded;
 
-  TALER_amount_get_zero (spent.currency,
-                         &refunded);
+  GNUNET_assert (GNUNET_OK ==
+                 TALER_amount_get_zero (spent.currency,
+                                        &refunded));
   for (pos = tl; NULL != pos; pos = pos->next)
   {
     switch (pos->type)
diff --git a/src/exchange/taler-exchange-httpd_deposit.c 
b/src/exchange/taler-exchange-httpd_deposit.c
index ccbd775..b7fb345 100644
--- a/src/exchange/taler-exchange-httpd_deposit.c
+++ b/src/exchange/taler-exchange-httpd_deposit.c
@@ -78,9 +78,15 @@ reply_deposit_success (struct MHD_Connection *connection,
                      amount_without_fee);
   dc.coin_pub = *coin_pub;
   dc.merchant = *merchant;
-  TEH_KS_sign (&dc.purpose,
-               &pub,
-               &sig);
+  if (GNUNET_OK !=
+      TEH_KS_sign (&dc.purpose,
+                  &pub,
+                  &sig))
+  {
+    return TEH_RESPONSE_reply_internal_error (connection,
+                                              
TALER_EC_EXCHANGE_BAD_CONFIGURATION,
+                                              "no keys");
+  }
   return TEH_RESPONSE_reply_json_pack (connection,
                                        MHD_HTTP_OK,
                                        "{s:s, s:o, s:o}",
@@ -104,7 +110,7 @@ struct DepositContext
    * Value of the coin.
    */
   struct TALER_Amount value;
-  
+
 };
 
 
@@ -133,7 +139,7 @@ deposit_transaction (void *cls,
   struct TALER_EXCHANGEDB_TransactionList *tl;
   struct TALER_Amount spent;
   enum GNUNET_DB_QueryStatus qs;
-  
+
   qs = TEH_plugin->have_deposit (TEH_plugin->cls,
                                 session,
                                 deposit);
@@ -255,6 +261,13 @@ verify_and_execute_deposit (struct MHD_Connection 
*connection,
 
   /* check denomination */
   mks = TEH_KS_acquire ();
+  if (NULL == mks)
+  {
+    TALER_LOG_ERROR ("Lacking keys to operate\n");
+    return TEH_RESPONSE_reply_internal_error (connection,
+                                              
TALER_EC_EXCHANGE_BAD_CONFIGURATION,
+                                              "no keys");
+  }
   dki = TEH_KS_denomination_key_lookup (mks,
                                         &deposit->coin.denom_pub,
                                        TEH_KS_DKU_DEPOSIT);
@@ -294,6 +307,44 @@ verify_and_execute_deposit (struct MHD_Connection 
*connection,
 
 
 /**
+ * Check that @a ts is reasonably close to our own RTC.
+ *
+ * @param ts timestamp to check
+ * @return #GNUNET_OK if @a ts is reasonable
+ */
+static int
+check_timestamp_current (struct GNUNET_TIME_Absolute ts)
+{
+  struct GNUNET_TIME_Relative r;
+  struct GNUNET_TIME_Relative tolerance;
+
+  /* Let's be VERY generous */
+  tolerance = GNUNET_TIME_UNIT_MONTHS;
+  r = GNUNET_TIME_absolute_get_duration (ts);
+  if (r.rel_value_us > tolerance.rel_value_us)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+               "Deposit timestamp too old: %llu vs %llu > %llu\n",
+               (unsigned long long) ts.abs_value_us,
+               (unsigned long long) GNUNET_TIME_absolute_get().abs_value_us,
+               (unsigned long long) tolerance.rel_value_us);
+    return GNUNET_SYSERR;
+  }
+  r = GNUNET_TIME_absolute_get_remaining (ts);
+  if (r.rel_value_us > tolerance.rel_value_us)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+               "Deposit timestamp too new: %llu vs %llu < - %llu\n",
+               (unsigned long long) ts.abs_value_us,
+               (unsigned long long) GNUNET_TIME_absolute_get().abs_value_us,
+               (unsigned long long) tolerance.rel_value_us);
+    return GNUNET_SYSERR;
+  }
+  return GNUNET_OK;
+}
+
+
+/**
  * Handle a "/deposit" request.  Parses the JSON, and, if successful,
  * passes the JSON data to #verify_and_execute_deposit() to further
  * check the details of the operation specified.  If everything checks
@@ -381,6 +432,15 @@ TEH_DEPOSIT_handler_deposit (struct TEH_RequestHandler *rh,
     return res;
   }
   if (GNUNET_OK !=
+      check_timestamp_current (deposit.timestamp))
+  {
+    GNUNET_break_op (0);
+    GNUNET_JSON_parse_free (spec);
+    return TEH_RESPONSE_reply_arg_invalid (connection,
+                                          TALER_EC_DEPOSIT_INVALID_TIMESTAMP,
+                                           "timestamp");
+  }
+  if (GNUNET_OK !=
       TALER_JSON_hash (wire,
                        &my_h_wire))
   {
@@ -403,6 +463,14 @@ TEH_DEPOSIT_handler_deposit (struct TEH_RequestHandler *rh,
 
   /* check denomination exists and is valid */
   key_state = TEH_KS_acquire ();
+  if (NULL == key_state)
+  {
+    TALER_LOG_ERROR ("Lacking keys to operate\n");
+    GNUNET_JSON_parse_free (spec);
+    return TEH_RESPONSE_reply_internal_error (connection,
+                                              
TALER_EC_EXCHANGE_BAD_CONFIGURATION,
+                                              "no keys");
+  }
   dki = TEH_KS_denomination_key_lookup (key_state,
                                         &deposit.coin.denom_pub,
                                        TEH_KS_DKU_DEPOSIT);
diff --git a/src/exchange/taler-exchange-httpd_keystate.c 
b/src/exchange/taler-exchange-httpd_keystate.c
index ec0a470..07ccd61 100644
--- a/src/exchange/taler-exchange-httpd_keystate.c
+++ b/src/exchange/taler-exchange-httpd_keystate.c
@@ -39,61 +39,195 @@
  * release version, and the format is NOT the same that semantic
  * versioning uses either.
  */
-#define TALER_PROTOCOL_VERSION "0:0:0"
+#define TALER_PROTOCOL_VERSION "1:0:1"
 
 
 /**
- * Snapshot of the (coin and signing) keys (including private keys) of
- * the exchange.  There can be multiple instances of this struct, as it is
- * reference counted and only destroyed once the last user is done
- * with it.  The current instance is acquired using
- * #TEH_KS_acquire().  Using this function increases the
- * reference count.  The contents of this structure (except for the
- * reference counter) should be considered READ-ONLY until it is
- * ultimately destroyed (as there can be many concurrent users).
+ * Signatures of an auditor over a denomination key of this exchange.
  */
-struct TEH_KS_StateHandle
+struct AuditorSignature
 {
   /**
-   * JSON array with denomination keys.  (Currently not really used
-   * after initialization.)
+   * We store the signatures in a DLL.
    */
-  json_t *denom_keys_array;
+  struct AuditorSignature *prev;
 
   /**
-   * JSON array with signing keys. (Currently not really used
-   * after initialization.)
+   * We store the signatures in a DLL.
    */
-  json_t *sign_keys_array;
+  struct AuditorSignature *next;
+
+  /**
+   * A signature from the auditor.
+   */
+  struct TALER_AuditorSignatureP asig;
+
+  /**
+   * Public key of the auditor.
+   */
+  struct TALER_AuditorPublicKeyP apub;
+
+  /**
+   * URL of the auditor. Allocated at the end of this struct.
+   */
+  const char *auditor_url;
+
+};
+
+
+/**
+ * Entry in sorted array of denomination keys.  Sorted by starting
+ * "start" time (validity period) of the `struct
+ * TALER_DenominationKeyValidityPS`.
+ */
+struct DenominationKeyEntry
+{
+
+  /**
+   * Reference to the public key.
+   * (Must also be in the `denomkey_map`).
+   */
+  const struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki;
+
+  /**
+   * Head of DLL of signatures for this @e dki.
+   */
+  struct AuditorSignature *as_head;
+
+  /**
+   * Tail of DLL of signatures for this @e dki.
+   */
+  struct AuditorSignature *as_tail;
 
   /**
-   * JSON array with auditor information. (Currently not really used
-   * after initialization.)
+   * Hash of the public denomination key.
+   */
+  struct GNUNET_HashCode denom_key_hash;
+
+};
+
+
+/**
+ * Entry in (sorted) array with possible pre-build responses for /keys.
+ * We keep pre-build responses for the various (valid) cherry-picking
+ * values around.
+ */
+struct KeysResponseData
+{
+
+  /**
+   * Response to return if the client supports (gzip) compression.
+   */
+  struct MHD_Response *response_compressed;
+
+  /**
+   * Response to return if the client does not support compression.
+   */
+  struct MHD_Response *response_uncompressed;
+
+  /**
+   * Cherry-picking timestamp the client must have set for this
+   * response to be valid.  0 if this is the "full" response.
+   * The client's request must include this date or a higher one
+   * for this response to be applicable.
+   */
+  struct GNUNET_TIME_Absolute cherry_pick_date;
+
+};
+
+
+/**
+ * State we keep around while building an individual entry in the
+ * `struct KeysResponseData` array, i.e. the global state for ONE of
+ * the responses.
+ */
+struct ResponseBuilderContext
+{
+
+  /**
+   * Hash context we used to combine the hashes of all denomination
+   * keys into one big hash for signing.
+   */
+  struct GNUNET_HashContext *hash_context;
+
+  /**
+   * JSON array with denomination key information.
+   */
+  json_t *denom_keys_array;
+
+  /**
+   * JSON array with auditor information.
    */
   json_t *auditors_array;
 
   /**
-   * JSON array with revoked denomination keys. (Currently not really used
-   * after initialization).
+   * Keys after what issue date do we care about?
+   */
+  struct GNUNET_TIME_Absolute last_issue_date;
+
+  /**
+   * Flag set to #GNUNET_SYSERR on internal errors
+   */
+  int error;
+
+};
+
+
+/**
+ * State we keep around while building the `struct KeysResponseData`
+ * array, i.e. the global state for all of the responses.
+ */
+struct ResponseFactoryContext
+{
+
+  /**
+   * JSON array with revoked denomination keys.  Every response
+   * always returns the full list (cherry picking does not apply
+   * for key revocations, as we cannot sort those by issue date).
    */
   json_t *payback_array;
 
   /**
-   * Cached JSON text that the exchange will send for a "/keys" request.
-   * Includes our @e TEH_master_public_key public key, the signing and
-   * denomination keys as well as the @e reload_time.
+   * JSON array with signing keys.  Every response includes the full
+   * list, as it should be quite short anyway, and for simplicity the
+   * client only communicates the one time stamp of the last
+   * denomination key it knows when cherry picking.
    */
-  char *keys_json;
+  json_t *sign_keys_array;
 
   /**
-   * deflate-compressed version of @e keys_json, or NULL if not available.
+   * Sorted array of denomination keys.  Length is @e denomkey_array_length.
+   * Entries are sorted by the validity period's starting time.  All entries
+   * must also be in the #denomkey_map.
    */
-  void *keys_jsonz;
+  struct DenominationKeyEntry *denomkey_array;
 
   /**
-   * Number of bytes in @e keys_jsonz.
+   * The main key state we are building everything for.
    */
-  size_t keys_jsonz_size;
+  struct TEH_KS_StateHandle *key_state;
+
+  /**
+   * Length of the @e denomkey_array.
+   */
+  unsigned int denomkey_array_length;
+
+};
+
+
+
+/**
+ * Snapshot of the (coin and signing) keys (including private keys) of
+ * the exchange.  There can be multiple instances of this struct, as it is
+ * reference counted and only destroyed once the last user is done
+ * with it.  The current instance is acquired using
+ * #TEH_KS_acquire().  Using this function increases the
+ * reference count.  The contents of this structure (except for the
+ * reference counter) should be considered READ-ONLY until it is
+ * ultimately destroyed (as there can be many concurrent users).
+ */
+struct TEH_KS_StateHandle
+{
 
   /**
    * Mapping from denomination keys to denomination key issue struct.
@@ -108,10 +242,10 @@ struct TEH_KS_StateHandle
   struct GNUNET_CONTAINER_MultiHashMap *revoked_map;
 
   /**
-   * Hash context we used to combine the hashes of all denomination
-   * keys into one big hash.
+   * Sorted array of responses to /keys (sorted by cherry-picking date) of
+   * length @e krd_array_length;
    */
-  struct GNUNET_HashContext *hash_context;
+  struct KeysResponseData *krd_array;
 
   /**
    * When did we initiate the key reloading?
@@ -138,19 +272,144 @@ struct TEH_KS_StateHandle
    * Reference count.  The struct is released when the RC hits zero.
    */
   unsigned int refcnt;
+
+  /**
+   * Length of the @e krd_array.
+   */
+  unsigned int krd_array_length;
 };
 
 
+/* ************************** Clean up logic *********************** */
+
+
 /**
- * Exchange key state.  Never use directly, instead access via
- * #TEH_KS_acquire() and #TEH_KS_release().
+ * Release memory used by @a rfc.
+ *
+ * @param rfc factory to release (but do not #GNUNET_free() rfc itself!)
  */
-static struct TEH_KS_StateHandle *internal_key_state;
+static void
+destroy_response_factory (struct ResponseFactoryContext *rfc)
+{
+  if (NULL != rfc->payback_array)
+  {
+    json_decref (rfc->payback_array);
+    rfc->payback_array = NULL;
+  }
+  if (NULL != rfc->sign_keys_array)
+  {
+    json_decref (rfc->sign_keys_array);
+    rfc->sign_keys_array = NULL;
+  }
+  for (unsigned int i=0;i<rfc->denomkey_array_length;i++)
+  {
+    struct DenominationKeyEntry *dke = &rfc->denomkey_array[i];
+    struct AuditorSignature *as;
+
+    while (NULL != (as = dke->as_head))
+    {
+      GNUNET_CONTAINER_DLL_remove (dke->as_head,
+                                   dke->as_tail,
+                                   as);
+      GNUNET_free (as);
+    }
+  }
+  GNUNET_array_grow (rfc->denomkey_array,
+                     rfc->denomkey_array_length,
+                     0);
+}
+
 
 /**
- * Mutex protecting access to #internal_key_state.
+ * Release memory used by @a rbc.
  */
-static pthread_mutex_t internal_key_state_mutex = PTHREAD_MUTEX_INITIALIZER;
+static void
+destroy_response_builder (struct ResponseBuilderContext *rbc)
+{
+  if (NULL != rbc->denom_keys_array)
+  {
+    json_decref (rbc->denom_keys_array);
+    rbc->denom_keys_array = NULL;
+  }
+  if (NULL != rbc->auditors_array)
+  {
+    json_decref (rbc->auditors_array);
+    rbc->auditors_array = NULL;
+  }
+}
+
+
+/**
+ * Iterator for freeing denomination keys.
+ *
+ * @param cls closure with the `struct TEH_KS_StateHandle`
+ * @param key key for the denomination key
+ * @param value coin details
+ * @return #GNUNET_OK to continue to iterate,
+ *  #GNUNET_NO to stop iteration with no error,
+ *  #GNUNET_SYSERR to abort iteration with error!
+ */
+static int
+free_denom_key (void *cls,
+                const struct GNUNET_HashCode *key,
+                void *value)
+{
+  struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki = value;
+
+  GNUNET_CRYPTO_rsa_private_key_free (dki->denom_priv.rsa_private_key);
+  GNUNET_CRYPTO_rsa_public_key_free (dki->denom_pub.rsa_public_key);
+  GNUNET_free (dki);
+  return GNUNET_OK;
+}
+
+
+/**
+ * Release key state, free if necessary (if reference count gets to zero).
+ * Internal method used when the mutex is already held.
+ *
+ * @param key_state the key state to release
+ */
+static void
+ks_release (struct TEH_KS_StateHandle *key_state)
+{
+  GNUNET_assert (0 < key_state->refcnt);
+  key_state->refcnt--;
+  if (0 == key_state->refcnt)
+  {
+    if (NULL != key_state->denomkey_map)
+    {
+      GNUNET_CONTAINER_multihashmap_iterate (key_state->denomkey_map,
+                                             &free_denom_key,
+                                             key_state);
+      GNUNET_CONTAINER_multihashmap_destroy (key_state->denomkey_map);
+      key_state->denomkey_map = NULL;
+    }
+    if (NULL != key_state->revoked_map)
+    {
+      GNUNET_CONTAINER_multihashmap_iterate (key_state->revoked_map,
+                                             &free_denom_key,
+                                             key_state);
+      GNUNET_CONTAINER_multihashmap_destroy (key_state->revoked_map);
+      key_state->revoked_map = NULL;
+    }
+    for (unsigned int i=0;i<key_state->krd_array_length;i++)
+    {
+      struct KeysResponseData *krd = &key_state->krd_array[i];
+
+      if (NULL != krd->response_compressed)
+        MHD_destroy_response (krd->response_compressed);
+      if (NULL != krd->response_uncompressed)
+        MHD_destroy_response (krd->response_uncompressed);
+    }
+    GNUNET_array_grow (key_state->krd_array,
+                       key_state->krd_array_length,
+                       0);
+    GNUNET_free (key_state);
+  }
+}
+
+
+/* ************************* Signal logic ************************** */
 
 /**
  * Pipe used for signaling reloading of our key state.
@@ -159,6 +418,37 @@ static int reload_pipe[2];
 
 
 /**
+ * Handle a signal, writing relevant signal numbers to the pipe.
+ *
+ * @param signal_number the signal number
+ */
+static void
+handle_signal (int signal_number)
+{
+  ssize_t res;
+  char c = signal_number;
+
+  res = write (reload_pipe[1],
+               &c,
+               1);
+  if ( (res < 0) &&
+       (EINTR != errno) )
+  {
+    GNUNET_break (0);
+    return;
+  }
+  if (0 == res)
+  {
+    GNUNET_break (0);
+    return;
+  }
+}
+
+
+/* ************************** State builder ************************ */
+
+
+/**
  * Convert the public part of a denomination key issue to a JSON
  * object.
  *
@@ -214,33 +504,6 @@ denom_key_issue_to_json (const struct 
TALER_DenominationPublicKey *pk,
 
 
 /**
- * Get the relative time value that describes how
- * far in the future do we want to provide coin keys.
- *
- * @return the provide duration
- */
-static struct GNUNET_TIME_Relative
-TALER_EXCHANGE_conf_duration_provide ()
-{
-  struct GNUNET_TIME_Relative rel;
-
-  if (GNUNET_OK !=
-      GNUNET_CONFIGURATION_get_value_time (cfg,
-                                           "exchange_keys",
-                                           "lookahead_provide",
-                                           &rel))
-  {
-    GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
-                               "exchange_keys",
-                               "lookahead_provide",
-                               "time value required");
-    GNUNET_assert (0);
-  }
-  return rel;
-}
-
-
-/**
  * Store a copy of @a dki in @a map.
  *
  * @param map hash map to store @a dki in
@@ -280,34 +543,6 @@ store_in_map (struct GNUNET_CONTAINER_MultiHashMap *map,
 
 
 /**
- * Handle a signal, writing relevant signal numbers to the pipe.
- *
- * @param signal_number the signal number
- */
-static void
-handle_signal (int signal_number)
-{
-  ssize_t res;
-  char c = signal_number;
-
-  res = write (reload_pipe[1],
-               &c,
-               1);
-  if ( (res < 0) &&
-       (EINTR != errno) )
-  {
-    GNUNET_break (0);
-    return;
-  }
-  if (0 == res)
-  {
-    GNUNET_break (0);
-    return;
-  }
-}
-
-
-/**
  * Closure for #add_revocations_transaction().
  */
 struct AddRevocationContext
@@ -325,7 +560,34 @@ struct AddRevocationContext
 
 
 /**
- * Execute transaction to add revocations.  
+ * Get the relative time value that describes how
+ * far in the future do we want to provide coin keys.
+ *
+ * @return the provide duration
+ */
+static struct GNUNET_TIME_Relative
+TALER_EXCHANGE_conf_duration_provide ()
+{
+  struct GNUNET_TIME_Relative rel;
+
+  if (GNUNET_OK !=
+      GNUNET_CONFIGURATION_get_value_time (cfg,
+                                           "exchange_keys",
+                                           "lookahead_provide",
+                                           &rel))
+  {
+    GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
+                               "exchange_keys",
+                               "lookahead_provide",
+                               "time value required");
+    GNUNET_assert (0);
+  }
+  return rel;
+}
+
+
+/**
+ * Execute transaction to add revocations.
  *
  * @param cls closure with the `struct AddRevocationContext *`
  * @param connection NULL
@@ -340,7 +602,7 @@ add_revocations_transaction (void *cls,
                             int *mhd_ret)
 {
   struct AddRevocationContext *arc = cls;
-  
+
   return TEH_plugin->insert_denomination_revocation (TEH_plugin->cls,
                                                     session,
                                                     
&arc->dki->issue.properties.denom_hash,
@@ -349,7 +611,7 @@ add_revocations_transaction (void *cls,
 
 
 /**
- * Execute transaction to add a denomination to the DB.  
+ * Execute transaction to add a denomination to the DB.
  *
  * @param cls closure with the `const struct 
TALER_EXCHANGEDB_DenominationKeyIssueInformation *`
  * @param connection NULL
@@ -385,7 +647,7 @@ add_denomination_transaction (void *cls,
 /**
  * Iterator for (re)loading/initializing denomination keys.
  *
- * @param cls closure
+ * @param cls closure with a `struct ResponseFactoryContext *`
  * @param dki the denomination key issue
  * @param alias coin alias
  * @param revocation_master_sig non-NULL if @a dki was revoked
@@ -399,17 +661,18 @@ reload_keys_denom_iter (void *cls,
                         const struct 
TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki,
                         const struct TALER_MasterSignatureP 
*revocation_master_sig)
 {
-  struct TEH_KS_StateHandle *ctx = cls;
+  struct ResponseFactoryContext *rfc = cls;
+  struct TEH_KS_StateHandle *key_state = rfc->key_state;
   struct GNUNET_TIME_Absolute now;
   struct GNUNET_TIME_Absolute start;
   struct GNUNET_TIME_Absolute horizon;
   struct GNUNET_TIME_Absolute expire_deposit;
-  struct GNUNET_HashCode denom_key_hash;
   int res;
 
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Loading denomination key `%s'\n",
-              alias);
+              "Loading denomination key `%s' (%s)\n",
+              alias,
+             GNUNET_h2s (&dki->issue.properties.denom_hash));
   now = GNUNET_TIME_absolute_get ();
   expire_deposit = GNUNET_TIME_absolute_ntoh 
(dki->issue.properties.expire_deposit);
   if (expire_deposit.abs_value_us < now.abs_value_us)
@@ -432,11 +695,12 @@ reload_keys_denom_iter (void *cls,
   if (NULL != revocation_master_sig)
   {
     struct AddRevocationContext arc;
-    
+
     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-                "Adding denomination key `%s' to revocation set\n",
-                alias);
-    res = store_in_map (ctx->revoked_map,
+                "Adding denomination key `%s' (%s) to revocation set\n",
+                alias,
+               GNUNET_h2s (&dki->issue.properties.denom_hash));
+    res = store_in_map (key_state->revoked_map,
                         dki);
     if (GNUNET_NO == res)
       return GNUNET_OK;
@@ -454,11 +718,10 @@ reload_keys_denom_iter (void *cls,
       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                  "Giving up, this is fatal. Committing suicide via 
SIGTERM.\n");
       handle_signal (SIGTERM);
-      return GNUNET_SYSERR;      
+      return GNUNET_SYSERR;
     }
-       
     GNUNET_assert (0 ==
-                   json_array_append_new (ctx->payback_array,
+                   json_array_append_new (rfc->payback_array,
                                           GNUNET_JSON_from_data_auto 
(&dki->issue.properties.denom_hash)));
     return GNUNET_OK;
   }
@@ -467,19 +730,13 @@ reload_keys_denom_iter (void *cls,
   if (start.abs_value_us > horizon.abs_value_us)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-                "Skipping future denomination key `%s' (starts at %s)\n",
+                "Skipping future denomination key `%s' (%s), validity starts 
at %s\n",
                 alias,
+               GNUNET_h2s (&dki->issue.properties.denom_hash),
                 GNUNET_STRINGS_absolute_time_to_string (start));
     return GNUNET_OK;
   }
 
-  GNUNET_CRYPTO_rsa_public_key_hash (dki->denom_pub.rsa_public_key,
-                                     &denom_key_hash);
-  GNUNET_CRYPTO_hash_context_read (ctx->hash_context,
-                                   &denom_key_hash,
-                                   sizeof (struct GNUNET_HashCode));
-
-
   if (GNUNET_OK !=
       TEH_DB_run_transaction (NULL,
                              NULL,
@@ -487,21 +744,22 @@ reload_keys_denom_iter (void *cls,
                              (void *) dki))
   {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-               "Giving up, this is fatal. Committing suicide via SIGTERM.\n");
+               "Could not persist denomination key %s in DB. Committing 
suicide via SIGTERM.\n",
+               GNUNET_h2s (&dki->issue.properties.denom_hash));
     handle_signal (SIGTERM);
-    return GNUNET_SYSERR;      
+    return GNUNET_SYSERR;
   }
 
-  res = store_in_map (ctx->denomkey_map,
+  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+             "Adding denomination key `%s' (%s) to active set\n",
+             alias,
+             GNUNET_h2s (&dki->issue.properties.denom_hash));
+  res = store_in_map (key_state->denomkey_map,
                       dki);
   if (GNUNET_NO == res)
     return GNUNET_OK;
-  ctx->min_dk_expire = GNUNET_TIME_absolute_min (ctx->min_dk_expire,
-                                                 expire_deposit);
-  GNUNET_assert (0 ==
-                 json_array_append_new (ctx->denom_keys_array,
-                                        denom_key_issue_to_json 
(&dki->denom_pub,
-                                                                 
&dki->issue)));
+  key_state->min_dk_expire = GNUNET_TIME_absolute_min 
(key_state->min_dk_expire,
+                                                       expire_deposit);
   return GNUNET_OK;
 }
 
@@ -531,9 +789,11 @@ sign_key_issue_to_json (const struct 
TALER_ExchangeSigningKeyValidityPS *ski)
 
 
 /**
- * Iterator for sign keys.
+ * Iterator for sign keys.  Adds current and near-future signing keys
+ * to the `sign_keys_array` and stores the current one in the
+ * `key_state`.
  *
- * @param cls closure with the `struct TEH_KS_StateHandle *`
+ * @param cls closure with the `struct ResponseFactoryContext *`
  * @param filename name of the file the key came from
  * @param ski the sign key issue
  * @return #GNUNET_OK to continue to iterate,
@@ -545,7 +805,8 @@ reload_keys_sign_iter (void *cls,
                        const char *filename,
                        const struct 
TALER_EXCHANGEDB_PrivateSigningKeyInformationP *ski)
 {
-  struct TEH_KS_StateHandle *ctx = cls;
+  struct ResponseFactoryContext *rfc = cls;
+  struct TEH_KS_StateHandle *key_state = rfc->key_state;
   struct GNUNET_TIME_Absolute now;
   struct GNUNET_TIME_Absolute horizon;
 
@@ -580,199 +841,762 @@ reload_keys_sign_iter (void *cls,
 
   /* The signkey is valid at this time, check if it's more recent than
      what we have so far! */
-  if ( (GNUNET_TIME_absolute_ntoh 
(ctx->current_sign_key_issue.issue.start).abs_value_us <
+  if ( (GNUNET_TIME_absolute_ntoh 
(key_state->current_sign_key_issue.issue.start).abs_value_us <
         GNUNET_TIME_absolute_ntoh (ski->issue.start).abs_value_us) &&
        (GNUNET_TIME_absolute_ntoh (ski->issue.start).abs_value_us <
         now.abs_value_us) )
   {
-    /* We use the most recent one, if it is valid now (not just in the near 
future) */
-    ctx->current_sign_key_issue = *ski;
+    /* We use the most recent one, if it is valid now (not just in the near 
future) */
+    key_state->current_sign_key_issue = *ski;
+  }
+  GNUNET_assert (0 ==
+                 json_array_append_new (rfc->sign_keys_array,
+                                        sign_key_issue_to_json (&ski->issue)));
+
+  return GNUNET_OK;
+}
+
+
+/**
+ * @brief Iterator called with auditor information.
+ * Check that the @a mpub actually matches this exchange, and then
+ * add the auditor information to our /keys response (if it is
+ * (still) applicable).
+ *
+ * @param cls closure with the `struct ResponseFactoryContext *`
+ * @param apub the auditor's public key
+ * @param auditor_url URL of the auditor
+ * @param mpub the exchange's public key (as expected by the auditor)
+ * @param dki_len length of @a dki and @a asigs
+ * @param asigs array with the auditor's signatures, of length @a dki_len
+ * @param dki array of denomination coin data signed by the auditor
+ * @return #GNUNET_OK to continue to iterate,
+ *  #GNUNET_NO to stop iteration with no error,
+ *  #GNUNET_SYSERR to abort iteration with error!
+ */
+static int
+reload_auditor_iter (void *cls,
+                     const struct TALER_AuditorPublicKeyP *apub,
+                     const char *auditor_url,
+                     const struct TALER_MasterPublicKeyP *mpub,
+                     unsigned int dki_len,
+                     const struct TALER_AuditorSignatureP *asigs,
+                     const struct TALER_DenominationKeyValidityPS *dki)
+{
+  struct ResponseFactoryContext *rfc = cls;
+  struct TEH_KS_StateHandle *key_state = rfc->key_state;
+
+  /* Check if the signature is at least for this exchange. */
+  if (0 != memcmp (&mpub->eddsa_pub,
+                   &TEH_master_public_key,
+                   sizeof (struct GNUNET_CRYPTO_EddsaPublicKey)))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                "Auditing information provided for a different exchange, 
ignored\n");
+    return GNUNET_OK;
+  }
+  /* Filter the auditor information for those for which the
+     keys actually match the denomination keys that are active right now */
+  for (unsigned int i=0;i<dki_len;i++)
+  {
+    int matched;
+
+    if (GNUNET_YES !=
+        GNUNET_CONTAINER_multihashmap_contains (key_state->denomkey_map,
+                                                &dki[i].denom_hash))
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                 "Found auditor signature for DK `%s', but key is not in 
active map\n",
+                 GNUNET_h2s (&dki[i].denom_hash));
+      continue;
+    }
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+               "Found auditor signature for DK `%s'\n",
+               GNUNET_h2s (&dki[i].denom_hash));
+    /* Note: the array is sorted, we could theoretically
+       speed this up using a binary search. */
+    matched = GNUNET_NO;
+    for (unsigned int j=0;j<rfc->denomkey_array_length;j++)
+    {
+      struct DenominationKeyEntry *dke = &rfc->denomkey_array[j];
+      struct AuditorSignature *as;
+
+      if (0 !=
+         memcmp (&dki[i].denom_hash,
+                 &dke->dki->issue.properties.denom_hash,
+                 sizeof (struct GNUNET_HashCode)))
+       continue;
+      if (0 !=
+          memcmp (&dki[i],
+                  &dke->dki->issue.properties,
+                  sizeof (struct TALER_DenominationKeyValidityPS)))
+      {
+       /* if the hash is the same, the properties should also match! */
+       GNUNET_break (0);
+        continue;
+      }
+      as = GNUNET_malloc (sizeof (struct AuditorSignature) +
+                          strlen (auditor_url) + 1);
+      as->asig = asigs[i];
+      as->apub = *apub;
+      as->auditor_url = (const char *) &as[1];
+      memcpy (&as[1],
+              auditor_url,
+              strlen (auditor_url) + 1);
+      GNUNET_CONTAINER_DLL_insert (dke->as_head,
+                                   dke->as_tail,
+                                   as);
+      matched = GNUNET_YES;
+      break;
+    }
+    if (GNUNET_NO == matched)
+    {
+      GNUNET_break (0);
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                 "DK `%s' is in active map, but not in array!?\n",
+                 GNUNET_h2s (&dki[i].denom_hash));
+    }
+  }
+  return GNUNET_OK;
+}
+
+
+/**
+ * Initialize the `denomkey_array`.  We are called once per
+ * array index, which is tracked in `denomkey_array_length` (the
+ * array will be of sufficient size).  Set the pointer to the
+ * denomination key and increment the `denomkey_array_length`.
+ *
+ * @param cls a `struct ResponseFactoryContext`
+ * @param denom_hash hash of a denomination key
+ * @param value a `struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *`
+ * @return #GNUNET_OK
+ */
+static int
+initialize_denomkey_array (void *cls,
+                           const struct GNUNET_HashCode *denom_hash,
+                           void *value)
+{
+  struct ResponseFactoryContext *rfc = cls;
+  struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki = value;
+
+  rfc->denomkey_array[rfc->denomkey_array_length].denom_key_hash = *denom_hash;
+  rfc->denomkey_array[rfc->denomkey_array_length++].dki = dki;
+  return GNUNET_OK;
+}
+
+
+/**
+ * Comparator used to sort the `struct DenominationKeyEntry` array
+ * by the validity period's starting time of the keys.
+ *
+ * @param k1 a `struct DenominationKeyEntry *`
+ * @param k2 a `struct DenominationKeyEntry *`
+ * @return -1 if k1 starts before k2,
+ *          1 if k2 starts before k1,
+ *          0 if they start at the same time
+ */
+static int
+denomkey_array_sort_comparator (const void *k1,
+                                const void *k2)
+{
+  const struct DenominationKeyEntry *dke1 = k1;
+  const struct DenominationKeyEntry *dke2 = k2;
+  struct GNUNET_TIME_Absolute d1
+    = GNUNET_TIME_absolute_ntoh (dke1->dki->issue.properties.start);
+  struct GNUNET_TIME_Absolute d2
+    = GNUNET_TIME_absolute_ntoh (dke2->dki->issue.properties.start);
+
+  if (d1.abs_value_us < d2.abs_value_us)
+    return -1;
+  if (d1.abs_value_us > d2.abs_value_us)
+    return  1;
+  return 0;
+}
+
+
+/**
+ * Produce HTTP "Date:" header.
+ *
+ * @param at time to write to @a date
+ * @param[out] date where to write the header, with
+ *        at least 128 bytes available space.
+ */
+static void
+get_date_string (struct GNUNET_TIME_Absolute at,
+                 char *date)
+{
+  static const char *const days[] =
+    { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
+  static const char *const mons[] =
+    { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct",
+    "Nov", "Dec"
+  };
+  struct tm now;
+  time_t t;
+#if !defined(HAVE_C11_GMTIME_S) && !defined(HAVE_W32_GMTIME_S) && 
!defined(HAVE_GMTIME_R)
+  struct tm* pNow;
+#endif
+
+  date[0] = 0;
+  t = (time_t) (at.abs_value_us / 1000LL / 1000LL);
+#if defined(HAVE_C11_GMTIME_S)
+  if (NULL == gmtime_s (&t, &now))
+    return;
+#elif defined(HAVE_W32_GMTIME_S)
+  if (0 != gmtime_s (&now, &t))
+    return;
+#elif defined(HAVE_GMTIME_R)
+  if (NULL == gmtime_r(&t, &now))
+    return;
+#else
+  pNow = gmtime(&t);
+  if (NULL == pNow)
+    return;
+  now = *pNow;
+#endif
+  sprintf (date,
+           "%3s, %02u %3s %04u %02u:%02u:%02u GMT",
+           days[now.tm_wday % 7],
+           (unsigned int) now.tm_mday,
+           mons[now.tm_mon % 12],
+           (unsigned int) (1900 + now.tm_year),
+           (unsigned int) now.tm_hour,
+           (unsigned int) now.tm_min,
+           (unsigned int) now.tm_sec);
+}
+
+
+/**
+ * Add the headers we want to set for every /keys response.
+ *
+ * @param key_state the key state to use
+ * @param[in,out] response the response to modify
+ * @return #GNUNET_OK on success
+ */
+static int
+setup_general_response_headers (const struct TEH_KS_StateHandle *key_state,
+                                struct MHD_Response *response)
+{
+  char dat[128];
+
+  TEH_RESPONSE_add_global_headers (response);
+  GNUNET_break (MHD_YES ==
+                MHD_add_response_header (response,
+                                         MHD_HTTP_HEADER_CONTENT_TYPE,
+                                         "application/json"));
+  get_date_string (key_state->reload_time,
+                   dat);
+  GNUNET_break (MHD_YES ==
+                MHD_add_response_header (response,
+                                         MHD_HTTP_HEADER_LAST_MODIFIED,
+                                         dat));
+  if (0 != key_state->next_reload.abs_value_us)
+  {
+    get_date_string (key_state->next_reload,
+                     dat);
+    GNUNET_break (MHD_YES ==
+                  MHD_add_response_header (response,
+                                           MHD_HTTP_HEADER_EXPIRES,
+                                           dat));
+  }
+  return GNUNET_OK;
+}
+
+
+/**
+ * Information about an auditor to be added.
+ */
+struct AuditorEntry
+{
+  /**
+   * URL of the auditor (allocated still as part of a
+   * `struct AuditorSignature`, do not free!).
+   */
+  const char *auditor_url;
+
+  /**
+   * Public key of the auditor (allocated still as part of a
+   * `struct AuditorSignature`, do not free!).
+   */
+  const struct TALER_AuditorPublicKeyP *apub;
+
+  /**
+   * Array of denomination keys and auditor signatures.
+   */
+  json_t *ar;
+
+};
+
+
+/**
+ * Convert auditor entries from the hash map to entries
+ * in the auditor array, free the auditor entry as well.
+ *
+ * @param cls a `struct ResponseBuilderContext *`
+ * @param key unused
+ * @param value a `struct AuditorEntry` to add to the `auditors_array`
+ * @return #GNUNET_OK (to continue to iterate)
+ */
+static int
+add_auditor_entry (void *cls,
+                   const struct GNUNET_HashCode *key,
+                   void *value)
+{
+  struct ResponseBuilderContext *rbc = cls;
+  struct AuditorEntry *ae = value;
+  json_t *ao;
+
+  ao = json_pack ("{s:o, s:s, s:o}",
+                  "denomination_keys", ae->ar,
+                  "auditor_url", ae->auditor_url,
+                  "auditor_pub", GNUNET_JSON_from_data_auto (ae->apub));
+  GNUNET_assert (NULL != ao);
+  GNUNET_assert (0 ==
+                 json_array_append_new (rbc->auditors_array,
+                                        ao));
+  GNUNET_free (ae);
+  return GNUNET_OK;
+}
+
+
+/**
+ * Initialize @a krd for the given @a cherry_pick_date using
+ * the key data in @a rfc.  This function actually builds the
+ * respective JSON replies (compressed and uncompressed).
+ *
+ * @param rfc factory with key material
+ * @param[out] krd response object to initialize
+ * @param denom_off offset in the @a rfc's `denomkey_array` at which
+ *        keys beyond the @a cherry_pick_date are stored
+ * @param cherry_pick_date cut-off date to use
+ * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
+ */
+static int
+build_keys_response (const struct ResponseFactoryContext *rfc,
+                     struct KeysResponseData *krd,
+                     unsigned int denom_off,
+                     struct GNUNET_TIME_Absolute cherry_pick_date)
+{
+  struct ResponseBuilderContext rbc;
+  json_t *keys;
+  struct TALER_ExchangeKeySetPS ks;
+  struct TALER_ExchangeSignatureP sig;
+  char *keys_json;
+  void *keys_jsonz;
+  size_t keys_jsonz_size;
+  int comp;
+
+  krd->cherry_pick_date = cherry_pick_date;
+
+  /* Initialize `rbc` */
+  memset (&rbc,
+          0,
+          sizeof (rbc));
+  rbc.denom_keys_array = json_array ();
+  if (NULL == rbc.denom_keys_array)
+  {
+    GNUNET_break (0);
+    return GNUNET_SYSERR;
+  }
+  rbc.auditors_array = json_array ();
+  if (NULL == rbc.auditors_array)
+  {
+    destroy_response_builder (&rbc);
+    GNUNET_break (0);
+    return GNUNET_SYSERR;
+  }
+  rbc.hash_context = GNUNET_CRYPTO_hash_context_start ();
+
+  /* Go over relevant denomination keys. */
+  {
+    struct GNUNET_CONTAINER_MultiHashMap *auditors;
+
+    auditors = GNUNET_CONTAINER_multihashmap_create (4,
+                                                     GNUNET_NO);
+    for (unsigned int i=denom_off;i<rfc->denomkey_array_length;i++)
+    {
+      /* Add denomination key to the response */
+      const struct DenominationKeyEntry *dke
+        = &rfc->denomkey_array[i];
+      const struct GNUNET_HashCode *denom_key_hash
+        = &dke->denom_key_hash;
+
+      GNUNET_CRYPTO_hash_context_read (rbc.hash_context,
+                                       denom_key_hash,
+                                       sizeof (struct GNUNET_HashCode));
+      if (0 !=
+          json_array_append_new (rbc.denom_keys_array,
+                                 denom_key_issue_to_json (&dke->dki->denom_pub,
+                                                          &dke->dki->issue)))
+      {
+        GNUNET_break (0);
+        destroy_response_builder (&rbc);
+        return GNUNET_SYSERR;
+      }
+
+      /* Add auditor data */
+      for (const struct AuditorSignature *as = dke->as_head;
+           NULL != as;
+           as = as->next)
+      {
+        struct GNUNET_HashCode ahash;
+        struct AuditorEntry *ae;
+
+        GNUNET_CRYPTO_hash (&as->apub,
+                            sizeof (as->apub),
+                            &ahash);
+        ae = GNUNET_CONTAINER_multihashmap_get (auditors,
+                                                &ahash);
+        if (NULL == ae)
+        {
+          ae = GNUNET_new (struct AuditorEntry);
+          ae->auditor_url = as->auditor_url;
+          ae->ar = json_array ();
+          ae->apub = &as->apub;
+          GNUNET_assert (GNUNET_YES ==
+                         GNUNET_CONTAINER_multihashmap_put (auditors,
+                                                            &ahash,
+                                                            ae,
+                                                            
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
+        }
+        GNUNET_assert (0 ==
+                       json_array_append_new (ae->ar,
+                                              json_pack ("{s:o, s:o}",
+                                                         "denom_pub_h",
+                                                         
GNUNET_JSON_from_data_auto (denom_key_hash),
+                                                         "auditor_sig",
+                                                         
GNUNET_JSON_from_data_auto (&as->asig))));
+      }
+    }
+
+    GNUNET_CONTAINER_multihashmap_iterate (auditors,
+                                           &add_auditor_entry,
+                                           &rbc);
+    GNUNET_CONTAINER_multihashmap_destroy (auditors);
+  }
+
+  /* Sign hash over denomination keys */
+  ks.purpose.size = htonl (sizeof (ks));
+  ks.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_KEY_SET);
+  ks.list_issue_date = GNUNET_TIME_absolute_hton (rfc->key_state->reload_time);
+  GNUNET_CRYPTO_hash_context_finish (rbc.hash_context,
+                                     &ks.hc);
+  rbc.hash_context = NULL;
+  GNUNET_assert (GNUNET_OK ==
+                 GNUNET_CRYPTO_eddsa_sign 
(&rfc->key_state->current_sign_key_issue.signkey_priv.eddsa_priv,
+                                           &ks.purpose,
+                                           &sig.eddsa_signature));
+
+  /* Build /keys response */
+  keys = json_pack ("{s:s, s:o, s:O, s:O, s:o, s:o, s:o, s:o, s:o}",
+                    "version", TALER_PROTOCOL_VERSION,
+                    "master_public_key", GNUNET_JSON_from_data_auto 
(&TEH_master_public_key),
+                    "signkeys", rfc->sign_keys_array,
+                    "payback", rfc->payback_array,
+                    "denoms", rbc.denom_keys_array,
+                    "auditors", rbc.auditors_array,
+                    "list_issue_date", GNUNET_JSON_from_time_abs 
(rfc->key_state->reload_time),
+                    "eddsa_pub", GNUNET_JSON_from_data_auto 
(&rfc->key_state->current_sign_key_issue.issue.signkey_pub),
+                    "eddsa_sig", GNUNET_JSON_from_data_auto (&sig));
+  if (NULL == keys)
+  {
+    destroy_response_builder (&rbc);
+    GNUNET_break (0);
+    return GNUNET_SYSERR;
+  }
+  rbc.denom_keys_array = NULL;
+  rbc.auditors_array = NULL;
+  destroy_response_builder (&rbc);
+
+  /* Convert /keys response to UTF8-String */
+  keys_json = json_dumps (keys,
+                          JSON_INDENT (2));
+  json_decref (keys);
+  if (NULL == keys_json)
+  {
+    GNUNET_break (0);
+    return GNUNET_SYSERR;
+  }
+  /* Keep copy for later compression... */
+  keys_jsonz = GNUNET_strdup (keys_json);
+  keys_jsonz_size = strlen (keys_json);
+
+  /* Create uncompressed response */
+  krd->response_uncompressed
+    = MHD_create_response_from_buffer (keys_jsonz_size,
+                                       keys_json,
+                                       MHD_RESPMEM_MUST_FREE);
+  if (NULL == krd->response_uncompressed)
+  {
+    GNUNET_break (0);
+    GNUNET_free (keys_json);
+    GNUNET_free (keys_jsonz);
+    return GNUNET_SYSERR;
+  }
+  if (GNUNET_OK !=
+      setup_general_response_headers (rfc->key_state,
+                                      krd->response_uncompressed))
+  {
+    GNUNET_break (0);
+    GNUNET_free (keys_jsonz);
+    return GNUNET_SYSERR;
+  }
+
+  /* Also compute compressed version of /keys response */
+  comp = TEH_RESPONSE_body_compress (&keys_jsonz,
+                                     &keys_jsonz_size);
+  krd->response_compressed
+    = MHD_create_response_from_buffer (keys_jsonz_size,
+                                       keys_jsonz,
+                                       MHD_RESPMEM_MUST_FREE);
+  if (NULL == krd->response_compressed)
+  {
+    GNUNET_break (0);
+    GNUNET_free (keys_jsonz);
+    return GNUNET_SYSERR;
+  }
+  /* If the response is actually compressed, set the
+     respective header. */
+  if ( (MHD_YES == comp) &&
+       (MHD_YES !=
+        MHD_add_response_header (krd->response_compressed,
+                                 MHD_HTTP_HEADER_CONTENT_ENCODING,
+                                 "deflate")) )
+  {
+    GNUNET_break (0);
+    return GNUNET_SYSERR;
+  }
+  if (GNUNET_OK !=
+      setup_general_response_headers (rfc->key_state,
+                                      krd->response_compressed))
+  {
+    GNUNET_break (0);
+    return GNUNET_SYSERR;
   }
-  GNUNET_assert (0 ==
-                 json_array_append_new (ctx->sign_keys_array,
-                                        sign_key_issue_to_json (&ski->issue)));
-
   return GNUNET_OK;
 }
 
 
 /**
- * Convert information from an auditor to a JSON object.
+ * Actual "main" logic that builds the state which this module
+ * evolves around.  This function will import the key data from
+ * the exchangedb module and convert it into (1) internally used
+ * lookup tables, and (2) HTTP responses to be returned from
+ * /keys.
  *
- * @param apub the auditor's public key
- * @param auditor_url URL of the auditor
- * @param dki_len length of @a dki and @a asigs arrays
- * @param asigs the auditor's signatures
- * @param dki array of denomination coin data signed by the auditor
- * @return a JSON object describing the auditor information and signature
+ * @return NULL on error (usually pretty fatal...)
  */
-static json_t *
-auditor_to_json (const struct TALER_AuditorPublicKeyP *apub,
-                 const char *auditor_url,
-                 unsigned int dki_len,
-                 const struct TALER_AuditorSignatureP **asigs,
-                 const struct TALER_DenominationKeyValidityPS **dki)
+static struct TEH_KS_StateHandle *
+make_fresh_key_state ()
 {
-  unsigned int i;
-  json_t *ja;
-
-  ja = json_array ();
-  for (i=0;i<dki_len;i++)
-    GNUNET_assert (0 ==
-                   json_array_append_new (ja,
-                                          json_pack ("{s:o, s:o}",
-                                                     "denom_pub_h",
-                                                     
GNUNET_JSON_from_data_auto (&dki[i]->denom_hash),
-                                                     "auditor_sig",
-                                                     
GNUNET_JSON_from_data_auto (asigs[i]))));
-  return
-    json_pack ("{s:o, s:s, s:o}",
-               "denomination_keys", ja,
-               "auditor_url", auditor_url,
-               "auditor_pub",
-               GNUNET_JSON_from_data_auto (apub));
-}
+  struct TEH_KS_StateHandle *key_state;
+  struct ResponseFactoryContext rfc;
+  struct GNUNET_TIME_Absolute last;
+  unsigned int off;
+
+  memset (&rfc,
+          0,
+          sizeof (rfc));
+  rfc.payback_array = json_array ();
+  if (NULL == rfc.payback_array)
+  {
+    GNUNET_break (0);
+    return NULL;
+  }
+  rfc.sign_keys_array = json_array ();
+  if (NULL == rfc.sign_keys_array)
+  {
+    GNUNET_break (0);
+    json_decref (rfc.payback_array);
+    return NULL;
+  }
 
+  key_state = GNUNET_new (struct TEH_KS_StateHandle);
+  rfc.key_state = key_state;
+  key_state->min_dk_expire = GNUNET_TIME_UNIT_FOREVER_ABS;
+  key_state->denomkey_map = GNUNET_CONTAINER_multihashmap_create (32,
+                                                                  GNUNET_NO);
+  key_state->revoked_map = GNUNET_CONTAINER_multihashmap_create (4,
+                                                                 GNUNET_NO);
+  key_state->reload_time = GNUNET_TIME_absolute_get ();
+  GNUNET_TIME_round_abs (&key_state->reload_time);
+
+  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+              "Loading keys from `%s'\n",
+              TEH_exchange_directory);
+  /* Initialize the 'denomkey_map' and the 'revoked_map' and
+     'rfc.payback_array' */
+  if (-1 ==
+      TALER_EXCHANGEDB_denomination_keys_iterate (TEH_exchange_directory,
+                                                  &TEH_master_public_key,
+                                                  &reload_keys_denom_iter,
+                                                  &rfc))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Failed to load denomination keys from `%s'.\n",
+                TEH_exchange_directory);
+    key_state->refcnt = 1;
+    ks_release (key_state);
+    json_decref (rfc.payback_array);
+    json_decref (rfc.sign_keys_array);
+    return NULL;
+  }
+  if (0 == GNUNET_CONTAINER_multihashmap_size (key_state->denomkey_map))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Have no denomination keys. Bad configuration.\n");
+    key_state->refcnt = 1;
+    ks_release (key_state);
+    destroy_response_factory (&rfc);
+    return NULL;
+  }
 
-/**
- * @brief Iterator called with auditor information.
- * Check that the @a mpub actually matches this exchange, and then
- * add the auditor information to our /keys response (if it is
- * (still) applicable).
- *
- * @param cls closure with the `struct TEH_KS_StateHandle *`
- * @param apub the auditor's public key
- * @param auditor_url URL of the auditor
- * @param mpub the exchange's public key (as expected by the auditor)
- * @param dki_len length of @a dki and @a asigs
- * @param asigs array with the auditor's signatures, of length @a dki_len
- * @param dki array of denomination coin data signed by the auditor
- * @return #GNUNET_OK to continue to iterate,
- *  #GNUNET_NO to stop iteration with no error,
- *  #GNUNET_SYSERR to abort iteration with error!
- */
-static int
-reload_auditor_iter (void *cls,
-                     const struct TALER_AuditorPublicKeyP *apub,
-                     const char *auditor_url,
-                     const struct TALER_MasterPublicKeyP *mpub,
-                     unsigned int dki_len,
-                     const struct TALER_AuditorSignatureP *asigs,
-                     const struct TALER_DenominationKeyValidityPS *dki)
-{
-  struct TEH_KS_StateHandle *ctx = cls;
-  unsigned int keep;
-  const struct TALER_AuditorSignatureP *kept_asigs[dki_len];
-  const struct TALER_DenominationKeyValidityPS *kept_dkis[dki_len];
+  /* Initialize `current_sign_key_issue` and `rfc.sign_keys_array` */
+  TALER_EXCHANGEDB_signing_keys_iterate (TEH_exchange_directory,
+                                         &reload_keys_sign_iter,
+                                         &rfc);
+  if (0 !=
+      memcmp (&key_state->current_sign_key_issue.issue.master_public_key,
+              &TEH_master_public_key,
+              sizeof (struct TALER_MasterPublicKeyP)))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Have no signing key. Bad configuration.\n");
+    key_state->refcnt = 1;
+    ks_release (key_state);
+    destroy_response_factory (&rfc);
+    return NULL;
+  }
 
-  /* Check if the signature is at least for this exchange. */
-  if (0 != memcmp (&mpub->eddsa_pub,
-                   &TEH_master_public_key,
-                   sizeof (struct GNUNET_CRYPTO_EddsaPublicKey)))
+  /* Initialize and sort the `denomkey_array` */
+  rfc.denomkey_array
+    = GNUNET_new_array (GNUNET_CONTAINER_multihashmap_size 
(key_state->denomkey_map),
+                        struct DenominationKeyEntry);
+  GNUNET_CONTAINER_multihashmap_iterate (key_state->denomkey_map,
+                                         &initialize_denomkey_array,
+                                         &rfc);
+  GNUNET_assert (rfc.denomkey_array_length ==
+                 GNUNET_CONTAINER_multihashmap_size (key_state->denomkey_map));
+  qsort (rfc.denomkey_array,
+         rfc.denomkey_array_length,
+         sizeof (struct DenominationKeyEntry),
+         &denomkey_array_sort_comparator);
+
+  /* Complete `denomkey_array` by adding auditor signature data */
+  TALER_EXCHANGEDB_auditor_iterate (cfg,
+                                    &reload_auditor_iter,
+                                    &rfc);
+  /* Sanity check: do we have auditors for all denomination keys? */
+  for (unsigned int i=0;i<rfc.denomkey_array_length;i++)
   {
-    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                "Auditing information provided for a different exchange, 
ignored\n");
-    return GNUNET_OK;
+    const struct DenominationKeyEntry *dke
+      = &rfc.denomkey_array[i];
+
+    if (NULL == dke->as_head)
+      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                 "Denomination key `%s' at %p not signed by any auditor!\n",
+                 GNUNET_h2s (&dke->denom_key_hash),
+                 dke);
   }
-  /* Filter the auditor information for those for which the
-     keys actually match the denomination keys that are active right now */
-  keep = 0;
-  for (unsigned int i=0;i<dki_len;i++)
+  
+  /* Determine size of `krd_array` by counting number of discrete
+     denomination key starting times. */
+  last = GNUNET_TIME_UNIT_ZERO_ABS;
+  key_state->krd_array_length = 0;
+  off = 1; /* reserve one slot for the "no keys" response */
+  for (unsigned int i=0;i<rfc.denomkey_array_length;i++)
   {
-    if (GNUNET_YES ==
-        GNUNET_CONTAINER_multihashmap_contains (ctx->denomkey_map,
-                                                &dki[i].denom_hash))
+    const struct DenominationKeyEntry *dke
+      = &rfc.denomkey_array[i];
+    struct GNUNET_TIME_Absolute d
+      = GNUNET_TIME_absolute_ntoh (dke->dki->issue.properties.start);
+
+    if (last.abs_value_us == d.abs_value_us)
+      continue;
+    last = d;
+    off++;
+  }
+
+  /* Compute next automatic reload time */
+  key_state->next_reload =
+    GNUNET_TIME_absolute_min (GNUNET_TIME_absolute_ntoh 
(key_state->current_sign_key_issue.issue.expire),
+                              key_state->min_dk_expire);
+  GNUNET_assert (0 != key_state->next_reload.abs_value_us);
+
+
+  /* Initialize `krd_array` */
+  key_state->krd_array_length = off;
+  key_state->krd_array
+    = GNUNET_new_array (key_state->krd_array_length,
+                        struct KeysResponseData);
+  off = 0;
+  last = GNUNET_TIME_UNIT_ZERO_ABS;
+  for (unsigned int i=0;i<rfc.denomkey_array_length;i++)
+  {
+    const struct DenominationKeyEntry *dke
+      = &rfc.denomkey_array[i];
+    struct GNUNET_TIME_Absolute d
+      = GNUNET_TIME_absolute_ntoh (dke->dki->issue.properties.start);
+
+    if (last.abs_value_us == d.abs_value_us)
+      continue;
+    if (GNUNET_OK !=
+        build_keys_response (&rfc,
+                             &key_state->krd_array[off++],
+                             i,
+                             last))
     {
-      kept_asigs[keep] = &asigs[i];
-      kept_dkis[keep] = &dki[i];
-      keep++;
+      /* Fail hard, will be caught via test on `off` below */
+      GNUNET_break (0);
+      off = key_state->krd_array_length; /* flag as 'invalid' */
+      break;
     }
+    last = d;
   }
-  /* add auditor information to our /keys response */
-  GNUNET_assert (0 ==
-                 json_array_append_new (ctx->auditors_array,
-                                        auditor_to_json (apub,
-                                                         auditor_url,
-                                                         keep,
-                                                         kept_asigs,
-                                                         kept_dkis)));
-  return GNUNET_OK;
+
+  /* Finally, build an `empty` response without denomination keys
+     for requests past the last known denomination key start date */
+  if ( (off + 1 < key_state->krd_array_length) ||
+       (GNUNET_OK !=
+        build_keys_response (&rfc,
+                             &key_state->krd_array[off++],
+                             rfc.denomkey_array_length,
+                             last)) )
+  {
+    GNUNET_break (0);
+    key_state->refcnt = 1;
+    ks_release (key_state);
+    destroy_response_factory (&rfc);
+    return NULL;
+  }
+
+  /* Clean up intermediary state we don't need anymore and return
+     new key_state! */
+  destroy_response_factory (&rfc);
+  return key_state;
 }
 
 
+/* ************************** Persistent part ********************** */
+
 /**
- * Iterator for freeing denomination keys.
+ * Exchange key state.  This is the long-term, read-only internal global state,
+ * which the various threads "lock" to use in read-only ways.  We eventually
+ * create a completely new object "on the side" and then start to return
+ * the new read-only object to threads that ask. Once none of the threads
+ * use the previous object (RC drops to zero), we discard it.
  *
- * @param cls closure with the `struct TEH_KS_StateHandle`
- * @param key key for the denomination key
- * @param value coin details
- * @return #GNUNET_OK to continue to iterate,
- *  #GNUNET_NO to stop iteration with no error,
- *  #GNUNET_SYSERR to abort iteration with error!
+ * Thus, this instance should never be used directly, instead reserve
+ * access via #TEH_KS_acquire() and release it via #TEH_KS_release().
  */
-static int
-free_denom_key (void *cls,
-                const struct GNUNET_HashCode *key,
-                void *value)
-{
-  struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki = value;
-
-  GNUNET_CRYPTO_rsa_private_key_free (dki->denom_priv.rsa_private_key);
-  GNUNET_CRYPTO_rsa_public_key_free (dki->denom_pub.rsa_public_key);
-  GNUNET_free (dki);
-  return GNUNET_OK;
-}
-
+static struct TEH_KS_StateHandle *internal_key_state;
 
 /**
- * Release key state, free if necessary (if reference count gets to zero).
- * Internal method used when the mutex is already held.
- *
- * @param key_state the key state to release
+ * Mutex protecting access to #internal_key_state.
  */
-static void
-ks_release_ (struct TEH_KS_StateHandle *key_state)
-{
-  GNUNET_assert (0 < key_state->refcnt);
-  key_state->refcnt--;
-  if (0 == key_state->refcnt)
-  {
-    if (NULL != key_state->denom_keys_array)
-    {
-      json_decref (key_state->denom_keys_array);
-      key_state->denom_keys_array = NULL;
-    }
-    if (NULL != key_state->payback_array)
-    {
-      json_decref (key_state->payback_array);
-      key_state->payback_array = NULL;
-    }
-    if (NULL != key_state->sign_keys_array)
-    {
-      json_decref (key_state->sign_keys_array);
-      key_state->sign_keys_array = NULL;
-    }
-    if (NULL != key_state->denomkey_map)
-    {
-      GNUNET_CONTAINER_multihashmap_iterate (key_state->denomkey_map,
-                                             &free_denom_key,
-                                             key_state);
-      GNUNET_CONTAINER_multihashmap_destroy (key_state->denomkey_map);
-      key_state->denomkey_map = NULL;
-    }
-    if (NULL != key_state->revoked_map)
-    {
-      GNUNET_CONTAINER_multihashmap_iterate (key_state->revoked_map,
-                                             &free_denom_key,
-                                             key_state);
-      GNUNET_CONTAINER_multihashmap_destroy (key_state->revoked_map);
-      key_state->revoked_map = NULL;
-    }
-    GNUNET_free_non_null (key_state->keys_json);
-    GNUNET_free_non_null (key_state->keys_jsonz);
-    GNUNET_free (key_state);
-  }
-}
+static pthread_mutex_t internal_key_state_mutex = PTHREAD_MUTEX_INITIALIZER;
+
 
 
 /**
@@ -786,7 +1610,7 @@ TEH_KS_release_ (const char *location,
                  struct TEH_KS_StateHandle *key_state)
 {
   GNUNET_assert (0 == pthread_mutex_lock (&internal_key_state_mutex));
-  ks_release_ (key_state);
+  ks_release (key_state);
   GNUNET_assert (0 == pthread_mutex_unlock (&internal_key_state_mutex));
 }
 
@@ -797,137 +1621,26 @@ TEH_KS_release_ (const char *location,
  * to #TEH_KS_release() must be made.
  *
  * @param location name of the function in which the lock is acquired
- * @return the key state
+ * @return the key state, NULL on error (usually pretty fatal)
  */
 struct TEH_KS_StateHandle *
 TEH_KS_acquire_ (const char *location)
 {
   struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get ();
   struct TEH_KS_StateHandle *key_state;
-  json_t *keys;
-  struct TALER_ExchangeKeySetPS ks;
-  struct TALER_ExchangeSignatureP sig;
 
   GNUNET_assert (0 == pthread_mutex_lock (&internal_key_state_mutex));
   if ( (NULL != internal_key_state) &&
        (internal_key_state->next_reload.abs_value_us <= now.abs_value_us) )
   {
-    ks_release_ (internal_key_state);
+    ks_release (internal_key_state);
     internal_key_state = NULL;
   }
   if (NULL == internal_key_state)
-  {
-    key_state = GNUNET_new (struct TEH_KS_StateHandle);
-    key_state->hash_context = GNUNET_CRYPTO_hash_context_start ();
-    key_state->min_dk_expire = GNUNET_TIME_UNIT_FOREVER_ABS;
-
-    key_state->denom_keys_array = json_array ();
-    GNUNET_assert (NULL != key_state->denom_keys_array);
-
-    key_state->payback_array = json_array ();
-    GNUNET_assert (NULL != key_state->payback_array);
-
-    key_state->sign_keys_array = json_array ();
-    GNUNET_assert (NULL != key_state->sign_keys_array);
-
-    key_state->auditors_array = json_array ();
-    GNUNET_assert (NULL != key_state->auditors_array);
-
-    key_state->denomkey_map = GNUNET_CONTAINER_multihashmap_create (32,
-                                                                    GNUNET_NO);
-    key_state->revoked_map = GNUNET_CONTAINER_multihashmap_create (4,
-                                                                   GNUNET_NO);
-    key_state->reload_time = GNUNET_TIME_absolute_get ();
-    GNUNET_TIME_round_abs (&key_state->reload_time);
-    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-                "Loading keys from `%s'\n",
-                TEH_exchange_directory);
-    if (-1 == TALER_EXCHANGEDB_denomination_keys_iterate 
(TEH_exchange_directory,
-                                                          
&TEH_master_public_key,
-                                                          
&reload_keys_denom_iter,
-                                                          key_state))
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Can't load denomination keys.\n");
-      GNUNET_assert (0 == pthread_mutex_unlock (&internal_key_state_mutex));
-      return NULL;
-    }
-    TALER_EXCHANGEDB_signing_keys_iterate (TEH_exchange_directory,
-                                           &reload_keys_sign_iter,
-                                           key_state);
-    TALER_EXCHANGEDB_auditor_iterate (cfg,
-                                      &reload_auditor_iter,
-                                      key_state);
-
-    if (0 != memcmp 
(&key_state->current_sign_key_issue.issue.master_public_key,
-                     &TEH_master_public_key,
-                     sizeof (struct TALER_MasterPublicKeyP)))
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  "Have no signing key. Bad configuration.\n");
-      GNUNET_assert (0 == pthread_mutex_unlock (&internal_key_state_mutex));
-      return NULL;
-    }
-
-    if (0 == GNUNET_CONTAINER_multihashmap_size (key_state->denomkey_map))
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  "Have no denomination keys. Bad configuration.\n");
-      GNUNET_assert (0 == pthread_mutex_unlock (&internal_key_state_mutex));
-      return NULL;
-    }
-
-    ks.purpose.size = htonl (sizeof (ks));
-    ks.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_KEY_SET);
-    ks.list_issue_date = GNUNET_TIME_absolute_hton (key_state->reload_time);
-    GNUNET_CRYPTO_hash_context_finish (key_state->hash_context,
-                                       &ks.hc);
-    key_state->hash_context = NULL;
-    GNUNET_assert (GNUNET_OK ==
-                   GNUNET_CRYPTO_eddsa_sign 
(&key_state->current_sign_key_issue.signkey_priv.eddsa_priv,
-                                             &ks.purpose,
-                                             &sig.eddsa_signature));
-    key_state->next_reload =
-      GNUNET_TIME_absolute_min (GNUNET_TIME_absolute_ntoh 
(key_state->current_sign_key_issue.issue.expire),
-                                key_state->min_dk_expire);
-    if (0 == key_state->next_reload.abs_value_us)
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  "No valid signing key found!\n");
-
-    keys = json_pack ("{s:s, s:o, s:o, s:o, s:o, s:o, s:o, s:o, s:o}",
-                      "version", TALER_PROTOCOL_VERSION,
-                      "master_public_key",
-                      GNUNET_JSON_from_data_auto (&TEH_master_public_key),
-                      "signkeys", key_state->sign_keys_array,
-                      "denoms", key_state->denom_keys_array,
-                      "payback", key_state->payback_array,
-                      "auditors", key_state->auditors_array,
-                      "list_issue_date", GNUNET_JSON_from_time_abs 
(key_state->reload_time),
-                      "eddsa_pub", GNUNET_JSON_from_data_auto 
(&key_state->current_sign_key_issue.issue.signkey_pub),
-                      "eddsa_sig", GNUNET_JSON_from_data_auto (&sig));
-    GNUNET_assert (NULL != keys);
-    key_state->auditors_array = NULL;
-    key_state->sign_keys_array = NULL;
-    key_state->denom_keys_array = NULL;
-    key_state->payback_array = NULL;
-    key_state->keys_json = json_dumps (keys,
-                                       JSON_INDENT (2));
-    GNUNET_assert (NULL != key_state->keys_json);
-    json_decref (keys);
-    /* also compute compressed version of /keys */
-    key_state->keys_jsonz = GNUNET_strdup (key_state->keys_json);
-    key_state->keys_jsonz_size = strlen (key_state->keys_json);
-    if (MHD_YES !=
-       TEH_RESPONSE_body_compress (&key_state->keys_jsonz,
-                                   &key_state->keys_jsonz_size))
-    {
-      GNUNET_free (key_state->keys_jsonz);
-      key_state->keys_jsonz = NULL;
-      key_state->keys_jsonz_size = 0;
-    }
-    internal_key_state = key_state;
-  }
+    internal_key_state = make_fresh_key_state ();
   key_state = internal_key_state;
-  key_state->refcnt++;
+  if (NULL != key_state)
+    key_state->refcnt++;
   GNUNET_assert (0 == pthread_mutex_unlock (&internal_key_state_mutex));
 
   return key_state;
@@ -1174,11 +1887,17 @@ read_again:
 /**
  * Sign the message in @a purpose with the exchange's signing key.
  *
+ * FIXME:
+ * - Change API to return status code and do not assert on TEH_KS_acquire()
+ *   failures, instead allow caller to handle it (i.e. by returning
+ *   #TALER_EC_EXCHANGE_BAD_CONFIGURATION to application).
+ *
  * @param purpose the message to sign
  * @param[out] pub set to the current public signing key of the exchange
  * @param[out] sig signature over purpose using current signing key
+ * @return #GNUNET_OK on success, #GNUNET_SYSERR if we lack key material
  */
-void
+int
 TEH_KS_sign (const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose,
              struct TALER_ExchangePublicKeyP *pub,
              struct TALER_ExchangeSignatureP *sig)
@@ -1187,64 +1906,44 @@ TEH_KS_sign (const struct 
GNUNET_CRYPTO_EccSignaturePurpose *purpose,
   struct TEH_KS_StateHandle *key_state;
 
   key_state = TEH_KS_acquire ();
+  if (NULL == key_state)
+  {
+    /* This *can* happen if the exchange's keys are
+       not properly maintained. */
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+               _("Cannot sign request, no valid keys available\n"));
+    return GNUNET_SYSERR;
+  }
   *pub = key_state->current_sign_key_issue.issue.signkey_pub;
   GNUNET_assert (GNUNET_OK ==
                  GNUNET_CRYPTO_eddsa_sign 
(&key_state->current_sign_key_issue.signkey_priv.eddsa_priv,
                                            purpose,
                                            &sig->eddsa_signature));
   TEH_KS_release (key_state);
+  return GNUNET_OK;
 }
 
 
 /**
- * Produce HTTP "Date:" header.
+ * Comparator used for a binary search for @a key in the
+ * `struct KeysResponseData` array.
  *
- * @param at time to write to @a date
- * @param[out] date where to write the header, with
- *        at least 128 bytes available space.
+ * @param key pointer to a `struct GNUNET_TIME_Absolute`
+ * @param value pointer to a `struct KeysResponseData` array entry
+ * @return 0 if time matches, -1 if key is smaller, 1 if key is larger
  */
-static void
-get_date_string (struct GNUNET_TIME_Absolute at,
-                 char *date)
+static int
+krd_search_comparator (const void *key,
+                       const void *value)
 {
-  static const char *const days[] =
-    { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
-  static const char *const mons[] =
-    { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct",
-    "Nov", "Dec"
-  };
-  struct tm now;
-  time_t t;
-#if !defined(HAVE_C11_GMTIME_S) && !defined(HAVE_W32_GMTIME_S) && 
!defined(HAVE_GMTIME_R)
-  struct tm* pNow;
-#endif
-
-  date[0] = 0;
-  t = (time_t) (at.abs_value_us / 1000LL / 1000LL);
-#if defined(HAVE_C11_GMTIME_S)
-  if (NULL == gmtime_s (&t, &now))
-    return;
-#elif defined(HAVE_W32_GMTIME_S)
-  if (0 != gmtime_s (&now, &t))
-    return;
-#elif defined(HAVE_GMTIME_R)
-  if (NULL == gmtime_r(&t, &now))
-    return;
-#else
-  pNow = gmtime(&t);
-  if (NULL == pNow)
-    return;
-  now = *pNow;
-#endif
-  sprintf (date,
-           "%3s, %02u %3s %04u %02u:%02u:%02u GMT",
-           days[now.tm_wday % 7],
-           (unsigned int) now.tm_mday,
-           mons[now.tm_mon % 12],
-           (unsigned int) (1900 + now.tm_year),
-           (unsigned int) now.tm_hour,
-           (unsigned int) now.tm_min,
-           (unsigned int) now.tm_sec);
+  const struct GNUNET_TIME_Absolute *kd = key;
+  const struct KeysResponseData *krd = value;
+
+  if (kd->abs_value_us > krd->cherry_pick_date.abs_value_us)
+    return 1;
+  if (kd->abs_value_us < krd->cherry_pick_date.abs_value_us)
+    return -1;
+  return 0;
 }
 
 
@@ -1267,14 +1966,10 @@ TEH_KS_handler_keys (struct TEH_RequestHandler *rh,
                      size_t *upload_data_size)
 {
   struct TEH_KS_StateHandle *key_state;
-  struct MHD_Response *response;
   int ret;
-  char dat[128];
-  char *json;
-  size_t json_len;
-  int comp;
   const char *have;
   struct GNUNET_TIME_Absolute last_issue_date;
+  const struct KeysResponseData *krd;
 
   have = MHD_lookup_connection_value (connection,
                                      MHD_GET_ARGUMENT_KIND,
@@ -1282,7 +1977,7 @@ TEH_KS_handler_keys (struct TEH_RequestHandler *rh,
   if (NULL != have)
   {
     unsigned long long haven;
-    
+
     if (1 !=
        sscanf (have,
                "%llu",
@@ -1293,68 +1988,45 @@ TEH_KS_handler_keys (struct TEH_RequestHandler *rh,
                                             TALER_EC_KEYS_HAVE_NOT_NUMERIC,
                                             "have");
     }
-    last_issue_date.abs_value_us = (uint64_t) haven;
+    last_issue_date.abs_value_us = (uint64_t) haven * 1000000LLU;
   }
   else
   {
     last_issue_date.abs_value_us = 0LLU;
   }
-  
   key_state = TEH_KS_acquire ();
-  /* FIXME: #4840: compute /keys delta from last_issue_date */
-  (void) last_issue_date;
-  comp = MHD_NO;
-  if (NULL != key_state->keys_jsonz)
-    comp = TEH_RESPONSE_can_compress (connection);
-  if (MHD_YES == comp)
-  {
-    json = key_state->keys_jsonz;
-    json_len = key_state->keys_jsonz_size;
-  }
-  else
+  if (NULL == key_state)
   {
-    json = key_state->keys_json;
-    json_len = strlen (key_state->keys_json);
+    TALER_LOG_ERROR ("Lacking keys to operate\n");
+    return TEH_RESPONSE_reply_internal_error (connection,
+                                              
TALER_EC_EXCHANGE_BAD_CONFIGURATION,
+                                              "no keys");
   }
-  response = MHD_create_response_from_buffer (json_len,
-                                              json,
-                                              MHD_RESPMEM_MUST_COPY);
-  TEH_KS_release (key_state);
-  if (NULL == response)
+  krd = bsearch (&last_issue_date,
+                 key_state->krd_array,
+                 key_state->krd_array_length,
+                 sizeof (struct KeysResponseData),
+                 &krd_search_comparator);
+  if ( (NULL == krd) &&
+       (key_state->krd_array_length > 0) )
   {
-    GNUNET_break (0);
-    return MHD_NO;
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "Client provided invalid cherry picking timestamp %s, 
returning full response\n",
+                GNUNET_STRINGS_absolute_time_to_string (last_issue_date));
+    krd = &key_state->krd_array[0];
   }
-  TEH_RESPONSE_add_global_headers (response);
-  GNUNET_break (MHD_YES ==
-                MHD_add_response_header (response,
-                                         MHD_HTTP_HEADER_CONTENT_TYPE,
-                                         rh->mime_type));
-  if (MHD_YES !=
-      MHD_add_response_header (response,
-                              MHD_HTTP_HEADER_CONTENT_ENCODING,
-                              "deflate"))
+  if (NULL == krd)
   {
+    /* FIXME: should return 500 response instead... */
     GNUNET_break (0);
-    MHD_destroy_response (response);
     return MHD_NO;
   }
-  get_date_string (key_state->reload_time,
-                   dat);
-  GNUNET_break (MHD_YES ==
-                MHD_add_response_header (response,
-                                         MHD_HTTP_HEADER_LAST_MODIFIED,
-                                         dat));
-  get_date_string (key_state->next_reload,
-                   dat);
-  GNUNET_break (MHD_YES ==
-                MHD_add_response_header (response,
-                                         MHD_HTTP_HEADER_EXPIRES,
-                                         dat));
   ret = MHD_queue_response (connection,
                             rh->response_code,
-                            response);
-  MHD_destroy_response (response);
+                            (MHD_YES == TEH_RESPONSE_can_compress (connection))
+                            ? krd->response_compressed
+                            : krd->response_uncompressed);
+  TEH_KS_release (key_state);
   return ret;
 }
 
diff --git a/src/exchange/taler-exchange-httpd_keystate.h 
b/src/exchange/taler-exchange-httpd_keystate.h
index 2b7df63..b956c63 100644
--- a/src/exchange/taler-exchange-httpd_keystate.h
+++ b/src/exchange/taler-exchange-httpd_keystate.h
@@ -42,7 +42,7 @@ struct TEH_KS_StateHandle;
  * to #TEH_KS_release() must be made.
  *
  * @param location name of the function in which the lock is acquired
- * @return the key state
+ * @return the key state, NULL on error (usually pretty fatal)
  */
 struct TEH_KS_StateHandle *
 TEH_KS_acquire_ (const char *location);
@@ -140,8 +140,9 @@ TEH_KS_loop (void);
  * @param purpose the message to sign
  * @param[out] pub set to the current public signing key of the exchange
  * @param[out] sig signature over purpose using current signing key
+ * @return #GNUNET_OK on success, #GNUNET_SYSERR if we lack key material
  */
-void
+int
 TEH_KS_sign (const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose,
              struct TALER_ExchangePublicKeyP *pub,
              struct TALER_ExchangeSignatureP *sig);
diff --git a/src/exchange/taler-exchange-httpd_mhd.c 
b/src/exchange/taler-exchange-httpd_mhd.c
index ee1781a..e76ada2 100644
--- a/src/exchange/taler-exchange-httpd_mhd.c
+++ b/src/exchange/taler-exchange-httpd_mhd.c
@@ -89,10 +89,10 @@ TEH_MHD_handler_static_response (struct TEH_RequestHandler 
*rh,
  */
 int
 TEH_MHD_handler_agpl_redirect (struct TEH_RequestHandler *rh,
-                                  struct MHD_Connection *connection,
-                                  void **connection_cls,
-                                  const char *upload_data,
-                                  size_t *upload_data_size)
+                               struct MHD_Connection *connection,
+                               void **connection_cls,
+                               const char *upload_data,
+                               size_t *upload_data_size)
 {
   const char *agpl =
     "This server is licensed under the Affero GPL. You will now be redirected 
to the source code.";
diff --git a/src/exchange/taler-exchange-httpd_payback.c 
b/src/exchange/taler-exchange-httpd_payback.c
index 8b4051c..e6fade4 100644
--- a/src/exchange/taler-exchange-httpd_payback.c
+++ b/src/exchange/taler-exchange-httpd_payback.c
@@ -82,9 +82,15 @@ reply_payback_success (struct MHD_Connection *connection,
                      amount);
   pc.coin_pub = *coin_pub;
   pc.reserve_pub = *reserve_pub;
-  TEH_KS_sign (&pc.purpose,
-               &pub,
-               &sig);
+  if (GNUNET_OK !=
+      TEH_KS_sign (&pc.purpose,
+                  &pub,
+                  &sig))
+  {
+    return TEH_RESPONSE_reply_internal_error (connection,
+                                              
TALER_EC_EXCHANGE_BAD_CONFIGURATION,
+                                              "no keys");
+  }
   return TEH_RESPONSE_reply_json_pack (connection,
                                        MHD_HTTP_OK,
                                        "{s:o, s:o, s:o, s:o, s:o}",
@@ -115,7 +121,7 @@ struct PaybackContext
    * Details about the coin.
    */
   const struct TALER_CoinPublicInfo *coin;
-  
+
   /**
    * Key used to blind the coin.
    */
@@ -174,7 +180,7 @@ payback_transaction (void *cls,
   struct TALER_EXCHANGEDB_TransactionList *tl;
   struct TALER_Amount spent;
   enum GNUNET_DB_QueryStatus qs;
-  
+
   /* Check whether a payback is allowed, and if so, to which
      reserve / account the money should go */
   qs = TEH_plugin->get_reserve_by_h_blind (TEH_plugin->cls,
@@ -214,8 +220,9 @@ payback_transaction (void *cls,
     }
     return qs;
   }
-  TALER_amount_get_zero (pc->value.currency,
-                         &spent);
+  GNUNET_assert (GNUNET_OK ==
+                 TALER_amount_get_zero (pc->value.currency,
+                                        &spent));
   if (GNUNET_OK !=
       TEH_DB_calculate_transaction_list_totals (tl,
                                                &spent,
@@ -311,6 +318,13 @@ verify_and_execute_payback (struct MHD_Connection 
*connection,
 
   /* check denomination exists and is in payback mode */
   key_state = TEH_KS_acquire ();
+  if (NULL == key_state)
+  {
+    TALER_LOG_ERROR ("Lacking keys to operate\n");
+    return TEH_RESPONSE_reply_internal_error (connection,
+                                              
TALER_EC_EXCHANGE_BAD_CONFIGURATION,
+                                              "no keys");
+  }
   dki = TEH_KS_denomination_key_lookup (key_state,
                                         &coin->denom_pub,
                                        TEH_KS_DKU_PAYBACK);
@@ -386,7 +400,7 @@ verify_and_execute_payback (struct MHD_Connection 
*connection,
                              &payback_transaction,
                              &pc))
     return mhd_ret;
-  
+
   return reply_payback_success (connection,
                                &coin->coin_pub,
                                &pc.reserve_pub,
diff --git a/src/exchange/taler-exchange-httpd_refresh_melt.c 
b/src/exchange/taler-exchange-httpd_refresh_melt.c
index edcd849..320ec9d 100644
--- a/src/exchange/taler-exchange-httpd_refresh_melt.c
+++ b/src/exchange/taler-exchange-httpd_refresh_melt.c
@@ -135,9 +135,15 @@ reply_refresh_melt_success (struct MHD_Connection 
*connection,
   body.session_hash = *session_hash;
   body.noreveal_index = htons (noreveal_index);
   body.reserved = htons (0);
-  TEH_KS_sign (&body.purpose,
-               &pub,
-               &sig);
+  if (GNUNET_OK !=
+      TEH_KS_sign (&body.purpose,
+                  &pub,
+                  &sig))
+  {
+    return TEH_RESPONSE_reply_internal_error (connection,
+                                              
TALER_EC_EXCHANGE_BAD_CONFIGURATION,
+                                              "no keys");
+  }
   sig_json = GNUNET_JSON_from_data_auto (&sig);
   GNUNET_assert (NULL != sig_json);
   return TEH_RESPONSE_reply_json_pack (connection,
@@ -163,7 +169,7 @@ struct RefreshMeltContext
   /**
    * Information about the denomination key of the coin being
    * melted.
-   */ 
+   */
   struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *dki;
 
   /**
@@ -184,7 +190,7 @@ struct RefreshMeltContext
 
   /**
    * Set to the session hash once the @e hash_context has finished.
-   */ 
+   */
   struct GNUNET_HashCode session_hash;
 
   /**
@@ -220,7 +226,7 @@ struct RefreshMeltContext
  * @param[out] mhd_ret status code to return to MHD on hard error
  * @return transaction status code
  */
-static enum GNUNET_DB_QueryStatus 
+static enum GNUNET_DB_QueryStatus
 refresh_check_melt (struct MHD_Connection *connection,
                     struct TALER_EXCHANGEDB_Session *session,
                    struct RefreshMeltContext *rmc,
@@ -416,7 +422,7 @@ refresh_melt_prepare (struct MHD_Connection *connection,
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "/refresh/melt request for session %s\n",
               GNUNET_h2s (&rmc->session_hash));
-  
+
   GNUNET_assert (GNUNET_OK ==
                  TALER_amount_get_zero (TEH_exchange_currency_string,
                                         &total_cost));
@@ -700,7 +706,7 @@ handle_refresh_melt_json (struct MHD_Connection *connection,
                                      buf_size);
     GNUNET_free (buf);
   }
-  
+
   /* decode JSON data on coin to melt and check that this is a
      valid coin */
   {
@@ -767,6 +773,13 @@ handle_refresh_melt_json (struct MHD_Connection 
*connection,
   rmc.hash_context = NULL;
 
   rmc.key_state = TEH_KS_acquire ();
+  if (NULL == rmc.key_state)
+  {
+    TALER_LOG_ERROR ("Lacking keys to operate\n");
+    return TEH_RESPONSE_reply_internal_error (connection,
+                                              
TALER_EC_EXCHANGE_BAD_CONFIGURATION,
+                                              "no keys");
+  }
   rmc.dki = TEH_KS_denomination_key_lookup (rmc.key_state,
                                            
&rmc.coin_melt_details.coin_info.denom_pub,
                                            TEH_KS_DKU_DEPOSIT);
@@ -804,7 +817,7 @@ handle_refresh_melt_json (struct MHD_Connection *connection,
                                                
TALER_EC_REFRESH_MELT_AMOUNT_INSUFFICIENT,
                                                "melt amount smaller than 
melting fee");
     }
-    
+
     if (GNUNET_OK !=
        GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_MELT,
                                    &body.purpose,
@@ -818,7 +831,7 @@ handle_refresh_melt_json (struct MHD_Connection *connection,
                                                   "confirm_sig");
     }
   }
-    
+
   /* prepare commit */
   if (GNUNET_OK !=
       refresh_melt_prepare (connection,
diff --git a/src/exchange/taler-exchange-httpd_refresh_reveal.c 
b/src/exchange/taler-exchange-httpd_refresh_reveal.c
index cfb2b68..5d857fc 100644
--- a/src/exchange/taler-exchange-httpd_refresh_reveal.c
+++ b/src/exchange/taler-exchange-httpd_refresh_reveal.c
@@ -531,7 +531,7 @@ refresh_reveal_transaction (void *cls,
   for (unsigned int i=0;i<TALER_CNC_KAPPA;i++)
   {
     int res;
-    
+
     if (i == rc->refresh_session.noreveal_index)
     {
       off = 1;
@@ -542,7 +542,7 @@ refresh_reveal_transaction (void *cls,
                                                 
rc->refresh_session.num_newcoins,
                                                 rc->commit_coins);
       if (0 >= qs)
-      {        
+      {
        cleanup_rc (rc);
         GNUNET_CRYPTO_hash_context_abort (hash_context);
        if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
@@ -596,7 +596,7 @@ refresh_reveal_transaction (void *cls,
     cleanup_rc (rc);
     return GNUNET_DB_STATUS_HARD_ERROR;
   }
-  
+
   /* Client request OK, sign coins */
   rc->ev_sigs = GNUNET_new_array (rc->refresh_session.num_newcoins,
                                  struct TALER_DenominationSignature);
@@ -604,6 +604,12 @@ refresh_reveal_transaction (void *cls,
     struct TEH_KS_StateHandle *key_state;
 
     key_state = TEH_KS_acquire ();
+    if (NULL == key_state)
+    {
+      TALER_LOG_ERROR ("Lacking keys to operate\n");
+      cleanup_rc (rc);
+      return GNUNET_DB_STATUS_HARD_ERROR;
+    }
     for (unsigned int j=0;j<rc->refresh_session.num_newcoins;j++)
     {
       qs = refresh_exchange_coin (connection,
diff --git a/src/exchange/taler-exchange-httpd_refund.c 
b/src/exchange/taler-exchange-httpd_refund.c
index 9846c73..f0aaa65 100644
--- a/src/exchange/taler-exchange-httpd_refund.c
+++ b/src/exchange/taler-exchange-httpd_refund.c
@@ -61,9 +61,15 @@ reply_refund_success (struct MHD_Connection *connection,
                      &refund->refund_amount);
   TALER_amount_hton (&rc.refund_fee,
                      &refund->refund_fee);
-  TEH_KS_sign (&rc.purpose,
-               &pub,
-               &sig);
+  if (GNUNET_OK !=
+      TEH_KS_sign (&rc.purpose,
+                  &pub,
+                  &sig))
+  {
+    return TEH_RESPONSE_reply_internal_error (connection,
+                                              
TALER_EC_EXCHANGE_BAD_CONFIGURATION,
+                                              "no keys");
+  }
   return TEH_RESPONSE_reply_json_pack (connection,
                                        MHD_HTTP_OK,
                                        "{s:s, s:o, s:o}",
@@ -241,7 +247,7 @@ refund_transaction (void *cls,
                                             tl);
     *mhd_ret = TEH_RESPONSE_reply_transaction_unknown (connection,
                                                       
TALER_EC_REFUND_DEPOSIT_NOT_FOUND);
-    return GNUNET_DB_STATUS_HARD_ERROR;    
+    return GNUNET_DB_STATUS_HARD_ERROR;
   }
   /* handle if conflicting refund found */
   if (GNUNET_SYSERR == refund_found)
@@ -250,7 +256,7 @@ refund_transaction (void *cls,
                                      tl);
     TEH_plugin->free_coin_transaction_list (TEH_plugin->cls,
                                             tl);
-    return GNUNET_DB_STATUS_HARD_ERROR; 
+    return GNUNET_DB_STATUS_HARD_ERROR;
   }
   /* handle if identical refund found */
   if (GNUNET_YES == refund_found)
@@ -297,7 +303,7 @@ refund_transaction (void *cls,
   }
   if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
     return qs; /* go and retry */
-  
+
   if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs)
   {
     /* money was already transferred to merchant, can no longer refund */
@@ -325,6 +331,16 @@ refund_transaction (void *cls,
   // FIXME: do this outside of transaction function?
   /* Check refund fee matches fee of denomination key! */
   mks = TEH_KS_acquire ();
+  if (NULL == mks)
+  {
+    TALER_LOG_ERROR ("Lacking keys to operate\n");
+    TEH_plugin->free_coin_transaction_list (TEH_plugin->cls,
+                                            tl);
+    *mhd_ret = TEH_RESPONSE_reply_internal_error (connection,
+                                                  
TALER_EC_EXCHANGE_BAD_CONFIGURATION,
+                                                  "no keys");
+    return GNUNET_DB_STATUS_HARD_ERROR;
+  }
   dki = TEH_KS_denomination_key_lookup (mks,
                                         &dep->coin.denom_pub,
                                        TEH_KS_DKU_DEPOSIT);
diff --git a/src/exchange/taler-exchange-httpd_reserve_withdraw.c 
b/src/exchange/taler-exchange-httpd_reserve_withdraw.c
index 2bc268d..cc21972 100644
--- a/src/exchange/taler-exchange-httpd_reserve_withdraw.c
+++ b/src/exchange/taler-exchange-httpd_reserve_withdraw.c
@@ -159,7 +159,7 @@ withdraw_transaction (void *cls,
                      int *mhd_ret)
 {
   struct WithdrawContext *wc = cls;
-  struct TALER_EXCHANGEDB_ReserveHistory *rh;  
+  struct TALER_EXCHANGEDB_ReserveHistory *rh;
   struct TALER_Amount deposit_total;
   struct TALER_Amount withdraw_total;
   struct TALER_Amount balance;
@@ -200,7 +200,7 @@ withdraw_transaction (void *cls,
   {
     if (GNUNET_DB_STATUS_HARD_ERROR == qs)
       *mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection,
-                                                      
TALER_EC_WITHDRAW_DB_FETCH_ERROR); 
+                                                      
TALER_EC_WITHDRAW_DB_FETCH_ERROR);
     return qs;
   }
   if (NULL == rh)
@@ -237,7 +237,7 @@ withdraw_transaction (void *cls,
     case TALER_EXCHANGEDB_RO_WITHDRAW_COIN:
       {
        struct TALER_EXCHANGEDB_DenominationKeyIssueInformation *tdki;
-       
+
        tdki = TEH_KS_denomination_key_lookup (wc->key_state,
                                               
&pos->details.withdraw->denom_pub,
                                               TEH_KS_DKU_WITHDRAW);
@@ -309,8 +309,9 @@ withdraw_transaction (void *cls,
   if (0 == (res & 2))
   {
     /* did not encounter any withdraw operations, set to zero */
-    TALER_amount_get_zero (deposit_total.currency,
-                           &withdraw_total);
+    GNUNET_assert (GNUNET_OK ==
+                   TALER_amount_get_zero (deposit_total.currency,
+                                          &withdraw_total));
   }
   /* All reserve balances should be non-negative */
   if (GNUNET_SYSERR ==
@@ -321,7 +322,7 @@ withdraw_transaction (void *cls,
     GNUNET_break (0); /* database inconsistent */
     *mhd_ret = TEH_RESPONSE_reply_internal_db_error (connection,
                                                     
TALER_EC_WITHDRAW_RESERVE_HISTORY_IMPOSSIBLE);
-    return GNUNET_DB_STATUS_HARD_ERROR;        
+    return GNUNET_DB_STATUS_HARD_ERROR;
   }
   if (0 < TALER_amount_cmp (&wc->amount_required,
                             &balance))
@@ -348,6 +349,8 @@ withdraw_transaction (void *cls,
                                                  "Internal error");
     return GNUNET_DB_STATUS_HARD_ERROR;
   }
+  TALER_amount_ntoh (&fee_withdraw,
+                     &wc->dki->issue.properties.fee_withdraw);
   wc->collectable.sig = denom_sig;
   wc->collectable.denom_pub = wc->denomination_pub;
   wc->collectable.amount_with_fee = wc->amount_required;
@@ -429,6 +432,14 @@ TEH_RESERVE_handler_reserve_withdraw (struct 
TEH_RequestHandler *rh,
   if (GNUNET_OK != res)
     return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES;
   wc.key_state = TEH_KS_acquire ();
+  if (NULL == wc.key_state)
+  {
+    TALER_LOG_ERROR ("Lacking keys to operate\n");
+    GNUNET_JSON_parse_free (spec);
+    return TEH_RESPONSE_reply_internal_error (connection,
+                                              
TALER_EC_EXCHANGE_BAD_CONFIGURATION,
+                                              "no keys");
+  }
   wc.dki = TEH_KS_denomination_key_lookup (wc.key_state,
                                           &wc.denomination_pub,
                                           TEH_KS_DKU_WITHDRAW);
diff --git a/src/exchange/taler-exchange-httpd_responses.c 
b/src/exchange/taler-exchange-httpd_responses.c
index c31c248..ac86416 100644
--- a/src/exchange/taler-exchange-httpd_responses.c
+++ b/src/exchange/taler-exchange-httpd_responses.c
@@ -53,6 +53,11 @@ TEH_RESPONSE_add_global_headers (struct MHD_Response 
*response)
  *
  * @param connection connection to check
  * @return #MHD_YES if 'deflate' compression is allowed
+ *
+ * Note that right now we're ignoring q-values, which is technically
+ * not correct, and also do not support "*" anywhere but in a line by
+ * itself.  This should eventually be fixed, see also
+ * https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
  */
 int
 TEH_RESPONSE_can_compress (struct MHD_Connection *connection)
@@ -69,11 +74,15 @@ TEH_RESPONSE_can_compress (struct MHD_Connection 
*connection)
               "deflate");
   if (NULL == de)
     return MHD_NO;
+  if (0 == strcmp (de,
+                   "*"))
+    return MHD_YES;
   if ( ( (de == ae) ||
         ( de[-1] == ',') ||
         (de[-1] == ' ') ) &&
        ( (de[strlen ("deflate")] == '\0') ||
-        (de[strlen ("deflate")] == ',') ) )
+        (de[strlen ("deflate")] == ',') ||
+         (de[strlen ("deflate")] == ';') ) )
     return MHD_YES;
   return MHD_NO;
 }
@@ -465,7 +474,7 @@ TEH_RESPONSE_reply_invalid_json (struct MHD_Connection 
*connection)
  * Compile the transaction history of a coin into a JSON object.
  *
  * @param tl transaction history to JSON-ify
- * @return json representation of the @a rh
+ * @return json representation of the @a rh, NULL on error
  */
 json_t *
 TEH_RESPONSE_compile_transaction_history (const struct 
TALER_EXCHANGEDB_TransactionList *tl)
@@ -623,9 +632,15 @@ TEH_RESPONSE_compile_transaction_history (const struct 
TALER_EXCHANGEDB_Transact
                            &payback->value);
         pc.coin_pub = payback->coin.coin_pub;
         pc.reserve_pub = payback->reserve_pub;
-        TEH_KS_sign (&pc.purpose,
-                     &epub,
-                     &esig);
+        if (GNUNET_OK !=
+           TEH_KS_sign (&pc.purpose,
+                        &epub,
+                        &esig))
+       {
+         GNUNET_break (0);
+         json_decref (history);
+         return NULL;
+       }
         GNUNET_assert (0 ==
                        json_array_append_new (history,
                                               json_pack ("{s:s, s:o, s:o, s:o, 
s:o, s:o}",
@@ -709,6 +724,7 @@ TEH_RESPONSE_compile_reserve_history (const struct 
TALER_EXCHANGEDB_ReserveHisto
                               &deposit_total,
                               &pos->details.bank->amount))
         {
+          GNUNET_break (0);
           json_decref (json_history);
           return NULL;
         }
@@ -739,6 +755,7 @@ TEH_RESPONSE_compile_reserve_history (const struct 
TALER_EXCHANGEDB_ReserveHisto
                                &withdraw_total,
                                &value))
          {
+            GNUNET_break (0);
            json_decref (json_history);
            return NULL;
          }
@@ -773,6 +790,7 @@ TEH_RESPONSE_compile_reserve_history (const struct 
TALER_EXCHANGEDB_ReserveHisto
                                &deposit_total,
                                &payback->value))
          {
+            GNUNET_break (0);
            json_decref (json_history);
            return NULL;
          }
@@ -784,9 +802,15 @@ TEH_RESPONSE_compile_reserve_history (const struct 
TALER_EXCHANGEDB_ReserveHisto
                           &payback->value);
        pc.coin_pub = payback->coin.coin_pub;
        pc.reserve_pub = payback->reserve_pub;
-       TEH_KS_sign (&pc.purpose,
-                    &pub,
-                    &sig);
+       if (GNUNET_OK !=
+           TEH_KS_sign (&pc.purpose,
+                        &pub,
+                        &sig))
+       {
+         GNUNET_break (0);
+         json_decref (json_history);
+         return NULL;
+       }
 
        GNUNET_assert (0 ==
                       json_array_append_new (json_history,
@@ -831,12 +855,24 @@ TEH_RESPONSE_compile_reserve_history (const struct 
TALER_EXCHANGEDB_ReserveHisto
        TALER_amount_hton (&rcc.closing_fee,
                           &pos->details.closing->closing_fee);
        rcc.reserve_pub = pos->details.closing->reserve_pub;
-       TALER_JSON_hash (pos->details.closing->receiver_account_details,
-                        &rcc.h_wire);
+       if (GNUNET_OK !=
+            TALER_JSON_hash (pos->details.closing->receiver_account_details,
+                             &rcc.h_wire))
+        {
+          GNUNET_break (0);
+          json_decref (json_history);
+          return NULL;
+        }
        rcc.wtid = pos->details.closing->wtid;
-       TEH_KS_sign (&rcc.purpose,
-                    &pub,
-                    &sig);
+       if (GNUNET_OK !=
+           TEH_KS_sign (&rcc.purpose,
+                        &pub,
+                        &sig))
+       {
+          GNUNET_break (0);
+          json_decref (json_history);
+          return NULL;
+       }
        GNUNET_assert (0 ==
                       json_array_append_new (json_history,
                                              json_pack ("{s:s, s:O, s:o, s:o, 
s:o, s:o, s:o, s:o}",
@@ -861,8 +897,9 @@ TEH_RESPONSE_compile_reserve_history (const struct 
TALER_EXCHANGEDB_ReserveHisto
   if (0 == (2 & ret))
   {
     /* did not encounter any withdraw operations, set to zero */
-    TALER_amount_get_zero (deposit_total.currency,
-                           &withdraw_total);
+    GNUNET_assert (GNUNET_OK ==
+                   TALER_amount_get_zero (deposit_total.currency,
+                                          &withdraw_total));
   }
   if (GNUNET_SYSERR ==
       TALER_amount_subtract (balance,
diff --git a/src/exchange/taler-exchange-httpd_track_transaction.c 
b/src/exchange/taler-exchange-httpd_track_transaction.c
index 7c1bd6a..13a1066 100644
--- a/src/exchange/taler-exchange-httpd_track_transaction.c
+++ b/src/exchange/taler-exchange-httpd_track_transaction.c
@@ -85,9 +85,15 @@ reply_track_transaction (struct MHD_Connection *connection,
   cw.execution_time = GNUNET_TIME_absolute_hton (exec_time);
   TALER_amount_hton (&cw.coin_contribution,
                      coin_contribution);
-  TEH_KS_sign (&cw.purpose,
-               &pub,
-               &sig);
+  if (GNUNET_OK !=
+      TEH_KS_sign (&cw.purpose,
+                  &pub,
+                  &sig))
+  {
+    return TEH_RESPONSE_reply_internal_error (connection,
+                                              
TALER_EC_EXCHANGE_BAD_CONFIGURATION,
+                                              "no keys");
+  }
   return TEH_RESPONSE_reply_json_pack (connection,
                                        MHD_HTTP_OK,
                                        "{s:o, s:o, s:o, s:o, s:o}",
diff --git a/src/exchange/taler-exchange-httpd_track_transfer.c 
b/src/exchange/taler-exchange-httpd_track_transfer.c
index 57b621e..4d28096 100644
--- a/src/exchange/taler-exchange-httpd_track_transfer.c
+++ b/src/exchange/taler-exchange-httpd_track_transfer.c
@@ -131,9 +131,17 @@ reply_track_transfer_details (struct MHD_Connection 
*connection,
   wdp.h_wire = *h_wire;
   GNUNET_CRYPTO_hash_context_finish (hash_context,
                                      &wdp.h_details);
-  TEH_KS_sign (&wdp.purpose,
-               &pub,
-               &sig);
+  if (GNUNET_OK !=
+      TEH_KS_sign (&wdp.purpose,
+                  &pub,
+                  &sig))
+  {
+    json_decref (deposits);
+    return TEH_RESPONSE_reply_internal_error (connection,
+                                              
TALER_EC_EXCHANGE_BAD_CONFIGURATION,
+                                              "no keys");
+  }
+    
   return TEH_RESPONSE_reply_json_pack (connection,
                                        MHD_HTTP_OK,
                                        "{s:o, s:o, s:o, s:o, s:o, s:o, s:o, 
s:o}",
diff --git a/src/exchange/test_taler_exchange_aggregator.c 
b/src/exchange/test_taler_exchange_aggregator.c
index 7f9ea41..0b56b48 100644
--- a/src/exchange/test_taler_exchange_aggregator.c
+++ b/src/exchange/test_taler_exchange_aggregator.c
@@ -1125,6 +1125,12 @@ run (void *cls)
   struct TALER_DenominationPublicKey dpk;
 
   plugin = TALER_EXCHANGEDB_plugin_load (cfg);
+  if (NULL == plugin)
+  {
+    GNUNET_break (0);
+    result = 77;
+    return;
+  }
   if (GNUNET_OK !=
       plugin->create_tables (plugin->cls))
   {
diff --git a/src/exchangedb/exchangedb_auditorkeys.c 
b/src/exchangedb/exchangedb_auditorkeys.c
index 9829441..a84d060 100644
--- a/src/exchangedb/exchangedb_auditorkeys.c
+++ b/src/exchangedb/exchangedb_auditorkeys.c
@@ -1,6 +1,6 @@
 /*
   This file is part of TALER
-  Copyright (C) 2014, 2015, 2016 Inria & GNUnet e.V.
+  Copyright (C) 2014, 2015, 2016, 2017 Inria & GNUnet e.V.
 
   TALER is free software; you can redistribute it and/or modify it under the
   terms of the GNU General Public License as published by the Free Software
@@ -40,6 +40,11 @@ struct AuditorIterateContext
    * Closure for @e it.
    */
   void *it_cls;
+
+  /**
+   * Status of the iteration.
+   */
+  int status;
 };
 
 
@@ -94,6 +99,7 @@ auditor_iter (void *cls,
   const char *auditor_url;
   unsigned int dki_len;
   size_t url_len;
+  int iret;
 
   if (GNUNET_OK != GNUNET_DISK_file_size (filename,
                                           &size,
@@ -160,14 +166,22 @@ auditor_iter (void *cls,
     GNUNET_free (af);
     return GNUNET_OK;
   }
-  /*Ignoring return value to not interrupt the iteration*/
-  aic->it (aic->it_cls,
-           &af->apub,
-           auditor_url,
-           &af->mpub,
-           dki_len,
-           sigs,
-           dki);
+  /* Ignoring return value to not interrupt the iteration */
+  if (GNUNET_OK !=
+      (iret = aic->it (aic->it_cls,
+                      &af->apub,
+                      auditor_url,
+                      &af->mpub,
+                      dki_len,
+                      sigs,
+                      dki)))
+  {
+    GNUNET_free (af);
+    if (GNUNET_SYSERR == iret)
+      aic->status = GNUNET_SYSERR;
+    return GNUNET_SYSERR;
+  }
+  aic->status++;
   GNUNET_free (af);
   return GNUNET_OK;
 }
@@ -201,10 +215,14 @@ TALER_EXCHANGEDB_auditor_iterate (const struct 
GNUNET_CONFIGURATION_Handle *cfg,
     return -1;
   aic.it = it;
   aic.it_cls = it_cls;
+  aic.status = 0;
   ret = GNUNET_DISK_directory_scan (auditor_base_dir,
                                     &auditor_iter,
                                     &aic);
   GNUNET_free (auditor_base_dir);
+  if ( (0 != aic.status) ||
+       (GNUNET_OK == ret) )
+    return aic.status;
   return ret;
 }
 
@@ -280,4 +298,4 @@ TALER_EXCHANGEDB_auditor_write (const char *filename,
 }
 
 
-/* end of exchangedb_keyio.c */
+/* end of exchangedb_auditorkeys.c */
diff --git a/src/exchangedb/plugin_exchangedb_postgres.c 
b/src/exchangedb/plugin_exchangedb_postgres.c
index 8b3fe7f..d39adf2 100644
--- a/src/exchangedb/plugin_exchangedb_postgres.c
+++ b/src/exchangedb/plugin_exchangedb_postgres.c
@@ -174,9 +174,13 @@ postgres_create_tables (void *cls)
                             ",fee_refund_frac INT4 NOT NULL"
                             ",fee_refund_curr 
VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL"
                             ")"),
+    /* index for gc_denominations */
+    GNUNET_PQ_make_try_execute ("CREATE INDEX denominations_expire_legal_index 
ON "
+                                "denominations (expire_legal);"),
+
     /* denomination_revocations table is for remembering which denomination 
keys have been revoked */
     GNUNET_PQ_make_execute ("CREATE TABLE IF NOT EXISTS 
denomination_revocations"
-                            "(denom_revocations_serial_id BIGSERIAL"
+                            "(denom_revocations_serial_id BIGSERIAL UNIQUE"
                             ",denom_pub_hash BYTEA PRIMARY KEY REFERENCES 
denominations (denom_pub_hash) ON DELETE CASCADE"
                             ",master_sig BYTEA NOT NULL CHECK 
(LENGTH(master_sig)=64)"
                             ");"),
@@ -196,13 +200,14 @@ postgres_create_tables (void *cls)
     /* index on reserves table */
     GNUNET_PQ_make_try_execute ("CREATE INDEX reserves_reserve_pub_index ON "
                                 "reserves (reserve_pub);"),
+    /* index for get_expired_reserves */
     GNUNET_PQ_make_try_execute ("CREATE INDEX reserves_expiration_index"
-                                " ON reserves (expiration_date);"),
+                                " ON reserves 
(expiration_date,current_balance_val,current_balance_frac);"),
     /* reserves_in table collects the transactions which transfer funds
        into the reserve.  The rows of this table correspond to each
        incoming transaction. */
     GNUNET_PQ_make_execute("CREATE TABLE IF NOT EXISTS reserves_in"
-                           "(reserve_in_serial_id BIGSERIAL"
+                           "(reserve_in_serial_id BIGSERIAL UNIQUE"
                            ",reserve_pub BYTEA NOT NULL REFERENCES reserves 
(reserve_pub) ON DELETE CASCADE"
                            ",wire_reference BYTEA NOT NULL"
                            ",credit_val INT8 NOT NULL"
@@ -238,9 +243,9 @@ postgres_create_tables (void *cls)
        should fail to even withdraw, as otherwise the coins will fail to 
deposit
        (as they really must be unique). */
     GNUNET_PQ_make_execute ("CREATE TABLE IF NOT EXISTS reserves_out"
-                            "(reserve_out_serial_id BIGSERIAL"
+                            "(reserve_out_serial_id BIGSERIAL UNIQUE"
                             ",h_blind_ev BYTEA PRIMARY KEY"
-                            ",denom_pub_hash BYTEA NOT NULL REFERENCES 
denominations (denom_pub_hash) ON DELETE CASCADE"
+                            ",denom_pub_hash BYTEA NOT NULL REFERENCES 
denominations (denom_pub_hash)" /* do NOT CASCADE on DELETE, we may keep the 
denomination key alive! */
                             ",denom_sig BYTEA NOT NULL"
                             ",reserve_pub BYTEA NOT NULL REFERENCES reserves 
(reserve_pub) ON DELETE CASCADE"
                             ",reserve_sig BYTEA NOT NULL CHECK 
(LENGTH(reserve_sig)=64)"
@@ -270,7 +275,7 @@ postgres_create_tables (void *cls)
      * NOTE: maybe we should instead forbid values >= 2^15 categorically?
      */
     GNUNET_PQ_make_execute("CREATE TABLE IF NOT EXISTS refresh_sessions "
-                           "(melt_serial_id BIGSERIAL"
+                           "(melt_serial_id BIGSERIAL UNIQUE"
                            ",session_hash BYTEA PRIMARY KEY CHECK 
(LENGTH(session_hash)=64)"
                            ",old_coin_pub BYTEA NOT NULL REFERENCES 
known_coins (coin_pub) ON DELETE CASCADE"
                            ",old_coin_sig BYTEA NOT NULL 
CHECK(LENGTH(old_coin_sig)=64)"
@@ -280,6 +285,9 @@ postgres_create_tables (void *cls)
                            ",num_newcoins INT2 NOT NULL"
                            ",noreveal_index INT2 NOT NULL"
                            ");"),
+    GNUNET_PQ_make_try_execute ("CREATE INDEX 
refresh_sessions_old_coin_pub_index ON "
+                                "refresh_sessions (old_coin_pub);"),
+
     /* Table with information about the desired denominations to be created
        during a refresh operation; contains the denomination key for each
        of the coins (for a given refresh session) */
@@ -308,10 +316,8 @@ postgres_create_tables (void *cls)
                            "(session_hash BYTEA NOT NULL REFERENCES 
refresh_sessions (session_hash) ON DELETE CASCADE"
                            ",newcoin_index INT2 NOT NULL"
                            ",coin_ev BYTEA NOT NULL"
-                           ",UNIQUE (session_hash, newcoin_index)"
+                           ",PRIMARY KEY (session_hash, newcoin_index)"
                            ");"),
-    GNUNET_PQ_make_try_execute("CREATE INDEX 
refresh_commit_coin_session_hash_index "
-                               "ON refresh_commit_coin(session_hash, 
newcoin_index)"),
     /* Table with the signatures over coins generated during a refresh
        operation. Needed to answer /refresh/link queries later.  Stores
        the coin signatures under the respective session hash and index. */
@@ -319,10 +325,8 @@ postgres_create_tables (void *cls)
                            "(session_hash BYTEA NOT NULL REFERENCES 
refresh_sessions (session_hash) ON DELETE CASCADE"
                            ",newcoin_index INT2 NOT NULL"
                            ",ev_sig BYTEA NOT NULL"
-                           ",UNIQUE (session_hash, newcoin_index)"
+                           ",PRIMARY KEY (session_hash, newcoin_index)"
                            ");"),
-    GNUNET_PQ_make_try_execute("CREATE INDEX refresh_out_session_hash_index "
-                               "ON refresh_out(session_hash, newcoin_index)"),
     /* This table contains the wire transfers the exchange is supposed to
        execute to transmit funds to the merchants (and manage refunds). */
     GNUNET_PQ_make_execute("CREATE TABLE IF NOT EXISTS deposits "
@@ -346,10 +350,20 @@ postgres_create_tables (void *cls)
     /* Index for get_deposit statement on coin_pub, h_contract_terms and 
merchant_pub */
     GNUNET_PQ_make_try_execute("CREATE INDEX deposits_coin_pub_index "
                                "ON deposits(coin_pub, h_contract_terms, 
merchant_pub)"),
+    /* Index for get_deposit_for_wtid */
+    GNUNET_PQ_make_try_execute("CREATE INDEX 
deposits_coin_pub_merchant_contract_index "
+                               "ON deposits(coin_pub, merchant_pub, 
h_contract_terms)"),
+    /* Index for deposits_get_ready */
+    GNUNET_PQ_make_try_execute("CREATE INDEX deposits_get_ready_index "
+                               "ON 
deposits(tiny,done,wire_deadline,refund_deadline)"),
+    /* Index for deposits_iterate_matching */
+    GNUNET_PQ_make_try_execute("CREATE INDEX deposits_iterate_matching "
+                               "ON 
deposits(merchant_pub,h_wire,done,wire_deadline)"),
+
     /* Table with information about coins that have been refunded. (Technically
        one of the deposit operations that a coin was involved with is 
refunded.)*/
     GNUNET_PQ_make_execute("CREATE TABLE IF NOT EXISTS refunds "
-                           "(refund_serial_id BIGSERIAL"
+                           "(refund_serial_id BIGSERIAL UNIQUE"
                            ",coin_pub BYTEA NOT NULL REFERENCES known_coins 
(coin_pub) ON DELETE CASCADE"
                            ",merchant_pub BYTEA NOT NULL 
CHECK(LENGTH(merchant_pub)=32)"
                            ",merchant_sig BYTEA NOT NULL 
CHECK(LENGTH(merchant_sig)=64)"
@@ -360,6 +374,8 @@ postgres_create_tables (void *cls)
                            ",amount_with_fee_curr 
VARCHAR("TALER_CURRENCY_LEN_STR") NOT NULL"
                            ",PRIMARY KEY (coin_pub, merchant_pub, 
h_contract_terms, rtransaction_id)" /* this combo must be unique, and we 
usually select by coin_pub */
                            ");"),
+    GNUNET_PQ_make_try_execute("CREATE INDEX refunds_coin_pub_index "
+                               "ON refunds(coin_pub)"),
     /* This table contains the data for
        wire transfers the exchange has executed. */
     GNUNET_PQ_make_execute("CREATE TABLE IF NOT EXISTS wire_out "
@@ -374,7 +390,7 @@ postgres_create_tables (void *cls)
     /* Table for the tracking API, mapping from wire transfer identifiers
        to transactions and back */
     GNUNET_PQ_make_execute("CREATE TABLE IF NOT EXISTS aggregation_tracking "
-                           "(aggregation_serial_id BIGSERIAL"
+                           "(aggregation_serial_id BIGSERIAL UNIQUE"
                            ",deposit_serial_id INT8 PRIMARY KEY REFERENCES 
deposits (deposit_serial_id) ON DELETE CASCADE"
                            ",wtid_raw BYTEA  CONSTRAINT wire_out_ref 
REFERENCES wire_out(wtid_raw) ON DELETE CASCADE DEFERRABLE"
                            ");"),
@@ -395,11 +411,13 @@ postgres_create_tables (void *cls)
     /* Index for lookup_transactions statement on wtid */
     GNUNET_PQ_make_try_execute("CREATE INDEX aggregation_tracking_wtid_index "
                                "ON aggregation_tracking(wtid_raw);"),
+    /* Index for gc_wire_fee */
+    GNUNET_PQ_make_try_execute("CREATE INDEX wire_fee_gc_index "
+                               "ON wire_fee(end_date);"),
     /* Table for /payback information */
     GNUNET_PQ_make_execute("CREATE TABLE IF NOT EXISTS payback "
-                           "(payback_uuid BIGSERIAL"
-                           ",reserve_pub BYTEA NOT NULL REFERENCES reserves 
(reserve_pub) ON DELETE CASCADE"
-                           ",coin_pub BYTEA NOT NULL REFERENCES known_coins 
(coin_pub) ON DELETE CASCADE"
+                           "(payback_uuid BIGSERIAL UNIQUE"
+                           ",coin_pub BYTEA NOT NULL REFERENCES known_coins 
(coin_pub)" /* do NOT CASCADE on delete, we may keep the coin alive! */
                            ",coin_sig BYTEA NOT NULL 
CHECK(LENGTH(coin_sig)=64)"
                            ",coin_blind BYTEA NOT NULL 
CHECK(LENGTH(coin_blind)=32)"
                            ",amount_val INT8 NOT NULL"
@@ -421,9 +439,9 @@ postgres_create_tables (void *cls)
                            ",finished BOOLEAN NOT NULL DEFAULT false"
                            ",buf BYTEA NOT NULL"
                            ");"),
-    /* Index for prepare_data_iterate statement */
+    /* Index for wire_prepare_data_get and gc_prewire statement */
     GNUNET_PQ_make_try_execute("CREATE INDEX prepare_iteration_index "
-                               "ON prewire(type,finished);"),
+                               "ON prewire(finished);"),
     GNUNET_PQ_EXECUTE_STATEMENT_END
   };
   PGconn *conn;
@@ -505,7 +523,7 @@ postgres_prepare (PGconn *db_conn)
                             ",fee_refund_frac"
                             ",fee_refund_curr" /* must match coin_curr */
                             " FROM denominations"
-                            " WHERE denom_pub=$1;",
+                            " WHERE denom_pub_hash=$1;",
                             1),
     /* Used in #postgres_insert_denomination_revocation() */
     GNUNET_PQ_make_prepare ("denomination_revocation_insert",
@@ -567,10 +585,11 @@ postgres_prepare (PGconn *db_conn)
                             "UPDATE reserves"
                             " SET"
                             " expiration_date=$1 "
-                            ",current_balance_val=$2 "
+                            ",current_balance_val=$2"
                             ",current_balance_frac=$3"
-                            " WHERE current_balance_curr=$4"
-                            " AND reserve_pub=$5;",
+                           ",current_balance_curr=$4"
+                            " WHERE"
+                            " reserve_pub=$5;",
                             5),
     /* Used in #postgres_reserves_in_insert() to store transaction details */
     GNUNET_PQ_make_prepare ("reserves_in_add_transaction",
@@ -896,7 +915,8 @@ postgres_prepare (PGconn *db_conn)
                             "SELECT"
                             " coin_ev"
                             " FROM refresh_commit_coin"
-                            " WHERE session_hash=$1 AND newcoin_index=$2;",
+                            " WHERE session_hash=$1"
+                           " AND newcoin_index=$2;",
                             2),
     /* Store information about a /deposit the exchange is to execute.
        Used in #postgres_insert_deposit(). */
@@ -1147,7 +1167,9 @@ postgres_prepare (PGconn *db_conn)
        NOTE: This may (in theory) return multiple results, one per session
        that the old coin was melted into. */
     GNUNET_PQ_make_prepare ("get_transfer",
-                            "SELECT transfer_pub,session_hash"
+                            "SELECT"
+                           " transfer_pub"
+                           ",session_hash"
                             " FROM refresh_sessions rs"
                             "     JOIN refresh_transfer_public_key rcl"
                             "       USING (session_hash)"
@@ -1278,6 +1300,29 @@ postgres_prepare (PGconn *db_conn)
                             " ORDER BY prewire_uuid ASC"
                             " LIMIT 1;",
                             0),
+    /* Used in #postgres_select_deposits_missing_wire */
+    GNUNET_PQ_make_prepare ("deposits_get_overdue",
+                           "SELECT"
+                           " deposit_serial_id"
+                           ",coin_pub"
+                           ",amount_with_fee_val"
+                           ",amount_with_fee_frac"
+                           ",amount_with_fee_curr"
+                           ",wire"
+                           ",wire_deadline"
+                           ",tiny"
+                           ",done"
+                           " FROM deposits"
+                           " WHERE wire_deadline <= $1"
+                           " AND wire_deadline > $2" 
+                           " AND NOT (EXISTS (SELECT 1"
+                           "            FROM refunds"
+                           "            WHERE (refunds.coin_pub = 
deposits.coin_pub))"
+                           "       OR EXISTS (SELECT 1"
+                           "            FROM aggregation_tracking"
+                           "            WHERE 
(aggregation_tracking.deposit_serial_id = deposits.deposit_serial_id)))"
+                           " ORDER BY wire_deadline ASC",
+                           2),
     /* Used in #postgres_gc() */
     GNUNET_PQ_make_prepare ("gc_prewire",
                             "DELETE"
@@ -1302,8 +1347,7 @@ postgres_prepare (PGconn *db_conn)
        information */
     GNUNET_PQ_make_prepare ("payback_insert",
                             "INSERT INTO payback "
-                            "(reserve_pub"
-                            ",coin_pub"
+                            "(coin_pub"
                             ",coin_sig"
                             ",coin_blind"
                             ",amount_val"
@@ -1312,14 +1356,14 @@ postgres_prepare (PGconn *db_conn)
                             ",timestamp"
                             ",h_blind_ev"
                             ") VALUES "
-                            "($1, $2, $3, $4, $5, $6, $7, $8, $9);",
-                            9),
+                            "($1, $2, $3, $4, $5, $6, $7, $8);",
+                            8),
     /* Used in #postgres_select_payback_above_serial_id() to obtain payback 
transactions */
     GNUNET_PQ_make_prepare ("payback_get_incr",
                             "SELECT"
                             " payback_uuid"
                             ",timestamp"
-                            ",reserve_pub"
+                            ",ro.reserve_pub"
                             ",coin_pub"
                             ",coin_sig"
                             ",coin_blind"
@@ -1334,6 +1378,8 @@ postgres_prepare (PGconn *db_conn)
                             "      USING (coin_pub)"
                             "    JOIN denominations denoms"
                             "      USING (denom_pub_hash)"
+                            "    JOIN reserves_out ro"
+                            "      USING (h_blind_ev)"
                             " WHERE payback_uuid>=$1"
                             " ORDER BY payback_uuid ASC;",
                             1),
@@ -1374,7 +1420,9 @@ postgres_prepare (PGconn *db_conn)
                             "      USING (coin_pub)"
                             "    JOIN denominations denoms"
                             "      USING (denom_pub_hash)"
-                            " WHERE payback.reserve_pub=$1;",
+                            "    JOIN reserves_out ro"
+                            "      USING (h_blind_ev)"
+                            " WHERE ro.reserve_pub=$1;",
                             1),
     /* Used in #postgres_get_reserve_history() */
     GNUNET_PQ_make_prepare ("close_by_reserve",
@@ -1411,7 +1459,7 @@ postgres_prepare (PGconn *db_conn)
        for a coin */
     GNUNET_PQ_make_prepare ("payback_by_coin",
                             "SELECT"
-                            " payback.reserve_pub"
+                            " ro.reserve_pub"
                             ",coin_sig"
                             ",coin_blind"
                             ",amount_val"
@@ -1420,12 +1468,13 @@ postgres_prepare (PGconn *db_conn)
                             ",timestamp"
                             ",denoms.denom_pub"
                             ",coins.denom_sig"
-
                             " FROM payback"
                             "    JOIN known_coins coins"
                             "      USING (coin_pub)"
                             "    JOIN denominations denoms"
                             "      USING (denom_pub_hash)"
+                            "    JOIN reserves_out ro"
+                            "      USING (h_blind_ev)"
                             " WHERE payback.coin_pub=$1;",
                             1),
     /* Used in #postgres_get_reserve_by_h_blind() */
@@ -1452,6 +1501,11 @@ postgres_prepare (PGconn *db_conn)
                             "   AND current_balance_val = 0"
                             "   AND current_balance_frac = 0;",
                             1),
+    GNUNET_PQ_make_prepare ("gc_wire_fee",
+                            "DELETE"
+                            " FROM wire_fee"
+                            " WHERE end_date < $1;",
+                            1),
     GNUNET_PQ_PREPARED_STATEMENT_END
   };
 
@@ -1679,8 +1733,9 @@ postgres_get_denomination_info (void *cls,
                                 struct 
TALER_EXCHANGEDB_DenominationKeyInformationP *issue)
 {
   enum GNUNET_DB_QueryStatus qs;
+  struct GNUNET_HashCode dph;
   struct GNUNET_PQ_QueryParam params[] = {
-    GNUNET_PQ_query_param_rsa_public_key (denom_pub->rsa_public_key),
+    GNUNET_PQ_query_param_auto_from_type (&dph),
     GNUNET_PQ_query_param_end
   };
   struct GNUNET_PQ_ResultSpec rs[] = {
@@ -1709,6 +1764,8 @@ postgres_get_denomination_info (void *cls,
     GNUNET_PQ_result_spec_end
   };
 
+  GNUNET_CRYPTO_rsa_public_key_hash (denom_pub->rsa_public_key,
+                                    &dph);
   qs = GNUNET_PQ_eval_prepared_singleton_select (session->conn,
                                                 "denomination_get",
                                                 params,
@@ -1906,7 +1963,7 @@ postgres_reserves_in_insert (void *cls,
        back for duplicate transactions; like this, we should virtually
        never actually have to rollback anything. */
     struct TALER_EXCHANGEDB_Reserve updated_reserve;
-    
+
     updated_reserve.pub = reserve.pub;
     if (GNUNET_OK !=
         TALER_amount_add (&updated_reserve.balance,
@@ -2101,14 +2158,14 @@ struct ReserveHistoryContext
 
   /**
    * Which reserve are we building the history for?
-   */ 
+   */
   const struct TALER_ReservePublicKeyP *reserve_pub;
-  
+
   /**
    * Where we build the history.
    */
   struct TALER_EXCHANGEDB_ReserveHistory *rh;
- 
+
   /**
    * Tail of @e rh list.
    */
@@ -2117,7 +2174,7 @@ struct ReserveHistoryContext
   /**
    * Set to #GNUNET_SYSERR on serious internal errors during
    * the callbacks.
-   */ 
+   */
   int status;
 };
 
@@ -2128,7 +2185,7 @@ struct ReserveHistoryContext
  *
  * @param rhc where the history is kept
  * @return the fresh element that was added
- */ 
+ */
 static struct TALER_EXCHANGEDB_ReserveHistory *
 append_rh (struct ReserveHistoryContext *rhc)
 {
@@ -2162,7 +2219,7 @@ add_bank_to_exchange (void *cls,
                      unsigned int num_results)
 {
   struct ReserveHistoryContext *rhc = cls;
-  
+
   while (0 < num_results)
   {
     struct TALER_EXCHANGEDB_BankTransfer *bt;
@@ -2182,7 +2239,7 @@ add_bank_to_exchange (void *cls,
                                   &bt->sender_account_details),
        GNUNET_PQ_result_spec_end
       };
-      
+
       if (GNUNET_OK !=
          GNUNET_PQ_extract_result (result,
                                    rs,
@@ -2215,7 +2272,7 @@ add_withdraw_coin (void *cls,
                   unsigned int num_results)
 {
   struct ReserveHistoryContext *rhc = cls;
-  
+
   while (0 < num_results)
   {
     struct TALER_EXCHANGEDB_CollectableBlindcoin *cbc;
@@ -2238,7 +2295,7 @@ add_withdraw_coin (void *cls,
                                     &cbc->withdraw_fee),
        GNUNET_PQ_result_spec_end
       };
-      
+
       if (GNUNET_OK !=
          GNUNET_PQ_extract_result (result,
                                    rs,
@@ -2267,11 +2324,11 @@ add_withdraw_coin (void *cls,
  */
 static void
 add_payback (void *cls,
-                  PGresult *result,
-                  unsigned int num_results)
+            PGresult *result,
+            unsigned int num_results)
 {
   struct ReserveHistoryContext *rhc = cls;
-  
+
   while (0 < num_results)
   {
     struct TALER_EXCHANGEDB_Payback *payback;
@@ -2296,7 +2353,7 @@ add_payback (void *cls,
                                             
&payback->coin.denom_sig.rsa_signature),
        GNUNET_PQ_result_spec_end
       };
-      
+
       if (GNUNET_OK !=
          GNUNET_PQ_extract_result (result,
                                    rs,
@@ -2330,12 +2387,12 @@ add_exchange_to_bank (void *cls,
                      unsigned int num_results)
 {
   struct ReserveHistoryContext *rhc = cls;
-  
+
   while (0 < num_results)
   {
     struct TALER_EXCHANGEDB_ClosingTransfer *closing;
     struct TALER_EXCHANGEDB_ReserveHistory *tail;
-      
+
     closing = GNUNET_new (struct TALER_EXCHANGEDB_ClosingTransfer);
     {
       struct GNUNET_PQ_ResultSpec rs[] = {
@@ -2351,7 +2408,7 @@ add_exchange_to_bank (void *cls,
                                              &closing->wtid),
        GNUNET_PQ_result_spec_end
       };
-      
+
       if (GNUNET_OK !=
          GNUNET_PQ_extract_result (result,
                                    rs,
@@ -2424,6 +2481,7 @@ postgres_get_reserve_history (void *cls,
   rhc.rh = NULL;
   rhc.rh_tail = NULL;
   rhc.status = GNUNET_OK;
+  qs = GNUNET_DB_STATUS_SUCCESS_NO_RESULTS; /* make static analysis happy */
   for (unsigned int i=0;NULL != work[i].cb;i++)
   {
     qs = GNUNET_PQ_eval_prepared_multi_select (session->conn,
@@ -2447,7 +2505,7 @@ postgres_get_reserve_history (void *cls,
       qs = GNUNET_DB_STATUS_HARD_ERROR;
     }
   }
-  *rhp = rhc.rh;  
+  *rhp = rhc.rh;
   return qs;
 }
 
@@ -2670,6 +2728,11 @@ postgres_get_ready_deposit (void *cls,
   };
   enum GNUNET_DB_QueryStatus qs;
 
+  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+             "Finding ready deposits by deadline %s (%llu)\n",
+             GNUNET_STRINGS_absolute_time_to_string (now),
+             (unsigned long long) now.abs_value_us);
+
   qs = GNUNET_PQ_eval_prepared_singleton_select (session->conn,
                                                 "deposits_get_ready",
                                                 params,
@@ -2709,7 +2772,7 @@ struct MatchingDepositContext
    * Public key of the merchant against which we are matching.
    */
   const struct TALER_MerchantPublicKeyP *merchant_pub;
-  
+
   /**
    * Maximum number of results to return.
    */
@@ -2742,7 +2805,7 @@ match_deposit_cb (void *cls,
                  unsigned int num_results)
 {
   struct MatchingDepositContext *mdc = cls;
-  
+
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Found %u/%u matching deposits\n",
              num_results,
@@ -2773,7 +2836,7 @@ match_deposit_cb (void *cls,
                                             &coin_pub),
       GNUNET_PQ_result_spec_end
     };
-    
+
     if (GNUNET_OK !=
         GNUNET_PQ_extract_result (result,
                                   rs,
@@ -2877,7 +2940,7 @@ get_known_coin (void *cls,
                                         &coin_info->denom_sig.rsa_signature),
     GNUNET_PQ_result_spec_end
   };
-  
+
   coin_info->coin_pub = *coin_pub;
   return GNUNET_PQ_eval_prepared_singleton_select (session->conn,
                                                   "get_known_coin",
@@ -2924,7 +2987,7 @@ insert_known_coin (void *cls,
  * @param session database session
  * @param coin the coin that must be made known
  * @return database transaction status, non-negative on success
- */ 
+ */
 static enum GNUNET_DB_QueryStatus
 ensure_coin_known (struct PostgresClosure *cls,
                   struct TALER_EXCHANGEDB_Session *session,
@@ -2993,6 +3056,11 @@ postgres_insert_deposit (void *cls,
                                   session,
                                   &deposit->coin)))
     return qs;
+  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+             "Inserting deposit to be executed at %s (%llu/%llu)\n",
+             GNUNET_STRINGS_absolute_time_to_string (deposit->wire_deadline),
+             (unsigned long long) deposit->wire_deadline.abs_value_us,
+             (unsigned long long) deposit->refund_deadline.abs_value_us);
   return GNUNET_PQ_eval_prepared_non_select (session->conn,
                                             "insert_deposit",
                                             params);
@@ -3206,7 +3274,7 @@ postgres_get_refresh_order (void *cls,
                             const struct GNUNET_HashCode *session_hash,
                             uint16_t num_newcoins,
                             struct TALER_DenominationPublicKey *denom_pubs)
-{ 
+{
   for (unsigned i=0;i<(unsigned int) num_newcoins;i++)
   {
     uint16_t newcoin_off = (uint16_t) i;
@@ -3221,7 +3289,7 @@ postgres_get_refresh_order (void *cls,
                                            &denom_pubs[i].rsa_public_key),
       GNUNET_PQ_result_spec_end
     };
-    
+
     qs = GNUNET_PQ_eval_prepared_singleton_select (session->conn,
                                                   "get_refresh_order",
                                                   params,
@@ -3412,7 +3480,7 @@ postgres_get_refresh_transfer_public_key (void *cls,
                                          tp),
     GNUNET_PQ_result_spec_end
   };
-  
+
   return GNUNET_PQ_eval_prepared_singleton_select (session->conn,
                                                   
"get_refresh_transfer_public_key",
                                                   params,
@@ -3495,9 +3563,9 @@ postgres_insert_refresh_out (void *cls,
  */
 struct LinkDataContext
 {
-  /** 
+  /**
    * List we are building.
-   */ 
+   */
   struct TALER_EXCHANGEDB_LinkDataList *ldl;
 
   /**
@@ -3521,7 +3589,7 @@ add_ldl (void *cls,
         unsigned int num_results)
 {
   struct LinkDataContext *ldc = cls;
-  
+
   for (int i = num_results - 1; i >= 0; i--)
   {
     struct GNUNET_CRYPTO_RsaPublicKey *denom_pub;
@@ -3725,10 +3793,10 @@ struct CoinHistoryContext
    * Database session we are using.
    */
   struct TALER_EXCHANGEDB_Session *session;
-  
+
   /**
    * Set to transaction status.
-   */ 
+   */
   enum GNUNET_DB_QueryStatus status;
 };
 
@@ -3753,7 +3821,7 @@ add_coin_deposit (void *cls,
     struct TALER_EXCHANGEDB_Deposit *deposit;
     struct TALER_EXCHANGEDB_TransactionList *tl;
     enum GNUNET_DB_QueryStatus qs;
-    
+
     deposit = GNUNET_new (struct TALER_EXCHANGEDB_Deposit);
     {
       struct GNUNET_PQ_ResultSpec rs[] = {
@@ -3777,7 +3845,7 @@ add_coin_deposit (void *cls,
                                              &deposit->csig),
        GNUNET_PQ_result_spec_end
       };
-      
+
       if (GNUNET_OK !=
          GNUNET_PQ_extract_result (result,
                                    rs,
@@ -3845,7 +3913,7 @@ add_coin_melt (void *cls,
                                     &melt->melt_fee),
        GNUNET_PQ_result_spec_end
       };
-      
+
       if (GNUNET_OK !=
          GNUNET_PQ_extract_result (result,
                                    rs,
@@ -3916,7 +3984,7 @@ add_coin_refund (void *cls,
                                     &refund->refund_fee),
        GNUNET_PQ_result_spec_end
       };
-      
+
       if (GNUNET_OK !=
          GNUNET_PQ_extract_result (result,
                                    rs,
@@ -3968,7 +4036,7 @@ add_coin_payback (void *cls,
   {
     struct TALER_EXCHANGEDB_Payback *payback;
     struct TALER_EXCHANGEDB_TransactionList *tl;
-    
+
     payback = GNUNET_new (struct TALER_EXCHANGEDB_Payback);
     {
       struct GNUNET_PQ_ResultSpec rs[] = {
@@ -3988,7 +4056,7 @@ add_coin_payback (void *cls,
                                             
&payback->coin.denom_sig.rsa_signature),
        GNUNET_PQ_result_spec_end
       };
-      
+
       if (GNUNET_OK !=
          GNUNET_PQ_extract_result (result,
                                    rs,
@@ -4126,7 +4194,7 @@ handle_wt_result (void *cls,
                  unsigned int num_results)
 {
   struct WireTransferResultContext *ctx = cls;
-  
+
   for (unsigned int i=0;i<num_results;i++)
   {
     uint64_t rowid;
@@ -4215,7 +4283,7 @@ postgres_lookup_wire_transfer (void *cls,
   };
   struct WireTransferResultContext ctx;
   enum GNUNET_DB_QueryStatus qs;
-  
+
   ctx.cb = cb;
   ctx.cb_cls = cb_cls;
   ctx.status = GNUNET_OK;
@@ -4275,7 +4343,7 @@ postgres_wire_lookup_deposit_wtid (void *cls,
     TALER_PQ_result_spec_amount ("fee_deposit", &deposit_fee),
     GNUNET_PQ_result_spec_end
   };
-  
+
   /* check if the melt record exists and get it */
   qs = GNUNET_PQ_eval_prepared_singleton_select (session->conn,
                                                 "lookup_deposit_wtid",
@@ -4587,7 +4655,7 @@ postgres_get_expired_reserves (void *cls,
   };
   struct ExpiredReserveContext ectx;
   enum GNUNET_DB_QueryStatus qs;
-  
+
   ectx.rec = rec;
   ectx.rec_cls = rec_cls;
   ectx.status = GNUNET_OK;
@@ -4873,6 +4941,7 @@ postgres_gc (void *cls)
 {
   struct PostgresClosure *pc = cls;
   struct GNUNET_TIME_Absolute now;
+  struct GNUNET_TIME_Absolute long_ago;
   struct GNUNET_PQ_QueryParam params_none[] = {
     GNUNET_PQ_query_param_end
   };
@@ -4880,26 +4949,46 @@ postgres_gc (void *cls)
     GNUNET_PQ_query_param_absolute_time (&now),
     GNUNET_PQ_query_param_end
   };
+  struct GNUNET_PQ_QueryParam params_ancient_time[] = {
+    GNUNET_PQ_query_param_absolute_time (&long_ago),
+    GNUNET_PQ_query_param_end
+  };
   PGconn *conn;
   int ret;
-  
+
   now = GNUNET_TIME_absolute_get ();
+  /* Keep wire fees for 10 years, that should always
+     be enough _and_ they are tiny so it does not
+     matter to make this tight */
+  long_ago = GNUNET_TIME_absolute_subtract (now,
+                                           GNUNET_TIME_relative_multiply 
(GNUNET_TIME_UNIT_YEARS,
+                                                                          10));
   conn = GNUNET_PQ_connect (pc->connection_cfg_str);
   if (NULL == conn)
     return GNUNET_SYSERR;
   ret = postgres_prepare (conn);
   if (GNUNET_OK == ret)
   {
-    if ( (0 > GNUNET_PQ_eval_prepared_non_select (conn,
-                                                 "gc_prewire",
-                                                 params_none)) ||
+    if (
         (0 > GNUNET_PQ_eval_prepared_non_select (conn,
-                                                 "gc_denominations",
+                                                 "gc_reserves",
                                                  params_time)) ||
         (0 > GNUNET_PQ_eval_prepared_non_select (conn,
-                                                 "gc_reserves",
-                                                 params_time)) )
+                                                 "gc_prewire",
+                                                 params_none)) ||
+        (0 > GNUNET_PQ_eval_prepared_non_select (conn,
+                                                 "gc_wire_fee",
+                                                 params_ancient_time))
+       )
       ret = GNUNET_SYSERR;
+    /* This one may fail due to foreign key constraints from
+       payback and reserves_out tables to known_coins; these
+       are NOT using 'ON DROP CASCADE' and might keep denomination
+       keys alive for a bit longer, thus causing this statement
+       to fail. */
+    (void) GNUNET_PQ_eval_prepared_non_select (conn,
+                                              "gc_denominations",
+                                              params_time);
   }
   PQfinish (conn);
   return ret;
@@ -4916,15 +5005,15 @@ struct DepositSerialContext
    * Callback to call.
    */
   TALER_EXCHANGEDB_DepositCallback cb;
-  
+
   /**
    * Closure for @e cb.
    */
   void *cb_cls;
-  
+
   /**
    * Status code, set to #GNUNET_SYSERR on hard errors.
-   */ 
+   */
   int status;
 };
 
@@ -4943,7 +5032,7 @@ deposit_serial_helper_cb (void *cls,
                          unsigned int num_results)
 {
   struct DepositSerialContext *dsc = cls;
-  
+
   for (unsigned int i=0;i<num_results;i++)
   {
     struct TALER_EXCHANGEDB_Deposit deposit;
@@ -4978,7 +5067,7 @@ deposit_serial_helper_cb (void *cls,
       GNUNET_PQ_result_spec_end
     };
     int ret;
-    
+
     if (GNUNET_OK !=
         GNUNET_PQ_extract_result (result,
                                   rs,
@@ -5058,15 +5147,15 @@ struct RefreshsSerialContext
    * Callback to call.
    */
   TALER_EXCHANGEDB_RefreshSessionCallback cb;
-  
+
   /**
    * Closure for @e cb.
    */
   void *cb_cls;
-  
+
   /**
    * Status code, set to #GNUNET_SYSERR on hard errors.
-   */ 
+   */
   int status;
 };
 
@@ -5085,7 +5174,7 @@ refreshs_serial_helper_cb (void *cls,
                           unsigned int num_results)
 {
   struct RefreshsSerialContext *rsc = cls;
-  
+
   for (unsigned int i=0;i<num_results;i++)
   {
     struct TALER_DenominationPublicKey denom_pub;
@@ -5192,15 +5281,15 @@ struct RefundsSerialContext
    * Callback to call.
    */
   TALER_EXCHANGEDB_RefundCallback cb;
-  
+
   /**
    * Closure for @e cb.
    */
   void *cb_cls;
-  
+
   /**
    * Status code, set to #GNUNET_SYSERR on hard errors.
-   */ 
+   */
   int status;
 };
 
@@ -5219,7 +5308,7 @@ refunds_serial_helper_cb (void *cls,
                          unsigned int num_results)
 {
   struct RefundsSerialContext *rsc = cls;
-  
+
   for (unsigned int i=0;i<num_results;i++)
   {
     struct TALER_EXCHANGEDB_Refund refund;
@@ -5245,7 +5334,7 @@ refunds_serial_helper_cb (void *cls,
       GNUNET_PQ_result_spec_end
     };
     int ret;
-    
+
     if (GNUNET_OK !=
         GNUNET_PQ_extract_result (result,
                                   rs,
@@ -5321,15 +5410,15 @@ struct ReservesInSerialContext
    * Callback to call.
    */
   TALER_EXCHANGEDB_ReserveInCallback cb;
-  
+
   /**
    * Closure for @e cb.
    */
   void *cb_cls;
-  
+
   /**
    * Status code, set to #GNUNET_SYSERR on hard errors.
-   */ 
+   */
   int status;
 };
 
@@ -5428,7 +5517,7 @@ postgres_select_reserves_in_above_serial_id (void *cls,
     .status = GNUNET_OK
   };
   enum GNUNET_DB_QueryStatus qs;
-  
+
   qs = GNUNET_PQ_eval_prepared_multi_select (session->conn,
                                             
"audit_reserves_in_get_transactions_incr",
                                             params,
@@ -5450,15 +5539,15 @@ struct ReservesOutSerialContext
    * Callback to call.
    */
   TALER_EXCHANGEDB_WithdrawCallback cb;
-  
+
   /**
    * Closure for @e cb.
    */
   void *cb_cls;
-  
+
   /**
    * Status code, set to #GNUNET_SYSERR on hard errors.
-   */ 
+   */
   int status;
 };
 
@@ -5477,7 +5566,7 @@ reserves_out_serial_helper_cb (void *cls,
                               unsigned int num_results)
 {
   struct ReservesOutSerialContext *rosc = cls;
-  
+
   for (unsigned int i=0;i<num_results;i++)
   {
     struct GNUNET_HashCode h_blind_ev;
@@ -5508,7 +5597,7 @@ reserves_out_serial_helper_cb (void *cls,
       GNUNET_PQ_result_spec_end
     };
     int ret;
-    
+
     if (GNUNET_OK !=
         GNUNET_PQ_extract_result (result,
                                   rs,
@@ -5584,15 +5673,15 @@ struct WireOutSerialContext
    * Callback to call.
    */
   TALER_EXCHANGEDB_WireTransferOutCallback cb;
-  
+
   /**
    * Closure for @e cb.
    */
   void *cb_cls;
-  
+
   /**
    * Status code, set to #GNUNET_SYSERR on hard errors.
-   */ 
+   */
   int status;
 };
 
@@ -5611,7 +5700,7 @@ wire_out_serial_helper_cb (void *cls,
                           unsigned int num_results)
 {
   struct WireOutSerialContext *wosc = cls;
-  
+
   for (unsigned int i=0;i<num_results;i++)
   {
     uint64_t rowid;
@@ -5706,15 +5795,15 @@ struct PaybackSerialContext
    * Callback to call.
    */
   TALER_EXCHANGEDB_PaybackCallback cb;
-  
+
   /**
    * Closure for @e cb.
    */
   void *cb_cls;
-  
+
   /**
    * Status code, set to #GNUNET_SYSERR on hard errors.
-   */ 
+   */
   int status;
 };
 
@@ -5733,7 +5822,7 @@ payback_serial_helper_cb (void *cls,
                          unsigned int num_results)
 {
   struct PaybackSerialContext *psc = cls;
-  
+
   for (unsigned int i=0;i<num_results;i++)
   {
     uint64_t rowid;
@@ -5821,7 +5910,7 @@ postgres_select_payback_above_serial_id (void *cls,
     .status = GNUNET_OK
   };
   enum GNUNET_DB_QueryStatus qs;
-  
+
   qs = GNUNET_PQ_eval_prepared_multi_select (session->conn,
                                             "payback_get_incr",
                                             params,
@@ -5843,15 +5932,15 @@ struct ReserveClosedSerialContext
    * Callback to call.
    */
   TALER_EXCHANGEDB_ReserveClosedCallback cb;
-  
+
   /**
    * Closure for @e cb.
    */
   void *cb_cls;
-  
+
   /**
    * Status code, set to #GNUNET_SYSERR on hard errors.
-   */ 
+   */
   int status;
 };
 
@@ -5870,7 +5959,7 @@ reserve_closed_serial_helper_cb (void *cls,
                                 unsigned int num_results)
 {
   struct ReserveClosedSerialContext *rcsc = cls;
-  
+
   for (unsigned int i=0;i<num_results;i++)
   {
     uint64_t rowid;
@@ -5951,7 +6040,7 @@ postgres_select_reserve_closed_above_serial_id (void *cls,
     .status = GNUNET_OK
   };
   enum GNUNET_DB_QueryStatus qs;
-  
+
   qs = GNUNET_PQ_eval_prepared_multi_select (session->conn,
                                             "reserves_close_get_incr",
                                             params,
@@ -5995,7 +6084,6 @@ postgres_insert_payback_request (void *cls,
   struct GNUNET_TIME_Absolute expiry;
   struct TALER_EXCHANGEDB_Reserve reserve;
   struct GNUNET_PQ_QueryParam params[] = {
-    GNUNET_PQ_query_param_auto_from_type (reserve_pub),
     GNUNET_PQ_query_param_auto_from_type (&coin->coin_pub),
     GNUNET_PQ_query_param_auto_from_type (coin_sig),
     GNUNET_PQ_query_param_auto_from_type (coin_blind),
@@ -6152,6 +6240,135 @@ postgres_get_denomination_revocation (void *cls,
 
 
 /**
+ * Closure for #missing_wire_cb().
+ */
+struct MissingWireContext
+{
+  /**
+   * Function to call per result.
+   */
+  TALER_EXCHANGEDB_WireMissingCallback cb;
+
+  /**
+   * Closure for @e cb.
+   */
+  void *cb_cls;
+
+  /**
+   * Set to #GNUNET_SYSERR on error.
+   */
+  int status;
+};
+
+
+/**
+ * Invoke the callback for each result.
+ *
+ * @param cls a `struct MissingWireContext *`
+ * @param result SQL result
+ * @param num_results number of rows in @a result
+ */
+static void
+missing_wire_cb (void *cls,
+                PGresult *result,
+                unsigned int num_results)
+{
+  struct MissingWireContext *mwc = cls;
+
+  while (0 < num_results)
+  {
+    uint64_t rowid;
+    struct TALER_CoinSpendPublicKeyP coin_pub;
+    struct TALER_Amount amount;
+    json_t *wire;
+    struct GNUNET_TIME_Absolute deadline;
+    /* bool? */ uint32_t tiny;
+    /* bool? */ uint32_t done;
+    struct GNUNET_PQ_ResultSpec rs[] = {
+      GNUNET_PQ_result_spec_uint64 ("deposit_serial_id",
+                                   &rowid),
+      GNUNET_PQ_result_spec_auto_from_type ("coin_pub",
+                                           &coin_pub),
+      TALER_PQ_result_spec_amount ("amount_with_fee",
+                                  &amount),
+      TALER_PQ_result_spec_json ("wire",
+                                &wire),
+      GNUNET_PQ_result_spec_absolute_time ("wire_deadline",
+                                          &deadline),
+      GNUNET_PQ_result_spec_uint32 ("tiny",
+                                   &tiny),
+      GNUNET_PQ_result_spec_uint32 ("done",
+                                   &done),
+      GNUNET_PQ_result_spec_end
+    };
+
+    if (GNUNET_OK !=
+       GNUNET_PQ_extract_result (result,
+                                 rs,
+                                 --num_results))
+    {
+      GNUNET_break (0);
+      mwc->status = GNUNET_SYSERR;
+      return;
+    }
+    mwc->cb (mwc->cb_cls,
+            rowid,
+            &coin_pub,
+            &amount,
+            wire,
+            deadline,
+            tiny,
+            done);
+    GNUNET_PQ_cleanup_result (rs);
+  }
+}
+
+
+/**
+ * Select all of those deposits in the database for which we do
+ * not have a wire transfer (or a refund) and which should have
+ * been deposited between @a start_date and @a end_date.
+ *
+ * @param cls closure
+ * @param session a session
+ * @param start_date lower bound on the requested wire execution date
+ * @param end_date upper bound on the requested wire execution date
+ * @param cb function to call on all such deposits
+ * @param cb_cls closure for @a cb
+ * @return transaction status code
+ */
+static enum GNUNET_DB_QueryStatus
+postgres_select_deposits_missing_wire (void *cls,
+                                      struct TALER_EXCHANGEDB_Session *session,
+                                      struct GNUNET_TIME_Absolute start_date,
+                                      struct GNUNET_TIME_Absolute end_date,
+                                      TALER_EXCHANGEDB_WireMissingCallback cb,
+                                      void *cb_cls)
+{
+  struct GNUNET_PQ_QueryParam params[] = {
+    GNUNET_PQ_query_param_absolute_time (&start_date),
+    GNUNET_PQ_query_param_absolute_time (&end_date),
+    GNUNET_PQ_query_param_end
+  };
+  struct MissingWireContext mwc = {
+    .cb = cb,
+    .cb_cls = cb_cls,
+    .status = GNUNET_OK
+  };
+  enum GNUNET_DB_QueryStatus qs;
+
+  qs = GNUNET_PQ_eval_prepared_multi_select (session->conn,
+                                            "deposits_get_overdue",
+                                            params,
+                                            &missing_wire_cb,
+                                            &mwc);
+  if (GNUNET_OK != mwc.status)
+    return GNUNET_DB_STATUS_HARD_ERROR;
+  return qs;
+}
+
+
+/**
  * Initialize Postgres database subsystem.
  *
  * @param cls a configuration instance
@@ -6272,6 +6489,7 @@ libtaler_plugin_exchangedb_postgres_init (void *cls)
   plugin->get_reserve_by_h_blind = &postgres_get_reserve_by_h_blind;
   plugin->insert_denomination_revocation = 
&postgres_insert_denomination_revocation;
   plugin->get_denomination_revocation = &postgres_get_denomination_revocation;
+  plugin->select_deposits_missing_wire = 
&postgres_select_deposits_missing_wire;
   return plugin;
 }
 
diff --git a/src/exchangedb/test_exchangedb.c b/src/exchangedb/test_exchangedb.c
index 6b89577..537f33c 100644
--- a/src/exchangedb/test_exchangedb.c
+++ b/src/exchangedb/test_exchangedb.c
@@ -551,6 +551,7 @@ test_melting (struct TALER_EXCHANGEDB_Session *session)
                                &fee_deposit,
                                &fee_refresh,
                               &fee_refund);
+  GNUNET_assert (NULL != dkp);
   /* initialize refresh session melt data */
   {
     struct GNUNET_HashCode hc;
@@ -633,6 +634,7 @@ test_melting (struct TALER_EXCHANGEDB_Session *session)
                                           &fee_deposit,
                                           &fee_refresh,
                                          &fee_refund);
+    GNUNET_assert (NULL != new_dkp[cnt]);
     new_denom_pubs[cnt] = new_dkp[cnt]->pub;
   }
   FAILIF (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT !=
@@ -932,7 +934,9 @@ deposit_cb (void *cls,
 
   deposit_rowid = rowid;
   if (NULL != wire)
-    TALER_JSON_hash (wire, &h_wire);
+    GNUNET_assert (GNUNET_OK ==
+                   TALER_JSON_hash (wire,
+                                    &h_wire));
   if ( (0 != memcmp (merchant_pub,
                      &deposit->merchant_pub,
                      sizeof (struct TALER_MerchantPublicKeyP))) ||
@@ -1115,6 +1119,7 @@ test_gc (struct TALER_EXCHANGEDB_Session *session)
                                &fee_deposit,
                                &fee_refresh,
                                &fee_refund);
+  GNUNET_assert (NULL != dkp);
   if (GNUNET_OK !=
       plugin->gc (plugin->cls))
   {
@@ -1583,6 +1588,7 @@ run (void *cls)
                                &fee_deposit,
                                &fee_refresh,
                               &fee_refund);
+  GNUNET_assert (NULL != dkp);
   GNUNET_CRYPTO_rsa_public_key_hash (dkp->pub.rsa_public_key,
                                      &dkp_pub_hash);
   RND_BLK(&cbc.h_coin_envelope);
@@ -1776,8 +1782,9 @@ run (void *cls)
   RND_BLK (&deposit.merchant_pub);
   RND_BLK (&deposit.h_contract_terms);
   wire = json_loads (json_wire_str, 0, NULL);
-  TALER_JSON_hash (wire,
-                   &deposit.h_wire);
+  GNUNET_assert (GNUNET_OK ==
+                 TALER_JSON_hash (wire,
+                                  &deposit.h_wire));
   deposit.receiver_wire_account = wire;
   deposit.amount_with_fee = value;
   deposit.deposit_fee = fee_deposit;
diff --git a/src/include/taler_auditordb_plugin.h 
b/src/include/taler_auditordb_plugin.h
index 3141ad6..2d7d460 100644
--- a/src/include/taler_auditordb_plugin.h
+++ b/src/include/taler_auditordb_plugin.h
@@ -107,6 +107,24 @@ typedef int
 
 
 /**
+ * Structure for remembering the wire auditor's progress over the
+ * various tables and (auditor) transactions.
+ */
+struct TALER_AUDITORDB_WireProgressPoint
+{
+  /**
+   * last_reserve_in_serial_id serial ID of the last reserve_in transfer the 
wire auditor processed
+   */
+  uint64_t last_reserve_in_serial_id;
+
+  /**
+   * last_wire_out_serial_id serial ID of the last wire_out the wire auditor 
processed
+   */
+  uint64_t last_wire_out_serial_id;
+};
+
+
+/**
  * Structure for remembering the auditor's progress over the
  * various tables and (auditor) transactions.
  */
@@ -352,6 +370,75 @@ struct TALER_AUDITORDB_Plugin
 
 
   /**
+   * Insert information about the wire auditor's progress with an exchange's
+   * data.
+   *
+   * @param cls the @e cls of this struct with the plugin-specific state
+   * @param session connection to use
+   * @param master_pub master key of the exchange
+   * @param pp where is the auditor in processing
+   * @param in_wire_off how far are we in the incoming wire transaction history
+   * @param out_wire_off how far are we in the outgoing wire transaction 
history
+   * @param wire_off_size how many bytes do @a in_wire_off and @a out_wire_off 
take?
+   * @return transaction status code
+   */
+  enum GNUNET_DB_QueryStatus
+  (*insert_wire_auditor_progress)(void *cls,
+                                  struct TALER_AUDITORDB_Session *session,
+                                  const struct TALER_MasterPublicKeyP 
*master_pub,
+                                  const struct 
TALER_AUDITORDB_WireProgressPoint *pp,
+                                  const void *in_wire_off,
+                                  const void *out_wire_off,
+                                  size_t wire_off_size);
+
+
+  /**
+   * Update information about the progress of the wire auditor.  There
+   * must be an existing record for the exchange.
+   *
+   * @param cls the @e cls of this struct with the plugin-specific state
+   * @param session connection to use
+   * @param master_pub master key of the exchange
+   * @param pp where is the auditor in processing
+   * @param in_wire_off how far are we in the incoming wire transaction history
+   * @param out_wire_off how far are we in the outgoing wire transaction 
history
+   * @param wire_off_size how many bytes do @a in_wire_off and @a out_wire_off 
take?
+   * @return transaction status code
+   */
+  enum GNUNET_DB_QueryStatus
+  (*update_wire_auditor_progress)(void *cls,
+                                  struct TALER_AUDITORDB_Session *session,
+                                  const struct TALER_MasterPublicKeyP 
*master_pub,
+                                  const struct 
TALER_AUDITORDB_WireProgressPoint *pp,
+                                  const void *in_wire_off,
+                                  const void *out_wire_off,
+                                  size_t wire_off_size);
+
+
+
+  /**
+   * Get information about the progress of the wire auditor.
+   *
+   * @param cls the @e cls of this struct with the plugin-specific state
+   * @param session connection to use
+   * @param master_pub master key of the exchange
+   * @param[out] pp set to where the auditor is in processing
+   * @param[out] in_wire_off how far are we in the incoming wire transaction 
history
+   * @param[out] out_wire_off how far are we in the outgoing wire transaction 
history
+   * @param[out] wire_off_size how many bytes do @a in_wire_off and @a 
out_wire_off take?
+   * @return transaction status code
+   */
+  enum GNUNET_DB_QueryStatus
+  (*get_wire_auditor_progress)(void *cls,
+                               struct TALER_AUDITORDB_Session *session,
+                               const struct TALER_MasterPublicKeyP *master_pub,
+                               struct TALER_AUDITORDB_WireProgressPoint *pp,
+                               void **in_wire_off,
+                               void **out_wire_off,
+                               size_t *wire_off_size);
+
+
+  /**
    * Insert information about a reserve.  There must not be an
    * existing record for the reserve.
    *
diff --git a/src/include/taler_error_codes.h b/src/include/taler_error_codes.h
index 907be84..5a95635 100644
--- a/src/include/taler_error_codes.h
+++ b/src/include/taler_error_codes.h
@@ -53,6 +53,11 @@ enum TALER_ErrorCode
    */
   TALER_EC_NOT_IMPLEMENTED = 3,
 
+  /**
+   * Exchange is badly configured and thus cannot operate.
+   */
+  TALER_EC_EXCHANGE_BAD_CONFIGURATION = 4,
+
   /* ********** generic error codes ************* */
 
   /**
@@ -407,6 +412,11 @@ enum TALER_ErrorCode
    */
   TALER_EC_DEPOSIT_INVALID_WIRE_FORMAT_TYPE_UNSUPPORTED = 1217,
 
+  /**
+   * Timestamp included in deposit permission is intolerably far off
+   * with respect to the clock of the exchange.
+   */
+  TALER_EC_DEPOSIT_INVALID_TIMESTAMP = 1218,
 
   /**
    * The respective coin did not have sufficient residual value
@@ -901,7 +911,7 @@ enum TALER_ErrorCode
    * MHD_HTTP_BAD_REQUEST.
    */
   TALER_EC_KEYS_HAVE_NOT_NUMERIC = 1900,
-  
+
 
   /* *********** Merchant backend error codes ********* */
 
@@ -1246,7 +1256,8 @@ enum TALER_ErrorCode
   /**
    * The exchange gave conflicting information about a coin which has
    * been wire transferred.
-   * The response is provided with HTTP status code 
MHD_HTTP_INTERNAL_SERVER_ERROR.
+   * The response is provided with HTTP status code
+   * MHD_HTTP_INTERNAL_SERVER_ERROR (FIXME: bad choice!).
    */
   TALER_EC_TRACK_TRANSFER_CONFLICTING_REPORTS = 2408,
 
@@ -1256,6 +1267,14 @@ enum TALER_ErrorCode
   TALER_EC_TRACK_TRANSFER_JSON_RESPONSE_ERROR = 2409,
 
   /**
+   * The exchange charged a different wire fee than what it
+   * originally advertised, and it is higher.  The response
+   * is provied with an HTTP status of
+   * MHD_HTTP_INTERNAL_SERVER_ERROR (FIXME: bad choice!).
+   */
+  TALER_EC_TRACK_TRANSFER_JSON_BAD_WIRE_FEE = 2410,
+
+  /**
    * The hash provided in the request of /map/in does not match
    * the contract sent alongside in the same request.
    */
@@ -1309,6 +1328,14 @@ enum TALER_ErrorCode
    */
   TALER_EC_REFUND_MERCHANT_DB_COMMIT_ERROR = 2604,
 
+  /**
+   * Payments are stored in a single db transaction; this error indicates
+   * that one db operation within that transaction failed.  This might involve
+   * storing of coins or other related db operations, like starting/committing
+   * the db transaction or marking a contract as paid.
+   */
+   TALER_EC_PAY_DB_STORE_PAYMENTS_ERROR = 2605,
+
 
   /* ********** /test API error codes ************* */
 
diff --git a/src/include/taler_exchange_service.h 
b/src/include/taler_exchange_service.h
index 487304c..814078a 100644
--- a/src/include/taler_exchange_service.h
+++ b/src/include/taler_exchange_service.h
@@ -206,14 +206,19 @@ struct TALER_EXCHANGE_Keys
   char *version;
 
   /**
-   * Timestamp indicating the /keys generation.  Monotonically
-   * increasing. Used to fetch /keys incrementally.  Set from
-   * the "list_issue_date" timestamp of /keys.
+   * Timestamp indicating the /keys generation.
    */
-  struct GNUNET_TIME_Absolute last_issue_date;
-  
+  struct GNUNET_TIME_Absolute list_issue_date;
+
+  /**
+   * Timestamp indicating the creation time of the last
+   * denomination key in /keys.
+   * Used to fetch /keys incrementally.
+   */
+  struct GNUNET_TIME_Absolute last_denom_issue_date;
+
   /**
-   * Length of the @e sign_keys array.
+   * Length of the @e sign_keys array (number of valid entries).
    */
   unsigned int num_sign_keys;
 
@@ -227,10 +232,20 @@ struct TALER_EXCHANGE_Keys
    */
   unsigned int num_auditors;
 
+  /**
+   * Actual length of the @e auditors array (size of allocation).
+   */
+  unsigned int auditors_size;
+
+  /**
+   * Actual length of the @e denom_keys array (size of allocation).
+   */
+  unsigned int denom_keys_size;
+
 };
 
 
-/** 
+/**
  * How compatible are the protocol version of the exchange and this
  * client?  The bits (1,2,4) can be used to test if the exchange's
  * version is incompatible, older or newer respectively.
@@ -270,7 +285,7 @@ enum TALER_EXCHANGE_VersionCompatibility
   /**
    * The exchange is too recent for this implementation.
    */
-  TALER_EXCHANGE_VC_INCOMPATIBLE_NEWER 
+  TALER_EXCHANGE_VC_INCOMPATIBLE_NEWER
   = TALER_EXCHANGE_VC_INCOMPATIBLE
   | TALER_EXCHANGE_VC_NEWER,
 
@@ -278,7 +293,7 @@ enum TALER_EXCHANGE_VersionCompatibility
    * We could not even parse the version data.
    */
   TALER_EXCHANGE_VC_PROTOCOL_ERROR = 8
-  
+
 };
 
 
@@ -352,10 +367,12 @@ TALER_EXCHANGE_get_keys (struct TALER_EXCHANGE_Handle 
*exchange);
  * not, trigger /keys download.
  *
  * @param exchange exchange to check keys for
+ * @param force_download #GNUNET_YES to force download even if /keys is still 
valid
  * @return until when the response is current, 0 if we are re-downloading
  */
 struct GNUNET_TIME_Absolute
-TALER_EXCHANGE_check_keys_current (struct TALER_EXCHANGE_Handle *exchange);
+TALER_EXCHANGE_check_keys_current (struct TALER_EXCHANGE_Handle *exchange,
+                                   int force_download);
 
 
 /**
diff --git a/src/include/taler_exchangedb_plugin.h 
b/src/include/taler_exchangedb_plugin.h
index 2cc2c75..006ea39 100644
--- a/src/include/taler_exchangedb_plugin.h
+++ b/src/include/taler_exchangedb_plugin.h
@@ -1042,6 +1042,30 @@ typedef void
 
 
 /**
+ * Function called on deposits that are past their due date
+ * and have not yet seen a wire transfer.
+ *
+ * @param cls closure
+ * @param rowid deposit table row of the coin's deposit
+ * @param coin_pub public key of the coin
+ * @param amount value of the deposit, including fee
+ * @param wire where should the funds be wired
+ * @param deadline what was the requested wire transfer deadline
+ * @param tiny did the exchange defer this transfer because it is too small?
+ * @param done did the exchange claim that it made a transfer?
+ */
+typedef void
+(*TALER_EXCHANGEDB_WireMissingCallback)(void *cls,
+                                       uint64_t rowid,
+                                       const struct TALER_CoinSpendPublicKeyP 
*coin_pub,
+                                       const struct TALER_Amount *amount,
+                                       const json_t *wire,
+                                       struct GNUNET_TIME_Absolute deadline,
+                                       /* bool? */ int tiny,
+                                       /* bool? */ int done);
+
+
+/**
  * @brief The plugin API, returned from the plugin's "init" function.
  * The argument given to "init" is simply a configuration handle.
  */
@@ -2189,6 +2213,28 @@ struct TALER_EXCHANGEDB_Plugin
                                 uint64_t *rowid);
 
 
+  /**
+   * Select all of those deposits in the database for which we do
+   * not have a wire transfer (or a refund) and which should have
+   * been deposited between @a start_date and @a end_date.
+   *
+   * @param cls closure
+   * @param session a session
+   * @param start_date lower bound on the requested wire execution date
+   * @param end_date upper bound on the requested wire execution date
+   * @param cb function to call on all such deposits
+   * @param cb_cls closure for @a cb
+   * @return transaction status code
+   */
+  enum GNUNET_DB_QueryStatus
+  (*select_deposits_missing_wire)(void *cls,
+                                 struct TALER_EXCHANGEDB_Session *session,
+                                 struct GNUNET_TIME_Absolute start_date,
+                                 struct GNUNET_TIME_Absolute end_date,
+                                 TALER_EXCHANGEDB_WireMissingCallback cb,
+                                 void *cb_cls);
+  
+
 };
 
 
diff --git a/src/include/taler_signatures.h b/src/include/taler_signatures.h
index 181c501..db71cca 100644
--- a/src/include/taler_signatures.h
+++ b/src/include/taler_signatures.h
@@ -793,7 +793,7 @@ struct TALER_ExchangeKeyValidityPS
   struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
 
   /**
-   * Hash of the auditor's URL.
+   * Hash of the auditor's URL (including 0-terminator).
    */
   struct GNUNET_HashCode auditor_url_hash;
 
diff --git a/src/include/taler_wire_plugin.h b/src/include/taler_wire_plugin.h
index 4134afc..969af35 100644
--- a/src/include/taler_wire_plugin.h
+++ b/src/include/taler_wire_plugin.h
@@ -59,7 +59,11 @@ struct TALER_WIRE_TransferDetails
   struct GNUNET_TIME_Absolute execution_date;
 
   /**
-   * Reserve public key that was encoded in the wire transfer subject
+   * Reserve public key that was encoded in the wire transfer subject.
+   * FIXME (#5077): this is incorrect for *outgoing* wire transfers.
+   * Maybe use `struct TALER_WireTransferIdentifierRawP` here instead?
+   * OTOH, we might want to make this even more generic in case of
+   * invalid transfers, so that we can capture those as well!
    */
   struct TALER_ReservePublicKeyP reserve_pub;
 
diff --git a/src/json/json.c b/src/json/json.c
index 74559e6..adcc231 100644
--- a/src/json/json.c
+++ b/src/json/json.c
@@ -40,7 +40,10 @@ TALER_JSON_hash (const json_t *json,
 
   if (NULL == (wire_enc = json_dumps (json,
                                       JSON_COMPACT | JSON_SORT_KEYS)))
+  {
+    GNUNET_break (0);
     return GNUNET_SYSERR;
+  }
   len = strlen (wire_enc) + 1;
   GNUNET_CRYPTO_hash (wire_enc,
                       len,
diff --git a/src/json/json_helper.c b/src/json/json_helper.c
index aea19ac..fec637b 100644
--- a/src/json/json_helper.c
+++ b/src/json/json_helper.c
@@ -152,8 +152,8 @@ TALER_JSON_spec_amount (const char *name,
  */
 static int
 parse_amount_nbo (void *cls,
-              json_t *root,
-              struct GNUNET_JSON_Specification *spec)
+                  json_t *root,
+                  struct GNUNET_JSON_Specification *spec)
 {
   struct TALER_AmountNBO *r_amount = spec->ptr;
   struct TALER_Amount amount;
diff --git a/src/pq/test_pq.c b/src/pq/test_pq.c
index 841c3e3..6f7de0d 100644
--- a/src/pq/test_pq.c
+++ b/src/pq/test_pq.c
@@ -111,15 +111,6 @@ run_queries (PGconn *conn)
       TALER_PQ_query_param_json (json),
       GNUNET_PQ_query_param_end
     };
-    struct GNUNET_PQ_QueryParam params_select[] = {
-      GNUNET_PQ_query_param_end
-    };
-    struct GNUNET_PQ_ResultSpec results_select[] = {
-      TALER_PQ_result_spec_amount ("hamount", &hamount2),
-      TALER_PQ_result_spec_amount_nbo ("namount", &namount2),
-      TALER_PQ_result_spec_json ("json", &json2),
-      GNUNET_PQ_result_spec_end
-    };
 
     result = GNUNET_PQ_exec_prepared (conn,
                                      "test_insert",
@@ -132,8 +123,13 @@ run_queries (PGconn *conn)
       PQclear (result);
       return 1;
     }
-
     PQclear (result);
+  }
+  {
+    struct GNUNET_PQ_QueryParam params_select[] = {
+      GNUNET_PQ_query_param_end
+    };
+
     result = GNUNET_PQ_exec_prepared (conn,
                                      "test_select",
                                      params_select);
@@ -144,6 +140,16 @@ run_queries (PGconn *conn)
       PQclear (result);
       return 1;
     }
+  }
+
+  {
+    struct GNUNET_PQ_ResultSpec results_select[] = {
+      TALER_PQ_result_spec_amount ("hamount", &hamount2),
+      TALER_PQ_result_spec_amount_nbo ("namount", &namount2),
+      TALER_PQ_result_spec_json ("json", &json2),
+      GNUNET_PQ_result_spec_end
+    };
+
     ret = GNUNET_PQ_extract_result (result,
                                    results_select,
                                    0);
diff --git a/src/util/amount.c b/src/util/amount.c
index e066485..33ba9a2 100644
--- a/src/util/amount.c
+++ b/src/util/amount.c
@@ -52,7 +52,7 @@ TALER_string_to_amount (const char *str,
           0,
           sizeof (struct TALER_Amount));
   /* skip leading whitespace */
-  while (isspace(str[0]))
+  while (isspace( (unsigned char) str[0]))
     str++;
   if ('\0' == str[0])
   {
diff --git a/src/wire/plugin_wire_sepa.c b/src/wire/plugin_wire_sepa.c
index 6300d82..5de3472 100644
--- a/src/wire/plugin_wire_sepa.c
+++ b/src/wire/plugin_wire_sepa.c
@@ -292,7 +292,10 @@ validate_iban (const char *iban)
 
   len = strlen (iban);
   if (len > 34)
+  {
+    GNUNET_break_op (0);
     return GNUNET_NO;
+  }
   strncpy (cc, iban, 2);
   strncpy (ibancpy, iban + 4, len - 4);
   strncpy (ibancpy + len - 4, iban, 4);
@@ -305,11 +308,14 @@ validate_iban (const char *iban)
                sizeof (country_table) / sizeof (struct table_entry),
                sizeof (struct table_entry),
                &cmp_country_code))
+  {
+    GNUNET_break_op (0);
     return GNUNET_NO;
+  }
   nbuf = GNUNET_malloc ((len * 2) + 1);
   for (i=0, j=0; i < len; i++)
   {
-    if (isalpha ((int) ibancpy[i]))
+    if (isalpha ((unsigned char) ibancpy[i]))
     {
       if (2 != snprintf(&nbuf[j],
                         3,
@@ -326,7 +332,7 @@ validate_iban (const char *iban)
     j++;
   }
   for (j=0;'\0' != nbuf[j];j++)
-    GNUNET_assert (isdigit(nbuf[j]));
+    GNUNET_assert (isdigit( (unsigned char) nbuf[j]));
   GNUNET_assert (sizeof(dividend) >= 8);
   remainder = 0;
   for (i=0; i<j; i+=16)
@@ -338,6 +344,7 @@ validate_iban (const char *iban)
                        &nread)))
     {
       GNUNET_free (nbuf);
+      GNUNET_break_op (0);
       return GNUNET_NO;
     }
     if (0 != remainder)
@@ -347,6 +354,7 @@ validate_iban (const char *iban)
   GNUNET_free (nbuf);
   if (1 == remainder)
     return GNUNET_YES;
+  GNUNET_break_op (0); /* checksum wrong */
   return GNUNET_NO;
 }
 
diff --git a/src/wire/plugin_wire_test.c b/src/wire/plugin_wire_test.c
index 6649b91..c41bd7e 100644
--- a/src/wire/plugin_wire_test.c
+++ b/src/wire/plugin_wire_test.c
@@ -307,7 +307,7 @@ test_wire_validate (void *cls,
                                      sizeof (sig)))
   {
     GNUNET_break (0);
-    return GNUNET_SYSERR;
+    return TALER_EC_DEPOSIT_INVALID_WIRE_FORMAT_SIGNATURE;
   }
   if (GNUNET_OK !=
       GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MASTER_TEST_DETAILS,

-- 
To stop receiving notification emails like this one, please contact
address@hidden



reply via email to

[Prev in Thread] Current Thread [Next in Thread]