mirror of
https://github.com/digital-asset/daml.git
synced 2024-09-20 01:07:18 +03:00
LF: Archive decoder reject choice observers for LF < 1.dev (#8283)
CHANGELOG_BEGIN CHANGELOG_END
This commit is contained in:
parent
70af09db51
commit
91b53dd3f1
@ -555,7 +555,7 @@ private[archive] class DecodeV1(minor: LV.Minor) extends Decode.OfPackage[PLF.Pa
|
||||
)
|
||||
}
|
||||
|
||||
private[this] def decodeChoice(
|
||||
private[archive] def decodeChoice(
|
||||
tpl: DottedName,
|
||||
lfChoice: PLF.TemplateChoice): TemplateChoice = {
|
||||
val (v, t) = decodeBinder(lfChoice.getArgBinder)
|
||||
@ -579,10 +579,12 @@ private[archive] class DecodeV1(minor: LV.Minor) extends Decode.OfPackage[PLF.Pa
|
||||
name = chName,
|
||||
consuming = lfChoice.getConsuming,
|
||||
controllers = decodeExpr(lfChoice.getControllers, s"$tpl:$chName:controller"),
|
||||
choiceObservers =
|
||||
if (lfChoice.hasObservers)
|
||||
choiceObservers = if (lfChoice.hasObservers) {
|
||||
assertSince(LV.Features.choiceObservers, "TemplateChoice.observers")
|
||||
Some(decodeExpr(lfChoice.getObservers, s"$tpl:$chName:observers"))
|
||||
else None,
|
||||
} else {
|
||||
None
|
||||
},
|
||||
selfBinder = selfBinder,
|
||||
argBinder = v -> t,
|
||||
returnType = decodeType(lfChoice.getRetType),
|
||||
|
@ -12,7 +12,6 @@ import com.daml.lf.data.{Decimal, Numeric, Ref}
|
||||
import com.daml.lf.language.Util._
|
||||
import com.daml.lf.language.{Ast, LanguageVersion => LV}
|
||||
import com.daml.lf.data.ImmArray.ImmArraySeq
|
||||
import com.daml.lf.data.Ref.DottedName
|
||||
import com.daml.daml_lf_dev.DamlLf1
|
||||
import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks
|
||||
import org.scalatest.{Inside, OptionValues}
|
||||
@ -53,7 +52,7 @@ class DecodeV1Spec
|
||||
}
|
||||
|
||||
private[this] val dummyModuleStr = "dummyModule"
|
||||
private[this] val dummyModuleName = DottedName.assertFromString(dummyModuleStr)
|
||||
private[this] val dummyModuleName = Ref.DottedName.assertFromString(dummyModuleStr)
|
||||
|
||||
private[this] val lfVersions = List(LV.v1_6, LV.v1_7, LV.v1_8, LV.v1_dev)
|
||||
|
||||
@ -69,13 +68,14 @@ class DecodeV1Spec
|
||||
private def moduleDecoder(
|
||||
version: LV,
|
||||
stringTable: ImmArraySeq[String] = ImmArraySeq.empty,
|
||||
dottedNameTable: ImmArraySeq[DottedName] = ImmArraySeq.empty,
|
||||
dottedNameTable: ImmArraySeq[Ref.DottedName] = ImmArraySeq.empty,
|
||||
typeTable: ImmArraySeq[Ast.Type] = ImmArraySeq.empty,
|
||||
) = {
|
||||
new DecodeV1(version.minor).Env(
|
||||
Ref.PackageId.assertFromString("noPkgId"),
|
||||
stringTable,
|
||||
dottedNameTable,
|
||||
IndexedSeq(),
|
||||
typeTable,
|
||||
None,
|
||||
Some(dummyModuleName),
|
||||
onlySerializableDataDefs = false
|
||||
@ -281,7 +281,7 @@ class DecodeV1Spec
|
||||
"reject non interned type for LF >= 1.dev" in {
|
||||
|
||||
val stringTable = ImmArraySeq("pkgId", "x")
|
||||
val dottedNameTable = ImmArraySeq("Mod", "T", "S").map(DottedName.assertFromString)
|
||||
val dottedNameTable = ImmArraySeq("Mod", "T", "S").map(Ref.DottedName.assertFromString)
|
||||
|
||||
val unit = DamlLf1.Unit.newBuilder().build()
|
||||
val pkgRef = DamlLf1.PackageRef.newBuilder().setSelf(unit).build
|
||||
@ -875,6 +875,113 @@ class DecodeV1Spec
|
||||
}
|
||||
}
|
||||
|
||||
"decodeChoice" should {
|
||||
val stringTable = ImmArraySeq("SomeChoice", "controllers", "observers", "self", "arg", "body")
|
||||
val typeTable = ImmArraySeq(TUnit)
|
||||
val templateName = Ref.DottedName.assertFromString("Template")
|
||||
val controllersExpr = DamlLf1.Expr.newBuilder().setVarInternedStr(1).build()
|
||||
val observersExpr = DamlLf1.Expr.newBuilder().setVarInternedStr(2).build()
|
||||
val bodyExp = DamlLf1.Expr.newBuilder().setVarInternedStr(5).build()
|
||||
|
||||
"reject choice with observers if lf version = 1.6" in {
|
||||
// special case for LF 1.6 that does not support string interning
|
||||
val unitTyp: DamlLf1.Type = DamlLf1.Type
|
||||
.newBuilder()
|
||||
.setPrim(DamlLf1.Type.Prim.newBuilder().setPrim(DamlLf1.PrimType.UNIT))
|
||||
.build()
|
||||
|
||||
val protoChoiceWithoutObservers = DamlLf1.TemplateChoice
|
||||
.newBuilder()
|
||||
.setNameStr("ChoiceName")
|
||||
.setConsuming(true)
|
||||
.setControllers(DamlLf1.Expr.newBuilder().setVarStr("controllers"))
|
||||
.setSelfBinderStr("self")
|
||||
.setArgBinder(DamlLf1.VarWithType.newBuilder().setVarStr("arg").setType(unitTyp))
|
||||
.setRetType(unitTyp)
|
||||
.setUpdate(DamlLf1.Expr.newBuilder().setVarStr("body").build())
|
||||
.build()
|
||||
|
||||
val protoChoiceWithObservers =
|
||||
protoChoiceWithoutObservers.toBuilder.setObservers(observersExpr).build
|
||||
|
||||
forEveryVersionSuchThat(_ < LV.Features.internedStrings) { version =>
|
||||
assert(version < LV.Features.internedStrings)
|
||||
assert(version < LV.Features.internedTypes)
|
||||
|
||||
val decoder = moduleDecoder(version)
|
||||
|
||||
decoder.decodeChoice(templateName, protoChoiceWithoutObservers)
|
||||
a[ParseError] should be thrownBy (decoder
|
||||
.decodeChoice(templateName, protoChoiceWithObservers))
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
"reject choice with observers if 1.7 < lf version < 1.dev" in {
|
||||
val unitTyp: DamlLf1.Type = DamlLf1.Type
|
||||
.newBuilder()
|
||||
.setPrim(DamlLf1.Type.Prim.newBuilder().setPrim(DamlLf1.PrimType.UNIT))
|
||||
.build()
|
||||
|
||||
val protoChoiceWithoutObservers = DamlLf1.TemplateChoice
|
||||
.newBuilder()
|
||||
.setNameInternedStr(0)
|
||||
.setConsuming(true)
|
||||
.setControllers(controllersExpr)
|
||||
.setSelfBinderInternedStr(3)
|
||||
.setArgBinder(DamlLf1.VarWithType.newBuilder().setVarInternedStr(4).setType(unitTyp))
|
||||
.setRetType(unitTyp)
|
||||
.setUpdate(bodyExp)
|
||||
.build()
|
||||
|
||||
val protoChoiceWithObservers =
|
||||
protoChoiceWithoutObservers.toBuilder.setObservers(observersExpr).build
|
||||
|
||||
forEveryVersionSuchThat(
|
||||
v => LV.Features.internedStrings < v && v < LV.Features.choiceObservers
|
||||
) { version =>
|
||||
assert(LV.Features.internedStrings <= version)
|
||||
assert(version < LV.Features.internedTypes)
|
||||
|
||||
val decoder = moduleDecoder(version, stringTable)
|
||||
|
||||
decoder.decodeChoice(templateName, protoChoiceWithoutObservers)
|
||||
a[ParseError] should be thrownBy decoder
|
||||
.decodeChoice(templateName, protoChoiceWithObservers)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
"accept choice with or without observers if lv version >= 1.dev" in {
|
||||
|
||||
val unitTyp = DamlLf1.Type.newBuilder().setInterned(0).build()
|
||||
|
||||
val protoChoiceWithoutObservers = DamlLf1.TemplateChoice
|
||||
.newBuilder()
|
||||
.setNameInternedStr(0)
|
||||
.setConsuming(true)
|
||||
.setControllers(controllersExpr)
|
||||
.setSelfBinderInternedStr(3)
|
||||
.setArgBinder(DamlLf1.VarWithType.newBuilder().setVarInternedStr(4).setType(unitTyp))
|
||||
.setRetType(unitTyp)
|
||||
.setUpdate(bodyExp)
|
||||
.build()
|
||||
|
||||
val protoChoiceWithObservers =
|
||||
protoChoiceWithoutObservers.toBuilder.setObservers(observersExpr).build
|
||||
|
||||
forEveryVersionSuchThat(LV.Features.choiceObservers <= _) { version =>
|
||||
assert(LV.Features.internedStrings <= version)
|
||||
assert(LV.Features.internedTypes <= version)
|
||||
|
||||
val decoder = moduleDecoder(version, stringTable, ImmArraySeq.empty, typeTable)
|
||||
|
||||
decoder.decodeChoice(templateName, protoChoiceWithoutObservers)
|
||||
decoder.decodeChoice(templateName, protoChoiceWithObservers)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"decodeInternedTypes" should {
|
||||
def pkgWithInternedTypes: DamlLf1.Package = {
|
||||
val typeNat1 = DamlLf1.Type.newBuilder().setNat(1).build()
|
||||
|
@ -47,6 +47,7 @@ object LanguageVersion {
|
||||
val contractIdTextConversions = v1_dev
|
||||
val exerciseByKey = v1_dev
|
||||
val internedTypes = v1_dev
|
||||
val choiceObservers = v1_dev
|
||||
val exceptions = v1_dev
|
||||
|
||||
/** Unstable, experimental features. This should stay in 1.dev forever.
|
||||
|
Loading…
Reference in New Issue
Block a user