Skip to content

canton: make core-bridge contracts publicly readable via a public observer#26

Closed
bengtlofgren wants to merge 2 commits into
integration/cantonfrom
feat/canton-public-observer
Closed

canton: make core-bridge contracts publicly readable via a public observer#26
bengtlofgren wants to merge 2 commits into
integration/cantonfrom
feat/canton-public-observer

Conversation

@bengtlofgren

@bengtlofgren bengtlofgren commented Jul 1, 2026

Copy link
Copy Markdown

Summary

Adds a public observer party to the durable core-bridge contracts (CoreState, Emitter, EmitterIdentity) so their state is readable by any participant granted read-as rights for that party, without exposing any signing authority. The public party is sourced authoritatively from CoreState in ApproveEmitter so all emitter records are guaranteed to share one canonical visibility party.

Changes

  • canton/core/daml/Wormhole/Core/State.damlpublic : Party added to CoreState, Emitter, and EmitterIdentity; listed as observer on each. ApproveEmitter fetches public from CoreState (operator is signatory) rather than accepting a requester-supplied value.
  • canton/core/daml/Wormhole/Core/Setup.damlsetup allocates and stores the public party on CoreState.
  • canton/devnet/bootstrap.sh — bootstrap passes the public party through to setup.
  • canton/test/daml/Test/TestCore.daml — tests updated for the new public field; coverage added for public-read visibility.
  • node/pkg/cantonclient/GetActiveContracts added to the client interface and gRPC implementation to support public-read queries.
  • node/pkg/watchers/canton/public_read_integration_test.go — new integration test verifying that contracts are visible when read as the public party.
  • canton/README.md — §4.6 added documenting the public-readability design.

@bengtlofgren
bengtlofgren requested a review from evan-gray as a code owner July 1, 2026 16:58
@bengtlofgren
bengtlofgren force-pushed the feat/canton-public-observer branch from 827d7dd to 72117f3 Compare July 1, 2026 18:00
…erver party

Add a read-only public party as an observer on the durable core-bridge templates
(CoreState, EmitterIdentity, Emitter) so the full records — config, emitter
registrations, sequences, and published messages — are readable by anyone the
participant grants read-as rights to that party.

- public is chosen once at setup and stored on CoreState (the single source of
  truth). ApproveEmitter sources it AUTHORITATIVELY from CoreState (fetching the
  operator's own singleton), not from a requester-supplied value, so every
  Emitter/EmitterIdentity is guaranteed to share the one canonical public party;
  it is carried forward on every recreate (publish, governance transition).
  EmitterRequest drops its public field (it is a transient proposal).
- Tests: testPublicVisibility (public reads CoreState/Emitter/EmitterIdentity
  across two publishes, asserts the canonical public, non-stakeholder sees
  nothing), testGovernancePreservesPublic, testApproveEmitterRejectsForeignCoreState.
- Add cantonclient.GetActiveContracts (ACS query) and a public-read integration
  test that reads the ACS as the public party over the real Ledger API and
  confirms it sees the three durable templates.
- Surface the public party id in the devnet bootstrap; document the model and the
  required participant-side read-as-public grant (README section 4.6).
@bengtlofgren
bengtlofgren force-pushed the feat/canton-public-observer branch from 72117f3 to c91c254 Compare July 1, 2026 18:43
@bengtlofgren
bengtlofgren force-pushed the feat/canton-public-observer branch from aa03c1a to 55f967c Compare July 1, 2026 19:44
@bengtlofgren

Copy link
Copy Markdown
Author

I dont know if this is going to be needed ..

@bengtlofgren

Copy link
Copy Markdown
Author

Closing in favor of #32 (canton-guardian-observer). On the current (post-#29) template set, the public party here observes the same two templates guardianObserver in #32 already observes (CoreState, Emitter) — the third template this PR touched, EmitterIdentity, no longer exists post-#29 (split into EmitterRegistry, which holds no per-emitter data worth reading, and Emitter, which #32 already covers). No remaining read-surface gap; re-open as a variant of #32 if a non-guardian public-read audience is still needed.

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