Skip to content

feat(external-call): confirmation-response router - #26

Draft
angelol wants to merge 19 commits into
angelol/external-call-06-split-pr6-checkerfrom
angelol/external-call-06-split-pr7-router
Draft

feat(external-call): confirmation-response router#26
angelol wants to merge 19 commits into
angelol/external-call-06-split-pr6-checkerfrom
angelol/external-call-06-split-pr7-router

Conversation

@angelol

@angelol angelol commented Jun 30, 2026

Copy link
Copy Markdown

Review-only — do not merge. This is the clean per-PR diff for upstream review, stacked on angelol/external-call-06-split-pr6-checker (PR 6). The mergeable upstream PR (targets main) opens after digital-asset#537 lands. Part of the 8-PR split that supersedes digital-asset#541.

Summary

This is PR 7 of 8 in the external-call runtime-integration series tracked in digital-asset#513, stacked on PR 6.

The external-call stack (digital-asset#513): digital-asset#506 added the transaction-side representation for recording external-call results; digital-asset#514 added the LF EXTERNAL_CALL builtin surface; digital-asset#518 wired it into Speedy and the LF engine; digital-asset#522 added transaction protobuf encoding/decoding; digital-asset#526 added Canton protocol serialization for recorded results; digital-asset#537 added the participant-side extension-service client. digital-asset#541 implemented the remaining runtime integration as one PR; this series splits digital-asset#541 into 8 independently reviewable PRs (each < 1000 lines) and supersedes it.

This PR adds the router that turns recorded-result consistency outcomes into confirmation-response routing decisions, directing disagreements to the relevant checking parties.

Scope

This PR adds:

  • ExternalCallResponseRouter, which maps consistency-check outcomes to confirmation-response routing (including routing disagreements to the relevant checking parties), plus the relocated ViewWithHostedParties router input
  • a focused ExternalCallResponseRouterTest covering the router's scenarios directly against its API

Out of scope

Assembly of confirmation responses and activation of validation in transaction processing (PR 8).

Refs digital-asset#513.

@angelol
angelol force-pushed the angelol/external-call-06-split-pr7-router branch from 7318b12 to 7be1784 Compare June 30, 2026 12:19
@angelol
angelol force-pushed the angelol/external-call-06-split-pr6-checker branch 2 times, most recently from 4d4d6d3 to eaed53c Compare June 30, 2026 14:33
@angelol
angelol force-pushed the angelol/external-call-06-split-pr7-router branch from 7be1784 to 1795b71 Compare June 30, 2026 14:33
@angelol
angelol force-pushed the angelol/external-call-06-split-pr6-checker branch from eaed53c to 80e12d6 Compare June 30, 2026 16:31
@angelol
angelol force-pushed the angelol/external-call-06-split-pr7-router branch from 1795b71 to 28cfc51 Compare June 30, 2026 16:31
@angelol
angelol force-pushed the angelol/external-call-06-split-pr6-checker branch from 269670f to e2fbfd3 Compare July 1, 2026 19:27
@angelol
angelol force-pushed the angelol/external-call-06-split-pr7-router branch from b7d9e4d to 65e975f Compare July 1, 2026 19:27
@angelol
angelol force-pushed the angelol/external-call-06-split-pr6-checker branch from e2fbfd3 to 109754c Compare July 3, 2026 08:19
@angelol
angelol force-pushed the angelol/external-call-06-split-pr7-router branch from 65e975f to 161bdd7 Compare July 3, 2026 08:23
@angelol
angelol force-pushed the angelol/external-call-06-split-pr6-checker branch from 8043a5f to 1610e64 Compare July 3, 2026 15:36
@angelol
angelol force-pushed the angelol/external-call-06-split-pr7-router branch from 7b44694 to 648a12d Compare July 3, 2026 15:36
@angelol
angelol force-pushed the angelol/external-call-06-split-pr6-checker branch from edabc86 to 375f885 Compare July 6, 2026 09:29
@angelol
angelol force-pushed the angelol/external-call-06-split-pr7-router branch from 8921f2a to 46e33e9 Compare July 6, 2026 09:33
@angelol
angelol force-pushed the angelol/external-call-06-split-pr6-checker branch from 375f885 to c0363cb Compare July 6, 2026 11:03
@angelol
angelol force-pushed the angelol/external-call-06-split-pr7-router branch from 46e33e9 to 1f3bb99 Compare July 6, 2026 11:03
canton-machine and others added 2 commits July 6, 2026 11:16
…n-service validator (digital-asset#554)

## Summary

This is PR 6 of 8 in the external-call runtime-integration series tracked in digital-asset#513, stacked on PR 5.

The external-call stack (digital-asset#513): digital-asset#506 added the transaction-side representation for recording external-call results; digital-asset#514 added the LF `EXTERNAL_CALL` builtin surface; digital-asset#518 wired it into Speedy and the LF engine; digital-asset#522 added transaction protobuf encoding/decoding; digital-asset#526 added Canton protocol serialization for recorded results; digital-asset#537 added the participant-side extension-service client. digital-asset#541 implemented the remaining runtime integration as one PR; this series splits digital-asset#541 into 8 independently reviewable PRs (each < 1000 lines) and supersedes it.

This PR adds the consistency checker that compares recorded external-call results against locally checked results, and the concrete extension-service validator implementing the PR 4 SPI.

## Scope

This PR adds:

- `ExternalCallConsistencyChecker`, which compares recorded results with locally checked results and identifies disagreements
- `ExtensionServiceExternalCallValidator`, the extension-service implementation of the PR 4 `ExternalCallValidator` SPI
- consistency-checker tests and the shared external-call validation test fixtures used here and in PR 7

## Out of scope

Routing of disagreements to checking parties (PR 7) and activation of the validator in transaction processing (PR 8). The validator is implemented here but not yet threaded into confirmation; it is dev-gated and dormant until PR 8.

## Stacking & review

This PR is stacked on PR 5, so its diff against `main` is **cumulative**. The incremental change for this PR alone (it depends on PR 3 and PR 4, not PR 5):
digital-asset/canton@zenith-network:angelol/external-call-06-split-pr5-extension...zenith-network:angelol/external-call-06-split-pr6-checker

Refs digital-asset#513.
@angelol
angelol force-pushed the angelol/external-call-06-split-pr7-router branch from 1f3bb99 to cfd179a Compare July 6, 2026 13:46
canton-machine and others added 11 commits July 6, 2026 15:36
…reement routing

On empty disagreements the general path already flat-maps to nothing and
groupMap yields Map.empty, so the isEmpty short-circuit is redundant (the only
skipped work is a cheap, pure view sort).
…ByParty

The supportsExternalCallResults guard is dead by the checkExternalCallResults
invariant (unsupported => results empty), so filter/flatMap over the results
already yields an empty Seq.
…leExternalCallResults

supportsExternalCallResults is redundant with externalCallResults.nonEmpty
by the checkExternalCallResults invariant (unsupported => results empty),
so the conjunct never changes the predicate.

Verified behavior-preserving by adversarial review.
…ccurrences

!supportsExternalCallResults is redundant with externalCallResults.isEmpty
by the checkExternalCallResults invariant (unsupported => results empty),
so the disjunct never changes which branch the if takes.

Verified behavior-preserving by adversarial review.
… parameters

The two party sets were only ever consumed as hosted-and-not-rejecting,
so pass that single set instead.
PrettyPrinting already bounds the rendered description (Pretty's default
pprinter), and the Inconsistency rendering only prints payload sizes.
Requested in the first review pass of digital-asset#555: specification-level ScalaDocs
for the public methods, the intended data flow from occurrence selection
to the reject/abstain routes, and the downstream interface.
angelol added 4 commits July 6, 2026 19:42
…flow

The replay-disagreement source spans a reinterpreted view together with
its subviews, not a single view; and the rejections that replace a
suppressed model-conformance rejection cover fewer parties than the
blanket rejection did.
The routed rejections cover at most as many parties as the suppressed
blanket rejection (equality is possible), and the routing-context class
doc now uses the same suppress-and-partially-replace framing as the
method doc.
…ker changes

Post-rebase adaptations for the digital-asset#554 review fixes now in this branch's
base:

- checker Result.inconsistencies -> hostedInconsistencies at the router's
  inconsistenciesForView and the four router-test assertion sites,
- the shared test fixtures that digital-asset#554 slimmed away are restored for the
  router test (validator mocks, view positions, withConfirmers, requestId,
  alarm-assertion helper), with view-position values matching their names
  as promised in digital-asset#554 review reply 3521058115; relative ordering of the
  positions is preserved, so no order-sensitive assertion is affected.
…allResult

Addresses the post-merge MINOR from the digital-asset#554 approval
(discussion r3529116181): the fixture is an ExternalCallResult, not an
output; renamed at the declaration and all usage sites.
@angelol
angelol force-pushed the angelol/external-call-06-split-pr7-router branch from cfd179a to b96374f Compare July 6, 2026 15:51
angelol added 2 commits July 6, 2026 20:20
Sweep of the PR slice per review request: the routing context's two lazy
vals, the router test's factory and key fixtures, and the checker test's
party fixtures.
Follow-up to the annotation sweep: the nested RecordingExternalCallValidator's
observedKeys val was missed.
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