diff --git a/compiler/scenario-service/server/src/main/scala/com/digitalasset/daml/lf/scenario/Context.scala b/compiler/scenario-service/server/src/main/scala/com/digitalasset/daml/lf/scenario/Context.scala index f9def6dde21..d7b2b674669 100644 --- a/compiler/scenario-service/server/src/main/scala/com/digitalasset/daml/lf/scenario/Context.scala +++ b/compiler/scenario-service/server/src/main/scala/com/digitalasset/daml/lf/scenario/Context.scala @@ -20,7 +20,6 @@ import com.daml.lf.speedy.Speedy import com.daml.lf.speedy.SExpr import com.daml.lf.speedy.SValue import com.daml.lf.speedy.SExpr.{LfDefRef, SDefinitionRef} -import com.daml.lf.transaction.TransactionVersions import com.daml.lf.validation.Validation import com.google.protobuf.ByteString @@ -164,7 +163,8 @@ class Context(val contextId: Context.ContextId, languageVersion: LanguageVersion compiledPackages, txSeeding, defn, - TransactionVersions.SupportedDevOutputVersions, + value.ValueVersions.DevOutputVersions, + transaction.TransactionVersions.DevOutputVersions, ) } diff --git a/compiler/scenario-service/server/src/main/scala/com/digitalasset/daml/lf/scenario/Conversions.scala b/compiler/scenario-service/server/src/main/scala/com/digitalasset/daml/lf/scenario/Conversions.scala index 33c9d4eb471..2cf0cfb313d 100644 --- a/compiler/scenario-service/server/src/main/scala/com/digitalasset/daml/lf/scenario/Conversions.scala +++ b/compiler/scenario-service/server/src/main/scala/com/digitalasset/daml/lf/scenario/Conversions.scala @@ -155,6 +155,11 @@ final class Conversions( sys.error( s"Got unexpected DamlEWronglyTypedContract error in scenario service: $wtc. Note that in the scenario service this error should never surface since contract fetches are all type checked.", ) + + case divv: SError.DamlEDisallowedInputValueVersion => + sys.error( + s"Got unexpected DamlEDisallowedInputVersion error in scenario service: $divv. Note that in the scenario service this error should never surface since its accept all stable versions.", + ) } builder.build } diff --git a/daml-lf/engine/src/main/scala/com/digitalasset/daml/lf/engine/Engine.scala b/daml-lf/engine/src/main/scala/com/digitalasset/daml/lf/engine/Engine.scala index 4ec1982b178..7357142e170 100644 --- a/daml-lf/engine/src/main/scala/com/digitalasset/daml/lf/engine/Engine.scala +++ b/daml-lf/engine/src/main/scala/com/digitalasset/daml/lf/engine/Engine.scala @@ -293,7 +293,8 @@ class Engine(private[lf] val config: EngineConfig = EngineConfig.Stable) { expr = SExpr.SEApp(sexpr, Array(SExpr.SEValue.Token)), globalCids = globalCids, committers = submitters, - outputTransactionVersions = config.outputTransactionVersions, + inputValueVersions = config.allowedInputValueVersions, + outputTransactionVersions = config.allowedOutputTransactionVersions, validating = validating, ) interpretLoop(machine, ledgerTime) @@ -428,13 +429,13 @@ class Engine(private[lf] val config: EngineConfig = EngineConfig.Stable) { } private[engine] def addPackage(pkgId: PackageId, pkg: Package): Result[Unit] = - if (config.languageVersions.contains(pkg.languageVersion)) + if (config.allowedLanguageVersions.contains(pkg.languageVersion)) compiledPackages.addPackage(pkgId, pkg) else ResultError( Error( s"Disallowed language version in package $pkgId: " + - s"Expected version between ${config.languageVersions.min} and ${config.languageVersions.max} but got ${pkg.languageVersion}" + s"Expected version between ${config.allowedLanguageVersions.min} and ${config.allowedLanguageVersions.max} but got ${pkg.languageVersion}" ) ) diff --git a/daml-lf/engine/src/main/scala/com/digitalasset/daml/lf/engine/EngineConfig.scala b/daml-lf/engine/src/main/scala/com/digitalasset/daml/lf/engine/EngineConfig.scala index 350b026be60..e10a3742ff4 100644 --- a/daml-lf/engine/src/main/scala/com/digitalasset/daml/lf/engine/EngineConfig.scala +++ b/daml-lf/engine/src/main/scala/com/digitalasset/daml/lf/engine/EngineConfig.scala @@ -11,45 +11,55 @@ import com.daml.lf.transaction.{TransactionVersions, TransactionVersion => TV} // Currently only outputTransactionVersions is used. // languageVersions and outputTransactionVersions should be plug final case class EngineConfig( - // constrains the version of language accepted by the engine - languageVersions: VersionRange[LV], - // constrains the version of output transactions - inputTransactionVersions: VersionRange[TV], - // constrains the version of output transactions - outputTransactionVersions: VersionRange[TV], -) + // constrains the versions of language accepted by the engine + allowedLanguageVersions: VersionRange[LV], + // constrains the versions of input transactions + allowedInputTransactionVersions: VersionRange[TV], + // constrains the versions of output transactions + allowedOutputTransactionVersions: VersionRange[TV], +) { + + private[lf] val allowedInputValueVersions = + VersionRange( + TransactionVersions.assignValueVersion(allowedInputTransactionVersions.min), + TransactionVersions.assignValueVersion(allowedInputTransactionVersions.max), + ) + + private[lf] val allowedOutputValueVersions = + VersionRange( + TransactionVersions.assignValueVersion(allowedOutputTransactionVersions.min), + TransactionVersions.assignValueVersion(allowedOutputTransactionVersions.max), + ) + +} object EngineConfig { - // development configuration, should not be used in PROD. - // accept all language and transaction versions supported by SDK_1_x plus development versions. + // Development configuration, should not be used in PROD. val Dev: EngineConfig = new EngineConfig( - languageVersions = VersionRange( + allowedLanguageVersions = VersionRange( LV(LV.Major.V1, LV.Minor.Stable("6")), LV(LV.Major.V1, LV.Minor.Dev), ), - inputTransactionVersions = VersionRange( + allowedInputTransactionVersions = VersionRange( TV("10"), TransactionVersions.acceptedVersions.last ), - outputTransactionVersions = VersionRange( - TV("10"), - TransactionVersions.acceptedVersions.last - ) + allowedOutputTransactionVersions = TransactionVersions.DevOutputVersions ) // Legacy configuration, to be used by sandbox classic only @deprecated("Sandbox_Classic is to be used by sandbox classic only", since = "1.4.0") val Sandbox_Classic: EngineConfig = new EngineConfig( - languageVersions = VersionRange( - LV(LV.Major.V1, LV.Minor.Stable("1")), + allowedLanguageVersions = VersionRange( + LV(LV.Major.V1, LV.Minor.Stable("0")), LV(LV.Major.V1, LV.Minor.Dev), ), - inputTransactionVersions = VersionRange( + allowedInputTransactionVersions = VersionRange( TransactionVersions.acceptedVersions.head, TransactionVersions.acceptedVersions.last ), - outputTransactionVersions = VersionRange( + allowedOutputTransactionVersions = VersionRange( TV("10"), TransactionVersions.acceptedVersions.last ) @@ -57,12 +67,12 @@ object EngineConfig { // recommended configuration val Stable: EngineConfig = new EngineConfig( - languageVersions = VersionRange( + allowedLanguageVersions = VersionRange( LV(LV.Major.V1, LV.Minor.Stable("6")), LV(LV.Major.V1, LV.Minor.Stable("8")), ), - inputTransactionVersions = VersionRange(TV("10"), TV("10")), - outputTransactionVersions = VersionRange(TV("10"), TV("10")) + allowedInputTransactionVersions = VersionRange(TV("10"), TV("10")), + allowedOutputTransactionVersions = VersionRange(TV("10"), TV("10")) ) } diff --git a/daml-lf/engine/src/main/scala/com/digitalasset/daml/lf/engine/EngineInfo.scala b/daml-lf/engine/src/main/scala/com/digitalasset/daml/lf/engine/EngineInfo.scala index 2823651da5c..304ba7aa3e5 100644 --- a/daml-lf/engine/src/main/scala/com/digitalasset/daml/lf/engine/EngineInfo.scala +++ b/daml-lf/engine/src/main/scala/com/digitalasset/daml/lf/engine/EngineInfo.scala @@ -1,53 +1,85 @@ // Copyright (c) 2020 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. // SPDX-License-Identifier: Apache-2.0 -package com.daml.lf.engine - -import com.daml.lf.language.{LanguageVersion => LV} -import com.daml.lf.transaction.TransactionVersions -import com.daml.lf.value.ValueVersions +package com.daml.lf +package engine class EngineInfo(config: EngineConfig) { - override lazy val toString: String = show + import language.{LanguageVersion => LV} - lazy val show: String = - s"DAML LF Engine supports LF versions: $formatLfVersions; Input Transaction versions: $formatInputTransactionVersions; Input Value versions: $formatInputValueVersions; Output Transaction versions: $formatOutputTransactionVersions; Output Value versions: $formatOutputValueVersions" + override def toString: String = show + def show: String = pretty.mkString(System.lineSeparator()) - private[this] def formatInputTransactionVersions: String = - format(TransactionVersions.acceptedVersions.map(_.protoValue)) + lazy val pretty: Iterable[String] = { - private[this] def formatOutputTransactionVersions: String = - format( - TransactionVersions.acceptedVersions - .collect { - case v if config.outputTransactionVersions.contains(v) => - v.protoValue - } + val allLangVersions = + for { + major <- LV.Major.All + minor <- major.supportedMinorVersions + } yield LV(major, minor) + + val allTransactionVersions = + transaction.TransactionVersions.acceptedVersions + + val allValueVersions = + value.ValueVersions.acceptedVersions + + val allOutputTransactionVersions = + allTransactionVersions.filter(transaction.TransactionVersions.DevOutputVersions.contains) + + val allOutputValueVersions = + allOutputTransactionVersions.map(transaction.TransactionVersions.assignValueVersion) + + val allowedLangVersions = + allLangVersions.filter(config.allowedLanguageVersions.contains) + + val allowedInputTransactionVersions = + allTransactionVersions.filter(config.allowedInputTransactionVersions.contains) + + val allowedInputValueVersions = + allValueVersions.filter(config.allowedInputValueVersions.contains) + + val allowedOutputTransactionVersions = + allTransactionVersions.filter(config.allowedOutputTransactionVersions.contains) + + val allowedOutputValueVersions = + allValueVersions.filter(config.allowedOutputValueVersions.contains) + + List( + List( + formatLangVersions(allLangVersions), + formatTxVersions("input", allTransactionVersions), + formatValVersions("input", allValueVersions), + formatTxVersions("output", allOutputTransactionVersions), + formatValVersions("output", allOutputValueVersions) + ).mkString("DAML LF Engine supports ", "; ", "."), + List( + formatLangVersions(allowedLangVersions), + formatTxVersions("input", allowedInputTransactionVersions), + formatValVersions("input", allowedInputValueVersions), + formatTxVersions("output", allowedOutputTransactionVersions), + formatValVersions("output", allowedOutputValueVersions) + ).mkString("DAML LF Engine config allows ", "; ", ".") ) - - private[this] def formatInputValueVersions: String = - format(ValueVersions.acceptedVersions.map(_.protoValue)) - - private[this] def formatOutputValueVersions: String = { - val outputValueVersions = - config.outputTransactionVersions.map(TransactionVersions.assignValueVersion) - format(ValueVersions.acceptedVersions.filter(outputValueVersions.contains).map(_.protoValue)) } - private def formatLfVersions: String = { - val allVersions: Iterable[String] = - LV.Major.All flatMap (mv => lfVersions(mv.pretty, mv.supportedMinorVersions)) - format(allVersions) - } - - private def lfVersions( - majorVersion: String, - minorVersions: Iterable[LV.Minor]): Iterable[String] = - minorVersions.map { a => - val ap = a.toProtoIdentifier - s"$majorVersion${if (ap.isEmpty) "" else s".$ap"}" + private[this] def formatLangVersions(versions: Iterable[LV]) = { + val prettyVersions = versions.map { + case LV(major, minor) => + val ap = minor.toProtoIdentifier + s"${major.pretty}${if (ap.isEmpty) "" else s".$ap"}" } + s"LF versions: ${prettyVersions.mkString(", ")}" + } + + private[this] def formatTxVersions( + prefix: String, + versions: List[transaction.TransactionVersion], + ) = + s"$prefix transaction versions: ${versions.map(_.protoValue).mkString(", ")}" + + private[this] def formatValVersions(prefix: String, versions: List[value.ValueVersion]) = + s"$prefix value versions: ${versions.map(_.protoValue).mkString(", ")}" - private def format(as: Iterable[String]): String = as.mkString(", ") } diff --git a/daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/EngineInfoTest.scala b/daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/EngineInfoTest.scala index 6183f87dbfd..a0ea406d654 100644 --- a/daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/EngineInfoTest.scala +++ b/daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/EngineInfoTest.scala @@ -18,14 +18,22 @@ class EngineInfoTest extends WordSpec with Matchers { "show supported LF, Transaction and Value versions" in { - engineInfoStable.show shouldBe - "DAML LF Engine supports LF versions: 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.dev; Input Transaction versions: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11; Input Value versions: 1, 2, 3, 4, 5, 6, 7; Output Transaction versions: 10; Output Value versions: 6" + infos.foreach( + _.pretty.toSeq(0) shouldBe + "DAML LF Engine supports LF versions: 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.dev; input transaction versions: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11; input value versions: 1, 2, 3, 4, 5, 6, 7; output transaction versions: 10, 11; output value versions: 6, 7." + ) + } - engineInfoDev.show shouldBe - "DAML LF Engine supports LF versions: 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.dev; Input Transaction versions: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11; Input Value versions: 1, 2, 3, 4, 5, 6, 7; Output Transaction versions: 10, 11; Output Value versions: 6, 7" + "show allowed LF, Transaction and Value versions" in { - engineInfoLegacy.show shouldBe - "DAML LF Engine supports LF versions: 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.dev; Input Transaction versions: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11; Input Value versions: 1, 2, 3, 4, 5, 6, 7; Output Transaction versions: 10, 11; Output Value versions: 6, 7" + engineInfoStable.pretty.toSeq(1) shouldBe + "DAML LF Engine config allows LF versions: 1.6, 1.7, 1.8; input transaction versions: 10; input value versions: 6; output transaction versions: 10; output value versions: 6." + + engineInfoDev.pretty.toSeq(1) shouldBe + "DAML LF Engine config allows LF versions: 1.6, 1.7, 1.8, 1.dev; input transaction versions: 10, 11; input value versions: 6, 7; output transaction versions: 10, 11; output value versions: 6, 7." + + engineInfoLegacy.pretty.toSeq(1) shouldBe + "DAML LF Engine config allows LF versions: 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.dev; input transaction versions: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11; input value versions: 1, 2, 3, 4, 5, 6, 7; output transaction versions: 10, 11; output value versions: 6, 7." } diff --git a/daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/EngineTest.scala b/daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/EngineTest.scala index 87227740235..9c61366c503 100644 --- a/daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/EngineTest.scala +++ b/daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/EngineTest.scala @@ -23,7 +23,7 @@ import com.daml.lf.transaction.{ Transaction => Tx, TransactionVersions => TxVersions } -import com.daml.lf.value.Value +import com.daml.lf.value.{Value, ValueVersion} import Value._ import com.daml.lf.speedy.{InitialSeeding, SValue, svalue} import com.daml.lf.speedy.SValue._ @@ -1628,6 +1628,48 @@ class EngineTest } } + "Engine#submit" should { + val cidV6 = toContractId("#cidV6") + val cidV7 = toContractId("#cidV7") + val contract = ValueRecord( + Some(Identifier(basicTestsPkgId, "BasicTests:Simple")), + ImmArray((Some[Name]("p"), ValueParty(party))) + ) + val hello = Identifier(basicTestsPkgId, "BasicTests:Hello") + val templateId = TypeConName(basicTestsPkgId, "BasicTests:Simple") + val now = Time.Timestamp.now() + val submissionSeed = crypto.Hash.hashPrivateKey("engine check the version of input value") + def contracts = Map( + cidV6 -> ContractInst(templateId, VersionedValue(ValueVersion("6"), contract), ""), + cidV7 -> ContractInst(templateId, VersionedValue(ValueVersion("7"), contract), ""), + ) + + def run(cid: ContractId) = { + val engine = new Engine(EngineConfig.Stable) + val cmds = Commands( + submitter = party, + commands = ImmArray( + ExerciseCommand(templateId, cid, "Hello", ValueRecord(Some(hello), ImmArray.empty))), + ledgerEffectiveTime = now, + commandsReference = "", + ) + engine + .submit(cmds, participant, submissionSeed) + .consume(contracts.get, lookupPackage, lookupKey) + } + + "succeed if fed with allowed value version" in { + run(cidV6) shouldBe 'right + } + + "fail if fed with disallowed value version" in { + val result = run(cidV7) + result shouldBe 'left + result.left.get.msg should include("Update failed due to disallowed value version") + } + + } + "Engine.addPackage" should { import com.daml.lf.language.{LanguageVersion => LV} @@ -1635,7 +1677,7 @@ class EngineTest def engine(min: LV.Minor, max: LV.Minor) = new Engine( EngineConfig.Dev.copy( - languageVersions = VersionRange(LV(LV.Major.V1, min), LV(LV.Major.V1, max)) + allowedLanguageVersions = VersionRange(LV(LV.Major.V1, min), LV(LV.Major.V1, max)) ) ) diff --git a/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/Anf.scala b/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/Anf.scala index e820d92ba0a..9dae2af51ce 100644 --- a/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/Anf.scala +++ b/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/Anf.scala @@ -345,7 +345,7 @@ private[lf] object Anf { } case x: SEAbs => throw CompilationError(s"flatten: unexpected: $x") - case x: SEWronglyTypeContractId => throw CompilationError(s"flatten: unexpected: $x") + case x: SEDamlException => throw CompilationError(s"flatten: unexpected: $x") case x: SEAppAtomicFun => throw CompilationError(s"flatten: unexpected: $x") case x: SEAppAtomicGeneral => throw CompilationError(s"flatten: unexpected: $x") case x: SEAppAtomicSaturatedBuiltin => throw CompilationError(s"flatten: unexpected: $x") diff --git a/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/Compiler.scala b/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/Compiler.scala index 3c0ba38ec58..d2982d3661b 100644 --- a/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/Compiler.scala +++ b/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/Compiler.scala @@ -1126,8 +1126,8 @@ private[lf] final case class Compiler( case SELabelClosure(label, expr) => SELabelClosure(label, closureConvert(remaps, expr)) - case x: SEWronglyTypeContractId => - throw CompilationError(s"unexpected SEWronglyTypeContractId: $x") + case x: SEDamlException => + throw CompilationError(s"unexpected SEDamlException: $x") case x: SEImportValue => throw CompilationError(s"unexpected SEImportValue: $x") @@ -1200,8 +1200,8 @@ private[lf] final case class Compiler( go(body, bound, go(handler, bound, go(fin, bound, free))) case SELabelClosure(_, expr) => go(expr, bound, free) - case x: SEWronglyTypeContractId => - throw CompilationError(s"unexpected SEWronglyTypeContractId: $x") + case x: SEDamlException => + throw CompilationError(s"unexpected SEDamlException: $x") case x: SEImportValue => throw CompilationError(s"unexpected SEImportValue: $x") @@ -1302,8 +1302,8 @@ private[lf] final case class Compiler( go(body) case SELabelClosure(_, expr) => go(expr) - case x: SEWronglyTypeContractId => - throw CompilationError(s"unexpected SEWronglyTypeContractId: $x") + case x: SEDamlException => + throw CompilationError(s"unexpected SEDamlException: $x") case x: SEImportValue => throw CompilationError(s"unexpected SEImportValue: $x") } diff --git a/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/Pretty.scala b/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/Pretty.scala index 3f1e10fef26..69151f83729 100644 --- a/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/Pretty.scala +++ b/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/Pretty.scala @@ -8,6 +8,7 @@ import org.typelevel.paiges.Doc._ import com.daml.lf.ledger.EventId import com.daml.lf.value.Value import Value.{NodeId => _, _} +import com.daml.lf.VersionRange import com.daml.lf.transaction.Node._ import com.daml.lf.ledger._ import com.daml.lf.data.Ref._ @@ -72,6 +73,12 @@ private[lf] object Pretty { text("Expected contract of type") & prettyTypeConName(expected) & text("but got") & prettyTypeConName( actual, ) + + case DamlEDisallowedInputValueVersion(VersionRange(expectedMin, expectedMax), actual) => + text("Update failed due to disallowed value version") / + text("Expected value version between") & text(expectedMin.protoValue) & + text("and") & text(expectedMax.protoValue) & text("but got") & + text(actual.protoValue) } // A minimal pretty-print of an update transaction node, without recursing into child nodes.. @@ -578,7 +585,7 @@ private[lf] object Pretty { case x: SEBuiltinRecursiveDefinition => str(x) case x: SEImportValue => str(x) case x: SELabelClosure => str(x) - case x: SEWronglyTypeContractId => str(x) + case x: SEDamlException => str(x) } } 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 2caa46281e5..fee36d06cce 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 @@ -1019,14 +1019,20 @@ private[lf] object SBuiltin { templateId, machine.committers, cbMissing = _ => machine.tryHandleException(), - cbPresent = { coinst => - // Note that we cannot throw in this continuation -- instead - // set the control appropriately which will crash the machine - // correctly later. - if (coinst.template != templateId) - machine.ctrl = SEWronglyTypeContractId(coid, templateId, coinst.template) - else - machine.ctrl = SEImportValue(coinst.arg.value) + cbPresent = { + case V.ContractInst(actualTmplId, V.VersionedValue(version, arg), _) => + // Note that we cannot throw in this continuation -- instead + // set the control appropriately which will crash the machine + // correctly later. + machine.ctrl = + if (actualTmplId != templateId) + SEDamlException(DamlEWronglyTypedContract(coid, templateId, actualTmplId)) + else if (!machine.inputValueVersions.contains(version)) + SEDamlException( + DamlEDisallowedInputValueVersion(machine.inputValueVersions, version), + ) + else + SEImportValue(arg) }, ), ) diff --git a/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/SError.scala b/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/SError.scala index 09e4bbb10d7..1700b359046 100644 --- a/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/SError.scala +++ b/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/SError.scala @@ -3,11 +3,12 @@ package com.daml.lf.speedy +import com.daml.lf.VersionRange import com.daml.lf.data.Ref._ import com.daml.lf.data.Time import com.daml.lf.ledger.EventId import com.daml.lf.transaction.{GlobalKey, NodeId, Transaction => Tx} -import com.daml.lf.value.Value +import com.daml.lf.value.{Value, ValueVersion} import com.daml.lf.scenario.ScenarioLedger import com.daml.lf.value.Value.ContractId @@ -88,6 +89,14 @@ object SError { actual: TypeConName, ) extends SErrorDamlException + /** We tried to fetch data with disallowed value version -- + * see + */ + final case class DamlEDisallowedInputValueVersion( + allowed: VersionRange[ValueVersion], + actual: ValueVersion, + ) extends SErrorDamlException + /** A fetch or exercise was being made against a contract that has not * been disclosed to 'committer'. */ final case class ScenarioErrorContractNotVisible( diff --git a/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/SExpr.scala b/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/SExpr.scala index 4ee35d2bdd1..dc4d97af13d 100644 --- a/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/SExpr.scala +++ b/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/SExpr.scala @@ -387,16 +387,12 @@ object SExpr { } } - /** When we fetch a contract id from upstream we cannot crash in the upstream - * calls. Rather, we set the control to this expression and then crash when executing. + /** We cannot crash in the engine call back. + * Rather, we set the control to this expression and then crash when executing. */ - final case class SEWronglyTypeContractId( - acoid: V.ContractId, - expected: TypeConName, - actual: TypeConName, - ) extends SExpr { + final case class SEDamlException(error: SErrorDamlException) extends SExpr { def execute(machine: Machine): Unit = { - throw DamlEWronglyTypedContract(acoid, expected, actual) + throw error } } diff --git a/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/Speedy.scala b/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/Speedy.scala index 0240b397a3d..f4015ceea4d 100644 --- a/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/Speedy.scala +++ b/daml-lf/interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/Speedy.scala @@ -15,7 +15,7 @@ import com.daml.lf.speedy.SExpr._ import com.daml.lf.speedy.SResult._ import com.daml.lf.speedy.SValue._ import com.daml.lf.transaction.{TransactionVersion, TransactionVersions} -import com.daml.lf.value.{Value => V} +import com.daml.lf.value.{ValueVersion, ValueVersions, Value => V} import org.slf4j.LoggerFactory import scala.collection.JavaConverters._ @@ -98,8 +98,10 @@ private[lf] object Speedy { /** The speedy CEK machine. */ final class Machine( + /* Transaction versions that the machine can read */ + val inputValueVersions: VersionRange[ValueVersion], /* Transaction versions that the machine can output */ - val outputTransactionVersions: VersionRange[transaction.TransactionVersion], + val outputTransactionVersions: VersionRange[TransactionVersion], /* Whether the current submission is validating the transaction, or interpreting * it. If this is false, the committers must be a singleton set. */ @@ -550,7 +552,6 @@ private[lf] object Speedy { // to speedy value and set the control of with the result. // All the contract IDs contained in the value are considered global. // Raises an exception if missing a package. - private[speedy] def importValue(value: V[V.ContractId]): Unit = { def go(value0: V[V.ContractId]): SValue = value0 match { @@ -658,10 +659,12 @@ private[lf] object Speedy { expr: SExpr, globalCids: Set[V.ContractId], committers: Set[Party], - outputTransactionVersions: VersionRange[transaction.TransactionVersion], + inputValueVersions: VersionRange[ValueVersion], + outputTransactionVersions: VersionRange[TransactionVersion], validating: Boolean = false, ): Machine = new Machine( + inputValueVersions = inputValueVersions, outputTransactionVersions = outputTransactionVersions, validating = validating, ctrl = expr, @@ -693,6 +696,7 @@ private[lf] object Speedy { compiledPackages: CompiledPackages, transactionSeed: crypto.Hash, scenario: SExpr, + inputValueVersions: VersionRange[ValueVersion], outputTransactionVersions: VersionRange[TransactionVersion], ): Machine = Machine( compiledPackages = compiledPackages, @@ -701,6 +705,7 @@ private[lf] object Speedy { expr = SEApp(scenario, Array(SEValue.Token)), globalCids = Set.empty, committers = Set.empty, + inputValueVersions: VersionRange[ValueVersion], outputTransactionVersions = outputTransactionVersions, ) @@ -711,12 +716,14 @@ private[lf] object Speedy { compiledPackages: CompiledPackages, transactionSeed: crypto.Hash, scenario: Expr, + inputValueVersions: VersionRange[ValueVersion], outputTransactionVersions: VersionRange[TransactionVersion], ): Machine = fromScenarioSExpr( compiledPackages = compiledPackages, transactionSeed = transactionSeed, scenario = compiledPackages.compiler.unsafeCompile(scenario), + inputValueVersions = inputValueVersions, outputTransactionVersions = outputTransactionVersions, ) @@ -734,7 +741,8 @@ private[lf] object Speedy { expr = expr, globalCids = Set.empty, committers = Set.empty, - outputTransactionVersions = TransactionVersions.SupportedDevOutputVersions, + inputValueVersions = ValueVersions.Empty, + outputTransactionVersions = TransactionVersions.Empty, ) @throws[PackageNotFound] diff --git a/daml-lf/repl/src/main/scala/com/digitalasset/daml/lf/repl/testing/Main.scala b/daml-lf/repl/src/main/scala/com/digitalasset/daml/lf/repl/testing/Main.scala index b42775adcda..3a88894a2a0 100644 --- a/daml-lf/repl/src/main/scala/com/digitalasset/daml/lf/repl/testing/Main.scala +++ b/daml-lf/repl/src/main/scala/com/digitalasset/daml/lf/repl/testing/Main.scala @@ -22,7 +22,6 @@ import java.io.{File, PrintWriter, StringWriter} import java.nio.file.{Path, Paths} import java.io.PrintStream -import com.daml.lf.transaction.TransactionVersions import org.jline.builtins.Completers import org.jline.reader.{History, LineReader, LineReaderBuilder} import org.jline.reader.impl.completer.{AggregateCompleter, ArgumentCompleter, StringsCompleter} @@ -185,11 +184,17 @@ object Repl { private val seed = nextSeed() - val txVersions = + val (inputValueVersion, outputTransactionVersions) = if (devMode) - TransactionVersions.SupportedDevOutputVersions + ( + value.ValueVersions.DevOutputVersions, + transaction.TransactionVersions.DevOutputVersions + ) else - TransactionVersions.SupportedStableOutputVersions + ( + value.ValueVersions.StableOutputVersions, + transaction.TransactionVersions.StableOutputVersions, + ) def run(expr: Expr): ( Speedy.Machine, @@ -199,7 +204,8 @@ object Repl { compiledPackages, seed, expr, - txVersions, + inputValueVersion, + outputTransactionVersions, ) (machine, ScenarioRunner(machine).run()) } diff --git a/daml-lf/scenario-interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/ScenarioRunner.scala b/daml-lf/scenario-interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/ScenarioRunner.scala index db3dbff5915..1936c803a8f 100644 --- a/daml-lf/scenario-interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/ScenarioRunner.scala +++ b/daml-lf/scenario-interpreter/src/main/scala/com/digitalasset/daml/lf/speedy/ScenarioRunner.scala @@ -277,7 +277,8 @@ object ScenarioRunner { engine.compiledPackages(), transactionSeed, scenarioExpr, - engine.config.outputTransactionVersions, + engine.config.allowedInputValueVersions, + engine.config.allowedOutputTransactionVersions, ) ScenarioRunner(speedyMachine).run() match { case Left(e) => diff --git a/daml-lf/scenario-interpreter/src/perf/benches/scala/com/digitalasset/daml/lf/speedy/perf/CollectAuthority.scala b/daml-lf/scenario-interpreter/src/perf/benches/scala/com/digitalasset/daml/lf/speedy/perf/CollectAuthority.scala index 63aba37d18d..466b50c304a 100644 --- a/daml-lf/scenario-interpreter/src/perf/benches/scala/com/digitalasset/daml/lf/speedy/perf/CollectAuthority.scala +++ b/daml-lf/scenario-interpreter/src/perf/benches/scala/com/digitalasset/daml/lf/speedy/perf/CollectAuthority.scala @@ -18,7 +18,6 @@ import com.daml.lf.speedy.Speedy.Machine import java.io.File import java.util.concurrent.TimeUnit -import com.daml.lf.transaction.TransactionVersions import org.openjdk.jmh.annotations._ class CollectAuthority { @@ -57,7 +56,8 @@ class CollectAuthorityState { compiledPackages, seeding(), expr, - TransactionVersions.SupportedDevOutputVersions, + value.ValueVersions.DevOutputVersions, + transaction.TransactionVersions.DevOutputVersions, ) the_sexpr = machine.ctrl diff --git a/daml-lf/scenario-interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/ScenarioRunnerTest.scala b/daml-lf/scenario-interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/ScenarioRunnerTest.scala index aa28de0d3c6..c0329ef5460 100644 --- a/daml-lf/scenario-interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/ScenarioRunnerTest.scala +++ b/daml-lf/scenario-interpreter/src/test/scala/com/digitalasset/daml/lf/speedy/ScenarioRunnerTest.scala @@ -1,14 +1,13 @@ // Copyright (c) 2020 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. // SPDX-License-Identifier: Apache-2.0 -package com.daml.lf +package com.daml +package lf package speedy import com.daml.lf.data.Ref import com.daml.lf.language.Ast -import com.daml.lf.language.Ast.ScenarioGetParty -import com.daml.lf.transaction.TransactionVersions -import org.scalatest._ +import org.scalatest.{AsyncWordSpec, Matchers} import org.scalatest.concurrent.ScalaFutures class ScenarioRunnerTest extends AsyncWordSpec with Matchers with ScalaFutures { @@ -16,13 +15,14 @@ class ScenarioRunnerTest extends AsyncWordSpec with Matchers with ScalaFutures { "ScenarioRunner" can { "mangle party names correctly" in { val compiledPackages = PureCompiledPackages(Map.empty).right.get - val e = Ast.EScenario(ScenarioGetParty(Ast.EPrimLit(Ast.PLText(("foo-bar"))))) + val e = Ast.EScenario(Ast.ScenarioGetParty(Ast.EPrimLit(Ast.PLText("foo-bar")))) val txSeed = crypto.Hash.hashPrivateKey("ScenarioRunnerTest") val m = Speedy.Machine.fromScenarioExpr( compiledPackages, txSeed, e, - TransactionVersions.SupportedDevOutputVersions, + lf.value.ValueVersions.DevOutputVersions, + transaction.TransactionVersions.DevOutputVersions, ) val sr = ScenarioRunner(m, _ + "-XXX") sr.run() match { diff --git a/daml-lf/transaction-test-lib/src/main/scala/lf/transaction/test/TransactionBuilder.scala b/daml-lf/transaction-test-lib/src/main/scala/lf/transaction/test/TransactionBuilder.scala index bdb2e229134..df8e30bf4ac 100644 --- a/daml-lf/transaction-test-lib/src/main/scala/lf/transaction/test/TransactionBuilder.scala +++ b/daml-lf/transaction-test-lib/src/main/scala/lf/transaction/test/TransactionBuilder.scala @@ -62,9 +62,7 @@ final class TransactionBuilder(pkgTxVersion: Ref.PackageId => TransactionVersion .toSeq val txVersion = VersionTimeline - .latestWhenAllPresent( - TransactionVersions.SupportedStableOutputVersions.min, - nodesVersions: _*) + .latestWhenAllPresent(TransactionVersions.StableOutputVersions.min, nodesVersions: _*) VersionedTransaction(txVersion, GenTransaction(nodes.result(), roots.result())) } @@ -80,7 +78,7 @@ final class TransactionBuilder(pkgTxVersion: Ref.PackageId => TransactionVersion private[this] def pkgValVersion(pkgId: Ref.PackageId) = { import VersionTimeline.Implicits._ VersionTimeline.latestWhenAllPresent( - ValueVersions.SupportedStableVersions.min, + ValueVersions.StableOutputVersions.min, pkgTxVersion(pkgId)) } @@ -124,7 +122,7 @@ object TransactionBuilder { private val KeyWithMaintainers = transaction.Node.KeyWithMaintainers def apply(): TransactionBuilder = - TransactionBuilder(TransactionVersions.SupportedStableOutputVersions.min) + TransactionBuilder(TransactionVersions.StableOutputVersions.min) def apply(txVersion: TransactionVersion): TransactionBuilder = new TransactionBuilder(_ => txVersion) @@ -133,7 +131,7 @@ object TransactionBuilder { def pkgTxVersion(pkgId: Ref.PackageId) = { import VersionTimeline.Implicits._ VersionTimeline.latestWhenAllPresent( - TransactionVersions.SupportedStableOutputVersions.min, + TransactionVersions.StableOutputVersions.min, pkgLangVersion(pkgId) ) } @@ -240,7 +238,7 @@ object TransactionBuilder { // not valid transactions. val Empty: Tx.Transaction = VersionedTransaction( - TransactionVersions.SupportedStableOutputVersions.min, + TransactionVersions.StableOutputVersions.min, GenTransaction(HashMap.empty, ImmArray.empty), ) val EmptySubmitted: SubmittedTransaction = SubmittedTransaction(Empty) diff --git a/daml-lf/transaction/src/main/scala/com/digitalasset/daml/lf/transaction/TransactionVersion.scala b/daml-lf/transaction/src/main/scala/com/digitalasset/daml/lf/transaction/TransactionVersion.scala index 50de7c7ca18..c8406654f95 100644 --- a/daml-lf/transaction/src/main/scala/com/digitalasset/daml/lf/transaction/TransactionVersion.scala +++ b/daml-lf/transaction/src/main/scala/com/digitalasset/daml/lf/transaction/TransactionVersion.scala @@ -34,16 +34,18 @@ private[lf] object TransactionVersions private[transaction] val minContractKeyInFetch = TransactionVersion("10") // Older versions are deprecated https://github.com/digital-asset/daml/issues/5220 - // We force output of recent version, but keep reading older version as long as - // Sandbox is alive. - val SupportedStableOutputVersions = + val StableOutputVersions: VersionRange[TransactionVersion] = VersionRange(TransactionVersion("10"), TransactionVersion("10")) - val SupportedDevOutputVersions = SupportedStableOutputVersions.copy(max = acceptedVersions.last) + val DevOutputVersions: VersionRange[TransactionVersion] = + StableOutputVersions.copy(max = acceptedVersions.last) + + val Empty: VersionRange[TransactionVersion] = + VersionRange(acceptedVersions.last, acceptedVersions.head) def assignVersion( a: GenTransaction.WithTxValue[_, Value.ContractId], - supportedVersions: VersionRange[TransactionVersion] = SupportedDevOutputVersions, + supportedVersions: VersionRange[TransactionVersion] = DevOutputVersions, ): Either[String, TransactionVersion] = { require(a != null) import VersionTimeline.Implicits._ @@ -118,7 +120,7 @@ private[lf] object TransactionVersions def asVersionedTransaction( tx: GenTransaction.WithTxValue[NodeId, Value.ContractId], - supportedVersions: VersionRange[TransactionVersion] = SupportedDevOutputVersions, + supportedVersions: VersionRange[TransactionVersion] = DevOutputVersions, ): Either[String, Transaction.Transaction] = for { v <- assignVersion(tx, supportedVersions) @@ -127,13 +129,13 @@ private[lf] object TransactionVersions @throws[IllegalArgumentException] def assertAsVersionedTransaction( tx: GenTransaction.WithTxValue[NodeId, Value.ContractId], - supportedVersions: VersionRange[TransactionVersion] = SupportedDevOutputVersions, + supportedVersions: VersionRange[TransactionVersion] = DevOutputVersions, ): Transaction.Transaction = data.assertRight(asVersionedTransaction(tx, supportedVersions)) private[lf] def assignValueVersion(transactionVersion: TransactionVersion): ValueVersion = latestWhenAllPresent( - ValueVersions.SupportedStableVersions.min, + ValueVersions.acceptedVersions.head, transactionVersion, ) @@ -145,7 +147,7 @@ private[lf] object TransactionVersions val transactionVersion = VersionTimeline.latestWhenAllPresent( supportedTxVersions.min, - (SupportedStableOutputVersions.min: SpecifiedVersion) +: as: _*, + (DevOutputVersions.min: SpecifiedVersion) +: as: _*, ) Either.cond( diff --git a/daml-lf/transaction/src/main/scala/com/digitalasset/daml/lf/transaction/VersionRange.scala b/daml-lf/transaction/src/main/scala/com/digitalasset/daml/lf/transaction/VersionRange.scala index baaab9a4ade..2f314b51cfc 100644 --- a/daml-lf/transaction/src/main/scala/com/digitalasset/daml/lf/transaction/VersionRange.scala +++ b/daml-lf/transaction/src/main/scala/com/digitalasset/daml/lf/transaction/VersionRange.scala @@ -8,7 +8,7 @@ import com.daml.lf.transaction.VersionTimeline final case class VersionRange[V]( min: V, max: V, -) { +)(implicit ev: VersionTimeline.SubVersion[V]) { import VersionTimeline._ import VersionTimeline.Implicits._ @@ -19,13 +19,10 @@ final case class VersionRange[V]( max = minVersion(this.max, that.max) ) - def nonEmpty(implicit ev: VersionTimeline.SubVersion[V]): Boolean = + def nonEmpty: Boolean = !(max precedes min) - def contains(v: V)(implicit ev: VersionTimeline.SubVersion[V]): Boolean = + def contains(v: V): Boolean = !((max precedes v) || (v precedes min)) - def map[W](f: V => W): VersionRange[W] = - VersionRange(f(min), f(max)) - } diff --git a/daml-lf/transaction/src/main/scala/com/digitalasset/daml/lf/value/ValueCoder.scala b/daml-lf/transaction/src/main/scala/com/digitalasset/daml/lf/value/ValueCoder.scala index f19e6ab760b..29e64dee31b 100644 --- a/daml-lf/transaction/src/main/scala/com/digitalasset/daml/lf/value/ValueCoder.scala +++ b/daml-lf/transaction/src/main/scala/com/digitalasset/daml/lf/value/ValueCoder.scala @@ -546,7 +546,7 @@ object ValueCoder { private[value] def valueToBytes[Cid]( encodeCid: EncodeCid[Cid], v: Value[Cid], - supportedVersions: VersionRange[ValueVersion] = ValueVersions.SupportedDevVersions, + supportedVersions: VersionRange[ValueVersion] = ValueVersions.DevOutputVersions, ): Either[EncodeError, Array[Byte]] = encodeVersionedValue(encodeCid, v, supportedVersions).map(_.toByteArray) diff --git a/daml-lf/transaction/src/main/scala/com/digitalasset/daml/lf/value/ValueVersion.scala b/daml-lf/transaction/src/main/scala/com/digitalasset/daml/lf/value/ValueVersion.scala index 87a78db2d87..8b8adb483a8 100644 --- a/daml-lf/transaction/src/main/scala/com/digitalasset/daml/lf/value/ValueVersion.scala +++ b/daml-lf/transaction/src/main/scala/com/digitalasset/daml/lf/value/ValueVersion.scala @@ -30,15 +30,19 @@ private[lf] object ValueVersions private[value] val minContractIdV1 = ValueVersion("7") // Older versions are deprecated https://github.com/digital-asset/daml/issues/5220 - // We force output of recent version, but keep reading older version as long as - // Sandbox is alive. - val SupportedStableVersions = VersionRange(ValueVersion("6"), ValueVersion("6")) + val StableOutputVersions: VersionRange[ValueVersion] = + VersionRange(ValueVersion("6"), ValueVersion("6")) - val SupportedDevVersions = SupportedStableVersions.copy(max = acceptedVersions.last) + val DevOutputVersions: VersionRange[ValueVersion] = + StableOutputVersions.copy(max = acceptedVersions.last) + + // Empty range + val Empty: VersionRange[ValueVersion] = + VersionRange(acceptedVersions.last, acceptedVersions.head) def assignVersion[Cid]( v0: Value[Cid], - supportedVersions: VersionRange[ValueVersion] = SupportedDevVersions, + supportedVersions: VersionRange[ValueVersion] = StableOutputVersions, ): Either[String, ValueVersion] = { import VersionTimeline.{maxVersion => maxVV} import VersionTimeline.Implicits._ @@ -98,20 +102,20 @@ private[lf] object ValueVersions @throws[IllegalArgumentException] def assertAssignVersion[Cid]( v0: Value[Cid], - supportedVersions: VersionRange[ValueVersion] = SupportedDevVersions, + supportedVersions: VersionRange[ValueVersion] = DevOutputVersions, ): ValueVersion = data.assertRight(assignVersion(v0, supportedVersions)) def asVersionedValue[Cid]( value: Value[Cid], - supportedVersions: VersionRange[ValueVersion] = SupportedDevVersions, + supportedVersions: VersionRange[ValueVersion] = DevOutputVersions, ): Either[String, VersionedValue[Cid]] = assignVersion(value, supportedVersions).map(VersionedValue(_, value)) @throws[IllegalArgumentException] def assertAsVersionedValue[Cid]( value: Value[Cid], - supportedVersions: VersionRange[ValueVersion] = SupportedDevVersions, + supportedVersions: VersionRange[ValueVersion] = DevOutputVersions, ): VersionedValue[Cid] = data.assertRight(asVersionedValue(value, supportedVersions)) } diff --git a/daml-lf/transaction/src/test/scala/com/digitalasset/daml/lf/transaction/TransactionVersionSpec.scala b/daml-lf/transaction/src/test/scala/com/digitalasset/daml/lf/transaction/TransactionVersionSpec.scala index e6d82f5fa2c..d6e582f3274 100644 --- a/daml-lf/transaction/src/test/scala/com/digitalasset/daml/lf/transaction/TransactionVersionSpec.scala +++ b/daml-lf/transaction/src/test/scala/com/digitalasset/daml/lf/transaction/TransactionVersionSpec.scala @@ -19,9 +19,9 @@ class TransactionVersionSpec extends WordSpec with Matchers with TableDrivenProp import VersionTimeline.maxVersion private[this] val supportedValVersions = - ValueVersions.SupportedDevVersions.copy(min = ValueVersion("1")) + ValueVersions.DevOutputVersions.copy(min = ValueVersion("1")) private[this] val supportedTxVersions = - TransactionVersions.SupportedDevOutputVersions.copy(min = TransactionVersion("1")) + TransactionVersions.DevOutputVersions.copy(min = TransactionVersion("1")) "assignVersion" should { "prefer picking an older version" in { @@ -139,6 +139,18 @@ class TransactionVersionSpec extends WordSpec with Matchers with TableDrivenProp } } + "ValueVersions.Empty" should { + "be empty" in { + ValueVersions.Empty.nonEmpty shouldBe false + } + } + + "TransactionVersions.Empty" should { + "be empty" in { + TransactionVersions.Empty.nonEmpty shouldBe false + } + } + private[this] def assignValueVersions[Nid, Cid <: ContractId]( t: GenTransaction[Nid, Cid, Value[Cid]], ): GenTransaction[Nid, Cid, VersionedValue[Cid]] = diff --git a/daml-script/runner/src/main/scala/com/digitalasset/daml/lf/engine/script/LedgerInteraction.scala b/daml-script/runner/src/main/scala/com/digitalasset/daml/lf/engine/script/LedgerInteraction.scala index 09bffdb40ef..7a8091f60bb 100644 --- a/daml-script/runner/src/main/scala/com/digitalasset/daml/lf/engine/script/LedgerInteraction.scala +++ b/daml-script/runner/src/main/scala/com/digitalasset/daml/lf/engine/script/LedgerInteraction.scala @@ -1,7 +1,9 @@ // Copyright (c) 2020 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. // SPDX-License-Identifier: Apache-2.0 -package com.daml.lf.engine.script +package com.daml.lf +package engine +package script import akka.actor.ActorSystem import akka.http.scaladsl.Http @@ -27,16 +29,12 @@ import spray.json._ import com.daml.api.util.TimestampConversion import com.daml.grpc.adapter.ExecutionSequencerFactory import com.daml.grpc.adapter.client.akka.ClientAdapter -import com.daml.lf.CompiledPackages import com.daml.lf.scenario.ScenarioLedger -import com.daml.lf.crypto import com.daml.lf.data.Ref._ import com.daml.lf.data.{Ref, ImmArray} import com.daml.lf.data.{Time} import com.daml.lf.iface.{EnvironmentInterface, InterfaceType} import com.daml.lf.language.Ast._ -import com.daml.lf.speedy -import com.daml.lf.speedy.{InitialSeeding, PartialTransaction} import com.daml.lf.transaction.Node.{NodeCreate, NodeExercises} import com.daml.lf.speedy.ScenarioRunner import com.daml.lf.speedy.Speedy.Machine @@ -321,12 +319,23 @@ class GrpcLedgerClient(val grpcClient: LedgerClient, val applicationId: Applicat // Client for the script service. class IdeClient(val compiledPackages: CompiledPackages) extends ScriptLedgerClient { + private val txSeeding = + speedy.InitialSeeding.TransactionSeed(crypto.Hash.hashPrivateKey(s"script-service")) + // Machine for scenario expressions. - val machine = Machine.fromPureSExpr(compiledPackages, SEValue(SUnit)) + val machine = Machine( + compiledPackages, + submissionTime = Time.Timestamp.Epoch, + initialSeeding = txSeeding, + expr = null, + globalCids = Set.empty, + committers = Set.empty, + inputValueVersions = value.ValueVersions.DevOutputVersions, + outputTransactionVersions = transaction.TransactionVersions.DevOutputVersions, + ) + (compiledPackages, SEValue(SUnit)) val scenarioRunner = ScenarioRunner(machine) - private val txSeeding = crypto.Hash.hashPrivateKey(s"script-service") - machine.ptx = - PartialTransaction.initial(Time.Timestamp.MinValue, InitialSeeding.TransactionSeed(txSeeding)) + override def query(party: SParty, templateId: Identifier)( implicit ec: ExecutionContext, mat: Materializer): Future[Seq[ScriptLedgerClient.ActiveContract]] = { diff --git a/ledger/participant-integration-api/src/main/scala/platform/apiserver/ApiServices.scala b/ledger/participant-integration-api/src/main/scala/platform/apiserver/ApiServices.scala index 8c2de7270cb..18681ee22dd 100644 --- a/ledger/participant-integration-api/src/main/scala/platform/apiserver/ApiServices.scala +++ b/ledger/participant-integration-api/src/main/scala/platform/apiserver/ApiServices.scala @@ -123,7 +123,7 @@ private[daml] object ApiServices { private def createServices(ledgerId: LedgerId, ledgerConfigProvider: LedgerConfigProvider)( implicit executionContext: ExecutionContext): List[BindableService] = { - logger.info(engine.info.show) + engine.info.pretty.foreach(logger.info(_)) val apiTransactionService = ApiTransactionService.create(ledgerId, transactionsService)