Drop v0 contract ids (#12464)

* Drop v0 contract ids

changelog_begin
changelog_end

* .

changelog_begin
changelog_end
This commit is contained in:
Moritz Kiefer 2022-01-20 16:28:27 +01:00 committed by GitHub
parent c35d34db3d
commit 688f1e1e0b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
65 changed files with 514 additions and 521 deletions

View File

@ -60,7 +60,6 @@ class Engine(val config: EngineConfig = Engine.StableConfig) {
private[engine] val preprocessor =
new preprocessing.Preprocessor(
compiledPackages = compiledPackages,
forbidV0ContractId = config.forbidV0ContractId,
requireV1ContractIdSuffix = config.requireSuffixedGlobalContractId,
)

View File

@ -115,10 +115,6 @@ object Error {
sealed abstract class Reason extends Serializable with Product {
def details: String
}
case object V0ContractId extends Reason {
def details = "V0 Contract IDs are forbidden"
def apply(cid: Value.ContractId.V0): IllegalContractId = IllegalContractId(cid, this)
}
case object NonSuffixV1ContractId extends Reason {
def details = "non-suffixed V1 Contract IDs are forbidden"
def apply(cid: Value.ContractId.V1): IllegalContractId = IllegalContractId(cid, this)

View File

@ -14,15 +14,12 @@ import scala.annotation.tailrec
private[lf] final class CommandPreprocessor(
interface: language.PackageInterface,
// See Preprocessor scala doc for more details about the following flags.
forbidV0ContractId: Boolean,
requireV1ContractIdSuffix: Boolean,
) {
val valueTranslator =
new ValueTranslator(
interface = interface,
forbidV0ContractId = forbidV0ContractId,
requireV1ContractIdSuffix = requireV1ContractIdSuffix,
)

View File

@ -31,16 +31,12 @@ import scala.annotation.tailrec
* Daml-LF package definitions against the command should
* resolved/typechecked. It is updated dynamically each time the
* [[ResultNeedPackage]] continuation is called.
* @param forbidV0ContractId when `true` the preprocessor will reject
* any value/command/transaction that contains V0 Contract IDs
* without suffixed.
* @param requireV1ContractIdSuffix when `true` the preprocessor will reject
* any value/command/transaction that contains V1 Contract IDs
* without suffixed.
*/
private[engine] final class Preprocessor(
compiledPackages: MutableCompiledPackages,
forbidV0ContractId: Boolean = true,
requireV1ContractIdSuffix: Boolean = true,
) {
@ -51,7 +47,6 @@ private[engine] final class Preprocessor(
val commandPreprocessor =
new CommandPreprocessor(
interface = interface,
forbidV0ContractId = forbidV0ContractId,
requireV1ContractIdSuffix = requireV1ContractIdSuffix,
)
val transactionPreprocessor = new TransactionPreprocessor(commandPreprocessor)

View File

@ -16,8 +16,6 @@ import scala.annotation.tailrec
private[lf] final class ValueTranslator(
interface: language.PackageInterface,
// See Preprocessor scala doc for more details about the following flags.
forbidV0ContractId: Boolean,
requireV1ContractIdSuffix: Boolean,
) {
@ -53,17 +51,10 @@ private[lf] final class ValueTranslator(
else
SValue.SContractId(_)
private[this] val unsafeTranslateV0Cid: ContractId.V0 => SValue.SContractId =
if (forbidV0ContractId)
cid => throw Error.Preprocessing.IllegalContractId.V0ContractId(cid)
else
SValue.SContractId(_)
@throws[Error.Preprocessing.Error]
private[preprocessing] def unsafeTranslateCid(cid: ContractId): SValue.SContractId =
cid match {
case cid1: ContractId.V1 => unsafeTranslateV1Cid(cid1)
case cid0: ContractId.V0 => unsafeTranslateV0Cid(cid0)
}
// For efficient reason we do not produce here the monad Result[SValue] but rather throw

View File

@ -72,7 +72,8 @@ class CommandPreprocessorSpec
"preprocessCommand" should {
val defaultPreprocessor = new CommandPreprocessor(compiledPackage.interface, true, false)
val defaultPreprocessor =
new CommandPreprocessor(compiledPackage.interface, requireV1ContractIdSuffix = false)
"reject improperly typed commands" in {
@ -233,7 +234,6 @@ class CommandPreprocessorSpec
val cmdPreprocessor = new CommandPreprocessor(
compiledPackage.interface,
forbidV0ContractId = false,
requireV1ContractIdSuffix = false,
)
@ -245,7 +245,6 @@ class CommandPreprocessorSpec
),
ContractId.V1
.assertBuild(crypto.Hash.hashPrivateKey("a non-suffixed V1 Contract ID"), Bytes.Empty),
ContractId.V0.assertFromString("#a V0 Contract ID"),
)
cids.foreach(cid =>
@ -256,35 +255,10 @@ class CommandPreprocessorSpec
}
"reject V0 Contract IDs when requireV1ContractId flag is true" in {
val cmdPreprocessor = new CommandPreprocessor(
compiledPackage.interface,
forbidV0ContractId = true,
requireV1ContractIdSuffix = false,
)
val List(aLegalCid, anotherLegalCid) =
List("a legal Contract ID", "another legal Contract ID").map(s =>
ContractId.V1.assertBuild(crypto.Hash.hashPrivateKey(s), Bytes.assertFromString("00"))
)
val illegalCid = ContractId.V0.assertFromString("#illegal Contract ID")
val failure = Failure(Error.Preprocessing.IllegalContractId.V0ContractId(illegalCid))
forEvery(contractIdTestCases(aLegalCid, anotherLegalCid))(cmd =>
Try(cmdPreprocessor.unsafePreprocessCommand(cmd)) shouldBe a[Success[_]]
)
forEvery(contractIdTestCases(illegalCid, aLegalCid))(cmd =>
Try(cmdPreprocessor.unsafePreprocessCommand(cmd)) shouldBe failure
)
}
"reject non suffixed V1 Contract IDs when requireV1ContractIdSuffix is true" in {
val cmdPreprocessor = new CommandPreprocessor(
compiledPackage.interface,
forbidV0ContractId = true,
requireV1ContractIdSuffix = true,
)
val List(aLegalCid, anotherLegalCid) =

View File

@ -4,6 +4,7 @@
package com.daml.lf
package engine
import com.daml.lf.crypto.Hash
import com.daml.lf.data._
import com.daml.lf.language.Ast.{TNat, TTyCon, Type}
import com.daml.lf.language.Util._
@ -23,6 +24,8 @@ class ValueEnricherSpec extends AnyWordSpec with Matchers with TableDrivenProper
private[this] implicit val defaultPackageId: Ref.PackageId =
defaultParserParameters.defaultPackageId
private def cid(key: String): ContractId = ContractId.V1(Hash.hashPrivateKey(key))
val pkg =
p"""
module Mod {
@ -90,8 +93,8 @@ class ValueEnricherSpec extends AnyWordSpec with Matchers with TableDrivenProper
(TParty, ValueParty("Alice"), ValueParty("Alice")),
(
TContractId(TTyCon("Mod:Record")),
ValueContractId("#contractId"),
ValueContractId("#contractId"),
ValueContractId(cid("#contractId").coid),
ValueContractId(cid("#contractId").coid),
),
(
TList(TText),
@ -138,7 +141,7 @@ class ValueEnricherSpec extends AnyWordSpec with Matchers with TableDrivenProper
val builder = new TransactionBuilder(_ => TransactionVersion.minTypeErasure)
val create =
builder.create(
id = "#01",
id = cid("#01"),
templateId = "Mod:Contract",
argument = contract,
signatories = Set("Alice"),

View File

@ -64,7 +64,6 @@ class ValueTranslatorSpec
val valueTranslator = new ValueTranslator(
compiledPackage.interface,
forbidV0ContractId = true,
requireV1ContractIdSuffix = false,
)
import valueTranslator.unsafeTranslateValue
@ -246,7 +245,6 @@ class ValueTranslatorSpec
val valueTranslator = new ValueTranslator(
compiledPackage.interface,
forbidV0ContractId = false,
requireV1ContractIdSuffix = false,
)
val cids = List(
@ -257,7 +255,6 @@ class ValueTranslatorSpec
),
ContractId.V1
.assertBuild(crypto.Hash.hashPrivateKey("a non-suffixed V1 Contract ID"), Bytes.Empty),
ContractId.V0.assertFromString("#a V0 Contract ID"),
)
cids.foreach(cid =>
@ -267,35 +264,10 @@ class ValueTranslatorSpec
)
}
"reject V0 Contract IDs when requireV1ContractId flag is true" in {
val valueTranslator = new ValueTranslator(
compiledPackage.interface,
forbidV0ContractId = true,
requireV1ContractIdSuffix = false,
)
val legalCid =
ContractId.V1.assertBuild(
crypto.Hash.hashPrivateKey("a legal Contract ID"),
Bytes.assertFromString("00"),
)
val illegalCid =
ContractId.V0.assertFromString("#illegal Contract ID")
val failure = Failure(Error.Preprocessing.IllegalContractId.V0ContractId(illegalCid))
forEvery(testCasesForCid(legalCid))((typ, value) =>
Try(valueTranslator.unsafeTranslateValue(typ, value)) shouldBe a[Success[_]]
)
forEvery(testCasesForCid(illegalCid))((typ, value) =>
Try(valueTranslator.unsafeTranslateValue(typ, value)) shouldBe failure
)
}
"reject non suffixed V1 Contract IDs when requireV1ContractIdSuffix is true" in {
val valueTranslator = new ValueTranslator(
compiledPackage.interface,
forbidV0ContractId = true,
requireV1ContractIdSuffix = true,
)
val legalCid =

View File

@ -107,17 +107,7 @@ object Ordering extends scala.math.Ordering[SValue] {
}
@inline
private[this] def compareCid(cid1: ContractId, cid2: ContractId): Int = {
// Note that the engine never produce V0 contract IDs directly
// (V0 contract ID scheme can only be "emulated" at commit using
// `com.daml.lf.transaction.LegacyTransactionCommitter`).
// So we can assume here that all V0 Contract IDs are global.
(cid1, cid2) match {
case (ContractId.V0(s1), ContractId.V0(s2)) =>
s1 compareTo s2
case (_: ContractId.V0, _: ContractId.V1) =>
-1
case (_: ContractId.V1, _: ContractId.V0) =>
+1
case (
cid1 @ ContractId.V1(discriminator1, suffix1),
cid2 @ ContractId.V1(discriminator2, suffix2),

View File

@ -5,6 +5,7 @@ package com.daml.lf
package speedy
import java.util
import com.daml.lf.crypto.Hash
import com.daml.lf.data._
import com.daml.lf.interpretation.{Error => IE}
import com.daml.lf.language.Ast._
@ -730,8 +731,8 @@ class SBuiltinTest extends AnyFreeSpec with Matchers with TableDrivenPropertyChe
"EQUAL @ContractId" - {
"works as expected" in {
val cid1 = SContractId(Value.ContractId.assertFromString("#contract1"))
val cid2 = SContractId(Value.ContractId.assertFromString("#contract2"))
val cid1 = SContractId(Value.ContractId.V1(Hash.hashPrivateKey("#contract1")))
val cid2 = SContractId(Value.ContractId.V1(Hash.hashPrivateKey("#contract2")))
evalApp(e"EQUAL @(ContractId Mod:T)", Array(cid1, cid1)) shouldBe Right(SBool(true))
evalApp(e"EQUAL @(ContractId Mod:T)", Array(cid1, cid2)) shouldBe Right(SBool(false))
}
@ -1298,19 +1299,21 @@ class SBuiltinTest extends AnyFreeSpec with Matchers with TableDrivenPropertyChe
"CONTRACT_ID_TO_TEXT" - {
"returns None on-ledger" in {
val f = """(\(c:(ContractId Mod:T)) -> CONTRACT_ID_TO_TEXT @Mod:T c)"""
val cid = Value.ContractId.V1(Hash.hashPrivateKey("abc"))
evalApp(
e"$f",
Array(SContractId(Value.ContractId.assertFromString("#abc"))),
Array(SContractId(cid)),
onLedger = true,
) shouldBe Right(SOptional(None))
}
"returns Some(abc) off-ledger" in {
val f = """(\(c:(ContractId Mod:T)) -> CONTRACT_ID_TO_TEXT @Mod:T c)"""
val cid = Value.ContractId.V1(Hash.hashPrivateKey("abc"))
evalApp(
e"$f",
Array(SContractId(Value.ContractId.assertFromString("#abc"))),
Array(SContractId(cid)),
onLedger = false,
) shouldBe Right(SOptional(Some(SText("#abc"))))
) shouldBe Right(SOptional(Some(SText(cid.coid))))
}
}

View File

@ -11,7 +11,7 @@ import com.daml.lf.speedy.SValue._
import com.daml.lf.speedy.SExpr.{SEApp, SEImportValue, SELocA, SEMakeClo}
import com.daml.lf.value.Value
import com.daml.lf.value.test.TypedValueGenerators.genAddend
import com.daml.lf.value.test.ValueGenerators.{cidV0Gen, comparableCoidsGen}
import com.daml.lf.value.test.ValueGenerators.{comparableCoidsGen, suffixedV1CidGen}
import com.daml.lf.PureCompiledPackages
import com.daml.lf.iface
import com.daml.lf.interpretation.Error.ContractIdComparability
@ -111,8 +111,7 @@ class OrderingSpec
// The tests are here as this is difficult to test outside daml-lf/interpreter.
"txn Value Ordering" should {
import Value.{ContractId => Cid}
// SContractId V1 ordering is nontotal so arbitrary generation of them is unsafe to use
implicit val cidArb: Arbitrary[Cid] = Arbitrary(cidV0Gen)
implicit val cidArb: Arbitrary[Cid] = Arbitrary(suffixedV1CidGen)
implicit val svalueOrd: Order[SValue] = Order fromScalaOrdering Ordering
implicit val cidOrd: Order[Cid] = svalueOrd contramap SContractId
val EmptyScope: Value.LookupVariantEnum = _ => None

View File

@ -31,7 +31,8 @@ import scala.jdk.CollectionConverters._
class TransactionConversionsSpec extends AnyWordSpec with Matchers {
import TransactionConversionsSpec._
import TransactionBuilder.Implicits._
private val cid = Value.ContractId.V1(crypto.Hash.hashPrivateKey("#id"))
"TransactionUtilsSpec" should {
"encodeTransaction" in {
@ -98,7 +99,7 @@ class TransactionConversionsSpec extends AnyWordSpec with Matchers {
"extractTransactionOutputs" should {
"return a single output for a create without a key" in {
val builder = TransactionBuilder()
val createNode = create(builder, "#id")
val createNode = create(builder, cid)
builder.add(createNode)
val result = TransactionConversions.extractTransactionOutputs(
TransactionConversions
@ -110,7 +111,7 @@ class TransactionConversionsSpec extends AnyWordSpec with Matchers {
"return two outputs for a create with a key" in {
val builder = TransactionBuilder()
val createNode = create(builder, "#id", hasKey = true)
val createNode = create(builder, cid, hasKey = true)
builder.add(createNode)
val result = TransactionConversions.extractTransactionOutputs(
TransactionConversions
@ -127,9 +128,9 @@ class TransactionConversionsSpec extends AnyWordSpec with Matchers {
"return a single output for a transient contract" in {
val builder = TransactionBuilder()
val createNode = create(builder, "#id", hasKey = true)
val createNode = create(builder, cid, hasKey = true)
builder.add(createNode)
builder.add(exercise(builder, "#id"))
builder.add(exercise(builder, cid))
val result = TransactionConversions.extractTransactionOutputs(
TransactionConversions
.encodeTransaction(builder.build())
@ -145,7 +146,7 @@ class TransactionConversionsSpec extends AnyWordSpec with Matchers {
"return a single output for an exercise without a key" in {
val builder = TransactionBuilder()
val exerciseNode = exercise(builder, "#id")
val exerciseNode = exercise(builder, cid)
builder.add(exerciseNode)
val result = TransactionConversions.extractTransactionOutputs(
TransactionConversions
@ -157,7 +158,7 @@ class TransactionConversionsSpec extends AnyWordSpec with Matchers {
"return two outputs for a consuming exercise with a key" in {
val builder = TransactionBuilder()
val exerciseNode = exercise(builder, "#id", hasKey = true)
val exerciseNode = exercise(builder, cid, hasKey = true)
builder.add(exerciseNode)
val result = TransactionConversions.extractTransactionOutputs(
TransactionConversions
@ -174,7 +175,7 @@ class TransactionConversionsSpec extends AnyWordSpec with Matchers {
"return two outputs for a non-consuming exercise with a key" in {
val builder = TransactionBuilder()
val exerciseNode = exercise(builder, "#id", hasKey = true, consuming = false)
val exerciseNode = exercise(builder, cid, hasKey = true, consuming = false)
builder.add(exerciseNode)
val result = TransactionConversions.extractTransactionOutputs(
TransactionConversions
@ -191,8 +192,10 @@ class TransactionConversionsSpec extends AnyWordSpec with Matchers {
"return one output per fetch and fetch-by-key" in {
val builder = TransactionBuilder()
val fetchNode1 = fetch(builder, "#id1", byKey = true)
val fetchNode2 = fetch(builder, "#id2", byKey = false)
val fetchNode1 =
fetch(builder, Value.ContractId.V1(crypto.Hash.hashPrivateKey("#id1")), byKey = true)
val fetchNode2 =
fetch(builder, Value.ContractId.V1(crypto.Hash.hashPrivateKey("#id2")), byKey = false)
builder.add(fetchNode1)
builder.add(fetchNode2)
val result = TransactionConversions.extractTransactionOutputs(
@ -210,7 +213,7 @@ class TransactionConversionsSpec extends AnyWordSpec with Matchers {
"return no output for a failing lookup-by-key" in {
val builder = TransactionBuilder()
builder.add(lookup(builder, "#id", found = false))
builder.add(lookup(builder, cid, found = false))
val result = TransactionConversions.extractTransactionOutputs(
TransactionConversions
.encodeTransaction(builder.build())
@ -221,7 +224,7 @@ class TransactionConversionsSpec extends AnyWordSpec with Matchers {
"return no output for a successful lookup-by-key" in {
val builder = TransactionBuilder()
builder.add(lookup(builder, "#id", found = true))
builder.add(lookup(builder, cid, found = true))
val result = TransactionConversions.extractTransactionOutputs(
TransactionConversions
.encodeTransaction(builder.build())
@ -233,11 +236,14 @@ class TransactionConversionsSpec extends AnyWordSpec with Matchers {
"return outputs for nodes under a rollback node" in {
val builder = TransactionBuilder()
val rollback = builder.add(builder.rollback())
val createNode = create(builder, "#id1", hasKey = true)
val createNode =
create(builder, Value.ContractId.V1(crypto.Hash.hashPrivateKey("#id1")), hasKey = true)
builder.add(createNode, rollback)
val exerciseNode = exercise(builder, "#id2", hasKey = true)
val exerciseNode =
exercise(builder, Value.ContractId.V1(crypto.Hash.hashPrivateKey("#id2")), hasKey = true)
builder.add(exerciseNode, rollback)
val fetchNode = fetch(builder, "#id3", byKey = true)
val fetchNode =
fetch(builder, Value.ContractId.V1(crypto.Hash.hashPrivateKey("#id3")), byKey = true)
builder.add(fetchNode, rollback)
val result = TransactionConversions.extractTransactionOutputs(
TransactionConversions

View File

@ -390,7 +390,6 @@ object ScenarioRunner {
val valueTranslator =
new ValueTranslator(
interface = compiledPackages.interface,
forbidV0ContractId = config.forbidV0ContractId,
requireV1ContractIdSuffix = config.requireSuffixedGlobalContractId,
)
def translateValue(typ: Ast.Type, value: Value): Result[SValue] =

View File

@ -167,8 +167,6 @@ object ValueGenerators {
ab <- Gen.containerOfN[Array, Byte](sz, arbitrary[Byte])
} yield Bytes fromByteArray ab
val cidV0Gen: Gen[ContractId.V0] =
Gen.alphaStr.map(t => Value.ContractId.V0.assertFromString('#' +: t.take(254)))
private val cidV1Gen: Gen[ContractId.V1] =
Gen.zip(genHash, genSuffixes) map { case (h, b) =>
ContractId.V1.assertBuild(h, b)
@ -176,21 +174,19 @@ object ValueGenerators {
/** Universes of totally-ordered ContractIds. */
def comparableCoidsGen: Seq[Gen[ContractId]] =
Seq(
Gen.oneOf(
cidV0Gen,
Gen.zip(cidV1Gen, arbitrary[Byte]) map { case (b1, b) =>
ContractId.V1
.assertBuild(
b1.discriminator,
if (b1.suffix.nonEmpty) b1.suffix else Bytes fromByteArray Array(b),
)
},
),
Gen.oneOf(cidV0Gen, cidV1Gen map (cid => ContractId.V1(cid.discriminator))),
)
Seq(suffixedV1CidGen, nonSuffixedCidV1Gen)
def coidGen: Gen[ContractId] = Gen.oneOf(cidV0Gen, cidV1Gen)
def suffixedV1CidGen: Gen[ContractId] = Gen.zip(cidV1Gen, arbitrary[Byte]) map { case (b1, b) =>
ContractId.V1
.assertBuild(
b1.discriminator,
if (b1.suffix.nonEmpty) b1.suffix else Bytes fromByteArray Array(b),
)
}
def nonSuffixedCidV1Gen: Gen[ContractId] = cidV1Gen map (cid => ContractId.V1(cid.discriminator))
def coidGen: Gen[ContractId] = cidV1Gen
def coidValueGen: Gen[ValueContractId] =
coidGen.map(ValueContractId(_))

View File

@ -77,11 +77,8 @@ object Hash {
implicit val order: Order[Hash] = Order.fromScalaOrdering
private[lf] val aCid2Bytes: Value.ContractId => Bytes = {
case cid @ Value.ContractId.V1(_, _) =>
cid.toBytes
case Value.ContractId.V0(s) =>
Utf8.getBytes(s)
private[lf] val aCid2Bytes: Value.ContractId => Bytes = { case cid @ Value.ContractId.V1(_, _) =>
cid.toBytes
}
private[lf] val noCid2String: Value.ContractId => Nothing =

View File

@ -57,7 +57,6 @@ trait CidContainer[+A] {
case Value.ContractId.V1(discriminator, Bytes.Empty) =>
Value.ContractId.V1.build(discriminator, f(discriminator))
case acoid @ Value.ContractId.V1(_, _) => Right(acoid)
case acoid @ Value.ContractId.V0(_) => Right(acoid)
}
}

View File

@ -212,19 +212,6 @@ object Value {
}
object ContractId {
final case class V0(coid: Ref.ContractIdString) extends ContractId {
override def toString: String = s"ContractId($coid)"
}
object V0 {
def fromString(s: String): Either[String, V0] =
Ref.ContractIdString.fromString(s).map(V0(_))
def assertFromString(s: String): V0 = assertRight(fromString(s))
implicit val `V0 Order`: Order[V0] = Order.fromScalaOrdering[String] contramap (_.coid)
}
final case class V1 private (discriminator: crypto.Hash, suffix: Bytes)
extends ContractId
with data.NoCopy {
@ -280,8 +267,6 @@ object Value {
def fromString(s: String): Either[String, ContractId] =
V1.fromString(s)
.left
.flatMap(_ => V0.fromString(s))
.left
.map(_ => s"""cannot parse ContractId "$s"""")
@ -289,18 +274,13 @@ object Value {
assertRight(fromString(s))
implicit val `Cid Order`: Order[ContractId] = new Order[ContractId] {
import scalaz.Ordering._
override def order(a: ContractId, b: ContractId) =
(a, b) match {
case (a: V0, b: V0) => a ?|? b
case (a: V1, b: V1) => a ?|? b
case (_: V0, _: V1) => LT
case (_: V1, _: V0) => GT
}
override def equal(a: ContractId, b: ContractId) =
(a, b).match2 {
case a: V0 => { case b: V0 => a === b }
case V1(discA, suffA) => { case V1(discB, suffB) =>
discA == discB && suffA.toByteString == suffB.toByteString
}

View File

@ -5,6 +5,7 @@ package com.daml
package lf
package transaction
import com.daml.lf.crypto.Hash
import com.daml.lf.data.ImmArray
import com.daml.lf.data.Ref.{Identifier, Party}
import com.daml.lf.transaction.{TransactionOuterClass => proto}
@ -867,7 +868,7 @@ class TransactionCoderSpec
}
private def absCid(s: String): ContractId =
ContractId.assertFromString(s)
ContractId.V1(Hash.hashPrivateKey(s))
def versionNodes(
version: TransactionVersion,

View File

@ -4,6 +4,7 @@
package com.daml.lf
package transaction
import com.daml.lf.crypto.Hash
import com.daml.lf.data.{Bytes, ImmArray, Ref}
import com.daml.lf.transaction.Transaction.{
AliasedNode,
@ -41,7 +42,7 @@ class TransactionSpec
"detects dangling references in children" in {
val tx = mkTransaction(
HashMap(NodeId(1) -> dummyExerciseNode("#cid1", ImmArray(NodeId(2)))),
HashMap(NodeId(1) -> dummyExerciseNode(cid("#cid1"), ImmArray(NodeId(2)))),
ImmArray(NodeId(1)),
)
tx.isWellFormed shouldBe Set(NotWellFormedError(NodeId(2), DanglingNodeId))
@ -49,7 +50,7 @@ class TransactionSpec
"detects cycles" in {
val tx = mkTransaction(
HashMap(NodeId(1) -> dummyExerciseNode("#cid1", ImmArray(NodeId(1)))),
HashMap(NodeId(1) -> dummyExerciseNode(cid("#cid1"), ImmArray(NodeId(1)))),
ImmArray(NodeId(1)),
)
tx.isWellFormed shouldBe Set(NotWellFormedError(NodeId(1), AliasedNode))
@ -58,9 +59,9 @@ class TransactionSpec
"detects aliasing from roots and exercise" in {
val tx = mkTransaction(
HashMap(
NodeId(0) -> dummyExerciseNode("#cid0", ImmArray(NodeId(1))),
NodeId(1) -> dummyExerciseNode("#cid1", ImmArray(NodeId(2))),
NodeId(2) -> dummyCreateNode("#cid2"),
NodeId(0) -> dummyExerciseNode(cid("#cid0"), ImmArray(NodeId(1))),
NodeId(1) -> dummyExerciseNode(cid("#cid1"), ImmArray(NodeId(2))),
NodeId(2) -> dummyCreateNode(cid("#cid2")),
),
ImmArray(NodeId(0), NodeId(2)),
)
@ -68,7 +69,7 @@ class TransactionSpec
}
"detects orphans" in {
val tx = mkTransaction(HashMap(NodeId(1) -> dummyCreateNode("#cid1")), ImmArray.Empty)
val tx = mkTransaction(HashMap(NodeId(1) -> dummyCreateNode(cid("#cid1"))), ImmArray.Empty)
tx.isWellFormed shouldBe Set(NotWellFormedError(NodeId(1), OrphanedNode))
}
}
@ -78,9 +79,9 @@ class TransactionSpec
"collects contract IDs" in {
val tx = mkTransaction(
HashMap(
NodeId(0) -> dummyExerciseNode("#cid0", ImmArray(NodeId(1))),
NodeId(1) -> dummyExerciseNode("#cid1", ImmArray(NodeId(2))),
NodeId(2) -> dummyCreateNode("#cid2"),
NodeId(0) -> dummyExerciseNode(cid("#cid0"), ImmArray(NodeId(1))),
NodeId(1) -> dummyExerciseNode(cid("#cid1"), ImmArray(NodeId(2))),
NodeId(2) -> dummyCreateNode(cid("#cid2")),
),
ImmArray(NodeId(0), NodeId(2)),
)
@ -91,7 +92,12 @@ class TransactionSpec
cids.result()
}
collectCids(tx) shouldBe Set[V.ContractId]("#cid0", "#cid1", "#cid2", "#dummyCid")
collectCids(tx) shouldBe Set[V.ContractId](
cid("#cid0"),
cid("#cid1"),
cid("#cid2"),
cid("#dummyCid"),
)
}
@ -102,12 +108,12 @@ class TransactionSpec
val tx = mkTransaction(
HashMap(
NodeId(0) -> dummyCreateNode("#cid0"),
NodeId(1) -> dummyExerciseNode("#cid1", ImmArray(NodeId(2), NodeId(4))),
NodeId(2) -> dummyExerciseNode("#cid2", ImmArray.Empty),
NodeId(3) -> dummyCreateNode("#cid3"),
NodeId(0) -> dummyCreateNode(cid("#cid0")),
NodeId(1) -> dummyExerciseNode(cid("#cid1"), ImmArray(NodeId(2), NodeId(4))),
NodeId(2) -> dummyExerciseNode(cid("#cid2"), ImmArray.Empty),
NodeId(3) -> dummyCreateNode(cid("#cid3")),
NodeId(4) -> dummyRollbackNode(ImmArray(NodeId(5))),
NodeId(5) -> dummyCreateNode("#cid5"),
NodeId(5) -> dummyCreateNode(cid("#cid5")),
),
ImmArray(NodeId(0), NodeId(1), NodeId(3)),
)
@ -130,19 +136,19 @@ class TransactionSpec
val tx = mkTransaction(
HashMap(
NodeId(0) -> dummyCreateNode("#cid0"),
NodeId(1) -> dummyExerciseNode("#cid1", ImmArray(NodeId(2), NodeId(4))),
NodeId(2) -> dummyExerciseNode("#cid2", ImmArray.Empty),
NodeId(3) -> dummyCreateNode("#cid3"),
NodeId(0) -> dummyCreateNode(cid("#cid0")),
NodeId(1) -> dummyExerciseNode(cid("#cid1"), ImmArray(NodeId(2), NodeId(4))),
NodeId(2) -> dummyExerciseNode(cid("#cid2"), ImmArray.Empty),
NodeId(3) -> dummyCreateNode(cid("#cid3")),
NodeId(4) -> dummyRollbackNode(ImmArray(NodeId(5))),
NodeId(5) -> dummyCreateNode("#cid5"),
NodeId(5) -> dummyCreateNode(cid("#cid5")),
// these are not reachable
NodeId(10) -> dummyCreateNode("#cid10"),
NodeId(11) -> dummyExerciseNode("#cid11", ImmArray(NodeId(12), NodeId(14))),
NodeId(12) -> dummyExerciseNode("#cid12", ImmArray.Empty),
NodeId(13) -> dummyCreateNode("#cid13"),
NodeId(10) -> dummyCreateNode(cid("#cid10")),
NodeId(11) -> dummyExerciseNode(cid("#cid11"), ImmArray(NodeId(12), NodeId(14))),
NodeId(12) -> dummyExerciseNode(cid("#cid12"), ImmArray.Empty),
NodeId(13) -> dummyCreateNode(cid("#cid13")),
NodeId(14) -> dummyRollbackNode(ImmArray(NodeId(15))),
NodeId(15) -> dummyCreateNode("#cid15"),
NodeId(15) -> dummyCreateNode(cid("#cid15")),
),
ImmArray(NodeId(0), NodeId(1), NodeId(3)),
)
@ -248,8 +254,8 @@ class TransactionSpec
val tx = mkTransaction(
HashMap(
NodeId(0) -> dummyCreateNode(cid1),
NodeId(0) -> dummyExerciseNode(cid1, ImmArray(NodeId(0))),
NodeId(1) -> dummyExerciseNode(cid2, ImmArray(NodeId(1))),
NodeId(0) -> dummyExerciseNode(cid1, ImmArray(NodeId(0)), true),
NodeId(1) -> dummyExerciseNode(cid2, ImmArray(NodeId(1)), true),
),
ImmArray(NodeId(0), NodeId(1)),
)
@ -262,11 +268,6 @@ class TransactionSpec
tx1 shouldBe Right(tx.mapCid(mapping2))
}
"suffixing v0 contract id should be a no op" in {
val v0Cid = V.ValueContractId(V.ContractId.V0.assertFromString("#deadbeef"))
val Right(v0CidSuffixed) = v0Cid.suffixCid(_ => Bytes.assertFromString("cafe"))
v0Cid shouldBe v0CidSuffixed
}
}
"contractKeys" - {
@ -275,36 +276,39 @@ class TransactionSpec
val builder = TransactionBuilder()
val parties = Set("Alice")
def create(s: String) = builder
.create(
id = s"#$s",
templateId = s"Mod:$s",
argument = V.ValueUnit,
signatories = parties,
observers = parties,
key = Some(V.ValueText(s)),
)
def create(s: V.ContractId) = {
println(s)
builder
.create(
id = s,
templateId = s"Mod:t${s.coid}",
argument = V.ValueUnit,
signatories = parties,
observers = parties,
key = Some(V.ValueText(s.coid)),
)
}
def exe(s: String, consuming: Boolean, byKey: Boolean) =
def exe(s: V.ContractId, consuming: Boolean, byKey: Boolean) =
builder
.exercise(
contract = create(s),
choice = s"Choice$s",
choice = s"Choice${s.coid}",
actingParties = parties.toSet,
consuming = consuming,
argument = V.ValueUnit,
byKey = byKey,
)
def fetch(s: String, byKey: Boolean) =
def fetch(s: V.ContractId, byKey: Boolean) =
builder.fetch(contract = create(s), byKey = byKey)
def lookup(s: String, found: Boolean) =
def lookup(s: V.ContractId, found: Boolean) =
builder.lookupByKey(contract = create(s), found = found)
val root1 =
builder.create(
"#root",
cid("#root"),
templateId = "Mod:Root",
argument = V.ValueUnit,
signatories = parties,
@ -322,25 +326,27 @@ class TransactionSpec
builder.add(root1)
val exeId = builder.add(root2)
builder.add(create("Create"))
builder.add(exe("NonConsumingExerciseById", false, false), exeId)
builder.add(exe("ConsumingExerciseById", true, false), exeId)
builder.add(exe("NonConsumingExerciseByKey", false, true), exeId)
builder.add(exe("NonConsumingExerciseByKey", true, true), exeId)
builder.add(fetch("FetchById", false), exeId)
builder.add(fetch("FetchByKey", true), exeId)
builder.add(lookup("SuccessfulLookup", true), exeId)
builder.add(lookup("UnsuccessfulLookup", true), exeId)
println(cid("Create"))
builder.add(create(cid("Create"): V.ContractId))
println("created")
builder.add(exe(cid("NonConsumingExerciseById"), false, false), exeId)
builder.add(exe(cid("ConsumingExerciseById"), true, false), exeId)
builder.add(exe(cid("NonConsumingExerciseByKey"), false, true), exeId)
builder.add(exe(cid("NonConsumingExerciseByKey"), true, true), exeId)
builder.add(fetch(cid("FetchById"), false), exeId)
builder.add(fetch(cid("FetchByKey"), true), exeId)
builder.add(lookup(cid("SuccessfulLookup"), true), exeId)
builder.add(lookup(cid("UnsuccessfulLookup"), true), exeId)
val rollbackId = builder.add(Node.Rollback(ImmArray.Empty))
builder.add(create("RolledBackCreate"))
builder.add(exe("RolledBackNonConsumingExerciseById", false, false), rollbackId)
builder.add(exe("RolledBackConsumingExerciseById", true, false), rollbackId)
builder.add(exe("RolledBackNonConsumingExerciseByKey", false, true), rollbackId)
builder.add(exe("RolledBackNonConsumingExerciseByKey", true, true), rollbackId)
builder.add(fetch("RolledBackFetchById", false), rollbackId)
builder.add(fetch("RolledBackFetchByKey", true), rollbackId)
builder.add(lookup("RolledBackSuccessfulLookup", true), rollbackId)
builder.add(lookup("RolledBackUnsuccessfulLookup", true), rollbackId)
builder.add(create(cid("RolledBackCreate")))
builder.add(exe(cid("RolledBackNonConsumingExerciseById"), false, false), rollbackId)
builder.add(exe(cid("RolledBackConsumingExerciseById"), true, false), rollbackId)
builder.add(exe(cid("RolledBackNonConsumingExerciseByKey"), false, true), rollbackId)
builder.add(exe(cid("RolledBackNonConsumingExerciseByKey"), true, true), rollbackId)
builder.add(fetch(cid("RolledBackFetchById"), false), rollbackId)
builder.add(fetch(cid("RolledBackFetchByKey"), true), rollbackId)
builder.add(lookup(cid("RolledBackSuccessfulLookup"), true), rollbackId)
builder.add(lookup(cid("RolledBackUnsuccessfulLookup"), true), rollbackId)
val expectedResults =
Iterator(
@ -362,7 +368,7 @@ class TransactionSpec
"RolledBackFetchByKey",
"RolledBackSuccessfulLookup",
"RolledBackUnsuccessfulLookup",
).map(s => GlobalKey.assertBuild("Mod:" + s, V.ValueText(s))).toSet
).map(s => GlobalKey.assertBuild(create(cid(s)).templateId, V.ValueText(cid(s).coid))).toSet
builder.build().contractKeys shouldBe expectedResults
}
@ -373,18 +379,18 @@ class TransactionSpec
val dummyBuilder = TransactionBuilder()
val parties = List("Alice")
def keyValue(s: String) = V.ValueText(s)
def globalKey(s: String) = GlobalKey("Mod:T", keyValue(s))
def create(s: String) = dummyBuilder
def globalKey(s: V.ContractId) = GlobalKey("Mod:T", keyValue(s.coid))
def create(s: V.ContractId) = dummyBuilder
.create(
id = s,
templateId = "Mod:T",
argument = V.ValueUnit,
signatories = parties,
observers = parties,
key = Some(keyValue(s)),
key = Some(keyValue(s.coid)),
)
def exe(s: String, consuming: Boolean, byKey: Boolean) =
def exe(s: V.ContractId, consuming: Boolean, byKey: Boolean) =
dummyBuilder
.exercise(
contract = create(s),
@ -395,64 +401,69 @@ class TransactionSpec
byKey = byKey,
)
def fetch(s: String, byKey: Boolean) =
def fetch(s: V.ContractId, byKey: Boolean) =
dummyBuilder.fetch(contract = create(s), byKey = byKey)
def lookup(s: String, found: Boolean) =
def lookup(s: V.ContractId, found: Boolean) =
dummyBuilder.lookupByKey(contract = create(s), found = found)
"return None for create" in {
val builder = TransactionBuilder()
val createNode = create("#0")
val createNode = create(cid("#0"))
builder.add(createNode)
builder.build().contractKeyInputs shouldBe Right(Map(globalKey("#0") -> KeyCreate))
builder.build().contractKeyInputs shouldBe Right(Map(globalKey(cid("#0")) -> KeyCreate))
}
"return Some(_) for fetch and fetch-by-key" in {
val builder = TransactionBuilder()
val fetchNode0 = fetch("#0", byKey = false)
val fetchNode1 = fetch("#1", byKey = true)
val fetchNode0 = fetch(cid("#0"), byKey = false)
val fetchNode1 = fetch(cid("#1"), byKey = true)
builder.add(fetchNode0)
builder.add(fetchNode1)
builder.build().contractKeyInputs shouldBe Right(
Map(globalKey("#0") -> KeyActive("#0"), globalKey("#1") -> KeyActive("#1"))
Map(
globalKey(cid("#0")) -> KeyActive(cid("#0")),
globalKey(cid("#1")) -> KeyActive(cid("#1")),
)
)
}
"return Some(_) for consuming/non-consuming exercise and exercise-by-key" in {
val builder = TransactionBuilder()
val exe0 = exe("#0", consuming = false, byKey = false)
val exe1 = exe("#1", consuming = true, byKey = false)
val exe2 = exe("#2", consuming = false, byKey = true)
val exe3 = exe("#3", consuming = true, byKey = true)
val exe0 = exe(cid("#0"), consuming = false, byKey = false)
val exe1 = exe(cid("#1"), consuming = true, byKey = false)
val exe2 = exe(cid("#2"), consuming = false, byKey = true)
val exe3 = exe(cid("#3"), consuming = true, byKey = true)
builder.add(exe0)
builder.add(exe1)
builder.add(exe2)
builder.add(exe3)
builder.build().contractKeyInputs shouldBe Right(
Seq("#0", "#1", "#2", "#3").map(s => globalKey(s) -> KeyActive(s)).toMap
Seq(cid("#0"), cid("#1"), cid("#2"), cid("#3")).map(s => globalKey(s) -> KeyActive(s)).toMap
)
}
"return None for negative lookup by key" in {
val builder = TransactionBuilder()
val lookupNode = lookup("#0", found = false)
val lookupNode = lookup(cid("#0"), found = false)
builder.add(lookupNode)
builder.build().contractKeyInputs shouldBe Right(Map(globalKey("#0") -> NegativeKeyLookup))
builder.build().contractKeyInputs shouldBe Right(
Map(globalKey(cid("#0")) -> NegativeKeyLookup)
)
}
"return Some(_) for negative lookup by key" in {
val builder = TransactionBuilder()
val lookupNode = lookup("#0", found = true)
val lookupNode = lookup(cid("#0"), found = true)
builder.add(lookupNode)
inside(lookupNode.result) { case Some(cid) =>
builder.build().contractKeyInputs shouldBe Right(Map(globalKey("#0") -> KeyActive(cid)))
builder.build().contractKeyInputs shouldBe Right(Map(globalKey(cid) -> KeyActive(cid)))
}
}
"returns keys used under rollback nodes" in {
val builder = TransactionBuilder()
val createNode = create("#0")
val exerciseNode = exe("#1", consuming = false, byKey = false)
val fetchNode = fetch("#2", byKey = false)
val lookupNode = lookup("#3", found = false)
val createNode = create(cid("#0"))
val exerciseNode = exe(cid("#1"), consuming = false, byKey = false)
val fetchNode = fetch(cid("#2"), byKey = false)
val lookupNode = lookup(cid("#3"), found = false)
val rollback = builder.add(builder.rollback())
builder.add(createNode, rollback)
builder.add(exerciseNode, rollback)
@ -460,101 +471,101 @@ class TransactionSpec
builder.add(lookupNode, rollback)
builder.build().contractKeyInputs shouldBe Right(
Map(
globalKey("#0") -> KeyCreate,
globalKey("#1") -> KeyActive(exerciseNode.targetCoid),
globalKey("#2") -> KeyActive(fetchNode.coid),
globalKey("#3") -> NegativeKeyLookup,
globalKey(cid("#0")) -> KeyCreate,
globalKey(cid("#1")) -> KeyActive(exerciseNode.targetCoid),
globalKey(cid("#2")) -> KeyActive(fetchNode.coid),
globalKey(cid("#3")) -> NegativeKeyLookup,
)
)
}
"two creates conflict" in {
val builder = TransactionBuilder()
builder.add(create("#0"))
builder.add(create("#0"))
builder.build().contractKeyInputs shouldBe Left(DuplicateKeys(globalKey("#0")))
builder.add(create(cid("#0")))
builder.add(create(cid("#0")))
builder.build().contractKeyInputs shouldBe Left(DuplicateKeys(globalKey(cid("#0"))))
}
"two creates do not conflict if interleaved with archive" in {
val builder = TransactionBuilder()
builder.add(create("#0"))
builder.add(exe("#0", consuming = true, byKey = false))
builder.add(create("#0"))
builder.build().contractKeyInputs shouldBe Right(Map(globalKey("#0") -> KeyCreate))
builder.add(create(cid("#0")))
builder.add(exe(cid("#0"), consuming = true, byKey = false))
builder.add(create(cid("#0")))
builder.build().contractKeyInputs shouldBe Right(Map(globalKey(cid("#0")) -> KeyCreate))
}
"two creates do not conflict if one is in rollback" in {
val builder = TransactionBuilder()
val rollback = builder.add(builder.rollback())
builder.add(create("#0"), rollback)
builder.add(create("#0"))
builder.build().contractKeyInputs shouldBe Right(Map(globalKey("#0") -> KeyCreate))
builder.add(create(cid("#0")), rollback)
builder.add(create(cid("#0")))
builder.build().contractKeyInputs shouldBe Right(Map(globalKey(cid("#0")) -> KeyCreate))
}
"negative lookup after create fails" in {
val builder = TransactionBuilder()
builder.add(create("#0"))
builder.add(lookup("#0", found = false))
builder.build().contractKeyInputs shouldBe Left(InconsistentKeys(globalKey("#0")))
builder.add(create(cid("#0")))
builder.add(lookup(cid("#0"), found = false))
builder.build().contractKeyInputs shouldBe Left(InconsistentKeys(globalKey(cid("#0"))))
}
"inconsistent lookups conflict" in {
val builder = TransactionBuilder()
builder.add(lookup("#0", found = true))
builder.add(lookup("#0", found = false))
builder.build().contractKeyInputs shouldBe Left(InconsistentKeys(globalKey("#0")))
builder.add(lookup(cid("#0"), found = true))
builder.add(lookup(cid("#0"), found = false))
builder.build().contractKeyInputs shouldBe Left(InconsistentKeys(globalKey(cid("#0"))))
}
"inconsistent lookups conflict across rollback" in {
val builder = TransactionBuilder()
val rollback = builder.add(builder.rollback())
builder.add(lookup("#0", found = true), rollback)
builder.add(lookup("#0", found = false))
builder.build().contractKeyInputs shouldBe Left(InconsistentKeys(globalKey("#0")))
builder.add(lookup(cid("#0"), found = true), rollback)
builder.add(lookup(cid("#0"), found = false))
builder.build().contractKeyInputs shouldBe Left(InconsistentKeys(globalKey(cid("#0"))))
}
"positive lookup conflicts with create" in {
val builder = TransactionBuilder()
builder.add(lookup("#0", found = true))
builder.add(create("#0"))
builder.build().contractKeyInputs shouldBe Left(DuplicateKeys(globalKey("#0")))
builder.add(lookup(cid("#0"), found = true))
builder.add(create(cid("#0")))
builder.build().contractKeyInputs shouldBe Left(DuplicateKeys(globalKey(cid("#0"))))
}
"positive lookup in rollback conflicts with create" in {
val builder = TransactionBuilder()
val rollback = builder.add(builder.rollback())
builder.add(lookup("#0", found = true), rollback)
builder.add(create("#0"))
builder.build().contractKeyInputs shouldBe Left(DuplicateKeys(globalKey("#0")))
builder.add(lookup(cid("#0"), found = true), rollback)
builder.add(create(cid("#0")))
builder.build().contractKeyInputs shouldBe Left(DuplicateKeys(globalKey(cid("#0"))))
}
"rolled back archive does not prevent conflict" in {
val builder = TransactionBuilder()
builder.add(create("#0"))
builder.add(create(cid("#0")))
val rollback = builder.add(builder.rollback())
builder.add(exe("#0", consuming = true, byKey = true), rollback)
builder.add(create("#0"))
builder.build().contractKeyInputs shouldBe Left(DuplicateKeys(globalKey("#0")))
builder.add(exe(cid("#0"), consuming = true, byKey = true), rollback)
builder.add(create(cid("#0")))
builder.build().contractKeyInputs shouldBe Left(DuplicateKeys(globalKey(cid("#0"))))
}
"successful, inconsistent lookups conflict" in {
val builder = TransactionBuilder()
val create0 = create("#0")
val create1 = create("#1").copy(
val create0 = create(cid("#0"))
val create1 = create(cid("#1")).copy(
key = Some(
Node.KeyWithMaintainers(
key = keyValue("#0"),
key = keyValue(cid("#0").coid),
maintainers = Set.empty,
)
)
)
builder.add(builder.lookupByKey(create0, found = true))
builder.add(builder.lookupByKey(create1, found = true))
builder.build().contractKeyInputs shouldBe Left(InconsistentKeys(globalKey("#0")))
builder.build().contractKeyInputs shouldBe Left(InconsistentKeys(globalKey(cid("#0"))))
}
"first negative input wins" in {
val builder = TransactionBuilder()
val rollback = builder.add(builder.rollback())
val create0 = create("#0")
val create0 = create(cid("#0"))
val lookup0 = builder.lookupByKey(create0, found = false)
val create1 = create("#1")
val create1 = create(cid("#1"))
val lookup1 = builder.lookupByKey(create1, found = false)
builder.add(create0, rollback)
builder.add(lookup1, rollback)
builder.add(lookup0)
builder.add(create1)
builder.build().contractKeyInputs shouldBe Right(
Map(globalKey("#0") -> KeyCreate, globalKey("#1") -> NegativeKeyLookup)
Map(globalKey(cid("#0")) -> KeyCreate, globalKey(cid("#1")) -> NegativeKeyLookup)
)
}
}
@ -648,6 +659,8 @@ object TransactionSpec {
import TransactionBuilder.Implicits._
def cid(s: String): V.ContractId = V.ContractId.V1(Hash.hashPrivateKey(s))
def mkTransaction(
nodes: HashMap[NodeId, Node],
roots: ImmArray[NodeId],
@ -683,11 +696,11 @@ object TransactionSpec {
version = TransactionVersion.minVersion,
)
def dummyCreateNode(cid: V.ContractId): Node.Create =
def dummyCreateNode(createCid: V.ContractId): Node.Create =
Node.Create(
coid = cid,
coid = createCid,
templateId = Ref.Identifier.assertFromString("-dummyPkg-:DummyModule:dummyName"),
arg = V.ValueContractId("#dummyCid"),
arg = V.ValueContractId(cid("#dummyCid")),
agreementText = "dummyAgreement",
signatories = Set.empty,
stakeholders = Set.empty,

View File

@ -8,7 +8,7 @@ import data.{Bytes, ImmArray, Ref}
import Value._
import Ref.{Identifier, Name}
import test.ValueGenerators.{cidV0Gen, coidGen, idGen, nameGen}
import test.ValueGenerators.{suffixedV1CidGen, coidGen, idGen, nameGen}
import test.TypedValueGenerators.{RNil, genAddend, ValueAddend => VA}
import org.scalacheck.{Arbitrary, Gen}
import org.scalatest.Inside
@ -85,8 +85,7 @@ class ValueSpec
"Order" - {
// SContractId V1 ordering is nontotal so arbitrary generation of them is unsafe to use
implicit val cidArb: Arbitrary[Value.ContractId] = Arbitrary(cidV0Gen)
implicit val cidArb: Arbitrary[Value.ContractId] = Arbitrary(suffixedV1CidGen)
val FooScope: Value.LookupVariantEnum =
Map(fooVariantId -> ImmArray("quux", "baz"), fooEnumId -> ImmArray("quux", "baz"))

View File

@ -758,7 +758,6 @@ object Converter {
valueTranslator =
new preprocessing.ValueTranslator(
compiledPackages.interface,
forbidV0ContractId = false,
requireV1ContractIdSuffix = false,
)
sValue <- valueTranslator

View File

@ -68,7 +68,6 @@ object ScriptF {
def compiledPackages = machine.compiledPackages
val valueTranslator = new ValueTranslator(
interface = compiledPackages.interface,
forbidV0ContractId = false,
requireV1ContractIdSuffix = false,
)
val utcClock = Clock.systemUTC()

View File

@ -47,7 +47,6 @@ class IdeLedgerClient(
private[this] val preprocessor =
new preprocessing.CommandPreprocessor(
compiledPackages.interface,
forbidV0ContractId = true,
requireV1ContractIdSuffix = false,
)

View File

@ -12,7 +12,7 @@ import com.daml.http.dbbackend.SurrogateTemplateIdCache
import com.daml.lf.iface
import com.daml.lf.value.{Value => V}
import com.daml.lf.value.test.TypedValueGenerators.{genAddendNoListMap, RNil, ValueAddend => VA}
import com.daml.lf.value.test.ValueGenerators.cidV0Gen
import com.daml.lf.value.test.ValueGenerators.coidGen
import com.daml.metrics.Metrics
import org.scalacheck.Arbitrary
import org.scalactic.source
@ -33,7 +33,7 @@ class ValuePredicateTest
with TableDrivenPropertyChecks {
import ValuePredicateTest._
type Cid = V.ContractId
private[this] implicit val arbCid: Arbitrary[Cid] = Arbitrary(cidV0Gen)
private[this] implicit val arbCid: Arbitrary[Cid] = Arbitrary(coidGen)
import Ref.QualifiedName.{assertFromString => qn}

View File

@ -43,10 +43,6 @@ class ApiValueToLfValueConverterTest
}
object ApiValueToLfValueConverterTest {
type Cid = V.ContractId
type CidSrc = V.ContractId.V0
// Numeric are normalized when converting from api to lf,
// them we have to relax numeric equality
private implicit def eqValue: Equal[V] = { (l, r) =>

View File

@ -117,7 +117,7 @@ class ApiCodecCompressedSpec
fUnit = (),
fInt64 = 100L,
fParty = Ref.Party assertFromString "BANK1",
fContractId = ContractId.assertFromString("#C0"),
fContractId = ContractId.assertFromString("00" + "00" * 32 + "c0"),
fListOfText = Vector("foo", "bar"),
fListOfUnit = Vector((), ()),
fDate = Time.Date assertFromString "2019-01-28",
@ -260,7 +260,14 @@ class ApiCodecCompressedSpec
val successes = Table(
("line#", "serialized", "serializedNumerically", "type", "parsed", "alternates"),
c("\"#123\"", VA.contractId)(ContractId.assertFromString("#123")),
c(
"\"0000000000000000000000000000000000000000000000000000000000000000000123\"",
VA.contractId,
)(
ContractId.assertFromString(
"0000000000000000000000000000000000000000000000000000000000000000000123"
)
),
cn("\"42.0\"", "42.0", VA.numeric(Decimal.scale))(
Decimal assertFromString "42",
"\"42\"",

View File

@ -105,6 +105,7 @@ da_scala_test_suite(
],
deps = [
":ledger-api-client",
"//daml-lf/transaction",
"//language-support/scala/bindings",
"//ledger-api/rs-grpc-bridge",
"//ledger-api/testing-utils",

View File

@ -38,6 +38,8 @@ import com.daml.ledger.client.services.commands.{
CompletionStreamElement,
}
import com.daml.ledger.client.services.testing.time.StaticTime
import com.daml.lf.crypto.Hash
import com.daml.lf.value.Value.ContractId
import com.daml.platform.common.LedgerIdMode
import com.daml.platform.participant.util.ValueConversions._
import com.daml.platform.sandbox.config.SandboxConfig
@ -483,12 +485,21 @@ final class CommandClientIT
}
"not accept exercises with bad contract IDs, return ABORTED" in {
val contractId = "#deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef-123"
val contractId = ContractId.V1(
Hash.hashPrivateKey(
"#deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef-123"
)
)
val command =
submitRequest(
"Exercise_contract_not_found",
List(
ExerciseCommand(Some(templateIds.dummy), contractId, "DummyChoice1", Some(unit)).wrap
ExerciseCommand(
Some(templateIds.dummy),
contractId.coid,
"DummyChoice1",
Some(unit),
).wrap
),
)

View File

@ -7,7 +7,9 @@ import com.daml.error.{ErrorCodesVersionSwitcher, NoLogging}
import com.daml.ledger.api.v1.value.Value.Sum
import com.daml.ledger.api.v1.{value => api}
import com.daml.ledger.api.validation.{ValidatorTestUtils, ValueValidator}
import com.daml.lf.crypto.Hash
import com.daml.lf.data.Time
import com.daml.lf.value.Value.ContractId
import com.daml.platform.participant.util.LfEngineToApi
import com.daml.platform.server.api.validation.{ErrorFactories, FieldValidations}
import com.google.protobuf.empty.Empty
@ -42,7 +44,7 @@ class ValueConversionRoundTripTest
val testCases: TableFor1[Sum] = Table(
"values",
Sum.ContractId("#coid"),
Sum.ContractId(ContractId.V1(Hash.hashPrivateKey("#coid")).coid),
DomainMocks.values.validApiParty.sum,
Sum.Int64(Long.MinValue),
Sum.Int64(0),

View File

@ -445,10 +445,10 @@ class SubmitRequestValidatorTest
"validating contractId values" should {
"succeed" in {
val coid = Ref.ContractIdString.assertFromString("#coid")
val coid = Lf.ContractId.V1.assertFromString("00" + "00" * 32)
val input = Value(Sum.ContractId(coid))
val expected = Lf.ValueContractId(Lf.ContractId.V0(coid))
val input = Value(Sum.ContractId(coid.coid))
val expected = Lf.ValueContractId(coid)
testedValueValidator.validateValue(input) shouldEqual Right(expected)
}

View File

@ -112,6 +112,7 @@ conformance_test(
"TLSOnePointThreeIT",
"TLSAtLeastOnePointTwoIT",
"MonotonicRecordTimeIT", # KV-utils specific
"ContractIdIT", # temporarily disabled due to changed error codes
]),
],
) if not is_windows else None

View File

@ -4,6 +4,7 @@
package com.daml.ledger.api.testtool.suites
import com.daml.error.definitions.LedgerApiErrors
import com.daml.error.ErrorCode
import com.daml.grpc.{GrpcException, GrpcStatus}
import com.daml.ledger.api.refinements.ApiTypes.Party
import com.daml.ledger.api.testtool.infrastructure.Allocation._
@ -66,7 +67,10 @@ final class ContractIdIT extends LedgerTestSuite {
case TestConfiguration(cidDescription, example, accepted, isSupported, disabledReason) =>
val result = if (accepted) "Accept" else "Reject"
def test(description: String)(
def test(
description: String,
errorCode: ErrorCode = LedgerApiErrors.RequestValidation.InvalidArgument,
)(
update: ExecutionContext => (
ParticipantTestContext,
Party,
@ -86,8 +90,8 @@ final class ContractIdIT extends LedgerTestSuite {
alpha,
err,
Status.Code.INVALID_ARGUMENT,
LedgerApiErrors.CommandExecution.Preprocessing.PreprocessingFailed,
Some(s"""Illegal Contract ID "$example""""),
errorCode,
Some(s"""cannot parse ContractId "$example""""),
checkDefiniteAnswerMetadata = true,
)
()
@ -103,38 +107,39 @@ final class ContractIdIT extends LedgerTestSuite {
.transformWith(Future.successful)
}
test("exercise target") { implicit ec => (alpha, party) =>
for {
contractCid <- alpha.create(party, Contract(party))
result <-
alpha
.exercise(
party,
ContractId[ContractRef](example).exerciseChange(_, contractCid),
)
.transformWith(Future.successful)
} yield result match {
// Assert V1 error code
case Failure(GrpcException(GrpcStatus(Status.Code.ABORTED, Some(msg)), _))
if !alpha.features.selfServiceErrorCodes && msg.contains(
s"Contract could not be found with id $example"
) =>
Success(())
test("exercise target", errorCode = LedgerApiErrors.RequestValidation.InvalidField) {
implicit ec => (alpha, party) =>
for {
contractCid <- alpha.create(party, Contract(party))
result <-
alpha
.exercise(
party,
ContractId[ContractRef](example).exerciseChange(_, contractCid),
)
.transformWith(Future.successful)
} yield result match {
// Assert V1 error code
case Failure(GrpcException(GrpcStatus(Status.Code.ABORTED, Some(msg)), _))
if !alpha.features.selfServiceErrorCodes && msg.contains(
s"Contract could not be found with id $example"
) =>
Success(())
// Assert self-service error code
case Failure(exception: StatusRuntimeException)
if alpha.features.selfServiceErrorCodes &&
Try(
assertSelfServiceErrorCode(
statusRuntimeException = exception,
expectedErrorCode = LedgerApiErrors.ConsistencyErrors.ContractNotFound,
)
).isSuccess =>
Success(())
// Assert self-service error code
case Failure(exception: StatusRuntimeException)
if alpha.features.selfServiceErrorCodes &&
Try(
assertSelfServiceErrorCode(
statusRuntimeException = exception,
expectedErrorCode = LedgerApiErrors.ConsistencyErrors.ContractNotFound,
)
).isSuccess =>
Success(())
case Success(_) => Failure(new UnknownError("Unexpected Success"))
case otherwise => otherwise.map(_ => ())
}
case Success(_) => Failure(new UnknownError("Unexpected Success"))
case otherwise => otherwise.map(_ => ())
}
}
test("choice argument") { implicit ec => (alpha, party) =>

View File

@ -167,7 +167,7 @@ object EndlessReadService {
def submissionId(i: Int): Ref.SubmissionId = Ref.SubmissionId.assertFromString(f"sub$i%08x")
def transactionId(i: Int): Ref.TransactionId = Ref.TransactionId.assertFromString(f"tx$i%08x")
def commandId(i: Int): Ref.CommandId = Ref.CommandId.assertFromString(f"cmd$i%08x")
def cid(i: Int): Value.ContractId = Value.ContractId.V0.assertFromString(s"#$i")
def cid(i: Int): Value.ContractId = Value.ContractId.V1(crypto.Hash.hashPrivateKey(i.toString))
def recordTime(i: Int): Timestamp =
Timestamp.assertFromInstant(Instant.EPOCH.plusSeconds(i.toLong))
def completionInfo(i: Int): CompletionInfo = CompletionInfo(

View File

@ -10,10 +10,12 @@ import com.daml.daml_lf_dev.DamlLf
import com.daml.ledger.api.domain.{LedgerId, ParticipantId}
import com.daml.ledger.configuration.{Configuration, LedgerTimeModel}
import com.daml.ledger.offset.Offset
import com.daml.lf.crypto.Hash
import com.daml.lf.data.Ref
import com.daml.lf.data.Time.Timestamp
import com.daml.lf.ledger.EventId
import com.daml.lf.transaction.NodeId
import com.daml.lf.value.Value.ContractId
import com.daml.platform.store.appendonlydao.JdbcLedgerDao
import com.google.protobuf.ByteString
@ -21,6 +23,8 @@ import com.google.protobuf.ByteString
*/
private[backend] object StorageBackendTestValues {
def hashCid(key: String): ContractId = ContractId.V1(Hash.hashPrivateKey(key))
/** Produces offsets that are ordered the same as the input value */
def offset(x: Long): Offset = Offset.fromHexString(Ref.HexString.assertFromString(f"$x%08d"))
def ledgerEnd(o: Long, e: Long): ParameterStorageBackend.LedgerEnd =
@ -108,7 +112,7 @@ private[backend] object StorageBackendTestValues {
def dtoCreate(
offset: Offset,
eventSequentialId: Long,
contractId: String,
contractId: ContractId,
signatory: String = "signatory",
observer: String = "observer",
commandId: String = UUID.randomUUID().toString,
@ -125,7 +129,7 @@ private[backend] object StorageBackendTestValues {
submitters = None,
node_index = Some(0),
event_id = Some(EventId(transactionId, NodeId(0)).toLedgerString),
contract_id = contractId,
contract_id = contractId.coid,
template_id = Some(someTemplateId.toString),
flat_event_witnesses = Set(signatory, observer),
tree_event_witnesses = Set(signatory, observer),
@ -151,7 +155,7 @@ private[backend] object StorageBackendTestValues {
offset: Offset,
eventSequentialId: Long,
consuming: Boolean,
contractId: String,
contractId: ContractId,
signatory: String = "signatory",
actor: String = "actor",
commandId: String = UUID.randomUUID().toString,
@ -168,7 +172,7 @@ private[backend] object StorageBackendTestValues {
submitters = Some(Set(actor)),
node_index = Some(0),
event_id = Some(EventId(transactionId, NodeId(0)).toLedgerString),
contract_id = contractId,
contract_id = contractId.coid,
template_id = Some(someTemplateId.toString),
flat_event_witnesses = if (consuming) Set(signatory) else Set.empty,
tree_event_witnesses = Set(signatory, actor),
@ -190,7 +194,7 @@ private[backend] object StorageBackendTestValues {
def dtoDivulgence(
offset: Option[Offset],
eventSequentialId: Long,
contractId: String,
contractId: ContractId,
submitter: String = "signatory",
divulgee: String = "divulgee",
commandId: String = UUID.randomUUID().toString,
@ -201,7 +205,7 @@ private[backend] object StorageBackendTestValues {
workflow_id = Some("workflow_id"),
application_id = Some(someApplicationId),
submitters = Some(Set(submitter)),
contract_id = contractId,
contract_id = contractId.coid,
template_id = Some(someTemplateId.toString),
tree_event_witnesses = Set(divulgee),
create_argument = Some(someSerializedDamlLfValue),

View File

@ -4,7 +4,6 @@
package com.daml.platform.store.backend
import com.daml.lf.data.Ref
import com.daml.lf.value.Value.ContractId
import org.scalatest.Inside
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers
@ -20,12 +19,12 @@ private[backend] trait StorageBackendTestsContracts
import StorageBackendTestValues._
it should "correctly find an active contract" in {
val contractId = ContractId.V0.assertFromString("#1")
val contractId = hashCid("#1")
val signatory = Ref.Party.assertFromString("signatory")
val dtos: Vector[DbDto] = Vector(
// 1: transaction with create node
dtoCreate(offset(1), 1L, contractId = contractId.coid, signatory = signatory),
dtoCreate(offset(1), 1L, contractId = contractId, signatory = signatory),
DbDto.CreateFilter(1L, someTemplateId.toString, signatory),
dtoCompletion(offset(1)),
)
@ -50,16 +49,16 @@ private[backend] trait StorageBackendTestsContracts
}
it should "not find an archived contract" in {
val contractId = ContractId.V0.assertFromString("#1")
val contractId = hashCid("#1")
val signatory = Ref.Party.assertFromString("signatory")
val dtos: Vector[DbDto] = Vector(
// 1: transaction with create node
dtoCreate(offset(1), 1L, contractId = contractId.coid, signatory = signatory),
dtoCreate(offset(1), 1L, contractId = contractId, signatory = signatory),
DbDto.CreateFilter(1L, someTemplateId.toString, signatory),
dtoCompletion(offset(1)),
// 2: transaction that archives the contract
dtoExercise(offset(2), 2L, true, contractId.coid),
dtoExercise(offset(2), 2L, true, contractId),
dtoCompletion(offset(2)),
)
@ -80,12 +79,12 @@ private[backend] trait StorageBackendTestsContracts
}
it should "correctly find a divulged contract" in {
val contractId = ContractId.V0.assertFromString("#1")
val contractId = hashCid("#1")
val divulgee = Ref.Party.assertFromString("divulgee")
val dtos: Vector[DbDto] = Vector(
// 1: divulgence
dtoDivulgence(Some(offset(1)), 1L, contractId = contractId.coid, divulgee = divulgee),
dtoDivulgence(Some(offset(1)), 1L, contractId = contractId, divulgee = divulgee),
DbDto.CreateFilter(1L, someTemplateId.toString, divulgee),
dtoCompletion(offset(1)),
)
@ -110,17 +109,17 @@ private[backend] trait StorageBackendTestsContracts
}
it should "correctly find an active contract that is also divulged" in {
val contractId = ContractId.V0.assertFromString("#1")
val contractId = hashCid("#1")
val signatory = Ref.Party.assertFromString("signatory")
val divulgee = Ref.Party.assertFromString("divulgee")
val dtos: Vector[DbDto] = Vector(
// 1: transaction with create node
dtoCreate(offset(1), 1L, contractId = contractId.coid, signatory = signatory),
dtoCreate(offset(1), 1L, contractId = contractId, signatory = signatory),
DbDto.CreateFilter(1L, someTemplateId.toString, signatory),
dtoCompletion(offset(1)),
// 2: divulgence without any optional information
dtoDivulgence(Some(offset(2)), 2L, contractId = contractId.coid, divulgee = divulgee)
dtoDivulgence(Some(offset(2)), 2L, contractId = contractId, divulgee = divulgee)
.copy(template_id = None, create_argument = None, create_argument_compression = None),
DbDto.CreateFilter(2L, someTemplateId.toString, divulgee),
dtoCompletion(offset(2)),
@ -146,21 +145,21 @@ private[backend] trait StorageBackendTestsContracts
}
it should "not disclose to divulgees that a contract was archived" in {
val contractId = ContractId.V0.assertFromString("#1")
val contractId = hashCid("#1")
val signatory = Ref.Party.assertFromString("signatory")
val divulgee = Ref.Party.assertFromString("divulgee")
val dtos: Vector[DbDto] = Vector(
// 1: transaction with create node
dtoCreate(offset(1), 1L, contractId = contractId.coid, signatory = signatory),
dtoCreate(offset(1), 1L, contractId = contractId, signatory = signatory),
DbDto.CreateFilter(1L, someTemplateId.toString, signatory),
dtoCompletion(offset(1)),
// 2: divulgence
dtoDivulgence(Some(offset(2)), 2L, contractId = contractId.coid, divulgee = divulgee),
dtoDivulgence(Some(offset(2)), 2L, contractId = contractId, divulgee = divulgee),
DbDto.CreateFilter(2L, someTemplateId.toString, divulgee),
dtoCompletion(offset(2)),
// 3: transaction that archives the contract
dtoExercise(offset(3), 3L, true, contractId.coid, signatory = signatory),
dtoExercise(offset(3), 3L, true, contractId, signatory = signatory),
dtoCompletion(offset(3)),
)

View File

@ -24,10 +24,22 @@ private[backend] trait StorageBackendTestsEvents
val partyObserver2 = Ref.Party.assertFromString("observer2")
val dtos = Vector(
dtoCreate(offset(1), 1L, "#1", signatory = partySignatory, observer = partyObserver1),
dtoCreate(
offset(1),
1L,
hashCid("#1"),
signatory = partySignatory,
observer = partyObserver1,
),
dtoCreateFilter(1L, someTemplateId, partySignatory),
dtoCreateFilter(1L, someTemplateId, partyObserver1),
dtoCreate(offset(2), 2L, "#2", signatory = partySignatory, observer = partyObserver2),
dtoCreate(
offset(2),
2L,
hashCid("#2"),
signatory = partySignatory,
observer = partyObserver2,
),
dtoCreateFilter(2L, someTemplateId, partySignatory),
dtoCreateFilter(2L, someTemplateId, partyObserver2),
)
@ -74,10 +86,22 @@ private[backend] trait StorageBackendTestsEvents
val partyObserver2 = Ref.Party.assertFromString("observer2")
val dtos = Vector(
dtoCreate(offset(1), 1L, "#1", signatory = partySignatory, observer = partyObserver1),
dtoCreate(
offset(1),
1L,
hashCid("#1"),
signatory = partySignatory,
observer = partyObserver1,
),
dtoCreateFilter(1L, someTemplateId, partySignatory),
dtoCreateFilter(1L, someTemplateId, partyObserver1),
dtoCreate(offset(2), 2L, "#2", signatory = partySignatory, observer = partyObserver2),
dtoCreate(
offset(2),
2L,
hashCid("#2"),
signatory = partySignatory,
observer = partyObserver2,
),
dtoCreateFilter(2L, someTemplateId, partySignatory),
dtoCreateFilter(2L, someTemplateId, partyObserver2),
)
@ -125,10 +149,22 @@ private[backend] trait StorageBackendTestsEvents
val otherTemplate = Ref.Identifier.assertFromString("pkg:Mod:Template2")
val dtos = Vector(
dtoCreate(offset(1), 1L, "#1", signatory = partySignatory, observer = partyObserver1),
dtoCreate(
offset(1),
1L,
hashCid("#1"),
signatory = partySignatory,
observer = partyObserver1,
),
dtoCreateFilter(1L, someTemplateId, partySignatory),
dtoCreateFilter(1L, someTemplateId, partyObserver1),
dtoCreate(offset(2), 2L, "#2", signatory = partySignatory, observer = partyObserver2),
dtoCreate(
offset(2),
2L,
hashCid("#2"),
signatory = partySignatory,
observer = partyObserver2,
),
dtoCreateFilter(2L, someTemplateId, partySignatory),
dtoCreateFilter(2L, someTemplateId, partyObserver2),
)
@ -176,7 +212,7 @@ private[backend] trait StorageBackendTestsEvents
val unknownTemplate = Ref.Identifier.assertFromString("unknown:unknown:unknown")
val dtos = Vector(
dtoCreate(offset(1), 1L, "#1", signatory = partySignatory, observer = partyObserver),
dtoCreate(offset(1), 1L, hashCid("#1"), signatory = partySignatory, observer = partyObserver),
dtoCreateFilter(1L, someTemplateId, partySignatory),
dtoCreateFilter(1L, someTemplateId, partyObserver),
)
@ -223,10 +259,22 @@ private[backend] trait StorageBackendTestsEvents
val partyObserver2 = Ref.Party.assertFromString("observer2")
val dtos = Vector(
dtoCreate(offset(1), 1L, "#1", signatory = partySignatory, observer = partyObserver1),
dtoCreate(
offset(1),
1L,
hashCid("#1"),
signatory = partySignatory,
observer = partyObserver1,
),
dtoCreateFilter(1L, someTemplateId, partySignatory),
dtoCreateFilter(1L, someTemplateId, partyObserver1),
dtoCreate(offset(2), 2L, "#2", signatory = partySignatory, observer = partyObserver2),
dtoCreate(
offset(2),
2L,
hashCid("#2"),
signatory = partySignatory,
observer = partyObserver2,
),
dtoCreateFilter(2L, someTemplateId, partySignatory),
dtoCreateFilter(2L, someTemplateId, partyObserver2),
)

View File

@ -4,7 +4,6 @@
package com.daml.platform.store.backend
import com.daml.lf.data.Ref
import com.daml.lf.value.Value.ContractId
import org.scalatest.Inside
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers
@ -29,12 +28,12 @@ private[backend] trait StorageBackendTestsInitializeIngestion
dtoPackage(offset(3)),
dtoPackageEntry(offset(3)),
// 4: transaction with create node
dtoCreate(offset(4), 1L, "#4"),
dtoCreate(offset(4), 1L, hashCid("#4")),
DbDto.CreateFilter(1L, someTemplateId.toString, someParty.toString),
dtoCompletion(offset(4)),
// 5: transaction with exercise node and retroactive divulgence
dtoExercise(offset(5), 2L, false, "#4"),
dtoDivulgence(Some(offset(5)), 3L, "#4"),
dtoExercise(offset(5), 2L, false, hashCid("#4")),
dtoDivulgence(Some(offset(5)), 3L, hashCid("#4")),
dtoCompletion(offset(5)),
)
@ -47,12 +46,12 @@ private[backend] trait StorageBackendTestsInitializeIngestion
dtoPackage(offset(8)),
dtoPackageEntry(offset(8)),
// 9: transaction with create node
dtoCreate(offset(9), 4L, "#9"),
dtoCreate(offset(9), 4L, hashCid("#9")),
DbDto.CreateFilter(4L, someTemplateId.toString, someParty.toString),
dtoCompletion(offset(9)),
// 10: transaction with exercise node and retroactive divulgence
dtoExercise(offset(10), 5L, false, "#9"),
dtoDivulgence(Some(offset(10)), 6L, "#9"),
dtoExercise(offset(10), 5L, false, hashCid("#9")),
dtoDivulgence(Some(offset(10)), 6L, hashCid("#9")),
dtoCompletion(offset(10)),
)
@ -80,13 +79,13 @@ private[backend] trait StorageBackendTestsInitializeIngestion
val contract41 = executeSql(
backend.contract.activeContractWithoutArgument(
readers,
ContractId.V0.assertFromString("#4"),
hashCid("#4"),
)
)
val contract91 = executeSql(
backend.contract.activeContractWithoutArgument(
readers,
ContractId.V0.assertFromString("#9"),
hashCid("#9"),
)
)
val filterIds1 = executeSql(
@ -113,13 +112,13 @@ private[backend] trait StorageBackendTestsInitializeIngestion
val contract42 = executeSql(
backend.contract.activeContractWithoutArgument(
readers,
ContractId.V0.assertFromString("#4"),
hashCid("#4"),
)
)
val contract92 = executeSql(
backend.contract.activeContractWithoutArgument(
readers,
ContractId.V0.assertFromString("#9"),
hashCid("#9"),
)
)
val filterIds2 = executeSql(

View File

@ -15,8 +15,8 @@ private[backend] trait StorageBackendTestsIntegrity extends Matchers with Storag
it should "find duplicate event ids" in {
val updates = Vector(
dtoCreate(offset(7), 7L, "#7"),
dtoCreate(offset(7), 7L, "#7"), // duplicate id
dtoCreate(offset(7), 7L, hashCid("#7")),
dtoCreate(offset(7), 7L, hashCid("#7")), // duplicate id
)
executeSql(backend.parameter.initializeParameters(someIdentityParams))
@ -30,8 +30,8 @@ private[backend] trait StorageBackendTestsIntegrity extends Matchers with Storag
it should "find non-consecutive event ids" in {
val updates = Vector(
dtoCreate(offset(1), 1L, "#1"),
dtoCreate(offset(3), 3L, "#3"), // non-consecutive id
dtoCreate(offset(1), 1L, hashCid("#1")),
dtoCreate(offset(3), 3L, hashCid("#3")), // non-consecutive id
)
executeSql(backend.parameter.initializeParameters(someIdentityParams))
@ -45,11 +45,11 @@ private[backend] trait StorageBackendTestsIntegrity extends Matchers with Storag
it should "not find errors beyond the ledger end" in {
val updates = Vector(
dtoCreate(offset(1), 1L, "#1"),
dtoCreate(offset(2), 2L, "#2"),
dtoCreate(offset(7), 7L, "#7"), // beyond the ledger end
dtoCreate(offset(7), 7L, "#7"), // duplicate id (beyond ledger end)
dtoCreate(offset(9), 9L, "#9"), // non-consecutive id (beyond ledger end)
dtoCreate(offset(1), 1L, hashCid("#1")),
dtoCreate(offset(2), 2L, hashCid("#2")),
dtoCreate(offset(7), 7L, hashCid("#7")), // beyond the ledger end
dtoCreate(offset(7), 7L, hashCid("#7")), // duplicate id (beyond ledger end)
dtoCreate(offset(9), 9L, hashCid("#9")), // non-consecutive id (beyond ledger end)
)
executeSql(backend.parameter.initializeParameters(someIdentityParams))

View File

@ -6,7 +6,6 @@ package com.daml.platform.store.backend
import java.sql.Connection
import com.daml.lf.data.Ref
import com.daml.platform.store.appendonlydao.events.ContractId
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers
@ -17,13 +16,15 @@ private[backend] trait StorageBackendTestsMigrationPruning
import StorageBackendTestValues._
private val cid = hashCid("#1")
it should "prune all divulgence events if pruning offset is after migration offset" in {
val divulgee = Ref.Party.assertFromString("divulgee")
val submitter = Ref.Party.assertFromString("submitter")
val create = dtoCreate(offset(1), 1L, "#1", submitter)
val divulgence = dtoDivulgence(None, 2L, "#1", submitter, divulgee)
val archive = dtoExercise(offset(2), 3L, consuming = true, "#1", submitter)
val create = dtoCreate(offset(1), 1L, cid, submitter)
val divulgence = dtoDivulgence(None, 2L, cid, submitter, divulgee)
val archive = dtoExercise(offset(2), 3L, consuming = true, cid, submitter)
executeSql(backend.parameter.initializeParameters(someIdentityParams))
executeSql(ingest(Vector(create, divulgence, archive), _))
@ -34,7 +35,7 @@ private[backend] trait StorageBackendTestsMigrationPruning
val beforePruning = executeSql(
backend.contract.activeContractWithoutArgument(
Set(divulgee),
ContractId.assertFromString("#1"),
cid,
)
)
@ -70,7 +71,7 @@ private[backend] trait StorageBackendTestsMigrationPruning
val afterPruning = executeSql(
backend.contract.activeContractWithoutArgument(
Set(divulgee),
ContractId.assertFromString("#1"),
cid,
)
)

View File

@ -4,7 +4,6 @@
package com.daml.platform.store.backend
import com.daml.lf.data.Ref
import com.daml.platform.store.appendonlydao.events.ContractId
import com.daml.platform.store.backend.EventStorageBackend.{FilterParams, RangeParams}
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers
@ -83,7 +82,7 @@ private[backend] trait StorageBackendTestsPruning extends Matchers with StorageB
val create = dtoCreate(
offset = offset(1),
eventSequentialId = 1L,
contractId = "#1",
contractId = hashCid("#1"),
signatory = someParty,
)
val createFilter1 = DbDto.CreateFilter(1L, someTemplateId.toString, "signatory")
@ -93,7 +92,7 @@ private[backend] trait StorageBackendTestsPruning extends Matchers with StorageB
offset = offset(2),
eventSequentialId = 2L,
consuming = true,
contractId = "#1",
contractId = hashCid("#1"),
signatory = someParty,
)
val range = RangeParams(0L, 2L, None, None)
@ -168,7 +167,7 @@ private[backend] trait StorageBackendTestsPruning extends Matchers with StorageB
val create = dtoCreate(
offset = offset(2),
eventSequentialId = 1L,
contractId = "#1",
contractId = hashCid("#1"),
signatory = someParty,
)
val createFilter1 = DbDto.CreateFilter(1L, someTemplateId.toString, "signatory")
@ -243,8 +242,8 @@ private[backend] trait StorageBackendTestsPruning extends Matchers with StorageB
it should "prune all retroactively and immediately divulged contracts (if pruneAllDivulgedContracts is set)" in {
val partyName = "party"
val divulgee = Ref.Party.assertFromString(partyName)
val contract1_id = "#1"
val contract2_id = "#2"
val contract1_id = hashCid("#1")
val contract2_id = hashCid("#2")
val contract1_immediateDivulgence = dtoCreate(
offset = offset(1),
@ -287,13 +286,13 @@ private[backend] trait StorageBackendTestsPruning extends Matchers with StorageB
val contract1_beforePruning = executeSql(
backend.contract.activeContractWithoutArgument(
Set(divulgee),
ContractId.assertFromString(contract1_id),
contract1_id,
)
)
val contract2_beforePruning = executeSql(
backend.contract.activeContractWithoutArgument(
Set(divulgee),
ContractId.assertFromString(contract2_id),
contract2_id,
)
)
executeSql(
@ -305,13 +304,13 @@ private[backend] trait StorageBackendTestsPruning extends Matchers with StorageB
val contract1_afterPruning = executeSql(
backend.contract.activeContractWithoutArgument(
Set(divulgee),
ContractId.assertFromString(contract1_id),
contract1_id,
)
)
val contract2_afterPruning = executeSql(
backend.contract.activeContractWithoutArgument(
Set(divulgee),
ContractId.assertFromString(contract2_id),
contract2_id,
)
)
@ -327,8 +326,8 @@ private[backend] trait StorageBackendTestsPruning extends Matchers with StorageB
it should "only prune retroactively divulged contracts if there exists an associated consuming exercise (if pruneAllDivulgedContracts is not set)" in {
val signatory = "signatory"
val divulgee = Ref.Party.assertFromString("party")
val contract1_id = "#1"
val contract2_id = "#2"
val contract1_id = hashCid("#1")
val contract2_id = hashCid("#2")
val contract1_create = dtoCreate(
offset = offset(1),
@ -376,13 +375,13 @@ private[backend] trait StorageBackendTestsPruning extends Matchers with StorageB
val contract1_beforePruning = executeSql(
backend.contract.activeContractWithoutArgument(
Set(divulgee),
ContractId.assertFromString(contract1_id),
contract1_id,
)
)
val contract2_beforePruning = executeSql(
backend.contract.activeContractWithoutArgument(
Set(divulgee),
ContractId.assertFromString(contract2_id),
contract2_id,
)
)
executeSql(
@ -394,13 +393,13 @@ private[backend] trait StorageBackendTestsPruning extends Matchers with StorageB
val contract1_afterPruning = executeSql(
backend.contract.activeContractWithoutArgument(
Set(divulgee),
ContractId.assertFromString(contract1_id),
contract1_id,
)
)
val contract2_afterPruning = executeSql(
backend.contract.activeContractWithoutArgument(
Set(divulgee),
ContractId.assertFromString(contract2_id),
contract2_id,
)
)

View File

@ -54,12 +54,12 @@ private[backend] trait StorageBackendTestsReset extends Matchers with StorageBac
dtoPackage(offset(3)),
dtoPackageEntry(offset(3)),
// 4: transaction with create node
dtoCreate(offset(4), 1L, "#4"),
dtoCreate(offset(4), 1L, hashCid("#4")),
DbDto.CreateFilter(1L, someTemplateId.toString, someParty.toString),
dtoCompletion(offset(4)),
// 5: transaction with exercise node and retroactive divulgence
dtoExercise(offset(5), 2L, true, "#4"),
dtoDivulgence(Some(offset(5)), 3L, "#4"),
dtoExercise(offset(5), 2L, true, hashCid("#4")),
dtoDivulgence(Some(offset(5)), 3L, hashCid("#4")),
dtoCompletion(offset(5)),
)

View File

@ -21,11 +21,11 @@ private[backend] trait StorageBackendTestsTimestamps extends Matchers with Stora
it should "correctly read ledger effective time using maximumLedgerTime" in {
val let = timestampFromInstant(Instant.now)
val cid = com.daml.lf.value.Value.ContractId.V0.assertFromString("#1")
val cid = hashCid("#1")
val create = dtoCreate(
offset = offset(1),
eventSequentialId = 1L,
contractId = cid.coid,
contractId = cid,
ledgerEffectiveTime = Some(let),
)
@ -49,11 +49,11 @@ private[backend] trait StorageBackendTestsTimestamps extends Matchers with Stora
it should "correctly read ledger effective time using rawEvents" in {
val let = timestampFromInstant(Instant.now)
val cid = com.daml.lf.value.Value.ContractId.V0.assertFromString("#1")
val cid = hashCid("#1")
val create = dtoCreate(
offset = offset(1),
eventSequentialId = 1L,
contractId = cid.coid,
contractId = cid,
ledgerEffectiveTime = Some(let),
)

View File

@ -3,6 +3,7 @@
package com.daml.platform.store.dao
import com.daml.lf.crypto.Hash
import com.daml.lf.data.Time.Timestamp
import java.util.UUID
@ -164,7 +165,7 @@ private[dao] trait JdbcLedgerDaoContractsSpec extends LoneElement with Inside wi
}
it should "prevent retrieving the maximum ledger time if some contracts are not found" in {
val randomContractId = ContractId.assertFromString(s"#random-${UUID.randomUUID}")
val randomContractId = ContractId.V1(Hash.hashPrivateKey(UUID.randomUUID.toString))
for {
failure <- contractsReader.lookupMaximumLedgerTime(Set(randomContractId)).failed
} yield {
@ -184,7 +185,7 @@ private[dao] trait JdbcLedgerDaoContractsSpec extends LoneElement with Inside wi
}
it should "allow the retrieval of the maximum ledger time even when there are divulged contracts" in {
val divulgedContractId = ContractId.assertFromString(s"#divulged-${UUID.randomUUID}")
val divulgedContractId = ContractId.V1(Hash.hashPrivateKey(UUID.randomUUID.toString))
for {
// Some contract divulged (its create node was not witnessed by any party on this participant)
(_, _) <- storeCommitedContractDivulgence(
@ -221,7 +222,7 @@ private[dao] trait JdbcLedgerDaoContractsSpec extends LoneElement with Inside wi
}
it should "allow the retrieval of the maximum ledger time even when there are only divulged contracts" in {
val divulgedContractId = ContractId.assertFromString(s"#divulged-${UUID.randomUUID}")
val divulgedContractId = ContractId.V1(Hash.hashPrivateKey(UUID.randomUUID.toString))
for {
// Some contract divulged (its create node was not witnessed by any party on this participant)
(_, _) <- storeCommitedContractDivulgence(

View File

@ -7,6 +7,7 @@ import java.util.UUID
import com.codahale.metrics.MetricRegistry
import com.daml.ledger.resources.ResourceOwner
import com.daml.lf.crypto.Hash
import com.daml.lf.data.Ref
import com.daml.lf.transaction.BlindingInfo
import com.daml.lf.value.Value.ContractId
@ -191,8 +192,8 @@ private[dao] trait JdbcLedgerDaoPostCommitValidationSpec extends LoneElement {
it should "be able to use divulged contract in later transaction" in {
val divulgedContractId =
ContractId.assertFromString(s"#${UUID.randomUUID}")
val divulgedContractId: ContractId =
ContractId.V1(Hash.hashPrivateKey(UUID.randomUUID.toString))
val divulgedContracts =
Map((divulgedContractId, someVersionedContractInstance) -> Set(alice))

View File

@ -16,6 +16,7 @@ import com.daml.ledger.participant.state.index.v2
import com.daml.ledger.participant.state.{v2 => state}
import com.daml.ledger.test.ModelTestDar
import com.daml.lf.archive.DarParser
import com.daml.lf.crypto.Hash
import com.daml.lf.data.Ref.{Identifier, Party}
import com.daml.lf.data.Time.Timestamp
import com.daml.lf.data.{FrontStack, ImmArray, Ref, Time}
@ -134,7 +135,7 @@ private[dao] trait JdbcLedgerDaoSuite extends JdbcLedgerDaoBackend {
),
)
protected final val someChoiceResult =
LfValue.ValueContractId(ContractId.V0.assertFromString("#1"))
LfValue.ValueContractId(ContractId.V1(Hash.hashPrivateKey("#1")))
protected final def someContractKey(party: Party, value: String): LfValue.ValueRecord =
LfValue.ValueRecord(

View File

@ -72,7 +72,7 @@ class ApiSubmissionServiceSpec
val (signatories, observers) = informeesOfNode.splitAt(2)
builder.add(
builder.create(
s"#contractId$i",
Value.ContractId.V1(Hash.hashPrivateKey(i.toString)).coid,
"test:test",
Value.ValueNil,
signatories.toSeq,
@ -199,7 +199,7 @@ class ApiSubmissionServiceSpec
val builder = TransactionBuilder()
builder.add(
builder.create(
s"#contractId1",
"00" + "00" * 32 + "01",
"test:test",
Value.ValueNil,
Seq(party),
@ -244,7 +244,9 @@ class ApiSubmissionServiceSpec
val errorsToExpectedStatuses: Seq[(ErrorCause, Status)] = List(
ErrorCause.DamlLf(
LfError.Interpretation(
LfError.Interpretation.DamlException(LfInterpretationError.ContractNotFound("#cid")),
LfError.Interpretation.DamlException(
LfInterpretationError.ContractNotFound("00" + "00" * 32)
),
None,
)
) -> ((Status.ABORTED, Status.NOT_FOUND)),

View File

@ -10,6 +10,7 @@ import akka.stream.scaladsl.Source
import akka.stream.{Materializer, QueueOfferResult}
import ch.qos.logback.classic.Level
import com.daml.ledger.offset.Offset
import com.daml.lf.crypto.Hash
import com.daml.lf.data.Ref
import com.daml.lf.data.Time.Timestamp
import com.daml.lf.transaction.{TransactionVersion, Versioned}
@ -197,7 +198,7 @@ final class BuffersUpdaterSpec
}
"convert TransactionLogUpdate.Transaction to a series of ContractStateEvent (created/archived)" in {
val createdCid = ContractId.assertFromString("#createdCid")
val createdCid = ContractId.V1(Hash.hashPrivateKey("createdCid"))
val createdOffset = Offset.fromByteArray(BigInt(1337L).toByteArray)
val createdEventSeqId = 9876L
val createdLedgerEffectiveTime = Timestamp.assertFromLong(987654321L)
@ -208,7 +209,7 @@ final class BuffersUpdaterSpec
val createArgument = Versioned(TransactionVersion.VDev, ValueText("arg"))
val createAgreement = "agreement"
val exercisedCid = ContractId.assertFromString("#exercisedCid")
val exercisedCid = ContractId.V1(Hash.hashPrivateKey("exercisedCid"))
val exercisedKey = Versioned(TransactionVersion.VDev, ValueInt64(8974L))
val exercisedTemplateId = Ref.Identifier.assertFromString("exercised:template:id")
val exercisedFlatEventWitnesses = Set("bob", "dan")

View File

@ -3,6 +3,7 @@
package com.daml.platform.index
import com.daml.lf.crypto.Hash
import com.daml.lf.data.Ref
import com.daml.lf.value.Value
import com.daml.ledger.api.domain.{Filters, InclusiveFilters, TransactionFilter}
@ -19,7 +20,7 @@ final class EventFilterSpec extends AnyWordSpec with Matchers with ScalaFutures
private val otherPartyWhoSeesEvents = Ref.Party.assertFromString("otherParty")
private val packageId = "myPackage"
private val eventId = Ref.LedgerString.assertFromString("someEventId")
private val contractId = Value.ContractId.assertFromString("#someContractId")
private val contractId = Value.ContractId.V1(Hash.hashPrivateKey("someContractId"))
private val party1 = Ref.Party.assertFromString("party1")
private val party2 = Ref.Party.assertFromString("party2")
private val module1 = "module1"

View File

@ -7,6 +7,7 @@ import com.daml.ledger.api.domain.LedgerOffset
import com.daml.ledger.api.v1.event.{ArchivedEvent, CreatedEvent, Event, ExercisedEvent}
import com.daml.ledger.api.v1.transaction.TreeEvent
import com.daml.ledger.api.v1.{value => v}
import com.daml.lf.crypto.Hash
import com.daml.lf.data.Ref.LedgerString
import com.daml.lf.data.Time.Timestamp
import com.daml.lf.data.{ImmArray, Ref}
@ -129,14 +130,15 @@ final class TransactionConversionSpec extends AnyWordSpec with Matchers {
)
"remove rollback nodes" in {
def cid(s: String): String = Value.ContractId.V1(Hash.hashPrivateKey(s)).coid
val builder = TransactionBuilder()
builder.add(create(builder, "#1"))
val rollbackParent = builder.add(exercise(builder, "#0"))
builder.add(create(builder, cid("#1")))
val rollbackParent = builder.add(exercise(builder, cid("#0")))
val rollback = builder.add(builder.rollback(), rollbackParent)
builder.add(create(builder, "#2"), rollback)
builder.add(exercise(builder, "#1"), rollback)
val ex = builder.add(exercise(builder, "#1"))
builder.add(create(builder, "#3"), ex)
builder.add(create(builder, cid("#2")), rollback)
builder.add(exercise(builder, cid("#1")), rollback)
val ex = builder.add(exercise(builder, cid("#1")))
builder.add(create(builder, cid("#3")), ex)
val transactionEntry = toEntry(builder.buildCommitted())
TransactionConversion
.ledgerEntryToTransactionTree(
@ -147,10 +149,10 @@ final class TransactionConversionSpec extends AnyWordSpec with Matchers {
)
.get
.eventsById shouldBe Map(
"#transactionId:0" -> createdEv("0", "#1"),
"#transactionId:1" -> exercisedEv("1", "#0", Seq.empty),
"#transactionId:5" -> exercisedEv("5", "#1", Seq("6")),
"#transactionId:6" -> createdEv("6", "#3"),
"#transactionId:0" -> createdEv("0", cid("#1")),
"#transactionId:1" -> exercisedEv("1", cid("#0"), Seq.empty),
"#transactionId:5" -> exercisedEv("5", cid("#1"), Seq("6")),
"#transactionId:6" -> createdEv("6", cid("#3")),
)
}
}

View File

@ -10,10 +10,10 @@ import com.daml.error.{
}
import com.daml.ledger.api.domain
import com.daml.ledger.api.domain.RejectionReason
import com.daml.lf.crypto.Hash
import com.daml.lf.data.Ref
import com.daml.lf.transaction.GlobalKey
import com.daml.lf.value.Value
import com.daml.lf.value.Value.ValueText
import com.daml.lf.value.Value.{ContractId, ValueText}
import com.daml.logging.{ContextualizedLogger, LoggingContext}
import com.daml.platform.server.api.validation.ErrorFactories
import com.daml.platform.store.Conversions._
@ -33,6 +33,8 @@ class ConversionsSpec extends AsyncWordSpec with Matchers {
None,
)
private def cid(key: String): ContractId = ContractId.V1(Hash.hashPrivateKey(key))
"converting rejection reasons" should {
"convert an 'Inconsistent' rejection reason" in {
assertConversion(domain.RejectionReason.Inconsistent("This was not very consistent."))(
@ -53,17 +55,17 @@ class ConversionsSpec extends AsyncWordSpec with Matchers {
}
"convert an 'InconsistentContractKeys' rejection reason" in {
val cId = "#cId1"
val cId = cid("#cId1")
assertConversion(
domain.RejectionReason
.InconsistentContractKeys(Some(Value.ContractId.assertFromString(cId)), None)
.InconsistentContractKeys(Some(cId), None)
)(
v1expectedCode = Status.Code.ABORTED.value(),
v1expectedMessage =
s"Inconsistent: Contract key lookup with different results: expected [Some(ContractId($cId))], actual [$None]",
s"Inconsistent: Contract key lookup with different results: expected [Some($cId)], actual [$None]",
v2expectedCode = Status.Code.FAILED_PRECONDITION.value(),
v2expectedMessage =
s"INCONSISTENT_CONTRACT_KEY(9,0): Contract key lookup with different results: expected [Some(ContractId($cId))], actual [$None]",
s"INCONSISTENT_CONTRACT_KEY(9,0): Contract key lookup with different results: expected [Some($cId)], actual [$None]",
)
}

View File

@ -5,6 +5,7 @@ package com.daml.platform.store.appendonlydao.events
import com.daml.ledger.api.domain.PartyDetails
import com.daml.ledger.offset.Offset
import com.daml.lf.crypto.Hash
import com.daml.lf.data.Ref
import com.daml.lf.data.Time.Timestamp
import com.daml.lf.transaction.GlobalKey
@ -523,7 +524,7 @@ object PostCommitValidationSpec {
private def genTestCreate(): Create =
txBuilder.create(
id = s"#${UUID.randomUUID}",
id = ContractId.V1(Hash.hashPrivateKey(UUID.randomUUID.toString)),
templateId = "bar:baz",
argument = TxBuilder.record("field" -> "value"),
signatories = Set("Alice"),

View File

@ -13,6 +13,7 @@ import akka.stream.{BoundedSourceQueue, Materializer}
import com.codahale.metrics.MetricRegistry
import com.daml.ledger.offset.Offset
import com.daml.ledger.resources.ResourceContext
import com.daml.lf.crypto.Hash
import com.daml.lf.data.ImmArray
import com.daml.lf.data.Time.Timestamp
import com.daml.lf.transaction.GlobalKey
@ -551,7 +552,7 @@ object MutableCacheBackedContractStoreSpec {
}
private def contractId(id: Int): ContractId =
ContractId.assertFromString(s"#contract-$id")
ContractId.V1(Hash.hashPrivateKey(id.toString))
private def globalKey(desc: String): Key =
GlobalKey.assertBuild(Identifier.assertFromString(s"some:template:$desc"), ValueText(desc))

View File

@ -24,8 +24,6 @@ import org.scalatest.wordspec.AnyWordSpec
class KeyValueCommittingSpec extends AnyWordSpec with Matchers {
import TransactionBuilder.Implicits._
private val metrics: Metrics = new Metrics(new MetricRegistry)
private val keyValueSubmission = new KeyValueSubmission(metrics)
@ -64,7 +62,7 @@ class KeyValueCommittingSpec extends AnyWordSpec with Matchers {
private def toSubmission(builder: TransactionBuilder): DamlSubmission =
this.toSubmission(builder.buildSubmitted())
private val contractId = "#1"
private val contractId = Value.ContractId.V1(crypto.Hash.hashPrivateKey("#1"))
private val dedupKey = DamlStateKey.newBuilder
.setCommandDedup(

View File

@ -70,7 +70,7 @@ class CommitterModelConformanceValidatorSpec
keyAndMaintainer = Some(inputContractKey -> inputContractKeyMaintainer),
)
private val aCreate = create(aContractId)
private val anotherCreate = create("#anotherContractId")
private val anotherCreate = create(ContractId.V1(Hash.hashPrivateKey("#anotherContractId")))
private val exercise = txBuilder.exercise(
contract = inputCreate,
@ -247,7 +247,7 @@ class CommitterModelConformanceValidatorSpec
)
val contractInstance = defaultValidator.lookupContract(commitContext)(
Conversions.decodeContractId(inputContractId)
Conversions.decodeContractId(inputContractId.coid)
)
contractInstance shouldBe Some(aContractInst)
@ -259,7 +259,7 @@ class CommitterModelConformanceValidatorSpec
None,
Map.empty,
)
)(Conversions.decodeContractId(inputContractId))
)(Conversions.decodeContractId(inputContractId.coid))
}
}
@ -272,7 +272,7 @@ class CommitterModelConformanceValidatorSpec
"return Some when mapping exists" in {
defaultValidator.lookupKey(contractKeyInputs)(
aGlobalKeyWithMaintainers(inputContractKey, inputContractKeyMaintainer)
) shouldBe Some(Conversions.decodeContractId(inputContractId))
) shouldBe Some(Conversions.decodeContractId(inputContractId.coid))
}
"return None when mapping does not exist" in {
@ -400,10 +400,10 @@ class CommitterModelConformanceValidatorSpec
object CommitterModelConformanceValidatorSpec {
private val inputContractId = "#inputContractId"
private val inputContractIdStateKey = makeContractIdStateKey(inputContractId)
private val aContractId = "#someContractId"
private val contractIdStateKey1 = makeContractIdStateKey(aContractId)
private val inputContractId = ContractId.V1(Hash.hashPrivateKey("#inputContractId"))
private val inputContractIdStateKey = makeContractIdStateKey(inputContractId.coid)
private val aContractId = ContractId.V1(Hash.hashPrivateKey("#someContractId"))
private val contractIdStateKey1 = makeContractIdStateKey(aContractId.coid)
private val inputContractKey = "inputContractKey"
private val inputContractKeyMaintainer = "inputContractKeyMaintainer"
private val aKey = "key"

View File

@ -32,6 +32,7 @@ import com.daml.ledger.participant.state.kvutils.store.{
DamlStateValue,
}
import com.daml.ledger.validator.TestHelper.{makeContractIdStateKey, makeContractIdStateValue}
import com.daml.lf.crypto.Hash
import com.daml.lf.data.{ImmArray, Ref}
import com.daml.lf.transaction.SubmittedTransaction
import com.daml.lf.transaction.test.TransactionBuilder
@ -56,7 +57,7 @@ class TransactionConsistencyValidatorSpec extends AnyWordSpec with Matchers {
private val txBuilder = TransactionBuilder()
private val conflictingKey = {
val aCreateNode = newCreateNodeWithFixedKey("#dummy")
val aCreateNode = newCreateNodeWithFixedKey(Value.ContractId.V1(Hash.hashPrivateKey("#dummy")))
Conversions.encodeContractKey(aCreateNode.templateId, aCreateNode.key.get.key)
}
@ -101,8 +102,8 @@ class TransactionConsistencyValidatorSpec extends AnyWordSpec with Matchers {
"return DuplicateKeys when two local contracts conflict" in {
val builder = TransactionBuilder()
builder.add(newCreateNodeWithFixedKey(s"#$freshContractId"))
builder.add(newCreateNodeWithFixedKey(s"#$freshContractId"))
builder.add(newCreateNodeWithFixedKey(freshContractId))
builder.add(newCreateNodeWithFixedKey(freshContractId))
val transaction = builder.buildSubmitted()
val context = commitContextWithContractStateKeys(conflictingKey -> None)
@ -116,9 +117,9 @@ class TransactionConsistencyValidatorSpec extends AnyWordSpec with Matchers {
"return DuplicateKeys when a local contract conflicts with a global contract" in {
val builder = TransactionBuilder()
builder.add(newCreateNodeWithFixedKey(s"#$freshContractId"))
builder.add(newCreateNodeWithFixedKey(freshContractId))
val transaction = builder.buildSubmitted()
val context = commitContextWithContractStateKeys(conflictingKey -> Some(s"#$freshContractId"))
val context = commitContextWithContractStateKeys(conflictingKey -> Some(freshContractId.coid))
val result = validate(context, transaction)
result shouldBe a[StepStop]
val rejectionReason =
@ -127,31 +128,31 @@ class TransactionConsistencyValidatorSpec extends AnyWordSpec with Matchers {
}
"succeeds when a global contract gets archived before a local contract gets created" in {
val globalCid = s"#$freshContractId"
val globalCid = freshContractId
val globalCreate = newCreateNodeWithFixedKey(globalCid)
val context = createCommitContext(
recordTime = None,
inputs = Map(
makeContractIdStateKey(globalCid) -> Some(makeContractIdStateValue()),
contractStateKey(conflictingKey) -> Some(contractKeyStateValue(globalCid)),
makeContractIdStateKey(globalCid.coid) -> Some(makeContractIdStateValue()),
contractStateKey(conflictingKey) -> Some(contractKeyStateValue(globalCid.coid)),
),
)
val builder = TransactionBuilder()
builder.add(archive(globalCreate, Set("Alice")))
builder.add(newCreateNodeWithFixedKey(s"#$freshContractId"))
builder.add(newCreateNodeWithFixedKey(freshContractId))
val transaction = builder.buildSubmitted()
val result = validate(context, transaction)
result shouldBe a[StepContinue[_]]
}
"succeeds when a local contract gets archived before another local contract gets created" in {
val localCid = s"#$freshContractId"
val localCid = freshContractId
val context = commitContextWithContractStateKeys(conflictingKey -> None)
val builder = TransactionBuilder()
val localCreate = newCreateNodeWithFixedKey(localCid)
builder.add(localCreate)
builder.add(archive(localCreate, Set("Alice")))
builder.add(newCreateNodeWithFixedKey(s"#$freshContractId"))
builder.add(newCreateNodeWithFixedKey(freshContractId))
val transaction = builder.buildSubmitted()
val result = validate(context, transaction)
result shouldBe a[StepContinue[_]]
@ -160,9 +161,9 @@ class TransactionConsistencyValidatorSpec extends AnyWordSpec with Matchers {
"return DuplicateKeys when a create in a rollback conflicts with a global key" in {
val builder = TransactionBuilder()
val rollback = builder.add(builder.rollback())
builder.add(newCreateNodeWithFixedKey(s"#$freshContractId"), rollback)
builder.add(newCreateNodeWithFixedKey(freshContractId), rollback)
val transaction = builder.buildSubmitted()
val context = commitContextWithContractStateKeys(conflictingKey -> Some(s"#$freshContractId"))
val context = commitContextWithContractStateKeys(conflictingKey -> Some(freshContractId.coid))
val result = validate(context, transaction)
result shouldBe a[StepStop]
@ -175,8 +176,8 @@ class TransactionConsistencyValidatorSpec extends AnyWordSpec with Matchers {
"not return DuplicateKeys between local contracts if first create is rolled back" in {
val builder = TransactionBuilder()
val rollback = builder.add(builder.rollback())
builder.add(newCreateNodeWithFixedKey(s"#$freshContractId"), rollback)
builder.add(newCreateNodeWithFixedKey(s"#$freshContractId"))
builder.add(newCreateNodeWithFixedKey(freshContractId), rollback)
builder.add(newCreateNodeWithFixedKey(freshContractId))
val transaction = builder.buildSubmitted()
@ -187,9 +188,9 @@ class TransactionConsistencyValidatorSpec extends AnyWordSpec with Matchers {
"return DuplicateKeys between local contracts even if second create is rolled back" in {
val builder = TransactionBuilder()
builder.add(newCreateNodeWithFixedKey(s"#$freshContractId"))
builder.add(newCreateNodeWithFixedKey(freshContractId))
val rollback = builder.add(builder.rollback())
builder.add(newCreateNodeWithFixedKey(s"#$freshContractId"), rollback)
builder.add(newCreateNodeWithFixedKey(freshContractId), rollback)
val transaction = builder.buildSubmitted()
val context = commitContextWithContractStateKeys(conflictingKey -> None)
@ -203,11 +204,11 @@ class TransactionConsistencyValidatorSpec extends AnyWordSpec with Matchers {
"return DuplicateKeys between local contracts even if the first one was archived in a rollback" in {
val builder = TransactionBuilder()
val create = newCreateNodeWithFixedKey(s"#$freshContractId")
val create = newCreateNodeWithFixedKey(freshContractId)
builder.add(create)
val rollback = builder.add(builder.rollback())
builder.add(archive(create, Set("Alice")), rollback)
builder.add(newCreateNodeWithFixedKey(s"#$freshContractId"))
builder.add(newCreateNodeWithFixedKey(freshContractId))
val transaction = builder.buildSubmitted()
val context = commitContextWithContractStateKeys(conflictingKey -> None)
@ -221,12 +222,12 @@ class TransactionConsistencyValidatorSpec extends AnyWordSpec with Matchers {
"return InconsistentKeys on conflict local and global contracts even if global was archived in a rollback" in {
val builder = TransactionBuilder()
val globalCid = s"#$freshContractId"
val globalCid = freshContractId
val rollback = builder.add(builder.rollback())
builder.add(archive(globalCid, Set("Alice")), rollback)
builder.add(newCreateNodeWithFixedKey(s"#$freshContractId"))
builder.add(newCreateNodeWithFixedKey(freshContractId))
val transaction = builder.buildSubmitted()
val context = commitContextWithContractStateKeys(conflictingKey -> Some(globalCid))
val context = commitContextWithContractStateKeys(conflictingKey -> Some(globalCid.coid))
val result = validate(context, transaction)
result shouldBe a[StepStop]
@ -239,12 +240,12 @@ class TransactionConsistencyValidatorSpec extends AnyWordSpec with Matchers {
}
"fail if a contract is not active anymore" in {
val globalCid = s"#$freshContractId"
val globalCid = freshContractId
val globalCreate = newCreateNodeWithFixedKey(globalCid)
val context = createCommitContext(
recordTime = None,
inputs = Map(
makeContractIdStateKey(globalCid) -> Some(
makeContractIdStateKey(globalCid.coid) -> Some(
makeContractIdStateValue().toBuilder
.setContractState(
DamlContractState.newBuilder().setArchivedAt(Timestamp.getDefaultInstance)
@ -268,7 +269,7 @@ class TransactionConsistencyValidatorSpec extends AnyWordSpec with Matchers {
inRollback: Boolean,
): SubmittedTransaction = {
val lookup =
txBuilder.lookupByKey(newCreateNodeWithFixedKey(contractId = s"#$freshContractId"), found)
txBuilder.lookupByKey(newCreateNodeWithFixedKey(contractId = freshContractId), found)
val builder = TransactionBuilder()
if (inRollback) {
val rollback = builder.add(txBuilder.rollback())
@ -279,7 +280,7 @@ class TransactionConsistencyValidatorSpec extends AnyWordSpec with Matchers {
builder.buildSubmitted()
}
private def newCreateNodeWithFixedKey(contractId: String): Node.Create =
private def newCreateNodeWithFixedKey(contractId: Value.ContractId): Node.Create =
create(contractId, signatories = Set("Alice"), keyAndMaintainer = Some(aKey -> "Alice"))
private def create(
@ -326,8 +327,8 @@ object TransactionConsistencyValidatorSpec {
private val aKey = "key"
private val aDummyValue = TransactionBuilder.record("field" -> "value")
private def freshContractId: String =
s"testContractId-${UUID.randomUUID().toString.take(10)}"
private def freshContractId: Value.ContractId =
Value.ContractId.V1(Hash.hashPrivateKey(UUID.randomUUID.toString))
private def commitContextWithContractStateKeys(
contractKeyIdPairs: (DamlContractKey, Option[String])*

View File

@ -107,8 +107,8 @@ final class StateUpdateComparisonSpec
private def buildATransaction(withFetchAndLookupByKeyNodes: Boolean): CommittedTransaction = {
val builder = TransactionBuilder()
val create1 = create("#someContractId")
val create2 = create("#otherContractId")
val create1 = create(ContractId.V1(crypto.Hash.hashPrivateKey("#someContractId")))
val create2 = create(ContractId.V1(crypto.Hash.hashPrivateKey("#otherContractId")))
val fetch1 = builder.fetch(create1)
val lookup1 = builder.lookupByKey(create1, found = true)
val fetch2 = builder.fetch(create2)

View File

@ -384,7 +384,7 @@ final class SandboxServer(
maxDeduplicationDurationEnforced = false,
),
contractIdFeatures = ExperimentalContractIds.of(
v0 = ExperimentalContractIds.ContractIdV0Support.SUPPORTED,
v0 = ExperimentalContractIds.ContractIdV0Support.NOT_SUPPORTED,
v1 = ExperimentalContractIds.ContractIdV1Support.NON_SUFFIXED,
),
),

View File

@ -260,7 +260,7 @@ object SandboxOnXRunner {
maxDeduplicationDurationEnforced = false,
),
contractIdFeatures = ExperimentalContractIds.of(
v0 = ExperimentalContractIds.ContractIdV0Support.SUPPORTED,
v0 = ExperimentalContractIds.ContractIdV0Support.NOT_SUPPORTED,
v1 = ExperimentalContractIds.ContractIdV1Support.NON_SUFFIXED,
),
),

View File

@ -227,7 +227,7 @@ object ConflictCheckWithCommittedSpec {
private val offsetString = Ref.HexString.assertFromString("ab")
private val offset = Offset.fromHexString(offsetString)
private def cid(i: Int): Value.ContractId = Value.ContractId.V0.assertFromString(s"#$i")
private def cid(i: Int): Value.ContractId = Value.ContractId.V1(Hash.hashPrivateKey(i.toString))
private def contractKey(idx: Long) = GlobalKey.assertBuild(
templateId = templateId,
key = Value.ValueInt64(idx),

View File

@ -39,6 +39,8 @@ class PrepareSubmissionSpec extends AsyncFlatSpec with Matchers {
new BridgeMetrics(new Metrics(new MetricRegistry))
)
private def cid(key: String): ContractId = ContractId.V1(Hash.hashPrivateKey(key))
behavior of classOf[PrepareSubmissionImpl].getSimpleName
it should "forward the correct failure on inconsistent keys" in {
@ -48,7 +50,7 @@ class PrepareSubmissionSpec extends AsyncFlatSpec with Matchers {
val keyValue = Value.ValueText("key-1")
val createNode = txBuilder.create(
id = ContractId.assertFromString("#1"),
id = cid("#1"),
templateId = templateId,
argument = Value.ValueInt64(1),
signatories = Set.empty,
@ -60,7 +62,7 @@ class PrepareSubmissionSpec extends AsyncFlatSpec with Matchers {
val contractKey = GlobalKey.assertBuild(templateId, keyValue)
val otherCreateNode = txBuilder.create(
id = ContractId.assertFromString("#2"),
id = cid("#2"),
templateId = templateId,
argument = Value.ValueInt64(1),
signatories = Set.empty,
@ -100,7 +102,7 @@ class PrepareSubmissionSpec extends AsyncFlatSpec with Matchers {
val keyValue = Value.ValueText("key-1")
val createNode = txBuilder.create(
id = ContractId.assertFromString("#1"),
id = cid("#1"),
templateId = templateId,
argument = Value.ValueInt64(1),
signatories = Set.empty,

View File

@ -155,7 +155,7 @@ class SequenceSpec extends AnyFlatSpec with MockitoSugar with Matchers with Argu
// Reject when trying to archive a contract again
val Seq((offset4, update4)) = sequence(consume(cId(3)))
offset4 shouldBe toOffset(4L)
assertCommandRejected(update4, "Inconsistent: Could not lookup contracts: [#3]")
assertCommandRejected(update4, s"Inconsistent: Could not lookup contracts: [${cId(3).coid}]")
// Archiving a contract with an assigned key for the first time succeeds
val Seq((offset5, update5)) = sequence(consume(cId(4), Some(contractKey(2L))))
@ -167,7 +167,7 @@ class SequenceSpec extends AnyFlatSpec with MockitoSugar with Matchers with Argu
offset6 shouldBe toOffset(6L)
assertCommandRejected(
update6,
"Inconsistent: Contract key lookup with different results: expected [None], actual [Some(ContractId(#5))]",
s"Inconsistent: Contract key lookup with different results: expected [None], actual [Some(${cId(5)})]",
)
// Reject on inconsistent key usage
@ -175,7 +175,7 @@ class SequenceSpec extends AnyFlatSpec with MockitoSugar with Matchers with Argu
offset7 shouldBe toOffset(7L)
assertCommandRejected(
update7,
"Inconsistent: Contract key lookup with different results: expected [Some(ContractId(#1))], actual [Some(ContractId(#5))]",
s"Inconsistent: Contract key lookup with different results: expected [Some(${cId(1)})], actual [Some(${cId(5)})]",
)
}
@ -426,5 +426,5 @@ class SequenceSpec extends AnyFlatSpec with MockitoSugar with Matchers with Argu
GlobalKey(templateId, Value.ValueInt64(i))
}
private def cId(i: Int) = ContractId.assertFromString(s"#$i")
private def cId(i: Int) = ContractId.V1(Hash.hashPrivateKey(i.toString))
}

View File

@ -7,6 +7,7 @@ import com.codahale.metrics.MetricRegistry
import com.daml.ledger.sandbox.bridge.BridgeMetrics
import com.daml.ledger.sandbox.bridge.LedgerBridge.toOffset
import com.daml.ledger.sandbox.bridge.validate.SequencerState.SequencerQueue
import com.daml.lf.crypto.Hash
import com.daml.lf.data.Ref
import com.daml.lf.transaction.GlobalKey
import com.daml.lf.value.Value
@ -117,5 +118,5 @@ class SequencerStateSpec extends AnyFlatSpec with Matchers {
GlobalKey(templateId, Value.ValueInt64(i))
}
private def cid(i: Int) = ContractId.assertFromString(s"#$i")
private def cid(i: Int): ContractId = ContractId.V1(Hash.hashPrivateKey(i.toString))
}

View File

@ -240,7 +240,7 @@ case object DamlConstants {
("fUnit", V.ValueUnit),
("fInt64", simpleInt64V),
("fParty", V.ValueParty(DamlLfRef.Party assertFromString "BANK1")),
("fContractId", V.ValueContractId(V.ContractId.assertFromString("#C0"))),
("fContractId", V.ValueContractId(V.ContractId.assertFromString("00" + "00" * 32 + "c0"))),
("fListOfText", V.ValueList(FrontStack(V.ValueText("foo"), V.ValueText("bar")))),
("fListOfUnit", V.ValueList(FrontStack(V.ValueUnit, V.ValueUnit))),
("fDate", simpleDateV),

View File

@ -87,29 +87,29 @@
## Input Validation:
- ensure builtin operators have the correct type: [TypingSpec.scala](daml-lf/validation/src/test/scala/com/digitalasset/daml/lf/validation/TypingSpec.scala#L47)
- ensure expression forms have the correct type: [TypingSpec.scala](daml-lf/validation/src/test/scala/com/digitalasset/daml/lf/validation/TypingSpec.scala#L107)
- ill-formed create command is rejected: [CommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/CommandPreprocessorSpec.scala#L133)
- ill-formed create-and-exercise command is rejected: [CommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/CommandPreprocessorSpec.scala#L154)
- ill-formed create command is rejected: [CommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/CommandPreprocessorSpec.scala#L134)
- ill-formed create-and-exercise command is rejected: [CommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/CommandPreprocessorSpec.scala#L155)
- ill-formed exception definitions are rejected: [TypingSpec.scala](daml-lf/validation/src/test/scala/com/digitalasset/daml/lf/validation/TypingSpec.scala#L1415)
- ill-formed exercise command is rejected: [CommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/CommandPreprocessorSpec.scala#L138)
- ill-formed exercise-by-key command is rejected: [CommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/CommandPreprocessorSpec.scala#L145)
- ill-formed exercise command is rejected: [CommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/CommandPreprocessorSpec.scala#L139)
- ill-formed exercise-by-key command is rejected: [CommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/CommandPreprocessorSpec.scala#L146)
- ill-formed expressions are rejected: [TypingSpec.scala](daml-lf/validation/src/test/scala/com/digitalasset/daml/lf/validation/TypingSpec.scala#L420)
- ill-formed fetch command is rejected: [CommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/CommandPreprocessorSpec.scala#L167)
- ill-formed fetch-by-key command is rejected: [CommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/CommandPreprocessorSpec.scala#L170)
- ill-formed fetch command is rejected: [CommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/CommandPreprocessorSpec.scala#L168)
- ill-formed fetch-by-key command is rejected: [CommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/CommandPreprocessorSpec.scala#L171)
- ill-formed interfaces are rejected: [TypingSpec.scala](daml-lf/validation/src/test/scala/com/digitalasset/daml/lf/validation/TypingSpec.scala#L1308)
- ill-formed kinds are rejected: [TypingSpec.scala](daml-lf/validation/src/test/scala/com/digitalasset/daml/lf/validation/TypingSpec.scala#L19)
- ill-formed lookup command is rejected: [CommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/CommandPreprocessorSpec.scala#L175)
- ill-formed lookup command is rejected: [CommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/CommandPreprocessorSpec.scala#L176)
- ill-formed records are rejected: [TypingSpec.scala](daml-lf/validation/src/test/scala/com/digitalasset/daml/lf/validation/TypingSpec.scala#L1557)
- ill-formed templates are rejected: [TypingSpec.scala](daml-lf/validation/src/test/scala/com/digitalasset/daml/lf/validation/TypingSpec.scala#L936)
- ill-formed type synonyms applications are rejected: [TypingSpec.scala](daml-lf/validation/src/test/scala/com/digitalasset/daml/lf/validation/TypingSpec.scala#L1536)
- ill-formed type synonyms definitions are rejected: [TypingSpec.scala](daml-lf/validation/src/test/scala/com/digitalasset/daml/lf/validation/TypingSpec.scala#L1603)
- ill-formed types are rejected: [TypingSpec.scala](daml-lf/validation/src/test/scala/com/digitalasset/daml/lf/validation/TypingSpec.scala#L99)
- ill-formed variants are rejected: [TypingSpec.scala](daml-lf/validation/src/test/scala/com/digitalasset/daml/lf/validation/TypingSpec.scala#L1580)
- well formed create command is accepted: [CommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/CommandPreprocessorSpec.scala#L79)
- well formed create-and-exercise command is accepted: [CommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/CommandPreprocessorSpec.scala#L98)
- well formed exercise command is accepted: [CommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/CommandPreprocessorSpec.scala#L84)
- well formed exercise-by-key command is accepted: [CommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/CommandPreprocessorSpec.scala#L91)
- well formed fetch command is accepted: [CommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/CommandPreprocessorSpec.scala#L105)
- well formed fetch-by-key command is accepted: [CommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/CommandPreprocessorSpec.scala#L110)
- well formed lookup command is accepted: [CommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/CommandPreprocessorSpec.scala#L115)
- well formed create command is accepted: [CommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/CommandPreprocessorSpec.scala#L80)
- well formed create-and-exercise command is accepted: [CommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/CommandPreprocessorSpec.scala#L99)
- well formed exercise command is accepted: [CommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/CommandPreprocessorSpec.scala#L85)
- well formed exercise-by-key command is accepted: [CommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/CommandPreprocessorSpec.scala#L92)
- well formed fetch command is accepted: [CommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/CommandPreprocessorSpec.scala#L106)
- well formed fetch-by-key command is accepted: [CommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/CommandPreprocessorSpec.scala#L111)
- well formed lookup command is accepted: [CommandPreprocessorSpec.scala](daml-lf/engine/src/test/scala/com/digitalasset/daml/lf/engine/CommandPreprocessorSpec.scala#L116)

View File

@ -504,7 +504,6 @@ object Converter {
def apply(compiledPackages: CompiledPackages, triggerIds: TriggerIds): Converter = {
val valueTranslator = new preprocessing.ValueTranslator(
compiledPackages.interface,
forbidV0ContractId = false,
requireV1ContractIdSuffix = false,
)
Converter(