NethermindEth / NethermindEth/pluto

Rewrite `core/qbft` to async-Rust-friendly API

Open
#393 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

enhancement rust track:duty-pipeline
Dominant language
Rust
Stars
8
Forks
5
Avg merge
4d 16h
Merged PRs (30d)
37

Description

Context

The current Rust port of core/qbft (crates/core/src/qbft/mod.rs) is a faithful translation of the Go reference but built on synchronous, thread-based primitives:

  • crossbeam::channel for transport
  • std::thread::scope for spawning per-process workers
  • A blocking pub fn run(...) entry point
  • cancellation::CancellationToken (third-party crate, not tokio_util)

This is at odds with the rest of Pluto, which is tokio-async end to end. Every consumer that will eventually wire QBFT in (core/consensus, core/scheduler, the duty pipeline) is async. The current shape forces either (a) bridging via spawn_blocking and ad-hoc channel adapters, or (b) blocking inside async tasks — both bad.

Closes the gap left by #13, which produced the initial sync port.

Goal

Rewrite core/qbft with an async-Rust-native API that integrates cleanly with the rest of the workspace and preserves the Byzantine-safety guarantees of the Go reference.

Scope

API
  • run becomes pub async fn run(...) -> Result<Decision, QbftError>
  • Transport trait methods return impl Future<Output = Result<...>> + Send (or are async fn via trait async)
  • Cancellation uses tokio_util::sync::CancellationToken (already used elsewhere in Pluto)
  • Channels: tokio::sync::mpsc (and oneshot where appropriate)
  • No std::thread, no crossbeam, no std::sync::mpsc anywhere in the public or internal API
Internals
  • Replace thread::scope with tokio::spawn + JoinSet (or select! for per-instance loops)
  • Replace blocking sleeps/timers with tokio::time::sleep / Interval
  • Clock abstraction (fake_clock.rs) becomes async-aware so deterministic tests still work — likely using tokio::time::pause() + advance() rather than the current fake clock
  • Keep the algorithm shape (rounds, justifications, message bookkeeping) bit-for-bit identical to the Go reference — only the concurrency primitives change
Safety net (mandatory)
  • Port charon/core/consensus/qbft/strategysim_internal_test.go (~1040 LOC) as the parity gate. This is the test that catches BFT correctness regressions; without it we cannot trust the rewrite.
  • All current crates/core/src/qbft/internal_test.rs cases pass (or are replaced by equivalent async versions)

Acceptance criteria

  • Public API is fully async; no pub fn run blocking entry point remains
  • No crossbeam, std::thread, or third-party cancellation crate usage in crates/core/src/qbft/
  • All existing QBFT unit tests pass (rewritten as async where needed)
  • Strategysim parity test ported from Go and green
  • cargo clippy --workspace --all-targets --all-features -- -D warnings clean
  • cargo +nightly fmt --all --check clean
  • Public API documented; missing_docs warning re-enabled for the module

References

Notes

This is on the critical path for the duty-flow pipeline. core/consensus (#157) and downstream modules (core/scheduler #176, etc.) will consume the new async API directly, so this should land before consensus framework integration begins.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with crates/core/src/qbft/mod.rs and its internal_test.rs, then compare the Go reference and strategysim_internal_test.go. Run the existing QBFT tests before changing the concurrency model. Done means an async public API, equivalent async tests including strategysim parity, clean clippy and formatting, and documented public items.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
distributed-systems
Issue type
Refactor
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.