From 9bfb5299ab1a66eba4d09c824ac876a7ee3ac393 Mon Sep 17 00:00:00 2001 From: Remy Haemmerle Date: Tue, 5 Oct 2021 08:45:38 +0200 Subject: [PATCH] LF: builtins to create, signatory, and obersver on interface payload. CHANGELOG_BEGIN CHANGELOG_END --- compiler/damlc/BUILD.bazel | 2 +- .../DA/Experimental/Interface.daml | 21 ++++++ .../damlc/daml-stdlib-src/LibraryModules.daml | 1 + .../InterfaceExperimental.daml | 74 +++++++++++++++++++ .../daml/lf/speedy/SBuiltin.scala | 23 +++++- daml-lf/spec/experimental.rst | 4 +- 6 files changed, 119 insertions(+), 6 deletions(-) create mode 100644 compiler/damlc/daml-stdlib-src/DA/Experimental/Interface.daml create mode 100644 compiler/damlc/tests/daml-test-files/InterfaceExperimental.daml diff --git a/compiler/damlc/BUILD.bazel b/compiler/damlc/BUILD.bazel index 220b98efad7c..c5e4bb91a325 100644 --- a/compiler/damlc/BUILD.bazel +++ b/compiler/damlc/BUILD.bazel @@ -320,7 +320,7 @@ daml_doc_test( flags = ["--no-dflags-check"], ignored_srcs = [ "LibraryModules.daml", - "DA/Experimental/Example.daml", + "DA/Experimental/*.daml", "DA/Time/Types.daml", ], ) diff --git a/compiler/damlc/daml-stdlib-src/DA/Experimental/Interface.daml b/compiler/damlc/daml-stdlib-src/DA/Experimental/Interface.daml new file mode 100644 index 000000000000..fccb9ecc4146 --- /dev/null +++ b/compiler/damlc/daml-stdlib-src/DA/Experimental/Interface.daml @@ -0,0 +1,21 @@ +-- Copyright (c) 2021 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. +-- SPDX-License-Identifier: Apache-2.0 + +{-# LANGUAGE CPP #-} + +module DA.Experimental.Interface( + interfaceCreate, + interfaceSignatory, + interfaceObserver, +) where + +import GHC.Types (primitive) + +interfaceCreate: t -> Update (ContractId t) +interfaceCreate = primitive @"$INTERFACE_CREATE" + +interfaceSignatory: t -> [Party] +interfaceSignatory = primitive @"$INTERFACE_SIGNATORIES" + +interfaceObserver: t -> [Party] +interfaceObserver = primitive @"$INTERFACE_OBSERVERS" diff --git a/compiler/damlc/daml-stdlib-src/LibraryModules.daml b/compiler/damlc/daml-stdlib-src/LibraryModules.daml index 41770e91f7e2..43d957b544db 100644 --- a/compiler/damlc/daml-stdlib-src/LibraryModules.daml +++ b/compiler/damlc/daml-stdlib-src/LibraryModules.daml @@ -60,6 +60,7 @@ import DA.Validation #ifdef DAML_EXPERIMENTAL import DA.Experimental.Example +import DA.Experimental.Interface #endif import Prelude diff --git a/compiler/damlc/tests/daml-test-files/InterfaceExperimental.daml b/compiler/damlc/tests/daml-test-files/InterfaceExperimental.daml new file mode 100644 index 000000000000..0cb2a7fc3114 --- /dev/null +++ b/compiler/damlc/tests/daml-test-files/InterfaceExperimental.daml @@ -0,0 +1,74 @@ +-- Copyright (c) 2021 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. +-- SPDX-License-Identifier: Apache-2.0 + +-- @SINCE-LF-FEATURE DAML_INTERFACE + +-- TODO https://github.com/digital-asset/daml/issues/10810 +-- DROP when we have more meaningful test for create, signatories, observers +module InterfaceExperimental where + +import DA.Assert ((===)) +import DA.Experimental.Interface +import GHC.Types (primitive) + +interface Token where + getAmount : Int + + choice Split : (ContractId Token, ContractId Token) + with + splitAmount : Int + + choice Transfer : ContractId Token + with + newOwner : Party + + nonconsuming choice Noop : () + with + nothing : () + +template Asset + with + issuer : Party + owner : Party + amount : Int + where + signatory issuer + observer issuer, owner + implements Token where + let getAmount = amount + + choice Split : (ContractId Token, ContractId Token) + with + splitAmount : Int + controller owner + do + assert (splitAmount < amount) + cid1 <- create this with amount = splitAmount + cid2 <- create this with amount = amount - splitAmount + pure (toTokenContractId cid1, toTokenContractId cid2) + + choice Transfer : ContractId Token + with + newOwner : Party + controller owner, newOwner + do + cid <- create this with owner = newOwner + pure (toTokenContractId cid) + + nonconsuming choice Noop : () + with + nothing : () + controller owner + do + pure () + +main = scenario do + alice <- getParty "Alice" + bob <- getParty "Bob" + let asset = Asset alice bob 15 + let token = toToken asset + submit alice do + interfaceCreate token + interfaceSignatory token === [alice] + interfaceObserver token === [bob, alice] + pure () diff --git a/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/SBuiltin.scala b/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/SBuiltin.scala index 0d324a4c9b45..a240c3ba1979 100644 --- a/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/SBuiltin.scala +++ b/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/SBuiltin.scala @@ -1702,14 +1702,31 @@ private[lf] object SBuiltin { } } - def apply(name: String): SExpr = - mapping.getOrElse(name, SBError(SEValue(SText(s"experimental $name not supported.")))) + private final class SBExperimentalInterfaceDef( + toSDefRef: Identifier => SDefinitionRef, + name: String, + arity: Int, + ) extends SBExperimental(name, arity) { + override private[speedy] def execute( + args: util.ArrayList[SValue], + machine: Machine, + ): Unit = { + val tmplId = getSRecord(args, 0).id + machine.ctrl = SEApp(SEVal(toSDefRef(tmplId)), args.asScala.view.map(SEValue(_)).toArray) + } + } private val mapping: Map[String, SEBuiltin] = List[SBExperimental]( - SBExperimentalAnswer + SBExperimentalAnswer, + new SBExperimentalInterfaceDef(CreateDefRef, "INTERFACE_CREATE", 2), + new SBExperimentalInterfaceDef(SignatoriesDefRef, "INTERFACE_SIGNATORIES", 1), + new SBExperimentalInterfaceDef(ObserversDefRef, "INTERFACE_OBSERVERS", 1), ).map(x => x.name -> SEBuiltin(x)).toMap + def apply(name: String): SExpr = + mapping.getOrElse(name, SBError(SEValue(SText(s"experimental $name not supported.")))) + } // Helpers diff --git a/daml-lf/spec/experimental.rst b/daml-lf/spec/experimental.rst index 2466c1bbd9f3..be60b9675728 100644 --- a/daml-lf/spec/experimental.rst +++ b/daml-lf/spec/experimental.rst @@ -14,8 +14,8 @@ archive Protobuf definitions, compilers, type checkers, and archive (de/en)coders. In addition of development speed, those hooks also adds some -confidence non-development feature are not impacted when prototyping -new Daml feature as few part of the stack had to be modified. +confidence non-development features are not impacted when prototyping +new Daml feature as few parts of the stack have to be modified. Daml-LF Experimental Specification ----------------------------------