expand exchangedb plugin for new /keys logic

This commit is contained in:
Christian Grothoff 2020-12-06 21:48:31 +01:00
parent fd96e34c78
commit 22c9321e67
No known key found for this signature in database
GPG Key ID: 939E6BE1E29FC3CC
4 changed files with 726 additions and 23 deletions

View File

@ -229,6 +229,9 @@ struct TEH_KeyStateHandle
*/
struct GNUNET_CONTAINER_MultiPeerMap *signkey_map;
// FIXME: need list of auditors here!
// FIXME: need list of auditor-denominations here!
/**
* Sorted array of responses to /keys (MUST be sorted by cherry-picking date) of
* length @e krd_array_length;
@ -780,15 +783,35 @@ signkey_info_cb (
* @param auditor_pub the public key of the auditor
* @param auditor_url URL of the REST API of the auditor
* @param auditor_name human readable official name of the auditor
* @param ... MORE
*/
static void
auditor_info_cb (
void *cls,
const struct TALER_AuditorPublicKeyP *auditor_pub,
const char *auditor_url,
const char *auditor_name,
...)
const char *auditor_name)
{
struct TEH_KeyStateHandle *ksh = cls;
// FIXME: remember...
}
/**
* Function called with information about the denominations
* audited by the exchange's auditors.
*
* @param cls closure with a `struct TEH_KeyStateHandle *`
* @param auditor_pub the public key of an auditor
* @param h_denom_pub hash of a denomination key audited by this auditor
* @param auditor_sig signature from the auditor affirming this
*/
static void
auditor_denom_cb (
void *cls,
const struct TALER_AuditorPublicKeyP *auditor_pub,
const struct GNUNET_HashCode *h_denom_pub,
const struct TALER_AuditorSignatureP *auditor_sig)
{
struct TEH_KeyStateHandle *ksh = cls;
@ -828,8 +851,7 @@ build_key_state (struct HelperState *hs)
GNUNET_YES);
ksh->signkey_map = GNUNET_CONTAINER_multihashmap_create (32,
GNUNET_NO /* MUST be NO! */);
#if TBD
// NOTE: should ONLY fetch master-signed signkeys, but ALSO those that were revoked!
/* NOTE: fetches master-signed signkeys, but ALSO those that were revoked! */
qs = TEH_plugin->iterate_denominations (TEH_plugin->cls,
&denomination_info_cb,
ksh);
@ -840,12 +862,10 @@ build_key_state (struct HelperState *hs)
true);
return NULL;
}
#endif
#if TBD
// NOTE: should ONLY fetch non-revoked AND master-signed signkeys!
qs = TEH_plugin->iterate_signkeys (TEH_plugin->cls,
&signkey_info_cb,
ksh);
/* NOTE: ONLY fetches non-revoked AND master-signed signkeys! */
qs = TEH_plugin->iterate_active_signkeys (TEH_plugin->cls,
&signkey_info_cb,
ksh);
if (qs < 0)
{
GNUNET_break (0);
@ -853,11 +873,19 @@ build_key_state (struct HelperState *hs)
true);
return NULL;
}
#endif
#if TBD
qs = TEH_plugin->iterate_auditor_info (TEH_plugin->cls,
&auditor_info_cb,
ksh);
qs = TEH_plugin->iterate_active_auditors (TEH_plugin->cls,
&auditor_info_cb,
ksh);
if (qs < 0)
{
GNUNET_break (0);
destroy_key_state (ksh,
true);
return NULL;
}
qs = TEH_plugin->iterate_auditor_denominations (TEH_plugin->cls,
&auditor_denom_cb,
ksh);
if (qs < 0)
{
GNUNET_break (0);
@ -865,7 +893,6 @@ build_key_state (struct HelperState *hs)
true);
return NULL;
}
#endif
return ksh;
}

View File

@ -114,20 +114,23 @@ COMMENT ON COLUMN auditor_denom_sigs.auditor_sig
CREATE TABLE IF NOT EXISTS exchange_sign_keys
(exchange_pub BYTEA PRIMARY KEY
,master_pub BYTEA NOT NULL CHECK (LENGTH(master_pub)=32)
(exchange_pub BYTEA PRIMARY KEY CHECK (LENGTH(exchange_pub)=32)
,master_sig BYTEA NOT NULL CHECK (LENGTH(master_sig)=64)
,legal_end INT8 NOT NULL
,valid_from INT8 NOT NULL
,expire_sign INT8 NOT NULL
,expire_legal INT8 NOT NULL
);
COMMENT ON TABLE exchange_sign_keys
IS 'Table with master public key signatures on exchange online signing keys.';
COMMENT ON COLUMN exchange_sign_keys.exchange_pub
IS 'Public online signing key of the exchange.';
COMMENT ON COLUMN exchange_sign_keys.master_pub
IS 'Master public key of the exchange that was used for master_sig.';
COMMENT ON COLUMN exchange_sign_keys.master_sig
IS 'Signature affirming the validity of the signing key of purpose TALER_SIGNATURE_MASTER_SIGNING_KEY_VALIDITY.';
COMMENT ON COLUMN exchange_sign_keys.legal_end
COMMENT ON COLUMN exchange_sign_keys.valid_from
IS 'Time when this online signing key will first be used to sign messages.';
COMMENT ON COLUMN exchange_sign_keys.expire_sign
IS 'Time when this online signing key will no longer be used to sign.';
COMMENT ON COLUMN exchange_sign_keys.expire_legal
IS 'Time when this online signing key legally expires.';

View File

@ -314,6 +314,66 @@ postgres_get_session (void *cls)
",denom_pub"
" FROM denominations;",
0),
/* Used in #postgres_iterate_denominations() */
GNUNET_PQ_make_prepare ("select_denominations",
"SELECT"
" denominations.master_sig"
",denom_revocations_serial_id IS NOT NULL AS revoked"
",valid_from"
",expire_withdraw"
",expire_deposit"
",expire_legal"
",coin_val" /* value of this denom */
",coin_frac" /* fractional value of this denom */
",fee_withdraw_val"
",fee_withdraw_frac"
",fee_deposit_val"
",fee_deposit_frac"
",fee_refresh_val"
",fee_refresh_frac"
",fee_refund_val"
",fee_refund_frac"
",denom_pub"
" FROM denominations"
" LEFT JOIN "
" denomination_revocations USING (denom_pub_hash);",
0),
/* Used in #postgres_iterate_active_signkeys() */
GNUNET_PQ_make_prepare ("select_signkeys",
"SELECT"
" master_sig"
",exchange_pub"
",valid_from"
",expire_sign"
",expire_legal"
" FROM exchange_sign_keys esk"
" WHERE"
" expire_sign > $1"
" AND NOT EXISTS "
" (SELECT exchange_pub "
" FROM signkey_revocations skr"
" WHERE esk.exchange_pub = skr.exchange_pub);",
1),
/* Used in #postgres_iterate_auditor_denominations() */
GNUNET_PQ_make_prepare ("select_auditor_denoms",
"SELECT"
" auditor_denom_sigs.auditor_pub"
",auditor_denom_sigs.denom_pub_hash"
",auditor_denom_sigs.auditor_sig"
" FROM auditor_denom_sigs"
" JOIN auditors USING (auditor_pub)"
" WHERE auditors.is_active;",
0),
/* Used in #postgres_iterate_active_auditors() */
GNUNET_PQ_make_prepare ("select_auditors",
"SELECT"
" auditor_pub"
",auditor_url"
",auditor_name"
" FROM auditors"
" WHERE"
" is_active;",
0),
/* Used in #postgres_get_denomination_info() */
GNUNET_PQ_make_prepare ("denomination_get",
"SELECT"
@ -1981,6 +2041,448 @@ postgres_iterate_denomination_info (void *cls,
}
/**
* Closure for #dominations_cb_helper()
*/
struct DenomsIteratorContext
{
/**
* Function to call with the results.
*/
TALER_EXCHANGEDB_DenominationsCallback cb;
/**
* Closure to pass to @e cb
*/
void *cb_cls;
/**
* Plugin context.
*/
struct PostgresClosure *pg;
};
/**
* Helper function for #postgres_iterate_denominations().
* Calls the callback with each denomination key.
*
* @param cls a `struct DenomsIteratorContext`
* @param result db results
* @param num_results number of results in @a result
*/
static void
dominations_cb_helper (void *cls,
PGresult *result,
unsigned int num_results)
{
struct DenomsIteratorContext *dic = cls;
struct PostgresClosure *pg = dic->pg;
for (unsigned int i = 0; i<num_results; i++)
{
struct TALER_EXCHANGEDB_DenominationKeyMetaData meta;
struct TALER_DenominationPublicKey denom_pub;
struct TALER_MasterSignatureP master_sig;
struct GNUNET_HashCode h_denom_pub;
uint8_t revoked;
struct GNUNET_PQ_ResultSpec rs[] = {
GNUNET_PQ_result_spec_auto_from_type ("master_sig",
&master_sig),
GNUNET_PQ_result_spec_auto_from_type ("revoked",
&revoked),
TALER_PQ_result_spec_absolute_time ("valid_from",
&meta.start),
TALER_PQ_result_spec_absolute_time ("expire_withdraw",
&meta.expire_withdraw),
TALER_PQ_result_spec_absolute_time ("expire_deposit",
&meta.expire_deposit),
TALER_PQ_result_spec_absolute_time ("expire_legal",
&meta.expire_legal),
TALER_PQ_RESULT_SPEC_AMOUNT ("coin",
&meta.value),
TALER_PQ_RESULT_SPEC_AMOUNT ("fee_withdraw",
&meta.fee_withdraw),
TALER_PQ_RESULT_SPEC_AMOUNT ("fee_deposit",
&meta.fee_deposit),
TALER_PQ_RESULT_SPEC_AMOUNT ("fee_refresh",
&meta.fee_refresh),
TALER_PQ_RESULT_SPEC_AMOUNT ("fee_refund",
&meta.fee_refund),
GNUNET_PQ_result_spec_rsa_public_key ("denom_pub",
&denom_pub.rsa_public_key),
GNUNET_PQ_result_spec_end
};
if (GNUNET_OK !=
GNUNET_PQ_extract_result (result,
rs,
i))
{
GNUNET_break (0);
return;
}
GNUNET_CRYPTO_rsa_public_key_hash (denom_pub.rsa_public_key,
&h_denom_pub);
dic->cb (dic->cb_cls,
&denom_pub,
&h_denom_pub,
&meta,
&master_sig,
(0 != revoked));
GNUNET_PQ_cleanup_result (rs);
}
}
/**
* Function called to invoke @a cb on every known denomination key (revoked
* and non-revoked) that has been signed by the master key. Runs in its own
* read-only transaction (hence no session provided).
*
*
* @param cls the @e cls of this struct with the plugin-specific state
* @param cb function to call on each denomination key
* @param cb_cls closure for @a cb
* @return transaction status code
*/
static enum GNUNET_DB_QueryStatus
postgres_iterate_denominations (void *cls,
TALER_EXCHANGEDB_DenominationsCallback cb,
void *cb_cls)
{
struct PostgresClosure *pc = cls;
struct GNUNET_PQ_QueryParam params[] = {
GNUNET_PQ_query_param_end
};
struct DenomsIteratorContext dic = {
.cb = cb,
.cb_cls = cb_cls,
.pg = pc
};
struct TALER_EXCHANGEDB_Session *session;
session = postgres_get_session (pc);
if (NULL == session)
return GNUNET_DB_STATUS_HARD_ERROR;
return GNUNET_PQ_eval_prepared_multi_select (session->conn,
"select_denominations",
params,
&dominations_cb_helper,
&dic);
}
/**
* Closure for #signkeys_cb_helper()
*/
struct SignkeysIteratorContext
{
/**
* Function to call with the results.
*/
TALER_EXCHANGEDB_ActiveSignkeysCallback cb;
/**
* Closure to pass to @e cb
*/
void *cb_cls;
};
/**
* Helper function for #postgres_active_signkeys().
* Calls the callback with each signkey.
*
* @param cls a `struct SignkeysIteratorContext`
* @param result db results
* @param num_results number of results in @a result
*/
static void
signkeys_cb_helper (void *cls,
PGresult *result,
unsigned int num_results)
{
struct SignkeysIteratorContext *dic = cls;
for (unsigned int i = 0; i<num_results; i++)
{
struct TALER_EXCHANGEDB_SignkeyMetaData meta;
struct TALER_ExchangePublicKeyP exchange_pub;
struct TALER_MasterSignatureP master_sig;
struct GNUNET_PQ_ResultSpec rs[] = {
GNUNET_PQ_result_spec_auto_from_type ("master_sig",
&master_sig),
GNUNET_PQ_result_spec_auto_from_type ("exchange_pub",
&exchange_pub),
TALER_PQ_result_spec_absolute_time ("valid_from",
&meta.start),
TALER_PQ_result_spec_absolute_time ("expire_sign",
&meta.expire_sign),
TALER_PQ_result_spec_absolute_time ("expire_legal",
&meta.expire_legal),
GNUNET_PQ_result_spec_end
};
if (GNUNET_OK !=
GNUNET_PQ_extract_result (result,
rs,
i))
{
GNUNET_break (0);
return;
}
dic->cb (dic->cb_cls,
&exchange_pub,
&meta,
&master_sig);
}
}
/**
* Function called to invoke @a cb on every non-revoked exchange signing key
* that has been signed by the master key. Revoked and (for signing!)
* expired keys are skipped. Runs in its own read-only transaction (hence no
* session provided).
*
* @param cls the @e cls of this struct with the plugin-specific state
* @param cb function to call on each signing key
* @param cb_cls closure for @a cb
* @return transaction status code
*/
static enum GNUNET_DB_QueryStatus
postgres_iterate_active_signkeys (void *cls,
TALER_EXCHANGEDB_ActiveSignkeysCallback cb,
void *cb_cls)
{
struct PostgresClosure *pc = cls;
struct GNUNET_TIME_Absolute now;
struct GNUNET_PQ_QueryParam params[] = {
GNUNET_PQ_query_param_absolute_time (&now),
GNUNET_PQ_query_param_end
};
struct SignkeysIteratorContext dic = {
.cb = cb,
.cb_cls = cb_cls,
};
struct TALER_EXCHANGEDB_Session *session;
now = GNUNET_TIME_absolute_get ();
session = postgres_get_session (pc);
if (NULL == session)
return GNUNET_DB_STATUS_HARD_ERROR;
return GNUNET_PQ_eval_prepared_multi_select (session->conn,
"select_signkeys",
params,
&signkeys_cb_helper,
&dic);
}
/**
* Closure for #auditors_cb_helper()
*/
struct AuditorsIteratorContext
{
/**
* Function to call with the results.
*/
TALER_EXCHANGEDB_AuditorsCallback cb;
/**
* Closure to pass to @e cb
*/
void *cb_cls;
};
/**
* Helper function for #postgres_active_auditors().
* Calls the callback with each auditor.
*
* @param cls a `struct SignkeysIteratorContext`
* @param result db results
* @param num_results number of results in @a result
*/
static void
auditors_cb_helper (void *cls,
PGresult *result,
unsigned int num_results)
{
struct AuditorsIteratorContext *dic = cls;
for (unsigned int i = 0; i<num_results; i++)
{
struct TALER_AuditorPublicKeyP auditor_pub;
char *auditor_url;
char *auditor_name;
struct GNUNET_PQ_ResultSpec rs[] = {
GNUNET_PQ_result_spec_auto_from_type ("auditor_pub",
&auditor_pub),
GNUNET_PQ_result_spec_string ("auditor_url",
&auditor_url),
GNUNET_PQ_result_spec_string ("auditor_name",
&auditor_name),
GNUNET_PQ_result_spec_end
};
if (GNUNET_OK !=
GNUNET_PQ_extract_result (result,
rs,
i))
{
GNUNET_break (0);
return;
}
dic->cb (dic->cb_cls,
&auditor_pub,
auditor_url,
auditor_name);
GNUNET_PQ_cleanup_result (rs);
}
}
/**
* Function called to invoke @a cb on every active auditor. Disabled
* auditors are skipped. Runs in its own read-only transaction (hence no
* session provided).
*
* @param cls the @e cls of this struct with the plugin-specific state
* @param cb function to call on each active auditor
* @param cb_cls closure for @a cb
* @return transaction status code
*/
static enum GNUNET_DB_QueryStatus
postgres_iterate_active_auditors (void *cls,
TALER_EXCHANGEDB_AuditorsCallback cb,
void *cb_cls)
{
struct PostgresClosure *pc = cls;
struct GNUNET_PQ_QueryParam params[] = {
GNUNET_PQ_query_param_end
};
struct AuditorsIteratorContext dic = {
.cb = cb,
.cb_cls = cb_cls,
};
struct TALER_EXCHANGEDB_Session *session;
session = postgres_get_session (pc);
if (NULL == session)
return GNUNET_DB_STATUS_HARD_ERROR;
return GNUNET_PQ_eval_prepared_multi_select (session->conn,
"select_auditors",
params,
&auditors_cb_helper,
&dic);
}
/**
* Closure for #auditor_denoms_cb_helper()
*/
struct AuditorDenomsIteratorContext
{
/**
* Function to call with the results.
*/
TALER_EXCHANGEDB_AuditorDenominationsCallback cb;
/**
* Closure to pass to @e cb
*/
void *cb_cls;
};
/**
* Helper function for #postgres_iterate_auditor_denominations().
* Calls the callback with each auditor and denomination pair.
*
* @param cls a `struct AuditorDenomsIteratorContext`
* @param result db results
* @param num_results number of results in @a result
*/
static void
auditor_denoms_cb_helper (void *cls,
PGresult *result,
unsigned int num_results)
{
struct AuditorDenomsIteratorContext *dic = cls;
for (unsigned int i = 0; i<num_results; i++)
{
struct TALER_AuditorPublicKeyP auditor_pub;
struct GNUNET_HashCode h_denom_pub;
struct TALER_AuditorSignatureP auditor_sig;
struct GNUNET_PQ_ResultSpec rs[] = {
GNUNET_PQ_result_spec_auto_from_type ("auditor_pub",
&auditor_pub),
GNUNET_PQ_result_spec_auto_from_type ("denom_pub_hash",
&h_denom_pub),
GNUNET_PQ_result_spec_auto_from_type ("auditor_sig",
&auditor_sig),
GNUNET_PQ_result_spec_end
};
if (GNUNET_OK !=
GNUNET_PQ_extract_result (result,
rs,
i))
{
GNUNET_break (0);
return;
}
dic->cb (dic->cb_cls,
&auditor_pub,
&h_denom_pub,
&auditor_sig);
}
}
/**
* Function called to invoke @a cb on every denomination with an active
* auditor. Disabled auditors and denominations without auditor are
* skipped. Runs in its own read-only transaction (hence no session
* provided).
*
* @param cls the @e cls of this struct with the plugin-specific state
* @param cb function to call on each active auditor
* @param cb_cls closure for @a cb
* @return transaction status code
*/
static enum GNUNET_DB_QueryStatus
postgres_iterate_auditor_denominations (
void *cls,
TALER_EXCHANGEDB_AuditorDenominationsCallback cb,
void *cb_cls)
{
struct PostgresClosure *pc = cls;
struct GNUNET_PQ_QueryParam params[] = {
GNUNET_PQ_query_param_end
};
struct AuditorDenomsIteratorContext dic = {
.cb = cb,
.cb_cls = cb_cls,
};
struct TALER_EXCHANGEDB_Session *session;
session = postgres_get_session (pc);
if (NULL == session)
return GNUNET_DB_STATUS_HARD_ERROR;
return GNUNET_PQ_eval_prepared_multi_select (session->conn,
"select_auditor_denoms",
params,
&auditor_denoms_cb_helper,
&dic);
}
/**
* Get the summary of a reserve.
*
@ -8208,6 +8710,11 @@ libtaler_plugin_exchangedb_postgres_init (void *cls)
plugin->insert_denomination_info = &postgres_insert_denomination_info;
plugin->get_denomination_info = &postgres_get_denomination_info;
plugin->iterate_denomination_info = &postgres_iterate_denomination_info;
plugin->iterate_denominations = &postgres_iterate_denominations;
plugin->iterate_active_signkeys = &postgres_iterate_active_signkeys;
plugin->iterate_active_auditors = &postgres_iterate_active_auditors;
plugin->iterate_auditor_denominations =
&postgres_iterate_auditor_denominations;
plugin->reserves_get = &postgres_reserves_get;
plugin->reserves_in_insert = &postgres_reserves_in_insert;
plugin->get_latest_reserve_in_reference =

View File

@ -293,6 +293,105 @@ struct TALER_EXCHANGEDB_DenominationKeyMetaData
};
/**
* Signature of a function called with information about the exchange's
* denomination keys.
*
* @param cls closure with a `struct TEH_KeyStateHandle *`
* @param denom_pub public key of the denomination
* @param h_denom_pub hash of @a denom_pub
* @param meta meta data information about the denomination type (value, expirations, fees)
* @param master_sig master signature affirming the validity of this denomination
* @param recoup_possible true if the key was revoked and clients can currently recoup
* coins of this denomination
*/
typedef void
(*TALER_EXCHANGEDB_DenominationsCallback)(
void *cls,
const struct TALER_DenominationPublicKey *denom_pub,
const struct GNUNET_HashCode *h_denom_pub,
const struct TALER_EXCHANGEDB_DenominationKeyMetaData *meta,
const struct TALER_MasterSignatureP *master_sig,
bool recoup_possible);
/**
* Meta data about an exchange online signing key.
*/
struct TALER_EXCHANGEDB_SignkeyMetaData
{
/**
* Start time of the validity period for this key.
*/
struct GNUNET_TIME_Absolute start;
/**
* The exchange will sign messages with this key between @e start and this time.
*/
struct GNUNET_TIME_Absolute expire_sign;
/**
* When do signatures with this sign key become invalid?
* After this point, these signatures cannot be used in (legal)
* disputes anymore, as the Exchange is then allowed to destroy its side
* of the evidence. @e expire_legal is expected to be significantly
* larger than @e expire_sign (by a year or more).
*/
struct GNUNET_TIME_Absolute expire_legal;
};
/**
* Signature of a function called with information about the exchange's
* online signing keys.
*
* @param cls closure with a `struct TEH_KeyStateHandle *`
* @param exchange_pub public key of the exchange
* @param meta meta data information about the signing type (expirations)
* @param master_sig master signature affirming the validity of this denomination
*/
typedef void
(*TALER_EXCHANGEDB_ActiveSignkeysCallback)(
void *cls,
const struct TALER_ExchangePublicKeyP *exchange_pub,
const struct TALER_EXCHANGEDB_SignkeyMetaData *meta,
const struct TALER_MasterSignatureP *master_sig);
/**
* Function called with information about the exchange's auditors.
*
* @param cls closure with a `struct TEH_KeyStateHandle *`
* @param auditor_pub the public key of the auditor
* @param auditor_url URL of the REST API of the auditor
* @param auditor_name human readable official name of the auditor
*/
typedef void
(*TALER_EXCHANGEDB_AuditorsCallback)(
void *cls,
const struct TALER_AuditorPublicKeyP *auditor_pub,
const char *auditor_url,
const char *auditor_name);
/**
* Function called with information about the denominations
* audited by the exchange's auditors.
*
* @param cls closure with a `struct TEH_KeyStateHandle *`
* @param auditor_pub the public key of an auditor
* @param h_denom_pub hash of a denomination key audited by this auditor
* @param auditor_sig signature from the auditor affirming this
*/
typedef void
(*TALER_EXCHANGEDB_AuditorDenominationsCallback)(
void *cls,
const struct TALER_AuditorPublicKeyP *auditor_pub,
const struct GNUNET_HashCode *h_denom_pub,
const struct TALER_AuditorSignatureP *auditor_sig);
/**
* @brief Information we keep for a withdrawn coin to reproduce
* the /withdraw operation if needed, and to have proof
@ -1778,6 +1877,73 @@ struct TALER_EXCHANGEDB_Plugin
TALER_EXCHANGEDB_DenominationCallback cb,
void *cb_cls);
/**
* Function called to invoke @a cb on every known denomination key (revoked
* and non-revoked) that has been signed by the master key. Runs in its own
* read-only transaction (hence no session provided).
*
* @param cls the @e cls of this struct with the plugin-specific state
* @param cb function to call on each denomination key
* @param cb_cls closure for @a cb
* @return transaction status code
*/
enum GNUNET_DB_QueryStatus
(*iterate_denominations)(void *cls,
TALER_EXCHANGEDB_DenominationsCallback cb,
void *cb_cls);
/**
* Function called to invoke @a cb on every non-revoked exchange signing key
* that has been signed by the master key. Revoked and (for signing!)
* expired keys are skipped. Runs in its own read-only transaction (hence no
* session provided).
*
* @param cls the @e cls of this struct with the plugin-specific state
* @param cb function to call on each signing key
* @param cb_cls closure for @a cb
* @return transaction status code
*/
enum GNUNET_DB_QueryStatus
(*iterate_active_signkeys)(void *cls,
TALER_EXCHANGEDB_ActiveSignkeysCallback cb,
void *cb_cls);
/**
* Function called to invoke @a cb on every active auditor. Disabled
* auditors are skipped. Runs in its own read-only transaction (hence no
* session provided).
*
* @param cls the @e cls of this struct with the plugin-specific state
* @param cb function to call on each active auditor
* @param cb_cls closure for @a cb
* @return transaction status code
*/
enum GNUNET_DB_QueryStatus
(*iterate_active_auditors)(void *cls,
TALER_EXCHANGEDB_AuditorsCallback cb,
void *cb_cls);
/**
* Function called to invoke @a cb on every denomination with an active
* auditor. Disabled auditors and denominations without auditor are
* skipped. Runs in its own read-only transaction (hence no session
* provided).
*
* @param cls the @e cls of this struct with the plugin-specific state
* @param cb function to call on each active auditor-denomination pair
* @param cb_cls closure for @a cb
* @return transaction status code
*/
enum GNUNET_DB_QueryStatus
(*iterate_auditor_denominations)(
void *cls,
TALER_EXCHANGEDB_AuditorDenominationsCallback cb,
void *cb_cls);
/**
* Get the summary of a reserve.
*