Skip to content

feat(external-call): Add transaction encoding/decoding for external calls#440

Closed
trusch wants to merge 1 commit into
digital-asset:mainfrom
zenith-network:external-call/03-transaction-coder
Closed

feat(external-call): Add transaction encoding/decoding for external calls#440
trusch wants to merge 1 commit into
digital-asset:mainfrom
zenith-network:external-call/03-transaction-coder

Conversation

@trusch

@trusch trusch commented Feb 6, 2026

Copy link
Copy Markdown
Contributor

Summary

This PR adds serialization support for external call results in transactions. It enables transactions with external calls to be persisted, transmitted between participants, and reconstructed.

Requires #439

Changes

Transaction Coder (TransactionCoder.scala)

Encoding

private def encodeExternalCallResult(result: ExternalCallResult): Proto.ExternalCallResult =
  Proto.ExternalCallResult.newBuilder()
    .setExtensionId(result.extensionId)
    .setFunctionId(result.functionId)
    .setConfig(ByteString.copyFrom(result.config.toByteArray))
    .setInput(ByteString.copyFrom(result.input.toByteArray))
    .setOutput(ByteString.copyFrom(result.output.toByteArray))
    .build()

private def encodeExerciseNode(node: Node.Exercise, ...): Proto.Node = {
  val builder = Proto.Node.Exercise.newBuilder()
  // ... existing fields ...
  node.externalCallResults.foreach { result =>
    builder.addExternalCallResults(encodeExternalCallResult(result))
  }
  // ...
}

Decoding

private def decodeExternalCallResult(proto: Proto.ExternalCallResult): ExternalCallResult =
  ExternalCallResult(
    extensionId = proto.getExtensionId,
    functionId = proto.getFunctionId,
    config = Bytes.fromByteString(proto.getConfig),
    input = Bytes.fromByteString(proto.getInput),
    output = Bytes.fromByteString(proto.getOutput)
  )

private def decodeExerciseNode(proto: Proto.Node.Exercise, ...): Node.Exercise = {
  // ... existing fields ...
  val externalCallResults = proto.getExternalCallResultsList.asScala.map(decodeExternalCallResult).toSeq
  Node.Exercise(..., externalCallResults = externalCallResults)
}

Backward Compatibility

  • Transactions without external calls decode normally (empty list)
  • Proto field is repeated so missing field = empty list
  • No migration needed for existing transactions

Testing

  • TransactionCoderSpec.scala - Round-trip encoding tests
  • ContractStateMachineSpec.scala - State machine with external calls
  • ValidationSpec.scala - Validation of encoded transactions
  • TestNodeBuilder.scala - Test helpers for building nodes

@github-actions

github-actions Bot commented Feb 6, 2026

Copy link
Copy Markdown

🎉 Thank you for your contribution! It appears you have not yet signed the Agreement DA Contributor License Agreement (CLA), which is required for your changes to be incorporated into an Open Source Software (OSS) project. Please kindly read the and reply on a new comment with the following text to agree:


I have hereby read the Digital Asset CLA and agree to its terms


You can retrigger this bot by commenting recheck in this Pull Request. Posted by the CLA Assistant Lite bot.

@trusch trusch force-pushed the external-call/03-transaction-coder branch 2 times, most recently from e14cd7c to 68dcbe2 Compare February 6, 2026 09:25
@trusch trusch marked this pull request as draft February 6, 2026 09:27
@trusch trusch force-pushed the external-call/03-transaction-coder branch from 68dcbe2 to c3939ce Compare March 17, 2026 12:15
@trusch trusch force-pushed the external-call/03-transaction-coder branch from c3939ce to 20f886f Compare March 26, 2026 12:58
@trusch trusch force-pushed the external-call/03-transaction-coder branch from 20f886f to 3ce660a Compare April 8, 2026 14:51
@angelol angelol force-pushed the external-call/03-transaction-coder branch 2 times, most recently from 2ffb802 to d51b122 Compare May 7, 2026 11:39
@angelol angelol force-pushed the external-call/03-transaction-coder branch from d51b122 to c4fd85b Compare May 8, 2026 09:03
This is the transaction-coder layer of the external-call stack, following the engine and Speedy support in digital-asset#518.

It adds encoding and decoding for recorded external call results on exercise nodes. Runtime execution, Canton protocol support, extension service integration, and validation policy remain in later PRs.

Refs digital-asset#513.
@angelol angelol force-pushed the external-call/03-transaction-coder branch from c4fd85b to c561f64 Compare May 11, 2026 08:13
@trusch trusch closed this Jul 7, 2026
@github-actions github-actions Bot locked and limited conversation to collaborators Jul 7, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant