Skip to content

test(mbt): Add Model Based Test for Emerald#201

Open
erickpintor wants to merge 1 commit intoerick/mbt-decide-on-roundfrom
erick/introduce-mbt-suite
Open

test(mbt): Add Model Based Test for Emerald#201
erickpintor wants to merge 1 commit intoerick/mbt-decide-on-roundfrom
erick/introduce-mbt-suite

Conversation

@erickpintor
Copy link
Collaborator

@erickpintor erickpintor commented Jan 29, 2026

This patch connects the newly added Quint specs to Emerald's code via the Quint Connect library.

PS: the best files to start reviewing are probable tests.rs and driver.rs.

@erickpintor erickpintor requested a review from a team as a code owner January 29, 2026 13:26
@erickpintor erickpintor force-pushed the erick/introduce-mbt-suite branch 4 times, most recently from 029e72f to d09bd51 Compare January 29, 2026 21:14
@erickpintor erickpintor changed the base branch from erick/fix-reth-recreate to erick/mbt-reset-timeouts January 29, 2026 21:14
Comment on lines 50 to 80
#[quint_run(
spec = "../../specs/emerald_mbt.qnt",
step = "step_no_failures",
max_samples = 32,
max_steps = 128
)]
fn simulation_no_failures() -> impl Driver {
EmeraldDriver::default()
}

#[quint_run(
spec = "../../specs/emerald_mbt.qnt",
step = "step_with_failures",
max_samples = 32,
max_steps = 128
)]
fn simulation_with_failures() -> impl Driver {
EmeraldDriver::default()
}
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First uncached run took about 30m in the CI. Let me know if you want to generate fewer traces or reduce the number of steps to minimize test time.

@erickpintor erickpintor requested a review from bugarela January 29, 2026 22:04
Copy link
Collaborator

@bugarela bugarela left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All good from my side!

@erickpintor erickpintor force-pushed the erick/mbt-reset-timeouts branch from 9b46ba5 to 6343e8e Compare February 3, 2026 14:25
@erickpintor erickpintor force-pushed the erick/introduce-mbt-suite branch 4 times, most recently from 58ca2f7 to 1de9af2 Compare February 3, 2026 15:23
@erickpintor erickpintor force-pushed the erick/mbt-reset-timeouts branch from 6343e8e to b9b7e32 Compare February 4, 2026 13:25
@erickpintor erickpintor force-pushed the erick/introduce-mbt-suite branch from 1de9af2 to 54fca10 Compare February 4, 2026 13:28
@erickpintor erickpintor force-pushed the erick/mbt-reset-timeouts branch from b9b7e32 to 133095a Compare February 4, 2026 13:30
Base automatically changed from erick/mbt-reset-timeouts to main February 4, 2026 13:45
@erickpintor erickpintor force-pushed the erick/introduce-mbt-suite branch 3 times, most recently from 3d62414 to 805fcc9 Compare February 4, 2026 16:56
let res = Command::new("make")
.env("RETH_NODES", nodes)
.arg(cmd)
.current_dir("../..")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we use absolute path here?

you may use CARGO_MANIFEST_DIR.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems like CARGO_MANIFEST_DIR points to tests/mbt. I had to make the path relative to that directory anyway. Lemme know if you want me to try something else.

impl Runtime {
pub fn new(temp_dir: TempDir) -> Result<Self> {
Ok(Self {
tokio: tokio::runtime::Runtime::new()?,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not TokioRt::new() ?

/// creating one Emerald and Reth instance per [crate::NODES].
pub fn init(&mut self) -> Result<()> {
// Reset the driver
*self = Default::default();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you explain this line ?

I would rather prefer pub fn reinit(self) -> Result<Self> { ... }

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The intent is to reset the state of the driver to its default (empty) state. I could extract it into a function but, it'd just be a function that returns Self::default().

impl EmeraldDriver {
/// Locates the system under test and use the driver's runtime to wait for
/// the execution of the given future.
pub fn perform<'a, F, Fut>(&'a mut self, node: Node, action: F) -> Result<()>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

curious why this is implemented separately.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't want pollute the driver.rs file with helper functions. The driver is the main entry point into the MBT code and I usually try to keep it clean and focused on the translation between quint actions and its associated code. Happy to move things around if needed, though.

Comment on lines +18 to +19
let peer_id = PeerId::from_multihash(Default::default())
.map_err(|err| anyhow!("Failed to create peer id: {err:?}"))?;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so, it's always from the same peer_id?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. Because we deliver all parts at once, I didn't find that to be a problem. I can try and make for some randomized ids if you think it can improve coverage.

Comment on lines +15 to +16
F: FnOnce(&'a mut Sut, &'a mut History) -> Fut,
Fut: Future<Output = Result<()>>,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't know if it'll fit nicely but there exists AsyncFnOnce.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fought the borrow checker for 5m and didn't win. AsyncFnOnce seems like an nice interface. I'll try again later and see if I get a better luck.

@erickpintor erickpintor force-pushed the erick/introduce-mbt-suite branch from 2f24a10 to c083964 Compare February 5, 2026 22:05
@erickpintor erickpintor changed the base branch from main to erick/mbt-decide-on-round February 5, 2026 22:06
@erickpintor
Copy link
Collaborator Author

@rnbguy thank you for the detailed review 🙏

I've addressed most comments and left a few replies.

This patch connects the newly added Quint specs to Emerald's code via
the Quint Connect library.
@erickpintor erickpintor force-pushed the erick/introduce-mbt-suite branch from c083964 to ffc1a1e Compare February 5, 2026 22:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants