Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ package com.daml.ledger.api.v2;

import "google/protobuf/empty.proto";

option go_package = "github.com/digital-asset/canton/go/ledger/api/v2;ledgerapiv2";
option csharp_namespace = "Com.Daml.Ledger.Api.V2";
option java_outer_classname = "ValueOuterClass";
option java_package = "com.daml.ledger.api.v2";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ package com.daml.ledger.api.v2;
import "com/daml/ledger/api/v2/completion.proto";
import "com/daml/ledger/api/v2/offset_checkpoint.proto";

option go_package = "github.com/digital-asset/canton/go/ledger/api/v2;ledgerapiv2";
option csharp_namespace = "Com.Daml.Ledger.Api.V2";
option java_outer_classname = "CommandCompletionServiceOuterClass";
option java_package = "com.daml.ledger.api.v2";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ import "com/daml/ledger/api/v2/reassignment.proto";
import "com/daml/ledger/api/v2/reassignment_commands.proto";
import "com/daml/ledger/api/v2/transaction.proto";
import "com/daml/ledger/api/v2/transaction_filter.proto";
import "google/api/annotations.proto";

option go_package = "github.com/digital-asset/canton/go/ledger/api/v2;ledgerapiv2";
option csharp_namespace = "Com.Daml.Ledger.Api.V2";
option java_outer_classname = "CommandServiceOuterClass";
option java_package = "com.daml.ledger.api.v2";
Expand All @@ -23,15 +25,30 @@ option java_package = "com.daml.ledger.api.v2";
service CommandService {
// Submits a single composite command and waits for its result.
// Propagates the gRPC error of failed submissions including Daml interpretation errors.
rpc SubmitAndWait(SubmitAndWaitRequest) returns (SubmitAndWaitResponse);
rpc SubmitAndWait(SubmitAndWaitRequest) returns (SubmitAndWaitResponse) {
option (google.api.http) = {
post: "/v2/commands/submit-and-wait"
body: "commands"
};
}

// Submits a single composite command, waits for its result, and returns the transaction.
// Propagates the gRPC error of failed submissions including Daml interpretation errors.
rpc SubmitAndWaitForTransaction(SubmitAndWaitForTransactionRequest) returns (SubmitAndWaitForTransactionResponse);
rpc SubmitAndWaitForTransaction(SubmitAndWaitForTransactionRequest) returns (SubmitAndWaitForTransactionResponse) {
option (google.api.http) = {
post: "/v2/commands/submit-and-wait-for-transaction"
body: "*"
};
}

// Submits a single composite reassignment command, waits for its result, and returns the reassignment.
// Propagates the gRPC error of failed submission.
rpc SubmitAndWaitForReassignment(SubmitAndWaitForReassignmentRequest) returns (SubmitAndWaitForReassignmentResponse);
rpc SubmitAndWaitForReassignment(SubmitAndWaitForReassignmentRequest) returns (SubmitAndWaitForReassignmentResponse) {
option (google.api.http) = {
post: "/v2/commands/submit-and-wait-for-reassignment"
body: "*"
};
}
}

// These commands are executed as a single atomic transaction.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ package com.daml.ledger.api.v2;
import "com/daml/ledger/api/v2/commands.proto";
import "com/daml/ledger/api/v2/reassignment_commands.proto";

option go_package = "github.com/digital-asset/canton/go/ledger/api/v2;ledgerapiv2";
option csharp_namespace = "Com.Daml.Ledger.Api.V2";
option java_outer_classname = "CommandSubmissionServiceOuterClass";
option java_package = "com.daml.ledger.api.v2";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import "com/daml/ledger/api/v2/value.proto";
import "google/protobuf/duration.proto";
import "google/protobuf/timestamp.proto";

option go_package = "github.com/digital-asset/canton/go/ledger/api/v2;ledgerapiv2";
option csharp_namespace = "Com.Daml.Ledger.Api.V2";
option java_outer_classname = "CommandsOuterClass";
option java_package = "com.daml.ledger.api.v2";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import "com/daml/ledger/api/v2/trace_context.proto";
import "google/protobuf/duration.proto";
import "google/rpc/status.proto";

