Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[LF] recompute key before store contract in the cache #19791

Open
wants to merge 2 commits into
base: main-2.x
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -306,10 +306,10 @@ private[lf] final class Compiler(
): (SDefRef, SDefinition) =
topLevelFunction(ref)(fun1(body))

private[this] def unlabelledTopLevelFunction2(ref: t.SDefinitionRef)(
body: (Position, Position, Env) => s.SExpr
private[this] def unlabelledTopLevelFunction1(ref: t.SDefinitionRef)(
body: (Position, Env) => s.SExpr
): (t.SDefinitionRef, SDefinition) =
ref -> SDefinition(pipeline(fun2(body)))
ref -> SDefinition(pipeline(fun1(body)))

private[this] def topLevelFunction2[SDefRef <: t.SDefinitionRef: LabelModule.Allowed](
ref: SDefRef
Expand Down Expand Up @@ -775,8 +775,7 @@ private[lf] final class Compiler(
optTargetTemplateId,
byKey = mbKey.isDefined,
)(
env.toSEVar(cidPos),
mbKey.fold(s.SEValue.None: s.SExpr)(pos => SBSome(env.toSEVar(pos))),
env.toSEVar(cidPos)
)

}
Expand Down Expand Up @@ -821,7 +820,6 @@ private[lf] final class Compiler(
SBResolveSBUInsertFetchNode(
env.toSEVar(payloadPos),
env.toSEVar(cidPos),
s.SEValue.None,
),
) { (_, env) =>
env.toSEVar(payloadPos)
Expand Down Expand Up @@ -860,7 +858,7 @@ private[lf] final class Compiler(
tmplId: Identifier,
tmpl: Template,
): (t.SDefinitionRef, SDefinition) =
unlabelledTopLevelFunction2(t.ToContractInfoDefRef(tmplId)) { (tmplArgPos, mbKeyPos, env) =>
unlabelledTopLevelFunction1(t.ToContractInfoDefRef(tmplId)) { (tmplArgPos, env) =>
// We use a chain of let bindings to make the evaluation order of SBuildContractInfoStruct's arguments is
// independent from the evaluation strategy imposed by the ANF transformation.
checkPreCondition(env, tmplId, env.toSEVar(tmplArgPos)) { env =>
Expand All @@ -875,24 +873,15 @@ private[lf] final class Compiler(
case None =>
s.SEValue.None
case Some(tmplKey) =>
s.SECase(
env.toSEVar(mbKeyPos),
List(
s.SCaseAlt(
t.SCPNone,
let(
env,
translateExp(
env.bindExprVar(tmpl.param, tmplArgPos),
tmplKey.body,
),
) { (keyPos, env) =>
SBSome(translateKeyWithMaintainers(env, keyPos, tmplKey))
},
),
s.SCaseAlt(t.SCPDefault, env.toSEVar(mbKeyPos)),
let(
env,
translateExp(
env.bindExprVar(tmpl.param, tmplArgPos),
tmplKey.body,
),
)
) { (keyPos, env) =>
SBSome(translateKeyWithMaintainers(env, keyPos, tmplKey))
}
}
let(env, body) { (bodyPos, env) =>
SBuildContractInfoStruct(
Expand Down Expand Up @@ -1174,7 +1163,7 @@ private[lf] final class Compiler(
val expr1 =
s.SEApp(
s.SEVal(t.ToContractInfoDefRef(templateId)),
List(s.SEValue(argument), s.SEValue.None),
List(s.SEValue(argument)),
)
val contractPos = env.nextPosition
env = env.pushVar
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -956,9 +956,8 @@ private[lf] object SBuiltin {
machine: UpdateMachine,
): Control[Question.Update] = {
val templateArg: SValue = args.get(0)
val keyOpt: SValue = SOptional(None)

computeContractInfo(machine, templateId, templateArg, keyOpt) { contract =>
computeContractInfo(machine, templateId, templateArg) { contract =>
contract.keyOpt match {
case Some(contractKey) if contractKey.maintainers.isEmpty =>
Control.Error(
Expand Down Expand Up @@ -1017,9 +1016,8 @@ private[lf] object SBuiltin {

val coid = getSContractId(args, 1)
val templateArg: SValue = args.get(5)
val keyOpt: SValue = SOptional(None)

getContractInfo(machine, coid, templateId, templateArg, keyOpt) { contract =>
getContractInfo(machine, coid, templateId, templateArg) { contract =>
val templateVersion = machine.tmplId2TxVersion(templateId)
val pkgName = machine.tmplId2PackageName(templateId, templateVersion)
val interfaceVersion = interfaceId.map(machine.tmplId2TxVersion)
Expand Down Expand Up @@ -1159,8 +1157,7 @@ private[lf] object SBuiltin {
machine: UpdateMachine,
): Control[Question.Update] = {
val coid = getSContractId(args, 0)
val keyOpt = args.get(1)
fetchAny(machine, optTargetTemplateId, coid, keyOpt) { sv =>
fetchAny(machine, optTargetTemplateId, coid) { sv =>
Control.Value(sv)
}
}
Expand All @@ -1172,8 +1169,7 @@ private[lf] object SBuiltin {
machine: UpdateMachine,
): Control[Question.Update] = {
val coid = getSContractId(args, 0)
val keyOpt = args.get(1)
softFetchInterface(machine, coid, keyOpt)(Control.Value)
softFetchInterface(machine, coid)(Control.Value)
}
}

Expand Down Expand Up @@ -1432,16 +1428,15 @@ private[lf] object SBuiltin {
templateId: TypeConName,
optTargetTemplateId: Option[TypeConName],
byKey: Boolean,
) extends UpdateBuiltin(2) {
) extends UpdateBuiltin(1) {

protected def executeUpdate(
args: util.ArrayList[SValue],
machine: UpdateMachine,
): Control[Question.Update] = {
val coid = getSContractId(args, 0)
val keyOpt: SValue = args.get(1)
fetchContract(machine, templateId, optTargetTemplateId, coid, keyOpt) { templateArg =>
getContractInfo(machine, coid, templateId, templateArg, keyOpt) { contract =>
fetchContract(machine, templateId, optTargetTemplateId, coid) { templateArg =>
getContractInfo(machine, coid, templateId, templateArg) { contract =>
val version = machine.tmplId2TxVersion(templateId)
machine.ptx.insertFetch(
coid = coid,
Expand Down Expand Up @@ -1567,18 +1562,16 @@ private[lf] object SBuiltin {
)
)
} else {
val keyOpt = SOptional(Some(keyValue))
val gkey = cachedKey.globalKey
machine.ptx.contractState.resolveKey(gkey) match {
case Right((keyMapping, next)) =>
machine.ptx = machine.ptx.copy(contractState = next)
keyMapping match {
case ContractStateMachine.KeyActive(coid) =>
fetchContract(machine, templateId, optTargetTemplateId, coid, keyOpt) {
templateArg =>
getContractInfo(machine, coid, templateId, templateArg, keyOpt) { contract =>
machine.checkKeyVisibility(gkey, coid, operation.handleKeyFound, contract)
}
fetchContract(machine, templateId, optTargetTemplateId, coid) { templateArg =>
getContractInfo(machine, coid, templateId, templateArg) { contract =>
machine.checkKeyVisibility(gkey, coid, operation.handleKeyFound, contract)
}
}

case ContractStateMachine.KeyInactive =>
Expand All @@ -1592,17 +1585,15 @@ private[lf] object SBuiltin {
keyMapping match {
case ContractStateMachine.KeyActive(coid) =>
val c =
fetchContract(machine, templateId, optTargetTemplateId, coid, keyOpt) {
templateArg =>
getContractInfo(machine, coid, templateId, templateArg, keyOpt) {
contract =>
machine.checkKeyVisibility(
gkey,
coid,
operation.handleKeyFound,
contract,
)
}
fetchContract(machine, templateId, optTargetTemplateId, coid) { templateArg =>
getContractInfo(machine, coid, templateId, templateArg) { contract =>
machine.checkKeyVisibility(
gkey,
coid,
operation.handleKeyFound,
contract,
)
}
}
(c, true)
case ContractStateMachine.KeyInactive =>
Expand Down Expand Up @@ -2180,9 +2171,8 @@ private[lf] object SBuiltin {
templateId: TypeConName,
optTargetTemplateId: Option[TypeConName],
coid: V.ContractId,
keyOpt: SValue,
)(f: SValue => Control[Question.Update]): Control[Question.Update] = {
fetchAny(machine, optTargetTemplateId, coid, keyOpt) { fetched =>
fetchAny(machine, optTargetTemplateId, coid) { fetched =>
// The SBCastAnyContract check can never fail when the upgrading feature flag is enabled.
// This is because the contract got up/down-graded when imported by importValue.

Expand All @@ -2205,7 +2195,6 @@ private[lf] object SBuiltin {
machine: UpdateMachine,
optTargetTemplateId: Option[TypeConName],
coid: V.ContractId,
keyOpt: SValue,
)(f: SValue => Control[Question.Update]): Control[Question.Update] = {
machine.getIfLocalContract(coid) match {
case Some((templateId, templateArg)) =>
Expand All @@ -2230,7 +2219,7 @@ private[lf] object SBuiltin {
language.Reference.Template(dstTmplId),
) { () =>
importValue(machine, dstTmplId, coinstArg) { templateArg =>
getContractInfo(machine, coid, dstTmplId, templateArg, keyOpt) { contract =>
getContractInfo(machine, coid, dstTmplId, templateArg) { contract =>
ensureContractActive(machine, coid, contract.templateId) {

machine.checkContractVisibility(coid, contract)
Expand Down Expand Up @@ -2267,7 +2256,6 @@ private[lf] object SBuiltin {
private def softFetchInterface(
machine: UpdateMachine,
coid: V.ContractId,
keyOpt: SValue,
)(f: SValue => Control[Question.Update]): Control[Question.Update] = {
machine.getIfLocalContract(coid) match {
case Some((templateId, templateArg)) =>
Expand All @@ -2286,7 +2274,7 @@ private[lf] object SBuiltin {
language.Reference.Template(dstTmplId),
) { () =>
importValue(machine, dstTmplId, coinstArg) { templateArg =>
getContractInfo(machine, coid, dstTmplId, templateArg, keyOpt) { contract =>
getContractInfo(machine, coid, dstTmplId, templateArg) { contract =>
ensureContractActive(machine, coid, contract.templateId) {

machine.checkContractVisibility(coid, contract)
Expand Down Expand Up @@ -2379,15 +2367,14 @@ private[lf] object SBuiltin {
coid: V.ContractId,
templateId: Identifier,
templateArg: SValue,
keyOpt: SValue,
)(f: ContractInfo => Control[Question.Update]): Control[Question.Update] = {
machine.contractInfoCache.get((coid, templateId.packageId)) match {
case Some(contract) =>
// sanity check
assert(contract.templateId == templateId)
f(contract)
case None =>
computeContractInfo(machine, templateId, templateArg, keyOpt) { contract =>
computeContractInfo(machine, templateId, templateArg) { contract =>
machine.insertContractInfoCache(coid, contract)
f(contract)
}
Expand All @@ -2398,14 +2385,10 @@ private[lf] object SBuiltin {
machine: Machine[Q],
templateId: Identifier,
templateArg: SValue,
keyOpt: SValue,
)(f: ContractInfo => Control[Q]): Control[Q] = {
val e: SExpr = SEApp(
SEVal(ToContractInfoDefRef(templateId)),
Array(
templateArg,
keyOpt,
),
Array(templateArg),
)
executeExpression(machine, e) { contractInfoStruct =>
val contract = extractContractInfo(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1310,6 +1310,8 @@ class EvaluationOrderTest(languageVersion: LanguageVersion)
"contract agreement",
"contract signatories",
"contract observers",
"key",
"maintainers",
"template choice controllers",
"template choice observers",
"template choice authorizers",
Expand Down Expand Up @@ -1356,6 +1358,8 @@ class EvaluationOrderTest(languageVersion: LanguageVersion)
"contract agreement",
"contract signatories",
"contract observers",
"key",
"maintainers",
"template choice controllers",
"template choice observers",
"template choice authorizers",
Expand Down Expand Up @@ -1388,6 +1392,8 @@ class EvaluationOrderTest(languageVersion: LanguageVersion)
"contract agreement",
"contract signatories",
"contract observers",
"key",
"maintainers",
)
}
}
Expand Down Expand Up @@ -1649,6 +1655,8 @@ class EvaluationOrderTest(languageVersion: LanguageVersion)
"contract agreement",
"contract signatories",
"contract observers",
"key",
"maintainers",
"template choice controllers",
"template choice observers",
"template choice authorizers",
Expand Down Expand Up @@ -1679,6 +1687,8 @@ class EvaluationOrderTest(languageVersion: LanguageVersion)
"contract agreement",
"contract signatories",
"contract observers",
"key",
"maintainers",
"template choice controllers",
"template choice observers",
"template choice authorizers",
Expand Down Expand Up @@ -2375,6 +2385,8 @@ class EvaluationOrderTest(languageVersion: LanguageVersion)
"contract agreement",
"contract signatories",
"contract observers",
"key",
"maintainers",
"ends test",
)
}
Expand Down Expand Up @@ -2421,6 +2433,8 @@ class EvaluationOrderTest(languageVersion: LanguageVersion)
"contract agreement",
"contract signatories",
"contract observers",
"key",
"maintainers",
)
}
}
Expand Down Expand Up @@ -2450,6 +2464,8 @@ class EvaluationOrderTest(languageVersion: LanguageVersion)
"contract agreement",
"contract signatories",
"contract observers",
"key",
"maintainers",
)
}
}
Expand Down Expand Up @@ -2957,6 +2973,8 @@ class EvaluationOrderTest(languageVersion: LanguageVersion)
"contract agreement",
"contract signatories",
"contract observers",
"key",
"maintainers",
"ends test",
)
}
Expand All @@ -2982,6 +3000,8 @@ class EvaluationOrderTest(languageVersion: LanguageVersion)
"contract agreement",
"contract signatories",
"contract observers",
"key",
"maintainers",
)
}
}
Expand Down Expand Up @@ -3011,6 +3031,8 @@ class EvaluationOrderTest(languageVersion: LanguageVersion)
"contract agreement",
"contract signatories",
"contract observers",
"key",
"maintainers",
)
}
}
Expand Down
Loading