Skip to content

PoC (draft): register dedicated synchronizers via governance (rung 1/2)#1

Draft
salindne wants to merge 5 commits into
mainfrom
multi-sync-poc-registration
Draft

PoC (draft): register dedicated synchronizers via governance (rung 1/2)#1
salindne wants to merge 5 commits into
mainfrom
multi-sync-poc-registration

Conversation

@salindne

@salindne salindne commented Jul 20, 2026

Copy link
Copy Markdown
Collaborator

Draft PoC, rung 1 of 2, on DA's splice-multi-sync fork (using this fork's CI).

What this does

Adds the on-ledger registration step for the "Extending Mainnet" CIP: letting DSO governance authorize a dedicated (operator-run) synchronizer so its traffic can later be funded in Canton Coin, the way the decentralized synchronizer's traffic is today.

  • RegisteredSynchronizer template: a registry entry binding a synchronizerId to the operator party that runs it. Signatory is the DSO party; the operator is an observer, so it learns it has been registered. A public RegisteredSynchronizer_Fetch choice (mirrors OpenMiningRound_Fetch) lets a later buyer read it via explicit disclosure.
  • DsoRules_RegisterSynchronizer governance action (SRARC_RegisterSynchronizer variant + choice + dispatch in executeActionRequiringConfirmation): a supermajority SV vote creates the registry entry.

In plain terms: a DSO vote records "synchronizer X, run by operator Y, is authorized for CC-funded traffic."

How it's verified (TestRegisterSynchronizer, Daml Script)

test_RegisterSynchronizer_viaVote runs a real 4-SV supermajority vote (RequestVote, CastVote x3, CloseVoteRequest, executeActionRequiringConfirmation, DsoRules_RegisterSynchronizer) and asserts the resulting RegisteredSynchronizer carries exactly the {dso, synchronizerId, operator} voted for and is visible to the operator. Negative: empty synchronizerId is rejected by the template ensure.

Design notes

Additive: new template + new governance variant/choice only; no change to existing templates or MemberTraffic. The new SRARC_RegisterSynchronizer constructor is appended last (SCU upgrade-safe).

Out of scope (next phase)

On-ledger only. The off-ledger side (the operator node granting the traffic) and a LocalNet end-to-end are the next workstream, not in this PR.

Rung 2 (the CC-funded buy) stacks on this in #2.

Tracked in

Internal work breakdown in ChainSafe/canton-extending-mainnet (private): #27 (RegisteredSynchronizer template + fetch), #28 (DsoRules_RegisterSynchronizer governance action); part of Epic #13 (E1) and #12 (E0). Follow-ups from review: lifecycle-state field and registry-held migrationId (#27).

… 1/2) [ci]

Signed-off-by: Sebastian Lindner <33971232+salindne@users.noreply.github.com>
@salindne
salindne force-pushed the multi-sync-poc-registration branch from 51a8808 to 56e4666 Compare July 21, 2026 10:14
salindne added 2 commits July 21, 2026 05:59
…isfy check-daml-warts

The trailing doc comment on the choice's `p` field ended with the word
"fetch", which the grep-based scripts/check-daml-warts.sh flags as a naked
fetch invocation (it only ignores full-line -- comments). Reword to drop the
word; no code/behaviour change. Fixes the static_tests "Run Daml warts check"
step. [ci]

Signed-off-by: Sebastian Lindner <33971232+salindne@users.noreply.github.com>
…for damlc docs

gen-daml-docs.sh (dpm docs) rejects a Haddock '-- |' doc comment attached
directly to a choice: 'parse error on input -- |'. Splice's own choices use
plain '--' comments (0/81 in splice-amulet use '-- |' on a choice), and
damlc build ignores the distinction, so the Daml tests stayed green while the
docs build failed.

Convert the doc comments on RegisteredSynchronizer_Fetch and
DsoRules_RegisterSynchronizer to plain comments. Verified locally with
dpm docs on splice-amulet and splice-dso-governance (both exit 0). [ci]

Signed-off-by: Sebastian Lindner <33971232+salindne@users.noreply.github.com>
Comment on lines +122 to +125
| SRARC_RegisterSynchronizer DsoRules_RegisterSynchronizer
-- ^ PoC (dedicated-synchronizer traffic): voted action to register a dedicated (non-global)
-- synchronizer by binding its id to an operator party, so its traffic can be funded in CC.
-- Executed via a DSO vote; see the `DsoRules_RegisterSynchronizer` choice.

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.

