Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use TO_TEXT_CONTRACT_ID in Show instance of ContractId #7153

Merged
merged 1 commit into from
Aug 17, 2020
Merged
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
Use TO_TEXT_CONTRACT_ID in Show instance of ContractId
fixes #7114

This PR changes the Show instance of ContractId and flips the switch
on triggers and DAML Script to run in off-ledger mode.

It also adds a test that for DAML Script we actually get back the
correct contract id.

There is a bit of a design decision here in how we want to print
contract ids, so let me list the options I considered. $cid will stand
for the actual cid and all options are wrapped in markdown inline
code.

1. `"$cid"`. Indistinguishable from string. Suggests that there might
be an IsString instance for ContractId.
2. `<$cid>`. Matches the dummy `<contract-id>` but it’s not a dummy so
I don’t think matching that is benefitial.
3. `$cid`. Easy to spot (contract ids start with # and have no
spaces), clearly not a string but might look slightly weird.

changelog_begin
changelog_end
  • Loading branch information
cocreature committed Aug 17, 2020
commit cc7f5076f4ff788aad950eb287896ef2394bc90a
9 changes: 9 additions & 0 deletions compiler/daml-lf-ast/src/DA/Daml/LF/Ast/Version.hs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,14 @@ featureUnstable = Feature
, featureCppFlag = "DAML_UNSTABLE"
}

featureToTextContractId :: Feature
featureToTextContractId = Feature
{ featureName = "TO_TEXT_CONTRACT_ID primitive"
-- TODO Change as part of #7139
, featureMinVersion = versionDev
, featureCppFlag = "DAML_TO_TEXT_CONTRACT_ID"
}

allFeatures :: [Feature]
allFeatures =
[ featureNumeric
Expand All @@ -130,6 +138,7 @@ allFeatures =
, featureGenMap
, featurePackageMetadata
, featureUnstable
, featureToTextContractId
]

allFeaturesForVersion :: Version -> [Feature]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,12 @@ convertPrim _ "BETextReplicate" (TInt64 :-> TText :-> TText) = EBuiltin BETextRe
convertPrim _ "BETextSplitOn" (TText :-> TText :-> TList TText) = EBuiltin BETextSplitOn
convertPrim _ "BETextIntercalate" (TText :-> TList TText :-> TText) = EBuiltin BETextIntercalate

-- Conversion from ContractId to Text

convertPrim _ "BEToTextContractId" (TContractId t :-> TOptional TText) =
ETyApp (EBuiltin BEToTextContractId) t


-- Template Desugaring.

