mirror of
https://github.com/digital-asset/daml.git
synced 2024-09-20 01:07:18 +03:00
Drop v0 contract ids (#12464)
* Drop v0 contract ids changelog_begin changelog_end * . changelog_begin changelog_end
This commit is contained in:
parent
c35d34db3d
commit
688f1e1e0b
@ -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,
|
||||
)
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
)
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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) =
|
||||
|
@ -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"),
|
||||
|
@ -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 =
|
||||
|
@ -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),
|
||||
|
@ -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))))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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] =
|
||||
|
@ -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(_))
|
||||
|
@ -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 =
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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"))
|
||||
|
@ -758,7 +758,6 @@ object Converter {
|
||||
valueTranslator =
|
||||
new preprocessing.ValueTranslator(
|
||||
compiledPackages.interface,
|
||||
forbidV0ContractId = false,
|
||||
requireV1ContractIdSuffix = false,
|
||||
)
|
||||
sValue <- valueTranslator
|
||||
|
@ -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()
|
||||
|
@ -47,7 +47,6 @@ class IdeLedgerClient(
|
||||
private[this] val preprocessor =
|
||||
new preprocessing.CommandPreprocessor(
|
||||
compiledPackages.interface,
|
||||
forbidV0ContractId = true,
|
||||
requireV1ContractIdSuffix = false,
|
||||
)
|
||||
|
||||
|
@ -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}
|
||||
|
||||
|
@ -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) =>
|
||||
|
@ -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\"",
|
||||
|
@ -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",
|
||||
|
@ -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
|
||||
),
|
||||
)
|
||||
|
||||
|
@ -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),
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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) =>
|
||||
|
@ -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(
|
||||
|
@ -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),
|
||||
|
@ -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)),
|
||||
)
|
||||
|
||||
|
@ -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),
|
||||
)
|
||||
|
@ -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(
|
||||
|
@ -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))
|
||||
|
@ -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,
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -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,
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -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)),
|
||||
)
|
||||
|
||||
|
@ -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),
|
||||
)
|
||||
|
||||
|
@ -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(
|
||||
|
@ -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))
|
||||
|
||||
|
@ -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(
|
||||
|
@ -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)),
|
||||
|
@ -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")
|
||||
|
@ -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"
|
||||
|
@ -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")),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -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]",
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -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"),
|
||||
|
@ -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))
|
||||
|
@ -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(
|
||||
|
@ -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"
|
||||
|
@ -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])*
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
),
|
||||
),
|
||||
|
@ -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,
|
||||
),
|
||||
),
|
||||
|
@ -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),
|
||||
|
@ -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,
|
||||
|
@ -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))
|
||||
}
|
||||
|
@ -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))
|
||||
}
|
||||
|
@ -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),
|
||||
|
@ -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)
|
||||
|
||||
|
||||
|
@ -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(
|
||||
|
Loading…
Reference in New Issue
Block a user