@distrohelena/canton-typescript-sdk 0.1.5 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +333 -1
- package/dist/client/canton-client-options.d.ts +3 -0
- package/dist/client/canton-client-options.js +2 -0
- package/dist/client/service-registry.js +3 -2
- package/dist/core/errors/grpc-transport-error.d.ts +14 -0
- package/dist/core/errors/grpc-transport-error.js +76 -0
- package/dist/core/types/canton-hash-purpose.d.ts +2 -1
- package/dist/core/types/canton-hash-purpose.js +1 -0
- package/dist/core/types/daml-numeric.d.ts +6 -0
- package/dist/core/types/daml-numeric.js +14 -0
- package/dist/core/types/daml-party.d.ts +6 -0
- package/dist/core/types/daml-party.js +14 -0
- package/dist/core/types/requests/create-decentralized-party-request.d.ts +41 -0
- package/dist/core/types/requests/create-decentralized-party-request.js +82 -0
- package/dist/core/types/requests/create-external-party-request.d.ts +42 -0
- package/dist/core/types/requests/create-external-party-request.js +47 -0
- package/dist/core/types/requests/finalize-decentralized-party-request.d.ts +39 -0
- package/dist/core/types/requests/finalize-decentralized-party-request.js +42 -0
- package/dist/core/types/requests/get-active-contracts-page-request.d.ts +15 -2
- package/dist/core/types/requests/get-active-contracts-page-request.js +4 -0
- package/dist/core/types/topology/topology-signature-format.d.ts +2 -1
- package/dist/core/types/topology/topology-signature-format.js +1 -0
- package/dist/daml-lf/container/dar-archive-entry.d.ts +8 -0
- package/dist/daml-lf/container/dar-archive-entry.js +8 -0
- package/dist/daml-lf/container/dar-archive-loader.js +14 -0
- package/dist/daml-lf/container/dar-archive.d.ts +6 -0
- package/dist/daml-lf/container/dar-archive.js +4 -0
- package/dist/daml-lf/container/dar-source-bundle-loader.d.ts +5 -0
- package/dist/daml-lf/container/dar-source-bundle-loader.js +33 -0
- package/dist/daml-lf/container/dar-source-bundle.d.ts +45 -0
- package/dist/daml-lf/container/dar-source-bundle.js +11 -0
- package/dist/daml-lf/container/dar-source-file-entry.d.ts +8 -0
- package/dist/daml-lf/container/dar-source-file-entry.js +8 -0
- package/dist/daml-lf/daml-lf-compilation.d.ts +12 -0
- package/dist/daml-lf/daml-lf-compilation.js +35 -0
- package/dist/daml-lf/index.d.ts +11 -0
- package/dist/daml-lf/index.js +10 -0
- package/dist/daml-lf/interpreter/daml-lf-builtin-dispatch.d.ts +43 -0
- package/dist/daml-lf/interpreter/daml-lf-builtin-dispatch.js +933 -0
- package/dist/daml-lf/interpreter/daml-lf-evaluator.d.ts +95 -0
- package/dist/daml-lf/interpreter/daml-lf-evaluator.js +1131 -0
- package/dist/daml-lf/interpreter/daml-lf-interpreter-scaffold.d.ts +3 -0
- package/dist/daml-lf/interpreter/daml-lf-interpreter-scaffold.js +6 -1
- package/dist/daml-lf/interpreter/daml-lf-lexical-scope.d.ts +13 -0
- package/dist/daml-lf/interpreter/daml-lf-lexical-scope.js +46 -0
- package/dist/daml-lf/interpreter/daml-lf-runtime-frame.d.ts +16 -0
- package/dist/daml-lf/interpreter/daml-lf-runtime-frame.js +15 -0
- package/dist/daml-lf/interpreter/daml-lf-runtime-value.d.ts +21 -0
- package/dist/daml-lf/interpreter/daml-lf-runtime-value.js +4 -1
- package/dist/daml-lf/interpreter/daml-lf-step-kind.d.ts +7 -0
- package/dist/daml-lf/interpreter/daml-lf-step-kind.js +8 -0
- package/dist/daml-lf/interpreter/daml-lf-trace-sink.interface.d.ts +30 -0
- package/dist/daml-lf/interpreter/daml-lf-trace-sink.interface.js +1 -0
- package/dist/daml-lf/model/daml-lf-builtin-type.d.ts +3 -0
- package/dist/daml-lf/model/daml-lf-builtin-type.js +3 -0
- package/dist/daml-lf/model/daml-lf-choice.d.ts +5 -0
- package/dist/daml-lf/model/daml-lf-choice.js +4 -0
- package/dist/daml-lf/model/daml-lf-expression-path.d.ts +2 -0
- package/dist/daml-lf/model/daml-lf-expression-path.js +81 -0
- package/dist/daml-lf/model/daml-lf-expression.d.ts +146 -0
- package/dist/daml-lf/model/daml-lf-expression.js +71 -0
- package/dist/daml-lf/model/daml-lf-template.d.ts +2 -0
- package/dist/daml-lf/model/daml-lf-template.js +2 -0
- package/dist/daml-lf/model/daml-lf-type.d.ts +2 -0
- package/dist/daml-lf/model/daml-lf-type.js +4 -0
- package/dist/daml-lf/model/lf-2-model-mapper.d.ts +5 -0
- package/dist/daml-lf/model/lf-2-model-mapper.js +445 -12
- package/dist/debugger/errors/replay-determinism.exception.d.ts +3 -0
- package/dist/debugger/errors/replay-determinism.exception.js +3 -0
- package/dist/debugger/errors/replay-missing-package.exception.d.ts +3 -0
- package/dist/debugger/errors/replay-missing-package.exception.js +3 -0
- package/dist/debugger/errors/replay-missing-source.exception.d.ts +3 -0
- package/dist/debugger/errors/replay-missing-source.exception.js +3 -0
- package/dist/debugger/errors/replay-source-map.exception.d.ts +3 -0
- package/dist/debugger/errors/replay-source-map.exception.js +3 -0
- package/dist/debugger/errors/replay-state-hydration.exception.d.ts +3 -0
- package/dist/debugger/errors/replay-state-hydration.exception.js +3 -0
- package/dist/debugger/errors/replay-unsupported-lf-construct.exception.d.ts +3 -0
- package/dist/debugger/errors/replay-unsupported-lf-construct.exception.js +3 -0
- package/dist/debugger/errors/replay-unsupported-update.exception.d.ts +3 -0
- package/dist/debugger/errors/replay-unsupported-update.exception.js +3 -0
- package/dist/debugger/index.d.ts +31 -0
- package/dist/debugger/index.js +31 -0
- package/dist/debugger/ledger-replay-debugger-client.d.ts +31 -0
- package/dist/debugger/ledger-replay-debugger-client.js +53 -0
- package/dist/debugger/replay/ledger-replay-environment-builder.d.ts +95 -0
- package/dist/debugger/replay/ledger-replay-environment-builder.js +249 -0
- package/dist/debugger/replay/ledger-replay-session-loader.d.ts +78 -0
- package/dist/debugger/replay/ledger-replay-session-loader.js +565 -0
- package/dist/debugger/replay/replay-artifact-resolver.d.ts +30 -0
- package/dist/debugger/replay/replay-artifact-resolver.js +210 -0
- package/dist/debugger/replay/replay-determinism-validator.d.ts +12 -0
- package/dist/debugger/replay/replay-determinism-validator.js +161 -0
- package/dist/debugger/replay/replay-entrypoint-definition-resolver.d.ts +40 -0
- package/dist/debugger/replay/replay-entrypoint-definition-resolver.js +337 -0
- package/dist/debugger/replay/replay-entrypoint.d.ts +22 -0
- package/dist/debugger/replay/replay-entrypoint.js +14 -0
- package/dist/debugger/replay/replay-ledger-value-normalizer.d.ts +7 -0
- package/dist/debugger/replay/replay-ledger-value-normalizer.js +194 -0
- package/dist/debugger/replay/replay-update-loader.d.ts +24 -0
- package/dist/debugger/replay/replay-update-loader.js +94 -0
- package/dist/debugger/replay/replay-update-visibility-validator.d.ts +19 -0
- package/dist/debugger/replay/replay-update-visibility-validator.js +19 -0
- package/dist/debugger/session/in-memory-replay-session-store.d.ts +27 -0
- package/dist/debugger/session/in-memory-replay-session-store.js +109 -0
- package/dist/debugger/session/replay-phase.d.ts +7 -0
- package/dist/debugger/session/replay-phase.js +8 -0
- package/dist/debugger/session/replay-scope.d.ts +10 -0
- package/dist/debugger/session/replay-scope.js +10 -0
- package/dist/debugger/session/replay-session-metadata.d.ts +10 -0
- package/dist/debugger/session/replay-session-metadata.js +10 -0
- package/dist/debugger/session/replay-session-request.d.ts +6 -0
- package/dist/debugger/session/replay-session-request.js +10 -0
- package/dist/debugger/session/replay-session.d.ts +12 -0
- package/dist/debugger/session/replay-session.js +10 -0
- package/dist/debugger/session/replay-source-location.d.ts +17 -0
- package/dist/debugger/session/replay-source-location.js +16 -0
- package/dist/debugger/session/replay-stack-frame.d.ts +8 -0
- package/dist/debugger/session/replay-stack-frame.js +8 -0
- package/dist/debugger/session/replay-state-delta.d.ts +29 -0
- package/dist/debugger/session/replay-state-delta.js +24 -0
- package/dist/debugger/session/replay-step-advance-result.d.ts +24 -0
- package/dist/debugger/session/replay-step-advance-result.js +16 -0
- package/dist/debugger/session/replay-step.d.ts +30 -0
- package/dist/debugger/session/replay-step.js +24 -0
- package/dist/debugger/session/replay-value-preview.d.ts +8 -0
- package/dist/debugger/session/replay-value-preview.js +15 -0
- package/dist/debugger/source/daml-source-mapper.d.ts +12 -0
- package/dist/debugger/source/daml-source-mapper.js +21 -0
- package/dist/debugger/source/dar-source-map-metadata.d.ts +26 -0
- package/dist/debugger/source/dar-source-map-metadata.js +10 -0
- package/dist/debugger/source/source-coverage-validator.d.ts +8 -0
- package/dist/debugger/source/source-coverage-validator.js +16 -0
- package/dist/debugger/source/source-indexed-compilation.d.ts +45 -0
- package/dist/debugger/source/source-indexed-compilation.js +110 -0
- package/dist/debugger/source/source-mapping-precision.d.ts +5 -0
- package/dist/debugger/source/source-mapping-precision.js +4 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.js +12 -0
- package/dist/query/cache/memory-query-cache.d.ts +9 -0
- package/dist/query/cache/memory-query-cache.js +24 -0
- package/dist/query/cache/query-cache-store.d.ts +5 -0
- package/dist/query/cache/query-cache-store.js +1 -0
- package/dist/query/canton-manager-options.d.ts +17 -0
- package/dist/query/canton-manager-options.js +1 -0
- package/dist/query/canton-manager.d.ts +11 -0
- package/dist/query/canton-manager.js +42 -0
- package/dist/query/errors/pqs-query-error.d.ts +10 -0
- package/dist/query/errors/pqs-query-error.js +11 -0
- package/dist/query/errors/pqs-schema-profile-error.d.ts +3 -0
- package/dist/query/errors/pqs-schema-profile-error.js +3 -0
- package/dist/query/errors/query-capability-error.d.ts +7 -0
- package/dist/query/errors/query-capability-error.js +10 -0
- package/dist/query/grpc/grpc-contract-query-client.d.ts +32 -0
- package/dist/query/grpc/grpc-contract-query-client.js +126 -0
- package/dist/query/model-types.d.ts +258 -0
- package/dist/query/model-types.js +14 -0
- package/dist/query/pqs/pqs-pool.d.ts +13 -0
- package/dist/query/pqs/pqs-pool.js +18 -0
- package/dist/query/pqs/pqs-query-client.d.ts +49 -0
- package/dist/query/pqs/pqs-query-client.js +324 -0
- package/dist/query/pqs/pqs-schema-profile.d.ts +25 -0
- package/dist/query/pqs/pqs-schema-profile.js +120 -0
- package/dist/query/pqs/pqs-sql-compiler.d.ts +7 -0
- package/dist/query/pqs/pqs-sql-compiler.js +132 -0
- package/dist/query/pqs/read-only-sql.d.ts +1 -0
- package/dist/query/pqs/read-only-sql.js +35 -0
- package/dist/query/query-client.d.ts +61 -0
- package/dist/query/query-client.js +1 -0
- package/dist/query/query-source.d.ts +4 -0
- package/dist/query/query-source.js +5 -0
- package/dist/services/party-management/decentralized-party-lifecycle.d.ts +6 -0
- package/dist/services/party-management/decentralized-party-lifecycle.js +82 -0
- package/dist/services/party-management/party-management-service-client.d.ts +16 -1
- package/dist/services/party-management/party-management-service-client.js +142 -1
- package/dist/services/topology-manager-write/topology-signed-transaction-assembler.js +4 -0
- package/dist/testing/campaign/campaign-artifact.d.ts +20 -0
- package/dist/testing/campaign/campaign-artifact.js +147 -0
- package/dist/testing/campaign/campaign-definition.d.ts +9 -0
- package/dist/testing/campaign/campaign-definition.js +78 -0
- package/dist/testing/campaign/campaign-metrics.d.ts +32 -0
- package/dist/testing/campaign/campaign-metrics.js +26 -0
- package/dist/testing/campaign/campaign-model.d.ts +11 -0
- package/dist/testing/campaign/campaign-model.js +21 -0
- package/dist/testing/campaign/campaign-runner.d.ts +99 -0
- package/dist/testing/campaign/campaign-runner.js +194 -0
- package/dist/testing/campaign/campaign-scheduler.d.ts +40 -0
- package/dist/testing/campaign/campaign-scheduler.js +75 -0
- package/dist/testing/campaign/campaign-types.d.ts +52 -0
- package/dist/testing/campaign/campaign-types.js +11 -0
- package/dist/testing/daml/daml-action-arbitrary.d.ts +13 -0
- package/dist/testing/daml/daml-action-arbitrary.js +24 -0
- package/dist/testing/daml/daml-choice-action-arbitrary.d.ts +18 -0
- package/dist/testing/daml/daml-choice-action-arbitrary.js +27 -0
- package/dist/testing/daml/daml-create-action-arbitrary.d.ts +19 -0
- package/dist/testing/daml/daml-create-action-arbitrary.js +34 -0
- package/dist/testing/daml/daml-testing-catalog.d.ts +38 -0
- package/dist/testing/daml/daml-testing-catalog.js +40 -0
- package/dist/testing/daml/daml-value-arbitrary.d.ts +8 -0
- package/dist/testing/daml/daml-value-arbitrary.js +43 -0
- package/dist/testing/daml/declarative-campaign-arbitrary.d.ts +15 -0
- package/dist/testing/daml/declarative-campaign-arbitrary.js +30 -0
- package/dist/testing/errors/invariant-campaign-failure.d.ts +24 -0
- package/dist/testing/errors/invariant-campaign-failure.js +37 -0
- package/dist/testing/errors/testing-configuration-error.d.ts +3 -0
- package/dist/testing/errors/testing-configuration-error.js +6 -0
- package/dist/testing/handlers/handler.d.ts +19 -0
- package/dist/testing/handlers/handler.js +31 -0
- package/dist/testing/index.d.ts +22 -0
- package/dist/testing/index.js +22 -0
- package/dist/testing/runtime/campaign-isolation.d.ts +14 -0
- package/dist/testing/runtime/campaign-isolation.js +23 -0
- package/dist/testing/runtime/canton-test-runtime.d.ts +58 -0
- package/dist/testing/runtime/canton-test-runtime.js +138 -0
- package/dist/testing/runtime/declarative-action-executor.d.ts +16 -0
- package/dist/testing/runtime/declarative-action-executor.js +41 -0
- package/dist/testing/targets/target.d.ts +49 -0
- package/dist/testing/targets/target.js +121 -0
- package/dist/transports/grpc/grpc-channel-factory.js +31 -1
- package/dist/transports/grpc/grpc-transport.js +5 -3
- package/dist/transports/grpc/mappers/commands-mapper.js +18 -0
- package/dist/transports/grpc/mappers/contracts-mapper.d.ts +3 -1
- package/dist/transports/grpc/mappers/contracts-mapper.js +16 -3
- package/dist/transports/grpc/mappers/topology-manager-write-mapper.js +59 -1
- package/dist/transports/json/mappers/commands-mapper.js +20 -6
- package/node/.generated/start-local/additional-config.extra-participants.conf +37 -0
- package/node/.generated/start-local/additional-config.extra-validators.conf +35 -0
- package/node/.generated/start-local/compose-extra-participants.yaml +147 -0
- package/node/.generated/start-local/extra-participants.env +30 -0
- package/node/es256-jwt.mjs +177 -0
- package/node/start-local.sh +886 -0
- package/node/stop-local.sh +200 -0
- package/node/test-start-local.sh +354 -0
- package/node/test-stop-local.sh +112 -0
- package/package.json +21 -2
|
@@ -0,0 +1,1131 @@
|
|
|
1
|
+
import { ValidationError } from "../../core/errors/validation-error.js";
|
|
2
|
+
import { ReplaySourceMapException } from "../../debugger/errors/replay-source-map.exception.js";
|
|
3
|
+
import { DamlLfBuiltinType } from "../model/daml-lf-builtin-type.js";
|
|
4
|
+
import { DamlLfExpression } from "../model/daml-lf-expression.js";
|
|
5
|
+
import { DamlLfTemplateId } from "../model/daml-lf-template-id.js";
|
|
6
|
+
import { DamlLfType } from "../model/daml-lf-type.js";
|
|
7
|
+
import { TypeConReference } from "../model/type-con-reference.js";
|
|
8
|
+
import { DamlLfBuiltinDispatch } from "./daml-lf-builtin-dispatch.js";
|
|
9
|
+
import { DamlLfLexicalScope } from "./daml-lf-lexical-scope.js";
|
|
10
|
+
import { DAML_LF_CONTRACT_ID_MARKER_KEY, DAML_LF_PARTY_MARKER_KEY, DAML_LF_RECORD_ID_MARKER_KEY, } from "./daml-lf-runtime-value.js";
|
|
11
|
+
import { DamlLfRuntimeFrame } from "./daml-lf-runtime-frame.js";
|
|
12
|
+
import { DamlLfStepKind } from "./daml-lf-step-kind.js";
|
|
13
|
+
class DamlLfThrownException extends Error {
|
|
14
|
+
value;
|
|
15
|
+
constructor(value) {
|
|
16
|
+
super("daml lf threw an exception");
|
|
17
|
+
this.value = value;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export class DamlLfEvaluator {
|
|
21
|
+
compilation;
|
|
22
|
+
builtinDispatch;
|
|
23
|
+
nextFrameNumber = 1;
|
|
24
|
+
activeReplayContext;
|
|
25
|
+
semanticModel;
|
|
26
|
+
constructor(compilation, builtinDispatch = new DamlLfBuiltinDispatch()) {
|
|
27
|
+
this.compilation = compilation;
|
|
28
|
+
this.builtinDispatch = builtinDispatch;
|
|
29
|
+
this.semanticModel = this.compilation.createSemanticModel();
|
|
30
|
+
void this.compilation;
|
|
31
|
+
}
|
|
32
|
+
getCompilation() {
|
|
33
|
+
return this.compilation;
|
|
34
|
+
}
|
|
35
|
+
getBuiltinDispatch() {
|
|
36
|
+
return this.builtinDispatch;
|
|
37
|
+
}
|
|
38
|
+
evaluateValueDefinitionOrThrow(definition, traceSink) {
|
|
39
|
+
const frame = this.createFrame(definition);
|
|
40
|
+
return this.evaluateExpressionOrThrow(definition.expression, frame, traceSink);
|
|
41
|
+
}
|
|
42
|
+
evaluateReplayEntrypointOrThrow(definition, environment, traceSink) {
|
|
43
|
+
const frame = this.createFrame(definition);
|
|
44
|
+
const replayExpression = environment.entrypointExpression ?? definition.expression;
|
|
45
|
+
const replayContext = {
|
|
46
|
+
environment,
|
|
47
|
+
effects: [],
|
|
48
|
+
createdContracts: new Map(),
|
|
49
|
+
observedCreateContractIds: [
|
|
50
|
+
...(environment.observedCreateContractIds ?? []),
|
|
51
|
+
],
|
|
52
|
+
nextSyntheticContractIdNumber: 1,
|
|
53
|
+
nextObservedCreateIndex: 0,
|
|
54
|
+
};
|
|
55
|
+
this.activeReplayContext = replayContext;
|
|
56
|
+
try {
|
|
57
|
+
const shouldEmitEntrypointEffects = !this.isUpdateDrivenEntrypointExpression(replayExpression);
|
|
58
|
+
const shouldEmitTopLevelExerciseEffect = !shouldEmitEntrypointEffects
|
|
59
|
+
&& environment.entrypoint.kind === "exercise"
|
|
60
|
+
&& environment.entrypointBindingMode === "templateChoice";
|
|
61
|
+
if (shouldEmitEntrypointEffects || shouldEmitTopLevelExerciseEffect) {
|
|
62
|
+
for (const effect of this.createReplayEffects(environment)) {
|
|
63
|
+
replayContext.effects.push(effect);
|
|
64
|
+
traceSink?.onStep({
|
|
65
|
+
kind: DamlLfStepKind.stateEffect,
|
|
66
|
+
expression: replayExpression,
|
|
67
|
+
frame,
|
|
68
|
+
locals: frame.scope.snapshotBindings(),
|
|
69
|
+
stateEffect: effect,
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return {
|
|
74
|
+
value: this.evaluateReplayExpressionOrThrow(replayExpression, frame, environment, traceSink),
|
|
75
|
+
effects: [...replayContext.effects],
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
finally {
|
|
79
|
+
this.activeReplayContext = undefined;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
evaluateExpressionOrThrow(expression, frame, traceSink) {
|
|
83
|
+
traceSink?.onStep({
|
|
84
|
+
kind: DamlLfStepKind.enterExpression,
|
|
85
|
+
expression,
|
|
86
|
+
frame,
|
|
87
|
+
locals: frame.scope.snapshotBindings(),
|
|
88
|
+
});
|
|
89
|
+
const value = this.resolveExpressionValue(expression, frame, traceSink);
|
|
90
|
+
traceSink?.onStep({
|
|
91
|
+
kind: DamlLfStepKind.exitExpression,
|
|
92
|
+
expression,
|
|
93
|
+
frame,
|
|
94
|
+
locals: frame.scope.snapshotBindings(),
|
|
95
|
+
value,
|
|
96
|
+
});
|
|
97
|
+
return value;
|
|
98
|
+
}
|
|
99
|
+
createReplayEffects(environment) {
|
|
100
|
+
if (environment.entrypoint.kind === "exercise") {
|
|
101
|
+
return [
|
|
102
|
+
{
|
|
103
|
+
kind: "exercise",
|
|
104
|
+
contractId: environment.entrypoint.contractId,
|
|
105
|
+
templateId: environment.entrypoint.templateId,
|
|
106
|
+
choice: environment.entrypoint.choice,
|
|
107
|
+
argument: environment.entrypoint.argument,
|
|
108
|
+
},
|
|
109
|
+
];
|
|
110
|
+
}
|
|
111
|
+
return [
|
|
112
|
+
{
|
|
113
|
+
kind: "create",
|
|
114
|
+
templateId: environment.entrypoint.templateId,
|
|
115
|
+
payload: environment.entrypoint.argument,
|
|
116
|
+
},
|
|
117
|
+
];
|
|
118
|
+
}
|
|
119
|
+
createFrame(definition, identityOverride) {
|
|
120
|
+
const identity = identityOverride
|
|
121
|
+
?? this.compilation.getValueDefinitionIdentityOrThrow(definition);
|
|
122
|
+
return new DamlLfRuntimeFrame({
|
|
123
|
+
frameId: `frame-${this.nextFrameNumber++}`,
|
|
124
|
+
packageId: identity.packageId,
|
|
125
|
+
moduleName: identity.moduleName,
|
|
126
|
+
definition,
|
|
127
|
+
scope: new DamlLfLexicalScope(),
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
resolveExpressionValue(expression, frame, traceSink) {
|
|
131
|
+
if (expression.textLiteral !== undefined) {
|
|
132
|
+
return {
|
|
133
|
+
kind: "text",
|
|
134
|
+
value: expression.textLiteral,
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
if (expression.numericLiteral !== undefined) {
|
|
138
|
+
return {
|
|
139
|
+
kind: "numeric",
|
|
140
|
+
value: expression.numericLiteral,
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
if (expression.int64Literal !== undefined) {
|
|
144
|
+
return {
|
|
145
|
+
kind: "int64",
|
|
146
|
+
value: expression.int64Literal,
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
if (expression.variableName !== undefined) {
|
|
150
|
+
const value = frame.scope.getBinding(expression.variableName);
|
|
151
|
+
if (value === undefined) {
|
|
152
|
+
throw new ValidationError(`daml lf variable '${expression.variableName}' is not bound`);
|
|
153
|
+
}
|
|
154
|
+
return value;
|
|
155
|
+
}
|
|
156
|
+
if (expression.builtinConstructor !== undefined) {
|
|
157
|
+
switch (expression.builtinConstructor) {
|
|
158
|
+
case "true":
|
|
159
|
+
return {
|
|
160
|
+
kind: "boolean",
|
|
161
|
+
value: true,
|
|
162
|
+
};
|
|
163
|
+
case "false":
|
|
164
|
+
return {
|
|
165
|
+
kind: "boolean",
|
|
166
|
+
value: false,
|
|
167
|
+
};
|
|
168
|
+
default:
|
|
169
|
+
return {
|
|
170
|
+
kind: "unit",
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
if (expression.builtinFunction !== undefined) {
|
|
175
|
+
return {
|
|
176
|
+
kind: "builtin",
|
|
177
|
+
builtinFunction: expression.builtinFunction,
|
|
178
|
+
appliedArguments: [],
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
if (expression.lambda !== undefined) {
|
|
182
|
+
return {
|
|
183
|
+
kind: "closure",
|
|
184
|
+
parameters: expression.lambda.parameters,
|
|
185
|
+
body: expression.lambda.body,
|
|
186
|
+
frame,
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
if (expression.application !== undefined) {
|
|
190
|
+
const functionValue = this.evaluateExpressionOrThrow(expression.application.function, frame, traceSink);
|
|
191
|
+
const argumentValues = expression.application.arguments.map((argument) => this.evaluateExpressionOrThrow(argument, frame, traceSink));
|
|
192
|
+
return this.applyFunctionOrThrow(functionValue, argumentValues, traceSink);
|
|
193
|
+
}
|
|
194
|
+
if (expression.letExpression !== undefined) {
|
|
195
|
+
const scopedFrame = this.deriveFrame(frame, frame.scope.createChild());
|
|
196
|
+
for (const binding of expression.letExpression.bindings) {
|
|
197
|
+
const boundValue = this.evaluateExpressionOrThrow(binding.value, scopedFrame, traceSink);
|
|
198
|
+
scopedFrame.scope.setBinding(binding.name, boundValue);
|
|
199
|
+
}
|
|
200
|
+
return this.evaluateExpressionOrThrow(expression.letExpression.body, scopedFrame, traceSink);
|
|
201
|
+
}
|
|
202
|
+
if (expression.recordConstruction !== undefined) {
|
|
203
|
+
return this.createRecordRuntimeValue(Object.fromEntries(expression.recordConstruction.fields.map((field) => [
|
|
204
|
+
field.name,
|
|
205
|
+
this.evaluateExpressionOrThrow(field.value, frame, traceSink),
|
|
206
|
+
])));
|
|
207
|
+
}
|
|
208
|
+
if (expression.recordProjection !== undefined) {
|
|
209
|
+
const recordValue = this.evaluateExpressionOrThrow(expression.recordProjection.record, frame, traceSink);
|
|
210
|
+
if (recordValue.kind === "record") {
|
|
211
|
+
const recordFields = recordValue.fields;
|
|
212
|
+
const fieldValue = recordFields[expression.recordProjection.fieldName];
|
|
213
|
+
if (fieldValue === undefined) {
|
|
214
|
+
throw new ValidationError(`daml lf record projection could not find field '${expression.recordProjection.fieldName}'`);
|
|
215
|
+
}
|
|
216
|
+
return fieldValue;
|
|
217
|
+
}
|
|
218
|
+
const rawValue = this.unwrapRuntimeValue(recordValue);
|
|
219
|
+
if (rawValue === null
|
|
220
|
+
|| typeof rawValue !== "object"
|
|
221
|
+
|| Array.isArray(rawValue)) {
|
|
222
|
+
throw new ValidationError(`daml lf record projection requires an object value for field '${expression.recordProjection.fieldName}'`);
|
|
223
|
+
}
|
|
224
|
+
return this.hydrateRuntimeValue(this.readLedgerRecordField(rawValue, expression.recordProjection.fieldName));
|
|
225
|
+
}
|
|
226
|
+
if (expression.recordUpdate !== undefined) {
|
|
227
|
+
const recordValue = this.evaluateExpressionOrThrow(expression.recordUpdate.record, frame, traceSink);
|
|
228
|
+
if (recordValue.kind === "record") {
|
|
229
|
+
const recordFields = recordValue.fields;
|
|
230
|
+
return this.createRecordRuntimeValue({
|
|
231
|
+
...recordFields,
|
|
232
|
+
[expression.recordUpdate.fieldName]: this.evaluateExpressionOrThrow(expression.recordUpdate.value, frame, traceSink),
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
const rawValue = this.unwrapRuntimeValue(recordValue);
|
|
236
|
+
if (rawValue === null
|
|
237
|
+
|| typeof rawValue !== "object"
|
|
238
|
+
|| Array.isArray(rawValue)) {
|
|
239
|
+
throw new ValidationError(`daml lf record update requires an object value for field '${expression.recordUpdate.fieldName}'`);
|
|
240
|
+
}
|
|
241
|
+
return this.hydrateRuntimeValue({
|
|
242
|
+
...rawValue,
|
|
243
|
+
...this.createLedgerRecordFieldUpdate(rawValue, expression.recordUpdate.fieldName, this.unwrapRuntimeValue(this.evaluateExpressionOrThrow(expression.recordUpdate.value, frame, traceSink))),
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
if (expression.throwExpression !== undefined) {
|
|
247
|
+
throw new DamlLfThrownException(this.evaluateExpressionOrThrow(expression.throwExpression.exception, frame, traceSink));
|
|
248
|
+
}
|
|
249
|
+
if (expression.variantConstruction !== undefined) {
|
|
250
|
+
return this.hydrateRuntimeValue({
|
|
251
|
+
constructor: expression.variantConstruction.constructorName,
|
|
252
|
+
value: this.unwrapRuntimeValue(this.evaluateExpressionOrThrow(expression.variantConstruction.argument, frame, traceSink)),
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
if (expression.optionalConstruction !== undefined) {
|
|
256
|
+
return expression.optionalConstruction.value === undefined
|
|
257
|
+
? {
|
|
258
|
+
kind: "unit",
|
|
259
|
+
}
|
|
260
|
+
: this.evaluateExpressionOrThrow(expression.optionalConstruction.value, frame, traceSink);
|
|
261
|
+
}
|
|
262
|
+
if (expression.enumConstruction !== undefined) {
|
|
263
|
+
return this.hydrateRuntimeValue(expression.enumConstruction.constructorName);
|
|
264
|
+
}
|
|
265
|
+
if (expression.listConstruction !== undefined) {
|
|
266
|
+
const front = expression.listConstruction.front.map((item) => this.unwrapRuntimeValue(this.evaluateExpressionOrThrow(item, frame, traceSink)));
|
|
267
|
+
const tail = expression.listConstruction.tail === undefined
|
|
268
|
+
? []
|
|
269
|
+
: this.unwrapRuntimeValue(this.evaluateExpressionOrThrow(expression.listConstruction.tail, frame, traceSink));
|
|
270
|
+
if (!Array.isArray(tail)) {
|
|
271
|
+
throw new ValidationError("daml lf list construction requires an array tail");
|
|
272
|
+
}
|
|
273
|
+
return this.hydrateRuntimeValue([...front, ...tail]);
|
|
274
|
+
}
|
|
275
|
+
if (expression.updateExpression !== undefined) {
|
|
276
|
+
return this.evaluateUpdateExpressionOrThrow(expression, frame, traceSink);
|
|
277
|
+
}
|
|
278
|
+
if (expression.caseExpression !== undefined) {
|
|
279
|
+
const scrutinee = this.evaluateExpressionOrThrow(expression.caseExpression.scrutinee, frame, traceSink);
|
|
280
|
+
const matchingAlternative = expression.caseExpression.alternatives.find((alternative) => this.matchesCaseAlternative(alternative, scrutinee));
|
|
281
|
+
if (matchingAlternative === undefined) {
|
|
282
|
+
const scrutineeDescription = scrutinee.kind === "builtin"
|
|
283
|
+
? `${String(scrutinee.builtinFunction)}(${scrutinee.appliedArguments
|
|
284
|
+
.map((argument) => argument.kind)
|
|
285
|
+
.join(", ")})`
|
|
286
|
+
: scrutinee.kind;
|
|
287
|
+
throw new ValidationError(`daml lf case expression in '${frame.definition.name}' did not match any alternative for '${scrutineeDescription}' across [${expression.caseExpression.alternatives
|
|
288
|
+
.map((alternative) => alternative.patternKind)
|
|
289
|
+
.join(", ")}]`);
|
|
290
|
+
}
|
|
291
|
+
if ((matchingAlternative.patternKind === "variant"
|
|
292
|
+
|| matchingAlternative.patternKind === "optionalSome"
|
|
293
|
+
|| matchingAlternative.patternKind === "cons")) {
|
|
294
|
+
const rawValue = this.unwrapRuntimeValue(scrutinee);
|
|
295
|
+
if (matchingAlternative.patternKind === "optionalSome"
|
|
296
|
+
|| matchingAlternative.patternKind === "cons"
|
|
297
|
+
|| (rawValue !== null
|
|
298
|
+
&& typeof rawValue === "object"
|
|
299
|
+
&& "value" in rawValue)) {
|
|
300
|
+
const scopedFrame = this.deriveFrame(frame, frame.scope.createChild());
|
|
301
|
+
if (matchingAlternative.patternKind === "cons"
|
|
302
|
+
&& Array.isArray(rawValue)) {
|
|
303
|
+
if (matchingAlternative.headBinderName !== undefined) {
|
|
304
|
+
scopedFrame.scope.setBinding(matchingAlternative.headBinderName, this.hydrateRuntimeValue(rawValue[0]));
|
|
305
|
+
}
|
|
306
|
+
if (matchingAlternative.tailBinderName !== undefined) {
|
|
307
|
+
scopedFrame.scope.setBinding(matchingAlternative.tailBinderName, this.hydrateRuntimeValue(rawValue.slice(1)));
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
else if (matchingAlternative.binderName !== undefined) {
|
|
311
|
+
scopedFrame.scope.setBinding(matchingAlternative.binderName, this.hydrateRuntimeValue(matchingAlternative.patternKind === "optionalSome"
|
|
312
|
+
? rawValue
|
|
313
|
+
: rawValue.value));
|
|
314
|
+
}
|
|
315
|
+
return this.evaluateExpressionOrThrow(matchingAlternative.body, scopedFrame, traceSink);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
return this.evaluateExpressionOrThrow(matchingAlternative.body, frame, traceSink);
|
|
319
|
+
}
|
|
320
|
+
if (expression.valueReference !== undefined) {
|
|
321
|
+
const definition = this.compilation.getValueDefinitionOrThrow(expression.valueReference.packageId, expression.valueReference.moduleName, expression.valueReference.definitionName);
|
|
322
|
+
const frame = this.createFrame(definition);
|
|
323
|
+
traceSink?.onStep({
|
|
324
|
+
kind: DamlLfStepKind.call,
|
|
325
|
+
expression,
|
|
326
|
+
frame,
|
|
327
|
+
locals: frame.scope.snapshotBindings(),
|
|
328
|
+
});
|
|
329
|
+
const value = this.evaluateExpressionOrThrow(definition.expression, frame, traceSink);
|
|
330
|
+
traceSink?.onStep({
|
|
331
|
+
kind: DamlLfStepKind.return,
|
|
332
|
+
expression,
|
|
333
|
+
frame,
|
|
334
|
+
locals: frame.scope.snapshotBindings(),
|
|
335
|
+
value,
|
|
336
|
+
});
|
|
337
|
+
return value;
|
|
338
|
+
}
|
|
339
|
+
throw new ValidationError(expression.unsupportedNodeKind === undefined
|
|
340
|
+
? "daml lf expression is not supported yet"
|
|
341
|
+
: `daml lf expression '${expression.unsupportedNodeKind}' is not supported yet`);
|
|
342
|
+
}
|
|
343
|
+
evaluateReplayExpressionOrThrow(expression, frame, environment, traceSink) {
|
|
344
|
+
return this.evaluateReplayLambdaOrExpressionOrThrow(expression, frame, this.resolveEntrypointBindingValues(environment), traceSink, environment.entrypointBindingMode ?? "standard");
|
|
345
|
+
}
|
|
346
|
+
evaluateUpdateExpressionOrThrow(expression, frame, traceSink) {
|
|
347
|
+
const updateExpression = expression.updateExpression;
|
|
348
|
+
if (updateExpression === undefined) {
|
|
349
|
+
throw new ValidationError("daml lf update expression is missing");
|
|
350
|
+
}
|
|
351
|
+
switch (updateExpression.kind) {
|
|
352
|
+
case "pure":
|
|
353
|
+
case "embedExpr":
|
|
354
|
+
return this.evaluateExpressionOrThrow(updateExpression.expression ?? new DamlLfExpression({}), frame, traceSink);
|
|
355
|
+
case "block": {
|
|
356
|
+
const scopedFrame = this.deriveFrame(frame, frame.scope.createChild());
|
|
357
|
+
for (const binding of updateExpression.bindings ?? []) {
|
|
358
|
+
const boundValue = this.evaluateExpressionOrThrow(binding.value, scopedFrame, traceSink);
|
|
359
|
+
scopedFrame.scope.setBinding(binding.name, boundValue);
|
|
360
|
+
}
|
|
361
|
+
return this.evaluateExpressionOrThrow(updateExpression.body ?? new DamlLfExpression({}), scopedFrame, traceSink);
|
|
362
|
+
}
|
|
363
|
+
case "tryCatch": {
|
|
364
|
+
try {
|
|
365
|
+
return this.evaluateExpressionOrThrow(updateExpression.expression ?? new DamlLfExpression({}), frame, traceSink);
|
|
366
|
+
}
|
|
367
|
+
catch (error) {
|
|
368
|
+
if (!(error instanceof DamlLfThrownException)) {
|
|
369
|
+
throw error;
|
|
370
|
+
}
|
|
371
|
+
const scopedFrame = this.deriveFrame(frame, frame.scope.createChild());
|
|
372
|
+
if (updateExpression.catchVariableName !== undefined) {
|
|
373
|
+
scopedFrame.scope.setBinding(updateExpression.catchVariableName, error.value);
|
|
374
|
+
}
|
|
375
|
+
return this.evaluateExpressionOrThrow(updateExpression.catchExpression ?? new DamlLfExpression({}), scopedFrame, traceSink);
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
case "create": {
|
|
379
|
+
const payload = this.normalizeSemanticRecordValue(this.unwrapRuntimeValue(this.evaluateExpressionOrThrow(updateExpression.argument ?? new DamlLfExpression({}), frame, traceSink)), updateExpression.templateId === undefined
|
|
380
|
+
? undefined
|
|
381
|
+
: new TypeConReference({
|
|
382
|
+
packageId: updateExpression.templateId.packageId,
|
|
383
|
+
moduleName: updateExpression.templateId.moduleName,
|
|
384
|
+
name: updateExpression.templateId.templateName,
|
|
385
|
+
}));
|
|
386
|
+
const nextSyntheticContractIdNumber = this.activeReplayContext?.nextSyntheticContractIdNumber ?? 1;
|
|
387
|
+
const observedContractId = this.activeReplayContext?.observedCreateContractIds[this.activeReplayContext.nextObservedCreateIndex];
|
|
388
|
+
const contractId = observedContractId
|
|
389
|
+
?? `created-${nextSyntheticContractIdNumber}`;
|
|
390
|
+
if (this.activeReplayContext !== undefined) {
|
|
391
|
+
this.activeReplayContext.nextSyntheticContractIdNumber =
|
|
392
|
+
nextSyntheticContractIdNumber + 1;
|
|
393
|
+
this.activeReplayContext.nextObservedCreateIndex += 1;
|
|
394
|
+
}
|
|
395
|
+
this.activeReplayContext?.createdContracts.set(contractId, {
|
|
396
|
+
payload,
|
|
397
|
+
templateId: updateExpression.templateId === undefined
|
|
398
|
+
? undefined
|
|
399
|
+
: {
|
|
400
|
+
packageId: updateExpression.templateId.packageId,
|
|
401
|
+
moduleName: updateExpression.templateId.moduleName,
|
|
402
|
+
entityName: updateExpression.templateId.templateName,
|
|
403
|
+
},
|
|
404
|
+
});
|
|
405
|
+
this.emitReplayEffect({
|
|
406
|
+
kind: "create",
|
|
407
|
+
contractId,
|
|
408
|
+
templateId: updateExpression.templateId === undefined
|
|
409
|
+
? undefined
|
|
410
|
+
: {
|
|
411
|
+
packageId: updateExpression.templateId.packageId,
|
|
412
|
+
moduleName: updateExpression.templateId.moduleName,
|
|
413
|
+
entityName: updateExpression.templateId.templateName,
|
|
414
|
+
},
|
|
415
|
+
payload,
|
|
416
|
+
}, expression, frame, traceSink);
|
|
417
|
+
return {
|
|
418
|
+
kind: "contractId",
|
|
419
|
+
value: contractId,
|
|
420
|
+
};
|
|
421
|
+
}
|
|
422
|
+
case "fetch": {
|
|
423
|
+
const contractId = this.readContractId(this.evaluateExpressionOrThrow(updateExpression.contractId ?? new DamlLfExpression({}), frame, traceSink));
|
|
424
|
+
const payload = this.activeReplayContext?.createdContracts.get(contractId)?.payload
|
|
425
|
+
?? this.activeReplayContext?.environment.contracts?.get(contractId)
|
|
426
|
+
?.payload;
|
|
427
|
+
this.emitReplayEffect({
|
|
428
|
+
kind: "fetch",
|
|
429
|
+
contractId,
|
|
430
|
+
templateId: updateExpression.templateId === undefined
|
|
431
|
+
? undefined
|
|
432
|
+
: {
|
|
433
|
+
packageId: updateExpression.templateId.packageId,
|
|
434
|
+
moduleName: updateExpression.templateId.moduleName,
|
|
435
|
+
entityName: updateExpression.templateId.templateName,
|
|
436
|
+
},
|
|
437
|
+
}, expression, frame, traceSink);
|
|
438
|
+
return this.hydrateRuntimeValue(payload);
|
|
439
|
+
}
|
|
440
|
+
case "fetchInterface": {
|
|
441
|
+
const contractId = this.readContractId(this.evaluateExpressionOrThrow(updateExpression.contractId ?? new DamlLfExpression({}), frame, traceSink));
|
|
442
|
+
const createdContract = this.activeReplayContext?.createdContracts.get(contractId);
|
|
443
|
+
const hydratedContract = this.activeReplayContext?.environment.contracts?.get(contractId);
|
|
444
|
+
const payload = createdContract?.payload
|
|
445
|
+
?? hydratedContract?.payload;
|
|
446
|
+
const resolvedTemplateId = createdContract?.templateId
|
|
447
|
+
?? hydratedContract?.templateId;
|
|
448
|
+
if (payload === undefined) {
|
|
449
|
+
throw new ValidationError(`daml lf fetch-interface update could not hydrate contract '${contractId}'`);
|
|
450
|
+
}
|
|
451
|
+
this.emitReplayEffect({
|
|
452
|
+
kind: "fetch",
|
|
453
|
+
contractId,
|
|
454
|
+
templateId: resolvedTemplateId,
|
|
455
|
+
}, expression, frame, traceSink);
|
|
456
|
+
return this.hydrateRuntimeValue(payload);
|
|
457
|
+
}
|
|
458
|
+
case "exercise": {
|
|
459
|
+
if (updateExpression.templateId === undefined
|
|
460
|
+
|| updateExpression.choiceName === undefined) {
|
|
461
|
+
throw new ValidationError("daml lf exercise update is missing its template or choice");
|
|
462
|
+
}
|
|
463
|
+
const contractId = this.readContractId(this.evaluateExpressionOrThrow(updateExpression.contractId ?? new DamlLfExpression({}), frame, traceSink));
|
|
464
|
+
const argument = this.unwrapRuntimeValue(this.evaluateExpressionOrThrow(updateExpression.argument ?? new DamlLfExpression({}), frame, traceSink));
|
|
465
|
+
const payload = this.activeReplayContext?.createdContracts.get(contractId)?.payload
|
|
466
|
+
?? this.activeReplayContext?.environment.contracts?.get(contractId)
|
|
467
|
+
?.payload;
|
|
468
|
+
if (payload === undefined) {
|
|
469
|
+
throw new ValidationError(`daml lf exercise update could not hydrate contract '${contractId}'`);
|
|
470
|
+
}
|
|
471
|
+
this.emitReplayEffect({
|
|
472
|
+
kind: "exercise",
|
|
473
|
+
contractId,
|
|
474
|
+
templateId: this.toReplayTemplateId(updateExpression.templateId),
|
|
475
|
+
choice: updateExpression.choiceName,
|
|
476
|
+
argument,
|
|
477
|
+
}, expression, frame, traceSink);
|
|
478
|
+
const resolvedDefinition = this.activeReplayContext
|
|
479
|
+
?.environment.definitionResolver
|
|
480
|
+
?.resolveChoiceDefinitionOrThrow?.(new DamlLfTemplateId(updateExpression.templateId), updateExpression.choiceName);
|
|
481
|
+
if (resolvedDefinition === undefined) {
|
|
482
|
+
throw new ValidationError("daml lf exercise update requires a replay definition resolver");
|
|
483
|
+
}
|
|
484
|
+
return this.evaluateReplayLambdaOrExpressionOrThrow(resolvedDefinition.replayExpression, this.createFrame(resolvedDefinition.definition, resolvedDefinition.frameIdentity), [
|
|
485
|
+
{
|
|
486
|
+
value: payload,
|
|
487
|
+
contractId,
|
|
488
|
+
},
|
|
489
|
+
{
|
|
490
|
+
value: argument,
|
|
491
|
+
},
|
|
492
|
+
], traceSink, resolvedDefinition.replayBindingMode);
|
|
493
|
+
}
|
|
494
|
+
case "exerciseInterface": {
|
|
495
|
+
if (updateExpression.choiceName === undefined) {
|
|
496
|
+
throw new ValidationError("daml lf exercise-interface update is missing its choice");
|
|
497
|
+
}
|
|
498
|
+
const contractId = this.readContractId(this.evaluateExpressionOrThrow(updateExpression.contractId ?? new DamlLfExpression({}), frame, traceSink));
|
|
499
|
+
const argument = this.unwrapRuntimeValue(this.evaluateExpressionOrThrow(updateExpression.argument ?? new DamlLfExpression({}), frame, traceSink));
|
|
500
|
+
const createdContract = this.activeReplayContext?.createdContracts.get(contractId);
|
|
501
|
+
const hydratedContract = this.activeReplayContext?.environment.contracts?.get(contractId);
|
|
502
|
+
const payload = createdContract?.payload
|
|
503
|
+
?? hydratedContract?.payload;
|
|
504
|
+
const resolvedTemplateId = createdContract?.templateId
|
|
505
|
+
?? hydratedContract?.templateId;
|
|
506
|
+
if (payload === undefined || resolvedTemplateId === undefined) {
|
|
507
|
+
throw new ValidationError(`daml lf exercise-interface update could not hydrate contract '${contractId}'`);
|
|
508
|
+
}
|
|
509
|
+
this.emitReplayEffect({
|
|
510
|
+
kind: "exercise",
|
|
511
|
+
contractId,
|
|
512
|
+
templateId: resolvedTemplateId,
|
|
513
|
+
choice: updateExpression.choiceName,
|
|
514
|
+
argument,
|
|
515
|
+
}, expression, frame, traceSink);
|
|
516
|
+
let resolvedDefinition;
|
|
517
|
+
try {
|
|
518
|
+
resolvedDefinition = this.activeReplayContext
|
|
519
|
+
?.environment.definitionResolver
|
|
520
|
+
?.resolveChoiceDefinitionOrThrow?.(new DamlLfTemplateId({
|
|
521
|
+
packageId: resolvedTemplateId.packageId ?? "",
|
|
522
|
+
moduleName: resolvedTemplateId.moduleName ?? "",
|
|
523
|
+
templateName: resolvedTemplateId.entityName ?? "",
|
|
524
|
+
}), updateExpression.choiceName);
|
|
525
|
+
}
|
|
526
|
+
catch (error) {
|
|
527
|
+
if (error instanceof ReplaySourceMapException
|
|
528
|
+
&& error.message.includes("missing executable metadata for choice")) {
|
|
529
|
+
return this.hydrateRuntimeValue({});
|
|
530
|
+
}
|
|
531
|
+
throw error;
|
|
532
|
+
}
|
|
533
|
+
if (resolvedDefinition === undefined) {
|
|
534
|
+
return this.hydrateRuntimeValue({});
|
|
535
|
+
}
|
|
536
|
+
return this.evaluateReplayLambdaOrExpressionOrThrow(resolvedDefinition.replayExpression, this.createFrame(resolvedDefinition.definition, resolvedDefinition.frameIdentity), [
|
|
537
|
+
{
|
|
538
|
+
value: payload,
|
|
539
|
+
contractId,
|
|
540
|
+
},
|
|
541
|
+
{
|
|
542
|
+
value: argument,
|
|
543
|
+
},
|
|
544
|
+
], traceSink, resolvedDefinition.replayBindingMode);
|
|
545
|
+
}
|
|
546
|
+
case "getTime":
|
|
547
|
+
return {
|
|
548
|
+
kind: "text",
|
|
549
|
+
value: this.activeReplayContext?.environment.offset ?? "",
|
|
550
|
+
};
|
|
551
|
+
case "ledgerTimeLt":
|
|
552
|
+
if (updateExpression.expression !== undefined) {
|
|
553
|
+
void this.evaluateExpressionOrThrow(updateExpression.expression, frame, traceSink);
|
|
554
|
+
}
|
|
555
|
+
return {
|
|
556
|
+
kind: "unit",
|
|
557
|
+
};
|
|
558
|
+
default:
|
|
559
|
+
throw new ValidationError(`daml lf update expression '${updateExpression.kind}' is not supported yet`);
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
resolveEntrypointBindingValues(environment) {
|
|
563
|
+
if (environment.entrypoint.kind === "create") {
|
|
564
|
+
return environment.entrypoint.argument === undefined
|
|
565
|
+
? []
|
|
566
|
+
: [{ value: environment.entrypoint.argument }];
|
|
567
|
+
}
|
|
568
|
+
const contractPayload = environment.entrypoint.contractId === undefined
|
|
569
|
+
? undefined
|
|
570
|
+
: environment.contracts?.get(environment.entrypoint.contractId)?.payload;
|
|
571
|
+
const bindingValues = [];
|
|
572
|
+
if (contractPayload !== undefined) {
|
|
573
|
+
bindingValues.push({
|
|
574
|
+
value: contractPayload,
|
|
575
|
+
contractId: environment.entrypoint.contractId,
|
|
576
|
+
});
|
|
577
|
+
}
|
|
578
|
+
if (environment.entrypoint.argument !== undefined) {
|
|
579
|
+
bindingValues.push({
|
|
580
|
+
value: environment.entrypoint.argument,
|
|
581
|
+
});
|
|
582
|
+
}
|
|
583
|
+
return bindingValues;
|
|
584
|
+
}
|
|
585
|
+
evaluateReplayLambdaOrExpressionOrThrow(expression, frame, bindingValues, traceSink, bindingMode = "standard") {
|
|
586
|
+
if (expression.lambda === undefined) {
|
|
587
|
+
return this.evaluateExpressionOrThrow(expression, frame, traceSink);
|
|
588
|
+
}
|
|
589
|
+
const scopedFrame = this.deriveFrame(frame, frame.scope.createChild());
|
|
590
|
+
if (bindingMode === "templateChoice") {
|
|
591
|
+
const selfParameterName = expression.lambda.parameters[0];
|
|
592
|
+
const thisParameterName = expression.lambda.parameters[1];
|
|
593
|
+
const argumentParameterName = expression.lambda.parameters[2];
|
|
594
|
+
const contractId = bindingValues[0]?.contractId;
|
|
595
|
+
const payload = bindingValues[0];
|
|
596
|
+
const argument = bindingValues[1];
|
|
597
|
+
if (selfParameterName !== undefined && contractId !== undefined) {
|
|
598
|
+
scopedFrame.scope.setBinding(selfParameterName, {
|
|
599
|
+
kind: "contractId",
|
|
600
|
+
value: contractId,
|
|
601
|
+
});
|
|
602
|
+
}
|
|
603
|
+
if (thisParameterName !== undefined && payload !== undefined) {
|
|
604
|
+
scopedFrame.scope.setBinding(thisParameterName, this.hydrateRuntimeValue(payload.value, payload.contractId));
|
|
605
|
+
}
|
|
606
|
+
if (argumentParameterName !== undefined && argument !== undefined) {
|
|
607
|
+
scopedFrame.scope.setBinding(argumentParameterName, this.hydrateRuntimeValue(argument.value, argument.contractId));
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
else if (bindingMode === "exerciseWrapper") {
|
|
611
|
+
const thisParameterName = expression.lambda.parameters.at(-2);
|
|
612
|
+
const argumentParameterName = expression.lambda.parameters.at(-1);
|
|
613
|
+
const contractId = bindingValues[0]?.contractId;
|
|
614
|
+
if (thisParameterName !== undefined && contractId !== undefined) {
|
|
615
|
+
scopedFrame.scope.setBinding(thisParameterName, {
|
|
616
|
+
kind: "contractId",
|
|
617
|
+
value: contractId,
|
|
618
|
+
});
|
|
619
|
+
}
|
|
620
|
+
if (argumentParameterName !== undefined && bindingValues[1] !== undefined) {
|
|
621
|
+
scopedFrame.scope.setBinding(argumentParameterName, this.hydrateRuntimeValue(bindingValues[1].value, bindingValues[1].contractId));
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
else if (bindingMode === "createWrapper") {
|
|
625
|
+
const argumentParameterName = expression.lambda.parameters.at(-1);
|
|
626
|
+
const bindingValue = bindingValues[0];
|
|
627
|
+
if (argumentParameterName !== undefined && bindingValue !== undefined) {
|
|
628
|
+
scopedFrame.scope.setBinding(argumentParameterName, this.hydrateRuntimeValue(bindingValue.value, bindingValue.contractId));
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
else {
|
|
632
|
+
for (let index = 0; index < expression.lambda.parameters.length; index += 1) {
|
|
633
|
+
const bindingValue = bindingValues[index];
|
|
634
|
+
if (bindingValue === undefined) {
|
|
635
|
+
break;
|
|
636
|
+
}
|
|
637
|
+
scopedFrame.scope.setBinding(expression.lambda.parameters[index], this.hydrateRuntimeValue(bindingValue.value, bindingValue.contractId));
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
return this.evaluateExpressionOrThrow(expression.lambda.body, scopedFrame, traceSink);
|
|
641
|
+
}
|
|
642
|
+
hydrateRuntimeValue(value, contractId) {
|
|
643
|
+
if (value === undefined || value === null) {
|
|
644
|
+
return {
|
|
645
|
+
kind: "unit",
|
|
646
|
+
};
|
|
647
|
+
}
|
|
648
|
+
const embeddedContractId = this.readEmbeddedContractId(value);
|
|
649
|
+
if (embeddedContractId !== undefined) {
|
|
650
|
+
return {
|
|
651
|
+
kind: "contractId",
|
|
652
|
+
value: embeddedContractId,
|
|
653
|
+
};
|
|
654
|
+
}
|
|
655
|
+
const embeddedContractIdArray = this.readEmbeddedContractIdArray(value);
|
|
656
|
+
if (embeddedContractIdArray !== undefined) {
|
|
657
|
+
return {
|
|
658
|
+
kind: "contractId[]",
|
|
659
|
+
value: embeddedContractIdArray,
|
|
660
|
+
};
|
|
661
|
+
}
|
|
662
|
+
const embeddedParty = this.readEmbeddedParty(value);
|
|
663
|
+
if (embeddedParty !== undefined) {
|
|
664
|
+
return {
|
|
665
|
+
kind: "party",
|
|
666
|
+
value: embeddedParty,
|
|
667
|
+
};
|
|
668
|
+
}
|
|
669
|
+
if (value !== null
|
|
670
|
+
&& typeof value === "object"
|
|
671
|
+
&& "__damlLfInt64" in value
|
|
672
|
+
&& typeof value.__damlLfInt64 === "string") {
|
|
673
|
+
return {
|
|
674
|
+
kind: "int64",
|
|
675
|
+
value: value.__damlLfInt64,
|
|
676
|
+
};
|
|
677
|
+
}
|
|
678
|
+
if (value !== null
|
|
679
|
+
&& typeof value === "object"
|
|
680
|
+
&& "__damlLfNumeric" in value
|
|
681
|
+
&& typeof value.__damlLfNumeric === "string") {
|
|
682
|
+
return {
|
|
683
|
+
kind: "numeric",
|
|
684
|
+
value: value.__damlLfNumeric,
|
|
685
|
+
};
|
|
686
|
+
}
|
|
687
|
+
if (typeof value === "string") {
|
|
688
|
+
return {
|
|
689
|
+
kind: "text",
|
|
690
|
+
value,
|
|
691
|
+
};
|
|
692
|
+
}
|
|
693
|
+
if (typeof value === "boolean") {
|
|
694
|
+
return {
|
|
695
|
+
kind: "boolean",
|
|
696
|
+
value,
|
|
697
|
+
};
|
|
698
|
+
}
|
|
699
|
+
return {
|
|
700
|
+
kind: "ledgerValue",
|
|
701
|
+
value,
|
|
702
|
+
contractId,
|
|
703
|
+
};
|
|
704
|
+
}
|
|
705
|
+
createRecordRuntimeValue(fields) {
|
|
706
|
+
return this.canProjectRecordAsLedgerValue(fields)
|
|
707
|
+
? this.hydrateRuntimeValue(Object.fromEntries(Object.entries(fields).map(([name, value]) => [
|
|
708
|
+
name,
|
|
709
|
+
this.unwrapRuntimeValue(value),
|
|
710
|
+
])))
|
|
711
|
+
: {
|
|
712
|
+
kind: "record",
|
|
713
|
+
fields,
|
|
714
|
+
};
|
|
715
|
+
}
|
|
716
|
+
canProjectRecordAsLedgerValue(fields) {
|
|
717
|
+
return Object.values(fields).every((value) => {
|
|
718
|
+
if (value.kind === "record") {
|
|
719
|
+
return this.canProjectRecordAsLedgerValue(value.fields);
|
|
720
|
+
}
|
|
721
|
+
return value.kind !== "closure" && value.kind !== "builtin";
|
|
722
|
+
});
|
|
723
|
+
}
|
|
724
|
+
readEmbeddedContractId(value) {
|
|
725
|
+
if (value !== null
|
|
726
|
+
&& typeof value === "object"
|
|
727
|
+
&& DAML_LF_CONTRACT_ID_MARKER_KEY in value
|
|
728
|
+
&& typeof value[DAML_LF_CONTRACT_ID_MARKER_KEY] === "string") {
|
|
729
|
+
return value[DAML_LF_CONTRACT_ID_MARKER_KEY];
|
|
730
|
+
}
|
|
731
|
+
if (value !== null
|
|
732
|
+
&& typeof value === "object"
|
|
733
|
+
&& "sum" in value
|
|
734
|
+
&& value.sum !== null
|
|
735
|
+
&& typeof value.sum === "object"
|
|
736
|
+
&& "oneofKind" in value.sum
|
|
737
|
+
&& value.sum.oneofKind === "contractId"
|
|
738
|
+
&& "contractId" in value.sum
|
|
739
|
+
&& typeof value.sum.contractId === "string") {
|
|
740
|
+
return value.sum.contractId;
|
|
741
|
+
}
|
|
742
|
+
return undefined;
|
|
743
|
+
}
|
|
744
|
+
readEmbeddedContractIdArray(value) {
|
|
745
|
+
if (!Array.isArray(value) || value.length === 0) {
|
|
746
|
+
return undefined;
|
|
747
|
+
}
|
|
748
|
+
const contractIds = value.map((item) => this.readEmbeddedContractId(item));
|
|
749
|
+
if (contractIds.some((contractId) => contractId === undefined)) {
|
|
750
|
+
return undefined;
|
|
751
|
+
}
|
|
752
|
+
return contractIds;
|
|
753
|
+
}
|
|
754
|
+
readEmbeddedParty(value) {
|
|
755
|
+
if (value !== null
|
|
756
|
+
&& typeof value === "object"
|
|
757
|
+
&& DAML_LF_PARTY_MARKER_KEY in value
|
|
758
|
+
&& typeof value[DAML_LF_PARTY_MARKER_KEY] === "string") {
|
|
759
|
+
return value[DAML_LF_PARTY_MARKER_KEY];
|
|
760
|
+
}
|
|
761
|
+
if (value !== null
|
|
762
|
+
&& typeof value === "object"
|
|
763
|
+
&& "sum" in value
|
|
764
|
+
&& value.sum !== null
|
|
765
|
+
&& typeof value.sum === "object"
|
|
766
|
+
&& "oneofKind" in value.sum
|
|
767
|
+
&& value.sum.oneofKind === "party"
|
|
768
|
+
&& "party" in value.sum
|
|
769
|
+
&& typeof value.sum.party === "string") {
|
|
770
|
+
return value.sum.party;
|
|
771
|
+
}
|
|
772
|
+
return undefined;
|
|
773
|
+
}
|
|
774
|
+
readLedgerRecordField(rawValue, fieldName) {
|
|
775
|
+
const semanticField = this.resolveSemanticRecordField(rawValue, fieldName);
|
|
776
|
+
if (fieldName in rawValue) {
|
|
777
|
+
return this.coerceSemanticFieldValue(this.attachSemanticRecordId(rawValue[fieldName], semanticField?.type.typeConReference), semanticField?.type);
|
|
778
|
+
}
|
|
779
|
+
if (semanticField === undefined) {
|
|
780
|
+
return undefined;
|
|
781
|
+
}
|
|
782
|
+
return this.coerceSemanticFieldValue(this.attachSemanticRecordId(rawValue[String(semanticField.index)], semanticField.type.typeConReference), semanticField.type);
|
|
783
|
+
}
|
|
784
|
+
createLedgerRecordFieldUpdate(rawValue, fieldName, nextValue) {
|
|
785
|
+
if (fieldName in rawValue) {
|
|
786
|
+
return {
|
|
787
|
+
[fieldName]: nextValue,
|
|
788
|
+
};
|
|
789
|
+
}
|
|
790
|
+
const semanticField = this.resolveSemanticRecordField(rawValue, fieldName);
|
|
791
|
+
return semanticField === undefined
|
|
792
|
+
? {
|
|
793
|
+
[fieldName]: nextValue,
|
|
794
|
+
}
|
|
795
|
+
: {
|
|
796
|
+
[String(semanticField.index)]: nextValue,
|
|
797
|
+
};
|
|
798
|
+
}
|
|
799
|
+
resolveSemanticRecordField(rawValue, fieldName) {
|
|
800
|
+
const recordId = rawValue[DAML_LF_RECORD_ID_MARKER_KEY];
|
|
801
|
+
if (recordId === undefined
|
|
802
|
+
|| recordId === null
|
|
803
|
+
|| typeof recordId !== "object") {
|
|
804
|
+
return undefined;
|
|
805
|
+
}
|
|
806
|
+
const typedRecordId = recordId;
|
|
807
|
+
const reference = new TypeConReference({
|
|
808
|
+
packageId: typeof typedRecordId.packageId === "string"
|
|
809
|
+
? typedRecordId.packageId
|
|
810
|
+
: "",
|
|
811
|
+
moduleName: typeof typedRecordId.moduleName === "string"
|
|
812
|
+
? typedRecordId.moduleName
|
|
813
|
+
: "",
|
|
814
|
+
name: typeof typedRecordId.entityName === "string"
|
|
815
|
+
? typedRecordId.entityName
|
|
816
|
+
: "",
|
|
817
|
+
});
|
|
818
|
+
try {
|
|
819
|
+
const fields = this.semanticModel.getRecordFieldsOrThrow(reference);
|
|
820
|
+
const semanticIndex = fields.findIndex((field) => field.name === fieldName);
|
|
821
|
+
if (semanticIndex < 0) {
|
|
822
|
+
return undefined;
|
|
823
|
+
}
|
|
824
|
+
return {
|
|
825
|
+
index: semanticIndex,
|
|
826
|
+
type: fields[semanticIndex]?.type ?? new DamlLfType({}),
|
|
827
|
+
};
|
|
828
|
+
}
|
|
829
|
+
catch {
|
|
830
|
+
return undefined;
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
coerceSemanticFieldValue(value, type) {
|
|
834
|
+
if (type?.builtinType === DamlLfBuiltinType.int64) {
|
|
835
|
+
return typeof value === "string" ? { __damlLfInt64: value } : value;
|
|
836
|
+
}
|
|
837
|
+
if (type?.builtinType === DamlLfBuiltinType.party) {
|
|
838
|
+
return typeof value === "string"
|
|
839
|
+
? { [DAML_LF_PARTY_MARKER_KEY]: value }
|
|
840
|
+
: value;
|
|
841
|
+
}
|
|
842
|
+
return value;
|
|
843
|
+
}
|
|
844
|
+
attachSemanticRecordId(value, typeConReference) {
|
|
845
|
+
if (typeConReference === undefined
|
|
846
|
+
|| value === null
|
|
847
|
+
|| value === undefined
|
|
848
|
+
|| typeof value !== "object"
|
|
849
|
+
|| Array.isArray(value)
|
|
850
|
+
|| DAML_LF_RECORD_ID_MARKER_KEY in value) {
|
|
851
|
+
return value;
|
|
852
|
+
}
|
|
853
|
+
return {
|
|
854
|
+
...value,
|
|
855
|
+
[DAML_LF_RECORD_ID_MARKER_KEY]: {
|
|
856
|
+
packageId: typeConReference.packageId,
|
|
857
|
+
moduleName: typeConReference.moduleName,
|
|
858
|
+
entityName: typeConReference.name,
|
|
859
|
+
},
|
|
860
|
+
};
|
|
861
|
+
}
|
|
862
|
+
normalizeSemanticRecordValue(value, typeConReference) {
|
|
863
|
+
if (typeConReference === undefined
|
|
864
|
+
|| value === null
|
|
865
|
+
|| value === undefined
|
|
866
|
+
|| typeof value !== "object"
|
|
867
|
+
|| Array.isArray(value)) {
|
|
868
|
+
return value;
|
|
869
|
+
}
|
|
870
|
+
try {
|
|
871
|
+
const fields = this.semanticModel.getRecordFieldsOrThrow(typeConReference);
|
|
872
|
+
const rawValue = value;
|
|
873
|
+
const normalizedValue = {};
|
|
874
|
+
const consumedKeys = new Set();
|
|
875
|
+
for (const [index, field] of fields.entries()) {
|
|
876
|
+
const directValue = rawValue[field.name];
|
|
877
|
+
const positionalKey = String(index);
|
|
878
|
+
const positionalValue = rawValue[positionalKey];
|
|
879
|
+
const nextValue = directValue !== undefined ? directValue : positionalValue;
|
|
880
|
+
if (nextValue === undefined) {
|
|
881
|
+
continue;
|
|
882
|
+
}
|
|
883
|
+
normalizedValue[field.name] = this.normalizeSemanticRecordValue(nextValue, field.type.typeConReference);
|
|
884
|
+
consumedKeys.add(field.name);
|
|
885
|
+
consumedKeys.add(positionalKey);
|
|
886
|
+
}
|
|
887
|
+
for (const [key, item] of Object.entries(rawValue)) {
|
|
888
|
+
if (!consumedKeys.has(key)) {
|
|
889
|
+
normalizedValue[key] = item;
|
|
890
|
+
}
|
|
891
|
+
}
|
|
892
|
+
return normalizedValue;
|
|
893
|
+
}
|
|
894
|
+
catch {
|
|
895
|
+
return value;
|
|
896
|
+
}
|
|
897
|
+
}
|
|
898
|
+
toReplayTemplateId(templateId) {
|
|
899
|
+
return templateId === undefined
|
|
900
|
+
? undefined
|
|
901
|
+
: {
|
|
902
|
+
packageId: templateId.packageId,
|
|
903
|
+
moduleName: templateId.moduleName,
|
|
904
|
+
entityName: templateId.templateName,
|
|
905
|
+
};
|
|
906
|
+
}
|
|
907
|
+
readContractId(value) {
|
|
908
|
+
if ((value.kind === "contractId" || value.kind === "text")
|
|
909
|
+
&& "value" in value
|
|
910
|
+
&& typeof value.value === "string") {
|
|
911
|
+
return value.value;
|
|
912
|
+
}
|
|
913
|
+
if (value.kind === "ledgerValue"
|
|
914
|
+
&& "contractId" in value
|
|
915
|
+
&& typeof value.contractId === "string") {
|
|
916
|
+
return value.contractId;
|
|
917
|
+
}
|
|
918
|
+
throw new ValidationError(`daml lf expected a contract id-compatible value, got '${value.kind}'`);
|
|
919
|
+
}
|
|
920
|
+
unwrapRuntimeValue(value) {
|
|
921
|
+
if (value.kind === "record") {
|
|
922
|
+
const recordFields = value.fields;
|
|
923
|
+
return Object.fromEntries(Object.entries(recordFields).map(([name, fieldValue]) => [
|
|
924
|
+
name,
|
|
925
|
+
this.unwrapRuntimeValue(fieldValue),
|
|
926
|
+
]));
|
|
927
|
+
}
|
|
928
|
+
if (value.kind === "contractId[]") {
|
|
929
|
+
return value.value.map((contractId) => ({
|
|
930
|
+
[DAML_LF_CONTRACT_ID_MARKER_KEY]: contractId,
|
|
931
|
+
}));
|
|
932
|
+
}
|
|
933
|
+
if (value.kind === "contractId") {
|
|
934
|
+
return {
|
|
935
|
+
[DAML_LF_CONTRACT_ID_MARKER_KEY]: value.value,
|
|
936
|
+
};
|
|
937
|
+
}
|
|
938
|
+
if (value.kind === "party") {
|
|
939
|
+
return {
|
|
940
|
+
[DAML_LF_PARTY_MARKER_KEY]: value.value,
|
|
941
|
+
};
|
|
942
|
+
}
|
|
943
|
+
if (value.kind === "builtin"
|
|
944
|
+
&& "builtinFunction" in value
|
|
945
|
+
&& value.builtinFunction === "TEXTMAP_EMPTY") {
|
|
946
|
+
return {};
|
|
947
|
+
}
|
|
948
|
+
if (value.kind === "builtin"
|
|
949
|
+
&& "builtinFunction" in value
|
|
950
|
+
&& value.builtinFunction === "GENMAP_EMPTY") {
|
|
951
|
+
return [];
|
|
952
|
+
}
|
|
953
|
+
if ("value" in value) {
|
|
954
|
+
return value.value;
|
|
955
|
+
}
|
|
956
|
+
if (value.kind === "unit") {
|
|
957
|
+
return null;
|
|
958
|
+
}
|
|
959
|
+
return value.kind;
|
|
960
|
+
}
|
|
961
|
+
readRuntimeListOrThrow(value) {
|
|
962
|
+
if (value.kind === "contractId[]") {
|
|
963
|
+
return value.value.map((contractId) => ({
|
|
964
|
+
kind: "contractId",
|
|
965
|
+
value: contractId,
|
|
966
|
+
}));
|
|
967
|
+
}
|
|
968
|
+
if (value.kind === "ledgerValue"
|
|
969
|
+
&& "value" in value
|
|
970
|
+
&& Array.isArray(value.value)) {
|
|
971
|
+
return value.value.map((item) => this.hydrateRuntimeValue(item));
|
|
972
|
+
}
|
|
973
|
+
throw new ValidationError(`daml lf expected a list-compatible value, got '${value.kind}'`);
|
|
974
|
+
}
|
|
975
|
+
matchesBuiltinConstructor(builtinConstructor, runtimeValue) {
|
|
976
|
+
switch (builtinConstructor) {
|
|
977
|
+
case "true":
|
|
978
|
+
return runtimeValue.kind === "boolean" && runtimeValue.value === true;
|
|
979
|
+
case "false":
|
|
980
|
+
return runtimeValue.kind === "boolean" && runtimeValue.value === false;
|
|
981
|
+
case "unit":
|
|
982
|
+
return runtimeValue.kind === "unit";
|
|
983
|
+
default:
|
|
984
|
+
return false;
|
|
985
|
+
}
|
|
986
|
+
}
|
|
987
|
+
matchesCaseAlternative(alternative, runtimeValue) {
|
|
988
|
+
if (alternative.patternKind === "default") {
|
|
989
|
+
return true;
|
|
990
|
+
}
|
|
991
|
+
if (alternative.patternKind === "builtinCon") {
|
|
992
|
+
return this.matchesBuiltinConstructor(alternative.builtinConstructor, runtimeValue);
|
|
993
|
+
}
|
|
994
|
+
if (alternative.patternKind === "optionalNone") {
|
|
995
|
+
return runtimeValue.kind === "unit";
|
|
996
|
+
}
|
|
997
|
+
if (alternative.patternKind === "optionalSome") {
|
|
998
|
+
return runtimeValue.kind !== "unit";
|
|
999
|
+
}
|
|
1000
|
+
if (alternative.patternKind === "enum") {
|
|
1001
|
+
return (runtimeValue.kind === "text"
|
|
1002
|
+
&& runtimeValue.value === alternative.constructorName);
|
|
1003
|
+
}
|
|
1004
|
+
if (alternative.patternKind === "nil") {
|
|
1005
|
+
const unwrapped = this.unwrapRuntimeValue(runtimeValue);
|
|
1006
|
+
return Array.isArray(unwrapped) && unwrapped.length === 0;
|
|
1007
|
+
}
|
|
1008
|
+
if (alternative.patternKind === "cons") {
|
|
1009
|
+
const unwrapped = this.unwrapRuntimeValue(runtimeValue);
|
|
1010
|
+
return Array.isArray(unwrapped) && unwrapped.length > 0;
|
|
1011
|
+
}
|
|
1012
|
+
const rawValue = this.unwrapRuntimeValue(runtimeValue);
|
|
1013
|
+
return (rawValue !== null
|
|
1014
|
+
&& typeof rawValue === "object"
|
|
1015
|
+
&& "constructor" in rawValue
|
|
1016
|
+
&& rawValue.constructor
|
|
1017
|
+
=== alternative.constructorName);
|
|
1018
|
+
}
|
|
1019
|
+
emitReplayEffect(effect, expression, frame, traceSink) {
|
|
1020
|
+
this.activeReplayContext?.effects.push(effect);
|
|
1021
|
+
traceSink?.onStep({
|
|
1022
|
+
kind: DamlLfStepKind.stateEffect,
|
|
1023
|
+
expression,
|
|
1024
|
+
frame,
|
|
1025
|
+
locals: frame.scope.snapshotBindings(),
|
|
1026
|
+
stateEffect: effect,
|
|
1027
|
+
});
|
|
1028
|
+
}
|
|
1029
|
+
isUpdateDrivenEntrypointExpression(expression) {
|
|
1030
|
+
if (expression.updateExpression !== undefined) {
|
|
1031
|
+
return true;
|
|
1032
|
+
}
|
|
1033
|
+
if (expression.lambda !== undefined) {
|
|
1034
|
+
return this.isUpdateDrivenEntrypointExpression(expression.lambda.body);
|
|
1035
|
+
}
|
|
1036
|
+
if (expression.letExpression !== undefined) {
|
|
1037
|
+
return this.isUpdateDrivenEntrypointExpression(expression.letExpression.body);
|
|
1038
|
+
}
|
|
1039
|
+
return false;
|
|
1040
|
+
}
|
|
1041
|
+
applyFunctionOrThrow(functionValue, argumentValues, traceSink) {
|
|
1042
|
+
if (functionValue.kind !== "closure") {
|
|
1043
|
+
if (functionValue.kind === "builtin") {
|
|
1044
|
+
const builtinValue = functionValue;
|
|
1045
|
+
if (builtinValue.builtinFunction === "FOLDL") {
|
|
1046
|
+
return this.applyFoldlBuiltinOrThrow(builtinValue, argumentValues, traceSink);
|
|
1047
|
+
}
|
|
1048
|
+
if (builtinValue.builtinFunction === "FOLDR") {
|
|
1049
|
+
return this.applyFoldrBuiltinOrThrow(builtinValue, argumentValues, traceSink);
|
|
1050
|
+
}
|
|
1051
|
+
return this.builtinDispatch.applyOrThrow(builtinValue, argumentValues);
|
|
1052
|
+
}
|
|
1053
|
+
throw new ValidationError(`daml lf expression is not callable (${functionValue.kind})`);
|
|
1054
|
+
}
|
|
1055
|
+
const closure = functionValue;
|
|
1056
|
+
const boundParameterCount = Math.min(closure.parameters.length, argumentValues.length);
|
|
1057
|
+
const remainingParameters = closure.parameters.slice(boundParameterCount);
|
|
1058
|
+
const remainingArguments = argumentValues.slice(boundParameterCount);
|
|
1059
|
+
const scope = closure.frame.scope.createChild();
|
|
1060
|
+
for (let index = 0; index < boundParameterCount; index += 1) {
|
|
1061
|
+
scope.setBinding(closure.parameters[index], argumentValues[index]);
|
|
1062
|
+
}
|
|
1063
|
+
const appliedFrame = this.deriveFrame(closure.frame, scope);
|
|
1064
|
+
const intermediateValue = remainingParameters.length === 0
|
|
1065
|
+
? this.evaluateExpressionOrThrow(closure.body, appliedFrame, traceSink)
|
|
1066
|
+
: {
|
|
1067
|
+
kind: "closure",
|
|
1068
|
+
parameters: remainingParameters,
|
|
1069
|
+
body: closure.body,
|
|
1070
|
+
frame: appliedFrame,
|
|
1071
|
+
};
|
|
1072
|
+
return remainingArguments.length === 0
|
|
1073
|
+
? intermediateValue
|
|
1074
|
+
: this.applyFunctionOrThrow(intermediateValue, remainingArguments, traceSink);
|
|
1075
|
+
}
|
|
1076
|
+
applyFoldlBuiltinOrThrow(builtinValue, argumentValues, traceSink) {
|
|
1077
|
+
const appliedArguments = [
|
|
1078
|
+
...builtinValue.appliedArguments,
|
|
1079
|
+
...argumentValues,
|
|
1080
|
+
];
|
|
1081
|
+
if (appliedArguments.length < 3) {
|
|
1082
|
+
return {
|
|
1083
|
+
kind: "builtin",
|
|
1084
|
+
builtinFunction: builtinValue.builtinFunction,
|
|
1085
|
+
appliedArguments,
|
|
1086
|
+
};
|
|
1087
|
+
}
|
|
1088
|
+
const foldFunction = appliedArguments[0];
|
|
1089
|
+
let accumulator = appliedArguments[1];
|
|
1090
|
+
const listItems = this.readRuntimeListOrThrow(appliedArguments[2]);
|
|
1091
|
+
const remainingArguments = appliedArguments.slice(3);
|
|
1092
|
+
for (const item of listItems) {
|
|
1093
|
+
accumulator = this.applyFunctionOrThrow(this.applyFunctionOrThrow(foldFunction, [accumulator], traceSink), [item], traceSink);
|
|
1094
|
+
}
|
|
1095
|
+
return remainingArguments.length === 0
|
|
1096
|
+
? accumulator
|
|
1097
|
+
: this.applyFunctionOrThrow(accumulator, remainingArguments, traceSink);
|
|
1098
|
+
}
|
|
1099
|
+
applyFoldrBuiltinOrThrow(builtinValue, argumentValues, traceSink) {
|
|
1100
|
+
const appliedArguments = [
|
|
1101
|
+
...builtinValue.appliedArguments,
|
|
1102
|
+
...argumentValues,
|
|
1103
|
+
];
|
|
1104
|
+
if (appliedArguments.length < 3) {
|
|
1105
|
+
return {
|
|
1106
|
+
kind: "builtin",
|
|
1107
|
+
builtinFunction: builtinValue.builtinFunction,
|
|
1108
|
+
appliedArguments,
|
|
1109
|
+
};
|
|
1110
|
+
}
|
|
1111
|
+
const foldFunction = appliedArguments[0];
|
|
1112
|
+
let accumulator = appliedArguments[1];
|
|
1113
|
+
const listItems = this.readRuntimeListOrThrow(appliedArguments[2]);
|
|
1114
|
+
const remainingArguments = appliedArguments.slice(3);
|
|
1115
|
+
for (const item of [...listItems].reverse()) {
|
|
1116
|
+
accumulator = this.applyFunctionOrThrow(this.applyFunctionOrThrow(foldFunction, [item], traceSink), [accumulator], traceSink);
|
|
1117
|
+
}
|
|
1118
|
+
return remainingArguments.length === 0
|
|
1119
|
+
? accumulator
|
|
1120
|
+
: this.applyFunctionOrThrow(accumulator, remainingArguments, traceSink);
|
|
1121
|
+
}
|
|
1122
|
+
deriveFrame(frame, scope) {
|
|
1123
|
+
return new DamlLfRuntimeFrame({
|
|
1124
|
+
frameId: frame.frameId,
|
|
1125
|
+
packageId: frame.packageId,
|
|
1126
|
+
moduleName: frame.moduleName,
|
|
1127
|
+
definition: frame.definition,
|
|
1128
|
+
scope,
|
|
1129
|
+
});
|
|
1130
|
+
}
|
|
1131
|
+
}
|