Skip to content

feat(external-call): command-execution errors, rejection and handler SPI - #22

Draft
angelol wants to merge 6 commits into
angelol/external-call-06-split-pr2-codecfrom
angelol/external-call-06-split-pr3-interp
Draft

feat(external-call): command-execution errors, rejection and handler SPI#22
angelol wants to merge 6 commits into
angelol/external-call-06-split-pr2-codecfrom
angelol/external-call-06-split-pr3-interp

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-pr2-codec (PR 2). 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 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.

Refs digital-asset#513.

@angelol
angelol force-pushed the angelol/external-call-06-split-pr3-interp branch from 5fb3a81 to e2cd4bd Compare June 30, 2026 12:19
@angelol
angelol force-pushed the angelol/external-call-06-split-pr2-codec branch from 82997b5 to bfd7a14 Compare June 30, 2026 12:19
@angelol
angelol force-pushed the angelol/external-call-06-split-pr3-interp branch from e2cd4bd to 62d58c0 Compare June 30, 2026 14:33
@angelol
angelol force-pushed the angelol/external-call-06-split-pr2-codec branch 2 times, most recently from 1db3847 to c88e6cf Compare June 30, 2026 16:31
@angelol
angelol force-pushed the angelol/external-call-06-split-pr3-interp branch from 62d58c0 to e2e961e Compare June 30, 2026 16:31
@angelol
angelol force-pushed the angelol/external-call-06-split-pr2-codec branch from b0eab55 to f52559e Compare July 1, 2026 19:18
@angelol
angelol force-pushed the angelol/external-call-06-split-pr3-interp branch from 85b4627 to 9afe465 Compare July 1, 2026 19:21
@angelol
angelol force-pushed the angelol/external-call-06-split-pr2-codec branch from f52559e to 8a3889f Compare July 3, 2026 05:56
angelol added 6 commits July 3, 2026 08:56
…ults (digital-asset#550)

## Summary

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

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 interactive-submission representation and codec for recorded external-call results, so prepared transactions can round-trip them.

## Scope

This PR adds:

- the `ExternalCallResult` interactive-submission message (`interactive_submission_data.proto`) and the related service doc-comments (`interactive_submission_service.proto`)
- prepared-transaction encoding/decoding of recorded external-call results (`PreparedTransactionEncoder` / `PreparedTransactionDecoder`)
- the regenerated protobuf snapshot, `proto-data.yml` and `openapi.yaml` for the new message
- prepared-transaction codec tests

## Out of scope

Runtime dispatch of external-call questions (PR 3+), engine replay (PR 4), and validation (PR 6–8).

## Hashing Boundary

Prepared/external-submission signatures authorize the LF action. Recorded external-call result payloads are Canton protocol data protected by the Canton view signature (see PR 1). Prepared transactions therefore carry external-call results for round-tripping, but those result payloads are intentionally excluded from the LF/prepared node hash.

## Stacking & review

This PR is stacked on PR 1, so its diff against `main` is **cumulative** (it includes PR 1). The incremental change for this PR alone:
digital-asset/canton@zenith-network:angelol/external-call-06-split-pr1-foundation...zenith-network:angelol/external-call-06-split-pr2-codec

Refs digital-asset#513.
Add `def message` to the sealed `ExecutionFailed.Error` so callers read it
directly, replacing the match/case that destructured `CallFailed`/`InvalidOutput`
in CommandExecutionErrors. Addresses an upstream review comment on digital-asset#551.
Fold the near-identical "expected payload" and "empty payloads" engine tests
into one payload table, loop-registering a named test per row (populated/empty)
so the body is shared while both cases stay independently reported. Addresses an
upstream review comment on digital-asset#551.
Fold the happy-path and empty-payloads Speedy tests into one payload table,
loop-registering a named test per row (populated/empty) and unifying on the
existing machineForRun helper so the body is shared while both cases stay
independently reported. Addresses an upstream review comment on digital-asset#551.
@angelol
angelol force-pushed the angelol/external-call-06-split-pr3-interp branch from 04bbe6c to 5ddbc6f Compare July 3, 2026 07:17
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