Skip to content

feat(external-call): recorded-result consistency checker and extension-service validator - #25

Draft
angelol wants to merge 10 commits into
angelol/external-call-06-split-pr5-extensionfrom
angelol/external-call-06-split-pr6-checker
Draft

feat(external-call): recorded-result consistency checker and extension-service validator#25
angelol wants to merge 10 commits into
angelol/external-call-06-split-pr5-extensionfrom
angelol/external-call-06-split-pr6-checker

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-pr5-extension (PR 5). 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 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.

Refs digital-asset#513.

@angelol
angelol force-pushed the angelol/external-call-06-split-pr6-checker branch from db4bbf8 to 4d4d6d3 Compare June 30, 2026 12:19
@angelol
angelol force-pushed the angelol/external-call-06-split-pr5-extension branch 2 times, most recently from 50c4618 to 82a25ba Compare June 30, 2026 14:33
@angelol
angelol force-pushed the angelol/external-call-06-split-pr6-checker branch 2 times, most recently from eaed53c to 80e12d6 Compare June 30, 2026 16:31
@angelol
angelol force-pushed the angelol/external-call-06-split-pr5-extension branch from b6e9db6 to 8d9554c Compare July 1, 2026 19:27
@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-pr5-extension branch from 230f4b2 to c690ddf Compare July 3, 2026 08:09
@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-pr5-extension branch from c690ddf to 7a301e7 Compare July 3, 2026 15:36
@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-pr5-extension branch from 7a301e7 to b213120 Compare July 6, 2026 09:25
@angelol
angelol force-pushed the angelol/external-call-06-split-pr6-checker branch from edabc86 to 375f885 Compare July 6, 2026 09:29
angelol added 9 commits July 6, 2026 12:51
…ecution wiring (digital-asset#553)

## Summary

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

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 connects the digital-asset#537 extension-service client to command execution: it adds the handler that routes engine external-call questions to configured extension services, the participant configuration that keys services by extension id, and the node wiring.

## Scope

This PR adds:

- the `ExtensionServiceExternalCallHandler` implementation of the PR 3 handler SPI, dispatching engine external-call questions to the digital-asset#537 extension-service client (`ExtensionServiceManager` / `HttpExtensionServiceClient` / `ExtensionServiceClient` glue)
- participant extension-service configuration keyed by extension id (`CantonConfig`, `ConfigValidations`, `CantonEngineConfig`)
- handler wiring through command execution (`ApiServiceOwner`, `ApiServices`, `StoreBackedCommandInterpreter`) and node startup (`LedgerApiServer`, `ParticipantNode`)
- configuration, HTTP-handler and command-interpreter tests

## Out of scope

Recorded-result consistency checking and the extension-service validator implementation (PR 6), response routing (PR 7), and activation of validation in transaction processing (PR 8). The handler is dev-gated and off unless an extension service is configured, so the intermediate state is dormant.

## Stacking & review

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

Refs digital-asset#513.
The supportsExternalCallResults guard is dead by the checkExternalCallResults
invariant (unsupported => results empty on every construction path), and the
.nonEmpty guard is redundant since map over empty is empty. Collapse to a
plain map.
On empty occurrences the general path already computes Result(Map.empty,
Seq.empty), structurally equal to Result.empty, so the isEmpty short-circuit
is redundant.
Rename Result.inconsistencies to hostedInconsistencies, aligning the field
with the method that computes it, and document the party grouping, the
definition of checking parties, and what "visible" means.
Use testedProtocolVersion instead of hardcoding dev, gate the
external-call tests to dev and above, and add an any-version test for
views without external-call results.
…ion test util

Drop the fixtures that only the response-router and confirmation-response
tests use (validator mocks, view positions, confirmer/model-conformance
helpers); they will be introduced by the PRs that use them.
@angelol
angelol force-pushed the angelol/external-call-06-split-pr6-checker branch from 375f885 to c0363cb Compare July 6, 2026 11:03
…alidator test

The unconfigured-extension case goes through a real ExtensionServiceManager,
whose choke-point logging (added on digital-asset#553) emits the full-error warning; the
validator test never captured it, so it leaked into canton_test.log and
failed CI's log check on digital-asset#554 (jobs 3608/3609). Wrap the call in
loggerFactory.assertLogs, asserting the complete warning message like the
handler test does; assertLogs suppresses asynchronously for Future results,
preserving the suite's async style.
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