stateright / stateright

A model checker for implementing distributed systems.

Home Page:https://docs.rs/stateright

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Infinite generation of states

Nightcro opened this issue · comments

I recently tried to write the Ballot Leader Election with Gossiping using Stateright and encountered some issues along the way.

I can not stop Stateright from generating new states. Even though I added a maximum of rounds to stop the set-up of the timer, it keeps generating states.

Are there issues with using the function on_timeout?

Repo: https://github.com/Nightcro/ble-stateright

Hi @Nightcro. Thanks for reaching out and for trying the library!

There should not be a problem using on_timeout, and my first thought is that the state space may simply be very large. I'll review your code this weekend and follow up.

In the meantime, have you tried running this in the Explorer UI to manually explore some behavior paths? Sometimes that will reveal cases where a path continues to grow beyond what had been intended.

BTW one temporary caveat w that debugging technique is that Explorer uses BFS, which consumes quite a lot more memory.

@Nightcro, I had a chance to look into this today. The state space is large but finite. Here are some techniques for reducing the state space:

  1. Using a BTreeSet for BallotLeaderElectionState::ballots rather than a Vec helps.
  2. The amount of delay for a timeout only impacts the probability of particular behavior traces, not the possibilities (the state space), so there's no reason for the model to store or modify BallotLeaderElectionState::hb_delay. Of course, that state is still needed in "the real world" so one compromise is to only update that state if BallotLeaderElectionActor::max_round equals u32::MAX. Let me know if you're uneasy about this change, as I can explain further as to why it is safe.
  3. Reducing BallotLeaderElectionActor::max_round to 2 when checking also of course reduces the state space.

Those changes aren't sufficient to get the model checking time into a convenient range, and I think I need to make a library update. You're using DuplicatingNetwork::No, but these network semantics still allow for message reordering between source/destination pairs. The spec assumes perfect links, so introducing a more flexible notion of "network semantics" allowing you to opt in to message ordering as suggested by @graydon with #4 should also reduce the state space.

Thank you for the response and your explanation
I was thinking that the state space might be very large. But I wasn't expecting it to be so large just for 3 rounds. I will try to adapt the code using your hints, hope it will lower the state space.

@Nightcro Please see 41a861d for an upcoming feature that should dramatically reduce the state space in this example. The feature isn't yet ready for publishing (see details in the commit message), but you could pull the ordered-network branch locally and run your example against that in the meantime, i.e.

[dependencies]
stateright = { path="../stateright" }

If you hit any snags, just let me know, as I would be more than happy to send you a PR.

@Nightcro I merged e0648cf into the master branch, so I am resolving this issue.