Skip to content

test: sync operators on a four-node BFT synchronizer - #63

Merged
sadiq1971 merged 15 commits into
mainfrom
feat/dedicated-sync-bft-localnet
Oct 14, 2026
Merged

sadiq1971 merged 15 commits into
mainfrom
feat/dedicated-sync-bft-localnet

Conversation

@sadiq1971

@sadiq1971 sadiq1971 commented Sep 29, 2026 •

Copy link
Copy Markdown
Collaborator

Part of ChainSafe/canton-extending-mainnet#106

Summary: adds an integration test that runs a dedicated synchronizer on four BFT nodes, one sync operator per node, and checks that all four nodes grant a traffic purchase and agree on what it consumes. LocalNet stays single-node.

Adds a -B LocalNet profile that runs the app-synchronizer on four BFT
nodes, each run by its own org with its own participant and sync
operator. At startup the four orgs create the operator party together:
they own its namespace and host it on their participants. A fifth node
and its org come up outside the synchronizer.

LocalNetDedicatedSyncBftIntegrationTest checks that purchases and
consumption agree on every node and org, that node 5 and its org join
and leave, and that the synchronizer keeps ordering with one node down
but not with two.

The extra nodes and apps use small connection pools, so LocalNet stays
under its Postgres connection limit.

Signed-off-by: sadiq1971 <sadiqurr8@gmail.com>
Found by running the four-node LocalNet and its test locally:

- Each BFT orderer gets its own database. Its migrations create a debug
  schema that the node's storage had already created when both shared
  one database, so sequencer initialization failed.
- The test reaches the sequencers' public APIs through published
  localhost ports. Onboarding a sequencer calls them from the test,
  which cannot resolve the canton container's name.
- The participant reconnects after switching to node 5 as its only
  sequencer, as a changed connection only takes effect on reconnect.

Also formats the test.

Signed-off-by: sadiq1971 <sadiqurr8@gmail.com>
The startup script skips sync operator users that already exist, so
starting the four-node LocalNet again without -D no longer fails. The
sequencer threshold proposal now waits a bounded time, so a BFT network
that never forms fails the startup instead of hanging it.

