feat(external-call): engine execution, model conformance and validation SPI - #23
Draft
angelol wants to merge 16 commits into
Draft
Conversation
angelol
force-pushed
the
angelol/external-call-06-split-pr3-interp
branch
from
June 30, 2026 12:19
5fb3a81 to
e2cd4bd
Compare
angelol
force-pushed
the
angelol/external-call-06-split-pr4-damle-mcc
branch
from
June 30, 2026 12:19
b22f73b to
bcd36d4
Compare
angelol
force-pushed
the
angelol/external-call-06-split-pr3-interp
branch
from
June 30, 2026 14:33
e2cd4bd to
62d58c0
Compare
angelol
force-pushed
the
angelol/external-call-06-split-pr4-damle-mcc
branch
2 times, most recently
from
June 30, 2026 16:31
1c261f2 to
7dc5bcb
Compare
angelol
force-pushed
the
angelol/external-call-06-split-pr3-interp
branch
2 times, most recently
from
July 1, 2026 19:21
85b4627 to
9afe465
Compare
angelol
force-pushed
the
angelol/external-call-06-split-pr4-damle-mcc
branch
from
July 1, 2026 19:26
106c4d7 to
3776335
Compare
angelol
force-pushed
the
angelol/external-call-06-split-pr3-interp
branch
from
July 3, 2026 07:17
04bbe6c to
5ddbc6f
Compare
angelol
force-pushed
the
angelol/external-call-06-split-pr4-damle-mcc
branch
from
July 3, 2026 07:53
3f92db5 to
2bda8c0
Compare
…SPI (digital-asset#551) ## Summary This is PR 3 of 8 in the external-call runtime-integration series tracked in digital-asset#513, stacked on PR 2. 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 command-execution error surface and the handler service-provider interface (SPI) that later PRs implement and wire in. ## Scope This PR adds: - external-call-aware command-execution errors (`CommandExecutionErrors`) and the `ErrorResource` metadata for them - rejection generators for external-call failures (`RejectionGenerators`) - the external-call handler SPI (`ExternalCallHandler`, `ExternalCallMode`) — the interface used by command interpretation to dispatch engine external-call questions - tests for rejection generation, request validation, and the LF/Speedy external-call surface ## Out of scope The concrete extension-service handler implementation and its wiring into command execution (PR 5), engine replay (PR 4), and validation/routing/factory (PR 6–8). The SPI ships with a no-op `Unsupported` handler; nothing dispatches to a real service yet. ## Stacking & review This PR is stacked on PR 2, so its diff against `main` is **cumulative**. The incremental change for this PR alone: digital-asset/canton@zenith-network:angelol/external-call-06-split-pr2-codec...zenith-network:angelol/external-call-06-split-pr3-interp Refs digital-asset#513.
Reference commit: 42b6511
…ining The inlining was incidental and unrelated to the external-call feature; reverting it keeps the PR diff focused.
The test feeds two different outputs for one input identity, so "conflicting" (not "duplicate") is accurate; the new name also matches its non-leakage assertions rather than "without choosing one".
…e results type ExternalCallReplayData was a redundant single-field wrapper around StoredExternalCallResults, which held all the logic. Fold that logic into ExternalCallReplayData and delete the separate results type; behavior unchanged.
…ay-data thunk The reinterpret SPI's externalCallReplayData thunk returned FutureUnlessShutdown[ExternalCallReplayData], but every producer wrapped a synchronous in-memory value in FutureUnlessShutdown.pure -- there is no async source. Make the thunk () => ExternalCallReplayData and unwrap the future in handleExternalCall accordingly; behavior unchanged.
… aggregation ViewParticipantData.validated already rejects non-empty externalCallResults below protocol version dev on every construction path, so the supports-guard was dead; fromResults(empty) equals empty, so the isEmpty short-circuit was too. Drop both and the now-unused viewParticipantData parameter.
ExternalCallKey implements PrettyPrinting (payload sizes only, never values),
so both replay-error prettys collapse to param("key", _.key). Also closes the
payload-leak channel through the key's default case-class toString.
resumeWithExternalCallOutput and replayStoredExternalCallOutput each had one caller and formed a single chain; fold both into handleExternalCall.
The replayDataO parameter cached the externalCallReplayData thunk across external calls within one reinterpretation, but the only production caller already passes a lazy-val-backed thunk, so the internal memoization was redundant. handleExternalCall now calls the thunk directly.
Replace the hardcoded dev-PV factory with the suite factory and testedProtocolVersion, gated onlyRunWithOrGreaterThan(dev) like the sibling tampered-metadata test, so the test no longer re-runs identically under every protocol version. Add a counterpart below dev asserting the aggregated replay data stays empty. Fold buildUnderTestWithFactory into its now-single caller.
Left behind by the earlier type-shortening rename; caught by Test/scalafmtCheck, which the Compile-scoped check used before misses.
Follow-up to the earlier helper inlining: with those gone, this two-use wrapper no longer pays for itself either.
angelol
force-pushed
the
angelol/external-call-06-split-pr4-damle-mcc
branch
from
July 3, 2026 15:36
2bda8c0 to
42bfe55
Compare
No longer needed per review feedback on digital-asset#551.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This is PR 4 of 8 in the external-call runtime-integration series tracked in digital-asset#513, stacked on PR 3.
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_CALLbuiltin 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 engine-side replay of recorded external-call results and the validation SPI used during confirmation.
Scope
This PR adds:
DAMLereinterpretation support for replaying recorded external-call results, withExternalCallPayloadDescriptionExternalCallValidatorSPI trait andExternalCallValidationErrorModelConformanceCheckerintegration that replays recorded results during conformance checkingOut of scope
The concrete validator implementation (PR 6), the extension-service runtime (PR 5), consistency checking and routing (PR 6–7), and activation of validation in transaction processing (PR 8).
Refs digital-asset#513.