Browse Source

test/test_protocol: keep cache of state with all changes applied.

This makes it easier to test for validity, though we still double-check
that a change doesn't overlap previous changes.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
ppa-0.6.1
Rusty Russell 9 years ago
parent
commit
52db7ae0c4
  1. 76
      test/test_protocol.c

76
test/test_protocol.c

@ -29,6 +29,8 @@ struct commit_info {
struct funding funding; struct funding funding;
/* Pending changes (for next commit_info) */ /* Pending changes (for next commit_info) */
int *changes_incoming, *changes_outgoing; int *changes_incoming, *changes_outgoing;
/* Cache of funding with changes applied. */
struct funding funding_next;
/* Have sent/received revocation secret. */ /* Have sent/received revocation secret. */
bool revoked; bool revoked;
/* Have their signature, ie. can be broadcast */ /* Have their signature, ie. can be broadcast */
@ -61,7 +63,27 @@ static bool have_htlc(u32 htlcs, unsigned int htlc)
return htlcs & htlc_mask(htlc); return htlcs & htlc_mask(htlc);
} }
static bool add_change_internal(struct commit_info *ci, int **changes, /* Each side can add their own incoming HTLC, or close your outgoing HTLC. */
static bool do_change(u32 *add, u32 *remove, u32 *fees, int htlc)
{
/* We ignore fee changes from them: they only count when reflected
* back to us via revocation. */
if (htlc == 0) {
if (fees)
(*fees)++;
} else if (htlc < 0) {
if (!have_htlc(*remove, -htlc))
return false;
*remove &= ~htlc_mask(-htlc);
} else {
if (have_htlc(*add, htlc))
return false;
*add |= htlc_mask(htlc);
}
return true;
}
static void add_change_internal(struct commit_info *ci, int **changes,
const u32 *add, const u32 *remove, const u32 *add, const u32 *remove,
int c) int c)
{ {
@ -73,19 +95,18 @@ static bool add_change_internal(struct commit_info *ci, int **changes,
/* Can't add/remove it already there/absent. */ /* Can't add/remove it already there/absent. */
if (c > 0 && have_htlc(*add, c)) if (c > 0 && have_htlc(*add, c))
return false; errx(1, "Already added htlc %u", c);
else if (c < 0 && !have_htlc(*remove, -c)) else if (c < 0 && !have_htlc(*remove, -c))
return false; errx(1, "Already removed htlc %u", -c);
/* Can't request add/remove twice. */ /* Can't request add/remove twice. */
for (i = 0; i < n; i++) for (i = 0; i < n; i++)
if ((*changes)[i] == c) if ((*changes)[i] == c)
return false; errx(1, "Already requestd htlc %+i", c);
add: add:
tal_resize(changes, n+1); tal_resize(changes, n+1);
(*changes)[n] = c; (*changes)[n] = c;
return true;
} }
/* /*
@ -97,11 +118,15 @@ static bool queue_changes_other(struct commit_info *ci, int *changes)
size_t i, n = tal_count(changes); size_t i, n = tal_count(changes);
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
if (!add_change_internal(ci, &ci->changes_outgoing, if (!do_change(&ci->funding_next.outhtlcs,
&ci->funding.outhtlcs, &ci->funding_next.inhtlcs,
&ci->funding.inhtlcs, &ci->funding_next.fee,
changes[i])) changes[i]))
return false; return false;
add_change_internal(ci, &ci->changes_outgoing,
&ci->funding.outhtlcs,
&ci->funding.inhtlcs,
changes[i]);
} }
return true; return true;
} }
@ -111,9 +136,13 @@ static bool queue_changes_other(struct commit_info *ci, int *changes)
*/ */
static bool add_incoming_change(struct commit_info *ci, int c) static bool add_incoming_change(struct commit_info *ci, int c)
{ {
return add_change_internal(ci, &ci->changes_incoming, if (!do_change(&ci->funding_next.inhtlcs, &ci->funding_next.outhtlcs,
&ci->funding.inhtlcs, &ci->funding.outhtlcs, NULL, c))
c); return false;
add_change_internal(ci, &ci->changes_incoming,
&ci->funding.inhtlcs, &ci->funding.outhtlcs,
c);
return true;
} }
static struct commit_info *new_commit_info(const tal_t *ctx, static struct commit_info *new_commit_info(const tal_t *ctx,
@ -126,29 +155,11 @@ static struct commit_info *new_commit_info(const tal_t *ctx,
if (prev) { if (prev) {
ci->number = prev->number + 1; ci->number = prev->number + 1;
ci->funding = prev->funding; ci->funding = prev->funding;
ci->funding_next = prev->funding_next;
} }
return ci; return ci;
} }
/* Each side can add their own incoming HTLC, or close your outgoing HTLC. */
static void do_change(u32 *add, u32 *remove, u32 *fees, int htlc)
{
/* We ignore fee changes from them: they only count when reflected
* back to us via revocation. */
if (htlc == 0) {
if (fees)
(*fees)++;
} else if (htlc < 0) {
if (!have_htlc(*remove, -htlc))
errx(1, "Already removed htlc %u", -htlc);
*remove &= ~htlc_mask(-htlc);
} else {
if (have_htlc(*add, htlc))
errx(1, "Already added htlc %u", htlc);
*add |= htlc_mask(htlc);
}
}
/* We duplicate the commit info, with the changes applied. */ /* We duplicate the commit info, with the changes applied. */
static struct commit_info *apply_changes(const tal_t *ctx, static struct commit_info *apply_changes(const tal_t *ctx,
struct commit_info *old) struct commit_info *old)
@ -171,7 +182,8 @@ static struct commit_info *apply_changes(const tal_t *ctx,
&ci->funding.inhtlcs, &ci->funding.inhtlcs,
&ci->funding.fee, &ci->funding.fee,
old->changes_outgoing[i]); old->changes_outgoing[i]);
assert(structeq(&ci->funding, &ci->funding_next));
return ci; return ci;
} }

Loading…
Cancel
Save