option go_package = "github.com/digital-asset/canton/go/ledger/api/v2;ledgerapiv2";
option csharp_namespace = "Com.Daml.Ledger.Api.V2";
option java_outer_classname = "CompletionOuterClass";
option java_package = "com.daml.ledger.api.v2";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ package com.daml.ledger.api.v2;

import "com/daml/ledger/api/v2/event.proto";

option go_package = "github.com/digital-asset/canton/go/ledger/api/v2;ledgerapiv2";
option csharp_namespace = "Com.Daml.Ledger.Api.V2";
option java_outer_classname = "ContractServiceOuterClass";
option java_package = "com.daml.ledger.api.v2";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ syntax = "proto3";

package com.daml.ledger.api.v2;

option go_package = "github.com/digital-asset/canton/go/ledger/api/v2;ledgerapiv2";
option csharp_namespace = "Com.Daml.Ledger.Api.V2";
option java_outer_classname = "CryptoOuterClass";
option java_package = "com.daml.ledger.api.v2";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import "com/daml/ledger/api/v2/value.proto";
import "google/protobuf/timestamp.proto";
import "google/rpc/status.proto";

option go_package = "github.com/digital-asset/canton/go/ledger/api/v2;ledgerapiv2";
option csharp_namespace = "Com.Daml.Ledger.Api.V2";
option java_outer_classname = "EventOuterClass";
option java_package = "com.daml.ledger.api.v2";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ package com.daml.ledger.api.v2;
import "com/daml/ledger/api/v2/event.proto";
import "com/daml/ledger/api/v2/transaction_filter.proto";

option go_package = "github.com/digital-asset/canton/go/ledger/api/v2;ledgerapiv2";
option csharp_namespace = "Com.Daml.Ledger.Api.V2";
option java_outer_classname = "EventQueryServiceOuterClass";
option java_package = "com.daml.ledger.api.v2";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ syntax = "proto3";

package com.daml.ledger.api.v2;

option go_package = "github.com/digital-asset/canton/go/ledger/api/v2;ledgerapiv2";
option csharp_namespace = "Com.Daml.Ledger.Api.V2";
option java_outer_classname = "ExperimentalFeaturesOuterClass";
option java_package = "com.daml.ledger.api.v2";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ package com.daml.ledger.api.v2;

import "google/protobuf/timestamp.proto";

option go_package = "github.com/digital-asset/canton/go/ledger/api/v2;ledgerapiv2";
option csharp_namespace = "Com.Daml.Ledger.Api.V2";
option java_outer_classname = "OffsetCheckpointOuterClass";
option java_package = "com.daml.ledger.api.v2";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ package com.daml.ledger.api.v2;
import "google/protobuf/empty.proto";
import "google/protobuf/timestamp.proto";

option go_package = "github.com/digital-asset/canton/go/ledger/api/v2;ledgerapiv2";
option csharp_namespace = "Com.Daml.Ledger.Api.V2";
option java_outer_classname = "PackageReferenceOuterClass";
option java_package = "com.daml.ledger.api.v2";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ package com.daml.ledger.api.v2;

import "com/daml/ledger/api/v2/package_reference.proto";

option go_package = "github.com/digital-asset/canton/go/ledger/api/v2;ledgerapiv2";
option csharp_namespace = "Com.Daml.Ledger.Api.V2";
option java_outer_classname = "PackageServiceOuterClass";
option java_package = "com.daml.ledger.api.v2";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import "com/daml/ledger/api/v2/trace_context.proto";
import "com/daml/ledger/api/v2/value.proto";
import "google/protobuf/timestamp.proto";

option go_package = "github.com/digital-asset/canton/go/ledger/api/v2;ledgerapiv2";
option csharp_namespace = "Com.Daml.Ledger.Api.V2";
option java_outer_classname = "ReassignmentOuterClass";
option java_package = "com.daml.ledger.api.v2";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ syntax = "proto3";

