simplify credit history computation

This commit is contained in:
Christian Grothoff 2020-01-15 22:47:20 +01:00
parent a5395c2065
commit 4c5c63e9b9
No known key found for this signature in database
GPG Key ID: 939E6BE1E29FC3CC
2 changed files with 68 additions and 167 deletions

View File

@ -150,9 +150,9 @@ print_expected (struct History *h,
unsigned int off) unsigned int off)
{ {
GNUNET_log (GNUNET_ERROR_TYPE_ERROR, GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Transaction history missmatch at position %u/%llu\n", "Transaction history missmatch at position %u/%u\n",
off, off,
(unsigned long long) h_len); h_len);
GNUNET_log (GNUNET_ERROR_TYPE_ERROR, GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Expected history:\n"); "Expected history:\n");
for (unsigned int i = 0; i<h_len; i++) for (unsigned int i = 0; i<h_len; i++)
@ -187,6 +187,7 @@ build_history (struct TALER_TESTING_Interpreter *is,
{ {
struct HistoryState *hs = is->commands[is->ip].cls; struct HistoryState *hs = is->commands[is->ip].cls;
unsigned int total; unsigned int total;
unsigned int pos;
struct History *h; struct History *h;
const struct TALER_TESTING_Command *add_incoming_cmd; const struct TALER_TESTING_Command *add_incoming_cmd;
int inc; int inc;
@ -235,192 +236,96 @@ build_history (struct TALER_TESTING_Interpreter *is,
end = 0; end = 0;
} }
total = 0;
ok = GNUNET_NO; ok = GNUNET_NO;
if (NULL == row_id_start) if (NULL == row_id_start)
ok = GNUNET_YES; ok = GNUNET_YES;
h = NULL;
// FIXME: simplify logic by folding the TWO loops into ONE, total = 0;
// (first doubling h if needed, and finally shrinking h to required size) GNUNET_array_grow (h,
total,
/* This loop counts how many commands _later than "start"_ belong 4);
* to the history of the caller. This is stored in the @var total pos = 0;
* variable. */
for (unsigned int off = start; off != end + inc; off += inc) for (unsigned int off = start; off != end + inc; off += inc)
{ {
const struct TALER_TESTING_Command *pos = &is->commands[off]; const struct TALER_TESTING_Command *cmd = &is->commands[off];
const uint64_t *row_id; const uint64_t *row_id;
const char *credit_account; const char *credit_account;
const char *debit_account; const char *debit_account;
const struct TALER_Amount *amount;
const struct TALER_ReservePublicKeyP *reserve_pub;
const char *account_url;
/* The following command allows us to skip over those CMDs /* The following command allows us to skip over those CMDs
* that do not offer a "row_id" trait. Such skipped CMDs are * that do not offer a "row_id" trait. Such skipped CMDs are
* not interesting for building a history. */// * not interesting for building a history. *///
if (GNUNET_OK != if ( (GNUNET_OK !=
TALER_TESTING_get_trait_bank_row (pos, TALER_TESTING_get_trait_bank_row (cmd,
&row_id)) &row_id)) ||
continue; (GNUNET_OK !=
TALER_TESTING_get_trait_payto (cmd,
TALER_TESTING_PT_CREDIT,
&credit_account)) ||
(GNUNET_OK !=
TALER_TESTING_get_trait_payto (cmd,
TALER_TESTING_PT_DEBIT,
&debit_account)) ||
(GNUNET_OK ==
TALER_TESTING_get_trait_amount_obj (cmd,
0,
&amount)) ||
(GNUNET_OK ==
TALER_TESTING_get_trait_reserve_pub (cmd,
0,
&reserve_pub)) ||
(GNUNET_OK ==
TALER_TESTING_get_trait_url (cmd,
1,
&account_url)) )
continue; /* not an interesting event */
/* Seek "/history" starting row. */ /* Seek "/history" starting row. */
if (NULL != row_id_start) if ( (NULL != row_id_start) &&
(*row_id_start == *row_id) &&
(GNUNET_NO == ok) )
{ {
if (*row_id_start == *row_id) /* Until here, nothing counted. */
{
/* Doesn't count, start is excluded from output. */
total = 0;
ok = GNUNET_YES; ok = GNUNET_YES;
continue; continue;
} }
}
/* when 'start' was _not_ given, then ok == GNUNET_YES */ /* when 'start' was _not_ given, then ok == GNUNET_YES */
if (GNUNET_NO == ok) if (GNUNET_NO == ok)
continue; /* skip until we find the marker */ continue; /* skip until we find the marker */
if (0 != strcasecmp (hs->account_url,
TALER_LOG_DEBUG ("Found first row\n"); credit_account))
continue; /* account missmatch */
if (total >= GNUNET_MAX (hs->num_results, if (total >= GNUNET_MAX (hs->num_results,
-hs->num_results) ) -hs->num_results) )
{ {
TALER_LOG_DEBUG ("Hit history limit\n"); TALER_LOG_DEBUG ("Hit history limit\n");
break; break;
} }
GNUNET_assert (GNUNET_OK == TALER_LOG_INFO ("Found history: %s->%s for account %s\n",
TALER_TESTING_get_trait_payto (pos,
TALER_TESTING_PT_CREDIT,
&credit_account));
GNUNET_assert (GNUNET_OK ==
TALER_TESTING_get_trait_payto (pos,
TALER_TESTING_PT_DEBIT,
&debit_account));
TALER_LOG_INFO ("Potential history element:"
" %s->%s; my account: %s\n",
debit_account, debit_account,
credit_account, credit_account,
hs->account_url); hs->account_url);
/* found matching record, make sure we have room */
if (0 == strcasecmp (hs->account_url, if (pos == total)
credit_account)) GNUNET_array_grow (h,
{ total,
TALER_LOG_INFO ("+1 my history\n"); pos * 2);
total++; /* found matching record */
}
}
GNUNET_assert (GNUNET_YES == ok);
if (0 == total)
{
TALER_LOG_DEBUG ("Checking history with ZERO transactions\n");
*rh = NULL;
return 0;
}
h = GNUNET_new_array (total,
struct History);
total = 0;
ok = GNUNET_NO;
if (NULL == row_id_start)
ok = GNUNET_YES;
/**
* This loop _only_ populates the array of history elements.
*/
for (unsigned int off = start; off != end + inc; off += inc)
{
const struct TALER_TESTING_Command *pos = &is->commands[off];
const uint64_t *row_id;
char *bank_hostname;
const char *credit_account;
const char *debit_account;
if (GNUNET_OK !=
TALER_TESTING_get_trait_bank_row (pos,
&row_id))
continue;
if (NULL != row_id_start)
{
if (*row_id_start == *row_id)
{
/**
* Warning: this zeroing is superfluous, as
* total doesn't get incremented if 'start'
* was given and couldn't be found.
*/total = 0;
ok = GNUNET_YES;
continue;
}
}
TALER_LOG_INFO ("Found first row (2)\n");
if (GNUNET_NO == ok)
{
TALER_LOG_INFO ("Skip on `%s'\n",
pos->label);
continue; /* skip until we find the marker */
}
if (total >= GNUNET_MAX (hs->num_results,
-hs->num_results) )
{
TALER_LOG_INFO ("Hit history limit (2)\n");
break;
}
GNUNET_assert (GNUNET_OK ==
TALER_TESTING_get_trait_payto (pos,
TALER_TESTING_PT_CREDIT,
&credit_account));
GNUNET_assert (GNUNET_OK ==
TALER_TESTING_get_trait_payto (pos,
TALER_TESTING_PT_DEBIT,
&debit_account));
TALER_LOG_INFO ("Potential history bit: %s->%s; my account: %s\n",
debit_account,
credit_account,
hs->account_url);
bank_hostname = strchr (hs->account_url, ':');
GNUNET_assert (NULL != bank_hostname);
bank_hostname += 3;
/* Next two blocks only put the 'direction' and 'banking'
* information. */
/* Asked for credit, and account got the credit. */
if (0 == strcasecmp (hs->account_url,
credit_account))
{
const struct TALER_Amount *amount;
const struct TALER_ReservePublicKeyP *reserve_pub;
const char *account_url;
GNUNET_assert (GNUNET_OK ==
TALER_TESTING_get_trait_amount_obj (pos,
0,
&amount));
GNUNET_assert (GNUNET_OK ==
TALER_TESTING_get_trait_reserve_pub (pos,
0,
&reserve_pub));
GNUNET_assert (GNUNET_OK ==
TALER_TESTING_get_trait_url (pos,
1,
&account_url));
h[total].url = GNUNET_strdup (debit_account); h[total].url = GNUNET_strdup (debit_account);
h[total].details.debit_account_url = h[total].url; h[total].details.debit_account_url = h[total].url;
h[total].details.amount = *amount; h[total].details.amount = *amount;
h[total].row_id = *row_id; h[total].row_id = *row_id;
h[total].details.reserve_pub = *reserve_pub; h[total].details.reserve_pub = *reserve_pub;
h[total].details.credit_account_url = account_url; h[total].details.credit_account_url = account_url;
TALER_LOG_INFO ("+1-bit of my history\n"); pos++;
total++;
}
} }
GNUNET_assert (GNUNET_YES == ok);
GNUNET_array_grow (h,
total,
pos);
if (0 == pos)
TALER_LOG_DEBUG ("Empty credit history computed\n");
*rh = h; *rh = h;
return total; return total;
} }

View File

@ -149,9 +149,9 @@ print_expected (struct History *h,
unsigned int off) unsigned int off)
{ {
GNUNET_log (GNUNET_ERROR_TYPE_ERROR, GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Transaction history missmatch at position %u/%llu\n", "Transaction history missmatch at position %u/%u\n",
off, off,
(unsigned long long) h_len); h_len);
GNUNET_log (GNUNET_ERROR_TYPE_ERROR, GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Expected history:\n"); "Expected history:\n");
for (unsigned int i = 0; i<h_len; i++) for (unsigned int i = 0; i<h_len; i++)
@ -281,7 +281,7 @@ build_history (struct TALER_TESTING_Interpreter *is,
(*row_id_start == *row_id) && (*row_id_start == *row_id) &&
(GNUNET_NO == ok) ) (GNUNET_NO == ok) )
{ {
/* Until here nothing counted */ /* Until here, nothing counted. */
ok = GNUNET_YES; ok = GNUNET_YES;
continue; continue;
} }
@ -319,11 +319,7 @@ build_history (struct TALER_TESTING_Interpreter *is,
total, total,
pos); pos);
if (0 == pos) if (0 == pos)
{ TALER_LOG_DEBUG ("Empty debit history computed\n");
TALER_LOG_DEBUG ("Empty history computed\n");
*rh = NULL;
return 0;
}
*rh = h; *rh = h;
return total; return total;
} }