convertPrim _ "UCreate" (TCon template :-> TUpdate (TContractId (TCon template')))
Expand Down
9 changes: 8 additions & 1 deletion compiler/damlc/daml-stdlib-src/DA/Internal/LF.daml
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,14 @@ data Map a b =
data ContractId a =
ContractId Opaque
instance Eq (ContractId a) where (==) = primitive @"BEEqualContractId"
instance Show (ContractId a) where show _ = "<contract-id>"
instance Show (ContractId a) where
#ifdef DAML_TO_TEXT_CONTRACT_ID
show cid = case primitive @"BEToTextContractId" cid of
None -> "<contract-id>"
Some t -> t
#else
show _ = "<contract-id>"
#endif

-- | HIDE This is currently used in the internals of DAML script and DAML triggers
-- but not really something that we want to expose to users.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,8 @@ class Runner(compiledPackages: CompiledPackages, script: Script.Action, timeMode
esf: ExecutionSequencerFactory,
mat: Materializer): Future[SValue] = {
var clients = initialClients
val machine = Speedy.Machine.fromPureSExpr(extendedCompiledPackages, script.expr)
val machine =
Speedy.Machine.fromPureSExpr(extendedCompiledPackages, script.expr, onLedger = false)

def stepToValue(): Either[RuntimeException, SValue] =
machine.run() match {
Expand Down
71 changes: 64 additions & 7 deletions daml-script/test/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,37 @@ EOF
visibility = ["//visibility:public"],
)

# Test DAR in 1.dev to test new features.
genrule(
name = "script-test-1.dev",
srcs =
glob(["**/*.daml"]) + ["//daml-script/daml:daml-script-1.dev.dar"],
outs = ["script-test-1.dev.dar"],
cmd = """
set -eou pipefail
TMP_DIR=$$(mktemp -d)
mkdir -p $$TMP_DIR/daml
cp -L $(location :daml/TestContractId.daml) $$TMP_DIR/daml
cp -L $(location //daml-script/daml:daml-script-1.dev.dar) $$TMP_DIR/
cat << EOF > $$TMP_DIR/daml.yaml
sdk-version: {sdk}
name: script-test-1dev
version: 0.0.1
source: daml
build-options:
- --target=1.dev
dependencies:
- daml-stdlib
- daml-prim
- daml-script-1.dev.dar
EOF
$(location //compiler/damlc) build --project-root=$$TMP_DIR -o $$PWD/$(location script-test-1.dev.dar)
rm -rf $$TMP_DIR
""".format(sdk = sdk_version),
tools = ["//compiler/damlc"],
visibility = ["//visibility:public"],
)

# A variant of script-test that has not been uploaded to the ledger
# to test missing template ids. We only care that this has a different package id.
genrule(
Expand Down Expand Up @@ -93,6 +124,7 @@ da_scala_library(
"//daml-lf/data",
"//daml-lf/interpreter",
"//daml-lf/language",
"//daml-lf/transaction",
"//daml-script/runner:script-runner-lib",
"//language-support/scala/bindings",
"//language-support/scala/bindings-akka",
Expand Down Expand Up @@ -175,28 +207,46 @@ da_scala_test_suite(
client_server_test(
name = "test_static_time",
client = ":test_client_single_participant",
client_files = ["$(rootpath :script-test.dar)"],
data = [":script-test.dar"],
client_files = [
"$(rootpath :script-test.dar)",
"$(rootpath :script-test-1.dev.dar)",
],
data = [
":script-test.dar",
":script-test-1.dev.dar",
],
server = "//ledger/sandbox-classic:sandbox-classic-binary",
server_args = [
"--static-time",
"--port=0",
],
server_files = ["$(rootpath :script-test.dar)"],
server_files = [
"$(rootpath :script-test.dar)",
"$(rootpath :script-test-1.dev.dar)",
],
)

client_server_test(
name = "test_wallclock_time",
client = ":test_client_single_participant",
client_args = ["-w"],
client_files = ["$(rootpath :script-test.dar)"],
data = [":script-test.dar"],
client_files = [
"$(rootpath :script-test.dar)",
"$(rootpath :script-test-1.dev.dar)",
],
data = [
":script-test.dar",
":script-test-1.dev.dar",
],
server = "//ledger/sandbox-classic:sandbox-classic-binary",
server_args = [
"--wall-clock-time",
"--port=0",
],
server_files = ["$(rootpath :script-test.dar)"],
server_files = [
"$(rootpath :script-test.dar)",
"$(rootpath :script-test-1.dev.dar)",
],
)

client_server_test(
Expand All @@ -208,9 +258,11 @@ client_server_test(
],
client_files = [
"$(rootpath :script-test.dar)",
"$(rootpath :script-test-1.dev.dar)",
],
data = [
":script-test.dar",
":script-test-1.dev.dar",
],
server = "//ledger/sandbox-classic:sandbox-classic-binary",
server_args = [
Expand All @@ -230,9 +282,11 @@ client_server_test(
],
client_files = [
"$(rootpath :script-test.dar)",
"$(rootpath :script-test-1.dev.dar)",
],
data = [
":script-test.dar",
":script-test-1.dev.dar",
"//ledger/test-common/test-certificates:ca.crt",
"//ledger/test-common/test-certificates:server.crt",
"//ledger/test-common/test-certificates:server.pem",
Expand All @@ -245,7 +299,10 @@ client_server_test(
"--pem $$(rlocation $$TEST_WORKSPACE/$(rootpath //ledger/test-common/test-certificates:server.pem))",
"--client-auth=none",
],
server_files = ["$(rootpath :script-test.dar)"],
server_files = [
"$(rootpath :script-test.dar)",
"$(rootpath :script-test-1.dev.dar)",
],
)

client_server_test(
Expand Down
18 changes: 18 additions & 0 deletions daml-script/test/daml/TestContractId.daml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
-- Copyright (c) 2020 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
-- SPDX-License-Identifier: Apache-2.0

module TestContractId where

import Daml.Script

template T
with
t : Party
where
signatory t

testContractId = do
p <- allocateParty "p"
cid <- submit p (createCmd (T p))
pure (cid, show cid)

Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ import com.daml.lf.engine.script.{Party => ScriptParty, _}
case class Config(
ledgerPort: Int,
darPath: File,
// 1.dev DAR
devDarPath: File,
wallclockTime: Boolean,
auth: Boolean,
// We use the presence of a root CA as a proxy for whether to enable TLS or not.
Expand Down Expand Up @@ -384,6 +386,28 @@ case class TestAuth(dar: Dar[(PackageId, Package)], runner: TestRunner) {
}
}

case class TestContractId(dar: Dar[(PackageId, Package)], runner: TestRunner) {
val scriptId =
Identifier(dar.main._1, QualifiedName.assertFromString("TestContractId:testContractId"))
def runTests(): Unit = {
runner.genericTest(
"testContractId",
scriptId,
None, {
case SRecord(_, _, vals) if vals.size == 2 => {
(vals.get(0), vals.get(1)) match {
case (SContractId(cid), SText(t)) =>
TestRunner.assertEqual(t, cid.coid, "contract ids")
case (a, b) =>
Left(s"Expected SContractId, SText but got $a, $b")
}
}
case v => Left(s"Expected Tuple2 but got $v")
}
)
}
}

object SingleParticipant {

private val configParser = new scopt.OptionParser[Config]("daml_script_test") {
Expand All @@ -397,6 +421,10 @@ object SingleParticipant {
.required()
.action((d, c) => c.copy(darPath = d))

arg[File]("dev-dar")
.required()
.action((d, c) => c.copy(devDarPath = d))

opt[Unit]('w', "wall-clock-time")
.action { (_, c) =>
c.copy(wallclockTime = true)
Expand Down Expand Up @@ -432,7 +460,7 @@ object SingleParticipant {
}

def main(args: Array[String]): Unit = {
configParser.parse(args, Config(0, null, false, false, None)) match {
configParser.parse(args, Config(0, null, null, false, false, None)) match {
case None =>
sys.exit(1)
case Some(config) =>
Expand All @@ -442,6 +470,13 @@ object SingleParticipant {
case (pkgId, pkgArchive) => Decode.readArchivePayload(pkgId, pkgArchive)
}

println(config.devDarPath)
val encodedDevDar: Dar[(PackageId, DamlLf.ArchivePayload)] =
DarReader().readArchiveFromFile(config.devDarPath).get
val devDar: Dar[(PackageId, Package)] = encodedDevDar.map {
case (pkgId, pkgArchive) => Decode.readArchivePayload(pkgId, pkgArchive)
}

val participantParams = if (config.auth) {
Participants(
None,
Expand Down Expand Up @@ -474,6 +509,8 @@ object SingleParticipant {

val runner =
new TestRunner(participantParams, dar, config.wallclockTime, config.rootCa)
val devRunner =
new TestRunner(participantParams, devDar, config.wallclockTime, config.rootCa)
if (!config.auth) {
TraceOrder(dar, runner).runTests()
Test0(dar, runner).runTests()
Expand All @@ -490,6 +527,7 @@ object SingleParticipant {
TestStack(dar, runner).runTests()
TestMaxInboundMessageSize(dar, runner).runTests()
ScriptExample(dar, runner).runTests()
TestContractId(devDar, devRunner).runTests()
// Keep this at the end since it changes the time and we cannot go backwards.
if (!config.wallclockTime) {
SetTime(dar, runner).runTests()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,8 @@ class Runner(
getInitialState,
Array(SParty(Party.assertFromString(party)), STimestamp(clientTime), createdValue))
// Prepare a speedy machine for evaluting expressions.
val machine: Speedy.Machine = Speedy.Machine.fromPureSExpr(compiledPackages, initialState)
val machine: Speedy.Machine =
Speedy.Machine.fromPureSExpr(compiledPackages, initialState, onLedger = false)
// Evaluate it.
machine.setExpressionToEvaluate(initialState)
val value = Machine.stepToValue(machine)
Expand Down