Constructor position: this needs to move to the end of the variant (SCU append-only rule).

Daml's smart-contract-upgrade rules require new constructors of a serializable variant to be appended after the last existing constructor — LF encodes constructor ranks, so inserting mid-list re-ranks SRARC_CreateBootstrapExternalPartyConfigStateInstruction and SRARC_UpdateFeaturedAppRight and makes the package upgrade-incompatible with the previously released splice-dso-governance. CI hasn't flagged it yet only because static_tests failed fast at the DAR-lock gate; once the checked-in DARs are updated, this will surface in the upgrade/compat checks (or at package-upload vetting on a live network).

Suggest removing the constructor here:

Suggested change
| SRARC_RegisterSynchronizer DsoRules_RegisterSynchronizer
-- ^ PoC (dedicated-synchronizer traffic): voted action to register a dedicated (non-global)
-- synchronizer by binding its id to an operator party, so its traffic can be funded in CC.
-- Executed via a DSO vote; see the `DsoRules_RegisterSynchronizer` choice.

…and re-adding it at the end of the variant, after -- ^ Update a specific featured app right., immediately before deriving (Eq, Show):

  | SRARC_RegisterSynchronizer DsoRules_RegisterSynchronizer
    -- ^ PoC (dedicated-synchronizer traffic): voted action to register a dedicated (non-global)
    --   synchronizer by binding its id to an operator party, so its traffic can be funded in CC.
    --   Executed via a DSO vote; see the `DsoRules_RegisterSynchronizer` choice.

(Only the data-type position matters — the case arm in executeActionRequiringConfirmation and the choice itself can stay where they are. Same rule will apply to any future SRARC_* we add in rung 2+.)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Good catch, thank you. Fixed in 3ac77dd: moved SRARC_RegisterSynchronizer to the end of DsoRules_ActionRequiringConfirmation (after SRARC_UpdateFeaturedAppRight, before deriving), so the existing constructors keep their LF ranks. The executeActionRequiringConfirmation case arm and the choice itself are unchanged, and I left a comment on the constructor so it stays last for future SRARC_* additions.

You were also right that the DAR-lock gate was masking it: static_tests failed first at DarLockChecker because the checked-in daml/dars/*.dar + dars.lock were stale. I've refreshed those with sbt damlDarsLockFileUpdate (no version bump needed since 0.1.22 / 0.1.28 aren't in release-line-0.6.11), so the upgrade/compat check should now actually run on the next CI pass.

salindne and others added 2 commits July 21, 2026 12:01
…erSynchronizer last (SCU)

Two issues surfaced by static_tests, both previously masked by the damlc-docs
parse error that ran earlier in the same step:

1. DAR lock: the PoC changed splice-amulet + splice-dso-governance source but the
   checked-in daml/dars/*.dar and daml/dars.lock were stale (DarLockChecker:
   'update the checked-in DAR'). Regenerated with 'sbt damlDarsLockFileUpdate'.
   No version bump needed: 0.1.22 / 0.1.28 are not in release-line-0.6.11.

2. Smart-contract upgrade (per @timwu20 review on PR): moved
   SRARC_RegisterSynchronizer to the END of DsoRules_ActionRequiringConfirmation.
   New constructors of a serializable variant must be appended after all existing
   ones - LF encodes constructor ranks, so inserting mid-list re-ranks the
   following constructors and breaks upgrade compatibility with the released
   splice-dso-governance. Semantically identical (matching is by name); the case
   arm and the choice are unchanged. [ci]

Signed-off-by: Sebastian Lindner <33971232+salindne@users.noreply.github.com>
…esources

static_tests' illegal-references check bans deployment-specific vocabulary
in daml/ ("global", "CC", DSO outside allowed phrases, lowercase dso in
comments). Reword the PoC comments to the upstream whitelabel terms: "the
decentralized synchronizer", "Amulet", "DSO governance" / "DSO party".

Comment-only, but Daml-LF embeds source locations, so package ids change
anyway: regenerated the checked-in DARs + dars.lock (sbt
damlDarsLockFileUpdate) and DarResources.scala (sbt updateDarResources).
The latter was still carrying pre-refresh package ids, which is what
failed the Scala shards ("No package found for template ...") in the
last CI run.

Verified locally: splice-dso-governance-test and splice-amulet-test
damlTest both green (test_RegisterSynchronizer_viaVote: ok).
[ci]

Signed-off-by: Timothy Wu <tim.wu@chainsafe.io>
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