Skip to content

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

Open
salindne wants to merge 2 commits into
mainfrom
daml-poc-registration
Open

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

Conversation

@salindne

Copy link
Copy Markdown

Dedicated-synchronizer traffic funding — PoC (rung 1 of 2)

Daml-level proof-of-concept for the "Dedicated Synchronizer Traffic Manager" design. This is the first PR in a stacked ladder:

  • Rung 1 (this PR): Registration — how a dedicated (non-global) synchronizer is registered with the DSO so its traffic can later be funded in CC.
  • Rung 2 (stacked on this): CC-funded traffic purchase — a new AmuletRules choice that burns CC for a registered synchronizer and records it with the operator as observer.

What this PR adds

  • RegisteredSynchronizer (splice-amulet, DecentralizedSynchronizer.daml): a DSO-signed contract binding a dedicated synchronizer id → its operator party, observed by that operator, plus a public RegisteredSynchronizer_Fetch choice (mirrors OpenMiningRound_Fetch) so a buyer can read it via explicit disclosure.
  • SRARC_RegisterSynchronizer / DsoRules_RegisterSynchronizer (splice-dso-governance): a governed "create" action + dispatch arm, so a DSO vote populates the registry. Mirrors the existing DsoRules_CreateUnallocatedUnclaimedActivityRecord pattern.
  • TestRegisterSynchronizer: a Daml Script test that registers a synchronizer via a supermajority vote and asserts the resulting contract.

Design notes

  • Additive only. No existing template or choice is modified — no MemberTraffic schema change, no Scala codegen churn.
  • Template placement. RegisteredSynchronizer lives in splice-amulet, not splice-dso-governance, because splice-dso-governance depends on splice-amulet (one-way) and the rung-2 AmuletRules choice must be able to fetch it. The governance action that creates it lives in splice-dso-governance (which can create an amulet template).

Not yet verified

Written without a local build — no dpm/nix env was available to run sbt damlBuild / damlTest. Please let CI (or a local nix build) compile it and run sbt 'splice-dso-governance-test-daml/Test/damlTest'. Draft until green.

Inline comments below walk through each hunk.

PoC rung 1 of dedicated-synchronizer traffic funding.

- splice-amulet: RegisteredSynchronizer template (dso-signed, operator observer)
  + public RegisteredSynchronizer_Fetch choice, binding a dedicated synchronizer
  id to its operator party.
- splice-dso-governance: SRARC_RegisterSynchronizer / DsoRules_RegisterSynchronizer
  governed create action + dispatch, so a DSO vote populates the registry.
- test: TestRegisterSynchronizer registers a synchronizer via a supermajority vote
  and asserts the RegisteredSynchronizer contract.

Not built locally (no dpm/nix env available); needs sbt damlTest / CI to verify.
--
-- This template lives in splice-amulet (not splice-dso-governance) so that `AmuletRules` can
-- `fetch` it: splice-dso-governance depends on splice-amulet, not the reverse.
template RegisteredSynchronizer with

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Crux of rung 1: this DSO-signed contract binds a dedicated synchronizer id to its operator party. It is created only by a governance vote (DsoRules_RegisterSynchronizer) and observed by the operator. It lives in splice-amulet rather than splice-dso-governance because the rung-2 AmuletRules_BuyDedicatedSyncTraffic choice must fetch it, and splice-dso-governance depends on splice-amulet (one-way), not the reverse.

-- | Public fetch choice, mirroring `OpenMiningRound_Fetch`: lets a buyer who is neither
-- signatory nor observer read this contract inside `AmuletRules_BuyDedicatedSyncTraffic`
-- when it is passed via explicit disclosure. Returns the contract unchanged.
nonconsuming choice RegisteredSynchronizer_Fetch : RegisteredSynchronizer

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Public fetch choice, copied from OpenMiningRound_Fetch. It lets the buyer -- who is neither signatory nor observer -- read this contract inside the rung-2 buy choice when it is supplied via explicit disclosure. Returns the contract unchanged.

-- ^ Create TransferCommandCounter contract for the given sender if it does not already exist
| SRARC_CreateUnallocatedUnclaimedActivityRecord DsoRules_CreateUnallocatedUnclaimedActivityRecord
-- ^ Voted action to create an UnallocatedUnclaimedActivityRecord contract.
| SRARC_RegisterSynchronizer DsoRules_RegisterSynchronizer

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

New variant on the closed DsoRules_ActionRequiringConfirmation sum. Adding a variant forces every exhaustive match to handle it; I verified there is exactly one such match (the dispatcher below) -- actionRequiringConfirmationEffectiveAt matches at the ARC_* level, not on these SRARC_* variants.

-- then reads that contract (via explicit disclosure) to authorize CC burns for the synchronizer.
-- `controller dso` + `nonconsuming`: a vote reaches this via `executeActionRequiringConfirmation`,
-- and the `DsoRules` contract is not archived by exercising it.
nonconsuming choice DsoRules_RegisterSynchronizer : DsoRules_RegisterSynchronizerResult

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Governed create, mirroring DsoRules_CreateUnallocatedUnclaimedActivityRecord. controller dso + nonconsuming: it is reached only via an accepted vote through executeActionRequiringConfirmation, and does not archive the DsoRules contract. It creates the splice-amulet RegisteredSynchronizer, which is allowed because splice-dso-governance depends on splice-amulet.

SRARC_CreateTransferCommandCounter choiceArg -> void $ exercise dsoRulesCid choiceArg
SRARC_CreateUnallocatedUnclaimedActivityRecord choiceArg -> void $ exercise dsoRulesCid choiceArg
-- PoC: an accepted vote to register a dedicated synchronizer runs the choice on DsoRules.
SRARC_RegisterSynchronizer choiceArg -> void $ exercise dsoRulesCid choiceArg

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Dispatch arm: an accepted SRARC_RegisterSynchronizer vote exercises the choice on DsoRules. This is the single exhaustive match over the DsoRules action variants.

-- Supermajority SV vote to register the dedicated synchronizer. `initiateAndAcceptVote` routes
-- through DsoRules_RequestVote -> DsoRules_CastVote (x3) -> DsoRules_CloseVoteRequest, which on
-- acceptance calls executeActionRequiringConfirmation, dispatching to DsoRules_RegisterSynchronizer.
initiateAndAcceptVote app [sv1, sv2, sv3, sv4] $

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Drives the full governance path (DsoRules_RequestVote -> DsoRules_CastVote x3 -> DsoRules_CloseVoteRequest -> executeActionRequiringConfirmation), so registration is exercised exactly as in production rather than by calling the choice in isolation.

@salindne

Copy link
Copy Markdown
Author

Status update — compiles + tested green.

splice-dso-governance builds clean (splice-dso-governance-0.1.28.dar); the Daml Script test TestRegisterSynchronizer::test_RegisterSynchronizer_viaVote passes (registration created via a supermajority DSO vote). One compile fix folded in: import RegisteredSynchronizer(..) so DsoRules_RegisterSynchronizer can create the contract.

Issues addressed: #19 (E1-1, RegisteredSynchronizer template + _Fetch), #20 (E1-2, DsoRules_RegisterSynchronizer governance action). Contributes to #15 (compile the PoC) and #16 (run the Daml Script tests) — both green.

Onboarding / full status: ChainSafe/canton-extending-mainnet#9.

@salindne
salindne marked this pull request as ready for review July 17, 2026 19:21
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.

1 participant