package com.daml.ledger.api.v2;

option go_package = "github.com/digital-asset/canton/go/ledger/api/v2;ledgerapiv2";
option csharp_namespace = "Com.Daml.Ledger.Api.V2";
option java_outer_classname = "ReassignmentCommandOuterClass";
option java_package = "com.daml.ledger.api.v2";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import "com/daml/ledger/api/v2/event.proto";
import "com/daml/ledger/api/v2/reassignment.proto";
import "com/daml/ledger/api/v2/transaction_filter.proto";

option go_package = "github.com/digital-asset/canton/go/ledger/api/v2;ledgerapiv2";
option csharp_namespace = "Com.Daml.Ledger.Api.V2";
option java_outer_classname = "StateServiceOuterClass";
option java_package = "com.daml.ledger.api.v2";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import "com/daml/ledger/api/v2/state_service.proto";
import "com/daml/ledger/api/v2/trace_context.proto";
import "google/protobuf/timestamp.proto";

option go_package = "github.com/digital-asset/canton/go/ledger/api/v2;ledgerapiv2";
option csharp_namespace = "Com.Daml.Ledger.Api.V2";
option java_outer_classname = "TopologyTransactionOuterClass";
option java_package = "com.daml.ledger.api.v2";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ syntax = "proto3";

package com.daml.ledger.api.v2;

option go_package = "github.com/digital-asset/canton/go/ledger/api/v2;ledgerapiv2";
option csharp_namespace = "Com.Daml.Ledger.Api.V2";
option java_outer_classname = "TraceContextOuterClass";
option java_package = "com.daml.ledger.api.v2";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import "com/daml/ledger/api/v2/event.proto";
import "com/daml/ledger/api/v2/trace_context.proto";
import "google/protobuf/timestamp.proto";

option go_package = "github.com/digital-asset/canton/go/ledger/api/v2;ledgerapiv2";
option csharp_namespace = "Com.Daml.Ledger.Api.V2";
option java_outer_classname = "TransactionOuterClass";
option java_package = "com.daml.ledger.api.v2";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ package com.daml.ledger.api.v2;

import "com/daml/ledger/api/v2/value.proto";

option go_package = "github.com/digital-asset/canton/go/ledger/api/v2;ledgerapiv2";
option csharp_namespace = "Com.Daml.Ledger.Api.V2";
option java_outer_classname = "TransactionFilterOuterClass";
option java_package = "com.daml.ledger.api.v2";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import "com/daml/ledger/api/v2/topology_transaction.proto";
import "com/daml/ledger/api/v2/transaction.proto";
import "com/daml/ledger/api/v2/transaction_filter.proto";

option go_package = "github.com/digital-asset/canton/go/ledger/api/v2;ledgerapiv2";
option csharp_namespace = "Com.Daml.Ledger.Api.V2";
option java_outer_classname = "UpdateServiceOuterClass";
option java_package = "com.daml.ledger.api.v2";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ package com.daml.ledger.api.v2;
import "com/daml/ledger/api/v2/experimental_features.proto";
import "google/protobuf/duration.proto";

option go_package = "github.com/digital-asset/canton/go/ledger/api/v2;ledgerapiv2";
option csharp_namespace = "Com.Daml.Ledger.Api.V2";
option java_outer_classname = "VersionServiceOuterClass";
option java_package = "com.daml.ledger.api.v2";
Expand Down
16 changes: 16 additions & 0 deletions experiment-evidence/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Experiment evidence

Burden-of-evidence artefacts for the PR `experiment: google.api.http annotations on CommandService`.

**This directory is internal to the Peaceful Studio fork.** Delete it before submitting any upstream PR to `digital-asset/canton` — these files are review aids, not part of the contribution.

## Contents

