DAML-LF: Kill RelativeContractId (#5991)

CHANGELOG_BEGIN
CHANGELOG_END
This commit is contained in:
Remy 2020-05-25 22:30:45 +02:00 committed by GitHub
parent 9a0cce155e
commit 9e456a1016
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
121 changed files with 804 additions and 1223 deletions

View File

@ -29,12 +29,7 @@ final class Conversions(
private val ptxCoidToNodeId = machine.ptx.nodes
.collect {
case (nodeId, node: N.NodeCreate.WithTxValue[V.ContractId]) =>
node.coid match {
case acoid: V.AbsoluteContractId =>
acoid -> ledger.ptxNodeId(nodeId)
case V.RelativeContractId(_) =>
throw new IllegalArgumentException("unexpected relative contract id")
}
node.coid -> ledger.ptxNodeId(nodeId)
}
private val coidToNodeId = ledger.ledgerData.coidToNodeId ++ ptxCoidToNodeId
@ -303,18 +298,10 @@ final class Conversions(
def mkContractRef(coid: V.ContractId, templateId: Ref.Identifier): ContractRef =
ContractRef.newBuilder
.setRelative(false)
.setContractId(convertContractId(coid))
.setContractId(coidToNodeId(coid))
.setTemplateId(convertIdentifier(templateId))
.build
def convertContractId(coid: V.ContractId): String =
coid match {
case acoid: V.AbsoluteContractId =>
coidToNodeId(acoid)
case V.RelativeContractId(_) =>
throw new IllegalArgumentException("unexpected relative contract id")
}
def convertScenarioStep(
stepId: Int,
step: Ledger.ScenarioStep,
@ -422,7 +409,7 @@ final class Conversions(
.map(nodeId => builder.setParent(convertNodeId(nodeId)))
nodeInfo.node match {
case create: N.NodeCreate[V.AbsoluteContractId, Tx.Value[V.AbsoluteContractId]] =>
case create: N.NodeCreate[V.ContractId, Tx.Value[V.ContractId]] =>
val createBuilder =
Node.Create.newBuilder
.setContractInstance(
@ -436,7 +423,7 @@ final class Conversions(
create.optLocation.map(loc => builder.setLocation(convertLocation(loc)))
builder.setCreate(createBuilder.build)
case fetch: N.NodeFetch.WithTxValue[V.AbsoluteContractId] =>
case fetch: N.NodeFetch.WithTxValue[V.ContractId] =>
builder.setFetch(
Node.Fetch.newBuilder
.setContractId(coidToNodeId(fetch.coid))
@ -447,9 +434,9 @@ final class Conversions(
)
case ex: N.NodeExercises[
Ledger.ScenarioNodeId,
V.AbsoluteContractId,
V.ContractId,
Tx.Value[
V.AbsoluteContractId,
V.ContractId,
]] =>
ex.optLocation.map(loc => builder.setLocation(convertLocation(loc)))
builder.setExercise(
@ -472,7 +459,7 @@ final class Conversions(
.build,
)
case lbk: N.NodeLookupByKey[V.AbsoluteContractId, Tx.Value[V.AbsoluteContractId]] =>
case lbk: N.NodeLookupByKey[V.ContractId, Tx.Value[V.ContractId]] =>
lbk.optLocation.foreach(loc => builder.setLocation(convertLocation(loc)))
val lbkBuilder = Node.LookupByKey.newBuilder
.setTemplateId(convertIdentifier(lbk.templateId))
@ -518,7 +505,7 @@ final class Conversions(
case fetch: N.NodeFetch.WithTxValue[V.ContractId] =>
builder.setFetch(
Node.Fetch.newBuilder
.setContractId(convertContractId(fetch.coid))
.setContractId(coidToNodeId(fetch.coid))
.setTemplateId(convertIdentifier(fetch.templateId))
.addAllSignatories(fetch.signatories.map(convertParty).asJava)
.addAllStakeholders(fetch.stakeholders.map(convertParty).asJava)
@ -528,7 +515,7 @@ final class Conversions(
ex.optLocation.map(loc => builder.setLocation(convertLocation(loc)))
builder.setExercise(
Node.Exercise.newBuilder
.setTargetContractId(convertContractId(ex.targetCoid))
.setTargetContractId(coidToNodeId(ex.targetCoid))
.setTemplateId(convertIdentifier(ex.templateId))
.setChoiceId(ex.choiceId)
.setConsuming(ex.consuming)
@ -551,7 +538,7 @@ final class Conversions(
builder.setLookupByKey({
val builder = Node.LookupByKey.newBuilder
.setKeyWithMaintainers(convertKeyWithMaintainers(lookup.key))
lookup.result.foreach(cid => builder.setContractId(convertContractId(cid)))
lookup.result.foreach(cid => builder.setContractId(coidToNodeId(cid)))
builder.build
})
}
@ -633,7 +620,7 @@ final class Conversions(
tycon.foreach(x => eBuilder.setEnumId(convertIdentifier(x)))
builder.setEnum(eBuilder.build)
case V.ValueContractId(coid) =>
builder.setContractId(convertContractId(coid))
builder.setContractId(coidToNodeId(coid))
case V.ValueList(values) =>
builder.setList(
v1.List.newBuilder

View File

@ -262,7 +262,7 @@ final class Engine {
ledgerTime: Time.Timestamp,
submissionTime: Time.Timestamp,
seeding: speedy.InitialSeeding,
globalCids: Set[Value.AbsoluteContractId],
globalCids: Set[Value.ContractId],
): Result[(Tx.Transaction, Tx.Metadata)] =
runSafely(
loadPackages(commands.foldLeft(Set.empty[PackageId])(_ + _.templateId.packageId).toList)

View File

@ -92,7 +92,7 @@ final case class ExerciseEvent[Nid, Cid, Val](
exerciseResult: Option[Val])
extends Event[Nid, Cid, Val]
object Event extends value.CidContainer3WithDefaultCidResolver[Event] {
object Event extends value.CidContainer3[Event] {
override private[lf] def map3[Nid, Cid, Val, Nid2, Cid2, Val2](
f1: Nid => Nid2,
@ -292,7 +292,7 @@ object Event extends value.CidContainer3WithDefaultCidResolver[Event] {
Events(relevantRoots, Map() ++ evts)
}
object Events extends value.CidContainer3WithDefaultCidResolver[Events] {
object Events extends value.CidContainer3[Events] {
override private[lf] def map3[Nid, Cid, Val, Nid2, Cid2, Val2](
f1: Nid => Nid2,
f2: Cid => Cid2,

View File

@ -41,9 +41,9 @@ sealed trait Result[+A] extends Product with Serializable {
// quick and dirty way to consume a Result
def consume(
pcs: AbsoluteContractId => Option[ContractInst[VersionedValue[AbsoluteContractId]]],
pcs: ContractId => Option[ContractInst[VersionedValue[ContractId]]],
packages: PackageId => Option[Package],
keys: GlobalKey => Option[AbsoluteContractId]): Either[Error, A] = {
keys: GlobalKey => Option[ContractId]): Either[Error, A] = {
@tailrec
def go(res: Result[A]): Either[Error, A] =
res match {
@ -72,8 +72,8 @@ final case class ResultError(err: Error) extends Result[Nothing]
* </ul>
*/
final case class ResultNeedContract[A](
acoid: AbsoluteContractId,
resume: Option[ContractInst[VersionedValue[AbsoluteContractId]]] => Result[A])
acoid: ContractId,
resume: Option[ContractInst[VersionedValue[ContractId]]] => Result[A])
extends Result[A]
/**
@ -87,7 +87,7 @@ final case class ResultNeedContract[A](
final case class ResultNeedPackage[A](packageId: PackageId, resume: Option[Package] => Result[A])
extends Result[A]
final case class ResultNeedKey[A](key: GlobalKey, resume: Option[AbsoluteContractId] => Result[A])
final case class ResultNeedKey[A](key: GlobalKey, resume: Option[ContractId] => Result[A])
extends Result[A]
object Result {
@ -151,8 +151,8 @@ object Result {
)
def needContract[A](
acoid: AbsoluteContractId,
resume: ContractInst[VersionedValue[AbsoluteContractId]] => Result[A]) =
acoid: ContractId,
resume: ContractInst[VersionedValue[ContractId]] => Result[A]) =
ResultNeedContract(acoid, {
case None => ResultError(Error(s"dependency error: couldn't find contract $acoid"))
case Some(contract) => resume(contract)

View File

@ -55,15 +55,15 @@ private[preprocessing] final class CommandPreprocessor(compiledPackages: Mutable
@throws[PreprocessorException]
def unsafePreprocessCreate(
templateId: Ref.Identifier,
argument: Value[Value.AbsoluteContractId],
): (speedy.Command.Create, Set[Value.AbsoluteContractId]) = {
argument: Value[Value.ContractId],
): (speedy.Command.Create, Set[Value.ContractId]) = {
val (arg, argCids) = valueTranslator.unsafeTranslateValue(Ast.TTyCon(templateId), argument)
speedy.Command.Create(templateId, arg) -> argCids
}
def unsafePreprocessFetch(
templateId: Ref.Identifier,
coid: Value.AbsoluteContractId,
coid: Value.ContractId,
): speedy.Command.Fetch =
speedy.Command.Fetch(templateId, SValue.SContractId(coid))
@ -72,13 +72,13 @@ private[preprocessing] final class CommandPreprocessor(compiledPackages: Mutable
templateId: Ref.Identifier,
contractId: Value.ContractId,
choiceId: Ref.ChoiceName,
argument: Value[Value.AbsoluteContractId],
): (speedy.Command.Exercise, Set[Value.AbsoluteContractId]) = {
argument: Value[Value.ContractId],
): (speedy.Command.Exercise, Set[Value.ContractId]) = {
val template = unsafeGetTemplate(templateId)
val choiceArgType = unsafeGetChoiceArgType(templateId, template, choiceId)
val (arg, argCids) = valueTranslator.unsafeTranslateValue(choiceArgType, argument)
val cids = contractId match {
case acoid: Value.AbsoluteContractId => argCids + acoid
case acoid: Value.ContractId => argCids + acoid
case _ => argCids
}
speedy.Command.Exercise(templateId, SValue.SContractId(contractId), choiceId, arg) -> cids
@ -87,10 +87,10 @@ private[preprocessing] final class CommandPreprocessor(compiledPackages: Mutable
@throws[PreprocessorException]
def unsafePreprocessExerciseByKey(
templateId: Ref.Identifier,
contractKey: Value[Value.AbsoluteContractId],
contractKey: Value[Value.ContractId],
choiceId: Ref.ChoiceName,
argument: Value[Value.AbsoluteContractId],
): (speedy.Command.ExerciseByKey, Set[Value.AbsoluteContractId]) = {
argument: Value[Value.ContractId],
): (speedy.Command.ExerciseByKey, Set[Value.ContractId]) = {
val template = unsafeGetTemplate(templateId)
val choiceArgType = unsafeGetChoiceArgType(templateId, template, choiceId)
val ckTtype = unsafeGetContractKeyType(templateId, template)
@ -105,10 +105,10 @@ private[preprocessing] final class CommandPreprocessor(compiledPackages: Mutable
@throws[PreprocessorException]
def unsafePreprocessCreateAndExercise(
templateId: Ref.ValueRef,
createArgument: Value[Value.AbsoluteContractId],
createArgument: Value[Value.ContractId],
choiceId: Ref.ChoiceName,
choiceArgument: Value[Value.AbsoluteContractId],
): (speedy.Command.CreateAndExercise, Set[Value.AbsoluteContractId]) = {
choiceArgument: Value[Value.ContractId],
): (speedy.Command.CreateAndExercise, Set[Value.ContractId]) = {
val (createArg, createArgCids) =
valueTranslator.unsafeTranslateValue(Ast.TTyCon(templateId), createArgument)
val template = unsafeGetTemplate(templateId)
@ -136,12 +136,12 @@ private[preprocessing] final class CommandPreprocessor(compiledPackages: Mutable
@throws[PreprocessorException]
def unsafePreprocessCommands(
cmds: ImmArray[command.Command],
): (ImmArray[speedy.Command], Set[Value.AbsoluteContractId]) = {
): (ImmArray[speedy.Command], Set[Value.ContractId]) = {
var cids = Set.empty[Value.AbsoluteContractId]
var cids = Set.empty[Value.ContractId]
@inline
def handleNewCids[X](tuple: (X, Set[Value.AbsoluteContractId])) = {
def handleNewCids[X](tuple: (X, Set[Value.ContractId])) = {
val (cmd, newCids) = tuple
cids = cids | newCids
cmd

View File

@ -126,7 +126,7 @@ private[engine] final class Preprocessor(compiledPackages: MutableCompiledPackag
* Fails if the nesting is too deep or if v0 does not match the type `ty0`.
* Assumes ty0 is a well-formed serializable typ.
*/
def translateValue(ty0: Ast.Type, v0: Value[Value.AbsoluteContractId]): Result[SValue] =
def translateValue(ty0: Ast.Type, v0: Value[Value.ContractId]): Result[SValue] =
safelyRun(getDependencies(List(ty0), List.empty)) {
unsafeTranslateValue(ty0, v0)
}.map(_._1)
@ -136,7 +136,7 @@ private[engine] final class Preprocessor(compiledPackages: MutableCompiledPackag
*/
def preprocessCommands(
cmds: data.ImmArray[command.Command],
): Result[(ImmArray[speedy.Command], Set[Value.AbsoluteContractId])] =
): Result[(ImmArray[speedy.Command], Set[Value.ContractId])] =
safelyRun(getDependencies(List.empty, cmds.map(_.templateId).toList)) {
unsafePreprocessCommands(cmds)
}
@ -168,7 +168,7 @@ private[engine] final class Preprocessor(compiledPackages: MutableCompiledPackag
def translateNode[Cid <: Value.ContractId](
node: Node.GenNode.WithTxValue[Transaction.NodeId, Cid],
): Result[(speedy.Command, Set[Value.AbsoluteContractId])] =
): Result[(speedy.Command, Set[Value.ContractId])] =
safelyRun(getDependencies(List.empty, List(getTemplateId(node)))) {
val (cmd, (globalCids, _)) = unsafeTranslateNode((Set.empty, Set.empty), node)
cmd -> globalCids
@ -176,7 +176,7 @@ private[engine] final class Preprocessor(compiledPackages: MutableCompiledPackag
def translateTransactionRoots[Cid <: Value.ContractId](
tx: GenTransaction.WithTxValue[Transaction.NodeId, Cid],
): Result[(ImmArray[speedy.Command], Set[Value.AbsoluteContractId])] =
): Result[(ImmArray[speedy.Command], Set[Value.ContractId])] =
safelyRun(
getDependencies(List.empty, tx.roots.toList.map(id => getTemplateId(tx.nodes(id))))
) {

View File

@ -8,7 +8,7 @@ package preprocessing
import com.daml.lf.data.{BackStack, ImmArray}
import com.daml.lf.transaction.{GenTransaction, Node, Transaction}
import com.daml.lf.value.Value
import com.daml.lf.value.Value.AbsoluteContractId
import com.daml.lf.value.Value.ContractId
private[preprocessing] final class TransactionPreprocessor(
compiledPackages: MutableCompiledPackages) {
@ -17,24 +17,6 @@ private[preprocessing] final class TransactionPreprocessor(
val commandPreprocessor = new CommandPreprocessor(compiledPackages)
// A cast of a value to a value which uses only absolute contract IDs.
// In particular, the cast will succeed for all values contained in the root nodes of a Transaction produced by submit
@throws[PreprocessorException]
private def unsafeAsValueWithAbsoluteContractIds(
v: Value[Value.ContractId]
): Value[Value.AbsoluteContractId] =
v.ensureNoRelCid
.fold(rcoid => fail(s"unexpected relative contract id $rcoid"), identity)
@throws[PreprocessorException]
private def unsafeAsAbsoluteContractId(coid: Value.ContractId): Value.AbsoluteContractId =
coid match {
case rcoid: Value.RelativeContractId =>
fail(s"not an absolute contract ID: $rcoid")
case acoid: Value.AbsoluteContractId =>
acoid
}
@throws[PreprocessorException]
private def unsafeAsValueWithNoContractIds(v: Value[Value.ContractId]): Value[Nothing] =
v.ensureNoCid.fold(
@ -45,23 +27,23 @@ private[preprocessing] final class TransactionPreprocessor(
// Translate a GenNode into an expression re-interpretable by the interpreter
@throws[PreprocessorException]
def unsafeTranslateNode[Cid <: Value.ContractId](
acc: (Set[Value.AbsoluteContractId], Set[Value.ContractId]),
acc: (Set[Value.ContractId], Set[Value.ContractId]),
node: Node.GenNode.WithTxValue[Transaction.NodeId, Cid]
): (speedy.Command, (Set[Value.AbsoluteContractId], Set[Value.ContractId])) = {
): (speedy.Command, (Set[Value.ContractId], Set[Value.ContractId])) = {
val (localCids, globalCids) = acc
node match {
case Node.NodeCreate(coid @ _, coinst, optLoc @ _, sigs @ _, stks @ _, key @ _) =>
val identifier = coinst.template
val arg = unsafeAsValueWithAbsoluteContractIds(coinst.arg.value)
coid match {
case acoid: AbsoluteContractId =>
case acoid: ContractId =>
if (globalCids(acoid))
fail("Conflicting discriminators between a global and local contract ID.")
case _ =>
}
val (cmd, newCids) = commandPreprocessor.unsafePreprocessCreate(identifier, arg)
val (cmd, newCids) =
commandPreprocessor.unsafePreprocessCreate(identifier, coinst.arg.value)
val newGlobalCids = globalCids + coid
val newLocalCids = localCids | newCids.filterNot(globalCids)
cmd -> (newLocalCids -> newGlobalCids)
@ -81,13 +63,11 @@ private[preprocessing] final class TransactionPreprocessor(
exerciseResult @ _,
key @ _) =>
val templateId = template
val arg = unsafeAsValueWithAbsoluteContractIds(chosenVal.value)
val (cmd, newCids) =
commandPreprocessor.unsafePreprocessExercise(templateId, coid, choice, arg)
commandPreprocessor.unsafePreprocessExercise(templateId, coid, choice, chosenVal.value)
(cmd, (localCids | newCids.filterNot(globalCids), globalCids))
case Node.NodeFetch(coid, templateId, _, _, _, _, _) =>
val acoid = unsafeAsAbsoluteContractId(coid)
val cmd = commandPreprocessor.unsafePreprocessFetch(templateId, acoid)
val cmd = commandPreprocessor.unsafePreprocessFetch(templateId, coid)
(cmd, acc)
case Node.NodeLookupByKey(templateId, _, key, _) =>
val keyValue = unsafeAsValueWithNoContractIds(key.key.value)
@ -99,9 +79,9 @@ private[preprocessing] final class TransactionPreprocessor(
@throws[PreprocessorException]
def unsafeTranslateTransactionRoots[Cid <: Value.ContractId](
tx: GenTransaction.WithTxValue[Transaction.NodeId, Cid],
): (ImmArray[speedy.Command], Set[AbsoluteContractId]) = {
): (ImmArray[speedy.Command], Set[ContractId]) = {
type Acc = ((Set[Value.AbsoluteContractId], Set[Value.ContractId]), BackStack[speedy.Command])
type Acc = ((Set[Value.ContractId], Set[Value.ContractId]), BackStack[speedy.Command])
val ((localCids, _), cmds) =
tx.roots.foldLeft[Acc](((Set.empty, Set.empty), BackStack.empty)) {

View File

@ -54,13 +54,12 @@ private[engine] final class ValueTranslator(compiledPackages: CompiledPackages)
}
@throws[PreprocessorException]
private def labeledRecordToMap(fields: ImmArray[(Option[String], Value[AbsoluteContractId])])
: Option[Map[String, Value[AbsoluteContractId]]] = {
private def labeledRecordToMap(fields: ImmArray[(Option[String], Value[ContractId])])
: Option[Map[String, Value[ContractId]]] = {
@tailrec
def go(
fields: ImmArray[(Option[String], Value[AbsoluteContractId])],
map: Map[String, Value[AbsoluteContractId]])
: Option[Map[String, Value[AbsoluteContractId]]] = {
fields: ImmArray[(Option[String], Value[ContractId])],
map: Map[String, Value[ContractId]]): Option[Map[String, Value[ContractId]]] = {
fields match {
case ImmArray() => Some(map)
case ImmArrayCons((None, _), _) => None
@ -81,12 +80,12 @@ private[engine] final class ValueTranslator(compiledPackages: CompiledPackages)
@throws[PreprocessorException]
private[preprocessing] def unsafeTranslateValue(
ty: Type,
value: Value[AbsoluteContractId],
): (SValue, Set[Value.AbsoluteContractId]) = {
value: Value[ContractId],
): (SValue, Set[Value.ContractId]) = {
val cids = Set.newBuilder[Value.AbsoluteContractId]
val cids = Set.newBuilder[Value.ContractId]
def go(ty: Type, value: Value[AbsoluteContractId], nesting: Int = 0): SValue =
def go(ty: Type, value: Value[ContractId], nesting: Int = 0): SValue =
if (nesting > Value.MAXIMUM_NESTING) {
fail(s"Provided value exceeds maximum nesting level of ${Value.MAXIMUM_NESTING}")
} else {
@ -115,13 +114,11 @@ private[engine] final class ValueTranslator(compiledPackages: CompiledPackages)
// optional
case (TOptional(elemType), ValueOptional(mb)) =>
SValue.SOptional(
mb.map((value: Value[AbsoluteContractId]) => go(elemType, value, newNesting)))
SValue.SOptional(mb.map((value: Value[ContractId]) => go(elemType, value, newNesting)))
// list
case (TList(elemType), ValueList(ls)) =>
SValue.SList(
ls.map((value: Value[AbsoluteContractId]) => go(elemType, value, newNesting)))
SValue.SList(ls.map((value: Value[ContractId]) => go(elemType, value, newNesting)))
// textMap
case (TTextMap(elemType), ValueTextMap(map)) =>
@ -234,7 +231,7 @@ private[engine] final class ValueTranslator(compiledPackages: CompiledPackages)
}
// This does not try to pull missing packages, return an error instead.
def translateValue(ty: Type, value: Value[AbsoluteContractId]): Either[Error, SValue] =
def translateValue(ty: Type, value: Value[ContractId]): Either[Error, SValue] =
safelyRun(unsafeTranslateValue(ty, value)._1)
}

View File

@ -7,7 +7,7 @@ import com.daml.lf.data._
import com.daml.lf.engine.Engine
import com.daml.lf.testing.parser.Implicits._
import com.daml.lf.transaction.Node
import com.daml.lf.value.Value.AbsoluteContractId
import com.daml.lf.value.Value.ContractId
import com.daml.lf.value.{Value, ValueVersions}
import org.scalatest.prop.TableDrivenPropertyChecks
import org.scalatest.{Matchers, WordSpec}
@ -67,8 +67,8 @@ class ContractDiscriminatorFreshnessCheckSpec
private val keyId = Ref.Identifier(pkgId, Ref.QualifiedName.assertFromString("Mod:Key"))
private val tmplId = Ref.Identifier(pkgId, Ref.QualifiedName.assertFromString("Mod:Contract"))
private def contractId(discriminator: crypto.Hash, suffix: Bytes): Value.AbsoluteContractId =
Value.AbsoluteContractId.V1.assertBuild(discriminator, suffix)
private def contractId(discriminator: crypto.Hash, suffix: Bytes): Value.ContractId =
Value.ContractId.V1.assertBuild(discriminator, suffix)
private def keyRecord(party: Ref.Party, idx: Int) =
Value.ValueRecord(
@ -79,7 +79,7 @@ class ContractDiscriminatorFreshnessCheckSpec
)
)
private def contractRecord(party: Ref.Party, idx: Int, cids: List[AbsoluteContractId]) =
private def contractRecord(party: Ref.Party, idx: Int, cids: List[ContractId]) =
Value.ValueRecord(
Some(tmplId),
ImmArray(
@ -94,7 +94,7 @@ class ContractDiscriminatorFreshnessCheckSpec
private val suffix2 = Utf8.getBytes("extension")
private val suffix3 = Utf8.getBytes("final-addition")
private def contractInstance(party: Ref.Party, idx: Int, cids: List[AbsoluteContractId]) =
private def contractInstance(party: Ref.Party, idx: Int, cids: List[ContractId]) =
Value.ContractInst(
tmplId,
ValueVersions.assertAsVersionedValue(contractRecord(party, idx, cids)),
@ -117,9 +117,8 @@ class ContractDiscriminatorFreshnessCheckSpec
private def submit(
cmds: ImmArray[command.Command],
pcs: Value.AbsoluteContractId => Option[
Value.ContractInst[Value.VersionedValue[AbsoluteContractId]]],
keys: Node.GlobalKey => Option[AbsoluteContractId]
pcs: Value.ContractId => Option[Value.ContractInst[Value.VersionedValue[ContractId]]],
keys: Node.GlobalKey => Option[ContractId]
) =
engine
.submit(

View File

@ -63,7 +63,7 @@ class EngineTest extends WordSpec with Matchers with EitherValues with BazelRunf
val withKeyTemplate = "BasicTests:WithKey"
val BasicTests_WithKey = Identifier(basicTestsPkgId, withKeyTemplate)
val withKeyContractInst: ContractInst[Tx.Value[AbsoluteContractId]] =
val withKeyContractInst: ContractInst[Tx.Value[ContractId]] =
ContractInst(
TypeConName(basicTestsPkgId, withKeyTemplate),
assertAsVersionedValue(
@ -110,7 +110,7 @@ class EngineTest extends WordSpec with Matchers with EitherValues with BazelRunf
allPackages.get(pkgId)
}
def lookupKey(key: GlobalKey): Option[AbsoluteContractId] =
def lookupKey(key: GlobalKey): Option[ContractId] =
(key.templateId, key.key) match {
case (
BasicTests_WithKey,
@ -1087,8 +1087,7 @@ class EngineTest extends WordSpec with Matchers with EitherValues with BazelRunf
""
)
def lookupContract(
id: AbsoluteContractId): Option[ContractInst[Tx.Value[AbsoluteContractId]]] = {
def lookupContract(id: ContractId): Option[ContractInst[Tx.Value[ContractId]]] = {
id match {
case `fetchedCid` => Some(makeContract(fetchedStrTid, fetchedTArgs))
case `fetcher1Cid` => Some(makeContract(fetcherStrTid, fetcher1TArgs))
@ -1112,7 +1111,7 @@ class EngineTest extends WordSpec with Matchers with EitherValues with BazelRunf
case (actors, (_, n)) => actors union actFetchActors(n)
}
def runExample(cid: AbsoluteContractId, exerciseActor: Party) = {
def runExample(cid: ContractId, exerciseActor: Party) = {
val command = ExerciseCommand(
fetcherTid,
cid,
@ -1199,8 +1198,7 @@ class EngineTest extends WordSpec with Matchers with EitherValues with BazelRunf
""
)
def lookupContract(
id: AbsoluteContractId): Option[ContractInst[Tx.Value[AbsoluteContractId]]] = {
def lookupContract(id: ContractId): Option[ContractInst[Tx.Value[ContractId]]] = {
id match {
case `fetchedCid` => Some(fetchedContract)
case _ => None
@ -1247,7 +1245,7 @@ class EngineTest extends WordSpec with Matchers with EitherValues with BazelRunf
""
)
def lookupKey(key: GlobalKey): Option[AbsoluteContractId] = {
def lookupKey(key: GlobalKey): Option[ContractId] = {
(key.templateId, key.key) match {
case (
BasicTests_WithKey,
@ -1416,7 +1414,7 @@ class EngineTest extends WordSpec with Matchers with EitherValues with BazelRunf
""
)
def lookupKey(key: GlobalKey): Option[AbsoluteContractId] = {
def lookupKey(key: GlobalKey): Option[ContractId] = {
(key.templateId, key.key) match {
case (
BasicTests_WithKey,
@ -1611,8 +1609,8 @@ object EngineTest {
private implicit def toName(s: String): Name =
Name.assertFromString(s)
private def toContractId(s: String): AbsoluteContractId =
AbsoluteContractId.assertFromString(s)
private def toContractId(s: String): ContractId =
ContractId.assertFromString(s)
private def ArrayList[X](as: X*): util.ArrayList[X] = {
val a = new util.ArrayList[X](as.length)
@ -1638,7 +1636,7 @@ object EngineTest {
txMeta: Tx.Metadata,
ledgerEffectiveTime: Time.Timestamp,
lookupPackages: PackageId => Option[Package],
contracts: Map[AbsoluteContractId, Tx.ContractInst[AbsoluteContractId]] = Map.empty,
contracts: Map[ContractId, Tx.ContractInst[ContractId]] = Map.empty,
): Either[Error, (Tx.Transaction, Tx.Metadata)] = {
type Acc =
(
@ -1646,8 +1644,8 @@ object EngineTest {
BackStack[NodeId],
Boolean,
BackStack[(NodeId, crypto.Hash)],
Map[AbsoluteContractId, Tx.ContractInst[AbsoluteContractId]],
Map[GlobalKey, AbsoluteContractId],
Map[ContractId, Tx.ContractInst[ContractId]],
Map[GlobalKey, ContractId],
)
val nodeSeedMap = txMeta.nodeSeeds.toSeq.toMap
@ -1673,7 +1671,7 @@ object EngineTest {
(
_,
NodeExercises(
targetCoid: AbsoluteContractId,
targetCoid: ContractId,
_,
_,
_,
@ -1687,13 +1685,12 @@ object EngineTest {
_,
_))) =>
(contracts - targetCoid, keys)
case (
(contracts, keys),
(_, NodeCreate(cid: AbsoluteContractId, coinst, _, _, _, key))) =>
case ((contracts, keys), (_, NodeCreate(cid: ContractId, coinst, _, _, _, key))) =>
(
contracts.updated(
cid,
coinst.assertNoRelCid(cid => s"unexpected relative contract ID $cid")),
coinst,
),
key.fold(keys)(
k =>
keys.updated(

View File

@ -5,7 +5,7 @@ package com.daml.lf.engine
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.atomic.AtomicInteger
import com.daml.lf.data.{FrontStack, FrontStackCons, Ref}
import com.daml.lf.data.{FrontStack, FrontStackCons}
import com.daml.lf.transaction.Node._
import com.daml.lf.transaction.{GenTransaction, Transaction => Tx}
import com.daml.lf.value.Value._
@ -14,27 +14,20 @@ import scala.annotation.tailrec
trait PrivateLedgerData {
def update(tx: GenTransaction.WithTxValue[NodeId, ContractId]): Unit
def get(id: AbsoluteContractId): Option[ContractInst[VersionedValue[AbsoluteContractId]]]
def toContractIdString(txCounter: Int)(cid: RelativeContractId): Ref.ContractIdString
def get(id: ContractId): Option[ContractInst[VersionedValue[ContractId]]]
def transactionCounter: Int
def clear(): Unit
}
private[engine] class InMemoryPrivateLedgerData extends PrivateLedgerData {
private val pcs
: ConcurrentHashMap[AbsoluteContractId, ContractInst[Tx.Value[AbsoluteContractId]]] =
private val pcs: ConcurrentHashMap[ContractId, ContractInst[Tx.Value[ContractId]]] =
new ConcurrentHashMap()
private val txCounter: AtomicInteger = new AtomicInteger(0)
def update(tx: GenTransaction.WithTxValue[NodeId, ContractId]): Unit =
updateWithAbsoluteContractId(tx.resolveRelCid(toContractIdString(txCounter.get)))
updateWithContractId(tx)
def toContractIdString(txCounter: Int)(r: RelativeContractId): Ref.ContractIdString =
// It is safe to concatenate numbers and "-" to form a valid ContractId
Ref.ContractIdString.assertFromString(s"#$txCounter-${r.txnid.index}")
def updateWithAbsoluteContractId(
tx: GenTransaction.WithTxValue[NodeId, AbsoluteContractId]): Unit =
def updateWithContractId(tx: GenTransaction.WithTxValue[NodeId, ContractId]): Unit =
this.synchronized {
// traverse in topo order and add / remove
@tailrec
@ -43,10 +36,10 @@ private[engine] class InMemoryPrivateLedgerData extends PrivateLedgerData {
case FrontStackCons(nodeId, nodeIds) =>
val node = tx.nodes(nodeId)
node match {
case nc: NodeCreate.WithTxValue[AbsoluteContractId] =>
case nc: NodeCreate.WithTxValue[ContractId] =>
pcs.put(nc.coid, nc.coinst)
go(nodeIds)
case ne: NodeExercises.WithTxValue[Tx.NodeId, AbsoluteContractId] =>
case ne: NodeExercises.WithTxValue[Tx.NodeId, ContractId] =>
go(ne.children ++: nodeIds)
case _: NodeLookupByKey[_, _] | _: NodeFetch[_, _] =>
go(nodeIds)
@ -57,7 +50,7 @@ private[engine] class InMemoryPrivateLedgerData extends PrivateLedgerData {
()
}
def get(id: AbsoluteContractId): Option[ContractInst[VersionedValue[AbsoluteContractId]]] =
def get(id: ContractId): Option[ContractInst[VersionedValue[ContractId]]] =
this.synchronized {
Option(pcs.get(id))
}

View File

@ -91,10 +91,8 @@ class LargeTransactionTest extends WordSpec with Matchers with BazelRunfiles {
cmd = createCmd,
cmdReference = "create RangeOfInts",
seed = hash("testLargeTransactionOneContract:create", txSize))
val contractId: AbsoluteContractId = firstRootNode(createCmdTx) match {
case N.NodeCreate(x: RelativeContractId, _, _, _, _, _) =>
AbsoluteContractId.V0(pcs.toContractIdString(pcs.transactionCounter - 1)(x))
case N.NodeCreate(x: AbsoluteContractId, _, _, _, _, _) => x
val contractId = firstRootNode(createCmdTx) match {
case N.NodeCreate(coid, _, _, _, _, _) => coid
case n @ _ => fail(s"Expected NodeCreate, but got: $n")
}
val exerciseCmd = toListContainerExerciseCmd(rangeOfIntsTemplateId, contractId)
@ -120,10 +118,8 @@ class LargeTransactionTest extends WordSpec with Matchers with BazelRunfiles {
cmd = createCmd,
cmdReference = "create RangeOfInts",
seed = hash("testLargeTransactionManySmallContracts:create", num))
val contractId: AbsoluteContractId = firstRootNode(createCmdTx) match {
case N.NodeCreate(x: RelativeContractId, _, _, _, _, _) =>
AbsoluteContractId.V0(pcs.toContractIdString(pcs.transactionCounter - 1)(x))
case N.NodeCreate(x: AbsoluteContractId, _, _, _, _, _) => x
val contractId = firstRootNode(createCmdTx) match {
case N.NodeCreate(coid, _, _, _, _, _) => coid
case n @ _ => fail(s"Expected NodeCreate, but got: $n")
}
val exerciseCmd = toListOfIntContainers(rangeOfIntsTemplateId, contractId)
@ -149,10 +145,8 @@ class LargeTransactionTest extends WordSpec with Matchers with BazelRunfiles {
cmd = createCmd,
cmdReference = "create ListUtil",
seed = hash("testLargeChoiceArgument:create", size))
val contractId: AbsoluteContractId = firstRootNode(createCmdTx) match {
case N.NodeCreate(x: RelativeContractId, _, _, _, _, _) =>
AbsoluteContractId.V0(pcs.toContractIdString(pcs.transactionCounter - 1)(x))
case N.NodeCreate(x: AbsoluteContractId, _, _, _, _, _) => x
val contractId = firstRootNode(createCmdTx) match {
case N.NodeCreate(coid, _, _, _, _, _) => coid
case n @ _ => fail(s"Expected NodeCreate, but got: $n")
}
val exerciseCmd = sizeExerciseCmd(listUtilTemplateId, contractId)(size)
@ -239,7 +233,7 @@ class LargeTransactionTest extends WordSpec with Matchers with BazelRunfiles {
private def toListContainerExerciseCmd(
templateId: Identifier,
contractId: AbsoluteContractId
contractId: ContractId
): ExerciseCommand = {
val choice = "ToListContainer"
val emptyArgs = ValueRecord(None, ImmArray.empty)
@ -248,7 +242,7 @@ class LargeTransactionTest extends WordSpec with Matchers with BazelRunfiles {
private def toListOfIntContainers(
templateId: Identifier,
contractId: AbsoluteContractId
contractId: ContractId
): ExerciseCommand = {
val choice = "ToListOfIntContainers"
val emptyArgs = ValueRecord(None, ImmArray.empty)
@ -260,7 +254,7 @@ class LargeTransactionTest extends WordSpec with Matchers with BazelRunfiles {
CreateCommand(templateId, ValueRecord(Some(templateId), fields))
}
private def sizeExerciseCmd(templateId: Identifier, contractId: AbsoluteContractId)(
private def sizeExerciseCmd(templateId: Identifier, contractId: ContractId)(
size: Int): ExerciseCommand = {
val choice = "Size"
val choiceDefRef = Identifier(templateId.packageId, qn(s"LargeTransaction:$choice"))

View File

@ -61,7 +61,7 @@ class PreprocessorSpec extends WordSpec with Matchers with TableDrivenPropertyCh
TParty ->
ValueParty(Ref.Party.assertFromString("Alice")),
TContractId(TTyCon(recordCon)) ->
ValueContractId(AbsoluteContractId.assertFromString("#contractId")),
ValueContractId(ContractId.assertFromString("#contractId")),
TList(TText) ->
ValueList(FrontStack(ValueText("a"), ValueText("b"))),
TTextMap(TBool) ->

View File

@ -249,19 +249,19 @@ object Pretty {
val ni = l.ledgerData.nodeInfos(nodeId) /* Ekke Ekke Ekke Ekke Ptang Zoo Boing! */
val ppNode = ni.node match {
case create: NodeCreate[AbsoluteContractId, Transaction.Value[AbsoluteContractId]] =>
case create: NodeCreate[ContractId, Transaction.Value[ContractId]] =>
val d = "create" &: prettyContractInst(create.coinst)
create.key match {
case None => d
case Some(key) => d / text("key") & prettyKeyWithMaintainers(key)
}
case ea: NodeFetch[AbsoluteContractId, Transaction.Value[AbsoluteContractId]] =>
case ea: NodeFetch[ContractId, Transaction.Value[ContractId]] =>
"ensure active" &: prettyContractId(ea.coid)
case ex: NodeExercises[
L.ScenarioNodeId,
AbsoluteContractId,
ContractId,
Transaction.Value[
AbsoluteContractId
ContractId
]] =>
val children =
if (ex.children.nonEmpty)
@ -273,7 +273,7 @@ object Pretty {
text("on") & prettyContractId(ex.targetCoid) /
(text(" ") + text("with") & prettyVersionedValue(false)(ex.chosenValue) / children)
.nested(4)
case lbk: NodeLookupByKey[AbsoluteContractId, Transaction.Value[AbsoluteContractId]] =>
case lbk: NodeLookupByKey[ContractId, Transaction.Value[ContractId]] =>
text("lookup by key") & prettyIdentifier(lbk.templateId) /
text("key") & prettyKeyWithMaintainers(lbk.key) /
(lbk.result match {
@ -331,10 +331,7 @@ object Pretty {
text(tycon.qualifiedName.toString) + char('@') + prettyPackageId(tycon.packageId)
def prettyContractId(coid: ContractId): Doc =
coid match {
case acoid: AbsoluteContractId => text(acoid.coid)
case RelativeContractId(rcoid) => str(rcoid)
}
text(coid.coid)
def prettyActiveContracts(c: L.LedgerData): Doc =
fill(
@ -402,9 +399,7 @@ object Pretty {
}) +
text(constructor)
case ValueText(t) => char('"') + text(t) + char('"')
case ValueContractId(acoid: AbsoluteContractId) => text(acoid.coid)
case ValueContractId(RelativeContractId(rcoid)) =>
char('~') + text(rcoid.toString)
case ValueContractId(acoid) => text(acoid.coid)
case ValueUnit => text("<unit>")
case ValueBool(b) => str(b)
case ValueList(lst) =>

View File

@ -897,7 +897,7 @@ object SBuiltin {
machine.returnValue = contract
case None =>
coid match {
case acoid: V.AbsoluteContractId =>
case acoid: V.ContractId =>
throw SpeedyHungry(
SResultNeedContract(
acoid,

View File

@ -8,7 +8,7 @@ import com.daml.lf.data.Time
import com.daml.lf.transaction.Transaction
import com.daml.lf.transaction.Transaction.Transaction
import com.daml.lf.types.Ledger
import com.daml.lf.value.Value.{AbsoluteContractId, ContractId}
import com.daml.lf.value.Value.ContractId
object SError {
@ -67,13 +67,13 @@ object SError {
sealed trait SErrorScenario extends SError
final case class ScenarioErrorContractNotEffective(
coid: AbsoluteContractId,
coid: ContractId,
templateId: Identifier,
effectiveAt: Time.Timestamp,
) extends SErrorScenario
final case class ScenarioErrorContractNotActive(
coid: AbsoluteContractId,
coid: ContractId,
templateId: Identifier,
consumedBy: Ledger.ScenarioNodeId,
) extends SErrorScenario
@ -90,7 +90,7 @@ object SError {
/** A fetch or exercise was being made against a contract that has not
* been disclosed to 'committer'. */
final case class ScenarioErrorContractNotVisible(
coid: AbsoluteContractId,
coid: ContractId,
templateId: Identifier,
committer: Party,
observers: Set[Party],

View File

@ -283,7 +283,7 @@ object SExpr {
* calls. Rather, we set the control to this expression and then crash when executing.
*/
final case class SEWronglyTypeContractId(
acoid: V.AbsoluteContractId,
acoid: V.ContractId,
expected: TypeConName,
actual: TypeConName,
) extends SExpr {

View File

@ -4,7 +4,7 @@
package com.daml.lf.speedy
import com.daml.lf.CompiledPackages
import com.daml.lf.value.Value.{AbsoluteContractId, ContractInst}
import com.daml.lf.value.Value.{ContractId, ContractInst}
import com.daml.lf.data.Ref._
import com.daml.lf.data.Time
import com.daml.lf.transaction.Transaction._
@ -28,13 +28,13 @@ object SResult {
/** Update interpretation requires access to a contract on the ledger. */
final case class SResultNeedContract(
contractId: AbsoluteContractId,
contractId: ContractId,
templateId: TypeConName,
committers: Set[Party],
// Callback to signal that the contract was not present
// or visible. Returns true if this was recoverable.
cbMissing: Unit => Boolean,
cbPresent: ContractInst[Value[AbsoluteContractId]] => Unit,
cbPresent: ContractInst[Value[ContractId]] => Unit,
) extends SResult
/** Machine needs a definition that was not present when the machine was
@ -92,11 +92,11 @@ object SResult {
sealed abstract class SKeyLookupResult
object SKeyLookupResult {
final case class Found(coid: AbsoluteContractId) extends SKeyLookupResult
final case class Found(coid: ContractId) extends SKeyLookupResult
final case object NotFound extends SKeyLookupResult
final case object NotVisible extends SKeyLookupResult
def apply(coid: Option[AbsoluteContractId]): SKeyLookupResult =
def apply(coid: Option[ContractId]): SKeyLookupResult =
coid.fold[SKeyLookupResult](NotFound)(Found)
}

View File

@ -230,16 +230,15 @@ object Speedy {
def addLocalContract(coid: V.ContractId, templateId: Ref.TypeConName, SValue: SValue) =
coid match {
case V.AbsoluteContractId.V1(discriminator, _)
if globalDiscriminators.contains(discriminator) =>
case V.ContractId.V1(discriminator, _) if globalDiscriminators.contains(discriminator) =>
crash("Conflicting discriminators between a global and local contract ID.")
case _ =>
localContracts = localContracts.updated(coid, templateId -> SValue)
}
def addGlobalCid(cid: V.ContractId) = cid match {
case V.AbsoluteContractId.V1(discriminator, _) =>
if (localContracts.isDefinedAt(V.AbsoluteContractId.V1(discriminator)))
case V.ContractId.V1(discriminator, _) =>
if (localContracts.isDefinedAt(V.ContractId.V1(discriminator)))
crash("Conflicting discriminators between a global and local contract ID.")
else
globalDiscriminators = globalDiscriminators + discriminator
@ -525,7 +524,7 @@ object Speedy {
compiledPackages: CompiledPackages,
submissionTime: Time.Timestamp,
initialSeeding: InitialSeeding,
globalCids: Set[V.AbsoluteContractId]
globalCids: Set[V.ContractId]
) =
Machine(
ctrl = null,
@ -543,7 +542,7 @@ object Speedy {
dependsOnTime = false,
localContracts = Map.empty,
globalDiscriminators = globalCids.collect {
case V.AbsoluteContractId.V1(discriminator, _) => discriminator
case V.ContractId.V1(discriminator, _) => discriminator
},
steps = 0,
track = Instrumentation(),
@ -572,7 +571,7 @@ object Speedy {
compiledPackages: CompiledPackages,
submissionTime: Time.Timestamp,
seeds: InitialSeeding,
globalCids: Set[V.AbsoluteContractId],
globalCids: Set[V.ContractId],
): Machine =
fromSExpr(
SEApp(sexpr, Array(SEValue.Token)),
@ -614,7 +613,7 @@ object Speedy {
compiledPackages: CompiledPackages,
submissionTime: Time.Timestamp,
seeding: InitialSeeding,
globalCids: Set[V.AbsoluteContractId],
globalCids: Set[V.ContractId],
): Machine =
initial(compiledPackages, submissionTime, seeding, globalCids).copy(ctrl = sexpr)
}

View File

@ -11,7 +11,7 @@ import com.daml.lf.language.Ast
import com.daml.lf.speedy.SError.SErrorCrash
import com.daml.lf.speedy.SValue
import com.daml.lf.speedy.SValue._
import com.daml.lf.value.Value.{AbsoluteContractId, RelativeContractId}
import com.daml.lf.value.Value.ContractId
import scala.annotation.tailrec
import scala.collection.JavaConverters._
@ -111,15 +111,15 @@ object Ordering extends scala.math.Ordering[SValue] {
private def compareText(text1: String, text2: String): Int =
Utf8.Ordering.compare(text1, text2)
private def compareAbsCid(cid1: AbsoluteContractId, cid2: AbsoluteContractId): Int =
private def compareAbsCid(cid1: ContractId, cid2: ContractId): Int =
(cid1, cid2) match {
case (AbsoluteContractId.V0(s1), AbsoluteContractId.V0(s2)) =>
case (ContractId.V0(s1), ContractId.V0(s2)) =>
s1 compareTo s2
case (AbsoluteContractId.V0(_), AbsoluteContractId.V1(_, _)) =>
case (ContractId.V0(_), ContractId.V1(_, _)) =>
-1
case (AbsoluteContractId.V1(_, _), AbsoluteContractId.V0(_)) =>
case (ContractId.V1(_, _), ContractId.V0(_)) =>
+1
case (AbsoluteContractId.V1(hash1, suffix1), AbsoluteContractId.V1(hash2, suffix2)) =>
case (ContractId.V1(hash1, suffix1), ContractId.V1(hash2, suffix2)) =>
val c1 = crypto.Hash.ordering.compare(hash1, hash2)
if (c1 != 0)
c1
@ -169,8 +169,8 @@ object Ordering extends scala.math.Ordering[SValue] {
case SParty(p2) =>
(compareText(p1, p2)) -> ImmArray.empty
}
case SContractId(coid1: AbsoluteContractId) => {
case SContractId(coid2: AbsoluteContractId) =>
case SContractId(coid1: ContractId) => {
case SContractId(coid2: ContractId) =>
compareAbsCid(coid1, coid2) -> ImmArray.empty
}
case STypeRep(t1) => {
@ -219,10 +219,6 @@ object Ordering extends scala.math.Ordering[SValue] {
case SAny(t2, v2) =>
compareType(t1, t2) -> ImmArray((v1, v2))
}
case SContractId(RelativeContractId(_)) => {
case SContractId(RelativeContractId(_)) =>
throw SErrorCrash("relative contract id are not comparable")
}
case SPAP(_, _, _) => {
case SPAP(_, _, _) =>
throw SErrorCrash("functions are not comparable")

View File

@ -136,15 +136,15 @@ object PartialTransaction {
* the caller to check for 'isAborted' after every
* change to a transaction.
* @param keys A local store of the contract keys. Note that this contains
* info both about relative and absolute contract ids. We must
* do this because absolute contract ids can be archived as
* info both about relative and contract ids. We must
* do this because contract ids can be archived as
* part of execution, and we must record these archivals locally.
* Note: it is important for keys that we know to not be present
* to be present as [[None]]. The reason for this is that we must
* record the "no key" information for absolute contract ids that
* record the "no key" information for contract ids that
* we archive. This is not an optimization and is required for
* correct semantics, since otherwise lookups for keys for
* locally archived absolute contract ids will succeed wrongly.
* locally archived contract ids will succeed wrongly.
*/
case class PartialTransaction(
submissionTime: Time.Timestamp,
@ -236,7 +236,7 @@ case class PartialTransaction(
val nodeSeed = context.nextChildrenSeed
val discriminator =
crypto.Hash.deriveContractDiscriminator(nodeSeed, submissionTime, stakeholders)
val cid = Value.AbsoluteContractId.V1(discriminator)
val cid = Value.ContractId.V1(discriminator)
val createNode = Node.NodeCreate(
cid,
coinst,

View File

@ -31,7 +31,7 @@ object Ledger {
/** This is the function that we use to turn relative contract ids (which are made of
* transaction node ids) in the still
* to be committed transaction into absolute contract ids in the ledger.
* to be committed transaction into contract ids in the ledger.
*/
// The prefix should be smaller than 244 chars.
@inline
@ -41,41 +41,6 @@ object Ledger {
): ScenarioNodeId =
LedgerString.assertConcat(commitPrefix, LedgerString.fromInt(txnidx))
@inline
private def relativeToScenarioNodeId(
commitPrefix: LedgerString,
cid: RelativeContractId,
): ScenarioNodeId =
txNodeIdToScenarioNodeId(commitPrefix, cid.txnid.index)
@inline
def relativeToContractIdString(
commitPrefix: LedgerString,
cid: RelativeContractId,
): LedgerString =
LedgerString.assertConcat(commitPrefix, LedgerString.fromInt(cid.txnid.index))
@inline
private def contractIdToAbsoluteContractId(
commitPrefix: LedgerString,
cid: ContractId,
): AbsoluteContractId =
cid match {
case acoid: AbsoluteContractId => acoid
case rcoid: RelativeContractId =>
AbsoluteContractId.V0.assertFromString(relativeToScenarioNodeId(commitPrefix, rcoid))
}
def contractIdToAbsoluteContractId(
transactionId: ScenarioTransactionId,
cid: ContractId,
): AbsoluteContractId = {
// commitPrefix is small enough (< 20 chars), so we do no exceed the 255
// chars limit when concatenate in txNodeIdToScenarioNodeId method.
val commitPrefix = transactionId.makeCommitPrefix
contractIdToAbsoluteContractId(commitPrefix, cid)
}
@inline
def assertNoContractId(key: Value[Value.ContractId]): Value[Nothing] =
key.ensureNoCid.fold(
@ -110,12 +75,8 @@ object Ledger {
/** The node of the transaction graph. Only differs from the update
* transaction node * in the node identifier, where here the identifier
* is global.
*
* Note that here the contract ids refer to NodeIds. Or in other
* words, all AbsoluteContractIds are also NodeIds (but not the
* reverse, node ids might be exercises)
*/
type Node = GenNode.WithTxValue[ScenarioNodeId, AbsoluteContractId]
type Node = GenNode.WithTxValue[ScenarioNodeId, ContractId]
/** A transaction as it is committed to the ledger.
*
@ -146,7 +107,7 @@ object Ledger {
nodes: immutable.HashMap[ScenarioNodeId, Node],
explicitDisclosure: Relation[ScenarioNodeId, Party],
localImplicitDisclosure: Relation[ScenarioNodeId, Party],
globalImplicitDisclosure: Relation[AbsoluteContractId, Party],
globalImplicitDisclosure: Relation[ContractId, Party],
failedAuthorizations: FailedAuthorizations,
) {
def disclosures = Relation.union(explicitDisclosure, localImplicitDisclosure)
@ -162,9 +123,9 @@ object Ledger {
// A relation between a node id and the parties to which this node get implictly disclosed
// (aka divulgence)
localImplicitDisclosure: Relation[Transaction.NodeId, Party],
// A relation between absolute contract id and the parties to which the contract id gets
// A relation between contract id and the parties to which the contract id gets
// explicitly disclosed.
globalImplicitDisclosure: Relation[AbsoluteContractId, Party],
globalImplicitDisclosure: Relation[ContractId, Party],
// A map from node ids to authorizations that failed for them.
failedAuthorizations: FailedAuthorizations,
)
@ -189,7 +150,6 @@ object Ledger {
nodes = enrichedTx.nodes.map {
case (nodeId, node) =>
ScenarioNodeId(commitPrefix, nodeId) -> node
.assertNoRelCid(_ => "Unexpected relative contract ID.")
.mapNodeId(ScenarioNodeId(commitPrefix, _))
}(breakOut),
explicitDisclosure = enrichedTx.explicitDisclosure.map {
@ -282,23 +242,23 @@ object Ledger {
sealed trait LookupResult
final case class LookupOk(
coid: AbsoluteContractId,
coinst: ContractInst[Transaction.Value[AbsoluteContractId]],
coid: ContractId,
coinst: ContractInst[Transaction.Value[ContractId]],
) extends LookupResult
final case class LookupContractNotFound(coid: AbsoluteContractId) extends LookupResult
final case class LookupContractNotFound(coid: ContractId) extends LookupResult
final case class LookupContractNotEffective(
coid: AbsoluteContractId,
coid: ContractId,
templateId: Identifier,
effectiveAt: Time.Timestamp,
) extends LookupResult
final case class LookupContractNotActive(
coid: AbsoluteContractId,
coid: ContractId,
templateId: Identifier,
consumedBy: ScenarioNodeId,
) extends LookupResult
final case class LookupContractNotVisible(
coid: AbsoluteContractId,
coid: ContractId,
templateId: Identifier,
observers: Set[Party],
) extends LookupResult
@ -357,13 +317,13 @@ object Ledger {
def lookupGlobalContract(
view: View,
effectiveAt: Time.Timestamp,
coid: AbsoluteContractId,
coid: ContractId,
): LookupResult = {
ledgerData.coidToNodeId.get(coid).flatMap(ledgerData.nodeInfos.get) match {
case None => LookupContractNotFound(coid)
case Some(info) =>
info.node match {
case create: NodeCreate.WithTxValue[AbsoluteContractId] =>
case create: NodeCreate.WithTxValue[ContractId] =>
if (info.effectiveAt.compareTo(effectiveAt) > 0)
LookupContractNotEffective(coid, create.coinst.template, info.effectiveAt)
else if (info.consumedBy.nonEmpty)
@ -539,7 +499,7 @@ object Ledger {
nodes: Map[ScenarioNodeId, Node],
disclosures: Relation[Transaction.NodeId, Party],
localDivulgences: Relation[Transaction.NodeId, Party],
globalDivulgences: Relation[AbsoluteContractId, Party],
globalDivulgences: Relation[ContractId, Party],
failedAuthorizations: Map[Transaction.NodeId, FailedAuthorization],
) {
def discloseNode(
@ -560,24 +520,7 @@ object Ledger {
case (s, coid) => s.divulgeCoidTo(witnesses, coid)
}
def divulgeCoidTo(witnesses: Set[Party], coid: ContractId): EnrichState = {
def divulgeRelativeCoidTo(ws: Set[Party], rcoid: RelativeContractId): EnrichState = {
val nid = rcoid.txnid
copy(
localDivulgences = localDivulgences
.updated(nid, ws union localDivulgences.getOrElse(nid, Set.empty)),
)
}
coid match {
case rcoid: RelativeContractId =>
divulgeRelativeCoidTo(witnesses, rcoid)
case acoid: AbsoluteContractId =>
divulgeAbsoluteCoidTo(witnesses, acoid)
}
}
def divulgeAbsoluteCoidTo(witnesses: Set[Party], acoid: AbsoluteContractId): EnrichState = {
def divulgeCoidTo(witnesses: Set[Party], acoid: ContractId): EnrichState = {
copy(
globalDivulgences = globalDivulgences
.updated(acoid, witnesses union globalDivulgences.getOrElse(acoid, Set.empty)),
@ -993,67 +936,6 @@ object Ledger {
coids.result()
}
def makeAbsolute(
commitPrefix: LedgerString,
value: VersionedValue[ContractId],
): VersionedValue[AbsoluteContractId] = {
VersionedValue(value.version, makeAbsolute(commitPrefix, value.value))
}
/** Convert all relative to absolute contract-ids in the value.
*
* TODO(FM) make this tail recursive
*/
def makeAbsolute(
commitPrefix: LedgerString,
value: Value[ContractId],
): Value[AbsoluteContractId] = {
def rewrite(v: Value[ContractId]): Value[AbsoluteContractId] =
v match {
case ValueRecord(tycon, fs) =>
ValueRecord(tycon, fs.map[(Option[Name], Value[AbsoluteContractId])] {
case (k, v) => (k, rewrite(v))
})
case ValueStruct(fs) =>
ValueStruct(fs.map[(Name, Value[AbsoluteContractId])] {
case (k, v) => (k, rewrite(v))
})
case ValueVariant(tycon, variant, value) =>
ValueVariant(tycon, variant, rewrite(value))
case ValueList(vs) => ValueList(vs.map(rewrite))
case ValueContractId(coid) =>
val acoid = contractIdToAbsoluteContractId(commitPrefix, coid)
ValueContractId(acoid)
case vlit: ValueCidlessLeaf => vlit
case ValueOptional(mbV) => ValueOptional(mbV.map(rewrite))
case ValueTextMap(map) => ValueTextMap(map.mapValue(rewrite))
case ValueGenMap(entries) =>
ValueGenMap(entries.map { case (k, v) => rewrite(k) -> rewrite(v) })
}
rewrite(value)
}
/*
def relativeContractIdToNodeId(commitPrefix: String,
rcoid: RelativeContractId): NodeId =
NodeId(commitPrefix ++ rcoid.index.toString)
def contractIdToNodeId(commitPrefix: String, coid: ContractId): NodeId =
coid match {
case acoid: AbsoluteContractId => absoluteContractIdToNodeId(acoid)
case rcoid: RelativeContractId =>
relativeContractIdToNodeId(commitPrefix, rcoid)
}
def contractIdToNodeIdOrTrNodeId(
coid: ContractId): Either[NodeId, Tr.NodeId] = {
coid match {
case AbsoluteContractId(acoid) => Left(acoid)
case RelativeContractId(rcoid) => Right(rcoid)
}
}
*/
// ----------------------------------------------------------------
// Cache for active contracts and nodes
// ----------------------------------------------------------------
@ -1069,15 +951,15 @@ object Ledger {
* the transaction graph
*/
final case class LedgerData(
activeContracts: Set[AbsoluteContractId],
activeContracts: Set[ContractId],
nodeInfos: LedgerNodeInfos,
activeKeys: Map[GlobalKey, AbsoluteContractId],
coidToNodeId: Map[AbsoluteContractId, ScenarioNodeId],
activeKeys: Map[GlobalKey, ContractId],
coidToNodeId: Map[ContractId, ScenarioNodeId],
) {
def nodeInfoByCoid(coid: AbsoluteContractId): LedgerNodeInfo = nodeInfos(coidToNodeId(coid))
def nodeInfoByCoid(coid: ContractId): LedgerNodeInfo = nodeInfos(coidToNodeId(coid))
def updateLedgerNodeInfo(
coid: AbsoluteContractId,
coid: ContractId,
)(f: (LedgerNodeInfo) => LedgerNodeInfo): LedgerData =
coidToNodeId.get(coid).map(updateLedgerNodeInfo(_)(f)).getOrElse(this)
@ -1091,16 +973,16 @@ object Ledger {
.getOrElse(nodeInfos),
)
def markAsActive(coid: AbsoluteContractId): LedgerData =
def markAsActive(coid: ContractId): LedgerData =
copy(activeContracts = activeContracts + coid)
def markAsInactive(coid: AbsoluteContractId): LedgerData =
def markAsInactive(coid: ContractId): LedgerData =
copy(activeContracts = activeContracts - coid)
def createdIn(coid: AbsoluteContractId, nodeId: ScenarioNodeId): LedgerData =
def createdIn(coid: ContractId, nodeId: ScenarioNodeId): LedgerData =
copy(coidToNodeId = coidToNodeId + (coid -> nodeId))
def addKey(key: GlobalKey, acoid: AbsoluteContractId): LedgerData =
def addKey(key: GlobalKey, acoid: ContractId): LedgerData =
copy(activeKeys = activeKeys + (key -> acoid))
def removeKey(key: GlobalKey): LedgerData =
@ -1147,7 +1029,7 @@ object Ledger {
val idsToProcess = (mbParentId -> restOfNodeIds) :: restENPs
node match {
case nc: NodeCreate.WithTxValue[AbsoluteContractId] =>
case nc: NodeCreate.WithTxValue[ContractId] =>
val newCache1 =
newCache
.markAsActive(nc.coid)
@ -1174,7 +1056,7 @@ object Ledger {
processNodes(Right(newCacheP), idsToProcess)
case ex: NodeExercises.WithTxValue[ScenarioNodeId, AbsoluteContractId] =>
case ex: NodeExercises.WithTxValue[ScenarioNodeId, ContractId] =>
val newCache0 =
newCache.updateLedgerNodeInfo(ex.targetCoid)(
info =>
@ -1189,9 +1071,9 @@ object Ledger {
.nodeInfoByCoid(ex.targetCoid)
.node
.asInstanceOf[NodeCreate[
AbsoluteContractId,
ContractId,
Transaction.Value[
AbsoluteContractId
ContractId
]]]
nc.key match {
case None => newCache0_1
@ -1211,7 +1093,7 @@ object Ledger {
(Some(nodeId) -> ex.children.toList) :: idsToProcess,
)
case nlkup: NodeLookupByKey.WithTxValue[AbsoluteContractId] =>
case nlkup: NodeLookupByKey.WithTxValue[ContractId] =>
nlkup.result match {
case None =>
processNodes(Right(newCache), idsToProcess)

View File

@ -9,7 +9,7 @@ import com.daml.lf.data.{FrontStack, Numeric, Ref, Time}
import com.daml.lf.language.{Ast, Util => AstUtil}
import com.daml.lf.speedy.SValue._
import com.daml.lf.speedy.{SBuiltin, SExpr, SValue}
import com.daml.lf.value.Value.{AbsoluteContractId, NodeId, RelativeContractId}
import com.daml.lf.value.Value.ContractId
import org.scalatest.prop.{TableDrivenPropertyChecks, TableFor1, TableFor2}
import org.scalatest.{Matchers, WordSpec}
import scalaz._
@ -62,11 +62,8 @@ class EqualitySpec extends WordSpec with Matchers with TableDrivenPropertyChecks
.map(STimestamp compose Time.Timestamp.assertFromString)
private val parties =
List("alice", "bob").map(SParty compose Ref.Party.assertFromString)
private val absoluteContractId =
List("a", "b").map(x => SContractId(AbsoluteContractId.assertFromString("#" + x)))
private val relativeContractId =
List(0, 1).map(x => SContractId(RelativeContractId(NodeId(x))))
private val contractIds = absoluteContractId ++ relativeContractId
private val contractIds =
List("a", "b").map(x => SContractId(ContractId.assertFromString("#" + x)))
private val enums = List(
SEnum(EnumTypeCon, EnumCon1, 0),

View File

@ -15,7 +15,7 @@ import com.daml.lf.speedy.SExpr.SEImportValue
import com.daml.lf.speedy.{SBuiltin, SExpr, SValue}
import com.daml.lf.value.Value
import com.daml.lf.value.TypedValueGenerators.genAddend
import com.daml.lf.value.ValueGenerators.{absCoidV0Gen, comparableAbsCoidsGen}
import com.daml.lf.value.ValueGenerators.{cidV0Gen, comparableCoidsGen}
import com.daml.lf.PureCompiledPackages
import org.scalacheck.Arbitrary
import org.scalatest.prop.{
@ -86,12 +86,9 @@ class OrderingSpec
).map(STimestamp compose Time.Timestamp.assertFromString)
private val parties =
List("alice", "bob", "carol").map(SParty compose Ref.Party.assertFromString)
private val absoluteContractId =
private val contractIds =
List("a", "b", "c")
.map(x => SContractId(Value.AbsoluteContractId.assertFromString("#" + x)))
// private val relativeContractId =
// List(0, 1).map(x => SContractId(Value.RelativeContractId(Value.NodeId(x))))
private val contractIds = absoluteContractId //++ relativeContractId
.map(x => SContractId(Value.ContractId.assertFromString("#" + x)))
private val enums =
List(EnumCon1, EnumCon2, EnumCon3).zipWithIndex.map {
@ -443,9 +440,9 @@ class OrderingSpec
// in Value.orderInstance or TypedValueGenerators, rather than to svalue.Ordering.
// The tests are here as this is difficult to test outside daml-lf/interpreter.
"txn Value Ordering" should {
import Value.{AbsoluteContractId => Cid}
import Value.{ContractId => Cid}
// SContractId V1 ordering is nontotal so arbitrary generation of them is unsafe to use
implicit val cidArb: Arbitrary[Cid] = Arbitrary(absCoidV0Gen)
implicit val cidArb: Arbitrary[Cid] = Arbitrary(cidV0Gen)
implicit val svalueOrd: Order[SValue] = Order fromScalaOrdering Ordering
implicit val cidOrd: Order[Cid] = svalueOrd contramap SValue.SContractId
val EmptyScope: Value.LookupVariantEnum = _ => None
@ -462,10 +459,10 @@ class OrderingSpec
}
}
"match global AbsoluteContractId ordering" in forEvery(Table("gen", comparableAbsCoidsGen: _*)) {
"match global ContractId ordering" in forEvery(Table("gen", comparableCoidsGen: _*)) {
coidGen =>
forAll(coidGen, coidGen, minSuccessful(50)) { (a, b) =>
Cid.`AbsCid Order`.order(a, b) should ===(cidOrd.order(a, b))
Cid.`Cid Order`.order(a, b) should ===(cidOrd.order(a, b))
}
}
}
@ -483,7 +480,7 @@ class OrderingSpec
globalCids = Set.empty,
)
private def translatePrimValue(v: Value[Value.AbsoluteContractId]) = {
private def translatePrimValue(v: Value[Value.ContractId]) = {
val machine = initMachine(SEImportValue(v))
machine.run() match {
case SResultFinalValue(value) => value

View File

@ -8,7 +8,7 @@ import com.daml.lf.types.Ledger._
import com.daml.lf.data.Ref._
import com.daml.lf.data.Time
import com.daml.lf.transaction.Transaction._
import com.daml.lf.value.Value.{AbsoluteContractId, ContractInst}
import com.daml.lf.value.Value.{ContractId, ContractInst}
import com.daml.lf.speedy.SError._
import com.daml.lf.speedy.SResult._
import com.daml.lf.transaction.Node.GlobalKey
@ -144,11 +144,7 @@ final case class ScenarioRunner(
throw SRunnerException(ScenarioErrorCommitError(fas))
case Right(result) =>
ledger = result.newLedger
callback(
value
.mapContractId(coid =>
Ledger
.contractIdToAbsoluteContractId(result.transactionId, coid)))
callback(value)
}
}
@ -158,10 +154,10 @@ final case class ScenarioRunner(
}
private def lookupContract(
acoid: AbsoluteContractId,
acoid: ContractId,
committers: Set[Party],
cbMissing: Unit => Boolean,
cbPresent: ContractInst[Value[AbsoluteContractId]] => Unit) = {
cbPresent: ContractInst[Value[ContractId]] => Unit) = {
val committer =
if (committers.size == 1) committers.head else crashTooManyCommitters(committers)

View File

@ -206,14 +206,14 @@ The submission performs the following steps:
discriminator is not `fresh <Discriminator Freshness_>`_, abort the
interpretation. The submitter can restart the interpretation, which will pick
another submission seed.
* If the transaction succeeds, the output is a *raw transaction*
* If the transaction succeeds, the output is a *submitted transaction*
Depending of the ledger implementation, the local contract IDs are
suffixed with a suffix in a latter step. This yields the *ready
transaction*. For ledgers that do not require suffixing, raw and ready
transaction coincide. Ready transactions are the source of true to
describe the state if the ledger.
Depending on the ledger implementation, the local contract IDs are
suffixed with a suffix in a later step. This yields the *committed
transaction*. For ledgers that do not require suffixing, committed and submitted
transactions coincide. Committed transactions are the source of truth to
derive the state of the ledger.

View File

@ -1 +1 @@
Error: CRASH: Unexpected contract id in key: AbsoluteContractId(007be5e2626fcafa36cdf73e6ad638f3026f866d665764c7bc0ece5e945d71bbfb)
Error: CRASH: Unexpected contract id in key: ContractId(007be5e2626fcafa36cdf73e6ad638f3026f866d665764c7bc0ece5e945d71bbfb)

View File

@ -150,44 +150,39 @@ object ValueGenerators {
def valueGenMapGen: Gen[ValueGenMap[ContractId]] = valueGenMapGen(0)
private val genRel: Gen[ContractId] =
Arbitrary.arbInt.arbitrary.map(i => RelativeContractId(Tx.NodeId(i)))
private val genHash: Gen[crypto.Hash] =
Gen
.containerOfN[Array, Byte](crypto.Hash.underlyingHashLength, arbitrary[Byte]) map crypto.Hash.assertFromByteArray
private val genSuffixes: Gen[Bytes] = for {
sz <- Gen.chooseNum(0, AbsoluteContractId.V1.maxSuffixLength)
sz <- Gen.chooseNum(0, ContractId.V1.maxSuffixLength)
ab <- Gen.containerOfN[Array, Byte](sz, arbitrary[Byte])
} yield Bytes fromByteArray ab
val absCoidV0Gen: Gen[AbsoluteContractId.V0] =
Gen.alphaStr.map(t => Value.AbsoluteContractId.V0.assertFromString('#' +: t))
private val genAbsCidV1: Gen[AbsoluteContractId.V1] =
val cidV0Gen: Gen[ContractId.V0] =
Gen.alphaStr.map(t => Value.ContractId.V0.assertFromString('#' +: t))
private val cidV1Gen: Gen[ContractId.V1] =
Gen.zip(genHash, genSuffixes) map {
case (h, b) => AbsoluteContractId.V1.assertBuild(h, b)
case (h, b) => ContractId.V1.assertBuild(h, b)
}
def absCoidGen: Gen[AbsoluteContractId] = Gen.oneOf(absCoidV0Gen, genAbsCidV1)
/** Universes of totally-ordered AbsoluteContractIds. */
def comparableAbsCoidsGen: Seq[Gen[AbsoluteContractId]] =
/** Universes of totally-ordered ContractIds. */
def comparableCoidsGen: Seq[Gen[ContractId]] =
Seq(
Gen.oneOf(
absCoidV0Gen,
Gen.zip(genAbsCidV1, arbitrary[Byte]) map {
cidV0Gen,
Gen.zip(cidV1Gen, arbitrary[Byte]) map {
case (b1, b) =>
AbsoluteContractId.V1
ContractId.V1
.assertBuild(
b1.discriminator,
if (b1.suffix.nonEmpty) b1.suffix else Bytes fromByteArray Array(b)
)
}
),
Gen.oneOf(absCoidV0Gen, genAbsCidV1 map (cid => AbsoluteContractId.V1(cid.discriminator))),
Gen.oneOf(cidV0Gen, cidV1Gen map (cid => ContractId.V1(cid.discriminator))),
)
def coidGen: Gen[ContractId] =
Gen.frequency((1, genRel), (3, absCoidV0Gen))
def coidGen: Gen[ContractId] = Gen.oneOf(cidV0Gen, cidV1Gen)
def coidValueGen: Gen[ValueContractId[ContractId]] =
coidGen.map(ValueContractId(_))
@ -439,7 +434,7 @@ object ValueGenerators {
disclosed1 <- nodePartiesGen
disclosed2 <- nodePartiesGen
divulged <- Gen.mapOf(
absCoidV0Gen.flatMap(c => genMaybeEmptyParties.map(ps => (c: AbsoluteContractId) -> ps)))
cidV0Gen.flatMap(c => genMaybeEmptyParties.map(ps => (c: ContractId) -> ps)))
} yield BlindingInfo(disclosed1, disclosed2, divulged)
}

View File

@ -20,7 +20,7 @@ sealed trait Command extends Product with Serializable {
* @param templateId identifier of the template that the contract is instantiating
* @param argument value passed to the template
*/
final case class CreateCommand(templateId: Identifier, argument: Value[Value.AbsoluteContractId])
final case class CreateCommand(templateId: Identifier, argument: Value[Value.ContractId])
extends Command
/** Command for exercising a choice on an existing contract
@ -32,9 +32,9 @@ final case class CreateCommand(templateId: Identifier, argument: Value[Value.Abs
*/
final case class ExerciseCommand(
templateId: Identifier,
contractId: Value.AbsoluteContractId,
contractId: Value.ContractId,
choiceId: ChoiceName,
argument: Value[Value.AbsoluteContractId],
argument: Value[Value.ContractId],
) extends Command
/** Command for exercising a choice on an existing contract specified by its key
@ -46,9 +46,9 @@ final case class ExerciseCommand(
*/
final case class ExerciseByKeyCommand(
templateId: Identifier,
contractKey: Value[Value.AbsoluteContractId],
contractKey: Value[Value.ContractId],
choiceId: ChoiceName,
argument: Value[Value.AbsoluteContractId],
argument: Value[Value.ContractId],
) extends Command
/** Command for creating a contract and exercising a choice
@ -61,9 +61,9 @@ final case class ExerciseByKeyCommand(
*/
final case class CreateAndExerciseCommand(
templateId: Identifier,
createArgument: Value[Value.AbsoluteContractId],
createArgument: Value[Value.ContractId],
choiceId: ChoiceName,
choiceArgument: Value[Value.AbsoluteContractId],
choiceArgument: Value[Value.ContractId],
) extends Command
/** Commands input adapted from ledger-api

View File

@ -79,12 +79,10 @@ object Hash {
@throws[HashingError]
private[lf] val aCid2Bytes: Value.ContractId => Bytes = {
case cid @ Value.AbsoluteContractId.V1(_, _) =>
case cid @ Value.ContractId.V1(_, _) =>
cid.toBytes
case Value.AbsoluteContractId.V0(s) =>
case Value.ContractId.V0(s) =>
Utf8.getBytes(s)
case Value.RelativeContractId(_) =>
error("Hashing of relative contract id is not supported")
}
@throws[HashingError]

View File

@ -4,7 +4,7 @@
package com.daml.lf.transaction
import com.daml.lf.data.Ref._
import com.daml.lf.value.Value.AbsoluteContractId
import com.daml.lf.value.Value.ContractId
import com.daml.lf.value.ValueCoder.DecodeError
import com.daml.lf.{blinding => proto}
import com.google.protobuf.ProtocolStringList
@ -92,7 +92,7 @@ object BlindingCoder {
}
}
private def toContractId(s: String): Either[DecodeError, AbsoluteContractId] =
AbsoluteContractId.fromString(s).left.map(err => DecodeError(s"Cannot decode contractId: $err"))
private def toContractId(s: String): Either[DecodeError, ContractId] =
ContractId.fromString(s).left.map(err => DecodeError(s"Cannot decode contractId: $err"))
}

View File

@ -5,7 +5,7 @@ package com.daml.lf.transaction
import com.daml.lf.data.Ref.Party
import com.daml.lf.data.Relation.Relation
import com.daml.lf.value.Value.AbsoluteContractId
import com.daml.lf.value.Value.ContractId
/** This gives disclosure and divulgence info.
*
@ -15,7 +15,7 @@ import com.daml.lf.value.Value.AbsoluteContractId
* "Divulgence" tells us what to communicate to
* each participant node so that they can perform post-commit
* validation. Note that divulgence can also divulge
* absolute contract ids -- e.g. contract ids that were created
* contract ids -- e.g. contract ids that were created
* _outside_ this transaction.
* See also https://docs.daml.com/concepts/ledger-model/ledger-privacy.html#divulgence-when-non-stakeholders-see-contracts
*/
@ -25,12 +25,12 @@ case class BlindingInfo(
/** Divulgence, specified in terms of local node IDs */
localDivulgence: Relation[Transaction.NodeId, Party],
/**
* Divulgence, specified in terms of absolute contract IDs.
* Divulgence, specified in terms of contract IDs.
* Note that if this info was produced by blinding a transaction
* containing only absolute contract ids, this map may also
* containing only contract ids, this map may also
* contain contracts produced in the same transaction.
*/
globalDivulgence: Relation[AbsoluteContractId, Party],
globalDivulgence: Relation[ContractId, Party],
) {
def localDisclosure: Relation[Transaction.NodeId, Party] =
Relation.union(disclosure, localDivulgence)

View File

@ -8,7 +8,7 @@ import com.daml.lf.crypto.Hash
import com.daml.lf.data.{ImmArray, Ref, ScalazEqual}
import com.daml.lf.data.Ref._
import com.daml.lf.value.Value
import com.daml.lf.value.Value.{AbsoluteContractId, ContractInst}
import com.daml.lf.value.Value.{ContractId, ContractInst}
import scala.language.higherKinds
import scalaz.Equal
@ -54,9 +54,7 @@ object Node {
GenNode.foreach3(fNid, fCid, fVal)(self)
}
object GenNode
extends WithTxValue3[GenNode]
with value.CidContainer3WithDefaultCidResolver[GenNode] {
object GenNode extends WithTxValue3[GenNode] with value.CidContainer3[GenNode] {
override private[lf] def map3[A1, A2, A3, B1, B2, B3](
f1: A1 => B1,
@ -323,7 +321,7 @@ object Node {
KeyWithMaintainers.foreach1(f)(self)
}
object KeyWithMaintainers extends value.CidContainer1WithDefaultCidResolver[KeyWithMaintainers] {
object KeyWithMaintainers extends value.CidContainer1[KeyWithMaintainers] {
implicit def equalInstance[Val: Equal]: Equal[KeyWithMaintainers[Val]] =
ScalazEqual.withNatural(Equal[Val].equalIsNatural) { (a, b) =>
import a._
@ -407,7 +405,7 @@ object Node {
*/
final class GlobalKey private (
val templateId: Identifier,
val key: Value[AbsoluteContractId],
val key: Value[ContractId],
val hash: Hash
) extends {
override def equals(obj: Any): Boolean = obj match {
@ -423,10 +421,10 @@ object Node {
new GlobalKey(templateId, key, Hash.safeHashContractKey(templateId, key))
// Will fail if key contains contract ids
def build(templateId: Identifier, key: Value[AbsoluteContractId]): Either[String, GlobalKey] =
def build(templateId: Identifier, key: Value[ContractId]): Either[String, GlobalKey] =
Hash.hashContractKey(templateId, key).map(new GlobalKey(templateId, key, _))
def assertBuild(templateId: Identifier, key: Value[AbsoluteContractId]): GlobalKey =
def assertBuild(templateId: Identifier, key: Value[ContractId]): GlobalKey =
data.assertRight(build(templateId, key))
}

View File

@ -54,12 +54,6 @@ case class VersionedTransaction[Nid, Cid](
*
* Abstracts over NodeId type and ContractId type
* ContractId restricts the occurrence of contractIds
* either AbsoluteContractId if only absolute ids occur
* or ContractId when both absolute and relative ids are allowed
*
* The Cid parameter is invariant on purpose, since we do not want
* to confuse transactions with AbsoluteContractId and ones with ContractId.
* For example, when enriching the transaction the difference is key.
*
* @param nodes The nodes of this transaction.
* @param roots References to the root nodes of the transaction.
@ -386,7 +380,7 @@ final case class GenTransaction[Nid, +Cid, +Val](
}
object GenTransaction extends value.CidContainer3WithDefaultCidResolver[GenTransaction] {
object GenTransaction extends value.CidContainer3[GenTransaction] {
type WithTxValue[Nid, +Cid] = GenTransaction[Nid, Cid, Transaction.Value[Cid]]
@ -476,9 +470,9 @@ object Transaction {
byKeyNodes: ImmArray[Value.NodeId],
)
type AbsTransaction = GenTransaction.WithTxValue[NodeId, Value.AbsoluteContractId]
type AbsTransaction = GenTransaction.WithTxValue[NodeId, Value.ContractId]
type AbsNode = GenNode.WithTxValue[NodeId, Value.AbsoluteContractId]
type AbsNode = GenNode.WithTxValue[NodeId, Value.ContractId]
/** Errors that can happen during building transactions. */
sealed abstract class TransactionError extends Product with Serializable

View File

@ -4,7 +4,7 @@
package com.daml.lf
package value
import com.daml.lf.data.{Bytes, Ref}
import com.daml.lf.data.Bytes
import scala.language.higherKinds
import scala.util.control.NoStackTrace
@ -33,13 +33,8 @@ object CidMapper {
type NoCidChecker[-A1, +A2] = CidChecker[A1, A2, Nothing]
type NoRelCidChecker[-A1, +A2] = CidChecker[A1, A2, Value.AbsoluteContractId]
type RelCidResolver[-A1, +A2] =
CidMapper[A1, A2, Value.RelativeContractId, Ref.ContractIdString]
type CidSuffixer[-A1, +A2] =
CidMapper[A1, A2, Value.ContractId, Value.AbsoluteContractId.V1]
CidMapper[A1, A2, Value.ContractId, Value.ContractId.V1]
@SuppressWarnings(Array("org.wartremover.warts.Any"))
private val _trivialMapper: CidMapper[Any, Any, Nothing, Any] =
@ -54,21 +49,6 @@ object CidMapper {
new CidMapper[Cid1, Cid2, Cid1, Cid2] {
override def map(f: Cid1 => Cid2): Cid1 => Cid2 = f
}
private[value] val basicCidResolverInstance
: RelCidResolver[Value.ContractId, Value.AbsoluteContractId] =
new CidMapper[
Value.ContractId,
Value.AbsoluteContractId,
Value.RelativeContractId,
Ref.ContractIdString] {
override def map(
f: Value.RelativeContractId => Ref.ContractIdString,
): Value.ContractId => Value.AbsoluteContractId = {
case acoid: Value.AbsoluteContractId => acoid
case rcoid: Value.RelativeContractId => Value.AbsoluteContractId.V0(f(rcoid))
}
}
}
trait CidContainer[+A] {
@ -77,11 +57,6 @@ trait CidContainer[+A] {
protected val self: A
final def resolveRelCid[B](f: Value.RelativeContractId => Ref.ContractIdString)(
implicit resolver: RelCidResolver[A, B]
): B =
resolver.map(f)(self)
final def ensureNoCid[B](
implicit checker: NoCidChecker[A, B]
): Either[Value.ContractId, B] =
@ -92,36 +67,21 @@ trait CidContainer[+A] {
): B =
data.assertRight(ensureNoCid.left.map(message))
final def ensureNoRelCid[B](
implicit checker: NoRelCidChecker[A, B]
): Either[Value.RelativeContractId, B] =
checker.traverse[Value.RelativeContractId] {
case acoid: Value.AbsoluteContractId => Right(acoid)
case rcoid: Value.RelativeContractId => Left(rcoid)
}(self)
// Sets the suffix of any the V1 AbsoluteContractId `coid` of the container that are not already suffixed.
// Sets the suffix of any the V1 ContractId `coid` of the container that are not already suffixed.
// Uses `f(coid.discriminator)` as suffix.
final def suffixCid[B](f: crypto.Hash => Bytes)(
implicit suffixer: CidSuffixer[A, B]
): Either[String, B] = {
suffixer.traverse[String] {
case Value.AbsoluteContractId.V1(discriminator, Bytes.Empty) =>
Value.AbsoluteContractId.V1.build(discriminator, f(discriminator))
case acoid @ Value.AbsoluteContractId.V1(_, _) =>
case Value.ContractId.V1(discriminator, Bytes.Empty) =>
Value.ContractId.V1.build(discriminator, f(discriminator))
case acoid @ Value.ContractId.V1(_, _) =>
Right(acoid)
case acoid @ Value.AbsoluteContractId.V0(_) =>
case acoid @ Value.ContractId.V0(_) =>
Left(s"expect a Contract ID V1, found $acoid")
case rcoid @ Value.RelativeContractId(_) =>
Left(s"expect a Contract Id V1, found $rcoid")
}(self)
}
final def assertNoRelCid[B](message: Value.ContractId => String)(
implicit checker: NoRelCidChecker[A, B]
): B =
data.assertRight(ensureNoRelCid.left.map(message))
}
trait CidContainer1[F[_]] {
@ -145,11 +105,6 @@ trait CidContainer1[F[_]] {
): NoCidChecker[F[A1], F[A2]] =
cidMapperInstance[A1, A2, Value.ContractId, Nothing]
final implicit def noRelCidCheckerInstance[A1, A2](
implicit checker1: NoRelCidChecker[A1, A2],
): NoRelCidChecker[F[A1], F[A2]] =
cidMapperInstance[A1, A2, Value.ContractId, Value.AbsoluteContractId]
final implicit def cidSuffixerInstance[A1, A2](
implicit resolver1: CidSuffixer[A1, A2],
): CidSuffixer[F[A1], F[A2]] =
@ -157,17 +112,6 @@ trait CidContainer1[F[_]] {
}
trait CidContainer1WithDefaultCidResolver[F[_]] extends CidContainer1[F] {
import CidMapper._
final implicit def cidResolverInstance[A1, A2](
implicit resolver1: RelCidResolver[A1, A2],
): RelCidResolver[F[A1], F[A2]] =
cidMapperInstance(resolver1)
}
trait CidContainer3[F[_, _, _]] {
import CidMapper._
@ -195,13 +139,6 @@ trait CidContainer3[F[_, _, _]] {
}
}
final implicit def noRelCidCheckerInstance[A1, B1, C1, A2, B2, C2](
implicit checker1: NoRelCidChecker[A1, A2],
checker2: NoRelCidChecker[B1, B2],
checker3: NoRelCidChecker[C1, C2],
): NoRelCidChecker[F[A1, B1, C1], F[A2, B2, C2]] =
cidMapperInstance
final implicit def cidSuffixerInstance[A1, B1, C1, A2, B2, C2](
implicit suffixer1: CidSuffixer[A1, A2],
suffixer2: CidSuffixer[B1, B2],
@ -210,16 +147,3 @@ trait CidContainer3[F[_, _, _]] {
cidMapperInstance
}
trait CidContainer3WithDefaultCidResolver[F[_, _, _]] extends CidContainer3[F] {
import CidMapper._
final implicit def cidResolverInstance[A1, B1, C1, A2, B2, C2](
implicit resolver1: RelCidResolver[A1, A2],
resolver2: RelCidResolver[B1, B2],
resolver3: RelCidResolver[C1, C2],
): RelCidResolver[F[A1, B1, C1], F[A2, B2, C2]] =
cidMapperInstance
}

View File

@ -145,7 +145,7 @@ sealed abstract class Value[+Cid] extends CidContainer[Value[Cid]] with Product
}
object Value extends CidContainer1WithDefaultCidResolver[Value] {
object Value extends CidContainer1[Value] {
// TODO (FM) make this tail recursive
private[lf] override def map1[Cid, Cid2](f: Cid => Cid2): Value[Cid] => Value[Cid2] = {
@ -247,11 +247,6 @@ object Value extends CidContainer1WithDefaultCidResolver[Value] {
override private[lf] def map1[A, B](f: A => B): VersionedValue[A] => VersionedValue[B] =
x => x.copy(value = Value.map1(f)(x.value))
final implicit def cidResolverInstance[A1, A2](
implicit mapper1: CidMapper.RelCidResolver[A1, A2],
): CidMapper.RelCidResolver[VersionedValue[A1], VersionedValue[A2]] =
cidMapperInstance
override private[lf] def foreach1[A](f: A => Unit): VersionedValue[A] => Unit =
x => Value.foreach1(f)(x.value)
}
@ -327,7 +322,7 @@ object Value extends CidContainer1WithDefaultCidResolver[Value] {
}
object ContractInst extends CidContainer1WithDefaultCidResolver[ContractInst] {
object ContractInst extends CidContainer1[ContractInst] {
implicit def equalInstance[Val: Equal]: Equal[ContractInst[Val]] =
ScalazEqual.withNatural(Equal[Val].equalIsNatural) { (a, b) =>
import a._
@ -344,30 +339,19 @@ object Value extends CidContainer1WithDefaultCidResolver[Value] {
type NodeIdx = Int
/** Possibly relative contract identifiers.
*
* The contract identifiers can be either absolute, referring to a
* specific instance in the contract store, or relative, referring
* to a contract created in the same transaction and hence not yet
* having been assigned an absolute identifier.
*
* Note that relative contract ids are useful only before commit, in
* the context of a transaction. After committing we should never
* mention them.
*
* Why put it here and not just in Transaction.scala? Because we want
* to be able to use AbsoluteContractId elsewhere, so that we can
* automatically upcast to ContractId by subtyping.
*/
sealed abstract class ContractId extends Product with Serializable
@deprecated("Use ContractId", since = "1.1.2")
type AbsoluteContractId = ContractId
sealed abstract class AbsoluteContractId extends ContractId {
@deprecated("Use ContractId", since = "1.1.2")
val AbsoluteContractId: ContractId.type = ContractId
sealed abstract class ContractId extends Product with Serializable {
def coid: String
}
object AbsoluteContractId {
final case class V0(coid: Ref.ContractIdString) extends AbsoluteContractId {
override def toString: String = s"AbsoluteContractId($coid)"
object ContractId {
final case class V0(coid: Ref.ContractIdString) extends ContractId {
override def toString: String = s"ContractId($coid)"
}
object V0 {
@ -380,11 +364,11 @@ object Value extends CidContainer1WithDefaultCidResolver[Value] {
}
final case class V1 private (discriminator: crypto.Hash, suffix: Bytes)
extends AbsoluteContractId
extends ContractId
with data.NoCopy {
lazy val toBytes: Bytes = V1.prefix ++ discriminator.bytes ++ suffix
lazy val coid: Ref.HexString = toBytes.toHexString
override def toString: String = s"AbsoluteContractId($coid)"
override def toString: String = s"ContractId($coid)"
}
object V1 {
@ -423,25 +407,25 @@ object Value extends CidContainer1WithDefaultCidResolver[Value] {
def assertFromString(s: String): V1 = assertRight(fromString(s))
implicit val `V1 Order`: Order[V1] = {
case (AbsoluteContractId.V1(hash1, suffix1), AbsoluteContractId.V1(hash2, suffix2)) =>
case (ContractId.V1(hash1, suffix1), ContractId.V1(hash2, suffix2)) =>
hash1 ?|? hash2 |+| suffix1 ?|? suffix2
}
}
def fromString(s: String): Either[String, AbsoluteContractId] =
def fromString(s: String): Either[String, ContractId] =
V1.fromString(s)
.left
.flatMap(_ => V0.fromString(s))
.left
.map(_ => s"""cannot parse ContractId "$s"""")
def assertFromString(s: String): AbsoluteContractId =
def assertFromString(s: String): ContractId =
assertRight(fromString(s))
implicit val `AbsCid Order`: Order[AbsoluteContractId] = new Order[AbsoluteContractId] {
implicit val `Cid Order`: Order[ContractId] = new Order[ContractId] {
import scalaz.Ordering._
override def order(a: AbsoluteContractId, b: AbsoluteContractId) =
override def order(a: ContractId, b: ContractId) =
(a, b) match {
case (a: V0, b: V0) => a ?|? b
case (a: V1, b: V1) => a ?|? b
@ -449,7 +433,7 @@ object Value extends CidContainer1WithDefaultCidResolver[Value] {
case (_: V1, _: V0) => GT
}
override def equal(a: AbsoluteContractId, b: AbsoluteContractId) =
override def equal(a: ContractId, b: ContractId) =
(a, b).match2 {
case a: V0 => { case b: V0 => a === b }
case V1(discA, suffA) => {
@ -457,21 +441,13 @@ object Value extends CidContainer1WithDefaultCidResolver[Value] {
}
}(fallback = false)
}
}
final case class RelativeContractId(txnid: NodeId) extends ContractId
object ContractId {
implicit val equalInstance: Equal[ContractId] = Equal.equalA
implicit val noCidMapper: CidMapper.NoCidChecker[ContractId, Nothing] =
CidMapper.basicMapperInstance[ContractId, Nothing]
implicit val noRelCidMapper: CidMapper.NoRelCidChecker[ContractId, AbsoluteContractId] =
CidMapper.basicMapperInstance[ContractId, AbsoluteContractId]
implicit val relCidResolver: CidMapper.RelCidResolver[ContractId, AbsoluteContractId] =
CidMapper.basicCidResolverInstance
implicit val cidSuffixer: CidMapper.CidSuffixer[ContractId, AbsoluteContractId.V1] =
CidMapper.basicMapperInstance[ContractId, AbsoluteContractId.V1]
implicit val cidSuffixer: CidMapper.CidSuffixer[ContractId, ContractId.V1] =
CidMapper.basicMapperInstance[ContractId, ContractId.V1]
}
/** The constructor is private so that we make sure that only this object constructs

View File

@ -12,8 +12,6 @@ import com.daml.lf.value.{ValueOuterClass => proto}
import com.google.protobuf
import scala.collection.JavaConverters._
import scalaz.std.either._
import scalaz.syntax.bifunctor._
/**
* Utilities to serialize and de-serialize Values
@ -53,30 +51,21 @@ object ValueCoder {
): Either[EncodeError, Either[String, (proto.ContractId)]]
}
@deprecated("use CidEndocer", since = "1.1.2")
val AbsCidDecoder = CidEncoder
object CidEncoder extends EncodeCid[ContractId] {
private[lf] def encode(
sv: SpecifiedVersion,
cid: ContractId
): Either[EncodeError, Either[String, (proto.ContractId)]] =
if (useOldStringField(sv))
cid match {
case RelativeContractId(nid) =>
Right(Left("~" + nid.index.toString))
case acoid: AbsoluteContractId =>
Right(Left(acoid.coid))
} else
cid match {
case RelativeContractId(nid) =>
Right(
Right(
proto.ContractId.newBuilder
.setRelative(true)
.setContractId(nid.index.toString)
.build))
case acoid: AbsoluteContractId =>
Right(
Right(proto.ContractId.newBuilder.setRelative(false).setContractId(acoid.coid).build))
}
): Either[EncodeError, Either[String, proto.ContractId]] =
Right(
Either.cond(
!useOldStringField(sv),
proto.ContractId.newBuilder.setRelative(false).setContractId(cid.coid).build,
cid.coid,
)
)
}
abstract class DecodeCid[Cid] private[lf] {
@ -99,22 +88,12 @@ object ValueCoder {
val CidDecoder: DecodeCid[ContractId] = new DecodeCid[ContractId] {
private def stringToRelativeCid(s: String) =
scalaz.std.string
.parseInt(s)
.toEither
.bimap(
_ => //
DecodeError(s"""cannot parse relative contractId "$s""""),
idx => Some(RelativeContractId(NodeId(idx)))
)
private def stringToCidString(s: String): Either[DecodeError, Value.AbsoluteContractId] =
Value.AbsoluteContractId
private def stringToCidString(s: String): Either[DecodeError, Value.ContractId] =
Value.ContractId
.fromString(s)
.left
.map(_ => //
DecodeError(s"""cannot parse absolute contractId "$s""""))
DecodeError(s"""cannot parse contractId "$s""""))
override def decodeOptional(
sv: SpecifiedVersion,
@ -127,8 +106,6 @@ object ValueCoder {
} else {
if (stringForm.isEmpty)
Right(None)
else if (stringForm.startsWith("~"))
stringToRelativeCid(stringForm.drop(1))
else
stringToCidString(stringForm).map(Some(_))
}
@ -137,30 +114,12 @@ object ValueCoder {
Left(DecodeError(s"${sv.showsVersion} is too new to use string contract IDs"))
else if (structForm.getContractId.isEmpty)
Right(None)
else if (structForm.getRelative)
stringToRelativeCid(structForm.getContractId)
else
stringToCidString(structForm.getContractId).map(Some(_))
}
}
val AbsCidDecoder: DecodeCid[AbsoluteContractId] = new DecodeCid[AbsoluteContractId] {
override def decodeOptional(
sv: SpecifiedVersion,
stringForm: String,
structForm: ValueOuterClass.ContractId,
): Either[DecodeError, Option[AbsoluteContractId]] =
CidDecoder.decodeOptional(sv, stringForm, structForm).flatMap {
case Some(cid: AbsoluteContractId) =>
Right(Some(cid))
case Some(RelativeContractId(_)) =>
Left(DecodeError("Unexpected relative contractId"))
case None =>
Right(None)
}
}
/**
* Simple encoding to wire of identifiers
* @param id identifier value
@ -232,8 +191,7 @@ object ValueCoder {
*
* @param protoValue0 the value to be read
* @param decodeCid a function to decode stringified contract ids
* @tparam Cid ContractId type as ContractId (allowing RelativeContractIds) or AbsoluteContractId
* see [[com.daml.lf.value.Value]] and [[com.daml.lf.value.Value.ContractId]]
* @tparam Cid ContractId type
* @return either error or [VersionedValue]
*/
def decodeVersionedValue[Cid](
@ -257,8 +215,7 @@ object ValueCoder {
*
* @param value value to be written
* @param encodeCid a function to stringify contractIds (it's better to be invertible)
* @tparam Cid ContractId type as ContractId (allowing RelativeContractIds) or AbsoluteContractId
* see [[com.daml.lf.value.Value]] and [[com.daml.lf.value.Value.ContractId]]
* @tparam Cid ContractId type
* @return protocol buffer serialized values
*/
def encodeVersionedValue[Cid](
@ -277,8 +234,7 @@ object ValueCoder {
*
* @param versionedValue value to be written
* @param encodeCid a function to stringify contractIds (it's better to be invertible)
* @tparam Cid ContractId type as ContractId (allowing RelativeContractIds) or AbsoluteContractId
* see [[com.daml.lf.value.Value]] and [[com.daml.lf.value.Value.ContractId]]
* @tparam Cid ContractId type
* @return protocol buffer serialized values
*/
def encodeVersionedValueWithCustomVersion[Cid](
@ -298,8 +254,7 @@ object ValueCoder {
*
* @param protoValue0 the value to be read
* @param decodeCid a function to decode stringified contract ids
* @tparam Cid ContractId type as ContractId (allowing RelativeContractIds) or AbsoluteContractId
* see [[com.daml.lf.value.Value]] and [[com.daml.lf.value.Value.ContractId]]
* @tparam Cid ContractId type
* @return either error or Value
*/
def decodeValue[Cid](
@ -467,8 +422,7 @@ object ValueCoder {
* @param v0 value to be written
* @param encodeCid a function to stringify contractIds (it's better to be invertible)
* @param valueVersion version of value specification to encode to, or fail
* @tparam Cid ContractId type as ContractId (allowing RelativeContractIds) or AbsoluteContractId
* see [[com.daml.lf.value.Value]] and [[com.daml.lf.value.Value.ContractId]]
* @tparam Cid ContractId type
* @return protocol buffer serialized values
*/
def encodeValue[Cid](

View File

@ -305,7 +305,7 @@ class HashSpec extends WordSpec with Matchers {
"stable " in {
type V = Value[AbsoluteContractId]
type V = Value[ContractId]
val pkgId = Ref.PackageId.assertFromString("pkgId")
@ -347,7 +347,7 @@ class HashSpec extends WordSpec with Matchers {
"0007e7b5534931dfca8e1b485c105bae4e10808bd13ddc8e897f258015f9d921c5",
"0059b59ad7a6b6066e77b91ced54b8282f0e24e7089944685cb8f22f32fcbc4e1b",
).map { str =>
VA.contractId.inj(AbsoluteContractId.V1 assertFromString str)
VA.contractId.inj(ContractId.V1 assertFromString str)
}
val enumT1 = VA.enum("Color", List("Red", "Green"))._2
@ -468,9 +468,9 @@ class HashSpec extends WordSpec with Matchers {
| 274830656c6f7de1daf729d11c57c40ef271a101a831d89e45f034ce7bd71d9d
|ValueParty(bob)
| dc1f0fc026d3200a1781f0989dd1801022e028e8afe5d953a033e6d35e8ea50b
|ValueContractId(AbsoluteContractId(0007e7b5534931dfca8e1b485c105bae4e10808bd13ddc8e897f258015f9d921c5))
|ValueContractId(ContractId(0007e7b5534931dfca8e1b485c105bae4e10808bd13ddc8e897f258015f9d921c5))
| 0649b1e1e7f34be457c44146e449299109167b9199101349873142ed05878b96
|ValueContractId(AbsoluteContractId(0059b59ad7a6b6066e77b91ced54b8282f0e24e7089944685cb8f22f32fcbc4e1b))
|ValueContractId(ContractId(0059b59ad7a6b6066e77b91ced54b8282f0e24e7089944685cb8f22f32fcbc4e1b))
| 0b8c0cc8ebbd56e275b60cf73133387322a42448986dc3858b31eef23098e8e8
|ValueOptional(None)
| 01cf85cfeb36d628ca2e6f583fa2331be029b6b28e877e1008fb3f862306c086

View File

@ -303,7 +303,7 @@ class TransactionCoderSpec
"do tx with a lot of root nodes" in {
val node =
Node.NodeCreate[Value.AbsoluteContractId, Value.VersionedValue[Value.AbsoluteContractId]](
Node.NodeCreate[Value.ContractId, Value.VersionedValue[Value.ContractId]](
coid = absCid("#test-cid"),
coinst = ContractInst(
Identifier(
@ -402,7 +402,7 @@ class TransactionCoderSpec
)
}
private def absCid(s: String): Value.AbsoluteContractId =
Value.AbsoluteContractId.assertFromString(s)
private def absCid(s: String): Value.ContractId =
Value.ContractId.assertFromString(s)
}

View File

@ -187,8 +187,8 @@ class TransactionSpec extends FreeSpec with Matchers with GeneratorDrivenPropert
)
val mapping2: V.ContractId => V.ContractId = Map(
cid1 -> V.AbsoluteContractId.V1.assertBuild(cid1.discriminator, suffix1),
cid2 -> V.AbsoluteContractId.V1.assertBuild(cid2.discriminator, suffix2),
cid1 -> V.ContractId.V1.assertBuild(cid1.discriminator, suffix1),
cid2 -> V.ContractId.V1.assertBuild(cid2.discriminator, suffix2),
)
dummyCreateNode("dd").coinst.suffixCid(mapping1)
@ -236,7 +236,7 @@ object TransactionSpec {
key = None,
)
val dummyCid = V.AbsoluteContractId.V1.assertBuild(
val dummyCid = V.ContractId.V1.assertBuild(
toCid("dummyCid").discriminator,
Bytes.assertFromString("f00d"),
)
@ -260,7 +260,7 @@ object TransactionSpec {
implicit def toChoiceName(s: String): Ref.Name = Ref.Name.assertFromString(s)
implicit def toCid(s: String): V.AbsoluteContractId.V1 =
V.AbsoluteContractId.V1(crypto.Hash.hashPrivateKey(s))
implicit def toCid(s: String): V.ContractId.V1 =
V.ContractId.V1(crypto.Hash.hashPrivateKey(s))
}

View File

@ -7,7 +7,7 @@ package value
import data.{Bytes, FrontStack, ImmArray, Ref, Unnatural}
import Value._
import Ref.{Identifier, Name}
import ValueGenerators.{absCoidGen, idGen, nameGen}
import ValueGenerators.{coidGen, idGen, nameGen}
import TypedValueGenerators.{RNil, genAddend, ValueAddend => VA}
import org.scalacheck.{Arbitrary, Gen, Shrink}
import org.scalatest.prop.{Checkers, GeneratorDrivenPropertyChecks, TableDrivenPropertyChecks}
@ -78,35 +78,11 @@ class ValueSpec
}
"ensureNoRelCid is used " in {
val value = VersionedValue(
ValueVersions.minVersion,
ValueContractId(AbsoluteContractId.assertFromString("#0:0")),
)
val contract = ContractInst(tmplId, value, "agreed")
value.ensureNoRelCid.map(_.version) shouldBe Right(ValueVersions.minVersion)
contract.ensureNoRelCid.map(_.arg.version) shouldBe Right(ValueVersions.minVersion)
}
"resolveRelCidV0 is used" in {
val value = VersionedValue(
ValueVersions.minVersion,
ValueContractId(ValueContractId(RelativeContractId(NodeId(0)))),
)
val contract = ContractInst(tmplId, value, "agreed")
val resolver: RelativeContractId => Ref.ContractIdString = {
case RelativeContractId(NodeId(idx)) =>
Ref.ContractIdString.assertFromString(s"#0:$idx")
}
value.resolveRelCid(resolver).version shouldBe ValueVersions.minVersion
contract.resolveRelCid(resolver).arg.version shouldBe ValueVersions.minVersion
}
}
}
"AbsoluteContractID.V1.build" - {
"ContractID.V1.build" - {
"rejects too long suffix" in {
@ -114,7 +90,7 @@ class ValueSpec
Bytes.fromByteArray(Array.iterate(0.toByte, size)(b => (b + 1).toByte))
val hash = crypto.Hash.hashPrivateKey("some hash")
import AbsoluteContractId.V1.build
import ContractId.V1.build
build(hash, suffix(0)) shouldBe 'right
build(hash, suffix(94)) shouldBe 'right
build(hash, suffix(95)) shouldBe 'left
@ -139,9 +115,9 @@ class ValueSpec
}
}
"AbsoluteContractId" - {
type T = AbsoluteContractId
implicit val arbT: Arbitrary[T] = Arbitrary(absCoidGen)
"ContractId" - {
type T = ContractId
implicit val arbT: Arbitrary[T] = Arbitrary(coidGen)
"Order" - {
"obeys Order laws" in checkLaws(SzP.order.laws[T])
}

View File

@ -24,7 +24,7 @@ import com.daml.lf.speedy.{InitialSeeding, Pretty, SExpr, SValue, Speedy}
import com.daml.lf.speedy.SResult._
import com.daml.lf.speedy.SValue._
import com.daml.lf.value.Value
import com.daml.lf.value.Value.AbsoluteContractId
import com.daml.lf.value.Value.ContractId
import com.daml.lf.CompiledPackages
import com.daml.ledger.api.v1.value
import com.daml.lf.data.Time
@ -75,12 +75,6 @@ object Converter {
DA_INTERNAL_ANY_PKGID,
QualifiedName(DottedName.assertFromString("DA.Internal.Any"), DottedName.assertFromString(s)))
private def toLedgerRecord(v: SValue): Either[String, Value[AbsoluteContractId]] =
v.toValue.ensureNoRelCid.left.map(rcoid => s"Unexpected contract id $rcoid")
private def toLedgerValue(v: SValue): Either[String, Value[AbsoluteContractId]] =
v.toValue.ensureNoRelCid.left.map(rcoid => s"Unexpected contract id $rcoid")
def toFuture[T](s: Either[String, T]): Future[T] = s match {
case Left(err) => Future.failed(new ConverterException(err))
case Right(s) => Future.successful(s)
@ -141,16 +135,19 @@ object Converter {
case SRecord(_, _, vals) if vals.size == 2 => {
for {
anyTemplate <- toAnyTemplate(vals.get(0))
templateArg <- toLedgerRecord(anyTemplate.arg)
} yield ScriptLedgerClient.CreateCommand(anyTemplate.ty, templateArg)
} yield
ScriptLedgerClient.CreateCommand(
templateId = anyTemplate.ty,
argument = anyTemplate.arg.toValue,
)
}
case _ => Left(s"Expected Create but got $v")
}
def toContractId(v: SValue): Either[String, AbsoluteContractId] =
def toContractId(v: SValue): Either[String, ContractId] =
v match {
case SContractId(cid: AbsoluteContractId) => Right(cid)
case _ => Left(s"Expected AbsoluteContractId but got $v")
case SContractId(cid: ContractId) => Right(cid)
case _ => Left(s"Expected ContractId but got $v")
}
def toExerciseCommand(v: SValue): Either[String, ScriptLedgerClient.Command] =
@ -161,8 +158,13 @@ object Converter {
tplId <- typeRepToIdentifier(vals.get(0))
cid <- toContractId(vals.get(1))
anyChoice <- toAnyChoice(vals.get(2))
choiceArg <- toLedgerValue(anyChoice.arg)
} yield ScriptLedgerClient.ExerciseCommand(tplId, cid, anyChoice.name, choiceArg)
} yield
ScriptLedgerClient.ExerciseCommand(
templateId = tplId,
contractId = cid,
choice = anyChoice.name,
argument = anyChoice.arg.toValue,
)
}
case _ => Left(s"Expected Exercise but got $v")
}
@ -174,10 +176,14 @@ object Converter {
for {
tplId <- typeRepToIdentifier(vals.get(0))
anyKey <- toAnyContractKey(vals.get(1))
keyArg <- toLedgerValue(anyKey.key)
anyChoice <- toAnyChoice(vals.get(2))
choiceArg <- toLedgerValue(anyChoice.arg)
} yield ScriptLedgerClient.ExerciseByKeyCommand(tplId, keyArg, anyChoice.name, choiceArg)
} yield
ScriptLedgerClient.ExerciseByKeyCommand(
templateId = tplId,
key = anyKey.key.toValue,
choice = anyChoice.name,
argument = anyChoice.arg.toValue,
)
}
case _ => Left(s"Expected ExerciseByKey but got $v")
}
@ -187,15 +193,14 @@ object Converter {
case SRecord(_, _, vals) if vals.size == 3 => {
for {
anyTemplate <- toAnyTemplate(vals.get(0))
templateArg <- toLedgerRecord(anyTemplate.arg)
anyChoice <- toAnyChoice(vals.get(1))
choiceArg <- toLedgerValue(anyChoice.arg)
} yield
ScriptLedgerClient.CreateAndExerciseCommand(
anyTemplate.ty,
templateArg,
anyChoice.name,
choiceArg)
templateId = anyTemplate.ty,
template = anyTemplate.arg.toValue,
choice = anyChoice.name,
argument = anyChoice.arg.toValue,
)
}
case _ => Left(s"Expected CreateAndExercise but got $v")
}
@ -446,7 +451,7 @@ object Converter {
.map(s => s"Failed to convert $ty: $s")
lfValue <- try {
Right(
jsValue.convertTo[Value[AbsoluteContractId]](
jsValue.convertTo[Value[ContractId]](
LfValueCodec.apiValueJsonReader(paramIface, damlLfTypeLookup(_))))
} catch {
case e: Exception => Left(s"LF conversion failed: ${e.toString}")

View File

@ -29,7 +29,7 @@ import com.daml.lf.iface.{EnvironmentInterface, InterfaceType}
import com.daml.lf.language.Ast._
import com.daml.lf.speedy.SValue._
import com.daml.lf.value.Value
import com.daml.lf.value.Value.AbsoluteContractId
import com.daml.lf.value.Value.ContractId
import com.daml.jwt.domain.Jwt
import com.daml.jwt.JwtDecoder
import com.daml.ledger.api.auth.{AuthServiceJWTCodec, AuthServiceJWTPayload}
@ -49,39 +49,36 @@ import com.daml.platform.participant.util.LfEngineToApi.{
object ScriptLedgerClient {
sealed trait Command
final case class CreateCommand(templateId: Identifier, argument: Value[AbsoluteContractId])
final case class CreateCommand(templateId: Identifier, argument: Value[ContractId])
extends Command
final case class ExerciseCommand(
templateId: Identifier,
contractId: AbsoluteContractId,
contractId: ContractId,
choice: String,
argument: Value[AbsoluteContractId])
argument: Value[ContractId])
extends Command
final case class ExerciseByKeyCommand(
templateId: Identifier,
key: Value[AbsoluteContractId],
key: Value[ContractId],
choice: String,
argument: Value[AbsoluteContractId])
argument: Value[ContractId])
extends Command
final case class CreateAndExerciseCommand(
templateId: Identifier,
template: Value[AbsoluteContractId],
template: Value[ContractId],
choice: String,
argument: Value[AbsoluteContractId])
argument: Value[ContractId])
extends Command
sealed trait CommandResult
final case class CreateResult(contractId: AbsoluteContractId) extends CommandResult
final case class ExerciseResult(
templateId: Identifier,
choice: String,
result: Value[AbsoluteContractId])
final case class CreateResult(contractId: ContractId) extends CommandResult
final case class ExerciseResult(templateId: Identifier, choice: String, result: Value[ContractId])
extends CommandResult
final case class ActiveContract(
templateId: Identifier,
contractId: AbsoluteContractId,
argument: Value[AbsoluteContractId])
contractId: ContractId,
argument: Value[ContractId])
}
// This abstracts over the interaction with the ledger. This allows
@ -122,7 +119,7 @@ class GrpcLedgerClient(val grpcClient: LedgerClient) extends ScriptLedgerClient
case Right(argument) => argument
}
val cid =
AbsoluteContractId
ContractId
.fromString(createdEvent.contractId)
.fold(
err => throw new ConverterException(err),
@ -221,7 +218,7 @@ class GrpcLedgerClient(val grpcClient: LedgerClient) extends ScriptLedgerClient
ev match {
case TreeEvent(TreeEvent.Kind.Created(created)) =>
for {
cid <- AbsoluteContractId.fromString(created.contractId)
cid <- ContractId.fromString(created.contractId)
} yield ScriptLedgerClient.CreateResult(cid)
case TreeEvent(TreeEvent.Kind.Exercised(exercised)) =>
for {
@ -291,9 +288,9 @@ class JsonLedgerClient(
val ctx = templateId.qualifiedName
val ifaceType = Converter.toIfaceType(ctx, TTyCon(templateId)).right.get
val parsedResults = queryResponse.results.map(r => {
val payload = r.payload.convertTo[Value[AbsoluteContractId]](
val payload = r.payload.convertTo[Value[ContractId]](
LfValueCodec.apiValueJsonReader(ifaceType, damlLfTypeLookup(_)))
val cid = AbsoluteContractId.assertFromString(r.contractId)
val cid = ContractId.assertFromString(r.contractId)
ScriptLedgerClient.ActiveContract(templateId, cid, payload)
})
parsedResults
@ -366,7 +363,7 @@ class JsonLedgerClient(
}
}
private def create(tplId: Identifier, argument: Value[AbsoluteContractId])
private def create(tplId: Identifier, argument: Value[ContractId])
: Future[Either[StatusRuntimeException, List[ScriptLedgerClient.CreateResult]]] = {
val ctx = tplId.qualifiedName
val ifaceType = Converter.toIfaceType(ctx, TTyCon(tplId)).right.get
@ -376,15 +373,15 @@ class JsonLedgerClient(
JsonLedgerClient.CreateArgs(tplId, jsonArgument))
.map(_.map {
case JsonLedgerClient.CreateResponse(cid) =>
List(ScriptLedgerClient.CreateResult(AbsoluteContractId.assertFromString(cid)))
List(ScriptLedgerClient.CreateResult(ContractId.assertFromString(cid)))
})
}
private def exercise(
tplId: Identifier,
contractId: AbsoluteContractId,
contractId: ContractId,
choice: String,
argument: Value[AbsoluteContractId])
argument: Value[ContractId])
: Future[Either[StatusRuntimeException, List[ScriptLedgerClient.ExerciseResult]]] = {
val ctx = tplId.qualifiedName
val choiceDef = envIface
@ -402,16 +399,16 @@ class JsonLedgerClient(
ScriptLedgerClient.ExerciseResult(
tplId,
choice,
result.convertTo[Value[AbsoluteContractId]](
result.convertTo[Value[ContractId]](
LfValueCodec.apiValueJsonReader(choiceDef.returnType, damlLfTypeLookup(_)))))
})
}
private def exerciseByKey(
tplId: Identifier,
key: Value[AbsoluteContractId],
key: Value[ContractId],
choice: String,
argument: Value[AbsoluteContractId])
argument: Value[ContractId])
: Future[Either[StatusRuntimeException, List[ScriptLedgerClient.ExerciseResult]]] = {
val ctx = tplId.qualifiedName
val choiceDef = envIface
@ -430,16 +427,16 @@ class JsonLedgerClient(
ScriptLedgerClient.ExerciseResult(
tplId,
choice,
result.convertTo[Value[AbsoluteContractId]](
result.convertTo[Value[ContractId]](
LfValueCodec.apiValueJsonReader(choiceDef.returnType, damlLfTypeLookup(_)))))
})
}
private def createAndExercise(
tplId: Identifier,
template: Value[AbsoluteContractId],
template: Value[ContractId],
choice: String,
argument: Value[AbsoluteContractId])
argument: Value[ContractId])
: Future[Either[StatusRuntimeException, List[ScriptLedgerClient.CommandResult]]] = {
val ctx = tplId.qualifiedName
val choiceDef = envIface
@ -459,11 +456,11 @@ class JsonLedgerClient(
case JsonLedgerClient.CreateAndExerciseResponse(cid, result) =>
List(
ScriptLedgerClient
.CreateResult(AbsoluteContractId.assertFromString(cid)): ScriptLedgerClient.CommandResult,
.CreateResult(ContractId.assertFromString(cid)): ScriptLedgerClient.CommandResult,
ScriptLedgerClient.ExerciseResult(
tplId,
choice,
result.convertTo[Value[AbsoluteContractId]](
result.convertTo[Value[ContractId]](
LfValueCodec.apiValueJsonReader(choiceDef.returnType, damlLfTypeLookup(_))))
)
})
@ -511,7 +508,7 @@ object JsonLedgerClient {
final case class ExerciseArgs(
templateId: Identifier,
contractId: AbsoluteContractId,
contractId: ContractId,
choice: String,
argument: JsValue)
final case class ExerciseResponse(result: JsValue)

View File

@ -30,7 +30,7 @@ import com.daml.lf.speedy.{Compiler, InitialSeeding, Pretty, SExpr, SValue, Spee
import com.daml.lf.speedy.SExpr._
import com.daml.lf.speedy.SResult._
import com.daml.lf.speedy.SValue._
import com.daml.lf.value.Value.AbsoluteContractId
import com.daml.lf.value.Value.ContractId
import com.daml.lf.value.json.ApiCodecCompressed
import com.daml.grpc.adapter.ExecutionSequencerFactory
import com.daml.jwt.domain.Jwt
@ -41,9 +41,9 @@ import com.daml.ledger.api.v1.commands._
import com.daml.ledger.client.LedgerClient
import com.daml.ledger.client.configuration.LedgerClientConfiguration
import com.google.protobuf.duration.Duration
import ParticipantsJsonProtocol.AbsoluteContractIdFormat
import ParticipantsJsonProtocol.ContractIdFormat
object LfValueCodec extends ApiCodecCompressed[AbsoluteContractId](false, false)
object LfValueCodec extends ApiCodecCompressed[ContractId](false, false)
case class Participant(participant: String)
case class Party(party: String)
@ -89,13 +89,13 @@ object ParticipantsJsonProtocol extends DefaultJsonProtocol {
}
def write(p: Party) = JsString(p.party)
}
implicit val AbsoluteContractIdFormat: JsonFormat[AbsoluteContractId] =
new JsonFormat[AbsoluteContractId] {
override def write(obj: AbsoluteContractId) =
implicit val ContractIdFormat: JsonFormat[ContractId] =
new JsonFormat[ContractId] {
override def write(obj: ContractId) =
JsString(obj.coid)
override def read(json: JsValue) = json match {
case JsString(s) =>
AbsoluteContractId fromString s fold (deserializationError(_), identity)
ContractId fromString s fold (deserializationError(_), identity)
case _ => deserializationError("ContractId must be a string")
}
}

View File

@ -120,8 +120,7 @@ object RunnerMain {
result <- Runner.run(dar, scriptId, inputValue, clients, applicationId, timeProvider)
_ <- Future {
config.outputFile.foreach { outputFile =>
val jsVal = LfValueCodec.apiValueToJsValue(
result.toValue.assertNoRelCid(rcoid => s"Unexpected relative contract id $rcoid"))
val jsVal = LfValueCodec.apiValueToJsValue(result.toValue)
Files.write(outputFile.toPath, Seq(jsVal.prettyPrint).asJava)
}
}

View File

@ -18,7 +18,7 @@ import scala.reflect.runtime.universe._
* inner classes in the generated contract template cases. An in
*
* A decoder for ArchivedEvent`s is not require since these don't contain any information
* besides the absolute contract ID of the archived contract.
* besides the contract ID of the archived contract.
*/
object EventDecoderGen {
import LFUtil._

View File

@ -353,7 +353,7 @@ class ContractsService(
object ContractsService {
private type ApiValue = api.value.Value
private type LfValue = lf.value.Value[lf.value.Value.AbsoluteContractId]
private type LfValue = lf.value.Value[lf.value.Value.ContractId]
case class Error(id: Symbol, message: String)

View File

@ -439,7 +439,7 @@ object Endpoints {
private type ApiRecord = lav1.value.Record
private type ApiValue = lav1.value.Value
private type LfValue = lf.value.Value[lf.value.Value.AbsoluteContractId]
private type LfValue = lf.value.Value[lf.value.Value.ContractId]
private def lfValueToJsValue(a: LfValue): Error \/ JsValue =
\/.fromTryCatchNonFatal(LfValueCodec.apiValueToJsValue(a)).liftErr(ServerError)

View File

@ -48,7 +48,7 @@ object domain {
}
}
type LfValue = lf.value.Value[lf.value.Value.AbsoluteContractId]
type LfValue = lf.value.Value[lf.value.Value.ContractId]
case class JwtPayload(ledgerId: LedgerId, applicationId: ApplicationId, party: Party)

View File

@ -19,14 +19,14 @@ class JsValueToApiValueConverter(lfTypeLookup: LfTypeLookup) {
def jsValueToLfValue(
lfId: lf.data.Ref.Identifier,
jsValue: JsValue): JsonError \/ lf.value.Value[lf.value.Value.AbsoluteContractId] =
jsValue: JsValue): JsonError \/ lf.value.Value[lf.value.Value.ContractId] =
\/.fromTryCatchNonFatal(
LfValueCodec.jsValueToApiValue(jsValue, lfId, lfTypeLookup)
).liftErr(JsonError)
def jsValueToLfValue(
lfType: iface.Type,
jsValue: JsValue): JsonError \/ lf.value.Value[lf.value.Value.AbsoluteContractId] =
jsValue: JsValue): JsonError \/ lf.value.Value[lf.value.Value.ContractId] =
\/.fromTryCatchNonFatal(
LfValueCodec.jsValueToApiValue(jsValue, lfType, lfTypeLookup)
).liftErr(JsonError)

View File

@ -6,7 +6,7 @@ package com.daml.http.json
import akka.http.scaladsl.model.StatusCode
import com.daml.http.domain
import com.daml.ledger.api.refinements.{ApiTypes => lar}
import com.daml.lf.value.Value.AbsoluteContractId
import com.daml.lf.value.Value.ContractId
import com.daml.lf.value.json.ApiCodecCompressed
import scalaz.syntax.std.option._
import scalaz.{-\/, NonEmptyList, OneAnd, \/-}
@ -27,16 +27,16 @@ object JsonProtocol extends DefaultJsonProtocol with ExtraFormats {
implicit val ChoiceFormat: JsonFormat[lar.Choice] = taggedJsonFormat[String, lar.ChoiceTag]
implicit val ContractIdFormat: JsonFormat[domain.ContractId] =
implicit val DomainContractIdFormat: JsonFormat[domain.ContractId] =
taggedJsonFormat[String, domain.ContractIdTag]
implicit val AbsoluteContractIdFormat: JsonFormat[AbsoluteContractId] =
new JsonFormat[AbsoluteContractId] {
override def write(obj: AbsoluteContractId) =
implicit val ContractIdFormat: JsonFormat[ContractId] =
new JsonFormat[ContractId] {
override def write(obj: ContractId) =
JsString(obj.coid)
override def read(json: JsValue) = json match {
case JsString(s) =>
AbsoluteContractId fromString s fold (deserializationError(_), identity)
ContractId fromString s fold (deserializationError(_), identity)
case _ => deserializationError("ContractId must be a string")
}
}
@ -75,13 +75,13 @@ object JsonProtocol extends DefaultJsonProtocol with ExtraFormats {
jsonFormat2(domain.AllocatePartyRequest)
object LfValueCodec
extends ApiCodecCompressed[AbsoluteContractId](
extends ApiCodecCompressed[ContractId](
encodeDecimalAsString = true,
encodeInt64AsString = true)
// DB *must not* use stringly ints or decimals; see ValuePredicate Range comments
object LfValueDatabaseCodec
extends ApiCodecCompressed[AbsoluteContractId](
extends ApiCodecCompressed[ContractId](
encodeDecimalAsString = false,
encodeInt64AsString = false) {
private[http] def asLfValueCodec(jv: JsValue): JsValue = jv match {

View File

@ -181,7 +181,7 @@ sealed abstract class ValuePredicate extends Product with Serializable {
object ValuePredicate {
type TypeLookup = Ref.Identifier => Option[iface.DefDataType.FWT]
type LfV = V[V.AbsoluteContractId]
type LfV = V[V.ContractId]
type SqlWhereClause = Vector[Fragment]
val AlwaysFails: SqlWhereClause = Vector(sql"1 = 2")

View File

@ -20,7 +20,7 @@ object ApiValueToLfValueConverter {
}
type ApiValueToLfValue =
lav1.value.Value => Error \/ lf.value.Value[lf.value.Value.AbsoluteContractId]
lav1.value.Value => Error \/ lf.value.Value[lf.value.Value.ContractId]
def apiValueToLfValue: ApiValueToLfValue = { a: lav1.value.Value =>
\/.fromEither(ValueValidator.validateValue(a)).leftMap(e => Error(e))

View File

@ -817,7 +817,7 @@ abstract class AbstractHttpServiceIntegrationTest
status shouldBe StatusCodes.InternalServerError
assertStatus(output, StatusCodes.InternalServerError)
expectedOneErrorMessage(output) should include(
"couldn't find contract AbsoluteContractId(#NonExistentContractId)")
"couldn't find contract ContractId(#NonExistentContractId)")
}: Future[Assertion]
}

View File

@ -26,13 +26,12 @@ class ValuePredicateTest
with GeneratorDrivenPropertyChecks
with TableDrivenPropertyChecks {
import ValuePredicateTest._
type Cid = V.AbsoluteContractId
type Cid = V.ContractId
private[this] implicit val arbCid: Arbitrary[Cid] = Arbitrary(
Gen.alphaStr map (t => V.AbsoluteContractId.V0 assertFromString ('#' +: t)))
Gen.alphaStr map (t => V.ContractId.V0 assertFromString ('#' +: t)))
// only V0 supported in this test atm
private[this] implicit val ordCid: Order[Cid] = Order[V.AbsoluteContractId.V0] contramap (inside(
_) {
case a0 @ V.AbsoluteContractId.V0(_) => a0
private[this] implicit val ordCid: Order[Cid] = Order[V.ContractId.V0] contramap (inside(_) {
case a0 @ V.ContractId.V0(_) => a0
})
private[this] val dummyId = Ref.Identifier(

View File

@ -23,7 +23,7 @@ class ApiValueToLfValueConverterTest
import ApiValueToLfValueConverterTest._
private[this] implicit val arbCid: Arbitrary[CidSrc] = Arbitrary(
Gen.alphaStr map (t => V.AbsoluteContractId.V0 assertFromString ('#' +: t)))
Gen.alphaStr map (t => V.ContractId.V0 assertFromString ('#' +: t)))
"apiValueToLfValue" should {
import ApiValueToLfValueConverter.apiValueToLfValue
@ -44,8 +44,8 @@ class ApiValueToLfValueConverterTest
@SuppressWarnings(Array("org.wartremover.warts.Any"))
object ApiValueToLfValueConverterTest {
type Cid = V.AbsoluteContractId
type CidSrc = V.AbsoluteContractId.V0
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

View File

@ -125,7 +125,7 @@ final class CommandsValidator(ledgerId: LedgerId) {
for {
templateId <- requirePresence(e.value.templateId, "template_id")
validatedTemplateId <- validateIdentifier(templateId)
contractId <- requireAbsoluteContractId(e.value.contractId, "contract_id")
contractId <- requireContractId(e.value.contractId, "contract_id")
choice <- requireName(e.value.choice, "choice")
value <- requirePresence(e.value.choiceArgument, "value")
validatedValue <- validateValue(value)

View File

@ -4,7 +4,7 @@
package com.daml.ledger.api.validation
import com.daml.lf.data._
import com.daml.lf.value.Value.{AbsoluteContractId, ValueUnit}
import com.daml.lf.value.Value.{ContractId, ValueUnit}
import com.daml.ledger.api.domain
import com.daml.ledger.api.v1.value.Value.Sum
import com.daml.ledger.api.v1.{value => api}
@ -32,8 +32,7 @@ object ValueValidator {
})
.map(_.toImmArray)
def validateRecord(
rec: api.Record): Either[StatusRuntimeException, Lf.ValueRecord[AbsoluteContractId]] =
def validateRecord(rec: api.Record): Either[StatusRuntimeException, Lf.ValueRecord[ContractId]] =
for {
recId <- validateOptionalIdentifier(rec.recordId)
fields <- validateRecordFields(rec.fields)
@ -44,7 +43,7 @@ object ValueValidator {
def validateValue(v0: api.Value): Either[StatusRuntimeException, domain.Value] = v0.sum match {
case Sum.ContractId(cId) =>
AbsoluteContractId
ContractId
.fromString(cId)
.bimap(invalidArgument, Lf.ValueContractId(_))
case Sum.Numeric(value) =>

View File

@ -45,11 +45,11 @@ object PlatformTypes {
f: Cid => Cid2): GenTransaction[Nid, Cid2] =
tx.mapContractIdAndValue(f, _.mapContractId(f))
def asVersionedValue[Cid <: V.AbsoluteContractId](
def asVersionedValue[Cid <: V.ContractId](
v: V[Cid]): scala.Either[String, V.VersionedValue[Cid]] =
ValueVersions.asVersionedValue(v)
def asVersionedValueOrThrow[Cid <: V.AbsoluteContractId](v: V[Cid]): V.VersionedValue[Cid] = {
def asVersionedValueOrThrow[Cid <: V.ContractId](v: V[Cid]): V.VersionedValue[Cid] = {
asVersionedValue(v).fold(
s => throw new IllegalArgumentException(s"Can't convert to versioned value: $s"),
identity)

View File

@ -35,12 +35,12 @@ object LfEngineToApi {
def lfVersionedValueToApiRecord(
verbose: Boolean,
recordValue: Lf.VersionedValue[Lf.AbsoluteContractId]): Either[String, api.Record] =
recordValue: Lf.VersionedValue[Lf.ContractId]): Either[String, api.Record] =
lfValueToApiRecord(verbose, recordValue.value)
def lfValueToApiRecord(
verbose: Boolean,
recordValue: LfValue[Lf.AbsoluteContractId]): Either[String, api.Record] = {
recordValue: LfValue[Lf.ContractId]): Either[String, api.Record] = {
recordValue match {
case Lf.ValueRecord(tycon, fields) =>
val fs = fields.foldLeft[Either[String, Vector[api.RecordField]]](Right(Vector.empty)) {
@ -65,19 +65,19 @@ object LfEngineToApi {
def lfVersionedValueToApiValue(
verbose: Boolean,
lf: Option[Lf.VersionedValue[Lf.AbsoluteContractId]],
lf: Option[Lf.VersionedValue[Lf.ContractId]],
): Either[String, Option[api.Value]] =
lf.fold[Either[String, Option[api.Value]]](Right(None))(
lfVersionedValueToApiValue(verbose, _).map(Some(_)))
def lfVersionedValueToApiValue(
verbose: Boolean,
value: Lf.VersionedValue[Lf.AbsoluteContractId]): Either[String, api.Value] =
value: Lf.VersionedValue[Lf.ContractId]): Either[String, api.Value] =
lfValueToApiValue(verbose, value.value)
def lfValueToApiValue(
verbose: Boolean,
value0: LfValue[Lf.AbsoluteContractId]): Either[String, api.Value] =
value0: LfValue[Lf.ContractId]): Either[String, api.Value] =
value0 match {
case Lf.ValueUnit => Right(api.Value(api.Value.Sum.Unit(Empty())))
case Lf.ValueNumeric(d) =>
@ -162,12 +162,12 @@ object LfEngineToApi {
def lfContractKeyToApiValue(
verbose: Boolean,
lf: KeyWithMaintainers[Lf.VersionedValue[Lf.AbsoluteContractId]]): Either[String, api.Value] =
lf: KeyWithMaintainers[Lf.VersionedValue[Lf.ContractId]]): Either[String, api.Value] =
lfVersionedValueToApiValue(verbose, lf.key)
def lfContractKeyToApiValue(
verbose: Boolean,
lf: Option[KeyWithMaintainers[Lf.VersionedValue[Lf.AbsoluteContractId]]])
lf: Option[KeyWithMaintainers[Lf.VersionedValue[Lf.ContractId]]])
: Either[String, Option[api.Value]] =
lf.fold[Either[String, Option[api.Value]]](Right(None))(
lfContractKeyToApiValue(verbose, _).map(Some(_)))
@ -175,7 +175,7 @@ object LfEngineToApi {
def lfNodeCreateToEvent(
verbose: Boolean,
eventId: String,
node: NodeCreate.WithTxValue[Lf.AbsoluteContractId],
node: NodeCreate.WithTxValue[Lf.ContractId],
): Either[String, Event] =
for {
arg <- lfValueToApiRecord(verbose, node.coinst.arg.value)
@ -196,7 +196,7 @@ object LfEngineToApi {
def lfNodeExercisesToEvent(
eventId: String,
node: NodeExercises.WithTxValue[EventId, Lf.AbsoluteContractId],
node: NodeExercises.WithTxValue[EventId, Lf.ContractId],
): Either[String, Event] =
Either.cond(
node.consuming,
@ -215,7 +215,7 @@ object LfEngineToApi {
verbose: Boolean,
eventId: String,
witnessParties: Set[Ref.Party],
node: NodeCreate.WithTxValue[Lf.AbsoluteContractId],
node: NodeCreate.WithTxValue[Lf.ContractId],
): Either[String, TreeEvent] =
for {
arg <- lfValueToApiRecord(verbose, node.coinst.arg.value)
@ -238,7 +238,7 @@ object LfEngineToApi {
verbose: Boolean,
eventId: String,
witnessParties: Set[Ref.Party],
node: NodeExercises.WithTxValue[EventId, Lf.AbsoluteContractId],
node: NodeExercises.WithTxValue[EventId, Lf.ContractId],
): Either[String, TreeEvent] =
for {
arg <- lfVersionedValueToApiValue(verbose, node.chosenValue)

View File

@ -6,7 +6,7 @@ package com.daml.platform.server.api.validation
import java.time.Duration
import com.daml.lf.data.Ref
import com.daml.lf.value.Value.AbsoluteContractId
import com.daml.lf.value.Value.ContractId
import com.daml.ledger.api.domain.LedgerId
import com.daml.ledger.api.v1.value.Identifier
import com.daml.platform.server.api.validation.ErrorFactories._
@ -69,12 +69,12 @@ trait FieldValidations {
def requireLedgerString(s: String): Either[StatusRuntimeException, Ref.LedgerString] =
Ref.LedgerString.fromString(s).left.map(invalidArgument)
def requireAbsoluteContractId(
def requireContractId(
s: String,
fieldName: String
): Either[StatusRuntimeException, AbsoluteContractId] =
): Either[StatusRuntimeException, ContractId] =
if (s.isEmpty) Left(missingField(fieldName))
else AbsoluteContractId.fromString(s).left.map(invalidField(fieldName, _))
else ContractId.fromString(s).left.map(invalidField(fieldName, _))
def requireDottedName(
s: String,

View File

@ -9,7 +9,7 @@ import java.security.MessageDigest
import com.daml.lf.data.{Numeric, Utf8}
import com.daml.lf.transaction.Node.GlobalKey
import com.daml.lf.value.Value
import com.daml.lf.value.Value.AbsoluteContractId
import com.daml.lf.value.Value.ContractId
/**
* @deprecated in favor of [[GlobalKey.hash]]
@ -55,7 +55,7 @@ object KeyHasher extends KeyHasher {
* @param op operation to append a hash token
* @return the final hash value
*/
def foldLeft[T](value: Value[AbsoluteContractId], z: T, op: (T, HashToken) => T): T = {
def foldLeft[T](value: Value[ContractId], z: T, op: (T, HashToken) => T): T = {
import com.daml.lf.value.Value._
value match {
@ -138,7 +138,7 @@ object KeyHasher extends KeyHasher {
// Do not use directly. It is package visible for testing purpose.
private[serialization] def putValue(
digest: MessageDigest,
value: Value[AbsoluteContractId],
value: Value[ContractId],
): MessageDigest = {
// Then, write the value
foldLeft[MessageDigest](

View File

@ -266,7 +266,7 @@ class SubmitRequestValidatorTest
val coid = Ref.ContractIdString.assertFromString("#coid")
val input = Value(Sum.ContractId(coid))
val expected = Lf.ValueContractId(Lf.AbsoluteContractId.V0(coid))
val expected = Lf.ValueContractId(Lf.ContractId.V0(coid))
validateValue(input) shouldEqual Right(expected)
}

View File

@ -326,7 +326,7 @@ class KeyHasherSpec extends WordSpec with Matchers {
"stable " in {
type Value = lf.value.Value[AbsoluteContractId]
type Value = lf.value.Value[ContractId]
val pkgId = Ref.PackageId.assertFromString("pkgId")
@ -404,10 +404,10 @@ class KeyHasherSpec extends WordSpec with Matchers {
val contractIds =
List[Value](
ValueContractId(
AbsoluteContractId.assertFromString(
ContractId.assertFromString(
"0007e7b5534931dfca8e1b485c105bae4e10808bd13ddc8e897f258015f9d921c5")),
ValueContractId(
AbsoluteContractId.assertFromString(
ContractId.assertFromString(
"0059b59ad7a6b6066e77b91ced54b8282f0e24e7089944685cb8f22f32fcbc4e1b"))
)
@ -525,9 +525,9 @@ class KeyHasherSpec extends WordSpec with Matchers {
| e3e40cc57896dcdac6731f60cb1748bd34b45ac0a6e42aa517d41dfea2ff8a88
|ValueParty(bob)
| 492f3783b824fb976eac36c0623337a7fd7440b95095581eb81687c71e802943
|ValueContractId(AbsoluteContractId(0007e7b5534931dfca8e1b485c105bae4e10808bd13ddc8e897f258015f9d921c5))
|ValueContractId(ContractId(0007e7b5534931dfca8e1b485c105bae4e10808bd13ddc8e897f258015f9d921c5))
| a03a7ce4c418622a2187d068208c5ad32460eb62a56797975f39988e959ca377
|ValueContractId(AbsoluteContractId(0059b59ad7a6b6066e77b91ced54b8282f0e24e7089944685cb8f22f32fcbc4e1b))
|ValueContractId(ContractId(0059b59ad7a6b6066e77b91ced54b8282f0e24e7089944685cb8f22f32fcbc4e1b))
| 01540890e0cd14209bcc408d019266b711ec85a16dac2e8eb3567f6e041cb86b
|ValueOptional(None)
| df3f619804a92fdb4057192dc43dd748ea778adc52bc498ce80524c014b81119

View File

@ -10,7 +10,6 @@ import com.daml.ledger.participant.state.v1.Configuration
import com.daml.lf.command.{Commands => LfCommands}
import com.daml.lf.data.Ref
import com.daml.lf.data.Ref.LedgerString.ordering
import com.daml.lf.value.Value.{AbsoluteContractId, ValueRecord}
import com.daml.lf.value.{Value => Lf}
import com.daml.ledger.api.domain.Event.{CreateOrArchiveEvent, CreateOrExerciseEvent}
import scalaz.syntax.tag._
@ -80,7 +79,7 @@ object domain {
eventId: EventId,
contractId: ContractId,
templateId: Ref.Identifier,
createArguments: ValueRecord[AbsoluteContractId],
createArguments: Lf.ValueRecord[ContractId],
witnessParties: immutable.Set[Ref.Party],
signatories: immutable.Set[Ref.Party],
observers: immutable.Set[Ref.Party],
@ -208,7 +207,7 @@ object domain {
final case class InvalidLedgerTime(description: String) extends RejectionReason
}
type Value = Lf[Lf.AbsoluteContractId]
type Value = Lf[Lf.ContractId]
final case class RecordField(label: Option[Label], value: Value)

View File

@ -9,7 +9,7 @@ import com.daml.lf.data.Ref
import com.daml.lf.data.Ref.Party
import com.daml.lf.transaction.Node.GlobalKey
import com.daml.lf.value.Value
import com.daml.lf.value.Value.{AbsoluteContractId, ContractInst}
import com.daml.lf.value.Value.{ContractId, ContractInst}
import scala.concurrent.Future
@ -19,15 +19,15 @@ import scala.concurrent.Future
trait ContractStore {
def lookupActiveContract(
submitter: Ref.Party,
contractId: AbsoluteContractId
): Future[Option[ContractInst[Value.VersionedValue[AbsoluteContractId]]]]
contractId: ContractId
): Future[Option[ContractInst[Value.VersionedValue[ContractId]]]]
def lookupContractKey(submitter: Party, key: GlobalKey): Future[Option[AbsoluteContractId]]
def lookupContractKey(submitter: Party, key: GlobalKey): Future[Option[ContractId]]
/**
* @return The maximum ledger effective time of all contracts in ids, fails as follows:
* - if ids is empty or not all the non-divulged ids can be found, a failed [[Future]]
* - if all ids are found but each refer to a divulged contract, a successful [[None]]
*/
def lookupMaximumLedgerTime(ids: Set[AbsoluteContractId]): Future[Option[Instant]]
def lookupMaximumLedgerTime(ids: Set[ContractId]): Future[Option[Instant]]
}

View File

@ -18,12 +18,12 @@ package object v2 {
final case class Create(
transactionId: TransactionId,
eventId: EventId,
contractId: Value.AbsoluteContractId,
contractId: Value.ContractId,
templateId: Ref.Identifier,
argument: Value.VersionedValue[Value.AbsoluteContractId],
argument: Value.VersionedValue[Value.ContractId],
// TODO(JM,SM): understand witnessing parties
stakeholders: Set[Ref.Party],
contractKey: Option[Value.VersionedValue[Value.AbsoluteContractId]],
contractKey: Option[Value.VersionedValue[Value.ContractId]],
signatories: Set[Ref.Party],
observers: Set[Ref.Party],
agreementText: String

View File

@ -123,7 +123,7 @@ message DamlLogEntryId {
// The entry identifier is used:
// * to lookup the log entry when producing `Update`.
// * as the DAML transaction identifier and rendered as hexadecimal.
// * as part of absolute contract identifiers.
// * as part of contract identifiers.
bytes entry_id = 1;
}

View File

@ -14,7 +14,7 @@ import com.daml.lf.data.Time
import com.daml.lf.transaction.Node.GlobalKey
import com.daml.lf.transaction._
import com.daml.lf.transaction.VersionTimeline.Implicits._
import com.daml.lf.value.Value.{AbsoluteContractId, VersionedValue}
import com.daml.lf.value.Value.{ContractId, VersionedValue}
import com.daml.lf.value.{Value, ValueCoder, ValueOuterClass}
import com.google.protobuf.Empty
@ -32,15 +32,15 @@ private[state] object Conversions {
def packageStateKey(packageId: PackageId): DamlStateKey =
DamlStateKey.newBuilder.setPackageId(packageId).build
def contractIdToStateKey(acoid: AbsoluteContractId): DamlStateKey =
def contractIdToStateKey(acoid: ContractId): DamlStateKey =
DamlStateKey.newBuilder
.setContractId(acoid.coid)
.build
def decodeContractId(coid: String): AbsoluteContractId =
AbsoluteContractId.assertFromString(coid)
def decodeContractId(coid: String): ContractId =
ContractId.assertFromString(coid)
def stateKeyToContractId(key: DamlStateKey): AbsoluteContractId =
def stateKeyToContractId(key: DamlStateKey): ContractId =
decodeContractId(key.getContractId)
def encodeGlobalKey(key: GlobalKey): DamlContractKey = {
@ -168,37 +168,36 @@ private[state] object Conversions {
TransactionCoder
.decodeVersionedTransaction(
TransactionCoder.NidDecoder,
ValueCoder.AbsCidDecoder,
ValueCoder.CidDecoder,
tx
)
.fold(err => throw Err.DecodeError("Transaction", err.errorMessage), _.transaction)
}
def decodeVersionedValue(
protoValue: ValueOuterClass.VersionedValue): VersionedValue[AbsoluteContractId] =
def decodeVersionedValue(protoValue: ValueOuterClass.VersionedValue): VersionedValue[ContractId] =
ValueCoder
.decodeVersionedValue(ValueCoder.AbsCidDecoder, protoValue)
.decodeVersionedValue(ValueCoder.CidDecoder, protoValue)
.fold(
err => throw Err.DecodeError("ContractInstance", err.errorMessage),
identity
)
def decodeContractInstance(coinst: TransactionOuterClass.ContractInstance)
: Value.ContractInst[VersionedValue[AbsoluteContractId]] =
: Value.ContractInst[VersionedValue[ContractId]] =
TransactionCoder
.decodeContractInstance(ValueCoder.AbsCidDecoder, coinst)
.decodeContractInstance(ValueCoder.CidDecoder, coinst)
.fold(
err => throw Err.DecodeError("ContractInstance", err.errorMessage),
identity
)
def encodeContractInstance(coinst: Value.ContractInst[VersionedValue[Value.AbsoluteContractId]])
def encodeContractInstance(coinst: Value.ContractInst[VersionedValue[Value.ContractId]])
: TransactionOuterClass.ContractInstance =
TransactionCoder
.encodeContractInstance(ValueCoder.CidEncoder, coinst)
.fold(err => throw Err.InternalError(s"encodeContractInstance failed: $err"), identity)
def forceNoContractIds(v: Value[Value.AbsoluteContractId]): Value[Nothing] =
def forceNoContractIds(v: Value[Value.ContractId]): Value[Nothing] =
v.ensureNoCid.fold(
coid => throw Err.InternalError(s"Contract identifier '$coid' encountered in contract key"),
identity,
@ -210,7 +209,7 @@ private[state] object Conversions {
coidString: String,
coidStruct: ValueOuterClass.ContractId,
): DamlStateKey =
ValueCoder.AbsCidDecoder
ValueCoder.CidDecoder
.decode(
sv = transactionVersion,
stringForm = coidString,

View File

@ -10,7 +10,7 @@ import com.daml.ledger.participant.state.v1.TransactionMeta
import com.daml.lf.data.Ref._
import com.daml.lf.transaction.Node._
import com.daml.lf.transaction.Transaction
import com.daml.lf.value.Value.{AbsoluteContractId, VersionedValue}
import com.daml.lf.value.Value.{ContractId, VersionedValue}
/** Internal utilities to compute the inputs and effects of a DAML transaction */
private[kvutils] object InputsAndEffects {
@ -32,10 +32,9 @@ private[kvutils] object InputsAndEffects {
* contracts should be created. The key should be a combination of the transaction
* id and the relative contract id (that is, the node index).
*/
createdContracts: List[
(DamlStateKey, NodeCreate[AbsoluteContractId, VersionedValue[AbsoluteContractId]])],
createdContracts: List[(DamlStateKey, NodeCreate[ContractId, VersionedValue[ContractId]])],
/** The contract keys created or updated as part of the transaction. */
updatedContractKeys: Map[DamlStateKey, Option[AbsoluteContractId]]
updatedContractKeys: Map[DamlStateKey, Option[ContractId]]
)
object Effects {
val empty = Effects(List.empty, List.empty, Map.empty)
@ -64,7 +63,7 @@ private[kvutils] object InputsAndEffects {
val localContract = tx.localContracts
def addContractInput(coid: AbsoluteContractId): Unit =
def addContractInput(coid: ContractId): Unit =
if (!localContract.isDefinedAt(coid))
inputs += contractIdToStateKey(coid)

View File

@ -9,7 +9,7 @@ import com.google.common.io.BaseEncoding
object Pretty {
/** Pretty-printing of the entry identifier. Uses the same hexadecimal encoding as is used
* for absolute contract identifiers.
* for contract identifiers.
*/
def prettyEntryId(entryId: DamlLogEntryId): String =
BaseEncoding.base16.encode(entryId.getEntryId.toByteArray)

View File

@ -69,7 +69,7 @@ object Version {
* 1: * Use hashing to serialize contract keys. Backwards incompatible to avoid having to do two lookups
* of a single contract key.
*
* 2: * Deprecate use of relative contract identifiers. The transaction is submitted with absolute contract
* 2: * Deprecate use of relative contract identifiers. The transaction is submitted with contract
* identifiers. Backwards incompatible to remove unnecessary traversal of the transaction when consuming
* it and to make it possible to remove DamlLogEntryId.
*

View File

@ -29,7 +29,7 @@ class KeyValueParticipantStateWriter(writer: LedgerWriter, metrics: Metrics) ext
keyValueSubmission.transactionToSubmission(
submitterInfo,
transactionMeta,
transaction.assertNoRelCid(cid => s"Unexpected relative contract id: $cid"),
transaction,
)
commit(correlationId = submitterInfo.commandId, submission = submission)
}

View File

@ -22,7 +22,7 @@ import com.daml.lf.language.Ast
import com.daml.lf.transaction.{BlindingInfo, GenTransaction, Node}
import com.daml.lf.transaction.Transaction.AbsTransaction
import com.daml.lf.value.Value
import com.daml.lf.value.Value.AbsoluteContractId
import com.daml.lf.value.Value.ContractId
import com.daml.metrics.Metrics
import com.google.protobuf.{Timestamp => ProtoTimestamp}
@ -172,7 +172,7 @@ private[kvutils] class TransactionCommitter(
// Pull all keys from referenced contracts. We require this for 'fetchByKey' calls
// which are not evidenced in the transaction itself and hence the contract key state is
// not included in the inputs.
lazy val knownKeys: Map[DamlContractKey, Value.AbsoluteContractId] =
lazy val knownKeys: Map[DamlContractKey, Value.ContractId] =
commitContext.inputs.collect {
case (key, Some(value))
if value.hasContractState
@ -338,7 +338,7 @@ private[kvutils] class TransactionCommitter(
): StepResult[DamlTransactionEntrySummary] = {
val effects = InputsAndEffects.computeEffects(transactionEntry.absoluteTransaction)
val cid2nid: Value.AbsoluteContractId => Value.NodeId =
val cid2nid: Value.ContractId => Value.NodeId =
transactionEntry.absoluteTransaction.localContracts
val dedupKey = commandDedupKey(transactionEntry.submitterInfo)
@ -434,7 +434,7 @@ private[kvutils] class TransactionCommitter(
private def updateContractKeyWithContractKeyState(
ledgerEffectiveTime: ProtoTimestamp,
key: DamlStateKey,
contractKeyState: Option[AbsoluteContractId]): (DamlStateKey, DamlStateValue) = {
contractKeyState: Option[ContractId]): (DamlStateKey, DamlStateValue) = {
logger.trace(s"updating contract key $key to $contractKeyState")
key ->
DamlStateValue.newBuilder
@ -456,8 +456,8 @@ private[kvutils] class TransactionCommitter(
private def lookupContract(
transactionEntry: DamlTransactionEntrySummary,
inputState: DamlStateMap)(
coid: Value.AbsoluteContractId,
): Option[Value.ContractInst[Value.VersionedValue[Value.AbsoluteContractId]]] = {
coid: Value.ContractId,
): Option[Value.ContractInst[Value.VersionedValue[Value.ContractId]]] = {
val stateKey = contractIdToStateKey(coid)
for {
// Fetch the state of the contract so that activeness and visibility can be checked.
@ -516,8 +516,8 @@ private[kvutils] class TransactionCommitter(
private def lookupKey(
transactionEntry: DamlTransactionEntrySummary,
inputState: DamlStateMap,
knownKeys: Map[DamlContractKey, Value.AbsoluteContractId],
)(key: Node.GlobalKey): Option[Value.AbsoluteContractId] = {
knownKeys: Map[DamlContractKey, Value.ContractId],
)(key: Node.GlobalKey): Option[Value.ContractId] = {
// we don't check whether the contract is active or not, because in we might not have loaded it earlier.
// this is not a problem, because:
// a) if the lookup was negative and we actually found a contract,

View File

@ -194,7 +194,7 @@ object KVTest {
}
)
.getOrElse(sys.error("Engine.submit fail"))
} yield tx.assertNoRelCid(_ => "Unexpected relative contract ids") -> meta
} yield tx -> meta
def runSimpleCommand(
submitter: Party,

View File

@ -15,7 +15,7 @@ import com.daml.lf.data.{FrontStack, Ref, SortedLookupList}
import com.daml.lf.transaction.Node.NodeCreate
import com.daml.lf.value.Value
import com.daml.lf.value.Value.{
AbsoluteContractId,
ContractId,
ValueList,
ValueOptional,
ValueParty,
@ -37,7 +37,7 @@ class KVUtilsTransactionSpec extends WordSpec with Matchers {
val eve = party("Eve")
val bobValue = ValueParty(bob)
val templateArgs: Map[String, Value[AbsoluteContractId]] = Map(
val templateArgs: Map[String, Value[ContractId]] = Map(
"Party" -> bobValue,
"Option Party" -> ValueOptional(Some(bobValue)),
"List Party" -> ValueList(FrontStack(bobValue)),
@ -59,9 +59,7 @@ class KVUtilsTransactionSpec extends WordSpec with Matchers {
// "GenMap Unit Party" -> Value.ValueGenMap(FrontStack(ValueUnit -> bobValue).toImmArray),
)
def createCmd(
templateId: Ref.Identifier,
templateArg: Value[Value.AbsoluteContractId]): Command =
def createCmd(templateId: Ref.Identifier, templateArg: Value[Value.ContractId]): Command =
CreateCommand(templateId, templateArg)
val simpleTemplateId = templateIdWith("Party")
@ -71,13 +69,13 @@ class KVUtilsTransactionSpec extends WordSpec with Matchers {
def exerciseCmd(coid: String, templateId: Ref.Identifier): Command =
ExerciseCommand(
templateId,
Value.AbsoluteContractId.assertFromString(coid),
Value.ContractId.assertFromString(coid),
simpleConsumeChoiceid,
ValueUnit)
def createAndExerciseCmd(
templateId: Ref.Identifier,
templateArg: Value[Value.AbsoluteContractId]): Command =
templateArg: Value[Value.ContractId]): Command =
CreateAndExerciseCommand(templateId, templateArg, simpleConsumeChoiceid, ValueUnit)
val p0 = mkParticipantId(0)
@ -135,7 +133,7 @@ class KVUtilsTransactionSpec extends WordSpec with Matchers {
.nodes
.values
.head
.asInstanceOf[NodeCreate[AbsoluteContractId, _]]
.asInstanceOf[NodeCreate[ContractId, _]]
.coid
transaction2 <- runSimpleCommand(alice, seeds(1), exerciseCmd(coid.coid, simpleTemplateId))

View File

@ -9,7 +9,7 @@ import com.daml.lf.data.{BackStack, ImmArray}
import com.daml.lf.engine.Blinding
import com.daml.lf.transaction.Transaction.Transaction
import com.daml.lf.transaction.{GenTransaction, Node}
import com.daml.lf.value.Value.{AbsoluteContractId, ContractInst, NodeId, ValueText, VersionedValue}
import com.daml.lf.value.Value.{ContractId, ContractInst, NodeId, ValueText, VersionedValue}
import com.daml.lf.value.ValueVersions
import org.scalatest.{Matchers, WordSpec}
@ -17,7 +17,7 @@ import scala.collection.immutable.HashMap
class ProjectionsSpec extends WordSpec with Matchers {
def makeCreateNode(cid: AbsoluteContractId, signatories: Set[Party], stakeholders: Set[Party]) =
def makeCreateNode(cid: ContractId, signatories: Set[Party], stakeholders: Set[Party]) =
Node.NodeCreate(
coid = cid,
coinst = ContractInst(
@ -34,7 +34,7 @@ class ProjectionsSpec extends WordSpec with Matchers {
)
def makeExeNode(
target: AbsoluteContractId,
target: ContractId,
actingParties: Set[Party],
signatories: Set[Party],
stakeholders: Set[Party],
@ -62,7 +62,7 @@ class ProjectionsSpec extends WordSpec with Matchers {
}
private def toCid(nid: NodeId) =
AbsoluteContractId.V1(crypto.Hash.hashPrivateKey(nid.toString))
ContractId.V1(crypto.Hash.hashPrivateKey(nid.toString))
"computePerPartyProjectionRoots" should {

View File

@ -85,7 +85,7 @@ object TestHelpers {
owner: String,
observer: String,
additionalContractDataType: String,
additionalContractValue: Value[Value.AbsoluteContractId]): Value[Value.AbsoluteContractId] =
additionalContractValue: Value[Value.ContractId]): Value[Value.ContractId] =
Value.ValueRecord(
Some(templateIdWith(additionalContractDataType)),
ImmArray(

View File

@ -11,10 +11,10 @@ import com.daml.lf.value.Value
* For more information on divulgence, see:
* https://docs.daml.com/concepts/ledger-model/ledger-privacy.html#divulgence-when-non-stakeholders-see-contracts
*
* @param contractId: The absolute contract identifier.
* @param contractId: The contract identifier.
* @param contractInst: The contract instance.
*/
final case class DivulgedContract(
contractId: Value.AbsoluteContractId,
contractInst: AbsoluteContractInst
contractId: Value.ContractId,
contractInst: ContractInst
)

View File

@ -85,18 +85,16 @@ trait WriteService
* associated [[ReadService]].
* @param transactionMeta : the meta-data accessible to all consumers of the
* transaction. See [[TransactionMeta]] for more information.
* @param transaction : the submitted transaction. This transaction can
* contain contract-ids that are relative to this transaction itself.
* These are used to refer to contracts created in the transaction
* itself. The participant state implementation is expected to convert
* these into absolute contract-ids that are guaranteed to be unique.
* This typically happens after a transaction has been assigned a
* globally unique id, as then the contract-ids can be derived from that
* transaction id.
* @param transaction : the submitted transaction. This transaction can contain local
* contract-ids that need suffixing. The participant state may have to
* suffix those contract-ids in order to guaranteed their global
* uniqueness. See the Contract Id specification for more detail
* daml-lf/spec/contract-id.rst.
* @return an async result of a SubmissionResult
*/
def submitTransaction(
submitterInfo: SubmitterInfo,
transactionMeta: TransactionMeta,
transaction: SubmittedTransaction): CompletionStage[SubmissionResult]
transaction: SubmittedTransaction,
): CompletionStage[SubmissionResult]
}

View File

@ -92,23 +92,22 @@ package object v1 {
/** Identifiers for parties. */
type Party = Ref.Party
/** A transaction with relative and absolute contract identifiers.
/** A transaction with contract IDs that may require suffixing.
*
* See [[WriteService.submitTransaction]] for details.
* See the Contract Id specification for more detail daml-lf/spec/contract-id.rst
*/
type SubmittedTransaction = Transaction.Transaction
/** A transaction with absolute contract identifiers only.
/** A transaction with globally unique contract IDs.
*
* Used to communicate transactions that have been accepted to the ledger.
* See [[WriteService.submitTransaction]] for details on relative and
* absolute contract identifiers.
* See the Contract Id specification for more detail daml-lf/spec/contract-id.rst
*/
type CommittedTransaction =
GenTransaction.WithTxValue[NodeId, Value.AbsoluteContractId]
GenTransaction.WithTxValue[NodeId, Value.ContractId]
/** A contract instance with absolute contract identifiers only. */
type AbsoluteContractInst =
Value.ContractInst[Value.VersionedValue[Value.AbsoluteContractId]]
/** A contract instance. */
type ContractInst =
Value.ContractInst[Value.VersionedValue[Value.ContractId]]
}

View File

@ -118,8 +118,8 @@ final class TimedIndexService(delegate: IndexService, metrics: Metrics) extends
override def lookupActiveContract(
submitter: Party,
contractId: Value.AbsoluteContractId
): Future[Option[Value.ContractInst[Value.VersionedValue[Value.AbsoluteContractId]]]] =
contractId: Value.ContractId
): Future[Option[Value.ContractInst[Value.VersionedValue[Value.ContractId]]]] =
Timed.future(
metrics.daml.services.indexService.lookupActiveContract,
delegate.lookupActiveContract(submitter, contractId))
@ -127,13 +127,13 @@ final class TimedIndexService(delegate: IndexService, metrics: Metrics) extends
override def lookupContractKey(
submitter: Party,
key: Node.GlobalKey
): Future[Option[Value.AbsoluteContractId]] =
): Future[Option[Value.ContractId]] =
Timed.future(
metrics.daml.services.indexService.lookupContractKey,
delegate.lookupContractKey(submitter, key))
override def lookupMaximumLedgerTime(
ids: Set[Value.AbsoluteContractId],
ids: Set[Value.ContractId],
): Future[Option[Instant]] =
Timed.future(
metrics.daml.services.indexService.lookupMaximumLedgerTime,

View File

@ -8,7 +8,7 @@ import com.daml.ledger.participant.state.index.v2.ContractStore
import com.daml.lf.crypto
import com.daml.lf.data.Time
import com.daml.lf.transaction.Transaction
import com.daml.lf.value.Value.AbsoluteContractId
import com.daml.lf.value.Value.ContractId
import com.daml.logging.{ContextualizedLogger, LoggingContext}
import com.daml.metrics.Metrics
import com.daml.platform.store.ErrorCause
@ -57,10 +57,10 @@ final class LedgerTimeAwareCommandExecutor(
// Command execution was successful.
// Check whether the ledger time used for input is consistent with the output,
// and advance output time or re-execute the command if necessary.
val usedContractIds: Set[AbsoluteContractId] = cer.transaction
val usedContractIds: Set[ContractId] = cer.transaction
.inputContracts[Transaction.TContractId]
.collect[AbsoluteContractId, Set[AbsoluteContractId]] {
case id: AbsoluteContractId => id
.collect[ContractId, Set[ContractId]] {
case id: ContractId => id
}
if (usedContractIds.isEmpty)
Future.successful(Right(cer))

View File

@ -15,7 +15,7 @@ import com.daml.lf.data.Ref.{Identifier, PackageId, Party}
import com.daml.lf.language.Ast
import com.daml.lf.transaction.Node.GlobalKey
import com.daml.lf.value.Value
import com.daml.lf.value.Value.{AbsoluteContractId, ContractInst}
import com.daml.lf.value.Value.{ContractId, ContractInst}
import com.daml.daml_lf_dev.DamlLf.Archive
import com.daml.dec.{DirectExecutionContext => DEC}
import com.daml.ledger.api.domain
@ -182,17 +182,17 @@ abstract class LedgerBackedIndexService(
override def lookupActiveContract(
submitter: Ref.Party,
contractId: AbsoluteContractId,
): Future[Option[ContractInst[Value.VersionedValue[AbsoluteContractId]]]] =
contractId: ContractId,
): Future[Option[ContractInst[Value.VersionedValue[ContractId]]]] =
ledger.lookupContract(contractId, submitter)
override def lookupMaximumLedgerTime(ids: Set[AbsoluteContractId]): Future[Option[Instant]] =
override def lookupMaximumLedgerTime(ids: Set[ContractId]): Future[Option[Instant]] =
ledger.lookupMaximumLedgerTime(ids)
override def lookupContractKey(
submitter: Party,
key: GlobalKey,
): Future[Option[AbsoluteContractId]] =
): Future[Option[ContractId]] =
ledger.lookupKey(key, submitter)
// PartyManagementService

View File

@ -26,7 +26,7 @@ import com.daml.lf.data.Ref.{Identifier, PackageId, Party}
import com.daml.lf.language.Ast
import com.daml.lf.transaction.Node.GlobalKey
import com.daml.lf.value.Value
import com.daml.lf.value.Value.{AbsoluteContractId, ContractInst}
import com.daml.lf.value.Value.{ContractId, ContractInst}
import com.daml.metrics.{Metrics, Timed}
import com.daml.platform.store.ReadOnlyLedger
import com.daml.platform.store.entries.{ConfigurationEntry, PackageLedgerEntry, PartyLedgerEntry}
@ -71,12 +71,12 @@ class MeteredReadOnlyLedger(ledger: ReadOnlyLedger, metrics: Metrics) extends Re
ledger.activeContracts(filter, verbose)
override def lookupContract(
contractId: Value.AbsoluteContractId,
contractId: Value.ContractId,
forParty: Party
): Future[Option[ContractInst[Value.VersionedValue[AbsoluteContractId]]]] =
): Future[Option[ContractInst[Value.VersionedValue[ContractId]]]] =
Timed.future(metrics.daml.index.lookupContract, ledger.lookupContract(contractId, forParty))
override def lookupKey(key: GlobalKey, forParty: Party): Future[Option[AbsoluteContractId]] =
override def lookupKey(key: GlobalKey, forParty: Party): Future[Option[ContractId]] =
Timed.future(metrics.daml.index.lookupKey, ledger.lookupKey(key, forParty))
override def lookupFlatTransactionById(
@ -98,7 +98,7 @@ class MeteredReadOnlyLedger(ledger: ReadOnlyLedger, metrics: Metrics) extends Re
)
override def lookupMaximumLedgerTime(
contractIds: Set[AbsoluteContractId],
contractIds: Set[ContractId],
): Future[Option[Instant]] =
Timed.future(
metrics.daml.index.lookupMaximumLedgerTime,

View File

@ -34,7 +34,7 @@ import scala.annotation.tailrec
object TransactionConversion {
private type ContractId = Lf.AbsoluteContractId
private type ContractId = Lf.ContractId
private type Transaction = GenTransaction.WithTxValue[EventId, ContractId]
private type Node = GenNode.WithTxValue[EventId, ContractId]
private type Create = NodeCreate.WithTxValue[ContractId]

View File

@ -6,46 +6,46 @@ package com.daml.platform.sandbox.stores
import java.time.Instant
import com.daml.ledger.api.domain.{PartyDetails, RejectionReason}
import com.daml.ledger.participant.state.v1.AbsoluteContractInst
import com.daml.ledger.participant.state.v1.ContractInst
import com.daml.ledger.{EventId, TransactionId, WorkflowId}
import com.daml.lf.data.Ref.Party
import com.daml.lf.data.Relation.Relation
import com.daml.lf.transaction.GenTransaction
import com.daml.lf.transaction.Node.GlobalKey
import com.daml.lf.value.Value
import com.daml.lf.value.Value.AbsoluteContractId
import com.daml.lf.value.Value.ContractId
import com.daml.platform.store.Contract.{ActiveContract, DivulgedContract}
import com.daml.platform.store._
import scalaz.syntax.std.map._
case class InMemoryActiveLedgerState(
activeContracts: Map[AbsoluteContractId, ActiveContract],
divulgedContracts: Map[AbsoluteContractId, DivulgedContract],
keys: Map[GlobalKey, AbsoluteContractId],
reverseKeys: Map[AbsoluteContractId, GlobalKey],
activeContracts: Map[ContractId, ActiveContract],
divulgedContracts: Map[ContractId, DivulgedContract],
keys: Map[GlobalKey, ContractId],
reverseKeys: Map[ContractId, GlobalKey],
parties: Map[Party, PartyDetails])
extends ActiveLedgerState[InMemoryActiveLedgerState] {
def isVisibleForDivulgees(contractId: AbsoluteContractId, forParty: Party): Boolean =
def isVisibleForDivulgees(contractId: ContractId, forParty: Party): Boolean =
activeContracts
.get(contractId)
.exists(ac => ac.witnesses.contains(forParty) || ac.divulgences.contains(forParty))
def isVisibleForStakeholders(contractId: AbsoluteContractId, forParty: Party): Boolean =
def isVisibleForStakeholders(contractId: ContractId, forParty: Party): Boolean =
activeContracts
.get(contractId)
.exists(ac => ac.signatories.contains(forParty) || ac.observers.contains(forParty))
def lookupContractByKeyFor(key: GlobalKey, forParty: Party): Option[AbsoluteContractId] =
def lookupContractByKeyFor(key: GlobalKey, forParty: Party): Option[ContractId] =
keys.get(key).filter(isVisibleForStakeholders(_, forParty))
override def lookupContractByKey(key: GlobalKey): Option[AbsoluteContractId] =
override def lookupContractByKey(key: GlobalKey): Option[ContractId] =
keys.get(key)
def lookupContract(cid: AbsoluteContractId): Option[Contract] =
def lookupContract(cid: ContractId): Option[Contract] =
activeContracts.get(cid).orElse[Contract](divulgedContracts.get(cid))
override def lookupContractLet(cid: AbsoluteContractId): Option[LetLookup] =
override def lookupContractLet(cid: ContractId): Option[LetLookup] =
activeContracts
.get(cid)
.map(c => Let(c.let))
@ -82,7 +82,7 @@ case class InMemoryActiveLedgerState(
}
}
override def removeContract(cid: AbsoluteContractId): InMemoryActiveLedgerState = {
override def removeContract(cid: ContractId): InMemoryActiveLedgerState = {
val (newKeys, newReverseKeys) = reverseKeys.get(cid) match {
case None => (keys, reverseKeys)
case Some(key) => (keys - key, reverseKeys - cid)
@ -100,24 +100,23 @@ case class InMemoryActiveLedgerState(
override def divulgeAlreadyCommittedContracts(
transactionId: TransactionId,
global: Relation[AbsoluteContractId, Party],
referencedContracts: List[(Value.AbsoluteContractId, AbsoluteContractInst)])
: InMemoryActiveLedgerState =
global: Relation[ContractId, Party],
referencedContracts: List[(Value.ContractId, ContractInst)]): InMemoryActiveLedgerState =
if (global.nonEmpty) {
val referencedContractsM = referencedContracts.toMap
// Note: each entry in `global` can refer to either:
// - a known active contract, in which case its divulgence info is updated
// - a previously divulged contract, in which case its divulgence info is updated
// - an unknown contract, in which case a new divulged contract is created from the corresponding info in `referencedContracts`
val updatedAcs: Map[AbsoluteContractId, ActiveContract] =
val updatedAcs: Map[ContractId, ActiveContract] =
activeContracts.intersectWith(global) { (ac, parties) =>
ac.copy(divulgences = ac.divulgeTo(parties, transactionId))
}
val updatedDcs: Map[AbsoluteContractId, DivulgedContract] =
val updatedDcs: Map[ContractId, DivulgedContract] =
divulgedContracts.intersectWith(global) { (dc, parties) =>
dc.copy(divulgences = dc.divulgeTo(parties, transactionId))
}
val newDcs = global.foldLeft(Map.empty[AbsoluteContractId, DivulgedContract]) {
val newDcs = global.foldLeft(Map.empty[ContractId, DivulgedContract]) {
case (m, (cid, divulgeTo)) =>
if (divulgeTo.isEmpty || updatedAcs.contains(cid) || updatedDcs.contains(cid))
m
@ -151,10 +150,10 @@ case class InMemoryActiveLedgerState(
transactionId: TransactionId,
workflowId: Option[WorkflowId],
submitter: Option[Party],
transaction: GenTransaction.WithTxValue[EventId, AbsoluteContractId],
transaction: GenTransaction.WithTxValue[EventId, ContractId],
disclosure: Relation[EventId, Party],
globalDivulgence: Relation[AbsoluteContractId, Party],
referencedContracts: List[(Value.AbsoluteContractId, AbsoluteContractInst)]
globalDivulgence: Relation[ContractId, Party],
referencedContracts: List[(Value.ContractId, ContractInst)]
): Either[Set[RejectionReason], InMemoryActiveLedgerState] =
acManager.addTransaction(
let,

View File

@ -12,7 +12,7 @@ import com.daml.lf.data.Time.Timestamp
import com.daml.lf.engine.Blinding
import com.daml.lf.transaction.{GenTransaction, TransactionCommitter}
import com.daml.lf.value.Value
import com.daml.lf.value.Value.AbsoluteContractId
import com.daml.lf.value.Value.ContractId
import com.daml.daml_lf_dev.DamlLf.Archive
import com.daml.ledger.EventId
import com.daml.platform.events.EventIdFormatter
@ -55,9 +55,9 @@ trait Ledger extends ReadOnlyLedger {
object Ledger {
type TransactionForIndex =
GenTransaction[EventId, AbsoluteContractId, Value.VersionedValue[AbsoluteContractId]]
GenTransaction[EventId, ContractId, Value.VersionedValue[ContractId]]
type DisclosureForIndex = Map[EventId, Set[Party]]
type GlobalDivulgence = Relation[AbsoluteContractId, Party]
type GlobalDivulgence = Relation[ContractId, Party]
def convertToCommittedTransaction(
committer: TransactionCommitter,

View File

@ -21,7 +21,7 @@ object StandardTransactionCommitter extends TransactionCommitter {
transactionId: Ref.LedgerString,
transaction: SubmittedTransaction
): CommittedTransaction =
transaction.assertNoRelCid(_ => "Unexpected relative contract ID")
transaction
}
// Committer emulating Contract ID legacy scheme
@ -34,24 +34,13 @@ object LegacyTransactionCommitter extends TransactionCommitter {
val prefix = "#" + transactionId + ":"
type AbsCoid = Value.AbsoluteContractId
val contractMap: AbsCoid => AbsCoid =
transaction.localContracts
.collect[(AbsCoid, AbsCoid), Map[AbsCoid, AbsCoid]] {
case (acoid: AbsCoid, nid) =>
acoid ->
Value.AbsoluteContractId.V0(
Ref.ContractIdString.assertFromString(prefix + nid.index.toString))
}
val contractMapping =
transaction
.localContracts[Value.ContractId]
.transform((_, nid) =>
Value.ContractId.V0(Ref.ContractIdString.assertFromString(prefix + nid.index.toString)))
.withDefault(identity)
val contractMapping: Transaction.TContractId => Value.AbsoluteContractId = {
case acoid: Value.AbsoluteContractId =>
contractMap(acoid)
case _: Value.RelativeContractId =>
throw new RuntimeException("Unexpected relative contract ID")
}
GenTransaction.map3(
identity[Transaction.NodeId],
contractMapping,

View File

@ -26,7 +26,7 @@ import com.daml.lf.data.{ImmArray, Ref, Time}
import com.daml.lf.language.Ast
import com.daml.lf.transaction.{Node, TransactionCommitter}
import com.daml.lf.value.Value
import com.daml.lf.value.Value.{AbsoluteContractId, ContractInst}
import com.daml.lf.value.Value.{ContractId, ContractInst}
import com.daml.daml_lf_dev.DamlLf.Archive
import com.daml.ledger
import com.daml.ledger.api.domain.{
@ -243,9 +243,9 @@ class InMemoryLedger(
}
override def lookupContract(
contractId: AbsoluteContractId,
contractId: ContractId,
forParty: Party
): Future[Option[ContractInst[Value.VersionedValue[AbsoluteContractId]]]] =
): Future[Option[ContractInst[Value.VersionedValue[ContractId]]]] =
Future.successful(this.synchronized {
acs.activeContracts
.get(contractId)
@ -253,13 +253,12 @@ class InMemoryLedger(
.map(_.contract)
})
override def lookupKey(key: Node.GlobalKey, forParty: Party): Future[Option[AbsoluteContractId]] =
override def lookupKey(key: Node.GlobalKey, forParty: Party): Future[Option[ContractId]] =
Future.successful(this.synchronized {
acs.keys.get(key).filter(acs.isVisibleForStakeholders(_, forParty))
})
override def lookupMaximumLedgerTime(
contractIds: Set[AbsoluteContractId]): Future[Option[Instant]] =
override def lookupMaximumLedgerTime(contractIds: Set[ContractId]): Future[Option[Instant]] =
if (contractIds.isEmpty) {
Future.failed(
new IllegalArgumentException(

View File

@ -5,12 +5,12 @@ package com.daml.platform.store
import java.time.Instant
import com.daml.ledger.participant.state.v1.AbsoluteContractInst
import com.daml.ledger.participant.state.v1.ContractInst
import com.daml.lf.data.Ref.Party
import com.daml.lf.data.Relation.Relation
import com.daml.lf.transaction.Node.GlobalKey
import com.daml.lf.value.Value
import com.daml.lf.value.Value.AbsoluteContractId
import com.daml.lf.value.Value.ContractId
import com.daml.ledger.TransactionId
import com.daml.platform.store.Contract.ActiveContract
@ -43,17 +43,17 @@ trait ActiveLedgerState[ALS <: ActiveLedgerState[ALS]] {
* - Some(LetUnknown) if the contract exists, but its LET is unknown (i.e., a divulged contract)
* - Some(Let(_)) if the contract exists and its LET is known
* */
def lookupContractLet(cid: AbsoluteContractId): Option[LetLookup]
def lookupContractLet(cid: ContractId): Option[LetLookup]
/** Callback to query a contract by key, used for validating NodeLookupByKey nodes.
* */
def lookupContractByKey(key: GlobalKey): Option[AbsoluteContractId]
def lookupContractByKey(key: GlobalKey): Option[ContractId]
/** Called when a new contract is created */
def addContract(c: ActiveContract, keyO: Option[GlobalKey]): ALS
/** Called when the given contract is archived */
def removeContract(cid: AbsoluteContractId): ALS
def removeContract(cid: ContractId): ALS
/** Called once for each transaction with the set of parties found in that transaction.
* As the sandbox has an open world of parties, any party name mentioned in a transaction
@ -68,6 +68,6 @@ trait ActiveLedgerState[ALS <: ActiveLedgerState[ALS]] {
*/
def divulgeAlreadyCommittedContracts(
transactionId: TransactionId,
global: Relation[AbsoluteContractId, Party],
referencedContracts: List[(Value.AbsoluteContractId, AbsoluteContractInst)]): ALS
global: Relation[ContractId, Party],
referencedContracts: List[(Value.ContractId, ContractInst)]): ALS
}

View File

@ -7,14 +7,14 @@ import java.time.Instant
import com.daml.ledger.api.domain.RejectionReason
import com.daml.ledger.api.domain.RejectionReason.{Disputed, Inconsistent, InvalidLedgerTime}
import com.daml.ledger.participant.state.v1.AbsoluteContractInst
import com.daml.ledger.participant.state.v1.ContractInst
import com.daml.ledger.{EventId, TransactionId, WorkflowId}
import com.daml.lf.data.Ref.Party
import com.daml.lf.data.Relation.Relation
import com.daml.lf.transaction.Node.GlobalKey
import com.daml.lf.transaction.{GenTransaction, Node => N}
import com.daml.lf.value.Value
import com.daml.lf.value.Value.AbsoluteContractId
import com.daml.lf.value.Value.ContractId
import com.daml.platform.store.Contract.ActiveContract
/**
@ -28,7 +28,7 @@ class ActiveLedgerStateManager[ALS <: ActiveLedgerState[ALS]](initialState: => A
acc: Option[ALS],
errs: Set[RejectionReason],
parties: Set[Party],
archivedIds: Set[AbsoluteContractId]) {
archivedIds: Set[ContractId]) {
def mapAcs(f: ALS => ALS): AddTransactionState = copy(acc = acc map f)
@ -63,10 +63,10 @@ class ActiveLedgerStateManager[ALS <: ActiveLedgerState[ALS]](initialState: => A
transactionId: TransactionId,
workflowId: Option[WorkflowId],
submitter: Option[Party],
transaction: GenTransaction.WithTxValue[EventId, AbsoluteContractId],
transaction: GenTransaction.WithTxValue[EventId, ContractId],
disclosure: Relation[EventId, Party],
globalDivulgence: Relation[AbsoluteContractId, Party],
divulgedContracts: List[(Value.AbsoluteContractId, AbsoluteContractInst)])
globalDivulgence: Relation[ContractId, Party],
divulgedContracts: List[(Value.ContractId, ContractInst)])
: Either[Set[RejectionReason], ALS] = {
// NOTE(RA): `globalImplicitDisclosure` was meant to refer to contracts created in previous transactions.
// However, because we have translated relative to absolute IDs at this point, `globalImplicitDisclosure`
@ -86,7 +86,7 @@ class ActiveLedgerStateManager[ALS <: ActiveLedgerState[ALS]](initialState: => A
case (ats @ AddTransactionState(Some(acc), errs, parties, archivedIds), (nodeId, node)) =>
// If some node requires a contract, check that we have that contract, and check that that contract is not
// created after the current let.
def contractCheck(cid: AbsoluteContractId): Option[RejectionReason] =
def contractCheck(cid: ContractId): Option[RejectionReason] =
acc lookupContractLet cid match {
case Some(Let(otherContractLet)) =>
// Existing active contract, check its LET
@ -108,7 +108,7 @@ class ActiveLedgerStateManager[ALS <: ActiveLedgerState[ALS]](initialState: => A
}
node match {
case nf: N.NodeFetch.WithTxValue[AbsoluteContractId] =>
case nf: N.NodeFetch.WithTxValue[ContractId] =>
val nodeParties = nf.signatories
.union(nf.stakeholders)
.union(nf.actingParties.getOrElse(Set.empty))
@ -118,7 +118,7 @@ class ActiveLedgerStateManager[ALS <: ActiveLedgerState[ALS]](initialState: => A
parties.union(nodeParties),
archivedIds
)
case nc: N.NodeCreate.WithTxValue[AbsoluteContractId] =>
case nc: N.NodeCreate.WithTxValue[ContractId] =>
val nodeParties = nc.signatories
.union(nc.stakeholders)
.union(nc.key.map(_.maintainers).getOrElse(Set.empty))
@ -131,7 +131,7 @@ class ActiveLedgerStateManager[ALS <: ActiveLedgerState[ALS]](initialState: => A
contract = nc.coinst,
witnesses = disclosure(nodeId),
// The divulgences field used to be filled with data coming from the `localDivulgence` field of the blinding info.
// But this field is always empty in transactions with only absolute contract ids.
// But this field is always empty in transactions with only contract ids.
divulgences = Map.empty,
key =
nc.key.map(_.assertNoCid(coid => s"Contract ID $coid found in contract key")),
@ -159,7 +159,7 @@ class ActiveLedgerStateManager[ALS <: ActiveLedgerState[ALS]](initialState: => A
)
}
}
case ne: N.NodeExercises.WithTxValue[EventId, AbsoluteContractId] =>
case ne: N.NodeExercises.WithTxValue[EventId, ContractId] =>
val nodeParties = ne.signatories
.union(ne.stakeholders)
.union(ne.actingParties)
@ -173,7 +173,7 @@ class ActiveLedgerStateManager[ALS <: ActiveLedgerState[ALS]](initialState: => A
parties = parties.union(nodeParties),
archivedIds = if (ne.consuming) archivedIds + ne.targetCoid else archivedIds
)
case nlkup: N.NodeLookupByKey.WithTxValue[AbsoluteContractId] =>
case nlkup: N.NodeLookupByKey.WithTxValue[ContractId] =>
// Check that the stored lookup result matches the current result
val key = nlkup.key.key.ensureNoCid.fold(
coid =>

View File

@ -16,7 +16,7 @@ import com.daml.lf.data.Ref.{Identifier, PackageId, Party}
import com.daml.lf.language.Ast
import com.daml.lf.transaction.Node
import com.daml.lf.value.Value
import com.daml.lf.value.Value.{AbsoluteContractId, ContractInst}
import com.daml.lf.value.Value.{ContractId, ContractInst}
import com.daml.daml_lf_dev.DamlLf
import com.daml.dec.DirectExecutionContext
import com.daml.ledger.TransactionId
@ -56,7 +56,7 @@ abstract class BaseLedger(
override def currentHealth(): HealthStatus = ledgerDao.currentHealth()
override def lookupKey(key: Node.GlobalKey, forParty: Party): Future[Option[AbsoluteContractId]] =
override def lookupKey(key: Node.GlobalKey, forParty: Party): Future[Option[ContractId]] =
ledgerDao.lookupKey(key, forParty)
override def flatTransactions(
@ -105,9 +105,9 @@ abstract class BaseLedger(
}
override def lookupContract(
contractId: AbsoluteContractId,
contractId: ContractId,
forParty: Party
): Future[Option[ContractInst[Value.VersionedValue[AbsoluteContractId]]]] =
): Future[Option[ContractInst[Value.VersionedValue[ContractId]]]] =
ledgerDao.lookupActiveOrDivulgedContract(contractId, forParty)
override def lookupFlatTransactionById(
@ -123,7 +123,7 @@ abstract class BaseLedger(
ledgerDao.transactionsReader.lookupTransactionTreeById(transactionId, requestingParties)
override def lookupMaximumLedgerTime(
contractIds: Set[AbsoluteContractId],
contractIds: Set[ContractId],
): Future[Option[Instant]] =
ledgerDao.lookupMaximumLedgerTime(contractIds)

View File

@ -8,16 +8,16 @@ import java.time.Instant
import com.daml.lf.data.Ref.Party
import com.daml.lf.transaction.Node.KeyWithMaintainers
import com.daml.lf.value.Value
import com.daml.lf.value.Value.{AbsoluteContractId, ContractInst, VersionedValue}
import com.daml.lf.value.Value.{ContractId, ContractInst, VersionedValue}
import com.daml.ledger.{EventId, TransactionId, WorkflowId}
/** A contract that is part of the [[ActiveLedgerState]].
* Depending on where the contract came from, other metadata may be available.
*/
sealed abstract class Contract {
def id: Value.AbsoluteContractId
def id: Value.ContractId
def contract: ContractInst[VersionedValue[AbsoluteContractId]]
def contract: ContractInst[VersionedValue[ContractId]]
/** For each party, the transaction id at which the contract was divulged */
def divulgences: Map[Party, TransactionId]
@ -39,8 +39,8 @@ object Contract {
* These contracts are only used for transaction validation, they are not part of the active contract set.
*/
final case class DivulgedContract(
id: Value.AbsoluteContractId,
contract: ContractInst[VersionedValue[AbsoluteContractId]],
id: Value.ContractId,
contract: ContractInst[VersionedValue[ContractId]],
/** For each party, the transaction id at which the contract was divulged */
divulgences: Map[Party, TransactionId],
) extends Contract
@ -49,12 +49,12 @@ object Contract {
* For active contracts, we know all metadata.
*/
final case class ActiveContract(
id: Value.AbsoluteContractId,
id: Value.ContractId,
let: Instant, // time when the contract was committed
transactionId: TransactionId, // transaction id where the contract originates
eventId: EventId,
workflowId: Option[WorkflowId], // workflow id from where the contract originates
contract: ContractInst[VersionedValue[AbsoluteContractId]],
contract: ContractInst[VersionedValue[ContractId]],
witnesses: Set[Party],
divulgences: Map[Party, TransactionId], // for each party, the transaction id at which the contract was divulged
key: Option[KeyWithMaintainers[VersionedValue[Nothing]]],

View File

@ -87,18 +87,16 @@ object Conversions {
def participantId(columnName: String): RowParser[Ref.ParticipantId] =
SqlParser.get[Ref.ParticipantId](columnName)(columnToParticipantId)
// AbsoluteContractId
implicit val columnToContractId: Column[Value.ContractId] =
stringColumnToX(Value.ContractId.fromString)
implicit val columnToContractId: Column[Value.AbsoluteContractId] =
stringColumnToX(Value.AbsoluteContractId.fromString)
implicit object ContractIdToStatement extends ToStatement[Value.AbsoluteContractId] {
override def set(s: PreparedStatement, index: Int, v: Value.AbsoluteContractId): Unit =
implicit object ContractIdToStatement extends ToStatement[Value.ContractId] {
override def set(s: PreparedStatement, index: Int, v: Value.ContractId): Unit =
ToStatement.stringToStatement.set(s, index, v.coid)
}
def contractId(columnName: String): RowParser[Value.AbsoluteContractId] =
SqlParser.get[Value.AbsoluteContractId](columnName)(columnToContractId)
def contractId(columnName: String): RowParser[Value.ContractId] =
SqlParser.get[Value.ContractId](columnName)(columnToContractId)
// ContractIdString

View File

@ -14,7 +14,7 @@ import com.daml.lf.data.Ref.{Identifier, PackageId, Party}
import com.daml.lf.language.Ast
import com.daml.lf.transaction.Node.GlobalKey
import com.daml.lf.value.Value
import com.daml.lf.value.Value.{AbsoluteContractId, ContractInst}
import com.daml.lf.value.Value.{ContractId, ContractInst}
import com.daml.daml_lf_dev.DamlLf.Archive
import com.daml.ledger.TransactionId
import com.daml.ledger.api.domain.{ApplicationId, CommandId, LedgerId, PartyDetails}
@ -64,15 +64,15 @@ trait ReadOnlyLedger extends ReportsHealth with AutoCloseable {
): (Source[GetActiveContractsResponse, NotUsed], Offset)
def lookupContract(
contractId: Value.AbsoluteContractId,
contractId: Value.ContractId,
forParty: Party
): Future[Option[ContractInst[Value.VersionedValue[AbsoluteContractId]]]]
): Future[Option[ContractInst[Value.VersionedValue[ContractId]]]]
def lookupMaximumLedgerTime(
contractIds: Set[AbsoluteContractId],
contractIds: Set[ContractId],
): Future[Option[Instant]]
def lookupKey(key: GlobalKey, forParty: Party): Future[Option[AbsoluteContractId]]
def lookupKey(key: GlobalKey, forParty: Party): Future[Option[ContractId]]
def lookupFlatTransactionById(
transactionId: TransactionId,

View File

@ -28,7 +28,7 @@ import com.daml.lf.archive.Decode
import com.daml.lf.data.Ref
import com.daml.lf.data.Ref.{PackageId, Party}
import com.daml.lf.transaction.Node
import com.daml.lf.value.Value.{AbsoluteContractId, NodeId}
import com.daml.lf.value.Value.{ContractId, NodeId}
import com.daml.logging.{ContextualizedLogger, LoggingContext}
import com.daml.metrics.Metrics
import com.daml.platform.ApiOffset.ApiOffsetConverter
@ -455,7 +455,7 @@ private class JdbcLedgerDao(
}
}
override def lookupKey(key: Node.GlobalKey, forParty: Party): Future[Option[AbsoluteContractId]] =
override def lookupKey(key: Node.GlobalKey, forParty: Party): Future[Option[ContractId]] =
contractsReader.lookupContractKey(forParty, key)
private def splitOrThrow(id: EventId): NodeId =
@ -582,14 +582,14 @@ private class JdbcLedgerDao(
private val PageSize = 100
override def lookupMaximumLedgerTime(
contractIds: Set[AbsoluteContractId],
contractIds: Set[ContractId],
): Future[Option[Instant]] =
contractsReader.lookupMaximumLedgerTime(contractIds)
override def lookupActiveOrDivulgedContract(
contractId: AbsoluteContractId,
contractId: ContractId,
forParty: Party,
): Future[Option[AbsoluteContractInst]] =
): Future[Option[ContractInst]] =
contractsReader.lookupActiveContract(forParty, contractId)
private val SQL_SELECT_MULTIPLE_PARTIES =

View File

@ -22,7 +22,7 @@ import com.daml.lf.data.Ref
import com.daml.lf.data.Ref.{PackageId, Party}
import com.daml.lf.transaction.Node
import com.daml.lf.value.Value
import com.daml.lf.value.Value.{AbsoluteContractId, ContractInst}
import com.daml.lf.value.Value.{ContractId, ContractInst}
import com.daml.daml_lf_dev.DamlLf.Archive
import com.daml.ledger.WorkflowId
import com.daml.ledger.api.domain.{CommandId, LedgerId, PartyDetails}
@ -52,12 +52,12 @@ trait LedgerReadDao extends ReportsHealth {
/** Looks up an active or divulged contract if it is visible for the given party. Archived contracts must not be returned by this method */
def lookupActiveOrDivulgedContract(
contractId: AbsoluteContractId,
forParty: Party): Future[Option[ContractInst[Value.VersionedValue[AbsoluteContractId]]]]
contractId: ContractId,
forParty: Party): Future[Option[ContractInst[Value.VersionedValue[ContractId]]]]
/** Returns the largest ledger time of any of the given contracts */
def lookupMaximumLedgerTime(
contractIds: Set[AbsoluteContractId],
contractIds: Set[ContractId],
): Future[Option[Instant]]
/** Looks up the current ledger configuration, if it has been set. */
@ -75,9 +75,9 @@ trait LedgerReadDao extends ReportsHealth {
*
* @param key the contract key to query
* @param forParty the party for which the contract must be visible
* @return the optional AbsoluteContractId
* @return the optional ContractId
*/
def lookupKey(key: Node.GlobalKey, forParty: Party): Future[Option[AbsoluteContractId]]
def lookupKey(key: Node.GlobalKey, forParty: Party): Future[Option[ContractId]]
/** Returns a list of party details for the parties specified. */
def getParties(parties: Seq[Party]): Future[List[PartyDetails]]

View File

@ -17,7 +17,7 @@ import com.daml.lf.data.Ref
import com.daml.lf.data.Ref.{PackageId, Party}
import com.daml.lf.transaction.Node
import com.daml.lf.value.Value
import com.daml.lf.value.Value.{AbsoluteContractId, ContractInst}
import com.daml.lf.value.Value.{ContractId, ContractInst}
import com.daml.metrics.{Metrics, Timed}
import com.daml.platform.store.dao.events.TransactionsReader
import com.daml.platform.store.entries.{
@ -45,14 +45,14 @@ class MeteredLedgerReadDao(ledgerDao: LedgerReadDao, metrics: Metrics) extends L
Timed.future(metrics.daml.index.db.lookupLedgerEnd, ledgerDao.lookupInitialLedgerEnd())
override def lookupActiveOrDivulgedContract(
contractId: Value.AbsoluteContractId,
forParty: Party): Future[Option[ContractInst[Value.VersionedValue[AbsoluteContractId]]]] =
contractId: Value.ContractId,
forParty: Party): Future[Option[ContractInst[Value.VersionedValue[ContractId]]]] =
Timed.future(
metrics.daml.index.db.lookupActiveContract,
ledgerDao.lookupActiveOrDivulgedContract(contractId, forParty))
override def lookupMaximumLedgerTime(
contractIds: Set[AbsoluteContractId],
contractIds: Set[ContractId],
): Future[Option[Instant]] =
Timed.future(
metrics.daml.index.db.lookupMaximumLedgerTime,
@ -60,9 +60,7 @@ class MeteredLedgerReadDao(ledgerDao: LedgerReadDao, metrics: Metrics) extends L
override def transactionsReader: TransactionsReader = ledgerDao.transactionsReader
override def lookupKey(
key: Node.GlobalKey,
forParty: Party): Future[Option[Value.AbsoluteContractId]] =
override def lookupKey(key: Node.GlobalKey, forParty: Party): Future[Option[Value.ContractId]] =
Timed.future(metrics.daml.index.db.lookupKey, ledgerDao.lookupKey(key, forParty))
override def getParties(parties: Seq[Party]): Future[List[PartyDetails]] =

View File

@ -11,8 +11,8 @@ import akka.stream.scaladsl.Source
package object events {
import com.daml.lf.value.{Value => lfval}
private[events] type ContractId = lfval.AbsoluteContractId
private[events] val ContractId = com.daml.lf.value.Value.AbsoluteContractId
private[events] type ContractId = lfval.ContractId
private[events] val ContractId = com.daml.lf.value.Value.ContractId
private[events] type Value = lfval.VersionedValue[ContractId]
private[events] type Contract = lfval.ContractInst[Value]
private[events] val Contract = lfval.ContractInst

Some files were not shown because too many files have changed in this diff Show More