Skip to content

Introduce hotswapping prod committee for dev committee#4235

Draft
vicsn wants to merge 2 commits intostagingfrom
test_fixed_dev_committee
Draft

Introduce hotswapping prod committee for dev committee#4235
vicsn wants to merge 2 commits intostagingfrom
test_fixed_dev_committee

Conversation

@vicsn
Copy link
Copy Markdown
Collaborator

@vicsn vicsn commented Apr 28, 2026

Motivation

E2E test would be more robust if we manage to fully replicate our production state and environment.

One blocker to this end is that snarkOS currently tightly couples ledger state and consensus. More concretely: a dev committee is not authorized to produce new blocks on top of production ledger state. This PR changes this by supporting hotswapping of a ledger without too many code changes through the use of a DEV_COMMITTEE_NUM_VALIDATORS environment variable and a --dev-on-prod flag. The relevant codepaths are compile-guarded by the test_network feature. I didn't introduce a new compilation feature to keep our testing environment simple.

The new settings enable the use of a production genesis block and disable checks on certificates. In order to avoid mutilating snarkVM, the entire call to check_next_block is skipped.

Open work

  • @vicsn Why can't we stop and start hotswapped networks? See the open TODO
  • @kaimast Is the trusted_ledger_certificate bool safe? Note that contrary to its name, sync_storage_with_ledger_at_bootup also runs after finishing fast-sync.
  • Is it worth the effort to get rid of DEV_COMMITTEE_NUM_VALIDATORS in favour of just having a flag? Properly compile-time guarding so many function signatures will be a pain.

Test Plan

  • New CI script passes
  • New prerelease workflow passes, still in development

@vicsn vicsn requested review from kaimast and ljedrz April 28, 2026 12:26
#[cfg(feature = "test_network")]
dev_start_round: Option<u64>,
#[cfg(feature = "test_network")]
dev_num_validators: Option<String>,
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

why not immediately expect a u16?


/// Returns the deterministic dev committee for rounds at or after the hotswap start.
#[cfg(feature = "test_network")]
fn dev_committee_for_round(&self, round: u64) -> Result<Option<Committee<N>>> {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

shouldn't this be created just once? current_committee is called routinely

fn get_committee_lookback_for_round(&self, round: u64) -> Result<Committee<N>> {
#[cfg(feature = "test_network")]
{
if let Some(dev_committee) = self.dev_committee_for_round(round)? {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

shouldn't this only be triggered if round >= dev_start_round?

Copy link
Copy Markdown
Collaborator

@ljedrz ljedrz left a comment

Choose a reason for hiding this comment

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

Left some initial comments.

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.

2 participants