mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-20 07:34:24 +01:00
test/test_state_coverage: Check that it terminates.
The state machine is infinite, but if we eliminate the normal inner state loop, and a couple of other unusual cases where inputs can repeat, we should be able to traverse it all. This is slower than simply stopping when we hit a repeated state though. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
@@ -533,6 +533,7 @@ static void copy_peers(struct state_data *dst, struct state_data *peer,
|
|||||||
/* Recursion! */
|
/* Recursion! */
|
||||||
static struct trail *run_peer(const struct state_data *sdata,
|
static struct trail *run_peer(const struct state_data *sdata,
|
||||||
bool normalpath, bool errorpath,
|
bool normalpath, bool errorpath,
|
||||||
|
size_t depth,
|
||||||
struct hist *hist);
|
struct hist *hist);
|
||||||
|
|
||||||
/* Returns false if we've been here before. */
|
/* Returns false if we've been here before. */
|
||||||
@@ -822,6 +823,7 @@ static const char *simplify_state(enum state s)
|
|||||||
static struct trail *try_input(const struct state_data *sdata,
|
static struct trail *try_input(const struct state_data *sdata,
|
||||||
enum state_input i,
|
enum state_input i,
|
||||||
bool normalpath, bool errorpath,
|
bool normalpath, bool errorpath,
|
||||||
|
size_t depth,
|
||||||
struct hist *hist)
|
struct hist *hist)
|
||||||
{
|
{
|
||||||
struct state_data copy, peer;
|
struct state_data copy, peer;
|
||||||
@@ -875,9 +877,21 @@ static struct trail *try_input(const struct state_data *sdata,
|
|||||||
|
|
||||||
/* Have we been in this overall situation before? */
|
/* Have we been in this overall situation before? */
|
||||||
if (!sithash_update(&hist->sithash, ©)) {
|
if (!sithash_update(&hist->sithash, ©)) {
|
||||||
|
/*
|
||||||
|
* We expect to loop if:
|
||||||
|
* 1) We deferred, OR
|
||||||
|
* 2) We get repeated BITCOIN_ANCHOR_OTHERSPEND, OR
|
||||||
|
* 3) We pass through NORMAL state.
|
||||||
|
*/
|
||||||
|
if (effect->defer != INPUT_NONE
|
||||||
|
|| newstate == STATE_NORMAL_LOWPRIO
|
||||||
|
|| i == BITCOIN_ANCHOR_OTHERSPEND) {
|
||||||
tal_free(effect);
|
tal_free(effect);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
if (depth > STATE_MAX * 10)
|
||||||
|
return new_trail(i, sdata, newstate, effect, "Loop");
|
||||||
|
}
|
||||||
|
|
||||||
/* Don't continue if we reached a different error state. */
|
/* Don't continue if we reached a different error state. */
|
||||||
if (state_is_error(newstate)) {
|
if (state_is_error(newstate)) {
|
||||||
@@ -903,9 +917,9 @@ static struct trail *try_input(const struct state_data *sdata,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Try inputs from here down. */
|
/* Try inputs from here down. */
|
||||||
t = run_peer(©, normalpath, errorpath, hist);
|
t = run_peer(©, normalpath, errorpath, depth+1, hist);
|
||||||
if (!t)
|
if (!t)
|
||||||
t = run_peer(&peer, normalpath, errorpath, hist);
|
t = run_peer(&peer, normalpath, errorpath, depth+1, hist);
|
||||||
if (!t) {
|
if (!t) {
|
||||||
tal_free(effect);
|
tal_free(effect);
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -943,6 +957,7 @@ static void activate_event(struct state_data *sdata, enum state_input i)
|
|||||||
|
|
||||||
static struct trail *run_peer(const struct state_data *sdata,
|
static struct trail *run_peer(const struct state_data *sdata,
|
||||||
bool normalpath, bool errorpath,
|
bool normalpath, bool errorpath,
|
||||||
|
size_t depth,
|
||||||
struct hist *hist)
|
struct hist *hist)
|
||||||
{
|
{
|
||||||
struct state_data copy, peer;
|
struct state_data copy, peer;
|
||||||
@@ -965,7 +980,7 @@ static struct trail *run_peer(const struct state_data *sdata,
|
|||||||
if (i != BITCOIN_ANCHOR_OTHERSPEND)
|
if (i != BITCOIN_ANCHOR_OTHERSPEND)
|
||||||
copy.event_notifies &= ~(1ULL << i);
|
copy.event_notifies &= ~(1ULL << i);
|
||||||
activate_event(©, i);
|
activate_event(©, i);
|
||||||
t = try_input(©, i, normalpath, errorpath, hist);
|
t = try_input(©, i, normalpath, errorpath, depth, hist);
|
||||||
if (t)
|
if (t)
|
||||||
return t;
|
return t;
|
||||||
copy.event_notifies = old_notifies;
|
copy.event_notifies = old_notifies;
|
||||||
@@ -989,7 +1004,8 @@ static struct trail *run_peer(const struct state_data *sdata,
|
|||||||
for (i = 0; i < sizeof(cmds) / sizeof(cmds[i]); i++) {
|
for (i = 0; i < sizeof(cmds) / sizeof(cmds[i]); i++) {
|
||||||
copy.current_command = cmds[i];
|
copy.current_command = cmds[i];
|
||||||
t = try_input(©, cmds[i],
|
t = try_input(©, cmds[i],
|
||||||
normalpath, errorpath, hist);
|
normalpath, errorpath, depth,
|
||||||
|
hist);
|
||||||
if (t)
|
if (t)
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
@@ -1007,7 +1023,8 @@ static struct trail *run_peer(const struct state_data *sdata,
|
|||||||
i = copy.deferred_pkt;
|
i = copy.deferred_pkt;
|
||||||
copy.deferred_pkt = INPUT_NONE;
|
copy.deferred_pkt = INPUT_NONE;
|
||||||
return try_input(©, i,
|
return try_input(©, i,
|
||||||
normalpath, errorpath, hist);
|
normalpath, errorpath, depth,
|
||||||
|
hist);
|
||||||
}
|
}
|
||||||
/* Can't send anything until that's done. */
|
/* Can't send anything until that's done. */
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -1020,7 +1037,8 @@ static struct trail *run_peer(const struct state_data *sdata,
|
|||||||
memmove(peer.outputs, peer.outputs + 1,
|
memmove(peer.outputs, peer.outputs + 1,
|
||||||
sizeof(peer.outputs) - sizeof(peer.outputs[0]));
|
sizeof(peer.outputs) - sizeof(peer.outputs[0]));
|
||||||
peer.num_outputs--;
|
peer.num_outputs--;
|
||||||
return try_input(©, i, normalpath, errorpath, hist);
|
return try_input(©, i, normalpath, errorpath, depth,
|
||||||
|
hist);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -1148,7 +1166,7 @@ int main(int argc, char *argv[])
|
|||||||
abort();
|
abort();
|
||||||
|
|
||||||
/* Now, try each input in each state. */
|
/* Now, try each input in each state. */
|
||||||
t = run_peer(&a, true, false, &hist);
|
t = run_peer(&a, true, false, 0, &hist);
|
||||||
if (t) {
|
if (t) {
|
||||||
report_trail(t);
|
report_trail(t);
|
||||||
exit(1);
|
exit(1);
|
||||||
@@ -1158,7 +1176,7 @@ int main(int argc, char *argv[])
|
|||||||
do_decline = true;
|
do_decline = true;
|
||||||
sithash_init(&hist.sithash);
|
sithash_init(&hist.sithash);
|
||||||
sithash_update(&hist.sithash, &a);
|
sithash_update(&hist.sithash, &a);
|
||||||
t = run_peer(&a, true, false, &hist);
|
t = run_peer(&a, true, false, 0, &hist);
|
||||||
if (t) {
|
if (t) {
|
||||||
report_trail(t);
|
report_trail(t);
|
||||||
exit(1);
|
exit(1);
|
||||||
|
|||||||
Reference in New Issue
Block a user