Signed-off-by: sadiq1971 <sadiqurr8@gmail.com>
traffic_state_of_members_at_timestamp does not return the state at the
given timestamp (see its TODO #25930), so the four-node test reads each
node's latest state directly and no longer claims one timestamp.

Signed-off-by: sadiq1971 <sadiqurr8@gmail.com>
@sadiq1971
sadiq1971 force-pushed the feat/dedicated-sync-bft-localnet branch from 96f0fce to a3e10b8 Compare October 4, 2026 21:43
@sadiq1971
sadiq1971 changed the base branch from feat/sync-operator-lsu to main October 4, 2026 21:44
Main drops the shared LocalNet test base and the LocalNet upgrade setup,
and its sync operator only configures its sequencer. The four-node test
now carries its own helpers, as the other LocalNet tests do, and the
extra sync operators only point at their own participant and sequencer.

Signed-off-by: sadiq1971 <sadiqurr8@gmail.com>
@sadiq1971
sadiq1971 force-pushed the feat/dedicated-sync-bft-localnet branch from a3e10b8 to bd3d2bb Compare October 4, 2026 21:48
@sadiq1971 sadiq1971 self-assigned this Oct 5, 2026
@sadiq1971
sadiq1971 marked this pull request as ready for review October 5, 2026 12:22

@moritzkiefer-da moritzkiefer-da left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

please stop putting every test in localnet.

As I mentioned on an earlier PR, localnet is for app devs to have a low resource and easy way to spin up something they can test against. A single node is perfectly sufficient for that, from an app dev's perspective it's irrelveant whether the synchronizer is decentralized.

For us, localnet tests are strictly worse. Instead of just running an integration test you now need to first build the docker images which takes much much longer and running the compose setup then often takes more resources.

@sadiq1971

Copy link
Copy Markdown
Collaborator Author

please stop putting every test in localnet.

As I mentioned on an earlier PR, localnet is for app devs to have a low resource and easy way to spin up something they can test against. A single node is perfectly sufficient for that, from an app dev's perspective it's irrelveant whether the synchronizer is decentralized.

For us, localnet tests are strictly worse. Instead of just running an integration test you now need to first build the docker images which takes much much longer and running the compose setup then often takes more resources.

I think that was in my mind and actually wanted to ask about it for the 4 node bft testing. As the PR was placed earlier so it added those tests- but Please confirm how we gonna proceed on this-

  1. Right now the setup is for localnet and we want to keep that right?
  2. We don't have any setup on splice tests for the 4 node bft
    So how we gonna test it? Do we exclude it from ci and have some sort of testing for locally? Or any other way?

@moritzkiefer-da

Copy link
Copy Markdown

Right now the setup is for localnet and we want to keep that right?

no we don't, localnet should just be a single node.

We don't have any setup on splice tests for the 4 node bft
So how we gonna test it? Do we exclude it from ci and have some sort of testing for locally? Or any other way?

extend the CI to test with 4 nodes.

Removes the four-node app-synchronizer profile (-B) and its LocalNet test.
The four-node setup moves to a Splice integration test.

Signed-off-by: sadiq1971 <sadiqurr8@gmail.com>
Starts a dedicated synchronizer on four BFT nodes with one sync operator
per node, and checks that every node grants a traffic purchase and that
the nodes agree on what it consumes. Runs in the sync-operator CI job.

Signed-off-by: sadiq1971 <sadiqurr8@gmail.com>
@sadiq1971 sadiq1971 changed the title feat: four-node BFT app-synchronizer in LocalNet test: sync operators on a four-node BFT synchronizer Oct 6, 2026
@sadiq1971

Copy link
Copy Markdown
Collaborator Author

Right now the setup is for localnet and we want to keep that right?

no we don't, localnet should just be a single node.

We don't have any setup on splice tests for the 4 node bft
So how we gonna test it? Do we exclude it from ci and have some sort of testing for locally? Or any other way?

extend the CI to test with 4 nodes.

Updated

@isegall-da

Copy link
Copy Markdown

@sadiq1971 I presume you're aware that your test is failing, and that you're looking into it?

The test JVM's Canton console asks a sequencer for its protocol version
over the public API while generating the genesis state, which an
uninitialized sequencer cannot answer. The four-node Canton now runs a
bootstrap script instead, as start-canton.sh does with bootstrap-canton.sc.

Also matches the other sync operator tests with
withOnlyAliceValidatorConnectingToSplitwell, waits for traffic control on
every node before the operators start, and formats the test.

Signed-off-by: sadiq1971 <sadiqurr8@gmail.com>
Signed-off-by: sadiq1971 <sadiqurr8@gmail.com>
@sadiq1971

Copy link
Copy Markdown
Collaborator Author

@sadiq1971 I presume you're aware that your test is failing, and that you're looking into it?

Yup. Will ping you once the CI is clean.

@sadiq1971

Copy link
Copy Markdown
Collaborator Author

@isegall-da Looks good now.

@sadiq1971
sadiq1971 requested a review from isegall-da October 8, 2026 15:06
Comment thread apps/app/src/test/resources/standalone-sync-operator-bft-bootstrap.sc Outdated
…embers [ci]

Bootstraps the four-node synchronizer at protocol version 36, the version
the global synchronizer runs in the tests, and checks that the synchronizer
lists all four sequencers and all four mediators with Splice's thresholds.

Signed-off-by: sadiq1971 <sadiqurr8@gmail.com>
Traffic control is now on from the bootstrap, as on a dedicated
synchronizer. The participant joins by handshake alone, which needs no
traffic and makes it a member the operators grant to, then buys traffic
and only then connects. The operators drop a purchase for a member the
synchronizer does not know yet (ChainSafe/canton-extending-mainnet#116),
so the purchase cannot come before the join.

Signed-off-by: sadiq1971 <sadiqurr8@gmail.com>

@moritzkiefer-da moritzkiefer-da left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

thanks

Signed-off-by: sadiq1971 <sadiqurr8@gmail.com>
Signed-off-by: sadiq1971 <sadiqurr8@gmail.com>
Like the other sync operator suites, the test registers a synchronizer,
which needs splice-dso-governance 0.1.30, so the compatibility run against
older packages skips it instead of failing it.

Signed-off-by: sadiq1971 <sadiqurr8@gmail.com>
Signed-off-by: sadiq1971 <sadiqurr8@gmail.com>
@sadiq1971
sadiq1971 merged commit e653ece into main Oct 14, 2026
124 of 126 checks passed
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