| Subdirectory | Purpose |
|---|---|
| [`go-package-harmlessness/`](go-package-harmlessness/) | Empirical proof that adding `option go_package = "..."` to the v2 protos does not affect any existing C# / Java / Scala codegen consumer. |
| [`openapi-generation/`](openapi-generation/) | The actual OpenAPI document generated from the annotated `command_service.proto`, plus the `buf.gen.yaml` used to produce it. The 1,372-line JSON is the "after" side of the SwaggerHub comparison linked from the PR description. |

## How to verify everything from scratch

The PR description (top of #1) has the full reproducible flow: install buf, drop the three google.api / google.rpc protos into `community/lib/google-common-protos-scala/target/protobuf_external/`, run `buf build` and `buf generate`. Every artefact in this directory is regeneratable from that flow.
89 changes: 89 additions & 0 deletions experiment-evidence/go-package-harmlessness/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# Proof that `option go_package` is harmless for existing Canton consumers

## Why we needed `go_package` in the first place

Every off-the-shelf OpenAPI generator in the protobuf ecosystem is written in Go: `protoc-gen-openapiv2` (grpc-ecosystem/grpc-gateway), `protoc-gen-openapi` (google/gnostic), the buf-published variants of both. They walk the `FileDescriptorSet` for the target service and, for every `.proto` in the transitive closure, look up its declared Go import path so the generator can emit per-file artefacts.

When the option is missing the plugin fails fast:

```
unable to determine Go import path for "com/daml/ledger/api/v2/value.proto"

Please specify either:
• a "go_package" option in the .proto source file, or
• a "M" argument on the command line.
```

This is enforced even when no Go code is being emitted — it is a hard precondition for *running* the plugin. Canton's protos currently declare `csharp_namespace`, `java_package`, `java_outer_classname` but not `go_package`, because Canton has no Go target. So every Go-based OpenAPI tool refuses to run against the proto set until that gap is filled.

The fix is a one-line `option go_package = "..."` per proto file, sitting alongside the existing language-target options. Three things to prove:

1. The added option is the **only** semantic change to the compiled `FileDescriptorSet`.
2. Canton's actual codegen pipeline **never reads** `go_package`, so the option cannot affect generated Scala / Java / C# output.
3. The option is **inert by design** in protobuf — each language has its own `FileOptions` field; consumers read only their own.

The artefacts below establish each claim with byte-level evidence.

## Artefacts

| File | What it proves |
|---|---|
| `version_service.proto.before` | Verbatim copy of the proto **as it exists upstream** in `digital-asset/canton@v3.5.1-rc3`. |
| `version_service.proto.after` | Verbatim copy of the proto **after our change**. |
| `version_service.proto.diff` | Unified diff of the two source files. One added line: `+option go_package = "...";`. |
| `version_service.before.descriptor.txt` | Full textproto-decoded `FileDescriptorProto` produced by `buf build` on the upstream proto. |
| `version_service.after.descriptor.txt` | Same, on the patched proto. |
| `version_service.before.descriptor.nosourceinfo.txt` | Same as above with `source_code_info` stripped. `source_code_info` only carries source-line spans for IDE tooling; it inevitably shifts when any line is added or removed and is not semantically meaningful. |
| `version_service.after.descriptor.nosourceinfo.txt` | Same. |
| `version_service.descriptor.semantic.diff` | Unified diff of the two `.nosourceinfo` descriptors. **One added line: `+ go_package: "..."` inside the `options { }` block, alongside `java_package`, `java_outer_classname`, `csharp_namespace`. Nothing else changes — no message field, no service method, no enum, no import.** |
| `canton-build-targets.txt` | `grep` of `project/BuildCommon.scala` for every `PB.targets` declaration. Every entry routes to `scalapb.gen` or `PB.gens.java`. No `gen_go`, no `protoc-gen-go`, no Go plugin anywhere. Canton's build pipeline literally cannot read the `go_package` option, because no Go plugin is invoked. |

## Why this is sound — the protobuf-language guarantee

`google/protobuf/descriptor.proto` defines `FileOptions` as a flat message with one field per language target:

```proto
message FileOptions {
optional string java_package = 1;
optional string java_outer_classname = 8;
...
optional string go_package = 11;
...
optional string csharp_namespace = 37;
optional string swift_prefix = 39;
optional string php_class_prefix = 40;
...
}
```

Each consuming plugin reads only the field assigned to its language. `protoc-gen-java` reads `java_package` and ignores the rest. `protoc-gen-go` reads `go_package` and ignores the rest. ScalaPB reads its own dedicated `scalapb.options` extension and ignores all of the language-target fields. Adding a sibling field to `options {}` has no effect on a plugin that does not read that field — this is the whole point of how proto FileOptions are structured.

The semantic diff above demonstrates this empirically: the **only** change to the compiled descriptor is one new sibling field inside `options {}`. Every other byte of the descriptor — message definitions, service methods, RPC signatures, imports, dependencies — is identical.

## Reproduce

```bash
# from canton repo root, on this branch:
git checkout HEAD~1 -- community/ledger-api-proto/src/main/protobuf/com/daml/ledger/api/v2/version_service.proto
( cd community/ledger-api-proto/src/main/protobuf && \
buf build --path com/daml/ledger/api/v2/version_service.proto -o /tmp/version_service.before.binpb )
git checkout HEAD -- community/ledger-api-proto/src/main/protobuf/com/daml/ledger/api/v2/version_service.proto
( cd community/ledger-api-proto/src/main/protobuf && \
buf build --path com/daml/ledger/api/v2/version_service.proto -o /tmp/version_service.after.binpb )

python3 - <<'EOF'
from google.protobuf import descriptor_pb2
for state in ('before', 'after'):
fds = descriptor_pb2.FileDescriptorSet()
with open(f'/tmp/version_service.{state}.binpb', 'rb') as f:
fds.ParseFromString(f.read())
for fproto in fds.file:
if fproto.name.endswith('version_service.proto'):
fproto.ClearField('source_code_info')
open(f'/tmp/version_service.{state}.txt', 'w').write(str(fproto))
EOF

diff -u /tmp/version_service.before.txt /tmp/version_service.after.txt
```

The diff is the same one-line addition shown in `version_service.descriptor.semantic.diff`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
922: Test / PB.targets := Seq(
923: scalapb.gen() -> (Test / sourceManaged).value / "protobuf"
1005: Compile / PB.targets := Seq(
1006: scalapb.gen(flatPackage = true) -> (Compile / sourceManaged).value / "protobuf"
1119: Compile / PB.targets := Seq(
1120: scalapb.gen(flatPackage = true) -> (Compile / sourceManaged).value / "protobuf"
1122: Test / PB.targets := Seq(
1123: scalapb.gen(flatPackage = true) -> (Test / sourceManaged).value / "protobuf"
1160: Compile / PB.targets := Seq(
1161: scalapb.gen(flatPackage = true) -> (Compile / sourceManaged).value / "protobuf"
1205: Compile / PB.targets := Seq(
1206: scalapb.gen(flatPackage = true) -> (Compile / sourceManaged).value / "protobuf"
1262: Compile / PB.targets := Seq(
1263: scalapb.gen(flatPackage = true) -> (Compile / sourceManaged).value / "protobuf"
1589: Compile / PB.targets := Seq(
1590: scalapb.gen(flatPackage = true) -> (Compile / sourceManaged).value / "protobuf"
2002: Compile / PB.targets := Seq(
2003: scalapb.gen(flatPackage = false) -> (Compile / sourceManaged).value / "protobuf"
2042: Test / PB.targets := Seq(
2044: PB.gens.java -> (Test / sourceManaged).value / "protobuf",
2046: scalapb.gen(
2916: Compile / PB.targets := Seq(
2917: scalapb.gen(flatPackage = true) -> (Compile / sourceManaged).value / "protobuf"
3141: Compile / PB.targets := Seq(
3143: scalapb.gen(
Loading
Loading